From 75163b922ad254a07139d1a7011d1245eb12368a Mon Sep 17 00:00:00 2001 From: eee <719747958@qq.com> Date: Mon, 1 Jan 2024 20:25:33 +0800 Subject: [PATCH 01/33] the reading --- src/kernel_liteos_a | 1 + 1 file changed, 1 insertion(+) create mode 160000 src/kernel_liteos_a diff --git a/src/kernel_liteos_a b/src/kernel_liteos_a new file mode 160000 index 00000000..c2cb0435 --- /dev/null +++ b/src/kernel_liteos_a @@ -0,0 +1 @@ +Subproject commit c2cb0435b290dbe0be3054aa904de7859e341fe9 From bf6361a9407abfd03b32984396e85e675bfca9d2 Mon Sep 17 00:00:00 2001 From: eee <719747958@qq.com> Date: Mon, 1 Jan 2024 20:26:43 +0800 Subject: [PATCH 02/33] one --- doc/泛读报告.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 doc/泛读报告.md diff --git a/doc/泛读报告.md b/doc/泛读报告.md new file mode 100644 index 00000000..e69de29b From 06457d80d97994e539f2e9a72484d5e608dd8df4 Mon Sep 17 00:00:00 2001 From: eee <719747958@qq.com> Date: Wed, 3 Jan 2024 21:35:20 +0800 Subject: [PATCH 03/33] write some thing --- .vscode/settings.json | 6 ++++++ doc/process.md | 26 ++++++++++++++++++++++++++ doc/泛读报告.md | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+) create mode 100644 .vscode/settings.json create mode 100644 doc/process.md diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..03f05d5c --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "files.associations": { + "los_swtmr_pri.h": "c", + "los_vm_syscall.h": "c" + } +} \ No newline at end of file diff --git a/doc/process.md b/doc/process.md new file mode 100644 index 00000000..b28c36fe --- /dev/null +++ b/doc/process.md @@ -0,0 +1,26 @@ +# base 下的代码阅读 + +根据官方的README.md,kernel/base下的文件主要为**基础内核包括调度、内存等模块** + +# 1. brief intro + +OpenHarmony liteos 的进程实现方式与 linux 类似,都是通过父进程和子进程的一系列操作来达到实现一些功能的目的. + +# 2. natural expression of requirement of software + +作为操作系统当中的子系统,以软件的角度来看进程管理: + +## 2.1 一个完备的进程管理系统应当具备 + +### (1) 进程调度 +### (2) 进程创建 +### (3) 进程回收 +### (4) +### (5) +### (6) + +# 3. user case diagram and user case description + + + +# 4. software architecture diff --git a/doc/泛读报告.md b/doc/泛读报告.md index e69de29b..a1e1be83 100644 --- a/doc/泛读报告.md +++ b/doc/泛读报告.md @@ -0,0 +1,37 @@ + + +# LiteOS_kernel_a 泛读报告 + +## 一、 软件功能的自然语言描述 + +### 1.1 简介 + +Huawei LiteOS是华为面向IoT领域,构建的轻量级物联网操作系统,可广泛应用于智能家居、个人穿戴、车联网、城市公共服务、制造业等领域。 + +Huawei LiteOS发布于2015年5月的华为网络大会上。自开源社区发布以来,围绕 NB-IoT 物联网市场从技术、生态、解决方案、商用支持等多维度使能合作伙伴,构建开源的物联网生态。目前已经聚合了 50+ MCU 和解决方案合作伙伴,共同推出一批开源开发套件和行业解决方案,帮助众多行业客户快速的推出物联网产品和服务。客户涵盖抄表、停车、路灯、环保、共享单车、物流等众多行业,为开发者提供 “一站式” 完整软件平台,可大幅降低设备布置及维护成本,有效降低开发门槛、缩短开发周期。 + +Huawei LiteOS开源项目目前支持 **ARM64、ARM Cortex-A、ARM Cortex-M0,Cortex-M3,Cortex-M4,Cortex-M7** 等芯片架构。 + +### 1.2 软件功能 + +#### 1.2.1 提供一个简单轻便的用户交互界面以供使用。 + +#### 1.2.2 能够调用系统软硬件资源来完成某些操作。 + +#### 1.2.3 进程管理 + +#### 1.2.4 内存分配 + +#### 1.2.5 提供并行编程 + +## 二、 软件的用例图和用例描述 + + +## 三、 软件的体系结构(用包图描述其逻辑视图) \ No newline at end of file From f8cf1d11f9941d668683fa4d0cabd6353e0034d0 Mon Sep 17 00:00:00 2001 From: eee <719747958@qq.com> Date: Thu, 4 Jan 2024 09:20:53 +0800 Subject: [PATCH 04/33] 20240104 --- doc/image-1.png | Bin 0 -> 385000 bytes doc/image-2.png | Bin 0 -> 385000 bytes doc/image.png | Bin 0 -> 137587 bytes doc/~$$绘图1.~vsdx | Bin 0 -> 4096 bytes doc/{process.md => 学习报告.md} | 5 +++++ doc/泛读报告.md | 5 ++++- doc/绘图1.vsdx | Bin 0 -> 42782 bytes 7 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 doc/image-1.png create mode 100644 doc/image-2.png create mode 100644 doc/image.png create mode 100644 doc/~$$绘图1.~vsdx rename doc/{process.md => 学习报告.md} (89%) create mode 100644 doc/绘图1.vsdx diff --git a/doc/image-1.png b/doc/image-1.png new file mode 100644 index 0000000000000000000000000000000000000000..18765b3d1a8bf55cd9345f4ad11ffe84284a0531 GIT binary patch literal 385000 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 @yynalG9<}tbg6$Z>w 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

    oNZlrk)(WT&rELsI5IQrXPNR&eRMYr}$Qkh<>_A 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 literal 0 HcmV?d00001 diff --git a/doc/image-2.png b/doc/image-2.png new file mode 100644 index 0000000000000000000000000000000000000000..18765b3d1a8bf55cd9345f4ad11ffe84284a0531 GIT binary patch literal 385000 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 @yynalG9<}tbg6$Z>w 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

      oNZlrk)(WT&rELsI5IQrXPNR&eRMYr}$Qkh<>_A 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 literal 0 HcmV?d00001 diff --git a/doc/image.png b/doc/image.png new file mode 100644 index 0000000000000000000000000000000000000000..04b5dd2e8e5778a67bcdbd1073199bd88274ddc8 GIT binary patch literal 137587 zcmeFYXH*ki^e-F%D^e5@MVca@AfOcKMXJ(!FDe}b1QL1?MNknCrAY6D7LX1J5D_Kx z(2~#sDm9dVw9o=~!sGMY5AS;45AV8P?pps@%QBgnGyCk>d!N03`*+^z>8R74V?74~ zf#@DRR51X7POE@GH2h~y0l(l

      j` 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 !1fW?@}@0eg?o$zir(?v&? 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 RMMH0N*v8?f601`e{|yY`B>4aU literal 0 HcmV?d00001 diff --git a/doc/~$$绘图1.~vsdx b/doc/~$$绘图1.~vsdx new file mode 100644 index 0000000000000000000000000000000000000000..51b621eeaf92be13f75fd8a527c1531414740773 GIT binary patch literal 4096 zcmca`Uhu)fjZzO8(10BSGsD0CoD6J8;*3Bx6O1pwz`zP*gT(&*|NkE(%nZap<|r6K zA@CRIR#5znf{_^lK@9moSi+#d;L4B(q>C6TL0Oq-AOZi2;JVuj2Z3>hpL%o)fvgHW4=Sa%FnbpRty BQ-1&e literal 0 HcmV?d00001 diff --git a/doc/process.md b/doc/学习报告.md similarity index 89% rename from doc/process.md rename to doc/学习报告.md index b28c36fe..8ad69581 100644 --- a/doc/process.md +++ b/doc/学习报告.md @@ -6,6 +6,10 @@ OpenHarmony liteos 的进程实现方式与 linux 类似,都是通过父进程和子进程的一系列操作来达到实现一些功能的目的. +## 1.1 描述各个子功能 +* 创建进程 | + + # 2. natural expression of requirement of software 作为操作系统当中的子系统,以软件的角度来看进程管理: @@ -21,6 +25,7 @@ OpenHarmony liteos 的进程实现方式与 linux 类似,都是通过父进程 # 3. user case diagram and user case description +![Alt text](image.png) # 4. software architecture diff --git a/doc/泛读报告.md b/doc/泛读报告.md index a1e1be83..db1759d1 100644 --- a/doc/泛读报告.md +++ b/doc/泛读报告.md @@ -33,5 +33,8 @@ Huawei LiteOS开源项目目前支持 **ARM64、ARM Cortex-A、ARM Cortex-M0,C ## 二、 软件的用例图和用例描述 +![Alt text](image.png) -## 三、 软件的体系结构(用包图描述其逻辑视图) \ No newline at end of file +## 三、 软件的体系结构 + +![Alt text](image-2.png) \ No newline at end of file diff --git a/doc/绘图1.vsdx b/doc/绘图1.vsdx new file mode 100644 index 0000000000000000000000000000000000000000..9ad9bee402100b5d37376cbb4114b1c5fe7b73ce GIT binary patch literal 42782 zcmeFYbCV`fwC4MkZQHi3F59+kS9RI8tu9+#wr$(Cb$ia4dtz?PnNKh`BV%Vq zBG!J^Uh7E(X%J9U05|{=000mHyo>vz6M+B#a0mbZ1po=GEo^V+Vru82uj1)o>a0ue zVQWKJ2ntM@4*>o*|Np=KFDB5GGG^D$h#7p7@(!O+t7?=VRT0@+Fj0RbNYESkYPOHJ`rC625Ra{Oz`>7L6+nm}@&S2swVmuKN3nsfZ5>AHV^f|B+a@Af(tTh*%(OMZ~vO#r%< zrvm>|Ur=-?gF=JoQPK+Acb6=11L@dEpH;h}xSj=$JTK->Z}{8+H&&orr7sdT_Zp$-O21k8-wM{xdp zNi+FDYPACk^H}gY8IN3V>5U_c-_n;33WYEa;-rJCM zv=1F;&w{|UB7;(V4#!B)z!NpK8wuCVRsFgD@``lgPxYWmS_!4W4n*@575Q|whApmI zX$VY9LCD6FjzTGTOs^Nv#~+?W3U6X|9p1WTe#oKefRTo%kO!@AoStSbKGN*W;vn8;T=-_%2c5tEtD(evT&c$?L9YTd}pv|tvx zwH%73I)|!pm)L6Gx4wJc^=gvVL3^3kA9_ds*45Ro)~kn*iZd$pF_9b^PIMRfRt%@) zVMSy)nfsG935D>gmhSuMeje!@4Gx!fUe#Xa2NJapK$*A_NQu`m5a^ zh5%WUFvrZ0Ef~H0aC|IHB{nRUR?(RWuBnq2(KX1kHU9%DIj;j&mSseF@)naWD5|DF zhMS~?n=HFU@9>~HiuJ`{cE0vY{i5F23eBBm8Kte`&m3}I_Z0a)hEw?Aq`(@kmmJZS z9x{}Buv!5(9N0EN#NesAO5Q(E|9e!~BBzl5LIVJ-f&l>Je>2=Hoh|JdOze$aZU4#S z|Io)vU1@s~NvCd{TR%cK_|2h0vTiE)Vm$@Yl2q|pw57PaYLV2zb^3-=BgL)Eg?|3m zZ<6jMwE;;QH8=Jf@; zS`~R;5|`vqcS=-Es(+C+PupFF=>c!nnDsf4S$+I&ekA`Ea>e?f5$JxYoOx*^HWrY~ zr>PuwZR&iy27uz>zPE03%hY_mjB$EG?inic@xq~ZKiyJ73SaEqai^QjqO*G9)_hg9 zopgQa9(;Uz?9rh$&spExV9SI0Jo4XRa3WToOr?Uxiv!Q=Z-#tZVQ|0J-3o4wI5OhV zb!N@x@z>tmFw4I%98lg-G?Z4JG=J$n1QgD6me|i81x5QFS0gK+C<#523gdQnY0FR% z`T%T7tcpPE1j73vsgr(U(Ir0>xICQ|Y?~@lDh~#N&ds+-K2-`zfu#tqVCQk&w7!5K z&P?K$5e0CID+zP#jA!==^WPHF%(}K#jXlpy%s`&3yU{at=ZajO0}ihtIbNcP9952ieX4xJV?2_vd-R+ zFw30n;ZbY^K6ape{X7-$JPaLBAeP1_L;;~IJ@@GD{Hx36)pE5PHB0APr+y-z&`ksotWe(`Rh~Ddac`5tao=Mt>J10)7U9q9rHD;gQcpL{XM;#ildv?kT8 z3DZ}?^V+%h`m+^Z2M%dc+fwi%-J4SZt^p-GM7re2+S7UIUa0}bV{b>aYK*^S8$)7I zmIARw?gzUx`U*J79l}5K8j$TB#j;2`Uea0ll?PeMTOF}oA-J%@8bKD_gSk2av}BFo zXb@1KR|DLnne4+z5k{g7ZOB0viJKnmKH@ZNS|Y?LZ9=4%ob5#(PP395a-g&ukOySU z!=kuj7_F@|0-nY%d||H*kd7$ee$CGz2uc7P`Oev}vuu%iL9C+uOdi;kM4ND#gptP6 zoUP$$R9(8fUe9h+j1W1!=N@oqC4~MxW$ba`9C1yJAp&_C_^@5!CYXVX zH;fD_5%`=D5Te73r=GI%rT@@~#N*~&ygYT=`@Z^*{>wfM z*nusvMXr-fp7=T7FTU+qrrM(V>7vS$2_#4AwrLo62-4~nLL1Kkrx18Wq{S9#@B5RC?+(XY z3;h|$azF%^;$hF1njj?{nMLtdUWAdXk@2(owsKxcT> zCOe(;z20RA^hmm<%x~*d3k%>I{Uu4@cU;hb>Dd%aJ7UN;oJNZ;(Ou-gWG#@L;4?fo z@Y9q)GaW&+GfGiTc2yG9#856Qi}JXfI#K$7Z3dOj8AMD?C~75XU9;qXA4;eFROSAX zp`HxGEVMnVOOhP)HYKd0)L>#!{Yxy3V2jq+m;i%+T1{(t%MYto2g^%Y$n-wnt`k&r zQkqlL?%dEni&cP)mRHpfvK4|ExH@})H5uptUA3Wvc)UL!cfv2Wj5#w3%J`iC_4g2? zlZGV`N}GKHgCBbPV?l`gSC%i9*bVe(-IcUS{QQ!%3Eh_X2^Qds+5*4qul7gO)9*1B zLBKV519k76>7h&oz+ZWKHLQqnbP{v!qzRZP6sc7vDgc{7cv^a~3G}Hq)u3Xq^t+2- zeUZiw%o>-ThFw++Z+3CD$!05axE zLRF-#py!Ys!wzn8SgkyaNs*-@2=7u1d@qG0%%BNmLSOuZ(OYS2z5I!=f2HPy+xtoj zg+y(!&cZ`Wo#~Siv=n;)Q}d`|-L86h>tdYH&@7I{LCqEEFTytvE_r;#-eCTm?Zp;} zsdiCgd(>=0((6w26*9AshuWJMrxs}2*NoO|J?*OiO?JthCd$z3_ajD~c0XSNA78wp zWKXP3g@W<6f`L$LilFMkvVS>d3L8e&YC^yiZFIP*&XF)GEICHG0is(kF$A(+RdN^8 z!Jsph@c~yui_z^qR}g{!%X#Cm7UH~OF*S9UwV2&s(}U{#)hQx~T~wiFFXeP&pR*Bt zP|MZc^rp~R%jUP@W^N(o&=kiPZV9vg;?aPT9FI2Oa=~z_p!F-f z!V#d=ISqTwCn*I{P1%D}_IwHV%S#Nq)ApEy3un?qf z2#S&dltmkYVQF1{YpF$>;fy+PVe|N|Xf!{l+m21XUt7R;8qO(iSX~CvoEGH7>N=>M z&Aw0*6%31$&?>`kzX%)}P7xE_8JZt-7>$ z2Muq9uFgL>OQH}g2-68<<~*(g7%7DHg;<1I3F(T)lNWb*^*U|IsJ{%{#uc21pfNIk z`G<4z{8gxoGVnl=sCtE;g#=bL#H=#Iymc{{Uu6?p2)QCx6lyplr9_551gZ)5)q)UP znGKqJcH-O*!@wwY$h?96D4Y?Qa$=fioUtqO3DyA5@(i@2Wv&dWVJnz3HwWv&8Q$ip z8`!CUy(|rPbzu?Rpj6#8VS=#>1RYQ+r*cq_WpG?B?ye z?8*WZ;v(Q+P2!PvcoVzy^CQ#K6N1O$!VkpruyNr*V2M-VhS%%-X3PV*)PpsjL3H-* z_CxDJu{32%ya`wq8zq$WAX=E;6XgU(1&NCa*ArV)Aw!dffuO)BG&BY&N=wDdd`Q@# z7%=RU=2VIj)q1g4P38dwHOE!6C6k%lW`6KO^z*4mk}nWZ9CD7@*-U4;tZ zN?rPWrPvp*1 z%qm#FRxfN=L5C#J#=>l-bGl|TIv&XRn6{ta7?6>yI7`ru!TMgJJZ`Z?kTRufI3Z${ zlcJgSXDT2l;6VGI;51~?G+(>-yv-o^{j?H%pY6y({+U*F$QI!tuEicI=rLS6&q5D( zNv_W)36TS?tNG)0jZ$^xvQHT2H5%#2$}|}hTvjwa={&H@ zDv14_)VgtLs}nnkHwXJJL0ULUnJ-yw;d z64huL4vW)|WNVy+qjSf{2*-TQJE;L(9LL#K{3Cd{fA# z_tRz(#MGS%z|u~r8J4L62>EJ*+>rT$n@|9(W!^W@S5z-BMhEBdKu0!o+y2 zUv8}f!%4QUt?o%!LyTLd_<~zz;0f+|n&Eq5jgaSZEP#b-cC(PZ4Q5d?-L@4uP{&3X zCM&EEI(QJ&X}A+N7L9XX6sK)lx_byiI&}^@2aE$Ju)Wj}$=^=EjV$`CP%c*-O&4P~ zMKl{P<2NkB5r5^30vh4W**E2Da@*9$JwpWy)Nde8TQHsd-+wJCGYR^soRDT2bJqf5 zDz_ty3&Au`Z8+TwVK`4~QbrYZ1O`)D%Lv+LOx01<5iae6T2c6lf5+-S*M3rjb3NmGeFsQ@mn8118+Lp|HJbCeCoRb5-;h5laoMkz|A zr9?%o6Qh4oBE0<1+)~gvN6-7k&d^g zxKKWpxtQ`dsyG*cuUqZXq)}&xa$oW^7sjI38b4^sdQG6C#W$o*u#Kh}Jq=4Bcig1( z#Bjior-`nXStTMD(EB}ekRbyT%im2?GjKzFD>K2ii7D8?uEWV){$W$|KbjgwPbKD| z(>lIp3YTOS;1FE8df&{fAdU2*Ea{s^7T|^@6O5SkD(Pt@Sg3xMnLv@}PH9wdq8vcX zQYwJif3Jw{8S_K3-)coLX&vjwfdN5QdJQf>)feuth)!nGb!pqyle*o9mBKgJ0Y(!S z+qwzVV?G`G)IgLYQE=U(0aLouF6xwnoJwh|Sovk~ddswfv(j0x@ok-w3Wtm~3hYI* zS83mNEE(@v9@KvGw&Zq~& z_I=%{{rUL$J|d9y;(zu}(uA1Y#fjjXRaw8$z6^jJdy1M{J5~L891+W3fE7s&TsY{6 z0nSJ;wx#a+I*m>9E(BZYh`Ko7B&wY( z>Q(kvk%lr!8;usrW6!&dDk_p8MYlzj!W73lEoIjIuM`GRTHAO^!XD-j&czUnFR4Of z6O<&Uqj2>`Pc#XI*31sD+nxc8@isU;MMzV+*5!CggB@HNjoB9IcFijKgY-_uR)5pQ zucM)YiL!|f9G;SiL=>nEwj zu+5`H^4D|!E@sYuiNTgJkA9GC`)dCMewHV8)e$=InEuLj(}pZbL!Ul;tAT;%8_Yhs z(lGPn#VNW3C9w&9X)S*9X@z$oim5-bnHs=F2V0%)C%}+&yUsFallS2-WKxluPhLvB zs&6v{tpj{>~tqK}zg2ijZin`NDAVj^3|n`T7v z`ZU3&F&A0WYNmhbI+*4BhoihqPO5S5=v8g>Y&e#OQ6WbQpeu8rh@j1xb`#eY2? znDspTUAy78dw#*^_~;rL`*#262R*?)W3?i1wDi`>s3toik@~ST{Z5|u)5;JidCXHg zmZ$m>?_tK!B{(bpghNASab~rEAGz`Sm?8MS-tiSwmyp`=HX;_?v8=dPlbm;>e^48` zGBIZto{;hSzEt~+_!ma6qaVMiUmuEuU%LuAF!iZOf58j9kI7$%K~I);3#WL-@6Zcn z#z+W|NvY={m$>#G&5=u87^jc8Zj0JGobnrJr02TbQ65)CK^TpCJG&lcNAW=@LkL>_ z!3AoQ|K;48In_s`Z3=!eia$xDYZ=6)k$P0x|5|L@48R=Lqqt9r(lDn>7KRa8-5|k;~50S?=(LVv({zh|eM|8Mt zq7l#^c%psUwo%fRB9JG(ZY`^48jT$FBVAMz%tqrlbIpId`f|2&a?BR2S56~}4{a-!&$tqXgc5u_h_!5@&GEr_Ug4o~xN=v3YYQtI_8(-OOGRP%d@T;c8d z!?9>oP=^OW*b~E6iv@Q2L~I8@K?urYz;ep&YaA3+`H!f%+f8gMu_)gqVOb@bODhi# z4-1dC`^N@WP3N;(Yf}5wBSg*35vZpovQn)23r@|-I8>Gpi!EgNiW&xnTE#OVpau2T zJ1Bb=K5*Mq5qEJzZUvv#eamZy;C0HN?b==Gwr8g~sIOtiK7^RIr+dw{6A&zcRe$4h3An^<+S>M)>fk+HbETkoe4p+;+i?qC znw?e|8i$IEZ#Qz!iOCi`57@y_N)a-2Mtt3hr*8btX6*jCK0PZ9bLZdH>?QbBvHa4} zMMwb{=-YXLf9~e}{e62oH&V3q@75>y{r%l%@AiE2ZT)j?elU{vb<%}5{IHedE~K*c zvb<%>h%gu*yK%3;z*cDm@#N+k)!cV9+CFE!3S_)}yQy!(%^A{4rpb;PWML_ph}tP( zSyU#eFd-pUP%P!8=P536bOm&v9wnxiCPPw_kUn z4OTCu1TLHv*BpZ4ek!*jHH9o*a0%(MFIAD6##E7yd8q}3S(8wxR0fX5QS#VT;$?e{ zdUY^$uG_$8?}Foz&;_lSXeup611nEcYbo^wf0!rp@a5&m_1L**D>N17@LO7|uTyZ?55@)n0A81i8*!%OZ@FSG_%P)N*yfcXAMc&oxy~=$sHn%=~!MU9SK;bMklX=96%iqw(ytuu%j7vAEL1|LFEB}xT+f}ShT<~2c5^$Aezf@zap(h{@K(J4V$ zN8q4wSYqTy{tyDEmt%S{%zDA7Bvy!qjw-OM3e<}@T0}@7heg3CR7T7KS3u%ENVPFd zRz8v7hGdpUYDvgwxJ%oFr^VhTMwYRQTA3DxB_S?2e(v{2N$n07xvJ%?Dbx&S_6D(; z1))s^J#S$*a5*qji-F;iwOG+5rqiYXOl-9RA@z32bb$Rp&`4#Z3c!;@nMczVpxTBk zIw{J*Rvkrv58y_`m#2~iH=#eI&oi~-2FWt0CBGC$CQBjBCIvWTaQP$V{*Ha2bJRll z$i+ksP+*ReDTP|oAYjC>%G+6kY8Zz2H-`up#7Ork%h?SWEXqwF)?#N8{X1*dgt&@D zpqr#mREIyJ)H_X`6~Cu#iOHR+V?QdBHsGZUkZVQDE_2w!w*a(VJ#T>sj-dEG@BR0n zb3+Cw4nB6GpS!XBKKow#^oQdF2>8BO2$SYo35Y}r{vH|Je9dhO=o2$DMd(nEfd?Xg zp^l0uJzy!ZPPr^AJXq4vm;*92tTM}>=cF{b>?P;1;v*`6R-<}mFlIps*Y3esxqyxJ z*esZR?+vIvkpaA#?&lu3ztX$R?74hAh-%&jRF1&=AE5GwmBGRI4{Cq-z6a!x1<*d> zbE5#LRPDK!8VHvLNquBglBE(1!B)7F6;HZxKyI`=A1KKvL&d$8T?Vm{}MXJ=O=Y+w{{KkiZ~$dw$D1(viE1L8##VN!dx#A!TV1! z(=%BWT%K>xv0(%|L?0Z0EV-N?Y3GyWn$WZ~U z)hR3vR(T^qS?KcSYGHUMK7eq*nDs?Cr^}#23?j3J`j*FItupLqwNoJByDZOwq3e23 ze^y-$g*3*dPsmpva5@Bz5b=Tua5W<4;*)g71SC-l`iF|!OZt!GWADrq@I23jQ7-i9 zzdYXvVETL@I^bm+AP9Uys0_dS+v;xCUXylWbA9d;fpUQu;Q;tC0y&6Y^NmvcB*Oku z^D2qU#WMW1l$p6|Q6f`jPfByd%UFP1r+^#EPCj$kv+RLHM^w9!Zb&|#p8|?^s)!lZ zTD?h2E0T0#8TPaCng>K*1xM4gAve}m+_mdj3#2WEJzylJb(EWRMTlW_PPyg2eJ>`I z%HCzDJ964F+03DsaYYZ{jtqJ;N#UVzMd6ssOxGVFAC3va*k>ONjN$BAO>+iBe>7K( zDDrk+Mwp?1Ma` zoHMTEcI2LOj!jbc4wu&izyUH@rSs-VRZiZPvT*S5yM>f=7uiyht5KO3W37zw+HqN7 z>d=)3do~~DS%9D#N`PCO!X2r)uX;Zn+1^vGt(r?b!@?_JW&-hI+|AWnZ9f6_A)f9~ z#30jH!&GymtY|aPcDzi%r!1*31sHdUF98;Y2%}>~NM|pGBLIC(@Ww!Oj~lVvb&ii< z82XjxIx&5usDlhnb`JZzsbWJF?Yp%=pb4lUdUM$0%tdNKV8o4rdz10h@Fvv3C9S*NXv3nEF2MIHW~2Cm6Xry-q-J~e09N1!&7-|tI z*GR>_#N6VFVnD3`*kNBnuUAoKg;NgpwTL=*+pIY$sE)^(-JxcRAZ`*$h(IWTBo49P8cx3u}MS!lPhe~4g4Qg6Su4L6? ze^S_w0u$(uWo4C%jTDz*%mFeD?@o7#^;ISf@dS&iy2`3l-uH3ACZ1fz)PJffLhW{U zv4qY1E7gz1f9aT+kkcM;(i>oP*FxPgeTe^Jg4BlA_r!DrI^2awQCz1x>yNV8kmRv$ zqRSg}AOD7NEOl9gZTS({kv-suOqzDgfETkZLN(@&^rYTf*mqcUtf#|6lGR3tdD~>ru1O2GV11ytAP<7UuS-&xAk#Y$`SyUMuid+Rwz zkEQMWEQjHMyGu&JJi1*euIgkHqK|Sg-CY@;LeyM<^)W^UUSDja2e;rDs%~5C!ryj@ z$~pl|b6DUbw6gvVavO`@d1Ur=d2!<52I1Xa?sfOXjVfZk4a|jW zXbcR2Ilkiy0BawP{}pLzc?dN`gb(c9I!ZWv=#WfZ%HPJsSb6Roeb5oWeDCJLd<(*3 zjFYpES=esuWZeo~Lm!2E4obL)B`%(T5eHdZP!lRm+%DMtuEg<%XmkaGGe|45+w2~a zX&3@7KK6qy3wjhm{bfW`8jn|7t+{|cF9p@+t`#>zAMH79mm$Sj-IBltb3*)O39TA{ zZ42jeG?Fyt$uSahbk;zvA+@C3vT}ffTcNGS*t|Ww_;s${mXLmSXxrzj*H6<;$&QF8 zX$d3zgC&cGY*@T1+gRcR?V4s=Yi-1xw*ZY?Rh(dUv!#%IngV3ZALb2$eC;m$JI^$} zqSRIn^u&VnaKX$x(2r#HvRp<+n@|};h5qrrf6m2LV3SDCmTPI?m3JYdEZ5wFHW~Sd z#fI!aih?Nt79)Kvfm~moC5uq?FKhE`t)rw>NED9`^+gJi0rAPPS5XR%7Ogwvp;Tmp zRc53&9eG+m_drM&ZJC%OBc-o)9sW6&u0U_BV{3bQKe)8LMbdd#&-dHyMV>Ah>qD94 z%Rt>nyg`Wc=1)7(mNyGlb(42P$NVSe$MzG=A($VQw&UZX-44HuC&MrTPK8(NanHco zxQI|Q_2&l>SdJyj&=l!W4mUQmt23+gHhn68&(GBXgWvD>moGJ1kf$Ds3apFjeK+K% zGPcq+p4XS9jgGoQpsW#**pok0$7m(xG3Q0K|E+_jDlT3Y_@6H=_@9Fm@4v$IKiz5n ztB>YCoNC31eOCV*N+LHQ-$AS1bUbt=$)jz_f;D7c0HRu3MQIvRGRyC7>GQc&a!If>yqN+r7mGO@At$ z+e!rL{#Kej!PP5~`6FJcECj^2(}bEc%{wdyZp-f)=A@W9!>s2e$ajaDB__1V8b{bN z(t9YdJ)J2Lv95#Z50Dph80m7UqL34pRZ^zgG{40olu8=@?iOK?R}Nh$1ja$XI0oJq1m75VX^sVZW!$I z|EAAoQGw4pP=p%4e7d~mkD;~=7D-nXBWnz3NUf7J;Emzb7!?vyq@{OJF&_gZ)$5xP z+FZP&J=}o1H2&d!!oDxx@#o%28ueS>Uc=?mlQJzDsZ4^9XevKZOlE^NwM^$#n7ie( zr`CkI^{dwvwn-Z_gR9p>cDD}iAam>p{riRF_>9-_&z$_h#TBE4Ati#D0MF*F9UaBkgoyIi$IB}UtuzrbuCuDE&eRAbYauxwPuhf{nh2GnswV>XuqoXH<8e53c){(2ck*{I2m=Yl#r8A(5vyS9?a z*Uj}*qopUn(Qa4RN4#OQ>HBrmuX4Hr3;~N>I;yh-|Lv+5?JcURKmmYN#Q$@7gz0}M z-=K!JeUTWdZ|&lb;1b01yc2{ls(DJYb3JOQ-K1GgDOyxmIywua1O3;Nx7lA0@EPoT z6&k6**KGT4uCyCQuCK=i*FUP`HC zc?Ye+CR$Pl>8Scns)mRtb6)a~O#lTL?^G-PF zZn^SF^a4GzMG|nB+TOIG`?myx9&>Qolv_s{a)%Z)cX-4Exp1XY#UW%GHByvsRt^C8 zW@h2Md#En-?#|!yO5>m^MjPtVB(qib7TYJD^e*r5sP}(nacjXO{BHJd^)nd~7op@F z^hEVoG{U>E#-0HzWyx&5_y!(OwoJXzby*Om_&tvcI7aSBqLj2zM1O+!5Ia5y<1F13 zLv>z1)0_;@kWxk+l_=d`-?FCvm%J z>F@jyRj4hYc;9Pxjxxmxjv(|DLI0gh{F{hKFT6rI_B(rs$h9Lb%08-NDG1rFrRVF~ zf@H#!BV+fH&Az0}CviLEhK%@iz7q>_9`poj+R~CL(FHzG3J<1y`LekmSY8qJGI1WE zn?X8Tk(y8nA5>>WS9hf>lx-X&Ka=(8KHFUbFvz4Uk3DU1+C8)vk1V+87XPWp=S_;9~_H*z#`=G998$QPXc~=`HNP zLnf0dBWCsXOc@}BPeqhyrt@ z0i$M9c9*?w{~oY%I&E*U<}6CMUj1X6p~mtu7G>w%x{tcsndm#jN;lGgH^RcZ#i|?j zWW(S}pbbmUm1iB@dc$ANxAS|~^6GDo*!%?RMEfx{EmBH%U!r^CduHwZPcG-je=B;p zJr^y}WB|ag^Z)Y}$NV1^V7@gc9InJ06s8}-4JMMYKd02&*>+FC^xBcLY>AhtdF&SD zq>h=yY@|omxqhqRUr|0=dF!h?t0KTqCTax=L&A0)8`ly4{#O7XM|8$#Nc{eJ(Z7bE z$xFN|7QnWv8D6q*CBxE-sreY#m|7Y+n-Vj3J-QM2e3RcHcp_gg>14r{OWJd30G znp)~Od)%|H)t9fiPW;#|_S)&ejw3J1vV5{~`SEgbUg(k1^E($lskK(r@%GudKu~wx z=!s#e7DpIEeDA`Fx$$0*bY<;k)4hzX!M`!oI3=~}!lww@M(xend?FxU-Pj>V=&Cev zelpCKNxUmHc?!Fkx$#068~p5Ys_ST5*U@czeFEzC;=$+Rud2a)4jX%WTmj-OudV4k zLjb>C5xt*S{C?m2$T4Bm;M&&VyFy@4SKp@Lb73~aOa5;>p*JdCHPtG$=#k?sg`4@aKE^sv~pjEn_2mg{CT#E%v%8@YIUq# zicOi}y6>+(yzQNi|H4-ViqvAco+o_#8qb^U1m)Y>rl0CwUpsOThbCv zvFm2*#3O~Y8ua#IITf(b0Ui=MXuWBfc3auD!OOj=F6~(`4(s8OCjauI5HGTx(XfYz zi_r24E*$U{z|V;lFTx>oi}C)xW^BvAe;RI$G%_43vRW*k5D0HyfZ0Bkp_`nnc1z0I zJ}~f_`|#k$1G3zAu#+s(>Qa43NGIOQnKNKrmc=AS*sjXiAscI2_k4!eC~U9g_d$q$ zb&OXzjj^@MZOUDvxNt)9=h}`Q9=p0--yNgVG$S37JWE()SqQ+3;+u$V`9g_#+6Vs$ zK2GHzb|W4hpjexe^Hz?x^~wndpyf)<%{mi|Hq9NIQ=rX(7t|{7m|I1?Y}v@;h4t#e zC(la+>fSD6E0VZ{cQ};i>FQgG`!HimUu2r1BN@!*Mj)4}yV89LSR8JRNF^-1(2c(l zFOnad*7bAXlY=C)@$Zr+40jiRcLV>b%yalXl}=IWJ%Zt#h9Q8DTMM<%b@`PU9hdkK z2bDl|AxpQl;ds-IkaG>^Etr$p-#_^sCyt4OWC5jSOk8ny);_by7^}G7Ib+~jBQB8k zdJC6dK4=czUbOA9`BQ?~$-Hy5wMnYJAekYL7W}qzMG+JhH7EQ7y$5Xf6}Qkhfv{BB z@nO!OrPx7bVPyVzd$CH5`(bT*W#uDk`IJI3|4zeGbT?oTz24T|&;X`|f+MFEZPZ;; z@x&D->Hn>UtqMgkyKG*Rw^aKvMqv`4v(4Iu7xOU&x}9+Evjf6p2N|n~2zmPfAv;!a zvof1aJ|AhVAcs zH344NCSDxATxe<6#^GlL#JN-G8y92~^rMlCM8LhXQXn|yJP$>7|MS?`-tS)gxaWXk za0xZ}g&)nIgORygN&l6G4T$IL@L_m&vABV9jBPG&KI!kLRRW5Y2@?u&JMSJHIQ&`| z?;Sk6I6*byxTzt-52&)Ry{iU?>5hpJk0M%CWp^J&ULVi`G%QSHi%=?{R%uy>8zj}j z@wu_~~(WhZ_40&U70 zRVNo&ie$G9E%1UPzsAx4mN4mEfIq$IPg2#$Dfsu7`;7K%g2OY!&D*ejc3r?U-kf*? z@T(h@Y>EXpIY|RaEUZL8Bib7$)?qiXZV21GJu}-id^?`qdVPL6{XNSoKiuiQVFK<5 zdFt(RUZy{v4z@pAxnCY#PTj73z8U=1F%}^2t_+(D3wO2^2QpF6E~Xv5Vtyg)&k?}2 zPED>E?`Fb+FaUypW^)`vj@m&AM*7JG87)_>)Y=wrl*Z;e#}xK?OM;-PBkW|A+z*T1 zA(kr2>R4R)TE+JaA^Y=st=p-;;F}8(dQ_by+XKgK;2V=tbXMKJI{$3j3vReRDRS7Q zjg;hC(wYAmgZm6iT${UQHpf1hYTC9_+c)zlwCx?PLaF|s$aGoqljoQd+ve4-R_g$U z!O&4W(oT0RjLD9u0PCXSQp{H-Gg5K^zb9BkzHK?#ssx^|5l``Q?h4G7S0Z2PG7Zw9 zw*U!H-*-#r>`h?@!LXT`yupAN3C6O~u4Lst0!z2s*C)QWgbe8mCE3I1)rSa%giQP# zQn2r+mg)e%Z>?H%-LTAC^l{u$`6;2i`0Z!y&LAp?hWKGR0{U|6edYJOPmR8fRGV|R zZbLaV?Q~MZajhGm4dJD_F%cwvyH}622#)2Rbn^A_AnxGu+R1MPB0`@e>mrAZA%Bu_ z-c!L{FGuhpvX65H5cdM|#XTC&u%^5eiw%i8G=L`T3R$!}$F*0>@HFIb65Qy(eZ=Lh z^)l9rxxo7tkJ5HXm}WCwss$C~n=`)f>2^PoH{7!y=?d$}P7%P=>p6?-OBEKNQEGhL z9Do>q!|{sq-QGla7C-Q_c3y#HBC##UQn95#2fMG=0TC@JEgD;fQ}}#7FfhpRre{PF z#7b`!zDj1|>;OnF^Gz_u-EFGlY-#COw}%50DbsO)p;!e5G&2ZrSQTJrat5wGUO$hZ z(it4%@s_LtysdP<`lFhkIPtpJ;AQUuqfpsC?<~M%zCT8U5gLh*&VPRy1>+P2BjI=_0r8Kp20lg@TR9f3S-JK-)~@hO!Bf!U zcqWB^GG~NpS4SC;N@${!1U7Wb1hZzSHbDL=wCdQ7;K`v6vG`&oKDtYbNKAzwa~?-x zZ0#Kf2b)oeivQ6k2Vcj6oy2dW*m_kZ&OZ?9?K~b5QGVc?teqYjrwc$yV+zC`EDk-rC6D@zH=EzHMq^5-&Et=;= zFJ?IJw+}HG`Rg9c$}BZ7o*B3p5h|P>+^&B~{5PqP9u~I{!2#&^oTQ5STo0-9*)f0#T=)o2})19o}_#W~%&)fERHRXSj&x^1F zg=6{FqiN<}H1FCc2vPloh(Q&e-gTY=zVX5_J#&{;UM0K$Dln7w{ZJd}sFxN&3&Z4$ z*eBz ze=OC`5qE$Wq3loIww`8qb>+N2U#ShO^d7K27#D!@H8Ea zUu*MSE&Z00v$G=~TRhi~D3K93zEDsnosATn*Yz1aJ3q+(sT~PESw(*y$$aGz9l61| z&B^Lix)L@MNywnLCTi!!&-wj%;%o20=PyI=BH?VzCP0UwwI+&^fl1AOS0wEln!U*x zNE!dJAcw-(cdi8usoP5u_nA`p33r%oxct`%_IdPR$MLK|iWxVXB+_l=Z*R+25T<&9 z1Ha!>tg|P5?pj!35Q_w+QaO|Fvg(|7CZCTbSvnFf-hno|X8)t+2nY4`G@|gs@x{ib=H>jiSE0;$|D?K5KQAotK7M>!WeM0uSi6o+ZiMkFR??=-us-v$ zr}v}{0$gxQsynW2M!d#sXa*7v^;3<@Pl%`ErWmLYm|F_d@?iRG4B}9qB${dWo7k-F zxZK1rPEKVn9g;ZS7|%xjA>_%A*JTV5ku|L6yr<;a_&uOc%I%q7&ajaj&UzG&6}!*Z z{LXO`CaJUhwWpwW1Gy*MrpFg*JSt@&qL0DPq^}F$a1p7rD^A5UR z%sv}#tGBwqR=?2D9-AkSK@!!~Nc^N?I5W?OKd0%R!EB32AB%m68Qj1_nG75e+Vf5i zl}#=bEUXD02{CBqhFNK7DIR@>bv9REa)s6UYlPnWr9dU40bg_UMvutJu=Ch8R5Ia| z(cOSI2xJN0kL;`=WP@$;q7M`9Z&$XYb0=OUnn3WZy0lpF@qYH1l=Fd-26!xbgE;XM z_o6&!e%q36+-LmXK?S<)FcGq^$b4z)=`7)e8^aUGi1Bd2_)(yqbYpH1nFrAjGoza)b@oK z!TXF6+7<`lU=NI8a+DF2l#4ch(ZN4P6TK78;sJ9*E3NDcdiS4azrYbVWfW)F-zC5l zu8{^DoR@?vdwT5nyaNfqoszw?(%?&vx&C>~KwQzvp7f);r#hZfQuDaG7PNP>zyROC zYC0~LhUPl0br1*Ir&topc=(+I=&e^H|ow|IoWQXgDO*ejP z9encRM7Qm4Q(H!duxD#MP=L+0QEk>S7jf=bv=N9+*2w`cAt%5y3{bSL>liX`zo6muD5EJ-0#9LSkb;(2AxUSVM-UmtyU zc&%EuTV;JXTY1_UdqR~>hnQY^V6mdHu?KNM&+ss51;*-NzA($mn^qsj7YTU0$e;5L z^pF>ARSNA%$roJMY4V;e79i*JV3odxYQp5`DdG};CTX@ZF>%?Ru$GvbT5^hhV-9XT z{&tfVPHhf;o_OAV&M}uV>`!&$e%`98<=S zb}dX&F7}wpW|Sm*(ycHtNl|{xd8AGsHg_#ZHG*YyoSZlH5Q-<_ydCBx>5!$b z1o;S?CP2EImdREWCu59B)oFBM`DBCmKAstQO=bNBUpsR#IsMLh;#>srMgQ>5*+Ui+ zp6o9QoMsg#LUb?iYkt()g;%g2@D0ZiHVg6@!x8S^bN_%Vv?89|=eq!oCm&A{f+u}b zCau1ls=IZ}T2!eb9%8HgwvaQ-3N<|tdo@Ss$gSbOHJ*BfC9G#@{@YNV=Y3DT_X!7U8j ziD*};T`>Unu78f5iFy>N+(6xIdPC<0Oow~~X;cc@v>uZ$B>I&%cz)73W_Iixx`*=j z!@)r`Br$y;9tn9zc=901xS3@QpjKgNG&GRfk{`(3UW35)$CCb~A0_|E$(8nTQpIpY zeRdf6pSS)x%7P~qtu+6d$|1X`Mn(8i;R8ijm5&uwgI_7C*oT&FtWzS@lWqPpx~I|I z!NcLxO?K;V!~a9qJ4NRfG;O=FZ96NrvtrxU%8G5xQPbx@20VlGml_i{r4(g09Ig) zLww3`!jQ8d3Vu8U+vX}Xg>Ist;XGbz05=@|aG{rbQMdYV#K9`&#R%DTA^ju4SluU& zx@l=;67%KR8E~Y@DGJsZ@Q^DttxS^ndaV`+aUJNtVY8Hv>Pc~FSD})w=ye*`+G-0< zNRmBHAmi{a0h@DvFL-OPe$lJDR3y1peEhmLDvOAPUdNM6SF4iT7^?$UL{t^=^>7|z z#QNu%GJ7$kk#mMxJB}$VheTU8mdvL0z`4_+JERo)+%1?yqQC zbeoxFt=b&{%ED@|c&NfQhx5~!Y22>Er=qe^0k#ns=h*HbY=7NA2{c>=Dyk4($w|ZR z23CR$)-_CsdDEc?Dx~N@u-a)G5aOy|@7Q!=F(V+TMP?=q6+o0|)>+SuQ$sU2Cl^bb z_i>UsuY|hTbne2q=!~?Om1>%1oeqL}1$R<&Pl4DhE27BiB5D^jVuSK-g}tq)ab%gAuzTOSx?`*v9sqy&p>jNw? zkWf0eR=Qp?9JEtr>G)$*OA>nu93QshD&F0HLk~AX7rTqlfFoO+cj=DDQKTWf7h3jW56| zfH**+iqv(@4?(`by^w$U`=~{`f++X@!HE^BxN{_<=N~LrHSoZfl8B_}`8P+5gHyKB zI03@s-O=u9-bECpp3~ADnYlg4V#RPYueOruc{1Vi@5s?OQIolNNijW2$EilI39Jqd6 z?*U^lGs!wwMne(VYFs~Xi%@Y_xoVcq{2QbKWNz8Pz};Om(9y8~YzoTRH+n$A7fH1h zz-~B-r~ob&6Kn=XH;|gOaJ*1b&6c$*u=9LikZd{;(9hQ9jR(KsJ z*&S$k+^sye>u!#)p)Qs|HFX9qq|NVzDD&1+TlAOrzG8}eyOwsqX^qzN9fxJG81Rs2;rrw&ftj{0**Z4cKfm)h__LJj0n7H}6d`S6^L&NP@1mPm6FdMZ z-YH*L7Igmf3aBci;dEgUBVXa65-DVp3E3-XIxR_|R9@vEaWzv05!gF$A{ezGQKZ&! zEnpa6bdMYv=RMXo?MG#YUrfi%cWDjRK|(B=k!Jeo?}EC=3`_+KFdLM~aug&l1iHE1 z$nD+mtj^_m-18F_k5 zr$d=p73ty+vteOkrII*6tnhlnW%KcS4UTjo?M8i@}!2_lO3vy*kFPt z(1tEjCM49+;{yVtzLo3M1fddRXE~4vU!k)xIA4~Qm!Da`6pF=)mV~6QtVy+G*fwEP z9c(J|q_q__f0VH}U;)lQon+d$^dJSkOP|M+02>_1RCsyx)`|Aq6+aor`v{d1wJLP7 zL)g#vZVIeyM3-4`2lY3>KNBfH21Vp^f^46w^r&`^@hu-44Nf!Bf(cK+i7X710&EV& z3ZYsP0R~2fD^%)Q6nfl0zliD?Jb4M@X%UV(%Sl{Y;)`OoRX-$1rlq+JYPgKyNxmw2 z)DG3pA|5Q*V-J8jTxmeFJi|!6%KrsNHKs9BA3^cGLWYCav_djP{j_sM8-+OMuEmcV z#8}40FBTSl7XjHm_M`z6PRe4$Yv(=KGWH9!)2_J@VJQgmrHF}BnC-7&k{bs-ix!29 z>OEBo315tbv$H|9;&OG5N9G3a^%(sLZ12~q%-w1DrW#S2EQ2{yLvYCmlF~7(HH_BG z!o6QwHV9zfK@4}Y_w2FMJqaF)YxzXjk+fq^zu-l!Lt|>fY!+QeF@he9=>RuSYf3s? zdezs-NYJs(ehBc;f-|b^-Z0*mBwwr_Pc}))O*+AIUghQX<|RuU!=-E2$MHHbPT^H^ za<8$PG=#mQT~DeB0RGl2&A6v-NrQzH?BQsYV7tmuAf^c&qT5x|^@`R{5Ca|b^41Et zGEL>*GQPojn}RKIJkivr8?izl4!(mhIZ5Q;Gu5Ulrx(YNA68}L%k6y0k8VA5L|3QS z>WokTPPLZX8gItxF?gynt^2yMu_N0t5NBf9@mksl)sCnfvj*!kYKlt-0b*=JnbUtY zk%G=;Xi-mfnO5>)>>wrEvaQ3WZN*IT!=VayNNPrjKmh-3_oTaLBa40gFRGMF;E5VZ z4uw3x7LI)?1J9TkR7^Hjq5N1fKy}JgP`Zi-qkp0X=9xWXQ><`4JfBsxUG@5gmzJbo z&d+&Jk)^%hxQK0EjI@JiQDaL2TvKeS1xtsW(d)53y}L+h!IEO7U)r*3Q>|TAS1>rWTEAVW|MbNO%+24 z{{m5#A?B=oU`;FLPaxbqBAwC>T$;r4P((}FX)*}LncKv}vD{+?+ZsZd=t3*#k4n~* z0MHGZ!3t*MN~IP1>%LTDf`_iPW0*p3dh%3?=b@;V7E6-yU!FvWeXn_m zLAk@136_MpBkD9?An9IN@k7(D0bFNLPFdl+*u~j>h7g0@zJ*J>?$n3@XJ>&)>zvQ% zMEza?&N_HU>I-Tf;)CU%*#d)1b+VHk0K0Eb8}s-%Vco}GLZw**jSr^$hTW$gjIB=G zoK7L)D$jo5EJdd2gmElI6@2`i(gv=`{#yHjb`=1*<$U8psw%jIm4#wewj!3h!DkX^t;Q)SBOZha#^R$2KX_0o=ZsD?k6RWq9$?*`W$4T}PX~Ra zt{u)O8Jk|8l5r$UWTaZr+KDO}n^NclISb4iZtW=WuJNqyt!H?NBYN14%6b)eX!!ds z*}2GnX-SU}P6dM*zKk^U*%|c4MSf#~lK@->vx&)==xVu3Ima|$Ok+72QnuRk>1Pej zV$YPyRurfSn$a2rtR{BBWY^b`-IN=+1Mp$!44))Fgl|Tt+@s!3+{FX4ki*m5sso{X z`{h?@HJ|(p)4EKeh$-P1aFhw;@J{EfM*kdf{{30={n7pXmCOHq`o2+7-R^`9yER?E zqPpCRChYB_8u=B|exs$4^Q43}(to#!qhFIIfNx$uxIU(XU@3^RSc+!V$=1<^8!cZ_ zd>8sD*;3||gB|S8p>G!-y`b)uGs5vVJthxwrd_vNoY}OG)BkdIx-F1hO(4P13p$es z!SPfYrm-WC%Tznj=7v667{m5t>^JQGo8#6aFiYS8|QK@lCF}-PyO$^c0yju>9Y|rri zRI%w40F|7kDLPkDie5W#}sydeO4Vr3Dy8o_xKhify8|h*1Kv*BIXZDZWC> zT5#TAXMJ*5h4|xV+<}=@1&ZNNKW#QB+6!;tiH?iRmy%pqUUt4`vc7USipeUS-wHcd zY*{sldKVf&7Nzer^xuc*xHCXnEj^In{x_z+DKXB(B=qZ>niVoz`2?H~ARJF>pv94D z)k`dmDUup^VnWVzbb)rg(MR>{pp&wr=@QYVL%f~UU=X}WX|YrwxB2OBfG5SJ17)E& zx24KK|GU14(y@5civ72J!_sNvz6VFlLp0{m1FEdHw(8pG!A-pzYtCu)Y^*X=)B1UBW=v~eNSWV)E*C%r+!4<*flpqYGGiKK{DD2S zjx~gPS%FE)pUh%XfEN0bamqH|M7g+DzJQv3x4w>9FvAB#?NoUhq6N``nP(*d+lP3c zbADYZb*OgLv+<}i+x$H_{{iZvHfke)EKFaXg7s-dY@FM zdwA+52dbP_O2jzdXy8YYNfngd9-CZMQ6|-ItqiqaB1bGDh^~|AaB5{xKu&pOER`Lo z@}Pvh&9o8)oTqIKI65eLmF&9>jR`Jc{^GP{049z^@(*;vh35=#VzN(&mO87d$DMQq zkbh1>CeaCHyJOPhI>|gA@LtD0oDj`{FPeS*;%In~N}k^arx_G?^qb6HJ>L{n>~>TI zLt(Z-5I!H326t` z=h0U>z~;U%tC!MAN8lw}I@=YFFV`rA0~wPzu4dGvzw(b;jU2`3rb>&nE^ws;DDsU* zRXiBHCbH$|+y1~xf$^Emz!;L%3|Wx;aL0Yunvj>zvrQmL$Swhkm6rTz`HC}AyD#NK z3Tv{)38t)?{G(^4vc2y1bOYU$fd^nE2u=JvSn`Q$x~JkbOl}DLx7X00fnQI2oM*Dd zc5_Kv($**tgK`m@)9eMerXhYgZdL2px;T^(mwHO6eoEh7%T2o+Tr0fDC(GZ&5& zJ>P+H2gyAai^IwhGl^638497M-u5F8np@8G?=HeLV0EW8a544$=Rz~(T|kkm+XcY4 z)UkiRSbXH{-5Zf>(mCT7da%?0sgd(KYsEvk<%q*?-epnv^(rwHOphGj_!_J-o7Ip` z6BQLl;py0Ot;>CE#RrP?n?r&k#6R8Wzg6JNvz^9E67B~|O`fw`7oV}0HLgc#ToGADWbw0x>_K3D&E8P}jOH>&S7RARRB12rbdu>Bo^mK!8b(F})YF51< zq$cX9`$M+ma=kB%S$J?%JK+S(?dgmm9M6qeoBUoXbIGf}Q-bcF$_*oF-qgkHuU=6I=c7OC%e8V=w3e~GOGBzk-d*S}rx1fV z%Y+P`?}eUEu>Z}(GP>YT=6+1f^G7THe={-G|Cm^m+NQ&r7+Tl0%(kE`1BMbU^jcBb zFlV73;{=dPJWju=I0o#R*4pC5*uVqz{MG>COym?R;!Md&f1|Tr;X7$BJxTgmAHn6% zK05X~7SHPJm{zg`r4j~n6MVq!{J92BqmcbLp^#3I<>#0rVRmD{F$-w3%+;IF(nysSeQ*LB1U zEp?jgNn6oL;tT!04OjU4Mm}RS3<15g!W7v$)p#M6i=Z5Fpc82Ct7e=Cm(iiG<-&D< zX-`{`S+reJgnEt{V3JEh3&b*t5iY`dOuh?r3FzPH7hTZv;ML_vCFJ}<(7kpg1usuqK{R^=!QanwTTWh640};ObRi?|c+gllA6K?$C0OH=UwJ6v{6RebWDYVXNWdGsJ7Y88hv>qm zSjGHv$9veuEgO5F-Q_hl`f+n}b^BQpi)c&u?N$r0Ue8d8oIgX(K&8gq*tYe3J+65s z^m*6SbQtNr{yGTdzD;tY(%M%)=py*z8wrU-Z(H!vyw!zyijM|c>*MHtKYtrZgH;K?{yzBSu#w*VIEgfN?DNUa0DM{-x%x!(ts;Lt|f)mqX8G7QF<73^T|B0iy?Jlp7<)@6BVI` z9wh9k8*t^(jWSb@Ru6E_mF1Ns52Wp(kR7h@qMP~SMd(BpPzDfqoaCS64}+Z6nByJ% zaY~Vvl$Lx2vJhw<%=Tt!V7Z=j_`ZFlt<>2igO^Z2jVppe$9pwG6G_ZqoE}1?&A)ru zxu1Uet(UQT5GH~hQ{M=(UeNeUrh(Rna=eUxkcA=H#6LGKDT-y3f+am_*gy8L0;tDW zRj{1rK0rd>lkgXAyJQq;4}PN2k#U(wf+Vma#g`X^4X_B)0a&OW#BT9Ck(^^=sQJY! z;MV}OoV`PEaNy_HLZrRcM^)B>WdOa(MkZF}9eMs70?Ed-jgVUbbg~IjNQEtZ*Hp?j z!c(jrmRcLzE^Qcu&|y|iqP0d_!Rm;LH7FG|&_d8YgoI z))7#7ky(hf>Laz1)20dsa0r?{0O5ue%Xpq7h?<#AwW+aOaS=W-($B-Er-0Jkc2}Qy z@@_LCC<2aESy5)Z(&2p>0rdqR zp8!=uo*|zUpN(2*?q@z4oSF1gL7_ZjA_yMWai{6`K1q~29*zTCMJjyIBnRUVHvttf zry7CcDXqVn<*!9_c^PZ^Vj&Y zyk=o=&xTHtsohBTLVLDe}0OaUleq~_tVMRGrn=!F;%^3`3`s7SR zm5RqpF_=ViCO-B_QS~{-T%2mtsY?o>Mpcrf^?REOSM@x)DCKD!G&>aEXLHiE(hVKn z5Pdi(|8?;_(dSzw2bR>A)6*b+XZZ^Cb)`KxXhTk1nkBDUbg^4h0|9|;t%EJDs`S-; z>niDeRP-bsCU%GX38z%dMseK&uw2yI7Q7s{n~Q%U39ZHjD0x21sUMvd#*u3*PYL47 zQgBJ6;KYJrJUdj+>zjbKqgvn_yx}bd<5+PO*`6Z-J}?~()280`DeHjGIG3eDAFYZv?U5?JmQ?| z-#TH1u~kdby}2PPNcCK4YE7E%G6YD{f`x%vg>Vp&iq8}23=Gk=Z55qQVv!JT@A8aG zECfaRTt)pkOC)w7YnLc=U0>Iz*Wak209wg*|PnFQ$0<-tmVm)%WY=!RSzt8Rt1P@DagrV@ito1Rn7% zu<&uJe{>g8(e&_G{p-n={@N)vVRBbL0q)m6Iu9#WjcW`=Vgusx(opCALE~>1x%bXl zJ06}a&d%M_wVRvTZRsU~$Js|5SL{E(FP|XsKQBTH=jQtxjQo5MLks7xj4t5B#mzCb z`?va);UeWW^sSS!oG8*RUI4!AYMtJkeCJOIk5j9Z*c650lE-6*o%>gs%yQp)t#wUX zyV=R>oAU=#9;Vm3ru!88k`Cqkn%6w<*S_wz-SU5UK8qXbzYpN>bqV1KbDY&|oM&O~ z(N64GxVSW1JGWL(5wD!puBu(VDD>%{L8gKU#o`HFm!j03=hZfz4VMuMdLqG>{F>j2 zd>OgaCPBoX4@3H*HSk0mSH&g2Puvn*j>`#;LP?->m$4p>YE!4D9CdQ*!dmrCU^rq# zO%K;Rj)!*ATq+4?P!D5j+7Sw8?!A^<_-4ElqHM@Za>+^A@Rv`j`2D=H;2wQDD?A$> z9jbgC9ISub1q5Vysw?86yy|=f;#~-2{)eF@z!C=h3DO~oW2@cK(%I6}^!;gRYq&*y z_1$w=lG)ztmgO;a^T6&==_%dxb%M_K*WR5ePoo!x2H*X7F4MS9nlXKpc8>Ak^oa_+ zZUSy&>cfG1{G2D`F=$`M?+=|Xm!{uxu9a~c?VE|A;jMI>%$bDSA8x7D?>KD$2Y0&5 zH7vt>!0)psJG(i5n~lUw#V9*?tOAIYi<}33+(+}4RVq@41EyT@&_>10mHu9VZfour zz9T)aW@cVY@1*qobLBCT+;);?DGisL5=0^{bq@mvd%Aw+dN7X_F;l0dzwYK5yDxu{ zLMDdgdqgHq)=Y32&ujI}SC|LllUYI^vlRT}K^RlthkO?3nMEx+N9aPTf_v8ferj%| zaOnuwV0sE7y(y@Gt1KhnCWTaOuCI0VDg9~M(_B|qIjeXIT6{uJ>}pid^XkM3Cf-~f ze9oE$t@>?A)B?sN4L8^@hd5}o^xLUs-Q2y==B9cTx^kaPgudaZX=7mSi_I}fR3Wx= zKX4kJ8`NaTQ>{-l<0`fdv{qeG#n0to#8lc7)$1%V;H@=gT&Fi+53&|&v7_P7BcozL zP}HSwqqpVzTXytj)#B#4y87nx?J-`CfZFAdU)Hdi4)GygJ;UHhxyKl%9^1JFrDtmn zoP6Twi6q4_Oc`J5dL92ykTBW8v9{UlfEJ}$;7eA`GbgmvH z2&un`%nI|8%vmGLr~ zj8v`}OvNhXnJapLU%F{HL(z>C6-n^&{pJf-^^(KNEM;N#YOTyQ(QdL)F% zKIP;`{>0#IyRgV$;&QretE=}|ipvx|{=Dgwb4E8+Q2sw;{nnBpX04!Dfo_@^RY*DJ zorte2vU;I;b=b-;P@5;1v^-zIxjjN;f^ID~N`ln-P{a|jE~*!n^xnvH91ZuoIvipc z^I9Fa!e@Nw6Q{g!4Rd;g>j9nT_+SO=${50;0-+D&=mNTb%r%O8-yaFANXS@YyPDey zAxEuvk>9kj79D(?iD~vEEzx5vL{xCnCCM9VImyG=6peM+-7i9?8kwW7DvQzB*r|nS z{+XN9rml+5|Gld3w44a)(nt?xb+5Amkrk+NFtd1T^nFebDQ?s+jv4b$@(BKi+3%qv zQ&)W>*y(N{8*I*QKE+O={>Vj0jqfLwP95o3b?vGZV~X8IJ5^(4mdVNClMK-(p`)dS zMxz~!fkc(41^*{Swa-Vr4s)m8873M*Y!QvNp(+;y{Y|VqpU0u85z`u;sin)M5LMmD zt*aw-eTfR&F|~fH33Y0y>|A~EE#yIjL$kpOWipt?)1Z33*lfmRt%_oH=Vh#6b|lr1 z3o@7|iy?}CjinR?K^NJPb99!+hkBpbd(Xr zoM;C~8C^W#U{2&jIP>MW$MnC5!F-wOiLJ%Eu)0aK<23@2Leley)hUUbDPw9X@fmR;ttLzP<|Lg0+m7|;(jA+8496&qOEnQk1;U^|FXei z)zvH&DqWzeGl=OJH?c=6g05GbKS@kUO@^>-^J!;n?%!E}6ayplVxvH1K^;q#L#3D! z*M`T_Y7{iwb4NooShrFc7*VvBx3tXCzheTH9MGEzxZqZN{%|wr>=z&NLR5b%9w(Rb zM_KEeFJACA6ZobLkzik+i}Uh}$)j+R>iqz4HL!5rKxq=2Qd*p){GL zLSxjodLQR4{2zxjG{%C1__R4ziw@0uzmb(<0g(@+SDs?LI#Y^5Mg&rk*y&>NGy!3= z^=yHbSkgG{#MUd712RR2MvYq1CF-Wi>gPlahEFk}xg}g&MNT)Ei0_?{o{1C`;Ttt1 zcR_37+?fTM$Pdb|ysDFo7ri(4zdrN%Dg;@$+O;=FOTPhE_y-45woTq{Vfq^{A0hQF zR&B`!T@2mdpOLoR9#8Ar{GM;Rf}t$Cv?B6v1jRMcs z6i|x&`}5Xg#*B7eh}Ith1ByL?oOx9#1>nt^5)YZ=TGQXR-FjcAxj(E?>2vv}ffXCal&VzU*SA&MF3;PC^JCu+;VLuY`SKvG zQ`2Cx-N2)QMG;#F1VqDJ(z;a75i913$y5*JO-O~jlm%IS?#{B_%b)$%@$r~zNsd&u zOAal=PeV47!>^amktvavTZ|`m;|lTDuO7WGDFx+4IZj}5gAC$poudf_s(&8FcEMAIEld=(bbp7|1Y)140#}SFAe>g8Xz1_YBE`)zQOOi6vJ+f-M@JG30Kb~ zIC5VYK{b7kE<8F-BCOy(1**%_Lf6qC*%(Gedh%KqTW8D*Hk$ykKxM2kN^ z`GdFS7r0eq&l=99UvQKg! zi$JmAn@701wEIrcD+9w3;N+tba?qLcqIMqgrk>mT>PWbf! z>20pCS(lI~vG@z4F7iEI&Et(5#a%Y$gK&fI;jm@8`z7>;FLnFM|2-Ue-BrUGD%L}l zYIn60LnuO{C{6B#NZ^x+6b}lm=?EGttq*N*!xcG#ZtBmK6K5Jd=+9%16XtaI^0c$F z1*x7$suNOFoi=JW%87o*MR*KicC@EPOt#~N?> zL&(V4KeGz43hQ|*@OYC#vf~ZL4PQZ2G`N1vIye4!NQ}<(_5D1`zEox1Bz%mGN%&EC z-(TeBI>{4UL?!ea1;I9;?1QUp<79#kH=nRP&@Jn=>tsp1X6(L23RT`bRF0~Q!Y)kU zAhKpUp68SVnnJ|V{3`h)EqPe-Tzz@H1@Q6qbXDD69oWmY=IRqiXelr3(iAHauBlK8z zZ6wf|LvlBdee{mI`te_+sFsRgAkRKBpl ze{Hj&<9%$=^1K6;ih=;71o(TMEq%>oXbsB{gjNHg7uLdS7Kfaoe&D`Lp+bcToCD)Z zXPDoEAJfN}t-?Yl39J%bPwoWrNHtN9AvcyLqbC#xT&`15f;z zvp2YgLRvmtbo`J|xh_maX+bG$yiFj*rJReaShn8JQ_A-FN<=4+`=%p#wN&b<;^ZQy zX6OR+FGkAWKZn)P?s4-ygRhEaV5B&QlVntA6nT<$V*Ma$*sDsW3*6jrNd|+lD)Y|FuKX4wc$Z3XIAzkjX^=f!ZTz%6x&sgy^d*D;f@zhK5Q2`FCKKy-$w| zS>OWw7=}sR4Nu?jq-R2jMPX7OvNf0*;%2UuDg;T@7x+R!q(jHc-(Ti(a<@~D2@JuF zjJZ>hA#6hWLo|nHID6pVZ|F6V5v6`8{x#aiVY(u;{pY|khtJ7+UVdj+5}jO6{_T-jsjIK;HH9I6_9d^rU8+N@TdDt1XMa3 zr?~3YJ%W1p16Lxj92tG06K8@ed!Sr643e4HOd9Q70*D8{776DaqQ$pa@Ld8g!I@3^ z1ahQ*QuoM5L7rjMqt_!q06&5tk|R6rE_yzz9fB)#h$G@eiXdFbS(D#a#3hPvDkPOr zA`&7^lI=?X3Vfv~@i4hUu|YUo`nlfjpw1|gZGtXh1f#2!nCHsc<6Z5jBN)$G5->UX zhsI@)ryWSYxPGPx(m*&z!SKCSCk8Qg^e?CvKR=wMV+hZ? zJs8doj@AfVL91Qb* zJW0r?E&*~{v=hm&*Y%7AD+g-4R2(zNBkWn9amc&qmI$RJBm?!#+wVG1!~`4kN%9Y} z1BJ?U4ff;MsfWvg@L4wNA5uG(pt*P}=~*Um-muya9M;-94Mx90!Tp)Dt_T@e$lp|v z5_MBA1O)RaU#Eq7LoE{z39h5rS4$nq?VF0-nJI&{t`poEw3kC>Nhv+dO=r^5YmG(L zM9eJBAm7C_?gzXE+}Jhu3>EFf%nUj?kkzoQn2grkXhql{O5}5d8F?Xvg`yN2 z{RZ?1Xc;@E;=X=-NJE@J0nqL}S=z{{s2+0%$_5iO(GosNp&~syzQp1yXNG$w{BI=n4HBC4TT0z2B_^7`JHE1w9Vp^IDk3cUK0zvEojx#K$3V~U(1>`tTLmFS zXYXc$QvjAhzHGcg`RxhzKo2mI11jEvl7cYs=*(ir*QFtL%?&rf{@2 zs|dd9H|9#W|GlaL6PN$PsE}(e>Pv!IC$7eS7!P#(XFrs})eQp0exqLA_t{!pErELg%}E8uJUlE7Yc|z?@BXhk2Sra2E156#toT zQ+z9ksJ!WZ)J@x#D%jEC`Y3IDZ8@m@)37MkF1SZOU|elT{p$yf_y1=lx_mxIF8_qa z<9}F*L_g2}ZPoh!<=5xkB^~W%aZIbcSshr_#wego^m)qAkkO|eB3!!{Y3{bhA z-rm!f2c}!lE>9)w2)lIckPzN zbFS6W>if6y-Rd%zg9JCxG11lLb`88KnRW-81FG|&B6I|$D*a+MX0+HBL+XdXB`>v* zBnM(vR{dj~*(9y?^+z`O7UNiv-4HLd8Pzp_&+>g{uHEalEkUR-D9=WVBEIo)lf5a`5tL8mNjl*%- zJrQc`Wn}u8P}FoDB4jzw!>tS1Rbw1&M`BE#Xo9~Wc{SZAo-ojhy)M3dt*uJF zmTppJm@hZf=t7Gzdld)Ro=?o@aDnFpH(9M&Q9$E(sIqk%KQS!w9Js=G;SGx2zfS6Y z`6RsBCSAPTuwE~ni@m2M=tf;pq+XxY??fj!$3A}_GsjtR=XU0fKM21r_wsaDGQa=V zy&V(;a{&JHryIxz1oV^m`hN`G$;{Z=nBjlM|4n(}j@s;xJQ5In3!F@0JP(>Z`&C@p z*xt+u5{{#g+snkmNVcw{PKblG9%R)(F^+6c7=Mw}L`0U4B>Zb$keeQ`$s45Z@_2lD zw%A=K?3zH`B_509ltzTS!!;)oIiAUzQq%(O!OcVm-q=%^yZl8Z3R^#aS z&yA$S3fYL6D9IBM^ym9?-1htJctlEHuNM9LSl?h2P^1Cy?+sC-}7In{Jhhoot76E5!Jh$KQ@;C>>eqQ87qj% zo17m%M8n}IdkTKJ<`WZd8HY_5mi`K>rR?JYxmD?HKq5X9b9 zj{G{zRAeVK87K%vWOBn;X|IF}@Al(BCPkP#{IJVgmwi8Z8h{L-c1$Ki=6CwC-1^jE zfwZdKkZ8uyaM=k9vBvF*MhmmS0+B8^3`O{8E!J{$bmf;FZm*wHMt8|y3l}gjLfCWV zmGa(J_ZqJim4_BmWHHWLfWeH@W_r&{k+1QL%vYp*+hSJHPq z2H~_&*-j5swfnnUx|B#i*{4X?V9OwgYo-DCyLds_mG33%TIeSSkyk*-22Gh{@rZtC zQLZ;EfD!YbX%Kf&bM*)Z)!40!@?CpjS9C$?ikv+N%s(w}QAO;C;PsLM)=jo3YIvnY zE2X63Hvjbo2L;OD!Wv3hOJ#ak@uoKdQF8kKyo)!2fyb{BFgX!ev}P7Zxx z&c?dA2EC$8>LeT#S2&40F~@l+;spMA)?)0Ygy0;~ZaVM1;ut9YXzn2{s9DSgJVN6r zlkSwZSq;isJ0+!Aw_zP$PKUF0f{I6so=HYRj4=@b97lU+sKQr}VQ^kex!FG4g>}9H z?%3P+b~)Ubn5;#)KXh-_KR5a{@>8+qD~Wr2<0xc0Cgg}87Xi+34Yb(-1PX0xn}qTp zVw)VdJk+(BFzTy#|L`i>c)1KDv@{p3d9vvor{W5C0_wKUhm8VA0`LkrQ6rA+-*8gP zRPJz6CB=NA$7}4kn;TBcbuJI8Gff0rfX&5>k8c8XUMkS=A zhi;J^8iqzB1nH7SLQ)!}8|e^+E=lP+y!!d!%ke)rXXd&l_Uz|(?Y-t%GizPz-p`F0 zd6r?7>^0n!Sw_B&y5Ff5LfBY-feY?C!txXq^Hxr)D9 zN@bt!rwg{67YzA$-}%`|cB~4jnD+2UVg?~Xn_+%zGr0RyaBn7zONA#ni-q(Nzwhdo zc5_Bv1s-S&1&5Afwto1CBax zSp}`%)i4YhFMppI#IBOL?Caa(QzY>Mr`M{4NSQNRu&ec+`}kC^;Ur7NOj?Votr6gW zU-@mqv%|u{lxZj7ScF~OoG2A~(6WPtOMX#AM_i?-Y!!9Uuwh68Tg%-JeA7JbccpOA zB0tqKOCjI9v|J`?zY#p?cc9w1UXy-@g#&w>J6xsvP)+x@g9R~3>?WGFqUq*k{oJOx zmU1N4#o#<*{CF1zCYx+v@LkROtbN#z+YV|)cDTpwqFjn^Ro1Y`gWnnU(8jHO>)k74 z&#$idTENO9F!-s)`jJmjtiXWx-3FBwaI+8&Ly;7FRMvc9A^hQxRm_-h`5?QG@c;!xjs6En6(M7hRzhtPpPq%t7e36^NKXivnnY zSxVxRHea2}piZ})n`dKNQk6c+8@m;^rNCIK0Qj70l8aH(m5ClBE;I~Zk4mv08;Hhl zJ233AKCi4 zvTsjzi5%aCQFjmfRA-yqeNtFeK#j$1YJaWTy<%T(;u1y|ALTm}MDN^R{5|YPK&a)Q zAxX3Q8)A1pO_#*L`4~;txkJX*nLAzCS~&-#?HDX=Q}#0k4Bg&v+Jr;4Tq&N57U^x438?4fyMNuIlO`` zN)n$SqZPbEzgqo>34G~ybWd#T^+lpz_Qy{WKDbnZN@BjM%o4loO#ghi?Y+0f@}+FE zh8eFqY-TvIz6oyx({`Gqq$Sj`c85M|*!t_^@}8Bg(ofYCh=dM*>?iM})kS_#H`^h{ zf3f`0np1P(c{c6w*8oowd!Yt5Nf7OMNRnQ;P>sOQVf= zb&GqWM4tX!&zV)sPW%0ZcZUvA&86@pQXEVv%}8WO-ihGdeh|(8qHWKRR?mG1Mi~-g zlr<nL`0Dt~KQUQZXaV@zeGxdv87`p6Z>o^H2j7d>3)-8jjZ@s) z3cEGYUHqD;uRs{~Spbbf*={hBTuU%~YpUv1g%fajYwvx_^0Sk$_QTWFC73@mV?8q= z{eiqUXOe-F(_!~=LS?yJ$Qs|~p3 z()0#S>ylk9N>6$%yM#|WPTRhnM>@mm%n1C-Q21i%AKqi8y*x>TgI5$-WM@uKzS=O) zoRL>Du)m2rzf3KndF6uGh&iY~X4wtRi#bCe*G%#eHlf+SZaY9ucrB}R8)!O6M<{^S ze8yPMYbrrnzH6^^ypvb9Oe~9uvru#=2FA9xF%qq+7tqz)Sj1r*YUh}65Y&0+Dd_?VUCXl?r;@1I z*cawZL%vf;k{|rQyBwmP2q)wT>3lIX4hd(5w^Z15kx2YtR5|I)yYyI6=1 zPf|;)K;hJ76eIRiaeGD{lc4fyDxm@DqNPccisjYdfa=35s}U^_1P)46kMU|cR!Z^$ z3Iumf?Q^4543kYOdBAim5m*arX9df`)fMK{7IWrB+{O#N+=4hwrU|Y>ND$Fh(srFq z2Kch@X|_{`PQScyD8;R>{0xTty0)kJDq>`m6~o$ZM8T_X6t*1hh-WJ1hJMA9r?z-g zOHLjd&%i*DDo&{X62Xz8;G31=71dPJ@$AqA*B~&@LZ!6o&c?p54(BKn7sQ!MmkW(! zD>uOjPJ=>VkSp>q^+T~LiGH6-H7^MHN1{*FXe1ehbEiRJ1!V!l{N1SHChvm~fTWo3 zqgG^2Scx@<_J%f7yxD0NZ(+qy63cAKQWyR;`Sin^ z@^`yQF)!A7Ur>xssy$Q~)7k&RijZhLr|x2f6o8-z%xo z`e5#71s91IY|Xk#Q4uXE$jTr0K#+RdKTYg2$K<|QtR@@( zWLGIR$Ue}@xrlD)NGU@o?%+_pbk5hiwGyA(r@AqjY16$JO3(_?wa6!J=eE*{(hVJ{ z4Acuy6`V>?tZ3~3dB&za{p_~a+GGA=j-H?ZO`np#I-Qr$*4g4Y2^~C@<<9(Bfz;Py z4DVF4k8EYgU@Zl9S2kz|cX+AY-CKC(LrutR3tpYxYzpvO9ATp3@QL4JJw6!w5p(sAQL|F#Zuu5Y=kKOXBAzKGc8T^;$n=q#<=M!dt= z!{}Y?B&&LQz8T!m)ugf?=%1P?6%xJ}dJxz!)Vpj=C-Qi5y+g9Ec2q!cc`=gt+tMP* zlCRhMk7ftf9Y>JJxt6ddh*pF!)#?*f?&PjmcY!uFql+N_RD~i~AHmn)TMQHMF#i;Q zFe;rjhdRaDUQnwS9h;#8P=*ZV+?tXUC6Q+xjbM%8Oh??o;vof1zvn<0F>(Eg2+C|v7 zp5XA2igSzM6p5I3ZIEXR$!xP6u|evr!dZQ;F3_3O&65C(fN37uRR|vjrJveyE-ykM z3)w=iaHln(Qkok&)UkYtAmD(K%46N+rniKcT->}+x^@zDHW{&Hp@y6}>XLE<0Vbc6 zD(nPYiZZ{XUI>957{5w7UY$d{aXXsWrUV9(6V~%(cY+CXagadw54x!*9wC{vMJjcF z^lo<|)rne`CrjYw4^)@MnhPN#KOHsqzhoyb)2rn8Ko9&RxsTD*uL069`_c)b?A)Gc z!5oF~HukS6L5MU+L$w0MalUz(k~>lPjbS^8*%)-{(@%(-+|p4v**Rn*w*#T2rvuAf zbTv8~9VIQ21-XcuzoI#iPi+eil;kelL5m?h&3cpO%mvklW@`hb{Z_~MV3hMj+d}Jj zX0f}7@%c_+Z45Qi{*3R8rx`|p{v04lhD|vU=ANWlf$urfrsvV%5h?Ca{|J+I?)A*j zz67?1ubRT=Haydcz>Qpaqut1ug+mqrw-Z47=+bEKgAP`63-s5gzSKFZmH|q5ei0n=-CU z24m@L2?8rPFz1VK@{l~B3dLA2$&dEAC~apYv}0HQmT>iSkG%R*{yIT2GDr)*$BgjKC?@>C z6R|c>drsu-_#IOkWlMhV2NLU4u>*9?vrcP-^l0lt5N-`NJc(#Z2r~%_Cxq?`Mv62F zTSO-GRIY-(MI3I0=V?L(T)k^eC81j^XnPg_9#J4InLAE0Z~dVzkcqwA{kAsSdK|IX z%D(}Et9zUsf2(*7gL!FIeQh(U>xVoyZv2u)t5h)K_8yBtIDpSKR*(@gSrmX;fh6E#eGN`nu%Twg2hC>cVCre~DX;uyFCqNoM- z(XG^hFBGNk!HJs5#Q`}yj+mJcPMi=7l%aEZw3-1J5gNY7kh@bSy=sly=>e-uQ3EEe zp9}L_Bz2!GMR$60n{AUIo{ua0&08*O;njA%gE)#TuA8=e-$)RRpxzXNeTJ^~%VA{~ z2U@dIV(L9k5YgLmc86Qnral%*Jq&4J=`&5-I|XOBlK2o z&a642f~;eb%D(y@4j;jZq`sP>3VV})!?HrCo#0PB;JhCzx+w_I1Bv<$352cSYg-y^ zaZ%bD4%v&1DE-6u6tfm}Vo^&XMx77uE1?Q2l>_V;F)c>u)$m2~Z4u3-eaVpU-m4HX zM2XXEPG8m=!N4taez;hsEkuWg(jpGw704Ro3IWN8UEAAg{Bv7S6bIj8WwTdsqf5#r z3Uug0qs5P}&(cWzhxZ3t2AguHNoeI~i%RIwSB{n#lI+faid!>P_7<0xTXl=$_3C3E zflx{@qOgvLz!1tDQHM&AbcsRaMx{?RIoc+C?(jx`1wiv`XQ^J#1Ncs}oM5wgO#G3C z7qWe7{tv@VdWmP8TWychzZ`};!Sjdp)Gi+r0dKW))D0U(IkB*Z#_Gahj(bK~r}1oh z-Z1)m;We&qghk-txcI9=F0livAW6DX*zxWxsV{=}XnB%~f95m&@;5sg-pY(V(d?Gr5cX4nGPcT}(~ zHlvG~KT=n}95!-y1%mwqfWw;ME%iW}Ow}TokY-uhI#tP3 z65~mWF@=C1ek&a9gO2iT*n=(9|v~-CT)ARfUAU zGb#3S>6l6SAychWFFGHdgv7LR2g5D@utj5>$1yY~eH>!5;>Hz7+()&>6>eX8YxO?X z*eB#1&FF1*4S(IWs#u83vuOQd95L;evbOu2)QXR}+<43hG2}$oyBhP0ckQd{rl*P> zozj`CMRXE9$r49CowF533>#Nvn>4+Bh_nXt!bsiOVT(=63Xn66Hg~Ys-=DFpx`_Lp z@Z5Q3Z@u91uM_J%dh>bStJPMwD}y%BpGmA|WApzxeBEyoltqKTis08_UigQ*#+Ppp zFn(pJX6?dw$I3OSB+_a)h(*V#X9O(BQW@{U81^xKEV|JWoW}C*^`+e8#s#KMgk_u= z4p-LUx5J|)*O?mh2@;e#f`68w1? zu6BI-VmtiK+L?~Y7iWhM(kxILVvp#;cw`^!941IBZ9w#wya{-srWG?a2gWilVE z!rxML(^@fhqwj|lM4!by~2pgMr zmq=qL!R`GV z-rDm2``dMYtBF*!_GTk&-I6^ZliHFB_LKpndk1zHb+-y`=!1fIQdv!d!nkx`BKAa^GHW@!`S#dW2ki>dM+HiIAPqqh#6 zzbwM7X%)j^xy#yUc;`T7xDMI@dt*xH>eBrqW5L@ql@)wj$sxIpl#M()}m5 z@vy+9SqB!vaWu&d*@|5}Y-*CPfAqMN1@K1tb2)1$3>xw|%O#Z^i5{z*(?tg$t)EPb zUIuJA9+`^g>W}xc5^#EP`UP_)JjC(7jaJ38TQlOli98az-HUycL3t_RC~zVstWPWD z9#*qh6BK1)LsC&-MKHD=&X{_{Zz|1{Zx1O+{T>T?-!Bc`9cb9X*3qPn2{q>&S;g<8 zpgp zS15*t?O#bFQe0+dZwF!mblS$Vpqo4X1)Lb?jK=S zM|E{9ztmBG8t~qXFK=?t*u5$))Arz3U5RT%B@!u%Wc`=ov$|2Vb35^vhjUK49reiLts z(0(ef{z|)P?|MxuVf{_}eSE*3e~MggHu_Bq#cND7$KNqO4Ha)5^##|@lUz_)))bJY7 z4f{9ZR}TGyyA~eaJfNEzy=xl6?KkZY#oo>En=+{D@LJE`;WtH5HyJlqgsvF}!2rO2 z=VJd_AG*o-_YCfu000EV{=xV?pSv0U@3Hfr;fnEpg#TwGeKY#sgMmMzYm)wmz8)Gp Wl|@1QXSaJ-_w1|cIl8I;y!#(He+>ly literal 0 HcmV?d00001 From d92ff9d4ddc9f8b0ec79ec2f140b8e83414225f8 Mon Sep 17 00:00:00 2001 From: eee <719747958@qq.com> Date: Fri, 5 Jan 2024 10:01:42 +0800 Subject: [PATCH 05/33] =?UTF-8?q?=E9=98=85=E8=AF=BB=E4=BA=86=E8=BF=9B?= =?UTF-8?q?=E7=A8=8B=E5=88=9B=E5=BB=BA=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/settings.json | 3 ++- doc/image-3.png | Bin 0 -> 69493 bytes doc/image-4.png | Bin 0 -> 69493 bytes doc/image-5.png | Bin 0 -> 138640 bytes doc/image-6.png | Bin 0 -> 138640 bytes doc/~$$绘图1.~vsdx | Bin 4096 -> 0 bytes doc/学习报告.md | 17 ++++++++++++++--- doc/泛读报告.md | 4 +++- 8 files changed, 19 insertions(+), 5 deletions(-) create mode 100644 doc/image-3.png create mode 100644 doc/image-4.png create mode 100644 doc/image-5.png create mode 100644 doc/image-6.png delete mode 100644 doc/~$$绘图1.~vsdx diff --git a/.vscode/settings.json b/.vscode/settings.json index 03f05d5c..3f272e5a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,7 @@ { "files.associations": { "los_swtmr_pri.h": "c", - "los_vm_syscall.h": "c" + "los_vm_syscall.h": "c", + "regex": "c" } } \ No newline at end of file diff --git a/doc/image-3.png b/doc/image-3.png new file mode 100644 index 0000000000000000000000000000000000000000..fc5179ebc4e6b32b89abf496ef6dc2345edb5746 GIT binary patch literal 69493 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 fGoB}J^Czh{?Qkf{G@deyK;_D;WS!@FVqGJPBW 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 >Hv zKK7{iVw|hT(@j+!k_l$7Z#&3jab`x^)`GBUWY~>>DHX5Jef!OuhiiYoj?O7*AP%g!-@b!??2SJXFGL$f64 zMb|KtMANW%)Lul-UiZ67E)mPM-veOzu`-425u2VGjoCMoPEE$jOt+oQzz=BEJE(QW zMPGjZ)n(jyM=!EDqlR%?^iN5)6hW7h^#vshSG?qXqPW6E-};tA`yt)S@--??7=V7A z9-Z8K;*c7EE8Q6252wnD8y9k1v_VGh4vV>-hLGpJ8v6J8Lz?5d?cFDZs`UlS|AgJV z-|DM;?Mv}PAG=&ptchQ5V2{I8heLsiWQ@RrZsPZ%G$_rD0BOX`HOL9%4%y>0;skwv zn#8&)8WW<_b-msI@tyqY#p80{x^~(qzA9l?GBw6`8{jnS!V2Q0wq?HtN=Ct6`v3+_ zEV+b@QW@{EpQVkSL@6vI1~x}NMz5Kr{f#*;Jnc);amhUA1AlHops4r_3|K*^iud%0 zsGJUa_pL#p*Q1q_{`P;(ca>eey4A!=13i9#u(gT_J$+Ovd3v0nj;=o$-`OrgI%7$Z4JSx)0Fs|45ao5qMKxRD;Q$T3%bxpnX3 z>og%4X&C$M);l#LN1-{&0uTLG{LPKUuWg8lHNXr6|XJp=Y(D}9R zLY5n?WktsVNixU4bt^H7y-PLA-YW~2y^+*FotEekO|F={>N_46|%3oRLpZ2ypVDg}tj3EAn;<%c=1FLE4==cGTZ zk4d}rMF62^&iA0l9KTTWo_AT~igr?ax&&p?mh`a&MSpgY<`Wm})^#P+em0>pZ|`0i z&uoU3<%)7gz@LQqJ|ZQhW2t<3K3o@HCW8Caumkg#em39#koLqhhVXFWpeDU>WgUwb z>r=D|mIG8cwh(sL|Eprg#D#vbv(`P{;hK<1u*AUXW|j}GrxTvcWenz?_o;^5!pA!v zoo&pLwRv;mcX2%h2jSP+pJw@o{45}~FM2hFv#J|Nme8B+zQV2Ll)yGph>CD_YS=g< zJCj20wF&%P>@@o=yeKJwWVmc=i!pY=Ao30P<>|AVM)O#xiu?dt)9u6UYuVTJ3+ z{B0QWleqZn(K_USL4}IIbIpK3yMEhx6J+B9C$hWgUb2y<-e46eWG2H@-33dK7h~_u zg=h6Cb*QYUOpvPujH;uG8;vA!%H14>&}S?EmUWJdHfuqC(@A4ELsyFJ!@3}FX@Ei` zm#(o;c$f8qZ*JYDD5Iq;zpW_Dc0}}MUeW=c{G!DlVzANE3Ypt&=PX!lTZY_;G55?*}sa98S+`zv)O zAX0lJzrA}YT&240g8RH<2YZJnJ+RW8>YqNEgC!@F{Ig?hs!X_{(V@)a)gNRTHY`C| z_kXX&x`3!Dqvr|Q(5&%idFhLZq0qkp@hZABV0SXKv4A=sny!@O|cp zQ+B;H_zDn`A_6aKRG4b69=oFw5at@ML3qYopzJ-rq#d84a?*3TvG?<%y8?nfja^&k z8r_q>zSykD77W@_J<|1edHu-S>0(>!B;Tb0@A`4iak;o|bE;e-zWDfa`hzQfBDjvyL0-Is&pEAJ(qP&$KeYcl`4@UM|=THekec%J~d3 zMP`D3UGhb=t8wZ*&$@WnnmS>%pjXK{f^;TFfY&EGjSf1$7{^l=tH$30XEStB_1omU zp$=NqZF7qnCtQgz3ePn#&B7-HgqpW}7!$1!MfH%3gF|^I?0f;M4hkEm)af{Ao*b+e z^A;D2DAc7U3ZqBmgS%ofy<^2_sf{s@_&1I(+?SPN)vH8Q)_Krp0n;V^-*V*m=d{c^ zM1NK5lOM7~AqCU#>@S@Jdd?uYgf1vD%OD@qGxhsRZ716$51;bCG;Hf*FB$cXm`^h& zBHNP*Winwe{A2LS0*DK-ZYZ0jVD@M4k*F<;oiKw;uC*D!Ww}lfqj}rs=e&2eiuH+*bY_$~{TfaM_ z2KhE~nNg3%g$c6ozds%%*AeI~Ol&VF&vm}$Ic+obJyvZLpbd}5l3#h7rW;;{Q0AaF z>T5n*m1^pq56q`&%$5EvbuAh;Da-pgS6{IDHQ{PyD%4+8Up*<}T;~bbgv1h|2l`#m z<$h!TABwp_hFneg&>yl^ym#6iEr)hRG$aRqcqY3x=$!MCfnU!wYc)2pC9(I6fjIr*^9){`em*D7Bm#JHrkKIN=&2xpJ@w(VSCz7p3;7ZhsUEBlNoR_ zz-}sUqnlqX+q{spSS~t*_FpjaBeYp81`SbiaVN9yE*%>S<624nz7!bOn_s5hH&9?n zB%)s6bi-U)-oMlmOV@=Ws|nIWq|%#y(pJ3_55>s3Sa2J%g_X@eqc$b5)RauK>T`tW zIuFb~w@BFOSS9}@>Z%Oj2>L2}wkfkDzE+JVX~JZ0BTV_+)T**utf;0EPyNiAToa`X z|I6&vT~^)0W8sR%4y}bO9}GaXwa&xa%QO~_bi3E)iifqajLH_ehH&QSPyRfK6T5#p z`t-l;SB8yOS7Zvk;u0NG;AJnl$Uo}bN)f2m)Alz=6%?qgGKD^JsyO+oBX+12eV%tEK0BPp>7_%oN>v$txSC4J_KK`U8sjjT8(Bv7 zEn!`QG3AS{xkv8I3S>o**Y&xaRk8jA*!cBygU5A5chr1ncVJz2q#pY!S=lK-`s*Q9 z6*=8@4-w5Q*aFy;7GUxmlbGC)g3@i71?wXglOL7Vw$`TITmO88e9^07nIsMy4dvDT zNm%III>sl&VaVQ$Y<#{uP4x|#$U~BTT;}1V+^8zLct%(M+nZPRa5Tn9b5=uvyXK-~ zm|Gc~93ZCf{R)hdSL|xIJ(daKDiX?7T)b~=XErjj)duxe_#%Sm|G>mv@xtPE?rN>^ z;XE1rN7uG5ge|KL41&H%GTwF+cMLMo;_+R&P%vkcr&$N=AY98DT~_bH&k_ zxqY{H5S#G?*V^YdjvbulWsg)o^VK!KKzVQ@qTvB4)Bk9>_?IS$Fljy7(Agayd4Kw6 zCZzSeraL9Tg6s8CcD7AQYtI$UY?W2<`@e=938S`uFK}AWlwQ447icap~ z{}2{%*j?IBZ=|mKp&nKU6)Wnj#eptEdqZAC%KXkw&`L|Pow2gh`G!Xi+DuiNWR2wZpa>;IZr%Tf> z+>Ga8mCSoOmUh=Q#^@tT3%^7oIakqDK!0a9>22m>o8v%0$>@ZBd(%~7f8_E}JlXY| zN+)|qeRnr{xsH}N2rGdvjN;JMQkn&$GIh)HRr&DqPTSWTD4A;*Nl|~z731i;jm2$I z>wPC+gFjzPmKktc;#X@#vZIJxv_0ZdtlU;kM)%!7M{zn_JD6ol7S3rX`OTv7ZvZpw zSkZYu?)&_WmpUg)aNo};7gG9Ln{Q5OMO#DLodY>e^!BcX1wF*yrjp^tRNs!R=)cGG zqg{<4&;3F<)n$C~mIA9;E8esQzZ(t@iTpv_#*G&PLZv+?iKEx#Ddj#~{RSyR_A-$5 z8m)I9*+COHZ+Rvie5t}^yL>lHaWrhuHoIW2VkWa1>C46Ct?IkHT1vMQh_^*A&MzzL zJ4Jo9ggtN?E!HD?5n^CfnOv!jy;so8;{V4Axpf|Xs2Iazt9S4KTF9(2XtPe z)*H1e5bi?fWL}Rs=m<_Lu1oR*1e(UCeDPT&A~8@aPO8yegq~+lh^O;i>;y6dY-|qJ zqy~n1A^cZ#|1J}b_7I&htJ)W{y!BC>dZ*|S7jGC>TVHNohwD>AhX?UT^6P3IObn;v zB9?R{bqY}em$f}HOI*hqg)GNbmEM;Xh}g=Ki+nTdi`%nIA5SBA1kQ|rCLk=cqeJQ5 zLZ$5=W3uhfT*4m`&#&G;Qg4vBNvP_kSG-^R? zZZe_<2|K(TSaOxC$OVOf*M40aGENhtJJcab+4Wg}kI{EVDMu$xc3*$(6L~!9+)62_ zk^cio=~+=oPtT4XxD3wOO1OD0AgOMCM6xFpc=d=XkGG<4B0|@GUrYaCb5t%@5MRA; zsU(|C`zVdBqkWhw@~6%wwEGR9boPD4f}^BS1-E3?^HUEo6;le49$=_?r95f(7`*xA1+_qem>oO^SDldMxR_ zPk=Ihh$k!CZF&p3iy5poBa^-nnKCJAQe3a*f}oyeQI&>8S<(J-Gr+WqM?DR=om98g z(lV#y#x244nb-`tMh{uf>}9zv>%=EHsVAeg3{e^twH()d6%_|J&*SKXr}8K@0iKA=T@ewB{0j3+Nr|VGCCGUNecQ zUzp@62Nuqa?R4e#8{|=7rE28y$Ci*amp|{uCWdyMMovCqD(>%h$gP|C#JnD&N#wEd z6@Ep`F5sy#B?9LB0R0;@QCV$EwruN_jS40uL48tqzp@POkca<(?N24^`eL^J@=|cU z(H^E5^y>fO!@F%~G8u2bLE#seUE~|AYn#~&t6xlTwvaC*h7L_jLTCC{xg<)!s!aGA zvL>LK)z!A!8C5NLwjZjHkzZ@S6U5tRbu&TxvfTHK8QpzbDlK63<2Hsum`l z-+7fxqZX7GX|~PG0}WY%?p@v&P7>^NDTNvsh@A zD?Uuf7p))gbQ*spvcB#3dDb@Rd`qRJ2}eEM>FCC_zhSD&NxAP;mF|7iWHs77hWFn) z44}rM!EYsoGuxwAO7>cVk1<=O%vO8T6zl%X5W&igFGwzcd>grj0iD#)Soa`*hsnKG zX1lp*igghIP!sx9niGB=$EaeV^X3vYssUaU*N9@`51MYWdiEiLihxBLHp^t$@dVj8 zl#BsO4V23O=eKTu80#{?5JCKYCYS}(68OIW_R@bc!P+#|G$id$m4S2`16-XBbl9L! z$-+q=3uS5;AU>M9gCvU$5TExyQ2bMH4+o371u(3liWpyS&}{(5gpavbl<(~S6s{8> zcfp_%E>0ee1h=aC03a|4%qf$x3f{ig$&Yv4(0g}#&12bYUh^~9iA}|Y@C9xtNu6<} z3pdGFW3t;qhsYLvS9QDo6L$QUY)5eknv#d^Y48B)lOJq#Gwd1ge!C3Vit#y-hMMgQ zG*|MimWhjnb>6T8zxIHoKi8yhWz+1+J3 z&V*wC$wwv}!(t`XtuBa3RBfA|0IfOYFLQj=2)ANaAks4oRFuJR54Nt@ z>tlg(SiwhX6CGjCme>EUKu)c%@XG7%F?Dwb4>(?nK zSqDkvAg8@m5|cx;btJ5-WQ>;uY+p0Q1E$mQm*h{i|NFCl%&n}c?{6f)aC@^E4@hM0 z;Z?$W_DnFQH%q~Wl_WJmuVMreqUbF^r2vxvU^l;ZO1%aP0I`eUDEK4&GV+r%Kp&L? zEi^F8KTbSR+X`-r;)bWC_6fJMzFk#f~Yb^`G~Bw9fOQdC1#m zmHw-g8fo70k0yZ8?7b^sj{U$?l+j@I5ks^JfgZ!u_jSvYfQR$}qy*!uZwCG7Hhl%%hDlyz0t$oyW26{hZQxg~u!|gB2g)x%iS9p7k6|(&OLvz+ zxM{d5sHnmC%535H8-%b!i)*^d?U^g~mbD#*6@%w8`v4CGXg`4Nc-6IAN>KwG!&_s| z1=)u8K}I(cha`0XJ97`PTL-cnuWM*2Y24?x)^x4~IJitHqYFKKb-d_m;=tR{JuHgsQeWZ0rJuLs0j$uwL)jPA)LZWm;yjc zMONNQl2_qp8{WTd?uM0jj;1opxicYI4kd8a!l#@0rIeSR-VkPk``Cq=A*V zzNJ6l*>~u*J_!+2GSyHrP2yx*=3#A9>r22;dNCo^>hyC^us`p=T-lLea_pX)dH$<~ zr@^`%hb>IeZ=>;F6V{;o##gn_lD6718n_1-s@96}sK;(~%t)tOXCZ4rT=E#5HJwqXGnt zfR*ixA=%HNnLn$!|Fae;nAKXAu?3w8(NVuKKA^)@0HvP~ep1Mhbh7o|gT=a?hE0~Q zNOkf&AZFV^r#|99JP^EwY$k3p&ULYOzWUF(;@_W#!i2PqSf=tJ6YWK*2JBnRDWISv zcZGd9?>|FN?+;yO3U)EkkwO3+`J5>T#*6|+wt&H>+@W?pWoqBS_oEHnZ=i6>moVe) zBmV1Kk7e!o!g{(@7@$~#9;GaN)-^$09&82(%N#X*t4vto1p=FWpgzfy!}Lm9pguY1 z=6P&6lB|ejP8o84%1)yIH9mAUV(;P6_4`nIwlmW`V*&t^-1;6kShQQe{dXPml9>8D z%-R%_dw}P6bBPWPYfA^QBaKuX&(uI0th(7 zN-7xhE0$ILAAu}{EHH9>_W{BT$I2 z-61GXD@N5vp7)r!Glsai!mLDtK&J$VSS4}qFNlHkzvZBFl~JGh6g6lQMe_@YwM_7p zy#dLE*X`B*UT>qaR8jVKle&B`W*sbEAkzC5jRFaab>E3+Lb*Vgr>zv+ zc0Qu^`P>Tqtqst4^ZoZf2GQ6Cz^kuUlUAFi^^uvosSt!T_tx1mlf`YGt&FLQ3CwlB zcu@uvP*nHVRo8510yF+;PaoK}@5r!tCC2EGyvzY@*-oI;k~;>1zSdJfg=2qd+TTW6edvW$j~A5g>KWFD@<`b{O^ zfr|l{=^Fm036RoIukfB=nuUt}c(n8L|2i>dym!A9!_!nP-(f*1f7JHf+~GPxb3 zOqIa!4rzKCm+_^Wj~6A(gOyFHTl&OYFc+4aWurY>s-(R+j|;pF$RhG!M*txzCeq$f zEZu4E!%A=MI&+5pjZlX1329_`=;A+`@xaXNwz0ApASVGFUEEy7$J(M+!{)ID<~uF_ z`%V)qWmX*GvBNku4LY-~#N_2nP^n)*<7Ml=NoM7vEUyQeo8$zk z=AH0Kqe70iC=;3Hu|Q2Vrcfb_wFW<${!N*Xp{+XVOaYLktrjAZp`Uz&DKXZE3k3>Z ztl|H6O^mJ0ogRy4%7w(v&97|sFkNKJm<31$Ka9L9h!9MIORWX~wqsuf5Uo=_6lM9e zvs8S4b%3-}wE@5q192Y~-w3ptL;cT_+g85~X254Iv>xoNrnGrEbd~Vl2O(%xcLPv} z!0rF*Ygf`Uv)Yv^W}>7U5i!qjFjHIQa7>c}3HHzkATbQAzqdNbR%*YmKk-R+i*5g8 zg)?Ov@t^iCb>TD@Ua=zI($ctuk*uqou(A_CDQTOw+>|7RVCt2KI572oK(9zVd}#V( zDTu|wS#&6j7b_>TrtDh-E!(}92FI~X(G&gPJHxv>_J)9=^v?`4O$r%d-`Cu;sUZGj$ur-gsZO#qJt~0e9rLB0 za7G6p%n(DGoJFeRS6qTt=!?}@VXJKqW)f)azCS-&u6u>+`$8l38Y-2mHCI>)#=xqx z1Sf`7_t(A0d7LT+rH(*2IirL2^{D`>fuRM&zJZh>YfK2xz(HJ=R-d&8flvDc@U$CJ z8E{%+AD{>{RkEJOb`?-b0)V1~6?akHgoI1bS|(7Apf3jkNgp=0epXh_mdh+7Fy$A3 zBnzcOsRe+)?aV;e0a!FPw(R|y$b(GgDc#*j3g0AdW%B1>EumUOpuIzn*EYy?>f18})xY z6PWJLtmDR}^#o)CAT8Lt#Z=O938FMGC!nvLrIs z_5-CyD^8MX<6q2-ReRq?3cOZU+4}Bnm8QMq7BmF`RzS(kKbW;UUhIFA+$YtU&%irQ zta@h9Q$cJBvi~6sA3N3<<$uRG?P~(fw=fl(z*@{>n1!+aPtG|^K0@~Xho3Ip-WKP% zZ$LY8u5zwIY0}I#`$CQKvGC_<#Kwu@p%4upr|D8H(03tQzJLu*nAi1~e z%K&PQYXi-l>Ujm**HQIO&U*lljClUUo?#+~GS&zIO>d@9OVZ!eBWmYBWD0x(6YePv zVCq=#-Nl!O4xaWSETObAJr7-zeADqNmn3-@>M1lUZzEVh80(^F#~ksWonO_41@<3T zGK3E;8|LFA6YVCIJ@w?gWviH63r?V1$I<$5sxZjYu!VE_@E~^uROuY8x~)t=wmJN_e+d+9l<)tF z9_0WzK&wVMP_@Hr(Fj%s*rw%sQ_mD!B2kWAIbMHS@xJak{1SRhdA+F&N1^-?RJh`8 zICui~#71=1E((@}cYOY2>Z<(jnuyErbBU8q*T+1y2E0OWaxl`Y3eg%> zcwg%bg(wBGrOBe1x`1I+8C7Mt(65jh2-|^+HB&f!`g1WZbw%EmrkDneul?VCBCkJt zJEo8<$MYrU?4V!X`bggKb(KicP~N;_VnhRe0g%wkgO>*rPlae1u&iil`y4LF2b5@b zAJ2z^FjdH84`?icOCioUzx;Iab!T!@6;j~r%2A)CXPJACnucepOYDx0tXG$wjtRE_ zy^OA{rOrfNZ^M}I?%Ofu1%}a*KS@<-uk-!^DjaTAT+4F%n~%$3e9;X`eaw&sLQYhG zXtuzJn=p3$05?Dw{c2eGNfk8x3HLE)_Ke43n~AIT()Rtmwf@`cvnN|;0u-+vc`y+y zyn!u-xYP_@E#0qIu*pALdk2ILL1G0|HoyfJ%uJM7p4G!PiRB+kdaeC)C1$e2@5b3{ zu{WRb1t?sx(s++@gtw;G!RzC*pVl|PsI+UX1PdkZ_;%j7oN`jONT?{`?bMzuVWD2p z)i#lkH;$}{%(l5M)CggGhAtK8yN=9wy(aU(B4+a+@AYwbSnr$t=bfO$cw9#YZkMDQ zU^2W*Zg0646t!YMVNu9IxdrZ^@3_>zY*JM9vgZVJ)pFrj1KE6lVz^@8=&p4y!-9*g z05U@@Mh^f8K9aIWi+0iTg2%g7LPjT=?7p2G@w+C&!W^MR3*Nx%srt)v}cO`iQ z@MdOh7wtwOAfj9j5!$ojv)iM$#Siamg0VGmC9BfUF>P;}L^y?rYUxk~f>!V!!C+bQ z2zE^>9?zUEEW4gMu5VmF=p|;ubCibGzB5Ntd_!uIdk=lGyXzDqwv_L7?fER!wx57~Ow#J@XL;jttK@dU&t!W;Qh#p5@YVd6l2j&!^`X&&+Ig1lwz(4=$o@?cY`(NjkG{Xa!N*!{T={+_?Pk4C0OlnVZQe z+XVrz@})-t#@v162Yw~5bAxzoxef)!0LT<1eM+d z4u&e7&;tSnP?}1$APCY79SJ>wgm&nMB2ohch=LRo0@8vc1l|dF-|ust_rv@3S?jsy z3t7X0nKk*(%-+}D`*-m#uFRIH@vWOCi{Nn6Dt{wzwQ3NmU*#fHf>fFrpjTS?#${+4 zK2btZjz(&qVNpE3r8L-lk$k>@Oh%6G0HSAJnyg`cIJV&=Q6(jRHpMCR?JWcfupCGY zS2t4<+?yo4D_!79xvS5h%@4eL9QU zP!ZhydZSHhBKG@MBlW~Wb81SefU>McYeh&3f`7tVcj08>an@C3JOH3sPoo%F8OxwgFywvnpUDjU0~(=UNGl{j*v3r6RMy87}1!1$)grpV5^mfqWkn z)EBgp9zTL++6vw}fScT8NUQ!xEix-K3X5B(XaloNB=mdPap)Wd0t9`>UklWgrvK7> zYk-E+d;m>~q`JE2HUS*EGj}RYLZnX4Drd?`=_{!9`-0x5q`r^Q5Yi9-ehELpfI4|% zzS@)LanEq4e@t+0>C3yw!BgYJK#iUKSM+Tf$C1NiJRte+SM7g{n_t1JA zMGXE!p-uewHMVNL<(AEPlvvTgh%^A}v1$YJ1tv-_juQ4hUcAp7gx3Ab$Xvj?+obVq z8M;qyg}b))a@@DjJhY&0P%vI0S=>i{a5B)hr!d$)++du|u7PnCFdd|YYS536<#1qp zq*WXc2j2rtke_gXP<_}V&zfi&VLN?Zw<|b_Jj1HJe0fU4d)@XRampjHZ%|Lw*oob< zWf0%%NtXeb<5yq?`x2)n>Zp!UY0bF$r+`S8^hd{%v7HA~4N0cCtvs4iyqB7a^Zi@|foZY_ z1CT_~RnN$8u~dRGtD@fi06+M3Kk}x?A4!WdhP{&j*I)`<5r3Z;0!56D=NN7?#xE=< zN@q6fPjIN_jH;E*zWvSN-f{SLrgx@U@Ru?bLmS1c+9UxHF7(GCyVsN15{>8}hsjAB zjK&1rpKtUJ2YX@4)VUeyUDIxs91F;2VZMU zDcIRlJTg8h^vcS{?3`0Jr$G8{4iBUEz!f1ET@@#d>V3lToGYAWt;yg9{c*%f_zbfd zGcl{z_ex8;{RcXh!vA;9j?Mr`-wyPw(Hnr99BpzDDB%INgnM;r_y6kz`${UT(V@>Q z$}0J4V*aP7^VzCT|K=*Y-%%>d*N3!}GpmMtB6yyhgv;KBECTE_4A4gy`#E-^dM-V6 z3-h}hXhL;hkRTb?qW+Ya15@k2EX&{(de+vQ6S9amo6@b^TyVTLcV3Q(74BzUrb(ec z#*I@i@$g-83eMC1?}AYQV*MiFF(fK<}Xwsm~tjzi))jf2+8%6 zL^Y88Y~UG8)cN_se~()GN8%BtEg`)c2vE@jyX2ptp_<%v#0bIyVqVdCsvLYiEteNt zpodoEex5}@L4!MjPjFoa^jF|kW{Dn5I${cwix0#lBy%V_jvM}w5`*iRF9q8&nB+1q z>5d0o3o0NcwNPI#n^i4 z8|1^}Q;q+M(fO_>r0hMZ+8@YerIC@7hMKM)_hRY`0uou
        UFqNT_G;K-$7bX=V=(;!S}A9_#yj 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 Z^1vm_V{Pe26Yb3I-ZuIJe#_zM{{iZnm4N^N literal 0 HcmV?d00001 diff --git a/doc/image-4.png b/doc/image-4.png new file mode 100644 index 0000000000000000000000000000000000000000..fc5179ebc4e6b32b89abf496ef6dc2345edb5746 GIT binary patch literal 69493 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 fGoB}J^Czh{?Qkf{G@deyK;_D;WS!@FVqGJPBW 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 >Hv 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
          UFqNT_G;K-$7bX=V=(;!S}A9_#yj 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 Z^1vm_V{Pe26Yb3I-ZuIJe#_zM{{iZnm4N^N literal 0 HcmV?d00001 diff --git a/doc/image-5.png b/doc/image-5.png new file mode 100644 index 0000000000000000000000000000000000000000..7bff255f9dc09c2ac0c715ee7b824d345195ba08 GIT binary patch literal 138640 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 Bgw_B6 literal 0 HcmV?d00001 diff --git a/doc/image-6.png b/doc/image-6.png new file mode 100644 index 0000000000000000000000000000000000000000..7bff255f9dc09c2ac0c715ee7b824d345195ba08 GIT binary patch literal 138640 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 Bgw_B6 literal 0 HcmV?d00001 diff --git a/doc/~$$绘图1.~vsdx b/doc/~$$绘图1.~vsdx deleted file mode 100644 index 51b621eeaf92be13f75fd8a527c1531414740773..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmca`Uhu)fjZzO8(10BSGsD0CoD6J8;*3Bx6O1pwz`zP*gT(&*|NkE(%nZap<|r6K zA@CRIR#5znf{_^lK@9moSi+#d;L4B(q>C6TL0Oq-AOZi2;JVuj2Z3>hpL%o)fvgHW4=Sa%FnbpRty BQ-1&e diff --git a/doc/学习报告.md b/doc/学习报告.md index 8ad69581..4503a12e 100644 --- a/doc/学习报告.md +++ b/doc/学习报告.md @@ -7,7 +7,10 @@ OpenHarmony liteos 的进程实现方式与 linux 类似,都是通过父进程和子进程的一系列操作来达到实现一些功能的目的. ## 1.1 描述各个子功能 -* 创建进程 | + +* los_bitmap.c 主要提供一些位操作 +* los_info.c 提供一些基本的方法来对进程的信息等内容进行操作 +* los_process.c 提供对于进程操作的方法包括创建切换等.. # 2. natural expression of requirement of software @@ -17,8 +20,13 @@ OpenHarmony liteos 的进程实现方式与 linux 类似,都是通过父进程 ## 2.1 一个完备的进程管理系统应当具备 ### (1) 进程调度 -### (2) 进程创建 -### (3) 进程回收 + +### (2) 进程创建 + +![Alt text](image-4.png) + + +### (3) 进程回收 ### (4) ### (5) ### (6) @@ -29,3 +37,6 @@ OpenHarmony liteos 的进程实现方式与 linux 类似,都是通过父进程 # 4. software architecture + + +![Alt text](image-5.png) \ No newline at end of file diff --git a/doc/泛读报告.md b/doc/泛读报告.md index db1759d1..769db50e 100644 --- a/doc/泛读报告.md +++ b/doc/泛读报告.md @@ -37,4 +37,6 @@ Huawei LiteOS开源项目目前支持 **ARM64、ARM Cortex-A、ARM Cortex-M0,C ## 三、 软件的体系结构 -![Alt text](image-2.png) \ No newline at end of file +![Alt text](image-2.png) + +![Alt text](image-6.png) \ No newline at end of file From a121ee05007fd44747265ba50871b513754f5789 Mon Sep 17 00:00:00 2001 From: eee <719747958@qq.com> Date: Fri, 5 Jan 2024 10:19:52 +0800 Subject: [PATCH 06/33] readme.md added --- README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..305ba24d --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# Brief Intro + +LMFAO, we do this shit just for fun :) \ No newline at end of file From 242903f5e2697f4db6d3d8958c97f41325671d86 Mon Sep 17 00:00:00 2001 From: eee <719747958@qq.com> Date: Thu, 18 Jan 2024 16:30:33 +0800 Subject: [PATCH 07/33] read and create --- doc/~$$绘图1.~vsdx | Bin 0 -> 4096 bytes doc/学习报告.md | 4 +++- doc/泛读报告.docx | Bin 0 -> 29305 bytes doc/绘图1.vsdx | Bin 42782 -> 43149 bytes 4 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 doc/~$$绘图1.~vsdx create mode 100644 doc/泛读报告.docx diff --git a/doc/~$$绘图1.~vsdx b/doc/~$$绘图1.~vsdx new file mode 100644 index 0000000000000000000000000000000000000000..786dca02036e27af03d11d2c7c980619578f98c5 GIT binary patch literal 4096 zcmca`Uhu)fjZzO8(10BSGsD0CoD6J8;*3Bx6O1pwz`zP*gT(&*|NkE(%nZap<|r6K zA@CRIR#5znf{_^lK@9moSi+#d;L4B(q>C6TL0Oq-AOZi2;JVuj2Z3>hpL%o)fvgHW4=Sa%FnbpVmu BQ@{WK literal 0 HcmV?d00001 diff --git a/doc/学习报告.md b/doc/学习报告.md index 4503a12e..533c3037 100644 --- a/doc/学习报告.md +++ b/doc/学习报告.md @@ -19,7 +19,9 @@ OpenHarmony liteos 的进程实现方式与 linux 类似,都是通过父进程 ## 2.1 一个完备的进程管理系统应当具备 -### (1) 进程调度 +### (1) 进程调度 + +鸿蒙内核的进程采用抢占式调度机制,支持时间片轮转调度方式和FIFO调度机制 ### (2) 进程创建 diff --git a/doc/泛读报告.docx b/doc/泛读报告.docx new file mode 100644 index 0000000000000000000000000000000000000000..84a1becd77563e3829d0789102259ae36df8de8a GIT binary patch literal 29305 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 )6)^T7@_UPIZL8AuP%N<6cNm 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 literal 0 HcmV?d00001 diff --git a/doc/绘图1.vsdx b/doc/绘图1.vsdx index 9ad9bee402100b5d37376cbb4114b1c5fe7b73ce..482066122cc8c3c5c8a75abeea5223ff83608821 100644 GIT binary patch delta 12250 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 delta 11876 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 From 21ef823272dd922315761809b8c4750389c472d1 Mon Sep 17 00:00:00 2001 From: eee <719747958@qq.com> Date: Thu, 18 Jan 2024 20:11:42 +0800 Subject: [PATCH 08/33] basic report finished --- doc/{ => cache}/~$$绘图1.~vsdx | Bin 4096 -> 4096 bytes doc/cache/绘图1.vsdx | Bin 0 -> 39152 bytes doc/泛读报告.docx | Bin 29305 -> 153975 bytes doc/绘图1.vsdx | Bin 43149 -> 43155 bytes 4 files changed, 0 insertions(+), 0 deletions(-) rename doc/{ => cache}/~$$绘图1.~vsdx (98%) create mode 100644 doc/cache/绘图1.vsdx diff --git a/doc/~$$绘图1.~vsdx b/doc/cache/~$$绘图1.~vsdx similarity index 98% rename from doc/~$$绘图1.~vsdx rename to doc/cache/~$$绘图1.~vsdx index 786dca02036e27af03d11d2c7c980619578f98c5..e7339ef1fcc14ce601709dccd6f848ffd682e095 100644 GIT binary patch delta 19 acmZorXi(UY!^XB?y?Z^2*XAO&K288bqy~-v delta 19 acmZorXi(UY!^W0y;c(kS&&@?_eVhPH#|O>; diff --git a/doc/cache/绘图1.vsdx b/doc/cache/绘图1.vsdx new file mode 100644 index 0000000000000000000000000000000000000000..5cec30dc2c7a11ead8bd5f8f689d48f97688fc54 GIT binary patch literal 39152 zcmeEtW0R)Awq@D2ZM&+=wr!)!wyU~qblFCiZQJHswrxzGb7oH5iF@uZn8^?Me8`N* z$Q667T+iN_iZY;JXh0A^P(VOH#6aSKnO;%AKtO^JKtQNKP#`)Y_I562b}k00o(^Wt zdJG=6HbezrAXIrkAb;oo|Mved0*%RI@&in0V$YHvA_w%+n;6iD;3izJDqIpWS<2REVG+X1>#sw%6VFdu>@XdHZhZshOlrPHQ>2wLdsx6O5ASCPe@Y@*#VRaM!934yI5E7S+G@Ll%C;Y_H=5ER=l5b^m4R_cthz z;{V0rQqBG*^1mbcpg=&de>rU6WM<>c$ncN;|8w{MVZ#2Gt^Y}y_{&|Se{eVW(09Lx z_m^Ul9g?y;R0ty0g_JR}fT=>o({&vTI0?Dg90MQ0wzqk8r}nk%Ofy!2Tl0ZfigTzs zcd@O`UCW#2ZLbztEsU2%-GO(skDi`Em3|$hbewUiuc_3~aH6~Dmr^(t4;vEe@mxvf zFgR#(Y(6@{0c0apil-lAzX7~{4BMLcZ(f^4c#Fp^%46ro5Frq7FyZz9SV9ynqHJ>` z_Fov~2jgR@sR_N}m%cyM~C37gb-BT2Mm`>pblLBjaUh>2MeH3W-U+VeX z@Zej75rZchs=0rG`tPjL-Y_@lME%PuHy|LCzcbt{oh|JdP3=uwZU3H+|2P;g^kke# z#~izP`oDpZxdr**Zb`y-A*8^eknp@-QTjap*vsV!HkQo6bK+#}=Ahm6NdRo{T@+U} zsC^znFQC4$ugAYIr~jOtO`nZhv8mrpD(^)bv!8s>&{opW{%w`-JCuZ&LYG2=v;r`Q z=T+I}T@?LNY>xx)18>~vT^?FBp9d#3-)B29i19{jT8yG;i+QT8+<#`0Okc$c>oO*X z`gJbpKBVxf3bg83BQRoqa@*o^ z<3*;oASCMCGGkN50rOs%BF=m&Y9dPbA!#BitbD18xaW^A7}C4AO1wkD??3l(J)~ea zb#3$g#8M#pJTM^<#tUCkvd{n?C51i>dk)lO&kKyphXnZIye}lpcEAokl)26t<`C$P zD3MT96jv4=2@Uwf&mC_mW4SyEE--egfmjJ+olxR9ethv~DGR;<4N5OjoCgF8p^5g& zett`(4aPM!xQ9JH*>$-&d--U7E7||@Kc7{GCXcTUy|{W@57tAdPZbL7xJeCuU^Bfz z`F28@^&y`)F$MGI8to2cJ0ygd2liFb4wwgWa+l(@51zx_qxE%Oye{Zt0@OSS4oC=#% zcQI-A4O*{gSFP*Ywk%J71;rQkc7!EnH(x}Bra+1&H8}8M_NIT8Wy2p%%7b@DTcK#y zWLH6)tD(>(7RQi12?I|Atk!efg$`nSOmkbhGg#;Nt7e|_>QHD;Svwr#9Wd_P3~{E@+1Xw4W1 z4L6`^GbGoDFt@caB;Ri-5L<|7@@-9AZmYdr*ZM3X<(}F|y;>63(g^*7r<+>~X=>Q^ zBE*U*dKyPGioE&Y$+7$wdl{GH>>P+}@}G4q2{LIDGZ}Kol_lr>*9TBDtHp59^<#*H z@cp0i6iLDIXKp0D1*Fl}3C!#6WCl~_vd#_>n@Di=QW8e)PlEME+S14|_2FnN7wjBh+QN6RTO~)7K$-`{d`b5P!yq0( zzjM;nxz6#Wi}8`J?XpBqRaZ~1I6DC9=Vp~lHttXB!>S_sA_Adic%7gfzFKMsa$Io~ z*V}IkrgoTO^R&jsCtwomVh==EOS5F+l<|uO^g`<0&G}HG{gaAxl(s+ya5l&atq~|Q zL-s&!nT(GVuO2Lq_$0>u?d44SeL{z8Im2`7O8dRA6!r$UL&LL_)nEPKa2kl+2UM{b z_46#{c71%9R{6(mlD%U#5W-9;=n@oW$e}>MGgZH)s9HcZmMJ*@;CDm z!m`($W8RtJ8xUKDJ&!@pD|KlRSZ+UMDfcNwr*Q}t{xnq}^DG$tCt^~qea{J*hPBJh9Ivk1jyh~zIk!3@E4kM7u zG9kFINNnINQTZaKRO$oq6g5Pr+^CeQiF)higP@f3Yv- zN|If63N`wGg~)bkNdI^y5c46%a4)Y`Uhl|sCE6pt`h|Lk>K@&6Qwi^)_60+8qzkOJ zF6JBdZmHe0j#YB?rBSS^cMR> zhsAcd4lhaZ&-|%{vJw9vQn*xDwk*jOZSZvD2Rf@tF>U?BtU5CfZqrWSRz+gyg@`}+ zM6ZcBo4A2is*b~h=sH&gj|FXX1yV)di%l`68>TT7Ae3On@Cs4|32+5&$xtoUiG<~1 z#7m0W`yxTHlVNaUH%WwPvu0!9ao~@(5O^h=>4z^$C_P$xDWm!^z9fxC50JnF2l}Kb zCn#&xdEa<69)lGGx`JVYb?`~|qo4!Yxv;Pqpt@0J`E$dC zvE^;P`#bUkE1E?u;V{&A%$8vjr)-2n1<|CyszLNp(?q!vuc$&qS~94IHU#Qi*8#xw3$oAV6-jfdY%Pge9sk6EOZ#(x3 z&P}G3vc41&rsAX}LGHKJBrXiyNi#~BRU5k@R$)DcF)9yDZTUd>=w1m{fgw|fBzSNw zCuKEK5c=#4(Obu~FLzF0-Uc!&8Le2YyddUD5)WS}e( z!%TY^*aAkekK)`=_~j-Wh9H82c-FO9%Gj2@WSZLT9ejr!t|DJqrZU!2AZ6k7x z#w;z8@w{S3x5)!nukwv=O?m9kJc9l|pSSTKF@+v-w33%^rn0VbvIIV*d5yNKy#G3~0iGNGrvtisWBFtE zvQj79WG%f43G6XqoO#du;rIgwmXM}7AwR~%F&{V~ex0qlq91aBB+r-*$;CL<7XWm0 z_&867pII#Ln7hF5*i)rmHxW-kRWWEyOsqS#~D?8C{3yWxiw#YJc! z4JsjtGD@wp$sneh>%?Ns?UI3Xnr)2$G8##aY%sC@ zK;B;TIR#Hc7kEC&uG9f!f$nzhuzhEZRZL$BtCWd^P)|3JOVU9a%}eO^Iw~6i7hCC= z?p7*G0MiqH0RET0nW2E#pF$lfZHZzKi`~thdsH}?;*#DeJe}w_6M|q>JPkT7U6DrP z#N1Fds<$^d)Q&5ka3@|nv|5L>3%iI#=y%E1&Hy|vCoVXVtHlEsJXO467ouUS+ddzJ zT5skoK9R}SlO2jTBG%XpvTe|+n2TVx-4I!sFw9*jML1pt5-R$U6&r%@s;i7uwMIG#t#-c~{(t88T$ zN#gOQeVpWd{-+e@Ft-2z;VbiTAP~6wiyI=a(ABx^xJQI_tItH5#{1kV)pAJyx5`PV8{cB1P0QtK+krAQ38YT&X5RS=Bk=8?Ts!Q3{yB4Z~_}oxwarGM}XE(R5^4a2~8Ou4~O?Xj- zS@64NIwHr!Qy&;-#fLIB0>d=FVR!Wx{Z3woI*G&&|8QFSKEh%~Q;p;X$lI2_jR=AY ze|dvv`%nS9FZiY|&)kC2dO7-#JfFVInOE~tm-(P^$)D-xbHvqO2)}OLzgdXIibJRclQH~| zi!TK=wQ#x2Vu}mLM)=TyJbe>KsWq`_srwoi11}@|T^7wu^|d(==om@Q=UFC%kH8L6Q?cQ^BhvfO8CY4N-j!KFX>{$(kuJzB zAfBlicvzSEQ8Ep@%ugl{Eg**UgUlV`7Y@-GMOc~6mDz%+bz{wu)Z5{L6J$a>wK9Zm zQ%kV(Of_0%Eved}6_pB51pU(IfgDq*_2$v++1njLDs36CxXO;mWiV&k{YHR@Et-Qo zPP>Nt4`p)jy;h)-b@ZRFB5TQ>FUPe&6k{-PeUw0TTC+~gsXA`SI*P`C$VI%g8qh=- zZCM15?kI#325N)wG9W`IMQwbT0ik&;QmkZqr>+zVoTlMeQ)8%RYplf=qvdT2 zEZ3FH*kQ8hA(J8y35S@~fQsX3QB$mS>h+oIcqDpQxn6q(7hb zDX_gLsJ{Vcgs&(dT^iRTnsHvEN`Q+=*jX3`A%_g=6eK?m@&TSdpl`>JX$vOwkt?Ft zSu9#MdYf;9$sX2$O^)1~C_ zj$jPsE{bA?*35*pRl-D1AfT~ZgrPZ52d9P5e^Iv^FW8egooHT@S{q(IMR~=q9v2%m ztF|&z<)TQ6dE6`Jg-MHQgq9+66sg+ii6*7AX50dC+cktW*@CEEhPAA-sjE~UZ)ex7 zN^?!}=rGoqtofL}z$oEkRPExqV_7={#KeqGsJ5i8$!+bWMC5v5`$Qe#rUr6y^mh|= zwn^U3GZjvp`CX}}$e|NsM$*Crair<8Y!#qgL_U7*MHbK6*sIVe5RT%>{kXYuw=x9J zH0T1}iu%1S#ISIi zKA~I7&;?X9!XC6j(gy{_kE;a?|7**rZSVEH9-sBSYXQ02??y&hhw23R!YAm|=HuUM z+RFS!*8(+@xed>`8b>p0?=!Ub#}}WJJuJ8@5~GMOqk2!5q8}&tV+R4p<`ocfhXHEq z1^(Nrv6ZeM_Q_!;PvFm93O<*3KFLRYn3J4sZwu6&@q2vFVnv*ay<(tqGWx+1!V&S1 zxSr=1Q}=7;@#7`kY-BaC~xZKli~A?&5+(0 z{H#JnMR$r6dwdbU zTRR#wD>!|2_j%RxXqEq-=-x$lY;oyveR5z2|`I-L?Dt`IPo9{73g@JR#s!~6XsLS zevzw}ln&PXtP=@g?*4t}jOUCugWulftuuUPhD45iTdXiFbWTaUNjv&PIrW3Cq8Tfj ztIx+t!e-GfBv2vH^$Uz1V$c!R$g4R%JDk8=t?bMrz$%^z0CB8dnG(_J39I=d0aLWv zND~2nE!LCg4}iicpykX9p7aK_TH{>lK+m~4FbhcX1?`x41FBb{$Bx~%pW}!V9+lc< zL4^PA2$^r|K8fZKUAw3}NgQ;F<{_HrSXD73L&)5aiye1Pb!_GMqu2HUN%)uA$<0X3 zvPSpi)*HExs|6DHZhpDtj4c~z$dzsz0R!Jv_X~e#TeIVP+|$`%kAeQBz7LMyz3cnZ z`PJQL3?}9ZBj2g6KLYRNN*wn@>ulG@L(M&Az_Lqr{o@Z0gyag_CA5c1`i-rMY~kaesdW!|iDtQM)t@#Wb!yOOY_8h* z#iHuc!T#xuldxlraOZaF`IMBFcC&k6^;VBNy%dLD#q4TTZ&WY8R&Stz#Tjo3l2OF; z<)fTBgXtei!KM(xl6Es8^yQgA`1@quF32o5=R)%bk#@N} zNcNz;uGBnUp+p->j5qJWeVU`j*+*4>ztqC{@;Fht*bf1*={$jM!D9~vAcDfxrO-`Y zW28~2HGhUqeGy}hGtq2{pWMJ~rJMd-jy0M^n`W!W zl-1>}v%o)j61v#>0yg@yo3;9!a%X-4(P>RB9ZM=9Y6r2F%xSKMwoa=y8ZjuwxD5PA zVqcL8tqQ->bPm-&aFWZx{?E5@D;U3o}Q?Zr#`p`JSfAVgLD{_ zVb;`{W@JW8UbkkfY~B=BfJZ`zYh9D++vcp4Y_qo3(Nqnoz6K^|s_3^hX z3T!CbbUoL81y_=T+pJfS5~2xnV_0`$M7zC_zN9xbb^;!02UYq*Ug8|@9i(%3sHZ)c zEVl~KCCRP=)4QMVoS2rh47K`F123)28k=M~$xNiM@-$RN5p?<7O6pfjMnV8Kbei={ z+O!Zj+=8zM;@2J1?tIMS#&i0#d)$D*b)Q8>6sg%gLFf0@$6+_XiEZ@~`G?1+-e7f& z4GA@C+!E*mWi#XS@oCO zWpQQ}l67qM4~X@yDFS1}rk1qJS#&U~IXk4-9sxqa-214~3~g&9`dvD)oJ$f|&1u;F z6l(3UJ38^@p_~1%d)&@n%gR5OOUe@KvAN_kH5B)ktECt`CS)v+JKa3A67jOwl`>+l zy}DIQ`V~j;!$CRh1E>LsQ8*LJN5*ZxvF?4;K$D~gFL^+yQfSO{5=z*uf}8t(6qO;* z25ExgWF#-UWRbYWTI&wjM!MXv*65U+%+zdqIZ7BN9j4JVTR;ju8x?g5ZkAHjev&;D z))G=0?Oa~+7mc>)F@_hAMVqv&C^T1VffH59^b;k`XlszCAxRr(zg5|AtuSV# zoxnKg%5QBx9?Cg>6WV?T=pQ`Cu68C8z@1)@r7*OVUo4NpClWaUsA9dUF~#|o6d)mS zU^|uIpL^KuP%&oUT|zrT)|dEV)9NF6QPP<=@#Y_u7(Bmx5#ZHgn!!(AaxEGr^a?Q# zJeCv_Ow-AwGx znZw*#OudnuebMcRR47m1tnK{=sWH?2o|(+Rd9jn2)?8neQ{pFDm`SJ8K)NW|cQ5es zhjgSSn*^zAYBkTGi?&j&-**!b7DwCsluCs#JAc5xq|1z*qt*s7m5WS*DXEOYaVM>; z{GL)RUp!b?*i)C|W_LXDDb#T7-~dmH==bqUr*==Pj%6E-*>PRatH6<`Za-QUl>?v; ztq&;`oVi<)fHw{F{KqK&6BjQB^4G=u`Wxx^|Bmv1 z)%^c!b@HF}|Dwb`tG{($(d&?};8kyW9{S?s(Y9p4YVuDY;u>2e8Co)O%dc*kv&7cc zwgWP^U&ogojk>;VLKn;wGWtSl$wafbR)4P1d~8+_8HtpayXQbXRUHPwD&M~BUSor& zKa|dFC4=;QlxL6e^owOnBuZ6;fcdr?(Xyv`hvgw``CY@Dlu~9`^t}Z6ZqYKug*MsZ zh?+-w4+OTRGbAI{b+MeB?0*1dsvj<@68y10iC+~RL1+k4qViyjzaJg49qoN(2q;Z( zZt#HD20$EcXSWSGPbFkbi|QAI3%&0D3L}2DU5AMZU)Tbx ziFyYOwX}icA(VyC`tAbOs;&39e?ht9wI8kier#x0G{+1MEvXPvs&#ZQTD)=I^tTgq zWHw@QhAY~YhVy-{TlZbCiKM$dK%vbCTW0#5*c@&{c^6ulMm2hX*1#!dOu&ro%|U9U zvtp1&h&@Z6cEkzay}J;UM}q9RE_xe}VCD-TWsMx-&B{ z{Y-EWHyt}X$(wqdh$QuHoJJaRkW_jXk>`XNByUf{nfF-2eg@rs9wB19b@2*HLMx3# zOzUi~Cup11#{gt7HB`!mqHvfkNv4y_lAax78p62?R%mq+>NM*qO6sv`EI4**lY=R~ z--a}CLt{1<16;}P&3vPG)&ctI##v~|j%R|p+v!Q)7dy66$yZHv)T5=xAkl7@IETDp zbZL9FG%xac1B`)-UAk(sg#U5ZMyZyfA<#fTeeD0U+h_i#+t<;F+ZaaoW1Ri&tq^Q; zGK(mZ)YF~lyRx!B*=kQ*=}-W#%GN_Jkqj*2SnDK56w(HjQ+gENK*@s- zdRh^Uy=Uasa0+EjERV6VKYugp%Gyn5J$|1yL$J8+ew-d%VGu&|HkzHAs>rt{!un;Q z?=Uw|we2Y+^y-VK#wX=z!lfT6Yndupu-b5yS-En5 z=;G_5kmX0G)CpZ+IlnA1z5~6c!=7K0U$Db=U9jVf4qdXNHMa-7Hcp#8HJ@OEuiUDo z8?e)EHh#0?l4R$sm{MQhm~=t@iBZtryf#;d(-K`VVE?OA{s|;(J#;^9t>EKawC3Zz zvM&U&wjP4fZQ*%%Fk{}N9Yf$9YH+K=kdaqKQdp9IRMuD(zA)!KtcmwRB#Xz(-`m7~ z-^10tIJrx+0!wXz|04C3-JkguB8~|j$?*n(&d+Bb#i{;%*5G-Uw_T{Qw{LgY&wsz@ z+t9*a3@JQ)1^1m`C>FCB{=-oK&l{BPWHriv&HF?ha$qjb&xS`%LeP{C&p?bCe15y} zw~&^IU&$r2z~b`2PdxEegNlr17|&>fX!bK23$-FqM7Vef;@Isl0=2$m` zrFHOQDaM;&hhIMi>dqCgu)>9{At5_HLJQ6^8qO5J0H9dR$?($80CWw z;dr(d&fs%RFjCVSbwLBGw#k(RvvHLU*wMOTIdL3GxzhpFHy}ub<3X%5`JnA0KGA*wSPML3G}N?%E6pBs%Bs zSQ19TA1PSoug5m8{hIyUukP4CYC1i~_|M)r?s5^Oxw^h?$AKlp?Y_&ytN<0D4|^-3lF>ZAB0P$%eD zhABQa13ZVwhp9~T3x6nC%lzZ$d|USWHr4*?)%xe;X_$hB-(Kvnzn? z$;vOs>P|FfjL};Zrr`(+f>A=>1khJS2rYIAcqi?AI`~7?0+1t{i>cxCqZCgjQUkxq z_qz_v!D>7>K8ST-sQ7N7!aD1}y-&0F~E%COGg&(Mnz|*Yc=tAOlyb8YtdoDI(Jra2g zDlJ()4?gV$z7k8vZs{_1NGD-63s739WNx@8h@nx651N74ZaqQz-9br3a0=Q*U4WBM^(xg;V~! zg0AyjLEGN3Jlv=7{fJ~gDbxZ5XmV*N>#w0dCQ*OF)6E;TJ?)e!en;F)m1BW4$)|G( zUAuCwj<;{y$hSe+La^I*{$ed` zn{6O~Z^2Do(QbTw^&+_OLoRDZhzwW%SjS@}Y86FSJy4-s(hq%8o@6X3vx8fzpT4)A zhO@Vr0`JGOh%M??QQ8XwN`@Iu2)OJRh&g)~5s|+eDYA%U+P5`E9a)s_{vOysGHDVG z-L|a!VyXqO^IZL{x%QyC=3p&u$zh{T^I_VJbUa{BrlFB9i4n%=K=4^^UA@Bxc0@ya zc7ZV_O9d512z2?u*7J*I!wX{c{TXL-&glU$K34>#E?M`YfAEkbgfoUTm zT)jjrD?~0c~W(ahK6c^PT5TtlG@2-mo25ja@N1`8p{b#B;xl$3WZ( z8D`KuVilKX*J#Y4sVl7eQAi@%Ws)T^rhzjLQ7c~8lxjNegatvl`58&7kh3dtJ(Dxr zM{&ya2$c(ZrZO5?K5$SZlu&^%jIAAXhgJ;4WUUjpGl1KFtBN;7|D(?Qw~d`23Nb!k zvmQ$M_>D1hMLG*(A>2`0;UA1e%!&r}qCF~5`+f`e3fn^42|9{ola-eGpWG8~P89U= zm{s^lhYpVTllvhcHg)Z2F z%?Kq}VG;n-^c-(0^3fyuDcm&sSQE{Dq3sIX3uC#YuSiSmq;$yy9St);r=r>06)?;i za*UNy)r%@y%ZoWZdG2P1;dmuWp2Gv{$cL)*>#T$X`o1sB#o(9y23R1-pCsi+*@f{R z9^D?mM(uD4ghpoIzJ}&U9iMD##1lr;bfu;xlfEO=2;q5B#DWJnhTZg<*%s;wXz5~Q zLiOdPy76NbBRF44$gABZ{xhnm-w5Yh{{PXt?G}XfIf4NJQ6v1%-i_rS-fdE2%5I+n zsT=czr)(oQktn~6aKa7AZ1;r{8p#`=>3Fdqtag%CMh263q4x~@2E_NgMM*n5LM5ey zVn!>p+w}+0QFIC}Y};qs!RPVT8jDINxhPFEwgR+_hU#t%HdY_sHK~e$yW;NlZG^CT zSU)4bNTC2uOshh%h01l&HDxF@BjwE+&5IhUE;l~;56e!HB55W1Q$q6)TdTPsU{)AW z!s^O99nT{PON{L*k}N;9IDo8%WH8_*Gu}=nSWrhsamS1e;1aW+EYTrrG9wX-LrEnz zhEcwv(a?lhsOm%e3@Tw;9@!C9j_zMfgUBV^V1qe}uA(N+1yw`;3Wu!&^k!E(D|v*o zWZ*D#y``rPdkC0U_n!wvN4>8FtZA0(>Kp&6grE--PInCZ}OF#MS8wBzTKgPWvfmIKu&g@)em ztpEOa9O?1@9y7K?<9pNC=|FTz9$=_-`|&cA;nZU&!HeNuSea>Fy2O0prqiOsqFT^T zz4IG<0#+&b&U<_3VUnwOz9x{hS4s%1oPB-?A|!Ra3V3b9^Z*0BI5|jC&`C%>oTY$s zgyM!q6q^(GhC8KngstZq6?k8Ac=k&@lI=KFHeHtuGZ`x=hg#E5!R05$>beYX?lgz6 z!Fy1~oHeCAnII?69i_d>1HXqspMnboa-C&v(ZVb*VM`IpWLJU4NmHiA(aU@0CJ9Ob z-C8*$ypiy#jq_>?#VFi!+(7r>L)5~#)!4~eFG>#`w{yf;@JFO~$=($dQ4U=p*^A3)pBOQNdV zud7cGC$}4a3KWuwNhMdAa!X;T*u$wD93JleIM#pNd3-kmx^l=u!fDRWCx&u3S+GXg zYTl*kT5~4$@O?SNgal=ja@;I7iX31Aw$Vy!+$E7K^wm@N0N3}5XeRTMMfFOu;@3NS zI0}8y>>;IVwIdl=OeKIeYIYOY(v%~`t8e9G)AzD0n0rwVJyG&+GTo>r8l5x2^PraD z)QYDJzg%U@^MM+Fh`V5R)N5n-T zr1+Jw^K5y0ev=m!3>v`m9y=KKDD)+w7| z(5C3OQi2gD?ga>kajvmbhoqScKctp;;UUq8O_Nngu1b$2zU44zTkv0SJuir+)D;rx zXApwf{5I*B>!^d-W#SlT?z9cIq3uDl@a5sX@#3k1QL7Lqx)yg~v*HPF0`ylz-`vDL zu7`YYaWQz(&(`l=7o#GG;?fSvlDG(~rF9cR-i2i4S51 zmXLY!w5Lt6``3M(Swm`>AFk@*07k%-A`J{Dwjp$54dW-!T`ckDG>HmChF6dK_my|Vkro1|FN3=GK`+j$`uvWx6FA>bZ6?GPm@+PStCt*bn)lHfk7n_^ z+VGy5Vd|UQ=B^x%eKxo8UCeb@8btT8)7O1CGh15tyXgs4YjYp3(uL$U;$ID=tjl2@ zNsgLO?~@nPS)1#iEXxY-eH!~et1)xHDse*NjN7AG_&*-c2G$G9?ONkN31D)p%^$^-#iVf3OzPbSl^(SZNw+B$yD*isEU|5gx5W*$#u{zJQzpq`HrOjXpS|Bh7F zW2Kn$y;wR(Qm*Ax@o0bS)>NOKFf;oZ*SLaSmIlFLSE*h!m2r_{iWd6Ri)&jxn;qH1 ztC0c+_j+Z6Qvz_pr2&{GJ;t0tcUD%6zNgRAoyRfgf2En;e=|OueKUl8|IJSS_ct}H zS;zD0j6gt!>%jl9Li4Yzo1U#b{)p?Be%^PWt$fNIv3n&Gv_v6*SA$$ z+wHrC-+K!~PuIKQ)7!_1i<^sAeV_n0_uAH`0H5!}YgJWJ*XP;*AZcf}Z|nBM)bE>Z zHB(?SW4p({mUF}F8c5E5$Oz4zZLb${AmhHxr&_UiNXb^x%DWa#&iXSuiT za}5YXiW2YlIrngD^^T0=TNChbQEqv9O_J#FZn&J17->jayY+6EqD^&wawnXU&+xbJ z^n~Zz*lcZkcX&FyoYJ{>kGq<>vfa$M%)TPv1fdQpm)-uNWt0 zrk$vrtmIlT=w#m3@zKL7^2|AMR2tM$7IRFux9hCy(wg|t#WDr-ByHnDNNNAJM8;6V zDUr&ceB2(hKl#}0o4Y`Ktbr{=DxCXLv9U8e+3wbBxjmZeW@sYV&;Im|bALLHJKsvs z_df*$chy{E`CU4=fhz0g5>Ce*${3Zk%y&Nx_wD8nSR;Acf35Bgan_#U>!TVxFJGPB z_Gz5Y$h-;Iz3Qx7Z;zbuYJC;FaNJkne^7ITYZe*|hxR6RvHR2cwe$JAn7DmEL_J^U zPRcj^{+Pbn?N|lZ95+J3fvwGHvF3d6+z@v5%4`{|$ZDKhIVw%^r&`at5oyT~3XQas z&?y_)e>Jk`ZOTum9Lu^pUN$HZ;*OwEQ9H%wRkp(=xJ4({fhe2QAZwr=P- z#ml@mX(sw6(XBNFyAXbvX@>jvQsFhh^_7r8p;X=7c4u%%6?>2K4W(6+h((fra!L?L z3v?PG{+O0M+2+>P;AW)-exQ}ER>*p~L`j|GyH`_Cv@gyEg-fI1XQxWg+WufMCiDWV zj>&!sIjavfDOYq97^Jb*kWxy~i+}U&L=@N91W8RjjZ}Sn=LUnhxYMxYFvjEn(|A2g zoDoAWlcl?J>4XXRarBOmUURq2rE_06!Mp|J*hTYqzs;9}o7YFv)X*1dCSlUu@<-R& zWt-3BC7FuGDXOp+jl9PaQVVO!dF4^mLujks?&j>$KHsCzCJA8ysZC*C%AuMWnF}Z4 zpALRnV3j=gGyrPJlJy3vQBJ5*tP0()!%U5?g<^Pw7JQrFKiq%VS}wuVujN^|HjmQJ zM7&p=#x68d4|iC&yM!w($W?V966_%8y0_|cD6%&sHTb35ZL`K!PXRm0aaH-29etK` znJ#NF>K5BMzK;*%hg}jeIa}>c`#UaAL)kG6Js*7*2H%HkE&N>XYb(H9He=7tR?mv= zhel^e$GTLh>jIlwXyz21Jx`Q#!+Vr_zh#^$5DKWK3TVcoP@V*}X_I7XrU-i5{9oVZ zx_B6EkuA{dnzGu^a+Ea>&C)5z7nMlhbzf86hYYsZzv^A@3W;VaSZE_@s>ewt4sx%2 zPM0rbQh$wV6u+c?QTb_o_-K6jU<&jUy(fdg2cY8~foN0JcTUQD^1(nP-vIB`|G8_F zjx2CIOAQ8oY^B;Zu>Y(ORkYe>ma8WjpJ!1(-68&sH(A+Ivlad5*IDqaWPcVj5G)as zV99Ui7WMVAd;#Y6p>yvYLtpbPk6`Gl>Dq_w*x2d&xLn*~zt!E?Ads02F?Zd#{4V7{ z=^Nth!|59V=T9%ZTij_F7w-_E2^QAA@n1uB2~P>|OZ zo}oWG;!e5_Ti0y`Z5dyplw~Yu3@n!KLirQ(r;Ph1SUCL4x&{FrptAU5>+>!5?cDym z@3E!Ye|JK|Uav#-`UH>LZCYE!wV7#K(oRn>AU)A^R%N$kwP%bDR#Nr3X_^3*E`9BVG&CI8-5&AZQ~ z$FtD84Ci}GPP91aNp8tgmZs&~G-c`hqlnG=LU0#AEcy># zi2;e=JQrhLNWQQRsH$ZH*o}!2h9GZ!5z)(uwNrHMLHY6`j-{6@|JCE$j6QrFHt9>O zBix7*mC}VfG5&UF{@eaJr(Ngk)AXaja6z~4Bgz(q6|*n61VXbG0w)ViLF3?z8P+Zy za8Pt%nGd*sp1=C7G$2>w05W09q3SD#ifRFE%QOO+db}*Y-RKs3#lYY9EY3r$>YmC& zFGuPKd7H11Sp=0}-AIk%#6eq_+&l($$H{6$DBO~^pn~AKfaaXqnY(Ep$chsZLecOl zFlxd`|8|i97B5-sHBSImVPS>z4vDa1gQFiW!Lj2oM3wWE)vhhhEFAZ5_| z(-yKdVm?dX?`jk`gbAM0j-j4h(@Mw;JIHHfO@n3RA|5$fKNh}25&?y8#aYOCa$=QV1_({jV2o*Oe-y`hj-xp=sdq<==*>@^B zc#62U#0k#(@8qlV(RK5OF}T=8N6nZ|HMaa%irm4N=|go;T*(e^2gCYmIpj`u=LX)~ zCh%G$$IbQ}zUReoW_)D(yq?}=e`h}l*ehW)zKrc+Ogy4# z0#e#49P^jfG{Rc29mv|S1-ignB&olTNmxjBEF=EZ(gYon!O`0JGbOeW=@Srl(1B4g zASeX%dYK#z?(PpmACY(lx7+x(0Sshw+g3N@`FSMGe-{etghDpQREe7Za#70~riq`l zjX8W9WUjy5jEA6fs@y!m)@nV{hK)%bV=7BUuN{?5JR}>TnG1^rpqE5c*fNv*IO;|) zX`_Ld(iqKC6ls`tH_q*H{IX5vVWF2O@^Vk?+ijjvC6tDc$VKL8ysRg{P%*~N(J!~L z@upX93h9Mt3A}r#E|aoIMYP*^lNDFEhAa)p0T9HtE^N~1yA`PcTsPk?2JCr1pCB!^ z-%m~{1qS_B_tpfR-<21FkKEaQ=<#N+@5_T2x`Y=UNP)@H7goFUOjNzkEpTmC&vID5 zdHQ$EociW}+9FpsXU&s-ULID(-n3-n;9uD5Xxl!bxISdDE|nvUywzhf$(I&$5XyXB zS`Pl`*l6^=L}niZP~_SWAh@99aN2KhwEXFJb&PAf-*kv`ZM)24<;Qa8(pgugm^QSo zmV-*v$2<+qP}nwryj_wryu8c{%61_f@^R zx89$rsZmYM^h~er)xG*Dhby6ckg9N$ws78r&u}K?o0-qmM%CLu| z<4?ZvtWLIgm+m1v*$P`5wN>k-lP_taRTpk&8yU5EGtId^(;9%mW$HrF7A{aN^$+HV zSF}KDaa;Z4ptaE8GN03mx zQDeb4*36TGjf1>siSOp#uSI@q7JV6qot#iKSTSidUU^^kqwIF~8*2b=e`Lg(Yf|-} zt6DZr#d2bI~=w-SW2N3H6aPmo%Pj@EnA-OtU}nx-_n;FajKq zH^n3~)}nF^eyk?o0gimcB`+uj(yL`S{UV@)7{?%wgT zh8uX|b!HBl=@}utt>${)S2n`+QV6Y1{#xTFr?zounAB*D;yv`t#B!FJA<}9DQlDVW+(P1KJ9tqS-k`qjPe!;n$6+C!Z&Llitr~q9HvJ z@Y0w$k&bI^gkH1#hZR!K31=Iy%glxDE^@435gz=XgRz3jcvHNcBeasj|6Y>qyd9VJ zzJ>>e!fd3uO#&5Y-DbiZ^Gfj>0wvtg!wUGV&#Jc1mN_L32j`y&7Xs~IC)4b909NXU zeJ7?XQq7f}a-24$Xu@|A%<71sd`Tq_(9|B)sLN-^8k4B!l@z;peT-zh?^@g zBSXSsDCWw(@=~vTa+-qaVv?%pNCJsKtf(>0?7nrsJDbp@c+w zfLMZ`n+hcQYhc4uvLesLoTHeFGgMe60!t&KgwY12Xe4@oOiRQJxZTR4rkA}}8_N{w zfJ|y27Je2Cd_&erOf*b?vq7?fc4M8M^nt4*w>=B-6*&cWW)V{yve*dczEo_=&ZPf_ zS3ba$X~vdtLC`r_X1@oSZ_lz(S3eQ7mNuCumB+;Q2jVe=7$|}~_tH;YKl5S|=m4i= zhyxZ_@{5%Fm@IbcAt4XumkW-Py?r0Kms=@v$e-)ygg_MH@7}daQ$7+EQ1)jjh*Fe? z9uXnO;xi4-^m9S*(jhp_hTL=mW)!4JDOGPX_k)X-gl86QyAp?AwYZ@{w!z$$huOQ@ zZHwUF9#?N;Xf{S$pLN@=w0pqs&z8_D8-f6sK<}4XpKBAgiNyqS16!jBni=Ak@+Yc0|?k zuycK?mWh~26uuP*P+@}+cwGKdiV4a90EfPYU+K>(euS!R(+=7;4-MRz$1$1;j@#*B z`5^AkZ^Au}b#!`7CCjGX@v+Ty!q1Z?-Rzu3l*b?<`1i+IA?}MYpUXR4Z(3X!S=J51 zC$LdMXzFC;^AM|MYu9#fhzeXn+(Dq{i^#|V4l;n`UJ~C^tDLla#oLNvJq^)I{QYrO z^{|{Ug%dOCTPKSBQ}JDE@3nnZpdEY3HIcitRzp-isV!}7#I9jgO`_?y45{={oyz*q zg>lliU4YsK5Y>yP{=4e@0{E_gl{C^u-o~v|(eYC#IR`T&n_a|Kchu1XLBQD4=2$do zk@B$T4Nu0Fx$SzN|9UAEL$o<-`PpLE)VXNlnIct%gqrj5%gvGBH8SXWDH|v=Fy;d0 zHpvS)Yq0?G)R|(AT+kN!Er7i<&-GacqCP;KRAF`>sr%PB^0k5T$gXI8AS7I2Q>m<+ zn;~`44d=IlAZaG`EuxE^iO{gE-X-tyjO_0QCW!~y%Yl=(kCMhvvnzxun&4Km+bsp8 z+1fn-Tg#@59v*z`Adi>N^mt9W+wrQ-DzVIQ&l3_>ucm=&LM>vG z8n|gr;2pM_m6X&HNkvkBoZy(Yo+3lp;kdS`6oD-LIH3ld9rA2?mm{N} z(4{aj)lRdzM{^CeKB7vQq?v#aM7~+#f?axIDb0yuoXhS^2ac)nh#hBQPore~Kg;UJ zc?7Xl/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
          R)F&%}$i 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 H$GiUmEcVAE literal 0 HcmV?d00001 diff --git a/doc/泛读报告.docx b/doc/泛读报告.docx index 84a1becd77563e3829d0789102259ae36df8de8a..9a4692829ed98be4d28dd66fb86964e9e0beeb6c 100644 GIT binary patch delta 143283 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 diff --git a/doc/绘图1.vsdx b/doc/绘图1.vsdx index 482066122cc8c3c5c8a75abeea5223ff83608821..b9c5a8419f995df080a6f4e657ec0827bd275f71 100644 GIT binary patch delta 2178 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 Date: Fri, 19 Jan 2024 08:10:20 +0800 Subject: [PATCH 09/33] normal commit --- doc/cache/~$$绘图1.~vsdx | Bin 4096 -> 0 bytes doc/泛读报告.docx | Bin 153975 -> 154013 bytes doc/绘图1.vsdx | Bin 43155 -> 42479 bytes 3 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 doc/cache/~$$绘图1.~vsdx diff --git a/doc/cache/~$$绘图1.~vsdx b/doc/cache/~$$绘图1.~vsdx deleted file mode 100644 index e7339ef1fcc14ce601709dccd6f848ffd682e095..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmca`Uhu)fjZzO8(10BSGsD0CoD6J8;*3Bx6O1pwz`zP*gT(&*|NkE(%nZap<|r6K zA@CRIR#5znf{_^lK@9moSi+#d;L4B(q>C6TL0Oq-AO&P^+ zd86#%9RjYduEZxaEGk`r?M6yWFgLU`H^E{qu|nnyh76Vr<_zSTL8#3_tUHFPIslx+ BQh)#e diff --git a/doc/泛读报告.docx b/doc/泛读报告.docx index 9a4692829ed98be4d28dd66fb86964e9e0beeb6c..108df28f038ef932882ad9d3ee76246665c6061f 100644 GIT binary patch delta 11359 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 delta 11318 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 diff --git a/doc/绘图1.vsdx b/doc/绘图1.vsdx index b9c5a8419f995df080a6f4e657ec0827bd275f71..39af97a67d6f6e57eb9877dd000928b45df99cc6 100644 GIT binary patch delta 11580 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 delta 12248 zcmY*y6nkeUcl^&H>{7n z;>wP31_-RXQTMi>Dn4$eJJ>U_NnLV}r#o&YDuC%FVgOZhWePcedB0`8#^#!6@gX56 zB(ui{nRI3I-yL3DA1_KL8<8a8;fPQbTwtRBnepQ|a2oYiB~@zmN6bK8o~oG|22qE) zQhG}1kqO#mAQnbD8v@q!V(jcjZA}5{@z2Op5f*AA-$b{V823sOMAN$LG@(a2vyIe?>-OqSK+|mq<`eUwUSxS{cD(+oq># zzlQlPM!yd>d!LCkf`4jCJ0!eV)BJ3fM@=x=ibS+#3L=%SCjtIpBt%>L=vE%>C5Qh( z;*(6^XFWT?_*&VfN?j!UKSL91e zSWW|*j<5>>SEgedY}Er88bT?G*OnwO#$?T44ND-qMtVwCTfzk-w4g% z^Fgt2WM3gEHL4=C<-Vz5#XTsAc_SRq=tL%38w48)w>@PH_O7HqK?? z?;CUeT_cpsTDUf%IvWm1ZP-hK?B`x;ys@E*H?34>4W=^}G#7;5YGUcmf89s$l?A@O zO(%-KEqP15kvE@<)vvT@{}|xC1c@d+c7c3|;+utAI+h@W{znkr(-3f+DfyfI-`2$M zovC~4`8xSVcbhwoR*i*5c!6&kA$l0)ZEdBUi}GwmC<5Q__r8NaAT#4O zmG4hdi_`7P8>U4Corep42tD1ten%N1*0EuuH~pwXudz!Dg{RLb007|Q0|ua>oZ8NY z+VqXtP8hw_;mOF95CE75|2H?UN(eybCPpr#^4@_MNgut<6cI6Xw)zj7oXv#_O8C^j zjZ;#}GI@sw=mjwar6=O7zk*562b|9xF?)TGyql)r+n(tpg7$y+*MlYu|K+NGMYSJf z;ohcQ@KZ4>8ro;en)d2;NZ!?kI_Pk_8g(L>8fT_LHos@AlO_-!}mZy{$-^y!%<(C?dbowL)GON498vJ%U>63h7Cp7g>S zHfpwK)aDs&x^KEc)k00(1H%VBdG#n>u~pv^`8#(K@zojhci+OXTg-LoaD-p{&%xCf zG;QM-SGMf6&sKN8MD4!yn*EmIznoPb*ZT!usfps)qTUWhYxiGEBO>Y&>`&dHqR?sf z?pdB!&t>gS?E12-NB>kTX!^O}z7sJI&v(wdL`rGlJZ(>VIMCP3vjwgO*&Et-(Xduz zubR8H+QBCnL;>4BkjSy2aGk1}2pZPS->CK>v_7(}KQ%}|Aw-4hEr3~Ye}-pC%qnRU z+l3$3+qFJu{KKlwQcF2#bRGT^>b)PyLA(xZ)N;G1CnlAYTazNda)j*Rq1&i`V2qWk zJiq@kt?Y_Amzw{Pk1{po+eqv=zRg`R6f}XNgIjh1s%?Gla4ttS_l*CdD%hap!eqX} z{8ncE40pyAtD*jwfFZ`OL%xh*U7^8bCH;hOL5^#zWm}6Kjw-awknL?})Y4GYYa@=S zi8(I(my~_371*R>vHoHAcj@s#n54s~repbg{o2)D50enIa5IVMa6iWaw8ge+ zUZn1(mTw-alJOskaA&t+j4wR$m19RcQyUnRDR0aDskmE#@8pZWVE8#M&`y{t4YktG zyxyo)z?qQtM}YgBD2bQwMQXexL)nW+-O^kwh!1!8CF7#KL9Yuj!^vD3%>>VA+ohJu zYkDW%O|0_oaEiVr&^vGJ!N0pq1i=+iCJ^96S}gvgHiytwoxs`PDDG)(zMgP_!V!mj zIpgvJ{sJ>-u{eM1nxot%t9?(_f5-h1J9R@}{i z7)oODc9CpkSqhYvRRXM{cYi~rvJ?>Oz`j~Z0cEpN#5kA5)74dbNe*_|35CjJKICeO z23b%vF6d2yN?}@dPQy}|1Xn6JB2K*QXGHS6RE8EkrYg}sjifWZkEXGh$CugL{tB*u z$%ZN;9c-I1thU{k$;bWffK2rpE{D<{;W zUF9TLa3$kFB-o!@LV92I1scFN9oTK*gMe!_JK#nRTzD(%QYsq!3+xm4a#>g zQ}SiDWd-G~ZgMWVCCjy61L=yevGwl|+v1K+L<&t#Bot?ZyUs|TojXbvYQOrOicnsE z&tXC8UjTMbg{r~^9da$}`CU^MIMJ6s+m`cOd}o&M`m?RgMpl;LlQtjsiCxkz8s)UJ zN_)Z+@6fvlX{Zjh4zQ5TFT1n=;>?K)IMRKeLl}3UROQn^SWwD5lvBU^0{;579&dt2 zQ_Nk9t>NARw=q_6iLRhxIk8qSb3$(NB$hB1@#^7bSmHJK6&U5+u1OkYgC4jsTw)-L1Wu(BG_T8C;EF8%Ql&DGv#1BpcQ!F1VIhDly z(aOjgnRQJ)#N%+RGb?VEergk2U{ z=!r}vS&yF)UQcIoo`wD6+?b;pd)id6o^EUfYeBWIEP3|}v6->esPYK>shX4S_o=%? zyk+CK+QGEiKD>$MVOjR&oBMUgiA|d@twC6#*1$sau46V6Wgp!B4D9(GH@*DeUen-*? z?TmgZL}UWnG6g&P1+q3p&hSk za^Il*X(Emb>dcy);f{B$BGnDrd-jJWWc@Y*sHH{vii+@bWZtK4p(!!36w{mp9ovwZd{XIYVmMxSA!u}%XyYH7(D9X~+@@Hy!)O8oM@PW|8p{~*o$}<3UTyi0xGro@z)Tg5&}%oxnLmfs<&eIxxfW?GY=indJBQ(9}ec`?OrzH z(R*{fx>8(gfmjxGetY-!eyMw`$isFqo&*I#Vg%t$$~a6F-0mPtQiZ9GY-z%GVjfRd z5Hu_qjHHRmGw0=Uc*Ux`lTH+8ai|{L@q~suw-t3|0Kyj9grYj*T5t*Ocsi?P_ZMqf zVJuUx<47!Po8O{`^SxkfV1ab=yBP5gfbd!8QA~Q4M|#c^Duh8X3UiE?IvkAO7Jo{5 z(pAS`ci@p}pIQ^)(4%xnWWLT7&^1v5Did+Fe%B^RxVu#M({NPoM~@|K5b1xPLv{dc7XmI#H9-b(GCj7^Fx45nryzLbmB2mUA@IQ%EtY)C@%ISyamCU7w>u0YK4?Cxzbt%8JW3Dx#CSS5vL`BvP&#DEaVr^?H4rucR3Eg@ zZHjr^A=yb!okmWA>eZWf<7L#4=@rZ~O0jodyBV+NQ!r$prmKKm=F_)1Yy zmpjZuUs4z(h7I)~C6!126D4_BM%w7hr&8tTaE$8K?}$)uj5Cfjx6rtYC7{%Wk>?Wz z68;YeWKwv&hOk}yn4D}V^yy|FbYdp{6)dtsG#GgUF!^b@2eq)VhH`8q8!0xh;rY0B zU>R;G7~|S5u=Crbsjd;Ba)sBqvh`^AlREq~swn$Tv{8|sLZJ%kcGa&Bt`%E8C-iaZYG z1Gs2W*(DmFn=Xdoo0uWvPG!Zw42+Um#+lKiw6E6L$O^dYAshs4Li7 zRI3~wkR^oCMXV_a>t33Gikt9m6K#8DStvgAw$HtH?C*<5C2eB>!=vEZ+*8TqWUItbURc&+JMzsy;VkvV$nENpc#U%B$W32+THet4!v17 zqLQ$FOqOrg-NL3{9IHcVyxug+%<EPp;_XHgwY3$2&6HUxUZtW zW4#ASkWdno%K+xh-O~zCZa9u33Vr2IhSspHibr&&ee`SB1E_JE)2JFgcKRZXwxnvZan@eZ8P*5p^MwHt}G;c1D|0We3b!%-kKS{bC#lb3k;=}B-=4>#KT z>rm#V>Cyg<+`k$S7^ktWFQqGal2OIh zXr+4GoVJ<$Nt3*QOeiU+2@6ijlB3WGWY`5(&{?|N#t{#Qf00%-$w^7X@}qLzsbxZg z@h~H!&PzZB35awnnKSYg)>_X6g@#6wl@f|6;^6)ZqfN1E*hS~fPjy8^KqLd zCED#1LkUzdl?0hm5GV9T$8|x`8-ISkY*Yl@Yd79?ZgFQ3(#j~iRHy*0d9hPx_MU|u zw7I9GMW%+pbE-0PJz}o~tFgS41*`{&#rGf7K`SiJ$XxnBQgf^0-U%&k*WVhb?kISu zGs>VNdO~QOx0eQKteeIgT^OYcvH`zla|yT8a0j9$`c2o(HsF{4_2xuc*6SPW=FIh>MVdTEJhDNW2EeELQneCDRl z?3ET3Y0L+7CAUbGbTACq8jF>5^zJIGhgY^)pSR^A=Xmuuq+6f@?s~s51_u`{^K3|u zF9wB#Bi;)?PoZ>pFkf0oA^>A`5Rl3Yx7sN;LOBo{N!Tolu2T04N@`#==^)hby>OsY z$!$4owUOAlNVE-UehYJQZXalfWkRqH>QmCZf>=5xgEV6FJ#j>0yjx;-35|8sF^|2@ zM8gg>*{kx3vhM!++wx#AYaR7t0p262|GHg$0|HAw+>w-;Fq%0=AOKU4w8WgqI;+E2 zGY{DhtFh`Dj3N%5pkOr{Vm>V^h6n1*z)nJdU1$(v@WS|NZ)XfO(jK&jYmug~_Z05n zcReAIFDHg!=m>oFgq8jj;oERfxGOn}0|oJyv3*eVSfBxm(-NL*R`$Tpu{VpRr~X|U zoGjHH{L|E5fI@JvVXkf%6&<{f? z(yguDdoA->ZnK?oLAoM|_nEku(8T(2MJ ztI$Pr#~bDxp&^vwBq)@ii9xFZ77f)SZwm>jz$v+`8RhA|jJnnA)Xw|V-Dzdm?;>_u z2Fb`ay=8YeGRV>_Y7%qB7l2BoHp zEXb=c&@kXNc=iFd@BdaF)%SVt#14#T7DZ4tp>W}bjsxwpnrr*SqCsiR*6k@r2cVDJ z)o&k~>Cd};mD#1e_iMj0;@BrLp>LeT^WzdwT?9HNlHAg)!%Sy<3 z6@f%jvc(Hj7W0vony$kOgI^(Zc+Qmb!&p$&T(mtNF(D_tq~YE~MRripU2|sUKoiP0 zC_@YzD#>W*uxaf+88wdEl%4b-bxmrpSkQJ`;Wi}f6V})MD5ssXb;dfb{>q8k2n}g1 zIGar>F5&~r)L@-_aS*mn6&z`e{0lnXRYM6jlk?NoKmLyUS0=EMr;&~v8#g`E z8}III0*LsWMMA#Ia(>-O^M@MdSe+Xwc%e`F*F{yxlH^9P`}|G|17~GAD08bm^D8Fh=DR!Di}*!`97T0-iR+?Ccnv^*}d?YaXX%C1eu)C8EiBQ*Fz zTp$Y{C6+@{SO^H{sVqR#yhEy-=O)t?!45TtmROfTJ{zQrkDTGH8UomVB(=!5@%b-E zJq*|gX3yq3Qp1fVg`==D7(wJ!KkTpuc|!v&^H`ddK`o;#;F8Z0yL4;C8h2lVuj|k^ z7O+s*L!3v46LmVEv(kvy9irjxZNn*x@0D?(0ZRDQ^aD%b9x$>4mE;j$zXuuh6l5#= zU}Y6&sU9O7KSQ-$`@)u!qO`k2!NUH04VICSW1M$X{UPyn(M~{y>E}HW2A^{+gSH!k z4;rOJAxL9D*cyG#5{kL?bO7cG3D?ClWv3*=a;L76;ByQdJAMq6bCD%fV2rT@O(64adim`iCCTOpvZM<}&NMuqR_-!mb@_ zP`CB@i=aVgmzzUN{IA4z*lNx7xeW{wUqJZQDXl`J{CmGOhD?0a&g)@qG!l^`=c z)J7;a8C=zcnI+K7br|(0Y-!to&57T$f2)Kapj??S1_@eAL0kTWkQ$vUL|Ch z1%%qr_8T$gMuHEZI#aI*XvH&L{$z@!B1cC=YL)gg3%6n+1A*eX^LZM*%f_|;DYn)}C+ zLIGmKA+9$mCg}iCji=C!t22wW-zAw$U}G-KjkneNpb1Cs2j!DJsc8Y*1XdL`(!C!Cn`5^ZG(H`T{&x!9CI)}rQ)2^(kq5mg zp}L>}0C=R-?}3CM-C5@~PTTq>|!xPDXTYrqLg%yd`xqoCLmHds6(ytzb+s}Cp4iNGN3$ny8Ikfc$UP;8P{LEt;? z7FRc}pG`c9TwAx5a+hKffowxjaJN>=AG^w(4zb2UR(&MUnw<$6nfw8XA+}8>Yo=6m zdW(mqkY%%_pqDo)`Zo~*KQ%={@pG~T@M{8TJKu)1gIS&p%vCXlQ_(1}(z>qin zj^7|hPVRio{#MgT(aRW0_pkERbu;obec;^I#k-xhl zXt0=EWj(&&bPef{o782erR!-IWl(5x8PE6`tCp(^B7<_yJ3J(^4RPB%=1MBVp99_wBK?|4>fGNi zDpW2RVX^a9CU2}ZC%!L0N^j@Odqcn%o>UfZ!f~eP@L5E?%xEfx6BhQlE}py`R*)xH z;ybMd{bWD&dZ~+sK+!fYsm}m^Whws1DE-;ZN!jtsId`(Xio}VFK#C*BWy5U2>C3^k zf(cp%$edH{(p#td6vwaZ!)f6V#^dSrHit^bhF38Uxx+6J(uZmP3y3C-HPlhB>PKaF^-4jl&yfxE!t6G{Hc zR^Bv6W+@NS=jg?DGkiC~@l8%hpYD3(lU{nBS>^}s^-f$;f3V>-MFk6@AVpx$qcNfa z0G+90apa&JkV^V8(TG_Gol&FpI>p}s@ka!M#?r4XLnke3t9t9vxzQ%7s++Hx;dZS# z&3smBt*efc=ReDcLAV{zmhp9CS-R`h1|)3Hq1A;1AWG;E4J-{j_3((90FNpJwx#Hr)LdV?taj9kQsnk(s3x}4F^}85V@2Y zR4q|E6!30A0>JyUfuPKnzv5~pg9qvcEQa%8)-@eqHBnofP{OBg4At zNT5yeX-)^=cNL7S7YqMg8pL}k94x|@mzTZa_*gpy5kv+$y2XWsutnP7NU~yBawL&+ z#1*6HXN7GG`QATDgYwWA!qAU;)MD7c6|9CjoNg zmmzuopJtWqI`_W`KGuQW}_XgdK5~fI;wN0H&PB>F#;3K*mv^l4vhq7whDhh&voJG z9+grqzRWzOT8{g-#f4=74Jj`KW;iWG91%PijFA@@t`-vcK3yNGOBC`AF;0S`@D<3h zRFK^W`VAMd)UO-Y&zPWMMV}$0a=^2j^Ww`Sdy!Ql0{e*4)0in~NKak6j;}Q1CGSQb zf)xU7n(gZz=Dh9sjXBd)w2dI>s4^AREQ*w zWQVIaA{5ph8f`)r0K;QIOEKzii2T<>Gj_6d6lQn(lrc%uYebMLV0O`?v!1nzeP!0G z!gL?cE+#`U~_DBOsR0EWgJ35Z+MY%dzIH-)c|rt zdy}tG#9tAM1a8nt1kAd!s58V|{WBx2go3tyvf{t!Bfv*_5e$B=l8J`Jw1mZ}qP-hIO$-n`Ir#+IX<3i; zXzegcIgs<90Y(w_?Tos7-!b)%h7XY#k5GVy*FcK#ltdBv(FapO?tid)qb_&-@tYXI zP)l>e0u+`xYw@zcIXCiy2go`B-g}Ui-<>`&eEufN@ z1@7F|+=g?ZOtvl(((i2Lfd{&70}`X&K_-@Xa7JgMndw&;VGZp0AJyr z5;`)JA=z=bOL_ia)#bV6jsFd?Q>sR zp~y!gg=Q{yA7>e%Ah*SYj7aOjqf(LfQBlgKaZJz*X2r#Iekju$GRahz&hK2-oBP$v^=SK<3LJJ<&c6h9;))Lb#S(+i{DD$kmFaPCgVS zu9-c_YTqo1(Sux_c994)i55A78D?**p|!4Dv@1}dyILTOLPSGSq}mxrh9d)n|D(qa ziK~K4L^XN9xD$a7P}mVSAriPB8ksp!Jms!l4+Ih6NhCQ`SN+m58~-bJ#Y9O<9>#@r zHnV_1j!u{r%*fRP?KVNQNnevn`B{Z8S-Wv-%qLC=#r#NYqIRXB)cOSl$mHU7I`$=S zqRD1fW#M`l2H}$qn|AuZZl44w8a^Jo*RIE3lY>JjU2)q4{3Ph1W0&KVoqAsQ&JKo* zo~YkyAjP`gR<*tZ{SRXOdor^j)=NLZHxit={N!PJGjC$7h#Hl1#%QO5L@97ad+nwsg8Xjdjq-BWG`sALASro zcb2$_O!Hjw2JBK%^8}s3m|HuUIzs)Ccgg<|qt%u@o6jo~vC4Bdfj)6vHJ5pOlcx>7nWePi{3gXh&lT`JeFv__; z;iX|cel5xl8hd;EJS=sJKr|M%Pr&SC%ITy%Hr+ZE5XZpp6-Sm>?s1U9+SznS>sMEJ zBk2W&!EH1aCjU-9VR6|jYkU;@n>P5VdE@9k4|*bJ;8AAy7k z&k2K#U#l>+;}=NCIZ+9n*^(+K>v#NfB?}vTbleyD8wp@tEs!#(=V6A`hgFc;Wv38p zC{_#j)!lJ2nQEw1p{(+%reOlqDf1fIDKpC|*t!FK!YgU-)4@EBx=t#_$ zL2(00Kc+8Xg=LJ4HUj%+ zY{e8sbO%X&*AaOQE{^gI$f}o%v2!KIN(`^B;~gb!Pk zwcnOhpG7#M%kCYfs+^SErMhcqOX6+3Vj`Cj107+!gTWl3lyvw`5V@p&w9sAmwxk<e}6JE z+MEj@Ysgi2e^q%uytUop8$ub}7wWNer~eG~$8+h$cPP-&dE7ydcHz%y`CWr0g2H(@ zs>ITXP*SyAU`Unj#*J65cNcu9%v`mA={>0dhVsaj43B8&w!ThK9ry?sfZ(wrtW z@)rK?(_3skHN8_OO5Q2IpZ#r(?6g05on?WkH8d=lv4B}j=@CCk_wM-!>Z1~c)8WM8 z@&2(!;Bb+%!CRhSD?R`!x++#(0OD&_gj*M*DD=4Y7SJhd9)~^6`oJ1Z4*6>$8^jFB zA$s|g4IWs@6~x#<9G5t8S3;KbLk+ABj)ov-hZ%37{MEPc_lrm?b6-WyaHSx5ngoD{!%6)*F)VU!i5bIJ#P&5d*Whte z-;1#6{HM>^2i^3QPYxep*ZkUw6&2DKss=wy!YsT_T1S$QOhBg*f!0%umtpfi3~)OtX}suCtG2_GoZBNeCF@(=-Hl6c`c+V{f^ll1=+TmS&p{|WL0r3RIX zLYs%A_LMS`{*N_K0|4;U11oDoGh8?0=qvRE{!y=!fi7`7%-H?!459GHTNQ e+(b7h0Koa5R3GR6%w;J|9W0}RUo8HQ_x}O(W?aGm From 8fcb30a26d6b9db3e5c52c7ec7d3c0f4311b30ad Mon Sep 17 00:00:00 2001 From: eee <719747958@qq.com> Date: Fri, 19 Jan 2024 08:33:16 +0800 Subject: [PATCH 10/33] cached not found fix --- src/kernel_liteos_a | 1 - src/kernel_liteos_a/.gitignore | 24 + src/kernel_liteos_a/BUILD.gn | 442 + src/kernel_liteos_a/CHANGELOG.md | 338 + src/kernel_liteos_a/Kconfig | 341 + src/kernel_liteos_a/LICENSE | 28 + src/kernel_liteos_a/Makefile | 198 + src/kernel_liteos_a/OAT.xml | 85 + src/kernel_liteos_a/README.md | 105 + src/kernel_liteos_a/README_zh-HK.md | 104 + src/kernel_liteos_a/README_zh.md | 109 + src/kernel_liteos_a/apps/BUILD.gn | 62 + src/kernel_liteos_a/apps/Makefile | 40 + src/kernel_liteos_a/apps/app.mk | 32 + src/kernel_liteos_a/apps/config.mk | 79 + src/kernel_liteos_a/apps/init/BUILD.gn | 39 + src/kernel_liteos_a/apps/init/Makefile | 41 + src/kernel_liteos_a/apps/init/src/init.c | 99 + src/kernel_liteos_a/apps/lms/BUILD.gn | 77 + .../apps/lms/src/sample_usr_lms.c | 250 + src/kernel_liteos_a/apps/mksh/BUILD.gn | 100 + src/kernel_liteos_a/apps/mksh/Makefile | 56 + src/kernel_liteos_a/apps/perf/BUILD.gn | 63 + src/kernel_liteos_a/apps/perf/Makefile | 62 + .../apps/perf/include/option.h | 81 + src/kernel_liteos_a/apps/perf/include/perf.h | 163 + .../apps/perf/include/perf_list.h | 57 + .../apps/perf/include/perf_record.h | 49 + .../apps/perf/include/perf_stat.h | 49 + src/kernel_liteos_a/apps/perf/src/main.c | 90 + src/kernel_liteos_a/apps/perf/src/option.c | 182 + src/kernel_liteos_a/apps/perf/src/perf.c | 136 + src/kernel_liteos_a/apps/perf/src/perf_list.c | 129 + .../apps/perf/src/perf_record.c | 203 + src/kernel_liteos_a/apps/perf/src/perf_stat.c | 149 + src/kernel_liteos_a/apps/shell/BUILD.gn | 44 + src/kernel_liteos_a/apps/shell/Makefile | 45 + src/kernel_liteos_a/apps/shell/builtin/cd.c | 54 + .../apps/shell/include/shcmd.h | 73 + .../apps/shell/include/shcmdparse.h | 65 + .../apps/shell/include/shell.h | 109 + .../apps/shell/include/shell_list.h | 574 + .../apps/shell/include/shell_pri.h | 52 + .../apps/shell/include/sherr.h | 59 + .../apps/shell/include/shmsg.h | 75 + src/kernel_liteos_a/apps/shell/include/show.h | 56 + src/kernel_liteos_a/apps/shell/src/main.c | 190 + src/kernel_liteos_a/apps/shell/src/shcmd.c | 594 + .../apps/shell/src/shcmdparse.c | 154 + src/kernel_liteos_a/apps/shell/src/shmsg.c | 685 ++ src/kernel_liteos_a/apps/tftp/BUILD.gn | 41 + src/kernel_liteos_a/apps/tftp/Makefile | 45 + src/kernel_liteos_a/apps/tftp/include/tftpc.h | 309 + .../apps/tftp/include/types_adapt.h | 88 + src/kernel_liteos_a/apps/tftp/src/main.c | 160 + src/kernel_liteos_a/apps/tftp/src/tftpc.c | 1718 +++ src/kernel_liteos_a/apps/toybox/BUILD.gn | 84 + src/kernel_liteos_a/apps/toybox/Makefile | 53 + .../apps/toybox/liteos_a_custom.config | 186 + src/kernel_liteos_a/apps/trace/BUILD.gn | 34 + src/kernel_liteos_a/apps/trace/Makefile | 36 + src/kernel_liteos_a/apps/trace/src/trace.c | 141 + src/kernel_liteos_a/arch/BUILD.gn | 44 + src/kernel_liteos_a/arch/Kconfig | 33 + src/kernel_liteos_a/arch/arm/BUILD.gn | 40 + src/kernel_liteos_a/arch/arm/Kconfig | 103 + src/kernel_liteos_a/arch/arm/arm.mk | 76 + src/kernel_liteos_a/arch/arm/arm/BUILD.gn | 96 + src/kernel_liteos_a/arch/arm/arm/Makefile | 65 + .../arch/arm/arm/include/arch_config.h | 102 + .../arch/arm/arm/include/arm.h | 1131 ++ .../arch/arm/arm/include/arm_user_clear.h | 50 + .../arch/arm/arm/include/arm_user_copy.h | 36 + .../arch/arm/arm/include/arm_user_get.h | 52 + .../arch/arm/arm/include/arm_user_put.h | 52 + .../arch/arm/arm/include/hal_timer.h | 64 + .../arch/arm/arm/include/los_arch_mmu.h | 80 + .../arch/arm/arm/include/los_asid.h | 61 + .../arch/arm/arm/include/los_atomic.h | 892 ++ .../arch/arm/arm/include/los_hw_cpu.h | 277 + .../arm/arm/include/los_mmu_descriptor_v6.h | 234 + .../arch/arm/arm/include/los_pte_ops.h | 181 + .../arch/arm/arm/include/los_tlb_v6.h | 92 + .../arch/arm/arm/include/smp.h | 58 + .../arch/arm/arm/src/arm_generic_timer.c | 183 + .../arch/arm/arm/src/armv7a/cache.S | 80 + .../arch/arm/arm/src/clear_user.S | 100 + .../arch/arm/arm/src/hw_user_get.S | 77 + .../arch/arm/arm/src/hw_user_put.S | 77 + .../arch/arm/arm/src/include/armv7_pmu_pri.h | 108 + .../arch/arm/arm/src/include/asm.h | 66 + .../arch/arm/arm/src/include/los_exc_pri.h | 72 + .../arch/arm/arm/src/include/los_hw_pri.h | 117 + .../arch/arm/arm/src/include/los_hwi_pri.h | 69 + src/kernel_liteos_a/arch/arm/arm/src/jmp.S | 52 + .../arch/arm/arm/src/los_arch_mmu.c | 1139 ++ .../arch/arm/arm/src/los_asid.c | 73 + .../arch/arm/arm/src/los_dispatch.S | 234 + .../arch/arm/arm/src/los_exc.c | 1296 ++ src/kernel_liteos_a/arch/arm/arm/src/los_hw.c | 183 + .../arch/arm/arm/src/los_hw_exc.S | 424 + .../arch/arm/arm/src/los_hw_runstop.S | 132 + .../arch/arm/arm/src/los_hw_tick.c | 76 + .../arch/arm/arm/src/los_hwi.c | 346 + .../arch/arm/arm/src/pmu/armv7_pmu.c | 373 + src/kernel_liteos_a/arch/arm/arm/src/smp.c | 104 + .../arm/arm/src/startup/reset_vector_mp.S | 459 + .../arm/arm/src/startup/reset_vector_up.S | 415 + .../arch/arm/arm/src/strncpy_from_user.c | 64 + .../arch/arm/arm/src/strnlen_user.c | 63 + .../arch/arm/arm/src/user_copy.c | 107 + src/kernel_liteos_a/arch/arm/gic/BUILD.gn | 41 + src/kernel_liteos_a/arch/arm/gic/Makefile | 40 + src/kernel_liteos_a/arch/arm/gic/gic_v2.c | 197 + src/kernel_liteos_a/arch/arm/gic/gic_v3.c | 450 + .../arch/arm/include/gic_common.h | 123 + src/kernel_liteos_a/arch/arm/include/gic_v3.h | 203 + .../arch/arm/include/hal_hwi.h | 63 + .../arch/arm/include/in_cksum.h | 52 + .../arch/arm/include/los_exc.h | 254 + src/kernel_liteos_a/arch/arm/include/los_hw.h | 190 + .../arch/arm/include/los_hw_arch.h | 50 + .../arch/arm/include/los_hw_tick_pri.h | 52 + .../arch/arm/include/los_hwi.h | 439 + .../arch/arm/include/los_strncpy_from_user.h | 64 + .../arch/arm/include/los_strnlen_user.h | 63 + .../arch/arm/include/los_sys_stack_pri.h | 59 + .../arch/arm/include/los_user_get.h | 65 + .../arch/arm/include/los_user_put.h | 65 + src/kernel_liteos_a/arch/arm/include/perf.h | 61 + .../arch/arm/include/user_copy.h | 103 + src/kernel_liteos_a/arch/cpu.mk | 32 + src/kernel_liteos_a/bsd/BUILD.gn | 86 + src/kernel_liteos_a/bsd/Kconfig | 14 + src/kernel_liteos_a/bsd/Makefile | 46 + src/kernel_liteos_a/bsd/arm/autoconf.c | 1 + src/kernel_liteos_a/bsd/arm/hw_user_copy.S | 1 + src/kernel_liteos_a/bsd/arm/in_cksum.c | 1 + src/kernel_liteos_a/bsd/arm/in_cksum_arm.S | 1 + src/kernel_liteos_a/bsd/arm/include/_bus.h | 1 + src/kernel_liteos_a/bsd/arm/nexus.c | 1 + .../bsd/compat/linuxkpi/BUILD.gn | 57 + .../bsd/compat/linuxkpi/Makefile | 40 + .../bsd/compat/linuxkpi/include/asm/atomic.h | 1 + .../bsd/compat/linuxkpi/include/asm/barrier.h | 1 + .../bsd/compat/linuxkpi/include/asm/io.h | 1 + .../bsd/compat/linuxkpi/include/asm/page.h | 1 + .../compat/linuxkpi/include/linux/atomic.h | 1 + .../compat/linuxkpi/include/linux/compat.h | 1 + .../compat/linuxkpi/include/linux/compiler.h | 1 + .../linuxkpi/include/linux/completion.h | 1 + .../bsd/compat/linuxkpi/include/linux/ctype.h | 1 + .../bsd/compat/linuxkpi/include/linux/delay.h | 1 + .../linuxkpi/include/linux/dma-mapping.h | 1 + .../bsd/compat/linuxkpi/include/linux/errno.h | 1 + .../bsd/compat/linuxkpi/include/linux/fcntl.h | 1 + .../bsd/compat/linuxkpi/include/linux/fs.h | 1 + .../compat/linuxkpi/include/linux/hrtimer.h | 1 + .../bsd/compat/linuxkpi/include/linux/icmp.h | 1 + .../compat/linuxkpi/include/linux/interrupt.h | 1 + .../bsd/compat/linuxkpi/include/linux/io.h | 1 + .../bsd/compat/linuxkpi/include/linux/ioctl.h | 1 + .../compat/linuxkpi/include/linux/jiffies.h | 1 + .../compat/linuxkpi/include/linux/kernel.h | 1 + .../bsd/compat/linuxkpi/include/linux/list.h | 1 + .../compat/linuxkpi/include/linux/module.h | 1 + .../linuxkpi/include/linux/moduleparam.h | 1 + .../compat/linuxkpi/include/linux/pagemap.h | 1 + .../compat/linuxkpi/include/linux/rbtree.h | 1 + .../bsd/compat/linuxkpi/include/linux/rtc.h | 1 + .../bsd/compat/linuxkpi/include/linux/rwsem.h | 1 + .../linuxkpi/include/linux/scatterlist.h | 1 + .../bsd/compat/linuxkpi/include/linux/sched.h | 1 + .../compat/linuxkpi/include/linux/semaphore.h | 1 + .../bsd/compat/linuxkpi/include/linux/slab.h | 1 + .../compat/linuxkpi/include/linux/spinlock.h | 1 + .../bsd/compat/linuxkpi/include/linux/stat.h | 1 + .../compat/linuxkpi/include/linux/string.h | 1 + .../bsd/compat/linuxkpi/include/linux/timer.h | 1 + .../bsd/compat/linuxkpi/include/linux/tree.h | 1 + .../bsd/compat/linuxkpi/include/linux/types.h | 1 + .../bsd/compat/linuxkpi/include/linux/wait.h | 1 + .../compat/linuxkpi/include/linux/wakelock.h | 1 + .../compat/linuxkpi/include/linux/workqueue.h | 1 + .../bsd/compat/linuxkpi/include/linux/zutil.h | 1 + .../bsd/compat/linuxkpi/include/tzdst.h | 1 + .../bsd/compat/linuxkpi/include/tzdst_pri.h | 1 + .../bsd/compat/linuxkpi/src/adp.c | 1 + .../compat/linuxkpi/src/linux_completion.c | 1 + .../bsd/compat/linuxkpi/src/linux_hrtimer.c | 1 + .../bsd/compat/linuxkpi/src/linux_interrupt.c | 1 + .../bsd/compat/linuxkpi/src/linux_sched.c | 1 + .../bsd/compat/linuxkpi/src/linux_semaphore.c | 1 + .../bsd/compat/linuxkpi/src/linux_timer.c | 1 + .../bsd/compat/linuxkpi/src/linux_wakelock.c | 1 + .../bsd/compat/linuxkpi/src/linux_workqueue.c | 1 + .../bsd/compat/linuxkpi/src/prctl.c | 1 + .../bsd/compat/linuxkpi/src/tzdst.c | 1 + .../bsd/crypto/rijndael/rijndael-alg-fst.c | 1 + .../bsd/crypto/rijndael/rijndael-api-fst.c | 1 + .../bsd/crypto/rijndael/rijndael-api-fst.h | 1 + .../bsd/crypto/rijndael/rijndael.h | 1 + .../bsd/crypto/rijndael/rijndael_local.h | 1 + src/kernel_liteos_a/bsd/crypto/sha2/sha256.h | 1 + src/kernel_liteos_a/bsd/crypto/sha2/sha256c.c | 1 + src/kernel_liteos_a/bsd/dev/random/hash.c | 1 + src/kernel_liteos_a/bsd/dev/random/hash.h | 1 + .../bsd/dev/random/randomdev.h | 1 + src/kernel_liteos_a/bsd/dev/random/uint128.h | 1 + .../bsd/dev/random/unit_test.h | 1 + src/kernel_liteos_a/bsd/dev/random/yarrow.c | 1 + src/kernel_liteos_a/bsd/dev/random/yarrow.h | 1 + src/kernel_liteos_a/bsd/dev/usb/BUILD.gn | 149 + src/kernel_liteos_a/bsd/dev/usb/Kconfig | 102 + src/kernel_liteos_a/bsd/dev/usb/Makefile | 138 + .../bsd/dev/usb/controller/ehci.c | 1 + .../bsd/dev/usb/controller/ehci.h | 1 + .../bsd/dev/usb/controller/ehci_pci.c | 1 + .../bsd/dev/usb/controller/ehcireg.h | 1 + .../bsd/dev/usb/controller/usb_controller.c | 1 + .../bsd/dev/usb/controller/xhci.c | 1 + .../bsd/dev/usb/controller/xhci.h | 1 + .../bsd/dev/usb/controller/xhci_pci.c | 1 + .../bsd/dev/usb/controller/xhcireg.h | 1 + .../bsd/dev/usb/implementation/_macro_ref.h | 1 + .../bsd/dev/usb/implementation/_thread_ref.h | 1 + .../bsd/dev/usb/implementation/_types_ref.h | 1 + .../bsd/dev/usb/implementation/bsd_busspace.c | 1 + .../bsd/dev/usb/implementation/bsd_kernel.c | 1 + .../bsd/dev/usb/implementation/bsd_kernel.h | 1 + .../bsd/dev/usb/implementation/freebsd_sys.h | 1 + .../bsd/dev/usb/implementation/freebsd_usb.h | 1 + .../implementation/global_implementation.h | 1 + .../bsd/dev/usb/implementation/usb_api_pri.h | 1 + .../bsd/dev/usb/implementation/usb_btree.c | 1 + .../bsd/dev/usb/implementation/usb_btree.h | 1 + .../usb/implementation/usb_busdma_loader.c | 1 + .../bsd/dev/usb/implementation/usb_init.c | 1 + .../bsd/dev/usb/implementation/usb_init.h | 1 + .../bsd/dev/usb/implementation/usb_version.c | 1 + .../bsd/dev/usb/implementation/usbdevs.h | 1 + src/kernel_liteos_a/bsd/dev/usb/input/uhid.c | 1 + .../bsd/dev/usb/input/usb_rdesc.h | 1 + src/kernel_liteos_a/bsd/dev/usb/linux_usb.c | 1 + src/kernel_liteos_a/bsd/dev/usb/linux_usb.h | 1 + src/kernel_liteos_a/bsd/dev/usb/net/if_axe.c | 1 + .../bsd/dev/usb/net/if_axereg.h | 1 + src/kernel_liteos_a/bsd/dev/usb/net/if_axge.c | 1 + .../bsd/dev/usb/net/if_axgereg.h | 1 + src/kernel_liteos_a/bsd/dev/usb/net/if_cdce.c | 1 + .../bsd/dev/usb/net/if_cdcereg.h | 1 + .../bsd/dev/usb/net/if_urndis.c | 1 + .../bsd/dev/usb/net/if_urndisreg.h | 1 + src/kernel_liteos_a/bsd/dev/usb/net/mii.h | 1 + .../bsd/dev/usb/net/usb_eth_drv.c | 1 + .../bsd/dev/usb/net/usb_eth_drv.h | 1 + .../bsd/dev/usb/net/usb_ethernet.c | 1 + .../bsd/dev/usb/net/usb_ethernet.h | 1 + .../bsd/dev/usb/quirk/usb_quirk.c | 1 + .../bsd/dev/usb/quirk/usb_quirk.h | 1 + src/kernel_liteos_a/bsd/dev/usb/serial.h | 1 + src/kernel_liteos_a/bsd/dev/usb/serial/u3g.c | 1 + .../bsd/dev/usb/serial/usb_serial.c | 1 + .../bsd/dev/usb/serial/usb_serial.h | 1 + .../bsd/dev/usb/storage/scsi.h | 1 + .../bsd/dev/usb/storage/scsi_all.h | 1 + .../bsd/dev/usb/storage/umass.c | 1 + src/kernel_liteos_a/bsd/dev/usb/usb.h | 1 + src/kernel_liteos_a/bsd/dev/usb/usb_bus.h | 1 + src/kernel_liteos_a/bsd/dev/usb/usb_busdma.h | 1 + src/kernel_liteos_a/bsd/dev/usb/usb_cdc.h | 1 + .../bsd/dev/usb/usb_controller.h | 1 + src/kernel_liteos_a/bsd/dev/usb/usb_core.c | 1 + src/kernel_liteos_a/bsd/dev/usb/usb_core.h | 1 + src/kernel_liteos_a/bsd/dev/usb/usb_debug.c | 1 + src/kernel_liteos_a/bsd/dev/usb/usb_debug.h | 1 + src/kernel_liteos_a/bsd/dev/usb/usb_dev.c | 1 + src/kernel_liteos_a/bsd/dev/usb/usb_dev.h | 1 + src/kernel_liteos_a/bsd/dev/usb/usb_device.c | 1 + src/kernel_liteos_a/bsd/dev/usb/usb_device.h | 1 + src/kernel_liteos_a/bsd/dev/usb/usb_dynamic.c | 1 + src/kernel_liteos_a/bsd/dev/usb/usb_dynamic.h | 1 + src/kernel_liteos_a/bsd/dev/usb/usb_endian.h | 1 + src/kernel_liteos_a/bsd/dev/usb/usb_error.c | 1 + .../bsd/dev/usb/usb_freebsd_loader.h | 1 + src/kernel_liteos_a/bsd/dev/usb/usb_generic.c | 1 + src/kernel_liteos_a/bsd/dev/usb/usb_generic.h | 1 + .../bsd/dev/usb/usb_handle_request.c | 1 + src/kernel_liteos_a/bsd/dev/usb/usb_hid.c | 1 + src/kernel_liteos_a/bsd/dev/usb/usb_hub.c | 1 + src/kernel_liteos_a/bsd/dev/usb/usb_hub.h | 1 + src/kernel_liteos_a/bsd/dev/usb/usb_if.c | 1 + src/kernel_liteos_a/bsd/dev/usb/usb_if.h | 1 + src/kernel_liteos_a/bsd/dev/usb/usb_ioctl.h | 1 + src/kernel_liteos_a/bsd/dev/usb/usb_lookup.c | 1 + src/kernel_liteos_a/bsd/dev/usb/usb_mbuf.c | 1 + src/kernel_liteos_a/bsd/dev/usb/usb_mbuf.h | 1 + src/kernel_liteos_a/bsd/dev/usb/usb_parse.c | 1 + src/kernel_liteos_a/bsd/dev/usb/usb_process.c | 1 + src/kernel_liteos_a/bsd/dev/usb/usb_process.h | 1 + src/kernel_liteos_a/bsd/dev/usb/usb_request.c | 1 + src/kernel_liteos_a/bsd/dev/usb/usb_request.h | 1 + .../bsd/dev/usb/usb_transfer.c | 1 + .../bsd/dev/usb/usb_transfer.h | 1 + src/kernel_liteos_a/bsd/dev/usb/usb_util.c | 1 + src/kernel_liteos_a/bsd/dev/usb/usb_util.h | 1 + src/kernel_liteos_a/bsd/dev/usb/usbdi.h | 1 + src/kernel_liteos_a/bsd/dev/usb/usbdi_util.h | 1 + src/kernel_liteos_a/bsd/dev/usb/usbhid.h | 1 + src/kernel_liteos_a/bsd/kern/bus_if.c | 1 + src/kernel_liteos_a/bsd/kern/bus_if.h | 1 + src/kernel_liteos_a/bsd/kern/device_if.c | 1 + src/kernel_liteos_a/bsd/kern/device_if.h | 1 + src/kernel_liteos_a/bsd/kern/kern_condvar.c | 1 + src/kernel_liteos_a/bsd/kern/kern_timeout.c | 1 + src/kernel_liteos_a/bsd/kern/subr_bus.c | 1 + src/kernel_liteos_a/bsd/kern/subr_kobj.c | 1 + .../bsd/libkern/explicit_bzero.c | 1 + src/kernel_liteos_a/bsd/net/ppp_defs.h | 1 + src/kernel_liteos_a/bsd/sys/_callout.h | 1 + src/kernel_liteos_a/bsd/sys/bus.h | 1 + src/kernel_liteos_a/bsd/sys/callout.h | 1 + src/kernel_liteos_a/bsd/sys/cdefs.h | 1 + src/kernel_liteos_a/bsd/sys/condvar.h | 1 + src/kernel_liteos_a/bsd/sys/kernel.h | 1 + src/kernel_liteos_a/bsd/sys/kobj.h | 1 + src/kernel_liteos_a/bsd/sys/linker_set.h | 1 + src/kernel_liteos_a/bsd/sys/malloc.h | 1 + src/kernel_liteos_a/bsd/sys/module.h | 1 + src/kernel_liteos_a/bsd/sys/mutex.h | 1 + src/kernel_liteos_a/bsd/sys/priv.h | 1 + src/kernel_liteos_a/bsd/sys/queue.h | 1 + src/kernel_liteos_a/bsd/sys/sema.h | 1 + src/kernel_liteos_a/bsd/sys/sx.h | 1 + src/kernel_liteos_a/bsd/sys/systm.h | 1 + src/kernel_liteos_a/build.sh | 69 + src/kernel_liteos_a/bundle.json | 65 + src/kernel_liteos_a/compat/BUILD.gn | 38 + src/kernel_liteos_a/compat/posix/BUILD.gn | 59 + src/kernel_liteos_a/compat/posix/Kconfig | 6 + src/kernel_liteos_a/compat/posix/Makefile | 40 + .../compat/posix/include/mqueue.h | 439 + .../compat/posix/include/time_posix.h | 96 + src/kernel_liteos_a/compat/posix/src/errno.c | 51 + src/kernel_liteos_a/compat/posix/src/malloc.c | 145 + .../compat/posix/src/map_error.c | 112 + .../compat/posix/src/map_error.h | 49 + src/kernel_liteos_a/compat/posix/src/misc.c | 237 + src/kernel_liteos_a/compat/posix/src/mqueue.c | 979 ++ .../compat/posix/src/posix_memalign.c | 49 + .../compat/posix/src/pprivate.h | 87 + .../compat/posix/src/pthread.c | 806 ++ .../compat/posix/src/pthread_attr.c | 277 + .../compat/posix/src/pthread_cond.c | 348 + .../compat/posix/src/pthread_mutex.c | 136 + src/kernel_liteos_a/compat/posix/src/sched.c | 145 + .../compat/posix/src/semaphore.c | 194 + src/kernel_liteos_a/compat/posix/src/socket.c | 188 + src/kernel_liteos_a/compat/posix/src/stdio.c | 121 + src/kernel_liteos_a/compat/posix/src/stdlib.c | 71 + src/kernel_liteos_a/compat/posix/src/time.c | 1215 ++ src/kernel_liteos_a/config.mk | 68 + src/kernel_liteos_a/drivers/BUILD.gn | 38 + src/kernel_liteos_a/drivers/Kconfig | 20 + src/kernel_liteos_a/drivers/block/BUILD.gn | 34 + .../drivers/block/disk/BUILD.gn | 45 + .../drivers/block/disk/Makefile | 36 + .../drivers/block/disk/include/disk.h | 742 ++ .../drivers/block/disk/include/disk_pri.h | 69 + .../drivers/block/disk/include/driver.h | 104 + .../drivers/block/disk/src/disk.c | 1799 +++ .../drivers/block/disk/src/disk_shellcmd.c | 76 + src/kernel_liteos_a/drivers/char/BUILD.gn | 42 + src/kernel_liteos_a/drivers/char/bch/BUILD.gn | 43 + src/kernel_liteos_a/drivers/char/bch/Makefile | 41 + .../drivers/char/bch/include/blockproxy.h | 53 + src/kernel_liteos_a/drivers/char/mem/BUILD.gn | 42 + src/kernel_liteos_a/drivers/char/mem/Kconfig | 6 + src/kernel_liteos_a/drivers/char/mem/Makefile | 36 + .../drivers/char/mem/include/los_dev_mem.h | 51 + .../drivers/char/mem/src/mem.c | 101 + .../drivers/char/perf/BUILD.gn | 42 + src/kernel_liteos_a/drivers/char/perf/Kconfig | 6 + .../drivers/char/perf/Makefile | 36 + .../drivers/char/perf/include/los_dev_perf.h | 49 + .../drivers/char/perf/src/perf.c | 153 + .../drivers/char/quickstart/BUILD.gn | 42 + .../drivers/char/quickstart/Kconfig | 6 + .../drivers/char/quickstart/Makefile | 36 + .../quickstart/include/los_dev_quickstart.h | 87 + .../drivers/char/quickstart/src/quickstart.c | 142 + .../drivers/char/random/BUILD.gn | 46 + .../drivers/char/random/Kconfig | 12 + .../drivers/char/random/Makefile | 40 + .../drivers/char/random/include/los_random.h | 66 + .../drivers/char/random/src/random.c | 119 + .../drivers/char/random/src/random_hw.c | 123 + .../drivers/char/trace/BUILD.gn | 42 + .../drivers/char/trace/Kconfig | 6 + .../drivers/char/trace/Makefile | 40 + .../char/trace/include/los_dev_trace.h | 49 + .../drivers/char/trace/src/trace.c | 160 + .../drivers/char/video/BUILD.gn | 43 + .../drivers/char/video/Kconfig | 6 + .../drivers/char/video/Makefile | 40 + src/kernel_liteos_a/drivers/mtd/BUILD.gn | 34 + .../drivers/mtd/multi_partition/BUILD.gn | 47 + .../drivers/mtd/multi_partition/Makefile | 41 + .../mtd/multi_partition/include/mtd_dev.h | 59 + .../mtd/multi_partition/include/mtd_list.h | 62 + .../multi_partition/include/mtd_partition.h | 160 + .../mtd/multi_partition/src/mtd_partition.c | 538 + .../mtd/multi_partition/src/mtd_shellcmd.c | 78 + .../OpenHarmony-LiteOS-A内核架构图.png | Bin 0 -> 158767 bytes ...the-openharmony-liteos-cortex-a-kernel.png | Bin 0 -> 142651 bytes src/kernel_liteos_a/fs/BUILD.gn | 60 + src/kernel_liteos_a/fs/Kconfig | 10 + src/kernel_liteos_a/fs/fat/BUILD.gn | 51 + src/kernel_liteos_a/fs/fat/Kconfig | 43 + src/kernel_liteos_a/fs/fat/Makefile | 42 + .../fs/fat/os_adapt/fat_shellcmd.c | 80 + src/kernel_liteos_a/fs/fat/os_adapt/fatfs.c | 2461 ++++ src/kernel_liteos_a/fs/fat/os_adapt/fatfs.h | 157 + src/kernel_liteos_a/fs/fat/os_adapt/format.c | 115 + src/kernel_liteos_a/fs/fat/virpart/BUILD.gn | 47 + src/kernel_liteos_a/fs/fat/virpart/Makefile | 40 + .../fs/fat/virpart/include/virpart.h | 55 + .../fs/fat/virpart/include/virpartff.h | 54 + .../fs/fat/virpart/src/virpart.c | 505 + .../fs/fat/virpart/src/virpartff.c | 839 ++ src/kernel_liteos_a/fs/include/fs/dirent_fs.h | 1 + src/kernel_liteos_a/fs/include/fs/driver.h | 1 + src/kernel_liteos_a/fs/include/fs/fd_table.h | 92 + src/kernel_liteos_a/fs/include/fs/file.h | 1 + src/kernel_liteos_a/fs/include/fs/fs.h | 1 + .../fs/include/fs/fs_operation.h | 382 + src/kernel_liteos_a/fs/include/fs/mount.h | 80 + src/kernel_liteos_a/fs/include/fs/vnode.h | 34 + src/kernel_liteos_a/fs/include/vfs_config.h | 146 + src/kernel_liteos_a/fs/jffs2/BUILD.gn | 116 + src/kernel_liteos_a/fs/jffs2/Kconfig | 13 + src/kernel_liteos_a/fs/jffs2/Makefile | 81 + .../fs/jffs2/include/jffs2_hash.h | 59 + .../fs/jffs2/include/vfs_jffs2.h | 84 + src/kernel_liteos_a/fs/jffs2/jffs2.patch | 10167 ++++++++++++++++ src/kernel_liteos_a/fs/jffs2/src/jffs2_hash.c | 123 + src/kernel_liteos_a/fs/jffs2/src/vfs_jffs2.c | 985 ++ src/kernel_liteos_a/fs/nfs/BUILD.gn | 37 + src/kernel_liteos_a/fs/nfs/Kconfig | 8 + src/kernel_liteos_a/fs/nfs/Makefile | 38 + src/kernel_liteos_a/fs/patchfs/BUILD.gn | 43 + src/kernel_liteos_a/fs/patchfs/Kconfig | 6 + src/kernel_liteos_a/fs/patchfs/Makefile | 7 + .../fs/patchfs/los_partition_utils.c | 235 + .../fs/patchfs/los_partition_utils.h | 72 + src/kernel_liteos_a/fs/patchfs/los_patchfs.c | 106 + src/kernel_liteos_a/fs/patchfs/los_patchfs.h | 66 + src/kernel_liteos_a/fs/proc/BUILD.gn | 58 + src/kernel_liteos_a/fs/proc/Kconfig | 11 + src/kernel_liteos_a/fs/proc/Makefile | 36 + .../fs/proc/include/internal.h | 100 + .../fs/proc/include/proc_file.h | 187 + src/kernel_liteos_a/fs/proc/include/proc_fs.h | 326 + .../fs/proc/os_adapt/fd_proc.c | 144 + .../fs/proc/os_adapt/file_sys.c | 69 + .../fs/proc/os_adapt/fs_cache_proc.c | 223 + .../fs/proc/os_adapt/mem_info.c | 69 + .../fs/proc/os_adapt/mounts_proc.c | 100 + .../fs/proc/os_adapt/plimits_proc.c | 905 ++ .../fs/proc/os_adapt/power_proc.c | 205 + .../fs/proc/os_adapt/proc_init.c | 85 + .../fs/proc/os_adapt/proc_vfs.c | 474 + .../fs/proc/os_adapt/process_proc.c | 728 ++ .../fs/proc/os_adapt/sys_user.c | 228 + .../fs/proc/os_adapt/uptime_proc.c | 87 + .../fs/proc/os_adapt/vmm_proc.c | 117 + src/kernel_liteos_a/fs/proc/src/proc_file.c | 725 ++ .../fs/proc/src/proc_shellcmd.c | 98 + src/kernel_liteos_a/fs/ramfs/BUILD.gn | 37 + src/kernel_liteos_a/fs/ramfs/Kconfig | 6 + src/kernel_liteos_a/fs/ramfs/Makefile | 36 + src/kernel_liteos_a/fs/romfs/BUILD.gn | 37 + src/kernel_liteos_a/fs/romfs/Kconfig | 6 + src/kernel_liteos_a/fs/romfs/Makefile | 35 + src/kernel_liteos_a/fs/rootfs/BUILD.gn | 44 + src/kernel_liteos_a/fs/rootfs/Kconfig | 49 + src/kernel_liteos_a/fs/rootfs/Makefile | 39 + src/kernel_liteos_a/fs/rootfs/los_bootargs.c | 233 + src/kernel_liteos_a/fs/rootfs/los_bootargs.h | 61 + src/kernel_liteos_a/fs/rootfs/los_rootfs.c | 363 + src/kernel_liteos_a/fs/rootfs/los_rootfs.h | 90 + src/kernel_liteos_a/fs/vfs/BUILD.gn | 75 + src/kernel_liteos_a/fs/vfs/Kconfig | 43 + src/kernel_liteos_a/fs/vfs/Makefile | 105 + src/kernel_liteos_a/fs/vfs/bcache/BUILD.gn | 42 + src/kernel_liteos_a/fs/vfs/bcache/Makefile | 37 + .../fs/vfs/bcache/src/bcache.c | 1228 ++ src/kernel_liteos_a/fs/vfs/epoll/fs_epoll.c | 352 + .../fs/vfs/include/bcache/bcache.h | 275 + src/kernel_liteos_a/fs/vfs/include/epoll.h | 84 + .../fs/vfs/include/fs_poll_pri.h | 34 + .../fs/vfs/include/path_cache.h | 63 + src/kernel_liteos_a/fs/vfs/include/vnode.h | 198 + src/kernel_liteos_a/fs/vfs/mount.c | 101 + .../fs/vfs/operation/fullpath.c | 329 + .../fs/vfs/operation/vfs_chattr.c | 103 + .../fs/vfs/operation/vfs_check.c | 93 + .../fs/vfs/operation/vfs_cloexec.c | 100 + .../fs/vfs/operation/vfs_fallocate.c | 139 + .../fs/vfs/operation/vfs_fallocate64.c | 144 + .../fs/vfs/operation/vfs_fcntl.c | 104 + .../fs/vfs/operation/vfs_force_umount.c | 487 + .../fs/vfs/operation/vfs_init.c | 86 + .../fs/vfs/operation/vfs_other.c | 802 ++ .../fs/vfs/operation/vfs_preadv.c | 50 + .../fs/vfs/operation/vfs_procfd.c | 476 + .../fs/vfs/operation/vfs_pwritev.c | 50 + .../fs/vfs/operation/vfs_readv.c | 147 + .../fs/vfs/operation/vfs_utime.c | 127 + .../fs/vfs/operation/vfs_writev.c | 138 + src/kernel_liteos_a/fs/vfs/path_cache.c | 211 + .../fs/vfs/vfs_cmd/vfs_shellcmd.c | 1390 +++ src/kernel_liteos_a/fs/vfs/vnode.c | 786 ++ src/kernel_liteos_a/fs/vfs/vnode_hash.c | 138 + src/kernel_liteos_a/fs/zpfs/BUILD.gn | 41 + src/kernel_liteos_a/fs/zpfs/Kconfig | 6 + src/kernel_liteos_a/fs/zpfs/Makefile | 40 + src/kernel_liteos_a/kernel/BUILD.gn | 49 + src/kernel_liteos_a/kernel/Kconfig | 80 + src/kernel_liteos_a/kernel/base/BUILD.gn | 104 + src/kernel_liteos_a/kernel/base/Makefile | 46 + .../kernel/base/core/los_bitmap.c | 173 + .../kernel/base/core/los_info.c | 262 + .../kernel/base/core/los_process.c | 2542 ++++ .../kernel/base/core/los_smp.c | 80 + .../kernel/base/core/los_swtmr.c | 924 ++ .../kernel/base/core/los_sys.c | 72 + .../kernel/base/core/los_task.c | 1651 +++ .../kernel/base/core/los_tick.c | 66 + .../kernel/base/include/los_base_pri.h | 53 + .../kernel/base/include/los_binarytree_pri.h | 110 + .../kernel/base/include/los_container_pri.h | 148 + .../kernel/base/include/los_credentials_pri.h | 73 + .../kernel/base/include/los_err_pri.h | 127 + .../kernel/base/include/los_event_pri.h | 64 + .../kernel/base/include/los_futex_pri.h | 63 + .../kernel/base/include/los_info_pri.h | 108 + .../base/include/los_ipc_container_pri.h | 98 + .../kernel/base/include/los_ipcdebug_pri.h | 67 + .../kernel/base/include/los_membox_pri.h | 49 + .../kernel/base/include/los_memory_pri.h | 65 + .../kernel/base/include/los_memstat_pri.h | 88 + .../base/include/los_mnt_container_pri.h | 66 + .../kernel/base/include/los_mux_pri.h | 57 + .../base/include/los_net_container_pri.h | 62 + .../kernel/base/include/los_oom.h | 70 + .../kernel/base/include/los_percpu_pri.h | 90 + .../base/include/los_pid_container_pri.h | 111 + .../kernel/base/include/los_printf_pri.h | 58 + .../kernel/base/include/los_process_pri.h | 563 + .../kernel/base/include/los_queue_debug_pri.h | 86 + .../kernel/base/include/los_queue_pri.h | 212 + .../kernel/base/include/los_rwlock_pri.h | 66 + .../kernel/base/include/los_sched_pri.h | 763 ++ .../kernel/base/include/los_sem_debug_pri.h | 87 + .../kernel/base/include/los_sem_pri.h | 120 + .../kernel/base/include/los_signal.h | 187 + .../kernel/base/include/los_sortlink_pri.h | 118 + .../kernel/base/include/los_stackinfo_pri.h | 84 + .../kernel/base/include/los_statistics_pri.h | 73 + .../kernel/base/include/los_swtmr_pri.h | 149 + .../kernel/base/include/los_sys_pri.h | 144 + .../kernel/base/include/los_task_pri.h | 346 + .../kernel/base/include/los_tick_pri.h | 89 + .../base/include/los_time_container_pri.h | 70 + .../kernel/base/include/los_typedef_pri.h | 37 + .../base/include/los_user_container_pri.h | 82 + .../base/include/los_uts_container_pri.h | 65 + .../kernel/base/include/los_vm_boot.h | 76 + .../kernel/base/include/los_vm_common.h | 140 + .../kernel/base/include/los_vm_dump.h | 82 + .../kernel/base/include/los_vm_fault.h | 67 + .../kernel/base/include/los_vm_filemap.h | 224 + .../kernel/base/include/los_vm_iomap.h | 60 + .../kernel/base/include/los_vm_lock.h | 64 + .../kernel/base/include/los_vm_map.h | 323 + .../kernel/base/include/los_vm_page.h | 72 + .../kernel/base/include/los_vm_phys.h | 122 + .../kernel/base/include/los_vm_shm_pri.h | 73 + .../kernel/base/include/los_vm_syscall.h | 78 + .../kernel/base/include/los_vm_zone.h | 112 + .../kernel/base/ipc/los_event.c | 343 + .../kernel/base/ipc/los_futex.c | 1014 ++ .../kernel/base/ipc/los_ipcdebug.c | 80 + src/kernel_liteos_a/kernel/base/ipc/los_mux.c | 527 + .../kernel/base/ipc/los_queue.c | 519 + .../kernel/base/ipc/los_queue_debug.c | 198 + .../kernel/base/ipc/los_rwlock.c | 462 + src/kernel_liteos_a/kernel/base/ipc/los_sem.c | 287 + .../kernel/base/ipc/los_sem_debug.c | 301 + .../kernel/base/ipc/los_signal.c | 794 ++ .../kernel/base/mem/common/los_memstat.c | 116 + .../kernel/base/mem/membox/los_membox.c | 223 + .../kernel/base/mem/tlsf/los_memory.c | 2083 ++++ .../kernel/base/misc/kill_shellcmd.c | 100 + .../kernel/base/misc/los_misc.c | 59 + .../kernel/base/misc/los_stackinfo.c | 128 + .../kernel/base/misc/mempt_shellcmd.c | 246 + .../kernel/base/misc/panic_shellcmd.c | 127 + .../kernel/base/misc/swtmr_shellcmd.c | 179 + .../kernel/base/misc/sysinfo_shellcmd.c | 176 + .../kernel/base/misc/task_shellcmd.c | 452 + .../kernel/base/misc/vm_shellcmd.c | 262 + .../kernel/base/mp/los_lockdep.c | 366 + src/kernel_liteos_a/kernel/base/mp/los_mp.c | 183 + .../kernel/base/mp/los_percpu.c | 59 + .../kernel/base/mp/los_spinlock.c | 120 + src/kernel_liteos_a/kernel/base/om/los_err.c | 51 + .../kernel/base/sched/los_deadline.c | 403 + .../kernel/base/sched/los_idle.c | 188 + .../kernel/base/sched/los_priority.c | 557 + .../kernel/base/sched/los_sched.c | 563 + .../kernel/base/sched/los_sortlink.c | 130 + .../kernel/base/sched/los_statistics.c | 345 + .../kernel/base/vm/los_vm_boot.c | 83 + .../kernel/base/vm/los_vm_dump.c | 564 + .../kernel/base/vm/los_vm_fault.c | 467 + .../kernel/base/vm/los_vm_filemap.c | 612 + .../kernel/base/vm/los_vm_iomap.c | 106 + .../kernel/base/vm/los_vm_map.c | 1212 ++ .../kernel/base/vm/los_vm_page.c | 138 + .../kernel/base/vm/los_vm_phys.c | 635 + .../kernel/base/vm/los_vm_scan.c | 343 + .../kernel/base/vm/los_vm_syscall.c | 517 + src/kernel_liteos_a/kernel/base/vm/oom.c | 252 + src/kernel_liteos_a/kernel/base/vm/shm.c | 914 ++ src/kernel_liteos_a/kernel/common/BUILD.gn | 55 + src/kernel_liteos_a/kernel/common/Makefile | 46 + src/kernel_liteos_a/kernel/common/console.c | 1640 +++ src/kernel_liteos_a/kernel/common/console.h | 147 + .../kernel/common/los_config.c | 320 + .../kernel/common/los_config.h | 486 + .../kernel/common/los_excinfo.c | 199 + .../kernel/common/los_excinfo_pri.h | 65 + src/kernel_liteos_a/kernel/common/los_init.c | 126 + .../kernel/common/los_init_info.h | 169 + .../kernel/common/los_init_pri.h | 40 + .../kernel/common/los_magickey.c | 147 + .../kernel/common/los_magickey.h | 57 + .../kernel/common/los_printf.c | 299 + src/kernel_liteos_a/kernel/common/main.c | 48 + .../kernel/common/virtual_serial.c | 256 + .../kernel/common/virtual_serial.h | 73 + src/kernel_liteos_a/kernel/extended/BUILD.gn | 70 + src/kernel_liteos_a/kernel/extended/Kconfig | 180 + .../kernel/extended/blackbox/BUILD.gn | 47 + .../kernel/extended/blackbox/Kconfig | 35 + .../kernel/extended/blackbox/Makefile | 11 + .../kernel/extended/blackbox/los_blackbox.h | 88 + .../extended/blackbox/los_blackbox_common.c | 220 + .../extended/blackbox/los_blackbox_common.h | 62 + .../extended/blackbox/los_blackbox_core.c | 478 + .../extended/blackbox/los_blackbox_detector.c | 63 + .../extended/blackbox/los_blackbox_detector.h | 51 + .../blackbox/los_blackbox_system_adapter.c | 265 + .../blackbox/los_blackbox_system_adapter.h | 51 + .../kernel/extended/container/BUILD.gn | 65 + .../kernel/extended/container/Makefile | 63 + .../kernel/extended/container/los_container.c | 755 ++ .../extended/container/los_credentials.c | 209 + .../extended/container/los_ipc_container.c | 222 + .../extended/container/los_mnt_container.c | 253 + .../extended/container/los_net_container.c | 344 + .../extended/container/los_pid_container.c | 623 + .../extended/container/los_time_container.c | 258 + .../extended/container/los_user_container.c | 439 + .../extended/container/los_uts_container.c | 240 + .../kernel/extended/cppsupport/BUILD.gn | 36 + .../kernel/extended/cppsupport/Makefile | 40 + .../extended/cppsupport/los_cppsupport.c | 50 + .../kernel/extended/cpup/BUILD.gn | 45 + .../kernel/extended/cpup/Makefile | 36 + .../kernel/extended/cpup/cpup_shellcmd.c | 139 + .../kernel/extended/cpup/los_cpup.c | 611 + .../kernel/extended/cpup/los_cpup_pri.h | 90 + .../kernel/extended/dynload/BUILD.gn | 45 + .../kernel/extended/dynload/Makefile | 38 + .../dynload/include/los_elf_auxvec_pri.h | 70 + .../extended/dynload/include/los_exec_elf.h | 51 + .../extended/dynload/include/los_ld_elf_pri.h | 422 + .../extended/dynload/include/los_load_elf.h | 134 + .../extended/dynload/src/los_exec_elf.c | 174 + .../extended/dynload/src/los_load_elf.c | 1085 ++ .../kernel/extended/hidumper/BUILD.gn | 41 + .../kernel/extended/hidumper/Kconfig | 6 + .../kernel/extended/hidumper/Makefile | 7 + .../kernel/extended/hidumper/los_hidumper.c | 381 + .../kernel/extended/hidumper/los_hidumper.h | 88 + .../kernel/extended/hilog/BUILD.gn | 49 + .../kernel/extended/hilog/Kconfig | 15 + .../kernel/extended/hilog/Makefile | 38 + .../kernel/extended/hilog/los_hilog.c | 354 + .../kernel/extended/hilog/los_hilog.h | 53 + .../kernel/extended/hook/BUILD.gn | 42 + .../kernel/extended/hook/Makefile | 36 + .../extended/hook/include/los_hook_types.h | 153 + .../hook/include/los_hook_types_parse.h | 76 + .../kernel/extended/hook/los_hook.c | 66 + .../kernel/extended/liteipc/BUILD.gn | 41 + .../kernel/extended/liteipc/Makefile | 35 + .../kernel/extended/liteipc/hm_liteipc.c | 1381 +++ .../kernel/extended/liteipc/hm_liteipc.h | 199 + .../kernel/extended/lms/BUILD.gn | 43 + .../kernel/extended/lms/Kconfig | 41 + .../kernel/extended/lms/Makefile | 10 + .../kernel/extended/lms/lms_libc.c | 122 + .../kernel/extended/lms/los_lms.c | 770 ++ .../kernel/extended/lms/los_lms_pri.h | 136 + .../kernel/extended/lms/usr/BUILD.gn | 59 + .../kernel/extended/lms/usr/los_lms.c | 486 + .../kernel/extended/lms/usr/los_lms.h | 93 + .../kernel/extended/lms/usr/los_lms_pri.h | 172 + .../kernel/extended/lms/usr/los_lmslibc.c | 210 + .../kernel/extended/perf/BUILD.gn | 56 + .../kernel/extended/perf/Kconfig | 38 + .../kernel/extended/perf/Makefile | 22 + .../kernel/extended/perf/los_perf.c | 544 + .../kernel/extended/perf/los_perf_pri.h | 158 + .../kernel/extended/perf/perf_output.c | 126 + .../kernel/extended/perf/perf_output_pri.h | 63 + .../kernel/extended/perf/perf_pmu.c | 70 + .../kernel/extended/perf/perf_pmu_pri.h | 130 + .../kernel/extended/perf/pmu/perf_hw_pmu.c | 187 + .../kernel/extended/perf/pmu/perf_sw_pmu.c | 169 + .../kernel/extended/perf/pmu/perf_timed_pmu.c | 177 + .../kernel/extended/pipes/BUILD.gn | 43 + .../kernel/extended/pipes/Makefile | 37 + .../kernel/extended/plimit/BUILD.gn | 46 + .../kernel/extended/plimit/Makefile | 35 + .../kernel/extended/plimit/los_devicelimit.c | 605 + .../kernel/extended/plimit/los_devicelimit.h | 96 + .../kernel/extended/plimit/los_ipclimit.c | 249 + .../kernel/extended/plimit/los_ipclimit.h | 92 + .../kernel/extended/plimit/los_memlimit.c | 223 + .../kernel/extended/plimit/los_memlimit.h | 69 + .../kernel/extended/plimit/los_plimits.c | 434 + .../kernel/extended/plimit/los_plimits.h | 114 + .../kernel/extended/plimit/los_processlimit.c | 182 + .../kernel/extended/plimit/los_processlimit.h | 67 + .../kernel/extended/plimit/los_schedlimit.c | 151 + .../kernel/extended/plimit/los_schedlimit.h | 68 + .../kernel/extended/power/BUILD.gn | 40 + .../kernel/extended/power/Makefile | 36 + .../kernel/extended/power/los_pm.c | 691 ++ .../kernel/extended/power/los_pm_pri.h | 50 + .../kernel/extended/trace/BUILD.gn | 65 + .../kernel/extended/trace/Kconfig | 78 + .../kernel/extended/trace/Makefile | 62 + .../kernel/extended/trace/cnv/trace_cnv.c | 344 + .../kernel/extended/trace/cnv/trace_cnv.h | 51 + .../kernel/extended/trace/los_trace.c | 427 + .../kernel/extended/trace/los_trace_pri.h | 158 + .../pipeline/serial/trace_pipeline_serial.c | 89 + .../pipeline/serial/trace_pipeline_serial.h | 51 + .../extended/trace/pipeline/trace_pipeline.c | 154 + .../extended/trace/pipeline/trace_pipeline.h | 106 + .../extended/trace/pipeline/trace_tlv.c | 110 + .../extended/trace/pipeline/trace_tlv.h | 97 + .../kernel/extended/trace/trace_offline.c | 263 + .../kernel/extended/trace/trace_online.c | 98 + .../kernel/extended/vdso/BUILD.gn | 55 + .../kernel/extended/vdso/include/los_vdso.h | 56 + .../extended/vdso/include/los_vdso_datapage.h | 63 + .../extended/vdso/include/los_vdso_pri.h | 57 + .../kernel/extended/vdso/src/Makefile | 38 + .../kernel/extended/vdso/src/los_vdso.c | 130 + .../kernel/extended/vdso/src/los_vdso_text.S | 34 + .../kernel/extended/vdso/usr/BUILD.gn | 51 + .../kernel/extended/vdso/usr/Makefile | 50 + .../kernel/extended/vdso/usr/los_vdso.ld | 68 + .../kernel/extended/vdso/usr/los_vdso_sys.c | 113 + src/kernel_liteos_a/kernel/include/los_base.h | 247 + .../kernel/include/los_bitmap.h | 222 + .../kernel/include/los_builddef.h | 103 + .../kernel/include/los_cppsupport.h | 86 + src/kernel_liteos_a/kernel/include/los_cpup.h | 314 + src/kernel_liteos_a/kernel/include/los_err.h | 159 + .../kernel/include/los_errno.h | 112 + .../kernel/include/los_event.h | 342 + src/kernel_liteos_a/kernel/include/los_hash.h | 94 + src/kernel_liteos_a/kernel/include/los_hook.h | 141 + src/kernel_liteos_a/kernel/include/los_init.h | 78 + .../kernel/include/los_ld_elflib.h | 244 + src/kernel_liteos_a/kernel/include/los_list.h | 609 + src/kernel_liteos_a/kernel/include/los_lms.h | 58 + .../kernel/include/los_lockdep.h | 147 + .../kernel/include/los_membox.h | 250 + .../kernel/include/los_memory.h | 433 + src/kernel_liteos_a/kernel/include/los_mp.h | 100 + src/kernel_liteos_a/kernel/include/los_mux.h | 242 + src/kernel_liteos_a/kernel/include/los_perf.h | 439 + src/kernel_liteos_a/kernel/include/los_pm.h | 327 + .../kernel/include/los_printf.h | 122 + .../kernel/include/los_process.h | 90 + .../kernel/include/los_queue.h | 735 ++ .../kernel/include/los_rwlock.h | 286 + src/kernel_liteos_a/kernel/include/los_sem.h | 305 + src/kernel_liteos_a/kernel/include/los_smp.h | 53 + .../kernel/include/los_spinlock.h | 270 + .../kernel/include/los_swtmr.h | 423 + src/kernel_liteos_a/kernel/include/los_sys.h | 202 + .../kernel/include/los_tables.h | 93 + src/kernel_liteos_a/kernel/include/los_task.h | 1138 ++ src/kernel_liteos_a/kernel/include/los_tick.h | 180 + .../kernel/include/los_toolchain.h | 179 + .../kernel/include/los_trace.h | 629 + .../kernel/include/los_typedef.h | 240 + src/kernel_liteos_a/kernel/user/BUILD.gn | 64 + src/kernel_liteos_a/kernel/user/Makefile | 55 + .../kernel/user/include/los_user_init.h | 70 + .../kernel/user/src/los_user_init.c | 71 + src/kernel_liteos_a/lib/BUILD.gn | 50 + src/kernel_liteos_a/lib/Kconfig | 29 + src/kernel_liteos_a/lib/libc/BUILD.gn | 44 + src/kernel_liteos_a/lib/libc/musl/BUILD.gn | 119 + src/kernel_liteos_a/lib/libc/musl/Makefile | 69 + .../lib/libc/musl/src/arch/arm/memcmp.S | 207 + .../lib/libc/musl/src/arch/arm/memset.S | 140 + .../lib/libc/musl/src/memcmp.c | 72 + .../lib/libc/musl/src/memset.c | 118 + src/kernel_liteos_a/lib/libc/newlib/BUILD.gn | 58 + src/kernel_liteos_a/lib/libmbedtls/BUILD.gn | 122 + src/kernel_liteos_a/lib/libmbedtls/Makefile | 8 + src/kernel_liteos_a/lib/libscrew/BUILD.gn | 49 + src/kernel_liteos_a/lib/libscrew/Makefile | 9 + .../lib/libscrew/include/los_cir_buf.h | 71 + .../lib/libscrew/include/los_crc32.h | 55 + .../lib/libscrew/include/los_rbtree.h | 142 + .../lib/libscrew/include/los_seq_buf.h | 66 + .../lib/libscrew/src/los_cir_buf.c | 226 + .../lib/libscrew/src/los_crc32.c | 72 + .../lib/libscrew/src/los_rbtree.c | 731 ++ .../lib/libscrew/src/los_seq_buf.c | 158 + src/kernel_liteos_a/lib/libsec/BUILD.gn | 60 + src/kernel_liteos_a/lib/libsec/Makefile | 6 + src/kernel_liteos_a/lib/zlib/BUILD.gn | 58 + src/kernel_liteos_a/lib/zlib/Makefile | 7 + src/kernel_liteos_a/liteos.gni | 156 + src/kernel_liteos_a/net/BUILD.gn | 48 + src/kernel_liteos_a/net/Kconfig | 36 + src/kernel_liteos_a/net/lwip-2.1/BUILD.gn | 59 + src/kernel_liteos_a/net/lwip-2.1/Makefile | 51 + .../enhancement/include/lwip/api_shell.h | 61 + .../lwip-2.1/enhancement/include/lwip/dhcps.h | 71 + .../lwip-2.1/enhancement/include/lwip/fixme.h | 121 + .../net/lwip-2.1/enhancement/src/api_shell.c | 3932 ++++++ .../net/lwip-2.1/enhancement/src/dhcps.c | 982 ++ .../net/lwip-2.1/enhancement/src/fixme.c | 497 + .../net/lwip-2.1/lwip_porting.gni | 40 + .../net/lwip-2.1/porting/include/arch/cc.h | 74 + .../net/lwip-2.1/porting/include/arch/perf.h | 42 + .../lwip-2.1/porting/include/arch/sys_arch.h | 77 + .../net/lwip-2.1/porting/include/lwip/dhcp.h | 67 + .../net/lwip-2.1/porting/include/lwip/inet.h | 61 + .../net/lwip-2.1/porting/include/lwip/ip.h | 45 + .../lwip-2.1/porting/include/lwip/lwipopts.h | 225 + .../net/lwip-2.1/porting/include/lwip/netif.h | 99 + .../lwip-2.1/porting/include/lwip/netifapi.h | 58 + .../net/lwip-2.1/porting/include/lwip/pbuf.h | 57 + .../porting/include/lwip/priv/api_msg.h | 47 + .../porting/include/lwip/priv/sockets_priv.h | 41 + .../lwip-2.1/porting/include/lwip/sockets.h | 89 + .../net/lwip-2.1/porting/include/lwipopts.h | 38 + .../net/lwip-2.1/porting/src/driverif.c | 380 + .../net/lwip-2.1/porting/src/sockets.c | 1741 +++ .../net/lwip-2.1/porting/src/sys_arch.c | 334 + src/kernel_liteos_a/net/mac/los_mac.h | 60 + src/kernel_liteos_a/net/telnet/BUILD.gn | 45 + src/kernel_liteos_a/net/telnet/Kconfig | 6 + src/kernel_liteos_a/net/telnet/Makefile | 36 + .../net/telnet/include/telnet_dev.h | 85 + .../net/telnet/include/telnet_loop.h | 59 + .../net/telnet/include/telnet_pri.h | 56 + .../net/telnet/src/telnet_dev.c | 409 + .../net/telnet/src/telnet_loop.c | 584 + src/kernel_liteos_a/platform/BUILD.gn | 44 + src/kernel_liteos_a/platform/Kconfig | 88 + src/kernel_liteos_a/platform/Makefile | 40 + src/kernel_liteos_a/platform/board.ld.S | 56 + src/kernel_liteos_a/platform/bsp.mk | 38 + src/kernel_liteos_a/security/BUILD.gn | 44 + src/kernel_liteos_a/security/Kconfig | 30 + src/kernel_liteos_a/security/Makefile | 48 + src/kernel_liteos_a/security/cap/BUILD.gn | 41 + src/kernel_liteos_a/security/cap/Makefile | 36 + src/kernel_liteos_a/security/cap/capability.c | 118 + .../security/cap/capability_api.h | 41 + .../security/cap/capability_type.h | 69 + src/kernel_liteos_a/security/vid/BUILD.gn | 41 + src/kernel_liteos_a/security/vid/vid.c | 238 + src/kernel_liteos_a/security/vid/vid_api.h | 48 + src/kernel_liteos_a/security/vid/vid_type.h | 48 + src/kernel_liteos_a/shell/BUILD.gn | 53 + src/kernel_liteos_a/shell/Kconfig | 25 + src/kernel_liteos_a/shell/Makefile | 44 + .../shell/full/include/dmesg.h | 172 + .../shell/full/include/dmesg_pri.h | 68 + .../shell/full/include/shcmd.h | 108 + .../shell/full/include/shcmdparse.h | 73 + .../shell/full/include/shell.h | 136 + .../shell/full/include/shell_lk.h | 119 + .../shell/full/include/shell_pri.h | 60 + .../shell/full/include/shmsg.h | 58 + src/kernel_liteos_a/shell/full/include/show.h | 53 + .../shell/full/src/base/shcmd.c | 866 ++ .../shell/full/src/base/shcmdparse.c | 155 + .../shell/full/src/base/shell_lk.c | 232 + .../shell/full/src/base/shmsg.c | 462 + .../shell/full/src/base/show.c | 175 + .../shell/full/src/cmds/date_shellcmd.c | 301 + .../shell/full/src/cmds/dmesg.c | 792 ++ .../shell/full/src/cmds/hwi_shellcmd.c | 144 + .../shell/full/src/cmds/shell_shellcmd.c | 65 + .../shell/full/src/cmds/watch_shellcmd.c | 276 + src/kernel_liteos_a/syscall/BUILD.gn | 46 + src/kernel_liteos_a/syscall/Makefile | 40 + src/kernel_liteos_a/syscall/fs_syscall.c | 2880 +++++ src/kernel_liteos_a/syscall/ipc_syscall.c | 349 + src/kernel_liteos_a/syscall/los_syscall.c | 140 + src/kernel_liteos_a/syscall/los_syscall.h | 326 + src/kernel_liteos_a/syscall/misc_syscall.c | 280 + src/kernel_liteos_a/syscall/net_syscall.c | 497 + src/kernel_liteos_a/syscall/process_syscall.c | 1414 +++ src/kernel_liteos_a/syscall/syscall_lookup.h | 280 + src/kernel_liteos_a/syscall/syscall_pub.c | 130 + src/kernel_liteos_a/syscall/syscall_pub.h | 252 + src/kernel_liteos_a/syscall/time_syscall.c | 600 + src/kernel_liteos_a/syscall/vm_syscall.c | 117 + src/kernel_liteos_a/testsuites/BUILD.gn | 41 + src/kernel_liteos_a/testsuites/Kconfig | 49 + src/kernel_liteos_a/testsuites/LICENSE | 28 + src/kernel_liteos_a/testsuites/Makefile | 121 + .../testsuites/build/los_test_config.mk | 43 + src/kernel_liteos_a/testsuites/config.mk | 46 + .../testsuites/kernel/BUILD.gn | 99 + src/kernel_liteos_a/testsuites/kernel/Kconfig | 79 + .../testsuites/kernel/Makefile | 43 + .../testsuites/kernel/include/iCunit.h | 464 + .../testsuites/kernel/include/iCunit.inc | 64 + .../testsuites/kernel/include/iCunit_config.h | 60 + .../testsuites/kernel/include/los_test_pri.h | 49 + .../testsuites/kernel/include/osTest.h | 379 + .../kernel/sample/kernel_base/BUILD.gn | 37 + .../kernel/sample/kernel_base/core/BUILD.gn | 264 + .../kernel/sample/kernel_base/core/Makefile | 46 + .../sample/kernel_base/core/hwi/It_smp_hwi.c | 100 + .../sample/kernel_base/core/hwi/It_smp_hwi.h | 98 + .../core/hwi/smp/It_smp_los_hwi_001.c | 89 + .../core/hwi/smp/It_smp_los_hwi_002.c | 91 + .../core/hwi/smp/It_smp_los_hwi_003.c | 108 + .../core/hwi/smp/It_smp_los_hwi_004.c | 112 + .../core/hwi/smp/It_smp_los_hwi_005.c | 100 + .../core/hwi/smp/It_smp_los_hwi_006.c | 103 + .../core/hwi/smp/It_smp_los_hwi_007.c | 105 + .../core/hwi/smp/It_smp_los_hwi_008.c | 103 + .../core/hwi/smp/It_smp_los_hwi_009.c | 99 + .../core/hwi/smp/It_smp_los_hwi_010.c | 121 + .../core/hwi/smp/It_smp_los_hwi_011.c | 190 + .../core/hwi/smp/It_smp_los_hwi_012.c | 125 + .../core/hwi/smp/It_smp_los_hwi_013.c | 102 + .../core/hwi/smp/It_smp_los_hwi_ipi_001.c | 107 + .../core/hwi/smp/It_smp_los_hwi_ipi_002.c | 103 + .../core/hwi/smp/It_smp_los_hwi_ipi_003.c | 100 + .../core/hwi/smp/It_smp_los_hwi_ipi_004.c | 100 + .../core/hwi/smp/It_smp_los_hwi_ipi_005.c | 107 + .../core/hwi/smp/It_smp_los_hwi_ipi_006.c | 128 + .../core/hwi/smp/It_smp_los_hwi_ipi_007.c | 143 + .../core/hwi/smp/It_smp_los_hwi_ipi_008.c | 129 + .../core/hwi/smp/It_smp_los_hwi_nest_001.c | 115 + .../core/hwi/smp/It_smp_los_hwi_nest_002.c | 115 + .../core/hwi/smp/It_smp_los_hwi_nest_003.c | 99 + .../core/hwi/smp/It_smp_los_hwi_nest_004.c | 106 + .../core/hwi/smp/It_smp_los_hwi_nest_005.c | 116 + .../core/hwi/smp/It_smp_los_hwi_nest_006.c | 115 + .../core/hwi/smp/It_smp_los_hwi_nest_007.c | 115 + .../core/hwi/smp/It_smp_los_hwi_nest_008.c | 114 + .../core/hwi/smp/It_smp_los_hwi_share_001.c | 114 + .../core/hwi/smp/It_smp_los_hwi_share_002.c | 115 + .../core/hwi/smp/It_smp_los_hwi_share_003.c | 114 + .../core/hwi/smp/It_smp_los_hwi_share_004.c | 111 + .../core/hwi/smp/It_smp_los_hwi_share_005.c | 113 + .../core/hwi/smp/It_smp_los_hwi_share_006.c | 118 + .../core/hwi/smp/It_smp_los_hwi_share_007.c | 124 + .../core/hwi/smp/It_smp_los_hwi_share_008.c | 103 + .../core/hwi/smp/It_smp_los_hwi_share_009.c | 108 + .../core/hwi/smp/It_smp_los_hwi_share_010.c | 138 + .../core/hwi_nesting/It_hwi_nesting.c | 102 + .../core/hwi_nesting/It_hwi_nesting.h | 68 + .../hwi_nesting/full/It_los_hwi_nesting_001.c | 127 + .../hwi_nesting/full/It_los_hwi_nesting_002.c | 128 + .../hwi_nesting/full/It_los_hwi_nesting_003.c | 129 + .../hwi_nesting/full/It_los_hwi_nesting_004.c | 128 + .../hwi_nesting/full/It_los_hwi_nesting_005.c | 143 + .../hwi_nesting/full/It_los_hwi_nesting_006.c | 93 + .../hwi_nesting/full/It_los_hwi_nesting_007.c | 123 + .../kernel_base/core/swtmr/It_los_swtmr.c | 169 + .../kernel_base/core/swtmr/It_los_swtmr.h | 213 + .../core/swtmr/full/It_los_swtmr_001.c | 95 + .../core/swtmr/full/It_los_swtmr_002.c | 95 + .../core/swtmr/full/It_los_swtmr_003.c | 90 + .../core/swtmr/full/It_los_swtmr_005.c | 78 + .../core/swtmr/full/It_los_swtmr_006.c | 78 + .../core/swtmr/full/It_los_swtmr_007.c | 83 + .../core/swtmr/full/It_los_swtmr_008.c | 82 + .../core/swtmr/full/It_los_swtmr_009.c | 65 + .../core/swtmr/full/It_los_swtmr_010.c | 89 + .../core/swtmr/full/It_los_swtmr_011.c | 91 + .../core/swtmr/full/It_los_swtmr_012.c | 93 + .../core/swtmr/full/It_los_swtmr_013.c | 87 + .../core/swtmr/full/It_los_swtmr_014.c | 64 + .../core/swtmr/full/It_los_swtmr_015.c | 90 + .../core/swtmr/full/It_los_swtmr_016.c | 88 + .../core/swtmr/full/It_los_swtmr_017.c | 80 + .../core/swtmr/full/It_los_swtmr_018.c | 81 + .../core/swtmr/full/It_los_swtmr_019.c | 88 + .../core/swtmr/full/It_los_swtmr_020.c | 95 + .../core/swtmr/full/It_los_swtmr_021.c | 91 + .../core/swtmr/full/It_los_swtmr_022.c | 120 + .../core/swtmr/full/It_los_swtmr_030.c | 92 + .../core/swtmr/full/It_los_swtmr_033.c | 128 + .../core/swtmr/full/It_los_swtmr_036.c | 89 + .../core/swtmr/full/It_los_swtmr_037.c | 90 + .../core/swtmr/full/It_los_swtmr_039.c | 109 + .../core/swtmr/full/It_los_swtmr_040.c | 117 + .../core/swtmr/full/It_los_swtmr_041.c | 136 + .../core/swtmr/full/It_los_swtmr_042.c | 89 + .../core/swtmr/full/It_los_swtmr_043.c | 108 + .../core/swtmr/full/It_los_swtmr_044.c | 77 + .../core/swtmr/full/It_los_swtmr_045.c | 83 + .../core/swtmr/full/It_los_swtmr_046.c | 86 + .../core/swtmr/full/It_los_swtmr_047.c | 71 + .../core/swtmr/full/It_los_swtmr_048.c | 85 + .../core/swtmr/full/It_los_swtmr_049.c | 89 + .../core/swtmr/full/It_los_swtmr_050.c | 64 + .../core/swtmr/full/It_los_swtmr_051.c | 90 + .../core/swtmr/full/It_los_swtmr_052.c | 90 + .../core/swtmr/full/It_los_swtmr_054.c | 81 + .../core/swtmr/full/It_los_swtmr_055.c | 82 + .../core/swtmr/full/It_los_swtmr_056.c | 81 + .../core/swtmr/full/It_los_swtmr_057.c | 84 + .../core/swtmr/full/It_los_swtmr_059.c | 81 + .../core/swtmr/full/It_los_swtmr_060.c | 81 + .../core/swtmr/full/It_los_swtmr_061.c | 82 + .../core/swtmr/full/It_los_swtmr_062.c | 84 + .../core/swtmr/full/It_los_swtmr_063.c | 88 + .../core/swtmr/full/It_los_swtmr_064.c | 119 + .../core/swtmr/full/It_los_swtmr_065.c | 114 + .../core/swtmr/full/It_los_swtmr_066.c | 106 + .../core/swtmr/full/It_los_swtmr_067.c | 108 + .../core/swtmr/full/It_los_swtmr_068.c | 103 + .../core/swtmr/full/It_los_swtmr_069.c | 109 + .../core/swtmr/full/It_los_swtmr_070.c | 99 + .../core/swtmr/full/It_los_swtmr_071.c | 126 + .../core/swtmr/full/It_los_swtmr_075.c | 94 + .../core/swtmr/full/It_los_swtmr_076.c | 99 + .../core/swtmr/full/It_los_swtmr_077.c | 92 + .../core/swtmr/full/It_los_swtmr_078.c | 91 + .../core/swtmr/smoke/It_los_swtmr_053.c | 80 + .../core/swtmr/smoke/It_los_swtmr_058.c | 84 + .../core/swtmr/smp/It_smp_los_swtmr_001.c | 107 + .../core/swtmr/smp/It_smp_los_swtmr_002.c | 120 + .../core/swtmr/smp/It_smp_los_swtmr_003.c | 102 + .../core/swtmr/smp/It_smp_los_swtmr_004.c | 108 + .../core/swtmr/smp/It_smp_los_swtmr_005.c | 102 + .../core/swtmr/smp/It_smp_los_swtmr_006.c | 104 + .../core/swtmr/smp/It_smp_los_swtmr_007.c | 98 + .../core/swtmr/smp/It_smp_los_swtmr_008.c | 100 + .../core/swtmr/smp/It_smp_los_swtmr_009.c | 98 + .../core/swtmr/smp/It_smp_los_swtmr_010.c | 100 + .../core/swtmr/smp/It_smp_los_swtmr_011.c | 92 + .../core/swtmr/smp/It_smp_los_swtmr_012.c | 94 + .../core/swtmr/smp/It_smp_los_swtmr_013.c | 92 + .../core/swtmr/smp/It_smp_los_swtmr_014.c | 93 + .../core/swtmr/smp/It_smp_los_swtmr_015.c | 101 + .../core/swtmr/smp/It_smp_los_swtmr_016.c | 103 + .../core/swtmr/smp/It_smp_los_swtmr_017.c | 101 + .../core/swtmr/smp/It_smp_los_swtmr_018.c | 103 + .../core/swtmr/smp/It_smp_los_swtmr_019.c | 95 + .../core/swtmr/smp/It_smp_los_swtmr_020.c | 97 + .../core/swtmr/smp/It_smp_los_swtmr_021.c | 95 + .../core/swtmr/smp/It_smp_los_swtmr_022.c | 97 + .../core/swtmr/smp/It_smp_los_swtmr_023.c | 107 + .../core/swtmr/smp/It_smp_los_swtmr_024.c | 133 + .../core/swtmr/smp/It_smp_los_swtmr_025.c | 114 + .../core/swtmr/smp/It_smp_los_swtmr_026.c | 123 + .../core/swtmr/smp/It_smp_los_swtmr_027.c | 129 + .../core/swtmr/smp/It_smp_los_swtmr_028.c | 131 + .../core/swtmr/smp/It_smp_los_swtmr_029.c | 133 + .../core/swtmr/smp/It_smp_los_swtmr_030.c | 121 + .../core/swtmr/smp/It_smp_los_swtmr_031.c | 120 + .../core/swtmr/smp/It_smp_los_swtmr_032.c | 126 + .../core/swtmr/smp/It_smp_los_swtmr_033.c | 141 + .../core/swtmr/smp/It_smp_los_swtmr_034.c | 139 + .../core/swtmr/smp/It_smp_los_swtmr_035.c | 138 + .../kernel_base/core/task/It_los_task.c | 183 + .../kernel_base/core/task/It_los_task.h | 368 + .../core/task/float/It_los_float.h | 65 + .../task/float/It_smp_los_float_switch_001.c | 129 + .../task/float/It_smp_los_float_switch_002.c | 186 + .../task/float/It_smp_los_float_switch_003.c | 131 + .../task/float/It_smp_los_float_switch_004.c | 167 + .../task/float/It_smp_los_float_switch_005.c | 167 + .../task/float/It_smp_los_float_switch_006.c | 133 + .../task/float/It_smp_los_float_switch_007.c | 144 + .../core/task/full/It_los_task_001.c | 75 + .../core/task/full/It_los_task_002.c | 79 + .../core/task/full/It_los_task_004.c | 73 + .../core/task/full/It_los_task_007.c | 69 + .../core/task/full/It_los_task_008.c | 84 + .../core/task/full/It_los_task_009.c | 66 + .../core/task/full/It_los_task_010.c | 79 + .../core/task/full/It_los_task_011.c | 90 + .../core/task/full/It_los_task_012.c | 79 + .../core/task/full/It_los_task_013.c | 78 + .../core/task/full/It_los_task_014.c | 79 + .../core/task/full/It_los_task_015.c | 78 + .../core/task/full/It_los_task_016.c | 146 + .../core/task/full/It_los_task_017.c | 80 + .../core/task/full/It_los_task_018.c | 79 + .../core/task/full/It_los_task_019.c | 77 + .../core/task/full/It_los_task_020.c | 64 + .../core/task/full/It_los_task_021.c | 70 + .../core/task/full/It_los_task_022.c | 58 + .../core/task/full/It_los_task_023.c | 59 + .../core/task/full/It_los_task_024.c | 59 + .../core/task/full/It_los_task_025.c | 88 + .../core/task/full/It_los_task_026.c | 59 + .../core/task/full/It_los_task_027.c | 58 + .../core/task/full/It_los_task_028.c | 60 + .../core/task/full/It_los_task_029.c | 100 + .../core/task/full/It_los_task_031.c | 104 + .../core/task/full/It_los_task_032.c | 62 + .../core/task/full/It_los_task_033.c | 100 + .../core/task/full/It_los_task_034.c | 62 + .../core/task/full/It_los_task_035.c | 62 + .../core/task/full/It_los_task_036.c | 58 + .../core/task/full/It_los_task_037.c | 66 + .../core/task/full/It_los_task_038.c | 105 + .../core/task/full/It_los_task_039.c | 100 + .../core/task/full/It_los_task_040.c | 86 + .../core/task/full/It_los_task_041.c | 99 + .../core/task/full/It_los_task_042.c | 101 + .../core/task/full/It_los_task_043.c | 98 + .../core/task/full/It_los_task_047.c | 95 + .../core/task/full/It_los_task_048.c | 118 + .../core/task/full/It_los_task_050.c | 109 + .../core/task/full/It_los_task_051.c | 109 + .../core/task/full/It_los_task_052.c | 105 + .../core/task/full/It_los_task_053.c | 113 + .../core/task/full/It_los_task_054.c | 134 + .../core/task/full/It_los_task_055.c | 107 + .../core/task/full/It_los_task_056.c | 117 + .../core/task/full/It_los_task_057.c | 113 + .../core/task/full/It_los_task_058.c | 134 + .../core/task/full/It_los_task_060.c | 111 + .../core/task/full/It_los_task_061.c | 148 + .../core/task/full/It_los_task_063.c | 120 + .../core/task/full/It_los_task_064.c | 152 + .../core/task/full/It_los_task_065.c | 104 + .../core/task/full/It_los_task_066.c | 123 + .../core/task/full/It_los_task_067.c | 116 + .../core/task/full/It_los_task_068.c | 113 + .../core/task/full/It_los_task_069.c | 113 + .../core/task/full/It_los_task_071.c | 96 + .../core/task/full/It_los_task_072.c | 99 + .../core/task/full/It_los_task_073.c | 139 + .../core/task/full/It_los_task_074.c | 106 + .../core/task/full/It_los_task_075.c | 155 + .../core/task/full/It_los_task_076.c | 123 + .../core/task/full/It_los_task_077.c | 131 + .../core/task/full/It_los_task_078.c | 94 + .../core/task/full/It_los_task_079.c | 99 + .../core/task/full/It_los_task_080.c | 89 + .../core/task/full/It_los_task_082.c | 102 + .../core/task/full/It_los_task_090.c | 103 + .../core/task/full/It_los_task_092.c | 73 + .../core/task/full/It_los_task_093.c | 101 + .../core/task/full/It_los_task_094.c | 163 + .../core/task/full/It_los_task_095.c | 97 + .../core/task/full/It_los_task_096.c | 123 + .../core/task/full/It_los_task_098.c | 130 + .../core/task/full/It_los_task_100.c | 102 + .../core/task/full/It_los_task_102.c | 108 + .../core/task/full/It_los_task_103.c | 125 + .../core/task/full/It_los_task_104.c | 129 + .../core/task/full/It_los_task_106.c | 138 + .../core/task/full/It_los_task_107.c | 130 + .../core/task/full/It_los_task_108.c | 133 + .../core/task/full/It_los_task_109.c | 130 + .../core/task/full/It_los_task_110.c | 135 + .../core/task/full/It_los_task_111.c | 130 + .../core/task/full/It_los_task_112.c | 136 + .../core/task/full/It_los_task_113.c | 138 + .../core/task/full/It_los_task_114.c | 121 + .../core/task/full/It_los_task_115.c | 143 + .../core/task/full/It_los_task_116.c | 128 + .../core/task/full/It_los_task_118.c | 178 + .../core/task/full/It_los_task_119.c | 78 + .../core/task/full/It_los_task_120.c | 105 + .../core/task/full/It_los_task_121.c | 77 + .../core/task/full/It_los_task_122.c | 121 + .../core/task/full/It_los_task_123.c | 111 + .../core/task/full/It_los_task_124.c | 115 + .../core/task/full/It_los_task_125.c | 125 + .../core/task/full/It_los_task_126.c | 156 + .../core/task/full/It_los_task_127.c | 104 + .../core/task/full/It_los_task_128.c | 119 + .../core/task/full/It_los_task_129.c | 111 + .../core/task/full/It_los_task_130.c | 138 + .../core/task/full/It_los_task_131.c | 176 + .../core/task/full/It_los_task_132.c | 64 + .../core/task/full/It_los_task_133.c | 93 + .../core/task/full/It_los_task_134.c | 91 + .../core/task/full/It_los_task_135.c | 92 + .../core/task/full/It_los_task_136.c | 127 + .../core/task/full/It_los_task_138.c | 178 + .../core/task/full/It_los_task_141.c | 140 + .../core/task/full/It_los_task_142.c | 118 + .../task/full/It_los_task_timeslice_002.c | 123 + .../task/full/It_los_task_timeslice_003.c | 181 + .../task/full/It_los_task_timeslice_004.c | 164 + .../core/task/smoke/It_los_task_045.c | 90 + .../core/task/smoke/It_los_task_046.c | 60 + .../core/task/smoke/It_los_task_049.c | 114 + .../core/task/smoke/It_los_task_081.c | 157 + .../core/task/smoke/It_los_task_089.c | 58 + .../core/task/smoke/It_los_task_097.c | 122 + .../core/task/smoke/It_los_task_099.c | 103 + .../core/task/smoke/It_los_task_101.c | 102 + .../core/task/smoke/It_los_task_105.c | 111 + .../task/smoke/It_los_task_timeslice_001.c | 114 + .../core/task/smp/It_smp_los_task_001.c | 85 + .../core/task/smp/It_smp_los_task_002.c | 85 + .../core/task/smp/It_smp_los_task_003.c | 90 + .../core/task/smp/It_smp_los_task_004.c | 78 + .../core/task/smp/It_smp_los_task_021.c | 102 + .../core/task/smp/It_smp_los_task_022.c | 108 + .../core/task/smp/It_smp_los_task_023.c | 97 + .../core/task/smp/It_smp_los_task_024.c | 132 + .../core/task/smp/It_smp_los_task_025.c | 154 + .../core/task/smp/It_smp_los_task_026.c | 102 + .../core/task/smp/It_smp_los_task_027.c | 99 + .../core/task/smp/It_smp_los_task_028.c | 104 + .../core/task/smp/It_smp_los_task_029.c | 117 + .../core/task/smp/It_smp_los_task_030.c | 124 + .../core/task/smp/It_smp_los_task_032.c | 94 + .../core/task/smp/It_smp_los_task_033.c | 127 + .../core/task/smp/It_smp_los_task_034.c | 111 + .../core/task/smp/It_smp_los_task_035.c | 80 + .../core/task/smp/It_smp_los_task_036.c | 103 + .../core/task/smp/It_smp_los_task_037.c | 131 + .../core/task/smp/It_smp_los_task_040.c | 94 + .../core/task/smp/It_smp_los_task_042.c | 122 + .../core/task/smp/It_smp_los_task_043.c | 120 + .../core/task/smp/It_smp_los_task_044.c | 68 + .../core/task/smp/It_smp_los_task_046.c | 121 + .../core/task/smp/It_smp_los_task_047.c | 109 + .../core/task/smp/It_smp_los_task_048.c | 76 + .../core/task/smp/It_smp_los_task_049.c | 110 + .../core/task/smp/It_smp_los_task_050.c | 107 + .../core/task/smp/It_smp_los_task_051.c | 130 + .../core/task/smp/It_smp_los_task_052.c | 89 + .../core/task/smp/It_smp_los_task_053.c | 122 + .../core/task/smp/It_smp_los_task_054.c | 92 + .../core/task/smp/It_smp_los_task_055.c | 128 + .../core/task/smp/It_smp_los_task_056.c | 100 + .../core/task/smp/It_smp_los_task_057.c | 119 + .../core/task/smp/It_smp_los_task_058.c | 113 + .../core/task/smp/It_smp_los_task_059.c | 112 + .../core/task/smp/It_smp_los_task_060.c | 120 + .../core/task/smp/It_smp_los_task_061.c | 117 + .../core/task/smp/It_smp_los_task_062.c | 119 + .../core/task/smp/It_smp_los_task_063.c | 124 + .../core/task/smp/It_smp_los_task_064.c | 134 + .../core/task/smp/It_smp_los_task_065.c | 136 + .../core/task/smp/It_smp_los_task_066.c | 140 + .../core/task/smp/It_smp_los_task_067.c | 150 + .../core/task/smp/It_smp_los_task_068.c | 143 + .../core/task/smp/It_smp_los_task_069.c | 137 + .../core/task/smp/It_smp_los_task_070.c | 106 + .../core/task/smp/It_smp_los_task_071.c | 108 + .../core/task/smp/It_smp_los_task_072.c | 112 + .../core/task/smp/It_smp_los_task_073.c | 83 + .../core/task/smp/It_smp_los_task_074.c | 106 + .../core/task/smp/It_smp_los_task_075.c | 126 + .../core/task/smp/It_smp_los_task_076.c | 111 + .../core/task/smp/It_smp_los_task_077.c | 131 + .../core/task/smp/It_smp_los_task_078.c | 144 + .../core/task/smp/It_smp_los_task_079.c | 150 + .../core/task/smp/It_smp_los_task_081.c | 69 + .../core/task/smp/It_smp_los_task_082.c | 69 + .../core/task/smp/It_smp_los_task_084.c | 106 + .../core/task/smp/It_smp_los_task_087.c | 88 + .../core/task/smp/It_smp_los_task_088.c | 116 + .../core/task/smp/It_smp_los_task_089.c | 123 + .../core/task/smp/It_smp_los_task_090.c | 106 + .../core/task/smp/It_smp_los_task_091.c | 118 + .../core/task/smp/It_smp_los_task_092.c | 136 + .../core/task/smp/It_smp_los_task_093.c | 138 + .../core/task/smp/It_smp_los_task_094.c | 97 + .../core/task/smp/It_smp_los_task_095.c | 117 + .../core/task/smp/It_smp_los_task_096.c | 116 + .../core/task/smp/It_smp_los_task_097.c | 110 + .../core/task/smp/It_smp_los_task_098.c | 106 + .../core/task/smp/It_smp_los_task_099.c | 173 + .../core/task/smp/It_smp_los_task_100.c | 100 + .../core/task/smp/It_smp_los_task_101.c | 147 + .../core/task/smp/It_smp_los_task_102.c | 151 + .../core/task/smp/It_smp_los_task_103.c | 130 + .../core/task/smp/It_smp_los_task_105.c | 104 + .../core/task/smp/It_smp_los_task_106.c | 109 + .../core/task/smp/It_smp_los_task_107.c | 86 + .../core/task/smp/It_smp_los_task_108.c | 95 + .../core/task/smp/It_smp_los_task_109.c | 100 + .../core/task/smp/It_smp_los_task_110.c | 98 + .../core/task/smp/It_smp_los_task_112.c | 82 + .../core/task/smp/It_smp_los_task_113.c | 101 + .../core/task/smp/It_smp_los_task_114.c | 69 + .../core/task/smp/It_smp_los_task_115.c | 64 + .../core/task/smp/It_smp_los_task_117.c | 124 + .../core/task/smp/It_smp_los_task_126.c | 93 + .../core/task/smp/It_smp_los_task_127.c | 84 + .../core/task/smp/It_smp_los_task_128.c | 108 + .../core/task/smp/It_smp_los_task_129.c | 102 + .../core/task/smp/It_smp_los_task_130.c | 118 + .../core/task/smp/It_smp_los_task_131.c | 105 + .../core/task/smp/It_smp_los_task_132.c | 131 + .../core/task/smp/It_smp_los_task_133.c | 91 + .../core/task/smp/It_smp_los_task_134.c | 111 + .../core/task/smp/It_smp_los_task_135.c | 121 + .../core/task/smp/It_smp_los_task_136.c | 114 + .../core/task/smp/It_smp_los_task_137.c | 112 + .../core/task/smp/It_smp_los_task_138.c | 85 + .../core/task/smp/It_smp_los_task_139.c | 100 + .../core/task/smp/It_smp_los_task_141.c | 105 + .../core/task/smp/It_smp_los_task_142.c | 86 + .../core/task/smp/It_smp_los_task_143.c | 108 + .../core/task/smp/It_smp_los_task_144.c | 114 + .../core/task/smp/It_smp_los_task_145.c | 109 + .../core/task/smp/It_smp_los_task_146.c | 106 + .../core/task/smp/It_smp_los_task_147.c | 106 + .../core/task/smp/It_smp_los_task_148.c | 114 + .../core/task/smp/It_smp_los_task_149.c | 118 + .../core/task/smp/It_smp_los_task_150.c | 127 + .../core/task/smp/It_smp_los_task_151.c | 112 + .../core/task/smp/It_smp_los_task_152.c | 121 + .../core/task/smp/It_smp_los_task_153.c | 124 + .../core/task/smp/It_smp_los_task_154.c | 137 + .../core/task/smp/It_smp_los_task_155.c | 107 + .../core/task/smp/It_smp_los_task_156.c | 129 + .../core/task/smp/It_smp_los_task_157.c | 95 + .../core/task/smp/It_smp_los_task_158.c | 122 + .../core/task/smp/It_smp_los_task_159.c | 142 + .../core/task/smp/It_smp_los_task_160.c | 91 + .../core/task/smp/It_smp_los_task_161.c | 106 + .../kernel/sample/kernel_base/ipc/BUILD.gn | 111 + .../kernel/sample/kernel_base/ipc/Makefile | 51 + .../kernel_base/ipc/event/It_los_event.c | 145 + .../kernel_base/ipc/event/It_los_event.h | 199 + .../ipc/event/full/It_los_event_001.c | 104 + .../ipc/event/full/It_los_event_002.c | 109 + .../ipc/event/full/It_los_event_003.c | 97 + .../ipc/event/full/It_los_event_004.c | 106 + .../ipc/event/full/It_los_event_005.c | 81 + .../ipc/event/full/It_los_event_006.c | 120 + .../ipc/event/full/It_los_event_007.c | 120 + .../ipc/event/full/It_los_event_008.c | 112 + .../ipc/event/full/It_los_event_009.c | 103 + .../ipc/event/full/It_los_event_010.c | 126 + .../ipc/event/full/It_los_event_011.c | 138 + .../ipc/event/full/It_los_event_012.c | 132 + .../ipc/event/full/It_los_event_013.c | 123 + .../ipc/event/full/It_los_event_014.c | 121 + .../ipc/event/full/It_los_event_015.c | 113 + .../ipc/event/full/It_los_event_016.c | 106 + .../ipc/event/full/It_los_event_018.c | 125 + .../ipc/event/full/It_los_event_019.c | 133 + .../ipc/event/full/It_los_event_020.c | 134 + .../ipc/event/full/It_los_event_021.c | 121 + .../ipc/event/full/It_los_event_022.c | 130 + .../ipc/event/full/It_los_event_023.c | 151 + .../ipc/event/full/It_los_event_024.c | 83 + .../ipc/event/full/It_los_event_025.c | 93 + .../ipc/event/full/It_los_event_026.c | 115 + .../ipc/event/full/It_los_event_027.c | 129 + .../ipc/event/full/It_los_event_029.c | 97 + .../ipc/event/full/It_los_event_030.c | 89 + .../ipc/event/full/It_los_event_032.c | 142 + .../ipc/event/full/It_los_event_033.c | 169 + .../ipc/event/full/It_los_event_037.c | 113 + .../ipc/event/full/It_los_event_038.c | 168 + .../ipc/event/full/It_los_event_039.c | 116 + .../ipc/event/full/It_los_event_040.c | 98 + .../ipc/event/full/It_los_event_042.c | 102 + .../ipc/event/full/It_los_event_043.c | 114 + .../ipc/event/smoke/It_los_event_031.c | 57 + .../ipc/event/smoke/It_los_event_035.c | 62 + .../ipc/event/smoke/It_los_event_036.c | 111 + .../ipc/event/smoke/It_los_event_041.c | 97 + .../ipc/event/smp/It_smp_los_event_001.c | 87 + .../ipc/event/smp/It_smp_los_event_002.c | 90 + .../ipc/event/smp/It_smp_los_event_003.c | 91 + .../ipc/event/smp/It_smp_los_event_004.c | 93 + .../ipc/event/smp/It_smp_los_event_005.c | 109 + .../ipc/event/smp/It_smp_los_event_006.c | 103 + .../ipc/event/smp/It_smp_los_event_007.c | 114 + .../ipc/event/smp/It_smp_los_event_008.c | 96 + .../ipc/event/smp/It_smp_los_event_009.c | 123 + .../ipc/event/smp/It_smp_los_event_010.c | 111 + .../ipc/event/smp/It_smp_los_event_011.c | 113 + .../ipc/event/smp/It_smp_los_event_012.c | 117 + .../ipc/event/smp/It_smp_los_event_013.c | 117 + .../ipc/event/smp/It_smp_los_event_014.c | 113 + .../ipc/event/smp/It_smp_los_event_015.c | 124 + .../ipc/event/smp/It_smp_los_event_016.c | 92 + .../ipc/event/smp/It_smp_los_event_017.c | 93 + .../ipc/event/smp/It_smp_los_event_018.c | 94 + .../ipc/event/smp/It_smp_los_event_019.c | 94 + .../ipc/event/smp/It_smp_los_event_020.c | 97 + .../ipc/event/smp/It_smp_los_event_021.c | 99 + .../ipc/event/smp/It_smp_los_event_022.c | 113 + .../ipc/event/smp/It_smp_los_event_023.c | 112 + .../ipc/event/smp/It_smp_los_event_024.c | 112 + .../ipc/event/smp/It_smp_los_event_025.c | 117 + .../ipc/event/smp/It_smp_los_event_026.c | 127 + .../ipc/event/smp/It_smp_los_event_027.c | 121 + .../ipc/event/smp/It_smp_los_event_028.c | 140 + .../ipc/event/smp/It_smp_los_event_029.c | 151 + .../ipc/event/smp/It_smp_los_event_030.c | 105 + .../ipc/event/smp/It_smp_los_event_031.c | 139 + .../ipc/event/smp/It_smp_los_event_032.c | 144 + .../ipc/event/smp/It_smp_los_event_033.c | 140 + .../ipc/event/smp/It_smp_los_event_034.c | 137 + .../ipc/event/smp/It_smp_los_event_035.c | 129 + .../ipc/event/smp/It_smp_los_event_036.c | 126 + .../ipc/event/smp/It_smp_los_event_037.c | 154 + .../sample/kernel_base/ipc/mux/It_los_mux.c | 157 + .../sample/kernel_base/ipc/mux/It_los_mux.h | 152 + .../ipc/mux/full/It_los_mutex_006.c | 76 + .../ipc/mux/full/It_los_mutex_007.c | 132 + .../ipc/mux/full/It_los_mutex_008.c | 66 + .../ipc/mux/full/It_los_mutex_009.c | 88 + .../ipc/mux/full/It_los_mutex_010.c | 72 + .../ipc/mux/full/It_los_mutex_011.c | 101 + .../ipc/mux/full/It_los_mutex_012.c | 109 + .../ipc/mux/full/It_los_mutex_013.c | 99 + .../ipc/mux/full/It_los_mutex_015.c | 121 + .../ipc/mux/full/It_los_mutex_016.c | 100 + .../ipc/mux/full/It_los_mutex_017.c | 95 + .../ipc/mux/full/It_los_mutex_018.c | 76 + .../ipc/mux/full/It_los_mutex_020.c | 111 + .../ipc/mux/full/It_los_mutex_021.c | 134 + .../ipc/mux/full/It_los_mutex_025.c | 89 + .../ipc/mux/full/It_los_mutex_026.c | 242 + .../ipc/mux/full/It_los_mutex_027.c | 195 + .../ipc/mux/full/It_los_mutex_028.c | 194 + .../ipc/mux/full/It_los_mutex_029.c | 205 + .../ipc/mux/full/It_los_mutex_031.c | 215 + .../ipc/mux/full/It_los_mutex_035.c | 193 + .../ipc/mux/full/It_los_mutex_036.c | 174 + .../ipc/mux/full/It_los_mutex_037.c | 145 + .../ipc/mux/full/It_los_mutex_038.c | 134 + .../ipc/mux/full/It_los_mutex_039.c | 181 + .../ipc/mux/full/It_los_mutex_040.c | 315 + .../ipc/mux/full/It_los_mutex_041.c | 121 + .../ipc/mux/full/It_los_mutex_042.c | 165 + .../ipc/mux/full/It_los_mutex_043.c | 183 + .../ipc/mux/smoke/It_los_mutex_001.c | 69 + .../ipc/mux/smoke/It_los_mutex_002.c | 77 + .../ipc/mux/smoke/It_los_mutex_003.c | 76 + .../ipc/mux/smoke/It_los_mutex_004.c | 85 + .../ipc/mux/smp/It_smp_los_mux_001.c | 98 + .../ipc/mux/smp/It_smp_los_mux_002.c | 100 + .../ipc/mux/smp/It_smp_los_mux_003.c | 120 + .../ipc/mux/smp/It_smp_los_mux_004.c | 86 + .../ipc/mux/smp/It_smp_los_mux_005.c | 95 + .../ipc/mux/smp/It_smp_los_mux_006.c | 118 + .../ipc/mux/smp/It_smp_los_mux_007.c | 119 + .../ipc/mux/smp/It_smp_los_mux_2001.c | 87 + .../ipc/mux/smp/It_smp_los_mux_2002.c | 90 + .../ipc/mux/smp/It_smp_los_mux_2003.c | 92 + .../ipc/mux/smp/It_smp_los_mux_2004.c | 91 + .../ipc/mux/smp/It_smp_los_mux_2005.c | 124 + .../ipc/mux/smp/It_smp_los_mux_2006.c | 111 + .../ipc/mux/smp/It_smp_los_mux_2007.c | 124 + .../ipc/mux/smp/It_smp_los_mux_2008.c | 95 + .../ipc/mux/smp/It_smp_los_mux_2009.c | 121 + .../ipc/mux/smp/It_smp_los_mux_2010.c | 101 + .../ipc/mux/smp/It_smp_los_mux_2011.c | 127 + .../ipc/mux/smp/It_smp_los_mux_2012.c | 157 + .../ipc/mux/smp/It_smp_los_mux_2013.c | 123 + .../ipc/mux/smp/It_smp_los_mux_2014.c | 127 + .../ipc/mux/smp/It_smp_los_mux_2015.c | 169 + .../ipc/mux/smp/It_smp_los_mux_2016.c | 104 + .../ipc/mux/smp/It_smp_los_mux_2017.c | 112 + .../ipc/mux/smp/It_smp_los_mux_2018.c | 179 + .../ipc/mux/smp/It_smp_los_mux_2021.c | 111 + .../ipc/mux/smp/It_smp_los_mux_2022.c | 96 + .../ipc/mux/smp/It_smp_los_mux_2024.c | 105 + .../ipc/mux/smp/It_smp_los_mux_2025.c | 102 + .../ipc/mux/smp/It_smp_los_mux_2026.c | 147 + .../ipc/mux/smp/It_smp_los_mux_2027.c | 140 + .../ipc/mux/smp/It_smp_los_mux_2028.c | 126 + .../ipc/mux/smp/It_smp_los_mux_2029.c | 144 + .../kernel_base/ipc/queue/It_los_queue.c | 240 + .../kernel_base/ipc/queue/It_los_queue.h | 299 + .../ipc/queue/full/It_los_queue_002.c | 73 + .../ipc/queue/full/It_los_queue_003.c | 71 + .../ipc/queue/full/It_los_queue_005.c | 77 + .../ipc/queue/full/It_los_queue_006.c | 77 + .../ipc/queue/full/It_los_queue_007.c | 76 + .../ipc/queue/full/It_los_queue_008.c | 74 + .../ipc/queue/full/It_los_queue_009.c | 76 + .../ipc/queue/full/It_los_queue_010.c | 80 + .../ipc/queue/full/It_los_queue_011.c | 74 + .../ipc/queue/full/It_los_queue_012.c | 72 + .../ipc/queue/full/It_los_queue_013.c | 71 + .../ipc/queue/full/It_los_queue_014.c | 74 + .../ipc/queue/full/It_los_queue_015.c | 73 + .../ipc/queue/full/It_los_queue_017.c | 70 + .../ipc/queue/full/It_los_queue_018.c | 70 + .../ipc/queue/full/It_los_queue_019.c | 80 + .../ipc/queue/full/It_los_queue_020.c | 77 + .../ipc/queue/full/It_los_queue_021.c | 84 + .../ipc/queue/full/It_los_queue_022.c | 81 + .../ipc/queue/full/It_los_queue_023.c | 71 + .../ipc/queue/full/It_los_queue_024.c | 71 + .../ipc/queue/full/It_los_queue_025.c | 78 + .../ipc/queue/full/It_los_queue_026.c | 74 + .../ipc/queue/full/It_los_queue_027.c | 71 + .../ipc/queue/full/It_los_queue_028.c | 74 + .../ipc/queue/full/It_los_queue_029.c | 77 + .../ipc/queue/full/It_los_queue_032.c | 77 + .../ipc/queue/full/It_los_queue_033.c | 70 + .../ipc/queue/full/It_los_queue_037.c | 98 + .../ipc/queue/full/It_los_queue_038.c | 85 + .../ipc/queue/full/It_los_queue_040.c | 101 + .../ipc/queue/full/It_los_queue_041.c | 100 + .../ipc/queue/full/It_los_queue_042.c | 126 + .../ipc/queue/full/It_los_queue_043.c | 131 + .../ipc/queue/full/It_los_queue_044.c | 102 + .../ipc/queue/full/It_los_queue_045.c | 90 + .../ipc/queue/full/It_los_queue_046.c | 119 + .../ipc/queue/full/It_los_queue_047.c | 125 + .../ipc/queue/full/It_los_queue_048.c | 126 + .../ipc/queue/full/It_los_queue_049.c | 100 + .../ipc/queue/full/It_los_queue_050.c | 101 + .../ipc/queue/full/It_los_queue_051.c | 81 + .../ipc/queue/full/It_los_queue_052.c | 78 + .../ipc/queue/full/It_los_queue_053.c | 129 + .../ipc/queue/full/It_los_queue_054.c | 74 + .../ipc/queue/full/It_los_queue_055.c | 75 + .../ipc/queue/full/It_los_queue_056.c | 75 + .../ipc/queue/full/It_los_queue_057.c | 80 + .../ipc/queue/full/It_los_queue_058.c | 78 + .../ipc/queue/full/It_los_queue_059.c | 76 + .../ipc/queue/full/It_los_queue_061.c | 83 + .../ipc/queue/full/It_los_queue_062.c | 80 + .../ipc/queue/full/It_los_queue_064.c | 78 + .../ipc/queue/full/It_los_queue_065.c | 79 + .../ipc/queue/full/It_los_queue_066.c | 77 + .../ipc/queue/full/It_los_queue_067.c | 75 + .../ipc/queue/full/It_los_queue_068.c | 77 + .../ipc/queue/full/It_los_queue_069.c | 77 + .../ipc/queue/full/It_los_queue_070.c | 77 + .../ipc/queue/full/It_los_queue_071.c | 77 + .../ipc/queue/full/It_los_queue_072.c | 77 + .../ipc/queue/full/It_los_queue_073.c | 123 + .../ipc/queue/full/It_los_queue_074.c | 77 + .../ipc/queue/full/It_los_queue_075.c | 76 + .../ipc/queue/full/It_los_queue_076.c | 76 + .../ipc/queue/full/It_los_queue_077.c | 76 + .../ipc/queue/full/It_los_queue_078.c | 76 + .../ipc/queue/full/It_los_queue_079.c | 76 + .../ipc/queue/full/It_los_queue_080.c | 73 + .../ipc/queue/full/It_los_queue_081.c | 79 + .../ipc/queue/full/It_los_queue_082.c | 79 + .../ipc/queue/full/It_los_queue_083.c | 79 + .../ipc/queue/full/It_los_queue_084.c | 75 + .../ipc/queue/full/It_los_queue_085.c | 78 + .../ipc/queue/full/It_los_queue_086.c | 79 + .../ipc/queue/full/It_los_queue_087.c | 92 + .../ipc/queue/full/It_los_queue_088.c | 105 + .../ipc/queue/full/It_los_queue_089.c | 110 + .../ipc/queue/full/It_los_queue_091.c | 96 + .../ipc/queue/full/It_los_queue_092.c | 98 + .../ipc/queue/full/It_los_queue_093.c | 97 + .../ipc/queue/full/It_los_queue_094.c | 106 + .../ipc/queue/full/It_los_queue_095.c | 107 + .../ipc/queue/full/It_los_queue_096.c | 76 + .../ipc/queue/full/It_los_queue_098.c | 98 + .../ipc/queue/full/It_los_queue_099.c | 77 + .../ipc/queue/full/It_los_queue_101.c | 86 + .../ipc/queue/full/It_los_queue_102.c | 98 + .../ipc/queue/full/It_los_queue_103.c | 80 + .../ipc/queue/full/It_los_queue_104.c | 84 + .../ipc/queue/full/It_los_queue_106.c | 86 + .../ipc/queue/full/It_los_queue_107.c | 94 + .../ipc/queue/full/It_los_queue_108.c | 117 + .../ipc/queue/full/It_los_queue_109.c | 117 + .../ipc/queue/full/It_los_queue_110.c | 117 + .../ipc/queue/full/It_los_queue_111.c | 123 + .../ipc/queue/full/It_los_queue_112.c | 126 + .../ipc/queue/full/It_los_queue_113.c | 130 + .../ipc/queue/full/It_los_queue_114.c | 87 + .../ipc/queue/full/It_los_queue_116.c | 89 + .../ipc/queue/full/It_los_queue_head_003.c | 78 + .../ipc/queue/full/It_los_queue_head_004.c | 82 + .../ipc/queue/full/It_los_queue_head_005.c | 68 + .../ipc/queue/full/It_los_queue_head_006.c | 70 + .../ipc/queue/full/It_los_queue_head_007.c | 71 + .../ipc/queue/full/It_los_queue_head_008.c | 70 + .../ipc/queue/full/It_los_queue_head_009.c | 71 + .../ipc/queue/full/It_los_queue_head_010.c | 70 + .../ipc/queue/full/It_los_queue_head_011.c | 72 + .../ipc/queue/full/It_los_queue_head_012.c | 72 + .../ipc/queue/full/It_los_queue_head_013.c | 73 + .../ipc/queue/full/It_los_queue_head_014.c | 70 + .../ipc/queue/full/It_los_queue_head_015.c | 79 + .../ipc/queue/full/It_los_queue_head_016.c | 80 + .../ipc/queue/full/It_los_queue_head_017.c | 67 + .../ipc/queue/full/It_los_queue_head_018.c | 67 + .../ipc/queue/full/It_los_queue_head_019.c | 77 + .../ipc/queue/full/It_los_queue_head_020.c | 69 + .../ipc/queue/full/It_los_queue_head_021.c | 70 + .../ipc/queue/full/It_los_queue_head_022.c | 77 + .../ipc/queue/full/It_los_queue_head_023.c | 70 + .../ipc/queue/full/It_los_queue_head_024.c | 76 + .../ipc/queue/full/It_los_queue_head_025.c | 78 + .../ipc/queue/full/It_los_queue_head_026.c | 79 + .../ipc/queue/full/It_los_queue_head_027.c | 72 + .../ipc/queue/full/It_los_queue_head_028.c | 93 + .../ipc/queue/full/It_los_queue_head_029.c | 81 + .../ipc/queue/full/It_los_queue_head_030.c | 94 + .../ipc/queue/full/It_los_queue_head_031.c | 119 + .../ipc/queue/full/It_los_queue_head_032.c | 123 + .../ipc/queue/full/It_los_queue_head_038.c | 76 + .../ipc/queue/full/It_los_queue_head_039.c | 73 + .../ipc/queue/full/It_los_queue_head_040.c | 124 + .../ipc/queue/full/It_los_queue_head_041.c | 71 + .../ipc/queue/full/It_los_queue_head_042.c | 96 + .../ipc/queue/smoke/It_los_queue_001.c | 69 + .../ipc/queue/smoke/It_los_queue_097.c | 83 + .../ipc/queue/smoke/It_los_queue_100.c | 106 + .../ipc/queue/smoke/It_los_queue_105.c | 109 + .../ipc/queue/smoke/It_los_queue_head_002.c | 75 + .../ipc/queue/smp/It_smp_los_queue_001.c | 87 + .../ipc/queue/smp/It_smp_los_queue_002.c | 90 + .../ipc/queue/smp/It_smp_los_queue_003.c | 93 + .../ipc/queue/smp/It_smp_los_queue_004.c | 94 + .../ipc/queue/smp/It_smp_los_queue_005.c | 110 + .../ipc/queue/smp/It_smp_los_queue_006.c | 106 + .../ipc/queue/smp/It_smp_los_queue_007.c | 111 + .../ipc/queue/smp/It_smp_los_queue_008.c | 96 + .../ipc/queue/smp/It_smp_los_queue_009.c | 123 + .../ipc/queue/smp/It_smp_los_queue_010.c | 109 + .../ipc/queue/smp/It_smp_los_queue_011.c | 112 + .../ipc/queue/smp/It_smp_los_queue_012.c | 115 + .../ipc/queue/smp/It_smp_los_queue_013.c | 116 + .../ipc/queue/smp/It_smp_los_queue_014.c | 117 + .../ipc/queue/smp/It_smp_los_queue_015.c | 122 + .../ipc/queue/smp/It_smp_los_queue_016.c | 90 + .../ipc/queue/smp/It_smp_los_queue_017.c | 91 + .../ipc/queue/smp/It_smp_los_queue_018.c | 93 + .../ipc/queue/smp/It_smp_los_queue_019.c | 92 + .../ipc/queue/smp/It_smp_los_queue_020.c | 96 + .../ipc/queue/smp/It_smp_los_queue_021.c | 98 + .../ipc/queue/smp/It_smp_los_queue_022.c | 115 + .../ipc/queue/smp/It_smp_los_queue_023.c | 113 + .../ipc/queue/smp/It_smp_los_queue_024.c | 109 + .../ipc/queue/smp/It_smp_los_queue_025.c | 115 + .../ipc/queue/smp/It_smp_los_queue_026.c | 146 + .../ipc/queue/smp/It_smp_los_queue_027.c | 152 + .../ipc/queue/smp/It_smp_los_queue_029.c | 134 + .../ipc/queue/smp/It_smp_los_queue_031.c | 114 + .../ipc/queue/smp/It_smp_los_queue_032.c | 116 + .../sample/kernel_base/ipc/sem/It_los_sem.c | 164 + .../sample/kernel_base/ipc/sem/It_los_sem.h | 152 + .../kernel_base/ipc/sem/full/It_los_sem_002.c | 60 + .../kernel_base/ipc/sem/full/It_los_sem_005.c | 75 + .../kernel_base/ipc/sem/full/It_los_sem_009.c | 91 + .../kernel_base/ipc/sem/full/It_los_sem_012.c | 151 + .../kernel_base/ipc/sem/full/It_los_sem_013.c | 125 + .../kernel_base/ipc/sem/full/It_los_sem_014.c | 121 + .../kernel_base/ipc/sem/full/It_los_sem_015.c | 122 + .../kernel_base/ipc/sem/full/It_los_sem_016.c | 123 + .../kernel_base/ipc/sem/full/It_los_sem_017.c | 102 + .../kernel_base/ipc/sem/full/It_los_sem_019.c | 101 + .../kernel_base/ipc/sem/full/It_los_sem_020.c | 106 + .../kernel_base/ipc/sem/full/It_los_sem_022.c | 125 + .../kernel_base/ipc/sem/full/It_los_sem_023.c | 123 + .../kernel_base/ipc/sem/full/It_los_sem_026.c | 142 + .../kernel_base/ipc/sem/full/It_los_sem_027.c | 98 + .../kernel_base/ipc/sem/full/It_los_sem_028.c | 102 + .../kernel_base/ipc/sem/full/It_los_sem_029.c | 76 + .../kernel_base/ipc/sem/full/It_los_sem_034.c | 107 + .../ipc/sem/smoke/It_los_sem_001.c | 79 + .../ipc/sem/smoke/It_los_sem_003.c | 85 + .../ipc/sem/smoke/It_los_sem_006.c | 76 + .../ipc/sem/smp/It_smp_los_sem_001.c | 86 + .../ipc/sem/smp/It_smp_los_sem_002.c | 89 + .../ipc/sem/smp/It_smp_los_sem_003.c | 91 + .../ipc/sem/smp/It_smp_los_sem_004.c | 93 + .../ipc/sem/smp/It_smp_los_sem_005.c | 112 + .../ipc/sem/smp/It_smp_los_sem_006.c | 99 + .../ipc/sem/smp/It_smp_los_sem_007.c | 131 + .../ipc/sem/smp/It_smp_los_sem_008.c | 97 + .../ipc/sem/smp/It_smp_los_sem_009.c | 125 + .../ipc/sem/smp/It_smp_los_sem_010.c | 110 + .../ipc/sem/smp/It_smp_los_sem_011.c | 112 + .../ipc/sem/smp/It_smp_los_sem_012.c | 114 + .../ipc/sem/smp/It_smp_los_sem_013.c | 115 + .../ipc/sem/smp/It_smp_los_sem_014.c | 111 + .../ipc/sem/smp/It_smp_los_sem_015.c | 120 + .../ipc/sem/smp/It_smp_los_sem_016.c | 90 + .../ipc/sem/smp/It_smp_los_sem_017.c | 91 + .../ipc/sem/smp/It_smp_los_sem_018.c | 93 + .../ipc/sem/smp/It_smp_los_sem_019.c | 92 + .../ipc/sem/smp/It_smp_los_sem_020.c | 94 + .../ipc/sem/smp/It_smp_los_sem_021.c | 96 + .../ipc/sem/smp/It_smp_los_sem_022.c | 115 + .../ipc/sem/smp/It_smp_los_sem_023.c | 111 + .../ipc/sem/smp/It_smp_los_sem_024.c | 106 + .../ipc/sem/smp/It_smp_los_sem_025.c | 119 + .../ipc/sem/smp/It_smp_los_sem_026.c | 129 + .../ipc/sem/smp/It_smp_los_sem_027.c | 139 + .../ipc/sem/smp/It_smp_los_sem_028.c | 117 + .../ipc/sem/smp/It_smp_los_sem_029.c | 140 + .../ipc/sem/smp/It_smp_los_sem_030.c | 133 + .../ipc/sem/smp/It_smp_los_sem_031.c | 110 + .../ipc/sem/smp/It_smp_los_sem_032.c | 106 + .../ipc/sem/smp/It_smp_los_sem_033.c | 143 + .../ipc/sem/smp/It_smp_los_sem_034.c | 143 + .../ipc/sem/smp/It_smp_los_sem_035.c | 121 + .../ipc/sem/smp/It_smp_los_sem_036.c | 153 + .../kernel/sample/kernel_extend/cpup/BUILD.gn | 47 + .../kernel_extend/cpup/It_extend_cpup.c | 117 + .../kernel_extend/cpup/It_extend_cpup.h | 142 + .../kernel/sample/kernel_extend/cpup/Makefile | 40 + .../cpup/full/It_extend_cpup_003.c | 163 + .../cpup/full/It_extend_cpup_004.c | 143 + .../cpup/full/It_extend_cpup_005.c | 107 + .../cpup/full/It_extend_cpup_006.c | 153 + .../cpup/full/It_extend_cpup_007.c | 88 + .../cpup/full/It_extend_cpup_008.c | 97 + .../cpup/full/It_extend_cpup_011.c | 122 + .../cpup/full/It_extend_cpup_012.c | 119 + .../cpup/smoke/It_extend_cpup_001.c | 118 + .../cpup/smoke/It_extend_cpup_002.c | 118 + .../cpup/smp/It_smp_extend_cpup_001.c | 118 + .../cpup/smp/It_smp_extend_cpup_002.c | 94 + .../cpup/smp/It_smp_extend_cpup_003.c | 144 + .../cpup/smp/It_smp_extend_cpup_004.c | 164 + .../cpup/smp/It_smp_extend_cpup_005.c | 186 + .../cpup/smp/It_smp_extend_cpup_007.c | 116 + .../cpup/smp/It_smp_extend_cpup_008.c | 114 + .../cpup/smp/It_smp_extend_cpup_009.c | 139 + .../cpup/smp/It_smp_extend_cpup_010.c | 118 + .../cpup/smp/It_smp_extend_cpup_011.c | 137 + .../cpup/smp/It_smp_extend_cpup_012.c | 126 + .../testsuites/kernel/sample/posix/BUILD.gn | 117 + .../testsuites/kernel/sample/posix/Makefile | 37 + .../sample/posix/mutex/It_posix_mutex.c | 155 + .../sample/posix/mutex/It_posix_mutex.h | 205 + .../kernel/sample/posix/mutex/Makefile | 35 + .../posix/mutex/full/It_posix_mutex_002.c | 75 + .../posix/mutex/full/It_posix_mutex_003.c | 79 + .../posix/mutex/full/It_posix_mutex_004.c | 90 + .../posix/mutex/full/It_posix_mutex_005.c | 81 + .../posix/mutex/full/It_posix_mutex_006.c | 73 + .../posix/mutex/full/It_posix_mutex_008.c | 87 + .../posix/mutex/full/It_posix_mutex_009.c | 77 + .../posix/mutex/full/It_posix_mutex_010.c | 84 + .../posix/mutex/full/It_posix_mutex_011.c | 96 + .../posix/mutex/full/It_posix_mutex_013.c | 71 + .../posix/mutex/full/It_posix_mutex_014.c | 86 + .../posix/mutex/full/It_posix_mutex_017.c | 84 + .../posix/mutex/full/It_posix_mutex_018.c | 102 + .../posix/mutex/full/It_posix_mutex_021.c | 61 + .../posix/mutex/full/It_posix_mutex_022.c | 184 + .../posix/mutex/full/It_posix_mutex_023.c | 86 + .../posix/mutex/full/It_posix_mutex_024.c | 107 + .../posix/mutex/full/It_posix_mutex_025.c | 82 + .../posix/mutex/full/It_posix_mutex_026.c | 113 + .../posix/mutex/full/It_posix_mutex_027.c | 74 + .../posix/mutex/full/It_posix_mutex_028.c | 83 + .../posix/mutex/full/It_posix_mutex_029.c | 86 + .../posix/mutex/full/It_posix_mutex_032.c | 101 + .../posix/mutex/full/It_posix_mutex_033.c | 88 + .../posix/mutex/full/It_posix_mutex_034.c | 104 + .../posix/mutex/full/It_posix_mutex_035.c | 104 + .../posix/mutex/full/It_posix_mutex_036.c | 132 + .../posix/mutex/full/It_posix_mutex_037.c | 87 + .../posix/mutex/full/It_posix_mutex_038.c | 170 + .../posix/mutex/full/It_posix_mutex_039.c | 93 + .../posix/mutex/full/It_posix_mutex_040.c | 129 + .../posix/mutex/full/It_posix_mutex_041.c | 77 + .../posix/mutex/full/It_posix_mutex_042.c | 103 + .../posix/mutex/full/It_posix_mutex_043.c | 112 + .../posix/mutex/full/It_posix_mutex_044.c | 131 + .../posix/mutex/full/It_posix_mutex_045.c | 99 + .../posix/mutex/full/It_posix_mutex_046.c | 109 + .../posix/mutex/full/It_posix_mutex_047.c | 81 + .../posix/mutex/full/It_posix_mutex_048.c | 81 + .../posix/mutex/full/It_posix_mutex_049.c | 93 + .../posix/mutex/full/It_posix_mutex_050.c | 108 + .../posix/mutex/full/It_posix_mutex_054.c | 76 + .../posix/mutex/full/It_posix_mutex_055.c | 75 + .../posix/mutex/full/It_posix_mutex_056.c | 100 + .../posix/mutex/full/It_posix_mutex_057.c | 68 + .../posix/mutex/full/It_posix_mutex_058.c | 106 + .../posix/mutex/full/It_posix_mutex_059.c | 105 + .../posix/mutex/full/It_posix_mutex_060.c | 99 + .../posix/mutex/full/It_posix_mutex_061.c | 66 + .../posix/mutex/full/It_posix_mutex_062.c | 72 + .../posix/mutex/full/It_posix_mutex_063.c | 75 + .../posix/mutex/full/It_posix_mutex_064.c | 85 + .../posix/mutex/full/It_posix_mutex_065.c | 79 + .../posix/mutex/full/It_posix_mutex_066.c | 111 + .../posix/mutex/full/It_posix_mutex_067.c | 104 + .../posix/mutex/full/It_posix_mutex_068.c | 140 + .../posix/mutex/full/It_posix_mutex_069.c | 124 + .../posix/mutex/full/It_posix_mutex_070.c | 161 + .../posix/mutex/full/It_posix_mutex_071.c | 134 + .../posix/mutex/full/It_posix_mutex_072.c | 133 + .../posix/mutex/full/It_posix_mutex_073.c | 72 + .../posix/mutex/full/It_posix_mutex_074.c | 178 + .../posix/mutex/full/It_posix_mutex_075.c | 177 + .../posix/mutex/full/It_posix_mutex_076.c | 117 + .../posix/mutex/full/It_posix_mutex_077.c | 137 + .../posix/mutex/full/It_posix_mutex_078.c | 81 + .../posix/mutex/full/It_posix_mutex_079.c | 141 + .../posix/mutex/full/It_posix_mutex_080.c | 92 + .../posix/mutex/full/It_posix_mutex_081.c | 90 + .../posix/mutex/full/It_posix_mutex_082.c | 96 + .../posix/mutex/full/It_posix_mutex_084.c | 85 + .../posix/mutex/full/It_posix_mutex_085.c | 95 + .../posix/mutex/full/It_posix_mutex_086.c | 84 + .../posix/mutex/full/It_posix_mutex_087.c | 90 + .../posix/mutex/full/It_posix_mutex_089.c | 80 + .../posix/mutex/full/It_posix_mutex_090.c | 75 + .../posix/mutex/full/It_posix_mutex_091.c | 94 + .../posix/mutex/full/It_posix_mutex_092.c | 107 + .../posix/mutex/full/It_posix_mutex_093.c | 136 + .../posix/mutex/full/It_posix_mutex_094.c | 75 + .../posix/mutex/full/It_posix_mutex_095.c | 83 + .../posix/mutex/full/It_posix_mutex_097.c | 94 + .../posix/mutex/full/It_posix_mutex_098.c | 107 + .../posix/mutex/full/It_posix_mutex_099.c | 130 + .../posix/mutex/full/It_posix_mutex_101.c | 103 + .../posix/mutex/smoke/It_posix_mutex_001.c | 76 + .../posix/mutex/smoke/It_posix_mutex_007.c | 100 + .../posix/mutex/smoke/It_posix_mutex_012.c | 91 + .../posix/mutex/smoke/It_posix_mutex_015.c | 96 + .../posix/mutex/smoke/It_posix_mutex_016.c | 104 + .../posix/mutex/smoke/It_posix_mutex_019.c | 210 + .../posix/mutex/smoke/It_posix_mutex_020.c | 89 + .../sample/posix/pthread/It_posix_pthread.c | 358 + .../sample/posix/pthread/It_posix_pthread.h | 358 + .../kernel/sample/posix/pthread/Makefile | 36 + .../posix/pthread/full/It_posix_pthread_001.c | 106 + .../posix/pthread/full/It_posix_pthread_002.c | 62 + .../posix/pthread/full/It_posix_pthread_007.c | 123 + .../posix/pthread/full/It_posix_pthread_008.c | 64 + .../posix/pthread/full/It_posix_pthread_010.c | 90 + .../posix/pthread/full/It_posix_pthread_011.c | 86 + .../posix/pthread/full/It_posix_pthread_013.c | 85 + .../posix/pthread/full/It_posix_pthread_023.c | 87 + .../posix/pthread/full/It_posix_pthread_028.c | 77 + .../posix/pthread/full/It_posix_pthread_029.c | 77 + .../posix/pthread/full/It_posix_pthread_030.c | 85 + .../posix/pthread/full/It_posix_pthread_031.c | 80 + .../posix/pthread/full/It_posix_pthread_032.c | 131 + .../posix/pthread/full/It_posix_pthread_033.c | 105 + .../posix/pthread/full/It_posix_pthread_034.c | 130 + .../posix/pthread/full/It_posix_pthread_035.c | 135 + .../posix/pthread/full/It_posix_pthread_039.c | 109 + .../posix/pthread/full/It_posix_pthread_040.c | 92 + .../posix/pthread/full/It_posix_pthread_041.c | 90 + .../posix/pthread/full/It_posix_pthread_042.c | 122 + .../posix/pthread/full/It_posix_pthread_044.c | 158 + .../posix/pthread/full/It_posix_pthread_045.c | 115 + .../posix/pthread/full/It_posix_pthread_046.c | 108 + .../posix/pthread/full/It_posix_pthread_047.c | 121 + .../posix/pthread/full/It_posix_pthread_048.c | 85 + .../posix/pthread/full/It_posix_pthread_049.c | 97 + .../posix/pthread/full/It_posix_pthread_050.c | 96 + .../posix/pthread/full/It_posix_pthread_051.c | 99 + .../posix/pthread/full/It_posix_pthread_056.c | 101 + .../posix/pthread/full/It_posix_pthread_057.c | 91 + .../posix/pthread/full/It_posix_pthread_058.c | 146 + .../posix/pthread/full/It_posix_pthread_060.c | 104 + .../posix/pthread/full/It_posix_pthread_066.c | 137 + .../posix/pthread/full/It_posix_pthread_068.c | 120 + .../posix/pthread/full/It_posix_pthread_069.c | 76 + .../posix/pthread/full/It_posix_pthread_071.c | 87 + .../posix/pthread/full/It_posix_pthread_072.c | 107 + .../posix/pthread/full/It_posix_pthread_073.c | 75 + .../posix/pthread/full/It_posix_pthread_074.c | 69 + .../posix/pthread/full/It_posix_pthread_075.c | 65 + .../posix/pthread/full/It_posix_pthread_078.c | 69 + .../posix/pthread/full/It_posix_pthread_079.c | 71 + .../posix/pthread/full/It_posix_pthread_080.c | 121 + .../posix/pthread/full/It_posix_pthread_081.c | 126 + .../posix/pthread/full/It_posix_pthread_082.c | 135 + .../posix/pthread/full/It_posix_pthread_083.c | 136 + .../posix/pthread/full/It_posix_pthread_084.c | 136 + .../posix/pthread/full/It_posix_pthread_085.c | 115 + .../posix/pthread/full/It_posix_pthread_087.c | 116 + .../posix/pthread/full/It_posix_pthread_088.c | 192 + .../posix/pthread/full/It_posix_pthread_089.c | 195 + .../posix/pthread/full/It_posix_pthread_092.c | 130 + .../posix/pthread/full/It_posix_pthread_095.c | 137 + .../posix/pthread/full/It_posix_pthread_098.c | 95 + .../posix/pthread/full/It_posix_pthread_101.c | 88 + .../posix/pthread/full/It_posix_pthread_102.c | 108 + .../posix/pthread/full/It_posix_pthread_103.c | 106 + .../posix/pthread/full/It_posix_pthread_107.c | 138 + .../posix/pthread/full/It_posix_pthread_108.c | 73 + .../posix/pthread/full/It_posix_pthread_110.c | 58 + .../posix/pthread/full/It_posix_pthread_112.c | 62 + .../posix/pthread/full/It_posix_pthread_116.c | 135 + .../posix/pthread/full/It_posix_pthread_121.c | 80 + .../posix/pthread/full/It_posix_pthread_123.c | 82 + .../posix/pthread/full/It_posix_pthread_124.c | 87 + .../posix/pthread/full/It_posix_pthread_125.c | 87 + .../posix/pthread/full/It_posix_pthread_127.c | 172 + .../posix/pthread/full/It_posix_pthread_128.c | 86 + .../posix/pthread/full/It_posix_pthread_129.c | 74 + .../posix/pthread/full/It_posix_pthread_132.c | 81 + .../posix/pthread/full/It_posix_pthread_133.c | 74 + .../posix/pthread/full/It_posix_pthread_134.c | 79 + .../posix/pthread/full/It_posix_pthread_136.c | 85 + .../posix/pthread/full/It_posix_pthread_138.c | 87 + .../posix/pthread/full/It_posix_pthread_141.c | 70 + .../posix/pthread/full/It_posix_pthread_142.c | 73 + .../posix/pthread/full/It_posix_pthread_144.c | 97 + .../posix/pthread/full/It_posix_pthread_150.c | 98 + .../posix/pthread/full/It_posix_pthread_152.c | 71 + .../posix/pthread/full/It_posix_pthread_154.c | 81 + .../posix/pthread/full/It_posix_pthread_166.c | 91 + .../posix/pthread/full/It_posix_pthread_167.c | 69 + .../posix/pthread/full/It_posix_pthread_173.c | 70 + .../posix/pthread/full/It_posix_pthread_175.c | 88 + .../posix/pthread/full/It_posix_pthread_176.c | 68 + .../posix/pthread/full/It_posix_pthread_177.c | 85 + .../posix/pthread/full/It_posix_pthread_182.c | 106 + .../posix/pthread/full/It_posix_pthread_185.c | 80 + .../posix/pthread/full/It_posix_pthread_186.c | 110 + .../posix/pthread/full/It_posix_pthread_187.c | 114 + .../posix/pthread/full/It_posix_pthread_188.c | 118 + .../posix/pthread/full/It_posix_pthread_193.c | 105 + .../posix/pthread/full/It_posix_pthread_194.c | 105 + .../posix/pthread/full/It_posix_pthread_197.c | 75 + .../posix/pthread/full/It_posix_pthread_198.c | 74 + .../posix/pthread/full/It_posix_pthread_200.c | 90 + .../posix/pthread/full/It_posix_pthread_204.c | 93 + .../posix/pthread/full/It_posix_pthread_205.c | 126 + .../posix/pthread/full/It_posix_pthread_206.c | 109 + .../posix/pthread/full/It_posix_pthread_208.c | 78 + .../posix/pthread/full/It_posix_pthread_209.c | 107 + .../posix/pthread/full/It_posix_pthread_211.c | 76 + .../posix/pthread/full/It_posix_pthread_213.c | 107 + .../posix/pthread/full/It_posix_pthread_214.c | 74 + .../posix/pthread/full/It_posix_pthread_215.c | 110 + .../posix/pthread/full/It_posix_pthread_217.c | 70 + .../posix/pthread/full/It_posix_pthread_218.c | 88 + .../posix/pthread/full/It_posix_pthread_219.c | 67 + .../posix/pthread/full/It_posix_pthread_221.c | 65 + .../posix/pthread/full/It_posix_pthread_224.c | 90 + .../posix/pthread/full/It_posix_pthread_226.c | 94 + .../posix/pthread/full/It_posix_pthread_233.c | 101 + .../posix/pthread/full/It_posix_pthread_237.c | 71 + .../posix/pthread/full/It_posix_pthread_238.c | 102 + .../posix/pthread/full/It_posix_pthread_239.c | 98 + .../posix/pthread/full/It_posix_pthread_240.c | 99 + .../posix/pthread/full/It_posix_pthread_241.c | 81 + .../posix/pthread/full/It_posix_pthread_246.c | 100 + .../pthread/smoke/It_posix_pthread_003.c | 85 + .../pthread/smoke/It_posix_pthread_004.c | 83 + .../pthread/smoke/It_posix_pthread_005.c | 84 + .../pthread/smoke/It_posix_pthread_006.c | 84 + .../pthread/smoke/It_posix_pthread_009.c | 95 + .../pthread/smoke/It_posix_pthread_018.c | 129 + .../pthread/smoke/It_posix_pthread_019.c | 83 + .../pthread/smoke/It_posix_pthread_021.c | 84 + .../testsuites/kernel/src/iCunit.c | 663 + .../testsuites/kernel/src/osTest.c | 509 + src/kernel_liteos_a/testsuites/kernel/test.mk | 587 + .../testsuites/unittest/BUILD.gn | 204 + .../testsuites/unittest/basic/BUILD.gn | 56 + .../testsuites/unittest/basic/config.gni | 77 + .../unittest/basic/dynload/config.gni | 40 + .../unittest/basic/dynload/dynload_test.cpp | 65 + .../unittest/basic/dynload/it_test_dynload.h | 41 + .../basic/dynload/smoke/dynload_test_002.cpp | 96 + .../basic/dynload/smoke/dynload_test_004.cpp | 74 + .../testsuites/unittest/basic/exc/config.gni | 44 + .../unittest/basic/exc/exc_test.cpp | 95 + .../basic/exc/full/it_test_fexecve_001.cpp | 121 + .../unittest/basic/exc/it_test_exc.h | 44 + .../basic/exc/smoke/it_test_exc_001.cpp | 76 + .../basic/exc/smoke/it_test_exc_002.cpp | 110 + .../basic/exc/smoke/it_test_exc_003.cpp | 118 + .../basic/exc/smoke/it_test_exc_004.cpp | 84 + .../basic/exc/smoke/it_test_exc_005.cpp | 85 + .../unittest/basic/mem/shm/config.gni | 52 + .../basic/mem/shm/full/it_test_mem_100.cpp | 62 + .../basic/mem/shm/full/shm_test_001.cpp | 169 + .../basic/mem/shm/full/shm_test_002.cpp | 84 + .../basic/mem/shm/full/shm_test_003.cpp | 82 + .../basic/mem/shm/full/shm_test_004.cpp | 91 + .../basic/mem/shm/full/shm_test_005.cpp | 81 + .../basic/mem/shm/full/shm_test_006.cpp | 66 + .../basic/mem/shm/full/shm_test_007.cpp | 97 + .../basic/mem/shm/full/shm_test_008.cpp | 63 + .../basic/mem/shm/full/shm_test_009.cpp | 159 + .../basic/mem/shm/full/shm_test_010.cpp | 70 + .../basic/mem/shm/full/shm_test_012.cpp | 78 + .../basic/mem/shm/full/shm_test_013.cpp | 76 + .../basic/mem/shm/full/shm_test_014.cpp | 91 + .../unittest/basic/mem/shm/it_test_shm.h | 54 + .../unittest/basic/mem/shm/mem_shm_test.cpp | 158 + .../basic/mem/shm/smoke/shm_test_011.cpp | 79 + .../unittest/basic/mem/vm/config.gni | 53 + .../unittest/basic/mem/vm/it_test_vm.h | 61 + .../unittest/basic/mem/vm/mem_vm_test.cpp | 167 + .../basic/mem/vm/smoke/mmap_test_001.cpp | 82 + .../basic/mem/vm/smoke/mmap_test_002.cpp | 139 + .../basic/mem/vm/smoke/mmap_test_003.cpp | 83 + .../basic/mem/vm/smoke/mmap_test_004.cpp | 83 + .../basic/mem/vm/smoke/mmap_test_005.cpp | 53 + .../basic/mem/vm/smoke/mmap_test_006.cpp | 100 + .../basic/mem/vm/smoke/mmap_test_007.cpp | 93 + .../basic/mem/vm/smoke/mmap_test_008.cpp | 84 + .../basic/mem/vm/smoke/mmap_test_009.cpp | 93 + .../basic/mem/vm/smoke/mmap_test_010.cpp | 63 + .../basic/mem/vm/smoke/mprotect_test_001.cpp | 81 + .../basic/mem/vm/smoke/mremap_test_001.cpp | 97 + .../basic/mem/vm/smoke/oom_test_001.cpp | 67 + .../mem/vm/smoke/open_wmemstream_test_001.cpp | 64 + .../basic/mem/vm/smoke/user_copy_test_001.cpp | 72 + .../unittest/common/include/iCunit.h | 401 + .../unittest/common/include/los_typedef.h | 202 + .../unittest/common/include/osTest.h | 498 + .../testsuites/unittest/common/osTest.cpp | 475 + .../testsuites/unittest/config.gni | 181 + .../testsuites/unittest/container/BUILD.gn | 88 + .../unittest/container/It_container_test.cpp | 1394 +++ .../unittest/container/It_container_test.h | 239 + .../testsuites/unittest/container/config.gni | 170 + .../container/full/It_net_container_010.cpp | 82 + .../container/full/It_pid_container_001.cpp | 54 + .../container/full/It_pid_container_002.cpp | 152 + .../container/full/It_pid_container_003.cpp | 104 + .../container/full/It_pid_container_004.cpp | 106 + .../container/full/It_pid_container_005.cpp | 140 + .../container/full/It_pid_container_006.cpp | 98 + .../container/full/It_pid_container_007.cpp | 72 + .../container/full/It_pid_container_008.cpp | 85 + .../container/full/It_pid_container_009.cpp | 96 + .../container/full/It_pid_container_010.cpp | 65 + .../container/full/It_pid_container_011.cpp | 54 + .../container/full/It_pid_container_012.cpp | 55 + .../container/full/It_pid_container_013.cpp | 67 + .../container/full/It_pid_container_014.cpp | 146 + .../container/full/It_pid_container_015.cpp | 58 + .../container/full/It_pid_container_016.cpp | 58 + .../container/full/It_pid_container_017.cpp | 58 + .../container/full/It_pid_container_018.cpp | 155 + .../container/full/It_pid_container_019.cpp | 120 + .../container/full/It_pid_container_020.cpp | 117 + .../container/full/It_pid_container_021.cpp | 72 + .../container/full/It_pid_container_022.cpp | 64 + .../container/full/It_pid_container_024.cpp | 82 + .../container/full/It_user_container_005.cpp | 90 + .../container/full/It_uts_container_003.cpp | 83 + .../container/smoke/It_container_001.cpp | 71 + .../smoke/It_container_chroot_001.cpp | 106 + .../smoke/It_container_chroot_002.cpp | 118 + .../container/smoke/It_ipc_container_001.cpp | 129 + .../container/smoke/It_ipc_container_002.cpp | 151 + .../container/smoke/It_ipc_container_003.cpp | 163 + .../container/smoke/It_ipc_container_004.cpp | 217 + .../container/smoke/It_ipc_container_005.cpp | 187 + .../container/smoke/It_ipc_container_006.cpp | 184 + .../container/smoke/It_ipc_container_007.cpp | 100 + .../container/smoke/It_ipc_container_008.cpp | 105 + .../container/smoke/It_mnt_container_001.cpp | 97 + .../container/smoke/It_mnt_container_002.cpp | 100 + .../container/smoke/It_mnt_container_003.cpp | 94 + .../container/smoke/It_mnt_container_004.cpp | 91 + .../container/smoke/It_mnt_container_005.cpp | 77 + .../container/smoke/It_mnt_container_006.cpp | 103 + .../container/smoke/It_mnt_container_007.cpp | 100 + .../container/smoke/It_mnt_container_008.cpp | 90 + .../container/smoke/It_mnt_container_009.cpp | 100 + .../container/smoke/It_mnt_container_010.cpp | 105 + .../container/smoke/It_net_container_001.cpp | 132 + .../container/smoke/It_net_container_002.cpp | 141 + .../container/smoke/It_net_container_003.cpp | 78 + .../container/smoke/It_net_container_004.cpp | 121 + .../container/smoke/It_net_container_005.cpp | 210 + .../container/smoke/It_net_container_006.cpp | 181 + .../container/smoke/It_net_container_007.cpp | 102 + .../container/smoke/It_net_container_008.cpp | 119 + .../container/smoke/It_net_container_009.cpp | 239 + .../container/smoke/It_net_container_011.cpp | 100 + .../container/smoke/It_net_container_012.cpp | 105 + .../container/smoke/It_pid_container_023.cpp | 71 + .../container/smoke/It_pid_container_025.cpp | 69 + .../container/smoke/It_pid_container_026.cpp | 70 + .../container/smoke/It_pid_container_027.cpp | 147 + .../container/smoke/It_pid_container_028.cpp | 145 + .../container/smoke/It_pid_container_029.cpp | 129 + .../container/smoke/It_pid_container_030.cpp | 135 + .../container/smoke/It_pid_container_031.cpp | 146 + .../container/smoke/It_pid_container_032.cpp | 102 + .../container/smoke/It_pid_container_033.cpp | 107 + .../container/smoke/It_time_container_001.cpp | 74 + .../container/smoke/It_time_container_002.cpp | 165 + .../container/smoke/It_time_container_003.cpp | 119 + .../container/smoke/It_time_container_004.cpp | 133 + .../container/smoke/It_time_container_005.cpp | 133 + .../container/smoke/It_time_container_006.cpp | 111 + .../container/smoke/It_time_container_007.cpp | 73 + .../container/smoke/It_time_container_008.cpp | 92 + .../container/smoke/It_time_container_009.cpp | 75 + .../container/smoke/It_time_container_010.cpp | 73 + .../container/smoke/It_user_container_001.cpp | 63 + .../container/smoke/It_user_container_002.cpp | 154 + .../container/smoke/It_user_container_003.cpp | 142 + .../container/smoke/It_user_container_004.cpp | 107 + .../container/smoke/It_user_container_006.cpp | 100 + .../container/smoke/It_user_container_007.cpp | 105 + .../container/smoke/It_uts_container_001.cpp | 58 + .../container/smoke/It_uts_container_002.cpp | 97 + .../container/smoke/It_uts_container_004.cpp | 97 + .../container/smoke/It_uts_container_005.cpp | 120 + .../container/smoke/It_uts_container_006.cpp | 99 + .../container/smoke/It_uts_container_007.cpp | 100 + .../container/smoke/It_uts_container_008.cpp | 105 + .../testsuites/unittest/drivers/BUILD.gn | 56 + .../testsuites/unittest/drivers/config.gni | 60 + .../unittest/drivers/hid/config.gni | 37 + .../unittest/drivers/hid/drivers_hid_test.cpp | 54 + .../unittest/drivers/hid/it_test_hid.h | 39 + .../drivers/hid/smoke/hid_test_001.cpp | 92 + .../unittest/drivers/storage/config.gni | 39 + .../drivers/storage/drivers_storage_test.cpp | 54 + .../drivers/storage/it_test_storage.h | 39 + .../storage/smoke/storage_test_001.cpp | 83 + .../testsuites/unittest/extended/BUILD.gn | 56 + .../testsuites/unittest/extended/config.gni | 78 + .../unittest/extended/ipc/It_test_IPC.h | 65 + .../unittest/extended/ipc/config.gni | 40 + .../ipc/full/ipc_test_mkfifoat_001.cpp | 81 + .../ipc/full/ipc_test_mkfifoat_002.cpp | 73 + .../unittest/extended/ipc/ipc_test.cpp | 43 + .../unittest/extended/liteipc/config.gni | 43 + .../extended/liteipc/it_test_liteipc.cpp | 63 + .../extended/liteipc/it_test_liteipc.h | 43 + .../unittest/extended/liteipc/liteipc.h | 110 + .../unittest/extended/liteipc/smgr_demo.cpp | 297 + .../unittest/extended/liteipc/smgr_demo.h | 53 + .../liteipc/smoke/liteipc_test_001.cpp | 145 + .../liteipc/smoke/liteipc_test_002.cpp | 274 + .../unittest/extended/signal/config.gni | 102 + .../extended/signal/full/It_ipc_fdclr_001.cpp | 96 + .../extended/signal/full/It_ipc_fdset_001.cpp | 96 + .../signal/full/It_ipc_fdzero_001.cpp | 96 + .../extended/signal/full/It_ipc_pipe_002.cpp | 87 + .../extended/signal/full/It_ipc_pipe_003.cpp | 89 + .../signal/full/It_ipc_sigaction_001.cpp | 86 + .../signal/full/It_ipc_sigpause_001.cpp | 77 + .../signal/full/It_ipc_sigprocmask_001.cpp | 75 + .../extended/signal/full/pipe_test_001.cpp | 97 + .../extended/signal/full/pipe_test_003.cpp | 106 + .../extended/signal/full/pipe_test_005.cpp | 101 + .../extended/signal/full/pipe_test_006.cpp | 84 + .../extended/signal/full/signal_test_001.cpp | 189 + .../extended/signal/full/signal_test_003.cpp | 105 + .../extended/signal/full/signal_test_004.cpp | 110 + .../extended/signal/full/signal_test_005.cpp | 57 + .../extended/signal/full/signal_test_006.cpp | 68 + .../extended/signal/full/signal_test_007.cpp | 81 + .../extended/signal/full/signal_test_008.cpp | 86 + .../extended/signal/full/signal_test_010.cpp | 102 + .../extended/signal/full/signal_test_011.cpp | 95 + .../extended/signal/full/signal_test_012.cpp | 80 + .../extended/signal/full/signal_test_015.cpp | 106 + .../extended/signal/full/signal_test_016.cpp | 147 + .../extended/signal/full/signal_test_017.cpp | 154 + .../extended/signal/full/signal_test_018.cpp | 101 + .../extended/signal/full/signal_test_019.cpp | 97 + .../extended/signal/full/signal_test_020.cpp | 221 + .../extended/signal/full/signal_test_025.cpp | 127 + .../extended/signal/full/signal_test_026.cpp | 105 + .../extended/signal/full/signal_test_028.cpp | 168 + .../extended/signal/full/signal_test_029.cpp | 115 + .../extended/signal/full/signal_test_030.cpp | 80 + .../extended/signal/full/signal_test_033.cpp | 118 + .../extended/signal/full/signal_test_038.cpp | 75 + .../extended/signal/full/signal_test_040.cpp | 95 + .../extended/signal/full/signal_test_041.cpp | 223 + .../unittest/extended/signal/it_test_signal.h | 109 + .../unittest/extended/signal/signal_test.cpp | 608 + .../signal/smoke/It_ipc_fdisset_001.cpp | 64 + .../signal/smoke/It_ipc_mkfifo_002.cpp | 95 + .../signal/smoke/It_ipc_mkfifo_003.cpp | 95 + .../extended/signal/smoke/It_ipc_pipe_004.cpp | 92 + .../extended/signal/smoke/It_ipc_pipe_005.cpp | 54 + .../extended/signal/smoke/mkfifo_test_001.cpp | 81 + .../extended/signal/smoke/mkfifo_test_002.cpp | 74 + .../extended/signal/smoke/pipe_test_002.cpp | 110 + .../extended/signal/smoke/pipe_test_004.cpp | 52 + .../extended/signal/smoke/signal_test_002.cpp | 84 + .../extended/signal/smoke/signal_test_009.cpp | 127 + .../extended/signal/smoke/signal_test_013.cpp | 149 + .../extended/signal/smoke/signal_test_014.cpp | 72 + .../extended/signal/smoke/signal_test_021.cpp | 91 + .../extended/signal/smoke/signal_test_022.cpp | 90 + .../extended/signal/smoke/signal_test_023.cpp | 77 + .../extended/signal/smoke/signal_test_024.cpp | 107 + .../extended/signal/smoke/signal_test_031.cpp | 112 + .../extended/signal/smoke/signal_test_032.cpp | 79 + .../extended/signal/smoke/signal_test_035.cpp | 79 + .../extended/signal/smoke/signal_test_036.cpp | 73 + .../extended/signal/smoke/signal_test_037.cpp | 72 + .../extended/signal/smoke/signal_test_039.cpp | 69 + .../extended/signal/smoke/signal_test_042.cpp | 104 + .../extended/signal/smoke/sigset_test_001.cpp | 86 + .../extended/signal/smoke/sigset_test_002.cpp | 75 + .../unittest/extended/trace/It_test_trace.h | 59 + .../unittest/extended/trace/config.gni | 43 + .../extended/trace/smoke/trace_test_001.cpp | 51 + .../extended/trace/smoke/trace_test_002.cpp | 58 + .../extended/trace/smoke/trace_test_003.cpp | 61 + .../extended/trace/smoke/trace_test_004.cpp | 66 + .../extended/trace/trace_unit_test.cpp | 86 + .../testsuites/unittest/fs/BUILD.gn | 77 + .../testsuites/unittest/fs/config.gni | 44 + .../testsuites/unittest/fuzz/BUILD.gn | 88 + .../unittest/fuzz/adjtime_fuzzer.cpp | 48 + .../unittest/fuzz/chroot_fuzzer.cpp | 46 + .../testsuites/unittest/fuzz/clone_fuzzer.cpp | 58 + .../unittest/fuzz/epoll_create_fuzzer.cpp | 46 + .../unittest/fuzz/epoll_ctl_fuzzer.cpp | 51 + .../unittest/fuzz/epoll_wait_fuzzer.cpp | 51 + .../unittest/fuzz/fesetenv_fuzzer.cpp | 47 + .../testsuites/unittest/fuzz/fuzzertest.h | 25 + .../unittest/fuzz/getrlimit_fuzzer.cpp | 48 + .../testsuites/unittest/fuzz/main.cpp | 92 + .../testsuites/unittest/fuzz/mlock_fuzzer.cpp | 48 + .../unittest/fuzz/mlockall_fuzzer.cpp | 46 + ..._spawn_file_actions_addchdir_np_fuzzer.cpp | 55 + ...osix_spawn_file_actions_adddup2_fuzzer.cpp | 56 + ...spawn_file_actions_addfchdir_np_fuzzer.cpp | 55 + ...osix_spawn_file_actions_addopen_fuzzer.cpp | 58 + ...osix_spawn_file_actions_destroy_fuzzer.cpp | 55 + .../posix_spawn_file_actions_init_fuzzer.cpp | 54 + .../unittest/fuzz/posix_spawn_fuzzer.cpp | 48 + .../fuzz/posix_spawnattr_destroy_fuzzer.cpp | 48 + .../fuzz/posix_spawnattr_getflags_fuzzer.cpp | 49 + .../fuzz/posix_spawnattr_getpgroup_fuzzer.cpp | 49 + .../posix_spawnattr_getschedparam_fuzzer.cpp | 51 + .../posix_spawnattr_getschedpolicy_fuzzer.cpp | 49 + .../posix_spawnattr_getsigdefault_fuzzer.cpp | 50 + .../posix_spawnattr_getsigmask_fuzzer.cpp | 50 + .../fuzz/posix_spawnattr_init_fuzzer.cpp | 48 + .../fuzz/posix_spawnattr_setflags_fuzzer.cpp | 49 + .../fuzz/posix_spawnattr_setpgroup_fuzzer.cpp | 48 + .../posix_spawnattr_setschedparam_fuzzer.cpp | 52 + .../posix_spawnattr_setschedpolicy_fuzzer.cpp | 50 + .../posix_spawnattr_setsigdefault_fuzzer.cpp | 50 + .../posix_spawnattr_setsigmask_fuzzer.cpp | 50 + .../unittest/fuzz/posix_spawnp_fuzzer.cpp | 48 + .../fuzz/pthread_mutex_consistent_fuzzer.cpp | 48 + .../pthread_mutex_getprioceiling_fuzzer.cpp | 52 + .../pthread_mutexattr_setprotocol_fuzzer.cpp | 49 + .../pthread_mutexattr_setrobust_fuzzer.cpp | 49 + .../fuzz/pthread_mutexattr_settype_fuzzer.cpp | 49 + .../fuzz/pthread_setconcurrency_fuzzer.cpp | 46 + .../unittest/fuzz/readlink_fuzzer.cpp | 48 + .../unittest/fuzz/readlinkat_fuzzer.cpp | 50 + .../unittest/fuzz/sem_open_fuzzer.cpp | 48 + .../unittest/fuzz/sethostname_fuzzer.cpp | 47 + .../testsuites/unittest/fuzz/setns_fuzzer.cpp | 47 + .../unittest/fuzz/syslog_fuzzer.cpp | 47 + .../unittest/fuzz/system_fuzzer.cpp | 46 + .../testsuites/unittest/fuzz/times_fuzzer.cpp | 48 + .../unittest/fuzz/unshare_fuzzer.cpp | 46 + .../testsuites/unittest/libc/io/BUILD.gn | 66 + .../testsuites/unittest/libc/io/It_test_IO.h | 143 + .../testsuites/unittest/libc/io/config.gni | 105 + .../libc/io/full/IO_test_confstr_001.cpp | 83 + .../libc/io/full/IO_test_dcgettext_001.cpp | 75 + .../libc/io/full/IO_test_dcgettext_002.cpp | 138 + .../libc/io/full/IO_test_dcngettext_001.cpp | 61 + .../libc/io/full/IO_test_dcngettext_002.cpp | 103 + .../libc/io/full/IO_test_dngettext_001.cpp | 62 + .../libc/io/full/IO_test_dngettext_002.cpp | 132 + .../libc/io/full/IO_test_duplocale_001.cpp | 154 + .../libc/io/full/IO_test_epoll_001.cpp | 119 + .../libc/io/full/IO_test_epoll_002.cpp | 141 + .../libc/io/full/IO_test_gettext_001.cpp | 76 + .../libc/io/full/IO_test_locale_001.cpp | 69 + .../libc/io/full/IO_test_locale_002.cpp | 69 + .../libc/io/full/IO_test_ngettext_001.cpp | 57 + .../libc/io/full/IO_test_nl_langinfo_001.cpp | 101 + .../io/full/IO_test_nl_langinfo_l_001.cpp | 69 + .../libc/io/full/IO_test_ppoll_001.cpp | 120 + .../libc/io/full/IO_test_ppoll_002.cpp | 116 + .../libc/io/full/IO_test_ppoll_003.cpp | 152 + .../libc/io/full/IO_test_pselect_001.cpp | 123 + .../libc/io/full/IO_test_pselect_002.cpp | 124 + .../libc/io/full/IO_test_strcasecmp_l_001.cpp | 53 + .../libc/io/full/IO_test_strcasecmp_l_002.cpp | 81 + .../libc/io/full/IO_test_strfmon_l_001.cpp | 56 + .../libc/io/full/IO_test_strfmon_l_002.cpp | 89 + .../io/full/IO_test_strncasecmp_l_001.cpp | 54 + .../io/full/IO_test_strncasecmp_l_002.cpp | 140 + .../libc/io/full/It_locale_localeconv_001.cpp | 45 + .../libc/io/full/It_stdio_fputws_001.cpp | 87 + .../libc/io/full/It_stdio_fwprintf_001.cpp | 87 + .../io/full/It_stdio_getc_unlocked_001.cpp | 81 + .../libc/io/full/It_stdio_hasmntopt_001.cpp | 111 + .../libc/io/full/It_stdio_mblen_001.cpp | 62 + .../libc/io/full/It_stdio_mbrlen_001.cpp | 64 + .../libc/io/full/It_stdio_putwc_001.cpp | 87 + .../libc/io/full/It_stdio_readv_001.cpp | 85 + .../libc/io/full/It_stdio_rindex_001.cpp | 51 + .../libc/io/full/It_stdio_setlogmask_001.cpp | 48 + .../libc/io/full/It_stdlib_gcvt_001.cpp | 52 + .../libc/io/full/It_stdlib_poll_002.cpp | 117 + .../libc/io/full/It_stdlib_poll_003.cpp | 86 + .../testsuites/unittest/libc/io/io_test.cpp | 493 + .../unittest/libc/io/smoke/IO_test_005.cpp | 63 + .../unittest/libc/io/smoke/IO_test_008.cpp | 85 + .../unittest/libc/io/smoke/IO_test_010.cpp | 61 + .../unittest/libc/io/smoke/IO_test_013.cpp | 52 + .../testsuites/unittest/libc/misc/BUILD.gn | 66 + .../unittest/libc/misc/It_test_misc.h | 58 + .../testsuites/unittest/libc/misc/config.gni | 74 + .../unittest/libc/misc/full/misc_test_006.cpp | 67 + .../unittest/libc/misc/full/misc_test_007.cpp | 52 + .../unittest/libc/misc/full/misc_test_008.cpp | 49 + .../unittest/libc/misc/full/misc_test_009.cpp | 61 + .../unittest/libc/misc/full/misc_test_010.cpp | 47 + .../unittest/libc/misc/full/misc_test_011.cpp | 53 + .../unittest/libc/misc/full/misc_test_012.cpp | 72 + .../unittest/libc/misc/full/misc_test_013.cpp | 59 + .../unittest/libc/misc/misc_test.cpp | 159 + .../libc/misc/smoke/misc_test_001.cpp | 52 + .../libc/misc/smoke/misc_test_002.cpp | 55 + .../libc/misc/smoke/misc_test_003.cpp | 55 + .../libc/misc/smoke/misc_test_004.cpp | 61 + .../libc/misc/smoke/misc_test_005.cpp | 61 + .../libc/misc/smoke/misc_test_014.cpp | 60 + .../testsuites/unittest/libc/posix/BUILD.gn | 66 + .../testsuites/unittest/libc/posix/config.gni | 69 + .../unittest/libc/posix/mem/It_posix_mem.h | 42 + .../unittest/libc/posix/mem/config.gni | 42 + .../libc/posix/mem/posix_mem_test.cpp | 68 + .../libc/posix/mem/smoke/It_posix_mem_001.cpp | 74 + .../libc/posix/mem/smoke/It_posix_mem_003.cpp | 68 + .../libc/posix/mqueue/It_posix_queue.h | 278 + .../unittest/libc/posix/mqueue/config.gni | 191 + .../posix/mqueue/full/It_posix_queue_002.cpp | 78 + .../posix/mqueue/full/It_posix_queue_005.cpp | 58 + .../posix/mqueue/full/It_posix_queue_008.cpp | 72 + .../posix/mqueue/full/It_posix_queue_011.cpp | 90 + .../posix/mqueue/full/It_posix_queue_013.cpp | 79 + .../posix/mqueue/full/It_posix_queue_014.cpp | 72 + .../posix/mqueue/full/It_posix_queue_015.cpp | 77 + .../posix/mqueue/full/It_posix_queue_016.cpp | 69 + .../posix/mqueue/full/It_posix_queue_018.cpp | 68 + .../posix/mqueue/full/It_posix_queue_019.cpp | 88 + .../posix/mqueue/full/It_posix_queue_020.cpp | 66 + .../posix/mqueue/full/It_posix_queue_021.cpp | 58 + .../posix/mqueue/full/It_posix_queue_025.cpp | 66 + .../posix/mqueue/full/It_posix_queue_026.cpp | 58 + .../posix/mqueue/full/It_posix_queue_027.cpp | 64 + .../posix/mqueue/full/It_posix_queue_030.cpp | 49 + .../posix/mqueue/full/It_posix_queue_031.cpp | 81 + .../posix/mqueue/full/It_posix_queue_032.cpp | 65 + .../posix/mqueue/full/It_posix_queue_033.cpp | 78 + .../posix/mqueue/full/It_posix_queue_036.cpp | 72 + .../posix/mqueue/full/It_posix_queue_038.cpp | 69 + .../posix/mqueue/full/It_posix_queue_040.cpp | 145 + .../posix/mqueue/full/It_posix_queue_041.cpp | 148 + .../posix/mqueue/full/It_posix_queue_042.cpp | 92 + .../posix/mqueue/full/It_posix_queue_043.cpp | 100 + .../posix/mqueue/full/It_posix_queue_044.cpp | 80 + .../posix/mqueue/full/It_posix_queue_046.cpp | 69 + .../posix/mqueue/full/It_posix_queue_047.cpp | 78 + .../posix/mqueue/full/It_posix_queue_048.cpp | 79 + .../posix/mqueue/full/It_posix_queue_049.cpp | 72 + .../posix/mqueue/full/It_posix_queue_050.cpp | 77 + .../posix/mqueue/full/It_posix_queue_052.cpp | 77 + .../posix/mqueue/full/It_posix_queue_054.cpp | 72 + .../posix/mqueue/full/It_posix_queue_055.cpp | 92 + .../posix/mqueue/full/It_posix_queue_056.cpp | 75 + .../posix/mqueue/full/It_posix_queue_057.cpp | 73 + .../posix/mqueue/full/It_posix_queue_058.cpp | 71 + .../posix/mqueue/full/It_posix_queue_060.cpp | 56 + .../posix/mqueue/full/It_posix_queue_061.cpp | 76 + .../posix/mqueue/full/It_posix_queue_063.cpp | 80 + .../posix/mqueue/full/It_posix_queue_064.cpp | 80 + .../posix/mqueue/full/It_posix_queue_065.cpp | 73 + .../posix/mqueue/full/It_posix_queue_066.cpp | 87 + .../posix/mqueue/full/It_posix_queue_067.cpp | 87 + .../posix/mqueue/full/It_posix_queue_069.cpp | 87 + .../posix/mqueue/full/It_posix_queue_070.cpp | 97 + .../posix/mqueue/full/It_posix_queue_071.cpp | 77 + .../posix/mqueue/full/It_posix_queue_072.cpp | 78 + .../posix/mqueue/full/It_posix_queue_073.cpp | 91 + .../posix/mqueue/full/It_posix_queue_074.cpp | 68 + .../posix/mqueue/full/It_posix_queue_075.cpp | 121 + .../posix/mqueue/full/It_posix_queue_076.cpp | 149 + .../posix/mqueue/full/It_posix_queue_077.cpp | 115 + .../posix/mqueue/full/It_posix_queue_078.cpp | 119 + .../posix/mqueue/full/It_posix_queue_079.cpp | 143 + .../posix/mqueue/full/It_posix_queue_080.cpp | 90 + .../posix/mqueue/full/It_posix_queue_081.cpp | 80 + .../posix/mqueue/full/It_posix_queue_082.cpp | 79 + .../posix/mqueue/full/It_posix_queue_083.cpp | 82 + .../posix/mqueue/full/It_posix_queue_084.cpp | 70 + .../posix/mqueue/full/It_posix_queue_085.cpp | 71 + .../posix/mqueue/full/It_posix_queue_086.cpp | 71 + .../posix/mqueue/full/It_posix_queue_087.cpp | 74 + .../posix/mqueue/full/It_posix_queue_088.cpp | 79 + .../posix/mqueue/full/It_posix_queue_089.cpp | 70 + .../posix/mqueue/full/It_posix_queue_090.cpp | 93 + .../posix/mqueue/full/It_posix_queue_091.cpp | 71 + .../posix/mqueue/full/It_posix_queue_093.cpp | 82 + .../posix/mqueue/full/It_posix_queue_094.cpp | 73 + .../posix/mqueue/full/It_posix_queue_095.cpp | 95 + .../posix/mqueue/full/It_posix_queue_096.cpp | 82 + .../posix/mqueue/full/It_posix_queue_097.cpp | 145 + .../posix/mqueue/full/It_posix_queue_098.cpp | 63 + .../posix/mqueue/full/It_posix_queue_100.cpp | 76 + .../posix/mqueue/full/It_posix_queue_101.cpp | 85 + .../posix/mqueue/full/It_posix_queue_102.cpp | 80 + .../posix/mqueue/full/It_posix_queue_103.cpp | 80 + .../posix/mqueue/full/It_posix_queue_104.cpp | 95 + .../posix/mqueue/full/It_posix_queue_106.cpp | 76 + .../posix/mqueue/full/It_posix_queue_108.cpp | 73 + .../posix/mqueue/full/It_posix_queue_109.cpp | 75 + .../posix/mqueue/full/It_posix_queue_110.cpp | 75 + .../posix/mqueue/full/It_posix_queue_111.cpp | 145 + .../posix/mqueue/full/It_posix_queue_112.cpp | 114 + .../posix/mqueue/full/It_posix_queue_113.cpp | 125 + .../posix/mqueue/full/It_posix_queue_114.cpp | 126 + .../posix/mqueue/full/It_posix_queue_115.cpp | 125 + .../posix/mqueue/full/It_posix_queue_116.cpp | 119 + .../posix/mqueue/full/It_posix_queue_117.cpp | 121 + .../posix/mqueue/full/It_posix_queue_118.cpp | 166 + .../posix/mqueue/full/It_posix_queue_119.cpp | 165 + .../posix/mqueue/full/It_posix_queue_120.cpp | 160 + .../posix/mqueue/full/It_posix_queue_121.cpp | 259 + .../posix/mqueue/full/It_posix_queue_122.cpp | 113 + .../posix/mqueue/full/It_posix_queue_123.cpp | 105 + .../posix/mqueue/full/It_posix_queue_124.cpp | 150 + .../posix/mqueue/full/It_posix_queue_125.cpp | 157 + .../posix/mqueue/full/It_posix_queue_126.cpp | 154 + .../posix/mqueue/full/It_posix_queue_127.cpp | 74 + .../posix/mqueue/full/It_posix_queue_128.cpp | 72 + .../posix/mqueue/full/It_posix_queue_129.cpp | 80 + .../posix/mqueue/full/It_posix_queue_130.cpp | 70 + .../posix/mqueue/full/It_posix_queue_133.cpp | 158 + .../posix/mqueue/full/It_posix_queue_134.cpp | 67 + .../posix/mqueue/full/It_posix_queue_136.cpp | 70 + .../posix/mqueue/full/It_posix_queue_143.cpp | 113 + .../posix/mqueue/full/It_posix_queue_144.cpp | 157 + .../posix/mqueue/full/It_posix_queue_145.cpp | 207 + .../posix/mqueue/full/It_posix_queue_146.cpp | 160 + .../posix/mqueue/full/It_posix_queue_147.cpp | 77 + .../posix/mqueue/full/It_posix_queue_148.cpp | 69 + .../posix/mqueue/full/It_posix_queue_149.cpp | 77 + .../posix/mqueue/full/It_posix_queue_150.cpp | 78 + .../posix/mqueue/full/It_posix_queue_151.cpp | 74 + .../posix/mqueue/full/It_posix_queue_152.cpp | 77 + .../posix/mqueue/full/It_posix_queue_153.cpp | 77 + .../posix/mqueue/full/It_posix_queue_154.cpp | 77 + .../posix/mqueue/full/It_posix_queue_155.cpp | 83 + .../posix/mqueue/full/It_posix_queue_156.cpp | 92 + .../posix/mqueue/full/It_posix_queue_157.cpp | 89 + .../posix/mqueue/full/It_posix_queue_159.cpp | 94 + .../posix/mqueue/full/It_posix_queue_160.cpp | 173 + .../posix/mqueue/full/It_posix_queue_161.cpp | 194 + .../posix/mqueue/full/It_posix_queue_162.cpp | 144 + .../posix/mqueue/full/It_posix_queue_163.cpp | 87 + .../posix/mqueue/full/It_posix_queue_164.cpp | 87 + .../posix/mqueue/full/It_posix_queue_165.cpp | 78 + .../posix/mqueue/full/It_posix_queue_166.cpp | 94 + .../posix/mqueue/full/It_posix_queue_168.cpp | 96 + .../posix/mqueue/full/It_posix_queue_169.cpp | 92 + .../posix/mqueue/full/It_posix_queue_173.cpp | 81 + .../posix/mqueue/full/It_posix_queue_175.cpp | 97 + .../posix/mqueue/full/It_posix_queue_176.cpp | 87 + .../posix/mqueue/full/It_posix_queue_177.cpp | 84 + .../posix/mqueue/full/It_posix_queue_187.cpp | 73 + .../posix/mqueue/full/It_posix_queue_200.cpp | 80 + .../posix/mqueue/full/It_posix_queue_201.cpp | 83 + .../posix/mqueue/full/It_posix_queue_202.cpp | 78 + .../posix/mqueue/full/It_posix_queue_203.cpp | 71 + .../posix/mqueue/full/It_posix_queue_204.cpp | 105 + .../posix/mqueue/full/It_posix_queue_205.cpp | 123 + .../posix/mqueue/full/It_posix_queue_206.cpp | 142 + .../posix/mqueue/full/It_posix_queue_207.cpp | 121 + .../posix/mqueue/full/It_posix_queue_208.cpp | 147 + .../posix/mqueue/full/It_posix_queue_209.cpp | 156 + .../libc/posix/mqueue/posix_mqueue_test.cpp | 1299 ++ .../posix/mqueue/smoke/It_posix_queue_001.cpp | 69 + .../posix/mqueue/smoke/It_posix_queue_003.cpp | 79 + .../posix/mqueue/smoke/It_posix_queue_028.cpp | 87 + .../posix/mqueue/smoke/It_posix_queue_053.cpp | 143 + .../posix/mqueue/smoke/It_posix_queue_062.cpp | 84 + .../libc/posix/pthread/It_posix_pthread.h | 441 + .../unittest/libc/posix/pthread/config.gni | 156 + .../pthread/full/It_posix_pthread_001.cpp | 94 + .../pthread/full/It_posix_pthread_002.cpp | 49 + .../pthread/full/It_posix_pthread_007.cpp | 108 + .../pthread/full/It_posix_pthread_010.cpp | 78 + .../pthread/full/It_posix_pthread_011.cpp | 64 + .../pthread/full/It_posix_pthread_013.cpp | 63 + .../pthread/full/It_posix_pthread_023.cpp | 79 + .../pthread/full/It_posix_pthread_025.cpp | 76 + .../pthread/full/It_posix_pthread_026.cpp | 81 + .../pthread/full/It_posix_pthread_027.cpp | 82 + .../pthread/full/It_posix_pthread_028.cpp | 64 + .../pthread/full/It_posix_pthread_029.cpp | 64 + .../pthread/full/It_posix_pthread_030.cpp | 70 + .../pthread/full/It_posix_pthread_031.cpp | 67 + .../pthread/full/It_posix_pthread_034.cpp | 117 + .../pthread/full/It_posix_pthread_035.cpp | 132 + .../pthread/full/It_posix_pthread_039.cpp | 81 + .../pthread/full/It_posix_pthread_040.cpp | 73 + .../pthread/full/It_posix_pthread_042.cpp | 95 + .../pthread/full/It_posix_pthread_044.cpp | 147 + .../pthread/full/It_posix_pthread_045.cpp | 92 + .../pthread/full/It_posix_pthread_046.cpp | 80 + .../pthread/full/It_posix_pthread_051.cpp | 89 + .../pthread/full/It_posix_pthread_052.cpp | 159 + .../pthread/full/It_posix_pthread_053.cpp | 184 + .../pthread/full/It_posix_pthread_054.cpp | 91 + .../pthread/full/It_posix_pthread_055.cpp | 95 + .../pthread/full/It_posix_pthread_057.cpp | 134 + .../pthread/full/It_posix_pthread_059.cpp | 74 + .../pthread/full/It_posix_pthread_060.cpp | 91 + .../pthread/full/It_posix_pthread_061.cpp | 82 + .../pthread/full/It_posix_pthread_062.cpp | 84 + .../pthread/full/It_posix_pthread_063.cpp | 83 + .../pthread/full/It_posix_pthread_064.cpp | 93 + .../pthread/full/It_posix_pthread_066.cpp | 128 + .../pthread/full/It_posix_pthread_069.cpp | 60 + .../pthread/full/It_posix_pthread_070.cpp | 55 + .../pthread/full/It_posix_pthread_071.cpp | 74 + .../pthread/full/It_posix_pthread_072.cpp | 94 + .../pthread/full/It_posix_pthread_073.cpp | 64 + .../pthread/full/It_posix_pthread_074.cpp | 56 + .../pthread/full/It_posix_pthread_078.cpp | 56 + .../pthread/full/It_posix_pthread_079.cpp | 58 + .../pthread/full/It_posix_pthread_080.cpp | 108 + .../pthread/full/It_posix_pthread_081.cpp | 112 + .../pthread/full/It_posix_pthread_082.cpp | 123 + .../pthread/full/It_posix_pthread_083.cpp | 124 + .../pthread/full/It_posix_pthread_084.cpp | 123 + .../pthread/full/It_posix_pthread_085.cpp | 102 + .../pthread/full/It_posix_pthread_087.cpp | 106 + .../pthread/full/It_posix_pthread_088.cpp | 183 + .../pthread/full/It_posix_pthread_089.cpp | 191 + .../pthread/full/It_posix_pthread_090.cpp | 119 + .../pthread/full/It_posix_pthread_091.cpp | 116 + .../pthread/full/It_posix_pthread_092.cpp | 150 + .../pthread/full/It_posix_pthread_094.cpp | 127 + .../pthread/full/It_posix_pthread_095.cpp | 126 + .../pthread/full/It_posix_pthread_106.cpp | 75 + .../pthread/full/It_posix_pthread_107.cpp | 125 + .../pthread/full/It_posix_pthread_116.cpp | 125 + .../pthread/full/It_posix_pthread_123.cpp | 69 + .../pthread/full/It_posix_pthread_124.cpp | 71 + .../pthread/full/It_posix_pthread_125.cpp | 74 + .../pthread/full/It_posix_pthread_127.cpp | 159 + .../pthread/full/It_posix_pthread_129.cpp | 62 + .../pthread/full/It_posix_pthread_132.cpp | 69 + .../pthread/full/It_posix_pthread_133.cpp | 62 + .../pthread/full/It_posix_pthread_134.cpp | 67 + .../pthread/full/It_posix_pthread_136.cpp | 72 + .../pthread/full/It_posix_pthread_138.cpp | 75 + .../pthread/full/It_posix_pthread_141.cpp | 59 + .../pthread/full/It_posix_pthread_142.cpp | 58 + .../pthread/full/It_posix_pthread_144.cpp | 82 + .../pthread/full/It_posix_pthread_152.cpp | 59 + .../pthread/full/It_posix_pthread_154.cpp | 66 + .../pthread/full/It_posix_pthread_166.cpp | 68 + .../pthread/full/It_posix_pthread_167.cpp | 57 + .../pthread/full/It_posix_pthread_173.cpp | 58 + .../pthread/full/It_posix_pthread_175.cpp | 76 + .../pthread/full/It_posix_pthread_176.cpp | 56 + .../pthread/full/It_posix_pthread_177.cpp | 73 + .../pthread/full/It_posix_pthread_182.cpp | 95 + .../pthread/full/It_posix_pthread_185.cpp | 68 + .../pthread/full/It_posix_pthread_186.cpp | 97 + .../pthread/full/It_posix_pthread_187.cpp | 96 + .../pthread/full/It_posix_pthread_188.cpp | 102 + .../pthread/full/It_posix_pthread_193.cpp | 98 + .../pthread/full/It_posix_pthread_194.cpp | 86 + .../pthread/full/It_posix_pthread_200.cpp | 78 + .../pthread/full/It_posix_pthread_203.cpp | 55 + .../pthread/full/It_posix_pthread_204.cpp | 82 + .../pthread/full/It_posix_pthread_205.cpp | 113 + .../pthread/full/It_posix_pthread_206.cpp | 97 + .../pthread/full/It_posix_pthread_209.cpp | 95 + .../pthread/full/It_posix_pthread_213.cpp | 95 + .../pthread/full/It_posix_pthread_217.cpp | 61 + .../pthread/full/It_posix_pthread_218.cpp | 80 + .../pthread/full/It_posix_pthread_219.cpp | 58 + .../pthread/full/It_posix_pthread_221.cpp | 55 + .../pthread/full/It_posix_pthread_224.cpp | 82 + .../pthread/full/It_posix_pthread_226.cpp | 89 + .../pthread/full/It_posix_pthread_233.cpp | 94 + .../pthread/full/It_posix_pthread_238.cpp | 90 + .../pthread/full/It_posix_pthread_239.cpp | 86 + .../pthread/full/It_posix_pthread_240.cpp | 87 + .../pthread/full/It_posix_pthread_241.cpp | 69 + .../libc/posix/pthread/posix_pthread_test.cpp | 1317 ++ .../pthread/smoke/It_posix_pthread_003.cpp | 71 + .../pthread/smoke/It_posix_pthread_004.cpp | 71 + .../pthread/smoke/It_posix_pthread_005.cpp | 69 + .../pthread/smoke/It_posix_pthread_006.cpp | 71 + .../pthread/smoke/It_posix_pthread_018.cpp | 94 + .../pthread/smoke/It_posix_pthread_019.cpp | 69 + .../pthread/smoke/It_posix_pthread_020.cpp | 65 + .../pthread/smoke/It_posix_pthread_021.cpp | 73 + .../pthread/smoke/It_posix_pthread_022.cpp | 98 + .../testsuites/unittest/libc/sys/BUILD.gn | 66 + .../unittest/libc/sys/It_test_sys.h | 87 + .../testsuites/unittest/libc/sys/config.gni | 88 + .../unittest/libc/sys/full/sys_test_001.cpp | 76 + .../unittest/libc/sys/full/sys_test_018.cpp | 98 + .../unittest/libc/sys/full/sys_test_019.cpp | 115 + .../unittest/libc/sys/full/sys_test_020.cpp | 100 + .../unittest/libc/sys/full/sys_test_021.cpp | 123 + .../unittest/libc/sys/full/sys_test_022.cpp | 96 + .../unittest/libc/sys/full/sys_test_023.cpp | 88 + .../unittest/libc/sys/full/sys_test_024.cpp | 73 + .../unittest/libc/sys/full/sys_test_025.cpp | 139 + .../unittest/libc/sys/full/sys_test_026.cpp | 59 + .../unittest/libc/sys/full/sys_test_027.cpp | 70 + .../unittest/libc/sys/full/sys_test_028.cpp | 60 + .../unittest/libc/sys/smoke/sys_test_004.cpp | 54 + .../unittest/libc/sys/smoke/sys_test_005.cpp | 53 + .../unittest/libc/sys/smoke/sys_test_006.cpp | 57 + .../unittest/libc/sys/smoke/sys_test_007.cpp | 56 + .../unittest/libc/sys/smoke/sys_test_008.cpp | 74 + .../unittest/libc/sys/smoke/sys_test_009.cpp | 63 + .../unittest/libc/sys/smoke/sys_test_010.cpp | 51 + .../unittest/libc/sys/smoke/sys_test_012.cpp | 67 + .../unittest/libc/sys/smoke/sys_test_013.cpp | 86 + .../unittest/libc/sys/smoke/sys_test_014.cpp | 92 + .../unittest/libc/sys/smoke/sys_test_015.cpp | 55 + .../unittest/libc/sys/smoke/sys_test_016.cpp | 66 + .../unittest/libc/sys/smoke/sys_test_017.cpp | 76 + .../unittest/libc/sys/smoke/sys_test_029.cpp | 58 + .../unittest/libc/sys/smoke/sys_test_030.cpp | 51 + .../unittest/libc/sys/smoke/sys_test_031.cpp | 50 + .../unittest/libc/sys/sys_unit_test.cpp | 332 + .../testsuites/unittest/libc/time/BUILD.gn | 66 + .../unittest/libc/time/clock/config.gni | 51 + .../libc/time/clock/full/clock_test_001.cpp | 87 + .../libc/time/clock/full/clock_test_002.cpp | 93 + .../libc/time/clock/full/clock_test_003.cpp | 80 + .../libc/time/clock/full/clock_test_004.cpp | 51 + .../libc/time/clock/full/clock_test_005.cpp | 54 + .../libc/time/clock/full/clock_test_006.cpp | 84 + .../libc/time/clock/full/clock_test_007.cpp | 83 + .../libc/time/clock/full/clock_test_008.cpp | 84 + .../libc/time/clock/full/clock_test_009.cpp | 84 + .../libc/time/clock/full/clock_test_010.cpp | 115 + .../unittest/libc/time/clock/lt_clock_test.h | 58 + .../time/clock/smoke/clock_test_smoke.cpp | 69 + .../libc/time/clock/time_clock_test.cpp | 159 + .../testsuites/unittest/libc/time/config.gni | 60 + .../unittest/libc/time/timer/config.gni | 47 + .../unittest/libc/time/timer/lt_timer_test.h | 48 + .../libc/time/timer/smoke/timer_test_001.cpp | 160 + .../libc/time/timer/smoke/timer_test_002.cpp | 91 + .../libc/time/timer/smoke/timer_test_003.cpp | 118 + .../libc/time/timer/smoke/timer_test_004.cpp | 141 + .../libc/time/timer/smoke/timer_test_005.cpp | 124 + .../time/timer/smoke/timer_test_tzset_001.cpp | 64 + .../time/timer/smoke/timer_test_tzset_002.cpp | 64 + .../libc/time/timer/time_timer_test.cpp | 86 + .../testsuites/unittest/libc/util/BUILD.gn | 66 + .../unittest/libc/util/It_test_util.h | 53 + .../testsuites/unittest/libc/util/config.gni | 71 + .../libc/util/smoke/it_test_util_100.cpp | 51 + .../libc/util/smoke/it_test_util_101.cpp | 51 + .../libc/util/smoke/util_test_001.cpp | 74 + .../libc/util/smoke/util_test_002.cpp | 74 + .../libc/util/smoke/util_test_003.cpp | 106 + .../libc/util/smoke/util_test_004.cpp | 54 + .../libc/util/smoke/util_test_005.cpp | 55 + .../libc/util/smoke/util_test_006.cpp | 80 + .../libc/util/smoke/util_test_007.cpp | 108 + .../unittest/libc/util/util_test.cpp | 126 + .../testsuites/unittest/net/BUILD.gn | 72 + .../testsuites/unittest/net/config.gni | 69 + .../testsuites/unittest/net/netdb/config.gni | 60 + .../net/netdb/full/net_netdb_test_002.cpp | 71 + .../net/netdb/full/net_netdb_test_003.cpp | 51 + .../net/netdb/full/net_netdb_test_004.cpp | 75 + .../net/netdb/full/net_netdb_test_005.cpp | 68 + .../net/netdb/full/net_netdb_test_006.cpp | 69 + .../net/netdb/full/net_netdb_test_007.cpp | 81 + .../net/netdb/full/net_netdb_test_008.cpp | 72 + .../net/netdb/full/net_netdb_test_009.cpp | 80 + .../net/netdb/full/net_netdb_test_010.cpp | 51 + .../net/netdb/full/net_netdb_test_011.cpp | 67 + .../net/netdb/full/net_netdb_test_012.cpp | 80 + .../net/netdb/full/net_netdb_test_015.cpp | 57 + .../net/netdb/full/net_netdb_test_016.cpp | 80 + .../net/netdb/full/net_netdb_test_017.cpp | 79 + .../net/netdb/full/net_netdb_test_018.cpp | 113 + .../net/netdb/full/net_netdb_test_019.cpp | 105 + .../net/netdb/full/net_netdb_test_020.cpp | 94 + .../net/netdb/full/net_netdb_test_021.cpp | 70 + .../net/netdb/full/net_netdb_test_022.cpp | 70 + .../unittest/net/netdb/lt_net_netdb.h | 64 + .../unittest/net/netdb/net_netdb_test.cpp | 257 + .../net/netdb/smoke/net_netdb_test_001.cpp | 58 + .../net/netdb/smoke/net_netdb_test_013.cpp | 48 + .../testsuites/unittest/net/resolv/config.gni | 47 + .../net/resolv/full/net_resolv_test_004.cpp | 66 + .../net/resolv/full/net_resolv_test_005.cpp | 61 + .../net/resolv/full/net_resolv_test_008.cpp | 63 + .../unittest/net/resolv/lt_net_resolv.h | 51 + .../unittest/net/resolv/net_resolv_test.cpp | 107 + .../net/resolv/smoke/net_resolv_test_001.cpp | 90 + .../net/resolv/smoke/net_resolv_test_002.cpp | 67 + .../net/resolv/smoke/net_resolv_test_003.cpp | 68 + .../net/resolv/smoke/net_resolv_test_006.cpp | 62 + .../net/resolv/smoke/net_resolv_test_007.cpp | 62 + .../testsuites/unittest/net/socket/config.gni | 51 + .../unittest/net/socket/lt_net_socket.h | 52 + .../unittest/net/socket/net_socket_test.cpp | 180 + .../net/socket/smoke/net_socket_test_001.cpp | 45 + .../net/socket/smoke/net_socket_test_002.cpp | 131 + .../net/socket/smoke/net_socket_test_003.cpp | 323 + .../net/socket/smoke/net_socket_test_004.cpp | 89 + .../net/socket/smoke/net_socket_test_005.cpp | 69 + .../net/socket/smoke/net_socket_test_006.cpp | 87 + .../net/socket/smoke/net_socket_test_007.cpp | 170 + .../net/socket/smoke/net_socket_test_008.cpp | 282 + .../net/socket/smoke/net_socket_test_009.cpp | 278 + .../net/socket/smoke/net_socket_test_010.cpp | 192 + .../net/socket/smoke/net_socket_test_011.cpp | 262 + .../net/socket/smoke/net_socket_test_012.cpp | 451 + .../net/socket/smoke/net_socket_test_013.cpp | 336 + .../unittest/process/basic/process/BUILD.gn | 56 + .../unittest/process/basic/process/config.gni | 136 + .../basic/process/full/process_test_007.cpp | 96 + .../basic/process/full/process_test_031.cpp | 107 + .../basic/process/full/process_test_032.cpp | 105 + .../basic/process/full/process_test_033.cpp | 107 + .../basic/process/full/process_test_034.cpp | 102 + .../basic/process/full/process_test_035.cpp | 100 + .../basic/process/full/process_test_036.cpp | 145 + .../basic/process/full/process_test_037.cpp | 143 + .../basic/process/full/process_test_040.cpp | 109 + .../basic/process/full/process_test_041.cpp | 132 + .../basic/process/full/process_test_042.cpp | 182 + .../basic/process/full/process_test_049.cpp | 119 + .../basic/process/full/process_test_050.cpp | 99 + .../basic/process/full/process_test_051.cpp | 109 + .../basic/process/full/process_test_052.cpp | 92 + .../basic/process/full/process_test_053.cpp | 76 + .../basic/process/full/process_test_055.cpp | 102 + .../basic/process/full/process_test_056.cpp | 53 + .../basic/process/full/process_test_057.cpp | 53 + .../basic/process/full/process_test_058.cpp | 234 + .../basic/process/full/process_test_059.cpp | 234 + .../basic/process/full/process_test_060.cpp | 129 + .../basic/process/full/process_test_062.cpp | 111 + .../basic/process/full/process_test_063.cpp | 113 + .../basic/process/full/process_test_064.cpp | 106 + .../basic/process/full/process_test_065.cpp | 127 + .../basic/process/full/process_test_066.cpp | 204 + .../basic/process/full/process_test_067.cpp | 202 + .../basic/process/full/process_test_068.cpp | 74 + .../basic/process/full/process_test_069.cpp | 75 + .../process/basic/process/it_test_process.h | 133 + .../basic/process/process_process_test.cpp | 670 + .../basic/process/smoke/process_test_001.cpp | 158 + .../basic/process/smoke/process_test_002.cpp | 95 + .../basic/process/smoke/process_test_004.cpp | 122 + .../basic/process/smoke/process_test_005.cpp | 168 + .../basic/process/smoke/process_test_006.cpp | 124 + .../basic/process/smoke/process_test_008.cpp | 118 + .../basic/process/smoke/process_test_009.cpp | 109 + .../basic/process/smoke/process_test_010.cpp | 120 + .../basic/process/smoke/process_test_011.cpp | 96 + .../basic/process/smoke/process_test_012.cpp | 127 + .../basic/process/smoke/process_test_013.cpp | 116 + .../basic/process/smoke/process_test_014.cpp | 89 + .../basic/process/smoke/process_test_015.cpp | 112 + .../basic/process/smoke/process_test_016.cpp | 117 + .../basic/process/smoke/process_test_017.cpp | 115 + .../basic/process/smoke/process_test_018.cpp | 124 + .../basic/process/smoke/process_test_019.cpp | 121 + .../basic/process/smoke/process_test_020.cpp | 139 + .../basic/process/smoke/process_test_021.cpp | 182 + .../basic/process/smoke/process_test_022.cpp | 156 + .../basic/process/smoke/process_test_023.cpp | 156 + .../basic/process/smoke/process_test_024.cpp | 152 + .../basic/process/smoke/process_test_025.cpp | 160 + .../basic/process/smoke/process_test_026.cpp | 71 + .../basic/process/smoke/process_test_027.cpp | 85 + .../basic/process/smoke/process_test_029.cpp | 76 + .../basic/process/smoke/process_test_030.cpp | 74 + .../basic/process/smoke/process_test_038.cpp | 143 + .../basic/process/smoke/process_test_039.cpp | 86 + .../basic/process/smoke/process_test_043.cpp | 122 + .../basic/process/smoke/process_test_044.cpp | 102 + .../basic/process/smoke/process_test_045.cpp | 80 + .../basic/process/smoke/process_test_046.cpp | 84 + .../basic/process/smoke/process_test_047.cpp | 73 + .../basic/process/smoke/process_test_048.cpp | 85 + .../basic/process/smoke/process_test_054.cpp | 90 + .../basic/process/smoke/process_test_061.cpp | 59 + .../process/smp/process_test_smp_001.cpp | 72 + .../process/smp/process_test_smp_002.cpp | 125 + .../process/smp/process_test_smp_003.cpp | 94 + .../process/smp/process_test_smp_004.cpp | 51 + .../process/smp/process_test_smp_005.cpp | 108 + .../process/smp/process_test_smp_006.cpp | 108 + .../process/smp/process_test_smp_007.cpp | 111 + .../process/smp/process_test_smp_008.cpp | 130 + .../unittest/process/basic/pthread/BUILD.gn | 56 + .../unittest/process/basic/pthread/config.gni | 96 + .../basic/pthread/full/pthread_test_001.cpp | 279 + .../basic/pthread/full/pthread_test_002.cpp | 216 + .../basic/pthread/full/pthread_test_004.cpp | 391 + .../basic/pthread/full/pthread_test_005.cpp | 94 + .../basic/pthread/full/pthread_test_014.cpp | 161 + .../process/basic/pthread/it_pthread_test.h | 92 + .../basic/pthread/process_pthread_test.cpp | 425 + .../pthread/smoke/pthread_atfork_test_001.cpp | 175 + .../pthread/smoke/pthread_atfork_test_002.cpp | 168 + .../pthread/smoke/pthread_cond_test_001.cpp | 124 + .../pthread/smoke/pthread_cond_test_002.cpp | 119 + .../pthread/smoke/pthread_cond_test_003.cpp | 151 + .../pthread/smoke/pthread_cond_test_004.cpp | 143 + .../pthread/smoke/pthread_once_test_001.cpp | 110 + .../basic/pthread/smoke/pthread_test_003.cpp | 127 + .../basic/pthread/smoke/pthread_test_006.cpp | 150 + .../basic/pthread/smoke/pthread_test_007.cpp | 112 + .../basic/pthread/smoke/pthread_test_008.cpp | 112 + .../basic/pthread/smoke/pthread_test_009.cpp | 62 + .../basic/pthread/smoke/pthread_test_010.cpp | 86 + .../basic/pthread/smoke/pthread_test_011.cpp | 167 + .../basic/pthread/smoke/pthread_test_012.cpp | 67 + .../basic/pthread/smoke/pthread_test_013.cpp | 55 + .../basic/pthread/smoke/pthread_test_015.cpp | 100 + .../basic/pthread/smoke/pthread_test_016.cpp | 99 + .../basic/pthread/smoke/pthread_test_017.cpp | 97 + .../basic/pthread/smoke/pthread_test_018.cpp | 147 + .../basic/pthread/smoke/pthread_test_019.cpp | 124 + .../basic/pthread/smoke/pthread_test_020.cpp | 105 + .../basic/pthread/smoke/pthread_test_021.cpp | 139 + .../basic/pthread/smoke/pthread_test_022.cpp | 139 + .../basic/pthread/smoke/pthread_test_023.cpp | 101 + .../basic/pthread/smoke/pthread_test_024.cpp | 90 + .../basic/pthread/smoke/pthread_test_025.cpp | 97 + .../basic/pthread/smoke/pthread_test_026.cpp | 106 + .../basic/pthread/smoke/pthread_test_027.cpp | 91 + .../testsuites/unittest/process/fs/BUILD.gn | 56 + .../unittest/process/fs/It_process_fs_test.h | 65 + .../testsuites/unittest/process/fs/config.gni | 76 + .../unittest/process/fs/process_fs_test.cpp | 252 + .../process/fs/smoke/It_process_fs_001.cpp | 44 + .../process/fs/smoke/It_process_fs_002.cpp | 49 + .../process/fs/smoke/It_process_fs_003.cpp | 54 + .../process/fs/smoke/It_process_fs_004.cpp | 64 + .../process/fs/smoke/It_process_fs_005.cpp | 65 + .../process/fs/smoke/It_process_fs_007.cpp | 49 + .../process/fs/smoke/It_process_fs_008.cpp | 49 + .../process/fs/smoke/It_process_fs_009.cpp | 49 + .../process/fs/smoke/It_process_fs_010.cpp | 49 + .../process/fs/smoke/It_process_fs_011.cpp | 49 + .../process/fs/smoke/It_process_fs_012.cpp | 79 + .../process/fs/smoke/It_process_fs_013.cpp | 42 + .../process/fs/smoke/It_process_fs_014.cpp | 39 + .../process/fs/smoke/It_process_fs_015.cpp | 41 + .../process/fs/smoke/It_process_fs_021.cpp | 49 + .../process/fs/smoke/It_process_fs_022.cpp | 49 + .../testsuites/unittest/process/lock/BUILD.gn | 56 + .../unittest/process/lock/config.gni | 69 + .../unittest/process/lock/mutex/config.gni | 66 + .../mutex/full/pthread_mutex_test_018.cpp | 166 + .../mutex/full/pthread_mutex_test_023.cpp | 116 + .../mutex/full/pthread_mutex_test_024.cpp | 163 + .../mutex/full/pthread_mutex_test_025.cpp | 147 + .../process/lock/mutex/it_mutex_test.h | 66 + .../process/lock/mutex/process_mutex_test.cpp | 309 + .../mutex/smoke/pthread_mutex_test_001.cpp | 106 + .../mutex/smoke/pthread_mutex_test_002.cpp | 124 + .../mutex/smoke/pthread_mutex_test_003.cpp | 154 + .../mutex/smoke/pthread_mutex_test_004.cpp | 195 + .../mutex/smoke/pthread_mutex_test_005.cpp | 195 + .../mutex/smoke/pthread_mutex_test_006.cpp | 191 + .../mutex/smoke/pthread_mutex_test_007.cpp | 205 + .../mutex/smoke/pthread_mutex_test_008.cpp | 168 + .../mutex/smoke/pthread_mutex_test_009.cpp | 123 + .../mutex/smoke/pthread_mutex_test_010.cpp | 117 + .../mutex/smoke/pthread_mutex_test_011.cpp | 68 + .../mutex/smoke/pthread_mutex_test_012.cpp | 73 + .../mutex/smoke/pthread_mutex_test_013.cpp | 73 + .../mutex/smoke/pthread_mutex_test_014.cpp | 82 + .../mutex/smoke/pthread_mutex_test_015.cpp | 79 + .../mutex/smoke/pthread_mutex_test_016.cpp | 63 + .../mutex/smoke/pthread_mutex_test_017.cpp | 134 + .../mutex/smoke/pthread_mutex_test_019.cpp | 178 + .../mutex/smoke/pthread_mutex_test_020.cpp | 214 + .../mutex/smoke/pthread_mutex_test_021.cpp | 211 + .../mutex/smoke/pthread_mutex_test_022.cpp | 211 + .../unittest/process/lock/rwlock/config.gni | 43 + .../rwlock/full/pthread_rwlock_test_002.cpp | 309 + .../process/lock/rwlock/it_rwlock_test.h | 39 + .../lock/rwlock/process_rwlock_test.cpp | 67 + .../rwlock/smoke/pthread_rwlock_test_001.cpp | 283 + .../unittest/process/lock/spinlock/config.gni | 40 + .../process/lock/spinlock/it_spinlock_test.h | 39 + .../lock/spinlock/process_spinlock_test.cpp | 55 + .../smoke/pthread_spinlock_test_001.cpp | 177 + .../unittest/process/plimits/BUILD.gn | 56 + .../process/plimits/It_process_plimits.h | 136 + .../unittest/process/plimits/config.gni | 101 + .../process/plimits/process_plimits_test.cpp | 901 ++ .../plimits/smoke/It_process_plimits_001.cpp | 55 + .../plimits/smoke/It_process_plimits_002.cpp | 43 + .../plimits/smoke/It_process_plimits_003.cpp | 43 + .../plimits/smoke/It_process_plimits_004.cpp | 60 + .../plimits/smoke/It_process_plimits_005.cpp | 43 + .../plimits/smoke/It_process_plimits_006.cpp | 99 + .../plimits/smoke/It_process_plimits_007.cpp | 66 + .../plimits/smoke/It_process_plimits_008.cpp | 88 + .../smoke/It_process_plimits_devices_001.cpp | 65 + .../smoke/It_process_plimits_devices_002.cpp | 66 + .../smoke/It_process_plimits_devices_003.cpp | 65 + .../smoke/It_process_plimits_devices_004.cpp | 65 + .../smoke/It_process_plimits_devices_005.cpp | 65 + .../smoke/It_process_plimits_devices_006.cpp | 65 + .../smoke/It_process_plimits_devices_007.cpp | 65 + .../smoke/It_process_plimits_devices_008.cpp | 65 + .../smoke/It_process_plimits_devices_009.cpp | 65 + .../smoke/It_process_plimits_ipc_002.cpp | 59 + .../smoke/It_process_plimits_ipc_003.cpp | 67 + .../smoke/It_process_plimits_ipc_004.cpp | 72 + .../smoke/It_process_plimits_ipc_005.cpp | 85 + .../smoke/It_process_plimits_ipc_006.cpp | 119 + .../smoke/It_process_plimits_ipc_007.cpp | 57 + .../smoke/It_process_plimits_ipc_008.cpp | 77 + .../smoke/It_process_plimits_ipc_009.cpp | 73 + .../smoke/It_process_plimits_ipc_010.cpp | 99 + .../smoke/It_process_plimits_ipc_011.cpp | 58 + .../smoke/It_process_plimits_ipc_012.cpp | 77 + .../smoke/It_process_plimits_ipc_013.cpp | 111 + .../smoke/It_process_plimits_memory_001.cpp | 87 + .../smoke/It_process_plimits_memory_002.cpp | 90 + .../smoke/It_process_plimits_pid_001.cpp | 108 + .../smoke/It_process_plimits_pid_002.cpp | 108 + .../smoke/It_process_plimits_pid_003.cpp | 93 + .../smoke/It_process_plimits_pid_004.cpp | 63 + .../smoke/It_process_plimits_pid_005.cpp | 78 + .../smoke/It_process_plimits_pid_006.cpp | 63 + .../smoke/It_process_plimits_sched_001.cpp | 42 + .../smoke/It_process_plimits_sched_002.cpp | 42 + .../smoke/It_process_plimits_sched_003.cpp | 41 + .../smoke/It_process_plimits_sched_004.cpp | 41 + .../testsuites/unittest/security/BUILD.gn | 56 + .../unittest/security/capability/config.gni | 39 + .../security/capability/it_test_capability.h | 39 + .../capability/security_capability_test.cpp | 56 + .../capability/smoke/cap_test_001.cpp | 182 + .../testsuites/unittest/security/config.gni | 69 + .../unittest/security/reugid/config.gni | 39 + .../unittest/security/reugid/it_test_reugid.h | 39 + .../security/reugid/security_reugid_test.cpp | 56 + .../security/reugid/smoke/reugid_test_001.cpp | 442 + .../unittest/security/vid/config.gni | 37 + .../unittest/security/vid/it_test_vid.h | 47 + .../security/vid/security_vid_test.cpp | 56 + .../security/vid/smoke/vid_test_001.cpp | 144 + .../testsuites/unittest/tools/BUILD.gn | 38 + .../testsuites/unittest/tools/README.md | 63 + .../unittest/tools/unittest_tools.cpp | 468 + src/kernel_liteos_a/tools/.gitignore | 2 + src/kernel_liteos_a/tools/build/liteos.ld | 202 + .../tools/build/liteos_llvm.ld | 207 + .../tools/build/mk/liteos_tables_ldflags.mk | 192 + .../tools/build/mk/los_config.mk | 601 + src/kernel_liteos_a/tools/build/mk/module.mk | 76 + .../tools/scripts/make_rootfs/releaseinfo.sh | 37 + .../tools/scripts/make_rootfs/rootfsdir.sh | 49 + .../tools/scripts/make_rootfs/rootfsimg.sh | 107 + .../tools/scripts/parse_exc/parse_excinfo.py | 265 + .../scripts/parse_memory/parse_mem_info.sh | 127 + 3020 files changed, 379271 insertions(+), 1 deletion(-) delete mode 160000 src/kernel_liteos_a create mode 100644 src/kernel_liteos_a/.gitignore create mode 100644 src/kernel_liteos_a/BUILD.gn create mode 100644 src/kernel_liteos_a/CHANGELOG.md create mode 100644 src/kernel_liteos_a/Kconfig create mode 100644 src/kernel_liteos_a/LICENSE create mode 100644 src/kernel_liteos_a/Makefile create mode 100644 src/kernel_liteos_a/OAT.xml create mode 100644 src/kernel_liteos_a/README.md create mode 100644 src/kernel_liteos_a/README_zh-HK.md create mode 100644 src/kernel_liteos_a/README_zh.md create mode 100644 src/kernel_liteos_a/apps/BUILD.gn create mode 100644 src/kernel_liteos_a/apps/Makefile create mode 100644 src/kernel_liteos_a/apps/app.mk create mode 100644 src/kernel_liteos_a/apps/config.mk create mode 100644 src/kernel_liteos_a/apps/init/BUILD.gn create mode 100644 src/kernel_liteos_a/apps/init/Makefile create mode 100644 src/kernel_liteos_a/apps/init/src/init.c create mode 100644 src/kernel_liteos_a/apps/lms/BUILD.gn create mode 100644 src/kernel_liteos_a/apps/lms/src/sample_usr_lms.c create mode 100644 src/kernel_liteos_a/apps/mksh/BUILD.gn create mode 100644 src/kernel_liteos_a/apps/mksh/Makefile create mode 100644 src/kernel_liteos_a/apps/perf/BUILD.gn create mode 100644 src/kernel_liteos_a/apps/perf/Makefile create mode 100644 src/kernel_liteos_a/apps/perf/include/option.h create mode 100644 src/kernel_liteos_a/apps/perf/include/perf.h create mode 100644 src/kernel_liteos_a/apps/perf/include/perf_list.h create mode 100644 src/kernel_liteos_a/apps/perf/include/perf_record.h create mode 100644 src/kernel_liteos_a/apps/perf/include/perf_stat.h create mode 100644 src/kernel_liteos_a/apps/perf/src/main.c create mode 100644 src/kernel_liteos_a/apps/perf/src/option.c create mode 100644 src/kernel_liteos_a/apps/perf/src/perf.c create mode 100644 src/kernel_liteos_a/apps/perf/src/perf_list.c create mode 100644 src/kernel_liteos_a/apps/perf/src/perf_record.c create mode 100644 src/kernel_liteos_a/apps/perf/src/perf_stat.c create mode 100644 src/kernel_liteos_a/apps/shell/BUILD.gn create mode 100644 src/kernel_liteos_a/apps/shell/Makefile create mode 100644 src/kernel_liteos_a/apps/shell/builtin/cd.c create mode 100644 src/kernel_liteos_a/apps/shell/include/shcmd.h create mode 100644 src/kernel_liteos_a/apps/shell/include/shcmdparse.h create mode 100644 src/kernel_liteos_a/apps/shell/include/shell.h create mode 100644 src/kernel_liteos_a/apps/shell/include/shell_list.h create mode 100644 src/kernel_liteos_a/apps/shell/include/shell_pri.h create mode 100644 src/kernel_liteos_a/apps/shell/include/sherr.h create mode 100644 src/kernel_liteos_a/apps/shell/include/shmsg.h create mode 100644 src/kernel_liteos_a/apps/shell/include/show.h create mode 100644 src/kernel_liteos_a/apps/shell/src/main.c create mode 100644 src/kernel_liteos_a/apps/shell/src/shcmd.c create mode 100644 src/kernel_liteos_a/apps/shell/src/shcmdparse.c create mode 100644 src/kernel_liteos_a/apps/shell/src/shmsg.c create mode 100644 src/kernel_liteos_a/apps/tftp/BUILD.gn create mode 100644 src/kernel_liteos_a/apps/tftp/Makefile create mode 100644 src/kernel_liteos_a/apps/tftp/include/tftpc.h create mode 100644 src/kernel_liteos_a/apps/tftp/include/types_adapt.h create mode 100644 src/kernel_liteos_a/apps/tftp/src/main.c create mode 100644 src/kernel_liteos_a/apps/tftp/src/tftpc.c create mode 100644 src/kernel_liteos_a/apps/toybox/BUILD.gn create mode 100644 src/kernel_liteos_a/apps/toybox/Makefile create mode 100644 src/kernel_liteos_a/apps/toybox/liteos_a_custom.config create mode 100644 src/kernel_liteos_a/apps/trace/BUILD.gn create mode 100644 src/kernel_liteos_a/apps/trace/Makefile create mode 100644 src/kernel_liteos_a/apps/trace/src/trace.c create mode 100644 src/kernel_liteos_a/arch/BUILD.gn create mode 100644 src/kernel_liteos_a/arch/Kconfig create mode 100644 src/kernel_liteos_a/arch/arm/BUILD.gn create mode 100644 src/kernel_liteos_a/arch/arm/Kconfig create mode 100644 src/kernel_liteos_a/arch/arm/arm.mk create mode 100644 src/kernel_liteos_a/arch/arm/arm/BUILD.gn create mode 100644 src/kernel_liteos_a/arch/arm/arm/Makefile create mode 100644 src/kernel_liteos_a/arch/arm/arm/include/arch_config.h create mode 100644 src/kernel_liteos_a/arch/arm/arm/include/arm.h create mode 100644 src/kernel_liteos_a/arch/arm/arm/include/arm_user_clear.h create mode 100644 src/kernel_liteos_a/arch/arm/arm/include/arm_user_copy.h create mode 100644 src/kernel_liteos_a/arch/arm/arm/include/arm_user_get.h create mode 100644 src/kernel_liteos_a/arch/arm/arm/include/arm_user_put.h create mode 100644 src/kernel_liteos_a/arch/arm/arm/include/hal_timer.h create mode 100644 src/kernel_liteos_a/arch/arm/arm/include/los_arch_mmu.h create mode 100644 src/kernel_liteos_a/arch/arm/arm/include/los_asid.h create mode 100644 src/kernel_liteos_a/arch/arm/arm/include/los_atomic.h create mode 100644 src/kernel_liteos_a/arch/arm/arm/include/los_hw_cpu.h create mode 100644 src/kernel_liteos_a/arch/arm/arm/include/los_mmu_descriptor_v6.h create mode 100644 src/kernel_liteos_a/arch/arm/arm/include/los_pte_ops.h create mode 100644 src/kernel_liteos_a/arch/arm/arm/include/los_tlb_v6.h create mode 100644 src/kernel_liteos_a/arch/arm/arm/include/smp.h create mode 100644 src/kernel_liteos_a/arch/arm/arm/src/arm_generic_timer.c create mode 100644 src/kernel_liteos_a/arch/arm/arm/src/armv7a/cache.S create mode 100644 src/kernel_liteos_a/arch/arm/arm/src/clear_user.S create mode 100644 src/kernel_liteos_a/arch/arm/arm/src/hw_user_get.S create mode 100644 src/kernel_liteos_a/arch/arm/arm/src/hw_user_put.S create mode 100644 src/kernel_liteos_a/arch/arm/arm/src/include/armv7_pmu_pri.h create mode 100644 src/kernel_liteos_a/arch/arm/arm/src/include/asm.h create mode 100644 src/kernel_liteos_a/arch/arm/arm/src/include/los_exc_pri.h create mode 100644 src/kernel_liteos_a/arch/arm/arm/src/include/los_hw_pri.h create mode 100644 src/kernel_liteos_a/arch/arm/arm/src/include/los_hwi_pri.h create mode 100644 src/kernel_liteos_a/arch/arm/arm/src/jmp.S create mode 100644 src/kernel_liteos_a/arch/arm/arm/src/los_arch_mmu.c create mode 100644 src/kernel_liteos_a/arch/arm/arm/src/los_asid.c create mode 100644 src/kernel_liteos_a/arch/arm/arm/src/los_dispatch.S create mode 100644 src/kernel_liteos_a/arch/arm/arm/src/los_exc.c create mode 100644 src/kernel_liteos_a/arch/arm/arm/src/los_hw.c create mode 100644 src/kernel_liteos_a/arch/arm/arm/src/los_hw_exc.S create mode 100644 src/kernel_liteos_a/arch/arm/arm/src/los_hw_runstop.S create mode 100644 src/kernel_liteos_a/arch/arm/arm/src/los_hw_tick.c create mode 100644 src/kernel_liteos_a/arch/arm/arm/src/los_hwi.c create mode 100644 src/kernel_liteos_a/arch/arm/arm/src/pmu/armv7_pmu.c create mode 100644 src/kernel_liteos_a/arch/arm/arm/src/smp.c create mode 100644 src/kernel_liteos_a/arch/arm/arm/src/startup/reset_vector_mp.S create mode 100644 src/kernel_liteos_a/arch/arm/arm/src/startup/reset_vector_up.S create mode 100644 src/kernel_liteos_a/arch/arm/arm/src/strncpy_from_user.c create mode 100644 src/kernel_liteos_a/arch/arm/arm/src/strnlen_user.c create mode 100644 src/kernel_liteos_a/arch/arm/arm/src/user_copy.c create mode 100644 src/kernel_liteos_a/arch/arm/gic/BUILD.gn create mode 100644 src/kernel_liteos_a/arch/arm/gic/Makefile create mode 100644 src/kernel_liteos_a/arch/arm/gic/gic_v2.c create mode 100644 src/kernel_liteos_a/arch/arm/gic/gic_v3.c create mode 100644 src/kernel_liteos_a/arch/arm/include/gic_common.h create mode 100644 src/kernel_liteos_a/arch/arm/include/gic_v3.h create mode 100644 src/kernel_liteos_a/arch/arm/include/hal_hwi.h create mode 100644 src/kernel_liteos_a/arch/arm/include/in_cksum.h create mode 100644 src/kernel_liteos_a/arch/arm/include/los_exc.h create mode 100644 src/kernel_liteos_a/arch/arm/include/los_hw.h create mode 100644 src/kernel_liteos_a/arch/arm/include/los_hw_arch.h create mode 100644 src/kernel_liteos_a/arch/arm/include/los_hw_tick_pri.h create mode 100644 src/kernel_liteos_a/arch/arm/include/los_hwi.h create mode 100644 src/kernel_liteos_a/arch/arm/include/los_strncpy_from_user.h create mode 100644 src/kernel_liteos_a/arch/arm/include/los_strnlen_user.h create mode 100644 src/kernel_liteos_a/arch/arm/include/los_sys_stack_pri.h create mode 100644 src/kernel_liteos_a/arch/arm/include/los_user_get.h create mode 100644 src/kernel_liteos_a/arch/arm/include/los_user_put.h create mode 100644 src/kernel_liteos_a/arch/arm/include/perf.h create mode 100644 src/kernel_liteos_a/arch/arm/include/user_copy.h create mode 100644 src/kernel_liteos_a/arch/cpu.mk create mode 100644 src/kernel_liteos_a/bsd/BUILD.gn create mode 100644 src/kernel_liteos_a/bsd/Kconfig create mode 100644 src/kernel_liteos_a/bsd/Makefile create mode 100644 src/kernel_liteos_a/bsd/arm/autoconf.c create mode 100644 src/kernel_liteos_a/bsd/arm/hw_user_copy.S create mode 100644 src/kernel_liteos_a/bsd/arm/in_cksum.c create mode 100644 src/kernel_liteos_a/bsd/arm/in_cksum_arm.S create mode 100644 src/kernel_liteos_a/bsd/arm/include/_bus.h create mode 100644 src/kernel_liteos_a/bsd/arm/nexus.c create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/BUILD.gn create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/Makefile create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/asm/atomic.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/asm/barrier.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/asm/io.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/asm/page.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/atomic.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/compat.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/compiler.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/completion.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/ctype.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/delay.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/dma-mapping.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/errno.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/fcntl.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/fs.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/hrtimer.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/icmp.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/interrupt.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/io.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/ioctl.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/jiffies.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/kernel.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/list.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/module.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/moduleparam.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/pagemap.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/rbtree.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/rtc.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/rwsem.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/scatterlist.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/sched.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/semaphore.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/slab.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/spinlock.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/stat.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/string.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/timer.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/tree.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/types.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/wait.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/wakelock.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/workqueue.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/zutil.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/tzdst.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/include/tzdst_pri.h create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/src/adp.c create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/src/linux_completion.c create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/src/linux_hrtimer.c create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/src/linux_interrupt.c create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/src/linux_sched.c create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/src/linux_semaphore.c create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/src/linux_timer.c create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/src/linux_wakelock.c create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/src/linux_workqueue.c create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/src/prctl.c create mode 100644 src/kernel_liteos_a/bsd/compat/linuxkpi/src/tzdst.c create mode 100644 src/kernel_liteos_a/bsd/crypto/rijndael/rijndael-alg-fst.c create mode 100644 src/kernel_liteos_a/bsd/crypto/rijndael/rijndael-api-fst.c create mode 100644 src/kernel_liteos_a/bsd/crypto/rijndael/rijndael-api-fst.h create mode 100644 src/kernel_liteos_a/bsd/crypto/rijndael/rijndael.h create mode 100644 src/kernel_liteos_a/bsd/crypto/rijndael/rijndael_local.h create mode 100644 src/kernel_liteos_a/bsd/crypto/sha2/sha256.h create mode 100644 src/kernel_liteos_a/bsd/crypto/sha2/sha256c.c create mode 100644 src/kernel_liteos_a/bsd/dev/random/hash.c create mode 100644 src/kernel_liteos_a/bsd/dev/random/hash.h create mode 100644 src/kernel_liteos_a/bsd/dev/random/randomdev.h create mode 100644 src/kernel_liteos_a/bsd/dev/random/uint128.h create mode 100644 src/kernel_liteos_a/bsd/dev/random/unit_test.h create mode 100644 src/kernel_liteos_a/bsd/dev/random/yarrow.c create mode 100644 src/kernel_liteos_a/bsd/dev/random/yarrow.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/BUILD.gn create mode 100644 src/kernel_liteos_a/bsd/dev/usb/Kconfig create mode 100644 src/kernel_liteos_a/bsd/dev/usb/Makefile create mode 100644 src/kernel_liteos_a/bsd/dev/usb/controller/ehci.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/controller/ehci.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/controller/ehci_pci.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/controller/ehcireg.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/controller/usb_controller.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/controller/xhci.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/controller/xhci.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/controller/xhci_pci.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/controller/xhcireg.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/implementation/_macro_ref.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/implementation/_thread_ref.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/implementation/_types_ref.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/implementation/bsd_busspace.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/implementation/bsd_kernel.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/implementation/bsd_kernel.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/implementation/freebsd_sys.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/implementation/freebsd_usb.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/implementation/global_implementation.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/implementation/usb_api_pri.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/implementation/usb_btree.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/implementation/usb_btree.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/implementation/usb_busdma_loader.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/implementation/usb_init.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/implementation/usb_init.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/implementation/usb_version.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/implementation/usbdevs.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/input/uhid.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/input/usb_rdesc.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/linux_usb.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/linux_usb.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/net/if_axe.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/net/if_axereg.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/net/if_axge.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/net/if_axgereg.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/net/if_cdce.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/net/if_cdcereg.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/net/if_urndis.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/net/if_urndisreg.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/net/mii.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/net/usb_eth_drv.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/net/usb_eth_drv.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/net/usb_ethernet.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/net/usb_ethernet.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/quirk/usb_quirk.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/quirk/usb_quirk.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/serial.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/serial/u3g.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/serial/usb_serial.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/serial/usb_serial.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/storage/scsi.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/storage/scsi_all.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/storage/umass.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usb.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usb_bus.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usb_busdma.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usb_cdc.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usb_controller.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usb_core.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usb_core.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usb_debug.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usb_debug.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usb_dev.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usb_dev.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usb_device.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usb_device.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usb_dynamic.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usb_dynamic.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usb_endian.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usb_error.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usb_freebsd_loader.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usb_generic.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usb_generic.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usb_handle_request.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usb_hid.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usb_hub.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usb_hub.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usb_if.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usb_if.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usb_ioctl.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usb_lookup.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usb_mbuf.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usb_mbuf.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usb_parse.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usb_process.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usb_process.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usb_request.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usb_request.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usb_transfer.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usb_transfer.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usb_util.c create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usb_util.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usbdi.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usbdi_util.h create mode 100644 src/kernel_liteos_a/bsd/dev/usb/usbhid.h create mode 100644 src/kernel_liteos_a/bsd/kern/bus_if.c create mode 100644 src/kernel_liteos_a/bsd/kern/bus_if.h create mode 100644 src/kernel_liteos_a/bsd/kern/device_if.c create mode 100644 src/kernel_liteos_a/bsd/kern/device_if.h create mode 100644 src/kernel_liteos_a/bsd/kern/kern_condvar.c create mode 100644 src/kernel_liteos_a/bsd/kern/kern_timeout.c create mode 100644 src/kernel_liteos_a/bsd/kern/subr_bus.c create mode 100644 src/kernel_liteos_a/bsd/kern/subr_kobj.c create mode 100644 src/kernel_liteos_a/bsd/libkern/explicit_bzero.c create mode 100644 src/kernel_liteos_a/bsd/net/ppp_defs.h create mode 100644 src/kernel_liteos_a/bsd/sys/_callout.h create mode 100644 src/kernel_liteos_a/bsd/sys/bus.h create mode 100644 src/kernel_liteos_a/bsd/sys/callout.h create mode 100644 src/kernel_liteos_a/bsd/sys/cdefs.h create mode 100644 src/kernel_liteos_a/bsd/sys/condvar.h create mode 100644 src/kernel_liteos_a/bsd/sys/kernel.h create mode 100644 src/kernel_liteos_a/bsd/sys/kobj.h create mode 100644 src/kernel_liteos_a/bsd/sys/linker_set.h create mode 100644 src/kernel_liteos_a/bsd/sys/malloc.h create mode 100644 src/kernel_liteos_a/bsd/sys/module.h create mode 100644 src/kernel_liteos_a/bsd/sys/mutex.h create mode 100644 src/kernel_liteos_a/bsd/sys/priv.h create mode 100644 src/kernel_liteos_a/bsd/sys/queue.h create mode 100644 src/kernel_liteos_a/bsd/sys/sema.h create mode 100644 src/kernel_liteos_a/bsd/sys/sx.h create mode 100644 src/kernel_liteos_a/bsd/sys/systm.h create mode 100644 src/kernel_liteos_a/build.sh create mode 100644 src/kernel_liteos_a/bundle.json create mode 100644 src/kernel_liteos_a/compat/BUILD.gn create mode 100644 src/kernel_liteos_a/compat/posix/BUILD.gn create mode 100644 src/kernel_liteos_a/compat/posix/Kconfig create mode 100644 src/kernel_liteos_a/compat/posix/Makefile create mode 100644 src/kernel_liteos_a/compat/posix/include/mqueue.h create mode 100644 src/kernel_liteos_a/compat/posix/include/time_posix.h create mode 100644 src/kernel_liteos_a/compat/posix/src/errno.c create mode 100644 src/kernel_liteos_a/compat/posix/src/malloc.c create mode 100644 src/kernel_liteos_a/compat/posix/src/map_error.c create mode 100644 src/kernel_liteos_a/compat/posix/src/map_error.h create mode 100644 src/kernel_liteos_a/compat/posix/src/misc.c create mode 100644 src/kernel_liteos_a/compat/posix/src/mqueue.c create mode 100644 src/kernel_liteos_a/compat/posix/src/posix_memalign.c create mode 100644 src/kernel_liteos_a/compat/posix/src/pprivate.h create mode 100644 src/kernel_liteos_a/compat/posix/src/pthread.c create mode 100644 src/kernel_liteos_a/compat/posix/src/pthread_attr.c create mode 100644 src/kernel_liteos_a/compat/posix/src/pthread_cond.c create mode 100644 src/kernel_liteos_a/compat/posix/src/pthread_mutex.c create mode 100644 src/kernel_liteos_a/compat/posix/src/sched.c create mode 100644 src/kernel_liteos_a/compat/posix/src/semaphore.c create mode 100644 src/kernel_liteos_a/compat/posix/src/socket.c create mode 100644 src/kernel_liteos_a/compat/posix/src/stdio.c create mode 100644 src/kernel_liteos_a/compat/posix/src/stdlib.c create mode 100644 src/kernel_liteos_a/compat/posix/src/time.c create mode 100644 src/kernel_liteos_a/config.mk create mode 100644 src/kernel_liteos_a/drivers/BUILD.gn create mode 100644 src/kernel_liteos_a/drivers/Kconfig create mode 100644 src/kernel_liteos_a/drivers/block/BUILD.gn create mode 100644 src/kernel_liteos_a/drivers/block/disk/BUILD.gn create mode 100644 src/kernel_liteos_a/drivers/block/disk/Makefile create mode 100644 src/kernel_liteos_a/drivers/block/disk/include/disk.h create mode 100644 src/kernel_liteos_a/drivers/block/disk/include/disk_pri.h create mode 100644 src/kernel_liteos_a/drivers/block/disk/include/driver.h create mode 100644 src/kernel_liteos_a/drivers/block/disk/src/disk.c create mode 100644 src/kernel_liteos_a/drivers/block/disk/src/disk_shellcmd.c create mode 100644 src/kernel_liteos_a/drivers/char/BUILD.gn create mode 100644 src/kernel_liteos_a/drivers/char/bch/BUILD.gn create mode 100644 src/kernel_liteos_a/drivers/char/bch/Makefile create mode 100644 src/kernel_liteos_a/drivers/char/bch/include/blockproxy.h create mode 100644 src/kernel_liteos_a/drivers/char/mem/BUILD.gn create mode 100644 src/kernel_liteos_a/drivers/char/mem/Kconfig create mode 100644 src/kernel_liteos_a/drivers/char/mem/Makefile create mode 100644 src/kernel_liteos_a/drivers/char/mem/include/los_dev_mem.h create mode 100644 src/kernel_liteos_a/drivers/char/mem/src/mem.c create mode 100644 src/kernel_liteos_a/drivers/char/perf/BUILD.gn create mode 100644 src/kernel_liteos_a/drivers/char/perf/Kconfig create mode 100644 src/kernel_liteos_a/drivers/char/perf/Makefile create mode 100644 src/kernel_liteos_a/drivers/char/perf/include/los_dev_perf.h create mode 100644 src/kernel_liteos_a/drivers/char/perf/src/perf.c create mode 100644 src/kernel_liteos_a/drivers/char/quickstart/BUILD.gn create mode 100644 src/kernel_liteos_a/drivers/char/quickstart/Kconfig create mode 100644 src/kernel_liteos_a/drivers/char/quickstart/Makefile create mode 100644 src/kernel_liteos_a/drivers/char/quickstart/include/los_dev_quickstart.h create mode 100644 src/kernel_liteos_a/drivers/char/quickstart/src/quickstart.c create mode 100644 src/kernel_liteos_a/drivers/char/random/BUILD.gn create mode 100644 src/kernel_liteos_a/drivers/char/random/Kconfig create mode 100644 src/kernel_liteos_a/drivers/char/random/Makefile create mode 100644 src/kernel_liteos_a/drivers/char/random/include/los_random.h create mode 100644 src/kernel_liteos_a/drivers/char/random/src/random.c create mode 100644 src/kernel_liteos_a/drivers/char/random/src/random_hw.c create mode 100644 src/kernel_liteos_a/drivers/char/trace/BUILD.gn create mode 100644 src/kernel_liteos_a/drivers/char/trace/Kconfig create mode 100644 src/kernel_liteos_a/drivers/char/trace/Makefile create mode 100644 src/kernel_liteos_a/drivers/char/trace/include/los_dev_trace.h create mode 100644 src/kernel_liteos_a/drivers/char/trace/src/trace.c create mode 100644 src/kernel_liteos_a/drivers/char/video/BUILD.gn create mode 100644 src/kernel_liteos_a/drivers/char/video/Kconfig create mode 100644 src/kernel_liteos_a/drivers/char/video/Makefile create mode 100644 src/kernel_liteos_a/drivers/mtd/BUILD.gn create mode 100644 src/kernel_liteos_a/drivers/mtd/multi_partition/BUILD.gn create mode 100644 src/kernel_liteos_a/drivers/mtd/multi_partition/Makefile create mode 100644 src/kernel_liteos_a/drivers/mtd/multi_partition/include/mtd_dev.h create mode 100644 src/kernel_liteos_a/drivers/mtd/multi_partition/include/mtd_list.h create mode 100644 src/kernel_liteos_a/drivers/mtd/multi_partition/include/mtd_partition.h create mode 100644 src/kernel_liteos_a/drivers/mtd/multi_partition/src/mtd_partition.c create mode 100644 src/kernel_liteos_a/drivers/mtd/multi_partition/src/mtd_shellcmd.c create mode 100644 src/kernel_liteos_a/figures/OpenHarmony-LiteOS-A内核架构图.png create mode 100644 src/kernel_liteos_a/figures/architecture-of-the-openharmony-liteos-cortex-a-kernel.png create mode 100644 src/kernel_liteos_a/fs/BUILD.gn create mode 100644 src/kernel_liteos_a/fs/Kconfig create mode 100644 src/kernel_liteos_a/fs/fat/BUILD.gn create mode 100644 src/kernel_liteos_a/fs/fat/Kconfig create mode 100644 src/kernel_liteos_a/fs/fat/Makefile create mode 100644 src/kernel_liteos_a/fs/fat/os_adapt/fat_shellcmd.c create mode 100644 src/kernel_liteos_a/fs/fat/os_adapt/fatfs.c create mode 100644 src/kernel_liteos_a/fs/fat/os_adapt/fatfs.h create mode 100644 src/kernel_liteos_a/fs/fat/os_adapt/format.c create mode 100644 src/kernel_liteos_a/fs/fat/virpart/BUILD.gn create mode 100644 src/kernel_liteos_a/fs/fat/virpart/Makefile create mode 100644 src/kernel_liteos_a/fs/fat/virpart/include/virpart.h create mode 100644 src/kernel_liteos_a/fs/fat/virpart/include/virpartff.h create mode 100644 src/kernel_liteos_a/fs/fat/virpart/src/virpart.c create mode 100644 src/kernel_liteos_a/fs/fat/virpart/src/virpartff.c create mode 100644 src/kernel_liteos_a/fs/include/fs/dirent_fs.h create mode 100644 src/kernel_liteos_a/fs/include/fs/driver.h create mode 100644 src/kernel_liteos_a/fs/include/fs/fd_table.h create mode 100644 src/kernel_liteos_a/fs/include/fs/file.h create mode 100644 src/kernel_liteos_a/fs/include/fs/fs.h create mode 100644 src/kernel_liteos_a/fs/include/fs/fs_operation.h create mode 100644 src/kernel_liteos_a/fs/include/fs/mount.h create mode 100644 src/kernel_liteos_a/fs/include/fs/vnode.h create mode 100644 src/kernel_liteos_a/fs/include/vfs_config.h create mode 100644 src/kernel_liteos_a/fs/jffs2/BUILD.gn create mode 100644 src/kernel_liteos_a/fs/jffs2/Kconfig create mode 100644 src/kernel_liteos_a/fs/jffs2/Makefile create mode 100644 src/kernel_liteos_a/fs/jffs2/include/jffs2_hash.h create mode 100644 src/kernel_liteos_a/fs/jffs2/include/vfs_jffs2.h create mode 100644 src/kernel_liteos_a/fs/jffs2/jffs2.patch create mode 100644 src/kernel_liteos_a/fs/jffs2/src/jffs2_hash.c create mode 100644 src/kernel_liteos_a/fs/jffs2/src/vfs_jffs2.c create mode 100644 src/kernel_liteos_a/fs/nfs/BUILD.gn create mode 100644 src/kernel_liteos_a/fs/nfs/Kconfig create mode 100644 src/kernel_liteos_a/fs/nfs/Makefile create mode 100644 src/kernel_liteos_a/fs/patchfs/BUILD.gn create mode 100644 src/kernel_liteos_a/fs/patchfs/Kconfig create mode 100644 src/kernel_liteos_a/fs/patchfs/Makefile create mode 100644 src/kernel_liteos_a/fs/patchfs/los_partition_utils.c create mode 100644 src/kernel_liteos_a/fs/patchfs/los_partition_utils.h create mode 100644 src/kernel_liteos_a/fs/patchfs/los_patchfs.c create mode 100644 src/kernel_liteos_a/fs/patchfs/los_patchfs.h create mode 100644 src/kernel_liteos_a/fs/proc/BUILD.gn create mode 100644 src/kernel_liteos_a/fs/proc/Kconfig create mode 100644 src/kernel_liteos_a/fs/proc/Makefile create mode 100644 src/kernel_liteos_a/fs/proc/include/internal.h create mode 100644 src/kernel_liteos_a/fs/proc/include/proc_file.h create mode 100644 src/kernel_liteos_a/fs/proc/include/proc_fs.h create mode 100644 src/kernel_liteos_a/fs/proc/os_adapt/fd_proc.c create mode 100644 src/kernel_liteos_a/fs/proc/os_adapt/file_sys.c create mode 100644 src/kernel_liteos_a/fs/proc/os_adapt/fs_cache_proc.c create mode 100644 src/kernel_liteos_a/fs/proc/os_adapt/mem_info.c create mode 100644 src/kernel_liteos_a/fs/proc/os_adapt/mounts_proc.c create mode 100644 src/kernel_liteos_a/fs/proc/os_adapt/plimits_proc.c create mode 100644 src/kernel_liteos_a/fs/proc/os_adapt/power_proc.c create mode 100644 src/kernel_liteos_a/fs/proc/os_adapt/proc_init.c create mode 100644 src/kernel_liteos_a/fs/proc/os_adapt/proc_vfs.c create mode 100644 src/kernel_liteos_a/fs/proc/os_adapt/process_proc.c create mode 100644 src/kernel_liteos_a/fs/proc/os_adapt/sys_user.c create mode 100644 src/kernel_liteos_a/fs/proc/os_adapt/uptime_proc.c create mode 100644 src/kernel_liteos_a/fs/proc/os_adapt/vmm_proc.c create mode 100644 src/kernel_liteos_a/fs/proc/src/proc_file.c create mode 100644 src/kernel_liteos_a/fs/proc/src/proc_shellcmd.c create mode 100644 src/kernel_liteos_a/fs/ramfs/BUILD.gn create mode 100644 src/kernel_liteos_a/fs/ramfs/Kconfig create mode 100644 src/kernel_liteos_a/fs/ramfs/Makefile create mode 100644 src/kernel_liteos_a/fs/romfs/BUILD.gn create mode 100644 src/kernel_liteos_a/fs/romfs/Kconfig create mode 100644 src/kernel_liteos_a/fs/romfs/Makefile create mode 100644 src/kernel_liteos_a/fs/rootfs/BUILD.gn create mode 100644 src/kernel_liteos_a/fs/rootfs/Kconfig create mode 100644 src/kernel_liteos_a/fs/rootfs/Makefile create mode 100644 src/kernel_liteos_a/fs/rootfs/los_bootargs.c create mode 100644 src/kernel_liteos_a/fs/rootfs/los_bootargs.h create mode 100644 src/kernel_liteos_a/fs/rootfs/los_rootfs.c create mode 100644 src/kernel_liteos_a/fs/rootfs/los_rootfs.h create mode 100644 src/kernel_liteos_a/fs/vfs/BUILD.gn create mode 100644 src/kernel_liteos_a/fs/vfs/Kconfig create mode 100644 src/kernel_liteos_a/fs/vfs/Makefile create mode 100644 src/kernel_liteos_a/fs/vfs/bcache/BUILD.gn create mode 100644 src/kernel_liteos_a/fs/vfs/bcache/Makefile create mode 100644 src/kernel_liteos_a/fs/vfs/bcache/src/bcache.c create mode 100644 src/kernel_liteos_a/fs/vfs/epoll/fs_epoll.c create mode 100644 src/kernel_liteos_a/fs/vfs/include/bcache/bcache.h create mode 100644 src/kernel_liteos_a/fs/vfs/include/epoll.h create mode 100644 src/kernel_liteos_a/fs/vfs/include/fs_poll_pri.h create mode 100644 src/kernel_liteos_a/fs/vfs/include/path_cache.h create mode 100644 src/kernel_liteos_a/fs/vfs/include/vnode.h create mode 100644 src/kernel_liteos_a/fs/vfs/mount.c create mode 100644 src/kernel_liteos_a/fs/vfs/operation/fullpath.c create mode 100644 src/kernel_liteos_a/fs/vfs/operation/vfs_chattr.c create mode 100644 src/kernel_liteos_a/fs/vfs/operation/vfs_check.c create mode 100644 src/kernel_liteos_a/fs/vfs/operation/vfs_cloexec.c create mode 100644 src/kernel_liteos_a/fs/vfs/operation/vfs_fallocate.c create mode 100644 src/kernel_liteos_a/fs/vfs/operation/vfs_fallocate64.c create mode 100644 src/kernel_liteos_a/fs/vfs/operation/vfs_fcntl.c create mode 100644 src/kernel_liteos_a/fs/vfs/operation/vfs_force_umount.c create mode 100644 src/kernel_liteos_a/fs/vfs/operation/vfs_init.c create mode 100644 src/kernel_liteos_a/fs/vfs/operation/vfs_other.c create mode 100644 src/kernel_liteos_a/fs/vfs/operation/vfs_preadv.c create mode 100644 src/kernel_liteos_a/fs/vfs/operation/vfs_procfd.c create mode 100644 src/kernel_liteos_a/fs/vfs/operation/vfs_pwritev.c create mode 100644 src/kernel_liteos_a/fs/vfs/operation/vfs_readv.c create mode 100644 src/kernel_liteos_a/fs/vfs/operation/vfs_utime.c create mode 100644 src/kernel_liteos_a/fs/vfs/operation/vfs_writev.c create mode 100644 src/kernel_liteos_a/fs/vfs/path_cache.c create mode 100644 src/kernel_liteos_a/fs/vfs/vfs_cmd/vfs_shellcmd.c create mode 100644 src/kernel_liteos_a/fs/vfs/vnode.c create mode 100644 src/kernel_liteos_a/fs/vfs/vnode_hash.c create mode 100644 src/kernel_liteos_a/fs/zpfs/BUILD.gn create mode 100644 src/kernel_liteos_a/fs/zpfs/Kconfig create mode 100644 src/kernel_liteos_a/fs/zpfs/Makefile create mode 100644 src/kernel_liteos_a/kernel/BUILD.gn create mode 100644 src/kernel_liteos_a/kernel/Kconfig create mode 100644 src/kernel_liteos_a/kernel/base/BUILD.gn create mode 100644 src/kernel_liteos_a/kernel/base/Makefile create mode 100644 src/kernel_liteos_a/kernel/base/core/los_bitmap.c create mode 100644 src/kernel_liteos_a/kernel/base/core/los_info.c create mode 100644 src/kernel_liteos_a/kernel/base/core/los_process.c create mode 100644 src/kernel_liteos_a/kernel/base/core/los_smp.c create mode 100644 src/kernel_liteos_a/kernel/base/core/los_swtmr.c create mode 100644 src/kernel_liteos_a/kernel/base/core/los_sys.c create mode 100644 src/kernel_liteos_a/kernel/base/core/los_task.c create mode 100644 src/kernel_liteos_a/kernel/base/core/los_tick.c create mode 100644 src/kernel_liteos_a/kernel/base/include/los_base_pri.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_binarytree_pri.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_container_pri.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_credentials_pri.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_err_pri.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_event_pri.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_futex_pri.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_info_pri.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_ipc_container_pri.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_ipcdebug_pri.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_membox_pri.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_memory_pri.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_memstat_pri.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_mnt_container_pri.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_mux_pri.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_net_container_pri.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_oom.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_percpu_pri.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_pid_container_pri.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_printf_pri.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_process_pri.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_queue_debug_pri.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_queue_pri.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_rwlock_pri.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_sched_pri.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_sem_debug_pri.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_sem_pri.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_signal.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_sortlink_pri.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_stackinfo_pri.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_statistics_pri.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_swtmr_pri.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_sys_pri.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_task_pri.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_tick_pri.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_time_container_pri.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_typedef_pri.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_user_container_pri.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_uts_container_pri.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_vm_boot.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_vm_common.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_vm_dump.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_vm_fault.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_vm_filemap.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_vm_iomap.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_vm_lock.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_vm_map.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_vm_page.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_vm_phys.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_vm_shm_pri.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_vm_syscall.h create mode 100644 src/kernel_liteos_a/kernel/base/include/los_vm_zone.h create mode 100644 src/kernel_liteos_a/kernel/base/ipc/los_event.c create mode 100644 src/kernel_liteos_a/kernel/base/ipc/los_futex.c create mode 100644 src/kernel_liteos_a/kernel/base/ipc/los_ipcdebug.c create mode 100644 src/kernel_liteos_a/kernel/base/ipc/los_mux.c create mode 100644 src/kernel_liteos_a/kernel/base/ipc/los_queue.c create mode 100644 src/kernel_liteos_a/kernel/base/ipc/los_queue_debug.c create mode 100644 src/kernel_liteos_a/kernel/base/ipc/los_rwlock.c create mode 100644 src/kernel_liteos_a/kernel/base/ipc/los_sem.c create mode 100644 src/kernel_liteos_a/kernel/base/ipc/los_sem_debug.c create mode 100644 src/kernel_liteos_a/kernel/base/ipc/los_signal.c create mode 100644 src/kernel_liteos_a/kernel/base/mem/common/los_memstat.c create mode 100644 src/kernel_liteos_a/kernel/base/mem/membox/los_membox.c create mode 100644 src/kernel_liteos_a/kernel/base/mem/tlsf/los_memory.c create mode 100644 src/kernel_liteos_a/kernel/base/misc/kill_shellcmd.c create mode 100644 src/kernel_liteos_a/kernel/base/misc/los_misc.c create mode 100644 src/kernel_liteos_a/kernel/base/misc/los_stackinfo.c create mode 100644 src/kernel_liteos_a/kernel/base/misc/mempt_shellcmd.c create mode 100644 src/kernel_liteos_a/kernel/base/misc/panic_shellcmd.c create mode 100644 src/kernel_liteos_a/kernel/base/misc/swtmr_shellcmd.c create mode 100644 src/kernel_liteos_a/kernel/base/misc/sysinfo_shellcmd.c create mode 100644 src/kernel_liteos_a/kernel/base/misc/task_shellcmd.c create mode 100644 src/kernel_liteos_a/kernel/base/misc/vm_shellcmd.c create mode 100644 src/kernel_liteos_a/kernel/base/mp/los_lockdep.c create mode 100644 src/kernel_liteos_a/kernel/base/mp/los_mp.c create mode 100644 src/kernel_liteos_a/kernel/base/mp/los_percpu.c create mode 100644 src/kernel_liteos_a/kernel/base/mp/los_spinlock.c create mode 100644 src/kernel_liteos_a/kernel/base/om/los_err.c create mode 100644 src/kernel_liteos_a/kernel/base/sched/los_deadline.c create mode 100644 src/kernel_liteos_a/kernel/base/sched/los_idle.c create mode 100644 src/kernel_liteos_a/kernel/base/sched/los_priority.c create mode 100644 src/kernel_liteos_a/kernel/base/sched/los_sched.c create mode 100644 src/kernel_liteos_a/kernel/base/sched/los_sortlink.c create mode 100644 src/kernel_liteos_a/kernel/base/sched/los_statistics.c create mode 100644 src/kernel_liteos_a/kernel/base/vm/los_vm_boot.c create mode 100644 src/kernel_liteos_a/kernel/base/vm/los_vm_dump.c create mode 100644 src/kernel_liteos_a/kernel/base/vm/los_vm_fault.c create mode 100644 src/kernel_liteos_a/kernel/base/vm/los_vm_filemap.c create mode 100644 src/kernel_liteos_a/kernel/base/vm/los_vm_iomap.c create mode 100644 src/kernel_liteos_a/kernel/base/vm/los_vm_map.c create mode 100644 src/kernel_liteos_a/kernel/base/vm/los_vm_page.c create mode 100644 src/kernel_liteos_a/kernel/base/vm/los_vm_phys.c create mode 100644 src/kernel_liteos_a/kernel/base/vm/los_vm_scan.c create mode 100644 src/kernel_liteos_a/kernel/base/vm/los_vm_syscall.c create mode 100644 src/kernel_liteos_a/kernel/base/vm/oom.c create mode 100644 src/kernel_liteos_a/kernel/base/vm/shm.c create mode 100644 src/kernel_liteos_a/kernel/common/BUILD.gn create mode 100644 src/kernel_liteos_a/kernel/common/Makefile create mode 100644 src/kernel_liteos_a/kernel/common/console.c create mode 100644 src/kernel_liteos_a/kernel/common/console.h create mode 100644 src/kernel_liteos_a/kernel/common/los_config.c create mode 100644 src/kernel_liteos_a/kernel/common/los_config.h create mode 100644 src/kernel_liteos_a/kernel/common/los_excinfo.c create mode 100644 src/kernel_liteos_a/kernel/common/los_excinfo_pri.h create mode 100644 src/kernel_liteos_a/kernel/common/los_init.c create mode 100644 src/kernel_liteos_a/kernel/common/los_init_info.h create mode 100644 src/kernel_liteos_a/kernel/common/los_init_pri.h create mode 100644 src/kernel_liteos_a/kernel/common/los_magickey.c create mode 100644 src/kernel_liteos_a/kernel/common/los_magickey.h create mode 100644 src/kernel_liteos_a/kernel/common/los_printf.c create mode 100644 src/kernel_liteos_a/kernel/common/main.c create mode 100644 src/kernel_liteos_a/kernel/common/virtual_serial.c create mode 100644 src/kernel_liteos_a/kernel/common/virtual_serial.h create mode 100644 src/kernel_liteos_a/kernel/extended/BUILD.gn create mode 100644 src/kernel_liteos_a/kernel/extended/Kconfig create mode 100644 src/kernel_liteos_a/kernel/extended/blackbox/BUILD.gn create mode 100644 src/kernel_liteos_a/kernel/extended/blackbox/Kconfig create mode 100644 src/kernel_liteos_a/kernel/extended/blackbox/Makefile create mode 100644 src/kernel_liteos_a/kernel/extended/blackbox/los_blackbox.h create mode 100644 src/kernel_liteos_a/kernel/extended/blackbox/los_blackbox_common.c create mode 100644 src/kernel_liteos_a/kernel/extended/blackbox/los_blackbox_common.h create mode 100644 src/kernel_liteos_a/kernel/extended/blackbox/los_blackbox_core.c create mode 100644 src/kernel_liteos_a/kernel/extended/blackbox/los_blackbox_detector.c create mode 100644 src/kernel_liteos_a/kernel/extended/blackbox/los_blackbox_detector.h create mode 100644 src/kernel_liteos_a/kernel/extended/blackbox/los_blackbox_system_adapter.c create mode 100644 src/kernel_liteos_a/kernel/extended/blackbox/los_blackbox_system_adapter.h create mode 100644 src/kernel_liteos_a/kernel/extended/container/BUILD.gn create mode 100644 src/kernel_liteos_a/kernel/extended/container/Makefile create mode 100644 src/kernel_liteos_a/kernel/extended/container/los_container.c create mode 100644 src/kernel_liteos_a/kernel/extended/container/los_credentials.c create mode 100644 src/kernel_liteos_a/kernel/extended/container/los_ipc_container.c create mode 100644 src/kernel_liteos_a/kernel/extended/container/los_mnt_container.c create mode 100644 src/kernel_liteos_a/kernel/extended/container/los_net_container.c create mode 100644 src/kernel_liteos_a/kernel/extended/container/los_pid_container.c create mode 100644 src/kernel_liteos_a/kernel/extended/container/los_time_container.c create mode 100644 src/kernel_liteos_a/kernel/extended/container/los_user_container.c create mode 100644 src/kernel_liteos_a/kernel/extended/container/los_uts_container.c create mode 100644 src/kernel_liteos_a/kernel/extended/cppsupport/BUILD.gn create mode 100644 src/kernel_liteos_a/kernel/extended/cppsupport/Makefile create mode 100644 src/kernel_liteos_a/kernel/extended/cppsupport/los_cppsupport.c create mode 100644 src/kernel_liteos_a/kernel/extended/cpup/BUILD.gn create mode 100644 src/kernel_liteos_a/kernel/extended/cpup/Makefile create mode 100644 src/kernel_liteos_a/kernel/extended/cpup/cpup_shellcmd.c create mode 100644 src/kernel_liteos_a/kernel/extended/cpup/los_cpup.c create mode 100644 src/kernel_liteos_a/kernel/extended/cpup/los_cpup_pri.h create mode 100644 src/kernel_liteos_a/kernel/extended/dynload/BUILD.gn create mode 100644 src/kernel_liteos_a/kernel/extended/dynload/Makefile create mode 100644 src/kernel_liteos_a/kernel/extended/dynload/include/los_elf_auxvec_pri.h create mode 100644 src/kernel_liteos_a/kernel/extended/dynload/include/los_exec_elf.h create mode 100644 src/kernel_liteos_a/kernel/extended/dynload/include/los_ld_elf_pri.h create mode 100644 src/kernel_liteos_a/kernel/extended/dynload/include/los_load_elf.h create mode 100644 src/kernel_liteos_a/kernel/extended/dynload/src/los_exec_elf.c create mode 100644 src/kernel_liteos_a/kernel/extended/dynload/src/los_load_elf.c create mode 100644 src/kernel_liteos_a/kernel/extended/hidumper/BUILD.gn create mode 100644 src/kernel_liteos_a/kernel/extended/hidumper/Kconfig create mode 100644 src/kernel_liteos_a/kernel/extended/hidumper/Makefile create mode 100644 src/kernel_liteos_a/kernel/extended/hidumper/los_hidumper.c create mode 100644 src/kernel_liteos_a/kernel/extended/hidumper/los_hidumper.h create mode 100644 src/kernel_liteos_a/kernel/extended/hilog/BUILD.gn create mode 100644 src/kernel_liteos_a/kernel/extended/hilog/Kconfig create mode 100644 src/kernel_liteos_a/kernel/extended/hilog/Makefile create mode 100644 src/kernel_liteos_a/kernel/extended/hilog/los_hilog.c create mode 100644 src/kernel_liteos_a/kernel/extended/hilog/los_hilog.h create mode 100644 src/kernel_liteos_a/kernel/extended/hook/BUILD.gn create mode 100644 src/kernel_liteos_a/kernel/extended/hook/Makefile create mode 100644 src/kernel_liteos_a/kernel/extended/hook/include/los_hook_types.h create mode 100644 src/kernel_liteos_a/kernel/extended/hook/include/los_hook_types_parse.h create mode 100644 src/kernel_liteos_a/kernel/extended/hook/los_hook.c create mode 100644 src/kernel_liteos_a/kernel/extended/liteipc/BUILD.gn create mode 100644 src/kernel_liteos_a/kernel/extended/liteipc/Makefile create mode 100644 src/kernel_liteos_a/kernel/extended/liteipc/hm_liteipc.c create mode 100644 src/kernel_liteos_a/kernel/extended/liteipc/hm_liteipc.h create mode 100644 src/kernel_liteos_a/kernel/extended/lms/BUILD.gn create mode 100644 src/kernel_liteos_a/kernel/extended/lms/Kconfig create mode 100644 src/kernel_liteos_a/kernel/extended/lms/Makefile create mode 100644 src/kernel_liteos_a/kernel/extended/lms/lms_libc.c create mode 100644 src/kernel_liteos_a/kernel/extended/lms/los_lms.c create mode 100644 src/kernel_liteos_a/kernel/extended/lms/los_lms_pri.h create mode 100644 src/kernel_liteos_a/kernel/extended/lms/usr/BUILD.gn create mode 100644 src/kernel_liteos_a/kernel/extended/lms/usr/los_lms.c create mode 100644 src/kernel_liteos_a/kernel/extended/lms/usr/los_lms.h create mode 100644 src/kernel_liteos_a/kernel/extended/lms/usr/los_lms_pri.h create mode 100644 src/kernel_liteos_a/kernel/extended/lms/usr/los_lmslibc.c create mode 100644 src/kernel_liteos_a/kernel/extended/perf/BUILD.gn create mode 100644 src/kernel_liteos_a/kernel/extended/perf/Kconfig create mode 100644 src/kernel_liteos_a/kernel/extended/perf/Makefile create mode 100644 src/kernel_liteos_a/kernel/extended/perf/los_perf.c create mode 100644 src/kernel_liteos_a/kernel/extended/perf/los_perf_pri.h create mode 100644 src/kernel_liteos_a/kernel/extended/perf/perf_output.c create mode 100644 src/kernel_liteos_a/kernel/extended/perf/perf_output_pri.h create mode 100644 src/kernel_liteos_a/kernel/extended/perf/perf_pmu.c create mode 100644 src/kernel_liteos_a/kernel/extended/perf/perf_pmu_pri.h create mode 100644 src/kernel_liteos_a/kernel/extended/perf/pmu/perf_hw_pmu.c create mode 100644 src/kernel_liteos_a/kernel/extended/perf/pmu/perf_sw_pmu.c create mode 100644 src/kernel_liteos_a/kernel/extended/perf/pmu/perf_timed_pmu.c create mode 100644 src/kernel_liteos_a/kernel/extended/pipes/BUILD.gn create mode 100644 src/kernel_liteos_a/kernel/extended/pipes/Makefile create mode 100644 src/kernel_liteos_a/kernel/extended/plimit/BUILD.gn create mode 100644 src/kernel_liteos_a/kernel/extended/plimit/Makefile create mode 100644 src/kernel_liteos_a/kernel/extended/plimit/los_devicelimit.c create mode 100644 src/kernel_liteos_a/kernel/extended/plimit/los_devicelimit.h create mode 100644 src/kernel_liteos_a/kernel/extended/plimit/los_ipclimit.c create mode 100644 src/kernel_liteos_a/kernel/extended/plimit/los_ipclimit.h create mode 100644 src/kernel_liteos_a/kernel/extended/plimit/los_memlimit.c create mode 100644 src/kernel_liteos_a/kernel/extended/plimit/los_memlimit.h create mode 100644 src/kernel_liteos_a/kernel/extended/plimit/los_plimits.c create mode 100644 src/kernel_liteos_a/kernel/extended/plimit/los_plimits.h create mode 100644 src/kernel_liteos_a/kernel/extended/plimit/los_processlimit.c create mode 100644 src/kernel_liteos_a/kernel/extended/plimit/los_processlimit.h create mode 100644 src/kernel_liteos_a/kernel/extended/plimit/los_schedlimit.c create mode 100644 src/kernel_liteos_a/kernel/extended/plimit/los_schedlimit.h create mode 100644 src/kernel_liteos_a/kernel/extended/power/BUILD.gn create mode 100644 src/kernel_liteos_a/kernel/extended/power/Makefile create mode 100644 src/kernel_liteos_a/kernel/extended/power/los_pm.c create mode 100644 src/kernel_liteos_a/kernel/extended/power/los_pm_pri.h create mode 100644 src/kernel_liteos_a/kernel/extended/trace/BUILD.gn create mode 100644 src/kernel_liteos_a/kernel/extended/trace/Kconfig create mode 100644 src/kernel_liteos_a/kernel/extended/trace/Makefile create mode 100644 src/kernel_liteos_a/kernel/extended/trace/cnv/trace_cnv.c create mode 100644 src/kernel_liteos_a/kernel/extended/trace/cnv/trace_cnv.h create mode 100644 src/kernel_liteos_a/kernel/extended/trace/los_trace.c create mode 100644 src/kernel_liteos_a/kernel/extended/trace/los_trace_pri.h create mode 100644 src/kernel_liteos_a/kernel/extended/trace/pipeline/serial/trace_pipeline_serial.c create mode 100644 src/kernel_liteos_a/kernel/extended/trace/pipeline/serial/trace_pipeline_serial.h create mode 100644 src/kernel_liteos_a/kernel/extended/trace/pipeline/trace_pipeline.c create mode 100644 src/kernel_liteos_a/kernel/extended/trace/pipeline/trace_pipeline.h create mode 100644 src/kernel_liteos_a/kernel/extended/trace/pipeline/trace_tlv.c create mode 100644 src/kernel_liteos_a/kernel/extended/trace/pipeline/trace_tlv.h create mode 100644 src/kernel_liteos_a/kernel/extended/trace/trace_offline.c create mode 100644 src/kernel_liteos_a/kernel/extended/trace/trace_online.c create mode 100644 src/kernel_liteos_a/kernel/extended/vdso/BUILD.gn create mode 100644 src/kernel_liteos_a/kernel/extended/vdso/include/los_vdso.h create mode 100644 src/kernel_liteos_a/kernel/extended/vdso/include/los_vdso_datapage.h create mode 100644 src/kernel_liteos_a/kernel/extended/vdso/include/los_vdso_pri.h create mode 100644 src/kernel_liteos_a/kernel/extended/vdso/src/Makefile create mode 100644 src/kernel_liteos_a/kernel/extended/vdso/src/los_vdso.c create mode 100644 src/kernel_liteos_a/kernel/extended/vdso/src/los_vdso_text.S create mode 100644 src/kernel_liteos_a/kernel/extended/vdso/usr/BUILD.gn create mode 100644 src/kernel_liteos_a/kernel/extended/vdso/usr/Makefile create mode 100644 src/kernel_liteos_a/kernel/extended/vdso/usr/los_vdso.ld create mode 100644 src/kernel_liteos_a/kernel/extended/vdso/usr/los_vdso_sys.c create mode 100644 src/kernel_liteos_a/kernel/include/los_base.h create mode 100644 src/kernel_liteos_a/kernel/include/los_bitmap.h create mode 100644 src/kernel_liteos_a/kernel/include/los_builddef.h create mode 100644 src/kernel_liteos_a/kernel/include/los_cppsupport.h create mode 100644 src/kernel_liteos_a/kernel/include/los_cpup.h create mode 100644 src/kernel_liteos_a/kernel/include/los_err.h create mode 100644 src/kernel_liteos_a/kernel/include/los_errno.h create mode 100644 src/kernel_liteos_a/kernel/include/los_event.h create mode 100644 src/kernel_liteos_a/kernel/include/los_hash.h create mode 100644 src/kernel_liteos_a/kernel/include/los_hook.h create mode 100644 src/kernel_liteos_a/kernel/include/los_init.h create mode 100644 src/kernel_liteos_a/kernel/include/los_ld_elflib.h create mode 100644 src/kernel_liteos_a/kernel/include/los_list.h create mode 100644 src/kernel_liteos_a/kernel/include/los_lms.h create mode 100644 src/kernel_liteos_a/kernel/include/los_lockdep.h create mode 100644 src/kernel_liteos_a/kernel/include/los_membox.h create mode 100644 src/kernel_liteos_a/kernel/include/los_memory.h create mode 100644 src/kernel_liteos_a/kernel/include/los_mp.h create mode 100644 src/kernel_liteos_a/kernel/include/los_mux.h create mode 100644 src/kernel_liteos_a/kernel/include/los_perf.h create mode 100644 src/kernel_liteos_a/kernel/include/los_pm.h create mode 100644 src/kernel_liteos_a/kernel/include/los_printf.h create mode 100644 src/kernel_liteos_a/kernel/include/los_process.h create mode 100644 src/kernel_liteos_a/kernel/include/los_queue.h create mode 100644 src/kernel_liteos_a/kernel/include/los_rwlock.h create mode 100644 src/kernel_liteos_a/kernel/include/los_sem.h create mode 100644 src/kernel_liteos_a/kernel/include/los_smp.h create mode 100644 src/kernel_liteos_a/kernel/include/los_spinlock.h create mode 100644 src/kernel_liteos_a/kernel/include/los_swtmr.h create mode 100644 src/kernel_liteos_a/kernel/include/los_sys.h create mode 100644 src/kernel_liteos_a/kernel/include/los_tables.h create mode 100644 src/kernel_liteos_a/kernel/include/los_task.h create mode 100644 src/kernel_liteos_a/kernel/include/los_tick.h create mode 100644 src/kernel_liteos_a/kernel/include/los_toolchain.h create mode 100644 src/kernel_liteos_a/kernel/include/los_trace.h create mode 100644 src/kernel_liteos_a/kernel/include/los_typedef.h create mode 100644 src/kernel_liteos_a/kernel/user/BUILD.gn create mode 100644 src/kernel_liteos_a/kernel/user/Makefile create mode 100644 src/kernel_liteos_a/kernel/user/include/los_user_init.h create mode 100644 src/kernel_liteos_a/kernel/user/src/los_user_init.c create mode 100644 src/kernel_liteos_a/lib/BUILD.gn create mode 100644 src/kernel_liteos_a/lib/Kconfig create mode 100644 src/kernel_liteos_a/lib/libc/BUILD.gn create mode 100644 src/kernel_liteos_a/lib/libc/musl/BUILD.gn create mode 100644 src/kernel_liteos_a/lib/libc/musl/Makefile create mode 100644 src/kernel_liteos_a/lib/libc/musl/src/arch/arm/memcmp.S create mode 100644 src/kernel_liteos_a/lib/libc/musl/src/arch/arm/memset.S create mode 100644 src/kernel_liteos_a/lib/libc/musl/src/memcmp.c create mode 100644 src/kernel_liteos_a/lib/libc/musl/src/memset.c create mode 100644 src/kernel_liteos_a/lib/libc/newlib/BUILD.gn create mode 100644 src/kernel_liteos_a/lib/libmbedtls/BUILD.gn create mode 100644 src/kernel_liteos_a/lib/libmbedtls/Makefile create mode 100644 src/kernel_liteos_a/lib/libscrew/BUILD.gn create mode 100644 src/kernel_liteos_a/lib/libscrew/Makefile create mode 100644 src/kernel_liteos_a/lib/libscrew/include/los_cir_buf.h create mode 100644 src/kernel_liteos_a/lib/libscrew/include/los_crc32.h create mode 100644 src/kernel_liteos_a/lib/libscrew/include/los_rbtree.h create mode 100644 src/kernel_liteos_a/lib/libscrew/include/los_seq_buf.h create mode 100644 src/kernel_liteos_a/lib/libscrew/src/los_cir_buf.c create mode 100644 src/kernel_liteos_a/lib/libscrew/src/los_crc32.c create mode 100644 src/kernel_liteos_a/lib/libscrew/src/los_rbtree.c create mode 100644 src/kernel_liteos_a/lib/libscrew/src/los_seq_buf.c create mode 100644 src/kernel_liteos_a/lib/libsec/BUILD.gn create mode 100644 src/kernel_liteos_a/lib/libsec/Makefile create mode 100644 src/kernel_liteos_a/lib/zlib/BUILD.gn create mode 100644 src/kernel_liteos_a/lib/zlib/Makefile create mode 100644 src/kernel_liteos_a/liteos.gni create mode 100644 src/kernel_liteos_a/net/BUILD.gn create mode 100644 src/kernel_liteos_a/net/Kconfig create mode 100644 src/kernel_liteos_a/net/lwip-2.1/BUILD.gn create mode 100644 src/kernel_liteos_a/net/lwip-2.1/Makefile create mode 100644 src/kernel_liteos_a/net/lwip-2.1/enhancement/include/lwip/api_shell.h create mode 100644 src/kernel_liteos_a/net/lwip-2.1/enhancement/include/lwip/dhcps.h create mode 100644 src/kernel_liteos_a/net/lwip-2.1/enhancement/include/lwip/fixme.h create mode 100644 src/kernel_liteos_a/net/lwip-2.1/enhancement/src/api_shell.c create mode 100644 src/kernel_liteos_a/net/lwip-2.1/enhancement/src/dhcps.c create mode 100644 src/kernel_liteos_a/net/lwip-2.1/enhancement/src/fixme.c create mode 100644 src/kernel_liteos_a/net/lwip-2.1/lwip_porting.gni create mode 100644 src/kernel_liteos_a/net/lwip-2.1/porting/include/arch/cc.h create mode 100644 src/kernel_liteos_a/net/lwip-2.1/porting/include/arch/perf.h create mode 100644 src/kernel_liteos_a/net/lwip-2.1/porting/include/arch/sys_arch.h create mode 100644 src/kernel_liteos_a/net/lwip-2.1/porting/include/lwip/dhcp.h create mode 100644 src/kernel_liteos_a/net/lwip-2.1/porting/include/lwip/inet.h create mode 100644 src/kernel_liteos_a/net/lwip-2.1/porting/include/lwip/ip.h create mode 100644 src/kernel_liteos_a/net/lwip-2.1/porting/include/lwip/lwipopts.h create mode 100644 src/kernel_liteos_a/net/lwip-2.1/porting/include/lwip/netif.h create mode 100644 src/kernel_liteos_a/net/lwip-2.1/porting/include/lwip/netifapi.h create mode 100644 src/kernel_liteos_a/net/lwip-2.1/porting/include/lwip/pbuf.h create mode 100644 src/kernel_liteos_a/net/lwip-2.1/porting/include/lwip/priv/api_msg.h create mode 100644 src/kernel_liteos_a/net/lwip-2.1/porting/include/lwip/priv/sockets_priv.h create mode 100644 src/kernel_liteos_a/net/lwip-2.1/porting/include/lwip/sockets.h create mode 100644 src/kernel_liteos_a/net/lwip-2.1/porting/include/lwipopts.h create mode 100644 src/kernel_liteos_a/net/lwip-2.1/porting/src/driverif.c create mode 100644 src/kernel_liteos_a/net/lwip-2.1/porting/src/sockets.c create mode 100644 src/kernel_liteos_a/net/lwip-2.1/porting/src/sys_arch.c create mode 100644 src/kernel_liteos_a/net/mac/los_mac.h create mode 100644 src/kernel_liteos_a/net/telnet/BUILD.gn create mode 100644 src/kernel_liteos_a/net/telnet/Kconfig create mode 100644 src/kernel_liteos_a/net/telnet/Makefile create mode 100644 src/kernel_liteos_a/net/telnet/include/telnet_dev.h create mode 100644 src/kernel_liteos_a/net/telnet/include/telnet_loop.h create mode 100644 src/kernel_liteos_a/net/telnet/include/telnet_pri.h create mode 100644 src/kernel_liteos_a/net/telnet/src/telnet_dev.c create mode 100644 src/kernel_liteos_a/net/telnet/src/telnet_loop.c create mode 100644 src/kernel_liteos_a/platform/BUILD.gn create mode 100644 src/kernel_liteos_a/platform/Kconfig create mode 100644 src/kernel_liteos_a/platform/Makefile create mode 100644 src/kernel_liteos_a/platform/board.ld.S create mode 100644 src/kernel_liteos_a/platform/bsp.mk create mode 100644 src/kernel_liteos_a/security/BUILD.gn create mode 100644 src/kernel_liteos_a/security/Kconfig create mode 100644 src/kernel_liteos_a/security/Makefile create mode 100644 src/kernel_liteos_a/security/cap/BUILD.gn create mode 100644 src/kernel_liteos_a/security/cap/Makefile create mode 100644 src/kernel_liteos_a/security/cap/capability.c create mode 100644 src/kernel_liteos_a/security/cap/capability_api.h create mode 100644 src/kernel_liteos_a/security/cap/capability_type.h create mode 100644 src/kernel_liteos_a/security/vid/BUILD.gn create mode 100644 src/kernel_liteos_a/security/vid/vid.c create mode 100644 src/kernel_liteos_a/security/vid/vid_api.h create mode 100644 src/kernel_liteos_a/security/vid/vid_type.h create mode 100644 src/kernel_liteos_a/shell/BUILD.gn create mode 100644 src/kernel_liteos_a/shell/Kconfig create mode 100644 src/kernel_liteos_a/shell/Makefile create mode 100644 src/kernel_liteos_a/shell/full/include/dmesg.h create mode 100644 src/kernel_liteos_a/shell/full/include/dmesg_pri.h create mode 100644 src/kernel_liteos_a/shell/full/include/shcmd.h create mode 100644 src/kernel_liteos_a/shell/full/include/shcmdparse.h create mode 100644 src/kernel_liteos_a/shell/full/include/shell.h create mode 100644 src/kernel_liteos_a/shell/full/include/shell_lk.h create mode 100644 src/kernel_liteos_a/shell/full/include/shell_pri.h create mode 100644 src/kernel_liteos_a/shell/full/include/shmsg.h create mode 100644 src/kernel_liteos_a/shell/full/include/show.h create mode 100644 src/kernel_liteos_a/shell/full/src/base/shcmd.c create mode 100644 src/kernel_liteos_a/shell/full/src/base/shcmdparse.c create mode 100644 src/kernel_liteos_a/shell/full/src/base/shell_lk.c create mode 100644 src/kernel_liteos_a/shell/full/src/base/shmsg.c create mode 100644 src/kernel_liteos_a/shell/full/src/base/show.c create mode 100644 src/kernel_liteos_a/shell/full/src/cmds/date_shellcmd.c create mode 100644 src/kernel_liteos_a/shell/full/src/cmds/dmesg.c create mode 100644 src/kernel_liteos_a/shell/full/src/cmds/hwi_shellcmd.c create mode 100644 src/kernel_liteos_a/shell/full/src/cmds/shell_shellcmd.c create mode 100644 src/kernel_liteos_a/shell/full/src/cmds/watch_shellcmd.c create mode 100644 src/kernel_liteos_a/syscall/BUILD.gn create mode 100644 src/kernel_liteos_a/syscall/Makefile create mode 100644 src/kernel_liteos_a/syscall/fs_syscall.c create mode 100644 src/kernel_liteos_a/syscall/ipc_syscall.c create mode 100644 src/kernel_liteos_a/syscall/los_syscall.c create mode 100644 src/kernel_liteos_a/syscall/los_syscall.h create mode 100644 src/kernel_liteos_a/syscall/misc_syscall.c create mode 100644 src/kernel_liteos_a/syscall/net_syscall.c create mode 100644 src/kernel_liteos_a/syscall/process_syscall.c create mode 100644 src/kernel_liteos_a/syscall/syscall_lookup.h create mode 100644 src/kernel_liteos_a/syscall/syscall_pub.c create mode 100644 src/kernel_liteos_a/syscall/syscall_pub.h create mode 100644 src/kernel_liteos_a/syscall/time_syscall.c create mode 100644 src/kernel_liteos_a/syscall/vm_syscall.c create mode 100644 src/kernel_liteos_a/testsuites/BUILD.gn create mode 100644 src/kernel_liteos_a/testsuites/Kconfig create mode 100644 src/kernel_liteos_a/testsuites/LICENSE create mode 100644 src/kernel_liteos_a/testsuites/Makefile create mode 100644 src/kernel_liteos_a/testsuites/build/los_test_config.mk create mode 100644 src/kernel_liteos_a/testsuites/config.mk create mode 100644 src/kernel_liteos_a/testsuites/kernel/BUILD.gn create mode 100644 src/kernel_liteos_a/testsuites/kernel/Kconfig create mode 100644 src/kernel_liteos_a/testsuites/kernel/Makefile create mode 100644 src/kernel_liteos_a/testsuites/kernel/include/iCunit.h create mode 100644 src/kernel_liteos_a/testsuites/kernel/include/iCunit.inc create mode 100644 src/kernel_liteos_a/testsuites/kernel/include/iCunit_config.h create mode 100644 src/kernel_liteos_a/testsuites/kernel/include/los_test_pri.h create mode 100644 src/kernel_liteos_a/testsuites/kernel/include/osTest.h create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/BUILD.gn create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/BUILD.gn create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/Makefile create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/It_smp_hwi.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/It_smp_hwi.h create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_001.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_002.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_003.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_004.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_005.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_006.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_007.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_008.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_009.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_010.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_011.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_012.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_013.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_ipi_001.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_ipi_002.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_ipi_003.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_ipi_004.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_ipi_005.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_ipi_006.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_ipi_007.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_ipi_008.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_nest_001.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_nest_002.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_nest_003.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_nest_004.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_nest_005.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_nest_006.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_nest_007.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_nest_008.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_share_001.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_share_002.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_share_003.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_share_004.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_share_005.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_share_006.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_share_007.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_share_008.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_share_009.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_share_010.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi_nesting/It_hwi_nesting.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi_nesting/It_hwi_nesting.h create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi_nesting/full/It_los_hwi_nesting_001.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi_nesting/full/It_los_hwi_nesting_002.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi_nesting/full/It_los_hwi_nesting_003.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi_nesting/full/It_los_hwi_nesting_004.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi_nesting/full/It_los_hwi_nesting_005.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi_nesting/full/It_los_hwi_nesting_006.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi_nesting/full/It_los_hwi_nesting_007.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/It_los_swtmr.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/It_los_swtmr.h create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_001.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_002.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_003.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_005.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_006.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_007.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_008.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_009.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_010.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_011.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_012.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_013.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_014.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_015.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_016.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_017.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_018.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_019.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_020.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_021.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_022.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_030.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_033.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_036.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_037.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_039.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_040.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_041.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_042.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_043.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_044.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_045.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_046.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_047.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_048.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_049.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_050.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_051.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_052.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_054.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_055.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_056.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_057.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_059.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_060.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_061.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_062.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_063.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_064.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_065.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_066.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_067.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_068.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_069.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_070.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_071.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_075.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_076.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_077.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_078.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smoke/It_los_swtmr_053.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smoke/It_los_swtmr_058.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_001.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_002.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_003.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_004.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_005.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_006.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_007.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_008.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_009.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_010.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_011.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_012.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_013.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_014.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_015.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_016.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_017.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_018.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_019.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_020.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_021.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_022.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_023.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_024.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_025.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_026.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_027.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_028.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_029.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_030.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_031.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_032.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_033.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_034.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_035.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/It_los_task.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/It_los_task.h create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/float/It_los_float.h create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/float/It_smp_los_float_switch_001.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/float/It_smp_los_float_switch_002.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/float/It_smp_los_float_switch_003.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/float/It_smp_los_float_switch_004.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/float/It_smp_los_float_switch_005.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/float/It_smp_los_float_switch_006.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/float/It_smp_los_float_switch_007.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_001.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_002.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_004.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_007.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_008.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_009.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_010.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_011.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_012.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_013.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_014.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_015.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_016.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_017.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_018.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_019.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_020.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_021.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_022.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_023.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_024.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_025.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_026.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_027.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_028.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_029.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_031.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_032.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_033.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_034.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_035.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_036.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_037.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_038.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_039.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_040.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_041.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_042.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_043.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_047.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_048.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_050.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_051.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_052.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_053.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_054.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_055.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_056.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_057.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_058.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_060.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_061.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_063.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_064.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_065.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_066.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_067.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_068.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_069.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_071.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_072.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_073.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_074.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_075.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_076.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_077.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_078.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_079.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_080.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_082.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_090.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_092.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_093.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_094.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_095.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_096.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_098.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_100.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_102.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_103.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_104.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_106.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_107.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_108.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_109.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_110.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_111.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_112.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_113.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_114.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_115.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_116.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_118.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_119.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_120.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_121.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_122.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_123.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_124.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_125.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_126.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_127.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_128.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_129.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_130.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_131.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_132.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_133.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_134.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_135.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_136.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_138.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_141.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_142.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_timeslice_002.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_timeslice_003.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_timeslice_004.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smoke/It_los_task_045.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smoke/It_los_task_046.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smoke/It_los_task_049.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smoke/It_los_task_081.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smoke/It_los_task_089.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smoke/It_los_task_097.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smoke/It_los_task_099.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smoke/It_los_task_101.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smoke/It_los_task_105.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smoke/It_los_task_timeslice_001.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_001.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_002.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_003.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_004.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_021.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_022.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_023.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_024.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_025.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_026.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_027.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_028.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_029.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_030.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_032.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_033.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_034.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_035.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_036.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_037.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_040.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_042.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_043.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_044.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_046.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_047.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_048.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_049.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_050.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_051.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_052.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_053.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_054.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_055.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_056.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_057.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_058.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_059.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_060.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_061.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_062.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_063.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_064.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_065.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_066.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_067.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_068.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_069.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_070.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_071.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_072.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_073.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_074.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_075.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_076.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_077.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_078.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_079.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_081.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_082.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_084.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_087.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_088.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_089.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_090.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_091.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_092.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_093.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_094.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_095.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_096.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_097.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_098.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_099.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_100.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_101.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_102.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_103.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_105.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_106.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_107.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_108.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_109.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_110.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_112.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_113.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_114.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_115.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_117.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_126.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_127.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_128.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_129.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_130.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_131.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_132.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_133.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_134.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_135.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_136.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_137.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_138.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_139.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_141.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_142.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_143.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_144.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_145.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_146.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_147.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_148.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_149.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_150.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_151.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_152.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_153.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_154.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_155.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_156.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_157.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_158.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_159.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_160.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_161.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/BUILD.gn create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/Makefile create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/It_los_event.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/It_los_event.h create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_001.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_002.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_003.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_004.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_005.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_006.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_007.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_008.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_009.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_010.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_011.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_012.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_013.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_014.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_015.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_016.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_018.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_019.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_020.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_021.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_022.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_023.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_024.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_025.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_026.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_027.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_029.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_030.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_032.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_033.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_037.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_038.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_039.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_040.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_042.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_043.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smoke/It_los_event_031.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smoke/It_los_event_035.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smoke/It_los_event_036.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smoke/It_los_event_041.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_001.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_002.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_003.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_004.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_005.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_006.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_007.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_008.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_009.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_010.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_011.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_012.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_013.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_014.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_015.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_016.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_017.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_018.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_019.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_020.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_021.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_022.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_023.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_024.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_025.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_026.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_027.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_028.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_029.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_030.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_031.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_032.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_033.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_034.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_035.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_036.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_037.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/It_los_mux.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/It_los_mux.h create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_006.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_007.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_008.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_009.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_010.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_011.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_012.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_013.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_015.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_016.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_017.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_018.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_020.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_021.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_025.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_026.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_027.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_028.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_029.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_031.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_035.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_036.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_037.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_038.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_039.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_040.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_041.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_042.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_043.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smoke/It_los_mutex_001.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smoke/It_los_mutex_002.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smoke/It_los_mutex_003.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smoke/It_los_mutex_004.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_001.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_002.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_003.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_004.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_005.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_006.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_007.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2001.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2002.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2003.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2004.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2005.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2006.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2007.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2008.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2009.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2010.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2011.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2012.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2013.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2014.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2015.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2016.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2017.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2018.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2021.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2022.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2024.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2025.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2026.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2027.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2028.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2029.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/It_los_queue.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/It_los_queue.h create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_002.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_003.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_005.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_006.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_007.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_008.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_009.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_010.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_011.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_012.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_013.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_014.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_015.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_017.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_018.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_019.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_020.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_021.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_022.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_023.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_024.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_025.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_026.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_027.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_028.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_029.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_032.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_033.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_037.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_038.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_040.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_041.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_042.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_043.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_044.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_045.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_046.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_047.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_048.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_049.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_050.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_051.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_052.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_053.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_054.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_055.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_056.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_057.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_058.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_059.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_061.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_062.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_064.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_065.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_066.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_067.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_068.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_069.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_070.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_071.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_072.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_073.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_074.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_075.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_076.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_077.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_078.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_079.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_080.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_081.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_082.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_083.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_084.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_085.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_086.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_087.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_088.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_089.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_091.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_092.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_093.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_094.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_095.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_096.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_098.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_099.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_101.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_102.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_103.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_104.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_106.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_107.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_108.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_109.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_110.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_111.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_112.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_113.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_114.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_116.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_003.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_004.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_005.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_006.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_007.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_008.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_009.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_010.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_011.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_012.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_013.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_014.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_015.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_016.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_017.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_018.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_019.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_020.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_021.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_022.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_023.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_024.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_025.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_026.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_027.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_028.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_029.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_030.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_031.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_032.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_038.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_039.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_040.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_041.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_042.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smoke/It_los_queue_001.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smoke/It_los_queue_097.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smoke/It_los_queue_100.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smoke/It_los_queue_105.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smoke/It_los_queue_head_002.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_001.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_002.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_003.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_004.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_005.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_006.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_007.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_008.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_009.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_010.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_011.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_012.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_013.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_014.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_015.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_016.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_017.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_018.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_019.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_020.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_021.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_022.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_023.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_024.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_025.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_026.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_027.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_029.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_031.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_032.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/It_los_sem.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/It_los_sem.h create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_002.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_005.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_009.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_012.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_013.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_014.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_015.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_016.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_017.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_019.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_020.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_022.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_023.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_026.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_027.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_028.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_029.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_034.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smoke/It_los_sem_001.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smoke/It_los_sem_003.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smoke/It_los_sem_006.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_001.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_002.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_003.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_004.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_005.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_006.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_007.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_008.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_009.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_010.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_011.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_012.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_013.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_014.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_015.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_016.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_017.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_018.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_019.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_020.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_021.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_022.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_023.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_024.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_025.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_026.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_027.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_028.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_029.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_030.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_031.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_032.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_033.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_034.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_035.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_036.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/BUILD.gn create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/It_extend_cpup.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/It_extend_cpup.h create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/Makefile create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/full/It_extend_cpup_003.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/full/It_extend_cpup_004.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/full/It_extend_cpup_005.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/full/It_extend_cpup_006.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/full/It_extend_cpup_007.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/full/It_extend_cpup_008.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/full/It_extend_cpup_011.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/full/It_extend_cpup_012.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smoke/It_extend_cpup_001.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smoke/It_extend_cpup_002.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_001.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_002.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_003.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_004.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_005.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_007.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_008.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_009.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_010.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_011.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_012.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/BUILD.gn create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/Makefile create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/It_posix_mutex.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/It_posix_mutex.h create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/Makefile create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_002.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_003.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_004.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_005.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_006.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_008.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_009.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_010.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_011.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_013.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_014.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_017.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_018.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_021.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_022.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_023.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_024.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_025.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_026.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_027.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_028.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_029.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_032.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_033.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_034.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_035.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_036.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_037.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_038.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_039.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_040.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_041.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_042.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_043.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_044.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_045.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_046.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_047.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_048.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_049.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_050.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_054.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_055.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_056.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_057.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_058.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_059.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_060.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_061.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_062.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_063.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_064.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_065.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_066.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_067.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_068.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_069.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_070.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_071.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_072.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_073.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_074.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_075.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_076.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_077.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_078.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_079.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_080.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_081.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_082.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_084.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_085.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_086.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_087.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_089.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_090.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_091.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_092.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_093.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_094.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_095.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_097.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_098.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_099.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_101.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/smoke/It_posix_mutex_001.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/smoke/It_posix_mutex_007.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/smoke/It_posix_mutex_012.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/smoke/It_posix_mutex_015.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/smoke/It_posix_mutex_016.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/smoke/It_posix_mutex_019.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/smoke/It_posix_mutex_020.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/It_posix_pthread.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/It_posix_pthread.h create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/Makefile create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_001.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_002.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_007.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_008.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_010.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_011.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_013.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_023.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_028.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_029.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_030.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_031.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_032.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_033.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_034.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_035.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_039.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_040.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_041.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_042.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_044.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_045.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_046.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_047.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_048.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_049.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_050.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_051.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_056.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_057.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_058.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_060.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_066.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_068.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_069.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_071.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_072.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_073.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_074.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_075.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_078.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_079.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_080.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_081.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_082.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_083.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_084.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_085.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_087.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_088.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_089.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_092.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_095.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_098.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_101.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_102.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_103.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_107.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_108.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_110.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_112.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_116.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_121.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_123.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_124.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_125.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_127.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_128.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_129.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_132.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_133.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_134.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_136.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_138.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_141.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_142.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_144.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_150.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_152.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_154.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_166.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_167.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_173.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_175.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_176.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_177.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_182.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_185.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_186.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_187.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_188.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_193.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_194.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_197.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_198.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_200.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_204.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_205.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_206.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_208.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_209.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_211.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_213.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_214.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_215.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_217.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_218.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_219.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_221.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_224.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_226.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_233.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_237.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_238.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_239.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_240.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_241.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_246.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/smoke/It_posix_pthread_003.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/smoke/It_posix_pthread_004.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/smoke/It_posix_pthread_005.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/smoke/It_posix_pthread_006.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/smoke/It_posix_pthread_009.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/smoke/It_posix_pthread_018.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/smoke/It_posix_pthread_019.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/smoke/It_posix_pthread_021.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/src/iCunit.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/src/osTest.c create mode 100644 src/kernel_liteos_a/testsuites/kernel/test.mk create mode 100644 src/kernel_liteos_a/testsuites/unittest/BUILD.gn create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/BUILD.gn create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/dynload/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/dynload/dynload_test.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/dynload/it_test_dynload.h create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/dynload/smoke/dynload_test_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/dynload/smoke/dynload_test_004.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/exc/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/exc/exc_test.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/exc/full/it_test_fexecve_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/exc/it_test_exc.h create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/exc/smoke/it_test_exc_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/exc/smoke/it_test_exc_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/exc/smoke/it_test_exc_003.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/exc/smoke/it_test_exc_004.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/exc/smoke/it_test_exc_005.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/it_test_mem_100.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_003.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_004.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_005.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_006.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_007.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_008.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_009.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_010.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_012.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_013.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_014.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/it_test_shm.h create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/mem_shm_test.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/smoke/shm_test_011.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/it_test_vm.h create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/mem_vm_test.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mmap_test_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mmap_test_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mmap_test_003.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mmap_test_004.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mmap_test_005.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mmap_test_006.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mmap_test_007.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mmap_test_008.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mmap_test_009.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mmap_test_010.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mprotect_test_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mremap_test_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/oom_test_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/open_wmemstream_test_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/user_copy_test_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/common/include/iCunit.h create mode 100644 src/kernel_liteos_a/testsuites/unittest/common/include/los_typedef.h create mode 100644 src/kernel_liteos_a/testsuites/unittest/common/include/osTest.h create mode 100644 src/kernel_liteos_a/testsuites/unittest/common/osTest.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/BUILD.gn create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/It_container_test.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/It_container_test.h create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/full/It_net_container_010.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_003.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_004.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_005.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_006.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_007.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_008.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_009.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_010.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_011.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_012.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_013.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_014.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_015.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_016.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_017.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_018.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_019.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_020.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_021.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_022.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_024.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/full/It_user_container_005.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/full/It_uts_container_003.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_container_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_container_chroot_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_container_chroot_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_ipc_container_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_ipc_container_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_ipc_container_003.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_ipc_container_004.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_ipc_container_005.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_ipc_container_006.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_ipc_container_007.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_ipc_container_008.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_mnt_container_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_mnt_container_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_mnt_container_003.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_mnt_container_004.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_mnt_container_005.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_mnt_container_006.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_mnt_container_007.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_mnt_container_008.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_mnt_container_009.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_mnt_container_010.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_003.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_004.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_005.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_006.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_007.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_008.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_009.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_011.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_012.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_pid_container_023.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_pid_container_025.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_pid_container_026.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_pid_container_027.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_pid_container_028.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_pid_container_029.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_pid_container_030.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_pid_container_031.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_pid_container_032.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_pid_container_033.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_time_container_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_time_container_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_time_container_003.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_time_container_004.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_time_container_005.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_time_container_006.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_time_container_007.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_time_container_008.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_time_container_009.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_time_container_010.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_user_container_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_user_container_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_user_container_003.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_user_container_004.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_user_container_006.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_user_container_007.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_uts_container_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_uts_container_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_uts_container_004.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_uts_container_005.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_uts_container_006.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_uts_container_007.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/container/smoke/It_uts_container_008.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/drivers/BUILD.gn create mode 100644 src/kernel_liteos_a/testsuites/unittest/drivers/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/drivers/hid/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/drivers/hid/drivers_hid_test.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/drivers/hid/it_test_hid.h create mode 100644 src/kernel_liteos_a/testsuites/unittest/drivers/hid/smoke/hid_test_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/drivers/storage/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/drivers/storage/drivers_storage_test.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/drivers/storage/it_test_storage.h create mode 100644 src/kernel_liteos_a/testsuites/unittest/drivers/storage/smoke/storage_test_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/BUILD.gn create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/ipc/It_test_IPC.h create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/ipc/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/ipc/full/ipc_test_mkfifoat_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/ipc/full/ipc_test_mkfifoat_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/ipc/ipc_test.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/liteipc/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/liteipc/it_test_liteipc.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/liteipc/it_test_liteipc.h create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/liteipc/liteipc.h create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/liteipc/smgr_demo.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/liteipc/smgr_demo.h create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/liteipc/smoke/liteipc_test_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/liteipc/smoke/liteipc_test_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/full/It_ipc_fdclr_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/full/It_ipc_fdset_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/full/It_ipc_fdzero_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/full/It_ipc_pipe_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/full/It_ipc_pipe_003.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/full/It_ipc_sigaction_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/full/It_ipc_sigpause_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/full/It_ipc_sigprocmask_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/full/pipe_test_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/full/pipe_test_003.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/full/pipe_test_005.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/full/pipe_test_006.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_003.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_004.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_005.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_006.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_007.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_008.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_010.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_011.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_012.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_015.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_016.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_017.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_018.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_019.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_020.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_025.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_026.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_028.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_029.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_030.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_033.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_038.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_040.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_041.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/it_test_signal.h create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/signal_test.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/It_ipc_fdisset_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/It_ipc_mkfifo_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/It_ipc_mkfifo_003.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/It_ipc_pipe_004.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/It_ipc_pipe_005.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/mkfifo_test_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/mkfifo_test_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/pipe_test_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/pipe_test_004.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_009.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_013.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_014.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_021.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_022.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_023.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_024.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_031.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_032.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_035.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_036.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_037.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_039.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_042.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/sigset_test_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/sigset_test_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/trace/It_test_trace.h create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/trace/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/trace/smoke/trace_test_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/trace/smoke/trace_test_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/trace/smoke/trace_test_003.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/trace/smoke/trace_test_004.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/extended/trace/trace_unit_test.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fs/BUILD.gn create mode 100644 src/kernel_liteos_a/testsuites/unittest/fs/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/BUILD.gn create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/adjtime_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/chroot_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/clone_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/epoll_create_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/epoll_ctl_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/epoll_wait_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/fesetenv_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/fuzzertest.h create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/getrlimit_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/main.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/mlock_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/mlockall_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawn_file_actions_addchdir_np_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawn_file_actions_adddup2_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawn_file_actions_addfchdir_np_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawn_file_actions_addopen_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawn_file_actions_destroy_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawn_file_actions_init_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawn_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_destroy_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_getflags_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_getpgroup_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_getschedparam_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_getschedpolicy_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_getsigdefault_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_getsigmask_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_init_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_setflags_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_setpgroup_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_setschedparam_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_setschedpolicy_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_setsigdefault_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_setsigmask_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnp_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/pthread_mutex_consistent_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/pthread_mutex_getprioceiling_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/pthread_mutexattr_setprotocol_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/pthread_mutexattr_setrobust_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/pthread_mutexattr_settype_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/pthread_setconcurrency_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/readlink_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/readlinkat_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/sem_open_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/sethostname_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/setns_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/syslog_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/system_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/times_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/fuzz/unshare_fuzzer.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/BUILD.gn create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/It_test_IO.h create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_confstr_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_dcgettext_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_dcgettext_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_dcngettext_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_dcngettext_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_dngettext_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_dngettext_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_duplocale_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_epoll_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_epoll_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_gettext_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_locale_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_locale_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_ngettext_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_nl_langinfo_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_nl_langinfo_l_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_ppoll_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_ppoll_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_ppoll_003.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_pselect_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_pselect_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_strcasecmp_l_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_strcasecmp_l_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_strfmon_l_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_strfmon_l_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_strncasecmp_l_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_strncasecmp_l_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_locale_localeconv_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdio_fputws_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdio_fwprintf_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdio_getc_unlocked_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdio_hasmntopt_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdio_mblen_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdio_mbrlen_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdio_putwc_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdio_readv_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdio_rindex_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdio_setlogmask_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdlib_gcvt_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdlib_poll_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdlib_poll_003.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/io_test.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/smoke/IO_test_005.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/smoke/IO_test_008.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/smoke/IO_test_010.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/io/smoke/IO_test_013.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/misc/BUILD.gn create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/misc/It_test_misc.h create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/misc/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/misc/full/misc_test_006.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/misc/full/misc_test_007.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/misc/full/misc_test_008.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/misc/full/misc_test_009.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/misc/full/misc_test_010.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/misc/full/misc_test_011.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/misc/full/misc_test_012.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/misc/full/misc_test_013.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/misc/misc_test.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/misc/smoke/misc_test_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/misc/smoke/misc_test_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/misc/smoke/misc_test_003.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/misc/smoke/misc_test_004.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/misc/smoke/misc_test_005.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/misc/smoke/misc_test_014.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/BUILD.gn create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mem/It_posix_mem.h create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mem/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mem/posix_mem_test.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mem/smoke/It_posix_mem_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mem/smoke/It_posix_mem_003.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/It_posix_queue.h create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_005.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_008.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_011.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_013.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_014.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_015.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_016.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_018.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_019.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_020.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_021.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_025.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_026.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_027.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_030.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_031.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_032.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_033.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_036.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_038.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_040.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_041.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_042.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_043.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_044.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_046.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_047.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_048.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_049.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_050.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_052.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_054.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_055.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_056.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_057.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_058.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_060.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_061.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_063.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_064.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_065.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_066.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_067.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_069.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_070.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_071.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_072.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_073.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_074.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_075.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_076.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_077.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_078.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_079.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_080.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_081.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_082.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_083.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_084.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_085.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_086.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_087.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_088.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_089.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_090.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_091.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_093.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_094.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_095.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_096.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_097.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_098.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_100.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_101.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_102.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_103.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_104.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_106.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_108.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_109.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_110.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_111.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_112.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_113.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_114.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_115.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_116.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_117.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_118.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_119.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_120.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_121.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_122.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_123.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_124.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_125.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_126.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_127.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_128.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_129.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_130.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_133.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_134.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_136.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_143.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_144.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_145.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_146.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_147.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_148.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_149.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_150.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_151.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_152.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_153.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_154.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_155.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_156.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_157.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_159.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_160.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_161.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_162.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_163.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_164.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_165.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_166.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_168.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_169.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_173.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_175.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_176.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_177.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_187.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_200.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_201.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_202.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_203.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_204.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_205.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_206.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_207.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_208.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_209.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/posix_mqueue_test.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/smoke/It_posix_queue_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/smoke/It_posix_queue_003.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/smoke/It_posix_queue_028.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/smoke/It_posix_queue_053.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/smoke/It_posix_queue_062.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/It_posix_pthread.h create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_007.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_010.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_011.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_013.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_023.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_025.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_026.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_027.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_028.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_029.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_030.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_031.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_034.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_035.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_039.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_040.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_042.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_044.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_045.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_046.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_051.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_052.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_053.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_054.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_055.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_057.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_059.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_060.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_061.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_062.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_063.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_064.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_066.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_069.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_070.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_071.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_072.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_073.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_074.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_078.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_079.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_080.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_081.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_082.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_083.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_084.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_085.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_087.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_088.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_089.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_090.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_091.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_092.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_094.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_095.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_106.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_107.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_116.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_123.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_124.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_125.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_127.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_129.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_132.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_133.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_134.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_136.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_138.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_141.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_142.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_144.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_152.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_154.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_166.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_167.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_173.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_175.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_176.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_177.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_182.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_185.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_186.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_187.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_188.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_193.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_194.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_200.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_203.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_204.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_205.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_206.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_209.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_213.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_217.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_218.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_219.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_221.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_224.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_226.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_233.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_238.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_239.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_240.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_241.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/posix_pthread_test.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/smoke/It_posix_pthread_003.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/smoke/It_posix_pthread_004.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/smoke/It_posix_pthread_005.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/smoke/It_posix_pthread_006.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/smoke/It_posix_pthread_018.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/smoke/It_posix_pthread_019.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/smoke/It_posix_pthread_020.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/smoke/It_posix_pthread_021.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/smoke/It_posix_pthread_022.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/sys/BUILD.gn create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/sys/It_test_sys.h create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/sys/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_018.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_019.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_020.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_021.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_022.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_023.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_024.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_025.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_026.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_027.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_028.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_004.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_005.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_006.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_007.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_008.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_009.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_010.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_012.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_013.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_014.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_015.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_016.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_017.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_029.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_030.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_031.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/sys/sys_unit_test.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/time/BUILD.gn create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/time/clock/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/time/clock/full/clock_test_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/time/clock/full/clock_test_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/time/clock/full/clock_test_003.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/time/clock/full/clock_test_004.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/time/clock/full/clock_test_005.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/time/clock/full/clock_test_006.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/time/clock/full/clock_test_007.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/time/clock/full/clock_test_008.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/time/clock/full/clock_test_009.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/time/clock/full/clock_test_010.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/time/clock/lt_clock_test.h create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/time/clock/smoke/clock_test_smoke.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/time/clock/time_clock_test.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/time/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/time/timer/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/time/timer/lt_timer_test.h create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/time/timer/smoke/timer_test_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/time/timer/smoke/timer_test_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/time/timer/smoke/timer_test_003.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/time/timer/smoke/timer_test_004.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/time/timer/smoke/timer_test_005.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/time/timer/smoke/timer_test_tzset_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/time/timer/smoke/timer_test_tzset_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/time/timer/time_timer_test.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/util/BUILD.gn create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/util/It_test_util.h create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/util/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/util/smoke/it_test_util_100.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/util/smoke/it_test_util_101.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/util/smoke/util_test_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/util/smoke/util_test_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/util/smoke/util_test_003.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/util/smoke/util_test_004.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/util/smoke/util_test_005.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/util/smoke/util_test_006.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/util/smoke/util_test_007.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/libc/util/util_test.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/BUILD.gn create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/netdb/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_003.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_004.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_005.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_006.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_007.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_008.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_009.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_010.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_011.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_012.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_015.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_016.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_017.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_018.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_019.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_020.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_021.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_022.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/netdb/lt_net_netdb.h create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/netdb/net_netdb_test.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/netdb/smoke/net_netdb_test_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/netdb/smoke/net_netdb_test_013.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/resolv/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/resolv/full/net_resolv_test_004.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/resolv/full/net_resolv_test_005.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/resolv/full/net_resolv_test_008.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/resolv/lt_net_resolv.h create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/resolv/net_resolv_test.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/resolv/smoke/net_resolv_test_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/resolv/smoke/net_resolv_test_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/resolv/smoke/net_resolv_test_003.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/resolv/smoke/net_resolv_test_006.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/resolv/smoke/net_resolv_test_007.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/socket/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/socket/lt_net_socket.h create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/socket/net_socket_test.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_003.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_004.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_005.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_006.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_007.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_008.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_009.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_010.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_011.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_012.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_013.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/BUILD.gn create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_007.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_031.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_032.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_033.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_034.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_035.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_036.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_037.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_040.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_041.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_042.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_049.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_050.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_051.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_052.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_053.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_055.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_056.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_057.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_058.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_059.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_060.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_062.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_063.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_064.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_065.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_066.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_067.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_068.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_069.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/it_test_process.h create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/process_process_test.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_004.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_005.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_006.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_008.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_009.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_010.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_011.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_012.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_013.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_014.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_015.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_016.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_017.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_018.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_019.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_020.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_021.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_022.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_023.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_024.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_025.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_026.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_027.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_029.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_030.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_038.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_039.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_043.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_044.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_045.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_046.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_047.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_048.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_054.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_061.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smp/process_test_smp_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smp/process_test_smp_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smp/process_test_smp_003.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smp/process_test_smp_004.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smp/process_test_smp_005.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smp/process_test_smp_006.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smp/process_test_smp_007.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/process/smp/process_test_smp_008.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/BUILD.gn create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/full/pthread_test_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/full/pthread_test_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/full/pthread_test_004.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/full/pthread_test_005.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/full/pthread_test_014.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/it_pthread_test.h create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/process_pthread_test.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_atfork_test_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_atfork_test_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_cond_test_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_cond_test_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_cond_test_003.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_cond_test_004.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_once_test_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_003.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_006.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_007.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_008.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_009.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_010.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_011.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_012.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_013.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_015.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_016.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_017.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_018.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_019.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_020.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_021.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_022.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_023.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_024.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_025.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_026.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_027.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/fs/BUILD.gn create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/fs/It_process_fs_test.h create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/fs/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/fs/process_fs_test.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_003.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_004.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_005.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_007.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_008.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_009.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_010.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_011.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_012.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_013.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_014.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_015.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_021.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_022.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/lock/BUILD.gn create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/lock/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/full/pthread_mutex_test_018.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/full/pthread_mutex_test_023.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/full/pthread_mutex_test_024.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/full/pthread_mutex_test_025.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/it_mutex_test.h create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/process_mutex_test.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_003.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_004.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_005.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_006.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_007.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_008.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_009.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_010.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_011.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_012.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_013.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_014.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_015.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_016.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_017.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_019.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_020.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_021.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_022.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/lock/rwlock/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/lock/rwlock/full/pthread_rwlock_test_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/lock/rwlock/it_rwlock_test.h create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/lock/rwlock/process_rwlock_test.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/lock/rwlock/smoke/pthread_rwlock_test_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/lock/spinlock/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/lock/spinlock/it_spinlock_test.h create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/lock/spinlock/process_spinlock_test.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/lock/spinlock/smoke/pthread_spinlock_test_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/BUILD.gn create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/It_process_plimits.h create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/process_plimits_test.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_003.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_004.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_005.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_006.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_007.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_008.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_devices_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_devices_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_devices_003.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_devices_004.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_devices_005.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_devices_006.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_devices_007.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_devices_008.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_devices_009.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_003.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_004.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_005.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_006.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_007.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_008.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_009.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_010.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_011.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_012.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_013.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_memory_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_memory_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_pid_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_pid_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_pid_003.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_pid_004.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_pid_005.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_pid_006.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_sched_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_sched_002.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_sched_003.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_sched_004.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/security/BUILD.gn create mode 100644 src/kernel_liteos_a/testsuites/unittest/security/capability/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/security/capability/it_test_capability.h create mode 100644 src/kernel_liteos_a/testsuites/unittest/security/capability/security_capability_test.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/security/capability/smoke/cap_test_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/security/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/security/reugid/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/security/reugid/it_test_reugid.h create mode 100644 src/kernel_liteos_a/testsuites/unittest/security/reugid/security_reugid_test.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/security/reugid/smoke/reugid_test_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/security/vid/config.gni create mode 100644 src/kernel_liteos_a/testsuites/unittest/security/vid/it_test_vid.h create mode 100644 src/kernel_liteos_a/testsuites/unittest/security/vid/security_vid_test.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/security/vid/smoke/vid_test_001.cpp create mode 100644 src/kernel_liteos_a/testsuites/unittest/tools/BUILD.gn create mode 100644 src/kernel_liteos_a/testsuites/unittest/tools/README.md create mode 100644 src/kernel_liteos_a/testsuites/unittest/tools/unittest_tools.cpp create mode 100644 src/kernel_liteos_a/tools/.gitignore create mode 100644 src/kernel_liteos_a/tools/build/liteos.ld create mode 100644 src/kernel_liteos_a/tools/build/liteos_llvm.ld create mode 100644 src/kernel_liteos_a/tools/build/mk/liteos_tables_ldflags.mk create mode 100644 src/kernel_liteos_a/tools/build/mk/los_config.mk create mode 100644 src/kernel_liteos_a/tools/build/mk/module.mk create mode 100644 src/kernel_liteos_a/tools/scripts/make_rootfs/releaseinfo.sh create mode 100644 src/kernel_liteos_a/tools/scripts/make_rootfs/rootfsdir.sh create mode 100644 src/kernel_liteos_a/tools/scripts/make_rootfs/rootfsimg.sh create mode 100644 src/kernel_liteos_a/tools/scripts/parse_exc/parse_excinfo.py create mode 100644 src/kernel_liteos_a/tools/scripts/parse_memory/parse_mem_info.sh diff --git a/src/kernel_liteos_a b/src/kernel_liteos_a deleted file mode 160000 index c2cb0435..00000000 --- a/src/kernel_liteos_a +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c2cb0435b290dbe0be3054aa904de7859e341fe9 diff --git a/src/kernel_liteos_a/.gitignore b/src/kernel_liteos_a/.gitignore new file mode 100644 index 00000000..c796d20f --- /dev/null +++ b/src/kernel_liteos_a/.gitignore @@ -0,0 +1,24 @@ +# General ignored file types +*.o +*.a +*.so +*.swp + +# IDE settings +.vscode +.idea +.settings +.cproject +.project + +# VIM files +cscope* +tags + +# Menuconfig temp files +/config.h +/.config +/.config.old + +# Build temp files +/out diff --git a/src/kernel_liteos_a/BUILD.gn b/src/kernel_liteos_a/BUILD.gn new file mode 100644 index 00000000..4ba2c2ff --- /dev/null +++ b/src/kernel_liteos_a/BUILD.gn @@ -0,0 +1,442 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//build/lite/config/component/lite_component.gni") + +LITEOS_MENUCONFIG_H = rebase_path("$root_out_dir/config.h") + +declare_args() { + tee_enable = false + liteos_name = "OHOS_Image" + liteos_container_enable = false + liteos_skip_make = false + liteos_is_mini = false +} + +tee = "" +if (tee_enable) { + tee = "_tee" +} + +declare_args() { + liteos_config_file = "${ohos_build_type}${tee}.config" +} + +liteos_config_file = + rebase_path(liteos_config_file, "", "$product_path/kernel_configs") +print("liteos_config_file:", liteos_config_file) + +exec_script("//build/lite/run_shell_cmd.py", + [ "env" + " CONFIG_=LOSCFG_" + " KCONFIG_CONFIG_HEADER='y=true'" + + " KCONFIG_CONFIG=$liteos_config_file" + + " DEVICE_PATH=$device_path" + " srctree=" + rebase_path(".") + + " genconfig" + " --header-path $LITEOS_MENUCONFIG_H" + + " --file-list kconfig_files.txt" + + " --env-list kconfig_env.txt" + " --config-out config.gni" ], + "", + [ liteos_config_file ]) + +import("liteos.gni") + +assert(ARCH != "", "ARCH not set!") +assert(ARCH == arch, "ARCH not match! details: $ARCH != $arch") +assert(tee_enable == defined(LOSCFG_TEE_ENABLE), "TEE switch not match!") +assert(ohos_build_compiler == "clang" == defined(LOSCFG_COMPILER_CLANG_LLVM), + "compiler not match!") + +generate_notice_file("kernel_notice_file") { + module_name = "kernel" + module_source_dir_list = [ + "$LITEOSTHIRDPARTY/FreeBSD", + "$LITEOSTHIRDPARTY/musl", + "$LITEOSTHIRDPARTY/zlib", + "$LITEOSTHIRDPARTY/FatFs", + "$LITEOSTHIRDPARTY/lwip", + "$LITEOSTHIRDPARTY/NuttX", + "$LITEOSTHIRDPARTY/mtd-utils", + ] +} + +liteos_arch_cflags = [] +if (defined(LOSCFG_ARCH_ARM)) { + mcpu = LOSCFG_ARCH_CPU + if (defined(LOSCFG_ARCH_ARM_AARCH64) && defined(LOSCFG_ARCH_FPU_DISABLE)) { + mcpu += "+nofp" + } + liteos_arch_cflags += [ "-mcpu=$mcpu" ] + if (defined(LOSCFG_ARCH_ARM_AARCH32)) { + liteos_arch_cflags += [ + "-mfloat-abi=softfp", + "-mfpu=$LOSCFG_ARCH_FPU", + ] + } +} + +cc = "$ohos_current_cc_command " + string_join(" ", liteos_arch_cflags) +if (ohos_build_compiler == "clang") { + cc += " --target=$target_triple" +} + +config("arch_config") { + cflags = liteos_arch_cflags + asmflags = cflags + ldflags = cflags + if (defined(LOSCFG_ARCH_ARM_AARCH32)) { + if (!defined(LOSCFG_COMPILER_CLANG_LLVM)) { + cflags += [ "-mthumb-interwork" ] + } + } + if (defined(LOSCFG_THUMB)) { + cflags += [ "-mthumb" ] + if (defined(LOSCFG_COMPILER_CLANG_LLVM)) { + cflags += [ "-mimplicit-it=thumb" ] + } else { + cflags += [ "-Wa,-mimplicit-it=thumb" ] + } + } +} + +config("stdinc_config") { + std_include = exec_script("//build/lite/run_shell_cmd.py", + [ "$cc -print-file-name=include" ], + "trim string") + cflags = [ + "-isystem", + std_include, + ] + if (!defined(LOSCFG_LIBC_NEWLIB)) { + cflags += [ "-nostdinc" ] + } + asmflags = cflags +} + +config("ssp_config") { + cflags = [] + if (defined(LOSCFG_CC_STACKPROTECTOR_ALL)) { + cflags += [ "-fstack-protector-all" ] + } else if (defined(LOSCFG_CC_STACKPROTECTOR_STRONG)) { + cflags += [ "-fstack-protector-strong" ] + } else if (defined(LOSCFG_CC_STACKPROTECTOR)) { + cflags += [ + "-fstack-protector", + "--param", + "ssp-buffer-size=4", + ] + } else { + cflags += [ "-fno-stack-protector" ] + } + asmflags = cflags +} + +config("optimize_config") { + cflags = [] + if (defined(LOSCFG_COMPILE_DEBUG)) { + cflags += [ + "-g", + "-gdwarf-2", + ] + optimization_cflag = "-O0" + } + if (defined(LOSCFG_COMPILE_OPTIMIZE)) { + optimization_cflag = "-O2" + } + if (defined(LOSCFG_COMPILE_OPTIMIZE_SIZE)) { + if (defined(LOSCFG_COMPILER_CLANG_LLVM)) { + optimization_cflag = "-Oz" + } else { + optimization_cflag = "-Os" + } + } + if (defined(LOSCFG_COMPILE_LTO)) { + if (defined(LOSCFG_COMPILER_CLANG_LLVM)) { + cflags += [ "-flto=thin" ] + } else { + #cflags += [ "-flto" ] + } + } + cflags += [ optimization_cflag ] + asmflags = cflags +} + +config("kconfig_config") { + cflags = [ + "-imacros", + "$LITEOS_MENUCONFIG_H", + ] + asmflags = cflags +} + +config("warn_config") { + cflags = [ + "-Wall", + "-Werror", + "-Wpointer-arith", + "-Wstrict-prototypes", + "-Winvalid-pch", + ] + if (defined(LOSCFG_COMPILER_CLANG_LLVM)) { + cflags += [ "-Wno-address-of-packed-member" ] + cflags += [ + "-Wno-unused-but-set-variable", + "-Wno-strict-prototypes", + ] + } + asmflags = cflags +} + +config("dialect_config") { + cflags_c = [ "-std=c99" ] + cflags_cc = [ "-std=c++11" ] +} + +config("misc_config") { + defines = [ "__LITEOS__" ] + defines += [ "__LITEOS_A__" ] + if (!defined(LOSCFG_DEBUG_VERSION)) { + defines += [ "NDEBUG" ] + } + + cflags = [ + "-fno-pic", + "-fno-builtin", + "-fms-extensions", + "-fno-strict-aliasing", + "-fno-common", + "-fsigned-char", + "-ffunction-sections", + "-fdata-sections", + "-fno-exceptions", + "-fno-omit-frame-pointer", + "-fno-short-enums", + "-mno-unaligned-access", + ] + + if (!defined(LOSCFG_COMPILER_CLANG_LLVM)) { + cflags += [ "-fno-aggressive-loop-optimizations" ] + } + + asmflags = cflags +} + +config("container_config") { + if (liteos_container_enable) { + cflags = [ + "-DLOSCFG_KERNEL_CONTAINER", + "-DLOSCFG_PID_CONTAINER", + "-DLOSCFG_UTS_CONTAINER", + "-DLOSCFG_MNT_CONTAINER", + "-DLOSCFG_CHROOT", + "-DLOSCFG_IPC_CONTAINER", + "-DLOSCFG_TIME_CONTAINER", + "-DLOSCFG_USER_CONTAINER", + "-DLOSCFG_NET_CONTAINER", + "-DLOSCFG_PROC_PROCESS_DIR", + "-DLOSCFG_KERNEL_PLIMITS", + "-DLOSCFG_KERNEL_MEM_PLIMIT", + "-DLOSCFG_KERNEL_IPC_PLIMIT", + "-DLOSCFG_KERNEL_DEV_PLIMIT", + "-DLOSCFG_KERNEL_SCHED_PLIMIT", + ] + } +} + +config("los_config") { + configs = [ + ":arch_config", + ":kconfig_config", + ":stdinc_config", + ":dialect_config", + ":optimize_config", + ":ssp_config", + ":warn_config", + ":misc_config", + ":container_config", + ] +} + +cmd = "if [ -f $device_path/BUILD.gn ]; then echo true; else echo false; fi" +HAVE_DEVICE_SDK = exec_script("//build/lite/run_shell_cmd.py", [ cmd ], "value") + +config("public") { + configs = [ + "arch:public", + "kernel:public", + "compat:public", + "bsd:public", + "fs:public", + "drivers:public", + "security:public", + "net:public", + "shell:public", + "lib:public", + ] + + configs += [ + "$HDFTOPDIR:public", + "$DRIVERS_LITEOS_DIR:public", + ] + + if (HAVE_DEVICE_SDK) { + configs += [ "$device_path:public" ] + } +} + +group("modules") { + deps = [ + "arch", + "bsd", + "compat", + "drivers", + "fs", + "kernel", + "lib", + "net", + "security", + "shell", + "syscall", + "testsuites/kernel:kernel_test", + ] + + deps += [ + "$DRIVERS_LITEOS_DIR", + "$HDFTOPDIR", + ] + + if (HAVE_DEVICE_SDK) { + deps += [ device_path ] + } +} + +group("apps") { + deps = [ "apps" ] +} + +group("tests") { + deps = [ "testsuites" ] +} + +group("kernel") { + deps = [ ":build_kernel_image" ] +} + +group("liteos_a") { + deps = [ ":kernel" ] + if (!liteos_is_mini) { + deps += [ + ":apps", + ":tests", + "$THIRDPARTY_MUSL_DIR/scripts/build_lite:strip", + ] + if (liteos_skip_make == false) { + deps += [ ":make" ] + } + } +} + +executable("liteos") { + configs = [] # clear default configs + configs += [ ":arch_config" ] + configs += [ ":public" ] + + ldflags = [ + "-static", + "-nostdlib", + "-Wl,--gc-sections", + "-Wl,-Map=$liteos_name.map", + "-Wl,--no-eh-frame-hdr", + ] + + if (defined(LOSCFG_LIBC_NEWLIB)) { + ldflags += [ + "-Wl,--wrap=_free_r", + "-Wl,--wrap,_malloc_usable_size_r", + "-Wl,--wrap,_malloc_r", + "-Wl,--wrap,_memalign_r", + "-Wl,--wrap,_realloc_r", + "-Wl,--wrap,_fseeko_r", + ] + ldflags -= [ "-nostdlib" ] + } + libgcc = exec_script("//build/lite/run_shell_cmd.py", + [ "$cc -print-libgcc-file-name" ], + "trim string") + libs = [ libgcc ] + if (defined(LOSCFG_COMPILER_CLANG_LLVM)) { + ldflags += + [ "-Wl,-T" + rebase_path("tools/build/liteos_llvm.ld", root_build_dir) ] + inputs = [ "tools/build/liteos_llvm.ld" ] + } else { + ldflags += + [ "-Wl,-T" + rebase_path("tools/build/liteos.ld", root_build_dir) ] + ldflags += [ "-nostartfiles" ] + inputs = [ "tools/build/liteos.ld" ] + } + + inputs += [ "$root_out_dir/board.ld" ] + + output_dir = target_out_dir + + deps = [ + ":modules", + "platform:copy_board.ld", + ] +} + +copy("copy_liteos") { + deps = [ ":liteos" ] + sources = [ "$target_out_dir/unstripped/bin/liteos" ] + outputs = [ "$root_out_dir/$liteos_name" ] +} + +build_ext_component("build_kernel_image") { + deps = [ ":copy_liteos" ] + exec_path = rebase_path(root_out_dir) + + objcopy = "${compile_prefix}objcopy$toolchain_cmd_suffix" + objdump = "${compile_prefix}objdump$toolchain_cmd_suffix" + + command = "$objcopy -O binary $liteos_name $liteos_name.bin" + command += + " && sh -c '$objdump -t $liteos_name | sort >$liteos_name.sym.sorted'" + command += " && sh -c '$objdump -d $liteos_name >$liteos_name.asm'" +} + +build_ext_component("make") { + exec_path = rebase_path(".", root_build_dir) + outdir = rebase_path("$target_out_dir/${target_name}_out") + sysroot_path = rebase_path(ohos_current_sysroot) + arch_cflags = string_join(" ", target_arch_cflags) + command = "./build.sh \"$board_name\" \"$ohos_build_compiler\" \"$root_build_dir\" \"$ohos_build_type\" \"$tee_enable\"" + command += " \"$device_company\" \"$product_path\" \"$outdir\" \"$ohos_version\" \"$sysroot_path\" \"$arch_cflags\"" + command += " \"$device_path\" \"$compile_prefix\" \"$liteos_config_file\"" + if (liteos_skip_make) { + print("build_ext_component \"$target_name\" skipped:", command) + command = "true" + } +} diff --git a/src/kernel_liteos_a/CHANGELOG.md b/src/kernel_liteos_a/CHANGELOG.md new file mode 100644 index 00000000..eaa49a85 --- /dev/null +++ b/src/kernel_liteos_a/CHANGELOG.md @@ -0,0 +1,338 @@ +# (2022-03-30) + + +### Bug Fixes + + +* **arm-virt:** HW_RANDOM_ENABLE配置支持arm virt平台 ([68f9f49](https://gitee.com/openharmony/kernel_liteos_a/commits/68f9f49c2a62d3271db14ccb896c9f9fc78a60e4)) +* A核代码静态告警定期清理 ([9ba725c](https://gitee.com/openharmony/kernel_liteos_a/commits/9ba725c3d486dd28fe9b2489b0f95a65354d7d86)), closes [#I4I0O8](https://gitee.com/openharmony/kernel_liteos_a/issues/I4I0O8) +* change default permission of procfs to 0550 ([a776c04](https://gitee.com/openharmony/kernel_liteos_a/commits/a776c04a3da414f73ef7136a543c029cc6dd75be)), closes [#I4NY49](https://gitee.com/openharmony/kernel_liteos_a/issues/I4NY49) +* change the execFile field in TCB to execVnode ([e4a0662](https://gitee.com/openharmony/kernel_liteos_a/commits/e4a06623ceb49b5bead60d45c0534db88b9c666f)), closes [#I4CLL9](https://gitee.com/openharmony/kernel_liteos_a/issues/I4CLL9) +* close file when process interpretor failed ([a375bf5](https://gitee.com/openharmony/kernel_liteos_a/commits/a375bf5668a5e86e082d0e124b538e423023a259)), closes [#I4ATQX](https://gitee.com/openharmony/kernel_liteos_a/issues/I4ATQX) +* codex 清理 ([9ab3e35](https://gitee.com/openharmony/kernel_liteos_a/commits/9ab3e351d38cdae2ec083048a50a253bc2a3b604)), closes [#I4BL3S](https://gitee.com/openharmony/kernel_liteos_a/issues/I4BL3S) +* dyload open close failed ([5e87d8c](https://gitee.com/openharmony/kernel_liteos_a/commits/5e87d8c183471166294e2caa041ab4da8570c6a1)), closes [#I452Z7](https://gitee.com/openharmony/kernel_liteos_a/issues/I452Z7) +* fix ppoll ([a55f68f](https://gitee.com/openharmony/kernel_liteos_a/commits/a55f68f957e9f8ad74bd9e0c1b3d27775e0f8c75)) +* fix some function declarations ([63fd8bc](https://gitee.com/openharmony/kernel_liteos_a/commits/63fd8bc39b21fffb6990f74e879eefecafad6c88)) +* implicit declaration of function 'syscall' in apps/shell ([bd0c083](https://gitee.com/openharmony/kernel_liteos_a/commits/bd0c0835fc58ed5f941dbbc9adfac74253eeb874)) +* LOS_Panic和魔法键功能中的使用PRINTK打印,依赖任务调度,特殊情况下存在打印不出来的问题 ([53addea](https://gitee.com/openharmony/kernel_liteos_a/commits/53addea304de09e0df457b690403ac652bbcea72)), closes [#I4NOC7](https://gitee.com/openharmony/kernel_liteos_a/issues/I4NOC7) +* los_stat_pri.h中缺少依赖的头文件 ([2cd03c5](https://gitee.com/openharmony/kernel_liteos_a/commits/2cd03c55b7a614c648adc965ebfe494d491fe20f)), closes [#I4KEZ1](https://gitee.com/openharmony/kernel_liteos_a/issues/I4KEZ1) +* los_trace.h接口注释错误修正 ([6d24961](https://gitee.com/openharmony/kernel_liteos_a/commits/6d249618aecc216388f9b1a2b48fe0ac6dd19ff2)), closes [#I4CYPZ](https://gitee.com/openharmony/kernel_liteos_a/issues/I4CYPZ) +* MMU竞态问题修复 ([748e0d8](https://gitee.com/openharmony/kernel_liteos_a/commits/748e0d8ffb6ee9c8757ed056f575e3abc6c10702)), closes [#I2WARC](https://gitee.com/openharmony/kernel_liteos_a/issues/I2WARC) +* **mtd:** 去除mtd对hisilicon驱动的依赖 ([f7d010d](https://gitee.com/openharmony/kernel_liteos_a/commits/f7d010dfa4cb825096267528e131a9e2735d7505)), closes [#I49FKL](https://gitee.com/openharmony/kernel_liteos_a/issues/I49FKL) +* OsFutexWaitParamCheck函数中absTime为0时,直接返回,不需要打印 ([3f71be7](https://gitee.com/openharmony/kernel_liteos_a/commits/3f71be75355f11037d9de80cc4d7da0f01905003)), closes [#I4D67E](https://gitee.com/openharmony/kernel_liteos_a/issues/I4D67E) +* OsLockDepCheckIn异常处理中存在g_lockdepAvailable锁嵌套调用, ([bf030b6](https://gitee.com/openharmony/kernel_liteos_a/commits/bf030b6bb5843151a5b8b8736246a1376a5fb9d0)), closes [#I457ZZ](https://gitee.com/openharmony/kernel_liteos_a/issues/I457ZZ) +* pr模板补充说明 ([e3cd485](https://gitee.com/openharmony/kernel_liteos_a/commits/e3cd485db528490a16a8932d734faab263b44bc9)) +* same file mode for procfs files ([c79bcd0](https://gitee.com/openharmony/kernel_liteos_a/commits/c79bcd028e1be34b45cba000077230fa2ef95e68)), closes [#I4ACTC](https://gitee.com/openharmony/kernel_liteos_a/issues/I4ACTC) +* shell支持exit退出,完善帮助信息,特殊处理不可见字符 ([cc6e112](https://gitee.com/openharmony/kernel_liteos_a/commits/cc6e11281e63b6bdc9be8e5d3c39f1258eb2ceaa)) +* smp初始化中副核冗余的启动框架调用 ([5ce70a5](https://gitee.com/openharmony/kernel_liteos_a/commits/5ce70a50c3733b6ec8cc4b444837e366ec837f69)), closes [#I4F8A5](https://gitee.com/openharmony/kernel_liteos_a/issues/I4F8A5) +* solve SIGCHLD ignored in sigsuspend() ([5a80d4e](https://gitee.com/openharmony/kernel_liteos_a/commits/5a80d4e1a34c94204a0bb01443bf25a4fdb12750)), closes [#I47CKK](https://gitee.com/openharmony/kernel_liteos_a/issues/I47CKK) +* syscall review bugfix ([214f44e](https://gitee.com/openharmony/kernel_liteos_a/commits/214f44e935277c29d347c50b553a31ea7df36448)), closes [#149](https://gitee.com/openharmony/kernel_liteos_a/issues/149) +* **test:** misc09用例因依赖hosts文件而失败 ([f2f5c5f](https://gitee.com/openharmony/kernel_liteos_a/commits/f2f5c5fdc3202610de173e7046adab4df5e59142)), closes [#I48IZ0](https://gitee.com/openharmony/kernel_liteos_a/issues/I48IZ0) +* **test:** 修复sys部分用例因依赖passwd、group文件而失败 ([614cdcc](https://gitee.com/openharmony/kernel_liteos_a/commits/614cdccf91bd2d220c4c76418b53400ce714c6cb)), closes [#I48IUC](https://gitee.com/openharmony/kernel_liteos_a/issues/I48IUC) +* 中断中调用PRINTK概率卡死,导致系统不能正常响应中断 ([9726ba1](https://gitee.com/openharmony/kernel_liteos_a/commits/9726ba11a79f3d2d1e616e12ef0bb44e4fc5cd20)), closes [#I4C9GC](https://gitee.com/openharmony/kernel_liteos_a/issues/I4C9GC) +* 临终遗言重定向内容缺失task相关信息,对应的shell命令中申请的内存需要cacheline对齐 ([48ca854](https://gitee.com/openharmony/kernel_liteos_a/commits/48ca854bf07f8dcda9657f950601043a485a1b33)), closes [#I482S5](https://gitee.com/openharmony/kernel_liteos_a/issues/I482S5) +* 优化liteipc任务状态,删除功能重复字段 ([5004ef4](https://gitee.com/openharmony/kernel_liteos_a/commits/5004ef4d87b54fb6d7f748ca8212ae155bcefac5)), closes [#I4FVHK](https://gitee.com/openharmony/kernel_liteos_a/issues/I4FVHK) +* 优化trace buffer初始化,删除swtmr 桩中的无效参数 ([b551270](https://gitee.com/openharmony/kernel_liteos_a/commits/b551270ef50cb206360e2eee3dd20ace5cecccb7)), closes [#I4DQ1X](https://gitee.com/openharmony/kernel_liteos_a/issues/I4DQ1X) +* 修复 virpart.c 不适配的格式化打印问题 ([de29140](https://gitee.com/openharmony/kernel_liteos_a/commits/de29140edf2567f4847876cb1ed5e0b6857420f3)), closes [#I4PEVP](https://gitee.com/openharmony/kernel_liteos_a/issues/I4PEVP) +* 修复A核文档失效的问题 ([456d255](https://gitee.com/openharmony/kernel_liteos_a/commits/456d255a81c2031be8ebecc2bf897af80c3d3c7a)), closes [#I4U7TF](https://gitee.com/openharmony/kernel_liteos_a/issues/I4U7TF) +* 修复A核测试用例失败的问题 ([59329ce](https://gitee.com/openharmony/kernel_liteos_a/commits/59329ce7c6b6a00084df427748e6283287a773c0)), closes [#I4SQDR](https://gitee.com/openharmony/kernel_liteos_a/issues/I4SQDR) +* 修复A核测试用例失败的问题 ([be68dc8](https://gitee.com/openharmony/kernel_liteos_a/commits/be68dc8bcaf8d965039ae1d792775f00a08adfac)), closes [#I4SQDP](https://gitee.com/openharmony/kernel_liteos_a/issues/I4SQDP) +* 修复dispatch单词拼写错误。 ([9b07aec](https://gitee.com/openharmony/kernel_liteos_a/commits/9b07aece2dfa3494cf35e8b388410341508d6224)), closes [#I4BLE8](https://gitee.com/openharmony/kernel_liteos_a/issues/I4BLE8) +* 修复futime提示错误22的BUG ([f2861dd](https://gitee.com/openharmony/kernel_liteos_a/commits/f2861ddfb424af7b99c278273601ce0fab1f37e6)) +* 修复jffs2适配层错误释放锁的BUG ([011a55f](https://gitee.com/openharmony/kernel_liteos_a/commits/011a55ff21d95f969abac60bcff96f4c4d7a326d)), closes [#I4FH9M](https://gitee.com/openharmony/kernel_liteos_a/issues/I4FH9M) +* 修复los_vm_scan.c中内部函数OsInactiveListIsLow冗余代码 ([bc32a1e](https://gitee.com/openharmony/kernel_liteos_a/commits/bc32a1ec0fa5d19c6d2672bcf4a01de5e1be3afb)), closes [#I4HKFF](https://gitee.com/openharmony/kernel_liteos_a/issues/I4HKFF) +* 修复LOSCFG_FS_FAT_CACHE宏关闭后编译失败的BUG ([63e71fe](https://gitee.com/openharmony/kernel_liteos_a/commits/63e71feca05a8d46a49822c713258738740f0712)), closes [#I3T3N0](https://gitee.com/openharmony/kernel_liteos_a/issues/I3T3N0) +* 修复OsVmPhysFreeListAdd和OsVmPhysFreeListAddUnsafe函数内容重复 ([6827bd2](https://gitee.com/openharmony/kernel_liteos_a/commits/6827bd2a22b78aa05e20d6460412fc7b2d738929)), closes [#I4FL95](https://gitee.com/openharmony/kernel_liteos_a/issues/I4FL95) +* 修复PR520缺陷 ([4033891](https://gitee.com/openharmony/kernel_liteos_a/commits/40338918d9132399ee0494d331930a05b7a13c67)), closes [#I4DEG5](https://gitee.com/openharmony/kernel_liteos_a/issues/I4DEG5) +* 修复shcmd.h需要用宏包起来的问题 ([6c4e4b1](https://gitee.com/openharmony/kernel_liteos_a/commits/6c4e4b16abe9c68fea43d40b2d39b4f0ed4bfc9c)), closes [#I4N50W](https://gitee.com/openharmony/kernel_liteos_a/issues/I4N50W) +* 修复xts权限用例压测异常问题 ([b0d31cb](https://gitee.com/openharmony/kernel_liteos_a/commits/b0d31cb43f5a8d1c3da574b2b957e3b0e98b3067)), closes [#I3ZJ1D](https://gitee.com/openharmony/kernel_liteos_a/issues/I3ZJ1D) +* 修复硬随机不可用时,地址随机化不可用问题 ([665c152](https://gitee.com/openharmony/kernel_liteos_a/commits/665c152c27bb86395ddd0395279255f6cdaf7255)), closes [#I4D4TK](https://gitee.com/openharmony/kernel_liteos_a/issues/I4D4TK) +* 修复进程用例导致门禁概率失败 ([1ed28b4](https://gitee.com/openharmony/kernel_liteos_a/commits/1ed28b4c80cfd222be08b0c2e71e6287e52bb276)), closes [#I4FO0N](https://gitee.com/openharmony/kernel_liteos_a/issues/I4FO0N) +* 修复进程线程不稳定用例 ([f6ac03d](https://gitee.com/openharmony/kernel_liteos_a/commits/f6ac03d3e3c56236adc5734d4c059f1fbcc9e0c1)), closes [#I4F1XL](https://gitee.com/openharmony/kernel_liteos_a/issues/I4F1XL) +* 修复重复执行内存用例导致系统卡死问题 ([6c2b163](https://gitee.com/openharmony/kernel_liteos_a/commits/6c2b163c7d7c696ef89b17a0275f3cddb3d7cefb)), closes [#I4F7PO](https://gitee.com/openharmony/kernel_liteos_a/issues/I4F7PO) +* 修改MMU模块的注释错误 ([1a8e22d](https://gitee.com/openharmony/kernel_liteos_a/commits/1a8e22dcf15944153e013d004fd7bbf24557a8c7)), closes [#I4KMMJ](https://gitee.com/openharmony/kernel_liteos_a/issues/I4KMMJ) +* 共享内存问题修复 ([9fdb80f](https://gitee.com/openharmony/kernel_liteos_a/commits/9fdb80f85f92d0167a0456455a94fc6f679797ce)), closes [#I47X2Z](https://gitee.com/openharmony/kernel_liteos_a/issues/I47X2Z) +* 内核ERR打印,无进程和线程信息,不方便问题定位。 ([cb423f8](https://gitee.com/openharmony/kernel_liteos_a/commits/cb423f845462b8cc474c3cba261dadf3943a08ef)), closes [#I4DAKM](https://gitee.com/openharmony/kernel_liteos_a/issues/I4DAKM) +* 内核ERR级别及以上的打印输出当前进程和线程名 ([540b201](https://gitee.com/openharmony/kernel_liteos_a/commits/540b2017c5460e300365d2039a08abd5945cec6b)) +* 内源检视测试用例问题修复 ([a6ac759](https://gitee.com/openharmony/kernel_liteos_a/commits/a6ac7597f85043ba6de3a1b395ca676d85c65ea7)) +* 删除冗余的头文件 ([8e614bb](https://gitee.com/openharmony/kernel_liteos_a/commits/8e614bb1616b75bc89eee7ad7da49b7a9c285b47)), closes [#I4KN63](https://gitee.com/openharmony/kernel_liteos_a/issues/I4KN63) +* 增加pselect SYSCALL函数及测试用例 ([f601c16](https://gitee.com/openharmony/kernel_liteos_a/commits/f601c16b9e67d531dda51fc18389a53db4360b7b)), closes [#I45SXU](https://gitee.com/openharmony/kernel_liteos_a/issues/I45SXU) +* 增加内核epoll系统调用 ([2251b8a](https://gitee.com/openharmony/kernel_liteos_a/commits/2251b8a2d1f649422dd67f8551b085a7e0c63ec7)), closes [#I4FXPT](https://gitee.com/openharmony/kernel_liteos_a/issues/I4FXPT) +* 实现了musl库net模块中的一些函数接口和相应的测试用例 ([3d00a7d](https://gitee.com/openharmony/kernel_liteos_a/commits/3d00a7d23a96f29c138cfc1672825b90b9e0c05e)), closes [#I4JQI1](https://gitee.com/openharmony/third_party_musl/issues/I4JQI1) +* 添加进程线程冒烟用例 ([2be5968](https://gitee.com/openharmony/kernel_liteos_a/commits/2be59680f2fb0801b43522cd38cc387c8ff38766)), closes [#I4EOGA](https://gitee.com/openharmony/kernel_liteos_a/issues/I4EOGA) +* 用户态进程主线程退出时,其他子线程刚好进入异常处理流程会导致系统卡死 ([d955790](https://gitee.com/openharmony/kernel_liteos_a/commits/d955790a44a679421798ec1ac2900b4d75dd75a4)), closes [#I4KGBT](https://gitee.com/openharmony/kernel_liteos_a/issues/I4KGBT) +* 编码规范修改 ([d161a0b](https://gitee.com/openharmony/kernel_liteos_a/commits/d161a0b03de046c05fff45a2b625631b4e45a347)) +* 编码规范问题修复 ([f60bc94](https://gitee.com/openharmony/kernel_liteos_a/commits/f60bc94cf231bc615ff6603ca0393b8fe33a8c47)) +* 编译框架在做编译入口的统一 ([bdb9864](https://gitee.com/openharmony/kernel_liteos_a/commits/bdb9864436a6f128a4c3891bbd63e3c60352689f)), closes [#I4KRQN](https://gitee.com/openharmony/kernel_liteos_a/issues/I4KRQN) +* 解决dmesg -s参数double lock问题 ([e151256](https://gitee.com/openharmony/kernel_liteos_a/commits/e1512566e322eb1fbc8f5d5997f9bfcd022feac7)), closes [#I4HIJK](https://gitee.com/openharmony/kernel_liteos_a/issues/I4HIJK) +* 进程退出前自己回收vmspace中的所有region ([298ccea](https://gitee.com/openharmony/kernel_liteos_a/commits/298ccea3fedaccc651b38973f0455fa1ce12e516)), closes [#I4CKQC](https://gitee.com/openharmony/kernel_liteos_a/issues/I4CKQC) +* 通过g_uart_fputc_en关闭打印后,shell进程不能正常启动 ([d21b05c](https://gitee.com/openharmony/kernel_liteos_a/commits/d21b05c0f69877130366ad37b852a0f30c11809d)), closes [#I4CTY2](https://gitee.com/openharmony/kernel_liteos_a/issues/I4CTY2) +* 针对pr是否同步至release分支,增加原因说明规则 ([b37a7b7](https://gitee.com/openharmony/kernel_liteos_a/commits/b37a7b79292d93dae6c4914952b5f3bb509e8721)) +* 非当前进程销毁时,销毁liteipc时错误的销毁了当前进程的liteipc资源 ([0f0e85b](https://gitee.com/openharmony/kernel_liteos_a/commits/0f0e85b7a6bf76d540925fbf661c483c8dba1cba)), closes [#I4FSA7](https://gitee.com/openharmony/kernel_liteos_a/issues/I4FSA7) + + +### Code Refactoring + +* los_cir_buf.c中接口整合 ([0d325c5](https://gitee.com/openharmony/kernel_liteos_a/commits/0d325c56a1053043db05d53a6c8083f4d35f116b)), closes [#I4MC13](https://gitee.com/openharmony/kernel_liteos_a/issues/I4MC13) + + +### Features + + +* add option SIOCGIFBRDADDR for ioctl ([4ecc473](https://gitee.com/openharmony/kernel_liteos_a/commits/4ecc473843207d259613d26b8ee176d75e7f00fd)), closes [#I4DNRF](https://gitee.com/openharmony/kernel_liteos_a/issues/I4DNRF) +* add sync() to vfs ([f67c4da](https://gitee.com/openharmony/kernel_liteos_a/commits/f67c4dae5141914df2e069dce0196b14780649d8)), closes [#I480HV](https://gitee.com/openharmony/kernel_liteos_a/issues/I480HV) +* **build:** support gcc toolchain ([6e886d4](https://gitee.com/openharmony/kernel_liteos_a/commits/6e886d4233dec3b82a27642f174b920e5f98f6aa)) +* L0-L1 支持Perf ([6e0a3f1](https://gitee.com/openharmony/kernel_liteos_a/commits/6e0a3f10bbbfe29d110c050da927684b6d77b961)), closes [#I47I9A](https://gitee.com/openharmony/kernel_liteos_a/issues/I47I9A) +* L0~L1 支持Lms ([e748fdb](https://gitee.com/openharmony/kernel_liteos_a/commits/e748fdbe578a1ddd8eb10b2e207042676231ba26)), closes [#I4HYAV](https://gitee.com/openharmony/kernel_liteos_a/issues/I4HYAV) +* liteipc 静态内存优化 ([5237924](https://gitee.com/openharmony/kernel_liteos_a/commits/52379242c109e0cf442784dbe811ff9d42d5f33a)), closes [#I4G4HP](https://gitee.com/openharmony/kernel_liteos_a/issues/I4G4HP) +* page cache backed by vnode instead of filep ([38a6b80](https://gitee.com/openharmony/kernel_liteos_a/commits/38a6b804e9291d2fdbd189825ebd7d56165ec51c)), closes [#I44TBS](https://gitee.com/openharmony/kernel_liteos_a/issues/I44TBS) +* 提供低功耗默认处理框架 ([212d1bd](https://gitee.com/openharmony/kernel_liteos_a/commits/212d1bd1e806530fe7e7a16ea986cb2c6fb084ed)), closes [#I4KBG9](https://gitee.com/openharmony/kernel_liteos_a/issues/I4KBG9) +* 支持AT_RANDOM以增强用户态栈保护能力 ([06ea037](https://gitee.com/openharmony/kernel_liteos_a/commits/06ea03715f0cfb8728fadd0d9c19a403dc8f6028)), closes [#I4CB8M](https://gitee.com/openharmony/kernel_liteos_a/issues/I4CB8M) +* 支持L1 低功耗框架 ([64e49ab](https://gitee.com/openharmony/kernel_liteos_a/commits/64e49aba7c9c7d2280c5b3f29f04b17b63209855)), closes [#I4JSOT](https://gitee.com/openharmony/kernel_liteos_a/issues/I4JSOT) +* 支持LOS_TaskJoin 和 LOS_TaskDetach ([37bc11f](https://gitee.com/openharmony/kernel_liteos_a/commits/37bc11fa8837a3019a0a56702f401ec1845f6547)), closes [#I4EENF](https://gitee.com/openharmony/kernel_liteos_a/issues/I4EENF) +* 新增解析异常和backtrace信息脚本 ([7019fdf](https://gitee.com/openharmony/kernel_liteos_a/commits/7019fdfcbb33c660e8aa9fd399d5fccbd7e23b49)), closes [#I47EVQ](https://gitee.com/openharmony/kernel_liteos_a/issues/I47EVQ) +* 调度tick响应时间计算优化 ([f47da44](https://gitee.com/openharmony/kernel_liteos_a/commits/f47da44b39be7fa3e9b5031d7b79b9bef1fd4fbc)) +* 调度去进程化,优化进程线程依赖关系 ([dc479fb](https://gitee.com/openharmony/kernel_liteos_a/commits/dc479fb7bd9cb8441e4e47d44b42110ea07d76a2)) +* 调度相关模块间依赖优化 ([0e3936c](https://gitee.com/openharmony/kernel_liteos_a/commits/0e3936c4f8b8bcfc48d283a6d53413e0fc0619b3)), closes [#I4RPRW](https://gitee.com/openharmony/kernel_liteos_a/issues/I4RPRW) +* 进程cpup占用率结构优化为动态分配 ([f06e090](https://gitee.com/openharmony/kernel_liteos_a/commits/f06e090a1085a654fd726fbc3c3a1c2bc703d663)), closes [#I4GLNT](https://gitee.com/openharmony/kernel_liteos_a/issues/I4GLNT) +* 进程rlimit修改为动态分配,减少静态内存占用 ([cf8446c](https://gitee.com/openharmony/kernel_liteos_a/commits/cf8446c94112ed6993a2e6e71e793d83a72689d5)), closes [#I4EZY5](https://gitee.com/openharmony/kernel_liteos_a/issues/I4EZY5) + +### BREAKING CHANGES + +* 1. 删除 LOS_CirBufLock(),LOS_CirBufUnlock()内核对外接口 +2. LOS_CirBufWrite(),LOS_CirBufRead()由原先内部不进行上/解锁操作,变为默认已包含上/解锁操作。 +* 新增支持API: + +LOS_LmsCheckPoolAdd使能检测指定内存池 +LOS_LmsCheckPoolDel不检测指定内存池 +LOS_LmsAddrProtect为指定内存段上锁,不允许访问 +LOS_LmsAddrDisableProtect去能指定内存段的访问保护 +* 1.新增一系列perf的对外API,位于los_perf.h中. + LOS_PerfInit配置采样数据缓冲区 + LOS_PerfStart开启Perf采样 + LOS_PerfStop停止Perf采样 + LOS_PerfConfig配置Perf采样事件 + LOS_PerfDataRead读取采样数据 + LOS_PerfNotifyHookReg 注册采样数据缓冲区的钩子函数 + LOS_PerfFlushHookReg 注册缓冲区刷cache的钩子 + +2. 用户态新增perf命令 +【Usage】: +./perf [start] /[start id] Start perf. +./perf [stop] Stop perf. +./perf [read nBytes] Read nBytes raw data from perf buffer and print out. +./perf [list] List events to be used in -e. +./perf [stat] or [record] + +- [Introduction](#section11660541593) +- [Directory Structure](#section161941989596) +- [Constraints](#section119744591305) +- [Usage](#section741617511812) +- [Preparations](#section1579912573329) +- [Source Code Acquisition](#section11443189655) +- [Compilation and Building](#section2081013992812) +- [Contribution](#section1371123476304) +- [Repositories Involved](#section1371113476307) + +## Introduction + +The OpenHarmony LiteOS Cortex-A is a new-generation kernel developed based on the Huawei LiteOS kernel. Huawei LiteOS is a lightweight operating system \(OS\) built for the Internet of Things \(IoT\) field. With the rapid development of the IoT industry, OpenHarmony LiteOS Cortex-A brings small-sized, low-power, and high-performance experience and builds a unified and open ecosystem for developers. In addition, it provides rich kernel mechanisms, more comprehensive Portable Operating System Interface \(POSIX\), and a unified driver framework, Hardware Driver Foundation \(HDF\), which offers unified access for device developers and friendly development experience for application developers. [Figure 1](#fig27311582210) shows the architecture of the OpenHarmony LiteOS Cortex-A kernel. + +**Figure 1** Architecture of the OpenHarmony LiteOS Cortex-A kernel +![](figures/architecture-of-the-openharmony-liteos-cortex-a-kernel.png "architecture-of-the-openharmony-liteos-cortex-a-kernel") + +## Directory Structure + +``` +/kernel/liteos_a +├── apps # User-space init and shell application programs +├── arch # System architecture, such as ARM +│ └── arm # Code for ARM architecture +├── bsd # Code of the driver and adaptation layer module related to the FreeBSD, such as the USB module +├── compat # Kernel API compatibility +│ └── posix # POSIX APIs +├── drivers # Kernel drivers +│ └── char # Character device +│ ├── mem # Driver for accessing physical input/output (I/O) devices +│ ├── quickstart # APIs for quick start of the system +│ ├── random # Driver for random number generators +│ └── video # Framework of the framebuffer driver +├── fs # File system module, which mainly derives from the NuttX open-source project +│ ├── fat # FAT file system +│ ├── jffs2 # JFFS2 file system +│ ├── include # Header files exposed externally +│ ├── nfs # NFS file system +│ ├── proc # proc file system +│ ├── ramfs # RAMFS file system +│ └── vfs # VFS layer +├── kernel # Kernel modules including the process, memory, and IPC modules +│ ├── base # Basic kernel modules including the scheduling and memory modules +│ ├── common # Common components used by the kernel +│ ├── extended # Extended kernel modules including the dynamic loading, vDSO, and LiteIPC modules +│ ├── include # Header files exposed externally +│ └── user # Init process loading +├── lib # Kernel library +├── net # Network module, which mainly derives from the lwIP open-source project +├── platform # Code for supporting different systems on a chip (SOCs), such as Hi3516D V300 +│ ├── hw # Logic code related to clocks and interrupts +│ ├── include # Header files exposed externally +│ └── uart # Logic code related to the serial port +├── platform # Code for supporting different systems on a chip (SOCs), such as Hi3516D V300 +├── security # Code related to security features, including process permission management and virtual ID mapping management +├── syscall # System calling +└── tools # Building tools as well as related configuration and code +``` + +## Constraints + +- Programming languages: C and C++ +- Applicable development boards: Hi3516D V300 +- Hi3516D V300 uses the FAT file system by default. + +## Usage + +OpenHarmony LiteOS Cortex-A supports the [Hi3516D V300](https://gitee.com/openharmony/docs/blob/master/en/device-dev/quick-start/quickstart-appendix-hi3516.md). You can develop and run your applications based on this development board. + +### Preparations + +You need to set up the compilation environment on Ubuntu. + +- [Setting Up Ubuntu Development Environment](https://gitee.com/openharmony/docs/blob/master/en/device-dev/quick-start/Readme-EN.md) + +### Source Code Acquisition + +Download and decompress a set of source code on a Ubuntu server to acquire the [source code](https://gitee.com/openharmony/docs/blob/master/en/device-dev/get-code/sourcecode-acquire.md). + +### Compilation and Building + +For details about how to develop the first application, see: [Developing the First Example Program Running on Hi3516](https://gitee.com/openharmony/docs/blob/master/en/device-dev/quick-start/quickstart-pkg-3516-helloworld.md) + +For compilation, please refer to the [compilation instructions](https://gitee.com/openharmony/docs/blob/master/en/device-dev/quick-start/quickstart-pkg-3516-build.md). + +## Contribution + +[How to involve](https://gitee.com/openharmony/docs/blob/HEAD/en/contribute/contribution-guide.md) + +[Commit message spec](https://gitee.com/openharmony/kernel_liteos_a/wikis/Commit%20message%20%E8%A7%84%E8%8C%83) + +[C&C++ Secure Coding Guide](https://gitee.com/openharmony/docs/blob/master/en/contribute/OpenHarmony-c-cpp-secure-coding-guide.md) + +[LiteOS-A Kernel Coding Style Guide](https://gitee.com/openharmony/kernel_liteos_a/wikis/LiteOS-A%20%E5%86%85%E6%A0%B8%E7%BC%96%E7%A0%81%E8%A7%84%E8%8C%83%E6%8C%87%E5%8D%97) + +## Repositories Involved + +[Kernel subsystem](https://gitee.com/openharmony/docs/blob/master/en/readme/kernel.md) + +[drivers\_liteos](https://gitee.com/openharmony/drivers_liteos/blob/master/README.md) + +[kernel\_liteos\_a](https://gitee.com/openharmony/kernel_liteos_a/blob/master/README.md) + diff --git a/src/kernel_liteos_a/README_zh-HK.md b/src/kernel_liteos_a/README_zh-HK.md new file mode 100644 index 00000000..3ec89180 --- /dev/null +++ b/src/kernel_liteos_a/README_zh-HK.md @@ -0,0 +1,104 @@ +# LiteOS-A內核 + +- [簡介](#section11660541593) +- [目錄](#section161941989596) +- [約束](#section119744591305) +- [使用說明](#section741617511812) +- [準備](#section1579912573329) +- [獲取源碼](#section11443189655) +- [編譯構建](#section2081013992812) +- [貢獻](#section1371123476304) +- [相關倉](#section1371113476307) + +## 簡介 + +OpenHarmony LiteOS-A內核是基於Huawei LiteOS內核演進發展的新一代內核,Huawei LiteOS是面向IoT領域構建的輕量級物聯網操作系統。在IoT產業高速發展的潮流中,OpenHarmony LiteOS-A內核能夠帶給用戶小體積、低功耗、高性能的體驗以及統一開放的生態系統能力,新增了豐富的內核機制、更加全面的POSIX標準接口以及統一驅動框架**HDF**(OpenHarmony Driver Foundation)等,為設備廠商提供了更統一的接入方式,為OpenHarmony的應用開發者提供了更友好的開發體驗。圖1為OpenHarmony LiteOS-A內核架構圖: + +**圖 1** OpenHarmony LiteOS-A內核架構圖 + +![](figures/OpenHarmony-LiteOS-A内核架构图.png "OpenHarmony-LiteOS-A內核架構圖") + +## 目錄 + +``` +/kernel/liteos_a +├── apps # 用戶態的init和shell應用程序 +├── arch # 體系架構的目錄,如arm等 +│ └── arm # arm架構代碼 +├── bsd # freebsd相關的驅動和適配層模塊代碼引入,例如USB等 +├── compat # 內核接口兼容性目錄 +│ └── posix # posix相關接口 +├── drivers # 內核驅動 +│ └── char # 字符設備 +│ ├── mem # 訪問物理IO設備驅動 +│ ├── quickstart # 系統快速啟動接口目錄 +│ ├── random # 隨機數設備驅動 +│ └── video # framebuffer驅動框架 +├── fs # 文件系統模塊,主要來源於NuttX開源項目 +│ ├── fat # fat文件系統 +│ ├── jffs2 # jffs2文件系統 +│ ├── include # 對外暴露頭文件存放目錄 +│ ├── nfs # nfs文件系統 +│ ├── proc # proc文件系統 +│ ├── ramfs # ramfs文件系統 +│ └── vfs # vfs層 +├── kernel # 進程、內存、IPC等模塊 +│ ├── base # 基礎內核,包括調度、內存等模塊 +│ ├── common # 內核通用組件 +│ ├── extended # 擴展內核,包括動態加載、vdso、liteipc等模塊 +│ ├── include # 對外暴露頭文件存放目錄 +│ └── user # 加載init進程 +├── lib # 內核的lib庫 +├── net # 網絡模塊,主要來源於lwip開源項目 +├── platform # 支持不同的芯片平台代碼,如Hi3516DV300等 +│ ├── hw # 時鐘與中斷相關邏輯代碼 +│ ├── include # 對外暴露頭文件存放目錄 +│ └── uart # 串口相關邏輯代碼 +├── security # 安全特性相關的代碼,包括進程權限管理和虛擬id映射管理 +├── syscall # 系統調用 +└── tools # 構建工具及相關配置和代碼 +``` + +## 約束 + +- 開發語言:C/C++; +- 適用於Hi3516DV300單板; +- Hi3516DV300默認使用FAT文件系統。 + +## 使用說明 + +OpenHarmony LiteOS-A內核支持[Hi3516DV300](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/quick-start/quickstart-appendix-hi3516.md)單板,開發者可基於此單板開發運行自己的應用程序。 + +### 準備 + +開發者需要在Ubuntu上搭建編譯環境: + +- [編譯環境凖備](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/quick-start/Readme-CN.md); + +### 獲取源碼 + +在Ubuntu服務器上下載並解壓一套源代碼,源碼獲取方式參考[源碼獲取](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/get-code/sourcecode-acquire.md)。 + +### 編譯構建 + +開發者開發第一個應用程序可參考:[helloworld for Hi3516DV300](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/quick-start/quickstart-pkg-3516-helloworld.md)。 + +編譯可以參考:[編譯指導](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/quick-start/quickstart-pkg-3516-build.md) + +## 貢獻 + +[如何貢獻](https://gitee.com/openharmony/docs/blob/HEAD/zh-cn/contribute/%E5%8F%82%E4%B8%8E%E8%B4%A1%E7%8C%AE.md) + +[Commit message規範](https://gitee.com/openharmony/kernel_liteos_a/wikis/Commit%20message%20%E8%A7%84%E8%8C%83) + +[OpenHarmony C&C++ 安全編程指南](https://gitee.com/openharmony/docs/blob/master/zh-cn/contribute/OpenHarmony-c-cpp-secure-coding-guide.md) + +[LiteOS-A 內核編碼規範指南](https://gitee.com/openharmony/kernel_liteos_a/wikis/LiteOS-A%20%E5%86%85%E6%A0%B8%E7%BC%96%E7%A0%81%E8%A7%84%E8%8C%83%E6%8C%87%E5%8D%97) + +## 相關倉 + +[內核子系統](https://gitee.com/openharmony/docs/blob/master/zh-cn/readme/%E5%86%85%E6%A0%B8%E5%AD%90%E7%B3%BB%E7%BB%9F.md) + +[drivers\_liteos](https://gitee.com/openharmony/drivers_liteos/blob/master/README_zh.md) + +[kernel\_liteos\_a](https://gitee.com/openharmony/kernel_liteos_a/blob/master/README_zh-HK.md) diff --git a/src/kernel_liteos_a/README_zh.md b/src/kernel_liteos_a/README_zh.md new file mode 100644 index 00000000..27d7da11 --- /dev/null +++ b/src/kernel_liteos_a/README_zh.md @@ -0,0 +1,109 @@ +# LiteOS-A内核 + +- [简介](#section11660541593) +- [目录](#section161941989596) +- [约束](#section119744591305) +- [使用说明](#section741617511812) +- [准备](#section1579912573329) +- [获取源码](#section11443189655) +- [编译构建](#section2081013992812) +- [贡献](#section1371123476304) +- [相关仓](#section1371113476307) + +## 简介 + +OpenHarmony LiteOS-A内核是基于Huawei LiteOS内核演进发展的新一代内核,Huawei LiteOS是面向IoT领域构建的轻量级物联网操作系统。在IoT产业高速发展的潮流中,OpenHarmony LiteOS-A内核能够带给用户小体积、低功耗、高性能的体验以及统一开放的生态系统能力,新增了丰富的内核机制、更加全面的POSIX标准接口以及统一驱动框架**HDF**(OpenHarmony Driver Foundation)等,为设备厂商提供了更统一的接入方式,为OpenHarmony的应用开发者提供了更友好的开发体验。图1为OpenHarmony LiteOS-A内核架构图: + +**图 1** OpenHarmony LiteOS-A内核架构图 +![](figures/OpenHarmony-LiteOS-A内核架构图.png "OpenHarmony-LiteOS-A内核架构图") + +## 目录 + +``` +/kernel/liteos_a +├── apps # 用户态的init和shell应用程序 +├── arch # 体系架构的目录,如arm等 +│ └── arm # arm架构代码 +├── bsd # freebsd相关的驱动和适配层模块代码引入,例如USB等 +├── compat # 内核接口兼容性目录 +│ └── posix # posix相关接口 +├── drivers # 内核驱动 +│ └── char # 字符设备 +│ ├── mem # 访问物理IO设备驱动 +│ ├── quickstart # 系统快速启动接口目录 +│ ├── random # 随机数设备驱动 +│ └── video # framebuffer驱动框架 +├── figures # 内核架构图 +├── fs # 文件系统模块,主要来源于NuttX开源项目 +│ ├── fat # fat文件系统 +│ ├── jffs2 # jffs2文件系统 +│ ├── include # 对外暴露头文件存放目录 +│ ├── nfs # nfs文件系统 +│ ├── proc # proc文件系统 +│ ├── ramfs # ramfs文件系统 +│ └── vfs # vfs层 +├── kernel # 进程、内存、IPC等模块 +│ ├── base # 基础内核,包括调度、内存等模块 +│ ├── common # 内核通用组件 +│ ├── extended # 扩展内核,包括动态加载、vdso、liteipc等模块 +│ ├── include # 对外暴露头文件存放目录 +│ └── user # 加载init进程 +├── lib # 内核的lib库 +├── net # 网络模块,主要来源于lwip开源项目 +├── platform # 支持不同的芯片平台代码,如Hi3516DV300等 +│ ├── hw # 时钟与中断相关逻辑代码 +│ ├── include # 对外暴露头文件存放目录 +│ └── uart # 串口相关逻辑代码 +├── security # 安全特性相关的代码,包括进程权限管理和虚拟id映射管理 +├── shell # 接收用户输入的命令,内核去执行 +├── syscall # 系统调用 +├── testsuilts # 测试套件 +└── tools # 构建工具及相关配置和代码 +``` + +## 约束 + +- 开发语言:C/C++; +- 适用于Hi3516DV300单板; +- Hi3516DV300默认使用FAT文件系统。 + +## 使用说明 + +OpenHarmony LiteOS-A内核支持[Hi3516DV300](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/quick-start/quickstart-appendix-hi3516.md)单板。开发者可基于此单板开发运行自己的应用程序。 + +### 准备 + +开发者需要在Ubuntu上搭建编译环境: + +- [编译环境准备](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/quick-start/Readme-CN.md); + +### 获取源码 + +在Ubuntu服务器源码获取方式参考: [源码获取](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/get-code/sourcecode-acquire.md)。 + +### 编译构建 + +如果这是您的首次应用程序开发,可参考:[helloworld for Hi3516DV300](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/quick-start/quickstart-pkg-3516-helloworld.md)。 + +编译可以参考:[编译指导](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/quick-start/quickstart-pkg-3516-build.md) + +测试参考:[单元测试](testsuites/unittest/tools/README.md) + +## 贡献 + +[如何贡献](https://gitee.com/openharmony/docs/blob/HEAD/zh-cn/contribute/%E5%8F%82%E4%B8%8E%E8%B4%A1%E7%8C%AE.md) + +[Commit message规范](https://gitee.com/openharmony/kernel_liteos_a/wikis/Commit%20message%20%E8%A7%84%E8%8C%83) + +[OpenHarmony C&C++ 安全编程指南](https://gitee.com/openharmony/docs/blob/master/zh-cn/contribute/OpenHarmony-c-cpp-secure-coding-guide.md) + +[LiteOS-A 内核编码规范指南](https://gitee.com/openharmony/kernel_liteos_a/wikis/LiteOS-A%20%E5%86%85%E6%A0%B8%E7%BC%96%E7%A0%81%E8%A7%84%E8%8C%83%E6%8C%87%E5%8D%97) + +## 相关仓 + +[内核子系统](https://gitee.com/openharmony/docs/blob/master/zh-cn/readme/%E5%86%85%E6%A0%B8%E5%AD%90%E7%B3%BB%E7%BB%9F.md) + +[drivers\_liteos](https://gitee.com/openharmony/drivers_liteos/blob/master/README_zh.md) + +[kernel\_liteos\_a](https://gitee.com/openharmony/kernel_liteos_a/blob/master/README_zh.md) + diff --git a/src/kernel_liteos_a/apps/BUILD.gn b/src/kernel_liteos_a/apps/BUILD.gn new file mode 100644 index 00000000..bf35c91a --- /dev/null +++ b/src/kernel_liteos_a/apps/BUILD.gn @@ -0,0 +1,62 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +group("apps") { + deps = [] + + if (defined(LOSCFG_SHELL)) { + deps += [ + "mksh", + "shell", + "toybox", + ] + } + + if (defined(LOSCFG_USER_INIT_DEBUG)) { + deps += [ "init" ] + } + + if (defined(LOSCFG_NET_LWIP_SACK_TFTP)) { + deps += [ "tftp" ] + } + + if (defined(LOSCFG_DRIVERS_TRACE)) { + deps += [ "trace" ] + } + + if (defined(LOSCFG_DRIVERS_PERF)) { + deps += [ "perf" ] + } + + if (defined(LOSCFG_KERNEL_LMS)) { + deps += [ "lms:sample_usr_lms" ] + } +} diff --git a/src/kernel_liteos_a/apps/Makefile b/src/kernel_liteos_a/apps/Makefile new file mode 100644 index 00000000..490a6cb3 --- /dev/null +++ b/src/kernel_liteos_a/apps/Makefile @@ -0,0 +1,40 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +APPSTOPDIR := $(shell pwd) +LITEOSTOPDIR ?= $(APPSTOPDIR)/.. +export LITEOSTOPDIR +export APPSTOPDIR + +include $(APPSTOPDIR)/config.mk + +all clean: + $(HIDE) for dir in $(APP_SUBDIRS); do $(MAKE) -C $$dir $@ || exit 1; done + +.PHONY: all clean diff --git a/src/kernel_liteos_a/apps/app.mk b/src/kernel_liteos_a/apps/app.mk new file mode 100644 index 00000000..3531c266 --- /dev/null +++ b/src/kernel_liteos_a/apps/app.mk @@ -0,0 +1,32 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +override TARGET = $(OUT)/bin/$(APP_NAME) + +include $(MODULE) diff --git a/src/kernel_liteos_a/apps/config.mk b/src/kernel_liteos_a/apps/config.mk new file mode 100644 index 00000000..5bff8f4b --- /dev/null +++ b/src/kernel_liteos_a/apps/config.mk @@ -0,0 +1,79 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +# common flags config +BASE_OPTS := -D_FORTIFY_SOURCE=2 -D_XOPEN_SOURCE=700 + +ASFLAGS := +CFLAGS := $(LITEOS_COPTS) $(BASE_OPTS) -fPIE +CXXFLAGS := $(LITEOS_CXXOPTS) $(BASE_OPTS) -fPIE +LDFLAGS := $(LITEOS_CORE_COPTS) -pie -Wl,-z,relro,-z,now -O2 + +CFLAGS := $(filter-out -fno-pic -fno-builtin -nostdinc -nostdlib,$(CFLAGS)) +CXXFLAGS := $(filter-out -fno-pic -fno-builtin -nostdinc -nostdlib -nostdinc++,$(CXXFLAGS)) + +# alias variable config +HIDE := @ +MAKE := make +RM := rm -rf +CP := cp -rf +MV := mv -f + +APP := $(APPSTOPDIR)/app.mk + +##build modules config## +APP_SUBDIRS := + +ifeq ($(LOSCFG_SHELL), y) +APP_SUBDIRS += shell +APP_SUBDIRS += mksh +APP_SUBDIRS += toybox +endif + +ifeq ($(LOSCFG_KERNEL_LMS), y) +APP_SUBDIRS += lms +endif + +ifeq ($(LOSCFG_USER_INIT_DEBUG), y) +APP_SUBDIRS += init +endif + +ifeq ($(LOSCFG_NET_LWIP_SACK_TFTP), y) +APP_SUBDIRS += tftp +endif + +ifeq ($(LOSCFG_DRIVERS_TRACE), y) +APP_SUBDIRS += trace +endif + +ifeq ($(LOSCFG_DRIVERS_PERF), y) +APP_SUBDIRS += perf +endif diff --git a/src/kernel_liteos_a/apps/init/BUILD.gn b/src/kernel_liteos_a/apps/init/BUILD.gn new file mode 100644 index 00000000..a69e257e --- /dev/null +++ b/src/kernel_liteos_a/apps/init/BUILD.gn @@ -0,0 +1,39 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +executable("init") { + sources = [ "src/init.c" ] + + if (defined(LOSCFG_QUICK_START)) { + ldflags = [ "--static" ] + defines = [ "LOSCFG_QUICK_START" ] + } +} diff --git a/src/kernel_liteos_a/apps/init/Makefile b/src/kernel_liteos_a/apps/init/Makefile new file mode 100644 index 00000000..bd254e65 --- /dev/null +++ b/src/kernel_liteos_a/apps/init/Makefile @@ -0,0 +1,41 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(APPSTOPDIR)/config.mk + +APP_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := src/init.c + +ifeq ($(LOSCFG_QUICK_START), y) +LDFLAGS += --static +CFLAGS += -DLOSCFG_QUICK_START +endif + +include $(APP) diff --git a/src/kernel_liteos_a/apps/init/src/init.c b/src/kernel_liteos_a/apps/init/src/init.c new file mode 100644 index 00000000..784bf83d --- /dev/null +++ b/src/kernel_liteos_a/apps/init/src/init.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +#ifdef LOSCFG_QUICK_START +#include +#include +#include +#include +#include + +#define QUICKSTART_IOC_MAGIC 'T' +#define QUICKSTART_INITSTEP2 _IO(QUICKSTART_IOC_MAGIC, 0) +#define WAIT_FOR_SAMPLE 300000 // wait 300ms for sample +#endif +int main(int argc, char * const *argv) +{ + (void)argv; + int ret; + pid_t gid; + const char *shellPath = "/bin/mksh"; + +#ifdef LOSCFG_QUICK_START + const char *samplePath = "/dev/shm/sample_quickstart"; + + ret = fork(); + if (ret < 0) { + printf("Failed to fork for sample_quickstart\n"); + } else if (ret == 0) { + (void)execve(samplePath, NULL, NULL); // 执行可执行文件 + exit(0); + } + + usleep(WAIT_FOR_SAMPLE); + + int fd = open("/dev/quickstart", O_RDONLY); + if (fd != -1) { + ioctl(fd, QUICKSTART_INITSTEP2); + close(fd); + } +#endif + ret = fork(); // 创建第一个程序来跑shell + if (ret < 0) { + printf("Failed to fork for shell\n"); + } else if (ret == 0) { + gid = getpgrp(); // 返回进程组ID + if (gid < 0) { + printf("get group id failed, pgrpid %d, errno %d\n", gid, errno); + exit(0); + } + ret = tcsetpgrp(STDIN_FILENO, gid); + if (ret != 0) { + printf("tcsetpgrp failed, errno %d\n", errno); + exit(0); + } + (void)execve(shellPath, NULL, NULL); // 正常执行命令行程序可执行文件 + exit(0); + } + // ret > 0 + while (1) { + ret = waitpid(-1, 0, WNOHANG); + if (ret == 0) { + sleep(1); + } + }; +} diff --git a/src/kernel_liteos_a/apps/lms/BUILD.gn b/src/kernel_liteos_a/apps/lms/BUILD.gn new file mode 100644 index 00000000..dd58d2d3 --- /dev/null +++ b/src/kernel_liteos_a/apps/lms/BUILD.gn @@ -0,0 +1,77 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//build/lite/config/component/lite_component.gni") +lite_component("LMS-Sample") { + features = [ ":sample_usr_lms" ] +} +executable("sample_usr_lms") { + output_name = "sample_usr_lms" + sources = [ "src/sample_usr_lms.c" ] + include_dirs = [] + defines = [] + if (ohos_build_compiler == "gcc") { + cflags_c = [ + "-O0", + "-fsanitize=kernel-address", + "-funwind-tables", + "-fasynchronous-unwind-tables", + ] + } else { + cflags_c = [ + "-O0", + "-fsanitize=kernel-address", + "-mllvm", + "-asan-instrumentation-with-call-threshold=0", + "-mllvm", + "-asan-stack=0", + "-mllvm", + "-asan-globals=0", + "-funwind-tables", + "-fasynchronous-unwind-tables", + ] + } + ldflags = [ + "-rdynamic", + "-lunwind", + "-lusrlms", + "-Wl,--wrap=realloc", + "-Wl,--wrap=calloc", + "-Wl,--wrap=malloc", + "-Wl,--wrap=free", + "-Wl,--wrap=valloc", + "-Wl,--wrap=aligned_alloc", + "-Wl,--wrap=memset", + "-Wl,--wrap=memcpy", + "-Wl,--wrap=memmove", + "-Wl,--wrap=strcpy", + "-Wl,--wrap=strcat", + ] + deps = [ "$LITEOSTOPDIR/kernel/extended/lms/usr:usrlmslib" ] +} diff --git a/src/kernel_liteos_a/apps/lms/src/sample_usr_lms.c b/src/kernel_liteos_a/apps/lms/src/sample_usr_lms.c new file mode 100644 index 00000000..7eb085e6 --- /dev/null +++ b/src/kernel_liteos_a/apps/lms/src/sample_usr_lms.c @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +static void BufWriteTest(void *buf, int start, int end) +{ + for (int i = start; i <= end; i++) { + ((char *)buf)[i] = 'a'; + } +} + +static void BufReadTest(void *buf, int start, int end) +{ + char tmp; + for (int i = start; i <= end; i++) { + tmp = ((char *)buf)[i]; + } +} + +static void LmsMallocTest(void) +{ +#define TEST_SIZE 16 + printf("\n-------- LmsMallocTest Start --------\n"); + char *buf = (char *)malloc(TEST_SIZE); + if (buf == NULL) { + return; + } + printf("[LmsMallocTest] read overflow & underflow error should be triggered, read range[-1, TEST_SIZE]\n"); + BufReadTest(buf, -1, TEST_SIZE); + printf("[LmsMallocTest] write overflow error should be triggered, write range[0, TEST_SIZE]\n"); + BufWriteTest(buf, 0, TEST_SIZE); + + free(buf); + printf("\n-------- LmsMallocTest End --------\n"); +} + +static void LmsReallocTest(void) +{ +#define TEST_SIZE 64 +#define TEST_SIZE_MIN 32 + printf("\n-------- LmsReallocTest Start --------\n"); + char *buf = (char *)malloc(TEST_SIZE); + printf("[LmsReallocTest] read overflow & underflow error should be triggered, read range[-1, TEST_SIZE]\n"); + BufReadTest(buf, -1, TEST_SIZE); + char *buf1 = (char *)realloc(buf, TEST_SIZE_MIN); + if (buf1 == NULL) { + free(buf); + return; + } + buf = NULL; + printf("[LmsReallocTest] read overflow & underflow error should be triggered, read range[-1, TEST_SIZE_MIN]\n"); + BufReadTest(buf1, -1, TEST_SIZE_MIN); + free(buf1); + printf("\n-------- LmsReallocTest End --------\n"); +} + +static void LmsCallocTest(void) +{ +#define TEST_SIZE 16 + printf("\n-------- LmsCallocTest Start --------\n"); + char *buf = (char *)calloc(4, 4); /* 4: test size */ + if (buf == NULL) { + return; + } + printf("[LmsCallocTest] read overflow & underflow error should be triggered, read range[-1, TEST_SIZE]\n"); + BufReadTest(buf, -1, TEST_SIZE); + free(buf); + printf("\n-------- LmsCallocTest End --------\n"); +} + +static void LmsVallocTest(void) +{ +#define TEST_SIZE 4096 + printf("\n-------- LmsVallocTest Start --------\n"); + char *buf = (char *)valloc(TEST_SIZE); + if (buf == NULL) { + return; + } + printf("[LmsVallocTest] read overflow & underflow error should be triggered, read range[-1, TEST_SIZE]\n"); + BufReadTest(buf, -1, TEST_SIZE); + free(buf); + printf("\n-------- LmsVallocTest End --------\n"); +} + +static void LmsAlignedAllocTest(void) +{ +#define TEST_ALIGN_SIZE 64 +#define TEST_SIZE 128 + printf("\n-------- LmsAlignedAllocTest Start --------\n"); + char *buf = (char *)aligned_alloc(TEST_ALIGN_SIZE, TEST_SIZE); + if (buf == NULL) { + return; + } + printf("[LmsAlignedAllocTest] read overflow & underflow error should be triggered, read range[-1,128]\n"); + BufReadTest(buf, -1, 128); + free(buf); + printf("\n-------- LmsAlignedAllocTest End --------\n"); +} + +static void LmsMemsetTest(void) +{ +#define TEST_SIZE 32 + printf("\n-------- LmsMemsetTest Start --------\n"); + char *buf = (char *)malloc(TEST_SIZE); + if (buf == NULL) { + return; + } + printf("[LmsMemsetTest] memset overflow & underflow error should be triggered, memset size:%d\n", TEST_SIZE + 1); + memset(buf, 0, TEST_SIZE + 1); + free(buf); + printf("\n-------- LmsMemsetTest End --------\n"); +} + +static void LmsMemcpyTest(void) +{ +#define TEST_SIZE 20 + printf("\n-------- LmsMemcpyTest Start --------\n"); + char *buf = (char *)malloc(TEST_SIZE); + if (buf == NULL) { + return; + } + char localBuf[32] = {0}; /* 32: test size */ + printf("[LmsMemcpyTest] memcpy overflow error should be triggered, memcpy size:%d\n", TEST_SIZE + 1); + memcpy(buf, localBuf, TEST_SIZE + 1); + free(buf); + printf("\n-------- LmsMemcpyTest End --------\n"); +} + +static void LmsMemmoveTest(void) +{ +#define TEST_SIZE 20 + printf("\n-------- LmsMemmoveTest Start --------\n"); + char *buf = (char *)malloc(TEST_SIZE); + if (buf == NULL) { + return; + } + printf("[LmsMemmoveTest] memmove overflow error should be triggered\n"); + memmove(buf + 12, buf, 10); /* 12 and 10: test size */ + free(buf); + printf("\n-------- LmsMemmoveTest End --------\n"); +} + +static void LmsStrcpyTest(void) +{ +#define TEST_SIZE 16 + printf("\n-------- LmsStrcpyTest Start --------\n"); + char *buf = (char *)malloc(TEST_SIZE); + if (buf == NULL) { + return; + } + char *testStr = "bbbbbbbbbbbbbbbbb"; + printf("[LmsStrcpyTest] strcpy overflow error should be triggered, src string buf size:%d\n", + (int)strlen(testStr) + 1); + strcpy(buf, testStr); + free(buf); + printf("\n-------- LmsStrcpyTest End --------\n"); +} + +static void LmsStrcatTest(void) +{ +#define TEST_SIZE 16 + printf("\n-------- LmsStrcatTest Start --------\n"); + char *buf = (char *)malloc(TEST_SIZE); + if (buf == NULL) { + return; + } + buf[0] = 'a'; + buf[1] = 'b'; + buf[2] = 0; + char *testStr = "cccccccccccccc"; + printf("[LmsStrcatTest] strcat overflow error should be triggered, src string:%s dest string:%s" + "total buf size:%d\n", + testStr, buf, strlen(testStr) + strlen(buf) + 1); + strcat(buf, testStr); + free(buf); + printf("\n-------- LmsStrcatTest End --------\n"); +} + +static void LmsFreeTest(void) +{ +#define TEST_SIZE 16 + printf("\n-------- LmsFreeTest Start --------\n"); + char *buf = (char *)malloc(TEST_SIZE); + if (buf == NULL) { + return; + } + printf("[LmsFreeTest] free size:%d\n", TEST_SIZE); + free(buf); + printf("[LmsFreeTest] Use after free error should be triggered, read range[1,1]\n"); + BufReadTest(buf, 1, 1); + printf("[LmsFreeTest] double free error should be triggered\n"); + free(buf); + printf("\n-------- LmsFreeTest End --------\n"); +} + +int main(int argc, char * const *argv) +{ + (void)argc; + (void)argv; + printf("\n############### Lms Test start ###############\n"); + char *tmp = (char *)malloc(5000); /* 5000: test mem size */ + if (tmp == NULL) { + return -1; + } + LmsMallocTest(); + LmsReallocTest(); + LmsCallocTest(); + LmsVallocTest(); + LmsAlignedAllocTest(); + LmsMemsetTest(); + LmsMemcpyTest(); + LmsMemmoveTest(); + LmsStrcpyTest(); + LmsStrcatTest(); + LmsFreeTest(); + free(tmp); + printf("\n############### Lms Test End ###############\n"); + return 0; +} diff --git a/src/kernel_liteos_a/apps/mksh/BUILD.gn b/src/kernel_liteos_a/apps/mksh/BUILD.gn new file mode 100644 index 00000000..2e9c46d6 --- /dev/null +++ b/src/kernel_liteos_a/apps/mksh/BUILD.gn @@ -0,0 +1,100 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//build/lite/config/component/lite_component.gni") +import("//kernel/liteos_a/liteos.gni") +import("$THIRDPARTY_MKSH_DIR/mksh.gni") + +group("mksh") { + deps = [ ":build_mksh" ] +} + +copy("copy_mksh_src") { + sources = MKSH_SRC_DIR + outputs = [ "$target_out_dir/mksh_build" ] +} + +build_ext_component("build_mksh") { + deps = [ ":copy_mksh_src" ] + deps += [ "$THIRDPARTY_MUSL_DIR:sysroot_lite" ] + exec_path = rebase_path("$target_out_dir/mksh_build") + + cflags = [ + "-flto", + "-fdata-sections", + "-ffunction-sections", + "-fstack-protector-strong", + "-D_FORTIFY_SOURCE=2", + "-DMKSH_DISABLE_TTY_WARNING", + "-DMKSH_SMALL=1", + "-DMKSH_ASSUME_UTF8=1", + "-DMKSH_SMALL_BUT_FAST=0", + "-DMKSH_S_NOVI=1", + "-DHAVE_CAN_FSTACKPROTECTORSTRONG=1", + "-DMKSH_LESS_CMDLINE_EDITING", + "-DMKSH_LESS_BUILDINS", + "-DMKSH_NO_INITCOMS", + "-DADAPT_FOR_LITEOS_A", + ] + if (defined(LOSCFG_COMPILER_CLANG_LLVM)) { + cflags += [ "-Oz" ] + } else { + cflags += [ "-O2" ] + } + cflags = string_join(" ", cflags) + + extra_flags = string_join(" ", target_arch_cflags) + if (ohos_build_compiler == "clang") { + extra_flags += " --target=$target_triple" + extra_flags += " --sysroot=" + rebase_path(ohos_current_sysroot) + } + + command = "rm -rf .git && env" + command += " CC=\"$ohos_current_cc_command\"" + command += " TARGET_OS=OpenHarmony" + command += " CFLAGS=\"$cflags $extra_flags\"" + command += " LDFLAGS=\"-Wl,--gc-sections -flto -O2\"" + command += " sh ./Build.sh -r" + + # copy mksh and .mkshrc to out dir + command += " && mkdir -p " + command += rebase_path("$root_out_dir/bin", exec_path) + command += " && install -D mksh " + command += rebase_path("$root_out_dir/unstripped/bin/mksh", exec_path) + command += " && $ohos_current_strip_command mksh -o " + command += rebase_path("$root_out_dir/bin/mksh", exec_path) + command += " && install -D .mkshrc " + command += rebase_path("$root_out_dir/etc/.mkshrc", exec_path) + + outputs = [ + "$root_out_dir/unstripped/bin/mksh", + "$root_out_dir/bin/mksh", + "$root_out_dir/etc/.mkshrc", + ] +} diff --git a/src/kernel_liteos_a/apps/mksh/Makefile b/src/kernel_liteos_a/apps/mksh/Makefile new file mode 100644 index 00000000..9bb177c9 --- /dev/null +++ b/src/kernel_liteos_a/apps/mksh/Makefile @@ -0,0 +1,56 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(APPSTOPDIR)/config.mk + +BUILD_DIR := $(OUT)/mksh_build +BUILD_LOG := $(BUILD_DIR)/build.log + +CFLAGS += -DMKSH_DISABLE_TTY_WARNING -DMKSH_SMALL=1 -DMKSH_ASSUME_UTF8=1 -DMKSH_SMALL_BUT_FAST=0 -DMKSH_S_NOVI=1 -DHAVE_CAN_FSTACKPROTECTORSTRONG=1 +CFLAGS += -DMKSH_LESS_CMDLINE_EDITING -DMKSH_LESS_BUILDINS -DMKSH_NO_INITCOMS -DADAPT_FOR_LITEOS_A +CFLAGS += -Wno-error +LDFLAGS += -Wl,--gc-sections + +all: +ifneq ($(wildcard $(BUILD_DIR)/Rebuild.sh),) + $(HIDE)echo "not clean, rebuilding now" + $(HIDE)cd $(BUILD_DIR) && sh ./Rebuild.sh > $(BUILD_LOG) 2>&1 +else + $(HIDE)mkdir -p $(BUILD_DIR) + $(HIDE)$(CP) $(LITEOSTHIRDPARTY)/mksh/. $(BUILD_DIR) + $(HIDE)cd $(BUILD_DIR) && CC="$(CC)" TARGET_OS=OpenHarmony CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" sh ./Build.sh -r > $(BUILD_LOG) 2>&1 +endif + $(HIDE)mkdir -p $(OUT)/bin/ $(OUT)/etc/ + $(HIDE)$(STRIP) $(BUILD_DIR)/mksh -o $(OUT)/bin/mksh + $(HIDE)$(CP) $(BUILD_DIR)/.mkshrc $(OUT)/etc/ + +clean: + $(HIDE)$(RM) $(BUILD_DIR) + +.PHONY: all clean diff --git a/src/kernel_liteos_a/apps/perf/BUILD.gn b/src/kernel_liteos_a/apps/perf/BUILD.gn new file mode 100644 index 00000000..c195375b --- /dev/null +++ b/src/kernel_liteos_a/apps/perf/BUILD.gn @@ -0,0 +1,63 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +executable("perf") { + sources = [ + "src/main.c", + "src/option.c", + "src/perf.c", + "src/perf_list.c", + "src/perf_record.c", + "src/perf_stat.c", + ] + include_dirs = [ "include" ] + defines = [] + + if (defined(LOSCFG_PERF_HW_PMU)) { + defines += [ "LOSCFG_PERF_HW_PMU" ] + } + + if (defined(LOSCFG_PERF_TIMED_PMU)) { + defines += [ "LOSCFG_PERF_TIMED_PMU" ] + } + + if (defined(LOSCFG_PERF_SW_PMU)) { + defines += [ "LOSCFG_PERF_SW_PMU" ] + } + + if (defined(LOSCFG_FS_VFS)) { + defines += [ "LOSCFG_FS_VFS" ] + } + + defines += [ "LOSCFG_PERF_BUFFER_SIZE=$LOSCFG_PERF_BUFFER_SIZE" ] + + deps = [ "$LITEOSTHIRDPARTY/bounds_checking_function:libsec_static" ] +} diff --git a/src/kernel_liteos_a/apps/perf/Makefile b/src/kernel_liteos_a/apps/perf/Makefile new file mode 100644 index 00000000..dcaadb8a --- /dev/null +++ b/src/kernel_liteos_a/apps/perf/Makefile @@ -0,0 +1,62 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(APPSTOPDIR)/config.mk + +APP_NAME := $(notdir $(shell pwd)) + +SECUREC_DIR := $(LITEOSTHIRDPARTY)/bounds_checking_function + +LOCAL_SRCS = $(wildcard src/*.c) +LOCAL_SRCS += $(wildcard $(SECUREC_DIR)/src/*.c) + +LOCAL_INCLUDE := \ + -I include \ + -I $(SECUREC_DIR)/include + +LOCAL_FLAGS += $(LOCAL_INCLUDE) + +ifeq ($(LOSCFG_PERF_HW_PMU), y) +CFLAGS += -DLOSCFG_PERF_HW_PMU +endif + +ifeq ($(LOSCFG_PERF_TIMED_PMU), y) +CFLAGS += -DLOSCFG_PERF_TIMED_PMU +endif + +ifeq ($(LOSCFG_PERF_SW_PMU), y) +CFLAGS += -DLOSCFG_PERF_SW_PMU +endif + +ifeq ($(LOSCFG_FS_VFS), y) +CFLAGS += -DLOSCFG_FS_VFS +endif + +CFLAGS += -DLOSCFG_PERF_BUFFER_SIZE=$(LOSCFG_PERF_BUFFER_SIZE) +include $(APP) diff --git a/src/kernel_liteos_a/apps/perf/include/option.h b/src/kernel_liteos_a/apps/perf/include/option.h new file mode 100644 index 00000000..e745bebf --- /dev/null +++ b/src/kernel_liteos_a/apps/perf/include/option.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef _OPTION_H +#define _OPTION_H + +#include "perf.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define CMD_MAX_PARAMS 10 +typedef int (*CALL_BACK)(const char *argv); + +enum OptionType { + OPTION_TYPE_UINT, + OPTION_TYPE_STRING, + OPTION_TYPE_CALLBACK, +}; + +typedef struct { + int type; + const char *name; + const char **str; + unsigned int *value; + CALL_BACK cb; +} PerfOption; + +typedef struct { + const char *path; + char *params[CMD_MAX_PARAMS]; +} SubCmd; + +#define OPTION_END() {.name = ""} +#define OPTION_UINT(n, v) {.type = OPTION_TYPE_UINT, .name = (n), .value = (v)} +#define OPTION_STRING(n, s) {.type = OPTION_TYPE_STRING, .name = (n), .str = (s)} +#define OPTION_CALLBACK(n, c) {.type = OPTION_TYPE_CALLBACK, .name = (n), .cb = (c)} + +int ParseOptions(int argc, char **argv, PerfOption *opt, SubCmd *cmd); +int ParseEvents(const char *argv, PerfEventConfig *eventsCfg, unsigned int *len); +int ParseIds(const char *argv, int *arr, unsigned int *len); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif + +#endif /* _OPTION_H */ diff --git a/src/kernel_liteos_a/apps/perf/include/perf.h b/src/kernel_liteos_a/apps/perf/include/perf.h new file mode 100644 index 00000000..2eccb5e1 --- /dev/null +++ b/src/kernel_liteos_a/apps/perf/include/perf.h @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef _PERF_H +#define _PERF_H + +#include + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define PERF_MAX_EVENT 7 +#define PERF_MAX_FILTER_TSKS 32 + +#ifdef PERF_DEBUG +#define printf_debug(fmt, ...) printf(fmt, ##__VA_ARGS__) +#else +#define printf_debug(fmt, ...) +#endif + +/* + * Perf types + */ +enum PerfEventType { + PERF_EVENT_TYPE_HW, /* boards common hw events */ + PERF_EVENT_TYPE_TIMED, /* hrtimer timed events */ + PERF_EVENT_TYPE_SW, /* software trace events */ + PERF_EVENT_TYPE_RAW, /* boards special hw events, see enum PmuEventType in corresponding arch headfile */ + + PERF_EVENT_TYPE_MAX +}; + +/* + * Common hardware pmu events + */ +enum PmuHwId { + PERF_COUNT_HW_CPU_CYCLES = 0, /* cpu cycle event */ + PERF_COUNT_HW_INSTRUCTIONS, /* instruction event */ + PERF_COUNT_HW_DCACHE_REFERENCES, /* dcache access event */ + PERF_COUNT_HW_DCACHE_MISSES, /* dcache miss event */ + PERF_COUNT_HW_ICACHE_REFERENCES, /* icache access event */ + PERF_COUNT_HW_ICACHE_MISSES, /* icache miss event */ + PERF_COUNT_HW_BRANCH_INSTRUCTIONS, /* software change of pc event */ + PERF_COUNT_HW_BRANCH_MISSES, /* branch miss event */ + + PERF_COUNT_HW_MAX, +}; + +/* + * Common hrtimer timed events + */ +enum PmuTimedId { + PERF_COUNT_CPU_CLOCK = 0, /* hrtimer timed event */ +}; + +/* + * Common software pmu events + */ +enum PmuSwId { + PERF_COUNT_SW_TASK_SWITCH = 1, /* task switch event */ + PERF_COUNT_SW_IRQ_RESPONSE, /* irq response event */ + PERF_COUNT_SW_MEM_ALLOC, /* memory alloc event */ + PERF_COUNT_SW_MUX_PEND, /* mutex pend event */ + + PERF_COUNT_SW_MAX, +}; + +/* + * perf sample data types + * Config it through PerfConfigAttr->sampleType. + */ +enum PerfSampleType { + PERF_RECORD_CPU = 1U << 0, /* record current cpuid */ + PERF_RECORD_TID = 1U << 1, /* record current task id */ + PERF_RECORD_TYPE = 1U << 2, /* record event type */ + PERF_RECORD_PERIOD = 1U << 3, /* record event period */ + PERF_RECORD_TIMESTAMP = 1U << 4, /* record timestamp */ + PERF_RECORD_IP = 1U << 5, /* record instruction pointer */ + PERF_RECORD_CALLCHAIN = 1U << 6, /* record backtrace */ + PERF_RECORD_PID = 1U << 7, /* record current process id */ +}; + +/* + * perf configuration sub event information + * + * This structure is used to config specific events attributes. + */ +typedef struct { + unsigned int type; /* enum PerfEventType */ + struct { + unsigned int eventId; /* the specific event corresponds to the PerfEventType */ + unsigned int period; /* event period, for every "period"th occurrence of the event a + sample will be recorded */ + } events[PERF_MAX_EVENT]; /* perf event list */ + unsigned int eventsNr; /* total perf event number */ + size_t predivided; /* whether to prescaler (once every 64 counts), + which only take effect on cpu cycle hardware event */ +} PerfEventConfig; + +/* + * perf configuration main information + * + * This structure is used to set perf sampling attributes, including events, tasks and other information. + */ +typedef struct { + PerfEventConfig eventsCfg; /* perf event config */ + unsigned int taskIds[PERF_MAX_FILTER_TSKS]; /* perf task filter list (allowlist) */ + unsigned int taskIdsNr; /* task numbers of task filter allowlist, + if set 0 perf will sample all tasks */ + unsigned int processIds[PERF_MAX_FILTER_TSKS]; /* perf process filter list (allowlist) */ + unsigned int processIdsNr; /* process numbers of process filter allowlist, + if set 0 perf will sample all processes */ + unsigned int sampleType; /* type of data to sample defined in PerfSampleType */ + size_t needSample; /* whether to sample data */ +} PerfConfigAttr; + +void PerfUsage(void); +void PerfDumpAttr(PerfConfigAttr *attr); +int PerfConfig(int fd, PerfConfigAttr *attr); +void PerfStart(int fd, size_t sectionId); +void PerfStop(int fd); +ssize_t PerfRead(int fd, char *buf, size_t size); +void PerfPrintBuffer(const char *buf, ssize_t num); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif + +#endif /* _PERF_H */ diff --git a/src/kernel_liteos_a/apps/perf/include/perf_list.h b/src/kernel_liteos_a/apps/perf/include/perf_list.h new file mode 100644 index 00000000..a65e9d70 --- /dev/null +++ b/src/kernel_liteos_a/apps/perf/include/perf_list.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef _PERF_LIST_H +#define _PERF_LIST_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef struct { + const char *name; + int event; + int type; +} PerfEvent; + +extern const PerfEvent g_events[]; +void PerfList(void); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif + +#endif /* _PERF_LIST_H */ diff --git a/src/kernel_liteos_a/apps/perf/include/perf_record.h b/src/kernel_liteos_a/apps/perf/include/perf_record.h new file mode 100644 index 00000000..b218eb75 --- /dev/null +++ b/src/kernel_liteos_a/apps/perf/include/perf_record.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _PERF_RECORD_H +#define _PERF_RECORD_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +void PerfRecord(int fd, int argc, char **argv); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif + +#endif /* _PERF_RECORD_H */ diff --git a/src/kernel_liteos_a/apps/perf/include/perf_stat.h b/src/kernel_liteos_a/apps/perf/include/perf_stat.h new file mode 100644 index 00000000..ad2a456c --- /dev/null +++ b/src/kernel_liteos_a/apps/perf/include/perf_stat.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _PERF_STAT_H +#define _PERF_STAT_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +void PerfStat(int fd, int argc, char **argv); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif + +#endif /* _PERF_STAT_H */ diff --git a/src/kernel_liteos_a/apps/perf/src/main.c b/src/kernel_liteos_a/apps/perf/src/main.c new file mode 100644 index 00000000..1482d490 --- /dev/null +++ b/src/kernel_liteos_a/apps/perf/src/main.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "perf.h" +#include "perf_list.h" +#include "perf_stat.h" +#include "perf_record.h" + +int main(int argc, char **argv) +{ +#define TWO_ARGS 2 +#define THREE_ARGS 3 + int fd = open("/dev/perf", O_RDWR); + if (fd == -1) { + printf("Perf open failed.\n"); + exit(EXIT_FAILURE); + } + + if (argc == 1) { + PerfUsage(); + } else if ((argc == TWO_ARGS) && strcmp(argv[1], "start") == 0) { + PerfStart(fd, 0); + } else if ((argc == THREE_ARGS) && strcmp(argv[1], "start") == 0) { + size_t id = strtoul(argv[THREE_ARGS - 1], NULL, 0); + PerfStart(fd, id); + } else if ((argc == TWO_ARGS) && strcmp(argv[1], "stop") == 0) { + PerfStop(fd); + } else if ((argc == THREE_ARGS) && strcmp(argv[1], "read") == 0) { + size_t size = strtoul(argv[THREE_ARGS - 1], NULL, 0); + if (size == 0) { + goto EXIT: + } + + char *buf = (char *)malloc(size); + if (buf != NULL) { + int len = PerfRead(fd, buf, size); + PerfPrintBuffer(buf, len); + free(buf); + buf = NULL; + } + } else if ((argc == TWO_ARGS) && strcmp(argv[1], "list") == 0) { + PerfList(); + } else if ((argc >= THREE_ARGS) && strcmp(argv[1], "stat") == 0) { + PerfStat(fd, argc, argv); + } else if ((argc >= THREE_ARGS) && strcmp(argv[1], "record") == 0) { + PerfRecord(fd, argc, argv); + } else { + printf("Unsupported perf command.\n"); + PerfUsage(); + } + +EXIT: + close(fd); + return 0; +} diff --git a/src/kernel_liteos_a/apps/perf/src/option.c b/src/kernel_liteos_a/apps/perf/src/option.c new file mode 100644 index 00000000..40ef3430 --- /dev/null +++ b/src/kernel_liteos_a/apps/perf/src/option.c @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "option.h" +#include "perf_list.h" + +static int ParseOption(char **argv, int *index, PerfOption *opts) +{ + int ret = 0; + const char *str = NULL; + + while ((opts->name != NULL) && (*opts->name != 0)) { + if (strcmp(argv[*index], opts->name) == 0) { + switch (opts->type) { + case OPTION_TYPE_UINT: + *opts->value = strtoul(argv[++(*index)], NULL, 0); + break; + case OPTION_TYPE_STRING: + *opts->str = argv[++(*index)]; + break; + case OPTION_TYPE_CALLBACK: + str = argv[++(*index)]; + if ((*opts->cb)(str) != 0) { + printf("parse error\n"); + ret = -1; + } + break; + default: + printf("invalid option\n"); + ret = -1; + break; + } + return ret; + } + opts++; + } + + return -1; +} + +int ParseOptions(int argc, char **argv, PerfOption *opts, SubCmd *cmd) +{ + int i; + int index = 0; + + while ((index < argc) && (argv[index] != NULL) && (*argv[index] == '-')) { + if (ParseOption(argv, &index, opts) != 0) { + return -1; + } + index++; + } + + if ((index < argc) && (argv[index] != NULL)) { + cmd->path = argv[index]; + cmd->params[0] = argv[index]; + index++; + } else { + printf("no subcmd to execute\n"); + return -1; + } + + for (i = 1; (index < argc) && (i < CMD_MAX_PARAMS); index++, i++) { + cmd->params[i] = argv[index]; + } + printf_debug("subcmd = %s\n", cmd->path); + for (int j = 0; j < i; j++) { + printf_debug("paras[%d]:%s\n", j, cmd->params[j]); + } + return 0; +} + +int ParseIds(const char *argv, int *arr, unsigned int *len) +{ + int res, ret; + unsigned int index = 0; + char *sp = NULL; + char *this = NULL; + char *list = strdup(argv); + + if (list == NULL) { + printf("no memory for ParseIds\n"); + return -1; + } + + sp = strtok_r(list, ",", &this); + while (sp) { + res = strtoul(sp, NULL, 0); + if (res < 0) { + ret = -1; + goto EXIT; + } + arr[index++] = res; + sp = strtok_r(NULL, ",", &this); + } + *len = index; + ret = 0; +EXIT: + free(list); + return ret; +} + +static inline const PerfEvent *StrToEvent(const char *str) +{ + const PerfEvent *evt = &g_events[0]; + + for (; evt->event != -1; evt++) { + if (strcmp(str, evt->name) == 0) { + return evt; + } + } + return NULL; +} + +int ParseEvents(const char *argv, PerfEventConfig *eventsCfg, unsigned int *len) +{ + int ret; + unsigned int index = 0; + const PerfEvent *event = NULL; + char *sp = NULL; + char *this = NULL; + char *list = strdup(argv); + + if (list == NULL) { + printf("no memory for ParseEvents\n"); + return -1; + } + + sp = strtok_r(list, ",", &this); + while (sp) { + event = StrToEvent(sp); + if (event == NULL) { + ret = -1; + goto EXIT; + } + + if (index == 0) { + eventsCfg->type = event->type; + } else if (eventsCfg->type != event->type) { + printf("events type must be same\n"); + ret = -1; + goto EXIT; + } + eventsCfg->events[index].eventId = event->event; + sp = strtok_r(NULL, ",", &this); + index++; + } + *len = index; + ret = 0; +EXIT: + free(list); + return ret; +} \ No newline at end of file diff --git a/src/kernel_liteos_a/apps/perf/src/perf.c b/src/kernel_liteos_a/apps/perf/src/perf.c new file mode 100644 index 00000000..aeafec0e --- /dev/null +++ b/src/kernel_liteos_a/apps/perf/src/perf.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include "perf.h" + +#define PERF_IOC_MAGIC 'T' +#define PERF_START _IO(PERF_IOC_MAGIC, 1) +#define PERF_STOP _IO(PERF_IOC_MAGIC, 2) + +void PerfUsage(void) +{ + printf("\nUsage: ./perf start [id]. Start perf.\n"); + printf("\nUsage: ./perf stop. Stop perf.\n"); + printf("\nUsage: ./perf read . Read nBytes raw data from perf buffer and print out.\n"); + printf("\nUsage: ./perf list. List events to be used in -e.\n"); + printf("\nUsage: ./perf stat/record [option] . \n" + "-e, event selector. use './perf list' to list available events.\n" + "-p, event period.\n" + "-o, perf data output filename.\n" + "-t, taskId filter(allowlist), if not set perf will sample all tasks.\n" + "-s, type of data to sample defined in PerfSampleType los_perf.h.\n" + "-P, processId filter(allowlist), if not set perf will sample all processes.\n" + "-d, whether to prescaler (once every 64 counts)," + "which only take effect on cpu cycle hardware event.\n" + ); +} + +static void PerfSetPeriod(PerfConfigAttr *attr) +{ + int i; + for (i = 1; i < attr->eventsCfg.eventsNr; i++) { + attr->eventsCfg.events[i].period = attr->eventsCfg.events[0].period; + } +} + +void PerfPrintBuffer(const char *buf, ssize_t num) +{ +#define BYTES_PER_LINE 4 + ssize_t i; + for (i = 0; i < num; i++) { + printf(" %02x", (unsigned char)buf[i]); + if (((i + 1) % BYTES_PER_LINE) == 0) { + printf("\n"); + } + } + printf("\n"); +} + +void PerfDumpAttr(PerfConfigAttr *attr) +{ + int i; + printf_debug("attr->type: %d\n", attr->eventsCfg.type); + for (i = 0; i < attr->eventsCfg.eventsNr; i++) { + printf_debug("attr->events[%d]: %d, 0x%x\n", i, attr->eventsCfg.events[i].eventId, + attr->eventsCfg.events[i].period); + } + printf_debug("attr->predivided: %d\n", attr->eventsCfg.predivided); + printf_debug("attr->sampleType: 0x%x\n", attr->sampleType); + + for (i = 0; i < attr->taskIdsNr; i++) { + printf_debug("attr->taskIds[%d]: %d\n", i, attr->taskIds[i]); + } + + for (i = 0; i < attr->processIdsNr; i++) { + printf_debug("attr->processIds[%d]: %d\n", i, attr->processIds[i]); + } + + printf_debug("attr->needSample: %d\n", attr->needSample); +} + + +void PerfStart(int fd, size_t sectionId) +{ + (void)ioctl(fd, PERF_START, sectionId); +} + +void PerfStop(int fd) +{ + (void)ioctl(fd, PERF_STOP, NULL); +} + +int PerfConfig(int fd, PerfConfigAttr *attr) +{ + if (attr == NULL) { + return -1; + } + PerfSetPeriod(attr); + PerfDumpAttr(attr); + return write(fd, attr, sizeof(PerfConfigAttr)); +} + +ssize_t PerfRead(int fd, char *buf, size_t size) +{ + ssize_t len; + if (buf == NULL) { + printf("Read buffer is null.\n"); + return 0; + } + + len = read(fd, buf, size); + return len; +} \ No newline at end of file diff --git a/src/kernel_liteos_a/apps/perf/src/perf_list.c b/src/kernel_liteos_a/apps/perf/src/perf_list.c new file mode 100644 index 00000000..73e6a6e8 --- /dev/null +++ b/src/kernel_liteos_a/apps/perf/src/perf_list.c @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "perf.h" +#include "perf_list.h" + +static const char *g_eventTypeStr[] = { + "[Hardware event]", + "[Timed event]", + "[Software event]", +}; + +const PerfEvent g_events[] = { +#ifdef LOSCFG_PERF_HW_PMU + { + .name = "cycles", + .event = PERF_COUNT_HW_CPU_CYCLES, + .type = PERF_EVENT_TYPE_HW, + }, + { + .name = "instruction", + .event = PERF_COUNT_HW_INSTRUCTIONS, + .type = PERF_EVENT_TYPE_HW, + }, + { + .name = "dcache", + .event = PERF_COUNT_HW_DCACHE_REFERENCES, + .type = PERF_EVENT_TYPE_HW, + }, + { + .name = "dcache-miss", + .event = PERF_COUNT_HW_DCACHE_MISSES, + .type = PERF_EVENT_TYPE_HW, + }, + { + .name = "icache", + .event = PERF_COUNT_HW_ICACHE_REFERENCES, + .type = PERF_EVENT_TYPE_HW, + }, + { + .name = "icache-miss", + .event = PERF_COUNT_HW_ICACHE_MISSES, + .type = PERF_EVENT_TYPE_HW, + }, + { + .name = "branch", + .event = PERF_COUNT_HW_BRANCH_INSTRUCTIONS, + .type = PERF_EVENT_TYPE_HW, + }, + { + .name = "branch-miss", + .event = PERF_COUNT_HW_BRANCH_MISSES, + .type = PERF_EVENT_TYPE_HW, + }, +#endif +#ifdef LOSCFG_PERF_TIMED_PMU + { + .name = "clock", + .event = PERF_COUNT_CPU_CLOCK, + .type = PERF_EVENT_TYPE_TIMED, + }, +#endif +#ifdef LOSCFG_PERF_SW_PMU + { + .name = "task-switch", + .event = PERF_COUNT_SW_TASK_SWITCH, + .type = PERF_EVENT_TYPE_SW, + }, + { + .name = "irq-in", + .event = PERF_COUNT_SW_IRQ_RESPONSE, + .type = PERF_EVENT_TYPE_SW, + }, + { + .name = "mem-alloc", + .event = PERF_COUNT_SW_MEM_ALLOC, + .type = PERF_EVENT_TYPE_SW, + }, + { + .name = "mux-pend", + .event = PERF_COUNT_SW_MUX_PEND, + .type = PERF_EVENT_TYPE_SW, + }, +#endif + { + .name = "", + .event = -1, + .type = PERF_EVENT_TYPE_MAX, + } +}; + +void PerfList(void) +{ + const PerfEvent *evt = &g_events[0]; + printf("\n"); + for (; evt->event != -1; evt++) { + printf("\t %-25s%30s\n", evt->name, g_eventTypeStr[evt->type]); + } + printf("\n"); +} diff --git a/src/kernel_liteos_a/apps/perf/src/perf_record.c b/src/kernel_liteos_a/apps/perf/src/perf_record.c new file mode 100644 index 00000000..98a64155 --- /dev/null +++ b/src/kernel_liteos_a/apps/perf/src/perf_record.c @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +#ifdef LOSCFG_FS_VFS +#include +#include +#endif + +#include "perf.h" +#include "option.h" +#include "perf_record.h" + +#define PERF_FILE_MODE 0644 +static PerfConfigAttr g_recordAttr; +static const char *g_savePath = "/storage/data/perf.data"; + +static inline int GetEvents(const char *argv) +{ + return ParseEvents(argv, &g_recordAttr.eventsCfg, &g_recordAttr.eventsCfg.eventsNr); +} + +static inline int GetTids(const char *argv) +{ + return ParseIds(argv, (int *)g_recordAttr.taskIds, &g_recordAttr.taskIdsNr); +} + +static inline int GetPids(const char *argv) +{ + return ParseIds(argv, (int *)g_recordAttr.processIds, &g_recordAttr.processIdsNr); +} + +static PerfOption g_recordOpts[] = { + OPTION_CALLBACK("-e", GetEvents), + OPTION_CALLBACK("-t", GetTids), + OPTION_CALLBACK("-P", GetPids), + OPTION_STRING("-o", &g_savePath), + OPTION_UINT("-p", &g_recordAttr.eventsCfg.events[0].period), + OPTION_UINT("-s", &g_recordAttr.sampleType), + OPTION_UINT("-d", &g_recordAttr.eventsCfg.predivided), +}; + +static int PerfRecordAttrInit(void) +{ + PerfConfigAttr attr = { + .eventsCfg = { +#ifdef LOSCFG_PERF_HW_PMU + .type = PERF_EVENT_TYPE_HW, + .events = { + [0] = {PERF_COUNT_HW_CPU_CYCLES, 0xFFFF}, + }, +#elif defined LOSCFG_PERF_TIMED_PMU + .type = PERF_EVENT_TYPE_TIMED, + .events = { + [0] = {PERF_COUNT_CPU_CLOCK, 100}, + }, +#elif defined LOSCFG_PERF_SW_PMU + .type = PERF_EVENT_TYPE_SW, + .events = { + [0] = {PERF_COUNT_SW_TASK_SWITCH, 1}, + }, +#endif + .eventsNr = 1, /* 1 event */ + .predivided = 0, + }, + .taskIds = {0}, + .taskIdsNr = 0, + .processIds = {0}, + .processIdsNr = 0, + .needSample = 1, + .sampleType = PERF_RECORD_IP | PERF_RECORD_CALLCHAIN, + }; + + return memcpy_s(&g_recordAttr, sizeof(PerfConfigAttr), &attr, sizeof(PerfConfigAttr)) != EOK ? -1 : 0; +} + +ssize_t PerfWriteFile(const char *filePath, const char *buf, ssize_t bufSize) +{ +#ifdef LOSCFG_FS_VFS + int fd = -1; + ssize_t totalToWrite = bufSize; + ssize_t totalWrite = 0; + + if (filePath == NULL || buf == NULL || bufSize == 0) { + return -1; + } + + fd = open(filePath, O_CREAT | O_RDWR | O_TRUNC, PERF_FILE_MODE); + if (fd < 0) { + printf("create file [%s] failed, fd: %d, %s!\n", filePath, fd, strerror(errno)); + return -1; + } + while (totalToWrite > 0) { + ssize_t writeThisTime = write(fd, buf, totalToWrite); + if (writeThisTime < 0) { + printf("failed to write file [%s], %s!\n", filePath, strerror(errno)); + (void)close(fd); + return -1; + } + buf += writeThisTime; + totalToWrite -= writeThisTime; + totalWrite += writeThisTime; + } + (void)fsync(fd); + (void)close(fd); + + return (totalWrite == bufSize) ? 0 : -1; +#else + (void)filePath; + PerfPrintBuffer(buf, bufSize); + return 0; +#endif +} + +void PerfRecord(int fd, int argc, char **argv) +{ + int ret; + int child; + char *buf; + ssize_t len; + SubCmd cmd = {0}; + + if (argc < 3) { /* perf record argc is at least 3 */ + return; + } + + ret = PerfRecordAttrInit(); + if (ret != 0) { + printf("perf record attr init failed\n"); + return; + } + + ret = ParseOptions(argc - 2, &argv[2], g_recordOpts, &cmd); /* parse option and cmd begin at index 2 */ + if (ret != 0) { + printf("parse error\n"); + return; + } + + ret = PerfConfig(fd, &g_recordAttr); + if (ret != 0) { + printf("perf config failed\n"); + return; + } + + PerfStart(fd, 0); + child = fork(); + if (child < 0) { + printf("fork error\n"); + PerfStop(fd); + return; + } else if (child == 0) { + (void)execve(cmd.path, cmd.params, NULL); + exit(0); + } + + waitpid(child, 0, 0); + PerfStop(fd); + + buf = (char *)malloc(LOSCFG_PERF_BUFFER_SIZE); + if (buf == NULL) { + printf("no memory for read perf 0x%x\n", LOSCFG_PERF_BUFFER_SIZE); + return; + } + len = PerfRead(fd, buf, LOSCFG_PERF_BUFFER_SIZE); + ret = PerfWriteFile(g_savePath, buf, len); + if (ret == 0) { + printf("save perf data success at %s\n", g_savePath); + } else { + printf("save perf data failed at %s\n", g_savePath); + } + free(buf); +} diff --git a/src/kernel_liteos_a/apps/perf/src/perf_stat.c b/src/kernel_liteos_a/apps/perf/src/perf_stat.c new file mode 100644 index 00000000..a1155048 --- /dev/null +++ b/src/kernel_liteos_a/apps/perf/src/perf_stat.c @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include "perf.h" +#include "option.h" +#include "perf_stat.h" + +static PerfConfigAttr g_statAttr; + +static inline int GetEvents(const char *argv) +{ + return ParseEvents(argv, &g_statAttr.eventsCfg, &g_statAttr.eventsCfg.eventsNr); +} + +static inline int GetTids(const char *argv) +{ + return ParseIds(argv, (int *)g_statAttr.taskIds, &g_statAttr.taskIdsNr); +} + +static inline int GetPids(const char *argv) +{ + return ParseIds(argv, (int *)g_statAttr.processIds, &g_statAttr.processIdsNr); +} + +static PerfOption g_statOpts[] = { + OPTION_CALLBACK("-e", GetEvents), + OPTION_CALLBACK("-t", GetTids), + OPTION_CALLBACK("-P", GetPids), + OPTION_UINT("-p", &g_statAttr.eventsCfg.events[0].period), + OPTION_UINT("-s", &g_statAttr.sampleType), + OPTION_UINT("-d", &g_statAttr.eventsCfg.predivided), +}; + +static int PerfStatAttrInit(void) +{ + PerfConfigAttr attr = { + .eventsCfg = { +#ifdef LOSCFG_PERF_HW_PMU + .type = PERF_EVENT_TYPE_HW, + .events = { + [0] = {PERF_COUNT_HW_CPU_CYCLES, 0xFFFF}, + [1] = {PERF_COUNT_HW_INSTRUCTIONS, 0xFFFFFF00}, + [2] = {PERF_COUNT_HW_ICACHE_REFERENCES, 0xFFFF}, + [3] = {PERF_COUNT_HW_DCACHE_REFERENCES, 0xFFFF}, + }, + .eventsNr = 4, /* 4 events */ +#elif defined LOSCFG_PERF_TIMED_PMU + .type = PERF_EVENT_TYPE_TIMED, + .events = { + [0] = {PERF_COUNT_CPU_CLOCK, 100}, + }, + .eventsNr = 1, /* 1 event */ +#elif defined LOSCFG_PERF_SW_PMU + .type = PERF_EVENT_TYPE_SW, + .events = { + [0] = {PERF_COUNT_SW_TASK_SWITCH, 1}, + [1] = {PERF_COUNT_SW_IRQ_RESPONSE, 1}, + [2] = {PERF_COUNT_SW_MEM_ALLOC, 1}, + [3] = {PERF_COUNT_SW_MUX_PEND, 1}, + }, + .eventsNr = 4, /* 4 events */ +#endif + .predivided = 0, + }, + .taskIds = {0}, + .taskIdsNr = 0, + .processIds = {0}, + .processIdsNr = 0, + .needSample = 0, + .sampleType = 0, + }; + + return memcpy_s(&g_statAttr, sizeof(PerfConfigAttr), &attr, sizeof(PerfConfigAttr)) != EOK ? -1 : 0; +} + +void PerfStat(int fd, int argc, char **argv) +{ + int ret; + int child; + SubCmd cmd = {0}; + + if (argc < 3) { /* perf stat argc is at least 3 */ + return; + } + + ret = PerfStatAttrInit(); + if (ret != 0) { + printf("perf stat attr init failed\n"); + return; + } + + ret = ParseOptions(argc - 2, &argv[2], g_statOpts, &cmd); /* parse option and cmd begin at index 2 */ + if (ret != 0) { + printf("parse error\n"); + return; + } + + ret = PerfConfig(fd, &g_statAttr); + if (ret != 0) { + printf("perf config failed\n"); + return; + } + + PerfStart(fd, 0); + child = fork(); + if (child < 0) { + printf("fork error\n"); + goto EXIT; + } else if (child == 0) { + (void)execve(cmd.path, cmd.params, NULL); + exit(0); + } + + (void)waitpid(child, 0, 0); +EXIT: + PerfStop(fd); +} + diff --git a/src/kernel_liteos_a/apps/shell/BUILD.gn b/src/kernel_liteos_a/apps/shell/BUILD.gn new file mode 100644 index 00000000..d7052575 --- /dev/null +++ b/src/kernel_liteos_a/apps/shell/BUILD.gn @@ -0,0 +1,44 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +executable("shell") { + sources = [ + "builtin/cd.c", + "src/main.c", + "src/shcmd.c", + "src/shcmdparse.c", + "src/shmsg.c", + ] + + deps = [ "$LITEOSTHIRDPARTY/bounds_checking_function:libsec_static" ] + + include_dirs = [ "include" ] +} diff --git a/src/kernel_liteos_a/apps/shell/Makefile b/src/kernel_liteos_a/apps/shell/Makefile new file mode 100644 index 00000000..16737994 --- /dev/null +++ b/src/kernel_liteos_a/apps/shell/Makefile @@ -0,0 +1,45 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(APPSTOPDIR)/config.mk + +APP_NAME := $(notdir $(shell pwd)) + +SECUREC_DIR := $(LITEOSTHIRDPARTY)/bounds_checking_function + +LOCAL_SRCS = $(wildcard src/*.c builtin/*.c) +LOCAL_SRCS += $(wildcard $(SECUREC_DIR)/src/*.c) + +LOCAL_INCLUDE := \ + -I include \ + -I $(SECUREC_DIR)/include + +LOCAL_FLAGS += $(LOCAL_INCLUDE) + +include $(APP) diff --git a/src/kernel_liteos_a/apps/shell/builtin/cd.c b/src/kernel_liteos_a/apps/shell/builtin/cd.c new file mode 100644 index 00000000..88e3eb93 --- /dev/null +++ b/src/kernel_liteos_a/apps/shell/builtin/cd.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#define _GNU_SOURCE + +#include "unistd.h" +#include "shcmd.h" +#include "sherr.h" + + +int Chdir(const char *tgtDir) +{ + int ret; + + if (!tgtDir) { + return SH_ERROR; + } + + ret = chdir(tgtDir); + if (ret == 0) { + ret = OsShellSetWorkingDirectory(tgtDir, strlen(tgtDir) + 1); /* 1: the length of '\0' */ + } + + return ret; +} + diff --git a/src/kernel_liteos_a/apps/shell/include/shcmd.h b/src/kernel_liteos_a/apps/shell/include/shcmd.h new file mode 100644 index 00000000..d1ab8b1c --- /dev/null +++ b/src/kernel_liteos_a/apps/shell/include/shcmd.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef _SHCMD_H +#define _SHCMD_H + +#include "string.h" +#include "stdlib.h" +#include "shell_list.h" +#include "shcmdparse.h" +#include "sherr.h" +#include "show.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef struct { + unsigned int count; + SH_List list; + char cmdString[0]; +} CmdKeyLink; + +#define NEED_NEW_LINE(timesPrint, lineCap) ((timesPrint) % (lineCap) == 0) +#define SCREEN_IS_FULL(timesPrint, lineCap) ((timesPrint) >= ((lineCap) * DEFAULT_SCREEN_HEIGHT)) + +extern unsigned int OsCmdExec(CmdParsed *cmdParsed, char *cmdStr); +extern unsigned int OsCmdKeyShift(const char *cmdKey, char *cmdOut, unsigned int size); +extern int OsTabCompletion(char *cmdKey, unsigned int *len); +extern void OsShellCmdPush(const char *string, CmdKeyLink *cmdKeyLink); +extern void OsShellHistoryShow(unsigned int value, ShellCB *shellCB); +extern unsigned int OsShellKeyInit(ShellCB *shellCB); +extern void OsShellKeyDeInit(CmdKeyLink *cmdKeyLink); +extern int OsShellSetWorkingDirectory(const char *dir, size_t len); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif + +#endif /* _SHCMD_H */ diff --git a/src/kernel_liteos_a/apps/shell/include/shcmdparse.h b/src/kernel_liteos_a/apps/shell/include/shcmdparse.h new file mode 100644 index 00000000..94e8f89d --- /dev/null +++ b/src/kernel_liteos_a/apps/shell/include/shcmdparse.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SHCMDPARSE_H +#define _SHCMDPARSE_H + +#include "string.h" +#include "show.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +/* + * Description: the info struct after cmd parser + */ +typedef struct { + unsigned int paramCnt; /* count of para */ + CmdType cmdType; /* cmd type, judge cmd keyword */ + char cmdKeyword[CMD_KEY_LEN]; /* cmd keyword str */ + char *paramArray[CMD_MAX_PARAS]; +} CmdParsed; + +extern unsigned int OsCmdParse(char *cmdStr, CmdParsed *cmdParsed); +extern char *OsCmdParseStrdup(const char *str); +extern unsigned int OsCmdParseOneToken(CmdParsed *cmdParsed, unsigned int index, const char *token); +extern unsigned int OsCmdTokenSplit(char *cmdStr, char split, CmdParsed *cmdParsed); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif + +#endif /* _SHCMDPARSE_H */ diff --git a/src/kernel_liteos_a/apps/shell/include/shell.h b/src/kernel_liteos_a/apps/shell/include/shell.h new file mode 100644 index 00000000..ebc94e0d --- /dev/null +++ b/src/kernel_liteos_a/apps/shell/include/shell.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SHELL_H +#define _SHELL_H + +#include "pthread.h" +#include "semaphore.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/* Max len of show str */ +#define SHOW_MAX_LEN CMD_MAX_LEN + +#define SHELL_PROCESS_PRIORITY_INIT 15 + +#define PATH_MAX 256 +#define CMD_MAX_PARAS 32 +#define CMD_KEY_LEN 16U +#define CMD_MAX_LEN (256U + CMD_KEY_LEN) +#define CMD_KEY_NUM 32 +#define CMD_HISTORY_LEN 10 +#define CMD_MAX_PATH 256 +#define DEFAULT_SCREEN_WIDTH 80 +#define DEFAULT_SCREEN_HEIGHT 24 + +#define SWITCH_QUOTES_STATUS(qu) do { \ + if ((qu) == TRUE) { \ + (qu) = FALSE; \ + } else { \ + (qu) = TRUE; \ + } \ +} while (0) + +#define QUOTES_STATUS_CLOSE(qu) ((qu) == FALSE) +#define QUOTES_STATUS_OPEN(qu) ((qu) == TRUE) + + +typedef struct { + unsigned int consoleID; + pthread_t shellTaskHandle; + pthread_t shellEntryHandle; + void *cmdKeyLink; + void *cmdHistoryKeyLink; + void *cmdMaskKeyLink; + unsigned int shellBufOffset; + unsigned int shellKeyType; + sem_t shellSem; + pthread_mutex_t keyMutex; + pthread_mutex_t historyMutex; + char shellBuf[SHOW_MAX_LEN]; + char shellWorkingDirectory[PATH_MAX]; +} ShellCB; + +/* All support cmd types */ +typedef enum { + CMD_TYPE_SHOW = 0, + CMD_TYPE_STD = 1, + CMD_TYPE_EX = 2, + CMD_TYPE_BUTT +} CmdType; + +typedef enum { + CMD_KEY_UP = 0, + CMD_KEY_DOWN = 1, + CMD_KEY_RIGHT = 2, + CMD_KEY_LEFT = 4, + CMD_KEY_BUTT +} CmdKeyDirection; + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _SHELL_H */ diff --git a/src/kernel_liteos_a/apps/shell/include/shell_list.h b/src/kernel_liteos_a/apps/shell/include/shell_list.h new file mode 100644 index 00000000..25030234 --- /dev/null +++ b/src/kernel_liteos_a/apps/shell/include/shell_list.h @@ -0,0 +1,574 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SHELL_LIST_H +#define _SHELL_LIST_H + +#include "sherr.h" +#include "stdint.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef size_t bool; + +/** + * @ingroup shell_list + * Structure of a node in a doubly linked list. + */ +typedef struct SH_List { + struct SH_List *pstPrev; /**< Current node's pointer to the previous node */ + struct SH_List *pstNext; /**< Current node's pointer to the next node */ +} SH_List; + +/** + * @ingroup shell_list + * + * @par Description: + * This API is used to initialize a doubly linked list. + * @attention + *
            + *
          • The parameter passed in should be ensured to be a legal pointer.
          • + *
          + * + * @param list [IN] Node in a doubly linked list. + * + * @retval None. + * @par Dependency: + *
          • shell_list.h: the header file that contains the API declaration.
          + * @see + */ +static inline void SH_ListInit(SH_List *list) +{ + list->pstNext = list; + list->pstPrev = list; +} + +/** + * @ingroup shell_list + * @brief Point to the next node pointed to by the current node. + * + * @par Description: + *
            + *
          • This API is used to point to the next node pointed to by the current node.
          • + *
          + * @attention + *
            + *
          • None.
          • + *
          + * + * @param object [IN] Node in the doubly linked list. + * + * @retval None. + * @par Dependency: + *
          • shell_list.h: the header file that contains the API declaration.
          + * @see + */ +#define SH_LIST_FIRST(object) ((object)->pstNext) + +/** + * @ingroup shell_list + * @brief Point to the previous node pointed to by the current node. + * + * @par Description: + *
            + *
          • This API is used to point to the previous node pointed to by the current node.
          • + *
          + * @attention + *
            + *
          • None.
          • + *
          + * + * @param object [IN] Node in the doubly linked list. + * + * @retval None. + * @par Dependency: + *
          • shell_list.h: the header file that contains the API declaration.
          + * @see + */ +#define SH_LIST_LAST(object) ((object)->pstPrev) + +/** + * @ingroup shell_list + * @brief Insert a new node to a doubly linked list. + * + * @par Description: + * This API is used to insert a new node to a doubly linked list. + * @attention + *
            + *
          • The parameters passed in should be ensured to be legal pointers.
          • + *
          + * + * @param list [IN] Doubly linked list where the new node is inserted. + * @param node [IN] New node to be inserted. + * + * @retval None + * @par Dependency: + *
          • shell_list.h: the header file that contains the API declaration.
          + * @see SH_ListDelete + */ +static inline void SH_ListAdd(SH_List *list, SH_List *node) +{ + node->pstNext = list->pstNext; + node->pstPrev = list; + list->pstNext->pstPrev = node; + list->pstNext = node; +} + +/** + * @ingroup shell_list + * @brief Insert a node to the tail of a doubly linked list. + * + * @par Description: + * This API is used to insert a new node to the tail of a doubly linked list. + * @attention + *
            + *
          • The parameters passed in should be ensured to be legal pointers.
          • + *
          + * + * @param list [IN] Doubly linked list where the new node is inserted. + * @param node [IN] New node to be inserted. + * + * @retval None. + * @par Dependency: + *
          • shell_list.h: the header file that contains the API declaration.
          + * @see SH_ListAdd | SH_ListHeadInsert + */ +static inline void SH_ListTailInsert(SH_List *list, SH_List *node) +{ + if ((list == NULL) || (node == NULL)) { + return; + } + + SH_ListAdd(list->pstPrev, node); +} + +/** + * @ingroup shell_list + * @brief Insert a node to the head of a doubly linked list. + * + * @par Description: + * This API is used to insert a new node to the head of a doubly linked list. + * @attention + *
            + *
          • The parameters passed in should be ensured to be legal pointers.
          • + *
          + * + * @param list [IN] Doubly linked list where the new node is inserted. + * @param node [IN] New node to be inserted. + * + * @retval None. + * @par Dependency: + *
          • shell_list.h: the header file that contains the API declaration.
          + * @see SH_ListAdd | SH_ListTailInsert + */ +static inline void SH_ListHeadInsert(SH_List *list, SH_List *node) +{ + if ((list == NULL) || (node == NULL)) { + return; + } + + SH_ListAdd(list, node); +} + +/** + * @ingroup shell_list + * + * @par Description: + *
            + *
          • This API is used to delete a specified node from a doubly linked list.
          • + *
          + * @attention + *
            + *
          • The parameter passed in should be ensured to be a legal pointer.
          • + *
          + * + * @param node [IN] Node to be deleted. + * + * @retval None. + * @par Dependency: + *
          • shell_list.h: the header file that contains the API declaration.
          + * @see SH_ListAdd + */ +static inline void SH_ListDelete(SH_List *node) +{ + node->pstNext->pstPrev = node->pstPrev; + node->pstPrev->pstNext = node->pstNext; + node->pstNext = NULL; + node->pstPrev = NULL; +} + +/** + * @ingroup shell_list + * @brief Identify whether a specified doubly linked list is empty. + * + * @par Description: + *
            + *
          • This API is used to return whether a doubly linked list is empty.
          • + *
          + * @attention + *
            + *
          • The parameter passed in should be ensured to be a legal pointer.
          • + *
          + * + * @param list [IN] Doubly linked list. + * + * @retval TRUE The doubly linked list is empty. + * @retval FALSE The doubly linked list is not empty. + * @par Dependency: + *
          • shell_list.h: the header file that contains the API declaration.
          + * @see + */ +static inline bool SH_ListEmpty(SH_List *list) +{ + if (list == NULL) { + return FALSE; + } + + return (bool)(list->pstNext == list); +} + +/** + * @ingroup shell_list + * @brief Insert a new list to a doubly linked list. + * + * @par Description: + * This API is used to insert a new list to a doubly linked list. + * @attention + *
            + *
          • The parameters passed in should be ensured to be legal pointers.
          • + *
          + * + * @param oldList [IN] Doubly linked list where the new list is inserted. + * @param newList [IN] New list to be inserted. + * + * @retval None + * @par Dependency: + *
          • shell_list.h: the header file that contains the API declaration.
          + * @see SH_ListDelete + */ +static inline void SH_ListAddList(SH_List *oldList, SH_List *newList) +{ + SH_List *oldListHead = oldList->pstNext; + SH_List *oldListTail = oldList; + SH_List *newListHead = newList; + SH_List *newListTail = newList->pstPrev; + + oldListTail->pstNext = newListHead; + newListHead->pstPrev = oldListTail; + oldListHead->pstPrev = newListTail; + newListTail->pstNext = oldListHead; +} + +/** + * @ingroup shell_list + * @brief Insert a doubly list to the tail of a doubly linked list. + * + * @par Description: + * This API is used to insert a new doubly list to the tail of a doubly linked list. + * @attention + *
            + *
          • The parameters passed in should be ensured to be legal pointers.
          • + *
          + * + * @param oldList [IN] Doubly linked list where the new list is inserted. + * @param newList [IN] New list to be inserted. + * + * @retval None. + * @par Dependency: + *
          • shell_list.h: the header file that contains the API declaration.
          + * @see SH_ListAddList | SH_ListHeadInsertList + */ +static inline void SH_ListTailInsertList(SH_List *oldList, SH_List *newList) +{ + SH_ListAddList(oldList->pstPrev, newList); +} + +/** + * @ingroup shell_list + * @brief Insert a doubly list to the head of a doubly linked list. + * + * @par Description: + * This API is used to insert a new doubly list to the head of a doubly linked list. + * @attention + *
            + *
          • The parameters passed in should be ensured to be legal pointers.
          • + *
          + * + * @param oldList [IN] Doubly linked list where the new list is inserted. + * @param newList [IN] New list to be inserted. + * + * @retval None. + * @par Dependency: + *
          • shell_list.h: the header file that contains the API declaration.
          + * @see SH_ListAddList | SH_ListTailInsertList + */ +static inline void SH_ListHeadInsertList(SH_List *oldList, SH_List *newList) +{ + SH_ListAddList(oldList, newList); +} + +/** + * @ingroup shell_list + * @brief Obtain the offset of a field to a structure address. + * + * @par Description: + * This API is used to obtain the offset of a field to a structure address. + * @attention + *
            + *
          • None.
          • + *
          + * + * @param type [IN] Structure name. + * @param member [IN] Name of the member of which the offset is to be measured. + * + * @retval Offset of the field to the structure address. + * @par Dependency: + *
          • shell_list.h: the header file that contains the API declaration.
          + * @see + */ +#define LOS_OFF_SET_OF(type, member) ((uintptr_t)&((type *)0)->member) + +/** + * @ingroup shell_list + * @brief Obtain the pointer to a structure that contains a doubly linked list. + * + * @par Description: + * This API is used to obtain the pointer to a structure that contains a doubly linked list. + *
            + *
          • None.
          • + *
          + * @attention + *
            + *
          • None.
          • + *
          + * + * @param item [IN] Current node's pointer to the next node. + * @param type [IN] Structure name. + * @param member [IN] Member name of the doubly linked list in the structure. + * + * @retval Pointer to the structure that contains the doubly linked list. + * @par Dependency: + *
          • shell_list.h: the header file that contains the API declaration.
          + * @see + */ +#define SH_LIST_ENTRY(item, type, member) \ + ((type *)(void *)((char *)(item) - LOS_OFF_SET_OF(type, member))) + +/** + * @ingroup shell_list + * @brief Iterate over a doubly linked list of given type. + * + * @par Description: + * This API is used to iterate over a doubly linked list of given type. + * @attention + *
            + *
          • None.
          • + *
          + * + * @param item [IN] Pointer to the structure that contains the doubly linked list that is to be traversed. + * @param list [IN] Pointer to the doubly linked list to be traversed. + * @param type [IN] Structure name. + * @param member [IN] Member name of the doubly linked list in the structure. + * + * @retval None. + * @par Dependency: + *
          • shell_list.h: the header file that contains the API declaration.
          + * @see + */ +#define SH_LIST_FOR_EACH_ENTRY(item, list, type, member) \ + for (item = SH_LIST_ENTRY((list)->pstNext, type, member); \ + &(item)->member != (list); \ + item = SH_LIST_ENTRY((item)->member.pstNext, type, member)) + +/** + * @ingroup shell_list + * @brief iterate over a doubly linked list safe against removal of list entry. + * + * @par Description: + * This API is used to iterate over a doubly linked list safe against removal of list entry. + * @attention + *
            + *
          • None.
          • + *
          + * + * @param item [IN] Pointer to the structure that contains the doubly linked list that is to be traversed. + * @param next [IN] Save the next node. + * @param list [IN] Pointer to the doubly linked list to be traversed. + * @param type [IN] Structure name. + * @param member [IN] Member name of the doubly linked list in the structure. + * + * @retval None. + * @par Dependency: + *
          • shell_list.h: the header file that contains the API declaration.
          + * @see + */ +#define SH_LIST_FOR_EACH_ENTRY_SAFE(item, next, list, type, member) \ + for (item = SH_LIST_ENTRY((list)->pstNext, type, member), \ + next = SH_LIST_ENTRY((item)->member.pstNext, type, member); \ + &(item)->member != (list); \ + item = next, next = SH_LIST_ENTRY((item)->member.pstNext, type, member)) + +/** + * @ingroup shell_list + * @brief Delete initialize a doubly linked list. + * + * @par Description: + * This API is used to delete initialize a doubly linked list. + * @attention + *
            + *
          • The parameter passed in should be ensured to be s legal pointer.
          • + *
          + * + * @param list [IN] Doubly linked list. + * + * @retval None. + * @par Dependency: + *
          • shell_list.h: the header file that contains the API declaration.
          + * @see + */ +static inline void SH_ListDelInit(SH_List *list) +{ + list->pstNext->pstPrev = list->pstPrev; + list->pstPrev->pstNext = list->pstNext; + SH_ListInit(list); +} + +/** + * @ingroup shell_list + * @brief iterate over a doubly linked list. + * + * @par Description: + * This API is used to iterate over a doubly linked list. + * @attention + *
            + *
          • None.
          • + *
          + * + * @param item [IN] Pointer to the structure that contains the doubly linked list that is to be traversed. + * @param list [IN] Pointer to the doubly linked list to be traversed. + * + * @retval None. + * @par Dependency: + *
          • shell_list.h: the header file that contains the API declaration.
          + * @see + */ +#define SH_LIST_FOR_EACH(item, list) \ + for (item = (list)->pstNext; \ + (item) != (list); \ + item = (item)->pstNext) + +/** + * @ingroup shell_list + * @brief Iterate over a doubly linked list safe against removal of list entry. + * + * @par Description: + * This API is used to iterate over a doubly linked list safe against removal of list entry. + * @attention + *
            + *
          • None.
          • + *
          + * + * @param item [IN] Pointer to the structure that contains the doubly linked list that is to be traversed. + * @param next [IN] Save the next node. + * @param list [IN] Pointer to the doubly linked list to be traversed. + * + * @retval None. + * @par Dependency: + *
          • shell_list.h: the header file that contains the API declaration.
          + * @see + */ +#define SH_LIST_FOR_EACH_SAFE(item, next, list) \ + for (item = (list)->pstNext, next = (item)->pstNext; \ + (item) != (list); \ + item = next, next = (item)->pstNext) + +/** + * @ingroup shell_list + * @brief Initialize a double linked list. + * + * @par Description: + * This API is used to initialize a double linked list. + * @attention + *
            + *
          • None.
          • + *
          + * + * @param list [IN] Pointer to the doubly linked list to be traversed. + * + * @retval None. + * @par Dependency: + *
          • shell_list.h: the header file that contains the API declaration.
          + * @see + */ +#define SH_LIST_HEAD(list) SH_List list = { &(list), &(list) } + +#define SH_ListPeekHeadType(list, type, element) do { \ + type *__t; \ + if ((list)->pstNext == list) { \ + __t = NULL; \ + } else { \ + __t = SH_LIST_ENTRY((list)->pstNext, type, element); \ + } \ + __t; \ +} while (0) + +#define SH_ListRemoveHeadType(list, type, element) do { \ + type *__t; \ + if ((list)->pstNext == list) { \ + __t = NULL; \ + } else { \ + __t = SH_LIST_ENTRY((list)->pstNext, type, element); \ + SH_ListDelete((list)->pstNext); \ + } \ + __t; \ +} while (0) + +#define SH_ListNextType(list, item, type, element) do { \ + type *__t; \ + if ((item)->pstNext == list) { \ + __t = NULL; \ + } else { \ + __t = SH_LIST_ENTRY((item)->pstNext, type, element); \ + } \ + __t; \ +} while (0) + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _SHELL_LIST_H */ diff --git a/src/kernel_liteos_a/apps/shell/include/shell_pri.h b/src/kernel_liteos_a/apps/shell/include/shell_pri.h new file mode 100644 index 00000000..11dd582d --- /dev/null +++ b/src/kernel_liteos_a/apps/shell/include/shell_pri.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SHELL_PRI_H +#define _SHELL_PRI_H + +#include "shell.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +extern void ShellEntry(ShellCB *shellCB); +extern void *ShellTask(void *argv); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _SHELL_PRI_H */ diff --git a/src/kernel_liteos_a/apps/shell/include/sherr.h b/src/kernel_liteos_a/apps/shell/include/sherr.h new file mode 100644 index 00000000..9645a97b --- /dev/null +++ b/src/kernel_liteos_a/apps/shell/include/sherr.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SHERR_H +#define _SHERR_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define SH_ERROR -1 +#define SH_OK 0 +#define SH_NOK -1 + +#ifndef TRUE +# define TRUE 1 +#endif +#ifndef FALSE +# define FALSE 0 +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _SHERR_H */ + diff --git a/src/kernel_liteos_a/apps/shell/include/shmsg.h b/src/kernel_liteos_a/apps/shell/include/shmsg.h new file mode 100644 index 00000000..a2cb6874 --- /dev/null +++ b/src/kernel_liteos_a/apps/shell/include/shmsg.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SHMSG_H +#define _SHMSG_H + +#include "shell_list.h" +#include "shell.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define SHELL_ENTRY_STACKSIZE 0x1000 +#define SHELL_TASK_STACKSIZE 0x3000 + +#define SHELL_EXEC_COMMAND "exec" +#define SHELL_EXEC_COMMAND_BYTES 4 +#define CMD_EXEC_COMMAND SHELL_EXEC_COMMAND" " +#define CMD_EXEC_COMMAND_BYTES (SHELL_EXEC_COMMAND_BYTES + 1) +#define CMD_EXIT_COMMAND "exit" +#define CMD_EXIT_COMMAND_BYTES 4 +#define CMD_EXIT_CODE_BASE_DEC 10 + +#define CONSOLE_IOC_MAGIC 'c' +#define CONSOLE_CONTROL_REG_USERTASK _IO(CONSOLE_IOC_MAGIC, 7) + +#define COLOR_NONE "\e[0m" +#define COLOR_RED "\e[0;31m" +#define COLOR_L_RED "\e[1;31m" +#define SHELL_PROMPT COLOR_L_RED"OHOS # "COLOR_NONE + +typedef void (* OutputFunc)(const char *fmt, ...); +extern int ShellTaskInit(ShellCB *shellCB); +extern void ChildExec(const char *cmdName, char *const paramArray[], bool foreground); +extern void ShellCmdLineParse(char c, OutputFunc outputFunc, ShellCB *shellCB); +extern int ShellNotify(ShellCB *shellCB); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _SHMSG_H */ diff --git a/src/kernel_liteos_a/apps/shell/include/show.h b/src/kernel_liteos_a/apps/shell/include/show.h new file mode 100644 index 00000000..542f27ac --- /dev/null +++ b/src/kernel_liteos_a/apps/shell/include/show.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SHOW_H +#define _SHOW_H + +#include "stdarg.h" + +#include "shell.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +extern char *OsShellGetWorkingDirectory(void); +extern unsigned int OsShellInit(void); +extern int OsShellDeinit(ShellCB *shellCB); +extern ShellCB *OsGetShellCb(void); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _SHOW_H */ diff --git a/src/kernel_liteos_a/apps/shell/src/main.c b/src/kernel_liteos_a/apps/shell/src/main.c new file mode 100644 index 00000000..37e0ebbd --- /dev/null +++ b/src/kernel_liteos_a/apps/shell/src/main.c @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include "show.h" +#include "shmsg.h" +#include "shcmd.h" +#include "shell_pri.h" +#include "semaphore.h" +#include "securec.h" + +ShellCB *g_shellCB = NULL; + +ShellCB *OsGetShellCb(void) +{ + return g_shellCB; +} + +static void ShellDeinit(ShellCB *shellCB) +{ + (void)pthread_mutex_destroy(&shellCB->historyMutex); + (void)pthread_mutex_destroy(&shellCB->keyMutex); + OsShellKeyDeInit((CmdKeyLink *)shellCB->cmdKeyLink); + OsShellKeyDeInit((CmdKeyLink *)shellCB->cmdHistoryKeyLink); + (void)free(shellCB); +} + +static int OsShellCreateTask(ShellCB *shellCB) +{ + struct sched_param param = { 0 }; + int ret; + + ret = sched_getparam(getpid(), ¶m); + if (ret != SH_OK) { + return ret; + } + + param.sched_priority = SHELL_PROCESS_PRIORITY_INIT; + + ret = sched_setparam(getpid(), ¶m); + if (ret != SH_OK) { + return ret; + } + + ret = ShellTaskInit(shellCB); + if (ret != SH_OK) { + return ret; + } + + shellCB->shellEntryHandle = pthread_self(); + return 0; +} + +static int DoShellExec(char **argv) +{ + int i, j; + int len = 0; + int ret = SH_NOK; + char *cmdLine = NULL; + + if (strncmp(argv[0], SHELL_EXEC_COMMAND, SHELL_EXEC_COMMAND_BYTES) == 0) { + ChildExec(argv[1], argv + 1, FALSE); + } + for (i = 0; argv[i]; i++) { + len += strlen(argv[i]); + } + len += i + 1; + cmdLine = (char *)malloc(len); + if (!cmdLine) { + return ret; + } + errno_t ret1 = memset_s(cmdLine, len, 0, len); + if (ret1 != EOK) { + free(cmdLine); + return ret1; + } + + for (j = 0; j < i; j++) { + (void)strcat_s(cmdLine, len, argv[j]); + (void)strcat_s(cmdLine, len, " "); + } + + cmdLine[len - 2] = '\0'; /* 2, (len - 2) is the end of cmdline buf */ + ret = syscall(__NR_shellexec, argv[0], cmdLine); + free(cmdLine); + return ret; +} + +static void ShellSigChildHook(int sig) +{ + (void)sig; + + while (waitpid(-1, NULL, WNOHANG) > 0) { + continue; + } +} + +int main(int argc, char **argv) +{ + int ret = SH_NOK; + ShellCB *shellCB = NULL; + + (void)signal(SIGCHLD, ShellSigChildHook); + + if (argc > 1) { + ret = DoShellExec(argv + 1); + return ret; + } + + setbuf(stdout, NULL); + + shellCB = (ShellCB *)malloc(sizeof(ShellCB)); + if (shellCB == NULL) { + return SH_NOK; + } + ret = memset_s(shellCB, sizeof(ShellCB), 0, sizeof(ShellCB)); + if (ret != SH_OK) { + goto ERR_OUT1; + } + + ret = pthread_mutex_init(&shellCB->keyMutex, NULL); + if (ret != SH_OK) { + goto ERR_OUT1; + } + + ret = pthread_mutex_init(&shellCB->historyMutex, NULL); + if (ret != SH_OK) { + goto ERR_OUT2; + } + + ret = (int)OsShellKeyInit(shellCB); + if (ret != SH_OK) { + goto ERR_OUT3; + } + (void)strncpy_s(shellCB->shellWorkingDirectory, PATH_MAX, "/", 2); /* 2:space for "/" */ + + sem_init(&shellCB->shellSem, 0, 0); + + g_shellCB = shellCB; + ret = OsShellCreateTask(shellCB); + if (ret != SH_OK) { + ShellDeinit(shellCB); + g_shellCB = NULL; + return ret; + } + + ShellEntry(shellCB); + +ERR_OUT3: + (void)pthread_mutex_destroy(&shellCB->historyMutex); +ERR_OUT2: + (void)pthread_mutex_destroy(&shellCB->keyMutex); +ERR_OUT1: + (void)free(shellCB); + return ret; +} + diff --git a/src/kernel_liteos_a/apps/shell/src/shcmd.c b/src/kernel_liteos_a/apps/shell/src/shcmd.c new file mode 100644 index 00000000..e51dee3d --- /dev/null +++ b/src/kernel_liteos_a/apps/shell/src/shcmd.c @@ -0,0 +1,594 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "shcmd.h" +#include "show.h" +#include "stdlib.h" +#include "unistd.h" +#include "dirent.h" +#include "securec.h" + +#define SHELL_INIT_MAGIC_FLAG 0xABABABAB +#define CTRL_C 0x03 /* 0x03: ctrl+c ASCII */ + +static void OsFreeCmdPara(CmdParsed *cmdParsed) +{ + unsigned int i; + for (i = 0; i < cmdParsed->paramCnt; i++) { + if ((cmdParsed->paramArray[i]) != NULL) { + free((cmdParsed->paramArray[i])); + cmdParsed->paramArray[i] = NULL; + } + } +} + +static int OsStrSeparateTabStrGet(const char **tabStr, CmdParsed *parsed, unsigned int tabStrLen) +{ + char *shiftStr = NULL; + char *tempStr = (char *)malloc(SHOW_MAX_LEN << 1); + if (tempStr == NULL) { + return (int)SH_ERROR; + } + + (void)memset_s(tempStr, SHOW_MAX_LEN << 1, 0, SHOW_MAX_LEN << 1); + shiftStr = tempStr + SHOW_MAX_LEN; + + if (strncpy_s(tempStr, SHOW_MAX_LEN - 1, *tabStr, tabStrLen)) { + free(tempStr); + return (int)SH_ERROR; + } + + parsed->cmdType = CMD_TYPE_STD; + + /* cut useless or repeat space */ + if (OsCmdKeyShift(tempStr, shiftStr, SHOW_MAX_LEN - 1)) { + free(tempStr); + return (int)SH_ERROR; + } + + /* get exact position of string to complete */ + /* situation different if end space lost or still exist */ + if ((strlen(shiftStr) == 0) || (tempStr[strlen(tempStr) - 1] != shiftStr[strlen(shiftStr) - 1])) { + *tabStr = ""; + } else { + if (OsCmdParse(shiftStr, parsed)) { + free(tempStr); + return (int)SH_ERROR; + } + *tabStr = parsed->paramArray[parsed->paramCnt - 1]; + } + + free(tempStr); + return SH_OK; +} + +char *OsShellGetWorkingDirectory(void) +{ + return OsGetShellCb()->shellWorkingDirectory; +} + +int OsShellSetWorkingDirectory(const char *dir, size_t len) +{ + if (dir == NULL) { + return SH_NOK; + } + + int ret = strncpy_s(OsGetShellCb()->shellWorkingDirectory, sizeof(OsGetShellCb()->shellWorkingDirectory), + dir, len); + if (ret != SH_OK) { + return SH_NOK; + } + return SH_OK; +} + +static int OsStrSeparate(const char *tabStr, char *strPath, char *nameLooking, unsigned int tabStrLen) +{ + char *strEnd = NULL; + char *cutPos = NULL; + CmdParsed parsed = {0}; + char *shellWorkingDirectory = OsShellGetWorkingDirectory(); + int ret; + + ret = OsStrSeparateTabStrGet(&tabStr, &parsed, tabStrLen); + if (ret != SH_OK) { + return ret; + } + + /* get fullpath str */ + if (*tabStr != '/') { + if (strncpy_s(strPath, CMD_MAX_PATH, shellWorkingDirectory, CMD_MAX_PATH - 1)) { + OsFreeCmdPara(&parsed); + return (int)SH_ERROR; + } + if (strcmp(shellWorkingDirectory, "/")) { + if (strncat_s(strPath, CMD_MAX_PATH - 1, "/", CMD_MAX_PATH - strlen(strPath) - 1)) { + OsFreeCmdPara(&parsed); + return (int)SH_ERROR; + } + } + } + + if (strncat_s(strPath, CMD_MAX_PATH - 1, tabStr, CMD_MAX_PATH - strlen(strPath) - 1)) { + OsFreeCmdPara(&parsed); + return (int)SH_ERROR; + } + + /* split str by last '/' */ + strEnd = strrchr(strPath, '/'); + if (strEnd != NULL) { + if (strncpy_s(nameLooking, CMD_MAX_PATH, strEnd + 1, CMD_MAX_PATH - 1)) { /* get cmp str */ + OsFreeCmdPara(&parsed); + return (int)SH_ERROR; + } + } + + cutPos = strrchr(strPath, '/'); + if (cutPos != NULL) { + *(cutPos + 1) = '\0'; + } + + OsFreeCmdPara(&parsed); + return SH_OK; +} + +static int OsShowPageInputControl(void) +{ + char readChar; + + while (1) { + if (read(STDIN_FILENO, &readChar, 1) != 1) { /* get one char from stdin */ + printf("\n"); + return (int)SH_ERROR; + } + if ((readChar == 'q') || (readChar == 'Q') || (readChar == CTRL_C)) { + printf("\n"); + return 0; + } else if (readChar == '\r') { + printf("\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b"); + return 1; + } + } +} + +static int OsShowPageControl(unsigned int timesPrint, unsigned int lineCap, unsigned int count) +{ + if (NEED_NEW_LINE(timesPrint, lineCap)) { + printf("\n"); + if (SCREEN_IS_FULL(timesPrint, lineCap) && (timesPrint < count)) { + printf("--More--"); + return OsShowPageInputControl(); + } + } + return 1; +} + +static int OsSurePrintAll(unsigned int count) +{ + char readChar = 0; + printf("\nDisplay all %u possibilities?(y/n)", count); + while (1) { + if (read(STDIN_FILENO, &readChar, 1) != 1) { + return (int)SH_ERROR; + } + if ((readChar == 'n') || (readChar == 'N') || (readChar == CTRL_C)) { + printf("\n"); + return 0; + } else if ((readChar == 'y') || (readChar == 'Y') || (readChar == '\r')) { + return 1; + } + } +} + +static int OsPrintMatchList(unsigned int count, const char *strPath, const char *nameLooking, unsigned int printLen) +{ + unsigned int timesPrint = 0; + unsigned int lineCap; + int ret; + DIR *openDir = NULL; + struct dirent *readDir = NULL; + char formatChar[10] = {0}; /* 10:for formatChar length */ + + printLen = (printLen > (DEFAULT_SCREEN_WIDTH - 2)) ? (DEFAULT_SCREEN_WIDTH - 2) : printLen; /* 2:revered 2 bytes */ + lineCap = DEFAULT_SCREEN_WIDTH / (printLen + 2); /* 2:DEFAULT_SCREEN_WIDTH revered 2 bytes */ + if (snprintf_s(formatChar, sizeof(formatChar) - 1, 7, "%%-%us ", printLen) < 0) { /* 7:format-len */ + return (int)SH_ERROR; + } + + if (count > (lineCap * DEFAULT_SCREEN_HEIGHT)) { + ret = OsSurePrintAll(count); + if (ret != 1) { + return ret; + } + } + openDir = opendir(strPath); + if (openDir == NULL) { + return (int)SH_ERROR; + } + + printf("\n"); + for (readDir = readdir(openDir); readDir != NULL; readDir = readdir(openDir)) { + if (strncmp(nameLooking, readDir->d_name, strlen(nameLooking)) != 0) { + continue; + } + printf(formatChar, readDir->d_name); + timesPrint++; + ret = OsShowPageControl(timesPrint, lineCap, count); + if (ret != 1) { + if (closedir(openDir) < 0) { + return (int)SH_ERROR; + } + return ret; + } + } + + printf("\n"); + if (closedir(openDir) < 0) { + return (int)SH_ERROR; + } + + return SH_OK; +} + +static void StrncmpCut(const char *s1, char *s2, size_t n) +{ + if ((n == 0) || (s1 == NULL) || (s2 == NULL)) { + return; + } + do { + if (*s1 && *s2 && (*s1 == *s2)) { + s1++; + s2++; + } else { + break; + } + } while (--n != 0); + if (n > 0) { + /* NULL pad the remaining n-1 bytes */ + while (n-- != 0) { + *s2++ = 0; + } + } + return; +} + +static void OsCompleteStr(char *result, const char *target, char *cmdKey, unsigned int *len) +{ + unsigned int size = strlen(result) - strlen(target); + char *des = cmdKey + *len; + char *src = result + strlen(target); + + while (size-- > 0) { + printf("%c", *src); + if (*len == (SHOW_MAX_LEN - 1)) { + *des = '\0'; + break; + } + *des++ = *src++; + (*len)++; + } +} + +static int OsExecNameMatch(const char *strPath, const char *nameLooking, char *strObj, unsigned int *maxLen) +{ + int count = 0; + DIR *openDir = NULL; + struct dirent *readDir = NULL; + + openDir = opendir(strPath); + if (openDir == NULL) { + return (int)SH_ERROR; + } + + for (readDir = readdir(openDir); readDir != NULL; readDir = readdir(openDir)) { + if (strncmp(nameLooking, readDir->d_name, strlen(nameLooking)) != 0) { + continue; + } + if (count == 0) { + if (strncpy_s(strObj, CMD_MAX_PATH, readDir->d_name, CMD_MAX_PATH - 1)) { + (void)closedir(openDir); + return (int)SH_ERROR; + } + *maxLen = strlen(readDir->d_name); + } else { + /* strncmp&cut the same strings of name matched */ + StrncmpCut(readDir->d_name, strObj, strlen(strObj)); + if (strlen(readDir->d_name) > *maxLen) { + *maxLen = strlen(readDir->d_name); + } + } + count++; + } + + if (closedir(openDir) < 0) { + return (int)SH_ERROR; + } + + return count; +} + +static int OsTabMatchFile(char *cmdKey, unsigned int *len) +{ + unsigned int maxLen = 0; + int count; + char *strOutput = NULL; + char *strCmp = NULL; + char *dirOpen = (char *)malloc(CMD_MAX_PATH * 3); /* 3:dirOpen\strOutput\strCmp */ + if (dirOpen == NULL) { + return (int)SH_ERROR; + } + + (void)memset_s(dirOpen, CMD_MAX_PATH * 3, 0, CMD_MAX_PATH * 3); /* 3:dirOpen\strOutput\strCmp */ + strOutput = dirOpen + CMD_MAX_PATH; + strCmp = strOutput + CMD_MAX_PATH; + + if (OsStrSeparate(cmdKey, dirOpen, strCmp, *len)) { + free(dirOpen); + return (int)SH_ERROR; + } + + count = OsExecNameMatch(dirOpen, strCmp, strOutput, &maxLen); + /* one or more matched */ + if (count >= 1) { + OsCompleteStr(strOutput, strCmp, cmdKey, len); + + if (count == 1) { + free(dirOpen); + return 1; + } + if (OsPrintMatchList((unsigned int)count, dirOpen, strCmp, maxLen) == -1) { + free(dirOpen); + return (int)SH_ERROR; + } + } + + free(dirOpen); + return count; +} + +/* + * Description: Pass in the string and clear useless space ,which include: + * 1) The overmatch space which is not be marked by Quote's area + * Squeeze the overmatch space into one space + * 2) Clear all space before first valid character + * Input: cmdKey : Pass in the buff string, which is ready to be operated + * cmdOut : Pass out the buffer string ,which has already been operated + * size : cmdKey length + */ +unsigned int OsCmdKeyShift(const char *cmdKey, char *cmdOut, unsigned int size) +{ + char *output = NULL; + char *outputBak = NULL; + unsigned int len; + int ret; + bool quotes = FALSE; + + if ((cmdKey == NULL) || (cmdOut == NULL)) { + return (unsigned int)SH_ERROR; + } + + len = strlen(cmdKey); + if ((*cmdKey == '\n') || (len >= size)) { + return (unsigned int)SH_ERROR; + } + output = (char *)malloc(len + 1); + if (output == NULL) { + printf("malloc failure in %s[%d]\n", __FUNCTION__, __LINE__); + return (unsigned int)SH_ERROR; + } + + /* Backup the 'output' start address */ + outputBak = output; + /* Scan each character in 'cmdKey',and squeeze the overmuch space and ignore invalid character */ + for (; *cmdKey != '\0'; cmdKey++) { + /* Detected a Double Quotes, switch the matching status */ + if (*(cmdKey) == '\"') { + SWITCH_QUOTES_STATUS(quotes); + } + /* Ignore the current character in following situation */ + /* 1) Quotes matching status is FALSE (which said that the space is not been marked by double quotes) */ + /* 2) Current character is a space */ + /* 3) Next character is a space too, or the string is been seeked to the end already(\0) */ + /* 4) Invalid character, such as single quotes */ + if ((*cmdKey == ' ') && ((*(cmdKey + 1) == ' ') || (*(cmdKey + 1) == '\0')) && QUOTES_STATUS_CLOSE(quotes)) { + continue; + } + if (*cmdKey == '\'') { + continue; + } + *output = *cmdKey; + output++; + } + *output = '\0'; + /* Restore the 'output' start address */ + output = outputBak; + len = strlen(output); + /* Clear the space which is located at the first character in buffer */ + if (*output == ' ') { + output++; + len--; + } + /* Copy out the buffer which is been operated already */ + ret = strncpy_s(cmdOut, size, output, len); + if (ret != SH_OK) { + printf("%s,%d strncpy_s failed, err:%d!\n", __FUNCTION__, __LINE__, ret); + free(outputBak); + return SH_ERROR; + } + cmdOut[len] = '\0'; + + free(outputBak); + return SH_OK; +} + +int OsTabCompletion(char *cmdKey, unsigned int *len) +{ + int count; + + if ((cmdKey == NULL) || (len == NULL)) { + return (int)SH_ERROR; + } + + count = OsTabMatchFile(cmdKey, len); + + return count; +} + +unsigned int OsShellKeyInit(ShellCB *shellCB) +{ + CmdKeyLink *cmdKeyLink = NULL; + CmdKeyLink *cmdHistoryLink = NULL; + + if (shellCB == NULL) { + return SH_ERROR; + } + + cmdKeyLink = (CmdKeyLink *)malloc(sizeof(CmdKeyLink)); + if (cmdKeyLink == NULL) { + printf("Shell CmdKeyLink memory alloc error!\n"); + return SH_ERROR; + } + cmdHistoryLink = (CmdKeyLink *)malloc(sizeof(CmdKeyLink)); + if (cmdHistoryLink == NULL) { + free(cmdKeyLink); + printf("Shell CmdHistoryLink memory alloc error!\n"); + return SH_ERROR; + } + + cmdKeyLink->count = 0; + SH_ListInit(&(cmdKeyLink->list)); + shellCB->cmdKeyLink = (void *)cmdKeyLink; + + cmdHistoryLink->count = 0; + SH_ListInit(&(cmdHistoryLink->list)); + shellCB->cmdHistoryKeyLink = (void *)cmdHistoryLink; + shellCB->cmdMaskKeyLink = (void *)cmdHistoryLink; + return SH_OK; +} + +void OsShellKeyDeInit(CmdKeyLink *cmdKeyLink) +{ + CmdKeyLink *cmdtmp = NULL; + if (cmdKeyLink == NULL) { + return; + } + + while (!SH_ListEmpty(&(cmdKeyLink->list))) { + cmdtmp = SH_LIST_ENTRY(cmdKeyLink->list.pstNext, CmdKeyLink, list); + SH_ListDelete(&cmdtmp->list); + free(cmdtmp); + } + + cmdKeyLink->count = 0; + free(cmdKeyLink); +} + +void OsShellCmdPush(const char *string, CmdKeyLink *cmdKeyLink) +{ + CmdKeyLink *cmdNewNode = NULL; + unsigned int len; + + if ((string == NULL) || (strlen(string) == 0)) { + return; + } + + len = strlen(string); + cmdNewNode = (CmdKeyLink *)malloc(sizeof(CmdKeyLink) + len + 1); + if (cmdNewNode == NULL) { + return; + } + + (void)memset_s(cmdNewNode, sizeof(CmdKeyLink) + len + 1, 0, sizeof(CmdKeyLink) + len + 1); + if (strncpy_s(cmdNewNode->cmdString, len + 1, string, len)) { + free(cmdNewNode); + return; + } + + SH_ListTailInsert(&(cmdKeyLink->list), &(cmdNewNode->list)); + + return; +} + +void OsShellHistoryShow(unsigned int value, ShellCB *shellCB) +{ + CmdKeyLink *cmdtmp = NULL; + CmdKeyLink *cmdNode = shellCB->cmdHistoryKeyLink; + CmdKeyLink *cmdMask = shellCB->cmdMaskKeyLink; + int ret; + + (void)pthread_mutex_lock(&shellCB->historyMutex); + if (value == CMD_KEY_DOWN) { + if (cmdMask == cmdNode) { + goto END; + } + + cmdtmp = SH_LIST_ENTRY(cmdMask->list.pstNext, CmdKeyLink, list); + if (cmdtmp != cmdNode) { + cmdMask = cmdtmp; + } else { + goto END; + } + } else if (value == CMD_KEY_UP) { + cmdtmp = SH_LIST_ENTRY(cmdMask->list.pstPrev, CmdKeyLink, list); + if (cmdtmp != cmdNode) { + cmdMask = cmdtmp; + } else { + goto END; + } + } + + while (shellCB->shellBufOffset--) { + printf("\b \b"); + } + printf("%s", cmdMask->cmdString); + shellCB->shellBufOffset = strlen(cmdMask->cmdString); + (void)memset_s(shellCB->shellBuf, SHOW_MAX_LEN, 0, SHOW_MAX_LEN); + ret = memcpy_s(shellCB->shellBuf, SHOW_MAX_LEN, cmdMask->cmdString, shellCB->shellBufOffset); + if (ret != SH_OK) { + printf("%s, %d memcpy failed!\n", __FUNCTION__, __LINE__); + goto END; + } + shellCB->cmdMaskKeyLink = (void *)cmdMask; + +END: + (void)pthread_mutex_unlock(&shellCB->historyMutex); + return; +} + +unsigned int OsCmdExec(CmdParsed *cmdParsed, char *cmdStr) +{ + unsigned int ret = SH_OK; + if (cmdParsed && cmdStr) { + ret = SH_NOK; + } + + return ret; +} + diff --git a/src/kernel_liteos_a/apps/shell/src/shcmdparse.c b/src/kernel_liteos_a/apps/shell/src/shcmdparse.c new file mode 100644 index 00000000..269b4193 --- /dev/null +++ b/src/kernel_liteos_a/apps/shell/src/shcmdparse.c @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "shcmd.h" +#include "sherr.h" + + +/* + * Filter out double quote or single-quoted strings at both ends + */ +char *OsCmdParseStrdup(const char *str) +{ + char *tempStr = NULL; + char *newStr = NULL; + + newStr = (char *)malloc(strlen(str) + 1); + if (newStr == NULL) { + return NULL; + } + + tempStr = newStr; + for (; *str != '\0'; str++) { + if ((*str == '\"') || (*str == '\'')) { + continue; + } + *newStr = *str; + newStr++; + } + *newStr = '\0'; + return tempStr; +} + +unsigned int OsCmdParseParaGet(char **value, const char *paraTokenStr) +{ + if ((paraTokenStr == NULL) || (value == NULL)) { + return (unsigned int)SH_ERROR; + } + *value = OsCmdParseStrdup(paraTokenStr); + if (*value == NULL) { + return SH_NOK; + } + return SH_OK; +} + +unsigned int OsCmdParseOneToken(CmdParsed *cmdParsed, unsigned int index, const char *token) +{ + unsigned int ret = SH_OK; + unsigned int tempLen; + + if (cmdParsed == NULL) { + return (unsigned int)SH_ERROR; + } + + if (index == 0) { + if (cmdParsed->cmdType != CMD_TYPE_STD) { + return ret; + } + } + + if ((token != NULL) && (cmdParsed->paramCnt < CMD_MAX_PARAS)) { + tempLen = cmdParsed->paramCnt; + ret = OsCmdParseParaGet(&(cmdParsed->paramArray[tempLen]), token); + if (ret != SH_OK) { + return ret; + } + cmdParsed->paramCnt++; + } + return ret; +} + +unsigned int OsCmdTokenSplit(char *cmdStr, char split, CmdParsed *cmdParsed) +{ + enum { + STAT_INIT, + STAT_TOKEN_IN, + STAT_TOKEN_OUT + } state = STAT_INIT; + unsigned int count = 0; + char *p = NULL; + char *token = cmdStr; + unsigned int ret = SH_OK; + bool quotes = FALSE; + + if (cmdStr == NULL) { + return (unsigned int)SH_ERROR; + } + + for (p = cmdStr; (*p != '\0') && (ret == SH_OK); p++) { + if (*p == '\"') { + SWITCH_QUOTES_STATUS(quotes); + } + switch (state) { + case STAT_INIT: + case STAT_TOKEN_IN: + if ((*p == split) && QUOTES_STATUS_CLOSE(quotes)) { + *p = '\0'; + ret = OsCmdParseOneToken(cmdParsed, count++, token); + state = STAT_TOKEN_OUT; + } + break; + case STAT_TOKEN_OUT: + if (*p != split) { + token = p; + state = STAT_TOKEN_IN; + } + break; + default: + break; + } + } + + if (((ret == SH_OK) && (state == STAT_TOKEN_IN)) || (state == STAT_INIT)) { + ret = OsCmdParseOneToken(cmdParsed, count, token); + } + + return ret; +} + +unsigned int OsCmdParse(char *cmdStr, CmdParsed *cmdParsed) +{ + if ((cmdStr == NULL) || (cmdParsed == NULL) || (strlen(cmdStr) == 0)) { + return (unsigned int)SH_ERROR; + } + return OsCmdTokenSplit(cmdStr, ' ', cmdParsed); +} + diff --git a/src/kernel_liteos_a/apps/shell/src/shmsg.c b/src/kernel_liteos_a/apps/shell/src/shmsg.c new file mode 100644 index 00000000..d51ef9aa --- /dev/null +++ b/src/kernel_liteos_a/apps/shell/src/shmsg.c @@ -0,0 +1,685 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#define _GNU_SOURCE + +#include "stdlib.h" +#include "stdio.h" +#include "unistd.h" +#include "sys/prctl.h" +#include "sys/ioctl.h" +#include "syscall.h" +#include "sys/wait.h" +#include "pthread.h" +#include "securec.h" +#include "shmsg.h" +#include "shell_pri.h" +#include "shcmd.h" + +#define CHAR_CTRL_C '\x03' +#define CHAR_CTRL_DEL '\x7F' + +#define VISIABLE_CHAR(ch) ((ch) > 0x1F && (ch) < 0x7F) + +char *GetCmdline(ShellCB *shellCB) +{ + CmdKeyLink *cmdkey = shellCB->cmdKeyLink; + CmdKeyLink *cmdNode = NULL; + + (void)pthread_mutex_lock(&shellCB->keyMutex); + if ((cmdkey == NULL) || SH_ListEmpty(&cmdkey->list)) { + (void)pthread_mutex_unlock(&shellCB->keyMutex); + return NULL; + } + + cmdNode = SH_LIST_ENTRY(cmdkey->list.pstNext, CmdKeyLink, list); + if (cmdNode == NULL) { + (void)pthread_mutex_unlock(&shellCB->keyMutex); + return NULL; + } + + SH_ListDelete(&(cmdNode->list)); + (void)pthread_mutex_unlock(&shellCB->keyMutex); + + if (strlen(cmdNode->cmdString) == 0) { + free(cmdNode); + return NULL; + } + + return cmdNode->cmdString; +} + +static void ShellSaveHistoryCmd(char *string, ShellCB *shellCB) +{ + CmdKeyLink *cmdHistory = shellCB->cmdHistoryKeyLink; + CmdKeyLink *cmdkey = SH_LIST_ENTRY(string, CmdKeyLink, cmdString); + CmdKeyLink *cmdNxt = NULL; + + if (*string == '\n') { + free(cmdkey); + return; + } + + (void)pthread_mutex_lock(&shellCB->historyMutex); + if (cmdHistory->count != 0) { + cmdNxt = SH_LIST_ENTRY(cmdHistory->list.pstPrev, CmdKeyLink, list); + if (strcmp(string, cmdNxt->cmdString) == 0) { + free((void *)cmdkey); + (void)pthread_mutex_unlock(&shellCB->historyMutex); + return; + } + } + + if (cmdHistory->count >= CMD_HISTORY_LEN) { + cmdNxt = SH_LIST_ENTRY(cmdHistory->list.pstNext, CmdKeyLink, list); + SH_ListDelete(&(cmdNxt->list)); + SH_ListTailInsert(&(cmdHistory->list), &(cmdkey->list)); + free((void *)cmdNxt); + (void)pthread_mutex_unlock(&shellCB->historyMutex); + return; + } + + SH_ListTailInsert(&(cmdHistory->list), &(cmdkey->list)); + cmdHistory->count++; + + (void)pthread_mutex_unlock(&shellCB->historyMutex); + return; +} + +int ShellPend(ShellCB *shellCB) +{ + if (shellCB == NULL) { + return SH_NOK; + } + + return sem_wait(&shellCB->shellSem); +} + +int ShellNotify(ShellCB *shellCB) +{ + if (shellCB == NULL) { + return SH_NOK; + } + + return sem_post(&shellCB->shellSem); +} + +enum { + STAT_NORMAL_KEY, + STAT_ESC_KEY, + STAT_MULTI_KEY +}; + +static int ShellCmdLineCheckUDRL(const char ch, ShellCB *shellCB) +{ + int ret = SH_OK; + if (ch == 0x1b) { /* 0x1b: ESC */ + shellCB->shellKeyType = STAT_ESC_KEY; + return ret; + } else if (ch == 0x5b) { /* 0x5b: first Key combination */ + if (shellCB->shellKeyType == STAT_ESC_KEY) { + shellCB->shellKeyType = STAT_MULTI_KEY; + return ret; + } + } else if (ch == 0x41) { /* up */ + if (shellCB->shellKeyType == STAT_MULTI_KEY) { + OsShellHistoryShow(CMD_KEY_UP, shellCB); + shellCB->shellKeyType = STAT_NORMAL_KEY; + return ret; + } + } else if (ch == 0x42) { /* down */ + if (shellCB->shellKeyType == STAT_MULTI_KEY) { + shellCB->shellKeyType = STAT_NORMAL_KEY; + OsShellHistoryShow(CMD_KEY_DOWN, shellCB); + return ret; + } + } else if (ch == 0x43) { /* right */ + if (shellCB->shellKeyType == STAT_MULTI_KEY) { + shellCB->shellKeyType = STAT_NORMAL_KEY; + return ret; + } + } else if (ch == 0x44) { /* left */ + if (shellCB->shellKeyType == STAT_MULTI_KEY) { + shellCB->shellKeyType = STAT_NORMAL_KEY; + return ret; + } + } + return SH_NOK; +} + +void ShellTaskNotify(ShellCB *shellCB) +{ + int ret; + + (void)pthread_mutex_lock(&shellCB->keyMutex); + OsShellCmdPush(shellCB->shellBuf, shellCB->cmdKeyLink); + (void)pthread_mutex_unlock(&shellCB->keyMutex); + + ret = ShellNotify(shellCB); + if (ret != SH_OK) { + printf("command execute failed, \"%s\"", shellCB->shellBuf); + } +} + +void ParseEnterKey(OutputFunc outputFunc, ShellCB *shellCB) +{ + if ((shellCB == NULL) || (outputFunc == NULL)) { + return; + } + + if (shellCB->shellBufOffset == 0) { + shellCB->shellBuf[shellCB->shellBufOffset] = '\n'; + shellCB->shellBuf[shellCB->shellBufOffset + 1] = '\0'; + goto NOTIFY; + } + + if (shellCB->shellBufOffset <= (SHOW_MAX_LEN - 1)) { + shellCB->shellBuf[shellCB->shellBufOffset] = '\0'; + } +NOTIFY: + shellCB->shellBufOffset = 0; + ShellTaskNotify(shellCB); +} + +void ParseCancelKey(OutputFunc outputFunc, ShellCB *shellCB) +{ + if ((shellCB == NULL) || (outputFunc == NULL)) { + return; + } + + if (shellCB->shellBufOffset <= (SHOW_MAX_LEN - 1)) { + shellCB->shellBuf[0] = CHAR_CTRL_C; + shellCB->shellBuf[1] = '\0'; + } + + shellCB->shellBufOffset = 0; + ShellTaskNotify(shellCB); +} + +void ParseDeleteKey(OutputFunc outputFunc, ShellCB *shellCB) +{ + if ((shellCB == NULL) || (outputFunc == NULL)) { + return; + } + + if ((shellCB->shellBufOffset > 0) && (shellCB->shellBufOffset <= (SHOW_MAX_LEN - 1))) { + shellCB->shellBuf[shellCB->shellBufOffset - 1] = '\0'; + shellCB->shellBufOffset--; + outputFunc("\b \b"); + } +} + +void ParseTabKey(OutputFunc outputFunc, ShellCB *shellCB) +{ + int ret; + + if ((shellCB == NULL) || (outputFunc == NULL)) { + return; + } + + if ((shellCB->shellBufOffset > 0) && (shellCB->shellBufOffset < (SHOW_MAX_LEN - 1))) { + ret = OsTabCompletion(shellCB->shellBuf, &shellCB->shellBufOffset); + if (ret > 1) { + outputFunc(SHELL_PROMPT"%s", shellCB->shellBuf); + } + } +} + +void ParseNormalChar(char ch, OutputFunc outputFunc, ShellCB *shellCB) +{ + if ((shellCB == NULL) || (outputFunc == NULL) || !VISIABLE_CHAR(ch)) { + return; + } + + if ((ch != '\0') && (shellCB->shellBufOffset < (SHOW_MAX_LEN - 1))) { + shellCB->shellBuf[shellCB->shellBufOffset] = ch; + shellCB->shellBufOffset++; + outputFunc("%c", ch); + } + + shellCB->shellKeyType = STAT_NORMAL_KEY; +} + +void ShellCmdLineParse(char c, OutputFunc outputFunc, ShellCB *shellCB) +{ + const char ch = c; + int ret; + + if ((shellCB->shellBufOffset == 0) && (ch != '\n') && (ch != CHAR_CTRL_C) && (ch != '\0')) { + (void)memset_s(shellCB->shellBuf, SHOW_MAX_LEN, 0, SHOW_MAX_LEN); + } + + switch (ch) { + case '\r': + case '\n': /* enter */ + ParseEnterKey(outputFunc, shellCB); + break; + case CHAR_CTRL_C: /* ctrl + c */ + ParseCancelKey(outputFunc, shellCB); + break; + case '\b': /* backspace */ + case CHAR_CTRL_DEL: /* delete(0x7F) */ + ParseDeleteKey(outputFunc, shellCB); + break; + case '\t': /* tab */ + ParseTabKey(outputFunc, shellCB); + break; + default: + /* parse the up/down/right/left key */ + ret = ShellCmdLineCheckUDRL(ch, shellCB); + if (ret == SH_OK) { + return; + } + ParseNormalChar(ch, outputFunc, shellCB); + break; + } + + return; +} + +unsigned int ShellMsgNameGet(CmdParsed *cmdParsed, const char *cmdType) +{ + (void)cmdParsed; + (void)cmdType; + return SH_ERROR; +} + +char *GetCmdName(const char *cmdline, unsigned int len) +{ + unsigned int loop; + const char *tmpStr = NULL; + bool quotes = FALSE; + char *cmdName = NULL; + if (cmdline == NULL) { + return NULL; + } + + cmdName = (char *)malloc(len + 1); + if (cmdName == NULL) { + printf("malloc failure in %s[%d]\n", __FUNCTION__, __LINE__); + return NULL; + } + + /* Scan the 'cmdline' string for command */ + /* Notice: Command string must not have any special name */ + for (tmpStr = cmdline, loop = 0; (*tmpStr != '\0') && (loop < len); ) { + /* If reach a double quotes, switch the quotes matching status */ + if (*tmpStr == '\"') { + SWITCH_QUOTES_STATUS(quotes); + /* Ignore the double quote character itself */ + tmpStr++; + continue; + } + /* If detected a space which the quotes matching status is false */ + /* which said has detected the first space for separator, finish this scan operation */ + if ((*tmpStr == ' ') && (QUOTES_STATUS_CLOSE(quotes))) { + break; + } + cmdName[loop] = *tmpStr++; + loop++; + } + cmdName[loop] = '\0'; + + return cmdName; +} + +void ChildExec(const char *cmdName, char *const paramArray[], bool foreground) +{ + int ret; + pid_t gid; + + ret = setpgrp(); + if (ret == -1) { + exit(1); + } + + gid = getpgrp(); + if (gid < 0) { + printf("get group id failed, pgrpid %d, errno %d\n", gid, errno); + exit(1); + } + + if (!foreground) { + ret = tcsetpgrp(STDIN_FILENO, gid); + if (ret != 0) { + printf("tcsetpgrp failed, errno %d\n", errno); + exit(1); + } + } + + ret = execve(cmdName, paramArray, NULL); + if (ret == -1) { + perror("execve"); + exit(-1); + } +} + +int CheckExit(const char *cmdName, const CmdParsed *cmdParsed) +{ + int ret = 0; + + if (strlen(cmdName) != CMD_EXIT_COMMAND_BYTES || strncmp(cmdName, CMD_EXIT_COMMAND, CMD_EXIT_COMMAND_BYTES) != 0) { + return 0; + } + + if (cmdParsed->paramCnt > 1) { + printf("exit: too many arguments\n"); + return -1; + } + if (cmdParsed->paramCnt == 1) { + char *p = NULL; + ret = strtol(cmdParsed->paramArray[0], &p, CMD_EXIT_CODE_BASE_DEC); + if (*p != '\0') { + printf("exit: bad number: %s\n", cmdParsed->paramArray[0]); + return -1; + } + } + + exit(ret); +} + +static void DoCmdExec(const char *cmdName, const char *cmdline, unsigned int len, CmdParsed *cmdParsed) +{ + bool foreground = FALSE; + int ret; + pid_t forkPid; + + if (strncmp(cmdline, CMD_EXEC_COMMAND, CMD_EXEC_COMMAND_BYTES) == 0) { + if ((cmdParsed->paramCnt > 1) && (strcmp(cmdParsed->paramArray[cmdParsed->paramCnt - 1], "&") == 0)) { + free(cmdParsed->paramArray[cmdParsed->paramCnt - 1]); + cmdParsed->paramArray[cmdParsed->paramCnt - 1] = NULL; + cmdParsed->paramCnt--; + foreground = TRUE; + } + + forkPid = fork(); + if (forkPid < 0) { + printf("Failed to fork from shell\n"); + return; + } else if (forkPid == 0) { + ChildExec(cmdParsed->paramArray[0], cmdParsed->paramArray, foreground); + } else { + if (!foreground) { + (void)waitpid(forkPid, 0, 0); + } + ret = tcsetpgrp(STDIN_FILENO, getpid()); + if (ret != 0) { + printf("tcsetpgrp failed, errno %d\n", errno); + } + } + } else { + if (CheckExit(cmdName, cmdParsed) < 0) { + return; + } + (void)syscall(__NR_shellexec, cmdName, cmdline); + } +} + +static void ParseAndExecCmdline(CmdParsed *cmdParsed, const char *cmdline, unsigned int len) +{ + int i; + unsigned int ret; + char shellWorkingDirectory[PATH_MAX + 1] = { 0 }; + char *cmdlineOrigin = NULL; + char *cmdName = NULL; + + cmdlineOrigin = strdup(cmdline); + if (cmdlineOrigin == NULL) { + printf("malloc failure in %s[%d]\n", __FUNCTION__, __LINE__); + return; + } + + cmdName = GetCmdName(cmdline, len); + if (cmdName == NULL) { + free(cmdlineOrigin); + printf("malloc failure in %s[%d]\n", __FUNCTION__, __LINE__); + return; + } + + ret = OsCmdParse((char *)cmdline, cmdParsed); + if (ret != SH_OK) { + printf("cmd parse failure in %s[%d]\n", __FUNCTION__, __LINE__); + goto OUT; + } + + DoCmdExec(cmdName, cmdlineOrigin, len, cmdParsed); + + if (getcwd(shellWorkingDirectory, PATH_MAX) != NULL) { + (void)OsShellSetWorkingDirectory(shellWorkingDirectory, (PATH_MAX + 1)); + } + +OUT: + for (i = 0; i < cmdParsed->paramCnt; i++) { + if (cmdParsed->paramArray[i] != NULL) { + free(cmdParsed->paramArray[i]); + cmdParsed->paramArray[i] = NULL; + } + } + free(cmdName); + free(cmdlineOrigin); +} + +unsigned int PreHandleCmdline(const char *input, char **output, unsigned int *outputlen) +{ + unsigned int shiftLen, execLen, newLen; + unsigned int removeLen = strlen("./"); /* "./" needs to be removed if it exists */ + unsigned int ret; + char *newCmd = NULL; + char *execCmd = CMD_EXEC_COMMAND; + const char *cmdBuf = input; + unsigned int cmdBufLen = strlen(cmdBuf); + char *shiftStr = (char *)malloc(cmdBufLen + 1); + errno_t err; + + if (shiftStr == NULL) { + printf("malloc failure in %s[%d]\n", __FUNCTION__, __LINE__); + return SH_NOK; + } + (void)memset_s(shiftStr, cmdBufLen + 1, 0, cmdBufLen + 1); + + /* Call function 'OsCmdKeyShift' to squeeze and clear useless or overmuch space if string buffer */ + ret = OsCmdKeyShift(cmdBuf, shiftStr, cmdBufLen + 1); + shiftLen = strlen(shiftStr); + if ((ret != SH_OK) || (shiftLen == 0)) { + ret = SH_NOK; + goto END_FREE_SHIFTSTR; + } + *output = shiftStr; + *outputlen = shiftLen; + + /* Check and parse "./", located at the first two characters of the cmd */ + if ((shiftLen > removeLen) && (shiftStr[0] == '.') && (shiftStr[1] == '/')) { + execLen = strlen(execCmd); + newLen = execLen + shiftLen - removeLen; /* i.e., newLen - execLen == shiftLen - removeLen */ + newCmd = (char *)malloc(newLen + 1); + if (newCmd == NULL) { + ret = SH_NOK; + printf("malloc failure in %s[%d]\n", __FUNCTION__, __LINE__); + goto END_FREE_SHIFTSTR; + } + + err = memcpy_s(newCmd, newLen, execCmd, execLen); + if (err != EOK) { + printf("memcpy_s failure in %s[%d]\n", __FUNCTION__, __LINE__); + ret = SH_NOK; + goto END_FREE_NEWCMD; + } + + err = memcpy_s(newCmd + execLen, newLen - execLen, shiftStr + removeLen, shiftLen - removeLen); + if (err != EOK) { + printf("memcpy_s failure in %s[%d]\n", __FUNCTION__, __LINE__); + ret = SH_NOK; + goto END_FREE_NEWCMD; + } + newCmd[newLen] = '\0'; + + *output = newCmd; + *outputlen = newLen; + ret = SH_OK; + goto END_FREE_SHIFTSTR; + } else { + ret = SH_OK; + goto END; + } +END_FREE_NEWCMD: + free(newCmd); +END_FREE_SHIFTSTR: + free(shiftStr); +END: + return ret; +} + +static void ExecCmdline(const char *cmdline) +{ + unsigned int ret; + char *output = NULL; + unsigned int outputlen; + CmdParsed cmdParsed; + + if (cmdline == NULL) { + return; + } + + /* strip out unnecessary characters */ + ret = PreHandleCmdline(cmdline, &output, &outputlen); + if (ret == SH_NOK) { + return; + } + + (void)memset_s(&cmdParsed, sizeof(CmdParsed), 0, sizeof(CmdParsed)); + ParseAndExecCmdline(&cmdParsed, output, outputlen); + free(output); +} + +static void ShellCmdProcess(ShellCB *shellCB) +{ + while (1) { + char *buf = GetCmdline(shellCB); + if (buf == NULL) { + break; + } + if (buf[0] == CHAR_CTRL_C) { + printf("^C"); + buf[0] = '\n'; + } + printf("\n"); + ExecCmdline(buf); + ShellSaveHistoryCmd(buf, shellCB); + shellCB->cmdMaskKeyLink = shellCB->cmdHistoryKeyLink; + printf(SHELL_PROMPT); + } +} + +void *ShellTask(void *argv) +{ + int ret; + ShellCB *shellCB = (ShellCB *)argv; + + if (shellCB == NULL) { + return NULL; + } + + ret = prctl(PR_SET_NAME, "ShellTask"); + if (ret != SH_OK) { + return NULL; + } + + printf(SHELL_PROMPT); + while (1) { + ret = ShellPend(shellCB); + if (ret == SH_OK) { + ShellCmdProcess(shellCB); + } else if (ret != SH_OK) { + break; + } + } + + return NULL; +} + +int ShellTaskInit(ShellCB *shellCB) +{ + unsigned int ret; + size_t stackSize = SHELL_TASK_STACKSIZE; + void *arg = NULL; + pthread_attr_t attr; + + if (shellCB == NULL) { + return SH_NOK; + } + + ret = pthread_attr_init(&attr); + if (ret != SH_OK) { + return SH_NOK; + } + + pthread_attr_setstacksize(&attr, stackSize); + arg = (void *)shellCB; + ret = pthread_create(&shellCB->shellTaskHandle, &attr, &ShellTask, arg); + if (ret != SH_OK) { + return SH_NOK; + } + + return ret; +} + +static int ShellKernelReg(unsigned int shellHandle) +{ + return ioctl(STDIN_FILENO, CONSOLE_CONTROL_REG_USERTASK, shellHandle); +} + +void ShellEntry(ShellCB *shellCB) +{ + char ch; + int ret; + int n; + pid_t tid = syscall(__NR_gettid); + + if (shellCB == NULL) { + return; + } + + (void)memset_s(shellCB->shellBuf, SHOW_MAX_LEN, 0, SHOW_MAX_LEN); + + ret = ShellKernelReg((int)tid); + if (ret != 0) { + printf("another shell is already running!\n"); + exit(-1); + } + + while (1) { + n = read(0, &ch, 1); + if (n == 1) { + ShellCmdLineParse(ch, (OutputFunc)printf, shellCB); + } + } + return; +} diff --git a/src/kernel_liteos_a/apps/tftp/BUILD.gn b/src/kernel_liteos_a/apps/tftp/BUILD.gn new file mode 100644 index 00000000..2c00ec02 --- /dev/null +++ b/src/kernel_liteos_a/apps/tftp/BUILD.gn @@ -0,0 +1,41 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +executable("tftp") { + sources = [ + "src/main.c", + "src/tftpc.c", + ] + + deps = [ "$LITEOSTHIRDPARTY/bounds_checking_function:libsec_static" ] + + include_dirs = [ "include" ] +} diff --git a/src/kernel_liteos_a/apps/tftp/Makefile b/src/kernel_liteos_a/apps/tftp/Makefile new file mode 100644 index 00000000..5e12e7dd --- /dev/null +++ b/src/kernel_liteos_a/apps/tftp/Makefile @@ -0,0 +1,45 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(APPSTOPDIR)/config.mk + +APP_NAME := $(notdir $(shell pwd)) + +SECUREC_DIR := $(LITEOSTHIRDPARTY)/bounds_checking_function + +LOCAL_SRCS = $(wildcard src/*.c) +LOCAL_SRCS += $(wildcard $(SECUREC_DIR)/src/*.c) + +LOCAL_INCLUDE := \ + -I include \ + -I $(SECUREC_DIR)/include + +LOCAL_FLAGS += $(LOCAL_INCLUDE) + +include $(APP) diff --git a/src/kernel_liteos_a/apps/tftp/include/tftpc.h b/src/kernel_liteos_a/apps/tftp/include/tftpc.h new file mode 100644 index 00000000..1ada9b43 --- /dev/null +++ b/src/kernel_liteos_a/apps/tftp/include/tftpc.h @@ -0,0 +1,309 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef TFTPC_H +#define TFTPC_H + +#include "types_adapt.h" + +#if LWIP_TFTP /* don't build if not configured for use in lwipopts.h */ + +#if defined (__cplusplus) && __cplusplus +extern "C" { +#endif + +#define TFTP_NULL_UINT32 ((u32_t)0xffffffffUL) + +#define TFTP_NULL_INT32 (-1) + +/** @cond liteos +* @defgroup TFTP_Interfaces +* @ingroup Enums +* * This section contains the TFTP enums. +*/ +/** +* +* This Enum is used to specify the transfer mode of the file to be handled by TFTP client. +*/ +typedef enum tagTFTPC_TransferMode { + TRANSFER_MODE_ASCII = 0, /**< Indicates that the mode of transfer is ASCII. */ + TRANSFER_MODE_BINARY, /**< Indicates that the mode of transfer is Binary */ + TRANSFER_MODE_BUTT /**< Indicates invalid transfer mode.*/ +} TFTPC_TRANSFER_MODE_E; + +/** +* This Enum is used to specify the transfer mode to be handled by TFTP client +* This Enum indicates the TFTP client transfer mode of the file + +*/ +typedef enum tagTFTPC_ErrCode { + TFTPC_SOCKET_FAILURE = 1, /**< Error while creating UDP socket. */ + TFTPC_BIND_FAILURE = 2, /**< Error while binding to the UDP socket. */ + TFTPC_SELECT_ERROR = 3, /**< Error returned by select() system call. */ + TFTPC_RECVFROM_ERROR = 4, /**< Error while receiving data from the peer. */ + TFTPC_SENDTO_ERROR = 5, /**< Error while sending data to the peer. */ + TFTPC_FILE_NOT_FOUND = 6, /**< Requested file is not found. */ + + /**< This is the error sent by the server when host name cannot be resolved. */ + TFTPC_CANNOT_RESOLVE_HOSTNAME = 7, + TFTPC_INVALID_PARAVALUE = 8, /**< Input parameters passed to TFTP interfaces are invalid. */ + + /**< Error detected in TFTP packet or the error received from the TFTP server. */ + TFTPC_PROTO_ERROR = 9, + /**< Error during packet synchronization while sending or unexpected packet is received. */ + TFTPC_SYNC_FAILURE = 10, + /**< File size limit crossed, Max block can be 0xFFFF, each block containing 512 bytes. */ + TFTPC_FILE_TOO_BIG = 11, + TFTPC_SRC_FILENAME_LENGTH_ERROR = 12, /**< File name length greater than 256. */ + TFTPC_IP_NOT_WITHIN_RANGE = 13, /**< Host name IP is not valid. */ + TFTPC_ACCESS_ERROR = 14, /**< TFTP server returned file access error. */ + + /**< TFTP server returned error signifying that the DISK is full to write. */ + TFTPC_DISK_FULL = 15, + TFTPC_FILE_EXISTS = 16, /**< TFTP server returned error signifying that the file exists. */ + + /**< tftp_put_file_by_filename returned error signifying that the source file name do not exist. */ + TFTPC_FILE_NOT_EXIST = 17, + TFTPC_MEMALLOC_ERROR = 18, /**< Memory allocation failed in TFTP client. */ + TFTPC_FILEOPEN_ERROR = 19, /**< File open failed. */ + TFTPC_FILEREAD_ERROR = 20, /**< File read error. */ + TFTPC_FILECREATE_ERROR = 21, /**< File create error. */ + TFTPC_FILEWRITE_ERROR = 22, /**< File write error. */ + TFTPC_TIMEOUT_ERROR = 23, /**< Max time expired while waiting for file to be received. */ + + /**< Error when the received packet is less than 4 bytes (error length) or greater than 512 bytes. */ + TFTPC_PKT_SIZE_ERROR = 24, + TFTPC_ERROR_NOT_DEFINED = 25, /**< Returned by TFTP server for protocol user error. */ + TFTPC_DEST_PATH_LENGTH_ERROR = 26, /**< If the destination file path length is greater than 256. */ + TFTPC_UNKNOWN_TRANSFER_ID = 27, /**< Returned by TFTP server for undefined transfer ID. */ + + /**< IOCTL function failed at TFTP client while setting the socket to non-block. */ + TFTPC_IOCTLSOCKET_FAILURE = 28, + TFTPC_MEMCPY_FAILURE = 29 /**< TFTP memcpy failure. */ +} TFTPC_ERR_CODE_E; + +typedef enum tagTFTPC_OpCode { + TFTPC_OP_RRQ = 1, /* read request */ + TFTPC_OP_WRQ, /* write request */ + TFTPC_OP_DATA, /* data packet */ + TFTPC_OP_ACK, /* acknowledgment */ + TFTPC_OP_ERROR, /* error code */ + TFTPC_OP_OPT /* option code */ +} TFTPC_OPCODE_E; + +typedef enum tagTFTPC_PROTOCOL_ErrCode { + TFTPC_PROTOCOL_USER_DEFINED = 0, + TFTPC_PROTOCOL_FILE_NOT_FOUND, + TFTPC_PROTOCOL_ACCESS_ERROR, + TFTPC_PROTOCOL_DISK_FULL, + TFTPC_PROTOCOL_PROTO_ERROR, + TFTPC_PROTOCOL_UNKNOWN_TRANSFER_ID, + TFTPC_PROTOCOL_FILE_EXISTS, + TFTPC_PROTOCOL_CANNOT_RESOLVE_HOSTNAME +} TFTPC_PROT_ERRCODE_E; + + +#ifndef TFTPC_MAX_SEND_REQ_ATTEMPTS +#define TFTPC_MAX_SEND_REQ_ATTEMPTS 5 /* tftp max attempts */ +#endif + +#ifndef TFTPC_TIMEOUT_PERIOD +#define TFTPC_TIMEOUT_PERIOD 5 /* tftp timeout period,unit :s */ +#endif + +#define TFTPC_SERVER_PORT 69 /* tftp server well known port no. */ + +/* MAX file size in TFTP is 32 MB. + Reason for keeping 75 here , is ((75*512=38400bytes)/1024) = 37MB. So the recv/Send Loop can + receive the complete MAX message from the network +*/ +#define TFTPC_MAX_WAIT_IN_LOOP 75 + +#define TFTP_BLKSIZE 512 /* data block size (IEN-133) */ +#define TFTP_HDRSIZE 4 /* TFTP header size */ +#define TFTP_PKTSIZE (TFTP_BLKSIZE + TFTP_HDRSIZE) /* Packet size */ +#define TFTP_MAX_MODE_SIZE 9 /* max size of mode string */ +#define TFTP_MAXERRSTRSIZE 100 /* max size of error message string */ +#define TFTP_MAX_PATH_LENGTH 256 /* Max path or filename length */ +#define TFTP_MAX_BLK_NUM (0xFFFFL) /* MAximum block number */ + +/* IP address not including reserved IPs(0 and 127) and multicast addresses(Class D) */ +#define TFTPC_IP_ADDR_MIN 0x01000000 +#define TFTPC_IP_ADDR_EX_RESV 0x7effffff +#define TFTPC_IP_ADDR_CLASS_B 0x80000000 +#define TFTPC_IP_ADDR_EX_CLASS_DE 0xdfffffff + +#define TFTPC_FOUR 4 /* minimum packet size */ + +/****************************************************************************/ +/* Structure definitions */ +/****************************************************************************/ +/* Tftp data packet */ +typedef struct tagTFTPC_DATA { + u16_t usBlknum; /* block number */ + u8_t ucDataBuf[TFTP_BLKSIZE]; /* Actual data */ +} TFTPC_DATA_S; + + +/* TFTP error packet */ +typedef struct tagTFTPC_ERROR { + u16_t usErrNum; /* error number */ + u8_t ucErrMesg[TFTP_MAXERRSTRSIZE]; /* error message */ +} TFTPC_ERROR_S; + + +/* TFTP packet format */ +typedef struct tagTFTPC_PACKET { + u16_t usOpcode; /* Opcode value */ + union { + /* it contains mode and filename */ + s8_t ucName_Mode[TFTP_MAX_PATH_LENGTH + TFTP_MAX_MODE_SIZE]; + u16_t usBlknum; /* Block Number */ + TFTPC_DATA_S stTFTP_Data; /* Data Packet */ + TFTPC_ERROR_S stTFTP_Err; /* Error Packet */ + } u; +} TFTPC_PACKET_S; + + +/** @defgroup TFTP_Interfaces +* This section contains the TFTP Interfaces +*/ +/* +Func Name: lwip_tftp_get_file_by_filename +*/ +/** +* @ingroup TFTP_Interfaces +* @brief +* This API gets the source file from the server. It then stores the received file in the destination path +* on the client system. +* +* @param[in] ulHostAddr IP address of Host. This is the TFTP server IP. [NA] +* @param[in] usTftpServPort TFTP server port. If the value is passed as 0 then the default TFTP +* PORT 69 is used. [NA] +* @param[in] ucTftpTransMode File transfer mode, either TRANSFER_MODE_BINARY or TRANSFER_MODE_ASCII. [NA] +* @param[in] szSrcFileName Source file in the tftp server. [NA] +* @param[in] szDestDirPath Destination file path in the in the client. [NA] +* @param[out] [N/A] +* +* @return +* ERR_OK: On success \n +* TFTPC_ERR_CODE_E: On failure +* +* @note +* \n +* The behavior of this API is such that if the destination file already exists, it will be overwritten. +*/ +u32_t lwip_tftp_get_file_by_filename(u32_t ulHostAddr, + u16_t usTftpServPort, + u8_t ucTftpTransMode, + s8_t *szSrcFileName, + s8_t *szDestDirPath); + + +/* @defgroup TFTP_Interfaces +* This section contains the TFTP Interfaces +*/ +/* +Func Name: lwip_tftp_put_file_by_filename +*/ +/** +* @ingroup TFTP_Interfaces + +* @brief +* This API reads the contents of the source file on the client system and sends it to the server and +* server then receives the data and stores it in the specified destination path. +* +* @param[in] ulHostAddr Indicates the IP address of Host. This is the TFTP server IP. +* @param[in] usTftpServPort Indicates the TFTP server port. If the value is passed as 0 then the default TFTP +* PORT 69 is used. +* @param[in] ucTftpTransMode Indicates the file transfer mode, either TRANSFER_MODE_BINARY or TRANSFER_MODE_ASCII. +* @param[in] szSrcFileName Indicates the source file in the client. +* @param[in] szDestDirPath Indicates the destination file path on the tftp server. +* +* @return +* ERR_OK: On success \n +* TFTPC_ERR_CODE_E: On failure +* +*/ +u32_t lwip_tftp_put_file_by_filename(u32_t ulHostAddr, + u16_t usTftpServPort, + u8_t cTftpTransMode, + s8_t *szSrcFileName, + s8_t *szDestDirPath); + +#ifdef TFTP_TO_RAWMEM +/* @defgroup TFTP_Interfaces +* This section contains the TFTP Interfaces +*/ +/* +Func Name: lwip_tftp_get_file_by_filename_to_rawmem +*/ +/** +* @ingroup TFTP_Interfaces + +* @brief +* This API gets the source file from the server. It then stores the received file in the target memory +* on the client system. +* +* @param[in] ulHostAddr Indicates the IP address of the Host. This is the TFTP server IP. +* @param[in] usTftpServPort Indicates the TFTP server port. If the value is passed as 0 then the default TFTP +* PORT 69 is used. +* @param[in] ucTftpTransMode Indicates the File transfer mode, either TRANSFER_MODE_BINARY or TRANSFER_MODE_ASCII. +* @param[in] szSrcFileName Indicates the Source file in the TFTP server. +* @param[in] szDestMemAddr Indicates the target memory address in the client. +* @param[in/out] ulFileLength Indicates the target memory address can cache the size of the content, + and The real size of the Source file. +* +* @return +* ERR_OK: On success \n +* TFTPC_ERR_CODE_E: On failure +* @note + +* 1.You must define TFTP_TO_RAWMEM when using this API. \n +* 2.The behavior of this API is such that if the destination file already exists, it will be overwritten. +* @endcond +*/ + +u32_t lwip_tftp_get_file_by_filename_to_rawmem(u32_t ulHostAddr, + u16_t usTftpServPort, + u8_t ucTftpTransMode, + s8_t *szSrcFileName, + s8_t *szDestMemAddr, + u32_t *ulFileLength); +#endif + +#if defined (__cplusplus) && __cplusplus +} +#endif + +#endif /* LWIP_TFTP */ + +#endif /* TFTPC_H */ diff --git a/src/kernel_liteos_a/apps/tftp/include/types_adapt.h b/src/kernel_liteos_a/apps/tftp/include/types_adapt.h new file mode 100644 index 00000000..5634495f --- /dev/null +++ b/src/kernel_liteos_a/apps/tftp/include/types_adapt.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef TYPES_ADAPT_H +#define TYPES_ADAPT_H + +#include +#include +#include + +#define LWIP_TFTP 1 +#define LOSCFG_NET_LWIP_SACK_TFTP 1 +#define LOSCFG_SHELL_CMD_DEBUG 1 + +#define u8_t uint8_t +#define s8_t int8_t +#define u16_t uint16_t +#define s16_t int16_t +#define u32_t uint32_t +#define s32_t int32_t + +#define X8_F "02" PRIx8 +#define U16_F PRIu16 +#define S16_F PRId16 +#define X16_F PRIx16 +#define U32_F PRIu32 +#define S32_F PRId32 +#define X32_F PRIx32 +#define SZT_F PRIuPTR + +#define PRINTK(fmt, ...) printf(fmt, ##__VA_ARGS__) +#define LWIP_ASSERT(msg, expr) assert(expr) +#define LWIP_DEBUGF(module, msg) PRINTK msg + +#define LOS_OK 0 +#define LOS_NOK 1 +#define ERR_OK 0 +#define EOK 0 + +#define mem_malloc malloc +#define mem_free free +#define lwip_socket socket +#define lwip_ioctl ioctl +#define lwip_close close +#define lwip_bind bind +#define lwip_sendto sendto +#define lwip_recvfrom recvfrom + +#define IPADDR_NONE INADDR_NONE +#define DEFFILEMODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) + +#define SHELLCMD_ENTRY(l, cmdType, cmdKey, paraNum, cmdHook) \ +int main(int argc, const char **argv) \ +{ \ + return (int)cmdHook(argc, argv); \ +} + +typedef u32_t (*CmdCallBackFunc)(u32_t argc, const char **argv); + +#endif /* TYPES_ADAPT_H */ diff --git a/src/kernel_liteos_a/apps/tftp/src/main.c b/src/kernel_liteos_a/apps/tftp/src/main.c new file mode 100644 index 00000000..6a989f3c --- /dev/null +++ b/src/kernel_liteos_a/apps/tftp/src/main.c @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "tftpc.h" + +#ifdef LOSCFG_NET_LWIP_SACK_TFTP +static int tcpip_init_finish = 1; +static char *TftpError[] = { + "TFTP transfer finish\n", + "Error while creating UDP socket\n", + "Error while binding to the UDP socket\n", + "Error returned by select() system call\n", + "Error while receiving data from the peer\n", + "Error while sending data to the peer\n", + "Requested file is not found\n", + "This is the error sent by the server when hostname cannot be resolved\n", + "Input parameters passed to TFTP interfaces are invalid\n", + "Error detected in TFTP packet or the error received from the TFTP server\n", + "Error during packet synhronization while sending or unexpected packet is received\n", + "File size limit crossed, Max block can be 0xFFFF, each block containing 512 bytes\n", + "File name length greater than 256\n", + "Hostname IP is not valid\n", + "TFTP server returned file access error\n", + "TFTP server returned error signifying that the DISK is full to write\n", + "TFTP server returned error signifying that the file exist\n", + "The source file name do not exisits\n", + "Memory allocaion failed in TFTP client\n", + "File open failed\n", + "File read error\n", + "File create error\n", + "File write error\n", + "Max time expired while waiting for file to be recived\n", + "Error when the received packet is less than 4bytes(error length) or greater than 512bytes\n", + "Returned by TFTP server for protocol user error\n", + "The destination file path length greater than 256\n", + "Returned by TFTP server for undefined transfer ID\n", + "IOCTL function failed at TFTP client while setting the socket to non-block\n", +}; + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0])) +#endif + +u32_t osShellTftp(int argc, const char **argv) +{ + u32_t ulRemoteAddr = IPADDR_NONE; + const u16_t usTftpServPort = 69; + u8_t ucTftpGet = 0; + s8_t *szLocalFileName = NULL; + s8_t *szRemoteFileName = NULL; + u32_t ret; + + int i = 1; + if (argc < 1 || argv == NULL) { + goto usage; + } + + if (!tcpip_init_finish) { + PRINTK("%s: tcpip_init have not been called\n", __FUNCTION__); + return LOS_NOK; + } + + while (i < argc) { + if (strcmp(argv[i], "-p") == 0) { + ucTftpGet = 0; + i++; + continue; + } + + if (strcmp(argv[i], "-g") == 0) { + ucTftpGet = 1; + i++; + continue; + } + + if (strcmp(argv[i], "-l") == 0 && ((i + 1) < argc)) { + szLocalFileName = (s8_t *)argv[i + 1]; + i += 2; + continue; + } + + if (strcmp(argv[i], "-r") == 0 && ((i + 1) < argc)) { + szRemoteFileName = (s8_t *)argv[i + 1]; + i += 2; + continue; + } + + if ((i + 1) == argc) { + ulRemoteAddr = inet_addr(argv[i]); + break; + } + + goto usage; + } + + if (ulRemoteAddr == IPADDR_NONE || szLocalFileName == NULL || szRemoteFileName == NULL) { + goto usage; + } + + if (ucTftpGet) { + ret = lwip_tftp_get_file_by_filename(ntohl(ulRemoteAddr), usTftpServPort, + TRANSFER_MODE_BINARY, szRemoteFileName, szLocalFileName); + } else { + ret = lwip_tftp_put_file_by_filename(ntohl(ulRemoteAddr), usTftpServPort, + TRANSFER_MODE_BINARY, szLocalFileName, szRemoteFileName); + } + + LWIP_ASSERT("TFTP UNKNOW ERROR!", ret < ARRAY_SIZE(TftpError)); + PRINTK("%s", TftpError[ret]); + if (ret) { + return LOS_NOK; + } else { + return LOS_OK; + } +usage: + PRINTK("usage:\nTransfer a file from/to tftp server\n"); + PRINTK("tftp <-g/-p> -l FullPathLocalFile -r RemoteFile Host\n"); + return LOS_NOK; +} + +#ifdef LOSCFG_SHELL_CMD_DEBUG +SHELLCMD_ENTRY(tftp_shellcmd, CMD_TYPE_EX, "tftp", XARGS, (CmdCallBackFunc)(uintptr_t)osShellTftp); +#endif /* LOSCFG_SHELL_CMD_DEBUG */ +#endif /* LOSCFG_NET_LWIP_SACK_TFTP */ diff --git a/src/kernel_liteos_a/apps/tftp/src/tftpc.c b/src/kernel_liteos_a/apps/tftp/src/tftpc.c new file mode 100644 index 00000000..6185c2af --- /dev/null +++ b/src/kernel_liteos_a/apps/tftp/src/tftpc.c @@ -0,0 +1,1718 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* TFTP Client utility */ + +#include "tftpc.h" + +#if LWIP_TFTP /* don't build if not configured for use in lwipopts.h */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Function Declarations */ +#ifdef LOSCFG_NET_LWIP_SACK_TFTP +static u32_t lwip_tftp_create_bind_socket(s32_t *piSocketID); + +static s32_t lwip_tftp_make_tftp_packet(u16_t usOpcode, s8_t *szFileName, + u32_t ulMode, TFTPC_PACKET_S *pstPacket); + +static u32_t lwip_tftp_recv_from_server(s32_t iSockNum, + u32_t *pulSize, + TFTPC_PACKET_S *pstRecvBuf, + u32_t *pulIgnorePkt, + struct sockaddr_in *pstServerAddr, + TFTPC_PACKET_S *pstSendBuf); + +static u32_t lwip_tftp_send_to_server(s32_t iSockNum, u32_t ulSize, + TFTPC_PACKET_S *pstSendBuf, + struct sockaddr_in *pstServerAddr); + +static u32_t lwip_tftp_validate_data_pkt(s32_t iSockNum, + u32_t *pulSize, + TFTPC_PACKET_S *pstRecvBuf, + u16_t usCurrBlk, u32_t *pulResendPkt, + struct sockaddr_in *pstServerAddr); + +static u32_t lwip_tftp_inner_put_file(s32_t iSockNum, TFTPC_PACKET_S *pstSendBuf, + u32_t ulSendSize, u16_t usCurrBlk, + struct sockaddr_in *pstServerAddr); + +static void lwip_tftp_send_error(s32_t iSockNum, u32_t ulError, const char *szErrMsg, + struct sockaddr_in *pstServerAddr, TFTPC_PACKET_S *pstSendBuf); + + +/* Create and bind a UDP socket. */ +u32_t lwip_tftp_create_bind_socket(s32_t *piSocketID) +{ + int retval; + struct sockaddr_in stClientAddr; + u32_t ulTempClientIp; + u32_t set_non_block_socket = 1; + + /* create a socket */ + *piSocketID = lwip_socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (*piSocketID == -1) { + LWIP_DEBUGF(TFTP_DEBUG, ("lwip_tftp_create_bind_socket : lwip_socket create socket failed\n")); + return TFTPC_SOCKET_FAILURE; + } + + /* Make the socket as NON-BLOCKING. */ + retval = lwip_ioctl(*piSocketID, (long)FIONBIO, &set_non_block_socket); + if (retval != 0) { + (void)lwip_close(*piSocketID); + *piSocketID = TFTP_NULL_INT32; + return TFTPC_IOCTLSOCKET_FAILURE; + } + + ulTempClientIp = INADDR_ANY; + + /* specify a local address for this socket */ + (void)memset_s(&stClientAddr, sizeof(stClientAddr), 0, sizeof(stClientAddr)); + stClientAddr.sin_family = AF_INET; + stClientAddr.sin_port = 0; + stClientAddr.sin_addr.s_addr = htonl(ulTempClientIp); + + retval = lwip_bind(*piSocketID, (struct sockaddr *)&stClientAddr, sizeof(stClientAddr)); + if (retval != 0) { + (void)lwip_close(*piSocketID); + *piSocketID = TFTP_NULL_INT32; + + return TFTPC_BIND_FAILURE; + } + + return ERR_OK; +} + + +/* Function to create TFTP packet. + usOpcode - indiacting the nature of the operation + pFileName -filename on which the operation needs to done + ulMode -mode in which the operation needs to done + pstPacket - packet generated + Returns packet address on success +*/ +static s32_t lwip_tftp_make_tftp_packet(u16_t usOpcode, s8_t *szFileName, u32_t ulMode, TFTPC_PACKET_S *pstPacket) +{ + s8_t *pcCp = NULL; + + pstPacket->usOpcode = htons(usOpcode); + pcCp = pstPacket->u.ucName_Mode; + + /* Request packet format is: + | Opcode | Filename | 0 | Mode | 0 | + */ + (void)strncpy_s((char *)pcCp, TFTP_MAX_PATH_LENGTH, (char *)szFileName, (TFTP_MAX_PATH_LENGTH - 1)); + pcCp[(TFTP_MAX_PATH_LENGTH - 1)] = '\0'; + + pcCp += (strlen((char *)szFileName) + 1); + if (ulMode == TRANSFER_MODE_BINARY) { + (void)strncpy_s((char *)pcCp, TFTP_MAX_MODE_SIZE, "octet", (TFTP_MAX_MODE_SIZE - 1)); + pcCp[(TFTP_MAX_MODE_SIZE - 1)] = '\0'; + } else if (ulMode == TRANSFER_MODE_ASCII) { + (void)strncpy_s((char *)pcCp, TFTP_MAX_MODE_SIZE, "netascii", (TFTP_MAX_MODE_SIZE - 1)); + pcCp[(TFTP_MAX_MODE_SIZE - 1)] = '\0'; + } + + pcCp += (strlen((char *)pcCp) + 1); + + return (pcCp - (s8_t *)pstPacket); +} + +/* Function to recv a packet from server + iSockNum - Socket Number + pstServerAddr - Server address + pulIgnorePkt - Ignore packet flag + pstRecvBuf - received packet + pulSize - Size of the packet +*/ +u32_t lwip_tftp_recv_from_server(s32_t iSockNum, u32_t *pulSize, TFTPC_PACKET_S *pstRecvBuf, u32_t *pulIgnorePkt, + struct sockaddr_in *pstServerAddr, TFTPC_PACKET_S *pstSendBuf) +{ + u32_t ulError; + socklen_t slFromAddrLen; + struct sockaddr_in stFromAddr; + fd_set stReadfds; + struct timeval stTimeout; + u16_t usOpcode; /* Opcode value */ + s32_t iRet; + + slFromAddrLen = sizeof(stFromAddr); + stTimeout.tv_sec = TFTPC_TIMEOUT_PERIOD; + stTimeout.tv_usec = 0; + + /* wait for DATA packet */ + FD_ZERO(&stReadfds); + FD_SET(iSockNum, &stReadfds); + + iRet = select((s32_t)(iSockNum + 1), &stReadfds, 0, 0, &stTimeout); + if (iRet == -1) { + return TFTPC_SELECT_ERROR; + } else if (iRet == 0) { + return TFTPC_TIMEOUT_ERROR; /* Select timeout occurred */ + } + + if (!FD_ISSET(iSockNum, &stReadfds)) { + return TFTPC_TIMEOUT_ERROR; /* FD not set*/ + } + + /* receive a packet from server */ + iRet = lwip_recvfrom(iSockNum, (s8_t *)pstRecvBuf, TFTP_PKTSIZE, 0, + (struct sockaddr *)&stFromAddr, &slFromAddrLen); + if (iRet <= 0) { + return TFTPC_RECVFROM_ERROR; + } + + /* If received packet size < minimum packet size */ + if (iRet < TFTPC_FOUR) { + /* Send Error packet to server */ + lwip_tftp_send_error(iSockNum, + TFTPC_PROTOCOL_PROTO_ERROR, + "Packet size < min size", + pstServerAddr, pstSendBuf); + + return TFTPC_PKT_SIZE_ERROR; + } + + /* convert network opcode to host format after receive. */ + usOpcode = ntohs(pstRecvBuf->usOpcode); + /* if this packet is ERROR packet */ + if (usOpcode == TFTPC_OP_ERROR) { + ulError = ntohs(pstRecvBuf->u.stTFTP_Err.usErrNum); + + /*If the error is according to RFC,then convert to lwip error codes. + Constant values are used in the cases as these error codes are as per + the RFC, these are constant values returned by many standard TFTP + serevrs.*/ + switch (ulError) { + case TFTPC_PROTOCOL_USER_DEFINED: + ulError = TFTPC_ERROR_NOT_DEFINED; + break; + case TFTPC_PROTOCOL_FILE_NOT_FOUND: + ulError = TFTPC_FILE_NOT_FOUND; + break; + case TFTPC_PROTOCOL_ACCESS_ERROR: + ulError = TFTPC_ACCESS_ERROR; + break; + case TFTPC_PROTOCOL_DISK_FULL: + ulError = TFTPC_DISK_FULL; + break; + case TFTPC_PROTOCOL_PROTO_ERROR: + ulError = TFTPC_PROTO_ERROR; + break; + case TFTPC_PROTOCOL_UNKNOWN_TRANSFER_ID: + ulError = TFTPC_UNKNOWN_TRANSFER_ID; + break; + case TFTPC_PROTOCOL_FILE_EXISTS: + ulError = TFTPC_FILE_EXISTS; + break; + case TFTPC_PROTOCOL_CANNOT_RESOLVE_HOSTNAME: + ulError = TFTPC_CANNOT_RESOLVE_HOSTNAME; + break; + default: + ulError = TFTPC_ERROR_NOT_DEFINED; + break; + } + + /* If length of error msg > 100 chars */ + pstRecvBuf->u.stTFTP_Err.ucErrMesg[TFTP_MAXERRSTRSIZE - 1] = '\0'; + + LWIP_DEBUGF(TFTP_DEBUG, ("lwip_tftp_recv_from_server : ERROR pkt received: %s\n", + pstRecvBuf->u.stTFTP_Err.ucErrMesg)); + + /* Now we get error block, so return. */ + return ulError; + } + + /* Store the size of received block */ + *pulSize = (u32_t)iRet; + + /* If received packet is first block of data(for get operation) or if + received packet is acknowledgment for write request (put operation) + store the received port number */ + if (((usOpcode == TFTPC_OP_DATA) && + (ntohs(pstRecvBuf->u.stTFTP_Data.usBlknum) == 1)) || + ((usOpcode == TFTPC_OP_ACK) && + (ntohs(pstRecvBuf->u.usBlknum) == 0))) { + /* If received packet from correct server */ + if (stFromAddr.sin_addr.s_addr == pstServerAddr->sin_addr.s_addr) { + /* set the server port to received port */ + pstServerAddr->sin_port = stFromAddr.sin_port; + } else { + /* Received packet form wrong server. */ + LWIP_DEBUGF(TFTP_DEBUG, + ("lwip_tftp_recv_from_server : Received 1st packet from wrong Server or unknown server\n")); + + /* Set ignore packet flag */ + *pulIgnorePkt = 1; + } + } else { + /* If not first packet, check if the received packet is from correct + server and from correct port */ + if ((stFromAddr.sin_addr.s_addr != pstServerAddr->sin_addr.s_addr) || + (pstServerAddr->sin_port != stFromAddr.sin_port)) { + /* Received packet form wrong server or wrong port.Ignore packet. */ + LWIP_DEBUGF(TFTP_DEBUG, + ("lwip_tftp_recv_from_server : Received a packet from wrong Server or unknown server\n")); + + /* Set ignore packet flag */ + *pulIgnorePkt = 1; + } + } + + return ERR_OK; +} + +/* Function to send a packet to server + iSockNum: Socket Number + ulSize: Size of the packet + pstSendBuf: Packet to send + pstServerAddr: Server address +*/ +u32_t lwip_tftp_send_to_server(s32_t iSockNum, + u32_t ulSize, + TFTPC_PACKET_S *pstSendBuf, + struct sockaddr_in *pstServerAddr) +{ + s32_t iRet; + + /* Send packet to server */ + iRet = lwip_sendto(iSockNum, (s8_t *)pstSendBuf, + (size_t)ulSize, 0, + (struct sockaddr *)pstServerAddr, + sizeof(struct sockaddr_in)); + /* Size of data sent not equal to size of packet */ + if ((iRet == TFTP_NULL_INT32) || ((u32_t)iRet != ulSize)) { + return TFTPC_SENDTO_ERROR; + } + + return ERR_OK; +} + +/* lwip_tftp_validate_data_pkt +* Get the data block from the received packet +* @param Input iSockNum Socket Number +* pulSize: Size of received packet, + pstRecvBuf - received packet + usCurrBlk - Current block number + * @param Output pulResendPkt - Resend packet flag + * @return VOS_OK on success.else error code*/ + +u32_t lwip_tftp_validate_data_pkt(s32_t iSockNum, + u32_t *pulSize, + TFTPC_PACKET_S *pstRecvBuf, + u16_t usCurrBlk, + u32_t *pulResendPkt, + struct sockaddr_in *pstServerAddr) +{ + fd_set stReadfds; + struct timeval stTimeout; + struct sockaddr_in stFromAddr; + socklen_t ulFromAddrLen; + s32_t iRecvLen = (s32_t)*pulSize; + s32_t iError; + u16_t usBlknum; + u32_t ulLoopCnt = 0; + + ulFromAddrLen = sizeof(stFromAddr); + + /* Initialize from address to the server address at first */ + if (memcpy_s((void *)&stFromAddr, sizeof(struct sockaddr_in), (void *)pstServerAddr, sizeof(stFromAddr)) != 0) { + LWIP_DEBUGF(TFTP_DEBUG, ("lwip_tftp_validate_data_pkt : memcpy_s error\n")); + return TFTPC_MEMCPY_FAILURE; + } + + /* Get Block Number */ + usBlknum = ntohs(pstRecvBuf->u.stTFTP_Data.usBlknum); + /* Now data blocks are not in sync. */ + if (usBlknum != usCurrBlk) { + /* Set timeout value */ + stTimeout.tv_sec = 1; + stTimeout.tv_usec = 0; + + /* Reset any stored packets. */ + FD_ZERO(&stReadfds); + FD_SET(iSockNum, &stReadfds); + + iError = select((s32_t)(iSockNum + 1), + &stReadfds, 0, 0, &stTimeout); + + /* Loop to get the last data packet from the receive buffer */ + while ((iError != TFTP_NULL_INT32) && (iError != 0)) { + ulLoopCnt++; + + /* MAX file size in TFTP is 32 MB. + Reason for keeping 75 here , is ((75*512=38400bytes)/1024) = 37MB. So the recv/Send + Loop can receive the complete MAX message from the network. + */ + if (ulLoopCnt > TFTPC_MAX_WAIT_IN_LOOP) { + LWIP_DEBUGF(TFTP_DEBUG, ("lwip_tftp_validate_data_pkt : unexpected packets are received repeatedly\n")); + *pulSize = TFTP_NULL_UINT32; + return TFTPC_PKT_SIZE_ERROR; + } + + FD_ZERO(&stReadfds); + FD_SET(iSockNum, &stReadfds); + + iRecvLen = lwip_recvfrom(iSockNum, + (s8_t *)pstRecvBuf, + TFTP_PKTSIZE, 0, + (struct sockaddr *)&stFromAddr, + &ulFromAddrLen); + if (iRecvLen == -1) { + *pulSize = TFTP_NULL_UINT32; + + /* return from the function, recvfrom operation failed */ + return TFTPC_RECVFROM_ERROR; + } + + stTimeout.tv_sec = 1; + stTimeout.tv_usec = 0; + iError = select((s32_t)(iSockNum + 1), &stReadfds, 0, 0, &stTimeout); + } + + /* If received packet size < minimum packet size */ + if (iRecvLen < TFTPC_FOUR) { + return TFTPC_PKT_SIZE_ERROR; + } + + /* Check if the received packet is from correct server and from + correct port + */ + if ((stFromAddr.sin_addr.s_addr != pstServerAddr->sin_addr.s_addr) || + (pstServerAddr->sin_port != stFromAddr.sin_port)) { + /* resend ack packet */ + *pulResendPkt = 1; + LWIP_DEBUGF(TFTP_DEBUG, ("lwip_tftp_validate_data_pkt : Received pkt from unknown server\n")); + + return ERR_OK; + } + + /* if this packet is not DATA packet */ + if (TFTPC_OP_DATA != ntohs(pstRecvBuf->usOpcode)) { + LWIP_DEBUGF(TFTP_DEBUG, ("lwip_tftp_validate_data_pkt : Received pkt not a DATA pkt\n")); + + /* return from the function, incorrect packet received, + expected packet is data packet */ + return TFTPC_PROTO_ERROR; + } + + usBlknum = ntohs(pstRecvBuf->u.stTFTP_Data.usBlknum); + /* if we now have the earlier data packet, then the host probably + never got our acknowledge packet, now we will send it again. */ + if (usBlknum == (usCurrBlk - 1)) { + /* resend ack packet */ + *pulResendPkt = 1; + LWIP_DEBUGF(TFTP_DEBUG, ("lwip_tftp_validate_data_pkt : Received previous DATA pkt\n")); + + return ERR_OK; + } + + /* If the block of data received is not current block or also + previous block, then it is abnormal case. */ + if (usBlknum != usCurrBlk) { + LWIP_DEBUGF(TFTP_DEBUG, + ("lwip_tftp_validate_data_pkt : Received DATA pkt no. %"S32_F" instead of pkt no.%"S32_F"\n", + usBlknum, usCurrBlk)); + + return TFTPC_SYNC_FAILURE; + } + } + + *pulSize = (u32_t)iRecvLen; + return ERR_OK; +} + +/* Send an error packet to the server + iSockNum : Socket Number + ulError: Error code + szErrMsg - Error message + pstServerAddr - Server address +*/ +static void lwip_tftp_send_error(s32_t iSockNum, u32_t ulError, const char *szErrMsg, + struct sockaddr_in *pstServerAddr, TFTPC_PACKET_S *pstSendBuf) +{ + u16_t usOpCode = TFTPC_OP_ERROR; + + if (memset_s((void *)pstSendBuf, sizeof(TFTPC_PACKET_S), 0, sizeof(TFTPC_PACKET_S)) != 0) { + LWIP_DEBUGF(TFTP_DEBUG, ("lwip_tftp_send_error : memset_s error\n")); + return; + } + + /* Set up the send buffer */ + pstSendBuf->usOpcode = htons(usOpCode); + pstSendBuf->u.stTFTP_Err.usErrNum = htons((u16_t)ulError); + + if (strncpy_s((char *)(pstSendBuf->u.stTFTP_Err.ucErrMesg), TFTP_MAXERRSTRSIZE, + (char *)szErrMsg, (TFTP_MAXERRSTRSIZE - 1)) != EOK) { + LWIP_DEBUGF(TFTP_DEBUG, ("lwip_tftp_send_error : strncpy_s error\n")); + return; + } + pstSendBuf->u.stTFTP_Err.ucErrMesg[(TFTP_MAXERRSTRSIZE - 1)] = '\0'; + + /* Send to server */ + if (lwip_tftp_send_to_server(iSockNum, + sizeof(TFTPC_PACKET_S), + pstSendBuf, + pstServerAddr) != ERR_OK) { + LWIP_DEBUGF(TFTP_DEBUG, ("lwip_tftp_send_to_server error.")); + return; + } +} + +/* INTERFACE to get a file using filename + ulHostAddr - IP address of Host + szSrcFileName - Source file + szDestDirPath - Destination file path +*/ +u32_t lwip_tftp_get_file_by_filename(u32_t ulHostAddr, + u16_t usTftpServPort, + u8_t ucTftpTransMode, + s8_t *szSrcFileName, + s8_t *szDestDirPath) +{ + s32_t iSockNum = TFTP_NULL_INT32; + u32_t ulSrcStrLen; + u32_t ulDestStrLen; + u32_t ulSize; + u32_t ulRecvSize = TFTP_NULL_UINT32; + s32_t iErrCode; + u32_t ulErrCode; + u16_t usReadReq; + u16_t usTempServPort; + s8_t *pszTempDestName = NULL; + s8_t *szTempSrcName = NULL; + u32_t ulCurrBlk = 1; + u32_t ulResendPkt = 0; /*Resend the previous packet*/ + u32_t ulIgnorePkt = 0; /*Ignore received packet*/ + u32_t ulTotalTime = 0; + u32_t isLocalFileOpened = false; + + TFTPC_PACKET_S *pstSendBuf = NULL; + TFTPC_PACKET_S *pstRecvBuf = NULL; + struct sockaddr_in stServerAddr; + struct stat sb; + u32_t IsDirExist = 0; + s32_t fp = -1; + + /*Validate the parameters*/ + if ((szSrcFileName == NULL) || (szDestDirPath == NULL)) { + return TFTPC_INVALID_PARAVALUE; + } + + if ((ucTftpTransMode != TRANSFER_MODE_BINARY) && (ucTftpTransMode != TRANSFER_MODE_ASCII)) { + return TFTPC_INVALID_PARAVALUE; + } + + /*check IP address not within ( 1.0.0.0 - 126.255.255.255 ) + and ( 128.0.0.0 - 223.255.255.255 ) range.*/ + if (!(((ulHostAddr >= TFTPC_IP_ADDR_MIN) && + (ulHostAddr <= TFTPC_IP_ADDR_EX_RESV)) || + ((ulHostAddr >= TFTPC_IP_ADDR_CLASS_B) && + (ulHostAddr <= TFTPC_IP_ADDR_EX_CLASS_DE)))) { + return TFTPC_IP_NOT_WITHIN_RANGE; + } + + /*Check validity of source filename*/ + ulSrcStrLen = strlen((char *)szSrcFileName); + if ((ulSrcStrLen == 0) || (ulSrcStrLen >= TFTP_MAX_PATH_LENGTH)) { + return TFTPC_SRC_FILENAME_LENGTH_ERROR; + } + + /*Check validity of destination path*/ + ulDestStrLen = strlen((char *)szDestDirPath); + if ((ulDestStrLen >= TFTP_MAX_PATH_LENGTH) || (ulDestStrLen == 0)) { + return TFTPC_DEST_PATH_LENGTH_ERROR; + } + + pstSendBuf = (TFTPC_PACKET_S *)mem_malloc(sizeof(TFTPC_PACKET_S)); + if (pstSendBuf == NULL) { + return TFTPC_MEMALLOC_ERROR; + } + + pstRecvBuf = (TFTPC_PACKET_S *)mem_malloc(sizeof(TFTPC_PACKET_S)); + if (pstRecvBuf == NULL) { + mem_free(pstSendBuf); + return TFTPC_MEMALLOC_ERROR; + } + + pszTempDestName = (s8_t *)mem_malloc(TFTP_MAX_PATH_LENGTH); + if (pszTempDestName == NULL) { + mem_free(pstSendBuf); + mem_free(pstRecvBuf); + return TFTPC_MEMALLOC_ERROR; + } + + /* First time initialize the buffers */ + (void)memset_s((void *)pstSendBuf, sizeof(TFTPC_PACKET_S), 0, sizeof(TFTPC_PACKET_S)); + (void)memset_s((void *)pstRecvBuf, sizeof(TFTPC_PACKET_S), 0, sizeof(TFTPC_PACKET_S)); + + /*If given src filename is a relative path extract + the file name from the path*/ + if ((0 != strchr((char *)szSrcFileName, '/')) || (0 != strchr((char *)szSrcFileName, '\\'))) { + /*Move to the end of the src file path*/ + szTempSrcName = szSrcFileName + (ulSrcStrLen - 1); + + while (((*(szTempSrcName - 1) != '/') && + (*(szTempSrcName - 1) != '\\')) && + (szTempSrcName != szSrcFileName)) { + szTempSrcName--; + } + + /*Get length of the extracted src filename*/ + ulSrcStrLen = strlen((char *)szTempSrcName); + } else { + /*If not a relative src path use the given src filename*/ + szTempSrcName = szSrcFileName; + } + + (void)memset_s(pszTempDestName, TFTP_MAX_PATH_LENGTH, 0, TFTP_MAX_PATH_LENGTH); + if (strncpy_s((char *)pszTempDestName, TFTP_MAX_PATH_LENGTH, (char *)szDestDirPath, TFTP_MAX_PATH_LENGTH - 1) != + 0) { + ulErrCode = TFTPC_MEMCPY_FAILURE; + goto err_handler; + } + pszTempDestName[TFTP_MAX_PATH_LENGTH - 1] = '\0'; + + if (stat((char *)pszTempDestName, &sb) == 0 && S_ISDIR(sb.st_mode)) { + IsDirExist = 1; + } + + if (IsDirExist == 1) { + /*The filename is not present concat source filename and try*/ + if ((ulDestStrLen + ulSrcStrLen) >= TFTP_MAX_PATH_LENGTH) { + /*If concatenating src filename exceeds 256 bytes*/ + ulErrCode = TFTPC_DEST_PATH_LENGTH_ERROR; + goto err_handler; + } + + /*Check if / present at end of string*/ + if ((pszTempDestName[ulDestStrLen - 1] != '/') && + (pszTempDestName[ulDestStrLen - 1] != '\\')) { + if ((ulDestStrLen + ulSrcStrLen + 1) >= TFTP_MAX_PATH_LENGTH) { + /*If concatenating src filename exceeds 256 bytes*/ + ulErrCode = TFTPC_DEST_PATH_LENGTH_ERROR; + goto err_handler; + } + + /*If not present concat / to the path*/ + if (strncat_s((char *)pszTempDestName, (TFTP_MAX_PATH_LENGTH - strlen((char *)pszTempDestName)), + "/", TFTP_MAX_PATH_LENGTH - strlen((char *)pszTempDestName) - 1) != 0) { + ulErrCode = TFTPC_ERROR_NOT_DEFINED; + goto err_handler; + } + } + + /*Concatenate src filename to destination path*/ + if (strncat_s((char *)pszTempDestName, (TFTP_MAX_PATH_LENGTH - strlen((char *)pszTempDestName)), + (char *)szTempSrcName, TFTP_MAX_PATH_LENGTH - strlen((char *)pszTempDestName) - 1) != 0) { + ulErrCode = TFTPC_ERROR_NOT_DEFINED; + goto err_handler; + } + } + + ulErrCode = lwip_tftp_create_bind_socket(&iSockNum); + if (ulErrCode != ERR_OK) { + goto err_handler; + } + + if (usTftpServPort == 0) { + usTftpServPort = TFTPC_SERVER_PORT; + } + + usTempServPort = usTftpServPort; + + /* set server IP address */ + (void)memset_s(&stServerAddr, sizeof(stServerAddr), 0, sizeof(stServerAddr)); + stServerAddr.sin_family = AF_INET; + stServerAddr.sin_port = htons(usTempServPort); + stServerAddr.sin_addr.s_addr = htonl(ulHostAddr); + + /* Make a request packet - TFTPC_OP_RRQ */ + ulSize = (u32_t)lwip_tftp_make_tftp_packet(TFTPC_OP_RRQ, szSrcFileName, + (u32_t)ucTftpTransMode, + pstSendBuf); + ulErrCode = lwip_tftp_send_to_server(iSockNum, ulSize, + pstSendBuf, &stServerAddr); + if (ulErrCode != ERR_OK) { + /* send to server failed */ + (void)lwip_close(iSockNum); + goto err_handler; + } + + for (;;) { + if (ulIgnorePkt > 0) { + ulIgnorePkt = 0; + } + + ulErrCode = lwip_tftp_recv_from_server(iSockNum, &ulRecvSize, pstRecvBuf, + &ulIgnorePkt, &stServerAddr, pstSendBuf); + /* If select timeout occurred */ + if (ulErrCode == TFTPC_TIMEOUT_ERROR) { + ulTotalTime++; + if (ulTotalTime < TFTPC_MAX_SEND_REQ_ATTEMPTS) { + /* Max attempts not reached. Resend packet */ + ulErrCode = lwip_tftp_send_to_server(iSockNum, ulSize, + pstSendBuf, &stServerAddr); + if (ulErrCode != ERR_OK) { + (void)lwip_close(iSockNum); + if (isLocalFileOpened == true) { + close(fp); + } + goto err_handler; + } + + continue; + } else { + /* return from the function, max attempts limit reached */ + (void)lwip_close(iSockNum); + if (isLocalFileOpened == true) { + close(fp); + } + ulErrCode = TFTPC_TIMEOUT_ERROR; + goto err_handler; + } + } else if (ulErrCode != ERR_OK) { + (void)lwip_close(iSockNum); + if (isLocalFileOpened == true) { + close(fp); + } + goto err_handler; + } + + /* Now we have receive block from different server. */ + if (ulIgnorePkt > 0) { + /*Continue without processing this block. */ + continue; + } + + /* if this packet is unkonwn or incorrect packet */ + if (ntohs(pstRecvBuf->usOpcode) != TFTPC_OP_DATA) { + /* Send error packet to server */ + lwip_tftp_send_error(iSockNum, + TFTPC_PROTOCOL_PROTO_ERROR, + "Protocol error.", + &stServerAddr, pstSendBuf); + + (void)lwip_close(iSockNum); + if (isLocalFileOpened == true) { + close(fp); + } + + LWIP_DEBUGF(TFTP_DEBUG, ("lwip_tftp_get_file_by_filename : Received pkt not DATA pkt\n")); + + ulErrCode = TFTPC_PROTO_ERROR; + goto err_handler; + } + + /* Now the number of tries will be reset. */ + ulTotalTime = 0; + + /* Validate received DATA packet. */ + ulErrCode = lwip_tftp_validate_data_pkt(iSockNum, &ulRecvSize, + pstRecvBuf, (u16_t)ulCurrBlk, + &ulResendPkt, + &stServerAddr); + if (ulErrCode != ERR_OK) { + /* Send Error packet to server */ + if (ulErrCode != TFTPC_RECVFROM_ERROR) { + lwip_tftp_send_error(iSockNum, + TFTPC_PROTOCOL_PROTO_ERROR, + "Received unexpected packet", + &stServerAddr, pstSendBuf); + } + + (void)lwip_close(iSockNum); + if (isLocalFileOpened == true) { + close(fp); + } + + goto err_handler; + } + + /* Received previous data block again. Resend last packet */ + if (ulResendPkt > 0) { + /* Now set ulResendPkt to 0 to send the last packet. */ + ulResendPkt = 0; + ulErrCode = lwip_tftp_send_to_server(iSockNum, ulSize, + pstSendBuf, &stServerAddr); + if (ulErrCode != ERR_OK) { + (void)lwip_close(iSockNum); + if (isLocalFileOpened == true) { + close(fp); + } + + goto err_handler; + } + + /* Continue in loop to send last packet again. */ + continue; + } + + /* Get the size of the data block received */ + ulRecvSize -= TFTP_HDRSIZE; + + /* Check if the size of the received data block > max size */ + if (ulRecvSize > TFTP_BLKSIZE) { + /* Send Error packet to server */ + lwip_tftp_send_error(iSockNum, + TFTPC_PROTOCOL_PROTO_ERROR, + "Packet size > max size", + &stServerAddr, pstSendBuf); + + (void)lwip_close(iSockNum); + if (isLocalFileOpened == true) { + close(fp); + } + + LWIP_DEBUGF(TFTP_DEBUG, ("lwip_tftp_get_file_by_filename : Packet size > max size\n")); + + ulErrCode = TFTPC_PKT_SIZE_ERROR; + goto err_handler; + } + + usReadReq = (u16_t)TFTPC_OP_ACK; + pstSendBuf->usOpcode = htons(usReadReq); + pstSendBuf->u.usBlknum = htons((u16_t)ulCurrBlk); + ulSize = TFTP_HDRSIZE; + + if (isLocalFileOpened == false) { + fp = open((char *)pszTempDestName, (O_WRONLY | O_CREAT | O_TRUNC), DEFFILEMODE); + if (fp == TFTP_NULL_INT32) { + ulErrCode = TFTPC_FILECREATE_ERROR; + (void)lwip_close(iSockNum); + goto err_handler; + } + isLocalFileOpened = true; + } + + if (ulRecvSize != TFTP_BLKSIZE) { + (void)lwip_tftp_send_to_server(iSockNum, ulSize, pstSendBuf, &stServerAddr); + + /* If the received packet has only header and do not have payload, the return failure */ + if (ulRecvSize != 0) { + /* Write the last packet to the file */ + iErrCode = write(fp, (void *)pstRecvBuf->u.stTFTP_Data.ucDataBuf, (size_t)ulRecvSize); + if (ulRecvSize != (u32_t)iErrCode) { + /* Write to file failed. */ + lwip_tftp_send_error(iSockNum, + TFTPC_PROTOCOL_USER_DEFINED, + "Write to file failed", + &stServerAddr, pstSendBuf); + + (void)lwip_close(iSockNum); + close(fp); + + /* return from the function, file write failed */ + ulErrCode = TFTPC_FILEWRITE_ERROR; + goto err_handler; + } + } + + /* Now free allocated resourdes and return, + data block receiving is already completed */ + (void)lwip_close(iSockNum); + close(fp); + ulErrCode = ERR_OK; + goto err_handler; + } + + ulErrCode = lwip_tftp_send_to_server(iSockNum, ulSize, + pstSendBuf, &stServerAddr); + if (ulErrCode != ERR_OK) { + (void)lwip_close(iSockNum); + close(fp); + goto err_handler; + } + + iErrCode = write(fp, (void *)pstRecvBuf->u.stTFTP_Data.ucDataBuf, (size_t)ulRecvSize); + if (ulRecvSize != (u32_t)iErrCode) { + /* Write to file failed. */ + lwip_tftp_send_error(iSockNum, + TFTPC_PROTOCOL_USER_DEFINED, + "Write to file failed", + &stServerAddr, pstSendBuf); + + (void)lwip_close(iSockNum); + close(fp); + + /* return from the function, file write failed */ + ulErrCode = TFTPC_FILEWRITE_ERROR; + goto err_handler; + } + + /* form the ACK packet for the DATA packet received */ + /* Go to the next packet no. */ + ulCurrBlk++; + + /* if the file is too big, exit */ + if (ulCurrBlk > TFTP_MAX_BLK_NUM) { + /* Send error packet to server */ + lwip_tftp_send_error(iSockNum, + TFTPC_PROTOCOL_USER_DEFINED, + "File is too big.", + &stServerAddr, pstSendBuf); + + (void)lwip_close(iSockNum); + close(fp); + LWIP_DEBUGF(TFTP_DEBUG, ("lwip_tftp_get_file_by_filename : Data block number exceeded max value\n")); + + ulErrCode = TFTPC_FILE_TOO_BIG; + goto err_handler; + } + } + +err_handler: + mem_free(pstSendBuf); + mem_free(pstRecvBuf); + mem_free(pszTempDestName); + return ulErrCode; +} + + +/* INTERFACE Function to put a file using filename + ulHostAddr: IP address of Host + szSrcFileName: Source file + szDestDirPath: Destination file path +*/ +u32_t lwip_tftp_put_file_by_filename(u32_t ulHostAddr, u16_t usTftpServPort, u8_t ucTftpTransMode, + s8_t *szSrcFileName, s8_t *szDestDirPath) +{ + u32_t ulSrcStrLen; + u32_t ulDestStrLen; + s32_t iSockNum = TFTP_NULL_INT32; + s32_t iErrCode; + u32_t ulErrCode; + u16_t usTempServPort; + TFTPC_PACKET_S *pstSendBuf = NULL; + u16_t usReadReq; + u32_t ulSize; + s8_t *pucBuffer = 0; + s8_t *szTempDestName = NULL; + + /*Initialize the block number*/ + u16_t usCurrBlk = 0; + struct sockaddr_in stServerAddr; + struct stat buffer; + s32_t fp = -1; + + /* Validate parameters */ + if ((szSrcFileName == NULL) || (szDestDirPath == NULL)) { + return TFTPC_INVALID_PARAVALUE; + } + + if ((ucTftpTransMode != TRANSFER_MODE_BINARY) && (ucTftpTransMode != TRANSFER_MODE_ASCII)) { + return TFTPC_INVALID_PARAVALUE; + } + + /*check IP address not within ( 1.0.0.0 - 126.255.255.255 ) + and ( 128.0.0.0 - 223.255.255.255 ) range.*/ + if (!(((ulHostAddr >= TFTPC_IP_ADDR_MIN) && + (ulHostAddr <= TFTPC_IP_ADDR_EX_RESV)) || + ((ulHostAddr >= TFTPC_IP_ADDR_CLASS_B) && + (ulHostAddr <= TFTPC_IP_ADDR_EX_CLASS_DE)))) { + return TFTPC_IP_NOT_WITHIN_RANGE; + } + + /* If Src filename is empty or exceeded max length */ + ulSrcStrLen = strlen((char *)szSrcFileName); + if ((ulSrcStrLen == 0) || (ulSrcStrLen >= TFTP_MAX_PATH_LENGTH)) { + return TFTPC_SRC_FILENAME_LENGTH_ERROR; + } + + /* Check if source file exists */ + if (stat((char *)szSrcFileName, &buffer) != 0) { + return TFTPC_FILE_NOT_EXIST; + } + + /* Check if the file is too big */ + if (buffer.st_size >= (off_t)(TFTP_MAX_BLK_NUM * TFTP_BLKSIZE)) { + return TFTPC_FILE_TOO_BIG; + } + + /* Check validity of destination path */ + ulDestStrLen = strlen((char *)szDestDirPath); + /* If dest path length exceeded max value */ + if (ulDestStrLen >= TFTP_MAX_PATH_LENGTH) { + return TFTPC_DEST_PATH_LENGTH_ERROR; + } + + pstSendBuf = (TFTPC_PACKET_S *)mem_malloc(sizeof(TFTPC_PACKET_S)); + if (pstSendBuf == NULL) { + return TFTPC_MEMALLOC_ERROR; + } + + /* First time initialize the buffer */ + (void)memset_s((void *)pstSendBuf, sizeof(TFTPC_PACKET_S), 0, sizeof(TFTPC_PACKET_S)); + + /* The destination path can only be one of the following: + 1. Only filename + 2. Relative path WITH filename + 3. Empty string + */ + if (ulDestStrLen != 0) { + /* If not empty string use the Destination path name */ + szTempDestName = szDestDirPath; + } else { + /* If destination directory is empty string use source filename + If given src filename is a relative path extract the file name + from the path */ + if ((strchr((char *)szSrcFileName, '/') != 0) || + (strchr((char *)szSrcFileName, '\\') != 0)) { + /* Move to the end of the src file path */ + szTempDestName = szSrcFileName + (ulSrcStrLen - 1); + + while (((*(szTempDestName - 1) != '/') && (*(szTempDestName - 1) != '\\')) && + (szTempDestName != szSrcFileName)) { + szTempDestName--; + } + } else { + /* If not a relative src path use the given src filename */ + szTempDestName = szSrcFileName; + } + } + + /* Create a socket and bind it to an available port number */ + ulErrCode = lwip_tftp_create_bind_socket(&iSockNum); + if (ulErrCode != EOK) { + /* Create and Bind socket failed */ + goto err_handler; + } + + if (usTftpServPort == 0) { + usTftpServPort = TFTPC_SERVER_PORT; + } + + usTempServPort = usTftpServPort; + + /* set server internet address */ + (void)memset_s(&stServerAddr, sizeof(stServerAddr), 0, sizeof(stServerAddr)); + stServerAddr.sin_family = AF_INET; + stServerAddr.sin_port = htons(usTempServPort); + stServerAddr.sin_addr.s_addr = htonl(ulHostAddr); + + /* Make request packet - TFTPC_OP_WRQ */ + ulSize = (u32_t)lwip_tftp_make_tftp_packet(TFTPC_OP_WRQ, + szTempDestName, + ucTftpTransMode, + pstSendBuf); + + ulErrCode = lwip_tftp_send_to_server(iSockNum, ulSize, + pstSendBuf, &stServerAddr); + if (ulErrCode != ERR_OK) { + /* Send to server error */ + (void)lwip_close(iSockNum); + + goto err_handler; + } + + /* Send the request packet */ + ulErrCode = lwip_tftp_inner_put_file(iSockNum, pstSendBuf, ulSize, + usCurrBlk, &stServerAddr); + if (ulErrCode != ERR_OK) { + /* Send request packet failed */ + (void)lwip_close(iSockNum); + + LWIP_DEBUGF(TFTP_DEBUG, ("lwip_tftp_put_file_by_filename : Failed to send request packet\n")); + + goto err_handler; + } + + /* Create buffer block size */ + pucBuffer = mem_malloc(TFTP_BLKSIZE); + if (pucBuffer == NULL) { + /* Memory allocation failed */ + lwip_tftp_send_error(iSockNum, + TFTPC_PROTOCOL_USER_DEFINED, + "Memory allocation failed.", + &stServerAddr, pstSendBuf); + + (void)lwip_close(iSockNum); + ulErrCode = TFTPC_MEMALLOC_ERROR; + goto err_handler; + } + + (void)memset_s((void *)pucBuffer, TFTP_BLKSIZE, 0, TFTP_BLKSIZE); + + fp = open((char *)szSrcFileName, O_RDONLY); + if (TFTP_NULL_INT32 == fp) { + /* If file could not be opened send error to server */ + lwip_tftp_send_error(iSockNum, + TFTPC_PROTOCOL_USER_DEFINED, + "File open error.", + &stServerAddr, pstSendBuf); + + (void)lwip_close(iSockNum); + mem_free(pucBuffer); + + ulErrCode = TFTPC_FILEOPEN_ERROR; + goto err_handler; + } + + iErrCode = read(fp, pucBuffer, TFTP_BLKSIZE); + if (iErrCode < 0) { + /* If failed to read from file */ + lwip_tftp_send_error(iSockNum, + TFTPC_PROTOCOL_USER_DEFINED, + "File read error.", + &stServerAddr, pstSendBuf); + + (void)lwip_close(iSockNum); + close(fp); + mem_free(pucBuffer); + + ulErrCode = TFTPC_FILEREAD_ERROR; + goto err_handler; + } + + /* Read from source file and send to server */ + /* To send empty packet to server when file is a 0 byte file */ + do { + if (((u32_t)usCurrBlk + 1) > TFTP_MAX_BLK_NUM) { + lwip_tftp_send_error(iSockNum, + TFTPC_PROTOCOL_USER_DEFINED, + "File is too big.", + &stServerAddr, pstSendBuf); + + (void)lwip_close(iSockNum); + close(fp); + mem_free(pucBuffer); + LWIP_DEBUGF(TFTP_DEBUG, ("lwip_tftp_put_file_by_filename : Data block number exceeded max value\n")); + + ulErrCode = TFTPC_FILE_TOO_BIG; + goto err_handler; + } + + /* Increment block number */ + usCurrBlk++; + + ulSize = (u32_t)iErrCode + TFTP_HDRSIZE; + + /* Form the DATA packet */ + usReadReq = (u16_t)TFTPC_OP_DATA; + pstSendBuf->usOpcode = htons(usReadReq); + pstSendBuf->u.stTFTP_Data.usBlknum = htons(usCurrBlk); + if (memcpy_s((void *)pstSendBuf->u.stTFTP_Data.ucDataBuf, TFTP_BLKSIZE, + (void *)pucBuffer, (u32_t)iErrCode) != EOK) { + (void)lwip_close(iSockNum); + close(fp); + mem_free(pucBuffer); + goto err_handler; + } + + ulErrCode = lwip_tftp_send_to_server(iSockNum, ulSize, + pstSendBuf, &stServerAddr); + if ((ulErrCode != ERR_OK) || (memset_s((void *)pucBuffer, TFTP_BLKSIZE, 0, TFTP_BLKSIZE) != 0)) { + (void)lwip_close(iSockNum); + close(fp); + mem_free(pucBuffer); + goto err_handler; + } + + /* Read a block from the file to buffer */ + iErrCode = read(fp, pucBuffer, TFTP_BLKSIZE); + if (iErrCode < 0) { + /*If failed to read from file*/ + lwip_tftp_send_error(iSockNum, TFTPC_PROTOCOL_USER_DEFINED, "File read error.", + &stServerAddr, pstSendBuf); + + (void)lwip_close(iSockNum); + close(fp); + mem_free(pucBuffer); + ulErrCode = TFTPC_FILEREAD_ERROR; + goto err_handler; + } + + /* Send the request packet */ + ulErrCode = lwip_tftp_inner_put_file(iSockNum, pstSendBuf, ulSize, + usCurrBlk, &stServerAddr); + if (ulErrCode != ERR_OK) { + /* Sending buffer contents failed */ + (void)lwip_close(iSockNum); + close(fp); + mem_free(pucBuffer); + LWIP_DEBUGF(TFTP_DEBUG, ("lwip_tftp_put_file_by_filename : Sending file to server failed\n")); + goto err_handler; + } + } while (ulSize == (TFTP_BLKSIZE + TFTP_HDRSIZE)); + + /* Transfer of data is finished */ + (void)lwip_close(iSockNum); + close(fp); + mem_free(pucBuffer); + + ulErrCode = ERR_OK; +err_handler: + mem_free(pstSendBuf); + return ulErrCode; +} + +/* Put file function + iSockNum: Socket ID + pstSendBuf: Packet to send to server + ulSendSize: Packet length + usCurrBlk: Current block number + pstServerAddr: Server address +*/ +u32_t lwip_tftp_inner_put_file(s32_t iSockNum, + TFTPC_PACKET_S *pstSendBuf, + u32_t ulSendSize, + u16_t usCurrBlk, + struct sockaddr_in *pstServerAddr) +{ + u32_t ulPktSize; + u32_t ulError; + s32_t iError; + int iRecvLen = 0; + socklen_t iFromAddrLen; + u32_t ulTotalTime = 0; + fd_set stReadfds; + struct sockaddr_in stFromAddr; + struct timeval stTimeout; + TFTPC_PACKET_S *pstRecvBuf = NULL; + u32_t ulIgnorePkt = 0; + u16_t usBlknum; + u32_t ulLoopCnt = 0; + + iFromAddrLen = sizeof(stFromAddr); + + pstRecvBuf = (TFTPC_PACKET_S *)mem_malloc(sizeof(TFTPC_PACKET_S)); + if (pstRecvBuf == NULL) { + return TFTPC_MEMALLOC_ERROR; + } + + /* First time initialize the buffer */ + (void)memset_s((void *)pstRecvBuf, sizeof(TFTPC_PACKET_S), 0, sizeof(TFTPC_PACKET_S)); + + /* Initialize from address to the server address at first */ + if (memcpy_s((void *)&stFromAddr, sizeof(struct sockaddr_in), + (void *)pstServerAddr, sizeof(stFromAddr)) != EOK) { + ulError = TFTPC_MEMCPY_FAILURE; + goto err_handler; + } + + for (;;) { + ulError = lwip_tftp_recv_from_server(iSockNum, &ulPktSize, + pstRecvBuf, &ulIgnorePkt, + pstServerAddr, pstSendBuf); + /* If select timeout occurred */ + if (ulError == TFTPC_TIMEOUT_ERROR) { + ulTotalTime++; + if (ulTotalTime < TFTPC_MAX_SEND_REQ_ATTEMPTS) { + /*Max attempts not reached. Resend packet*/ + ulError = lwip_tftp_send_to_server(iSockNum, ulSendSize, + pstSendBuf, pstServerAddr); + if (ulError != ERR_OK) { + goto err_handler; + } + + continue; + } else { + /* return from the function, max attempts limit reached */ + ulError = TFTPC_TIMEOUT_ERROR; + goto err_handler; + } + } else if (ulError != ERR_OK) { + /* return from the function, RecvFromServer failed */ + goto err_handler; + } + + /* If Received packet from another server */ + if (ulIgnorePkt > 0) { + /* The packet that is received is to be ignored. + So continue without processing it. */ + ulIgnorePkt = 0; + continue; + } + + /* if this packet is unknown or incorrect packet */ + if (TFTPC_OP_ACK != ntohs(pstRecvBuf->usOpcode)) { + lwip_tftp_send_error(iSockNum, + TFTPC_PROTOCOL_PROTO_ERROR, + "Protocol error.", + pstServerAddr, pstSendBuf); + + LWIP_DEBUGF(TFTP_DEBUG, ("lwip_tftp_inner_put_file : Received pkt not Ack pkt\n")); + + ulError = TFTPC_PROTO_ERROR; + goto err_handler; + } + + ulTotalTime = 0; + + /* if the packet is acknowledge packet */ + usBlknum = ntohs(pstRecvBuf->u.usBlknum); + iRecvLen = (int)ulPktSize; + + /* If not correct block no. */ + if (usBlknum != usCurrBlk) { + /* we are not in sync now */ + /* reset any collected packets. */ + stTimeout.tv_sec = 1; + stTimeout.tv_usec = 0; + + FD_ZERO(&stReadfds); + FD_SET(iSockNum, &stReadfds); + + /* + Need to take care of timeout scenario in Select call. + Since the socket used is blocking, if select timeout occurs, + the following recvfrom will block indefinitely. + */ + iError = select((s32_t)(iSockNum + 1), &stReadfds, 0, 0, &stTimeout); + + /* Loop to get the last data packet from the receive buffer */ + while ((iError != -1) && (iError != 0)) { + ulLoopCnt++; + + /* MAX file size in TFTP is 32 MB. + Reason for keeping 75 here , is ((75*512=38400bytes)/1024) = 37MB. So the recv/Snd + Loop can receive the complete MAX message from the network. + */ + if (ulLoopCnt > TFTPC_MAX_WAIT_IN_LOOP) { + LWIP_DEBUGF(TFTP_DEBUG, + ("lwip_tftp_inner_put_file : unexpected packets are received repeatedly\n")); + ulError = TFTPC_PKT_SIZE_ERROR; + goto err_handler; + } + + FD_ZERO(&stReadfds); + FD_SET(iSockNum, &stReadfds); + iRecvLen = lwip_recvfrom(iSockNum, + (s8_t *)pstRecvBuf, + TFTP_PKTSIZE, 0, + (struct sockaddr *)&stFromAddr, + &iFromAddrLen); + if (TFTP_NULL_INT32 == iRecvLen) { + ulError = TFTPC_RECVFROM_ERROR; + goto err_handler; + } + + stTimeout.tv_sec = 1; + stTimeout.tv_usec = 0; + iError = select((s32_t)(iSockNum + 1), + &stReadfds, 0, 0, &stTimeout); + } + + /* If a new packet is not received then donot change the byte order + * as it has already been done + */ + /* If received packet size < minimum packet size */ + if (iRecvLen < TFTPC_FOUR) { + lwip_tftp_send_error(iSockNum, + TFTPC_PROTOCOL_PROTO_ERROR, + "Packet size < min packet size", + pstServerAddr, pstSendBuf); + + LWIP_DEBUGF(TFTP_DEBUG, ("lwip_tftp_inner_put_file : Received pkt not Ack pkt\n")); + + ulError = TFTPC_PKT_SIZE_ERROR; + goto err_handler; + } + + /* Check if the received packet is from correct server and from + correct port + */ + if ((stFromAddr.sin_addr.s_addr != pstServerAddr->sin_addr.s_addr) || + (pstServerAddr->sin_port != stFromAddr.sin_port)) { + /* This ACK packet is invalid. Just ignore it. */ + LWIP_DEBUGF(TFTP_DEBUG, ("lwip_tftp_inner_put_file : Received pkt from unknown server\n")); + continue; + } + + /* if this packet is not ACK packet */ + if (TFTPC_OP_ACK != ntohs(pstRecvBuf->usOpcode)) { + lwip_tftp_send_error(iSockNum, + TFTPC_PROTOCOL_PROTO_ERROR, + "Protocol error.", + pstServerAddr, pstSendBuf); + + LWIP_DEBUGF(TFTP_DEBUG, ("lwip_tftp_inner_put_file : Received pkt not Ack pkt\n")); + + ulError = TFTPC_PROTO_ERROR; + goto err_handler; + } + + usBlknum = ntohs(pstRecvBuf->u.usBlknum); + /* + * In this case we have received a duplicate ACK for data block. + * (ACK for this data block was aready received earlier) + * In this case we have usRecvBlkNum == (usNextBlkNum - 1). + * This could mean that: + * (i) last data packet that was sent was not received at server side + * (ii) Acknowledgement of peer side is delayed. + * + * In this case, this duplicate ACK will be ignored and return to the + * state machine to initiate a receive of this data packet. + */ + if ((usCurrBlk - 1) == usBlknum) { + /* This ACK packet is invalid. Just ignore it. */ + continue; + } + + /* Now check the block number with current block. + * If it is not the previous block and the current block, + * then it is an unexpected packet. + */ + if (usBlknum != usCurrBlk) { + lwip_tftp_send_error(iSockNum, + TFTPC_PROTOCOL_PROTO_ERROR, + "Received unexpected packet", + pstServerAddr, pstSendBuf); + + LWIP_DEBUGF(TFTP_DEBUG, + ("lwip_tftp_inner_put_file : Received DATA pkt no. %"S32_F"instead of pkt no. %"S32_F"\n", + usBlknum, usCurrBlk)); + + ulError = TFTPC_SYNC_FAILURE; + goto err_handler; + } + } + + ulError = ERR_OK; + goto err_handler; + } + +err_handler: + mem_free(pstRecvBuf); + return ulError; +} + +#ifdef TFTP_TO_RAWMEM +/* INTERFACE to get a file using filename + ulHostAddr - IP address of Host + szSrcFileName - Source file + szDestMemAddr - The target memory address in the client + + Example : + ulHostAddr = ntohl(inet_addr ("192.168.1.3")); + lwip_tftp_get_file_by_filename_to_rawmem(ulHostAddr, "/ramfs/vs_server.bin", memaddr, &filelen); +*/ +u32_t lwip_tftp_get_file_by_filename_to_rawmem(u32_t ulHostAddr, + u16_t usTftpServPort, + u8_t ucTftpTransMode, + s8_t *szSrcFileName, + s8_t *szDestMemAddr, + u32_t *ulFileLength) +{ + s32_t iSockNum = TFTP_NULL_INT32; + u32_t ulSrcStrLen; + u32_t ulSize; + u32_t ulRecvSize = TFTP_NULL_UINT32; + u32_t ulErrCode; + u16_t usReadReq; + u16_t usTempServPort; + u32_t ulCurrBlk = 1; + u32_t ulResendPkt = 0; /* Resend the previous packet */ + u32_t ulIgnorePkt = 0; /* Ignore received packet */ + u32_t ulTotalTime = 0; + + TFTPC_PACKET_S *pstSendBuf = NULL; + TFTPC_PACKET_S *pstRecvBuf = NULL; + struct sockaddr_in stServerAddr; + u32_t ulMemOffset = 0; + + /* Validate the parameters */ + if ((szSrcFileName == NULL) || (szDestMemAddr == NULL) || (*ulFileLength == 0)) { + return TFTPC_INVALID_PARAVALUE; + } + + if ((ucTftpTransMode != TRANSFER_MODE_BINARY) && (ucTftpTransMode != TRANSFER_MODE_ASCII)) { + return TFTPC_INVALID_PARAVALUE; + } + + /* check IP address not within ( 1.0.0.0 - 126.255.255.255 ) + and ( 128.0.0.0 - 223.255.255.255 ) range. */ + if (!(((ulHostAddr >= TFTPC_IP_ADDR_MIN) && + (ulHostAddr <= TFTPC_IP_ADDR_EX_RESV)) || + ((ulHostAddr >= TFTPC_IP_ADDR_CLASS_B) && + (ulHostAddr <= TFTPC_IP_ADDR_EX_CLASS_DE)))) { + return TFTPC_IP_NOT_WITHIN_RANGE; + } + + /*Check validity of source filename*/ + ulSrcStrLen = strlen(szSrcFileName); + if ((ulSrcStrLen == 0) || (ulSrcStrLen >= TFTP_MAX_PATH_LENGTH)) { + return TFTPC_SRC_FILENAME_LENGTH_ERROR; + } + + pstSendBuf = (TFTPC_PACKET_S *)mem_malloc(sizeof(TFTPC_PACKET_S)); + if (pstSendBuf == NULL) { + return TFTPC_MEMALLOC_ERROR; + } + + pstRecvBuf = (TFTPC_PACKET_S *)mem_malloc(sizeof(TFTPC_PACKET_S)); + if (pstRecvBuf == NULL) { + mem_free(pstSendBuf); + return TFTPC_MEMALLOC_ERROR; + } + + /* First time initialize the buffers */ + (void)memset_s((void *)pstSendBuf, sizeof(TFTPC_PACKET_S), 0, sizeof(TFTPC_PACKET_S)); + (void)memset_s((void *)pstRecvBuf, sizeof(TFTPC_PACKET_S), 0, sizeof(TFTPC_PACKET_S)); + + ulErrCode = lwip_tftp_create_bind_socket(&iSockNum); + if (ulErrCode != EOK) { + goto err_handler; + } + + if (usTftpServPort == 0) { + usTftpServPort = TFTPC_SERVER_PORT; + } + + usTempServPort = usTftpServPort; + + /* set server IP address */ + (void)memset_s(&stServerAddr, sizeof(stServerAddr), 0, sizeof(stServerAddr)); + stServerAddr.sin_family = AF_INET; + stServerAddr.sin_port = htons(usTempServPort); + stServerAddr.sin_addr.s_addr = htonl(ulHostAddr); + + /* Make a request packet - TFTPC_OP_RRQ */ + ulSize = (u32_t)lwip_tftp_make_tftp_packet(TFTPC_OP_RRQ, szSrcFileName, (u32_t)ucTftpTransMode, pstSendBuf); + ulErrCode = lwip_tftp_send_to_server(iSockNum, ulSize, pstSendBuf, &stServerAddr); + if (ulErrCode != ERR_OK) { + /* send to server failed */ + (void)lwip_close(iSockNum); + goto err_handler; + } + + for (;;) { + if (ulIgnorePkt > 0) { + ulIgnorePkt = 0; + } + + ulErrCode = lwip_tftp_recv_from_server(iSockNum, &ulRecvSize, pstRecvBuf, &ulIgnorePkt, + &stServerAddr, pstSendBuf); + /* If select timeout occurred */ + if (ulErrCode == TFTPC_TIMEOUT_ERROR) { + ulTotalTime++; + if (ulTotalTime < TFTPC_MAX_SEND_REQ_ATTEMPTS) { + /* Max attempts not reached. Resend packet */ + ulErrCode = lwip_tftp_send_to_server(iSockNum, ulSize, + pstSendBuf, &stServerAddr); + if (ulErrCode != ERR_OK) { + (void)lwip_close(iSockNum); + goto err_handler; + } + + continue; + } else { + /* return from the function, max attempts limit reached */ + (void)lwip_close(iSockNum); + ulErrCode = TFTPC_TIMEOUT_ERROR; + goto err_handler; + } + } else if (ulErrCode != ERR_OK) { + (void)lwip_close(iSockNum); + goto err_handler; + } + + /* Now we have receive block from different server. */ + if (ulIgnorePkt > 0) { + /*Continue without processing this block. */ + continue; + } + + /* if this packet is unkonwn or incorrect packet */ + if (ntohs(pstRecvBuf->usOpcode) != TFTPC_OP_DATA) { + /* Send error packet to server */ + lwip_tftp_send_error(iSockNum, + TFTPC_PROTOCOL_PROTO_ERROR, + "Protocol error.", + &stServerAddr, pstSendBuf); + + (void)lwip_close(iSockNum); + + LWIP_DEBUGF(TFTP_DEBUG, ("lwip_tftp_get_file_by_filename : Received pkt not DATA pkt\n")); + + ulErrCode = TFTPC_PROTO_ERROR; + goto err_handler; + } + + /* Now the number of tries will be reset. */ + ulTotalTime = 0; + + /* Validate received DATA packet. */ + ulErrCode = lwip_tftp_validate_data_pkt(iSockNum, &ulRecvSize, + pstRecvBuf, (u16_t)ulCurrBlk, + &ulResendPkt, + &stServerAddr); + if (ulErrCode != ERR_OK) { + /* Send Error packet to server */ + if (ulErrCode != TFTPC_RECVFROM_ERROR) { + lwip_tftp_send_error(iSockNum, + TFTPC_PROTOCOL_PROTO_ERROR, + "Received unexpected packet", + &stServerAddr, pstSendBuf); + } + + (void)lwip_close(iSockNum); + + goto err_handler; + } + + /* Received previous data block again. Resend last packet */ + if (ulResendPkt > 0) { + /* Now set ulResendPkt to 0 to send the last packet. */ + ulResendPkt = 0; + ulErrCode = lwip_tftp_send_to_server(iSockNum, ulSize, + pstSendBuf, &stServerAddr); + if (ulErrCode != ERR_OK) { + (void)lwip_close(iSockNum); + + goto err_handler; + } + + /* Continue in loop to send last packet again. */ + continue; + } + + /* Get the size of the data block received */ + ulRecvSize -= TFTP_HDRSIZE; + + /* Check if the size of the received data block > max size */ + if (ulRecvSize > TFTP_BLKSIZE) { + /* Send Error packet to server */ + lwip_tftp_send_error(iSockNum, + TFTPC_PROTOCOL_PROTO_ERROR, + "Packet size > max size", + &stServerAddr, pstSendBuf); + + (void)lwip_close(iSockNum); + + LWIP_DEBUGF(TFTP_DEBUG, ("lwip_tftp_get_file_by_filename : Packet size > max size\n")); + + ulErrCode = TFTPC_PKT_SIZE_ERROR; + goto err_handler; + } + + usReadReq = (u16_t)TFTPC_OP_ACK; + pstSendBuf->usOpcode = htons(usReadReq); + pstSendBuf->u.usBlknum = htons((u16_t)ulCurrBlk); + ulSize = TFTP_HDRSIZE; + + if (ulRecvSize != TFTP_BLKSIZE) { + (void)lwip_tftp_send_to_server(iSockNum, ulSize, + pstSendBuf, &stServerAddr); + + /* If the received packet has only header and do not have payload, the return failure */ + if (ulRecvSize != 0) { + /* memcopy filed */ + if (*ulFileLength < (ulMemOffset + ulRecvSize)) { + ulErrCode = TFTPC_MEMCPY_FAILURE; + (void)lwip_close(iSockNum); + *ulFileLength = ulMemOffset; + goto err_handler; + } + /* copy the last packet to the memory */ + if (memcpy_s(szDestMemAddr + ulMemOffset, TFTP_MAX_BLK_NUM * TFTP_BLKSIZE, + (void *)pstRecvBuf->u.stTFTP_Data.ucDataBuf, (size_t)ulRecvSize) != EOK) { + ulErrCode = TFTPC_MEMCPY_FAILURE; + (void)lwip_close(iSockNum); + *ulFileLength = ulMemOffset; + goto err_handler; + } + ulMemOffset += ulRecvSize; + } + + /* Now free allocated resourdes and return, + data block receiving is already completed */ + (void)lwip_close(iSockNum); + ulErrCode = ERR_OK; + *ulFileLength = ulMemOffset; + goto err_handler; + } + + ulErrCode = lwip_tftp_send_to_server(iSockNum, ulSize, + pstSendBuf, &stServerAddr); + if (ulErrCode != ERR_OK) { + (void)lwip_close(iSockNum); + goto err_handler; + } + + /* memcopy filed */ + if (*ulFileLength < ulRecvSize * ulCurrBlk) { + ulErrCode = TFTPC_MEMCPY_FAILURE; + (void)lwip_close(iSockNum); + *ulFileLength = ulMemOffset; + goto err_handler; + } + if (memcpy_s(szDestMemAddr + ulMemOffset, TFTP_MAX_BLK_NUM * TFTP_BLKSIZE, + (void *)pstRecvBuf->u.stTFTP_Data.ucDataBuf, (size_t)ulRecvSize) != EOK) { + ulErrCode = TFTPC_MEMCPY_FAILURE; + (void)lwip_close(iSockNum); + *ulFileLength = ulMemOffset; + goto err_handler; + } + + ulMemOffset += ulRecvSize; + /* form the ACK packet for the DATA packet received */ + /* Go to the next packet no. */ + ulCurrBlk++; + /* if the file is too big, exit */ + if (ulCurrBlk > TFTP_MAX_BLK_NUM) { + /* Send error packet to server */ + lwip_tftp_send_error(iSockNum, + TFTPC_PROTOCOL_USER_DEFINED, + "File is too big.", + &stServerAddr, pstSendBuf); + + (void)lwip_close(iSockNum); + + LWIP_DEBUGF(TFTP_DEBUG, ("lwip_tftp_get_file_by_filename : Data block number exceeded max value\n")); + + ulErrCode = TFTPC_FILE_TOO_BIG; + goto err_handler; + } + } + +err_handler: + mem_free(pstSendBuf); + mem_free(pstRecvBuf); + return ulErrCode; +} +#endif + +#endif /* LOSCFG_NET_LWIP_SACK_TFTP */ +#endif /* LWIP_TFTP */ diff --git a/src/kernel_liteos_a/apps/toybox/BUILD.gn b/src/kernel_liteos_a/apps/toybox/BUILD.gn new file mode 100644 index 00000000..e347c372 --- /dev/null +++ b/src/kernel_liteos_a/apps/toybox/BUILD.gn @@ -0,0 +1,84 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//build/lite/config/component/lite_component.gni") +import("//kernel/liteos_a/liteos.gni") +import("$THIRDPARTY_TOYBOX_DIR/toybox.gni") + +group("toybox") { + deps = [ ":build_toybox" ] +} + +copy("copy_toybox_src") { + sources = TOYBOX_SRC_DIR + outputs = [ "$target_out_dir/toybox_build" ] +} + +copy("copy_toybox_config") { + deps = [ ":copy_toybox_src" ] + sources = [ "liteos_a_custom.config" ] + outputs = [ "$target_out_dir/{{source_file_part}}" ] +} + +build_ext_component("build_toybox") { + deps = [ + ":copy_toybox_config", + ":copy_toybox_src", + ] + deps += [ "$THIRDPARTY_MUSL_DIR:sysroot_lite" ] + exec_path = rebase_path("$target_out_dir/toybox_build") + + cflags = [ + "-fstack-protector-strong", + "-D_FORTIFY_SOURCE=2", + ] + cflags = string_join(" ", cflags) + + extra_flags = string_join(" ", target_arch_cflags) + if (ohos_build_compiler == "clang") { + extra_flags += " --target=$target_triple" + extra_flags += " --sysroot=" + rebase_path(ohos_current_sysroot) + } + + command = "rm -rf .git && cp -rfp porting/liteos_a/. . && env" + command += " CC=\"$ohos_current_cc_command\"" + command += " STRIP=\"$ohos_current_strip_command\"" + command += " OUTNAME=toybox" + command += " CFLAGS=\"$cflags $extra_flags\"" + command += " make toybox" + command += " && install -D toybox " + command += rebase_path("$root_out_dir/bin/toybox", exec_path) + command += " && install -D generated/unstripped/toybox " + command += rebase_path("$root_out_dir/unstripped/bin/toybox", exec_path) + + outputs = [ + "$root_out_dir/unstripped/bin/toybox", + "$root_out_dir/bin/toybox", + ] +} diff --git a/src/kernel_liteos_a/apps/toybox/Makefile b/src/kernel_liteos_a/apps/toybox/Makefile new file mode 100644 index 00000000..6fd3d005 --- /dev/null +++ b/src/kernel_liteos_a/apps/toybox/Makefile @@ -0,0 +1,53 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(APPSTOPDIR)/config.mk + +BUILD_DIR := $(OUT)/toybox_build +BUILD_LOG := $(BUILD_DIR)/build.log + +CFLAGS += -Wno-error + +all: +ifneq ($(wildcard $(BUILD_DIR)),) + $(HIDE)echo "not clean, rebuilding now" +else + $(HIDE)mkdir -p $(BUILD_DIR) + $(HIDE)$(CP) $(LITEOSTHIRDPARTY)/toybox/. $(BUILD_DIR) + $(HIDE)$(CP) $(LITEOSTHIRDPARTY)/toybox/porting/liteos_a/. $(BUILD_DIR) + $(HIDE)$(CP) liteos_a_custom.config $(BUILD_DIR)/../ +endif + $(HIDE)unset KCONFIG_CONFIG CROSS_COMPILE && \ + env CC="$(CC)" OUTNAME="$(OUT)/bin/toybox" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" STRIP="$(STRIP)" \ + make -C $(BUILD_DIR) toybox -j> $(BUILD_LOG) 2>&1 + +clean: + $(HIDE)$(RM) $(BUILD_DIR) + +.PHONY: all clean diff --git a/src/kernel_liteos_a/apps/toybox/liteos_a_custom.config b/src/kernel_liteos_a/apps/toybox/liteos_a_custom.config new file mode 100644 index 00000000..7628c2fa --- /dev/null +++ b/src/kernel_liteos_a/apps/toybox/liteos_a_custom.config @@ -0,0 +1,186 @@ +# CONFIG_BASENAME is not set +# CONFIG_CAL is not set +# CONFIG_CAT is not set +# CONFIG_CATV is not set +# CONFIG_CKSUM is not set +# CONFIG_CRC32 is not set +# CONFIG_CMP is not set +# CONFIG_COMM is not set +# CONFIG_CP_PRESERVE is not set +# CONFIG_INSTALL is not set +# CONFIG_CPIO is not set +# CONFIG_CUT is not set +# CONFIG_DF is not set +# CONFIG_DIRNAME is not set +# CONFIG_ECHO is not set +# CONFIG_ENV is not set +# CONFIG_EXPAND is not set +# CONFIG_FALSE is not set +# CONFIG_FILE is not set +# CONFIG_FIND is not set +# CONFIG_GETCONF is not set +# CONFIG_GREP is not set +# CONFIG_EGREP is not set +# CONFIG_FGREP is not set +# CONFIG_HEAD is not set +# CONFIG_ICONV is not set +# CONFIG_ID is not set +# CONFIG_GROUPS is not set +# CONFIG_LOGNAME is not set +# CONFIG_WHOAMI is not set +# CONFIG_LINK is not set +# CONFIG_LN is not set +# CONFIG_LOGGER is not set +# CONFIG_MKFIFO is not set +# CONFIG_NICE is not set +# CONFIG_NL is not set +# CONFIG_NOHUP is not set +# CONFIG_OD is not set +# CONFIG_PASTE is not set +# CONFIG_PATCH is not set +# CONFIG_PRINTF is not set +# CONFIG_IOTOP is not set +# CONFIG_PGREP is not set +# CONFIG_PKILL is not set +# CONFIG_PWD is not set +# CONFIG_RENICE is not set +# CONFIG_SED is not set +# CONFIG_SLEEP is not set +# CONFIG_SORT is not set +# CONFIG_SORT_FLOAT is not set +# CONFIG_SPLIT is not set +# CONFIG_STRINGS is not set +# CONFIG_TAIL is not set +# CONFIG_TAR is not set +# CONFIG_TEE is not set +# CONFIG_TEST is not set +# CONFIG_TIME is not set +# CONFIG_TRUE is not set +# CONFIG_TTY is not set +# CONFIG_ULIMIT is not set +# CONFIG_ARCH is not set +# CONFIG_UNIQ is not set +# CONFIG_UNLINK is not set +# CONFIG_UUDECODE is not set +# CONFIG_UUENCODE is not set +# CONFIG_WC is not set +# CONFIG_WHO is not set +# CONFIG_XARGS is not set +# CONFIG_ACPI is not set +# CONFIG_ASCII is not set +# CONFIG_BASE64 is not set +# CONFIG_BLKID is not set +# CONFIG_FSTYPE is not set +# CONFIG_BLOCKDEV is not set +# CONFIG_BUNZIP2 is not set +# CONFIG_BZCAT is not set +# CONFIG_CHROOT is not set +# CONFIG_CHRT is not set +# CONFIG_CHVT is not set +# CONFIG_CLEAR is not set +# CONFIG_COUNT is not set +# CONFIG_DEVMEM is not set +# CONFIG_DOS2UNIX is not set +# CONFIG_UNIX2DOS is not set +# CONFIG_EJECT is not set +# CONFIG_FACTOR is not set +# CONFIG_FALLOCATE is not set +# CONFIG_FLOCK is not set +# CONFIG_FMT is not set +# CONFIG_FREERAMDISK is not set +# CONFIG_FSFREEZE is not set +# CONFIG_FSYNC is not set +# CONFIG_HELP_EXTRAS is not set +# CONFIG_HEXEDIT is not set +# CONFIG_HWCLOCK is not set +# CONFIG_I2CDETECT is not set +# CONFIG_I2CDUMP is not set +# CONFIG_I2CGET is not set +# CONFIG_I2CSET is not set +# CONFIG_INOTIFYD is not set +# CONFIG_INSMOD is not set +# CONFIG_IONICE is not set +# CONFIG_IORENICE is not set +# CONFIG_LOGIN is not set +# CONFIG_LOSETUP is not set +# CONFIG_LSATTR is not set +# CONFIG_CHATTR is not set +# CONFIG_LSMOD is not set +# CONFIG_LSPCI is not set +# CONFIG_LSPCI_TEXT is not set +# CONFIG_LSUSB is not set +# CONFIG_MAKEDEVS is not set +# CONFIG_MCOOKIE is not set +# CONFIG_MIX is not set +# CONFIG_MKPASSWD is not set +# CONFIG_MKSWAP is not set +# CONFIG_MODINFO is not set +# CONFIG_MOUNTPOINT is not set +# CONFIG_NBD_CLIENT is not set +# CONFIG_UNSHARE is not set +# CONFIG_NSENTER is not set +# CONFIG_ONEIT is not set +# CONFIG_PARTPROBE is not set +# CONFIG_PIVOT_ROOT is not set +# CONFIG_PMAP is not set +# CONFIG_PRINTENV is not set +# CONFIG_PWDX is not set +# CONFIG_READAHEAD is not set +# CONFIG_READLINK is not set +# CONFIG_REALPATH is not set +# CONFIG_RESET is not set +# CONFIG_REV is not set +# CONFIG_RMMOD is not set +# CONFIG_SETFATTR is not set +# CONFIG_SETSID is not set +# CONFIG_SHRED is not set +# CONFIG_STAT is not set +# CONFIG_SWAPOFF is not set +# CONFIG_SWAPON is not set +# CONFIG_SWITCH_ROOT is not set +# CONFIG_SYSCTL is not set +# CONFIG_TAC is not set +# CONFIG_NPROC is not set +# CONFIG_TASKSET is not set +# CONFIG_TIMEOUT is not set +# CONFIG_TRUNCATE is not set +# CONFIG_UPTIME is not set +# CONFIG_USLEEP is not set +# CONFIG_UUIDGEN is not set +# CONFIG_VCONFIG is not set +# CONFIG_VMSTAT is not set +# CONFIG_W is not set +# CONFIG_WATCH is not set +# CONFIG_WHICH is not set +# CONFIG_XXD is not set +# CONFIG_YES is not set +# CONFIG_FTPGET is not set +# CONFIG_FTPPUT is not set +# CONFIG_MICROCOM is not set +# CONFIG_NETCAT is not set +# CONFIG_NETCAT_LISTEN is not set +# CONFIG_NETSTAT is not set +# CONFIG_RFKILL is not set +# CONFIG_SNTP is not set +# CONFIG_TUNCTL is not set +# CONFIG_DMESG is not set +# CONFIG_GUNZIP is not set +# CONFIG_ZCAT is not set +# CONFIG_HOSTNAME is not set +# CONFIG_DNSDOMAINNAME is not set +# CONFIG_KILLALL is not set +# CONFIG_MD5SUM is not set +# CONFIG_SHA1SUM is not set +# CONFIG_MKNOD is not set +# CONFIG_MKTEMP is not set +# CONFIG_PASSWD is not set +# CONFIG_PIDOF is not set +# CONFIG_SEQ is not set +# CONFIG_SU is not set +# CONFIG_SYNC is not set +# +# pending (see toys/pending/README) +# +# CONFIG_GETTY is not set +# CONFIG_MDEV is not set +# CONFIG_MDEV_CONF is not set diff --git a/src/kernel_liteos_a/apps/trace/BUILD.gn b/src/kernel_liteos_a/apps/trace/BUILD.gn new file mode 100644 index 00000000..e8afff91 --- /dev/null +++ b/src/kernel_liteos_a/apps/trace/BUILD.gn @@ -0,0 +1,34 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +executable("trace") { + sources = [ "src/trace.c" ] +} diff --git a/src/kernel_liteos_a/apps/trace/Makefile b/src/kernel_liteos_a/apps/trace/Makefile new file mode 100644 index 00000000..787ca20f --- /dev/null +++ b/src/kernel_liteos_a/apps/trace/Makefile @@ -0,0 +1,36 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(APPSTOPDIR)/config.mk + +APP_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := src/trace.c + +include $(APP) \ No newline at end of file diff --git a/src/kernel_liteos_a/apps/trace/src/trace.c b/src/kernel_liteos_a/apps/trace/src/trace.c new file mode 100644 index 00000000..ecc4f229 --- /dev/null +++ b/src/kernel_liteos_a/apps/trace/src/trace.c @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TRACE_IOC_MAGIC 'T' +#define TRACE_START _IO(TRACE_IOC_MAGIC, 1) +#define TRACE_STOP _IO(TRACE_IOC_MAGIC, 2) +#define TRACE_RESET _IO(TRACE_IOC_MAGIC, 3) +#define TRACE_DUMP _IO(TRACE_IOC_MAGIC, 4) +#define TRACE_SET_MASK _IO(TRACE_IOC_MAGIC, 5) + +#define TRACE_USR_MAX_PARAMS 3 +typedef struct { + unsigned int eventType; + uintptr_t identity; + uintptr_t params[TRACE_USR_MAX_PARAMS]; +} UsrEventInfo; + +static void TraceUsage(void) +{ + printf("\nUsage: ./trace [start] Start to trace events.\n"); + printf("\nUsage: ./trace [stop] Stop trace.\n"); + printf("\nUsage: ./trace [reset] Clear the trace record buffer.\n"); + printf("\nUsage: ./trace [dump 0/1] Format printf trace data," + "0/1 stands for whether to send data to studio for analysis.\n"); + printf("\nUsage: ./trace [mask num] Set trace filter event mask.\n"); + printf("\nUsage: ./trace [read nBytes] Read nBytes raw data from trace buffer.\n"); + printf("\nUsage: ./trace [write type id params..] Write a user event, no more than 3 parameters.\n"); +} + +static void TraceRead(int fd, size_t size) +{ + ssize_t i; + ssize_t len; + if (size == 0) { + return; + } + + char *buffer = (char *)malloc(size); + if (buffer == NULL) { + printf("Read buffer malloc failed.\n"); + return; + } + + len = read(fd, buffer, size); + for (i = 0; i < len; i++) { + printf("%02x ", buffer[i] & 0xFF); + } + printf("\n"); + free(buffer); +} + +static void TraceWrite(int fd, int argc, char **argv) +{ + int i; + UsrEventInfo info = {0}; + info.eventType = strtoul(argv[2], NULL, 0); /* 2, argv number */ + info.identity = strtoul(argv[3], NULL, 0); /* 3, argv number */ + /* 4, argc -4 means user argv that does not contain argv[0]~argv[3] */ + int paramNum = (argc - 4) > TRACE_USR_MAX_PARAMS ? TRACE_USR_MAX_PARAMS : (argc - 4); + + for (i = 0; i < paramNum; i++) { + /* 4, argc -4 means user argv that does not contain argv[0]~argv[3] */ + info.params[i] = strtoul(argv[4 + i], NULL, 0); + } + (void)write(fd, &info, sizeof(UsrEventInfo)); +} + +int main(int argc, char **argv) +{ + int fd = open("/dev/trace", O_RDWR); + if (fd == -1) { + printf("Trace open failed.\n"); + exit(EXIT_FAILURE); + } + + if (argc == 1) { + TraceUsage(); + } else if (argc == 2 && strcmp(argv[1], "start") == 0) { /* 2, argv num, no special meaning */ + ioctl(fd, TRACE_START, NULL); + } else if (argc == 2 && strcmp(argv[1], "stop") == 0) { /* 2, argv num, no special meaning */ + ioctl(fd, TRACE_STOP, NULL); + } else if (argc == 2 && strcmp(argv[1], "reset") == 0) { /* 2, argv num, no special meaning */ + ioctl(fd, TRACE_RESET, NULL); + } else if (argc == 3 && strcmp(argv[1], "mask") == 0) { /* 3, argv num, no special meaning */ + size_t mask = strtoul(argv[2], NULL, 0); + ioctl(fd, TRACE_SET_MASK, mask); + } else if (argc == 3 && strcmp(argv[1], "dump") == 0) { /* 3, argv num, no special meaning */ + size_t flag = strtoul(argv[2], NULL, 0); + ioctl(fd, TRACE_DUMP, flag); + } else if (argc == 3 && strcmp(argv[1], "read") == 0) { /* 3, argv num, no special meaning */ + size_t size = strtoul(argv[2], NULL, 0); + TraceRead(fd, size); + } else if (argc >= 4 && strcmp(argv[1], "write") == 0) { /* 4, argv num, no special meaning */ + TraceWrite(fd, argc, argv); + } else { + printf("Unsupported trace command.\n"); + TraceUsage(); + } + + close(fd); + return 0; +} diff --git a/src/kernel_liteos_a/arch/BUILD.gn b/src/kernel_liteos_a/arch/BUILD.gn new file mode 100644 index 00000000..75517815 --- /dev/null +++ b/src/kernel_liteos_a/arch/BUILD.gn @@ -0,0 +1,44 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +group("arch") { + deps = [] + if (defined(LOSCFG_ARCH_ARM)) { + deps += [ "arm" ] + } +} + +config("public") { + configs = [] + if (defined(LOSCFG_ARCH_ARM)) { + configs += [ "arm:public" ] + } +} diff --git a/src/kernel_liteos_a/arch/Kconfig b/src/kernel_liteos_a/arch/Kconfig new file mode 100644 index 00000000..9e58fe4a --- /dev/null +++ b/src/kernel_liteos_a/arch/Kconfig @@ -0,0 +1,33 @@ +config ARCH_ARM + bool + +source "arch/arm/Kconfig" + +comment "Extra Configurations" + +config ARCH_FPU_DISABLE + bool "Disable Floating Pointer Unit" + default n + help + This option will bypass floating procedure in system. + +config ARCH_SECURE_MONITOR_MODE + bool "Run On Secure Monitor Mode" + default n + depends on ARCH_ARM_AARCH64 + help + This option will make the system run on EL3. + +config ARCH_INTERRUPT_PREEMPTION + bool "Enable Interrupt Preemption" + default n + depends on ARCH_ARM_AARCH64 + help + This option will support high priority interrupt preemption. + +config IRQ_USE_STANDALONE_STACK + bool "Use Interrupt Stack" + default y + depends on ARCH_ARM_AARCH64 || ARCH_ARM_AARCH32 + help + This option will support using standalone interrupt stack. diff --git a/src/kernel_liteos_a/arch/arm/BUILD.gn b/src/kernel_liteos_a/arch/arm/BUILD.gn new file mode 100644 index 00000000..257b1830 --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/BUILD.gn @@ -0,0 +1,40 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +group("arm") { + deps = [ "gic" ] + deps += [ ARCH ] +} + +config("public") { + include_dirs = [ "include" ] + configs = [ "$ARCH:public" ] +} diff --git a/src/kernel_liteos_a/arch/arm/Kconfig b/src/kernel_liteos_a/arch/arm/Kconfig new file mode 100644 index 00000000..f87fa49c --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/Kconfig @@ -0,0 +1,103 @@ +# ARM Architecture + +# +# ARM has 32-bit(Aarch32) and 64-bit(Aarch64) implementations +# +config ARCH_ARM_AARCH32 + bool + select ARCH_ARM + help + 32-bit ARM architecture implementations, Except the M-profile. + It is not limited to ARMv7-A but also ARMv7-R, ARMv8-A 32-bit and etc. + +# +# Architecture Versions +# +config ARCH_ARM_V7A + bool + +config ARCH_ARM_VER + string + default "armv7-a" if ARCH_ARM_V7A + +# +# VFP Hardware +# +config ARCH_FPU_VFP_V3 + bool + help + An optional extension to the Arm, Thumb, and ThumbEE instruction sets in the ARMv7-A and ARMv7-R profiles. + VFPv3U is a variant of VFPv3 that supports the trapping of floating-point exceptions to support code. + +config ARCH_FPU_VFP_V4 + bool + help + An optional extension to the Arm, Thumb, and ThumbEE instruction sets in the ARMv7-A and ARMv7-R profiles. + VFPv4U is a variant of VFPv4 that supports the trapping of floating-point exceptions to support code. + VFPv4 and VFPv4U add both the Half-precision Extension and the fused multiply-add instructions to the features of VFPv3. + +config ARCH_FPU_VFP_D16 + bool + depends on ARCH_ARM_AARCH32 + help + VPU implemented with 16 doubleword registers (16 x 64-bit). + +config ARCH_FPU_VFP_D32 + bool + depends on ARCH_ARM_AARCH32 + help + VPU implemented with 32 doubleword registers (32 x 64-bit). + +config ARCH_FPU_VFP_NEON + bool + help + Advanced SIMD extension (NEON) support. + +config ARCH_FPU + string + default "vfpv3" if ARCH_FPU_VFP_V3 && ARCH_FPU_VFP_D32 + default "vfpv3-d16" if ARCH_FPU_VFP_V3 && ARCH_FPU_VFP_D16 + default "neon-vfpv4" if ARCH_FPU_VFP_V4 && ARCH_FPU_VFP_D32 && ARCH_FPU_VFP_NEON + default "vfpv4" if ARCH_FPU_VFP_V4 && ARCH_FPU_VFP_D32 + default "vfpv4-d16" if ARCH_FPU_VFP_V4 && ARCH_FPU_VFP_D16 + +# +# Supported Processor Cores +# +config ARCH_CORTEX_A7 + bool + select ARCH_ARM_V7A + select ARCH_ARM_AARCH32 + select ARCH_FPU_VFP_V4 + select ARCH_FPU_VFP_D32 + select ARCH_FPU_VFP_NEON + +config ARCH_CPU + string + default "cortex-a7" if ARCH_CORTEX_A7 + +# +# Supported GIC version +# + +choice + prompt "GIC version" + default ARCH_GIC_V2 + help + Interrupt Controller. + +config ARCH_GIC_V2 + bool "GIC Version 2" + help + This GIC(General Interrupt Controller) version 2 driver is compatatble with + GIC version 1 and version 2. + +config ARCH_GIC_V3 + bool "GIC Version 3" + depends on ARCH_ARM_V8A || ARCH_ARM_V8R + help + General Interrupt Controller version 3. + +endchoice + + diff --git a/src/kernel_liteos_a/arch/arm/arm.mk b/src/kernel_liteos_a/arch/arm/arm.mk new file mode 100644 index 00000000..248ef5ee --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm.mk @@ -0,0 +1,76 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# strip quotation mark in configuration + +LOSCFG_ARCH_CPU_STRIP := $(subst $\",,$(LOSCFG_ARCH_CPU)) +LOSCFG_ARCH_CPU = $(LOSCFG_ARCH_CPU_STRIP) + +LOSCFG_ARCH_FPU_STRIP := $(subst $\",,$(LOSCFG_ARCH_FPU)) +LOSCFG_ARCH_FPU = $(LOSCFG_ARCH_FPU_STRIP) + +ifeq ($(LOSCFG_ARCH_ARM_AARCH32), y) +ARCH := arm +else ifeq ($(LOSCFG_ARCH_ARM_AARCH64), y) +ARCH := aarch64 +endif + +LITEOS_BASELIB += -l$(LOSCFG_ARCH_CPU) +LITEOS_BASELIB += -lgic + +LIB_SUBDIRS += arch/arm/$(ARCH) +LIB_SUBDIRS += arch/arm/gic + +# CPU compile options +ifeq ($(LOSCFG_ARCH_ARM_AARCH64), y) +ifeq ($(LOSCFG_ARCH_FPU_DISABLE), y) +EXTENSION := +nofp +endif +endif +LITEOS_CPU_OPTS := -mcpu=$(LOSCFG_ARCH_CPU)$(EXTENSION) + +# FPU compile options +# -mfloat and -mfpu is ignored with AArch64 targets +ifeq ($(LOSCFG_ARCH_ARM_AARCH32), y) +LITEOS_FLOAT_OPTS := -mfloat-abi=softfp +LITEOS_FPU_OPTS := -mfpu=$(LOSCFG_ARCH_FPU) +# gcc libc folder style is combine with core and fpu +# for example, cortex-a7 with softfp abi and neon vfp4 is: a7_softfp_neon_vfp4 +LITEOS_GCCLIB := $(subst cortex-,,$(LOSCFG_ARCH_CPU))_softfp_$(LOSCFG_ARCH_FPU) +endif + +LITEOS_CORE_COPTS = $(or $(ARCH_CFLAGS),$(LITEOS_CPU_OPTS) $(LITEOS_FLOAT_OPTS) $(LITEOS_FPU_OPTS)) +LITEOS_ASOPTS += $(LITEOS_CPU_OPTS) +LITEOS_CXXOPTS_BASE += $(LITEOS_CORE_COPTS) + +ARCH_INCLUDE := -I $(LITEOSTOPDIR)/arch/arm/include \ + -I $(LITEOSTOPDIR)/arch/arm/$(ARCH)/include \ + -I $(LITEOSTOPDIR)/arch/arm/$(ARCH)/src/include + +LITEOS_PLATFORM_INCLUDE += $(ARCH_INCLUDE) diff --git a/src/kernel_liteos_a/arch/arm/arm/BUILD.gn b/src/kernel_liteos_a/arch/arm/arm/BUILD.gn new file mode 100644 index 00000000..260544f6 --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/BUILD.gn @@ -0,0 +1,96 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_name = LOSCFG_ARCH_CPU +kernel_module(module_name) { + sources = [ + "src/arm_generic_timer.c", + "src/clear_user.S", + "src/hw_user_get.S", + "src/hw_user_put.S", + "src/jmp.S", + "src/los_arch_mmu.c", + "src/los_asid.c", + "src/los_dispatch.S", + "src/los_exc.c", + "src/los_hw.c", + "src/los_hw_exc.S", + "src/los_hw_runstop.S", + "src/los_hw_tick.c", + "src/los_hwi.c", + "src/smp.c", + "src/strncpy_from_user.c", + "src/strnlen_user.c", + "src/user_copy.c", + ] + + if (LOSCFG_ARCH_ARM_VER == "armv7-a") { + sources += [ "src/armv7a/cache.S" ] + } + + if (defined(LOSCFG_KERNEL_SMP)) { + sources += [ "src/startup/reset_vector_mp.S" ] + } else { + sources += [ "src/startup/reset_vector_up.S" ] + } + + include_dirs = [ "src/include" ] + + if (defined(LOSCFG_PERF_HW_PMU)) { + sources += [ "src/pmu/armv7_pmu.c" ] + } + + if (defined(LOSCFG_GDB)) { + configs += [ ":as_objs_libc_flags" ] + } + + public_configs = [ ":public" ] +} + +config("public") { + include_dirs = [ + "include", + "src/include", + ] +} + +config("as_objs_libc_flags") { + defines = [ "__ASSEMBLY__" ] + + # linux style macros + if (defined(LOSCFG_ARCH_ARM_V7A) || defined(LOSCFG_ARCH_ARM_V7R) || + defined(LOSCFG_ARCH_ARM_V7M)) { + defines += [ "__LINUX_ARM_ARCH__=7" ] + } else if (defined(LOSCFG_ARCH_ARM_V8A) || defined(LOSCFG_ARCH_ARM_V8R) || + defined(LOSCFG_ARCH_ARM_V8M)) { + defines += [ "__LINUX_ARM_ARCH__=8" ] + } +} diff --git a/src/kernel_liteos_a/arch/arm/arm/Makefile b/src/kernel_liteos_a/arch/arm/arm/Makefile new file mode 100644 index 00000000..52f8b55b --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/Makefile @@ -0,0 +1,65 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(LOSCFG_ARCH_CPU) + +LOCAL_SRCS := $(wildcard src/*.c) $(wildcard src/*.S) + +ifeq ($(LOSCFG_ARCH_ARM_VER), "armv7-a") +LOCAL_SRCS += $(wildcard src/armv7a/*.S) +endif + +ifeq ($(LOSCFG_KERNEL_SMP), y) +LOCAL_SRCS += src/startup/reset_vector_mp.S +else +LOCAL_SRCS += src/startup/reset_vector_up.S +endif + +ifeq ($(LOSCFG_PERF_HW_PMU), y) +LOCAL_SRCS += src/pmu/armv7_pmu.c +endif + +LOCAL_FLAGS := $(LOCAL_INCLUDE) + +AS_OBJS_LIBC_FLAGS = -D__ASSEMBLY__ +# linux style macros +LINUX_ARCH_$(LOSCFG_ARCH_ARM_V7A) = -D__LINUX_ARM_ARCH__=7 +LINUX_ARCH_$(LOSCFG_ARCH_ARM_V7R) = -D__LINUX_ARM_ARCH__=7 +LINUX_ARCH_$(LOSCFG_ARCH_ARM_V7M) = -D__LINUX_ARM_ARCH__=7 +LINUX_ARCH_$(LOSCFG_ARCH_ARM_V8A) = -D__LINUX_ARM_ARCH__=8 +LINUX_ARCH_$(LOSCFG_ARCH_ARM_V8R) = -D__LINUX_ARM_ARCH__=8 +LINUX_ARCH_$(LOSCFG_ARCH_ARM_V8M) = -D__LINUX_ARM_ARCH__=8 +AS_OBJS_LIBC_FLAGS += $(LINUX_ARCH_y) + +ifeq ($(LOSCFG_GDB), y) +LOCAL_FLAGS += $(AS_OBJS_LIBC_FLAGS) +endif +include $(MODULE) diff --git a/src/kernel_liteos_a/arch/arm/arm/include/arch_config.h b/src/kernel_liteos_a/arch/arm/arm/include/arch_config.h new file mode 100644 index 00000000..56aa7558 --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/include/arch_config.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _ARCH_CONFIG_H +#define _ARCH_CONFIG_H + + +#define CPSR_INT_DISABLE 0xC0 /* Disable both FIQ and IRQ */ +#define CPSR_IRQ_DISABLE 0x80 /* IRQ disabled when =1 */ +#define CPSR_FIQ_DISABLE 0x40 /* FIQ disabled when =1 */ +#define CPSR_THUMB_ENABLE 0x20 /* Thumb mode when =1 */ +#define CPSR_USER_MODE 0x10 +#define CPSR_FIQ_MODE 0x11 +#define CPSR_IRQ_MODE 0x12 +#define CPSR_SVC_MODE 0x13 +#define CPSR_ABT_MODE 0x17 +#define CPSR_UNDEF_MODE 0x1B +#define CPSR_MASK_MODE 0x1F + +/* Define exception type ID */ +#define OS_EXCEPT_RESET 0x00 +#define OS_EXCEPT_UNDEF_INSTR 0x01 +#define OS_EXCEPT_SWI 0x02 +#define OS_EXCEPT_PREFETCH_ABORT 0x03 +#define OS_EXCEPT_DATA_ABORT 0x04 +#define OS_EXCEPT_FIQ 0x05 +#define OS_EXCEPT_ADDR_ABORT 0x06 +#define OS_EXCEPT_IRQ 0x07 + +/* Define core num */ +#ifdef LOSCFG_KERNEL_SMP +#define CORE_NUM LOSCFG_KERNEL_SMP_CORE_NUM +#else +#define CORE_NUM 1 +#endif + +/* Initial bit32 stack value. */ +#define OS_STACK_INIT 0xCACACACA +/* Bit32 stack top magic number. */ +#define OS_STACK_MAGIC_WORD 0xCCCCCCCC + +#ifdef LOSCFG_GDB +#define OS_EXC_UNDEF_STACK_SIZE 512 +#define OS_EXC_ABT_STACK_SIZE 512 +#else +#define OS_EXC_UNDEF_STACK_SIZE 40 +#define OS_EXC_ABT_STACK_SIZE 40 +#endif +#define OS_EXC_FIQ_STACK_SIZE 64 +#define OS_EXC_IRQ_STACK_SIZE 64 +#define OS_EXC_SVC_STACK_SIZE 0x2000 +#define OS_EXC_STACK_SIZE 0x1000 + +#define REG_R0 0 +#define REG_R1 1 +#define REG_R2 2 +#define REG_R3 3 +#define REG_R4 4 +#define REG_R5 5 +#define REG_R6 6 +#define REG_R7 7 +#define REG_R8 8 +#define REG_R9 9 +#define REG_R10 10 +#define REG_R11 11 +#define REG_R12 12 +#define REG_R13 13 +#define REG_R14 14 +#define REG_R15 15 +#define REG_CPSR 16 +#define REG_SP REG_R13 +#define REG_LR REG_R14 +#define REG_PC REG_R15 +#endif \ No newline at end of file diff --git a/src/kernel_liteos_a/arch/arm/arm/include/arm.h b/src/kernel_liteos_a/arch/arm/arm/include/arm.h new file mode 100644 index 00000000..9d8aeb6a --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/include/arm.h @@ -0,0 +1,1131 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef __LOS_ARM_H__ +#define __LOS_ARM_H__ + +#define CPSR_MODE_USR 0x10 +#define CPSR_MODE_MASK 0x1f + +STATIC INLINE UINT32 OsArmReadSctlr(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c1,c0,0" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteSctlr(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c1,c0,0" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadActlr(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c1,c0,1" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteActlr(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c1,c0,1" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadCpacr(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c1,c0,2" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteCpacr(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c1,c0,2" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadTtbr(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c2,c0,0" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteTtbr(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c2,c0,0" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadTtbr0(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c2,c0,0" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteTtbr0(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c2,c0,0" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadTtbr1(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c2,c0,1" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteTtbr1(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c2,c0,1" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadTtbcr(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c2,c0,2" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteTtbcr(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c2,c0,2" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadDacr(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c3,c0,0" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteDacr(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c3,c0,0" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadDfsr(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c5,c0,0" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteDfsr(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c5,c0,0" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadIfsr(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c5,c0,1" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteIfsr(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c5,c0,1" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadDfar(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c6,c0,0" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteDfar(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c6,c0,0" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadWfar(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c6,c0,1" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteWfar(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c6,c0,1" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadIfar(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c6,c0,2" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteIfar(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c6,c0,2" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadFcseidr(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c13,c0,0" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteFcseidr(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c13,c0,0" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadContextidr(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c13,c0,1" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteContextidr(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c13,c0,1" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadTpidrurw(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c13,c0,2" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteTpidrurw(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c13,c0,2" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadTpidruro(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c13,c0,3" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteTpidruro(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c13,c0,3" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadTpidrprw(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c13,c0,4" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteTpidrprw(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c13,c0,4" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadMidr(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c0,c0,0" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteMidr(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c0,c0,0" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadMpidr(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c0,c0,5" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteMpidr(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c0,c0,5" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadVbar(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c12,c0,0" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteVbar(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c12,c0,0" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadCbar(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 4, %0, c15,c0,0" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteCbar(UINT32 val) +{ + __asm__ volatile("mcr p15, 4, %0, c15,c0,0" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadAts1cpr(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c7,c8,0" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteAts1cpr(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c7,c8,0" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadAts1cpw(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c7,c8,1" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteAts1cpw(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c7,c8,1" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadAts1cur(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c7,c8,2" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteAts1cur(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c7,c8,2" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadAts1cuw(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c7,c8,3" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteAts1cuw(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c7,c8,3" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadAts12nsopr(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c7,c8,4" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteAts12nsopr(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c7,c8,4" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadAts12nsopw(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c7,c8,5" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteAts12nsopw(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c7,c8,5" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadAts12nsour(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c7,c8,6" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteAts12nsour(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c7,c8,6" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadAts12nsouw(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c7,c8,7" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteAts12nsouw(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c7,c8,7" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadPar(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c7,c4,0" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWritePar(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c7,c4,0" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadBpiall(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c7,c5,6" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteBpiall(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c7,c5,6" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadBpimva(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c7,c5,7" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteBpimva(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c7,c5,7" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadBpiallis(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c7,c1,6" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteBpiallis(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c7,c1,6" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadTlbiallis(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c8,c3,0" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteTlbiallis(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c8,c3,0" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadTlbimvais(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c8,c3,1" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteTlbimvais(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c8,c3,1" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadTlbiasidis(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c8,c3,2" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteTlbiasidis(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c8,c3,2" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadTlbimvaais(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c8,c3,3" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteTlbimvaais(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c8,c3,3" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadItlbiall(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c8,c5,0" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteItlbiall(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c8,c5,0" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadItlbimva(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c8,c5,1" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteItlbimva(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c8,c5,1" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadItlbiasid(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c8,c5,2" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteItlbiasid(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c8,c5,2" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadDtlbiall(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c8,c6,0" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteDtlbiall(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c8,c6,0" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadDtlbimva(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c8,c6,1" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteDtlbimva(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c8,c6,1" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadDtlbiasid(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c8,c6,2" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteDtlbiasid(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c8,c6,2" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadTlbiall(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c8,c7,0" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteTlbiall(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c8,c7,0" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadTlbimva(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c8,c7,1" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteTlbimva(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c8,c7,1" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadTlbiasid(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c8,c7,2" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteTlbiasid(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c8,c7,2" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadTlbimvaa(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 0, %0, c8,c7,3" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteTlbimvaa(UINT32 val) +{ + __asm__ volatile("mcr p15, 0, %0, c8,c7,3" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadL2ctlr(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 1, %0, c9,c0,2" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteL2ctlr(UINT32 val) +{ + __asm__ volatile("mcr p15, 1, %0, c9,c0,2" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadL2ectlr(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p15, 1, %0, c9,c0,3" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteL2ectlr(UINT32 val) +{ + __asm__ volatile("mcr p15, 1, %0, c9,c0,3" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadDbddidr(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p14, 0, %0, c0,c0,0" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteDbddidr(UINT32 val) +{ + __asm__ volatile("mcr p14, 0, %0, c0,c0,0" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadDbgdrar(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p14, 0, %0, c1,c0,0" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteDbgdrar(UINT32 val) +{ + __asm__ volatile("mcr p14, 0, %0, c1,c0,0" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadDbgdsar(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p14, 0, %0, c2,c0,0" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteDbgdsar(UINT32 val) +{ + __asm__ volatile("mcr p14, 0, %0, c2,c0,0" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadDbgdscr(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p14, 0, %0, c0,c1,0" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteDbgdscr(UINT32 val) +{ + __asm__ volatile("mcr p14, 0, %0, c0,c1,0" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadDbgdtrtxint(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p14, 0, %0, c0,c5,0" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteDbgdtrtxint(UINT32 val) +{ + __asm__ volatile("mcr p14, 0, %0, c0,c5,0" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadDbgdtrrxint(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p14, 0, %0, c0,c5,0" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteDbgdtrrxint(UINT32 val) +{ + __asm__ volatile("mcr p14, 0, %0, c0,c5,0" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadDbgwfar(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p14, 0, %0, c0,c6,0" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteDbgwfar(UINT32 val) +{ + __asm__ volatile("mcr p14, 0, %0, c0,c6,0" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadDbgvcr(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p14, 0, %0, c0,c7,0" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteDbgvcr(UINT32 val) +{ + __asm__ volatile("mcr p14, 0, %0, c0,c7,0" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadDbgecr(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p14, 0, %0, c0,c9,0" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteDbgecr(UINT32 val) +{ + __asm__ volatile("mcr p14, 0, %0, c0,c9,0" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadDbgdsccr(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p14, 0, %0, c0,c10,0" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteDbgdsccr(UINT32 val) +{ + __asm__ volatile("mcr p14, 0, %0, c0,c10,0" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadDbgdsmcr(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p14, 0, %0, c0,c11,0" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteDbgdsmcr(UINT32 val) +{ + __asm__ volatile("mcr p14, 0, %0, c0,c11,0" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadDbgdtrrxext(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p14, 0, %0, c0,c0,2" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteDbgdtrrxext(UINT32 val) +{ + __asm__ volatile("mcr p14, 0, %0, c0,c0,2" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadDbgdscrext(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p14, 0, %0, c0,c2,2" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteDbgdscrext(UINT32 val) +{ + __asm__ volatile("mcr p14, 0, %0, c0,c2,2" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadDbgdtrtxext(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p14, 0, %0, c0,c3,2" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteDbgdtrtxext(UINT32 val) +{ + __asm__ volatile("mcr p14, 0, %0, c0,c3,2" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadDbgdrcr(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p14, 0, %0, c0,c4,2" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteDbgdrcr(UINT32 val) +{ + __asm__ volatile("mcr p14, 0, %0, c0,c4,2" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadDbgvr0(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p14, 0, %0, c0,c0,4" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteDbgvr0(UINT32 val) +{ + __asm__ volatile("mcr p14, 0, %0, c0,c0,4" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadDbgvr1(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p14, 0, %0, c0,c1,4" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteDbgvr1(UINT32 val) +{ + __asm__ volatile("mcr p14, 0, %0, c0,c1,4" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadDbgvr2(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p14, 0, %0, c0,c2,4" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteDbgvr2(UINT32 val) +{ + __asm__ volatile("mcr p14, 0, %0, c0,c2,4" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadDbgbcr0(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p14, 0, %0, c0,c0,5" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteDbgbcr0(UINT32 val) +{ + __asm__ volatile("mcr p14, 0, %0, c0,c0,5" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadDbgbcr1(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p14, 0, %0, c0,c1,5" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteDbgbcr1(UINT32 val) +{ + __asm__ volatile("mcr p14, 0, %0, c0,c1,5" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadDbgbcr2(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p14, 0, %0, c0,c2,5" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteDbgbcr2(UINT32 val) +{ + __asm__ volatile("mcr p14, 0, %0, c0,c2,5" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadDbgwvr0(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p14, 0, %0, c0,c0,6" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteDbgwvr0(UINT32 val) +{ + __asm__ volatile("mcr p14, 0, %0, c0,c0,6" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadDbgwvr1(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p14, 0, %0, c0,c1,6" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteDbgwvr1(UINT32 val) +{ + __asm__ volatile("mcr p14, 0, %0, c0,c1,6" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadDbgwcr0(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p14, 0, %0, c0,c0,7" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteDbgwcr0(UINT32 val) +{ + __asm__ volatile("mcr p14, 0, %0, c0,c0,7" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadDbgwcr1(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p14, 0, %0, c0,c1,7" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteDbgwcr1(UINT32 val) +{ + __asm__ volatile("mcr p14, 0, %0, c0,c1,7" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadDbgoslar(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p14, 0, %0, c1,c0,4" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteDbgoslar(UINT32 val) +{ + __asm__ volatile("mcr p14, 0, %0, c1,c0,4" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadDbgoslsr(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p14, 0, %0, c1,c1,4" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteDbgoslsr(UINT32 val) +{ + __asm__ volatile("mcr p14, 0, %0, c1,c1,4" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadDbgossrr(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p14, 0, %0, c1,c2,4" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteDbgossrr(UINT32 val) +{ + __asm__ volatile("mcr p14, 0, %0, c1,c2,4" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadDbgprcr(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p14, 0, %0, c1,c4,4" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteDbgprcr(UINT32 val) +{ + __asm__ volatile("mcr p14, 0, %0, c1,c4,4" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadDbgprsr(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p14, 0, %0, c1,c5,4" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteDbgprsr(UINT32 val) +{ + __asm__ volatile("mcr p14, 0, %0, c1,c5,4" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadDbgclaimset(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p14, 0, %0, c7,c8,6" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteDbgclaimset(UINT32 val) +{ + __asm__ volatile("mcr p14, 0, %0, c7,c8,6" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadDbgclaimclr(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p14, 0, %0, c7,c9,6" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteDbgclaimclr(UINT32 val) +{ + __asm__ volatile("mcr p14, 0, %0, c7,c9,6" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadDbgauthstatus(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p14, 0, %0, c7,c14,6" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteDbgauthstatus(UINT32 val) +{ + __asm__ volatile("mcr p14, 0, %0, c7,c14,6" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +STATIC INLINE UINT32 OsArmReadDbgdevid(VOID) +{ + UINT32 val; + __asm__ volatile("mrc p14, 0, %0, c7,c2,7" : "=r"(val)); + return val; +} + +STATIC INLINE VOID OsArmWriteDbgdevid(UINT32 val) +{ + __asm__ volatile("mcr p14, 0, %0, c7,c2,7" ::"r"(val)); + __asm__ volatile("isb" ::: "memory"); +} + +#endif /* __LOS_ARM_H__ */ diff --git a/src/kernel_liteos_a/arch/arm/arm/include/arm_user_clear.h b/src/kernel_liteos_a/arch/arm/arm/include/arm_user_clear.h new file mode 100644 index 00000000..d808208a --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/include/arm_user_clear.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _ARM_USER_CLEAR_H +#define _ARM_USER_CLEAR_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +size_t _arm_clear_user(void *addr, size_t bytes); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _ARM_USER_CLEAR_H */ diff --git a/src/kernel_liteos_a/arch/arm/arm/include/arm_user_copy.h b/src/kernel_liteos_a/arch/arm/arm/include/arm_user_copy.h new file mode 100644 index 00000000..b86e37c4 --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/include/arm_user_copy.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_typedef.h" +#pragma once + +size_t _arm_user_copy(void *dst, const void *src, size_t len); + diff --git a/src/kernel_liteos_a/arch/arm/arm/include/arm_user_get.h b/src/kernel_liteos_a/arch/arm/arm/include/arm_user_get.h new file mode 100644 index 00000000..2f4a67ef --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/include/arm_user_get.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _ARM_USER_GET_H +#define _ARM_USER_GET_H + +#include "los_typedef.h" +#include "securec.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +errno_t _arm_get_user(void *dst, const void *src, size_t dstTypeLen, size_t srcTypeLen); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _ARM_USER_GET_H */ diff --git a/src/kernel_liteos_a/arch/arm/arm/include/arm_user_put.h b/src/kernel_liteos_a/arch/arm/arm/include/arm_user_put.h new file mode 100644 index 00000000..28b04f46 --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/include/arm_user_put.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _ARM_USER_PUT_H +#define _ARM_USER_PUT_H + +#include "los_typedef.h" +#include "securec.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +errno_t _arm_put_user(void *dst, const void *src, size_t dstTypeLen, size_t srcTypeLen); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _ARM_USER_PUT_H */ diff --git a/src/kernel_liteos_a/arch/arm/arm/include/hal_timer.h b/src/kernel_liteos_a/arch/arm/arm/include/hal_timer.h new file mode 100644 index 00000000..667188bc --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/include/hal_timer.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_TIMER_H +#define _LOS_TIMER_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +extern UINT32 HalClockFreqRead(VOID); +extern VOID HalClockFreqWrite(UINT32 freq); +extern VOID HalClockStart(VOID); +extern VOID HalClockIrqClear(VOID); +extern VOID HalClockInit(VOID); +extern UINT64 HalClockGetCycles(VOID); +extern VOID HalDelayUs(UINT32 usecs); +extern UINT32 HalClockGetTickTimerCycles(VOID); +extern UINT64 HalClockTickTimerReload(UINT64 cycles); + +extern UINT32 HrtimersInit(VOID); +extern VOID HrtimerClockIrqClear(VOID); +extern VOID HrtimerClockStart(UINT32 period); +extern VOID HrtimerClockStop(VOID); +extern UINT32 HrtimerClockValueGet(VOID); +extern VOID HrtimerClockInit(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_TIMER_H */ diff --git a/src/kernel_liteos_a/arch/arm/arm/include/los_arch_mmu.h b/src/kernel_liteos_a/arch/arm/arm/include/los_arch_mmu.h new file mode 100644 index 00000000..afb0ab93 --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/include/los_arch_mmu.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_arch_mmu architecture mmu + * @ingroup kernel + */ + +#ifndef __LOS_ARCH_MMU_H__ +#define __LOS_ARCH_MMU_H__ + +#include "los_typedef.h" +#include "los_vm_phys.h" +#ifndef LOSCFG_PAGE_TABLE_FINE_LOCK +#include "los_spinlock.h" +#endif + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef struct ArchMmu { +#ifndef LOSCFG_PAGE_TABLE_FINE_LOCK + SPIN_LOCK_S lock; /**< arch mmu page table entry modification spin lock */ +#endif + VADDR_T *virtTtb; /**< translation table base virtual addr */ + PADDR_T physTtb; /**< translation table base phys addr */ + UINT32 asid; /**< TLB asid */ + LOS_DL_LIST ptList; /**< page table vm page list */ +} LosArchMmu; + +BOOL OsArchMmuInit(LosArchMmu *archMmu, VADDR_T *virtTtb); +STATUS_T LOS_ArchMmuQuery(const LosArchMmu *archMmu, VADDR_T vaddr, PADDR_T *paddr, UINT32 *flags); +STATUS_T LOS_ArchMmuUnmap(LosArchMmu *archMmu, VADDR_T vaddr, size_t count); +STATUS_T LOS_ArchMmuMap(LosArchMmu *archMmu, VADDR_T vaddr, PADDR_T paddr, size_t count, UINT32 flags); +STATUS_T LOS_ArchMmuChangeProt(LosArchMmu *archMmu, VADDR_T vaddr, size_t count, UINT32 flags); +STATUS_T LOS_ArchMmuMove(LosArchMmu *archMmu, VADDR_T oldVaddr, VADDR_T newVaddr, size_t count, UINT32 flags); +VOID LOS_ArchMmuContextSwitch(LosArchMmu *archMmu); +STATUS_T LOS_ArchMmuDestroy(LosArchMmu *archMmu); +VOID OsArchMmuInitPerCPU(VOID); +VADDR_T *OsGFirstTableGet(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* __LOS_ARCH_MMU_H__ */ + diff --git a/src/kernel_liteos_a/arch/arm/arm/include/los_asid.h b/src/kernel_liteos_a/arch/arm/arm/include/los_asid.h new file mode 100644 index 00000000..613982db --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/include/los_asid.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_asid mmu address space id + * @ingroup kernel + */ + +#ifndef __LOS_ASID_H__ +#define __LOS_ASID_H__ + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define MMU_ARM_ASID_BITS 8 + +/* allocate and free asid */ +STATUS_T OsAllocAsid(UINT32 *asid); +VOID OsFreeAsid(UINT32 asid); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* __LOS_VM_PAGE_H__ */ + diff --git a/src/kernel_liteos_a/arch/arm/arm/include/los_atomic.h b/src/kernel_liteos_a/arch/arm/arm/include/los_atomic.h new file mode 100644 index 00000000..6d79cf94 --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/include/los_atomic.h @@ -0,0 +1,892 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_atomic Atomic + * @ingroup kernel + */ + +#ifndef __LOS_ATOMIC_H__ +#define __LOS_ATOMIC_H__ + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef volatile INT32 Atomic; +typedef volatile INT64 Atomic64; + +/** + * @ingroup los_atomic + * @brief Atomic read. + * + * @par Description: + * This API is used to implement the atomic read and return the result value of the read. + * @attention + *
            + *
          • The pointer v must not be NULL.
          • + *
          + * + * @param v [IN] The reading pointer. + * + * @retval #INT32 The result value of the read. + * @par Dependency: + *
          • los_atomic.h: the header file that contains the API declaration.
          + * @see + */ +STATIC INLINE INT32 LOS_AtomicRead(const Atomic *v) +{ + return *(volatile INT32 *)v; +} + +/** + * @ingroup los_atomic + * @brief Atomic setting. + * + * @par Description: + * This API is used to implement the atomic setting operation. + * @attention + *
            + *
          • The pointer v must not be NULL.
          • + *
          + * + * @param v [IN] The variable pointer to be setting. + * @param setVal [IN] The value to be setting. + * + * @retval none. + * @par Dependency: + *
          • los_atomic.h: the header file that contains the API declaration.
          + * @see + */ +STATIC INLINE VOID LOS_AtomicSet(Atomic *v, INT32 setVal) +{ + *(volatile INT32 *)v = setVal; +} + +/** + * @ingroup los_atomic + * @brief Atomic addition. + * + * @par Description: + * This API is used to implement the atomic addition and return the result value of the augend. + * @attention + *
            + *
          • The pointer v must not be NULL.
          • + *
          • If the addtion result is not in the range of representable values for 32-bit signed integer, + * an int integer overflow may occur to the return value
          • + *
          + * + * @param v [IN] The augend pointer. + * @param addVal [IN] The addend. + * + * @retval #INT32 The result value of the augend. + * @par Dependency: + *
          • los_atomic.h: the header file that contains the API declaration.
          + * @see + */ +STATIC INLINE INT32 LOS_AtomicAdd(Atomic *v, INT32 addVal) +{ + INT32 val; + UINT32 status; + + do { + __asm__ __volatile__("ldrex %1, [%2]\n" + "add %1, %1, %3\n" + "strex %0, %1, [%2]" + : "=&r"(status), "=&r"(val) + : "r"(v), "r"(addVal) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return val; +} + +/** + * @ingroup los_atomic + * @brief Atomic subtraction. + * + * @par Description: + * This API is used to implement the atomic subtraction and return the result value of the minuend. + * @attention + *
            + *
          • The pointer v must not be NULL.
          • + *
          • If the subtraction result is not in the range of representable values for 32-bit signed integer, + * an int integer overflow may occur to the return value
          • + *
          + * + * @param v [IN] The minuend pointer. + * @param subVal [IN] The subtrahend. + * + * @retval #INT32 The result value of the minuend. + * @par Dependency: + *
          • los_atomic.h: the header file that contains the API declaration.
          + * @see + */ +STATIC INLINE INT32 LOS_AtomicSub(Atomic *v, INT32 subVal) +{ + INT32 val; + UINT32 status; + + do { + __asm__ __volatile__("ldrex %1, [%2]\n" + "sub %1, %1, %3\n" + "strex %0, %1, [%2]" + : "=&r"(status), "=&r"(val) + : "r"(v), "r"(subVal) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return val; +} + +/** + * @ingroup los_atomic + * @brief Atomic addSelf. + * + * @par Description: + * This API is used to implement the atomic addSelf. + * @attention + *
            + *
          • The pointer v must not be NULL.
          • + *
          • The value which v point to must not be INT_MAX to avoid integer overflow after adding 1.
          • + *
          + * + * @param v [IN] The addSelf variable pointer. + * + * @retval none. + * @par Dependency: + *
          • los_atomic.h: the header file that contains the API declaration.
          + * @see + */ +STATIC INLINE VOID LOS_AtomicInc(Atomic *v) +{ + INT32 val; + UINT32 status; + + do { + __asm__ __volatile__("ldrex %0, [%3]\n" + "add %0, %0, #1\n" + "strex %1, %0, [%3]" + : "=&r"(val), "=&r"(status), "+m"(*v) + : "r"(v) + : "cc"); + } while (__builtin_expect(status != 0, 0)); +} + +/** + * @ingroup los_atomic + * @brief Atomic addSelf. + * + * @par Description: + * This API is used to implement the atomic addSelf and return the result of addSelf. + * @attention + *
            + *
          • The pointer v must not be NULL.
          • + *
          • The value which v point to must not be INT_MAX to avoid integer overflow after adding 1.
          • + *
          + * + * @param v [IN] The addSelf variable pointer. + * + * @retval #INT32 The return value of variable addSelf. + * @par Dependency: + *
          • los_atomic.h: the header file that contains the API declaration.
          + * @see + */ +STATIC INLINE INT32 LOS_AtomicIncRet(Atomic *v) +{ + INT32 val; + UINT32 status; + + do { + __asm__ __volatile__("ldrex %0, [%3]\n" + "add %0, %0, #1\n" + "strex %1, %0, [%3]" + : "=&r"(val), "=&r"(status), "+m"(*v) + : "r"(v) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return val; +} + +/** + * @ingroup los_atomic + * @brief Atomic auto-decrement. + * + * @par Description: + * This API is used to implement the atomic auto-decrement. + * @attention + *
            + *
          • The pointer v must not be NULL.
          • + *
          • The value which v point to must not be INT_MIN to avoid overflow after reducing 1.
          • + *
          + * + * @param v [IN] The auto-decrement variable pointer. + * + * @retval none. + * @par Dependency: + *
          • los_atomic.h: the header file that contains the API declaration.
          + * @see + */ +STATIC INLINE VOID LOS_AtomicDec(Atomic *v) +{ + INT32 val; + UINT32 status; + + do { + __asm__ __volatile__("ldrex %0, [%3]\n" + "sub %0, %0, #1\n" + "strex %1, %0, [%3]" + : "=&r"(val), "=&r"(status), "+m"(*v) + : "r"(v) + : "cc"); + } while (__builtin_expect(status != 0, 0)); +} + +/** + * @ingroup los_atomic + * @brief Atomic auto-decrement. + * + * @par Description: + * This API is used to implement the atomic auto-decrement and return the result of auto-decrement. + * @attention + *
            + *
          • The pointer v must not be NULL.
          • + *
          • The value which v point to must not be INT_MIN to avoid overflow after reducing 1.
          • + *
          + * + * @param v [IN] The auto-decrement variable pointer. + * + * @retval #INT32 The return value of variable auto-decrement. + * @par Dependency: + *
          • los_atomic.h: the header file that contains the API declaration.
          + * @see + */ +STATIC INLINE INT32 LOS_AtomicDecRet(Atomic *v) +{ + INT32 val; + UINT32 status; + + do { + __asm__ __volatile__("ldrex %0, [%3]\n" + "sub %0, %0, #1\n" + "strex %1, %0, [%3]" + : "=&r"(val), "=&r"(status), "+m"(*v) + : "r"(v) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return val; +} + +/** + * @ingroup los_atomic + * @brief Atomic64 read. + * + * @par Description: + * This API is used to implement the atomic64 read and return the result value of the read. + * @attention + *
            + *
          • The pointer v must not be NULL.
          • + *
          + * + * @param v [IN] The reading pointer. + * + * @retval #INT64 The result value of the read. + * @par Dependency: + *
          • los_atomic.h: the header file that contains the API declaration.
          + * @see + */ +STATIC INLINE INT64 LOS_Atomic64Read(const Atomic64 *v) +{ + INT64 val; + + do { + __asm__ __volatile__("ldrexd %0, %H0, [%1]" + : "=&r"(val) + : "r"(v) + : "cc"); + } while (0); + + return val; +} + +/** + * @ingroup los_atomic + * @brief Atomic64 setting. + * + * @par Description: + * This API is used to implement the atomic64 setting operation. + * @attention + *
            + *
          • The pointer v must not be NULL.
          • + *
          + * + * @param v [IN] The variable pointer to be setting. + * @param setVal [IN] The value to be setting. + * + * @retval none. + * @par Dependency: + *
          • los_atomic.h: the header file that contains the API declaration.
          + * @see + */ +STATIC INLINE VOID LOS_Atomic64Set(Atomic64 *v, INT64 setVal) +{ + INT64 tmp; + UINT32 status; + + do { + __asm__ __volatile__("ldrexd %1, %H1, [%2]\n" + "strexd %0, %3, %H3, [%2]" + : "=&r"(status), "=&r"(tmp) + : "r"(v), "r"(setVal) + : "cc"); + } while (__builtin_expect(status != 0, 0)); +} + +/** + * @ingroup los_atomic + * @brief Atomic64 addition. + * + * @par Description: + * This API is used to implement the atomic64 addition and return the result value of the augend. + * @attention + *
            + *
          • The pointer v must not be NULL.
          • + *
          • If the addtion result is not in the range of representable values for 64-bit signed integer, + * an int integer overflow may occur to the return value
          • + *
          + * + * @param v [IN] The augend pointer. + * @param addVal [IN] The addend. + * + * @retval #INT64 The result value of the augend. + * @par Dependency: + *
          • los_atomic.h: the header file that contains the API declaration.
          + * @see + */ +STATIC INLINE INT64 LOS_Atomic64Add(Atomic64 *v, INT64 addVal) +{ + INT64 val; + UINT32 status; + + do { + __asm__ __volatile__("ldrexd %1, %H1, [%2]\n" + "adds %Q1, %Q1, %Q3\n" + "adc %R1, %R1, %R3\n" + "strexd %0, %1, %H1, [%2]" + : "=&r"(status), "=&r"(val) + : "r"(v), "r"(addVal) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return val; +} + +/** + * @ingroup los_atomic + * @brief Atomic64 subtraction. + * + * @par Description: + * This API is used to implement the atomic64 subtraction and return the result value of the minuend. + * @attention + *
            + *
          • The pointer v must not be NULL.
          • + *
          • If the subtraction result is not in the range of representable values for 64-bit signed integer, + * an int integer overflow may occur to the return value
          • + *
          + * + * @param v [IN] The minuend pointer. + * @param subVal [IN] The subtrahend. + * + * @retval #INT64 The result value of the minuend. + * @par Dependency: + *
          • los_atomic.h: the header file that contains the API declaration.
          + * @see + */ +STATIC INLINE INT64 LOS_Atomic64Sub(Atomic64 *v, INT64 subVal) +{ + INT64 val; + UINT32 status; + + do { + __asm__ __volatile__("ldrexd %1, %H1, [%2]\n" + "subs %Q1, %Q1, %Q3\n" + "sbc %R1, %R1, %R3\n" + "strexd %0, %1, %H1, [%2]" + : "=&r"(status), "=&r"(val) + : "r"(v), "r"(subVal) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return val; +} + +/** + * @ingroup los_atomic + * @brief Atomic64 addSelf. + * + * @par Description: + * This API is used to implement the atomic64 addSelf . + * @attention + *
            + *
          • The pointer v must not be NULL.
          • + *
          • The value which v point to must not be INT64_MAX to avoid integer overflow after adding 1.
          • + *
          + * + * @param v [IN] The addSelf variable pointer. + * + * @retval none. + * @par Dependency: + *
          • los_atomic.h: the header file that contains the API declaration.
          + * @see + */ +STATIC INLINE VOID LOS_Atomic64Inc(Atomic64 *v) +{ + INT64 val; + UINT32 status; + + do { + __asm__ __volatile__("ldrexd %0, %H0, [%3]\n" + "adds %Q0, %Q0, #1\n" + "adc %R0, %R0, #0\n" + "strexd %1, %0, %H0, [%3]" + : "=&r"(val), "=&r"(status), "+m"(*v) + : "r"(v) + : "cc"); + } while (__builtin_expect(status != 0, 0)); +} + +/** + * @ingroup los_atomic + * @brief Atomic64 addSelf. + * + * @par Description: + * This API is used to implement the atomic64 addSelf and return the result of addSelf. + * @attention + *
            + *
          • The pointer v must not be NULL.
          • + *
          • The value which v point to must not be INT64_MAX to avoid integer overflow after adding 1.
          • + *
          + * + * @param v [IN] The addSelf variable pointer. + * + * @retval #INT64 The return value of variable addSelf. + * @par Dependency: + *
          • los_atomic.h: the header file that contains the API declaration.
          + * @see + */ +STATIC INLINE INT64 LOS_Atomic64IncRet(Atomic64 *v) +{ + INT64 val; + UINT32 status; + + do { + __asm__ __volatile__("ldrexd %0, %H0, [%3]\n" + "adds %Q0, %Q0, #1\n" + "adc %R0, %R0, #0\n" + "strexd %1, %0, %H0, [%3]" + : "=&r"(val), "=&r"(status), "+m"(*v) + : "r"(v) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return val; +} + +/** + * @ingroup los_atomic + * @brief Atomic64 auto-decrement. + * + * @par Description: + * This API is used to implement the atomic64 auto-decrement. + * @attention + *
            + *
          • The pointer v must not be NULL.
          • + *
          • The value which v point to must not be INT64_MIN to avoid overflow after reducing 1.
          • + *
          + * + * @param v [IN] The auto-decrement variable pointer. + * + * @retval none. + * @par Dependency: + *
          • los_atomic.h: the header file that contains the API declaration.
          + * @see + */ +STATIC INLINE VOID LOS_Atomic64Dec(Atomic64 *v) +{ + INT64 val; + UINT32 status; + + do { + __asm__ __volatile__("ldrexd %0, %H0, [%3]\n" + "subs %Q0, %Q0, #1\n" + "sbc %R0, %R0, #0\n" + "strexd %1, %0, %H0, [%3]" + : "=&r"(val), "=&r"(status), "+m"(*v) + : "r"(v) + : "cc"); + } while (__builtin_expect(status != 0, 0)); +} + +/** + * @ingroup los_atomic + * @brief Atomic64 auto-decrement. + * + * @par Description: + * This API is used to implement the atomic64 auto-decrement and return the result of auto-decrement. + * @attention + *
            + *
          • The pointer v must not be NULL.
          • + *
          • The value which v point to must not be INT64_MIN to avoid overflow after reducing 1.
          • + *
          + * + * @param v [IN] The auto-decrement variable pointer. + * + * @retval #INT64 The return value of variable auto-decrement. + * @par Dependency: + *
          • los_atomic.h: the header file that contains the API declaration.
          + * @see + */ +STATIC INLINE INT64 LOS_Atomic64DecRet(Atomic64 *v) +{ + INT64 val; + UINT32 status; + + do { + __asm__ __volatile__("ldrexd %0, %H0, [%3]\n" + "subs %Q0, %Q0, #1\n" + "sbc %R0, %R0, #0\n" + "strexd %1, %0, %H0, [%3]" + : "=&r"(val), "=&r"(status), "+m"(*v) + : "r"(v) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return val; +} + +/** + * @ingroup los_atomic + * @brief Atomic exchange for 8-bit variable. + * + * @par Description: + * This API is used to implement the atomic exchange for 8-bit variable and + * return the previous value of the atomic variable. + * @attention + *
            The pointer v must not be NULL.
          + * + * @param v [IN] The variable pointer. + * @param val [IN] The exchange value. + * + * @retval #INT32 The previous value of the atomic variable + * @par Dependency: + *
          • los_atomic.h: the header file that contains the API declaration.
          + * @see + */ +STATIC INLINE INT32 LOS_AtomicXchgByte(volatile INT8 *v, INT32 val) +{ + INT32 prevVal; + UINT32 status; + + do { + __asm__ __volatile__("ldrexb %0, [%3]\n" + "strexb %1, %4, [%3]" + : "=&r"(prevVal), "=&r"(status), "+m"(*v) + : "r"(v), "r"(val) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return prevVal; +} + +/** + * @ingroup los_atomic + * @brief Atomic exchange for 16-bit variable. + * + * @par Description: + * This API is used to implement the atomic exchange for 16-bit variable and + * return the previous value of the atomic variable. + * @attention + *
            The pointer v must not be NULL.
          + * + * @param v [IN] The variable pointer. + * @param val [IN] The exchange value. + * + * @retval #INT32 The previous value of the atomic variable + * @par Dependency: + *
          • los_atomic.h: the header file that contains the API declaration.
          + * @see + */ +STATIC INLINE INT32 LOS_AtomicXchg16bits(volatile INT16 *v, INT32 val) +{ + INT32 prevVal; + UINT32 status; + + do { + __asm__ __volatile__("ldrexh %0, [%3]\n" + "strexh %1, %4, [%3]" + : "=&r"(prevVal), "=&r"(status), "+m"(*v) + : "r"(v), "r"(val) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return prevVal; +} + +/** + * @ingroup los_atomic + * @brief Atomic exchange for 32-bit variable. + * + * @par Description: + * This API is used to implement the atomic exchange for 32-bit variable + * and return the previous value of the atomic variable. + * @attention + *
            The pointer v must not be NULL.
          + * + * @param v [IN] The variable pointer. + * @param val [IN] The exchange value. + * + * @retval #INT32 The previous value of the atomic variable + * @par Dependency: + *
          • los_atomic.h: the header file that contains the API declaration.
          + * @see + */ +STATIC INLINE INT32 LOS_AtomicXchg32bits(Atomic *v, INT32 val) +{ + INT32 prevVal; + UINT32 status; + + do { + __asm__ __volatile__("ldrex %0, [%3]\n" + "strex %1, %4, [%3]" + : "=&r"(prevVal), "=&r"(status), "+m"(*v) + : "r"(v), "r"(val) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return prevVal; +} + +/** + * @ingroup los_atomic + * @brief Atomic exchange for 64-bit variable. + * + * @par Description: + * This API is used to implement the atomic exchange for 64-bit variable + * and return the previous value of the atomic variable. + * @attention + *
            The pointer v must not be NULL.
          + * + * @param v [IN] The variable pointer. + * @param val [IN] The exchange value. + * + * @retval #INT64 The previous value of the atomic variable + * @par Dependency: + *
          • los_atomic.h: the header file that contains the API declaration.
          + * @see + */ +STATIC INLINE INT64 LOS_AtomicXchg64bits(Atomic64 *v, INT64 val) +{ + INT64 prevVal; + UINT32 status; + + do { + __asm__ __volatile__("ldrexd %0, %H0, [%3]\n" + "strexd %1, %4, %H4, [%3]" + : "=&r"(prevVal), "=&r"(status), "+m"(*v) + : "r"(v), "r"(val) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return prevVal; +} + +/** + * @ingroup los_atomic + * @brief Atomic exchange for 8-bit variable with compare. + * + * @par Description: + * This API is used to implement the atomic exchange for 8-bit variable, if the value of variable is equal to oldVal. + * @attention + *
            The pointer v must not be NULL.
          + * + * @param v [IN] The variable pointer. + * @param val [IN] The new value. + * @param oldVal [IN] The old value. + * + * @retval TRUE The previous value of the atomic variable is not equal to oldVal. + * @retval FALSE The previous value of the atomic variable is equal to oldVal. + * @par Dependency: + *
          • los_atomic.h: the header file that contains the API declaration.
          + * @see + */ +STATIC INLINE BOOL LOS_AtomicCmpXchgByte(volatile INT8 *v, INT32 val, INT32 oldVal) +{ + INT32 prevVal; + UINT32 status; + + do { + __asm__ __volatile__("ldrexb %0, [%3]\n" + "mov %1, #0\n" + "teq %0, %4\n" + "strexbeq %1, %5, [%3]" + : "=&r"(prevVal), "=&r"(status), "+m"(*v) + : "r"(v), "r"(oldVal), "r"(val) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return prevVal != oldVal; +} + +/** + * @ingroup los_atomic + * @brief Atomic exchange for 16-bit variable with compare. + * + * @par Description: + * This API is used to implement the atomic exchange for 16-bit variable, if the value of variable is equal to oldVal. + * @attention + *
            The pointer v must not be NULL.
          + * + * @param v [IN] The variable pointer. + * @param val [IN] The new value. + * @param oldVal [IN] The old value. + * + * @retval TRUE The previous value of the atomic variable is not equal to oldVal. + * @retval FALSE The previous value of the atomic variable is equal to oldVal. + * @par Dependency: + *
          • los_atomic.h: the header file that contains the API declaration.
          + * @see + */ +STATIC INLINE BOOL LOS_AtomicCmpXchg16bits(volatile INT16 *v, INT32 val, INT32 oldVal) +{ + INT32 prevVal; + UINT32 status; + + do { + __asm__ __volatile__("ldrexh %0, [%3]\n" + "mov %1, #0\n" + "teq %0, %4\n" + "strexheq %1, %5, [%3]" + : "=&r"(prevVal), "=&r"(status), "+m"(*v) + : "r"(v), "r"(oldVal), "r"(val) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return prevVal != oldVal; +} + +/** + * @ingroup los_atomic + * @brief Atomic exchange for 32-bit variable with compare. + * + * @par Description: + * This API is used to implement the atomic exchange for 32-bit variable, if the value of variable is equal to oldVal. + * @attention + *
            The pointer v must not be NULL.
          + * + * @param v [IN] The variable pointer. + * @param val [IN] The new value. + * @param oldVal [IN] The old value. + * + * @retval TRUE The previous value of the atomic variable is not equal to oldVal. + * @retval FALSE The previous value of the atomic variable is equal to oldVal. + * @par Dependency: + *
          • los_atomic.h: the header file that contains the API declaration.
          + * @see + */ +STATIC INLINE BOOL LOS_AtomicCmpXchg32bits(Atomic *v, INT32 val, INT32 oldVal) +{ + INT32 prevVal; + UINT32 status; + + do { + __asm__ __volatile__("ldrex %0, [%3]\n" + "mov %1, #0\n" + "teq %0, %4\n" + "strexeq %1, %5, [%3]" + : "=&r"(prevVal), "=&r"(status), "+m"(*v) + : "r"(v), "r"(oldVal), "r"(val) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return prevVal != oldVal; +} + +/** + * @ingroup los_atomic + * @brief Atomic exchange for 64-bit variable with compare. + * + * @par Description: + * This API is used to implement the atomic exchange for 64-bit variable, if the value of variable is equal to oldVal. + * @attention + *
            The pointer v must not be NULL.
          + * + * @param v [IN] The variable pointer. + * @param val [IN] The new value. + * @param oldVal [IN] The old value. + * + * @retval TRUE The previous value of the atomic variable is not equal to oldVal. + * @retval FALSE The previous value of the atomic variable is equal to oldVal. + * @par Dependency: + *
          • los_atomic.h: the header file that contains the API declaration.
          + * @see + */ +STATIC INLINE BOOL LOS_AtomicCmpXchg64bits(Atomic64 *v, INT64 val, INT64 oldVal) +{ + INT64 prevVal; + UINT32 status; + + do { + __asm__ __volatile__("ldrexd %0, %H0, [%3]\n" + "mov %1, #0\n" + "teq %0, %4\n" + "teqeq %H0, %H4\n" + "strexdeq %1, %5, %H5, [%3]" + : "=&r"(prevVal), "=&r"(status), "+m"(*v) + : "r"(v), "r"(oldVal), "r"(val) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return prevVal != oldVal; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* __LOS_ATOMIC_H__ */ diff --git a/src/kernel_liteos_a/arch/arm/arm/include/los_hw_cpu.h b/src/kernel_liteos_a/arch/arm/arm/include/los_hw_cpu.h new file mode 100644 index 00000000..0234052f --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/include/los_hw_cpu.h @@ -0,0 +1,277 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_hw Hardware + * @ingroup kernel + */ + +#ifndef _LOS_HW_CPU_H +#define _LOS_HW_CPU_H + +#include "los_typedef.h" +#include "los_toolchain.h" +#include "los_hw_arch.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/* ARM System Registers */ +#define DSB __asm__ volatile("dsb" ::: "memory") +#define DMB __asm__ volatile("dmb" ::: "memory") +#define ISB __asm__ volatile("isb" ::: "memory") +#define WFI __asm__ volatile("wfi" ::: "memory") +#define BARRIER __asm__ volatile("":::"memory") +#define WFE __asm__ volatile("wfe" ::: "memory") +#define SEV __asm__ volatile("sev" ::: "memory") + +#define ARM_SYSREG_READ(REG) \ +({ \ + UINT32 _val; \ + __asm__ volatile("mrc " REG : "=r" (_val)); \ + _val; \ +}) + +#define ARM_SYSREG_WRITE(REG, val) \ +({ \ + __asm__ volatile("mcr " REG :: "r" (val)); \ + ISB; \ +}) + +#define ARM_SYSREG64_READ(REG) \ +({ \ + UINT64 _val; \ + __asm__ volatile("mrrc " REG : "=r" (_val)); \ + _val; \ +}) + +#define ARM_SYSREG64_WRITE(REG, val) \ +({ \ + __asm__ volatile("mcrr " REG :: "r" (val)); \ + ISB; \ +}) + +#define CP14_REG(CRn, Op1, CRm, Op2) "p14, "#Op1", %0, "#CRn","#CRm","#Op2 +#define CP15_REG(CRn, Op1, CRm, Op2) "p15, "#Op1", %0, "#CRn","#CRm","#Op2 +#define CP15_REG64(CRn, Op1) "p15, "#Op1", %0, %H0,"#CRn + +/* + * Identification registers (c0) + */ +#define MIDR CP15_REG(c0, 0, c0, 0) /* Main ID Register */ +#define MPIDR CP15_REG(c0, 0, c0, 5) /* Multiprocessor Affinity Register */ +#define CCSIDR CP15_REG(c0, 1, c0, 0) /* Cache Size ID Registers */ +#define CLIDR CP15_REG(c0, 1, c0, 1) /* Cache Level ID Register */ +#define VPIDR CP15_REG(c0, 4, c0, 0) /* Virtualization Processor ID Register */ +#define VMPIDR CP15_REG(c0, 4, c0, 5) /* Virtualization Multiprocessor ID Register */ + +/* + * System control registers (c1) + */ +#define SCTLR CP15_REG(c1, 0, c0, 0) /* System Control Register */ +#define ACTLR CP15_REG(c1, 0, c0, 1) /* Auxiliary Control Register */ +#define CPACR CP15_REG(c1, 0, c0, 2) /* Coprocessor Access Control Register */ + +/* + * Memory protection and control registers (c2 & c3) + */ +#define TTBR0 CP15_REG(c2, 0, c0, 0) /* Translation Table Base Register 0 */ +#define TTBR1 CP15_REG(c2, 0, c0, 1) /* Translation Table Base Register 1 */ +#define TTBCR CP15_REG(c2, 0, c0, 2) /* Translation Table Base Control Register */ +#define DACR CP15_REG(c3, 0, c0, 0) /* Domain Access Control Register */ + +/* + * Memory system fault registers (c5 & c6) + */ +#define DFSR CP15_REG(c5, 0, c0, 0) /* Data Fault Status Register */ +#define IFSR CP15_REG(c5, 0, c0, 1) /* Instruction Fault Status Register */ +#define DFAR CP15_REG(c6, 0, c0, 0) /* Data Fault Address Register */ +#define IFAR CP15_REG(c6, 0, c0, 2) /* Instruction Fault Address Register */ + +/* + * Process, context and thread ID registers (c13) + */ +#define FCSEIDR CP15_REG(c13, 0, c0, 0) /* FCSE Process ID Register */ +#define CONTEXTIDR CP15_REG(c13, 0, c0, 1) /* Context ID Register */ +#define TPIDRURW CP15_REG(c13, 0, c0, 2) /* User Read/Write Thread ID Register */ +#define TPIDRURO CP15_REG(c13, 0, c0, 3) /* User Read-Only Thread ID Register */ +#define TPIDRPRW CP15_REG(c13, 0, c0, 4) /* PL1 only Thread ID Register */ + +#define MPIDR_CPUID_MASK (0xffU) + +STATIC INLINE VOID *ArchCurrTaskGet(VOID) +{ + return (VOID *)(UINTPTR)ARM_SYSREG_READ(TPIDRPRW); +} + +STATIC INLINE VOID ArchCurrTaskSet(VOID *val) +{ + ARM_SYSREG_WRITE(TPIDRPRW, (UINT32)(UINTPTR)val); +} + +STATIC INLINE VOID ArchCurrUserTaskSet(UINTPTR val) +{ + ARM_SYSREG_WRITE(TPIDRURO, (UINT32)val); +} + +STATIC INLINE UINT32 ArchCurrCpuid(VOID) +{ +#ifdef LOSCFG_KERNEL_SMP + return ARM_SYSREG_READ(MPIDR) & MPIDR_CPUID_MASK; +#else + return 0; +#endif +} + +STATIC INLINE UINT64 OsHwIDGet(VOID) +{ + return ARM_SYSREG_READ(MPIDR); +} + +STATIC INLINE UINT32 OsMainIDGet(VOID) +{ + return ARM_SYSREG_READ(MIDR); +} + +/* CPU interrupt mask handle implementation */ +#if LOSCFG_ARM_ARCH >= 6 + +STATIC INLINE UINT32 ArchIntLock(VOID) +{ + UINT32 intSave; + __asm__ __volatile__( + "mrs %0, cpsr \n" + "cpsid if " + : "=r"(intSave) + : + : "memory"); + return intSave; +} + +STATIC INLINE UINT32 ArchIntUnlock(VOID) +{ + UINT32 intSave; + __asm__ __volatile__( + "mrs %0, cpsr \n" + "cpsie if " + : "=r"(intSave) + : + : "memory"); + return intSave; +} + +STATIC INLINE VOID ArchIrqDisable(VOID) +{ + __asm__ __volatile__( + "cpsid i " + : + : + : "memory", "cc"); +} + +STATIC INLINE VOID ArchIrqEnable(VOID) +{ + __asm__ __volatile__( + "cpsie i " + : + : + : "memory", "cc"); +} + +#else + +STATIC INLINE UINT32 ArchIntLock(VOID) +{ + UINT32 intSave, temp; + __asm__ __volatile__( + "mrs %0, cpsr \n" + "orr %1, %0, #0xc0 \n" + "msr cpsr_c, %1 " + :"=r"(intSave), "=r"(temp) + : :"memory"); + return intSave; +} + +STATIC INLINE UINT32 ArchIntUnlock(VOID) +{ + UINT32 intSave; + __asm__ __volatile__( + "mrs %0, cpsr \n" + "bic %0, %0, #0xc0 \n" + "msr cpsr_c, %0 " + : "=r"(intSave) + : : "memory"); + return intSave; +} + +#endif + +STATIC INLINE VOID ArchIntRestore(UINT32 intSave) +{ + __asm__ __volatile__( + "msr cpsr_c, %0 " + : + : "r"(intSave) + : "memory"); +} + +#define PSR_I_BIT 0x00000080U + +STATIC INLINE UINT32 OsIntLocked(VOID) +{ + UINT32 intSave; + + asm volatile( + "mrs %0, cpsr " + : "=r" (intSave) + : + : "memory", "cc"); + + return intSave & PSR_I_BIT; +} + +STATIC INLINE UINT32 ArchSPGet(VOID) +{ + UINT32 val; + __asm__ __volatile__("mov %0, sp" : "=r"(val)); + return val; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_HW_CPU_H */ diff --git a/src/kernel_liteos_a/arch/arm/arm/include/los_mmu_descriptor_v6.h b/src/kernel_liteos_a/arch/arm/arm/include/los_mmu_descriptor_v6.h new file mode 100644 index 00000000..6f93de03 --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/include/los_mmu_descriptor_v6.h @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_mmu_descriptor_v6 MMU Descriptor v6 + * @ingroup kernel + */ + +#ifndef __LOS_MMU_DESCRIPTOR_V6_H__ +#define __LOS_MMU_DESCRIPTOR_V6_H__ + +#include "los_vm_common.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define __iomem +#ifndef IS_ALIGNED +#define IS_ALIGNED(a, b) (!(((UINTPTR)(a)) & (((UINTPTR)(b))-1))) +#endif + +#define MMU_DESCRIPTOR_TEX_0 0 +#define MMU_DESCRIPTOR_TEX_1 1 +#define MMU_DESCRIPTOR_TEX_2 2 +#define MMU_DESCRIPTOR_TEX_MASK 7 + +#define MMU_DESCRIPTOR_CACHE_BUFFER_SHIFT 2 +#define MMU_DESCRIPTOR_CACHE_BUFFER(x) ((x) << MMU_DESCRIPTOR_CACHE_BUFFER_SHIFT) +#define MMU_DESCRIPTOR_NON_CACHEABLE MMU_DESCRIPTOR_CACHE_BUFFER(0) +#define MMU_DESCRIPTOR_WRITE_BACK_ALLOCATE MMU_DESCRIPTOR_CACHE_BUFFER(1) +#define MMU_DESCRIPTOR_WRITE_THROUGH_NO_ALLOCATE MMU_DESCRIPTOR_CACHE_BUFFER(2) +#define MMU_DESCRIPTOR_WRITE_BACK_NO_ALLOCATE MMU_DESCRIPTOR_CACHE_BUFFER(3) + +/* user space mmu access permission define begin */ +#define MMU_DESCRIPTOR_DOMAIN_MANAGER 0 +#define MMU_DESCRIPTOR_DOMAIN_CLIENT 1 +#define MMU_DESCRIPTOR_DOMAIN_NA 2 + +/* L1 descriptor type */ +#define MMU_DESCRIPTOR_L1_TYPE_INVALID (0x0 << 0) +#define MMU_DESCRIPTOR_L1_TYPE_PAGE_TABLE (0x1 << 0) +#define MMU_DESCRIPTOR_L1_TYPE_SECTION (0x2 << 0) +#define MMU_DESCRIPTOR_L1_TYPE_MASK (0x3 << 0) + +/* L2 descriptor type */ +#define MMU_DESCRIPTOR_L2_TYPE_INVALID (0x0 << 0) +#define MMU_DESCRIPTOR_L2_TYPE_LARGE_PAGE (0x1 << 0) +#define MMU_DESCRIPTOR_L2_TYPE_SMALL_PAGE (0x2 << 0) +#define MMU_DESCRIPTOR_L2_TYPE_SMALL_PAGE_XN (0x3 << 0) +#define MMU_DESCRIPTOR_L2_TYPE_MASK (0x3 << 0) + +#define MMU_DESCRIPTOR_IS_L1_SIZE_ALIGNED(x) IS_ALIGNED(x, MMU_DESCRIPTOR_L1_SMALL_SIZE) +#define MMU_DESCRIPTOR_L1_SMALL_SIZE 0x100000 +#define MMU_DESCRIPTOR_L1_SMALL_MASK (MMU_DESCRIPTOR_L1_SMALL_SIZE - 1) +#define MMU_DESCRIPTOR_L1_SMALL_FRAME (~MMU_DESCRIPTOR_L1_SMALL_MASK) +#define MMU_DESCRIPTOR_L1_SMALL_SHIFT 20 +#define MMU_DESCRIPTOR_L1_SECTION_ADDR(x) ((x) & MMU_DESCRIPTOR_L1_SMALL_FRAME) +#define MMU_DESCRIPTOR_L1_PAGE_TABLE_ADDR(x) ((x) & ~((1 << 10)-1)) +#define MMU_DESCRIPTOR_L1_SMALL_L2_TABLES_PER_PAGE 4 +#define MMU_DESCRIPTOR_L1_SMALL_ENTRY_NUMBERS 0x4000U +#define MMU_DESCRIPTOR_L1_SMALL_DOMAIN_MASK (~(0x0f << 5)) /* 4k page section domain mask */ +#define MMU_DESCRIPTOR_L1_SMALL_DOMAIN_CLIENT (MMU_DESCRIPTOR_DOMAIN_CLIENT << 5) + +#define MMU_DESCRIPTOR_L1_PAGETABLE_NON_SECURE (1 << 3) +#define MMU_DESCRIPTOR_L1_SECTION_NON_SECURE (1 << 19) +#define MMU_DESCRIPTOR_L1_SECTION_SHAREABLE (1 << 16) +#define MMU_DESCRIPTOR_L1_SECTION_NON_GLOBAL (1 << 17) +#define MMU_DESCRIPTOR_L1_SECTION_XN (1 << 4) + +/* TEX CB */ +#define MMU_DESCRIPTOR_L1_TEX_SHIFT 12 /* type extension field shift */ +#define MMU_DESCRIPTOR_L1_TEX(x) \ + ((x) << MMU_DESCRIPTOR_L1_TEX_SHIFT) /* type extension */ +#define MMU_DESCRIPTOR_L1_TYPE_STRONGLY_ORDERED \ + (MMU_DESCRIPTOR_L1_TEX(MMU_DESCRIPTOR_TEX_0) | MMU_DESCRIPTOR_NON_CACHEABLE) +#define MMU_DESCRIPTOR_L1_TYPE_NORMAL_NOCACHE \ + (MMU_DESCRIPTOR_L1_TEX(MMU_DESCRIPTOR_TEX_1) | MMU_DESCRIPTOR_NON_CACHEABLE) +#define MMU_DESCRIPTOR_L1_TYPE_DEVICE_SHARED \ + (MMU_DESCRIPTOR_L1_TEX(MMU_DESCRIPTOR_TEX_0) | MMU_DESCRIPTOR_WRITE_BACK_ALLOCATE) +#define MMU_DESCRIPTOR_L1_TYPE_DEVICE_NON_SHARED \ + (MMU_DESCRIPTOR_L1_TEX(MMU_DESCRIPTOR_TEX_2) | MMU_DESCRIPTOR_NON_CACHEABLE) +#define MMU_DESCRIPTOR_L1_TYPE_NORMAL_WRITE_BACK_ALLOCATE \ + (MMU_DESCRIPTOR_L1_TEX(MMU_DESCRIPTOR_TEX_1) | MMU_DESCRIPTOR_WRITE_BACK_NO_ALLOCATE) +#define MMU_DESCRIPTOR_L1_TEX_TYPE_MASK \ + (MMU_DESCRIPTOR_L1_TEX(MMU_DESCRIPTOR_TEX_MASK) | MMU_DESCRIPTOR_WRITE_BACK_NO_ALLOCATE) + +#define MMU_DESCRIPTOR_L1_AP2_SHIFT 15 +#define MMU_DESCRIPTOR_L1_AP2(x) ((x) << MMU_DESCRIPTOR_L1_AP2_SHIFT) +#define MMU_DESCRIPTOR_L1_AP2_0 (MMU_DESCRIPTOR_L1_AP2(0)) +#define MMU_DESCRIPTOR_L1_AP2_1 (MMU_DESCRIPTOR_L1_AP2(1)) +#define MMU_DESCRIPTOR_L1_AP01_SHIFT 10 +#define MMU_DESCRIPTOR_L1_AP01(x) ((x) << MMU_DESCRIPTOR_L1_AP01_SHIFT) +#define MMU_DESCRIPTOR_L1_AP01_0 (MMU_DESCRIPTOR_L1_AP01(0)) +#define MMU_DESCRIPTOR_L1_AP01_1 (MMU_DESCRIPTOR_L1_AP01(1)) +#define MMU_DESCRIPTOR_L1_AP01_3 (MMU_DESCRIPTOR_L1_AP01(3)) +#define MMU_DESCRIPTOR_L1_AP_P_NA_U_NA (MMU_DESCRIPTOR_L1_AP2_0 | MMU_DESCRIPTOR_L1_AP01_0) +#define MMU_DESCRIPTOR_L1_AP_P_RW_U_RW (MMU_DESCRIPTOR_L1_AP2_0 | MMU_DESCRIPTOR_L1_AP01_3) +#define MMU_DESCRIPTOR_L1_AP_P_RW_U_NA (MMU_DESCRIPTOR_L1_AP2_0 | MMU_DESCRIPTOR_L1_AP01_1) +#define MMU_DESCRIPTOR_L1_AP_P_RO_U_RO (MMU_DESCRIPTOR_L1_AP2_1 | MMU_DESCRIPTOR_L1_AP01_3) +#define MMU_DESCRIPTOR_L1_AP_P_RO_U_NA (MMU_DESCRIPTOR_L1_AP2_1 | MMU_DESCRIPTOR_L1_AP01_1) +#define MMU_DESCRIPTOR_L1_AP_MASK (MMU_DESCRIPTOR_L1_AP2_1 | MMU_DESCRIPTOR_L1_AP01_3) + +#define MMU_DESCRIPTOR_L2_SMALL_SIZE 0x1000 +#define MMU_DESCRIPTOR_L2_SMALL_MASK (MMU_DESCRIPTOR_L2_SMALL_SIZE - 1) +#define MMU_DESCRIPTOR_L2_SMALL_FRAME (~MMU_DESCRIPTOR_L2_SMALL_MASK) +#define MMU_DESCRIPTOR_L2_SMALL_SHIFT 12 +#define MMU_DESCRIPTOR_L2_NUMBERS_PER_L1 \ + (MMU_DESCRIPTOR_L1_SMALL_SIZE >> MMU_DESCRIPTOR_L2_SMALL_SHIFT) +#define MMU_DESCRIPTOR_IS_L2_SIZE_ALIGNED(x) IS_ALIGNED(x, MMU_DESCRIPTOR_L2_SMALL_SIZE) +#define MMU_DESCRIPTOR_L2_TEX_SHIFT 6 /* type extension field shift */ +#define MMU_DESCRIPTOR_L2_TEX(x) \ + ((x) << MMU_DESCRIPTOR_L2_TEX_SHIFT) /* type extension */ +#define MMU_DESCRIPTOR_L2_TYPE_STRONGLY_ORDERED \ + (MMU_DESCRIPTOR_L2_TEX(MMU_DESCRIPTOR_TEX_0) | MMU_DESCRIPTOR_NON_CACHEABLE) +#define MMU_DESCRIPTOR_L2_TYPE_NORMAL_NOCACHE \ + (MMU_DESCRIPTOR_L2_TEX(MMU_DESCRIPTOR_TEX_1) | MMU_DESCRIPTOR_NON_CACHEABLE) +#define MMU_DESCRIPTOR_L2_TYPE_DEVICE_SHARED \ + (MMU_DESCRIPTOR_L2_TEX(MMU_DESCRIPTOR_TEX_0) | MMU_DESCRIPTOR_WRITE_BACK_ALLOCATE) +#define MMU_DESCRIPTOR_L2_TYPE_DEVICE_NON_SHARED \ + (MMU_DESCRIPTOR_L2_TEX(MMU_DESCRIPTOR_TEX_2) | MMU_DESCRIPTOR_NON_CACHEABLE) +#define MMU_DESCRIPTOR_L2_TYPE_NORMAL_WRITE_BACK_ALLOCATE \ + (MMU_DESCRIPTOR_L2_TEX(MMU_DESCRIPTOR_TEX_1) | MMU_DESCRIPTOR_WRITE_BACK_NO_ALLOCATE) +#define MMU_DESCRIPTOR_L2_TEX_TYPE_MASK \ + (MMU_DESCRIPTOR_L2_TEX(MMU_DESCRIPTOR_TEX_MASK) | MMU_DESCRIPTOR_WRITE_BACK_NO_ALLOCATE) +#define MMU_DESCRIPTOR_L2_AP2_SHIFT 9 +#define MMU_DESCRIPTOR_L2_AP2(x) ((x) << MMU_DESCRIPTOR_L2_AP2_SHIFT) +#define MMU_DESCRIPTOR_L2_AP2_0 (MMU_DESCRIPTOR_L2_AP2(0)) +#define MMU_DESCRIPTOR_L2_AP2_1 (MMU_DESCRIPTOR_L2_AP2(1)) +#define MMU_DESCRIPTOR_L2_AP01_SHIFT 4 +#define MMU_DESCRIPTOR_L2_AP01(x) ((x) << MMU_DESCRIPTOR_L2_AP01_SHIFT) +#define MMU_DESCRIPTOR_L2_AP01_0 (MMU_DESCRIPTOR_L2_AP01(0)) +#define MMU_DESCRIPTOR_L2_AP01_1 (MMU_DESCRIPTOR_L2_AP01(1)) +#define MMU_DESCRIPTOR_L2_AP01_3 (MMU_DESCRIPTOR_L2_AP01(3)) +#define MMU_DESCRIPTOR_L2_AP_P_NA_U_NA (MMU_DESCRIPTOR_L2_AP2_0 | MMU_DESCRIPTOR_L2_AP01_0) +#define MMU_DESCRIPTOR_L2_AP_P_RW_U_RW (MMU_DESCRIPTOR_L2_AP2_0 | MMU_DESCRIPTOR_L2_AP01_3) +#define MMU_DESCRIPTOR_L2_AP_P_RW_U_NA (MMU_DESCRIPTOR_L2_AP2_0 | MMU_DESCRIPTOR_L2_AP01_1) +#define MMU_DESCRIPTOR_L2_AP_P_RO_U_RO (MMU_DESCRIPTOR_L2_AP2_1 | MMU_DESCRIPTOR_L2_AP01_3) +#define MMU_DESCRIPTOR_L2_AP_P_RO_U_NA (MMU_DESCRIPTOR_L2_AP2_1 | MMU_DESCRIPTOR_L2_AP01_1) +#define MMU_DESCRIPTOR_L2_AP_MASK (MMU_DESCRIPTOR_L2_AP2_1 | MMU_DESCRIPTOR_L2_AP01_3) + +#define MMU_DESCRIPTOR_L2_SHAREABLE (1 << 10) +#define MMU_DESCRIPTOR_L2_NON_GLOBAL (1 << 11) +#define MMU_DESCRIPTOR_L2_SMALL_PAGE_ADDR(x) ((x) & MMU_DESCRIPTOR_L2_SMALL_FRAME) + +#define MMU_DESCRIPTOR_TTBCR_PD0 (1 << 4) +#define MMU_DESCRIPTOR_TTBR_WRITE_BACK_ALLOCATE 1 +#define MMU_DESCRIPTOR_TTBR_RGN(x) (((x) & 0x3) << 3) +#define MMU_DESCRIPTOR_TTBR_IRGN(x) ((((x) & 0x1) << 6) | ((((x) >> 1) & 0x1) << 0)) +#define MMU_DESCRIPTOR_TTBR_S (1 << 1) +#define MMU_DESCRIPTOR_TTBR_NOS (1 << 5) + +#ifdef LOSCFG_KERNEL_SMP +#define MMU_TTBRx_SHARABLE_FLAGS (MMU_DESCRIPTOR_TTBR_S | MMU_DESCRIPTOR_TTBR_NOS) +#else +#define MMU_TTBRx_SHARABLE_FLAGS 0 +#endif + +#define MMU_TTBRx_FLAGS \ + (MMU_DESCRIPTOR_TTBR_RGN(MMU_DESCRIPTOR_TTBR_WRITE_BACK_ALLOCATE) | \ + MMU_DESCRIPTOR_TTBR_IRGN(MMU_DESCRIPTOR_TTBR_WRITE_BACK_ALLOCATE) | \ + MMU_TTBRx_SHARABLE_FLAGS) + +#ifdef LOSCFG_KERNEL_SMP +#define MMU_DESCRIPTOR_KERNEL_L1_PTE_FLAGS \ + (MMU_DESCRIPTOR_L1_TYPE_SECTION | \ + MMU_DESCRIPTOR_L1_TYPE_NORMAL_WRITE_BACK_ALLOCATE | \ + MMU_DESCRIPTOR_L1_AP_P_RW_U_NA | \ + MMU_DESCRIPTOR_L1_SMALL_DOMAIN_CLIENT | \ + MMU_DESCRIPTOR_L1_SECTION_SHAREABLE) +#else +#define MMU_DESCRIPTOR_KERNEL_L1_PTE_FLAGS \ + (MMU_DESCRIPTOR_L1_TYPE_SECTION | \ + MMU_DESCRIPTOR_L1_TYPE_NORMAL_WRITE_BACK_ALLOCATE | \ + MMU_DESCRIPTOR_L1_SMALL_DOMAIN_CLIENT | \ + MMU_DESCRIPTOR_L1_AP_P_RW_U_NA) +#endif + +#define MMU_INITIAL_MAP_STRONGLY_ORDERED \ + (MMU_DESCRIPTOR_L1_TYPE_SECTION | \ + MMU_DESCRIPTOR_L1_TYPE_STRONGLY_ORDERED | \ + MMU_DESCRIPTOR_L1_SMALL_DOMAIN_CLIENT | \ + MMU_DESCRIPTOR_L1_AP_P_RW_U_NA) + +#define MMU_INITIAL_MAP_NORMAL_NOCACHE \ + (MMU_DESCRIPTOR_L1_TYPE_SECTION | \ + MMU_DESCRIPTOR_L1_TYPE_NORMAL_NOCACHE | \ + MMU_DESCRIPTOR_L1_SMALL_DOMAIN_CLIENT | \ + MMU_DESCRIPTOR_L1_AP_P_RW_U_NA) + +#define MMU_INITIAL_MAP_DEVICE \ + (MMU_DESCRIPTOR_L1_TYPE_SECTION | \ + MMU_DESCRIPTOR_L1_TYPE_DEVICE_SHARED | \ + MMU_DESCRIPTOR_L1_SMALL_DOMAIN_CLIENT | \ + MMU_DESCRIPTOR_L1_AP_P_RW_U_NA) + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* __LOS_MMU_DESCRIPTOR_V6_H__ */ + diff --git a/src/kernel_liteos_a/arch/arm/arm/include/los_pte_ops.h b/src/kernel_liteos_a/arch/arm/arm/include/los_pte_ops.h new file mode 100644 index 00000000..e47b4d65 --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/include/los_pte_ops.h @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_pte_ops page table entry operations + * @ingroup kernel + */ + +#ifndef __LOS_PTE_OPS_H__ +#define __LOS_PTE_OPS_H__ + +#include "los_typedef.h" +#include "arm.h" +#include "los_mmu_descriptor_v6.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +STATIC INLINE VOID OsSavePte1(PTE_T *pte1Ptr, PTE_T pte1) +{ + DMB; + *pte1Ptr = pte1; + DSB; +} + +STATIC INLINE ADDR_T OsTruncPte1(ADDR_T addr) +{ + return MMU_DESCRIPTOR_L1_SECTION_ADDR(addr); +} + +STATIC INLINE UINT32 OsGetPte1Index(vaddr_t va) +{ + return va >> MMU_DESCRIPTOR_L1_SMALL_SHIFT; +} + +STATIC INLINE VOID OsClearPte1(PTE_T *pte1Ptr) +{ + OsSavePte1(pte1Ptr, 0); +} + +STATIC INLINE PADDR_T OsGetPte1Paddr(PADDR_T PhysTtb, vaddr_t va) +{ + return (PhysTtb + (OsGetPte1Index(va) * sizeof(PADDR_T))); +} + +STATIC INLINE PTE_T *OsGetPte1Ptr(PTE_T *pte1BasePtr, vaddr_t va) +{ + return (pte1BasePtr + OsGetPte1Index(va)); +} + +STATIC INLINE PTE_T OsGetPte1(PTE_T *pte1BasePtr, vaddr_t va) +{ + return *OsGetPte1Ptr(pte1BasePtr, va); +} + +STATIC INLINE BOOL OsIsPte1PageTable(PTE_T pte1) +{ + return (pte1 & MMU_DESCRIPTOR_L1_TYPE_MASK) == MMU_DESCRIPTOR_L1_TYPE_PAGE_TABLE; +} + +STATIC INLINE BOOL OsIsPte1Invalid(PTE_T pte1) +{ + return (pte1 & MMU_DESCRIPTOR_L1_TYPE_MASK) == MMU_DESCRIPTOR_L1_TYPE_INVALID; +} + +STATIC INLINE BOOL OsIsPte1Section(PTE_T pte1) +{ + return (pte1 & MMU_DESCRIPTOR_L1_TYPE_MASK) == MMU_DESCRIPTOR_L1_TYPE_SECTION; +} + +STATIC INLINE UINT32 OsGetPte2Index(vaddr_t va) +{ + return (va % MMU_DESCRIPTOR_L1_SMALL_SIZE) >> MMU_DESCRIPTOR_L2_SMALL_SHIFT; +} + +STATIC INLINE PTE_T *OsGetPte2Ptr(PTE_T *pte2BasePtr, vaddr_t va) +{ + return (pte2BasePtr + OsGetPte2Index(va)); +} + +STATIC INLINE PTE_T OsGetPte2(PTE_T *pte2BasePtr, vaddr_t va) +{ + return *(pte2BasePtr + OsGetPte2Index(va)); +} + +STATIC INLINE VOID OsSavePte2(PTE_T *pte2Ptr, PTE_T pte2) +{ + DMB; + *pte2Ptr = pte2; + DSB; +} + +STATIC INLINE UINT32 OsSavePte2Continuous(PTE_T *pte2BasePtr, UINT32 index, PTE_T pte2, UINT32 count) +{ + UINT32 saveCounts = 0; + if (count == 0) { + return 0; + } + + DMB; + do { + pte2BasePtr[index++] = pte2; + count--; + pte2 += MMU_DESCRIPTOR_L2_SMALL_SIZE; + saveCounts++; + } while ((count != 0) && (index != MMU_DESCRIPTOR_L2_NUMBERS_PER_L1)); + DSB; + + return saveCounts; +} + +STATIC INLINE VOID OsClearPte2Continuous(PTE_T *pte2Ptr, UINT32 count) +{ + UINT32 index = 0; + + DMB; + while (count > 0) { + pte2Ptr[index++] = 0; + count--; + } + DSB; +} + +STATIC INLINE BOOL OsIsPte2SmallPage(PTE_T pte2) +{ + return (pte2 & MMU_DESCRIPTOR_L2_TYPE_MASK) == MMU_DESCRIPTOR_L2_TYPE_SMALL_PAGE; +} + +STATIC INLINE BOOL OsIsPte2SmallPageXN(PTE_T pte2) +{ + return (pte2 & MMU_DESCRIPTOR_L2_TYPE_MASK) == MMU_DESCRIPTOR_L2_TYPE_SMALL_PAGE_XN; +} + +STATIC INLINE BOOL OsIsPte2LargePage(PTE_T pte2) +{ + return (pte2 & MMU_DESCRIPTOR_L2_TYPE_MASK) == MMU_DESCRIPTOR_L2_TYPE_LARGE_PAGE; +} + +STATIC INLINE BOOL OsIsPte2Invalid(PTE_T pte2) +{ + return (pte2 & MMU_DESCRIPTOR_L2_TYPE_MASK) == MMU_DESCRIPTOR_L2_TYPE_INVALID; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* __LOS_PTE_OPS_H__ */ diff --git a/src/kernel_liteos_a/arch/arm/arm/include/los_tlb_v6.h b/src/kernel_liteos_a/arch/arm/arm/include/los_tlb_v6.h new file mode 100644 index 00000000..cdfa7971 --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/include/los_tlb_v6.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_tlb_v6 MMU TLB v6 + * @ingroup kernel + */ +#ifndef __LOS_TLB_V6_H__ +#define __LOS_TLB_V6_H__ + +#include "los_typedef.h" +#include "arm.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +STATIC INLINE VOID OsArmInvalidateTlbBarrier(VOID) +{ +#ifdef LOSCFG_KERNEL_SMP + OsArmWriteBpiallis(0); +#else + OsArmWriteBpiall(0); +#endif + DSB; + ISB; +} + +STATIC INLINE VOID OsArmInvalidateTlbMvaNoBarrier(VADDR_T va) +{ +#ifdef LOSCFG_KERNEL_SMP + OsArmWriteTlbimvaais(va & 0xfffff000); +#else + OsArmWriteTlbimvaa(va & 0xfffff000); +#endif +} + +STATIC INLINE VOID OsArmInvalidateTlbMvaRangeNoBarrier(VADDR_T start, UINT32 count) +{ + UINT32 index = 0; + + while (count > 0) { + OsArmInvalidateTlbMvaNoBarrier(start + (index << MMU_DESCRIPTOR_L2_SMALL_SHIFT)); + index++; + count--; + } +} + +STATIC INLINE VOID OsCleanTLB(VOID) +{ + UINT32 val = 0; + __asm volatile("mcr p15, 0, %0, c8, c7, 0" : : "r"(val)); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* __LOS_TLB_V6_H__ */ + diff --git a/src/kernel_liteos_a/arch/arm/arm/include/smp.h b/src/kernel_liteos_a/arch/arm/arm/include/smp.h new file mode 100644 index 00000000..bc3b335d --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/include/smp.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _ARCH_SMP_H +#define _ARCH_SMP_H + +#include "los_config.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +struct SmpOps { + INT32 (*SmpCpuOn)(UINT32 cpuNum, UINTPTR startEntry); /* The startEntry is physical addr. */ +}; + +typedef VOID (*ArchCpuStartFunc)(VOID *arg); + +VOID HalArchCpuOn(UINT32 cpuNum, ArchCpuStartFunc func, struct SmpOps *ops, VOID *arg); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _ARCH_SMP_H */ + diff --git a/src/kernel_liteos_a/arch/arm/arm/src/arm_generic_timer.c b/src/kernel_liteos_a/arch/arm/arm/src/arm_generic_timer.c new file mode 100644 index 00000000..4e8a655c --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/src/arm_generic_timer.c @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_hw_pri.h" +#include "los_tick_pri.h" +#include "los_sys_pri.h" +#include "gic_common.h" + +#define STRING_COMB(x, y, z) x ## y ## z + +#ifdef LOSCFG_ARCH_SECURE_MONITOR_MODE +#define TIMER_REG(reg) STRING_COMB(TIMER_REG_, CNTPS, reg) +#else +#define TIMER_REG(reg) STRING_COMB(TIMER_REG_, CNTP, reg) +#endif +#define TIMER_REG_CTL TIMER_REG(_CTL) /* 32 bits */ +#define TIMER_REG_TVAL TIMER_REG(_TVAL) /* 32 bits */ +#define TIMER_REG_CVAL TIMER_REG(_CVAL) /* 64 bits */ +#define TIMER_REG_CT TIMER_REG(CT) /* 64 bits */ + +#ifdef __LP64__ + +#define TIMER_REG_CNTFRQ cntfrq_el0 + +/* CNTP AArch64 registers */ +#define TIMER_REG_CNTP_CTL cntp_ctl_el0 +#define TIMER_REG_CNTP_TVAL cntp_tval_el0 +#define TIMER_REG_CNTP_CVAL cntp_cval_el0 +#define TIMER_REG_CNTPCT cntpct_el0 + +/* CNTPS AArch64 registers */ +#define TIMER_REG_CNTPS_CTL cntps_ctl_el1 +#define TIMER_REG_CNTPS_TVAL cntps_tval_el1 +#define TIMER_REG_CNTPS_CVAL cntps_cval_el1 +#define TIMER_REG_CNTPSCT cntpct_el0 + +#define READ_TIMER_REG32(reg) AARCH64_SYSREG_READ(reg) +#define READ_TIMER_REG64(reg) AARCH64_SYSREG_READ(reg) +#define WRITE_TIMER_REG32(reg, val) AARCH64_SYSREG_WRITE(reg, (UINT64)(val)) +#define WRITE_TIMER_REG64(reg, val) AARCH64_SYSREG_WRITE(reg, val) + +#else /* Aarch32 */ + +#define TIMER_REG_CNTFRQ CP15_REG(c14, 0, c0, 0) + +/* CNTP AArch32 registers */ +#define TIMER_REG_CNTP_CTL CP15_REG(c14, 0, c2, 1) +#define TIMER_REG_CNTP_TVAL CP15_REG(c14, 0, c2, 0) +#define TIMER_REG_CNTP_CVAL CP15_REG64(c14, 2) +#define TIMER_REG_CNTPCT CP15_REG64(c14, 0) + +/* CNTPS AArch32 registers are banked and accessed though CNTP */ +#define CNTPS CNTP + +#define READ_TIMER_REG32(reg) ARM_SYSREG_READ(reg) +#define READ_TIMER_REG64(reg) ARM_SYSREG64_READ(reg) +#define WRITE_TIMER_REG32(reg, val) ARM_SYSREG_WRITE(reg, val) +#define WRITE_TIMER_REG64(reg, val) ARM_SYSREG64_WRITE(reg, val) + +#endif + +UINT32 HalClockFreqRead(VOID) +{ + return READ_TIMER_REG32(TIMER_REG_CNTFRQ); +} + +VOID HalClockFreqWrite(UINT32 freq) +{ + WRITE_TIMER_REG32(TIMER_REG_CNTFRQ, freq); +} + +STATIC_INLINE VOID TimerCtlWrite(UINT32 cntpCtl) +{ + WRITE_TIMER_REG32(TIMER_REG_CTL, cntpCtl); +} + +STATIC_INLINE UINT64 TimerCvalRead(VOID) +{ + return READ_TIMER_REG64(TIMER_REG_CVAL); +} + +STATIC_INLINE VOID TimerCvalWrite(UINT64 cval) +{ + WRITE_TIMER_REG64(TIMER_REG_CVAL, cval); +} + +STATIC_INLINE VOID TimerTvalWrite(UINT32 tval) +{ + WRITE_TIMER_REG32(TIMER_REG_TVAL, tval); +} + +UINT64 HalClockGetCycles(VOID) +{ + UINT64 cntpct; + + cntpct = READ_TIMER_REG64(TIMER_REG_CT); + return cntpct; +} + +LITE_OS_SEC_TEXT_INIT VOID HalClockInit(VOID) +{ + UINT32 ret; + + g_sysClock = HalClockFreqRead(); + ret = LOS_HwiCreate(OS_TICK_INT_NUM, MIN_INTERRUPT_PRIORITY, 0, OsTickHandler, 0); + if (ret != LOS_OK) { + PRINT_ERR("%s, %d create tick irq failed, ret:0x%x\n", __FUNCTION__, __LINE__, ret); + } +} + +LITE_OS_SEC_TEXT_INIT VOID HalClockStart(VOID) +{ + HalIrqUnmask(OS_TICK_INT_NUM); + + /* triggle the first tick */ + TimerCtlWrite(0); + TimerTvalWrite(OS_CYCLE_PER_TICK); + TimerCtlWrite(1); +} + +VOID HalDelayUs(UINT32 usecs) +{ + UINT64 cycles = (UINT64)usecs * g_sysClock / OS_SYS_US_PER_SECOND; + UINT64 deadline = HalClockGetCycles() + cycles; + + while (HalClockGetCycles() < deadline) { + __asm__ volatile ("nop"); + } +} + +DEPRECATED UINT64 hi_sched_clock(VOID) +{ + return LOS_CurrNanosec(); +} + +UINT32 HalClockGetTickTimerCycles(VOID) +{ + UINT64 cval = TimerCvalRead(); + UINT64 cycles = HalClockGetCycles(); + + return (UINT32)((cval > cycles) ? (cval - cycles) : 0); +} + +UINT64 HalClockTickTimerReload(UINT64 cycles) +{ + HalIrqMask(OS_TICK_INT_NUM); + HalIrqClear(OS_TICK_INT_NUM); + + TimerCtlWrite(0); + TimerCvalWrite(HalClockGetCycles() + cycles); + TimerCtlWrite(1); + + HalIrqUnmask(OS_TICK_INT_NUM); + return cycles; +} diff --git a/src/kernel_liteos_a/arch/arm/arm/src/armv7a/cache.S b/src/kernel_liteos_a/arch/arm/arm/src/armv7a/cache.S new file mode 100644 index 00000000..0970d453 --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/src/armv7a/cache.S @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "asm.h" + + .fpu vfpv4 + .arch armv7a +.macro DCACHE_LINE_SIZE, reg, tmp + mrc p15, 0, \tmp, c0, c0, 1 + lsr \tmp, \tmp, #16 + and \tmp, \tmp, #0xf + mov \reg, #4 + mov \reg, \reg, lsl \tmp +.endm + + +FUNCTION(arm_inv_cache_range) + push {r2, r3} + DCACHE_LINE_SIZE r2, r3 + sub r3, r2, #1 + tst r0, r3 + bic r0, r0, r3 + + mcrne p15, 0, r0, c7, c14, 1 + + tst r1, r3 + bic r1, r1, r3 + mcrne p15, 0, r1, c7, c14, 1 +1: + mcr p15, 0, r0, c7, c6, 1 + add r0, r0, r2 + cmp r0, r1 + blo 1b + dsb + pop {r2, r3} + mov pc, lr + +FUNCTION(arm_clean_cache_range) + push {r2, r3} + DCACHE_LINE_SIZE r2, r3 + sub r3, r2, #1 + bic r0, r0, r3 + +1: + mcr p15, 0, r0, c7, c10, 1 + add r0, r0, r2 + cmp r0, r1 + blo 1b + dsb + pop {r2, r3} + mov pc, lr diff --git a/src/kernel_liteos_a/arch/arm/arm/src/clear_user.S b/src/kernel_liteos_a/arch/arm/arm/src/clear_user.S new file mode 100644 index 00000000..907a5041 --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/src/clear_user.S @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "asm.h" + +.syntax unified +.arm + +// size_t _arm_clear_user(void *addr, size_t bytes) +FUNCTION(_arm_clear_user) + push {r0-r6, lr} + cmp r1, #0 + beq .Lclear_user_return + tst r0, #7 + beq .Lclear_user_aligned + +.Lclear_user_byte: + mov r2, #0 +0: strb r2, [r0], #1 + subs r1, r1, #1 + beq .Lclear_user_return + tst r0, #7 + bne 0b + +.Lclear_user_aligned: + eor r3, r3 + eor r4, r4 + bics r2, r1, #15 + bne .Lclear_user_16bytes + bics r2, r1, #7 + bne .Lclear_user_8bytes + b .Lclear_user_remaining + +.Lclear_user_16bytes: + eor r5, r5 + eor r6, r6 +1: stmia r0!, {r3, r4, r5, r6} + subs r2, r2, #16 + bne 1b + ands r1, r1, #15 + beq .Lclear_user_return + bics r2, r1, #7 + beq .Lclear_user_remaining + +.Lclear_user_8bytes: +2: stmia r0!, {r3, r4} + ands r1, r1, #7 + beq .Lclear_user_return + +.Lclear_user_remaining: + mov r2, #0 +3: strb r2, [r0], #1 + subs r1, r1, #1 + bne 3b + +.Lclear_user_return: + pop {r0-r6, lr} + mov r0, #0 + bx lr + +.Lclear_user_err: + pop {r0, r1} + sub r0, r2, r0 + sub r0, r1, r0 + pop {r2-r6, lr} + bx lr + +.pushsection __exc_table, "a" + .long 0b, .Lclear_user_err + .long 1b, .Lclear_user_err + .long 2b, .Lclear_user_err + .long 3b, .Lclear_user_err +.popsection diff --git a/src/kernel_liteos_a/arch/arm/arm/src/hw_user_get.S b/src/kernel_liteos_a/arch/arm/arm/src/hw_user_get.S new file mode 100644 index 00000000..169cbf9e --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/src/hw_user_get.S @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "asm.h" + +.syntax unified +.arm + +// errno_t _arm_get_user(void *dst, const void *src, size_t dstTypeLen, size_t srcTypeLen) +FUNCTION(_arm_get_user) + stmdb sp!, {r0, r1, r2, r3, lr} + cmp r2, #0 + beq .Lget_user_return + cmp r2, r3 + bne .Lget_user_err + cmp r2, #1 + bhi .Lget_user_half +.Lget_user_byte: +0: ldrbt r3, [r1], #0 +1: strb r3, [r0], #0 + b .Lget_user_return +.Lget_user_half: + cmp r2, #2 + bhi .Lget_user_word +2: ldrht r3, [r1], #0 +3: strh r3, [r0], #0 + b .Lget_user_return +.Lget_user_word: + cmp r2, #4 + bhi .Lget_user_err +4: ldrt r3, [r1], #0 +5: str r3, [r0], #0 +.Lget_user_return: + ldmia sp!, {r0, r1, r2, r3, lr} + mov r0, 0 + bx lr +.Lget_user_err: + ldmia sp!, {r0, r1, r2, r3, lr} + mov r0, #-14 + bx lr + +.pushsection __exc_table, "a" + .long 0b, .Lget_user_err + .long 1b, .Lget_user_err + .long 2b, .Lget_user_err + .long 3b, .Lget_user_err + .long 4b, .Lget_user_err + .long 5b, .Lget_user_err +.popsection diff --git a/src/kernel_liteos_a/arch/arm/arm/src/hw_user_put.S b/src/kernel_liteos_a/arch/arm/arm/src/hw_user_put.S new file mode 100644 index 00000000..e463addd --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/src/hw_user_put.S @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "asm.h" + +.syntax unified +.arm + +// errno_t _arm_put_user(void *dst, const void *src, size_t dstTypeLen, size_t srcTypeLen) +FUNCTION(_arm_put_user) + stmdb sp!, {r0, r1, r2, r3, lr} + cmp r2, #0 + beq .Lget_user_return + cmp r2, r3 + bne .Lget_user_err + cmp r2, #1 + bhi .Lget_user_half +.Lget_user_byte: +0: ldrb r3, [r1], #0 +1: strbt r3, [r0], #0 + b .Lget_user_return +.Lget_user_half: + cmp r2, #2 + bhi .Lget_user_word +2: ldrh r3, [r1], #0 +3: strht r3, [r0], #0 + b .Lget_user_return +.Lget_user_word: + cmp r2, #4 + bhi .Lget_user_err +4: ldr r3, [r1], #0 +5: strt r3, [r0], #0 +.Lget_user_return: + ldmia sp!, {r0, r1, r2, r3, lr} + mov r0, 0 + bx lr +.Lget_user_err: + ldmia sp!, {r0, r1, r2, r3, lr} + mov r0, #-14 + bx lr + +.pushsection __exc_table, "a" + .long 0b, .Lget_user_err + .long 1b, .Lget_user_err + .long 2b, .Lget_user_err + .long 3b, .Lget_user_err + .long 4b, .Lget_user_err + .long 5b, .Lget_user_err +.popsection diff --git a/src/kernel_liteos_a/arch/arm/arm/src/include/armv7_pmu_pri.h b/src/kernel_liteos_a/arch/arm/arm/src/include/armv7_pmu_pri.h new file mode 100644 index 00000000..cb712f45 --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/src/include/armv7_pmu_pri.h @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _ARMV7_PMU_PRI_H +#define _ARMV7_PMU_PRI_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/* counters overflow flag status reg */ +#define ARMV7_FLAG_MASK 0xffffffff /* Mask for writable bits */ +#define ARMV7_OVERFLOWED_MASK ARMV7_FLAG_MASK /* Mask for pmu overflowed */ + +/* pmnc config reg */ +#define ARMV7_PMNC_E (1U << 0) /* Enable all counters */ +#define ARMV7_PMNC_P (1U << 1) /* Reset all counters */ +#define ARMV7_PMNC_C (1U << 2) /* Cycle counter reset */ +#define ARMV7_PMNC_D (1U << 3) /* CCNT counts every 64th cpu cycle */ +#define ARMV7_PMNC_X (1U << 4) /* Export to ETM */ +#define ARMV7_PMNC_DP (1U << 5) /* Disable CCNT if non-invasive debug */ +#define ARMV7_PMNC_MASK 0x3f /* Mask for writable bits */ + +/* pmxevtyper event selection reg */ +#define ARMV7_EVTYPE_MASK 0xc80000ff /* Mask for writable bits */ + +/* armv7 counters index */ +#define ARMV7_IDX_COUNTER0 1 +#define ARMV7_IDX_CYCLE_COUNTER 0 +#define ARMV7_IDX_MAX_COUNTER 9 + +#define ARMV7_MAX_COUNTERS 32 +#define ARMV7_IDX_COUNTER_LAST (ARMV7_IDX_CYCLE_COUNTER + ARMV7_MAX_COUNTERS - 1) +#define ARMV7_COUNTER_MASK (ARMV7_MAX_COUNTERS - 1) + +/* armv7 event counter index mapping */ +#define ARMV7_CNT2BIT(x) (1UL << (x)) +#define ARMV7_IDX2CNT(x) (((x) - ARMV7_IDX_COUNTER0) & ARMV7_COUNTER_MASK) + +enum PmuEventType { + ARMV7_PERF_HW_CYCLES = 0xFF, /* cycles */ + ARMV7_PERF_HW_INSTRUCTIONS = 0x08, /* instructions */ + ARMV7_PERF_HW_DCACHES = 0x04, /* dcache */ + ARMV7_PERF_HW_DCACHE_MISSES = 0x03, /* dcache-misses */ + ARMV7_PERF_HW_ICACHES = 0x14, /* icache */ + ARMV7_PERF_HW_ICACHE_MISSES = 0x01, /* icache-misses */ + ARMV7_PERF_HW_BRANCHES = 0x0C, /* software change of pc */ + ARMV7_PERF_HW_BRANCE_MISSES = 0x10, /* branch-misses */ + ARMV7_PERF_HW_PRED_BRANCH = 0x12, /* predictable branches */ + ARMV7_PERF_HW_NUM_CYC_IRQ = 0x50, /* number of cycles Irqs are interrupted */ + ARMV7_PERF_HW_EXC_TAKEN = 0x09, /* exception_taken */ + ARMV7_PERF_HW_DATA_READ = 0x06, /* data read */ + ARMV7_PERF_HW_DATA_WRITE = 0x07, /* data write */ + ARMV7_PERF_HW_STREX_PASSED = 0x80, /* strex passed */ + ARMV7_PERF_HW_STREX_FAILED = 0x81, /* strex failed */ + ARMV7_PERF_HW_LP_IN_TCM = 0x82, /* literal pool in TCM region */ + ARMV7_PERF_HW_DMB_STALL = 0x90, /* DMB stall */ + ARMV7_PERF_HW_ITCM_ACCESS = 0x91, /* ITCM access */ + ARMV7_PERF_HW_DTCM_ACCESS = 0x92, /* DTCM access */ + ARMV7_PERF_HW_DATA_EVICTION = 0x93, /* data eviction */ + ARMV7_PERF_HW_SCU = 0x94, /* SCU coherency operation */ + ARMV7_PERF_HW_INSCACHE_DEP_DW = 0x95, /* instruction cache dependent stall */ + ARMV7_PERF_HW_DATA_CACHE_DEP_STALL = 0x96, /* data cache dependent stall */ + ARMV7_PERF_HW_NOCACHE_NO_PER_DEP_STALL = 0x97, /* non-cacheable no peripheral dependent stall */ + ARMV7_PERF_HW_NOCACHE_PER_DEP_STALL = 0x98, /* non-Cacheable peripheral dependent stall */ + ARMV7_PERF_HW_DATA_CACHE_HP_DEP_STALL = 0x99, /* data cache high priority dependent stall */ + ARMV7_PERF_HW_AXI_FAST_PERIPHERAL = 0x9A, /* Accesses_to_AXI_fast_peripheral_port(reads_and_writes) */ +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _ARMV7_PMU_PRI_H */ diff --git a/src/kernel_liteos_a/arch/arm/arm/src/include/asm.h b/src/kernel_liteos_a/arch/arm/arm/src/include/asm.h new file mode 100644 index 00000000..b58871f8 --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/src/include/asm.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __ASM_H +#define __ASM_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define FUNCTION(x) .global x; .text; .code 32; x: +#define MPIDR_CPUID_MASK 0xFFU + +/* + * ------------------------------------------ + * stackTop | cpu n | ... | cpu 1 | cpu 0 | stackBottom + * ------------------------------------------ + * | stackSize | ... | stackSize | stackSize | + */ +.macro EXC_SP_SET stackBottom, stackSize, reg0, reg1 + mrc p15, 0, \reg0, c0, c0, 5 + and \reg0, \reg0, #MPIDR_CPUID_MASK /* get cpu id */ + mov \reg1, #\stackSize + mul \reg1, \reg1, \reg0 /* calculate current cpu stack offset */ + ldr \reg0, =\stackBottom + sub \reg0, \reg0, \reg1 /* calculate current cpu stack bottom */ + mov sp, \reg0 /* set sp */ +.endm + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* __ASM_H */ diff --git a/src/kernel_liteos_a/arch/arm/arm/src/include/los_exc_pri.h b/src/kernel_liteos_a/arch/arm/arm/src/include/los_exc_pri.h new file mode 100644 index 00000000..da9796da --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/src/include/los_exc_pri.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_EXC_PRI_H +#define _LOS_EXC_PRI_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define OS_SYSTEM_NORMAL 0 +#define OS_SYSTEM_EXC_CURR_CPU 1 +#define OS_SYSTEM_EXC_OTHER_CPU 2 + +#define REGION_PATH_MAX 32 + +typedef struct { +#ifdef LOSCFG_KERNEL_VM + UINTPTR ip; + UINT32 len; /* f_path length */ + CHAR f_path[REGION_PATH_MAX]; +#else + UINTPTR ip; +#endif +} IpInfo; + +extern UINT32 OsGetSystemStatus(VOID); +extern VOID BackTraceSub(UINTPTR regFP); +extern VOID OsExcInit(VOID); +extern BOOL OsSystemExcIsReset(VOID); +extern UINT32 BackTraceGet(UINTPTR regFP, IpInfo *callChain, UINT32 maxDepth); +extern BOOL OsGetUsrIpInfo(UINTPTR ip, IpInfo *info); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_EXC_PRI_H */ diff --git a/src/kernel_liteos_a/arch/arm/arm/src/include/los_hw_pri.h b/src/kernel_liteos_a/arch/arm/arm/src/include/los_hw_pri.h new file mode 100644 index 00000000..08e9e6bb --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/src/include/los_hw_pri.h @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_HW_PRI_H +#define _LOS_HW_PRI_H + +#include "los_base.h" +#include "los_hw.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#if defined(LOSCFG_ARCH_FPU_VFP_D16) +#define FP_REGS_NUM 16 +#elif defined (LOSCFG_ARCH_FPU_VFP_D32) +#define FP_REGS_NUM 32 +#endif +#define GEN_REGS_NUM 13 + +/* The size of this structure must be smaller than or equal to the size specified by OS_TSK_STACK_ALIGN (16 bytes). */ +typedef struct { +#if !defined(LOSCFG_ARCH_FPU_DISABLE) + UINT64 D[FP_REGS_NUM]; /* D0-D31 */ + UINT32 regFPSCR; /* FPSCR */ + UINT32 regFPEXC; /* FPEXC */ +#endif + UINT32 R4; + UINT32 R5; + UINT32 R6; + UINT32 R7; + UINT32 R8; + UINT32 R9; + UINT32 R10; + UINT32 R11; + + /* It has the same structure as IrqContext */ + UINT32 reserved2; /**< Multiplexing registers, used in interrupts and system calls but with different meanings */ + UINT32 reserved1; /**< Multiplexing registers, used in interrupts and system calls but with different meanings */ + UINT32 USP; /**< User mode sp register */ + UINT32 ULR; /**< User mode lr register */ + UINT32 R0; + UINT32 R1; + UINT32 R2; + UINT32 R3; + UINT32 R12; + UINT32 LR; + UINT32 PC; + UINT32 regCPSR; +} TaskContext; + +typedef struct { + UINT32 reserved2; /**< Multiplexing registers, used in interrupts and system calls but with different meanings */ + UINT32 reserved1; /**< Multiplexing registers, used in interrupts and system calls but with different meanings */ + UINT32 USP; /**< User mode sp register */ + UINT32 ULR; /**< User mode lr register */ + UINT32 R0; + UINT32 R1; + UINT32 R2; + UINT32 R3; + UINT32 R12; + UINT32 LR; + UINT32 PC; + UINT32 regCPSR; +} IrqContext; + +/* + * Description : task stack initialization + * Input : taskID -- task ID + * stackSize -- task stack size + * topStack -- stack top of task (low address) + * Return : pointer to the task context + */ +extern VOID *OsTaskStackInit(UINT32 taskID, UINT32 stackSize, VOID *topStack, BOOL initFlag); +extern VOID OsUserCloneParentStack(VOID *childStack, UINTPTR sp, UINTPTR parentTopOfStask, UINT32 parentStackSize); +extern VOID OsUserTaskStackInit(TaskContext *context, UINTPTR taskEntry, UINTPTR stack); +extern VOID OsInitSignalContext(const VOID *sp, VOID *signalContext, UINTPTR sigHandler, UINT32 signo, UINT32 param); +extern void arm_clean_cache_range(UINTPTR start, UINTPTR end); +extern void arm_inv_cache_range(UINTPTR start, UINTPTR end); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_HW_PRI_H */ diff --git a/src/kernel_liteos_a/arch/arm/arm/src/include/los_hwi_pri.h b/src/kernel_liteos_a/arch/arm/arm/src/include/los_hwi_pri.h new file mode 100644 index 00000000..e0b62adb --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/src/include/los_hwi_pri.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_HWI_PRI_H +#define _LOS_HWI_PRI_H + +#include "los_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_hwi + * The hwi form does not contain exceptions for Aarch32 + */ +#define OS_HWI_FORM_EXC_NUM 0 +#if OS_HWI_FORM_EXC_NUM != 0 +#error "OS_HWI_FORM_EXC_NUM must be zero" +#endif + +#ifdef LOSCFG_NO_SHARED_IRQ +#define HWI_IS_REGISTED(num) ((&g_hwiForm[num])->pfnHook != NULL) +#else +#define HWI_IS_REGISTED(num) ((&g_hwiForm[num])->pstNext != NULL) +#endif +extern VOID OsHwiInit(VOID); +extern VOID OsIncHwiFormCnt(UINT16 cpuid, UINT32 index); +extern UINT32 OsGetHwiFormCnt(UINT16 cpuid, UINT32 index); +extern CHAR *OsGetHwiFormName(UINT32 index); +extern VOID OsInterrupt(UINT32 intNum); +extern VOID OsSyscallHandleInit(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ +#endif /* _LOS_HWI_PRI_H */ diff --git a/src/kernel_liteos_a/arch/arm/arm/src/jmp.S b/src/kernel_liteos_a/arch/arm/arm/src/jmp.S new file mode 100644 index 00000000..14dd05a3 --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/src/jmp.S @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "asm.h" + +FUNCTION(longjmp) + ldmfd r0,{r4-r12} + add r0,#(4 * 9) + ldr r13,[r0] + add r0,#4 + ldr r14,[r0] + cmp r1,#0 + moveq r1,#1 + mov r0,r1 + mov pc,lr + +FUNCTION(setjmp) + stmea r0,{r4-r12} + add r0,#(4 * 9) + str r13,[r0] + add r0,#4 + str r14,[r0] + mov r0,#0 + mov pc,lr diff --git a/src/kernel_liteos_a/arch/arm/arm/src/los_arch_mmu.c b/src/kernel_liteos_a/arch/arm/arm/src/los_arch_mmu.c new file mode 100644 index 00000000..04f58204 --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/src/los_arch_mmu.c @@ -0,0 +1,1139 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_arch_mmu architecture mmu + * @ingroup kernel + */ + +#include "los_arch_mmu.h" +#include "los_asid.h" +#include "los_pte_ops.h" +#include "los_tlb_v6.h" +#include "los_printf.h" +#include "los_vm_common.h" +#include "los_vm_map.h" +#include "los_vm_boot.h" +#include "los_mmu_descriptor_v6.h" +#include "los_process_pri.h" + +#ifdef LOSCFG_KERNEL_MMU +typedef struct { + LosArchMmu *archMmu; + VADDR_T *vaddr; + PADDR_T *paddr; + UINT32 *flags; +} MmuMapInfo; + +#define TRY_MAX_TIMES 10 + +__attribute__((aligned(MMU_DESCRIPTOR_L1_SMALL_ENTRY_NUMBERS))) \ + __attribute__((section(".bss.prebss.translation_table"))) UINT8 \ + g_firstPageTable[MMU_DESCRIPTOR_L1_SMALL_ENTRY_NUMBERS]; +#ifdef LOSCFG_KERNEL_SMP +__attribute__((aligned(MMU_DESCRIPTOR_L1_SMALL_ENTRY_NUMBERS))) \ + __attribute__((section(".bss.prebss.translation_table"))) UINT8 \ + g_tempPageTable[MMU_DESCRIPTOR_L1_SMALL_ENTRY_NUMBERS]; +UINT8 *g_mmuJumpPageTable = g_tempPageTable; +#else +extern CHAR __mmu_ttlb_begin; /* defined in .ld script */ +UINT8 *g_mmuJumpPageTable = (UINT8 *)&__mmu_ttlb_begin; /* temp page table, this is only used when system power up */ +#endif + +STATIC SPIN_LOCK_S *OsGetPteLock(LosArchMmu *archMmu, PADDR_T paddr, UINT32 *intSave) +{ + SPIN_LOCK_S *lock = NULL; +#ifdef LOSCFG_PAGE_TABLE_FINE_LOCK + LosVmPage *vmPage = NULL; + + vmPage = OsVmPaddrToPage(paddr); + if (vmPage == NULL) { + return NULL; + } + lock = &vmPage->lock; +#else + lock = &archMmu->lock; +#endif + + LOS_SpinLockSave(lock, intSave); + return lock; +} + +STATIC SPIN_LOCK_S *OsGetPte1Lock(LosArchMmu *archMmu, PADDR_T paddr, UINT32 *intSave) +{ + return OsGetPteLock(archMmu, paddr, intSave); +} + +STATIC INLINE VOID OsUnlockPte1(SPIN_LOCK_S *lock, UINT32 intSave) +{ + if (lock == NULL) { + return; + } + LOS_SpinUnlockRestore(lock, intSave); +} + +STATIC SPIN_LOCK_S *OsGetPte1LockTmp(LosArchMmu *archMmu, PADDR_T paddr, UINT32 *intSave) +{ + SPIN_LOCK_S *spinLock = NULL; +#ifdef LOSCFG_PAGE_TABLE_FINE_LOCK + spinLock = OsGetPteLock(archMmu, paddr, intSave); +#else + (VOID)archMmu; + (VOID)paddr; + (VOID)intSave; +#endif + return spinLock; +} + +STATIC INLINE VOID OsUnlockPte1Tmp(SPIN_LOCK_S *lock, UINT32 intSave) +{ +#ifdef LOSCFG_PAGE_TABLE_FINE_LOCK + if (lock == NULL) { + return; + } + LOS_SpinUnlockRestore(lock, intSave); +#else + (VOID)lock; + (VOID)intSave; +#endif +} + +STATIC INLINE SPIN_LOCK_S *OsGetPte2Lock(LosArchMmu *archMmu, PTE_T pte1, UINT32 *intSave) +{ + PADDR_T pa = MMU_DESCRIPTOR_L1_PAGE_TABLE_ADDR(pte1); + return OsGetPteLock(archMmu, pa, intSave); +} + +STATIC INLINE VOID OsUnlockPte2(SPIN_LOCK_S *lock, UINT32 intSave) +{ + return OsUnlockPte1(lock, intSave); +} + +STATIC INLINE PTE_T *OsGetPte2BasePtr(PTE_T pte1) +{ + PADDR_T pa = MMU_DESCRIPTOR_L1_PAGE_TABLE_ADDR(pte1); + return LOS_PaddrToKVaddr(pa); +} + +VADDR_T *OsGFirstTableGet(VOID) +{ + return (VADDR_T *)g_firstPageTable; +} + +STATIC INLINE UINT32 OsUnmapL1Invalid(vaddr_t *vaddr, UINT32 *count) +{ + UINT32 unmapCount; + + unmapCount = MIN2((MMU_DESCRIPTOR_L1_SMALL_SIZE - (*vaddr % MMU_DESCRIPTOR_L1_SMALL_SIZE)) >> + MMU_DESCRIPTOR_L2_SMALL_SHIFT, *count); + *vaddr += unmapCount << MMU_DESCRIPTOR_L2_SMALL_SHIFT; + *count -= unmapCount; + + return unmapCount; +} + +STATIC INT32 OsMapParamCheck(UINT32 flags, VADDR_T vaddr, PADDR_T paddr) +{ +#if !WITH_ARCH_MMU_PICK_SPOT + if (flags & VM_MAP_REGION_FLAG_NS) { + /* WITH_ARCH_MMU_PICK_SPOT is required to support NS memory */ + LOS_Panic("NS mem is not supported\n"); + } +#endif + + /* paddr and vaddr must be aligned */ + if (!MMU_DESCRIPTOR_IS_L2_SIZE_ALIGNED(vaddr) || !MMU_DESCRIPTOR_IS_L2_SIZE_ALIGNED(paddr)) { + return LOS_ERRNO_VM_INVALID_ARGS; + } + + return 0; +} + +STATIC VOID OsCvtPte2AttsToFlags(PTE_T l1Entry, PTE_T l2Entry, UINT32 *flags) +{ + *flags = 0; + /* NS flag is only present on L1 entry */ + if (l1Entry & MMU_DESCRIPTOR_L1_PAGETABLE_NON_SECURE) { + *flags |= VM_MAP_REGION_FLAG_NS; + } + + switch (l2Entry & MMU_DESCRIPTOR_L2_TEX_TYPE_MASK) { + case MMU_DESCRIPTOR_L2_TYPE_STRONGLY_ORDERED: + *flags |= VM_MAP_REGION_FLAG_STRONGLY_ORDERED; + break; + case MMU_DESCRIPTOR_L2_TYPE_NORMAL_NOCACHE: + *flags |= VM_MAP_REGION_FLAG_UNCACHED; + break; + case MMU_DESCRIPTOR_L2_TYPE_DEVICE_SHARED: + case MMU_DESCRIPTOR_L2_TYPE_DEVICE_NON_SHARED: + *flags |= VM_MAP_REGION_FLAG_UNCACHED_DEVICE; + break; + default: + break; + } + + *flags |= VM_MAP_REGION_FLAG_PERM_READ; + + switch (l2Entry & MMU_DESCRIPTOR_L2_AP_MASK) { + case MMU_DESCRIPTOR_L2_AP_P_RO_U_NA: + break; + case MMU_DESCRIPTOR_L2_AP_P_RW_U_NA: + *flags |= VM_MAP_REGION_FLAG_PERM_WRITE; + break; + case MMU_DESCRIPTOR_L2_AP_P_RO_U_RO: + *flags |= VM_MAP_REGION_FLAG_PERM_USER; + break; + case MMU_DESCRIPTOR_L2_AP_P_RW_U_RW: + *flags |= VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_WRITE; + break; + default: + break; + } + if ((l2Entry & MMU_DESCRIPTOR_L2_TYPE_MASK) != MMU_DESCRIPTOR_L2_TYPE_SMALL_PAGE_XN) { + *flags |= VM_MAP_REGION_FLAG_PERM_EXECUTE; + } +} + +STATIC VOID OsPutL2Table(const LosArchMmu *archMmu, UINT32 l1Index, paddr_t l2Paddr) +{ + UINT32 index; + PTE_T ttEntry; + /* check if any l1 entry points to this l2 table */ + for (index = 0; index < MMU_DESCRIPTOR_L1_SMALL_L2_TABLES_PER_PAGE; index++) { + ttEntry = archMmu->virtTtb[ROUNDDOWN(l1Index, MMU_DESCRIPTOR_L1_SMALL_L2_TABLES_PER_PAGE) + index]; + if ((ttEntry & MMU_DESCRIPTOR_L1_TYPE_MASK) == MMU_DESCRIPTOR_L1_TYPE_PAGE_TABLE) { + return; + } + } +#ifdef LOSCFG_KERNEL_VM + /* we can free this l2 table */ + LosVmPage *vmPage = LOS_VmPageGet(l2Paddr); + if (vmPage == NULL) { + LOS_Panic("bad page table paddr %#x\n", l2Paddr); + return; + } + + LOS_ListDelete(&vmPage->node); + LOS_PhysPageFree(vmPage); +#else + (VOID)LOS_MemFree(OS_SYS_MEM_ADDR, LOS_PaddrToKVaddr(l2Paddr)); +#endif +} + +STATIC VOID OsTryUnmapL1PTE(LosArchMmu *archMmu, PTE_T *l1Entry, vaddr_t vaddr, UINT32 scanIndex, UINT32 scanCount) +{ + /* + * Check if all pages related to this l1 entry are deallocated. + * We only need to check pages that we did not clear above starting + * from scanIndex and wrapped around SECTION. + */ + UINT32 l1Index; + PTE_T *pte2BasePtr = NULL; + SPIN_LOCK_S *pte1Lock = NULL; + SPIN_LOCK_S *pte2Lock = NULL; + UINT32 pte1IntSave; + UINT32 pte2IntSave; + PTE_T pte1Val; + PADDR_T pte1Paddr; + + pte1Paddr = OsGetPte1Paddr(archMmu->physTtb, vaddr); + pte2Lock = OsGetPte2Lock(archMmu, *l1Entry, &pte2IntSave); + if (pte2Lock == NULL) { + return; + } + pte2BasePtr = OsGetPte2BasePtr(*l1Entry); + if (pte2BasePtr == NULL) { + OsUnlockPte2(pte2Lock, pte2IntSave); + return; + } + + while (scanCount) { + if (scanIndex == MMU_DESCRIPTOR_L2_NUMBERS_PER_L1) { + scanIndex = 0; + } + if (pte2BasePtr[scanIndex++]) { + break; + } + scanCount--; + } + + if (!scanCount) { + /* + * The pte1 of kprocess is placed in kernel image when compiled. So the pte1Lock will be null. + * There is no situation to simultaneous access the pte1 of kprocess. + */ + pte1Lock = OsGetPte1LockTmp(archMmu, pte1Paddr, &pte1IntSave); + if (!OsIsPte1PageTable(*l1Entry)) { + OsUnlockPte1Tmp(pte1Lock, pte1IntSave); + OsUnlockPte2(pte2Lock, pte2IntSave); + return; + } + pte1Val = *l1Entry; + /* we can kill l1 entry */ + OsClearPte1(l1Entry); + l1Index = OsGetPte1Index(vaddr); + OsArmInvalidateTlbMvaNoBarrier(l1Index << MMU_DESCRIPTOR_L1_SMALL_SHIFT); + + /* try to free l2 page itself */ + OsPutL2Table(archMmu, l1Index, MMU_DESCRIPTOR_L1_PAGE_TABLE_ADDR(pte1Val)); + OsUnlockPte1Tmp(pte1Lock, pte1IntSave); + } + OsUnlockPte2(pte2Lock, pte2IntSave); +} + +STATIC UINT32 OsCvtSecCacheFlagsToMMUFlags(UINT32 flags) +{ + UINT32 mmuFlags = 0; + + switch (flags & VM_MAP_REGION_FLAG_CACHE_MASK) { + case VM_MAP_REGION_FLAG_CACHED: + mmuFlags |= MMU_DESCRIPTOR_L1_TYPE_NORMAL_WRITE_BACK_ALLOCATE; +#ifdef LOSCFG_KERNEL_SMP + mmuFlags |= MMU_DESCRIPTOR_L1_SECTION_SHAREABLE; +#endif + break; + case VM_MAP_REGION_FLAG_STRONGLY_ORDERED: + mmuFlags |= MMU_DESCRIPTOR_L1_TYPE_STRONGLY_ORDERED; + break; + case VM_MAP_REGION_FLAG_UNCACHED: + mmuFlags |= MMU_DESCRIPTOR_L1_TYPE_NORMAL_NOCACHE; + break; + case VM_MAP_REGION_FLAG_UNCACHED_DEVICE: + mmuFlags |= MMU_DESCRIPTOR_L1_TYPE_DEVICE_SHARED; + break; + default: + return LOS_ERRNO_VM_INVALID_ARGS; + } + return mmuFlags; +} + +STATIC UINT32 OsCvtSecAccessFlagsToMMUFlags(UINT32 flags) +{ + UINT32 mmuFlags = 0; + + switch (flags & (VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE)) { + case 0: + mmuFlags |= MMU_DESCRIPTOR_L1_AP_P_NA_U_NA; + break; + case VM_MAP_REGION_FLAG_PERM_READ: + case VM_MAP_REGION_FLAG_PERM_USER: + mmuFlags |= MMU_DESCRIPTOR_L1_AP_P_RO_U_NA; + break; + case VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_READ: + mmuFlags |= MMU_DESCRIPTOR_L1_AP_P_RO_U_RO; + break; + case VM_MAP_REGION_FLAG_PERM_WRITE: + case VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE: + mmuFlags |= MMU_DESCRIPTOR_L1_AP_P_RW_U_NA; + break; + case VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_WRITE: + case VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE: + mmuFlags |= MMU_DESCRIPTOR_L1_AP_P_RW_U_RW; + break; + default: + break; + } + return mmuFlags; +} + +/* convert user level mmu flags to L1 descriptors flags */ +STATIC UINT32 OsCvtSecFlagsToAttrs(UINT32 flags) +{ + UINT32 mmuFlags; + + mmuFlags = OsCvtSecCacheFlagsToMMUFlags(flags); + if (mmuFlags == LOS_ERRNO_VM_INVALID_ARGS) { + return mmuFlags; + } + + mmuFlags |= MMU_DESCRIPTOR_L1_SMALL_DOMAIN_CLIENT; + + mmuFlags |= OsCvtSecAccessFlagsToMMUFlags(flags); + + if (!(flags & VM_MAP_REGION_FLAG_PERM_EXECUTE)) { + mmuFlags |= MMU_DESCRIPTOR_L1_SECTION_XN; + } + + if (flags & VM_MAP_REGION_FLAG_NS) { + mmuFlags |= MMU_DESCRIPTOR_L1_SECTION_NON_SECURE; + } + + if (flags & VM_MAP_REGION_FLAG_PERM_USER) { + mmuFlags |= MMU_DESCRIPTOR_L1_SECTION_NON_GLOBAL; + } + + return mmuFlags; +} + +STATIC VOID OsCvtSecAttsToFlags(PTE_T l1Entry, UINT32 *flags) +{ + *flags = 0; + if (l1Entry & MMU_DESCRIPTOR_L1_SECTION_NON_SECURE) { + *flags |= VM_MAP_REGION_FLAG_NS; + } + + switch (l1Entry & MMU_DESCRIPTOR_L1_TEX_TYPE_MASK) { + case MMU_DESCRIPTOR_L1_TYPE_STRONGLY_ORDERED: + *flags |= VM_MAP_REGION_FLAG_STRONGLY_ORDERED; + break; + case MMU_DESCRIPTOR_L1_TYPE_NORMAL_NOCACHE: + *flags |= VM_MAP_REGION_FLAG_UNCACHED; + break; + case MMU_DESCRIPTOR_L1_TYPE_DEVICE_SHARED: + case MMU_DESCRIPTOR_L1_TYPE_DEVICE_NON_SHARED: + *flags |= VM_MAP_REGION_FLAG_UNCACHED_DEVICE; + break; + default: + break; + } + + *flags |= VM_MAP_REGION_FLAG_PERM_READ; + + switch (l1Entry & MMU_DESCRIPTOR_L1_AP_MASK) { + case MMU_DESCRIPTOR_L1_AP_P_RO_U_NA: + break; + case MMU_DESCRIPTOR_L1_AP_P_RW_U_NA: + *flags |= VM_MAP_REGION_FLAG_PERM_WRITE; + break; + case MMU_DESCRIPTOR_L1_AP_P_RO_U_RO: + *flags |= VM_MAP_REGION_FLAG_PERM_USER; + break; + case MMU_DESCRIPTOR_L1_AP_P_RW_U_RW: + *flags |= VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_WRITE; + break; + default: + break; + } + + if (!(l1Entry & MMU_DESCRIPTOR_L1_SECTION_XN)) { + *flags |= VM_MAP_REGION_FLAG_PERM_EXECUTE; + } +} + +STATIC UINT32 OsUnmapL2PTE(LosArchMmu *archMmu, PTE_T *pte1, vaddr_t vaddr, UINT32 *count) +{ + UINT32 unmapCount; + UINT32 pte2Index; + UINT32 intSave; + PTE_T *pte2BasePtr = NULL; + SPIN_LOCK_S *lock = NULL; + + pte2Index = OsGetPte2Index(vaddr); + unmapCount = MIN2(MMU_DESCRIPTOR_L2_NUMBERS_PER_L1 - pte2Index, *count); + + lock = OsGetPte2Lock(archMmu, *pte1, &intSave); + if (lock == NULL) { + return unmapCount; + } + + pte2BasePtr = OsGetPte2BasePtr(*pte1); + if (pte2BasePtr == NULL) { + OsUnlockPte2(lock, intSave); + return unmapCount; + } + + /* unmap page run */ + OsClearPte2Continuous(&pte2BasePtr[pte2Index], unmapCount); + + /* invalidate tlb */ + OsArmInvalidateTlbMvaRangeNoBarrier(vaddr, unmapCount); + OsUnlockPte2(lock, intSave); + + *count -= unmapCount; + return unmapCount; +} + +STATIC UINT32 OsUnmapSection(LosArchMmu *archMmu, PTE_T *l1Entry, vaddr_t *vaddr, UINT32 *count) +{ + UINT32 intSave; + PADDR_T pte1Paddr; + SPIN_LOCK_S *lock = NULL; + + pte1Paddr = OsGetPte1Paddr(archMmu->physTtb, *vaddr); + lock = OsGetPte1Lock(archMmu, pte1Paddr, &intSave); + if (!OsIsPte1Section(*l1Entry)) { + OsUnlockPte1(lock, intSave); + return 0; + } + OsClearPte1(OsGetPte1Ptr((PTE_T *)archMmu->virtTtb, *vaddr)); + OsArmInvalidateTlbMvaNoBarrier(*vaddr); + OsUnlockPte1(lock, intSave); + + *vaddr += MMU_DESCRIPTOR_L1_SMALL_SIZE; + *count -= MMU_DESCRIPTOR_L2_NUMBERS_PER_L1; + + return MMU_DESCRIPTOR_L2_NUMBERS_PER_L1; +} + +BOOL OsArchMmuInit(LosArchMmu *archMmu, VADDR_T *virtTtb) +{ +#ifdef LOSCFG_KERNEL_VM + if (OsAllocAsid(&archMmu->asid) != LOS_OK) { + VM_ERR("alloc arch mmu asid failed"); + return FALSE; + } +#endif + +#ifndef LOSCFG_PAGE_TABLE_FINE_LOCK + LOS_SpinInit(&archMmu->lock); +#endif + LOS_ListInit(&archMmu->ptList); + archMmu->virtTtb = virtTtb; + archMmu->physTtb = (VADDR_T)(UINTPTR)virtTtb - KERNEL_ASPACE_BASE + SYS_MEM_BASE; + return TRUE; +} + +STATUS_T LOS_ArchMmuQuery(const LosArchMmu *archMmu, VADDR_T vaddr, PADDR_T *paddr, UINT32 *flags) +{ + PTE_T l1Entry = OsGetPte1(archMmu->virtTtb, vaddr); + PTE_T l2Entry; + PTE_T* l2Base = NULL; + + if (OsIsPte1Invalid(l1Entry)) { + return LOS_ERRNO_VM_NOT_FOUND; + } else if (OsIsPte1Section(l1Entry)) { + if (paddr != NULL) { + *paddr = MMU_DESCRIPTOR_L1_SECTION_ADDR(l1Entry) + (vaddr & (MMU_DESCRIPTOR_L1_SMALL_SIZE - 1)); + } + + if (flags != NULL) { + OsCvtSecAttsToFlags(l1Entry, flags); + } + } else if (OsIsPte1PageTable(l1Entry)) { + l2Base = OsGetPte2BasePtr(l1Entry); + if (l2Base == NULL) { + return LOS_ERRNO_VM_NOT_FOUND; + } + l2Entry = OsGetPte2(l2Base, vaddr); + if (OsIsPte2SmallPage(l2Entry) || OsIsPte2SmallPageXN(l2Entry)) { + if (paddr != NULL) { + *paddr = MMU_DESCRIPTOR_L2_SMALL_PAGE_ADDR(l2Entry) + (vaddr & (MMU_DESCRIPTOR_L2_SMALL_SIZE - 1)); + } + + if (flags != NULL) { + OsCvtPte2AttsToFlags(l1Entry, l2Entry, flags); + } + } else if (OsIsPte2LargePage(l2Entry)) { + LOS_Panic("%s %d, large page unimplemented\n", __FUNCTION__, __LINE__); + } else { + return LOS_ERRNO_VM_NOT_FOUND; + } + } + + return LOS_OK; +} + +STATUS_T LOS_ArchMmuUnmap(LosArchMmu *archMmu, VADDR_T vaddr, size_t count) +{ + PTE_T *l1Entry = NULL; + INT32 unmapped = 0; + UINT32 unmapCount = 0; + INT32 tryTime = TRY_MAX_TIMES; + + while (count > 0) { + l1Entry = OsGetPte1Ptr(archMmu->virtTtb, vaddr); + if (OsIsPte1Invalid(*l1Entry)) { + unmapCount = OsUnmapL1Invalid(&vaddr, &count); + } else if (OsIsPte1Section(*l1Entry)) { + if (MMU_DESCRIPTOR_IS_L1_SIZE_ALIGNED(vaddr) && count >= MMU_DESCRIPTOR_L2_NUMBERS_PER_L1) { + unmapCount = OsUnmapSection(archMmu, l1Entry, &vaddr, &count); + } else { + LOS_Panic("%s %d, unimplemented\n", __FUNCTION__, __LINE__); + } + } else if (OsIsPte1PageTable(*l1Entry)) { + unmapCount = OsUnmapL2PTE(archMmu, l1Entry, vaddr, &count); + OsTryUnmapL1PTE(archMmu, l1Entry, vaddr, OsGetPte2Index(vaddr) + unmapCount, + MMU_DESCRIPTOR_L2_NUMBERS_PER_L1); + vaddr += unmapCount << MMU_DESCRIPTOR_L2_SMALL_SHIFT; + } else { + LOS_Panic("%s %d, unimplemented\n", __FUNCTION__, __LINE__); + } + tryTime = (unmapCount == 0) ? (tryTime - 1) : tryTime; + if (tryTime == 0) { + return LOS_ERRNO_VM_FAULT; + } + unmapped += unmapCount; + } + OsArmInvalidateTlbBarrier(); + return unmapped; +} + +STATIC UINT32 OsMapSection(MmuMapInfo *mmuMapInfo, UINT32 *count) +{ + UINT32 mmuFlags = 0; + UINT32 intSave; + PADDR_T pte1Paddr; + SPIN_LOCK_S *lock = NULL; + + mmuFlags |= OsCvtSecFlagsToAttrs(*mmuMapInfo->flags); + pte1Paddr = OsGetPte1Paddr(mmuMapInfo->archMmu->physTtb, *mmuMapInfo->vaddr); + lock = OsGetPte1Lock(mmuMapInfo->archMmu, pte1Paddr, &intSave); + OsSavePte1(OsGetPte1Ptr(mmuMapInfo->archMmu->virtTtb, *mmuMapInfo->vaddr), + OsTruncPte1(*mmuMapInfo->paddr) | mmuFlags | MMU_DESCRIPTOR_L1_TYPE_SECTION); + OsUnlockPte1(lock, intSave); + *count -= MMU_DESCRIPTOR_L2_NUMBERS_PER_L1; + *mmuMapInfo->vaddr += MMU_DESCRIPTOR_L1_SMALL_SIZE; + *mmuMapInfo->paddr += MMU_DESCRIPTOR_L1_SMALL_SIZE; + + return MMU_DESCRIPTOR_L2_NUMBERS_PER_L1; +} + +STATIC STATUS_T OsGetL2Table(LosArchMmu *archMmu, UINT32 l1Index, paddr_t *ppa) +{ + UINT32 index; + PTE_T ttEntry; + VADDR_T *kvaddr = NULL; + UINT32 l2Offset = (MMU_DESCRIPTOR_L2_SMALL_SIZE / MMU_DESCRIPTOR_L1_SMALL_L2_TABLES_PER_PAGE) * + (l1Index & (MMU_DESCRIPTOR_L1_SMALL_L2_TABLES_PER_PAGE - 1)); + /* lookup an existing l2 page table */ + for (index = 0; index < MMU_DESCRIPTOR_L1_SMALL_L2_TABLES_PER_PAGE; index++) { + ttEntry = archMmu->virtTtb[ROUNDDOWN(l1Index, MMU_DESCRIPTOR_L1_SMALL_L2_TABLES_PER_PAGE) + index]; + if ((ttEntry & MMU_DESCRIPTOR_L1_TYPE_MASK) == MMU_DESCRIPTOR_L1_TYPE_PAGE_TABLE) { + *ppa = (PADDR_T)ROUNDDOWN(MMU_DESCRIPTOR_L1_PAGE_TABLE_ADDR(ttEntry), MMU_DESCRIPTOR_L2_SMALL_SIZE) + + l2Offset; + return LOS_OK; + } + } + +#ifdef LOSCFG_KERNEL_VM + /* not found: allocate one (paddr) */ + LosVmPage *vmPage = LOS_PhysPageAlloc(); + if (vmPage == NULL) { + VM_ERR("have no memory to save l2 page"); + return LOS_ERRNO_VM_NO_MEMORY; + } + LOS_ListAdd(&archMmu->ptList, &vmPage->node); + kvaddr = OsVmPageToVaddr(vmPage); +#else + kvaddr = LOS_MemAlloc(OS_SYS_MEM_ADDR, MMU_DESCRIPTOR_L2_SMALL_SIZE); + if (kvaddr == NULL) { + VM_ERR("have no memory to save l2 page"); + return LOS_ERRNO_VM_NO_MEMORY; + } +#endif + (VOID)memset_s(kvaddr, MMU_DESCRIPTOR_L2_SMALL_SIZE, 0, MMU_DESCRIPTOR_L2_SMALL_SIZE); + + /* get physical address */ + *ppa = OsKVaddrToPaddr((VADDR_T)kvaddr) + l2Offset; + return LOS_OK; +} + +STATIC UINT32 OsCvtPte2CacheFlagsToMMUFlags(UINT32 flags) +{ + UINT32 mmuFlags = 0; + + switch (flags & VM_MAP_REGION_FLAG_CACHE_MASK) { + case VM_MAP_REGION_FLAG_CACHED: +#ifdef LOSCFG_KERNEL_SMP + mmuFlags |= MMU_DESCRIPTOR_L2_SHAREABLE; +#endif + mmuFlags |= MMU_DESCRIPTOR_L2_TYPE_NORMAL_WRITE_BACK_ALLOCATE; + break; + case VM_MAP_REGION_FLAG_STRONGLY_ORDERED: + mmuFlags |= MMU_DESCRIPTOR_L2_TYPE_STRONGLY_ORDERED; + break; + case VM_MAP_REGION_FLAG_UNCACHED: + mmuFlags |= MMU_DESCRIPTOR_L2_TYPE_NORMAL_NOCACHE; + break; + case VM_MAP_REGION_FLAG_UNCACHED_DEVICE: + mmuFlags |= MMU_DESCRIPTOR_L2_TYPE_DEVICE_SHARED; + break; + default: + return LOS_ERRNO_VM_INVALID_ARGS; + } + return mmuFlags; +} + +STATIC UINT32 OsCvtPte2AccessFlagsToMMUFlags(UINT32 flags) +{ + UINT32 mmuFlags = 0; + + switch (flags & (VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE)) { + case 0: + mmuFlags |= MMU_DESCRIPTOR_L1_AP_P_NA_U_NA; + break; + case VM_MAP_REGION_FLAG_PERM_READ: + case VM_MAP_REGION_FLAG_PERM_USER: + mmuFlags |= MMU_DESCRIPTOR_L2_AP_P_RO_U_NA; + break; + case VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_READ: + mmuFlags |= MMU_DESCRIPTOR_L2_AP_P_RO_U_RO; + break; + case VM_MAP_REGION_FLAG_PERM_WRITE: + case VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE: + mmuFlags |= MMU_DESCRIPTOR_L2_AP_P_RW_U_NA; + break; + case VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_WRITE: + case VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE: + mmuFlags |= MMU_DESCRIPTOR_L2_AP_P_RW_U_RW; + break; + default: + break; + } + return mmuFlags; +} + +/* convert user level mmu flags to L2 descriptors flags */ +STATIC UINT32 OsCvtPte2FlagsToAttrs(UINT32 flags) +{ + UINT32 mmuFlags; + + mmuFlags = OsCvtPte2CacheFlagsToMMUFlags(flags); + if (mmuFlags == LOS_ERRNO_VM_INVALID_ARGS) { + return mmuFlags; + } + + mmuFlags |= OsCvtPte2AccessFlagsToMMUFlags(flags); + + if (!(flags & VM_MAP_REGION_FLAG_PERM_EXECUTE)) { + mmuFlags |= MMU_DESCRIPTOR_L2_TYPE_SMALL_PAGE_XN; + } else { + mmuFlags |= MMU_DESCRIPTOR_L2_TYPE_SMALL_PAGE; + } + + if (flags & VM_MAP_REGION_FLAG_PERM_USER) { + mmuFlags |= MMU_DESCRIPTOR_L2_NON_GLOBAL; + } + + return mmuFlags; +} + +STATIC UINT32 OsMapL1PTE(MmuMapInfo *mmuMapInfo, PTE_T *l1Entry, UINT32 *count) +{ + PADDR_T pte2Base = 0; + PADDR_T pte1Paddr; + SPIN_LOCK_S *pte1Lock = NULL; + SPIN_LOCK_S *pte2Lock = NULL; + PTE_T *pte2BasePtr = NULL; + UINT32 saveCounts, archFlags, pte1IntSave, pte2IntSave; + + pte1Paddr = OsGetPte1Paddr(mmuMapInfo->archMmu->physTtb, *mmuMapInfo->vaddr); + pte1Lock = OsGetPte1Lock(mmuMapInfo->archMmu, pte1Paddr, &pte1IntSave); + if (!OsIsPte1Invalid(*l1Entry)) { + OsUnlockPte1(pte1Lock, pte1IntSave); + return 0; + } + if (OsGetL2Table(mmuMapInfo->archMmu, OsGetPte1Index(*mmuMapInfo->vaddr), &pte2Base) != LOS_OK) { + LOS_Panic("%s %d, failed to allocate pagetable\n", __FUNCTION__, __LINE__); + } + + *l1Entry = pte2Base | MMU_DESCRIPTOR_L1_TYPE_PAGE_TABLE; + if (*mmuMapInfo->flags & VM_MAP_REGION_FLAG_NS) { + *l1Entry |= MMU_DESCRIPTOR_L1_PAGETABLE_NON_SECURE; + } + *l1Entry &= MMU_DESCRIPTOR_L1_SMALL_DOMAIN_MASK; + *l1Entry |= MMU_DESCRIPTOR_L1_SMALL_DOMAIN_CLIENT; // use client AP + OsSavePte1(OsGetPte1Ptr(mmuMapInfo->archMmu->virtTtb, *mmuMapInfo->vaddr), *l1Entry); + OsUnlockPte1(pte1Lock, pte1IntSave); + + pte2Lock = OsGetPte2Lock(mmuMapInfo->archMmu, *l1Entry, &pte2IntSave); + if (pte2Lock == NULL) { + LOS_Panic("pte2 should not be null!\n"); + } + pte2BasePtr = (PTE_T *)LOS_PaddrToKVaddr(pte2Base); + + /* compute the arch flags for L2 4K pages */ + archFlags = OsCvtPte2FlagsToAttrs(*mmuMapInfo->flags); + saveCounts = OsSavePte2Continuous(pte2BasePtr, OsGetPte2Index(*mmuMapInfo->vaddr), *mmuMapInfo->paddr | archFlags, + *count); + OsUnlockPte2(pte2Lock, pte2IntSave); + *mmuMapInfo->paddr += (saveCounts << MMU_DESCRIPTOR_L2_SMALL_SHIFT); + *mmuMapInfo->vaddr += (saveCounts << MMU_DESCRIPTOR_L2_SMALL_SHIFT); + *count -= saveCounts; + return saveCounts; +} + +STATIC UINT32 OsMapL2PageContinous(MmuMapInfo *mmuMapInfo, PTE_T *pte1, UINT32 *count) +{ + PTE_T *pte2BasePtr = NULL; + UINT32 archFlags; + UINT32 saveCounts; + UINT32 intSave; + SPIN_LOCK_S *lock = NULL; + + lock = OsGetPte2Lock(mmuMapInfo->archMmu, *pte1, &intSave); + if (lock == NULL) { + return 0; + } + pte2BasePtr = OsGetPte2BasePtr(*pte1); + if (pte2BasePtr == NULL) { + OsUnlockPte2(lock, intSave); + return 0; + } + + /* compute the arch flags for L2 4K pages */ + archFlags = OsCvtPte2FlagsToAttrs(*mmuMapInfo->flags); + saveCounts = OsSavePte2Continuous(pte2BasePtr, OsGetPte2Index(*mmuMapInfo->vaddr), *mmuMapInfo->paddr | archFlags, + *count); + OsUnlockPte2(lock, intSave); + *mmuMapInfo->paddr += (saveCounts << MMU_DESCRIPTOR_L2_SMALL_SHIFT); + *mmuMapInfo->vaddr += (saveCounts << MMU_DESCRIPTOR_L2_SMALL_SHIFT); + *count -= saveCounts; + return saveCounts; +} + +status_t LOS_ArchMmuMap(LosArchMmu *archMmu, VADDR_T vaddr, PADDR_T paddr, size_t count, UINT32 flags) +{ + PTE_T *l1Entry = NULL; + UINT32 saveCounts = 0; + INT32 mapped = 0; + INT32 tryTime = TRY_MAX_TIMES; + INT32 checkRst; + MmuMapInfo mmuMapInfo = { + .archMmu = archMmu, + .vaddr = &vaddr, + .paddr = &paddr, + .flags = &flags, + }; + + checkRst = OsMapParamCheck(flags, vaddr, paddr); + if (checkRst < 0) { + return checkRst; + } + + /* see what kind of mapping we can use */ + while (count > 0) { + if (MMU_DESCRIPTOR_IS_L1_SIZE_ALIGNED(*mmuMapInfo.vaddr) && + MMU_DESCRIPTOR_IS_L1_SIZE_ALIGNED(*mmuMapInfo.paddr) && + count >= MMU_DESCRIPTOR_L2_NUMBERS_PER_L1) { + /* compute the arch flags for L1 sections cache, r ,w ,x, domain and type */ + saveCounts = OsMapSection(&mmuMapInfo, &count); + } else { + /* have to use a L2 mapping, we only allocate 4KB for L1, support 0 ~ 1GB */ + l1Entry = OsGetPte1Ptr(archMmu->virtTtb, *mmuMapInfo.vaddr); + if (OsIsPte1Invalid(*l1Entry)) { + saveCounts = OsMapL1PTE(&mmuMapInfo, l1Entry, &count); + } else if (OsIsPte1PageTable(*l1Entry)) { + saveCounts = OsMapL2PageContinous(&mmuMapInfo, l1Entry, &count); + } else { + LOS_Panic("%s %d, unimplemented tt_entry %x\n", __FUNCTION__, __LINE__, l1Entry); + } + } + mapped += saveCounts; + tryTime = (saveCounts == 0) ? (tryTime - 1) : tryTime; + if (tryTime == 0) { + return LOS_ERRNO_VM_TIMED_OUT; + } + } + + return mapped; +} + +STATUS_T LOS_ArchMmuChangeProt(LosArchMmu *archMmu, VADDR_T vaddr, size_t count, UINT32 flags) +{ + STATUS_T status; + PADDR_T paddr = 0; + + if ((archMmu == NULL) || (vaddr == 0) || (count == 0)) { + VM_ERR("invalid args: archMmu %p, vaddr %p, count %d", archMmu, vaddr, count); + return LOS_NOK; + } + + while (count > 0) { + count--; + status = LOS_ArchMmuQuery(archMmu, vaddr, &paddr, NULL); + if (status != LOS_OK) { + vaddr += MMU_DESCRIPTOR_L2_SMALL_SIZE; + continue; + } + + status = LOS_ArchMmuUnmap(archMmu, vaddr, 1); + if (status < 0) { + VM_ERR("invalid args:aspace %p, vaddr %p, count %d", archMmu, vaddr, count); + return LOS_NOK; + } + + status = LOS_ArchMmuMap(archMmu, vaddr, paddr, 1, flags); + if (status < 0) { + VM_ERR("invalid args:aspace %p, vaddr %p, count %d", + archMmu, vaddr, count); + return LOS_NOK; + } + vaddr += MMU_DESCRIPTOR_L2_SMALL_SIZE; + } + return LOS_OK; +} + +STATUS_T LOS_ArchMmuMove(LosArchMmu *archMmu, VADDR_T oldVaddr, VADDR_T newVaddr, size_t count, UINT32 flags) +{ + STATUS_T status; + PADDR_T paddr = 0; + + if ((archMmu == NULL) || (oldVaddr == 0) || (newVaddr == 0) || (count == 0)) { + VM_ERR("invalid args: archMmu %p, oldVaddr %p, newVaddr %p, count %d", + archMmu, oldVaddr, newVaddr, count); + return LOS_NOK; + } + + while (count > 0) { + count--; + status = LOS_ArchMmuQuery(archMmu, oldVaddr, &paddr, NULL); + if (status != LOS_OK) { + oldVaddr += MMU_DESCRIPTOR_L2_SMALL_SIZE; + newVaddr += MMU_DESCRIPTOR_L2_SMALL_SIZE; + continue; + } + // we need to clear the mapping here and remain the phy page. + status = LOS_ArchMmuUnmap(archMmu, oldVaddr, 1); + if (status < 0) { + VM_ERR("invalid args: archMmu %p, vaddr %p, count %d", + archMmu, oldVaddr, count); + return LOS_NOK; + } + + status = LOS_ArchMmuMap(archMmu, newVaddr, paddr, 1, flags); + if (status < 0) { + VM_ERR("invalid args:archMmu %p, old_vaddr %p, new_addr %p, count %d", + archMmu, oldVaddr, newVaddr, count); + return LOS_NOK; + } + oldVaddr += MMU_DESCRIPTOR_L2_SMALL_SIZE; + newVaddr += MMU_DESCRIPTOR_L2_SMALL_SIZE; + } + + return LOS_OK; +} + +VOID LOS_ArchMmuContextSwitch(LosArchMmu *archMmu) +{ + UINT32 ttbr; + UINT32 ttbcr = OsArmReadTtbcr(); + if (archMmu) { + ttbr = MMU_TTBRx_FLAGS | (archMmu->physTtb); + /* enable TTBR0 */ + ttbcr &= ~MMU_DESCRIPTOR_TTBCR_PD0; + } else { + ttbr = 0; + /* disable TTBR0 */ + ttbcr |= MMU_DESCRIPTOR_TTBCR_PD0; + } + +#ifdef LOSCFG_KERNEL_VM + /* from armv7a arm B3.10.4, we should do synchronization changes of ASID and TTBR. */ + OsArmWriteContextidr(LOS_GetKVmSpace()->archMmu.asid); + ISB; +#endif + OsArmWriteTtbr0(ttbr); + ISB; + OsArmWriteTtbcr(ttbcr); + ISB; +#ifdef LOSCFG_KERNEL_VM + if (archMmu) { + OsArmWriteContextidr(archMmu->asid); + ISB; + } +#endif +} + +STATUS_T LOS_ArchMmuDestroy(LosArchMmu *archMmu) +{ +#ifdef LOSCFG_KERNEL_VM + LosVmPage *page = NULL; + /* free all of the pages allocated in archMmu->ptList */ + while ((page = LOS_ListRemoveHeadType(&archMmu->ptList, LosVmPage, node)) != NULL) { + LOS_PhysPageFree(page); + } + + OsArmWriteTlbiasidis(archMmu->asid); + OsFreeAsid(archMmu->asid); +#endif + return LOS_OK; +} + +STATIC VOID OsSwitchTmpTTB(VOID) +{ + PTE_T *tmpTtbase = NULL; + errno_t err; + LosVmSpace *kSpace = LOS_GetKVmSpace(); + + /* ttbr address should be 16KByte align */ + tmpTtbase = LOS_MemAllocAlign(m_aucSysMem0, MMU_DESCRIPTOR_L1_SMALL_ENTRY_NUMBERS, + MMU_DESCRIPTOR_L1_SMALL_ENTRY_NUMBERS); + if (tmpTtbase == NULL) { + VM_ERR("memory alloc failed"); + return; + } + + kSpace->archMmu.virtTtb = tmpTtbase; + err = memcpy_s(kSpace->archMmu.virtTtb, MMU_DESCRIPTOR_L1_SMALL_ENTRY_NUMBERS, + g_firstPageTable, MMU_DESCRIPTOR_L1_SMALL_ENTRY_NUMBERS); + if (err != EOK) { + (VOID)LOS_MemFree(m_aucSysMem0, tmpTtbase); + kSpace->archMmu.virtTtb = (VADDR_T *)g_firstPageTable; + VM_ERR("memcpy failed, errno: %d", err); + return; + } + kSpace->archMmu.physTtb = LOS_PaddrQuery(kSpace->archMmu.virtTtb); + OsArmWriteTtbr0(kSpace->archMmu.physTtb | MMU_TTBRx_FLAGS); + ISB; +} + +STATIC VOID OsSetKSectionAttr(UINTPTR virtAddr, BOOL uncached) +{ + UINT32 offset = virtAddr - KERNEL_VMM_BASE; + /* every section should be page aligned */ + UINTPTR textStart = (UINTPTR)&__text_start + offset; + UINTPTR textEnd = (UINTPTR)&__text_end + offset; + UINTPTR rodataStart = (UINTPTR)&__rodata_start + offset; + UINTPTR rodataEnd = (UINTPTR)&__rodata_end + offset; + UINTPTR ramDataStart = (UINTPTR)&__ram_data_start + offset; + UINTPTR bssEnd = (UINTPTR)&__bss_end + offset; + UINT32 bssEndBoundary = ROUNDUP(bssEnd, MB); + LosArchMmuInitMapping mmuKernelMappings[] = { + { + .phys = SYS_MEM_BASE + textStart - virtAddr, + .virt = textStart, + .size = ROUNDUP(textEnd - textStart, MMU_DESCRIPTOR_L2_SMALL_SIZE), + .flags = VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_EXECUTE, + .name = "kernel_text" + }, + { + .phys = SYS_MEM_BASE + rodataStart - virtAddr, + .virt = rodataStart, + .size = ROUNDUP(rodataEnd - rodataStart, MMU_DESCRIPTOR_L2_SMALL_SIZE), + .flags = VM_MAP_REGION_FLAG_PERM_READ, + .name = "kernel_rodata" + }, + { + .phys = SYS_MEM_BASE + ramDataStart - virtAddr, + .virt = ramDataStart, + .size = ROUNDUP(bssEndBoundary - ramDataStart, MMU_DESCRIPTOR_L2_SMALL_SIZE), + .flags = VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE, + .name = "kernel_data_bss" + } + }; + LosVmSpace *kSpace = LOS_GetKVmSpace(); + status_t status; + UINT32 length; + INT32 i; + LosArchMmuInitMapping *kernelMap = NULL; + UINT32 kmallocLength; + UINT32 flags; + + /* use second-level mapping of default READ and WRITE */ + kSpace->archMmu.virtTtb = (PTE_T *)g_firstPageTable; + kSpace->archMmu.physTtb = LOS_PaddrQuery(kSpace->archMmu.virtTtb); + status = LOS_ArchMmuUnmap(&kSpace->archMmu, virtAddr, + (bssEndBoundary - virtAddr) >> MMU_DESCRIPTOR_L2_SMALL_SHIFT); + if (status != ((bssEndBoundary - virtAddr) >> MMU_DESCRIPTOR_L2_SMALL_SHIFT)) { + VM_ERR("unmap failed, status: %d", status); + return; + } + + flags = VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE | VM_MAP_REGION_FLAG_PERM_EXECUTE; + if (uncached) { + flags |= VM_MAP_REGION_FLAG_UNCACHED; + } + status = LOS_ArchMmuMap(&kSpace->archMmu, virtAddr, SYS_MEM_BASE, + (textStart - virtAddr) >> MMU_DESCRIPTOR_L2_SMALL_SHIFT, + flags); + if (status != ((textStart - virtAddr) >> MMU_DESCRIPTOR_L2_SMALL_SHIFT)) { + VM_ERR("mmap failed, status: %d", status); + return; + } + + length = sizeof(mmuKernelMappings) / sizeof(LosArchMmuInitMapping); + for (i = 0; i < length; i++) { + kernelMap = &mmuKernelMappings[i]; + if (uncached) { + kernelMap->flags |= VM_MAP_REGION_FLAG_UNCACHED; + } + status = LOS_ArchMmuMap(&kSpace->archMmu, kernelMap->virt, kernelMap->phys, + kernelMap->size >> MMU_DESCRIPTOR_L2_SMALL_SHIFT, kernelMap->flags); + if (status != (kernelMap->size >> MMU_DESCRIPTOR_L2_SMALL_SHIFT)) { + VM_ERR("mmap failed, status: %d", status); + return; + } + LOS_VmSpaceReserve(kSpace, kernelMap->size, kernelMap->virt); + } + + kmallocLength = virtAddr + SYS_MEM_SIZE_DEFAULT - bssEndBoundary; + flags = VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE; + if (uncached) { + flags |= VM_MAP_REGION_FLAG_UNCACHED; + } + status = LOS_ArchMmuMap(&kSpace->archMmu, bssEndBoundary, + SYS_MEM_BASE + bssEndBoundary - virtAddr, + kmallocLength >> MMU_DESCRIPTOR_L2_SMALL_SHIFT, + flags); + if (status != (kmallocLength >> MMU_DESCRIPTOR_L2_SMALL_SHIFT)) { + VM_ERR("mmap failed, status: %d", status); + return; + } + LOS_VmSpaceReserve(kSpace, kmallocLength, bssEndBoundary); +} + +STATIC VOID OsKSectionNewAttrEnable(VOID) +{ + LosVmSpace *kSpace = LOS_GetKVmSpace(); + paddr_t oldTtPhyBase; + + kSpace->archMmu.virtTtb = (PTE_T *)g_firstPageTable; + kSpace->archMmu.physTtb = LOS_PaddrQuery(kSpace->archMmu.virtTtb); + + /* we need free tmp ttbase */ + oldTtPhyBase = OsArmReadTtbr0(); + oldTtPhyBase = oldTtPhyBase & MMU_DESCRIPTOR_L2_SMALL_FRAME; + OsArmWriteTtbr0(kSpace->archMmu.physTtb | MMU_TTBRx_FLAGS); + ISB; + + /* we changed page table entry, so we need to clean TLB here */ + OsCleanTLB(); + + (VOID)LOS_MemFree(m_aucSysMem0, (VOID *)(UINTPTR)(oldTtPhyBase - SYS_MEM_BASE + KERNEL_VMM_BASE)); +} + +/* disable TTBCR0 and set the split between TTBR0 and TTBR1 */ +VOID OsArchMmuInitPerCPU(VOID) +{ + UINT32 n = __builtin_clz(KERNEL_ASPACE_BASE) + 1; + UINT32 ttbcr = MMU_DESCRIPTOR_TTBCR_PD0 | n; + + OsArmWriteTtbr1(OsArmReadTtbr0()); + ISB; + OsArmWriteTtbcr(ttbcr); + ISB; + OsArmWriteTtbr0(0); + ISB; +} + +VOID OsInitMappingStartUp(VOID) +{ + OsArmInvalidateTlbBarrier(); + + OsSwitchTmpTTB(); + + OsSetKSectionAttr(KERNEL_VMM_BASE, FALSE); + OsSetKSectionAttr(UNCACHED_VMM_BASE, TRUE); + OsKSectionNewAttrEnable(); +} +#endif + diff --git a/src/kernel_liteos_a/arch/arm/arm/src/los_asid.c b/src/kernel_liteos_a/arch/arm/arm/src/los_asid.c new file mode 100644 index 00000000..30fd6331 --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/src/los_asid.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_asid mmu address space id + * @ingroup kernel + */ + +#include "los_asid.h" +#include "los_bitmap.h" +#include "los_spinlock.h" +#include "los_mmu_descriptor_v6.h" + + +#ifdef LOSCFG_KERNEL_VM + +STATIC SPIN_LOCK_INIT(g_cpuAsidLock); +STATIC UINTPTR g_asidPool[BITMAP_NUM_WORDS(1UL << MMU_ARM_ASID_BITS)]; + +/* allocate and free asid */ +status_t OsAllocAsid(UINT32 *asid) +{ + UINT32 flags; + LOS_SpinLockSave(&g_cpuAsidLock, &flags); + UINT32 firstZeroBit = LOS_BitmapFfz(g_asidPool, 1UL << MMU_ARM_ASID_BITS); + if (firstZeroBit >= 0 && firstZeroBit < (1UL << MMU_ARM_ASID_BITS)) { + LOS_BitmapSetNBits(g_asidPool, firstZeroBit, 1); + *asid = firstZeroBit; + LOS_SpinUnlockRestore(&g_cpuAsidLock, flags); + return LOS_OK; + } + + LOS_SpinUnlockRestore(&g_cpuAsidLock, flags); + return firstZeroBit; +} + +VOID OsFreeAsid(UINT32 asid) +{ + UINT32 flags; + LOS_SpinLockSave(&g_cpuAsidLock, &flags); + LOS_BitmapClrNBits(g_asidPool, asid, 1); + LOS_SpinUnlockRestore(&g_cpuAsidLock, flags); +} +#endif + diff --git a/src/kernel_liteos_a/arch/arm/arm/src/los_dispatch.S b/src/kernel_liteos_a/arch/arm/arm/src/los_dispatch.S new file mode 100644 index 00000000..797d1677 --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/src/los_dispatch.S @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "asm.h" +#include "arch_config.h" + + .extern OsSaveSignalContext + .extern OsSchedToUserReleaseLock + .global OsTaskSchedule + .global OsTaskContextLoad + .global OsIrqHandler + + .fpu vfpv4 + +/* macros to align and unalign the stack on 8 byte boundary for ABI compliance */ +.macro STACK_ALIGN, reg + MOV \reg, sp + TST SP, #4 + SUBEQ SP, #4 + PUSH { \reg } +.endm + +.macro STACK_RESTORE, reg + POP { \reg } + MOV sp, \reg +.endm + +/* macros to save and restore fpu regs */ +.macro PUSH_FPU_REGS reg1 +#if !defined(LOSCFG_ARCH_FPU_DISABLE) + VMRS \reg1, FPEXC + PUSH {\reg1} + VMRS \reg1, FPSCR + PUSH {\reg1} +#if defined(LOSCFG_ARCH_FPU_VFP_D32) + VPUSH {D16-D31} +#endif + VPUSH {D0-D15} +#endif +.endm + +.macro POP_FPU_REGS reg1 +#if !defined(LOSCFG_ARCH_FPU_DISABLE) + VPOP {D0-D15} +#if defined(LOSCFG_ARCH_FPU_VFP_D32) + VPOP {D16-D31} +#endif + POP {\reg1} + VMSR FPSCR, \reg1 + POP {\reg1} + VMSR FPEXC, \reg1 +#endif +.endm + +/* + * R0: new task + * R1: run task + */ +OsTaskSchedule: + MRS R2, CPSR + STMFD SP!, {R2} + STMFD SP!, {LR} + STMFD SP!, {LR} + STMFD SP!, {R12} + + /* jump R0 - R3 USP, ULR reserved */ + SUB SP, SP, #(8 * 4) + + /* push R4 - R11*/ + STMFD SP!, {R4-R11} + + /* save fpu registers */ + PUSH_FPU_REGS R2 + + /* store sp on running task */ + STR SP, [R1] + +OsTaskContextLoad: + /* clear the flag of ldrex */ + CLREX + + /* switch to new task's sp */ + LDR SP, [R0] + + /* restore fpu registers */ + POP_FPU_REGS R2 + + LDMFD SP!, {R4-R11} + LDR R3, [SP, #(11 * 4)] + AND R0, R3, #CPSR_MASK_MODE + CMP R0, #CPSR_USER_MODE + BNE OsKernelTaskLoad + + MVN R2, #CPSR_INT_DISABLE + AND R3, R3, R2 + STR R3, [SP, #(11 * 4)] + +#ifdef LOSCFG_KERNEL_SMP + BL OsSchedToUserReleaseLock +#endif + + /* jump sp, reserved */ + ADD SP, SP, #(2 * 4) + LDMFD SP, {R13, R14}^ + ADD SP, SP, #(2 * 4) + LDMFD SP!, {R0-R3, R12, LR} + RFEIA SP! + +OsKernelTaskLoad: + ADD SP, SP, #(4 * 4) + LDMFD SP!, {R0-R3, R12, LR} + RFEIA SP! + +OsIrqHandler: + SUB LR, LR, #4 + + /* Save pc and cpsr to svc sp, ARMv6 and above support */ + SRSFD #0x13! + /* disable irq, switch to svc mode */ + CPSID i, #0x13 + +#ifdef LOSCFG_KERNEL_PERF + PUSH {R0-R3, R12, LR} + MOV R0, LR + MOV R1, FP + BL OsPerfSetIrqRegs + POP {R0-R3, R12, LR} +#endif + + STMFD SP!, {R0-R3, R12, LR} + STMFD SP, {R13, R14}^ + SUB SP, SP, #(4 * 4) + STR R4, [SP, #0] + + /* + * save fpu regs in case in case those been + * altered in interrupt handlers. + */ + PUSH_FPU_REGS R0 + + MOV R4, SP + EXC_SP_SET __svc_stack_top, OS_EXC_SVC_STACK_SIZE, R1, R2 + + BLX HalIrqHandler + + MOV SP, R4 + + /* process pending signals */ + BLX OsTaskProcSignal + BLX OsSchedIrqEndCheckNeedSched + + /* restore fpu regs */ + POP_FPU_REGS R0 + LDR R4, [SP, #0] + +#ifdef LOSCFG_KERNEL_VM + /* Obtain the CPSR to determine the mode the system is in when the interrupt is triggered */ + LDR R3, [SP, #(11 * 4)] + AND R1, R3, #CPSR_MASK_MODE + CMP R1, #CPSR_USER_MODE + BNE 1f + + MOV R0, SP + STR R7, [SP, #0] + /* sp - sizeof(IrqContext) */ + SUB SP, SP, #(12 * 4) + MOV R1, SP + BLX OsSaveSignalContext + MOV SP, R0 +1: +#endif + ADD SP, SP, #(2 * 4) + /* load user sp and lr, and jump cpsr */ + LDMFD SP, {R13, R14}^ + ADD SP, SP, #(2 * 4) + LDMFD SP!, {R0-R3, R12, LR} + RFEIA SP! + +FUNCTION(ArchSpinLock) + mov r1, #1 +1: + ldrex r2, [r0] + cmp r2, #0 + wfene + strexeq r2, r1, [r0] + cmpeq r2, #0 + bne 1b + dmb + bx lr + +FUNCTION(ArchSpinTrylock) + mov r1, #1 + mov r2, r0 + ldrex r0, [r2] + cmp r0, #0 + strexeq r0, r1, [r2] + dmb + bx lr + +FUNCTION(ArchSpinUnlock) + mov r1, #0 + dmb + str r1, [r0] + dsb + sev + bx lr diff --git a/src/kernel_liteos_a/arch/arm/arm/src/los_exc.c b/src/kernel_liteos_a/arch/arm/arm/src/los_exc.c new file mode 100644 index 00000000..f51ac52a --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/src/los_exc.c @@ -0,0 +1,1296 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_exc.h" +#include "los_memory_pri.h" +#include "los_printf_pri.h" +#include "los_task_pri.h" +#include "los_percpu_pri.h" +#include "los_hw_pri.h" +#ifdef LOSCFG_SAVE_EXCINFO +#include "los_excinfo_pri.h" +#endif +#include "los_sys_stack_pri.h" +#ifdef LOSCFG_COREDUMP +#include "los_coredump.h" +#endif +#ifdef LOSCFG_GDB +#include "gdb_int.h" +#endif +#include "los_mp.h" +#include "los_vm_map.h" +#include "los_vm_dump.h" +#include "los_arch_mmu.h" +#include "los_vm_phys.h" +#include "los_vm_fault.h" +#include "los_vm_common.h" +#ifdef LOSCFG_KERNEL_DYNLOAD +#include "los_load_elf.h" +#endif +#include "arm.h" +#include "los_bitmap.h" +#include "los_process_pri.h" +#include "los_exc_pri.h" +#include "los_sched_pri.h" +#ifdef LOSCFG_FS_VFS +#include "console.h" +#endif +#ifdef LOSCFG_BLACKBOX +#include "los_blackbox.h" +#endif + + +#define INVALID_CPUID 0xFFFF +#define OS_EXC_VMM_NO_REGION 0x0U +#define OS_EXC_VMM_ALL_REGION 0x1U + +STATIC UINTPTR g_minAddr; +STATIC UINTPTR g_maxAddr; +STATIC UINT32 g_currHandleExcCpuid = INVALID_CPUID; +VOID OsExcHook(UINT32 excType, ExcContext *excBufAddr, UINT32 far, UINT32 fsr); +UINT32 g_curNestCount[LOSCFG_KERNEL_CORE_NUM] = { 0 }; +BOOL g_excFromUserMode[LOSCFG_KERNEL_CORE_NUM]; +STATIC EXC_PROC_FUNC g_excHook = (EXC_PROC_FUNC)OsExcHook; +#ifdef LOSCFG_KERNEL_SMP +STATIC SPIN_LOCK_INIT(g_excSerializerSpin); +STATIC UINT32 g_currHandleExcPID = OS_INVALID_VALUE; +STATIC UINT32 g_nextExcWaitCpu = INVALID_CPUID; +#endif + +#define OS_MAX_BACKTRACE 15U +#define DUMPSIZE 128U +#define DUMPREGS 12U +#define COM_REGS 4U +#define INSTR_SET_MASK 0x01000020U +#define THUMB_INSTR_LEN 2U +#define ARM_INSTR_LEN 4U +#define POINTER_SIZE 4U +#define WNR_BIT 11U +#define FSR_FLAG_OFFSET_BIT 10U +#define FSR_BITS_BEGIN_BIT 3U + + +#define GET_FS(fsr) (((fsr) & 0xFU) | (((fsr) & (1U << 10)) >> 6)) +#define GET_WNR(dfsr) ((dfsr) & (1U << 11)) + +#define IS_VALID_ADDR(ptr) (((ptr) >= g_minAddr) && \ + ((ptr) <= g_maxAddr) && \ + (IS_ALIGNED((ptr), sizeof(CHAR *)))) + +STATIC const StackInfo g_excStack[] = { + { &__svc_stack, OS_EXC_SVC_STACK_SIZE, "svc_stack" }, + { &__exc_stack, OS_EXC_STACK_SIZE, "exc_stack" } +}; + +UINT32 OsGetSystemStatus(VOID) +{ + UINT32 flag; + UINT32 cpuid = g_currHandleExcCpuid; + + if (cpuid == INVALID_CPUID) { + flag = OS_SYSTEM_NORMAL; + } else if (cpuid == ArchCurrCpuid()) { + flag = OS_SYSTEM_EXC_CURR_CPU; + } else { + flag = OS_SYSTEM_EXC_OTHER_CPU; + } + + return flag; +} + +STATIC INT32 OsDecodeFS(UINT32 bitsFS) +{ + switch (bitsFS) { + case 0x05: /* 0b00101 */ + case 0x07: /* 0b00111 */ + PrintExcInfo("Translation fault, %s\n", (bitsFS & 0x2) ? "page" : "section"); + break; + case 0x09: /* 0b01001 */ + case 0x0b: /* 0b01011 */ + PrintExcInfo("Domain fault, %s\n", (bitsFS & 0x2) ? "page" : "section"); + break; + case 0x0d: /* 0b01101 */ + case 0x0f: /* 0b01111 */ + PrintExcInfo("Permission fault, %s\n", (bitsFS & 0x2) ? "page" : "section"); + break; + default: + PrintExcInfo("Unknown fault! FS:0x%x. " + "Check IFSR and DFSR in ARM Architecture Reference Manual.\n", + bitsFS); + break; + } + + return LOS_OK; +} + +STATIC INT32 OsDecodeInstructionFSR(UINT32 regIFSR) +{ + INT32 ret; + UINT32 bitsFS = GET_FS(regIFSR); /* FS bits[4]+[3:0] */ + + ret = OsDecodeFS(bitsFS); + return ret; +} + +STATIC INT32 OsDecodeDataFSR(UINT32 regDFSR) +{ + INT32 ret = 0; + UINT32 bitWnR = GET_WNR(regDFSR); /* WnR bit[11] */ + UINT32 bitsFS = GET_FS(regDFSR); /* FS bits[4]+[3:0] */ + + if (bitWnR) { + PrintExcInfo("Abort caused by a write instruction. "); + } else { + PrintExcInfo("Abort caused by a read instruction. "); + } + + if (bitsFS == 0x01) { /* 0b00001 */ + PrintExcInfo("Alignment fault.\n"); + return ret; + } + ret = OsDecodeFS(bitsFS); + return ret; +} + +#ifdef LOSCFG_KERNEL_VM +UINT32 OsArmSharedPageFault(UINT32 excType, ExcContext *frame, UINT32 far, UINT32 fsr) +{ + BOOL instructionFault = FALSE; + UINT32 pfFlags = 0; + UINT32 fsrFlag; + BOOL write = FALSE; + UINT32 ret; + + PRINT_INFO("page fault entry!!!\n"); + if (OsGetSystemStatus() == OS_SYSTEM_EXC_CURR_CPU) { + return LOS_ERRNO_VM_NOT_FOUND; + } +#if defined(LOSCFG_KERNEL_SMP) && defined(LOSCFG_DEBUG_VERSION) + BOOL irqEnable = !(LOS_SpinHeld(&g_taskSpin) && OsSchedIsLock()); + if (irqEnable) { + ArchIrqEnable(); + } else { + PrintExcInfo("[ERR][%s] may be held scheduler lock when entering [%s] on cpu [%u]\n", + OsCurrTaskGet()->taskName, __FUNCTION__, ArchCurrCpuid()); + } +#else + ArchIrqEnable(); +#endif + if (excType == OS_EXCEPT_PREFETCH_ABORT) { + instructionFault = TRUE; + } else { + write = !!BIT_GET(fsr, WNR_BIT); + } + + fsrFlag = ((BIT_GET(fsr, FSR_FLAG_OFFSET_BIT) ? 0b10000 : 0) | BITS_GET(fsr, FSR_BITS_BEGIN_BIT, 0)); + switch (fsrFlag) { + case 0b00101: + /* translation fault */ + case 0b00111: + /* translation fault */ + case 0b01101: + /* permission fault */ + case 0b01111: { + /* permission fault */ + BOOL user = (frame->regCPSR & CPSR_MODE_MASK) == CPSR_MODE_USR; + pfFlags |= write ? VM_MAP_PF_FLAG_WRITE : 0; + pfFlags |= user ? VM_MAP_PF_FLAG_USER : 0; + pfFlags |= instructionFault ? VM_MAP_PF_FLAG_INSTRUCTION : 0; + pfFlags |= VM_MAP_PF_FLAG_NOT_PRESENT; + OsSigIntLock(); + ret = OsVmPageFaultHandler(far, pfFlags, frame); + OsSigIntUnlock(); + break; + } + default: + OsArmWriteTlbimvaais(ROUNDDOWN(far, PAGE_SIZE)); + ret = LOS_OK; + break; + } +#if defined(LOSCFG_KERNEL_SMP) && defined(LOSCFG_DEBUG_VERSION) + if (irqEnable) { + ArchIrqDisable(); + } +#else + ArchIrqDisable(); +#endif + return ret; +} +#endif + +STATIC VOID OsExcType(UINT32 excType, ExcContext *excBufAddr, UINT32 far, UINT32 fsr) +{ + /* undefined exception handling or software interrupt */ + if ((excType == OS_EXCEPT_UNDEF_INSTR) || (excType == OS_EXCEPT_SWI)) { + if ((excBufAddr->regCPSR & INSTR_SET_MASK) == 0) { /* work status: ARM */ + excBufAddr->PC = excBufAddr->PC - ARM_INSTR_LEN; + } else if ((excBufAddr->regCPSR & INSTR_SET_MASK) == 0x20) { /* work status: Thumb */ + excBufAddr->PC = excBufAddr->PC - THUMB_INSTR_LEN; + } + } + + if (excType == OS_EXCEPT_PREFETCH_ABORT) { + PrintExcInfo("prefetch_abort fault fsr:0x%x, far:0x%0+8x\n", fsr, far); + (VOID)OsDecodeInstructionFSR(fsr); + } else if (excType == OS_EXCEPT_DATA_ABORT) { + PrintExcInfo("data_abort fsr:0x%x, far:0x%0+8x\n", fsr, far); + (VOID)OsDecodeDataFSR(fsr); + } +} + +STATIC const CHAR *g_excTypeString[] = { + "reset", + "undefined instruction", + "software interrupt", + "prefetch abort", + "data abort", + "fiq", + "address abort", + "irq" +}; + +#ifdef LOSCFG_KERNEL_VM +STATIC VADDR_T OsGetTextRegionBase(LosVmMapRegion *region, LosProcessCB *runProcess) +{ + struct Vnode *curVnode = NULL; + struct Vnode *lastVnode = NULL; + LosVmMapRegion *curRegion = NULL; + LosVmMapRegion *lastRegion = NULL; + + if ((region == NULL) || (runProcess == NULL)) { + return 0; + } + + if (!LOS_IsRegionFileValid(region)) { + return region->range.base; + } + + lastRegion = region; + do { + curRegion = lastRegion; + lastRegion = LOS_RegionFind(runProcess->vmSpace, curRegion->range.base - 1); + if ((lastRegion == NULL) || !LOS_IsRegionFileValid(lastRegion)) { + goto DONE; + } + curVnode = curRegion->unTypeData.rf.vnode; + lastVnode = lastRegion->unTypeData.rf.vnode; + } while (curVnode == lastVnode); + +DONE: +#ifdef LOSCFG_KERNEL_DYNLOAD + if (curRegion->range.base == EXEC_MMAP_BASE) { + return 0; + } +#endif + return curRegion->range.base; +} +#endif + +STATIC VOID OsExcSysInfo(UINT32 excType, const ExcContext *excBufAddr) +{ + LosTaskCB *runTask = OsCurrTaskGet(); + LosProcessCB *runProcess = OsCurrProcessGet(); + + PrintExcInfo("excType: %s\n" + "processName = %s\n" + "processID = %u\n" +#ifdef LOSCFG_KERNEL_VM + "process aspace = 0x%08x -> 0x%08x\n" +#endif + "taskName = %s\n" + "taskID = %u\n", + g_excTypeString[excType], + runProcess->processName, + runProcess->processID, +#ifdef LOSCFG_KERNEL_VM + runProcess->vmSpace->base, + runProcess->vmSpace->base + runProcess->vmSpace->size, +#endif + runTask->taskName, + runTask->taskID); + +#ifdef LOSCFG_KERNEL_VM + if (OsProcessIsUserMode(runProcess)) { + PrintExcInfo("task user stack = 0x%08x -> 0x%08x\n", + runTask->userMapBase, runTask->userMapBase + runTask->userMapSize); + } else +#endif + { + PrintExcInfo("task kernel stack = 0x%08x -> 0x%08x\n", + runTask->topOfStack, runTask->topOfStack + runTask->stackSize); + } + + PrintExcInfo("pc = 0x%x ", excBufAddr->PC); +#ifdef LOSCFG_KERNEL_VM + LosVmMapRegion *region = NULL; + if (g_excFromUserMode[ArchCurrCpuid()] == TRUE) { + if (LOS_IsUserAddress((vaddr_t)excBufAddr->PC)) { + region = LOS_RegionFind(runProcess->vmSpace, (VADDR_T)excBufAddr->PC); + if (region != NULL) { + PrintExcInfo("in %s ---> 0x%x", OsGetRegionNameOrFilePath(region), + (VADDR_T)excBufAddr->PC - OsGetTextRegionBase(region, runProcess)); + } + } + + PrintExcInfo("\nulr = 0x%x ", excBufAddr->ULR); + region = LOS_RegionFind(runProcess->vmSpace, (VADDR_T)excBufAddr->ULR); + if (region != NULL) { + PrintExcInfo("in %s ---> 0x%x", OsGetRegionNameOrFilePath(region), + (VADDR_T)excBufAddr->ULR - OsGetTextRegionBase(region, runProcess)); + } + PrintExcInfo("\nusp = 0x%x", excBufAddr->USP); + } else +#endif + { + PrintExcInfo("\nklr = 0x%x\n" + "ksp = 0x%x\n", + excBufAddr->LR, + excBufAddr->SP); + } + + PrintExcInfo("\nfp = 0x%x\n", excBufAddr->R11); +} + +STATIC VOID OsExcRegsInfo(const ExcContext *excBufAddr) +{ + /* + * Split register information into two parts: + * Ensure printing does not rely on memory modules. + */ + PrintExcInfo("R0 = 0x%x\n" + "R1 = 0x%x\n" + "R2 = 0x%x\n" + "R3 = 0x%x\n" + "R4 = 0x%x\n" + "R5 = 0x%x\n" + "R6 = 0x%x\n", + excBufAddr->R0, excBufAddr->R1, excBufAddr->R2, excBufAddr->R3, + excBufAddr->R4, excBufAddr->R5, excBufAddr->R6); + PrintExcInfo("R7 = 0x%x\n" + "R8 = 0x%x\n" + "R9 = 0x%x\n" + "R10 = 0x%x\n" + "R11 = 0x%x\n" + "R12 = 0x%x\n" + "CPSR = 0x%x\n", + excBufAddr->R7, excBufAddr->R8, excBufAddr->R9, excBufAddr->R10, + excBufAddr->R11, excBufAddr->R12, excBufAddr->regCPSR); +} + +LITE_OS_SEC_TEXT_INIT UINT32 LOS_ExcRegHook(EXC_PROC_FUNC excHook) +{ + UINT32 intSave; + + intSave = LOS_IntLock(); + g_excHook = excHook; + LOS_IntRestore(intSave); + + return LOS_OK; +} + +EXC_PROC_FUNC OsExcRegHookGet(VOID) +{ + return g_excHook; +} + +#ifdef LOSCFG_KERNEL_VM +STATIC VOID OsDumpExcVaddrRegion(LosVmSpace *space, LosVmMapRegion *region) +{ + INT32 i, numPages, pageCount; + paddr_t addr, oldAddr, startVaddr, startPaddr; + vaddr_t pageBase; + BOOL mmuFlag = FALSE; + + numPages = region->range.size >> PAGE_SHIFT; + mmuFlag = TRUE; + for (pageCount = 0, startPaddr = 0, startVaddr = 0, i = 0; i < numPages; i++) { + pageBase = region->range.base + i * PAGE_SIZE; + addr = 0; + if (LOS_ArchMmuQuery(&space->archMmu, pageBase, &addr, NULL) != LOS_OK) { + if (startPaddr == 0) { + continue; + } + } else if (startPaddr == 0) { + startVaddr = pageBase; + startPaddr = addr; + oldAddr = addr; + pageCount++; + if (numPages > 1) { + continue; + } + } else if (addr == (oldAddr + PAGE_SIZE)) { + pageCount++; + oldAddr = addr; + if (i < (numPages - 1)) { + continue; + } + } + if (mmuFlag == TRUE) { + PrintExcInfo(" uvaddr kvaddr mapped size\n"); + mmuFlag = FALSE; + } + PrintExcInfo(" 0x%08x 0x%08x 0x%08x\n", + startVaddr, LOS_PaddrToKVaddr(startPaddr), (UINT32)pageCount << PAGE_SHIFT); + pageCount = 0; + startPaddr = 0; + } +} + +STATIC VOID OsDumpProcessUsedMemRegion(LosProcessCB *runProcess, LosVmSpace *runspace, UINT16 vmmFlags) +{ + LosVmMapRegion *region = NULL; + LosRbNode *pstRbNodeTemp = NULL; + LosRbNode *pstRbNodeNext = NULL; + UINT32 count = 0; + + /* search the region list */ + RB_SCAN_SAFE(&runspace->regionRbTree, pstRbNodeTemp, pstRbNodeNext) + region = (LosVmMapRegion *)pstRbNodeTemp; + PrintExcInfo("%3u -> regionBase: 0x%08x regionSize: 0x%08x\n", count, region->range.base, region->range.size); + if (vmmFlags == OS_EXC_VMM_ALL_REGION) { + OsDumpExcVaddrRegion(runspace, region); + } + count++; + (VOID)OsRegionOverlapCheckUnlock(runspace, region); + RB_SCAN_SAFE_END(&space->regionRbTree, pstRbNodeTemp, pstRbNodeNext) +} + +STATIC VOID OsDumpProcessUsedMemNode(UINT16 vmmFlags) +{ + LosProcessCB *runProcess = NULL; + LosVmSpace *runspace = NULL; + + runProcess = OsCurrProcessGet(); + if (runProcess == NULL) { + return; + } + + if (!OsProcessIsUserMode(runProcess)) { + return; + } + + PrintExcInfo("\n ******Current process %u vmm regions: ******\n", runProcess->processID); + + runspace = runProcess->vmSpace; + if (!runspace) { + return; + } + + OsDumpProcessUsedMemRegion(runProcess, runspace, vmmFlags); + return; +} +#endif + +VOID OsDumpContextMem(const ExcContext *excBufAddr) +{ + UINT32 count = 0; + const UINT32 *excReg = NULL; + if (g_excFromUserMode[ArchCurrCpuid()] == TRUE) { + return; + } + + for (excReg = &(excBufAddr->R0); count < COM_REGS; excReg++, count++) { + if (IS_VALID_ADDR(*excReg)) { + PrintExcInfo("\ndump mem around R%u:%p", count, (*excReg)); + OsDumpMemByte(DUMPSIZE, ((*excReg) - (DUMPSIZE >> 1))); + } + } + for (excReg = &(excBufAddr->R4); count < DUMPREGS; excReg++, count++) { + if (IS_VALID_ADDR(*excReg)) { + PrintExcInfo("\ndump mem around R%u:%p", count, (*excReg)); + OsDumpMemByte(DUMPSIZE, ((*excReg) - (DUMPSIZE >> 1))); + } + } + if (IS_VALID_ADDR(excBufAddr->R12)) { + PrintExcInfo("\ndump mem around R12:%p", excBufAddr->R12); + OsDumpMemByte(DUMPSIZE, (excBufAddr->R12 - (DUMPSIZE >> 1))); + } + if (IS_VALID_ADDR(excBufAddr->SP)) { + PrintExcInfo("\ndump mem around SP:%p", excBufAddr->SP); + OsDumpMemByte(DUMPSIZE, (excBufAddr->SP - (DUMPSIZE >> 1))); + } +} + +STATIC VOID OsExcRestore(VOID) +{ + UINT32 currCpuid = ArchCurrCpuid(); + + g_excFromUserMode[currCpuid] = FALSE; + g_intCount[currCpuid] = 0; + g_curNestCount[currCpuid] = 0; +#ifdef LOSCFG_KERNEL_SMP + OsCpuStatusSet(CPU_RUNNING); +#endif + OsSchedLockSet(0); +} + +STATIC VOID OsUserExcHandle(ExcContext *excBufAddr) +{ + UINT32 intSave; + UINT32 currCpu = ArchCurrCpuid(); + LosTaskCB *runTask = OsCurrTaskGet(); + LosProcessCB *runProcess = OsCurrProcessGet(); + + if (g_excFromUserMode[ArchCurrCpuid()] == FALSE) { + return; + } + +#ifdef LOSCFG_KERNEL_SMP + LOS_SpinLock(&g_excSerializerSpin); + if (g_nextExcWaitCpu != INVALID_CPUID) { + g_currHandleExcCpuid = g_nextExcWaitCpu; + g_nextExcWaitCpu = INVALID_CPUID; + } else { + g_currHandleExcCpuid = INVALID_CPUID; + } + g_currHandleExcPID = OS_INVALID_VALUE; + LOS_SpinUnlock(&g_excSerializerSpin); +#else + g_currHandleExcCpuid = INVALID_CPUID; +#endif + +#ifdef LOSCFG_KERNEL_SMP +#ifdef LOSCFG_FS_VFS + OsWakeConsoleSendTask(); +#endif +#endif + +#ifdef LOSCFG_BLACKBOX + BBoxNotifyError("USER_CRASH", MODULE_SYSTEM, "Crash in user", 0); +#endif + SCHEDULER_LOCK(intSave); +#ifdef LOSCFG_SAVE_EXCINFO + OsProcessExitCodeCoreDumpSet(runProcess); +#endif + OsProcessExitCodeSignalSet(runProcess, SIGUSR2); + + /* An exception was raised by a task during the exit process of + * the current process. + */ + if (runProcess->processStatus & OS_PROCESS_FLAG_EXIT) { + SCHEDULER_UNLOCK(intSave); + /* Exception handling All operations should be kept prior to that operation */ + OsExcRestore(); + OsRunningTaskToExit(runTask, OS_PRO_EXIT_OK); + } else { + SCHEDULER_UNLOCK(intSave); + + /* Exception handling All operations should be kept prior to that operation */ + OsExcRestore(); + /* kill user exc process */ + LOS_Exit(OS_PRO_EXIT_OK); + } + + /* User mode exception handling failed , which normally does not exist */ + g_curNestCount[currCpu]++; + g_intCount[currCpu]++; + PrintExcInfo("User mode exception ends unscheduled!\n"); +} + +/* this function is used to validate fp or validate the checking range start and end. */ +STATIC INLINE BOOL IsValidFP(UINTPTR regFP, UINTPTR start, UINTPTR end, vaddr_t *vaddr) +{ + VADDR_T kvaddr = regFP; + + if (!((regFP > start) && (regFP < end) && IS_ALIGNED(regFP, sizeof(CHAR *)))) { + return FALSE; + } + +#ifdef LOSCFG_KERNEL_VM + PADDR_T paddr; + if (g_excFromUserMode[ArchCurrCpuid()] == TRUE) { + LosProcessCB *runProcess = OsCurrProcessGet(); + LosVmSpace *runspace = runProcess->vmSpace; + if (runspace == NULL) { + return FALSE; + } + + if (LOS_ArchMmuQuery(&runspace->archMmu, regFP, &paddr, NULL) != LOS_OK) { + return FALSE; + } + + kvaddr = (PADDR_T)(UINTPTR)LOS_PaddrToKVaddr(paddr); + } +#endif + if (vaddr != NULL) { + *vaddr = kvaddr; + } + + return TRUE; +} + +STATIC INLINE BOOL FindSuitableStack(UINTPTR regFP, UINTPTR *start, UINTPTR *end, vaddr_t *vaddr) +{ + UINT32 index, stackStart, stackEnd; + BOOL found = FALSE; + LosTaskCB *taskCB = NULL; + const StackInfo *stack = NULL; + vaddr_t kvaddr; + +#ifdef LOSCFG_KERNEL_VM + if (g_excFromUserMode[ArchCurrCpuid()] == TRUE) { + taskCB = OsCurrTaskGet(); + stackStart = taskCB->userMapBase; + stackEnd = taskCB->userMapBase + taskCB->userMapSize; + if (IsValidFP(regFP, stackStart, stackEnd, &kvaddr) == TRUE) { + found = TRUE; + goto FOUND; + } + return found; + } +#endif + + /* Search in the task stacks */ + for (index = 0; index < g_taskMaxNum; index++) { + taskCB = &g_taskCBArray[index]; + if (OsTaskIsUnused(taskCB)) { + continue; + } + + stackStart = taskCB->topOfStack; + stackEnd = taskCB->topOfStack + taskCB->stackSize; + if (IsValidFP(regFP, stackStart, stackEnd, &kvaddr) == TRUE) { + found = TRUE; + goto FOUND; + } + } + + /* Search in the exc stacks */ + for (index = 0; index < sizeof(g_excStack) / sizeof(StackInfo); index++) { + stack = &g_excStack[index]; + stackStart = (UINTPTR)stack->stackTop; + stackEnd = stackStart + LOSCFG_KERNEL_CORE_NUM * stack->stackSize; + if (IsValidFP(regFP, stackStart, stackEnd, &kvaddr) == TRUE) { + found = TRUE; + goto FOUND; + } + } + +FOUND: + if (found == TRUE) { + *start = stackStart; + *end = stackEnd; + *vaddr = kvaddr; + } + + return found; +} + +BOOL OsGetUsrIpInfo(UINTPTR ip, IpInfo *info) +{ + if (info == NULL) { + return FALSE; + } +#ifdef LOSCFG_KERNEL_VM + BOOL ret = FALSE; + const CHAR *name = NULL; + LosVmMapRegion *region = NULL; + LosProcessCB *runProcess = OsCurrProcessGet(); + + if (LOS_IsUserAddress((VADDR_T)ip) == FALSE) { + info->ip = ip; + name = "kernel"; + ret = FALSE; + goto END; + } + + region = LOS_RegionFind(runProcess->vmSpace, (VADDR_T)ip); + if (region == NULL) { + info->ip = ip; + name = "invalid"; + ret = FALSE; + goto END; + } + + info->ip = ip - OsGetTextRegionBase(region, runProcess); + name = OsGetRegionNameOrFilePath(region); + ret = TRUE; + if (strcmp(name, "/lib/libc.so") != 0) { + PRINT_ERR("ip = 0x%x, %s\n", info->ip, name); + } +END: + info->len = strlen(name); + if (strncpy_s(info->f_path, REGION_PATH_MAX, name, REGION_PATH_MAX - 1) != EOK) { + info->f_path[0] = '\0'; + info->len = 0; + PRINT_ERR("copy f_path failed, %s\n", name); + } + return ret; +#else + info->ip = ip; + return FALSE; +#endif +} + +UINT32 BackTraceGet(UINTPTR regFP, IpInfo *callChain, UINT32 maxDepth) +{ + UINTPTR tmpFP, backLR; + UINTPTR stackStart, stackEnd; + UINTPTR backFP = regFP; + UINT32 count = 0; + BOOL ret; + VADDR_T kvaddr; + + if (FindSuitableStack(regFP, &stackStart, &stackEnd, &kvaddr) == FALSE) { + if (callChain == NULL) { + PrintExcInfo("traceback error fp = 0x%x\n", regFP); + } + return 0; + } + + /* + * Check whether it is the leaf function. + * Generally, the frame pointer points to the address of link register, while in the leaf function, + * there's no function call, and compiler will not store the link register, but the frame pointer + * will still be stored and updated. In that case we needs to find the right position of frame pointer. + */ + tmpFP = *(UINTPTR *)(UINTPTR)kvaddr; + if (IsValidFP(tmpFP, stackStart, stackEnd, NULL) == TRUE) { + backFP = tmpFP; + if (callChain == NULL) { + PrintExcInfo("traceback fp fixed, trace using fp = 0x%x\n", backFP); + } + } + + while (IsValidFP(backFP, stackStart, stackEnd, &kvaddr) == TRUE) { + tmpFP = backFP; +#ifdef LOSCFG_COMPILER_CLANG_LLVM + backFP = *(UINTPTR *)(UINTPTR)kvaddr; + if (IsValidFP(tmpFP + POINTER_SIZE, stackStart, stackEnd, &kvaddr) == FALSE) { + if (callChain == NULL) { + PrintExcInfo("traceback backLR check failed, backLP: 0x%x\n", tmpFP + POINTER_SIZE); + } + return 0; + } + backLR = *(UINTPTR *)(UINTPTR)kvaddr; +#else + backLR = *(UINTPTR *)(UINTPTR)kvaddr; + if (IsValidFP(tmpFP - POINTER_SIZE, stackStart, stackEnd, &kvaddr) == FALSE) { + if (callChain == NULL) { + PrintExcInfo("traceback backFP check failed, backFP: 0x%x\n", tmpFP - POINTER_SIZE); + } + return 0; + } + backFP = *(UINTPTR *)(UINTPTR)kvaddr; +#endif + IpInfo info = {0}; + ret = OsGetUsrIpInfo((VADDR_T)backLR, &info); + if (callChain == NULL) { + PrintExcInfo("traceback %u -- lr = 0x%x fp = 0x%x ", count, backLR, backFP); + if (ret) { +#ifdef LOSCFG_KERNEL_VM + PrintExcInfo("lr in %s --> 0x%x\n", info.f_path, info.ip); +#else + PrintExcInfo("\n"); +#endif + } else { + PrintExcInfo("\n"); + } + } else { + (VOID)memcpy_s(&callChain[count], sizeof(IpInfo), &info, sizeof(IpInfo)); + } + count++; + if ((count == maxDepth) || (backFP == tmpFP)) { + break; + } + } + return count; +} + +VOID BackTraceSub(UINTPTR regFP) +{ + (VOID)BackTraceGet(regFP, NULL, OS_MAX_BACKTRACE); +} + +VOID BackTrace(UINT32 regFP) +{ + PrintExcInfo("*******backtrace begin*******\n"); + + BackTraceSub(regFP); +} + +VOID OsExcInit(VOID) +{ + OsExcStackInfoReg(g_excStack, sizeof(g_excStack) / sizeof(g_excStack[0])); +} + +VOID OsExcHook(UINT32 excType, ExcContext *excBufAddr, UINT32 far, UINT32 fsr) +{ + OsExcType(excType, excBufAddr, far, fsr); + OsExcSysInfo(excType, excBufAddr); + OsExcRegsInfo(excBufAddr); + + BackTrace(excBufAddr->R11); + + (VOID)OsShellCmdTskInfoGet(OS_ALL_TASK_MASK, NULL, OS_PROCESS_INFO_ALL); + +#ifndef LOSCFG_DEBUG_VERSION + if (g_excFromUserMode[ArchCurrCpuid()] != TRUE) { +#endif +#ifdef LOSCFG_KERNEL_VM + OsDumpProcessUsedMemNode(OS_EXC_VMM_NO_REGION); +#endif + OsExcStackInfo(); +#ifndef LOSCFG_DEBUG_VERSION + } +#endif + + OsDumpContextMem(excBufAddr); + + (VOID)OsShellCmdMemCheck(0, NULL); + +#ifdef LOSCFG_COREDUMP + LOS_CoreDumpV2(excType, excBufAddr); +#endif + + OsUserExcHandle(excBufAddr); +} + +VOID OsCallStackInfo(VOID) +{ + UINT32 count = 0; + LosTaskCB *runTask = OsCurrTaskGet(); + UINTPTR stackBottom = runTask->topOfStack + runTask->stackSize; + UINT32 *stackPointer = (UINT32 *)stackBottom; + + PrintExcInfo("runTask->stackPointer = 0x%x\n" + "runTask->topOfStack = 0x%x\n" + "text_start:0x%x,text_end:0x%x\n", + stackPointer, runTask->topOfStack, &__text_start, &__text_end); + + while ((stackPointer > (UINT32 *)runTask->topOfStack) && (count < OS_MAX_BACKTRACE)) { + if ((*stackPointer > (UINTPTR)(&__text_start)) && + (*stackPointer < (UINTPTR)(&__text_end)) && + IS_ALIGNED((*stackPointer), POINTER_SIZE)) { + if ((*(stackPointer - 1) > (UINT32)runTask->topOfStack) && + (*(stackPointer - 1) < stackBottom) && + IS_ALIGNED((*(stackPointer - 1)), POINTER_SIZE)) { + count++; + PrintExcInfo("traceback %u -- lr = 0x%x\n", count, *stackPointer); + } + } + stackPointer--; + } + PRINTK("\n"); +} + +VOID OsTaskBackTrace(UINT32 taskID) +{ + LosTaskCB *taskCB = NULL; + + if (OS_TID_CHECK_INVALID(taskID)) { + PRINT_ERR("\r\nTask ID is invalid!\n"); + return; + } + taskCB = OS_TCB_FROM_TID(taskID); + if (OsTaskIsUnused(taskCB) || (taskCB->taskEntry == NULL)) { + PRINT_ERR("\r\nThe task is not created!\n"); + return; + } + PRINTK("TaskName = %s\n", taskCB->taskName); + PRINTK("TaskID = 0x%x\n", taskCB->taskID); + BackTrace(((TaskContext *)(taskCB->stackPointer))->R11); /* R11 : FP */ +} + +VOID OsBackTrace(VOID) +{ + UINT32 regFP = Get_Fp(); + LosTaskCB *runTask = OsCurrTaskGet(); + PrintExcInfo("OsBackTrace fp = 0x%x\n", regFP); + PrintExcInfo("runTask->taskName = %s\n", runTask->taskName); + PrintExcInfo("runTask->taskID = %u\n", runTask->taskID); + BackTrace(regFP); +} + +#ifdef LOSCFG_GDB +VOID OsUndefIncExcHandleEntry(ExcContext *excBufAddr) +{ + excBufAddr->PC -= 4; /* lr in undef is pc + 4 */ + + if (gdb_undef_hook(excBufAddr, OS_EXCEPT_UNDEF_INSTR)) { + return; + } + + if (g_excHook != NULL) { + /* far, fsr are unused in exc type of OS_EXCEPT_UNDEF_INSTR */ + g_excHook(OS_EXCEPT_UNDEF_INSTR, excBufAddr, 0, 0); + } + while (1) {} +} + +#if __LINUX_ARM_ARCH__ >= 7 +VOID OsPrefetchAbortExcHandleEntry(ExcContext *excBufAddr) +{ + UINT32 far; + UINT32 fsr; + + excBufAddr->PC -= 4; /* lr in prefetch abort is pc + 4 */ + + if (gdbhw_hook(excBufAddr, OS_EXCEPT_PREFETCH_ABORT)) { + return; + } + + if (g_excHook != NULL) { + far = OsArmReadIfar(); + fsr = OsArmReadIfsr(); + g_excHook(OS_EXCEPT_PREFETCH_ABORT, excBufAddr, far, fsr); + } + while (1) {} +} + +VOID OsDataAbortExcHandleEntry(ExcContext *excBufAddr) +{ + UINT32 far; + UINT32 fsr; + + excBufAddr->PC -= 8; /* lr in data abort is pc + 8 */ + + if (gdbhw_hook(excBufAddr, OS_EXCEPT_DATA_ABORT)) { + return; + } + + if (g_excHook != NULL) { + far = OsArmReadDfar(); + fsr = OsArmReadDfsr(); + g_excHook(OS_EXCEPT_DATA_ABORT, excBufAddr, far, fsr); + } + while (1) {} +} +#endif /* __LINUX_ARM_ARCH__ */ +#endif /* LOSCFG_GDB */ + +#ifdef LOSCFG_KERNEL_SMP +#define EXC_WAIT_INTER 50U +#define EXC_WAIT_TIME 2000U + +STATIC VOID WaitAllCpuStop(UINT32 cpuid) +{ + UINT32 i; + UINT32 time = 0; + + while (time < EXC_WAIT_TIME) { + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + if ((i != cpuid) && !OsCpuStatusIsHalt(i)) { + LOS_Mdelay(EXC_WAIT_INTER); + time += EXC_WAIT_INTER; + break; + } + } + /* Other CPUs are all haletd or in the exc. */ + if (i == LOSCFG_KERNEL_CORE_NUM) { + break; + } + } + return; +} + +STATIC VOID OsWaitOtherCoresHandleExcEnd(UINT32 currCpuid) +{ + while (1) { + LOS_SpinLock(&g_excSerializerSpin); + if ((g_currHandleExcCpuid == INVALID_CPUID) || (g_currHandleExcCpuid == currCpuid)) { + g_currHandleExcCpuid = currCpuid; + g_currHandleExcPID = OsCurrProcessGet()->processID; + LOS_SpinUnlock(&g_excSerializerSpin); + break; + } + + if (g_nextExcWaitCpu == INVALID_CPUID) { + g_nextExcWaitCpu = currCpuid; + } + LOS_SpinUnlock(&g_excSerializerSpin); + LOS_Mdelay(EXC_WAIT_INTER); + } +} + +STATIC VOID OsCheckAllCpuStatus(VOID) +{ + UINT32 currCpuid = ArchCurrCpuid(); + UINT32 ret, target; + + OsCpuStatusSet(CPU_EXC); + LOCKDEP_CLEAR_LOCKS(); + + LOS_SpinLock(&g_excSerializerSpin); + /* Only the current CPU anomaly */ + if (g_currHandleExcCpuid == INVALID_CPUID) { + g_currHandleExcCpuid = currCpuid; + g_currHandleExcPID = OsCurrProcessGet()->processID; + LOS_SpinUnlock(&g_excSerializerSpin); +#ifndef LOSCFG_SAVE_EXCINFO + if (g_excFromUserMode[currCpuid] == FALSE) { + target = (UINT32)(OS_MP_CPU_ALL & ~CPUID_TO_AFFI_MASK(currCpuid)); + HalIrqSendIpi(target, LOS_MP_IPI_HALT); + } +#endif + } else if (g_excFromUserMode[currCpuid] == TRUE) { + /* Both cores raise exceptions, and the current core is a user-mode exception. + * Both cores are abnormal and come from the same process + */ + if (OsCurrProcessGet()->processID == g_currHandleExcPID) { + LOS_SpinUnlock(&g_excSerializerSpin); + OsExcRestore(); + ret = LOS_TaskDelete(OsCurrTaskGet()->taskID); + LOS_Panic("%s supend task :%u failed: 0x%x\n", __FUNCTION__, OsCurrTaskGet()->taskID, ret); + } + LOS_SpinUnlock(&g_excSerializerSpin); + + OsWaitOtherCoresHandleExcEnd(currCpuid); + } else { + if ((g_currHandleExcCpuid < LOSCFG_KERNEL_CORE_NUM) && (g_excFromUserMode[g_currHandleExcCpuid] == TRUE)) { + g_currHandleExcCpuid = currCpuid; + LOS_SpinUnlock(&g_excSerializerSpin); + target = (UINT32)(OS_MP_CPU_ALL & ~CPUID_TO_AFFI_MASK(currCpuid)); + HalIrqSendIpi(target, LOS_MP_IPI_HALT); + } else { + LOS_SpinUnlock(&g_excSerializerSpin); + while (1) {} + } + } +#ifndef LOSCFG_SAVE_EXCINFO + /* use halt ipi to stop other active cores */ + if (g_excFromUserMode[ArchCurrCpuid()] == FALSE) { + WaitAllCpuStop(currCpuid); + } +#endif +} +#endif + +STATIC VOID OsCheckCpuStatus(VOID) +{ +#ifdef LOSCFG_KERNEL_SMP + OsCheckAllCpuStatus(); +#else + g_currHandleExcCpuid = ArchCurrCpuid(); +#endif +} + +LITE_OS_SEC_TEXT VOID STATIC OsExcPriorDisposal(ExcContext *excBufAddr) +{ + if ((excBufAddr->regCPSR & CPSR_MASK_MODE) == CPSR_USER_MODE) { + g_minAddr = USER_ASPACE_BASE; + g_maxAddr = USER_ASPACE_BASE + USER_ASPACE_SIZE; + g_excFromUserMode[ArchCurrCpuid()] = TRUE; + } else { + g_minAddr = KERNEL_ASPACE_BASE; + g_maxAddr = KERNEL_ASPACE_BASE + KERNEL_ASPACE_SIZE; + g_excFromUserMode[ArchCurrCpuid()] = FALSE; + } + + OsCheckCpuStatus(); + +#ifdef LOSCFG_KERNEL_SMP +#ifdef LOSCFG_FS_VFS + /* Wait for the end of the Console task to avoid multicore printing code */ + OsWaitConsoleSendTaskPend(OsCurrTaskGet()->taskID); +#endif +#endif +} + +LITE_OS_SEC_TEXT_INIT STATIC VOID OsPrintExcHead(UINT32 far) +{ +#ifdef LOSCFG_BLACKBOX +#ifdef LOSCFG_SAVE_EXCINFO + SetExcInfoIndex(0); +#endif +#endif +#ifdef LOSCFG_KERNEL_VM + /* You are not allowed to add any other print information before this exception information */ + if (g_excFromUserMode[ArchCurrCpuid()] == TRUE) { +#ifdef LOSCFG_DEBUG_VERSION + VADDR_T vaddr = ROUNDDOWN(far, PAGE_SIZE); + LosVmSpace *space = LOS_SpaceGet(vaddr); + if (space != NULL) { + LOS_DumpMemRegion(vaddr); + } +#endif + PrintExcInfo("##################excFrom: User!####################\n"); + } else +#endif + { + PrintExcInfo("##################excFrom: kernel!###################\n"); + } +} + +#ifdef LOSCFG_SAVE_EXCINFO +STATIC VOID OsSysStateSave(UINT32 *intCount, UINT32 *lockCount) +{ + *intCount = g_intCount[ArchCurrCpuid()]; + *lockCount = OsSchedLockCountGet(); + g_intCount[ArchCurrCpuid()] = 0; + OsSchedLockSet(0); +} + +STATIC VOID OsSysStateRestore(UINT32 intCount, UINT32 lockCount) +{ + g_intCount[ArchCurrCpuid()] = intCount; + OsSchedLockSet(lockCount); +} +#endif + +/* + * Description : EXC handler entry + * Input : excType --- exc type + * excBufAddr --- address of EXC buf + */ +LITE_OS_SEC_TEXT_INIT VOID OsExcHandleEntry(UINT32 excType, ExcContext *excBufAddr, UINT32 far, UINT32 fsr) +{ +#ifdef LOSCFG_SAVE_EXCINFO + UINT32 intCount; + UINT32 lockCount; +#endif + + /* Task scheduling is not allowed during exception handling */ + OsSchedLock(); + + g_curNestCount[ArchCurrCpuid()]++; + + OsExcPriorDisposal(excBufAddr); + + OsPrintExcHead(far); + +#ifdef LOSCFG_KERNEL_SMP + OsAllCpuStatusOutput(); +#endif + +#ifdef LOSCFG_SAVE_EXCINFO + log_read_write_fn func = GetExcInfoRW(); +#endif + + if (g_excHook != NULL) { + if (g_curNestCount[ArchCurrCpuid()] == 1) { +#ifdef LOSCFG_SAVE_EXCINFO + if (func != NULL) { +#ifndef LOSCFG_BLACKBOX + SetExcInfoIndex(0); +#endif + OsSysStateSave(&intCount, &lockCount); + OsRecordExcInfoTime(); + OsSysStateRestore(intCount, lockCount); + } +#endif + g_excHook(excType, excBufAddr, far, fsr); + } else { + OsCallStackInfo(); + } + +#ifdef LOSCFG_SAVE_EXCINFO + if (func != NULL) { + PrintExcInfo("Be sure flash space bigger than GetExcInfoIndex():0x%x\n", GetExcInfoIndex()); + OsSysStateSave(&intCount, &lockCount); + func(GetRecordAddr(), GetRecordSpace(), 0, GetExcInfoBuf()); + OsSysStateRestore(intCount, lockCount); + } +#endif + } + +#ifdef LOSCFG_SHELL_CMD_DEBUG + SystemRebootFunc rebootHook = OsGetRebootHook(); + if ((OsSystemExcIsReset() == TRUE) && (rebootHook != NULL)) { + LOS_Mdelay(3000); /* 3000: System dead, delay 3 seconds after system restart */ + rebootHook(); + } +#endif + +#ifdef LOSCFG_BLACKBOX + BBoxNotifyError(EVENT_PANIC, MODULE_SYSTEM, "Crash in kernel", 1); +#endif + while (1) {} +} + +__attribute__((noinline)) VOID LOS_Panic(const CHAR *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + OsVprintf(fmt, ap, EXC_OUTPUT); + va_end(ap); + __asm__ __volatile__("swi 0"); + while (1) {} +} + +/* stack protector */ +USED UINT32 __stack_chk_guard = 0xd00a0dff; + +VOID __stack_chk_fail(VOID) +{ + /* __builtin_return_address is a builtin function, building in gcc */ + LOS_Panic("stack-protector: Kernel stack is corrupted in: %p\n", + __builtin_return_address(0)); +} + +VOID LOS_RecordLR(UINTPTR *LR, UINT32 LRSize, UINT32 recordCount, UINT32 jumpCount) +{ + UINT32 count = 0; + UINT32 index = 0; + UINT32 stackStart, stackEnd; + LosTaskCB *taskCB = NULL; + UINTPTR framePtr, tmpFramePtr, linkReg; + + if (LR == NULL) { + return; + } + /* if LR array is not enough,just record LRSize. */ + if (LRSize < recordCount) { + recordCount = LRSize; + } + + taskCB = OsCurrTaskGet(); + stackStart = taskCB->topOfStack; + stackEnd = stackStart + taskCB->stackSize; + + framePtr = Get_Fp(); + while ((framePtr > stackStart) && (framePtr < stackEnd) && IS_ALIGNED(framePtr, sizeof(CHAR *))) { + tmpFramePtr = framePtr; +#ifdef LOSCFG_COMPILER_CLANG_LLVM + linkReg = *(UINTPTR *)(tmpFramePtr + sizeof(UINTPTR)); +#else + linkReg = *(UINTPTR *)framePtr; +#endif + if (index >= jumpCount) { + LR[count++] = linkReg; + if (count == recordCount) { + break; + } + } + index++; +#ifdef LOSCFG_COMPILER_CLANG_LLVM + framePtr = *(UINTPTR *)framePtr; +#else + framePtr = *(UINTPTR *)(tmpFramePtr - sizeof(UINTPTR)); +#endif + } + + /* if linkReg is not enough,clean up the last of the effective LR as the end. */ + if (count < recordCount) { + LR[count] = 0; + } +} + diff --git a/src/kernel_liteos_a/arch/arm/arm/src/los_hw.c b/src/kernel_liteos_a/arch/arm/arm/src/los_hw.c new file mode 100644 index 00000000..ba04a89f --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/src/los_hw.c @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_hw_pri.h" +#include "los_task_pri.h" + +/* support cpu vendors */ +CpuVendor g_cpuTable[] = { + /* armv7-a */ + { 0xc07, "Cortex-A7" }, + { 0xc09, "Cortex-A9" }, + { 0, NULL } +}; + +/* logical cpu mapping */ +UINT64 g_cpuMap[LOSCFG_KERNEL_CORE_NUM] = { + [0 ... LOSCFG_KERNEL_CORE_NUM - 1] = (UINT64)(-1) +}; + +/* bit[30] is enable FPU */ +#define FP_EN (1U << 30) +LITE_OS_SEC_TEXT_INIT VOID OsTaskExit(VOID) +{ + __asm__ __volatile__("swi 0"); +} + +#ifdef LOSCFG_GDB +STATIC VOID OsTaskEntrySetupLoopFrame(UINT32) __attribute__((noinline, naked)); +VOID OsTaskEntrySetupLoopFrame(UINT32 arg0) +{ + asm volatile("\tsub fp, sp, #0x4\n" + "\tpush {fp, lr}\n" + "\tadd fp, sp, #0x4\n" + "\tpush {fp, lr}\n" + + "\tadd fp, sp, #0x4\n" + "\tbl OsTaskEntry\n" + + "\tpop {fp, lr}\n" + "\tpop {fp, pc}\n"); +} +#endif + +LITE_OS_SEC_TEXT_INIT VOID *OsTaskStackInit(UINT32 taskID, UINT32 stackSize, VOID *topStack, BOOL initFlag) +{ + if (initFlag == TRUE) { + OsStackInit(topStack, stackSize); + } + TaskContext *taskContext = (TaskContext *)(((UINTPTR)topStack + stackSize) - sizeof(TaskContext)); + + /* initialize the task context */ +#ifdef LOSCFG_GDB + taskContext->PC = (UINTPTR)OsTaskEntrySetupLoopFrame; +#else + taskContext->PC = (UINTPTR)OsTaskEntry; +#endif + taskContext->LR = (UINTPTR)OsTaskExit; /* LR should be kept, to distinguish it's THUMB or ARM instruction */ + taskContext->R0 = taskID; /* R0 */ + +#ifdef LOSCFG_THUMB + taskContext->regCPSR = PSR_MODE_SVC_THUMB; /* CPSR (Enable IRQ and FIQ interrupts, THUMNB-mode) */ +#else + taskContext->regCPSR = PSR_MODE_SVC_ARM; /* CPSR (Enable IRQ and FIQ interrupts, ARM-mode) */ +#endif + +#if !defined(LOSCFG_ARCH_FPU_DISABLE) + /* 0xAAA0000000000000LL : float reg initialed magic word */ + for (UINT32 index = 0; index < FP_REGS_NUM; index++) { + taskContext->D[index] = 0xAAA0000000000000LL + index; /* D0 - D31 */ + } + taskContext->regFPSCR = 0; + taskContext->regFPEXC = FP_EN; +#endif + + return (VOID *)taskContext; +} + +VOID OsUserCloneParentStack(VOID *childStack, UINTPTR sp, UINTPTR parentTopOfStack, UINT32 parentStackSize) +{ + LosTaskCB *task = OsCurrTaskGet(); + sig_cb *sigcb = &task->sig; + VOID *cloneStack = NULL; + + if (sigcb->sigContext != NULL) { + cloneStack = (VOID *)((UINTPTR)sigcb->sigContext - sizeof(TaskContext)); + } else { + cloneStack = (VOID *)(((UINTPTR)parentTopOfStack + parentStackSize) - sizeof(TaskContext)); + } + + (VOID)memcpy_s(childStack, sizeof(TaskContext), cloneStack, sizeof(TaskContext)); + ((TaskContext *)childStack)->R0 = 0; + if (sp != 0) { + ((TaskContext *)childStack)->USP = TRUNCATE(sp, LOSCFG_STACK_POINT_ALIGN_SIZE); + ((TaskContext *)childStack)->ULR = 0; + } +} + +LITE_OS_SEC_TEXT_INIT VOID OsUserTaskStackInit(TaskContext *context, UINTPTR taskEntry, UINTPTR stack) +{ + LOS_ASSERT(context != NULL); + +#ifdef LOSCFG_THUMB + context->regCPSR = PSR_MODE_USR_THUMB; +#else + context->regCPSR = PSR_MODE_USR_ARM; +#endif + context->R0 = stack; + context->USP = TRUNCATE(stack, LOSCFG_STACK_POINT_ALIGN_SIZE); + context->ULR = 0; + context->PC = (UINTPTR)taskEntry; +} + +VOID OsInitSignalContext(const VOID *sp, VOID *signalContext, UINTPTR sigHandler, UINT32 signo, UINT32 param) +{ + IrqContext *newSp = (IrqContext *)signalContext; + (VOID)memcpy_s(signalContext, sizeof(IrqContext), sp, sizeof(IrqContext)); + newSp->PC = sigHandler; + newSp->R0 = signo; + newSp->R1 = param; +} + +DEPRECATED VOID Dmb(VOID) +{ + __asm__ __volatile__ ("dmb" : : : "memory"); +} + +DEPRECATED VOID Dsb(VOID) +{ + __asm__ __volatile__("dsb" : : : "memory"); +} + +DEPRECATED VOID Isb(VOID) +{ + __asm__ __volatile__("isb" : : : "memory"); +} + +VOID FlushICache(VOID) +{ + /* + * Use ICIALLUIS instead of ICIALLU. ICIALLUIS operates on all processors in the Inner + * shareable domain of the processor that performs the operation. + */ + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c1, 0" : : "r" (0) : "memory"); +} + +VOID DCacheFlushRange(UINT32 start, UINT32 end) +{ + arm_clean_cache_range(start, end); +} + +VOID DCacheInvRange(UINT32 start, UINT32 end) +{ + arm_inv_cache_range(start, end); +} + diff --git a/src/kernel_liteos_a/arch/arm/arm/src/los_hw_exc.S b/src/kernel_liteos_a/arch/arm/arm/src/los_hw_exc.S new file mode 100644 index 00000000..18805462 --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/src/los_hw_exc.S @@ -0,0 +1,424 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "asm.h" +#include "arch_config.h" + + .extern g_losTask + .extern g_intCount + .extern g_curNestCount + .extern OsExcHandleEntry + .extern __svc_stack_top + .extern __exc_stack_top + .extern __stack_chk_guard + .extern OsRandomStackGuard +#ifdef LOSCFG_GDB + .extern OsUndefIncExcHandleEntry +#if __LINUX_ARM_ARCH__ >= 7 + .extern OsPrefetchAbortExcHandleEntry + .extern OsDataAbortExcHandleEntry +#endif +#endif + .extern OsSaveSignalContext + .extern OsRestorSignalContext + .extern OsArmSharedPageFault + .extern OsArmA32SyscallHandle + + .global _osExceptFiqHdl + .global _osExceptAddrAbortHdl + .global _osExceptDataAbortHdl + .global _osExceptPrefetchAbortHdl + .global _osExceptSwiHdl + .global _osExceptUndefInstrHdl +#if defined(LOSCFG_CC_STACKPROTECTOR_ALL) || \ + defined(LOSCFG_CC_STACKPROTECTOR_STRONG) || \ + defined(LOSCFG_CC_STACKPROTECTOR) + .global __stack_chk_guard_setup +#endif + + .fpu vfpv4 + +.macro PUSH_FPU_REGS reg1 +#if !defined(LOSCFG_ARCH_FPU_DISABLE) + VMRS \reg1, FPEXC + PUSH {\reg1} + VMRS \reg1, FPSCR + PUSH {\reg1} +#if defined(LOSCFG_ARCH_FPU_VFP_D32) + VPUSH {D16-D31} +#endif + VPUSH {D0-D15} +#endif +.endm + +.macro POP_FPU_REGS reg1 +#if !defined(LOSCFG_ARCH_FPU_DISABLE) + VPOP {D0-D15} +#if defined(LOSCFG_ARCH_FPU_VFP_D32) + VPOP {D16-D31} +#endif + POP {\reg1} + VMSR FPSCR, \reg1 + POP {\reg1} + VMSR FPEXC, \reg1 +#endif +.endm + +#ifdef LOSCFG_GDB +.macro GDB_HANDLE fun + SUB SP, SP, #12 + + STMFD SP!, {R0-R12} + MRS R1, SPSR + STMFD SP!, {R1} @save spsr + + ADD R0, SP, #14 * 4 + MOV R3, LR @save pc + + MRS R1, CPSR + MRS R2, SPSR + MOV R4, SP + + ORR R2, R2, #(CPSR_INT_DISABLE) + MSR CPSR_c, R2 + + STR SP, [R0] @SP + STR LR, [R0, #4] @LR + STR R3, [R0, #8] @PC + + ORR R1, R1, #(CPSR_INT_DISABLE) + BIC R1, R1, #OS_PSR_THUMB + MSR CPSR_c, R1 + MOV R0, R4 + + BL \fun + + ADD SP, SP, #4 + LDMFD SP!, {R0-R12} + + MOV R0, SP + ADD SP, SP, #8 + + LDR R1, [R0, #8] @get pc + STMFD SP!, {R1} + + AND R1, R1, #0x03 + CMP R1, #0 + BEQ 1f + LDR R1, [R0, #-14 * 4] + ORR R1, R1, #OS_PSR_THUMB + B 2f +1: + LDR R1, [R0, #-14 * 4] + +2: + MSR SPSR, R1 + + LDR R1, [R0, #-12 * 4] @get R1 + STMFD SP!, {R1} + LDR R1, [R0,#-13 * 4] @get R0 + STMFD SP!, {R1} + + LDMFD SP!, {R0-R1, PC}^ +.endm +#endif + +#if defined(LOSCFG_CC_STACKPROTECTOR_ALL) || \ + defined(LOSCFG_CC_STACKPROTECTOR_STRONG) || \ + defined(LOSCFG_CC_STACKPROTECTOR) +@ Description: Stack-Protector Init +__stack_chk_guard_setup: + PUSH {FP, LR} +#if defined(LOSCFG_PLATFORM_HI3516DV300) || defined(LOSCFG_PLATFORM_HI3518EV300) + /* Randomize __stack_chk_quard using platform-specific function. */ + BL OsRandomStackGuard + LDR R1, =__stack_chk_guard + MOV R3, R0 + ORR R2, R3, #0X80000000 + STR R2, [R1] +#endif + POP {FP, PC} +#endif + +@ Description: Undefined instruction exception handler +_osExceptUndefInstrHdl: +#ifdef LOSCFG_GDB + GDB_HANDLE OsUndefIncExcHandleEntry +#else + SRSFD #CPSR_SVC_MODE! @ Save pc and cpsr to svc sp, ARMv6 and above support + MSR CPSR_c, #(CPSR_INT_DISABLE | CPSR_SVC_MODE) @ Switch to svc mode, and disable all interrupt + STMFD SP!, {R0-R3, R12, LR} + STMFD SP, {R13, R14}^ @ push user sp and lr + SUB SP, SP, #(2 * 4) + MOV R2, #0 + MOV R3, #0 + STMFD SP!, {R2-R3} @ far and fsr fields, are 0 under this anomaly + STMFD SP!, {R4-R11} + + MOV R0, #OS_EXCEPT_UNDEF_INSTR @ Set exception ID to OS_EXCEPT_UNDEF_INSTR. + B _osExceptDispatch @ Branch to global exception handler. +#endif + +@ Description: Software interrupt exception handler +_osExceptSwiHdl: + SRSFD #CPSR_SVC_MODE! @ Save pc and cpsr to svc sp, ARMv6 and above support + STMFD SP!, {R0-R3, R12, LR} + STMFD SP, {R13, R14}^ + SUB SP, SP, #(4 * 4) @ push user sp and lr and jump reserved field + STR R7, [SP, #0] @ Save system call number to reserved2 filed + +#ifdef LOSCFG_KERNEL_SYSCALL + LDR R3, [SP, #(11 * 4)] + AND R1, R3, #CPSR_MASK_MODE @ Interrupted mode + CMP R1, #CPSR_USER_MODE @ User mode + BNE _osKernelSVCHandler @ Branch if not user mode + + CMP R7, #119 @ __NR_sigreturn + BNE _osIsSyscall + MOV R0, SP + BLX OsRestorSignalContext + MOV SP, R0 + B _osSyscallReturn + +_osIsSyscall: + STMFD SP!, {R4-R11} + + PUSH_FPU_REGS R1 + + MOV R0, SP + MOV FP, #0 @ Init frame pointer + CPSIE I + BLX OsArmA32SyscallHandle + CPSID I + + POP_FPU_REGS R1 + LDMFD SP!, {R4-R11} + + MOV R0, SP + SUB SP, SP, #(12 * 4) @ sp - sizeof(IrqContext), reserved for signal + MOV R1, SP + BLX OsSaveSignalContext + MOV SP, R0 + +_osSyscallReturn: + LDR R7, [SP, #0] + ADD SP, SP, #(2 * 4) @ jump reserved filed + LDMFD SP, {R13, R14}^ @ Restore user mode R13/R14 + ADD SP, SP, #(2 * 4) + LDMFD SP!, {R0-R3, R12, LR} + RFEIA SP! @ Return to user + +_osKernelSVCHandler: +#endif + MOV R0, #0 + STR R0, [SP, #0] + STR R0, [SP, #4] + STMFD SP!, {R4-R11} + MOV R0, #OS_EXCEPT_SWI @ Set exception ID to OS_EXCEPT_SWI. + B _osExceptDispatch @ Branch to global exception handler. + +@ Description: Prefectch abort exception handler +_osExceptPrefetchAbortHdl: +#ifdef LOSCFG_GDB +#if __LINUX_ARM_ARCH__ >= 7 + GDB_HANDLE OsPrefetchAbortExcHandleEntry +#endif +#else + SUB LR, LR, #4 @ LR offset to return from this exception: -4. + + SRSFD #CPSR_SVC_MODE! @ Save pc and cpsr to svc sp, ARMv6 and above support + MSR CPSR_c, #(CPSR_INT_DISABLE | CPSR_SVC_MODE) @ Switch to svc mode, and disable all interrupt + STMFD SP!, {R0-R3, R12, LR} + STMFD SP, {R13, R14}^ + SUB SP, SP, #(2 * 4) + + MRC P15, 0, R2, C6, C0, 2 + MRC P15, 0, R3, C5, C0, 1 + STMFD SP!, {R2-R3} @ Save far and fsr + STMFD SP!, {R4-R11} + +#ifdef LOSCFG_KERNEL_VM + LDR R0, [SP, #(19 * 4)] + AND R0, R0, #CPSR_MASK_MODE @ Interrupted mode + CMP R0, #CPSR_USER_MODE @ User mode + BNE _osKernelExceptPrefetchAbortHdl + + MOV R1, SP + PUSH_FPU_REGS R0 + + MOV R0, #OS_EXCEPT_PREFETCH_ABORT + BLX OsArmSharedPageFault + CMP R0, #0 + + POP_FPU_REGS R0 + BEQ _osExcPageFaultReturn +#endif + +_osKernelExceptPrefetchAbortHdl: + MOV R0, #OS_EXCEPT_PREFETCH_ABORT + B _osExceptDispatch @ Branch to global exception handler. +#endif + +@ Description: Data abort exception handler +_osExceptDataAbortHdl: +#ifdef LOSCFG_GDB +#if __LINUX_ARM_ARCH__ >= 7 + GDB_HANDLE OsDataAbortExcHandleEntry +#endif +#else + SUB LR, LR, #8 @ LR offset to return from this exception: -8. + + SRSFD #CPSR_SVC_MODE! @ Save pc and cpsr to svc sp, ARMv6 and above support + MSR CPSR_c, #(CPSR_INT_DISABLE | CPSR_SVC_MODE) @ Switch to svc mode, and disable all interrupt + STMFD SP!, {R0-R3, R12, LR} + STMFD SP, {R13, R14}^ + SUB SP, SP, #(2 * 4) + + MRC P15, 0, R2, C6, C0, 0 + MRC P15, 0, R3, C5, C0, 0 + STMFD SP!, {R2-R3} @ Save far and fsr + STMFD SP!, {R4-R11} + +#ifdef LOSCFG_KERNEL_VM + MOV R1, SP + PUSH_FPU_REGS R0 + + MOV R0, #OS_EXCEPT_DATA_ABORT @ Set exception ID to OS_EXCEPT_DATA_ABORT. + BLX OsArmSharedPageFault + CMP R0, #0 + POP_FPU_REGS R0 + BEQ _osExcPageFaultReturn +#endif + + MOV R0, #OS_EXCEPT_DATA_ABORT + B _osExceptDispatch +#endif + +#ifdef LOSCFG_KERNEL_VM +_osExcPageFaultReturn: + LDMFD SP!, {R4-R11} + + MOV R0, SP + STR R7, [SP, #0] + SUB SP, SP, #(12 * 4) @ sp - sizeof(IrqContext), reserved for signal + MOV R1, SP + BLX OsSaveSignalContext + MOV SP, R0 + + ADD SP, SP, #(2 * 4) + LDMFD SP, {R13, R14}^ + ADD SP, SP, #(2 * 4) @ Jump reserved fileds + LDMFD SP!, {R0-R3, R12, LR} + RFEIA SP! +#endif + +@ Description: Address abort exception handler +_osExceptAddrAbortHdl: + SUB LR, LR, #8 @ LR offset to return from this exception: -8. + + SRSFD #CPSR_SVC_MODE! @ Save pc and cpsr to svc sp, ARMv6 and above support + MSR CPSR_c, #(CPSR_INT_DISABLE | CPSR_SVC_MODE) @ Switch to svc mode, and disable all interrupt + STMFD SP!, {R0-R3, R12, LR} + STMFD SP, {R13, R14}^ + SUB SP, SP, #(2 * 4) + + MOV R2, #0 + MOV R3, #0 + STMFD SP!, {R2-R3} @ far and fsr fields, are 0 under this anomaly + STMFD SP!, {R4-R11} + + MOV R0, #OS_EXCEPT_ADDR_ABORT @ Set exception ID to OS_EXCEPT_ADDR_ABORT. + B _osExceptDispatch @ Branch to global exception handler. + +@ Description: Fast interrupt request exception handler +_osExceptFiqHdl: + SUB LR, LR, #4 @ LR offset to return from this exception: -4. + + SRSFD #CPSR_SVC_MODE! @ Save pc and cpsr to svc sp, ARMv6 and above support + MSR CPSR_c, #(CPSR_INT_DISABLE | CPSR_SVC_MODE) @ Switch to svc mode, and disable all interrupt + STMFD SP!, {R0-R3, R12, LR} + STMFD SP, {R13, R14}^ + SUB SP, SP, #(2 * 4) + + MOV R2, #0 + MOV R3, #0 + STMFD SP!, {R2-R3} @ far and fsr fields, are 0 under this anomaly + STMFD SP!, {R4-R11} + +@ Description: Exception handler +@ Parameter : R0 Exception Type +@ Regs Hold : R3 Exception`s CPSR +_osExceptDispatch: + LDR R8, [SP, #(8 * 4)] @ Get far + LDR R9, [SP, #(9 * 4)] @ Get fsr + + ADD R2, SP, #(20 * 4) @ sp + sizeof(ExcContext), position of SVC stack before exception + STR R2, [SP, #(8 * 4)] @ Save svc sp + + MOV R1, SP + +#ifdef LOSCFG_KERNEL_VM + LDR R2, [SP, #(19 * 4)] @ Get CPSR + AND R2, R2, #CPSR_MASK_MODE @ Interrupted mode + CMP R2, #CPSR_USER_MODE @ User mode + BEQ _osExceptionGetSP +#endif + + EXC_SP_SET __exc_stack_top, OS_EXC_STACK_SIZE, R6, R7 + + MRC P15, 0, R4, C0, C0, 5 + AND R4, R4, #MPIDR_CPUID_MASK @ Get Current cpu id + LSL R2, R4, #2 + LDR R3, =g_curNestCount @ if(g_curNestCount > 0) dump to _osExceptionGetSP + ADD R3, R3, R2 + LDR R4, [R3] + + CMP R4, #0 + BNE _osExceptionGetSP + + LDR R3, =g_intCount @ Judge the exception is occur in task stack or system stack + ADD R3, R3, R2 + LDR R4, [R3] + + CMP R4, #0 @ if (g_intCount[ArchCurrCpuid()] > 0) + BNE _osExceptionGetSP @ can not switch svc stack + + EXC_SP_SET __svc_stack_top, OS_EXC_SVC_STACK_SIZE, R6, R7 @ Switch to unified exception stack. + ADD R4, R4, #1 + STR R4, [R3] + +_osExceptionGetSP: + MOV R2, R8 @ far + MOV R3, R9 @ fsr + LDR R5, =OsExcHandleEntry @ OsExcHandleEntry(UINT32 excType, ExcContext * excBufAddr) + BX R5 + + .end diff --git a/src/kernel_liteos_a/arch/arm/arm/src/los_hw_runstop.S b/src/kernel_liteos_a/arch/arm/arm/src/los_hw_runstop.S new file mode 100644 index 00000000..b8f8cf74 --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/src/los_hw_runstop.S @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "arch_config.h" + + .equ MPIDR_CPUID_MASK, 0xffU + + .extern g_saveAR + .extern g_saveSRContext + + .global OsSRSaveRegister + .global OsSRRestoreRegister + + .fpu vfpv4 + @.fpu neon + .arch armv7a + + .text + +OsSRSaveRegister: + PUSH {R2} + LDR R2, =g_saveAR + STR R0, [R2] + STR R1, [R2, #4] + POP {R2} + + MRC P15, 0, R0, c0, c0, 5 + AND R0, R0, #MPIDR_CPUID_MASK + MOV R1, #72 @This number is the total number of bytes in the task context register(R0~R15, SPSR, CPSR). + MUL R1, R1, R0 + + LDR R0, =g_saveSRContext + ADD R0, R0, R1 + ADD R0, R0, #72 + + MOV R1, SP + STMFD R0!, {R1} + + MRS R1, SPSR + STMFD R0!, {R1} + + MOV R1, LR + STMFD R0!, {R1} @PC + STMFD R0!, {R1} @LR + + STMFD R0!, {R12} + + MOV R12, R0 + + LDR R0, =g_saveAR + LDR R0, [R0] + LDR R1, =g_saveAR + LDR R1, [R1, #4] + + STMFD R12!, {R0-R3} + STMFD R12!, {R4-R11} + + MRS R0, CPSR + STMFD R12!, {R0} + + BX LR + +OsSRRestoreRegister: + MRC P15, 0, R0, c0, c0, 5 + AND R0, R0, #MPIDR_CPUID_MASK + MOV R1, #72 @This number is the total number of bytes in the task context register(R0~R15, SPSR, CPSR). + MUL R1, R1, R0 + + LDR R12, =g_saveSRContext + ADD R12, R12, R1 + + LDMFD R12!, {R0} + MSR CPSR_cxsf, R0 + + LDMFD R12!, {R4-R11} + LDMFD R12!, {R0-R3} + + PUSH {R2} + LDR R2, =g_saveAR + STR R0, [R2] + STR R1, [R2, #4] + POP {R2} + + MOV R0, R12 + LDMFD R0!, {R12} + LDMFD R0!, {R1} @LR + LDMFD R0!, {R1} @PC + + MOV LR, R1 + + LDMFD R0!, {R1} + MSR SPSR_cxsf, R1 + + LDMFD R0!, {R1} + MOV SP, R1 + + LDR R0, =g_saveAR + LDR R0, [R0] + LDR R1, =g_saveAR + LDR R1, [R1, #4] + + BX LR + + .end diff --git a/src/kernel_liteos_a/arch/arm/arm/src/los_hw_tick.c b/src/kernel_liteos_a/arch/arm/arm/src/los_hw_tick.c new file mode 100644 index 00000000..4210f638 --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/src/los_hw_tick.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_sys_pri.h" +#include "los_hwi.h" + + +LITE_OS_SEC_TEXT_INIT UINT32 OsTickInit(UINT32 systemClock, UINT32 tickPerSecond) +{ + if ((systemClock == 0) || + (tickPerSecond == 0) || + (tickPerSecond > systemClock)) { + return LOS_ERRNO_TICK_CFG_INVALID; + } + HalClockInit(); + + return LOS_OK; +} + +LITE_OS_SEC_TEXT_INIT VOID OsTickStart(VOID) +{ + HalClockStart(); +} + +LITE_OS_SEC_TEXT_MINOR VOID LOS_GetCpuCycle(UINT32 *highCnt, UINT32 *lowCnt) +{ + UINT64 cycle = HalClockGetCycles(); + + *highCnt = cycle >> 32; /* 32: offset 32 bits and retain high bits */ + *lowCnt = cycle & 0xFFFFFFFFU; +} + +LITE_OS_SEC_TEXT_MINOR UINT64 LOS_CurrNanosec(VOID) +{ + UINT64 cycle = HalClockGetCycles(); + return (cycle / g_sysClock) * OS_SYS_NS_PER_SECOND + (cycle % g_sysClock) * OS_SYS_NS_PER_SECOND / g_sysClock; +} + +LITE_OS_SEC_TEXT_MINOR VOID LOS_Udelay(UINT32 usecs) +{ + HalDelayUs(usecs); +} + +LITE_OS_SEC_TEXT_MINOR VOID LOS_Mdelay(UINT32 msecs) +{ + HalDelayUs(msecs * 1000); /* 1000 : 1ms = 1000us */ +} + diff --git a/src/kernel_liteos_a/arch/arm/arm/src/los_hwi.c b/src/kernel_liteos_a/arch/arm/arm/src/los_hwi.c new file mode 100644 index 00000000..dd41e50d --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/src/los_hwi.c @@ -0,0 +1,346 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_hwi.h" +#include "los_memory.h" +#include "los_spinlock.h" +#ifdef LOSCFG_KERNEL_CPUP +#include "los_cpup_pri.h" +#endif +#include "los_sched_pri.h" +#include "los_hook.h" + +/* spinlock for hwi module, only available on SMP mode */ +LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_hwiSpin); +#define HWI_LOCK(state) LOS_SpinLockSave(&g_hwiSpin, &(state)) +#define HWI_UNLOCK(state) LOS_SpinUnlockRestore(&g_hwiSpin, (state)) + +size_t g_intCount[LOSCFG_KERNEL_CORE_NUM] = {0}; +HwiHandleForm g_hwiForm[OS_HWI_MAX_NUM]; +STATIC CHAR *g_hwiFormName[OS_HWI_MAX_NUM] = {0}; +STATIC UINT32 g_hwiFormCnt[LOSCFG_KERNEL_CORE_NUM][OS_HWI_MAX_NUM] = {0}; + +UINT32 OsGetHwiFormCnt(UINT16 cpuid, UINT32 index) +{ + return g_hwiFormCnt[cpuid][index]; +} + +CHAR *OsGetHwiFormName(UINT32 index) +{ + return g_hwiFormName[index]; +} + +UINT32 LOS_GetSystemHwiMaximum(VOID) +{ + return OS_HWI_MAX_NUM; +} + +typedef VOID (*HWI_PROC_FUNC0)(VOID); +typedef VOID (*HWI_PROC_FUNC2)(INT32, VOID *); +VOID OsInterrupt(UINT32 intNum) +{ + HwiHandleForm *hwiForm = NULL; + UINT32 *intCnt = NULL; + UINT16 cpuid = ArchCurrCpuid(); + + /* Must keep the operation at the beginning of the interface */ + intCnt = &g_intCount[cpuid]; + *intCnt = *intCnt + 1; + +#ifdef LOSCFG_CPUP_INCLUDE_IRQ + OsCpupIrqStart(cpuid); +#endif + + OsSchedIrqStartTime(); + OsHookCall(LOS_HOOK_TYPE_ISR_ENTER, intNum); + hwiForm = (&g_hwiForm[intNum]); +#ifndef LOSCFG_NO_SHARED_IRQ + while (hwiForm->pstNext != NULL) { + hwiForm = hwiForm->pstNext; +#endif + if (hwiForm->uwParam) { + HWI_PROC_FUNC2 func = (HWI_PROC_FUNC2)hwiForm->pfnHook; + if (func != NULL) { + UINTPTR *param = (UINTPTR *)(hwiForm->uwParam); + func((INT32)(*param), (VOID *)(*(param + 1))); + } + } else { + HWI_PROC_FUNC0 func = (HWI_PROC_FUNC0)hwiForm->pfnHook; + if (func != NULL) { + func(); + } + } +#ifndef LOSCFG_NO_SHARED_IRQ + } +#endif + ++g_hwiFormCnt[cpuid][intNum]; + + OsHookCall(LOS_HOOK_TYPE_ISR_EXIT, intNum); + OsSchedIrqUsedTimeUpdate(); + +#ifdef LOSCFG_CPUP_INCLUDE_IRQ + OsCpupIrqEnd(cpuid, intNum); +#endif + /* Must keep the operation at the end of the interface */ + *intCnt = *intCnt - 1; +} + +STATIC HWI_ARG_T OsHwiCpIrqParam(const HwiIrqParam *irqParam) +{ + HwiIrqParam *paramByAlloc = NULL; + + if (irqParam != NULL) { + paramByAlloc = (HwiIrqParam *)LOS_MemAlloc(m_aucSysMem0, sizeof(HwiIrqParam)); + if (paramByAlloc == NULL) { + return LOS_NOK; + } + (VOID)memcpy_s(paramByAlloc, sizeof(HwiIrqParam), irqParam, sizeof(HwiIrqParam)); + } + /* When "irqParam" is NULL, the function return 0(LOS_OK). */ + return (HWI_ARG_T)paramByAlloc; +} + +#ifdef LOSCFG_NO_SHARED_IRQ +STATIC UINT32 OsHwiDelNoShared(HWI_HANDLE_T hwiNum) +{ + UINT32 intSave; + + HWI_LOCK(intSave); + g_hwiForm[hwiNum].pfnHook = NULL; + if (g_hwiForm[hwiNum].uwParam) { + (VOID)LOS_MemFree(m_aucSysMem0, (VOID *)g_hwiForm[hwiNum].uwParam); + } + g_hwiForm[hwiNum].uwParam = 0; + + HWI_UNLOCK(intSave); + return LOS_OK; +} + +STATIC UINT32 OsHwiCreateNoShared(HWI_HANDLE_T hwiNum, HWI_MODE_T hwiMode, + HWI_PROC_FUNC hwiHandler, const HwiIrqParam *irqParam) +{ + HWI_ARG_T retParam; + UINT32 intSave; + + HWI_LOCK(intSave); + if (g_hwiForm[hwiNum].pfnHook == NULL) { + g_hwiForm[hwiNum].pfnHook = hwiHandler; + + retParam = OsHwiCpIrqParam(irqParam); + if (retParam == LOS_NOK) { + HWI_UNLOCK(intSave); + return OS_ERRNO_HWI_NO_MEMORY; + } + g_hwiForm[hwiNum].uwParam = retParam; + } else { + HWI_UNLOCK(intSave); + return OS_ERRNO_HWI_ALREADY_CREATED; + } + HWI_UNLOCK(intSave); + return LOS_OK; +} +#else +STATIC UINT32 OsHwiDelShared(HWI_HANDLE_T hwiNum, const HwiIrqParam *irqParam) +{ + HwiHandleForm *hwiForm = NULL; + HwiHandleForm *hwiFormtmp = NULL; + UINT32 hwiValid = FALSE; + UINT32 intSave; + + HWI_LOCK(intSave); + hwiForm = &g_hwiForm[hwiNum]; + hwiFormtmp = hwiForm; + + if ((hwiForm->uwParam & IRQF_SHARED) && ((irqParam == NULL) || (irqParam->pDevId == NULL))) { + HWI_UNLOCK(intSave); + return OS_ERRNO_HWI_SHARED_ERROR; + } + + if ((hwiForm->pstNext != NULL) && !(hwiForm->uwParam & IRQF_SHARED)) { + hwiForm = hwiForm->pstNext; + if (hwiForm->uwParam) { + (VOID)LOS_MemFree(m_aucSysMem0, (VOID *)hwiForm->uwParam); + } + (VOID)LOS_MemFree(m_aucSysMem0, hwiForm); + hwiFormtmp->pstNext = NULL; + + g_hwiFormName[hwiNum] = NULL; + + HWI_UNLOCK(intSave); + return LOS_OK; + } + hwiForm = hwiForm->pstNext; + while (hwiForm != NULL) { + if (((HwiIrqParam *)(hwiForm->uwParam))->pDevId != irqParam->pDevId) { + hwiFormtmp = hwiForm; + hwiForm = hwiForm->pstNext; + } else { + hwiFormtmp->pstNext = hwiForm->pstNext; + (VOID)LOS_MemFree(m_aucSysMem0, (VOID *)hwiForm->uwParam); + (VOID)LOS_MemFree(m_aucSysMem0, hwiForm); + + hwiValid = TRUE; + break; + } + } + + if (hwiValid != TRUE) { + HWI_UNLOCK(intSave); + return OS_ERRNO_HWI_HWINUM_UNCREATE; + } + + if (g_hwiForm[hwiNum].pstNext == NULL) { + g_hwiForm[hwiNum].uwParam = 0; + g_hwiFormName[hwiNum] = NULL; + } + + HWI_UNLOCK(intSave); + return LOS_OK; +} + +STATIC UINT32 OsHwiCreateShared(HWI_HANDLE_T hwiNum, HWI_MODE_T hwiMode, + HWI_PROC_FUNC hwiHandler, const HwiIrqParam *irqParam) +{ + UINT32 intSave; + HwiHandleForm *hwiFormNode = NULL; + HwiHandleForm *hwiForm = NULL; + HwiIrqParam *hwiParam = NULL; + HWI_MODE_T modeResult = hwiMode & IRQF_SHARED; + + if (modeResult && ((irqParam == NULL) || (irqParam->pDevId == NULL))) { + return OS_ERRNO_HWI_SHARED_ERROR; + } + + HWI_LOCK(intSave); + + hwiForm = &g_hwiForm[hwiNum]; + if ((hwiForm->pstNext != NULL) && ((modeResult == 0) || (!(hwiForm->uwParam & IRQF_SHARED)))) { + HWI_UNLOCK(intSave); + return OS_ERRNO_HWI_SHARED_ERROR; + } + + while (hwiForm->pstNext != NULL) { + hwiForm = hwiForm->pstNext; + hwiParam = (HwiIrqParam *)(hwiForm->uwParam); + if (hwiParam->pDevId == irqParam->pDevId) { + HWI_UNLOCK(intSave); + return OS_ERRNO_HWI_ALREADY_CREATED; + } + } + + hwiFormNode = (HwiHandleForm *)LOS_MemAlloc(m_aucSysMem0, sizeof(HwiHandleForm)); + if (hwiFormNode == NULL) { + HWI_UNLOCK(intSave); + return OS_ERRNO_HWI_NO_MEMORY; + } + + hwiFormNode->uwParam = OsHwiCpIrqParam(irqParam); + if (hwiFormNode->uwParam == LOS_NOK) { + HWI_UNLOCK(intSave); + (VOID)LOS_MemFree(m_aucSysMem0, hwiFormNode); + return OS_ERRNO_HWI_NO_MEMORY; + } + + hwiFormNode->pfnHook = hwiHandler; + hwiFormNode->pstNext = (struct tagHwiHandleForm *)NULL; + hwiForm->pstNext = hwiFormNode; + + if ((irqParam != NULL) && (irqParam->pName != NULL)) { + g_hwiFormName[hwiNum] = (CHAR *)irqParam->pName; + } + + g_hwiForm[hwiNum].uwParam = modeResult; + + HWI_UNLOCK(intSave); + return LOS_OK; +} +#endif + +/* + * Description : initialization of the hardware interrupt + */ +LITE_OS_SEC_TEXT_INIT VOID OsHwiInit(VOID) +{ + UINT32 hwiNum; + + for (hwiNum = 0; hwiNum < OS_HWI_MAX_NUM; hwiNum++) { + g_hwiForm[hwiNum].pfnHook = NULL; + g_hwiForm[hwiNum].uwParam = 0; + g_hwiForm[hwiNum].pstNext = NULL; + } + + (VOID)memset_s(g_hwiFormName, (sizeof(CHAR *) * OS_HWI_MAX_NUM), 0, (sizeof(CHAR *) * OS_HWI_MAX_NUM)); + + HalIrqInit(); + + return; +} + +LITE_OS_SEC_TEXT_INIT UINT32 LOS_HwiCreate(HWI_HANDLE_T hwiNum, + HWI_PRIOR_T hwiPrio, + HWI_MODE_T hwiMode, + HWI_PROC_FUNC hwiHandler, + HwiIrqParam *irqParam) +{ + UINT32 ret; + + (VOID)hwiPrio; + if (hwiHandler == NULL) { + return OS_ERRNO_HWI_PROC_FUNC_NULL; + } + if ((hwiNum > OS_USER_HWI_MAX) || ((INT32)hwiNum < OS_USER_HWI_MIN)) { + return OS_ERRNO_HWI_NUM_INVALID; + } + +#ifdef LOSCFG_NO_SHARED_IRQ + ret = OsHwiCreateNoShared(hwiNum, hwiMode, hwiHandler, irqParam); +#else + ret = OsHwiCreateShared(hwiNum, hwiMode, hwiHandler, irqParam); +#endif + return ret; +} + +LITE_OS_SEC_TEXT_INIT UINT32 LOS_HwiDelete(HWI_HANDLE_T hwiNum, HwiIrqParam *irqParam) +{ + UINT32 ret; + + if ((hwiNum > OS_USER_HWI_MAX) || ((INT32)hwiNum < OS_USER_HWI_MIN)) { + return OS_ERRNO_HWI_NUM_INVALID; + } + +#ifdef LOSCFG_NO_SHARED_IRQ + ret = OsHwiDelNoShared(hwiNum); +#else + ret = OsHwiDelShared(hwiNum, irqParam); +#endif + return ret; +} + diff --git a/src/kernel_liteos_a/arch/arm/arm/src/pmu/armv7_pmu.c b/src/kernel_liteos_a/arch/arm/arm/src/pmu/armv7_pmu.c new file mode 100644 index 00000000..df17555b --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/src/pmu/armv7_pmu.c @@ -0,0 +1,373 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "armv7_pmu_pri.h" +#include "perf_pmu_pri.h" +#include "los_hw_cpu.h" +#include "asm/platform.h" + +OS_PMU_INTS(LOSCFG_KERNEL_CORE_NUM, g_pmuIrqNr); +STATIC HwPmu g_armv7Pmu; + +STATIC INLINE UINT32 Armv7PmncRead(VOID) +{ + UINT32 value = 0; + __asm__ volatile("mrc p15, 0, %0, c9, c12, 0" : "=r"(value)); + return value; +} + +STATIC INLINE VOID Armv7PmncWrite(UINT32 value) +{ + value &= ARMV7_PMNC_MASK; + __asm__ volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(value)); + ISB; +} + +STATIC INLINE UINT32 Armv7PmuOverflowed(UINT32 pmnc) +{ + return pmnc & ARMV7_OVERFLOWED_MASK; +} + +STATIC INLINE UINT32 Armv7PmuCntOverflowed(UINT32 pmnc, UINT32 index) +{ + return pmnc & ARMV7_CNT2BIT(ARMV7_IDX2CNT(index)); +} + +STATIC INLINE UINT32 Armv7CntValid(UINT32 index) +{ + return index <= ARMV7_IDX_COUNTER_LAST; +} + +STATIC INLINE VOID Armv7PmuSelCnt(UINT32 index) +{ + UINT32 counter = ARMV7_IDX2CNT(index); + __asm__ volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (counter)); + ISB; +} + +STATIC INLINE VOID Armv7PmuSetCntPeriod(UINT32 index, UINT32 period) +{ + if (!Armv7CntValid(index)) { + PRINT_ERR("CPU writing wrong counter %u\n", index); + } else if (index == ARMV7_IDX_CYCLE_COUNTER) { + __asm__ volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (period)); + } else { + Armv7PmuSelCnt(index); + __asm__ volatile("mcr p15, 0, %0, c9, c13, 2" : : "r" (period)); + } +} + +STATIC INLINE VOID Armv7BindEvt2Cnt(UINT32 index, UINT32 value) +{ + PRINT_DEBUG("bind event: %u to counter: %u\n", value, index); + Armv7PmuSelCnt(index); + value &= ARMV7_EVTYPE_MASK; + __asm__ volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (value)); +} + +STATIC INLINE VOID Armv7EnableCnt(UINT32 index) +{ + UINT32 counter = ARMV7_IDX2CNT(index); + PRINT_DEBUG("index : %u, counter: %u\n", index, counter); + __asm__ volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (ARMV7_CNT2BIT(counter))); +} + +STATIC INLINE VOID Armv7DisableCnt(UINT32 index) +{ + UINT32 counter = ARMV7_IDX2CNT(index); + PRINT_DEBUG("index : %u, counter: %u\n", index, counter); + __asm__ volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (ARMV7_CNT2BIT(counter))); +} + +STATIC INLINE VOID Armv7EnableCntInterrupt(UINT32 index) +{ + UINT32 counter = ARMV7_IDX2CNT(index); + __asm__ volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (ARMV7_CNT2BIT(counter))); + ISB; +} + +STATIC INLINE VOID Armv7DisableCntInterrupt(UINT32 index) +{ + UINT32 counter = ARMV7_IDX2CNT(index); + __asm__ volatile("mcr p15, 0, %0, c9, c14, 2" : : "r" (ARMV7_CNT2BIT(counter))); + /* Clear the overflow flag in case an interrupt is pending. */ + __asm__ volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (ARMV7_CNT2BIT(counter))); + ISB; +} + +STATIC INLINE UINT32 Armv7PmuGetOverflowStatus(VOID) +{ + UINT32 value; + + __asm__ volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (value)); + value &= ARMV7_FLAG_MASK; + __asm__ volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (value)); + + return value; +} + +STATIC VOID Armv7EnableEvent(Event *event) +{ + UINT32 cnt = event->counter; + + if (!Armv7CntValid(cnt)) { + PRINT_ERR("CPU enabling wrong PMNC counter IRQ enable %u\n", cnt); + return; + } + + if (event->period == 0) { + PRINT_INFO("event period value not valid, counter: %u\n", cnt); + return; + } + /* + * Enable counter and interrupt, and set the counter to count + * the event that we're interested in. + */ + UINT32 intSave = LOS_IntLock(); + + Armv7DisableCnt(cnt); + + /* + * Set event (if destined for PMNx counters) + * We only need to set the event for the cycle counter if we + * have the ability to perform event filtering. + */ + if (cnt != ARMV7_IDX_CYCLE_COUNTER) { + Armv7BindEvt2Cnt(cnt, event->eventId); + } + + /* Enable interrupt for this counter */ + Armv7EnableCntInterrupt(cnt); + Armv7EnableCnt(cnt); + LOS_IntRestore(intSave); + + PRINT_DEBUG("enabled event: %u cnt: %u\n", event->eventId, cnt); +} + +STATIC VOID Armv7DisableEvent(Event *event) +{ + UINT32 cnt = event->counter; + + if (!Armv7CntValid(cnt)) { + PRINT_ERR("CPU enabling wrong PMNC counter IRQ enable %u\n", cnt); + return; + } + + UINT32 intSave = LOS_IntLock(); + Armv7DisableCnt(cnt); + Armv7DisableCntInterrupt(cnt); + LOS_IntRestore(intSave); +} + + +STATIC VOID Armv7StartAllCnt(VOID) +{ + PRINT_DEBUG("starting pmu...\n"); + + /* Enable all counters */ + UINT32 reg = Armv7PmncRead() | ARMV7_PMNC_E; + if (g_armv7Pmu.cntDivided) { + reg |= ARMV7_PMNC_D; + } else { + reg &= ~ARMV7_PMNC_D; + } + + Armv7PmncWrite(reg); + HalIrqUnmask(g_pmuIrqNr[ArchCurrCpuid()]); +} + +STATIC VOID Armv7StopAllCnt(VOID) +{ + PRINT_DEBUG("stopping pmu...\n"); + /* Disable all counters */ + Armv7PmncWrite(Armv7PmncRead() & ~ARMV7_PMNC_E); + + HalIrqMask(g_pmuIrqNr[ArchCurrCpuid()]); +} + +STATIC VOID Armv7ResetAllCnt(VOID) +{ + UINT32 index; + + /* The counter and interrupt enable registers are unknown at reset. */ + for (index = ARMV7_IDX_CYCLE_COUNTER; index < ARMV7_IDX_MAX_COUNTER; index++) { + Armv7DisableCnt(index); + Armv7DisableCntInterrupt(index); + } + + /* Initialize & Reset PMNC: C and P bits and D bits */ + UINT32 reg = ARMV7_PMNC_P | ARMV7_PMNC_C | (g_armv7Pmu.cntDivided ? ARMV7_PMNC_D : 0); + Armv7PmncWrite(reg); +} + +STATIC VOID Armv7SetEventPeriod(Event *event) +{ + if (event->period != 0) { + PRINT_INFO("counter: %u, period: 0x%x\n", event->counter, event->period); + Armv7PmuSetCntPeriod(event->counter, PERIOD_CALC(event->period)); + } +} + +STATIC UINTPTR Armv7ReadEventCnt(Event *event) +{ + UINT32 value = 0; + UINT32 index = event->counter; + + if (!Armv7CntValid(index)) { + PRINT_ERR("CPU reading wrong counter %u\n", index); + } else if (index == ARMV7_IDX_CYCLE_COUNTER) { + __asm__ volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (value)); + } else { + Armv7PmuSelCnt(index); + __asm__ volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (value)); + } + + if (value < PERIOD_CALC(event->period)) { + if (Armv7PmuCntOverflowed(Armv7PmuGetOverflowStatus(), event->counter)) { + value += event->period; + } + } else { + value -= PERIOD_CALC(event->period); + } + return value; +} + +STATIC const UINT32 g_armv7Map[] = { + [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERF_HW_CYCLES, + [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERF_HW_INSTRUCTIONS, + [PERF_COUNT_HW_DCACHE_REFERENCES] = ARMV7_PERF_HW_DCACHES, + [PERF_COUNT_HW_DCACHE_MISSES] = ARMV7_PERF_HW_DCACHE_MISSES, + [PERF_COUNT_HW_ICACHE_REFERENCES] = ARMV7_PERF_HW_ICACHES, + [PERF_COUNT_HW_ICACHE_MISSES] = ARMV7_PERF_HW_ICACHE_MISSES, + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERF_HW_BRANCHES, + [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERF_HW_BRANCE_MISSES, +}; + +UINT32 Armv7PmuMapEvent(UINT32 eventType, BOOL reverse) +{ + if (!reverse) { /* Common event to armv7 real event */ + if (eventType < ARRAY_SIZE(g_armv7Map)) { + return g_armv7Map[eventType]; + } + return eventType; + } else { /* Armv7 real event to common event */ + UINT32 i; + for (i = 0; i < ARRAY_SIZE(g_armv7Map); i++) { + if (g_armv7Map[i] == eventType) { + return i; + } + } + return PERF_HW_INVALID_EVENT_TYPE; + } +} + +STATIC VOID Armv7PmuIrqHandler(VOID) +{ + UINT32 index; + PerfRegs regs; + + PerfEvent *events = &(g_armv7Pmu.pmu.events); + UINT32 eventNum = events->nr; + + /* Get and reset the IRQ flags */ + UINT32 pmnc = Armv7PmuGetOverflowStatus(); + if (!Armv7PmuOverflowed(pmnc)) { + return; + } + + (VOID)memset_s(®s, sizeof(PerfRegs), 0, sizeof(PerfRegs)); + OsPerfFetchIrqRegs(®s); + + Armv7StopAllCnt(); + + for (index = 0; index < eventNum; index++) { + Event *event = &(events->per[index]); + /* + * We have a single interrupt for all counters. Check that + * each counter has overflowed before we process it. + */ + if (!Armv7PmuCntOverflowed(pmnc, event->counter) || (event->period == 0)) { + continue; + } + + Armv7PmuSetCntPeriod(event->counter, PERIOD_CALC(event->period)); + + OsPerfUpdateEventCount(event, event->period); + OsPerfHandleOverFlow(event, ®s); + } + Armv7StartAllCnt(); +} + +UINT32 OsGetPmuMaxCounter(VOID) +{ + return ARMV7_IDX_MAX_COUNTER; +} + +UINT32 OsGetPmuCycleCounter(VOID) +{ + return ARMV7_IDX_CYCLE_COUNTER; +} + +UINT32 OsGetPmuCounter0(VOID) +{ + return ARMV7_IDX_COUNTER0; +} + +STATIC HwPmu g_armv7Pmu = { + .canDivided = TRUE, + .enable = Armv7EnableEvent, + .disable = Armv7DisableEvent, + .start = Armv7StartAllCnt, + .stop = Armv7StopAllCnt, + .clear = Armv7ResetAllCnt, + .setPeriod = Armv7SetEventPeriod, + .readCnt = Armv7ReadEventCnt, + .mapEvent = Armv7PmuMapEvent, +}; + +UINT32 OsHwPmuInit(VOID) +{ + UINT32 ret; + UINT32 index; + + for (index = 0; index < LOSCFG_KERNEL_CORE_NUM; index++) { + ret = LOS_HwiCreate(g_pmuIrqNr[index], 0, 0, Armv7PmuIrqHandler, 0); + if (ret != LOS_OK) { + PRINT_ERR("pmu %u irq handler register failed\n", g_pmuIrqNr[index]); + return ret; + } +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(g_pmuIrqNr[index], CPUID_TO_AFFI_MASK(index)); +#endif + } + ret = OsPerfHwInit(&g_armv7Pmu); + return ret; +} diff --git a/src/kernel_liteos_a/arch/arm/arm/src/smp.c b/src/kernel_liteos_a/arch/arm/arm/src/smp.c new file mode 100644 index 00000000..fef09f13 --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/src/smp.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "smp.h" +#include "arch_config.h" +#include "los_base.h" +#include "los_hw.h" +#include "los_atomic.h" +#include "los_arch_mmu.h" +#include "gic_common.h" +#include "los_task_pri.h" + +#ifdef LOSCFG_KERNEL_SMP + +extern VOID reset_vector(VOID); + +struct OsCpuInit { + ArchCpuStartFunc cpuStart; + VOID *arg; + Atomic initFlag; +}; + +STATIC struct OsCpuInit g_cpuInit[CORE_NUM - 1] = {0}; + +VOID HalArchCpuOn(UINT32 cpuNum, ArchCpuStartFunc func, struct SmpOps *ops, VOID *arg) +{ + struct OsCpuInit *cpuInit = &g_cpuInit[cpuNum - 1]; + UINTPTR startEntry = (UINTPTR)&reset_vector - KERNEL_VMM_BASE + SYS_MEM_BASE; + INT32 ret; + + cpuInit->cpuStart = func; + cpuInit->arg = arg; + cpuInit->initFlag = 0; + + DCacheFlushRange((UINTPTR)cpuInit, (UINTPTR)cpuInit + sizeof(struct OsCpuInit)); + + LOS_ASSERT(ops != NULL); + + + ret = ops->SmpCpuOn(cpuNum, startEntry); + if (ret < 0) { + PRINT_ERR("cpu start failed, cpu num: %u, ret: %d\n", cpuNum, ret); + return; + } + + while (!LOS_AtomicRead(&cpuInit->initFlag)) { + WFE; + } +} + +VOID HalSecondaryCpuStart(VOID) +{ + UINT32 cpuid = ArchCurrCpuid(); + struct OsCpuInit *cpuInit = &g_cpuInit[cpuid - 1]; + + OsCurrTaskSet(OsGetMainTask()); + + LOS_AtomicSet(&cpuInit->initFlag, 1); + SEV; + +#ifdef LOSCFG_KERNEL_MMU + OsArchMmuInitPerCPU(); +#endif + + /* store each core's hwid */ + CPU_MAP_SET(cpuid, OsHwIDGet()); + HalIrqInitPercpu(); + + cpuInit->cpuStart(cpuInit->arg); + + while (1) { + WFI; + } +} +#endif + diff --git a/src/kernel_liteos_a/arch/arm/arm/src/startup/reset_vector_mp.S b/src/kernel_liteos_a/arch/arm/arm/src/startup/reset_vector_mp.S new file mode 100644 index 00000000..11c74afc --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/src/startup/reset_vector_mp.S @@ -0,0 +1,459 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#define ASSEMBLY +#include "arch_config.h" +#include "los_vm_boot.h" +#include "los_vm_zone.h" +#include "los_mmu_descriptor_v6.h" +#undef ASSEMBLY + + + .global __exc_stack_top + .global __svc_stack_top + .global __exc_stack + .global __svc_stack + + .extern __bss_start + .extern __bss_end + .extern hal_clock_initialize_start + .extern los_bss_init + .extern _osExceptFiqHdl + .extern _osExceptAddrAbortHdl + .extern _osExceptDataAbortHdl + .extern _osExceptPrefetchAbortHdl + .extern _osExceptSwiHdl + .extern _osExceptUndefInstrHdl + .extern __stack_chk_guard_setup + .extern g_firstPageTable + .extern g_mmuJumpPageTable + .extern g_archMmuInitMapping + .extern HalSecondaryCpuStart + + .equ MPIDR_CPUID_MASK, 0xffU + + .fpu neon-vfpv4 + .syntax unified + .arch armv7-a + .arm + +/* param0 is stack bottom, param1 is stack size, r12 hold cpu id */ +.macro EXC_SP_SET param0, param1 + ldr r1, =\param0 + mov r0, \param1 + bl sp_set +.endm + +/* param0 is stack top, param1 is stack size, param2 is magic num */ +.macro STACK_MAGIC_SET param0, param1, param2 + ldr r0, =\param0 + mov r1, \param1 + ldr r2, =\param2 + bl excstack_magic +.endm + + .code 32 + .section ".vectors","ax" + + .global __exception_handlers +__exception_handlers: + /* + *Assumption: ROM code has these vectors at the hardware reset address. + *A simple jump removes any address-space dependencies [i.e. safer] + */ + b reset_vector + b _osExceptUndefInstrHdl + b _osExceptSwiHdl + b _osExceptPrefetchAbortHdl + b _osExceptDataAbortHdl + b _osExceptAddrAbortHdl + b OsIrqHandler + b _osExceptFiqHdl + + /* Startup code which will get the machine into supervisor mode */ + .global reset_vector + .type reset_vector,function + +#ifdef LOSCFG_BOOTENV_RAM +__quickstart_args_start: + .fill LOSCFG_BOOTENV_RAMSIZE,1,0 +__quickstart_args_end: + +.global OsGetArgsAddr +.type OsGetArgsAddr,function + +OsGetArgsAddr: + ldr r0, =__quickstart_args_start + bx lr +#endif + +reset_vector: + /* clear register TPIDRPRW */ + mov r0, #0 + mcr p15, 0, r0, c13, c0, 4 + /* do some early cpu setup: i/d cache disable, mmu disabled */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, #(1 << 12) /* i cache */ + bic r0, #(1 << 2) /* d cache */ + bic r0, #(1 << 0) /* mmu */ + mcr p15, 0, r0, c1, c0, 0 + + /* enable fpu+neon */ +#ifndef LOSCFG_TEE_ENABLE + MRC p15, 0, r0, c1, c1, 2 + ORR r0, r0, #0xC00 + BIC r0, r0, #0xC000 + MCR p15, 0, r0, c1, c1, 2 + + LDR r0, =(0xF << 20) + MCR p15, 0, r0, c1, c0, 2 + ISB +#endif + MOV r3, #0x40000000 + VMSR FPEXC, r3 + + /* r11: delta of physical address and virtual address */ + adr r11, pa_va_offset + ldr r0, [r11] + sub r11, r11, r0 + + mrc p15, 0, r12, c0, c0, 5 /* r12: get cpuid */ + and r12, r12, #MPIDR_CPUID_MASK + cmp r12, #0 + bne secondary_cpu_init + + /* if we need to relocate to proper location or not */ + adr r4, __exception_handlers /* r4: base of load address */ + ldr r5, =SYS_MEM_BASE /* r5: base of physical address */ + subs r12, r4, r5 /* r12: delta of load address and physical address */ + beq reloc_img_to_bottom_done /* if we load image at the bottom of physical address */ + + /* we need to relocate image at the bottom of physical address */ + ldr r7, =__exception_handlers /* r7: base of linked address (or vm address) */ + ldr r6, =__bss_start /* r6: end of linked address (or vm address) */ + sub r6, r7 /* r6: delta of linked address (or vm address) */ + add r6, r4 /* r6: end of load address */ + +reloc_img_to_bottom_loop: + ldr r7, [r4], #4 + str r7, [r5], #4 + cmp r4, r6 + bne reloc_img_to_bottom_loop + sub pc, r12 + nop + sub r11, r11, r12 /* r11: eventual address offset */ + +reloc_img_to_bottom_done: +#ifdef LOSCFG_KERNEL_MMU + ldr r4, =g_firstPageTable /* r4: physical address of translation table and clear it */ + add r4, r4, r11 + mov r0, r4 + mov r1, #0 + mov r2, #MMU_DESCRIPTOR_L1_SMALL_ENTRY_NUMBERS + bl memset_optimized /* optimized memset since r0 is 64-byte aligned */ + + ldr r5, =g_archMmuInitMapping + add r5, r5, r11 +init_mmu_loop: + ldmia r5!, {r6-r10} /* r6 = phys, r7 = virt, r8 = size, r9 = mmu_flags, r10 = name */ + cmp r8, 0 /* if size = 0, the mmu init done */ + beq init_mmu_done + bl page_table_build + b init_mmu_loop +init_mmu_done: + orr r8, r4, #MMU_TTBRx_FLAGS /* r8 = r4 and set cacheable attributes on translation walk */ + ldr r4, =g_mmuJumpPageTable /* r4: jump pagetable vaddr */ + add r4, r4, r11 + ldr r4, [r4] + add r4, r4, r11 /* r4: jump pagetable paddr */ + + /* build 1M section mapping, in order to jump va during turing on mmu:pa == pa, va == pa */ + mov r6, pc + mov r7, r6 /* r7: pa (MB aligned)*/ + lsr r6, r6, #20 /* r6: va l1 index */ + ldr r10, =MMU_DESCRIPTOR_KERNEL_L1_PTE_FLAGS + add r12, r10, r6, lsl #20 /* r12: pa |flags */ + str r12, [r4, r7, lsr #(20 - 2)] /* jumpTable[paIndex] = pt entry */ + rsb r7, r11, r6, lsl #20 /* r7: va */ + str r12, [r4, r7, lsr #(20 - 2)] /* jumpTable[vaIndex] = pt entry */ + + bl mmu_setup /* set up the mmu */ +#endif + /* clear out the interrupt and exception stack and set magic num to check the overflow */ + ldr r0, =__svc_stack + ldr r1, =__exc_stack_top + bl stack_init + + STACK_MAGIC_SET __svc_stack, #OS_EXC_SVC_STACK_SIZE, OS_STACK_MAGIC_WORD + STACK_MAGIC_SET __exc_stack, #OS_EXC_STACK_SIZE, OS_STACK_MAGIC_WORD + +warm_reset: + /* initialize CPSR (machine state register) */ + mov r0, #(CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE|CPSR_SVC_MODE) + msr cpsr, r0 + + /* Note: some functions in LIBGCC1 will cause a "restore from SPSR"!! */ + msr spsr, r0 + + /* get cpuid and keep it in r12 */ + mrc p15, 0, r12, c0, c0, 5 + and r12, r12, #MPIDR_CPUID_MASK + + /* set svc stack, every cpu has OS_EXC_SVC_STACK_SIZE stack */ + ldr r0, =__svc_stack_top + mov r2, #OS_EXC_SVC_STACK_SIZE + mul r2, r2, r12 + sub r0, r0, r2 + mov sp, r0 + + LDR r0, =__exception_handlers + MCR p15, 0, r0, c12, c0, 0 + + cmp r12, #0 + bne cpu_start + +clear_bss: + ldr r0, =__bss_start + ldr r2, =__bss_end + mov r1, #0 + sub r2, r2, r0 + bl memset + +#if defined(LOSCFG_CC_STACKPROTECTOR_ALL) || \ + defined(LOSCFG_CC_STACKPROTECTOR_STRONG) || \ + defined(LOSCFG_CC_STACKPROTECTOR) + bl __stack_chk_guard_setup +#endif + +#ifdef LOSCFG_GDB_DEBUG + /* GDB_START - generate a compiled_breadk,This function will get GDB stubs started, with a proper environment */ + bl GDB_START + .word 0xe7ffdeff +#endif + + bl main + +_start_hang: + b _start_hang +#ifdef LOSCFG_KERNEL_MMU +mmu_setup: + mov r12, #0 + mcr p15, 0, r12, c8, c7, 0 /* Set c8 to control the TLB and set the mapping to invalid */ + isb + mcr p15, 0, r12, c2, c0, 2 /* Initialize the c2 register */ + isb + orr r12, r4, #MMU_TTBRx_FLAGS + mcr p15, 0, r12, c2, c0, 0 /* Set attributes and set temp page table */ + isb + mov r12, #0x7 /* 0b0111 */ + mcr p15, 0, r12, c3, c0, 0 /* Set DACR with 0b0111, client and manager domian */ + isb + mrc p15, 0, r12, c1, c0, 1 /* ACTLR, Auxiliary Control Register */ + orr r12, r12, #(1 << 6) /* SMP, Enables coherent requests to the processor. */ + orr r12, r12, #(1 << 2) /* Enable D-side prefetch */ + orr r12, r12, #(1 << 11) /* Global BP Enable bit */ + mcr p15, 0, r12, c1, c0, 1 /* ACTLR, Auxiliary Control Register */ + dsb + mrc p15, 0, r12, c1, c0, 0 + bic r12, #(1 << 29 | 1 << 28) /* Disable TRE/AFE */ + orr r12, #(1 << 0) /* mmu enable */ + bic r12, #(1 << 1) + orr r12, #(1 << 2) /* D cache enable */ + orr r12, #(1 << 12) /* I cache enable */ + mcr p15, 0, r12, c1, c0, 0 /* Set SCTLR with r12: Turn on the MMU, I/D cache Disable TRE/AFE */ + isb + ldr pc, =1f /* Convert to VA */ +1: + mcr p15, 0, r8, c2, c0, 0 /* Go to the base address saved in C2: Jump to the page table */ + isb + mov r12, #0 + mcr p15, 0, r12, c8, c7, 0 + isb + sub lr, r11 /* adjust lr with delta of physical address and virtual address */ + bx lr +#endif + .code 32 + + .global reset_platform + .type reset_platform,function +reset_platform: +#ifdef A7SEM_HAL_ROM_MONITOR + /* initialize CPSR (machine state register) */ + mov r0, #(CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE|CPSR_SVC_MODE) + msr cpsr, r0 + b warm_reset +#else + mov r0, #0 + mov pc, r0 // Jump to reset vector +#endif + +cpu_start: +#ifdef LOSCFG_KERNEL_MMU + ldr r4, =g_firstPageTable /* r4 = physical address of translation table and clear it */ + add r4, r4, r11 + orr r8, r4, #MMU_TTBRx_FLAGS + + ldr r4, =g_mmuJumpPageTable /* r4 = tt_trampoline vaddr */ + add r4, r4, r11 + ldr r4, [r4] + add r4, r4, r11 /* r4 = tt_trampoline paddr */ + + bl mmu_setup +#endif + + bl HalSecondaryCpuStart + b . + +secondary_cpu_init: +#ifdef LOSCFG_TEE_ENABLE + /* enable fpu+neon */ + ldr r0, =0x60c00 + MCR p15, 0, r0, c1, c1, 2 + + LDR r0, =(0xF << 20) + MCR p15, 0, r0, c1, c0, 2 + cps #0x16 + mov r1, #0x25 + mcr p15, 0, r1, c1, c1, 0 + cps #0x13 +#endif + bl warm_reset + +/* + * set sp for current cpu + * r1 is stack bottom, r0 is stack size, r12 hold cpu id + */ +sp_set: + mrc p15, 0, r12, c0, c0, 5 + and r12, r12, #MPIDR_CPUID_MASK + mul r3, r0, r12 + sub r2, r1, r3 + mov sp, r2 + bx lr /* set sp */ + +/* + * r4: page table base address + * r6: physical address + * r7: virtual address + * r8: sizes + * r10: flags + * r9 and r12 will be used as variable + */ +#ifdef LOSCFG_KERNEL_MMU +page_table_build: + mov r10, r6 + bfc r10, #20, #12 /* r9: pa % MB */ + add r8, r8, r10 + add r8, r8, #(1 << 20) + sub r8, r8, #1 + lsr r6, #20 /* r6 = physical address / MB */ + lsr r7, #20 /* r7 = virtual address / MB */ + lsr r8, #20 /* r8 = roundup(size, MB) */ + +page_table_build_loop: + orr r12, r9, r6, lsl #20 /* r12: flags | physAddr */ + str r12, [r4, r7, lsl #2] /* gPgTable[l1Index] = physAddr | flags */ + add r6, #1 /* physAddr+ */ + add r7, #1 /* l1Index++ */ + subs r8, #1 /* sizes-- */ + bne page_table_build_loop + bx lr +#endif +/* + * init stack to initial value + * r0 is stack mem start, r1 is stack mem end + */ +stack_init: + ldr r2, =OS_STACK_INIT + ldr r3, =OS_STACK_INIT + /* Main loop sets 32 bytes at a time. */ +stack_init_loop: + .irp offset, #0, #8, #16, #24 + strd r2, r3, [r0, \offset] + .endr + add r0, #32 + cmp r0, r1 + blt stack_init_loop + bx lr + +pa_va_offset: + .word . + +/* + * set magic num to stack top for all cpu + * r0 is stack top, r1 is stack size, r2 is magic num + */ +excstack_magic: + mov r3, #0 +excstack_magic_loop: + str r2, [r0] + add r0, r0, r1 + add r3, r3, #1 + cmp r3, #CORE_NUM + blt excstack_magic_loop + bx lr + +#ifdef LOSCFG_KERNEL_MMU +memset_optimized: + mov r3, r0 + vdup.8 q0, r1 + vmov q1, q0 + vmov q2, q0 + vmov q3, q0 +memset_optimized_loop: + subs r2, #64 + vstmia r3!, {d0 - d7} + bge memset_optimized_loop + bx lr +#endif +init_done: + .long 0xDEADB00B + + .code 32 + .data + +init_flag: + .balign 4 + .long 0 + + /* + * Temporary interrupt stack + */ + .section ".int_stack", "wa", %nobits + .align 3 + +__svc_stack: + .space OS_EXC_SVC_STACK_SIZE * CORE_NUM +__svc_stack_top: + +__exc_stack: + .space OS_EXC_STACK_SIZE * CORE_NUM +__exc_stack_top: diff --git a/src/kernel_liteos_a/arch/arm/arm/src/startup/reset_vector_up.S b/src/kernel_liteos_a/arch/arm/arm/src/startup/reset_vector_up.S new file mode 100644 index 00000000..a54f468a --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/src/startup/reset_vector_up.S @@ -0,0 +1,415 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#define ASSEMBLY +#include "arch_config.h" +#include "los_vm_boot.h" +#include "los_vm_zone.h" +#include "los_mmu_descriptor_v6.h" +#undef ASSEMBLY + + + .global __exc_stack_top + .global __svc_stack_top + .global __exc_stack + .global __svc_stack + + .extern __bss_start + .extern __bss_end + .extern hal_clock_initialize_start + .extern _osExceptFiqHdl + .extern _osExceptAddrAbortHdl + .extern _osExceptDataAbortHdl + .extern _osExceptPrefetchAbortHdl + .extern _osExceptSwiHdl + .extern _osExceptUndefInstrHdl + .extern __stack_chk_guard_setup + .extern g_firstPageTable + .extern g_mmuJumpPageTable + .extern g_archMmuInitMapping + + .equ MPIDR_CPUID_MASK, 0xffU + + .fpu neon-vfpv4 + .syntax unified + .arch armv7-a + .arm + +/* param0 is stack bottom, param1 is stack size, r11 hold cpu id */ +.macro EXC_SP_SET param0, param1 + ldr r1, =\param0 + mov r0, \param1 + bl sp_set +.endm + +/* param0 is stack top, param1 is stack size, param2 is magic num */ +.macro STACK_MAGIC_SET param0, param1, param2 + ldr r0, =\param0 + mov r1, \param1 + ldr r2, =\param2 + bl excstack_magic +.endm + + .code 32 + .section ".vectors","ax" + +__exception_handlers: + /* + *Assumption: ROM code has these vectors at the hardware reset address. + *A simple jump removes any address-space dependencies [i.e. safer] + */ + b reset_vector + b _osExceptUndefInstrHdl + b _osExceptSwiHdl + b _osExceptPrefetchAbortHdl + b _osExceptDataAbortHdl + b _osExceptAddrAbortHdl + b OsIrqHandler + b _osExceptFiqHdl + + /* Startup code which will get the machine into supervisor mode */ + .global reset_vector + .type reset_vector,function +reset_vector: + /* do some early cpu setup: i/d cache disable, mmu disabled */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, #(1 << 12) /* i cache */ + bic r0, #(1 << 2) /* d cache */ + bic r0, #(1 << 0) /* mmu */ + mcr p15, 0, r0, c1, c0, 0 + + /* enable fpu+neon */ +#ifndef LOSCFG_TEE_ENABLE + MRC p15, 0, r0, c1, c1, 2 + ORR r0, r0, #0xC00 + BIC r0, r0, #0xC000 + MCR p15, 0, r0, c1, c1, 2 + + LDR r0, =(0xF << 20) + MCR p15, 0, r0, c1, c0, 2 + ISB +#endif + MOV r3, #0x40000000 + VMSR FPEXC, r3 + + /* r11: delta of physical address and virtual address */ + adr r11, pa_va_offset + ldr r0, [r11] + sub r11, r11, r0 + + /* if we need to relocate to proper location or not */ + adr r4, __exception_handlers /* r4: base of load address */ + ldr r5, =SYS_MEM_BASE /* r5: base of physical address */ + subs r12, r4, r5 /* r12: delta of load address and physical address */ + beq reloc_img_to_bottom_done /* if we load image at the bottom of physical address */ + + /* we need to relocate image at the bottom of physical address */ + ldr r7, =__exception_handlers /* r7: base of linked address (or vm address) */ + ldr r6, =__bss_start /* r6: end of linked address (or vm address) */ + sub r6, r7 /* r6: delta of linked address (or vm address) */ + add r6, r4 /* r6: end of load address */ + +reloc_img_to_bottom_loop: + ldr r7, [r4], #4 + str r7, [r5], #4 + cmp r4, r6 + bne reloc_img_to_bottom_loop + sub pc, r12 + nop + sub r11, r11, r12 /* r11: eventual address offset */ + +reloc_img_to_bottom_done: +#ifdef LOSCFG_KERNEL_MMU + ldr r4, =g_firstPageTable /* r4: physical address of translation table and clear it */ + add r4, r4, r11 + mov r0, r4 + mov r1, #0 + mov r2, #MMU_DESCRIPTOR_L1_SMALL_ENTRY_NUMBERS + bl memset_optimized /* optimized memset since r0 is 64-byte aligned */ + + ldr r5, =g_archMmuInitMapping + add r5, r5, r11 +init_mmu_loop: + ldmia r5!, {r6-r10} /* r6 = phys, r7 = virt, r8 = size, r9 = mmu_flags, r10 = name */ + cmp r8, 0 /* if size = 0, the mmu init done */ + beq init_mmu_done + bl page_table_build + b init_mmu_loop +init_mmu_done: + orr r8, r4, #MMU_TTBRx_FLAGS /* r8 = r4 and set cacheable attributes on translation walk */ + ldr r4, =g_mmuJumpPageTable /* r4: jump pagetable vaddr */ + add r4, r4, r11 + ldr r4, [r4] + add r4, r4, r11 /* r4: jump pagetable paddr */ + + /* build 1M section mapping, in order to jump va during turing on mmu:pa == pa, va == pa */ + mov r6, pc + mov r7, r6 /* r7: pa (MB aligned)*/ + lsr r6, r6, #20 /* r6: va l1 index */ + ldr r10, =MMU_DESCRIPTOR_KERNEL_L1_PTE_FLAGS + add r12, r10, r6, lsl #20 /* r12: pa |flags */ + str r12, [r4, r7, lsr #(20 - 2)] /* jumpTable[paIndex] = pt entry */ + rsb r7, r11, r6, lsl #20 /* r7: va */ + str r12, [r4, r7, lsr #(20 - 2)] /* jumpTable[vaIndex] = pt entry */ + + bl mmu_setup /* set up the mmu */ +#endif + /* get cpuid and keep it in r11 */ + mrc p15, 0, r11, c0, c0, 5 + and r11, r11, #MPIDR_CPUID_MASK + cmp r11, #0 + bne excstatck_loop_done + +excstatck_loop: + /* clear out the interrupt and exception stack and set magic num to check the overflow */ + ldr r0, =__svc_stack + ldr r1, =__exc_stack_top + bl stack_init + + STACK_MAGIC_SET __svc_stack, #OS_EXC_SVC_STACK_SIZE, OS_STACK_MAGIC_WORD + STACK_MAGIC_SET __exc_stack, #OS_EXC_STACK_SIZE, OS_STACK_MAGIC_WORD + +excstatck_loop_done: +warm_reset: + /* initialize CPSR (machine state register) */ + mov r0, #(CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE|CPSR_SVC_MODE) + msr cpsr, r0 + + /* Note: some functions in LIBGCC1 will cause a "restore from SPSR"!! */ + msr spsr, r0 + + /* set svc stack, every cpu has OS_EXC_SVC_STACK_SIZE stack */ + ldr r0, =__svc_stack_top + mov r2, #OS_EXC_SVC_STACK_SIZE + mul r2, r2, r11 + sub r0, r0, r2 + mov sp, r0 + + /* enable fpu+neon */ + MRC p15, 0, r0, c1, c1, 2 + ORR r0, r0, #0xC00 + BIC r0, r0, #0xC000 + MCR p15, 0, r0, c1, c1, 2 + + LDR r0, =(0xF << 20) + MCR p15, 0, r0, c1, c0, 2 + + MOV r3, #0x40000000 + VMSR FPEXC, r3 + + LDR r0, =__exception_handlers + MCR p15, 0, r0, c12, c0, 0 + +clear_bss: + ldr r0, =__bss_start + ldr r2, =__bss_end + mov r1, #0 + sub r2, r2, r0 + bl memset + +#if defined(LOSCFG_CC_STACKPROTECTOR_ALL) || \ + defined(LOSCFG_CC_STACKPROTECTOR_STRONG) || \ + defined(LOSCFG_CC_STACKPROTECTOR) + bl __stack_chk_guard_setup +#endif + +#ifdef LOSCFG_GDB_DEBUG + /* GDB_START - generate a compiled_breadk,This function will get GDB stubs started, with a proper environment */ + bl GDB_START + .word 0xe7ffdeff +#endif + + bl main + +_start_hang: + b _start_hang + +#ifdef LOSCFG_KERNEL_MMU +mmu_setup: + mov r12, #0 + mcr p15, 0, r12, c8, c7, 0 /* Set c8 to control the TLB and set the mapping to invalid */ + isb + + mcr p15, 0, r12, c2, c0, 2 /* Initialize the c2 register */ + isb + + orr r12, r4, #MMU_TTBRx_FLAGS + mcr p15, 0, r12, c2, c0, 0 /* Set attributes and set temp page table */ + isb + + mov r12, #0x7 /* 0b0111 */ + mcr p15, 0, r12, c3, c0, 0 /* Set DACR with 0b0111, client and manager domian */ + isb + + mrc p15, 0, r12, c1, c0, 0 + bic r12, #(1 << 29 | 1 << 28) /* Disable TRE/AFE */ + orr r12, #(1 << 0) /* mmu enable */ + bic r12, #(1 << 1) + orr r12, #(1 << 2) /* D cache enable */ + orr r12, #(1 << 12) /* I cache enable */ + mcr p15, 0, r12, c1, c0, 0 /* Set SCTLR with r12: Turn on the MMU, I/D cache Disable TRE/AFE */ + isb + + ldr pc, =1f /* Convert to VA */ +1: + mcr p15, 0, r8, c2, c0, 0 /* Go to the base address saved in C2: Jump to the page table */ + isb + + mov r12, #0 + mcr p15, 0, r12, c8, c7, 0 + isb + + sub lr, r11 /* adjust lr with delta of physical address and virtual address */ + bx lr +#endif + .code 32 + + .global reset_platform + .type reset_platform,function +reset_platform: +#ifdef A7SEM_HAL_ROM_MONITOR + /* initialize CPSR (machine state register) */ + mov r0, #(CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE|CPSR_SVC_MODE) + msr cpsr, r0 + b warm_reset +#else + mov r0, #0 + mov pc, r0 // Jump to reset vector +#endif + +/* + * set sp for current cpu + * r1 is stack bottom, r0 is stack size, r11 hold cpu id + */ +sp_set: + mul r3, r0, r11 + sub r2, r1, r3 + mov sp, r2 + bx lr /* set sp */ + +/* + * r4: page table base address + * r6: physical address + * r7: virtual address + * r8: sizes + * r10: flags + * r9 and r12 will be used as variable + */ +#ifdef LOSCFG_KERNEL_MMU +page_table_build: + mov r10, r6 + bfc r10, #20, #12 /* r9: pa % MB */ + add r8, r8, r10 + add r8, r8, #(1 << 20) + sub r8, r8, #1 + lsr r6, #20 /* r6 = physical address / MB */ + lsr r7, #20 /* r7 = virtual address / MB */ + lsr r8, #20 /* r8 = roundup(size, MB) */ + +page_table_build_loop: + orr r12, r9, r6, lsl #20 /* r12: flags | physAddr */ + str r12, [r4, r7, lsl #2] /* gPgTable[l1Index] = physAddr | flags */ + add r6, #1 /* physAddr+ */ + add r7, #1 /* l1Index++ */ + subs r8, #1 /* sizes-- */ + bne page_table_build_loop + bx lr +#endif +/* + * init stack to initial value + * r0 is stack mem start, r1 is stack mem end + */ +stack_init: + ldr r2, =OS_STACK_INIT + ldr r3, =OS_STACK_INIT + /* Main loop sets 32 bytes at a time. */ +stack_init_loop: + .irp offset, #0, #8, #16, #24 + strd r2, r3, [r0, \offset] + .endr + add r0, #32 + cmp r0, r1 + blt stack_init_loop + bx lr + +pa_va_offset: + .word . + +/* + * set magic num to stack top for all cpu + * r0 is stack top, r1 is stack size, r2 is magic num + */ +excstack_magic: + mov r3, #0 +excstack_magic_loop: + str r2, [r0] + add r0, r0, r1 + add r3, r3, #1 + cmp r3, #CORE_NUM + blt excstack_magic_loop + bx lr + +#ifdef LOSCFG_KERNEL_MMU +memset_optimized: + mov r3, r0 + vdup.8 q0, r1 + vmov q1, q0 + vmov q2, q0 + vmov q3, q0 +memset_optimized_loop: + subs r2, #64 + vstmia r3!, {d0 - d7} + bge memset_optimized_loop + bx lr +#endif +init_done: + .long 0xDEADB00B + + .code 32 + .data + +init_flag: + .balign 4 + .long 0 + + /* + * Temporary interrupt stack + */ + .section ".int_stack", "wa", %nobits + .align 3 + +__svc_stack: + .space OS_EXC_SVC_STACK_SIZE * CORE_NUM +__svc_stack_top: + +__exc_stack: + .space OS_EXC_STACK_SIZE * CORE_NUM +__exc_stack_top: diff --git a/src/kernel_liteos_a/arch/arm/arm/src/strncpy_from_user.c b/src/kernel_liteos_a/arch/arm/arm/src/strncpy_from_user.c new file mode 100644 index 00000000..1d6c6634 --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/src/strncpy_from_user.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_strncpy_from_user.h" +#include "los_user_get.h" +#include "los_vm_map.h" + + +INT32 LOS_StrncpyFromUser(CHAR *dst, const CHAR *src, INT32 count) +{ + CHAR character; + INT32 i; + INT32 maxCount; + size_t offset = 0; + + if ((!LOS_IsKernelAddress((VADDR_T)(UINTPTR)dst)) || (!LOS_IsUserAddress((VADDR_T)(UINTPTR)src)) || (count <= 0)) { + return -EFAULT; + } + + maxCount = (LOS_IsUserAddressRange((VADDR_T)(UINTPTR)src, (size_t)count)) ? \ + count : (INT32)(USER_ASPACE_TOP_MAX - (UINTPTR)src); + + for (i = 0; i < maxCount; ++i) { + if (LOS_GetUser(&character, src + offset) != LOS_OK) { + return -EFAULT; + } + *(CHAR *)(dst + offset) = character; + if (character == '\0') { + return offset; + } + ++offset; + } + + return offset; +} + diff --git a/src/kernel_liteos_a/arch/arm/arm/src/strnlen_user.c b/src/kernel_liteos_a/arch/arm/arm/src/strnlen_user.c new file mode 100644 index 00000000..356742f7 --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/src/strnlen_user.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_strnlen_user.h" +#include "los_user_get.h" +#include "los_vm_map.h" + + +INT32 LOS_StrnlenUser(const CHAR *src, INT32 count) +{ + CHAR character; + INT32 maxCount; + INT32 i; + size_t offset = 0; + + if ((!LOS_IsUserAddress((VADDR_T)(UINTPTR)src)) || (count <= 0)) { + return 0; + } + + maxCount = (LOS_IsUserAddressRange((VADDR_T)(UINTPTR)src, (size_t)count)) ? \ + count : (USER_ASPACE_TOP_MAX - (UINTPTR)src); + + for (i = 0; i < maxCount; ++i) { + if (LOS_GetUser(&character, src + offset) != LOS_OK) { + return 0; + } + ++offset; + if (character == '\0') { + return offset; + } + } + + return count + 1; +} + diff --git a/src/kernel_liteos_a/arch/arm/arm/src/user_copy.c b/src/kernel_liteos_a/arch/arm/arm/src/user_copy.c new file mode 100644 index 00000000..081bc413 --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/arm/src/user_copy.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "user_copy.h" +#include "arm_user_copy.h" +#include "arm_user_clear.h" +#include "securec.h" +#include "los_memory.h" +#include "los_vm_map.h" + + +size_t arch_copy_from_user(void *dst, const void *src, size_t len) +{ + return LOS_ArchCopyFromUser(dst, src, len); +} + +size_t LOS_ArchCopyFromUser(void *dst, const void *src, size_t len) +{ + if (!LOS_IsUserAddressRange((VADDR_T)(UINTPTR)src, len)) { + return len; + } + + return _arm_user_copy(dst, src, len); +} + +size_t arch_copy_to_user(void *dst, const void *src, size_t len) +{ + return LOS_ArchCopyToUser(dst, src, len); +} + +size_t LOS_ArchCopyToUser(void *dst, const void *src, size_t len) +{ + if (!LOS_IsUserAddressRange((VADDR_T)(UINTPTR)dst, len)) { + return len; + } + + return _arm_user_copy(dst, src, len); +} + +INT32 LOS_CopyFromKernel(VOID *dest, UINT32 max, const VOID *src, UINT32 count) +{ + INT32 ret; + + if (!LOS_IsUserAddressRange((VADDR_T)(UINTPTR)dest, count)) { + ret = memcpy_s(dest, max, src, count); + } else { + ret = ((max >= count) ? _arm_user_copy(dest, src, count) : ERANGE_AND_RESET); + } + + return ret; +} + +INT32 LOS_CopyToKernel(VOID *dest, UINT32 max, const VOID *src, UINT32 count) +{ + INT32 ret; + + if (!LOS_IsUserAddressRange((vaddr_t)(UINTPTR)src, count)) { + ret = memcpy_s(dest, max, src, count); + } else { + ret = ((max >= count) ? _arm_user_copy(dest, src, count) : ERANGE_AND_RESET); + } + + return ret; +} + +INT32 LOS_UserMemClear(unsigned char *buf, UINT32 len) +{ + INT32 ret = 0; + if (!LOS_IsUserAddressRange((vaddr_t)(UINTPTR)buf, len)) { + (VOID)memset_s(buf, len, 0, len); + } else { + if (_arm_clear_user(buf, len)) { + return -EFAULT; + } + } + return ret; +} + + diff --git a/src/kernel_liteos_a/arch/arm/gic/BUILD.gn b/src/kernel_liteos_a/arch/arm/gic/BUILD.gn new file mode 100644 index 00000000..127100f5 --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/gic/BUILD.gn @@ -0,0 +1,41 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [] + + if (defined(LOSCFG_ARCH_GIC_V2)) { + sources += [ "gic_v2.c" ] + } else if (defined(LOSCFG_ARCH_GIC_V3)) { + sources += [ "gic_v3.c" ] + } +} diff --git a/src/kernel_liteos_a/arch/arm/gic/Makefile b/src/kernel_liteos_a/arch/arm/gic/Makefile new file mode 100644 index 00000000..376cfa2e --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/gic/Makefile @@ -0,0 +1,40 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +ifeq ($(LOSCFG_ARCH_GIC_V2), y) +LOCAL_SRCS := gic_v2.c +else ifeq ($(LOSCFG_ARCH_GIC_V3), y) +LOCAL_SRCS := gic_v3.c +endif + +include $(MODULE) diff --git a/src/kernel_liteos_a/arch/arm/gic/gic_v2.c b/src/kernel_liteos_a/arch/arm/gic/gic_v2.c new file mode 100644 index 00000000..14aa69af --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/gic/gic_v2.c @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "gic_common.h" +#include "los_hwi.h" +#include "los_hwi_pri.h" +#include "los_mp.h" + +STATIC_ASSERT(OS_USER_HWI_MAX <= 1020, "hwi max is too large!"); + +#ifdef LOSCFG_ARCH_GIC_V2 + +STATIC UINT32 g_curIrqNum = 0; + +#ifdef LOSCFG_KERNEL_SMP +/* + * filter description + * 0b00: forward to the cpu interfaces specified in cpu_mask + * 0b01: forward to all cpu interfaces + * 0b10: forward only to the cpu interface that request the irq + */ +STATIC VOID GicWriteSgi(UINT32 vector, UINT32 cpuMask, UINT32 filter) +{ + UINT32 val = ((filter & 0x3) << 24) | ((cpuMask & 0xFF) << 16) | /* 24, 16: Register bit offset */ + (vector & 0xF); + + GIC_REG_32(GICD_SGIR) = val; +} + +VOID HalIrqSendIpi(UINT32 target, UINT32 ipi) +{ + GicWriteSgi(ipi, target, 0); +} + +VOID HalIrqSetAffinity(UINT32 vector, UINT32 cpuMask) +{ + UINT32 offset = vector / 4; /* 4: Interrupt bit width */ + UINT32 index = vector & 0x3; + + GIC_REG_8(GICD_ITARGETSR(offset) + index) = cpuMask; +} +#endif + +UINT32 HalCurIrqGet(VOID) +{ + return g_curIrqNum; +} + +VOID HalIrqMask(UINT32 vector) +{ + if ((vector > OS_USER_HWI_MAX) || (vector < OS_USER_HWI_MIN)) { + return; + } + + GIC_REG_32(GICD_ICENABLER(vector / 32)) = 1U << (vector % 32); /* 32: Interrupt bit width */ +} + +VOID HalIrqUnmask(UINT32 vector) +{ + if ((vector > OS_USER_HWI_MAX) || (vector < OS_USER_HWI_MIN)) { + return; + } + + GIC_REG_32(GICD_ISENABLER(vector >> 5)) = 1U << (vector % 32); /* 5, 32: Register bit offset */ +} + +VOID HalIrqPending(UINT32 vector) +{ + if ((vector > OS_USER_HWI_MAX) || (vector < OS_USER_HWI_MIN)) { + return; + } + + GIC_REG_32(GICD_ISPENDR(vector >> 5)) = 1U << (vector % 32); /* 5, 32: Register bit offset */ +} + +VOID HalIrqClear(UINT32 vector) +{ + GIC_REG_32(GICC_EOIR) = vector; +} + +VOID HalIrqInitPercpu(VOID) +{ + /* unmask interrupts */ + GIC_REG_32(GICC_PMR) = 0xFF; + + /* enable gic cpu interface */ + GIC_REG_32(GICC_CTLR) = 1; +} + +VOID HalIrqInit(VOID) +{ + UINT32 i; + + /* set external interrupts to be level triggered, active low. */ + for (i = 32; i < OS_HWI_MAX_NUM; i += 16) { /* 32: Start interrupt number, 16: Interrupt bit width */ + GIC_REG_32(GICD_ICFGR(i / 16)) = 0; /* 16: Register bit offset */ + } + + /* set external interrupts to CPU 0 */ + for (i = 32; i < OS_HWI_MAX_NUM; i += 4) { /* 32: Start interrupt number, 4: Interrupt bit width */ + GIC_REG_32(GICD_ITARGETSR(i / 4)) = 0x01010101; + } + + /* set priority on all interrupts */ + for (i = 0; i < OS_HWI_MAX_NUM; i += 4) { /* 4: Interrupt bit width */ + GIC_REG_32(GICD_IPRIORITYR(i / 4)) = GICD_INT_DEF_PRI_X4; + } + + /* disable all interrupts. */ + for (i = 0; i < OS_HWI_MAX_NUM; i += 32) { /* 32: Interrupt bit width */ + GIC_REG_32(GICD_ICENABLER(i / 32)) = ~0; /* 32: Interrupt bit width */ + } + + HalIrqInitPercpu(); + + /* enable gic distributor control */ + GIC_REG_32(GICD_CTLR) = 1; + +#ifdef LOSCFG_KERNEL_SMP + /* register inter-processor interrupt */ + (VOID)LOS_HwiCreate(LOS_MP_IPI_WAKEUP, 0xa0, 0, OsMpWakeHandler, 0); + (VOID)LOS_HwiCreate(LOS_MP_IPI_SCHEDULE, 0xa0, 0, OsMpScheduleHandler, 0); + (VOID)LOS_HwiCreate(LOS_MP_IPI_HALT, 0xa0, 0, OsMpHaltHandler, 0); +#ifdef LOSCFG_KERNEL_SMP_CALL + (VOID)LOS_HwiCreate(LOS_MP_IPI_FUNC_CALL, 0xa0, 0, OsMpFuncCallHandler, 0); +#endif +#endif +} + +VOID HalIrqHandler(VOID) +{ + UINT32 iar = GIC_REG_32(GICC_IAR); + UINT32 vector = iar & 0x3FFU; + + /* + * invalid irq number, mainly the spurious interrupts 0x3ff, + * gicv2 valid irq ranges from 0~1019, we use OS_HWI_MAX_NUM + * to do the checking. + */ + if (vector >= OS_HWI_MAX_NUM) { + return; + } + g_curIrqNum = vector; + + OsInterrupt(vector); + + /* use original iar to do the EOI */ + GIC_REG_32(GICC_EOIR) = iar; +} + +CHAR *HalIrqVersion(VOID) +{ + UINT32 pidr = GIC_REG_32(GICD_PIDR2V2); + CHAR *irqVerString = NULL; + + switch (pidr >> GIC_REV_OFFSET) { + case GICV1: + irqVerString = "GICv1"; + break; + case GICV2: + irqVerString = "GICv2"; + break; + default: + irqVerString = "unknown"; + } + return irqVerString; +} + +#endif diff --git a/src/kernel_liteos_a/arch/arm/gic/gic_v3.c b/src/kernel_liteos_a/arch/arm/gic/gic_v3.c new file mode 100644 index 00000000..50039776 --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/gic/gic_v3.c @@ -0,0 +1,450 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "gic_common.h" +#include "gic_v3.h" +#include "los_typedef.h" +#include "los_hwi.h" +#include "los_hwi_pri.h" +#include "los_mp.h" + +#ifdef LOSCFG_ARCH_GIC_V3 + +STATIC UINT32 g_curIrqNum = 0; + +STATIC INLINE UINT64 MpidrToAffinity(UINT64 mpidr) +{ + return ((MPIDR_AFF_LEVEL(mpidr, 3) << 32) | /* 3: Serial number, 32: Register bit offset */ + (MPIDR_AFF_LEVEL(mpidr, 2) << 16) | /* 2: Serial number, 16: Register bit offset */ + (MPIDR_AFF_LEVEL(mpidr, 1) << 8) | /* 1: Serial number, 8: Register bit offset */ + (MPIDR_AFF_LEVEL(mpidr, 0))); +} + +#ifdef LOSCFG_KERNEL_SMP + +STATIC UINT32 NextCpu(UINT32 cpu, UINT32 cpuMask) +{ + UINT32 next = cpu + 1; + + while (next < LOSCFG_KERNEL_CORE_NUM) { + if (cpuMask & (1U << next)) { + goto OUT; + } + + next++; + } + +OUT: + return next; +} + +STATIC UINT16 GicTargetList(UINT32 *base, UINT32 cpuMask, UINT64 cluster) +{ + UINT32 nextCpu; + UINT16 tList = 0; + UINT32 cpu = *base; + UINT64 mpidr = CPU_MAP_GET(cpu); + while (cpu < LOSCFG_KERNEL_CORE_NUM) { + tList |= 1U << (mpidr & 0xf); + + nextCpu = NextCpu(cpu, cpuMask); + if (nextCpu >= LOSCFG_KERNEL_CORE_NUM) { + goto out; + } + + cpu = nextCpu; + mpidr = CPU_MAP_GET(cpu); + if (cluster != (mpidr & ~0xffUL)) { + cpu--; + goto out; + } + } + +out: + *base = cpu; + return tList; +} + +STATIC VOID GicSgi(UINT32 irq, UINT32 cpuMask) +{ + UINT16 tList; + UINT32 cpu = 0; + UINT64 val, cluster; + + while (cpuMask && (cpu < LOSCFG_KERNEL_CORE_NUM)) { + if (cpuMask & (1U << cpu)) { + cluster = CPU_MAP_GET(cpu) & ~0xffUL; + + tList = GicTargetList(&cpu, cpuMask, cluster); + + /* Generates a Group 1 interrupt for the current security state */ + val = ((MPIDR_AFF_LEVEL(cluster, 3) << 48) | /* 3: Serial number, 48: Register bit offset */ + (MPIDR_AFF_LEVEL(cluster, 2) << 32) | /* 2: Serial number, 32: Register bit offset */ + (MPIDR_AFF_LEVEL(cluster, 1) << 16) | /* 1: Serial number, 16: Register bit offset */ + (irq << 24) | tList); /* 24: Register bit offset */ + + GiccSetSgi1r(val); + } + + cpu++; + } +} + +VOID HalIrqSendIpi(UINT32 target, UINT32 ipi) +{ + GicSgi(ipi, target); +} + +VOID HalIrqSetAffinity(UINT32 irq, UINT32 cpuMask) +{ + UINT64 affinity = MpidrToAffinity(NextCpu(0, cpuMask)); + + /* When ARE is on, use router */ + GIC_REG_64(GICD_IROUTER(irq)) = affinity; +} + +#endif + +STATIC VOID GicWaitForRwp(UINT64 reg) +{ + INT32 count = 1000000; /* 1s */ + + while (GIC_REG_32(reg) & GICD_CTLR_RWP) { + count -= 1; + if (!count) { + PRINTK("gic_v3: rwp timeout 0x%x\n", GIC_REG_32(reg)); + return; + } + } +} + +STATIC INLINE VOID GicdSetGroup(UINT32 irq) +{ + /* configure spi as group 0 on secure mode and group 1 on unsecure mode */ +#ifdef LOSCFG_ARCH_SECURE_MONITOR_MODE + GIC_REG_32(GICD_IGROUPR(irq / 32)) = 0; /* 32: Interrupt bit width */ +#else + GIC_REG_32(GICD_IGROUPR(irq / 32)) = 0xffffffff; /* 32: Interrupt bit width */ +#endif +} + +STATIC INLINE VOID GicrSetWaker(UINT32 cpu) +{ + GIC_REG_32(GICR_WAKER(cpu)) &= ~GICR_WAKER_PROCESSORSLEEP; + DSB; + ISB; + while ((GIC_REG_32(GICR_WAKER(cpu)) & 0x4) == GICR_WAKER_CHILDRENASLEEP); +} + +STATIC INLINE VOID GicrSetGroup(UINT32 cpu) +{ + /* configure sgi/ppi as group 0 on secure mode and group 1 on unsecure mode */ +#ifdef LOSCFG_ARCH_SECURE_MONITOR_MODE + GIC_REG_32(GICR_IGROUPR0(cpu)) = 0; + GIC_REG_32(GICR_IGRPMOD0(cpu)) = 0; +#else + GIC_REG_32(GICR_IGROUPR0(cpu)) = 0xffffffff; +#endif +} + +STATIC VOID GicdSetPmr(UINT32 irq, UINT8 priority) +{ + UINT32 pos = irq >> 2; /* one irq have the 8-bit interrupt priority field */ + UINT32 newPri = GIC_REG_32(GICD_IPRIORITYR(pos)); + + /* Shift and mask the correct bits for the priority */ + newPri &= ~(GIC_PRIORITY_MASK << ((irq % 4) * GIC_PRIORITY_OFFSET)); + newPri |= priority << ((irq % 4) * GIC_PRIORITY_OFFSET); + + GIC_REG_32(GICD_IPRIORITYR(pos)) = newPri; +} + +STATIC VOID GicrSetPmr(UINT32 irq, UINT8 priority) +{ + UINT32 cpu = ArchCurrCpuid(); + UINT32 pos = irq >> 2; /* one irq have the 8-bit interrupt priority field */ + UINT32 newPri = GIC_REG_32(GICR_IPRIORITYR0(cpu) + pos * 4); + + /* Clear priority offset bits and set new priority */ + newPri &= ~(GIC_PRIORITY_MASK << ((irq % 4) * GIC_PRIORITY_OFFSET)); + newPri |= priority << ((irq % 4) * GIC_PRIORITY_OFFSET); + + GIC_REG_32(GICR_IPRIORITYR0(cpu) + pos * 4) = newPri; +} + +STATIC VOID GiccInitPercpu(VOID) +{ + /* enable system register interface */ + UINT32 sre = GiccGetSre(); + if (!(sre & 0x1)) { + GiccSetSre(sre | 0x1); + + /* + * Need to check that the SRE bit has actually been set. If + * not, it means that SRE is disabled at up EL level. We're going to + * die painfully, and there is nothing we can do about it. + */ + sre = GiccGetSre(); + LOS_ASSERT(sre & 0x1); + } + +#ifdef LOSCFG_ARCH_SECURE_MONITOR_MODE + /* Enable group 0 and disable grp1ns grp1s interrupts */ + GiccSetIgrpen0(1); + GiccSetIgrpen1(0); + + /* + * For priority grouping. + * The value of this field control show the 8-bit interrupt priority field + * is split into a group priority field, that determines interrupt preemption, + * and a subpriority field. + */ + GiccSetBpr0(MAX_BINARY_POINT_VALUE); +#else + /* enable group 1 interrupts */ + GiccSetIgrpen1(1); +#endif + + /* set priority threshold to max */ + GiccSetPmr(0xff); + + /* EOI deactivates interrupt too (mode 0) */ + GiccSetCtlr(0); +} + +UINT32 HalCurIrqGet(VOID) +{ + return g_curIrqNum; +} + +VOID HalIrqMask(UINT32 vector) +{ + INT32 i; + const UINT32 mask = 1U << (vector % 32); /* 32: Interrupt bit width */ + + if ((vector > OS_USER_HWI_MAX) || (vector < OS_USER_HWI_MIN)) { + return; + } + + if (vector < 32) { /* 32: Interrupt bit width */ + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + GIC_REG_32(GICR_ICENABLER0(i)) = mask; + GicWaitForRwp(GICR_CTLR(i)); + } + } else { + GIC_REG_32(GICD_ICENABLER(vector >> 5)) = mask; + GicWaitForRwp(GICD_CTLR); + } +} + +VOID HalIrqUnmask(UINT32 vector) +{ + INT32 i; + const UINT32 mask = 1U << (vector % 32); /* 32: Interrupt bit width */ + + if ((vector > OS_USER_HWI_MAX) || (vector < OS_USER_HWI_MIN)) { + return; + } + + if (vector < 32) { /* 32: Interrupt bit width */ + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + GIC_REG_32(GICR_ISENABLER0(i)) = mask; + GicWaitForRwp(GICR_CTLR(i)); + } + } else { + GIC_REG_32(GICD_ISENABLER(vector >> 5)) = mask; /* 5: Register bit offset */ + GicWaitForRwp(GICD_CTLR); + } +} + +VOID HalIrqPending(UINT32 vector) +{ + if ((vector > OS_USER_HWI_MAX) || (vector < OS_USER_HWI_MIN)) { + return; + } + + GIC_REG_32(GICD_ISPENDR(vector >> 5)) = 1U << (vector % 32); /* 5: Register bit offset, 32: Interrupt bit width */ +} + +VOID HalIrqClear(UINT32 vector) +{ + GiccSetEoir(vector); + ISB; +} + +UINT32 HalIrqSetPrio(UINT32 vector, UINT8 priority) +{ + UINT8 prio = priority; + + if (vector > OS_HWI_MAX_NUM) { + PRINT_ERR("Invalid irq value %u, max irq is %u\n", vector, OS_HWI_MAX_NUM); + return LOS_NOK; + } + + prio = prio & (UINT8)GIC_INTR_PRIO_MASK; + + if (vector >= GIC_MIN_SPI_NUM) { + GicdSetPmr(vector, prio); + } else { + GicrSetPmr(vector, prio); + } + + return LOS_OK; +} + +VOID HalIrqInitPercpu(VOID) +{ + INT32 idx; + UINT32 cpu = ArchCurrCpuid(); + + /* GICR init */ + GicrSetWaker(cpu); + GicrSetGroup(cpu); + GicWaitForRwp(GICR_CTLR(cpu)); + + /* GICR: clear and mask sgi/ppi */ + GIC_REG_32(GICR_ICENABLER0(cpu)) = 0xffffffff; + GIC_REG_32(GICR_ICPENDR0(cpu)) = 0xffffffff; + + GIC_REG_32(GICR_ISENABLER0(cpu)) = 0xffffffff; + + for (idx = 0; idx < GIC_MIN_SPI_NUM; idx += 1) { + GicrSetPmr(idx, MIN_INTERRUPT_PRIORITY); + } + + GicWaitForRwp(GICR_CTLR(cpu)); + + /* GICC init */ + GiccInitPercpu(); + +#ifdef LOSCFG_KERNEL_SMP + /* unmask ipi interrupts */ + HalIrqUnmask(LOS_MP_IPI_WAKEUP); + HalIrqUnmask(LOS_MP_IPI_HALT); +#endif +} + +VOID HalIrqInit(VOID) +{ + UINT32 i; + UINT64 affinity; + + /* disable distributor */ + GIC_REG_32(GICD_CTLR) = 0; + GicWaitForRwp(GICD_CTLR); + ISB; + + /* set external interrupts to be level triggered, active low. */ + for (i = 32; i < OS_HWI_MAX_NUM; i += 16) { /* 32: Start interrupt number, 16: Interrupt bit width */ + GIC_REG_32(GICD_ICFGR(i / 16)) = 0; + } + + /* config distributer, mask and clear all spis, set group x */ + for (i = 32; i < OS_HWI_MAX_NUM; i += 32) { /* 32: Start interrupt number, 32: Interrupt bit width */ + GIC_REG_32(GICD_ICENABLER(i / 32)) = 0xffffffff; /* 32: Interrupt bit width */ + GIC_REG_32(GICD_ICPENDR(i / 32)) = 0xffffffff; /* 32: Interrupt bit width */ + GIC_REG_32(GICD_IGRPMODR(i / 32)) = 0; /* 32: Interrupt bit width */ + + GicdSetGroup(i); + } + + /* set spi priority as default */ + for (i = 32; i < OS_HWI_MAX_NUM; i++) { /* 32: Start interrupt number */ + GicdSetPmr(i, MIN_INTERRUPT_PRIORITY); + } + + GicWaitForRwp(GICD_CTLR); + + /* disable all interrupts. */ + for (i = 0; i < OS_HWI_MAX_NUM; i += 32) { /* 32: Interrupt bit width */ + GIC_REG_32(GICD_ICENABLER(i / 32)) = 0xffffffff; /* 32: Interrupt bit width */ + } + + /* enable distributor with ARE, group 1 enabled */ + GIC_REG_32(GICD_CTLR) = CTLR_ENALBE_G0 | CTLR_ENABLE_G1NS | CTLR_ARE_S; + + /* set spi to boot cpu only. ARE must be enabled */ + affinity = MpidrToAffinity(AARCH64_SYSREG_READ(mpidr_el1)); + for (i = 32; i < OS_HWI_MAX_NUM; i++) { /* 32: Start interrupt number */ + GIC_REG_64(GICD_IROUTER(i)) = affinity; + } + + HalIrqInitPercpu(); + +#ifdef LOSCFG_KERNEL_SMP + /* register inter-processor interrupt */ + (VOID)LOS_HwiCreate(LOS_MP_IPI_WAKEUP, 0xa0, 0, OsMpWakeHandler, 0); + (VOID)LOS_HwiCreate(LOS_MP_IPI_SCHEDULE, 0xa0, 0, OsMpScheduleHandler, 0); + (VOID)LOS_HwiCreate(LOS_MP_IPI_HALT, 0xa0, 0, OsMpScheduleHandler, 0); +#ifdef LOSCFG_KERNEL_SMP_CALL + (VOID)LOS_HwiCreate(LOS_MP_IPI_FUNC_CALL, 0xa0, 0, OsMpFuncCallHandler, 0); +#endif +#endif +} + +VOID HalIrqHandler(VOID) +{ + UINT32 iar = GiccGetIar(); + UINT32 vector = iar & 0x3FFU; + + /* + * invalid irq number, mainly the spurious interrupts 0x3ff, + * valid irq ranges from 0~1019, we use OS_HWI_MAX_NUM to do + * the checking. + */ + if (vector >= OS_HWI_MAX_NUM) { + return; + } + g_curIrqNum = vector; + + OsInterrupt(vector); + GiccSetEoir(vector); +} + +CHAR *HalIrqVersion(VOID) +{ + UINT32 pidr = GIC_REG_32(GICD_PIDR2V3); + CHAR *irqVerString = NULL; + + switch (pidr >> GIC_REV_OFFSET) { + case GICV3: + irqVerString = "GICv3"; + break; + case GICV4: + irqVerString = "GICv4"; + break; + default: + irqVerString = "unknown"; + } + return irqVerString; +} + +#endif diff --git a/src/kernel_liteos_a/arch/arm/include/gic_common.h b/src/kernel_liteos_a/arch/arm/include/gic_common.h new file mode 100644 index 00000000..e9ac5622 --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/include/gic_common.h @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _GIC_COMMON_H +#define _GIC_COMMON_H + +#include "stdint.h" +#include "target_config.h" +#include "los_config.h" + +/* gic arch revision */ +enum { + GICV1 = 1, + GICV2, + GICV3, + GICV4 +}; + +#define GIC_REV_MASK 0xF0 +#define GIC_REV_OFFSET 0x4 + +#ifdef LOSCFG_ARCH_GIC_V2 +#define GICC_CTLR (GICC_OFFSET + 0x00) /* CPU Interface Control Register */ +#define GICC_PMR (GICC_OFFSET + 0x04) /* Interrupt Priority Mask Register */ +#define GICC_BPR (GICC_OFFSET + 0x08) /* Binary Point Register */ +#define GICC_IAR (GICC_OFFSET + 0x0c) /* Interrupt Acknowledge Register */ +#define GICC_EOIR (GICC_OFFSET + 0x10) /* End of Interrupt Register */ +#define GICC_RPR (GICC_OFFSET + 0x14) /* Running Priority Register */ +#define GICC_HPPIR (GICC_OFFSET + 0x18) /* Highest Priority Pending Interrupt Register */ +#endif + +#define GICD_CTLR (GICD_OFFSET + 0x000) /* Distributor Control Register */ +#define GICD_TYPER (GICD_OFFSET + 0x004) /* Interrupt Controller Type Register */ +#define GICD_IIDR (GICD_OFFSET + 0x008) /* Distributor Implementer Identification Register */ +#define GICD_IGROUPR(n) (GICD_OFFSET + 0x080 + (n) * 4) /* Interrupt Group Registers */ +#define GICD_ISENABLER(n) (GICD_OFFSET + 0x100 + (n) * 4) /* Interrupt Set-Enable Registers */ +#define GICD_ICENABLER(n) (GICD_OFFSET + 0x180 + (n) * 4) /* Interrupt Clear-Enable Registers */ +#define GICD_ISPENDR(n) (GICD_OFFSET + 0x200 + (n) * 4) /* Interrupt Set-Pending Registers */ +#define GICD_ICPENDR(n) (GICD_OFFSET + 0x280 + (n) * 4) /* Interrupt Clear-Pending Registers */ +#define GICD_ISACTIVER(n) (GICD_OFFSET + 0x300 + (n) * 4) /* GICv2 Interrupt Set-Active Registers */ +#define GICD_ICACTIVER(n) (GICD_OFFSET + 0x380 + (n) * 4) /* Interrupt Clear-Active Registers */ +#define GICD_IPRIORITYR(n) (GICD_OFFSET + 0x400 + (n) * 4) /* Interrupt Priority Registers */ +#define GICD_ITARGETSR(n) (GICD_OFFSET + 0x800 + (n) * 4) /* Interrupt Processor Targets Registers */ +#define GICD_ICFGR(n) (GICD_OFFSET + 0xc00 + (n) * 4) /* Interrupt Configuration Registers */ +#define GICD_SGIR (GICD_OFFSET + 0xf00) /* Software Generated Interrupt Register */ +#define GICD_CPENDSGIR(n) (GICD_OFFSET + 0xf10 + (n) * 4) /* SGI Clear-Pending Registers; NOT available on cortex-a9 */ +#define GICD_SPENDSGIR(n) (GICD_OFFSET + 0xf20 + (n) * 4) /* SGI Set-Pending Registers; NOT available on cortex-a9 */ +#define GICD_PIDR2V2 (GICD_OFFSET + 0xfe8) +#define GICD_PIDR2V3 (GICD_OFFSET + 0xffe8) + +#ifdef LOSCFG_ARCH_GIC_V3 +#define GICD_IGRPMODR(n) (GICD_OFFSET + 0x0d00 + (n) * 4) /* Interrupt Group Mode Registers */ +#define GICD_IROUTER(n) (GICD_OFFSET + 0x6000 + (n) * 8) /* Interrupt Rounter Registers */ +#endif + +#define GIC_REG_8(reg) (*(volatile UINT8 *)((UINTPTR)(GIC_BASE_ADDR + (reg)))) +#define GIC_REG_32(reg) (*(volatile UINT32 *)((UINTPTR)(GIC_BASE_ADDR + (reg)))) +#define GIC_REG_64(reg) (*(volatile UINT64 *)((UINTPTR)(GIC_BASE_ADDR + (reg)))) + +#define GICD_INT_DEF_PRI 0xa0U +#define GICD_INT_DEF_PRI_X4 (((UINT32)GICD_INT_DEF_PRI << 24) | \ + ((UINT32)GICD_INT_DEF_PRI << 16) | \ + ((UINT32)GICD_INT_DEF_PRI << 8) | \ + (UINT32)GICD_INT_DEF_PRI) + +#define GIC_MIN_SPI_NUM 32 + +/* Interrupt preemption config */ +#define GIC_PRIORITY_MASK 0xFFU +#define GIC_PRIORITY_OFFSET 8 + +/* + * The number of bits to shift for an interrupt priority is dependent + * on the number of bits implemented by the interrupt controller. + * If the MAX_BINARY_POINT_VALUE is 7, + * it means that interrupt preemption is not supported. + */ +#ifndef LOSCFG_ARCH_INTERRUPT_PREEMPTION +#define MAX_BINARY_POINT_VALUE 7 +#define PRIORITY_SHIFT 0 +#define GIC_MAX_INTERRUPT_PREEMPTION_LEVEL 0U +#else +#define PRIORITY_SHIFT ((MAX_BINARY_POINT_VALUE + 1) % GIC_PRIORITY_OFFSET) +#define GIC_MAX_INTERRUPT_PREEMPTION_LEVEL ((UINT8)((GIC_PRIORITY_MASK + 1) >> PRIORITY_SHIFT)) +#endif + +#define GIC_INTR_PRIO_MASK ((UINT8)(0xFFFFFFFFU << PRIORITY_SHIFT)) + +/* + * The preemption level is up to 128, and the maximum value corresponding to the interrupt priority is 254 [7:1]. + * If the GIC_MAX_INTERRUPT_PREEMPTION_LEVEL is 0, the minimum priority is 0xff. + */ +#define MIN_INTERRUPT_PRIORITY ((UINT8)((GIC_MAX_INTERRUPT_PREEMPTION_LEVEL - 1) << PRIORITY_SHIFT)) + +#endif diff --git a/src/kernel_liteos_a/arch/arm/include/gic_v3.h b/src/kernel_liteos_a/arch/arm/include/gic_v3.h new file mode 100644 index 00000000..7f846732 --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/include/gic_v3.h @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _GIC_V3_H_ +#define _GIC_V3_H_ + +#include "stdint.h" +#include "target_config.h" +#include "los_hw_cpu.h" + +#define BIT_32(bit) (1u << bit) +#define BIT_64(bit) (1ul << bit) + +#define ICC_CTLR_EL1 "S3_0_C12_C12_4" +#define ICC_PMR_EL1 "S3_0_C4_C6_0" +#define ICC_IAR1_EL1 "S3_0_C12_C12_0" +#define ICC_SRE_EL1 "S3_0_C12_C12_5" +#define ICC_BPR0_EL1 "S3_0_C12_C8_3" +#define ICC_BPR1_EL1 "S3_0_C12_C12_3" +#define ICC_IGRPEN0_EL1 "S3_0_C12_C12_6" +#define ICC_IGRPEN1_EL1 "S3_0_C12_C12_7" +#define ICC_EOIR1_EL1 "S3_0_C12_C12_1" +#define ICC_SGI1R_EL1 "S3_0_C12_C11_5" +#define ICC_EOIR0_EL1 "S3_0_c12_c8_1" +#define ICC_IAR0_EL1 "S3_0_C12_C8_0" + +#define ICC_CTLR_EL3 "S3_6_C12_C12_4" +#define ICC_SRE_EL3 "S3_6_C12_C12_5" +#define ICC_IGRPEN1_EL3 "S3_6_C12_C12_7" + +/* GICD_CTLR bit definitions */ +#define CTLR_ENALBE_G0 BIT_32(0) +#define CTLR_ENABLE_G1NS BIT_32(1) +#define CTLR_ENABLE_G1S BIT_32(2) +#define CTLR_RES0 BIT_32(3) +#define CTLR_ARE_S BIT_32(4) +#define CTLR_ARE_NS BIT_32(5) +#define CTLR_DS BIT_32(6) +#define CTLR_E1NWF BIT_32(7) +#define GICD_CTLR_RWP BIT_32(31) + +/* peripheral identification registers */ +#define GICD_CIDR0 (GICD_OFFSET + 0xfff0) +#define GICD_CIDR1 (GICD_OFFSET + 0xfff4) +#define GICD_CIDR2 (GICD_OFFSET + 0xfff8) +#define GICD_CIDR3 (GICD_OFFSET + 0xfffc) +#define GICD_PIDR0 (GICD_OFFSET + 0xffe0) +#define GICD_PIDR1 (GICD_OFFSET + 0xffe4) +#define GICD_PIDR2 (GICD_OFFSET + 0xffe8) +#define GICD_PIDR3 (GICD_OFFSET + 0xffec) + +/* GICD_PIDR bit definitions and masks */ +#define GICD_PIDR2_ARCHREV_SHIFT 4 +#define GICD_PIDR2_ARCHREV_MASK 0xf + +/* redistributor registers */ +#define GICR_SGI_OFFSET (GICR_OFFSET + 0x10000) + +#define GICR_CTLR(i) (GICR_OFFSET + GICR_STRIDE * (i) + 0x0000) +#define GICR_IIDR(i) (GICR_OFFSET + GICR_STRIDE * (i) + 0x0004) +#define GICR_TYPER(i, n) (GICR_OFFSET + GICR_STRIDE * (i) + 0x0008 + (n)*4) +#define GICR_STATUSR(i) (GICR_OFFSET + GICR_STRIDE * (i) + 0x0010) +#define GICR_WAKER(i) (GICR_OFFSET + GICR_STRIDE * (i) + 0x0014) +#define GICR_IGROUPR0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0080) +#define GICR_IGRPMOD0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0d00) +#define GICR_ISENABLER0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0100) +#define GICR_ICENABLER0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0180) +#define GICR_ISPENDR0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0200) +#define GICR_ICPENDR0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0280) +#define GICR_ISACTIVER0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0300) +#define GICR_ICACTIVER0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0380) +#define GICR_IPRIORITYR0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0400) +#define GICR_ICFGR0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0c00) +#define GICR_ICFGR1(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0c04) +#define GICR_NSACR(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0e00) + +#define GICR_WAKER_PROCESSORSLEEP_LEN 1U +#define GICR_WAKER_PROCESSORSLEEP_OFFSET 1 +#define GICR_WAKER_CHILDRENASLEEP_LEN 1U +#define GICR_WAKER_CHILDRENASLEEP_OFFSET 2 +#define GICR_WAKER_PROCESSORSLEEP (GICR_WAKER_PROCESSORSLEEP_LEN << GICR_WAKER_PROCESSORSLEEP_OFFSET) +#define GICR_WAKER_CHILDRENASLEEP (GICR_WAKER_CHILDRENASLEEP_LEN << GICR_WAKER_CHILDRENASLEEP_OFFSET) + +STATIC INLINE VOID GiccSetCtlr(UINT32 val) +{ +#ifdef LOSCFG_ARCH_SECURE_MONITOR_MODE + __asm__ volatile("msr " ICC_CTLR_EL3 ", %0" ::"r"(val)); +#else + __asm__ volatile("msr " ICC_CTLR_EL1 ", %0" ::"r"(val)); +#endif + ISB; +} + +STATIC INLINE VOID GiccSetPmr(UINT32 val) +{ + __asm__ volatile("msr " ICC_PMR_EL1 ", %0" ::"r"(val)); + ISB; + DSB; +} + +STATIC INLINE VOID GiccSetIgrpen0(UINT32 val) +{ + __asm__ volatile("msr " ICC_IGRPEN0_EL1 ", %0" ::"r"(val)); + ISB; +} + +STATIC INLINE VOID GiccSetIgrpen1(UINT32 val) +{ +#ifdef LOSCFG_ARCH_SECURE_MONITOR_MODE + __asm__ volatile("msr " ICC_IGRPEN1_EL3 ", %0" ::"r"(val)); +#else + __asm__ volatile("msr " ICC_IGRPEN1_EL1 ", %0" ::"r"(val)); +#endif + ISB; +} + +STATIC INLINE UINT32 GiccGetSre(VOID) +{ + UINT32 temp; +#ifdef LOSCFG_ARCH_SECURE_MONITOR_MODE + __asm__ volatile("mrs %0, " ICC_SRE_EL3 : "=r"(temp)); +#else + __asm__ volatile("mrs %0, " ICC_SRE_EL1 : "=r"(temp)); +#endif + return temp; +} + +STATIC INLINE VOID GiccSetSre(UINT32 val) +{ +#ifdef LOSCFG_ARCH_SECURE_MONITOR_MODE + __asm__ volatile("msr " ICC_SRE_EL3 ", %0" ::"r"(val)); +#else + __asm__ volatile("msr " ICC_SRE_EL1 ", %0" ::"r"(val)); +#endif + ISB; +} + +STATIC INLINE VOID GiccSetEoir(UINT32 val) +{ +#ifdef LOSCFG_ARCH_SECURE_MONITOR_MODE + __asm__ volatile("msr " ICC_EOIR0_EL1 ", %0" ::"r"(val)); +#else + __asm__ volatile("msr " ICC_EOIR1_EL1 ", %0" ::"r"(val)); +#endif + ISB; +} + +STATIC INLINE UINT32 GiccGetIar(VOID) +{ + UINT32 temp; + +#ifdef LOSCFG_ARCH_SECURE_MONITOR_MODE + __asm__ volatile("mrs %0, " ICC_IAR0_EL1 : "=r"(temp)); +#else + __asm__ volatile("mrs %0, " ICC_IAR1_EL1 : "=r"(temp)); +#endif + DSB; + + return temp; +} + +STATIC INLINE VOID GiccSetSgi1r(UINT64 val) +{ + __asm__ volatile("msr " ICC_SGI1R_EL1 ", %0" ::"r"(val)); + ISB; + DSB; +} + +STATIC INLINE VOID GiccSetBpr0(UINT32 val) +{ + __asm__ volatile("msr " ICC_BPR0_EL1 ", %0" ::"r"(val)); + ISB; + DSB; +} +#endif diff --git a/src/kernel_liteos_a/arch/arm/include/hal_hwi.h b/src/kernel_liteos_a/arch/arm/include/hal_hwi.h new file mode 100644 index 00000000..4b068e41 --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/include/hal_hwi.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _HWI_H +#define _HWI_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +extern VOID HalIrqInit(VOID); +extern VOID HalIrqInitPercpu(VOID); +extern VOID HalIrqMask(UINT32 vector); +extern VOID HalIrqUnmask(UINT32 vector); +extern VOID HalIrqPending(UINT32 vector); +extern VOID HalIrqClear(UINT32 vector); +extern CHAR *HalIrqVersion(VOID); +extern UINT32 HalCurIrqGet(VOID); +extern UINT32 HalIrqSetPrio(UINT32 vector, UINT8 priority); +#ifdef LOSCFG_KERNEL_SMP +extern VOID HalIrqSendIpi(UINT32 target, UINT32 ipi); +extern VOID HalIrqSetAffinity(UINT32 vector, UINT32 cpuMask); +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _HWI_H */ diff --git a/src/kernel_liteos_a/arch/arm/include/in_cksum.h b/src/kernel_liteos_a/arch/arm/include/in_cksum.h new file mode 100644 index 00000000..e86c4966 --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/include/in_cksum.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __LINUX_CHECKSUM_H__ +#define __LINUX_CHECKSUM_H__ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +unsigned int csum_partial(const void *buf, int len, unsigned int wsum); +unsigned int csum_partial_copy_nocheck(const void *src, void *dst, int len, unsigned int wsum); +unsigned short in_cksum(const void *buf, int len); +unsigned short in_cksum_copy(const void *src, void *dst, int len); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/src/kernel_liteos_a/arch/arm/include/los_exc.h b/src/kernel_liteos_a/arch/arm/include/los_exc.h new file mode 100644 index 00000000..893f06e0 --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/include/los_exc.h @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_exc Exception handling + * @ingroup kernel + */ +#ifndef _LOS_EXC_H +#define _LOS_EXC_H + +#include "los_typedef.h" +#include "arch_config.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_exc + * Register information structure + * + * Description: register information stored when an exception occurs on an LPC2458 platform. + * + * Note: The following register names without uw are the register names used in the chip manual. + */ +#ifdef LOSCFG_ARCH_ARM_AARCH64 +#define EXC_GEN_REGS_NUM 30 +typedef struct { + UINT64 X[EXC_GEN_REGS_NUM]; /**< Register X0-X29 */ + UINT64 LR; /**< Program returning address. X30 */ + UINT64 SP; + UINT64 regELR; + UINT64 SPSR; +} ExcContext; +#else +/* It has the same structure as TaskContext */ +typedef struct { + UINT32 R4; + UINT32 R5; + UINT32 R6; + UINT32 R7; + UINT32 R8; + UINT32 R9; + UINT32 R10; + UINT32 R11; + + UINT32 SP; /**< svc sp */ + UINT32 reserved; /**< Reserved, multiplexing register */ + UINT32 USP; + UINT32 ULR; + UINT32 R0; /**< Register R0 */ + UINT32 R1; /**< Register R1 */ + UINT32 R2; /**< Register R2 */ + UINT32 R3; /**< Register R3 */ + UINT32 R12; /**< Register R12 */ + UINT32 LR; /**< Program returning address. */ + UINT32 PC; /**< PC pointer of the exceptional function */ + UINT32 regCPSR; +} ExcContext; +#endif + +/** + * @ingroup los_exc + * Exception information structure + * + * Description: exception information stored when an exception occurs on an LPC2458 platform. + * + */ +typedef struct { + UINT16 phase; /**< Phase in which an exception occurs */ + UINT16 type; /**< Exception type */ + UINT16 nestCnt; /**< Count of nested exception */ + UINT16 reserved; /**< Reserved for alignment */ + ExcContext *context; /**< Hardware context when an exception occurs */ +} ExcInfo; + +/** + * @ingroup los_exc + * @brief Kernel FP Register address obtain function. + * + * @par Description: + * The API is used to obtain the FP Register address. + * @attention None. + * + * @param None. + * + * @retval #UINTPTR The FP Register address. + * + * @par Dependency: + * los_exc.h: the header file that contains the API declaration. + * @see None. + */ +STATIC INLINE UINTPTR Get_Fp(VOID) +{ + UINTPTR regFp; + +#ifdef LOSCFG_ARCH_ARM_AARCH64 + __asm__ __volatile__("mov %0, X29" : "=r"(regFp)); +#else + __asm__ __volatile__("mov %0, fp" : "=r"(regFp)); +#endif + + return regFp; +} + +/** + * @ingroup los_exc + * @brief Define an exception handling function hook. + * + * @par Description: + * This API is used to define the exception handling function hook based on the type of + * the exception handling function and record exceptions. + * @attention None. + * + * @param None. + * + * @retval None. + * + * @par Dependency: + * los_exc.h: the header file that contains the API declaration. + * @see None. + */ +typedef VOID (*EXC_PROC_FUNC)(UINT32, ExcContext *, UINT32, UINT32); + +/** + * @ingroup los_exc + * @brief Register an exception handling hook. + * + * @par Description: + * This API is used to register an exception handling hook. + * @attention If the hook is registered for multiple times, the hook registered at the last time is effective. + * @attention The hook can be registered as NULL, indicating that the hook registration is canceled. + * @param excHook [IN] Type #EXC_PROC_FUNC: hook function. + * + * @retval #LOS_OK The exception handling hook is successfully registered. + * + * @par Dependency: + * los_exc.h: the header file that contains the API declaration. + * @see None. + */ +extern UINT32 LOS_ExcRegHook(EXC_PROC_FUNC excHook); + +/** + * @ingroup los_exc + * @brief Kernel panic function. + * + * @par Description: + * Stack function that prints kernel panics. + * @attention After this function is called and stack information is printed, the system will fail to respond. + * @attention The input parameter can be NULL. + * @param fmt [IN] Type #CHAR* : variadic argument. + * + * @retval #None. + * + * @par Dependency: + * los_exc.h: the header file that contains the API declaration. + * @see None. + */ +NORETURN VOID LOS_Panic(const CHAR *fmt, ...); + +/** + * @ingroup los_exc + * @brief record LR function. + * + * @par Description: + * @attention + * @param LR [IN] Type #UINTPTR * LR buffer. + * @param recordCount [IN] Type UINT32 record LR lay number. + * @param jumpCount [IN] Type UINT32 ignore LR lay number. + * + * @retval #None. + * + * @par Dependency: + * los_exc.h: the header file that contains the API declaration. + * @see None. + */ +VOID LOS_RecordLR(UINTPTR *LR, UINT32 LRSize, UINT32 recordCount, UINT32 jumpCount); + +/** + * @ingroup los_exc + * @brief Kernel backtrace function. + * + * @par Description: + * Backtrace function that prints task call stack information traced from the running task. + * @attention None. + * + * @param None. + * + * @retval #None. + * + * @par Dependency: + * los_exc.h: the header file that contains the API declaration. + * @see None. + */ +extern VOID OsBackTrace(VOID); + +/** + * @ingroup los_exc + * @brief Kernel task backtrace function. + * + * @par Description: + * Backtrace function that prints task call stack information traced from the input task. + * @attention + *
            + *
          • The input taskID should be valid.
          • + *
          + * + * @param taskID [IN] Type #UINT32 Task ID. + * + * @retval #None. + * + * @par Dependency: + * los_exc.h: the header file that contains the API declaration. + * @see None. + */ +extern VOID OsTaskBackTrace(UINT32 taskID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_EXC_H */ diff --git a/src/kernel_liteos_a/arch/arm/include/los_hw.h b/src/kernel_liteos_a/arch/arm/include/los_hw.h new file mode 100644 index 00000000..18f13e43 --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/include/los_hw.h @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_hw Hardware + * @ingroup kernel + */ +#ifndef _LOS_HW_H +#define _LOS_HW_H + +#include "los_typedef.h" +#include "los_hw_cpu.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define OS_SCHEDULE_IN_IRQ 0x0 +#define OS_SCHEDULE_IN_TASK 0x1 + +#define PSR_T_ARM 0x00000000u +#define PSR_T_THUMB 0x00000020u +#define PSR_MODE_SVC 0x00000013u +#define PSR_MODE_SYS 0x0000001Fu +#define PSR_FIQ_DIS 0x00000040u +#define PSR_IRQ_DIS 0x00000080u +#define PSR_MODE_USR 0x00000010u + +#define PSR_MODE_SVC_THUMB (PSR_MODE_SVC | PSR_T_THUMB | PSR_FIQ_DIS | PSR_IRQ_DIS) +#define PSR_MODE_SVC_ARM (PSR_MODE_SVC | PSR_T_ARM | PSR_FIQ_DIS | PSR_IRQ_DIS) + +#define PSR_MODE_SYS_THUMB (PSR_MODE_SYS | PSR_T_THUMB) +#define PSR_MODE_SYS_ARM (PSR_MODE_SYS | PSR_T_ARM) + +#define PSR_MODE_USR_THUMB (PSR_MODE_USR | PSR_T_THUMB) +#define PSR_MODE_USR_ARM (PSR_MODE_USR | PSR_T_ARM) + +#define LOS_CHECK_SCHEDULE ((!OS_INT_ACTIVE) && OsPreemptable()) + +typedef struct { + const UINT32 partNo; + const CHAR *cpuName; +} CpuVendor; + +extern CpuVendor g_cpuTable[]; +extern UINT64 g_cpuMap[]; + +#define CPU_MAP_GET(cpuid) g_cpuMap[(cpuid)] +#define CPU_MAP_SET(cpuid, hwid) g_cpuMap[(cpuid)] = (hwid) + +/** + * @ingroup los_hw + * @brief Invalidate instruction cache. + * + * @par Description: + *
            + *
          • This API is used to invalidate the instruction cache.
          • + *
          + * @attention None. + * + * @param None. + * + * @retval #None. + * + * @par Dependency: + * los_hw.h: the header file that contains the API declaration. + * @see None. + */ +extern VOID FlushICache(VOID); + +/** + * @ingroup los_hw + * @brief Flush data cache. + * + * @par Description: + *
            + *
          • This API is used to flush the data cache to the memory.
          • + *
          + * @attention + *
            + *
          • The input end address must be greater than the input start address.
          • + *
          + * + * @param start [IN] Type #int Flush start address. + * @param end [IN] Type #int Flush end address. + * + * @retval #None. + * + * @par Dependency: + * los_hw.h: the header file that contains the API declaration. + * @see None. + */ +extern VOID DCacheFlushRange(UINTPTR start, UINTPTR end); + +/** + * @ingroup los_hw + * @brief Invalidate data cache. + * + * @par Description: + *
            + *
          • This API is used to Invalidate the data in cache.
          • + *
          + * @attention + *
            + *
          • The input end address must be greater than the input start address.
          • + *
          + * + * @param start [IN] Type #int Invalidate start address. + * @param end [IN] Type #int Invalidate end address . + * + * @retval #None. + * + * @par Dependency: + * los_hw.h: the header file that contains the API declaration. + * @see None. + */ +extern VOID DCacheInvRange(UINTPTR start, UINTPTR end); + +/** + * @ingroup los_hw + * @brief Get cpu core name. + * + * @par Description: + *
            + *
          • This API is used to get cpu core name.
          • + *
          + * @attention + *
            + *
          • None.
          • + *
          + * + * @param + * @retval #CHAR * cpu core name. + * + * @par Dependency: + * los_hw.h: the header file that contains the API declaration. + * @see None. + */ +STATIC INLINE const CHAR *LOS_CpuInfo(VOID) +{ + INT32 i; + UINT32 midr = OsMainIDGet(); + /* [15:4] is the primary part number */ + UINT32 partNo = (midr & 0xFFF0) >> 0x4; + + for (i = 0; g_cpuTable[i].partNo != 0; i++) { + if (partNo == g_cpuTable[i].partNo) { + return g_cpuTable[i].cpuName; + } + } + + return "unknown"; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_HW_H */ diff --git a/src/kernel_liteos_a/arch/arm/include/los_hw_arch.h b/src/kernel_liteos_a/arch/arm/include/los_hw_arch.h new file mode 100644 index 00000000..3539d928 --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/include/los_hw_arch.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_hw Hardware + * @ingroup kernel + */ + +#ifndef _LOS_HW_ARCH_H +#define _LOS_HW_ARCH_H + +# if defined(__GNUC__) +# if defined(__aarch64__) +# define LOSCFG_ARM_AARCH64 1 +# endif +# +# define LOSCFG_ARM_ARCH __ARM_ARCH +# else +# error "unsupported compiler!" +# endif + +#endif diff --git a/src/kernel_liteos_a/arch/arm/include/los_hw_tick_pri.h b/src/kernel_liteos_a/arch/arm/include/los_hw_tick_pri.h new file mode 100644 index 00000000..1b893176 --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/include/los_hw_tick_pri.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_HW_TICK_PRI_H +#define _LOS_HW_TICK_PRI_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +extern UINT32 OsTickInit(UINT32 systemClock, UINT32 tickPerSecond); +extern VOID OsTickStart(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_HW_TICK_PRI_H */ diff --git a/src/kernel_liteos_a/arch/arm/include/los_hwi.h b/src/kernel_liteos_a/arch/arm/include/los_hwi.h new file mode 100644 index 00000000..cee783dc --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/include/los_hwi.h @@ -0,0 +1,439 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_hwi Hardware interrupt + * @ingroup kernel + */ +#ifndef _LOS_HWI_H +#define _LOS_HWI_H + +#include "los_base.h" +#include "los_hw_cpu.h" +#include "hal_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_hwi + * Count of interrupts. + */ +extern size_t g_intCount[]; + +/** + * @ingroup los_hwi + * An interrupt is active. + */ +#define OS_INT_ACTIVE ({ \ + size_t intCount; \ + UINT32 intSave_ = LOS_IntLock(); \ + intCount = g_intCount[ArchCurrCpuid()]; \ + LOS_IntRestore(intSave_); \ + intCount; \ +}) + +/** + * @ingroup los_hwi + * An interrupt is inactive. + */ +#define OS_INT_INACTIVE (!(OS_INT_ACTIVE)) + +/** + * @ingroup los_hwi + * Highest priority of a hardware interrupt. + */ +#define OS_HWI_PRIO_HIGHEST 0 + +/** + * @ingroup los_hwi + * Lowest priority of a hardware interrupt. + */ +#define OS_HWI_PRIO_LOWEST 31 + +/** + * @ingroup los_hwi + * Max name length of a hardware interrupt. + */ +#define OS_HWI_MAX_NAMELEN 10 + +/** + * @ingroup los_hwi + * Hardware interrupt error code: Invalid interrupt number. + * + * Value: 0x02000900 + * + * Solution: Ensure that the interrupt number is valid. + */ +#define OS_ERRNO_HWI_NUM_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x00) + +/** + * @ingroup los_hwi + * Hardware interrupt error code: Null hardware interrupt handling function. + * + * Value: 0x02000901 + * + * Solution: Pass in a valid non-null hardware interrupt handling function. + */ +#define OS_ERRNO_HWI_PROC_FUNC_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x01) + +/** + * @ingroup los_hwi + * Hardware interrupt error code: Insufficient interrupt resources for hardware interrupt creation. + * + * Value: 0x02000902 + * + * Solution: Increase the configured maximum number of supported hardware interrupts. + */ +#define OS_ERRNO_HWI_CB_UNAVAILABLE LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x02) + +/** + * @ingroup los_hwi + * Hardware interrupt error code: Insufficient memory for hardware interrupt initialization. + * + * Value: 0x02000903 + * + * Solution: Expand the configured memory. + */ +#define OS_ERRNO_HWI_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x03) + +/** + * @ingroup los_hwi + * Hardware interrupt error code: The interrupt has already been created. + * + * Value: 0x02000904 + * + * Solution: Check whether the interrupt specified by the passed-in interrupt number has already been created. + */ +#define OS_ERRNO_HWI_ALREADY_CREATED LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x04) + +/** + * @ingroup los_hwi + * Hardware interrupt error code: Invalid interrupt priority. + * + * Value: 0x02000905 + * + * Solution: Ensure that the interrupt priority is valid. + */ +#define OS_ERRNO_HWI_PRIO_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x05) + +/** + * @ingroup los_hwi + * Hardware interrupt error code: Incorrect interrupt creation mode. + * + * Value: 0x02000906 + * + * Solution: The interrupt creation mode can be only set to OS_HWI_MODE_COMM or OS_HWI_MODE_FAST of + * which the value can be 0 or 1. + */ +#define OS_ERRNO_HWI_MODE_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x06) + +/** + * @ingroup los_hwi + * Hardware interrupt error code: The interrupt has already been created as a fast interrupt. + * + * Value: 0x02000907 + * + * Solution: Check whether the interrupt specified by the passed-in interrupt number has already been created. + */ +#define OS_ERRNO_HWI_FASTMODE_ALREADY_CREATED LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x07) + +/** + * @ingroup los_hwi + * Hardware interrupt error code: The API is called during an interrupt, which is forbidden. + * + * Value: 0x02000908 + * + * * Solution: Do not call the API during an interrupt. + */ +#define OS_ERRNO_HWI_INTERR LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x08) + +/** + * @ingroup los_hwi + * Hardware interrupt error code:the hwi support SHARED error. + * + * Value: 0x02000909 + * + * * Solution: Check the input params hwiMode and irqParam of LOS_HwiCreate or + * LOS_HwiDelete whether adapt the current hwi. + */ +#define OS_ERRNO_HWI_SHARED_ERROR LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x09) + +/** + * @ingroup los_hwi + * Hardware interrupt error code:Invalid interrupt Arg when interrupt mode is IRQF_SHARED. + * + * Value: 0x0200090a + * + * * Solution: Check the interrupt Arg, Arg should not be NULL and pDevId should not be NULL. + */ +#define OS_ERRNO_HWI_ARG_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x0a) + +/** + * @ingroup los_hwi + * Hardware interrupt error code:The interrupt corresponded to the hwi number or devid has not been created. + * + * Value: 0x0200090b + * + * * Solution: Check the hwi number or devid, make sure the hwi number or devid need to delete. + */ +#define OS_ERRNO_HWI_HWINUM_UNCREATE LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x0b) + +/** + * @ingroup los_hwi + * Define the type of a hardware interrupt number. + */ +typedef UINT32 HWI_HANDLE_T; + +/** + * @ingroup los_hwi + * Define the type of a hardware interrupt priority. + */ +typedef UINT16 HWI_PRIOR_T; + +/** + * @ingroup los_hwi + * Define the type of hardware interrupt mode configurations. + */ +typedef UINT16 HWI_MODE_T; + +/** + * @ingroup los_hwi + * Define the type of the parameter used for the hardware interrupt creation function. + * The function of this parameter varies among platforms. + */ +typedef UINTPTR HWI_ARG_T; + +/** + * @ingroup los_hwi + * Define the type of a hardware interrupt handling function. + */ +typedef VOID (*HWI_PROC_FUNC)(VOID); + +/* + * These flags used only by the kernel as part of the + * irq handling routines. + * + * IRQF_SHARED - allow sharing the irq among several devices + */ +#define IRQF_SHARED 0x8000U + +typedef struct tagHwiHandleForm { + HWI_PROC_FUNC pfnHook; + HWI_ARG_T uwParam; + struct tagHwiHandleForm *pstNext; +} HwiHandleForm; + +typedef struct tagIrqParam { + int swIrq; + VOID *pDevId; + const CHAR *pName; +} HwiIrqParam; + +extern HwiHandleForm g_hwiForm[OS_HWI_MAX_NUM]; + +/** + * @ingroup los_hwi + * @brief Disable all interrupts. + * + * @par Description: + *
            + *
          • This API is used to disable all IRQ and FIQ interrupts in the CPSR.
          • + *
          + * @attention + *
            + *
          • None.
          • + *
          + * + * @param None. + * + * @retval #UINT32 CPSR value obtained before all interrupts are disabled. + * @par Dependency: + *
          • los_hwi.h: the header file that contains the API declaration.
          + * @see LOS_IntRestore + */ +STATIC INLINE UINT32 LOS_IntLock(VOID) +{ + return ArchIntLock(); +} + +/** + * @ingroup los_hwi + * @brief Enable all interrupts. + * + * @par Description: + *
            + *
          • This API is used to enable all IRQ and FIQ interrupts in the CPSR.
          • + *
          + * @attention + *
            + *
          • None.
          • + *
          + * + * @param None. + * + * @retval #UINT32 CPSR value obtained after all interrupts are enabled. + * @par Dependency: + *
          • los_hwi.h: the header file that contains the API declaration.
          + * @see LOS_IntLock + */ +STATIC INLINE UINT32 LOS_IntUnLock(VOID) +{ + return ArchIntUnlock(); +} + +/** + * @ingroup los_hwi + * @brief Restore interrupts. + * + * @par Description: + *
            + *
          • This API is used to restore the CPSR value obtained before all interrupts are disabled.
          • + *
          + * @attention + *
            + *
          • This API can be called only after all interrupts are disabled, and the input parameter value should be + * the value returned by LOS_IntLock.
          • + *
          + * + * @param intSave [IN] Type #UINT32 : CPSR value obtained before all interrupts are disabled. + * + * @retval None. + * @par Dependency: + *
          • los_hwi.h: the header file that contains the API declaration.
          + * @see LOS_IntLock + */ +STATIC INLINE VOID LOS_IntRestore(UINT32 intSave) +{ + ArchIntRestore(intSave); +} + +/** + * @ingroup los_hwi + * @brief Gets the maximum number of interrupts supported by the system. + * + * @par Description: + *
            + *
          • This API is used to gets the maximum number of interrupts supported by the system.
          • + *
          + * + * @param None. + * + * @retval None. + * @par Dependency: + *
          • los_hwi.h: the header file that contains the API declaration.
          + */ +extern UINT32 LOS_GetSystemHwiMaximum(VOID); + +/** + * @ingroup los_hwi + * @brief Create a hardware interrupt. + * + * @par Description: + * This API is used to configure a hardware interrupt and register a hardware interrupt handling function. + * + * @attention + *
            + *
          • The hardware interrupt module is usable only when the configuration item for + * hardware interrupt tailoring is enabled.
          • + *
          • Hardware interrupt number value range: [OS_USER_HWI_MIN,OS_USER_HWI_MAX].
          • + *
          • OS_HWI_MAX_NUM specifies the maximum number of interrupts that can be created.
          • + *
          • Before executing an interrupt on a platform, refer to the chip manual of the platform.
          • + *
          • The parameter handler of this interface is a interrupt handler, it should be correct, otherwise, + * the system may be abnormal.
          • + *
          • The input irqParam could be NULL, if not, it should be address which point to a struct HwiIrqParam
          • + *
          + * + * @param hwiNum [IN] Type #HWI_HANDLE_T: hardware interrupt number. + * for an ARM926 platform is [0,31]. + * @param hwiPrio [IN] Type #HWI_PRIOR_T: hardware interrupt priority. The value range is + * [0, GIC_MAX_INTERRUPT_PREEMPTION_LEVEL - 1] << PRIORITY_SHIFT. + * @param hwiMode [IN] Type #HWI_MODE_T: hardware interrupt mode. Ignore this parameter temporarily. + * @param hwiHandler [IN] Type #HWI_PROC_FUNC: interrupt handler used when a hardware interrupt is triggered. + * @param irqParam [IN] Type #HwiIrqParam: input parameter of the interrupt handler used when + * a hardware interrupt is triggered. + * + * @retval #OS_ERRNO_HWI_PROC_FUNC_NULL Null hardware interrupt handling function. + * @retval #OS_ERRNO_HWI_NUM_INVALID Invalid interrupt number. + * @retval #OS_ERRNO_HWI_NO_MEMORY Insufficient memory for hardware interrupt creation. + * @retval #OS_ERRNO_HWI_ALREADY_CREATED The interrupt handler being created has already been created. + * @retval #LOS_OK The interrupt is successfully created. + * @par Dependency: + *
          • los_hwi.h: the header file that contains the API declaration.
          + * @see None. + */ +extern UINT32 LOS_HwiCreate(HWI_HANDLE_T hwiNum, + HWI_PRIOR_T hwiPrio, + HWI_MODE_T hwiMode, + HWI_PROC_FUNC hwiHandler, + HwiIrqParam *irqParam); + +/** + * @ingroup los_hwi + * @brief delete a hardware interrupt. + * + * @par Description: + * This API is used to delete a hardware interrupt. + * + * @attention + *
            + *
          • The hardware interrupt module is usable only when the configuration item for + * hardware interrupt tailoring is enabled.
          • + *
          • Hardware interrupt number value range: [OS_USER_HWI_MIN,OS_USER_HWI_MAX].
          • + *
          • OS_HWI_MAX_NUM specifies the maximum number of interrupts that can be created.
          • + *
          • Before executing an interrupt on a platform, refer to the chip manual of the platform.
          • + *
          + * + * @param hwiNum [IN] Type #HWI_HANDLE_T: hardware interrupt number. + * @param irqParam [IN] Type #HwiIrqParam *: id of hardware interrupt which will base on + * when delete the hardware interrupt. + * + * @retval #OS_ERRNO_HWI_NUM_INVALID Invalid interrupt number. + * @retval #OS_ERRNO_HWI_SHARED_ERROR Invalid interrupt mode. + * @retval #LOS_OK The interrupt is successfully deleted. + * @retval #LOS_NOK The interrupt is failed deleted based on the pDev_ID. + + * @par Dependency: + *
          • los_hwi.h: the header file that contains the API declaration.
          + * @see None. + */ +extern UINT32 LOS_HwiDelete(HWI_HANDLE_T hwiNum, HwiIrqParam *irqParam); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_HWI_H */ diff --git a/src/kernel_liteos_a/arch/arm/include/los_strncpy_from_user.h b/src/kernel_liteos_a/arch/arm/include/los_strncpy_from_user.h new file mode 100644 index 00000000..7b0024ec --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/include/los_strncpy_from_user.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_STRNCPY_FROM_USER_H +#define _LOS_STRNCPY_FROM_USER_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/* + * @brief Copy a string end with NULL from userspace to kernelspace + * + * This function validates that usermode has access to src before copying the + * data. + * + * @param dst The destination buffer in kernel space. + * @param src The source buffer in user space. + * @param count Max number of bytes to copy. + * + * @return Return -EFAULT if src is not in user space or count <= 0 or copy out of range. Return the length of + * the string if success, if count is smaller than the length of the string then copy count bytes and return count. + */ +INT32 LOS_StrncpyFromUser(CHAR *dst, const CHAR *src, INT32 count); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_STRNCPY_FROM_USER_H */ diff --git a/src/kernel_liteos_a/arch/arm/include/los_strnlen_user.h b/src/kernel_liteos_a/arch/arm/include/los_strnlen_user.h new file mode 100644 index 00000000..39371a8c --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/include/los_strnlen_user.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_STRNLEN_USER_H +#define _LOS_STRNLEN_USER_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/* + * @brief Get the length of string including final NULL. + * + * This function validates that usermode has access to src before measuring the string. + * + * @param src The string in userspace to measure. + * @param count Max count. + * + * @return Return the length of the string including final NULL. Return 0 if src is not in user space or count <= 0 or + * visit the memory out of range. Return a number larger than count if the string is too long, User should handle + * this situation. + */ +INT32 LOS_StrnlenUser(const CHAR *src, INT32 count); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_STRNLEN_USER_H */ diff --git a/src/kernel_liteos_a/arch/arm/include/los_sys_stack_pri.h b/src/kernel_liteos_a/arch/arm/include/los_sys_stack_pri.h new file mode 100644 index 00000000..fb968fd9 --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/include/los_sys_stack_pri.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_SYS_STACK_H +#define _LOS_SYS_STACK_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#ifdef LOSCFG_AARCH64 +extern UINTPTR __stack_startup; +extern UINTPTR __stack_startup_top; +#else +extern UINTPTR __svc_stack_top; +extern UINTPTR __exc_stack_top; +extern UINTPTR __svc_stack; +extern UINTPTR __exc_stack; +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/src/kernel_liteos_a/arch/arm/include/los_user_get.h b/src/kernel_liteos_a/arch/arm/include/los_user_get.h new file mode 100644 index 00000000..de882a77 --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/include/los_user_get.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_USER_GET_H +#define _LOS_USER_GET_H + +#include "los_typedef.h" +#include "arm_user_get.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/* + * @brief Get data from userspace into kernelspace + * + * This function validates that usermode has access to src before copying the + * data. + * + * @param dst The destination buffer in kernel space. + * @param src The source buffer in user space. + * + * @note The data type is simple such as char, short, int, long in 32bits platform. + * + * @return Return -EFAULT if error. Return 0 if success. + */ +#define LOS_GetUser(dst, src) _arm_get_user((dst), (src), sizeof(*(dst)), sizeof(*(src))) + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_USER_GET_H */ diff --git a/src/kernel_liteos_a/arch/arm/include/los_user_put.h b/src/kernel_liteos_a/arch/arm/include/los_user_put.h new file mode 100644 index 00000000..f8e74535 --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/include/los_user_put.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_USER_PUT_H +#define _LOS_USER_PUT_H + +#include "los_typedef.h" +#include "arm_user_put.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/* + * @brief put data from kernelspace into userspace + * + * This function validates that usermode has access to dst before copying the + * data. + * + * @param dst The destination buffer in user space. + * @param src The source buffer in kernel space. + * + * @note The data type is simple such as char, short, int, long in 32bits platform. + * + * @return Return -EFAULT if error. Return 0 if success. + */ +#define LOS_PutUser(src, dst) _arm_put_user((dst), (src), sizeof(*(dst)), sizeof(*(src))) + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_USER_PUT_H */ diff --git a/src/kernel_liteos_a/arch/arm/include/perf.h b/src/kernel_liteos_a/arch/arm/include/perf.h new file mode 100644 index 00000000..cb9ecd4d --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/include/perf.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _PERF_H +#define _PERF_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define OsPerfArchFetchCallerRegs(regs) \ + do { \ + (regs)->pc = (UINTPTR)__builtin_return_address(0); \ + (regs)->fp = (UINTPTR)__builtin_frame_address(0); \ + } while (0) + +#define OsPerfArchFetchIrqRegs(regs, tcb) \ + do { \ + (regs)->pc = (tcb)->pc; \ + (regs)->fp = (tcb)->fp; \ + } while (0) + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _PERF_H */ diff --git a/src/kernel_liteos_a/arch/arm/include/user_copy.h b/src/kernel_liteos_a/arch/arm/include/user_copy.h new file mode 100644 index 00000000..293d4e34 --- /dev/null +++ b/src/kernel_liteos_a/arch/arm/include/user_copy.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_typedef.h" +#pragma once + +/* + * @brief Copy data from userspace into kernelspace + * + * This function validates that usermode has access to src before copying the + * data. + * + * @param dst The destination buffer. + * @param src The source buffer. + * @param len The number of bytes to copy. + * + * @return bytes not copied + */ +size_t LOS_ArchCopyFromUser(void *dst, const void *src, size_t len); + +/* + * @brief Copy data from kernelspace into userspace + * + * This function validates that usermode has access to dst before copying the + * data. + * + * @param dst The destination buffer. + * @param src The source buffer. + * @param len The number of bytes to copy. + * + * @return bytes not copied + */ +size_t LOS_ArchCopyToUser(void *dst, const void *src, size_t len); + +/* + * @brief Copy data from src to dst + * + * This function will use different copy methods to copy src data to dst, according to + * the different spaces (userspace or kernelspace) of dst data. + * + * @param dst The destination buffer, can be userspace address. + * @param max The maxsimum number of bytes to copy. + * @param src The source buffer. + * @param len The number of bytes to copy. + * + * @return zero on success; non-zero on failure. + */ +INT32 LOS_CopyFromKernel(VOID *dest, UINT32 max, const VOID *src, UINT32 count); + +/* + * @brief Copy data from src to dst + * + * This function will use different copy methods to copy src data to dst, according to + * the different spaces (userspace or kernelspace) of src data. + * + * @param dst The destination buffer. + * @param max The maxsimum number of bytes to copy. + * @param src The source buffer, can be userspace address. + * @param len The number of bytes to copy. + * + * @return zero on success; non-zero on failure. + */ +INT32 LOS_CopyToKernel(VOID *dest, UINT32 max, const VOID *src, UINT32 count); + +/* + * @brief Clear data in buf + * + * This function will clear buf from buf to buf + len. + * + * @param buf The destination buffer, can be userspace address. + * @param len The number of bytes to clear. + * + * @return zero on success; non-zero on failure. + */ +INT32 LOS_UserMemClear(unsigned char *buf, UINT32 len); diff --git a/src/kernel_liteos_a/arch/cpu.mk b/src/kernel_liteos_a/arch/cpu.mk new file mode 100644 index 00000000..856099ef --- /dev/null +++ b/src/kernel_liteos_a/arch/cpu.mk @@ -0,0 +1,32 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +ifeq ($(LOSCFG_ARCH_ARM), y) +-include $(LITEOSTOPDIR)/arch/arm/arm.mk +endif \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/BUILD.gn b/src/kernel_liteos_a/bsd/BUILD.gn new file mode 100644 index 00000000..fac70d00 --- /dev/null +++ b/src/kernel_liteos_a/bsd/BUILD.gn @@ -0,0 +1,86 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = defined(LOSCFG_COMPAT_BSD) +module_name = "libbsd" +kernel_module(module_name) { + sources = [ + "kern/bus_if.c", + "kern/device_if.c", + "kern/kern_condvar.c", + "kern/kern_timeout.c", + "kern/subr_bus.c", + "kern/subr_kobj.c", + ] + + if (defined(LOSCFG_ARCH_ARM_AARCH32)) { + sources += [ + "arm/autoconf.c", + "arm/hw_user_copy.S", + "arm/in_cksum.c", + "arm/in_cksum_arm.S", + "arm/nexus.c", + ] + } + + if (defined(LOSCFG_DRIVERS_RANDOM)) { + sources += [ + "crypto/rijndael/rijndael-alg-fst.c", + "crypto/rijndael/rijndael-api-fst.c", + "crypto/sha2/sha256c.c", + "dev/random/hash.c", + "dev/random/yarrow.c", + "libkern/explicit_bzero.c", + ] + } + + public_configs = [ ":public" ] +} + +group("bsd") { + public_deps = [ ":$module_name" ] + + deps = [ + "compat/linuxkpi", + "dev/usb", + ] +} + +config("public") { + include_dirs = [ + ".", + "kern", + ] + configs = [ + "compat/linuxkpi:public", + "dev/usb:public", + ] +} diff --git a/src/kernel_liteos_a/bsd/Kconfig b/src/kernel_liteos_a/bsd/Kconfig new file mode 100644 index 00000000..c19d8cd8 --- /dev/null +++ b/src/kernel_liteos_a/bsd/Kconfig @@ -0,0 +1,14 @@ +config COMPAT_BSD + bool "Enable FreeBSD" + default y + select COMPAT_LINUXKPI + + help + Answer Y to enable LiteOS support FreeBSD. + +config COMPAT_LINUXKPI + bool "Enable linuxkpi" if COMPAT_BSD + default y + + help + Answer Y to enable LiteOS support compatible layer for linuxkpi. diff --git a/src/kernel_liteos_a/bsd/Makefile b/src/kernel_liteos_a/bsd/Makefile new file mode 100644 index 00000000..353779cd --- /dev/null +++ b/src/kernel_liteos_a/bsd/Makefile @@ -0,0 +1,46 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := $(wildcard kern/*.c) + +LOCAL_SRCS += $(wildcard $(ARCH)/*.c) +LOCAL_SRCS += $(wildcard $(ARCH)/*.S) + +ifeq ($(LOSCFG_DRIVERS_RANDOM), y) +LOCAL_SRCS += $(wildcard crypto/rijndael/*.c) \ + $(wildcard crypto/sha2/*.c) \ + $(wildcard dev/random/*.c) \ + $(wildcard libkern/*.c) +endif + +include $(MODULE) diff --git a/src/kernel_liteos_a/bsd/arm/autoconf.c b/src/kernel_liteos_a/bsd/arm/autoconf.c new file mode 100644 index 00000000..f2ba141c --- /dev/null +++ b/src/kernel_liteos_a/bsd/arm/autoconf.c @@ -0,0 +1 @@ +../../../../third_party/FreeBSD/sys/arm/arm/autoconf.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/arm/hw_user_copy.S b/src/kernel_liteos_a/bsd/arm/hw_user_copy.S new file mode 100644 index 00000000..576e247f --- /dev/null +++ b/src/kernel_liteos_a/bsd/arm/hw_user_copy.S @@ -0,0 +1 @@ +../../../../third_party/FreeBSD/lib/libc/arm/string/hw_user_copy.S \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/arm/in_cksum.c b/src/kernel_liteos_a/bsd/arm/in_cksum.c new file mode 100644 index 00000000..0adb79c6 --- /dev/null +++ b/src/kernel_liteos_a/bsd/arm/in_cksum.c @@ -0,0 +1 @@ +../../../../third_party/FreeBSD/sys/arm/arm/in_cksum.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/arm/in_cksum_arm.S b/src/kernel_liteos_a/bsd/arm/in_cksum_arm.S new file mode 100644 index 00000000..daa2408f --- /dev/null +++ b/src/kernel_liteos_a/bsd/arm/in_cksum_arm.S @@ -0,0 +1 @@ +../../../../third_party/FreeBSD/sys/arm/arm/in_cksum_arm.S \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/arm/include/_bus.h b/src/kernel_liteos_a/bsd/arm/include/_bus.h new file mode 100644 index 00000000..61b5e9b7 --- /dev/null +++ b/src/kernel_liteos_a/bsd/arm/include/_bus.h @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/arm/include/_bus.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/arm/nexus.c b/src/kernel_liteos_a/bsd/arm/nexus.c new file mode 100644 index 00000000..1e37fd01 --- /dev/null +++ b/src/kernel_liteos_a/bsd/arm/nexus.c @@ -0,0 +1 @@ +../../../../third_party/FreeBSD/sys/arm/arm/nexus.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/BUILD.gn b/src/kernel_liteos_a/bsd/compat/linuxkpi/BUILD.gn new file mode 100644 index 00000000..01c73efb --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/BUILD.gn @@ -0,0 +1,57 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = defined(LOSCFG_COMPAT_BSD) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ + "src/adp.c", + "src/linux_completion.c", + "src/linux_interrupt.c", + "src/linux_sched.c", + "src/linux_semaphore.c", + "src/linux_timer.c", + "src/linux_wakelock.c", + "src/linux_workqueue.c", + "src/prctl.c", + "src/tzdst.c", + ] + + if (defined(LOSCFG_HRTIMER_ENABLE)) { + sources += [ "src/linux_hrtimer.c" ] + } + + public_configs = [ ":public" ] +} + +config("public") { + include_dirs = [ "include" ] +} diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/Makefile b/src/kernel_liteos_a/bsd/compat/linuxkpi/Makefile new file mode 100644 index 00000000..d4e304db --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/Makefile @@ -0,0 +1,40 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := $(wildcard src/*.c) + +ifneq ($(LOSCFG_HRTIMER_ENABLE), y) +LOCAL_SRCS := $(filter-out src/linux_hrtimer.c, $(LOCAL_SRCS)) +endif + +include $(MODULE) diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/asm/atomic.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/asm/atomic.h new file mode 100644 index 00000000..4abd5f80 --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/asm/atomic.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/asm/atomic.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/asm/barrier.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/asm/barrier.h new file mode 100644 index 00000000..1ba23c96 --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/asm/barrier.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/asm/barrier.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/asm/io.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/asm/io.h new file mode 100644 index 00000000..131e070f --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/asm/io.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/asm/io.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/asm/page.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/asm/page.h new file mode 100644 index 00000000..a0e95fc8 --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/asm/page.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/asm/page.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/atomic.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/atomic.h new file mode 100644 index 00000000..247db5a7 --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/atomic.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/linux/atomic.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/compat.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/compat.h new file mode 100644 index 00000000..53270094 --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/compat.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/linux/compat.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/compiler.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/compiler.h new file mode 100644 index 00000000..9f438623 --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/compiler.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/linux/compiler.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/completion.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/completion.h new file mode 100644 index 00000000..84ca930f --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/completion.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/linux/completion.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/ctype.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/ctype.h new file mode 100644 index 00000000..0a07c759 --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/ctype.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/linux/ctype.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/delay.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/delay.h new file mode 100644 index 00000000..1dc51ca2 --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/delay.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/linux/delay.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/dma-mapping.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/dma-mapping.h new file mode 100644 index 00000000..67c63612 --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/dma-mapping.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/linux/dma-mapping.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/errno.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/errno.h new file mode 100644 index 00000000..b4779432 --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/errno.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/linux/errno.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/fcntl.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/fcntl.h new file mode 100644 index 00000000..7ec7319c --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/fcntl.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/linux/fcntl.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/fs.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/fs.h new file mode 100644 index 00000000..2b73fb25 --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/fs.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/linux/fs.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/hrtimer.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/hrtimer.h new file mode 100644 index 00000000..3ce6c933 --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/hrtimer.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/linux/hrtimer.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/icmp.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/icmp.h new file mode 100644 index 00000000..368b7911 --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/icmp.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/linux/icmp.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/interrupt.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/interrupt.h new file mode 100644 index 00000000..533736ef --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/interrupt.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/linux/interrupt.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/io.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/io.h new file mode 100644 index 00000000..c64b0af8 --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/io.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/linux/io.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/ioctl.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/ioctl.h new file mode 100644 index 00000000..3fb3dd8c --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/ioctl.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/linux/ioctl.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/jiffies.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/jiffies.h new file mode 100644 index 00000000..6065f203 --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/jiffies.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/linux/jiffies.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/kernel.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/kernel.h new file mode 100644 index 00000000..ae8eaae0 --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/kernel.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/linux/kernel.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/list.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/list.h new file mode 100644 index 00000000..4ac90bf0 --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/list.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/linux/list.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/module.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/module.h new file mode 100644 index 00000000..255944c4 --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/module.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/linux/module.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/moduleparam.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/moduleparam.h new file mode 100644 index 00000000..b64f6707 --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/moduleparam.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/linux/moduleparam.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/pagemap.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/pagemap.h new file mode 100644 index 00000000..4b0d72be --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/pagemap.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/linux/pagemap.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/rbtree.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/rbtree.h new file mode 100644 index 00000000..59762226 --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/rbtree.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/linux/rbtree.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/rtc.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/rtc.h new file mode 100644 index 00000000..8dec352b --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/rtc.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/linux/rtc.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/rwsem.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/rwsem.h new file mode 100644 index 00000000..a0c620ef --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/rwsem.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/linux/rwsem.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/scatterlist.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/scatterlist.h new file mode 100644 index 00000000..e2bad8d4 --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/scatterlist.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/linux/scatterlist.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/sched.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/sched.h new file mode 100644 index 00000000..0b5ccb67 --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/sched.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/linux/sched.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/semaphore.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/semaphore.h new file mode 100644 index 00000000..d870dbcc --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/semaphore.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/linux/semaphore.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/slab.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/slab.h new file mode 100644 index 00000000..9351dc8d --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/slab.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/linux/slab.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/spinlock.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/spinlock.h new file mode 100644 index 00000000..9cf0152a --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/spinlock.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/linux/spinlock.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/stat.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/stat.h new file mode 100644 index 00000000..87229a30 --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/stat.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/linux/stat.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/string.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/string.h new file mode 100644 index 00000000..c48791d6 --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/string.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/linux/string.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/timer.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/timer.h new file mode 100644 index 00000000..7ba43e71 --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/timer.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/linux/timer.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/tree.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/tree.h new file mode 100644 index 00000000..5cc79a5f --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/tree.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/sys/tree.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/types.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/types.h new file mode 100644 index 00000000..8f330774 --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/types.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/linux/types.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/wait.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/wait.h new file mode 100644 index 00000000..e0ce82d7 --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/wait.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/linux/wait.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/wakelock.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/wakelock.h new file mode 100644 index 00000000..12b2192c --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/wakelock.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/linux/wakelock.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/workqueue.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/workqueue.h new file mode 100644 index 00000000..086614c3 --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/workqueue.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/linux/workqueue.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/zutil.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/zutil.h new file mode 100644 index 00000000..f481a37b --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/linux/zutil.h @@ -0,0 +1 @@ +../../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/linux/zutil.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/tzdst.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/tzdst.h new file mode 100644 index 00000000..5b435de2 --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/tzdst.h @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/linux/tzdst.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/include/tzdst_pri.h b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/tzdst_pri.h new file mode 100644 index 00000000..2b1feb81 --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/include/tzdst_pri.h @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/linux/tzdst_pri.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/src/adp.c b/src/kernel_liteos_a/bsd/compat/linuxkpi/src/adp.c new file mode 100644 index 00000000..a5397f02 --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/src/adp.c @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/src/adp.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/src/linux_completion.c b/src/kernel_liteos_a/bsd/compat/linuxkpi/src/linux_completion.c new file mode 100644 index 00000000..a6a575ef --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/src/linux_completion.c @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/src/linux_completion.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/src/linux_hrtimer.c b/src/kernel_liteos_a/bsd/compat/linuxkpi/src/linux_hrtimer.c new file mode 100644 index 00000000..32cf1aa1 --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/src/linux_hrtimer.c @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/src/linux_hrtimer.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/src/linux_interrupt.c b/src/kernel_liteos_a/bsd/compat/linuxkpi/src/linux_interrupt.c new file mode 100644 index 00000000..758b8b6a --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/src/linux_interrupt.c @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/src/linux_interrupt.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/src/linux_sched.c b/src/kernel_liteos_a/bsd/compat/linuxkpi/src/linux_sched.c new file mode 100644 index 00000000..e0cdaf6c --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/src/linux_sched.c @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/src/linux_sched.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/src/linux_semaphore.c b/src/kernel_liteos_a/bsd/compat/linuxkpi/src/linux_semaphore.c new file mode 100644 index 00000000..b9035814 --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/src/linux_semaphore.c @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/src/linux_semaphore.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/src/linux_timer.c b/src/kernel_liteos_a/bsd/compat/linuxkpi/src/linux_timer.c new file mode 100644 index 00000000..c55e2dc1 --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/src/linux_timer.c @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/src/linux_timer.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/src/linux_wakelock.c b/src/kernel_liteos_a/bsd/compat/linuxkpi/src/linux_wakelock.c new file mode 100644 index 00000000..fc48dfca --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/src/linux_wakelock.c @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/src/linux_wakelock.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/src/linux_workqueue.c b/src/kernel_liteos_a/bsd/compat/linuxkpi/src/linux_workqueue.c new file mode 100644 index 00000000..de98e3b9 --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/src/linux_workqueue.c @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/src/linux_workqueue.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/src/prctl.c b/src/kernel_liteos_a/bsd/compat/linuxkpi/src/prctl.c new file mode 100644 index 00000000..526eb743 --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/src/prctl.c @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/src/prctl.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/compat/linuxkpi/src/tzdst.c b/src/kernel_liteos_a/bsd/compat/linuxkpi/src/tzdst.c new file mode 100644 index 00000000..8833fbb4 --- /dev/null +++ b/src/kernel_liteos_a/bsd/compat/linuxkpi/src/tzdst.c @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/src/tzdst.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/crypto/rijndael/rijndael-alg-fst.c b/src/kernel_liteos_a/bsd/crypto/rijndael/rijndael-alg-fst.c new file mode 100644 index 00000000..eb82dbfd --- /dev/null +++ b/src/kernel_liteos_a/bsd/crypto/rijndael/rijndael-alg-fst.c @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/crypto/rijndael/rijndael-alg-fst.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/crypto/rijndael/rijndael-api-fst.c b/src/kernel_liteos_a/bsd/crypto/rijndael/rijndael-api-fst.c new file mode 100644 index 00000000..e9f5f2a9 --- /dev/null +++ b/src/kernel_liteos_a/bsd/crypto/rijndael/rijndael-api-fst.c @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/crypto/rijndael/rijndael-api-fst.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/crypto/rijndael/rijndael-api-fst.h b/src/kernel_liteos_a/bsd/crypto/rijndael/rijndael-api-fst.h new file mode 100644 index 00000000..ec1cf599 --- /dev/null +++ b/src/kernel_liteos_a/bsd/crypto/rijndael/rijndael-api-fst.h @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/crypto/rijndael/rijndael-api-fst.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/crypto/rijndael/rijndael.h b/src/kernel_liteos_a/bsd/crypto/rijndael/rijndael.h new file mode 100644 index 00000000..f9c3474b --- /dev/null +++ b/src/kernel_liteos_a/bsd/crypto/rijndael/rijndael.h @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/crypto/rijndael/rijndael.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/crypto/rijndael/rijndael_local.h b/src/kernel_liteos_a/bsd/crypto/rijndael/rijndael_local.h new file mode 100644 index 00000000..9d8a607b --- /dev/null +++ b/src/kernel_liteos_a/bsd/crypto/rijndael/rijndael_local.h @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/crypto/rijndael/rijndael_local.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/crypto/sha2/sha256.h b/src/kernel_liteos_a/bsd/crypto/sha2/sha256.h new file mode 100644 index 00000000..30c79cf3 --- /dev/null +++ b/src/kernel_liteos_a/bsd/crypto/sha2/sha256.h @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/crypto/sha2/sha256.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/crypto/sha2/sha256c.c b/src/kernel_liteos_a/bsd/crypto/sha2/sha256c.c new file mode 100644 index 00000000..fd0534e4 --- /dev/null +++ b/src/kernel_liteos_a/bsd/crypto/sha2/sha256c.c @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/crypto/sha2/sha256c.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/random/hash.c b/src/kernel_liteos_a/bsd/dev/random/hash.c new file mode 100644 index 00000000..529bd599 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/random/hash.c @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/random/hash.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/random/hash.h b/src/kernel_liteos_a/bsd/dev/random/hash.h new file mode 100644 index 00000000..7a93abec --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/random/hash.h @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/random/hash.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/random/randomdev.h b/src/kernel_liteos_a/bsd/dev/random/randomdev.h new file mode 100644 index 00000000..c4fb7a8d --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/random/randomdev.h @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/random/randomdev.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/random/uint128.h b/src/kernel_liteos_a/bsd/dev/random/uint128.h new file mode 100644 index 00000000..1bb9c89a --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/random/uint128.h @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/random/uint128.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/random/unit_test.h b/src/kernel_liteos_a/bsd/dev/random/unit_test.h new file mode 100644 index 00000000..9bf98b1b --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/random/unit_test.h @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/random/unit_test.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/random/yarrow.c b/src/kernel_liteos_a/bsd/dev/random/yarrow.c new file mode 100644 index 00000000..192b879c --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/random/yarrow.c @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/random/yarrow.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/random/yarrow.h b/src/kernel_liteos_a/bsd/dev/random/yarrow.h new file mode 100644 index 00000000..b2dee7df --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/random/yarrow.h @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/random/yarrow.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/BUILD.gn b/src/kernel_liteos_a/bsd/dev/usb/BUILD.gn new file mode 100644 index 00000000..205a8f51 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/BUILD.gn @@ -0,0 +1,149 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = defined(LOSCFG_DRIVERS_USB) +module_name = "usb_base" +kernel_module(module_name) { + sources = [ + "implementation/bsd_busspace.c", + "implementation/bsd_kernel.c", + "implementation/usb_btree.c", + "implementation/usb_busdma_loader.c", + "implementation/usb_init.c", + "implementation/usb_version.c", + "usb_debug.c", + ] + + if (defined(LOSCFG_DRIVERS_USB)) { + sources += [ + "controller/usb_controller.c", + "quirk/usb_quirk.c", + "usb_dev.c", + "usb_device.c", + "usb_dynamic.c", + "usb_error.c", + "usb_generic.c", + "usb_handle_request.c", + "usb_hub.c", + "usb_if.c", + "usb_lookup.c", + "usb_mbuf.c", + "usb_parse.c", + "usb_process.c", + "usb_request.c", + "usb_transfer.c", + "usb_util.c", + ] + } + + if (defined(LOSCFG_DRIVERS_USB_4G_MODEM)) { + sources += [ "net/if_cdce.c" ] + } + + if (defined(LOSCFG_DRIVERS_USB_ETHERNET)) { + sources += [ + "net/if_axe.c", + "net/if_axge.c", + ] + } + + if (defined(LOSCFG_DRIVERS_USB_RNDIS_HOST)) { + sources += [ "net/if_urndis.c" ] + } + + if (defined(LOSCFG_DRIVERS_USB_4G_MODEM) || + defined(LOSCFG_DRIVERS_USB_ETHERNET) || + defined(LOSCFG_DRIVERS_USB_RNDIS_HOST)) { + sources += [ + "net/usb_eth_drv.c", + "net/usb_ethernet.c", + ] + } + + if (defined(LOSCFG_DRIVERS_USB_4G_MODEM) || + defined(LOSCFG_DRIVERS_USB_SERIAL)) { + sources += [ + "serial/u3g.c", + "serial/usb_serial.c", + ] + } + + if (defined(LOSCFG_DRIVERS_USB_HOST_EHCI)) { + sources += [ + "controller/ehci.c", + "controller/ehci_pci.c", + ] + } + + if (defined(LOSCFG_DRIVERS_USB_HOST_XHCI) || + defined(LOSCFG_DRIVERS_USB_HOST_XHCI_FOR_PORT2)) { + sources += [ + "controller/xhci.c", + "controller/xhci_pci.c", + ] + } + + if (defined(LOSCFG_DRIVERS_USB_WIRELESS)) { + sources += [ "linux_usb.c" ] + } + + if (defined(LOSCFG_DRIVERS_USB_MASS_STORAGE)) { + sources += [ "storage/umass.c" ] + } + + if (defined(LOSCFG_DRIVERS_USB_HID_CLASS) && + defined(LOSCFG_DRIVERS_HDF_INPUT)) { + sources += [ + "input/uhid.c", + "usb_hid.c", + ] + + include_dirs = [ + "//drivers/framework/model/input/driver", + "//drivers/framework/include/core", + "//drivers/framework/core/common/include/host", + "//drivers/framework/utils", + "//drivers/framework/osal", + "//drivers/framework/ability/sbuf/include", + "//drivers/framework/include/osal", + ] + } + + configs += [ "$HDFTOPDIR:hdf_config" ] + + public_configs = [ ":public" ] +} + +config("public") { + defines = [ "USB_DEBUG_VAR=5" ] + include_dirs = [ "." ] + include_dirs += [ "$LITEOSTHIRDPARTY/FreeBSD/sys/dev/evdev" ] +} diff --git a/src/kernel_liteos_a/bsd/dev/usb/Kconfig b/src/kernel_liteos_a/bsd/dev/usb/Kconfig new file mode 100644 index 00000000..6d365d5e --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/Kconfig @@ -0,0 +1,102 @@ +config DRIVERS_USB + bool "Enable USB" + default y + depends on DRIVERS && COMPAT_BSD + help + Answer Y to enable LiteOS support usb. + +config DRIVERS_USB_HOST_DRIVER + bool "Enable USB HCD" + default y + depends on DRIVERS_USB && DRIVERS + help + Answer Y to enable LiteOS to support usb host controller driver. + +choice + depends on DRIVERS_USB_HOST_DRIVER + prompt "USB HCD" + default DRIVERS_USB_HOST_EHCI + help + Enable EHCI for USB 2.0. + Enable XHCI for USB 3.0 + +config DRIVERS_USB_HOST_EHCI + bool "Enable EHCI HCD (USB 2.0)" + depends on DRIVERS_USB + +config DRIVERS_USB_HOST_XHCI + bool "Enable XHCI HCD (USB 3.0)" + depends on DRIVERS_USB + +endchoice + +choice + depends on PLATFORM_HI3556AV100 && DRIVERS_USB_HOST_XHCI + prompt "" + default DRIVERS_USB3_HOST_FOR_PORT1 + help + This selects the usb3.0 port or usb2.0 port. + +config DRIVERS_USB3_HOST_FOR_PORT1 + bool "Enable USB3.0 Host Controller For USB3.0 Port1" + +config DRIVERS_USB3_HOST_FOR_PORT2 + bool "Enable USB3.0 Host Controller For USB2.0 Port2" + +endchoice + +config DRIVERS_USB_DEVICE_CLASS_DRIVERS + bool "Enable USB Device Class Drivers" + default y + depends on DRIVERS_USB && DRIVERS && DRIVERS_USB_HOST_DRIVER + help + Answer Y to enable LiteOS to support usb device class drivers. + +menu "USB Device Class Drivers" + depends on DRIVERS_USB_DEVICE_CLASS_DRIVERS +config DRIVERS_USB_MASS_STORAGE + bool "Enable USB Mass Storage Support" + default y + depends on DRIVERS_USB_DEVICE_CLASS_DRIVERS && FS_VFS + help + Say Y here if you want to connect USB mass storage devices to your system's USB port. + +config DRIVERS_USB_RNDIS_HOST + bool "Enable USB Rndis Host Support" + default y + depends on DRIVERS_USB_DEVICE_CLASS_DRIVERS && NET_LWIP_SACK + help + Say Y here if you want to connect USB Rndis Host devices to your system's USB port. + +config DRIVERS_USB_4G_MODEM + bool "Enable USB 4G Modem Support" + default y + depends on DRIVERS_USB_DEVICE_CLASS_DRIVERS && NET_LWIP_SACK + help + Say Y here if you want to connect USB 4G devices to your system's USB port. + +config DRIVERS_USB_SERIAL + bool "Enable USB Serial Converter Support" + default y + depends on DRIVERS_USB_DEVICE_CLASS_DRIVERS + help + Say Y here if you want to connect USB serial devices to your system's USB port. + +config DRIVERS_USB_ETHERNET + bool "Enable USB Ethernet Support" + depends on NET_LWIP_SACK && DRIVERS_USB_DEVICE_CLASS_DRIVERS + help + Say Y here if you want to connect USB ethernet devices to your system's USB port. + +config DRIVERS_USB_WIRELESS + bool "Enable USB Wireless Device Support" + depends on NET_LWIP_SACK && DRIVERS_USB_DEVICE_CLASS_DRIVERS + help + Say Y here if you want to connect usb-wifi devices to your system's USB port. +config DRIVERS_USB_HID_CLASS + bool "Enable USB HID Device Support" + depends on DRIVERS_USB_DEVICE_CLASS_DRIVERS && FS_VFS + help + Say Y here if you want to connect hid devices to your system's USB port. + +endmenu diff --git a/src/kernel_liteos_a/bsd/dev/usb/Makefile b/src/kernel_liteos_a/bsd/dev/usb/Makefile new file mode 100644 index 00000000..2d465482 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/Makefile @@ -0,0 +1,138 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk +include $(LITEOSTOPDIR)/../../drivers/hdf_core/adapter/khdf/liteos/lite.mk + +MODULE_NAME := usb_base + +CONTROLLER_HOST_SRC = controller +CORE_SRC = . +IMPLEMENTATION_SRC = implementation +Net_SRC = net +QUIRK_SRC = quirk +SERIAL_SRC = serial +STORAGE_SRC = storage +INPUT_SRC = input +LOCAL_SRCS := $(CORE_SRC)/usb_debug.c \ + $(IMPLEMENTATION_SRC)/bsd_busspace.c \ + $(IMPLEMENTATION_SRC)/usb_busdma_loader.c \ + $(IMPLEMENTATION_SRC)/bsd_kernel.c \ + $(IMPLEMENTATION_SRC)/usb_init.c \ + $(IMPLEMENTATION_SRC)/usb_version.c \ + $(IMPLEMENTATION_SRC)/usb_btree.c + +ifeq ($(LOSCFG_DRIVERS_USB), y) +LOCAL_SRCS += $(CORE_SRC)/usb_dynamic.c \ + $(CORE_SRC)/usb_parse.c \ + $(CORE_SRC)/usb_error.c \ + $(CORE_SRC)/usb_handle_request.c \ + $(CORE_SRC)/usb_util.c \ + $(CORE_SRC)/usb_lookup.c \ + $(CONTROLLER_HOST_SRC)/usb_controller.c \ + $(QUIRK_SRC)/usb_quirk.c \ + $(CORE_SRC)/usb_device.c \ + $(CORE_SRC)/usb_process.c \ + $(CORE_SRC)/usb_hub.c \ + $(CORE_SRC)/usb_request.c \ + $(CORE_SRC)/usb_transfer.c \ + $(CORE_SRC)/usb_dev.c \ + $(CORE_SRC)/usb_mbuf.c \ + $(CORE_SRC)/usb_generic.c \ + $(CORE_SRC)/usb_if.c +endif + +ifeq ($(LOSCFG_DRIVERS_USB_4G_MODEM), y) +LOCAL_SRCS += $(Net_SRC)/if_cdce.c +endif + +ifeq ($(LOSCFG_DRIVERS_USB_ETHERNET), y) +LOCAL_SRCS += $(Net_SRC)/if_axe.c \ + $(Net_SRC)/if_axge.c +endif + +ifeq ($(LOSCFG_DRIVERS_USB_RNDIS_HOST), y) +LOCAL_SRCS += $(Net_SRC)/if_urndis.c +endif + +ifeq ($(LOSCFG_DRIVERS_USB_4G_MODEM), y) +LOCAL_SRCS += $(Net_SRC)/usb_eth_drv.c \ + $(Net_SRC)/usb_ethernet.c +else ifeq ($(LOSCFG_DRIVERS_USB_ETHERNET), y) +LOCAL_SRCS += $(Net_SRC)/usb_eth_drv.c \ + $(Net_SRC)/usb_ethernet.c +else ifeq ($(LOSCFG_DRIVERS_USB_RNDIS_HOST), y) +LOCAL_SRCS += $(Net_SRC)/usb_eth_drv.c\ + $(Net_SRC)/usb_ethernet.c +endif + +ifeq ($(LOSCFG_DRIVERS_USB_4G_MODEM), y) +LOCAL_SRCS += $(SERIAL_SRC)/usb_serial.c \ + $(SERIAL_SRC)/u3g.c +else ifeq ($(LOSCFG_DRIVERS_USB_SERIAL), y) +LOCAL_SRCS += $(SERIAL_SRC)/usb_serial.c \ + $(SERIAL_SRC)/u3g.c +endif + +ifeq ($(LOSCFG_DRIVERS_USB_HOST_EHCI), y) +LOCAL_SRCS += $(CONTROLLER_HOST_SRC)/ehci_pci.c \ + $(CONTROLLER_HOST_SRC)/ehci.c +endif + +ifeq ($(LOSCFG_DRIVERS_USB_HOST_XHCI), y) +LOCAL_SRCS += $(CONTROLLER_HOST_SRC)/xhci.c \ + $(CONTROLLER_HOST_SRC)/xhci_pci.c +else ifeq ($(LOSCFG_DRIVERS_USB_HOST_XHCI_FOR_PORT2), y) +LOCAL_SRCS += $(CONTROLLER_HOST_SRC)/xhci.c \ + $(CONTROLLER_HOST_SRC)/xhci_pci.c +endif + +ifeq ($(LOSCFG_DRIVERS_USB_WIRELESS), y) +LOCAL_SRCS += $(CORE_SRC)/linux_usb.c +endif + +ifeq ($(LOSCFG_DRIVERS_USB_MASS_STORAGE), y) +LOCAL_SRCS += $(STORAGE_SRC)/umass.c +endif + +ifeq ($(LOSCFG_DRIVERS_USB_HID_CLASS)_$(LOSCFG_DRIVERS_HDF_INPUT), y_y) +LOCAL_FLAGS += -I$(LITEOSTOPDIR)/../../drivers/hdf_core/framework/model/input/driver \ + -I$(LITEOSTOPDIR)/../../drivers/hdf_core/framework/include/core \ + -I$(LITEOSTOPDIR)/../../drivers/hdf_core/framework/core/common/include/host \ + -I$(LITEOSTOPDIR)/../../drivers/hdf_core/framework/utils \ + -I$(LITEOSTOPDIR)/../../drivers/hdf_core/framework/osal \ + -I$(LITEOSTOPDIR)/../../drivers/hdf_core/framework/ability/sbuf/include \ + -I$(LITEOSTOPDIR)/../../drivers/hdf_core/framework/include/osal \ + -I$(LITEOSTOPDIR)/../../third_party/FreeBSD/sys/dev/evdev + +LOCAL_SRCS += $(INPUT_SRC)/uhid.c \ + $(CORE_SRC)/usb_hid.c +endif + +include $(HDF_DRIVER) diff --git a/src/kernel_liteos_a/bsd/dev/usb/controller/ehci.c b/src/kernel_liteos_a/bsd/dev/usb/controller/ehci.c new file mode 100644 index 00000000..580e5096 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/controller/ehci.c @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/controller/ehci.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/controller/ehci.h b/src/kernel_liteos_a/bsd/dev/usb/controller/ehci.h new file mode 100644 index 00000000..bdbe96c2 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/controller/ehci.h @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/controller/ehci.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/controller/ehci_pci.c b/src/kernel_liteos_a/bsd/dev/usb/controller/ehci_pci.c new file mode 100644 index 00000000..468a4591 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/controller/ehci_pci.c @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/controller/ehci_pci.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/controller/ehcireg.h b/src/kernel_liteos_a/bsd/dev/usb/controller/ehcireg.h new file mode 100644 index 00000000..438e0c5b --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/controller/ehcireg.h @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/controller/ehcireg.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/controller/usb_controller.c b/src/kernel_liteos_a/bsd/dev/usb/controller/usb_controller.c new file mode 100644 index 00000000..603ad2dc --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/controller/usb_controller.c @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/controller/usb_controller.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/controller/xhci.c b/src/kernel_liteos_a/bsd/dev/usb/controller/xhci.c new file mode 100644 index 00000000..3d3d07d0 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/controller/xhci.c @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/controller/xhci.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/controller/xhci.h b/src/kernel_liteos_a/bsd/dev/usb/controller/xhci.h new file mode 100644 index 00000000..cde351d6 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/controller/xhci.h @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/controller/xhci.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/controller/xhci_pci.c b/src/kernel_liteos_a/bsd/dev/usb/controller/xhci_pci.c new file mode 100644 index 00000000..a1671800 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/controller/xhci_pci.c @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/controller/xhci_pci.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/controller/xhcireg.h b/src/kernel_liteos_a/bsd/dev/usb/controller/xhcireg.h new file mode 100644 index 00000000..ea9f0dc1 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/controller/xhcireg.h @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/controller/xhcireg.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/implementation/_macro_ref.h b/src/kernel_liteos_a/bsd/dev/usb/implementation/_macro_ref.h new file mode 100644 index 00000000..0bb8b8ad --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/implementation/_macro_ref.h @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/implementation/_macro_ref.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/implementation/_thread_ref.h b/src/kernel_liteos_a/bsd/dev/usb/implementation/_thread_ref.h new file mode 100644 index 00000000..4abbfd4f --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/implementation/_thread_ref.h @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/implementation/_thread_ref.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/implementation/_types_ref.h b/src/kernel_liteos_a/bsd/dev/usb/implementation/_types_ref.h new file mode 100644 index 00000000..200e9c7e --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/implementation/_types_ref.h @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/implementation/_types_ref.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/implementation/bsd_busspace.c b/src/kernel_liteos_a/bsd/dev/usb/implementation/bsd_busspace.c new file mode 100644 index 00000000..53d8bbf7 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/implementation/bsd_busspace.c @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/stand/kshim/bsd_busspace.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/implementation/bsd_kernel.c b/src/kernel_liteos_a/bsd/dev/usb/implementation/bsd_kernel.c new file mode 100644 index 00000000..32d71825 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/implementation/bsd_kernel.c @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/stand/kshim/bsd_kernel.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/implementation/bsd_kernel.h b/src/kernel_liteos_a/bsd/dev/usb/implementation/bsd_kernel.h new file mode 100644 index 00000000..3b91da37 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/implementation/bsd_kernel.h @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/stand/kshim/bsd_kernel.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/implementation/freebsd_sys.h b/src/kernel_liteos_a/bsd/dev/usb/implementation/freebsd_sys.h new file mode 100644 index 00000000..e35723ee --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/implementation/freebsd_sys.h @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/implementation/freebsd_sys.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/implementation/freebsd_usb.h b/src/kernel_liteos_a/bsd/dev/usb/implementation/freebsd_usb.h new file mode 100644 index 00000000..de6fe4d2 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/implementation/freebsd_usb.h @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/implementation/freebsd_usb.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/implementation/global_implementation.h b/src/kernel_liteos_a/bsd/dev/usb/implementation/global_implementation.h new file mode 100644 index 00000000..2deea9d9 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/implementation/global_implementation.h @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/implementation/global_implementation.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/implementation/usb_api_pri.h b/src/kernel_liteos_a/bsd/dev/usb/implementation/usb_api_pri.h new file mode 100644 index 00000000..41f4e850 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/implementation/usb_api_pri.h @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/implementation/usb_api_pri.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/implementation/usb_btree.c b/src/kernel_liteos_a/bsd/dev/usb/implementation/usb_btree.c new file mode 100644 index 00000000..8ea1fd06 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/implementation/usb_btree.c @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/implementation/usb_btree.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/implementation/usb_btree.h b/src/kernel_liteos_a/bsd/dev/usb/implementation/usb_btree.h new file mode 100644 index 00000000..6daf0d0b --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/implementation/usb_btree.h @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/implementation/usb_btree.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/implementation/usb_busdma_loader.c b/src/kernel_liteos_a/bsd/dev/usb/implementation/usb_busdma_loader.c new file mode 100644 index 00000000..25fda953 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/implementation/usb_busdma_loader.c @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/stand/usb/usb_busdma_loader.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/implementation/usb_init.c b/src/kernel_liteos_a/bsd/dev/usb/implementation/usb_init.c new file mode 100644 index 00000000..ff702025 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/implementation/usb_init.c @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/implementation/usb_init.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/implementation/usb_init.h b/src/kernel_liteos_a/bsd/dev/usb/implementation/usb_init.h new file mode 100644 index 00000000..2294e821 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/implementation/usb_init.h @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/implementation/usb_init.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/implementation/usb_version.c b/src/kernel_liteos_a/bsd/dev/usb/implementation/usb_version.c new file mode 100644 index 00000000..98bbe214 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/implementation/usb_version.c @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/implementation/usb_version.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/implementation/usbdevs.h b/src/kernel_liteos_a/bsd/dev/usb/implementation/usbdevs.h new file mode 100644 index 00000000..7268cbea --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/implementation/usbdevs.h @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/implementation/usbdevs.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/input/uhid.c b/src/kernel_liteos_a/bsd/dev/usb/input/uhid.c new file mode 100644 index 00000000..3b7815ec --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/input/uhid.c @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/input/uhid.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/input/usb_rdesc.h b/src/kernel_liteos_a/bsd/dev/usb/input/usb_rdesc.h new file mode 100644 index 00000000..ead4cbdc --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/input/usb_rdesc.h @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/input/usb_rdesc.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/linux_usb.c b/src/kernel_liteos_a/bsd/dev/usb/linux_usb.c new file mode 100644 index 00000000..02829ea5 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/linux_usb.c @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/src/linux_usb.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/linux_usb.h b/src/kernel_liteos_a/bsd/dev/usb/linux_usb.h new file mode 100644 index 00000000..09a40781 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/linux_usb.h @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/compat/linuxkpi/common/include/linux/usb.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/net/if_axe.c b/src/kernel_liteos_a/bsd/dev/usb/net/if_axe.c new file mode 100644 index 00000000..5e0cd316 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/net/if_axe.c @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/net/if_axe.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/net/if_axereg.h b/src/kernel_liteos_a/bsd/dev/usb/net/if_axereg.h new file mode 100644 index 00000000..e5360198 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/net/if_axereg.h @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/net/if_axereg.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/net/if_axge.c b/src/kernel_liteos_a/bsd/dev/usb/net/if_axge.c new file mode 100644 index 00000000..5b7707c1 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/net/if_axge.c @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/net/if_axge.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/net/if_axgereg.h b/src/kernel_liteos_a/bsd/dev/usb/net/if_axgereg.h new file mode 100644 index 00000000..92ddbbc0 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/net/if_axgereg.h @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/net/if_axgereg.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/net/if_cdce.c b/src/kernel_liteos_a/bsd/dev/usb/net/if_cdce.c new file mode 100644 index 00000000..ddce6582 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/net/if_cdce.c @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/net/if_cdce.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/net/if_cdcereg.h b/src/kernel_liteos_a/bsd/dev/usb/net/if_cdcereg.h new file mode 100644 index 00000000..8c49aa92 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/net/if_cdcereg.h @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/net/if_cdcereg.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/net/if_urndis.c b/src/kernel_liteos_a/bsd/dev/usb/net/if_urndis.c new file mode 100644 index 00000000..c8e3aa86 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/net/if_urndis.c @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/net/if_urndis.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/net/if_urndisreg.h b/src/kernel_liteos_a/bsd/dev/usb/net/if_urndisreg.h new file mode 100644 index 00000000..2c301bd0 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/net/if_urndisreg.h @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/net/if_urndisreg.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/net/mii.h b/src/kernel_liteos_a/bsd/dev/usb/net/mii.h new file mode 100644 index 00000000..31752ff1 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/net/mii.h @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/mii/mii.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/net/usb_eth_drv.c b/src/kernel_liteos_a/bsd/dev/usb/net/usb_eth_drv.c new file mode 100644 index 00000000..9322c742 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/net/usb_eth_drv.c @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/net/usb_eth_drv.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/net/usb_eth_drv.h b/src/kernel_liteos_a/bsd/dev/usb/net/usb_eth_drv.h new file mode 100644 index 00000000..22d05e55 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/net/usb_eth_drv.h @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/net/usb_eth_drv.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/net/usb_ethernet.c b/src/kernel_liteos_a/bsd/dev/usb/net/usb_ethernet.c new file mode 100644 index 00000000..f09d6597 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/net/usb_ethernet.c @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/net/usb_ethernet.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/net/usb_ethernet.h b/src/kernel_liteos_a/bsd/dev/usb/net/usb_ethernet.h new file mode 100644 index 00000000..81a3f57c --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/net/usb_ethernet.h @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/net/usb_ethernet.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/quirk/usb_quirk.c b/src/kernel_liteos_a/bsd/dev/usb/quirk/usb_quirk.c new file mode 100644 index 00000000..f4aea237 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/quirk/usb_quirk.c @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/quirk/usb_quirk.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/quirk/usb_quirk.h b/src/kernel_liteos_a/bsd/dev/usb/quirk/usb_quirk.h new file mode 100644 index 00000000..4ed3ea90 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/quirk/usb_quirk.h @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/quirk/usb_quirk.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/serial.h b/src/kernel_liteos_a/bsd/dev/usb/serial.h new file mode 100644 index 00000000..9270f051 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/serial.h @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/sys/serial.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/serial/u3g.c b/src/kernel_liteos_a/bsd/dev/usb/serial/u3g.c new file mode 100644 index 00000000..4294b9df --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/serial/u3g.c @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/serial/u3g.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/serial/usb_serial.c b/src/kernel_liteos_a/bsd/dev/usb/serial/usb_serial.c new file mode 100644 index 00000000..5f346935 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/serial/usb_serial.c @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/serial/usb_serial.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/serial/usb_serial.h b/src/kernel_liteos_a/bsd/dev/usb/serial/usb_serial.h new file mode 100644 index 00000000..0a325644 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/serial/usb_serial.h @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/serial/usb_serial.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/storage/scsi.h b/src/kernel_liteos_a/bsd/dev/usb/storage/scsi.h new file mode 100644 index 00000000..2a04e33c --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/storage/scsi.h @@ -0,0 +1 @@ +../../../../../../third_party/NuttX/include/nuttx/scsi.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/storage/scsi_all.h b/src/kernel_liteos_a/bsd/dev/usb/storage/scsi_all.h new file mode 100644 index 00000000..fc25d9d4 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/storage/scsi_all.h @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/cam/scsi/scsi_all.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/storage/umass.c b/src/kernel_liteos_a/bsd/dev/usb/storage/umass.c new file mode 100644 index 00000000..4a961a0d --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/storage/umass.c @@ -0,0 +1 @@ +../../../../../../third_party/FreeBSD/sys/dev/usb/storage/umass.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usb.h b/src/kernel_liteos_a/bsd/dev/usb/usb.h new file mode 100644 index 00000000..98080d6f --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usb.h @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usb.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usb_bus.h b/src/kernel_liteos_a/bsd/dev/usb/usb_bus.h new file mode 100644 index 00000000..9570cf7b --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usb_bus.h @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usb_bus.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usb_busdma.h b/src/kernel_liteos_a/bsd/dev/usb/usb_busdma.h new file mode 100644 index 00000000..79da69fa --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usb_busdma.h @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usb_busdma.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usb_cdc.h b/src/kernel_liteos_a/bsd/dev/usb/usb_cdc.h new file mode 100644 index 00000000..ba1456f7 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usb_cdc.h @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usb_cdc.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usb_controller.h b/src/kernel_liteos_a/bsd/dev/usb/usb_controller.h new file mode 100644 index 00000000..7abe004f --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usb_controller.h @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usb_controller.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usb_core.c b/src/kernel_liteos_a/bsd/dev/usb/usb_core.c new file mode 100644 index 00000000..d45c5007 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usb_core.c @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usb_core.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usb_core.h b/src/kernel_liteos_a/bsd/dev/usb/usb_core.h new file mode 100644 index 00000000..51169e12 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usb_core.h @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usb_core.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usb_debug.c b/src/kernel_liteos_a/bsd/dev/usb/usb_debug.c new file mode 100644 index 00000000..e715de30 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usb_debug.c @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usb_debug.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usb_debug.h b/src/kernel_liteos_a/bsd/dev/usb/usb_debug.h new file mode 100644 index 00000000..a8afa3ec --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usb_debug.h @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usb_debug.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usb_dev.c b/src/kernel_liteos_a/bsd/dev/usb/usb_dev.c new file mode 100644 index 00000000..87796e1b --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usb_dev.c @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usb_dev.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usb_dev.h b/src/kernel_liteos_a/bsd/dev/usb/usb_dev.h new file mode 100644 index 00000000..6ef815a9 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usb_dev.h @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usb_dev.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usb_device.c b/src/kernel_liteos_a/bsd/dev/usb/usb_device.c new file mode 100644 index 00000000..fb9877ec --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usb_device.c @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usb_device.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usb_device.h b/src/kernel_liteos_a/bsd/dev/usb/usb_device.h new file mode 100644 index 00000000..cc4dc64b --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usb_device.h @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usb_device.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usb_dynamic.c b/src/kernel_liteos_a/bsd/dev/usb/usb_dynamic.c new file mode 100644 index 00000000..c574c631 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usb_dynamic.c @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usb_dynamic.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usb_dynamic.h b/src/kernel_liteos_a/bsd/dev/usb/usb_dynamic.h new file mode 100644 index 00000000..61873333 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usb_dynamic.h @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usb_dynamic.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usb_endian.h b/src/kernel_liteos_a/bsd/dev/usb/usb_endian.h new file mode 100644 index 00000000..49970156 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usb_endian.h @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usb_endian.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usb_error.c b/src/kernel_liteos_a/bsd/dev/usb/usb_error.c new file mode 100644 index 00000000..4d5e70df --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usb_error.c @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usb_error.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usb_freebsd_loader.h b/src/kernel_liteos_a/bsd/dev/usb/usb_freebsd_loader.h new file mode 100644 index 00000000..5e7aabd7 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usb_freebsd_loader.h @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usb_freebsd_loader.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usb_generic.c b/src/kernel_liteos_a/bsd/dev/usb/usb_generic.c new file mode 100644 index 00000000..fb65b651 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usb_generic.c @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usb_generic.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usb_generic.h b/src/kernel_liteos_a/bsd/dev/usb/usb_generic.h new file mode 100644 index 00000000..8befb6c5 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usb_generic.h @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usb_generic.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usb_handle_request.c b/src/kernel_liteos_a/bsd/dev/usb/usb_handle_request.c new file mode 100644 index 00000000..3fd0764c --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usb_handle_request.c @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usb_handle_request.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usb_hid.c b/src/kernel_liteos_a/bsd/dev/usb/usb_hid.c new file mode 100644 index 00000000..55b33ac4 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usb_hid.c @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usb_hid.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usb_hub.c b/src/kernel_liteos_a/bsd/dev/usb/usb_hub.c new file mode 100644 index 00000000..2f4c414e --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usb_hub.c @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usb_hub.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usb_hub.h b/src/kernel_liteos_a/bsd/dev/usb/usb_hub.h new file mode 100644 index 00000000..3921270e --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usb_hub.h @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usb_hub.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usb_if.c b/src/kernel_liteos_a/bsd/dev/usb/usb_if.c new file mode 100644 index 00000000..c3153d57 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usb_if.c @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usb_if.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usb_if.h b/src/kernel_liteos_a/bsd/dev/usb/usb_if.h new file mode 100644 index 00000000..36f651f7 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usb_if.h @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usb_if.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usb_ioctl.h b/src/kernel_liteos_a/bsd/dev/usb/usb_ioctl.h new file mode 100644 index 00000000..efc78e39 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usb_ioctl.h @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usb_ioctl.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usb_lookup.c b/src/kernel_liteos_a/bsd/dev/usb/usb_lookup.c new file mode 100644 index 00000000..b2250f89 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usb_lookup.c @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usb_lookup.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usb_mbuf.c b/src/kernel_liteos_a/bsd/dev/usb/usb_mbuf.c new file mode 100644 index 00000000..4b6732e8 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usb_mbuf.c @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usb_mbuf.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usb_mbuf.h b/src/kernel_liteos_a/bsd/dev/usb/usb_mbuf.h new file mode 100644 index 00000000..6e4b02e1 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usb_mbuf.h @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usb_mbuf.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usb_parse.c b/src/kernel_liteos_a/bsd/dev/usb/usb_parse.c new file mode 100644 index 00000000..be492026 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usb_parse.c @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usb_parse.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usb_process.c b/src/kernel_liteos_a/bsd/dev/usb/usb_process.c new file mode 100644 index 00000000..9c81bf2c --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usb_process.c @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usb_process.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usb_process.h b/src/kernel_liteos_a/bsd/dev/usb/usb_process.h new file mode 100644 index 00000000..c01ef856 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usb_process.h @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usb_process.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usb_request.c b/src/kernel_liteos_a/bsd/dev/usb/usb_request.c new file mode 100644 index 00000000..9fc07786 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usb_request.c @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usb_request.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usb_request.h b/src/kernel_liteos_a/bsd/dev/usb/usb_request.h new file mode 100644 index 00000000..6faf149c --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usb_request.h @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usb_request.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usb_transfer.c b/src/kernel_liteos_a/bsd/dev/usb/usb_transfer.c new file mode 100644 index 00000000..14da3d87 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usb_transfer.c @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usb_transfer.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usb_transfer.h b/src/kernel_liteos_a/bsd/dev/usb/usb_transfer.h new file mode 100644 index 00000000..8520c64f --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usb_transfer.h @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usb_transfer.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usb_util.c b/src/kernel_liteos_a/bsd/dev/usb/usb_util.c new file mode 100644 index 00000000..d4d290da --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usb_util.c @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usb_util.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usb_util.h b/src/kernel_liteos_a/bsd/dev/usb/usb_util.h new file mode 100644 index 00000000..0470a037 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usb_util.h @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usb_util.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usbdi.h b/src/kernel_liteos_a/bsd/dev/usb/usbdi.h new file mode 100644 index 00000000..3fa51ad3 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usbdi.h @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usbdi.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usbdi_util.h b/src/kernel_liteos_a/bsd/dev/usb/usbdi_util.h new file mode 100644 index 00000000..e726cc24 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usbdi_util.h @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usbdi_util.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/dev/usb/usbhid.h b/src/kernel_liteos_a/bsd/dev/usb/usbhid.h new file mode 100644 index 00000000..410e9d76 --- /dev/null +++ b/src/kernel_liteos_a/bsd/dev/usb/usbhid.h @@ -0,0 +1 @@ +../../../../../third_party/FreeBSD/sys/dev/usb/usbhid.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/kern/bus_if.c b/src/kernel_liteos_a/bsd/kern/bus_if.c new file mode 100644 index 00000000..1561860f --- /dev/null +++ b/src/kernel_liteos_a/bsd/kern/bus_if.c @@ -0,0 +1 @@ +../../../../third_party/FreeBSD/sys/kern/bus_if.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/kern/bus_if.h b/src/kernel_liteos_a/bsd/kern/bus_if.h new file mode 100644 index 00000000..d8e93ac9 --- /dev/null +++ b/src/kernel_liteos_a/bsd/kern/bus_if.h @@ -0,0 +1 @@ +../../../../third_party/FreeBSD/sys/kern/bus_if.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/kern/device_if.c b/src/kernel_liteos_a/bsd/kern/device_if.c new file mode 100644 index 00000000..a018079c --- /dev/null +++ b/src/kernel_liteos_a/bsd/kern/device_if.c @@ -0,0 +1 @@ +../../../../third_party/FreeBSD/sys/kern/device_if.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/kern/device_if.h b/src/kernel_liteos_a/bsd/kern/device_if.h new file mode 100644 index 00000000..47739543 --- /dev/null +++ b/src/kernel_liteos_a/bsd/kern/device_if.h @@ -0,0 +1 @@ +../../../../third_party/FreeBSD/sys/kern/device_if.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/kern/kern_condvar.c b/src/kernel_liteos_a/bsd/kern/kern_condvar.c new file mode 100644 index 00000000..7352eb86 --- /dev/null +++ b/src/kernel_liteos_a/bsd/kern/kern_condvar.c @@ -0,0 +1 @@ +../../../../third_party/FreeBSD/sys/kern/kern_condvar.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/kern/kern_timeout.c b/src/kernel_liteos_a/bsd/kern/kern_timeout.c new file mode 100644 index 00000000..24d34da2 --- /dev/null +++ b/src/kernel_liteos_a/bsd/kern/kern_timeout.c @@ -0,0 +1 @@ +../../../../third_party/FreeBSD/sys/kern/kern_timeout.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/kern/subr_bus.c b/src/kernel_liteos_a/bsd/kern/subr_bus.c new file mode 100644 index 00000000..c003b0c8 --- /dev/null +++ b/src/kernel_liteos_a/bsd/kern/subr_bus.c @@ -0,0 +1 @@ +../../../../third_party/FreeBSD/sys/kern/subr_bus.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/kern/subr_kobj.c b/src/kernel_liteos_a/bsd/kern/subr_kobj.c new file mode 100644 index 00000000..f339bb21 --- /dev/null +++ b/src/kernel_liteos_a/bsd/kern/subr_kobj.c @@ -0,0 +1 @@ +../../../../third_party/FreeBSD/sys/kern/subr_kobj.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/libkern/explicit_bzero.c b/src/kernel_liteos_a/bsd/libkern/explicit_bzero.c new file mode 100644 index 00000000..b4d4d101 --- /dev/null +++ b/src/kernel_liteos_a/bsd/libkern/explicit_bzero.c @@ -0,0 +1 @@ +../../../../third_party/FreeBSD/sys/libkern/explicit_bzero.c \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/net/ppp_defs.h b/src/kernel_liteos_a/bsd/net/ppp_defs.h new file mode 100644 index 00000000..6ac30526 --- /dev/null +++ b/src/kernel_liteos_a/bsd/net/ppp_defs.h @@ -0,0 +1 @@ +../../../../third_party/FreeBSD/sys/net/ppp_defs.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/sys/_callout.h b/src/kernel_liteos_a/bsd/sys/_callout.h new file mode 100644 index 00000000..513f2665 --- /dev/null +++ b/src/kernel_liteos_a/bsd/sys/_callout.h @@ -0,0 +1 @@ +../../../../third_party/FreeBSD/sys/sys/_callout.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/sys/bus.h b/src/kernel_liteos_a/bsd/sys/bus.h new file mode 100644 index 00000000..51b415e8 --- /dev/null +++ b/src/kernel_liteos_a/bsd/sys/bus.h @@ -0,0 +1 @@ +../../../../third_party/FreeBSD/sys/sys/bus.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/sys/callout.h b/src/kernel_liteos_a/bsd/sys/callout.h new file mode 100644 index 00000000..1c5a8ba9 --- /dev/null +++ b/src/kernel_liteos_a/bsd/sys/callout.h @@ -0,0 +1 @@ +../../../../third_party/FreeBSD/sys/sys/callout.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/sys/cdefs.h b/src/kernel_liteos_a/bsd/sys/cdefs.h new file mode 100644 index 00000000..ca38dcb1 --- /dev/null +++ b/src/kernel_liteos_a/bsd/sys/cdefs.h @@ -0,0 +1 @@ +../../../../third_party/FreeBSD/sys/sys/cdefs.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/sys/condvar.h b/src/kernel_liteos_a/bsd/sys/condvar.h new file mode 100644 index 00000000..5948c1a2 --- /dev/null +++ b/src/kernel_liteos_a/bsd/sys/condvar.h @@ -0,0 +1 @@ +../../../../third_party/FreeBSD/sys/sys/condvar.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/sys/kernel.h b/src/kernel_liteos_a/bsd/sys/kernel.h new file mode 100644 index 00000000..a22030ec --- /dev/null +++ b/src/kernel_liteos_a/bsd/sys/kernel.h @@ -0,0 +1 @@ +../../../../third_party/FreeBSD/sys/sys/kernel.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/sys/kobj.h b/src/kernel_liteos_a/bsd/sys/kobj.h new file mode 100644 index 00000000..465e8619 --- /dev/null +++ b/src/kernel_liteos_a/bsd/sys/kobj.h @@ -0,0 +1 @@ +../../../../third_party/FreeBSD/sys/sys/kobj.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/sys/linker_set.h b/src/kernel_liteos_a/bsd/sys/linker_set.h new file mode 100644 index 00000000..4b7e6772 --- /dev/null +++ b/src/kernel_liteos_a/bsd/sys/linker_set.h @@ -0,0 +1 @@ +../../../../third_party/FreeBSD/sys/sys/linker_set.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/sys/malloc.h b/src/kernel_liteos_a/bsd/sys/malloc.h new file mode 100644 index 00000000..73fd4e30 --- /dev/null +++ b/src/kernel_liteos_a/bsd/sys/malloc.h @@ -0,0 +1 @@ +../../../../third_party/FreeBSD/sys/sys/malloc.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/sys/module.h b/src/kernel_liteos_a/bsd/sys/module.h new file mode 100644 index 00000000..7058563a --- /dev/null +++ b/src/kernel_liteos_a/bsd/sys/module.h @@ -0,0 +1 @@ +../../../../third_party/FreeBSD/sys/sys/module.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/sys/mutex.h b/src/kernel_liteos_a/bsd/sys/mutex.h new file mode 100644 index 00000000..47606d1b --- /dev/null +++ b/src/kernel_liteos_a/bsd/sys/mutex.h @@ -0,0 +1 @@ +../../../../third_party/FreeBSD/sys/sys/mutex.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/sys/priv.h b/src/kernel_liteos_a/bsd/sys/priv.h new file mode 100644 index 00000000..5302a516 --- /dev/null +++ b/src/kernel_liteos_a/bsd/sys/priv.h @@ -0,0 +1 @@ +../../../../third_party/FreeBSD/sys/sys/priv.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/sys/queue.h b/src/kernel_liteos_a/bsd/sys/queue.h new file mode 100644 index 00000000..762e5add --- /dev/null +++ b/src/kernel_liteos_a/bsd/sys/queue.h @@ -0,0 +1 @@ +../../../../third_party/FreeBSD/sys/sys/queue.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/sys/sema.h b/src/kernel_liteos_a/bsd/sys/sema.h new file mode 100644 index 00000000..ddf8c43b --- /dev/null +++ b/src/kernel_liteos_a/bsd/sys/sema.h @@ -0,0 +1 @@ +../../../../third_party/FreeBSD/sys/sys/sema.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/sys/sx.h b/src/kernel_liteos_a/bsd/sys/sx.h new file mode 100644 index 00000000..202ca5f0 --- /dev/null +++ b/src/kernel_liteos_a/bsd/sys/sx.h @@ -0,0 +1 @@ +../../../../third_party/FreeBSD/sys/sys/sx.h \ No newline at end of file diff --git a/src/kernel_liteos_a/bsd/sys/systm.h b/src/kernel_liteos_a/bsd/sys/systm.h new file mode 100644 index 00000000..82118401 --- /dev/null +++ b/src/kernel_liteos_a/bsd/sys/systm.h @@ -0,0 +1 @@ +../../../../third_party/FreeBSD/sys/sys/systm.h \ No newline at end of file diff --git a/src/kernel_liteos_a/build.sh b/src/kernel_liteos_a/build.sh new file mode 100644 index 00000000..52c19e53 --- /dev/null +++ b/src/kernel_liteos_a/build.sh @@ -0,0 +1,69 @@ +#!/bin/bash +# +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +set -e + +board_name=${1} +ohos_build_compiler=${2} +root_build_dir=${3} +ohos_build_type=${4} +tee_enable=${5} +device_company=${6} +product_path=${7} +outdir=${8} +ohos_version=${9} +sysroot_path=${10} +arch_cflags=${11} +device_path=${12} +compile_prefix=${13} +liteos_config_file=${14} + +echo "sh param:" "$@" + +if [ "x" != "x${sysroot_path}" ]; then + export SYSROOT_PATH=${sysroot_path} +fi + +if [ "x" != "x${arch_cflags}" ]; then + export ARCH_CFLAGS="${arch_cflags}" +fi + +export PRODUCT_PATH="${product_path}" +export DEVICE_PATH="${device_path}" + +export OUTDIR="${outdir}" +export KCONFIG_CONFIG="${liteos_config_file}" +export LITEOS_MENUCONFIG_H="${outdir}/config.h" +export LITEOS_CONFIG_FILE="${outdir}/.config" +export LITEOS_COMPILER_PATH="${compile_prefix%/*}/" +export CROSS_COMPILE="${compile_prefix##*/}" + +mkdir -p "${outdir}" +make -j all VERSION="${ohos_version}" diff --git a/src/kernel_liteos_a/bundle.json b/src/kernel_liteos_a/bundle.json new file mode 100644 index 00000000..cccbce32 --- /dev/null +++ b/src/kernel_liteos_a/bundle.json @@ -0,0 +1,65 @@ +{ + "name": "@ohos/liteos_a", + "version": "3.1.0", + "description": "liteos-a kernel", + "homePage": "https://gitee.com/openharmony", + "license": "BSD 3-clause", + "repository": "https://gitee.com/openharmony/kernel_liteos_a", + "domain": "os", + "language": "", + "publishAs": "code-segment", + "private": false, + "scripts": {}, + "tags": [ + "kernel" + ], + "keywords": [ + "kernel", + "liteos-a" + ], + "envs": [], + "dirs": [], + "author": {}, + "contributors": [], + "segment": { + "destPath": "kernel/liteos_a" + }, + "component": { + "name": "liteos_a", + "subsystem": "kernel", + "syscap": [ + "SystemCapability.Kernel.Liteos-A" + ], + "features": [], + "adapted_system_type": [ + "small" + ], + "rom": "1.5MB", + "ram": "2MB", + "deps": { + "components": [ + ], + "third_party": [ + "bounds_checking_function", + "toybox", + "NuttX", + "FatFs", + "mksh", + "musl", + "mbedtls", + "FreeBSD", + "zlib", + "lwip", + "optimized-routines", + "googletest" + ] + }, + "build": { + "sub_component": [ + "//kernel/liteos_a:liteos_a" + ], + "inner_kits": [], + "test": [] + } + } +} diff --git a/src/kernel_liteos_a/compat/BUILD.gn b/src/kernel_liteos_a/compat/BUILD.gn new file mode 100644 index 00000000..300dcf3e --- /dev/null +++ b/src/kernel_liteos_a/compat/BUILD.gn @@ -0,0 +1,38 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +group("compat") { + deps = [ "posix" ] +} + +config("public") { + configs = [ "posix:public" ] +} diff --git a/src/kernel_liteos_a/compat/posix/BUILD.gn b/src/kernel_liteos_a/compat/posix/BUILD.gn new file mode 100644 index 00000000..31210665 --- /dev/null +++ b/src/kernel_liteos_a/compat/posix/BUILD.gn @@ -0,0 +1,59 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = defined(LOSCFG_COMPAT_POSIX) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ + "src/errno.c", + "src/malloc.c", + "src/map_error.c", + "src/misc.c", + "src/mqueue.c", + "src/posix_memalign.c", + "src/pthread.c", + "src/pthread_attr.c", + "src/pthread_cond.c", + "src/pthread_mutex.c", + "src/sched.c", + "src/semaphore.c", + "src/socket.c", + "src/stdio.c", + "src/stdlib.c", + "src/time.c", + ] + + public_configs = [ ":public" ] +} + +config("public") { + include_dirs = [ "include" ] +} diff --git a/src/kernel_liteos_a/compat/posix/Kconfig b/src/kernel_liteos_a/compat/posix/Kconfig new file mode 100644 index 00000000..1d0c733e --- /dev/null +++ b/src/kernel_liteos_a/compat/posix/Kconfig @@ -0,0 +1,6 @@ +config COMPAT_POSIX + bool "Enable Posix" + default y + + help + Answer Y to enable LiteOS support posix interface. \ No newline at end of file diff --git a/src/kernel_liteos_a/compat/posix/Makefile b/src/kernel_liteos_a/compat/posix/Makefile new file mode 100644 index 00000000..cfeb6a3a --- /dev/null +++ b/src/kernel_liteos_a/compat/posix/Makefile @@ -0,0 +1,40 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := $(wildcard src/*.c) + +LOCAL_INCLUDE := -I $(LITEOSTOPDIR)/compat/posix/src + +LOCAL_FLAGS := $(LOCAL_INCLUDE) + +include $(MODULE) diff --git a/src/kernel_liteos_a/compat/posix/include/mqueue.h b/src/kernel_liteos_a/compat/posix/include/mqueue.h new file mode 100644 index 00000000..551dd06a --- /dev/null +++ b/src/kernel_liteos_a/compat/posix/include/mqueue.h @@ -0,0 +1,439 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup mqueue Message queue + * @ingroup posix + */ + +#ifndef _HWLITEOS_POSIX_MQUEUE_H +#define _HWLITEOS_POSIX_MQUEUE_H + +/* INCLUDES */ +#include "stdarg.h" +#include "stdlib.h" +#include "limits.h" +#include "los_typedef.h" +#include "time.h" +#include +#include +#include + +#include "los_queue_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup mqueue + * Maximum number of messages in a message queue + */ +#define MQ_MAX_MSG_NUM 16 + +/** + * @ingroup mqueue + * Maximum size of a single message in a message queue + */ +#define MQ_MAX_MSG_LEN 64 + + +/* CONSTANTS */ + +#define MQ_USE_MAGIC 0x89abcdef +/* not support prio */ +#define MQ_PRIO_MAX 1 + +#ifndef MAX_MQ_FD +#define MAX_MQ_FD CONFIG_NQUEUE_DESCRIPTORS +#endif + +typedef union send_receive_t { + unsigned oth : 3; + unsigned grp : 6; + unsigned usr : 9; + short data; +} mode_s; + +struct mqnotify { + pid_t pid; + struct sigevent notify; +}; + +/* TYPE DEFINITIONS */ +struct mqarray { + UINT32 mq_id : 31; + UINT32 unlinkflag : 1; + char *mq_name; + UINT32 unlink_ref; + mode_s mode_data; /* mode data of mqueue */ + uid_t euid; /* euid of mqueue */ + gid_t egid; /* egid of mqueue */ + struct mqnotify mq_notify; + LosQueueCB *mqcb; + struct mqpersonal *mq_personal; +}; + +struct mqpersonal { + struct mqarray *mq_posixdes; + struct mqpersonal *mq_next; + int mq_flags; + int mq_mode; /* Mode of mqueue */ + UINT32 mq_status; + UINT32 mq_refcount; +}; + +/** + * @ingroup mqueue + * Message queue attribute structure + */ +struct mq_attr { + long mq_flags; /**< Message queue flags */ + long mq_maxmsg; /**< Maximum number of messages */ + long mq_msgsize; /**< Maximum size of a message */ + long mq_curmsgs; /**< Number of messages in the current message queue */ +}; + +/** + * @ingroup mqueue + * Handle type of a message queue + */ +typedef UINTPTR mqd_t; + +/** + * @ingroup mqueue + * + * @par Description: + * This API is used to open an existed message queue that has a specified name or create a new message queue. + * @attention + *
            + *
          • A message queue does not restrict the read and write permissions.
          • + *
          • The length of mqueue name must less than 256.
          • + *
          • This operation and closed mqueue scheduling must be used in coordination to release the resource.
          • + *
          • The parameter "mode" is not supported.
          • + *
          • The "mq_curmsgs" member of the mq_attr structure is not supported.
          • + *
          + * + * @param mqName [IN] Message queue name. + * @param openFlag [IN] Permission attributes of the message queue. The value range is + * [O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_EXCL, O_NONBLOCK]. + * @param mode [IN] Message queue mode (variadic argument). When oflag is O_CREAT, it requires + * two additional arguments: mode, which shall be of type mode_t, and attr, + * which shall be a pointer to an mq_attr structure. + * @param attr [IN] Message queue attribute (variadic argument). + * + * @retval mqd_t The message queue is successfully opened or created. + * @retval (mqd_t)-1 The message queue fails to be opened or created, with any of the following error codes in errno. + * + * + * @par Errors + *
            + *
          • ENOENT: O_CREAT flag is not set for oflag, and the message queue specified by name does not exist.
          • + *
          • EEXIST: Both O_CREAT and O_EXCL are set for oflag, but the message queue + * specified by name already exists.
          • + *
          • EINVAL: invalid parameter.
          • + *
          • ENFILE: The number of opened message queues exceeds the maximum limit.
          • + *
          • ENOSPC: insufficient memory.
          • + *
          • ENAMETOOLONG: The message queue name specified by name is too long.
          • + *
          + * + * @par Dependency: + *
          • mqueue.h
          + * @see mq_close + */ +extern mqd_t mq_open(const char *mqName, int openFlag, ...); + +/** + * @ingroup mqueue + * + * @par Description: + * This API is used to close a message queue that has a specified descriptor. + * @attention + *
            + *
          • If the message queue is empty, it will be reclaimed, which is similar to when mq_unlink is called.
          • + *
          + * + * @param personal [IN] Message queue descriptor. + * + * @retval 0 The message queue is successfully closed. + * @retval -1 The message queue fails to be closed, with either of the following error codes in errno. + * + * @par Errors + *
            + *
          • EBADF: Invalid message queue descriptor.
          • + *
          • EAGAIN: Failed to delete the message queue.
          • + *
          • EFAULT: Failed to free the message queue.
          • + *
          • EINVAL: Invalid parameter.
          • + *
          + * + * @par Dependency: + *
          • mqueue.h
          + * @see mq_open + */ +extern int mq_close(mqd_t personal); + +/** + * @ingroup mqueue + * + * @par Description: + * This API is used to remove a message queue that has a specified name. + * @attention + *
            + *
          • If the message queue is empty, it will be reclaimed, which is similar to when mq_close is called.
          • + *
          • The length of mqueue name must less than 256.
          • + *
          + * + * @param mqName [IN] Message queue name. + * + * @retval 0 The message queue is successfully removed. + * @retval -1 The message queue fails to be removed, with any of the following error codes in errno. + * + * @par Errors + *
            + *
          • ENOENT: The message queue specified by name does not exist.
          • + *
          • EAGAIN: Failed to delete the message queue.
          • + *
          • EBUSY: The message queue to be removed is being used.
          • + *
          • EINVAL: Invalid parameter.
          • + *
          • ENAMETOOLONG: The name of mqueue is too long.
          • + *
          + * + * @par Dependency: + *
          • mqueue.h
          + * @see mq_close + */ +extern int mq_unlink(const char *mqName); + +/** + * @ingroup mqueue + * + * @par Description: + * This API is used to put a message with specified message content and length into + * a message queue that has a specified descriptor. + * @attention + *
            + *
          • Priority-based message processing is not supported.
          • + *
          • The msg_len should be same to the length of string which msg_ptr point to.
          • + *
          + * + * @param personal [IN] Message queue descriptor. + * @param msg [IN] Pointer to the message content to be sent. + * @param msgLen [IN] Length of the message to be sent. + * @param msgPrio [IN] Priority of the message to be sent (the value of this parameter must + * be 0 because priority-based message sending is not supported. If the + * value is not 0, this API will cease to work.) + * + * @retval 0 The message is successfully sent. + * @retval -1 The message fails to be sent, with any of the following error codes in errno. + * + * @par Errors + *
            + *
          • EINTR: An interrupt is in progress while the message is being sent.
          • + *
          • EBADF: The message queue is invalid or not writable.
          • + *
          • EAGAIN: The message queue is full.
          • + *
          • EINVAL: Invalid parameter.
          • + *
          • ENOSPC: Insufficient memory.
          • + *
          • EMSGSIZE: The message to be sent is too long.
          • + *
          • EOPNOTSUPP: The operation is not supported.
          • + *
          • ETIMEDOUT: The operation times out.
          • + *
          + * + * @par Dependency: + *
          • mqueue.h
          + * @see mq_receive + */ +extern int mq_send(mqd_t personal, const char *msg, size_t msgLen, unsigned int msgPrio); + +/** + * @ingroup mqueue + * + * @par Description: + * This API is used to remove the oldest message from the message queue that has a specified descriptor, + * and puts it in the buffer pointed to by msg_ptr. + * @attention + *
            + *
          • Priority-based message processing is not supported.
          • + *
          • The msg_len should be same to the length of string which msg_ptr point to.
          • + *
          + * + * @param personal [IN] Message queue descriptor. + * @param msg [IN] Pointer to the message content to be received. + * @param msgLen [IN] Length of the message to be received. + * @param msgPrio [OUT] Priority of the message to be received + * because priority-based message processing is not supported, this parameter is useless). + * + * @retval 0 The message is successfully received. + * @retval -1 The message fails to be received, with any of the following error codes in the errno. + * + * @par Errors + *
            + *
          • EINTR: An interrupt is in progress while the message is being received.
          • + *
          • EBADF: The message queue is invalid or not readable.
          • + *
          • EAGAIN: The message queue is empty.
          • + *
          • EINVAL: invalid parameter.
          • + *
          • EMSGSIZE: The message to be received is too long.
          • + *
          • ETIMEDOUT: The operation times out.
          • + *
          + * + * @par Dependency: + *
          • mqueue.h
          + * @see mq_send + */ +extern ssize_t mq_receive(mqd_t personal, char *msg, size_t msgLen, unsigned int *msgPrio); + +/** + * @ingroup mqueue + * + * @par Description: + * This API is used to obtain or modify attributes of the message queue that has a specified descriptor. + * @attention + *
            + *
          • The mq_maxmsg, mq_msgsize, and mq_curmsgs attributes are not modified + * in the message queue attribute setting.
          • + *
          + * + * @param personal [IN] Message queue descriptor. + * @param mqSetAttr [IN] New attribute of the message queue. + * @param MqOldAttr [OUT] Old attribute of the message queue. + * + * @retval 0 The message queue attributes are successfully set or get. + * @retval -1 The message queue attributes fail to be set or get, + * with either of the following error codes in the errno. + * + * @par Errors + *
            + *
          • EBADF: Invalid message queue.
          • + *
          • EINVAL: Invalid parameter.
          • + *
          + * + * @par Dependency: + *
          • mqueue.h
          + * @see sys_mq_getsetattr + */ +extern int mq_getsetattr(mqd_t personal, const struct mq_attr *mqSetAttr, struct mq_attr *MqOldAttr); + +/** + * @ingroup mqueue + * + * @par Description: + * This API is used to put a message with specified message content and length into + * a message queue that has a descriptor at a scheduled time. + * @attention + *
            + *
          • Priority-based message processing is not supported.
          • + *
          • The expiry time must be later than the current time.
          • + *
          • The wait time is a relative time.
          • + *
          • The msg_len should be same to the length of string which msg_ptr point to.
          • + *
          + * + * @param mqdes [IN] Message queue descriptor. + * @param msg [IN] Pointer to the message content to be sent. + * @param msgLen [IN] Length of the message to be sent. + * @param msgPrio [IN] Priority of the message to be sent (the value of this parameter must be 0 + * because priority-based message processing is not supported). + * @param absTimeout [IN] Scheduled time at which the message will be sent. If the value is 0, + * the message is an instant message. + * + * @retval 0 The message is successfully sent. + * @retval -1 The message fails to be sent, with any of the following error codes in errno. + * + * @par Errors + *
            + *
          • EINTR: An interrupt is in progress while the message is being sent.
          • + *
          • EBADF: The message queue is invalid or not writable.
          • + *
          • EAGAIN: The message queue is full.
          • + *
          • EINVAL: Invalid parameter.
          • + *
          • EMSGSIZE: The message to be sent is too long.
          • + *
          • EOPNOTSUPP: The operation is not supported.
          • + *
          • ETIMEDOUT: The operation times out.
          • + *
          + * + * @par Dependency: + *
          • mqueue.h
          + * @see mq_receive + */ +extern int mq_timedsend(mqd_t personal, const char *msg, size_t msgLen, + unsigned int msgPrio, const struct timespec *absTimeout); + +/** + * @ingroup mqueue + * + * @par Description: + * This API is used to obtain a message with specified message content and length from + * a message queue message that has a specified descriptor. + * @attention + *
            + *
          • Priority-based message processing is not supported.
          • + *
          • The expiry time must be later than the current time.
          • + *
          • The wait time is a relative time.
          • + *
          • The msg_len should be same to the length of string which msg_ptr point to.
          • + *
          + * + * @param personal [IN] Message queue descriptor. + * @param msg [IN] Pointer to the message content to be received. + * @param msgLen [IN] Length of the message to be received. + * @param msgPrio [OUT] Priority of the message to be received (because priority-based message + * processing is not supported, this parameter is useless ). + * @param absTimeout [IN] Scheduled time at which the messagewill be received. If the value is 0, + * the message is an instant message. + * + * @retval 0 The message is successfully received. + * @retval -1 The message fails to be received, with any of the following error codes in errno. + * + * @par Errors + *
            + *
          • EINTR: An interrupt is in progress while the message is being received.
          • + *
          • EBADF: The message queue is invalid or not readable.
          • + *
          • EAGAIN: The message queue is empty.
          • + *
          • EINVAL: invalid parameter.
          • + *
          • EMSGSIZE: The message to be received is too long.
          • + *
          • ETIMEDOUT: The operation times out.
          • + *
          + * + * @par Dependency: + *
          • mqueue.h
          + * @see mq_send + */ +extern ssize_t mq_timedreceive(mqd_t personal, char *msg, size_t msgLen, + unsigned int *msgPrio, const struct timespec *absTimeout); + +extern void MqueueRefer(int sysFd); +extern int OsMqNotify(mqd_t personal, const struct sigevent *sigev); +extern VOID OsMqueueCBDestroy(struct mqarray *queueTable); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/src/kernel_liteos_a/compat/posix/include/time_posix.h b/src/kernel_liteos_a/compat/posix/include/time_posix.h new file mode 100644 index 00000000..3f19bde8 --- /dev/null +++ b/src/kernel_liteos_a/compat/posix/include/time_posix.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _TIME_PRI_H +#define _TIME_PRI_H + +#include "time.h" +#include "errno.h" +#include "los_sys_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +struct ksigevent { + union sigval sigev_value; + int sigev_signo; + int sigev_notify; + int sigev_tid; +}; + +/* internal functions */ +STATIC INLINE BOOL ValidTimeSpec(const struct timespec *tp) +{ + /* Fail a NULL pointer */ + if (tp == NULL) { + return FALSE; + } + + /* Fail illegal nanosecond values */ + if ((tp->tv_nsec < 0) || (tp->tv_nsec >= OS_SYS_NS_PER_SECOND) || (tp->tv_sec < 0)) { + return FALSE; + } + + return TRUE; +} + +STATIC INLINE UINT32 OsTimeSpec2Tick(const struct timespec *tp) +{ + UINT64 tick, ns; + + ns = (UINT64)tp->tv_sec * OS_SYS_NS_PER_SECOND + tp->tv_nsec; + /* Round up for ticks */ + tick = (ns * LOSCFG_BASE_CORE_TICK_PER_SECOND + (OS_SYS_NS_PER_SECOND - 1)) / OS_SYS_NS_PER_SECOND; + if (tick > LOS_WAIT_FOREVER) { + tick = LOS_WAIT_FOREVER; + } + return (UINT32)tick; +} + +STATIC INLINE VOID OsTick2TimeSpec(struct timespec *tp, UINT32 tick) +{ + UINT64 ns = ((UINT64)tick * OS_SYS_NS_PER_SECOND) / LOSCFG_BASE_CORE_TICK_PER_SECOND; + tp->tv_sec = (time_t)(ns / OS_SYS_NS_PER_SECOND); + tp->tv_nsec = (long)(ns % OS_SYS_NS_PER_SECOND); +} + +int OsTimerCreate(clockid_t, struct ksigevent *__restrict, timer_t *__restrict); +void OsAdjTime(void); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ +#endif /* _TIME_PRI_H */ \ No newline at end of file diff --git a/src/kernel_liteos_a/compat/posix/src/errno.c b/src/kernel_liteos_a/compat/posix/src/errno.c new file mode 100644 index 00000000..ca487216 --- /dev/null +++ b/src/kernel_liteos_a/compat/posix/src/errno.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "errno.h" +#include "los_errno.h" +#include "los_task_pri.h" + +/* the specific errno get or set in interrupt service routine */ +static int errno_isr; + +int *__errno_location(void) +{ + LosTaskCB *runTask = NULL; + + if (OS_INT_INACTIVE) { + runTask = OsCurrTaskGet(); + return &runTask->errorNo; + } else { + return &errno_isr; + } +} + +int *__errno(void) __attribute__((__weak__, __alias__("__errno_location"))); diff --git a/src/kernel_liteos_a/compat/posix/src/malloc.c b/src/kernel_liteos_a/compat/posix/src/malloc.c new file mode 100644 index 00000000..50e4f8dc --- /dev/null +++ b/src/kernel_liteos_a/compat/posix/src/malloc.c @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "stdlib.h" +#include "string.h" +#include "los_vm_map.h" + +/* + * Allocates the requested memory and returns a pointer to it. The requested + * size is nitems each size bytes long (total memory requested is nitems*size). + * The space is initialized to all zero bits. + */ + +void *calloc(size_t nitems, size_t size) +{ + size_t real_size; + void *ptr = NULL; + + if (nitems == 0 || size == 0) { + return NULL; + } + + real_size = (size_t)(nitems * size); + ptr = LOS_KernelMalloc((UINT32) real_size); + if (ptr != NULL) { + (void) memset_s((void *) ptr, real_size, 0, real_size); + } + return ptr; +} + +/* + * Deallocates the memory previously allocated by a call to calloc, malloc, or + * realloc. The argument ptr points to the space that was previously allocated. + * If ptr points to a memory block that was not allocated with calloc, malloc, + * or realloc, or is a space that has been deallocated, then the result is undefined. + */ + +void free(void *ptr) +{ + if (ptr == NULL) { + return; + } + + LOS_KernelFree(ptr); +} + +/* + * Allocates the requested memory and returns a pointer to it. The requested + * size is size bytes. The value of the space is indeterminate. + */ + +void *malloc(size_t size) +{ + if (size == 0) { + return NULL; + } + + return LOS_KernelMalloc((UINT32) size); +} + +void *zalloc(size_t size) +{ + void *ptr = NULL; + + if (size == 0) { + return NULL; + } + + ptr = LOS_KernelMalloc((UINT32) size); + if (ptr != NULL) { + (void) memset_s(ptr, size, 0, size); + } + return ptr; +} + +/* + * allocates a block of size bytes whose address is a multiple of boundary. + * The boundary must be a power of two! + */ + +void *memalign(size_t boundary, size_t size) +{ + if (size == 0) { + return NULL; + } + + return LOS_KernelMallocAlign((UINT32) size, (UINT32) boundary); +} + +/* + * Attempts to resize the memory block pointed to by ptr that was previously + * allocated with a call to malloc or calloc. The contents pointed to by ptr are + * unchanged. If the value of size is greater than the previous size of the + * block, then the additional bytes have an undeterminate value. If the value + * of size is less than the previous size of the block, then the difference of + * bytes at the end of the block are freed. If ptr is null, then it behaves like + * malloc. If ptr points to a memory block that was not allocated with calloc + * or malloc, or is a space that has been deallocated, then the result is + * undefined. If the new space cannot be allocated, then the contents pointed + * to by ptr are unchanged. If size is zero, then the memory block is completely + * freed. + */ + +void *realloc(void *ptr, size_t size) +{ + if (ptr == NULL) { + ptr = malloc(size); + return ptr; + } + + if (size == 0) { + free(ptr); + return NULL; + } + + return LOS_KernelRealloc(ptr, (UINT32) size); +} diff --git a/src/kernel_liteos_a/compat/posix/src/map_error.c b/src/kernel_liteos_a/compat/posix/src/map_error.c new file mode 100644 index 00000000..c25d1133 --- /dev/null +++ b/src/kernel_liteos_a/compat/posix/src/map_error.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_mux.h" +#include "los_queue.h" +#include "los_sem.h" +#include "los_task.h" + + +int map_errno(UINT32 err) +{ + if (err == LOS_OK) { + return ENOERR; + } + switch (err) { + case LOS_ERRNO_QUEUE_INVALID: + case LOS_ERRNO_QUEUE_WRITE_PTR_NULL: + case LOS_ERRNO_QUEUE_WRITESIZE_ISZERO: + case LOS_ERRNO_QUEUE_SIZE_TOO_BIG: + case LOS_ERRNO_QUEUE_CREAT_PTR_NULL: + case LOS_ERRNO_QUEUE_PARA_ISZERO: + case LOS_ERRNO_QUEUE_WRITE_SIZE_TOO_BIG: + errno = EINVAL; + break; + case LOS_ERRNO_QUEUE_ISFULL: + case LOS_ERRNO_QUEUE_ISEMPTY: + errno = EAGAIN; + break; + case LOS_ERRNO_QUEUE_CREATE_NO_MEMORY: + errno = ENOSPC; + break; + case LOS_ERRNO_QUEUE_TIMEOUT: + errno = ETIMEDOUT; + break; + case LOS_ERRNO_QUEUE_CB_UNAVAILABLE: + errno = ENFILE; + break; + case LOS_ERRNO_QUEUE_READ_IN_INTERRUPT: + case LOS_ERRNO_QUEUE_WRITE_IN_INTERRUPT: + errno = EINTR; + break; + case LOS_ERRNO_TSK_ID_INVALID: + case LOS_ERRNO_TSK_PTR_NULL: + case LOS_ERRNO_TSK_NAME_EMPTY: + case LOS_ERRNO_TSK_ENTRY_NULL: + case LOS_ERRNO_TSK_PRIOR_ERROR: + case LOS_ERRNO_TSK_STKSZ_TOO_LARGE: + case LOS_ERRNO_TSK_STKSZ_TOO_SMALL: + case LOS_ERRNO_TSK_NOT_CREATED: + case LOS_ERRNO_TSK_CPU_AFFINITY_MASK_ERR: + case OS_ERROR: + case LOS_ERRNO_SEM_INVALID: + case LOS_ERRNO_SEM_UNAVAILABLE: + errno = EINVAL; + break; + case LOS_ERRNO_TSK_TCB_UNAVAILABLE: + case LOS_ERRNO_TSK_MP_SYNC_RESOURCE: + case LOS_ERRNO_SEM_ALL_BUSY: + errno = ENOSPC; + break; + case LOS_ERRNO_TSK_NO_MEMORY: + case LOS_ERRNO_SEM_OVERFLOW: + errno = ENOMEM; + break; + case LOS_ERRNO_SEM_PENDED: + case LOS_ERRNO_EVENT_SHOULD_NOT_DESTROY: + errno = EBUSY; + break; + case LOS_ERRNO_SEM_PEND_IN_LOCK: + errno = EPERM; + break; + case LOS_ERRNO_SEM_PEND_INTERR: + errno = EINTR; + break; + case LOS_ERRNO_SEM_TIMEOUT: + errno = ETIMEDOUT; + break; + default: + errno = EINVAL; + break; + } + return errno; +} + diff --git a/src/kernel_liteos_a/compat/posix/src/map_error.h b/src/kernel_liteos_a/compat/posix/src/map_error.h new file mode 100644 index 00000000..935b2d5e --- /dev/null +++ b/src/kernel_liteos_a/compat/posix/src/map_error.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _HWLITEOS_POSIX_MAP_ERROR_H +#define _HWLITEOS_POSIX_MAP_ERROR_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +int map_errno(unsigned int err); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/src/kernel_liteos_a/compat/posix/src/misc.c b/src/kernel_liteos_a/compat/posix/src/misc.c new file mode 100644 index 00000000..9f619070 --- /dev/null +++ b/src/kernel_liteos_a/compat/posix/src/misc.c @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "sys/types.h" +#include "sys/resource.h" +#include "unistd.h" +#include "stdio.h" +#include "pthread.h" +#include "sys/utsname.h" +#include "mqueue.h" +#include "semaphore.h" +#include "los_process_pri.h" +#include "los_hw.h" + +/* + * Supply some suitable values for constants that may not be present + * in all configurations. + */ +#define SC_ENABLE 1 +#define SC_DISABLE (-1) + +#define CONF_CASE_RETURN(name, val) \ + case (name): \ + return (val) + +int uname(struct utsname *name) +{ + if (name == NULL) { + return -EFAULT; + } + +#ifdef LOSCFG_UTS_CONTAINER + struct utsname *currentUtsName = OsGetCurrUtsName(); + if (currentUtsName == NULL) { + return -EFAULT; + } + (VOID)memcpy_s(name, sizeof(struct utsname), currentUtsName, sizeof(struct utsname)); +#else + + (VOID)strcpy_s(name->sysname, sizeof(name->sysname), KERNEL_NAME); + (VOID)strcpy_s(name->nodename, sizeof(name->nodename), KERNEL_NODE_NAME); + INT32 ret = sprintf_s(name->version, sizeof(name->version), "%s %u.%u.%u.%u %s %s", + KERNEL_NAME, KERNEL_MAJOR, KERNEL_MINOR, KERNEL_PATCH, KERNEL_ITRE, __DATE__, __TIME__); + if (ret < 0) { + return -EIO; + } + + const char *cpuInfo = LOS_CpuInfo(); + (VOID)strcpy_s(name->machine, sizeof(name->machine), cpuInfo); + ret = sprintf_s(name->release, sizeof(name->release), "%u.%u.%u.%u", + KERNEL_MAJOR, KERNEL_MINOR, KERNEL_PATCH, KERNEL_ITRE); + if (ret < 0) { + return -EIO; + } + + name->domainname[0] = '\0'; +#endif + return 0; +} + +long sysconf(int name) +{ + switch (name) { + CONF_CASE_RETURN(_SC_AIO_LISTIO_MAX, SC_DISABLE); + CONF_CASE_RETURN(_SC_AIO_MAX, SC_DISABLE); + CONF_CASE_RETURN(_SC_AIO_PRIO_DELTA_MAX, SC_DISABLE); + CONF_CASE_RETURN(_SC_ARG_MAX, ARG_MAX); + CONF_CASE_RETURN(_SC_ASYNCHRONOUS_IO, SC_DISABLE); + CONF_CASE_RETURN(_SC_CHILD_MAX, CHILD_MAX); + CONF_CASE_RETURN(_SC_CLK_TCK, SYS_CLK_TCK); + CONF_CASE_RETURN(_SC_DELAYTIMER_MAX, DELAYTIMER_MAX); + CONF_CASE_RETURN(_SC_FSYNC, SC_DISABLE); + CONF_CASE_RETURN(_SC_GETGR_R_SIZE_MAX, GETGR_R_SIZE_MAX); + CONF_CASE_RETURN(_SC_GETPW_R_SIZE_MAX, GETPW_R_SIZE_MAX); + CONF_CASE_RETURN(_SC_JOB_CONTROL, SC_DISABLE); + CONF_CASE_RETURN(_SC_LOGIN_NAME_MAX, LOGIN_NAME_MAX); + CONF_CASE_RETURN(_SC_MAPPED_FILES, SC_DISABLE); + CONF_CASE_RETURN(_SC_MEMLOCK, SC_DISABLE); + CONF_CASE_RETURN(_SC_MEMLOCK_RANGE, SC_DISABLE); + CONF_CASE_RETURN(_SC_MEMORY_PROTECTION, SC_DISABLE); + CONF_CASE_RETURN(_SC_MESSAGE_PASSING, SC_DISABLE); +#ifdef LOSCFG_BASE_IPC_QUEUE + CONF_CASE_RETURN(_SC_MQ_OPEN_MAX, MQ_OPEN_MAX); + CONF_CASE_RETURN(_SC_MQ_PRIO_MAX, MQ_PRIO_MAX); +#endif + CONF_CASE_RETURN(_SC_NGROUPS_MAX, NGROUPS_MAX); + CONF_CASE_RETURN(_SC_OPEN_MAX, OPEN_MAX); + CONF_CASE_RETURN(_SC_PAGESIZE, 0x1000); + CONF_CASE_RETURN(_SC_PRIORITIZED_IO, SC_DISABLE); + CONF_CASE_RETURN(_SC_PRIORITY_SCHEDULING, SC_DISABLE); + CONF_CASE_RETURN(_SC_REALTIME_SIGNALS, SC_DISABLE); + CONF_CASE_RETURN(_SC_RTSIG_MAX, RTSIG_MAX); + CONF_CASE_RETURN(_SC_SAVED_IDS, SC_DISABLE); + +#ifdef LOSCFG_BASE_IPC_SEM + CONF_CASE_RETURN(_SC_SEMAPHORES, SC_ENABLE); + CONF_CASE_RETURN(_SC_SEM_NSEMS_MAX, SEM_NSEMS_MAX); + CONF_CASE_RETURN(_SC_SEM_VALUE_MAX, SEM_VALUE_MAX); +#endif + + CONF_CASE_RETURN(_SC_SHARED_MEMORY_OBJECTS, SC_DISABLE); + CONF_CASE_RETURN(_SC_SIGQUEUE_MAX, SIGQUEUE_MAX); + CONF_CASE_RETURN(_SC_STREAM_MAX, STREAM_MAX); + CONF_CASE_RETURN(_SC_SYNCHRONIZED_IO, SC_DISABLE); + CONF_CASE_RETURN(_SC_THREADS, SC_ENABLE); + CONF_CASE_RETURN(_SC_THREAD_ATTR_STACKADDR, SC_ENABLE); + CONF_CASE_RETURN(_SC_THREAD_ATTR_STACKSIZE, PTHREAD_ATTR_STACKSIZE); + CONF_CASE_RETURN(_SC_THREAD_DESTRUCTOR_ITERATIONS, PTHREAD_DESTRUCTOR_ITERATIONS); + CONF_CASE_RETURN(_SC_THREAD_KEYS_MAX, PTHREAD_KEYS_MAX); + CONF_CASE_RETURN(_SC_THREAD_PRIO_INHERIT, PTHREAD_PRIO_INHERIT); + CONF_CASE_RETURN(_SC_THREAD_PRIO_PROTECT, PTHREAD_PRIO_PROTECT); + CONF_CASE_RETURN(_SC_THREAD_PRIORITY_SCHEDULING, PTHREAD_PRIORITY_SCHEDULING); + CONF_CASE_RETURN(_SC_THREAD_PROCESS_SHARED, PTHREAD_PROCESS_SHARED); + CONF_CASE_RETURN(_SC_THREAD_SAFE_FUNCTIONS, SC_DISABLE); + CONF_CASE_RETURN(_SC_THREAD_STACK_MIN, PTHREAD_STACK_MIN); + CONF_CASE_RETURN(_SC_THREAD_THREADS_MAX, PTHREAD_THREADS_MAX); + CONF_CASE_RETURN(_SC_TIMERS, TIMERS); + CONF_CASE_RETURN(_SC_TIMER_MAX, TIMER_MAX); + CONF_CASE_RETURN(_SC_TTY_NAME_MAX, TTY_NAME_MAX); + CONF_CASE_RETURN(_SC_TZNAME_MAX, TZNAME_MAX); + CONF_CASE_RETURN(_SC_VERSION, POSIX_VERSION); + + default: + set_errno(EINVAL); + return -1; + } +} + +pid_t getpid(void) +{ + return ((LosTaskCB *)(OsCurrTaskGet()))->taskID; +} + +int getrlimit(int resource, struct rlimit *rlim) +{ + unsigned int intSave; + LosProcessCB *pcb = OsCurrProcessGet(); + struct rlimit *resourceLimit = pcb->resourceLimit; + + switch (resource) { + case RLIMIT_NOFILE: + case RLIMIT_FSIZE: + break; + default: + return -EINVAL; + } + + if (resourceLimit == NULL) { + rlim->rlim_cur = 0; + rlim->rlim_max = 0; + + return 0; + } + + SCHEDULER_LOCK(intSave); + rlim->rlim_cur = resourceLimit[resource].rlim_cur; + rlim->rlim_max = resourceLimit[resource].rlim_max; + SCHEDULER_UNLOCK(intSave); + + return 0; +} + +#define FSIZE_RLIMIT 0XFFFFFFFF +#ifndef NR_OPEN_DEFAULT +#define NR_OPEN_DEFAULT 1024 +#endif +int setrlimit(int resource, const struct rlimit *rlim) +{ + unsigned int intSave; + struct rlimit *resourceLimit = NULL; + LosProcessCB *pcb = OsCurrProcessGet(); + + if (rlim->rlim_cur > rlim->rlim_max) { + return -EINVAL; + } + switch (resource) { + case RLIMIT_NOFILE: + if (rlim->rlim_max > NR_OPEN_DEFAULT) { + return -EPERM; + } + break; + case RLIMIT_FSIZE: + if (rlim->rlim_max > FSIZE_RLIMIT) { + return -EPERM; + } + break; + default: + return -EINVAL; + } + + if (pcb->resourceLimit == NULL) { + resourceLimit = LOS_MemAlloc((VOID *)m_aucSysMem0, RLIM_NLIMITS * sizeof(struct rlimit)); + if (resourceLimit == NULL) { + return -EINVAL; + } + } + + SCHEDULER_LOCK(intSave); + if (pcb->resourceLimit == NULL) { + pcb->resourceLimit = resourceLimit; + resourceLimit = NULL; + } + pcb->resourceLimit[resource].rlim_cur = rlim->rlim_cur; + pcb->resourceLimit[resource].rlim_max = rlim->rlim_max; + SCHEDULER_UNLOCK(intSave); + + (VOID)LOS_MemFree((VOID *)m_aucSysMem0, resourceLimit); + return 0; +} diff --git a/src/kernel_liteos_a/compat/posix/src/mqueue.c b/src/kernel_liteos_a/compat/posix/src/mqueue.c new file mode 100644 index 00000000..0b885d86 --- /dev/null +++ b/src/kernel_liteos_a/compat/posix/src/mqueue.c @@ -0,0 +1,979 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "mqueue.h" +#ifdef LOSCFG_FS_VFS +#include "fcntl.h" +#include "pthread.h" +#include "map_error.h" +#include "time_posix.h" +#include "los_memory.h" +#include "los_vm_map.h" +#include "los_process_pri.h" +#include "fs/file.h" +#include "user_copy.h" + + +#define FNONBLOCK O_NONBLOCK + +#ifndef LOSCFG_IPC_CONTAINER +/* GLOBALS */ +STATIC fd_set g_queueFdSet; +STATIC struct mqarray g_queueTable[LOSCFG_BASE_IPC_QUEUE_LIMIT]; +STATIC pthread_mutex_t g_mqueueMutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; +STATIC struct mqpersonal *g_mqPrivBuf[MAX_MQ_FD]; + +#define IPC_QUEUE_FD_SET g_queueFdSet +#define IPC_QUEUE_TABLE g_queueTable +#define IPC_QUEUE_MUTEX g_mqueueMutex +#define IPC_QUEUE_MQ_PRIV_BUF g_mqPrivBuf +#endif + +/* LOCAL FUNCTIONS */ +STATIC INLINE INT32 MqNameCheck(const CHAR *mqName) +{ + if (mqName == NULL) { + errno = EINVAL; + return -1; + } + + if (strlen(mqName) == 0) { + errno = EINVAL; + return -1; + } + + if (strlen(mqName) > (PATH_MAX - 1)) { + errno = ENAMETOOLONG; + return -1; + } + return 0; +} + +STATIC INLINE UINT32 GetMqueueCBByID(UINT32 queueID, LosQueueCB **queueCB) +{ + LosQueueCB *tmpQueueCB = NULL; + if (queueCB == NULL) { + errno = EINVAL; + return LOS_ERRNO_QUEUE_READ_PTR_NULL; + } + tmpQueueCB = GET_QUEUE_HANDLE(queueID); + if ((GET_QUEUE_INDEX(queueID) >= LOSCFG_BASE_IPC_QUEUE_LIMIT) || (tmpQueueCB->queueID != queueID)) { + return LOS_ERRNO_QUEUE_INVALID; + } + *queueCB = tmpQueueCB; + + return LOS_OK; +} + +STATIC INLINE struct mqarray *GetMqueueCBByName(const CHAR *name) +{ + UINT32 index; + UINT32 mylen = strlen(name); + + for (index = 0; index < LOSCFG_BASE_IPC_QUEUE_LIMIT; index++) { + if ((IPC_QUEUE_TABLE[index].mq_name == NULL) || (strlen(IPC_QUEUE_TABLE[index].mq_name) != mylen)) { + continue; + } + + if (strncmp(name, (const CHAR *)(IPC_QUEUE_TABLE[index].mq_name), mylen) == 0) { + return &(IPC_QUEUE_TABLE[index]); + } + } + return NULL; +} + +STATIC INT32 DoMqueueDelete(struct mqarray *mqueueCB) +{ + UINT32 ret; +#ifdef LOSCFG_KERNEL_IPC_PLIMIT + OsIPCLimitMqFree(); +#endif + if (mqueueCB->mq_name != NULL) { + LOS_MemFree(OS_SYS_MEM_ADDR, mqueueCB->mq_name); + mqueueCB->mq_name = NULL; + } + + mqueueCB->mqcb = NULL; + /* When mqueue-list head node needed free ,reset the mode_data */ + mqueueCB->mode_data.data = 0; + mqueueCB->euid = -1; + mqueueCB->egid = -1; + mqueueCB->mq_notify.pid = 0; + + ret = LOS_QueueDelete(mqueueCB->mq_id); + switch (ret) { + case LOS_OK: + return 0; + case LOS_ERRNO_QUEUE_NOT_FOUND: + case LOS_ERRNO_QUEUE_NOT_CREATE: + case LOS_ERRNO_QUEUE_IN_TSKUSE: + case LOS_ERRNO_QUEUE_IN_TSKWRITE: + errno = EAGAIN; + return -1; + default: + errno = EINVAL; + return -1; + } +} + +STATIC int SaveMqueueName(const CHAR *mqName, struct mqarray *mqueueCB) +{ + size_t nameLen; + + nameLen = strlen(mqName); /* sys_mq_open has checked name and name length */ + mqueueCB->mq_name = (char *)LOS_MemAlloc(OS_SYS_MEM_ADDR, nameLen + 1); + if (mqueueCB->mq_name == NULL) { + errno = ENOMEM; + return LOS_NOK; + } + + if (strncpy_s(mqueueCB->mq_name, (nameLen + 1), mqName, nameLen) != EOK) { + LOS_MemFree(OS_SYS_MEM_ADDR, mqueueCB->mq_name); + mqueueCB->mq_name = NULL; + errno = EINVAL; + return LOS_NOK; + } + mqueueCB->mq_name[nameLen] = '\0'; + return LOS_OK; +} + +STATIC VOID MqueueCBInit(struct mqarray *mqueueCB, const struct mq_attr *attr, INT32 openFlag, UINT32 mode) +{ + mqueueCB->unlinkflag = FALSE; + mqueueCB->unlink_ref = 0; + mqueueCB->mq_personal->mq_status = MQ_USE_MAGIC; + mqueueCB->mq_personal->mq_next = NULL; + mqueueCB->mq_personal->mq_posixdes = mqueueCB; + mqueueCB->mq_personal->mq_flags = (INT32)((UINT32)openFlag | ((UINT32)attr->mq_flags & (UINT32)FNONBLOCK)); + mqueueCB->mq_personal->mq_mode = mode; + mqueueCB->mq_personal->mq_refcount = 0; + mqueueCB->mq_notify.pid = 0; +} + +STATIC struct mqpersonal *DoMqueueCreate(const struct mq_attr *attr, const CHAR *mqName, INT32 openFlag, UINT32 mode) +{ + struct mqarray *mqueueCB = NULL; + UINT32 mqueueID; + +#ifdef LOSCFG_KERNEL_IPC_PLIMIT + if (OsIPCLimitMqAlloc() != LOS_OK) { + return (struct mqpersonal *)-1; + } +#endif + UINT32 err = LOS_QueueCreate(NULL, attr->mq_maxmsg, &mqueueID, 0, attr->mq_msgsize); + if (map_errno(err) != ENOERR) { + goto ERROUT; + } + + if (IPC_QUEUE_TABLE[GET_QUEUE_INDEX(mqueueID)].mqcb == NULL) { + mqueueCB = &(IPC_QUEUE_TABLE[GET_QUEUE_INDEX(mqueueID)]); + mqueueCB->mq_id = mqueueID; + } + + if (mqueueCB == NULL) { + errno = EINVAL; + goto ERROUT; + } + + if (SaveMqueueName(mqName, mqueueCB) != LOS_OK) { + goto ERROUT; + } + + if (GetMqueueCBByID(mqueueCB->mq_id, &(mqueueCB->mqcb)) != LOS_OK) { + errno = ENOSPC; + goto ERROUT; + } + + mqueueCB->mq_personal = (struct mqpersonal *)LOS_MemAlloc(OS_SYS_MEM_ADDR, sizeof(struct mqpersonal)); + if (mqueueCB->mq_personal == NULL) { + (VOID)LOS_QueueDelete(mqueueCB->mq_id); + mqueueCB->mqcb->queueHandle = NULL; + mqueueCB->mqcb = NULL; + errno = ENOSPC; + goto ERROUT; + } + + MqueueCBInit(mqueueCB, attr, openFlag, mode); + + return mqueueCB->mq_personal; +ERROUT: + + if ((mqueueCB != NULL) && (mqueueCB->mq_name != NULL)) { + LOS_MemFree(OS_SYS_MEM_ADDR, mqueueCB->mq_name); + mqueueCB->mq_name = NULL; + } +#ifdef LOSCFG_KERNEL_IPC_PLIMIT + OsIPCLimitMqFree(); +#endif + return (struct mqpersonal *)-1; +} + +STATIC struct mqpersonal *DoMqueueOpen(struct mqarray *mqueueCB, INT32 openFlag) +{ + struct mqpersonal *privateMqPersonal = NULL; + + /* already have the same name of g_squeuetable */ + if (mqueueCB->unlinkflag == TRUE) { + errno = EINVAL; + goto ERROUT; + } + /* alloc mqprivate and add to mqarray */ + privateMqPersonal = (struct mqpersonal *)LOS_MemAlloc(OS_SYS_MEM_ADDR, sizeof(struct mqpersonal)); + if (privateMqPersonal == NULL) { + errno = ENOSPC; + goto ERROUT; + } + + privateMqPersonal->mq_next = mqueueCB->mq_personal; + mqueueCB->mq_personal = privateMqPersonal; + + privateMqPersonal->mq_posixdes = mqueueCB; + privateMqPersonal->mq_flags = openFlag; + privateMqPersonal->mq_status = MQ_USE_MAGIC; + privateMqPersonal->mq_refcount = 0; + + return privateMqPersonal; + +ERROUT: + return (struct mqpersonal *)-1; +} + +STATIC INT32 DoMqueueClose(struct mqpersonal *privateMqPersonal) +{ + struct mqarray *mqueueCB = NULL; + struct mqpersonal *tmp = NULL; + + mqueueCB = privateMqPersonal->mq_posixdes; + if (mqueueCB == NULL || mqueueCB->mq_personal == NULL) { + errno = EBADF; + return LOS_NOK; + } + + /* find the personal and remove */ + if (mqueueCB->mq_personal == privateMqPersonal) { + mqueueCB->mq_personal = privateMqPersonal->mq_next; + } else { + for (tmp = mqueueCB->mq_personal; tmp->mq_next != NULL; tmp = tmp->mq_next) { + if (tmp->mq_next == privateMqPersonal) { + break; + } + } + if (tmp->mq_next == NULL) { + errno = EBADF; + return LOS_NOK; + } + tmp->mq_next = privateMqPersonal->mq_next; + } + /* flag no use */ + privateMqPersonal->mq_status = 0; + + /* free the personal */ + (VOID)LOS_MemFree(OS_SYS_MEM_ADDR, privateMqPersonal); + + if ((mqueueCB->unlinkflag == TRUE) && (mqueueCB->mq_personal == NULL)) { + return DoMqueueDelete(mqueueCB); + } + return LOS_OK; +} + +/* Translate a sysFd into privateMqPersonal */ +STATIC struct mqpersonal *MqGetPrivDataBuff(mqd_t personal) +{ + INT32 sysFd = (INT32)personal; + INT32 id = sysFd - MQUEUE_FD_OFFSET; + + /* Filter illegal id */ + if ((id < 0) || (id >= MAX_MQ_FD)) { + errno = EBADF; + return NULL; + } + return IPC_QUEUE_MQ_PRIV_BUF[id]; +} + +/** + * Alloc sysFd, storage mq private data, set using bit. + * + * @param maxfdp: Maximum allowed application of mqueue sysFd. + * @param fdset: Mqueue sysFd bit map. + * @param privateMqPersonal: Private data. + * @return the index of the new fd; -1 on error + */ +STATIC INT32 MqAllocSysFd(int maxfdp, struct mqpersonal *privateMqPersonal) +{ + INT32 i; + fd_set *fdset = &IPC_QUEUE_FD_SET; + for (i = 0; i < maxfdp; i++) { + /* sysFd: used bit setting, and get the index of swtmrID buffer */ + if (fdset && !(FD_ISSET(i + MQUEUE_FD_OFFSET, fdset))) { + FD_SET(i + MQUEUE_FD_OFFSET, fdset); + if (!IPC_QUEUE_MQ_PRIV_BUF[i]) { + IPC_QUEUE_MQ_PRIV_BUF[i] = privateMqPersonal; + return i + MQUEUE_FD_OFFSET; + } + } + } + return -1; +} + +STATIC VOID MqFreeSysFd(mqd_t personal) +{ + INT32 sysFd = (INT32)personal; + fd_set *fdset = &IPC_QUEUE_FD_SET; + if (fdset && FD_ISSET(sysFd, fdset)) { + FD_CLR(sysFd, fdset); + IPC_QUEUE_MQ_PRIV_BUF[sysFd - MQUEUE_FD_OFFSET] = NULL; + } +} + +/* Mqueue fd reference count */ +void MqueueRefer(int sysFd) +{ + struct mqarray *mqueueCB = NULL; + struct mqpersonal *privateMqPersonal = NULL; + + (VOID)pthread_mutex_lock(&IPC_QUEUE_MUTEX); + /* Get the personal sysFd and reset personal fd -1 */ + privateMqPersonal = MqGetPrivDataBuff((mqd_t)sysFd); + if (privateMqPersonal == NULL) { + goto OUT_UNLOCK; + } + mqueueCB = privateMqPersonal->mq_posixdes; + if (mqueueCB == NULL) { + goto OUT_UNLOCK; + } + + privateMqPersonal->mq_refcount++; +OUT_UNLOCK: + (VOID)pthread_mutex_unlock(&IPC_QUEUE_MUTEX); + return; +} + +STATIC INT32 MqTryClose(struct mqpersonal *privateMqPersonal) +{ + struct mqarray *mqueueCB = NULL; + mqueueCB = privateMqPersonal->mq_posixdes; + if (mqueueCB == NULL) { + errno = ENFILE; + return false; + } + + if (privateMqPersonal->mq_refcount == 0) { + return TRUE; + } + privateMqPersonal->mq_refcount--; + return FALSE; +} + +/* Set the mode data bit,for consumer's mode comparing. */ +STATIC INT32 MqueueModeAnalysisSet(struct mqpersonal *privateMqPersonal) +{ + UINT32 mode; + UINT32 intSave; + User *user = NULL; + struct mqarray *mqueueCB = NULL; + + if ((INT32)(UINTPTR)privateMqPersonal < 0) { + return -1; + } + /* Get mqueueCB of first time creating mqueue */ + mqueueCB = privateMqPersonal->mq_posixdes; + if (mqueueCB == NULL) { + errno = ENFILE; + return -1; + } + + mode = mqueueCB->mq_personal->mq_mode; + /* Set mqueue gid uid */ + SCHEDULER_LOCK(intSave); + user = OsCurrUserGet(); + mqueueCB->euid = user->effUserID; + mqueueCB->egid = user->effGid; + SCHEDULER_UNLOCK(intSave); + + /* Set mode data bit */ + if (mode & S_IRUSR) { + mqueueCB->mode_data.usr |= S_IRUSR; + } + if (mode & S_IWUSR) { + mqueueCB->mode_data.usr |= S_IWUSR; + } + if (mode & S_IRGRP) { + mqueueCB->mode_data.grp |= S_IRGRP; + } + if (mode & S_IWGRP) { + mqueueCB->mode_data.grp |= S_IWGRP; + } + if (mode & S_IROTH) { + mqueueCB->mode_data.oth |= S_IROTH; + } + if (mode & S_IWOTH) { + mqueueCB->mode_data.oth |= S_IWOTH; + } + return 0; +} + +STATIC INT32 GetPermissionOfVisitor(struct mqarray *mqueueCB) +{ + uid_t euid; + gid_t egid; + UINT32 intSave; + User *user = NULL; + + if (mqueueCB == NULL) { + errno = ENOENT; + return -EPERM; + } + + /* Get the visitor process euid and egid */ + SCHEDULER_LOCK(intSave); + user = OsCurrUserGet(); + euid = user->effUserID; + egid = user->effGid; + SCHEDULER_UNLOCK(intSave); + + /* root */ + if (euid == 0) { + return ENOERR; + } + if (euid == mqueueCB->euid) { /* usr */ + if (!((mqueueCB->mode_data.usr & S_IRUSR) || (mqueueCB->mode_data.usr & S_IWUSR))) { + errno = EACCES; + goto ERR_OUT; + } + } else if (egid == mqueueCB->egid) { /* grp */ + if (!((mqueueCB->mode_data.grp & S_IRGRP) || (mqueueCB->mode_data.grp & S_IWGRP))) { + errno = EACCES; + goto ERR_OUT; + } + } else { /* oth */ + if (!((mqueueCB->mode_data.oth & S_IROTH) || (mqueueCB->mode_data.oth & S_IWOTH))) { + errno = EACCES; + goto ERR_OUT; + } + } + return ENOERR; + +ERR_OUT: + return -EPERM; +} + +STATIC INT32 GetMqueueAttr(struct mq_attr *defaultAttr, struct mq_attr *attr) +{ + if (attr != NULL) { + if (LOS_ArchCopyFromUser(defaultAttr, attr, sizeof(struct mq_attr))) { + errno = EFAULT; + return -1; + } + if ((defaultAttr->mq_maxmsg < 0) || (defaultAttr->mq_maxmsg > (long int)USHRT_MAX) || + (defaultAttr->mq_msgsize < 0) || (defaultAttr->mq_msgsize > (long int)(USHRT_MAX - sizeof(UINT32)))) { + errno = EINVAL; + return -1; + } + } + return 0; +} + +mqd_t mq_open(const char *mqName, int openFlag, ...) +{ + struct mqarray *mqueueCB = NULL; + struct mqpersonal *privateMqPersonal = (struct mqpersonal *)-1; + struct mq_attr *attr = NULL; + struct mq_attr defaultAttr = { 0, MQ_MAX_MSG_NUM, MQ_MAX_MSG_LEN, 0 }; + va_list ap; + int sysFd; + mqd_t mqFd = -1; + unsigned int mode = 0; + + if (MqNameCheck(mqName) == -1) { + return (mqd_t)-1; + } + + (VOID)pthread_mutex_lock(&IPC_QUEUE_MUTEX); + mqueueCB = GetMqueueCBByName(mqName); + if ((UINT32)openFlag & (UINT32)O_CREAT) { + if (mqueueCB != NULL) { + if (((UINT32)openFlag & (UINT32)O_EXCL)) { + errno = EEXIST; + goto OUT; + } + privateMqPersonal = DoMqueueOpen(mqueueCB, openFlag); + } else { + va_start(ap, openFlag); + mode = va_arg(ap, unsigned int); + attr = va_arg(ap, struct mq_attr *); + va_end(ap); + + if (GetMqueueAttr(&defaultAttr, attr)) { + goto OUT; + } + privateMqPersonal = DoMqueueCreate(&defaultAttr, mqName, openFlag, mode); + } + /* Set mode data bit ,just for the first node */ + if (MqueueModeAnalysisSet(privateMqPersonal)) { + if ((INT32)(UINTPTR)privateMqPersonal > 0) { + (VOID)DoMqueueClose(privateMqPersonal); + } + goto OUT; + } + } else { + if (GetPermissionOfVisitor(mqueueCB)) { + goto OUT; + } + privateMqPersonal = DoMqueueOpen(mqueueCB, openFlag); + } + + if ((INT32)(UINTPTR)privateMqPersonal > 0) { + /* alloc sysFd */ + sysFd = MqAllocSysFd(MAX_MQ_FD, privateMqPersonal); + if (sysFd == -1) { + /* there are no more mq sysFd to use, close the personal */ + (VOID)DoMqueueClose(privateMqPersonal); + errno = ENFILE; + } + mqFd = (mqd_t)sysFd; + } +OUT: + (VOID)pthread_mutex_unlock(&IPC_QUEUE_MUTEX); + return mqFd; +} + +int mq_close(mqd_t personal) +{ + INT32 ret = -1; + struct mqpersonal *privateMqPersonal = NULL; + + (VOID)pthread_mutex_lock(&IPC_QUEUE_MUTEX); + + /* Get the personal sysFd and reset personal fd -1 */ + privateMqPersonal = MqGetPrivDataBuff(personal); + if (privateMqPersonal == NULL) { + goto OUT_UNLOCK; + } + + if (privateMqPersonal->mq_status != MQ_USE_MAGIC) { + errno = EBADF; + goto OUT_UNLOCK; + } + + if (!MqTryClose(privateMqPersonal)) { + ret = 0; + goto OUT_UNLOCK; + } + + ret = DoMqueueClose(privateMqPersonal); + if (ret < 0) { + goto OUT_UNLOCK; + } + MqFreeSysFd(personal); + +OUT_UNLOCK: + (VOID)pthread_mutex_unlock(&IPC_QUEUE_MUTEX); + return ret; +} + +int OsMqGetAttr(mqd_t personal, struct mq_attr *mqAttr) +{ + struct mqarray *mqueueCB = NULL; + struct mqpersonal *privateMqPersonal = NULL; + + privateMqPersonal = MqGetPrivDataBuff(personal); + if (privateMqPersonal == NULL) { + return -1; + } + + if (mqAttr == NULL) { + errno = EINVAL; + return -1; + } + + (VOID)pthread_mutex_lock(&IPC_QUEUE_MUTEX); + if (privateMqPersonal->mq_status != MQ_USE_MAGIC) { + errno = EBADF; + (VOID)pthread_mutex_unlock(&IPC_QUEUE_MUTEX); + return -1; + } + + mqueueCB = privateMqPersonal->mq_posixdes; + mqAttr->mq_maxmsg = mqueueCB->mqcb->queueLen; + mqAttr->mq_msgsize = mqueueCB->mqcb->queueSize - sizeof(UINT32); + mqAttr->mq_curmsgs = mqueueCB->mqcb->readWriteableCnt[OS_QUEUE_READ]; + mqAttr->mq_flags = privateMqPersonal->mq_flags; + (VOID)pthread_mutex_unlock(&IPC_QUEUE_MUTEX); + return 0; +} + +int OsMqSetAttr(mqd_t personal, const struct mq_attr *mqSetAttr, struct mq_attr *mqOldAttr) +{ + struct mqpersonal *privateMqPersonal = NULL; + + privateMqPersonal = MqGetPrivDataBuff(personal); + if (privateMqPersonal == NULL) { + return -1; + } + + if (mqSetAttr == NULL) { + errno = EINVAL; + return -1; + } + + (VOID)pthread_mutex_lock(&IPC_QUEUE_MUTEX); + if (privateMqPersonal->mq_status != MQ_USE_MAGIC) { + errno = EBADF; + (VOID)pthread_mutex_unlock(&IPC_QUEUE_MUTEX); + return -1; + } + + if (mqOldAttr != NULL) { + (VOID)OsMqGetAttr(personal, mqOldAttr); + } + + privateMqPersonal->mq_flags = (INT32)((UINT32)privateMqPersonal->mq_flags & (UINT32)(~FNONBLOCK)); /* clear */ + if (((UINT32)mqSetAttr->mq_flags & (UINT32)FNONBLOCK) == (UINT32)FNONBLOCK) { + privateMqPersonal->mq_flags = (INT32)((UINT32)privateMqPersonal->mq_flags | (UINT32)FNONBLOCK); + } + (VOID)pthread_mutex_unlock(&IPC_QUEUE_MUTEX); + return 0; +} + +int mq_getsetattr(mqd_t mqd, const struct mq_attr *new, struct mq_attr *old) +{ + if (new == NULL) { + return OsMqGetAttr(mqd, old); + } + return OsMqSetAttr(mqd, new, old); +} + +int mq_unlink(const char *mqName) +{ + INT32 ret = 0; + struct mqarray *mqueueCB = NULL; + + if (MqNameCheck(mqName) == -1) { + return -1; + } + + (VOID)pthread_mutex_lock(&IPC_QUEUE_MUTEX); + mqueueCB = GetMqueueCBByName(mqName); + if (mqueueCB == NULL) { + errno = ENOENT; + goto ERROUT_UNLOCK; + } + + if (mqueueCB->mq_personal != NULL) { + mqueueCB->unlinkflag = TRUE; + } else if (mqueueCB->unlink_ref == 0) { + ret = DoMqueueDelete(mqueueCB); + } + + (VOID)pthread_mutex_unlock(&IPC_QUEUE_MUTEX); + return ret; + +ERROUT_UNLOCK: + (VOID)pthread_mutex_unlock(&IPC_QUEUE_MUTEX); + return -1; +} + +STATIC INT32 ConvertTimeout(long flags, const struct timespec *absTimeout, UINT64 *ticks) +{ + if ((UINT32)flags & (UINT32)FNONBLOCK) { + *ticks = LOS_NO_WAIT; + return 0; + } + + if (absTimeout == NULL) { + *ticks = LOS_WAIT_FOREVER; + return 0; + } + + if (!ValidTimeSpec(absTimeout)) { + errno = EINVAL; + return -1; + } + + *ticks = OsTimeSpec2Tick(absTimeout); + return 0; +} + +STATIC INLINE BOOL MqParamCheck(mqd_t personal, const char *msg, size_t msgLen) +{ + if (personal < 0) { + return FALSE; + } + + if ((msg == NULL) || (msgLen == 0)) { + errno = EINVAL; + return FALSE; + } + return TRUE; +} + +/* + * Send realtime a signal to process which registered itself + * successfully by mq_notify. + */ +static void MqSendNotify(struct mqarray *mqueueCB) +{ + struct mqnotify *mqnotify = &mqueueCB->mq_notify; + + if ((mqnotify->pid) && (mqueueCB->mqcb->readWriteableCnt[OS_QUEUE_READ] == 0)) { + siginfo_t info; + + switch (mqnotify->notify.sigev_notify) { + case SIGEV_SIGNAL: + /* sends signal */ + /* Create the siginfo structure */ + info.si_signo = mqnotify->notify.sigev_signo; + info.si_code = SI_MESGQ; + info.si_value = mqnotify->notify.sigev_value; + OsDispatch(mqnotify->pid, &info, OS_USER_KILL_PERMISSION); + break; + case SIGEV_NONE: + default: + break; + } + /* after notification unregisters process */ + mqnotify->pid = 0; + } +} + +#define OS_MQ_GOTO_ERROUT_UNLOCK_IF(expr, errcode) \ + if (expr) { \ + errno = errcode; \ + goto ERROUT_UNLOCK; \ + } +#define OS_MQ_GOTO_ERROUT_IF(expr, errcode) \ + if (expr) { \ + errno = errcode; \ + goto ERROUT; \ + } +int mq_timedsend(mqd_t personal, const char *msg, size_t msgLen, unsigned int msgPrio, + const struct timespec *absTimeout) +{ + UINT32 mqueueID, err; + UINT64 absTicks; + struct mqarray *mqueueCB = NULL; + struct mqpersonal *privateMqPersonal = NULL; + + OS_MQ_GOTO_ERROUT_IF(!MqParamCheck(personal, msg, msgLen), errno); + OS_MQ_GOTO_ERROUT_IF(msgPrio > (MQ_PRIO_MAX - 1), EINVAL); + + (VOID)pthread_mutex_lock(&IPC_QUEUE_MUTEX); + privateMqPersonal = MqGetPrivDataBuff(personal); + + OS_MQ_GOTO_ERROUT_UNLOCK_IF(privateMqPersonal == NULL || privateMqPersonal->mq_status != MQ_USE_MAGIC, EBADF); + + mqueueCB = privateMqPersonal->mq_posixdes; + OS_MQ_GOTO_ERROUT_UNLOCK_IF(msgLen > (size_t)(mqueueCB->mqcb->queueSize - sizeof(UINT32)), EMSGSIZE); + + OS_MQ_GOTO_ERROUT_UNLOCK_IF((((UINT32)privateMqPersonal->mq_flags & (UINT32)O_WRONLY) != (UINT32)O_WRONLY) && + (((UINT32)privateMqPersonal->mq_flags & (UINT32)O_RDWR) != (UINT32)O_RDWR), + EBADF); + + OS_MQ_GOTO_ERROUT_UNLOCK_IF(ConvertTimeout(privateMqPersonal->mq_flags, absTimeout, &absTicks) == -1, errno); + mqueueID = mqueueCB->mq_id; + (VOID)pthread_mutex_unlock(&IPC_QUEUE_MUTEX); + + if (LOS_ListEmpty(&mqueueCB->mqcb->readWriteList[OS_QUEUE_READ])) { + MqSendNotify(mqueueCB); + } + + err = LOS_QueueWriteCopy(mqueueID, (VOID *)msg, (UINT32)msgLen, (UINT32)absTicks); + if (map_errno(err) != ENOERR) { + goto ERROUT; + } + return 0; +ERROUT_UNLOCK: + (VOID)pthread_mutex_unlock(&IPC_QUEUE_MUTEX); +ERROUT: + return -1; +} + +ssize_t mq_timedreceive(mqd_t personal, char *msg, size_t msgLen, unsigned int *msgPrio, + const struct timespec *absTimeout) +{ + UINT32 mqueueID, err; + UINT32 receiveLen; + UINT64 absTicks; + struct mqarray *mqueueCB = NULL; + struct mqpersonal *privateMqPersonal = NULL; + + if (!MqParamCheck(personal, msg, msgLen)) { + goto ERROUT; + } + + if (msgPrio != NULL) { + *msgPrio = 0; + } + + (VOID)pthread_mutex_lock(&IPC_QUEUE_MUTEX); + privateMqPersonal = MqGetPrivDataBuff(personal); + if (privateMqPersonal == NULL || privateMqPersonal->mq_status != MQ_USE_MAGIC) { + errno = EBADF; + goto ERROUT_UNLOCK; + } + + mqueueCB = privateMqPersonal->mq_posixdes; + if (msgLen < (size_t)(mqueueCB->mqcb->queueSize - sizeof(UINT32))) { + errno = EMSGSIZE; + goto ERROUT_UNLOCK; + } + + if (((UINT32)privateMqPersonal->mq_flags & (UINT32)O_WRONLY) == (UINT32)O_WRONLY) { + errno = EBADF; + goto ERROUT_UNLOCK; + } + + if (ConvertTimeout(privateMqPersonal->mq_flags, absTimeout, &absTicks) == -1) { + goto ERROUT_UNLOCK; + } + + receiveLen = msgLen; + mqueueID = mqueueCB->mq_id; + (VOID)pthread_mutex_unlock(&IPC_QUEUE_MUTEX); + + err = LOS_QueueReadCopy(mqueueID, (VOID *)msg, &receiveLen, (UINT32)absTicks); + if (map_errno(err) == ENOERR) { + return (ssize_t)receiveLen; + } else { + goto ERROUT; + } + +ERROUT_UNLOCK: + (VOID)pthread_mutex_unlock(&IPC_QUEUE_MUTEX); +ERROUT: + return -1; +} + +/* not support the prio */ +int mq_send(mqd_t personal, const char *msg_ptr, size_t msg_len, unsigned int msg_prio) +{ + return mq_timedsend(personal, msg_ptr, msg_len, msg_prio, NULL); +} + +ssize_t mq_receive(mqd_t personal, char *msg_ptr, size_t msg_len, unsigned int *msg_prio) +{ + return mq_timedreceive(personal, msg_ptr, msg_len, msg_prio, NULL); +} + +STATIC INLINE BOOL MqNotifyParamCheck(mqd_t personal, const struct sigevent *sigev) +{ + if (personal < 0) { + errno = EBADF; + goto ERROUT; + } + + if (sigev != NULL) { + if (sigev->sigev_notify != SIGEV_NONE && sigev->sigev_notify != SIGEV_SIGNAL) { + errno = EINVAL; + goto ERROUT; + } + if (sigev->sigev_notify == SIGEV_SIGNAL && !GOOD_SIGNO(sigev->sigev_signo)) { + errno = EINVAL; + goto ERROUT; + } + } + + return TRUE; +ERROUT: + return FALSE; +} + +int OsMqNotify(mqd_t personal, const struct sigevent *sigev) +{ + struct mqarray *mqueueCB = NULL; + struct mqnotify *mqnotify = NULL; + struct mqpersonal *privateMqPersonal = NULL; + + if (!MqNotifyParamCheck(personal, sigev)) { + goto ERROUT; + } + + (VOID)pthread_mutex_lock(&IPC_QUEUE_MUTEX); + privateMqPersonal = MqGetPrivDataBuff(personal); + if (privateMqPersonal == NULL) { + goto OUT_UNLOCK; + } + + if (privateMqPersonal->mq_status != MQ_USE_MAGIC) { + errno = EBADF; + goto OUT_UNLOCK; + } + + mqueueCB = privateMqPersonal->mq_posixdes; + mqnotify = &mqueueCB->mq_notify; + + if (sigev == NULL) { + if (mqnotify->pid == LOS_GetCurrProcessID()) { + mqnotify->pid = 0; + } + } else if (mqnotify->pid != 0) { + errno = EBUSY; + goto OUT_UNLOCK; + } else { + switch (sigev->sigev_notify) { + case SIGEV_NONE: + mqnotify->notify.sigev_notify = SIGEV_NONE; + break; + case SIGEV_SIGNAL: + mqnotify->notify.sigev_signo = sigev->sigev_signo; + mqnotify->notify.sigev_value = sigev->sigev_value; + mqnotify->notify.sigev_notify = SIGEV_SIGNAL; + break; + default: + break; + } + + mqnotify->pid = LOS_GetCurrProcessID(); + } + + (VOID)pthread_mutex_unlock(&IPC_QUEUE_MUTEX); + return 0; +OUT_UNLOCK: + (VOID)pthread_mutex_unlock(&IPC_QUEUE_MUTEX); +ERROUT: + return -1; +} + +VOID OsMqueueCBDestroy(struct mqarray *queueTable) +{ + if (queueTable == NULL) { + return; + } + + for (UINT32 index = 0; index < LOSCFG_BASE_IPC_QUEUE_LIMIT; index++) { + struct mqarray *mqueueCB = &(queueTable[index]); + if (mqueueCB->mq_name == NULL) { + continue; + } + (VOID)DoMqueueClose(mqueueCB->mq_personal); + } +} +#endif diff --git a/src/kernel_liteos_a/compat/posix/src/posix_memalign.c b/src/kernel_liteos_a/compat/posix/src/posix_memalign.c new file mode 100644 index 00000000..5b93834e --- /dev/null +++ b/src/kernel_liteos_a/compat/posix/src/posix_memalign.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_typedef.h" +#include "los_memory.h" + + +int posix_memalign(void **memAddr, size_t alignment, size_t size) +{ + if ((alignment == 0) || ((alignment & (alignment - 1)) != 0) || ((alignment % sizeof(void *)) != 0)) { + return EINVAL; + } + + *memAddr = LOS_MemAllocAlign(OS_SYS_MEM_ADDR, size, alignment); + if (*memAddr == NULL) { + return ENOMEM; + } + + return ENOERR; +} + diff --git a/src/kernel_liteos_a/compat/posix/src/pprivate.h b/src/kernel_liteos_a/compat/posix/src/pprivate.h new file mode 100644 index 00000000..85f358ef --- /dev/null +++ b/src/kernel_liteos_a/compat/posix/src/pprivate.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _HWLITEOS_POSIX_PPRIVATE_H +#define _HWLITEOS_POSIX_PPRIVATE_H + +#include "los_process.h" +#include "pthread.h" +#include "sys/types.h" +#include "los_sem_pri.h" +#include "los_task_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define PTHREAD_DATA_NAME_MAX 20 +/* + * Thread control data structure + * Per-thread information needed by POSIX + */ +typedef struct { + pthread_attr_t attr; /* Current thread attributes */ + pthread_t id; /* My thread ID */ + LosTaskCB *task; /* pointer to Huawei LiteOS thread object */ + CHAR name[PTHREAD_DATA_NAME_MAX]; /* name string for debugging */ + UINT8 state; /* Thread state */ + UINT8 cancelstate; /* Cancel state of thread */ + volatile UINT8 canceltype; /* Cancel type of thread */ + volatile UINT8 canceled; /* pending cancel flag */ + struct pthread_cleanup_buffer *cancelbuffer; /* stack of cleanup buffers */ + UINT32 freestack; /* stack malloced, must be freed */ + UINT32 stackmem; /* base of stack memory area only valid if freestack == true */ + VOID **thread_data; /* Per-thread data table pointer */ +} _pthread_data; + +/* + * Values for the state field. These are solely concerned with the + * states visible to POSIX. The thread's run state is stored in the + * struct _pthread_data about thread object. + * Note: numerical order here is important, do not rearrange. + */ +#define PTHREAD_STATE_FREE 0 /* This structure is free for reuse */ +#define PTHREAD_STATE_DETACHED 1 /* The thread is running but detached */ +#define PTHREAD_STATE_RUNNING 2 /* The thread is running and will wait to join when it exits */ +#define PTHREAD_STATE_JOIN 3 /* The thread has exited and is waiting to be joined */ +#define PTHREAD_STATE_EXITED 4 /* The thread has exited and is ready to be reaped */ +#define PTHREAD_STATE_ALRDY_JOIN 5 /* The thread state is in join */ + + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/src/kernel_liteos_a/compat/posix/src/pthread.c b/src/kernel_liteos_a/compat/posix/src/pthread.c new file mode 100644 index 00000000..9b939d73 --- /dev/null +++ b/src/kernel_liteos_a/compat/posix/src/pthread.c @@ -0,0 +1,806 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "pprivate.h" +#include "pthread.h" +#include "sched.h" + +#include "stdio.h" +#include "map_error.h" +#include "los_process_pri.h" +#include "los_sched_pri.h" + + +/* + * Array of pthread control structures. A pthread_t object is + * "just" an index into this array. + */ +STATIC _pthread_data g_pthreadData[LOSCFG_BASE_CORE_TSK_LIMIT + 1]; + +/* Count of number of threads that have exited and not been reaped. */ +STATIC INT32 g_pthreadsExited = 0; + +/* this is to protect the pthread data */ +STATIC pthread_mutex_t g_pthreadsDataMutex = PTHREAD_MUTEX_INITIALIZER; + +/* pointed to by PTHREAD_CANCELED */ +UINTPTR g_pthreadCanceledDummyVar; + +/* + * Private version of pthread_self() that returns a pointer to our internal + * control structure. + */ +_pthread_data *pthread_get_self_data(void) +{ + UINT32 runningTaskPID = ((LosTaskCB *)(OsCurrTaskGet()))->taskID; + _pthread_data *data = &g_pthreadData[runningTaskPID]; + + return data; +} + +_pthread_data *pthread_get_data(pthread_t id) +{ + _pthread_data *data = NULL; + + if (OS_TID_CHECK_INVALID(id)) { + return NULL; + } + + data = &g_pthreadData[id]; + /* Check that this is a valid entry */ + if ((data->state == PTHREAD_STATE_FREE) || (data->state == PTHREAD_STATE_EXITED)) { + return NULL; + } + + /* Check that the entry matches the id */ + if (data->id != id) { + return NULL; + } + + /* Return the pointer */ + return data; +} + +/* + * Check whether there is a cancel pending and if so, whether + * cancellations are enabled. We do it in this order to reduce the + * number of tests in the common case - when no cancellations are + * pending. We make this inline so it can be called directly below for speed + */ +STATIC INT32 CheckForCancel(VOID) +{ + _pthread_data *self = pthread_get_self_data(); + if (self->canceled && (self->cancelstate == PTHREAD_CANCEL_ENABLE)) { + return 1; + } + return 0; +} + +STATIC VOID ProcessUnusedStatusTask(_pthread_data *data) +{ + data->state = PTHREAD_STATE_FREE; + (VOID)memset_s(data, sizeof(_pthread_data), 0, sizeof(_pthread_data)); +} + +/* + * This function is called to tidy up and dispose of any threads that have + * exited. This work must be done from a thread other than the one exiting. + * Note: this function must be called with pthread_mutex locked. + */ +STATIC VOID PthreadReap(VOID) +{ + UINT32 i; + _pthread_data *data = NULL; + /* + * Loop over the thread table looking for exited threads. The + * g_pthreadsExited counter springs us out of this once we have + * found them all (and keeps us out if there are none to do). + */ + for (i = 0; g_pthreadsExited && (i < g_taskMaxNum); i++) { + data = &g_pthreadData[i]; + if (data->state == PTHREAD_STATE_EXITED) { + /* the Huawei LiteOS not delete the dead TCB,so need to delete the TCB */ + (VOID)LOS_TaskDelete(data->task->taskID); + if (data->task->taskStatus & OS_TASK_STATUS_UNUSED) { + ProcessUnusedStatusTask(data); + g_pthreadsExited--; + } + } + } +} + +STATIC VOID SetPthreadAttr(const _pthread_data *self, const pthread_attr_t *attr, pthread_attr_t *outAttr) +{ + /* + * Set use_attr to the set of attributes we are going to + * actually use. Either those passed in, or the default set. + */ + if (attr == NULL) { + (VOID)pthread_attr_init(outAttr); + } else { + (VOID)memcpy_s(outAttr, sizeof(pthread_attr_t), attr, sizeof(pthread_attr_t)); + } + + /* + * If the stack size is not valid, we can assume that it is at + * least PTHREAD_STACK_MIN bytes. + */ + if (!outAttr->stacksize_set) { + outAttr->stacksize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + } + if (outAttr->inheritsched == PTHREAD_INHERIT_SCHED) { + if (self->task == NULL) { + outAttr->schedparam.sched_priority = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + } else { + outAttr->schedpolicy = self->attr.schedpolicy; + outAttr->schedparam = self->attr.schedparam; + outAttr->scope = self->attr.scope; + } + } +} + +STATIC VOID SetPthreadDataAttr(const pthread_attr_t *userAttr, const pthread_t threadID, + LosTaskCB *taskCB, _pthread_data *created) +{ + created->attr = *userAttr; + created->id = threadID; + created->task = taskCB; + created->state = (userAttr->detachstate == PTHREAD_CREATE_JOINABLE) ? + PTHREAD_STATE_RUNNING : PTHREAD_STATE_DETACHED; + /* need to confirmation */ + created->cancelstate = PTHREAD_CANCEL_ENABLE; + created->canceltype = PTHREAD_CANCEL_DEFERRED; + created->cancelbuffer = NULL; + created->canceled = 0; + created->freestack = 0; /* no use default : 0 */ + created->stackmem = taskCB->topOfStack; + created->thread_data = NULL; +} + +STATIC UINT32 InitPthreadData(pthread_t threadID, pthread_attr_t *userAttr, + const CHAR name[], size_t len) +{ + errno_t err; + UINT32 ret = LOS_OK; + LosTaskCB *taskCB = OS_TCB_FROM_TID(threadID); + _pthread_data *created = &g_pthreadData[threadID]; + + err = strncpy_s(created->name, sizeof(created->name), name, len); + if (err != EOK) { + PRINT_ERR("%s: %d, err: %d\n", __FUNCTION__, __LINE__, err); + return LOS_NOK; + } + userAttr->stacksize = taskCB->stackSize; + err = OsSetTaskName(taskCB, created->name, FALSE); + if (err != LOS_OK) { + PRINT_ERR("%s: %d, err: %d\n", __FUNCTION__, __LINE__, err); + return LOS_NOK; + } +#ifdef LOSCFG_KERNEL_SMP + if (userAttr->cpuset.__bits[0] > 0) { + taskCB->cpuAffiMask = (UINT16)userAttr->cpuset.__bits[0]; + } +#endif + + SetPthreadDataAttr(userAttr, threadID, taskCB, created); + return ret; +} + +int pthread_create(pthread_t *thread, const pthread_attr_t *attr, + void *(*startRoutine)(void *), void *arg) +{ + pthread_attr_t userAttr; + UINT32 ret; + CHAR name[PTHREAD_DATA_NAME_MAX] = {0}; + STATIC UINT16 pthreadNumber = 1; + TSK_INIT_PARAM_S taskInitParam = {0}; + UINT32 taskHandle; + _pthread_data *self = pthread_get_self_data(); + + if ((thread == NULL) || (startRoutine == NULL)) { + return EINVAL; + } + + SetPthreadAttr(self, attr, &userAttr); + + (VOID)snprintf_s(name, sizeof(name), sizeof(name) - 1, "pth%02d", pthreadNumber); + pthreadNumber++; + + taskInitParam.pcName = name; + taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)startRoutine; + taskInitParam.auwArgs[0] = (UINTPTR)arg; + taskInitParam.usTaskPrio = (UINT16)userAttr.schedparam.sched_priority; + taskInitParam.uwStackSize = userAttr.stacksize; + if (OsProcessIsUserMode(OsCurrProcessGet())) { + taskInitParam.processID = (UINTPTR)OsGetKernelInitProcess(); + } else { + taskInitParam.processID = (UINTPTR)OsCurrProcessGet(); + } + if (userAttr.detachstate == PTHREAD_CREATE_DETACHED) { + taskInitParam.uwResved = LOS_TASK_STATUS_DETACHED; + } else { + /* Set the pthread default joinable */ + taskInitParam.uwResved = LOS_TASK_ATTR_JOINABLE; + } + + PthreadReap(); + ret = LOS_TaskCreateOnly(&taskHandle, &taskInitParam); + if (ret == LOS_OK) { + *thread = (pthread_t)taskHandle; + ret = InitPthreadData(*thread, &userAttr, name, PTHREAD_DATA_NAME_MAX); + if (ret != LOS_OK) { + goto ERROR_OUT_WITH_TASK; + } + (VOID)LOS_SetTaskScheduler(taskHandle, SCHED_RR, taskInitParam.usTaskPrio); + } + + if (ret == LOS_OK) { + return ENOERR; + } else { + goto ERROR_OUT; + } + +ERROR_OUT_WITH_TASK: + (VOID)LOS_TaskDelete(taskHandle); +ERROR_OUT: + *thread = (pthread_t)-1; + + return map_errno(ret); +} + +void pthread_exit(void *retVal) +{ + _pthread_data *self = pthread_get_self_data(); + UINT32 intSave; + + if (pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, (int *)0) != ENOERR) { + PRINT_ERR("%s: %d failed\n", __FUNCTION__, __LINE__); + } + + if (pthread_mutex_lock(&g_pthreadsDataMutex) != ENOERR) { + PRINT_ERR("%s: %d failed\n", __FUNCTION__, __LINE__); + } + + self->task->joinRetval = retVal; + /* + * If we are already detached, go to EXITED state, otherwise + * go into JOIN state. + */ + if (self->state == PTHREAD_STATE_DETACHED) { + self->state = PTHREAD_STATE_EXITED; + g_pthreadsExited++; + } else { + self->state = PTHREAD_STATE_JOIN; + } + + if (pthread_mutex_unlock(&g_pthreadsDataMutex) != ENOERR) { + PRINT_ERR("%s: %d failed\n", __FUNCTION__, __LINE__); + } + SCHEDULER_LOCK(intSave); + /* If the thread is the highest thread,it can't schedule in LOS_SemPost. */ + OsTaskJoinPostUnsafe(self->task); + if (self->task->taskStatus & OS_TASK_STATUS_RUNNING) { + OsSchedResched(); + } + SCHEDULER_UNLOCK(intSave); +} + +STATIC INT32 ProcessByJoinState(_pthread_data *joined) +{ + UINT32 intSave; + INT32 err = 0; + UINT32 ret; + switch (joined->state) { + case PTHREAD_STATE_RUNNING: + /* The thread is still running, we must wait for it. */ + SCHEDULER_LOCK(intSave); + ret = OsTaskJoinPendUnsafe(joined->task); + SCHEDULER_UNLOCK(intSave); + if (ret != LOS_OK) { + err = (INT32)ret; + break; + } + + joined->state = PTHREAD_STATE_ALRDY_JOIN; + break; + /* + * The thread has become unjoinable while we waited, so we + * fall through to complain. + */ + case PTHREAD_STATE_FREE: + case PTHREAD_STATE_DETACHED: + case PTHREAD_STATE_EXITED: + /* None of these may be joined. */ + err = EINVAL; + break; + case PTHREAD_STATE_ALRDY_JOIN: + err = EINVAL; + break; + case PTHREAD_STATE_JOIN: + break; + default: + PRINT_ERR("state: %u is not supported\n", (UINT32)joined->state); + break; + } + return err; +} + +int pthread_join(pthread_t thread, void **retVal) +{ + INT32 err; + UINT8 status; + _pthread_data *self = NULL; + _pthread_data *joined = NULL; + + /* Check for cancellation first. */ + pthread_testcancel(); + + /* Dispose of any dead threads */ + (VOID)pthread_mutex_lock(&g_pthreadsDataMutex); + PthreadReap(); + (VOID)pthread_mutex_unlock(&g_pthreadsDataMutex); + + self = pthread_get_self_data(); + joined = pthread_get_data(thread); + if (joined == NULL) { + return ESRCH; + } + status = joined->state; + + if (joined == self) { + return EDEADLK; + } + + err = ProcessByJoinState(joined); + (VOID)pthread_mutex_lock(&g_pthreadsDataMutex); + + if (!err) { + /* + * Here, we know that joinee is a thread that has exited and is + * ready to be joined. + */ + if (retVal != NULL) { + /* Get the retVal */ + *retVal = joined->task->joinRetval; + } + + /* Set state to exited. */ + joined->state = PTHREAD_STATE_EXITED; + g_pthreadsExited++; + + /* Dispose of any dead threads */ + PthreadReap(); + } else { + joined->state = status; + } + + (VOID)pthread_mutex_unlock(&g_pthreadsDataMutex); + /* Check for cancellation before returning */ + pthread_testcancel(); + + return err; +} + +/* + * Set the detachstate of the thread to "detached". The thread then does not + * need to be joined and its resources will be freed when it exits. + */ +int pthread_detach(pthread_t thread) +{ + int ret = 0; + UINT32 intSave; + + _pthread_data *detached = NULL; + + if (pthread_mutex_lock(&g_pthreadsDataMutex) != ENOERR) { + ret = ESRCH; + } + detached = pthread_get_data(thread); + if (detached == NULL) { + ret = ESRCH; /* No such thread */ + } else if (detached->state == PTHREAD_STATE_DETACHED) { + ret = EINVAL; /* Already detached! */ + } else if (detached->state == PTHREAD_STATE_JOIN) { + detached->state = PTHREAD_STATE_EXITED; + g_pthreadsExited++; + } else { + /* Set state to detached and kick any joinees to make them return. */ + SCHEDULER_LOCK(intSave); + if (!(detached->task->taskStatus & OS_TASK_STATUS_EXIT)) { + ret = OsTaskSetDetachUnsafe(detached->task); + if (ret == ESRCH) { + ret = LOS_OK; + } else if (ret == LOS_OK) { + detached->state = PTHREAD_STATE_DETACHED; + } + } else { + detached->state = PTHREAD_STATE_EXITED; + g_pthreadsExited++; + } + SCHEDULER_UNLOCK(intSave); + } + + /* Dispose of any dead threads */ + PthreadReap(); + if (pthread_mutex_unlock(&g_pthreadsDataMutex) != ENOERR) { + ret = ESRCH; + } + + return ret; +} + +int pthread_setschedparam(pthread_t thread, int policy, const struct sched_param *param) +{ + _pthread_data *data = NULL; + int ret; + + if ((param == NULL) || (param->sched_priority > OS_TASK_PRIORITY_LOWEST)) { + return EINVAL; + } + + if (policy != SCHED_RR) { + return EINVAL; + } + + /* The parameters seem OK, change the thread. */ + ret = pthread_mutex_lock(&g_pthreadsDataMutex); + if (ret != ENOERR) { + return ret; + } + + data = pthread_get_data(thread); + if (data == NULL) { + ret = pthread_mutex_unlock(&g_pthreadsDataMutex); + if (ret != ENOERR) { + return ret; + } + return ESRCH; + } + + /* Only support one policy now */ + data->attr.schedpolicy = SCHED_RR; + data->attr.schedparam = *param; + + ret = pthread_mutex_unlock(&g_pthreadsDataMutex); + if (ret != ENOERR) { + return ret; + } + (VOID)LOS_TaskPriSet((UINT32)thread, (UINT16)param->sched_priority); + + return ENOERR; +} + +int pthread_getschedparam(pthread_t thread, int *policy, struct sched_param *param) +{ + _pthread_data *data = NULL; + int ret; + + if ((policy == NULL) || (param == NULL)) { + return EINVAL; + } + + ret = pthread_mutex_lock(&g_pthreadsDataMutex); + if (ret != ENOERR) { + return ret; + } + + data = pthread_get_data(thread); + if (data == NULL) { + goto ERR_OUT; + } + + *policy = data->attr.schedpolicy; + *param = data->attr.schedparam; + + ret = pthread_mutex_unlock(&g_pthreadsDataMutex); + return ret; +ERR_OUT: + ret = pthread_mutex_unlock(&g_pthreadsDataMutex); + if (ret != ENOERR) { + return ret; + } + return ESRCH; +} + +/* Call initRoutine just the once per control variable. */ +int pthread_once(pthread_once_t *onceControl, void (*initRoutine)(void)) +{ + pthread_once_t old; + int ret; + + if ((onceControl == NULL) || (initRoutine == NULL)) { + return EINVAL; + } + + /* Do a test and set on the onceControl object. */ + ret = pthread_mutex_lock(&g_pthreadsDataMutex); + if (ret != ENOERR) { + return ret; + } + + old = *onceControl; + *onceControl = 1; + + ret = pthread_mutex_unlock(&g_pthreadsDataMutex); + if (ret != ENOERR) { + return ret; + } + /* If the onceControl was zero, call the initRoutine(). */ + if (!old) { + initRoutine(); + } + + return ENOERR; +} + +/* Thread specific data */ +int pthread_key_create(pthread_key_t *key, void (*destructor)(void *)) +{ + (VOID)key; + (VOID)destructor; + PRINT_ERR("[%s] is not support.\n", __FUNCTION__); + return 0; +} + +/* Store the pointer value in the thread-specific data slot addressed by the key. */ +int pthread_setspecific(pthread_key_t key, const void *pointer) +{ + (VOID)key; + (VOID)pointer; + PRINT_ERR("[%s] is not support.\n", __FUNCTION__); + return 0; +} + +/* Retrieve the pointer value in the thread-specific data slot addressed by the key. */ +void *pthread_getspecific(pthread_key_t key) +{ + (VOID)key; + PRINT_ERR("[%s] is not support.\n", __FUNCTION__); + return NULL; +} + +/* + * Set cancel state of current thread to ENABLE or DISABLE. + * Returns old state in *oldState. + */ +int pthread_setcancelstate(int state, int *oldState) +{ + _pthread_data *self = NULL; + int ret; + + if ((state != PTHREAD_CANCEL_ENABLE) && (state != PTHREAD_CANCEL_DISABLE)) { + return EINVAL; + } + + ret = pthread_mutex_lock(&g_pthreadsDataMutex); + if (ret != ENOERR) { + return ret; + } + + self = pthread_get_self_data(); + + if (oldState != NULL) { + *oldState = self->cancelstate; + } + + self->cancelstate = (UINT8)state; + + ret = pthread_mutex_unlock(&g_pthreadsDataMutex); + if (ret != ENOERR) { + return ret; + } + + return ENOERR; +} + +/* + * Set cancel type of current thread to ASYNCHRONOUS or DEFERRED. + * Returns old type in *oldType. + */ +int pthread_setcanceltype(int type, int *oldType) +{ + _pthread_data *self = NULL; + int ret; + + if ((type != PTHREAD_CANCEL_ASYNCHRONOUS) && (type != PTHREAD_CANCEL_DEFERRED)) { + return EINVAL; + } + + ret = pthread_mutex_lock(&g_pthreadsDataMutex); + if (ret != ENOERR) { + return ret; + } + + self = pthread_get_self_data(); + if (oldType != NULL) { + *oldType = self->canceltype; + } + + self->canceltype = (UINT8)type; + + ret = pthread_mutex_unlock(&g_pthreadsDataMutex); + if (ret != ENOERR) { + return ret; + } + + return ENOERR; +} + +STATIC UINT32 DoPthreadCancel(_pthread_data *data) +{ + UINT32 ret = LOS_OK; + UINT32 intSave; + LOS_TaskLock(); + data->canceled = 0; + if ((data->task->taskStatus & OS_TASK_STATUS_EXIT) || (LOS_TaskSuspend(data->task->taskID) != ENOERR)) { + ret = LOS_NOK; + goto OUT; + } + + if (data->task->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) { + SCHEDULER_LOCK(intSave); + OsTaskJoinPostUnsafe(data->task); + SCHEDULER_UNLOCK(intSave); + g_pthreadCanceledDummyVar = (UINTPTR)PTHREAD_CANCELED; + data->task->joinRetval = (VOID *)g_pthreadCanceledDummyVar; + } else if (data->state && !(data->task->taskStatus & OS_TASK_STATUS_UNUSED)) { + data->state = PTHREAD_STATE_EXITED; + g_pthreadsExited++; + PthreadReap(); + } else { + ret = LOS_NOK; + } +OUT: + LOS_TaskUnlock(); + return ret; +} + +int pthread_cancel(pthread_t thread) +{ + _pthread_data *data = NULL; + + if (pthread_mutex_lock(&g_pthreadsDataMutex) != ENOERR) { + PRINT_ERR("%s: %d failed\n", __FUNCTION__, __LINE__); + } + + data = pthread_get_data(thread); + if (data == NULL) { + if (pthread_mutex_unlock(&g_pthreadsDataMutex) != ENOERR) { + PRINT_ERR("%s: %d failed\n", __FUNCTION__, __LINE__); + } + return ESRCH; + } + + data->canceled = 1; + + if ((data->cancelstate == PTHREAD_CANCEL_ENABLE) && + (data->canceltype == PTHREAD_CANCEL_ASYNCHRONOUS)) { + /* + * If the thread has cancellation enabled, and it is in + * asynchronous mode, suspend it and set corresponding thread's status. + * We also release the thread out of any current wait to make it wake up. + */ + if (DoPthreadCancel(data) == LOS_NOK) { + goto ERROR_OUT; + } + } + + /* + * Otherwise the thread has cancellation disabled, in which case + * it is up to the thread to enable cancellation + */ + if (pthread_mutex_unlock(&g_pthreadsDataMutex) != ENOERR) { + PRINT_ERR("%s: %d failed\n", __FUNCTION__, __LINE__); + } + + return ENOERR; +ERROR_OUT: + if (pthread_mutex_unlock(&g_pthreadsDataMutex) != ENOERR) { + PRINT_ERR("%s: %d failed\n", __FUNCTION__, __LINE__); + } + return ESRCH; +} + +/* + * Test for a pending cancellation for the current thread and terminate + * the thread if there is one. + */ +void pthread_testcancel(void) +{ + if (CheckForCancel()) { + /* + * If we have cancellation enabled, and there is a cancellation + * pending, then go ahead and do the deed. + * Exit now with special retVal. pthread_exit() calls the + * cancellation handlers implicitly. + */ + pthread_exit((void *)PTHREAD_CANCELED); + } +} + +/* Get current thread id. */ +pthread_t pthread_self(void) +{ + _pthread_data *data = pthread_get_self_data(); + + return data->id; +} + +/* Compare two thread identifiers. */ +int pthread_equal(pthread_t thread1, pthread_t thread2) +{ + return thread1 == thread2; +} + +void pthread_cleanup_push_inner(struct pthread_cleanup_buffer *buffer, + void (*routine)(void *), void *arg) +{ + (VOID)buffer; + (VOID)routine; + (VOID)arg; + PRINT_ERR("[%s] is not support.\n", __FUNCTION__); + return; +} + +void pthread_cleanup_pop_inner(struct pthread_cleanup_buffer *buffer, int execute) +{ + (VOID)buffer; + (VOID)execute; + PRINT_ERR("[%s] is not support.\n", __FUNCTION__); + return; +} + +/* + * Set the cpu affinity mask for the thread + */ +int pthread_setaffinity_np(pthread_t thread, size_t cpusetsize, const cpu_set_t* cpuset) +{ + INT32 ret = sched_setaffinity(thread, cpusetsize, cpuset); + if (ret == -1) { + return errno; + } else { + return ENOERR; + } +} + +/* + * Get the cpu affinity mask from the thread + */ +int pthread_getaffinity_np(pthread_t thread, size_t cpusetsize, cpu_set_t* cpuset) +{ + INT32 ret = sched_getaffinity(thread, cpusetsize, cpuset); + if (ret == -1) { + return errno; + } else { + return ENOERR; + } +} + diff --git a/src/kernel_liteos_a/compat/posix/src/pthread_attr.c b/src/kernel_liteos_a/compat/posix/src/pthread_attr.c new file mode 100644 index 00000000..0368b7bb --- /dev/null +++ b/src/kernel_liteos_a/compat/posix/src/pthread_attr.c @@ -0,0 +1,277 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "pthread.h" +#include "pprivate.h" + + +int pthread_attr_init(pthread_attr_t *attr) +{ + if (attr == NULL) { + return EINVAL; + } + + attr->detachstate = PTHREAD_CREATE_JOINABLE; + attr->schedpolicy = SCHED_RR; + attr->schedparam.sched_priority = LOSCFG_BASE_CORE_TSK_DEFAULT_PRIO; + attr->inheritsched = PTHREAD_INHERIT_SCHED; + attr->scope = PTHREAD_SCOPE_PROCESS; + attr->stackaddr_set = 0; + attr->stackaddr = NULL; + attr->stacksize_set = 1; + attr->stacksize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + +#ifdef LOSCFG_KERNEL_SMP + attr->cpuset.__bits[0] = 0; +#endif + + return ENOERR; +} + +int pthread_attr_destroy(pthread_attr_t *attr) +{ + if (attr == NULL) { + return EINVAL; + } + + /* Nothing to do here... */ + return ENOERR; +} + +int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachState) +{ + if ((attr != NULL) && ((detachState == PTHREAD_CREATE_JOINABLE) || (detachState == PTHREAD_CREATE_DETACHED))) { + attr->detachstate = (UINT32)detachState; + return ENOERR; + } + + return EINVAL; +} + +int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachState) +{ + if ((attr == NULL) || (detachState == NULL)) { + return EINVAL; + } + + *detachState = (int)attr->detachstate; + + return ENOERR; +} + +int pthread_attr_setscope(pthread_attr_t *attr, int scope) +{ + if (attr == NULL) { + return EINVAL; + } + + if (scope == PTHREAD_SCOPE_PROCESS) { + attr->scope = (unsigned int)scope; + return ENOERR; + } + + if (scope == PTHREAD_SCOPE_SYSTEM) { + return ENOTSUP; + } + + return EINVAL; +} + +int pthread_attr_getscope(const pthread_attr_t *attr, int *scope) +{ + if ((attr == NULL) || (scope == NULL)) { + return EINVAL; + } + + *scope = (int)attr->scope; + + return ENOERR; +} + +int pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit) +{ + if ((attr != NULL) && ((inherit == PTHREAD_INHERIT_SCHED) || (inherit == PTHREAD_EXPLICIT_SCHED))) { + attr->inheritsched = (UINT32)inherit; + return ENOERR; + } + + return EINVAL; +} + +int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inherit) +{ + if ((attr == NULL) || (inherit == NULL)) { + return EINVAL; + } + + *inherit = (int)attr->inheritsched; + + return ENOERR; +} + +int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy) +{ + if ((attr != NULL) && (policy == SCHED_RR)) { + attr->schedpolicy = SCHED_RR; + return ENOERR; + } + + return EINVAL; +} + +int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy) +{ + if ((attr == NULL) || (policy == NULL)) { + return EINVAL; + } + + *policy = (int)attr->schedpolicy; + + return ENOERR; +} + +int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param) +{ + if ((attr == NULL) || (param == NULL)) { + return EINVAL; + } else if ((param->sched_priority < 0) || (param->sched_priority > OS_TASK_PRIORITY_LOWEST)) { + return ENOTSUP; + } + + attr->schedparam = *param; + + return ENOERR; +} + +int pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param) +{ + if ((attr == NULL) || (param == NULL)) { + return EINVAL; + } + + *param = attr->schedparam; + + return ENOERR; +} + +/* + * Set starting address of stack. Whether this is at the start or end of + * the memory block allocated for the stack depends on whether the stack + * grows up or down. + */ +int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackAddr) +{ + if (attr == NULL) { + return EINVAL; + } + + attr->stackaddr_set = 1; + attr->stackaddr = stackAddr; + + return ENOERR; +} + +int pthread_attr_getstackaddr(const pthread_attr_t *attr, void **stackAddr) +{ + if (((attr != NULL) && (stackAddr != NULL)) && attr->stackaddr_set) { + *stackAddr = attr->stackaddr; + return ENOERR; + } + + return EINVAL; /* Stack address not set, return EINVAL. */ +} + +int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stackSize) +{ + /* Reject inadequate stack sizes */ + if ((attr == NULL) || (stackSize < PTHREAD_STACK_MIN)) { + return EINVAL; + } + + attr->stacksize_set = 1; + attr->stacksize = stackSize; + + return ENOERR; +} + +int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stackSize) +{ + /* Reject attempts to get a stack size when one has not been set. */ + if ((attr == NULL) || (stackSize == NULL) || (!attr->stacksize_set)) { + return EINVAL; + } + + *stackSize = attr->stacksize; + + return ENOERR; +} + +/* + * Set the cpu affinity mask + */ +int pthread_attr_setaffinity_np(pthread_attr_t* attr, size_t cpusetsize, const cpu_set_t* cpuset) +{ +#ifdef LOSCFG_KERNEL_SMP + if (attr == NULL) { + return EINVAL; + } + + if ((cpuset == NULL) || (cpusetsize == 0)) { + attr->cpuset.__bits[0] = 0; + return ENOERR; + } + + if ((cpusetsize != sizeof(cpu_set_t)) || (cpuset->__bits[0] > LOSCFG_KERNEL_CPU_MASK)) { + return EINVAL; + } + + attr->cpuset = *cpuset; +#endif + + return ENOERR; +} + +/* + * Get the cpu affinity mask + */ +int pthread_attr_getaffinity_np(const pthread_attr_t* attr, size_t cpusetsize, cpu_set_t* cpuset) +{ +#ifdef LOSCFG_KERNEL_SMP + if ((attr == NULL) || (cpuset == NULL) || (cpusetsize != sizeof(cpu_set_t))) { + return EINVAL; + } + + *cpuset = attr->cpuset; +#endif + + return ENOERR; +} + diff --git a/src/kernel_liteos_a/compat/posix/src/pthread_cond.c b/src/kernel_liteos_a/compat/posix/src/pthread_cond.c new file mode 100644 index 00000000..425d6cc8 --- /dev/null +++ b/src/kernel_liteos_a/compat/posix/src/pthread_cond.c @@ -0,0 +1,348 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "pprivate.h" +#include "pthread.h" +#include "stdlib.h" +#include "time_posix.h" +#include "los_atomic.h" +#include "los_event_pri.h" + + +#define BROADCAST_EVENT 1 +#define COND_COUNTER_STEP 0x0004U +#define COND_FLAGS_MASK 0x0003U +#define COND_COUNTER_MASK (~COND_FLAGS_MASK) + +STATIC INLINE INT32 CondInitCheck(const pthread_cond_t *cond) +{ + if ((cond->event.stEventList.pstPrev == NULL) && + (cond->event.stEventList.pstNext == NULL)) { + return 1; + } + return 0; +} + +int pthread_condattr_getpshared(const pthread_condattr_t *attr, int *shared) +{ + if ((attr == NULL) || (shared == NULL)) { + return EINVAL; + } + + *shared = PTHREAD_PROCESS_PRIVATE; + + return 0; +} + +int pthread_condattr_setpshared(pthread_condattr_t *attr, int shared) +{ + (VOID)attr; + if ((shared != PTHREAD_PROCESS_PRIVATE) && (shared != PTHREAD_PROCESS_SHARED)) { + return EINVAL; + } + + if (shared != PTHREAD_PROCESS_PRIVATE) { + return ENOSYS; + } + + return 0; +} + +int pthread_condattr_destroy(pthread_condattr_t *attr) +{ + if (attr == NULL) { + return EINVAL; + } + + return 0; +} + +int pthread_condattr_init(pthread_condattr_t *attr) +{ + if (attr == NULL) { + return EINVAL; + } + + return 0; +} + +int pthread_cond_destroy(pthread_cond_t *cond) +{ + if (cond == NULL) { + return EINVAL; + } + + if (CondInitCheck(cond)) { + return ENOERR; + } + + if (LOS_EventDestroy(&cond->event) != LOS_OK) { + return EBUSY; + } + if (pthread_mutex_destroy(cond->mutex) != ENOERR) { + PRINT_ERR("%s mutex destroy fail!\n", __FUNCTION__); + return EINVAL; + } + free(cond->mutex); + cond->mutex = NULL; + return ENOERR; +} + +int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) +{ + int ret = ENOERR; + + if (cond == NULL) { + return EINVAL; + } + (VOID)attr; + (VOID)LOS_EventInit(&(cond->event)); + + cond->mutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t)); + if (cond->mutex == NULL) { + return ENOMEM; + } + + (VOID)pthread_mutex_init(cond->mutex, NULL); + + cond->value = 0; + (VOID)pthread_mutex_lock(cond->mutex); + cond->count = 0; + (VOID)pthread_mutex_unlock(cond->mutex); + + return ret; +} + +STATIC VOID PthreadCondValueModify(pthread_cond_t *cond) +{ + UINT32 flags = ((UINT32)cond->value & COND_FLAGS_MASK); + INT32 oldVal, newVal; + + while (true) { + oldVal = cond->value; + newVal = (INT32)(((UINT32)(oldVal - COND_COUNTER_STEP) & COND_COUNTER_MASK) | flags); + if (LOS_AtomicCmpXchg32bits(&cond->value, newVal, oldVal) == 0) { + break; + } + } +} + +int pthread_cond_broadcast(pthread_cond_t *cond) +{ + int ret = ENOERR; + + if (cond == NULL) { + return EINVAL; + } + + (VOID)pthread_mutex_lock(cond->mutex); + if (cond->count > 0) { + cond->count = 0; + (VOID)pthread_mutex_unlock(cond->mutex); + + PthreadCondValueModify(cond); + + (VOID)LOS_EventWrite(&(cond->event), BROADCAST_EVENT); + return ret; + } + (VOID)pthread_mutex_unlock(cond->mutex); + + return ret; +} + +int pthread_cond_signal(pthread_cond_t *cond) +{ + int ret = ENOERR; + + if (cond == NULL) { + return EINVAL; + } + + (VOID)pthread_mutex_lock(cond->mutex); + if (cond->count > 0) { + cond->count--; + (VOID)pthread_mutex_unlock(cond->mutex); + PthreadCondValueModify(cond); + (VOID)OsEventWriteOnce(&(cond->event), 0x01); + + return ret; + } + (VOID)pthread_mutex_unlock(cond->mutex); + + return ret; +} + +STATIC INT32 PthreadCondWaitSub(pthread_cond_t *cond, INT32 value, UINT32 ticks) +{ + EventCond eventCond = { &cond->value, value, ~0x01U }; + /* + * When the scheduling lock is held: + * (1) value is not equal to cond->value, clear the event message and + * do not block the current thread, because other threads is calling pthread_cond_broadcast or + * pthread_cond_signal to modify cond->value and wake up the current thread, + * and others threads will block on the scheduling lock until the current thread releases + * the scheduling lock. + * (2) value is equal to cond->value, block the current thread + * and wait to be awakened by other threads. + */ + return (int)OsEventReadWithCond(&eventCond, &(cond->event), 0x0fU, + LOS_WAITMODE_OR | LOS_WAITMODE_CLR, ticks); +} +STATIC VOID PthreadCountSub(pthread_cond_t *cond) +{ + (VOID)pthread_mutex_lock(cond->mutex); + if (cond->count > 0) { + cond->count--; + } + (VOID)pthread_mutex_unlock(cond->mutex); +} + +STATIC INT32 ProcessReturnVal(pthread_cond_t *cond, INT32 val) +{ + INT32 ret; + switch (val) { + /* 0: event does not occur */ + case 0: + case BROADCAST_EVENT: + ret = ENOERR; + break; + case LOS_ERRNO_EVENT_READ_TIMEOUT: + PthreadCountSub(cond); + ret = ETIMEDOUT; + break; + default: + PthreadCountSub(cond); + ret = EINVAL; + break; + } + return ret; +} + +int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, + const struct timespec *absTime) +{ + UINT32 absTicks; + INT32 ret; + INT32 oldValue; + + pthread_testcancel(); + if ((cond == NULL) || (mutex == NULL) || (absTime == NULL)) { + return EINVAL; + } + + if (CondInitCheck(cond)) { + ret = pthread_cond_init(cond, NULL); + if (ret != ENOERR) { + return ret; + } + } + oldValue = cond->value; + + (VOID)pthread_mutex_lock(cond->mutex); + cond->count++; + (VOID)pthread_mutex_unlock(cond->mutex); + + if ((absTime->tv_sec == 0) && (absTime->tv_nsec == 0)) { + return ETIMEDOUT; + } + + if (!ValidTimeSpec(absTime)) { + return EINVAL; + } + + absTicks = OsTimeSpec2Tick(absTime); + if (pthread_mutex_unlock(mutex) != ENOERR) { + PRINT_ERR("%s: %d failed\n", __FUNCTION__, __LINE__); + } + +#ifndef LOSCFG_ARCH_CORTEX_M7 + ret = PthreadCondWaitSub(cond, oldValue, absTicks); +#else + ret = (INT32)LOS_EventRead(&(cond->event), 0x0f, LOS_WAITMODE_OR | LOS_WAITMODE_CLR, absTicks); +#endif + if (pthread_mutex_lock(mutex) != ENOERR) { + PRINT_ERR("%s: %d failed\n", __FUNCTION__, __LINE__); + } + + ret = ProcessReturnVal(cond, ret); + pthread_testcancel(); + return ret; +} + +int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) +{ + int ret; + int oldValue; + + if ((cond == NULL) || (mutex == NULL)) { + return EINVAL; + } + + if (CondInitCheck(cond)) { + ret = pthread_cond_init(cond, NULL); + if (ret != ENOERR) { + return ret; + } + } + oldValue = cond->value; + + (VOID)pthread_mutex_lock(cond->mutex); + cond->count++; + (VOID)pthread_mutex_unlock(cond->mutex); + + if (pthread_mutex_unlock(mutex) != ENOERR) { + PRINT_ERR("%s: %d failed\n", __FUNCTION__, __LINE__); + } + +#ifndef LOSCFG_ARCH_CORTEX_M7 + ret = PthreadCondWaitSub(cond, oldValue, LOS_WAIT_FOREVER); +#else + ret = (INT32)LOS_EventRead(&(cond->event), 0x0f, LOS_WAITMODE_OR | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER); +#endif + if (pthread_mutex_lock(mutex) != ENOERR) { + PRINT_ERR("%s: %d failed\n", __FUNCTION__, __LINE__); + } + + switch (ret) { + /* 0: event does not occur */ + case 0: + case BROADCAST_EVENT: + ret = ENOERR; + break; + default: + PthreadCountSub(cond); + ret = EINVAL; + break; + } + + return ret; +} + diff --git a/src/kernel_liteos_a/compat/posix/src/pthread_mutex.c b/src/kernel_liteos_a/compat/posix/src/pthread_mutex.c new file mode 100644 index 00000000..35c838bd --- /dev/null +++ b/src/kernel_liteos_a/compat/posix/src/pthread_mutex.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "pthread.h" + + +int pthread_mutexattr_init(pthread_mutexattr_t *attr) +{ + unsigned int ret = LOS_MuxAttrInit(attr); + if (ret != LOS_OK) { + return (int)ret; + } + +#if defined POSIX_MUTEX_DEFAULT_INHERIT + attr->protocol = PTHREAD_PRIO_INHERIT; +#elif defined POSIX_MUTEX_DEFAULT_PROTECT + attr->protocol = PTHREAD_PRIO_PROTECT; +#else + attr->protocol = PTHREAD_PRIO_NONE; +#endif + attr->type = PTHREAD_MUTEX_NORMAL; + return LOS_OK; +} + +int pthread_mutexattr_destroy(pthread_mutexattr_t *attr) +{ + return LOS_MuxAttrDestroy(attr); +} + +int pthread_mutexattr_setprotocol(pthread_mutexattr_t *attr, int protocol) +{ + return LOS_MuxAttrSetProtocol(attr, protocol); +} + +int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *attr, int *protocol) +{ + return LOS_MuxAttrGetProtocol(attr, protocol); +} + +int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *attr, int prioceiling) +{ + return LOS_MuxAttrSetPrioceiling(attr, prioceiling); +} + +int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *attr, int *prioceiling) +{ + return LOS_MuxAttrGetPrioceiling(attr, prioceiling); +} + +int pthread_mutex_setprioceiling(pthread_mutex_t *mutex, int prioceiling, int *oldPrioceiling) +{ + return LOS_MuxSetPrioceiling(mutex, prioceiling, oldPrioceiling); +} + +int pthread_mutex_getprioceiling(const pthread_mutex_t *mutex, int *prioceiling) +{ + return LOS_MuxGetPrioceiling(mutex, prioceiling); +} + +int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *outType) +{ + return LOS_MuxAttrGetType(attr, outType); +} + +int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type) +{ + return LOS_MuxAttrSetType(attr, type); +} + +/* Initialize mutex. If mutexAttr is NULL, use default attributes. */ +int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexAttr) +{ + unsigned int ret = LOS_MuxInit(mutex, mutexAttr); + if ((ret == LOS_OK) && (mutexAttr == NULL)) { +#if defined POSIX_MUTEX_DEFAULT_INHERIT + mutex->attr.protocol = PTHREAD_PRIO_INHERIT; +#elif defined POSIX_MUTEX_DEFAULT_PROTECT + mutex->attr.protocol = PTHREAD_PRIO_PROTECT; +#else + mutex->attr.protocol = PTHREAD_PRIO_NONE; +#endif + mutex->attr.type = PTHREAD_MUTEX_NORMAL; + } + + return (int)ret; +} + +int pthread_mutex_destroy(pthread_mutex_t *mutex) +{ + return LOS_MuxDestroy(mutex); +} + +/* Lock mutex, waiting for it if necessary. */ +int pthread_mutex_lock(pthread_mutex_t *mutex) +{ + return LOS_MuxLock(mutex, LOS_WAIT_FOREVER); +} + +int pthread_mutex_trylock(pthread_mutex_t *mutex) +{ + return LOS_MuxTrylock(mutex); +} + +int pthread_mutex_unlock(pthread_mutex_t *mutex) +{ + return LOS_MuxUnlock(mutex); +} + diff --git a/src/kernel_liteos_a/compat/posix/src/sched.c b/src/kernel_liteos_a/compat/posix/src/sched.c new file mode 100644 index 00000000..7ff7a5a5 --- /dev/null +++ b/src/kernel_liteos_a/compat/posix/src/sched.c @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "sched.h" +#include "map_error.h" +#include "sys/types.h" +#include "unistd.h" +#include "los_task_pri.h" + + +int sched_get_priority_min(int policy) +{ + if (policy != SCHED_RR) { + errno = EINVAL; + return -1; + } + + return OS_TASK_PRIORITY_HIGHEST; +} + +int sched_get_priority_max(int policy) +{ + if (policy != SCHED_RR) { + errno = EINVAL; + return -1; + } + + return OS_TASK_PRIORITY_LOWEST; +} + +/* + * This API is Linux-specific, not conforming to POSIX. + */ +int sched_setaffinity(pid_t pid, size_t set_size, const cpu_set_t* set) +{ +#ifdef LOSCFG_KERNEL_SMP + UINT32 taskID = (UINT32)pid; + UINT32 ret; + + if ((set == NULL) || (set_size != sizeof(cpu_set_t)) || (set->__bits[0] > LOSCFG_KERNEL_CPU_MASK)) { + errno = EINVAL; + return -1; + } + + if (taskID == 0) { + taskID = LOS_CurTaskIDGet(); + if (taskID == LOS_ERRNO_TSK_ID_INVALID) { + errno = EINVAL; + return -1; + } + } + + ret = LOS_TaskCpuAffiSet(taskID, (UINT16)set->__bits[0]); + if (ret != LOS_OK) { + errno = map_errno(ret); + return -1; + } +#endif + + return 0; +} + +/* + * This API is Linux-specific, not conforming to POSIX. + */ +int sched_getaffinity(pid_t pid, size_t set_size, cpu_set_t* set) +{ +#ifdef LOSCFG_KERNEL_SMP + UINT32 taskID = (UINT32)pid; + UINT16 cpuAffiMask; + + if ((set == NULL) || (set_size != sizeof(cpu_set_t))) { + errno = EINVAL; + return -1; + } + + if (taskID == 0) { + taskID = LOS_CurTaskIDGet(); + if (taskID == LOS_ERRNO_TSK_ID_INVALID) { + errno = EINVAL; + return -1; + } + } + + cpuAffiMask = LOS_TaskCpuAffiGet(taskID); + if (cpuAffiMask == 0) { + errno = EINVAL; + return -1; + } + + set->__bits[0] = cpuAffiMask; +#endif + + return 0; +} + +int __sched_cpucount(size_t set_size, const cpu_set_t* set) +{ + INT32 count = 0; + UINT32 i; + + if ((set_size != sizeof(cpu_set_t)) || (set == NULL)) { + return 0; + } + + for (i = 0; i < set_size / sizeof(__CPU_BITTYPE); i++) { + count += __builtin_popcountl(set->__bits[i]); + } + + return count; +} + +int sched_yield() +{ + (void)LOS_TaskYield(); + return 0; +} diff --git a/src/kernel_liteos_a/compat/posix/src/semaphore.c b/src/kernel_liteos_a/compat/posix/src/semaphore.c new file mode 100644 index 00000000..71b8f32b --- /dev/null +++ b/src/kernel_liteos_a/compat/posix/src/semaphore.c @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "semaphore.h" +#include "sys/types.h" +#include "map_error.h" +#include "time_posix.h" + + +/* Initialize semaphore to value, shared is not supported in Huawei LiteOS. */ +int sem_init(sem_t *sem, int shared, unsigned int value) +{ + UINT32 semHandle = 0; + UINT32 ret; + + (VOID)shared; + if ((sem == NULL) || (value > OS_SEM_COUNT_MAX)) { + errno = EINVAL; + return -1; + } + + ret = LOS_SemCreate(value, &semHandle); + if (map_errno(ret) != ENOERR) { + return -1; + } + + sem->sem = GET_SEM(semHandle); + + return 0; +} + +int sem_destroy(sem_t *sem) +{ + UINT32 ret; + + if ((sem == NULL) || (sem->sem == NULL)) { + errno = EINVAL; + return -1; + } + + ret = LOS_SemDelete(sem->sem->semID); + if (map_errno(ret) != ENOERR) { + return -1; + } + return 0; +} + +/* Decrement value if >0 or wait for a post. */ +int sem_wait(sem_t *sem) +{ + UINT32 ret; + + if ((sem == NULL) || (sem->sem == NULL)) { + errno = EINVAL; + return -1; + } + + ret = LOS_SemPend(sem->sem->semID, LOS_WAIT_FOREVER); + if (map_errno(ret) == ENOERR) { + return 0; + } else { + return -1; + } +} + +/* Decrement value if >0, return -1 if not. */ +int sem_trywait(sem_t *sem) +{ + UINT32 ret; + + if ((sem == NULL) || (sem->sem == NULL)) { + errno = EINVAL; + return -1; + } + + ret = LOS_SemPend(sem->sem->semID, LOS_NO_WAIT); + if (map_errno(ret) == ENOERR) { + return 0; + } else { + if ((errno != EINVAL) || (ret == LOS_ERRNO_SEM_UNAVAILABLE)) { + errno = EAGAIN; + } + return -1; + } +} + +int sem_timedwait(sem_t *sem, const struct timespec *timeout) +{ + UINT32 ret; + UINT32 tickCnt; + + if ((sem == NULL) || (sem->sem == NULL)) { + errno = EINVAL; + return -1; + } + + if (!ValidTimeSpec(timeout)) { + errno = EINVAL; + return -1; + } + + tickCnt = OsTimeSpec2Tick(timeout); + ret = LOS_SemPend(sem->sem->semID, tickCnt); + if (map_errno(ret) == ENOERR) { + return 0; + } else { + return -1; + } +} + +int sem_post(sem_t *sem) +{ + UINT32 ret; + + if ((sem == NULL) || (sem->sem == NULL)) { + errno = EINVAL; + return -1; + } + + ret = LOS_SemPost(sem->sem->semID); + if (map_errno(ret) != ENOERR) { + return -1; + } + + return 0; +} + +int sem_getvalue(sem_t *sem, int *currVal) +{ + INT32 val; + + if ((sem == NULL) || (currVal == NULL)) { + errno = EINVAL; + return -1; + } + val = sem->sem->semCount; + if (val < 0) { + val = 0; + } + + *currVal = val; + return 0; +} + +sem_t *sem_open(const char *name, int openFlag, ...) +{ + (VOID)name; + (VOID)openFlag; + errno = ENOSYS; + return NULL; +} + +int sem_close(sem_t *sem) +{ + (VOID)sem; + errno = ENOSYS; + return -1; +} + +int sem_unlink(const char *name) +{ + (VOID)name; + errno = ENOSYS; + return -1; +} + diff --git a/src/kernel_liteos_a/compat/posix/src/socket.c b/src/kernel_liteos_a/compat/posix/src/socket.c new file mode 100644 index 00000000..23d00cf7 --- /dev/null +++ b/src/kernel_liteos_a/compat/posix/src/socket.c @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +#ifdef LOSCFG_NET_LWIP_SACK +#include + +#if !LWIP_COMPAT_SOCKETS + +#define CHECK_NULL_PTR(ptr) do { if (ptr == NULL) { set_errno(EFAULT); return -1; } } while (0) + +int accept(int s, struct sockaddr *addr, socklen_t *addrlen) +{ + return lwip_accept(s, addr, addrlen); +} + +int bind(int s, const struct sockaddr *name, socklen_t namelen) +{ + CHECK_NULL_PTR(name); + if (namelen < sizeof(*name)) { + set_errno(EINVAL); + return -1; + } + return lwip_bind(s, name, namelen); +} + +int shutdown(int s, int how) +{ + return lwip_shutdown(s, how); +} + +int getpeername(int s, struct sockaddr *name, socklen_t *namelen) +{ + CHECK_NULL_PTR(name); + CHECK_NULL_PTR(namelen); + return lwip_getpeername(s, name, namelen); +} + +int getsockname(int s, struct sockaddr *name, socklen_t *namelen) +{ + CHECK_NULL_PTR(name); + CHECK_NULL_PTR(namelen); + return lwip_getsockname(s, name, namelen); +} + +int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) +{ + return lwip_getsockopt(s, level, optname, optval, optlen); +} + +int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen) +{ + return lwip_setsockopt(s, level, optname, optval, optlen); +} + +int closesocket(int s) +{ + return lwip_close(s); +} + +int connect(int s, const struct sockaddr *name, socklen_t namelen) +{ + CHECK_NULL_PTR(name); + if (namelen < sizeof(*name)) { + set_errno(EINVAL); + return -1; + } + return lwip_connect(s, name, namelen); +} + +int listen(int s, int backlog) +{ + return lwip_listen(s, backlog); +} + +ssize_t recv(int s, void *mem, size_t len, int flags) +{ + CHECK_NULL_PTR(mem); + return lwip_recv(s, mem, len, flags); +} + +ssize_t recvfrom(int s, void *mem, size_t len, int flags, + struct sockaddr *from, socklen_t *fromlen) +{ + CHECK_NULL_PTR(mem); + return lwip_recvfrom(s, mem, len, flags, from, fromlen); +} + +ssize_t recvmsg(int s, struct msghdr *message, int flags) +{ + CHECK_NULL_PTR(message); + if (message->msg_iovlen) { + CHECK_NULL_PTR(message->msg_iov); + } + return lwip_recvmsg(s, message, flags); +} + +ssize_t send(int s, const void *dataptr, size_t size, int flags) +{ + CHECK_NULL_PTR(dataptr); + return lwip_send(s, dataptr, size, flags); +} + +ssize_t sendmsg(int s, const struct msghdr *message, int flags) +{ + return lwip_sendmsg(s, message, flags); +} + +ssize_t sendto(int s, const void *dataptr, size_t size, int flags, + const struct sockaddr *to, socklen_t tolen) +{ + CHECK_NULL_PTR(dataptr); + if (to && tolen < sizeof(*to)) { + set_errno(EINVAL); + return -1; + } + return lwip_sendto(s, dataptr, size, flags, to, tolen); +} + +int socket(int domain, int type, int protocol) +{ + return lwip_socket(domain, type, protocol); +} + +const char *inet_ntop(int af, const void *src, char *dst, socklen_t size) +{ + return lwip_inet_ntop(af, src, dst, size); +} + +int inet_pton(int af, const char *src, void *dst) +{ + return lwip_inet_pton(af, src, dst); +} + +#ifndef LWIP_INET_ADDR_FUNC +in_addr_t inet_addr(const char* cp) +{ + return ipaddr_addr(cp); +} +#endif + +#ifndef LWIP_INET_ATON_FUNC +int inet_aton(const char* cp, struct in_addr* inp) +{ + return ip4addr_aton(cp, (ip4_addr_t*)inp); +} +#endif + +#ifndef LWIP_INET_NTOA_FUNC +char* inet_ntoa(struct in_addr in) +{ + return ip4addr_ntoa((const ip4_addr_t*)&(in)); +} +#endif + +#endif /* !LWIP_COMPAT_SOCKETS */ +#endif /* LOSCFG_NET_LWIP_SACK */ \ No newline at end of file diff --git a/src/kernel_liteos_a/compat/posix/src/stdio.c b/src/kernel_liteos_a/compat/posix/src/stdio.c new file mode 100644 index 00000000..f2182d44 --- /dev/null +++ b/src/kernel_liteos_a/compat/posix/src/stdio.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#ifdef LOSCFG_FS_VFS +#include + +off_t _lseek(int fd, off_t offset, int whence) +{ + int ret; + struct file *filep = NULL; + + /* Get the file structure corresponding to the file descriptor. */ + ret = fs_getfilep(fd, &filep); + if (ret < 0) { + /* The errno value has already been set */ + return (off_t)-get_errno(); + } + + /* libc seekdir function should set the whence to SEEK_SET, so we can discard + * the whence argument here */ + if (filep->f_oflags & O_DIRECTORY) { + /* defensive coding */ + if (filep->f_dir == NULL) { + return (off_t)-EINVAL; + } + if (offset == 0) { + rewinddir(filep->f_dir); + } else { + seekdir(filep->f_dir, offset); + } + ret = telldir(filep->f_dir); + if (ret < 0) { + return (off_t)-get_errno(); + } + return ret; + } + + /* Then let file_seek do the real work */ + ret = file_seek(filep, offset, whence); + if (ret < 0) { + return -get_errno(); + } + return ret; +} + +off64_t _lseek64(int fd, int offsetHigh, int offsetLow, off64_t *result, int whence) +{ + off64_t ret; + struct file *filep = NULL; + off64_t offset = ((off64_t)offsetHigh << 32) + (uint)offsetLow; /* 32: offsetHigh is high 32 bits */ + + /* Get the file structure corresponding to the file descriptor. */ + ret = fs_getfilep(fd, &filep); + if (ret < 0) { + /* The errno value has already been set */ + return (off64_t)-get_errno(); + } + + /* libc seekdir function should set the whence to SEEK_SET, so we can discard + * the whence argument here */ + if (filep->f_oflags & O_DIRECTORY) { + /* defensive coding */ + if (filep->f_dir == NULL) { + return (off64_t)-EINVAL; + } + if (offsetLow == 0) { + rewinddir(filep->f_dir); + } else { + seekdir(filep->f_dir, offsetLow); + } + ret = telldir(filep->f_dir); + if (ret < 0) { + return (off64_t)-get_errno(); + } + goto out; + } + + /* Then let file_seek do the real work */ + ret = file_seek64(filep, offset, whence); + if (ret < 0) { + return (off64_t)-get_errno(); + } + +out: + *result = ret; + + return 0; +} + +#endif diff --git a/src/kernel_liteos_a/compat/posix/src/stdlib.c b/src/kernel_liteos_a/compat/posix/src/stdlib.c new file mode 100644 index 00000000..cbab4f7d --- /dev/null +++ b/src/kernel_liteos_a/compat/posix/src/stdlib.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include "los_printf.h" +#include "los_exc.h" + +char *getenv(const char *name) +{ + return NULL; +} + +void srand(unsigned s) +{ + return srandom(s); +} + +int rand(void) +{ + return random(); +} + +void _exit(int status) +{ + PRINT_ERR("%s NOT SUPPORT\n", __FUNCTION__); + errno = ENOSYS; + while (1); +} + +void exit(int status) +{ + PRINT_ERR("%s NOT SUPPORT\n", __FUNCTION__); + errno = ENOSYS; + while (1); +} + +void abort(void) +{ + LOS_Panic("System was being aborted\n"); + while (1); +} diff --git a/src/kernel_liteos_a/compat/posix/src/time.c b/src/kernel_liteos_a/compat/posix/src/time.c new file mode 100644 index 00000000..c7e6521f --- /dev/null +++ b/src/kernel_liteos_a/compat/posix/src/time.c @@ -0,0 +1,1215 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "time.h" +#include "stdint.h" +#include "stdio.h" +#include "sys/times.h" +#include "time_posix.h" +#include "unistd.h" +#ifdef LOSCFG_SECURITY_CAPABILITY +#include "capability_api.h" +#endif +#include "los_signal.h" +#ifdef LOSCFG_KERNEL_VDSO +#include "los_vdso.h" +#endif +#ifdef LOSCFG_SECURITY_VID +#include "vid_api.h" +#endif +#include "user_copy.h" +#include "los_process_pri.h" +#include "los_swtmr_pri.h" +#include "los_sys_pri.h" + +#define CPUCLOCK_PERTHREAD_MASK 4 +#define CPUCLOCK_ID_OFFSET 3 + +/* + * Do a time package defined return. This requires the error code + * to be placed in errno, and if it is non-zero, -1 returned as the + * result of the function. This also gives us a place to put any + * generic tidyup handling needed for things like signal delivery and + * cancellation. + */ +#define TIME_RETURN(err) do { \ + INT32 retVal = 0; \ + if ((err) != 0) { \ + retVal = -1; \ + errno = (err); \ + } \ + return retVal; \ +} while (0) + +#ifdef LOSCFG_AARCH64 +/* + * This two structures originally didn't exit, + * they added by liteos to support 64bit interfaces on 32bit platform, + * in 64bit platform, timeval64 define to timeval which is platform adaptive. + */ +#define timeval64 timeval +#define timespec64 timespec +#endif + +STATIC INLINE BOOL ValidTimeval(const struct timeval *tv) +{ + /* Fail a NULL pointer */ + if (tv == NULL) { + return FALSE; + } + + /* Fail illegal microseconds values */ + if ((tv->tv_usec < 0) || (tv->tv_usec >= OS_SYS_US_PER_SECOND) || (tv->tv_sec < 0)) { + return FALSE; + } + + return TRUE; +} + +STATIC INLINE BOOL ValidTimeval64(const struct timeval64 *tv) +{ + /* Fail a NULL pointer */ + if (tv == NULL) { + return FALSE; + } + + /* Fail illegal microseconds values */ + if ((tv->tv_usec < 0) || (tv->tv_usec >= OS_SYS_US_PER_SECOND) || (tv->tv_sec < 0)) { + return FALSE; + } + + return TRUE; +} + +STATIC INLINE BOOL ValidTimerID(UINT16 swtmrID) +{ + /* check timer id */ + if (swtmrID >= OS_SWTMR_MAX_TIMERID) { + return FALSE; + } + + /* check owner of this timer */ + if (OS_SWT_FROM_SID(swtmrID)->uwOwnerPid != (UINTPTR)OsCurrProcessGet()) { + return FALSE; + } + + return TRUE; +} + +STATIC SPIN_LOCK_INIT(g_timeSpin); +STATIC long long g_adjTimeLeft; /* absolute value of adjtime */ +STATIC INT32 g_adjDirection; /* 1, speed up; 0, slow down; */ + +/* Adjust pacement, nanoseconds per SCHED_CLOCK_INTETRVAL_TICKS ticks */ +STATIC const long long g_adjPacement = (((LOSCFG_BASE_CORE_ADJ_PER_SECOND * SCHED_CLOCK_INTETRVAL_TICKS) / + LOSCFG_BASE_CORE_TICK_PER_SECOND) * OS_SYS_NS_PER_US); + +/* accumulative time delta from continuous modify, such as adjtime */ +STATIC struct timespec64 g_accDeltaFromAdj; +/* accumulative time delta from discontinuous modify, such as settimeofday */ +STATIC struct timespec64 g_accDeltaFromSet; + +VOID OsAdjTime(VOID) +{ + UINT32 intSave; + + LOS_SpinLockSave(&g_timeSpin, &intSave); + if (!g_adjTimeLeft) { + LOS_SpinUnlockRestore(&g_timeSpin, intSave); + return; + } + + if (g_adjTimeLeft > g_adjPacement) { + if (g_adjDirection) { + if ((g_accDeltaFromAdj.tv_nsec + g_adjPacement) >= OS_SYS_NS_PER_SECOND) { + g_accDeltaFromAdj.tv_sec++; + g_accDeltaFromAdj.tv_nsec = (g_accDeltaFromAdj.tv_nsec + g_adjPacement) % OS_SYS_NS_PER_SECOND; + } else { + g_accDeltaFromAdj.tv_nsec = g_accDeltaFromAdj.tv_nsec + g_adjPacement; + } + } else { + if ((g_accDeltaFromAdj.tv_nsec - g_adjPacement) < 0) { + g_accDeltaFromAdj.tv_sec--; + g_accDeltaFromAdj.tv_nsec = g_accDeltaFromAdj.tv_nsec - g_adjPacement + OS_SYS_NS_PER_SECOND; + } else { + g_accDeltaFromAdj.tv_nsec = g_accDeltaFromAdj.tv_nsec - g_adjPacement; + } + } + + g_adjTimeLeft -= g_adjPacement; + } else { + if (g_adjDirection) { + if ((g_accDeltaFromAdj.tv_nsec + g_adjTimeLeft) >= OS_SYS_NS_PER_SECOND) { + g_accDeltaFromAdj.tv_sec++; + g_accDeltaFromAdj.tv_nsec = (g_accDeltaFromAdj.tv_nsec + g_adjTimeLeft) % OS_SYS_NS_PER_SECOND; + } else { + g_accDeltaFromAdj.tv_nsec = g_accDeltaFromAdj.tv_nsec + g_adjTimeLeft; + } + } else { + if ((g_accDeltaFromAdj.tv_nsec - g_adjTimeLeft) < 0) { + g_accDeltaFromAdj.tv_sec--; + g_accDeltaFromAdj.tv_nsec = g_accDeltaFromAdj.tv_nsec - g_adjTimeLeft + OS_SYS_NS_PER_SECOND; + } else { + g_accDeltaFromAdj.tv_nsec = g_accDeltaFromAdj.tv_nsec - g_adjTimeLeft; + } + } + + g_adjTimeLeft = 0; + } + LOS_SpinUnlockRestore(&g_timeSpin, intSave); + return; +} + +/* + * Function: adjtime + * Description: correct the time to synchronize the system clock. + * Input: delta - The amount of time by which the clock is to be adjusted. + * Output: oldDelta - the amount of time remaining from any previous adjustment that has not yet been completed. + * Return: On success, returns 0. On failure, -1 is returned, and errno is set to indicate the error. + */ +int adjtime(const struct timeval *delta, struct timeval *oldDelta) +{ + UINT32 intSave; + LOS_SpinLockSave(&g_timeSpin, &intSave); + /* return the amount of time remaining from any previous adjustment that has not yet been completed. */ + if (oldDelta != NULL) { + if (g_adjDirection == 1) { + oldDelta->tv_sec = g_adjTimeLeft / OS_SYS_NS_PER_SECOND; + oldDelta->tv_usec = (g_adjTimeLeft % OS_SYS_NS_PER_SECOND) / OS_SYS_NS_PER_US; + } else { + oldDelta->tv_sec = -(g_adjTimeLeft / OS_SYS_NS_PER_SECOND); + oldDelta->tv_usec = -((g_adjTimeLeft % OS_SYS_NS_PER_SECOND) / OS_SYS_NS_PER_US); + } + } + + if ((delta == NULL) || ((delta->tv_sec == 0) && (delta->tv_usec == 0))) { + LOS_SpinUnlockRestore(&g_timeSpin, intSave); + return 0; + } + + if ((delta->tv_usec > OS_SYS_US_PER_SECOND) || (delta->tv_usec < -OS_SYS_US_PER_SECOND)) { + LOS_SpinUnlockRestore(&g_timeSpin, intSave); + TIME_RETURN(EINVAL); + } + + /* + * 2: in the glibc implementation, delta must be less than or equal to (INT_MAX / 1000000 - 2) and + * greater than or equal to (INT_MIN / 1000000 + 2) + */ + if ((delta->tv_sec < (INT_MIN / OS_SYS_US_PER_SECOND + 2)) || + (delta->tv_sec > (INT_MAX / OS_SYS_US_PER_SECOND + 2))) { + LOS_SpinUnlockRestore(&g_timeSpin, intSave); + TIME_RETURN(EINVAL); + } + + g_adjTimeLeft = (INT64)delta->tv_sec * OS_SYS_NS_PER_SECOND + delta->tv_usec * OS_SYS_NS_PER_US; + if (g_adjTimeLeft > 0) { + g_adjDirection = 1; + } else { + g_adjDirection = 0; + g_adjTimeLeft = -g_adjTimeLeft; + } + + LOS_SpinUnlockRestore(&g_timeSpin, intSave); + return 0; +} + +STATIC INLINE struct timespec64 OsTimeSpecAdd(const struct timespec64 t1, const struct timespec64 t2) +{ + struct timespec64 ret = {0}; + + ret.tv_sec = t1.tv_sec + t2.tv_sec; + ret.tv_nsec = t1.tv_nsec + t2.tv_nsec; + if (ret.tv_nsec >= OS_SYS_NS_PER_SECOND) { + ret.tv_sec += 1; + ret.tv_nsec -= OS_SYS_NS_PER_SECOND; + } else if (ret.tv_nsec < 0L) { + ret.tv_sec -= 1; + ret.tv_nsec += OS_SYS_NS_PER_SECOND; + } + + return ret; +} + +STATIC INLINE struct timespec64 OsTimeSpecSub(const struct timespec64 t1, const struct timespec64 t2) +{ + struct timespec64 ret = {0}; + + ret.tv_sec = t1.tv_sec - t2.tv_sec; + ret.tv_nsec = t1.tv_nsec - t2.tv_nsec; + if (ret.tv_nsec < 0) { + ret.tv_sec -= 1; + ret.tv_nsec += OS_SYS_NS_PER_SECOND; + } + + return ret; +} + +STATIC VOID OsGetHwTime(struct timespec64 *hwTime) +{ + UINT64 nowNsec; + + nowNsec = LOS_CurrNanosec(); + hwTime->tv_sec = nowNsec / OS_SYS_NS_PER_SECOND; + hwTime->tv_nsec = nowNsec - hwTime->tv_sec * OS_SYS_NS_PER_SECOND; +} + +STATIC INT32 OsSetTimeOfDay(const struct timeval64 *tv, const struct timezone *tz) +{ + UINT32 intSave; + struct timespec64 setTime = {0}; + struct timespec64 hwTime = {0}; + struct timespec64 realTime = {0}; + struct timespec64 tmp = {0}; + +#ifdef LOSCFG_SECURITY_CAPABILITY + if (!IsCapPermit(CAP_SET_TIMEOFDAY)) { + TIME_RETURN(EPERM); + } +#endif + + (VOID)tz; + OsGetHwTime(&hwTime); + setTime.tv_sec = tv->tv_sec; + setTime.tv_nsec = tv->tv_usec * OS_SYS_NS_PER_US; + + LOS_SpinLockSave(&g_timeSpin, &intSave); + /* stop on-going continuous adjusement */ + if (g_adjTimeLeft) { + g_adjTimeLeft = 0; + } + realTime = OsTimeSpecAdd(hwTime, g_accDeltaFromAdj); + realTime = OsTimeSpecAdd(realTime, g_accDeltaFromSet); + + tmp = OsTimeSpecSub(setTime, realTime); + g_accDeltaFromSet = OsTimeSpecAdd(g_accDeltaFromSet, tmp); + + LOS_SpinUnlockRestore(&g_timeSpin, intSave); + + return 0; +} + +int settimeofday(const struct timeval *tv, const struct timezone *tz) +{ + struct timeval64 stTimeVal64 = {0}; + + if (!ValidTimeval(tv)) { + TIME_RETURN(EINVAL); + } + + stTimeVal64.tv_sec = tv->tv_sec; + stTimeVal64.tv_usec = tv->tv_usec; + + return OsSetTimeOfDay(&stTimeVal64, tz); +} + +#ifndef LOSCFG_AARCH64 +int settimeofday64(const struct timeval64 *tv, const struct timezone *tz) +{ + if (!ValidTimeval64(tv)) { + TIME_RETURN(EINVAL); + } + + return OsSetTimeOfDay(tv, tz); +} +#endif + +int setlocalseconds(int seconds) +{ + struct timeval tv = {0}; + + tv.tv_sec = seconds; + tv.tv_usec = 0; + + return settimeofday(&tv, NULL); +} + +STATIC INT32 OsGetTimeOfDay(struct timeval64 *tv, struct timezone *tz) +{ + UINT32 intSave; + + (VOID)tz; + struct timespec64 hwTime = {0}; + struct timespec64 realTime = {0}; + + OsGetHwTime(&hwTime); + + LOS_SpinLockSave(&g_timeSpin, &intSave); + realTime = OsTimeSpecAdd(hwTime, g_accDeltaFromAdj); + realTime = OsTimeSpecAdd(realTime, g_accDeltaFromSet); + LOS_SpinUnlockRestore(&g_timeSpin, intSave); + + tv->tv_sec = realTime.tv_sec; + tv->tv_usec = realTime.tv_nsec / OS_SYS_NS_PER_US; + + if (tv->tv_sec < 0) { + TIME_RETURN(EINVAL); + } + return 0; +} + +#ifndef LOSCFG_AARCH64 +int gettimeofday64(struct timeval64 *tv, struct timezone *tz) +{ + if (tv == NULL) { + TIME_RETURN(EINVAL); + } + + return OsGetTimeOfDay(tv, tz); +} +#endif + +#ifdef LOSCFG_LIBC_NEWLIB +int gettimeofday(struct timeval *tv, void *_tz) +#else +int gettimeofday(struct timeval *tv, struct timezone *tz) +#endif +{ + struct timeval64 stTimeVal64 = {0}; +#ifdef LOSCFG_LIBC_NEWLIB + struct timezone *tz = (struct timezone *)_tz; +#endif + + if (tv == NULL) { + TIME_RETURN(EINVAL); + } + + if (OsGetTimeOfDay(&stTimeVal64, tz) == -1) { + return -1; + } + +#ifdef LOSCFG_AARCH64 + tv->tv_sec = stTimeVal64.tv_sec; + tv->tv_usec = stTimeVal64.tv_usec; +#else + if (stTimeVal64.tv_sec > (long long)LONG_MAX) { + return -1; + } + tv->tv_sec = (time_t)stTimeVal64.tv_sec; + tv->tv_usec = (suseconds_t)stTimeVal64.tv_usec; +#endif + + return 0; +} + +int clock_settime(clockid_t clockID, const struct timespec *tp) +{ + struct timeval tv = {0}; + + switch (clockID) { + case CLOCK_REALTIME: + /* we only support the realtime clock currently */ + break; + case CLOCK_MONOTONIC_COARSE: + case CLOCK_REALTIME_COARSE: + case CLOCK_MONOTONIC_RAW: + case CLOCK_PROCESS_CPUTIME_ID: + case CLOCK_BOOTTIME: + case CLOCK_REALTIME_ALARM: + case CLOCK_BOOTTIME_ALARM: + case CLOCK_TAI: + case CLOCK_THREAD_CPUTIME_ID: + TIME_RETURN(ENOTSUP); + case CLOCK_MONOTONIC: + default: + TIME_RETURN(EINVAL); + } + + if (!ValidTimeSpec(tp)) { + TIME_RETURN(EINVAL); + } + +#ifdef LOSCFG_SECURITY_CAPABILITY + if (!IsCapPermit(CAP_CLOCK_SETTIME)) { + TIME_RETURN(EPERM); + } +#endif + + tv.tv_sec = tp->tv_sec; + tv.tv_usec = tp->tv_nsec / OS_SYS_NS_PER_US; + return settimeofday(&tv, NULL); +} + +#ifdef LOSCFG_KERNEL_CPUP +inline UINT32 GetTidFromClockID(clockid_t clockID) +{ + // In musl/src/thread/pthread_getcpuclockid.c, we know 'clockid = (-tid - 1) * 8 + 6' + UINT32 tid = -(clockID - 6) / 8 - 1; // 6 8 1 inverse operation from clockID to tid + return tid; +} + +inline const pid_t GetPidFromClockID(clockid_t clockID) +{ + // In musl/src/time/clock_getcpuclockid.c, we know 'clockid = (-pid - 1) * 8 + 2' + const pid_t pid = -(clockID - 2) / 8 - 1; // 2 8 1 inverse operation from clockID to pid + return pid; +} + +static int PthreadGetCputime(clockid_t clockID, struct timespec *ats) +{ + uint64_t runtime; + UINT32 intSave; + UINT32 tid = GetTidFromClockID(clockID); + if (OS_TID_CHECK_INVALID(tid)) { + return -EINVAL; + } + + LosTaskCB *task = OsGetTaskCB(tid); + + if (OsCurrTaskGet()->processCB != task->processCB) { + return -EINVAL; + } + + SCHEDULER_LOCK(intSave); + runtime = task->taskCpup.allTime; + SCHEDULER_UNLOCK(intSave); + + ats->tv_sec = runtime / OS_SYS_NS_PER_SECOND; + ats->tv_nsec = runtime % OS_SYS_NS_PER_SECOND; + + return 0; +} + +static int ProcessGetCputime(clockid_t clockID, struct timespec *ats) +{ + UINT64 runtime; + UINT32 intSave; + const pid_t pid = GetPidFromClockID(clockID); + LosProcessCB *spcb = NULL; + + if (OsProcessIDUserCheckInvalid(pid) || pid < 0) { + return -EINVAL; + } + + spcb = OS_PCB_FROM_PID(pid); + if (OsProcessIsUnused(spcb)) { + return -EINVAL; + } + + SCHEDULER_LOCK(intSave); + if (spcb->processCpup == NULL) { + SCHEDULER_UNLOCK(intSave); + return -EINVAL; + } + runtime = spcb->processCpup->allTime; + SCHEDULER_UNLOCK(intSave); + + ats->tv_sec = runtime / OS_SYS_NS_PER_SECOND; + ats->tv_nsec = runtime % OS_SYS_NS_PER_SECOND; + + return 0; +} + +static int GetCputime(clockid_t clockID, struct timespec *tp) +{ + int ret; + + if (clockID >= 0) { + return -EINVAL; + } + + if ((UINT32)clockID & CPUCLOCK_PERTHREAD_MASK) { + ret = PthreadGetCputime(clockID, tp); + } else { + ret = ProcessGetCputime(clockID, tp); + } + + return ret; +} + +static int CheckClock(const clockid_t clockID) +{ + int error = 0; + const pid_t pid = GetPidFromClockID(clockID); + + if (!((UINT32)clockID & CPUCLOCK_PERTHREAD_MASK)) { + LosProcessCB *spcb = NULL; + if (OsProcessIDUserCheckInvalid(pid) || pid < 0) { + return -EINVAL; + } + spcb = OS_PCB_FROM_PID(pid); + if (OsProcessIsUnused(spcb)) { + error = -EINVAL; + } + } else { + error = -EINVAL; + } + + return error; +} + +static int CpuClockGetres(const clockid_t clockID, struct timespec *tp) +{ + if (clockID > 0) { + return -EINVAL; + } + + int error = CheckClock(clockID); + if (!error) { + error = ProcessGetCputime(clockID, tp); + } + + return error; +} +#endif + +int clock_gettime(clockid_t clockID, struct timespec *tp) +{ + UINT32 intSave; + struct timespec64 tmp = {0}; + struct timespec64 hwTime = {0}; + + if (clockID > MAX_CLOCKS) { + goto ERROUT; + } + + if (tp == NULL) { + goto ERROUT; + } + + OsGetHwTime(&hwTime); + + switch (clockID) { + case CLOCK_MONOTONIC_RAW: +#ifdef LOSCFG_TIME_CONTAINER + tmp = OsTimeSpecAdd(hwTime, CLOCK_MONOTONIC_TIME_BASE); + tp->tv_sec = tmp.tv_sec; + tp->tv_nsec = tmp.tv_nsec; +#else + tp->tv_sec = hwTime.tv_sec; + tp->tv_nsec = hwTime.tv_nsec; +#endif + break; + case CLOCK_MONOTONIC: + LOS_SpinLockSave(&g_timeSpin, &intSave); + tmp = OsTimeSpecAdd(hwTime, g_accDeltaFromAdj); + LOS_SpinUnlockRestore(&g_timeSpin, intSave); +#ifdef LOSCFG_TIME_CONTAINER + tmp = OsTimeSpecAdd(tmp, CLOCK_MONOTONIC_TIME_BASE); +#endif + tp->tv_sec = tmp.tv_sec; + tp->tv_nsec = tmp.tv_nsec; + break; + case CLOCK_REALTIME: + LOS_SpinLockSave(&g_timeSpin, &intSave); + tmp = OsTimeSpecAdd(hwTime, g_accDeltaFromAdj); + tmp = OsTimeSpecAdd(tmp, g_accDeltaFromSet); + LOS_SpinUnlockRestore(&g_timeSpin, intSave); + tp->tv_sec = tmp.tv_sec; + tp->tv_nsec = tmp.tv_nsec; + break; + case CLOCK_MONOTONIC_COARSE: + case CLOCK_REALTIME_COARSE: + case CLOCK_THREAD_CPUTIME_ID: + case CLOCK_PROCESS_CPUTIME_ID: + case CLOCK_BOOTTIME: + case CLOCK_REALTIME_ALARM: + case CLOCK_BOOTTIME_ALARM: + case CLOCK_TAI: + TIME_RETURN(ENOTSUP); + default: + { +#ifdef LOSCFG_KERNEL_CPUP + int ret = GetCputime(clockID, tp); + TIME_RETURN(-ret); +#else + TIME_RETURN(EINVAL); +#endif + } + } + + return 0; + +ERROUT: + TIME_RETURN(EINVAL); +} + +int clock_getres(clockid_t clockID, struct timespec *tp) +{ + if (tp == NULL) { + TIME_RETURN(EINVAL); + } + + switch (clockID) { + case CLOCK_MONOTONIC_RAW: + case CLOCK_MONOTONIC: + case CLOCK_REALTIME: + /* the accessible rtc resolution */ + tp->tv_nsec = OS_SYS_NS_PER_US; /* the precision of clock_gettime is 1us */ + tp->tv_sec = 0; + break; + case CLOCK_MONOTONIC_COARSE: + case CLOCK_REALTIME_COARSE: + /* the clock coarse resolution, supported by vdso. + * the precision of clock_gettime is 1tick */ + tp->tv_nsec = OS_SYS_NS_PER_SECOND / LOSCFG_BASE_CORE_TICK_PER_SECOND; + tp->tv_sec = 0; + break; + case CLOCK_THREAD_CPUTIME_ID: + case CLOCK_PROCESS_CPUTIME_ID: + case CLOCK_BOOTTIME: + case CLOCK_REALTIME_ALARM: + case CLOCK_BOOTTIME_ALARM: + case CLOCK_TAI: + TIME_RETURN(ENOTSUP); + default: +#ifdef LOSCFG_KERNEL_CPUP + { + int ret = CpuClockGetres(clockID, tp); + TIME_RETURN(-ret); + } +#else + TIME_RETURN(EINVAL); +#endif + } + + TIME_RETURN(0); +} + +int clock_nanosleep(clockid_t clk, int flags, const struct timespec *req, struct timespec *rem) +{ + switch (clk) { + case CLOCK_REALTIME: + if (flags == 0) { + /* we only support the realtime clock currently */ + return nanosleep(req, rem); + } + /* fallthrough */ + case CLOCK_MONOTONIC_COARSE: + case CLOCK_REALTIME_COARSE: + case CLOCK_MONOTONIC_RAW: + case CLOCK_MONOTONIC: + case CLOCK_PROCESS_CPUTIME_ID: + case CLOCK_BOOTTIME: + case CLOCK_REALTIME_ALARM: + case CLOCK_BOOTTIME_ALARM: + case CLOCK_TAI: + if (flags == 0 || flags == TIMER_ABSTIME) { + TIME_RETURN(ENOTSUP); + } + /* fallthrough */ + case CLOCK_THREAD_CPUTIME_ID: + default: + TIME_RETURN(EINVAL); + } + + TIME_RETURN(0); +} + +typedef struct { + int sigev_signo; + pid_t pid; + unsigned int tid; + union sigval sigev_value; +} swtmr_proc_arg; + +static VOID SwtmrProc(UINTPTR tmrArg) +{ +#ifdef LOSCFG_KERNEL_VM + INT32 sig, ret; + UINT32 intSave; + pid_t pid; + siginfo_t info; + LosTaskCB *stcb = NULL; + + swtmr_proc_arg *arg = (swtmr_proc_arg *)tmrArg; + OS_GOTO_EXIT_IF(arg == NULL, EINVAL); + + sig = arg->sigev_signo; + pid = arg->pid; + OS_GOTO_EXIT_IF(!GOOD_SIGNO(sig), EINVAL); + + /* Create the siginfo structure */ + info.si_signo = sig; + info.si_code = SI_TIMER; + info.si_value.sival_ptr = arg->sigev_value.sival_ptr; + + /* Send signals to threads or processes */ + if (arg->tid > 0) { + /* Make sure that the para is valid */ + OS_GOTO_EXIT_IF(OS_TID_CHECK_INVALID(arg->tid), EINVAL); + stcb = OsGetTaskCB(arg->tid); + ret = OsUserProcessOperatePermissionsCheck(stcb, stcb->processCB); + OS_GOTO_EXIT_IF(ret != LOS_OK, -ret); + + /* Dispatch the signal to thread, bypassing normal task group thread + * dispatch rules. */ + SCHEDULER_LOCK(intSave); + ret = OsTcbDispatch(stcb, &info); + SCHEDULER_UNLOCK(intSave); + OS_GOTO_EXIT_IF(ret != LOS_OK, -ret); + } else { + /* Make sure that the para is valid */ + OS_GOTO_EXIT_IF(pid <= 0 || OS_PID_CHECK_INVALID(pid), EINVAL); + /* Dispatch the signal to process */ + SCHEDULER_LOCK(intSave); + OsDispatch(pid, &info, OS_USER_KILL_PERMISSION); + SCHEDULER_UNLOCK(intSave); + } + return; +EXIT: + PRINT_ERR("Dispatch signals failed!, ret: %d\r\n", ret); +#endif + return; +} + +int timer_create(clockid_t clockID, struct sigevent *restrict evp, timer_t *restrict timerID) +{ + UINT32 ret; + UINT16 swtmrID; +#ifdef LOSCFG_SECURITY_VID + UINT16 vid; +#endif + + if (!timerID || (clockID != CLOCK_REALTIME) || !evp) { + errno = EINVAL; + return -1; + } + + if ((evp->sigev_notify != SIGEV_THREAD) || evp->sigev_notify_attributes) { + errno = ENOTSUP; + return -1; + } + + ret = LOS_SwtmrCreate(1, LOS_SWTMR_MODE_ONCE, (SWTMR_PROC_FUNC)evp->sigev_notify_function, + &swtmrID, (UINTPTR)evp->sigev_value.sival_ptr); + if (ret != LOS_OK) { + errno = (ret == LOS_ERRNO_SWTMR_MAXSIZE) ? EAGAIN : EINVAL; + return -1; + } + +#ifdef LOSCFG_SECURITY_VID + vid = AddNodeByRid(swtmrID); + if (vid == MAX_INVALID_TIMER_VID) { + (VOID)LOS_SwtmrDelete(swtmrID); + return -1; + } + swtmrID = vid; +#endif + *timerID = (timer_t)(UINTPTR)swtmrID; + return 0; +} + +int OsTimerCreate(clockid_t clockID, struct ksigevent *evp, timer_t *timerID) +{ + UINT32 ret; + UINT16 swtmrID; + swtmr_proc_arg *arg = NULL; + int signo; +#ifdef LOSCFG_SECURITY_VID + UINT16 vid; +#endif + + if ((clockID != CLOCK_REALTIME) || (timerID == NULL)) { + errno = EINVAL; + return -1; + } + + signo = evp ? evp->sigev_signo : SIGALRM; + if (signo > SIGRTMAX || signo < 1) { + errno = EINVAL; + return -1; + } + if (evp && (evp->sigev_notify != SIGEV_SIGNAL && evp->sigev_notify != SIGEV_THREAD_ID)) { + errno = ENOTSUP; + return -1; + } + + arg = (swtmr_proc_arg *)malloc(sizeof(swtmr_proc_arg)); + if (arg == NULL) { + errno = ENOMEM; + return -1; + } + + arg->tid = evp ? evp->sigev_tid : 0; + arg->sigev_signo = signo; + arg->pid = LOS_GetCurrProcessID(); + arg->sigev_value.sival_ptr = evp ? evp->sigev_value.sival_ptr : NULL; + ret = LOS_SwtmrCreate(1, LOS_SWTMR_MODE_ONCE, SwtmrProc, &swtmrID, (UINTPTR)arg); + if (ret != LOS_OK) { + errno = (ret == LOS_ERRNO_SWTMR_MAXSIZE) ? EAGAIN : EINVAL; + free(arg); + return -1; + } + +#ifdef LOSCFG_SECURITY_VID + vid = AddNodeByRid(swtmrID); + if (vid == MAX_INVALID_TIMER_VID) { + free(arg); + (VOID)LOS_SwtmrDelete(swtmrID); + return -1; + } + swtmrID = vid; +#endif + *timerID = (timer_t)(UINTPTR)swtmrID; + return 0; +} + +int timer_delete(timer_t timerID) +{ + UINT16 swtmrID = (UINT16)(UINTPTR)timerID; + VOID *arg = NULL; + UINTPTR swtmrProc; + +#ifdef LOSCFG_SECURITY_VID + swtmrID = GetRidByVid(swtmrID); +#endif + if (OS_INT_ACTIVE || !ValidTimerID(swtmrID)) { + goto ERROUT; + } + + arg = (VOID *)OS_SWT_FROM_SID(swtmrID)->uwArg; + swtmrProc = (UINTPTR)OS_SWT_FROM_SID(swtmrID)->pfnHandler; + if (LOS_SwtmrDelete(swtmrID)) { + goto ERROUT; + } + if ((swtmrProc == (UINTPTR)SwtmrProc) && (arg != NULL)) { + free(arg); + } + +#ifdef LOSCFG_SECURITY_VID + RemoveNodeByVid((UINT16)(UINTPTR)timerID); +#endif + return 0; + +ERROUT: + errno = EINVAL; + return -1; +} + +int timer_settime(timer_t timerID, int flags, + const struct itimerspec *value, /* new value */ + struct itimerspec *oldValue) /* old value to return, always 0 */ +{ + UINT16 swtmrID = (UINT16)(UINTPTR)timerID; + SWTMR_CTRL_S *swtmr = NULL; + UINT32 interval, expiry, ret; + UINT32 intSave; + + if (flags != 0) { + /* flags not supported currently */ + errno = ENOSYS; + return -1; + } + +#ifdef LOSCFG_SECURITY_VID + swtmrID = GetRidByVid(swtmrID); +#endif + if ((value == NULL) || OS_INT_ACTIVE || !ValidTimerID(swtmrID)) { + errno = EINVAL; + return -1; + } + + if (!ValidTimeSpec(&value->it_value) || !ValidTimeSpec(&value->it_interval)) { + errno = EINVAL; + return -1; + } + + if (oldValue) { + (VOID)timer_gettime(timerID, oldValue); + } + + swtmr = OS_SWT_FROM_SID(swtmrID); + ret = LOS_SwtmrStop(swtmr->usTimerID); + if ((ret != LOS_OK) && (ret != LOS_ERRNO_SWTMR_NOT_STARTED)) { + errno = EINVAL; + return -1; + } + + expiry = OsTimeSpec2Tick(&value->it_value); + interval = OsTimeSpec2Tick(&value->it_interval); + + LOS_SpinLockSave(&g_swtmrSpin, &intSave); + swtmr->ucMode = interval ? LOS_SWTMR_MODE_OPP : LOS_SWTMR_MODE_NO_SELFDELETE; + swtmr->uwExpiry = expiry + !!expiry; // PS: skip the first tick because it is NOT a full tick. + swtmr->uwInterval = interval; + swtmr->uwOverrun = 0; + LOS_SpinUnlockRestore(&g_swtmrSpin, intSave); + + if ((value->it_value.tv_sec == 0) && (value->it_value.tv_nsec == 0)) { + /* + * 1) when expiry is 0, means timer should be stopped. + * 2) If timer is ticking, stopping timer is already done before. + * 3) If timer is created but not ticking, return 0 as well. + */ + return 0; + } + + if (LOS_SwtmrStart(swtmr->usTimerID)) { + errno = EINVAL; + return -1; + } + + return 0; +} + +int timer_gettime(timer_t timerID, struct itimerspec *value) +{ + UINT32 tick = 0; + SWTMR_CTRL_S *swtmr = NULL; + UINT16 swtmrID = (UINT16)(UINTPTR)timerID; + UINT32 ret; + +#ifdef LOSCFG_SECURITY_VID + swtmrID = GetRidByVid(swtmrID); +#endif + if ((value == NULL) || !ValidTimerID(swtmrID)) { + errno = EINVAL; + return -1; + } + + swtmr = OS_SWT_FROM_SID(swtmrID); + + /* get expire time */ + ret = LOS_SwtmrTimeGet(swtmr->usTimerID, &tick); + if ((ret != LOS_OK) && (ret != LOS_ERRNO_SWTMR_NOT_STARTED)) { + errno = EINVAL; + return -1; + } + + OsTick2TimeSpec(&value->it_value, tick); + OsTick2TimeSpec(&value->it_interval, (swtmr->ucMode == LOS_SWTMR_MODE_ONCE) ? 0 : swtmr->uwInterval); + return 0; +} + +int timer_getoverrun(timer_t timerID) +{ + UINT16 swtmrID = (UINT16)(UINTPTR)timerID; + SWTMR_CTRL_S *swtmr = NULL; + INT32 overRun; + +#ifdef LOSCFG_SECURITY_VID + swtmrID = GetRidByVid(swtmrID); +#endif + if (!ValidTimerID(swtmrID)) { + errno = EINVAL; + return -1; + } + + swtmr = OS_SWT_FROM_SID(swtmrID); + if (swtmr->usTimerID >= OS_SWTMR_MAX_TIMERID) { + errno = EINVAL; + return -1; + } + + overRun = (INT32)(swtmr->uwOverrun); + return (overRun > DELAYTIMER_MAX) ? DELAYTIMER_MAX : overRun; +} + +STATIC INT32 DoNanoSleep(UINT64 nanoseconds) +{ + UINT32 ret; + + ret = LOS_TaskDelay(OsNS2Tick(nanoseconds)); + if (ret == LOS_OK || ret == LOS_ERRNO_TSK_YIELD_NOT_ENOUGH_TASK) { + return 0; + } + return -1; +} + +#ifdef LOSCFG_LIBC_NEWLIB +int usleep(unsigned long useconds) +#else +int usleep(unsigned useconds) +#endif +{ + return DoNanoSleep((UINT64)useconds * OS_SYS_NS_PER_US); +} + +int nanosleep(const struct timespec *rqtp, struct timespec *rmtp) +{ + UINT64 nanoseconds; + INT32 ret = -1; + + (VOID)rmtp; + /* expire time */ + + if (!ValidTimeSpec(rqtp)) { + errno = EINVAL; + return ret; + } + + nanoseconds = (UINT64)rqtp->tv_sec * OS_SYS_NS_PER_SECOND + rqtp->tv_nsec; + + return DoNanoSleep(nanoseconds); +} + +unsigned int sleep(unsigned int seconds) +{ + return DoNanoSleep((UINT64)seconds * OS_SYS_NS_PER_SECOND); +} + +double difftime(time_t time2, time_t time1) +{ + return (double)(time2 - time1); +} + +clock_t clock(VOID) +{ + clock_t clockMsec; + UINT64 nowNsec; + + nowNsec = LOS_CurrNanosec(); + clockMsec = (clock_t)(nowNsec / (OS_SYS_NS_PER_SECOND / CLOCKS_PER_SEC)); + + return clockMsec; +} + +clock_t times(struct tms *buf) +{ + clock_t clockTick = -1; + + (void)buf; + set_errno(ENOSYS); + + return clockTick; +} + +int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue) +{ + UINT32 intSave; + LosProcessCB *processCB = OsCurrProcessGet(); + timer_t timerID = 0; + struct itimerspec spec; + struct itimerspec ospec; + int ret = LOS_OK; + + /* we only support the realtime clock timer currently */ + if (which != ITIMER_REAL || !value) { + set_errno(EINVAL); + return -1; + } + + /* To avoid creating an invalid timer after the timer has already been create */ + if (processCB->timerID == (timer_t)(UINTPTR)MAX_INVALID_TIMER_VID) { + ret = OsTimerCreate(CLOCK_REALTIME, NULL, &timerID); + if (ret != LOS_OK) { + return ret; + } + } + + /* The initialization of this global timer must be in spinlock + * OsTimerCreate cannot be located in spinlock. + */ + SCHEDULER_LOCK(intSave); + if (processCB->timerID == (timer_t)(UINTPTR)MAX_INVALID_TIMER_VID) { + processCB->timerID = timerID; + SCHEDULER_UNLOCK(intSave); + } else { + SCHEDULER_UNLOCK(intSave); + if (timerID) { + timer_delete(timerID); + } + } + + if (!ValidTimeval(&value->it_value) || !ValidTimeval(&value->it_interval)) { + set_errno(EINVAL); + return -1; + } + + TIMEVAL_TO_TIMESPEC(&value->it_value, &spec.it_value); + TIMEVAL_TO_TIMESPEC(&value->it_interval, &spec.it_interval); + + ret = timer_settime(processCB->timerID, 0, &spec, ovalue ? &ospec : NULL); + if (ret == LOS_OK && ovalue) { + TIMESPEC_TO_TIMEVAL(&ovalue->it_value, &ospec.it_value); + TIMESPEC_TO_TIMEVAL(&ovalue->it_interval, &ospec.it_interval); + } + + return ret; +} + +int getitimer(int which, struct itimerval *value) +{ + LosProcessCB *processCB = OsCurrProcessGet(); + struct itimerspec spec = {}; + + int ret = LOS_OK; + + /* we only support the realtime clock timer currently */ + if (which != ITIMER_REAL || !value) { + set_errno(EINVAL); + return -1; + } + + if (processCB->timerID != (timer_t)(UINTPTR)MAX_INVALID_TIMER_VID) { + ret = timer_gettime(processCB->timerID, &spec); + } + + if (ret == LOS_OK) { + TIMESPEC_TO_TIMEVAL(&value->it_value, &spec.it_value); + TIMESPEC_TO_TIMEVAL(&value->it_interval, &spec.it_interval); + } + + return ret; +} + +#ifdef LOSCFG_KERNEL_VDSO +VOID OsVdsoTimeGet(VdsoDataPage *vdsoDataPage) +{ + UINT32 intSave; + struct timespec64 tmp = {0}; + struct timespec64 hwTime = {0}; + + if (vdsoDataPage == NULL) { + return; + } + + OsGetHwTime(&hwTime); + + LOS_SpinLockSave(&g_timeSpin, &intSave); + tmp = OsTimeSpecAdd(hwTime, g_accDeltaFromAdj); + vdsoDataPage->monoTimeSec = tmp.tv_sec; + vdsoDataPage->monoTimeNsec = tmp.tv_nsec; + + tmp = OsTimeSpecAdd(tmp, g_accDeltaFromSet); + vdsoDataPage->realTimeSec = tmp.tv_sec; + vdsoDataPage->realTimeNsec = tmp.tv_nsec; + LOS_SpinUnlockRestore(&g_timeSpin, intSave); +} +#endif + +time_t time(time_t *t) +{ + struct timeval tp; + int ret; + + /* Get the current time from the system */ + ret = gettimeofday(&tp, (struct timezone *)NULL); + if (ret == LOS_OK) { + /* Return the seconds since the epoch */ + if (t) { + *t = tp.tv_sec; + } + return tp.tv_sec; + } + return (time_t)OS_ERROR; +} diff --git a/src/kernel_liteos_a/config.mk b/src/kernel_liteos_a/config.mk new file mode 100644 index 00000000..8007d9ed --- /dev/null +++ b/src/kernel_liteos_a/config.mk @@ -0,0 +1,68 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +############### this is a makefile that you can config it ############### +-include $(LITEOSTOPDIR)/tools/build/mk/los_config.mk +##### liteos tables -u ldflags ##### +-include $(LITEOSTOPDIR)/tools/build/mk/liteos_tables_ldflags.mk + +LITEOS_COPTS := $(LITEOS_COPTS_DEBUG) $(LITEOS_COPTS_BASE) \ + $(LITEOS_COPTS_EXTRA) $(LITEOS_CORE_COPTS) +LITEOS_CXXOPTS := $(LITEOS_CXXOPTS_BASE) +LITEOS_INCLUDE := $(LITEOS_KERNEL_INCLUDE) $(LITEOS_EXTKERNEL_INCLUDE) \ + $(LITEOS_COMPAT_INCLUDE) $(LITEOS_FS_INCLUDE) \ + $(LITEOS_NET_INCLUDE) $(LITEOS_LIB_INCLUDE) \ + $(LITEOS_DRIVERS_INCLUDE) $(LITEOS_TOOLS_DEBUG_INCLUDE) \ + $(LITEOS_PLATFORM_INCLUDE) $(LITEOS_DFX_INCLUDE) \ + $(LITEOS_SECURITY_INCLUDE) +LITEOS_LIBDEP := $(LITEOS_BASELIB) +LITEOS_ASFLAGS := $(LITEOS_ASOPTS) $(LITEOS_INCLUDE) +LITEOS_CFLAGS := $(LITEOS_COPTS) $(LITEOS_CMACRO) \ + $(LITEOS_CMACRO_TEST) $(LITEOS_IMAGE_MACRO) \ + $(LITEOS_INCLUDE) +LITEOS_CXXFLAGS := $(LITEOS_CXXOPTS) $(LITEOS_CXXMACRO) \ + $(LITEOS_CMACRO) $(LITEOS_CXXINCLUDE) +LITEOS_LDFLAGS := $(LITEOS_LD_OPTS) $(LITEOS_LD_PATH) \ + $(LITEOS_LD_SCRIPT) + +# clear all local variables +LOCAL_FLAGS = +LOCAL_CFLAGS = +LOCAL_CPPFLAGS = +LOCAL_ASFLAGS = +LOCAL_SRCS = +LOCAL_CHS = +LOCAL_CPPHS = + +# basic build flags +CFLAGS := $(LITEOS_CFLAGS) +CXXFLAGS := $(LITEOS_CXXFLAGS) +ASFLAGS := $(LITEOS_ASFLAGS) +LDFLAGS := $(LITEOS_LDFLAGS) +ARFLAGS := rc diff --git a/src/kernel_liteos_a/drivers/BUILD.gn b/src/kernel_liteos_a/drivers/BUILD.gn new file mode 100644 index 00000000..d9e29eaa --- /dev/null +++ b/src/kernel_liteos_a/drivers/BUILD.gn @@ -0,0 +1,38 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_group("drivers") { + modules = [ + "block", + "char", + "mtd", + ] +} diff --git a/src/kernel_liteos_a/drivers/Kconfig b/src/kernel_liteos_a/drivers/Kconfig new file mode 100644 index 00000000..da5e9e9b --- /dev/null +++ b/src/kernel_liteos_a/drivers/Kconfig @@ -0,0 +1,20 @@ +config DRIVERS + bool "Enable Driver" + default y + help + Answer Y to enable LiteOS support driver. + +source "bsd/dev/usb/Kconfig" +source "../../drivers/hdf_core/adapter/khdf/liteos/Kconfig" + +# Device driver Kconfig import +source "$(DEVICE_PATH)/drivers/Kconfig" + +source "drivers/char/mem/Kconfig" +source "drivers/char/quickstart/Kconfig" +source "drivers/char/random/Kconfig" +source "drivers/char/video/Kconfig" +source "drivers/char/trace/Kconfig" +source "drivers/char/perf/Kconfig" + +source "../../drivers/liteos/hievent/Kconfig" diff --git a/src/kernel_liteos_a/drivers/block/BUILD.gn b/src/kernel_liteos_a/drivers/block/BUILD.gn new file mode 100644 index 00000000..d41dafe4 --- /dev/null +++ b/src/kernel_liteos_a/drivers/block/BUILD.gn @@ -0,0 +1,34 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_group("block") { + modules = [ "disk" ] +} diff --git a/src/kernel_liteos_a/drivers/block/disk/BUILD.gn b/src/kernel_liteos_a/drivers/block/disk/BUILD.gn new file mode 100644 index 00000000..48e42b06 --- /dev/null +++ b/src/kernel_liteos_a/drivers/block/disk/BUILD.gn @@ -0,0 +1,45 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = defined(LOSCFG_FS_FAT_DISK) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ + "src/disk.c", + "src/disk_shellcmd.c", + ] + + public_configs = [ ":public" ] +} + +config("public") { + include_dirs = [ "include" ] +} diff --git a/src/kernel_liteos_a/drivers/block/disk/Makefile b/src/kernel_liteos_a/drivers/block/disk/Makefile new file mode 100644 index 00000000..4e35bd1b --- /dev/null +++ b/src/kernel_liteos_a/drivers/block/disk/Makefile @@ -0,0 +1,36 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := $(wildcard src/*.c) + +include $(MODULE) diff --git a/src/kernel_liteos_a/drivers/block/disk/include/disk.h b/src/kernel_liteos_a/drivers/block/disk/include/disk.h new file mode 100644 index 00000000..46c55ee1 --- /dev/null +++ b/src/kernel_liteos_a/drivers/block/disk/include/disk.h @@ -0,0 +1,742 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup disk Disk + * @ingroup filesystem + */ + +#ifndef _DISK_H +#define _DISK_H + +#include "fs/driver.h" +#include "los_base.h" +#include "pthread.h" + +#ifdef LOSCFG_FS_FAT_CACHE +#include "bcache.h" +#endif + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +#define SYS_MAX_DISK 5 +#define MAX_DIVIDE_PART_PER_DISK 16 +#define MAX_PRIMARY_PART_PER_DISK 4 +#define SYS_MAX_PART (SYS_MAX_DISK * MAX_DIVIDE_PART_PER_DISK) +#define DISK_NAME 255 +#define DISK_MAX_SECTOR_SIZE 512 + +#define PAR_OFFSET 446 /* MBR: Partition table offset (2) */ +#define BS_SIG55AA 510 /* Signature word (2) */ +#define BS_FILSYSTEMTYPE32 82 /* File system type (1) */ +#define BS_JMPBOOT 0 /* x86 jump instruction (3-byte) */ +#define BS_FILSYSTYPE 0x36 /* File system type (2) */ +#define BS_SIG55AA_VALUE 0xAA55 + +#define PAR_TYPE_OFFSET 4 +#define PAR_START_OFFSET 8 +#define PAR_COUNT_OFFSET 12 +#define PAR_TABLE_SIZE 16 +#define EXTENDED_PAR 0x0F +#define EXTENDED_8G 0x05 +#define EMMC 0xEC +#define OTHERS 0x01 /* sdcard or umass */ + +#define BS_FS_TYPE_MASK 0xFFFFFF +#define BS_FS_TYPE_VALUE 0x544146 +#define BS_FS_TYPE_FAT 0x0B +#define BS_FS_TYPE_NTFS 0x07 + +#define FIRST_BYTE 1 +#define SECOND_BYTE 2 +#define THIRD_BYTE 3 +#define FOURTH_BYTE 4 + +#define BIT_FOR_BYTE 8 + +#define LD_WORD_DISK(ptr) (UINT16)(((UINT16)*((UINT8 *)(ptr) + FIRST_BYTE) << (BIT_FOR_BYTE * FIRST_BYTE)) | \ + (UINT16)*(UINT8 *)(ptr)) +#define LD_DWORD_DISK(ptr) (UINT32)(((UINT32)*((UINT8 *)(ptr) + THIRD_BYTE) << (BIT_FOR_BYTE * THIRD_BYTE)) | \ + ((UINT32)*((UINT8 *)(ptr) + SECOND_BYTE) << (BIT_FOR_BYTE * SECOND_BYTE)) | \ + ((UINT16)*((UINT8 *)(ptr) + FIRST_BYTE) << (BIT_FOR_BYTE * FIRST_BYTE)) | \ + (*(UINT8 *)(ptr))) + +#define LD_QWORD_DISK(ptr) ((UINT64)(((UINT64)LD_DWORD_DISK(&(ptr)[FOURTH_BYTE]) << (BIT_FOR_BYTE * FOURTH_BYTE)) | \ + LD_DWORD_DISK(ptr))) + +/* Check VBR string, including FAT, NTFS */ +#define VERIFY_FS(ptr) (((LD_DWORD_DISK(&(ptr)[BS_FILSYSTEMTYPE32]) & BS_FS_TYPE_MASK) == BS_FS_TYPE_VALUE) || \ + !strncmp(&(ptr)[BS_FILSYSTYPE], "FAT", strlen("FAT")) || \ + !strncmp(&(ptr)[BS_JMPBOOT], "\xEB\x52\x90" "NTFS ", \ + strlen("\xEB\x52\x90" "NTFS "))) + +#define PARTION_MODE_BTYE (PAR_OFFSET + PAR_TYPE_OFFSET) /* 0xEE: GPT(GUID), else: MBR */ +#define PARTION_MODE_GPT 0xEE /* 0xEE: GPT(GUID), else: MBR */ +#define SIGNATURE_OFFSET 0 /* The offset of GPT partition header signature */ +#define SIGNATURE_LEN 8 /* The length of GPT signature */ +#define HEADER_SIZE_OFFSET 12 /* The offset of GPT header size */ +#define TABLE_SIZE_OFFSET 84 /* The offset of GPT table size */ +#define TABLE_NUM_OFFSET 80 /* The number of GPT table */ +#define TABLE_START_SECTOR 2 +#define TABLE_MAX_NUM 128 +#define TABLE_SIZE 128 +#define GPT_PAR_START_OFFSET 32 +#define GPT_PAR_END_OFFSET 40 +#define PAR_ENTRY_NUM_PER_SECTOR 4 +#define HEADER_SIZE_MASK 0xFFFFFFFF +#define HEADER_SIZE 0x5C +#define HARD_DISK_GUID_OFFSET 56 +#define HARD_DISK_GUID_FOR_ESP 0x0020004900460045 +#define HARD_DISK_GUID_FOR_MSP 0x007200630069004D +#define PAR_VALID_OFFSET0 0 +#define PAR_VALID_OFFSET1 4 +#define PAR_VALID_OFFSET2 8 +#define PAR_VALID_OFFSET3 12 + +#define VERIFY_GPT(ptr) ((!strncmp(&(ptr)[SIGNATURE_OFFSET], "EFI PART", SIGNATURE_LEN)) && \ + ((LD_DWORD_DISK(&(ptr)[HEADER_SIZE_OFFSET]) & HEADER_SIZE_MASK) == HEADER_SIZE)) + +#define VERITY_PAR_VALID(ptr) ((LD_DWORD_DISK(&(ptr)[PAR_VALID_OFFSET0]) + \ + LD_DWORD_DISK(&(ptr)[PAR_VALID_OFFSET1]) + \ + LD_DWORD_DISK(&(ptr)[PAR_VALID_OFFSET2]) + \ + LD_DWORD_DISK(&(ptr)[PAR_VALID_OFFSET3])) != 0) + +/* ESP MSP */ +#define VERITY_AVAILABLE_PAR(ptr) ((LD_QWORD_DISK(&(ptr)[HARD_DISK_GUID_OFFSET]) != HARD_DISK_GUID_FOR_ESP) && \ + (LD_QWORD_DISK(&(ptr)[HARD_DISK_GUID_OFFSET]) != HARD_DISK_GUID_FOR_MSP)) + +/* Command code for disk_ioctrl function */ +/* Generic command (Used by FatFs) */ +#define DISK_CTRL_SYNC 0 /* Complete pending write process */ +#define DISK_GET_SECTOR_COUNT 1 /* Get media size */ +#define DISK_GET_SECTOR_SIZE 2 /* Get sector size */ +#define DISK_GET_BLOCK_SIZE 3 /* Get erase block size */ +#define DISK_CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used */ + +/* Generic command (Not used by FatFs) */ +#define DISK_CTRL_POWER 5 /* Get/Set power status */ +#define DISK_CTRL_LOCK 6 /* Lock/Unlock media removal */ +#define DISK_CTRL_EJECT 7 /* Eject media */ +#define DISK_CTRL_FORMAT 8 /* Create physical format on the media */ + +/* MMC/SDC specific ioctl command */ +#define DISK_MMC_GET_TYPE 10 /* Get card type */ +#define DISK_MMC_GET_CSD 11 /* Get CSD */ +#define DISK_MMC_GET_CID 12 /* Get CID */ +#define DISK_MMC_GET_OCR 13 /* Get OCR */ +#define DISK_MMC_GET_SDSTAT 14 /* Get SD status */ + +/* ATA/CF specific ioctl command */ +#define DISK_ATA_GET_REV 20 /* Get F/W revision */ +#define DISK_ATA_GET_MODEL 21 /* Get model name */ +#define DISK_ATA_GET_SN 22 /* Get serial number */ + +#ifndef LOSCFG_FS_FAT_CACHE +#define DISK_DIRECT_BUFFER_SIZE 4 /* los_disk direct io buffer when bcache is off */ +#endif + +typedef enum _disk_status_ { + STAT_UNUSED, + STAT_INUSED, + STAT_UNREADY +} disk_status_e; + +typedef struct _los_disk_ { + UINT32 disk_id : 8; /* physics disk number */ + UINT32 disk_status : 2; /* status of disk */ + UINT32 part_count : 8; /* current partition count */ + UINT32 reserved : 14; + struct Vnode *dev; /* device */ +#ifdef LOSCFG_FS_FAT_CACHE + OsBcache *bcache; /* cache of the disk, shared in all partitions */ +#endif + UINT32 sector_size; /* disk sector size */ + UINT64 sector_start; /* disk start sector */ + UINT64 sector_count; /* disk sector number */ + UINT8 type; + CHAR *disk_name; + LOS_DL_LIST head; /* link head of all the partitions */ + struct pthread_mutex disk_mutex; +#ifndef LOSCFG_FS_FAT_CACHE + UINT8 *buff; +#endif +} los_disk; + +typedef struct _los_part_ { + UINT32 disk_id : 8; /* physics disk number */ + UINT32 part_id : 8; /* partition number in the system */ + UINT32 part_no_disk : 8; /* partition number in the disk */ + UINT32 part_no_mbr : 5; /* partition number in the mbr */ + UINT32 reserved : 3; + UINT8 filesystem_type; /* filesystem used in the partition */ + UINT8 type; + struct Vnode *dev; /* dev devices used in the partition */ + CHAR *part_name; + UINT64 sector_start; /* + * offset of a partition to the primary devices + * (multi-mbr partitions are seen as same parition) + */ + UINT64 sector_count; /* + * sector numbers of a partition. If there is no addpartition operation, + * then all the mbr devices equal to the primary device count. + */ + LOS_DL_LIST list; /* linklist of partition */ +} los_part; + +struct partition_info { + UINT8 type; + UINT64 sector_start; + UINT64 sector_count; +}; + +struct disk_divide_info { + UINT64 sector_count; + UINT32 sector_size; + UINT32 part_count; + /* + * The primary partition place should be reversed and set to 0 in case all the partitions are + * logical partition (maximum 16 currently). So the maximum part number should be 4 + 16. + */ + struct partition_info part[MAX_DIVIDE_PART_PER_DISK + MAX_PRIMARY_PART_PER_DISK]; +}; + +/** + * @ingroup disk + * @brief Disk driver initialization. + * + * @par Description: + * Initializate a disk dirver, and set the block cache. + * + * @attention + *
            + *
          • The parameter diskName must point a valid string, which end with the terminating null byte.
          • + *
          • The total length of parameter diskName must be less than the value defined by PATH_MAX.
          • + *
          • The parameter bops must pointed the right functions, otherwise the system + * will crash when the disk is being operated.
          • + *
          • The parameter info can be null or point to struct disk_divide_info. when info is null, + * the disk will be divided base the information of MBR, otherwise, + * the disk will be divided base the information of parameter info.
          • + *
          + * + * @param diskName [IN] Type #const CHAR * disk driver name. + * @param bops [IN] Type #const struct block_operations * block driver control structure. + * @param priv [IN] Type #VOID * private data of vnode. + * @param diskID [IN] Type #INT32 disk id number, less than SYS_MAX_DISK. + * @param info [IN] Type #VOID * disk driver partition information. + * + * @retval #0 Initialization success. + * @retval #-1 Initialization failed. + * + * @par Dependency: + *
          • disk.h
          + * @see los_disk_deinit + * + */ +INT32 los_disk_init(const CHAR *diskName, const struct block_operations *bops, + VOID *priv, INT32 diskID, VOID *info); + +/** + * @ingroup disk + * @brief Destroy a disk driver. + * + * @par Description: + * Destroy a disk driver, free the dependent resource. + * + * @attention + *
            + * None + *
          + * + * @param diskID [IN] Type #INT32 disk driver id number, less than the value defined by SYS_MAX_DISK. + * + * @retval #0 Destroy success. + * @retval #-1 Destroy failed. + * + * @par Dependency: + *
          • disk.h
          + * @see los_disk_init + * + */ +INT32 los_disk_deinit(INT32 diskID); + +/** + * @ingroup disk + * @brief Read data from disk driver. + * + * @par Description: + * Read data from disk driver. + * + * @attention + *
            + *
          • The sector size of the disk to be read should be acquired by los_part_ioctl before calling this function.
          • + *
          • The parameter buf must point to a valid memory and the buf size is count * sector_size.
          • + *
          + * + * @param drvID [IN] Type #INT32 disk driver id number, less than the value defined by SYS_MAX_DISK. + * @param buf [OUT] Type #VOID * memory which used to store read data. + * @param sector [IN] Type #UINT64 expected start sector number to read. + * @param count [IN] Type #UINT32 expected sector count to read. + * @param useRead [IN] Type #BOOL set FALSE to use the write block for optimization + * + * @retval #0 Read success. + * @retval #-1 Read failed. + * + * @par Dependency: + *
          • disk.h
          + * @see los_disk_write + * + */ +INT32 los_disk_read(INT32 drvID, VOID *buf, UINT64 sector, UINT32 count, BOOL useRead); + +/** + * @ingroup disk + * @brief Write data to a disk driver. + * + * @par Description: + * Write data to a disk driver. + * + * @attention + *
            + *
          • The sector size of the disk to be read should be acquired by los_part_ioctl before calling this function.
          • + *
          • The parameter buf must point to a valid memory and the buf size is count * sector_size.
          • + *
          + * + * @param drvID [IN] Type #INT32 disk driver id number, less than the value defined by SYS_MAX_DISK. + * @param buf [IN] Type #const VOID * memory which used to storage write data. + * @param sector [IN] Type #UINT64 expected start sector number to read. + * @param count [IN] Type #UINT32 experted sector count of write. + * + * @retval #0 Write success. + * @retval #-1 Write failed. + * + * @par Dependency: + *
          • disk.h
          + * @see los_disk_read + * + */ +INT32 los_disk_write(INT32 drvID, const VOID *buf, UINT64 sector, UINT32 count); + +/** + * @ingroup disk + * @brief Get information of disk driver. + * + * @par Description: + * Get information of disk driver. + * + * @attention + *
            + * None + *
          + * + * @param drvID [IN] Type #INT32 disk driver id number, less than the value defined by SYS_MAX_DISK. + * @param cmd [IN] Type #INT32 command to issu, currently support GET_SECTOR_COUNT, GET_SECTOR_SIZE, + * GET_BLOCK_SIZE, CTRL_SYNC. + * @param buf [OUT] Type #VOID * memory to storage the information, the size must enough for data type(UINT64) + * when cmd type is DISK_GET_SECTOR_COUNT, others is size_t. + * + * @retval #0 Get information success. + * @retval #-1 Get information failed. + * + * @par Dependency: + *
          • disk.h
          + * @see None + * + */ +INT32 los_disk_ioctl(INT32 drvID, INT32 cmd, VOID *buf); + +/** + * @ingroup disk + * @brief Sync blib cache. + * + * @par Description: + * Sync blib cache, write the valid data to disk driver. + * + * @attention + *
            + * None + *
          + * + * @param drvID [IN] Type #INT32 disk driver id number, less than the value defined by SYS_MAX_DISK. + * + * @retval #0 Sync success. + * @retval #INT32 Sync failed. + * + * @par Dependency: + *
          • disk.h
          + * @see None + * + */ +INT32 los_disk_sync(INT32 drvID); + +/** + * @ingroup disk + * @brief Set blib cache for the disk driver. + * + * @par Description: + * Set blib cache for the disk driver, users can set the number of sectors of per block, + * and the number of blocks. + * + * @attention + *
            + * None + *
          + * + * @param drvID [IN] Type #INT32 disk driver id number, less than the value defined by SYS_MAX_DISK. + * @param sectorPerBlock [IN] Type #UINT32 sector number of per block, only can be 32 * (1, 2, ..., 8). + * @param blockNum [IN] Type #UINT32 block number of cache. + * + * @retval #0 Set success. + * @retval #INT32 Set failed. + * + * @par Dependency: + *
          • disk.h
          + * @see None + * + */ +INT32 los_disk_set_bcache(INT32 drvID, UINT32 sectorPerBlock, UINT32 blockNum); + +/** + * @ingroup disk + * @brief Read data from chosen partition. + * + * @par Description: + * Read data from chosen partition. + * + * @attention + *
            + *
          • The sector size of the disk to be read should be acquired by los_part_ioctl before calling this function.
          • + *
          • The parameter buf must point to valid memory and the buf size is count * sector_size.
          • + *
          + * + * @param pt [IN] Type #INT32 partition number, less than the value defined by SYS_MAX_PART. + * @param buf [OUT] Type #VOID * memory which used to store the data to be read. + * @param sector [IN] Type #UINT64 start sector number of chosen partition. + * @param count [IN] Type #UINT32 the expected sector count for reading. + * @param useRead [IN] Type #BOOL FALSE when reading large contiguous data, TRUE for other situations + * + * @retval #0 Read success. + * @retval #-1 Read failed. + * + * @par Dependency: + *
          • disk.h
          + * @see los_part_read + * + */ +INT32 los_part_read(INT32 pt, VOID *buf, UINT64 sector, UINT32 count, BOOL useRead); + +/** + * @ingroup disk + * @brief Write data to chosen partition. + * + * @par Description: + * Write data to chosen partition. + * + * @attention + *
            + *
          • The sector size of the disk to be write should be acquired by los_part_ioctl before calling this function.
          • + *
          • The parameter buf must point to valid memory and the buf size is count * sector_size.
          • + *
          + * + * @param pt [IN] Type #INT32 partition number,less than the value defined by SYS_MAX_PART. + * @param buf [IN] Type #VOID * memory which used to storage the written data. + * @param sector [IN] Type #UINT64 start sector number of chosen partition. + * @param count [IN] Type #UINT32 the expected sector count for write. + * + * @retval #0 Write success. + * @retval #-1 Write failed. + * + * @par Dependency: + *
          • disk.h
          + * @see los_part_read + * + */ +INT32 los_part_write(INT32 pt, const VOID *buf, UINT64 sector, UINT32 count); + +/** + * @ingroup disk + * @brief Clear the bcache data + * + * @par Description: + * Flush the data and mark the block as unused. + * + * @attention + *
            + * None + *
          + * + * @param drvID [IN] Type #INT32 disk id + * + * @retval #0 Write success. + * @retval #-1 Write failed. + * + * @par Dependency: + *
          • disk.h
          + * @see los_part_read + * + */ +INT32 los_disk_cache_clear(INT32 drvID); + +/** + * @ingroup disk + * @brief Get information of chosen partition. + * + * @par Description: + * By passed command to get information of chosen partition. + * + * @attention + *
            + * None + *
          + * + * @param pt [IN] Type #INT32 partition number,less than the value defined by SYS_MAX_PART. + * @param cmd [IN] Type #INT32 command to issu, currently support GET_SECTOR_COUNT, GET_SECTOR_SIZE, + * GET_BLOCK_SIZE, CTRL_SYNC. + * @param buf [OUT] Type #VOID * memory to store the information, the size must enough for data type (UINT64) + * when cmd type is DISK_GET_SECTOR_COUNT, others is size_t. + * + * @retval #0 Get information success. + * @retval #-1 Get information failed. + * + * @par Dependency: + *
          • disk.h
          + * @see None + * + */ +INT32 los_part_ioctl(INT32 pt, INT32 cmd, VOID *buf); + +/** + * @ingroup disk + * @brief Decide the chosen partition is exist or not. + * + * @par Description: + * Decide the chosen partition is exist or not. + * + * @attention + *
            + *
          • The parameter dev is a full path, which begin with '/' and end with '/0'.
          • + *
          + * + * @param dev [IN] Type #const CHAR * partition driver name. + * @param mode [IN] Type #mode_t access modd. + * + * @retval #0 The chosen partition is exist. + * @retval #-1 The chosen partition is not exist. + * + * @par Dependency: + *
          • disk.h
          + * @see None + * + */ +INT32 los_part_access(const CHAR *dev, mode_t mode); + +/** + * @ingroup disk + * @brief Find disk partition. + * + * @par Description: + * By driver partition vnode to find disk partition. + * + * @attention + *
            + * None + *
          + * + * @param blkDriver [IN] Type #struct Vnode * partition driver vnode. + * + * @retval #NULL Can't find chosen disk partition. + * @retval #los_part * This is partition structure pointer of chosen disk partition. + * + * @par Dependency: + *
          • disk.h
          + * @see None + * + */ +los_part *los_part_find(struct Vnode *blkDriver); + +/** + * @ingroup disk + * @brief Find disk driver. + * + * @par Description: + * By disk driver id number to find disk dirver. + * + * @attention + *
            + * None + *
          + * + * @param id [IN] Type #INT32 disk id number,less than the value defined by SYS_MAX_DISK. + * + * @retval #NULL Can't find chosen disk driver. + * @retval #los_disk * This is disk structure pointer of chosen disk driver. + * + * @par Dependency: + *
          • disk.h
          + * @see None + * + */ +los_disk *get_disk(INT32 id); + +/** + * @ingroup disk + * @brief Find disk partition. + * + * @par Description: + * By driver partition id number to find disk partition. + * + * @attention + *
            + * None + *
          + * + * @param id [IN] Type #INT32 partition id number,less than the value defined by SYS_MAX_PART. + * + * @retval #NULL Can't find chosen disk partition. + * @retval #los_part * This is partition structure pointer of chosen disk partition. + * + * @par Dependency: + *
          • disk.h
          + * @see None + * + */ +los_part *get_part(INT32 id); + +/** + * @ingroup disk + * @brief Print partition information. + * + * @par Description: + * Print partition information. + * + * @attention + *
            + * None + *
          + * + * @param part [IN] Type #los_part * partition control structure pointer + * + * @par Dependency: + *
          • disk.h
          + * @see None + * + */ +VOID show_part(los_part *part); + +/** + * @ingroup disk + * @brief Add a new mmc partition. + * + * @par Description: + * Add a new mmc partition, users can set the start sector and size of the new partition. + * + * @attention + *
            + * None + *
          + * + * @param info [IN] Type #struct disk_divide_info * Disk driver information structure pointer. + * @param sectorStart [IN] Type #size_t Start sector number of the new partition. + * @param sectorCount [IN] Type #size_t Sector count of the new partition. + * + * @retval #0 Add partition success. + * @retval #-1 Add partition failed. + * + * @par Dependency: + *
          • disk.h
          + * @see None + * + */ +INT32 add_mmc_partition(struct disk_divide_info *info, size_t sectorStart, size_t sectorCount); + +/** + * @ingroup disk + * @brief alloc a new UNUSED disk id. + * + * @par Description: + * Get a free disk id for new device. + * + * @attention + *
            + *
          • The parameter diskName must point a valid string, which end with the null byte ('\0')
          • + *
          • The total length of parameter diskName must be less than the value defined by DISK_NAME
          • + *
          + * + * @param diskName [IN] Type #const CHAR * device name. + * + * @retval #INT32 available disk id + * @retval #-1 alloc disk id failed + + * @par Dependency: + *
          • disk.h
          + * @see los_get_diskid_byname + * + */ +INT32 los_alloc_diskid_byname(const CHAR *diskName); + +/** + * @ingroup disk + * @brief get the INUSED disk id. + * + * @par Description: + * Get the corresponding INUSED disk id by diskName. + * + * @attention + *
            + *
          • The parameter diskName must point a valid string, which end with the null byte ('\0')
          • + *
          • The total length of parameter diskName must be less than the value defined by DISK_NAME
          • + *
          + * + * @param diskName [IN] Type #const CHAR * device name. + * + * @retval #INT32 available disk id + * @retval #-1 get disk id failed + + * @par Dependency: + *
          • disk.h
          + * @see los_alloc_diskid_byname + * + */ +INT32 los_get_diskid_byname(const CHAR *diskName); + + +los_disk *los_get_mmcdisk_bytype(UINT8 type); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif diff --git a/src/kernel_liteos_a/drivers/block/disk/include/disk_pri.h b/src/kernel_liteos_a/drivers/block/disk/include/disk_pri.h new file mode 100644 index 00000000..573f1b5c --- /dev/null +++ b/src/kernel_liteos_a/drivers/block/disk/include/disk_pri.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup disk Disk + * @ingroup filesystem + */ + +#ifndef _DISK_PRI_H +#define _DISK_PRI_H + +#include "linux/spinlock.h" +#include "disk.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +extern spinlock_t g_diskSpinlock; +extern spinlock_t g_diskFatBlockSpinlock; + +#ifdef LOSCFG_FS_FAT_CACHE +extern UINT32 GetFatBlockNums(VOID); +extern VOID SetFatBlockNums(UINT32 blockNums); +extern UINT32 GetFatSectorsPerBlock(VOID); +extern VOID SetFatSectorsPerBlock(UINT32 sectorsPerBlock); +#endif + +extern INT32 SetDiskPartName(los_part *part, const CHAR *src); + +extern INT32 EraseDiskByID(UINT32 diskID, size_t startSector, UINT32 sectors); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif diff --git a/src/kernel_liteos_a/drivers/block/disk/include/driver.h b/src/kernel_liteos_a/drivers/block/disk/include/driver.h new file mode 100644 index 00000000..d2dcf27f --- /dev/null +++ b/src/kernel_liteos_a/drivers/block/disk/include/driver.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __FS_DRIVER_DRIVER_H +#define __FS_DRIVER_DRIVER_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "vfs_config.h" +#include "fs/file.h" + + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** +* Global Variables +****************************************************************************/ + +/** + * @ingroup disk + * @brief Set usb mode. + * + * @par Description: + * Set the corresponding bit of g_usbMode as usb host mode. + * + * @attention + *
            + *
          • diskId should be [0,SYS_MAX_DISK)
          • + *
          + * + * @param diskId [IN] Type # unsigned int disk id. + * + * @par Dependency: + *
          • driver.h
          + * @see OsClearUsbStatus + * + */ +VOID OsSetUsbStatus(UINT32 diskId); + +/** + * @ingroup disk + * @brief Set usb mode. + * + * @par Description: + * Clear the corresponding bit of g_usbMode as usb host mode. + * + * @attention + *
            + *
          • diskId should be [0,SYS_MAX_DISK)
          • + *
          + * + * @param diskId [IN] Type # unsigned int disk id. + * + * @par Dependency: + *
          • driver.h
          + * @see OsSetUsbStatus + * + */ +VOID OsClearUsbStatus(UINT32 diskId); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ +#endif /* __FS_DRIVER_DRIVER_H */ diff --git a/src/kernel_liteos_a/drivers/block/disk/src/disk.c b/src/kernel_liteos_a/drivers/block/disk/src/disk.c new file mode 100644 index 00000000..60ecf2c2 --- /dev/null +++ b/src/kernel_liteos_a/drivers/block/disk/src/disk.c @@ -0,0 +1,1799 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "disk.h" +#include "stdio.h" +#include "stdlib.h" +#include "unistd.h" +#include "sys/mount.h" +#include "linux/spinlock.h" +#include "path_cache.h" +#ifndef LOSCFG_FS_FAT_CACHE +#include "los_vm_common.h" +#include "user_copy.h" +#endif + +los_disk g_sysDisk[SYS_MAX_DISK]; +los_part g_sysPart[SYS_MAX_PART]; + +UINT32 g_uwFatSectorsPerBlock = CONFIG_FS_FAT_SECTOR_PER_BLOCK; +UINT32 g_uwFatBlockNums = CONFIG_FS_FAT_BLOCK_NUMS; + +spinlock_t g_diskSpinlock; +spinlock_t g_diskFatBlockSpinlock; + +UINT32 g_usbMode = 0; + +#define MEM_ADDR_ALIGN_BYTE 64 +#define RWE_RW_RW 0755 + +#define DISK_LOCK(mux) do { \ + if (pthread_mutex_lock(mux) != 0) { \ + PRINT_ERR("%s %d, mutex lock failed\n", __FUNCTION__, __LINE__); \ + } \ +} while (0) + +#define DISK_UNLOCK(mux) do { \ + if (pthread_mutex_unlock(mux) != 0) { \ + PRINT_ERR("%s %d, mutex unlock failed\n", __FUNCTION__, __LINE__); \ + } \ +} while (0) + +typedef VOID *(*StorageHookFunction)(VOID *); + +#ifdef LOSCFG_FS_FAT_CACHE +static UINT32 OsReHookFuncAddDiskRef(StorageHookFunction handler, + VOID *param) __attribute__((weakref("osReHookFuncAdd"))); + +static UINT32 OsReHookFuncDelDiskRef(StorageHookFunction handler) __attribute__((weakref("osReHookFuncDel"))); + +UINT32 GetFatBlockNums(VOID) +{ + return g_uwFatBlockNums; +} + +VOID SetFatBlockNums(UINT32 blockNums) +{ + g_uwFatBlockNums = blockNums; +} + +UINT32 GetFatSectorsPerBlock(VOID) +{ + return g_uwFatSectorsPerBlock; +} + +VOID SetFatSectorsPerBlock(UINT32 sectorsPerBlock) +{ + if (((sectorsPerBlock % UNSIGNED_INTEGER_BITS) == 0) && + ((sectorsPerBlock >> UNINT_LOG2_SHIFT) <= BCACHE_BLOCK_FLAGS)) { + g_uwFatSectorsPerBlock = sectorsPerBlock; + } +} +#endif + +INT32 los_alloc_diskid_byname(const CHAR *diskName) +{ + INT32 diskID; + los_disk *disk = NULL; + UINT32 intSave; + size_t nameLen; + + if (diskName == NULL) { + PRINT_ERR("The parameter disk_name is NULL"); + return VFS_ERROR; + } + + nameLen = strlen(diskName); + if (nameLen > DISK_NAME) { + PRINT_ERR("diskName is too long!\n"); + return VFS_ERROR; + } + spin_lock_irqsave(&g_diskSpinlock, intSave); + + for (diskID = 0; diskID < SYS_MAX_DISK; diskID++) { + disk = get_disk(diskID); + if ((disk != NULL) && (disk->disk_status == STAT_UNUSED)) { + disk->disk_status = STAT_UNREADY; + break; + } + } + + spin_unlock_irqrestore(&g_diskSpinlock, intSave); + + if ((disk == NULL) || (diskID == SYS_MAX_DISK)) { + PRINT_ERR("los_alloc_diskid_byname failed %d!\n", diskID); + return VFS_ERROR; + } + + if (disk->disk_name != NULL) { + LOS_MemFree(m_aucSysMem0, disk->disk_name); + disk->disk_name = NULL; + } + + disk->disk_name = LOS_MemAlloc(m_aucSysMem0, (nameLen + 1)); + if (disk->disk_name == NULL) { + PRINT_ERR("los_alloc_diskid_byname alloc disk name failed\n"); + return VFS_ERROR; + } + + if (strncpy_s(disk->disk_name, (nameLen + 1), diskName, nameLen) != EOK) { + PRINT_ERR("The strncpy_s failed.\n"); + LOS_MemFree(m_aucSysMem0, disk->disk_name); + disk->disk_name = NULL; + return VFS_ERROR; + } + + disk->disk_name[nameLen] = '\0'; + + return diskID; +} + +INT32 los_get_diskid_byname(const CHAR *diskName) +{ + INT32 diskID; + los_disk *disk = NULL; + size_t diskNameLen; + + if (diskName == NULL) { + PRINT_ERR("The parameter diskName is NULL"); + return VFS_ERROR; + } + + diskNameLen = strlen(diskName); + if (diskNameLen > DISK_NAME) { + PRINT_ERR("diskName is too long!\n"); + return VFS_ERROR; + } + + for (diskID = 0; diskID < SYS_MAX_DISK; diskID++) { + disk = get_disk(diskID); + if ((disk != NULL) && (disk->disk_name != NULL) && (disk->disk_status == STAT_INUSED)) { + if (strlen(disk->disk_name) != diskNameLen) { + continue; + } + if (strcmp(diskName, disk->disk_name) == 0) { + break; + } + } + } + if ((disk == NULL) || (diskID == SYS_MAX_DISK)) { + PRINT_ERR("los_get_diskid_byname failed!\n"); + return VFS_ERROR; + } + return diskID; +} + +los_disk *los_get_mmcdisk_bytype(UINT8 type) +{ + const CHAR *mmcDevHead = "/dev/mmcblk"; + + for (INT32 diskId = 0; diskId < SYS_MAX_DISK; diskId++) { + los_disk *disk = get_disk(diskId); + if (disk == NULL) { + continue; + } else if ((disk->type == type) && (strncmp(disk->disk_name, mmcDevHead, strlen(mmcDevHead)) == 0)) { + return disk; + } + } + PRINT_ERR("Cannot find the mmc disk!\n"); + return NULL; +} + +VOID OsSetUsbStatus(UINT32 diskID) +{ + if (diskID < SYS_MAX_DISK) { + g_usbMode |= (1u << diskID) & UINT_MAX; + } +} + +VOID OsClearUsbStatus(UINT32 diskID) +{ + if (diskID < SYS_MAX_DISK) { + g_usbMode &= ~((1u << diskID) & UINT_MAX); + } +} + +#ifdef LOSCFG_FS_FAT_CACHE +static BOOL GetDiskUsbStatus(UINT32 diskID) +{ + return (g_usbMode & (1u << diskID)) ? TRUE : FALSE; +} +#endif + +los_disk *get_disk(INT32 id) +{ + if ((id >= 0) && (id < SYS_MAX_DISK)) { + return &g_sysDisk[id]; + } + + return NULL; +} + +los_part *get_part(INT32 id) +{ + if ((id >= 0) && (id < SYS_MAX_PART)) { + return &g_sysPart[id]; + } + + return NULL; +} + +static UINT64 GetFirstPartStart(const los_part *part) +{ + los_part *firstPart = NULL; + los_disk *disk = get_disk((INT32)part->disk_id); + firstPart = (disk == NULL) ? NULL : LOS_DL_LIST_ENTRY(disk->head.pstNext, los_part, list); + return (firstPart == NULL) ? 0 : firstPart->sector_start; +} + +static VOID DiskPartAddToDisk(los_disk *disk, los_part *part) +{ + part->disk_id = disk->disk_id; + part->part_no_disk = disk->part_count; + LOS_ListTailInsert(&disk->head, &part->list); + disk->part_count++; +} + +static VOID DiskPartDelFromDisk(los_disk *disk, los_part *part) +{ + LOS_ListDelete(&part->list); + disk->part_count--; +} + +static los_part *DiskPartAllocate(struct Vnode *dev, UINT64 start, UINT64 count) +{ + UINT32 i; + los_part *part = get_part(0); /* traversing from the beginning of the array */ + + if (part == NULL) { + return NULL; + } + + for (i = 0; i < SYS_MAX_PART; i++) { + if (part->dev == NULL) { + part->part_id = i; + part->part_no_mbr = 0; + part->dev = dev; + part->sector_start = start; + part->sector_count = count; + part->part_name = NULL; + LOS_ListInit(&part->list); + + return part; + } + part++; + } + + return NULL; +} + +static VOID DiskPartRelease(los_part *part) +{ + part->dev = NULL; + part->part_no_disk = 0; + part->part_no_mbr = 0; + if (part->part_name != NULL) { + free(part->part_name); + part->part_name = NULL; + } +} + +/* + * name is a combination of disk_name, 'p' and part_count, such as "/dev/mmcblk0p0" + * disk_name : DISK_NAME + 1 + * 'p' : 1 + * part_count: 1 + */ +#define DEV_NAME_BUFF_SIZE (DISK_NAME + 3) + +static INT32 DiskAddPart(los_disk *disk, UINT64 sectorStart, UINT64 sectorCount, BOOL IsValidPart) +{ + CHAR devName[DEV_NAME_BUFF_SIZE]; + struct Vnode *diskDev = NULL; + struct Vnode *partDev = NULL; + los_part *part = NULL; + INT32 ret; + + if ((disk == NULL) || (disk->disk_status == STAT_UNUSED) || + (disk->dev == NULL)) { + return VFS_ERROR; + } + + if ((sectorCount > disk->sector_count) || ((disk->sector_count - sectorCount) < sectorStart)) { + PRINT_ERR("DiskAddPart failed: sector start is %llu, sector count is %llu\n", sectorStart, sectorCount); + return VFS_ERROR; + } + + diskDev = disk->dev; + if (IsValidPart == TRUE) { + ret = snprintf_s(devName, sizeof(devName), sizeof(devName) - 1, "%s%c%u", + ((disk->disk_name == NULL) ? "null" : disk->disk_name), 'p', disk->part_count); + if (ret < 0) { + return VFS_ERROR; + } + + if (register_blockdriver(devName, ((struct drv_data *)diskDev->data)->ops, + RWE_RW_RW, ((struct drv_data *)diskDev->data)->priv)) { + PRINT_ERR("DiskAddPart : register %s fail!\n", devName); + return VFS_ERROR; + } + + VnodeHold(); + VnodeLookup(devName, &partDev, 0); + + part = DiskPartAllocate(partDev, sectorStart, sectorCount); + VnodeDrop(); + if (part == NULL) { + (VOID)unregister_blockdriver(devName); + return VFS_ERROR; + } + } else { + part = DiskPartAllocate(diskDev, sectorStart, sectorCount); + if (part == NULL) { + return VFS_ERROR; + } + } + + DiskPartAddToDisk(disk, part); + if (disk->type == EMMC) { + part->type = EMMC; + } + return (INT32)part->part_id; +} + +static INT32 DiskDivide(los_disk *disk, struct disk_divide_info *info) +{ + UINT32 i; + INT32 ret; + + disk->type = info->part[0].type; + for (i = 0; i < info->part_count; i++) { + if (info->sector_count < info->part[i].sector_start) { + return VFS_ERROR; + } + if (info->part[i].sector_count > (info->sector_count - info->part[i].sector_start)) { + PRINT_ERR("Part[%u] sector_start:%llu, sector_count:%llu, exceed emmc sector_count:%llu.\n", i, + info->part[i].sector_start, info->part[i].sector_count, + (info->sector_count - info->part[i].sector_start)); + info->part[i].sector_count = info->sector_count - info->part[i].sector_start; + PRINT_ERR("Part[%u] sector_count change to %llu.\n", i, info->part[i].sector_count); + + ret = DiskAddPart(disk, info->part[i].sector_start, info->part[i].sector_count, TRUE); + if (ret == VFS_ERROR) { + return VFS_ERROR; + } + break; + } + ret = DiskAddPart(disk, info->part[i].sector_start, info->part[i].sector_count, TRUE); + if (ret == VFS_ERROR) { + return VFS_ERROR; + } + } + + return ENOERR; +} + +static CHAR GPTPartitionTypeRecognition(const CHAR *parBuf) +{ + const CHAR *buf = parBuf; + const CHAR *fsType = "FAT"; + const CHAR *str = "\xEB\x52\x90" "NTFS "; /* NTFS Boot entry point */ + + if (((LD_DWORD_DISK(&buf[BS_FILSYSTEMTYPE32]) & BS_FS_TYPE_MASK) == BS_FS_TYPE_VALUE) || + (strncmp(&buf[BS_FILSYSTYPE], fsType, strlen(fsType)) == 0)) { + return BS_FS_TYPE_FAT; + } else if (strncmp(&buf[BS_JMPBOOT], str, strlen(str)) == 0) { + return BS_FS_TYPE_NTFS; + } + + return ENOERR; +} + +static INT32 DiskPartitionMemZalloc(size_t boundary, size_t size, CHAR **gptBuf, CHAR **partitionBuf) +{ + CHAR *buffer1 = NULL; + CHAR *buffer2 = NULL; + + buffer1 = (CHAR *)memalign(boundary, size); + if (buffer1 == NULL) { + PRINT_ERR("%s buffer1 malloc %lu failed! %d\n", __FUNCTION__, size, __LINE__); + return -ENOMEM; + } + buffer2 = (CHAR *)memalign(boundary, size); + if (buffer2 == NULL) { + PRINT_ERR("%s buffer2 malloc %lu failed! %d\n", __FUNCTION__, size, __LINE__); + free(buffer1); + return -ENOMEM; + } + (VOID)memset_s(buffer1, size, 0, size); + (VOID)memset_s(buffer2, size, 0, size); + + *gptBuf = buffer1; + *partitionBuf = buffer2; + + return ENOERR; +} + +static INT32 GPTInfoGet(struct Vnode *blkDrv, CHAR *gptBuf) +{ + INT32 ret; + + struct block_operations *bops = (struct block_operations *)((struct drv_data *)blkDrv->data)->ops; + + ret = bops->read(blkDrv, (UINT8 *)gptBuf, 1, 1); /* Read the device first sector */ + if (ret != 1) { /* Read failed */ + PRINT_ERR("%s %d\n", __FUNCTION__, __LINE__); + return -EIO; + } + + if (!VERIFY_GPT(gptBuf)) { + PRINT_ERR("%s %d\n", __FUNCTION__, __LINE__); + return VFS_ERROR; + } + + return ENOERR; +} + +static INT32 OsGPTPartitionRecognitionSub(struct disk_divide_info *info, const CHAR *partitionBuf, + UINT32 *partitionCount, UINT64 partitionStart, UINT64 partitionEnd) +{ + CHAR partitionType; + + if (VERIFY_FS(partitionBuf)) { + partitionType = GPTPartitionTypeRecognition(partitionBuf); + if (partitionType) { + if (*partitionCount >= MAX_DIVIDE_PART_PER_DISK) { + return VFS_ERROR; + } + info->part[*partitionCount].type = partitionType; + info->part[*partitionCount].sector_start = partitionStart; + info->part[*partitionCount].sector_count = (partitionEnd - partitionStart) + 1; + (*partitionCount)++; + } else { + PRINT_ERR("The partition type is not allowed to use!\n"); + } + } else { + PRINT_ERR("Do not support the partition type!\n"); + } + return ENOERR; +} + +static INT32 OsGPTPartitionRecognition(struct Vnode *blkDrv, struct disk_divide_info *info, + const CHAR *gptBuf, CHAR *partitionBuf, UINT32 *partitionCount) +{ + UINT32 j; + INT32 ret = VFS_ERROR; + UINT64 partitionStart, partitionEnd; + struct block_operations *bops = NULL; + + for (j = 0; j < PAR_ENTRY_NUM_PER_SECTOR; j++) { + if (!VERITY_AVAILABLE_PAR(&gptBuf[j * TABLE_SIZE])) { + PRINTK("The partition type is ESP or MSR!\n"); + continue; + } + + if (!VERITY_PAR_VALID(&gptBuf[j * TABLE_SIZE])) { + return VFS_ERROR; + } + + partitionStart = LD_QWORD_DISK(&gptBuf[(j * TABLE_SIZE) + GPT_PAR_START_OFFSET]); + partitionEnd = LD_QWORD_DISK(&gptBuf[(j * TABLE_SIZE) + GPT_PAR_END_OFFSET]); + if ((partitionStart >= partitionEnd) || (partitionEnd > info->sector_count)) { + PRINT_ERR("GPT partition %u recognition failed : partitionStart = %llu, partitionEnd = %llu\n", + j, partitionStart, partitionEnd); + return VFS_ERROR; + } + + (VOID)memset_s(partitionBuf, info->sector_size, 0, info->sector_size); + + bops = (struct block_operations *)((struct drv_data *)blkDrv->data)->ops; + + ret = bops->read(blkDrv, (UINT8 *)partitionBuf, partitionStart, 1); + if (ret != 1) { /* read failed */ + PRINT_ERR("%s %d\n", __FUNCTION__, __LINE__); + return -EIO; + } + + ret = OsGPTPartitionRecognitionSub(info, partitionBuf, partitionCount, partitionStart, partitionEnd); + if (ret != ENOERR) { + return VFS_ERROR; + } + } + + return ret; +} + +static INT32 DiskGPTPartitionRecognition(struct Vnode *blkDrv, struct disk_divide_info *info) +{ + CHAR *gptBuf = NULL; + CHAR *partitionBuf = NULL; + UINT32 tableNum, i, index; + UINT32 partitionCount = 0; + INT32 ret; + + ret = DiskPartitionMemZalloc(MEM_ADDR_ALIGN_BYTE, info->sector_size, &gptBuf, &partitionBuf); + if (ret != ENOERR) { + return ret; + } + + ret = GPTInfoGet(blkDrv, gptBuf); + if (ret < 0) { + goto OUT_WITH_MEM; + } + + tableNum = LD_DWORD_DISK(&gptBuf[TABLE_NUM_OFFSET]); + if (tableNum > TABLE_MAX_NUM) { + tableNum = TABLE_MAX_NUM; + } + + index = (tableNum % PAR_ENTRY_NUM_PER_SECTOR) ? ((tableNum / PAR_ENTRY_NUM_PER_SECTOR) + 1) : + (tableNum / PAR_ENTRY_NUM_PER_SECTOR); + + for (i = 0; i < index; i++) { + (VOID)memset_s(gptBuf, info->sector_size, 0, info->sector_size); + struct block_operations *bops = (struct block_operations *)((struct drv_data *)blkDrv->data)->ops; + ret = bops->read(blkDrv, (UINT8 *)gptBuf, TABLE_START_SECTOR + i, 1); + if (ret != 1) { /* read failed */ + PRINT_ERR("%s %d\n", __FUNCTION__, __LINE__); + ret = -EIO; + goto OUT_WITH_MEM; + } + + ret = OsGPTPartitionRecognition(blkDrv, info, gptBuf, partitionBuf, &partitionCount); + if (ret < 0) { + if (ret == VFS_ERROR) { + ret = (INT32)partitionCount; + } + goto OUT_WITH_MEM; + } + } + ret = (INT32)partitionCount; + +OUT_WITH_MEM: + free(gptBuf); + free(partitionBuf); + return ret; +} + +static INT32 OsMBRInfoGet(struct Vnode *blkDrv, CHAR *mbrBuf) +{ + INT32 ret; + + /* read MBR, start from sector 0, length is 1 sector */ + struct block_operations *bops = (struct block_operations *)((struct drv_data *)blkDrv->data)->ops; + + ret = bops->read(blkDrv, (UINT8 *)mbrBuf, 0, 1); + if (ret != 1) { /* read failed */ + PRINT_ERR("driver read return error: %d\n", ret); + return -EIO; + } + + /* Check boot record signature. */ + if (LD_WORD_DISK(&mbrBuf[BS_SIG55AA]) != BS_SIG55AA_VALUE) { + return VFS_ERROR; + } + + return ENOERR; +} + +static INT32 OsEBRInfoGet(struct Vnode *blkDrv, const struct disk_divide_info *info, + CHAR *ebrBuf, const CHAR *mbrBuf) +{ + INT32 ret; + + if (VERIFY_FS(mbrBuf)) { + if (info->sector_count <= LD_DWORD_DISK(&mbrBuf[PAR_OFFSET + PAR_START_OFFSET])) { + return VFS_ERROR; + } + + struct block_operations *bops = (struct block_operations *)((struct drv_data *)blkDrv->data)->ops; + ret = bops->read(blkDrv, (UINT8 *)ebrBuf, LD_DWORD_DISK(&mbrBuf[PAR_OFFSET + PAR_START_OFFSET]), 1); + if ((ret != 1) || (!VERIFY_FS(ebrBuf))) { /* read failed */ + PRINT_ERR("OsEBRInfoGet, verify_fs error, ret = %d\n", ret); + return -EIO; + } + } + + return ENOERR; +} + +static INT32 OsPrimaryPartitionRecognition(const CHAR *mbrBuf, struct disk_divide_info *info, + INT32 *extendedPos, INT32 *mbrCount) +{ + INT32 i; + CHAR mbrPartitionType; + INT32 extendedFlag = 0; + INT32 count = 0; + + for (i = 0; i < MAX_PRIMARY_PART_PER_DISK; i++) { + mbrPartitionType = mbrBuf[PAR_OFFSET + PAR_TYPE_OFFSET + (i * PAR_TABLE_SIZE)]; + if (mbrPartitionType) { + info->part[i].type = mbrPartitionType; + info->part[i].sector_start = LD_DWORD_DISK(&mbrBuf[PAR_OFFSET + PAR_START_OFFSET + (i * PAR_TABLE_SIZE)]); + info->part[i].sector_count = LD_DWORD_DISK(&mbrBuf[PAR_OFFSET + PAR_COUNT_OFFSET + (i * PAR_TABLE_SIZE)]); + if ((mbrPartitionType == EXTENDED_PAR) || (mbrPartitionType == EXTENDED_8G)) { + extendedFlag = 1; + *extendedPos = i; + continue; + } + count++; + } + } + *mbrCount = count; + + return extendedFlag; +} + +static INT32 OsLogicalPartitionRecognition(struct Vnode *blkDrv, struct disk_divide_info *info, + UINT32 extendedAddress, CHAR *ebrBuf, INT32 mbrCount) +{ + INT32 ret; + UINT32 extendedOffset = 0; + CHAR ebrPartitionType; + INT32 ebrCount = 0; + + do { + (VOID)memset_s(ebrBuf, info->sector_size, 0, info->sector_size); + if (((UINT64)(extendedAddress) + extendedOffset) >= info->sector_count) { + PRINT_ERR("extended partition is out of disk range: extendedAddress = %u, extendedOffset = %u\n", + extendedAddress, extendedOffset); + break; + } + struct block_operations *bops = (struct block_operations *)((struct drv_data *)blkDrv->data)->ops; + ret = bops->read(blkDrv, (UINT8 *)ebrBuf, extendedAddress + extendedOffset, 1); + if (ret != 1) { /* read failed */ + PRINT_ERR("driver read return error: %d, extendedAddress = %u, extendedOffset = %u\n", ret, + extendedAddress, extendedOffset); + return -EIO; + } + ebrPartitionType = ebrBuf[PAR_OFFSET + PAR_TYPE_OFFSET]; + if (ebrPartitionType && ((mbrCount + ebrCount) < MAX_DIVIDE_PART_PER_DISK)) { + info->part[MAX_PRIMARY_PART_PER_DISK + ebrCount].type = ebrPartitionType; + info->part[MAX_PRIMARY_PART_PER_DISK + ebrCount].sector_start = extendedAddress + extendedOffset + + LD_DWORD_DISK(&ebrBuf[PAR_OFFSET + + PAR_START_OFFSET]); + info->part[MAX_PRIMARY_PART_PER_DISK + ebrCount].sector_count = LD_DWORD_DISK(&ebrBuf[PAR_OFFSET + + PAR_COUNT_OFFSET]); + ebrCount++; + } + extendedOffset = LD_DWORD_DISK(&ebrBuf[PAR_OFFSET + PAR_START_OFFSET + PAR_TABLE_SIZE]); + } while ((ebrBuf[PAR_OFFSET + PAR_TYPE_OFFSET + PAR_TABLE_SIZE] != 0) && + ((mbrCount + ebrCount) < MAX_DIVIDE_PART_PER_DISK)); + + return ebrCount; +} + +static INT32 DiskPartitionRecognition(struct Vnode *blkDrv, struct disk_divide_info *info) +{ + INT32 ret; + INT32 extendedFlag; + INT32 extendedPos = 0; + INT32 mbrCount = 0; + UINT32 extendedAddress; + CHAR *mbrBuf = NULL; + CHAR *ebrBuf = NULL; + + if (blkDrv == NULL) { + return -EINVAL; + } + + struct block_operations *bops = (struct block_operations *)((struct drv_data *)blkDrv->data)->ops; + + if ((bops == NULL) || (bops->read == NULL)) { + return -EINVAL; + } + + ret = DiskPartitionMemZalloc(MEM_ADDR_ALIGN_BYTE, info->sector_size, &mbrBuf, &ebrBuf); + if (ret != ENOERR) { + return ret; + } + + ret = OsMBRInfoGet(blkDrv, mbrBuf); + if (ret < 0) { + goto OUT_WITH_MEM; + } + + /* The partition type is GPT */ + if (mbrBuf[PARTION_MODE_BTYE] == (CHAR)PARTION_MODE_GPT) { + ret = DiskGPTPartitionRecognition(blkDrv, info); + goto OUT_WITH_MEM; + } + + ret = OsEBRInfoGet(blkDrv, info, ebrBuf, mbrBuf); + if (ret < 0) { + ret = 0; /* no mbr */ + goto OUT_WITH_MEM; + } + + extendedFlag = OsPrimaryPartitionRecognition(mbrBuf, info, &extendedPos, &mbrCount); + if (extendedFlag) { + extendedAddress = LD_DWORD_DISK(&mbrBuf[PAR_OFFSET + PAR_START_OFFSET + (extendedPos * PAR_TABLE_SIZE)]); + ret = OsLogicalPartitionRecognition(blkDrv, info, extendedAddress, ebrBuf, mbrCount); + if (ret <= 0) { + goto OUT_WITH_MEM; + } + } + ret += mbrCount; + +OUT_WITH_MEM: + free(ebrBuf); + free(mbrBuf); + return ret; +} + +INT32 DiskPartitionRegister(los_disk *disk) +{ + INT32 count; + UINT32 i, partSize; + los_part *part = NULL; + struct disk_divide_info parInfo; + + /* Fill disk_divide_info structure to set partition's information. */ + (VOID)memset_s(parInfo.part, sizeof(parInfo.part), 0, sizeof(parInfo.part)); + partSize = sizeof(parInfo.part) / sizeof(parInfo.part[0]); + + parInfo.sector_size = disk->sector_size; + parInfo.sector_count = disk->sector_count; + count = DiskPartitionRecognition(disk->dev, &parInfo); + if (count == VFS_ERROR) { + part = get_part(DiskAddPart(disk, 0, disk->sector_count, FALSE)); + if (part == NULL) { + return VFS_ERROR; + } + part->part_no_mbr = 0; + PRINTK("Disk %s doesn't contain a valid partition table.\n", disk->disk_name); + return ENOERR; + } else if (count < 0) { + return VFS_ERROR; + } + + parInfo.part_count = count; + if (count == 0) { + part = get_part(DiskAddPart(disk, 0, disk->sector_count, TRUE)); + if (part == NULL) { + return VFS_ERROR; + } + part->part_no_mbr = 0; + + PRINTK("No MBR detected.\n"); + return ENOERR; + } + + for (i = 0; i < partSize; i++) { + /* Read the disk_divide_info structure to get partition's information. */ + if ((parInfo.part[i].type != 0) && (parInfo.part[i].type != EXTENDED_PAR) && + (parInfo.part[i].type != EXTENDED_8G)) { + part = get_part(DiskAddPart(disk, parInfo.part[i].sector_start, parInfo.part[i].sector_count, TRUE)); + if (part == NULL) { + return VFS_ERROR; + } + part->part_no_mbr = i + 1; + part->filesystem_type = parInfo.part[i].type; + } + } + + return ENOERR; +} + +#ifndef LOSCFG_FS_FAT_CACHE +static INT32 disk_read_directly(los_disk *disk, VOID *buf, UINT64 sector, UINT32 count) +{ + INT32 result = VFS_ERROR; + struct block_operations *bops = (struct block_operations *)((struct drv_data *)disk->dev->data)->ops; + if ((bops == NULL) || (bops->read == NULL)) { + return VFS_ERROR; + } + if (LOS_IsUserAddressRange((VADDR_T)buf, count * disk->sector_size)) { + UINT32 cnt = 0; + UINT8 *buffer = disk->buff; + for (; count != 0; count -= cnt) { + cnt = (count > DISK_DIRECT_BUFFER_SIZE) ? DISK_DIRECT_BUFFER_SIZE : count; + result = bops->read(disk->dev, buffer, sector, cnt); + if (result == (INT32)cnt) { + result = ENOERR; + } else { + break; + } + if (LOS_CopyFromKernel(buf, disk->sector_size * cnt, buffer, disk->sector_size * cnt)) { + result = VFS_ERROR; + break; + } + buf = (UINT8 *)buf + disk->sector_size * cnt; + sector += cnt; + } + } else { + result = bops->read(disk->dev, buf, sector, count); + if (result == count) { + result = ENOERR; + } + } + + return result; +} + +static INT32 disk_write_directly(los_disk *disk, const VOID *buf, UINT64 sector, UINT32 count) +{ + struct block_operations *bops = (struct block_operations *)((struct drv_data *)disk->dev->data)->ops; + INT32 result = VFS_ERROR; + if ((bops == NULL) || (bops->read == NULL)) { + return VFS_ERROR; + } + if (LOS_IsUserAddressRange((VADDR_T)buf, count * disk->sector_size)) { + UINT32 cnt = 0; + UINT8 *buffer = disk->buff; + for (; count != 0; count -= cnt) { + cnt = (count > DISK_DIRECT_BUFFER_SIZE) ? DISK_DIRECT_BUFFER_SIZE : count; + if (LOS_CopyToKernel(buffer, disk->sector_size * cnt, buf, disk->sector_size * cnt)) { + result = VFS_ERROR; + break; + } + result = bops->write(disk->dev, buffer, sector, cnt); + if (result == (INT32)cnt) { + result = ENOERR; + } else { + break; + } + buf = (UINT8 *)buf + disk->sector_size * cnt; + sector += cnt; + } + } else { + result = bops->write(disk->dev, buf, sector, count); + if (result == count) { + result = ENOERR; + } + } + + return result; +} +#endif + +INT32 los_disk_read(INT32 drvID, VOID *buf, UINT64 sector, UINT32 count, BOOL useRead) +{ +#ifdef LOSCFG_FS_FAT_CACHE + UINT32 len; +#endif + INT32 result = VFS_ERROR; + los_disk *disk = get_disk(drvID); + + if ((buf == NULL) || (count == 0)) { /* buff equal to NULL or count equal to 0 */ + return result; + } + + if (disk == NULL) { + return result; + } + + DISK_LOCK(&disk->disk_mutex); + + if (disk->disk_status != STAT_INUSED) { + goto ERROR_HANDLE; + } + + if ((count > disk->sector_count) || ((disk->sector_count - count) < sector)) { + goto ERROR_HANDLE; + } + +#ifdef LOSCFG_FS_FAT_CACHE + if (disk->bcache != NULL) { + if (((UINT64)(disk->bcache->sectorSize) * count) > UINT_MAX) { + goto ERROR_HANDLE; + } + len = disk->bcache->sectorSize * count; + /* useRead should be FALSE when reading large contiguous data */ + result = BlockCacheRead(disk->bcache, (UINT8 *)buf, &len, sector, useRead); + if (result != ENOERR) { + PRINT_ERR("los_disk_read read err = %d, sector = %llu, len = %u\n", result, sector, len); + } + } else { + result = VFS_ERROR; + } +#else + if (disk->dev == NULL) { + goto ERROR_HANDLE; + } + result = disk_read_directly(disk, buf, sector, count); +#endif + if (result != ENOERR) { + goto ERROR_HANDLE; + } + + DISK_UNLOCK(&disk->disk_mutex); + return ENOERR; + +ERROR_HANDLE: + DISK_UNLOCK(&disk->disk_mutex); + return VFS_ERROR; +} + +INT32 los_disk_write(INT32 drvID, const VOID *buf, UINT64 sector, UINT32 count) +{ +#ifdef LOSCFG_FS_FAT_CACHE + UINT32 len; +#endif + INT32 result = VFS_ERROR; + los_disk *disk = get_disk(drvID); + if (disk == NULL || disk->dev == NULL || disk->dev->data == NULL) { + return result; + } + + if ((buf == NULL) || (count == 0)) { /* buff equal to NULL or count equal to 0 */ + return result; + } + + DISK_LOCK(&disk->disk_mutex); + + if (disk->disk_status != STAT_INUSED) { + goto ERROR_HANDLE; + } + + if ((count > disk->sector_count) || ((disk->sector_count - count) < sector)) { + goto ERROR_HANDLE; + } + +#ifdef LOSCFG_FS_FAT_CACHE + if (disk->bcache != NULL) { + if (((UINT64)(disk->bcache->sectorSize) * count) > UINT_MAX) { + goto ERROR_HANDLE; + } + len = disk->bcache->sectorSize * count; + result = BlockCacheWrite(disk->bcache, (const UINT8 *)buf, &len, sector); + if (result != ENOERR) { + PRINT_ERR("los_disk_write write err = %d, sector = %llu, len = %u\n", result, sector, len); + } + } else { + result = VFS_ERROR; + } +#else + if (disk->dev == NULL) { + goto ERROR_HANDLE; + } + result = disk_write_directly(disk, buf, sector, count); +#endif + if (result != ENOERR) { + goto ERROR_HANDLE; + } + + DISK_UNLOCK(&disk->disk_mutex); + return ENOERR; + +ERROR_HANDLE: + DISK_UNLOCK(&disk->disk_mutex); + return VFS_ERROR; +} + +INT32 los_disk_ioctl(INT32 drvID, INT32 cmd, VOID *buf) +{ + struct geometry info; + los_disk *disk = get_disk(drvID); + if (disk == NULL) { + return VFS_ERROR; + } + + DISK_LOCK(&disk->disk_mutex); + + if ((disk->dev == NULL) || (disk->disk_status != STAT_INUSED)) { + goto ERROR_HANDLE; + } + + if (cmd == DISK_CTRL_SYNC) { + DISK_UNLOCK(&disk->disk_mutex); + return ENOERR; + } + + if (buf == NULL) { + goto ERROR_HANDLE; + } + + (VOID)memset_s(&info, sizeof(info), 0, sizeof(info)); + + struct block_operations *bops = (struct block_operations *)((struct drv_data *)disk->dev->data)->ops; + if ((bops == NULL) || (bops->geometry == NULL) || + (bops->geometry(disk->dev, &info) != 0)) { + goto ERROR_HANDLE; + } + + if (cmd == DISK_GET_SECTOR_COUNT) { + *(UINT64 *)buf = info.geo_nsectors; + if (info.geo_nsectors == 0) { + goto ERROR_HANDLE; + } + } else if (cmd == DISK_GET_SECTOR_SIZE) { + *(size_t *)buf = info.geo_sectorsize; + } else if (cmd == DISK_GET_BLOCK_SIZE) { /* Get erase block size in unit of sectors (UINT32) */ + /* Block Num SDHC == 512, SD can be set to 512 or other */ + *(size_t *)buf = DISK_MAX_SECTOR_SIZE / info.geo_sectorsize; + } else { + goto ERROR_HANDLE; + } + + DISK_UNLOCK(&disk->disk_mutex); + return ENOERR; + +ERROR_HANDLE: + DISK_UNLOCK(&disk->disk_mutex); + return VFS_ERROR; +} + +INT32 los_part_read(INT32 pt, VOID *buf, UINT64 sector, UINT32 count, BOOL useRead) +{ + const los_part *part = get_part(pt); + los_disk *disk = NULL; + INT32 ret; + + if (part == NULL) { + return VFS_ERROR; + } + + disk = get_disk((INT32)part->disk_id); + if (disk == NULL) { + return VFS_ERROR; + } + + DISK_LOCK(&disk->disk_mutex); + if ((part->dev == NULL) || (disk->disk_status != STAT_INUSED)) { + goto ERROR_HANDLE; + } + + if (count > part->sector_count) { + PRINT_ERR("los_part_read failed, invalid count, count = %u\n", count); + goto ERROR_HANDLE; + } + + /* Read from absolute sector. */ + if (part->type == EMMC) { + if ((disk->sector_count - part->sector_start) > sector) { + sector += part->sector_start; + } else { + PRINT_ERR("los_part_read failed, invalid sector, sector = %llu\n", sector); + goto ERROR_HANDLE; + } + } + + if ((sector >= GetFirstPartStart(part)) && + (((sector + count) > (part->sector_start + part->sector_count)) || (sector < part->sector_start))) { + PRINT_ERR("los_part_read error, sector = %llu, count = %u, part->sector_start = %llu, " + "part->sector_count = %llu\n", sector, count, part->sector_start, part->sector_count); + goto ERROR_HANDLE; + } + + /* useRead should be FALSE when reading large contiguous data */ + ret = los_disk_read((INT32)part->disk_id, buf, sector, count, useRead); + if (ret < 0) { + goto ERROR_HANDLE; + } + + DISK_UNLOCK(&disk->disk_mutex); + return ENOERR; + +ERROR_HANDLE: + DISK_UNLOCK(&disk->disk_mutex); + return VFS_ERROR; +} + +INT32 los_part_write(INT32 pt, const VOID *buf, UINT64 sector, UINT32 count) +{ + const los_part *part = get_part(pt); + los_disk *disk = NULL; + INT32 ret; + + if (part == NULL) { + return VFS_ERROR; + } + + disk = get_disk((INT32)part->disk_id); + if (disk == NULL) { + return VFS_ERROR; + } + + DISK_LOCK(&disk->disk_mutex); + if ((part->dev == NULL) || (disk->disk_status != STAT_INUSED)) { + goto ERROR_HANDLE; + } + + if (count > part->sector_count) { + PRINT_ERR("los_part_write failed, invalid count, count = %u\n", count); + goto ERROR_HANDLE; + } + + /* Write to absolute sector. */ + if (part->type == EMMC) { + if ((disk->sector_count - part->sector_start) > sector) { + sector += part->sector_start; + } else { + PRINT_ERR("los_part_write failed, invalid sector, sector = %llu\n", sector); + goto ERROR_HANDLE; + } + } + + if ((sector >= GetFirstPartStart(part)) && + (((sector + count) > (part->sector_start + part->sector_count)) || (sector < part->sector_start))) { + PRINT_ERR("los_part_write, sector = %llu, count = %u, part->sector_start = %llu, " + "part->sector_count = %llu\n", sector, count, part->sector_start, part->sector_count); + goto ERROR_HANDLE; + } + + ret = los_disk_write((INT32)part->disk_id, buf, sector, count); + if (ret < 0) { + goto ERROR_HANDLE; + } + + DISK_UNLOCK(&disk->disk_mutex); + return ENOERR; + +ERROR_HANDLE: + DISK_UNLOCK(&disk->disk_mutex); + return VFS_ERROR; +} + +#define GET_ERASE_BLOCK_SIZE 0x2 + +INT32 los_part_ioctl(INT32 pt, INT32 cmd, VOID *buf) +{ + struct geometry info; + los_part *part = get_part(pt); + los_disk *disk = NULL; + + if (part == NULL) { + return VFS_ERROR; + } + + disk = get_disk((INT32)part->disk_id); + if (disk == NULL) { + return VFS_ERROR; + } + + DISK_LOCK(&disk->disk_mutex); + if ((part->dev == NULL) || (disk->disk_status != STAT_INUSED)) { + goto ERROR_HANDLE; + } + + if (cmd == DISK_CTRL_SYNC) { + DISK_UNLOCK(&disk->disk_mutex); + return ENOERR; + } + + if (buf == NULL) { + goto ERROR_HANDLE; + } + + (VOID)memset_s(&info, sizeof(info), 0, sizeof(info)); + + struct block_operations *bops = (struct block_operations *)((struct drv_data *)part->dev->data)->ops; + if ((bops == NULL) || (bops->geometry == NULL) || + (bops->geometry(part->dev, &info) != 0)) { + goto ERROR_HANDLE; + } + + if (cmd == DISK_GET_SECTOR_COUNT) { + *(UINT64 *)buf = part->sector_count; + if (*(UINT64 *)buf == 0) { + goto ERROR_HANDLE; + } + } else if (cmd == DISK_GET_SECTOR_SIZE) { + *(size_t *)buf = info.geo_sectorsize; + } else if (cmd == DISK_GET_BLOCK_SIZE) { /* Get erase block size in unit of sectors (UINT32) */ + if ((bops->ioctl == NULL) || + (bops->ioctl(part->dev, GET_ERASE_BLOCK_SIZE, (UINTPTR)buf) != 0)) { + goto ERROR_HANDLE; + } + } else { + goto ERROR_HANDLE; + } + + DISK_UNLOCK(&disk->disk_mutex); + return ENOERR; + +ERROR_HANDLE: + DISK_UNLOCK(&disk->disk_mutex); + return VFS_ERROR; +} + +INT32 los_disk_cache_clear(INT32 drvID) +{ + INT32 result = ENOERR; +#ifdef LOSCFG_FS_FAT_CACHE + los_part *part = get_part(drvID); + los_disk *disk = NULL; + + if (part == NULL) { + return VFS_ERROR; + } + result = OsSdSync(part->disk_id); + if (result != ENOERR) { + PRINTK("[ERROR]disk_cache_clear SD sync failed!\n"); + return result; + } + + disk = get_disk(part->disk_id); + if (disk == NULL) { + return VFS_ERROR; + } + + DISK_LOCK(&disk->disk_mutex); + result = BcacheClearCache(disk->bcache); + DISK_UNLOCK(&disk->disk_mutex); +#endif + return result; +} + +#ifdef LOSCFG_FS_FAT_CACHE +static VOID DiskCacheThreadInit(UINT32 diskID, OsBcache *bc) +{ + bc->prereadFun = NULL; + + if (GetDiskUsbStatus(diskID) == FALSE) { + if (BcacheAsyncPrereadInit(bc) == LOS_OK) { + bc->prereadFun = ResumeAsyncPreread; + } + +#ifdef LOSCFG_FS_FAT_CACHE_SYNC_THREAD + BcacheSyncThreadInit(bc, diskID); +#endif + } + + if (OsReHookFuncAddDiskRef != NULL) { + (VOID)OsReHookFuncAddDiskRef((StorageHookFunction)OsSdSync, (VOID *)0); + (VOID)OsReHookFuncAddDiskRef((StorageHookFunction)OsSdSync, (VOID *)1); + } +} + +static OsBcache *DiskCacheInit(UINT32 diskID, const struct geometry *diskInfo, struct Vnode *blkDriver) +{ +#define SECTOR_SIZE 512 + + OsBcache *bc = NULL; + UINT32 sectorPerBlock = diskInfo->geo_sectorsize / SECTOR_SIZE; + if (sectorPerBlock != 0) { + sectorPerBlock = g_uwFatSectorsPerBlock / sectorPerBlock; + if (sectorPerBlock != 0) { + bc = BlockCacheInit(blkDriver, diskInfo->geo_sectorsize, sectorPerBlock, + g_uwFatBlockNums, diskInfo->geo_nsectors / sectorPerBlock); + } + } + + if (bc == NULL) { + PRINT_ERR("disk_init : disk have not init bcache cache!\n"); + return NULL; + } + + DiskCacheThreadInit(diskID, bc); + return bc; +} + +static VOID DiskCacheDeinit(los_disk *disk) +{ + UINT32 diskID = disk->disk_id; + if (GetDiskUsbStatus(diskID) == FALSE) { + if (BcacheAsyncPrereadDeinit(disk->bcache) != LOS_OK) { + PRINT_ERR("Blib async preread deinit failed in %s, %d\n", __FUNCTION__, __LINE__); + } +#ifdef LOSCFG_FS_FAT_CACHE_SYNC_THREAD + BcacheSyncThreadDeinit(disk->bcache); +#endif + } + + BlockCacheDeinit(disk->bcache); + disk->bcache = NULL; + + if (OsReHookFuncDelDiskRef != NULL) { + (VOID)OsReHookFuncDelDiskRef((StorageHookFunction)OsSdSync); + } +} +#endif + +static VOID DiskStructInit(const CHAR *diskName, INT32 diskID, const struct geometry *diskInfo, + struct Vnode *blkDriver, los_disk *disk) +{ + size_t nameLen; + disk->disk_id = diskID; + disk->dev = blkDriver; + disk->sector_start = 0; + disk->sector_size = diskInfo->geo_sectorsize; + disk->sector_count = diskInfo->geo_nsectors; + + nameLen = strlen(diskName); /* caller los_disk_init has chek name */ + + if (disk->disk_name != NULL) { + LOS_MemFree(m_aucSysMem0, disk->disk_name); + disk->disk_name = NULL; + } + + disk->disk_name = LOS_MemAlloc(m_aucSysMem0, (nameLen + 1)); + if (disk->disk_name == NULL) { + PRINT_ERR("DiskStructInit alloc memory failed.\n"); + return; + } + + if (strncpy_s(disk->disk_name, (nameLen + 1), diskName, nameLen) != EOK) { + PRINT_ERR("DiskStructInit strncpy_s failed.\n"); + LOS_MemFree(m_aucSysMem0, disk->disk_name); + disk->disk_name = NULL; + return; + } + disk->disk_name[nameLen] = '\0'; + LOS_ListInit(&disk->head); +} + +static INT32 DiskDivideAndPartitionRegister(struct disk_divide_info *info, los_disk *disk) +{ + INT32 ret; + + if (info != NULL) { + ret = DiskDivide(disk, info); + if (ret != ENOERR) { + PRINT_ERR("DiskDivide failed, ret = %d\n", ret); + return ret; + } + } else { + ret = DiskPartitionRegister(disk); + if (ret != ENOERR) { + PRINT_ERR("DiskPartitionRegister failed, ret = %d\n", ret); + return ret; + } + } + return ENOERR; +} + +static INT32 DiskDeinit(los_disk *disk) +{ + los_part *part = NULL; + char *diskName = NULL; + CHAR devName[DEV_NAME_BUFF_SIZE]; + INT32 ret; + + if (LOS_ListEmpty(&disk->head) == FALSE) { + part = LOS_DL_LIST_ENTRY(disk->head.pstNext, los_part, list); + while (&part->list != &disk->head) { + diskName = (disk->disk_name == NULL) ? "null" : disk->disk_name; + ret = snprintf_s(devName, sizeof(devName), sizeof(devName) - 1, "%s%c%d", + diskName, 'p', disk->part_count - 1); + if (ret < 0) { + return -ENAMETOOLONG; + } + DiskPartDelFromDisk(disk, part); + (VOID)unregister_blockdriver(devName); + DiskPartRelease(part); + + part = LOS_DL_LIST_ENTRY(disk->head.pstNext, los_part, list); + } + } + + DISK_LOCK(&disk->disk_mutex); + +#ifdef LOSCFG_FS_FAT_CACHE + DiskCacheDeinit(disk); +#else + if (disk->buff != NULL) { + free(disk->buff); + } +#endif + + disk->dev = NULL; + DISK_UNLOCK(&disk->disk_mutex); + (VOID)unregister_blockdriver(disk->disk_name); + if (disk->disk_name != NULL) { + LOS_MemFree(m_aucSysMem0, disk->disk_name); + disk->disk_name = NULL; + } + ret = pthread_mutex_destroy(&disk->disk_mutex); + if (ret != 0) { + PRINT_ERR("%s %d, mutex destroy failed, ret = %d\n", __FUNCTION__, __LINE__, ret); + return -EFAULT; + } + + disk->disk_status = STAT_UNUSED; + + return ENOERR; +} + +static UINT32 OsDiskInitSub(const CHAR *diskName, INT32 diskID, los_disk *disk, + struct geometry *diskInfo, struct Vnode *blkDriver) +{ + pthread_mutexattr_t attr; +#ifdef LOSCFG_FS_FAT_CACHE + OsBcache *bc = DiskCacheInit((UINT32)diskID, diskInfo, blkDriver); + if (bc == NULL) { + return VFS_ERROR; + } + disk->bcache = bc; +#endif + + (VOID)pthread_mutexattr_init(&attr); + attr.type = PTHREAD_MUTEX_RECURSIVE; + (VOID)pthread_mutex_init(&disk->disk_mutex, &attr); + + DiskStructInit(diskName, diskID, diskInfo, blkDriver, disk); + +#ifndef LOSCFG_FS_FAT_CACHE + disk->buff = malloc(diskInfo->geo_sectorsize * DISK_DIRECT_BUFFER_SIZE); + if (disk->buff == NULL) { + PRINT_ERR("OsDiskInitSub: direct buffer of disk init failed\n"); + return VFS_ERROR; + } +#endif + + return ENOERR; +} + +INT32 los_disk_init(const CHAR *diskName, const struct block_operations *bops, + VOID *priv, INT32 diskID, VOID *info) +{ + struct geometry diskInfo; + struct Vnode *blkDriver = NULL; + los_disk *disk = get_disk(diskID); + INT32 ret; + + if ((diskName == NULL) || (disk == NULL) || + (disk->disk_status != STAT_UNREADY) || (strlen(diskName) > DISK_NAME)) { + return VFS_ERROR; + } + + if (register_blockdriver(diskName, bops, RWE_RW_RW, priv) != 0) { + PRINT_ERR("disk_init : register %s fail!\n", diskName); + return VFS_ERROR; + } + + VnodeHold(); + ret = VnodeLookup(diskName, &blkDriver, 0); + if (ret < 0) { + VnodeDrop(); + PRINT_ERR("disk_init : %s, failed to find the vnode, ERRNO=%d\n", diskName, ret); + goto DISK_FIND_ERROR; + } + struct block_operations *bops2 = (struct block_operations *)((struct drv_data *)blkDriver->data)->ops; + + if ((bops2 == NULL) || (bops2->geometry == NULL) || (bops2->geometry(blkDriver, &diskInfo) != 0)) { + goto DISK_BLKDRIVER_ERROR; + } + + if (diskInfo.geo_sectorsize < DISK_MAX_SECTOR_SIZE) { + goto DISK_BLKDRIVER_ERROR; + } + + ret = OsDiskInitSub(diskName, diskID, disk, &diskInfo, blkDriver); + if (ret != ENOERR) { + (VOID)DiskDeinit(disk); + VnodeDrop(); + return VFS_ERROR; + } + VnodeDrop(); + if (DiskDivideAndPartitionRegister(info, disk) != ENOERR) { + (VOID)DiskDeinit(disk); + return VFS_ERROR; + } + + disk->disk_status = STAT_INUSED; + if (info != NULL) { + disk->type = EMMC; + } else { + disk->type = OTHERS; + } + return ENOERR; + +DISK_BLKDRIVER_ERROR: + PRINT_ERR("disk_init : register %s ok but get disk info fail!\n", diskName); + VnodeDrop(); +DISK_FIND_ERROR: + (VOID)unregister_blockdriver(diskName); + return VFS_ERROR; +} + +INT32 los_disk_deinit(INT32 diskID) +{ + int ret; + los_disk *disk = get_disk(diskID); + if (disk == NULL) { + return -EINVAL; + } + ret = ForceUmountDev(disk->dev); + PRINTK("warning: %s lost, force umount ret = %d\n", disk->disk_name, ret); + + DISK_LOCK(&disk->disk_mutex); + + if (disk->disk_status != STAT_INUSED) { + DISK_UNLOCK(&disk->disk_mutex); + return -EINVAL; + } + + disk->disk_status = STAT_UNREADY; + DISK_UNLOCK(&disk->disk_mutex); + + return DiskDeinit(disk); +} + +INT32 los_disk_sync(INT32 drvID) +{ + INT32 ret = ENOERR; + los_disk *disk = get_disk(drvID); + if (disk == NULL) { + return EINVAL; + } + + DISK_LOCK(&disk->disk_mutex); + if (disk->disk_status != STAT_INUSED) { + DISK_UNLOCK(&disk->disk_mutex); + return EINVAL; + } + +#ifdef LOSCFG_FS_FAT_CACHE + if (disk->bcache != NULL) { + ret = BlockCacheSync(disk->bcache); + } +#endif + + DISK_UNLOCK(&disk->disk_mutex); + return ret; +} + +INT32 los_disk_set_bcache(INT32 drvID, UINT32 sectorPerBlock, UINT32 blockNum) +{ +#ifdef LOSCFG_FS_FAT_CACHE + + INT32 ret; + UINT32 intSave; + OsBcache *bc = NULL; + los_disk *disk = get_disk(drvID); + if ((disk == NULL) || (sectorPerBlock == 0)) { + return EINVAL; + } + + /* + * Because we use UINT32 flag[BCACHE_BLOCK_FLAGS] in bcache for sectors bitmap tag, so it must + * be less than 32 * BCACHE_BLOCK_FLAGS. + */ + if (((sectorPerBlock % UNSIGNED_INTEGER_BITS) != 0) || + ((sectorPerBlock >> UNINT_LOG2_SHIFT) > BCACHE_BLOCK_FLAGS)) { + return EINVAL; + } + + DISK_LOCK(&disk->disk_mutex); + + if (disk->disk_status != STAT_INUSED) { + goto ERROR_HANDLE; + } + + if (disk->bcache != NULL) { + ret = BlockCacheSync(disk->bcache); + if (ret != ENOERR) { + DISK_UNLOCK(&disk->disk_mutex); + return ret; + } + } + + spin_lock_irqsave(&g_diskFatBlockSpinlock, intSave); + DiskCacheDeinit(disk); + + g_uwFatBlockNums = blockNum; + g_uwFatSectorsPerBlock = sectorPerBlock; + + bc = BlockCacheInit(disk->dev, disk->sector_size, sectorPerBlock, blockNum, disk->sector_count / sectorPerBlock); + if ((bc == NULL) && (blockNum != 0)) { + spin_unlock_irqrestore(&g_diskFatBlockSpinlock, intSave); + DISK_UNLOCK(&disk->disk_mutex); + return ENOMEM; + } + + if (bc != NULL) { + DiskCacheThreadInit((UINT32)drvID, bc); + } + + disk->bcache = bc; + spin_unlock_irqrestore(&g_diskFatBlockSpinlock, intSave); + DISK_UNLOCK(&disk->disk_mutex); + return ENOERR; + +ERROR_HANDLE: + DISK_UNLOCK(&disk->disk_mutex); + return EINVAL; +#else + return VFS_ERROR; +#endif +} + +static los_part *OsPartFind(los_disk *disk, const struct Vnode *blkDriver) +{ + los_part *part = NULL; + + DISK_LOCK(&disk->disk_mutex); + if ((disk->disk_status != STAT_INUSED) || (LOS_ListEmpty(&disk->head) == TRUE)) { + goto EXIT; + } + part = LOS_DL_LIST_ENTRY(disk->head.pstNext, los_part, list); + if (disk->dev == blkDriver) { + goto EXIT; + } + + while (&part->list != &disk->head) { + if (part->dev == blkDriver) { + goto EXIT; + } + part = LOS_DL_LIST_ENTRY(part->list.pstNext, los_part, list); + } + part = NULL; + +EXIT: + DISK_UNLOCK(&disk->disk_mutex); + return part; +} + +los_part *los_part_find(struct Vnode *blkDriver) +{ + INT32 i; + los_disk *disk = NULL; + los_part *part = NULL; + + if (blkDriver == NULL) { + return NULL; + } + + for (i = 0; i < SYS_MAX_DISK; i++) { + disk = get_disk(i); + if (disk == NULL) { + continue; + } + part = OsPartFind(disk, blkDriver); + if (part != NULL) { + return part; + } + } + + return NULL; +} + +INT32 los_part_access(const CHAR *dev, mode_t mode) +{ + los_part *part = NULL; + struct Vnode *node = NULL; + + VnodeHold(); + if (VnodeLookup(dev, &node, 0) < 0) { + VnodeDrop(); + return VFS_ERROR; + } + + part = los_part_find(node); + VnodeDrop(); + if (part == NULL) { + return VFS_ERROR; + } + + return ENOERR; +} + +INT32 SetDiskPartName(los_part *part, const CHAR *src) +{ + size_t len; + los_disk *disk = NULL; + + if ((part == NULL) || (src == NULL)) { + return VFS_ERROR; + } + + len = strlen(src); + if ((len == 0) || (len >= DISK_NAME)) { + return VFS_ERROR; + } + + disk = get_disk((INT32)part->disk_id); + if (disk == NULL) { + return VFS_ERROR; + } + + DISK_LOCK(&disk->disk_mutex); + if (disk->disk_status != STAT_INUSED) { + goto ERROR_HANDLE; + } + + part->part_name = (CHAR *)zalloc(len + 1); + if (part->part_name == NULL) { + PRINT_ERR("%s[%d] zalloc failure\n", __FUNCTION__, __LINE__); + goto ERROR_HANDLE; + } + + if (strcpy_s(part->part_name, len + 1, src) != EOK) { + free(part->part_name); + part->part_name = NULL; + goto ERROR_HANDLE; + } + + DISK_UNLOCK(&disk->disk_mutex); + return ENOERR; + +ERROR_HANDLE: + DISK_UNLOCK(&disk->disk_mutex); + return VFS_ERROR; +} + +INT32 add_mmc_partition(struct disk_divide_info *info, size_t sectorStart, size_t sectorCount) +{ + UINT32 index, i; + + if (info == NULL) { + return VFS_ERROR; + } + + if ((info->part_count >= MAX_DIVIDE_PART_PER_DISK) || (sectorCount == 0)) { + return VFS_ERROR; + } + + if ((sectorCount > info->sector_count) || ((info->sector_count - sectorCount) < sectorStart)) { + return VFS_ERROR; + } + + index = info->part_count; + for (i = 0; i < index; i++) { + if (sectorStart < (info->part[i].sector_start + info->part[i].sector_count)) { + return VFS_ERROR; + } + } + + info->part[index].sector_start = sectorStart; + info->part[index].sector_count = sectorCount; + info->part[index].type = EMMC; + info->part_count++; + + return ENOERR; +} + +VOID show_part(los_part *part) +{ + if ((part == NULL) || (part->dev == NULL)) { + PRINT_ERR("part is NULL\n"); + return; + } + + PRINTK("\npart info :\n"); + PRINTK("disk id : %u\n", part->disk_id); + PRINTK("part_id in system: %u\n", part->part_id); + PRINTK("part no in disk : %u\n", part->part_no_disk); + PRINTK("part no in mbr : %u\n", part->part_no_mbr); + PRINTK("part filesystem : %02X\n", part->filesystem_type); + PRINTK("part sec start : %llu\n", part->sector_start); + PRINTK("part sec count : %llu\n", part->sector_count); +} + +#ifdef LOSCFG_DRIVERS_MMC +ssize_t StorageBlockMmcErase(uint32_t blockId, size_t secStart, size_t secNr); +#endif + +INT32 EraseDiskByID(UINT32 diskID, size_t startSector, UINT32 sectors) +{ + INT32 ret = VFS_ERROR; +#ifdef LOSCFG_DRIVERS_MMC + los_disk *disk = get_disk((INT32)diskID); + if (disk != NULL) { + ret = StorageBlockMmcErase(diskID, startSector, sectors); + } +#endif + + return ret; +} + diff --git a/src/kernel_liteos_a/drivers/block/disk/src/disk_shellcmd.c b/src/kernel_liteos_a/drivers/block/disk/src/disk_shellcmd.c new file mode 100644 index 00000000..38227121 --- /dev/null +++ b/src/kernel_liteos_a/drivers/block/disk/src/disk_shellcmd.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "stdio.h" +#include "stdlib.h" +#include "los_config.h" +#ifdef LOSCFG_SHELL_CMD_DEBUG +#include "disk.h" +#include "shcmd.h" +#include "shell.h" +#include "path_cache.h" + +INT32 osShellCmdPartInfo(INT32 argc, const CHAR **argv) +{ + struct Vnode *node = NULL; + los_part *part = NULL; + const CHAR *str = "/dev"; + int ret; + + if ((argc != 1) || (strncmp(argv[0], str, strlen(str)) != 0)) { + PRINTK("Usage :\n"); + PRINTK(" partinfo \n"); + PRINTK(" dev_vnodename : the name of dev\n"); + PRINTK("Example:\n"); + PRINTK(" partinfo /dev/sdap0 \n"); + + set_errno(EINVAL); + return -LOS_NOK; + } + VnodeHold(); + ret = VnodeLookup(argv[0], &node, 0); + if (ret < 0) { + PRINT_ERR("no part found\n"); + VnodeDrop(); + set_errno(ENOENT); + return -LOS_NOK; + } + + part = los_part_find(node); + VnodeDrop(); + show_part(part); + + return LOS_OK; +} + +SHELLCMD_ENTRY(partinfo_shellcmd, CMD_TYPE_EX, "partinfo", XARGS, (CmdCallBackFunc)osShellCmdPartInfo); + +#endif diff --git a/src/kernel_liteos_a/drivers/char/BUILD.gn b/src/kernel_liteos_a/drivers/char/BUILD.gn new file mode 100644 index 00000000..9044b2f8 --- /dev/null +++ b/src/kernel_liteos_a/drivers/char/BUILD.gn @@ -0,0 +1,42 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_group("char") { + modules = [ + "bch", + "mem", + "perf", + "quickstart", + "random", + "trace", + "video", + ] +} diff --git a/src/kernel_liteos_a/drivers/char/bch/BUILD.gn b/src/kernel_liteos_a/drivers/char/bch/BUILD.gn new file mode 100644 index 00000000..16f29213 --- /dev/null +++ b/src/kernel_liteos_a/drivers/char/bch/BUILD.gn @@ -0,0 +1,43 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") +import("$THIRDPARTY_NUTTX_DIR/NuttX.gni") + +module_switch = defined(LOSCFG_FS_VFS_BLOCK_DEVICE) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = NUTTX_DRIVERS_BCH_SRC_FILES + + public_configs = [ ":public" ] +} + +config("public") { + include_dirs = [ "include" ] +} diff --git a/src/kernel_liteos_a/drivers/char/bch/Makefile b/src/kernel_liteos_a/drivers/char/bch/Makefile new file mode 100644 index 00000000..6774a104 --- /dev/null +++ b/src/kernel_liteos_a/drivers/char/bch/Makefile @@ -0,0 +1,41 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := $(wildcard $(LITEOSTHIRDPARTY)/NuttX/drivers/bch/*.c) + +LOCAL_INCLUDE := \ + -I $(LITEOSTHIRDPARTY)/NuttX/drivers/bch + +LOCAL_FLAGS := $(LOCAL_INCLUDE) + +include $(MODULE) diff --git a/src/kernel_liteos_a/drivers/char/bch/include/blockproxy.h b/src/kernel_liteos_a/drivers/char/bch/include/blockproxy.h new file mode 100644 index 00000000..4d884e79 --- /dev/null +++ b/src/kernel_liteos_a/drivers/char/bch/include/blockproxy.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __FS_DRIVER_BLOCKPROXY_H +#define __FS_DRIVER_BLOCKPROXY_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +int bchdev_register(const char *blkdev, const char *chardev, bool readonly); + +int block_proxy(const char *blkdev, int oflags); + +int bchdev_unregister(const char *blkdev); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ +#endif /* __FS_DRIVER_BLOCKPROXY_H */ + diff --git a/src/kernel_liteos_a/drivers/char/mem/BUILD.gn b/src/kernel_liteos_a/drivers/char/mem/BUILD.gn new file mode 100644 index 00000000..aad2d717 --- /dev/null +++ b/src/kernel_liteos_a/drivers/char/mem/BUILD.gn @@ -0,0 +1,42 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = defined(LOSCFG_DRIVERS_MEM) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ "src/mem.c" ] + + public_configs = [ ":public" ] +} + +config("public") { + include_dirs = [ "include" ] +} diff --git a/src/kernel_liteos_a/drivers/char/mem/Kconfig b/src/kernel_liteos_a/drivers/char/mem/Kconfig new file mode 100644 index 00000000..7cfed492 --- /dev/null +++ b/src/kernel_liteos_a/drivers/char/mem/Kconfig @@ -0,0 +1,6 @@ +config DRIVERS_MEM + bool "Enable MEM" + default y + depends on DRIVERS && FS_VFS + help + Answer Y to enable LiteOS support mem. \ No newline at end of file diff --git a/src/kernel_liteos_a/drivers/char/mem/Makefile b/src/kernel_liteos_a/drivers/char/mem/Makefile new file mode 100644 index 00000000..4e35bd1b --- /dev/null +++ b/src/kernel_liteos_a/drivers/char/mem/Makefile @@ -0,0 +1,36 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := $(wildcard src/*.c) + +include $(MODULE) diff --git a/src/kernel_liteos_a/drivers/char/mem/include/los_dev_mem.h b/src/kernel_liteos_a/drivers/char/mem/include/los_dev_mem.h new file mode 100644 index 00000000..cb5989e8 --- /dev/null +++ b/src/kernel_liteos_a/drivers/char/mem/include/los_dev_mem.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __LOS_DEV_MEM_H__ +#define __LOS_DEV_MEM_H__ + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +extern int DevMemRegister(void); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/src/kernel_liteos_a/drivers/char/mem/src/mem.c b/src/kernel_liteos_a/drivers/char/mem/src/mem.c new file mode 100644 index 00000000..8a4e96e9 --- /dev/null +++ b/src/kernel_liteos_a/drivers/char/mem/src/mem.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fcntl.h" +#include "linux/kernel.h" +#include "fs/driver.h" + +static int MemOpen(struct file *filep) +{ + return 0; +} + +static int MemClose(struct file *filep) +{ + return 0; +} + +static ssize_t MemRead(struct file *filep, char *buffer, size_t buflen) +{ + return 0; +} + +static ssize_t MemWrite(struct file *filep, const char *buffer, size_t buflen) +{ + return 0; +} + +static ssize_t MemMap(struct file *filep, LosVmMapRegion *region) +{ +#ifdef LOSCFG_KERNEL_VM + size_t size = region->range.size; + PADDR_T paddr = region->pgOff << PAGE_SHIFT; + VADDR_T vaddr = region->range.base; + LosVmSpace *space = LOS_SpaceGet(vaddr); + + if ((paddr >= SYS_MEM_BASE) && (paddr < SYS_MEM_END)) { + return -EINVAL; + } + + /* Peripheral register memory adds strongly ordered attributes */ + region->regionFlags |= VM_MAP_REGION_FLAG_STRONGLY_ORDERED; + + if (space == NULL) { + return -EAGAIN; + } + if (LOS_ArchMmuMap(&space->archMmu, vaddr, paddr, size >> PAGE_SHIFT, region->regionFlags) <= 0) { + return -EAGAIN; + } +#else + UNUSED(filep); + UNUSED(region); +#endif + return 0; +} + +static const struct file_operations_vfs g_memDevOps = { + MemOpen, /* open */ + MemClose, /* close */ + MemRead, /* read */ + MemWrite, /* write */ + NULL, /* seek */ + NULL, /* ioctl */ + MemMap, /* mmap */ +#ifndef CONFIG_DISABLE_POLL + NULL, /* poll */ +#endif + NULL, /* unlink */ +}; + +int DevMemRegister(void) +{ + return register_driver("/dev/mem", &g_memDevOps, 0644, 0); /* 0644: file mode */ +} diff --git a/src/kernel_liteos_a/drivers/char/perf/BUILD.gn b/src/kernel_liteos_a/drivers/char/perf/BUILD.gn new file mode 100644 index 00000000..223bc274 --- /dev/null +++ b/src/kernel_liteos_a/drivers/char/perf/BUILD.gn @@ -0,0 +1,42 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = defined(LOSCFG_DRIVERS_PERF) +module_name = "perf_dev" +kernel_module(module_name) { + sources = [ "src/perf.c" ] + + public_configs = [ ":public" ] +} + +config("public") { + include_dirs = [ "include" ] +} diff --git a/src/kernel_liteos_a/drivers/char/perf/Kconfig b/src/kernel_liteos_a/drivers/char/perf/Kconfig new file mode 100644 index 00000000..b760bb57 --- /dev/null +++ b/src/kernel_liteos_a/drivers/char/perf/Kconfig @@ -0,0 +1,6 @@ +config DRIVERS_PERF + bool "Enable PERF DRIVER" + default y + depends on DRIVERS && FS_VFS && KERNEL_PERF + help + Answer Y to enable LiteOS support perf in userspace. diff --git a/src/kernel_liteos_a/drivers/char/perf/Makefile b/src/kernel_liteos_a/drivers/char/perf/Makefile new file mode 100644 index 00000000..f3b7fe20 --- /dev/null +++ b/src/kernel_liteos_a/drivers/char/perf/Makefile @@ -0,0 +1,36 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := perf_dev + +LOCAL_SRCS := $(wildcard src/*.c) + +include $(MODULE) diff --git a/src/kernel_liteos_a/drivers/char/perf/include/los_dev_perf.h b/src/kernel_liteos_a/drivers/char/perf/include/los_dev_perf.h new file mode 100644 index 00000000..414f1211 --- /dev/null +++ b/src/kernel_liteos_a/drivers/char/perf/include/los_dev_perf.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __LOS_DEV_PERF_H__ +#define __LOS_DEV_PERF_H__ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +int DevPerfRegister(void); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/src/kernel_liteos_a/drivers/char/perf/src/perf.c b/src/kernel_liteos_a/drivers/char/perf/src/perf.c new file mode 100644 index 00000000..b5a29287 --- /dev/null +++ b/src/kernel_liteos_a/drivers/char/perf/src/perf.c @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fcntl.h" +#include "user_copy.h" +#include "sys/ioctl.h" +#include "fs/driver.h" +#include "los_dev_perf.h" +#include "los_perf.h" +#include "los_init.h" + +#define PERF_DRIVER "/dev/perf" +#define PERF_DRIVER_MODE 0666 + +/* perf ioctl */ +#define PERF_IOC_MAGIC 'T' +#define PERF_START _IO(PERF_IOC_MAGIC, 1) +#define PERF_STOP _IO(PERF_IOC_MAGIC, 2) + +static int PerfOpen(struct file *filep) +{ + (void)filep; + return 0; +} + +static int PerfClose(struct file *filep) +{ + (void)filep; + return 0; +} + +static ssize_t PerfRead(struct file *filep, char *buffer, size_t buflen) +{ + /* perf record buffer read */ + (void)filep; + int ret; + int realLen; + + char *records = LOS_MemAlloc(m_aucSysMem0, buflen); + if (records == NULL) { + return -ENOMEM; + } + + realLen = LOS_PerfDataRead(records, buflen); /* get sample data */ + if (realLen == 0) { + PRINT_ERR("Perf read failed, check whether perf is configured to sample mode.\n"); + ret = -EINVAL; + goto EXIT; + } + + ret = LOS_CopyFromKernel((void *)buffer, buflen, (void *)records, realLen); + if (ret != 0) { + ret = -EINVAL; + goto EXIT; + } + + ret = realLen; +EXIT: + LOS_MemFree(m_aucSysMem0, records); + return ret; +} + +static ssize_t PerfConfig(struct file *filep, const char *buffer, size_t buflen) +{ + (void)filep; + int ret; + PerfConfigAttr attr = {0}; + int attrlen = sizeof(PerfConfigAttr); + + if (buflen != attrlen) { + PRINT_ERR("PerfConfigAttr is %d bytes not %d\n", attrlen, buflen); + return -EINVAL; + } + + ret = LOS_CopyToKernel(&attr, attrlen, buffer, buflen); + if (ret != 0) { + return -EINVAL; + } + + ret = LOS_PerfConfig(&attr); + if (ret != LOS_OK) { + PRINT_ERR("perf config error %u\n", ret); + return -EINVAL; + } + + return 0; +} + +static int PerfIoctl(struct file *filep, int cmd, unsigned long arg) +{ + (void)filep; + switch (cmd) { + case PERF_START: + LOS_PerfStart((UINT32)arg); + break; + case PERF_STOP: + LOS_PerfStop(); + break; + default: + PRINT_ERR("Unknown perf ioctl cmd:%d\n", cmd); + return -EINVAL; + } + return 0; +} + +static const struct file_operations_vfs g_perfDevOps = { + PerfOpen, /* open */ + PerfClose, /* close */ + PerfRead, /* read */ + PerfConfig, /* write */ + NULL, /* seek */ + PerfIoctl, /* ioctl */ + NULL, /* mmap */ +#ifndef CONFIG_DISABLE_POLL + NULL, /* poll */ +#endif + NULL, /* unlink */ +}; + +int DevPerfRegister(void) +{ + return register_driver(PERF_DRIVER, &g_perfDevOps, PERF_DRIVER_MODE, 0); /* 0666: file mode */ +} + +LOS_MODULE_INIT(DevPerfRegister, LOS_INIT_LEVEL_KMOD_EXTENDED); diff --git a/src/kernel_liteos_a/drivers/char/quickstart/BUILD.gn b/src/kernel_liteos_a/drivers/char/quickstart/BUILD.gn new file mode 100644 index 00000000..9f2cb98d --- /dev/null +++ b/src/kernel_liteos_a/drivers/char/quickstart/BUILD.gn @@ -0,0 +1,42 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = defined(LOSCFG_DRIVERS_QUICKSTART) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ "src/quickstart.c" ] + + public_configs = [ ":public" ] +} + +config("public") { + include_dirs = [ "include" ] +} diff --git a/src/kernel_liteos_a/drivers/char/quickstart/Kconfig b/src/kernel_liteos_a/drivers/char/quickstart/Kconfig new file mode 100644 index 00000000..5ff73fe5 --- /dev/null +++ b/src/kernel_liteos_a/drivers/char/quickstart/Kconfig @@ -0,0 +1,6 @@ +config DRIVERS_QUICKSTART + bool "Enable QUICKSTART" + default y + depends on DRIVERS && FS_VFS + help + Answer Y to enable LiteOS support quickstart frame dev. diff --git a/src/kernel_liteos_a/drivers/char/quickstart/Makefile b/src/kernel_liteos_a/drivers/char/quickstart/Makefile new file mode 100644 index 00000000..4e35bd1b --- /dev/null +++ b/src/kernel_liteos_a/drivers/char/quickstart/Makefile @@ -0,0 +1,36 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := $(wildcard src/*.c) + +include $(MODULE) diff --git a/src/kernel_liteos_a/drivers/char/quickstart/include/los_dev_quickstart.h b/src/kernel_liteos_a/drivers/char/quickstart/include/los_dev_quickstart.h new file mode 100644 index 00000000..8d9ff447 --- /dev/null +++ b/src/kernel_liteos_a/drivers/char/quickstart/include/los_dev_quickstart.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __LOS_DEV_QUICKSTART_H__ +#define __LOS_DEV_QUICKSTART_H__ + +#include "los_typedef.h" +#include "sys/ioctl.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef enum { + QS_STAGE1 = 1, /* 1: start from stage1, 0 is already called in kernel process */ + QS_STAGE2, /* system init stage No 2 */ + QS_STAGE3, /* system init stage No 3 */ + QS_STAGE_LIMIT +} QuickstartStage; + +typedef enum { + QS_NOTIFY = QS_STAGE_LIMIT, /* quickstart notify */ + QS_LISTEN, /* quickstart listen */ + QS_CTL_LIMIT +} QuickstartConctrl; + +typedef struct { + unsigned int events; + unsigned int wait; +} QuickstartListenArgs; + +#define QUICKSTART_IOC_MAGIC 'T' +#define QUICKSTART_NOTIFY _IO(QUICKSTART_IOC_MAGIC, QS_NOTIFY) +#define QUICKSTART_LISTEN _IOR(QUICKSTART_IOC_MAGIC, QS_LISTEN, QuickstartListenArgs) +#define QUICKSTART_STAGE(x) _IO(QUICKSTART_IOC_MAGIC, (x)) + +#define QUICKSTART_NODE "/dev/quickstart" + +#define QS_STAGE_CNT (QS_STAGE_LIMIT - QS_STAGE1) + +typedef void (*SysteminitHook)(void); + +typedef struct { + SysteminitHook func[QS_STAGE_CNT]; +} LosSysteminitHook; + +extern void QuickstartHookRegister(LosSysteminitHook hooks); + +extern int QuickstartDevRegister(void); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/src/kernel_liteos_a/drivers/char/quickstart/src/quickstart.c b/src/kernel_liteos_a/drivers/char/quickstart/src/quickstart.c new file mode 100644 index 00000000..3270e57c --- /dev/null +++ b/src/kernel_liteos_a/drivers/char/quickstart/src/quickstart.c @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_dev_quickstart.h" +#include "fcntl.h" +#include "linux/kernel.h" +#include "los_process_pri.h" +#include "fs/file.h" +#include "fs/driver.h" + +EVENT_CB_S g_qsEvent; +static SysteminitHook g_systemInitFunc[QS_STAGE_CNT] = {0}; +static char g_callOnce[QS_STAGE_CNT] = {0}; + +static int QuickstartOpen(struct file *filep) +{ + return 0; +} + +static int QuickstartClose(struct file *filep) +{ + return 0; +} + +static int QuickstartNotify(unsigned int events) +{ + int ret = LOS_EventWrite((PEVENT_CB_S)&g_qsEvent, events); + if (ret != 0) { + PRINT_ERR("%s,%d:0x%x\n", __FUNCTION__, __LINE__, ret); + ret = -EINVAL; + } + return ret; +} + +#define WAITLIMIT 300000 /* 5min = 5*60*1000*1tick(1ms) */ + +static int QuickstartListen(unsigned long arg) +{ + QuickstartListenArgs args; + if (copy_from_user(&args, (QuickstartListenArgs __user *)arg, sizeof(QuickstartListenArgs)) != LOS_OK) { + PRINT_ERR("%s,%d,failed!\n", __FUNCTION__, __LINE__); + return -EINVAL; + } + if (args.wait > WAITLIMIT) { + args.wait = WAITLIMIT; + PRINT_ERR("%s wait arg is too longer, set to WAITLIMIT!\n", __FUNCTION__); + } + int ret = LOS_EventRead((PEVENT_CB_S)&g_qsEvent, args.events, LOS_WAITMODE_AND | LOS_WAITMODE_CLR, args.wait); + if (ret != args.events && ret != 0) { /* 0: nowait is normal case */ + PRINT_ERR("%s,%d:0x%x\n", __FUNCTION__, __LINE__, ret); + ret = -EINVAL; + } + return ret; +} + +void QuickstartHookRegister(LosSysteminitHook hooks) +{ + for (int i = 0; i < QS_STAGE_CNT; i++) { + g_systemInitFunc[i] = hooks.func[i]; + } +} + +static int QuickstartStageWorking(unsigned int level) +{ + if ((level < QS_STAGE_CNT) && (g_callOnce[level] == 0) && (g_systemInitFunc[level] != NULL)) { + g_callOnce[level] = 1; /* 1: Already called */ + g_systemInitFunc[level](); + } else { + PRINT_WARN("Trigger quickstart,but doing nothing!!\n"); + } + return 0; +} + +static int QuickstartDevUnlink(struct Vnode *node) +{ + (void)node; + return unregister_driver(QUICKSTART_NODE); +} + +static ssize_t QuickstartIoctl(struct file *filep, int cmd, unsigned long arg) +{ + ssize_t ret; + if (cmd == QUICKSTART_NOTIFY) { + return QuickstartNotify(arg); + } + + if (LOS_GetCurrProcessID() != OS_USER_ROOT_PROCESS_ID) { + PRINT_ERR("Permission denios!\n"); + return -EACCES; + } + switch (cmd) { + case QUICKSTART_LISTEN: + ret = QuickstartListen(arg); + break; + default: + ret = QuickstartStageWorking(cmd - QUICKSTART_STAGE(QS_STAGE1)); /* ioctl cmd converted to stage level */ + break; + } + return ret; +} + +static const struct file_operations_vfs g_quickstartDevOps = { + .open = QuickstartOpen, /* open */ + .close = QuickstartClose, /* close */ + .ioctl = QuickstartIoctl, /* ioctl */ + .unlink = QuickstartDevUnlink, /* unlink */ +}; + +int QuickstartDevRegister(void) +{ + LOS_EventInit(&g_qsEvent); + return register_driver(QUICKSTART_NODE, &g_quickstartDevOps, 0644, 0); /* 0644: file mode */ +} + diff --git a/src/kernel_liteos_a/drivers/char/random/BUILD.gn b/src/kernel_liteos_a/drivers/char/random/BUILD.gn new file mode 100644 index 00000000..0410df5b --- /dev/null +++ b/src/kernel_liteos_a/drivers/char/random/BUILD.gn @@ -0,0 +1,46 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = defined(LOSCFG_DRIVERS_RANDOM) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ "src/random.c" ] + + if (defined(LOSCFG_HW_RANDOM_ENABLE)) { + sources += [ "src/random_hw.c" ] + } + + public_configs = [ ":public" ] +} + +config("public") { + include_dirs = [ "include" ] +} diff --git a/src/kernel_liteos_a/drivers/char/random/Kconfig b/src/kernel_liteos_a/drivers/char/random/Kconfig new file mode 100644 index 00000000..5b75e0e5 --- /dev/null +++ b/src/kernel_liteos_a/drivers/char/random/Kconfig @@ -0,0 +1,12 @@ +config DRIVERS_RANDOM + bool "Enable random" + default y + depends on DRIVERS && FS_VFS && COMPAT_BSD + help + Answer Y to support random. +config HW_RANDOM_ENABLE + depends on DRIVERS_RANDOM && (PLATFORM_HI3518EV300 || PLATFORM_HI3516CV300 || PLATFORM_HI3516DV300 || PLATFORM_HI3556V200 || PLATFORM_QEMU_ARM_VIRT_CA7) + bool "Select hw random" + default y + help + Answer Y to select hw random. diff --git a/src/kernel_liteos_a/drivers/char/random/Makefile b/src/kernel_liteos_a/drivers/char/random/Makefile new file mode 100644 index 00000000..6f43d9ee --- /dev/null +++ b/src/kernel_liteos_a/drivers/char/random/Makefile @@ -0,0 +1,40 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := $(wildcard src/random.c) + +ifdef LOSCFG_HW_RANDOM_ENABLE +LOCAL_SRCS += $(wildcard src/random_hw.c) +endif + +include $(MODULE) diff --git a/src/kernel_liteos_a/drivers/char/random/include/los_random.h b/src/kernel_liteos_a/drivers/char/random/include/los_random.h new file mode 100644 index 00000000..298449ea --- /dev/null +++ b/src/kernel_liteos_a/drivers/char/random/include/los_random.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __LOS_RANDOM_H__ +#define __LOS_RANDOM_H__ + +#include "los_typedef.h" +#include "sys/ioctl.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define RAMDOM_IOC_MAGIC 'r' +#define RANDOM_SET_MAX _IO(RAMDOM_IOC_MAGIC, 1) + +int DevRandomRegister(void); +int DevUrandomRegister(void); + +typedef struct { + int (*support)(void); /* Whether hard random numbers are supported */ + void (*init)(void); /* Initializing the hard random number generator */ + void (*deinit)(void); /* Deinitializing the hard random number generator */ + int (*read)(char *buffer, size_t buflen); /* Read hard random number */ + int (*ioctl)(int cmd, unsigned long arg); /* Control hard random number generator */ +} RandomOperations; + +void RandomOperationsInit(const RandomOperations *r); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/src/kernel_liteos_a/drivers/char/random/src/random.c b/src/kernel_liteos_a/drivers/char/random/src/random.c new file mode 100644 index 00000000..365249e1 --- /dev/null +++ b/src/kernel_liteos_a/drivers/char/random/src/random.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_random.h" +#include "fcntl.h" +#include "linux/kernel.h" +#include "fs/driver.h" + + +static unsigned long g_randomMax = 0x7FFFFFFF; + +static long DoRand(unsigned long *value) +{ + long quotient, remainder, t; + + quotient = *value / 127773L; + remainder = *value % 127773L; + t = 16807L * remainder - 2836L * quotient; + if (t <= 0) { + t += 0x7fffffff; + } + return ((*value = t) % (g_randomMax + 1)); +} + +static unsigned long g_seed = 1; + +int RanOpen(struct file *filep) +{ + g_seed = (unsigned long)(LOS_CurrNanosec() & 0xffffffff); + return 0; +} + +static int RanClose(struct file *filep) +{ + return 0; +} + +int RanIoctl(struct file *filep, int cmd, unsigned long arg) +{ + PRINT_ERR("random ioctl is not supported\n"); + return -ENOTSUP; +} + +ssize_t RanRead(struct file *filep, char *buffer, size_t buflen) +{ + ssize_t len = buflen; + char *buf = buffer; + unsigned int temp; + int ret; + + if (len % sizeof(unsigned int)) { + PRINT_ERR("random size not aligned by 4 bytes\n"); + return -EINVAL; + } + while (len > 0) { + temp = DoRand(&g_seed); + ret = LOS_CopyFromKernel((void *)buf, sizeof(unsigned int), (void *)&temp, sizeof(unsigned int)); + if (ret) { + break; + } + len -= sizeof(unsigned int); + buf += sizeof(unsigned int); + } + return (buflen - len); /* return a successful len */ +} + +static ssize_t RanMap(struct file *filep, LosVmMapRegion *region) +{ + PRINTK("%s %d, mmap is not support\n", __FUNCTION__, __LINE__); + return 0; +} + +static const struct file_operations_vfs g_ranDevOps = { + RanOpen, /* open */ + RanClose, /* close */ + RanRead, /* read */ + NULL, /* write */ + NULL, /* seek */ + RanIoctl, /* ioctl */ + RanMap, /* mmap */ +#ifndef CONFIG_DISABLE_POLL + NULL, /* poll */ +#endif + NULL, /* unlink */ +}; + +int DevRandomRegister(void) +{ + return register_driver("/dev/random", &g_ranDevOps, 0666, 0); /* 0666: file mode */ +} + diff --git a/src/kernel_liteos_a/drivers/char/random/src/random_hw.c b/src/kernel_liteos_a/drivers/char/random/src/random_hw.c new file mode 100644 index 00000000..04934a14 --- /dev/null +++ b/src/kernel_liteos_a/drivers/char/random/src/random_hw.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_random.h" +#include "fcntl.h" +#include "hisoc/random.h" +#include "linux/kernel.h" +#include "fs/driver.h" + +static RandomOperations g_randomOp; +void RandomOperationsInit(const RandomOperations *r) +{ + if (r != NULL) { + (void)memcpy_s(&g_randomOp, sizeof(RandomOperations), r, sizeof(RandomOperations)); + } else { + PRINT_ERR("%s %d param is invalid\n", __FUNCTION__, __LINE__); + } + return; +} +static int RandomHwOpen(struct file *filep) +{ + if (g_randomOp.init != NULL) { + g_randomOp.init(); + return ENOERR; + } + return -1; +} + +static int RandomHwClose(struct file *filep) +{ + if (g_randomOp.deinit != NULL) { + g_randomOp.deinit(); + return ENOERR; + } + return -1; +} + +static int RandomHwIoctl(struct file *filep, int cmd, unsigned long arg) +{ + int ret = -1; + + switch (cmd) { + default: + PRINT_ERR("!!!bad command!!!\n"); + return -EINVAL; + } + return ret; +} + +static ssize_t RandomHwRead(struct file *filep, char *buffer, size_t buflen) +{ + int ret = -1; + + if (g_randomOp.read != NULL) { + ret = g_randomOp.read(buffer, buflen); + if (ret == ENOERR) { + ret = buflen; + } + } else { + ret = -1; + } + return ret; +} + +static ssize_t RandomMap(struct file *filep, LosVmMapRegion *region) +{ + PRINTK("%s %d, mmap is not support\n", __FUNCTION__, __LINE__); + return 0; +} + +static const struct file_operations_vfs g_randomHwDevOps = { + RandomHwOpen, /* open */ + RandomHwClose, /* close */ + RandomHwRead, /* read */ + NULL, /* write */ + NULL, /* seek */ + RandomHwIoctl, /* ioctl */ + RandomMap, /* mmap */ +#ifndef CONFIG_DISABLE_POLL + NULL, /* poll */ +#endif + NULL, /* unlink */ +}; + +int DevUrandomRegister(void) +{ + if (g_randomOp.support != NULL) { + int ret = g_randomOp.support(); + if (ret) { + return register_driver("/dev/urandom", &g_randomHwDevOps, 0666, 0); /* 0666: file mode */ + } + } + return -EPERM; +} + diff --git a/src/kernel_liteos_a/drivers/char/trace/BUILD.gn b/src/kernel_liteos_a/drivers/char/trace/BUILD.gn new file mode 100644 index 00000000..4411dbe8 --- /dev/null +++ b/src/kernel_liteos_a/drivers/char/trace/BUILD.gn @@ -0,0 +1,42 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = defined(LOSCFG_DRIVERS_TRACE) +module_name = "trace_dev" +kernel_module(module_name) { + sources = [ "src/trace.c" ] + + public_configs = [ ":public" ] +} + +config("public") { + include_dirs = [ "include" ] +} diff --git a/src/kernel_liteos_a/drivers/char/trace/Kconfig b/src/kernel_liteos_a/drivers/char/trace/Kconfig new file mode 100644 index 00000000..70cc87cb --- /dev/null +++ b/src/kernel_liteos_a/drivers/char/trace/Kconfig @@ -0,0 +1,6 @@ +config DRIVERS_TRACE + bool "Enable TRACE DRIVER" + default y + depends on DRIVERS && FS_VFS && KERNEL_TRACE + help + Answer Y to enable LiteOS support trace in userspace. \ No newline at end of file diff --git a/src/kernel_liteos_a/drivers/char/trace/Makefile b/src/kernel_liteos_a/drivers/char/trace/Makefile new file mode 100644 index 00000000..f4fa8887 --- /dev/null +++ b/src/kernel_liteos_a/drivers/char/trace/Makefile @@ -0,0 +1,40 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := trace_dev + +LOCAL_SRCS := $(wildcard src/*.c) + +LOCAL_INCLUDE := -I $(LITEOSTOPDIR)/drivers/char/trace/include + +LOCAL_FLAGS := $(LOCAL_INCLUDE) + +include $(MODULE) diff --git a/src/kernel_liteos_a/drivers/char/trace/include/los_dev_trace.h b/src/kernel_liteos_a/drivers/char/trace/include/los_dev_trace.h new file mode 100644 index 00000000..da9901eb --- /dev/null +++ b/src/kernel_liteos_a/drivers/char/trace/include/los_dev_trace.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __LOS_DEV_TRACE_H__ +#define __LOS_DEV_TRACE_H__ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +int DevTraceRegister(void); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/src/kernel_liteos_a/drivers/char/trace/src/trace.c b/src/kernel_liteos_a/drivers/char/trace/src/trace.c new file mode 100644 index 00000000..9bb001fa --- /dev/null +++ b/src/kernel_liteos_a/drivers/char/trace/src/trace.c @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fcntl.h" +#include "linux/kernel.h" +#include "sys/ioctl.h" +#include "fs/driver.h" +#include "los_dev_trace.h" +#include "los_trace.h" +#include "los_hook.h" +#include "los_init.h" + +#define TRACE_DRIVER "/dev/trace" +#define TRACE_DRIVER_MODE 0666 + +/* trace ioctl */ +#define TRACE_IOC_MAGIC 'T' +#define TRACE_START _IO(TRACE_IOC_MAGIC, 1) +#define TRACE_STOP _IO(TRACE_IOC_MAGIC, 2) +#define TRACE_RESET _IO(TRACE_IOC_MAGIC, 3) +#define TRACE_DUMP _IO(TRACE_IOC_MAGIC, 4) +#define TRACE_SET_MASK _IO(TRACE_IOC_MAGIC, 5) + +static int TraceOpen(struct file *filep) +{ + return 0; +} + +static int TraceClose(struct file *filep) +{ + return 0; +} + +static ssize_t TraceRead(struct file *filep, char *buffer, size_t buflen) +{ + /* trace record buffer read */ + ssize_t len = buflen; + OfflineHead *records; + int ret; + int realLen; + + if (len % sizeof(unsigned int)) { + PRINT_ERR("Buffer size not aligned by 4 bytes\n"); + return -EINVAL; + } + + records = LOS_TraceRecordGet(); + if (records == NULL) { + PRINT_ERR("Trace read failed, check whether trace mode is set to offline\n"); + return -EINVAL; + } + + realLen = buflen < records->totalLen ? buflen : records->totalLen; + ret = LOS_CopyFromKernel((void *)buffer, buflen, (void *)records, realLen); + if (ret != 0) { + return -EINVAL; + } + + return realLen; +} + +static ssize_t TraceWrite(struct file *filep, const char *buffer, size_t buflen) +{ + /* trace usr event here */ + int ret; + UsrEventInfo *info = NULL; + int infoLen = sizeof(UsrEventInfo); + + if (buflen != infoLen) { + PRINT_ERR("Buffer size not %d bytes\n", infoLen); + return -EINVAL; + } + + info = LOS_MemAlloc(m_aucSysMem0, infoLen); + if (info == NULL) { + return -ENOMEM; + } + (void)memset_s(info, infoLen, 0, infoLen); + + ret = LOS_CopyToKernel(info, infoLen, buffer, buflen); + if (ret != 0) { + LOS_MemFree(m_aucSysMem0, info); + return -EINVAL; + } + OsHookCall(LOS_HOOK_TYPE_USR_EVENT, info, infoLen); + return 0; +} + +static int TraceIoctl(struct file *filep, int cmd, unsigned long arg) +{ + switch (cmd) { + case TRACE_START: + return LOS_TraceStart(); + case TRACE_STOP: + LOS_TraceStop(); + break; + case TRACE_RESET: + LOS_TraceReset(); + break; + case TRACE_DUMP: + LOS_TraceRecordDump((BOOL)arg); + break; + case TRACE_SET_MASK: + LOS_TraceEventMaskSet((UINT32)arg); + break; + default: + PRINT_ERR("Unknown trace ioctl cmd:%d\n", cmd); + return -EINVAL; + } + return 0; +} + +static const struct file_operations_vfs g_traceDevOps = { + TraceOpen, /* open */ + TraceClose, /* close */ + TraceRead, /* read */ + TraceWrite, /* write */ + NULL, /* seek */ + TraceIoctl, /* ioctl */ + NULL, /* mmap */ +#ifndef CONFIG_DISABLE_POLL + NULL, /* poll */ +#endif + NULL, /* unlink */ +}; + +int DevTraceRegister(void) +{ + return register_driver(TRACE_DRIVER, &g_traceDevOps, TRACE_DRIVER_MODE, 0); /* 0666: file mode */ +} + +LOS_MODULE_INIT(DevTraceRegister, LOS_INIT_LEVEL_KMOD_EXTENDED); \ No newline at end of file diff --git a/src/kernel_liteos_a/drivers/char/video/BUILD.gn b/src/kernel_liteos_a/drivers/char/video/BUILD.gn new file mode 100644 index 00000000..b6395569 --- /dev/null +++ b/src/kernel_liteos_a/drivers/char/video/BUILD.gn @@ -0,0 +1,43 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") +import("$THIRDPARTY_NUTTX_DIR/NuttX.gni") + +module_switch = defined(LOSCFG_DRIVERS_VIDEO) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = NUTTX_DRIVERS_VIDEO_SRC_FILES + + public_configs = [ ":public" ] +} + +config("public") { + include_dirs = NUTTX_DRIVERS_VIDEO_INCLUDE_DIRS +} diff --git a/src/kernel_liteos_a/drivers/char/video/Kconfig b/src/kernel_liteos_a/drivers/char/video/Kconfig new file mode 100644 index 00000000..3fad196a --- /dev/null +++ b/src/kernel_liteos_a/drivers/char/video/Kconfig @@ -0,0 +1,6 @@ +config DRIVERS_VIDEO + bool "Enable Video" + default y + depends on DRIVERS + help + Answer Y to enable LiteOS support video driver. \ No newline at end of file diff --git a/src/kernel_liteos_a/drivers/char/video/Makefile b/src/kernel_liteos_a/drivers/char/video/Makefile new file mode 100644 index 00000000..790d2e62 --- /dev/null +++ b/src/kernel_liteos_a/drivers/char/video/Makefile @@ -0,0 +1,40 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := $(LITEOSTHIRDPARTY)/NuttX/drivers/video/fb.c + +LOCAL_INCLUDE := -I $(LITEOSTHIRDPARTY)/NuttX/include/nuttx/video + +LOCAL_FLAGS := $(LOCAL_INCLUDE) + +include $(MODULE) diff --git a/src/kernel_liteos_a/drivers/mtd/BUILD.gn b/src/kernel_liteos_a/drivers/mtd/BUILD.gn new file mode 100644 index 00000000..5a1be361 --- /dev/null +++ b/src/kernel_liteos_a/drivers/mtd/BUILD.gn @@ -0,0 +1,34 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_group("mtd") { + modules = [ "multi_partition" ] +} diff --git a/src/kernel_liteos_a/drivers/mtd/multi_partition/BUILD.gn b/src/kernel_liteos_a/drivers/mtd/multi_partition/BUILD.gn new file mode 100644 index 00000000..f54c2424 --- /dev/null +++ b/src/kernel_liteos_a/drivers/mtd/multi_partition/BUILD.gn @@ -0,0 +1,47 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = defined(LOSCFG_FS_VFS) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ + "src/mtd_partition.c", + "src/mtd_shellcmd.c", + ] + + include_dirs = [ "$LITEOSTOPDIR/fs/jffs2/include" ] + + public_configs = [ ":public" ] +} + +config("public") { + include_dirs = [ "include" ] +} diff --git a/src/kernel_liteos_a/drivers/mtd/multi_partition/Makefile b/src/kernel_liteos_a/drivers/mtd/multi_partition/Makefile new file mode 100644 index 00000000..46b5d78d --- /dev/null +++ b/src/kernel_liteos_a/drivers/mtd/multi_partition/Makefile @@ -0,0 +1,41 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := $(wildcard src/*.c) + +LOCAL_INCLUDE := \ + -I $(LITEOSTOPDIR)/fs/jffs2/include + +LOCAL_FLAGS := $(LOCAL_INCLUDE) + +include $(MODULE) diff --git a/src/kernel_liteos_a/drivers/mtd/multi_partition/include/mtd_dev.h b/src/kernel_liteos_a/drivers/mtd/multi_partition/include/mtd_dev.h new file mode 100644 index 00000000..30f41da6 --- /dev/null +++ b/src/kernel_liteos_a/drivers/mtd/multi_partition/include/mtd_dev.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __MTD_DEV_H__ +#define __MTD_DEV_H__ + +#include "los_typedef.h" + +#define MTD_NORFLASH 3 +#define MTD_NANDFLASH 4 +#define MTD_DATAFLASH 6 +#define MTD_MLCNANDFLASH 8 + +struct MtdNorDev { + unsigned long blockSize; + unsigned long blockStart; + unsigned long blockEnd; +}; + +struct MtdDev { + VOID *priv; + UINT32 type; + + UINT64 size; + UINT32 eraseSize; + + int (*erase)(struct MtdDev *mtd, UINT64 start, UINT64 len, UINT64 *failAddr); + int (*read)(struct MtdDev *mtd, UINT64 start, UINT64 len, const char *buf); + int (*write)(struct MtdDev *mtd, UINT64 start, UINT64 len, const char *buf); +}; + +#endif /* __MTD_DEV_H__ */ diff --git a/src/kernel_liteos_a/drivers/mtd/multi_partition/include/mtd_list.h b/src/kernel_liteos_a/drivers/mtd/multi_partition/include/mtd_list.h new file mode 100644 index 00000000..cf4f7725 --- /dev/null +++ b/src/kernel_liteos_a/drivers/mtd/multi_partition/include/mtd_list.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __MTD_LIST_H__ +#define __MTD_LIST_H__ + +#include "sys/types.h" +#include "mtd_dev.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef struct Node { + char *type; + int status; + struct MtdDev *mtd; + struct Node *next; +} Lnode, *Linklist; + +void* GetMtd(const char *type); +int GetMtdInfo(const char *type); +int FreeMtd(struct MtdDev *mtd); +int DelMtdList(struct MtdDev *mtd); +void AddMtdList(char *type, struct MtdDev *mtd); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* __MTD_LIST_H__ */ diff --git a/src/kernel_liteos_a/drivers/mtd/multi_partition/include/mtd_partition.h b/src/kernel_liteos_a/drivers/mtd/multi_partition/include/mtd_partition.h new file mode 100644 index 00000000..2fec42d7 --- /dev/null +++ b/src/kernel_liteos_a/drivers/mtd/multi_partition/include/mtd_partition.h @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup filesystem FileSystem + * @defgroup mtd_partition Multi Partition + * @ingroup filesystem + */ +#ifndef _MTD_PARTITION_H +#define _MTD_PARTITION_H + +#include "sys/types.h" +#include "los_mux.h" +#include "mtd_list.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define SPIBLK_NAME "/dev/spinorblk" +#define SPICHR_NAME "/dev/spinorchr" + +#define NANDBLK_NAME "/dev/nandblk" +#define NANDCHR_NAME "/dev/nandchr" + +typedef struct mtd_node { + UINT32 start_block; + UINT32 end_block; + UINT32 patitionnum; + CHAR *blockdriver_name; + CHAR *chardriver_name; + CHAR *mountpoint_name; + VOID *mtd_info; /* Driver used by a partition */ + LOS_DL_LIST node_info; + LosMux lock; + UINT32 user_num; +} mtd_partition; + +typedef struct par_param { + mtd_partition *partition_head; + struct MtdDev *flash_mtd; + const struct block_operations *flash_ops; + const struct file_operations_vfs *char_ops; + CHAR *blockname; + CHAR *charname; + UINT32 block_size; +} partition_param; + +#define CONFIG_MTD_PATTITION_NUM 20 + +#define ALIGN_ASSIGN(len, startAddr, startBlk, endBlk, blkSize) do { \ + (len) = (((len) + ((blkSize) - 1)) & ~((blkSize) - 1)); \ + (startAddr) = ((startAddr) & ~((blkSize) - 1)); \ + (startBlk) = (startAddr) / (blkSize); \ + (endBlk) = (len) / (blkSize) + ((startBlk) - 1); \ +} while (0) + +#define PAR_ASSIGNMENT(node, len, startAddr, num, mtd, blkSize) do { \ + (node)->start_block = (startAddr) / (blkSize); \ + (node)->end_block = (len) / (blkSize) + ((node)->start_block - 1); \ + (node)->patitionnum = (num); \ + (node)->mtd_info = (mtd); \ + (node)->mountpoint_name = NULL; \ +} while (0) + +partition_param *GetNandPartParam(VOID); +partition_param *GetSpinorPartParam(VOID); +mtd_partition *GetSpinorPartitionHead(VOID); + +/** + * @ingroup mtd_partition + * @brief Add a partition. + * + * @par Description: + *
            + *
          • This API is used to add a partition according to the passed-in parameters.
          • + *
          + * @attention + *
            + *
          • None.
          • + *
          + * + * @param type [IN] Storage medium type, support "nand" and "spinor" currently. + * @param startAddr [IN] Starting address of a partition. + * @param length [IN] Partition size. + * @param partitionNum [IN] Partition number, less than the value defined by CONFIG_MTD_PATTITION_NUM. + * + * @retval #-ENODEV The driver is not found. + * @retval #-EINVAL Invalid parameter. + * @retval #-ENOMEM Insufficient memory. + * @retval #ENOERR The partition is successfully created. + * + * @par Dependency: + *
          • mtd_partition.h: the header file that contains the API declaration.
          + * @see delete_mtd_partition + */ +extern INT32 add_mtd_partition(const CHAR *type, UINT32 startAddr, UINT32 length, UINT32 partitionNum); + +/** + * @ingroup mtd_partition + * @brief Delete a partition. + * + * @par Description: + *
            + *
          • This API is used to delete a partition according to its partition number and storage medium type.
          • + *
          + * @attention + *
            + *
          • None.
          • + *
          + * + * @param partitionNum [IN] Partition number, less than the value defined by CONFIG_MTD_PATTITION_NUM. + * @param type [IN] Storage medium type, support "nand" and "spinor" currently. + * + * @retval #-EINVAL Invalid parameter. + * @retval #ENOERR The partition is successfully deleted. + * + * @par Dependency: + *
          • mtd_partition.h: the header file that contains the API declaration.
          + * @see add_mtd_partition + */ +extern INT32 delete_mtd_partition(UINT32 partitionNum, const CHAR *type); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _MTD_PARTITION_H */ diff --git a/src/kernel_liteos_a/drivers/mtd/multi_partition/src/mtd_partition.c b/src/kernel_liteos_a/drivers/mtd/multi_partition/src/mtd_partition.c new file mode 100644 index 00000000..034bc551 --- /dev/null +++ b/src/kernel_liteos_a/drivers/mtd/multi_partition/src/mtd_partition.c @@ -0,0 +1,538 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "mtd_partition.h" +#include "stdlib.h" +#include "stdio.h" +#include "pthread.h" +#include "mtd_list.h" +#include "los_config.h" +#include "los_mux.h" +#include "fs/driver.h" +#include "mtd/mtd_legacy_lite.h" + +#define DRIVER_NAME_ADD_SIZE 3 +pthread_mutex_t g_mtdPartitionLock = PTHREAD_MUTEX_INITIALIZER; + +static VOID YaffsLockInit(VOID) __attribute__((weakref("yaffsfs_OSInitialisation"))); +static VOID YaffsLockDeinit(VOID) __attribute__((weakref("yaffsfs_OsDestroy"))); +static INT32 Jffs2LockInit(VOID) __attribute__((weakref("Jffs2MutexCreate"))); +static VOID Jffs2LockDeinit(VOID) __attribute__((weakref("Jffs2MutexDelete"))); + +partition_param *g_nandPartParam = NULL; +partition_param *g_spinorPartParam = NULL; +mtd_partition *g_spinorPartitionHead = NULL; +mtd_partition *g_nandPartitionHead = NULL; + +#define RWE_RW_RW 0755 + +partition_param *GetNandPartParam(VOID) +{ + return g_nandPartParam; +} + +partition_param *GetSpinorPartParam(VOID) +{ + return g_spinorPartParam; +} + +mtd_partition *GetSpinorPartitionHead(VOID) +{ + return g_spinorPartitionHead; +} + + +static VOID MtdNandParamAssign(partition_param *nandParam, const struct MtdDev *nandMtd) +{ + LOS_ListInit(&g_nandPartitionHead->node_info); + /* + * If the user do not want to use block mtd or char mtd , + * you can change the NANDBLK_NAME or NANDCHR_NAME to NULL. + */ + nandParam->flash_mtd = (struct MtdDev *)nandMtd; + nandParam->flash_ops = GetDevNandOps(); + nandParam->char_ops = GetMtdCharFops(); + nandParam->blockname = NANDBLK_NAME; + nandParam->charname = NANDCHR_NAME; + nandParam->partition_head = g_nandPartitionHead; + nandParam->block_size = nandMtd->eraseSize; +} + +static VOID MtdDeinitNandParam(VOID) +{ + if (YaffsLockDeinit != NULL) { + YaffsLockDeinit(); + } +} + +static partition_param *MtdInitNandParam(partition_param *nandParam) +{ + struct MtdDev *nandMtd = GetMtd("nand"); + if (nandMtd == NULL) { + return NULL; + } + if (nandParam == NULL) { + if (YaffsLockInit != NULL) { + YaffsLockInit(); + } + nandParam = (partition_param *)zalloc(sizeof(partition_param)); + if (nandParam == NULL) { + MtdDeinitNandParam(); + return NULL; + } + g_nandPartitionHead = (mtd_partition *)zalloc(sizeof(mtd_partition)); + if (g_nandPartitionHead == NULL) { + MtdDeinitNandParam(); + free(nandParam); + return NULL; + } + + MtdNandParamAssign(nandParam, nandMtd); + } + + return nandParam; +} + +static VOID MtdNorParamAssign(partition_param *spinorParam, const struct MtdDev *spinorMtd) +{ + LOS_ListInit(&g_spinorPartitionHead->node_info); + /* + * If the user do not want to use block mtd or char mtd , + * you can change the SPIBLK_NAME or SPICHR_NAME to NULL. + */ + spinorParam->flash_mtd = (struct MtdDev *)spinorMtd; + spinorParam->flash_ops = GetDevSpinorOps(); + spinorParam->char_ops = GetMtdCharFops(); + spinorParam->blockname = SPIBLK_NAME; + spinorParam->charname = SPICHR_NAME; + spinorParam->partition_head = g_spinorPartitionHead; + spinorParam->block_size = spinorMtd->eraseSize; +} + +static VOID MtdDeinitSpinorParam(VOID) +{ + if (Jffs2LockDeinit != NULL) { + Jffs2LockDeinit(); + } +} + +static partition_param *MtdInitSpinorParam(partition_param *spinorParam) +{ + struct MtdDev *spinorMtd = GetMtd("spinor"); + if (spinorMtd == NULL) { + return NULL; + } + if (spinorParam == NULL) { + if (Jffs2LockInit != NULL) { + if (Jffs2LockInit() != 0) { /* create jffs2 lock failed */ + return NULL; + } + } + spinorParam = (partition_param *)zalloc(sizeof(partition_param)); + if (spinorParam == NULL) { + PRINT_ERR("%s, partition_param malloc failed\n", __FUNCTION__); + MtdDeinitSpinorParam(); + return NULL; + } + g_spinorPartitionHead = (mtd_partition *)zalloc(sizeof(mtd_partition)); + if (g_spinorPartitionHead == NULL) { + PRINT_ERR("%s, mtd_partition malloc failed\n", __FUNCTION__); + MtdDeinitSpinorParam(); + free(spinorParam); + return NULL; + } + + MtdNorParamAssign(spinorParam, spinorMtd); + } + + return spinorParam; +} + +/* According the flash-type to init the param of the partition. */ +static INT32 MtdInitFsparParam(const CHAR *type, partition_param **fsparParam) +{ + if (strcmp(type, "nand") == 0) { + g_nandPartParam = MtdInitNandParam(g_nandPartParam); + *fsparParam = g_nandPartParam; + } else if (strcmp(type, "spinor") == 0 || strcmp(type, "cfi-flash") == 0) { + g_spinorPartParam = MtdInitSpinorParam(g_spinorPartParam); + *fsparParam = g_spinorPartParam; + } else { + return -EINVAL; + } + + if ((*fsparParam == NULL) || ((VOID *)((*fsparParam)->flash_mtd) == NULL)) { + return -ENODEV; + } + + return ENOERR; +} + +/* According the flash-type to deinit the param of the partition. */ +static INT32 MtdDeinitFsparParam(const CHAR *type) +{ + if (strcmp(type, "nand") == 0) { + MtdDeinitNandParam(); + g_nandPartParam = NULL; + } else if (strcmp(type, "spinor") == 0 || strcmp(type, "cfi-flash") == 0) { + MtdDeinitSpinorParam(); + g_spinorPartParam = NULL; + } else { + return -EINVAL; + } + + return ENOERR; +} + +static INT32 AddParamCheck(UINT32 startAddr, + const partition_param *param, + UINT32 partitionNum, + UINT32 length) +{ + UINT32 startBlk, endBlk; + mtd_partition *node = NULL; + if ((param->blockname == NULL) && (param->charname == NULL)) { + return -EINVAL; + } + + if ((length == 0) || (length < param->block_size) || + (((UINT64)(startAddr) + length) > param->flash_mtd->size)) { + return -EINVAL; + } + + ALIGN_ASSIGN(length, startAddr, startBlk, endBlk, param->block_size); + + if (startBlk > endBlk) { + return -EINVAL; + } + LOS_DL_LIST_FOR_EACH_ENTRY(node, ¶m->partition_head->node_info, mtd_partition, node_info) { + if ((node->start_block != 0) && (node->patitionnum == partitionNum)) { + return -EINVAL; + } + if ((startBlk > node->end_block) || (endBlk < node->start_block)) { + continue; + } + return -EINVAL; + } + + return ENOERR; +} + +static INT32 BlockDriverRegisterOperate(mtd_partition *newNode, + const partition_param *param, + UINT32 partitionNum) +{ + INT32 ret; + size_t driverNameSize; + + if (param->blockname != NULL) { + driverNameSize = strlen(param->blockname) + DRIVER_NAME_ADD_SIZE; + newNode->blockdriver_name = (CHAR *)malloc(driverNameSize); + if (newNode->blockdriver_name == NULL) { + return -ENOMEM; + } + + ret = snprintf_s(newNode->blockdriver_name, driverNameSize, + driverNameSize - 1, "%s%u", param->blockname, partitionNum); + if (ret < 0) { + free(newNode->blockdriver_name); + newNode->blockdriver_name = NULL; + return -ENAMETOOLONG; + } + + ret = register_blockdriver(newNode->blockdriver_name, param->flash_ops, + RWE_RW_RW, newNode); + if (ret) { + free(newNode->blockdriver_name); + newNode->blockdriver_name = NULL; + PRINT_ERR("register blkdev partition error\n"); + return ret; + } + } else { + newNode->blockdriver_name = NULL; + } + return ENOERR; +} + +static INT32 CharDriverRegisterOperate(mtd_partition *newNode, + const partition_param *param, + UINT32 partitionNum) +{ + INT32 ret; + size_t driverNameSize; + + if (param->charname != NULL) { + driverNameSize = strlen(param->charname) + DRIVER_NAME_ADD_SIZE; + newNode->chardriver_name = (CHAR *)malloc(driverNameSize); + if (newNode->chardriver_name == NULL) { + return -ENOMEM; + } + + ret = snprintf_s(newNode->chardriver_name, driverNameSize, + driverNameSize - 1, "%s%u", param->charname, partitionNum); + if (ret < 0) { + free(newNode->chardriver_name); + newNode->chardriver_name = NULL; + return -ENAMETOOLONG; + } + + ret = register_driver(newNode->chardriver_name, param->char_ops, RWE_RW_RW, newNode); + if (ret) { + PRINT_ERR("register chardev partition error\n"); + free(newNode->chardriver_name); + newNode->chardriver_name = NULL; + return ret; + } + } else { + newNode->chardriver_name = NULL; + } + return ENOERR; +} + +static INT32 BlockDriverUnregister(mtd_partition *node) +{ + INT32 ret; + + if (node->blockdriver_name != NULL) { + ret = unregister_blockdriver(node->blockdriver_name); + if (ret == -EBUSY) { + PRINT_ERR("unregister blkdev partition error:%d\n", ret); + return ret; + } + free(node->blockdriver_name); + node->blockdriver_name = NULL; + } + return ENOERR; +} + +static INT32 CharDriverUnregister(mtd_partition *node) +{ + INT32 ret; + + if (node->chardriver_name != NULL) { + ret = unregister_driver(node->chardriver_name); + if (ret == -EBUSY) { + PRINT_ERR("unregister chardev partition error:%d\n", ret); + return ret; + } + free(node->chardriver_name); + node->chardriver_name = NULL; + } + + return ENOERR; +} + +/* + * Attention: both startAddr and length should be aligned with block size. + * If not, the actual start address and length won't be what you expected. + */ +INT32 add_mtd_partition(const CHAR *type, UINT32 startAddr, + UINT32 length, UINT32 partitionNum) +{ + INT32 ret; + mtd_partition *newNode = NULL; + partition_param *param = NULL; + + if ((partitionNum >= CONFIG_MTD_PATTITION_NUM) || (type == NULL)) { + return -EINVAL; + } + + ret = pthread_mutex_lock(&g_mtdPartitionLock); + if (ret != ENOERR) { + PRINT_ERR("%s %d, mutex lock failed, error:%d\n", __FUNCTION__, __LINE__, ret); + } + + ret = MtdInitFsparParam(type, ¶m); + if (ret != ENOERR) { + goto ERROR_OUT; + } + + ret = AddParamCheck(startAddr, param, partitionNum, length); + if (ret != ENOERR) { + goto ERROR_OUT; + } + + newNode = (mtd_partition *)zalloc(sizeof(mtd_partition)); + if (newNode == NULL) { + (VOID)pthread_mutex_unlock(&g_mtdPartitionLock); + return -ENOMEM; + } + + PAR_ASSIGNMENT(newNode, length, startAddr, partitionNum, param->flash_mtd, param->block_size); + + ret = BlockDriverRegisterOperate(newNode, param, partitionNum); + if (ret) { + goto ERROR_OUT1; + } + + ret = CharDriverRegisterOperate(newNode, param, partitionNum); + if (ret) { + goto ERROR_OUT2; + } + + LOS_ListTailInsert(¶m->partition_head->node_info, &newNode->node_info); + (VOID)LOS_MuxInit(&newNode->lock, NULL); + + ret = pthread_mutex_unlock(&g_mtdPartitionLock); + if (ret != ENOERR) { + PRINT_ERR("%s %d, mutex unlock failed, error:%d\n", __FUNCTION__, __LINE__, ret); + } + + return ENOERR; +ERROR_OUT2: + (VOID)BlockDriverUnregister(newNode); +ERROR_OUT1: + free(newNode); +ERROR_OUT: + (VOID)pthread_mutex_unlock(&g_mtdPartitionLock); + return ret; +} + +static INT32 DeleteParamCheck(UINT32 partitionNum, + const CHAR *type, + partition_param **param) +{ + if (strcmp(type, "nand") == 0) { + *param = g_nandPartParam; + } else if (strcmp(type, "spinor") == 0 || strcmp(type, "cfi-flash") == 0) { + *param = g_spinorPartParam; + } else { + PRINT_ERR("type error \n"); + return -EINVAL; + } + + if ((partitionNum >= CONFIG_MTD_PATTITION_NUM) || + ((*param) == NULL) || ((*param)->flash_mtd == NULL)) { + return -EINVAL; + } + return ENOERR; +} + +static INT32 DeletePartitionUnregister(mtd_partition *node) +{ + INT32 ret; + + ret = BlockDriverUnregister(node); + if (ret == -EBUSY) { + return ret; + } + + ret = CharDriverUnregister(node); + if (ret == -EBUSY) { + return ret; + } + + return ENOERR; +} + +static INT32 OsNodeGet(mtd_partition **node, UINT32 partitionNum, const partition_param *param) +{ + LOS_DL_LIST_FOR_EACH_ENTRY(*node, ¶m->partition_head->node_info, mtd_partition, node_info) { + if ((*node)->patitionnum == partitionNum) { + break; + } + } + if ((*node == NULL) || ((*node)->patitionnum != partitionNum) || + ((*node)->mountpoint_name != NULL)) { + return -EINVAL; + } + + return ENOERR; +} + +static INT32 OsResourceRelease(mtd_partition *node, const CHAR *type, partition_param *param) +{ + (VOID)LOS_MuxDestroy(&node->lock); + LOS_ListDelete(&node->node_info); + (VOID)memset_s(node, sizeof(mtd_partition), 0, sizeof(mtd_partition)); + free(node); + (VOID)FreeMtd(param->flash_mtd); + if (LOS_ListEmpty(¶m->partition_head->node_info)) { + free(param->partition_head); + param->partition_head = NULL; + free(param); + + if (MtdDeinitFsparParam(type) != ENOERR) { + return -EINVAL; + } + } + return ENOERR; +} + +INT32 delete_mtd_partition(UINT32 partitionNum, const CHAR *type) +{ + INT32 ret; + mtd_partition *node = NULL; + partition_param *param = NULL; + + if (type == NULL) { + return -EINVAL; + } + + ret = pthread_mutex_lock(&g_mtdPartitionLock); + if (ret != ENOERR) { + PRINT_ERR("%s %d, mutex lock failed, error:%d\n", __FUNCTION__, __LINE__, ret); + } + + ret = DeleteParamCheck(partitionNum, type, ¶m); + if (ret) { + PRINT_ERR("delete_mtd_partition param invalid\n"); + (VOID)pthread_mutex_unlock(&g_mtdPartitionLock); + return ret; + } + + ret = OsNodeGet(&node, partitionNum, param); + if (ret) { + (VOID)pthread_mutex_unlock(&g_mtdPartitionLock); + return ret; + } + + ret = DeletePartitionUnregister(node); + if (ret) { + PRINT_ERR("DeletePartitionUnregister error:%d\n", ret); + (VOID)pthread_mutex_unlock(&g_mtdPartitionLock); + return ret; + } + + ret = OsResourceRelease(node, type, param); + if (ret) { + PRINT_ERR("DeletePartitionUnregister error:%d\n", ret); + (VOID)pthread_mutex_unlock(&g_mtdPartitionLock); + return ret; + } + + ret = pthread_mutex_unlock(&g_mtdPartitionLock); + if (ret != ENOERR) { + PRINT_ERR("%s %d, mutex unlock failed, error:%d\n", __FUNCTION__, __LINE__, ret); + } + return ENOERR; +} + diff --git a/src/kernel_liteos_a/drivers/mtd/multi_partition/src/mtd_shellcmd.c b/src/kernel_liteos_a/drivers/mtd/multi_partition/src/mtd_shellcmd.c new file mode 100644 index 00000000..ef72e50b --- /dev/null +++ b/src/kernel_liteos_a/drivers/mtd/multi_partition/src/mtd_shellcmd.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "mtd_partition.h" +#include "stdlib.h" +#include "stdio.h" +#include "los_config.h" + +#ifdef LOSCFG_SHELL_CMD_DEBUG +#include "shcmd.h" + +INT32 osShellCmdPartitionShow(INT32 argc, const CHAR **argv) +{ + mtd_partition *node = NULL; + const CHAR *fs = NULL; + partition_param *param = NULL; + + if (argc != 1) { + PRINT_ERR("partition [nand/spinor]\n"); + return -EPERM; + } else { + fs = argv[0]; + } + + if (strcmp(fs, "nand") == 0) { + param = GetNandPartParam(); + } else if (strcmp(fs, "spinor") == 0) { + param = GetSpinorPartParam(); + } else { + PRINT_ERR("not supported!\n"); + return -EINVAL; + } + + if ((param == NULL) || (param->flash_mtd == NULL)) { + PRINT_ERR("no partition!\n"); + return -EINVAL; + } + + LOS_DL_LIST_FOR_EACH_ENTRY(node, ¶m->partition_head->node_info, mtd_partition, node_info) { + PRINTK("%s partition num:%u, blkdev name:%s, mountpt:%s, startaddr:0x%08x, length:0x%08x\n", + fs, node->patitionnum, node->blockdriver_name, node->mountpoint_name, + (node->start_block * param->block_size), + ((node->end_block - node->start_block) + 1) * param->block_size); + } + return ENOERR; +} + +SHELLCMD_ENTRY(partition_shellcmd, CMD_TYPE_EX, "partition", XARGS, (CmdCallBackFunc)osShellCmdPartitionShow); + +#endif /* LOSCFG_SHELL */ diff --git a/src/kernel_liteos_a/figures/OpenHarmony-LiteOS-A内核架构图.png b/src/kernel_liteos_a/figures/OpenHarmony-LiteOS-A内核架构图.png new file mode 100644 index 0000000000000000000000000000000000000000..6635920e71a8c2f978ebcdf03e17c13674222e89 GIT binary patch literal 158767 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

          {k+tF?B7~6hCu@uQFG2Qr+@5R-&x~4>j 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

          qW3)$PRz}e1@l!P4S*5@R_3z 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

          wTa-B81U~K8@ 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 EU*x*1LjV8( literal 0 HcmV?d00001 diff --git a/src/kernel_liteos_a/figures/architecture-of-the-openharmony-liteos-cortex-a-kernel.png b/src/kernel_liteos_a/figures/architecture-of-the-openharmony-liteos-cortex-a-kernel.png new file mode 100644 index 0000000000000000000000000000000000000000..9a028a05f5f470ab6f9c751b8a28f7a75e60d16c GIT binary patch literal 142651 zcmeFa1z1$;zA!!pvXxSi5D7t%aHLC8rArzlgiQ;Al+vY0cS}pdP$DHcDBUr2IC-fv4GDh@-oVz!0++xo#pKv z)Z#MmH|WhWA0MC49T6c>(L2Io!oZKHsIZv0h?t0|sHpfoVR12Gwe~e*6EkaTYX|3- zj-Fml&%K{}dOi2@eevSOOYfJSo}Rw$&wah0`vrujrl#f=R^}B}`ysLdzQ}Yg5 zS6*IT^}e#Yy1K6PU0v-vI2=AYy#c^5xv~dAnj=eD$A4D6d*197%Wg#r;^~vX?$MLJ90K0kbOd?bM0C3ry$GQ0B*~?vfD_i zkw4FI{8)XTP*4u(UPs@3bPfN`Dg4wsHr*#`CqvXhweuXKYZC-K0Vg|t0MPTYD_m%V z<=-3qn??sx_rF<=!sBg5+qR*#ZpK@=bE&{ptnS7XTp&~|%HwB{{3s=UQ2o(JT zFFpFHRyUjz5xRE`2n>k%_Brux0MCq^4wU8(pDOmfsJ(AwR zd&1^_>vt#Dx8+2|K8}B-u;_K|1Zc9cKnAQQO18U%=upt(fxOU+)|HeK%MNI>OVz(q1J)i z>CRXd=>F)N$3VcwY_)JA=#LTpAc3n^%Aicke$HmFdo<4`Nc^-VWfNrx52L#h&jOhN zaji7Dll!%kJi+<|668d+4CJxy zAkWXk<(|qg1RR+1%F-Ext(bKivy~nCn)}%M!V~1OD*#j%8(xl|;t9Feq1$)02vj4D zzIKTq2yf((A2$F4{S9)e+UJ){@hi{7U@bpHUwdtDX$BHks=B@DF2Xvx4Z=^8x50qE zqzGICHF)Ts;)xyW0KoD)+k|a-)ibs(|E|#q=VehKs?5~cOLd_dlV=OHh+pkskTyEd9z$} zW0Dv-EB(7~JYTQ66X2GwUI=X0BRRC@UsN{Um?ZJ_ zNB&~9txi22F6!>O*C$l49IU(?ocywV4Cm+9BJXdP6VjsKMH&1e8E%>PkvVi-+YvDW zzF*Rmw=EXfK0&^1rTt>fzua-GlhgUYpeB*tvTP_?UDXh&FPUUOeDf#hlkGG@nqG=G z3DOJcqdDYKlJCq5Z&bR8i~QoU-g&I+B~F}~-JnA4**W8DD$hbu@atEjBe2-~iH<<3 zZqF)Y216+&!(Oa=&%uoElPgD{;v-_YM&!xy}NW)8P_uN>8e{%vtv}R5qx3A(; zPncgykn!mi$}W|*j4WZJLJT~By95~O@RDRd;A34zMEZxS_>10E9AJc6(zoy|ejheU zanD~Vi-RBy*$Y2_gr@*l@p;B`wu7QyKdU>goZLziad#$ENickU zK+qSmNxi97IvoG&j)b!tl=0Nc<@eO%YxXzhHl3>T12K*m?R4#k2>jQJ?(eAOZ;(pT z4n{bN~LHe?i|N7NyB@*bR#~i%>6@@3s(e@i}xAdHQi#Y{*#2;S4 zoQV!p7ESF#dW9Ts^9zn$;JAS`>u`x`66bR1`gN)7hIhgOO;1qspYQ(4m&nxy=$zqF z!@!j_)dEY6By+#x>HhEWvhdhhhrg4LtdKQj;Ybd zs;tzvg3+baXk9@EM`&%crzw)SX>L@wUMv}$4@t51A9(&m{8uQV?J2re|6nd9Jjv$I z{8L-Md8D~IZ-2fNlOq-;FQgrnC=ynqq@WVuIG(>K`MX`NFuQf>t+sLlyZnU0To0h~ z_KEAAmyB)!TMU@Bfv=Tg?9QFtBm6M2 za$)w)fR;dj*Gp;@E&Ge=Dy+*7el=K6{FHWF&0Hz;$j|(~$Zx}6HuKwtAg0`ySPdP&J#QLw7&n&We_@2P9d;05 zzI$$u&Z*zUnYlOO@R<4>mZ^On}duYo8D_7T{Y%b0bO)|Sr8zS`6+_afp z(l&O&>CG+uBc$rZcgwb6;t&`8AMCU@vwxZ9?OP+o3LbfU4iglPok56`5kmdP&zQ3L zBkpxsmpte;RyiVbfXyyCi&|K@ki*rhWJ zzwb(n%<0<^Y900{sKI*x-IC683(ocu%o)r&!udKqZ8kSj+8s?&;gW&y8E8)j>QkAH zw;Rt=%@4g;e!wrbDtw(%;dTQl@iOOsJ4SY zflCI&s8}OnA;66WlLX&0dVcd?F?O#6@|j&@Flu`mx;ltLbh*KHg}f`W2iz3LGYK#J za|{L8aVCi*wfBSjyapLEyLUqz%|!nxnuYpC7knFpP#Z}o#JtW$Dv03N>B=R|LxuiQDRotrF%FGd6om=&0tGWw1ECTU9#-}&%x%X=7M&2 znHtInaR6k({_*ZEP-BHjJcaDs$m`>ueX(M&m@p>fw|QD)4Y1e{-z1%s9mm{}G6pOE zP_KT?=^BG#M3JB6QP$R>Q8$@j8PlQaBYuZw{?|loAx1q7j~Zn|q(L4rTqHp?eCMB2 z^s$iw63@T5B18;)$z0^0u3brJ*V|@)%l5DbTA5HIJbF4+%;WY9z!K8KOQ?bZFFmO@_Bsjgp5mnukLrpv4L7 zK5mo4Unmv*bcK7np0$9N)&DV(oNpF2XEy}9&2_a$J*A!`MeX)My_Sr#I)zfNo6Ac& zX9QbZEvh9tv=_fQS=(r|_nw!9jJ?bDXch!$776|nO|~#1p7l0kf&Q+IT8Z|#o7s256lWLe4?6=wT_~)30?0+t*KvCk~nf?FIiy14=W3Vi5G*OQD zfI7#4qLDb34V1EcQ%~}EVoE(#^@Z3xH12CWo9^`rC*nU~N=w>f zf2#y0c(VxI>g~n`dZZwr!4nF!)j=S8ihqTVBU&gNi;lW}pil+^)t2+$ZHQZC;Q|^; zAdn@Kocu}#e*jRJ13tyK5h_CK)e*K2X*Iz9+salb50=r?R5T@szR=D8T{Of+k`# zL>m$zV|kBe_yYpF+Q80m;PQ-Y5qnoJBcm-*717U4Js#Okp_k{sC`(CRI|TN8M<>5h zPFBCl@{xVMYEN27*?*W0xMScY~X>2-}N}CrJOa-kz4bp-AvRQ5B z_R4r>wD!uLe=l_@YJ~>mEc)vduksh|xG=P-)MvyV%tuc=v867@>l8T($*v z-XfD;<*9L|N)3{W>gP4=IP*$8jNPJW{OY9BA~^hZo2^J<`Wr21+wWJDYlO>R1QM?3 z&QUey>Vi8s^{LHeD!U!W-ZF6J`t?BepIU((XWIh)Ol968BpOu0au@xT7TZA)#0dOY z#GVt@&K{|d8*e!M+FEg}Y2)>zTSSu@B#3b_eODjVODX)|Q!WV%x zLkhj5U1vd*zp}s9PC3Stq-p7nga#bfMI#=UHeIr$NP{ts&g?I{K!pWx9e=ZQJjW&Leig>L+j&raOS(XiE71koOtmyf7vA)pB}PuWA=e6& zm#K)ZqjobPh{xcaB$UF(2dhcNyIqg=P6Jx4M!2@5Zgc^a(B9mJ;G3EV56}<0nx&vA zoWg_DRLPIlALl6Y!E%{ur$I6o4o47Pe{xycAz1^gqHIiEL|VGXq0hh!swFv8r*a5> za76?2H?07)uG!xxl81%ROH0IvGFT-pQx$kohmw*_^6Ez#TLZBnNKMI**r9O$p6jKw z7{@_*q?p+hp5)-Gx1fSg&M$WblsLiulkB$2Npc8g)Yod)V3qqxHJ;Rh)(>0LiC|2;kMsxnk(7@MW$OA zOjzirk)Z;@=;^aX2WL{0!!G)}A?a){CY5*G0E}7w4N8>Z4Jv|Sd%`q_G92(Z4%8<# z#Qc{OGl|u*Q&B_L3u)mH_Nc;9%VI_41i8VeEgs6--)Ol5v0S{~J|OaZBq)$j_^oTS zC>|TcpYh!UwGOP>a3kW8sTnp3b<&w8l(i&jX!DiW3{G*XzD{;wl7PWU{v))tOEf(~ z7>6Oe*$~xhY}TA(;z7&>3S9`s!nf5>i(6J)AelxIj?b%(k z4VXzR_A-_U+WKa)`L__Th+0H%JcxHaMYHO)Qc0@e^L8C&wV~7H-1DOSWGy@`#(7tK ze!Zk%-3XGg$<+ysbg8$6zW+ia9T%m2y>5?|xV7z;ifogNx$~R11#{1oZ$;&)jJ_+= zwaSfD?kIwIa;kv-^gJ{_#{S;1iNh=O(*8{5B?M5qh7%C)dE%wzr*O1+?sDn+FdP>0 zU_-I>Vg{6x)!@8J`gO*rhsu(TeSo9Vl6AdiXlN?rgdG?o+FUN`+JuWky<|N4l@PCr z5&T#bM{?OmnV0MR-<-m(>3$W&O(%4mb0HWuj95Ai8o3C(2Q%grGE zR<|VCC3JImbQXeP(w=}nZ;1~la|fG03PHEOLr2u^HpTEQ8StCSontFWkyJghSPt1f zFRW@7zuc4F@Olu0hr?W2XzAROCUAY6KoxHfqAd>B11O!^PLrhZj5?g;bGJ1|!Aa2L zL;bm}$-nGnyu5z%rcxdIYGtCEYE4~_3fk@PhpN+;kfNN;z)smxS67GAWu=T*C8?_N zEN2f$z>mya`?e{)xAsC=*nF(0syRYMdETSg&818bRjb0JmG!_6(x*_uQ|uhCo_2#8 zRjdlv0%%ut=ev1|ENU2k;v5kq*Wb7s6?pXIaP_n$+0&?4TktGgcG%at|;#z?9zOJq^<~&l(>UEx?X5%nB70zhScAEQ( zt4o5QzSlog0`aD8&e#q)nl|a^KO%|=5&$uc7v45b8B-EXHUJWa*AYw+0eaL$%P<>^RPe7EuYI%sAe-@- zHkdShOJp~I0D6;OG>JRVPU;eTb?U(@r~#lWg5z-v<{L1z7}4J47Ud4w1V0j-zSHi^ zhhE6KboEQSm+{c{myI5dD6fLmcUg{ig8b9(vk7kMJ0+*81aFMa=(p`4y$8qf3+`dK z6{9Zl_WZ2JTkm(OM5pP_j~8ev$244z^nuTDbCzC1tMbZrlE6}rW}2gVdf&a0*a)t= zD8=qi3GH8djBXWIlKXk_!s8gABt`v+U3Opy3E@(TX`<-LLY9^7+8XGm&y6?Vm6z^X zT#uoAE`&mS+&Z@^%tBOejg0BlQWm)CEy}qaeiJ?%BG0$~;IW2uWuM0G)4bla1tFp2 zw);xv`=>JC1@MQS7;DX2MEVxX?RuzUnn4|v?zXn5GDOKYERx?Jt?u>XZc*wpv=gGx z)M6G_W zt+XYA>Gb{uVSMRy(aM7PZj3oFCZ5%aF=j#?sNpZ(jCmG*_ss3Qg&jwt89BWG$Z% zREo4+98U#I)5?UaW83-y=+A^7*69jWw4`JGWbo>rH|5^<%lqjmh{8|31&axja0WL* zHn*#&60^sPo_*2Ms5gG**M|v8OO1&qsrs1)?yh^e#qjM9+3p71+WAb%0B^o5BFU?m z9-)VOMX!f&xEe4ZfH?FgRo`1Tm2jQYd3&?KGmG?wsCL#cV|Eltc-BL0amj3TPI|AD z6@g3A=_~L0`aQe2TVZy?<4~&zpMs6K7ik6-g|{HwsHo1# zwdXc23Zcemw;A#YwU&g4Hcq(n=ysV@j7Teo;+2xtz)}qC{=xg}FBrY@6pEIe8l+b) z##X7c;?UQ}MzdK^*s+rOweDqULpIrsh$pYRWh`m*Vht(5tK>~XCmz<%Rh zvlW&c%JkU_q*U2&mg|@-LROm#C_@Zc1*^*-uB!0-G6!S$r_p#RbzTOcB4%;4rkQnt zBQ7f zP9rchb`7a1t%(SYpfiivQS;YVP!YPqtr9$ZQRKQyLa{j4rf6%hZ$Atzzv2wj!!d6Bz08roUN-1 zV&W3BqQ;Jb%mgD5!&N(Jwk|SMjHUPlJz);Yw+u#eD|)`CY|GSR9Zwst&}%={K6%t! z4}gUVde@x&Wz(~I$)H;yQR~ev%MDSCaz5h`riN6rMe*V-SEphcocGTiCZNuKHd6?K zp%f5H<`2)*c-aM6XYb&kwJYSdY9=T(g*vkpf>$3g9F7dT1SVYzVZHECQBb~kJ?V?| z9&@Ei-rF`sSK6Ox?vKoI(u~zx7L}Hb!s^-8JS*gi>_mlRWvpf25uL3gL==83Uv(_q7!QAc#4706&K4pXB^ zGsB=^=kUA3@)E<~<~8SzRh6leAGt5;3AccY1r)|1dMQg95f%zF@9Lnp87FA1R($n*18dBffQ$dS>e`egDB>Rpv!=V-hI(=Jwt6w+fcU;A5s$CxrFE!h3iFQ5y z-AQuX@0oTtoT1l-wW0Y-b`zEJeQWzc&QALkz)nkx{)v4?n8HzHRA~xH@P~6ME9g2= z;*%E-*N<-BS1`Rtv9r1R%mvu#D~UkCcN*U^7X_F>1Q|nDeE7efuADi#eZEc?0O+@k z`CS0eN@hpxH~~!MNh7#yjOU7@_J0zw`4v@iW8tnGKXlb>n^%cwm zkS^BDIGAr@YF8!#Lw@6CGYW_Gvti zr_(D@jR;*b9Gkt-FN)dU7_q%lCtbO{Ki)*eY}<<_hy!EeXc>tGhG5prd_o*G2ST*Q zC4kGso}shzA7XHM&zP9x)yGXVFFTQl&aZMtR*A0Si=ORcd1qYgNh31rF0$b;kINk4 zEBUw_|DB0x*&CD?!A-i5Jd*w}L_OYdV$>F2Na?OK1l0oW>{)7V=px;m)AaNXb|LSS zPQb{E>(DX_y_`2~^yQuc=Z|aOwGQT3MbtFVy>=*Y6QnC4m%r%E9Z>o51#Im>ETE|& zo^N3ssPCNheS1$YH;G#`UzMXA$gwruFruF%ZnUBh(;zPJnfoW%Z;QqHA@FB&w8Wuq zOvxDGiiRW)?|51VW&-LXw9`Cmi!_N?C)TRM%2q76}7(-9joD9x|&~ zgeK_F_u0<@)CdpeAL?YU46d8hF{aycP9F~Sf9EUg5bFlaII#pAf2C(O+U=5%{!jG@*B4QaD!YGrV-9D=2BYjqMgEp55u?I_@L;X4ol1W>ugBtx zePH|8>HQ!?m8^&BFDMaQsut|ueKyo4uMb}7mwxUCSwr$mgbUbu?84rSbhw!d2|uhAatO zHS$kr&?u=+#b|R0sXr+;UWhjx-u);VYC(Rzx;jZ&MSr$LvTt((8=B)nXG5LcA8{4W zWn*BSS)ApgJ=Z$Tg5R-CG;Yop6Cjo?*wj&2_Ca6J>139J+C8rV{^ z=z6K6(3ZWxtMI}kTzv#xbjB{NYU7&~;VLr;%|`DJ-CUnY#^(4j0x3R@7u(U4ODe`m z+-m&NZ*g>v_({{#%?XJsFxK6g0q9YC=J;CoH0;}F+%Io+d9dsHtCNn{si4qA9BrAx zc)^}<8e)ok2Zh!(eQ+zSW1{b4Tr3SLh@H#yB@8DX&(g95_%t@PQRB%wIwjg14SC6?;*~r#Eqg+(uQnTdqbd^jl z$&#}fTC^bCy?M*0Z|(%eb(Bc; zKmCX?N-P1P-mfng(KJ3GRe{TTsJ}?=4HR_=(jVl%tw$aG%%$G#sN!$j`4~f4-CN`^ zd$Z0GpNqRX@hI9C6x1ncfgA|dGnV;5MJ{N4zkFR?;Lla=1!W;Pa(_B_h#eBbC33e| z@^N;>r@?}R^=`CfE{~!V9{0%z|bI5zv{no47X~BBnt>iF2Diwy?n4ihRX1tvEHr57E9=lTx9o{2mVRN?1pm zSEiJ$oW4caE2292ri|66^7EHSY0v2~xTJk@koipKt&xs;CrNc&$Gf{f&n;H1M*{K? z7pL8I#3wXKbX{T=<6*orZsUBnK4n;H_G4S zf_-2~EF?t*eyvpH#;AZl{~sQntT$7x23wr{124l5rnsv`+Qa2IW>Y#%dCZ|ZzAhAQ z+G8DhV?ugE$UL`TZ2NIZon^+2-Ko^{&+J^PLahjK2P2bLlLZLey-p`4yUp1n-u1TF zX>I(J6`UZ3b*Xq!UEf0T(sAQ3!Bi>r4a!C?-+Oz!2lRmD)QyJ{ufg8D77ZRcPnNAs zgk{L;H;)}rI{D&{vlf!?+46ctF>b-69TxqXkSL)lJZtl~~2N6=OmT9m@ zVcgfVUCerW@7q1qmhiGC^_#-JVjBPWs0&EjmhCx@^#K2iE_H7k{>a6q1`a8uZxsrH zFGvbrqaC1i9%YSV^TuUj;`s{!lWe8%oEulpL0sBX(}P_fx~+z$R$|ZD4Tsh7@RLFx zu~nO|)izKTvwYPeFe^#2ewUT|41QCy=>vQGfhc_G`M5P(gu9MGn^+&$xb8vVsH6IV z^~I||yonb5jD0AFQ3K1&TBdL{4^>aUJhAk;mTokLZb^sG zbX4Pe;V7w|x%JFA{o9aqRHYZ46F&Z}sf5fyNa1$TTjOI91H(%{^3w1o`RaH*4nZ2? z`B(n1^=qFl#=!&?iyd{6Pa{Mz-Y`FXWp!+uG{?(9*J>#3Rlwuirgu5D&uN~0cEy;* zphe0@k6fhj$3t5E2V4e*N;T+{dOF~>8MI4<`~b@#CtsWKHyx;c3R&e0g00&GSvW^jq}D6w zcqF|>3i3SXA^Q21+O1zT8sCpAr=`4KFAbb5=2^6=a3Jr00Ew)7r1{W-C)(ya*QK_m z#cdt@GCyW#iE;89*7sbUCN>;57}298`h-_KZ8GufyE`bq8{L>o+L*5lIb-vnH$+uG zwhtSaOse^d?tdv~>ud%uO5w>?^WSg#2?s6A1uYmuN{PnqNsN_sWTWMKmV*wxjJ!iy$9n3FX>-g#j8L|y=}T8=c~Fg zXPJ_v=X3R$TpJrdv%2|}Pp2k_N*vqol?T(6X?Hu~PHs;GmugF0$+S4la7sr-CdK;l zlJ%Qo91rlU%}Fu8sI48t|8|h2Y+WA0D3*FZloylEm8%A;1xRTJz5i(Z;6ZMja-9FV zOwVRI-LRB>eC}bq^H6p16B|CxxLS_IXRT*%>rB^p-bf3_f4%|#G!Q=i=l5tdd9TM^ z05KZrxSXO5M#)5`@_0c4_6lCzZ2EH#8V{Pajk33-)Uu2!O0Z zKCl10CxyYRSQevL^-X>+-c2C=?VF>M4Ul)WRnaec^MKp;?VMF~zzKOuv1by!<_D}T zUvy*;)@n?qfX1wp2HyAvO%^nxGTjWE<4Ts$kSx;%Xl4Ef+Y^uP6H%-sskN!VqE~OR`hfnD1 zl{R!ZVN!anoFtAqkjk|Z06i0Nt1lXfN*lF0`n?!;{p88?Dluc~`i4DjYNlsaLFC;5 z{>z){3A}!g5r%2&po4I=p?}}RQc4~i=)%dbA*mFs9J0w0;4*L*7Ub4!xH4?AoN$md z24FujY4_7zXr)lcn|cFSY0sIMZ>8bK9TI&-G5@umtn|rRkMe1#yL3zIo?aCuy;)2DGXb8{Y(?n&z%|if;rNQ4h%-s3@6W za39Y*xWp~+r)zzUZSS7-b5YV@bzq5AV`SFIzEv|TK#|WikoqKyr4(N6K)z}E4!cfp z&T)--X()x=M`gP7#IA0bp zE_k}}{i|Sg)_|{wS$XEpCJwG#{&T#4Wu=02TlTzuNQRI(zgtiSwe&a#z8ohDynE`s zveHt@LSfe6#@nO3tg+V)Ac$gps+9Ja+HVY6=uO>CR61FZ=Fms`CdX6&Q`*T-A8i$8 z3o<8zt#13?W5)B}sAC|Ca^FdX71veqnvvb3+0-oimVw6FVAv*gm6)v2k~EFYwPB&O zLwbCfL;`C+4WT;Vq5UudJC4!;gTk1(R$kbsu;(;VfRtx}-yM$>;qkkx#`R zXOs1f+CRIxjxopsQ`|Ej0Eg7y5Vi9szJJH7#t&det@NVfjLxEjkS5GbvnB2%$|RLL zr%_9DuXevBdu944C&6hX(+;&hlW?T`VjaNx1UvkZv>Yue6|CakWQ~m0ggIs_)?AC` zQg#cyEr^gSY$pKXDs-hJ*6S9YJZB2o2hx;cGU;+Nt$-Wj;kg0G<>2{8?m!<8*^1wz zhyPsi^ONr`IdRC4^)y+UE)bO#6(=_3Udl1`_1c*#UNO$iAi{GQGz3r7HB|`Gy;tg- zB>$n%Yqbu_#EmtSVtpNTkx^a=xOhF&^3SRYrQw(U(3nX_m)qW^7q*oBNtq19r(T6O z?F;}rtyc`2X2~#LkGSRHay(B-e;huuL+WQ`rU!aTCEhYYo%9$t^&;f?<+#2E!;$$q zPv`plqn@deUrLxLiWXQgJH zOFSw8RIriurM5RL0S=W>%7R{s8%0CgF?Q_Jm)GCW0uagfmaJWu zHFnm9yyu4Fn9`Nq-J=Dg`R7u7UcFyeSc7E2CRfL7X10o3IANAKW^63_YZW|Et$#%2 zxuv`&Pfk6i?4x|A6GdM-O0FgmZqF{|8tt|=ZwC)YGD2-6k-HmjcDA~T2N9LbKvD!0 zI`d~GQ%}Sp#y!ajIYi(y;-P}mtSO_iI@PNoQ`HUE7~J}VTTc*=<#=Gi(zwN-WEegC z%G9`V(Pu7^)Iyb_+vc*V`IEDRul;BmG*yqXzs}&&XCNbE{km!>GOwDxm@ z^05ei>vxJAdnV%%1ZfB+mwHo&^vp3<8=sDB+x;3jJlCdt#Y*aA3By4Li0URkvi|eH z5s~{|6b8IvhdCzj9=cm)F~qIuQH+$f`c>IaLwRW26 z3ns!5ycYDL&tQ56#NO0J+x!PL1_R>EIlBpp`p*s07Foxtwa1MJy>^%S#`v_qka;}Y zNmRV1!70~tanZi+sbX&{{jfOEombrUOLZR+9icm2t%-&|Q<(2XU~8ZRAmVae}m$oZk_@sQzAoz3YysNwrp!wLr__G8ZB zcSjx;(*N(2gAWA=!;!=0!7<4_R#N@fui^jAj?1xj!Sf*gbLfVTuQ$3`v%5@>Zs*WZ zdZC*&b*XRe{H`;B^Y=PIFqrE4n8Jf(Os4>gclG$z$NM}d51SGuHyu~#bLBCW`;&jK zK~-E#RBeArH4A8eSZ!e@guM@^E{}DJ&_l>SW^9l5b%6h|{Fj{n{hRH-gCXeu>0#yn z8nDMZfB+|cwtJ6s(Y^>2$rA$N^fx+?{{wP&*XaMG9{r`a^RI7+{&t)6e{nPMKlUCQ z)d=Luco|93GVlm4=7b~l#lPR7-PLXe=XJ_7G*IdJr9JDyY(U(%))Lc@ z^hW}fP_-gLi++y<<581{t(G&v2GBLf70oL~o_%mk1G;b)l+jSNe(U2GX%ZNw1$@(S zMovT*v8Au*|4YmM5VoXvb&)F0f(WgtNCG(KTP7E<96Gbzn_YuU>O(B5+TznN&Hrm~ zT&4LHNu$CzS8=42Yi(Z&3sTx>Iz>*a!Nn3g_(I9kz$$*$(gKzZ|>kG=Z z;mR-HqMaXM*gi!6WQt%vrtf#V?@yALI2KJ&$-_xp=A5s(asFvPFn6X?=c-iBtf&@B z{w{J(XK1SZo>Q*Qr}EZ`+pj&g=?s7;3&7jPE*)vJE`Z0r83&c$t(QNiTHum}!AR+{K?4P6`O~cw7>70Yxq(%^k58P$fsS;?H8H&s?!Qqv<<1xiy11Ebm)rO zNWN}5Nkt*A;P{$uGJ|Qp+%a~t+#Zd?-?ns z`eI^MA#?j!`S!OP zf>I_iC*t*vfo3ml#ol=_b)w54jAb7`o{O)!Bwy6L)f)EA;yo6pM2Tyrs<6G7d|zJY zrvpJ{4RWaR!U}XIE8Dh*s!L*o>Dg?_n5e%dT)M`eHn0d82enEpql0c3&<}G{4c+U* zD279-iIKt?ovwLr0(;N*=}XApvVS%?$4ORBRki}AufaWLU)k8`EPS6a@Rm&px|h}D zl9|4q%{W*xNPts5lPPH9z#FIK7-Hn{=_Nxf4(N%+QF)4Xy zy(-0P^4+k}e+I$Wg&r?f$eEjsECPus*M+_eeaB>6I?bo>*?W7EX-zJqrpxDtt8Fq` z7o{CWr7*0sxO9z2aMSxeYV3p%z7u@Y^!Hp^taJuCRPEdkzC5Qjr03Q(11IUHLkxGw zpA2rJ-YxaYNW)KEExo@M_Jy7*dk8LhBxM^=7f}`o8>4HZ=DL*Tli-Za#OZ^|bFRC; zv44vvdh*OHYQstjv2|cTKbQ;lL$%L8S<=e$c=SM=u>{isjCw3+75X`cnKxB;?YqMPvqSB*2x zD`^f#1}VMA=gL{vVV?%V$l7gFU>Bzk^v-pVFFpA;O(mHYL$x!tuA%SNp0oUe~*& zRl$4{LIRAsD&KOs7QI)VWg5{?m3cQphUzS}MNCwJ?oq844M~5)U=dWDIL6wfzDxe1 zHBoC|o<^!+Bg=+~$+!q=nW(~o%Vau|>)InDDS%Z9+W>(q! z6o>m2Qo6EIyX0>f)qTzyu*SlCjXU=KHOPCnZFf6KzO&^azg1<~B?0CgF@JMTbH=3b zsG88WeJy3qR=pvmP`}tX-quvJicIz+1;e*Rf3SJy(J+cC?5>NSyX#h#>x`X$PG0RC z?bV#X+w|l5io|>$Thrcn9~yIpLiq`7xd5HZd)zRLFTOb&#GI-j%e2qPP^X1wS3Wd@UBK54xw*52WJ}Z{Q?6ld-? zfy&q6RHp)&1XIAQ0QYanLC>fJz9sE2E_$=hw5*r0(XV1N<8h=Z__pX`0e<4e2grat zPLjMcsAb!W-nQ_o6I`;Oq=WIj9=(WFOMDzrvf2URS-gW{5zV4<;FRTF6nBf|lIqrD z^>t#)Xq&du*=AXv3|&LnJC#_ zy6)O_Fr{e1TI=x2%acZ6iZ^(K`vBmS007*^4_(7MaQa0U} zbZX&~WcE>X4m#>{xK69pk1w&>Q$*q@FRs05Qq(3TZW0$R-#h@x)ScG$ZMn%>S6{D;Ba8+#Mi+BexAp}f>T8zEV zy%FuUZddD7$q`kpOx*O@(cV-!GC%depVZY#a&FHPY_G4YzAwQv0)J7j(dy_YHT{XG z%VRr)Wv1#+CLWP&tU~QC=cokg7Ah;GBY3y&0?&ORq!KP9zJIip(n*tsu$8=^^5O9x zS%qm?CySNIJcL9|v#AQR{8T)yQ?MX~KF`m753fi&xNsE}R8*1h;>VaF%&I5b&z!%O z&K6aLdl`SICA!EQRQ9YQwM1T}BIv+6U_=?}s2zMt1A?#bV*Xpt3pjC@q!!Jd|r&lmGgoq zt(nrxNO%8+s@Lywpr_PCC*@6Wkq_iwWsHzd-x4OJa|qU+%{UCO$cY)r=GOnHXmo#a z(ECsDVs4Z}sYrtHmk1*p`DEtdd4k}KZ*Iu#24$&r2ZjSJg=Bz}agmKcSn`3p>t)Ui z+WsM2OhhtqqA9-+9UF-{HcvaC&M(~hnYQCX)q`p!{uT-4l@_5vnp1xx@0?|-dNMC6n zl%tiEz9CdE0G1wHY;gS!m(L4Ea#P_)_WN@fg%eV2ERdnmdsXskv3uQc*7;^;3L_}x zI`ekrlnG^+1u~L;HU~p$)o?nS%ZLtw?UiXdrc6xgxD^>nMKU+)O7f4%<>1CjJu5`? z?Z_-QlzNINQTNf?6*FJWs8Dc1^;6$fu-)?kEpY|vgb%@vi~k7i}@>c z@)S-#r|<33oQmz&>R+%zQ-2fW9Gg=Qx3deSDmXeA51lSU#rWf(_LBlJ{5_n_|Nlqh zV9-yS|J+UG|Kx=H&*JxgX7>NTS7!hF<<6rx-4XxSxjkhu5%U}lmcyG#|D)${{MSm` z|3eQA`4504wP^e6gG{P!0XK)OVII?>8ycxLCOp4)bfLEnwI~zq5h+4)C~}era^k5t+B7`EG{u$3iFHfH7n3U0Gm3 z8Tth({gS&;o+NhnfIlr>0tdYbe}&r9BzD4VgTC6|f^Y)Lm~m&ZbYq1 zq7QLL9}*qG-Fx|tB(62=JQYLV_WpF21?okaqA#K>P4QfqAS@|LD*bjza~^>2$SpMO zH^ZQ_EK{IRM*D{ByDgX6FN>PK5_ChYmoa+T{=lvBqlK&p@dz&U#gix=#~H2+z;4t5Z4rLv(pQGQfBj5 zzZJ+@Lh3qWGS-!}os) z7ufvi7J6|)`OfWolIOuL7BuD?;umIxJLxb)K|i!Ld@!6uq{{dzd5669-bPJiCQ3D)pUfv}d$t=wX7U_;#2@G*=t8k4aB0$UCo3-$ zlCE0sh?h!Fg}4^p!wU7CP&EuhuOq;$WAOBezq;zlS|~9fykG4@1$CR3Yh!GXV5kpH zf+|_HUWK(L3GFa9ZdR(ru-)xI;bWu2<;2Y zsY`KJk$&zO+}@4{R^FNBK)Dnmc@iKknx#_$Bl4)X*k;JqXO`+%SS z+Ix-|iZD_R*rxP@*CwI2I{4v%qtG4UTEpt52m#=&89M08(HoRXwiqKbG6--D_^Ap4 zC<-i_|DXCe1iZHc16##%L={@Uf#*l5Cx)pVz{B6Bw0iEq#u+w7 zeYD&>;7Q_ZlXsaDLRf?zBV9wsE0t1{+PCF}1-! zf9vJf`bYb~L$<1@4hd9i%)?l;ook_vK)M8;-KVNCIWdx8a!6#y9l{p$7wuwo^NopF z{qt((S$f0!xnjod&)*Qfn?^eD)H<<1&-QYW^qO|+n?VQVWkp(wdVfh?fy;KoiKEww z24{<_wo8V0{4%5CaH7}3jqeNkt(^o_Q6BC8%9{2E*wR`TD84jbdxiDT!f5eaaguB*yb3O^dPIYBUi{E_zFdpgdltDLve5ygtc#MEe#80vhOeXXPXYmEvO}VSnO18Yf-tj;K9Z0=dMHBGQvj12kI!&-uJ)-%-k+-};WP`%rr zZGBFGDR*6-QPw3y%0}{Ac6jhZm9O}qCDB6>>u%sFLKby(2{)v1E*Y~`%4QVJ>sBPC z$%gOtROo6^$-PUYmxK9g4Qda*>C2k1l-Gae_ z`N&>f8P+fk7uBzuFt2KSNpTJN7LkaICEtL(TvfdSjrgQd{hSh#U?GVq@#?H4B=<|jToQ-mv#jj4hT)290{(}mVz ztC?9v?kF!oDd&atLd!vQGv~#Lho?an5Aa6et~wiVvD5+~M#4a=20VAuoh3dwP# zc_`;nw<^Q)jfF%eb0B?l0hUoIDUPF^(+~x#S|~FmHCNVHntxn0IC(x?+nPIo;zFR& zGznIE<`ju}R}#YV0T9~!IQTvc!FeOrkdmy;A!T;J*twUm>y>xZ?b)Y-WLMTNZ>;6( ziSLq6oKk5No_Z*zFpx>0-J2tvR}3xohp0z!;o^LJOKx1z$200s2R6-q2N3|zkx&}Cl|-}o7lPsUr@v6rn9l1xB`f@r=vwTsI+1EQa}{LI`~w7Se%TF@Eqz!FU2LM& zr|@q1sf@rZ?Tq4b7bW&m8Ham(#S%ot-Q>@*E-Kcouc^)Es?Z5$vM;Q1qIS|{w;;?2 zCkH+HAkURc8wG17cEUn%<84p%Z|UtckchVBsm=40;pabxC9C=Ax{Ws$$6?b^wRLEN zMg)H77jG+}We2afNx4wZE)SHV^giNj`aX+-x#_2#0mm?MX$NY~l?g`;JGQ;R|Bt<| z4y$VW+C>pTK~TYsN{Ncp2Bf70MWm#=Te`cHhD|8lDBZOwY3WAk?vU=TyEYgc&k;Sp z@78ng_b1P0tvTly?|4VdG1uhbOuvrYp0qM?KZQ4JQEYO99V~5auCgI{8yq!?sh&H2 zQ{D?_3PH~1Eqy}Flx}s8<_<}i@pesp?P|^*+=%Y?F$>!+$nr+oqxuOnD>e#Xc!`YN zJ>r-CoMRfC`0O<+;)Y3Hmyy$OsN5Lw{SA##qB zBWbLOVhhEYK!*0I(ATi8RT#*D2xby3Wv(G~UeZ<#<+b0OP_ZmTgR{W;F747b8Zjt; zD@|>P{my$kvexPL${gC4V~l*FF^{7htr%q%*lr}?b*;3{CF+Qq4`>o0-uBecGF^x* z&B^W-4fKtk>AauyF#$a+#kiy5W!6Hn)It{4_*F}MGO;$pb_QV4#dl15VyT6B*Itw| z??^_P;lUMO`A(S{l)TN*W@g(6KCX5Y@j0N^mEUeHs3N9eiwb$c+Mloi+H1hFhck;& z>5eI+!YDybn_MzgNl&|WL(J%)cji7aCt8zMhAK#&q%Db$oOY8cjXGl`!Vm8v5WaeU zi#OgumHKWY+qc<2SmW2{7wMLLQ=P1lN6FsV_Q^opm@xu}Fb7(ni6t=iLOiC02D+Sd zCG^scpvr((hRP64l_h^-CTl4f2Ft?~9M>%^hKdT)q?c4khI&wy7A>3UiN?op<$FI^ zl&*=6cFubzUi@O@tC~EkLmBmqzQeR8WvZ+Vr?QYMXp>527x8&!8?tJxX#GpPtjU-( zXS=v=3+S0K)^mJ@U)b;@^u>(FdCQryE8YGfH;6T5q&jnDBBoC#0dAT6d!)s(f9nYU zgQ0p@d`hzp&4U2sZ7I*gTMu3_RSo5FZykyJq>F^RG_s=agb z3^Xg{MUcs8{5E=o(<%HfKB@c+3=1G;D-d03NJ$5$vF(GF?mi;ptlgz7$h3f6A&~nJ ze#Z;03vs+1f4}iO5lUnXYE)zfTBlt+*^`p@mNYE{Lho8Xnz+pM9_AQGM%)OBX$3({ z3?#Zuzg%#U^9&OANVd6~mxe>MGP`e5A?Z)CmDP({(^N6|rYegkf{mP)P`ZWCY!nx# zL0G7yKP%f}W3)a&dM)iQ%YIq7`{ZbL;1Ox3O9q;fj+P0F;mswA2>EqA>2|R%t*X@t<{_av^R9W%WHo5=%h4kof7I zO=xFQqohA7m2S?R2scjXZnnr8w?_PujOgAPy;D4VY_<~0JQHEmZQx@}KTK_eLz!nb zE~U<_d=L!ELQe zvfBw}Lt90l{f8K@%)bW+1)i%#s6p2WO-DcMwVEFo64~9nT+Y<~ErOA)L9oB6wX*dl zV}c(Y8A$#{(!NK~>CuOkoR}5&x8ZCW&zH-5e+H=X{6C+|tZtrUcI|)7?7k*nli%|= zDD(GREihpsz`W%+bCo^$RMUU?bJ6+@N7<~e_EtpT;K*H?&Rd8?D!~=tu_3^XC7O+j9W^ktOf zfIPTkcUkBCE*vXlN#A(1-e&n0aPb=tcDGDo>GW;5MGo^)VBkd7SFK}v{m~;w=Gjx& z9<6oY{bGcn5anLO66e_>vR6f)B9;=$LCH&ba6?gxn#02&gvjNncm`MC>!bxp)!E}# z$erdgaOUrshJpEt4(pyPW*clTEhD?kJj%vzj0(us;F^b8?Z)vdz71O1f8N5rFu~Sd z2E(GlK6DEEGBCBf7>(X@$FCT0UbJCD$P={9M_4{I5!gG-BU*MkqG@Kp00h8E6o>;` zL;v~jOVmRiIhcvuJkS*yxpbr%YD@$O0wM@z0we{z!T_^y?Es^PV`C6hzSqvO0Iaqg z{ji;8S`f(FG2cs?$?Ct~)q_CV?%1LzVC=R@Zo|Y1tbHrNx^F9=^EKgqf@TZs1Ek~} zS@Q)$uoq#*vG3k2C0dWmS{6|}mcWw0R?d<>HbP%` zRYrd=N?HGlGb-EBpMq*CelO4hqAP8+%bf2iyqsaWJX@@WLU`2A@r?2D9{Q}0Ud+xOpR1?+BV&>ZF07O`|oLgH6Yo)NqcdzJEN?`X)Es6 z82nl05c;*P47||{1$kSkz6i{f(qEd+So9`#Y?p3zP1o9Vo+z|~g)IZLVmoc;E%7b9 zzTtR9Tv&N!4p`KfaY9ptf)CQl$jEf`P{6NV+rQLfI_9pHfhtUIK;uHJLq>KFyO2x8XHH~@wl3Q%=@IQvojPogsb-Ap%!|P(l z>c%rX4Y}Dw1=%sDGs~WH9wE4md_rZ_Ozze@1$dHop%yB?q&~doAywsbeS)lp@4Osy zKC9L#b3(nP)G1{K8%r@ABwm8|Pl#+ub;TNFpAcoduf5uNAz&iZ@F+-CRg%xgX`McP z9r%P}P?q@qf%!q5o1En(%=lknX!G^@-OCW z?)=gTprw|QjG2zbMTjoZ^whBTCE_+pwm@I^!gaSh;Vf9=TR4A5%!{_>)C|NcM)kwH z66CAxbOB$MxF)9`Z(!hpRCtruC4kScFAd!3ld z>>L0sr6p5hfu`ZZA6(n>scgY?!2B*)eFBXOVtPQ+JQ)Fo^z%y&phLSiQWutDRY9iB zN(zX@Hw=(|y|O04NXNlp{7$ATd4_NDZkI*h^gBnheDE?GTn%wQh>bDtmp4zsZ zg|13F!74%1C5$z>S-N2#mG`KyeS0#m2N#k=bo5!~z!-V5dh-JvYMc1D;?&`~uU#U( z(CdrP^)-33(yPVaJ%R;wY1qLX9R0o3$KJm6Dml`4pqPW@hmuWTm+D77s`>>)zg~S6 zuZk}vihiKQ;1>~2x+E!Gx78e3d4VB~5(baUoefKssx}0Hj6x+kxIp)i7JxE36DjZ) zZ7vRBIxMw+XBr_Z&sm1#ek*@^{!(Ui zAII7HH<-rF;7AlZuqdsFS56So?mFSB>!)8u8hhpYYLvxNF5S(`dOYnyWReH7Av(>x z?ah80D;qbMB$Ra4eTRH^r|kO1C(^bp0iCHQVI4?Wk%NNN;ggIL#@BpHC@u^qeCMe+ z6Z(WA=E05_6YC{EDT@!xX@;g}FbulD0gB!8xyrD(V!axP<_S4;WPRHUiWU*<&5n!J+F+H)T1|4s;781%-4jVXIW$y{lo z0;5VM7bIeSO*%Aj6m5{$dT=y{C9N3uv+FYIDLecVy$d>P1-7d$t6}=t zS=gB*`+``AnneRMl!8xcn_ZRO2tT5Np#5Oygo4Jk4tqP^JtgME$fQbT%ML=)5YE(n z7P5~4XAt%f$Z=g5xYkWno{um|Q%gE6L5ytMIPZfMMI6BrL!FC(pQA&kv>)Jo>ef zGz~K!3w{h5PsN)NhF3W(EI=D^e}bin&PP94GC8homKH=He|y*{3NR5Cc4J5ua{oD8 z&a__4M`ij)$REu$zxe?DiKS5=vmpQIlHPV`7vzYkQ_$m%CNZ1wTy6DsQyOkPJ`0%j z&~TsO*M{=Y9`j0u&uXE2E6+yyrOBvgb=r0}ycFnV2Ev21$X9D-S+;gE00^u*(L{dM zkE1qzjp;|(4v`*r8WY{04O2u z^3`Z8uJ62??NmVsI>Q_FRvFts{kIw>4%&oQM_4A3{cyy?#-H0!dht3Y6D<+k`YM)t z8|DYiZoP1|Q^jNr=JSK_IpqAe}2 z$sb7Qd-S~Z6LZY%*HRh@X+qJ`OlFJcFdg)NV1(N$PulX?G|HV6V~6`0(@*b5UdtL4 zQWx4>WJ#z-v%hVB^$e(J>{Nyk$lu?^F3rx>N_;z{q{&a}m~F|2E2^(G@LYZ6b~9qK ztN~s5;iX*F)>4)cj%EJu!G<;Wu(cc02Rn|SXoborj|uz~EZU`+<&C9ux-^8@jN6TO zGqMB4XDde<&Ok?)g*QOwZ@(DJzrR7d-{4NS5k^cJR;!gf%^9Y*E?kr$00peXH~yMD zUo?6G`uPKuSxS{)uX1hgf~z(@-`x1?8|}51$@zcnoGF`OmnAq0SC(PCG-Z7oM5BS@ zp%JFiI@#$z8{n>c*alopYrPkYyaV@bc?f|Av`3c_$oYQ#QUwhV@xAB6vUv8ypJc;X zWuub`D1!B0U^VJrn8n)E49a?!rV3hGP$8dy|L*)H=~x2|ZGTOj+l)|y(l?zU&TWpW z1MDSTIxo1NeIj@98sbx58DgE{V14y{&75mn7tUO>b(D>tb#Qa-fI<}a9`EZ_UVG(4 zaz5_5%p!H;K54sqnfp0M8L}meUPPO1z!`Au@jG(Ee@VwOiEt%wk#B?tG=EKjbom6vbzF~EtxNQ5~>6}qPK^`IhT9P`uc2X|)rDf~)Rg?dJN>Bes z1lP|;ur)&ZLe>bmbYjFoW|=_1qMdBp7m;NBx2n;N_qATWK}h}qLBYu2Bk&Mm@eIhO z9{$GeZwqI1BK0iW9_T>>4ipRpBfvxGLngokUSIxwfi5g*0@tS6omcN;5VouV@X#gw zLIj1?$IibmI5mqJp_PtR5#*2XqLLQ?4>{2fI#5`?$OM6l>tL{@03<^hr z(8lmIyX4MB*}-Kg5QWH}thdisfTpZrXV*1UZc1lEBu##5)}=MuBIHk$+ZAXNy(8Ar z&DJqbrI8Y)wLv98ZxdMEDEj{QB}Qo81bTCZQR(4(^&keB1JRVA4~3&puzdWV=r@-j z>ZM)4+6EeJQB&`1f^$7KgUHRH2n{wGo|Ik?e2JCb{l3R9fC_sr|F#E(7E4P1Lz z?8g7Ceh$r3WwW1l_uHS$mSs$})T3p500)E8F#834`9un0TL!E5n1?SEQVv(TEz-(5 zzI1<7D2YrfRV;{~y&V~_J0c-lAh897p*1q6wv!NXqx>w)qH?IOfWPhp0E+1KnQC=z zl%1VCO5@MXZwB9`uXBG*@wBZor{v)j?v7UNfJ#%D86`}|$g|qJiws=t2lm%Vq+se6 z=o_E)dujI+?JUR)aD|>1TPlqqJY1=H0JZS=T4vYn3Y;fwEt1i@?7o6JdzRoKd(ZV-D0AIzeIiwOzX!yq(9;T_jMOcUt%zsl@#ZGhfx#LFB}j0X zs=gRg`0iWM{RsQec&8F7Pq`u`7&l;gcKfS$4;O0sSce`fov_4c<8wK$>zSgjwvA0{ z+1|8Xe=smfAQdm!!}E22f=-)vlR8R-H&nXXsY%-`q3JHkimB$2w>6aQVjKd^r6V+d4SgYdZrzGRYq7N<)u_WggiwpXQ=--&hPvI^?L=LV z0BW6^JUUiIP0E^Y^0z&Kiv&_KaQ*dzq!LlWKJ>rh6%^b(y@9j!_5u5N%A2M!qtoKz zZBHkHSZ*-OF8WJ7tV+nt>;IB+eZd}FVYv>my2;i*u0q%fI^!gyb3(uPsEp2~GX}puj#^KxkBFMIV>;R(dnb$8xtu-aA49kvLNZC7wD?77Bt|D(V#%r~1Lhe3b=VeGT>oh3 zUKqK0tEM^YU8{lUX>CZ7R7MA+3sV9*xgzVSJD}~{U~_8E6|z^C@p07!d&o)XVav@N z!IForNsdEh(mXPqKvM^94aHa-&twEPS+r)~jQ3Kn&*{ZzYA90XJu&D|VSd{2eHo>S z+;hBZpAxavhx2bPx(_zNVkU=`P*CZXu+`n+mg_g<^ohcoQp|ATlURXcHD8QnN;`(w;FvYVNnvQ3vXRFsmFL8 zrf(vvRED1W!O6T$_{$!Yi748;8sY4i1rn{cEic~$87a(LOdiKI+{h9Naw+L_axE60 z`yx}sow-hvH6)G-EIpGPpqv9L(#pDu9B9S!lO=4^1`oxq2n{)9Ne?+xHfC8VSyAfV z#`=;gQ^qRM$a7EU-CwX1j;dDm^pfArDMOOLF0(L6vJfCFwMDEX=(rX^Q=<4;u~^e+ zSd=9jazgLvnnrDvcn(I0U(8yf>v${CRV0ySJytRpi(j5t!RRdEIc!oPS%r7WT1xZo zm8Wgs_mWTUR@zAR%w3P;CZ?zrrk>c+vN{Ot)|BRp5{nyMU?$~NK*Aob-F7%_#-1y8 zZhYCgvW_sUC6l^9n<0A~qXN=@p6?1uopHW9h+7$0-yna&N(TH{f{VjBl8NxqiYn@( zdAwzvhgZG{p6$|zq$M4+2a5P3B9;LMD1GLUNW+N9?Gb}GOJ;V6{6wZP#TVDCvx+Zm zpkgOI+d;8gs^PL6wi+Kx$T=4zq`t579uM^EU*VFr{`_eT2ot z6gM-7Tce*8I_z_9wV?}XYOB8uTf(^TeQut1z7h{GAEkP-7)t)#8l{P!X=kN?kh2t% z5=5s?HzN$xF5mWaR;UaU)GueZgVs2(`W1)gO?=?Y5s9l0qbcEP*BE>#=96!9P+0xs zG^7nL22Orxe>w0dBp65WE7f1cr27zPN#Ussab(+QI;X^T9B|cW-wv#4Bxku62Hcw{ zbajE}An2{TquExqWGrQ`Vp$mCF_O>{6B>11WzL7D)QZla2y_ z_O0|`?bL6ICWmarNLTfXk&UG#hty2)7v?}|Zg6vjmg;A{I31+4lxNeF%6Bx}S7jz+ zsX6wtZjJRp55Yafn9nK$V;t$^abaot9D2h7mz#&u0-RN>#ssd5)dD z`x@SpJ17iKOuc@x#B7M$A=~=7)zpCWv!uTr&8uIt`XF^UnDc<#lGGI^e_i4<1rn>s@^R61xiF7E3#lF+Z*2>jQNO&?i*1YtOW8`_0db{Uua_+2 z<9uT}Juuo^LnWFnt9n>!V$oL7*)5Ppm8vH5JZw$)A12&GY+?p&6C0{|Iwj>3C!3|hn0rM^WZyi%{M^wQlNut{d1X!X{vlIDs8Yab`wM+dFuu-{ z>@FeAYEm~1Bn0;L!!uM5jBD$2o2-;1JK40}YQ@K!dVQt8+0X{(TCUROMm4|-FpM(d zC-1Gg%IzDa)6OO8%N&R6(gjwW#-*O4yX|=c=QQidl(lF4f1>bSTG97rS75-gIp<@Q z$-6}UtMw3Gn3)ll_u*YCOO79k6nf_>BMBc|lp!_Y0LJ>*RbHxeleb$BTuSL5FGHsk2^tb_IScFz>a3AWA>ge@@+%-?Ffpw1sv1>~4D=C5Z}buev2~#kIyVe@s3Y$3K;8 z33$L$xX?`bbz9z`CXn@}g1IwbYt+|J*NChg_{jg;Im_xz&;4&pFN|Ejr9xC0bbSo! zsgGd|TyWymUV?G6mz6T}B-=CD*pU(JHMpgzLgzhOVE0on(a$@Wp!CJVN{MDJzQbNV zwf21n*4Dz9j!&ulF;+9`d-oN__qLdn@tRSUGf1%V0vxEpztFcEp?lDNU=!NQ5~K|@ z^ePQI)`Z#*Wf+)kn*+jWE(vdOciSn(s)gl|CNBkU+V`Q)rxAZ``~qq+cFNduO4v06 zE|`I!5|b0f$JF!TOvpE=mt1Y=7A;B6{g}GQd*VtaLdRk^uGZz7f~`uDF|dj;oGT*~ z@}?-L${x|){u|3c=3&F}@D;px* zXJZ+IxN5`sfAdcF7Oztvl;Ow#oSzyEF_0~hHKDuJKKIibd?tm2Cz6l8do;l#QjlIt=%yMBALs6$Msv%4v z+q%4%R>j&WQ<*3HhG)RXRcb!Dx&lfA^_BEFLj4@zTH%eHru+9erpm917k^N)vNFNO zR&U?1Q&h0@rSBpoMf_Ot{btOS*(X)kY+jA(opxDgm$m>$zM!^Qg(rV!f#W$vfD-4@ zm3)5vAT9bssX@bGG_&js7>^&8t_yF9RgvyEo2#!2`AK0cqfd$U zsRTF{uda^G*HBSMH~VLS|7a0x{!P8CUpYyKqH-UMrLMlf;X9=#kMg-IEZRcJjAe1} zAr1##hpad#?4+%Kxkm+|h#lHg9($_dmQLB!ri`PB^D}>+YIpoy(JW7rq@S0T zjMv3os_0ED!%zW;)DnNnYU72+DPiOt_{P8n&ftTuv1NPOeN%nSKf^IDQaI$Fn-YO) z$=PK-5U-kbQi7UNaAhvCuz;=#XnHacN;8VHRZ{8~am;JxWYf>eRw?9AhChDloU474 zqOcMv(O~-?Z{pVO{e}h&@mEw%(Yp^JUX#TH%~LrKsTZwn37KSo;CpOIy6{!Ur72#1i42;%1$cct zSt;xKed^?pXVN_V$qpu>ydj)P5e;+rHlJZpO{B(k#m~2914gqGy79uy=e-ihe)7Bj zQg4kq(u{nP{Rm0Z7L{Xt9cEyK;rfb+*(*y(BVT6qC8Sxd2_dkB#zbN z=mQ_;i~Gry1&^)U6qX{wIWXun)@)%ZkVW+SA`X++tRk)anAz{KiX>-=19nc=R(>?c z{;qC)?7YmR#pA2j5R!ZyB-fqH2Dtc)sA+FC@^Wu(hH!@4QwJT1*-dB$e@U>b3yLV@ z9o>LAC0!eUCTfOOs4C;`zv$$CwL*#yv=MJDr;axf<|>YnW8URsA- zY1+zohlFo$SM=wE@khtyt3A5#$H1#Puq*NwPL<26d~EnU$dGUF|QYw zBJNS9ZN)%sXu6Y}k`lgQBu1QvvNn?4&mY2BV%Qq8ek>Tx`IYyCuBoJnVAT&s)tFo2t{L!OZQSUaJ5XV~9=rN~OO1Ydl1U zM`a_~=8(lrOMO5b6{@nRc`ON1at)=`S$lZKi4+KetxJ~cR6sO^i(CMMVW+*N3~_LW zw_I#R36t@$GxTQ^l)EbT-eI;vgGJCP%jXOZID4z<7{$FgseB_KkZN#VXK&TR1*n$# zyluw3sy!^`+?O*v*Q~>8ixpjmrNSQdeqCIKc=zQONE^k9)GmcSDS}_0Jh|8AiP!Kz zZCCSV0mw7+O+cva8H`OGFyNT+$gm#R`f@}D_M@0b`GKt^+{CZjIxt~%+~Oz!AzM;0 zf$yuJUTgo5^{6?hBv_PMMPNtVEW7O3fu$FeTal9{@lp2`6c=aB`nP515=SLG@>%oI&@|CZUFa%E?4bpfz8Lr2dt%w~Ks;Ih-J z8Xc%!V@WKq4(8uWu9u^w#?_`+_%1o6wca_4G@z-9L?)4DbGt`h>}XOqPEnXC4QR6J zJu!SzbIWz7?)CsQxi9kk;STF(dD%ahnlY__%vx$wW2JEJhh!|;xl6iz4_g)+o?3*j zk}XZZ9jjE=uQ9;Th3)MT9kNyX6VdA<%y8Pv2ocl?dwzx&d z9?_WCCpp9ZOS%$1vD{$eujdH*v26|uN7#7C?DpdZ6!*_tfTu1=lkAgnBUfUOgGyBO z+L1wcWeMSWwluH@KvwdQ+X{2cZD^PvtPW?M)u} zQ3$0($H^}LNtH}@Bj^jk<^CO+$nLl#6XKhzKGhM}N-!!@cx%<u(@Yi}+rU#)Km*XEVLI=vMRafM1 zbl*?E(DV%ZJ#~-mRLM}+{MjBLa7 zDY2l1p~5D0+QUwS2dU%;;W&#W>RSthD znv){)N)~D>*n3+kaq>TU*t-RM$T}tiYW!F0Kf6TyOCyuaIioW4OHpOMgu(l>G!Tb# zfX@gWA4r!WDi}^>GcDgh!~_~OK1`7T-Yq?`=cH-jcZKa!vv%)V`X~|pVII|{`Xd7D z9hQxN%OoY)JZ>@R=TPfu8WflMWj*wVEr-240D3<{8W+nYPI^B=^I;Q|J#83p-NwB*+aAZRTXroF=zWn8oj>U@_}zZo4@b+NV+Zt< zG^v@7kRJDx7&XfPk$|jF)=8Jd@Ae%}IiHXW`}j?gexPNer~%gZP}G#WiUu_b`Ky># zF6vC^VHMo$FX+DftDyhE+D2=Kyc*CsqAmezzt9f)AbzMMPA*b?(jx;YNtDP6DbgKL z))|*4{cG|0l(3t+*+i@ZV2v+wld$d)xhd%#SE&ztH;&I67LgfT@!-*!{4c!Vj5a^I z-$+9S?$-zHbg2}M_!h+SfIbql09e0`S%~%|p86z}*jMeIafGp7we&EgFGUB4gXc+L zZ7&N{-3@F_4Qk0>VSiTtW4+A*b*@A&kWu%F!MacS)Y1d&g992xzk=bc!;XGCyBb;< z*+BmaGzHe@liMgudi0PqDCsM<&pH7K=)2|c5cW;Avf}Kh9~kPjtL{16$d^FP`F9c+ z>K>-tV!oUE^80)u!316(wGn^D%jj+cz-hJK_I^u(JVTe#1{d;DdP=fb{Gre=^S`&ifcU(QO@8BV^7b z^ZGE|8&``(F8c}A|2s`sNlinpv6}XiZ-UTL~sJ5#Tm5 zwLdl%T}mPE)W>Bs5BJlbhVmUosDEm~1RY}d9-f1g2}2S!w4(Z|18olv9FJvLWjV)m zeW#-vICoJAaSZ`@#guKlXU13A6iAX}qC2sXZg0Y;{!BDy!@yo9ls~>c`w@;?y$X55 z2M17GEV9byVQ7RG&f>*X-u?FmJ{iR0B$`Pir= zd=NaR@bA=llo!k&pR|^t&~VjADm5XXtVZ^|POAvdjma`^|I!a{^I|V&QR?n&m}4xg znJ%2H{)2@36EIjE6soXfWI6{U=RpA!QQvf;w3>i;h?g%>9l;LPO?>e-18oDG2iE@* zU`KTPcWI5q#ouL%(%8rq>U5z!o&>IFU)sMlmmV<{Z>fn1BgH*;Qm>;xh)gqBm<=af zrYYShudt{5lJ1f&>i{+*TX z=2v4FZLeB~NP43;&1BDY@vHhu%`@!j0Ib#PL)acEDlpaWoYBwOF5h!Z=GG9>`br5j z9b#Z^Dn!^y|B~AKfrYLlZN$oZ7itDd*;%MRR0mO_4N@P|WUs)7j&0958Q_3ih-u*` zISNx{m@P$kRqk-AzbzFrR@KV-cO-nMyP=caM5%HyX+w}7yk^44TJy9b`FwMM`5rX( zSdqj*5fsJ+M$;n3g>5C|ChD*OZ7l`;;v{bt;>UK3mE)cNw+PCMpoWYFT`k@XJq9dF zP}&+^x(xxe4t+r-z86L?iz$U}8G!lX&#&nRM-`} zFcDOV>u5|9+LFy+(dNcISioT_v9WC*A~m7SI+Kj}ul%Nzzx1*-8p z)eLqM6|xw%Ov$@r@*U?+Al+w#KED!=lNAJW)mt=p!w*2}A)FXAm1RNy()H@6X!xlG zO109dSk~QUPSA<(<5w5bDos8aN-be$(;xti8q#aJqzcmz3qQFMF(|Z2In;Ar^WQ>H znNDgd@Ga^Dw)WP<1)u4 zE}~!t4uXWMfhvJaG)$n-oC;>%c5QF0D5X4{C098QSM~K;cU9P6AZ6epXGVM>@ zTp2&KKKR+82eD`fWsR`>b74!J^!x-%ja~Dkb}nfjegdfAj-K)2F_gBoo^}UjDAD=7 zz>0o4nBB-p9(?R%X4=;EAxCY)zMY({%I_P%Io$o5b+=_;(8@2djx2X?F z5_xfrBZR0nI>o_RhsDfxV>u-lHT9;l_O`T#(879F%nyn% z?H_D2`kIjOW&zv*Wgi}fG2Rk|+&<0wn;`G}@3H=GB8j6sny~$0`-Dp!+sGFv%{P5t z&iRx*IPzpa%+8ak+AMz4(C$)lNSk{s5k7LJ<`~x~#M@TS0(Vsuj%`?j&)3AAH|uII zm(-y()t9|vnmD+kDOzMu{Kw&Hz9yZe*pD!~(!|^O-&)Q+Xu&&}{h>Wk|J?q^F?N3) znEW`huY4o5p7X~-qoaZ#A7?Vatz|5K4nE*USO=J=W$9{AWx1pPoMK9BC{m zn924Urs)>=d6C?~f{I}EhD7w$wVWTqD_R>oN;{bN^u~cvQi%zSSL>Lp=C0~gdGDn= zpN3UMlh_FM)m9bfs~KoR?Kbx4)R`k?Sc9~x9a2au_wNLSbWgvsz@5uk+lsXhD4E33 zlvks+m3UFoB(h0AUe)Lnl2XoaC$jc3zC2!W!p`9Xb;XbN^o81WiO{QK+>gnrGg{BB zFn4KAFL57{ST{1Y6*s8wriWXFB+TpAxCdRLmUwOanAztBM=`5~z}f+SQ@O*Do=Nu` zAr1U0zgM#A@=@?(mZ|M6!+wWin}O!BmI2M{ats?(0=>hY=oIMc>E~h7BXzQ{U5=dE z3k!aYa5VTO9Y3ap!;SFVho)jy#HuyPgorZ2gOqu)rRQrTVKYTWvucsqWw!|BA2i7# zv;fl+M_Sn(VQJo?r-Vm7Ecz_>3?1?WUS;&W8@)He z>-}l%+A;y6;uMJi>~{{gZp0jZX<2`-dnf1U{ilC_`~IJm}st! zZG5y2UD8*+2--J~DRS{-M8=Q2FhRAp3)3o26B~T#*ah7vIE5_sO0M!C?Dx~a0#M8U zOzVn=w}7KRFZV8NdtABAdcJf5i3PR*xIYs+epSLNbJjmn@YOMqa;B(1ffArA;*p5f zKLIVN(>BI(%k-Zp=>~_*Ws7O!8;@Xc!LOQg+@cvCu0jECFFiBAa?2FN!F;JsZEE8L z>8uFFYkwqt=c`fYhjxB}u_+cnQ$q;HFP-!JtpGw4VW#k*1quIm!(aMWuk^XfVS{@- z#nk6c|HJ`&4>MX{a{ZHs2+0l#1Shu>kMD<+bZak?6X z1OQ>=8i$*?!(YKFkC95o;U?e&D1R9Vzl!POU(JvMX(jL7XU}!2?_PSWV_9!6f`h%=knVY8VTYzIp{<3y_E#67rRR+hdkW z9*lG<058uXBLTb&la|~6j7Q2F%|SM=kA?5bZupVoNt}xX&znF#q3Ltn(h83s11t*s zc;WwnpK4x}DJUEnJQ|&wL*u%{G)v)1KQT84iD^BrS&w0g`zCe+;R4_=@rQy4idqu% z)HrM|5|K;3OzgO6An)^u+Q8Gj1$_NQdQP-!9Cnz}I1%EFLs?Z%>25-bA>@U}aCl!u(n_0_kpwgw#6bsCqD>J#X7Re;ziQ z)~7?)R(h*PyOitG*OFvHu11~nKnC5;=$D#LjpUlOF$MV`{&l^P?%DSaRbndlKKaT` zi{w+`v%+Iwf@wOWPy{trEdC0Gv5+3Kr}|`VU#tS>8KVjVF0I^pSD^U*eT(v|f0#;D z-o0c1s?2b(_YK8D6T3Rg&<9*&pU?9T`0ZgD z^uY7G8~IZ#?1aot=U!zh3Sl;|xpEMY3^n+nrAT+()=Lr93OWx;N z_KnViZ313QY*5M^Iw3H>^)W(>>7U-X@u*jas>H=0F6smJJ+hGK7I@#B6T7UU&RV#c zS0B5e(O;aMBKcxo00BDk8QxbrlTrz}Dt>w|^Z;+dD|?tp*Z(4i8~p{Cw&`cU9v?xE zDVA1nZf&Qd+%7vjTtl0+h*FU@kMC8 z7S+wM3=WPrw7;?t(ABz1eCMahDD6G%yJmYt++2<~4Bz|)yqG;$ofn=HvQfnEa?#x1 z_)5Ouo=*hng7yG&`v*kpge%KLP8M8(vYDSO23sonFD6I}EW8#gA$uu1=I}YNEW55Z zyH<#5=Q0wnBrcg96U)U-H)AFDG|Yx|Pf0<)_xAGPp?RNaJu@(TqAvc7+fvs@r4(^2 zb4Pn&WCg!6VoKfCiSd1mfedgaa2?(Y=F9j)*I?L?&xh6-aOXHT zb(Lm^SBsfY2Ua)Zeh`+Hy&XV+&WrETZxt#aAx5Yy@uKCoH?JMlIZbOrA+-mUouA1T4J#O4;i*k$v{X2*txcgjj{f72cbE8P z1n?UkOuDSX(=Xj<*rXZIrLyxd2rcmoiYbBBGYQf~H}Z z#&?Tu3AF4r)ABOE{=Ue-)q8_A7@N7wd~Xp#_t}wF0%3Hp@+<-&kj;Bsxf=}0oaAz> z%zP9ni8H8*wg_i9zb%yK8zt?nNg_a1>hj#g7W+AGeB#=x`)L$+-n9VX0ACO5Tl1=Y zO?cLlI|BhPD<07F=~B_@vqIg<1MwmML5=ani zS4xsp?_m9>ymK2dHViFk)gzXqB99^~KVEax-bVSE%rb4G=iTTwZL92?oDc3FFMp7T&S}kmmNM0zDN(a9pE87PN!#*fhHDip zHoFKTZ2fjA#f^#3868Lj=ALHGH9qW`#2hMpAFPjU5p*mu3LJ$wAJ_CS)h^JxGD++T z{euw1kRec)|!@T?ZgDXk{T@QwKvc7u;V4(YugP=Jn$@$%pg1X63 z(BvGEcdjuFTk<844C9=$Z)-tsKDBxU=Ys4L{HL}UKkLgW&C#|zuQzA!CX3_X1HTqQ zx{4DV_OK>g147ectYhr+YA9_KQ>d1L9&l|_Ldc8=LXSKIB_~!hpIT~Xk|kPN?kD7J z&xAQsWh70$JG3-LLaLn}-REJu{If63i>Sr|4}=|Kn7gkD}|x$@L|?RM#YlhaU88D#S<7~`?}yUExBvO>stLd`P2OBS zM2_uPB0b#=nZr!uurL`O#`}QBrqj`z8_bK0i%Qyd2qcumL?6tSbdkJ_bCh6PAP5S3 z`yxzWqn0aEHJLUSm2SCM2?1B3a{V8c-WK^*F-VY(LK{($Bn%mT7oZy#noPHe5IsI6 zg?^X8Ax$3xz%WiYHK#+d|4lhfhG%J{ZVVgEkt6)!{zpV?moz_3!8CK+iQ#q)uE2}0 z*j9IBSjlT79QMHB@H$+&LG8@?%q#BN!Ll=4uYZayF63RAZjCAyi7TnfFE1PLIow5D z=qY|))UVo*4n3F~fWr6(B-YY7AMu@kTzIam`2Q82u&^KIkN^9puQC3AOXGWF^$i;} zu^q3Tgu~xJ&xbFBIow3qpOTS?YO;6AV`h&f0Pg`8@HHX_vZ6c3K|8bnK@|MhHJClk z<<2YO*?Fgoci%Ir6KOL-WFA+aH*vewp@nolIJ)J<_T?X`)gQj3MqXpZUKv$1TKQaX zHMSP*g>!sD8iY0oUo#0{Emu!MY3vImLRoN4%BZ=w9pK^jBi@VbsY|&7Rd47v$ zi{A#L&P2WBH8JuPQxM{79#JqH^^>P)>+i*%TrI~iHLH*igc(dV6FfVSwSuV{#LlZ19&$!REZ^vW<-IE{kFR=+E53-j%FCWjx#Dk0abYoFF>IUY z%}kROyvSLQ2a-wii+|U%$#50dYd($tOwnJ|nSqh+Dsx=y$nTYWdTHIT^`&TkMrP(SZ z8RoXWQAnfDYXpKLPsV^Z!@~hWo-nM))2-Po9jf0hFUKf<1mE5zWnpvKdTQ{Hra*$i zZrG^+<*OcRpk^QnC=UCH(ehHhCb8suq>pt+L0u*VpOC1eTD@>O8ugdJyeTA(Dq~Y{ zb0^tXXZzZS9(>1SafG8R>-Je<>4n^`HB9o;% zGI!gOP{z5%PHhw3#_STZPYVwQP_wi3?+cUE$T+fIImm$YB z2#kS;05h-bkZCrF#6>Hfi%_GM93mIr$DPL#UI8Sm_Fclc(3|>PQ!j%e;^|76PK>!u zxh*?_=zJ$K4T3J#C7)y`a<6)$zj^-6OlGUzjJHlF9*Z)1U_28eq&W!0>PG#|ys(lM zts5YWObzz!uOLntH#OIl0d#HK_QP-Grr#09>g}s?Jtcq&BhzA>-oo}kVxJedDbzoCTuH$U2=(s)mxWG}WO?bUa=D9Z>g3*G3t6)eBF$aeFD zVkvHfThgx59eS<)N_}~0^7T0sOc>l@1jH8qwhBCXA!)6w}^K8(8Qht&HUa*YI>YM!#ncaE| zTNjycQ+FD4F%f78mDP*(VZhLM1;k4wR#Wfu%LiMryqXy}?F>B56&!@^=mChUwPkW2 zezs>{%$;{pzuLJc?(I@1``6f{_@#!@oc~~qhwz&L%&(wh*xanCSYUhn>YNnr z=8yEAUObFdsGHuyd_vvpSZj^9a4!tz}KGuE>Kq(#a!Go$O zm+itHeU+`<)Q&Y>*^W{sLuyiCg{Nb&Y%vLd3Zvl{ulipueMzIEMR|O66SDr9$n0(NQNK-avjM$c>%hfZGtzKD zsZ&qZBBohZ#*}zn7A{o;6x00O61!9!EL~)3;w_8B!}J1pEHV-hrJrj^BK$2P#g*CJ z(F(=my}o;Yr?JkMGNg3nC2>SN12-8}`dAJ*+)3P5Vu3Du*<63RS8?8bo!sT zLoMsj(6W!fe_l{%Ms-T*cYoy(50Jg$KQ-0-BQac{orykPsRSP`_SD;7Q zQPks-5fpDyI%SL4Zm_D0O8-ew|2J`=z6o`Sg`EUVZkMVJvA$_8GtRsA0b(6lWzLKk zcbMlz7S|VN^4A`fw#RZt&n+LA8m|syK)hn}zBWgOs*}{sUfex%8$NT`pJF5LTnh{)dZ_A=t#&KYqd#wj$LP+iw8Bn4c*eV?UxHgo>h7Tmh* zK9>}gFz%!b>B1W2(opXxp*%>N@twWGre%2!=`jO zALZA4wLVPi(2XSBGhMG4!r?TawJ~h9 zIrIkR&>qx>F&j2=Jc?^ZoQ6`WS5mWmEakdTCVa-)u2M24X23P36(*P0g}fi!U3)yu zDWT*yo|7&w`!=RR6IF0_6ArdT>-*Bq#Nt|(J|@v0P4kR5IbEAF6I-5_3M+?3?N__obk zMhDUrg}LTm>C)%Sxi8wEy8?T({jmD*3gz}6l+QRFx+?r~gF({)k}y>@i(Kma)WFt% zX(0vqXpyhwPoK5+yOFB;?9=G}mv)8E>ZYu%Yv}IqplDbTbC`eW zm>CIZ(4Zxj=>VSzu6gXbZn^yoWnQnJR@>S>=_-c*NXSg}-1p2e3(9zO;Eq2O<`#b4 zF)PzLVj5!?Ov1@U51<su#&2`O`P< z;Y+IO=5ynlrPF4hUpJzAqQUVf$0$ia3#K-Y*%IjlkJ*N!iK*Xccan7Ke8MkN8`bn% zloUK$-h{gJ-2Yf$X~b25+naQ@TgP?@o$BL`W%d>){}uhg8T|Wvs#(Uaucu*MX!ig{ zm51A$fi-tE*v>PDHp&y^()cC%%*6(ZtrFTYV?V23CF|#Cx1Q6r>|YF|3l9pq)l(7V zAq!8Ez;lQ9 zf@qEG<50Ghz1;q0(%*)9RQnx6)HqA&hLOi+XM@M-w)q^1;rOmkm(UDSnw83Hi`PZ0 zi7kaJlT0~<$FDHC5kz>!n?R5h9B$MwMGcW3peVd1ka?2*Kw(wV`-H~|7xjJYHtVKQK^R=-xtVjgm$sO=V+CBtG%1HscES{WjdKHu#^u%Hjg|aUk!h z&S4m?7gqREl-S2osXX_zf9RBf#hF_6p@65Z|bo%58@2M*rY#Wt2$Hm_^f2n5v z+UFe(2(D1qy3zo;1iw8-V;TRu{EQa@Y#tE>V+IVYrwtBU)jtA@?eXf6NoqDbW*slO zq|a~Svo2D|ec>?r5<__c_69tzL96A%7cDs<^`i{Q%tclZY^=#5a-38?Xsk-MTXsjb z+#}&{qc|5FO#K=nJnRE-P4SuW)WHHbVg*vUq>I)J#y2036rld42xZJd(y6l^=Arjd zKTkc^Uicxy)i`cjJoZ7$7WS-nD*1j5cNmT3C^CZbk7;!&jHc98KAWaw?Yf8xQUKT1 z`-qYWkbe-!JtKQDIxzSy1`DHDdg;#kNOp67!X;k3&DTqJE&Uc=a*X`s{lFI(!CBMD zV?W>Zt#QNP(uBA=#os99iSRIRpa&1f8cHW0pAkW=U+CtF&m^)lC4ci=VOjNp!!0+X z5cPPh0iAZ#3JD0#L+s|5>bqnw$D#|?9-_asmt@5HuP7_r#U;NndqVE6cF(NbC~aqZ zJI>6^Eu;HIZdwDSgxSMrP)=-_Fh*y-vRf>F9Td{v;yO2dx$|P|2Kt!^XKS1FpKDy} z4U1B0cAl#!VE14J^#2Z2PycXre?+Y|lNmkd-mi+aGjb5i{sUs(LzKG4rE*7Kqg0GQ z3;n;o3tdk(so7h9@Q1PWUj9OSp8v~%!sjIJ=*t|dyz1>Ss-jUR^{8pm4g)jpL<0INZ|iRk^Z(*VUOdu(Qw~5Ei4t+ zmbWM`{+CvTI*Q60x1U5eJke@eP#6iMjq3kXuLalG3-m$z+eH!@X}tWqyajCP7~TKA zgTPiy{qUWikjvxOynJ&k^GiSMfL7Px7D)RfxSUHS{S>(t+R@J6{%h(zm-sA0?t<1N zX!ERJXK>=v`timS=%4>Wcn*Katw7!DD_5MtyxwMy0xh#6os^T?s0UrERL#K+84}S~ z@7seke77Rz3SdFwLInCUjGjv8(Q|Kh6IgXk|=Wg)V`o!;fiOCU420{@%Cf0}C;yk?g0 z3`)=ww`K@vQ#Q4I)Z$kC_MqrPpWJ_aCq!+d4Cb22aJo|Kha&~-MvSr_8-c>?=XVr9}FuHGJ0 z(h#Jy$s+(%=ic=m-N z%QxP7g6|O>fE_LY*ppGH&EVH#O>^AW8fTxCpZ8`%c1U{1>aQle%Mv&+#~yEJCJpKm z`_i+uu~ou?(`3C$IrLlFcxf82={`oc2^P3g;$m{+vko(Sm<01~bX{RVp&yuInQ~Jp z-j(Bt?#A#Gs?Rs7B$rkx(}B#&<}^8kaH}<{UMXc+c{7h( zhFxFw2||+uei`V2vj2!DIz}H-!IH~Mp0wxnPQw5u4n=|MF3aY((mlW=yw{_L!aGV? zqaYrkPi9a=#MYzJYIwv}?5|gqdsyUc<;lV6>v?$a%H!3MmMSRmm&ONtA zO#<+*1(&unxUT35a^R~yrg%js94x>|=I6Sv9$zA^QJ~HWpBmi)+Kr@#7!^34H%l(3 zvEIUYE{GsPqgJJ2Ae#XK+wWgRr5k|N%18=LB?)z?T8r@Rumq>ABYLhLtaD7|~lUM2aWv|(Q%iebW69xk`y!p8ZLr*Fe8k7Kbs zzF!riIN!0))tc%6`27j?Lkgr(JZ)L&iG=T|<@-FA_Gevu*dAG?O9WuML}USB<5SwR z>}hZi?fGVd;@A3x3IpA6h4d;&`?;)G^wJ!DMSAE~rkC2AzynMFzx^I(D<^DpBX=k3 zwQL6rNPY@p+8Oj?HC=&Qt^0pLDY!{>p!hDV(l}gky#Gy--m;JZw~P)Yg|-XqWb?ID<%pG4-)sx1nZf9gn+_0Fz(P>s49>{k2h2t=f4@D{fL+JWx@+67b+XeX<^ z6YvMEo7I&%7#hqQGS_cx!XL2yq5yBagVTCcvaLv2Z zF1Q)qMPId$O9$1NYDIqe6m&=ok*ToFzp#x%iD%x0UM1Kg(_EjYId;f_y0=n7r7b~y zpp1`?(BLrw+HcY2vmxa&+k9c|%KO0k!i31=)65mQ)b;dOp-%hHI$IKP%{@wn;;(Jx zC%E?@`wq`BbPFqV>%Lo@lZEllli)3nk6qI01o&PNe)Ym5J_qn~DAB9))uBc^-;w{{ z`av{0ReXUY&%{~AJonjIN;Lf}Q+<~F&~3E`%-7%^yk49UHo56h)LJfW(fyR&u|kw( z=VIxn5f@6bfy~zr=!TI;;hCAO`KZ^~Yat#sJB66@w+>avD3@i^Fs5FdMY)JyL4qV8 z_dP<4F%C|x{KeQJ+0WM*sM(111cGw+94PH#Odvr`*}pKx1LoR664&O8cj>#5XX1Z; zjNL*e?^R#yf~}-i&R2Q5X#J>ea*Uhlw~8CjTZ}eI zATUu25lhV9s%)Zn5t>8!oxHgCfLyvCWa|p%LkFtn8n3Ly-TZm^CmxN)J&4Jx-4to2 zLbSHbcMnuO`49WgkX{`OmFYNbFsLSDbqeKxNO@o@tCcr&@CFJ{w*`A8eKCrX^0|G8 zcXPdNYzq+Mt=~1@zAl*eF`dnJt-1P`VAVMfh3FTHcHhC|awtOvKB2lBK22Z`+gV11 zSfL-yf^ys!#spBgujUIwE*(ZnELr`vO{C#^J6@=H*%0%k?P?|7a&?XqKsWTR2HG5W_i!p>}?EDhf-N^*Hs3htwLz?)7a?g%73 z)v$$GEMe+}$%+@GQ%*_BD0_)XH>quFZf14to#ICu`h$Xf7I{<1N0TF!vRSLrzTk`b za?+Yg&u)D;*dvD&qUGGgZe@Oqj~nt9UF~YG;iw6C<}09T6g?bw%jx4Xym~J`XnKOX z_j;8s+}JmeD)A)HBgeGbYgH!+^B1yqT&6NEi4AbjwJQ&^x)Y4No>ft2JhkWbb2+Yd zrDbARKFyU1Q#}>{P!#VND&=@20#m7BF27MUAQ9sPt-{@`|BN!*S@en4DSE97(LeT| zgEuL&xRJgf*;t0Vor*V+XoV%`bb20*&^U1&`n8AH**Qp%TX(SrIj+zrzrM7a5Qp0i zHM5m15j|pZ@ya{#An!7*Z4W_bhZW*Jfk}W`J%SWOxUrK7?+Ns~$a5=hHJ)>>C?8!2 z6mS=AM|;n`zC42xZ^ubWK!t8omw`p{OAd-DJyUKF+oyl?)nY|lF90~)mSsPgeJ5>vH7v)pw7j!o}hm|jxp z^fE_wKWjE~!+N9^cu15cb1oHm@iDAW(IF7&>sgEj&q=_8Ui{_* z$#S7*Y_>j%qHo!7_Bi7H<6y;6XBF;{HyotiR5+jV-%&(cXY6dUDF(|=i}ChDe;w!w ztqk&qkcygVQc4P>MLY)E_<7g)Q5qU`G8oTSr?h3hFX~2 zIOs%rzjoJVvY%c))12I)Tz;MVljh!lf%U6~%cN#rXMaSq3~$_Py_$PlN}V}U1`^or zP;up5?UNtXC;t4;p3TMj^YpPvt+Wxn8&(G3yt?v(Spv8So?Uk+P32-wSY5H@hVu0A@NM4r!He^D zs;<%5byg zkN`?kSJk0S%Wv&G9isc3HHwRWz}IO%=u1AKV)y=v-ep>JqEEX~acjd3%i}@aBBP>W z9=CF`3Hl#{k^qKn`~rPsp~1kt8mI#r6wP?acrPBF;Qpw%eZCP}*He;s8g1@8kUK3# zGP!_Wd2$s zEqmR0(?k7-XKAu_X8JCy$JUV2woz+BLIPoFjM9)mAsu7=1_BnJH*H})*aT;ZpW6XcV# zT8@)pt83Bwxz6!`2_r)LQl}GQu!TdBBbxTBr zjI5($P~Ftygb1?$Ghq0(p7iv|4W&tiH`?P-VXvER8%=!Kr`001mGXP)hSr$Zz66Ol zXEQ(5=p5+sFi8o~?jOE{;*LMW82Cyn|wApDfY*Q3JHOvDIHb-zl@y z;VStV)RvGo6B3s@Uo8{RMy&46#6j37dzb%CQsl4nMDDe!z0248156mttd3^^m$ppa>*5!O~k5Sk3o}PdQSSJ;U3#F2r_BFoc3# z!Ov;7O7~9DodDjEdP9FhS0AI1>3TfvWjYL|dCIZXo^FZ^i>`UfvOmTUc?k0(Wj!^t zKh`^EzL|sG*D+~lj5>yN@$xs)30wA|?D=Uugl^XAaKzYb$J4S(G9&fbQyN&&Zod7Q zLflDHD}`7gR`w+8xxo{p{_GWN^S%|d@HFtGke1X?8b)wN{U44ah=PRE2AyNDg=e;|PL@9YP)`+CJ-$GF zn>F+(Ya;p97MO~%&A_i&T~T8DOfbVucGLGyuRL9rp00q>y`}W_Ymu1unbv+UhgklI z!g2~PFS;zE+*6H1GKg1%~)~!xL0CPOg1DnUkK#1vW z>nVo^BEQoy4@@6oqMNw(jQa zkh0I89Na%6<0oPlv$?E{j`qr}XVT`Zu(@5#xP8v)4>vN_g-GvwVWX!|idmNZQ!oQY zNDr`w@>9oBwf)K0U$B7xMZ&bP0H5BMdk}GVgu(_A0cRH8O0^@TYv)QSW#doqoU+t} zyaU-S8IDu(rBbRJa~_SDw+nE!;^b(__;) ze9RQ1!I0CEUdWoG9Q^lIcf*rru!>KDrJx5jBf*40xO`JsJ`CmNtVE|I{| zYT%Vk7{4pM_yrs&08+#GRg3}u`lpr^0%qtpWUE?G*0H1z{NO9uvH>{ndoKlu223wQ|ozq}6>1def_n5a&XZ(}sJz=M6d}eaaYX ztcbct`U0lhKi^zK4%XLw+KZ&iK^mW}sTSLVFFi9>^1iPB+6dFfE(iCGT;}9f!e z%z5;`K%~EQ%T?*q1KFK(`lOhm=IwmV-&QX=i=^Qp-L?NB{&ry+!vz&?V3AskR6F?$ z`IjRzO!~JUp7!w$X;Z(O)~=ln>M*L??Hl0L=F@%sS-^3`z&|3nMb$vvjo&j7wDml* z8OZaY;TXxfiWHW5W#&ywLr6nMEZN%{p@HfQ!|eF!+_DRKS%oi@|AVDWQJ4fXiL|pZ zNf>)l>aI67)bxJe60D=F4b5@hYpyM~OQi3hGs7xO-X`9Qbf!?<=eq34F(E=FRFmT9Z;a^9uVT1;zBc$cxga;;D5!VhNb zGGu5LQCi6)I#XR0nR{_p^8upx*R~$@SwR1b>ogg(EMbRav^ZYYy~4}>T}Q-%<$3nc zT`llttM}}O9zEBy@gG&1%2g-a!kVB;jzi4kde`DDPX}!S36V_jV}K;r z_%_ad(;cstml-jwP>?N{80wstD0O~{bc_EoIB!`AC#DKRmbayU_|jvZ<`@hgdAk_c z&6o93&f+@xw1>1k2kAUm*gstOaAyFKGB=b^Pi17vzlxirPule(6E``UwyjP%Skq;8 z^GALCQc}AQJtMP3{}-luC7-!=H*{R5Mnde*RB#^02}<#)J|{5sdR;ITGI{>#rKsdrd&!e)vWV&tpi zP&pVukHz4mp%Vo=Eo}~(6IISC=2UUV`hCtf6`Wr(`)0I(Lc@55{soJ|Fo)aH`r4VB+{uBAMKQS~X|8=>=yN8c%HCv3>S6OsAx!Fu~zw|n$DFzjJ2cj)~QxP#Wo z4Z>5W_NaGdc)gqDFBpF#?*OiAeE7~C)+y}lNqzc@jjy-T4Bd8SZNx2-K=>xCj| z*XCBjocbhkbqslQ_5M2~p#M_FB7OHr`jv3ODa0)L_YcVq4Qao)Ss{RY>U%tv|kesB^}%&Ns4k6RC7{ z0U(g_-QZg7pn5zXiF;}?QTaH;HuSU76wXkp>5osiGKS_-P1_n(`QkdVQH-R2IoLmP z0J)`l`I>*c^y$e6Yo95VtXPe>@xdx7Ur(n_@7jE3Q`+<0NLK1&0nFVtrL|AqxTfxK zX3;=^E+~stj=v&xGw6oBld;4fwIPi=;lf2;ged*kU%sEMNw{*70F3U_8iPAH-1%17kdN-$Np8CL^rQojcGc~QRx#!jSbXlyrpq#HR zH0s}HMh~(i0s@2z*YrZGGXKZ;!UqALpX!RN54bTh6>1fG2H>)q$cJ8va*}QZtS`cg z>I+c}JN@$WYZ&OKRH`x(liT(&O8DO3lNrC{Z#xChctS{9@Y3|l#IN?9EpjY0A+wBI zLt(Zp4^-wV*pq#yYOA_YGtx61bLWe_8dDScBz{44jhiw!YEfm3*%1I>V1qhQjxt&32j$)L;ZA$9Q;`}8 zjBTu*2LnnQ6die6rkp}km9}X=gF70It&&tdC~7)=etEBBtB`+Dn5)u%hQ@Q^2qX$8 zP8Chae<>zyztO#!I#vsiPio??D({b)aG3kO&l>p!caJpi z%0cF{rs5xb``>nO2)O~aa_!Pa#tZk`4W^J7pjHOxf&~X%-*vjr4``^3iTNe!nWzq(n3oVX*TPc7%O;2b|$UyepswLg4Rgb?Fqq z^tc~v_GCxXxi2-<2v&=kJ&p-*#U_92Nwk|a5wI@h_e!_92hpfFZ=6n;5CLc%gR*lB zr#0aAWXkYEN%2~G;5Hk(1qcPPIsFq{UZ(L1an+j<9`o`*JW`}ij5UjK>aEpJ zucB&=`r}1!$1_x9@;lqCjiWM_6xoFrRXy@3l8(!UixDhV>mj;9YKJ6p0p&cI&;e8h7AB ze772$$M6T;FJ^`7BJP;mqs>AQ`%}ErMZh#bEBs*=-`6-s-Yqb_x4Eznqh%Eq_#>^v0I*R-&hOlWAvQJ1VKpWpvO?k-gn5w@Ku6#1giV0E;y_izZIIPJcaMHX zG?#eGW4lN|ZFq-BEgkPn#_L%lv#uyndyG2?nOptwXm*8x?zEkePP2XLOXo%i2n3#R zC+=Ls?YR2d<8kaaX~@p{y!PT-Qe7WP^C+<+)(zOu>D%;49shI9-|nkpw__P4x32@zP24Hx{BAi2WcJU%1>rVRNeTNlrnb#5f{73Ha86|Ec#CM~!ly;(K^8 zA_?4EU?!qvBT-~uFG{KL+4;^S>o>z2c_}LVR_1Wh#n|Gz??r|13p#R?Mxo8#D!2Ym z;+3ct*vfW}p|+j^3*RqfL%Zf)Icv0BD{c+ecQ@9;UbQT?v((pWS27NXo*xFacYqlr z-^|v;Vm z@yWt{9XMqTm+LtgCcsSZ8v}KjXORDuyh!@b(aTr87P=u5LjeF2&-CE)W^f0=fWns3 zIuFx%2mBhg4yL08Brujgvqee&T4STCKpcQ;aWTC4Hy+>!5pi!WbJu&b%#n)3fr0nY z7`KQ9(Qta=mv^Dond^ridlS$DcDLF27={ z2c?-({DQ;$%##;dD1Wqd#K!v}kqdvL)EB);%Oh-HWc|HS+H~Mlq~euY8_MnNB%>H| z&_)x!R1^<(2xp(AlmIOlK=v|Jl=DU@c{MXWONV=3m0~zT2?XFWlBt6Gy@PH~QLF93 zC^fqH`@t2Sts4`MNr%$Y zh)cc9AZL>!fG(j7LDM%r%_Y?%#4ey6$JQQst$-D#Iy}uwvJBG|H~KU?TSId_;2}aH z^?Nt&uMXkf(CZ=nuaLkv<9n~5>!KwHW2lj7-d09{9V$lDJS%P2%GizrQi)67F*R?}|lND1ZAk1pImDz$qW& zn*Ic*#La@|*qZqP9RM9mbWCi&E9IjCXxjdy^zYjq<@CZ0_(Q`Rn1sz5-#m;a>9`cv zT^-qJZ{V#s3}C3AcMiYlow>82eBB57E(p zjI~W;L~;U*^*%1mi9fR){g^H^R2H?JYTr!E*BktDTHOx6_tq3RqvDKUn_4UD!}gYKBW0^qj|nBp^fwZbv@NKni6CNQiG_x#5=+(1tit;_KhaAhBB{!y7I zwBtWsvFRS$*B2XW z`3WXI9Qpj1IgB;u3n(rtv4xY)-TV4dh^@Q#Zby5R3DPgis~0RQpS6Ge1W7{L!5fai z+H%wKWi#dY1=#Lg|JPvUiF|gr?%%OteP?EuJR}o!`nV#Xx=~i430S9D`SNrRia5TY zRwWvJW|BxDDzN)Qtk>q%Uv|GE74sN@5X}m?gR7vNyG|faQQw5I^ zKy3i|qUv|QtF=P1#mLbxT`BE z#x*}bHy>X4BtNr4V}}~%q(djokOc1=MLC5;B9BmtievQ`iH{CjIW%8a9ZnOO2~;Cn z1^fd7u5+S`=<}QuLS;`bZ&hB3JnpCo2dUL4`iHPcJ0q`Ho|!W*tKR|AfJ|@>ZOKTv z+USHMJrkJeQht<+5c^YqAL-9-_SdK$^)z&=3`FcA>@5;cKuKz0{7xPdn5`e!81im*sFvw|(3zQ% zVzsMOG8k<;5BqmUv?qwBjNtv~S_vNPN!<1E@ zI$+KeCtt@La`L4RSf?6UFr5wAQv&4xn?WXouH2zn0g)4PeG`VnZ!1I*-sR1=L}M869}u|t8^Ybis7t5 z=*J!!@BmhSQy?AFfhZpZvx#g;Q`#||{s*{5I%HVmu|}!-A{JrV+1~R~iIng!GyuD9 zI*}OpLoy9CRrCanb~?@I@cFoUDVRAHjCoouZ+|w(re!A%gC`?l8jR%wlX%Dr8`CfQ zo3!R0yJ}vhWD8jPvFqcruP&A|Bea4JO>MbzW6xt8_b@8Wcp<)u>7$+X)5^;=$W1tL zd8{a6Mn9DLQHiZ3w=-C`YNyz4CyXa($WwPghiaI@VF9q=a8d`5it9Xgv?#Ss9f6vo zgVTVUdt9KJ0XHvJuKO+%>48oRCt~;de@jbp<3Zz`B-(?#k)TGtC#UoI%iB^q`_1o@ zNBR7oF~otP4pppa7u&~`CRS9Fv{&og6|7UlkNij!iD%|gHf>!N+e0bRZh6nxw*ejr ziA8G`NH|365yJm z0h(*vF73!4C&7;kJmK*l|4wc}Wr_kuDh=Mc7zyx2Oim93*2$r1u7Aeu0R7;`PMwj1 z2#H*h&xzzvsCQ7@AgaDTgc6N<_0klYjs;wAF%rAg;=j&q1s4hsp2J|g4`A=W1E$MP&;==mbjmIf^!fhMJ5D0!HNn!WZ+`z4o#%dKr~@P?IwR%#h_HOaaj z_4k@vPh{M?ChtQoH6RRVfSEj%h3=QMAIz2h6GjQYtH1o}L&k5RnQ^5(*9X5TY4Fd0 zGpu~PuZDJX1-qwxSj_Q*i}ze1^kX3HLgaR36-3I~gv{^*a9haUROKEm+Y&@n{^|7x z4gG^}yqsjAhbm&p+eOcZ(n7LLLj`ykU9qf^JvSRlZvi8fd@lD}CLSrv6NA*pFAFPj z^(^m24sqfePpNSkL&_wFP0^ia_VS$Bm56J8hbe3S`WQ6JUx4*_F4^7!7ohtxxbk-A zZlO8o>*xhb)6P@=wX3-x5pq|M1YUg){&Dhy+7 z200IVe~6P%H`WKN%DtJH{{gE5QPg!#^=ApW!7`09jYN_odNMobwXuK z+Fw4OGd>IFGmI|Xvn1gPXr>roT1cxltQY0J{^v7H;0)g3rmp(iGlVRel&xBANKzD2 zM(xan1$-QhHV4sm;`#exG~{iKIJp_0_xU;VUL-ttOQ7vS`)-atJ^7U+S8#hkqPewz ziZAGqWij4M+&soTV#NhOj}X*3wBce(f}H8!s&fw^T>v3rIRu_2%z8MI1V-ZO(Y6Qh zq3p8Y3T}?tBaBf%{^fn`Wg$)Ys7gCr< zvILtXb@$Fdc>7%9QE%1Z=?zOnx#lEf7R%p!cNcH#ji4sR-G9KW3g2Zuo)`FB%`2y! zzRQ3MtIkKHtAnG3RK(v7|MGl;`0_~}4zjPAPG9{)I|N8tEY!a%Ey3nub8}{5Vaj_O zt{4MtC=nRxO583vK~i7S_ogWUkmS2fDAqpb402@jfru+ zMWl#Eh6tJ95B;elJOB2VS{%&x9(jC~ZY5*z=+n9a%1S|;@T0B8f83w&i|=quh*@>5 z;kE)VoQRkZ8b-yN7NFghFRKCKR>A%4B)=-!Omj37>gXWtUt13JB9fU`9f(kvH4tzs zrz%U(&icj%o`)PTMerPGCjYLZ+T*4 z*>(cE$J3K8#BMoIN%}Rufkh7Y^|kFpdZ&I@ zYF}h{tRQtAzR_WiQqs^&T>jGhjvwy9r^HfpQYyPQHF3(Hdm%vO3^U;T^qf{PQ1%SC z{EWQFr15(7s)0c>< zc_qdAXlw%`mJ~gDiWVi6xu!BMX-kB8%D>j}T41aO-0&2&;bwG&y_42m<-MiL@Ue9g z0&Z+reZ_r&Mg@q;J@_7sKRFG0Gq%xQJnf5Uh>qA;2{NC$Fb3)`+7=_+xel`0Zll_g z!@ZgGd{`2O9STeL;P%->t_X+jeZMYJr?;H#swL<#eaiddR;4KU-^01bqLfOlif`^} z8IdOvqMuUvuJqm4&GC8Q>n3Hix&q}nFRQas>s#;jtFKysR#5?Qy6t{j5WXit?{2FS ztj{Xkep6k|&Zvld8Kq1C*6;vk;!f-yExJ+b`;$)1(WK`5L%(^;q;2w#>Wi1^C>}p$ zsB(7=i)-Qv!Eu?mL6?IQ%!HI?A6{A58KJ5*>dsBFeXM#^c< zW5zFMmy(ysBuyET+7x?3;C|s0>pz_xSZp`Du!fesy2+I_AEBui4mix-pbUM(J~_kS zstFd2V^1#xX@V_7v(TT6TH?SOUSd$b?R%CX^pp}D5Np_;4t!xLhY_$>y4{a8?k)w; z-e^Epb`5J2C@P}K97ro!UG-nZ*O9P{jpz>I0Fm}HPxD*w-kp$m2P3W@s>)$g6ZBfl zB>g%XY|T}~neLeQGM03ViBW&XFourrnYrowI=;Mme7(u*9S#mQ#DW7cldukIc#}Uu zu$?kyTzPP_b05Q8pX$etopdeD?8`Sm%8@b~C`AU;rIkyY=|mxFr_~$*_n;2AhX;Ef za)j@jsBC9Hi)~ByesUqweP{D)k!J{QyM{)YRIomKaXel#WG z0_Z2oP{KEAF{M$p^Ed@a(dy0SzZP4jz-|tZY!SC$X9@8S@*b`ekGM(TdvPJuH1em9izA$fn2c9RmuQR&hB3(_zdC)cbH)t&~Z^kiaxplUaFElfbWr ziLCJ|kg33ZLDvx;5wLK^4g{4<`-TP;wH6|`#8NiqyrZZSbH~t~MD5#K%`@!k{K-69 zD(g-2Rq|6Ff`cYxuQH=jzC_X2`Bjf;pf~X=KzXR28T&fi>m*TK`6q>gKx8rKDl(ZB zv}X#ayPC(bmt-o$Sn*L1GcwMi%wi)E1N-Na+mRjI*g1mX#^V6dWUlBl@EVSPaMq%7 zLS1SDqmFq;9;!szKp|fv>g4PK#iYiamD5cE$8?ur5{xcCGIE zrIXyet3j!Fw3|_CQNmAfGZ}h0O0A{7gzWM-6H~NJnLn|?UCYNd{4u)LTwQW&XCvm# z3|%1wwxIqWx^{h}B zu&;OwjI^KfClak|=5Mof>dNv>`Cn38tEWv9F5I7%7$UblqBa}=G>3VJMUd58f4>G+%P>{*oFT=zcnL`^=;-q zl~5qh6psoTKd%U>kAG1=ffxUw$B&Wp^H5dzr!GTltm658Q!SMYU6^p^m^Wc$s)4!h z{MWKM@IM=9!UZbu4P!$+3hl*GEvN1E$CqQ@5_yk6;TbKkfO0M0bkt(;u4-O|!-Zqn zC=jW4{G1W?F{1eUcCL;$i0WQ?X3j6 ziCA*_LT11}XWv?CZ?$&mXwENRL4D=JuU-c=%2O-eeT+3aBX`@p?|qnsF~>4=ooF|K zjJP$0zVqS!R8)64m!PK?0o-6u{}DEU_uN=q=nd#kQ6!D75AvBK(jJ0lw%3@Vb-quw zN3F8f=s}TJ=9eaj{gB2d>gczU3&rkEaWwZGNHDPm?O_yq3&^+;i&0(+2(t=p>9e3R z@O3a%MOf*&WE%%$*H@OBMybR67{oiDR;bn<3(KVq$c|5)e!Nj+ud4_=d(|c!uV>%k z1Dje8E&1z}WM$MRcrv}J`nnGVirZ$VGx@xPhQ|mx&-=XLr`HSfTYcVluF#Bi#=I#a z)6R6Gy1l6~uu!|~f7lRC7JSwXC1$U@gGp~48}{Tv+fV^AQM59nu#!9C^CYozKExEuM| zx8g!2+#HKn&J#XLDW{e_?TGe6?8-cZf?EowT#?lrf zYBZj^oibYT8T#{}P&D0)oz4MIn(e#nYk|C~R$T7U3`Sb(7(*N#uf|GqnX1xq^7Oh( z2M^49Z}FV@kwhY*p;T<`svgys#UarBhVwt-Mfc1)wUYQLXHx|wOBZ)R_%WNPh(_hc z`i%0JzS<^Q^eO#032tn~o2ZFMOiV}0SimIgBG)XN@03QDW@B|-Dea@`T-sda*oyM* zLJ_HxXFs3WpH4RGkF&bbpWw@BqiOV5?37`wVC`LF@n%~0 z;FVJ)iWDzwJyw+g3l~26(9l26LMPjV;H`CE-tr5spTj6E*W%o8+*!usEZo-dNO;ff zGa^HB3graN>lCO>d2WBnLNDbOuO5VI7$}(a^>DvxHbD-($5chz-)Jp!is*2Nw5cohx^jBomR|or&G6L|B1P zR6$lM$1`GJuK-cC(34X*=7_kA+^-d<$KOM`SIJfSx^P5P(IoeSZ|_m&*S_B#zSk*f zozJ#=t&A3>&w1?^Jr;RN+K%NWz}r*`p1Fgf@j7$g|4vl2Kdoqzv@Z9*|8RHs?Vo&lpbLr{35+`w#di8Wps1S7OS%4d)dpkrj6iddNGWB|Nad~<`l<#o5e}O^dWbqo zM;mg-@q!n-i$agyzJSPf*3_K9&@L}|j~w$4kIE|x2~0QT2&+uwtgM^VZngluccY;| zp}wIgC(yW;-pq+Zm|JvSvXCFnZ5rp?vcB2wZ4=FB4sZdCY+N5$u6)a`2x_!61|P(X zL2|&lw{1W{np9$tGe42ChrEjc+oRzKF|b)Zhb_7t0mPlZ5-pnINFHezjmrMO&Tl~5 z)u7LUoNj!$yRfbEw!jDVWjcY~*U>`GVw@*ag_-&Auz{!!0f3Ebbfki_I(wf9`29wC z#EOe7pZOT!je)Rlw=`oYjmmwctuE}%taC4xd;ZCdUYh{>Ibm(|!e3*yT*RChLCfm| zNF56~*TyKh854FFE_0xn!i^TL@AbuaXw_dSQ57-7@ZemH87E4r#6GM0kombf0xEdI z2`uo=P9pen1j*mSNTlpEAnEgCodT&e$1k&TwRe^zCT@3SwmIG;&Dul9?@GM9f4&Bs zoWcSR*94T^O0eMVkj)xtx^ug$U=KfDCAtM@I}p`lxH5H;_|Yr)#}a0nBCg$ncOHPf z^t&FxnrU_O)1q?Ap-w?gDBM7!*SZ@9Q(N)-Z|ljb3j$P6QWP$@hiL#pyRMxKq^amT zX;BI!;K^=x_^29a-d^`fnbmRhicAxo7XLBobGW&2AQF9u6CQZGq)h!)%Ijm|eq3u1 zITq_=GX6D2qo1)b?=q#1HU-mKhR5#gp%v$Rgy_Z@tcNdRjqFfG*JWSx@Lk;@zO%L9 zyFd+E5tO@(IX*D)Xbr`mM%L`QFWU$oqn+PA!`D??3$nHU8eU_M6Ae~|Ui5~#VtURLr;m?D zY{;#1L0_Bp4)X@@Z7Yek(JDU_Ox-VSLsuPJ>Fi~7GpGI^?!G&o>h_OY3Kf#lF(WPH z5ZOB`4I`NcnduOP?2J=(j*&7_4x&g_$SAAq$j+9%_nyZ&&)2aI(cS&KpFf`0^N0VO z>w8_F@&3%~`m`QXKgX(mD%5?m%+bxl4|iX6=~mdV17O+-tJ5&WC-q&;?H(U4o&p++ zy`Rwd`y(07vGz{WFj1?%^FOrkFn(J5V|Bfgw)>PtnQT##%Z`kMHV(5;%vJeaKo zwWea=TJ>vShr$p|rlYtun$)sb|Dhhx-eDp}`iXL>zKM9Cl>Fsm*DZ5Yeo+0?M_bmM z^f%{hslumZGvAUI>1&_2Q$^>etd_tDUOk?gA_|Mr;<+#vh8&if6En{?=_w6|EzWr~ zAcXHfW^#Uo%kYE*8m0EVKI|T0vrpF5`aKA52AQ>| zPpi>iE$VZ0l#Obt(3~$VX@x z*%bjB2Zi7CbGwX(Ce16(?{iHB(cHfBJK+VSimVA=_d7tTUtJ`&pLxwheT`qLkvgav zDE(IES(n=<0eL}EH@9s57OKqfZ)Mgurc(Rge`?i$q@fh)8EFg~NO|UjcD~@h=8?EH zQuD^s9?D8_=>2Y@zciYQq)E-FSvp`40lNDYR4NYRH1Fdsc|4k~6b#ik8R9ctQHr4&&Sf_QPScozbCSq3;7jBO)Ts z4Lt8Q>+cyEDMv|vD{0#Fm5S8U-ulhBG(I@W6OkccEZ)Lb^Hu7}QON1Q)w+D;`SF0x z57Qr!Un{QW0r@N0WGJ$?Mf@S9*~kGFo`#H+%OOHb&ZIt{hC9<7*9Jie?Q{jiM~G>H z>J$y^Zp-eMLeZ@t`PC=XJ4<~}<`ZR^F zCDDU#C(}9Yi=#nAZJr89J?vSh%{c5h(1Hw&c|!N4@pN#Y2+oa{0;<=kTSl?a_7w|T z{il{Hmut?)1>Bfbj;LQ-W!&qmR5z6u?m2p00sgmn4iIaieozC_x0tmOkU&toh%R$}mvL?)dU@Q(MPicF3>0+N$P{bqFQZ_NSc!H1?1^UfF)$U(XtzW@t9r z=F_*>nht$T>zP&(9eokZq;Ux+e%t%PW$Fh&SIPx zGrXJ{{ST7mX(ecY8)#`!YL)F(&@b2^Dm@~l3O5=t^Y zGxuf6^hN%$3*KT?9lcUFyeymoUo(fLizppDEcGfm=%4`R`u=Z_c1K<6arV=d6^*v~ zkm3`Ow*{{d-sCmn?tA}HSMfmR$-IEG)cKNq`gfP^v`}{OJyN&bju!6WmxN~ExUTeD zMQefyp_Gbt=khg-4$`|3Jc-Cra;9Swi0Leu%P65bSDK_$-Ka%Eg1hDaxUB5=FQ-2u z^OBR|0cB&WhHwRDoKj^mYrTnM#@!?74T6o0QWr&31siy!0qIl`9>4sZ1pp5-rO+|V zgsisTj#kk2)eO@6Iy>&@D1bj#mRj7c_ECWeU-TaMQGaT_llrWeea_&ELZcsvY|US= zwQF}dyfVfdqPK2&$o0xJ3>l0mTa_(yWi;p!@n^XyzJZ#af! zeYaPn_rOHX@dtL$?iFKS)LquLkGd{Axfjod69Xr+<>O10b`ejTo;WovIdx*mxmpC` z$jYWF&K{%L?!V>9Jg*S*P{+E>auJz2U(ulQ;Np=~5XSk^@JxKza;uM!qd|f$5U(LJ z9E|!7RCp-tb}CwX(``dy0Yu}pk=ttzr3T#c)sc#h=0BeGqfR{JLvrF zO(xrX&63Ht#xR`yvJI zX2&cP7k#%mxqj66J7y=-4b?{NX9*L61lmsRNPue0t$V)~3I^v+r?{fQCxnyGK2XH{IHva_N%iyd#7$ zs!Ys>KUMlieRv1+kI*;`zZVRh=O_$8-Llxx#_OCSZ$<#@F$2Z>M>|A9ON( z$Rs2*SarHx!tkfgwJ;K=>Db!VYrJKo?q;vfLCPeW(0zM;Xz`At&&UD$xiQ7LgT)3a zB0<|czp-&@x30jmI)sRL4x*SKB|8%HyL0UmV{L7dwizc?L7s!j&mxUOZ=dLVHYzA+ zV3*+C^kUH|far=aZ?m>{qRDkE%f79l)8;(du4Rz?4XSGzZWM!Y$Hk1#!DCy}e!R+7 z>ng1=@XZ|*IRNhrX6~ZjQdFWBZym~6qtT7vFVfXh?qK8-6iH4|gVXew;(bA*)zfCa zy?7qQ3hOYr=n{F~S>i`}cGL`|%!vaZg2u!3CLz?62f)$RdQBCt748?iOLOWuMwqX) zk!^&Bs2m-}2iK0JRW71*$NLUEsR0Ta$oOO9(T4F^@ z>jF1?DICmKrgn!rW7wSYk7r(CRU8AO_-2N0u8H(j&7Q*=cb5Y=E_&M#-GHjmMe3Z` z%s^nhd9wLv#5R6(9ywr7ec^b!Z5mS=;(&V#t)grao-6UaDu};Ap$wQNS+d9Z$1Q%m zOAeRpeyC{9)lX#kggu16+Osz<^m{HEXj2L1CsZ%*()E}C=Z7}fH ztqs*+TF=1vBxc0OKF>lu*qnUv&QdECzV% z>{f??SqK6)u zhKk#|+1y0kg411*3HxD?d*DpYft%SmOjzOX_6rEX$Yr^D2yzz2O7env9Vot}{!kXt z;&ULCcJreAcy@~YVyK2ezSinuAOz3pokf7h;lt~d~i zo4xdV1;C}o)pSTUWq)qYra9kfFcS8 zu)jB~I(*X-G;(f=;L8v=6akp)^~qV7TY5v|>J*;&UOz{S5uIXFpqYda^wyDp_f*6@ zB-u6|v`9xz_m8*hIpDEAk!u4|A7a<@FJG6^@l}ewsrHQKu^iXP#2p}?Hv$B=YeUDf z?6Noty}xE-f8-RUTeiLH;Uwp{CMej{-$lXW8rb&3`G?#V>p8GC~y2RC_Qu%HZ( z)Dr+K@7m?oan^BZGiuYsrR7c8$slSm4jgCq?Qv>oz{7Td+|hBpHUzgq`WD%H(&ogqfqSuEb1&b^79C*@ znMri3M{~!xJ|uIm*9WRCj#$Hw#^x)?+`nN<$xc#W<}Cwzj=17oTq-{Y2DFYzBZ#<GHS-=znRX|W z(sNXG`-X+nV3NpGy-sH)^~`v61|V?zy>81EZ13xKwYiRY2lK;OC1~}&+l#ozKbpQf zI;zX$P;gQ-nSIjV7I-a53D%x>ljiQ*yMTG#ac5!e9lzM;itWU8|KaB|m0>X6FK*jt zc{qveEcJ1q8uu5xwY~hjp8V)mO-f;{m#s7l7&iVP*F=Z$2*<6I6ie)4>gs(p|5Gf$ z^xyr@KW)pTuk~~)^koCjr2M1k%iKb7*y6ofm;DWa`d3Rx*Cc{Al;?k2;MUx6>Q7qY z+Y)zc-J-yocYh&)A;E89XtKEYg=rNuzV-e!s~#Zs3I1+|)cU~pqJqC8M#9xw!z@0? zU{@{Nuq@Hd>WA!FV=mLQ=3i)4!`Za(PXHlT!S~c9Srt^*P+Za;r#}A~d7h>nj!Y^+e8f2Y4sw zF-oT$;RRIxti@U>>L9%f#S<>>y?1!?rSVDAOOl9d0~dh#X}~J zGr~teKfTyNGn0=+ZZ*ur>%Qm?6GwaaMf`qQU~2oJ+dxw83DAmTbQm=ohDObcpckit zEkSd+u$AH{eB3O!>3(7V$LF{}-w(huM`#vk_V0rN_d^fTj}g~5?!jR@1YYH-f^tzO z_9p(0JD&V6ssdp(VPLh^cYO&*!`!O6i=3aT2H>F)z>x zeigZ~`p4qEZfo-he#_0^HcckF7yS*Yk8y@wX}G0OVPaLsc)IHfRqu^u;|?bZ7YS3#K7yu`~6zI_TO^OUY<8 zBeNd5&IHW5PwMm3oH?H&Bn?lYjFg`Xz#D~)HE%kEumkY{pe@vKNjkna_P_|KCkOPB zEx&#zvpoOCFW2~dO@5d-of_Z?0!^mc&}S$XU<5a*fIA02q1wDWl-}j&Jid`}V|UH& zcAr{AOG|{NjhOia-;&@KH8^!2O;roPb1SPLZ$-Y#{>lS_AL!E6GuC7dP_wyyGSW>! z7Gm99kduIiI&w~Z+t4Ahf@vLz0woH4v!{giwa( zYz7K3qL4}Yrv+7uKTgVY1xR(-MQcU`#I}Cj(f%sb zkI>QH-t0qah9uO?FwAt3bbS9YuT6~Ag?6H;(&xz=fb!GoZI1^NFw}HdD;L0IIQ6ah z#~x_l6>Ej|j@!jRpX2@)l|qe`T~dYZFV+Fz4_{V=KFR&eJNwxQxK-nXC8t0Hucd{O z>k~q0m5RT>sp3>kc}9hQX8zy+wf%!5j;E_>l*GLB5rt?u00p?TiM@vnH$~PN`--o( z+%ULGEo6Xh_4dhGiVduc@3?r`melcM(!`C97d#q(eB`2|d>Iz3TiSqufs_~3y~uQg zBnH9B@da;vIZ?BTXk)3-2n-$f)mLSNx^0Lt_qLnh3mFw%=$!nK7W7n?0NP3sm^;)! z@h<=1H=UB)M$<|X{YC$*tEl3DZnmHTS1I~SYvuv{LZeAsJJa306G5OU8 z*>jHgTSnxICnih*e2hCE-HK*8*X@M)o#RHE@A`I|3&6GSywEWlbUqvzkMvGB^l>h{ zfFW&Qh|jR1-(t%AKEp5jFx)NWQbwBNep#DXPY9qGW!xJxA!0iXjI&77R6w=)cA$|6SDXsk+9VY_WpNek5P+Bo;1V??a!%^pa9U#HqH0OTO4bAT_ z5_l#n^-Pdjb8UwmgKYsj) zbAYZ1Ol}Rz3ZL>dvd6*N`r>l`ff+3^Of&=dC71Tzwk-nBXsPkaGY$blktZUn6p*kAVG0v6uF@ebq5t^&$Izi(7jTV~ErCT{C_<<+Ta z#iVfy;&hX+L4n{736c(1*geLFJdfp=ZqB?O?+JtS)1D@#?32>{gs78xmpkcBSM(rg zY2Uy64#^-mC+DOc=R@_!gT9?IkEyF58Q+CIf0YA;IMFfKsCU@IthJ5}6R5?}!QYQt z+;J>LdUYbXrwDu_B8B>~&Bi)6JYMU;>7@E60apcGrsKYdau=ts|ATneK**+`hw%@u zNQ{AN+^L#6{Dt#GQs0ARmk06Ug{8wDK0fy8_BG*L;uRf%{(er-eYN^EcWUcp0{zqJF zOds$}kV;r4OnLS4+uSnmD4|%M`<<#?hf)3QImngDr*c$33af1ahRW^V8^k4`W(slp zOGaIIDCuS>^W%S)wSq!qV)}_gYWHNDLB~0cY)&F}mAexj<9{%Tq{*Sk0#p z(z6y)!(r%3bcZ?Nt9t-Zg7Eg#j@A6^0N63z_hLcsE=Rl-7r9_fwc-opZ0=&4`M#3# z^;<&#_~ADubNv?e8RM#SRk z`=vn9A7}j|r-3R{DE^*64Rjdr4b~n;%Q8_FC~d7|P$zI+S_A^|>ii4}!GkS*vT zCoPccV{~e0_yf_SQ{xj3w-#;?3q)CvbUqgJ0^FOf1Lq1ftm2w}KJs||WKY2Yj)fgZ zdDI=%8_0E8GgcW#$HC2suVoWPBd;2oE7bXUke-tR#$`2o?-*??JAwbXq6oU6MNvnc)c*|4sMy{CSE^Qb{)^iRvM<2mQ6}({m6;8Rc zid|rrFizDoI0_HM*|hzMCk%RY2Eij4Gc+h;ijJ>Snet+-xPRajJuTiY!s3?etcW`F z;B_Ca$o%n^i{N+igM`;Bp9y&Vyf9(~Qa8FK-3ED|bTs`>QoW5_8$iMQwHWUm*GGA( zXKa=ERr^1FKPdWHiQ*(hvq$Tzp7Z(A_rL|-djj%m=|p}@o;EPN>jKglUwN*#;l(AL ziZ}BF=o`17q%BUZLO=KkUr#Tfi4l0})btPV_5=n%9I+$N4ew0FsSWTqGzQ6+@V~u! z>~Ydk5=#1%mHq+2zg}qCgn1G@56r2DTvs=>h3GqD6!O?Y5AhJ#C4&n6vugwh)^HOBz-%PI3DW;wbYsundp>G1rMcGbD5l|?O&^~& zkMHaz@zUHt=JGFl#Xt_Al1bi52@rhl51>OhiIorF)D4i30VY|Ntk#-|j9cklRlT$6 zvs?SczxC1d>NEhWPT_r8dGgMoG3RX>5R$dh{;gapBWpXNa#grMj)&~0@PSBLqa^nR zUs&dTyOK1tezf1+mMYrUzBJtMu=6K#Q%O(^G!#8^-)LXU2?5ZH_qPYwNQjxyzdQG_ zR9I=bjp}S|uKaL+!qevYN6*i8uiA2N}vbz-sXD; z_^rE51+H&N$S$Lf($5kf0nZ(bO(IT@w4qSLD@G3rq#bOUGl3mbO`CgDKn?u-^xw+j zh8vmj5H9YVN}YujfdB|KsUn=+>dZwBGbOJnQMZfP{2zx z`{NK-_h0^ROPxTgihO%B3u-{xN@7ZlzeP&M_g}(WF3WHrh&Nx=N`H)d&fqx9&uE-8 zn^Auw6`=`B!s7dgo4W?RX~0d{`{7Z+75HoK>=XeP9gCf2B4$ABKM!otW>Ep?@=qdR zSu^E3*;DWKIfM8oXKj=A#_Moq&ouqpPP@JOTC$ntn=K}TB?74%>0M);rsn3)89shK zSf?QvlpJKyeSc_+!&9@fL1&~8k_14}=Ev8fled6Oh(5Nm-!(Go@8ZA0Z^gYnKpc1x z=q>rXbdNXZ*)DCQbFcn_{LH1cWWrQgfn<2ezh0q4Wj6Z6Waa0J(QCfnju_VX{-}mV z@zvrDngS2hI{!{lYBe|v8J5njQ^y(~tI**0G2;=OwDx(TVc%$C5NK#kvr ztym(%N(H9MZf;;DRv4MZp7z|T)&Mc>jS+>OQ)MU7)c)lEnw^5Lia6a6`af43<2!bOR5D4KiV4P%CtPOx#&8Uvaf zMLucBub@L5N_zWqNd9hBE9CTiWta%8J4j-+4gkE?gdIQ&I`QC9&VjhEJEs76T>*Wo z2X)?j;7jz8{3AHUJ={$-*<%5bqI4lghkOg$S@dg?Uy=w{iowP|3HgR2ft6YE)kfgG z#vNywXgJ0k3$q02{`-yO0U@u^lQ;Zui9N(ykRCNTG#}hfX0{(&<Sm!Xf&R*)aJ= z{Be>An8P&Gqc<_Pyz|86#fX?N6S4!nHw^FpApI6o`{KTckFjs59Kn=ir)}CWf6>+Q z`W?b9XaxP1E+Omi_M<{g#-jOILPqC;&+WhLS7Bw!A|nIUuN{&A#lnV9V(3uGzIp^+ zgbOczis1=+5WUY=V}3fC6PQrHlhioBqE2=M{4mM+R`JQteL7jMagMZIkJ2sP*8-+9 ziR3I<@LT-;#oQmtk{aX}<~I@U?Dcb}A{Uukf#{7Ce1AO6kK)T}pfNvdcNo`t@qQR) zS1)3fKi7kJ=EhWjke89lPALCpMuL=B&R-skS{aSuC z0$U5bk=|(G&{>cas&PH4O>k-YbXXXER7#s0LE__yNjXm(eAAqiO|1m zc|_GDpA>!(;mU(Yf$W-OKp(6hVR958W#1pml=xkH$Y(0rJw`Cz_Lg);viL4!<*)*U zx=UX(dOS(Xh(G`B(jfR%Nh*MtfzbT7pPeuHVWYRlFAJX#Jxn!cPkO#l6j;c_^GchF z;=M5{4i|cBd)j1KlTzPqCbQcD`i)^)$5;`Mi<7@Y&ZG;%mBF#% zYT30O)SRYiB1u^blRWOy`o_*=^^OUqd2|L%RuKR`X6io?Cquk!*~7BXHahP7_zOOMuj1no@L?>} zvB|55u;|^#(R;S{0Q)9LO;-y+0$nYu#bl0;X6}OJw(?>jU9^-IzWqnX ze^^qwM0R1)p@L3I0(kYD04&}&Sbjt`QQfZ-S=l1I?Bmw1g%&*P>Tb^9^oBJnPhS1Z zHv>C1>j?gVdsptIrCG5i=xrfa_aZ+bOu&Lz^y8$1*%c_eBf+nifDR=4&$u0dsRbD1 zj1kMz&U7CpT^jp}O(Y3~q$m*Uu#WkO&f6TBtk4J&<-LGO?&qIroI^C`OxB#Ixi3zg zk^A$C=8gMWA1V3a4+GIKJ6PkH&wg(QoBPGz;GH~}$0sBfiPMRw4wrvyYL%p_jRyXu zoL2bkuWNG3&qMF9ogO31L|8<==$uLNU{g@O=GaGtqO1ZZr zkdbc{9Mm#Dd$APrMy2}3zQnCq3V%cB4Lnh}cz&uAtP6M4c{EQHb!a%aU(KYH|KW#5 z52O^X^JI1O*Nkg?MhmAH+a~g3m^tSqL>XEEB$bVR@ujOO0b$XF)~%+Edh(-hyO!;mOnyM?&?bDnlQdB%4?AW3s#>ztHaftB;|! z3A0ggXQE42JhLZqj~IFMX6B+AvU~lBiips$-A)x65uX_j^EWA5)G)o`jtWG@ntQ8d-{W=5egA}Pl(PEI78Z8j?5xCe&DSF z=Y8pTGBp2tq>1_rGJ0wVk8A+^cqO4EoLO^!;)p8#;D@Q{PYXWON9@2K5S)%F?u%@F zD<$Zd3-6I*m0{ftj*0}mi;Havw{N!E-8>*@=%9q8VY!i%SkqjtZ_HQ39`B%0NM>43 zKz!Rk5QtvJk0C-i)awTY%LN-ADb)KZ^qMabhqy1AFS*<_Xic!q^_(U*9DC{{n|1p94C_OGDkPo7J!}E`>Zo$3>O|rb6)Ui_h0>y}ntd^`yHMA#-J7gwh$kqim!kO7oY@J5uMj#; zi#KLv6}lh%8AxgPAmoPB48X+HnL@)~X&A0ftJ^obBH5?7{Zj_O!qJ+SpH$#Bj(ZY) z>EfCw_0fNpa6v>4KAzF}Q7ZDP??qd>0C#rwg;>WWK7YL029!y+sD#^%BEN3EJID5+ z338{y8v80|m4>zCy`Xu%g)w@&(1&3d90hZ3p2`OG4^`-HsDh{WOWHb<2PWSbEB|RH z#SzWdP`Yx3I`xaSj6O&ctLnnqhMe<-!AR148sq{yQs9pJA@Qtd(NQ;|#Ei@Wj_6Ia zsM>iaMwYq7E`8cv;zfc?PQRNx%|Sk%YM4jfI}shvqkoc5$+*A@`X;3p%nz@OA-@@( zf-{$S+Bw07I4fC?@@;HsWo?(h1KyFO_g1&;Q0v%uP^n938eMt{n$O@K?c<=9gQ~4D?GRh8y*v72BsS zAY^RWKsxyy>EqM-Lc1^r0Mp>aSWb=NsgphVY`$tLVQU)#AtZ(E^+*Q5bFq8UA?vCV zxkG?lE9Z@mNkbm|J^r|nyI`Rf)DMz%z3fUn&7054p@jWKKNQwz-NaFl-|uUqSE^_F0-4~)BrwAJih;{oQT-D%LWmje+Nd(|;QavC` z?B^V5a&(}i4*3(-$!;&xqLv!6H-v4nzDtO!K_3z@*rBx;%Ao?)H+VVIhC%Y~xzm%a z5Z*<6h5EqaH>C>vaPciA$dVx2H$9JRc$zg)UF`PA*z}fd_3z-_nw(;4M4t}}J9ngh zMa-|%{Csi8C_lVYi{oU}ea7})3lPCNg>2*;fTjoLfv{sFmbcv;Q<(z<6WrE0`Z+iIc5<0OZq|yQ$^@B2{-pPry=F%8W(M}QU%~$a^VJf zG-6*?alyMKmY=YHD3^mpMV?;n1{S|O9>o9BC<@f0sckM+lHLb(sH$=;x-9^YPQsvY zoynQ857;I@^xdlbcf~7NLLyU2>c!j@jZ@b}Lm4V>k!1l=#{%c0zkU}@Vt%+R=0HHl zOyHw^c>M76IbfWD;9K3;+kT=dSw*9%0)(j`en8huu`J*~{qJ0>f>>Z2stf$^jiZNI zf%LpQQu@3o)Xz3X{=_*sqklLvK0-1Y3Fx0aEK{4oTVBt!*JTu@z$9um4X=$p^`x zFEwdJi)3p0LrH5ysG>Fr=KxG0x^H^2&H^m}ZAaza6@{AV{m$NvqZ(j4A{!f(52_xC0^5AzN?yRmW(fcaPPTol_k zT=Q%S)nkW}fd;h1!LujSM=>tOgYn3U)8?G8dikkO5C2XIo%%u<2kxj>UyC+qe)(u! zvX$%f0UsM&`M&YqI!I6>T)Qkl)PJcYRjtSI5XQ{>gJd$)3YE83t?p#~0QktdRxiI# zSqMOf7FJ^U+4Sqq^Tny|F>j#gmk&rmmYi-kaf>yYj?b*5+nC!gqw@3R%HZ}3R9NxEy5Juu7m}~~ zo)+;!w)zwMEEr?ROyWP30e;+?1NUGY=*wzg*O2^P+nhvHqtx4PIC+wXCPE$KdDsNe zO;)f;2{R{zrvPa5M{%7zCk8buSko%a%#;!s-4xsVOD_fEcOl4pNl{n&c>Am!oc>sM zXLt-Rb(`G0w2wQ^GbF&(Sms_`yY2k2N_!B+VDU|e9oU$d0mjJJBUGrl3;U>9J zf-jTJJl!bzELPmR6q+7p?e@JRi_C;{KJ|Vzb4~sATUd^dC{&riC#K1NJ`eq!=W6yq zhbN8M8d$1WgCez}<18xE-i%M_zWD=Qr)gD!J zUbguAqVS`^sYH)q{8}}8(TXL_l>lFxLT6Y~)?e-#XBlIU@HLxukx}3}beZERqj^zf zB&3DJZK>V4BPGY;6;J9RCbxUEH6+=$sG_~PnVx$)J#we#)G{n99B`t4*&h|;W40(E zfTfa2(J44N&yW4sp)b2ef$KJ~?aYnoF1ktdLTKU2{L#9_iDkFWcItO|+5E4Aj-1P? zkYaQ6=W;l}r5@d%uj4tk((V4}Y3FP=qinIm=_wX8l$S=pEsIl2&0673#wm1e^PxgF z>Sfc!ZCE+Mc%5xC8L`I2KhnduQ-z?Hj_$&RX?9J;;ld`y!MbxjO-Y478yMp<$IYxO z8XTX1AyL!W?mnk|leJzZ(nR$(75cH7c9RC##FMgw-Sz!X-zP^uiC7%JTJTjWRyYpQ%+syg~8{?>adjsk5=+f z-*ylu)Xv3t0AHB}cF_m_6OSm+*I+bD2Hf1F^x!0MIwR{dk4kddYHUp| zB%eUNbl%Ox?wZKjV5l|4hspM2H9F=MK@>_zs_DKxx)U}%aEMt*t~15b z`)bG?fvM5-ae7BqYS+cmn3R`&{gs{iaKbyPZUjG+<8oClZ>0g2{67~ZTPaB88eT%e#mr`oSq!j zoAid?9oT&|J;wZSExdtF<0Zk3?C=Kt+v}!+DD1FYGQeexPGaz`YBBmfT){c=kQ-5$ zh&yA-?GU<=5Zs74O)jAA14w-TuWU+jJP|CM+91A`w*23>G^F0%-i~V3Bv}iz0oOLH zD3nvoBynem-6SHXyIDm5QRkaR#OIX8Wi9jQ zl!ec$X&XYEuUEs~Y!BVGXZKSox|U6j=}(zXsQ1GnkQUxThAy%|P9phlf1WoaGGGq< zcR$-uPNo5{tTHA`{ZB+1057c~B|jdb@H-|H{wLWjI&J}yKY(6nZ$I<))`AqR!}6Ru zgnanoUHhHTmJdKd;m!2=q%Mj>xkVVDW|)%kPEO}$QHN`@Xh4_kpy+FE@l|u=@8klim!cI>DGN%ES!JW; zY9;@G4wJ@+!d4ags1#LXLid3+L9T45gG>m(!`@>`IqSyV!i?YH73+GnZ^MvnE3^ZJ zyJTfr6rpKo%>dZm!W#p13yM%bXMNzW^=DRJME$n9^=cBk(_4U$ZvRGz-~5KG=8wC* zgDBLH0pg#!>x#W|co-p#c=R(O<>mYts|rLRvW!~molN=nh7sl8^NX7f=ev{F>2E9k z0c|URpvNF2nb9Zq!V)fqCh|gyKjr=9P28x7DEoUReotv`#tb(E{KfvP z42dZeJ}GDG{XZL{WTJI>mFjEt*ClE2TkTIs&$o$ITTWw1E9!3A#RxNnXuke?ySR88 zh0RamOmE@qh0S$uXnQ&7J3pKkHMio9E>AH}LXO&@;69uz!-FQd4kVN2Io~1cJj;nm zp_mt^?uycBeu3oE;CL|9>JhR_iDR?aTyx~zvwsplw=aB1kh~nFctWJol@+KyB6(*1jy3(xMWz0;S$&bR(G!!n>yQp-eNv7b4GB1&{9i2ctzbI~|09b})# z_;Jp2Xv&qv6Xr&MudPs^u*6t!zTCm(5nNY1FN1*=^qT5LC3^biZ?Lx2We{Y==xQPV z2Pdx;7>Gf;DkN>1|3$JbKn|-6$j<&RBDHR*cZq5K#eu3IdwZ>a&6Gbn-hT@!8?MT3 zq0QF;t@fOiGIwW__MF9oglqXyr)VgFj8a$m4CdP(JM{fYoQ!@gUN z?F5vk?U=~xheqzVuKvk_|0(wAVv#tpFfDR6=R!BY5(`Xbep%9WRAb3{xl;UBY)WGW z@;J}9{fhfP;qRZ0Wdf9N;cJI*q+9u*3lvf4{?n$bAofX^ENP?3Qb3{90C=qXzwp)d zOA2G@J6Lh>Wcw6HfP6Qd4UVO^dUBE9@rWh6 zLuCh+w9r#r3e6|Tz1(X*E4I_i7N(Zfkv)AM`6QvbohVrOGq1p}zHVx=M8zDVsUp7K zNSIQ+_-|&pmO?Avj$dt~wd+ri(I)m&SX?xqFBkrbrQlTMm2>Zg7$aXD6`7X0IeIpy z+~VE&`bcZjbv|AIqZ0-7i~YIu?p*((ge&6*^EOm@+hW0sPzSae^EK?^Vg1wf-rquo z@@HdH^2P7BeXSH~zi#~s6jh!5o5KIAT`G#0|56B&Urb!2#AWTi#2@0je?@T;zyY*+ zKnN}$1FqSiO`+hUHKa)jtBJf2!NKh4&FM);St%c-z+(E+i7H^_3Vkq z2MsnF!GOBk*H?R`4BN!~MZ7EWQsu8q_1`Sg@8pz-UV8B5RAR}6*!K&!gx0rgcDd(r zk9dHrY=TyCMP78bb_x70?&q(SgZXj1Rh4YCvcYvZ`4rSF$CD_~MjDeg4whC~D@DXn zCklw&oI7tT#4S1ghIxiwiJd|x;=X?`{Tlha+p9E9%TVb{AmpFMvQ>{L7K6Zn+( zwx&mec^t1m&N=P}6V;h_vpuPQ!?7s#9JhIkPaEBwK(7LB8=d*l8*O1&9fs?LeL_hc zK18DwW~lTLZ--jkQBi%ee=P4|Uyo`rNAy+AL|Nt+DWaNQbzH*Z3?c?%P- zYEe`fq28Pd6rNrn#j`MQ`}hq+yPCE64wfnt^{bAiuC=}b)?v@2Gd#WHo-tefRnoY7 zZ{vbba|bCWj9)^TOnY~M3bP)~fYz$3?@OH7qVkTW=#J!D;!57R{xU{UON$p_^tQtS zq7&>9%a`99dMo5)`!Q-Bis*vbIw5n0zWMs{9V(J?BA-v$E`F`w2q-xd+Q5E@f^A{v zw^~@&`&n2rsHn-fZYdp;qzvd&C7N>YK2xUzaVm$MilWVS#vmInEAx=FFZ=8B;;Qxl zg*>FmW$NrgY5>vl>8E1iy{)WvR+oz*v+s%47hVCOf?{A};C8P3D+}%Vc04=4)ws~q zr%sc3Es57y3&GL4wzKR6Prn%;PFHsoaz)bk!lE!Ek>x$)arT7Fp=#<3OiRxZh>KK$ zwB#aVp70Xy6HiYEVOrVmHoT!mZ?$dV5QIk|P1w=IbU^_;k(?*d1&fm8?BE2{y#B9( z9ifgodx&0Y!)BAjE``4=*AFy6%|V0pNEa`RtXD~rtC90FZT1%oSq4ba%;VxUu{t5o7z$HpTf^n8Vjnf6UD2Y@@5junej zC0q=th#zOuN&`g?m6cI@HEI3QIdZ)lpDxD;e=*j_H*os$pZF4<@->q2TgZ;?3(zYd z61-3BcIiUwg-T0@)DI`2mO_@5LqlX3AFVonk)yvXyd;q1_J~?68yZ6ctI$M(aJ#79bn4b1!#xYKSRbFR#$O z;Fj$8kn)82Nm`OFsFFa1XDRc~$e^{xr_2>Q)bat=+%p12=vcHs}-FH5% z@4Qu{VR~+DhVmNZMV`CoTI6rs{>_j_{k$%#%)Z-+&P2o{H$%$B0SW%bsXv)OiEe3| z#LXE+{8`O+so@o>d)zaKEAymc8jdo_MKQ-F#Dx{9vE=hpKCK%ntj# zIbOiLnROAiGvhELKfOQ@v^d@6^eDBL0$CYkQLoWgN2yR?gnNg1Y4Yr(iOp8tC@DOV zl6T_UXsq8rC5cXs1|bD+PO@vyq0zv8DLv?@G83o=Y7AQ`vR&64F1Zu4+R`ygXw;-a zH5(o4aRb?GSh1hF3;UcAs$R^G>0E;~qpXbb(}BVwvFHZ)`EXn1Z==+_yuUtt8UI9W z{qT=CPAKU4TWf*|{o%88uAi@X9*5jm%q0SuHQZwtf_lx~UP!+lrv+PS;1x&ze1sf# zuG?^Yq!^(^Z%Orw6H(@(lJyclrD6}YM{RRTygyWf1 zmB|0h68NooX|vX7xCwbQIW-@XGWM^~6=0h20UvCFJua0gzR}KT%wy|{!j1y|`UVtW z-}fcn2p+@SBLQNxpUwWtBiUTm|9JG6+@8k`@1(6UcP4-a&U^Q-GtafX68Nn-X(!Qt zYCZfqd@D*|qnR(2``rmUlk$^$me4oYJ#>+;!;+~Mfw@Iu0Ya#~uJO!H@AKKS9KMm- znhm0v_~Ji^xy=K}hitrzVPTuPxzx^{t>5x{OE-?#+%C1iG}ErOuhmC=(jAZgd}gQH z@mr2*6}+RWMReOPa55CEeKr_!~D-&-ZHvUHXM#B#>5!`G19tZ5b&z zOT60?+kd^+oeAK-rp`uzxyxdSb2Z0r+@(j>CLsY5ivc13>!H8W`v}qE;q4 z5xa@+&a^!C?k5Eig}&qB1Kt8~Gs43>E#AJIyC}dvt-wCWPXzer$eYDSYeguqz z!-6T@?snkp0kG5RwWjS=mTk%r3Y6%|VUZnc+p+-luU!#YFZFFB#xyWDm1hi0H2|(q zz%G{UCi-&`DF?ASI&mKRt(K>E0|H~9<)&k+V|CwpaSMA8D*4%IX{QDX=IN#%6mSnfDM-3CG=`q?)xVMTW{ADHIe{(jgvGJ2Wu^7CH3Ztp1c+)Rn zVOD4Gfe1I>n6L|dqg6NSZiZxNh?P-mjO{Y=IiFF+0}8sjzx-m06-d4k6=*sAQ_4%< zvY_v3ef?7ZSc1#+KxXM+hRs0)25>di)x#O)V@4|?G9;1cPSeH@yrt7g4z|klT%g>Q zg*PkIW3Lo0U4_a=q~Pqv#rpz;4QaM-tG=X^DAbC;=zNl&Dc|`rWU&fZb4%YrKL}nU zTr2Nd9~Ba((Vu41`cPh4W$HVLIy|TyS{Jv*bpa~+)^^iiq zb0Nk|ma1~|2uDTSmBR-PcU>0Ax8ZF+9sOB^B9Ub*%zcsLuD6VYOB6(_O7+t&`mx@p z@MM1dQsRARXN|2eP1#Vy0K!PKp-6$zvu6^Y!3d+O^`HgAT8jh^Z}&o$)12v~hd~U* zDWp?xW4?P-sc?cUKqMbi03y*8_cOKmuH7>MrfbA-(i(Ng97&K3{jiFRn$+q?yJK3z zDpo$FOvqPrNDFX|wx!cW7RAx-Voz`$9}bJQ5m~#`*$*`GCl#D>R@k?q1U%lbYJ^&h z^ayp4sX!6V?wz1Q#ZdKbvhjYx)^olaV=ZmsD^6Dsvy&H*uc1#7h%CCVyX$FjzHXcS zTrI-2A~5CAZa{)_!9KKWWv!cCGdiV2)W5tvhXh^!b1-ZuY)z1;)o+Hp^6mDU^tU`u2)(1nzbsRaoD=&oz?PB|Z^`r}33B3VoC+E;oA8aTv8~PHMx22=~=cW4v zMSO%CAYMFA35%+J#zM^Cth+G}2Pdj4&$VdU3UtB4y_wf&P_XnvQ{9w4X06#5EEGqk zzQKQ$ge@V;83f>+Gp&e%Z;fh5iqnNGUv^~z&Pz{1aw@sj|I^-=$3xk^eNT03vrLOE zVcIRpl6}b}No7ky*2$8!?6R9SrU;Hmh8r^n6YFqX5MQoWf|qZ z-{*ba=lOhof9Vs~b)M(3AK&XZj#I}}fe2K9wQ24L)BBw0$Z9Kq)fv5-l?Q9u3>pG6 zm=o(3VKO-uHN-dK_w8h}nzD2R*Wjn2T59qEy2Q(`Zy{rE-T{{p7}{Tg-e)k@kB6!a&W!& z`%pRsb3D&)c&-FAU@Ja7)Ic!{QJ+_*dcKx99))Pr>Vjk5->9Leblz^DKqi^x9I)Vt zb->mP^iTf~Etv z5Xctob8@~(g8Iff#-;qpTYy#1@N%wc-RblA_7nSn2EE?~pde6dnBS%~9k<|uO!nWK zfp+uXrU{_y6LFpIW)A~YFRrI=eHt8_=;pEls#_0`S%3-5f8ge9PtR{sCJ<;?srVM{ zU7#2Lx7i&)>qTeoJnVYwRA5X`%gSo5Yo7k2IkWyQ`@an*;IUeDOWfXn1Zw_k5k|H*4A zs0q#W2Q!*8`=@6@rI0k&cP6>o%}XQ|tYUrP#~3jn?1T03ftv6Bk_;;N73j&g%hLY9 z>}nL~g!#JW@IU==sI))k$UXG>Y@uIlr$#V|T}T=vjh)FaIj2^LZg*6QR*JU0Ir99+#}$w#IP3)yYbbE0>No%{rIB2f8+^Q#Z)W8h_^#CzQR>((1Aw8NQR8C zp6(Re#S!RG01rPr{o}1JyjyB0#mqR7)GIw%OdLoVKjrz%BNb+xAIjXx`e#lu9g(}U zRX^1IVH1joM|gwVYwVw%)!)g8N!{1)M|cGF?6>R7g&rc`7q7^XH$vq$K;ScR8&8-k z<;Z+u*9(Ceo3)-1kaA{D86ObbFNN%wIyiFE!vE+tU)Jl>f0Clhp`?lf8|6O^L6Qp* zvCj)j;hj+|{eocMB>R55yClJe?iE<C@4Lp9_73C8 zprI2>jL51>@hMG|=bncok4T6*~!WQXHk& ze!OZ*SopB|6J69vHv_yNXz0}1)_Bg>qUp*KIt4SbT0dYD!#9CA>}h$g6t=m`h{R3@ z|74V%TA)p$-@L1wgc`9`e1?D3I_Q+raR5*e>t8BDL5wQxL-NH} zB1Y||>es}jX=g>dNFO$3YZT#t0lUy%5*O2JR zF{`(uNt5?XMZBwYK$zoeI}%^{5YRZRg?#}a+7rE4qZ15>FEH$*4%;(e?|Pk(;P2=Y z9sN#jkAeP*T_a$gpmojn7MPz0RB#o2ef&AFAg#xH1)2lm^3TYt*6D)qvXSzxk!FfA zc88bGOiGvyybn+HD0$RTE+ItR^sNM1G*)C3Hes0?_-CzemfG6Enk8br^AYsD0ugll)7OGjitY`J{5s zX$SQOcqfy$qoDy|+_sv08w*O_cA)BXLME)j1yT*IL?RlAdDB=Kj~ZZ-S2P% z@N!-)6~JIWT%bP?=KO~GDHY=}nXKg_&+`z;`Fw@gn7t7R3F~ETMN6?{p5%{GW&EZs zI?5B}ScMHwGqK;D8?)(4*LKrLM|+4WjJ_#`SjcYow&LHN-bD198Ieb$0Tw znYj=#mh?B-GB;@q<1bT{(_t6M?&B4k8E$y^iVO27@(0DQ4%8NiCYPUTH3P`&67w@& z_ziiN23=CG#p5`PH5FTw!bC!IB^@M#DqnYxP83 zGk67Zx;StR8sIB{Pyc8^JfKur^>JyjWDQ*lURB2aZ-{Wl+jIKIV{muYmoi(Z%*$}$ zQtuDm#iA@WI#l>f<vdFxN~MpH8%R0#e+M9TjP zMCRwDffQM4R&dD~fUG`r=-h@B5JOw( zdzS%F#?`8KK|sawZvUQ^qhihGQsocqw?UK7<||Q@<-v#17XVNez?NlAXnPts*x4HM zXChVl3|Fb&gK|}`SN{I~;+9@a^y$d20X;3{*71*um}X@3Ybo^y|Ps+4~+)S~$Xol4r@)i|Gk zV&FIZ(QiHKd`<0S;68tl-)wnvAu$H^0V{TM#C!33NCnLe;2F8?*3B<+%{*y1yspZ% zPy&Yoz(56TJmE@?;u+}tH`CFY-7%Soe#Qph;0K_aDqT`iAH|yq z8R$>Y%-Rmq)|c-H*K_1YKLW4XKKU8ecEy59V6({j2S__Ho7@mz|dW`uPrQ+yWI&lIM7QYpY5ELZ^j*yxuH7PRzr-VW%d{c zB3oOEF1hD>R@qAf2IJ7+@JD!~81awV@GA3;t~S|Qr=i$hghc#a8r0DyGst@p(dMj9 zXK(;>_2i%pR#YlstJHp}ZU(Hl_mbEE?s3wuJ~Iaxfxq#^;6CxX z5LhbX6N!jhdpQ+GCUVqRy*Y%OHx_Uo>bY0naufbt9iyUSKmAghVnQ;zG<0PLUj@|} zrCZj$0mcw63jsRalkC+E@ND*h9PX4`BJ$v^3OnY${gG@-x z!Vd*5gIUOr0@AG(L0>;Cx!Yy5yHH+|WB$hiEh!&;*Rohvs{ak|$2^Jin*>JGtQuJr zhCT_%n{;T8eiE4HY(O{Gq%4PY`iT%yPa#~hfHvU5@!X>?2aTV?w6|Vc<8#0~IsVU~ zHw;)d%;cV@Jlkfrb>P_olD2xVW*3}F_br#TuOaj%i>y9QdmzljMIO1ctall#wq8x*=Ij7*3Qe;?~;=CeFnR}I15#!9j2i?do}*4 zYVJ>Da@7ovrN6w8!Y2bB%Cok@G|qDh^Lr+r*4{`V_u$!g|A5B||NmL_ZHRAmK;`=C zyrSTyW`VI?Z&%``zacvXM16$icC%fH^JcG3K?>;GBXPF%@ya@x-^eX6pJo;CX4PYv zsF|S{ts<8@ZWv0`7{Ckst?0f92J`j?~L=5@IcG;JU zl!+R^D?0|je1y%gXo@m1a36vf5Ip41$E&`(5q*5EbjV_kD~oIwphSDV#k^QPx8$r7 zGuHscbU}R3F?Z3OpZKKx-H2_DjyMca{PZXC&=)eg1Db%6iAE{n+a_6FlO>fu%2yn3 zG$kgG3@(hm@U?b^Dz<)J!wxSvGpobsH%&Qq=&+Jv+y~Pn@JGn|O8U~WzcmRE6E=Cr z%nDe@X@4_wJc4uzlhxlg&9-G+`>#@W@6#_OelU&t*axL|K~l(3&4Wc<>|7r{+TSm6 zyA?bvNt}u8KjUD=FSNfdMI|d7>}stno(+VWU7{N-CAM=Q zRCbajKdC1U@%f?N9fL^~SUk~yso!p`{&|pq7Nk#*(Uo$e74q?PpYL1!g8JOwNrq?0# zqGZdtGNcK;aB`NnqLA_(dsUL!jO>ZM90M>(rnz=&y-7`zCoJ@+@^f8BmiVm?@$B&{ zS+9N|$8&4V9>1sDw@Fn{w>l__g8}hCM|@_a0XEfJNh-~-m=lf5XYYsHjk#5Zgn3V5 z!J4?Deu)bjAVYD(*A(GutZ97M=in9;8Z>a-sr zDjKLmAi|Njdy|4;vdw$~AIo4;m3bJwQFcn`&}p8K>y2yMYB~u~)PT0z6B4{nfd$oS z<%mvv(;IxsQRYG|JX}+ejjny%0vsedO#uJTkNTy#fH(gVQuNAs**Kx&JiO0xS|4rH zVeALrO6=Qx_LYR>1+$vxNe(CV<{0(p2q}vdAp|9{k}s*B^mTw;o*)F_N{c#N)=7OOi4%rLvsQ}co=;35+SUCJ#M3iyO^*|ra2A}6~ySI{ta8*N{>Sn&yUZn z_}r@h1*}P~J+7>BT;#7wa&O0%V;|y7EOM1nGP#Etcb0m;PtP`%nf6|6)0~Vo7;5U5 zRraorOWL7SbBQmIQ8&cOv0Jm=#G-FjQx7^k>&aFaqTBLdd?H-I#Mq}&jN^maW#quv zUXi-VAJuPV&!YQlWsb#HDq_1jIfM$FQjP9~rirO+#u`OVG|R9D`nh4AQNkPVYwBNv z^uMGGMCDy)rQdYR0^}QLVzbL{mxf2x0N+S~)Mo5t=htG|x1oQgc2Z)j-#h&+pNbn; z@0GbKsFz01IgF69;0UbPLFHgAH<{NUERzY}Q3vJn?oYD04T>Lit}##TiZ3#zFTPx? z6y);4@P%_qr|PJ4alZLyN_+^-%V^F@oRY6Lr&GN31p2j2r_Y>?i#dI5Tk7A5EbfH# znB|D*GTJ6OQzFQqqjjHoKF9JU?uYI3@x5(X-)59=oG;Q7q>-ZEl-pnt{3Pld-$lUk=2>fwql=7T$&(OeibVY4vkJW%(a!YRiTh%8CZ0W>Yhb*~U{JOZK zX|eaKzN;dsywcpqo9$D%m9v9)>%pi1$G8r5T}nLHsd)Excui6tUkNI5MqRwUND|Lp zc@&;)R?x{c!7IrdHOzO`uS5;0)SdF$Ml&+VhoQ8aK61h1M8cezr{a8qvZVdHqbvXi zWVSc}%<%BxiE#mAODA?rdOs<{fr6t0{2ajs6HpywfustD_~f z*P5+6Mv*?SOIrHsZ*>Q?x+hDf`;(j~Ne9NJg(q=m8FZT{9m~#`URFI{_39nU^a`<= zi9;f-@!4-AJf)YUcIi9_%fV&sBsV^j(EGeAVZ@9t!ACYqjowfK*7oeP-7ji-=CS_89Z3Ib~A7Zu31&9Ij$h-c-H+q$lyR z{9ZGO5Y$7~p?W~wUG_?`9vZkr+~rr4mANP=jM@3vA^Z(`+3-Q`90OM61vxGofDFVW z&HL{sz-PL0WCn?U2k-eS%K6z6C@fV z02jR|ou)464tav%8yyc`U_6g)l#tZ2g@00DuAkGnM->C-fQge*moK%@D{l!+=-nX` zt0CiH8%}QY@KJE+F>pGEDzW?9Wq07%R;(~F-BX&+@ai`XUzAqrIYZgXG7tBGSH#|V zOZEH*mr$hc&369d`({IX=!bZW9tED_zf{g*_ z-CYzbuVO7quF1u}yLd>`r`A>MFwmDm+}_#iDWo;G|D>bFybZ!I(v&qJt5_`eMrCYe z0--Iu^OAZ@@3@9c;G3awdxw%o-_f06*_MXUdc7Q-mz))5taKZ3y4dp9-{^X-`c@$H zN}k&j_~vvtteAA5M135C(k9q)B<(#tn#Or5;%{iFWD%3xRo@avbD@nztas%h)j9;% zMeql8|CQ+0GiA+oa__S!&Ap;X&2ckLysz$@>(xA^j4TcjRJRe&y%GHojOq$DDN-nk z=AG!kB}_~SN@70=Sapo_RVDp`ri-( zY3in%I%1!UVLHGv2WLL-g`W{R=}RlzbG@sZT0!Dx2FQ7dDkU~}4 z&NIr%Zq*nTWN}phb{&xDmj)x@qL}68g9gXW+er_}QIjs|sF@wN@KH^rNinhzl8E{t z4YwJ6Kl2$`6>=lR1zU<1TYr#&^ox$9N@-c+fFfbmu#~CB@^Rl?^%v0S3ugL9i#?xEx-vR53&hNV6G#QrAN}$?NP`8^g6D(AK$G&~jD)((&8Om=KIr$k z`~ZOQKXQ>}a1%AB0{RUoL)BFLCS|8?1LyK;>aZDA=l>g&qmOEk{u@|;deHbAM1-oi zulpTHMlG!VE$a8boei$Z=uV(st_>>T8ji3nAN{-{C|{Mnk;$2aAK#m7A?z}hMdICV zE8O^RDa~2HgHc)$D=rcjXCd4r)l%R_m{~X%e*swxe2$(Ww6`1mi$^(D8a|v2k_LAX zUDDzyi94rSI{#x~J)pppx;&r#?|eeBJr0OE79e-3KIa!mzulGRtj*8b)0L9!8Vd|B z1YMF_R8v7!dKZ0k18gBxyRo!5l)9-{R`fuXnoDa(sT+i4pZ%#4VeuEs z$r%J1++t`7bk{-7oRquZ>bOuu4p_y73%TaIT^AMB({PqAOOF7aeae~rZuAAXO{`R1 z7r3!)!~IwDoeIC20J0Cp#c7Bf+jC}+hS4yYqH}%GKrhP1xQ#YvEP)#xz^6aYO~M3$ zH0(Q0+&aG@>)9*dTChzAEEo4g$R*v-JHK>|**=e_wS`A`jv!)o4cvN&he z{xIaBYW3Ll121L=>489kOf38&+@f|$XO$8x+>hU{r`!_*>}R%>C4_D9MuGb6x#k=C zv-HjPKLhu?asK^m_6i5!|0%6B|JnZk9P0Zd3{%)u5CU{K(5~RtK}sje3f`Wbl?0e- zHRFC3V%U6ZD2O|!3Xmr+Nd=92`Z!qpyevQMqDbXLH=~M>!#nsRpgYxkh_aySvmFfC zdlM}Df@w(=vzHD5|0$AmdxK3GPlR#TP4dwNi7CvC$^7C^amS#GvHv~)8oY(x7r7Ns zQtKQvDDuR!=fEC43H;F%1?0{_KmAPQm{PaSEWBM^5yx_ zu%NT4!igewi|FS{LU)pZcYD&;F{cXm@h$${tfv*E{6Fx_toAJ-S-2H#!>$YS`nO~i z<<~y5tIulS5{kxueeb+6bl!x_vt@R_AdRaXlyl4(5!Re`l=4qA^2QD+7dK}{mN2;R zf?hU-BD02s=M+CdV7?6)bSe3WzWF)JIa9JkRQ_`u(0>be3N3+-=oUrrk6xh5XKEYh zO(JzJ&i-9b>?UiVV}*PsbKNC{Rb)qY%w=2&F+*-A*CQ490_)co-d{!jJh``y#AFhX z==Fsat4P&#@LMPI?Lnhi44qweIG$;<4X$FVhzu?|Y>4mBV=nC3mZ(rG7&zlrKx=4#-*8lcoYk&e>0=7A-CS%0uPL4gVwrMVAYP?*!E^{CPI#`kiJ zyf;!+M(W;}8Xu6>%*5IhG{*O{r%GNG}B*h-9r=!Y;)?0lIr!x?)dbzK>MT@tN3W;yQmt7IPZ`I zjJ3K0XFF3XsZtS3OyVg5I>B3W@$UZ8p_zJ!$rD)MM(LDIc6xK-_)Q%Cm+wFgoS{^) zb6aW*mGvudm2vpeS}5GFdRDi zq_n2mX;?y%|MHA`#q5GYUJ>NGbsMsG&zbojhh;Y))T%lxnCcV#I%_DA*dp_Zi{>jk zY_j*NNk98&yxCLktOR%Wd&NZjeSGaR=d|!TtE0SldeO>Bi|t9QYKR(o{|AE&daX%r zDV>6m*1A1hTHtn@ISu-fM%+dOI!)m0I?<4p!$G6^R`osdp4l31MsI5enw=zC>|`5V-*zJ-vUmY%F$CnT z%RaVnDAa~Gz-`SuxN6ti%Y~T{Li&V0LDp@&QNS3VD|IiOv9v~RV`eRYgk}C$%&BF_L;stzSKJcdjJ^7FDSD%8Uu`@^QCrx;vAl3sotUTEdo)H^mkWRe5eH#J z7N1iv?|lj^__f~BAf%1k@e#6`N4B*;VZ!g-*lUfMnF5*UTb`lLz#TQaW9(%~SpXqR zLOKFRwPAzf%r3m|fq!Rn|J=O4Zw#|oO!X-w$ zxFhdTrOr}qeS9N>eA>ZK^{;<;&dsmo&xrgY-TQ~+TDy#jTF7uMqk+S zljZ~TkQe4N|_WVt5l=k9LuFF+U7%fYWJ`Q2f3<4vdZyTIs zFTBnf3X8FVsMZ35`J5X%o1Iu)eu(SdF1Z`fkTP5wi6lP?>_`==!n{*lWHVVHE+h;3 z$w^6e%?^SEyX=k>ZdsM(q7^Z4nddD2c{n`i#{TjA4wPsxoXF)Z^-SRJmrMBI!dz^--dk%pDL)JMeGJgck0JxR{4!+Ng1LH-4f2B>-Tk5j;-(Bj|c*cTk5=V z6ObJ#399eFI?Or_DQb=bNK@yXjQ3X^I`VTfiTF&3Q_D69q}H=hu?Z?j8n{X?K_;B! zYQg?lhyCeNz5?O?0?q6AYLUgj zdhdt(_T-^~37E?h!}fZjthY$o#zKve-IKy1ZO*`$fjKm5k^9W*nZU=oiGm{Ux0OXj zPo@g%TY|*9mINp({$y$1?D`m}Tn9y#B3tuZbZM`1{3vh}on33FVo4x9G@v@%BK?A< zkinxZKVn!4z-bqu6_m8t#W`VO2wA`W65_3`;U^cQocWDuhb0z0FSo{HLe+ZR%c55C zG~m=rF#|ho7x&>-%Ojv`U#5HN0Kye&+zD|8zz}fTK__O=@(pZo-5Q($q|u`tdAEV= z$)KhGtw+LZ&=;fO$J(O?<{-7b=j#D5LDn-20N}Dyq~E#>zhVYSfAbo(Dj1||=Q&xP z+m5P44DX<_^>s2nr*#0#W)f!r3{GfI9U5zWTcZp5_HyD=3P9xR3EOxE0q6x%phOwM zP`8YBIL3XK4RElYB9|?|G>88+hYl9;=J9@cwWcDS5(;iAZU1tZU3!#X!TmLRebm4!=Te?tTptHLtso%&3OBfLArfZ7PHsl>B% zZBkw&?#o5&A8wgk>R(j^ynL(sd*K>K!Xq<3_mYY#`9Gc1pz7GMWA`9eVxDrz2p>a4 zS;i-t=hGbv`NKKB(6rRl{6AXG4h$zx9wCwv5M0yJhJ!I-ClE^o{NA&4+T4T$1pbx^ zn?Y0=%rs+T|0hkw||HDW;lt|kM4XN#BfLT&|}shJH3CkGZ}p` zW=Cm!Z!hWZ^V%lct}3)%hcY<3{JVEGN5dda&diM;i60?|T-3iJIOh@g=XIEFbJJ2!aq9D$ zY(x3z>_G1$kQ%4m35>CaUMg>d{1Y``dGC0M7?UnwWWb4*W zRG?#~9F-^Y5X63nSWsu8$X}x|c+SbZExW$nnQX1G6|mFzm+!{A@Sfs87JuPoECmuo z)O!4|U}tEBUgx!cNn3$Q^9DyB^Lyfc}?nyRsgjF2Q>1N7&IW z%+WV}d|Kb-TAx;@-cZ!Bbb%srG~HJP^dFvEYYYBUr_XS zEYX>+;JN5?jpUL(w_k|hMbO0v5Z)1#d?dz#8M*3oFX|)ZRX#THdmj`+X0V1KHx6~r zF#~o$_OP$oo$+;sWpe@Q8qFf-Skqlw6j^cx`yN%NM;tn}|HEGp`jMOXZ?3QTgJSV9 zo3#UqlCRuhi4M$8`&R~WMHIQVovny_XTt(jG9EHHJq{;gp)w>0ITU-rhtyGogXP9Z zw49mu^{^OM-;Q+;2gyNj(=jNiqDUZSl@NmJ)&`G?Y}vrldbzCF<#s&U*h=O^wT;t4 z>=hOsCC71_(cl9+J7mhbkGiO@jJhdeC6%p2D24jwx+msmW)gy)eqm&LycxruM(~5b zPn!>R1cZ(i;q;59m^PEU+qcb>!}R{q5`h{fLL_|Dw*$Vn(*M$?PtA1XZVF6CmerUP zRm(3>$JiaXF1x%NQ##2N*T=_Dy@nW)gQeR^MCK{=0cpR(dl(BbHs+D7bu}F z^RRn#aL;s{z*VlTs{~xsWh6Eu(nf^&@|H-AkzQ6^gOP&=bLPEY!H3*T)+n1s0WY3^ z6bq}@Kr>)K8HZNbNflB)vUp4cKl&V|Q>CLnH+gbJ26rI9po(K$UHe=}yMkhLREko4 z_td)i@R6`%Fz%G;0N>as-9I~4Or*_>QDVkl5V8@8Rd=Rn1{lcdmjLuVu3s94u0oY~ zU@T_k1G>ct5|wS5jh0a#a6^dlMzw@0m0;SC7)2*@4~sQUK3DnJy>0fvCwHYsiERHfh$X+mZICd{4(cX}a@~-O8}~ zr>imc^!2=Xk#xG3IY`0W{>~b!bBo#(dI#LQH;p4oDi=_M&7lR2MR{>-R^KlrfIBErwIfx2|$^*C*#j33ZPFRi* zuGQg-qJkiwQr6)@h^I(&01CIZ$PZ*^?G1rOXm4oenG7KA0`R@HMOf=rpp0N&;T2ue4Y6Zu@{xxt(n*|aA1fJ2p6iqR^wXd|LBXl}i}O?pxz;h+3lxLJ>D!^ z1HI(XW$cZgEBFIv`?>F30yaO`&ob&SFk36@S*Te{3jmkw-t+*xg%v0Rhm&9k{&DhD zG0SYxtZe(y0iPuxasKXEivrHR=dtkG+lbjZL{L@GY)#~GDCI9epqbe>fW~4eMT-CR zzx0TlU9Ip%jyp;?jS*O)(2MFnkIcZx4P=PiMpRr}ckE%xX3i+6o=iP)>E{0du`Zu$ literal 0 HcmV?d00001 diff --git a/src/kernel_liteos_a/fs/BUILD.gn b/src/kernel_liteos_a/fs/BUILD.gn new file mode 100644 index 00000000..26b27df3 --- /dev/null +++ b/src/kernel_liteos_a/fs/BUILD.gn @@ -0,0 +1,60 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +group("fs") { + deps = [ + "fat", + "fat/virpart", + "jffs2", + "nfs", + "patchfs", + "proc", + "ramfs", + "romfs", + "rootfs", + "vfs", + "vfs/bcache", + "zpfs", + ] +} + +config("public") { + include_dirs = [ "include" ] + configs = [ + "vfs:public", + "vfs/bcache:public", + "fat:public", + "fat/virpart:public", + "proc:public", + "patchfs:public", + "rootfs:public", + ] +} diff --git a/src/kernel_liteos_a/fs/Kconfig b/src/kernel_liteos_a/fs/Kconfig new file mode 100644 index 00000000..032668fb --- /dev/null +++ b/src/kernel_liteos_a/fs/Kconfig @@ -0,0 +1,10 @@ +source "fs/vfs/Kconfig" +source "fs/fat/Kconfig" +source "fs/ramfs/Kconfig" +source "fs/romfs/Kconfig" +source "fs/nfs/Kconfig" +source "fs/proc/Kconfig" +#source "fs/jffs2/Kconfig" +source "fs/rootfs/Kconfig" +source "fs/patchfs/Kconfig" +source "fs/zpfs/Kconfig" diff --git a/src/kernel_liteos_a/fs/fat/BUILD.gn b/src/kernel_liteos_a/fs/fat/BUILD.gn new file mode 100644 index 00000000..d87d32e1 --- /dev/null +++ b/src/kernel_liteos_a/fs/fat/BUILD.gn @@ -0,0 +1,51 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") +import("$THIRDPARTY_FATFS_DIR/FatFs.gni") + +module_switch = defined(LOSCFG_FS_FAT) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ + "os_adapt/fat_shellcmd.c", + "os_adapt/fatfs.c", + "os_adapt/format.c", + ] + + sources += FATFS_SRC_FILES + + include_dirs = [ "os_adapt" ] + + public_configs = [ ":public" ] +} + +config("public") { + include_dirs = FATFS_INCLUDE_DIRS +} diff --git a/src/kernel_liteos_a/fs/fat/Kconfig b/src/kernel_liteos_a/fs/fat/Kconfig new file mode 100644 index 00000000..6d7060fa --- /dev/null +++ b/src/kernel_liteos_a/fs/fat/Kconfig @@ -0,0 +1,43 @@ +config FS_FAT + bool "Enable FAT" + default y + depends on FS_VFS + help + Answer Y to enable LiteOS support fat filesystem. + +config FS_FAT_CACHE + bool "Enable FAT Cache" + default y + depends on FS_FAT + help + Answer Y to enable LiteOS fat filesystem support cache. + +config FS_FAT_CACHE_SYNC_THREAD + bool "Enable FAT Cache Sync Thread" + default n + depends on FS_FAT_CACHE + help + Answer Y to enable LiteOS fat filesystem support cache sync thread. + +config FS_FAT_CHINESE + bool "Enable Chinese" + default y + depends on FS_FAT + help + Answer Y to enable LiteOS fat filesystem support Chinese. + +config FS_FAT_VIRTUAL_PARTITION + bool "Enable Virtual Partition" + default n + depends on FS_FAT + +config FS_FAT_VOLUMES + int + depends on FS_FAT + default 32 if PLATFORM_HI3731 + default 16 + +config FS_FAT_DISK + bool "Enable partinfo for storage device" + depends on FS_VFS && (FS_FAT || DRIVERS_MMC || DRIVERS_USB) + default y diff --git a/src/kernel_liteos_a/fs/fat/Makefile b/src/kernel_liteos_a/fs/fat/Makefile new file mode 100644 index 00000000..cc615847 --- /dev/null +++ b/src/kernel_liteos_a/fs/fat/Makefile @@ -0,0 +1,42 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := $(wildcard os_adapt/*.c) +LOCAL_SRCS += $(wildcard $(LITEOSTHIRDPARTY)/FatFs/source/*.c) + +LOCAL_INCLUDE := -I $(LITEOSTOPDIR)/fs/fat/os_adapt + +LOCAL_FLAGS := $(LOCAL_INCLUDE) + +include $(MODULE) + diff --git a/src/kernel_liteos_a/fs/fat/os_adapt/fat_shellcmd.c b/src/kernel_liteos_a/fs/fat/os_adapt/fat_shellcmd.c new file mode 100644 index 00000000..74e25a89 --- /dev/null +++ b/src/kernel_liteos_a/fs/fat/os_adapt/fat_shellcmd.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_config.h" + +#if defined(LOSCFG_SHELL) && defined(LOSCFG_FS_FAT) +#include "stdlib.h" +#include "stdio.h" +#include "errno.h" +#include "shcmd.h" +#include "shell.h" +#include "fatfs.h" + +int osShellCmdFormat(int argc, char **argv) +{ + if (argc < 3) { /* 3, at least 3 params for this shell command. */ + perror("format error"); + PRINTK("Usage :\n"); + PRINTK(" format

            + *
          • Called only once, multiple calls will cause file system error.
          • + *
          + * + * @param none + * + * @retval none + * @par Dependency: + *
          • fs.h: the header file that contains the API declaration.
          + * @see NULL + */ + +void los_vfs_init(void); + +void CloseOnExec(struct files_struct *files); +void SetCloexecFlag(int procFd); +bool CheckCloexecFlag(int procFd); +void ClearCloexecFlag(int procFd); + +void clear_fd(int fd); + +/** + * @ingroup fs + * @brief locate character in string. + * + * @par Description: + * The API function returns a pointer to the last occurrence of the character c in the string s. + * + * @attention + *
            + *
          • The parameter s must point a valid string, which end with the terminating null byte.
          • + *
          + * + * @param s [IN] Type #const char* A pointer to string. + * @param c [IN] Type #int The character. + * + * @retval #char* a pointer to the matched character or NULL if the character is not found. + * + * @par Dependency: + *
          • fs.h: the header file that contains the API declaration.
          + * @see rindex + */ + +extern char *rindex(const char *s, int c); + +/** + * @ingroup fs + * + * @par Description: + * The set_label() function shall set the value of a global variable, + * the value will be used to set the label of SD card in format(). + * + * @param name [IN] label to set, the length must be less than 12 + * + * @attention + *
            + *
          • The function must be called before format().
          • + *
          + * + * @retval #void None. + * + * @par Dependency: + *
          • fs.h
          + * @see format + */ + +extern void set_label(const char *name); + +/** + * @ingroup fs + * @brief formatting sd card + * + * @par Description: + * formatting sd card. + * + * @attention + *
            + *
          • The prefix of the parameter dev must be "/dev", and the length must be less than the value defined by PATH_MAX. + * There are four kind of format option: FMT_FAT16, FMT_FAT32, FMT_ANY, FMT_ERASE. If users input anything else, + * the default format option is FMT_ANY. Format option is decided by the number of clusters. Choosing the wrong + * option will cause error of format. The detailed information of (FAT16,FAT32) is ff.h. + *
          • + *
          + * + * @param dev [IN] Type #const char* path of the block device to format, which must be a really + * existing block device node. + * @param sectors [IN] Type #int number of sectors per cluster. + * @param option [IN] Type #int option of format. + * + * @retval #0 Format success. + * @retval #-1 Format failed. + * + * @par Dependency: + *
          • unistd.h: the header file that contains the API declaration.
          + * @see + * + */ + +extern int format(const char *dev, int sectors, int option); + +/** + * @ingroup fs + * @brief list directory contents. + * + * @par Description: + * List information about the FILEs (the current directory by default). + * + * @attention + *
            + *
          • The total length of parameter pathname must be less than the value defined by PATH_MAX.
          • + *
          + * + * @param pathname [IN] Type #const char* The file pathname. + * + * @retval + *
            None.
          + * + * @par Dependency: + *
          • fs.h: the header file that contains the API declaration.
          + * @see ls + */ + +extern void ls(const char *pathname); + +/** + * @ingroup fs + * @brief set current system time is valid or invalid for FAT file system. + * + * @par Description: + * The function is used for setting current system time is valid or invalid for FAT file system. + * The value can be set as FAT_SYSTEM_TIME_ENABLE/FAT_SYSTEM_TIME_DISABLE. + * + * @attention + *
            + *
          • When the system time is valid, it should set FAT_SYSTEM_TIME_ENABLE.
          • + *
          • When the system time is invalid, it should set FAT_SYSTEM_TIME_DISABLE.
          • + *
          + * + * @param b_status [IN] Type #BOOL system time status. + * + * @retval #0 set status success + * @retval #-22 Invalid argument + * + * @par Dependency: + *
          • fs.h: the header file that contains the API declaration.
          + * @see + * + */ + +extern int los_set_systime_status(BOOL b_status); + +/** + * @ingroup fs + * + * @par Description: + * The chattr() function shall change the mode of file named by the pathname pointed to by the path argument. + * + * @attention + *
            + *
          • Now only fat filesystem support this function.
          • + *
          + * + * @retval #0 On success. + * @retval #-1 On failure with errno set. + * + * @par Errors + *
            + *
          • EINVAL: The path is a null pointer or points to an empty string.
          • + *
          • ENAMETOOLONG: The length of a component of a pathname is longer than {NAME_MAX}.
          • + *
          • ENOENT: A component of the path does not exist.
          • + *
          • EPERM: The entry represented by the path is a mount point.
          • + *
          • ENOSYS: The file system doesn't support this function.
          • + *
          • EACCES: It is a read-only file system.
          • + *
          • ENOMEM: Out of memory.
          • + *
          • EIO: A hard error occurred in the low level disk I/O layer or the physical drive cannot work.
          • + *
          • ENODEV: The device is not existed.
          • + *
          + * + * @par Dependency: + *
          • fs.h
          + * @see None + */ + +struct IATTR; +extern int chattr(const char *pathname, struct IATTR *attr); + +#define CONTINE_NUTTX_FCNTL 0XFF0F +/** + * @ingroup fs + * + * @par Description: + * The VfsFcntl function shall manipulate file descriptor. + * + * @retval #0 On success. + * @retval #-1 On failure with errno set. + * @retval CONTINE_NUTTX_FCNTL doesn't support some cmds in VfsFcntl, needs to continue going through + * Nuttx vfs operation. + * + * @par Dependency: + *
          • fs.h
          + * @see None + */ + +extern int VfsFcntl(int fd, int cmd, ...); +/** + * @ingroup fs + * + * @par Description: + * The LOS_BcacheSyncByName() function shall sync all the data in the cache corresponding to the disk name to the disk. + * + * @param name [IN] name of the disk + * + * @attention + *
            + *
          • Now only fat filesystem support this function.
          • + *
          + * + * @retval #0 On success. + * @retval #INT32 On failure. + * + * @par Dependency: + *
          • fs.h
          + * @see None + */ + +extern INT32 LOS_BcacheSyncByName(const CHAR *name); + +/** + * @ingroup fs + * + * @par Description: + * The LOS_GetDirtyRatioByName() function shall return the percentage of dirty blocks in the cache corresponding + * to the disk name. + * + * @param name [IN] name of the disk + * + * @attention + *
            + *
          • Now only fat filesystem support this function.
          • + *
          + * + * @retval #INT32 the percentage of dirty blocks. + * @retval #-1 On failure. + * + * @par Dependency: + *
          • fs.h
          + * @see None + */ + +extern INT32 LOS_GetDirtyRatioByName(const CHAR *name); + +#ifdef LOSCFG_FS_FAT_CACHE_SYNC_THREAD +/** + * @ingroup fs + * + * @par Description: + * The LOS_SetDirtyRatioThreshold() function shall set the dirty ratio threshold of bcache. When the percentage + * of dirty blocks in the cache is greater than the threshold, write back data to disk. + * + * @param dirtyRatio [IN] Threshold of the percentage of dirty blocks, expressed in %. + * + * @attention + *
            + *
          • The dirtyRatio must be less than or equal to 100, or the setting is invalid.
          • + *
          + * + * @retval #VOID None. + * + * @par Dependency: + *
          • fs.h
          + * @see LOS_SetSyncThreadInterval | LOS_SetSyncThreadPrio + */ + +extern VOID LOS_SetDirtyRatioThreshold(UINT32 dirtyRatio); + +/** + * @ingroup fs + * + * @par Description: + * The LOS_SetSyncThreadInterval() function shall set the interval for the sync thread to wake up. + * + * @param interval [IN] the interval time for the sync thread to wake up, in milliseconds, accuracy is 10ms. + * + * @attention + *
            + *
          • None
          • + *
          + * + * @retval #VOID None. + * + * @par Dependency: + *
          • fs.h
          + * @see LOS_SetDirtyRatioThreshold | LOS_SetSyncThreadPrio + */ + +extern VOID LOS_SetSyncThreadInterval(UINT32 interval); + +/** + * @ingroup fs + * + * @par Description: + * The LOS_SetSyncThreadPrio() function shall set the priority of the sync thread. + * + * @param prio [IN] priority of sync thread to be set + * @param name [IN] name of the disk + * + * @attention + *
            + *
          • The prio must be less than 31 and be greater than 0, or the setting is invalid.
          • + *
          • If the parameter name is NULL, it only set the value of a global variable, and take effect the next time the + * thread is created. If name is not NULL and can't find the disk corresponding to name, it shall return an error.
          • + *
          + * + * @retval #INT32 On failure. + * @retval 0 On success. + * + * @par Dependency: + *
          • fs.h
          + * @see LOS_SetDirtyRatioThreshold | LOS_SetSyncThreadInterval | LOS_TaskPriSet + */ + +extern INT32 LOS_SetSyncThreadPrio(UINT32 prio, const CHAR *name); + +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ +#endif diff --git a/src/kernel_liteos_a/fs/include/fs/mount.h b/src/kernel_liteos_a/fs/include/fs/mount.h new file mode 100644 index 00000000..d457df1a --- /dev/null +++ b/src/kernel_liteos_a/fs/include/fs/mount.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _MOUNT_H_ +#define _MOUNT_H_ + +#include +#include +#include "vnode.h" + +#define MS_RDONLY 1 +#define MS_NOSYNC 2 + +struct MountOps; +struct fsmap_t; + +struct Mount { + LIST_ENTRY mountList; /* mount list */ + const struct MountOps *ops; /* operations of mount */ + struct Vnode *vnodeBeCovered; /* vnode we mounted on */ + struct Vnode *vnodeCovered; /* syncer vnode */ + struct Vnode *vnodeDev; /* dev vnode */ + LIST_HEAD vnodeList; /* list of vnodes */ + int vnodeSize; /* size of vnode list */ + LIST_HEAD activeVnodeList; /* list of active vnodes */ + int activeVnodeSize; /* size of active vnodes list */ + void *data; /* private data */ + uint32_t hashseed; /* Random seed for vfshash */ + unsigned long mountFlags; /* Flags for mount */ + char pathName[PATH_MAX]; /* path name of mount point */ + char devName[PATH_MAX]; /* path name of dev point */ +}; + +struct MountOps { + int (*Mount)(struct Mount *mount, struct Vnode *vnode, const void *data); + int (*Unmount)(struct Mount *mount, struct Vnode **blkdriver); + int (*Statfs)(struct Mount *mount, struct statfs *sbp); + int (*Sync)(struct Mount *mount); +}; + +typedef int (*foreach_mountpoint_t)(const char *devpoint, + const char *mountpoint, + struct statfs *statbuf, + void *arg); + +struct Mount *MountAlloc(struct Vnode *vnode, struct MountOps *mop); +LIST_HEAD *GetMountList(void); +#ifdef LOSCFG_MNT_CONTAINER +LIST_HEAD *GetMountCache(void); +#endif +int foreach_mountpoint(foreach_mountpoint_t handler, void *arg); +int ForceUmountDev(struct Vnode *dev); +#endif diff --git a/src/kernel_liteos_a/fs/include/fs/vnode.h b/src/kernel_liteos_a/fs/include/fs/vnode.h new file mode 100644 index 00000000..63287166 --- /dev/null +++ b/src/kernel_liteos_a/fs/include/fs/vnode.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FS_VNODE_H_ +#define _FS_VNODE_H_ +#include "../../vfs/include/vnode.h" /* for hdf compatibility, should remove later */ +#endif /* !_VNODE_H_ */ diff --git a/src/kernel_liteos_a/fs/include/vfs_config.h b/src/kernel_liteos_a/fs/include/vfs_config.h new file mode 100644 index 00000000..eded5bad --- /dev/null +++ b/src/kernel_liteos_a/fs/include/vfs_config.h @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef _VFS_CONFIG_H_ +#define _VFS_CONFIG_H_ + +#include "los_config.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define PATH_MAX 256 +#define CONFIG_DISABLE_MQUEUE // disable posix mqueue inode configure + +/* file system config */ + +#define CONFIG_FS_WRITABLE // enable file system can be written +#define CONFIG_FS_READABLE // enable file system can be read +#define CONFIG_DEBUG_FS // enable vfs debug function + + +/* fatfs cache config */ +/* config block size for fat file system, only can be 0,32,64,128,256,512,1024 */ +#define CONFIG_FS_FAT_SECTOR_PER_BLOCK 64 + +/* config block num for fat file system */ +#define CONFIG_FS_FAT_READ_NUMS 7 +#define CONFIG_FS_FAT_BLOCK_NUMS 28 + +#ifdef LOSCFG_FS_FAT_CACHE_SYNC_THREAD + +/* config the priority of sync task */ + +#define CONFIG_FS_FAT_SYNC_THREAD_PRIO 10 + +/* config dirty ratio of bcache for fat file system */ + +#define CONFIG_FS_FAT_DIRTY_RATIO 60 + +/* config time interval of sync thread for fat file system, in milliseconds */ + +#define CONFIG_FS_FAT_SYNC_INTERVAL 5000 +#endif + +#define CONFIG_FS_FLASH_BLOCK_NUM 1 + +#define CONFIG_FS_MAX_LNK_CNT 40 + +/* nfs configure */ + +#define CONFIG_NFS_MACHINE_NAME "IPC" // nfs device name is IPC +#define CONFIG_NFS_MACHINE_NAME_SIZE 3 // size of nfs machine name + + +/* file descriptors configure */ + +#define CONFIG_NFILE_STREAMS 1 // enable file stream +#define CONFIG_STDIO_BUFFER_SIZE 0 +#define CONFIG_NUNGET_CHARS 0 +#define MIN_START_FD 3 // 0,1,2 are used for stdin,stdout,stderr respectively + +#define FD_SET_TOTAL_SIZE (FD_SETSIZE + CONFIG_NEXPANED_DESCRIPTORS) +#define FD_SETSIZE (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS) +#define CONFIG_NEXPANED_DESCRIPTORS (CONFIG_NTIME_DESCRIPTORS + CONFIG_NQUEUE_DESCRIPTORS) +#define TIMER_FD_OFFSET FD_SETSIZE +#define MQUEUE_FD_OFFSET (FD_SETSIZE + CONFIG_NTIME_DESCRIPTORS) +#define EPOLL_FD_OFFSET (FD_SETSIZE + CONFIG_NTIME_DESCRIPTORS + CONFIG_NQUEUE_DESCRIPTORS) + +/* net configure */ + +#ifdef LOSCFG_NET_LWIP_SACK // enable socket and net function +#include "lwip/lwipopts.h" +#define CONFIG_NSOCKET_DESCRIPTORS LWIP_CONFIG_NUM_SOCKETS // max numbers of socket descriptor + +/* max numbers of other descriptors except socket descriptors */ + +#define CONFIG_NFILE_DESCRIPTORS 512 +#define CONFIG_NET_SENDFILE 1 // enable sendfile function +#define CONFIG_NET_TCP 1 // enable sendfile and send function +#else +#define CONFIG_NSOCKET_DESCRIPTORS 0 +#define CONFIG_NFILE_DESCRIPTORS 512 +#define CONFIG_NET_SENDFILE 0 // disable sendfile function +#define CONFIG_NET_TCP 0 // disable sendfile and send function +#endif + +#define NR_OPEN_DEFAULT CONFIG_NFILE_DESCRIPTORS + +/* time configure */ + +#define CONFIG_NTIME_DESCRIPTORS 0 + +/* mqueue configure */ + +#define CONFIG_NQUEUE_DESCRIPTORS 256 + +/* directory configure */ + +#define VFS_USING_WORKDIR // enable current working directory + +#define CONFIG_EPOLL_DESCRIPTORS 32 + +/* permission configure */ +#define DEFAULT_DIR_MODE 0777 +#define DEFAULT_FILE_MODE 0666 + +#define MAX_DIRENT_NUM 14 // 14 means 4096 length buffer can store 14 dirent, see struct DIR + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ +#endif diff --git a/src/kernel_liteos_a/fs/jffs2/BUILD.gn b/src/kernel_liteos_a/fs/jffs2/BUILD.gn new file mode 100644 index 00000000..c184f753 --- /dev/null +++ b/src/kernel_liteos_a/fs/jffs2/BUILD.gn @@ -0,0 +1,116 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = defined(LOSCFG_FS_JFFS) +module_name = get_path_info(rebase_path("."), "name") +linux_path = rebase_path("$KERNEL_LINUX_DIR") +out_path = rebase_path(target_out_dir) + +kernel_module(module_name) { + patch_path = rebase_path(".") + cmd = "if [ -d ${out_path}/jffs2_build ]; then rm -r ${out_path}/jffs2_build; fi && mkdir -p ${out_path}/jffs2_build/fs" + cmd += " && cp ${linux_path}/fs/jffs2 ${out_path}/jffs2_build/fs/. -r" + cmd += " && pushd ${out_path}/jffs2_build/" + cmd += " && patch -p1 < ${patch_path}/jffs2.patch && popd" + exec_script("//build/lite/run_shell_cmd.py", [ cmd ]) + + sources = [ + "src/jffs2_hash.c", + "src/vfs_jffs2.c", + ] + + sources += [ + "${out_path}/jffs2_build/fs/jffs2/background.c", + "${out_path}/jffs2_build/fs/jffs2/build.c", + "${out_path}/jffs2_build/fs/jffs2/compr.c", + "${out_path}/jffs2_build/fs/jffs2/compr_rtime.c", + "${out_path}/jffs2_build/fs/jffs2/compr_rubin.c", + "${out_path}/jffs2_build/fs/jffs2/compr_zlib.c", + "${out_path}/jffs2_build/fs/jffs2/debug.c", + "${out_path}/jffs2_build/fs/jffs2/dir.c", + "${out_path}/jffs2_build/fs/jffs2/erase.c", + "${out_path}/jffs2_build/fs/jffs2/file.c", + "${out_path}/jffs2_build/fs/jffs2/fs.c", + "${out_path}/jffs2_build/fs/jffs2/gc.c", + "${out_path}/jffs2_build/fs/jffs2/malloc.c", + "${out_path}/jffs2_build/fs/jffs2/nodelist.c", + "${out_path}/jffs2_build/fs/jffs2/nodemgmt.c", + "${out_path}/jffs2_build/fs/jffs2/read.c", + "${out_path}/jffs2_build/fs/jffs2/readinode.c", + "${out_path}/jffs2_build/fs/jffs2/scan.c", + "${out_path}/jffs2_build/fs/jffs2/summary.c", + "${out_path}/jffs2_build/fs/jffs2/super.c", + "${out_path}/jffs2_build/fs/jffs2/write.c", + "${out_path}/jffs2_build/fs/jffs2/writev.c", + ] + + include_dirs = [ + "${out_path}/jffs2_build/fs", + "${out_path}/jffs2_build/fs/jffs2", + ] + + public_configs = [ ":public" ] + + deps = [ ":cp_jffs2_src" ] +} + +config("public") { + include_dirs = [ "include" ] +} + +action("cp_jffs2_src") { + script = "//build/lite/run_shell_cmd.py" + + outputs = [ + "${target_out_dir}/jffs2_build/fs/jffs2/background.c", + "${target_out_dir}/jffs2_build/fs/jffs2/build.c", + "${target_out_dir}/jffs2_build/fs/jffs2/compr.c", + "${target_out_dir}/jffs2_build/fs/jffs2/compr_rtime.c", + "${target_out_dir}/jffs2_build/fs/jffs2/compr_rubin.c", + "${target_out_dir}/jffs2_build/fs/jffs2/compr_zlib.c", + "${target_out_dir}/jffs2_build/fs/jffs2/debug.c", + "${target_out_dir}/jffs2_build/fs/jffs2/dir.c", + "${target_out_dir}/jffs2_build/fs/jffs2/erase.c", + "${target_out_dir}/jffs2_build/fs/jffs2/file.c", + "${target_out_dir}/jffs2_build/fs/jffs2/fs.c", + "${target_out_dir}/jffs2_build/fs/jffs2/gc.c", + "${target_out_dir}/jffs2_build/fs/jffs2/malloc.c", + "${target_out_dir}/jffs2_build/fs/jffs2/nodelist.c", + "${target_out_dir}/jffs2_build/fs/jffs2/nodemgmt.c", + "${target_out_dir}/jffs2_build/fs/jffs2/read.c", + "${target_out_dir}/jffs2_build/fs/jffs2/readinode.c", + "${target_out_dir}/jffs2_build/fs/jffs2/scan.c", + "${target_out_dir}/jffs2_build/fs/jffs2/summary.c", + "${target_out_dir}/jffs2_build/fs/jffs2/super.c", + "${target_out_dir}/jffs2_build/fs/jffs2/write.c", + "${target_out_dir}/jffs2_build/fs/jffs2/writev.c", + ] +} diff --git a/src/kernel_liteos_a/fs/jffs2/Kconfig b/src/kernel_liteos_a/fs/jffs2/Kconfig new file mode 100644 index 00000000..eac54f9d --- /dev/null +++ b/src/kernel_liteos_a/fs/jffs2/Kconfig @@ -0,0 +1,13 @@ +config FS_JFFS + bool "Enable JFFS2" + default y + depends on FS_VFS + help + Answer Y to enable LiteOS support jffs2 filesystem. + +config FS_JFFS2_SUMMARY + bool "Enable JFFS2 SUMMARY" + default n + depends on FS_JFFS + help + Answer Y to enable LiteOS jffs2 filesystem support Summary Patch. diff --git a/src/kernel_liteos_a/fs/jffs2/Makefile b/src/kernel_liteos_a/fs/jffs2/Makefile new file mode 100644 index 00000000..338db4cc --- /dev/null +++ b/src/kernel_liteos_a/fs/jffs2/Makefile @@ -0,0 +1,81 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +LINUX_PATH := $(LITEOSTOPDIR)/../linux/linux-5.10 +LOCAL_PATH := $(shell pwd) +TEMP_SRC_PATH := $(OUT)/jffs2_build + +LOCAL_SRCS := \ + $(TEMP_SRC_PATH)/fs/jffs2/background.c \ + $(TEMP_SRC_PATH)/fs/jffs2/build.c \ + $(TEMP_SRC_PATH)/fs/jffs2/compr.c \ + $(TEMP_SRC_PATH)/fs/jffs2/compr_rtime.c \ + $(TEMP_SRC_PATH)/fs/jffs2/compr_rubin.c \ + $(TEMP_SRC_PATH)/fs/jffs2/compr_zlib.c \ + $(TEMP_SRC_PATH)/fs/jffs2/debug.c \ + $(TEMP_SRC_PATH)/fs/jffs2/dir.c \ + $(TEMP_SRC_PATH)/fs/jffs2/erase.c \ + $(TEMP_SRC_PATH)/fs/jffs2/file.c \ + $(TEMP_SRC_PATH)/fs/jffs2/fs.c \ + $(TEMP_SRC_PATH)/fs/jffs2/gc.c \ + $(TEMP_SRC_PATH)/fs/jffs2/malloc.c \ + $(TEMP_SRC_PATH)/fs/jffs2/nodelist.c \ + $(TEMP_SRC_PATH)/fs/jffs2/nodemgmt.c \ + $(TEMP_SRC_PATH)/fs/jffs2/read.c \ + $(TEMP_SRC_PATH)/fs/jffs2/readinode.c \ + $(TEMP_SRC_PATH)/fs/jffs2/scan.c \ + $(TEMP_SRC_PATH)/fs/jffs2/summary.c \ + $(TEMP_SRC_PATH)/fs/jffs2/super.c \ + $(TEMP_SRC_PATH)/fs/jffs2/write.c \ + $(TEMP_SRC_PATH)/fs/jffs2/writev.c \ + $(LOCAL_PATH)/src/jffs2_hash.c \ + $(LOCAL_PATH)/src/vfs_jffs2.c \ + +LOCAL_INCLUDE := \ + -I $(LITEOSTOPDIR)/fs/jffs2/include \ + -I $(TEMP_SRC_PATH)/fs/jffs2 \ + -I $(TEMP_SRC_PATH)/fs +LOCAL_FLAGS := $(LOCAL_INCLUDE) + +.PHONY: patch patch_clean +$(LOCAL_SRCS): patch + +patch: patch_clean + cp $(LINUX_PATH)/fs/jffs2 $(TEMP_SRC_PATH)/fs/. -r + cd $(TEMP_SRC_PATH) && patch -p1 < $(LOCAL_PATH)/jffs2.patch + +patch_clean: + $(HIDE) $(RM) -rf $(TEMP_SRC_PATH) + +include $(MODULE) + diff --git a/src/kernel_liteos_a/fs/jffs2/include/jffs2_hash.h b/src/kernel_liteos_a/fs/jffs2/include/jffs2_hash.h new file mode 100644 index 00000000..8da07117 --- /dev/null +++ b/src/kernel_liteos_a/fs/jffs2/include/jffs2_hash.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __JFFS2_HASH_H__ +#define __JFFS2_HASH_H__ + +#include "vfs_jffs2.h" +#include "los_mux.h" +#include "los_list.h" +#include "jffs2_fs_i.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +int Jffs2HashInit(LosMux *lock, LOS_DL_LIST *heads); +int Jffs2HashDeinit(LosMux *lock); +void Jffs2HashDump(LosMux *lock, LOS_DL_LIST *heads); +int Jffs2HashGet(LosMux *lock, LOS_DL_LIST *heads, const void *sb, const uint32_t ino, struct jffs2_inode **ppNode); +void Jffs2HashRemove(LosMux *lock, struct jffs2_inode *node); +int Jffs2HashInsert(LosMux *lock, LOS_DL_LIST *heads, struct jffs2_inode *node, const uint32_t ino); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + + +#endif diff --git a/src/kernel_liteos_a/fs/jffs2/include/vfs_jffs2.h b/src/kernel_liteos_a/fs/jffs2/include/vfs_jffs2.h new file mode 100644 index 00000000..1a704b91 --- /dev/null +++ b/src/kernel_liteos_a/fs/jffs2/include/vfs_jffs2.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __VFS_JFFS2_H__ +#define __VFS_JFFS2_H__ + +#include +#include +#include "los_config.h" +#include "los_typedef.h" +#include "los_list.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#ifndef NOR_FLASH_BOOT_SIZE +#define NOR_FLASH_BOOT_SIZE 0x100000 +#endif + +#define BLOCK_SIZE 4096 +#define JFFS2_NODE_HASH_BUCKETS 128 +#define JFFS2_NODE_HASH_MASK (JFFS2_NODE_HASH_BUCKETS - 1) + + +#define JFFS2_WAITING_FOREVER -1 /* Block forever until get resource. */ + +/* block/char not support */ +#define JFFS2_F_I_RDEV_MIN(f) (0) +#define JFFS2_F_I_RDEV_MAJ(f) (0) + +static inline unsigned int full_name_hash(const unsigned char *name, unsigned int len) +{ + unsigned hash = 0; + while (len--) { + hash = (hash << 4) | (hash >> 28); + hash ^= *(name++); + } + return hash; +} + +int Jffs2MutexCreate(void); +void Jffs2MutexDelete(void); +void Jffs2NodeLock(void); /* lock for inode ops */ +void Jffs2NodeUnlock(void); +time_t Jffs2CurSec(void); + + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/src/kernel_liteos_a/fs/jffs2/jffs2.patch b/src/kernel_liteos_a/fs/jffs2/jffs2.patch new file mode 100644 index 00000000..eba19047 --- /dev/null +++ b/src/kernel_liteos_a/fs/jffs2/jffs2.patch @@ -0,0 +1,10167 @@ +diff -Nupr old/fs/jffs2/acl.c new/fs/jffs2/acl.c +--- old/fs/jffs2/acl.c 2022-05-09 17:15:24.350000000 +0800 ++++ new/fs/jffs2/acl.c 1970-01-01 08:00:00.000000000 +0800 +@@ -1,307 +0,0 @@ +-/* +- * JFFS2 -- Journalling Flash File System, Version 2. +- * +- * Copyright © 2006 NEC Corporation +- * +- * Created by KaiGai Kohei +- * +- * For licensing information, see the file 'LICENCE' in this directory. +- * +- */ +- +-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include "nodelist.h" +- +-static size_t jffs2_acl_size(int count) +-{ +- if (count <= 4) { +- return sizeof(struct jffs2_acl_header) +- + count * sizeof(struct jffs2_acl_entry_short); +- } else { +- return sizeof(struct jffs2_acl_header) +- + 4 * sizeof(struct jffs2_acl_entry_short) +- + (count - 4) * sizeof(struct jffs2_acl_entry); +- } +-} +- +-static int jffs2_acl_count(size_t size) +-{ +- size_t s; +- +- size -= sizeof(struct jffs2_acl_header); +- if (size < 4 * sizeof(struct jffs2_acl_entry_short)) { +- if (size % sizeof(struct jffs2_acl_entry_short)) +- return -1; +- return size / sizeof(struct jffs2_acl_entry_short); +- } else { +- s = size - 4 * sizeof(struct jffs2_acl_entry_short); +- if (s % sizeof(struct jffs2_acl_entry)) +- return -1; +- return s / sizeof(struct jffs2_acl_entry) + 4; +- } +-} +- +-static struct posix_acl *jffs2_acl_from_medium(void *value, size_t size) +-{ +- void *end = value + size; +- struct jffs2_acl_header *header = value; +- struct jffs2_acl_entry *entry; +- struct posix_acl *acl; +- uint32_t ver; +- int i, count; +- +- if (!value) +- return NULL; +- if (size < sizeof(struct jffs2_acl_header)) +- return ERR_PTR(-EINVAL); +- ver = je32_to_cpu(header->a_version); +- if (ver != JFFS2_ACL_VERSION) { +- JFFS2_WARNING("Invalid ACL version. (=%u)\n", ver); +- return ERR_PTR(-EINVAL); +- } +- +- value += sizeof(struct jffs2_acl_header); +- count = jffs2_acl_count(size); +- if (count < 0) +- return ERR_PTR(-EINVAL); +- if (count == 0) +- return NULL; +- +- acl = posix_acl_alloc(count, GFP_KERNEL); +- if (!acl) +- return ERR_PTR(-ENOMEM); +- +- for (i=0; i < count; i++) { +- entry = value; +- if (value + sizeof(struct jffs2_acl_entry_short) > end) +- goto fail; +- acl->a_entries[i].e_tag = je16_to_cpu(entry->e_tag); +- acl->a_entries[i].e_perm = je16_to_cpu(entry->e_perm); +- switch (acl->a_entries[i].e_tag) { +- case ACL_USER_OBJ: +- case ACL_GROUP_OBJ: +- case ACL_MASK: +- case ACL_OTHER: +- value += sizeof(struct jffs2_acl_entry_short); +- break; +- +- case ACL_USER: +- value += sizeof(struct jffs2_acl_entry); +- if (value > end) +- goto fail; +- acl->a_entries[i].e_uid = +- make_kuid(&init_user_ns, +- je32_to_cpu(entry->e_id)); +- break; +- case ACL_GROUP: +- value += sizeof(struct jffs2_acl_entry); +- if (value > end) +- goto fail; +- acl->a_entries[i].e_gid = +- make_kgid(&init_user_ns, +- je32_to_cpu(entry->e_id)); +- break; +- +- default: +- goto fail; +- } +- } +- if (value != end) +- goto fail; +- return acl; +- fail: +- posix_acl_release(acl); +- return ERR_PTR(-EINVAL); +-} +- +-static void *jffs2_acl_to_medium(const struct posix_acl *acl, size_t *size) +-{ +- struct jffs2_acl_header *header; +- struct jffs2_acl_entry *entry; +- void *e; +- size_t i; +- +- *size = jffs2_acl_size(acl->a_count); +- header = kmalloc(struct_size(header, a_entries, acl->a_count), +- GFP_KERNEL); +- if (!header) +- return ERR_PTR(-ENOMEM); +- header->a_version = cpu_to_je32(JFFS2_ACL_VERSION); +- e = header + 1; +- for (i=0; i < acl->a_count; i++) { +- const struct posix_acl_entry *acl_e = &acl->a_entries[i]; +- entry = e; +- entry->e_tag = cpu_to_je16(acl_e->e_tag); +- entry->e_perm = cpu_to_je16(acl_e->e_perm); +- switch(acl_e->e_tag) { +- case ACL_USER: +- entry->e_id = cpu_to_je32( +- from_kuid(&init_user_ns, acl_e->e_uid)); +- e += sizeof(struct jffs2_acl_entry); +- break; +- case ACL_GROUP: +- entry->e_id = cpu_to_je32( +- from_kgid(&init_user_ns, acl_e->e_gid)); +- e += sizeof(struct jffs2_acl_entry); +- break; +- +- case ACL_USER_OBJ: +- case ACL_GROUP_OBJ: +- case ACL_MASK: +- case ACL_OTHER: +- e += sizeof(struct jffs2_acl_entry_short); +- break; +- +- default: +- goto fail; +- } +- } +- return header; +- fail: +- kfree(header); +- return ERR_PTR(-EINVAL); +-} +- +-struct posix_acl *jffs2_get_acl(struct inode *inode, int type) +-{ +- struct posix_acl *acl; +- char *value = NULL; +- int rc, xprefix; +- +- switch (type) { +- case ACL_TYPE_ACCESS: +- xprefix = JFFS2_XPREFIX_ACL_ACCESS; +- break; +- case ACL_TYPE_DEFAULT: +- xprefix = JFFS2_XPREFIX_ACL_DEFAULT; +- break; +- default: +- BUG(); +- } +- rc = do_jffs2_getxattr(inode, xprefix, "", NULL, 0); +- if (rc > 0) { +- value = kmalloc(rc, GFP_KERNEL); +- if (!value) +- return ERR_PTR(-ENOMEM); +- rc = do_jffs2_getxattr(inode, xprefix, "", value, rc); +- } +- if (rc > 0) { +- acl = jffs2_acl_from_medium(value, rc); +- } else if (rc == -ENODATA || rc == -ENOSYS) { +- acl = NULL; +- } else { +- acl = ERR_PTR(rc); +- } +- kfree(value); +- return acl; +-} +- +-static int __jffs2_set_acl(struct inode *inode, int xprefix, struct posix_acl *acl) +-{ +- char *value = NULL; +- size_t size = 0; +- int rc; +- +- if (acl) { +- value = jffs2_acl_to_medium(acl, &size); +- if (IS_ERR(value)) +- return PTR_ERR(value); +- } +- rc = do_jffs2_setxattr(inode, xprefix, "", value, size, 0); +- if (!value && rc == -ENODATA) +- rc = 0; +- kfree(value); +- +- return rc; +-} +- +-int jffs2_set_acl(struct inode *inode, struct posix_acl *acl, int type) +-{ +- int rc, xprefix; +- +- switch (type) { +- case ACL_TYPE_ACCESS: +- xprefix = JFFS2_XPREFIX_ACL_ACCESS; +- if (acl) { +- umode_t mode; +- +- rc = posix_acl_update_mode(inode, &mode, &acl); +- if (rc) +- return rc; +- if (inode->i_mode != mode) { +- struct iattr attr; +- +- attr.ia_valid = ATTR_MODE | ATTR_CTIME; +- attr.ia_mode = mode; +- attr.ia_ctime = current_time(inode); +- rc = jffs2_do_setattr(inode, &attr); +- if (rc < 0) +- return rc; +- } +- } +- break; +- case ACL_TYPE_DEFAULT: +- xprefix = JFFS2_XPREFIX_ACL_DEFAULT; +- if (!S_ISDIR(inode->i_mode)) +- return acl ? -EACCES : 0; +- break; +- default: +- return -EINVAL; +- } +- rc = __jffs2_set_acl(inode, xprefix, acl); +- if (!rc) +- set_cached_acl(inode, type, acl); +- return rc; +-} +- +-int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, umode_t *i_mode) +-{ +- struct posix_acl *default_acl, *acl; +- int rc; +- +- cache_no_acl(inode); +- +- rc = posix_acl_create(dir_i, i_mode, &default_acl, &acl); +- if (rc) +- return rc; +- +- if (default_acl) { +- set_cached_acl(inode, ACL_TYPE_DEFAULT, default_acl); +- posix_acl_release(default_acl); +- } +- if (acl) { +- set_cached_acl(inode, ACL_TYPE_ACCESS, acl); +- posix_acl_release(acl); +- } +- return 0; +-} +- +-int jffs2_init_acl_post(struct inode *inode) +-{ +- int rc; +- +- if (inode->i_default_acl) { +- rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_DEFAULT, inode->i_default_acl); +- if (rc) +- return rc; +- } +- +- if (inode->i_acl) { +- rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_ACCESS, inode->i_acl); +- if (rc) +- return rc; +- } +- +- return 0; +-} +diff -Nupr old/fs/jffs2/acl.h new/fs/jffs2/acl.h +--- old/fs/jffs2/acl.h 2022-05-09 17:22:53.000000000 +0800 ++++ new/fs/jffs2/acl.h 2022-05-10 14:52:22.930000000 +0800 +@@ -8,6 +8,8 @@ + * For licensing information, see the file 'LICENCE' in this directory. + * + */ ++#ifndef _JFFS2_ACL_H_ ++#define _JFFS2_ACL_H_ + + struct jffs2_acl_entry { + jint16_t e_tag; +@@ -27,11 +29,6 @@ struct jffs2_acl_header { + + #ifdef CONFIG_JFFS2_FS_POSIX_ACL + +-struct posix_acl *jffs2_get_acl(struct inode *inode, int type); +-int jffs2_set_acl(struct inode *inode, struct posix_acl *acl, int type); +-extern int jffs2_init_acl_pre(struct inode *, struct inode *, umode_t *); +-extern int jffs2_init_acl_post(struct inode *); +- + #else + + #define jffs2_get_acl (NULL) +@@ -40,3 +37,4 @@ extern int jffs2_init_acl_post(struct in + #define jffs2_init_acl_post(inode) (0) + + #endif /* CONFIG_JFFS2_FS_POSIX_ACL */ ++#endif /* _JFFS2_ACL_H_ */ +diff -Nupr old/fs/jffs2/background.c new/fs/jffs2/background.c +--- old/fs/jffs2/background.c 2022-05-09 17:22:53.000000000 +0800 ++++ new/fs/jffs2/background.c 2022-05-10 14:53:26.200000000 +0800 +@@ -10,156 +10,113 @@ + * + */ + +-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +- + #include +-#include +-#include +-#include +-#include +-#include +-#include ++#include + #include "nodelist.h" ++#include "vfs_jffs2.h" ++#include "mtd_partition.h" + ++#define GC_THREAD_FLAG_TRIG 1 ++#define GC_THREAD_FLAG_STOP 2 ++#define GC_THREAD_FLAG_HAS_EXIT 4 + +-static int jffs2_garbage_collect_thread(void *); ++extern struct MtdNorDev jffs2_dev_list[CONFIG_MTD_PATTITION_NUM]; ++static void jffs2_garbage_collect_thread(unsigned long data); + + void jffs2_garbage_collect_trigger(struct jffs2_sb_info *c) + { +- assert_spin_locked(&c->erase_completion_lock); +- if (c->gc_task && jffs2_thread_should_wake(c)) +- send_sig(SIGHUP, c->gc_task, 1); ++ struct super_block *sb = OFNI_BS_2SFFJ(c); ++ /* Wake up the thread */ ++ jffs2_dbg(1, "jffs2_garbage_collect_trigger\n"); ++ LOS_EventWrite(&sb->s_gc_thread_flags, GC_THREAD_FLAG_TRIG); + } + + /* This must only ever be called when no GC thread is currently running */ +-int jffs2_start_garbage_collect_thread(struct jffs2_sb_info *c) ++void jffs2_start_garbage_collect_thread(struct jffs2_sb_info *c) + { +- struct task_struct *tsk; +- int ret = 0; ++ struct super_block *sb = OFNI_BS_2SFFJ(c); ++ TSK_INIT_PARAM_S stGcTask; + +- BUG_ON(c->gc_task); ++ if (c == NULL) ++ return; + +- init_completion(&c->gc_thread_start); +- init_completion(&c->gc_thread_exit); ++ if (sb->s_root == NULL) ++ return; + +- tsk = kthread_run(jffs2_garbage_collect_thread, c, "jffs2_gcd_mtd%d", c->mtd->index); +- if (IS_ERR(tsk)) { +- pr_warn("fork failed for JFFS2 garbage collect thread: %ld\n", +- -PTR_ERR(tsk)); +- complete(&c->gc_thread_exit); +- ret = PTR_ERR(tsk); +- } else { +- /* Wait for it... */ +- jffs2_dbg(1, "Garbage collect thread is pid %d\n", tsk->pid); +- wait_for_completion(&c->gc_thread_start); +- ret = tsk->pid; ++ LOS_EventInit(&sb->s_gc_thread_flags); ++ ++ /* Start the thread. Doesn't matter if it fails -- it's only an ++ * optimisation anyway */ ++ (void)memset_s(&stGcTask, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); ++ ++ stGcTask.pfnTaskEntry = (TSK_ENTRY_FUNC)jffs2_garbage_collect_thread; ++ stGcTask.auwArgs[0] = (UINTPTR)c; ++ stGcTask.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; ++ stGcTask.pcName = "jffs2_gc_thread"; ++#ifdef LOSCFG_KERNEL_SMP ++ unsigned int i; ++ for (i = 0; i < CONFIG_MTD_PATTITION_NUM; i++) { ++ if (sb->s_dev == &jffs2_dev_list[i]) ++ break; + } ++ stGcTask.usCpuAffiMask = CPUID_TO_AFFI_MASK(i % LOSCFG_KERNEL_CORE_NUM); ++#endif ++ stGcTask.usTaskPrio = JFFS2_GC_THREAD_PRIORITY; + +- return ret; ++ if (LOS_TaskCreate(&sb->s_gc_thread, &stGcTask)) ++ JFFS2_ERROR("Create gc task failed!!!\n"); + } + + void jffs2_stop_garbage_collect_thread(struct jffs2_sb_info *c) + { +- int wait = 0; +- spin_lock(&c->erase_completion_lock); +- if (c->gc_task) { +- jffs2_dbg(1, "Killing GC task %d\n", c->gc_task->pid); +- send_sig(SIGKILL, c->gc_task, 1); +- wait = 1; +- } +- spin_unlock(&c->erase_completion_lock); +- if (wait) +- wait_for_completion(&c->gc_thread_exit); ++ struct super_block *sb = OFNI_BS_2SFFJ(c); ++ ++ JFFS2_DEBUG("jffs2_stop_garbage_collect_thread\n"); ++ /* Stop the thread and wait for it if necessary */ ++ ++ LOS_EventWrite(&sb->s_gc_thread_flags, GC_THREAD_FLAG_STOP); ++ ++ JFFS2_DEBUG("jffs2_stop_garbage_collect_thread wait\n"); ++ ++ (void)LOS_EventRead(&sb->s_gc_thread_flags, ++ GC_THREAD_FLAG_HAS_EXIT, ++ LOS_WAITMODE_OR | LOS_WAITMODE_CLR, ++ LOS_WAIT_FOREVER); ++ ++ // Kill and free the resources ... this is safe due to the flag ++ // from the thread. ++ (void)LOS_TaskDelete(sb->s_gc_thread); ++ (void)LOS_EventWrite(&sb->s_gc_thread_flags, 0xFFFFFFFF); + } + +-static int jffs2_garbage_collect_thread(void *_c) ++static void jffs2_garbage_collect_thread(unsigned long data) + { +- struct jffs2_sb_info *c = _c; +- sigset_t hupmask; ++ struct jffs2_sb_info *c = (struct jffs2_sb_info *)data; ++ struct super_block *sb = OFNI_BS_2SFFJ(c); ++ unsigned int flag = 0; ++ ++ jffs2_dbg(1, "jffs2_garbage_collect_thread START\n"); ++ while(1) { ++ flag = LOS_EventRead(&sb->s_gc_thread_flags, ++ GC_THREAD_FLAG_TRIG | GC_THREAD_FLAG_STOP, ++ LOS_WAITMODE_OR | LOS_WAITMODE_CLR, ++ LOS_WAIT_FOREVER ++ ); ++ if (flag & GC_THREAD_FLAG_STOP) ++ break; + +- siginitset(&hupmask, sigmask(SIGHUP)); +- allow_signal(SIGKILL); +- allow_signal(SIGSTOP); +- allow_signal(SIGHUP); +- +- c->gc_task = current; +- complete(&c->gc_thread_start); +- +- set_user_nice(current, 10); +- +- set_freezable(); +- for (;;) { +- sigprocmask(SIG_UNBLOCK, &hupmask, NULL); +- again: +- spin_lock(&c->erase_completion_lock); +- if (!jffs2_thread_should_wake(c)) { +- set_current_state (TASK_INTERRUPTIBLE); +- spin_unlock(&c->erase_completion_lock); +- jffs2_dbg(1, "%s(): sleeping...\n", __func__); +- schedule(); +- } else { +- spin_unlock(&c->erase_completion_lock); +- } +- /* Problem - immediately after bootup, the GCD spends a lot +- * of time in places like jffs2_kill_fragtree(); so much so +- * that userspace processes (like gdm and X) are starved +- * despite plenty of cond_resched()s and renicing. Yield() +- * doesn't help, either (presumably because userspace and GCD +- * are generally competing for a higher latency resource - +- * disk). +- * This forces the GCD to slow the hell down. Pulling an +- * inode in with read_inode() is much preferable to having +- * the GC thread get there first. */ +- schedule_timeout_interruptible(msecs_to_jiffies(50)); +- +- if (kthread_should_stop()) { +- jffs2_dbg(1, "%s(): kthread_stop() called\n", __func__); +- goto die; +- } ++ jffs2_dbg(1, "jffs2: GC THREAD GC BEGIN\n"); + +- /* Put_super will send a SIGKILL and then wait on the sem. +- */ +- while (signal_pending(current) || freezing(current)) { +- unsigned long signr; +- +- if (try_to_freeze()) +- goto again; +- +- signr = kernel_dequeue_signal(); +- +- switch(signr) { +- case SIGSTOP: +- jffs2_dbg(1, "%s(): SIGSTOP received\n", +- __func__); +- kernel_signal_stop(); +- break; +- +- case SIGKILL: +- jffs2_dbg(1, "%s(): SIGKILL received\n", +- __func__); +- goto die; +- +- case SIGHUP: +- jffs2_dbg(1, "%s(): SIGHUP received\n", +- __func__); +- break; +- default: +- jffs2_dbg(1, "%s(): signal %ld received\n", +- __func__, signr); +- } +- } +- /* We don't want SIGHUP to interrupt us. STOP and KILL are OK though. */ +- sigprocmask(SIG_BLOCK, &hupmask, NULL); ++ if (sb->s_root == NULL) ++ return; + +- jffs2_dbg(1, "%s(): pass\n", __func__); + if (jffs2_garbage_collect_pass(c) == -ENOSPC) { +- pr_notice("No space for garbage collection. Aborting GC thread\n"); +- goto die; ++ PRINTK("No space for garbage collection. " ++ "Aborting JFFS2 GC thread\n"); ++ break; + } ++ jffs2_dbg(1, "jffs2: GC THREAD GC END\n"); + } +- die: +- spin_lock(&c->erase_completion_lock); +- c->gc_task = NULL; +- spin_unlock(&c->erase_completion_lock); +- complete_and_exit(&c->gc_thread_exit, 0); ++ JFFS2_DEBUG("jffs2_garbage_collect_thread EXIT\n"); ++ LOS_EventWrite(&sb->s_gc_thread_flags, GC_THREAD_FLAG_HAS_EXIT); + } +diff -Nupr old/fs/jffs2/build.c new/fs/jffs2/build.c +--- old/fs/jffs2/build.c 2022-05-09 17:22:53.000000000 +0800 ++++ new/fs/jffs2/build.c 2022-05-10 15:01:38.800000000 +0800 +@@ -10,15 +10,13 @@ + * + */ + +-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +- ++#include + #include + #include + #include +-#include +-#include +-#include /* kvfree() */ ++#include + #include "nodelist.h" ++#include "los_exc.h" + + static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *, + struct jffs2_inode_cache *, struct jffs2_full_dirent **); +@@ -50,8 +48,7 @@ next_inode(int *i, struct jffs2_inode_ca + + + static void jffs2_build_inode_pass1(struct jffs2_sb_info *c, +- struct jffs2_inode_cache *ic, +- int *dir_hardlinks) ++ struct jffs2_inode_cache *ic) + { + struct jffs2_full_dirent *fd; + +@@ -372,20 +369,24 @@ int jffs2_do_mount_fs(struct jffs2_sb_in + int ret; + int i; + int size; ++ struct super_block *sb; ++ struct MtdNorDev *device; + + c->free_size = c->flash_size; + c->nr_blocks = c->flash_size / c->sector_size; +- size = sizeof(struct jffs2_eraseblock) * c->nr_blocks; ++ sb = OFNI_BS_2SFFJ(c); ++ device = (struct MtdNorDev *)(sb->s_dev); ++ size = sizeof(struct jffs2_eraseblock) *(c->nr_blocks + device->blockStart); + #ifndef __ECOS + if (jffs2_blocks_use_vmalloc(c)) +- c->blocks = vzalloc(size); ++ c->blocks = malloc(size); + else + #endif + c->blocks = kzalloc(size, GFP_KERNEL); + if (!c->blocks) + return -ENOMEM; + +- for (i=0; inr_blocks; i++) { ++ for (i = device->blockStart; i < c->nr_blocks + device->blockStart; i++) { + INIT_LIST_HEAD(&c->blocks[i].list); + c->blocks[i].offset = i * c->sector_size; + c->blocks[i].free_size = c->sector_size; +diff -Nupr old/fs/jffs2/compr.c new/fs/jffs2/compr.c +--- old/fs/jffs2/compr.c 2022-05-09 17:22:53.000000000 +0800 ++++ new/fs/jffs2/compr.c 2022-05-10 15:02:17.440000000 +0800 +@@ -12,14 +12,13 @@ + * + */ + +-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +- + #include "compr.h" ++#include "jffs2.h" ++#include "user_copy.h" + +-static DEFINE_SPINLOCK(jffs2_compressor_list_lock); +- ++static spinlock_t jffs2_compressor_list_lock; + /* Available compressors are on this list */ +-static LIST_HEAD(jffs2_compressor_list); ++static LINUX_LIST_HEAD(jffs2_compressor_list); + + /* Actual compression mode */ + static int jffs2_compression_mode = JFFS2_COMPR_MODE_PRIORITY; +@@ -71,15 +70,15 @@ static int jffs2_is_best_compression(str + * could not be compressed; probably because we couldn't find the requested + * compression mode. + */ +-static int jffs2_selected_compress(u8 compr, unsigned char *data_in, +- unsigned char **cpage_out, u32 *datalen, u32 *cdatalen) ++static int jffs2_selected_compress(uint8_t compr, unsigned char *data_in, ++ unsigned char **cpage_out, uint32_t *datalen, uint32_t *cdatalen) + { + struct jffs2_compressor *this; + int err, ret = JFFS2_COMPR_NONE; + uint32_t orig_slen, orig_dlen; +- char *output_buf; ++ unsigned char *output_buf; + +- output_buf = kmalloc(*cdatalen, GFP_KERNEL); ++ output_buf = kmalloc(*cdatalen,GFP_KERNEL); + if (!output_buf) { + pr_warn("No memory for compressor allocation. Compression failed.\n"); + return ret; +@@ -265,11 +264,16 @@ int jffs2_decompress(struct jffs2_sb_inf + switch (comprtype & 0xff) { + case JFFS2_COMPR_NONE: + /* This should be special-cased elsewhere, but we might as well deal with it */ +- memcpy(data_out, cdata_in, datalen); ++ if (LOS_CopyFromKernel(data_out, datalen, cdata_in, datalen) != 0) { ++ return -EFAULT; ++ } + none_stat_decompr_blocks++; + break; + case JFFS2_COMPR_ZERO: +- memset(data_out, 0, datalen); ++ ret = LOS_UserMemClear(data_out, datalen); ++ if (ret != 0) { ++ return ret; ++ } + break; + default: + spin_lock(&jffs2_compressor_list_lock); +diff -Nupr old/fs/jffs2/compr.h new/fs/jffs2/compr.h +--- old/fs/jffs2/compr.h 2022-05-09 17:22:53.000000000 +0800 ++++ new/fs/jffs2/compr.h 2022-05-10 15:02:50.040000000 +0800 +@@ -13,18 +13,20 @@ + #define __JFFS2_COMPR_H__ + + #include +-#include + #include + #include + #include + #include + #include +-#include +-#include +-#include "jffs2_fs_i.h" +-#include "jffs2_fs_sb.h" ++#include + #include "nodelist.h" + ++#ifdef __cplusplus ++#if __cplusplus ++extern "C" { ++#endif /* __cplusplus */ ++#endif /* __cplusplus */ ++ + #define JFFS2_RUBINMIPS_PRIORITY 10 + #define JFFS2_DYNRUBIN_PRIORITY 20 + #define JFFS2_LZARI_PRIORITY 30 +@@ -102,4 +104,10 @@ int jffs2_lzo_init(void); + void jffs2_lzo_exit(void); + #endif + ++#ifdef __cplusplus ++#if __cplusplus ++} ++#endif /* __cplusplus */ ++#endif /* __cplusplus */ ++ + #endif /* __JFFS2_COMPR_H__ */ +diff -Nupr old/fs/jffs2/compr_lzo.c new/fs/jffs2/compr_lzo.c +--- old/fs/jffs2/compr_lzo.c 2022-05-09 17:15:24.350000000 +0800 ++++ new/fs/jffs2/compr_lzo.c 1970-01-01 08:00:00.000000000 +0800 +@@ -1,110 +0,0 @@ +-/* +- * JFFS2 -- Journalling Flash File System, Version 2. +- * +- * Copyright © 2007 Nokia Corporation. All rights reserved. +- * Copyright © 2004-2010 David Woodhouse +- * +- * Created by Richard Purdie +- * +- * For licensing information, see the file 'LICENCE' in this directory. +- * +- */ +- +-#include +-#include +-#include +-#include +-#include +-#include "compr.h" +- +-static void *lzo_mem; +-static void *lzo_compress_buf; +-static DEFINE_MUTEX(deflate_mutex); /* for lzo_mem and lzo_compress_buf */ +- +-static void free_workspace(void) +-{ +- vfree(lzo_mem); +- vfree(lzo_compress_buf); +-} +- +-static int __init alloc_workspace(void) +-{ +- lzo_mem = vmalloc(LZO1X_MEM_COMPRESS); +- lzo_compress_buf = vmalloc(lzo1x_worst_compress(PAGE_SIZE)); +- +- if (!lzo_mem || !lzo_compress_buf) { +- free_workspace(); +- return -ENOMEM; +- } +- +- return 0; +-} +- +-static int jffs2_lzo_compress(unsigned char *data_in, unsigned char *cpage_out, +- uint32_t *sourcelen, uint32_t *dstlen) +-{ +- size_t compress_size; +- int ret; +- +- mutex_lock(&deflate_mutex); +- ret = lzo1x_1_compress(data_in, *sourcelen, lzo_compress_buf, &compress_size, lzo_mem); +- if (ret != LZO_E_OK) +- goto fail; +- +- if (compress_size > *dstlen) +- goto fail; +- +- memcpy(cpage_out, lzo_compress_buf, compress_size); +- mutex_unlock(&deflate_mutex); +- +- *dstlen = compress_size; +- return 0; +- +- fail: +- mutex_unlock(&deflate_mutex); +- return -1; +-} +- +-static int jffs2_lzo_decompress(unsigned char *data_in, unsigned char *cpage_out, +- uint32_t srclen, uint32_t destlen) +-{ +- size_t dl = destlen; +- int ret; +- +- ret = lzo1x_decompress_safe(data_in, srclen, cpage_out, &dl); +- +- if (ret != LZO_E_OK || dl != destlen) +- return -1; +- +- return 0; +-} +- +-static struct jffs2_compressor jffs2_lzo_comp = { +- .priority = JFFS2_LZO_PRIORITY, +- .name = "lzo", +- .compr = JFFS2_COMPR_LZO, +- .compress = &jffs2_lzo_compress, +- .decompress = &jffs2_lzo_decompress, +- .disabled = 0, +-}; +- +-int __init jffs2_lzo_init(void) +-{ +- int ret; +- +- ret = alloc_workspace(); +- if (ret < 0) +- return ret; +- +- ret = jffs2_register_compressor(&jffs2_lzo_comp); +- if (ret) +- free_workspace(); +- +- return ret; +-} +- +-void jffs2_lzo_exit(void) +-{ +- jffs2_unregister_compressor(&jffs2_lzo_comp); +- free_workspace(); +-} +diff -Nupr old/fs/jffs2/compr_rtime.c new/fs/jffs2/compr_rtime.c +--- old/fs/jffs2/compr_rtime.c 2022-05-09 17:22:53.000000000 +0800 ++++ new/fs/jffs2/compr_rtime.c 2022-05-10 15:05:05.970000000 +0800 +@@ -25,7 +25,7 @@ + #include + #include + #include +-#include ++#include "jffs2.h" + #include "compr.h" + + /* _compress returns the compressed size, -1 if bigger */ +diff -Nupr old/fs/jffs2/compr_rubin.c new/fs/jffs2/compr_rubin.c +--- old/fs/jffs2/compr_rubin.c 2022-05-09 17:22:53.000000000 +0800 ++++ new/fs/jffs2/compr_rubin.c 2022-05-10 15:05:51.830000000 +0800 +@@ -10,15 +10,12 @@ + * + */ + +-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +- + #include + #include +-#include + #include ++#include "jffs2.h" + #include "compr.h" + +- + #define RUBIN_REG_SIZE 16 + #define UPPER_BIT_RUBIN (((long) 1)<<(RUBIN_REG_SIZE-1)) + #define LOWER_BITS_RUBIN ((((long) 1)<<(RUBIN_REG_SIZE-1))-1) +@@ -48,7 +45,7 @@ static inline void init_pushpull(struct + unsigned buflen, unsigned ofs, + unsigned reserve) + { +- pp->buf = buf; ++ pp->buf = (unsigned char *)buf; + pp->buflen = buflen; + pp->ofs = ofs; + pp->reserve = reserve; +@@ -267,7 +264,7 @@ static int rubin_do_compress(int bit_div + int pos=0; + struct rubin_state rs; + +- init_pushpull(&rs.pp, cpage_out, *dstlen * 8, 0, 32); ++ init_pushpull(&rs.pp, (char *)cpage_out, *dstlen * 8, 0, 32); + + init_rubin(&rs, bit_divider, bits); + +@@ -366,14 +363,14 @@ static int jffs2_dynrubin_compress(unsig + } + + static void rubin_do_decompress(int bit_divider, int *bits, +- unsigned char *cdata_in, ++ unsigned char *cdata_in, + unsigned char *page_out, uint32_t srclen, + uint32_t destlen) + { + int outpos = 0; + struct rubin_state rs; + +- init_pushpull(&rs.pp, cdata_in, srclen, 0, 0); ++ init_pushpull(&rs.pp, (char *)cdata_in, srclen, 0, 0); + init_decode(&rs, bit_divider, bits); + + while (outpos < destlen) +diff -Nupr old/fs/jffs2/compr_zlib.c new/fs/jffs2/compr_zlib.c +--- old/fs/jffs2/compr_zlib.c 2022-05-09 17:22:53.000000000 +0800 ++++ new/fs/jffs2/compr_zlib.c 2022-05-10 15:06:46.640000000 +0800 +@@ -10,15 +10,10 @@ + * + */ + +-#if !defined(__KERNEL__) && !defined(__ECOS) +-#error "The userspace support got too messy and was removed. Update your mkfs.jffs2" +-#endif +- +-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +- + #include +-#include ++#include + #include ++#include + #include "nodelist.h" + #include "compr.h" + +@@ -35,39 +30,8 @@ static DEFINE_MUTEX(deflate_mutex); + static DEFINE_MUTEX(inflate_mutex); + static z_stream inf_strm, def_strm; + +-#ifdef __KERNEL__ /* Linux-only */ +-#include +-#include +-#include +- +-static int __init alloc_workspaces(void) +-{ +- def_strm.workspace = vmalloc(zlib_deflate_workspacesize(MAX_WBITS, +- MAX_MEM_LEVEL)); +- if (!def_strm.workspace) +- return -ENOMEM; +- +- jffs2_dbg(1, "Allocated %d bytes for deflate workspace\n", +- zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL)); +- inf_strm.workspace = vmalloc(zlib_inflate_workspacesize()); +- if (!inf_strm.workspace) { +- vfree(def_strm.workspace); +- return -ENOMEM; +- } +- jffs2_dbg(1, "Allocated %d bytes for inflate workspace\n", +- zlib_inflate_workspacesize()); +- return 0; +-} +- +-static void free_workspaces(void) +-{ +- vfree(def_strm.workspace); +- vfree(inf_strm.workspace); +-} +-#else + #define alloc_workspaces() (0) + #define free_workspaces() do { } while(0) +-#endif /* __KERNEL__ */ + + static int jffs2_zlib_compress(unsigned char *data_in, + unsigned char *cpage_out, +@@ -80,7 +44,7 @@ static int jffs2_zlib_compress(unsigned + + mutex_lock(&deflate_mutex); + +- if (Z_OK != zlib_deflateInit(&def_strm, 3)) { ++ if (Z_OK != deflateInit(&def_strm, 3)) { + pr_warn("deflateInit failed\n"); + mutex_unlock(&deflate_mutex); + return -1; +@@ -98,21 +62,21 @@ static int jffs2_zlib_compress(unsigned + (*sourcelen-def_strm.total_in), def_strm.avail_out); + jffs2_dbg(1, "calling deflate with avail_in %ld, avail_out %ld\n", + def_strm.avail_in, def_strm.avail_out); +- ret = zlib_deflate(&def_strm, Z_PARTIAL_FLUSH); ++ ret = deflate(&def_strm, Z_PARTIAL_FLUSH); + jffs2_dbg(1, "deflate returned with avail_in %ld, avail_out %ld, total_in %ld, total_out %ld\n", + def_strm.avail_in, def_strm.avail_out, + def_strm.total_in, def_strm.total_out); + if (ret != Z_OK) { + jffs2_dbg(1, "deflate in loop returned %d\n", ret); +- zlib_deflateEnd(&def_strm); ++ deflateEnd(&def_strm); + mutex_unlock(&deflate_mutex); + return -1; + } + } + def_strm.avail_out += STREAM_END_SPACE; + def_strm.avail_in = 0; +- ret = zlib_deflate(&def_strm, Z_FINISH); +- zlib_deflateEnd(&def_strm); ++ ret = deflate(&def_strm, Z_FINISH); ++ deflateEnd(&def_strm); + + if (ret != Z_STREAM_END) { + jffs2_dbg(1, "final deflate returned %d\n", ret); +@@ -171,18 +135,18 @@ static int jffs2_zlib_decompress(unsigne + } + + +- if (Z_OK != zlib_inflateInit2(&inf_strm, wbits)) { ++ if (Z_OK != inflateInit2(&inf_strm, wbits)) { + pr_warn("inflateInit failed\n"); + mutex_unlock(&inflate_mutex); + return 1; + } + +- while((ret = zlib_inflate(&inf_strm, Z_FINISH)) == Z_OK) ++ while((ret = inflate(&inf_strm, Z_FINISH)) == Z_OK) + ; + if (ret != Z_STREAM_END) { + pr_notice("inflate returned %d\n", ret); + } +- zlib_inflateEnd(&inf_strm); ++ inflateEnd(&inf_strm); + mutex_unlock(&inflate_mutex); + return 0; + } +@@ -204,13 +168,30 @@ int __init jffs2_zlib_init(void) + { + int ret; + ++ ret = pthread_mutex_init(&inflate_mutex, NULL); ++ if (ret) { ++ return ret; ++ } ++ ++ ret = pthread_mutex_init(&deflate_mutex, NULL); ++ if (ret) { ++ pthread_mutex_destroy(&inflate_mutex); ++ return ret; ++ } ++ + ret = alloc_workspaces(); +- if (ret) +- return ret; ++ if (ret) { ++ pthread_mutex_destroy(&inflate_mutex); ++ pthread_mutex_destroy(&deflate_mutex); ++ return ret; ++ } + + ret = jffs2_register_compressor(&jffs2_zlib_comp); +- if (ret) +- free_workspaces(); ++ if (ret) { ++ pthread_mutex_destroy(&inflate_mutex); ++ pthread_mutex_destroy(&deflate_mutex); ++ free_workspaces(); ++ } + + return ret; + } +@@ -219,4 +200,6 @@ void jffs2_zlib_exit(void) + { + jffs2_unregister_compressor(&jffs2_zlib_comp); + free_workspaces(); ++ pthread_mutex_destroy(&inflate_mutex); ++ pthread_mutex_destroy(&deflate_mutex); + } +diff -Nupr old/fs/jffs2/debug.c new/fs/jffs2/debug.c +--- old/fs/jffs2/debug.c 2022-05-09 17:22:53.000000000 +0800 ++++ new/fs/jffs2/debug.c 2022-05-10 15:11:46.200000000 +0800 +@@ -10,15 +10,12 @@ + * + */ + +-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +- + #include + #include + #include +-#include +-#include +-#include + #include ++#include ++#include "los_crc32.h" + #include "nodelist.h" + #include "debug.h" + +@@ -133,7 +130,7 @@ __jffs2_dbg_prewrite_paranoia_check(stru + if (!buf) + return; + +- ret = jffs2_flash_read(c, ofs, len, &retlen, buf); ++ ret = jffs2_flash_read(c, ofs, len, &retlen, (char *)buf); + if (ret || (retlen != len)) { + JFFS2_WARNING("read %d bytes failed or short. ret %d, retlen %zd.\n", + len, ret, retlen); +diff -Nupr old/fs/jffs2/debug.h new/fs/jffs2/debug.h +--- old/fs/jffs2/debug.h 2022-05-09 17:22:53.000000000 +0800 ++++ new/fs/jffs2/debug.h 2022-05-10 15:12:30.850000000 +0800 +@@ -14,7 +14,12 @@ + #define _JFFS2_DEBUG_H_ + + #include +- ++#include "los_process.h" ++#ifdef __cplusplus ++#if __cplusplus ++extern "C" { ++#endif /* __cplusplus */ ++#endif /* __cplusplus */ + #ifndef CONFIG_JFFS2_FS_DEBUG + #define CONFIG_JFFS2_FS_DEBUG 0 + #endif +@@ -71,25 +76,26 @@ do { \ + + /* The prefixes of JFFS2 messages */ + #define JFFS2_DBG KERN_DEBUG ++#define JFFS2_DBG_LVL KERN_DEBUG + #define JFFS2_DBG_PREFIX "[JFFS2 DBG]" + #define JFFS2_DBG_MSG_PREFIX JFFS2_DBG JFFS2_DBG_PREFIX + + /* JFFS2 message macros */ + #define JFFS2_ERROR(fmt, ...) \ +- pr_err("error: (%d) %s: " fmt, \ +- task_pid_nr(current), __func__, ##__VA_ARGS__) ++ pr_err("error: (%u) %s: " fmt, \ ++ LOS_GetCurrProcessID, __func__, ##__VA_ARGS__) + + #define JFFS2_WARNING(fmt, ...) \ +- pr_warn("warning: (%d) %s: " fmt, \ +- task_pid_nr(current), __func__, ##__VA_ARGS__) ++ pr_warn("warning: (%u) %s: " fmt, \ ++ LOS_GetCurrProcessID, __func__, ##__VA_ARGS__) + + #define JFFS2_NOTICE(fmt, ...) \ +- pr_notice("notice: (%d) %s: " fmt, \ +- task_pid_nr(current), __func__, ##__VA_ARGS__) ++ pr_notice("notice: (%u) %s: " fmt, \ ++ LOS_GetCurrProcessID, __func__, ##__VA_ARGS__) + + #define JFFS2_DEBUG(fmt, ...) \ +- printk(KERN_DEBUG "[JFFS2 DBG] (%d) %s: " fmt, \ +- task_pid_nr(current), __func__, ##__VA_ARGS__) ++ printk(KERN_DEBUG "[JFFS2 DBG] (%u) %s: " fmt, \ ++ LOS_GetCurrProcessID, __func__, ##__VA_ARGS__) + + /* + * We split our debugging messages on several parts, depending on the JFFS2 +@@ -272,4 +278,10 @@ __jffs2_dbg_dump_node(struct jffs2_sb_in + #define jffs2_dbg_acct_sanity_check_nolock(c, jeb) + #endif /* !JFFS2_DBG_SANITY_CHECKS */ + ++#ifdef __cplusplus ++#if __cplusplus ++} ++#endif /* __cplusplus */ ++#endif /* __cplusplus */ ++ + #endif /* _JFFS2_DEBUG_H_ */ +diff -Nupr old/fs/jffs2/dir.c new/fs/jffs2/dir.c +--- old/fs/jffs2/dir.c 2022-05-09 17:22:53.000000000 +0800 ++++ new/fs/jffs2/dir.c 2022-05-10 16:08:26.380000000 +0800 +@@ -10,95 +10,42 @@ + * + */ + +-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +- ++#include + #include + #include + #include +-#include +-#include +-#include "jffs2_fs_i.h" +-#include "jffs2_fs_sb.h" +-#include ++#include "los_crc32.h" + #include "nodelist.h" +- +-static int jffs2_readdir (struct file *, struct dir_context *); +- +-static int jffs2_create (struct inode *,struct dentry *,umode_t, +- bool); +-static struct dentry *jffs2_lookup (struct inode *,struct dentry *, +- unsigned int); +-static int jffs2_link (struct dentry *,struct inode *,struct dentry *); +-static int jffs2_unlink (struct inode *,struct dentry *); +-static int jffs2_symlink (struct inode *,struct dentry *,const char *); +-static int jffs2_mkdir (struct inode *,struct dentry *,umode_t); +-static int jffs2_rmdir (struct inode *,struct dentry *); +-static int jffs2_mknod (struct inode *,struct dentry *,umode_t,dev_t); +-static int jffs2_rename (struct inode *, struct dentry *, +- struct inode *, struct dentry *, +- unsigned int); +- +-const struct file_operations jffs2_dir_operations = +-{ +- .read = generic_read_dir, +- .iterate_shared=jffs2_readdir, +- .unlocked_ioctl=jffs2_ioctl, +- .fsync = jffs2_fsync, +- .llseek = generic_file_llseek, +-}; +- +- +-const struct inode_operations jffs2_dir_inode_operations = +-{ +- .create = jffs2_create, +- .lookup = jffs2_lookup, +- .link = jffs2_link, +- .unlink = jffs2_unlink, +- .symlink = jffs2_symlink, +- .mkdir = jffs2_mkdir, +- .rmdir = jffs2_rmdir, +- .mknod = jffs2_mknod, +- .rename = jffs2_rename, +- .get_acl = jffs2_get_acl, +- .set_acl = jffs2_set_acl, +- .setattr = jffs2_setattr, +- .listxattr = jffs2_listxattr, +-}; +- +-/***********************************************************************/ +- ++#include "vfs_jffs2.h" ++#include "jffs2_hash.h" + + /* We keep the dirent list sorted in increasing order of name hash, + and we use the same hash function as the dentries. Makes this + nice and simple + */ +-static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target, +- unsigned int flags) ++struct jffs2_inode *jffs2_lookup(struct jffs2_inode *dir_i, const unsigned char *d_name, int namelen) + { + struct jffs2_inode_info *dir_f; + struct jffs2_full_dirent *fd = NULL, *fd_list; + uint32_t ino = 0; +- struct inode *inode = NULL; +- unsigned int nhash; ++ uint32_t hash = full_name_hash(d_name, namelen); ++ struct jffs2_inode *inode = NULL; + + jffs2_dbg(1, "jffs2_lookup()\n"); + +- if (target->d_name.len > JFFS2_MAX_NAME_LEN) ++ if (namelen > JFFS2_MAX_NAME_LEN) + return ERR_PTR(-ENAMETOOLONG); + + dir_f = JFFS2_INODE_INFO(dir_i); + +- /* The 'nhash' on the fd_list is not the same as the dentry hash */ +- nhash = full_name_hash(NULL, target->d_name.name, target->d_name.len); +- + mutex_lock(&dir_f->sem); + + /* NB: The 2.2 backport will need to explicitly check for '.' and '..' here */ +- for (fd_list = dir_f->dents; fd_list && fd_list->nhash <= nhash; fd_list = fd_list->next) { +- if (fd_list->nhash == nhash && +- (!fd || fd_list->version > fd->version) && +- strlen(fd_list->name) == target->d_name.len && +- !strncmp(fd_list->name, target->d_name.name, target->d_name.len)) { ++ for (fd_list = dir_f->dents; fd_list && fd_list->nhash <= hash; fd_list = fd_list->next) { ++ if (fd_list->nhash == hash && ++ (!fd || fd_list->version > fd->version) && ++ strlen((char *)fd_list->name) == namelen && ++ !strncmp((char *)fd_list->name, (char *)d_name, namelen)) { + fd = fd_list; + } + } +@@ -111,176 +58,57 @@ static struct dentry *jffs2_lookup(struc + pr_warn("iget() failed for ino #%u\n", ino); + } + +- return d_splice_alias(inode, target); +-} +- +-/***********************************************************************/ +- +- +-static int jffs2_readdir(struct file *file, struct dir_context *ctx) +-{ +- struct inode *inode = file_inode(file); +- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); +- struct jffs2_full_dirent *fd; +- unsigned long curofs = 1; +- +- jffs2_dbg(1, "jffs2_readdir() for dir_i #%lu\n", inode->i_ino); +- +- if (!dir_emit_dots(file, ctx)) +- return 0; +- +- mutex_lock(&f->sem); +- for (fd = f->dents; fd; fd = fd->next) { +- curofs++; +- /* First loop: curofs = 2; pos = 2 */ +- if (curofs < ctx->pos) { +- jffs2_dbg(2, "Skipping dirent: \"%s\", ino #%u, type %d, because curofs %ld < offset %ld\n", +- fd->name, fd->ino, fd->type, curofs, (unsigned long)ctx->pos); +- continue; +- } +- if (!fd->ino) { +- jffs2_dbg(2, "Skipping deletion dirent \"%s\"\n", +- fd->name); +- ctx->pos++; +- continue; +- } +- jffs2_dbg(2, "Dirent %ld: \"%s\", ino #%u, type %d\n", +- (unsigned long)ctx->pos, fd->name, fd->ino, fd->type); +- if (!dir_emit(ctx, fd->name, strlen(fd->name), fd->ino, fd->type)) +- break; +- ctx->pos++; +- } +- mutex_unlock(&f->sem); +- return 0; +-} +- +-/***********************************************************************/ +- +- +-static int jffs2_create(struct inode *dir_i, struct dentry *dentry, +- umode_t mode, bool excl) +-{ +- struct jffs2_raw_inode *ri; +- struct jffs2_inode_info *f, *dir_f; +- struct jffs2_sb_info *c; +- struct inode *inode; +- int ret; +- +- ri = jffs2_alloc_raw_inode(); +- if (!ri) +- return -ENOMEM; +- +- c = JFFS2_SB_INFO(dir_i->i_sb); +- +- jffs2_dbg(1, "%s()\n", __func__); +- +- inode = jffs2_new_inode(dir_i, mode, ri); +- +- if (IS_ERR(inode)) { +- jffs2_dbg(1, "jffs2_new_inode() failed\n"); +- jffs2_free_raw_inode(ri); +- return PTR_ERR(inode); +- } +- +- inode->i_op = &jffs2_file_inode_operations; +- inode->i_fop = &jffs2_file_operations; +- inode->i_mapping->a_ops = &jffs2_file_address_operations; +- inode->i_mapping->nrpages = 0; +- +- f = JFFS2_INODE_INFO(inode); +- dir_f = JFFS2_INODE_INFO(dir_i); +- +- /* jffs2_do_create() will want to lock it, _after_ reserving +- space and taking c-alloc_sem. If we keep it locked here, +- lockdep gets unhappy (although it's a false positive; +- nothing else will be looking at this inode yet so there's +- no chance of AB-BA deadlock involving its f->sem). */ +- mutex_unlock(&f->sem); +- +- ret = jffs2_do_create(c, dir_f, f, ri, &dentry->d_name); +- if (ret) +- goto fail; +- +- dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(ri->ctime)); +- +- jffs2_free_raw_inode(ri); +- +- jffs2_dbg(1, "%s(): Created ino #%lu with mode %o, nlink %d(%d). nrpages %ld\n", +- __func__, inode->i_ino, inode->i_mode, inode->i_nlink, +- f->inocache->pino_nlink, inode->i_mapping->nrpages); +- +- d_instantiate_new(dentry, inode); +- return 0; +- +- fail: +- iget_failed(inode); +- jffs2_free_raw_inode(ri); +- return ret; ++ return inode; + } + +-/***********************************************************************/ +- +- +-static int jffs2_unlink(struct inode *dir_i, struct dentry *dentry) ++int jffs2_unlink(struct jffs2_inode *dir_i, struct jffs2_inode *d_inode, const unsigned char *d_name) + { + struct jffs2_sb_info *c = JFFS2_SB_INFO(dir_i->i_sb); + struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i); +- struct jffs2_inode_info *dead_f = JFFS2_INODE_INFO(d_inode(dentry)); ++ struct jffs2_inode_info *dead_f = JFFS2_INODE_INFO(d_inode); + int ret; +- uint32_t now = JFFS2_NOW(); ++ uint32_t now = Jffs2CurSec(); + +- ret = jffs2_do_unlink(c, dir_f, dentry->d_name.name, +- dentry->d_name.len, dead_f, now); ++ ret = jffs2_do_unlink(c, dir_f, (const char *)d_name, ++ strlen((char *)d_name), dead_f, now); + if (dead_f->inocache) +- set_nlink(d_inode(dentry), dead_f->inocache->pino_nlink); ++ d_inode->i_nlink = dead_f->inocache->pino_nlink; + if (!ret) +- dir_i->i_mtime = dir_i->i_ctime = ITIME(now); ++ dir_i->i_mtime = dir_i->i_ctime = now; + return ret; + } +-/***********************************************************************/ + +- +-static int jffs2_link (struct dentry *old_dentry, struct inode *dir_i, struct dentry *dentry) ++int jffs2_link(struct jffs2_inode *old_d_inode, struct jffs2_inode *dir_i, const unsigned char *d_name) + { +- struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dentry->d_sb); +- struct jffs2_inode_info *f = JFFS2_INODE_INFO(d_inode(old_dentry)); ++ struct jffs2_sb_info *c = JFFS2_SB_INFO(old_d_inode->i_sb); ++ struct jffs2_inode_info *f = JFFS2_INODE_INFO(old_d_inode); + struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i); + int ret; + uint8_t type; + uint32_t now; + +- /* Don't let people make hard links to bad inodes. */ +- if (!f->inocache) +- return -EIO; +- +- if (d_is_dir(old_dentry)) +- return -EPERM; +- + /* XXX: This is ugly */ +- type = (d_inode(old_dentry)->i_mode & S_IFMT) >> 12; ++ type = (old_d_inode->i_mode & S_IFMT) >> 12; + if (!type) type = DT_REG; + +- now = JFFS2_NOW(); +- ret = jffs2_do_link(c, dir_f, f->inocache->ino, type, dentry->d_name.name, dentry->d_name.len, now); ++ now = Jffs2CurSec(); ++ ret = jffs2_do_link(c, dir_f, f->inocache->ino, type, (const char *)d_name, ++ strlen((char *)d_name), now); + + if (!ret) { + mutex_lock(&f->sem); +- set_nlink(d_inode(old_dentry), ++f->inocache->pino_nlink); ++ old_d_inode->i_nlink = ++f->inocache->pino_nlink; + mutex_unlock(&f->sem); +- d_instantiate(dentry, d_inode(old_dentry)); +- dir_i->i_mtime = dir_i->i_ctime = ITIME(now); +- ihold(d_inode(old_dentry)); ++ dir_i->i_mtime = dir_i->i_ctime = now; + } + return ret; + } + +-/***********************************************************************/ +- +-static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char *target) ++int jffs2_symlink(struct jffs2_inode *dir_i, struct jffs2_inode **d_inode, const unsigned char *d_name, const char *target) + { + struct jffs2_inode_info *f, *dir_f; + struct jffs2_sb_info *c; +- struct inode *inode; ++ struct jffs2_inode *inode; + struct jffs2_raw_inode *ri; + struct jffs2_raw_dirent *rd; + struct jffs2_full_dnode *fn; +@@ -304,7 +132,7 @@ static int jffs2_symlink (struct inode * + /* Try to reserve enough space for both node and dirent. + * Just the node will do for now, though + */ +- namelen = dentry->d_name.len; ++ namelen = strlen((char *)d_name); + ret = jffs2_reserve_space(c, sizeof(*ri) + targetlen, &alloclen, + ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); + +@@ -321,8 +149,6 @@ static int jffs2_symlink (struct inode * + return PTR_ERR(inode); + } + +- inode->i_op = &jffs2_symlink_inode_operations; +- + f = JFFS2_INODE_INFO(inode); + + inode->i_size = targetlen; +@@ -334,7 +160,7 @@ static int jffs2_symlink (struct inode * + ri->data_crc = cpu_to_je32(crc32(0, target, targetlen)); + ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); + +- fn = jffs2_write_dnode(c, f, ri, target, targetlen, ALLOC_NORMAL); ++ fn = jffs2_write_dnode(c, f, ri, (const unsigned char *)target, targetlen, ALLOC_NORMAL); + + jffs2_free_raw_inode(ri); + +@@ -347,7 +173,8 @@ static int jffs2_symlink (struct inode * + } + + /* We use f->target field to store the target path. */ +- f->target = kmemdup(target, targetlen + 1, GFP_KERNEL); ++ ++ f->target = (unsigned char *)malloc(targetlen + 1); + if (!f->target) { + pr_warn("Can't allocate %d bytes of memory\n", targetlen + 1); + mutex_unlock(&f->sem); +@@ -355,7 +182,15 @@ static int jffs2_symlink (struct inode * + ret = -ENOMEM; + goto fail; + } +- inode->i_link = f->target; ++ ++ ret = LOS_CopyToKernel((char *)f->target, targetlen + 1, target, targetlen + 1); ++ if (ret != EOK) { ++ (void)free(f->target); ++ f->target = NULL; ++ mutex_unlock(&f->sem); ++ jffs2_complete_reservation(c); ++ goto fail; ++ } + + jffs2_dbg(1, "%s(): symlink's target '%s' cached\n", + __func__, (char *)f->target); +@@ -368,14 +203,6 @@ static int jffs2_symlink (struct inode * + + jffs2_complete_reservation(c); + +- ret = jffs2_init_security(inode, dir_i, &dentry->d_name); +- if (ret) +- goto fail; +- +- ret = jffs2_init_acl_post(inode); +- if (ret) +- goto fail; +- + ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen, + ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); + if (ret) +@@ -400,13 +227,13 @@ static int jffs2_symlink (struct inode * + rd->pino = cpu_to_je32(dir_i->i_ino); + rd->version = cpu_to_je32(++dir_f->highest_version); + rd->ino = cpu_to_je32(inode->i_ino); +- rd->mctime = cpu_to_je32(JFFS2_NOW()); ++ rd->mctime = cpu_to_je32(Jffs2CurSec()); + rd->nsize = namelen; + rd->type = DT_LNK; + rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); +- rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen)); ++ rd->name_crc = cpu_to_je32(crc32(0, (const char *)d_name, namelen)); + +- fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, ALLOC_NORMAL); ++ fd = jffs2_write_dirent(c, dir_f, rd, (const unsigned char *)d_name, namelen, ALLOC_NORMAL); + + if (IS_ERR(fd)) { + /* dirent failed to write. Delete the inode normally +@@ -418,7 +245,7 @@ static int jffs2_symlink (struct inode * + goto fail; + } + +- dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(rd->mctime)); ++ dir_i->i_mtime = dir_i->i_ctime = je32_to_cpu(rd->mctime); + + jffs2_free_raw_dirent(rd); + +@@ -429,20 +256,20 @@ static int jffs2_symlink (struct inode * + mutex_unlock(&dir_f->sem); + jffs2_complete_reservation(c); + +- d_instantiate_new(dentry, inode); ++ *d_inode = inode; + return 0; + + fail: +- iget_failed(inode); ++ inode->i_nlink = 0; ++ jffs2_iput(inode); + return ret; + } + +- +-static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, umode_t mode) ++int jffs2_mkdir(struct jffs2_inode *dir_i, const unsigned char *d_name, int mode, struct jffs2_inode **new_i) + { + struct jffs2_inode_info *f, *dir_f; + struct jffs2_sb_info *c; +- struct inode *inode; ++ struct jffs2_inode *inode; + struct jffs2_raw_inode *ri; + struct jffs2_raw_dirent *rd; + struct jffs2_full_dnode *fn; +@@ -450,7 +277,7 @@ static int jffs2_mkdir (struct inode *di + int namelen; + uint32_t alloclen; + int ret; +- ++ mode &= ~S_IFMT; + mode |= S_IFDIR; + + ri = jffs2_alloc_raw_inode(); +@@ -462,9 +289,8 @@ static int jffs2_mkdir (struct inode *di + /* Try to reserve enough space for both node and dirent. + * Just the node will do for now, though + */ +- namelen = dentry->d_name.len; +- ret = jffs2_reserve_space(c, sizeof(*ri), &alloclen, ALLOC_NORMAL, +- JFFS2_SUMMARY_INODE_SIZE); ++ namelen = strlen((char *)d_name); ++ ret = jffs2_reserve_space(c, sizeof(*ri), &alloclen, ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); + + if (ret) { + jffs2_free_raw_inode(ri); +@@ -478,14 +304,8 @@ static int jffs2_mkdir (struct inode *di + jffs2_complete_reservation(c); + return PTR_ERR(inode); + } +- +- inode->i_op = &jffs2_dir_inode_operations; +- inode->i_fop = &jffs2_dir_operations; +- + f = JFFS2_INODE_INFO(inode); + +- /* Directories get nlink 2 at start */ +- set_nlink(inode, 2); + /* but ic->pino_nlink is the parent ino# */ + f->inocache->pino_nlink = dir_i->i_ino; + +@@ -500,6 +320,7 @@ static int jffs2_mkdir (struct inode *di + /* Eeek. Wave bye bye */ + mutex_unlock(&f->sem); + jffs2_complete_reservation(c); ++ + ret = PTR_ERR(fn); + goto fail; + } +@@ -511,14 +332,6 @@ static int jffs2_mkdir (struct inode *di + + jffs2_complete_reservation(c); + +- ret = jffs2_init_security(inode, dir_i, &dentry->d_name); +- if (ret) +- goto fail; +- +- ret = jffs2_init_acl_post(inode); +- if (ret) +- goto fail; +- + ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen, + ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); + if (ret) +@@ -543,13 +356,13 @@ static int jffs2_mkdir (struct inode *di + rd->pino = cpu_to_je32(dir_i->i_ino); + rd->version = cpu_to_je32(++dir_f->highest_version); + rd->ino = cpu_to_je32(inode->i_ino); +- rd->mctime = cpu_to_je32(JFFS2_NOW()); ++ rd->mctime = cpu_to_je32(Jffs2CurSec()); + rd->nsize = namelen; + rd->type = DT_DIR; + rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); +- rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen)); ++ rd->name_crc = cpu_to_je32(crc32(0, d_name, namelen)); + +- fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, ALLOC_NORMAL); ++ fd = jffs2_write_dirent(c, dir_f, rd, d_name, namelen, ALLOC_NORMAL); + + if (IS_ERR(fd)) { + /* dirent failed to write. Delete the inode normally +@@ -557,12 +370,12 @@ static int jffs2_mkdir (struct inode *di + jffs2_complete_reservation(c); + jffs2_free_raw_dirent(rd); + mutex_unlock(&dir_f->sem); ++ inode->i_nlink = 0; + ret = PTR_ERR(fd); + goto fail; + } + +- dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(rd->mctime)); +- inc_nlink(dir_i); ++ dir_i->i_mtime = dir_i->i_ctime = je32_to_cpu(rd->mctime); + + jffs2_free_raw_dirent(rd); + +@@ -572,300 +385,198 @@ static int jffs2_mkdir (struct inode *di + + mutex_unlock(&dir_f->sem); + jffs2_complete_reservation(c); ++ *new_i = inode; + +- d_instantiate_new(dentry, inode); + return 0; + + fail: +- iget_failed(inode); ++ inode->i_nlink = 0; ++ jffs2_iput(inode); + return ret; + } + +-static int jffs2_rmdir (struct inode *dir_i, struct dentry *dentry) ++int jffs2_rmdir (struct jffs2_inode *dir_i, struct jffs2_inode *d_inode, const unsigned char *d_name) + { + struct jffs2_sb_info *c = JFFS2_SB_INFO(dir_i->i_sb); + struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i); +- struct jffs2_inode_info *f = JFFS2_INODE_INFO(d_inode(dentry)); ++ struct jffs2_inode_info *f = JFFS2_INODE_INFO(d_inode); + struct jffs2_full_dirent *fd; + int ret; +- uint32_t now = JFFS2_NOW(); ++ uint32_t now = Jffs2CurSec(); + +- mutex_lock(&f->sem); + for (fd = f->dents ; fd; fd = fd->next) { + if (fd->ino) { +- mutex_unlock(&f->sem); ++ PRINT_ERR("%s-%d: ret=%d\n", __FUNCTION__, __LINE__, ENOTEMPTY); + return -ENOTEMPTY; + } + } +- mutex_unlock(&f->sem); + +- ret = jffs2_do_unlink(c, dir_f, dentry->d_name.name, +- dentry->d_name.len, f, now); +- if (!ret) { +- dir_i->i_mtime = dir_i->i_ctime = ITIME(now); +- clear_nlink(d_inode(dentry)); +- drop_nlink(dir_i); +- } ++ ret = jffs2_do_unlink(c, dir_f, (const char *)d_name, ++ strlen((char *)d_name), f, now); ++ if (f->inocache) ++ d_inode->i_nlink = f->inocache->pino_nlink; ++ if (!ret) ++ dir_i->i_mtime = dir_i->i_ctime = now; ++ + return ret; + } + +-static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, umode_t mode, dev_t rdev) ++int jffs2_rename (struct jffs2_inode *old_dir_i, struct jffs2_inode *d_inode, const unsigned char *old_d_name, ++ struct jffs2_inode *new_dir_i, const unsigned char *new_d_name) + { +- struct jffs2_inode_info *f, *dir_f; +- struct jffs2_sb_info *c; +- struct inode *inode; +- struct jffs2_raw_inode *ri; +- struct jffs2_raw_dirent *rd; +- struct jffs2_full_dnode *fn; +- struct jffs2_full_dirent *fd; +- int namelen; +- union jffs2_device_node dev; +- int devlen = 0; +- uint32_t alloclen; + int ret; ++ struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dir_i->i_sb); ++ uint8_t type; ++ uint32_t now; + +- ri = jffs2_alloc_raw_inode(); +- if (!ri) +- return -ENOMEM; +- +- c = JFFS2_SB_INFO(dir_i->i_sb); +- +- if (S_ISBLK(mode) || S_ISCHR(mode)) +- devlen = jffs2_encode_dev(&dev, rdev); ++ /* XXX: This is ugly */ ++ type = (d_inode->i_mode & S_IFMT) >> 12; ++ if (!type) type = DT_REG; + +- /* Try to reserve enough space for both node and dirent. +- * Just the node will do for now, though +- */ +- namelen = dentry->d_name.len; +- ret = jffs2_reserve_space(c, sizeof(*ri) + devlen, &alloclen, +- ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); ++ now = Jffs2CurSec(); ++ ret = jffs2_do_link(c, JFFS2_INODE_INFO(new_dir_i), ++ d_inode->i_ino, type, ++ (const char *)new_d_name, strlen((char *)new_d_name), now); + +- if (ret) { +- jffs2_free_raw_inode(ri); ++ if (ret) + return ret; +- } + +- inode = jffs2_new_inode(dir_i, mode, ri); + +- if (IS_ERR(inode)) { +- jffs2_free_raw_inode(ri); +- jffs2_complete_reservation(c); +- return PTR_ERR(inode); ++ /* If it was a directory we moved, and there was no victim, ++ increase i_nlink on its new parent */ ++ if ((d_inode->i_mode & S_IFMT) == S_IFDIR) { ++ new_dir_i->i_nlink++; + } +- inode->i_op = &jffs2_file_inode_operations; +- init_special_inode(inode, inode->i_mode, rdev); + +- f = JFFS2_INODE_INFO(inode); +- +- ri->dsize = ri->csize = cpu_to_je32(devlen); +- ri->totlen = cpu_to_je32(sizeof(*ri) + devlen); +- ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4)); +- +- ri->compr = JFFS2_COMPR_NONE; +- ri->data_crc = cpu_to_je32(crc32(0, &dev, devlen)); +- ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); +- +- fn = jffs2_write_dnode(c, f, ri, (char *)&dev, devlen, ALLOC_NORMAL); ++ /* Unlink the original */ ++ ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i), ++ (const char *)old_d_name, strlen((char *)old_d_name), NULL, now); + +- jffs2_free_raw_inode(ri); ++ /* We don't touch inode->i_nlink */ + +- if (IS_ERR(fn)) { +- /* Eeek. Wave bye bye */ ++ if (ret) { ++ /* Oh shit. We really ought to make a single node which can do both atomically */ ++ struct jffs2_inode_info *f = JFFS2_INODE_INFO(d_inode); ++ mutex_lock(&f->sem); ++ if (f->inocache) ++ d_inode->i_nlink = f->inocache->pino_nlink++; + mutex_unlock(&f->sem); +- jffs2_complete_reservation(c); +- ret = PTR_ERR(fn); +- goto fail; +- } +- /* No data here. Only a metadata node, which will be +- obsoleted by the first data write +- */ +- f->metadata = fn; +- mutex_unlock(&f->sem); +- +- jffs2_complete_reservation(c); +- +- ret = jffs2_init_security(inode, dir_i, &dentry->d_name); +- if (ret) +- goto fail; +- +- ret = jffs2_init_acl_post(inode); +- if (ret) +- goto fail; +- +- ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen, +- ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); +- if (ret) +- goto fail; + +- rd = jffs2_alloc_raw_dirent(); +- if (!rd) { +- /* Argh. Now we treat it like a normal delete */ +- jffs2_complete_reservation(c); +- ret = -ENOMEM; +- goto fail; ++ pr_notice("%s(): Link succeeded, unlink failed (err %d). You now have a hard link\n", ++ __func__, ret); ++ /* Might as well let the VFS know */ ++ new_dir_i->i_mtime = new_dir_i->i_ctime = now; ++ return ret; + } + +- dir_f = JFFS2_INODE_INFO(dir_i); +- mutex_lock(&dir_f->sem); + +- rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); +- rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT); +- rd->totlen = cpu_to_je32(sizeof(*rd) + namelen); +- rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)); ++ new_dir_i->i_mtime = new_dir_i->i_ctime = old_dir_i->i_mtime = old_dir_i->i_ctime = now; + +- rd->pino = cpu_to_je32(dir_i->i_ino); +- rd->version = cpu_to_je32(++dir_f->highest_version); +- rd->ino = cpu_to_je32(inode->i_ino); +- rd->mctime = cpu_to_je32(JFFS2_NOW()); +- rd->nsize = namelen; ++ return 0; ++} + +- /* XXX: This is ugly. */ +- rd->type = (mode & S_IFMT) >> 12; ++int jffs2_create(struct jffs2_inode *dir_i, const unsigned char *d_name, int mode, ++ struct jffs2_inode **new_i) ++{ ++ struct jffs2_raw_inode *ri; ++ struct jffs2_inode_info *f, *dir_f; ++ struct jffs2_sb_info *c; ++ struct jffs2_inode *inode; ++ int ret; ++ mode &= ~S_IFMT; ++ mode |= S_IFREG; ++ ri = jffs2_alloc_raw_inode(); ++ if (!ri) ++ return -ENOMEM; + +- rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); +- rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen)); ++ c = JFFS2_SB_INFO(dir_i->i_sb); + +- fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, ALLOC_NORMAL); ++ D1(printk(KERN_DEBUG "jffs2_create()\n")); ++ inode = jffs2_new_inode(dir_i, mode, ri); + +- if (IS_ERR(fd)) { +- /* dirent failed to write. Delete the inode normally +- as if it were the final unlink() */ +- jffs2_complete_reservation(c); +- jffs2_free_raw_dirent(rd); +- mutex_unlock(&dir_f->sem); +- ret = PTR_ERR(fd); +- goto fail; ++ if (IS_ERR(inode)) { ++ D1(printk(KERN_DEBUG "jffs2_new_inode() failed, error:%ld\n", PTR_ERR(inode))); ++ jffs2_free_raw_inode(ri); ++ return PTR_ERR(inode); + } + +- dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(rd->mctime)); ++ f = JFFS2_INODE_INFO(inode); ++ dir_f = JFFS2_INODE_INFO(dir_i); + +- jffs2_free_raw_dirent(rd); ++ /* jffs2_do_create() will want to lock it, _after_ reserving ++ space and taking c-alloc_sem. If we keep it locked here, ++ lockdep gets unhappy (although it's a false positive; ++ nothing else will be looking at this inode yet so there's ++ no chance of AB-BA deadlock involving its f->sem). */ ++ mutex_unlock(&f->sem); ++ ret = jffs2_do_create(c, dir_f, f, ri, ++ (const char *)d_name, ++ strlen((char *)d_name)); + +- /* Link the fd into the inode's list, obsoleting an old +- one if necessary. */ +- jffs2_add_fd_to_list(c, fd, &dir_f->dents); ++ if (ret) { ++ inode->i_nlink = 0; ++ jffs2_iput(inode); ++ jffs2_free_raw_inode(ri); ++ return ret; ++ } + +- mutex_unlock(&dir_f->sem); +- jffs2_complete_reservation(c); ++ jffs2_free_raw_inode(ri); + +- d_instantiate_new(dentry, inode); ++ D1(printk(KERN_DEBUG "jffs2_create: Created ino #%lu with mode %o, nlink %d(%d)\n", ++ inode->i_ino, inode->i_mode, inode->i_nlink, f->inocache->pino_nlink)); ++ *new_i = inode; + return 0; ++} + +- fail: +- iget_failed(inode); +- return ret; ++static __inline void fill_name(char *dst_name, int nlen, const unsigned char *name, int namlen) ++{ ++ int len = nlen < namlen ? nlen : namlen; ++ (void)memcpy_s(dst_name, nlen, name, len); ++ dst_name[len] = '\0'; + } + +-static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry, +- struct inode *new_dir_i, struct dentry *new_dentry, +- unsigned int flags) ++int jffs2_readdir(struct jffs2_inode *inode, off_t *offset, off_t *int_off, struct dirent *ent) + { +- int ret; +- struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dir_i->i_sb); +- struct jffs2_inode_info *victim_f = NULL; +- uint8_t type; +- uint32_t now; ++ struct jffs2_inode_info *f; ++ struct jffs2_full_dirent *fd; ++ off_t curofs = 0; + +- if (flags & ~RENAME_NOREPLACE) +- return -EINVAL; ++ f = JFFS2_INODE_INFO(inode); + +- /* The VFS will check for us and prevent trying to rename a +- * file over a directory and vice versa, but if it's a directory, +- * the VFS can't check whether the victim is empty. The filesystem +- * needs to do that for itself. +- */ +- if (d_really_is_positive(new_dentry)) { +- victim_f = JFFS2_INODE_INFO(d_inode(new_dentry)); +- if (d_is_dir(new_dentry)) { +- struct jffs2_full_dirent *fd; +- +- mutex_lock(&victim_f->sem); +- for (fd = victim_f->dents; fd; fd = fd->next) { +- if (fd->ino) { +- mutex_unlock(&victim_f->sem); +- return -ENOTEMPTY; +- } +- } +- mutex_unlock(&victim_f->sem); ++ mutex_lock(&f->sem); ++ for (fd = f->dents; fd; fd = fd->next) { ++ if (curofs++ < *int_off) { ++ D2(printk ++ (KERN_DEBUG ++ "Skipping dirent: \"%s\", ino #%u, type %d, because curofs %ld < offset %ld\n", ++ fd->name, fd->ino, fd->type, curofs, offset)); ++ continue; + } +- } +- +- /* XXX: We probably ought to alloc enough space for +- both nodes at the same time. Writing the new link, +- then getting -ENOSPC, is quite bad :) +- */ +- +- /* Make a hard link */ +- +- /* XXX: This is ugly */ +- type = (d_inode(old_dentry)->i_mode & S_IFMT) >> 12; +- if (!type) type = DT_REG; +- +- now = JFFS2_NOW(); +- ret = jffs2_do_link(c, JFFS2_INODE_INFO(new_dir_i), +- d_inode(old_dentry)->i_ino, type, +- new_dentry->d_name.name, new_dentry->d_name.len, now); +- +- if (ret) +- return ret; +- +- if (victim_f) { +- /* There was a victim. Kill it off nicely */ +- if (d_is_dir(new_dentry)) +- clear_nlink(d_inode(new_dentry)); +- else +- drop_nlink(d_inode(new_dentry)); +- /* Don't oops if the victim was a dirent pointing to an +- inode which didn't exist. */ +- if (victim_f->inocache) { +- mutex_lock(&victim_f->sem); +- if (d_is_dir(new_dentry)) +- victim_f->inocache->pino_nlink = 0; +- else +- victim_f->inocache->pino_nlink--; +- mutex_unlock(&victim_f->sem); ++ if (!fd->ino) { ++ D2(printk (KERN_DEBUG "Skipping deletion dirent \"%s\"\n", fd->name)); ++ (*int_off)++; ++ continue; + } +- } + +- /* If it was a directory we moved, and there was no victim, +- increase i_nlink on its new parent */ +- if (d_is_dir(old_dentry) && !victim_f) +- inc_nlink(new_dir_i); +- +- /* Unlink the original */ +- ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i), +- old_dentry->d_name.name, old_dentry->d_name.len, NULL, now); +- +- /* We don't touch inode->i_nlink */ +- +- if (ret) { +- /* Oh shit. We really ought to make a single node which can do both atomically */ +- struct jffs2_inode_info *f = JFFS2_INODE_INFO(d_inode(old_dentry)); +- mutex_lock(&f->sem); +- inc_nlink(d_inode(old_dentry)); +- if (f->inocache && !d_is_dir(old_dentry)) +- f->inocache->pino_nlink++; +- mutex_unlock(&f->sem); ++ D2(printk ++ (KERN_DEBUG "%s-%d: Dirent %ld: \"%s\", ino #%u, type %d\n", __FUNCTION__, __LINE__, offset, ++ fd->name, fd->ino, fd->type)); ++ fill_name(ent->d_name, sizeof(ent->d_name) - 1, fd->name, strlen((char *)fd->name)); ++ ent->d_type = fd->type; ++ ent->d_off = ++(*offset); ++ ent->d_reclen = (uint16_t)sizeof(struct dirent); + +- pr_notice("%s(): Link succeeded, unlink failed (err %d). You now have a hard link\n", +- __func__, ret); +- /* +- * We can't keep the target in dcache after that. +- * For one thing, we can't afford dentry aliases for directories. +- * For another, if there was a victim, we _can't_ set new inode +- * for that sucker and we have to trigger mount eviction - the +- * caller won't do it on its own since we are returning an error. +- */ +- d_invalidate(new_dentry); +- new_dir_i->i_mtime = new_dir_i->i_ctime = ITIME(now); +- return ret; ++ (*int_off)++; ++ break; + } + +- if (d_is_dir(old_dentry)) +- drop_nlink(old_dir_i); ++ mutex_unlock(&f->sem); + +- new_dir_i->i_mtime = new_dir_i->i_ctime = old_dir_i->i_mtime = old_dir_i->i_ctime = ITIME(now); ++ if (fd == NULL) { ++ D2(printk(KERN_DEBUG "reached the end of the directory\n")); ++ return ENOENT; ++ } + +- return 0; ++ return ENOERR; + } + +diff -Nupr old/fs/jffs2/erase.c new/fs/jffs2/erase.c +--- old/fs/jffs2/erase.c 2022-05-09 17:22:53.000000000 +0800 ++++ new/fs/jffs2/erase.c 2022-05-10 16:09:47.150000000 +0800 +@@ -10,16 +10,19 @@ + * + */ + +-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +- + #include + #include +-#include + #include +-#include + #include + #include ++#include "mtd_dev.h" + #include "nodelist.h" ++#include "los_crc32.h" ++ ++struct erase_priv_struct { ++ struct jffs2_eraseblock *jeb; ++ struct jffs2_sb_info *c; ++}; + + static void jffs2_erase_failed(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, uint32_t bad_offset); + static void jffs2_erase_succeeded(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); +@@ -29,50 +32,14 @@ static void jffs2_erase_block(struct jff + struct jffs2_eraseblock *jeb) + { + int ret; +- uint32_t bad_offset; +-#ifdef __ECOS +- ret = jffs2_flash_erase(c, jeb); +- if (!ret) { +- jffs2_erase_succeeded(c, jeb); +- return; +- } +- bad_offset = jeb->offset; +-#else /* Linux */ +- struct erase_info *instr; +- +- jffs2_dbg(1, "%s(): erase block %#08x (range %#08x-%#08x)\n", +- __func__, +- jeb->offset, jeb->offset, jeb->offset + c->sector_size); +- instr = kmalloc(sizeof(struct erase_info), GFP_KERNEL); +- if (!instr) { +- pr_warn("kmalloc for struct erase_info in jffs2_erase_block failed. Refiling block for later\n"); +- mutex_lock(&c->erase_free_sem); +- spin_lock(&c->erase_completion_lock); +- list_move(&jeb->list, &c->erase_pending_list); +- c->erasing_size -= c->sector_size; +- c->dirty_size += c->sector_size; +- jeb->dirty_size = c->sector_size; +- spin_unlock(&c->erase_completion_lock); +- mutex_unlock(&c->erase_free_sem); +- return; +- } ++ uint64_t bad_offset = 0; + +- memset(instr, 0, sizeof(*instr)); +- +- instr->addr = jeb->offset; +- instr->len = c->sector_size; +- +- ret = mtd_erase(c->mtd, instr); ++ ret = c->mtd->erase(c->mtd, jeb->offset, c->sector_size, &bad_offset); + if (!ret) { + jffs2_erase_succeeded(c, jeb); +- kfree(instr); + return; + } + +- bad_offset = instr->fail_addr; +- kfree(instr); +-#endif /* __ECOS */ +- + if (ret == -ENOMEM || ret == -EAGAIN) { + /* Erase failed immediately. Refile it on the list */ + jffs2_dbg(1, "Erase at 0x%08x failed: %d. Refiling on erase_pending_list\n", +@@ -168,29 +135,10 @@ static void jffs2_erase_succeeded(struct + jffs2_garbage_collect_trigger(c); + spin_unlock(&c->erase_completion_lock); + mutex_unlock(&c->erase_free_sem); +- wake_up(&c->erase_wait); + } + + static void jffs2_erase_failed(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, uint32_t bad_offset) + { +- /* For NAND, if the failure did not occur at the device level for a +- specific physical page, don't bother updating the bad block table. */ +- if (jffs2_cleanmarker_oob(c) && (bad_offset != (uint32_t)MTD_FAIL_ADDR_UNKNOWN)) { +- /* We had a device-level failure to erase. Let's see if we've +- failed too many times. */ +- if (!jffs2_write_nand_badblock(c, jeb, bad_offset)) { +- /* We'd like to give this block another try. */ +- mutex_lock(&c->erase_free_sem); +- spin_lock(&c->erase_completion_lock); +- list_move(&jeb->list, &c->erase_pending_list); +- c->erasing_size -= c->sector_size; +- c->dirty_size += c->sector_size; +- jeb->dirty_size = c->sector_size; +- spin_unlock(&c->erase_completion_lock); +- mutex_unlock(&c->erase_free_sem); +- return; +- } +- } + + mutex_lock(&c->erase_free_sem); + spin_lock(&c->erase_completion_lock); +@@ -200,7 +148,6 @@ static void jffs2_erase_failed(struct jf + c->nr_erasing_blocks--; + spin_unlock(&c->erase_completion_lock); + mutex_unlock(&c->erase_free_sem); +- wake_up(&c->erase_wait); + } + + /* Hmmm. Maybe we should accept the extra space it takes and make +@@ -315,40 +262,8 @@ static int jffs2_block_check_erase(struc + void *ebuf; + uint32_t ofs; + size_t retlen; +- int ret; +- unsigned long *wordebuf; ++ int ret = -EIO; + +- ret = mtd_point(c->mtd, jeb->offset, c->sector_size, &retlen, +- &ebuf, NULL); +- if (ret != -EOPNOTSUPP) { +- if (ret) { +- jffs2_dbg(1, "MTD point failed %d\n", ret); +- goto do_flash_read; +- } +- if (retlen < c->sector_size) { +- /* Don't muck about if it won't let us point to the whole erase sector */ +- jffs2_dbg(1, "MTD point returned len too short: 0x%zx\n", +- retlen); +- mtd_unpoint(c->mtd, jeb->offset, retlen); +- goto do_flash_read; +- } +- wordebuf = ebuf-sizeof(*wordebuf); +- retlen /= sizeof(*wordebuf); +- do { +- if (*++wordebuf != ~0) +- break; +- } while(--retlen); +- mtd_unpoint(c->mtd, jeb->offset, c->sector_size); +- if (retlen) { +- pr_warn("Newly-erased block contained word 0x%lx at offset 0x%08tx\n", +- *wordebuf, +- jeb->offset + +- c->sector_size-retlen * sizeof(*wordebuf)); +- return -EIO; +- } +- return 0; +- } +- do_flash_read: + ebuf = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (!ebuf) { + pr_warn("Failed to allocate page buffer for verifying erase at 0x%08x. Refiling\n", +@@ -364,7 +279,7 @@ static int jffs2_block_check_erase(struc + + *bad_offset = ofs; + +- ret = mtd_read(c->mtd, ofs, readlen, &retlen, ebuf); ++ ret = jffs2_flash_read(c, ofs, readlen, &retlen, ebuf); + if (ret) { + pr_warn("Read of newly-erased block at 0x%08x failed: %d. Putting on bad_list\n", + ofs, ret); +@@ -379,7 +294,7 @@ static int jffs2_block_check_erase(struc + } + for (i=0; ierase_completion_lock); + mutex_unlock(&c->erase_free_sem); +- wake_up(&c->erase_wait); + return; + + filebad: +diff -Nupr old/fs/jffs2/file.c new/fs/jffs2/file.c +--- old/fs/jffs2/file.c 2022-05-09 17:22:53.000000000 +0800 ++++ new/fs/jffs2/file.c 2022-05-10 09:43:14.250000000 +0800 +@@ -9,334 +9,31 @@ + * For licensing information, see the file 'LICENCE' in this directory. + * + */ ++#include "los_vm_common.h" + +-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include + #include "nodelist.h" ++#include "vfs_jffs2.h" + +-static int jffs2_write_end(struct file *filp, struct address_space *mapping, +- loff_t pos, unsigned len, unsigned copied, +- struct page *pg, void *fsdata); +-static int jffs2_write_begin(struct file *filp, struct address_space *mapping, +- loff_t pos, unsigned len, unsigned flags, +- struct page **pagep, void **fsdata); +-static int jffs2_readpage (struct file *filp, struct page *pg); ++static unsigned char gc_buffer[PAGE_SIZE]; //avoids malloc when user may be under memory pressure + +-int jffs2_fsync(struct file *filp, loff_t start, loff_t end, int datasync) ++unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c, ++ struct jffs2_inode_info *f, ++ unsigned long offset, ++ unsigned long *priv) + { +- struct inode *inode = filp->f_mapping->host; +- struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); ++ /* FIXME: This works only with one file system mounted at a time */ + int ret; + +- ret = file_write_and_wait_range(filp, start, end); ++ ret = jffs2_read_inode_range(c, f, gc_buffer, ++ offset & ~(PAGE_SIZE-1), PAGE_SIZE); + if (ret) +- return ret; +- +- inode_lock(inode); +- /* Trigger GC to flush any pending writes for this inode */ +- jffs2_flush_wbuf_gc(c, inode->i_ino); +- inode_unlock(inode); +- +- return 0; ++ return ERR_PTR(ret); ++ return gc_buffer; + } + +-const struct file_operations jffs2_file_operations = +-{ +- .llseek = generic_file_llseek, +- .open = generic_file_open, +- .read_iter = generic_file_read_iter, +- .write_iter = generic_file_write_iter, +- .unlocked_ioctl=jffs2_ioctl, +- .mmap = generic_file_readonly_mmap, +- .fsync = jffs2_fsync, +- .splice_read = generic_file_splice_read, +- .splice_write = iter_file_splice_write, +-}; +- +-/* jffs2_file_inode_operations */ +- +-const struct inode_operations jffs2_file_inode_operations = +-{ +- .get_acl = jffs2_get_acl, +- .set_acl = jffs2_set_acl, +- .setattr = jffs2_setattr, +- .listxattr = jffs2_listxattr, +-}; +- +-const struct address_space_operations jffs2_file_address_operations = ++void jffs2_gc_release_page(struct jffs2_sb_info *c, ++ unsigned char *ptr, ++ unsigned long *priv) + { +- .readpage = jffs2_readpage, +- .write_begin = jffs2_write_begin, +- .write_end = jffs2_write_end, +-}; +- +-static int jffs2_do_readpage_nolock (struct inode *inode, struct page *pg) +-{ +- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); +- struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); +- unsigned char *pg_buf; +- int ret; +- +- jffs2_dbg(2, "%s(): ino #%lu, page at offset 0x%lx\n", +- __func__, inode->i_ino, pg->index << PAGE_SHIFT); +- +- BUG_ON(!PageLocked(pg)); +- +- pg_buf = kmap(pg); +- /* FIXME: Can kmap fail? */ +- +- ret = jffs2_read_inode_range(c, f, pg_buf, pg->index << PAGE_SHIFT, +- PAGE_SIZE); +- +- if (ret) { +- ClearPageUptodate(pg); +- SetPageError(pg); +- } else { +- SetPageUptodate(pg); +- ClearPageError(pg); +- } +- +- flush_dcache_page(pg); +- kunmap(pg); +- +- jffs2_dbg(2, "readpage finished\n"); +- return ret; +-} +- +-int jffs2_do_readpage_unlock(void *data, struct page *pg) +-{ +- int ret = jffs2_do_readpage_nolock(data, pg); +- unlock_page(pg); +- return ret; +-} +- +- +-static int jffs2_readpage (struct file *filp, struct page *pg) +-{ +- struct jffs2_inode_info *f = JFFS2_INODE_INFO(pg->mapping->host); +- int ret; +- +- mutex_lock(&f->sem); +- ret = jffs2_do_readpage_unlock(pg->mapping->host, pg); +- mutex_unlock(&f->sem); +- return ret; +-} +- +-static int jffs2_write_begin(struct file *filp, struct address_space *mapping, +- loff_t pos, unsigned len, unsigned flags, +- struct page **pagep, void **fsdata) +-{ +- struct page *pg; +- struct inode *inode = mapping->host; +- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); +- struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); +- pgoff_t index = pos >> PAGE_SHIFT; +- int ret = 0; +- +- jffs2_dbg(1, "%s()\n", __func__); +- +- if (pos > inode->i_size) { +- /* Make new hole frag from old EOF to new position */ +- struct jffs2_raw_inode ri; +- struct jffs2_full_dnode *fn; +- uint32_t alloc_len; +- +- jffs2_dbg(1, "Writing new hole frag 0x%x-0x%x between current EOF and new position\n", +- (unsigned int)inode->i_size, (uint32_t)pos); +- +- ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len, +- ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); +- if (ret) +- goto out_err; +- +- mutex_lock(&f->sem); +- memset(&ri, 0, sizeof(ri)); +- +- ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); +- ri.nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE); +- ri.totlen = cpu_to_je32(sizeof(ri)); +- ri.hdr_crc = cpu_to_je32(crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4)); +- +- ri.ino = cpu_to_je32(f->inocache->ino); +- ri.version = cpu_to_je32(++f->highest_version); +- ri.mode = cpu_to_jemode(inode->i_mode); +- ri.uid = cpu_to_je16(i_uid_read(inode)); +- ri.gid = cpu_to_je16(i_gid_read(inode)); +- ri.isize = cpu_to_je32((uint32_t)pos); +- ri.atime = ri.ctime = ri.mtime = cpu_to_je32(JFFS2_NOW()); +- ri.offset = cpu_to_je32(inode->i_size); +- ri.dsize = cpu_to_je32((uint32_t)pos - inode->i_size); +- ri.csize = cpu_to_je32(0); +- ri.compr = JFFS2_COMPR_ZERO; +- ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8)); +- ri.data_crc = cpu_to_je32(0); +- +- fn = jffs2_write_dnode(c, f, &ri, NULL, 0, ALLOC_NORMAL); +- +- if (IS_ERR(fn)) { +- ret = PTR_ERR(fn); +- jffs2_complete_reservation(c); +- mutex_unlock(&f->sem); +- goto out_err; +- } +- ret = jffs2_add_full_dnode_to_inode(c, f, fn); +- if (f->metadata) { +- jffs2_mark_node_obsolete(c, f->metadata->raw); +- jffs2_free_full_dnode(f->metadata); +- f->metadata = NULL; +- } +- if (ret) { +- jffs2_dbg(1, "Eep. add_full_dnode_to_inode() failed in write_begin, returned %d\n", +- ret); +- jffs2_mark_node_obsolete(c, fn->raw); +- jffs2_free_full_dnode(fn); +- jffs2_complete_reservation(c); +- mutex_unlock(&f->sem); +- goto out_err; +- } +- jffs2_complete_reservation(c); +- inode->i_size = pos; +- mutex_unlock(&f->sem); +- } +- +- /* +- * While getting a page and reading data in, lock c->alloc_sem until +- * the page is Uptodate. Otherwise GC task may attempt to read the same +- * page in read_cache_page(), which causes a deadlock. +- */ +- mutex_lock(&c->alloc_sem); +- pg = grab_cache_page_write_begin(mapping, index, flags); +- if (!pg) { +- ret = -ENOMEM; +- goto release_sem; +- } +- *pagep = pg; +- +- /* +- * Read in the page if it wasn't already present. Cannot optimize away +- * the whole page write case until jffs2_write_end can handle the +- * case of a short-copy. +- */ +- if (!PageUptodate(pg)) { +- mutex_lock(&f->sem); +- ret = jffs2_do_readpage_nolock(inode, pg); +- mutex_unlock(&f->sem); +- if (ret) { +- unlock_page(pg); +- put_page(pg); +- goto release_sem; +- } +- } +- jffs2_dbg(1, "end write_begin(). pg->flags %lx\n", pg->flags); +- +-release_sem: +- mutex_unlock(&c->alloc_sem); +-out_err: +- return ret; +-} +- +-static int jffs2_write_end(struct file *filp, struct address_space *mapping, +- loff_t pos, unsigned len, unsigned copied, +- struct page *pg, void *fsdata) +-{ +- /* Actually commit the write from the page cache page we're looking at. +- * For now, we write the full page out each time. It sucks, but it's simple +- */ +- struct inode *inode = mapping->host; +- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); +- struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); +- struct jffs2_raw_inode *ri; +- unsigned start = pos & (PAGE_SIZE - 1); +- unsigned end = start + copied; +- unsigned aligned_start = start & ~3; +- int ret = 0; +- uint32_t writtenlen = 0; +- +- jffs2_dbg(1, "%s(): ino #%lu, page at 0x%lx, range %d-%d, flags %lx\n", +- __func__, inode->i_ino, pg->index << PAGE_SHIFT, +- start, end, pg->flags); +- +- /* We need to avoid deadlock with page_cache_read() in +- jffs2_garbage_collect_pass(). So the page must be +- up to date to prevent page_cache_read() from trying +- to re-lock it. */ +- BUG_ON(!PageUptodate(pg)); +- +- if (end == PAGE_SIZE) { +- /* When writing out the end of a page, write out the +- _whole_ page. This helps to reduce the number of +- nodes in files which have many short writes, like +- syslog files. */ +- aligned_start = 0; +- } +- +- ri = jffs2_alloc_raw_inode(); +- +- if (!ri) { +- jffs2_dbg(1, "%s(): Allocation of raw inode failed\n", +- __func__); +- unlock_page(pg); +- put_page(pg); +- return -ENOMEM; +- } +- +- /* Set the fields that the generic jffs2_write_inode_range() code can't find */ +- ri->ino = cpu_to_je32(inode->i_ino); +- ri->mode = cpu_to_jemode(inode->i_mode); +- ri->uid = cpu_to_je16(i_uid_read(inode)); +- ri->gid = cpu_to_je16(i_gid_read(inode)); +- ri->isize = cpu_to_je32((uint32_t)inode->i_size); +- ri->atime = ri->ctime = ri->mtime = cpu_to_je32(JFFS2_NOW()); +- +- /* In 2.4, it was already kmapped by generic_file_write(). Doesn't +- hurt to do it again. The alternative is ifdefs, which are ugly. */ +- kmap(pg); +- +- ret = jffs2_write_inode_range(c, f, ri, page_address(pg) + aligned_start, +- (pg->index << PAGE_SHIFT) + aligned_start, +- end - aligned_start, &writtenlen); +- +- kunmap(pg); +- +- if (ret) { +- /* There was an error writing. */ +- SetPageError(pg); +- } +- +- /* Adjust writtenlen for the padding we did, so we don't confuse our caller */ +- writtenlen -= min(writtenlen, (start - aligned_start)); +- +- if (writtenlen) { +- if (inode->i_size < pos + writtenlen) { +- inode->i_size = pos + writtenlen; +- inode->i_blocks = (inode->i_size + 511) >> 9; +- +- inode->i_ctime = inode->i_mtime = ITIME(je32_to_cpu(ri->ctime)); +- } +- } +- +- jffs2_free_raw_inode(ri); +- +- if (start+writtenlen < end) { +- /* generic_file_write has written more to the page cache than we've +- actually written to the medium. Mark the page !Uptodate so that +- it gets reread */ +- jffs2_dbg(1, "%s(): Not all bytes written. Marking page !uptodate\n", +- __func__); +- SetPageError(pg); +- ClearPageUptodate(pg); +- } +- +- jffs2_dbg(1, "%s() returning %d\n", +- __func__, writtenlen > 0 ? writtenlen : ret); +- unlock_page(pg); +- put_page(pg); +- return writtenlen > 0 ? writtenlen : ret; ++ /* Do nothing */ + } +diff -Nupr old/fs/jffs2/fs.c new/fs/jffs2/fs.c +--- old/fs/jffs2/fs.c 2022-05-09 17:22:53.000000000 +0800 ++++ new/fs/jffs2/fs.c 2022-05-10 16:13:37.830000000 +0800 +@@ -10,136 +10,129 @@ + * + */ + +-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include ++#include + #include "nodelist.h" ++#include "os-linux.h" ++#include "los_crc32.h" ++#include "jffs2_hash.h" ++#include "capability_type.h" ++#include "capability_api.h" + +-static int jffs2_flash_setup(struct jffs2_sb_info *c); +- +-int jffs2_do_setattr (struct inode *inode, struct iattr *iattr) ++int jffs2_setattr (struct jffs2_inode *inode, struct IATTR *attr) + { + struct jffs2_full_dnode *old_metadata, *new_metadata; + struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); + struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); + struct jffs2_raw_inode *ri; +- union jffs2_device_node dev; +- unsigned char *mdata = NULL; +- int mdatalen = 0; + unsigned int ivalid; ++ mode_t tmp_mode; ++ uint c_uid = OsCurrUserGet()->effUserID; ++ uint c_gid = OsCurrUserGet()->effGid; + uint32_t alloclen; + int ret; + int alloc_type = ALLOC_NORMAL; + + jffs2_dbg(1, "%s(): ino #%lu\n", __func__, inode->i_ino); +- +- /* Special cases - we don't want more than one data node +- for these types on the medium at any time. So setattr +- must read the original data associated with the node +- (i.e. the device numbers or the target name) and write +- it out again with the appropriate data attached */ +- if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) { +- /* For these, we don't actually need to read the old node */ +- mdatalen = jffs2_encode_dev(&dev, inode->i_rdev); +- mdata = (char *)&dev; +- jffs2_dbg(1, "%s(): Writing %d bytes of kdev_t\n", +- __func__, mdatalen); +- } else if (S_ISLNK(inode->i_mode)) { +- mutex_lock(&f->sem); +- mdatalen = f->metadata->size; +- mdata = kmalloc(f->metadata->size, GFP_USER); +- if (!mdata) { +- mutex_unlock(&f->sem); +- return -ENOMEM; +- } +- ret = jffs2_read_dnode(c, f, f->metadata, mdata, 0, mdatalen); +- if (ret) { +- mutex_unlock(&f->sem); +- kfree(mdata); +- return ret; +- } +- mutex_unlock(&f->sem); +- jffs2_dbg(1, "%s(): Writing %d bytes of symlink target\n", +- __func__, mdatalen); +- } +- + ri = jffs2_alloc_raw_inode(); + if (!ri) { +- if (S_ISLNK(inode->i_mode)) +- kfree(mdata); + return -ENOMEM; + } + +- ret = jffs2_reserve_space(c, sizeof(*ri) + mdatalen, &alloclen, +- ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); ++ ret = jffs2_reserve_space(c, sizeof(*ri), &alloclen, ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); ++ + if (ret) { + jffs2_free_raw_inode(ri); +- if (S_ISLNK(inode->i_mode)) +- kfree(mdata); + return ret; + } + mutex_lock(&f->sem); +- ivalid = iattr->ia_valid; ++ ivalid = attr->attr_chg_valid; ++ tmp_mode = inode->i_mode; + + ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); + ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE); +- ri->totlen = cpu_to_je32(sizeof(*ri) + mdatalen); +- ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4)); ++ ri->totlen = cpu_to_je32(sizeof(*ri)); ++ ri->hdr_crc = cpu_to_je32(crc32(0, ri, (sizeof(struct jffs2_unknown_node)-4))); + + ri->ino = cpu_to_je32(inode->i_ino); + ri->version = cpu_to_je32(++f->highest_version); ++ ri->uid = cpu_to_je16(inode->i_uid); ++ ri->gid = cpu_to_je16(inode->i_gid); + +- ri->uid = cpu_to_je16((ivalid & ATTR_UID)? +- from_kuid(&init_user_ns, iattr->ia_uid):i_uid_read(inode)); +- ri->gid = cpu_to_je16((ivalid & ATTR_GID)? +- from_kgid(&init_user_ns, iattr->ia_gid):i_gid_read(inode)); ++ if (ivalid & CHG_UID) { ++ if (((c_uid != inode->i_uid) || (attr->attr_chg_uid != inode->i_uid)) && (!IsCapPermit(CAP_CHOWN))) { ++ jffs2_complete_reservation(c); ++ jffs2_free_raw_inode(ri); ++ mutex_unlock(&f->sem); ++ return -EPERM; ++ } else { ++ ri->uid = cpu_to_je16(attr->attr_chg_uid); ++ } ++ } ++ ++ if (ivalid & CHG_GID) { ++ if (((c_gid != inode->i_gid) || (attr->attr_chg_gid != inode->i_gid)) && (!IsCapPermit(CAP_CHOWN))) { ++ jffs2_complete_reservation(c); ++ jffs2_free_raw_inode(ri); ++ mutex_unlock(&f->sem); ++ return -EPERM; ++ } else { ++ ri->gid = cpu_to_je16(attr->attr_chg_gid); ++ } ++ } ++ ++ if (ivalid & CHG_MODE) { ++ if (!IsCapPermit(CAP_FOWNER) && (c_uid != inode->i_uid)) { ++ jffs2_complete_reservation(c); ++ jffs2_free_raw_inode(ri); ++ mutex_unlock(&f->sem); ++ return -EPERM; ++ } else { ++ attr->attr_chg_mode &= ~S_IFMT; // delete file type ++ tmp_mode &= S_IFMT; ++ tmp_mode = attr->attr_chg_mode | tmp_mode; // add old file type ++ } ++ } + +- if (ivalid & ATTR_MODE) +- ri->mode = cpu_to_jemode(iattr->ia_mode); +- else +- ri->mode = cpu_to_jemode(inode->i_mode); ++ if (ivalid & CHG_ATIME) { ++ if ((c_uid != inode->i_uid) || (attr->attr_chg_uid != inode->i_uid)) { ++ return -EPERM; ++ } else { ++ ri->atime = cpu_to_je32(attr->attr_chg_atime); ++ } ++ } else { ++ ri->atime = cpu_to_je32(inode->i_atime); ++ } + ++ if (ivalid & CHG_MTIME) { ++ if ((c_uid != inode->i_uid) || (attr->attr_chg_uid != inode->i_uid)) { ++ return -EPERM; ++ } else { ++ ri->mtime = cpu_to_je32(attr->attr_chg_mtime); ++ } ++ } else { ++ ri->mtime = cpu_to_je32(Jffs2CurSec()); ++ } ++ ri->mode = cpu_to_jemode(tmp_mode); + +- ri->isize = cpu_to_je32((ivalid & ATTR_SIZE)?iattr->ia_size:inode->i_size); +- ri->atime = cpu_to_je32(I_SEC((ivalid & ATTR_ATIME)?iattr->ia_atime:inode->i_atime)); +- ri->mtime = cpu_to_je32(I_SEC((ivalid & ATTR_MTIME)?iattr->ia_mtime:inode->i_mtime)); +- ri->ctime = cpu_to_je32(I_SEC((ivalid & ATTR_CTIME)?iattr->ia_ctime:inode->i_ctime)); ++ ri->isize = cpu_to_je32((ivalid & CHG_SIZE) ? attr->attr_chg_size : inode->i_size); ++ ri->ctime = cpu_to_je32(Jffs2CurSec()); + + ri->offset = cpu_to_je32(0); +- ri->csize = ri->dsize = cpu_to_je32(mdatalen); ++ ri->csize = ri->dsize = cpu_to_je32(0); + ri->compr = JFFS2_COMPR_NONE; +- if (ivalid & ATTR_SIZE && inode->i_size < iattr->ia_size) { ++ if (ivalid & CHG_SIZE && inode->i_size < attr->attr_chg_size) { + /* It's an extension. Make it a hole node */ + ri->compr = JFFS2_COMPR_ZERO; +- ri->dsize = cpu_to_je32(iattr->ia_size - inode->i_size); ++ ri->dsize = cpu_to_je32(attr->attr_chg_size - inode->i_size); + ri->offset = cpu_to_je32(inode->i_size); +- } else if (ivalid & ATTR_SIZE && !iattr->ia_size) { ++ } else if (ivalid & CHG_SIZE && !attr->attr_chg_size) { + /* For truncate-to-zero, treat it as deletion because + it'll always be obsoleting all previous nodes */ + alloc_type = ALLOC_DELETION; + } +- ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); +- if (mdatalen) +- ri->data_crc = cpu_to_je32(crc32(0, mdata, mdatalen)); +- else +- ri->data_crc = cpu_to_je32(0); +- +- new_metadata = jffs2_write_dnode(c, f, ri, mdata, mdatalen, alloc_type); +- if (S_ISLNK(inode->i_mode)) +- kfree(mdata); +- ++ ri->node_crc = cpu_to_je32(crc32(0, ri, (sizeof(*ri)-8))); ++ ri->data_crc = cpu_to_je32(0); ++ new_metadata = jffs2_write_dnode(c, f, ri, NULL, 0, alloc_type); + if (IS_ERR(new_metadata)) { + jffs2_complete_reservation(c); + jffs2_free_raw_inode(ri); +@@ -147,23 +140,20 @@ int jffs2_do_setattr (struct inode *inode, struct iattr *iattr) + return PTR_ERR(new_metadata); + } + /* It worked. Update the inode */ +- inode->i_atime = ITIME(je32_to_cpu(ri->atime)); +- inode->i_ctime = ITIME(je32_to_cpu(ri->ctime)); +- inode->i_mtime = ITIME(je32_to_cpu(ri->mtime)); ++ inode->i_atime = je32_to_cpu(ri->atime); ++ inode->i_ctime = je32_to_cpu(ri->ctime); ++ inode->i_mtime = je32_to_cpu(ri->mtime); + inode->i_mode = jemode_to_cpu(ri->mode); +- i_uid_write(inode, je16_to_cpu(ri->uid)); +- i_gid_write(inode, je16_to_cpu(ri->gid)); +- ++ inode->i_uid = je16_to_cpu(ri->uid); ++ inode->i_gid = je16_to_cpu(ri->gid); + + old_metadata = f->metadata; ++ if (ivalid & CHG_SIZE && inode->i_size > attr->attr_chg_size) ++ jffs2_truncate_fragtree (c, &f->fragtree, attr->attr_chg_size); + +- if (ivalid & ATTR_SIZE && inode->i_size > iattr->ia_size) +- jffs2_truncate_fragtree (c, &f->fragtree, iattr->ia_size); +- +- if (ivalid & ATTR_SIZE && inode->i_size < iattr->ia_size) { ++ if (ivalid & CHG_SIZE && inode->i_size < attr->attr_chg_size) { + jffs2_add_full_dnode_to_inode(c, f, new_metadata); +- inode->i_size = iattr->ia_size; +- inode->i_blocks = (inode->i_size + 511) >> 9; ++ inode->i_size = attr->attr_chg_size; + f->metadata = NULL; + } else { + f->metadata = new_metadata; +@@ -182,315 +172,201 @@ int jffs2_do_setattr (struct inode *inode, struct iattr *iattr) + We are protected from a simultaneous write() extending i_size + back past iattr->ia_size, because do_truncate() holds the + generic inode semaphore. */ +- if (ivalid & ATTR_SIZE && inode->i_size > iattr->ia_size) { +- truncate_setsize(inode, iattr->ia_size); +- inode->i_blocks = (inode->i_size + 511) >> 9; ++ if (ivalid & CHG_SIZE && inode->i_size > attr->attr_chg_size) { ++ inode->i_size = attr->attr_chg_size; // truncate_setsize + } + + return 0; + } + +-int jffs2_setattr(struct dentry *dentry, struct iattr *iattr) ++static void jffs2_clear_inode (struct jffs2_inode *inode) + { +- struct inode *inode = d_inode(dentry); +- int rc; ++ /* We can forget about this inode for now - drop all ++ * the nodelists associated with it, etc. ++ */ ++ struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); ++ struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); ++ ++ jffs2_do_clear_inode(c, f); ++} + +- rc = setattr_prepare(dentry, iattr); +- if (rc) +- return rc; ++static struct jffs2_inode *ilookup(struct super_block *sb, uint32_t ino) ++{ ++ struct jffs2_inode *node = NULL; + +- rc = jffs2_do_setattr(inode, iattr); +- if (!rc && (iattr->ia_valid & ATTR_MODE)) +- rc = posix_acl_chmod(inode, inode->i_mode); ++ if (sb->s_root == NULL) { ++ return NULL; ++ } + +- return rc; ++ // Check for this inode in the cache ++ Jffs2NodeLock(); ++ (void)Jffs2HashGet(&sb->s_node_hash_lock, &sb->s_node_hash[0], sb, ino, &node); ++ Jffs2NodeUnlock(); ++ return node; + } + +-int jffs2_statfs(struct dentry *dentry, struct kstatfs *buf) ++struct jffs2_inode *new_inode(struct super_block *sb) + { +- struct jffs2_sb_info *c = JFFS2_SB_INFO(dentry->d_sb); +- unsigned long avail; +- +- buf->f_type = JFFS2_SUPER_MAGIC; +- buf->f_bsize = 1 << PAGE_SHIFT; +- buf->f_blocks = c->flash_size >> PAGE_SHIFT; +- buf->f_files = 0; +- buf->f_ffree = 0; +- buf->f_namelen = JFFS2_MAX_NAME_LEN; +- buf->f_fsid.val[0] = JFFS2_SUPER_MAGIC; +- buf->f_fsid.val[1] = c->mtd->index; +- +- spin_lock(&c->erase_completion_lock); +- avail = c->dirty_size + c->free_size; +- if (avail > c->sector_size * c->resv_blocks_write) +- avail -= c->sector_size * c->resv_blocks_write; +- else +- avail = 0; +- spin_unlock(&c->erase_completion_lock); +- +- buf->f_bavail = buf->f_bfree = avail >> PAGE_SHIFT; ++ struct jffs2_inode *inode = NULL; + +- return 0; +-} ++ inode = zalloc(sizeof (struct jffs2_inode)); ++ if (inode == NULL) ++ return 0; + ++ D2(PRINTK("malloc new_inode %x ####################################\n", ++ inode)); + +-void jffs2_evict_inode (struct inode *inode) +-{ +- /* We can forget about this inode for now - drop all +- * the nodelists associated with it, etc. +- */ +- struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); +- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); ++ inode->i_sb = sb; ++ inode->i_ino = 1; ++ inode->i_nlink = 1; // Let JFFS2 manage the link count ++ inode->i_size = 0; ++ LOS_ListInit((&(inode->i_hashlist))); + +- jffs2_dbg(1, "%s(): ino #%lu mode %o\n", +- __func__, inode->i_ino, inode->i_mode); +- truncate_inode_pages_final(&inode->i_data); +- clear_inode(inode); +- jffs2_do_clear_inode(c, f); ++ return inode; + } + +-struct inode *jffs2_iget(struct super_block *sb, unsigned long ino) ++struct jffs2_inode *jffs2_iget(struct super_block *sb, uint32_t ino) + { + struct jffs2_inode_info *f; + struct jffs2_sb_info *c; + struct jffs2_raw_inode latest_node; +- union jffs2_device_node jdev; +- struct inode *inode; +- dev_t rdev = 0; ++ struct jffs2_inode *inode; + int ret; + +- jffs2_dbg(1, "%s(): ino == %lu\n", __func__, ino); +- +- inode = iget_locked(sb, ino); +- if (!inode) +- return ERR_PTR(-ENOMEM); +- if (!(inode->i_state & I_NEW)) ++ Jffs2NodeLock(); ++ inode = ilookup(sb, ino); ++ if (inode) { ++ Jffs2NodeUnlock(); + return inode; ++ } ++ inode = new_inode(sb); ++ if (inode == NULL) { ++ Jffs2NodeUnlock(); ++ return (struct jffs2_inode *)-ENOMEM; ++ } + ++ inode->i_ino = ino; + f = JFFS2_INODE_INFO(inode); + c = JFFS2_SB_INFO(inode->i_sb); + +- jffs2_init_inode_info(f); +- mutex_lock(&f->sem); ++ (void)mutex_init(&f->sem); ++ (void)mutex_lock(&f->sem); + + ret = jffs2_do_read_inode(c, f, inode->i_ino, &latest_node); +- if (ret) +- goto error; ++ if (ret) { ++ (void)mutex_unlock(&f->sem); ++ inode->i_nlink = 0; ++ free(inode); ++ Jffs2NodeUnlock(); ++ return (struct jffs2_inode *)ret; ++ } + + inode->i_mode = jemode_to_cpu(latest_node.mode); +- i_uid_write(inode, je16_to_cpu(latest_node.uid)); +- i_gid_write(inode, je16_to_cpu(latest_node.gid)); ++ inode->i_uid = je16_to_cpu(latest_node.uid); ++ inode->i_gid = je16_to_cpu(latest_node.gid); + inode->i_size = je32_to_cpu(latest_node.isize); +- inode->i_atime = ITIME(je32_to_cpu(latest_node.atime)); +- inode->i_mtime = ITIME(je32_to_cpu(latest_node.mtime)); +- inode->i_ctime = ITIME(je32_to_cpu(latest_node.ctime)); +- +- set_nlink(inode, f->inocache->pino_nlink); +- +- inode->i_blocks = (inode->i_size + 511) >> 9; ++ inode->i_atime = je32_to_cpu(latest_node.atime); ++ inode->i_mtime = je32_to_cpu(latest_node.mtime); ++ inode->i_ctime = je32_to_cpu(latest_node.ctime); ++ inode->i_nlink = f->inocache->pino_nlink; + +- switch (inode->i_mode & S_IFMT) { ++ (void)mutex_unlock(&f->sem); + +- case S_IFLNK: +- inode->i_op = &jffs2_symlink_inode_operations; +- inode->i_link = f->target; +- break; +- +- case S_IFDIR: +- { +- struct jffs2_full_dirent *fd; +- set_nlink(inode, 2); /* parent and '.' */ +- +- for (fd=f->dents; fd; fd = fd->next) { +- if (fd->type == DT_DIR && fd->ino) +- inc_nlink(inode); +- } +- /* Root dir gets i_nlink 3 for some reason */ +- if (inode->i_ino == 1) +- inc_nlink(inode); +- +- inode->i_op = &jffs2_dir_inode_operations; +- inode->i_fop = &jffs2_dir_operations; +- break; +- } +- case S_IFREG: +- inode->i_op = &jffs2_file_inode_operations; +- inode->i_fop = &jffs2_file_operations; +- inode->i_mapping->a_ops = &jffs2_file_address_operations; +- inode->i_mapping->nrpages = 0; +- break; +- +- case S_IFBLK: +- case S_IFCHR: +- /* Read the device numbers from the media */ +- if (f->metadata->size != sizeof(jdev.old_id) && +- f->metadata->size != sizeof(jdev.new_id)) { +- pr_notice("Device node has strange size %d\n", +- f->metadata->size); +- goto error_io; +- } +- jffs2_dbg(1, "Reading device numbers from flash\n"); +- ret = jffs2_read_dnode(c, f, f->metadata, (char *)&jdev, 0, f->metadata->size); +- if (ret < 0) { +- /* Eep */ +- pr_notice("Read device numbers for inode %lu failed\n", +- (unsigned long)inode->i_ino); +- goto error; +- } +- if (f->metadata->size == sizeof(jdev.old_id)) +- rdev = old_decode_dev(je16_to_cpu(jdev.old_id)); +- else +- rdev = new_decode_dev(je32_to_cpu(jdev.new_id)); +- fallthrough; +- +- case S_IFSOCK: +- case S_IFIFO: +- inode->i_op = &jffs2_file_inode_operations; +- init_special_inode(inode, inode->i_mode, rdev); +- break; +- +- default: +- pr_warn("%s(): Bogus i_mode %o for ino %lu\n", +- __func__, inode->i_mode, (unsigned long)inode->i_ino); +- } +- +- mutex_unlock(&f->sem); ++ (void)Jffs2HashInsert(&sb->s_node_hash_lock, &sb->s_node_hash[0], inode, ino); + + jffs2_dbg(1, "jffs2_read_inode() returning\n"); +- unlock_new_inode(inode); +- return inode; ++ Jffs2NodeUnlock(); + +-error_io: +- ret = -EIO; +-error: +- mutex_unlock(&f->sem); +- iget_failed(inode); +- return ERR_PTR(ret); ++ return inode; + } + +-void jffs2_dirty_inode(struct inode *inode, int flags) +-{ +- struct iattr iattr; + +- if (!(inode->i_state & I_DIRTY_DATASYNC)) { +- jffs2_dbg(2, "%s(): not calling setattr() for ino #%lu\n", +- __func__, inode->i_ino); +- return; +- } +- +- jffs2_dbg(1, "%s(): calling setattr() for ino #%lu\n", +- __func__, inode->i_ino); +- +- iattr.ia_valid = ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_MTIME|ATTR_CTIME; +- iattr.ia_mode = inode->i_mode; +- iattr.ia_uid = inode->i_uid; +- iattr.ia_gid = inode->i_gid; +- iattr.ia_atime = inode->i_atime; +- iattr.ia_mtime = inode->i_mtime; +- iattr.ia_ctime = inode->i_ctime; +- +- jffs2_do_setattr(inode, &iattr); +-} ++// ------------------------------------------------------------------------- ++// Decrement the reference count on an inode. If this makes the ref count ++// zero, then this inode can be freed. + +-int jffs2_do_remount_fs(struct super_block *sb, struct fs_context *fc) ++int jffs2_iput(struct jffs2_inode *i) + { +- struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); +- +- if (c->flags & JFFS2_SB_FLAG_RO && !sb_rdonly(sb)) +- return -EROFS; +- +- /* We stop if it was running, then restart if it needs to. +- This also catches the case where it was stopped and this +- is just a remount to restart it. +- Flush the writebuffer, if neccecary, else we loose it */ +- if (!sb_rdonly(sb)) { +- jffs2_stop_garbage_collect_thread(c); +- mutex_lock(&c->alloc_sem); +- jffs2_flush_wbuf_pad(c); +- mutex_unlock(&c->alloc_sem); +- } +- +- if (!(fc->sb_flags & SB_RDONLY)) +- jffs2_start_garbage_collect_thread(c); ++ // Called in jffs2_find ++ // (and jffs2_open and jffs2_ops_mkdir?) ++ // super.c jffs2_fill_super, ++ // and gc.c jffs2_garbage_collect_pass ++ struct jffs2_inode_info *f = NULL; ++ ++ Jffs2NodeLock(); ++ if (!i || i->i_nlink) { ++ // and let it fault... ++ Jffs2NodeUnlock(); ++ return -EBUSY; ++ } ++ ++ jffs2_clear_inode(i); ++ f = JFFS2_INODE_INFO(i); ++ (void)mutex_destroy(&(f->sem)); ++ (void)Jffs2HashRemove(&i->i_sb->s_node_hash_lock, i); ++ (void)memset_s(i, sizeof(*i), 0x5a, sizeof(*i)); ++ free(i); ++ Jffs2NodeUnlock(); + +- fc->sb_flags |= SB_NOATIME; + return 0; + } + ++ + /* jffs2_new_inode: allocate a new inode and inocache, add it to the hash, + fill in the raw_inode while you're at it. */ +-struct inode *jffs2_new_inode (struct inode *dir_i, umode_t mode, struct jffs2_raw_inode *ri) ++struct jffs2_inode *jffs2_new_inode (struct jffs2_inode *dir_i, int mode, struct jffs2_raw_inode *ri) + { +- struct inode *inode; ++ struct jffs2_inode *inode; + struct super_block *sb = dir_i->i_sb; + struct jffs2_sb_info *c; + struct jffs2_inode_info *f; + int ret; + +- jffs2_dbg(1, "%s(): dir_i %ld, mode 0x%x\n", +- __func__, dir_i->i_ino, mode); +- + c = JFFS2_SB_INFO(sb); + ++ Jffs2NodeLock(); + inode = new_inode(sb); + + if (!inode) +- return ERR_PTR(-ENOMEM); ++ return (struct jffs2_inode *)-ENOMEM; + + f = JFFS2_INODE_INFO(inode); +- jffs2_init_inode_info(f); +- mutex_lock(&f->sem); ++ (void)mutex_init(&f->sem); ++ (void)mutex_lock(&f->sem);; + + memset(ri, 0, sizeof(*ri)); + /* Set OS-specific defaults for new inodes */ +- ri->uid = cpu_to_je16(from_kuid(&init_user_ns, current_fsuid())); ++ ri->uid = cpu_to_je16(OsCurrUserGet()->effUserID); ++ ri->gid = cpu_to_je16(OsCurrUserGet()->effGid); + +- if (dir_i->i_mode & S_ISGID) { +- ri->gid = cpu_to_je16(i_gid_read(dir_i)); +- if (S_ISDIR(mode)) +- mode |= S_ISGID; +- } else { +- ri->gid = cpu_to_je16(from_kgid(&init_user_ns, current_fsgid())); +- } +- +- /* POSIX ACLs have to be processed now, at least partly. +- The umask is only applied if there's no default ACL */ +- ret = jffs2_init_acl_pre(dir_i, inode, &mode); +- if (ret) { +- mutex_unlock(&f->sem); +- make_bad_inode(inode); +- iput(inode); +- return ERR_PTR(ret); +- } + ret = jffs2_do_new_inode (c, f, mode, ri); + if (ret) { +- mutex_unlock(&f->sem); +- make_bad_inode(inode); +- iput(inode); +- return ERR_PTR(ret); ++ mutex_unlock(&(f->sem)); ++ jffs2_clear_inode(inode); ++ (void)mutex_destroy(&(f->sem)); ++ (void)memset_s(inode, sizeof(*inode), 0x6a, sizeof(*inode)); ++ free(inode); ++ Jffs2NodeUnlock(); ++ return (struct jffs2_inode *)ret; ++ + } +- set_nlink(inode, 1); ++ inode->i_nlink = 1; + inode->i_ino = je32_to_cpu(ri->ino); + inode->i_mode = jemode_to_cpu(ri->mode); +- i_gid_write(inode, je16_to_cpu(ri->gid)); +- i_uid_write(inode, je16_to_cpu(ri->uid)); +- inode->i_atime = inode->i_ctime = inode->i_mtime = current_time(inode); +- ri->atime = ri->mtime = ri->ctime = cpu_to_je32(I_SEC(inode->i_mtime)); ++ inode->i_gid = je16_to_cpu(ri->gid); ++ inode->i_uid = je16_to_cpu(ri->uid); ++ inode->i_atime = inode->i_ctime = inode->i_mtime = Jffs2CurSec(); ++ ri->atime = ri->mtime = ri->ctime = cpu_to_je32(inode->i_mtime); + +- inode->i_blocks = 0; + inode->i_size = 0; + +- if (insert_inode_locked(inode) < 0) { +- mutex_unlock(&f->sem); +- make_bad_inode(inode); +- iput(inode); +- return ERR_PTR(-EINVAL); +- } ++ (void)Jffs2HashInsert(&sb->s_node_hash_lock, &sb->s_node_hash[0], inode, inode->i_ino); ++ Jffs2NodeUnlock(); + + return inode; + } + +-static int calculate_inocache_hashsize(uint32_t flash_size) ++int calculate_inocache_hashsize(uint32_t flash_size) + { + /* + * Pick a inocache hash size based on the size of the medium. +@@ -510,118 +386,17 @@ static int calculate_inocache_hashsize(uint32_t flash_size) + return hashsize; + } + +-int jffs2_do_fill_super(struct super_block *sb, struct fs_context *fc) +-{ +- struct jffs2_sb_info *c; +- struct inode *root_i; +- int ret; +- size_t blocks; +- +- c = JFFS2_SB_INFO(sb); +- +- /* Do not support the MLC nand */ +- if (c->mtd->type == MTD_MLCNANDFLASH) +- return -EINVAL; +- +-#ifndef CONFIG_JFFS2_FS_WRITEBUFFER +- if (c->mtd->type == MTD_NANDFLASH) { +- errorf(fc, "Cannot operate on NAND flash unless jffs2 NAND support is compiled in"); +- return -EINVAL; +- } +- if (c->mtd->type == MTD_DATAFLASH) { +- errorf(fc, "Cannot operate on DataFlash unless jffs2 DataFlash support is compiled in"); +- return -EINVAL; +- } +-#endif +- +- c->flash_size = c->mtd->size; +- c->sector_size = c->mtd->erasesize; +- blocks = c->flash_size / c->sector_size; +- +- /* +- * Size alignment check +- */ +- if ((c->sector_size * blocks) != c->flash_size) { +- c->flash_size = c->sector_size * blocks; +- infof(fc, "Flash size not aligned to erasesize, reducing to %dKiB", +- c->flash_size / 1024); +- } +- +- if (c->flash_size < 5*c->sector_size) { +- errorf(fc, "Too few erase blocks (%d)", +- c->flash_size / c->sector_size); +- return -EINVAL; +- } +- +- c->cleanmarker_size = sizeof(struct jffs2_unknown_node); +- +- /* NAND (or other bizarre) flash... do setup accordingly */ +- ret = jffs2_flash_setup(c); +- if (ret) +- return ret; +- +- c->inocache_hashsize = calculate_inocache_hashsize(c->flash_size); +- c->inocache_list = kcalloc(c->inocache_hashsize, sizeof(struct jffs2_inode_cache *), GFP_KERNEL); +- if (!c->inocache_list) { +- ret = -ENOMEM; +- goto out_wbuf; +- } +- +- jffs2_init_xattr_subsystem(c); +- +- if ((ret = jffs2_do_mount_fs(c))) +- goto out_inohash; +- +- jffs2_dbg(1, "%s(): Getting root inode\n", __func__); +- root_i = jffs2_iget(sb, 1); +- if (IS_ERR(root_i)) { +- jffs2_dbg(1, "get root inode failed\n"); +- ret = PTR_ERR(root_i); +- goto out_root; +- } +- +- ret = -ENOMEM; +- +- jffs2_dbg(1, "%s(): d_make_root()\n", __func__); +- sb->s_root = d_make_root(root_i); +- if (!sb->s_root) +- goto out_root; +- +- sb->s_maxbytes = 0xFFFFFFFF; +- sb->s_blocksize = PAGE_SIZE; +- sb->s_blocksize_bits = PAGE_SHIFT; +- sb->s_magic = JFFS2_SUPER_MAGIC; +- sb->s_time_min = 0; +- sb->s_time_max = U32_MAX; +- +- if (!sb_rdonly(sb)) +- jffs2_start_garbage_collect_thread(c); +- return 0; +- +-out_root: +- jffs2_free_ino_caches(c); +- jffs2_free_raw_node_refs(c); +- kvfree(c->blocks); +- jffs2_clear_xattr_subsystem(c); +- jffs2_sum_exit(c); +- out_inohash: +- kfree(c->inocache_list); +- out_wbuf: +- jffs2_flash_cleanup(c); +- +- return ret; +-} +- + void jffs2_gc_release_inode(struct jffs2_sb_info *c, + struct jffs2_inode_info *f) + { +- iput(OFNI_EDONI_2SFFJ(f)); ++ struct jffs2_inode *node = OFNI_EDONI_2SFFJ(f); ++ jffs2_iput(node); + } + + struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c, + int inum, int unlinked) + { +- struct inode *inode; ++ struct jffs2_inode *inode; + struct jffs2_inode_cache *ic; + + if (unlinked) { +@@ -669,72 +444,9 @@ struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c, + Just iget() it, and if read_inode() is necessary that's OK. + */ + inode = jffs2_iget(OFNI_BS_2SFFJ(c), inum); +- if (IS_ERR(inode)) +- return ERR_CAST(inode); +- } +- if (is_bad_inode(inode)) { +- pr_notice("Eep. read_inode() failed for ino #%u. unlinked %d\n", +- inum, unlinked); +- /* NB. This will happen again. We need to do something appropriate here. */ +- iput(inode); +- return ERR_PTR(-EIO); ++ if (inode <= 0) ++ return (struct jffs2_inode_info *)inode; + } + + return JFFS2_INODE_INFO(inode); + } +- +-static int jffs2_flash_setup(struct jffs2_sb_info *c) { +- int ret = 0; +- +- if (jffs2_cleanmarker_oob(c)) { +- /* NAND flash... do setup accordingly */ +- ret = jffs2_nand_flash_setup(c); +- if (ret) +- return ret; +- } +- +- /* and Dataflash */ +- if (jffs2_dataflash(c)) { +- ret = jffs2_dataflash_setup(c); +- if (ret) +- return ret; +- } +- +- /* and Intel "Sibley" flash */ +- if (jffs2_nor_wbuf_flash(c)) { +- ret = jffs2_nor_wbuf_flash_setup(c); +- if (ret) +- return ret; +- } +- +- /* and an UBI volume */ +- if (jffs2_ubivol(c)) { +- ret = jffs2_ubivol_setup(c); +- if (ret) +- return ret; +- } +- +- return ret; +-} +- +-void jffs2_flash_cleanup(struct jffs2_sb_info *c) { +- +- if (jffs2_cleanmarker_oob(c)) { +- jffs2_nand_flash_cleanup(c); +- } +- +- /* and DataFlash */ +- if (jffs2_dataflash(c)) { +- jffs2_dataflash_cleanup(c); +- } +- +- /* and Intel "Sibley" flash */ +- if (jffs2_nor_wbuf_flash(c)) { +- jffs2_nor_wbuf_flash_cleanup(c); +- } +- +- /* and an UBI volume */ +- if (jffs2_ubivol(c)) { +- jffs2_ubivol_cleanup(c); +- } +-} +diff -Nupr old/fs/jffs2/gc.c new/fs/jffs2/gc.c +--- old/fs/jffs2/gc.c 2022-05-09 17:22:53.000000000 +0800 ++++ new/fs/jffs2/gc.c 2022-05-10 16:11:42.090000000 +0800 +@@ -10,17 +10,17 @@ + * + */ + +-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +- + #include +-#include + #include + #include +-#include ++#include ++#include + #include + #include ++#include "mtd_dev.h" + #include "nodelist.h" + #include "compr.h" ++#include "los_crc32.h" + + static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c, + struct jffs2_inode_cache *ic, +@@ -43,7 +43,7 @@ static int jffs2_garbage_collect_live(st + /* Called with erase_completion_lock held */ + static struct jffs2_eraseblock *jffs2_find_gc_block(struct jffs2_sb_info *c) + { +- struct jffs2_eraseblock *ret; ++ struct jffs2_eraseblock *ret = NULL; + struct list_head *nextlist = NULL; + int n = jiffies % 128; + +@@ -131,62 +131,40 @@ int jffs2_garbage_collect_pass(struct jf + int ret = 0, inum, nlink; + int xattr = 0; + +- if (mutex_lock_interruptible(&c->alloc_sem)) ++ if (mutex_lock(&c->alloc_sem)) + return -EINTR; + +- + for (;;) { +- /* We can't start doing GC until we've finished checking +- the node CRCs etc. */ +- int bucket, want_ino; +- + spin_lock(&c->erase_completion_lock); + if (!c->unchecked_size) + break; ++ ++ /* We can't start doing GC yet. We haven't finished checking ++ the node CRCs etc. Do it now. */ ++ ++ /* checked_ino is protected by the alloc_sem */ ++ if (c->checked_ino > c->highest_ino && xattr) { ++ pr_crit("Checked all inodes but still 0x%x bytes of unchecked space?\n", ++ c->unchecked_size); ++ jffs2_dbg_dump_block_lists_nolock(c); ++ spin_unlock(&c->erase_completion_lock); ++ mutex_unlock(&c->alloc_sem); ++ return -ENOSPC; ++ } ++ + spin_unlock(&c->erase_completion_lock); + + if (!xattr) + xattr = jffs2_verify_xattr(c); + + spin_lock(&c->inocache_lock); +- /* Instead of doing the inodes in numeric order, doing a lookup +- * in the hash for each possible number, just walk the hash +- * buckets of *existing* inodes. This means that we process +- * them out-of-order, but it can be a lot faster if there's +- * a sparse inode# space. Which there often is. */ +- want_ino = c->check_ino; +- for (bucket = c->check_ino % c->inocache_hashsize ; bucket < c->inocache_hashsize; bucket++) { +- for (ic = c->inocache_list[bucket]; ic; ic = ic->next) { +- if (ic->ino < want_ino) +- continue; +- +- if (ic->state != INO_STATE_CHECKEDABSENT && +- ic->state != INO_STATE_PRESENT) +- goto got_next; /* with inocache_lock held */ + +- jffs2_dbg(1, "Skipping ino #%u already checked\n", +- ic->ino); +- } +- want_ino = 0; +- } +- +- /* Point c->check_ino past the end of the last bucket. */ +- c->check_ino = ((c->highest_ino + c->inocache_hashsize + 1) & +- ~c->inocache_hashsize) - 1; +- +- spin_unlock(&c->inocache_lock); +- +- pr_crit("Checked all inodes but still 0x%x bytes of unchecked space?\n", +- c->unchecked_size); +- jffs2_dbg_dump_block_lists_nolock(c); +- mutex_unlock(&c->alloc_sem); +- return -ENOSPC; ++ ic = jffs2_get_ino_cache(c, c->checked_ino++); + +- got_next: +- /* For next time round the loop, we want c->checked_ino to indicate +- * the *next* one we want to check. And since we're walking the +- * buckets rather than doing it sequentially, it's: */ +- c->check_ino = ic->ino + c->inocache_hashsize; ++ if (!ic) { ++ spin_unlock(&c->inocache_lock); ++ continue; ++ } + + if (!ic->pino_nlink) { + jffs2_dbg(1, "Skipping check of ino #%d with nlink/pino zero\n", +@@ -198,6 +176,8 @@ int jffs2_garbage_collect_pass(struct jf + switch(ic->state) { + case INO_STATE_CHECKEDABSENT: + case INO_STATE_PRESENT: ++ jffs2_dbg(1, "Skipping ino #%u already checked\n", ++ ic->ino); + spin_unlock(&c->inocache_lock); + continue; + +@@ -207,6 +187,7 @@ int jffs2_garbage_collect_pass(struct jf + ic->ino, ic->state); + spin_unlock(&c->inocache_lock); + BUG(); ++ break; + + case INO_STATE_READING: + /* We need to wait for it to finish, lest we move on +@@ -216,7 +197,7 @@ int jffs2_garbage_collect_pass(struct jf + ic->ino); + /* We need to come back again for the _same_ inode. We've + made no progress in this case, but that should be OK */ +- c->check_ino = ic->ino; ++ c->checked_ino--; + + mutex_unlock(&c->alloc_sem); + sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock); +@@ -224,6 +205,7 @@ int jffs2_garbage_collect_pass(struct jf + + default: + BUG(); ++ break; + + case INO_STATE_UNCHECKED: + ; +@@ -290,7 +272,7 @@ int jffs2_garbage_collect_pass(struct jf + raw = jeb->gc_node; + gcblock_dirty = jeb->dirty_size; + +- while(ref_obsolete(raw)) { ++ while(raw && ref_obsolete(raw)) { + jffs2_dbg(1, "Node at 0x%08x is obsolete... skipping\n", + ref_offset(raw)); + raw = ref_next(raw); +@@ -310,7 +292,7 @@ int jffs2_garbage_collect_pass(struct jf + jffs2_dbg(1, "Going to garbage collect node at 0x%08x\n", + ref_offset(raw)); + +- if (!raw->next_in_ino) { ++ if (raw &&!raw->next_in_ino) { + /* Inode-less node. Clean marker, snapshot or something like that */ + spin_unlock(&c->erase_completion_lock); + if (ref_flags(raw) == REF_PRISTINE) { +@@ -368,7 +350,7 @@ int jffs2_garbage_collect_pass(struct jf + We can just copy any pristine nodes, but have + to prevent anyone else from doing read_inode() while + we're at it, so we set the state accordingly */ +- if (ref_flags(raw) == REF_PRISTINE) ++ if (raw && ref_flags(raw) == REF_PRISTINE) + ic->state = INO_STATE_GC; + else { + jffs2_dbg(1, "Ino #%u is absent but node not REF_PRISTINE. Reading.\n", +@@ -393,6 +375,7 @@ int jffs2_garbage_collect_pass(struct jf + mutex_unlock(&c->alloc_sem); + spin_unlock(&c->inocache_lock); + BUG(); ++ break; + + case INO_STATE_READING: + /* Someone's currently trying to read it. We must wait for +@@ -430,7 +413,6 @@ int jffs2_garbage_collect_pass(struct jf + + spin_lock(&c->inocache_lock); + ic->state = INO_STATE_CHECKEDABSENT; +- wake_up(&c->inocache_wq); + + if (ret != -EBADFD) { + spin_unlock(&c->inocache_lock); +@@ -460,9 +442,7 @@ int jffs2_garbage_collect_pass(struct jf + ret = 0; + goto release_sem; + } +- + ret = jffs2_garbage_collect_live(c, jeb, raw, f); +- + jffs2_gc_release_inode(c, f); + + test_gcnode: +@@ -541,7 +521,7 @@ static int jffs2_garbage_collect_live(st + break; /* We've found them all */ + } + } +- if (fn) { ++ if (fn != NULL && frag != NULL) { + if (ref_flags(raw) == REF_PRISTINE) { + ret = jffs2_garbage_collect_pristine(c, f->inocache, raw); + if (!ret) { +@@ -552,7 +532,7 @@ static int jffs2_garbage_collect_live(st + goto upnout; + } + /* We found a datanode. Do the GC */ +- if((start >> PAGE_SHIFT) < ((end-1) >> PAGE_SHIFT)) { ++ if((start >> PAGE_CACHE_SHIFT) < ((end-1) >> PAGE_CACHE_SHIFT)) { + /* It crosses a page boundary. Therefore, it must be a hole. */ + ret = jffs2_garbage_collect_hole(c, jeb, f, fn, start, end); + } else { +@@ -635,6 +615,7 @@ static int jffs2_garbage_collect_pristin + if (je32_to_cpu(node->u.hdr_crc) != crc) { + pr_warn("Header CRC failed on REF_PRISTINE node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", + ref_offset(raw), je32_to_cpu(node->u.hdr_crc), crc); ++ jffs2_dbg_dump_node(c, ref_offset(raw)); + goto bail; + } + +@@ -645,6 +626,7 @@ static int jffs2_garbage_collect_pristin + pr_warn("Node CRC failed on REF_PRISTINE data node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", + ref_offset(raw), je32_to_cpu(node->i.node_crc), + crc); ++ jffs2_dbg_dump_node(c, ref_offset(raw)); + goto bail; + } + +@@ -654,6 +636,7 @@ static int jffs2_garbage_collect_pristin + pr_warn("Data CRC failed on REF_PRISTINE data node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", + ref_offset(raw), + je32_to_cpu(node->i.data_crc), crc); ++ jffs2_dbg_dump_node(c, ref_offset(raw)); + goto bail; + } + } +@@ -665,12 +648,14 @@ static int jffs2_garbage_collect_pristin + pr_warn("Node CRC failed on REF_PRISTINE dirent node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", + ref_offset(raw), + je32_to_cpu(node->d.node_crc), crc); ++ jffs2_dbg_dump_node(c, ref_offset(raw)); + goto bail; + } + +- if (strnlen(node->d.name, node->d.nsize) != node->d.nsize) { ++ if (strnlen((const char *)node->d.name, node->d.nsize) != node->d.nsize) { + pr_warn("Name in dirent node at 0x%08x contains zeroes\n", + ref_offset(raw)); ++ jffs2_dbg_dump_node(c, ref_offset(raw)); + goto bail; + } + +@@ -680,6 +665,7 @@ static int jffs2_garbage_collect_pristin + pr_warn("Name CRC failed on REF_PRISTINE dirent node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", + ref_offset(raw), + je32_to_cpu(node->d.name_crc), crc); ++ jffs2_dbg_dump_node(c, ref_offset(raw)); + goto bail; + } + } +@@ -689,6 +675,7 @@ static int jffs2_garbage_collect_pristin + if (ic) { + pr_warn("Unknown node type for REF_PRISTINE node at 0x%08x: 0x%04x\n", + ref_offset(raw), je16_to_cpu(node->u.nodetype)); ++ jffs2_dbg_dump_node(c, ref_offset(raw)); + goto bail; + } + } +@@ -697,7 +684,7 @@ static int jffs2_garbage_collect_pristin + retry: + phys_ofs = write_ofs(c); + +- ret = jffs2_flash_write(c, phys_ofs, rawlen, &retlen, (char *)node); ++ ret = jffs2_flash_write(c, phys_ofs, rawlen, &retlen, (const u_char *)node); + + if (ret || (retlen != rawlen)) { + pr_notice("Write of %d bytes at 0x%08x failed. returned %d, retlen %zd\n", +@@ -761,7 +748,7 @@ static int jffs2_garbage_collect_metadat + struct jffs2_full_dnode *new_fn; + struct jffs2_raw_inode ri; + struct jffs2_node_frag *last_frag; +- union jffs2_device_node dev; ++ jint16_t dev; + char *mdata = NULL; + int mdatalen = 0; + uint32_t alloclen, ilen; +@@ -770,8 +757,9 @@ static int jffs2_garbage_collect_metadat + if (S_ISBLK(JFFS2_F_I_MODE(f)) || + S_ISCHR(JFFS2_F_I_MODE(f)) ) { + /* For these, we don't actually need to read the old node */ +- mdatalen = jffs2_encode_dev(&dev, JFFS2_F_I_RDEV(f)); ++ dev = cpu_to_je16(((JFFS2_F_I_RDEV_MAJ(f) << 8) | JFFS2_F_I_RDEV_MIN(f))); + mdata = (char *)&dev; ++ mdatalen = sizeof(dev); + jffs2_dbg(1, "%s(): Writing %d bytes of kdev_t\n", + __func__, mdatalen); + } else if (S_ISLNK(JFFS2_F_I_MODE(f))) { +@@ -781,7 +769,7 @@ static int jffs2_garbage_collect_metadat + pr_warn("kmalloc of mdata failed in jffs2_garbage_collect_metadata()\n"); + return -ENOMEM; + } +- ret = jffs2_read_dnode(c, f, fn, mdata, 0, mdatalen); ++ ret = jffs2_read_dnode(c, f, fn, (unsigned char *)mdata, 0, mdatalen); + if (ret) { + pr_warn("read of old metadata failed in jffs2_garbage_collect_metadata(): %d\n", + ret); +@@ -831,7 +819,7 @@ static int jffs2_garbage_collect_metadat + ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8)); + ri.data_crc = cpu_to_je32(crc32(0, mdata, mdatalen)); + +- new_fn = jffs2_write_dnode(c, f, &ri, mdata, mdatalen, ALLOC_GC); ++ new_fn = jffs2_write_dnode(c, f, &ri, (unsigned char *)mdata, mdatalen, ALLOC_GC); + + if (IS_ERR(new_fn)) { + pr_warn("Error writing new dnode: %ld\n", PTR_ERR(new_fn)); +@@ -857,7 +845,7 @@ static int jffs2_garbage_collect_dirent( + + rd.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); + rd.nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT); +- rd.nsize = strlen(fd->name); ++ rd.nsize = strlen((const char *)fd->name); + rd.totlen = cpu_to_je32(sizeof(rd) + rd.nsize); + rd.hdr_crc = cpu_to_je32(crc32(0, &rd, sizeof(struct jffs2_unknown_node)-4)); + +@@ -908,7 +896,7 @@ static int jffs2_garbage_collect_deletio + struct jffs2_raw_node_ref *raw; + int ret; + size_t retlen; +- int name_len = strlen(fd->name); ++ int name_len = strlen((const char *)fd->name); + uint32_t name_crc = crc32(0, fd->name, name_len); + uint32_t rawlen = ref_totlen(c, jeb, fd->raw); + +@@ -1053,6 +1041,7 @@ static int jffs2_garbage_collect_hole(st + pr_warn("%s: Node at 0x%08x had CRC 0x%08x which doesn't match calculated CRC 0x%08x\n", + __func__, ref_offset(fn->raw), + je32_to_cpu(ri.node_crc), crc); ++ jffs2_dbg_dump_node(c, ref_offset(fn->raw)); + /* FIXME: We could possibly deal with this by writing new holes for each frag */ + pr_warn("Data in the range 0x%08x to 0x%08x of inode #%u will be lost\n", + start, end, f->inocache->ino); +@@ -1165,13 +1154,12 @@ static int jffs2_garbage_collect_dnode(s + struct jffs2_inode_info *f, struct jffs2_full_dnode *fn, + uint32_t start, uint32_t end) + { +- struct inode *inode = OFNI_EDONI_2SFFJ(f); + struct jffs2_full_dnode *new_fn; + struct jffs2_raw_inode ri; + uint32_t alloclen, offset, orig_end, orig_start; + int ret = 0; + unsigned char *comprbuf = NULL, *writebuf; +- struct page *page; ++ unsigned long pg; + unsigned char *pg_ptr; + + memset(&ri, 0, sizeof(ri)); +@@ -1193,8 +1181,8 @@ static int jffs2_garbage_collect_dnode(s + struct jffs2_node_frag *frag; + uint32_t min, max; + +- min = start & ~(PAGE_SIZE-1); +- max = min + PAGE_SIZE; ++ min = start & ~(PAGE_CACHE_SIZE-1); ++ max = min + PAGE_CACHE_SIZE; + + frag = jffs2_lookup_node_frag(&f->fragtree, start); + +@@ -1203,7 +1191,7 @@ static int jffs2_garbage_collect_dnode(s + BUG_ON(frag->ofs != start); + + /* First grow down... */ +- while((frag = frag_prev(frag)) && frag->ofs >= min) { ++ while(frag && (frag = frag_prev(frag)) && frag->ofs >= min) { + + /* If the previous frag doesn't even reach the beginning, there's + excessive fragmentation. Just merge. */ +@@ -1259,7 +1247,7 @@ static int jffs2_garbage_collect_dnode(s + /* Find last frag which is actually part of the node we're to GC. */ + frag = jffs2_lookup_node_frag(&f->fragtree, end-1); + +- while((frag = frag_next(frag)) && frag->ofs+frag->size <= max) { ++ while(frag && (frag = frag_next(frag)) && frag->ofs+frag->size <= max) { + + /* If the previous frag doesn't even reach the beginning, there's lots + of fragmentation. Just merge. */ +@@ -1317,27 +1305,21 @@ static int jffs2_garbage_collect_dnode(s + BUG_ON(start > orig_start); + } + +- /* The rules state that we must obtain the page lock *before* f->sem, so +- * drop f->sem temporarily. Since we also hold c->alloc_sem, nothing's +- * actually going to *change* so we're safe; we only allow reading. +- * +- * It is important to note that jffs2_write_begin() will ensure that its +- * page is marked Uptodate before allocating space. That means that if we +- * end up here trying to GC the *same* page that jffs2_write_begin() is +- * trying to write out, read_cache_page() will not deadlock. */ +- mutex_unlock(&f->sem); +- page = read_cache_page(inode->i_mapping, start >> PAGE_SHIFT, +- jffs2_do_readpage_unlock, inode); +- if (IS_ERR(page)) { ++ /* First, use readpage() to read the appropriate page into the page cache */ ++ /* Q: What happens if we actually try to GC the _same_ page for which commit_write() ++ * triggered garbage collection in the first place? ++ * A: I _think_ it's OK. read_cache_page shouldn't deadlock, we'll write out the ++ * page OK. We'll actually write it out again in commit_write, which is a little ++ * suboptimal, but at least we're correct. ++ */ ++ pg_ptr = jffs2_gc_fetch_page(c, f, start, &pg); ++ ++ if (IS_ERR(pg_ptr)) { + pr_warn("read_cache_page() returned error: %ld\n", +- PTR_ERR(page)); +- mutex_lock(&f->sem); +- return PTR_ERR(page); ++ PTR_ERR(pg_ptr)); ++ return PTR_ERR(pg_ptr); + } + +- pg_ptr = kmap(page); +- mutex_lock(&f->sem); +- + offset = start; + while(offset < orig_end) { + uint32_t datalen; +@@ -1355,7 +1337,7 @@ static int jffs2_garbage_collect_dnode(s + cdatalen = min_t(uint32_t, alloclen - sizeof(ri), end - offset); + datalen = end - offset; + +- writebuf = pg_ptr + (offset & (PAGE_SIZE -1)); ++ writebuf = pg_ptr + (offset & (PAGE_CACHE_SIZE -1)); + + comprtype = jffs2_compress(c, f, writebuf, &comprbuf, &datalen, &cdatalen); + +@@ -1400,7 +1382,6 @@ static int jffs2_garbage_collect_dnode(s + } + } + +- kunmap(page); +- put_page(page); ++ jffs2_gc_release_page(c, pg_ptr, &pg); + return ret; + } +diff -Nupr old/fs/jffs2/ioctl.c new/fs/jffs2/ioctl.c +--- old/fs/jffs2/ioctl.c 2022-05-09 17:15:24.350000000 +0800 ++++ new/fs/jffs2/ioctl.c 1970-01-01 08:00:00.000000000 +0800 +@@ -1,22 +0,0 @@ +-/* +- * JFFS2 -- Journalling Flash File System, Version 2. +- * +- * Copyright © 2001-2007 Red Hat, Inc. +- * Copyright © 2004-2010 David Woodhouse +- * +- * Created by David Woodhouse +- * +- * For licensing information, see the file 'LICENCE' in this directory. +- * +- */ +- +-#include +-#include "nodelist.h" +- +-long jffs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +-{ +- /* Later, this will provide for lsattr.jffs2 and chattr.jffs2, which +- will include compression support etc. */ +- return -ENOTTY; +-} +- +diff -Nupr old/fs/jffs2/jffs2_fs_i.h new/fs/jffs2/jffs2_fs_i.h +--- old/fs/jffs2/jffs2_fs_i.h 2022-05-09 17:22:53.000000000 +0800 ++++ new/fs/jffs2/jffs2_fs_i.h 2022-05-09 20:50:05.810000000 +0800 +@@ -14,8 +14,13 @@ + #define _JFFS2_FS_I + + #include +-#include +-#include ++#include ++ ++#ifdef __cplusplus ++#if __cplusplus ++extern "C" { ++#endif /* __cplusplus */ ++#endif /* __cplusplus */ + + struct jffs2_inode_info { + /* We need an internal mutex similar to inode->i_mutex. +@@ -24,7 +29,7 @@ struct jffs2_inode_info { + before letting GC proceed. Or we'd have to put ugliness + into the GC code so it didn't attempt to obtain the i_mutex + for the inode(s) which are already locked */ +- struct mutex sem; ++ struct pthread_mutex sem; + + /* The highest (datanode) version number used for this ino */ + uint32_t highest_version; +@@ -50,7 +55,29 @@ struct jffs2_inode_info { + + uint16_t flags; + uint8_t usercompr; +- struct inode vfs_inode; + }; + ++struct super_block; ++ ++struct jffs2_inode { ++ uint32_t i_ino; ++ mode_t i_mode; ++ nlink_t i_nlink; ++ uid_t i_uid; ++ gid_t i_gid; ++ time_t i_atime; ++ time_t i_mtime; ++ time_t i_ctime; ++ off_t i_size; ++ struct super_block *i_sb; ++ LOS_DL_LIST i_hashlist; ++ struct jffs2_inode_info jffs2_i; ++}; ++ ++#ifdef __cplusplus ++#if __cplusplus ++} ++#endif /* __cplusplus */ ++#endif /* __cplusplus */ ++ + #endif /* _JFFS2_FS_I */ +diff -Nupr old/fs/jffs2/jffs2_fs_sb.h new/fs/jffs2/jffs2_fs_sb.h +--- old/fs/jffs2/jffs2_fs_sb.h 2022-05-09 17:22:53.000000000 +0800 ++++ new/fs/jffs2/jffs2_fs_sb.h 2022-05-09 20:49:43.100000000 +0800 +@@ -17,11 +17,18 @@ + #include + #include + #include +-#include + #include + #include + #include + #include ++#include "vfs_jffs2.h" ++#include "mtd_dev.h" ++ ++#ifdef __cplusplus ++#if __cplusplus ++extern "C" { ++#endif /* __cplusplus */ ++#endif /* __cplusplus */ + + #define JFFS2_SB_FLAG_RO 1 + #define JFFS2_SB_FLAG_SCANNING 2 /* Flash scanning is in progress */ +@@ -47,10 +54,10 @@ struct jffs2_mount_opts { + Nee jffs_control + */ + struct jffs2_sb_info { +- struct mtd_info *mtd; ++ struct MtdDev *mtd; + + uint32_t highest_ino; +- uint32_t check_ino; /* *NEXT* inode to be checked */ ++ uint32_t checked_ino; + + unsigned int flags; + +@@ -58,7 +65,7 @@ struct jffs2_sb_info { + struct completion gc_thread_start; /* GC thread start completion */ + struct completion gc_thread_exit; /* GC thread exit completion port */ + +- struct mutex alloc_sem; /* Used to protect all the following ++ struct pthread_mutex alloc_sem; /* Used to protect all the following + fields, and also to protect against + out-of-order writing of nodes. And GC. */ + uint32_t cleanmarker_size; /* Size of an _inline_ CLEANMARKER +@@ -120,7 +127,7 @@ struct jffs2_sb_info { + /* Sem to allow jffs2_garbage_collect_deletion_dirent to + drop the erase_completion_lock while it's holding a pointer + to an obsoleted node. I don't like this. Alternatives welcomed. */ +- struct mutex erase_free_sem; ++ struct pthread_mutex erase_free_sem; + + uint32_t wbuf_pagesize; /* 0 for NOR and other flashes with no wbuf */ + +@@ -160,4 +167,27 @@ struct jffs2_sb_info { + void *os_priv; + }; + ++struct super_block { ++ struct jffs2_sb_info jffs2_sb; ++ LIST_HEAD s_node_hash[JFFS2_NODE_HASH_BUCKETS]; ++ LosMux s_node_hash_lock; ++ struct jffs2_inode *s_root; ++ void *s_dev; ++ ++ UINT32 s_lock; /* Lock the inode cache */ ++ EVENT_CB_S s_gc_thread_flags; /* Communication with the gcthread */ ++ unsigned int s_gc_thread; ++ unsigned long s_mount_flags; ++}; ++ ++#define JFFS2_SB_INFO(sb) (&(sb)->jffs2_sb) ++#define OFNI_BS_2SFFJ(c) \ ++ ((struct super_block *) ( ((char *)c) - ((char *)(&((struct super_block *)NULL)->jffs2_sb)) ) ) ++ ++#ifdef __cplusplus ++#if __cplusplus ++} ++#endif /* __cplusplus */ ++#endif /* __cplusplus */ ++ + #endif /* _JFFS2_FS_SB */ +diff -Nupr old/fs/jffs2/malloc.c new/fs/jffs2/malloc.c +--- old/fs/jffs2/malloc.c 2022-05-09 17:22:53.000000000 +0800 ++++ new/fs/jffs2/malloc.c 2022-05-10 09:43:16.720000000 +0800 +@@ -9,111 +9,31 @@ + * + */ + +-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +- + #include + #include +-#include +-#include ++#include + #include "nodelist.h" + +-/* These are initialised to NULL in the kernel startup code. +- If you're porting to other operating systems, beware */ +-static struct kmem_cache *full_dnode_slab; +-static struct kmem_cache *raw_dirent_slab; +-static struct kmem_cache *raw_inode_slab; +-static struct kmem_cache *tmp_dnode_info_slab; +-static struct kmem_cache *raw_node_ref_slab; +-static struct kmem_cache *node_frag_slab; +-static struct kmem_cache *inode_cache_slab; +-#ifdef CONFIG_JFFS2_FS_XATTR +-static struct kmem_cache *xattr_datum_cache; +-static struct kmem_cache *xattr_ref_cache; ++#if !defined(JFFS2NUM_FS_JFFS2_RAW_NODE_REF_CACHE_POOL_SIZE) ++# define JFFS2NUM_FS_JFFS2_RAW_NODE_REF_CACHE_POOL_SIZE 0 + #endif + + int __init jffs2_create_slab_caches(void) + { +- full_dnode_slab = kmem_cache_create("jffs2_full_dnode", +- sizeof(struct jffs2_full_dnode), +- 0, 0, NULL); +- if (!full_dnode_slab) +- goto err; +- +- raw_dirent_slab = kmem_cache_create("jffs2_raw_dirent", +- sizeof(struct jffs2_raw_dirent), +- 0, SLAB_HWCACHE_ALIGN, NULL); +- if (!raw_dirent_slab) +- goto err; +- +- raw_inode_slab = kmem_cache_create("jffs2_raw_inode", +- sizeof(struct jffs2_raw_inode), +- 0, SLAB_HWCACHE_ALIGN, NULL); +- if (!raw_inode_slab) +- goto err; +- +- tmp_dnode_info_slab = kmem_cache_create("jffs2_tmp_dnode", +- sizeof(struct jffs2_tmp_dnode_info), +- 0, 0, NULL); +- if (!tmp_dnode_info_slab) +- goto err; +- +- raw_node_ref_slab = kmem_cache_create("jffs2_refblock", +- sizeof(struct jffs2_raw_node_ref) * (REFS_PER_BLOCK + 1), +- 0, 0, NULL); +- if (!raw_node_ref_slab) +- goto err; +- +- node_frag_slab = kmem_cache_create("jffs2_node_frag", +- sizeof(struct jffs2_node_frag), +- 0, 0, NULL); +- if (!node_frag_slab) +- goto err; +- +- inode_cache_slab = kmem_cache_create("jffs2_inode_cache", +- sizeof(struct jffs2_inode_cache), +- 0, 0, NULL); +- if (!inode_cache_slab) +- goto err; +- +-#ifdef CONFIG_JFFS2_FS_XATTR +- xattr_datum_cache = kmem_cache_create("jffs2_xattr_datum", +- sizeof(struct jffs2_xattr_datum), +- 0, 0, NULL); +- if (!xattr_datum_cache) +- goto err; +- +- xattr_ref_cache = kmem_cache_create("jffs2_xattr_ref", +- sizeof(struct jffs2_xattr_ref), +- 0, 0, NULL); +- if (!xattr_ref_cache) +- goto err; +-#endif +- + return 0; +- err: +- jffs2_destroy_slab_caches(); +- return -ENOMEM; ++ + } + + void jffs2_destroy_slab_caches(void) + { +- kmem_cache_destroy(full_dnode_slab); +- kmem_cache_destroy(raw_dirent_slab); +- kmem_cache_destroy(raw_inode_slab); +- kmem_cache_destroy(tmp_dnode_info_slab); +- kmem_cache_destroy(raw_node_ref_slab); +- kmem_cache_destroy(node_frag_slab); +- kmem_cache_destroy(inode_cache_slab); +-#ifdef CONFIG_JFFS2_FS_XATTR +- kmem_cache_destroy(xattr_datum_cache); +- kmem_cache_destroy(xattr_ref_cache); +-#endif ++ return; + } + ++ + struct jffs2_full_dirent *jffs2_alloc_full_dirent(int namesize) + { + struct jffs2_full_dirent *ret; +- ret = kmalloc(sizeof(struct jffs2_full_dirent) + namesize, GFP_KERNEL); ++ ret = zalloc(sizeof(struct jffs2_full_dirent) + namesize); + dbg_memalloc("%p\n", ret); + return ret; + } +@@ -127,7 +47,7 @@ void jffs2_free_full_dirent(struct jffs2 + struct jffs2_full_dnode *jffs2_alloc_full_dnode(void) + { + struct jffs2_full_dnode *ret; +- ret = kmem_cache_alloc(full_dnode_slab, GFP_KERNEL); ++ ret = zalloc(sizeof(struct jffs2_full_dnode)); + dbg_memalloc("%p\n", ret); + return ret; + } +@@ -135,13 +55,13 @@ struct jffs2_full_dnode *jffs2_alloc_ful + void jffs2_free_full_dnode(struct jffs2_full_dnode *x) + { + dbg_memalloc("%p\n", x); +- kmem_cache_free(full_dnode_slab, x); ++ free(x); + } + + struct jffs2_raw_dirent *jffs2_alloc_raw_dirent(void) + { + struct jffs2_raw_dirent *ret; +- ret = kmem_cache_alloc(raw_dirent_slab, GFP_KERNEL); ++ ret = zalloc(sizeof(struct jffs2_raw_dirent)); + dbg_memalloc("%p\n", ret); + return ret; + } +@@ -149,13 +69,13 @@ struct jffs2_raw_dirent *jffs2_alloc_raw + void jffs2_free_raw_dirent(struct jffs2_raw_dirent *x) + { + dbg_memalloc("%p\n", x); +- kmem_cache_free(raw_dirent_slab, x); ++ free(x); + } + + struct jffs2_raw_inode *jffs2_alloc_raw_inode(void) + { + struct jffs2_raw_inode *ret; +- ret = kmem_cache_alloc(raw_inode_slab, GFP_KERNEL); ++ ret = zalloc(sizeof(struct jffs2_raw_inode)); + dbg_memalloc("%p\n", ret); + return ret; + } +@@ -163,13 +83,13 @@ struct jffs2_raw_inode *jffs2_alloc_raw_ + void jffs2_free_raw_inode(struct jffs2_raw_inode *x) + { + dbg_memalloc("%p\n", x); +- kmem_cache_free(raw_inode_slab, x); ++ free(x); + } + + struct jffs2_tmp_dnode_info *jffs2_alloc_tmp_dnode_info(void) + { + struct jffs2_tmp_dnode_info *ret; +- ret = kmem_cache_alloc(tmp_dnode_info_slab, GFP_KERNEL); ++ ret = zalloc(sizeof(struct jffs2_tmp_dnode_info)); + dbg_memalloc("%p\n", + ret); + return ret; +@@ -178,14 +98,14 @@ struct jffs2_tmp_dnode_info *jffs2_alloc + void jffs2_free_tmp_dnode_info(struct jffs2_tmp_dnode_info *x) + { + dbg_memalloc("%p\n", x); +- kmem_cache_free(tmp_dnode_info_slab, x); ++ free(x); + } + + static struct jffs2_raw_node_ref *jffs2_alloc_refblock(void) + { + struct jffs2_raw_node_ref *ret; + +- ret = kmem_cache_alloc(raw_node_ref_slab, GFP_KERNEL); ++ ret = malloc(sizeof(struct jffs2_raw_node_ref) * (REFS_PER_BLOCK+1)); + if (ret) { + int i = 0; + for (i=0; i < REFS_PER_BLOCK; i++) { +@@ -242,13 +162,13 @@ int jffs2_prealloc_raw_node_refs(struct + void jffs2_free_refblock(struct jffs2_raw_node_ref *x) + { + dbg_memalloc("%p\n", x); +- kmem_cache_free(raw_node_ref_slab, x); ++ free(x); + } + + struct jffs2_node_frag *jffs2_alloc_node_frag(void) + { + struct jffs2_node_frag *ret; +- ret = kmem_cache_alloc(node_frag_slab, GFP_KERNEL); ++ ret = malloc(sizeof(struct jffs2_node_frag)); + dbg_memalloc("%p\n", ret); + return ret; + } +@@ -256,13 +176,14 @@ struct jffs2_node_frag *jffs2_alloc_node + void jffs2_free_node_frag(struct jffs2_node_frag *x) + { + dbg_memalloc("%p\n", x); +- kmem_cache_free(node_frag_slab, x); ++ free(x); + } + ++ + struct jffs2_inode_cache *jffs2_alloc_inode_cache(void) + { + struct jffs2_inode_cache *ret; +- ret = kmem_cache_alloc(inode_cache_slab, GFP_KERNEL); ++ ret = zalloc(sizeof(struct jffs2_inode_cache));; + dbg_memalloc("%p\n", ret); + return ret; + } +@@ -270,14 +191,14 @@ struct jffs2_inode_cache *jffs2_alloc_in + void jffs2_free_inode_cache(struct jffs2_inode_cache *x) + { + dbg_memalloc("%p\n", x); +- kmem_cache_free(inode_cache_slab, x); ++ kfree(x); + } + + #ifdef CONFIG_JFFS2_FS_XATTR + struct jffs2_xattr_datum *jffs2_alloc_xattr_datum(void) + { + struct jffs2_xattr_datum *xd; +- xd = kmem_cache_zalloc(xattr_datum_cache, GFP_KERNEL); ++ xd = malloc(sizeof(struct jffs2_xattr_datum)); + dbg_memalloc("%p\n", xd); + if (!xd) + return NULL; +@@ -291,13 +212,13 @@ struct jffs2_xattr_datum *jffs2_alloc_xa + void jffs2_free_xattr_datum(struct jffs2_xattr_datum *xd) + { + dbg_memalloc("%p\n", xd); +- kmem_cache_free(xattr_datum_cache, xd); ++ kfree(xd); + } + + struct jffs2_xattr_ref *jffs2_alloc_xattr_ref(void) + { + struct jffs2_xattr_ref *ref; +- ref = kmem_cache_zalloc(xattr_ref_cache, GFP_KERNEL); ++ ref = malloc(sizeof(struct jffs2_xattr_ref)); + dbg_memalloc("%p\n", ref); + if (!ref) + return NULL; +@@ -310,6 +231,6 @@ struct jffs2_xattr_ref *jffs2_alloc_xatt + void jffs2_free_xattr_ref(struct jffs2_xattr_ref *ref) + { + dbg_memalloc("%p\n", ref); +- kmem_cache_free(xattr_ref_cache, ref); ++ kfree(ref); + } + #endif +diff -Nupr old/fs/jffs2/nodelist.c new/fs/jffs2/nodelist.c +--- old/fs/jffs2/nodelist.c 2022-05-09 17:22:53.000000000 +0800 ++++ new/fs/jffs2/nodelist.c 2022-05-09 20:37:35.680000000 +0800 +@@ -9,16 +9,15 @@ + * + */ + +-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +- + #include + #include + #include +-#include + #include +-#include + #include ++#include + #include "nodelist.h" ++#include "jffs2.h" ++#include "los_crc32.h" + + static void jffs2_obsolete_node_frag(struct jffs2_sb_info *c, + struct jffs2_node_frag *this); +@@ -30,7 +29,7 @@ void jffs2_add_fd_to_list(struct jffs2_s + dbg_dentlist("add dirent \"%s\", ino #%u\n", new->name, new->ino); + + while ((*prev) && (*prev)->nhash <= new->nhash) { +- if ((*prev)->nhash == new->nhash && !strcmp((*prev)->name, new->name)) { ++ if ((*prev)->nhash == new->nhash && !strcmp((const char *)((*prev)->name), (const char *)new->name)) { + /* Duplicate. Free one */ + if (new->version < (*prev)->version) { + dbg_dentlist("Eep! Marking new dirent node obsolete, old is \"%s\", ino #%u\n", +@@ -41,7 +40,7 @@ void jffs2_add_fd_to_list(struct jffs2_s + dbg_dentlist("marking old dirent \"%s\", ino #%u obsolete\n", + (*prev)->name, (*prev)->ino); + new->next = (*prev)->next; +- /* It may have been a 'placeholder' deletion dirent, ++ /* It may have been a 'placeholder' deletion dirent, + if jffs2_can_mark_obsolete() (see jffs2_do_unlink()) */ + if ((*prev)->raw) + jffs2_mark_node_obsolete(c, ((*prev)->raw)); +@@ -65,13 +64,14 @@ uint32_t jffs2_truncate_fragtree(struct + /* We know frag->ofs <= size. That's what lookup does for us */ + if (frag && frag->ofs != size) { + if (frag->ofs+frag->size > size) { ++ dbg_fragtree("truncating frag 0x%08x-0x%08x\n", frag->ofs, frag->ofs+frag->size); + frag->size = size - frag->ofs; + } + frag = frag_next(frag); + } + while (frag && frag->ofs >= size) { + struct jffs2_node_frag *next = frag_next(frag); +- ++ dbg_fragtree("removing frag 0x%08x-0x%08x\n", frag->ofs, frag->ofs+frag->size); + frag_erase(frag, list); + jffs2_obsolete_node_frag(c, frag); + frag = next; +@@ -90,7 +90,7 @@ uint32_t jffs2_truncate_fragtree(struct + + /* If the last fragment starts at the RAM page boundary, it is + * REF_PRISTINE irrespective of its size. */ +- if (frag->node && (frag->ofs & (PAGE_SIZE - 1)) == 0) { ++ if (frag->node && (frag->ofs & (PAGE_CACHE_SIZE - 1)) == 0) { + dbg_fragtree2("marking the last fragment 0x%08x-0x%08x REF_PRISTINE.\n", + frag->ofs, frag->ofs + frag->size); + frag->node->raw->flash_offset = ref_offset(frag->node->raw) | REF_PRISTINE; +@@ -237,7 +237,7 @@ static int jffs2_add_frag_to_fragtree(st + If so, both 'this' and the new node get marked REF_NORMAL so + the GC can take a look. + */ +- if (lastend && (lastend-1) >> PAGE_SHIFT == newfrag->ofs >> PAGE_SHIFT) { ++ if (lastend && (lastend-1) >> PAGE_CACHE_SHIFT == newfrag->ofs >> PAGE_CACHE_SHIFT) { + if (this->node) + mark_ref_normal(this->node->raw); + mark_ref_normal(newfrag->node->raw); +@@ -382,7 +382,7 @@ int jffs2_add_full_dnode_to_inode(struct + + /* If we now share a page with other nodes, mark either previous + or next node REF_NORMAL, as appropriate. */ +- if (newfrag->ofs & (PAGE_SIZE-1)) { ++ if (newfrag->ofs & (PAGE_CACHE_SIZE-1)) { + struct jffs2_node_frag *prev = frag_prev(newfrag); + + mark_ref_normal(fn->raw); +@@ -391,7 +391,7 @@ int jffs2_add_full_dnode_to_inode(struct + mark_ref_normal(prev->node->raw); + } + +- if ((newfrag->ofs+newfrag->size) & (PAGE_SIZE-1)) { ++ if ((newfrag->ofs+newfrag->size) & (PAGE_CACHE_SIZE-1)) { + struct jffs2_node_frag *next = frag_next(newfrag); + + if (next) { +@@ -401,7 +401,7 @@ int jffs2_add_full_dnode_to_inode(struct + } + } + jffs2_dbg_fragtree_paranoia_check_nolock(f); +- ++ jffs2_dbg_dump_fragtree_nolock(f); + return 0; + } + +@@ -409,7 +409,6 @@ void jffs2_set_inocache_state(struct jff + { + spin_lock(&c->inocache_lock); + ic->state = state; +- wake_up(&c->inocache_wq); + spin_unlock(&c->inocache_lock); + } + +@@ -505,8 +504,12 @@ void jffs2_free_raw_node_refs(struct jff + { + int i; + struct jffs2_raw_node_ref *this, *next; ++ struct super_block *sb = NULL; ++ struct MtdNorDev *device = NULL; ++ sb = OFNI_BS_2SFFJ(c); ++ device = (struct MtdNorDev*)(sb->s_dev); + +- for (i=0; inr_blocks; i++) { ++ for (i=device->blockStart; inr_blocks+device->blockStart; i++) { + this = c->blocks[i].first_node; + while (this) { + if (this[REFS_PER_BLOCK].flash_offset == REF_LINK_NODE) +@@ -536,14 +539,22 @@ struct jffs2_node_frag *jffs2_lookup_nod + while(next) { + frag = rb_entry(next, struct jffs2_node_frag, rb); + ++ dbg_fragtree2("considering frag %#04x-%#04x (%p). left %p, right %p\n", ++ frag->ofs, frag->ofs+frag->size, frag, frag->rb.rb_left, frag->rb.rb_right); + if (frag->ofs + frag->size <= offset) { ++ dbg_fragtree2("going right from frag %#04x-%#04x, before the region we care about\n", ++ frag->ofs, frag->ofs+frag->size); + /* Remember the closest smaller match on the way down */ + if (!prev || frag->ofs > prev->ofs) + prev = frag; + next = frag->rb.rb_right; + } else if (frag->ofs > offset) { ++ dbg_fragtree2("going left from frag %#04x-%#04x, after the region we care about\n", ++ frag->ofs, frag->ofs+frag->size); + next = frag->rb.rb_left; + } else { ++ dbg_fragtree2("returning frag %#04x-%#04x, matched\n", ++ frag->ofs, frag->ofs+frag->size); + return frag; + } + } +@@ -564,10 +575,12 @@ struct jffs2_node_frag *jffs2_lookup_nod + they're killed. */ + void jffs2_kill_fragtree(struct rb_root *root, struct jffs2_sb_info *c) + { +- struct jffs2_node_frag *frag, *next; ++ struct jffs2_node_frag *frag; ++ struct rb_node *tn,*next; + + dbg_fragtree("killing\n"); +- rbtree_postorder_for_each_entry_safe(frag, next, root, rb) { ++ RB_POSTORDER_FOREACH_SAFE(tn, linux_root, (struct linux_root *)root, next) { ++ frag = (struct jffs2_node_frag *)tn; + if (frag->node && !(--frag->node->frags)) { + /* Not a hole, and it's the final remaining frag + of this node. Free the node */ +@@ -604,7 +617,7 @@ struct jffs2_raw_node_ref *jffs2_link_no + ref++; + } + +- dbg_noderef("New ref is %p (%08x becomes %08x,%p) len 0x%x\n", ref, ++ dbg_noderef("New ref is %p (%08x becomes %08x,%p) len 0x%x\n", ref, + ref->flash_offset, ofs, ref->next_in_ino, len); + + ref->flash_offset = ofs; +@@ -617,7 +630,7 @@ struct jffs2_raw_node_ref *jffs2_link_no + + JFFS2_ERROR("Adding new ref %p at (0x%08x-0x%08x) not immediately after previous (0x%08x-0x%08x)\n", + ref, ref_offset(ref), ref_offset(ref)+len, +- ref_offset(jeb->last_node), ++ ref_offset(jeb->last_node), + ref_offset(jeb->last_node)+last_len); + BUG(); + } +@@ -734,7 +747,7 @@ uint32_t __jffs2_ref_totlen(struct jffs2 + pr_crit("next %p (0x%08x-0x%08x)\n", + ref_next(ref), ref_offset(ref_next(ref)), + ref_offset(ref_next(ref)) + ref->__totlen); +- } else ++ } else + pr_crit("No next ref. jeb->last_node is %p\n", + jeb->last_node); + +diff -Nupr old/fs/jffs2/nodelist.h new/fs/jffs2/nodelist.h +--- old/fs/jffs2/nodelist.h 2022-05-09 17:22:53.000000000 +0800 ++++ new/fs/jffs2/nodelist.h 2022-05-09 20:36:25.460000000 +0800 +@@ -12,20 +12,28 @@ + #ifndef __JFFS2_NODELIST_H__ + #define __JFFS2_NODELIST_H__ + +-#include ++#include + #include +-#include ++#include ++#include "jffs2.h" + #include "jffs2_fs_sb.h" + #include "jffs2_fs_i.h" + #include "xattr.h" + #include "acl.h" + #include "summary.h" +- +-#ifdef __ECOS +-#include "os-ecos.h" +-#else ++#include "vfs_jffs2.h" + #include "os-linux.h" +-#endif ++ ++#ifdef __cplusplus ++#if __cplusplus ++extern "C" { ++#endif /* __cplusplus */ ++#endif /* __cplusplus */ ++ ++struct kvec { ++ void *iov_base; ++ long iov_len; ++}; + + #define JFFS2_NATIVE_ENDIAN + +@@ -193,6 +201,8 @@ struct jffs2_inode_cache { + #define INO_STATE_READING 5 /* In read_inode() */ + #define INO_STATE_CLEARING 6 /* In clear_inode() */ + ++#define INOCACHE_HASHSIZE 128 ++ + #define INO_FLAGS_XATTR_CHECKED 0x01 /* has no duplicate xattr_ref */ + #define INO_FLAGS_IS_DIR 0x02 /* is a directory */ + +@@ -250,10 +260,7 @@ struct jffs2_readinode_info + + struct jffs2_full_dirent + { +- union { +- struct jffs2_raw_node_ref *raw; +- struct jffs2_inode_cache *ic; /* Just during part of build */ +- }; ++ struct jffs2_raw_node_ref *raw; + struct jffs2_full_dirent *next; + uint32_t version; + uint32_t ino; /* == zero for unlink */ +@@ -313,34 +320,26 @@ static inline int jffs2_blocks_use_vmall + + #define PAD(x) (((x)+3)&~3) + +-static inline int jffs2_encode_dev(union jffs2_device_node *jdev, dev_t rdev) +-{ +- if (old_valid_dev(rdev)) { +- jdev->old_id = cpu_to_je16(old_encode_dev(rdev)); +- return sizeof(jdev->old_id); +- } else { +- jdev->new_id = cpu_to_je32(new_encode_dev(rdev)); +- return sizeof(jdev->new_id); +- } +-} + + static inline struct jffs2_node_frag *frag_first(struct rb_root *root) + { +- struct rb_node *node = rb_first(root); ++ struct rb_node *node = root->rb_node; + + if (!node) + return NULL; +- ++ while(node->rb_left) ++ node = node->rb_left; + return rb_entry(node, struct jffs2_node_frag, rb); + } + + static inline struct jffs2_node_frag *frag_last(struct rb_root *root) + { +- struct rb_node *node = rb_last(root); ++ struct rb_node *node = root->rb_node; + + if (!node) + return NULL; +- ++ while(node->rb_right) ++ node = node->rb_right; + return rb_entry(node, struct jffs2_node_frag, rb); + } + +@@ -404,8 +403,9 @@ struct jffs2_full_dirent *jffs2_write_di + int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f, + struct jffs2_raw_inode *ri, unsigned char *buf, + uint32_t offset, uint32_t writelen, uint32_t *retlen); +-int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, struct jffs2_inode_info *f, +- struct jffs2_raw_inode *ri, const struct qstr *qstr); ++int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, ++ struct jffs2_inode_info *f, struct jffs2_raw_inode *ri, ++ const char *name, int namelen); + int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, const char *name, + int namelen, struct jffs2_inode_info *dead_f, uint32_t time); + int jffs2_do_link(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint32_t ino, +@@ -481,4 +481,10 @@ int jffs2_write_nand_cleanmarker(struct + + #include "debug.h" + ++#ifdef __cplusplus ++#if __cplusplus ++} ++#endif /* __cplusplus */ ++#endif /* __cplusplus */ ++ + #endif /* __JFFS2_NODELIST_H__ */ +diff -Nupr old/fs/jffs2/nodemgmt.c new/fs/jffs2/nodemgmt.c +--- old/fs/jffs2/nodemgmt.c 2022-05-09 17:22:53.000000000 +0800 ++++ new/fs/jffs2/nodemgmt.c 2022-05-09 20:35:50.910000000 +0800 +@@ -9,46 +9,14 @@ + * + */ + +-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +- + #include +-#include + #include +-#include ++#include /* For cond_resched() */ ++#include ++#include + #include "nodelist.h" + #include "debug.h" + +-/* +- * Check whether the user is allowed to write. +- */ +-static int jffs2_rp_can_write(struct jffs2_sb_info *c) +-{ +- uint32_t avail; +- struct jffs2_mount_opts *opts = &c->mount_opts; +- +- avail = c->dirty_size + c->free_size + c->unchecked_size + +- c->erasing_size - c->resv_blocks_write * c->sector_size +- - c->nospc_dirty_size; +- +- if (avail < 2 * opts->rp_size) +- jffs2_dbg(1, "rpsize %u, dirty_size %u, free_size %u, " +- "erasing_size %u, unchecked_size %u, " +- "nr_erasing_blocks %u, avail %u, resrv %u\n", +- opts->rp_size, c->dirty_size, c->free_size, +- c->erasing_size, c->unchecked_size, +- c->nr_erasing_blocks, avail, c->nospc_dirty_size); +- +- if (avail > opts->rp_size) +- return 1; +- +- /* Always allow root */ +- if (capable(CAP_SYS_RESOURCE)) +- return 1; +- +- jffs2_dbg(1, "forbid writing\n"); +- return 0; +-} +- + /** + * jffs2_reserve_space - request physical space to write nodes to flash + * @c: superblock info +@@ -57,8 +25,8 @@ static int jffs2_rp_can_write(struct jff + * @prio: Allocation type - ALLOC_{NORMAL,DELETION} + * + * Requests a block of physical space on the flash. Returns zero for success +- * and puts 'len' into the appropriate place, or returns -ENOSPC or other +- * error if appropriate. Doesn't return len since that's ++ * and puts 'len' into the appropriate place, or returns -ENOSPC or other ++ * error if appropriate. Doesn't return len since that's + * + * If it returns zero, jffs2_reserve_space() also downs the per-filesystem + * allocation semaphore, to prevent more than one allocation from being +@@ -86,15 +54,6 @@ int jffs2_reserve_space(struct jffs2_sb_ + + spin_lock(&c->erase_completion_lock); + +- /* +- * Check if the free space is greater then size of the reserved pool. +- * If not, only allow root to proceed with writing. +- */ +- if (prio != ALLOC_DELETION && !jffs2_rp_can_write(c)) { +- ret = -ENOSPC; +- goto out; +- } +- + /* this needs a little more thought (true :)) */ + while(ret == -EAGAIN) { + while(c->nr_free_blocks + c->nr_erasing_blocks < blocksneeded) { +@@ -165,24 +124,7 @@ int jffs2_reserve_space(struct jffs2_sb_ + spin_unlock(&c->erase_completion_lock); + + ret = jffs2_garbage_collect_pass(c); +- +- if (ret == -EAGAIN) { +- spin_lock(&c->erase_completion_lock); +- if (c->nr_erasing_blocks && +- list_empty(&c->erase_pending_list) && +- list_empty(&c->erase_complete_list)) { +- DECLARE_WAITQUEUE(wait, current); +- set_current_state(TASK_UNINTERRUPTIBLE); +- add_wait_queue(&c->erase_wait, &wait); +- jffs2_dbg(1, "%s waiting for erase to complete\n", +- __func__); +- spin_unlock(&c->erase_completion_lock); +- +- schedule(); +- remove_wait_queue(&c->erase_wait, &wait); +- } else +- spin_unlock(&c->erase_completion_lock); +- } else if (ret) ++ if (ret) + return ret; + + cond_resched(); +@@ -200,7 +142,6 @@ int jffs2_reserve_space(struct jffs2_sb_ + } + } + +-out: + spin_unlock(&c->erase_completion_lock); + if (!ret) + ret = jffs2_prealloc_raw_node_refs(c, c->nextblock, 1); +@@ -509,7 +450,7 @@ struct jffs2_raw_node_ref *jffs2_add_phy + jffs2_dbg(1, "%s(): Node at 0x%x(%d), size 0x%x\n", + __func__, ofs & ~3, ofs & 3, len); + #if 1 +- /* Allow non-obsolete nodes only to be added at the end of c->nextblock, ++ /* Allow non-obsolete nodes only to be added at the end of c->nextblock, + if c->nextblock is set. Note that wbuf.c will file obsolete nodes + even after refiling c->nextblock */ + if ((c->nextblock || ((ofs & 3) != REF_OBSOLETE)) +@@ -584,6 +525,8 @@ void jffs2_mark_node_obsolete(struct jff + int ret, addedsize; + size_t retlen; + uint32_t freed_len; ++ struct super_block *sb; ++ struct MtdNorDev *device; + + if(unlikely(!ref)) { + pr_notice("EEEEEK. jffs2_mark_node_obsolete called with NULL node\n"); +@@ -595,9 +538,10 @@ void jffs2_mark_node_obsolete(struct jff + return; + } + blocknr = ref->flash_offset / c->sector_size; +- if (blocknr >= c->nr_blocks) { +- pr_notice("raw node at 0x%08x is off the end of device!\n", +- ref->flash_offset); ++ sb = OFNI_BS_2SFFJ(c); ++ device = (struct MtdNorDev*)(sb->s_dev); ++ if (blocknr >= c->nr_blocks +device->blockStart) { ++ pr_notice("raw node at 0x%08x is off the end of device!\n",ref->flash_offset); + BUG(); + } + jeb = &c->blocks[blocknr]; +@@ -778,7 +722,7 @@ void jffs2_mark_node_obsolete(struct jff + } + /* XXX FIXME: This is ugly now */ + n.nodetype = cpu_to_je16(je16_to_cpu(n.nodetype) & ~JFFS2_NODE_ACCURATE); +- ret = jffs2_flash_write(c, ref_offset(ref), sizeof(n), &retlen, (char *)&n); ++ ret = jffs2_flash_write(c, ref_offset(ref), sizeof(n), &retlen, (const u_char *)&n); + if (ret) { + pr_warn("Write error in obliterating obsoleted node at 0x%08x: %d\n", + ref_offset(ref), ret); +@@ -846,8 +790,8 @@ int jffs2_thread_should_wake(struct jffs + return 1; + + if (c->unchecked_size) { +- jffs2_dbg(1, "jffs2_thread_should_wake(): unchecked_size %d, check_ino #%d\n", +- c->unchecked_size, c->check_ino); ++ jffs2_dbg(1, "jffs2_thread_should_wake(): unchecked_size %d, checked_ino #%d\n", ++ c->unchecked_size, c->checked_ino); + return 1; + } + +diff -Nupr old/fs/jffs2/os-linux.h new/fs/jffs2/os-linux.h +--- old/fs/jffs2/os-linux.h 2022-05-09 17:22:53.000000000 +0800 ++++ new/fs/jffs2/os-linux.h 2022-05-09 20:33:21.200000000 +0800 +@@ -12,59 +12,57 @@ + #ifndef __JFFS2_OS_LINUX_H__ + #define __JFFS2_OS_LINUX_H__ + ++#include ++#include "fs/fs.h" ++#include "jffs2.h" ++#include "jffs2_fs_sb.h" ++ ++ ++/* jffs2 debug output opion */ ++#define CONFIG_JFFS2_FS_DEBUG 0 /* 1 or 2 */ ++ ++/* jffs2 gc thread section */ ++#define JFFS2_GC_THREAD_PRIORITY 10 /* GC thread's priority */ ++ ++/* zlib section*/ ++#define CONFIG_JFFS2_ZLIB ++#define CONFIG_JFFS2_RTIME ++#define CONFIG_JFFS2_RUBIN ++ + /* JFFS2 uses Linux mode bits natively -- no need for conversion */ + #define os_to_jffs2_mode(x) (x) + #define jffs2_to_os_mode(x) (x) + ++#ifndef BUG_ON ++#define BUG_ON(x) do {if (unlikely(x)) BUG();} while (0) ++#endif ++ + struct kstatfs; + struct kvec; + +-#define JFFS2_INODE_INFO(i) (container_of(i, struct jffs2_inode_info, vfs_inode)) +-#define OFNI_EDONI_2SFFJ(f) (&(f)->vfs_inode) +-#define JFFS2_SB_INFO(sb) (sb->s_fs_info) +-#define OFNI_BS_2SFFJ(c) ((struct super_block *)c->os_priv) + ++#define JFFS2_INODE_INFO(i) (&(i)->jffs2_i) ++#define OFNI_EDONI_2SFFJ(f) \ ++ ((struct jffs2_inode *) (((char *)f) - ((char *)(&((struct jffs2_inode *)NULL)->jffs2_i)))) + + #define JFFS2_F_I_SIZE(f) (OFNI_EDONI_2SFFJ(f)->i_size) + #define JFFS2_F_I_MODE(f) (OFNI_EDONI_2SFFJ(f)->i_mode) +-#define JFFS2_F_I_UID(f) (i_uid_read(OFNI_EDONI_2SFFJ(f))) +-#define JFFS2_F_I_GID(f) (i_gid_read(OFNI_EDONI_2SFFJ(f))) +-#define JFFS2_F_I_RDEV(f) (OFNI_EDONI_2SFFJ(f)->i_rdev) +- +-#define JFFS2_CLAMP_TIME(t) ((uint32_t)clamp_t(time64_t, (t), 0, U32_MAX)) +-#define ITIME(sec) ((struct timespec64){sec, 0}) +-#define JFFS2_NOW() JFFS2_CLAMP_TIME(ktime_get_real_seconds()) +-#define I_SEC(tv) JFFS2_CLAMP_TIME((tv).tv_sec) +-#define JFFS2_F_I_CTIME(f) I_SEC(OFNI_EDONI_2SFFJ(f)->i_ctime) +-#define JFFS2_F_I_MTIME(f) I_SEC(OFNI_EDONI_2SFFJ(f)->i_mtime) +-#define JFFS2_F_I_ATIME(f) I_SEC(OFNI_EDONI_2SFFJ(f)->i_atime) +-#define sleep_on_spinunlock(wq, s) \ +- do { \ +- DECLARE_WAITQUEUE(__wait, current); \ +- add_wait_queue((wq), &__wait); \ +- set_current_state(TASK_UNINTERRUPTIBLE); \ +- spin_unlock(s); \ +- schedule(); \ +- remove_wait_queue((wq), &__wait); \ +- } while(0) +- +-static inline void jffs2_init_inode_info(struct jffs2_inode_info *f) +-{ +- f->highest_version = 0; +- f->fragtree = RB_ROOT; +- f->metadata = NULL; +- f->dents = NULL; +- f->target = NULL; +- f->flags = 0; +- f->usercompr = 0; +-} ++#define JFFS2_F_I_UID(f) (OFNI_EDONI_2SFFJ(f)->i_uid) ++#define JFFS2_F_I_GID(f) (OFNI_EDONI_2SFFJ(f)->i_gid) ++#define JFFS2_F_I_CTIME(f) (OFNI_EDONI_2SFFJ(f)->i_ctime) ++#define JFFS2_F_I_MTIME(f) (OFNI_EDONI_2SFFJ(f)->i_mtime) ++#define JFFS2_F_I_ATIME(f) (OFNI_EDONI_2SFFJ(f)->i_atime) ++ ++#define ITIME(sec) ((struct timespec){sec, 0}) ++#define I_SEC(tv) ((tv).tv_sec) + ++#define sleep_on_spinunlock(wq, sl) do {spin_unlock(sl); msleep(100);} while (0) + +-#define jffs2_is_readonly(c) (OFNI_BS_2SFFJ(c)->s_flags & SB_RDONLY) ++#define jffs2_is_readonly(c) (0) + + #define SECTOR_ADDR(x) ( (((unsigned long)(x) / c->sector_size) * c->sector_size) ) +-#ifndef CONFIG_JFFS2_FS_WRITEBUFFER + ++#ifndef CONFIG_JFFS2_FS_WRITEBUFFER + + #ifdef CONFIG_JFFS2_SUMMARY + #define jffs2_can_mark_obsolete(c) (0) +@@ -77,10 +75,10 @@ static inline void jffs2_init_inode_info + #define jffs2_write_nand_cleanmarker(c,jeb) (-EIO) + + #define jffs2_flash_write(c, ofs, len, retlen, buf) jffs2_flash_direct_write(c, ofs, len, retlen, buf) +-#define jffs2_flash_read(c, ofs, len, retlen, buf) (mtd_read((c)->mtd, ofs, len, retlen, buf)) +-#define jffs2_flush_wbuf_pad(c) ({ do{} while(0); (void)(c), 0; }) ++#define jffs2_flash_read(c, ofs, len, retlen, buf) jffs2_flash_direct_read(c, ofs, len, retlen, buf) ++#define jffs2_flush_wbuf_pad(c) (c=c) + #define jffs2_flush_wbuf_gc(c, i) ({ do{} while(0); (void)(c), (void) i, 0; }) +-#define jffs2_write_nand_badblock(c,jeb,bad_offset) (1) ++#define jffs2_write_nand_badblock(c,jeb,p) (0) + #define jffs2_nand_flash_setup(c) (0) + #define jffs2_nand_flash_cleanup(c) do {} while(0) + #define jffs2_wbuf_dirty(c) (0) +@@ -100,7 +98,8 @@ static inline void jffs2_init_inode_info + + #else /* NAND and/or ECC'd NOR support present */ + +-#define jffs2_is_writebuffered(c) (c->wbuf != NULL) ++/* current not support */ ++#define jffs2_is_writebuffered(c) (0) + + #ifdef CONFIG_JFFS2_SUMMARY + #define jffs2_can_mark_obsolete(c) (0) +@@ -142,38 +141,28 @@ void jffs2_dirty_trigger(struct jffs2_sb + #endif /* WRITEBUFFER */ + + /* background.c */ +-int jffs2_start_garbage_collect_thread(struct jffs2_sb_info *c); ++void jffs2_start_garbage_collect_thread(struct jffs2_sb_info *c); + void jffs2_stop_garbage_collect_thread(struct jffs2_sb_info *c); + void jffs2_garbage_collect_trigger(struct jffs2_sb_info *c); + + /* dir.c */ +-extern const struct file_operations jffs2_dir_operations; +-extern const struct inode_operations jffs2_dir_inode_operations; +- +-/* file.c */ +-extern const struct file_operations jffs2_file_operations; +-extern const struct inode_operations jffs2_file_inode_operations; +-extern const struct address_space_operations jffs2_file_address_operations; +-int jffs2_fsync(struct file *, loff_t, loff_t, int); +-int jffs2_do_readpage_unlock(void *data, struct page *pg); +- +-/* ioctl.c */ +-long jffs2_ioctl(struct file *, unsigned int, unsigned long); +- +-/* symlink.c */ +-extern const struct inode_operations jffs2_symlink_inode_operations; ++struct jffs2_inode *jffs2_lookup(struct jffs2_inode *dir_i, const unsigned char *name, int namelen); ++int jffs2_create(struct jffs2_inode *dir_i, const unsigned char *d_name, int mode, struct jffs2_inode **new_i); ++int jffs2_mkdir (struct jffs2_inode *dir_i, const unsigned char *d_name, int mode, struct jffs2_inode **new_i); ++int jffs2_link (struct jffs2_inode *old_d_inode, struct jffs2_inode *dir_i, const unsigned char *d_name); ++int jffs2_symlink(struct jffs2_inode *dir_i, struct jffs2_inode **d_inode, const unsigned char *d_name, const char *target); ++int jffs2_unlink(struct jffs2_inode *dir_i, struct jffs2_inode *d_inode, const unsigned char *d_name); ++int jffs2_rmdir (struct jffs2_inode *dir_i, struct jffs2_inode *d_inode, const unsigned char *d_name); ++int jffs2_rename (struct jffs2_inode *old_dir_i, struct jffs2_inode *d_inode, const unsigned char *old_d_name, ++ struct jffs2_inode *new_dir_i, const unsigned char *new_d_name); ++int jffs2_readdir(struct jffs2_inode *inode, off_t *offset, off_t *int_off, struct dirent *ent); + + /* fs.c */ +-int jffs2_setattr (struct dentry *, struct iattr *); +-int jffs2_do_setattr (struct inode *, struct iattr *); +-struct inode *jffs2_iget(struct super_block *, unsigned long); +-void jffs2_evict_inode (struct inode *); +-void jffs2_dirty_inode(struct inode *inode, int flags); +-struct inode *jffs2_new_inode (struct inode *dir_i, umode_t mode, +- struct jffs2_raw_inode *ri); +-int jffs2_statfs (struct dentry *, struct kstatfs *); +-int jffs2_do_remount_fs(struct super_block *sb, struct fs_context *fc); +-int jffs2_do_fill_super(struct super_block *sb, struct fs_context *fc); ++int jffs2_setattr (struct jffs2_inode *inode, struct IATTR *attr); ++struct jffs2_inode *jffs2_iget(struct super_block *sb, uint32_t ino); ++int jffs2_iput(struct jffs2_inode * i); ++struct jffs2_inode *jffs2_new_inode (struct jffs2_inode *dir_i, int mode, struct jffs2_raw_inode *ri); ++ + void jffs2_gc_release_inode(struct jffs2_sb_info *c, + struct jffs2_inode_info *f); + struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c, +@@ -183,15 +172,25 @@ unsigned char *jffs2_gc_fetch_page(struc + struct jffs2_inode_info *f, + unsigned long offset, + unsigned long *priv); ++void jffs2_gc_release_page(struct jffs2_sb_info *c, ++ unsigned char *pg, ++ unsigned long *priv); + void jffs2_flash_cleanup(struct jffs2_sb_info *c); + ++int calculate_inocache_hashsize(uint32_t flash_size); + + /* writev.c */ + int jffs2_flash_direct_writev(struct jffs2_sb_info *c, const struct kvec *vecs, + unsigned long count, loff_t to, size_t *retlen); + int jffs2_flash_direct_write(struct jffs2_sb_info *c, loff_t ofs, size_t len, + size_t *retlen, const u_char *buf); ++int jffs2_flash_direct_read(struct jffs2_sb_info *c, loff_t ofs, size_t len, ++ size_t *retlen, const char *buf); + +-#endif /* __JFFS2_OS_LINUX_H__ */ ++/* super.c */ ++int jffs2_fill_super(struct super_block *sb); ++int jffs2_mount(int part_no, struct jffs2_inode **root_node, unsigned long mountflags); ++int jffs2_umount(struct jffs2_inode *root_node); + ++#endif /* __JFFS2_OS_LINUX_H__ */ + +diff -Nupr old/fs/jffs2/read.c new/fs/jffs2/read.c +--- old/fs/jffs2/read.c 2022-05-09 17:22:53.000000000 +0800 ++++ new/fs/jffs2/read.c 2022-05-09 20:27:15.580000000 +0800 +@@ -9,16 +9,15 @@ + * + */ + +-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +- + #include + #include +-#include + #include +-#include + #include ++#include + #include "nodelist.h" + #include "compr.h" ++#include "los_crc32.h" ++#include "user_copy.h" + + int jffs2_read_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, + struct jffs2_full_dnode *fd, unsigned char *buf, +@@ -57,6 +56,7 @@ int jffs2_read_dnode(struct jffs2_sb_inf + if (crc != je32_to_cpu(ri->node_crc)) { + pr_warn("Node CRC %08x != calculated CRC %08x for node at %08x\n", + je32_to_cpu(ri->node_crc), crc, ref_offset(fd->raw)); ++ jffs2_dbg_dump_node(c, ref_offset(fd->raw)); + ret = -EIO; + goto out_ri; + } +@@ -75,9 +75,8 @@ int jffs2_read_dnode(struct jffs2_sb_inf + goto out_ri; + }); + +- + if (ri->compr == JFFS2_COMPR_ZERO) { +- memset(buf, 0, len); ++ ret = LOS_UserMemClear(buf, len); + goto out_ri; + } + +@@ -88,7 +87,11 @@ int jffs2_read_dnode(struct jffs2_sb_inf + Reading partial node and it's compressed - read into readbuf, check checksum, decompress to decomprbuf and copy + */ + if (ri->compr == JFFS2_COMPR_NONE && len == je32_to_cpu(ri->dsize)) { +- readbuf = buf; ++ readbuf = kmalloc(je32_to_cpu(ri->dsize), GFP_KERNEL); ++ if (!readbuf) { ++ ret = -ENOMEM; ++ goto out_ri; ++ } + } else { + readbuf = kmalloc(je32_to_cpu(ri->csize), GFP_KERNEL); + if (!readbuf) { +@@ -97,14 +100,10 @@ int jffs2_read_dnode(struct jffs2_sb_inf + } + } + if (ri->compr != JFFS2_COMPR_NONE) { +- if (len < je32_to_cpu(ri->dsize)) { +- decomprbuf = kmalloc(je32_to_cpu(ri->dsize), GFP_KERNEL); +- if (!decomprbuf) { +- ret = -ENOMEM; +- goto out_readbuf; +- } +- } else { +- decomprbuf = buf; ++ decomprbuf = kmalloc(je32_to_cpu(ri->dsize), GFP_KERNEL); ++ if (!decomprbuf) { ++ ret = -ENOMEM; ++ goto out_readbuf; + } + } else { + decomprbuf = readbuf; +@@ -113,7 +112,7 @@ int jffs2_read_dnode(struct jffs2_sb_inf + jffs2_dbg(2, "Read %d bytes to %p\n", je32_to_cpu(ri->csize), + readbuf); + ret = jffs2_flash_read(c, (ref_offset(fd->raw)) + sizeof(*ri), +- je32_to_cpu(ri->csize), &readlen, readbuf); ++ je32_to_cpu(ri->csize), &readlen, (char *)readbuf); + + if (!ret && readlen != je32_to_cpu(ri->csize)) + ret = -EIO; +@@ -124,6 +123,7 @@ int jffs2_read_dnode(struct jffs2_sb_inf + if (crc != je32_to_cpu(ri->data_crc)) { + pr_warn("Data CRC %08x != calculated CRC %08x for node at %08x\n", + je32_to_cpu(ri->data_crc), crc, ref_offset(fd->raw)); ++ jffs2_dbg_dump_node(c, ref_offset(fd->raw)); + ret = -EIO; + goto out_decomprbuf; + } +@@ -139,8 +139,8 @@ int jffs2_read_dnode(struct jffs2_sb_inf + } + } + +- if (len < je32_to_cpu(ri->dsize)) { +- memcpy(buf, decomprbuf+ofs, len); ++ if (LOS_CopyFromKernel(buf, len, decomprbuf + ofs, len) != 0) { ++ ret = -EFAULT; + } + out_decomprbuf: + if(decomprbuf != buf && decomprbuf != readbuf) +@@ -184,7 +184,10 @@ int jffs2_read_inode_range(struct jffs2_ + } + jffs2_dbg(1, "Filling non-frag hole from %d-%d\n", + offset, offset + holesize); +- memset(buf, 0, holesize); ++ ret = LOS_UserMemClear(buf, holesize); ++ if (ret != 0) { ++ return ret; ++ } + buf += holesize; + offset += holesize; + continue; +@@ -193,7 +196,10 @@ int jffs2_read_inode_range(struct jffs2_ + jffs2_dbg(1, "Filling frag hole from %d-%d (frag 0x%x 0x%x)\n", + offset, holeend, frag->ofs, + frag->ofs + frag->size); +- memset(buf, 0, holeend - offset); ++ ret = LOS_UserMemClear(buf, holeend - offset); ++ if (ret != 0) { ++ return ret; ++ } + buf += holeend - offset; + offset = holeend; + frag = frag_next(frag); +@@ -214,7 +220,7 @@ int jffs2_read_inode_range(struct jffs2_ + if (ret) { + jffs2_dbg(1, "%s(): error %d\n", + __func__, ret); +- memset(buf, 0, readlen); ++ (void)LOS_UserMemClear(buf, readlen); + return ret; + } + buf += readlen; +@@ -226,3 +232,15 @@ int jffs2_read_inode_range(struct jffs2_ + return 0; + } + ++int jffs2_flash_direct_read(struct jffs2_sb_info *c, loff_t ofs, size_t len, ++ size_t *retlen, const char *buf) ++{ ++ int ret; ++ ret = c->mtd->read(c->mtd, ofs, len, (char *)buf); ++ if (ret >= 0) { ++ *retlen = ret; ++ return 0; ++ } ++ *retlen = 0; ++ return ret; ++} +\ No newline at end of file +diff -Nupr old/fs/jffs2/readinode.c new/fs/jffs2/readinode.c +--- old/fs/jffs2/readinode.c 2022-05-09 17:22:53.000000000 +0800 ++++ new/fs/jffs2/readinode.c 2022-05-09 20:26:31.030000000 +0800 +@@ -9,17 +9,18 @@ + * + */ + +-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +- + #include + #include + #include + #include +-#include ++#include ++#include + #include +-#include + #include ++#include + #include "nodelist.h" ++#include "os-linux.h" ++#include "los_crc32.h" + + /* + * Check the data CRC of the node. +@@ -31,9 +32,9 @@ + static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info *tn) + { + struct jffs2_raw_node_ref *ref = tn->fn->raw; +- int err = 0, pointed = 0; ++ int err = 0; + struct jffs2_eraseblock *jeb; +- unsigned char *buffer; ++ unsigned char *buffer = NULL; + uint32_t crc, ofs, len; + size_t retlen; + +@@ -61,48 +62,28 @@ static int check_node_data(struct jffs2_ + dbg_readinode("check node at %#08x, data length %u, partial CRC %#08x, correct CRC %#08x, data starts at %#08x, start checking from %#08x - %u bytes.\n", + ref_offset(ref), tn->csize, tn->partial_crc, tn->data_crc, ofs - len, ofs, len); + +-#ifndef __ECOS +- /* TODO: instead, incapsulate point() stuff to jffs2_flash_read(), +- * adding and jffs2_flash_read_end() interface. */ +- err = mtd_point(c->mtd, ofs, len, &retlen, (void **)&buffer, NULL); +- if (!err && retlen < len) { +- JFFS2_WARNING("MTD point returned len too short: %zu instead of %u.\n", retlen, tn->csize); +- mtd_unpoint(c->mtd, ofs, retlen); +- } else if (err) { +- if (err != -EOPNOTSUPP) +- JFFS2_WARNING("MTD point failed: error code %d.\n", err); +- } else +- pointed = 1; /* succefully pointed to device */ +-#endif +- +- if (!pointed) { +- buffer = kmalloc(len, GFP_KERNEL); +- if (unlikely(!buffer)) +- return -ENOMEM; ++ buffer = kmalloc(len, GFP_KERNEL); ++ if (unlikely(!buffer)) ++ return -ENOMEM; + +- /* TODO: this is very frequent pattern, make it a separate +- * routine */ +- err = jffs2_flash_read(c, ofs, len, &retlen, buffer); +- if (err) { +- JFFS2_ERROR("can not read %d bytes from 0x%08x, error code: %d.\n", len, ofs, err); +- goto free_out; +- } ++ /* TODO: this is very frequent pattern, make it a separate ++ * routine */ ++ err = jffs2_flash_read(c, ofs, len, &retlen, (char *)buffer); ++ if (err) { ++ JFFS2_ERROR("can not read %d bytes from 0x%08x, error code: %d.\n", len, ofs, err); ++ goto free_out; ++ } + +- if (retlen != len) { +- JFFS2_ERROR("short read at %#08x: %zd instead of %d.\n", ofs, retlen, len); +- err = -EIO; +- goto free_out; +- } ++ if (retlen != len) { ++ JFFS2_ERROR("short read at %#08x: %zd instead of %d.\n", ofs, retlen, len); ++ err = -EIO; ++ goto free_out; + } + + /* Continue calculating CRC */ + crc = crc32(tn->partial_crc, buffer, len); +- if(!pointed) +- kfree(buffer); +-#ifndef __ECOS +- else +- mtd_unpoint(c->mtd, ofs, len); +-#endif ++ ++ kfree(buffer); + + if (crc != tn->data_crc) { + JFFS2_NOTICE("wrong data CRC in data node at 0x%08x: read %#08x, calculated %#08x.\n", +@@ -133,12 +114,7 @@ adj_acc: + return 0; + + free_out: +- if(!pointed) +- kfree(buffer); +-#ifndef __ECOS +- else +- mtd_unpoint(c->mtd, ofs, len); +-#endif ++ kfree(buffer); + return err; + } + +@@ -415,8 +391,12 @@ static void eat_last(struct rb_root *roo + link = &parent->rb_right; + + *link = node->rb_left; +- if (node->rb_left) +- node->rb_left->__rb_parent_color = node->__rb_parent_color; ++ if (node->rb_left) { ++ node->rb_left->rb_parent_color = node->rb_parent_color; ++ // set child parent only ++ rb_parent(node->rb_left) = parent; ++ node->rb_left = NULL; ++ } + } + + /* We put the version tree in reverse order, so we can use the same eat_last() +@@ -464,8 +444,8 @@ static int jffs2_build_inode_fragtree(st + #ifdef JFFS2_DBG_READINODE_MESSAGES + this = tn_last(&rii->tn_root); + while (this) { +- dbg_readinode("tn %p ver %d range 0x%x-0x%x ov %d\n", this, this->version, this->fn->ofs, +- this->fn->ofs+this->fn->size, this->overlapped); ++ dbg_readinode("tn %p ver %d range 0x%x-0x%x ov %d,left %p,right %p ,parent %p\n", this, this->version, this->fn->ofs, ++ this->fn->ofs+this->fn->size, this->overlapped,this->rb.rb_left,this->rb.rb_right,rb_parent(&(this->rb))); + this = tn_prev(this); + } + #endif +@@ -543,11 +523,13 @@ static int jffs2_build_inode_fragtree(st + + static void jffs2_free_tmp_dnode_info_list(struct rb_root *list) + { +- struct jffs2_tmp_dnode_info *tn, *next; ++ struct jffs2_tmp_dnode_info *tn; ++ struct rb_node *rbn,*next; + +- rbtree_postorder_for_each_entry_safe(tn, next, list, rb) { +- jffs2_free_full_dnode(tn->fn); +- jffs2_free_tmp_dnode_info(tn); ++ RB_POSTORDER_FOREACH_SAFE(rbn, linux_root, (struct linux_root *)list, next) { ++ tn = (struct jffs2_tmp_dnode_info *)rbn; ++ jffs2_free_full_dnode(tn->fn); ++ jffs2_free_tmp_dnode_info(tn); + } + + *list = RB_ROOT; +@@ -659,7 +641,7 @@ static inline int read_direntry(struct j + int already = read - sizeof(*rd); + + err = jffs2_flash_read(c, (ref_offset(ref)) + read, +- rd->nsize - already, &read, &fd->name[already]); ++ rd->nsize - already, &read, (char *)&fd->name[already]); + if (unlikely(read != rd->nsize - already) && likely(!err)) { + jffs2_free_full_dirent(fd); + JFFS2_ERROR("short read: wanted %d bytes, got %zd\n", +@@ -690,7 +672,7 @@ static inline int read_direntry(struct j + #endif + } + +- fd->nhash = full_name_hash(NULL, fd->name, rd->nsize); ++ fd->nhash = full_name_hash(fd->name, rd->nsize); + fd->next = NULL; + fd->name[rd->nsize] = '\0'; + +@@ -956,7 +938,7 @@ static int read_more(struct jffs2_sb_inf + + dbg_readinode("read more %d bytes\n", to_read); + +- err = jffs2_flash_read(c, offs, to_read, &retlen, buf + *rdlen); ++ err = jffs2_flash_read(c, offs, to_read, &retlen, (char *)(buf + *rdlen)); + if (err) { + JFFS2_ERROR("can not read %d bytes from 0x%08x, " + "error code: %d.\n", to_read, offs, err); +@@ -1042,7 +1024,7 @@ static int jffs2_get_inode_nodes(struct + dbg_readinode("read %d bytes at %#08x(%d).\n", len, ref_offset(ref), ref_flags(ref)); + + /* FIXME: point() */ +- err = jffs2_flash_read(c, ref_offset(ref), len, &retlen, buf); ++ err = jffs2_flash_read(c, ref_offset(ref), len, &retlen, (char *)buf); + if (err) { + JFFS2_ERROR("can not read %d bytes from 0x%08x, error code: %d.\n", len, ref_offset(ref), err); + goto free_out; +@@ -1079,6 +1061,7 @@ static int jffs2_get_inode_nodes(struct + + case JFFS2_NODETYPE_DIRENT: + ++ dbg_readinode("node at %08x (%d) is a dirent node\n", ref_offset(ref), ref_flags(ref)); + if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_raw_dirent) && + len < sizeof(struct jffs2_raw_dirent)) { + err = read_more(c, ref, sizeof(struct jffs2_raw_dirent), &len, buf); +@@ -1094,6 +1077,7 @@ static int jffs2_get_inode_nodes(struct + + case JFFS2_NODETYPE_INODE: + ++ dbg_readinode("node at %08x (%d) is a data node\n", ref_offset(ref), ref_flags(ref)); + if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_raw_inode) && + len < sizeof(struct jffs2_raw_inode)) { + err = read_more(c, ref, sizeof(struct jffs2_raw_inode), &len, buf); +@@ -1289,7 +1273,7 @@ static int jffs2_do_read_inode_internal( + dbg_readinode("symlink's target '%s' cached\n", f->target); + } + +- fallthrough; ++ /* fall through... */ + + case S_IFBLK: + case S_IFCHR: +@@ -1315,7 +1299,7 @@ static int jffs2_do_read_inode_internal( + /* OK. We're happy */ + f->metadata = frag_first(&f->fragtree)->node; + jffs2_free_node_frag(frag_first(&f->fragtree)); +- f->fragtree = RB_ROOT; ++ f->fragtree.rb_node = NULL; + break; + } + if (f->inocache->state == INO_STATE_READING) +@@ -1362,6 +1346,7 @@ int jffs2_do_read_inode(struct jffs2_sb_ + break; + + default: ++ JFFS2_ERROR("Unknown f->inocache->state %d!\n", f->inocache->state); + BUG(); + } + } +@@ -1375,14 +1360,13 @@ int jffs2_do_read_inode(struct jffs2_sb_ + return -ENOMEM; + } + dbg_readinode("creating inocache for root inode\n"); +- memset(f->inocache, 0, sizeof(struct jffs2_inode_cache)); + f->inocache->ino = f->inocache->pino_nlink = 1; + f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache; + f->inocache->state = INO_STATE_READING; + jffs2_add_ino_cache(c, f->inocache); + } + if (!f->inocache) { +- JFFS2_ERROR("requested to read a nonexistent ino %u\n", ino); ++ JFFS2_ERROR("requestied to read an nonexistent ino %u\n", ino); + return -ENOENT; + } + +@@ -1430,6 +1414,11 @@ void jffs2_do_clear_inode(struct jffs2_s + + jffs2_kill_fragtree(&f->fragtree, deleted?c:NULL); + ++ if (f->target) { ++ kfree(f->target); ++ f->target = NULL; ++ } ++ + fds = f->dents; + while(fds) { + fd = fds; +diff -Nupr old/fs/jffs2/scan.c new/fs/jffs2/scan.c +--- old/fs/jffs2/scan.c 2022-05-09 17:22:53.000000000 +0800 ++++ new/fs/jffs2/scan.c 2022-05-09 20:23:02.230000000 +0800 +@@ -9,18 +9,17 @@ + * + */ + +-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +- + #include + #include + #include +-#include + #include +-#include + #include + #include "nodelist.h" + #include "summary.h" + #include "debug.h" ++#include "mtd_dev.h" ++#include "los_typedef.h" ++#include "los_crc32.h" + + #define DEFAULT_EMPTY_SCAN_SIZE 256 + +@@ -74,7 +73,7 @@ static int file_dirty(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) + return ret; + if ((ret = jffs2_scan_dirty_space(c, jeb, jeb->free_size))) + return ret; +- /* Turned wasted size into dirty, since we apparently ++ /* Turned wasted size into dirty, since we apparently + think it's recoverable now. */ + jeb->dirty_size += jeb->wasted_size; + c->dirty_size += jeb->wasted_size; +@@ -95,40 +94,26 @@ int jffs2_scan_medium(struct jffs2_sb_info *c) + unsigned char *flashbuf = NULL; + uint32_t buf_size = 0; + struct jffs2_summary *s = NULL; /* summary info collected by the scan process */ +-#ifndef __ECOS +- size_t pointlen, try_size; +- +- ret = mtd_point(c->mtd, 0, c->mtd->size, &pointlen, +- (void **)&flashbuf, NULL); +- if (!ret && pointlen < c->mtd->size) { +- /* Don't muck about if it won't let us point to the whole flash */ +- jffs2_dbg(1, "MTD point returned len too short: 0x%zx\n", +- pointlen); +- mtd_unpoint(c->mtd, 0, pointlen); +- flashbuf = NULL; +- } +- if (ret && ret != -EOPNOTSUPP) +- jffs2_dbg(1, "MTD point failed %d\n", ret); +-#endif ++ struct super_block *sb = NULL; ++ struct MtdNorDev *device = NULL; ++ + if (!flashbuf) { + /* For NAND it's quicker to read a whole eraseblock at a time, + apparently */ + if (jffs2_cleanmarker_oob(c)) +- try_size = c->sector_size; ++ buf_size = c->sector_size; + else +- try_size = PAGE_SIZE; ++ buf_size = PAGE_SIZE; + + jffs2_dbg(1, "Trying to allocate readbuf of %zu " +- "bytes\n", try_size); ++ "bytes\n", buf_size); + +- flashbuf = mtd_kmalloc_up_to(c->mtd, &try_size); ++ flashbuf = kmalloc(buf_size, GFP_KERNEL); + if (!flashbuf) + return -ENOMEM; + + jffs2_dbg(1, "Allocated readbuf of %zu bytes\n", +- try_size); +- +- buf_size = (uint32_t)try_size; ++ buf_size); + } + + if (jffs2_sum_active()) { +@@ -140,7 +125,9 @@ int jffs2_scan_medium(struct jffs2_sb_info *c) + } + } + +- for (i=0; inr_blocks; i++) { ++ sb = OFNI_BS_2SFFJ(c); ++ device = (struct MtdNorDev*)(sb->s_dev); ++ for (i=device->blockStart; inr_blocks + device->blockStart; i++) { + struct jffs2_eraseblock *jeb = &c->blocks[i]; + + cond_resched(); +@@ -269,14 +256,10 @@ int jffs2_scan_medium(struct jffs2_sb_info *c) + ret = -EIO; + goto out; + } +- spin_lock(&c->erase_completion_lock); +- jffs2_garbage_collect_trigger(c); +- spin_unlock(&c->erase_completion_lock); + } + ret = 0; + out: +- jffs2_sum_reset_collected(s); +- kfree(s); ++ kfree(flashbuf); + out_buf: + if (buf_size) + kfree(flashbuf); +@@ -413,7 +396,7 @@ static int jffs2_scan_xref_node(struct jffs2_sb_info *c, struct jffs2_eraseblock + if (!ref) + return -ENOMEM; + +- /* BEFORE jffs2_build_xattr_subsystem() called, ++ /* BEFORE jffs2_build_xattr_subsystem() called, + * and AFTER xattr_ref is marked as a dead xref, + * ref->xid is used to store 32bit xid, xd is not used + * ref->ino is used to store 32bit inode-number, ic is not used +@@ -486,10 +469,10 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo + struct jffs2_sum_marker *sm; + void *sumptr = NULL; + uint32_t sumlen; +- ++ + if (!buf_size) { + /* XIP case. Just look, point at the summary if it's there */ +- sm = (void *)buf + c->sector_size - sizeof(*sm); ++ sm = (struct jffs2_sum_marker *)((uint8_t *)buf + c->sector_size - sizeof(*sm)); + if (je32_to_cpu(sm->magic) == JFFS2_SUM_MAGIC) { + sumptr = buf + je32_to_cpu(sm->offset); + sumlen = c->sector_size - je32_to_cpu(sm->offset); +@@ -502,13 +485,13 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo + buf_len = sizeof(*sm); + + /* Read as much as we want into the _end_ of the preallocated buffer */ +- err = jffs2_fill_scan_buf(c, buf + buf_size - buf_len, ++ err = jffs2_fill_scan_buf(c, buf + buf_size - buf_len, + jeb->offset + c->sector_size - buf_len, +- buf_len); ++ buf_len); + if (err) + return err; + +- sm = (void *)buf + buf_size - sizeof(*sm); ++ sm = (struct jffs2_sum_marker *)((uint8_t *)buf + buf_size - sizeof(*sm)); + if (je32_to_cpu(sm->magic) == JFFS2_SUM_MAGIC) { + sumlen = c->sector_size - je32_to_cpu(sm->offset); + sumptr = buf + buf_size - sumlen; +@@ -523,18 +506,15 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo + sumptr = kmalloc(sumlen, GFP_KERNEL); + if (!sumptr) + return -ENOMEM; +- memcpy(sumptr + sumlen - buf_len, buf + buf_size - buf_len, buf_len); ++ memcpy((uint8_t *)sumptr + sumlen - buf_len, buf + buf_size - buf_len, buf_len); + } + if (buf_len < sumlen) { + /* Need to read more so that the entire summary node is present */ +- err = jffs2_fill_scan_buf(c, sumptr, ++ err = jffs2_fill_scan_buf(c, sumptr, + jeb->offset + c->sector_size - sumlen, +- sumlen - buf_len); +- if (err) { +- if (sumlen > buf_size) +- kfree(sumptr); ++ sumlen - buf_len); ++ if (err) + return err; +- } + } + } + +@@ -545,7 +525,7 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo + + if (buf_size && sumlen > buf_size) + kfree(sumptr); +- /* If it returns with a real error, bail. ++ /* If it returns with a real error, bail. + If it returns positive, that's a block classification + (i.e. BLK_STATE_xxx) so return that too. + If it returns zero, fall through to full scan. */ +@@ -607,7 +587,7 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo + /* Now ofs is a complete physical flash offset as it always was... */ + ofs += jeb->offset; + +- noise = 10; ++ noise = 1; + + dbg_summary("no summary found in jeb 0x%08x. Apply original scan.\n",jeb->offset); + +@@ -700,7 +680,7 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo + scan_end = buf_len; + goto more_empty; + } +- ++ + /* See how much more there is to read in this eraseblock... */ + buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs); + if (!buf_len) { +@@ -950,7 +930,7 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo + jffs2_dbg(1, "Block at 0x%08x: free 0x%08x, dirty 0x%08x, unchecked 0x%08x, used 0x%08x, wasted 0x%08x\n", + jeb->offset, jeb->free_size, jeb->dirty_size, + jeb->unchecked_size, jeb->used_size, jeb->wasted_size); +- ++ + /* mark_node_obsolete can add to wasted !! */ + if (jeb->wasted_size) { + jeb->dirty_size += jeb->wasted_size; +@@ -978,7 +958,6 @@ struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uin + pr_notice("%s(): allocation of inode cache failed\n", __func__); + return NULL; + } +- memset(ic, 0, sizeof(*ic)); + + ic->ino = ino; + ic->nodes = (void *)ic; +@@ -1069,7 +1048,7 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo + pseudo_random += je32_to_cpu(rd->version); + + /* Should never happen. Did. (OLPC trac #4184)*/ +- checkedlen = strnlen(rd->name, rd->nsize); ++ checkedlen = strnlen((const char *)rd->name, rd->nsize); + if (checkedlen < rd->nsize) { + pr_err("Dirent at %08x has zeroes in name. Truncating to %d chars\n", + ofs, checkedlen); +@@ -1081,7 +1060,7 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo + memcpy(&fd->name, rd->name, checkedlen); + fd->name[checkedlen] = 0; + +- crc = crc32(0, fd->name, checkedlen); ++ crc = crc32(0, fd->name, rd->nsize); + if (crc != je32_to_cpu(rd->name_crc)) { + pr_notice("%s(): Name CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", + __func__, ofs, je32_to_cpu(rd->name_crc), crc); +@@ -1106,7 +1085,7 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo + fd->next = NULL; + fd->version = je32_to_cpu(rd->version); + fd->ino = je32_to_cpu(rd->ino); +- fd->nhash = full_name_hash(NULL, fd->name, checkedlen); ++ fd->nhash = full_name_hash(fd->name, checkedlen); + fd->type = rd->type; + jffs2_add_fd_to_list(c, fd, &ic->scan_dents); + +diff +@@ -9,18 +9,17 @@ + * + */ + +-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +- + #include + #include + #include +-#include + #include +-#include + #include + #include "nodelist.h" + #include "summary.h" + #include "debug.h" ++#include "mtd_dev.h" ++#include "los_typedef.h" ++#include "los_crc32.h" + + #define DEFAULT_EMPTY_SCAN_SIZE 256 + +@@ -74,7 +73,7 @@ static int file_dirty(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) + return ret; + if ((ret = jffs2_scan_dirty_space(c, jeb, jeb->free_size))) + return ret; +- /* Turned wasted size into dirty, since we apparently ++ /* Turned wasted size into dirty, since we apparently + think it's recoverable now. */ + jeb->dirty_size += jeb->wasted_size; + c->dirty_size += jeb->wasted_size; +@@ -95,40 +94,26 @@ int jffs2_scan_medium(struct jffs2_sb_info *c) + unsigned char *flashbuf = NULL; + uint32_t buf_size = 0; + struct jffs2_summary *s = NULL; /* summary info collected by the scan process */ +-#ifndef __ECOS +- size_t pointlen, try_size; +- +- ret = mtd_point(c->mtd, 0, c->mtd->size, &pointlen, +- (void **)&flashbuf, NULL); +- if (!ret && pointlen < c->mtd->size) { +- /* Don't muck about if it won't let us point to the whole flash */ +- jffs2_dbg(1, "MTD point returned len too short: 0x%zx\n", +- pointlen); +- mtd_unpoint(c->mtd, 0, pointlen); +- flashbuf = NULL; +- } +- if (ret && ret != -EOPNOTSUPP) +- jffs2_dbg(1, "MTD point failed %d\n", ret); +-#endif ++ struct super_block *sb = NULL; ++ struct MtdNorDev *device = NULL; ++ + if (!flashbuf) { + /* For NAND it's quicker to read a whole eraseblock at a time, + apparently */ + if (jffs2_cleanmarker_oob(c)) +- try_size = c->sector_size; ++ buf_size = c->sector_size; + else +- try_size = PAGE_SIZE; ++ buf_size = PAGE_SIZE; + + jffs2_dbg(1, "Trying to allocate readbuf of %zu " +- "bytes\n", try_size); ++ "bytes\n", buf_size); + +- flashbuf = mtd_kmalloc_up_to(c->mtd, &try_size); ++ flashbuf = kmalloc(buf_size, GFP_KERNEL); + if (!flashbuf) + return -ENOMEM; + + jffs2_dbg(1, "Allocated readbuf of %zu bytes\n", +- try_size); +- +- buf_size = (uint32_t)try_size; ++ buf_size); + } + + if (jffs2_sum_active()) { +@@ -140,7 +125,9 @@ int jffs2_scan_medium(struct jffs2_sb_info *c) + } + } + +- for (i=0; inr_blocks; i++) { ++ sb = OFNI_BS_2SFFJ(c); ++ device = (struct MtdNorDev*)(sb->s_dev); ++ for (i=device->blockStart; inr_blocks + device->blockStart; i++) { + struct jffs2_eraseblock *jeb = &c->blocks[i]; + + cond_resched(); +@@ -269,14 +256,10 @@ int jffs2_scan_medium(struct jffs2_sb_info *c) + ret = -EIO; + goto out; + } +- spin_lock(&c->erase_completion_lock); +- jffs2_garbage_collect_trigger(c); +- spin_unlock(&c->erase_completion_lock); + } + ret = 0; + out: +- jffs2_sum_reset_collected(s); +- kfree(s); ++ kfree(flashbuf); + out_buf: + if (buf_size) + kfree(flashbuf); +@@ -413,7 +396,7 @@ static int jffs2_scan_xref_node(struct jffs2_sb_info *c, struct jffs2_eraseblock + if (!ref) + return -ENOMEM; + +- /* BEFORE jffs2_build_xattr_subsystem() called, ++ /* BEFORE jffs2_build_xattr_subsystem() called, + * and AFTER xattr_ref is marked as a dead xref, + * ref->xid is used to store 32bit xid, xd is not used + * ref->ino is used to store 32bit inode-number, ic is not used +@@ -486,10 +469,10 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo + struct jffs2_sum_marker *sm; + void *sumptr = NULL; + uint32_t sumlen; +- ++ + if (!buf_size) { + /* XIP case. Just look, point at the summary if it's there */ +- sm = (void *)buf + c->sector_size - sizeof(*sm); ++ sm = (struct jffs2_sum_marker *)((uint8_t *)buf + c->sector_size - sizeof(*sm)); + if (je32_to_cpu(sm->magic) == JFFS2_SUM_MAGIC) { + sumptr = buf + je32_to_cpu(sm->offset); + sumlen = c->sector_size - je32_to_cpu(sm->offset); +@@ -502,13 +485,13 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo + buf_len = sizeof(*sm); + + /* Read as much as we want into the _end_ of the preallocated buffer */ +- err = jffs2_fill_scan_buf(c, buf + buf_size - buf_len, ++ err = jffs2_fill_scan_buf(c, buf + buf_size - buf_len, + jeb->offset + c->sector_size - buf_len, +- buf_len); ++ buf_len); + if (err) + return err; + +- sm = (void *)buf + buf_size - sizeof(*sm); ++ sm = (struct jffs2_sum_marker *)((uint8_t *)buf + buf_size - sizeof(*sm)); + if (je32_to_cpu(sm->magic) == JFFS2_SUM_MAGIC) { + sumlen = c->sector_size - je32_to_cpu(sm->offset); + sumptr = buf + buf_size - sumlen; +@@ -523,18 +506,15 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo + sumptr = kmalloc(sumlen, GFP_KERNEL); + if (!sumptr) + return -ENOMEM; +- memcpy(sumptr + sumlen - buf_len, buf + buf_size - buf_len, buf_len); ++ memcpy((uint8_t *)sumptr + sumlen - buf_len, buf + buf_size - buf_len, buf_len); + } + if (buf_len < sumlen) { + /* Need to read more so that the entire summary node is present */ +- err = jffs2_fill_scan_buf(c, sumptr, ++ err = jffs2_fill_scan_buf(c, sumptr, + jeb->offset + c->sector_size - sumlen, +- sumlen - buf_len); +- if (err) { +- if (sumlen > buf_size) +- kfree(sumptr); ++ sumlen - buf_len); ++ if (err) + return err; +- } + } + } + +@@ -545,7 +525,7 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo + + if (buf_size && sumlen > buf_size) + kfree(sumptr); +- /* If it returns with a real error, bail. ++ /* If it returns with a real error, bail. + If it returns positive, that's a block classification + (i.e. BLK_STATE_xxx) so return that too. + If it returns zero, fall through to full scan. */ +@@ -607,7 +587,7 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo + /* Now ofs is a complete physical flash offset as it always was... */ + ofs += jeb->offset; + +- noise = 10; ++ noise = 1; + + dbg_summary("no summary found in jeb 0x%08x. Apply original scan.\n",jeb->offset); + +@@ -700,7 +680,7 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo + scan_end = buf_len; + goto more_empty; + } +- ++ + /* See how much more there is to read in this eraseblock... */ + buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs); + if (!buf_len) { +@@ -950,7 +930,7 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo + jffs2_dbg(1, "Block at 0x%08x: free 0x%08x, dirty 0x%08x, unchecked 0x%08x, used 0x%08x, wasted 0x%08x\n", + jeb->offset, jeb->free_size, jeb->dirty_size, + jeb->unchecked_size, jeb->used_size, jeb->wasted_size); +- ++ + /* mark_node_obsolete can add to wasted !! */ + if (jeb->wasted_size) { + jeb->dirty_size += jeb->wasted_size; +@@ -978,7 +958,6 @@ struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uin + pr_notice("%s(): allocation of inode cache failed\n", __func__); + return NULL; + } +- memset(ic, 0, sizeof(*ic)); + + ic->ino = ino; + ic->nodes = (void *)ic; +@@ -1069,7 +1048,7 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo + pseudo_random += je32_to_cpu(rd->version); + + /* Should never happen. Did. (OLPC trac #4184)*/ +- checkedlen = strnlen(rd->name, rd->nsize); ++ checkedlen = strnlen((const char *)rd->name, rd->nsize); + if (checkedlen < rd->nsize) { + pr_err("Dirent at %08x has zeroes in name. Truncating to %d chars\n", + ofs, checkedlen); +@@ -1081,7 +1060,7 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo + memcpy(&fd->name, rd->name, checkedlen); + fd->name[checkedlen] = 0; + +- crc = crc32(0, fd->name, checkedlen); ++ crc = crc32(0, fd->name, rd->nsize); + if (crc != je32_to_cpu(rd->name_crc)) { + pr_notice("%s(): Name CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", + __func__, ofs, je32_to_cpu(rd->name_crc), crc); +@@ -1106,7 +1085,7 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo + fd->next = NULL; + fd->version = je32_to_cpu(rd->version); + fd->ino = je32_to_cpu(rd->ino); +- fd->nhash = full_name_hash(NULL, fd->name, checkedlen); ++ fd->nhash = full_name_hash(fd->name, checkedlen); + fd->type = rd->type; + jffs2_add_fd_to_list(c, fd, &ic->scan_dents); + +diff -Nupr old/fs/jffs2/security.c new/fs/jffs2/security.c +--- old/fs/jffs2/security.c 2022-05-09 17:15:24.350000000 +0800 ++++ new/fs/jffs2/security.c 1970-01-01 08:00:00.000000000 +0800 +@@ -1,72 +0,0 @@ +-/* +- * JFFS2 -- Journalling Flash File System, Version 2. +- * +- * Copyright © 2006 NEC Corporation +- * +- * Created by KaiGai Kohei +- * +- * For licensing information, see the file 'LICENCE' in this directory. +- * +- */ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include "nodelist.h" +- +-/* ---- Initial Security Label(s) Attachment callback --- */ +-static int jffs2_initxattrs(struct inode *inode, +- const struct xattr *xattr_array, void *fs_info) +-{ +- const struct xattr *xattr; +- int err = 0; +- +- for (xattr = xattr_array; xattr->name != NULL; xattr++) { +- err = do_jffs2_setxattr(inode, JFFS2_XPREFIX_SECURITY, +- xattr->name, xattr->value, +- xattr->value_len, 0); +- if (err < 0) +- break; +- } +- return err; +-} +- +-/* ---- Initial Security Label(s) Attachment ----------- */ +-int jffs2_init_security(struct inode *inode, struct inode *dir, +- const struct qstr *qstr) +-{ +- return security_inode_init_security(inode, dir, qstr, +- &jffs2_initxattrs, NULL); +-} +- +-/* ---- XATTR Handler for "security.*" ----------------- */ +-static int jffs2_security_getxattr(const struct xattr_handler *handler, +- struct dentry *unused, struct inode *inode, +- const char *name, void *buffer, size_t size) +-{ +- return do_jffs2_getxattr(inode, JFFS2_XPREFIX_SECURITY, +- name, buffer, size); +-} +- +-static int jffs2_security_setxattr(const struct xattr_handler *handler, +- struct dentry *unused, struct inode *inode, +- const char *name, const void *buffer, +- size_t size, int flags) +-{ +- return do_jffs2_setxattr(inode, JFFS2_XPREFIX_SECURITY, +- name, buffer, size, flags); +-} +- +-const struct xattr_handler jffs2_security_xattr_handler = { +- .prefix = XATTR_SECURITY_PREFIX, +- .set = jffs2_security_setxattr, +- .get = jffs2_security_getxattr +-}; +diff -Nupr old/fs/jffs2/summary.c new/fs/jffs2/summary.c +--- old/fs/jffs2/summary.c 2022-05-09 17:22:53.000000000 +0800 ++++ new/fs/jffs2/summary.c 2022-05-09 20:13:24.440000000 +0800 +@@ -10,16 +10,20 @@ + * For licensing information, see the file 'LICENCE' in this directory. + * + */ ++#include "summary.h" + ++#ifdef CONFIG_JFFS2_SUMMARY ++ ++#ifndef pr_fmt + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt ++#endif + + #include + #include +-#include ++#include + #include +-#include ++#include "los_crc32.h" + #include +-#include + #include "nodelist.h" + #include "debug.h" + +@@ -388,11 +392,25 @@ static int jffs2_sum_process_sum_data(st + { + struct jffs2_inode_cache *ic; + struct jffs2_full_dirent *fd; +- void *sp; ++ uintptr_t sp; + int i, ino; + int err; + +- sp = summary->sum; ++ sp = (uintptr_t)summary->sum; ++ ++#if 0 ++ PRINTK("summary: %x %x %d %d %x %x %d %x %x %p %p\n", ++ je16_to_cpu(summary->magic), ++ je16_to_cpu(summary->nodetype), ++ je32_to_cpu(summary->totlen), ++ je32_to_cpu(summary->hdr_crc), ++ je32_to_cpu(summary->sum_num), ++ je32_to_cpu(summary->cln_mkr), ++ je32_to_cpu(summary->padded), ++ je32_to_cpu(summary->sum_crc), ++ je32_to_cpu(summary->node_crc), ++ sp, summary->sum); ++#endif + + for (i=0; isum_num); i++) { + dbg_summary("processing summary index %d\n", i); +@@ -404,10 +422,12 @@ static int jffs2_sum_process_sum_data(st + if (err) + return err; + ++ //PRINTK("sum type %d \n", je16_to_cpu(((struct jffs2_sum_unknown_flash *)sp)->nodetype)); ++ + switch (je16_to_cpu(((struct jffs2_sum_unknown_flash *)sp)->nodetype)) { + case JFFS2_NODETYPE_INODE: { + struct jffs2_sum_inode_flash *spi; +- spi = sp; ++ spi = (struct jffs2_sum_inode_flash *)sp; + + ino = je32_to_cpu(spi->inode); + +@@ -428,13 +448,29 @@ static int jffs2_sum_process_sum_data(st + + sp += JFFS2_SUMMARY_INODE_SIZE; + ++ //PRINTK("1 sp + %d %p\n", JFFS2_SUMMARY_INODE_SIZE, sp); ++ + break; + } + + case JFFS2_NODETYPE_DIRENT: { + struct jffs2_sum_dirent_flash *spd; + int checkedlen; +- spd = sp; ++ spd = (struct jffs2_sum_dirent_flash *)sp; ++ ++ ++#if 0 ++ PRINTK("dir: %x %d %d %d %d %d %d %d %d\n", ++ je16_to_cpu(spd->nodetype), ++ je32_to_cpu(spd->totlen), ++ je32_to_cpu(spd->offset), ++ je32_to_cpu(spd->pino), ++ je32_to_cpu(spd->version), ++ je32_to_cpu(spd->ino), ++ spd->nsize, ++ spd->type, ++ spd->name); ++#endif + + dbg_summary("Dirent at 0x%08x-0x%08x\n", + jeb->offset + je32_to_cpu(spd->offset), +@@ -442,7 +478,7 @@ static int jffs2_sum_process_sum_data(st + + + /* This should never happen, but https://dev.laptop.org/ticket/4184 */ +- checkedlen = strnlen(spd->name, spd->nsize); ++ checkedlen = strnlen((const char *)spd->name, spd->nsize); + if (!checkedlen) { + pr_err("Dirent at %08x has zero at start of name. Aborting mount.\n", + jeb->offset + +@@ -463,6 +499,7 @@ static int jffs2_sum_process_sum_data(st + + memcpy(&fd->name, spd->name, checkedlen); + fd->name[checkedlen] = 0; ++ //PRINTK("add %s \n", fd->name); + + ic = jffs2_scan_make_ino_cache(c, je32_to_cpu(spd->pino)); + if (!ic) { +@@ -476,15 +513,19 @@ static int jffs2_sum_process_sum_data(st + fd->next = NULL; + fd->version = je32_to_cpu(spd->version); + fd->ino = je32_to_cpu(spd->ino); +- fd->nhash = full_name_hash(NULL, fd->name, checkedlen); ++ fd->nhash = full_name_hash((const unsigned char *)fd->name, checkedlen); + fd->type = spd->type; + + jffs2_add_fd_to_list(c, fd, &ic->scan_dents); + + *pseudo_random += je32_to_cpu(spd->version); + ++ //PRINTK("2 sp before add %p\n", sp); ++ + sp += JFFS2_SUMMARY_DIRENT_SIZE(spd->nsize); + ++ //PRINTK("2 sp + %d %p\n", JFFS2_SUMMARY_DIRENT_SIZE(spd->nsize), sp); ++ + break; + } + #ifdef CONFIG_JFFS2_FS_XATTR +@@ -493,7 +534,7 @@ static int jffs2_sum_process_sum_data(st + struct jffs2_sum_xattr_flash *spx; + + spx = (struct jffs2_sum_xattr_flash *)sp; +- dbg_summary("xattr at %#08x-%#08x (xid=%u, version=%u)\n", ++ dbg_summary("xattr at %#08x-%#08x (xid=%u, version=%u)\n", + jeb->offset + je32_to_cpu(spx->offset), + jeb->offset + je32_to_cpu(spx->offset) + je32_to_cpu(spx->totlen), + je32_to_cpu(spx->xid), je32_to_cpu(spx->version)); +@@ -526,7 +567,7 @@ static int jffs2_sum_process_sum_data(st + spr = (struct jffs2_sum_xref_flash *)sp; + dbg_summary("xref at %#08x-%#08x\n", + jeb->offset + je32_to_cpu(spr->offset), +- jeb->offset + je32_to_cpu(spr->offset) + ++ jeb->offset + je32_to_cpu(spr->offset) + + (uint32_t)PAD(sizeof(struct jffs2_raw_xref))); + + ref = jffs2_alloc_xattr_ref(); +@@ -679,7 +720,7 @@ static int jffs2_sum_write_data(struct j + struct jffs2_sum_marker *sm; + struct kvec vecs[2]; + uint32_t sum_ofs; +- void *wpage; ++ uintptr_t wpage; + int ret; + size_t retlen; + +@@ -713,14 +754,14 @@ static int jffs2_sum_write_data(struct j + isum.padded = cpu_to_je32(c->summary->sum_padded); + isum.cln_mkr = cpu_to_je32(c->cleanmarker_size); + isum.sum_num = cpu_to_je32(c->summary->sum_num); +- wpage = c->summary->sum_buf; ++ wpage = (uintptr_t)c->summary->sum_buf; + + while (c->summary->sum_num) { + temp = c->summary->sum_list_head; + + switch (je16_to_cpu(temp->u.nodetype)) { + case JFFS2_NODETYPE_INODE: { +- struct jffs2_sum_inode_flash *sino_ptr = wpage; ++ struct jffs2_sum_inode_flash *sino_ptr = (struct jffs2_sum_inode_flash *)wpage; + + sino_ptr->nodetype = temp->i.nodetype; + sino_ptr->inode = temp->i.inode; +@@ -734,7 +775,7 @@ static int jffs2_sum_write_data(struct j + } + + case JFFS2_NODETYPE_DIRENT: { +- struct jffs2_sum_dirent_flash *sdrnt_ptr = wpage; ++ struct jffs2_sum_dirent_flash *sdrnt_ptr = (struct jffs2_sum_dirent_flash *)wpage; + + sdrnt_ptr->nodetype = temp->d.nodetype; + sdrnt_ptr->totlen = temp->d.totlen; +@@ -802,7 +843,7 @@ static int jffs2_sum_write_data(struct j + + wpage += padsize; + +- sm = wpage; ++ sm = (struct jffs2_sum_marker *)wpage; + sm->offset = cpu_to_je32(c->sector_size - jeb->free_size); + sm->magic = cpu_to_je32(JFFS2_SUM_MAGIC); + +@@ -847,7 +888,7 @@ static int jffs2_sum_write_data(struct j + /* Write out summary information - called from jffs2_do_reserve_space */ + + int jffs2_sum_write_sumnode(struct jffs2_sb_info *c) +- __must_hold(&c->erase_completion_block) ++ //__must_hold(&c->erase_completion_block) + { + int datasize, infosize, padsize; + struct jffs2_eraseblock *jeb; +@@ -875,3 +916,5 @@ int jffs2_sum_write_sumnode(struct jffs2 + spin_lock(&c->erase_completion_lock); + return ret; + } ++ ++#endif +diff -Nupr old/fs/jffs2/summary.h new/fs/jffs2/summary.h +--- old/fs/jffs2/summary.h 2022-05-09 17:22:53.000000000 +0800 ++++ new/fs/jffs2/summary.h 2022-05-09 20:35:43.430000000 +0800 +@@ -19,8 +19,9 @@ + anyway. */ + #define MAX_SUMMARY_SIZE 65536 + +-#include +-#include ++#include ++#include ++#include "jffs2.h" + + #define BLK_STATE_ALLFF 0 + #define BLK_STATE_CLEAN 1 +@@ -169,6 +170,10 @@ struct jffs2_sum_marker + + #define JFFS2_SUMMARY_FRAME_SIZE (sizeof(struct jffs2_raw_summary) + sizeof(struct jffs2_sum_marker)) + ++#ifdef LOSCFG_FS_JFFS2_SUMMARY ++#define CONFIG_JFFS2_SUMMARY ++#endif ++ + #ifdef CONFIG_JFFS2_SUMMARY /* SUMMARY SUPPORT ENABLED */ + + #define jffs2_sum_active() (1) +diff -Nupr old/fs/jffs2/super.c new/fs/jffs2/super.c +--- old/fs/jffs2/super.c 2022-05-09 17:22:53.000000000 +0800 ++++ new/fs/jffs2/super.c 2022-05-09 20:09:32.170000000 +0800 +@@ -9,433 +9,188 @@ + * + */ + +-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include "compr.h" ++#include "jffs2.h" + #include "nodelist.h" ++#include "jffs2_fs_sb.h" ++#include "mtd_dev.h" ++#include "mtd_partition.h" ++#include "compr.h" ++#include "jffs2_hash.h" + +-static void jffs2_put_super(struct super_block *); +- +-static struct kmem_cache *jffs2_inode_cachep; ++static unsigned char jffs2_mounted_number = 0; /* a counter to track the number of jffs2 instances mounted */ ++struct MtdNorDev jffs2_dev_list[CONFIG_MTD_PATTITION_NUM]; + +-static struct inode *jffs2_alloc_inode(struct super_block *sb) ++/* ++ * fill in the superblock ++ */ ++int jffs2_fill_super(struct super_block *sb) + { +- struct jffs2_inode_info *f; +- +- f = kmem_cache_alloc(jffs2_inode_cachep, GFP_KERNEL); +- if (!f) +- return NULL; +- return &f->vfs_inode; +-} ++ int ret; ++ struct jffs2_sb_info *c; ++ struct MtdNorDev *device; + +-static void jffs2_free_inode(struct inode *inode) +-{ +- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); ++ c = JFFS2_SB_INFO(sb); ++ device = (struct MtdNorDev*)(sb->s_dev); + +- kfree(f->target); +- kmem_cache_free(jffs2_inode_cachep, f); +-} ++ (void)mutex_init(&c->alloc_sem); ++ (void)mutex_init(&c->erase_free_sem); ++ spin_lock_init(&c->erase_completion_lock); ++ spin_lock_init(&c->inocache_lock); + +-static void jffs2_i_init_once(void *foo) +-{ +- struct jffs2_inode_info *f = foo; ++ /* sector size is the erase block size */ ++ c->sector_size = device->blockSize; ++ c->flash_size = (device->blockEnd - device->blockStart + 1) * device->blockSize; ++ c->cleanmarker_size = sizeof(struct jffs2_unknown_node); + +- mutex_init(&f->sem); +- inode_init_once(&f->vfs_inode); +-} ++ ret = jffs2_do_mount_fs(c); ++ if (ret) { ++ (void)mutex_destroy(&c->alloc_sem); ++ (void)mutex_destroy(&c->erase_free_sem); ++ return ret; ++ } ++ D1(printk(KERN_DEBUG "jffs2_fill_super(): Getting root inode\n")); ++ ++ sb->s_root = jffs2_iget(sb, 1); ++ ++ if (IS_ERR(sb->s_root)) { ++ D1(printk(KERN_WARNING "get root inode failed\n")); ++ ret = PTR_ERR(sb->s_root); ++ sb->s_root = NULL; ++ jffs2_free_ino_caches(c); ++ jffs2_free_raw_node_refs(c); ++ free(c->blocks); ++ (void)mutex_destroy(&c->alloc_sem); ++ (void)mutex_destroy(&c->erase_free_sem); + +-static const char *jffs2_compr_name(unsigned int compr) +-{ +- switch (compr) { +- case JFFS2_COMPR_MODE_NONE: +- return "none"; +-#ifdef CONFIG_JFFS2_LZO +- case JFFS2_COMPR_MODE_FORCELZO: +- return "lzo"; +-#endif +-#ifdef CONFIG_JFFS2_ZLIB +- case JFFS2_COMPR_MODE_FORCEZLIB: +- return "zlib"; +-#endif +- default: +- /* should never happen; programmer error */ +- WARN_ON(1); +- return ""; ++ return ret; + } +-} +- +-static int jffs2_show_options(struct seq_file *s, struct dentry *root) +-{ +- struct jffs2_sb_info *c = JFFS2_SB_INFO(root->d_sb); +- struct jffs2_mount_opts *opts = &c->mount_opts; +- +- if (opts->override_compr) +- seq_printf(s, ",compr=%s", jffs2_compr_name(opts->compr)); +- if (opts->set_rp_size) +- seq_printf(s, ",rp_size=%u", opts->rp_size / 1024); +- +- return 0; +-} +- +-static int jffs2_sync_fs(struct super_block *sb, int wait) +-{ +- struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); +- +-#ifdef CONFIG_JFFS2_FS_WRITEBUFFER +- if (jffs2_is_writebuffered(c)) +- cancel_delayed_work_sync(&c->wbuf_dwork); +-#endif +- +- mutex_lock(&c->alloc_sem); +- jffs2_flush_wbuf_pad(c); +- mutex_unlock(&c->alloc_sem); + return 0; + } + +-static struct inode *jffs2_nfs_get_inode(struct super_block *sb, uint64_t ino, +- uint32_t generation) ++int jffs2_mount(int part_no, struct jffs2_inode **root_node, unsigned long mountflags) + { +- /* We don't care about i_generation. We'll destroy the flash +- before we start re-using inode numbers anyway. And even +- if that wasn't true, we'd have other problems...*/ +- return jffs2_iget(sb, ino); +-} +- +-static struct dentry *jffs2_fh_to_dentry(struct super_block *sb, struct fid *fid, +- int fh_len, int fh_type) +-{ +- return generic_fh_to_dentry(sb, fid, fh_len, fh_type, +- jffs2_nfs_get_inode); +-} +- +-static struct dentry *jffs2_fh_to_parent(struct super_block *sb, struct fid *fid, +- int fh_len, int fh_type) +-{ +- return generic_fh_to_parent(sb, fid, fh_len, fh_type, +- jffs2_nfs_get_inode); +-} +- +-static struct dentry *jffs2_get_parent(struct dentry *child) +-{ +- struct jffs2_inode_info *f; +- uint32_t pino; +- +- BUG_ON(!d_is_dir(child)); +- +- f = JFFS2_INODE_INFO(d_inode(child)); +- +- pino = f->inocache->pino_nlink; +- +- JFFS2_DEBUG("Parent of directory ino #%u is #%u\n", +- f->inocache->ino, pino); +- +- return d_obtain_alias(jffs2_iget(child->d_sb, pino)); +-} +- +-static const struct export_operations jffs2_export_ops = { +- .get_parent = jffs2_get_parent, +- .fh_to_dentry = jffs2_fh_to_dentry, +- .fh_to_parent = jffs2_fh_to_parent, +-}; +- +-/* +- * JFFS2 mount options. +- * +- * Opt_source: The source device +- * Opt_override_compr: override default compressor +- * Opt_rp_size: size of reserved pool in KiB +- */ +-enum { +- Opt_override_compr, +- Opt_rp_size, +-}; +- +-static const struct constant_table jffs2_param_compr[] = { +- {"none", JFFS2_COMPR_MODE_NONE }, +-#ifdef CONFIG_JFFS2_LZO +- {"lzo", JFFS2_COMPR_MODE_FORCELZO }, +-#endif +-#ifdef CONFIG_JFFS2_ZLIB +- {"zlib", JFFS2_COMPR_MODE_FORCEZLIB }, +-#endif +- {} +-}; ++ struct super_block *sb = NULL; ++ struct jffs2_sb_info *c = NULL; ++ LOS_DL_LIST *part_head = NULL; ++ struct MtdDev *spinor_mtd = NULL; ++ mtd_partition *mtd_part = GetSpinorPartitionHead(); ++ int ret; + +-static const struct fs_parameter_spec jffs2_fs_parameters[] = { +- fsparam_enum ("compr", Opt_override_compr, jffs2_param_compr), +- fsparam_u32 ("rp_size", Opt_rp_size), +- {} +-}; ++ jffs2_dbg(1, "begin los_jffs2_mount:%d\n", part_no); + +-static int jffs2_parse_param(struct fs_context *fc, struct fs_parameter *param) +-{ +- struct fs_parse_result result; +- struct jffs2_sb_info *c = fc->s_fs_info; +- int opt; +- +- opt = fs_parse(fc, jffs2_fs_parameters, param, &result); +- if (opt < 0) +- return opt; +- +- switch (opt) { +- case Opt_override_compr: +- c->mount_opts.compr = result.uint_32; +- c->mount_opts.override_compr = true; +- break; +- case Opt_rp_size: +- if (result.uint_32 > UINT_MAX / 1024) +- return invalf(fc, "jffs2: rp_size unrepresentable"); +- c->mount_opts.rp_size = result.uint_32 * 1024; +- c->mount_opts.set_rp_size = true; +- break; +- default: +- return -EINVAL; ++ sb = zalloc(sizeof(struct super_block)); ++ if (sb == NULL) { ++ return -ENOMEM; + } + +- return 0; +-} +- +-static inline void jffs2_update_mount_opts(struct fs_context *fc) +-{ +- struct jffs2_sb_info *new_c = fc->s_fs_info; +- struct jffs2_sb_info *c = JFFS2_SB_INFO(fc->root->d_sb); +- +- mutex_lock(&c->alloc_sem); +- if (new_c->mount_opts.override_compr) { +- c->mount_opts.override_compr = new_c->mount_opts.override_compr; +- c->mount_opts.compr = new_c->mount_opts.compr; +- } +- if (new_c->mount_opts.set_rp_size) { +- c->mount_opts.set_rp_size = new_c->mount_opts.set_rp_size; +- c->mount_opts.rp_size = new_c->mount_opts.rp_size; ++ ret = Jffs2HashInit(&sb->s_node_hash_lock, &sb->s_node_hash[0]); ++ if (ret) { ++ free(sb); ++ return ret; ++ } ++ part_head = &(GetSpinorPartitionHead()->node_info); ++ LOS_DL_LIST_FOR_EACH_ENTRY(mtd_part,part_head, mtd_partition, node_info) { ++ if (mtd_part->patitionnum == part_no) ++ break; ++ } ++#ifndef LOSCFG_PLATFORM_QEMU_ARM_VIRT_CA7 ++ spinor_mtd = GetMtd("spinor"); ++#else ++ spinor_mtd = (struct MtdDev *)LOS_DL_LIST_ENTRY(part_head->pstNext, mtd_partition, node_info)->mtd_info; ++#endif ++ if (spinor_mtd == NULL) { ++ free(sb); ++ return -EPERM; ++ } ++ jffs2_dev_list[part_no].blockEnd = mtd_part->end_block; ++ jffs2_dev_list[part_no].blockSize = spinor_mtd->eraseSize; ++ jffs2_dev_list[part_no].blockStart = mtd_part->start_block; ++#ifndef LOSCFG_PLATFORM_QEMU_ARM_VIRT_CA7 ++ (void)FreeMtd(spinor_mtd); ++#endif ++ sb->jffs2_sb.mtd = mtd_part->mtd_info; ++ sb->s_dev = &jffs2_dev_list[part_no]; ++ ++ c = JFFS2_SB_INFO(sb); ++ c->flash_size = (mtd_part->end_block - mtd_part->start_block + 1) * spinor_mtd->eraseSize; ++ c->inocache_hashsize = calculate_inocache_hashsize(c->flash_size); ++ c->sector_size = spinor_mtd->eraseSize; ++ ++ jffs2_dbg(1, "C mtd_size:%d,mtd-erase:%d,blocks:%d,hashsize:%d\n", ++ c->flash_size, c->sector_size, c->flash_size / c->sector_size, c->inocache_hashsize); ++ ++ c->inocache_list = zalloc(sizeof(struct jffs2_inode_cache *) * c->inocache_hashsize); ++ if (c->inocache_list == NULL) { ++ free(sb); ++ return -ENOMEM; ++ } ++ if (jffs2_mounted_number++ == 0) { ++ (void)jffs2_create_slab_caches(); // No error check, cannot fail ++ (void)jffs2_compressors_init(); + } +- mutex_unlock(&c->alloc_sem); +-} +- +-static int jffs2_reconfigure(struct fs_context *fc) +-{ +- struct super_block *sb = fc->root->d_sb; +- +- sync_filesystem(sb); +- jffs2_update_mount_opts(fc); +- +- return jffs2_do_remount_fs(sb, fc); +-} +- +-static const struct super_operations jffs2_super_operations = +-{ +- .alloc_inode = jffs2_alloc_inode, +- .free_inode = jffs2_free_inode, +- .put_super = jffs2_put_super, +- .statfs = jffs2_statfs, +- .evict_inode = jffs2_evict_inode, +- .dirty_inode = jffs2_dirty_inode, +- .show_options = jffs2_show_options, +- .sync_fs = jffs2_sync_fs, +-}; +- +-/* +- * fill in the superblock +- */ +-static int jffs2_fill_super(struct super_block *sb, struct fs_context *fc) +-{ +- struct jffs2_sb_info *c = sb->s_fs_info; +- +- jffs2_dbg(1, "jffs2_get_sb_mtd():" +- " New superblock for device %d (\"%s\")\n", +- sb->s_mtd->index, sb->s_mtd->name); +- +- c->mtd = sb->s_mtd; +- c->os_priv = sb; +- +- if (c->mount_opts.rp_size > c->mtd->size) +- return invalf(fc, "jffs2: Too large reserve pool specified, max is %llu KB", +- c->mtd->size / 1024); +- +- /* Initialize JFFS2 superblock locks, the further initialization will +- * be done later */ +- mutex_init(&c->alloc_sem); +- mutex_init(&c->erase_free_sem); +- init_waitqueue_head(&c->erase_wait); +- init_waitqueue_head(&c->inocache_wq); +- spin_lock_init(&c->erase_completion_lock); +- spin_lock_init(&c->inocache_lock); +- +- sb->s_op = &jffs2_super_operations; +- sb->s_export_op = &jffs2_export_ops; +- sb->s_flags = sb->s_flags | SB_NOATIME; +- sb->s_xattr = jffs2_xattr_handlers; +-#ifdef CONFIG_JFFS2_FS_POSIX_ACL +- sb->s_flags |= SB_POSIXACL; +-#endif +- return jffs2_do_fill_super(sb, fc); +-} +- +-static int jffs2_get_tree(struct fs_context *fc) +-{ +- return get_tree_mtd(fc, jffs2_fill_super); +-} +- +-static void jffs2_free_fc(struct fs_context *fc) +-{ +- kfree(fc->s_fs_info); +-} + +-static const struct fs_context_operations jffs2_context_ops = { +- .free = jffs2_free_fc, +- .parse_param = jffs2_parse_param, +- .get_tree = jffs2_get_tree, +- .reconfigure = jffs2_reconfigure, +-}; ++ ret = jffs2_fill_super(sb); ++ if (ret) { ++ if (--jffs2_mounted_number == 0) { ++ jffs2_destroy_slab_caches(); ++ (void)jffs2_compressors_exit(); ++ } + +-static int jffs2_init_fs_context(struct fs_context *fc) +-{ +- struct jffs2_sb_info *ctx; ++ free(sb); ++ free(c->inocache_list); ++ c->inocache_list = NULL; ++ return ret; ++ } + +- ctx = kzalloc(sizeof(struct jffs2_sb_info), GFP_KERNEL); +- if (!ctx) +- return -ENOMEM; ++ if (!(mountflags & MS_RDONLY)) { ++ jffs2_start_garbage_collect_thread(c); ++ } + +- fc->s_fs_info = ctx; +- fc->ops = &jffs2_context_ops; ++ sb->s_mount_flags = mountflags; ++ *root_node = sb->s_root; + return 0; + } + +-static void jffs2_put_super (struct super_block *sb) ++int jffs2_umount(struct jffs2_inode *root_node) + { ++ struct super_block *sb = root_node->i_sb; + struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); ++ struct jffs2_full_dirent *fd, *next; + +- jffs2_dbg(2, "%s()\n", __func__); ++ D2(PRINTK("Jffs2Umount\n")); + +- mutex_lock(&c->alloc_sem); +- jffs2_flush_wbuf_pad(c); +- mutex_unlock(&c->alloc_sem); +- +- jffs2_sum_exit(c); +- +- jffs2_free_ino_caches(c); +- jffs2_free_raw_node_refs(c); +- kvfree(c->blocks); +- jffs2_flash_cleanup(c); +- kfree(c->inocache_list); +- jffs2_clear_xattr_subsystem(c); +- mtd_sync(c->mtd); +- jffs2_dbg(1, "%s(): returning\n", __func__); +-} +- +-static void jffs2_kill_sb(struct super_block *sb) +-{ +- struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); +- if (c && !sb_rdonly(sb)) ++ // Only really umount if this is the only mount ++ if (!(sb->s_mount_flags & MS_RDONLY)) { + jffs2_stop_garbage_collect_thread(c); +- kill_mtd_super(sb); +- kfree(c); +-} +- +-static struct file_system_type jffs2_fs_type = { +- .owner = THIS_MODULE, +- .name = "jffs2", +- .init_fs_context = jffs2_init_fs_context, +- .parameters = jffs2_fs_parameters, +- .kill_sb = jffs2_kill_sb, +-}; +-MODULE_ALIAS_FS("jffs2"); ++ } + +-static int __init init_jffs2_fs(void) +-{ +- int ret; ++ // free directory entries ++ for (fd = root_node->jffs2_i.dents; fd; fd = next) { ++ next = fd->next; ++ jffs2_free_full_dirent(fd); ++ } + +- /* Paranoia checks for on-medium structures. If we ask GCC +- to pack them with __attribute__((packed)) then it _also_ +- assumes that they're not aligned -- so it emits crappy +- code on some architectures. Ideally we want an attribute +- which means just 'no padding', without the alignment +- thing. But GCC doesn't have that -- we have to just +- hope the structs are the right sizes, instead. */ +- BUILD_BUG_ON(sizeof(struct jffs2_unknown_node) != 12); +- BUILD_BUG_ON(sizeof(struct jffs2_raw_dirent) != 40); +- BUILD_BUG_ON(sizeof(struct jffs2_raw_inode) != 68); +- BUILD_BUG_ON(sizeof(struct jffs2_raw_summary) != 32); +- +- pr_info("version 2.2." +-#ifdef CONFIG_JFFS2_FS_WRITEBUFFER +- " (NAND)" +-#endif +-#ifdef CONFIG_JFFS2_SUMMARY +- " (SUMMARY) " +-#endif +- " © 2001-2006 Red Hat, Inc.\n"); ++ free(root_node); + +- jffs2_inode_cachep = kmem_cache_create("jffs2_i", +- sizeof(struct jffs2_inode_info), +- 0, (SLAB_RECLAIM_ACCOUNT| +- SLAB_MEM_SPREAD|SLAB_ACCOUNT), +- jffs2_i_init_once); +- if (!jffs2_inode_cachep) { +- pr_err("error: Failed to initialise inode cache\n"); +- return -ENOMEM; +- } +- ret = jffs2_compressors_init(); +- if (ret) { +- pr_err("error: Failed to initialise compressors\n"); +- goto out; +- } +- ret = jffs2_create_slab_caches(); +- if (ret) { +- pr_err("error: Failed to initialise slab caches\n"); +- goto out_compressors; +- } +- ret = register_filesystem(&jffs2_fs_type); +- if (ret) { +- pr_err("error: Failed to register filesystem\n"); +- goto out_slab; ++ // Clean up the super block and root_node inode ++ jffs2_free_ino_caches(c); ++ jffs2_free_raw_node_refs(c); ++ free(c->blocks); ++ c->blocks = NULL; ++ free(c->inocache_list); ++ c->inocache_list = NULL; ++ (void)Jffs2HashDeinit(&sb->s_node_hash_lock); ++ ++ (void)mutex_destroy(&c->alloc_sem); ++ (void)mutex_destroy(&c->erase_free_sem); ++ free(sb); ++ // That's all folks. ++ D2(PRINTK("Jffs2Umount No current mounts\n")); ++ ++ if (--jffs2_mounted_number == 0) { ++ jffs2_destroy_slab_caches(); ++ (void)jffs2_compressors_exit(); + } + return 0; +- +- out_slab: +- jffs2_destroy_slab_caches(); +- out_compressors: +- jffs2_compressors_exit(); +- out: +- kmem_cache_destroy(jffs2_inode_cachep); +- return ret; + } +- +-static void __exit exit_jffs2_fs(void) +-{ +- unregister_filesystem(&jffs2_fs_type); +- jffs2_destroy_slab_caches(); +- jffs2_compressors_exit(); +- +- /* +- * Make sure all delayed rcu free inodes are flushed before we +- * destroy cache. +- */ +- rcu_barrier(); +- kmem_cache_destroy(jffs2_inode_cachep); +-} +- +-module_init(init_jffs2_fs); +-module_exit(exit_jffs2_fs); +- +-MODULE_DESCRIPTION("The Journalling Flash File System, v2"); +-MODULE_AUTHOR("Red Hat, Inc."); +-MODULE_LICENSE("GPL"); // Actually dual-licensed, but it doesn't matter for +- // the sake of this tag. It's Free Software. +diff -Nupr old/fs/jffs2/symlink.c new/fs/jffs2/symlink.c +--- old/fs/jffs2/symlink.c 2022-05-09 17:15:24.350000000 +0800 ++++ new/fs/jffs2/symlink.c 1970-01-01 08:00:00.000000000 +0800 +@@ -1,19 +0,0 @@ +-/* +- * JFFS2 -- Journalling Flash File System, Version 2. +- * +- * Copyright © 2001-2007 Red Hat, Inc. +- * +- * Created by David Woodhouse +- * +- * For licensing information, see the file 'LICENCE' in this directory. +- * +- */ +- +-#include "nodelist.h" +- +-const struct inode_operations jffs2_symlink_inode_operations = +-{ +- .get_link = simple_get_link, +- .setattr = jffs2_setattr, +- .listxattr = jffs2_listxattr, +-}; +diff -Nupr old/fs/jffs2/wbuf.c new/fs/jffs2/wbuf.c +--- old/fs/jffs2/wbuf.c 2022-05-09 17:15:24.350000000 +0800 ++++ new/fs/jffs2/wbuf.c 1970-01-01 08:00:00.000000000 +0800 +@@ -1,1350 +0,0 @@ +-/* +- * JFFS2 -- Journalling Flash File System, Version 2. +- * +- * Copyright © 2001-2007 Red Hat, Inc. +- * Copyright © 2004 Thomas Gleixner +- * +- * Created by David Woodhouse +- * Modified debugged and enhanced by Thomas Gleixner +- * +- * For licensing information, see the file 'LICENCE' in this directory. +- * +- */ +- +-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include "nodelist.h" +- +-/* For testing write failures */ +-#undef BREAKME +-#undef BREAKMEHEADER +- +-#ifdef BREAKME +-static unsigned char *brokenbuf; +-#endif +- +-#define PAGE_DIV(x) ( ((unsigned long)(x) / (unsigned long)(c->wbuf_pagesize)) * (unsigned long)(c->wbuf_pagesize) ) +-#define PAGE_MOD(x) ( (unsigned long)(x) % (unsigned long)(c->wbuf_pagesize) ) +- +-/* max. erase failures before we mark a block bad */ +-#define MAX_ERASE_FAILURES 2 +- +-struct jffs2_inodirty { +- uint32_t ino; +- struct jffs2_inodirty *next; +-}; +- +-static struct jffs2_inodirty inodirty_nomem; +- +-static int jffs2_wbuf_pending_for_ino(struct jffs2_sb_info *c, uint32_t ino) +-{ +- struct jffs2_inodirty *this = c->wbuf_inodes; +- +- /* If a malloc failed, consider _everything_ dirty */ +- if (this == &inodirty_nomem) +- return 1; +- +- /* If ino == 0, _any_ non-GC writes mean 'yes' */ +- if (this && !ino) +- return 1; +- +- /* Look to see if the inode in question is pending in the wbuf */ +- while (this) { +- if (this->ino == ino) +- return 1; +- this = this->next; +- } +- return 0; +-} +- +-static void jffs2_clear_wbuf_ino_list(struct jffs2_sb_info *c) +-{ +- struct jffs2_inodirty *this; +- +- this = c->wbuf_inodes; +- +- if (this != &inodirty_nomem) { +- while (this) { +- struct jffs2_inodirty *next = this->next; +- kfree(this); +- this = next; +- } +- } +- c->wbuf_inodes = NULL; +-} +- +-static void jffs2_wbuf_dirties_inode(struct jffs2_sb_info *c, uint32_t ino) +-{ +- struct jffs2_inodirty *new; +- +- /* Schedule delayed write-buffer write-out */ +- jffs2_dirty_trigger(c); +- +- if (jffs2_wbuf_pending_for_ino(c, ino)) +- return; +- +- new = kmalloc(sizeof(*new), GFP_KERNEL); +- if (!new) { +- jffs2_dbg(1, "No memory to allocate inodirty. Fallback to all considered dirty\n"); +- jffs2_clear_wbuf_ino_list(c); +- c->wbuf_inodes = &inodirty_nomem; +- return; +- } +- new->ino = ino; +- new->next = c->wbuf_inodes; +- c->wbuf_inodes = new; +- return; +-} +- +-static inline void jffs2_refile_wbuf_blocks(struct jffs2_sb_info *c) +-{ +- struct list_head *this, *next; +- static int n; +- +- if (list_empty(&c->erasable_pending_wbuf_list)) +- return; +- +- list_for_each_safe(this, next, &c->erasable_pending_wbuf_list) { +- struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); +- +- jffs2_dbg(1, "Removing eraseblock at 0x%08x from erasable_pending_wbuf_list...\n", +- jeb->offset); +- list_del(this); +- if ((jiffies + (n++)) & 127) { +- /* Most of the time, we just erase it immediately. Otherwise we +- spend ages scanning it on mount, etc. */ +- jffs2_dbg(1, "...and adding to erase_pending_list\n"); +- list_add_tail(&jeb->list, &c->erase_pending_list); +- c->nr_erasing_blocks++; +- jffs2_garbage_collect_trigger(c); +- } else { +- /* Sometimes, however, we leave it elsewhere so it doesn't get +- immediately reused, and we spread the load a bit. */ +- jffs2_dbg(1, "...and adding to erasable_list\n"); +- list_add_tail(&jeb->list, &c->erasable_list); +- } +- } +-} +- +-#define REFILE_NOTEMPTY 0 +-#define REFILE_ANYWAY 1 +- +-static void jffs2_block_refile(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, int allow_empty) +-{ +- jffs2_dbg(1, "About to refile bad block at %08x\n", jeb->offset); +- +- /* File the existing block on the bad_used_list.... */ +- if (c->nextblock == jeb) +- c->nextblock = NULL; +- else /* Not sure this should ever happen... need more coffee */ +- list_del(&jeb->list); +- if (jeb->first_node) { +- jffs2_dbg(1, "Refiling block at %08x to bad_used_list\n", +- jeb->offset); +- list_add(&jeb->list, &c->bad_used_list); +- } else { +- BUG_ON(allow_empty == REFILE_NOTEMPTY); +- /* It has to have had some nodes or we couldn't be here */ +- jffs2_dbg(1, "Refiling block at %08x to erase_pending_list\n", +- jeb->offset); +- list_add(&jeb->list, &c->erase_pending_list); +- c->nr_erasing_blocks++; +- jffs2_garbage_collect_trigger(c); +- } +- +- if (!jffs2_prealloc_raw_node_refs(c, jeb, 1)) { +- uint32_t oldfree = jeb->free_size; +- +- jffs2_link_node_ref(c, jeb, +- (jeb->offset+c->sector_size-oldfree) | REF_OBSOLETE, +- oldfree, NULL); +- /* convert to wasted */ +- c->wasted_size += oldfree; +- jeb->wasted_size += oldfree; +- c->dirty_size -= oldfree; +- jeb->dirty_size -= oldfree; +- } +- +- jffs2_dbg_dump_block_lists_nolock(c); +- jffs2_dbg_acct_sanity_check_nolock(c,jeb); +- jffs2_dbg_acct_paranoia_check_nolock(c, jeb); +-} +- +-static struct jffs2_raw_node_ref **jffs2_incore_replace_raw(struct jffs2_sb_info *c, +- struct jffs2_inode_info *f, +- struct jffs2_raw_node_ref *raw, +- union jffs2_node_union *node) +-{ +- struct jffs2_node_frag *frag; +- struct jffs2_full_dirent *fd; +- +- dbg_noderef("incore_replace_raw: node at %p is {%04x,%04x}\n", +- node, je16_to_cpu(node->u.magic), je16_to_cpu(node->u.nodetype)); +- +- BUG_ON(je16_to_cpu(node->u.magic) != 0x1985 && +- je16_to_cpu(node->u.magic) != 0); +- +- switch (je16_to_cpu(node->u.nodetype)) { +- case JFFS2_NODETYPE_INODE: +- if (f->metadata && f->metadata->raw == raw) { +- dbg_noderef("Will replace ->raw in f->metadata at %p\n", f->metadata); +- return &f->metadata->raw; +- } +- frag = jffs2_lookup_node_frag(&f->fragtree, je32_to_cpu(node->i.offset)); +- BUG_ON(!frag); +- /* Find a frag which refers to the full_dnode we want to modify */ +- while (!frag->node || frag->node->raw != raw) { +- frag = frag_next(frag); +- BUG_ON(!frag); +- } +- dbg_noderef("Will replace ->raw in full_dnode at %p\n", frag->node); +- return &frag->node->raw; +- +- case JFFS2_NODETYPE_DIRENT: +- for (fd = f->dents; fd; fd = fd->next) { +- if (fd->raw == raw) { +- dbg_noderef("Will replace ->raw in full_dirent at %p\n", fd); +- return &fd->raw; +- } +- } +- BUG(); +- +- default: +- dbg_noderef("Don't care about replacing raw for nodetype %x\n", +- je16_to_cpu(node->u.nodetype)); +- break; +- } +- return NULL; +-} +- +-#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY +-static int jffs2_verify_write(struct jffs2_sb_info *c, unsigned char *buf, +- uint32_t ofs) +-{ +- int ret; +- size_t retlen; +- char *eccstr; +- +- ret = mtd_read(c->mtd, ofs, c->wbuf_pagesize, &retlen, c->wbuf_verify); +- if (ret && ret != -EUCLEAN && ret != -EBADMSG) { +- pr_warn("%s(): Read back of page at %08x failed: %d\n", +- __func__, c->wbuf_ofs, ret); +- return ret; +- } else if (retlen != c->wbuf_pagesize) { +- pr_warn("%s(): Read back of page at %08x gave short read: %zd not %d\n", +- __func__, ofs, retlen, c->wbuf_pagesize); +- return -EIO; +- } +- if (!memcmp(buf, c->wbuf_verify, c->wbuf_pagesize)) +- return 0; +- +- if (ret == -EUCLEAN) +- eccstr = "corrected"; +- else if (ret == -EBADMSG) +- eccstr = "correction failed"; +- else +- eccstr = "OK or unused"; +- +- pr_warn("Write verify error (ECC %s) at %08x. Wrote:\n", +- eccstr, c->wbuf_ofs); +- print_hex_dump(KERN_WARNING, "", DUMP_PREFIX_OFFSET, 16, 1, +- c->wbuf, c->wbuf_pagesize, 0); +- +- pr_warn("Read back:\n"); +- print_hex_dump(KERN_WARNING, "", DUMP_PREFIX_OFFSET, 16, 1, +- c->wbuf_verify, c->wbuf_pagesize, 0); +- +- return -EIO; +-} +-#else +-#define jffs2_verify_write(c,b,o) (0) +-#endif +- +-/* Recover from failure to write wbuf. Recover the nodes up to the +- * wbuf, not the one which we were starting to try to write. */ +- +-static void jffs2_wbuf_recover(struct jffs2_sb_info *c) +-{ +- struct jffs2_eraseblock *jeb, *new_jeb; +- struct jffs2_raw_node_ref *raw, *next, *first_raw = NULL; +- size_t retlen; +- int ret; +- int nr_refile = 0; +- unsigned char *buf; +- uint32_t start, end, ofs, len; +- +- jeb = &c->blocks[c->wbuf_ofs / c->sector_size]; +- +- spin_lock(&c->erase_completion_lock); +- if (c->wbuf_ofs % c->mtd->erasesize) +- jffs2_block_refile(c, jeb, REFILE_NOTEMPTY); +- else +- jffs2_block_refile(c, jeb, REFILE_ANYWAY); +- spin_unlock(&c->erase_completion_lock); +- +- BUG_ON(!ref_obsolete(jeb->last_node)); +- +- /* Find the first node to be recovered, by skipping over every +- node which ends before the wbuf starts, or which is obsolete. */ +- for (next = raw = jeb->first_node; next; raw = next) { +- next = ref_next(raw); +- +- if (ref_obsolete(raw) || +- (next && ref_offset(next) <= c->wbuf_ofs)) { +- dbg_noderef("Skipping node at 0x%08x(%d)-0x%08x which is either before 0x%08x or obsolete\n", +- ref_offset(raw), ref_flags(raw), +- (ref_offset(raw) + ref_totlen(c, jeb, raw)), +- c->wbuf_ofs); +- continue; +- } +- dbg_noderef("First node to be recovered is at 0x%08x(%d)-0x%08x\n", +- ref_offset(raw), ref_flags(raw), +- (ref_offset(raw) + ref_totlen(c, jeb, raw))); +- +- first_raw = raw; +- break; +- } +- +- if (!first_raw) { +- /* All nodes were obsolete. Nothing to recover. */ +- jffs2_dbg(1, "No non-obsolete nodes to be recovered. Just filing block bad\n"); +- c->wbuf_len = 0; +- return; +- } +- +- start = ref_offset(first_raw); +- end = ref_offset(jeb->last_node); +- nr_refile = 1; +- +- /* Count the number of refs which need to be copied */ +- while ((raw = ref_next(raw)) != jeb->last_node) +- nr_refile++; +- +- dbg_noderef("wbuf recover %08x-%08x (%d bytes in %d nodes)\n", +- start, end, end - start, nr_refile); +- +- buf = NULL; +- if (start < c->wbuf_ofs) { +- /* First affected node was already partially written. +- * Attempt to reread the old data into our buffer. */ +- +- buf = kmalloc(end - start, GFP_KERNEL); +- if (!buf) { +- pr_crit("Malloc failure in wbuf recovery. Data loss ensues.\n"); +- +- goto read_failed; +- } +- +- /* Do the read... */ +- ret = mtd_read(c->mtd, start, c->wbuf_ofs - start, &retlen, +- buf); +- +- /* ECC recovered ? */ +- if ((ret == -EUCLEAN || ret == -EBADMSG) && +- (retlen == c->wbuf_ofs - start)) +- ret = 0; +- +- if (ret || retlen != c->wbuf_ofs - start) { +- pr_crit("Old data are already lost in wbuf recovery. Data loss ensues.\n"); +- +- kfree(buf); +- buf = NULL; +- read_failed: +- first_raw = ref_next(first_raw); +- nr_refile--; +- while (first_raw && ref_obsolete(first_raw)) { +- first_raw = ref_next(first_raw); +- nr_refile--; +- } +- +- /* If this was the only node to be recovered, give up */ +- if (!first_raw) { +- c->wbuf_len = 0; +- return; +- } +- +- /* It wasn't. Go on and try to recover nodes complete in the wbuf */ +- start = ref_offset(first_raw); +- dbg_noderef("wbuf now recover %08x-%08x (%d bytes in %d nodes)\n", +- start, end, end - start, nr_refile); +- +- } else { +- /* Read succeeded. Copy the remaining data from the wbuf */ +- memcpy(buf + (c->wbuf_ofs - start), c->wbuf, end - c->wbuf_ofs); +- } +- } +- /* OK... we're to rewrite (end-start) bytes of data from first_raw onwards. +- Either 'buf' contains the data, or we find it in the wbuf */ +- +- /* ... and get an allocation of space from a shiny new block instead */ +- ret = jffs2_reserve_space_gc(c, end-start, &len, JFFS2_SUMMARY_NOSUM_SIZE); +- if (ret) { +- pr_warn("Failed to allocate space for wbuf recovery. Data loss ensues.\n"); +- kfree(buf); +- return; +- } +- +- /* The summary is not recovered, so it must be disabled for this erase block */ +- jffs2_sum_disable_collecting(c->summary); +- +- ret = jffs2_prealloc_raw_node_refs(c, c->nextblock, nr_refile); +- if (ret) { +- pr_warn("Failed to allocate node refs for wbuf recovery. Data loss ensues.\n"); +- kfree(buf); +- return; +- } +- +- ofs = write_ofs(c); +- +- if (end-start >= c->wbuf_pagesize) { +- /* Need to do another write immediately, but it's possible +- that this is just because the wbuf itself is completely +- full, and there's nothing earlier read back from the +- flash. Hence 'buf' isn't necessarily what we're writing +- from. */ +- unsigned char *rewrite_buf = buf?:c->wbuf; +- uint32_t towrite = (end-start) - ((end-start)%c->wbuf_pagesize); +- +- jffs2_dbg(1, "Write 0x%x bytes at 0x%08x in wbuf recover\n", +- towrite, ofs); +- +-#ifdef BREAKMEHEADER +- static int breakme; +- if (breakme++ == 20) { +- pr_notice("Faking write error at 0x%08x\n", ofs); +- breakme = 0; +- mtd_write(c->mtd, ofs, towrite, &retlen, brokenbuf); +- ret = -EIO; +- } else +-#endif +- ret = mtd_write(c->mtd, ofs, towrite, &retlen, +- rewrite_buf); +- +- if (ret || retlen != towrite || jffs2_verify_write(c, rewrite_buf, ofs)) { +- /* Argh. We tried. Really we did. */ +- pr_crit("Recovery of wbuf failed due to a second write error\n"); +- kfree(buf); +- +- if (retlen) +- jffs2_add_physical_node_ref(c, ofs | REF_OBSOLETE, ref_totlen(c, jeb, first_raw), NULL); +- +- return; +- } +- pr_notice("Recovery of wbuf succeeded to %08x\n", ofs); +- +- c->wbuf_len = (end - start) - towrite; +- c->wbuf_ofs = ofs + towrite; +- memmove(c->wbuf, rewrite_buf + towrite, c->wbuf_len); +- /* Don't muck about with c->wbuf_inodes. False positives are harmless. */ +- } else { +- /* OK, now we're left with the dregs in whichever buffer we're using */ +- if (buf) { +- memcpy(c->wbuf, buf, end-start); +- } else { +- memmove(c->wbuf, c->wbuf + (start - c->wbuf_ofs), end - start); +- } +- c->wbuf_ofs = ofs; +- c->wbuf_len = end - start; +- } +- +- /* Now sort out the jffs2_raw_node_refs, moving them from the old to the next block */ +- new_jeb = &c->blocks[ofs / c->sector_size]; +- +- spin_lock(&c->erase_completion_lock); +- for (raw = first_raw; raw != jeb->last_node; raw = ref_next(raw)) { +- uint32_t rawlen = ref_totlen(c, jeb, raw); +- struct jffs2_inode_cache *ic; +- struct jffs2_raw_node_ref *new_ref; +- struct jffs2_raw_node_ref **adjust_ref = NULL; +- struct jffs2_inode_info *f = NULL; +- +- jffs2_dbg(1, "Refiling block of %08x at %08x(%d) to %08x\n", +- rawlen, ref_offset(raw), ref_flags(raw), ofs); +- +- ic = jffs2_raw_ref_to_ic(raw); +- +- /* Ick. This XATTR mess should be fixed shortly... */ +- if (ic && ic->class == RAWNODE_CLASS_XATTR_DATUM) { +- struct jffs2_xattr_datum *xd = (void *)ic; +- BUG_ON(xd->node != raw); +- adjust_ref = &xd->node; +- raw->next_in_ino = NULL; +- ic = NULL; +- } else if (ic && ic->class == RAWNODE_CLASS_XATTR_REF) { +- struct jffs2_xattr_datum *xr = (void *)ic; +- BUG_ON(xr->node != raw); +- adjust_ref = &xr->node; +- raw->next_in_ino = NULL; +- ic = NULL; +- } else if (ic && ic->class == RAWNODE_CLASS_INODE_CACHE) { +- struct jffs2_raw_node_ref **p = &ic->nodes; +- +- /* Remove the old node from the per-inode list */ +- while (*p && *p != (void *)ic) { +- if (*p == raw) { +- (*p) = (raw->next_in_ino); +- raw->next_in_ino = NULL; +- break; +- } +- p = &((*p)->next_in_ino); +- } +- +- if (ic->state == INO_STATE_PRESENT && !ref_obsolete(raw)) { +- /* If it's an in-core inode, then we have to adjust any +- full_dirent or full_dnode structure to point to the +- new version instead of the old */ +- f = jffs2_gc_fetch_inode(c, ic->ino, !ic->pino_nlink); +- if (IS_ERR(f)) { +- /* Should never happen; it _must_ be present */ +- JFFS2_ERROR("Failed to iget() ino #%u, err %ld\n", +- ic->ino, PTR_ERR(f)); +- BUG(); +- } +- /* We don't lock f->sem. There's a number of ways we could +- end up in here with it already being locked, and nobody's +- going to modify it on us anyway because we hold the +- alloc_sem. We're only changing one ->raw pointer too, +- which we can get away with without upsetting readers. */ +- adjust_ref = jffs2_incore_replace_raw(c, f, raw, +- (void *)(buf?:c->wbuf) + (ref_offset(raw) - start)); +- } else if (unlikely(ic->state != INO_STATE_PRESENT && +- ic->state != INO_STATE_CHECKEDABSENT && +- ic->state != INO_STATE_GC)) { +- JFFS2_ERROR("Inode #%u is in strange state %d!\n", ic->ino, ic->state); +- BUG(); +- } +- } +- +- new_ref = jffs2_link_node_ref(c, new_jeb, ofs | ref_flags(raw), rawlen, ic); +- +- if (adjust_ref) { +- BUG_ON(*adjust_ref != raw); +- *adjust_ref = new_ref; +- } +- if (f) +- jffs2_gc_release_inode(c, f); +- +- if (!ref_obsolete(raw)) { +- jeb->dirty_size += rawlen; +- jeb->used_size -= rawlen; +- c->dirty_size += rawlen; +- c->used_size -= rawlen; +- raw->flash_offset = ref_offset(raw) | REF_OBSOLETE; +- BUG_ON(raw->next_in_ino); +- } +- ofs += rawlen; +- } +- +- kfree(buf); +- +- /* Fix up the original jeb now it's on the bad_list */ +- if (first_raw == jeb->first_node) { +- jffs2_dbg(1, "Failing block at %08x is now empty. Moving to erase_pending_list\n", +- jeb->offset); +- list_move(&jeb->list, &c->erase_pending_list); +- c->nr_erasing_blocks++; +- jffs2_garbage_collect_trigger(c); +- } +- +- jffs2_dbg_acct_sanity_check_nolock(c, jeb); +- jffs2_dbg_acct_paranoia_check_nolock(c, jeb); +- +- jffs2_dbg_acct_sanity_check_nolock(c, new_jeb); +- jffs2_dbg_acct_paranoia_check_nolock(c, new_jeb); +- +- spin_unlock(&c->erase_completion_lock); +- +- jffs2_dbg(1, "wbuf recovery completed OK. wbuf_ofs 0x%08x, len 0x%x\n", +- c->wbuf_ofs, c->wbuf_len); +- +-} +- +-/* Meaning of pad argument: +- 0: Do not pad. Probably pointless - we only ever use this when we can't pad anyway. +- 1: Pad, do not adjust nextblock free_size +- 2: Pad, adjust nextblock free_size +-*/ +-#define NOPAD 0 +-#define PAD_NOACCOUNT 1 +-#define PAD_ACCOUNTING 2 +- +-static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad) +-{ +- struct jffs2_eraseblock *wbuf_jeb; +- int ret; +- size_t retlen; +- +- /* Nothing to do if not write-buffering the flash. In particular, we shouldn't +- del_timer() the timer we never initialised. */ +- if (!jffs2_is_writebuffered(c)) +- return 0; +- +- if (!mutex_is_locked(&c->alloc_sem)) { +- pr_crit("jffs2_flush_wbuf() called with alloc_sem not locked!\n"); +- BUG(); +- } +- +- if (!c->wbuf_len) /* already checked c->wbuf above */ +- return 0; +- +- wbuf_jeb = &c->blocks[c->wbuf_ofs / c->sector_size]; +- if (jffs2_prealloc_raw_node_refs(c, wbuf_jeb, c->nextblock->allocated_refs + 1)) +- return -ENOMEM; +- +- /* claim remaining space on the page +- this happens, if we have a change to a new block, +- or if fsync forces us to flush the writebuffer. +- if we have a switch to next page, we will not have +- enough remaining space for this. +- */ +- if (pad ) { +- c->wbuf_len = PAD(c->wbuf_len); +- +- /* Pad with JFFS2_DIRTY_BITMASK initially. this helps out ECC'd NOR +- with 8 byte page size */ +- memset(c->wbuf + c->wbuf_len, 0, c->wbuf_pagesize - c->wbuf_len); +- +- if ( c->wbuf_len + sizeof(struct jffs2_unknown_node) < c->wbuf_pagesize) { +- struct jffs2_unknown_node *padnode = (void *)(c->wbuf + c->wbuf_len); +- padnode->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); +- padnode->nodetype = cpu_to_je16(JFFS2_NODETYPE_PADDING); +- padnode->totlen = cpu_to_je32(c->wbuf_pagesize - c->wbuf_len); +- padnode->hdr_crc = cpu_to_je32(crc32(0, padnode, sizeof(*padnode)-4)); +- } +- } +- /* else jffs2_flash_writev has actually filled in the rest of the +- buffer for us, and will deal with the node refs etc. later. */ +- +-#ifdef BREAKME +- static int breakme; +- if (breakme++ == 20) { +- pr_notice("Faking write error at 0x%08x\n", c->wbuf_ofs); +- breakme = 0; +- mtd_write(c->mtd, c->wbuf_ofs, c->wbuf_pagesize, &retlen, +- brokenbuf); +- ret = -EIO; +- } else +-#endif +- +- ret = mtd_write(c->mtd, c->wbuf_ofs, c->wbuf_pagesize, +- &retlen, c->wbuf); +- +- if (ret) { +- pr_warn("jffs2_flush_wbuf(): Write failed with %d\n", ret); +- goto wfail; +- } else if (retlen != c->wbuf_pagesize) { +- pr_warn("jffs2_flush_wbuf(): Write was short: %zd instead of %d\n", +- retlen, c->wbuf_pagesize); +- ret = -EIO; +- goto wfail; +- } else if ((ret = jffs2_verify_write(c, c->wbuf, c->wbuf_ofs))) { +- wfail: +- jffs2_wbuf_recover(c); +- +- return ret; +- } +- +- /* Adjust free size of the block if we padded. */ +- if (pad) { +- uint32_t waste = c->wbuf_pagesize - c->wbuf_len; +- +- jffs2_dbg(1, "jffs2_flush_wbuf() adjusting free_size of %sblock at %08x\n", +- (wbuf_jeb == c->nextblock) ? "next" : "", +- wbuf_jeb->offset); +- +- /* wbuf_pagesize - wbuf_len is the amount of space that's to be +- padded. If there is less free space in the block than that, +- something screwed up */ +- if (wbuf_jeb->free_size < waste) { +- pr_crit("jffs2_flush_wbuf(): Accounting error. wbuf at 0x%08x has 0x%03x bytes, 0x%03x left.\n", +- c->wbuf_ofs, c->wbuf_len, waste); +- pr_crit("jffs2_flush_wbuf(): But free_size for block at 0x%08x is only 0x%08x\n", +- wbuf_jeb->offset, wbuf_jeb->free_size); +- BUG(); +- } +- +- spin_lock(&c->erase_completion_lock); +- +- jffs2_link_node_ref(c, wbuf_jeb, (c->wbuf_ofs + c->wbuf_len) | REF_OBSOLETE, waste, NULL); +- /* FIXME: that made it count as dirty. Convert to wasted */ +- wbuf_jeb->dirty_size -= waste; +- c->dirty_size -= waste; +- wbuf_jeb->wasted_size += waste; +- c->wasted_size += waste; +- } else +- spin_lock(&c->erase_completion_lock); +- +- /* Stick any now-obsoleted blocks on the erase_pending_list */ +- jffs2_refile_wbuf_blocks(c); +- jffs2_clear_wbuf_ino_list(c); +- spin_unlock(&c->erase_completion_lock); +- +- memset(c->wbuf,0xff,c->wbuf_pagesize); +- /* adjust write buffer offset, else we get a non contiguous write bug */ +- c->wbuf_ofs += c->wbuf_pagesize; +- c->wbuf_len = 0; +- return 0; +-} +- +-/* Trigger garbage collection to flush the write-buffer. +- If ino arg is zero, do it if _any_ real (i.e. not GC) writes are +- outstanding. If ino arg non-zero, do it only if a write for the +- given inode is outstanding. */ +-int jffs2_flush_wbuf_gc(struct jffs2_sb_info *c, uint32_t ino) +-{ +- uint32_t old_wbuf_ofs; +- uint32_t old_wbuf_len; +- int ret = 0; +- +- jffs2_dbg(1, "jffs2_flush_wbuf_gc() called for ino #%u...\n", ino); +- +- if (!c->wbuf) +- return 0; +- +- mutex_lock(&c->alloc_sem); +- if (!jffs2_wbuf_pending_for_ino(c, ino)) { +- jffs2_dbg(1, "Ino #%d not pending in wbuf. Returning\n", ino); +- mutex_unlock(&c->alloc_sem); +- return 0; +- } +- +- old_wbuf_ofs = c->wbuf_ofs; +- old_wbuf_len = c->wbuf_len; +- +- if (c->unchecked_size) { +- /* GC won't make any progress for a while */ +- jffs2_dbg(1, "%s(): padding. Not finished checking\n", +- __func__); +- down_write(&c->wbuf_sem); +- ret = __jffs2_flush_wbuf(c, PAD_ACCOUNTING); +- /* retry flushing wbuf in case jffs2_wbuf_recover +- left some data in the wbuf */ +- if (ret) +- ret = __jffs2_flush_wbuf(c, PAD_ACCOUNTING); +- up_write(&c->wbuf_sem); +- } else while (old_wbuf_len && +- old_wbuf_ofs == c->wbuf_ofs) { +- +- mutex_unlock(&c->alloc_sem); +- +- jffs2_dbg(1, "%s(): calls gc pass\n", __func__); +- +- ret = jffs2_garbage_collect_pass(c); +- if (ret) { +- /* GC failed. Flush it with padding instead */ +- mutex_lock(&c->alloc_sem); +- down_write(&c->wbuf_sem); +- ret = __jffs2_flush_wbuf(c, PAD_ACCOUNTING); +- /* retry flushing wbuf in case jffs2_wbuf_recover +- left some data in the wbuf */ +- if (ret) +- ret = __jffs2_flush_wbuf(c, PAD_ACCOUNTING); +- up_write(&c->wbuf_sem); +- break; +- } +- mutex_lock(&c->alloc_sem); +- } +- +- jffs2_dbg(1, "%s(): ends...\n", __func__); +- +- mutex_unlock(&c->alloc_sem); +- return ret; +-} +- +-/* Pad write-buffer to end and write it, wasting space. */ +-int jffs2_flush_wbuf_pad(struct jffs2_sb_info *c) +-{ +- int ret; +- +- if (!c->wbuf) +- return 0; +- +- down_write(&c->wbuf_sem); +- ret = __jffs2_flush_wbuf(c, PAD_NOACCOUNT); +- /* retry - maybe wbuf recover left some data in wbuf. */ +- if (ret) +- ret = __jffs2_flush_wbuf(c, PAD_NOACCOUNT); +- up_write(&c->wbuf_sem); +- +- return ret; +-} +- +-static size_t jffs2_fill_wbuf(struct jffs2_sb_info *c, const uint8_t *buf, +- size_t len) +-{ +- if (len && !c->wbuf_len && (len >= c->wbuf_pagesize)) +- return 0; +- +- if (len > (c->wbuf_pagesize - c->wbuf_len)) +- len = c->wbuf_pagesize - c->wbuf_len; +- memcpy(c->wbuf + c->wbuf_len, buf, len); +- c->wbuf_len += (uint32_t) len; +- return len; +-} +- +-int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, +- unsigned long count, loff_t to, size_t *retlen, +- uint32_t ino) +-{ +- struct jffs2_eraseblock *jeb; +- size_t wbuf_retlen, donelen = 0; +- uint32_t outvec_to = to; +- int ret, invec; +- +- /* If not writebuffered flash, don't bother */ +- if (!jffs2_is_writebuffered(c)) +- return jffs2_flash_direct_writev(c, invecs, count, to, retlen); +- +- down_write(&c->wbuf_sem); +- +- /* If wbuf_ofs is not initialized, set it to target address */ +- if (c->wbuf_ofs == 0xFFFFFFFF) { +- c->wbuf_ofs = PAGE_DIV(to); +- c->wbuf_len = PAGE_MOD(to); +- memset(c->wbuf,0xff,c->wbuf_pagesize); +- } +- +- /* +- * Sanity checks on target address. It's permitted to write +- * at PAD(c->wbuf_len+c->wbuf_ofs), and it's permitted to +- * write at the beginning of a new erase block. Anything else, +- * and you die. New block starts at xxx000c (0-b = block +- * header) +- */ +- if (SECTOR_ADDR(to) != SECTOR_ADDR(c->wbuf_ofs)) { +- /* It's a write to a new block */ +- if (c->wbuf_len) { +- jffs2_dbg(1, "%s(): to 0x%lx causes flush of wbuf at 0x%08x\n", +- __func__, (unsigned long)to, c->wbuf_ofs); +- ret = __jffs2_flush_wbuf(c, PAD_NOACCOUNT); +- if (ret) +- goto outerr; +- } +- /* set pointer to new block */ +- c->wbuf_ofs = PAGE_DIV(to); +- c->wbuf_len = PAGE_MOD(to); +- } +- +- if (to != PAD(c->wbuf_ofs + c->wbuf_len)) { +- /* We're not writing immediately after the writebuffer. Bad. */ +- pr_crit("%s(): Non-contiguous write to %08lx\n", +- __func__, (unsigned long)to); +- if (c->wbuf_len) +- pr_crit("wbuf was previously %08x-%08x\n", +- c->wbuf_ofs, c->wbuf_ofs + c->wbuf_len); +- BUG(); +- } +- +- /* adjust alignment offset */ +- if (c->wbuf_len != PAGE_MOD(to)) { +- c->wbuf_len = PAGE_MOD(to); +- /* take care of alignment to next page */ +- if (!c->wbuf_len) { +- c->wbuf_len = c->wbuf_pagesize; +- ret = __jffs2_flush_wbuf(c, NOPAD); +- if (ret) +- goto outerr; +- } +- } +- +- for (invec = 0; invec < count; invec++) { +- int vlen = invecs[invec].iov_len; +- uint8_t *v = invecs[invec].iov_base; +- +- wbuf_retlen = jffs2_fill_wbuf(c, v, vlen); +- +- if (c->wbuf_len == c->wbuf_pagesize) { +- ret = __jffs2_flush_wbuf(c, NOPAD); +- if (ret) +- goto outerr; +- } +- vlen -= wbuf_retlen; +- outvec_to += wbuf_retlen; +- donelen += wbuf_retlen; +- v += wbuf_retlen; +- +- if (vlen >= c->wbuf_pagesize) { +- ret = mtd_write(c->mtd, outvec_to, PAGE_DIV(vlen), +- &wbuf_retlen, v); +- if (ret < 0 || wbuf_retlen != PAGE_DIV(vlen)) +- goto outfile; +- +- vlen -= wbuf_retlen; +- outvec_to += wbuf_retlen; +- c->wbuf_ofs = outvec_to; +- donelen += wbuf_retlen; +- v += wbuf_retlen; +- } +- +- wbuf_retlen = jffs2_fill_wbuf(c, v, vlen); +- if (c->wbuf_len == c->wbuf_pagesize) { +- ret = __jffs2_flush_wbuf(c, NOPAD); +- if (ret) +- goto outerr; +- } +- +- outvec_to += wbuf_retlen; +- donelen += wbuf_retlen; +- } +- +- /* +- * If there's a remainder in the wbuf and it's a non-GC write, +- * remember that the wbuf affects this ino +- */ +- *retlen = donelen; +- +- if (jffs2_sum_active()) { +- int res = jffs2_sum_add_kvec(c, invecs, count, (uint32_t) to); +- if (res) +- return res; +- } +- +- if (c->wbuf_len && ino) +- jffs2_wbuf_dirties_inode(c, ino); +- +- ret = 0; +- up_write(&c->wbuf_sem); +- return ret; +- +-outfile: +- /* +- * At this point we have no problem, c->wbuf is empty. However +- * refile nextblock to avoid writing again to same address. +- */ +- +- spin_lock(&c->erase_completion_lock); +- +- jeb = &c->blocks[outvec_to / c->sector_size]; +- jffs2_block_refile(c, jeb, REFILE_ANYWAY); +- +- spin_unlock(&c->erase_completion_lock); +- +-outerr: +- *retlen = 0; +- up_write(&c->wbuf_sem); +- return ret; +-} +- +-/* +- * This is the entry for flash write. +- * Check, if we work on NAND FLASH, if so build an kvec and write it via vritev +-*/ +-int jffs2_flash_write(struct jffs2_sb_info *c, loff_t ofs, size_t len, +- size_t *retlen, const u_char *buf) +-{ +- struct kvec vecs[1]; +- +- if (!jffs2_is_writebuffered(c)) +- return jffs2_flash_direct_write(c, ofs, len, retlen, buf); +- +- vecs[0].iov_base = (unsigned char *) buf; +- vecs[0].iov_len = len; +- return jffs2_flash_writev(c, vecs, 1, ofs, retlen, 0); +-} +- +-/* +- Handle readback from writebuffer and ECC failure return +-*/ +-int jffs2_flash_read(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *retlen, u_char *buf) +-{ +- loff_t orbf = 0, owbf = 0, lwbf = 0; +- int ret; +- +- if (!jffs2_is_writebuffered(c)) +- return mtd_read(c->mtd, ofs, len, retlen, buf); +- +- /* Read flash */ +- down_read(&c->wbuf_sem); +- ret = mtd_read(c->mtd, ofs, len, retlen, buf); +- +- if ( (ret == -EBADMSG || ret == -EUCLEAN) && (*retlen == len) ) { +- if (ret == -EBADMSG) +- pr_warn("mtd->read(0x%zx bytes from 0x%llx) returned ECC error\n", +- len, ofs); +- /* +- * We have the raw data without ECC correction in the buffer, +- * maybe we are lucky and all data or parts are correct. We +- * check the node. If data are corrupted node check will sort +- * it out. We keep this block, it will fail on write or erase +- * and the we mark it bad. Or should we do that now? But we +- * should give him a chance. Maybe we had a system crash or +- * power loss before the ecc write or a erase was completed. +- * So we return success. :) +- */ +- ret = 0; +- } +- +- /* if no writebuffer available or write buffer empty, return */ +- if (!c->wbuf_pagesize || !c->wbuf_len) +- goto exit; +- +- /* if we read in a different block, return */ +- if (SECTOR_ADDR(ofs) != SECTOR_ADDR(c->wbuf_ofs)) +- goto exit; +- +- if (ofs >= c->wbuf_ofs) { +- owbf = (ofs - c->wbuf_ofs); /* offset in write buffer */ +- if (owbf > c->wbuf_len) /* is read beyond write buffer ? */ +- goto exit; +- lwbf = c->wbuf_len - owbf; /* number of bytes to copy */ +- if (lwbf > len) +- lwbf = len; +- } else { +- orbf = (c->wbuf_ofs - ofs); /* offset in read buffer */ +- if (orbf > len) /* is write beyond write buffer ? */ +- goto exit; +- lwbf = len - orbf; /* number of bytes to copy */ +- if (lwbf > c->wbuf_len) +- lwbf = c->wbuf_len; +- } +- if (lwbf > 0) +- memcpy(buf+orbf,c->wbuf+owbf,lwbf); +- +-exit: +- up_read(&c->wbuf_sem); +- return ret; +-} +- +-#define NR_OOB_SCAN_PAGES 4 +- +-/* For historical reasons we use only 8 bytes for OOB clean marker */ +-#define OOB_CM_SIZE 8 +- +-static const struct jffs2_unknown_node oob_cleanmarker = +-{ +- .magic = constant_cpu_to_je16(JFFS2_MAGIC_BITMASK), +- .nodetype = constant_cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER), +- .totlen = constant_cpu_to_je32(8) +-}; +- +-/* +- * Check, if the out of band area is empty. This function knows about the clean +- * marker and if it is present in OOB, treats the OOB as empty anyway. +- */ +-int jffs2_check_oob_empty(struct jffs2_sb_info *c, +- struct jffs2_eraseblock *jeb, int mode) +-{ +- int i, ret; +- int cmlen = min_t(int, c->oobavail, OOB_CM_SIZE); +- struct mtd_oob_ops ops; +- +- ops.mode = MTD_OPS_AUTO_OOB; +- ops.ooblen = NR_OOB_SCAN_PAGES * c->oobavail; +- ops.oobbuf = c->oobbuf; +- ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0; +- ops.datbuf = NULL; +- +- ret = mtd_read_oob(c->mtd, jeb->offset, &ops); +- if ((ret && !mtd_is_bitflip(ret)) || ops.oobretlen != ops.ooblen) { +- pr_err("cannot read OOB for EB at %08x, requested %zd bytes, read %zd bytes, error %d\n", +- jeb->offset, ops.ooblen, ops.oobretlen, ret); +- if (!ret || mtd_is_bitflip(ret)) +- ret = -EIO; +- return ret; +- } +- +- for(i = 0; i < ops.ooblen; i++) { +- if (mode && i < cmlen) +- /* Yeah, we know about the cleanmarker */ +- continue; +- +- if (ops.oobbuf[i] != 0xFF) { +- jffs2_dbg(2, "Found %02x at %x in OOB for " +- "%08x\n", ops.oobbuf[i], i, jeb->offset); +- return 1; +- } +- } +- +- return 0; +-} +- +-/* +- * Check for a valid cleanmarker. +- * Returns: 0 if a valid cleanmarker was found +- * 1 if no cleanmarker was found +- * negative error code if an error occurred +- */ +-int jffs2_check_nand_cleanmarker(struct jffs2_sb_info *c, +- struct jffs2_eraseblock *jeb) +-{ +- struct mtd_oob_ops ops; +- int ret, cmlen = min_t(int, c->oobavail, OOB_CM_SIZE); +- +- ops.mode = MTD_OPS_AUTO_OOB; +- ops.ooblen = cmlen; +- ops.oobbuf = c->oobbuf; +- ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0; +- ops.datbuf = NULL; +- +- ret = mtd_read_oob(c->mtd, jeb->offset, &ops); +- if ((ret && !mtd_is_bitflip(ret)) || ops.oobretlen != ops.ooblen) { +- pr_err("cannot read OOB for EB at %08x, requested %zd bytes, read %zd bytes, error %d\n", +- jeb->offset, ops.ooblen, ops.oobretlen, ret); +- if (!ret || mtd_is_bitflip(ret)) +- ret = -EIO; +- return ret; +- } +- +- return !!memcmp(&oob_cleanmarker, c->oobbuf, cmlen); +-} +- +-int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c, +- struct jffs2_eraseblock *jeb) +-{ +- int ret; +- struct mtd_oob_ops ops; +- int cmlen = min_t(int, c->oobavail, OOB_CM_SIZE); +- +- ops.mode = MTD_OPS_AUTO_OOB; +- ops.ooblen = cmlen; +- ops.oobbuf = (uint8_t *)&oob_cleanmarker; +- ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0; +- ops.datbuf = NULL; +- +- ret = mtd_write_oob(c->mtd, jeb->offset, &ops); +- if (ret || ops.oobretlen != ops.ooblen) { +- pr_err("cannot write OOB for EB at %08x, requested %zd bytes, read %zd bytes, error %d\n", +- jeb->offset, ops.ooblen, ops.oobretlen, ret); +- if (!ret) +- ret = -EIO; +- return ret; +- } +- +- return 0; +-} +- +-/* +- * On NAND we try to mark this block bad. If the block was erased more +- * than MAX_ERASE_FAILURES we mark it finally bad. +- * Don't care about failures. This block remains on the erase-pending +- * or badblock list as long as nobody manipulates the flash with +- * a bootloader or something like that. +- */ +- +-int jffs2_write_nand_badblock(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, uint32_t bad_offset) +-{ +- int ret; +- +- /* if the count is < max, we try to write the counter to the 2nd page oob area */ +- if( ++jeb->bad_count < MAX_ERASE_FAILURES) +- return 0; +- +- pr_warn("marking eraseblock at %08x as bad\n", bad_offset); +- ret = mtd_block_markbad(c->mtd, bad_offset); +- +- if (ret) { +- jffs2_dbg(1, "%s(): Write failed for block at %08x: error %d\n", +- __func__, jeb->offset, ret); +- return ret; +- } +- return 1; +-} +- +-static struct jffs2_sb_info *work_to_sb(struct work_struct *work) +-{ +- struct delayed_work *dwork; +- +- dwork = to_delayed_work(work); +- return container_of(dwork, struct jffs2_sb_info, wbuf_dwork); +-} +- +-static void delayed_wbuf_sync(struct work_struct *work) +-{ +- struct jffs2_sb_info *c = work_to_sb(work); +- struct super_block *sb = OFNI_BS_2SFFJ(c); +- +- if (!sb_rdonly(sb)) { +- jffs2_dbg(1, "%s()\n", __func__); +- jffs2_flush_wbuf_gc(c, 0); +- } +-} +- +-void jffs2_dirty_trigger(struct jffs2_sb_info *c) +-{ +- struct super_block *sb = OFNI_BS_2SFFJ(c); +- unsigned long delay; +- +- if (sb_rdonly(sb)) +- return; +- +- delay = msecs_to_jiffies(dirty_writeback_interval * 10); +- if (queue_delayed_work(system_long_wq, &c->wbuf_dwork, delay)) +- jffs2_dbg(1, "%s()\n", __func__); +-} +- +-int jffs2_nand_flash_setup(struct jffs2_sb_info *c) +-{ +- if (!c->mtd->oobsize) +- return 0; +- +- /* Cleanmarker is out-of-band, so inline size zero */ +- c->cleanmarker_size = 0; +- +- if (c->mtd->oobavail == 0) { +- pr_err("inconsistent device description\n"); +- return -EINVAL; +- } +- +- jffs2_dbg(1, "using OOB on NAND\n"); +- +- c->oobavail = c->mtd->oobavail; +- +- /* Initialise write buffer */ +- init_rwsem(&c->wbuf_sem); +- INIT_DELAYED_WORK(&c->wbuf_dwork, delayed_wbuf_sync); +- c->wbuf_pagesize = c->mtd->writesize; +- c->wbuf_ofs = 0xFFFFFFFF; +- +- c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL); +- if (!c->wbuf) +- return -ENOMEM; +- +- c->oobbuf = kmalloc_array(NR_OOB_SCAN_PAGES, c->oobavail, GFP_KERNEL); +- if (!c->oobbuf) { +- kfree(c->wbuf); +- return -ENOMEM; +- } +- +-#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY +- c->wbuf_verify = kmalloc(c->wbuf_pagesize, GFP_KERNEL); +- if (!c->wbuf_verify) { +- kfree(c->oobbuf); +- kfree(c->wbuf); +- return -ENOMEM; +- } +-#endif +- return 0; +-} +- +-void jffs2_nand_flash_cleanup(struct jffs2_sb_info *c) +-{ +-#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY +- kfree(c->wbuf_verify); +-#endif +- kfree(c->wbuf); +- kfree(c->oobbuf); +-} +- +-int jffs2_dataflash_setup(struct jffs2_sb_info *c) { +- c->cleanmarker_size = 0; /* No cleanmarkers needed */ +- +- /* Initialize write buffer */ +- init_rwsem(&c->wbuf_sem); +- INIT_DELAYED_WORK(&c->wbuf_dwork, delayed_wbuf_sync); +- c->wbuf_pagesize = c->mtd->erasesize; +- +- /* Find a suitable c->sector_size +- * - Not too much sectors +- * - Sectors have to be at least 4 K + some bytes +- * - All known dataflashes have erase sizes of 528 or 1056 +- * - we take at least 8 eraseblocks and want to have at least 8K size +- * - The concatenation should be a power of 2 +- */ +- +- c->sector_size = 8 * c->mtd->erasesize; +- +- while (c->sector_size < 8192) { +- c->sector_size *= 2; +- } +- +- /* It may be necessary to adjust the flash size */ +- c->flash_size = c->mtd->size; +- +- if ((c->flash_size % c->sector_size) != 0) { +- c->flash_size = (c->flash_size / c->sector_size) * c->sector_size; +- pr_warn("flash size adjusted to %dKiB\n", c->flash_size); +- } +- +- c->wbuf_ofs = 0xFFFFFFFF; +- c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL); +- if (!c->wbuf) +- return -ENOMEM; +- +-#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY +- c->wbuf_verify = kmalloc(c->wbuf_pagesize, GFP_KERNEL); +- if (!c->wbuf_verify) { +- kfree(c->wbuf); +- return -ENOMEM; +- } +-#endif +- +- pr_info("write-buffering enabled buffer (%d) erasesize (%d)\n", +- c->wbuf_pagesize, c->sector_size); +- +- return 0; +-} +- +-void jffs2_dataflash_cleanup(struct jffs2_sb_info *c) { +-#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY +- kfree(c->wbuf_verify); +-#endif +- kfree(c->wbuf); +-} +- +-int jffs2_nor_wbuf_flash_setup(struct jffs2_sb_info *c) { +- /* Cleanmarker currently occupies whole programming regions, +- * either one or 2 for 8Byte STMicro flashes. */ +- c->cleanmarker_size = max(16u, c->mtd->writesize); +- +- /* Initialize write buffer */ +- init_rwsem(&c->wbuf_sem); +- INIT_DELAYED_WORK(&c->wbuf_dwork, delayed_wbuf_sync); +- +- c->wbuf_pagesize = c->mtd->writesize; +- c->wbuf_ofs = 0xFFFFFFFF; +- +- c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL); +- if (!c->wbuf) +- return -ENOMEM; +- +-#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY +- c->wbuf_verify = kmalloc(c->wbuf_pagesize, GFP_KERNEL); +- if (!c->wbuf_verify) { +- kfree(c->wbuf); +- return -ENOMEM; +- } +-#endif +- return 0; +-} +- +-void jffs2_nor_wbuf_flash_cleanup(struct jffs2_sb_info *c) { +-#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY +- kfree(c->wbuf_verify); +-#endif +- kfree(c->wbuf); +-} +- +-int jffs2_ubivol_setup(struct jffs2_sb_info *c) { +- c->cleanmarker_size = 0; +- +- if (c->mtd->writesize == 1) +- /* We do not need write-buffer */ +- return 0; +- +- init_rwsem(&c->wbuf_sem); +- INIT_DELAYED_WORK(&c->wbuf_dwork, delayed_wbuf_sync); +- +- c->wbuf_pagesize = c->mtd->writesize; +- c->wbuf_ofs = 0xFFFFFFFF; +- c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL); +- if (!c->wbuf) +- return -ENOMEM; +- +- pr_info("write-buffering enabled buffer (%d) erasesize (%d)\n", +- c->wbuf_pagesize, c->sector_size); +- +- return 0; +-} +- +-void jffs2_ubivol_cleanup(struct jffs2_sb_info *c) { +- kfree(c->wbuf); +-} +diff -Nupr old/fs/jffs2/write.c new/fs/jffs2/write.c +--- old/fs/jffs2/write.c 2022-05-09 17:22:53.000000000 +0800 ++++ new/fs/jffs2/write.c 2022-05-09 20:07:33.520000000 +0800 +@@ -9,16 +9,15 @@ + * + */ + +-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +- ++#include + #include + #include +-#include + #include +-#include ++#include ++#include "mtd_dev.h" + #include "nodelist.h" + #include "compr.h" +- ++#include "los_crc32.h" + + int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, + uint32_t mode, struct jffs2_raw_inode *ri) +@@ -30,8 +29,6 @@ int jffs2_do_new_inode(struct jffs2_sb_i + return -ENOMEM; + } + +- memset(ic, 0, sizeof(*ic)); +- + f->inocache = ic; + f->inocache->pino_nlink = 1; /* Will be overwritten shortly for directories */ + f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache; +@@ -69,8 +66,10 @@ struct jffs2_full_dnode *jffs2_write_dno + int retried = 0; + unsigned long cnt = 2; + +- D1(if(je32_to_cpu(ri->hdr_crc) != crc32(0, ri, sizeof(struct jffs2_unknown_node)-4)) { +- pr_crit("Eep. CRC not correct in jffs2_write_dnode()\n"); ++ D1(if (je32_to_cpu(ri->hdr_crc) != crc32(0, ri, sizeof(struct jffs2_unknown_node)-4)) { ++ printk(KERN_CRIT "Eep. CRC not correct in jffs2_write_dnode(), je32_to_cpu(ri->hdr_crc):%d, " ++ "crc32(0, ri, sizeof(struct jffs2_unknown_node) - 4):%d\n", je32_to_cpu(ri->hdr_crc), ++ crc32(0, ri, sizeof(struct jffs2_unknown_node) - 4)); + BUG(); + } + ); +@@ -172,8 +171,8 @@ struct jffs2_full_dnode *jffs2_write_dno + beginning of a page and runs to the end of the file, or if + it's a hole node, mark it REF_PRISTINE, else REF_NORMAL. + */ +- if ((je32_to_cpu(ri->dsize) >= PAGE_SIZE) || +- ( ((je32_to_cpu(ri->offset)&(PAGE_SIZE-1))==0) && ++ if ((je32_to_cpu(ri->dsize) >= PAGE_CACHE_SIZE) || ++ ( ((je32_to_cpu(ri->offset)&(PAGE_CACHE_SIZE-1))==0) && + (je32_to_cpu(ri->dsize)+je32_to_cpu(ri->offset) == je32_to_cpu(ri->isize)))) { + flash_ofs |= REF_PRISTINE; + } else { +@@ -219,11 +218,13 @@ struct jffs2_full_dirent *jffs2_write_di + je32_to_cpu(rd->name_crc)); + + D1(if(je32_to_cpu(rd->hdr_crc) != crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)) { +- pr_crit("Eep. CRC not correct in jffs2_write_dirent()\n"); ++ printk(KERN_CRIT "Eep. CRC not correct in jffs2_write_dirent(), je32_to_cpu(rd->hdr_crc):%d, " ++ "crc32(0, rd, sizeof(struct jffs2_unknown_node) - 4):%d\n", je32_to_cpu(rd->hdr_crc), ++ crc32(0, rd, sizeof(struct jffs2_unknown_node) - 4)); + BUG(); + }); + +- if (strnlen(name, namelen) != namelen) { ++ if (strnlen((const char *)name, namelen) != namelen) { + /* This should never happen, but seems to have done on at least one + occasion: https://dev.laptop.org/ticket/4184 */ + pr_crit("Error in jffs2_write_dirent() -- name contains zero bytes!\n"); +@@ -245,7 +246,7 @@ struct jffs2_full_dirent *jffs2_write_di + + fd->version = je32_to_cpu(rd->version); + fd->ino = je32_to_cpu(rd->ino); +- fd->nhash = full_name_hash(NULL, name, namelen); ++ fd->nhash = full_name_hash(name, namelen); + fd->type = rd->type; + memcpy(fd->name, name, namelen); + fd->name[namelen]=0; +@@ -343,10 +344,24 @@ int jffs2_write_inode_range(struct jffs2 + { + int ret = 0; + uint32_t writtenlen = 0; ++ unsigned char *bufRet = NULL; ++ unsigned char *bufRetBak = NULL; + + jffs2_dbg(1, "%s(): Ino #%u, ofs 0x%x, len 0x%x\n", + __func__, f->inocache->ino, offset, writelen); + ++ if (writelen > 0) { ++ bufRet = kmalloc(writelen, GFP_KERNEL); ++ if (bufRet == NULL) { ++ return -ENOMEM; ++ } ++ bufRetBak = bufRet; ++ if (LOS_CopyToKernel(bufRet, writelen, buf, writelen) != 0) { ++ kfree(bufRet); ++ return -EFAULT; ++ } ++ } ++ + while(writelen) { + struct jffs2_full_dnode *fn; + unsigned char *comprbuf = NULL; +@@ -366,11 +381,10 @@ int jffs2_write_inode_range(struct jffs2 + break; + } + mutex_lock(&f->sem); +- datalen = min_t(uint32_t, writelen, +- PAGE_SIZE - (offset & (PAGE_SIZE-1))); ++ datalen = min_t(uint32_t, writelen, PAGE_CACHE_SIZE - (offset & (PAGE_CACHE_SIZE-1))); + cdatalen = min_t(uint32_t, alloclen - sizeof(*ri), datalen); + +- comprtype = jffs2_compress(c, f, buf, &comprbuf, &datalen, &cdatalen); ++ comprtype = jffs2_compress(c, f, bufRet, &comprbuf, &datalen, &cdatalen); + + ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); + ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE); +@@ -390,7 +404,7 @@ int jffs2_write_inode_range(struct jffs2 + + fn = jffs2_write_dnode(c, f, ri, comprbuf, cdatalen, ALLOC_NORETRY); + +- jffs2_free_comprbuf(comprbuf, buf); ++ jffs2_free_comprbuf(comprbuf, bufRet); + + if (IS_ERR(fn)) { + ret = PTR_ERR(fn); +@@ -432,15 +446,18 @@ int jffs2_write_inode_range(struct jffs2 + writtenlen += datalen; + offset += datalen; + writelen -= datalen; +- buf += datalen; ++ bufRet += datalen; + } + *retlen = writtenlen; ++ if (bufRetBak != NULL) { ++ kfree(bufRetBak); ++ } + return ret; + } + + int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, + struct jffs2_inode_info *f, struct jffs2_raw_inode *ri, +- const struct qstr *qstr) ++ const char *name, int namelen) + { + struct jffs2_raw_dirent *rd; + struct jffs2_full_dnode *fn; +@@ -468,7 +485,8 @@ int jffs2_do_create(struct jffs2_sb_info + jemode_to_cpu(ri->mode)); + + if (IS_ERR(fn)) { +- jffs2_dbg(1, "jffs2_write_dnode() failed\n"); ++ jffs2_dbg(1, "jffs2_write_dnode() failed,error:%ld\n", ++ PTR_ERR(fn)); + /* Eeek. Wave bye bye */ + mutex_unlock(&f->sem); + jffs2_complete_reservation(c); +@@ -482,19 +500,12 @@ int jffs2_do_create(struct jffs2_sb_info + mutex_unlock(&f->sem); + jffs2_complete_reservation(c); + +- ret = jffs2_init_security(&f->vfs_inode, &dir_f->vfs_inode, qstr); +- if (ret) +- return ret; +- ret = jffs2_init_acl_post(&f->vfs_inode); +- if (ret) +- return ret; +- +- ret = jffs2_reserve_space(c, sizeof(*rd)+qstr->len, &alloclen, +- ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(qstr->len)); ++ ret = jffs2_reserve_space(c, sizeof(*rd)+ namelen, &alloclen, ++ ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); + + if (ret) { + /* Eep. */ +- jffs2_dbg(1, "jffs2_reserve_space() for dirent failed\n"); ++ jffs2_dbg(1, "jffs2_reserve_space() for dirent failed,ret:%d\n",ret); + return ret; + } + +@@ -509,19 +520,19 @@ int jffs2_do_create(struct jffs2_sb_info + + rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); + rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT); +- rd->totlen = cpu_to_je32(sizeof(*rd) + qstr->len); ++ rd->totlen = cpu_to_je32(sizeof(*rd) + namelen); + rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)); + + rd->pino = cpu_to_je32(dir_f->inocache->ino); + rd->version = cpu_to_je32(++dir_f->highest_version); + rd->ino = ri->ino; + rd->mctime = ri->ctime; +- rd->nsize = qstr->len; ++ rd->nsize = namelen; + rd->type = DT_REG; + rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); +- rd->name_crc = cpu_to_je32(crc32(0, qstr->name, qstr->len)); ++ rd->name_crc = cpu_to_je32(crc32(0, name, namelen)); + +- fd = jffs2_write_dirent(c, dir_f, rd, qstr->name, qstr->len, ALLOC_NORMAL); ++ fd = jffs2_write_dirent(c, dir_f, rd, (const unsigned char *)name, namelen, ALLOC_NORMAL); + + jffs2_free_raw_dirent(rd); + +@@ -553,7 +564,7 @@ int jffs2_do_unlink(struct jffs2_sb_info + uint32_t alloclen; + int ret; + +- if (!jffs2_can_mark_obsolete(c)) { ++ if (jffs2_can_mark_obsolete(c)) { + /* We can't mark stuff obsolete on the medium. We need to write a deletion dirent */ + + rd = jffs2_alloc_raw_dirent(); +@@ -584,7 +595,7 @@ int jffs2_do_unlink(struct jffs2_sb_info + rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); + rd->name_crc = cpu_to_je32(crc32(0, name, namelen)); + +- fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, ALLOC_DELETION); ++ fd = jffs2_write_dirent(c, dir_f, rd, (const unsigned char *)name, namelen, ALLOC_DELETION); + + jffs2_free_raw_dirent(rd); + +@@ -598,7 +609,7 @@ int jffs2_do_unlink(struct jffs2_sb_info + jffs2_add_fd_to_list(c, fd, &dir_f->dents); + mutex_unlock(&dir_f->sem); + } else { +- uint32_t nhash = full_name_hash(NULL, name, namelen); ++ uint32_t nhash = full_name_hash((const unsigned char *)name, namelen); + + fd = dir_f->dents; + /* We don't actually want to reserve any space, but we do +@@ -703,7 +714,7 @@ int jffs2_do_link (struct jffs2_sb_info + rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); + rd->name_crc = cpu_to_je32(crc32(0, name, namelen)); + +- fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, ALLOC_NORMAL); ++ fd = jffs2_write_dirent(c, dir_f, rd, (const unsigned char *)name, namelen, ALLOC_NORMAL); + + jffs2_free_raw_dirent(rd); + +diff -Nupr old/fs/jffs2/writev.c new/fs/jffs2/writev.c +--- old/fs/jffs2/writev.c 2022-05-09 17:22:53.000000000 +0800 ++++ new/fs/jffs2/writev.c 2022-05-09 20:05:36.440000000 +0800 +@@ -10,42 +10,97 @@ + */ + + #include +-#include ++#include "mtd_dev.h" + #include "nodelist.h" + + int jffs2_flash_direct_writev(struct jffs2_sb_info *c, const struct kvec *vecs, + unsigned long count, loff_t to, size_t *retlen) + { +- if (!jffs2_is_writebuffered(c)) { +- if (jffs2_sum_active()) { +- int res; +- res = jffs2_sum_add_kvec(c, vecs, count, (uint32_t) to); +- if (res) { +- return res; ++ unsigned long i; ++ size_t totlen = 0, thislen; ++ int ret = 0; ++ ++ for (i = 0; i < count; i++) { ++ // writes need to be aligned but the data we're passed may not be ++ // Observation suggests most unaligned writes are small, so we ++ // optimize for that case. ++ ++ if (((vecs[i].iov_len & (sizeof(int) - 1))) || ++ (((unsigned long) vecs[i].iov_base & (sizeof(unsigned long) - 1)))) { ++ // are there iov's after this one? Or is it so much we'd need ++ // to do multiple writes anyway? ++ if ((i + 1) < count || vecs[i].iov_len > 256) { ++ // cop out and malloc ++ unsigned long j; ++ size_t sizetomalloc = 0, totvecsize = 0; ++ char *cbuf, *cbufptr; ++ ++ for (j = i; j < count; j++) ++ totvecsize += vecs[j].iov_len; ++ ++ // pad up in case unaligned ++ sizetomalloc = totvecsize + sizeof(int) - 1; ++ sizetomalloc &= ~(sizeof(int) - 1); ++ cbuf = (char *) malloc(sizetomalloc); ++ // malloc returns aligned memory ++ if (!cbuf) { ++ ret = -ENOMEM; ++ goto writev_out; ++ } ++ cbufptr = cbuf; ++ for (j = i; j < count; j++) { ++ (void)memcpy_s(cbufptr, vecs[j].iov_len, vecs[j].iov_base, vecs[j].iov_len); ++ cbufptr += vecs[j].iov_len; ++ } ++ ret = jffs2_flash_write(c, to, sizetomalloc, &thislen, ++ (unsigned char *) cbuf); ++ if (thislen > totvecsize) // in case it was aligned up ++ thislen = totvecsize; ++ totlen += thislen; ++ free(cbuf); ++ goto writev_out; ++ } else { ++ // otherwise optimize for the common case ++ int buf[256/sizeof(int)]; // int, so int aligned ++ size_t lentowrite; ++ ++ lentowrite = vecs[i].iov_len; ++ // pad up in case its unaligned ++ lentowrite += sizeof(int) - 1; ++ lentowrite &= ~(sizeof(int) - 1); ++ ret = memcpy_s(buf, sizeof(buf), vecs[i].iov_base, vecs[i].iov_len); ++ if (ret != EOK) ++ goto writev_out; ++ ++ ret = jffs2_flash_write(c, to, lentowrite, &thislen, ++ (unsigned char *) &buf[0]); ++ if (thislen > vecs[i].iov_len) ++ thislen = vecs[i].iov_len; + } ++ } else { ++ ret = jffs2_flash_write(c, to, vecs[i].iov_len, &thislen, ++ vecs[i].iov_base); + } ++ totlen += thislen; ++ if (ret || thislen != vecs[i].iov_len) break; ++ to += vecs[i].iov_len; + } + +- return mtd_writev(c->mtd, vecs, count, to, retlen); ++writev_out: ++ if (retlen) *retlen = totlen; ++ ++ return ret; + } + + int jffs2_flash_direct_write(struct jffs2_sb_info *c, loff_t ofs, size_t len, + size_t *retlen, const u_char *buf) + { + int ret; +- ret = mtd_write(c->mtd, ofs, len, retlen, buf); +- +- if (jffs2_sum_active()) { +- struct kvec vecs[1]; +- int res; +- +- vecs[0].iov_base = (unsigned char *) buf; +- vecs[0].iov_len = len; +- +- res = jffs2_sum_add_kvec(c, vecs, 1, (uint32_t) ofs); +- if (res) { +- return res; +- } ++ ret = c->mtd->write(c->mtd, ofs, len, (char *)buf); ++ if (ret >= 0) { ++ *retlen = ret; ++ return 0; + } ++ *retlen = 0; + return ret; + } +diff -Nupr old/fs/jffs2/xattr.c new/fs/jffs2/xattr.c +--- old/fs/jffs2/xattr.c 2022-05-09 17:15:24.360000000 +0800 ++++ new/fs/jffs2/xattr.c 1970-01-01 08:00:00.000000000 +0800 +@@ -1,1347 +0,0 @@ +-/* +- * JFFS2 -- Journalling Flash File System, Version 2. +- * +- * Copyright © 2006 NEC Corporation +- * +- * Created by KaiGai Kohei +- * +- * For licensing information, see the file 'LICENCE' in this directory. +- * +- */ +- +-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +- +-#define JFFS2_XATTR_IS_CORRUPTED 1 +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include "nodelist.h" +-/* -------- xdatum related functions ---------------- +- * xattr_datum_hashkey(xprefix, xname, xvalue, xsize) +- * is used to calcurate xdatum hashkey. The reminder of hashkey into XATTRINDEX_HASHSIZE is +- * the index of the xattr name/value pair cache (c->xattrindex). +- * is_xattr_datum_unchecked(c, xd) +- * returns 1, if xdatum contains any unchecked raw nodes. if all raw nodes are not +- * unchecked, it returns 0. +- * unload_xattr_datum(c, xd) +- * is used to release xattr name/value pair and detach from c->xattrindex. +- * reclaim_xattr_datum(c) +- * is used to reclaim xattr name/value pairs on the xattr name/value pair cache when +- * memory usage by cache is over c->xdatum_mem_threshold. Currently, this threshold +- * is hard coded as 32KiB. +- * do_verify_xattr_datum(c, xd) +- * is used to load the xdatum informations without name/value pair from the medium. +- * It's necessary once, because those informations are not collected during mounting +- * process when EBS is enabled. +- * 0 will be returned, if success. An negative return value means recoverable error, and +- * positive return value means unrecoverable error. Thus, caller must remove this xdatum +- * and xref when it returned positive value. +- * do_load_xattr_datum(c, xd) +- * is used to load name/value pair from the medium. +- * The meanings of return value is same as do_verify_xattr_datum(). +- * load_xattr_datum(c, xd) +- * is used to be as a wrapper of do_verify_xattr_datum() and do_load_xattr_datum(). +- * If xd need to call do_verify_xattr_datum() at first, it's called before calling +- * do_load_xattr_datum(). The meanings of return value is same as do_verify_xattr_datum(). +- * save_xattr_datum(c, xd) +- * is used to write xdatum to medium. xd->version will be incremented. +- * create_xattr_datum(c, xprefix, xname, xvalue, xsize) +- * is used to create new xdatum and write to medium. +- * unrefer_xattr_datum(c, xd) +- * is used to delete a xdatum. When nobody refers this xdatum, JFFS2_XFLAGS_DEAD +- * is set on xd->flags and chained xattr_dead_list or release it immediately. +- * In the first case, the garbage collector release it later. +- * -------------------------------------------------- */ +-static uint32_t xattr_datum_hashkey(int xprefix, const char *xname, const char *xvalue, int xsize) +-{ +- int name_len = strlen(xname); +- +- return crc32(xprefix, xname, name_len) ^ crc32(xprefix, xvalue, xsize); +-} +- +-static int is_xattr_datum_unchecked(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd) +-{ +- struct jffs2_raw_node_ref *raw; +- int rc = 0; +- +- spin_lock(&c->erase_completion_lock); +- for (raw=xd->node; raw != (void *)xd; raw=raw->next_in_ino) { +- if (ref_flags(raw) == REF_UNCHECKED) { +- rc = 1; +- break; +- } +- } +- spin_unlock(&c->erase_completion_lock); +- return rc; +-} +- +-static void unload_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd) +-{ +- /* must be called under down_write(xattr_sem) */ +- D1(dbg_xattr("%s: xid=%u, version=%u\n", __func__, xd->xid, xd->version)); +- if (xd->xname) { +- c->xdatum_mem_usage -= (xd->name_len + 1 + xd->value_len); +- kfree(xd->xname); +- } +- +- list_del_init(&xd->xindex); +- xd->hashkey = 0; +- xd->xname = NULL; +- xd->xvalue = NULL; +-} +- +-static void reclaim_xattr_datum(struct jffs2_sb_info *c) +-{ +- /* must be called under down_write(xattr_sem) */ +- struct jffs2_xattr_datum *xd, *_xd; +- uint32_t target, before; +- static int index = 0; +- int count; +- +- if (c->xdatum_mem_threshold > c->xdatum_mem_usage) +- return; +- +- before = c->xdatum_mem_usage; +- target = c->xdatum_mem_usage * 4 / 5; /* 20% reduction */ +- for (count = 0; count < XATTRINDEX_HASHSIZE; count++) { +- list_for_each_entry_safe(xd, _xd, &c->xattrindex[index], xindex) { +- if (xd->flags & JFFS2_XFLAGS_HOT) { +- xd->flags &= ~JFFS2_XFLAGS_HOT; +- } else if (!(xd->flags & JFFS2_XFLAGS_BIND)) { +- unload_xattr_datum(c, xd); +- } +- if (c->xdatum_mem_usage <= target) +- goto out; +- } +- index = (index+1) % XATTRINDEX_HASHSIZE; +- } +- out: +- JFFS2_NOTICE("xdatum_mem_usage from %u byte to %u byte (%u byte reclaimed)\n", +- before, c->xdatum_mem_usage, before - c->xdatum_mem_usage); +-} +- +-static int do_verify_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd) +-{ +- /* must be called under down_write(xattr_sem) */ +- struct jffs2_eraseblock *jeb; +- struct jffs2_raw_node_ref *raw; +- struct jffs2_raw_xattr rx; +- size_t readlen; +- uint32_t crc, offset, totlen; +- int rc; +- +- spin_lock(&c->erase_completion_lock); +- offset = ref_offset(xd->node); +- if (ref_flags(xd->node) == REF_PRISTINE) +- goto complete; +- spin_unlock(&c->erase_completion_lock); +- +- rc = jffs2_flash_read(c, offset, sizeof(rx), &readlen, (char *)&rx); +- if (rc || readlen != sizeof(rx)) { +- JFFS2_WARNING("jffs2_flash_read()=%d, req=%zu, read=%zu at %#08x\n", +- rc, sizeof(rx), readlen, offset); +- return rc ? rc : -EIO; +- } +- crc = crc32(0, &rx, sizeof(rx) - 4); +- if (crc != je32_to_cpu(rx.node_crc)) { +- JFFS2_ERROR("node CRC failed at %#08x, read=%#08x, calc=%#08x\n", +- offset, je32_to_cpu(rx.hdr_crc), crc); +- xd->flags |= JFFS2_XFLAGS_INVALID; +- return JFFS2_XATTR_IS_CORRUPTED; +- } +- totlen = PAD(sizeof(rx) + rx.name_len + 1 + je16_to_cpu(rx.value_len)); +- if (je16_to_cpu(rx.magic) != JFFS2_MAGIC_BITMASK +- || je16_to_cpu(rx.nodetype) != JFFS2_NODETYPE_XATTR +- || je32_to_cpu(rx.totlen) != totlen +- || je32_to_cpu(rx.xid) != xd->xid +- || je32_to_cpu(rx.version) != xd->version) { +- JFFS2_ERROR("inconsistent xdatum at %#08x, magic=%#04x/%#04x, " +- "nodetype=%#04x/%#04x, totlen=%u/%u, xid=%u/%u, version=%u/%u\n", +- offset, je16_to_cpu(rx.magic), JFFS2_MAGIC_BITMASK, +- je16_to_cpu(rx.nodetype), JFFS2_NODETYPE_XATTR, +- je32_to_cpu(rx.totlen), totlen, +- je32_to_cpu(rx.xid), xd->xid, +- je32_to_cpu(rx.version), xd->version); +- xd->flags |= JFFS2_XFLAGS_INVALID; +- return JFFS2_XATTR_IS_CORRUPTED; +- } +- xd->xprefix = rx.xprefix; +- xd->name_len = rx.name_len; +- xd->value_len = je16_to_cpu(rx.value_len); +- xd->data_crc = je32_to_cpu(rx.data_crc); +- +- spin_lock(&c->erase_completion_lock); +- complete: +- for (raw=xd->node; raw != (void *)xd; raw=raw->next_in_ino) { +- jeb = &c->blocks[ref_offset(raw) / c->sector_size]; +- totlen = PAD(ref_totlen(c, jeb, raw)); +- if (ref_flags(raw) == REF_UNCHECKED) { +- c->unchecked_size -= totlen; c->used_size += totlen; +- jeb->unchecked_size -= totlen; jeb->used_size += totlen; +- } +- raw->flash_offset = ref_offset(raw) | ((xd->node==raw) ? REF_PRISTINE : REF_NORMAL); +- } +- spin_unlock(&c->erase_completion_lock); +- +- /* unchecked xdatum is chained with c->xattr_unchecked */ +- list_del_init(&xd->xindex); +- +- dbg_xattr("success on verifying xdatum (xid=%u, version=%u)\n", +- xd->xid, xd->version); +- +- return 0; +-} +- +-static int do_load_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd) +-{ +- /* must be called under down_write(xattr_sem) */ +- char *data; +- size_t readlen; +- uint32_t crc, length; +- int i, ret, retry = 0; +- +- BUG_ON(ref_flags(xd->node) != REF_PRISTINE); +- BUG_ON(!list_empty(&xd->xindex)); +- retry: +- length = xd->name_len + 1 + xd->value_len; +- data = kmalloc(length, GFP_KERNEL); +- if (!data) +- return -ENOMEM; +- +- ret = jffs2_flash_read(c, ref_offset(xd->node)+sizeof(struct jffs2_raw_xattr), +- length, &readlen, data); +- +- if (ret || length!=readlen) { +- JFFS2_WARNING("jffs2_flash_read() returned %d, request=%d, readlen=%zu, at %#08x\n", +- ret, length, readlen, ref_offset(xd->node)); +- kfree(data); +- return ret ? ret : -EIO; +- } +- +- data[xd->name_len] = '\0'; +- crc = crc32(0, data, length); +- if (crc != xd->data_crc) { +- JFFS2_WARNING("node CRC failed (JFFS2_NODETYPE_XATTR)" +- " at %#08x, read: 0x%08x calculated: 0x%08x\n", +- ref_offset(xd->node), xd->data_crc, crc); +- kfree(data); +- xd->flags |= JFFS2_XFLAGS_INVALID; +- return JFFS2_XATTR_IS_CORRUPTED; +- } +- +- xd->flags |= JFFS2_XFLAGS_HOT; +- xd->xname = data; +- xd->xvalue = data + xd->name_len+1; +- +- c->xdatum_mem_usage += length; +- +- xd->hashkey = xattr_datum_hashkey(xd->xprefix, xd->xname, xd->xvalue, xd->value_len); +- i = xd->hashkey % XATTRINDEX_HASHSIZE; +- list_add(&xd->xindex, &c->xattrindex[i]); +- if (!retry) { +- retry = 1; +- reclaim_xattr_datum(c); +- if (!xd->xname) +- goto retry; +- } +- +- dbg_xattr("success on loading xdatum (xid=%u, xprefix=%u, xname='%s')\n", +- xd->xid, xd->xprefix, xd->xname); +- +- return 0; +-} +- +-static int load_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd) +-{ +- /* must be called under down_write(xattr_sem); +- * rc < 0 : recoverable error, try again +- * rc = 0 : success +- * rc > 0 : Unrecoverable error, this node should be deleted. +- */ +- int rc = 0; +- +- BUG_ON(xd->flags & JFFS2_XFLAGS_DEAD); +- if (xd->xname) +- return 0; +- if (xd->flags & JFFS2_XFLAGS_INVALID) +- return JFFS2_XATTR_IS_CORRUPTED; +- if (unlikely(is_xattr_datum_unchecked(c, xd))) +- rc = do_verify_xattr_datum(c, xd); +- if (!rc) +- rc = do_load_xattr_datum(c, xd); +- return rc; +-} +- +-static int save_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd) +-{ +- /* must be called under down_write(xattr_sem) */ +- struct jffs2_raw_xattr rx; +- struct kvec vecs[2]; +- size_t length; +- int rc, totlen; +- uint32_t phys_ofs = write_ofs(c); +- +- BUG_ON(!xd->xname); +- BUG_ON(xd->flags & (JFFS2_XFLAGS_DEAD|JFFS2_XFLAGS_INVALID)); +- +- vecs[0].iov_base = ℞ +- vecs[0].iov_len = sizeof(rx); +- vecs[1].iov_base = xd->xname; +- vecs[1].iov_len = xd->name_len + 1 + xd->value_len; +- totlen = vecs[0].iov_len + vecs[1].iov_len; +- +- /* Setup raw-xattr */ +- memset(&rx, 0, sizeof(rx)); +- rx.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); +- rx.nodetype = cpu_to_je16(JFFS2_NODETYPE_XATTR); +- rx.totlen = cpu_to_je32(PAD(totlen)); +- rx.hdr_crc = cpu_to_je32(crc32(0, &rx, sizeof(struct jffs2_unknown_node) - 4)); +- +- rx.xid = cpu_to_je32(xd->xid); +- rx.version = cpu_to_je32(++xd->version); +- rx.xprefix = xd->xprefix; +- rx.name_len = xd->name_len; +- rx.value_len = cpu_to_je16(xd->value_len); +- rx.data_crc = cpu_to_je32(crc32(0, vecs[1].iov_base, vecs[1].iov_len)); +- rx.node_crc = cpu_to_je32(crc32(0, &rx, sizeof(struct jffs2_raw_xattr) - 4)); +- +- rc = jffs2_flash_writev(c, vecs, 2, phys_ofs, &length, 0); +- if (rc || totlen != length) { +- JFFS2_WARNING("jffs2_flash_writev()=%d, req=%u, wrote=%zu, at %#08x\n", +- rc, totlen, length, phys_ofs); +- rc = rc ? rc : -EIO; +- if (length) +- jffs2_add_physical_node_ref(c, phys_ofs | REF_OBSOLETE, PAD(totlen), NULL); +- +- return rc; +- } +- /* success */ +- jffs2_add_physical_node_ref(c, phys_ofs | REF_PRISTINE, PAD(totlen), (void *)xd); +- +- dbg_xattr("success on saving xdatum (xid=%u, version=%u, xprefix=%u, xname='%s')\n", +- xd->xid, xd->version, xd->xprefix, xd->xname); +- +- return 0; +-} +- +-static struct jffs2_xattr_datum *create_xattr_datum(struct jffs2_sb_info *c, +- int xprefix, const char *xname, +- const char *xvalue, int xsize) +-{ +- /* must be called under down_write(xattr_sem) */ +- struct jffs2_xattr_datum *xd; +- uint32_t hashkey, name_len; +- char *data; +- int i, rc; +- +- /* Search xattr_datum has same xname/xvalue by index */ +- hashkey = xattr_datum_hashkey(xprefix, xname, xvalue, xsize); +- i = hashkey % XATTRINDEX_HASHSIZE; +- list_for_each_entry(xd, &c->xattrindex[i], xindex) { +- if (xd->hashkey==hashkey +- && xd->xprefix==xprefix +- && xd->value_len==xsize +- && !strcmp(xd->xname, xname) +- && !memcmp(xd->xvalue, xvalue, xsize)) { +- atomic_inc(&xd->refcnt); +- return xd; +- } +- } +- +- /* Not found, Create NEW XATTR-Cache */ +- name_len = strlen(xname); +- +- xd = jffs2_alloc_xattr_datum(); +- if (!xd) +- return ERR_PTR(-ENOMEM); +- +- data = kmalloc(name_len + 1 + xsize, GFP_KERNEL); +- if (!data) { +- jffs2_free_xattr_datum(xd); +- return ERR_PTR(-ENOMEM); +- } +- strcpy(data, xname); +- memcpy(data + name_len + 1, xvalue, xsize); +- +- atomic_set(&xd->refcnt, 1); +- xd->xid = ++c->highest_xid; +- xd->flags |= JFFS2_XFLAGS_HOT; +- xd->xprefix = xprefix; +- +- xd->hashkey = hashkey; +- xd->xname = data; +- xd->xvalue = data + name_len + 1; +- xd->name_len = name_len; +- xd->value_len = xsize; +- xd->data_crc = crc32(0, data, xd->name_len + 1 + xd->value_len); +- +- rc = save_xattr_datum(c, xd); +- if (rc) { +- kfree(xd->xname); +- jffs2_free_xattr_datum(xd); +- return ERR_PTR(rc); +- } +- +- /* Insert Hash Index */ +- i = hashkey % XATTRINDEX_HASHSIZE; +- list_add(&xd->xindex, &c->xattrindex[i]); +- +- c->xdatum_mem_usage += (xd->name_len + 1 + xd->value_len); +- reclaim_xattr_datum(c); +- +- return xd; +-} +- +-static void unrefer_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd) +-{ +- /* must be called under down_write(xattr_sem) */ +- if (atomic_dec_and_lock(&xd->refcnt, &c->erase_completion_lock)) { +- unload_xattr_datum(c, xd); +- xd->flags |= JFFS2_XFLAGS_DEAD; +- if (xd->node == (void *)xd) { +- BUG_ON(!(xd->flags & JFFS2_XFLAGS_INVALID)); +- jffs2_free_xattr_datum(xd); +- } else { +- list_add(&xd->xindex, &c->xattr_dead_list); +- } +- spin_unlock(&c->erase_completion_lock); +- +- dbg_xattr("xdatum(xid=%u, version=%u) was removed.\n", +- xd->xid, xd->version); +- } +-} +- +-/* -------- xref related functions ------------------ +- * verify_xattr_ref(c, ref) +- * is used to load xref information from medium. Because summary data does not +- * contain xid/ino, it's necessary to verify once while mounting process. +- * save_xattr_ref(c, ref) +- * is used to write xref to medium. If delete marker is marked, it write +- * a delete marker of xref into medium. +- * create_xattr_ref(c, ic, xd) +- * is used to create a new xref and write to medium. +- * delete_xattr_ref(c, ref) +- * is used to delete jffs2_xattr_ref. It marks xref XREF_DELETE_MARKER, +- * and allows GC to reclaim those physical nodes. +- * jffs2_xattr_delete_inode(c, ic) +- * is called to remove xrefs related to obsolete inode when inode is unlinked. +- * jffs2_xattr_free_inode(c, ic) +- * is called to release xattr related objects when unmounting. +- * check_xattr_ref_inode(c, ic) +- * is used to confirm inode does not have duplicate xattr name/value pair. +- * jffs2_xattr_do_crccheck_inode(c, ic) +- * is used to force xattr data integrity check during the initial gc scan. +- * -------------------------------------------------- */ +-static int verify_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref) +-{ +- struct jffs2_eraseblock *jeb; +- struct jffs2_raw_node_ref *raw; +- struct jffs2_raw_xref rr; +- size_t readlen; +- uint32_t crc, offset, totlen; +- int rc; +- +- spin_lock(&c->erase_completion_lock); +- if (ref_flags(ref->node) != REF_UNCHECKED) +- goto complete; +- offset = ref_offset(ref->node); +- spin_unlock(&c->erase_completion_lock); +- +- rc = jffs2_flash_read(c, offset, sizeof(rr), &readlen, (char *)&rr); +- if (rc || sizeof(rr) != readlen) { +- JFFS2_WARNING("jffs2_flash_read()=%d, req=%zu, read=%zu, at %#08x\n", +- rc, sizeof(rr), readlen, offset); +- return rc ? rc : -EIO; +- } +- /* obsolete node */ +- crc = crc32(0, &rr, sizeof(rr) - 4); +- if (crc != je32_to_cpu(rr.node_crc)) { +- JFFS2_ERROR("node CRC failed at %#08x, read=%#08x, calc=%#08x\n", +- offset, je32_to_cpu(rr.node_crc), crc); +- return JFFS2_XATTR_IS_CORRUPTED; +- } +- if (je16_to_cpu(rr.magic) != JFFS2_MAGIC_BITMASK +- || je16_to_cpu(rr.nodetype) != JFFS2_NODETYPE_XREF +- || je32_to_cpu(rr.totlen) != PAD(sizeof(rr))) { +- JFFS2_ERROR("inconsistent xref at %#08x, magic=%#04x/%#04x, " +- "nodetype=%#04x/%#04x, totlen=%u/%zu\n", +- offset, je16_to_cpu(rr.magic), JFFS2_MAGIC_BITMASK, +- je16_to_cpu(rr.nodetype), JFFS2_NODETYPE_XREF, +- je32_to_cpu(rr.totlen), PAD(sizeof(rr))); +- return JFFS2_XATTR_IS_CORRUPTED; +- } +- ref->ino = je32_to_cpu(rr.ino); +- ref->xid = je32_to_cpu(rr.xid); +- ref->xseqno = je32_to_cpu(rr.xseqno); +- if (ref->xseqno > c->highest_xseqno) +- c->highest_xseqno = (ref->xseqno & ~XREF_DELETE_MARKER); +- +- spin_lock(&c->erase_completion_lock); +- complete: +- for (raw=ref->node; raw != (void *)ref; raw=raw->next_in_ino) { +- jeb = &c->blocks[ref_offset(raw) / c->sector_size]; +- totlen = PAD(ref_totlen(c, jeb, raw)); +- if (ref_flags(raw) == REF_UNCHECKED) { +- c->unchecked_size -= totlen; c->used_size += totlen; +- jeb->unchecked_size -= totlen; jeb->used_size += totlen; +- } +- raw->flash_offset = ref_offset(raw) | ((ref->node==raw) ? REF_PRISTINE : REF_NORMAL); +- } +- spin_unlock(&c->erase_completion_lock); +- +- dbg_xattr("success on verifying xref (ino=%u, xid=%u) at %#08x\n", +- ref->ino, ref->xid, ref_offset(ref->node)); +- return 0; +-} +- +-static int save_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref) +-{ +- /* must be called under down_write(xattr_sem) */ +- struct jffs2_raw_xref rr; +- size_t length; +- uint32_t xseqno, phys_ofs = write_ofs(c); +- int ret; +- +- rr.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); +- rr.nodetype = cpu_to_je16(JFFS2_NODETYPE_XREF); +- rr.totlen = cpu_to_je32(PAD(sizeof(rr))); +- rr.hdr_crc = cpu_to_je32(crc32(0, &rr, sizeof(struct jffs2_unknown_node) - 4)); +- +- xseqno = (c->highest_xseqno += 2); +- if (is_xattr_ref_dead(ref)) { +- xseqno |= XREF_DELETE_MARKER; +- rr.ino = cpu_to_je32(ref->ino); +- rr.xid = cpu_to_je32(ref->xid); +- } else { +- rr.ino = cpu_to_je32(ref->ic->ino); +- rr.xid = cpu_to_je32(ref->xd->xid); +- } +- rr.xseqno = cpu_to_je32(xseqno); +- rr.node_crc = cpu_to_je32(crc32(0, &rr, sizeof(rr) - 4)); +- +- ret = jffs2_flash_write(c, phys_ofs, sizeof(rr), &length, (char *)&rr); +- if (ret || sizeof(rr) != length) { +- JFFS2_WARNING("jffs2_flash_write() returned %d, request=%zu, retlen=%zu, at %#08x\n", +- ret, sizeof(rr), length, phys_ofs); +- ret = ret ? ret : -EIO; +- if (length) +- jffs2_add_physical_node_ref(c, phys_ofs | REF_OBSOLETE, PAD(sizeof(rr)), NULL); +- +- return ret; +- } +- /* success */ +- ref->xseqno = xseqno; +- jffs2_add_physical_node_ref(c, phys_ofs | REF_PRISTINE, PAD(sizeof(rr)), (void *)ref); +- +- dbg_xattr("success on saving xref (ino=%u, xid=%u)\n", ref->ic->ino, ref->xd->xid); +- +- return 0; +-} +- +-static struct jffs2_xattr_ref *create_xattr_ref(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic, +- struct jffs2_xattr_datum *xd) +-{ +- /* must be called under down_write(xattr_sem) */ +- struct jffs2_xattr_ref *ref; +- int ret; +- +- ref = jffs2_alloc_xattr_ref(); +- if (!ref) +- return ERR_PTR(-ENOMEM); +- ref->ic = ic; +- ref->xd = xd; +- +- ret = save_xattr_ref(c, ref); +- if (ret) { +- jffs2_free_xattr_ref(ref); +- return ERR_PTR(ret); +- } +- +- /* Chain to inode */ +- ref->next = ic->xref; +- ic->xref = ref; +- +- return ref; /* success */ +-} +- +-static void delete_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref) +-{ +- /* must be called under down_write(xattr_sem) */ +- struct jffs2_xattr_datum *xd; +- +- xd = ref->xd; +- ref->xseqno |= XREF_DELETE_MARKER; +- ref->ino = ref->ic->ino; +- ref->xid = ref->xd->xid; +- spin_lock(&c->erase_completion_lock); +- ref->next = c->xref_dead_list; +- c->xref_dead_list = ref; +- spin_unlock(&c->erase_completion_lock); +- +- dbg_xattr("xref(ino=%u, xid=%u, xseqno=%u) was removed.\n", +- ref->ino, ref->xid, ref->xseqno); +- +- unrefer_xattr_datum(c, xd); +-} +- +-void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic) +-{ +- /* It's called from jffs2_evict_inode() on inode removing. +- When an inode with XATTR is removed, those XATTRs must be removed. */ +- struct jffs2_xattr_ref *ref, *_ref; +- +- if (!ic || ic->pino_nlink > 0) +- return; +- +- down_write(&c->xattr_sem); +- for (ref = ic->xref; ref; ref = _ref) { +- _ref = ref->next; +- delete_xattr_ref(c, ref); +- } +- ic->xref = NULL; +- up_write(&c->xattr_sem); +-} +- +-void jffs2_xattr_free_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic) +-{ +- /* It's called from jffs2_free_ino_caches() until unmounting FS. */ +- struct jffs2_xattr_datum *xd; +- struct jffs2_xattr_ref *ref, *_ref; +- +- down_write(&c->xattr_sem); +- for (ref = ic->xref; ref; ref = _ref) { +- _ref = ref->next; +- xd = ref->xd; +- if (atomic_dec_and_test(&xd->refcnt)) { +- unload_xattr_datum(c, xd); +- jffs2_free_xattr_datum(xd); +- } +- jffs2_free_xattr_ref(ref); +- } +- ic->xref = NULL; +- up_write(&c->xattr_sem); +-} +- +-static int check_xattr_ref_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic) +-{ +- /* success of check_xattr_ref_inode() means that inode (ic) dose not have +- * duplicate name/value pairs. If duplicate name/value pair would be found, +- * one will be removed. +- */ +- struct jffs2_xattr_ref *ref, *cmp, **pref, **pcmp; +- int rc = 0; +- +- if (likely(ic->flags & INO_FLAGS_XATTR_CHECKED)) +- return 0; +- down_write(&c->xattr_sem); +- retry: +- rc = 0; +- for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) { +- if (!ref->xd->xname) { +- rc = load_xattr_datum(c, ref->xd); +- if (unlikely(rc > 0)) { +- *pref = ref->next; +- delete_xattr_ref(c, ref); +- goto retry; +- } else if (unlikely(rc < 0)) +- goto out; +- } +- for (cmp=ref->next, pcmp=&ref->next; cmp; pcmp=&cmp->next, cmp=cmp->next) { +- if (!cmp->xd->xname) { +- ref->xd->flags |= JFFS2_XFLAGS_BIND; +- rc = load_xattr_datum(c, cmp->xd); +- ref->xd->flags &= ~JFFS2_XFLAGS_BIND; +- if (unlikely(rc > 0)) { +- *pcmp = cmp->next; +- delete_xattr_ref(c, cmp); +- goto retry; +- } else if (unlikely(rc < 0)) +- goto out; +- } +- if (ref->xd->xprefix == cmp->xd->xprefix +- && !strcmp(ref->xd->xname, cmp->xd->xname)) { +- if (ref->xseqno > cmp->xseqno) { +- *pcmp = cmp->next; +- delete_xattr_ref(c, cmp); +- } else { +- *pref = ref->next; +- delete_xattr_ref(c, ref); +- } +- goto retry; +- } +- } +- } +- ic->flags |= INO_FLAGS_XATTR_CHECKED; +- out: +- up_write(&c->xattr_sem); +- +- return rc; +-} +- +-void jffs2_xattr_do_crccheck_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic) +-{ +- check_xattr_ref_inode(c, ic); +-} +- +-/* -------- xattr subsystem functions --------------- +- * jffs2_init_xattr_subsystem(c) +- * is used to initialize semaphore and list_head, and some variables. +- * jffs2_find_xattr_datum(c, xid) +- * is used to lookup xdatum while scanning process. +- * jffs2_clear_xattr_subsystem(c) +- * is used to release any xattr related objects. +- * jffs2_build_xattr_subsystem(c) +- * is used to associate xdatum and xref while super block building process. +- * jffs2_setup_xattr_datum(c, xid, version) +- * is used to insert xdatum while scanning process. +- * -------------------------------------------------- */ +-void jffs2_init_xattr_subsystem(struct jffs2_sb_info *c) +-{ +- int i; +- +- for (i=0; i < XATTRINDEX_HASHSIZE; i++) +- INIT_LIST_HEAD(&c->xattrindex[i]); +- INIT_LIST_HEAD(&c->xattr_unchecked); +- INIT_LIST_HEAD(&c->xattr_dead_list); +- c->xref_dead_list = NULL; +- c->xref_temp = NULL; +- +- init_rwsem(&c->xattr_sem); +- c->highest_xid = 0; +- c->highest_xseqno = 0; +- c->xdatum_mem_usage = 0; +- c->xdatum_mem_threshold = 32 * 1024; /* Default 32KB */ +-} +- +-static struct jffs2_xattr_datum *jffs2_find_xattr_datum(struct jffs2_sb_info *c, uint32_t xid) +-{ +- struct jffs2_xattr_datum *xd; +- int i = xid % XATTRINDEX_HASHSIZE; +- +- /* It's only used in scanning/building process. */ +- BUG_ON(!(c->flags & (JFFS2_SB_FLAG_SCANNING|JFFS2_SB_FLAG_BUILDING))); +- +- list_for_each_entry(xd, &c->xattrindex[i], xindex) { +- if (xd->xid==xid) +- return xd; +- } +- return NULL; +-} +- +-void jffs2_clear_xattr_subsystem(struct jffs2_sb_info *c) +-{ +- struct jffs2_xattr_datum *xd, *_xd; +- struct jffs2_xattr_ref *ref, *_ref; +- int i; +- +- for (ref=c->xref_temp; ref; ref = _ref) { +- _ref = ref->next; +- jffs2_free_xattr_ref(ref); +- } +- +- for (ref=c->xref_dead_list; ref; ref = _ref) { +- _ref = ref->next; +- jffs2_free_xattr_ref(ref); +- } +- +- for (i=0; i < XATTRINDEX_HASHSIZE; i++) { +- list_for_each_entry_safe(xd, _xd, &c->xattrindex[i], xindex) { +- list_del(&xd->xindex); +- kfree(xd->xname); +- jffs2_free_xattr_datum(xd); +- } +- } +- +- list_for_each_entry_safe(xd, _xd, &c->xattr_dead_list, xindex) { +- list_del(&xd->xindex); +- jffs2_free_xattr_datum(xd); +- } +- list_for_each_entry_safe(xd, _xd, &c->xattr_unchecked, xindex) { +- list_del(&xd->xindex); +- jffs2_free_xattr_datum(xd); +- } +-} +- +-#define XREF_TMPHASH_SIZE (128) +-void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c) +-{ +- struct jffs2_xattr_ref *ref, *_ref; +- struct jffs2_xattr_ref *xref_tmphash[XREF_TMPHASH_SIZE]; +- struct jffs2_xattr_datum *xd, *_xd; +- struct jffs2_inode_cache *ic; +- struct jffs2_raw_node_ref *raw; +- int i, xdatum_count = 0, xdatum_unchecked_count = 0, xref_count = 0; +- int xdatum_orphan_count = 0, xref_orphan_count = 0, xref_dead_count = 0; +- +- BUG_ON(!(c->flags & JFFS2_SB_FLAG_BUILDING)); +- +- /* Phase.1 : Merge same xref */ +- for (i=0; i < XREF_TMPHASH_SIZE; i++) +- xref_tmphash[i] = NULL; +- for (ref=c->xref_temp; ref; ref=_ref) { +- struct jffs2_xattr_ref *tmp; +- +- _ref = ref->next; +- if (ref_flags(ref->node) != REF_PRISTINE) { +- if (verify_xattr_ref(c, ref)) { +- BUG_ON(ref->node->next_in_ino != (void *)ref); +- ref->node->next_in_ino = NULL; +- jffs2_mark_node_obsolete(c, ref->node); +- jffs2_free_xattr_ref(ref); +- continue; +- } +- } +- +- i = (ref->ino ^ ref->xid) % XREF_TMPHASH_SIZE; +- for (tmp=xref_tmphash[i]; tmp; tmp=tmp->next) { +- if (tmp->ino == ref->ino && tmp->xid == ref->xid) +- break; +- } +- if (tmp) { +- raw = ref->node; +- if (ref->xseqno > tmp->xseqno) { +- tmp->xseqno = ref->xseqno; +- raw->next_in_ino = tmp->node; +- tmp->node = raw; +- } else { +- raw->next_in_ino = tmp->node->next_in_ino; +- tmp->node->next_in_ino = raw; +- } +- jffs2_free_xattr_ref(ref); +- continue; +- } else { +- ref->next = xref_tmphash[i]; +- xref_tmphash[i] = ref; +- } +- } +- c->xref_temp = NULL; +- +- /* Phase.2 : Bind xref with inode_cache and xattr_datum */ +- for (i=0; i < XREF_TMPHASH_SIZE; i++) { +- for (ref=xref_tmphash[i]; ref; ref=_ref) { +- xref_count++; +- _ref = ref->next; +- if (is_xattr_ref_dead(ref)) { +- ref->next = c->xref_dead_list; +- c->xref_dead_list = ref; +- xref_dead_count++; +- continue; +- } +- /* At this point, ref->xid and ref->ino contain XID and inode number. +- ref->xd and ref->ic are not valid yet. */ +- xd = jffs2_find_xattr_datum(c, ref->xid); +- ic = jffs2_get_ino_cache(c, ref->ino); +- if (!xd || !ic || !ic->pino_nlink) { +- dbg_xattr("xref(ino=%u, xid=%u, xseqno=%u) is orphan.\n", +- ref->ino, ref->xid, ref->xseqno); +- ref->xseqno |= XREF_DELETE_MARKER; +- ref->next = c->xref_dead_list; +- c->xref_dead_list = ref; +- xref_orphan_count++; +- continue; +- } +- ref->xd = xd; +- ref->ic = ic; +- atomic_inc(&xd->refcnt); +- ref->next = ic->xref; +- ic->xref = ref; +- } +- } +- +- /* Phase.3 : Link unchecked xdatum to xattr_unchecked list */ +- for (i=0; i < XATTRINDEX_HASHSIZE; i++) { +- list_for_each_entry_safe(xd, _xd, &c->xattrindex[i], xindex) { +- xdatum_count++; +- list_del_init(&xd->xindex); +- if (!atomic_read(&xd->refcnt)) { +- dbg_xattr("xdatum(xid=%u, version=%u) is orphan.\n", +- xd->xid, xd->version); +- xd->flags |= JFFS2_XFLAGS_DEAD; +- list_add(&xd->xindex, &c->xattr_unchecked); +- xdatum_orphan_count++; +- continue; +- } +- if (is_xattr_datum_unchecked(c, xd)) { +- dbg_xattr("unchecked xdatum(xid=%u, version=%u)\n", +- xd->xid, xd->version); +- list_add(&xd->xindex, &c->xattr_unchecked); +- xdatum_unchecked_count++; +- } +- } +- } +- /* build complete */ +- JFFS2_NOTICE("complete building xattr subsystem, %u of xdatum" +- " (%u unchecked, %u orphan) and " +- "%u of xref (%u dead, %u orphan) found.\n", +- xdatum_count, xdatum_unchecked_count, xdatum_orphan_count, +- xref_count, xref_dead_count, xref_orphan_count); +-} +- +-struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c, +- uint32_t xid, uint32_t version) +-{ +- struct jffs2_xattr_datum *xd; +- +- xd = jffs2_find_xattr_datum(c, xid); +- if (!xd) { +- xd = jffs2_alloc_xattr_datum(); +- if (!xd) +- return ERR_PTR(-ENOMEM); +- xd->xid = xid; +- xd->version = version; +- if (xd->xid > c->highest_xid) +- c->highest_xid = xd->xid; +- list_add_tail(&xd->xindex, &c->xattrindex[xid % XATTRINDEX_HASHSIZE]); +- } +- return xd; +-} +- +-/* -------- xattr subsystem functions --------------- +- * xprefix_to_handler(xprefix) +- * is used to translate xprefix into xattr_handler. +- * jffs2_listxattr(dentry, buffer, size) +- * is an implementation of listxattr handler on jffs2. +- * do_jffs2_getxattr(inode, xprefix, xname, buffer, size) +- * is an implementation of getxattr handler on jffs2. +- * do_jffs2_setxattr(inode, xprefix, xname, buffer, size, flags) +- * is an implementation of setxattr handler on jffs2. +- * -------------------------------------------------- */ +-const struct xattr_handler *jffs2_xattr_handlers[] = { +- &jffs2_user_xattr_handler, +-#ifdef CONFIG_JFFS2_FS_SECURITY +- &jffs2_security_xattr_handler, +-#endif +-#ifdef CONFIG_JFFS2_FS_POSIX_ACL +- &posix_acl_access_xattr_handler, +- &posix_acl_default_xattr_handler, +-#endif +- &jffs2_trusted_xattr_handler, +- NULL +-}; +- +-static const struct xattr_handler *xprefix_to_handler(int xprefix) { +- const struct xattr_handler *ret; +- +- switch (xprefix) { +- case JFFS2_XPREFIX_USER: +- ret = &jffs2_user_xattr_handler; +- break; +-#ifdef CONFIG_JFFS2_FS_SECURITY +- case JFFS2_XPREFIX_SECURITY: +- ret = &jffs2_security_xattr_handler; +- break; +-#endif +-#ifdef CONFIG_JFFS2_FS_POSIX_ACL +- case JFFS2_XPREFIX_ACL_ACCESS: +- ret = &posix_acl_access_xattr_handler; +- break; +- case JFFS2_XPREFIX_ACL_DEFAULT: +- ret = &posix_acl_default_xattr_handler; +- break; +-#endif +- case JFFS2_XPREFIX_TRUSTED: +- ret = &jffs2_trusted_xattr_handler; +- break; +- default: +- ret = NULL; +- break; +- } +- return ret; +-} +- +-ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size) +-{ +- struct inode *inode = d_inode(dentry); +- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); +- struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); +- struct jffs2_inode_cache *ic = f->inocache; +- struct jffs2_xattr_ref *ref, **pref; +- struct jffs2_xattr_datum *xd; +- const struct xattr_handler *xhandle; +- const char *prefix; +- ssize_t prefix_len, len, rc; +- int retry = 0; +- +- rc = check_xattr_ref_inode(c, ic); +- if (unlikely(rc)) +- return rc; +- +- down_read(&c->xattr_sem); +- retry: +- len = 0; +- for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) { +- BUG_ON(ref->ic != ic); +- xd = ref->xd; +- if (!xd->xname) { +- /* xdatum is unchached */ +- if (!retry) { +- retry = 1; +- up_read(&c->xattr_sem); +- down_write(&c->xattr_sem); +- goto retry; +- } else { +- rc = load_xattr_datum(c, xd); +- if (unlikely(rc > 0)) { +- *pref = ref->next; +- delete_xattr_ref(c, ref); +- goto retry; +- } else if (unlikely(rc < 0)) +- goto out; +- } +- } +- xhandle = xprefix_to_handler(xd->xprefix); +- if (!xhandle || (xhandle->list && !xhandle->list(dentry))) +- continue; +- prefix = xhandle->prefix ?: xhandle->name; +- prefix_len = strlen(prefix); +- rc = prefix_len + xd->name_len + 1; +- +- if (buffer) { +- if (rc > size - len) { +- rc = -ERANGE; +- goto out; +- } +- memcpy(buffer, prefix, prefix_len); +- buffer += prefix_len; +- memcpy(buffer, xd->xname, xd->name_len); +- buffer += xd->name_len; +- *buffer++ = 0; +- } +- len += rc; +- } +- rc = len; +- out: +- if (!retry) { +- up_read(&c->xattr_sem); +- } else { +- up_write(&c->xattr_sem); +- } +- return rc; +-} +- +-int do_jffs2_getxattr(struct inode *inode, int xprefix, const char *xname, +- char *buffer, size_t size) +-{ +- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); +- struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); +- struct jffs2_inode_cache *ic = f->inocache; +- struct jffs2_xattr_datum *xd; +- struct jffs2_xattr_ref *ref, **pref; +- int rc, retry = 0; +- +- rc = check_xattr_ref_inode(c, ic); +- if (unlikely(rc)) +- return rc; +- +- down_read(&c->xattr_sem); +- retry: +- for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) { +- BUG_ON(ref->ic!=ic); +- +- xd = ref->xd; +- if (xd->xprefix != xprefix) +- continue; +- if (!xd->xname) { +- /* xdatum is unchached */ +- if (!retry) { +- retry = 1; +- up_read(&c->xattr_sem); +- down_write(&c->xattr_sem); +- goto retry; +- } else { +- rc = load_xattr_datum(c, xd); +- if (unlikely(rc > 0)) { +- *pref = ref->next; +- delete_xattr_ref(c, ref); +- goto retry; +- } else if (unlikely(rc < 0)) { +- goto out; +- } +- } +- } +- if (!strcmp(xname, xd->xname)) { +- rc = xd->value_len; +- if (buffer) { +- if (size < rc) { +- rc = -ERANGE; +- } else { +- memcpy(buffer, xd->xvalue, rc); +- } +- } +- goto out; +- } +- } +- rc = -ENODATA; +- out: +- if (!retry) { +- up_read(&c->xattr_sem); +- } else { +- up_write(&c->xattr_sem); +- } +- return rc; +-} +- +-int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname, +- const char *buffer, size_t size, int flags) +-{ +- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); +- struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); +- struct jffs2_inode_cache *ic = f->inocache; +- struct jffs2_xattr_datum *xd; +- struct jffs2_xattr_ref *ref, *newref, **pref; +- uint32_t length, request; +- int rc; +- +- rc = check_xattr_ref_inode(c, ic); +- if (unlikely(rc)) +- return rc; +- +- request = PAD(sizeof(struct jffs2_raw_xattr) + strlen(xname) + 1 + size); +- rc = jffs2_reserve_space(c, request, &length, +- ALLOC_NORMAL, JFFS2_SUMMARY_XATTR_SIZE); +- if (rc) { +- JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, request); +- return rc; +- } +- +- /* Find existing xattr */ +- down_write(&c->xattr_sem); +- retry: +- for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) { +- xd = ref->xd; +- if (xd->xprefix != xprefix) +- continue; +- if (!xd->xname) { +- rc = load_xattr_datum(c, xd); +- if (unlikely(rc > 0)) { +- *pref = ref->next; +- delete_xattr_ref(c, ref); +- goto retry; +- } else if (unlikely(rc < 0)) +- goto out; +- } +- if (!strcmp(xd->xname, xname)) { +- if (flags & XATTR_CREATE) { +- rc = -EEXIST; +- goto out; +- } +- if (!buffer) { +- ref->ino = ic->ino; +- ref->xid = xd->xid; +- ref->xseqno |= XREF_DELETE_MARKER; +- rc = save_xattr_ref(c, ref); +- if (!rc) { +- *pref = ref->next; +- spin_lock(&c->erase_completion_lock); +- ref->next = c->xref_dead_list; +- c->xref_dead_list = ref; +- spin_unlock(&c->erase_completion_lock); +- unrefer_xattr_datum(c, xd); +- } else { +- ref->ic = ic; +- ref->xd = xd; +- ref->xseqno &= ~XREF_DELETE_MARKER; +- } +- goto out; +- } +- goto found; +- } +- } +- /* not found */ +- if (flags & XATTR_REPLACE) { +- rc = -ENODATA; +- goto out; +- } +- if (!buffer) { +- rc = -ENODATA; +- goto out; +- } +- found: +- xd = create_xattr_datum(c, xprefix, xname, buffer, size); +- if (IS_ERR(xd)) { +- rc = PTR_ERR(xd); +- goto out; +- } +- up_write(&c->xattr_sem); +- jffs2_complete_reservation(c); +- +- /* create xattr_ref */ +- request = PAD(sizeof(struct jffs2_raw_xref)); +- rc = jffs2_reserve_space(c, request, &length, +- ALLOC_NORMAL, JFFS2_SUMMARY_XREF_SIZE); +- down_write(&c->xattr_sem); +- if (rc) { +- JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, request); +- unrefer_xattr_datum(c, xd); +- up_write(&c->xattr_sem); +- return rc; +- } +- if (ref) +- *pref = ref->next; +- newref = create_xattr_ref(c, ic, xd); +- if (IS_ERR(newref)) { +- if (ref) { +- ref->next = ic->xref; +- ic->xref = ref; +- } +- rc = PTR_ERR(newref); +- unrefer_xattr_datum(c, xd); +- } else if (ref) { +- delete_xattr_ref(c, ref); +- } +- out: +- up_write(&c->xattr_sem); +- jffs2_complete_reservation(c); +- return rc; +-} +- +-/* -------- garbage collector functions ------------- +- * jffs2_garbage_collect_xattr_datum(c, xd, raw) +- * is used to move xdatum into new node. +- * jffs2_garbage_collect_xattr_ref(c, ref, raw) +- * is used to move xref into new node. +- * jffs2_verify_xattr(c) +- * is used to call do_verify_xattr_datum() before garbage collecting. +- * jffs2_release_xattr_datum(c, xd) +- * is used to release an in-memory object of xdatum. +- * jffs2_release_xattr_ref(c, ref) +- * is used to release an in-memory object of xref. +- * -------------------------------------------------- */ +-int jffs2_garbage_collect_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd, +- struct jffs2_raw_node_ref *raw) +-{ +- uint32_t totlen, length, old_ofs; +- int rc = 0; +- +- down_write(&c->xattr_sem); +- if (xd->node != raw) +- goto out; +- if (xd->flags & (JFFS2_XFLAGS_DEAD|JFFS2_XFLAGS_INVALID)) +- goto out; +- +- rc = load_xattr_datum(c, xd); +- if (unlikely(rc)) { +- rc = (rc > 0) ? 0 : rc; +- goto out; +- } +- old_ofs = ref_offset(xd->node); +- totlen = PAD(sizeof(struct jffs2_raw_xattr) +- + xd->name_len + 1 + xd->value_len); +- rc = jffs2_reserve_space_gc(c, totlen, &length, JFFS2_SUMMARY_XATTR_SIZE); +- if (rc) { +- JFFS2_WARNING("jffs2_reserve_space_gc()=%d, request=%u\n", rc, totlen); +- goto out; +- } +- rc = save_xattr_datum(c, xd); +- if (!rc) +- dbg_xattr("xdatum (xid=%u, version=%u) GC'ed from %#08x to %08x\n", +- xd->xid, xd->version, old_ofs, ref_offset(xd->node)); +- out: +- if (!rc) +- jffs2_mark_node_obsolete(c, raw); +- up_write(&c->xattr_sem); +- return rc; +-} +- +-int jffs2_garbage_collect_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref, +- struct jffs2_raw_node_ref *raw) +-{ +- uint32_t totlen, length, old_ofs; +- int rc = 0; +- +- down_write(&c->xattr_sem); +- BUG_ON(!ref->node); +- +- if (ref->node != raw) +- goto out; +- if (is_xattr_ref_dead(ref) && (raw->next_in_ino == (void *)ref)) +- goto out; +- +- old_ofs = ref_offset(ref->node); +- totlen = ref_totlen(c, c->gcblock, ref->node); +- +- rc = jffs2_reserve_space_gc(c, totlen, &length, JFFS2_SUMMARY_XREF_SIZE); +- if (rc) { +- JFFS2_WARNING("%s: jffs2_reserve_space_gc() = %d, request = %u\n", +- __func__, rc, totlen); +- goto out; +- } +- rc = save_xattr_ref(c, ref); +- if (!rc) +- dbg_xattr("xref (ino=%u, xid=%u) GC'ed from %#08x to %08x\n", +- ref->ic->ino, ref->xd->xid, old_ofs, ref_offset(ref->node)); +- out: +- if (!rc) +- jffs2_mark_node_obsolete(c, raw); +- up_write(&c->xattr_sem); +- return rc; +-} +- +-int jffs2_verify_xattr(struct jffs2_sb_info *c) +-{ +- struct jffs2_xattr_datum *xd, *_xd; +- struct jffs2_eraseblock *jeb; +- struct jffs2_raw_node_ref *raw; +- uint32_t totlen; +- int rc; +- +- down_write(&c->xattr_sem); +- list_for_each_entry_safe(xd, _xd, &c->xattr_unchecked, xindex) { +- rc = do_verify_xattr_datum(c, xd); +- if (rc < 0) +- continue; +- list_del_init(&xd->xindex); +- spin_lock(&c->erase_completion_lock); +- for (raw=xd->node; raw != (void *)xd; raw=raw->next_in_ino) { +- if (ref_flags(raw) != REF_UNCHECKED) +- continue; +- jeb = &c->blocks[ref_offset(raw) / c->sector_size]; +- totlen = PAD(ref_totlen(c, jeb, raw)); +- c->unchecked_size -= totlen; c->used_size += totlen; +- jeb->unchecked_size -= totlen; jeb->used_size += totlen; +- raw->flash_offset = ref_offset(raw) +- | ((xd->node == (void *)raw) ? REF_PRISTINE : REF_NORMAL); +- } +- if (xd->flags & JFFS2_XFLAGS_DEAD) +- list_add(&xd->xindex, &c->xattr_dead_list); +- spin_unlock(&c->erase_completion_lock); +- } +- up_write(&c->xattr_sem); +- return list_empty(&c->xattr_unchecked) ? 1 : 0; +-} +- +-void jffs2_release_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd) +-{ +- /* must be called under spin_lock(&c->erase_completion_lock) */ +- if (atomic_read(&xd->refcnt) || xd->node != (void *)xd) +- return; +- +- list_del(&xd->xindex); +- jffs2_free_xattr_datum(xd); +-} +- +-void jffs2_release_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref) +-{ +- /* must be called under spin_lock(&c->erase_completion_lock) */ +- struct jffs2_xattr_ref *tmp, **ptmp; +- +- if (ref->node != (void *)ref) +- return; +- +- for (tmp=c->xref_dead_list, ptmp=&c->xref_dead_list; tmp; ptmp=&tmp->next, tmp=tmp->next) { +- if (ref == tmp) { +- *ptmp = tmp->next; +- break; +- } +- } +- jffs2_free_xattr_ref(ref); +-} +diff -Nupr old/fs/jffs2/xattr.h new/fs/jffs2/xattr.h +--- old/fs/jffs2/xattr.h 2022-05-09 17:22:53.000000000 +0800 ++++ new/fs/jffs2/xattr.h 2022-05-09 20:04:55.580000000 +0800 +@@ -12,7 +12,6 @@ + #ifndef _JFFS2_FS_XATTR_H_ + #define _JFFS2_FS_XATTR_H_ + +-#include + #include + + #define JFFS2_XFLAGS_HOT (0x01) /* This datum is HOT */ +@@ -48,7 +47,7 @@ struct jffs2_xattr_ref + struct jffs2_raw_node_ref *node; + uint8_t class; + uint8_t flags; /* Currently unused */ +- u16 unused; ++ uint16_t unused; + + uint32_t xseqno; + union { +@@ -89,16 +88,14 @@ extern int jffs2_verify_xattr(struct jff + extern void jffs2_release_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd); + extern void jffs2_release_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref); + +-extern int do_jffs2_getxattr(struct inode *inode, int xprefix, const char *xname, +- char *buffer, size_t size); +-extern int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname, +- const char *buffer, size_t size, int flags); +- + extern const struct xattr_handler *jffs2_xattr_handlers[]; + extern const struct xattr_handler jffs2_user_xattr_handler; + extern const struct xattr_handler jffs2_trusted_xattr_handler; + + extern ssize_t jffs2_listxattr(struct dentry *, char *, size_t); ++#define jffs2_getxattr generic_getxattr ++#define jffs2_setxattr generic_setxattr ++#define jffs2_removexattr generic_removexattr + + #else + +@@ -113,12 +110,13 @@ extern ssize_t jffs2_listxattr(struct de + + #define jffs2_xattr_handlers NULL + #define jffs2_listxattr NULL ++#define jffs2_getxattr NULL ++#define jffs2_setxattr NULL ++#define jffs2_removexattr NULL + + #endif /* CONFIG_JFFS2_FS_XATTR */ + + #ifdef CONFIG_JFFS2_FS_SECURITY +-extern int jffs2_init_security(struct inode *inode, struct inode *dir, +- const struct qstr *qstr); + extern const struct xattr_handler jffs2_security_xattr_handler; + #else + #define jffs2_init_security(inode,dir,qstr) (0) +diff -Nupr old/fs/jffs2/xattr_trusted.c new/fs/jffs2/xattr_trusted.c +--- old/fs/jffs2/xattr_trusted.c 2022-05-09 17:15:24.360000000 +0800 ++++ new/fs/jffs2/xattr_trusted.c 1970-01-01 08:00:00.000000000 +0800 +@@ -1,46 +0,0 @@ +-/* +- * JFFS2 -- Journalling Flash File System, Version 2. +- * +- * Copyright © 2006 NEC Corporation +- * +- * Created by KaiGai Kohei +- * +- * For licensing information, see the file 'LICENCE' in this directory. +- * +- */ +- +-#include +-#include +-#include +-#include +-#include +-#include "nodelist.h" +- +-static int jffs2_trusted_getxattr(const struct xattr_handler *handler, +- struct dentry *unused, struct inode *inode, +- const char *name, void *buffer, size_t size) +-{ +- return do_jffs2_getxattr(inode, JFFS2_XPREFIX_TRUSTED, +- name, buffer, size); +-} +- +-static int jffs2_trusted_setxattr(const struct xattr_handler *handler, +- struct dentry *unused, struct inode *inode, +- const char *name, const void *buffer, +- size_t size, int flags) +-{ +- return do_jffs2_setxattr(inode, JFFS2_XPREFIX_TRUSTED, +- name, buffer, size, flags); +-} +- +-static bool jffs2_trusted_listxattr(struct dentry *dentry) +-{ +- return capable(CAP_SYS_ADMIN); +-} +- +-const struct xattr_handler jffs2_trusted_xattr_handler = { +- .prefix = XATTR_TRUSTED_PREFIX, +- .list = jffs2_trusted_listxattr, +- .set = jffs2_trusted_setxattr, +- .get = jffs2_trusted_getxattr +-}; +diff -Nupr old/fs/jffs2/xattr_user.c new/fs/jffs2/xattr_user.c +--- old/fs/jffs2/xattr_user.c 2022-05-09 17:15:24.360000000 +0800 ++++ new/fs/jffs2/xattr_user.c 1970-01-01 08:00:00.000000000 +0800 +@@ -1,40 +0,0 @@ +-/* +- * JFFS2 -- Journalling Flash File System, Version 2. +- * +- * Copyright © 2006 NEC Corporation +- * +- * Created by KaiGai Kohei +- * +- * For licensing information, see the file 'LICENCE' in this directory. +- * +- */ +- +-#include +-#include +-#include +-#include +-#include +-#include "nodelist.h" +- +-static int jffs2_user_getxattr(const struct xattr_handler *handler, +- struct dentry *unused, struct inode *inode, +- const char *name, void *buffer, size_t size) +-{ +- return do_jffs2_getxattr(inode, JFFS2_XPREFIX_USER, +- name, buffer, size); +-} +- +-static int jffs2_user_setxattr(const struct xattr_handler *handler, +- struct dentry *unused, struct inode *inode, +- const char *name, const void *buffer, +- size_t size, int flags) +-{ +- return do_jffs2_setxattr(inode, JFFS2_XPREFIX_USER, +- name, buffer, size, flags); +-} +- +-const struct xattr_handler jffs2_user_xattr_handler = { +- .prefix = XATTR_USER_PREFIX, +- .set = jffs2_user_setxattr, +- .get = jffs2_user_getxattr +-}; diff --git a/src/kernel_liteos_a/fs/jffs2/src/jffs2_hash.c b/src/kernel_liteos_a/fs/jffs2/src/jffs2_hash.c new file mode 100644 index 00000000..6e5d5919 --- /dev/null +++ b/src/kernel_liteos_a/fs/jffs2/src/jffs2_hash.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "jffs2_hash.h" + +#ifdef LOSCFG_FS_JFFS + +int Jffs2HashInit(LosMux *lock, LOS_DL_LIST *heads) +{ + int ret; + for (int i = 0; i < JFFS2_NODE_HASH_BUCKETS; i++) { + LOS_ListInit(&heads[i]); + } + + ret = LOS_MuxInit(lock, NULL); + if (ret != LOS_OK) { + PRINT_ERR("Create mutex for vnode hash list fail, status: %d", ret); + return ret; + } + + return LOS_OK; +} + +int Jffs2HashDeinit(LosMux *lock) +{ + int ret; + ret = LOS_MuxDestroy(lock); + if (ret != LOS_OK) { + PRINT_ERR("Destroy mutex for vnode hash list fail, status: %d", ret); + return ret; + } + + return LOS_OK; +} + +void Jffs2HashDump(LosMux *lock, LOS_DL_LIST *heads) +{ + PRINTK("-------->Jffs2HashDump in\n"); + (void)LOS_MuxLock(lock, LOS_WAIT_FOREVER); + for (int i = 0; i < JFFS2_NODE_HASH_BUCKETS; i++) { + LIST_HEAD *nhead = &heads[i]; + struct jffs2_inode *node = NULL; + + LOS_DL_LIST_FOR_EACH_ENTRY(node, nhead, struct jffs2_inode, i_hashlist) { + PRINTK(" vnode dump: col %d item %p\n", i, node); + } + } + (void)LOS_MuxUnlock(lock); + PRINTK("-------->Jffs2HashDump out\n"); +} + +static LOS_DL_LIST *Jffs2HashBucket(LOS_DL_LIST *heads, const uint32_t ino) +{ + LOS_DL_LIST *head = &(heads[ino & JFFS2_NODE_HASH_MASK]); + return head; +} + +int Jffs2HashGet(LosMux *lock, LOS_DL_LIST *heads, const void *sb, const uint32_t ino, struct jffs2_inode **ppNode) +{ + struct jffs2_inode *node = NULL; + + while (1) { + (void)LOS_MuxLock(lock, LOS_WAIT_FOREVER); + LOS_DL_LIST *list = Jffs2HashBucket(heads, ino); + LOS_DL_LIST_FOR_EACH_ENTRY(node, list, struct jffs2_inode, i_hashlist) { + if (node->i_ino != ino) + continue; + if (node->i_sb != sb) + continue; + (void)LOS_MuxUnlock(lock); + *ppNode = node; + return 0; + } + (void)LOS_MuxUnlock(lock); + *ppNode = NULL; + return 0; + } +} + +void Jffs2HashRemove(LosMux *lock, struct jffs2_inode *node) +{ + (void)LOS_MuxLock(lock, LOS_WAIT_FOREVER); + LOS_ListDelete(&node->i_hashlist); + (void)LOS_MuxUnlock(lock); +} + +int Jffs2HashInsert(LosMux *lock, LOS_DL_LIST *heads, struct jffs2_inode *node, const uint32_t ino) +{ + (void)LOS_MuxLock(lock, LOS_WAIT_FOREVER); + LOS_ListHeadInsert(Jffs2HashBucket(heads, ino), &node->i_hashlist); + (void)LOS_MuxUnlock(lock); + return 0; +} + +#endif + diff --git a/src/kernel_liteos_a/fs/jffs2/src/vfs_jffs2.c b/src/kernel_liteos_a/fs/jffs2/src/vfs_jffs2.c new file mode 100644 index 00000000..a67ed280 --- /dev/null +++ b/src/kernel_liteos_a/fs/jffs2/src/vfs_jffs2.c @@ -0,0 +1,985 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "vfs_jffs2.h" + +#include "fcntl.h" +#include "sys/stat.h" +#include "sys/statfs.h" +#include "errno.h" + +#include "los_config.h" +#include "los_typedef.h" +#include "los_mux.h" +#include "los_tables.h" +#include "los_vm_filemap.h" +#include "los_crc32.h" +#include "capability_type.h" +#include "capability_api.h" + +#include "fs/dirent_fs.h" +#include "fs/fs.h" +#include "fs/driver.h" +#include "vnode.h" +#include "mtd_list.h" +#include "mtd_partition.h" +#include "jffs2_hash.h" + +#include "os-linux.h" +#include "jffs2/nodelist.h" + +#ifdef LOSCFG_FS_JFFS + +/* forward define */ +struct VnodeOps g_jffs2Vops; +struct file_operations_vfs g_jffs2Fops; + +static LosMux g_jffs2FsLock; /* lock for all jffs2 ops */ + +static pthread_mutex_t g_jffs2NodeLock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; +struct Vnode *g_jffs2PartList[CONFIG_MTD_PATTITION_NUM]; + +static void Jffs2SetVtype(struct jffs2_inode *node, struct Vnode *pVnode) +{ + switch (node->i_mode & S_IFMT) { + case S_IFREG: + pVnode->type = VNODE_TYPE_REG; + break; + case S_IFDIR: + pVnode->type = VNODE_TYPE_DIR; + break; + case S_IFLNK: + pVnode->type = VNODE_TYPE_LNK; + break; + default: + pVnode->type = VNODE_TYPE_UNKNOWN; + break; + } +} + +time_t Jffs2CurSec(void) +{ + struct timeval tv; + if (gettimeofday(&tv, NULL)) + return 0; + return (uint32_t)(tv.tv_sec); +} + +void Jffs2NodeLock(void) +{ + (void)pthread_mutex_lock(&g_jffs2NodeLock); +} + +void Jffs2NodeUnlock(void) +{ + (void)pthread_mutex_unlock(&g_jffs2NodeLock); +} + +int VfsJffs2Bind(struct Mount *mnt, struct Vnode *blkDriver, const void *data) +{ + int ret; + int partNo; + mtd_partition *p = NULL; + struct MtdDev *mtd = NULL; + struct Vnode *pv = NULL; + struct jffs2_inode *rootNode = NULL; + + LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER); + p = (mtd_partition *)((struct drv_data *)blkDriver->data)->priv; + mtd = (struct MtdDev *)(p->mtd_info); + + /* find a empty mte in partition table */ + if (mtd == NULL || mtd->type != MTD_NORFLASH) { + LOS_MuxUnlock(&g_jffs2FsLock); + return -EINVAL; + } + + partNo = p->patitionnum; + + ret = jffs2_mount(partNo, &rootNode, mnt->mountFlags); + if (ret != 0) { + LOS_MuxUnlock(&g_jffs2FsLock); + return ret; + } + + ret = VnodeAlloc(&g_jffs2Vops, &pv); + if (ret != 0) { + LOS_MuxUnlock(&g_jffs2FsLock); + goto ERROR_WITH_VNODE; + } + pv->type = VNODE_TYPE_DIR; + pv->data = (void *)rootNode; + pv->originMount = mnt; + pv->fop = &g_jffs2Fops; + mnt->data = p; + mnt->vnodeCovered = pv; + pv->uid = rootNode->i_uid; + pv->gid = rootNode->i_gid; + pv->mode = rootNode->i_mode; + + (void)VfsHashInsert(pv, rootNode->i_ino); + + g_jffs2PartList[partNo] = blkDriver; + + LOS_MuxUnlock(&g_jffs2FsLock); + + return 0; +ERROR_WITH_VNODE: + return ret; +} + +int VfsJffs2Unbind(struct Mount *mnt, struct Vnode **blkDriver) +{ + int ret; + mtd_partition *p = NULL; + int partNo; + + LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER); + + p = (mtd_partition *)mnt->data; + if (p == NULL) { + LOS_MuxUnlock(&g_jffs2FsLock); + return -EINVAL; + } + + partNo = p->patitionnum; + ret = jffs2_umount((struct jffs2_inode *)mnt->vnodeCovered->data); + if (ret) { + LOS_MuxUnlock(&g_jffs2FsLock); + return ret; + } + + free(p->mountpoint_name); + p->mountpoint_name = NULL; + *blkDriver = g_jffs2PartList[partNo]; + + LOS_MuxUnlock(&g_jffs2FsLock); + return 0; +} + +int VfsJffs2Lookup(struct Vnode *parentVnode, const char *path, int len, struct Vnode **ppVnode) +{ + int ret; + struct Vnode *newVnode = NULL; + struct jffs2_inode *node = NULL; + struct jffs2_inode *parentNode = NULL; + + LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER); + + parentNode = (struct jffs2_inode *)parentVnode->data; + node = jffs2_lookup(parentNode, (const unsigned char *)path, len); + if (!node) { + LOS_MuxUnlock(&g_jffs2FsLock); + return -ENOENT; + } + + (void)VfsHashGet(parentVnode->originMount, node->i_ino, &newVnode, NULL, NULL); + if (newVnode) { + if (newVnode->data == NULL) { + LOS_Panic("#####VfsHashGet error#####\n"); + } + newVnode->parent = parentVnode; + *ppVnode = newVnode; + LOS_MuxUnlock(&g_jffs2FsLock); + return 0; + } + ret = VnodeAlloc(&g_jffs2Vops, &newVnode); + if (ret != 0) { + PRINT_ERR("%s-%d, ret: %x\n", __FUNCTION__, __LINE__, ret); + (void)jffs2_iput(node); + LOS_MuxUnlock(&g_jffs2FsLock); + return ret; + } + + Jffs2SetVtype(node, newVnode); + newVnode->fop = parentVnode->fop; + newVnode->data = node; + newVnode->parent = parentVnode; + newVnode->originMount = parentVnode->originMount; + newVnode->uid = node->i_uid; + newVnode->gid = node->i_gid; + newVnode->mode = node->i_mode; + + (void)VfsHashInsert(newVnode, node->i_ino); + + *ppVnode = newVnode; + + LOS_MuxUnlock(&g_jffs2FsLock); + return 0; +} + +int VfsJffs2Create(struct Vnode *parentVnode, const char *path, int mode, struct Vnode **ppVnode) +{ + int ret; + struct jffs2_inode *newNode = NULL; + struct Vnode *newVnode = NULL; + + ret = VnodeAlloc(&g_jffs2Vops, &newVnode); + if (ret != 0) { + return -ENOMEM; + } + + LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER); + ret = jffs2_create((struct jffs2_inode *)parentVnode->data, (const unsigned char *)path, mode, &newNode); + if (ret != 0) { + VnodeFree(newVnode); + LOS_MuxUnlock(&g_jffs2FsLock); + return ret; + } + + newVnode->type = VNODE_TYPE_REG; + newVnode->fop = parentVnode->fop; + newVnode->data = newNode; + newVnode->parent = parentVnode; + newVnode->originMount = parentVnode->originMount; + newVnode->uid = newNode->i_uid; + newVnode->gid = newNode->i_gid; + newVnode->mode = newNode->i_mode; + + (void)VfsHashInsert(newVnode, newNode->i_ino); + + *ppVnode = newVnode; + + LOS_MuxUnlock(&g_jffs2FsLock); + return 0; +} + +int VfsJffs2Close(struct file *filep) +{ + return 0; +} + +ssize_t VfsJffs2ReadPage(struct Vnode *vnode, char *buffer, off_t off) +{ + struct jffs2_inode *node = NULL; + struct jffs2_inode_info *f = NULL; + struct jffs2_sb_info *c = NULL; + int ret; + + LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER); + + node = (struct jffs2_inode *)vnode->data; + f = JFFS2_INODE_INFO(node); + c = JFFS2_SB_INFO(node->i_sb); + + off_t pos = min(node->i_size, off); + ssize_t len = min(PAGE_SIZE, (node->i_size - pos)); + ret = jffs2_read_inode_range(c, f, (unsigned char *)buffer, off, len); + if (ret) { + LOS_MuxUnlock(&g_jffs2FsLock); + return ret; + } + node->i_atime = Jffs2CurSec(); + + LOS_MuxUnlock(&g_jffs2FsLock); + + return len; +} + +ssize_t VfsJffs2Read(struct file *filep, char *buffer, size_t bufLen) +{ + struct jffs2_inode *node = NULL; + struct jffs2_inode_info *f = NULL; + struct jffs2_sb_info *c = NULL; + int ret; + + LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER); + node = (struct jffs2_inode *)filep->f_vnode->data; + f = JFFS2_INODE_INFO(node); + c = JFFS2_SB_INFO(node->i_sb); + + off_t pos = min(node->i_size, filep->f_pos); + off_t len = min(bufLen, (node->i_size - pos)); + ret = jffs2_read_inode_range(c, f, (unsigned char *)buffer, filep->f_pos, len); + if (ret) { + LOS_MuxUnlock(&g_jffs2FsLock); + return ret; + } + node->i_atime = Jffs2CurSec(); + filep->f_pos += len; + + LOS_MuxUnlock(&g_jffs2FsLock); + + return len; +} + +ssize_t VfsJffs2WritePage(struct Vnode *vnode, char *buffer, off_t pos, size_t buflen) +{ + struct jffs2_inode *node = NULL; + struct jffs2_inode_info *f = NULL; + struct jffs2_sb_info *c = NULL; + struct jffs2_raw_inode ri = {0}; + struct IATTR attr = {0}; + int ret; + uint32_t writtenLen; + + LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER); + + node = (struct jffs2_inode *)vnode->data; + f = JFFS2_INODE_INFO(node); + c = JFFS2_SB_INFO(node->i_sb); + + if (pos < 0) { + LOS_MuxUnlock(&g_jffs2FsLock); + return -EINVAL; + } + + ri.ino = cpu_to_je32(f->inocache->ino); + ri.mode = cpu_to_jemode(node->i_mode); + ri.uid = cpu_to_je16(node->i_uid); + ri.gid = cpu_to_je16(node->i_gid); + ri.atime = ri.ctime = ri.mtime = cpu_to_je32(Jffs2CurSec()); + + if (pos > node->i_size) { + int err; + attr.attr_chg_valid = CHG_SIZE; + attr.attr_chg_size = pos; + err = jffs2_setattr(node, &attr); + if (err) { + LOS_MuxUnlock(&g_jffs2FsLock); + return err; + } + } + ri.isize = cpu_to_je32(node->i_size); + + ret = jffs2_write_inode_range(c, f, &ri, (unsigned char *)buffer, pos, buflen, &writtenLen); + if (ret) { + node->i_mtime = node->i_ctime = je32_to_cpu(ri.mtime); + LOS_MuxUnlock(&g_jffs2FsLock); + return ret; + } + + node->i_mtime = node->i_ctime = je32_to_cpu(ri.mtime); + + LOS_MuxUnlock(&g_jffs2FsLock); + + return (ssize_t)writtenLen; +} + +ssize_t VfsJffs2Write(struct file *filep, const char *buffer, size_t bufLen) +{ + struct jffs2_inode *node = NULL; + struct jffs2_inode_info *f = NULL; + struct jffs2_sb_info *c = NULL; + struct jffs2_raw_inode ri = {0}; + struct IATTR attr = {0}; + int ret; + off_t pos; + uint32_t writtenLen; + + LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER); + + node = (struct jffs2_inode *)filep->f_vnode->data; + f = JFFS2_INODE_INFO(node); + c = JFFS2_SB_INFO(node->i_sb); + pos = filep->f_pos; + +#ifdef LOSCFG_KERNEL_SMP + struct super_block *sb = node->i_sb; + UINT16 gcCpuMask = LOS_TaskCpuAffiGet(sb->s_gc_thread); + UINT32 curTaskId = LOS_CurTaskIDGet(); + UINT16 curCpuMask = LOS_TaskCpuAffiGet(curTaskId); + if (curCpuMask != gcCpuMask) { + if (curCpuMask != LOSCFG_KERNEL_CPU_MASK) { + (void)LOS_TaskCpuAffiSet(sb->s_gc_thread, curCpuMask); + } else { + (void)LOS_TaskCpuAffiSet(curTaskId, gcCpuMask); + } + } +#endif + if (pos < 0) { + LOS_MuxUnlock(&g_jffs2FsLock); + return -EINVAL; + } + + ri.ino = cpu_to_je32(f->inocache->ino); + ri.mode = cpu_to_jemode(node->i_mode); + ri.uid = cpu_to_je16(node->i_uid); + ri.gid = cpu_to_je16(node->i_gid); + ri.atime = ri.ctime = ri.mtime = cpu_to_je32(Jffs2CurSec()); + + if (pos > node->i_size) { + int err; + attr.attr_chg_valid = CHG_SIZE; + attr.attr_chg_size = pos; + err = jffs2_setattr(node, &attr); + if (err) { + LOS_MuxUnlock(&g_jffs2FsLock); + return err; + } + } + ri.isize = cpu_to_je32(node->i_size); + + ret = jffs2_write_inode_range(c, f, &ri, (unsigned char *)buffer, pos, bufLen, &writtenLen); + if (ret) { + pos += writtenLen; + + node->i_mtime = node->i_ctime = je32_to_cpu(ri.mtime); + if (pos > node->i_size) + node->i_size = pos; + + filep->f_pos = pos; + + LOS_MuxUnlock(&g_jffs2FsLock); + + return ret; + } + + if (writtenLen != bufLen) { + pos += writtenLen; + + node->i_mtime = node->i_ctime = je32_to_cpu(ri.mtime); + if (pos > node->i_size) + node->i_size = pos; + + filep->f_pos = pos; + + LOS_MuxUnlock(&g_jffs2FsLock); + + return -ENOSPC; + } + + pos += bufLen; + + node->i_mtime = node->i_ctime = je32_to_cpu(ri.mtime); + if (pos > node->i_size) + node->i_size = pos; + + filep->f_pos = pos; + + LOS_MuxUnlock(&g_jffs2FsLock); + + return writtenLen; +} + +off_t VfsJffs2Seek(struct file *filep, off_t offset, int whence) +{ + struct jffs2_inode *node = NULL; + loff_t filePos; + + LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER); + + node = (struct jffs2_inode *)filep->f_vnode->data; + filePos = filep->f_pos; + + switch (whence) { + case SEEK_CUR: + filePos += offset; + break; + + case SEEK_SET: + filePos = offset; + break; + + case SEEK_END: + filePos = node->i_size + offset; + break; + + default: + LOS_MuxUnlock(&g_jffs2FsLock); + return -EINVAL; + } + + LOS_MuxUnlock(&g_jffs2FsLock); + + if (filePos < 0) + return -EINVAL; + + return filePos; +} + +int VfsJffs2Ioctl(struct file *filep, int cmd, unsigned long arg) +{ + PRINT_DEBUG("%s NOT SUPPORT\n", __FUNCTION__); + return -ENOSYS; +} + +int VfsJffs2Fsync(struct file *filep) +{ + /* jffs2_write directly write to flash, sync is OK. + BUT after pagecache enabled, pages need to be flushed to flash */ + return 0; +} + +int VfsJffs2Dup(const struct file *oldFile, struct file *newFile) +{ + PRINT_DEBUG("%s NOT SUPPORT\n", __FUNCTION__); + return -ENOSYS; +} + +int VfsJffs2Opendir(struct Vnode *pVnode, struct fs_dirent_s *dir) +{ + dir->fd_int_offset = 0; + return 0; +} + +int VfsJffs2Readdir(struct Vnode *pVnode, struct fs_dirent_s *dir) +{ + int ret; + int i = 0; + + LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER); + + /* set jffs2_d */ + while (i < dir->read_cnt) { + ret = jffs2_readdir((struct jffs2_inode *)pVnode->data, &dir->fd_position, + &dir->fd_int_offset, &dir->fd_dir[i]); + if (ret) { + break; + } + + i++; + } + + LOS_MuxUnlock(&g_jffs2FsLock); + + return i; +} + +int VfsJffs2Seekdir(struct Vnode *pVnode, struct fs_dirent_s *dir, unsigned long offset) +{ + return 0; +} + +int VfsJffs2Rewinddir(struct Vnode *pVnode, struct fs_dirent_s *dir) +{ + dir->fd_int_offset = 0; + + return 0; +} + +int VfsJffs2Closedir(struct Vnode *node, struct fs_dirent_s *dir) +{ + return 0; +} + +int VfsJffs2Mkdir(struct Vnode *parentNode, const char *dirName, mode_t mode, struct Vnode **ppVnode) +{ + int ret; + struct jffs2_inode *node = NULL; + struct Vnode *newVnode = NULL; + + ret = VnodeAlloc(&g_jffs2Vops, &newVnode); + if (ret != 0) { + return -ENOMEM; + } + + LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER); + + ret = jffs2_mkdir((struct jffs2_inode *)parentNode->data, (const unsigned char *)dirName, mode, &node); + if (ret != 0) { + LOS_MuxUnlock(&g_jffs2FsLock); + VnodeFree(newVnode); + return ret; + } + + newVnode->type = VNODE_TYPE_DIR; + newVnode->fop = parentNode->fop; + newVnode->data = node; + newVnode->parent = parentNode; + newVnode->originMount = parentNode->originMount; + newVnode->uid = node->i_uid; + newVnode->gid = node->i_gid; + newVnode->mode = node->i_mode; + + *ppVnode = newVnode; + + (void)VfsHashInsert(newVnode, node->i_ino); + + LOS_MuxUnlock(&g_jffs2FsLock); + + return 0; +} + +static int Jffs2Truncate(struct Vnode *pVnode, unsigned int len) +{ + int ret; + struct IATTR attr = {0}; + + attr.attr_chg_size = len; + attr.attr_chg_valid = CHG_SIZE; + + LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER); + ret = jffs2_setattr((struct jffs2_inode *)pVnode->data, &attr); + LOS_MuxUnlock(&g_jffs2FsLock); + return ret; +} + +int VfsJffs2Truncate(struct Vnode *pVnode, off_t len) +{ + int ret = Jffs2Truncate(pVnode, (unsigned int)len); + return ret; +} + +int VfsJffs2Truncate64(struct Vnode *pVnode, off64_t len) +{ + int ret = Jffs2Truncate(pVnode, (unsigned int)len); + return ret; +} + +int VfsJffs2Chattr(struct Vnode *pVnode, struct IATTR *attr) +{ + int ret; + struct jffs2_inode *node = NULL; + + if (pVnode == NULL) { + return -EINVAL; + } + + LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER); + + node = pVnode->data; + ret = jffs2_setattr(node, attr); + if (ret == 0) { + pVnode->uid = node->i_uid; + pVnode->gid = node->i_gid; + pVnode->mode = node->i_mode; + } + LOS_MuxUnlock(&g_jffs2FsLock); + return ret; +} + +int VfsJffs2Rmdir(struct Vnode *parentVnode, struct Vnode *targetVnode, const char *path) +{ + int ret; + struct jffs2_inode *parentInode = NULL; + struct jffs2_inode *targetInode = NULL; + + if (!parentVnode || !targetVnode) { + return -EINVAL; + } + + parentInode = (struct jffs2_inode *)parentVnode->data; + targetInode = (struct jffs2_inode *)targetVnode->data; + + LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER); + + ret = jffs2_rmdir(parentInode, targetInode, (const unsigned char *)path); + if (ret == 0) { + (void)jffs2_iput(targetInode); + } + + LOS_MuxUnlock(&g_jffs2FsLock); + return ret; +} + +int VfsJffs2Link(struct Vnode *oldVnode, struct Vnode *newParentVnode, struct Vnode **newVnode, const char *newName) +{ + int ret; + struct jffs2_inode *oldInode = oldVnode->data; + struct jffs2_inode *newParentInode = newParentVnode->data; + struct Vnode *pVnode = NULL; + + ret = VnodeAlloc(&g_jffs2Vops, &pVnode); + if (ret != 0) { + return -ENOMEM; + } + + LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER); + ret = jffs2_link(oldInode, newParentInode, (const unsigned char *)newName); + if (ret != 0) { + LOS_MuxUnlock(&g_jffs2FsLock); + VnodeFree(pVnode); + return ret; + } + + pVnode->type = VNODE_TYPE_REG; + pVnode->fop = &g_jffs2Fops; + pVnode->parent = newParentVnode; + pVnode->originMount = newParentVnode->originMount; + pVnode->data = oldInode; + pVnode->uid = oldVnode->uid; + pVnode->gid = oldVnode->gid; + pVnode->mode = oldVnode->mode; + + *newVnode = pVnode; + (void)VfsHashInsert(*newVnode, oldInode->i_ino); + + LOS_MuxUnlock(&g_jffs2FsLock); + return ret; +} + +int VfsJffs2Symlink(struct Vnode *parentVnode, struct Vnode **newVnode, const char *path, const char *target) +{ + int ret; + struct jffs2_inode *inode = NULL; + struct Vnode *pVnode = NULL; + + ret = VnodeAlloc(&g_jffs2Vops, &pVnode); + if (ret != 0) { + return -ENOMEM; + } + + LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER); + ret = jffs2_symlink((struct jffs2_inode *)parentVnode->data, &inode, (const unsigned char *)path, target); + if (ret != 0) { + LOS_MuxUnlock(&g_jffs2FsLock); + VnodeFree(pVnode); + return ret; + } + + pVnode->type = VNODE_TYPE_LNK; + pVnode->fop = &g_jffs2Fops; + pVnode->parent = parentVnode; + pVnode->originMount = parentVnode->originMount; + pVnode->data = inode; + pVnode->uid = inode->i_uid; + pVnode->gid = inode->i_gid; + pVnode->mode = inode->i_mode; + + *newVnode = pVnode; + (void)VfsHashInsert(*newVnode, inode->i_ino); + + LOS_MuxUnlock(&g_jffs2FsLock); + return ret; +} + +ssize_t VfsJffs2Readlink(struct Vnode *vnode, char *buffer, size_t bufLen) +{ + struct jffs2_inode *inode = NULL; + struct jffs2_inode_info *f = NULL; + ssize_t targetLen; + ssize_t cnt; + + LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER); + + inode = (struct jffs2_inode *)vnode->data; + f = JFFS2_INODE_INFO(inode); + targetLen = strlen((const char *)f->target); + if (bufLen == 0) { + LOS_MuxUnlock(&g_jffs2FsLock); + return 0; + } + + cnt = (bufLen - 1) < targetLen ? (bufLen - 1) : targetLen; + if (LOS_CopyFromKernel(buffer, bufLen, (const char *)f->target, cnt) != 0) { + LOS_MuxUnlock(&g_jffs2FsLock); + return -EFAULT; + } + buffer[cnt] = '\0'; + + LOS_MuxUnlock(&g_jffs2FsLock); + + return cnt; +} + +int VfsJffs2Unlink(struct Vnode *parentVnode, struct Vnode *targetVnode, const char *path) +{ + int ret; + struct jffs2_inode *parentInode = NULL; + struct jffs2_inode *targetInode = NULL; + + if (!parentVnode || !targetVnode) { + PRINTK("%s-%d parentVnode=%x, targetVnode=%x\n", __FUNCTION__, __LINE__, parentVnode, targetVnode); + return -EINVAL; + } + + parentInode = (struct jffs2_inode *)parentVnode->data; + targetInode = (struct jffs2_inode *)targetVnode->data; + + LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER); + + ret = jffs2_unlink(parentInode, targetInode, (const unsigned char *)path); + if (ret == 0) { + (void)jffs2_iput(targetInode); + } + + LOS_MuxUnlock(&g_jffs2FsLock); + return ret; +} + +int VfsJffs2Rename(struct Vnode *fromVnode, struct Vnode *toParentVnode, const char *fromName, const char *toName) +{ + int ret; + struct Vnode *fromParentVnode = NULL; + struct Vnode *toVnode = NULL; + struct jffs2_inode *fromNode = NULL; + + LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER); + fromParentVnode = fromVnode->parent; + + ret = VfsJffs2Lookup(toParentVnode, toName, strlen(toName), &toVnode); + if (ret == 0) { + if (toVnode->type == VNODE_TYPE_DIR) { + ret = VfsJffs2Rmdir(toParentVnode, toVnode, (char *)toName); + } else { + ret = VfsJffs2Unlink(toParentVnode, toVnode, (char *)toName); + } + if (ret) { + PRINTK("%s-%d remove newname(%s) failed ret=%d\n", __FUNCTION__, __LINE__, toName, ret); + LOS_MuxUnlock(&g_jffs2FsLock); + return ret; + } + } + fromNode = (struct jffs2_inode *)fromVnode->data; + ret = jffs2_rename((struct jffs2_inode *)fromParentVnode->data, fromNode, + (const unsigned char *)fromName, (struct jffs2_inode *)toParentVnode->data, (const unsigned char *)toName); + fromVnode->parent = toParentVnode; + LOS_MuxUnlock(&g_jffs2FsLock); + + if (ret) { + return ret; + } + + return 0; +} + +int VfsJffs2Stat(struct Vnode *pVnode, struct stat *buf) +{ + struct jffs2_inode *node = NULL; + + LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER); + + node = (struct jffs2_inode *)pVnode->data; + switch (node->i_mode & S_IFMT) { + case S_IFREG: + case S_IFDIR: + case S_IFLNK: + buf->st_mode = node->i_mode; + break; + + default: + buf->st_mode = DT_UNKNOWN; + break; + } + + buf->st_dev = 0; + buf->st_ino = node->i_ino; + buf->st_nlink = node->i_nlink; + buf->st_uid = node->i_uid; + buf->st_gid = node->i_gid; + buf->st_size = node->i_size; + buf->st_blksize = BLOCK_SIZE; + buf->st_blocks = buf->st_size / buf->st_blksize; + buf->st_atime = node->i_atime; + buf->st_mtime = node->i_mtime; + buf->st_ctime = node->i_ctime; + + /* Adapt to kstat member long tv_sec */ + buf->__st_atim32.tv_sec = (long)node->i_atime; + buf->__st_mtim32.tv_sec = (long)node->i_mtime; + buf->__st_ctim32.tv_sec = (long)node->i_ctime; + + LOS_MuxUnlock(&g_jffs2FsLock); + + return 0; +} + +int VfsJffs2Reclaim(struct Vnode *pVnode) +{ + return 0; +} + +int VfsJffs2Statfs(struct Mount *mnt, struct statfs *buf) +{ + unsigned long freeSize; + struct jffs2_sb_info *c = NULL; + struct jffs2_inode *rootNode = NULL; + + LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER); + + rootNode = (struct jffs2_inode *)mnt->vnodeCovered->data; + c = JFFS2_SB_INFO(rootNode->i_sb); + + freeSize = c->free_size + c->dirty_size; + buf->f_type = JFFS2_SUPER_MAGIC; + buf->f_bsize = PAGE_SIZE; + buf->f_blocks = (((uint64_t)c->nr_blocks) * c->sector_size) / PAGE_SIZE; + buf->f_bfree = freeSize / PAGE_SIZE; + buf->f_bavail = buf->f_bfree; + buf->f_namelen = NAME_MAX; + buf->f_fsid.__val[0] = JFFS2_SUPER_MAGIC; + buf->f_fsid.__val[1] = 1; + buf->f_frsize = BLOCK_SIZE; + buf->f_files = 0; + buf->f_ffree = 0; + buf->f_flags = mnt->mountFlags; + + LOS_MuxUnlock(&g_jffs2FsLock); + return 0; +} + +int Jffs2MutexCreate(void) +{ + if (LOS_MuxInit(&g_jffs2FsLock, NULL) != LOS_OK) { + PRINT_ERR("%s, LOS_MuxCreate failed\n", __FUNCTION__); + return -1; + } else { + return 0; + } +} + +void Jffs2MutexDelete(void) +{ + (void)LOS_MuxDestroy(&g_jffs2FsLock); +} + +const struct MountOps jffs_operations = { + .Mount = VfsJffs2Bind, + .Unmount = VfsJffs2Unbind, + .Statfs = VfsJffs2Statfs, +}; + +struct VnodeOps g_jffs2Vops = { + .Lookup = VfsJffs2Lookup, + .Create = VfsJffs2Create, + .ReadPage = VfsJffs2ReadPage, + .WritePage = VfsJffs2WritePage, + .Rename = VfsJffs2Rename, + .Mkdir = VfsJffs2Mkdir, + .Getattr = VfsJffs2Stat, + .Opendir = VfsJffs2Opendir, + .Readdir = VfsJffs2Readdir, + .Closedir = VfsJffs2Closedir, + .Rewinddir = VfsJffs2Rewinddir, + .Unlink = VfsJffs2Unlink, + .Rmdir = VfsJffs2Rmdir, + .Chattr = VfsJffs2Chattr, + .Reclaim = VfsJffs2Reclaim, + .Truncate = VfsJffs2Truncate, + .Truncate64 = VfsJffs2Truncate64, + .Link = VfsJffs2Link, + .Symlink = VfsJffs2Symlink, + .Readlink = VfsJffs2Readlink, +}; + +struct file_operations_vfs g_jffs2Fops = { + .read = VfsJffs2Read, + .write = VfsJffs2Write, + .mmap = OsVfsFileMmap, + .seek = VfsJffs2Seek, + .close = VfsJffs2Close, + .fsync = VfsJffs2Fsync, +}; + + +FSMAP_ENTRY(jffs_fsmap, "jffs2", jffs_operations, TRUE, TRUE); + +#endif diff --git a/src/kernel_liteos_a/fs/nfs/BUILD.gn b/src/kernel_liteos_a/fs/nfs/BUILD.gn new file mode 100644 index 00000000..c48f95eb --- /dev/null +++ b/src/kernel_liteos_a/fs/nfs/BUILD.gn @@ -0,0 +1,37 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") +import("$THIRDPARTY_NUTTX_DIR/NuttX.gni") + +module_switch = defined(LOSCFG_FS_NFS) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = NUTTX_FS_NFS_SRC_FILES +} diff --git a/src/kernel_liteos_a/fs/nfs/Kconfig b/src/kernel_liteos_a/fs/nfs/Kconfig new file mode 100644 index 00000000..5665c46c --- /dev/null +++ b/src/kernel_liteos_a/fs/nfs/Kconfig @@ -0,0 +1,8 @@ +config FS_NFS + bool "Enable NFS" + default y + depends on FS_VFS + depends on NET_LWIP_SACK + depends on DEBUG_VERSION + help + Answer Y to enable LiteOS support nfs filesystem. diff --git a/src/kernel_liteos_a/fs/nfs/Makefile b/src/kernel_liteos_a/fs/nfs/Makefile new file mode 100644 index 00000000..4991913a --- /dev/null +++ b/src/kernel_liteos_a/fs/nfs/Makefile @@ -0,0 +1,38 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := $(wildcard $(LITEOSTHIRDPARTY)/NuttX/fs/nfs/*.c) + +LOCAL_FLAGS := $(LOCAL_INCLUDE) + +include $(MODULE) diff --git a/src/kernel_liteos_a/fs/patchfs/BUILD.gn b/src/kernel_liteos_a/fs/patchfs/BUILD.gn new file mode 100644 index 00000000..bf74298c --- /dev/null +++ b/src/kernel_liteos_a/fs/patchfs/BUILD.gn @@ -0,0 +1,43 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = defined(LOSCFG_PLATFORM_PATCHFS) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ + "los_partition_utils.c", + "los_patchfs.c", + ] + public_configs = [ ":public" ] +} + +config("public") { +} diff --git a/src/kernel_liteos_a/fs/patchfs/Kconfig b/src/kernel_liteos_a/fs/patchfs/Kconfig new file mode 100644 index 00000000..b7c11145 --- /dev/null +++ b/src/kernel_liteos_a/fs/patchfs/Kconfig @@ -0,0 +1,6 @@ +config PLATFORM_PATCHFS + bool "Enable PATCHFS" + default n + depends on FS_JFFS + help + Answer Y to enable LiteOS support patchfs. diff --git a/src/kernel_liteos_a/fs/patchfs/Makefile b/src/kernel_liteos_a/fs/patchfs/Makefile new file mode 100644 index 00000000..eab29ad3 --- /dev/null +++ b/src/kernel_liteos_a/fs/patchfs/Makefile @@ -0,0 +1,7 @@ +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := $(wildcard *.c) + +include $(MODULE) diff --git a/src/kernel_liteos_a/fs/patchfs/los_partition_utils.c b/src/kernel_liteos_a/fs/patchfs/los_partition_utils.c new file mode 100644 index 00000000..c2556011 --- /dev/null +++ b/src/kernel_liteos_a/fs/patchfs/los_partition_utils.c @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "los_partition_utils.h" +#if defined(LOSCFG_STORAGE_SPINOR) +#include "mtd_partition.h" +#endif + +STATIC INT32 MatchPartPos(CHAR *p, const CHAR *partInfoName, INT32 *partInfo) +{ + UINT32 offset; + CHAR *value = NULL; + + if (strncmp(p, partInfoName, strlen(partInfoName)) == 0) { + value = p + strlen(partInfoName); + offset = strspn(value, DEC_NUMBER_STRING); + if (strcmp(p + strlen(p) - 1, "M") == 0) { + if ((offset < strlen(value) - 1) || (sscanf_s(value, "%d", partInfo) <= 0)) { + goto ERROUT; + } + *partInfo = *partInfo * BYTES_PER_MBYTE; + } else if (strcmp(p + strlen(p) - 1, "K") == 0) { + if ((offset < (strlen(value) - 1)) || (sscanf_s(value, "%d", partInfo) <= 0)) { + goto ERROUT; + } + *partInfo = *partInfo * BYTES_PER_KBYTE; + } else if (sscanf_s(value, "0x%x", partInfo) > 0) { + value += strlen("0x"); + if (strspn(value, HEX_NUMBER_STRING) < strlen(value)) { + goto ERROUT; + } + } else { + goto ERROUT; + } + } + + return LOS_OK; + +ERROUT: + PRINT_ERR("Invalid format: %s\n", p + strlen(partInfoName)); + return LOS_NOK; +} + +STATIC INT32 MatchPartInfo(CHAR *p, struct PartitionInfo *partInfo) +{ + const CHAR *storageTypeArgName = partInfo->storageTypeArgName; + const CHAR *fsTypeArgName = partInfo->fsTypeArgName; + const CHAR *addrArgName = partInfo->addrArgName; + const CHAR *partSizeArgName = partInfo->partSizeArgName; + + if ((partInfo->storageType == NULL) && (strncmp(p, storageTypeArgName, strlen(storageTypeArgName)) == 0)) { + partInfo->storageType = strdup(p + strlen(storageTypeArgName)); + if (partInfo->storageType == NULL) { + return LOS_NOK; + } + return LOS_OK; + } + + if ((partInfo->fsType == NULL) && (strncmp(p, fsTypeArgName, strlen(fsTypeArgName)) == 0)) { + partInfo->fsType = strdup(p + strlen(fsTypeArgName)); + if (partInfo->fsType == NULL) { + return LOS_NOK; + } + return LOS_OK; + } + + if (partInfo->startAddr < 0) { + if (MatchPartPos(p, addrArgName, &partInfo->startAddr) != LOS_OK) { + return LOS_NOK; + } else if (partInfo->startAddr >= 0) { + return LOS_OK; + } + } + + if (partInfo->partSize < 0) { + if (MatchPartPos(p, partSizeArgName, &partInfo->partSize) != LOS_OK) { + return LOS_NOK; + } + } + + return LOS_OK; +} + +STATIC INT32 GetPartitionBootArgs(const CHAR *argName, CHAR **args) +{ + INT32 i; + INT32 len = 0; + CHAR *cmdLine = NULL; + INT32 cmdLineLen; + CHAR *tmp = NULL; + + cmdLine = (CHAR *)malloc(COMMAND_LINE_SIZE); + if (cmdLine == NULL) { + PRINT_ERR("Malloc cmdLine space failed!\n"); + return LOS_NOK; + } + +#if defined(LOSCFG_STORAGE_SPINOR) + struct MtdDev *mtd = GetMtd(FLASH_TYPE); + if (mtd == NULL) { + PRINT_ERR("Get spinor mtd failed!\n"); + goto ERROUT; + } + cmdLineLen = mtd->read(mtd, COMMAND_LINE_ADDR, COMMAND_LINE_SIZE, cmdLine); + if ((cmdLineLen != COMMAND_LINE_SIZE)) { + PRINT_ERR("Read spinor command line failed!\n"); + goto ERROUT; + } +#else + cmdLineLen = 0; +#endif + + for (i = 0; i < cmdLineLen; i += len + 1) { + len = strlen(cmdLine + i); + tmp = strstr(cmdLine + i, argName); + if (tmp != NULL) { + *args = strdup(tmp + strlen(argName)); + if (*args == NULL) { + goto ERROUT; + } + free(cmdLine); + return LOS_OK; + } + } + + PRINTK("no patch partition bootargs\n"); + +ERROUT: + free(cmdLine); + return LOS_NOK; +} + +INT32 GetPartitionInfo(struct PartitionInfo *partInfo) +{ + CHAR *args = NULL; + CHAR *argsBak = NULL; + CHAR *p = NULL; + + if (GetPartitionBootArgs(partInfo->cmdlineArgName, &args) != LOS_OK) { + return LOS_NOK; + } + argsBak = args; + + p = strsep(&args, " "); + while (p != NULL) { + if (MatchPartInfo(p, partInfo) != LOS_OK) { + goto ERROUT; + } + p = strsep(&args, " "); + } + if ((partInfo->fsType != NULL) && (partInfo->storageType != NULL)) { + free(argsBak); + return LOS_OK; + } + PRINT_ERR("Cannot find %s type\n", partInfo->partName); + +ERROUT: + PRINT_ERR("Invalid %s information!\n", partInfo->partName); + if (partInfo->storageType != NULL) { + free(partInfo->storageType); + partInfo->storageType = NULL; + } + if (partInfo->fsType != NULL) { + free(partInfo->fsType); + partInfo->fsType = NULL; + } + free(argsBak); + + return LOS_NOK; +} + +const CHAR *GetDevNameOfPartition(const struct PartitionInfo *partInfo) +{ + const CHAR *devName = NULL; + + if (strcmp(partInfo->storageType, STORAGE_TYPE) == 0) { +#if defined(LOSCFG_STORAGE_SPINOR) + INT32 ret = add_mtd_partition(FLASH_TYPE, partInfo->startAddr, partInfo->partSize, partInfo->partNum); + if (ret != LOS_OK) { + PRINT_ERR("Failed to add %s partition! error = %d\n", partInfo->partName, ret); + } else { + if (partInfo->devName != NULL) { + devName = partInfo->devName; + } + } +#endif + } else { + PRINT_ERR("Failed to find %s dev type: %s\n", partInfo->partName, partInfo->storageType); + } + + return devName; +} + +INT32 ResetDevNameofPartition(const struct PartitionInfo *partInfo) +{ + INT32 ret; +#if defined(LOSCFG_STORAGE_SPINOR) + ret = delete_mtd_partition(partInfo->partNum, FLASH_TYPE); + if (ret != ENOERR) { + int err = get_errno(); + PRINT_ERR("Failed to delete %s, errno %d: %s\n", partInfo->devName, err, strerror(err)); + ret = LOS_NOK; + } +#else + ret = LOS_NOK; +#endif + return ret; +} diff --git a/src/kernel_liteos_a/fs/patchfs/los_partition_utils.h b/src/kernel_liteos_a/fs/patchfs/los_partition_utils.h new file mode 100644 index 00000000..d4f98607 --- /dev/null +++ b/src/kernel_liteos_a/fs/patchfs/los_partition_utils.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _LOS_PARTITION_UTILS_H +#define _LOS_PARTITION_UTILS_H + +#include "los_typedef.h" +#include "los_base.h" + +#define BYTES_PER_MBYTE 0x100000 +#define BYTES_PER_KBYTE 0x400 +#define DEC_NUMBER_STRING "0123456789" +#define HEX_NUMBER_STRING "0123456789abcdefABCDEF" + +#define COMMAND_LINE_ADDR LOSCFG_BOOTENV_ADDR * BYTES_PER_KBYTE +#define COMMAND_LINE_SIZE 1024 + +#if defined(LOSCFG_STORAGE_SPINOR) +#define FLASH_TYPE "spinor" +#define STORAGE_TYPE "flash" +#define FS_TYPE "jffs2" +#else +#define STORAGE_TYPE "emmc" +#endif + +struct PartitionInfo { + const CHAR *partName; + const CHAR *cmdlineArgName; + const CHAR *storageTypeArgName; + CHAR *storageType; + const CHAR *fsTypeArgName; + CHAR *fsType; + const CHAR *addrArgName; + INT32 startAddr; + const CHAR *partSizeArgName; + INT32 partSize; + CHAR *devName; + UINT32 partNum; +}; + +INT32 GetPartitionInfo(struct PartitionInfo *partInfo); +const CHAR *GetDevNameOfPartition(const struct PartitionInfo *partInfo); +INT32 ResetDevNameofPartition(const struct PartitionInfo *partInfo); + +#endif /* _LOS_PARTITION_UTILS_H */ diff --git a/src/kernel_liteos_a/fs/patchfs/los_patchfs.c b/src/kernel_liteos_a/fs/patchfs/los_patchfs.c new file mode 100644 index 00000000..04346c6a --- /dev/null +++ b/src/kernel_liteos_a/fs/patchfs/los_patchfs.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "los_patchfs.h" +#include "los_partition_utils.h" + +#include "sys/mount.h" +#include "vnode.h" + +#ifdef LOSCFG_PLATFORM_PATCHFS + +INT32 OsMountPatchFs(VOID) +{ + INT32 ret; + struct PartitionInfo partInfo = { + PATCHPART_NAME, PATCH_CMDLINE_ARGNAME, + PATCH_STORAGE_ARGNAME, NULL, + PATCH_FSTYPE_ARGNAME, NULL, + PATCH_ADDR_ARGNAME, -1, + PATCH_SIZE_ARGNAME, -1, + NULL, PATCH_PARTITIONNUM + }; + +#ifdef LOSCFG_SECURITY_BOOT + partInfo.storageType = strdup(STORAGE_TYPE); + if (partInfo.storageType == NULL) { + return LOS_NOK; + } + partInfo.fsType = strdup(FS_TYPE); + if (partInfo.fsType == NULL) { + ret = LOS_NOK; + goto EXIT; + } + partInfo.startAddr = PATCHFS_FLASH_ADDR; + partInfo.partSize = PATCHFS_FLASH_SIZE; +#else + ret = GetPartitionInfo(&partInfo); + if (ret != LOS_OK) { + goto EXIT; + } + partInfo.startAddr = (partInfo.startAddr >= 0) ? partInfo.startAddr : PATCHFS_FLASH_ADDR; + partInfo.partSize = (partInfo.partSize >= 0) ? partInfo.partSize : PATCHFS_FLASH_SIZE; +#endif + + ret = LOS_NOK; + partInfo.devName = strdup(PATCH_FLASH_DEV_NAME); + if (partInfo.devName == NULL) { + goto EXIT; + } + const CHAR *devName = GetDevNameOfPartition(&partInfo); + if (devName != NULL) { + ret = mkdir(PATCHFS_MOUNT_POINT, 0); + if (ret == LOS_OK) { + ret = mount(devName, PATCHFS_MOUNT_POINT, partInfo.fsType, MS_RDONLY, NULL); + if (ret != LOS_OK) { + int err = get_errno(); + PRINT_ERR("Failed to mount %s, errno %d: %s\n", partInfo.partName, err, strerror(err)); + } + } else { + int err = get_errno(); + PRINT_ERR("Failed to mkdir %s, errno %d: %s\n", PATCHFS_MOUNT_POINT, err, strerror(err)); + } + } + + if ((ret != LOS_OK) && (devName != NULL)) { + ResetDevNameofPartition(&partInfo); + } + +EXIT: + free(partInfo.devName); + partInfo.devName = NULL; + free(partInfo.storageType); + partInfo.storageType = NULL; + free(partInfo.fsType); + partInfo.fsType = NULL; + return ret; +} + +#endif // LOSCFG_PLATFORM_PATCHFS diff --git a/src/kernel_liteos_a/fs/patchfs/los_patchfs.h b/src/kernel_liteos_a/fs/patchfs/los_patchfs.h new file mode 100644 index 00000000..72e3e876 --- /dev/null +++ b/src/kernel_liteos_a/fs/patchfs/los_patchfs.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _LOS_PATCHFS_H +#define _LOS_PATCHFS_H + +#include "los_typedef.h" +#include "los_base.h" + +#define __stringify_1(x...) #x +#define __stringify(x...) __stringify_1(x) + +#define PATCH_PARTITIONNUM 1 +#ifdef TEE_ENABLE +#define PATCHFS_FLASH_ADDR 0xC00000 +#define PATCHFS_FLASH_SIZE 0x200000 +#else +#define PATCHFS_FLASH_ADDR 0xD00000 +#define PATCHFS_FLASH_SIZE 0x300000 +#endif + +#if defined(LOSCFG_STORAGE_SPINOR) +#define PATCH_FLASH_DEV_NAME "/dev/spinorblk"__stringify(PATCH_PARTITIONNUM) +#else +#define PATCH_FLASH_DEV_NAME "/dev/mmcblk"__stringify(PATCH_PARTITIONNUM) +#endif + +#define PATCHFS_MOUNT_POINT "/patch" + +#define PATCHPART_NAME "patchfs" +#define PATCH_CMDLINE_ARGNAME "patchfs=" +#define PATCH_STORAGE_ARGNAME "patch=" +#define PATCH_FSTYPE_ARGNAME "patchfstype=" +#define PATCH_ADDR_ARGNAME "patchaddr=" +#define PATCH_SIZE_ARGNAME "patchsize=" + +INT32 OsMountPatchFs(VOID); + +#endif /* _LOS_PATCHFS_H */ diff --git a/src/kernel_liteos_a/fs/proc/BUILD.gn b/src/kernel_liteos_a/fs/proc/BUILD.gn new file mode 100644 index 00000000..eb2538ed --- /dev/null +++ b/src/kernel_liteos_a/fs/proc/BUILD.gn @@ -0,0 +1,58 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = defined(LOSCFG_FS_PROC) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ + "os_adapt/fd_proc.c", + "os_adapt/file_sys.c", + "os_adapt/fs_cache_proc.c", + "os_adapt/mem_info.c", + "os_adapt/mounts_proc.c", + "os_adapt/plimits_proc.c", + "os_adapt/power_proc.c", + "os_adapt/proc_init.c", + "os_adapt/proc_vfs.c", + "os_adapt/process_proc.c", + "os_adapt/sys_user.c", + "os_adapt/uptime_proc.c", + "os_adapt/vmm_proc.c", + "src/proc_file.c", + "src/proc_shellcmd.c", + ] + + public_configs = [ ":public" ] +} + +config("public") { + include_dirs = [ "include" ] +} diff --git a/src/kernel_liteos_a/fs/proc/Kconfig b/src/kernel_liteos_a/fs/proc/Kconfig new file mode 100644 index 00000000..c91ebe6e --- /dev/null +++ b/src/kernel_liteos_a/fs/proc/Kconfig @@ -0,0 +1,11 @@ +config FS_PROC + bool "Enable PROC" + default y + depends on FS_VFS + help + Answer Y to enable LiteOS support proc filesystem. + +config PROC_PROCESS_DIR + bool "Enable Process mount directory" + default n + depends on FS_PROC diff --git a/src/kernel_liteos_a/fs/proc/Makefile b/src/kernel_liteos_a/fs/proc/Makefile new file mode 100644 index 00000000..943fa35b --- /dev/null +++ b/src/kernel_liteos_a/fs/proc/Makefile @@ -0,0 +1,36 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := $(wildcard os_adapt/*.c) $(wildcard src/*.c) + +include $(MODULE) \ No newline at end of file diff --git a/src/kernel_liteos_a/fs/proc/include/internal.h b/src/kernel_liteos_a/fs/proc/include/internal.h new file mode 100644 index 00000000..22949386 --- /dev/null +++ b/src/kernel_liteos_a/fs/proc/include/internal.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _PROC_INTERNAL_H +#define _PROC_INTERNAL_H + +#include "proc_fs.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define MAX_NON_LFS ((1UL << 31) - 1) + +extern spinlock_t procfsLock; +extern bool procfsInit; + +#ifdef LOSCFG_PROC_PROCESS_DIR +int ProcCreateProcessDir(UINT32 pid, uintptr_t process); + +void ProcFreeProcessDir(struct ProcDirEntry *processDir); + +void ProcSysMemInfoInit(void); + +void ProcFileSysInit(void); +#endif + +#ifdef LOSCFG_KERNEL_PLIMITS +void ProcLimitsInit(void); +#endif + +void ProcEntryClearVnode(struct ProcDirEntry *entry); + +void ProcDetachNode(struct ProcDirEntry *pn); + +void RemoveProcEntryTravalsal(struct ProcDirEntry *pn); + +void ProcPmInit(void); + +void ProcVmmInit(void); + +void ProcProcessInit(void); + +int ProcMatch(unsigned int len, const char *name, struct ProcDirEntry *pde); + +struct ProcDirEntry *ProcFindEntry(const char *path); + +void ProcFreeEntry(struct ProcDirEntry *pde); + +int ProcStat(const char *file, struct ProcStat *buf); + +void ProcMountsInit(void); + +void ProcUptimeInit(void); + +void ProcFsCacheInit(void); + +void ProcFdInit(void); + +#ifdef LOSCFG_KERNEL_CONTAINER +void *ProcfsContainerGet(int fd, unsigned int *containerType); +void ProcSysUserInit(void); +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ +#endif diff --git a/src/kernel_liteos_a/fs/proc/include/proc_file.h b/src/kernel_liteos_a/fs/proc/include/proc_file.h new file mode 100644 index 00000000..5d6b9fda --- /dev/null +++ b/src/kernel_liteos_a/fs/proc/include/proc_file.h @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef PROC_FILE_H +#define PROC_FILE_H + +#include "proc_fs.h" + +/** + * @ingroup procfs + * @brief open a proc node + * + * @par Description: + * This API is used to open the node by 'fileName' and flags, + * + * @attention + *
            + *
          • None.
          • + *
          + * + * @param fileName [IN] Type #const char * the fileName of the node to be opened + * @param flags [IN] Type #int the flags of open's node + * + * @retval #NULL open failed + * @retval #NOT NULL open successfully + * @par Dependency: + *
          • proc_fs.h: the header file that contains the API declaration.
          + * @see proc_close + * + */ +extern struct ProcDirEntry *OpenProcFile(const char *fileName, int flags, ...); + +/** + * @ingroup procfs + * @brief read a proc node + * + * @par Description: + * This API is used to read the node by pde + * + * @attention + *
            + *
          • None.
          • + *
          + * + * @param pde [IN] Type #struct ProcDirEntry * pointer of the node structure to be read + * @param buf [IN] Type #void * user-provided to save the data + * @param len [IN] Type #size_t the length of want to read + * + * @retval #-1 read failed + * @retval #>0 Number of bytes read success + * @par Dependency: + *
          • proc_fs.h: the header file that contains the API declaration.
          + * @see proc_open + * + */ +extern int ReadProcFile(struct ProcDirEntry *pde, void *buf, size_t len); + +/** + * @ingroup procfs + * @brief write a proc node + * + * @par Description: + * This API is used to write the node by pde + * + * @attention + *
            + *
          • None.
          • + *
          + * + * @param pde [IN] Type #struct ProcDirEntry * pointer of the node structure to be written + * @param buf [IN] Type #const void * data to write + * @param len [IN] Type #size_t length of data to write + * + * @retval #-1 write failed + * @retval #>0 Number of bytes write successfully + * @par Dependency: + *
          • proc_fs.h: the header file that contains the API declaration.
          + * @see proc_open + * + */ +extern int WriteProcFile(struct ProcDirEntry *pde, const void *buf, size_t len); + +/** + * @ingroup procfs + * @brief File migration + * + * @par Description: + * This API is used to set the proc file migration + * + * @attention + *
            + *
          • None.
          • + *
          + * + * @param pde [IN] Type #struct ProcDirEntry * pointer of the node structure to be deviation + * @param offset [IN] Type #loff_t the number of deviation + * @param whence [IN] Type #int the begin of deviation + * + * @retval #<0 deviation failed + * @retval #>=0 deviation successfully + * @par Dependency: + *
          • proc_fs.h: the header file that contains the API declaration.
          + * @see proc_open + * + */ +extern loff_t LseekProcFile(struct ProcDirEntry *pde, loff_t offset, int whence); + +/** + * @ingroup procfs + * @brief directory migration + * + * @par Description: + * This API is used to set the proc directory migration + * + * @attention + *
            + *
          • Only allow SEEK_SET to zero.
          • + *
          + * + * @param pde [IN] Type #struct ProcDirEntry * pointer of the node structure to be deviated + * @param pos [IN] Type #off_t * the number of deviation + * @param whence [IN] Type #int the begin of deviation + * + * @retval #EINVAL deviation failed + * @retval #ENOERR deviation successfully + * @par Dependency: + *
          • proc_fs.h: the header file that contains the API declaration.
          + * @see proc_open + * + */ +int LseekDirProcFile(struct ProcDirEntry *pde, off_t *pos, int whence); + +/** + * @ingroup procfs + * @brief close a proc node + * + * @par Description: + * This API is used to close the node by pde + * + * @attention + *
            + *
          • None.
          • + *
          + * + * @param pde [IN] Type #struct ProcDirEntry * pointer of the node structure to be closed + * + * @retval #-1 close failed + * @retval #0 close successfully + * @par Dependency: + *
          • proc_fs.h: the header file that contains the API declaration.
          + * @see proc_open + * + */ +extern int CloseProcFile(struct ProcDirEntry *pde); + +extern struct ProcDirEntry *GetProcRootEntry(void); +extern int ProcOpen(struct ProcFile *procFile); + +#endif diff --git a/src/kernel_liteos_a/fs/proc/include/proc_fs.h b/src/kernel_liteos_a/fs/proc/include/proc_fs.h new file mode 100644 index 00000000..f172d439 --- /dev/null +++ b/src/kernel_liteos_a/fs/proc/include/proc_fs.h @@ -0,0 +1,326 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _PROC_FS_H +#define _PROC_FS_H + +#include +#include + +#include "los_config.h" + +#ifdef LOSCFG_FS_PROC +#include "linux/spinlock.h" +#include "asm/atomic.h" +#include "vnode.h" +#include "fs/file.h" +#include "los_seq_buf.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef unsigned short fmode_t; +#define PROC_ERROR (-1) + +/* Default file mode for procfs */ +#define PROCFS_DEFAULT_MODE 0550 + +/* 64bit hashes as llseek() offset (for directories) */ +#define FMODE_64BITHASH ((fmode_t)0x400) +/* 32bit hashes as llseek() offset (for directories) */ +#define FMODE_32BITHASH ((fmode_t)0x200) +/* File is opened using open(.., 3, ..) and is writable only for ioctls + * (specialy hack for floppy.c) + */ +#define FMODE_WRITE_IOCTL ((fmode_t)0x100) +/* File is opened with O_EXCL (only set for block devices) */ +#define FMODE_EXCL ((fmode_t)0x80) +/* File is opened with O_NDELAY (only set for block devices) */ +#define FMODE_NDELAY ((fmode_t)0x40) +/* File is opened for execution with sys_execve / sys_uselib */ +#define FMODE_EXEC ((fmode_t)0x20) +/* file can be accessed using pwrite */ +#define FMODE_PWRITE ((fmode_t)0x10) +/* file can be accessed using pread */ +#define FMODE_PREAD ((fmode_t)0x8) +/* file is seekable */ +#define FMODE_LSEEK ((fmode_t)0x4) +/* file is open for writing */ +#define FMODE_WRITE ((fmode_t)0x2) +/* file is open for reading */ +#define FMODE_READ ((fmode_t)0x1) + +struct ProcFile; +struct ProcDirEntry; + +struct ProcFileOperations { + char *name; + ssize_t (*write)(struct ProcFile *pf, const char *buf, size_t count, loff_t *ppos); + int (*open)(struct Vnode *vnode, struct ProcFile *pf); + int (*release)(struct Vnode *vnode, struct ProcFile *pf); + int (*read)(struct SeqBuf *m, void *v); + ssize_t (*readLink)(struct ProcDirEntry *pde, char *buf, size_t bufLen); +}; + +#ifdef LOSCFG_KERNEL_PLIMITS +struct ProcDirOperations { + int (*rmdir)(struct ProcDirEntry *parent, struct ProcDirEntry *pde, const char *name); + int (*mkdir)(struct ProcDirEntry *parent, const char *dirName, mode_t mode, struct ProcDirEntry **pde); +}; +#endif + +#define PROC_DATA_STATIC 0 +#define PROC_DATA_FREE 1 +struct ProcDirEntry { + uint uid; + uint gid; + mode_t mode; + int flags; + const struct ProcFileOperations *procFileOps; + struct ProcFile *pf; + struct ProcDirEntry *next, *parent, *subdir; +#ifdef LOSCFG_KERNEL_PLIMITS + const struct ProcDirOperations *procDirOps; +#endif + int dataType; + void *data; + atomic_t count; /* open file count */ + spinlock_t pdeUnloadLock; + + int nameLen; + struct ProcDirEntry *pdirCurrent; + char name[NAME_MAX]; + enum VnodeType type; +}; + +struct ProcDataParm { + void *data; + int dataType; +}; + +struct ProcFile { + fmode_t fMode; + spinlock_t fLock; + atomic_t fCount; + struct SeqBuf *sbuf; + struct ProcDirEntry *pPDE; + unsigned long long fVersion; + loff_t fPos; + char name[NAME_MAX]; +}; + +struct ProcStat { + mode_t stMode; + struct ProcDirEntry *pPDE; + char name[NAME_MAX]; +}; + +struct ProcData { + ssize_t size; + loff_t fPos; + char buf[1]; +}; + +#define PROCDATA(n) (sizeof(struct ProcData) + (n)) + +#define S_IALLUGO (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO) + +/** + * Interface for modules using proc below internal proc module; + */ +/** + * @ingroup procfs + * @brief create a proc node + * + * @par Description: + * This API is used to create the node by 'name' and parent vnode + * + * @attention + *
            + *
          • This interface should be called after system initialization.
          • + *
          • The parameter name should be a valid string.
          • + *
          + * + * @param name [IN] Type #const char * The name of the node to be created. + * @param mode [IN] Type #mode_t the mode of create's node. + * @param parent [IN] Type #struct ProcDirEntry * the parent node of the node to be created, + * if pass NULL, default parent node is "/proc". + * + * @retval #NULL Create failed. + * @retval #ProcDirEntry* Create successfully. + * @par Dependency: + *
          • proc_fs.h: the header file that contains the API declaration.
          + * @see + * + */ +extern struct ProcDirEntry *CreateProcEntry(const char *name, mode_t mode, struct ProcDirEntry *parent); + +/** + * @ingroup procfs + * @brief remove a proc node + * + * @par Description: + * This API is used to remove the node by 'name' and parent vnode + * + * @attention + *
            + *
          • This interface should be called after system initialization.
          • + *
          • The parameter name should be a valid string.
          • + *
          + * + * @param name [IN] Type #const char * The name of the node to be removed. + * @param parent [IN] Type #struct ProcDirEntry * the parent node of the node to be remove. + * + * @par Dependency: + *
          • proc_fs.h: the header file that contains the API declaration.
          + * @see + * + */ +extern void RemoveProcEntry(const char *name, struct ProcDirEntry *parent); + +/** + * @ingroup procfs + * @brief create a proc directory node + * + * @par Description: + * This API is used to create the directory node by 'name' and parent vnode + * + * @attention + *
            + *
          • This interface should be called after system initialization.
          • + *
          • The parameter name should be a valid string.
          • + *
          + * + * @param name [IN] Type #const char * The name of the node directory to be created. + * @param parent [IN] Type #struct ProcDirEntry * the parent node of the directory node to be created, + * if pass NULL, default parent node is "/proc". + * + * @retval #NULL Create failed. + * @retval #ProcDirEntry* Create successfully. + * @par Dependency: + *
          • proc_fs.h: the header file that contains the API declaration.
          + * @see + * + */ +extern struct ProcDirEntry *ProcMkdir(const char *name, struct ProcDirEntry *parent); + +/** + * @ingroup procfs + * @brief create a proc node + * + * @par Description: + * This API is used to create the node by 'name' and parent vnode, + * And assignment operation function + * + * @attention + *
            + *
          • This interface should be called after system initialization.
          • + *
          • The parameter name should be a valid string.
          • + *
          + * + * @param name [IN] Type #const char * The name of the node to be created. + * @param mode [IN] Type #mode_t the mode of create's node. + * @param parent [IN] Type #struct ProcDirEntry * the parent node of the node to be created. + * @param procFops [IN] Type #const struct ProcFileOperations * operation function of the node. + * + * @retval #NULL Create failed. + * @retval #ProcDirEntry* Create successfully. + * @par Dependency: + *
          • proc_fs.h: the header file that contains the API declaration.
          + * @see + * + */ +extern struct ProcDirEntry *ProcCreate(const char *name, mode_t mode, + struct ProcDirEntry *parent, const struct ProcFileOperations *procFops); + +/** + * @ingroup procfs + * @brief create a proc node + * + * @par Description: + * This API is used to create the node by 'name' and parent vnode, + * And assignment operation function + * + * @attention + *
            + *
          • This interface should be called after system initialization.
          • + *
          • The parameter name should be a valid string.
          • + *
          + * + * @param name [IN] Type #const char * The name of the node to be created. + * @param mode [IN] Type #mode_t the mode of create's node. + * @param parent [IN] Type #struct ProcDirEntry * the parent node of the node to be created. + * @param procFops [IN] Type #const struct ProcFileOperations * operation function of the node. + * @param data [IN] Type #void * data of the node. + * + * @retval #NULL Create failed. + * @retval #ProcDirEntry* Create successfully. + * @par Dependency: + *
          • proc_fs.h: the header file that contains the API declaration.
          + * @see + * + */ +extern struct ProcDirEntry *ProcCreateData(const char *name, mode_t mode, struct ProcDirEntry *parent, + const struct ProcFileOperations *procFileOps, struct ProcDataParm *param); +/** + * @ingroup procfs + * @brief init proc fs + * + * @par Description: + * This API is used to init proc fs. + * + * @attention + *
            + *
          • None.
          • + *
          + * + * @param NONE + * + * @retval NONE + * @par Dependency: + *
          • proc_fs.h: the header file that contains the API declaration.
          + * @see ProcFsInit + * + */ +extern void ProcFsInit(void); + +extern struct ProcDirEntry *VnodeToEntry(struct Vnode *node); +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* LOSCFG_FS_PROC */ +#endif /* _PROC_FS_H */ diff --git a/src/kernel_liteos_a/fs/proc/os_adapt/fd_proc.c b/src/kernel_liteos_a/fs/proc/os_adapt/fd_proc.c new file mode 100644 index 00000000..1c658b39 --- /dev/null +++ b/src/kernel_liteos_a/fs/proc/os_adapt/fd_proc.c @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "proc_fs.h" + +#include +#include "fs/file.h" +#include "vfs_config.h" +#include "internal.h" + +#include "fs/fd_table.h" +#include "los_process.h" +#include "capability_api.h" +#include "capability_type.h" + + +/* + * Template: Pid Fd [SysFd ] Name + */ +static void FillFdInfo(struct SeqBuf *seqBuf, struct filelist *fileList, unsigned int pid, bool hasPrivilege) +{ + int fd; + int sysFd; + char *name = NULL; + struct file *filp = NULL; + + struct fd_table_s *fdt = LOS_GetFdTable(pid); + if ((fdt == NULL) || (fdt->proc_fds == NULL)) { + return; + } + + (void)sem_wait(&fdt->ft_sem); + + for (fd = MIN_START_FD; fd < fdt->max_fds; fd++) { + if (FD_ISSET(fd, fdt->proc_fds)) { + sysFd = fdt->ft_fds[fd].sysFd; + if (sysFd < CONFIG_NFILE_DESCRIPTORS) { + filp = &fileList->fl_files[sysFd]; + name = filp->f_path; + } else if (sysFd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS)) { + name = "(socks)"; + } else if (sysFd < (FD_SETSIZE + CONFIG_NTIME_DESCRIPTORS)) { + name = "(timer)"; + } else if (sysFd < (MQUEUE_FD_OFFSET + CONFIG_NQUEUE_DESCRIPTORS)) { + name = "(mqueue)"; + } else if (sysFd < (EPOLL_FD_OFFSET + CONFIG_EPOLL_DESCRIPTORS)) { + name = "(epoll)"; + } else { + name = "(unknown)"; + } + + if (hasPrivilege) { + (void)LosBufPrintf(seqBuf, "%u\t%d\t%6d <%d>\t%s\n", pid, fd, sysFd, filp ? filp->f_refcount : 1, name); + } else { + (void)LosBufPrintf(seqBuf, "%u\t%d\t%s\n", pid, fd, name); + } + } + } + + (void)sem_post(&fdt->ft_sem); +} + +static int FdProcFill(struct SeqBuf *seqBuf, void *v) +{ + int pidNum; + bool hasPrivilege; + unsigned int pidMaxNum; + unsigned int *pidList = NULL; + + /* privilege user */ + if (IsCapPermit(CAP_DAC_READ_SEARCH)) { + pidMaxNum = LOS_GetSystemProcessMaximum(); + pidList = (unsigned int *)malloc(pidMaxNum * sizeof(unsigned int)); + if (pidList == NULL) { + return -ENOMEM; + } + pidNum = LOS_GetUsedPIDList(pidList, pidMaxNum); + hasPrivilege = true; + (void)LosBufPrintf(seqBuf, "%s\t%s\t%6s %s\t%s\n", "Pid", "Fd", "SysFd", "", "Name"); + } else { + pidNum = 1; + pidList = (unsigned int *)malloc(pidNum * sizeof(unsigned int)); + if (pidList == NULL) { + return -ENOMEM; + } + pidList[0] = LOS_GetCurrProcessID(); + hasPrivilege = false; + (void)LosBufPrintf(seqBuf, "Pid\tFd\tName\n"); + } + + struct filelist *fileList = &tg_filelist; + (void)sem_wait(&fileList->fl_sem); + + for (int i = 0; i < pidNum; i++) { + FillFdInfo(seqBuf, fileList, pidList[i], hasPrivilege); + } + + free(pidList); + (void)sem_post(&fileList->fl_sem); + return 0; +} + +static const struct ProcFileOperations FD_PROC_FOPS = { + .read = FdProcFill, +}; + +void ProcFdInit(void) +{ + struct ProcDirEntry *pde = CreateProcEntry("fd", 0, NULL); + if (pde == NULL) { + PRINT_ERR("create /proc/fd error.\n"); + return; + } + + pde->procFileOps = &FD_PROC_FOPS; +} + diff --git a/src/kernel_liteos_a/fs/proc/os_adapt/file_sys.c b/src/kernel_liteos_a/fs/proc/os_adapt/file_sys.c new file mode 100644 index 00000000..2fc5836e --- /dev/null +++ b/src/kernel_liteos_a/fs/proc/os_adapt/file_sys.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fs/fs.h" +#include "proc_fs.h" +#include "proc_file.h" +#include "errno.h" +#include "sys/mount.h" + +extern struct fsmap_t g_fsmap[]; +extern struct fsmap_t g_fsmap_end; + +static int FsFileSysProcRead(struct SeqBuf *seqBuf, void *buf) +{ + (void)buf; + + struct fsmap_t *m = NULL; + for (m = &g_fsmap[0]; m != &g_fsmap_end; ++m) { + if (m->fs_filesystemtype) { + if (m->is_bdfs == true) { + (void)LosBufPrintf(seqBuf, "\n %s\n", m->fs_filesystemtype); + } else { + (void)LosBufPrintf(seqBuf, "%s %s\n", "nodev", m->fs_filesystemtype); + } + } + } + return 0; +} + +static const struct ProcFileOperations FILESYS_PROC_FOPS = { + .read = FsFileSysProcRead, +}; + +void ProcFileSysInit(void) +{ + struct ProcDirEntry *pde = CreateProcEntry("filesystems", 0, NULL); + if (pde == NULL) { + PRINT_ERR("creat /proc/filesystems error!\n"); + return; + } + pde->procFileOps = &FILESYS_PROC_FOPS; +} diff --git a/src/kernel_liteos_a/fs/proc/os_adapt/fs_cache_proc.c b/src/kernel_liteos_a/fs/proc/os_adapt/fs_cache_proc.c new file mode 100644 index 00000000..19bcdb02 --- /dev/null +++ b/src/kernel_liteos_a/fs/proc/os_adapt/fs_cache_proc.c @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "internal.h" +#include "proc_fs.h" +#include "vnode.h" +#include "path_cache.h" +#include "los_vm_filemap.h" + +#ifdef LOSCFG_DEBUG_VERSION + +#define CLEAR_ALL_CACHE "clear all" +#define CLEAR_PATH_CACHE "clear pathcache" +#define CLEAR_PAGE_CACHE "clear pagecache" + +static char* VnodeTypeToStr(enum VnodeType type) +{ + switch (type) { + case VNODE_TYPE_UNKNOWN: + return "UKN"; + case VNODE_TYPE_REG: + return "REG"; + case VNODE_TYPE_DIR: + return "DIR"; + case VNODE_TYPE_BLK: + return "BLK"; + case VNODE_TYPE_CHR: + return "CHR"; + case VNODE_TYPE_BCHR: + return "BCH"; + case VNODE_TYPE_FIFO: + return "FIF"; + case VNODE_TYPE_LNK: + return "LNK"; + default: + return "BAD"; + } +} + +static int VnodeListProcess(struct SeqBuf *buf, LIST_HEAD* list) +{ + int count = 0; + struct Vnode *item = NULL; + struct Vnode *nextItem = NULL; + + LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, list, struct Vnode, actFreeEntry) { + LosBufPrintf(buf, "%-10p %-10p %-10p %10p 0x%08x %-3d %-4s %-3d %-3d %-8o\t%s\n", + item, item->parent, item->data, item->vop, item->hash, item->useCount, + VnodeTypeToStr(item->type), item->gid, item->uid, item->mode, item->filePath); + count++; + } + + return count; +} + +static int PathCacheListProcess(struct SeqBuf *buf) +{ + int count = 0; + LIST_HEAD* bucketList = GetPathCacheList(); + + for (int i = 0; i < LOSCFG_MAX_PATH_CACHE_SIZE; i++) { + struct PathCache *pc = NULL; + LIST_HEAD *list = &bucketList[i]; + + LOS_DL_LIST_FOR_EACH_ENTRY(pc, list, struct PathCache, hashEntry) { + LosBufPrintf(buf, "%-3d %-10p %-11p %-10p %-9d %s\n", i, pc, + pc->parentVnode, pc->childVnode, pc->hit, pc->name); + count++; + } + } + + return count; +} + +static int PageCacheEntryProcess(struct SeqBuf *buf, struct page_mapping *mapping) +{ + int total = 0; + LosFilePage *fpage = NULL; + + if (mapping->nrpages == 0) { + LosBufPrintf(buf, "null]\n"); + return total; + } + + LOS_DL_LIST_FOR_EACH_ENTRY(fpage, &mapping->page_list, LosFilePage, node) { + LosBufPrintf(buf, "%d,", fpage->pgoff); + total++; + } + LosBufPrintf(buf, "]\n"); + return total; +} + +static int PageCacheMapProcess(struct SeqBuf *buf) +{ + LIST_HEAD *vnodeList = GetVnodeActiveList(); + struct page_mapping *mapping = NULL; + struct Vnode *vnode = NULL; + int total = 0; + + VnodeHold(); + LOS_DL_LIST_FOR_EACH_ENTRY(vnode, vnodeList, struct Vnode, actFreeEntry) { + mapping = &vnode->mapping; + LosBufPrintf(buf, "%p, %s:[", vnode, vnode->filePath); + total += PageCacheEntryProcess(buf, mapping); + } + VnodeDrop(); + return total; +} + +static int FsCacheInfoFill(struct SeqBuf *buf, void *arg) +{ + int vnodeFree; + int vnodeActive; + int vnodeVirtual; + int vnodeTotal; + + int pathCacheTotal; + int pathCacheTotalTry = 0; + int pathCacheTotalHit = 0; + + int pageCacheTotal; + int pageCacheTotalTry = 0; + int pageCacheTotalHit = 0; + + ResetPathCacheHitInfo(&pathCacheTotalHit, &pathCacheTotalTry); + ResetPageCacheHitInfo(&pageCacheTotalTry, &pageCacheTotalHit); + + VnodeHold(); + LosBufPrintf(buf, "\n=================================================================\n"); + LosBufPrintf(buf, + "VnodeAddr ParentAddr DataAddr VnodeOps Hash Ref Type Gid Uid Mode\n"); + vnodeVirtual = VnodeListProcess(buf, GetVnodeVirtualList()); + vnodeFree = VnodeListProcess(buf, GetVnodeFreeList()); + vnodeActive = VnodeListProcess(buf, GetVnodeActiveList()); + vnodeTotal = vnodeVirtual + vnodeFree + vnodeActive; + + LosBufPrintf(buf, "\n=================================================================\n"); + LosBufPrintf(buf, "No. CacheAddr ParentAddr ChildAddr HitCount Name\n"); + pathCacheTotal = PathCacheListProcess(buf); + + LosBufPrintf(buf, "\n=================================================================\n"); + pageCacheTotal = PageCacheMapProcess(buf); + + LosBufPrintf(buf, "\n=================================================================\n"); + LosBufPrintf(buf, "PathCache Total:%d Try:%d Hit:%d\n", + pathCacheTotal, pathCacheTotalTry, pathCacheTotalHit); + LosBufPrintf(buf, "Vnode Total:%d Free:%d Virtual:%d Active:%d\n", + vnodeTotal, vnodeFree, vnodeVirtual, vnodeActive); + LosBufPrintf(buf, "PageCache total:%d Try:%d Hit:%d\n", pageCacheTotal, pageCacheTotalTry, pageCacheTotalHit); + VnodeDrop(); + return 0; +} + +static int FsCacheClear(struct ProcFile *pf, const char *buffer, size_t buflen, loff_t *ppos) +{ + if (buffer == NULL || buflen < sizeof(CLEAR_ALL_CACHE)) { + return -EINVAL; + } + int vnodeCount = 0; + int pageCount = 0; + + if (!strcmp(buffer, CLEAR_ALL_CACHE)) { + vnodeCount = VnodeClearCache(); + pageCount = OsTryShrinkMemory(VM_FILEMAP_MAX_SCAN); + } else if (!strcmp(buffer, CLEAR_PAGE_CACHE)) { + pageCount = OsTryShrinkMemory(VM_FILEMAP_MAX_SCAN); + } else if (!strcmp(buffer, CLEAR_PATH_CACHE)) { + vnodeCount = VnodeClearCache(); + } else { + return -EINVAL; + } + + PRINTK("%d vnodes and related pathcaches cleared\n%d pages cleared\n", vnodeCount, pageCount); + return buflen; +} +static const struct ProcFileOperations FS_CACHE_PROC_FOPS = { + .read = FsCacheInfoFill, + .write = FsCacheClear, +}; + +void ProcFsCacheInit(void) +{ + struct ProcDirEntry *pde = CreateProcEntry("fs_cache", 0400, NULL); + if (pde == NULL) { + PRINT_ERR("create fs_cache error!\n"); + return; + } + + pde->procFileOps = &FS_CACHE_PROC_FOPS; +} +#else +void ProcFsCacheInit(void) +{ + /* do nothing in release version */ +} +#endif diff --git a/src/kernel_liteos_a/fs/proc/os_adapt/mem_info.c b/src/kernel_liteos_a/fs/proc/os_adapt/mem_info.c new file mode 100644 index 00000000..c67363aa --- /dev/null +++ b/src/kernel_liteos_a/fs/proc/os_adapt/mem_info.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "internal.h" +#include "proc_fs.h" +#include "vnode.h" +#include "los_memory.h" +#include "los_vm_filemap.h" +#include "los_memory_pri.h" + +static int SysMemInfoFill(struct SeqBuf *seqBuf, void *arg) +{ + (void)arg; + LOS_MEM_POOL_STATUS mem = {0}; + if (LOS_MemInfoGet(m_aucSysMem0, &mem) == LOS_NOK) { + return -EBADF; + } + (void)LosBufPrintf(seqBuf, "\nUsedSize: %u byte\n", mem.totalUsedSize); + (void)LosBufPrintf(seqBuf, "FreeSize: %u byte\n", mem.totalFreeSize); + (void)LosBufPrintf(seqBuf, "MaxFreeNodeSize: %u byte\n", mem.maxFreeNodeSize); + (void)LosBufPrintf(seqBuf, "UsedNodeNum: %u\n", mem.usedNodeNum); + (void)LosBufPrintf(seqBuf, "FreeNodeNum: %u\n", mem.freeNodeNum); +#ifdef LOSCFG_MEM_WATERLINE + (void)LosBufPrintf(seqBuf, "UsageWaterLine: %u byte\n", mem.usageWaterLine); +#endif + return 0; +} + +static const struct ProcFileOperations SYS_MEMINFO_PROC_FOPS = { + .read = SysMemInfoFill, +}; + +void ProcSysMemInfoInit(void) +{ + struct ProcDirEntry *pde = CreateProcEntry("meminfo", 0, NULL); + if (pde == NULL) { + PRINT_ERR("create mem_info error!\n"); + return; + } + + pde->procFileOps = &SYS_MEMINFO_PROC_FOPS; +} diff --git a/src/kernel_liteos_a/fs/proc/os_adapt/mounts_proc.c b/src/kernel_liteos_a/fs/proc/os_adapt/mounts_proc.c new file mode 100644 index 00000000..bc36dc9f --- /dev/null +++ b/src/kernel_liteos_a/fs/proc/os_adapt/mounts_proc.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "proc_fs.h" + +#include +#include +#include + +#include "fs/mount.h" +#include "internal.h" + +static int ShowType(const char *devPoint, const char *mountPoint, struct statfs *statBuf, void *arg) +{ + struct SeqBuf *seqBuf = (struct SeqBuf *)arg; + char *type = NULL; + + switch (statBuf->f_type) { + case PROCFS_MAGIC: + type = "proc"; + break; + case JFFS2_SUPER_MAGIC: + type = "jffs2"; + break; + case NFS_SUPER_MAGIC: + type = "nfs"; + break; + case TMPFS_MAGIC: + type = "tmpfs"; + break; + case MSDOS_SUPER_MAGIC: + type = "vfat"; + break; + case ZPFS_MAGIC: + type = "zpfs"; + break; + default: + return 0; + } + + if (strlen(devPoint) == 0) { + (void)LosBufPrintf(seqBuf, "%s %s %s %s %d %d\n", type, mountPoint, type, "()", 0, 0); + } else { + (void)LosBufPrintf(seqBuf, "%s %s %s %s %d %d\n", devPoint, mountPoint, type, "()", 0, 0); + } + + return 0; +} + +static int MountsProcFill(struct SeqBuf *m, void *v) +{ + foreach_mountpoint_t handler = ShowType; + (void)foreach_mountpoint(handler, (void *)m); + + return 0; +} + +static const struct ProcFileOperations MOUNTS_PROC_FOPS = { + .read = MountsProcFill, +}; + +void ProcMountsInit(void) +{ + struct ProcDirEntry *pde = CreateProcEntry("mounts", 0, NULL); + if (pde == NULL) { + PRINT_ERR("create mounts error!\n"); + return; + } + + pde->procFileOps = &MOUNTS_PROC_FOPS; +} + diff --git a/src/kernel_liteos_a/fs/proc/os_adapt/plimits_proc.c b/src/kernel_liteos_a/fs/proc/os_adapt/plimits_proc.c new file mode 100644 index 00000000..b18bd84e --- /dev/null +++ b/src/kernel_liteos_a/fs/proc/os_adapt/plimits_proc.c @@ -0,0 +1,905 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include "stdlib.h" +#include "los_printf.h" +#include "los_base.h" +#include "los_seq_buf.h" +#include "internal.h" +#include "proc_fs.h" +#include "los_task_pri.h" +#include "los_process_pri.h" +#include "los_process.h" +#include "show.h" +#include "vnode.h" +#include "proc_file.h" +#include "user_copy.h" + +#ifdef LOSCFG_KERNEL_PLIMITS +#include "los_plimits.h" + +#define PLIMITS_ENTRY_NAME_MAX 64 +#define PLIMITERSET_DELETE_ALLOC 4 +#define UNITPTR_NULL ((uintptr_t)(0xFFFFFFFF)) +#define PLIMIT_FILE_MODE_READ_WRITE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) +#define PLIMIT_FILE_MODE_READ_ONLY (S_IRUSR | S_IRGRP | S_IROTH) +#define PLIMIT_FILE_MODE_WRITE_ONLY (S_IWUSR) +#define PLIMIT_FILE_MODE_MASK_WRITE (~((mode_t)(S_IWUSR))) +#define PLIMIT_FILE_MODE_MASK_NONE (~((mode_t)(0))) +#define LOS_MAX_CACHE (UINT64)(0xFFFFFFFFFFFFFFFF) +#define PLIMIT_CAT_BUF_SIZE 512 +#define MAX_PROTECTED_PROCESS_ID 14 +#define UNITPTR_NULL ((uintptr_t)(0xFFFFFFFF)) + +static int ShowPids(struct SeqBuf *seqBuf, VOID *data); +static ssize_t PidMigrateFromProcLimiterSet(struct ProcFile *pf, const CHAR *buf, size_t count, loff_t *ppos); +static ssize_t PidLimitReadPidLimit(struct SeqBuf *seqBuf, VOID *data); +static ssize_t PidLimitReadPriorityLimit(struct SeqBuf *seqBuf, VOID *data); +static ssize_t PriorityLimitVariableWrite(struct ProcFile *pf, const CHAR *buf, size_t count, loff_t *ppos); +static ssize_t PidsMaxVariableWrite(struct ProcFile *pf, const CHAR *buf, size_t count, loff_t *ppos); +static ssize_t ProcLimitsShowLimiters(struct SeqBuf *seqBuf, VOID *data); +static int ProcfsPlimitsMkdir(struct ProcDirEntry *parent, const char *dirName, mode_t mode, struct ProcDirEntry **pde); +static int ProcfsPlimitsRmdir(struct ProcDirEntry *parent, struct ProcDirEntry *pde, const char *name); +#ifdef LOSCFG_KERNEL_MEM_PLIMIT +static ssize_t MemLimitReadLimit(struct SeqBuf *seqBuf, VOID *data); +static ssize_t MemLimitWriteLimit(struct ProcFile *pf, const CHAR *buf, size_t count, loff_t *ppos); +static ssize_t MemLimitStatShow(struct SeqBuf *seqBuf, VOID *data); +#endif +#ifdef LOSCFG_KERNEL_IPC_PLIMIT +static ssize_t IPCLimitReadMqLimit(struct SeqBuf *seqBuf, VOID *data); +static ssize_t IPCLimitWriteMqLimit(struct ProcFile *pf, const CHAR *buf, size_t count, loff_t *ppos); +static ssize_t IPCLimitReadShmLimit(struct SeqBuf *seqBuf, VOID *data); +static ssize_t IPCLimitWriteShmLimit(struct ProcFile *pf, const CHAR *buf, size_t count, loff_t *ppos); +static ssize_t IPCLimitShowStat(struct SeqBuf *seqBuf, VOID *data); +#endif +#ifdef LOSCFG_KERNEL_DEV_PLIMIT +static ssize_t DevLimitWriteAllow(struct ProcFile *pf, const CHAR *buf, size_t count, loff_t *ppos); +static ssize_t DevLimitWriteDeny(struct ProcFile *pf, const CHAR *buf, size_t count, loff_t *ppos); +static ssize_t DevLimitShow(struct SeqBuf *seqBuf, VOID *data); +#endif +#ifdef LOSCFG_KERNEL_SCHED_PLIMIT +static ssize_t SchedLimitReadPeriod(struct SeqBuf *seqBuf, VOID *data); +static ssize_t SchedLimitWritePeriod(struct ProcFile *pf, const CHAR *buf, size_t count, loff_t *ppos); +static ssize_t SchedLimitReadQuota(struct SeqBuf *seqBuf, VOID *data); +static ssize_t SchedLimitWriteQuota(struct ProcFile *pf, const CHAR *buf, size_t count, loff_t *ppos); +static ssize_t SchedLimitShow(struct SeqBuf *seqBuf, VOID *data); +#endif + +struct PLimitsEntryOpt { + int id; + char name[PLIMITS_ENTRY_NAME_MAX]; + mode_t mode; + uintptr_t offset; + struct ProcFileOperations ops; +}; + +static struct ProcDirOperations g_procDirOperations = { + .mkdir = ProcfsPlimitsMkdir, + .rmdir = ProcfsPlimitsRmdir, +}; + +static struct PLimitsEntryOpt g_plimitsEntryOpts[] = { + { + .id = PROCESS_LIMITER_COUNT, + .name = "plimits.limiters", + .mode = PLIMIT_FILE_MODE_READ_ONLY, + .offset = UNITPTR_NULL, + .ops = { + .read = ProcLimitsShowLimiters, + } + }, + { + .id = PROCESS_LIMITER_COUNT, + .name = "plimits.procs", + .mode = PLIMIT_FILE_MODE_READ_WRITE, + .offset = UNITPTR_NULL, + .ops = { + .read = ShowPids, + .write = PidMigrateFromProcLimiterSet, + }, + }, + { + .id = PROCESS_LIMITER_ID_PIDS, + .name = "pids.max", + .mode = PLIMIT_FILE_MODE_READ_WRITE, + .offset = 0, + .ops = { + .read = PidLimitReadPidLimit, + .write = PidsMaxVariableWrite, + }, + }, + { + .id = PROCESS_LIMITER_ID_PIDS, + .name = "pids.priority", + .mode = PLIMIT_FILE_MODE_READ_WRITE, + .offset = 0, + .ops = { + .read = PidLimitReadPriorityLimit, + .write = PriorityLimitVariableWrite, + }, + }, +#ifdef LOSCFG_KERNEL_MEM_PLIMIT + { + .id = PROCESS_LIMITER_ID_MEM, + .name = "memory.limit", + .mode = PLIMIT_FILE_MODE_READ_WRITE, + .offset = 0, + .ops = { + .read = MemLimitReadLimit, + .write = MemLimitWriteLimit, + }, + }, + { + .id = PROCESS_LIMITER_ID_MEM, + .name = "memory.stat", + .mode = PLIMIT_FILE_MODE_READ_ONLY, + .offset = UNITPTR_NULL, + .ops = { + .read = MemLimitStatShow, + } + }, +#endif +#ifdef LOSCFG_KERNEL_IPC_PLIMIT + { + .id = PROCESS_LIMITER_ID_IPC, + .name = "ipc.mq_limit", + .mode = PLIMIT_FILE_MODE_READ_WRITE, + .offset = 0, + .ops = { + .read = IPCLimitReadMqLimit, + .write = IPCLimitWriteMqLimit, + } + }, + { + .id = PROCESS_LIMITER_ID_IPC, + .name = "ipc.shm_limit", + .mode = PLIMIT_FILE_MODE_READ_WRITE, + .offset = 0, + .ops = { + .read = IPCLimitReadShmLimit, + .write = IPCLimitWriteShmLimit, + } + }, + { + .id = PROCESS_LIMITER_ID_IPC, + .name = "ipc.stat", + .mode = PLIMIT_FILE_MODE_READ_ONLY, + .offset = UNITPTR_NULL, + .ops = { + .read = IPCLimitShowStat, + } + }, +#endif +#ifdef LOSCFG_KERNEL_DEV_PLIMIT + { + .id = PROCESS_LIMITER_ID_DEV, + .name = "devices.allow", + .mode = PLIMIT_FILE_MODE_WRITE_ONLY, + .offset = UNITPTR_NULL, + .ops = { + .write = DevLimitWriteAllow, + } + }, + { + .id = PROCESS_LIMITER_ID_DEV, + .name = "devices.deny", + .mode = PLIMIT_FILE_MODE_WRITE_ONLY, + .offset = UNITPTR_NULL, + .ops = { + .write = DevLimitWriteDeny, + } + }, + { + .id = PROCESS_LIMITER_ID_DEV, + .name = "devices.list", + .mode = PLIMIT_FILE_MODE_READ_ONLY, + .offset = 0, + .ops = { + .read = DevLimitShow, + } + }, +#endif +#ifdef LOSCFG_KERNEL_SCHED_PLIMIT + { + .id = PROCESS_LIMITER_ID_SCHED, + .name = "sched.period", + .mode = PLIMIT_FILE_MODE_READ_WRITE, + .offset = 0, + .ops = { + .read = SchedLimitReadPeriod, + .write = SchedLimitWritePeriod, + }, + }, + { + .id = PROCESS_LIMITER_ID_SCHED, + .name = "sched.quota", + .mode = PLIMIT_FILE_MODE_READ_WRITE, + .offset = 0, + .ops = { + .read = SchedLimitReadQuota, + .write = SchedLimitWriteQuota, + }, + }, + { + .id = PROCESS_LIMITER_ID_SCHED, + .name = "sched.stat", + .mode = PLIMIT_FILE_MODE_READ_ONLY, + .offset = UNITPTR_NULL, + .ops = { + .read = SchedLimitShow, + } + }, +#endif +}; + +static unsigned int MemUserCopy(const char *src, size_t len, char **kbuf) +{ + if (LOS_IsUserAddressRange((VADDR_T)(UINTPTR)src, len)) { + char *kernelBuf = LOS_MemAlloc(m_aucSysMem1, len + 1); + if (kernelBuf == NULL) { + return ENOMEM; + } + + if (LOS_ArchCopyFromUser(kernelBuf, src, len) != 0) { + (VOID)LOS_MemFree(m_aucSysMem1, kernelBuf); + return EFAULT; + } + kernelBuf[len] = '\0'; + *kbuf = kernelBuf; + return 0; + } + return 0; +} + +static inline struct ProcDirEntry *GetCurrDirectory(struct ProcDirEntry *dirEntry) +{ + return ((dirEntry == NULL) || S_ISDIR(dirEntry->mode)) ? dirEntry : dirEntry->parent; +} + +static inline ProcLimiterSet *GetProcLimiterSetFromDirEntry(struct ProcDirEntry *dirEntry) +{ + struct ProcDirEntry *currDirectory = GetCurrDirectory(dirEntry); + return (currDirectory == NULL) || (currDirectory->data == NULL) ? NULL : (ProcLimiterSet *)currDirectory->data; +} + +static struct ProcDirEntry *ProcCreateLimiterFiles(struct ProcDirEntry *parentEntry, + struct PLimitsEntryOpt *entryOpt, + mode_t mode, void *data) +{ + struct ProcDataParm dataParm = { + .data = data, + .dataType = PROC_DATA_STATIC, + }; + struct ProcDirEntry *plimitFile = ProcCreateData(entryOpt->name, entryOpt->mode & mode, parentEntry, + &entryOpt->ops, &dataParm); + if (plimitFile == NULL) { + return NULL; + } + return plimitFile; +} + +static void ProcLimiterDirEntryInit(struct ProcDirEntry *dirEntry, unsigned mask, mode_t mode) +{ + struct ProcDirEntry *currDir = GetCurrDirectory(dirEntry); + if (currDir == NULL) { + return; + } + + ProcLimiterSet *plimiterData = (ProcLimiterSet *)currDir->data; + if (plimiterData == NULL) { + return; + } + + for (int index = 0; index < (sizeof(g_plimitsEntryOpts) / sizeof(struct PLimitsEntryOpt)); index++) { + struct PLimitsEntryOpt *entryOpt = &g_plimitsEntryOpts[index]; + enum ProcLimiterID plimiterType = entryOpt->id; + if (!(BIT(plimiterType) & mask)) { + continue; + } + + void *head = (entryOpt->offset == UNITPTR_NULL) ? + plimiterData : (void *)plimiterData->limitsList[plimiterType]; + struct ProcDirEntry *entry = ProcCreateLimiterFiles(currDir, entryOpt, mode, head); + if (entry == NULL) { + RemoveProcEntry(currDir->name, NULL); + return; + } + } + return; +} + +static ssize_t PLimitsCopyLimits(struct ProcDirEntry *dirEntry) +{ + struct ProcDirEntry *parentPde = dirEntry->parent; + ProcLimiterSet *parentPLimits = (ProcLimiterSet *)parentPde->data; + if (parentPLimits == NULL) { + return -EINVAL; + } + + ProcLimiterSet *newPLimits = OsPLimitsCreate(parentPLimits); + if (newPLimits == NULL) { + return -ENOMEM; + } + dirEntry->data = (VOID *)newPLimits; + dirEntry->dataType = PROC_DATA_STATIC; + dirEntry->procDirOps = parentPde->procDirOps; + ProcLimiterDirEntryInit(dirEntry, newPLimits->mask, PLIMIT_FILE_MODE_MASK_NONE); + return 0; +} + +static int ProcfsPlimitsMkdir(struct ProcDirEntry *parent, const char *dirName, mode_t mode, struct ProcDirEntry **pde) +{ + int ret; + if (strcmp(parent->name, "plimits") != 0) { + return -EPERM; + } + + struct ProcDirEntry *plimitDir = ProcCreateData(dirName, S_IFDIR | mode, parent, NULL, NULL); + if (plimitDir == NULL) { + return -EINVAL; + } + + ret = PLimitsCopyLimits(plimitDir); + if (ret != LOS_OK) { + ProcFreeEntry(plimitDir); + return -ENOSYS; + } + *pde = plimitDir; + return ret; +} + +static int ProcfsPlimitsRmdir(struct ProcDirEntry *parent, struct ProcDirEntry *pde, const char *name) +{ + if (pde == NULL) { + return -EINVAL; + } + + ProcLimiterSet *plimits = GetProcLimiterSetFromDirEntry(pde); + pde->data = NULL; + + unsigned ret = OsPLimitsFree(plimits); + if (ret != 0) { + pde->data = plimits; + return -ret; + } + + spin_lock(&procfsLock); + ProcDetachNode(pde); + spin_unlock(&procfsLock); + + RemoveProcEntryTravalsal(pde->subdir); + + ProcFreeEntry(pde); + return 0; +} + +static ssize_t ProcLimitsShowLimiters(struct SeqBuf *seqBuf, VOID *data) +{ + ProcLimiterSet *plimits = (ProcLimiterSet *)data; + UINT32 mask; + if (plimits == NULL) { + return -LOS_NOK; + } + mask = plimits->mask; + + if (mask & BIT(PROCESS_LIMITER_ID_PIDS)) { + LosBufPrintf(seqBuf, "%s ", "pids"); + } +#ifdef LOSCFG_KERNEL_MEM_PLIMIT + if (mask & BIT(PROCESS_LIMITER_ID_MEM)) { + LosBufPrintf(seqBuf, "%s ", "memory"); + } +#endif +#ifdef LOSCFG_KERNEL_IPC_PLIMIT + if (mask & BIT(PROCESS_LIMITER_ID_IPC)) { + LosBufPrintf(seqBuf, "%s ", "ipc"); + } +#endif +#ifdef LOSCFG_KERNEL_DEV_PLIMIT + if (mask & BIT(PROCESS_LIMITER_ID_DEV)) { + LosBufPrintf(seqBuf, "%s ", "devices"); + } +#endif +#ifdef LOSCFG_KERNEL_SCHED_PLIMIT + if (mask & BIT(PROCESS_LIMITER_ID_SCHED)) { + LosBufPrintf(seqBuf, "%s ", "sched"); + } +#endif + return LOS_OK; +} + +#define PLIMITS_PID_STR_LENGTH 4 +static int ShowPids(struct SeqBuf *seqBuf, VOID *data) +{ + unsigned int size, pidMax; + if (data == NULL) { + return -EINVAL; + } + + const ProcLimiterSet *plimits = (const ProcLimiterSet *)data; + pidMax = LOS_GetSystemProcessMaximum(); + size = pidMax * sizeof(unsigned int); + unsigned int *pids = (unsigned int *)LOS_MemAlloc(m_aucSysMem1, size); + if (pids == NULL) { + return -ENOMEM; + } + (void)memset_s(pids, size, 0, size); + + unsigned int ret = OsPLimitsPidsGet(plimits, pids, size); + if (ret != LOS_OK) { + (VOID)LOS_MemFree(m_aucSysMem1, pids); + return -ret; + } + + (void)LosBufPrintf(seqBuf, "\n"); + for (unsigned int index = 0; index < pidMax; index++) { + if (pids[index] == 0) { + continue; + } + (void)LosBufPrintf(seqBuf, "%u ", index); + } + (void)LOS_MemFree(m_aucSysMem1, pids); + return 0; +} + +static long long int GetPidLimitValue(struct ProcFile *pf, const CHAR *buf, size_t count) +{ + long long int value; + char *kbuf = NULL; + + if ((pf == NULL) || (pf->pPDE == NULL) || (buf == NULL) || (count <= 0)) { + return -EINVAL; + } + + unsigned ret = MemUserCopy(buf, count, &kbuf); + if (ret != 0) { + return -ret; + } else if ((ret == 0) && (kbuf != NULL)) { + buf = (const char *)kbuf; + } + + if (strspn(buf, "0123456789") != count) { + (void)LOS_MemFree(m_aucSysMem1, kbuf); + return -EINVAL; + } + value = strtoll(buf, NULL, 10); /* 10: decimal */ + (void)LOS_MemFree(m_aucSysMem1, kbuf); + return value; +} + +static ssize_t PidMigrateFromProcLimiterSet(struct ProcFile *pf, const CHAR *buf, size_t count, loff_t *ppos) +{ + (VOID)ppos; + unsigned ret; + + long long int pid = GetPidLimitValue(pf, buf, count); + if (pid < 0) { + return pid; + } + + ProcLimiterSet *plimits = GetCurrDirectory(pf->pPDE)->data; + ret = OsPLimitsAddPid(plimits, (unsigned int)pid); + if (ret != LOS_OK) { + return -ret; + } + return count; +} + +static ssize_t PidLimitReadPidLimit(struct SeqBuf *seqBuf, VOID *data) +{ + PidLimit *pidLimit = (PidLimit *)data; + if ((seqBuf == NULL) || (pidLimit == NULL)) { + return -EINVAL; + } + + (void)LosBufPrintf(seqBuf, "%u\n", pidLimit->pidLimit); + return 0; +} + +static ssize_t PidLimitReadPriorityLimit(struct SeqBuf *seqBuf, VOID *data) +{ + PidLimit *pidLimit = (PidLimit *)data; + if ((seqBuf == NULL) || (pidLimit == NULL)) { + return -EINVAL; + } + + (void)LosBufPrintf(seqBuf, "%u\n", pidLimit->priorityLimit); + return 0; +} + +static ssize_t PriorityLimitVariableWrite(struct ProcFile *pf, const CHAR *buf, size_t count, loff_t *ppos) +{ + (void)ppos; + long long int value = GetPidLimitValue(pf, buf, count); + if (value < 0) { + return value; + } + + PidLimit *pidLimit = (PidLimit *)pf->pPDE->data; + unsigned ret = PidLimitSetPriorityLimit(pidLimit, (unsigned)value); + if (ret != LOS_OK) { + return -ret; + } + return count; +} + +static ssize_t PidsMaxVariableWrite(struct ProcFile *pf, const CHAR *buf, size_t count, loff_t *ppos) +{ + (void)ppos; + long long int value = GetPidLimitValue(pf, buf, count); + if (value < 0) { + return value; + } + + PidLimit *pidLimit = (PidLimit *)pf->pPDE->data; + unsigned ret = PidLimitSetPidLimit(pidLimit, (unsigned)value); + if (ret != LOS_OK) { + return -ret; + } + return count; +} + +#ifdef LOSCFG_KERNEL_MEM_PLIMIT +static ssize_t MemLimitReadLimit(struct SeqBuf *seqBuf, VOID *data) +{ + ProcMemLimiter *memLimit = (ProcMemLimiter *)data; + if ((seqBuf == NULL) || (memLimit == NULL)) { + return -EINVAL; + } + + (void)LosBufPrintf(seqBuf, "%llu\n", memLimit->limit); + return 0; +} + +static ssize_t MemLimitWriteLimit(struct ProcFile *pf, const CHAR *buf, size_t count, loff_t *ppos) +{ + (void)ppos; + long long int value = GetPidLimitValue(pf, buf, count); + if ((value < 0) || (value > (long long int)OS_NULL_INT)) { + return value; + } + + ProcMemLimiter *memLimit = (ProcMemLimiter *)pf->pPDE->data; + unsigned ret = OsMemLimitSetMemLimit(memLimit, (unsigned long long)value); + if (ret != LOS_OK) { + return -ret; + } + return count; +} + +static ssize_t MemLimitStatShow(struct SeqBuf *seqBuf, VOID *data) +{ + ProcLimiterSet *plimits = (ProcLimiterSet *)data; + if ((seqBuf == NULL) || (plimits == NULL)) { + return -EINVAL; + } + + UINT32 pidMax = LOS_GetSystemProcessMaximum(); + UINT32 size = sizeof(ProcMemLimiter) + pidMax * sizeof(unsigned long long); + unsigned long long *usage = (unsigned long long *)LOS_MemAlloc(m_aucSysMem1, size); + if (usage == NULL) { + return -ENOMEM; + } + (void)memset_s(usage, size, 0, size); + + unsigned int ret = OsPLimitsMemUsageGet(plimits, usage, size); + if (ret != LOS_OK) { + (VOID)LOS_MemFree(m_aucSysMem1, usage); + return -ret; + } + + ProcMemLimiter *memLimit = (ProcMemLimiter *)usage; + unsigned long long *memUsage = (unsigned long long *)((uintptr_t)usage + sizeof(ProcMemLimiter)); + (void)LosBufPrintf(seqBuf, "\nMem used: %llu\n", memLimit->usage); + (void)LosBufPrintf(seqBuf, "Mem peak: %llu\n", memLimit->peak); + (void)LosBufPrintf(seqBuf, "Mem failed count: %u\n", memLimit->failcnt); + + for (unsigned int index = 0; index < pidMax; index++) { + if (memUsage[index] == 0) { + continue; + } + (void)LosBufPrintf(seqBuf, "PID: %u mem used: %llu \n", index, memUsage[index]); + } + (void)LOS_MemFree(m_aucSysMem1, usage); + return 0; +} +#endif + +#ifdef LOSCFG_KERNEL_IPC_PLIMIT +static ssize_t IPCLimitReadMqLimit(struct SeqBuf *seqBuf, VOID *data) +{ + ProcIPCLimit *ipcLimit = (ProcIPCLimit *)data; + if ((seqBuf == NULL) || (ipcLimit == NULL)) { + return -EINVAL; + } + + (void)LosBufPrintf(seqBuf, "%u\n", ipcLimit->mqCountLimit); + return 0; +} + +static ssize_t IPCLimitWriteMqLimit(struct ProcFile *pf, const CHAR *buf, size_t count, loff_t *ppos) +{ + (void)ppos; + long long int value = GetPidLimitValue(pf, buf, count); + if (value < 0) { + return value; + } + + ProcIPCLimit *ipcLimit = (ProcIPCLimit *)pf->pPDE->data; + unsigned ret = OsIPCLimitSetMqLimit(ipcLimit, (unsigned long long)value); + if (ret != LOS_OK) { + return -ret; + } + return count; +} + +static ssize_t IPCLimitReadShmLimit(struct SeqBuf *seqBuf, VOID *data) +{ + ProcIPCLimit *ipcLimit = (ProcIPCLimit *)data; + if ((seqBuf == NULL) || (ipcLimit == NULL)) { + return -EINVAL; + } + + (void)LosBufPrintf(seqBuf, "%u\n", ipcLimit->shmSizeLimit); + return 0; +} + +static ssize_t IPCLimitWriteShmLimit(struct ProcFile *pf, const CHAR *buf, size_t count, loff_t *ppos) +{ + (void)ppos; + long long int value = GetPidLimitValue(pf, buf, count); + if ((value < 0) || (value > (long long int)OS_NULL_INT)) { + return value; + } + + ProcIPCLimit *ipcLimit = (ProcIPCLimit *)pf->pPDE->data; + unsigned ret = OsIPCLimitSetShmLimit(ipcLimit, (unsigned long long)value); + if (ret != LOS_OK) { + return -ret; + } + return count; +} + +static ssize_t IPCLimitShowStat(struct SeqBuf *seqBuf, VOID *data) +{ + ProcLimiterSet *plimits = (ProcLimiterSet *)data; + if ((seqBuf == NULL) || (plimits == NULL)) { + return -EINVAL; + } + + unsigned int size = sizeof(ProcIPCLimit); + ProcIPCLimit *newIPCLimit = (ProcIPCLimit *)LOS_MemAlloc(m_aucSysMem1, size); + if (newIPCLimit == NULL) { + return -ENOMEM; + } + (void)memset_s(newIPCLimit, size, 0, size); + + unsigned int ret = OsPLimitsIPCStatGet(plimits, newIPCLimit, size); + if (ret != LOS_OK) { + (VOID)LOS_MemFree(m_aucSysMem1, newIPCLimit); + return -ret; + } + + (void)LosBufPrintf(seqBuf, "mq count: %u\n", newIPCLimit->mqCount); + (void)LosBufPrintf(seqBuf, "mq failed count: %u\n", newIPCLimit->mqFailedCount); + (void)LosBufPrintf(seqBuf, "shm size: %u\n", newIPCLimit->shmSize); + (void)LosBufPrintf(seqBuf, "shm failed count: %u\n", newIPCLimit->shmFailedCount); + (void)LOS_MemFree(m_aucSysMem1, newIPCLimit); + return 0; +} +#endif + +#ifdef LOSCFG_KERNEL_DEV_PLIMIT +static ssize_t DevLimitWriteAllow(struct ProcFile *pf, const CHAR *buf, size_t count, loff_t *ppos) +{ + (void)ppos; + char *kbuf = NULL; + + if ((pf == NULL) || (pf->pPDE == NULL) || (buf == NULL) || (count <= 0)) { + return -EINVAL; + } + + unsigned ret = MemUserCopy(buf, count, &kbuf); + if (ret != 0) { + return -ret; + } else if ((ret == 0) && (kbuf != NULL)) { + buf = (const char *)kbuf; + } + + ProcLimiterSet *plimit = (ProcLimiterSet *)pf->pPDE->data; + ret = OsDevLimitWriteAllow(plimit, buf, count); + (VOID)LOS_MemFree(m_aucSysMem1, kbuf); + if (ret != LOS_OK) { + return -ret; + } + return count; +} + +static ssize_t DevLimitWriteDeny(struct ProcFile *pf, const CHAR *buf, size_t count, loff_t *ppos) +{ + (void)ppos; + char *kbuf = NULL; + + if ((pf == NULL) || (pf->pPDE == NULL) || (buf == NULL) || (count <= 0)) { + return -EINVAL; + } + + unsigned ret = MemUserCopy(buf, count, &kbuf); + if (ret != 0) { + return -ret; + } else if ((ret == 0) && (kbuf != NULL)) { + buf = (const char *)kbuf; + } + + ProcLimiterSet *plimit = (ProcLimiterSet *)pf->pPDE->data; + ret = OsDevLimitWriteDeny(plimit, buf, count); + (VOID)LOS_MemFree(m_aucSysMem1, kbuf); + if (ret != LOS_OK) { + return -ret; + } + return count; +} + +static ssize_t DevLimitShow(struct SeqBuf *seqBuf, VOID *data) +{ + ProcDevLimit *devLimit = (ProcDevLimit *)data; + if ((seqBuf == NULL) || (devLimit == NULL)) { + return -EINVAL; + } + + unsigned ret = OsDevLimitShow(devLimit, seqBuf); + if (ret != LOS_OK) { + return -ret; + } + return 0; +} +#endif + +#ifdef LOSCFG_KERNEL_SCHED_PLIMIT +static ssize_t SchedLimitReadPeriod(struct SeqBuf *seqBuf, VOID *data) +{ + ProcSchedLimiter *schedLimit = (ProcSchedLimiter *)data; + if ((seqBuf == NULL) || (schedLimit == NULL)) { + return -EINVAL; + } + + (void)LosBufPrintf(seqBuf, "%lld\n", schedLimit->period); + return 0; +} + +static ssize_t SchedLimitWritePeriod(struct ProcFile *pf, const CHAR *buf, size_t count, loff_t *ppos) +{ + (void)ppos; + long long int value = GetPidLimitValue(pf, buf, count); + if (value < 0) { + return value; + } + + ProcSchedLimiter *schedLimit = (ProcSchedLimiter *)pf->pPDE->data; + unsigned ret = OsSchedLimitSetPeriod(schedLimit, (unsigned long long)value); + if (ret != LOS_OK) { + return -ret; + } + return count; +} + +static ssize_t SchedLimitReadQuota(struct SeqBuf *seqBuf, VOID *data) +{ + ProcSchedLimiter *schedLimit = (ProcSchedLimiter *)data; + if ((seqBuf == NULL) || (schedLimit == NULL)) { + return -EINVAL; + } + + (void)LosBufPrintf(seqBuf, "%lld\n", schedLimit->quota); + return 0; +} + +static ssize_t SchedLimitWriteQuota(struct ProcFile *pf, const CHAR *buf, size_t count, loff_t *ppos) +{ + (void)ppos; + long long int value = GetPidLimitValue(pf, buf, count); + if (value < 0) { + return value; + } + + ProcSchedLimiter *schedLimit = (ProcSchedLimiter *)pf->pPDE->data; + unsigned ret = OsSchedLimitSetQuota(schedLimit, (unsigned long long)value); + if (ret != LOS_OK) { + return -ret; + } + return count; +} + +#define TIME_CYCLE_TO_US(time) ((((UINT64)time) * OS_NS_PER_CYCLE) / OS_SYS_NS_PER_US) +#define SCHED_DEFAULT_VALUE (0x101010101010101) + +static ssize_t SchedLimitShow(struct SeqBuf *seqBuf, VOID *data) +{ + ProcLimiterSet *plimits = (ProcLimiterSet *)data; + if ((seqBuf == NULL) || (plimits == NULL)) { + return -EINVAL; + } + + UINT32 pidMax = LOS_GetSystemProcessMaximum(); + UINT32 size = pidMax * sizeof(unsigned long long); + unsigned long long *usage = (unsigned long long *)LOS_MemAlloc(m_aucSysMem1, size); + if (usage == NULL) { + return -ENOMEM; + } + (void)memset_s(usage, size, 1, size); + + unsigned int ret = OsPLimitsSchedUsageGet(plimits, usage, size); + if (ret != LOS_OK) { + (VOID)LOS_MemFree(m_aucSysMem1, usage); + return -ret; + } + + for (unsigned int index = 0; index < pidMax; index++) { + if (usage[index] == SCHED_DEFAULT_VALUE) { + continue; + } + (void)LosBufPrintf(seqBuf, "PID: %u runTime: %llu us\n", index, TIME_CYCLE_TO_US(usage[index])); + } + (void)LOS_MemFree(m_aucSysMem1, usage); + return 0; +} +#endif + +#define PROC_PLIMITS_MODE (S_IFDIR | S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) +void ProcLimitsInit(void) +{ + struct ProcDirEntry *parentPDE = CreateProcEntry("plimits", PROC_PLIMITS_MODE, NULL); + if (parentPDE == NULL) { + return; + } + ProcLimiterSet *plimits = OsRootPLimitsGet(); + parentPDE->procDirOps = &g_procDirOperations; + parentPDE->data = (VOID *)plimits; + parentPDE->dataType = PROC_DATA_STATIC; + plimits->mask = BIT(PROCESS_LIMITER_ID_PIDS) | BIT(PROCESS_LIMITER_COUNT); +#ifdef LOSCFG_KERNEL_MEM_PLIMIT + plimits->mask |= BIT(PROCESS_LIMITER_ID_MEM); +#endif +#ifdef LOSCFG_KERNEL_IPC_PLIMIT + plimits->mask |= BIT(PROCESS_LIMITER_ID_IPC); +#endif +#ifdef LOSCFG_KERNEL_DEV_PLIMIT + plimits->mask |= BIT(PROCESS_LIMITER_ID_DEV); +#endif +#ifdef LOSCFG_KERNEL_SCHED_PLIMIT + plimits->mask |= BIT(PROCESS_LIMITER_ID_SCHED); +#endif + ProcLimiterDirEntryInit(parentPDE, plimits->mask, PLIMIT_FILE_MODE_MASK_WRITE); + return; +} +#endif diff --git a/src/kernel_liteos_a/fs/proc/os_adapt/power_proc.c b/src/kernel_liteos_a/fs/proc/os_adapt/power_proc.c new file mode 100644 index 00000000..3d61eb9a --- /dev/null +++ b/src/kernel_liteos_a/fs/proc/os_adapt/power_proc.c @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "proc_fs.h" +#include "internal.h" +#ifdef LOSCFG_KERNEL_PM +#include "los_pm.h" + +static int PowerLockWrite(struct ProcFile *pf, const char *buf, size_t count, loff_t *ppos) +{ + (void)pf; + (void)count; + (void)ppos; + return -LOS_PmLockRequest(buf); +} + +static int PowerLockRead(struct SeqBuf *m, void *v) +{ + (void)v; + + LOS_PmLockInfoShow(m); + return 0; +} + +static const struct ProcFileOperations PowerLock = { + .write = PowerLockWrite, + .read = PowerLockRead, +}; + +static int PowerUnlockWrite(struct ProcFile *pf, const char *buf, size_t count, loff_t *ppos) +{ + (void)pf; + (void)count; + (void)ppos; + return -LOS_PmLockRelease(buf); +} + +static const struct ProcFileOperations PowerUnlock = { + .write = PowerUnlockWrite, + .read = PowerLockRead, +}; + +static int PowerModeWrite(struct ProcFile *pf, const char *buf, size_t count, loff_t *ppos) +{ + (void)pf; + (void)count; + (void)ppos; + + LOS_SysSleepEnum mode; + + if (buf == NULL) { + return 0; + } + + if (strcmp(buf, "normal") == 0) { + mode = LOS_SYS_NORMAL_SLEEP; + } else if (strcmp(buf, "light") == 0) { + mode = LOS_SYS_LIGHT_SLEEP; + } else if (strcmp(buf, "deep") == 0) { + mode = LOS_SYS_DEEP_SLEEP; + } else if (strcmp(buf, "shutdown") == 0) { + mode = LOS_SYS_SHUTDOWN; + } else { + PRINT_ERR("Unsupported hibernation mode: %s\n", buf); + return -EINVAL; + } + + return -LOS_PmModeSet(mode); +} + +static int PowerModeRead(struct SeqBuf *m, void *v) +{ + (void)v; + + LosBufPrintf(m, "normal light deep shutdown\n"); + return 0; +} + +static const struct ProcFileOperations PowerMode = { + .write = PowerModeWrite, + .read = PowerModeRead, +}; + +static int PowerCountRead(struct SeqBuf *m, void *v) +{ + (void)v; + UINT32 count = LOS_PmReadLock(); + + LosBufPrintf(m, "%u\n", count); + return 0; +} + +static int PowerCountWrite(struct ProcFile *pf, const char *buf, size_t count, loff_t *ppos) +{ + (void)pf; + (void)count; + (void)ppos; + + int weakCount; + + if (buf == NULL) { + return 0; + } + + weakCount = atoi(buf); + return -LOS_PmSuspend(weakCount); +} + +static const struct ProcFileOperations PowerCount = { + .write = PowerCountWrite, + .read = PowerCountRead, +}; + +#define POWER_FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH) +#define OS_POWER_PRIVILEGE 7 + +void ProcPmInit(void) +{ + struct ProcDirEntry *power = CreateProcEntry("power", S_IFDIR | S_IRWXU | S_IRWXG | S_IROTH, NULL); + if (power == NULL) { + PRINT_ERR("create /proc/power error!\n"); + return; + } + power->uid = OS_POWER_PRIVILEGE; + power->gid = OS_POWER_PRIVILEGE; + + struct ProcDirEntry *mode = CreateProcEntry("power/power_mode", POWER_FILE_MODE, NULL); + if (mode == NULL) { + PRINT_ERR("create /proc/power/power_mode error!\n"); + goto FREE_POWER; + } + mode->procFileOps = &PowerMode; + mode->uid = OS_POWER_PRIVILEGE; + mode->gid = OS_POWER_PRIVILEGE; + + struct ProcDirEntry *lock = CreateProcEntry("power/power_lock", POWER_FILE_MODE, NULL); + if (lock == NULL) { + PRINT_ERR("create /proc/power/power_lock error!\n"); + goto FREE_MODE; + } + lock->procFileOps = &PowerLock; + lock->uid = OS_POWER_PRIVILEGE; + lock->gid = OS_POWER_PRIVILEGE; + + struct ProcDirEntry *unlock = CreateProcEntry("power/power_unlock", POWER_FILE_MODE, NULL); + if (unlock == NULL) { + PRINT_ERR("create /proc/power/power_unlock error!\n"); + goto FREE_LOCK; + } + unlock->procFileOps = &PowerUnlock; + unlock->uid = OS_POWER_PRIVILEGE; + unlock->gid = OS_POWER_PRIVILEGE; + + struct ProcDirEntry *count = CreateProcEntry("power/power_count", S_IRUSR | S_IRGRP | S_IROTH, NULL); + if (count == NULL) { + PRINT_ERR("create /proc/power/power_count error!\n"); + goto FREE_UNLOCK; + } + count->procFileOps = &PowerCount; + count->uid = OS_POWER_PRIVILEGE; + count->gid = OS_POWER_PRIVILEGE; + + return; + +FREE_UNLOCK: + ProcFreeEntry(unlock); +FREE_LOCK: + ProcFreeEntry(lock); +FREE_MODE: + ProcFreeEntry(mode); +FREE_POWER: + ProcFreeEntry(power); + return; +} +#endif diff --git a/src/kernel_liteos_a/fs/proc/os_adapt/proc_init.c b/src/kernel_liteos_a/fs/proc/os_adapt/proc_init.c new file mode 100644 index 00000000..85913e1d --- /dev/null +++ b/src/kernel_liteos_a/fs/proc/os_adapt/proc_init.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "proc_fs.h" +#include "internal.h" +#include "stdio.h" +#include "sys/mount.h" +#include "sys/stat.h" +#include "los_init.h" + +#ifdef LOSCFG_FS_PROC + +#define PROCFS_MOUNT_POINT "/proc" +#define PROCFS_MOUNT_POINT_SIZE (sizeof(PROCFS_MOUNT_POINT) - 1) + +void ProcFsInit(void) +{ + int ret; + + ret = mkdir(PROCFS_MOUNT_POINT, PROCFS_DEFAULT_MODE); + if (ret < 0) { + PRINT_ERR("failed to mkdir %s, errno = %d\n", PROCFS_MOUNT_POINT, get_errno()); + return; + } + + ret = mount(NULL, PROCFS_MOUNT_POINT, "procfs", 0, NULL); + if (ret) { + PRINT_ERR("mount procfs err %d\n", ret); + return; + } + + ProcMountsInit(); +#if defined(LOSCFG_SHELL_CMD_DEBUG) && defined(LOSCFG_KERNEL_VM) + ProcVmmInit(); +#endif + ProcProcessInit(); + ProcUptimeInit(); + ProcFsCacheInit(); + ProcFdInit(); +#ifdef LOSCFG_KERNEL_PM + ProcPmInit(); +#endif +#ifdef LOSCFG_PROC_PROCESS_DIR + ProcSysMemInfoInit(); + ProcFileSysInit(); +#endif +#ifdef LOSCFG_KERNEL_PLIMITS + ProcLimitsInit(); +#endif +#ifdef LOSCFG_KERNEL_CONTAINER + ProcSysUserInit(); +#endif +} + +LOS_MODULE_INIT(ProcFsInit, LOS_INIT_LEVEL_KMOD_EXTENDED); + +#endif diff --git a/src/kernel_liteos_a/fs/proc/os_adapt/proc_vfs.c b/src/kernel_liteos_a/fs/proc/os_adapt/proc_vfs.c new file mode 100644 index 00000000..b479bd63 --- /dev/null +++ b/src/kernel_liteos_a/fs/proc/os_adapt/proc_vfs.c @@ -0,0 +1,474 @@ +/* + * Copyright (c) 2021-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "proc_file.h" + +#include +#include +#include +#include + +#include "fs/dirent_fs.h" +#include "fs/mount.h" +#include "fs/fs.h" +#include "los_tables.h" +#include "internal.h" + +#ifdef LOSCFG_FS_PROC +static struct VnodeOps g_procfsVops; +static struct file_operations_vfs g_procfsFops; + +struct ProcDirEntry *VnodeToEntry(struct Vnode *node) +{ + return (struct ProcDirEntry *)(node->data); +} + +static struct Vnode *EntryToVnode(struct ProcDirEntry *entry) +{ + struct Vnode *node = NULL; + + (void)VnodeAlloc(&g_procfsVops, &node); + node->fop = &g_procfsFops; + node->data = entry; + node->type = entry->type; + node->uid = entry->uid; + node->gid = entry->gid; + node->mode = entry->mode; + return node; +} + +static int EntryMatch(const char *name, int len, const struct ProcDirEntry *pn) +{ + if (len != pn->nameLen) { + return 0; + } + return !strncmp(name, pn->name, len); +} + +int VfsProcfsTruncate(struct Vnode *pVnode, off_t len) +{ + return 0; +} + +int VfsProcfsCreate(struct Vnode* parent, const char *name, int mode, struct Vnode **vnode) +{ + int ret; + struct Vnode *vp = NULL; + struct ProcDirEntry *curEntry = NULL; + + struct ProcDirEntry *parentEntry = VnodeToEntry(parent); + if (parentEntry == NULL) { + return -ENODATA; + } + + ret = VnodeAlloc(&g_procfsVops, &vp); + if (ret != 0) { + return -ENOMEM; + } + + curEntry = ProcCreate(name, mode, parentEntry, NULL); + if (curEntry == NULL) { + VnodeFree(vp); + return -ENODATA; + } + + vp->data = curEntry; + vp->type = curEntry->type; + if (vp->type == VNODE_TYPE_DIR) { + vp->mode = S_IFDIR | PROCFS_DEFAULT_MODE; + } else { + vp->mode = S_IFREG | PROCFS_DEFAULT_MODE; + } + + vp->vop = parent->vop; + vp->fop = parent->fop; + vp->parent = parent; + vp->originMount = parent->originMount; + + *vnode = vp; + + return LOS_OK; +} + +int VfsProcfsRead(struct file *filep, char *buffer, size_t buflen) +{ + ssize_t size; + struct ProcDirEntry *entry = NULL; + if ((filep == NULL) || (filep->f_vnode == NULL) || (buffer == NULL)) { + return -EINVAL; + } + + VnodeHold(); + entry = VnodeToEntry(filep->f_vnode); + if (entry == NULL) { + VnodeDrop(); + return -EPERM; + } + + size = (ssize_t)ReadProcFile(entry, (void *)buffer, buflen); + filep->f_pos = entry->pf->fPos; + VnodeDrop(); + return size; +} + +int VfsProcfsWrite(struct file *filep, const char *buffer, size_t buflen) +{ + ssize_t size; + struct ProcDirEntry *entry = NULL; + if ((filep == NULL) || (filep->f_vnode == NULL) || (buffer == NULL)) { + return -EINVAL; + } + + VnodeHold(); + entry = VnodeToEntry(filep->f_vnode); + if (entry == NULL) { + VnodeDrop(); + return -EPERM; + } + + size = (ssize_t)WriteProcFile(entry, (void *)buffer, buflen); + filep->f_pos = entry->pf->fPos; + VnodeDrop(); + return size; +} + +int VfsProcfsLookup(struct Vnode *parent, const char *name, int len, struct Vnode **vpp) +{ + if (parent == NULL || name == NULL || len <= 0 || vpp == NULL) { + return -EINVAL; + } + struct ProcDirEntry *entry = VnodeToEntry(parent); + if (entry == NULL) { + return -ENODATA; + } + + entry = entry->subdir; + while (1) { + if (entry == NULL) { + return -ENOENT; + } + if (EntryMatch(name, len, entry)) { + break; + } + entry = entry->next; + } + + *vpp = EntryToVnode(entry); + if ((*vpp) == NULL) { + return -ENOMEM; + } + (*vpp)->originMount = parent->originMount; + (*vpp)->parent = parent; + return LOS_OK; +} + +int VfsProcfsMount(struct Mount *mnt, struct Vnode *device, const void *data) +{ + struct Vnode *vp = NULL; + int ret; + + spin_lock_init(&procfsLock); + procfsInit = true; + + ret = VnodeAlloc(&g_procfsVops, &vp); + if (ret != 0) { + return -ENOMEM; + } + + struct ProcDirEntry *root = GetProcRootEntry(); + vp->data = root; + vp->originMount = mnt; + vp->fop = &g_procfsFops; + mnt->data = NULL; + mnt->vnodeCovered = vp; + vp->type = root->type; + if (vp->type == VNODE_TYPE_DIR) { + vp->mode = S_IFDIR | PROCFS_DEFAULT_MODE; + } else { + vp->mode = S_IFREG | PROCFS_DEFAULT_MODE; + } + + return LOS_OK; +} + +int VfsProcfsUnmount(void *handle, struct Vnode **blkdriver) +{ + (void)handle; + (void)blkdriver; + return -EPERM; +} + +int VfsProcfsStat(struct Vnode *node, struct stat *buf) +{ + VnodeHold(); + struct ProcDirEntry *entry = VnodeToEntry(node); + if (entry == NULL) { + VnodeDrop(); + return -EPERM; + } + (void)memset_s(buf, sizeof(struct stat), 0, sizeof(struct stat)); + buf->st_mode = entry->mode; + VnodeDrop(); + return LOS_OK; +} + +#ifdef LOSCFG_KERNEL_PLIMITS +int VfsProcfsMkdir(struct Vnode *parent, const char *dirName, mode_t mode, struct Vnode **vnode) +{ + struct ProcDirEntry *parentEntry = VnodeToEntry(parent); + struct ProcDirEntry *pde = NULL; + if ((parentEntry->procDirOps == NULL) || (parentEntry->procDirOps->mkdir == NULL)) { + return -ENOSYS; + } + + int ret = parentEntry->procDirOps->mkdir(parentEntry, dirName, mode, &pde); + if ((ret < 0) || (pde == NULL)) { + return ret; + } + + *vnode = EntryToVnode(pde); + (*vnode)->vop = parent->vop; + (*vnode)->parent = parent; + (*vnode)->originMount = parent->originMount; + if ((*vnode)->type == VNODE_TYPE_DIR) { + (*vnode)->mode = S_IFDIR | PROCFS_DEFAULT_MODE; + } else { + (*vnode)->mode = S_IFREG | PROCFS_DEFAULT_MODE; + } + return ret; +} + +int VfsProcfsRmdir(struct Vnode *parent, struct Vnode *vnode, const char *dirName) +{ + if (parent == NULL) { + return -EINVAL; + } + + struct ProcDirEntry *parentEntry = VnodeToEntry(parent); + if ((parentEntry->procDirOps == NULL) || (parentEntry->procDirOps->rmdir == NULL)) { + return -ENOSYS; + } + + struct ProcDirEntry *dirEntry = VnodeToEntry(vnode); + int ret = parentEntry->procDirOps->rmdir(parentEntry, dirEntry, dirName); + if (ret < 0) { + return ret; + } + vnode->data = NULL; + return 0; +} +#endif + +int VfsProcfsReaddir(struct Vnode *node, struct fs_dirent_s *dir) +{ + int result; + char *buffer = NULL; + unsigned int minSize, dstNameSize; + struct ProcDirEntry *pde = NULL; + int i = 0; + + if (dir == NULL) { + return -EINVAL; + } + if (node->type != VNODE_TYPE_DIR) { + return -ENOTDIR; + } + VnodeHold(); + pde = VnodeToEntry(node); + if (pde == NULL) { + VnodeDrop(); + return -EPERM; + } + + while (i < dir->read_cnt) { + buffer = (char *)zalloc(sizeof(char) * NAME_MAX); + if (buffer == NULL) { + VnodeDrop(); + PRINT_ERR("malloc failed\n"); + return -ENOMEM; + } + + result = ReadProcFile(pde, (void *)buffer, NAME_MAX); + if (result != ENOERR) { + free(buffer); + break; + } + dstNameSize = sizeof(dir->fd_dir[i].d_name); + minSize = (dstNameSize < NAME_MAX) ? dstNameSize : NAME_MAX; + result = strncpy_s(dir->fd_dir[i].d_name, dstNameSize, buffer, minSize); + if (result != EOK) { + VnodeDrop(); + free(buffer); + return -ENAMETOOLONG; + } + dir->fd_dir[i].d_name[dstNameSize - 1] = '\0'; + dir->fd_position++; + dir->fd_dir[i].d_off = dir->fd_position; + dir->fd_dir[i].d_reclen = (uint16_t)sizeof(struct dirent); + + i++; + free(buffer); + } + VnodeDrop(); + return i; +} + +int VfsProcfsOpendir(struct Vnode *node, struct fs_dirent_s *dir) +{ + VnodeHold(); + struct ProcDirEntry *pde = VnodeToEntry(node); + if (pde == NULL) { + VnodeDrop(); + return -EINVAL; + } + + pde->pdirCurrent = pde->subdir; + if (pde->pf == NULL) { + VnodeDrop(); + return -EINVAL; + } + pde->pf->fPos = 0; + VnodeDrop(); + return LOS_OK; +} + +int VfsProcfsOpen(struct file *filep) +{ + if (filep == NULL) { + return -EINVAL; + } + VnodeHold(); + struct Vnode *node = filep->f_vnode; + struct ProcDirEntry *pde = VnodeToEntry(node); + if (pde == NULL) { + VnodeDrop(); + return -EPERM; + } + + if (ProcOpen(pde->pf) != OK) { + return -ENOMEM; + } + if (S_ISREG(pde->mode) && (pde->procFileOps != NULL) && (pde->procFileOps->open != NULL)) { + (void)pde->procFileOps->open((struct Vnode *)pde, pde->pf); + } + if (S_ISDIR(pde->mode)) { + pde->pdirCurrent = pde->subdir; + pde->pf->fPos = 0; + } + filep->f_priv = (void *)pde; + VnodeDrop(); + return LOS_OK; +} + +int VfsProcfsClose(struct file *filep) +{ + int result = 0; + if (filep == NULL) { + return -EINVAL; + } + + VnodeHold(); + struct Vnode *node = filep->f_vnode; + struct ProcDirEntry *pde = VnodeToEntry(node); + if ((pde == NULL) || (pde->pf == NULL)) { + VnodeDrop(); + return -EPERM; + } + + pde->pf->fPos = 0; + if ((pde->procFileOps != NULL) && (pde->procFileOps->release != NULL)) { + result = pde->procFileOps->release((struct Vnode *)pde, pde->pf); + } + LosBufRelease(pde->pf->sbuf); + pde->pf->sbuf = NULL; + VnodeDrop(); + return result; +} + +int VfsProcfsStatfs(struct Mount *mnt, struct statfs *buf) +{ + (void)memset_s(buf, sizeof(struct statfs), 0, sizeof(struct statfs)); + buf->f_type = PROCFS_MAGIC; + + return LOS_OK; +} + +int VfsProcfsClosedir(struct Vnode *vp, struct fs_dirent_s *dir) +{ + return LOS_OK; +} + +ssize_t VfsProcfsReadlink(struct Vnode *vnode, char *buffer, size_t bufLen) +{ + int result = -EINVAL; + if (vnode == NULL) { + return result; + } + + struct ProcDirEntry *pde = VnodeToEntry(vnode); + if (pde == NULL) { + return -EPERM; + } + + if ((pde->procFileOps != NULL) && (pde->procFileOps->readLink != NULL)) { + result = pde->procFileOps->readLink(pde, buffer, bufLen); + } + return result; +} + +const struct MountOps procfs_operations = { + .Mount = VfsProcfsMount, + .Unmount = NULL, + .Statfs = VfsProcfsStatfs, +}; + +static struct VnodeOps g_procfsVops = { + .Lookup = VfsProcfsLookup, + .Getattr = VfsProcfsStat, + .Readdir = VfsProcfsReaddir, + .Opendir = VfsProcfsOpendir, + .Closedir = VfsProcfsClosedir, + .Truncate = VfsProcfsTruncate, + .Readlink = VfsProcfsReadlink, +#ifdef LOSCFG_KERNEL_PLIMITS + .Mkdir = VfsProcfsMkdir, + .Rmdir = VfsProcfsRmdir, +#endif +}; + +static struct file_operations_vfs g_procfsFops = { + .read = VfsProcfsRead, + .write = VfsProcfsWrite, + .open = VfsProcfsOpen, + .close = VfsProcfsClose +}; + +FSMAP_ENTRY(procfs_fsmap, "procfs", procfs_operations, FALSE, FALSE); +#endif diff --git a/src/kernel_liteos_a/fs/proc/os_adapt/process_proc.c b/src/kernel_liteos_a/fs/proc/os_adapt/process_proc.c new file mode 100644 index 00000000..f9a9d53a --- /dev/null +++ b/src/kernel_liteos_a/fs/proc/os_adapt/process_proc.c @@ -0,0 +1,728 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "proc_fs.h" +#include "internal.h" +#include "los_process_pri.h" +#include "user_copy.h" +#include "los_memory.h" + +#ifdef LOSCFG_PROC_PROCESS_DIR +#include "los_vm_dump.h" + +typedef enum { + PROC_PID, + PROC_PID_MEM, +#ifdef LOSCFG_KERNEL_CPUP + PROC_PID_CPUP, +#endif +#ifdef LOSCFG_USER_CONTAINER + PROC_UID_MAP, + PROC_GID_MAP, +#endif + PROC_P_TYPE_MAX, +} ProcessDataType; + +struct ProcProcess { + char *name; + mode_t mode; + int type; + const struct ProcFileOperations *fileOps; +}; + +struct ProcessData { + uintptr_t process; + unsigned int type; +}; + +static LosProcessCB *ProcGetProcessCB(struct ProcessData *data) +{ + if (data->process != 0) { + return (LosProcessCB *)data->process; + } + return OsCurrProcessGet(); +} + +#define PROC_PID_PRIVILEGE 7 +#define PROC_PID_DIR_LEN 100 +#ifdef LOSCFG_KERNEL_CONTAINER +static ssize_t ProcessContainerLink(unsigned int containerID, ContainerType type, char *buffer, size_t bufLen) +{ + ssize_t count = -1; + if ((type == PID_CONTAINER) || (type == PID_CHILD_CONTAINER)) { + count = snprintf_s(buffer, bufLen, bufLen - 1, "'pid:[%u]'", containerID); + } else if (type == UTS_CONTAINER) { + count = snprintf_s(buffer, bufLen, bufLen - 1, "'uts:[%u]'", containerID); + } else if (type == MNT_CONTAINER) { + count = snprintf_s(buffer, bufLen, bufLen - 1, "'mnt:[%u]'", containerID); + } else if (type == IPC_CONTAINER) { + count = snprintf_s(buffer, bufLen, bufLen - 1, "'ipc:[%u]'", containerID); + } else if ((type == TIME_CONTAINER) || (type == TIME_CHILD_CONTAINER)) { + count = snprintf_s(buffer, bufLen, bufLen - 1, "'time:[%u]'", containerID); + } else if (type == USER_CONTAINER) { + count = snprintf_s(buffer, bufLen, bufLen - 1, "'user:[%u]'", containerID); + } else if (type == NET_CONTAINER) { + count = snprintf_s(buffer, bufLen, bufLen - 1, "'net:[%u]'", containerID); + } + + if (count < 0) { + return -EBADF; + } + return count; +} + +static ssize_t ProcessContainerReadLink(struct ProcDirEntry *entry, char *buffer, size_t bufLen) +{ + char *freeBuf = NULL; + char *buf = buffer; + ssize_t count; + unsigned int intSave; + if (entry == NULL) { + return -EINVAL; + } + struct ProcessData *data = (struct ProcessData *)entry->data; + if (data == NULL) { + return -EINVAL; + } + + if (LOS_IsUserAddressRange((VADDR_T)(UINTPTR)buffer, bufLen)) { + buf = LOS_MemAlloc(m_aucSysMem1, bufLen); + if (buf == NULL) { + return -ENOMEM; + } + (void)memset_s(buf, bufLen, 0, bufLen); + freeBuf = buf; + } + + LosProcessCB *processCB = ProcGetProcessCB(data); + SCHEDULER_LOCK(intSave); + UINT32 containerID = OsGetContainerID(processCB, (ContainerType)data->type); + SCHEDULER_UNLOCK(intSave); + if (containerID != OS_INVALID_VALUE) { + count = ProcessContainerLink(containerID, (ContainerType)data->type, buf, bufLen); + } else { + count = strlen("(unknown)"); + if (memcpy_s(buf, bufLen, "(unknown)", count + 1) != EOK) { + (void)LOS_MemFree(m_aucSysMem1, freeBuf); + return -EBADF; + } + } + if (count < 0) { + (void)LOS_MemFree(m_aucSysMem1, freeBuf); + return count; + } + + if (LOS_IsUserAddressRange((VADDR_T)(UINTPTR)buffer, bufLen)) { + if (LOS_ArchCopyToUser(buffer, buf, bufLen) != 0) { + (void)LOS_MemFree(m_aucSysMem1, freeBuf); + return -EFAULT; + } + } + (void)LOS_MemFree(m_aucSysMem1, freeBuf); + return count; +} + +static const struct ProcFileOperations PID_CONTAINER_FOPS = { + .readLink = ProcessContainerReadLink, +}; + +void *ProcfsContainerGet(int fd, unsigned int *containerType) +{ + if ((fd <= 0) || (containerType == NULL)) { + return NULL; + } + + VnodeHold(); + struct Vnode *vnode = VnodeFind(fd); + if (vnode == NULL) { + VnodeDrop(); + return NULL; + } + + struct ProcDirEntry *entry = VnodeToEntry(vnode); + if (entry == NULL) { + VnodeDrop(); + return NULL; + } + + struct ProcessData *data = (struct ProcessData *)entry->data; + if (data == NULL) { + VnodeDrop(); + return NULL; + } + + void *processCB = (void *)ProcGetProcessCB(data); + *containerType = data->type; + VnodeDrop(); + return processCB; +} + +#endif /* LOSCFG_KERNEL_CONTAINER */ + +static int ProcessMemInfoRead(struct SeqBuf *seqBuf, LosProcessCB *pcb) +{ + unsigned int intSave; + unsigned int size = sizeof(LosVmSpace) + sizeof(LosVmMapRegion); + LosVmSpace *vmSpace = (LosVmSpace *)LOS_MemAlloc(m_aucSysMem1, size); + if (vmSpace == NULL) { + return -ENOMEM; + } + (void)memset_s(vmSpace, size, 0, size); + LosVmMapRegion *heap = (LosVmMapRegion *)((char *)vmSpace + sizeof(LosVmSpace)); + + SCHEDULER_LOCK(intSave); + if (OsProcessIsInactive(pcb)) { + SCHEDULER_UNLOCK(intSave); + (void)LOS_MemFree(m_aucSysMem1, vmSpace); + return -EINVAL; + } + (void)memcpy_s(vmSpace, sizeof(LosVmSpace), pcb->vmSpace, sizeof(LosVmSpace)); + (void)memcpy_s(heap, sizeof(LosVmMapRegion), pcb->vmSpace->heap, sizeof(LosVmMapRegion)); + SCHEDULER_UNLOCK(intSave); + + (void)LosBufPrintf(seqBuf, "\nVMSpaceSize: %u byte\n", vmSpace->size); + (void)LosBufPrintf(seqBuf, "VMSpaceMapSize: %u byte\n", vmSpace->mapSize); + (void)LosBufPrintf(seqBuf, "VM TLB Asid: %u\n", vmSpace->archMmu.asid); + (void)LosBufPrintf(seqBuf, "VMHeapSize: %u byte\n", heap->range.size); + (void)LosBufPrintf(seqBuf, "VMHeapRegionName: %s\n", OsGetRegionNameOrFilePath(heap)); + (void)LosBufPrintf(seqBuf, "VMHeapRegionType: 0x%x\n", heap->regionType); + (void)LOS_MemFree(m_aucSysMem1, vmSpace); + return 0; +} + +#ifdef LOSCFG_KERNEL_CPUP +#define TIME_CYCLE_TO_US(time) ((((UINT64)time) * OS_NS_PER_CYCLE) / OS_SYS_NS_PER_US) +static int ProcessCpupRead(struct SeqBuf *seqBuf, LosProcessCB *pcb) +{ + unsigned int intSave; + OsCpupBase *processCpup = (OsCpupBase *)LOS_MemAlloc(m_aucSysMem1, sizeof(OsCpupBase)); + if (processCpup == NULL) { + return -ENOMEM; + } + (void)memset_s(processCpup, sizeof(OsCpupBase), 0, sizeof(OsCpupBase)); + + SCHEDULER_LOCK(intSave); + if (OsProcessIsInactive(pcb)) { + SCHEDULER_UNLOCK(intSave); + (VOID)LOS_MemFree(m_aucSysMem1, processCpup); + return -EINVAL; + } + (void)memcpy_s(processCpup, sizeof(OsCpupBase), pcb->processCpup, sizeof(OsCpupBase)); + SCHEDULER_UNLOCK(intSave); + + (void)LosBufPrintf(seqBuf, "\nTotalRunningTime: %lu us\n", TIME_CYCLE_TO_US(processCpup->allTime)); + (void)LosBufPrintf(seqBuf, "HistoricalRunningTime:(us) "); + for (UINT32 i = 0; i < OS_CPUP_HISTORY_RECORD_NUM + 1; i++) { + (void)LosBufPrintf(seqBuf, "%lu ", TIME_CYCLE_TO_US(processCpup->historyTime[i])); + } + (void)LosBufPrintf(seqBuf, "\n"); + (void)LOS_MemFree(m_aucSysMem1, processCpup); + return 0; +} +#endif + +#ifdef LOSCFG_TIME_CONTAINER +static const CHAR *g_monotonic = "monotonic"; +#define DECIMAL_BASE 10 + +static int ProcTimeContainerRead(struct SeqBuf *m, void *v) +{ + int ret; + unsigned int intSave; + struct timespec64 offsets = {0}; + + if ((m == NULL) || (v == NULL)) { + return -EINVAL; + } + + struct ProcessData *data = (struct ProcessData *)v; + SCHEDULER_LOCK(intSave); + LosProcessCB *processCB = ProcGetProcessCB(data); + ret = OsGetTimeContainerMonotonic(processCB, &offsets); + SCHEDULER_UNLOCK(intSave); + if (ret != LOS_OK) { + return -ret; + } + + LosBufPrintf(m, "monotonic %lld %ld\n", offsets.tv_sec, offsets.tv_nsec); + return 0; +} + +static int ProcSetTimensOffset(const char *buf, LosProcessCB *processCB) +{ + unsigned int intSave; + struct timespec64 offsets; + char *endptr = NULL; + + offsets.tv_sec = strtoll(buf, &endptr, DECIMAL_BASE); + offsets.tv_nsec = strtoll(endptr, NULL, DECIMAL_BASE); + if (offsets.tv_nsec >= OS_SYS_NS_PER_SECOND) { + return -EACCES; + } + + SCHEDULER_LOCK(intSave); + unsigned int ret = OsSetTimeContainerMonotonic(processCB, &offsets); + SCHEDULER_UNLOCK(intSave); + if (ret != LOS_OK) { + return -ret; + } + return 0; +} + +static int ProcTimeContainerWrite(struct ProcFile *pf, const char *buf, size_t count, loff_t *ppos) +{ + (void)ppos; + char *kbuf = NULL; + int ret; + + if ((pf == NULL) || (count <= 0)) { + return -EINVAL; + } + + struct ProcDirEntry *entry = pf->pPDE; + if (entry == NULL) { + return -EINVAL; + } + + struct ProcessData *data = (struct ProcessData *)entry->data; + if (data == NULL) { + return -EINVAL; + } + + if (LOS_IsUserAddressRange((VADDR_T)(UINTPTR)buf, count)) { + kbuf = LOS_MemAlloc(m_aucSysMem1, count + 1); + if (kbuf == NULL) { + return -ENOMEM; + } + + if (LOS_ArchCopyFromUser(kbuf, buf, count) != 0) { + (VOID)LOS_MemFree(m_aucSysMem1, kbuf); + return -EFAULT; + } + kbuf[count] = '\0'; + buf = kbuf; + } + + ret = strncmp(buf, g_monotonic, strlen(g_monotonic)); + if (ret != 0) { + (VOID)LOS_MemFree(m_aucSysMem1, kbuf); + return -EINVAL; + } + + buf += strlen(g_monotonic); + ret = ProcSetTimensOffset(buf, ProcGetProcessCB(data)); + if (ret < 0) { + (VOID)LOS_MemFree(m_aucSysMem1, kbuf); + return ret; + } + (VOID)LOS_MemFree(m_aucSysMem1, kbuf); + return count; +} + +static const struct ProcFileOperations TIME_CONTAINER_FOPS = { + .read = ProcTimeContainerRead, + .write = ProcTimeContainerWrite, +}; +#endif + +#ifdef LOSCFG_USER_CONTAINER + +static void *MemdupUserNul(const void *src, size_t len) +{ + char *des = NULL; + if (len <= 0) { + return NULL; + } + des = LOS_MemAlloc(OS_SYS_MEM_ADDR, len + 1); + if (des == NULL) { + return NULL; + } + + if (LOS_ArchCopyFromUser(des, src, len) != 0) { + (VOID)LOS_MemFree(OS_SYS_MEM_ADDR, des); + return NULL; + } + + des[len] = '\0'; + return des; +} + +static LosProcessCB *ProcUidGidMapWriteCheck(struct ProcFile *pf, const char *buf, size_t size, + char **kbuf, ProcessDataType *type) +{ + if ((pf == NULL) || (size <= 0) || (size >= PAGE_SIZE)) { + return NULL; + } + + struct ProcDirEntry *entry = pf->pPDE; + if (entry == NULL) { + return NULL; + } + + struct ProcessData *data = (struct ProcessData *)entry->data; + if (data == NULL) { + return NULL; + } + + *kbuf = MemdupUserNul(buf, size); + if (*kbuf == NULL) { + return NULL; + } + *type = (ProcessDataType)data->type; + return ProcGetProcessCB(data); +} + +static ssize_t ProcIDMapWrite(struct ProcFile *file, const char *buf, size_t size, loff_t *ppos) +{ + (void)ppos; + char *kbuf = NULL; + int ret; + unsigned int intSave; + ProcessDataType type = PROC_P_TYPE_MAX; + LosProcessCB *processCB = ProcUidGidMapWriteCheck(file, buf, size, &kbuf, &type); + if (processCB == NULL) { + return -EINVAL; + } + + SCHEDULER_LOCK(intSave); + if ((processCB->credentials == NULL) || (processCB->credentials->userContainer == NULL)) { + SCHEDULER_UNLOCK(intSave); + (void)LOS_MemFree(m_aucSysMem1, kbuf); + return -EINVAL; + } + UserContainer *userContainer = processCB->credentials->userContainer; + if (userContainer->parent == NULL) { + SCHEDULER_UNLOCK(intSave); + (void)LOS_MemFree(m_aucSysMem1, kbuf); + return -EPERM; + } + if (type == PROC_UID_MAP) { + ret = OsUserContainerMapWrite(file, kbuf, size, CAP_SETUID, + &userContainer->uidMap, &userContainer->parent->uidMap); + } else { + ret = OsUserContainerMapWrite(file, kbuf, size, CAP_SETGID, + &userContainer->gidMap, &userContainer->parent->gidMap); + } + SCHEDULER_UNLOCK(intSave); + (void)LOS_MemFree(m_aucSysMem1, kbuf); + return ret; +} + +static int ProcIDMapRead(struct SeqBuf *seqBuf, void *v) +{ + unsigned int intSave; + if ((seqBuf == NULL) || (v == NULL)) { + return -EINVAL; + } + struct ProcessData *data = (struct ProcessData *)v; + LosProcessCB *processCB = ProcGetProcessCB(data); + + SCHEDULER_LOCK(intSave); + if ((processCB->credentials == NULL) || (processCB->credentials->userContainer == NULL)) { + SCHEDULER_UNLOCK(intSave); + return -EINVAL; + } + UserContainer *userContainer = processCB->credentials->userContainer; + if ((userContainer != NULL) && (userContainer->parent == NULL)) { + UidGidExtent uidGidExtent = userContainer->uidMap.extent[0]; + SCHEDULER_UNLOCK(intSave); + (void)LosBufPrintf(seqBuf, "%d %d %u\n", uidGidExtent.first, uidGidExtent.lowerFirst, + uidGidExtent.count); + return 0; + } + SCHEDULER_LOCK(intSave); + return 0; +} + +static const struct ProcFileOperations UID_GID_MAP_FOPS = { + .read = ProcIDMapRead, + .write = ProcIDMapWrite, +}; +#endif + +static int ProcProcessRead(struct SeqBuf *m, void *v) +{ + if ((m == NULL) || (v == NULL)) { + return -EINVAL; + } + struct ProcessData *data = (struct ProcessData *)v; + switch (data->type) { + case PROC_PID_MEM: + return ProcessMemInfoRead(m, ProcGetProcessCB(data)); +#ifdef LOSCFG_KERNEL_CPUP + case PROC_PID_CPUP: + return ProcessCpupRead(m, ProcGetProcessCB(data)); +#endif + default: + break; + } + return -EINVAL; +} + +static const struct ProcFileOperations PID_FOPS = { + .read = ProcProcessRead, +}; + +static struct ProcProcess g_procProcess[] = { + { + .name = NULL, + .mode = S_IFDIR | S_IRWXU | S_IRWXG | S_IROTH, + .type = PROC_PID, + .fileOps = &PID_FOPS + + }, + { + .name = "meminfo", + .mode = 0, + .type = PROC_PID_MEM, + .fileOps = &PID_FOPS + }, +#ifdef LOSCFG_KERNEL_CPUP + { + .name = "cpup", + .mode = 0, + .type = PROC_PID_CPUP, + .fileOps = &PID_FOPS + + }, +#endif +#ifdef LOSCFG_KERNEL_CONTAINER + { + .name = "container", + .mode = S_IFDIR | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH, + .type = CONTAINER, + .fileOps = &PID_CONTAINER_FOPS + + }, +#ifdef LOSCFG_PID_CONTAINER + { + .name = "container/pid", + .mode = S_IFLNK, + .type = PID_CONTAINER, + .fileOps = &PID_CONTAINER_FOPS + }, + { + .name = "container/pid_for_children", + .mode = S_IFLNK, + .type = PID_CHILD_CONTAINER, + .fileOps = &PID_CONTAINER_FOPS + }, +#endif +#ifdef LOSCFG_UTS_CONTAINER + { + .name = "container/uts", + .mode = S_IFLNK, + .type = UTS_CONTAINER, + .fileOps = &PID_CONTAINER_FOPS + }, +#endif +#ifdef LOSCFG_MNT_CONTAINER + { + .name = "container/mnt", + .mode = S_IFLNK, + .type = MNT_CONTAINER, + .fileOps = &PID_CONTAINER_FOPS + }, +#endif +#ifdef LOSCFG_IPC_CONTAINER + { + .name = "container/ipc", + .mode = S_IFLNK, + .type = IPC_CONTAINER, + .fileOps = &PID_CONTAINER_FOPS + }, +#endif +#ifdef LOSCFG_TIME_CONTAINER + { + .name = "container/time", + .mode = S_IFLNK, + .type = TIME_CONTAINER, + .fileOps = &PID_CONTAINER_FOPS + }, + { + .name = "container/time_for_children", + .mode = S_IFLNK, + .type = TIME_CHILD_CONTAINER, + .fileOps = &PID_CONTAINER_FOPS + }, + { + .name = "time_offsets", + .mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, + .type = TIME_CONTAINER, + .fileOps = &TIME_CONTAINER_FOPS + }, +#endif +#ifdef LOSCFG_IPC_CONTAINER + { + .name = "container/user", + .mode = S_IFLNK, + .type = USER_CONTAINER, + .fileOps = &PID_CONTAINER_FOPS + }, + { + .name = "uid_map", + .mode = 0, + .type = PROC_UID_MAP, + .fileOps = &UID_GID_MAP_FOPS + }, + { + .name = "gid_map", + .mode = 0, + .type = PROC_GID_MAP, + .fileOps = &UID_GID_MAP_FOPS + }, +#endif +#ifdef LOSCFG_IPC_CONTAINER + { + .name = "container/net", + .mode = S_IFLNK, + .type = NET_CONTAINER, + .fileOps = &PID_CONTAINER_FOPS + }, +#endif +#endif +}; + +void ProcFreeProcessDir(struct ProcDirEntry *processDir) +{ + if (processDir == NULL) { + return; + } + RemoveProcEntry(processDir->name, NULL); +} + +static struct ProcDirEntry *ProcCreatePorcess(UINT32 pid, struct ProcProcess *porcess, uintptr_t processCB) +{ + int ret; + struct ProcDataParm dataParm; + char pidName[PROC_PID_DIR_LEN] = {0}; + struct ProcessData *data = (struct ProcessData *)malloc(sizeof(struct ProcessData)); + if (data == NULL) { + return NULL; + } + if (pid != OS_INVALID_VALUE) { + if (porcess->name != NULL) { + ret = snprintf_s(pidName, PROC_PID_DIR_LEN, PROC_PID_DIR_LEN - 1, "%u/%s", pid, porcess->name); + } else { + ret = snprintf_s(pidName, PROC_PID_DIR_LEN, PROC_PID_DIR_LEN - 1, "%u", pid); + } + } else { + if (porcess->name != NULL) { + ret = snprintf_s(pidName, PROC_PID_DIR_LEN, PROC_PID_DIR_LEN - 1, "%s/%s", "self", porcess->name); + } else { + ret = snprintf_s(pidName, PROC_PID_DIR_LEN, PROC_PID_DIR_LEN - 1, "%s", "self"); + } + } + if (ret < 0) { + free(data); + return NULL; + } + + data->process = processCB; + data->type = porcess->type; + dataParm.data = data; + dataParm.dataType = PROC_DATA_FREE; + struct ProcDirEntry *container = ProcCreateData(pidName, porcess->mode, NULL, porcess->fileOps, &dataParm); + if (container == NULL) { + free(data); + PRINT_ERR("create /proc/%s error!\n", pidName); + return NULL; + } + return container; +} + +int ProcCreateProcessDir(UINT32 pid, uintptr_t process) +{ + unsigned int intSave; + struct ProcDirEntry *pidDir = NULL; + for (int index = 0; index < (sizeof(g_procProcess) / sizeof(struct ProcProcess)); index++) { + struct ProcProcess *procProcess = &g_procProcess[index]; + struct ProcDirEntry *dir = ProcCreatePorcess(pid, procProcess, process); + if (dir == NULL) { + PRINT_ERR("create /proc/%s error!\n", procProcess->name); + goto CREATE_ERROR; + } + if (index == 0) { + pidDir = dir; + } + } + + if (process != 0) { + SCHEDULER_LOCK(intSave); + ((LosProcessCB *)process)->procDir = pidDir; + SCHEDULER_UNLOCK(intSave); + } + + return 0; + +CREATE_ERROR: + if (pidDir != NULL) { + RemoveProcEntry(pidDir->name, NULL); + } + return -1; +} +#endif /* LOSCFG_PROC_PROCESS_DIR */ + +static int ProcessProcFill(struct SeqBuf *m, void *v) +{ + (void)v; + (void)OsShellCmdTskInfoGet(OS_ALL_TASK_MASK, m, OS_PROCESS_INFO_ALL); + return 0; +} + +static const struct ProcFileOperations PROCESS_PROC_FOPS = { + .read = ProcessProcFill, +}; + +void ProcProcessInit(void) +{ + struct ProcDirEntry *pde = CreateProcEntry("process", 0, NULL); + if (pde == NULL) { + PRINT_ERR("create /proc/process error!\n"); + return; + } + pde->procFileOps = &PROCESS_PROC_FOPS; + +#ifdef LOSCFG_PROC_PROCESS_DIR + int ret = ProcCreateProcessDir(OS_INVALID_VALUE, 0); + if (ret < 0) { + PRINT_ERR("Create proc process self dir failed!\n"); + } + + ret = ProcCreateProcessDir(OS_USER_ROOT_PROCESS_ID, (uintptr_t)OsGetUserInitProcess()); + if (ret < 0) { + PRINT_ERR("Create proc process %d dir failed!\n", OS_USER_ROOT_PROCESS_ID); + } +#endif + return; +} diff --git a/src/kernel_liteos_a/fs/proc/os_adapt/sys_user.c b/src/kernel_liteos_a/fs/proc/os_adapt/sys_user.c new file mode 100644 index 00000000..e834fffc --- /dev/null +++ b/src/kernel_liteos_a/fs/proc/os_adapt/sys_user.c @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "proc_fs.h" +#include "internal.h" +#include "los_process_pri.h" +#include "user_copy.h" +#include "los_memory.h" + +#ifdef LOSCFG_KERNEL_CONTAINER +struct ProcSysUser { + char *name; + mode_t mode; + int type; + const struct ProcFileOperations *fileOps; +}; + +static unsigned int MemUserCopy(const char *src, size_t len, char **kbuf) +{ + if (LOS_IsUserAddressRange((VADDR_T)(UINTPTR)src, len)) { + char *kernelBuf = LOS_MemAlloc(m_aucSysMem1, len + 1); + if (kernelBuf == NULL) { + return ENOMEM; + } + + if (LOS_ArchCopyFromUser(kernelBuf, src, len) != 0) { + (VOID)LOS_MemFree(m_aucSysMem1, kernelBuf); + return EFAULT; + } + kernelBuf[len] = '\0'; + *kbuf = kernelBuf; + return 0; + } + return 0; +} + +static int GetContainerLimitValue(struct ProcFile *pf, const CHAR *buf, size_t count) +{ + int value; + char *kbuf = NULL; + + if ((pf == NULL) || (pf->pPDE == NULL) || (buf == NULL) || (count <= 0)) { + return -EINVAL; + } + + unsigned ret = MemUserCopy(buf, count, &kbuf); + if (ret != 0) { + return -ret; + } else if ((ret == 0) && (kbuf != NULL)) { + buf = (const char *)kbuf; + } + + if (strspn(buf, "0123456789") != count) { + (void)LOS_MemFree(m_aucSysMem1, kbuf); + return -EINVAL; + } + value = atoi(buf); + (void)LOS_MemFree(m_aucSysMem1, kbuf); + return value; +} + +static ssize_t ProcSysUserWrite(struct ProcFile *pf, const char *buf, size_t size, loff_t *ppos) +{ + (void)ppos; + unsigned ret; + int value = GetContainerLimitValue(pf, buf, size); + if (value < 0) { + return -EINVAL; + } + + ContainerType type = (ContainerType)(uintptr_t)pf->pPDE->data; + ret = OsSetContainerLimit(type, value); + if (ret != LOS_OK) { + return -EINVAL; + } + return size; +} + +static int ProcSysUserRead(struct SeqBuf *seqBuf, void *v) +{ + unsigned ret; + if ((seqBuf == NULL) || (v == NULL)) { + return EINVAL; + } + + ContainerType type = (ContainerType)(uintptr_t)v; + ret = OsGetContainerLimit(type); + if (ret == OS_INVALID_VALUE) { + return EINVAL; + } + (void)LosBufPrintf(seqBuf, "\nlimit: %u\n", ret); + (void)LosBufPrintf(seqBuf, "count: %u\n", OsGetContainerCount(type)); + return 0; +} + +static const struct ProcFileOperations SYS_USER_OPT = { + .read = ProcSysUserRead, + .write = ProcSysUserWrite, +}; + +static struct ProcSysUser g_sysUser[] = { +#ifdef LOSCFG_MNT_CONTAINER + { + .name = "max_mnt_container", + .mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, + .type = MNT_CONTAINER, + .fileOps = &SYS_USER_OPT + + }, +#endif +#ifdef LOSCFG_PID_CONTAINER + { + .name = "max_pid_container", + .mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, + .type = PID_CONTAINER, + .fileOps = &SYS_USER_OPT + }, +#endif +#ifdef LOSCFG_USER_CONTAINER + { + .name = "max_user_container", + .mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, + .type = USER_CONTAINER, + .fileOps = &SYS_USER_OPT + + }, +#endif +#ifdef LOSCFG_UTS_CONTAINER + { + .name = "max_uts_container", + .mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, + .type = UTS_CONTAINER, + .fileOps = &SYS_USER_OPT + + }, +#endif +#ifdef LOSCFG_UTS_CONTAINER + { + .name = "max_time_container", + .mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, + .type = UTS_CONTAINER, + .fileOps = &SYS_USER_OPT + + }, +#endif +#ifdef LOSCFG_IPC_CONTAINER + { + .name = "max_ipc_container", + .mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, + .type = IPC_CONTAINER, + .fileOps = &SYS_USER_OPT + }, +#endif +#ifdef LOSCFG_NET_CONTAINER + { + .name = "max_net_container", + .mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, + .type = NET_CONTAINER, + .fileOps = &SYS_USER_OPT + }, +#endif +}; + +static int ProcCreateSysUser(struct ProcDirEntry *parent) +{ + struct ProcDataParm parm; + for (int index = 0; index < (sizeof(g_sysUser) / sizeof(struct ProcSysUser)); index++) { + struct ProcSysUser *sysUser = &g_sysUser[index]; + parm.data = (void *)(uintptr_t)sysUser->type; + parm.dataType = PROC_DATA_STATIC; + struct ProcDirEntry *userFile = ProcCreateData(sysUser->name, sysUser->mode, parent, sysUser->fileOps, &parm); + if (userFile == NULL) { + PRINT_ERR("create /proc/%s/%s error!\n", parent->name, sysUser->name); + return -1; + } + } + return 0; +} + +#define PROC_SYS_USER_MODE (S_IFDIR | S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) +void ProcSysUserInit(void) +{ + struct ProcDirEntry *parentPDE = CreateProcEntry("sys", PROC_SYS_USER_MODE, NULL); + if (parentPDE == NULL) { + return; + } + struct ProcDirEntry *pde = CreateProcEntry("user", PROC_SYS_USER_MODE, parentPDE); + if (pde == NULL) { + PRINT_ERR("create /proc/process error!\n"); + return; + } + + int ret = ProcCreateSysUser(pde); + if (ret < 0) { + PRINT_ERR("Create proc sys user failed!\n"); + } + return; +} +#endif diff --git a/src/kernel_liteos_a/fs/proc/os_adapt/uptime_proc.c b/src/kernel_liteos_a/fs/proc/os_adapt/uptime_proc.c new file mode 100644 index 00000000..552a4451 --- /dev/null +++ b/src/kernel_liteos_a/fs/proc/os_adapt/uptime_proc.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "proc_fs.h" +#include "time.h" +#include "errno.h" +#include "los_cpup.h" + +#define MSEC_TO_NSEC 1000000 +#define SEC_TO_MSEC 1000 +#define DECIMAL_TO_PERCENT 100 + +static int UptimeProcFill(struct SeqBuf *seqBuf, void *v) +{ + struct timespec curtime = {0, 0}; + int ret; +#ifdef LOSCFG_KERNEL_CPUP + float idleRate; + float idleMSec; + float usage; +#endif + ret = clock_gettime(CLOCK_MONOTONIC, &curtime); + if (ret < 0) { + PRINT_ERR("clock_gettime error!\n"); + return -get_errno(); + } + +#ifdef LOSCFG_KERNEL_CPUP + usage = (float)LOS_HistorySysCpuUsage(CPUP_ALL_TIME); + idleRate = LOSCFG_KERNEL_CORE_NUM - usage / LOS_CPUP_PRECISION_MULT / DECIMAL_TO_PERCENT; + idleMSec = ((float)curtime.tv_sec * SEC_TO_MSEC + curtime.tv_nsec / MSEC_TO_NSEC) * idleRate; + + (void)LosBufPrintf(seqBuf, "%llu.%03llu %llu.%03llu\n", (unsigned long long)curtime.tv_sec, + (unsigned long long)(curtime.tv_nsec / MSEC_TO_NSEC), + (unsigned long long)(idleMSec / SEC_TO_MSEC), + (unsigned long long)((unsigned long long)idleMSec % SEC_TO_MSEC)); +#else + (void)LosBufPrintf(seqBuf, "%llu.%03llu\n", (unsigned long long)curtime.tv_sec, + (unsigned long long)(curtime.tv_nsec / MSEC_TO_NSEC)); + +#endif + return 0; +} + +static const struct ProcFileOperations UPTIME_PROC_FOPS = { + .read = UptimeProcFill, +}; + +void ProcUptimeInit(void) +{ + struct ProcDirEntry *pde = CreateProcEntry("uptime", 0, NULL); + if (pde == NULL) { + PRINT_ERR("create /proc/uptime error!\n"); + return; + } + + pde->procFileOps = &UPTIME_PROC_FOPS; +} + diff --git a/src/kernel_liteos_a/fs/proc/os_adapt/vmm_proc.c b/src/kernel_liteos_a/fs/proc/os_adapt/vmm_proc.c new file mode 100644 index 00000000..b4d52391 --- /dev/null +++ b/src/kernel_liteos_a/fs/proc/os_adapt/vmm_proc.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "proc_fs.h" + +#ifdef LOSCFG_SHELL_CMD_DEBUG +#include "los_vm_map.h" +#include "los_vm_dump.h" +#include "los_vm_lock.h" +#include "los_process_pri.h" + +#ifdef LOSCFG_KERNEL_VM + +STATIC VOID OsVmDumpSeqSpaces(struct SeqBuf *seqBuf) +{ + LosVmSpace *space = NULL; + LosVmMapRegion *region = NULL; + LosRbNode *pstRbNode = NULL; + LosRbNode *pstRbNodeNext = NULL; + UINT32 pssPages = 0; + UINT32 spacePages; + UINT32 regionPages; + LosProcessCB *pcb = NULL; + LOS_DL_LIST *aspaceList = LOS_GetVmSpaceList(); + LosMux *aspaceListMux = OsGVmSpaceMuxGet(); + + (VOID)LOS_MuxAcquire(aspaceListMux); + LOS_DL_LIST_FOR_EACH_ENTRY(space, aspaceList, LosVmSpace, node) { + (VOID)LOS_MuxAcquire(&space->regionMux); + spacePages = OsCountAspacePages(space); + pcb = OsGetPIDByAspace(space); + if (pcb == NULL) { + (VOID)LOS_MuxRelease(&space->regionMux); + continue; + } + (VOID)LosBufPrintf(seqBuf, "\r\n PID aspace name base size pages \n"); + (VOID)LosBufPrintf(seqBuf, " ---- ------ ---- ---- ----- ----\n"); + (VOID)LosBufPrintf(seqBuf, " %-4d %#010x %-10.10s %#010x %#010x %d\n", + pcb->processID, space, pcb->processName, space->base, space->size, spacePages); + (VOID)LosBufPrintf(seqBuf, + "\r\n\t region name base size mmu_flags pages pg/ref\n"); + (VOID)LosBufPrintf(seqBuf, + "\t ------ ---- ---- ---- --------- ----- -----\n"); + + RB_SCAN_SAFE(&space->regionRbTree, pstRbNode, pstRbNodeNext) + region = (LosVmMapRegion *)pstRbNode; + regionPages = OsCountRegionPages(space, region, &pssPages); + CHAR *flagsStr = OsArchFlagsToStr(region->regionFlags); + if (flagsStr == NULL) { + break; + } + (VOID)LosBufPrintf(seqBuf, "\t %#010x %-19.19s %#010x %#010x %-15.15s %4d %4d\n", + region, OsGetRegionNameOrFilePath(region), region->range.base, + region->range.size, flagsStr, regionPages, pssPages); + (VOID)LOS_MemFree(m_aucSysMem0, flagsStr); + (VOID)OsRegionOverlapCheck(space, region); + RB_SCAN_SAFE_END(&space->regionRbTree, pstRbNode, pstRbNodeNext) + (VOID)LOS_MuxRelease(&space->regionMux); + } + (VOID)LOS_MuxRelease(aspaceListMux); +} + +static int VmmProcFill(struct SeqBuf *m, void *v) +{ + (void)v; + OsVmDumpSeqSpaces(m); + + return 0; +} + +static const struct ProcFileOperations VMM_PROC_FOPS = { + .write = NULL, + .read = VmmProcFill, +}; + +void ProcVmmInit(void) +{ + struct ProcDirEntry *pde = CreateProcEntry("vmm", 0, NULL); + if (pde == NULL) { + PRINT_ERR("create /proc/vmm error!\n"); + return; + } + + pde->procFileOps = &VMM_PROC_FOPS; +} +#endif +#endif diff --git a/src/kernel_liteos_a/fs/proc/src/proc_file.c b/src/kernel_liteos_a/fs/proc/src/proc_file.c new file mode 100644 index 00000000..92415022 --- /dev/null +++ b/src/kernel_liteos_a/fs/proc/src/proc_file.c @@ -0,0 +1,725 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "proc_file.h" +#include +#include +#include +#include "internal.h" +#include "user_copy.h" + +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define PROC_ROOTDIR_NAMELEN 5 +#define PROC_INUSE 2 + +DEFINE_SPINLOCK(procfsLock); +bool procfsInit = false; + +static struct ProcFile g_procPf = { + .fPos = 0, +}; + +static struct ProcDirEntry g_procRootDirEntry = { + .nameLen = 5, + .mode = S_IFDIR | PROCFS_DEFAULT_MODE, + .count = ATOMIC_INIT(1), + .procFileOps = NULL, + .parent = &g_procRootDirEntry, + .name = "/proc", + .subdir = NULL, + .next = NULL, + .pf = &g_procPf, + .type = VNODE_TYPE_DIR, +}; + +int ProcMatch(unsigned int len, const char *name, struct ProcDirEntry *pn) +{ + if (len != pn->nameLen) { + return 0; + } + return !strncmp(name, pn->name, len); +} + +static struct ProcDirEntry *ProcFindNode(struct ProcDirEntry *parent, const char *name) +{ + struct ProcDirEntry *pn = NULL; + int length; + + if ((parent == NULL) || (name == NULL)) { + return pn; + } + length = strlen(name); + + for (pn = parent->subdir; pn != NULL; pn = pn->next) { + if ((length == pn->nameLen) && strcmp(pn->name, name) == 0) { + break; + } + } + + return pn; +} + +/* + * description: find the file's handle + * path: the file of fullpath + * return: the file of handle + * add by ll + */ +struct ProcDirEntry *ProcFindEntry(const char *path) +{ + struct ProcDirEntry *pn = NULL; + int isfoundsub; + const char *next = NULL; + unsigned int len; + int leveltotal = 0; + int levelcount = 0; + const char *p = NULL; + const char *name = path; + + while ((p = strchr(name, '/')) != NULL) { + leveltotal++; + name = p; + name++; + } + if (leveltotal < 1) { + return pn; + } + + spin_lock(&procfsLock); + + pn = &g_procRootDirEntry; + + while ((pn != NULL) && (levelcount < leveltotal)) { + levelcount++; + isfoundsub = 0; + while (pn != NULL) { + next = strchr(path, '/'); + if (next == NULL) { + while (pn != NULL) { + if (strcmp(path, pn->name) == 0) { + spin_unlock(&procfsLock); + return pn; + } + pn = pn->next; + } + pn = NULL; + spin_unlock(&procfsLock); + return pn; + } + + len = next - path; + if (pn == &g_procRootDirEntry) { + if (levelcount == leveltotal) { + spin_unlock(&procfsLock); + return pn; + } + len = g_procRootDirEntry.nameLen; + } + if (ProcMatch(len, path, pn)) { + isfoundsub = 1; + path += len + 1; + break; + } + + pn = pn->next; + } + + if ((isfoundsub == 1) && (pn != NULL)) { + pn = pn->subdir; + } else { + pn = NULL; + spin_unlock(&procfsLock); + return pn; + } + } + spin_unlock(&procfsLock); + return NULL; +} + +static int CheckProcName(const char *name, struct ProcDirEntry **parent, const char **lastName) +{ + struct ProcDirEntry *pn = *parent; + const char *segment = name; + const char *restName = NULL; + int length; + + if (pn == NULL) { + pn = &g_procRootDirEntry; + } + + spin_lock(&procfsLock); + + restName = strchr(segment, '/'); + for (; restName != NULL; restName = strchr(segment, '/')) { + length = restName - segment; + for (pn = pn->subdir; pn != NULL; pn = pn->next) { + if (ProcMatch(length, segment, pn)) { + break; + } + } + if (pn == NULL) { + PRINT_ERR(" Error!No such name '%s'\n", name); + spin_unlock(&procfsLock); + return -ENOENT; + } + segment = restName; + segment++; + } + *lastName = segment; + *parent = pn; + spin_unlock(&procfsLock); + + return 0; +} + +static struct ProcDirEntry *ProcAllocNode(struct ProcDirEntry **parent, const char *name, mode_t mode) +{ + struct ProcDirEntry *pn = NULL; + const char *lastName = NULL; + int ret; + + if ((name == NULL) || (strlen(name) == 0) || (procfsInit == false)) { + return pn; + } + + if (CheckProcName(name, parent, &lastName) != 0) { + return pn; + } + + if (strlen(lastName) > NAME_MAX) { + return pn; + } + + if ((S_ISDIR((*parent)->mode) == 0) || (strchr(lastName, '/'))) { + return pn; + } + + pn = (struct ProcDirEntry *)malloc(sizeof(struct ProcDirEntry)); + if (pn == NULL) { + return NULL; + } + + if ((mode & S_IALLUGO) == 0) { + mode |= S_IRUSR | S_IRGRP | S_IROTH; + } + + (void)memset_s(pn, sizeof(struct ProcDirEntry), 0, sizeof(struct ProcDirEntry)); + pn->nameLen = strlen(lastName); + pn->mode = mode; + ret = memcpy_s(pn->name, sizeof(pn->name), lastName, strlen(lastName) + 1); + if (ret != EOK) { + free(pn); + return NULL; + } + + pn->pf = (struct ProcFile *)malloc(sizeof(struct ProcFile)); + if (pn->pf == NULL) { + free(pn); + return NULL; + } + (void)memset_s(pn->pf, sizeof(struct ProcFile), 0, sizeof(struct ProcFile)); + pn->pf->pPDE = pn; + ret = memcpy_s(pn->pf->name, sizeof(pn->pf->name), pn->name, pn->nameLen + 1); + if (ret != EOK) { + free(pn->pf); + free(pn); + return NULL; + } + + atomic_set(&pn->count, 1); + spin_lock_init(&pn->pdeUnloadLock); + return pn; +} + +static int ProcAddNode(struct ProcDirEntry *parent, struct ProcDirEntry *pn) +{ + struct ProcDirEntry *temp = NULL; + + if (parent == NULL) { + PRINT_ERR("%s(): parent is NULL", __FUNCTION__); + return -EINVAL; + } + + if (pn->parent != NULL) { + PRINT_ERR("%s(): node already has a parent", __FUNCTION__); + return -EINVAL; + } + + if (S_ISDIR(parent->mode) == 0) { + PRINT_ERR("%s(): parent is not a directory", __FUNCTION__); + return -EINVAL; + } + + spin_lock(&procfsLock); + + temp = ProcFindNode(parent, pn->name); + if (temp != NULL) { + PRINT_ERR("Error!ProcDirEntry '%s/%s' already registered\n", parent->name, pn->name); + spin_unlock(&procfsLock); + return -EEXIST; + } + + pn->parent = parent; + pn->next = parent->subdir; + parent->subdir = pn; + + spin_unlock(&procfsLock); + + return 0; +} + +void ProcDetachNode(struct ProcDirEntry *pn) +{ + struct ProcDirEntry *parent = pn->parent; + struct ProcDirEntry **iter = NULL; + + if (parent == NULL) { + PRINT_ERR("%s(): node has no parent", __FUNCTION__); + return; + } + + iter = &parent->subdir; + while (*iter != NULL) { + if (*iter == pn) { + *iter = pn->next; + break; + } + iter = &(*iter)->next; + } + pn->parent = NULL; +} + +static struct ProcDirEntry *ProcCreateDir(struct ProcDirEntry *parent, const char *name, + const struct ProcFileOperations *procFileOps, mode_t mode) +{ + struct ProcDirEntry *pn = NULL; + int ret; + + pn = ProcAllocNode(&parent, name, S_IFDIR | mode); + if (pn == NULL) { + return pn; + } + pn->procFileOps = procFileOps; + pn->type = VNODE_TYPE_DIR; + ret = ProcAddNode(parent, pn); + if (ret != 0) { + free(pn->pf); + free(pn); + return NULL; + } + + return pn; +} + +static struct ProcDirEntry *ProcCreateFile(struct ProcDirEntry *parent, const char *name, + const struct ProcFileOperations *procFileOps, mode_t mode) +{ + struct ProcDirEntry *pn = NULL; + int ret; + + pn = ProcAllocNode(&parent, name, S_IFREG | mode); + if (pn == NULL) { + return pn; + } + + pn->procFileOps = procFileOps; + pn->type = VNODE_TYPE_REG; +#ifdef LOSCFG_PROC_PROCESS_DIR + if (S_ISLNK(mode)) { + pn->type = VNODE_TYPE_VIR_LNK; + } +#endif + ret = ProcAddNode(parent, pn); + if (ret != 0) { + free(pn->pf); + free(pn); + return NULL; + } + + return pn; +} + +struct ProcDirEntry *CreateProcEntry(const char *name, mode_t mode, struct ProcDirEntry *parent) +{ + struct ProcDirEntry *pde = NULL; + + if (S_ISDIR(mode)) { + pde = ProcCreateDir(parent, name, NULL, mode); + } else { + pde = ProcCreateFile(parent, name, NULL, mode); + } + return pde; +} + +void ProcEntryClearVnode(struct ProcDirEntry *entry) +{ + struct Vnode *item = NULL; + struct Vnode *nextItem = NULL; + + VnodeHold(); + LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, GetVnodeActiveList(), struct Vnode, actFreeEntry) { + if ((struct ProcDirEntry *)item->data != entry) { + continue; + } + + if (VnodeFree(item) != LOS_OK) { + PRINT_ERR("ProcEntryClearVnode free failed, entry: %s\n", entry->name); + } + } + VnodeDrop(); + return; +} + +static void FreeProcEntry(struct ProcDirEntry *entry) +{ + if (entry == NULL) { + return; + } + + if (entry->pf != NULL) { + free(entry->pf); + entry->pf = NULL; + } + if ((entry->dataType == PROC_DATA_FREE) && (entry->data != NULL)) { + free(entry->data); + } + entry->data = NULL; + free(entry); +} + +void ProcFreeEntry(struct ProcDirEntry *pn) +{ + if (atomic_dec_and_test(&pn->count)) { + FreeProcEntry(pn); + } +} + +void RemoveProcEntryTravalsal(struct ProcDirEntry *pn) +{ + if (pn == NULL) { + return; + } + RemoveProcEntryTravalsal(pn->next); + RemoveProcEntryTravalsal(pn->subdir); + + ProcEntryClearVnode(pn); + + ProcFreeEntry(pn); +} + +void RemoveProcEntry(const char *name, struct ProcDirEntry *parent) +{ + struct ProcDirEntry *pn = NULL; + const char *lastName = name; + + if ((name == NULL) || (strlen(name) == 0) || (procfsInit == false)) { + return; + } + + if (CheckProcName(name, &parent, &lastName) != 0) { + return; + } + + spin_lock(&procfsLock); + + pn = ProcFindNode(parent, lastName); + if (pn == NULL) { + PRINT_ERR("Error:name '%s' not found!\n", name); + spin_unlock(&procfsLock); + return; + } + ProcDetachNode(pn); + + spin_unlock(&procfsLock); + + RemoveProcEntryTravalsal(pn->subdir); + + ProcEntryClearVnode(pn); + + ProcFreeEntry(pn); +} + +struct ProcDirEntry *ProcMkdirMode(const char *name, mode_t mode, struct ProcDirEntry *parent) +{ + return ProcCreateDir(parent, name, NULL, mode); +} + +struct ProcDirEntry *ProcMkdir(const char *name, struct ProcDirEntry *parent) +{ + return ProcCreateDir(parent, name, NULL, 0); +} + +struct ProcDirEntry *ProcCreateData(const char *name, mode_t mode, struct ProcDirEntry *parent, + const struct ProcFileOperations *procFileOps, struct ProcDataParm *param) +{ + struct ProcDirEntry *pde = CreateProcEntry(name, mode, parent); + if (pde != NULL) { + if (procFileOps != NULL) { + pde->procFileOps = procFileOps; + } + if (param != NULL) { + pde->data = param->data; + pde->dataType = param->dataType; + } + } + return pde; +} + +struct ProcDirEntry *ProcCreate(const char *name, mode_t mode, struct ProcDirEntry *parent, + const struct ProcFileOperations *procFileOps) +{ + return ProcCreateData(name, mode, parent, procFileOps, NULL); +} + +int ProcStat(const char *file, struct ProcStat *buf) +{ + struct ProcDirEntry *pn = NULL; + int len = sizeof(buf->name); + int ret; + + pn = ProcFindEntry(file); + if (pn == NULL) { + return ENOENT; + } + ret = strncpy_s(buf->name, len, pn->name, len - 1); + if (ret != EOK) { + return ENAMETOOLONG; + } + buf->name[len - 1] = '\0'; + buf->stMode = pn->mode; + buf->pPDE = pn; + + return 0; +} + +static int GetNextDir(struct ProcDirEntry *pn, void *buf, size_t len) +{ + char *buff = (char *)buf; + + if (pn->pdirCurrent == NULL) { + *buff = '\0'; + return -ENOENT; + } + int namelen = pn->pdirCurrent->nameLen; + int ret = memcpy_s(buff, len, pn->pdirCurrent->name, namelen); + if (ret != EOK) { + return -ENAMETOOLONG; + } + + pn->pdirCurrent = pn->pdirCurrent->next; + pn->pf->fPos++; + return ENOERR; +} + +int ProcOpen(struct ProcFile *procFile) +{ + if (procFile == NULL) { + return PROC_ERROR; + } + if (procFile->sbuf != NULL) { + return OK; + } + + struct SeqBuf *buf = LosBufCreat(); + if (buf == NULL) { + return PROC_ERROR; + } + procFile->sbuf = buf; + return OK; +} + +static int ProcRead(struct ProcDirEntry *pde, char *buf, size_t len) +{ + if (pde == NULL || pde->pf == NULL) { + return PROC_ERROR; + } + struct ProcFile *procFile = pde->pf; + struct SeqBuf *sb = procFile->sbuf; + + if (sb->buf == NULL) { + // only read once to build the storage buffer + if (pde->procFileOps->read(sb, pde->data) != 0) { + return PROC_ERROR; + } + } + + size_t realLen; + loff_t pos = procFile->fPos; + + if ((pos >= sb->count) || (len == 0)) { + /* there's no data or at the file tail. */ + realLen = 0; + } else { + realLen = MIN((sb->count - pos), MIN(len, INT_MAX)); + if (LOS_CopyFromKernel(buf, len, sb->buf + pos, realLen) != 0) { + return PROC_ERROR; + } + + procFile->fPos = pos + realLen; + } + + return (ssize_t)realLen; +} + +struct ProcDirEntry *OpenProcFile(const char *fileName, int flags, ...) +{ + struct ProcDirEntry *pn = ProcFindEntry(fileName); + if (pn == NULL) { + return NULL; + } + + if (S_ISREG(pn->mode) && (pn->count != 1)) { + return NULL; + } + + pn->flags = (unsigned int)(pn->flags) | (unsigned int)flags; + atomic_set(&pn->count, PROC_INUSE); + if (ProcOpen(pn->pf) != OK) { + return NULL; + } + if (S_ISREG(pn->mode) && (pn->procFileOps != NULL) && (pn->procFileOps->open != NULL)) { + (void)pn->procFileOps->open((struct Vnode *)pn, pn->pf); + } + if (S_ISDIR(pn->mode)) { + pn->pdirCurrent = pn->subdir; + pn->pf->fPos = 0; + } + + return pn; +} + +int ReadProcFile(struct ProcDirEntry *pde, void *buf, size_t len) +{ + int result = -EPERM; + + if (pde == NULL) { + return result; + } + if (S_ISREG(pde->mode)) { + if ((pde->procFileOps != NULL) && (pde->procFileOps->read != NULL)) { + result = ProcRead(pde, (char *)buf, len); + } + } else if (S_ISDIR(pde->mode)) { + result = GetNextDir(pde, buf, len); + } + return result; +} + +int WriteProcFile(struct ProcDirEntry *pde, const void *buf, size_t len) +{ + int result = -EPERM; + + if (pde == NULL) { + return result; + } + + if (S_ISDIR(pde->mode)) { + return -EISDIR; + } + + spin_lock(&procfsLock); + if ((pde->procFileOps != NULL) && (pde->procFileOps->write != NULL)) { + result = pde->procFileOps->write(pde->pf, (const char *)buf, len, &(pde->pf->fPos)); + } + spin_unlock(&procfsLock); + return result; +} + +loff_t LseekProcFile(struct ProcDirEntry *pde, loff_t offset, int whence) +{ + if (pde == NULL || pde->pf == NULL) { + return PROC_ERROR; + } + + struct ProcFile *procFile = pde->pf; + + loff_t result = -EINVAL; + + switch (whence) { + case SEEK_CUR: + result = procFile->fPos + offset; + break; + + case SEEK_SET: + result = offset; + break; + + default: + break; + } + + if (result >= 0) { + procFile->fPos = result; + } + + return result; +} + +int LseekDirProcFile(struct ProcDirEntry *pde, off_t *pos, int whence) +{ + /* Only allow SEEK_SET to zero */ + if ((whence != SEEK_SET) || (*pos != 0)) { + return EINVAL; + } + pde->pdirCurrent = pde->subdir; + pde->pf->fPos = 0; + return ENOERR; +} + +int CloseProcFile(struct ProcDirEntry *pde) +{ + int result = 0; + + if (pde == NULL) { + return -EPERM; + } + pde->pf->fPos = 0; + atomic_set(&pde->count, 1); + if (S_ISDIR(pde->mode)) { + pde->pdirCurrent = pde->subdir; + } + + if ((pde->procFileOps != NULL) && (pde->procFileOps->release != NULL)) { + result = pde->procFileOps->release((struct Vnode *)pde, pde->pf); + } + LosBufRelease(pde->pf->sbuf); + pde->pf->sbuf = NULL; + + if (pde->parent == NULL) { + FreeProcEntry(pde); + } + return result; +} + +struct ProcDirEntry *GetProcRootEntry(void) +{ + return &g_procRootDirEntry; +} diff --git a/src/kernel_liteos_a/fs/proc/src/proc_shellcmd.c b/src/kernel_liteos_a/fs/proc/src/proc_shellcmd.c new file mode 100644 index 00000000..6e2d8fbf --- /dev/null +++ b/src/kernel_liteos_a/fs/proc/src/proc_shellcmd.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "los_config.h" + +#if defined(LOSCFG_SHELL_CMD_DEBUG) && defined(LOSCFG_FS_PROC) +#include "los_typedef.h" +#include "shell.h" +#include "shcmd.h" +#include "proc_file.h" +#include "dirent.h" +#include "proc_fs.h" + +#define WRITEPROC_ARGC 3 + +int OsShellCmdWriteProc(int argc, char **argv) +{ + int i; + int ret; + const char *path = NULL; + const char *value = NULL; + unsigned int len; + struct ProcDirEntry *handle = NULL; + char realPath[PATH_MAX] = {'\0'}; + const char *rootProcDir = "/proc/"; + + if (argc == WRITEPROC_ARGC) { + value = argv[0]; + path = argv[2]; // 2: index of path + len = strlen(value) + 1; /* + 1:add the \0 */ + if (strncmp(argv[1], ">>", strlen(">>")) == 0) { + if ((realpath(path, realPath) == NULL) || (strncmp(realPath, rootProcDir, strlen(rootProcDir)) != 0)) { + PRINT_ERR("No such file or directory\n"); + return PROC_ERROR; + } + + handle = OpenProcFile(realPath, O_TRUNC); + if (handle == NULL) { + PRINT_ERR("No such file or directory\n"); + return PROC_ERROR; + } + + ret = WriteProcFile(handle, value, len); + if (ret < 0) { + (void)CloseProcFile(handle); + PRINT_ERR("write error\n"); + return PROC_ERROR; + } + for (i = 0; i < argc; i++) { + PRINTK("%s%s", i > 0 ? " " : "", argv[i]); + } + PRINTK("\n"); + (void)CloseProcFile(handle); + return LOS_OK; + } + } + PRINT_ERR("writeproc [data] [>>] [path]\n"); + return PROC_ERROR; +} + +SHELLCMD_ENTRY(writeproc_shellcmd, CMD_TYPE_EX, "writeproc", XARGS, (CmdCallBackFunc)OsShellCmdWriteProc); +#endif diff --git a/src/kernel_liteos_a/fs/ramfs/BUILD.gn b/src/kernel_liteos_a/fs/ramfs/BUILD.gn new file mode 100644 index 00000000..1f95d11c --- /dev/null +++ b/src/kernel_liteos_a/fs/ramfs/BUILD.gn @@ -0,0 +1,37 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") +import("$THIRDPARTY_NUTTX_DIR/NuttX.gni") + +module_switch = defined(LOSCFG_FS_RAMFS) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = NUTTX_FS_TMPFS_SRC_FILES +} diff --git a/src/kernel_liteos_a/fs/ramfs/Kconfig b/src/kernel_liteos_a/fs/ramfs/Kconfig new file mode 100644 index 00000000..a1d2480e --- /dev/null +++ b/src/kernel_liteos_a/fs/ramfs/Kconfig @@ -0,0 +1,6 @@ +config FS_RAMFS + bool "Enable RAMFS" + default y + depends on FS_VFS + help + Answer Y to enable LiteOS support ramfs filesystem. diff --git a/src/kernel_liteos_a/fs/ramfs/Makefile b/src/kernel_liteos_a/fs/ramfs/Makefile new file mode 100644 index 00000000..dce8aef8 --- /dev/null +++ b/src/kernel_liteos_a/fs/ramfs/Makefile @@ -0,0 +1,36 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := $(wildcard $(LITEOSTHIRDPARTY)/NuttX/fs/tmpfs/*.c) + +include $(MODULE) diff --git a/src/kernel_liteos_a/fs/romfs/BUILD.gn b/src/kernel_liteos_a/fs/romfs/BUILD.gn new file mode 100644 index 00000000..e01fc43b --- /dev/null +++ b/src/kernel_liteos_a/fs/romfs/BUILD.gn @@ -0,0 +1,37 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") +import("$THIRDPARTY_NUTTX_DIR/NuttX.gni") + +module_switch = defined(LOSCFG_FS_ROMFS) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = NUTTX_FS_ROMFS_SRC_FILES +} diff --git a/src/kernel_liteos_a/fs/romfs/Kconfig b/src/kernel_liteos_a/fs/romfs/Kconfig new file mode 100644 index 00000000..bb6744a0 --- /dev/null +++ b/src/kernel_liteos_a/fs/romfs/Kconfig @@ -0,0 +1,6 @@ +config FS_ROMFS + bool "Enable ROMFS" + default n + depends on FS_VFS + help + Answer Y to enable LiteOS support romfs filesystem. diff --git a/src/kernel_liteos_a/fs/romfs/Makefile b/src/kernel_liteos_a/fs/romfs/Makefile new file mode 100644 index 00000000..4d40ec5c --- /dev/null +++ b/src/kernel_liteos_a/fs/romfs/Makefile @@ -0,0 +1,35 @@ +# Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := $(wildcard $(LITEOSTHIRDPARTY)/NuttX/fs/romfs/*.c) + +include $(MODULE) diff --git a/src/kernel_liteos_a/fs/rootfs/BUILD.gn b/src/kernel_liteos_a/fs/rootfs/BUILD.gn new file mode 100644 index 00000000..e69ae93e --- /dev/null +++ b/src/kernel_liteos_a/fs/rootfs/BUILD.gn @@ -0,0 +1,44 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = defined(LOSCFG_PLATFORM_ROOTFS) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ + "los_bootargs.c", + "los_rootfs.c", + ] + public_configs = [ ":public" ] +} + +config("public") { + include_dirs = [ "." ] +} diff --git a/src/kernel_liteos_a/fs/rootfs/Kconfig b/src/kernel_liteos_a/fs/rootfs/Kconfig new file mode 100644 index 00000000..d1c39d24 --- /dev/null +++ b/src/kernel_liteos_a/fs/rootfs/Kconfig @@ -0,0 +1,49 @@ +config PLATFORM_ROOTFS + bool "Enable ROOTFS" + default y + depends on FS_JFFS || FS_FAT || DRIVERS_MTD_NAND + help + Answer Y to enable LiteOS support rootfs. + +choice + prompt "Storage device type" + default STORAGE_SPINOR + depends on PLATFORM_ROOTFS + help + SPI_NOR or SPI_NAND or EMMC. + +config STORAGE_SPINOR + depends on PLATFORM_ROOTFS && DRIVERS_MTD_SPI_NOR + bool "SPI_NOR Flash" + +config STORAGE_SPINAND + depends on PLATFORM_ROOTFS && DRIVERS_MTD_NAND + bool "SPI_NAND Flash" + +config STORAGE_EMMC + depends on PLATFORM_ROOTFS && DRIVERS_EMMC + bool "EMMC" + +endchoice + +config BOOTENV_ADDR + int "Address of boot command line (KB)" + depends on PLATFORM_ROOTFS && (STORAGE_SPINOR || STORAGE_SPINAND || STORAGE_EMMC) + default 512 + help + Boot command line addr. + +config BOOTENV_RAM + bool "Read bootenv from RAM" + default n + depends on PLATFORM_ROOTFS + help + Answer Y to read bootenv from ram. Need boot copy to RAM. + +config BOOTENV_RAMSIZE + int "Size of boot environment in RAM (Byte)" + depends on PLATFORM_ROOTFS && BOOTENV_RAM + range 128 1024 + default 512 + help + Boot environment in Ram space size, range from 128 to 1024 byte. diff --git a/src/kernel_liteos_a/fs/rootfs/Makefile b/src/kernel_liteos_a/fs/rootfs/Makefile new file mode 100644 index 00000000..7afed881 --- /dev/null +++ b/src/kernel_liteos_a/fs/rootfs/Makefile @@ -0,0 +1,39 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := rootfs + +LOCAL_SRCS := $(wildcard los_rootfs.c los_bootargs.c) + +LOCAL_FLAGS := $(LOCAL_INCLUDE) + +include $(MODULE) + diff --git a/src/kernel_liteos_a/fs/rootfs/los_bootargs.c b/src/kernel_liteos_a/fs/rootfs/los_bootargs.c new file mode 100644 index 00000000..fb40d796 --- /dev/null +++ b/src/kernel_liteos_a/fs/rootfs/los_bootargs.c @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_bootargs.h" +#include "los_base.h" +#include "string.h" + +#if defined(LOSCFG_STORAGE_SPINOR) || defined(LOSCFG_STORAGE_SPINAND) +#include "mtd_list.h" +#endif + +#ifdef LOSCFG_STORAGE_EMMC +#include "disk.h" +#endif + +STATIC CHAR *g_cmdLine = NULL; +STATIC UINT64 g_alignSize = 0; +STATIC struct BootArgs g_bootArgs[MAX_ARGS_NUM] = {0}; + +INT32 LOS_GetCmdLine(VOID) +{ + int ret; + + g_cmdLine = (CHAR *)malloc(COMMAND_LINE_SIZE); + if (g_cmdLine == NULL) { + PRINT_ERR("Malloc g_cmdLine space error!\n"); + return LOS_NOK; + } + +#ifdef LOSCFG_STORAGE_EMMC + los_disk *emmcDisk = los_get_mmcdisk_bytype(EMMC); + if (emmcDisk == NULL) { + PRINT_ERR("Get EMMC disk failed!\n"); + goto ERROUT; + } + g_alignSize = EMMC_SEC_SIZE; + ret = los_disk_read(emmcDisk->disk_id, g_cmdLine, COMMAND_LINE_ADDR / EMMC_SEC_SIZE, + COMMAND_LINE_SIZE / EMMC_SEC_SIZE, TRUE); + if (ret == 0) { + return LOS_OK; + } +#endif + +#ifdef LOSCFG_STORAGE_SPINOR + struct MtdDev *mtd = GetMtd("spinor"); + if (mtd == NULL) { + PRINT_ERR("Get spinor mtd failed!\n"); + goto ERROUT; + } + g_alignSize = mtd->eraseSize; + ret = mtd->read(mtd, COMMAND_LINE_ADDR, COMMAND_LINE_SIZE, g_cmdLine); + if (ret == COMMAND_LINE_SIZE) { + return LOS_OK; + } +#endif + +#ifdef LOSCFG_STORAGE_SPINAND + struct MtdDev *mtd = GetMtd("nand"); + if (mtd == NULL) { + PRINT_ERR("Get nand mtd failed!\n"); + goto ERROUT; + } + g_alignSize = mtd->eraseSize; + ret = mtd->read(mtd, COMMAND_LINE_ADDR, COMMAND_LINE_SIZE, g_cmdLine); + if (ret == COMMAND_LINE_SIZE) { + return LOS_OK; + } +#endif + + PRINT_ERR("Read cmdline error!\n"); +ERROUT: + free(g_cmdLine); + g_cmdLine = NULL; + return LOS_NOK; +} + +VOID LOS_FreeCmdLine(VOID) +{ + if (g_cmdLine != NULL) { + free(g_cmdLine); + g_cmdLine = NULL; + } +} + +STATIC INT32 GetBootargs(CHAR **args) +{ +#ifdef LOSCFG_BOOTENV_RAM + *args = OsGetArgsAddr(); + return LOS_OK; +#else + INT32 i; + INT32 len = 0; + CHAR *tmp = NULL; + const CHAR *bootargsName = "bootargs="; + + if (g_cmdLine == NULL) { + PRINT_ERR("Should call LOS_GetCmdLine() first!\n"); + return LOS_NOK; + } + + for (i = 0; i < COMMAND_LINE_SIZE; i += len + 1) { + len = strlen(g_cmdLine + i); + tmp = strstr(g_cmdLine + i, bootargsName); + if (tmp != NULL) { + *args = tmp + strlen(bootargsName); + return LOS_OK; + } + } + PRINT_ERR("Cannot find bootargs!\n"); + return LOS_NOK; +#endif +} + +INT32 LOS_ParseBootargs(VOID) +{ + INT32 idx = 0; + INT32 ret; + CHAR *args = NULL; + CHAR *argName = NULL; + CHAR *argValue = NULL; + + ret = GetBootargs(&args); + if (ret != LOS_OK) { + return LOS_NOK; + } + + while ((argValue = strsep(&args, " ")) != NULL) { + argName = strsep(&argValue, "="); + if (argValue == NULL) { + /* If the argument is not compliance with the format 'foo=bar' */ + g_bootArgs[idx].argName = argName; + g_bootArgs[idx].argValue = argName; + } else { + g_bootArgs[idx].argName = argName; + g_bootArgs[idx].argValue = argValue; + } + if (++idx >= MAX_ARGS_NUM) { + /* Discard the rest arguments */ + break; + } + } + return LOS_OK; +} + +INT32 LOS_GetArgValue(CHAR *argName, CHAR **argValue) +{ + INT32 idx = 0; + + while (idx < MAX_ARGS_NUM) { + if (g_bootArgs[idx].argName == NULL) { + break; + } + if (strcmp(argName, g_bootArgs[idx].argName) == 0) { + *argValue = g_bootArgs[idx].argValue; + return LOS_OK; + } + idx++; + } + + return LOS_NOK; +} + +UINT64 LOS_GetAlignsize(VOID) +{ + return g_alignSize; +} + +UINT64 LOS_SizeStrToNum(CHAR *value) +{ + UINT64 num = 0; + + /* If the string is a hexadecimal value */ + if (sscanf_s(value, "0x%llx", &num) > 0) { + value += strlen("0x"); + if (strspn(value, "0123456789abcdefABCDEF") < strlen(value)) { + goto ERROUT; + } + return num; + } + + /* If the string is a decimal value in unit *Bytes */ + INT32 ret = sscanf_s(value, "%d", &num); + INT32 decOffset = strspn(value, "0123456789"); + CHAR *endPos = value + decOffset; + if ((ret <= 0) || (decOffset < (strlen(value) - 1))) { + goto ERROUT; + } + + if (strlen(endPos) == 0) { + return num; + } else if (strcasecmp(endPos, "k") == 0) { + num = num * BYTES_PER_KBYTE; + } else if (strcasecmp(endPos, "m") == 0) { + num = num * BYTES_PER_MBYTE; + } else if (strcasecmp(endPos, "g") == 0) { + num = num * BYTES_PER_GBYTE; + } else { + goto ERROUT; + } + + return num; + +ERROUT: + PRINT_ERR("Invalid value string \"%s\"!\n", value); + return num; +} diff --git a/src/kernel_liteos_a/fs/rootfs/los_bootargs.h b/src/kernel_liteos_a/fs/rootfs/los_bootargs.h new file mode 100644 index 00000000..93735b92 --- /dev/null +++ b/src/kernel_liteos_a/fs/rootfs/los_bootargs.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_BOOTARGS_H +#define _LOS_BOOTARGS_H + +#include "los_typedef.h" + +#define BYTES_PER_GBYTE (1 << 30) +#define BYTES_PER_MBYTE (1 << 20) +#define BYTES_PER_KBYTE (1 << 10) +#define COMMAND_LINE_ADDR (LOSCFG_BOOTENV_ADDR * BYTES_PER_KBYTE) +#define COMMAND_LINE_SIZE 1024 +#define MAX_ARGS_NUM 100 +#ifdef LOSCFG_STORAGE_EMMC +#define EMMC_SEC_SIZE 512 +#endif + +struct BootArgs { + CHAR *argName; + CHAR *argValue; +}; + +INT32 LOS_GetCmdLine(VOID); +VOID LOS_FreeCmdLine(VOID); +INT32 LOS_ParseBootargs(VOID); +INT32 LOS_GetArgValue(CHAR *argName, CHAR **argValue); +UINT64 LOS_GetAlignsize(VOID); +UINT64 LOS_SizeStrToNum(CHAR *value); + +#ifdef LOSCFG_BOOTENV_RAM +CHAR *OsGetArgsAddr(VOID); +#endif +#endif /* _LOS_BOOTARGS_H */ \ No newline at end of file diff --git a/src/kernel_liteos_a/fs/rootfs/los_rootfs.c b/src/kernel_liteos_a/fs/rootfs/los_rootfs.c new file mode 100644 index 00000000..346618b4 --- /dev/null +++ b/src/kernel_liteos_a/fs/rootfs/los_rootfs.c @@ -0,0 +1,363 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_rootfs.h" +#include "los_bootargs.h" +#include "los_base.h" +#include "string.h" +#include "sys/mount.h" +#include "sys/stat.h" +#include "sys/types.h" + +#if defined(LOSCFG_STORAGE_SPINOR) || defined(LOSCFG_STORAGE_SPINAND) +#include "mtd_list.h" +#include "mtd_partition.h" +#endif + +#ifdef LOSCFG_STORAGE_EMMC +#include "disk.h" +#include "ff.h" +#endif + + +#ifdef LOSCFG_STORAGE_EMMC +struct disk_divide_info *StorageBlockGetEmmc(void); +struct block_operations *StorageBlockGetMmcOps(void); +char *StorageBlockGetEmmcNodeName(void *block); + +STATIC INT32 AddEmmcParts(INT32 rootAddr, INT32 rootSize, INT32 userAddr, INT32 userSize) +{ + INT32 ret; + + los_disk *emmcDisk = los_get_mmcdisk_bytype(EMMC); + if (emmcDisk == NULL) { + PRINT_ERR("Get EMMC disk failed!\n"); + return LOS_NOK; + } + + void *block = ((struct drv_data *)emmcDisk->dev->data)->priv; + const char *node_name = StorageBlockGetEmmcNodeName(block); + if (los_disk_deinit(emmcDisk->disk_id) != ENOERR) { + PRINT_ERR("Failed to deinit emmc disk!\n"); + return LOS_NOK; + } + + struct disk_divide_info *emmc = StorageBlockGetEmmc(); + ret = add_mmc_partition(emmc, rootAddr / EMMC_SEC_SIZE, rootSize / EMMC_SEC_SIZE); + if (ret != LOS_OK) { + PRINT_ERR("Failed to add mmc root partition!\n"); + return LOS_NOK; + } + +#ifdef LOSCFG_PLATFORM_PATCHFS + UINT64 patchStartCnt = userAddr / EMMC_SEC_SIZE; + UINT64 patchSizeCnt = PATCH_SIZE / EMMC_SEC_SIZE; + ret = add_mmc_partition(emmc, patchStartCnt, patchSizeCnt); + if (ret != LOS_OK) { + PRINT_ERR("Failed to add mmc patch partition!\n"); + return LOS_NOK; + } + userAddr += PATCH_SIZE; +#endif + + UINT64 storageStartCnt = userAddr / EMMC_SEC_SIZE; + UINT64 storageSizeCnt = userSize / EMMC_SEC_SIZE; + UINT64 userdataStartCnt = storageStartCnt + storageSizeCnt; + UINT64 userdataSizeCnt = emmcDisk->sector_count - userdataStartCnt; + ret = add_mmc_partition(emmc, storageStartCnt, storageSizeCnt); + if (ret != LOS_OK) { + PRINT_ERR("Failed to add mmc storage partition!\n"); + return LOS_NOK; + } + + ret = add_mmc_partition(emmc, userdataStartCnt, userdataSizeCnt); + if (ret != LOS_OK) { + PRINT_ERR("Failed to add mmc userdata partition!\n"); + return LOS_NOK; + } + + LOS_Msleep(10); /* 100, sleep time. waiting for device identification */ + + INT32 diskId = los_alloc_diskid_byname(node_name); + if (diskId < 0) { + PRINT_ERR("Failed to alloc disk %s!\n", node_name); + return LOS_NOK; + } + + if (los_disk_init(node_name, StorageBlockGetMmcOps(), block, diskId, emmc) != ENOERR) { + PRINT_ERR("Failed to init emmc disk!\n"); + return LOS_NOK; + } + + return LOS_OK; +} +#endif + + +STATIC INT32 AddPartitions(CHAR *dev, UINT64 rootAddr, UINT64 rootSize, UINT64 userAddr, UINT64 userSize) +{ +#if defined(LOSCFG_STORAGE_SPINOR) || defined(LOSCFG_STORAGE_SPINAND) + INT32 ret; + INT32 blk0 = 0; + INT32 blk2 = 2; + if (strcmp(dev, "flash") == 0 || strcmp(dev, FLASH_TYPE) == 0) { + ret = add_mtd_partition(FLASH_TYPE, rootAddr, rootSize, blk0); + if (ret != LOS_OK) { + PRINT_ERR("Failed to add mtd root partition!\n"); + return LOS_NOK; + } + + ret = add_mtd_partition(FLASH_TYPE, userAddr, userSize, blk2); + if (ret != LOS_OK) { + PRINT_ERR("Failed to add mtd storage partition!\n"); + return LOS_NOK; + } + + return LOS_OK; + } +#endif + +#ifdef LOSCFG_STORAGE_EMMC + if (strcmp(dev, "emmc") == 0) { + return AddEmmcParts(rootAddr, rootSize, userAddr, userSize); + } +#endif + + PRINT_ERR("Unsupport dev type: %s\n", dev); + return LOS_NOK; +} + + +STATIC INT32 ParseRootArgs(CHAR **dev, CHAR **fstype, UINT64 *rootAddr, UINT64 *rootSize, UINT32 *mountFlags) +{ + INT32 ret; + CHAR *rootAddrStr = NULL; + CHAR *rootSizeStr = NULL; + CHAR *rwTag = NULL; + + ret = LOS_GetArgValue("root", dev); + if (ret != LOS_OK) { + PRINT_ERR("Cannot find root!"); + return ret; + } + + ret = LOS_GetArgValue("fstype", fstype); + if (ret != LOS_OK) { + PRINT_ERR("Cannot find fstype!"); + return ret; + } + + ret = LOS_GetArgValue("rootaddr", &rootAddrStr); + if (ret != LOS_OK) { + *rootAddr = ROOTFS_ADDR; + } else { + *rootAddr = LOS_SizeStrToNum(rootAddrStr); + } + + ret = LOS_GetArgValue("rootsize", &rootSizeStr); + if (ret != LOS_OK) { + *rootSize = ROOTFS_SIZE; + } else { + *rootSize = LOS_SizeStrToNum(rootSizeStr); + } + + ret = LOS_GetArgValue("ro", &rwTag); + if (ret == LOS_OK) { + *mountFlags = MS_RDONLY; + } else { + *mountFlags = 0; + } + + return LOS_OK; +} + +STATIC INT32 ParseUserArgs(UINT64 rootAddr, UINT64 rootSize, UINT64 *userAddr, UINT64 *userSize) +{ + INT32 ret; + CHAR *userAddrStr = NULL; + CHAR *userSizeStr = NULL; + + ret = LOS_GetArgValue("useraddr", &userAddrStr); + if (ret != LOS_OK) { + *userAddr = rootAddr + rootSize; + } else { + *userAddr = LOS_SizeStrToNum(userAddrStr); + } + + ret = LOS_GetArgValue("usersize", &userSizeStr); + if (ret != LOS_OK) { + *userSize = USERFS_SIZE; + } else { + *userSize = LOS_SizeStrToNum(userSizeStr); + } + + return LOS_OK; +} + +STATIC INT32 MountPartitions(CHAR *fsType, UINT32 mountFlags) +{ + INT32 ret; + INT32 err; + + /* Mount rootfs */ + ret = mount(ROOT_DEV_NAME, ROOT_DIR_NAME, fsType, mountFlags, NULL); + if (ret != LOS_OK) { + err = get_errno(); + PRINT_ERR("Failed to mount %s, rootDev %s, errno %d: %s\n", ROOT_DIR_NAME, ROOT_DEV_NAME, err, strerror(err)); + return ret; + } + +#ifdef LOSCFG_STORAGE_EMMC +#ifdef LOSCFG_PLATFORM_PATCHFS + /* Mount patch */ + ret = mkdir(PATCH_DIR_NAME, DEFAULT_MOUNT_DIR_MODE); + if ((ret != LOS_OK) && ((err = get_errno()) != EEXIST)) { + PRINT_ERR("Failed to mkdir %s, errno %d: %s\n", PATCH_DIR_NAME, err, strerror(err)); + return ret; + } + + ret = mount(PATCH_DEV_NAME, PATCH_DIR_NAME, fsType, 0, DEFAULT_MOUNT_DATA); + if ((ret != LOS_OK) && ((err = get_errno()) == ENOTSUP)) { + ret = format(PATCH_DEV_NAME, 0, FM_FAT32); + if (ret != LOS_OK) { + PRINT_ERR("Failed to format %s\n", PATCH_DEV_NAME); + return ret; + } + + ret = mount(PATCH_DEV_NAME, PATCH_DIR_NAME, fsType, 0, DEFAULT_MOUNT_DATA); + if (ret != LOS_OK) { + err = get_errno(); + } + } + if (ret != LOS_OK) { + PRINT_ERR("Failed to mount %s, errno %d: %s\n", PATCH_DIR_NAME, err, strerror(err)); + return ret; + } +#endif +#endif + + /* Mount userfs */ + ret = mkdir(STORAGE_DIR_NAME, DEFAULT_MOUNT_DIR_MODE); + if ((ret != LOS_OK) && ((err = get_errno()) != EEXIST)) { + PRINT_ERR("Failed to mkdir %s, errno %d: %s\n", STORAGE_DIR_NAME, err, strerror(err)); + return ret; + } + + ret = mount(USER_DEV_NAME, STORAGE_DIR_NAME, fsType, 0, DEFAULT_MOUNT_DATA); + if (ret != LOS_OK) { + err = get_errno(); + PRINT_ERR("Failed to mount %s, errno %d: %s\n", STORAGE_DIR_NAME, err, strerror(err)); + return ret; + } + +#ifdef LOSCFG_STORAGE_EMMC + /* Mount userdata */ + ret = mkdir(USERDATA_DIR_NAME, DEFAULT_MOUNT_DIR_MODE); + if ((ret != LOS_OK) && ((err = get_errno()) != EEXIST)) { + PRINT_ERR("Failed to mkdir %s, errno %d: %s\n", USERDATA_DIR_NAME, err, strerror(err)); + return ret; + } + + ret = mount(USERDATA_DEV_NAME, USERDATA_DIR_NAME, fsType, 0, DEFAULT_MOUNT_DATA); + if ((ret != LOS_OK) && ((err = get_errno()) == ENOTSUP)) { + ret = format(USERDATA_DEV_NAME, 0, FM_FAT32); + if (ret != LOS_OK) { + PRINT_ERR("Failed to format %s\n", USERDATA_DEV_NAME); + return ret; + } + + ret = mount(USERDATA_DEV_NAME, USERDATA_DIR_NAME, fsType, 0, DEFAULT_MOUNT_DATA); + if (ret != LOS_OK) { + err = get_errno(); + } + } + if (ret != LOS_OK) { + PRINT_ERR("Failed to mount %s, errno %d: %s\n", USERDATA_DIR_NAME, err, strerror(err)); + return ret; + } +#endif + return LOS_OK; +} + +STATIC INT32 CheckValidation(UINT64 rootAddr, UINT64 rootSize, UINT64 userAddr, UINT64 userSize) +{ + UINT64 alignSize = LOS_GetAlignsize(); + if (alignSize == 0) { + return LOS_OK; + } + + if ((rootAddr & (alignSize - 1)) || (rootSize & (alignSize - 1)) || + (userAddr & (alignSize - 1)) || (userSize & (alignSize - 1))) { + PRINT_ERR("The address or size value should be 0x%llx aligned!\n", alignSize); + return LOS_NOK; + } + + return LOS_OK; +} + +INT32 OsMountRootfs() +{ + INT32 ret; + CHAR *dev = NULL; + CHAR *fstype = NULL; + UINT64 rootAddr; + UINT64 rootSize; + UINT64 userAddr; + UINT64 userSize; + UINT32 mountFlags; + + ret = ParseRootArgs(&dev, &fstype, &rootAddr, &rootSize, &mountFlags); + if (ret != LOS_OK) { + return ret; + } + + ret = ParseUserArgs(rootAddr, rootSize, &userAddr, &userSize); + if (ret != LOS_OK) { + return ret; + } + + ret = CheckValidation(rootAddr, rootSize, userAddr, userSize); + if (ret != LOS_OK) { + return ret; + } + + ret = AddPartitions(dev, rootAddr, rootSize, userAddr, userSize); + if (ret != LOS_OK) { + return ret; + } + + ret = MountPartitions(fstype, mountFlags); + if (ret != LOS_OK) { + return ret; + } + + return LOS_OK; +} diff --git a/src/kernel_liteos_a/fs/rootfs/los_rootfs.h b/src/kernel_liteos_a/fs/rootfs/los_rootfs.h new file mode 100644 index 00000000..ec12869c --- /dev/null +++ b/src/kernel_liteos_a/fs/rootfs/los_rootfs.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_ROOTFS_H +#define _LOS_ROOTFS_H + +#include "los_typedef.h" + +#define ROOT_DIR_NAME "/" +#define STORAGE_DIR_NAME "/storage" +#ifdef LOSCFG_STORAGE_EMMC +#define USERDATA_DIR_NAME "/userdata" +#ifdef LOSCFG_PLATFORM_PATCHFS +#define PATCH_DIR_NAME "/patch" +#endif +#endif +#define DEFAULT_MOUNT_DIR_MODE 0755 +#define DEFAULT_MOUNT_DATA NULL + +#ifdef LOSCFG_STORAGE_SPINOR +#define FLASH_TYPE "spinor" +#define ROOT_DEV_NAME "/dev/spinorblk0" +#define USER_DEV_NAME "/dev/spinorblk2" +#define ROOTFS_ADDR 0x600000 +#define ROOTFS_SIZE 0x800000 +#define USERFS_SIZE 0x80000 +#elif defined (LOSCFG_STORAGE_SPINAND) +#define FLASH_TYPE "nand" +#define ROOT_DEV_NAME "/dev/nandblk0" +#define USER_DEV_NAME "/dev/nandblk2" +#define ROOTFS_ADDR 0x600000 +#define ROOTFS_SIZE 0x800000 +#define USERFS_SIZE 0x80000 +#elif defined (LOSCFG_STORAGE_EMMC) +#define ROOT_DEV_NAME "/dev/mmcblk0p0" +#ifdef LOSCFG_PLATFORM_PATCHFS +#define PATCH_DEV_NAME "/dev/mmcblk0p1" +#define USER_DEV_NAME "/dev/mmcblk0p2" +#define USERDATA_DEV_NAME "/dev/mmcblk0p3" +#else +#define USER_DEV_NAME "/dev/mmcblk0p1" +#define USERDATA_DEV_NAME "/dev/mmcblk0p2" +#endif +#define ROOTFS_ADDR 0xA00000 +#define ROOTFS_SIZE 0x1400000 +#define USERFS_SIZE 0x3200000 +#ifdef LOSCFG_PLATFORM_PATCHFS +#define PATCH_SIZE 0x200000 +#endif +#ifdef DEFAULT_MOUNT_DIR_MODE +#undef DEFAULT_MOUNT_DIR_MODE +#endif +#ifdef DEFAULT_MOUNT_DATA +#undef DEFAULT_MOUNT_DATA +#endif +#define DEFAULT_MOUNT_DIR_MODE 0777 +#define DEFAULT_MOUNT_DATA "umask=000" +#endif + +INT32 OsMountRootfs(VOID); + +#endif /* _LOS_ROOTFS_H */ diff --git a/src/kernel_liteos_a/fs/vfs/BUILD.gn b/src/kernel_liteos_a/fs/vfs/BUILD.gn new file mode 100644 index 00000000..96c181d1 --- /dev/null +++ b/src/kernel_liteos_a/fs/vfs/BUILD.gn @@ -0,0 +1,75 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") +import("$THIRDPARTY_NUTTX_DIR/NuttX.gni") + +module_switch = defined(LOSCFG_FS_VFS) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ + "epoll/fs_epoll.c", + "mount.c", + "operation/fullpath.c", + "operation/vfs_chattr.c", + "operation/vfs_check.c", + "operation/vfs_cloexec.c", + "operation/vfs_fallocate.c", + "operation/vfs_fallocate64.c", + "operation/vfs_fcntl.c", + "operation/vfs_force_umount.c", + "operation/vfs_init.c", + "operation/vfs_other.c", + "operation/vfs_preadv.c", + "operation/vfs_procfd.c", + "operation/vfs_pwritev.c", + "operation/vfs_readv.c", + "operation/vfs_utime.c", + "operation/vfs_writev.c", + "path_cache.c", + "vfs_cmd/vfs_shellcmd.c", + "vnode.c", + "vnode_hash.c", + ] + sources += NUTTX_FS_DIRENT_SRC_FILES + sources += NUTTX_FS_DRIVER_SRC_FILES + sources += NUTTX_FS_INODE_SRC_FILES + sources += NUTTX_FS_MOUNT_SRC_FILES + sources += NUTTX_FS_VFS_SRC_FILES + + include_dirs = [ + "$LITEOSTOPDIR/syscall", + "$LITEOSTOPDIR/fs/zpfs/include", + ] + public_configs = [ ":public" ] +} + +config("public") { + include_dirs = [ "include" ] +} diff --git a/src/kernel_liteos_a/fs/vfs/Kconfig b/src/kernel_liteos_a/fs/vfs/Kconfig new file mode 100644 index 00000000..d81e15cd --- /dev/null +++ b/src/kernel_liteos_a/fs/vfs/Kconfig @@ -0,0 +1,43 @@ +config FS_VFS + bool "Enable VFS" + default y + + help + Answer Y to enable LiteOS support virtual filesystem. + +config FS_VFS_BLOCK_DEVICE + bool "Enable Block DEVICE" + default n + depends on FS_VFS + help + Answer Y to enable LiteOS support read/open/seek/write block device. + +config FILE_MODE + bool "Enable FILE MODE" + default y + depends on FS_VFS + help + Answer Y to enable LiteOS support file mode. + +config ENABLE_READ_BUFFER + bool "Enable read buffer Option" + default n + depends on FS_VFS + help + Answer Y to add enable read buffer Option. + +config MAX_VNODE_SIZE + int "Vnode max number" + range 0 512 + default 512 + depends on FS_VFS + help + vnode number, range from 0 to 512. + +config MAX_PATH_CACHE_SIZE + int "PathCache max number" + range 0 1024 + default 512 + depends on FS_VFS + help + pathCache number, range from 0 to 1024. \ No newline at end of file diff --git a/src/kernel_liteos_a/fs/vfs/Makefile b/src/kernel_liteos_a/fs/vfs/Makefile new file mode 100644 index 00000000..9fcfc33a --- /dev/null +++ b/src/kernel_liteos_a/fs/vfs/Makefile @@ -0,0 +1,105 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) +LOCAL_SRCS := \ +$(LITEOSTOPDIR)/fs/vfs/mount.c \ +$(LITEOSTOPDIR)/fs/vfs/vnode.c \ +$(LITEOSTOPDIR)/fs/vfs/path_cache.c \ +$(LITEOSTOPDIR)/fs/vfs/vnode_hash.c \ +$(LITEOSTOPDIR)/fs/vfs/epoll/fs_epoll.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/vfs/fs_close.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/vfs/fs_dup2.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/vfs/fs_dup.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/vfs/fs_dupfd2.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/vfs/fs_dupfd.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/vfs/fs_fcntl.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/vfs/fs_fsync.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/vfs/fs_getfilep.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/vfs/fs_ioctl.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/vfs/fs_lseek.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/vfs/fs_lseek64.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/vfs/fs_mkdir.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/vfs/fs_open.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/vfs/fs_poll.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/vfs/fs_pread.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/vfs/fs_pread64.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/vfs/fs_pwrite.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/vfs/fs_pwrite64.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/vfs/fs_read.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/vfs/fs_rename.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/vfs/fs_rmdir.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/vfs/fs_select.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/vfs/fs_sendfile.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/vfs/fs_stat.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/vfs/fs_statfs.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/vfs/fs_truncate.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/vfs/fs_truncate64.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/vfs/fs_unlink.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/vfs/fs_link.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/vfs/fs_readlink.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/vfs/fs_symlink.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/vfs/fs_write.c \ +$(wildcard operation/*.c) \ +\ +$(LITEOSTHIRDPARTY)/NuttX/fs/inode/fs_files.c \ +\ +$(LITEOSTHIRDPARTY)/NuttX/fs/dirent/fs_closedir.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/dirent/fs_opendir.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/dirent/fs_readdir.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/dirent/fs_rewinddir.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/dirent/fs_seekdir.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/dirent/fs_telldir.c \ +\ +$(LITEOSTHIRDPARTY)/NuttX/fs/mount/fs_mount.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/mount/fs_umount.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/mount/fs_sync.c \ +\ +$(LITEOSTHIRDPARTY)/NuttX/fs/driver/fs_blockproxy.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/mount/fs_foreachmountpoint.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/driver/fs_findblockdriver.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/driver/fs_openblockdriver.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/driver/fs_closeblockdriver.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/driver/fs_registerblockdriver.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/driver/fs_registerdriver.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/driver/fs_unregisterblockdriver.c \ +$(LITEOSTHIRDPARTY)/NuttX/fs/driver/fs_unregisterdriver.c \ +\ +$(wildcard vfs_cmd/*.c) + +LOCAL_INCLUDE := \ + -I $(LITEOSTOPDIR)/drivers/char/bch/include\ + -I $(LITEOSTOPDIR)/syscall\ + -I $(LITEOSTOPDIR)/fs/zpfs/include + +LOCAL_FLAGS := $(LOCAL_INCLUDE) + +include $(MODULE) diff --git a/src/kernel_liteos_a/fs/vfs/bcache/BUILD.gn b/src/kernel_liteos_a/fs/vfs/bcache/BUILD.gn new file mode 100644 index 00000000..6f52a9bc --- /dev/null +++ b/src/kernel_liteos_a/fs/vfs/bcache/BUILD.gn @@ -0,0 +1,42 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = defined(LOSCFG_FS_FAT_CACHE) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ "src/bcache.c" ] + + public_configs = [ ":public" ] +} + +config("public") { + include_dirs = [ "../include/bcache" ] +} diff --git a/src/kernel_liteos_a/fs/vfs/bcache/Makefile b/src/kernel_liteos_a/fs/vfs/bcache/Makefile new file mode 100644 index 00000000..01e51cb4 --- /dev/null +++ b/src/kernel_liteos_a/fs/vfs/bcache/Makefile @@ -0,0 +1,37 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := $(wildcard src/*.c) + +include $(MODULE) + diff --git a/src/kernel_liteos_a/fs/vfs/bcache/src/bcache.c b/src/kernel_liteos_a/fs/vfs/bcache/src/bcache.c new file mode 100644 index 00000000..4c1e0732 --- /dev/null +++ b/src/kernel_liteos_a/fs/vfs/bcache/src/bcache.c @@ -0,0 +1,1228 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "bcache.h" +#include "assert.h" +#include "stdlib.h" +#include "linux/delay.h" +#include "disk_pri.h" +#include "user_copy.h" + +#undef HALARC_ALIGNMENT +#define DMA_ALLGN 64 +#define HALARC_ALIGNMENT DMA_ALLGN +#define BCACHE_MAGIC_NUM 20132016 +#define BCACHE_STATCK_SIZE 0x3000 +#define ASYNC_EVENT_BIT 0x01 + +#ifdef DEBUG +#define D(args) printf args +#else +#define D(args) +#endif + +#ifdef BCACHE_ANALYSE +UINT32 g_memSize; +volatile UINT32 g_blockNum; +volatile UINT32 g_dataSize; +volatile UINT8 *g_memStart; +volatile UINT32 g_switchTimes[CONFIG_FS_FAT_BLOCK_NUMS] = { 0 }; +volatile UINT32 g_hitTimes[CONFIG_FS_FAT_BLOCK_NUMS] = { 0 }; +#endif + +VOID BcacheAnalyse(UINT32 level) +{ + (VOID)level; +#ifdef BCACHE_ANALYSE + int i; + + PRINTK("Bcache information:\n"); + PRINTK(" mem: %u\n", g_memSize); + PRINTK(" block number: %u\n", g_blockNum); + PRINTK("index, switch, hit\n"); + for (i = 0; i < g_blockNum; i++) { + PRINTK("%5d, %6d, %3d\n", i, g_switchTimes[i], g_hitTimes[i]); + } +#else + PRINTK("Bcache hasn't started\n"); +#endif +} + +#ifdef LOSCFG_FS_FAT_CACHE_SYNC_THREAD + +UINT32 g_syncThreadPrio = CONFIG_FS_FAT_SYNC_THREAD_PRIO; +UINT32 g_dirtyRatio = CONFIG_FS_FAT_DIRTY_RATIO; +UINT32 g_syncInterval = CONFIG_FS_FAT_SYNC_INTERVAL; + +VOID LOS_SetDirtyRatioThreshold(UINT32 dirtyRatio) +{ + if ((dirtyRatio != g_dirtyRatio) && (dirtyRatio <= 100)) { /* The ratio cannot exceed 100% */ + g_dirtyRatio = dirtyRatio; + } +} + +VOID LOS_SetSyncThreadInterval(UINT32 interval) +{ + g_syncInterval = interval; +} + +INT32 LOS_SetSyncThreadPrio(UINT32 prio, const CHAR *name) +{ + INT32 ret = VFS_ERROR; + INT32 diskID; + los_disk *disk = NULL; + if ((prio == 0) || (prio >= OS_TASK_PRIORITY_LOWEST)) { /* The priority can not be zero */ + return ret; + } + + g_syncThreadPrio = prio; + + /* + * If the name is NULL, it only sets the value of a global variable, + * and takes effect the next time the thread is created. + */ + if (name == NULL) { + return ENOERR; + } + + /* If the name is not NULL, it shall return an error if can't find the disk corresponding to name. */ + diskID = los_get_diskid_byname(name); + disk = get_disk(diskID); + if (disk == NULL) { + return ret; + } + + if (pthread_mutex_lock(&disk->disk_mutex) != ENOERR) { + PRINT_ERR("%s %d, mutex lock fail!\n", __FUNCTION__, __LINE__); + return ret; + } + if ((disk->disk_status == STAT_INUSED) && (disk->bcache != NULL)) { + ret = LOS_TaskPriSet(disk->bcache->syncTaskId, prio); + } + if (pthread_mutex_unlock(&disk->disk_mutex) != ENOERR) { + PRINT_ERR("%s %d, mutex unlock fail!\n", __FUNCTION__, __LINE__); + return VFS_ERROR; + } + return ret; +} +#endif + +static OsBcacheBlock *RbFindBlock(const OsBcache *bc, UINT64 num) +{ + OsBcacheBlock *block = NULL; + struct rb_node *node = bc->rbRoot.rb_node; + + for (; node != NULL; node = (block->num < num) ? node->rb_right : node->rb_left) { + block = rb_entry(node, OsBcacheBlock, rbNode); + if (block->num == num) { + return block; + } + } + return NULL; +} + +static VOID RbAddBlock(OsBcache *bc, OsBcacheBlock *block) +{ + struct rb_node *node = bc->rbRoot.rb_node; + struct rb_node **link = NULL; + OsBcacheBlock *b = NULL; + + if (node == NULL) { + rb_link_node(&block->rbNode, NULL, &bc->rbRoot.rb_node); + } else { + for (; node != NULL; link = (b->num > block->num) ? &node->rb_left : &node->rb_right, node = *link) { + b = rb_entry(node, OsBcacheBlock, rbNode); + if (b->num == block->num) { + PRINT_ERR("RbAddBlock fail, b->num = %llu, block->num = %llu\n", b->num, block->num); + return; + } + } + rb_link_node(&block->rbNode, &b->rbNode, link); + } + rb_insert_color(&block->rbNode, &bc->rbRoot); +} + +static inline VOID RbDelBlock(OsBcache *bc, OsBcacheBlock *block) +{ + rb_erase(&block->rbNode, &bc->rbRoot); +} + +static inline VOID ListMoveBlockToHead(OsBcache *bc, OsBcacheBlock *block) +{ + LOS_ListDelete(&block->listNode); + LOS_ListAdd(&bc->listHead, &block->listNode); +} + +static inline VOID FreeBlock(OsBcache *bc, OsBcacheBlock *block) +{ + block->used = FALSE; + LOS_ListAdd(&bc->freeListHead, &block->listNode); +} + +static UINT32 GetValLog2(UINT32 val) +{ + UINT32 i, log2; + + i = val; + log2 = 0; + while ((i & 1) == 0) { /* Check if the last bit is 1 */ + i >>= 1; + log2++; + } + if (i != 1) { /* Not the power of 2 */ + return 0; + } + + return log2; +} + +static INT32 FindFlagPos(const UINT32 *arr, UINT32 len, UINT32 *p1, UINT32 *p2) +{ + UINT32 *start = p1; + UINT32 *end = p2; + UINT32 i, j, tmp; + UINT32 val = 1; + + *start = BCACHE_MAGIC_NUM; + *end = 0; + for (i = 0; i < len; i++) { + for (j = 0; j < UNSIGNED_INTEGER_BITS; j++) { + tmp = arr[i] << j; + tmp = tmp >> UNINT_MAX_SHIFT_BITS; + if (tmp != val) { + continue; + } + if (val && (*start == BCACHE_MAGIC_NUM)) { + *start = (i << UNINT_LOG2_SHIFT) + j; + val = 1 - val; /* Control parity by 0 and 1 */ + } else if (val && (*start != BCACHE_MAGIC_NUM)) { + *start = 0; + return VFS_ERROR; + } else { + *end = (i << UNINT_LOG2_SHIFT) + j; + val = 1 - val; /* Control parity by 0 and 1 */ + } + } + } + if (*start == BCACHE_MAGIC_NUM) { + *start = 0; + return VFS_ERROR; + } + if (*end == 0) { + *end = len << UNINT_LOG2_SHIFT; + } + + return ENOERR; +} + +static INT32 BlockRead(OsBcache *bc, OsBcacheBlock *block, UINT8 *buf) +{ + INT32 ret = bc->breadFun(bc->priv, buf, bc->sectorPerBlock, + (block->num) << GetValLog2(bc->sectorPerBlock)); + if (ret) { + PRINT_ERR("BlockRead, brread_fn error, ret = %d\n", ret); + if (block->modified == FALSE) { + if (block->listNode.pstNext != NULL) { + LOS_ListDelete(&block->listNode); /* list del block */ + RbDelBlock(bc, block); + } + FreeBlock(bc, block); + } + return ret; + } + + block->readFlag = TRUE; + return ENOERR; +} + +static INT32 BcacheGetFlag(OsBcache *bc, OsBcacheBlock *block) +{ + UINT32 i, n, f, sectorPos, val, start, pos, currentSize; + UINT32 flagUse = bc->sectorPerBlock >> UNINT_LOG2_SHIFT; + UINT32 flag = UINT_MAX; + INT32 ret, bits; + + if (block->readFlag == TRUE) { + return ENOERR; + } + + for (i = 0; i < flagUse; i++) { + flag &= block->flag[i]; + } + + if (flag == UINT_MAX) { + return ENOERR; + } + + ret = BlockRead(bc, block, bc->rwBuffer); + if (ret != ENOERR) { + return ret; + } + + for (i = 0, sectorPos = 0; i < flagUse; i++) { + val = block->flag[i]; + /* use unsigned integer for bit map */ + for (f = 0, bits = UNSIGNED_INTEGER_BITS; bits > 0; val = ~(val << n), f++, bits = bits - (INT32)n) { + if (val == 0) { + n = UNSIGNED_INTEGER_BITS; + } else { + n = (UINT32)CLZ(val); + } + sectorPos += n; + if (((f % EVEN_JUDGED) != 0) || (n == 0)) { /* Number of leading zeros of n is zero */ + goto LOOP; + } + if (sectorPos > ((i + 1) << UNINT_LOG2_SHIFT)) { + start = sectorPos - n; + currentSize = (((i + 1) << UNINT_LOG2_SHIFT) - start) * bc->sectorSize; + } else { + start = sectorPos - n; + currentSize = n * bc->sectorSize; + } + pos = start * bc->sectorSize; + if (memcpy_s(block->data + pos, bc->blockSize - pos, bc->rwBuffer + pos, currentSize) != EOK) { + return VFS_ERROR; + } +LOOP: + if (sectorPos > ((i + 1) << UNINT_LOG2_SHIFT)) { + sectorPos = (i + 1) << UNINT_LOG2_SHIFT; + } + } + } + + return ENOERR; +} + +static VOID BcacheSetFlag(const OsBcache *bc, OsBcacheBlock *block, UINT32 pos, UINT32 size) +{ + UINT32 start, num, i, j, k; + + if (bc->sectorSize == 0) { + PRINT_ERR("BcacheSetFlag sectorSize is equal to zero! \n"); + return; + } + + start = pos / bc->sectorSize; + num = size / bc->sectorSize; + + i = start / UNSIGNED_INTEGER_BITS; + j = start % UNSIGNED_INTEGER_BITS; + for (k = 0; k < num; k++) { + block->flag[i] |= 1u << (UNINT_MAX_SHIFT_BITS - j); + j++; + if (j == UNSIGNED_INTEGER_BITS) { + j = 0; + i++; + } + } +} + +static INT32 BcacheSyncBlock(OsBcache *bc, OsBcacheBlock *block) +{ + INT32 ret = ENOERR; + UINT32 len, start, end; + + if (block->modified == TRUE) { + D(("bcache writing block = %llu\n", block->num)); + + ret = FindFlagPos(block->flag, bc->sectorPerBlock >> UNINT_LOG2_SHIFT, &start, &end); + if (ret == ENOERR) { + len = end - start; + } else { + ret = BcacheGetFlag(bc, block); + if (ret != ENOERR) { + return ret; + } + + len = bc->sectorPerBlock; + } + + ret = bc->bwriteFun(bc->priv, (const UINT8 *)(block->data + (start * bc->sectorSize)), + len, (block->num * bc->sectorPerBlock) + start); + if (ret == ENOERR) { + block->modified = FALSE; + bc->modifiedBlock--; + } else { + PRINT_ERR("BcacheSyncBlock fail, ret = %d, len = %u, block->num = %llu, start = %u\n", + ret, len, block->num, start); + } + } + return ret; +} + +static void NumListAdd(OsBcache *bc, OsBcacheBlock *block) +{ + OsBcacheBlock *temp = NULL; + + LOS_DL_LIST_FOR_EACH_ENTRY(temp, &bc->numHead, OsBcacheBlock, numNode) { + if (temp->num > block->num) { + LOS_ListTailInsert(&temp->numNode, &block->numNode); + return; + } + } + + LOS_ListTailInsert(&bc->numHead, &block->numNode); +} + +static void AddBlock(OsBcache *bc, OsBcacheBlock *block) +{ + RbAddBlock(bc, block); + NumListAdd(bc, block); + bc->sumNum += block->num; + bc->nBlock++; + LOS_ListAdd(&bc->listHead, &block->listNode); +} + +static void DelBlock(OsBcache *bc, OsBcacheBlock *block) +{ + LOS_ListDelete(&block->listNode); /* lru list del */ + LOS_ListDelete(&block->numNode); /* num list del */ + bc->sumNum -= block->num; + bc->nBlock--; + RbDelBlock(bc, block); /* rb tree del */ + FreeBlock(bc, block); /* free list add */ +} + +static BOOL BlockAllDirty(const OsBcache *bc, OsBcacheBlock *block) +{ + UINT32 start = 0; + UINT32 end = 0; + UINT32 len = bc->sectorPerBlock >> UNINT_LOG2_SHIFT; + + if (block->modified == TRUE) { + if (block->allDirty) { + return TRUE; + } + + if (FindFlagPos(block->flag, len, &start, &end) == ENOERR) { + if ((end - start) == bc->sectorPerBlock) { + block->allDirty = TRUE; + return TRUE; + } + } + } + + return FALSE; +} + +static OsBcacheBlock *GetBaseBlock(OsBcache *bc) +{ + OsBcacheBlock *base = bc->wStart; + OsBcacheBlock *end = bc->wEnd; + while (base < end) { + if (base->used == FALSE) { + base->used = TRUE; + LOS_ListDelete(&base->listNode); + return base; + } + base++; + } + + return NULL; +} + +/* try get free block first, if failed free a useless block */ +static OsBcacheBlock *GetSlowBlock(OsBcache *bc, BOOL read) +{ + LOS_DL_LIST *node = NULL; + OsBcacheBlock *block = NULL; + + LOS_DL_LIST_FOR_EACH_ENTRY(block, &bc->freeListHead, OsBcacheBlock, listNode) { + if (block->readBuff == read) { + block->used = TRUE; + LOS_ListDelete(&block->listNode); + return block; /* get free one */ + } + } + + node = bc->listHead.pstPrev; + while (node != &bc->listHead) { + block = LOS_DL_LIST_ENTRY(node, OsBcacheBlock, listNode); + node = block->listNode.pstPrev; + + if (block->readBuff == read) { + if (block->modified == TRUE) { + BcacheSyncBlock(bc, block); + } + + DelBlock(bc, block); + block->used = TRUE; + LOS_ListDelete(&block->listNode); + return block; /* get used one */ + } + } + + return NULL; +} + +/* flush combined blocks */ +static VOID WriteMergedBlocks(OsBcache *bc, OsBcacheBlock *begin, int blocks) +{ + INT32 ret; + OsBcacheBlock *cur = NULL; + OsBcacheBlock *next = NULL; + UINT32 len = blocks * bc->sectorPerBlock; + UINT64 pos = begin->num * bc->sectorPerBlock; + + ret = bc->bwriteFun(bc->priv, (const UINT8 *)begin->data, len, pos); + if (ret != ENOERR) { + PRINT_ERR("WriteMergedBlocks bwriteFun failed ret %d\n", ret); + return; + } + + bc->modifiedBlock -= blocks; + cur = begin; + while (blocks > 0) { + next = LOS_DL_LIST_ENTRY(cur->numNode.pstNext, OsBcacheBlock, numNode); + DelBlock(bc, cur); + cur->modified = FALSE; + blocks--; + cur = next; + } +} + +/* find continue blocks and flush them */ +static VOID MergeSyncBlocks(OsBcache *bc, OsBcacheBlock *start) +{ + INT32 mergedBlock = 0; + OsBcacheBlock *cur = start; + OsBcacheBlock *last = NULL; + + while (cur <= bc->wEnd) { + if (!cur->used || !BlockAllDirty(bc, cur)) { + break; + } + + if (last && (last->num + 1 != cur->num)) { + break; + } + + mergedBlock++; + last = cur; + cur++; + } + + if (mergedBlock > 0) { + WriteMergedBlocks(bc, start, mergedBlock); + } +} + +/* get the min write block num of block cache buffer */ +static inline UINT64 GetMinWriteNum(OsBcache *bc) +{ + UINT64 ret = 0; + OsBcacheBlock *block = NULL; + + LOS_DL_LIST_FOR_EACH_ENTRY(block, &bc->numHead, OsBcacheBlock, numNode) { + if (!block->readBuff) { + ret = block->num; + break; + } + } + + return ret; +} + +static OsBcacheBlock *AllocNewBlock(OsBcache *bc, BOOL read, UINT64 num) +{ + OsBcacheBlock *last = NULL; + OsBcacheBlock *prefer = NULL; + + if (read) { /* read */ + return GetSlowBlock(bc, TRUE); + } + + /* fallback, this may happen when the block previously flushed, use read buffer */ + if (bc->nBlock && num < GetMinWriteNum(bc)) { + return GetSlowBlock(bc, TRUE); + } + + last = RbFindBlock(bc, num - 1); /* num=0 is ok */ + if (last == NULL || last->readBuff) { + return GetBaseBlock(bc); /* new block */ + } + + prefer = last + 1; + if (prefer > bc->wEnd) { + prefer = bc->wStart; + } + + /* this is a sync thread synced block! */ + if (prefer->used && !prefer->modified) { + prefer->used = FALSE; + DelBlock(bc, prefer); + } + + if (prefer->used) { /* do not combine with next check */ + MergeSyncBlocks(bc, prefer); /* prefer->used may be changed here */ + } + + if (prefer->used) { + BcacheSyncBlock(bc, prefer); + DelBlock(bc, prefer); + } + + prefer->used = TRUE; + LOS_ListDelete(&prefer->listNode); /* del from free list */ + + return prefer; +} + +static INT32 BcacheSync(OsBcache *bc) +{ + LOS_DL_LIST *node = NULL; + OsBcacheBlock *block = NULL; + INT32 ret = ENOERR; + + D(("bcache cache sync\n")); + + (VOID)pthread_mutex_lock(&bc->bcacheMutex); + node = bc->listHead.pstPrev; + while (&bc->listHead != node) { + block = LOS_DL_LIST_ENTRY(node, OsBcacheBlock, listNode); + ret = BcacheSyncBlock(bc, block); + if (ret != ENOERR) { + PRINT_ERR("BcacheSync error, ret = %d\n", ret); + break; + } + node = node->pstPrev; + } + (VOID)pthread_mutex_unlock(&bc->bcacheMutex); + + return ret; +} + +static VOID BlockInit(OsBcache *bc, OsBcacheBlock *block, UINT64 num) +{ + (VOID)memset_s(block->flag, sizeof(block->flag), 0, sizeof(block->flag)); + block->num = num; + block->readFlag = FALSE; + if (block->modified == TRUE) { + block->modified = FALSE; + bc->modifiedBlock--; + } + block->allDirty = FALSE; +} + +static INT32 BcacheGetBlock(OsBcache *bc, UINT64 num, BOOL readData, OsBcacheBlock **dblock) +{ + INT32 ret; + OsBcacheBlock *block = NULL; + OsBcacheBlock *first = NULL; + + /* + * First check if the most recently used block is the requested block, + * this can improve performance when using byte access functions. + */ + if (LOS_ListEmpty(&bc->listHead) == FALSE) { + first = LOS_DL_LIST_ENTRY(bc->listHead.pstNext, OsBcacheBlock, listNode); + block = (first->num == num) ? first : RbFindBlock(bc, num); + } + + if (block != NULL) { + D(("bcache block = %llu found in cache\n", num)); +#ifdef BCACHE_ANALYSE + UINT32 index = ((UINT32)(block->data - g_memStart)) / g_dataSize; + PRINTK(", [HIT], %llu, %u\n", num, index); + g_hitTimes[index]++; +#endif + + if (first != block) { + ListMoveBlockToHead(bc, block); + } + *dblock = block; + + if ((bc->prereadFun != NULL) && (readData == TRUE) && (block->pgHit == 1)) { + block->pgHit = 0; + bc->prereadFun(bc, block); + } + + return ENOERR; + } + + D(("bcache block = %llu NOT found in cache\n", num)); + + block = AllocNewBlock(bc, readData, num); + if (block == NULL) { + block = GetSlowBlock(bc, readData); + } + + if (block == NULL) { + return -ENOMEM; + } +#ifdef BCACHE_ANALYSE + UINT32 index = ((UINT32)(block->data - g_memStart)) / g_dataSize; + PRINTK(", [MISS], %llu, %u\n", num, index); + g_switchTimes[index]++; +#endif + BlockInit(bc, block, num); + + if (readData == TRUE) { + D(("bcache reading block = %llu\n", block->num)); + + ret = BlockRead(bc, block, block->data); + if (ret != ENOERR) { + return ret; + } + if (bc->prereadFun != NULL) { + bc->prereadFun(bc, block); + } + } + + AddBlock(bc, block); + + *dblock = block; + return ENOERR; +} + +INT32 BcacheClearCache(OsBcache *bc) +{ + OsBcacheBlock *block = NULL; + OsBcacheBlock *next = NULL; + LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(block, next, &bc->listHead, OsBcacheBlock, listNode) { + DelBlock(bc, block); + } + return 0; +} + +static INT32 BcacheInitCache(OsBcache *bc, + UINT8 *memStart, + UINT32 memSize, + UINT32 blockSize) +{ + UINT8 *blockMem = NULL; + UINT8 *dataMem = NULL; + OsBcacheBlock *block = NULL; + UINT32 blockNum, i; + + LOS_ListInit(&bc->listHead); + LOS_ListInit(&bc->numHead); + bc->sumNum = 0; + bc->nBlock = 0; + + if (!GetValLog2(blockSize)) { + PRINT_ERR("GetValLog2(%u) return 0.\n", blockSize); + return -EINVAL; + } + + bc->rbRoot.rb_node = NULL; + bc->memStart = memStart; + bc->blockSize = blockSize; + bc->blockSizeLog2 = GetValLog2(blockSize); + bc->modifiedBlock = 0; + + /* init block memory pool */ + LOS_ListInit(&bc->freeListHead); + + blockNum = (memSize - DMA_ALLGN) / (sizeof(OsBcacheBlock) + bc->blockSize); + blockMem = bc->memStart; + dataMem = blockMem + (sizeof(OsBcacheBlock) * blockNum); + dataMem += ALIGN_DISP((UINTPTR)dataMem); + +#ifdef BCACHE_ANALYSE + g_memSize = memSize; + g_blockNum = blockNum; + g_dataSize = bc->blockSize; + g_memStart = dataMem; +#endif + + for (i = 0; i < blockNum; i++) { + block = (OsBcacheBlock *)(VOID *)blockMem; + block->data = dataMem; + block->readBuff = (i < CONFIG_FS_FAT_READ_NUMS) ? TRUE : FALSE; + + if (i == CONFIG_FS_FAT_READ_NUMS) { + bc->wStart = block; + } + + LOS_ListTailInsert(&bc->freeListHead, &block->listNode); + + blockMem += sizeof(OsBcacheBlock); + dataMem += bc->blockSize; + } + + bc->wEnd = block; + + return ENOERR; +} + +static INT32 DrvBread(struct Vnode *priv, UINT8 *buf, UINT32 len, UINT64 pos) +{ + struct block_operations *bops = (struct block_operations *)((struct drv_data *)priv->data)->ops; + + INT32 ret = bops->read(priv, buf, pos, len); + if (ret != (INT32)len) { + PRINT_ERR("%s failure\n", __FUNCTION__); + return ret; + } + return ENOERR; +} + +static INT32 DrvBwrite(struct Vnode *priv, const UINT8 *buf, UINT32 len, UINT64 pos) +{ + struct block_operations *bops = (struct block_operations *)((struct drv_data *)priv->data)->ops; + INT32 ret = bops->write(priv, buf, pos, len); + if (ret != (INT32)len) { + PRINT_ERR("%s failure\n", __FUNCTION__); + return ret; + } + return ENOERR; +} + +INT32 BlockCacheDrvCreate(VOID *handle, + UINT8 *memStart, + UINT32 memSize, + UINT32 blockSize, + OsBcache *bc) +{ + INT32 ret; + bc->priv = handle; + bc->breadFun = DrvBread; + bc->bwriteFun = DrvBwrite; + + ret = BcacheInitCache(bc, memStart, memSize, blockSize); + if (ret != ENOERR) { + return ret; + } + + if (pthread_mutex_init(&bc->bcacheMutex, NULL) != ENOERR) { + return VFS_ERROR; + } + bc->bcacheMutex.attr.type = PTHREAD_MUTEX_RECURSIVE; + + return ENOERR; +} + +INT32 BlockCacheRead(OsBcache *bc, UINT8 *buf, UINT32 *len, UINT64 sector, BOOL useRead) +{ + OsBcacheBlock *block = NULL; + UINT8 *tempBuf = buf; + UINT32 size; + UINT32 currentSize; + INT32 ret = ENOERR; + UINT64 pos; + UINT64 num; +#ifdef BCACHE_ANALYSE + PRINTK("bcache read:\n"); +#endif + + if (bc == NULL || buf == NULL || len == NULL) { + return -EPERM; + } + + size = *len; + pos = sector * bc->sectorSize; + num = pos >> bc->blockSizeLog2; + pos = pos & (bc->blockSize - 1); + + while (size > 0) { + if ((size + pos) > bc->blockSize) { + currentSize = bc->blockSize - (UINT32)pos; + } else { + currentSize = size; + } + + (VOID)pthread_mutex_lock(&bc->bcacheMutex); + + /* useRead should be FALSE when reading large contiguous data */ + ret = BcacheGetBlock(bc, num, useRead, &block); + if (ret != ENOERR) { + (VOID)pthread_mutex_unlock(&bc->bcacheMutex); + break; + } + + if ((block->readFlag == FALSE) && (block->modified == TRUE)) { + ret = BcacheGetFlag(bc, block); + if (ret != ENOERR) { + (VOID)pthread_mutex_unlock(&bc->bcacheMutex); + return ret; + } + } else if ((block->readFlag == FALSE) && (block->modified == FALSE)) { + ret = BlockRead(bc, block, block->data); + if (ret != ENOERR) { + (VOID)pthread_mutex_unlock(&bc->bcacheMutex); + return ret; + } + } + + if (LOS_CopyFromKernel((VOID *)tempBuf, size, (VOID *)(block->data + pos), currentSize) != EOK) { + (VOID)pthread_mutex_unlock(&bc->bcacheMutex); + return VFS_ERROR; + } + + (VOID)pthread_mutex_unlock(&bc->bcacheMutex); + + tempBuf += currentSize; + size -= currentSize; + pos = 0; + num++; + } + *len -= size; + return ret; +} + +INT32 BlockCacheWrite(OsBcache *bc, const UINT8 *buf, UINT32 *len, UINT64 sector) +{ + OsBcacheBlock *block = NULL; + const UINT8 *tempBuf = buf; + UINT32 size = *len; + INT32 ret = ENOERR; + UINT32 currentSize; + UINT64 pos; + UINT64 num; +#ifdef BCACHE_ANALYSE + PRINTK("bcache write:\n"); +#endif + + pos = sector * bc->sectorSize; + num = pos >> bc->blockSizeLog2; + pos = pos & (bc->blockSize - 1); + + D(("bcache write len = %u pos = %llu bnum = %llu\n", *len, pos, num)); + + while (size > 0) { + if ((size + pos) > bc->blockSize) { + currentSize = bc->blockSize - (UINT32)pos; + } else { + currentSize = size; + } + + (VOID)pthread_mutex_lock(&bc->bcacheMutex); + ret = BcacheGetBlock(bc, num, FALSE, &block); + if (ret != ENOERR) { + (VOID)pthread_mutex_unlock(&bc->bcacheMutex); + break; + } + + if (LOS_CopyToKernel((VOID *)(block->data + pos), bc->blockSize - (UINT32)pos, + (VOID *)tempBuf, currentSize) != EOK) { + (VOID)pthread_mutex_unlock(&bc->bcacheMutex); + return VFS_ERROR; + } + if (block->modified == FALSE) { + block->modified = TRUE; + bc->modifiedBlock++; + } + if ((pos == 0) && (currentSize == bc->blockSize)) { + (void)memset_s(block->flag, sizeof(block->flag), 0xFF, sizeof(block->flag)); + block->allDirty = TRUE; + } else { + BcacheSetFlag(bc, block, (UINT32)pos, currentSize); + } + (VOID)pthread_mutex_unlock(&bc->bcacheMutex); + + tempBuf += currentSize; + size -= currentSize; + pos = 0; + num++; + } + *len -= size; + return ret; +} + +INT32 BlockCacheSync(OsBcache *bc) +{ + return BcacheSync(bc); +} + +INT32 OsSdSync(INT32 id) +{ +#ifdef LOSCFG_FS_FAT_CACHE + INT32 ret; + los_disk *disk = get_disk(id); + if ((disk == NULL) || (disk->disk_status == STAT_UNUSED)) { + return VFS_ERROR; + } + if (pthread_mutex_lock(&disk->disk_mutex) != ENOERR) { + PRINT_ERR("%s %d, mutex lock fail!\n", __FUNCTION__, __LINE__); + return VFS_ERROR; + } + if ((disk->disk_status == STAT_INUSED) && (disk->bcache != NULL)) { + ret = BcacheSync(disk->bcache); + } else { + ret = VFS_ERROR; + } + if (pthread_mutex_unlock(&disk->disk_mutex) != ENOERR) { + PRINT_ERR("%s %d, mutex unlock fail!\n", __FUNCTION__, __LINE__); + return VFS_ERROR; + } + return ret; +#else + return VFS_ERROR; +#endif +} + +INT32 LOS_BcacheSyncByName(const CHAR *name) +{ + INT32 diskID = los_get_diskid_byname(name); + return OsSdSync(diskID); +} + +INT32 BcacheGetDirtyRatio(INT32 id) +{ +#ifdef LOSCFG_FS_FAT_CACHE + INT32 ret; + los_disk *disk = get_disk(id); + if (disk == NULL) { + return VFS_ERROR; + } + + if (pthread_mutex_lock(&disk->disk_mutex) != ENOERR) { + PRINT_ERR("%s %d, mutex lock fail!\n", __FUNCTION__, __LINE__); + return VFS_ERROR; + } + if ((disk->disk_status == STAT_INUSED) && (disk->bcache != NULL)) { + ret = (INT32)((disk->bcache->modifiedBlock * PERCENTAGE) / GetFatBlockNums()); + } else { + ret = VFS_ERROR; + } + if (pthread_mutex_unlock(&disk->disk_mutex) != ENOERR) { + PRINT_ERR("%s %d, mutex unlock fail!\n", __FUNCTION__, __LINE__); + return VFS_ERROR; + } + return ret; +#else + return VFS_ERROR; +#endif +} + +INT32 LOS_GetDirtyRatioByName(const CHAR *name) +{ + INT32 diskID = los_get_diskid_byname(name); + return BcacheGetDirtyRatio(diskID); +} + +#ifdef LOSCFG_FS_FAT_CACHE_SYNC_THREAD +static VOID BcacheSyncThread(UINT32 id) +{ + INT32 diskID = (INT32)id; + INT32 dirtyRatio; + while (1) { + dirtyRatio = BcacheGetDirtyRatio(diskID); + if (dirtyRatio > (INT32)g_dirtyRatio) { + (VOID)OsSdSync(diskID); + } + msleep(g_syncInterval); + } +} + +VOID BcacheSyncThreadInit(OsBcache *bc, INT32 id) +{ + UINT32 ret; + TSK_INIT_PARAM_S appTask; + + (VOID)memset_s(&appTask, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + appTask.pfnTaskEntry = (TSK_ENTRY_FUNC)BcacheSyncThread; + appTask.uwStackSize = BCACHE_STATCK_SIZE; + appTask.pcName = "bcache_sync_task"; + appTask.usTaskPrio = g_syncThreadPrio; + appTask.auwArgs[0] = (UINTPTR)id; + appTask.uwResved = LOS_TASK_STATUS_DETACHED; + ret = LOS_TaskCreate(&bc->syncTaskId, &appTask); + if (ret != ENOERR) { + PRINT_ERR("Bcache sync task create failed in %s, %d\n", __FUNCTION__, __LINE__); + } +} + +VOID BcacheSyncThreadDeinit(const OsBcache *bc) +{ + if (bc != NULL) { + if (LOS_TaskDelete(bc->syncTaskId) != ENOERR) { + PRINT_ERR("Bcache sync task delete failed in %s, %d\n", __FUNCTION__, __LINE__); + } + } +} +#endif + +OsBcache *BlockCacheInit(struct Vnode *devNode, UINT32 sectorSize, UINT32 sectorPerBlock, + UINT32 blockNum, UINT64 blockCount) +{ + OsBcache *bcache = NULL; + struct Vnode *blkDriver = devNode; + UINT8 *bcacheMem = NULL; + UINT8 *rwBuffer = NULL; + UINT32 blockSize, memSize; + + if ((blkDriver == NULL) || (sectorSize * sectorPerBlock * blockNum == 0) || (blockCount == 0)) { + return NULL; + } + + blockSize = sectorSize * sectorPerBlock; + if ((((UINT64)(sizeof(OsBcacheBlock) + blockSize) * blockNum) + DMA_ALLGN) > UINT_MAX) { + return NULL; + } + memSize = ((sizeof(OsBcacheBlock) + blockSize) * blockNum) + DMA_ALLGN; + + bcache = (OsBcache *)zalloc(sizeof(OsBcache)); + if (bcache == NULL) { + PRINT_ERR("bcache_init : malloc %u Bytes failed!\n", sizeof(OsBcache)); + return NULL; + } + + bcacheMem = (UINT8 *)zalloc(memSize); + if (bcacheMem == NULL) { + PRINT_ERR("bcache_init : malloc %u Bytes failed!\n", memSize); + goto ERROR_OUT_WITH_BCACHE; + } + + rwBuffer = (UINT8 *)memalign(DMA_ALLGN, blockSize); + if (rwBuffer == NULL) { + PRINT_ERR("bcache_init : malloc %u Bytes failed!\n", blockSize); + goto ERROR_OUT_WITH_MEM; + } + + bcache->rwBuffer = rwBuffer; + bcache->sectorSize = sectorSize; + bcache->sectorPerBlock = sectorPerBlock; + bcache->blockCount = blockCount; + + if (BlockCacheDrvCreate(blkDriver, bcacheMem, memSize, blockSize, bcache) != ENOERR) { + goto ERROR_OUT_WITH_BUFFER; + } + + return bcache; + +ERROR_OUT_WITH_BUFFER: + free(rwBuffer); +ERROR_OUT_WITH_MEM: + free(bcacheMem); +ERROR_OUT_WITH_BCACHE: + free(bcache); + return NULL; +} + +VOID BlockCacheDeinit(OsBcache *bcache) +{ + if (bcache != NULL) { + (VOID)pthread_mutex_destroy(&bcache->bcacheMutex); + free(bcache->memStart); + bcache->memStart = NULL; + free(bcache->rwBuffer); + bcache->rwBuffer = NULL; + free(bcache); + } +} + +static VOID BcacheAsyncPrereadThread(VOID *arg) +{ + OsBcache *bc = (OsBcache *)arg; + OsBcacheBlock *block = NULL; + INT32 ret; + UINT32 i; + + for (;;) { + ret = (INT32)LOS_EventRead(&bc->bcacheEvent, PREREAD_EVENT_MASK, + LOS_WAITMODE_OR | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER); + if (ret != ASYNC_EVENT_BIT) { + PRINT_ERR("The event read in %s, %d is error!!!\n", __FUNCTION__, __LINE__); + continue; + } + + for (i = 1; i <= PREREAD_BLOCK_NUM; i++) { + if ((bc->curBlockNum + i) >= bc->blockCount) { + break; + } + + (VOID)pthread_mutex_lock(&bc->bcacheMutex); + ret = BcacheGetBlock(bc, bc->curBlockNum + i, TRUE, &block); + if (ret != ENOERR) { + PRINT_ERR("read block %llu error : %d!\n", bc->curBlockNum, ret); + } + + (VOID)pthread_mutex_unlock(&bc->bcacheMutex); + } + + if (block != NULL) { + block->pgHit = 1; /* preread complete */ + } + } +} + +VOID ResumeAsyncPreread(OsBcache *arg1, const OsBcacheBlock *arg2) +{ + UINT32 ret; + OsBcache *bc = arg1; + const OsBcacheBlock *block = arg2; + + if (OsCurrTaskGet()->taskID != bc->prereadTaskId) { + bc->curBlockNum = block->num; + ret = LOS_EventWrite(&bc->bcacheEvent, ASYNC_EVENT_BIT); + if (ret != ENOERR) { + PRINT_ERR("Write event failed in %s, %d\n", __FUNCTION__, __LINE__); + } + } +} + +UINT32 BcacheAsyncPrereadInit(OsBcache *bc) +{ + UINT32 ret; + TSK_INIT_PARAM_S appTask; + + ret = LOS_EventInit(&bc->bcacheEvent); + if (ret != ENOERR) { + PRINT_ERR("Async event init failed in %s, %d\n", __FUNCTION__, __LINE__); + return ret; + } + + (VOID)memset_s(&appTask, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + appTask.pfnTaskEntry = (TSK_ENTRY_FUNC)BcacheAsyncPrereadThread; + appTask.uwStackSize = BCACHE_STATCK_SIZE; + appTask.pcName = "bcache_async_task"; + appTask.usTaskPrio = BCACHE_PREREAD_PRIO; + appTask.auwArgs[0] = (UINTPTR)bc; + appTask.uwResved = LOS_TASK_STATUS_DETACHED; + ret = LOS_TaskCreate(&bc->prereadTaskId, &appTask); + if (ret != ENOERR) { + PRINT_ERR("Bcache async task create failed in %s, %d\n", __FUNCTION__, __LINE__); + } + + return ret; +} + +UINT32 BcacheAsyncPrereadDeinit(OsBcache *bc) +{ + UINT32 ret = LOS_NOK; + + if (bc != NULL) { + ret = LOS_TaskDelete(bc->prereadTaskId); + if (ret != ENOERR) { + PRINT_ERR("Bcache async task delete failed in %s, %d\n", __FUNCTION__, __LINE__); + } + + ret = LOS_EventDestroy(&bc->bcacheEvent); + if (ret != ENOERR) { + PRINT_ERR("Async event destroy failed in %s, %d\n", __FUNCTION__, __LINE__); + return ret; + } + } + + return ret; +} diff --git a/src/kernel_liteos_a/fs/vfs/epoll/fs_epoll.c b/src/kernel_liteos_a/fs/vfs/epoll/fs_epoll.c new file mode 100644 index 00000000..9252e80c --- /dev/null +++ b/src/kernel_liteos_a/fs/vfs/epoll/fs_epoll.c @@ -0,0 +1,352 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "epoll.h" +#include +#include +#include +#include +#include "pthread.h" + +/* 100, the number of fd one epollfd can control */ +#define EPOLL_DEFAULT_SIZE 100 + +/* Internal data, used to manage each epoll fd */ +struct epoll_head { + int size; + int nodeCount; + struct epoll_event *evs; +}; + +STATIC pthread_mutex_t g_epollMutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; + +#ifndef MAX_EPOLL_FD +#define MAX_EPOLL_FD CONFIG_EPOLL_DESCRIPTORS +#endif + +/* Record the kernel fd of epoll */ +STATIC fd_set g_epollFdSet; + +/* Record the private data of epoll */ +STATIC struct epoll_head *g_epPrivBuf[MAX_EPOLL_FD]; + +/** + * Alloc sysFd, storage epoll private data, set using bit. + * + * @param maxfdp: Maximum allowed application of sysFd. + * @param head: Private data. + * @return the index of the new fd; -1 on error + */ +static int EpollAllocSysFd(int maxfdp, struct epoll_head *head) +{ + int i; + + fd_set *fdset = &g_epollFdSet; + + for (i = 0; i < maxfdp; i++) { + if (fdset && !(FD_ISSET(i, fdset))) { + FD_SET(i, fdset); + if (!g_epPrivBuf[i]) { + g_epPrivBuf[i] = head; + return i + EPOLL_FD_OFFSET; + } + } + } + + set_errno(EMFILE); + return -1; +} + +/** + * free sysFd, delete epoll private data, clear using bit. + * + * @param fd: epoll fd. + * @return 0 or -1 + */ +static int EpollFreeSysFd(int fd) +{ + int efd = fd - EPOLL_FD_OFFSET; + + if ((efd < 0) || (efd >= MAX_EPOLL_FD)) { + set_errno(EMFILE); + return -1; + } + + fd_set *fdset = &g_epollFdSet; + if (fdset && FD_ISSET(efd, fdset)) { + FD_CLR(efd, fdset); + g_epPrivBuf[efd] = NULL; + } + + return 0; +} + +/** + * get private data by epoll fd + * + * @param fd: epoll fd. + * @return point to epoll_head + */ +static struct epoll_head *EpollGetDataBuff(int fd) +{ + int id = fd - EPOLL_FD_OFFSET; + + if ((id < 0) || (id >= MAX_EPOLL_FD)) { + return NULL; + } + + return g_epPrivBuf[id]; +} + +/** + * when do EPOLL_CTL_ADD, need check if fd exist + * + * @param epHead: epoll control head, find by epoll id . + * @param fd: ctl add fd. + * @return 0 or -1 + */ +static int CheckFdExist(struct epoll_head *epHead, int fd) +{ + int i; + for (i = 0; i < epHead->nodeCount; i++) { + if (epHead->evs[i].data.fd == fd) { + return -1; + } + } + + return 0; +} + +/** + * close epoll + * + * @param epHead: epoll control head. + * @return void + */ +static VOID DoEpollClose(struct epoll_head *epHead) +{ + if (epHead != NULL) { + if (epHead->evs != NULL) { + free(epHead->evs); + } + + free(epHead); + } + + return; +} + +/** + * epoll_create unsupported api + * + * epoll_create is implemented by calling epoll_create1, it's parameter 'size' is useless. + * + * epoll_create1, + * The simple version of epoll does not use red-black trees, + * so when fd is normal value (greater than 0), + * actually allocated epoll can manage num of EPOLL_DEFAULT_SIZE + * + * @param flags: not actually used + * @return epoll fd + */ +int epoll_create1(int flags) +{ + (void)flags; + int fd = -1; + + struct epoll_head *epHead = (struct epoll_head *)malloc(sizeof(struct epoll_head)); + if (epHead == NULL) { + set_errno(ENOMEM); + return fd; + } + + /* actually allocated epoll can manage num is EPOLL_DEFAULT_SIZE */ + epHead->size = EPOLL_DEFAULT_SIZE; + epHead->nodeCount = 0; + epHead->evs = malloc(sizeof(struct epoll_event) * EPOLL_DEFAULT_SIZE); + if (epHead->evs == NULL) { + free(epHead); + set_errno(ENOMEM); + return fd; + } + + /* fd set, get sysfd, for close */ + (VOID)pthread_mutex_lock(&g_epollMutex); + fd = EpollAllocSysFd(MAX_EPOLL_FD, epHead); + if (fd == -1) { + (VOID)pthread_mutex_unlock(&g_epollMutex); + DoEpollClose(epHead); + set_errno(EMFILE); + return fd; + } + (VOID)pthread_mutex_unlock(&g_epollMutex); + return fd; +} + +/** + * epoll_close, + * called by close + * @param epfd: epoll fd + * @return 0 or -1 + */ +int epoll_close(int epfd) +{ + struct epoll_head *epHead = NULL; + + epHead = EpollGetDataBuff(epfd); + if (epHead == NULL) { + set_errno(EBADF); + return -1; + } + + DoEpollClose(epHead); + return EpollFreeSysFd(epfd); +} + +int epoll_ctl(int epfd, int op, int fd, struct epoll_event *ev) +{ + struct epoll_head *epHead = NULL; + int i; + int ret = -1; + + epHead = EpollGetDataBuff(epfd); + if (epHead == NULL) { + set_errno(EBADF); + return ret; + } + + if (ev == NULL) { + set_errno(EINVAL); + return -1; + } + + switch (op) { + case EPOLL_CTL_ADD: + ret = CheckFdExist(epHead, fd); + if (ret == -1) { + set_errno(EEXIST); + return -1; + } + + if (epHead->nodeCount == EPOLL_DEFAULT_SIZE) { + set_errno(ENOMEM); + return -1; + } + + epHead->evs[epHead->nodeCount].events = ev->events | POLLERR | POLLHUP; + epHead->evs[epHead->nodeCount].data.fd = fd; + epHead->nodeCount++; + return 0; + case EPOLL_CTL_DEL: + for (i = 0; i < epHead->nodeCount; i++) { + if (epHead->evs[i].data.fd != fd) { + continue; + } + + if (i != epHead->nodeCount - 1) { + memmove_s(&epHead->evs[i], epHead->nodeCount - i, &epHead->evs[i + 1], + epHead->nodeCount - i); + } + epHead->nodeCount--; + return 0; + } + set_errno(ENOENT); + return -1; + case EPOLL_CTL_MOD: + for (i = 0; i < epHead->nodeCount; i++) { + if (epHead->evs[i].data.fd == fd) { + epHead->evs[i].events = ev->events | POLLERR | POLLHUP; + return 0; + } + } + set_errno(ENOENT); + return -1; + default: + set_errno(EINVAL); + return -1; + } +} + +int epoll_wait(int epfd, FAR struct epoll_event *evs, int maxevents, int timeout) +{ + struct epoll_head *epHead = NULL; + int ret; + int counter; + int i; + struct pollfd *pFd = NULL; + int pollSize; + + epHead = EpollGetDataBuff(epfd); + if (epHead == NULL) { + set_errno(EBADF); + return -1; + } + + if ((maxevents <= 0) || (evs == NULL)) { + set_errno(EINVAL); + return -1; + } + + if (maxevents > epHead->nodeCount) { + pollSize = epHead->nodeCount; + } else { + pollSize = maxevents; + } + + pFd = malloc(sizeof(struct pollfd) * pollSize); + if (pFd == NULL) { + set_errno(EINVAL); + return -1; + } + + for (i = 0; i < epHead->nodeCount; i++) { + pFd[i].fd = epHead->evs[i].data.fd; + pFd[i].events = (short)epHead->evs[i].events; + } + + + ret = poll(pFd, pollSize, timeout); + if (ret <= 0) { + free(pFd); + return 0; + } + + for (i = 0, counter = 0; i < ret && counter < pollSize; counter++) { + if (pFd[counter].revents != 0) { + evs[i].data.fd = pFd[counter].fd; + evs[i].events = pFd[counter].revents; + i++; + } + } + + free(pFd); + return i; +} + diff --git a/src/kernel_liteos_a/fs/vfs/include/bcache/bcache.h b/src/kernel_liteos_a/fs/vfs/include/bcache/bcache.h new file mode 100644 index 00000000..591baaac --- /dev/null +++ b/src/kernel_liteos_a/fs/vfs/include/bcache/bcache.h @@ -0,0 +1,275 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _BCACHE_H +#define _BCACHE_H + +#include "pthread.h" +#include "linux/rbtree.h" +#include "los_list.h" +#include "vnode.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define ALIGN_LIB(x) (((x) + (HALARC_ALIGNMENT - 1)) & ~(HALARC_ALIGNMENT - 1)) +#define ALIGN_DISP(x) (HALARC_ALIGNMENT - ((x) & (HALARC_ALIGNMENT - 1))) +#define BCACHE_PREREAD_PRIO 12 +#define UNSIGNED_INTEGER_BITS 32 +#define UNINT_MAX_SHIFT_BITS 31 +#define UNINT_LOG2_SHIFT 5 +#define PREREAD_BLOCK_NUM 2 +#define EVEN_JUDGED 2 +#define PERCENTAGE 100 +#define PREREAD_EVENT_MASK 0xf + +#if CONFIG_FS_FAT_SECTOR_PER_BLOCK < UNSIGNED_INTEGER_BITS +#error cache too small +#else +#define BCACHE_BLOCK_FLAGS (CONFIG_FS_FAT_SECTOR_PER_BLOCK / UNSIGNED_INTEGER_BITS) +#endif + +typedef struct { + LOS_DL_LIST listNode; /* list node */ + LOS_DL_LIST numNode; /* num node */ + struct rb_node rbNode; /* red-black tree node */ + UINT64 num; /* block number */ + UINT32 flag[BCACHE_BLOCK_FLAGS]; + UINT32 pgHit; + UINT8 *data; /* block data */ + BOOL modified; /* is this block data modified (needs write) */ + BOOL readFlag; /* is the block data have read from sd(real data) */ + BOOL readBuff; /* read write buffer */ + BOOL used; /* used or free for write buf */ + BOOL allDirty; /* the whole block is dirty */ +} OsBcacheBlock; + +typedef INT32 (*BcacheReadFun)(struct Vnode *, /* private data */ + UINT8 *, /* block buffer */ + UINT32, /* number of blocks to read */ + UINT64); /* starting block number */ + +typedef INT32 (*BcacheWriteFun)(struct Vnode *, /* private data */ + const UINT8 *, /* block buffer */ + UINT32, /* number of blocks to write */ + UINT64); /* starting block number */ + +struct tagOsBcache; + +typedef VOID (*BcachePrereadFun)(struct tagOsBcache *, /* block cache instance space holder */ + const OsBcacheBlock *); /* block data */ + +typedef struct tagOsBcache { + VOID *priv; /* private data */ + LOS_DL_LIST listHead; /* head of block list */ + LOS_DL_LIST numHead; /* block num list */ + struct rb_root rbRoot; /* block red-black tree root */ + UINT32 blockSize; /* block size in bytes */ + UINT32 blockSizeLog2; /* block size log2 */ + UINT64 blockCount; /* block count of the disk */ + UINT32 sectorSize; /* device sector size in bytes */ + UINT32 sectorPerBlock; /* sector count per block */ + UINT8 *memStart; /* memory base */ + UINT32 prereadTaskId; /* preread task id */ + UINT64 curBlockNum; /* current preread block number */ + LOS_DL_LIST freeListHead; /* list of free blocks */ + BcacheReadFun breadFun; /* block read function */ + BcacheWriteFun bwriteFun; /* block write function */ + BcachePrereadFun prereadFun; /* block preread function */ + UINT8 *rwBuffer; /* buffer for bcache block */ + pthread_mutex_t bcacheMutex; /* mutex for bcache */ + EVENT_CB_S bcacheEvent; /* event for bcache */ + UINT32 modifiedBlock; /* number of modified blocks */ +#ifdef LOSCFG_FS_FAT_CACHE_SYNC_THREAD + UINT32 syncTaskId; /* sync task id */ +#endif + OsBcacheBlock *wStart; /* write start block */ + OsBcacheBlock *wEnd; /* write end block */ + UINT64 sumNum; /* block num sum val */ + UINT32 nBlock; /* current block count */ +} OsBcache; + +/** + * @ingroup bcache + * + * @par Description: + * The BlockCacheRead() function shall read data from the bcache, and if it doesn't hit, read the data from disk. + * + * @param bc [IN] block cache instance + * @param buf [OUT] data buffer ptr + * @param len [IN] number of bytes to read + * @param num [IN] starting block number + * @param pos [IN] starting position inside starting block + * @param useRead [IN] whether use the read block or write block + * + * @attention + *
            + *
          • The block number is automatically adjusted if position is greater than block size.
          • + *
          + * + * @retval #0 read succeeded + * @retval #INT32 read failed + * + * @par Dependency: + *
          • bcache.h
          + * + */ +INT32 BlockCacheRead(OsBcache *bc, + UINT8 *buf, + UINT32 *len, + UINT64 pos, + BOOL useRead); + +/** + * @ingroup bcache + * + * @par Description: + * The BlockCacheWrite() function shall write data to the bcache. + * + * @param bc [IN] block cache instance + * @param buf [IN] data buffer ptr + * @param len [IN] number of bytes to write + * @param num [IN] starting block number + * @param pos [IN] starting position inside starting block + * + * @attention + *
            + *
          • The block number is automatically adjusted if position is greater than block size.
          • + *
          + * + * @retval #0 write succeeded + * @retval #INT32 write failed + * + * @par Dependency: + *
          • bcache.h
          + * + */ +INT32 BlockCacheWrite(OsBcache *bc, + const UINT8 *buf, + UINT32 *len, + UINT64 pos); + +/** + * @ingroup bcache + * + * @par Description: + * The BlockCacheSync() function shall write-back all dirty data in the bcache into the disk. + * + * @param bc [IN] block cache instance + * + * @attention + *
            + *
          • None.
          • + *
          + * + * @retval #0 sync succeeded + * @retval #INT32 sync failed + * + * @par Dependency: + *
          • bcache.h
          + * + */ +INT32 BlockCacheSync(OsBcache *bc); + +/** + * @ingroup bcache + * + * @par Description: + * The BlockCacheInit() function shall alloc memory for bcache and init it. + * + * @param devNode [IN] dev node instance + * @param sectorSize [IN] size of a sector + * @param sectorPerBlock [IN] sector count per block in bcache + * @param blockNum [IN] block number of bcache + * @param blockCount [IN] block count of the disk + * + * @attention + *
            + *
          • None.
          • + *
          + * + * @retval #OsBcache * init succeeded + * @retval #NULL init failed + * + * @par Dependency: + *
          • bcache.h
          + * + */ +OsBcache *BlockCacheInit(struct Vnode *devNode, + UINT32 sectorSize, + UINT32 sectorPerBlock, + UINT32 blockNum, + UINT64 blockCount); + +/** + * @ingroup bcache + * + * @par Description: + * The BlockCacheDeinit() function shall deinit the bcache and release resources. + * + * @param bc [IN] block cache instance + * + * @attention + *
            + *
          • None.
          • + *
          + * + * @retval #VOID None. + * + * @par Dependency: + *
          • bcache.h
          + * + */ +VOID BlockCacheDeinit(OsBcache *bc); + +INT32 BcacheClearCache(OsBcache *bc); +INT32 OsSdSync(INT32 id); + +#ifdef LOSCFG_FS_FAT_CACHE_SYNC_THREAD +VOID BcacheSyncThreadInit(OsBcache *bc, INT32 id); +VOID BcacheSyncThreadDeinit(const OsBcache *bc); +#endif + +UINT32 BcacheAsyncPrereadInit(OsBcache *bc); + +VOID ResumeAsyncPreread(OsBcache *arg1, const OsBcacheBlock *arg2); + +UINT32 BcacheAsyncPrereadDeinit(OsBcache *bc); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ +#endif /* _BCACHE_H */ diff --git a/src/kernel_liteos_a/fs/vfs/include/epoll.h b/src/kernel_liteos_a/fs/vfs/include/epoll.h new file mode 100644 index 00000000..e0aed193 --- /dev/null +++ b/src/kernel_liteos_a/fs/vfs/include/epoll.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FS_EPOLL_H_ +#define _FS_EPOLL_H_ + +#include "los_typedef.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef FAR +#define FAR +#endif + +#define EPOLL_CLOEXEC O_CLOEXEC +#define EPOLL_NONBLOCK O_NONBLOCK + +#define EPOLLIN 0x001 +#define EPOLLPRI 0x002 +#define EPOLLOUT 0x004 +#define EPOLLRDNORM 0x040 +#define EPOLLNVAL 0x020 +#define EPOLLRDBAND 0x080 +#define EPOLLWRNORM 0x100 +#define EPOLLWRBAND 0x200 +#define EPOLLMSG 0x400 +#define EPOLLERR 0x008 +#define EPOLLHUP 0x010 + +#define EPOLL_CTL_ADD 1 +#define EPOLL_CTL_DEL 2 +#define EPOLL_CTL_MOD 3 + +typedef union epoll_data { + void *ptr; + int fd; + UINT32 u32; + UINT64 u64; +} epoll_data_t; + +struct epoll_event { + UINT32 events; + epoll_data_t data; +}; + +int epoll_create1(int flags); +int epoll_close(int epfd); +int epoll_ctl(int epfd, int op, int fd, struct epoll_event *ev); +int epoll_wait(int epfd, FAR struct epoll_event *evs, int maxevents, int timeout); + +#ifdef __cplusplus +} +#endif + +#endif /* sys/epoll.h */ diff --git a/src/kernel_liteos_a/fs/vfs/include/fs_poll_pri.h b/src/kernel_liteos_a/fs/vfs/include/fs_poll_pri.h new file mode 100644 index 00000000..ae9f96cf --- /dev/null +++ b/src/kernel_liteos_a/fs/vfs/include/fs_poll_pri.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FS_POLL_PRI_H_ +#define _FS_POLL_PRI_H_ +/* empty file for hdf compatibility should remove later */ +#endif diff --git a/src/kernel_liteos_a/fs/vfs/include/path_cache.h b/src/kernel_liteos_a/fs/vfs/include/path_cache.h new file mode 100644 index 00000000..a71785e4 --- /dev/null +++ b/src/kernel_liteos_a/fs/vfs/include/path_cache.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _PATH_CACHE_H +#define _PATH_CACHE_H + +#include "los_list.h" +#include "fs/mount.h" +#include "vnode.h" + +struct PathCache { + struct Vnode *parentVnode; /* vnode points to the cache */ + struct Vnode *childVnode; /* vnode the cache points to */ + LIST_ENTRY parentEntry; /* list entry for cache list in the parent vnode */ + LIST_ENTRY childEntry; /* list entry for cache list in the child vnode */ + LIST_ENTRY hashEntry; /* list entry for buckets in the hash table */ + uint8_t nameLen; /* length of path component */ +#ifdef LOSCFG_DEBUG_VERSION + int hit; /* cache hit count */ +#endif + char name[0]; /* path component name */ +}; + +int PathCacheInit(void); +int PathCacheFree(struct PathCache *cache); +struct PathCache *PathCacheAlloc(struct Vnode *parent, struct Vnode *vnode, const char *name, uint8_t len); +int PathCacheLookup(struct Vnode *parent, const char *name, int len, struct Vnode **vnode); +void VnodePathCacheFree(struct Vnode *vnode); +void PathCacheMemoryDump(void); +void PathCacheDump(void); +LIST_HEAD* GetPathCacheList(void); +#ifdef LOSCFG_DEBUG_VERSION +void ResetPathCacheHitInfo(int *hit, int *try); +#endif + +#endif /* _PATH_CACHE_H */ diff --git a/src/kernel_liteos_a/fs/vfs/include/vnode.h b/src/kernel_liteos_a/fs/vfs/include/vnode.h new file mode 100644 index 00000000..95afde6c --- /dev/null +++ b/src/kernel_liteos_a/fs/vfs/include/vnode.h @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _VNODE_H_ +#define _VNODE_H_ + +#include +#include "fs/fs_operation.h" +#include "fs/file.h" +#include "los_list.h" + +typedef LOS_DL_LIST LIST_HEAD; +typedef LOS_DL_LIST LIST_ENTRY; + +#define VNODE_FLAG_MOUNT_NEW (1 << 0) /* new mount vnode */ +#define VNODE_FLAG_MOUNT_ORIGIN (1 << 1) /* origin vnode */ + +#define V_CREATE (1 << 0) +#define V_DUMMY (1 << 2) + +#ifndef VFS_ERROR +#define VFS_ERROR -1 +#endif + +#ifndef OK +#define OK 0 +#endif + +#define AT_REMOVEDIR 0x200 + +#define DEV_PATH_LEN 5 + +/* Permission flags */ +#define READ_OP 4 +#define WRITE_OP 2 +#define EXEC_OP 1 +#define UGO_NUMS 3 +#define MODE_IXUGO 0111 +#define USER_MODE_SHIFT 6 +#define GROUP_MODE_SHIFT 3 +#define UMASK_FULL 0777 + +/* Attribute flags. */ +#define CHG_MODE 1 +#define CHG_UID 2 +#define CHG_GID 4 +#define CHG_SIZE 8 +#define CHG_ATIME 16 +#define CHG_MTIME 32 +#define CHG_CTIME 64 + +struct IATTR { + /* This structure is used for record vnode attr. */ + unsigned int attr_chg_valid; + unsigned int attr_chg_flags; + unsigned attr_chg_mode; + unsigned attr_chg_uid; + unsigned attr_chg_gid; + unsigned attr_chg_size; + unsigned attr_chg_atime; + unsigned attr_chg_mtime; + unsigned attr_chg_ctime; +}; + + /* + * Vnode types. VNODE_TYPE_UNKNOWN means no type. + */ +enum VnodeType { + VNODE_TYPE_UNKNOWN, /* unknown type */ + VNODE_TYPE_REG, /* regular fle */ + VNODE_TYPE_DIR, /* directory */ + VNODE_TYPE_BLK, /* block device */ + VNODE_TYPE_CHR, /* char device */ + VNODE_TYPE_BCHR, /* block char mix device */ + VNODE_TYPE_FIFO, /* pipe */ + VNODE_TYPE_LNK, /* link */ +#ifdef LOSCFG_PROC_PROCESS_DIR + VNODE_TYPE_VIR_LNK, /* virtual link */ +#endif +}; + +struct fs_dirent_s; +struct VnodeOps; +struct IATTR; + +struct Vnode { + enum VnodeType type; /* vnode type */ + int useCount; /* ref count of users */ + uint32_t hash; /* vnode hash */ + uint uid; /* uid for dac */ + uint gid; /* gid for dac */ + mode_t mode; /* mode for dac */ + LIST_HEAD parentPathCaches; /* pathCaches point to parents */ + LIST_HEAD childPathCaches; /* pathCaches point to children */ + struct Vnode *parent; /* parent vnode */ + struct VnodeOps *vop; /* vnode operations */ + struct file_operations_vfs *fop; /* file operations */ + void *data; /* private data */ + uint32_t flag; /* vnode flag */ + LIST_ENTRY hashEntry; /* list entry for bucket in hash table */ + LIST_ENTRY actFreeEntry; /* vnode active/free list entry */ + struct Mount *originMount; /* fs info about this vnode */ + struct Mount *newMount; /* fs info about who mount on this vnode */ + char *filePath; /* file path of the vnode */ + struct page_mapping mapping; /* page mapping of the vnode */ +#ifdef LOSCFG_MNT_CONTAINER + int mntCount; /* ref count of mounts */ +#endif +}; + +struct VnodeOps { + int (*Create)(struct Vnode *parent, const char *name, int mode, struct Vnode **vnode); + int (*Lookup)(struct Vnode *parent, const char *name, int len, struct Vnode **vnode); + int (*Open)(struct Vnode *vnode, int fd, int mode, int flags); + ssize_t (*ReadPage)(struct Vnode *vnode, char *buffer, off_t pos); + ssize_t (*WritePage)(struct Vnode *vnode, char *buffer, off_t pos, size_t buflen); + int (*Close)(struct Vnode *vnode); + int (*Reclaim)(struct Vnode *vnode); + int (*Unlink)(struct Vnode *parent, struct Vnode *vnode, const char *fileName); + int (*Rmdir)(struct Vnode *parent, struct Vnode *vnode, const char *dirName); + int (*Mkdir)(struct Vnode *parent, const char *dirName, mode_t mode, struct Vnode **vnode); + int (*Readdir)(struct Vnode *vnode, struct fs_dirent_s *dir); + int (*Opendir)(struct Vnode *vnode, struct fs_dirent_s *dir); + int (*Rewinddir)(struct Vnode *vnode, struct fs_dirent_s *dir); + int (*Closedir)(struct Vnode *vnode, struct fs_dirent_s *dir); + int (*Getattr)(struct Vnode *vnode, struct stat *st); + int (*Setattr)(struct Vnode *vnode, struct stat *st); + int (*Chattr)(struct Vnode *vnode, struct IATTR *attr); + int (*Rename)(struct Vnode *src, struct Vnode *dstParent, const char *srcName, const char *dstName); + int (*Truncate)(struct Vnode *vnode, off_t len); + int (*Truncate64)(struct Vnode *vnode, off64_t len); + int (*Fscheck)(struct Vnode *vnode, struct fs_dirent_s *dir); + int (*Link)(struct Vnode *src, struct Vnode *dstParent, struct Vnode **dst, const char *dstName); + int (*Symlink)(struct Vnode *parentVnode, struct Vnode **newVnode, const char *path, const char *target); + ssize_t (*Readlink)(struct Vnode *vnode, char *buffer, size_t bufLen); +}; + +typedef int VfsHashCmp(struct Vnode *vnode, void *arg); + +int VnodesInit(void); +int VnodeDevInit(void); +int VnodeAlloc(struct VnodeOps *vop, struct Vnode **newVnode); +int VnodeFree(struct Vnode *vnode); +int VnodeLookup(const char *path, struct Vnode **vnode, uint32_t flags); +int VnodeLookupFullpath(const char *fullpath, struct Vnode **vnode, uint32_t flags); +int VnodeLookupAt(const char *path, struct Vnode **vnode, uint32_t flags, struct Vnode *orgVnode); +int VnodeHold(void); +int VnodeDrop(void); +void VnodeRefDec(struct Vnode *vnode); +int VnodeFreeAll(const struct Mount *mnt); +int VnodeHashInit(void); +uint32_t VfsHashIndex(struct Vnode *vnode); +int VfsHashGet(const struct Mount *mount, uint32_t hash, struct Vnode **vnode, VfsHashCmp *fun, void *arg); +void VfsHashRemove(struct Vnode *vnode); +int VfsHashInsert(struct Vnode *vnode, uint32_t hash); +void ChangeRoot(struct Vnode *newRoot); +BOOL VnodeInUseIter(const struct Mount *mount); +struct Vnode *VnodeGetRoot(void); +void VnodeMemoryDump(void); +mode_t GetUmask(void); +int VfsPermissionCheck(uint fuid, uint fgid, mode_t fileMode, int accMode); +int VfsVnodePermissionCheck(const struct Vnode *node, int accMode); +LIST_HEAD* GetVnodeFreeList(void); +LIST_HEAD* GetVnodeActiveList(void); +LIST_HEAD* GetVnodeVirtualList(void); +int VnodeClearCache(void); +struct Vnode *GetCurrRootVnode(void); +#ifdef LOSCFG_PROC_PROCESS_DIR +struct Vnode *VnodeFind(int fd); +#endif +#endif /* !_VNODE_H_ */ diff --git a/src/kernel_liteos_a/fs/vfs/mount.c b/src/kernel_liteos_a/fs/vfs/mount.c new file mode 100644 index 00000000..b95a7673 --- /dev/null +++ b/src/kernel_liteos_a/fs/vfs/mount.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fs/mount.h" +#include "path_cache.h" +#include "vnode.h" +#ifdef LOSCFG_DRIVERS_RANDOM +#include "hisoc/random.h" +#else +#include "stdlib.h" +#endif + +#ifdef LOSCFG_MNT_CONTAINER +#include "los_mnt_container_pri.h" +static LIST_HEAD *g_mountCache = NULL; +#else +static LIST_HEAD *g_mountList = NULL; +#endif + +struct Mount *MountAlloc(struct Vnode *vnodeBeCovered, struct MountOps *fsop) +{ + struct Mount *mnt = (struct Mount *)zalloc(sizeof(struct Mount)); + if (mnt == NULL) { + PRINT_ERR("MountAlloc failed no memory!\n"); + return NULL; + } + + LOS_ListInit(&mnt->activeVnodeList); + LOS_ListInit(&mnt->vnodeList); + + mnt->vnodeBeCovered = vnodeBeCovered; + vnodeBeCovered->newMount = mnt; +#ifdef LOSCFG_DRIVERS_RANDOM + HiRandomHwInit(); + (VOID)HiRandomHwGetInteger(&mnt->hashseed); + HiRandomHwDeinit(); +#else + mnt->hashseed = (uint32_t)random(); +#endif + return mnt; +} + +#ifdef LOSCFG_MNT_CONTAINER +LIST_HEAD *GetMountList(void) +{ + return GetContainerMntList(); +} + +LIST_HEAD *GetMountCache(void) +{ + if (g_mountCache == NULL) { + g_mountCache = zalloc(sizeof(LIST_HEAD)); + if (g_mountCache == NULL) { + PRINT_ERR("init cache mount list failed, no memory."); + return NULL; + } + LOS_ListInit(g_mountCache); + } + return g_mountCache; +} +#else +LIST_HEAD* GetMountList(void) +{ + if (g_mountList == NULL) { + g_mountList = zalloc(sizeof(LIST_HEAD)); + if (g_mountList == NULL) { + PRINT_ERR("init mount list failed, no memory."); + return NULL; + } + LOS_ListInit(g_mountList); + } + return g_mountList; +} +#endif diff --git a/src/kernel_liteos_a/fs/vfs/operation/fullpath.c b/src/kernel_liteos_a/fs/vfs/operation/fullpath.c new file mode 100644 index 00000000..f42caead --- /dev/null +++ b/src/kernel_liteos_a/fs/vfs/operation/fullpath.c @@ -0,0 +1,329 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "stdio.h" +#include "stdlib.h" +#include "string.h" +#include "errno.h" +#include "limits.h" +#include "los_process_pri.h" +#include "fs/fd_table.h" +#include "fs/file.h" + +#ifdef LOSCFG_SHELL +#include "shell.h" +#endif + + +#ifdef LOSCFG_SHELL +#define TEMP_PATH_MAX (PATH_MAX + SHOW_MAX_LEN) +#else +#define TEMP_PATH_MAX PATH_MAX +#endif + +static unsigned int vfs_strnlen(const char *str, size_t maxlen) +{ + const char *p = NULL; + + for (p = str; ((maxlen-- != 0) && (*p != '\0')); ++p) {} + + return p - str; +} + +/* abandon the redundant '/' in the path, only keep one. */ + +static char *str_path(char *path) +{ + char *dest = path; + char *src = path; + + while (*src != '\0') { + if (*src == '/') { + *dest++ = *src++; + while (*src == '/') { + src++; + } + continue; + } + *dest++ = *src++; + } + *dest = '\0'; + return path; +} + +static void str_remove_path_end_slash(char *dest, const char *fullpath) +{ + if ((*dest == '.') && (*(dest - 1) == '/')) { + *dest = '\0'; + dest--; + } + if ((dest != fullpath) && (*dest == '/')) { + *dest = '\0'; + } +} + +static char *str_normalize_path(char *fullpath) +{ + char *dest = fullpath; + char *src = fullpath; + + /* 2: The position of the path character: / and the end character /0 */ + + while (*src != '\0') { + if (*src == '.') { + if (*(src + 1) == '/') { + src += 2; + continue; + } else if (*(src + 1) == '.') { + if ((*(src + 2) == '/') || (*(src + 2) == '\0')) { + src += 2; + } else { + while ((*src != '\0') && (*src != '/')) { + *dest++ = *src++; + } + continue; + } + } else { + *dest++ = *src++; + continue; + } + } else { + *dest++ = *src++; + continue; + } + + if ((dest - 1) != fullpath) { + dest--; + } + + while ((dest > fullpath) && (*(dest - 1) != '/')) { + dest--; + } + + if (*src == '/') { + src++; + } + } + + *dest = '\0'; + + /* remove '/' in the end of path if exist */ + + dest--; + + str_remove_path_end_slash(dest, fullpath); + return dest; +} + +static int vfs_normalize_path_parame_check(const char *filename, char **pathname) +{ + int namelen; + char *name = NULL; + + if (pathname == NULL) { + return -EINVAL; + } + + /* check parameters */ + + if (filename == NULL) { + *pathname = NULL; + return -EINVAL; + } + + namelen = vfs_strnlen(filename, PATH_MAX); + if (!namelen) { + *pathname = NULL; + return -EINVAL; + } else if (namelen >= PATH_MAX) { + *pathname = NULL; + return -ENAMETOOLONG; + } + + for (name = (char *)filename + namelen; ((name != filename) && (*name != '/')); name--) { + if (strlen(name) > NAME_MAX) { + *pathname = NULL; + return -ENAMETOOLONG; + } + } + + return namelen; +} + +static char *vfs_not_absolute_path(const char *directory, const char *filename, char **pathname, int namelen) +{ + int ret; + char *fullpath = NULL; + + /* 2: The position of the path character: / and the end character /0 */ + + if ((namelen > 1) && (filename[0] == '.') && (filename[1] == '/')) { + filename += 2; + } + + fullpath = (char *)malloc(strlen(directory) + namelen + 2); + if (fullpath == NULL) { + *pathname = NULL; + set_errno(ENOMEM); + return (char *)NULL; + } + + /* join path and file name */ + + ret = snprintf_s(fullpath, strlen(directory) + namelen + 2, strlen(directory) + namelen + 1, + "%s/%s", directory, filename); + if (ret < 0) { + *pathname = NULL; + free(fullpath); + set_errno(ENAMETOOLONG); + return (char *)NULL; + } + + return fullpath; +} + +static char *vfs_normalize_fullpath(const char *directory, const char *filename, char **pathname, int namelen) +{ + char *fullpath = NULL; + + if (filename[0] != '/') { + /* not a absolute path */ + + fullpath = vfs_not_absolute_path(directory, filename, pathname, namelen); + if (fullpath == NULL) { + return (char *)NULL; + } + } else { + /* it's a absolute path, use it directly */ + + fullpath = strdup(filename); /* copy string */ + if (fullpath == NULL) { + *pathname = NULL; + set_errno(ENOMEM); + return (char *)NULL; + } + if (filename[1] == '/') { + *pathname = NULL; + free(fullpath); + set_errno(EINVAL); + return (char *)NULL; + } + } + + return fullpath; +} + +int vfs_normalize_path(const char *directory, const char *filename, char **pathname) +{ + char *fullpath = NULL; + int namelen; +#ifdef VFS_USING_WORKDIR + UINTPTR lock_flags; + LosProcessCB *curr = OsCurrProcessGet(); + BOOL dir_flags = (directory == NULL) ? TRUE : FALSE; +#endif + + namelen = vfs_normalize_path_parame_check(filename, pathname); + if (namelen < 0) { + return namelen; + } + +#ifdef VFS_USING_WORKDIR + if (directory == NULL) { + spin_lock_irqsave(&curr->files->workdir_lock, lock_flags); + directory = curr->files->workdir; + } +#else + if ((directory == NULL) && (filename[0] != '/')) { + PRINT_ERR("NO_WORKING_DIR\n"); + *pathname = NULL; + return -EINVAL; + } +#endif + + /* 2: The position of the path character: / and the end character /0 */ + + if ((filename[0] != '/') && (strlen(directory) + namelen + 2 > TEMP_PATH_MAX)) { +#ifdef VFS_USING_WORKDIR + if (dir_flags == TRUE) { + spin_unlock_irqrestore(&curr->files->workdir_lock, lock_flags); + } +#endif + return -ENAMETOOLONG; + } + + fullpath = vfs_normalize_fullpath(directory, filename, pathname, namelen); +#ifdef VFS_USING_WORKDIR + if (dir_flags == TRUE) { + spin_unlock_irqrestore(&curr->files->workdir_lock, lock_flags); + } +#endif + if (fullpath == NULL) { + return -get_errno(); + } + + (void)str_path(fullpath); + (void)str_normalize_path(fullpath); + if (strlen(fullpath) >= PATH_MAX) { + *pathname = NULL; + free(fullpath); + return -ENAMETOOLONG; + } + + *pathname = fullpath; + return ENOERR; +} + +int vfs_normalize_pathat(int dirfd, const char *filename, char **pathname) +{ + /* Get path by dirfd */ + char *relativeoldpath = NULL; + char *fullpath = NULL; + int ret = 0; + + ret = get_path_from_fd(dirfd, &relativeoldpath); + if (ret < 0) { + return ret; + } + + ret = vfs_normalize_path((const char *)relativeoldpath, filename, &fullpath); + if (relativeoldpath) { + free(relativeoldpath); + } + + if (ret < 0) { + return ret; + } + + *pathname = fullpath; + return ret; +} + diff --git a/src/kernel_liteos_a/fs/vfs/operation/vfs_chattr.c b/src/kernel_liteos_a/fs/vfs/operation/vfs_chattr.c new file mode 100644 index 00000000..04caf82b --- /dev/null +++ b/src/kernel_liteos_a/fs/vfs/operation/vfs_chattr.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "capability_api.h" +#include "errno.h" +#include "fs/fs_operation.h" +#include "fs/file.h" +#include "string.h" +#include "stdlib.h" +#include "sys/stat.h" +#include "vnode.h" +#include "fs/mount.h" +#include + +/**************************************************************************** + * Static Functions + ****************************************************************************/ +/**************************************************************************** + * Name: chattr + * + * Returned Value: + * Zero on success; -1 on failure with errno set: + * + ****************************************************************************/ + +int chattr(const char *pathname, struct IATTR *attr) +{ + struct Vnode *vnode = NULL; + int ret; + + if (pathname == NULL || attr == NULL) { + set_errno(EINVAL); + return VFS_ERROR; + } + + VnodeHold(); + ret = VnodeLookup(pathname, &vnode, 0); + if (ret != LOS_OK) { + goto errout_with_lock; + } + + if ((vnode->originMount) && (vnode->originMount->mountFlags & MS_RDONLY)) { + ret = -EROFS; + goto errout_with_lock; + } + + /* The way we handle the stat depends on the type of vnode that we + * are dealing with. + */ + + if (vnode->vop != NULL && vnode->vop->Chattr != NULL) { + ret = vnode->vop->Chattr(vnode, attr); + } else { + ret = -ENOSYS; + } + VnodeDrop(); + + if (ret < 0) { + goto errout; + } + + return OK; + + /* Failure conditions always set the errno appropriately */ + +errout_with_lock: + VnodeDrop(); +errout: + set_errno(-ret); + return VFS_ERROR; +} diff --git a/src/kernel_liteos_a/fs/vfs/operation/vfs_check.c b/src/kernel_liteos_a/fs/vfs/operation/vfs_check.c new file mode 100644 index 00000000..d4aed072 --- /dev/null +++ b/src/kernel_liteos_a/fs/vfs/operation/vfs_check.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "errno.h" +#include "stdlib.h" +#include "string.h" +#include "dirent.h" +#include "unistd.h" +#include "sys/select.h" +#include "sys/stat.h" +#include "sys/prctl.h" +#include "fs/dirent_fs.h" +#include "vnode.h" + +/**************************************************************************** + * Name: fscheck + ****************************************************************************/ +int fscheck(const char *path) +{ + int ret; + struct Vnode *vnode = NULL; + struct fs_dirent_s *dir = NULL; + + /* Find the node matching the path. */ + VnodeHold(); + ret = VnodeLookup(path, &vnode, 0); + if (ret != OK) { + VnodeDrop(); + goto errout; + } + + dir = (struct fs_dirent_s *)zalloc(sizeof(struct fs_dirent_s)); + if (!dir) { + /* Insufficient memory to complete the operation. */ + ret = -ENOMEM; + VnodeDrop(); + goto errout; + } + + if (vnode->vop && vnode->vop->Fscheck) { + ret = vnode->vop->Fscheck(vnode, dir); + if (ret != OK) { + VnodeDrop(); + goto errout_with_direntry; + } + } else { + ret = -ENOSYS; + VnodeDrop(); + goto errout_with_direntry; + } + VnodeDrop(); + + free(dir); + return 0; + +errout_with_direntry: + free(dir); +errout: + set_errno(-ret); + return VFS_ERROR; +} diff --git a/src/kernel_liteos_a/fs/vfs/operation/vfs_cloexec.c b/src/kernel_liteos_a/fs/vfs/operation/vfs_cloexec.c new file mode 100644 index 00000000..f69edecb --- /dev/null +++ b/src/kernel_liteos_a/fs/vfs/operation/vfs_cloexec.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include "fs/file.h" +#include "fs/fs_operation.h" +#include "fs/fd_table.h" +#include "unistd.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ +void CloseOnExec(struct files_struct *files) +{ + int sysFd; + if ((files == NULL) || (files->fdt == NULL)) { + return; + } + + for (int i = 0; i < files->fdt->max_fds; i++) { + if (FD_ISSET(i, files->fdt->proc_fds) && + FD_ISSET(i, files->fdt->cloexec_fds)) { + sysFd = DisassociateProcessFd(i); + if (sysFd >= 0) { + close(sysFd); + } + + FreeProcessFd(i); + } + } +} + +void SetCloexecFlag(int procFd) +{ + struct fd_table_s *fdt = GetFdTable(); + if (fdt == NULL) { + return; + } + + FileTableLock(fdt); + FD_SET(procFd, fdt->cloexec_fds); + FileTableUnLock(fdt); + return; +} + +bool CheckCloexecFlag(int procFd) +{ + bool isCloexec = 0; + struct fd_table_s *fdt = GetFdTable(); + if (fdt == NULL) { + return false; + } + + FileTableLock(fdt); + isCloexec = FD_ISSET(procFd, fdt->cloexec_fds); + FileTableUnLock(fdt); + return isCloexec; +} + +void ClearCloexecFlag(int procFd) +{ + struct fd_table_s *fdt = GetFdTable(); + if (fdt == NULL) { + return; + } + + FileTableLock(fdt); + FD_CLR(procFd, fdt->cloexec_fds); + FileTableUnLock(fdt); + return; +} diff --git a/src/kernel_liteos_a/fs/vfs/operation/vfs_fallocate.c b/src/kernel_liteos_a/fs/vfs/operation/vfs_fallocate.c new file mode 100644 index 00000000..320df2d3 --- /dev/null +++ b/src/kernel_liteos_a/fs/vfs/operation/vfs_fallocate.c @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "assert.h" +#include "errno.h" +#include "fcntl.h" +#include "fs/file.h" +#include "sys/types.h" +#include "sched.h" +#include "unistd.h" +#include "vfs_config.h" + +/**************************************************************************** + * Name: file_fallocate + ****************************************************************************/ + +static ssize_t file_fallocate(struct file *filep, int mode, off_t offset, off_t len) +{ + int ret; + + if (len <= 0) { + ret = EINVAL; + goto errout; + } + + /* Was this file opened for write access? */ + + if (((unsigned int)(filep->f_oflags) & O_ACCMODE) == O_RDONLY) { + ret = -EACCES; + goto errout; + } + + if (!filep->ops || !filep->ops->fallocate) { + ret = -EBADF; + goto errout; + } + + /* Yes, then let the driver perform the fallocate */ + + ret = filep->ops->fallocate(filep, mode, offset, len); + if (ret < 0) { + goto errout; + } + + return ret; + +errout: + set_errno(-ret); + return VFS_ERROR; +} + +/*************************************************************************** + * Name: fallocate + * + * Description: + * The fallocate() function prepares or allocates a contiguous data area to the file. + * Thus the write file is guaranteed be contiguous and no allocation delay until the + * size reaches that size at least unless any other changes to the volume is performed. + * + * Parameters: + * fp Pointer to the open file object. + * mode Operation mode. only support FALLOC_FL_KEEP_SIZE. + * offset offset of the file to allocated. + * len The size to allocate for the file. + * + * Returned Value: + * On success, allocate contiguous data area to the file . On error, -1 is returned, and errno is set appro- + * priately: + * + * + ********************************************************************************************/ + +int fallocate(int fd, int mode, off_t offset, off_t len) +{ +#if CONFIG_NFILE_DESCRIPTORS > 0 + struct file *filep = NULL; +#endif + +/* Did we get a valid file descriptor? */ + +#if CONFIG_NFILE_DESCRIPTORS > 0 + if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS) +#endif + { + set_errno(EBADF); + return VFS_ERROR; + } + +#if CONFIG_NFILE_DESCRIPTORS > 0 + + /* The descriptor is in the right range to be a file descriptor... write to the file. */ + + int ret = fs_getfilep(fd, &filep); + if (ret < 0) { + /* The errno value has already been set */ + return VFS_ERROR; + } + + if (filep->f_oflags & O_DIRECTORY) { + set_errno(EBADF); + return VFS_ERROR; + } + + /* Perform the fallocate operation using the file descriptor as an index */ + return file_fallocate(filep, mode, offset, len); +#endif +} diff --git a/src/kernel_liteos_a/fs/vfs/operation/vfs_fallocate64.c b/src/kernel_liteos_a/fs/vfs/operation/vfs_fallocate64.c new file mode 100644 index 00000000..9686173c --- /dev/null +++ b/src/kernel_liteos_a/fs/vfs/operation/vfs_fallocate64.c @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "assert.h" +#include "errno.h" +#include "fcntl.h" +#include "fs/file.h" +#include "sched.h" +#include "sys/types.h" +#include "unistd.h" +#include "vfs_config.h" + +/**************************************************************************** + * Name: file_fallocate + ****************************************************************************/ + +ssize_t file_fallocate64(struct file *filep, int mode, off64_t offset, off64_t len) +{ + int ret; + int err; + + if (len <= 0) { + err = EINVAL; + goto errout; + } + + /* Was this file opened for write access? */ + + if (((unsigned int)(filep->f_oflags) & O_ACCMODE) == O_RDONLY) { + err = EACCES; + goto errout; + } + + /* Is a driver registered? Does it support the fallocate method? */ + if (!filep->ops || !filep->ops->fallocate64) { + err = EBADF; + goto errout; + } + + /* Yes, then let the driver perform the fallocate */ + + ret = filep->ops->fallocate64(filep, mode, offset, len); + if (ret < 0) { + err = -ret; + goto errout; + } + + return ret; + +errout: + set_errno(err); + return VFS_ERROR; +} + +/*************************************************************************** + * Name: fallocate + * + * Description: + * The fallocate() function prepares or allocates a contiguous data area to the file. + * Thus the write file is guaranteed be contiguous and no allocation delay until the + * size reaches that size at least unless any other changes to the volume is performed. + * + * Parameters: + * fp Pointer to the open file object. + * mode Operation mode. only support FALLOC_FL_KEEP_SIZE. + * offset offset of the file to allocated. + * len The size to allocate for the file. + * + * Returned Value: + * On success, allocate contiguous data area to the file . On error, -1 is returned, and errno is set appro- + * priately: + * + * + ********************************************************************************************/ + +int fallocate64(int fd, int mode, off64_t offset, off64_t len) +{ +#if CONFIG_NFILE_DESCRIPTORS > 0 + struct file *filep = NULL; +#endif + + /* Did we get a valid file descriptor? */ + +#if CONFIG_NFILE_DESCRIPTORS > 0 + if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS) +#endif + { + set_errno(EBADF); + return VFS_ERROR; + } + +#if CONFIG_NFILE_DESCRIPTORS > 0 + + /* The descriptor is in the right range to be a file descriptor... write + * to the file. + */ + + int ret = fs_getfilep(fd, &filep); + if (ret < 0) { + /* The errno value has already been set */ + return VFS_ERROR; + } + + if ((unsigned int)filep->f_oflags & O_DIRECTORY) { + set_errno(EBADF); + return VFS_ERROR; + } + + /* Perform the fallocate operation using the file descriptor as an index */ + return file_fallocate64(filep, mode, offset, len); +#endif +} diff --git a/src/kernel_liteos_a/fs/vfs/operation/vfs_fcntl.c b/src/kernel_liteos_a/fs/vfs/operation/vfs_fcntl.c new file mode 100644 index 00000000..11ec6b7a --- /dev/null +++ b/src/kernel_liteos_a/fs/vfs/operation/vfs_fcntl.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include "fs/file.h" +#include "fs/fd_table.h" +#include "fs/fs_operation.h" +#include "sys/types.h" +#include "sys/uio.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ +static int FcntlDupFd(int procfd, int leastFd) +{ + int sysfd = GetAssociatedSystemFd(procfd); + if ((sysfd < 0) || (sysfd >= CONFIG_NFILE_DESCRIPTORS)) { + return -EBADF; + } + + if (CheckProcessFd(leastFd) != OK) { + return -EINVAL; + } + + int dupFd = AllocLowestProcessFd(leastFd); + if (dupFd < 0) { + return -EMFILE; + } + + files_refer(sysfd); + AssociateSystemFd(dupFd, sysfd); + + return dupFd; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ +int VfsFcntl(int procfd, int cmd, ...) +{ + va_list ap; + int ret = 0; + + va_start(ap, cmd); + switch (cmd) { + case F_DUPFD: + { + int arg = va_arg(ap, int); + ret = FcntlDupFd(procfd, arg); + } + break; + case F_GETFD: + { + bool isCloexec = CheckCloexecFlag(procfd); + ret = isCloexec ? FD_CLOEXEC : 0; + } + break; + case F_SETFD: + { + int oflags = va_arg(ap, int); + if (oflags & FD_CLOEXEC) { + SetCloexecFlag(procfd); + } else { + ClearCloexecFlag(procfd); + } + } + break; + default: + ret = CONTINE_NUTTX_FCNTL; + break; + } + + va_end(ap); + return ret; +} diff --git a/src/kernel_liteos_a/fs/vfs/operation/vfs_force_umount.c b/src/kernel_liteos_a/fs/vfs/operation/vfs_force_umount.c new file mode 100644 index 00000000..3d7f4ed7 --- /dev/null +++ b/src/kernel_liteos_a/fs/vfs/operation/vfs_force_umount.c @@ -0,0 +1,487 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fs/mount.h" +#include "fs/dirent_fs.h" +#include "fs/file.h" +#include "vnode.h" +#include "path_cache.h" + +/* vnode operations returns EIO */ +static int ErrorVopCreate(struct Vnode *parent, const char *name, int mode, struct Vnode **vnode) +{ + (void)parent; + (void)name; + (void)mode; + (void)vnode; + return -EIO; +} + +static int ErrorVopLookup(struct Vnode *parent, const char *name, int len, struct Vnode **vnode) +{ + (void)parent; + (void)name; + (void)len; + (void)vnode; + return -EIO; +} + +static int ErrorVopOpen(struct Vnode *vnode, int fd, int mode, int flags) +{ + (void)vnode; + (void)fd; + (void)mode; + (void)flags; + return -EIO; +} + +static int ErrorVopClose(struct Vnode *vnode) +{ + (void)vnode; + /* already closed at force umount, do nothing here */ + return OK; +} + +static int ErrorVopReclaim(struct Vnode *vnode) +{ + (void)vnode; + return -EIO; +} + +static int ErrorVopUnlink(struct Vnode *parent, struct Vnode *vnode, const char *fileName) +{ + (void)parent; + (void)vnode; + (void)fileName; + return -EIO; +} + +static int ErrorVopRmdir(struct Vnode *parent, struct Vnode *vnode, const char *dirName) +{ + (void)parent; + (void)vnode; + (void)dirName; + return -EIO; +} + +static int ErrorVopMkdir(struct Vnode *parent, const char *dirName, mode_t mode, struct Vnode **vnode) +{ + (void)parent; + (void)dirName; + (void)mode; + (void)vnode; + return -EIO; +} + +static int ErrorVopReaddir(struct Vnode *vnode, struct fs_dirent_s *dir) +{ + (void)vnode; + (void)dir; + return -EIO; +} + +static int ErrorVopOpendir(struct Vnode *vnode, struct fs_dirent_s *dir) +{ + (void)vnode; + (void)dir; + return -EIO; +} + +static int ErrorVopRewinddir(struct Vnode *vnode, struct fs_dirent_s *dir) +{ + (void)vnode; + (void)dir; + return -EIO; +} + +static int ErrorVopClosedir(struct Vnode *vnode, struct fs_dirent_s *dir) +{ + (void)vnode; + (void)dir; + /* already closed at force umount, do nothing here */ + return OK; +} + +static int ErrorVopGetattr(struct Vnode *vnode, struct stat *st) +{ + (void)vnode; + (void)st; + return -EIO; +} + +static int ErrorVopSetattr(struct Vnode *vnode, struct stat *st) +{ + (void)vnode; + (void)st; + return -EIO; +} + +static int ErrorVopChattr(struct Vnode *vnode, struct IATTR *attr) +{ + (void)vnode; + (void)attr; + return -EIO; +} + +static int ErrorVopRename(struct Vnode *src, struct Vnode *dstParent, const char *srcName, const char *dstName) +{ + (void)src; + (void)dstParent; + (void)srcName; + (void)dstName; + return -EIO; +} + +static int ErrorVopTruncate(struct Vnode *vnode, off_t len) +{ + (void)vnode; + (void)len; + return -EIO; +} + +static int ErrorVopTruncate64(struct Vnode *vnode, off64_t len) +{ + (void)vnode; + (void)len; + return -EIO; +} + +static int ErrorVopFscheck(struct Vnode *vnode, struct fs_dirent_s *dir) +{ + (void)vnode; + (void)dir; + return -EIO; +} + +static int ErrorVopLink(struct Vnode *src, struct Vnode *dstParent, struct Vnode **dst, const char *dstName) +{ + (void)src; + (void)dstParent; + (void)dst; + (void)dstName; + return -EIO; +} + +static int ErrorVopSymlink(struct Vnode *parentVnode, struct Vnode **newVnode, const char *path, const char *target) +{ + (void)parentVnode; + (void)newVnode; + (void)path; + (void)target; + return -EIO; +} + +static ssize_t ErrorVopReadlink(struct Vnode *vnode, char *buffer, size_t bufLen) +{ + (void)vnode; + (void)buffer; + (void)bufLen; + return -EIO; +} + +static struct VnodeOps g_errorVnodeOps = { + .Create = ErrorVopCreate, + .Lookup = ErrorVopLookup, + .Open = ErrorVopOpen, + .Close = ErrorVopClose, + .Reclaim = ErrorVopReclaim, + .Unlink = ErrorVopUnlink, + .Rmdir = ErrorVopRmdir, + .Mkdir = ErrorVopMkdir, + .Readdir = ErrorVopReaddir, + .Opendir = ErrorVopOpendir, + .Rewinddir = ErrorVopRewinddir, + .Closedir = ErrorVopClosedir, + .Getattr = ErrorVopGetattr, + .Setattr = ErrorVopSetattr, + .Chattr = ErrorVopChattr, + .Rename = ErrorVopRename, + .Truncate = ErrorVopTruncate, + .Truncate64 = ErrorVopTruncate64, + .Fscheck = ErrorVopFscheck, + .Link = ErrorVopLink, + .Symlink = ErrorVopSymlink, + .Readlink = ErrorVopReadlink, +}; + +/* file operations returns EIO */ +static int ErrorFopOpen(struct file *filep) +{ + (void)filep; + return -EIO; +} + +static int ErrorFopClose(struct file *filep) +{ + (void)filep; + /* already closed at force umount, do nothing here */ + return OK; +} + +static ssize_t ErrorFopRead(struct file *filep, char *buffer, size_t buflen) +{ + (void)filep; + (void)buffer; + (void)buflen; + return -EIO; +} + +static ssize_t ErrorFopWrite(struct file *filep, const char *buffer, size_t buflen) +{ + (void)filep; + (void)buffer; + (void)buflen; + return -EIO; +} + +static off_t ErrorFopSeek(struct file *filep, off_t offset, int whence) +{ + (void)filep; + (void)offset; + (void)whence; + return -EIO; +} + +static int ErrorFopIoctl(struct file *filep, int cmd, unsigned long arg) +{ + (void)filep; + (void)cmd; + (void)arg; + return -EIO; +} + +static int ErrorFopMmap(struct file* filep, struct VmMapRegion *region) +{ + (void)filep; + (void)region; + return -EIO; +} + +static int ErrorFopPoll(struct file *filep, poll_table *fds) +{ + (void)filep; + (void)fds; + return -EIO; +} + +static int ErrorFopStat(struct file *filep, struct stat* st) +{ + (void)filep; + (void)st; + return -EIO; +} + +static int ErrorFopFallocate(struct file* filep, int mode, off_t offset, off_t len) +{ + (void)filep; + (void)mode; + (void)offset; + (void)len; + return -EIO; +} + +static int ErrorFopFallocate64(struct file *filep, int mode, off64_t offset, off64_t len) +{ + (void)filep; + (void)mode; + (void)offset; + (void)len; + return -EIO; +} + +static int ErrorFopFsync(struct file *filep) +{ + (void)filep; + return -EIO; +} + +static ssize_t ErrorFopReadpage(struct file *filep, char *buffer, size_t buflen) +{ + (void)filep; + (void)buffer; + (void)buflen; + return -EIO; +} + +static int ErrorFopUnlink(struct Vnode *vnode) +{ + (void)vnode; + return -EIO; +} + +static struct file_operations_vfs g_errorFileOps = { + .open = ErrorFopOpen, + .close = ErrorFopClose, + .read = ErrorFopRead, + .write = ErrorFopWrite, + .seek = ErrorFopSeek, + .ioctl = ErrorFopIoctl, + .mmap = ErrorFopMmap, + .poll = ErrorFopPoll, + .stat = ErrorFopStat, + .fallocate = ErrorFopFallocate, + .fallocate64 = ErrorFopFallocate64, + .fsync = ErrorFopFsync, + .readpage = ErrorFopReadpage, + .unlink = ErrorFopUnlink, +}; + +static struct Mount* GetDevMountPoint(const struct Vnode *dev) +{ + struct Mount *mnt = NULL; + LIST_HEAD *mntList = GetMountList(); + if (mntList == NULL) { + return NULL; + } + + LOS_DL_LIST_FOR_EACH_ENTRY(mnt, mntList, struct Mount, mountList) { + if (mnt->vnodeDev == dev) { + return mnt; + } + } + return NULL; +} + +static void DirPreClose(struct fs_dirent_s *dirp) +{ + struct Vnode *node = NULL; + if (dirp == NULL || dirp->fd_root == NULL) { + return; + } + + node = dirp->fd_root; + if (node->vop && node->vop->Closedir) { + node->vop->Closedir(node, dirp); + } +} + +static void FilePreClose(struct file *filep, const struct file_operations_vfs *ops) +{ + if (filep->f_oflags & O_DIRECTORY) { + DirPreClose(filep->f_dir); + return; + } + + if (ops && ops->close) { + ops->close(filep); + } +} + +static void FileDisableAndClean(const struct Mount *mnt) +{ + struct filelist *flist = &tg_filelist; + struct file *filep = NULL; + const struct file_operations_vfs *originOps = NULL; + + for (int i = 3; i < CONFIG_NFILE_DESCRIPTORS; i++) { + if (!get_bit(i)) { + continue; + } + filep = &flist->fl_files[i]; + if (filep == NULL || filep->f_vnode == NULL) { + continue; + } + if (filep->f_vnode->originMount != mnt) { + continue; + } + originOps = filep->ops; + filep->ops = &g_errorFileOps; + FilePreClose(filep, originOps); + } +} + +static void VnodeTryFree(struct Vnode *vnode) +{ + if (vnode->useCount == 0) { + VnodeFree(vnode); + return; + } + + VnodePathCacheFree(vnode); + LOS_ListDelete(&(vnode->hashEntry)); + LOS_ListDelete(&vnode->actFreeEntry); + + if (vnode->vop->Reclaim) { + vnode->vop->Reclaim(vnode); + } + vnode->vop = &g_errorVnodeOps; + vnode->fop = &g_errorFileOps; +} + +static void VnodeTryFreeAll(const struct Mount *mount) +{ + struct Vnode *vnode = NULL; + struct Vnode *nextVnode = NULL; + + LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(vnode, nextVnode, GetVnodeActiveList(), struct Vnode, actFreeEntry) { + if ((vnode->originMount != mount) || (vnode->flag & VNODE_FLAG_MOUNT_NEW)) { + continue; + } + VnodeTryFree(vnode); + } +} + +int ForceUmountDev(struct Vnode *dev) +{ + int ret; + struct Vnode *origin = NULL; + struct filelist *flist = &tg_filelist; + if (dev == NULL) { + return -EINVAL; + } + + (void)sem_wait(&flist->fl_sem); + VnodeHold(); + + struct Mount *mnt = GetDevMountPoint(dev); + if (mnt == NULL) { + VnodeDrop(); + (void)sem_post(&flist->fl_sem); + return -ENXIO; + } + origin = mnt->vnodeBeCovered; + + FileDisableAndClean(mnt); + VnodeTryFreeAll(mnt); + ret = mnt->ops->Unmount(mnt, &dev); + if (ret != OK) { + PRINT_ERR("unmount in fs failed, ret = %d, errno = %d\n", ret, errno); + } + + LOS_ListDelete(&mnt->mountList); + free(mnt); + origin->newMount = NULL; + origin->flag &= ~(VNODE_FLAG_MOUNT_ORIGIN); + + VnodeDrop(); + (void)sem_post(&flist->fl_sem); + + return OK; +} diff --git a/src/kernel_liteos_a/fs/vfs/operation/vfs_init.c b/src/kernel_liteos_a/fs/vfs/operation/vfs_init.c new file mode 100644 index 00000000..fbb88a07 --- /dev/null +++ b/src/kernel_liteos_a/fs/vfs/operation/vfs_init.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "disk_pri.h" +#include "fcntl.h" +#include "fs/file.h" +#include "fs/fs_operation.h" +#include "linux/spinlock.h" +#include "los_init.h" +#include "los_printf.h" +#include "fs/mount.h" +#include "path_cache.h" +#include "sys/statfs.h" +#include "unistd.h" +#include "vnode.h" + +void los_vfs_init(void) +{ + uint retval; + static bool g_vfs_init = false; + if (g_vfs_init) { + return; + } + +#ifdef LOSCFG_FS_FAT_DISK + spin_lock_init(&g_diskSpinlock); + spin_lock_init(&g_diskFatBlockSpinlock); +#endif + files_initialize(); + files_initlist(&tg_filelist); + + retval = VnodesInit(); + if (retval != LOS_OK) { + PRINT_ERR("los_vfs_init VnodeInit failed error %d\n", retval); + return; + } + + retval = PathCacheInit(); + if (retval != LOS_OK) { + PRINT_ERR("los_vfs_init PathCacheInit failed error %d\n", retval); + return; + } + retval = VnodeHashInit(); + if (retval != LOS_OK) { + PRINT_ERR("los_vfs_init VnodeHashInit failed error %d\n", retval); + return; + } + + retval = VnodeDevInit(); + if (retval != LOS_OK) { + PRINT_ERR("los_vfs_init VnodeDevInit failed error %d\n", retval); + return; + } + + g_vfs_init = true; +} + +LOS_MODULE_INIT(los_vfs_init, LOS_INIT_LEVEL_KMOD_BASIC); diff --git a/src/kernel_liteos_a/fs/vfs/operation/vfs_other.c b/src/kernel_liteos_a/fs/vfs/operation/vfs_other.c new file mode 100644 index 00000000..7495f5be --- /dev/null +++ b/src/kernel_liteos_a/fs/vfs/operation/vfs_other.c @@ -0,0 +1,802 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "errno.h" +#include "stdlib.h" +#include "string.h" +#include "dirent.h" +#include "unistd.h" +#include "sys/select.h" +#include "sys/mount.h" +#include "sys/stat.h" +#include "sys/statfs.h" +#include "sys/prctl.h" +#include "fs/fd_table.h" +#include "fs/file.h" +#include "linux/spinlock.h" +#include "los_process_pri.h" +#include "los_task_pri.h" +#include "capability_api.h" +#include "vnode.h" + +#define MAX_DIR_ENT 1024 +int fstat(int fd, struct stat *buf) +{ + struct file *filep = NULL; + + int ret = fs_getfilep(fd, &filep); + if (ret < 0) { + return VFS_ERROR; + } + + return stat(filep->f_path, buf); +} + +int fstat64(int fd, struct stat64 *buf) +{ + struct file *filep = NULL; + + int ret = fs_getfilep(fd, &filep); + if (ret < 0) { + return VFS_ERROR; + } + + return stat64(filep->f_path, buf); +} + +int lstat(const char *path, struct stat *buffer) +{ + return stat(path, buffer); +} + +int VfsVnodePermissionCheck(const struct Vnode *node, int accMode) +{ + uint fuid = node->uid; + uint fgid = node->gid; + uint fileMode = node->mode; + return VfsPermissionCheck(fuid, fgid, fileMode, accMode); +} + +int VfsPermissionCheck(uint fuid, uint fgid, uint fileMode, int accMode) +{ + uint uid = OsCurrUserGet()->effUserID; + mode_t tmpMode = fileMode; + + if (uid == fuid) { + tmpMode >>= USER_MODE_SHIFT; + } else if (LOS_CheckInGroups(fgid)) { + tmpMode >>= GROUP_MODE_SHIFT; + } + + tmpMode &= (READ_OP | WRITE_OP | EXEC_OP); + + if (((uint)accMode & tmpMode) == accMode) { + return 0; + } + + tmpMode = 0; + if (S_ISDIR(fileMode)) { + if (IsCapPermit(CAP_DAC_EXECUTE) + || (!((uint)accMode & WRITE_OP) && IsCapPermit(CAP_DAC_READ_SEARCH))) { + tmpMode |= EXEC_OP; + } + } else { + if (IsCapPermit(CAP_DAC_EXECUTE) && (fileMode & MODE_IXUGO)) { + tmpMode |= EXEC_OP; + } + } + + if (IsCapPermit(CAP_DAC_WRITE)) { + tmpMode |= WRITE_OP; + } + + if (IsCapPermit(CAP_DAC_READ_SEARCH)) { + tmpMode |= READ_OP; + } + + if (((uint)accMode & tmpMode) == accMode) { + return 0; + } + + return 1; +} + +#ifdef VFS_USING_WORKDIR +static int SetWorkDir(const char *dir, size_t len) +{ + errno_t ret; + uint lock_flags; + LosProcessCB *curr = OsCurrProcessGet(); + + spin_lock_irqsave(&curr->files->workdir_lock, lock_flags); + ret = strncpy_s(curr->files->workdir, PATH_MAX, dir, len); + curr->files->workdir[PATH_MAX - 1] = '\0'; + spin_unlock_irqrestore(&curr->files->workdir_lock, lock_flags); + if (ret != EOK) { + return -1; + } + + return 0; +} +#endif + +int chdir(const char *path) +{ + int ret; + char *fullpath = NULL; + char *fullpath_bak = NULL; + struct stat statBuff; + + if (!path) { + set_errno(EFAULT); + return -1; + } + + if (!strlen(path)) { + set_errno(ENOENT); + return -1; + } + + if (strlen(path) > PATH_MAX) { + set_errno(ENAMETOOLONG); + return -1; + } + + ret = vfs_normalize_path((const char *)NULL, path, &fullpath); + if (ret < 0) { + set_errno(-ret); + return -1; /* build path failed */ + } + fullpath_bak = fullpath; + ret = stat(fullpath, &statBuff); + if (ret < 0) { + free(fullpath_bak); + return -1; + } + + if (!S_ISDIR(statBuff.st_mode)) { + set_errno(ENOTDIR); + free(fullpath_bak); + return -1; + } + + if (VfsPermissionCheck(statBuff.st_uid, statBuff.st_gid, statBuff.st_mode, EXEC_OP)) { + set_errno(EACCES); + free(fullpath_bak); + return -1; + } + +#ifdef VFS_USING_WORKDIR + ret = SetWorkDir(fullpath, strlen(fullpath)); + if (ret != 0) { + PRINT_ERR("chdir path error!\n"); + ret = -1; + } +#endif + + /* release normalize directory path name */ + + free(fullpath_bak); + + return ret; +} + +/** + * this function is a POSIX compliant version, which will return current + * working directory. + * + * @param buf the returned current directory. + * @param size the buffer size. + * + * @return the returned current directory. + */ + +char *getcwd(char *buf, size_t n) +{ +#ifdef VFS_USING_WORKDIR + int ret; + unsigned int len; + UINTPTR lock_flags; + LosProcessCB *curr = OsCurrProcessGet(); +#endif + if (buf == NULL) { + set_errno(EINVAL); + return buf; + } +#ifdef VFS_USING_WORKDIR + spin_lock_irqsave(&curr->files->workdir_lock, lock_flags); + len = strlen(curr->files->workdir); + if (n <= len) { + set_errno(ERANGE); + spin_unlock_irqrestore(&curr->files->workdir_lock, lock_flags); + return NULL; + } + ret = memcpy_s(buf, n, curr->files->workdir, len + 1); + if (ret != EOK) { + set_errno(ENAMETOOLONG); + spin_unlock_irqrestore(&curr->files->workdir_lock, lock_flags); + return NULL; + } + spin_unlock_irqrestore(&curr->files->workdir_lock, lock_flags); +#else + PRINT_ERR("NO_WORKING_DIR\n"); +#endif + + return buf; +} + +int chmod(const char *path, mode_t mode) +{ + struct IATTR attr = {0}; + attr.attr_chg_mode = mode; + attr.attr_chg_valid = CHG_MODE; /* change mode */ + int ret; + + ret = chattr(path, &attr); + if (ret < 0) { + return VFS_ERROR; + } + + return OK; +} + +int chown(const char *pathname, uid_t owner, gid_t group) +{ + struct IATTR attr = {0}; + attr.attr_chg_valid = 0; + int ret; + + if (owner != (uid_t)-1) { + attr.attr_chg_uid = owner; + attr.attr_chg_valid |= CHG_UID; + } + if (group != (gid_t)-1) { + attr.attr_chg_gid = group; + attr.attr_chg_valid |= CHG_GID; + } + ret = chattr(pathname, &attr); + if (ret < 0) { + return VFS_ERROR; + } + + return OK; +} + +int access(const char *path, int amode) +{ + int ret; + struct stat buf; + struct statfs fsBuf; + + ret = statfs(path, &fsBuf); + if (ret != 0) { + if (get_errno() != ENOSYS) { + return VFS_ERROR; + } + /* dev has no statfs ops, need devfs to handle this in feature */ + } + + if ((fsBuf.f_flags & MS_RDONLY) && ((unsigned int)amode & W_OK)) { + set_errno(EROFS); + return VFS_ERROR; + } + + ret = stat(path, &buf); + if (ret != 0) { + return VFS_ERROR; + } + + if (VfsPermissionCheck(buf.st_uid, buf.st_gid, buf.st_mode, amode)) { + set_errno(EACCES); + return VFS_ERROR; + } + + return OK; +} + +static struct dirent **scandir_get_file_list(const char *dir, int *num, int(*filter)(const struct dirent *)) +{ + DIR *od = NULL; + int listSize = MAX_DIR_ENT; + int n = 0; + struct dirent **list = NULL; + struct dirent **newList = NULL; + struct dirent *ent = NULL; + struct dirent *p = NULL; + int err; + + od = opendir(dir); + if (od == NULL) { + return NULL; + } + + list = (struct dirent **)malloc(listSize * sizeof(struct dirent *)); + if (list == NULL) { + (void)closedir(od); + return NULL; + } + + for (ent = readdir(od); ent != NULL; ent = readdir(od)) { + if (filter && !filter(ent)) { + continue; + } + + if (n == listSize) { + listSize += MAX_DIR_ENT; + newList = (struct dirent **)malloc(listSize * sizeof(struct dirent *)); + if (newList == NULL) { + break; + } + + err = memcpy_s(newList, listSize * sizeof(struct dirent *), list, n * sizeof(struct dirent *)); + if (err != EOK) { + free(newList); + break; + } + free(list); + list = newList; + } + + p = (struct dirent *)malloc(sizeof(struct dirent)); + if (p == NULL) { + break; + } + + (void)memcpy_s((void *)p, sizeof(struct dirent), (void *)ent, sizeof(struct dirent)); + list[n] = p; + + n++; + } + + if (closedir(od) < 0) { + while (n--) { + free(list[n]); + } + free(list); + return NULL; + } + + *num = n; + return list; +} + +int scandir(const char *dir, struct dirent ***namelist, + int(*filter)(const struct dirent *), + int(*compar)(const struct dirent **, const struct dirent **)) +{ + int n = 0; + struct dirent **list = NULL; + + if ((dir == NULL) || (namelist == NULL)) { + return -1; + } + + list = scandir_get_file_list(dir, &n, filter); + if (list == NULL) { + return -1; + } + + /* Change to return to the array size */ + *namelist = (struct dirent **)malloc(n * sizeof(struct dirent *)); + if (*namelist == NULL && n > 0) { + *namelist = list; + } else if (*namelist != NULL) { + (void)memcpy_s(*namelist, n * sizeof(struct dirent *), list, n * sizeof(struct dirent *)); + free(list); + } else { + free(list); + } + + /* Sort array */ + + if (compar && *namelist) { + qsort((void *)*namelist, (size_t)n, sizeof(struct dirent *), (int (*)(const void *, const void *))*compar); + } + + return n; +} + +int alphasort(const struct dirent **a, const struct dirent **b) +{ + return strcoll((*a)->d_name, (*b)->d_name); +} + +char *rindex(const char *s, int c) +{ + if (s == NULL) { + return NULL; + } + + /* Don't bother tracing - strrchr can do that */ + return (char *)strrchr(s, c); +} + +static char *ls_get_fullpath(const char *path, struct dirent *pdirent) +{ + char *fullpath = NULL; + int ret; + + if (path[1] != '\0') { + /* 2, The position of the path character: / and the end character '/0' */ + fullpath = (char *)malloc(strlen(path) + strlen(pdirent->d_name) + 2); + if (fullpath == NULL) { + goto exit_with_nomem; + } + + /* 2, The position of the path character: / and the end character '/0' */ + ret = snprintf_s(fullpath, strlen(path) + strlen(pdirent->d_name) + 2, + strlen(path) + strlen(pdirent->d_name) + 1, "%s/%s", path, pdirent->d_name); + if (ret < 0) { + free(fullpath); + set_errno(ENAMETOOLONG); + return NULL; + } + } else { + /* 2, The position of the path character: / and the end character '/0' */ + fullpath = (char *)malloc(strlen(pdirent->d_name) + 2); + if (fullpath == NULL) { + goto exit_with_nomem; + } + + /* 2, The position of the path character: / and the end character '/0' */ + ret = snprintf_s(fullpath, strlen(pdirent->d_name) + 2, strlen(pdirent->d_name) + 1, + "/%s", pdirent->d_name); + if (ret < 0) { + free(fullpath); + set_errno(ENAMETOOLONG); + return NULL; + } + } + return fullpath; + +exit_with_nomem: + set_errno(ENOSPC); + return (char *)NULL; +} + +static void PrintFileInfo64(const struct stat64 *stat64Info, const char *name, const char *linkName) +{ + mode_t mode; + char str[UGO_NUMS][UGO_NUMS + 1] = {0}; + char dirFlag; + int i; + + for (i = 0; i < UGO_NUMS; i++) { + mode = stat64Info->st_mode >> (uint)(USER_MODE_SHIFT - i * UGO_NUMS); + str[i][0] = (mode & READ_OP) ? 'r' : '-'; + str[i][1] = (mode & WRITE_OP) ? 'w' : '-'; + str[i][UGO_NUMS - 1] = (mode & EXEC_OP) ? 'x' : '-'; + } + + if (S_ISDIR(stat64Info->st_mode)) { + dirFlag = 'd'; + } else if (S_ISLNK(stat64Info->st_mode)) { + dirFlag = 'l'; + } else { + dirFlag = '-'; + } + + if (S_ISLNK(stat64Info->st_mode)) { + PRINTK("%c%s%s%s %-8lld u:%-5d g:%-5d %-10s -> %s\n", dirFlag, + str[0], str[1], str[UGO_NUMS - 1], stat64Info->st_size, + stat64Info->st_uid, stat64Info->st_gid, name, linkName); + } else { + PRINTK("%c%s%s%s %-8lld u:%-5d g:%-5d %-10s\n", dirFlag, + str[0], str[1], str[UGO_NUMS - 1], stat64Info->st_size, + stat64Info->st_uid, stat64Info->st_gid, name); + } +} + +static void PrintFileInfo(const struct stat *statInfo, const char *name, const char *linkName) +{ + mode_t mode; + char str[UGO_NUMS][UGO_NUMS + 1] = {0}; + char dirFlag; + int i; + + for (i = 0; i < UGO_NUMS; i++) { + mode = statInfo->st_mode >> (uint)(USER_MODE_SHIFT - i * UGO_NUMS); + str[i][0] = (mode & READ_OP) ? 'r' : '-'; + str[i][1] = (mode & WRITE_OP) ? 'w' : '-'; + str[i][UGO_NUMS - 1] = (mode & EXEC_OP) ? 'x' : '-'; + } + + if (S_ISDIR(statInfo->st_mode)) { + dirFlag = 'd'; + } else if (S_ISLNK(statInfo->st_mode)) { + dirFlag = 'l'; + } else { + dirFlag = '-'; + } + + if (S_ISLNK(statInfo->st_mode)) { + PRINTK("%c%s%s%s %-8lld u:%-5d g:%-5d %-10s -> %s\n", dirFlag, + str[0], str[1], str[UGO_NUMS - 1], statInfo->st_size, + statInfo->st_uid, statInfo->st_gid, name, linkName); + } else { + PRINTK("%c%s%s%s %-8lld u:%-5d g:%-5d %-10s\n", dirFlag, + str[0], str[1], str[UGO_NUMS - 1], statInfo->st_size, + statInfo->st_uid, statInfo->st_gid, name); + } +} + +int LsFile(const char *path) +{ + struct stat64 stat64Info; + struct stat statInfo; + char linkName[NAME_MAX] = { 0 }; + + if (stat64(path, &stat64Info) == 0) { + if (S_ISLNK(stat64Info.st_mode)) { + readlink(path, linkName, NAME_MAX); + } + PrintFileInfo64(&stat64Info, path, (const char *)linkName); + } else if (stat(path, &statInfo) == 0) { + if (S_ISLNK(statInfo.st_mode)) { + readlink(path, linkName, NAME_MAX); + } + PrintFileInfo(&statInfo, path, (const char *)linkName); + } else { + return -1; + } + + return 0; +} + +int LsDir(const char *path) +{ + struct stat statInfo = { 0 }; + struct stat64 stat64Info = { 0 }; + char linkName[NAME_MAX] = { 0 }; + DIR *d = NULL; + char *fullpath = NULL; + char *fullpath_bak = NULL; + struct dirent *pdirent = NULL; + + d = opendir(path); + if (d == NULL) { + return -1; + } + + PRINTK("Directory %s:\n", path); + do { + pdirent = readdir(d); + if (pdirent == NULL) { + break; + } + if (!strcmp(pdirent->d_name, ".") || !strcmp(pdirent->d_name, "..")) { + continue; + } + (void)memset_s(&statInfo, sizeof(struct stat), 0, sizeof(struct stat)); + (void)memset_s(&stat64Info, sizeof(struct stat), 0, sizeof(struct stat)); + (void)memset_s(&linkName, sizeof(linkName), 0, sizeof(linkName)); + fullpath = ls_get_fullpath(path, pdirent); + if (fullpath == NULL) { + (void)closedir(d); + return -1; + } + + fullpath_bak = fullpath; + if (stat64(fullpath, &stat64Info) == 0) { + if (S_ISLNK(stat64Info.st_mode)) { + readlink(fullpath, linkName, NAME_MAX); + } + PrintFileInfo64(&stat64Info, pdirent->d_name, linkName); + } else if (stat(fullpath, &statInfo) == 0) { + if (S_ISLNK(statInfo.st_mode)) { + readlink(fullpath, linkName, NAME_MAX); + } + PrintFileInfo(&statInfo, pdirent->d_name, linkName); + } else { + PRINTK("BAD file: %s\n", pdirent->d_name); + } + free(fullpath_bak); + } while (1); + (void)closedir(d); + + return 0; +} + +void ls(const char *pathname) +{ + struct stat statInfo = { 0 }; + char *path = NULL; + int ret; + + if (pathname == NULL) { +#ifdef VFS_USING_WORKDIR + UINTPTR lock_flags; + LosProcessCB *curr = OsCurrProcessGet(); + + /* open current working directory */ + + spin_lock_irqsave(&curr->files->workdir_lock, lock_flags); + path = strdup(curr->files->workdir); + spin_unlock_irqrestore(&curr->files->workdir_lock, lock_flags); +#else + path = strdup("/"); +#endif + if (path == NULL) { + return; + } + } else { + ret = vfs_normalize_path(NULL, pathname, &path); + if (ret < 0) { + set_errno(-ret); + return; + } + } + + ret = stat(path, &statInfo); + if (ret < 0) { + perror("ls error"); + free(path); + return; + } + + if (statInfo.st_mode & S_IFDIR) { /* list all directory and file */ + ret = LsDir((pathname == NULL) ? path : pathname); + } else { /* show the file information */ + ret = LsFile(path); + } + if (ret < 0) { + perror("ls error"); + } + + free(path); + return; +} + + +char *realpath(const char *path, char *resolved_path) +{ + int ret, result; + char *new_path = NULL; + struct stat buf; + + ret = vfs_normalize_path(NULL, path, &new_path); + if (ret < 0) { + ret = -ret; + set_errno(ret); + return NULL; + } + + result = stat(new_path, &buf); + + if (resolved_path == NULL) { + if (result != ENOERR) { + free(new_path); + return NULL; + } + return new_path; + } + + ret = strcpy_s(resolved_path, PATH_MAX, new_path); + if (ret != EOK) { + ret = -ret; + set_errno(ret); + free(new_path); + return NULL; + } + + free(new_path); + if (result != ENOERR) { + return NULL; + } + return resolved_path; +} + +void lsfd(void) +{ + struct filelist *f_list = NULL; + unsigned int i = 3; /* file start fd */ + int ret; + struct Vnode *node = NULL; + + f_list = &tg_filelist; + + PRINTK(" fd filename\n"); + ret = sem_wait(&f_list->fl_sem); + if (ret < 0) { + PRINTK("sem_wait error, ret=%d\n", ret); + return; + } + + while (i < CONFIG_NFILE_DESCRIPTORS) { + node = files_get_openfile(i); + if (node) { + PRINTK("%5d %s\n", i, f_list->fl_files[i].f_path); + } + i++; + } + (void)sem_post(&f_list->fl_sem); +} + +mode_t GetUmask(void) +{ + return OsCurrProcessGet()->umask; +} + +mode_t SysUmask(mode_t mask) +{ + UINT32 intSave; + mode_t umask; + mode_t oldUmask; + umask = mask & UMASK_FULL; + SCHEDULER_LOCK(intSave); + oldUmask = OsCurrProcessGet()->umask; + OsCurrProcessGet()->umask = umask; + SCHEDULER_UNLOCK(intSave); + return oldUmask; +} + +#ifdef LOSCFG_CHROOT +int chroot(const char *path) +{ + int ret; + struct Vnode *vnode = NULL; + + if (!path) { + set_errno(EFAULT); + return VFS_ERROR; + } + + if (!strlen(path)) { + set_errno(ENOENT); + return VFS_ERROR; + } + + if (strlen(path) > PATH_MAX) { + set_errno(ENAMETOOLONG); + return VFS_ERROR; + } + VnodeHold(); + ret = VnodeLookup(path, &vnode, 0); + if (ret != LOS_OK) { + VnodeDrop(); + return ret; + } + + LosProcessCB *curr = OsCurrProcessGet(); + if ((curr->files == NULL) || (curr->files->rootVnode == NULL)) { + VnodeDrop(); + return VFS_ERROR; + } + if (curr->files->rootVnode->useCount > 0) { + curr->files->rootVnode->useCount--; + } + vnode->useCount++; + curr->files->rootVnode = vnode; + + VnodeDrop(); + return LOS_OK; +} +#endif diff --git a/src/kernel_liteos_a/fs/vfs/operation/vfs_preadv.c b/src/kernel_liteos_a/fs/vfs/operation/vfs_preadv.c new file mode 100644 index 00000000..97f8d0c0 --- /dev/null +++ b/src/kernel_liteos_a/fs/vfs/operation/vfs_preadv.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "sys/types.h" +#include "sys/uio.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +ssize_t preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset) +{ + return vfs_readv(fd, iov, iovcnt, &offset); +} diff --git a/src/kernel_liteos_a/fs/vfs/operation/vfs_procfd.c b/src/kernel_liteos_a/fs/vfs/operation/vfs_procfd.c new file mode 100644 index 00000000..17b6d58d --- /dev/null +++ b/src/kernel_liteos_a/fs/vfs/operation/vfs_procfd.c @@ -0,0 +1,476 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fs/file.h" +#include "los_process_pri.h" +#include "fs/fd_table.h" +#include "mqueue.h" +#ifdef LOSCFG_NET_LWIP_SACK +#include "lwip/sockets.h" +#endif + +void FileTableLock(struct fd_table_s *fdt) +{ + /* Take the semaphore (perhaps waiting) */ + while (sem_wait(&fdt->ft_sem) != 0) { + /* + * The only case that an error should occur here is if the wait was + * awakened by a signal. + */ + LOS_ASSERT(errno == EINTR); + } +} + +void FileTableUnLock(struct fd_table_s *fdt) +{ + int ret = sem_post(&fdt->ft_sem); + if (ret == -1) { + PRINTK("sem_post error, errno %d \n", get_errno()); + } +} + +static int AssignProcessFd(const struct fd_table_s *fdt, int minFd) +{ + if (minFd >= fdt->max_fds) { + set_errno(EINVAL); + return VFS_ERROR; + } + + /* search unused fd from table */ + for (int i = minFd; i < fdt->max_fds; i++) { + if (!FD_ISSET(i, fdt->proc_fds)) { + return i; + } + } + set_errno(EMFILE); + return VFS_ERROR; +} + +struct fd_table_s *GetFdTable(void) +{ + struct fd_table_s *fdt = NULL; + struct files_struct *procFiles = OsCurrProcessGet()->files; + + if (procFiles == NULL) { + return NULL; + } + + fdt = procFiles->fdt; + if ((fdt == NULL) || (fdt->ft_fds == NULL)) { + return NULL; + } + + return fdt; +} + +static bool IsValidProcessFd(struct fd_table_s *fdt, int procFd) +{ + if (fdt == NULL) { + return false; + } + if ((procFd < 0) || (procFd >= fdt->max_fds)) { + return false; + } + return true; +} + +void AssociateSystemFd(int procFd, int sysFd) +{ + struct fd_table_s *fdt = GetFdTable(); + + if (!IsValidProcessFd(fdt, procFd)) { + return; + } + + if (sysFd < 0) { + return; + } + + FileTableLock(fdt); + fdt->ft_fds[procFd].sysFd = sysFd; + FileTableUnLock(fdt); +} + +int CheckProcessFd(int procFd) +{ + struct fd_table_s *fdt = GetFdTable(); + + if (!IsValidProcessFd(fdt, procFd)) { + return VFS_ERROR; + } + + return OK; +} + +int GetAssociatedSystemFd(int procFd) +{ + struct fd_table_s *fdt = GetFdTable(); + + if (!IsValidProcessFd(fdt, procFd)) { + return VFS_ERROR; + } + + FileTableLock(fdt); + if (fdt->ft_fds[procFd].sysFd < 0) { + FileTableUnLock(fdt); + return VFS_ERROR; + } + int sysFd = fdt->ft_fds[procFd].sysFd; + FileTableUnLock(fdt); + + return sysFd; +} + +/* Occupy the procFd, there are three circumstances: + * 1.procFd is already associated, we need disassociate procFd with relevant sysfd. + * 2.procFd is not allocated, we occupy it immediately. + * 3.procFd is in open(), close(), dup() process, we return EBUSY immediately. + */ +int AllocSpecifiedProcessFd(int procFd) +{ + struct fd_table_s *fdt = GetFdTable(); + + if (!IsValidProcessFd(fdt, procFd)) { + return -EBADF; + } + + FileTableLock(fdt); + if (fdt->ft_fds[procFd].sysFd >= 0) { + /* Disassociate procFd */ + fdt->ft_fds[procFd].sysFd = -1; + FileTableUnLock(fdt); + return OK; + } + + if (FD_ISSET(procFd, fdt->proc_fds)) { + /* procFd in race condition */ + FileTableUnLock(fdt); + return -EBUSY; + } else { + /* Unused procFd */ + FD_SET(procFd, fdt->proc_fds); + } + + FileTableUnLock(fdt); + return OK; +} + +void FreeProcessFd(int procFd) +{ + struct fd_table_s *fdt = GetFdTable(); + + if (!IsValidProcessFd(fdt, procFd)) { + return; + } + + FileTableLock(fdt); + FD_CLR(procFd, fdt->proc_fds); + FD_CLR(procFd, fdt->cloexec_fds); + fdt->ft_fds[procFd].sysFd = -1; + FileTableUnLock(fdt); +} + +int DisassociateProcessFd(int procFd) +{ + struct fd_table_s *fdt = GetFdTable(); + + if (!IsValidProcessFd(fdt, procFd)) { + return VFS_ERROR; + } + + FileTableLock(fdt); + if (fdt->ft_fds[procFd].sysFd < 0) { + FileTableUnLock(fdt); + return VFS_ERROR; + } + int sysFd = fdt->ft_fds[procFd].sysFd; + if (procFd >= MIN_START_FD) { + fdt->ft_fds[procFd].sysFd = -1; + } + FileTableUnLock(fdt); + + return sysFd; +} + +int AllocProcessFd(void) +{ + return AllocLowestProcessFd(MIN_START_FD); +} + +int AllocLowestProcessFd(int minFd) +{ + struct fd_table_s *fdt = GetFdTable(); + + if (fdt == NULL) { + return VFS_ERROR; + } + + /* minFd should be a positive number,and 0,1,2 had be distributed to stdin,stdout,stderr */ + if (minFd < MIN_START_FD) { + minFd = MIN_START_FD; + } + + FileTableLock(fdt); + + int procFd = AssignProcessFd(fdt, minFd); + if (procFd == VFS_ERROR) { + FileTableUnLock(fdt); + return VFS_ERROR; + } + + /* occupy the fd set */ + FD_SET(procFd, fdt->proc_fds); + FileTableUnLock(fdt); + + return procFd; +} + +int AllocAndAssocProcessFd(int sysFd, int minFd) +{ + struct fd_table_s *fdt = GetFdTable(); + + if (fdt == NULL) { + return VFS_ERROR; + } + + /* minFd should be a positive number,and 0,1,2 had be distributed to stdin,stdout,stderr */ + if (minFd < MIN_START_FD) { + minFd = MIN_START_FD; + } + + FileTableLock(fdt); + + int procFd = AssignProcessFd(fdt, minFd); + if (procFd == VFS_ERROR) { + FileTableUnLock(fdt); + return VFS_ERROR; + } + + /* occupy the fd set */ + FD_SET(procFd, fdt->proc_fds); + fdt->ft_fds[procFd].sysFd = sysFd; + FileTableUnLock(fdt); + + return procFd; +} + +int AllocAndAssocSystemFd(int procFd, int minFd) +{ + struct fd_table_s *fdt = GetFdTable(); + + if (!IsValidProcessFd(fdt, procFd)) { + return VFS_ERROR; + } + + int sysFd = alloc_fd(minFd); + if (sysFd < 0) { + return VFS_ERROR; + } + + FileTableLock(fdt); + fdt->ft_fds[procFd].sysFd = sysFd; + FileTableUnLock(fdt); + + return sysFd; +} + +static void FdRefer(int sysFd) +{ + if ((sysFd > STDERR_FILENO) && (sysFd < CONFIG_NFILE_DESCRIPTORS)) { + files_refer(sysFd); + } +#if defined(LOSCFG_NET_LWIP_SACK) + if ((sysFd >= CONFIG_NFILE_DESCRIPTORS) && (sysFd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS))) { + socks_refer(sysFd); + } +#endif +#if defined(LOSCFG_COMPAT_POSIX) + if ((sysFd >= MQUEUE_FD_OFFSET) && (sysFd < (MQUEUE_FD_OFFSET + CONFIG_NQUEUE_DESCRIPTORS))) { + MqueueRefer(sysFd); + } +#endif +} + +static void FdClose(int sysFd, unsigned int targetPid) +{ + UINT32 intSave; + + if ((sysFd > STDERR_FILENO) && (sysFd < CONFIG_NFILE_DESCRIPTORS)) { + LosProcessCB *processCB = OS_PCB_FROM_PID(targetPid); + SCHEDULER_LOCK(intSave); + if (OsProcessIsInactive(processCB)) { + SCHEDULER_UNLOCK(intSave); + return; + } + SCHEDULER_UNLOCK(intSave); + + files_close_internal(sysFd, processCB); + } +#if defined(LOSCFG_NET_LWIP_SACK) + if ((sysFd >= CONFIG_NFILE_DESCRIPTORS) && (sysFd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS))) { + socks_close(sysFd); + } +#endif +#if defined(LOSCFG_COMPAT_POSIX) + if ((sysFd >= MQUEUE_FD_OFFSET) && (sysFd < (MQUEUE_FD_OFFSET + CONFIG_NQUEUE_DESCRIPTORS))) { + mq_close((mqd_t)sysFd); + } +#endif +} + +static struct fd_table_s *GetProcessFTable(unsigned int pid, sem_t *semId) +{ + UINT32 intSave; + struct files_struct *procFiles = NULL; + LosProcessCB *processCB = OS_PCB_FROM_PID(pid); + + SCHEDULER_LOCK(intSave); + if (OsProcessIsInactive(processCB)) { + SCHEDULER_UNLOCK(intSave); + return NULL; + } + + procFiles = processCB->files; + if (procFiles == NULL || procFiles->fdt == NULL) { + SCHEDULER_UNLOCK(intSave); + return NULL; + } + + *semId = procFiles->fdt->ft_sem; + SCHEDULER_UNLOCK(intSave); + + return procFiles->fdt; +} + +int CopyFdToProc(int fd, unsigned int targetPid) +{ +#if !defined(LOSCFG_NET_LWIP_SACK) && !defined(LOSCFG_COMPAT_POSIX) && !defined(LOSCFG_FS_VFS) + return -ENOSYS; +#else + int sysFd; + struct fd_table_s *fdt = NULL; + int procFd; + sem_t semId; + + if (OS_PID_CHECK_INVALID(targetPid)) { + return -EINVAL; + } + + sysFd = GetAssociatedSystemFd(fd); + if (sysFd < 0) { + return -EBADF; + } + + FdRefer(sysFd); + fdt = GetProcessFTable(targetPid, &semId); + if (fdt == NULL || fdt->ft_fds == NULL) { + FdClose(sysFd, targetPid); + return -EPERM; + } + + /* Take the semaphore (perhaps waiting) */ + if (sem_wait(&semId) != 0) { + /* Target process changed */ + FdClose(sysFd, targetPid); + return -ESRCH; + } + + procFd = AssignProcessFd(fdt, 3); // minfd is 3 + if (procFd < 0) { + if (sem_post(&semId) == -1) { + PRINT_ERR("sem_post error, errno %d \n", get_errno()); + } + FdClose(sysFd, targetPid); + return -EPERM; + } + + /* occupy the fd set */ + FD_SET(procFd, fdt->proc_fds); + fdt->ft_fds[procFd].sysFd = sysFd; + if (sem_post(&semId) == -1) { + PRINTK("sem_post error, errno %d \n", get_errno()); + } + + return procFd; +#endif +} + +int CloseProcFd(int procFd, unsigned int targetPid) +{ +#if !defined(LOSCFG_NET_LWIP_SACK) && !defined(LOSCFG_COMPAT_POSIX) && !defined(LOSCFG_FS_VFS) + return -ENOSYS; +#else + int sysFd; + struct fd_table_s *fdt = NULL; + sem_t semId; + + if (OS_PID_CHECK_INVALID(targetPid)) { + return -EINVAL; + } + + fdt = GetProcessFTable(targetPid, &semId); + if (fdt == NULL || fdt->ft_fds == NULL) { + return -EPERM; + } + + /* Take the semaphore (perhaps waiting) */ + if (sem_wait(&semId) != 0) { + /* Target process changed */ + return -ESRCH; + } + + if (!IsValidProcessFd(fdt, procFd)) { + if (sem_post(&semId) == -1) { + PRINTK("sem_post error, errno %d \n", get_errno()); + } + return -EPERM; + } + + sysFd = fdt->ft_fds[procFd].sysFd; + if (sysFd < 0) { + if (sem_post(&semId) == -1) { + PRINTK("sem_post error, errno %d \n", get_errno()); + } + return -EPERM; + } + + /* clean the fd set */ + FD_CLR(procFd, fdt->proc_fds); + FD_CLR(procFd, fdt->cloexec_fds); + fdt->ft_fds[procFd].sysFd = -1; + if (sem_post(&semId) == -1) { + PRINTK("sem_post error, errno %d \n", get_errno()); + } + FdClose(sysFd, targetPid); + + return 0; +#endif +} diff --git a/src/kernel_liteos_a/fs/vfs/operation/vfs_pwritev.c b/src/kernel_liteos_a/fs/vfs/operation/vfs_pwritev.c new file mode 100644 index 00000000..3b57eaab --- /dev/null +++ b/src/kernel_liteos_a/fs/vfs/operation/vfs_pwritev.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "sys/types.h" +#include "sys/uio.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +ssize_t pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset) +{ + return vfs_writev(fd, iov, iovcnt, &offset); +} diff --git a/src/kernel_liteos_a/fs/vfs/operation/vfs_readv.c b/src/kernel_liteos_a/fs/vfs/operation/vfs_readv.c new file mode 100644 index 00000000..a9861a52 --- /dev/null +++ b/src/kernel_liteos_a/fs/vfs/operation/vfs_readv.c @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "sys/types.h" +#include "sys/uio.h" +#include "unistd.h" +#include "string.h" +#include "stdlib.h" +#include "fs/file.h" +#include "user_copy.h" +#include "stdio.h" +#include "limits.h" + +static char *pread_buf_and_check(int fd, const struct iovec *iov, int iovcnt, ssize_t *totalbytesread, off_t *offset) +{ + char *buf = NULL; + size_t buflen = 0; + int i; + + if ((iov == NULL) || (iovcnt > IOV_MAX)) { + *totalbytesread = VFS_ERROR; + return NULL; + } + + for (i = 0; i < iovcnt; ++i) { + if (SSIZE_MAX - buflen < iov[i].iov_len) { + set_errno(EINVAL); + return NULL; + } + buflen += iov[i].iov_len; + } + + if (buflen == 0) { + *totalbytesread = 0; + return NULL; + } + +#ifdef LOSCFG_KERNEL_VM + buf = (char *)LOS_VMalloc(buflen * sizeof(char)); +#else + buf = (char *)malloc(buflen * sizeof(char)); +#endif + if (buf == NULL) { + set_errno(ENOMEM); + *totalbytesread = VFS_ERROR; + return buf; + } + + *totalbytesread = (offset == NULL) ? read(fd, buf, buflen) + : pread(fd, buf, buflen, *offset); + if ((*totalbytesread == VFS_ERROR) || (*totalbytesread == 0)) { +#ifdef LOSCFG_KERNEL_VM + LOS_VFree(buf); +#else + free(buf); +#endif + return NULL; + } + + return buf; +} + +ssize_t vfs_readv(int fd, const struct iovec *iov, int iovcnt, off_t *offset) +{ + int i; + int ret; + char *buf = NULL; + char *curbuf = NULL; + ssize_t bytestoread; + ssize_t totalbytesread = 0; + ssize_t bytesleft; + + buf = pread_buf_and_check(fd, iov, iovcnt, &totalbytesread, offset); + if (buf == NULL) { + return totalbytesread; + } + + curbuf = buf; + bytesleft = totalbytesread; + for (i = 0; i < iovcnt; ++i) { + bytestoread = iov[i].iov_len; + if (bytestoread == 0) { + continue; + } + + if (bytesleft <= bytestoread) { + ret = LOS_CopyFromKernel(iov[i].iov_base, bytesleft, curbuf, bytesleft); + bytesleft = ret; + goto out; + } + + ret = LOS_CopyFromKernel(iov[i].iov_base, bytestoread, curbuf, bytestoread); + if (ret != 0) { + bytesleft = bytesleft - (bytestoread - ret); + goto out; + } + bytesleft -= bytestoread; + curbuf += bytestoread; + } + +out: +#ifdef LOSCFG_KERNEL_VM + LOS_VFree(buf); +#else + free(buf); +#endif + if ((i == 0) && (ret == iov[i].iov_len)) { + /* failed in the first iovec copy, and 0 bytes copied */ + set_errno(EFAULT); + return VFS_ERROR; + } + + return totalbytesread - bytesleft; +} + +ssize_t readv(int fd, const struct iovec *iov, int iovcnt) +{ + return vfs_readv(fd, iov, iovcnt, NULL); +} diff --git a/src/kernel_liteos_a/fs/vfs/operation/vfs_utime.c b/src/kernel_liteos_a/fs/vfs/operation/vfs_utime.c new file mode 100644 index 00000000..cbe607f7 --- /dev/null +++ b/src/kernel_liteos_a/fs/vfs/operation/vfs_utime.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "errno.h" +#include "vfs_config.h" +#include "sys/stat.h" +#include "vnode.h" +#include "fs/mount.h" +#include "string.h" +#include "stdlib.h" +#include "utime.h" +#include + +/**************************************************************************** + * Global Functions + ****************************************************************************/ + +int utime(const char *path, const struct utimbuf *ptimes) +{ + int ret; + char *fullpath = NULL; + struct Vnode *vnode = NULL; + time_t cur_sec; + struct IATTR attr = {0}; + + /* Sanity checks */ + + if (path == NULL) { + ret = -EINVAL; + goto errout; + } + + if (!path[0]) { + ret = -ENOENT; + goto errout; + } + + ret = vfs_normalize_path((const char *)NULL, path, &fullpath); + if (ret < 0) { + goto errout; + } + + /* Get the vnode for this file */ + VnodeHold(); + ret = VnodeLookup(fullpath, &vnode, 0); + if (ret != LOS_OK) { + VnodeDrop(); + goto errout_with_path; + } + + if ((vnode->originMount) && (vnode->originMount->mountFlags & MS_RDONLY)) { + VnodeDrop(); + ret = -EROFS; + goto errout_with_path; + } + + if (vnode->vop && vnode->vop->Chattr) { + if (ptimes == NULL) { + /* get current seconds */ + cur_sec = time(NULL); + attr.attr_chg_atime = cur_sec; + attr.attr_chg_mtime = cur_sec; + } else { + attr.attr_chg_atime = ptimes->actime; + attr.attr_chg_mtime = ptimes->modtime; + } + attr.attr_chg_valid = CHG_ATIME | CHG_MTIME; + ret = vnode->vop->Chattr(vnode, &attr); + if (ret != OK) { + VnodeDrop(); + goto errout_with_path; + } + } else { + ret = -ENOSYS; + VnodeDrop(); + goto errout_with_path; + } + VnodeDrop(); + + /* Successfully stat'ed the file */ + free(fullpath); + + return OK; + + /* Failure conditions always set the errno appropriately */ + +errout_with_path: + free(fullpath); +errout: + + if (ret != 0) { + set_errno(-ret); + } + return VFS_ERROR; +} diff --git a/src/kernel_liteos_a/fs/vfs/operation/vfs_writev.c b/src/kernel_liteos_a/fs/vfs/operation/vfs_writev.c new file mode 100644 index 00000000..7638a650 --- /dev/null +++ b/src/kernel_liteos_a/fs/vfs/operation/vfs_writev.c @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "sys/types.h" +#include "sys/uio.h" +#include "unistd.h" +#include "string.h" +#include "stdlib.h" +#include "fs/file.h" +#include "user_copy.h" +#include "limits.h" + +static int iov_trans_to_buf(char *buf, ssize_t totallen, const struct iovec *iov, int iovcnt) +{ + int i; + size_t ret, writepart; + size_t bytestowrite; + char *writebuf = NULL; + char *curbuf = buf; + + for (i = 0; i < iovcnt; ++i) { + writebuf = (char *)iov[i].iov_base; + bytestowrite = iov[i].iov_len; + if (bytestowrite == 0) { + continue; + } + + if (totallen == 0) { + break; + } + + bytestowrite = (totallen < bytestowrite) ? totallen : bytestowrite; + ret = LOS_CopyToKernel(curbuf, bytestowrite, writebuf, bytestowrite); + if (ret != 0) { + if (ret == bytestowrite) { + set_errno(EFAULT); + return VFS_ERROR; + } else { + writepart = bytestowrite - ret; + curbuf += writepart; + break; + } + } + curbuf += bytestowrite; + totallen -= bytestowrite; + } + + return (int)((intptr_t)curbuf - (intptr_t)buf); +} + +ssize_t vfs_writev(int fd, const struct iovec *iov, int iovcnt, off_t *offset) +{ + int i, ret; + char *buf = NULL; + size_t buflen = 0; + size_t bytestowrite; + ssize_t totalbyteswritten; + size_t totallen; + + if ((iov == NULL) || (iovcnt > IOV_MAX)) { + return VFS_ERROR; + } + + for (i = 0; i < iovcnt; ++i) { + if (SSIZE_MAX - buflen < iov[i].iov_len) { + set_errno(EINVAL); + return VFS_ERROR; + } + buflen += iov[i].iov_len; + } + + if (buflen == 0) { + return 0; + } + + totallen = buflen * sizeof(char); +#ifdef LOSCFG_KERNEL_VM + buf = (char *)LOS_VMalloc(totallen); +#else + buf = (char *)malloc(totallen); +#endif + if (buf == NULL) { + return VFS_ERROR; + } + + ret = iov_trans_to_buf(buf, totallen, iov, iovcnt); + if (ret <= 0) { +#ifdef LOSCFG_KERNEL_VM + LOS_VFree(buf); +#else + free(buf); +#endif + return VFS_ERROR; + } + + bytestowrite = (ssize_t)ret; + totalbyteswritten = (offset == NULL) ? write(fd, buf, bytestowrite) + : pwrite(fd, buf, bytestowrite, *offset); +#ifdef LOSCFG_KERNEL_VM + LOS_VFree(buf); +#else + free(buf); +#endif + return totalbyteswritten; +} + +ssize_t writev(int fd, const struct iovec *iov, int iovcnt) +{ + return vfs_writev(fd, iov, iovcnt, NULL); +} diff --git a/src/kernel_liteos_a/fs/vfs/path_cache.c b/src/kernel_liteos_a/fs/vfs/path_cache.c new file mode 100644 index 00000000..a8e506f6 --- /dev/null +++ b/src/kernel_liteos_a/fs/vfs/path_cache.c @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "path_cache.h" +#include "los_config.h" +#include "los_hash.h" +#include "stdlib.h" +#include "limits.h" +#include "vnode.h" + +#define PATH_CACHE_HASH_MASK (LOSCFG_MAX_PATH_CACHE_SIZE - 1) +LIST_HEAD g_pathCacheHashEntrys[LOSCFG_MAX_PATH_CACHE_SIZE]; +#ifdef LOSCFG_DEBUG_VERSION +static int g_totalPathCacheHit = 0; +static int g_totalPathCacheTry = 0; +#define TRACE_TRY_CACHE() do { g_totalPathCacheTry++; } while (0) +#define TRACE_HIT_CACHE(pc) do { pc->hit++; g_totalPathCacheHit++; } while (0) + +void ResetPathCacheHitInfo(int *hit, int *try) +{ + *hit = g_totalPathCacheHit; + *try = g_totalPathCacheTry; + g_totalPathCacheHit = 0; + g_totalPathCacheTry = 0; +} +#else +#define TRACE_TRY_CACHE() +#define TRACE_HIT_CACHE(pc) +#endif + +int PathCacheInit(void) +{ + for (int i = 0; i < LOSCFG_MAX_PATH_CACHE_SIZE; i++) { + LOS_ListInit(&g_pathCacheHashEntrys[i]); + } + return LOS_OK; +} + +void PathCacheDump(void) +{ + PRINTK("-------->pathCache dump in\n"); + for (int i = 0; i < LOSCFG_MAX_PATH_CACHE_SIZE; i++) { + struct PathCache *pc = NULL; + LIST_HEAD *nhead = &g_pathCacheHashEntrys[i]; + + LOS_DL_LIST_FOR_EACH_ENTRY(pc, nhead, struct PathCache, hashEntry) { + PRINTK(" pathCache dump hash %d item %s %p %p %d\n", i, + pc->name, pc->parentVnode, pc->childVnode, pc->nameLen); + } + } + PRINTK("-------->pathCache dump out\n"); +} + +void PathCacheMemoryDump(void) +{ + int pathCacheNum = 0; + int nameSum = 0; + for (int i = 0; i < LOSCFG_MAX_PATH_CACHE_SIZE; i++) { + LIST_HEAD *dhead = &g_pathCacheHashEntrys[i]; + struct PathCache *dent = NULL; + + LOS_DL_LIST_FOR_EACH_ENTRY(dent, dhead, struct PathCache, hashEntry) { + pathCacheNum++; + nameSum += dent->nameLen; + } + } + PRINTK("pathCache number = %d\n", pathCacheNum); + PRINTK("pathCache memory size = %d(B)\n", pathCacheNum * sizeof(struct PathCache) + nameSum); +} + +static uint32_t NameHash(const char *name, int len, struct Vnode *dvp) +{ + uint32_t hash; + hash = LOS_HashFNV32aBuf(name, len, FNV1_32A_INIT); + hash = LOS_HashFNV32aBuf(&dvp, sizeof(struct Vnode *), hash); + return hash; +} + +static void PathCacheInsert(struct Vnode *parent, struct PathCache *cache, const char* name, int len) +{ + int hash = NameHash(name, len, parent) & PATH_CACHE_HASH_MASK; + LOS_ListAdd(&g_pathCacheHashEntrys[hash], &cache->hashEntry); +} + +struct PathCache *PathCacheAlloc(struct Vnode *parent, struct Vnode *vnode, const char *name, uint8_t len) +{ + struct PathCache *pc = NULL; + size_t pathCacheSize; + int ret; + + if (name == NULL || len > NAME_MAX || parent == NULL || vnode == NULL) { + return NULL; + } + pathCacheSize = sizeof(struct PathCache) + len + 1; + + pc = (struct PathCache*)zalloc(pathCacheSize); + if (pc == NULL) { + PRINT_ERR("pathCache alloc failed, no memory!\n"); + return NULL; + } + + ret = strncpy_s(pc->name, len + 1, name, len); + if (ret != LOS_OK) { + free(pc); + return NULL; + } + + pc->parentVnode = parent; + pc->nameLen = len; + pc->childVnode = vnode; + + LOS_ListAdd((&(parent->childPathCaches)), (&(pc->childEntry))); + LOS_ListAdd((&(vnode->parentPathCaches)), (&(pc->parentEntry))); + + PathCacheInsert(parent, pc, name, len); + + return pc; +} + +int PathCacheFree(struct PathCache *pc) +{ + if (pc == NULL) { + PRINT_ERR("pathCache free: invalid pathCache\n"); + return -ENOENT; + } + + LOS_ListDelete(&pc->hashEntry); + LOS_ListDelete(&pc->parentEntry); + LOS_ListDelete(&pc->childEntry); + free(pc); + + return LOS_OK; +} + +int PathCacheLookup(struct Vnode *parent, const char *name, int len, struct Vnode **vnode) +{ + struct PathCache *pc = NULL; + int hash = NameHash(name, len, parent) & PATH_CACHE_HASH_MASK; + LIST_HEAD *dhead = &g_pathCacheHashEntrys[hash]; + + TRACE_TRY_CACHE(); + LOS_DL_LIST_FOR_EACH_ENTRY(pc, dhead, struct PathCache, hashEntry) { + if (pc->parentVnode == parent && pc->nameLen == len && !strncmp(pc->name, name, len)) { + *vnode = pc->childVnode; + TRACE_HIT_CACHE(pc); + return LOS_OK; + } + } + return -ENOENT; +} + +static void FreeChildPathCache(struct Vnode *vnode) +{ + struct PathCache *item = NULL; + struct PathCache *nextItem = NULL; + + LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &(vnode->childPathCaches), struct PathCache, childEntry) { + PathCacheFree(item); + } +} + +static void FreeParentPathCache(struct Vnode *vnode) +{ + struct PathCache *item = NULL; + struct PathCache *nextItem = NULL; + + LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &(vnode->parentPathCaches), struct PathCache, parentEntry) { + PathCacheFree(item); + } +} + +void VnodePathCacheFree(struct Vnode *vnode) +{ + if (vnode == NULL) { + return; + } + FreeParentPathCache(vnode); + FreeChildPathCache(vnode); +} + +LIST_HEAD* GetPathCacheList() +{ + return g_pathCacheHashEntrys; +} diff --git a/src/kernel_liteos_a/fs/vfs/vfs_cmd/vfs_shellcmd.c b/src/kernel_liteos_a/fs/vfs/vfs_cmd/vfs_shellcmd.c new file mode 100644 index 00000000..b69a78af --- /dev/null +++ b/src/kernel_liteos_a/fs/vfs/vfs_cmd/vfs_shellcmd.c @@ -0,0 +1,1390 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_config.h" +#include "sys/mount.h" + +#ifdef LOSCFG_SHELL + +#include "los_typedef.h" +#include "shell.h" +#include "sys/stat.h" +#include "stdlib.h" +#include "unistd.h" +#include "fcntl.h" +#include "sys/statfs.h" +#include "stdio.h" +#include "pthread.h" + +#include "shcmd.h" +#include "securec.h" +#include "show.h" +#include "los_syscall.h" + +#include "los_process_pri.h" +#include +#include "fs/fs_operation.h" + +typedef enum { + RM_RECURSIVER, + RM_FILE, + RM_DIR, + CP_FILE, + CP_COUNT +} wildcard_type; + +#define ERROR_OUT_IF(condition, message_function, handler) \ + do { \ + if (condition) { \ + message_function; \ + handler; \ + } \ + } while (0) + +static inline void set_err(int errcode, const char *err_message) +{ + set_errno(errcode); + perror(err_message); +} + +int osShellCmdDoChdir(const char *path) +{ + char *fullpath = NULL; + char *fullpath_bak = NULL; + int ret; + char *shell_working_directory = OsShellGetWorkingDirectory(); + if (shell_working_directory == NULL) { + return -1; + } + + if (path == NULL) { + LOS_TaskLock(); + PRINTK("%s\n", shell_working_directory); + LOS_TaskUnlock(); + + return 0; + } + + ERROR_OUT_IF(strlen(path) > PATH_MAX, set_err(ENOTDIR, "cd error"), return -1); + + ret = vfs_normalize_path(shell_working_directory, path, &fullpath); + ERROR_OUT_IF(ret < 0, set_err(-ret, "cd error"), return -1); + + fullpath_bak = fullpath; + ret = chdir(fullpath); + if (ret < 0) { + free(fullpath_bak); + perror("cd"); + return -1; + } + + /* copy full path to working directory */ + + LOS_TaskLock(); + ret = strncpy_s(shell_working_directory, PATH_MAX, fullpath, strlen(fullpath)); + if (ret != EOK) { + free(fullpath_bak); + LOS_TaskUnlock(); + return -1; + } + LOS_TaskUnlock(); + /* release normalize directory path name */ + + free(fullpath_bak); + + return 0; +} + +int osShellCmdLs(int argc, const char **argv) +{ + char *fullpath = NULL; + const char *filename = NULL; + int ret; + char *shell_working_directory = OsShellGetWorkingDirectory(); + if (shell_working_directory == NULL) { + return -1; + } + + ERROR_OUT_IF(argc > 1, PRINTK("ls or ls [DIRECTORY]\n"), return -1); + + if (argc == 0) { + ls(shell_working_directory); + return 0; + } + + filename = argv[0]; + ret = vfs_normalize_path(shell_working_directory, filename, &fullpath); + ERROR_OUT_IF(ret < 0, set_err(-ret, "ls error"), return -1); + + ls(fullpath); + free(fullpath); + + return 0; +} + +int osShellCmdCd(int argc, const char **argv) +{ + if (argc == 0) { + (void)osShellCmdDoChdir("/"); + return 0; + } + + (void)osShellCmdDoChdir(argv[0]); + + return 0; +} + +#define CAT_BUF_SIZE 512 +#define CAT_TASK_PRIORITY 10 +#define CAT_TASK_STACK_SIZE 0x3000 +pthread_mutex_t g_mutex_cat = PTHREAD_MUTEX_INITIALIZER; + +int osShellCmdDoCatShow(UINTPTR arg) +{ + int ret = 0; + char buf[CAT_BUF_SIZE]; + size_t size, written, toWrite; + ssize_t cnt; + char *fullpath = (char *)arg; + FILE *ini = NULL; + + (void)pthread_mutex_lock(&g_mutex_cat); + ini = fopen(fullpath, "r"); + if (ini == NULL) { + ret = -1; + perror("cat error"); + goto out; + } + + do { + (void)memset_s(buf, sizeof(buf), 0, CAT_BUF_SIZE); + size = fread(buf, 1, CAT_BUF_SIZE, ini); + if ((int)size < 0) { + ret = -1; + perror("cat error"); + goto out_with_fclose; + } + + for (toWrite = size, written = 0; toWrite > 0;) { + cnt = write(1, buf + written, toWrite); + if (cnt == 0) { + /* avoid task-starvation */ + (void)LOS_TaskDelay(1); + continue; + } else if (cnt < 0) { + perror("cat write error"); + break; + } + + written += cnt; + toWrite -= cnt; + } + } + while (size > 0); + +out_with_fclose: + (void)fclose(ini); +out: + free(fullpath); + (void)pthread_mutex_unlock(&g_mutex_cat); + return ret; +} + +int osShellCmdCat(int argc, const char **argv) +{ + char *fullpath = NULL; + int ret; + unsigned int ca_task; + struct Vnode *vnode = NULL; + TSK_INIT_PARAM_S init_param; + char *shell_working_directory = OsShellGetWorkingDirectory(); + if (shell_working_directory == NULL) { + return -1; + } + + ERROR_OUT_IF(argc != 1, PRINTK("cat [FILE]\n"), return -1); + + ret = vfs_normalize_path(shell_working_directory, argv[0], &fullpath); + ERROR_OUT_IF(ret < 0, set_err(-ret, "cat error"), return -1); + + VnodeHold(); + ret = VnodeLookup(fullpath, &vnode, O_RDONLY); + if (ret != LOS_OK) { + set_errno(-ret); + perror("cat error"); + VnodeDrop(); + free(fullpath); + return -1; + } + if (vnode->type != VNODE_TYPE_REG) { + set_errno(EINVAL); + perror("cat error"); + VnodeDrop(); + free(fullpath); + return -1; + } + VnodeDrop(); + (void)memset_s(&init_param, sizeof(init_param), 0, sizeof(TSK_INIT_PARAM_S)); + init_param.pfnTaskEntry = (TSK_ENTRY_FUNC)osShellCmdDoCatShow; + init_param.usTaskPrio = CAT_TASK_PRIORITY; + init_param.auwArgs[0] = (UINTPTR)fullpath; + init_param.uwStackSize = CAT_TASK_STACK_SIZE; + init_param.pcName = "shellcmd_cat"; + init_param.uwResved = LOS_TASK_STATUS_DETACHED | OS_TASK_FLAG_SPECIFIES_PROCESS; + + ret = (int)LOS_TaskCreate(&ca_task, &init_param); + if (ret != LOS_OK) { + free(fullpath); + } + + return ret; +} + +static int nfs_mount_ref(const char *server_ip_and_path, const char *mount_path, + unsigned int uid, unsigned int gid) __attribute__((weakref("nfs_mount"))); + +static unsigned long get_mountflags(const char *options) +{ + unsigned long mountfalgs = 0; + char *p; + while ((options != NULL) && (p = strsep((char**)&options, ",")) != NULL) { + if (strncmp(p, "ro", strlen("ro")) == 0) { + mountfalgs |= MS_RDONLY; + } else if (strncmp(p, "rw", strlen("rw")) == 0) { + mountfalgs &= ~MS_RDONLY; + } else if (strncmp(p, "nosuid", strlen("nosuid")) == 0) { + mountfalgs |= MS_NOSUID; + } else if (strncmp(p, "suid", strlen("suid")) == 0) { + mountfalgs &= ~MS_NOSUID; + } else { + continue; + } + } + + return mountfalgs; +} +static inline void print_mount_usage(void) +{ + PRINTK("mount [DEVICE] [PATH] [NAME]\n"); +} + +int osShellCmdMount(int argc, const char **argv) +{ + int ret; + char *fullpath = NULL; + const char *filename = NULL; + unsigned int gid, uid; + char *data = NULL; + char *filessystemtype = NULL; + unsigned long mountfalgs; + char *shell_working_directory = OsShellGetWorkingDirectory(); + if (shell_working_directory == NULL) { + return -1; + } + + ERROR_OUT_IF(argc < 3, print_mount_usage(), return OS_FAIL); + + if (strncmp(argv[0], "-t", 2) == 0 || strncmp(argv[0], "-o", 2) == 0) // 2: length of "-t" + { + if (argc < 4) { // 4: required number of parameters + PRINTK("mount -t/-o [DEVICE] [PATH] [NAME]\n"); + return -1; + } + + filename = argv[2]; // 2: index of file path + ret = vfs_normalize_path(shell_working_directory, filename, &fullpath); + ERROR_OUT_IF(ret < 0, set_err(-ret, "mount error"), return -1); + + if (strncmp(argv[3], "nfs", 3) == 0) { // 3: index of fs type + if (argc <= 6) { // 6: arguments include uid or gid + uid = ((argc >= 5) && (argv[4] != NULL)) ? (unsigned int)strtoul(argv[4], (char **)NULL, 0) : 0; + gid = ((argc == 6) && (argv[5] != NULL)) ? (unsigned int)strtoul(argv[5], (char **)NULL, 0) : 0; + + if (nfs_mount_ref != NULL) { + ret = nfs_mount_ref(argv[1], fullpath, uid, gid); + if (ret != LOS_OK) { + PRINTK("mount -t [DEVICE] [PATH] [NAME]\n"); + } + } else { + PRINTK("can't find nfs_mount\n"); + } + free(fullpath); + return 0; + } + } + + filessystemtype = (argc >= 4) ? (char *)argv[3] : NULL; /* 4: specify fs type, 3: fs type */ + mountfalgs = (argc >= 5) ? get_mountflags((const char *)argv[4]) : 0; /* 4: usr option */ + data = (argc >= 6) ? (char *)argv[5] : NULL; /* 5: usr option data, 6: six args needed for data */ + + if (strcmp(argv[1], "0") == 0) { + ret = mount((const char *)NULL, fullpath, filessystemtype, mountfalgs, data); + } else { + ret = mount(argv[1], fullpath, filessystemtype, mountfalgs, data); /* 3: fs type */ + } + if (ret != LOS_OK) { + perror("mount error"); + } else { + PRINTK("mount ok\n"); + } + } else { + filename = argv[1]; + ret = vfs_normalize_path(shell_working_directory, filename, &fullpath); + ERROR_OUT_IF(ret < 0, set_err(-ret, "mount error"), return -1); + + if (strncmp(argv[2], "nfs", 3) == 0) { // 2: index of fs type, 3: length of "nfs" + if (argc <= 5) { // 5: arguments include gid and uid + uid = ((argc >= 4) && (argv[3] != NULL)) ? (unsigned int)strtoul(argv[3], (char **)NULL, 0) : 0; + gid = ((argc == 5) && (argv[4] != NULL)) ? (unsigned int)strtoul(argv[4], (char **)NULL, 0) : 0; + + if (nfs_mount_ref != NULL) { + ret = nfs_mount_ref(argv[0], fullpath, uid, gid); + if (ret != LOS_OK) { + PRINTK("mount [DEVICE] [PATH] [NAME]\n"); + } + } else { + PRINTK("can't find nfs_mount\n"); + } + free(fullpath); + return 0; + } + + print_mount_usage(); + free(fullpath); + return 0; + } + + mountfalgs = (argc >= 4) ? get_mountflags((const char *)argv[3]) : 0; /* 3: usr option */ + data = (argc >= 5) ? (char *)argv[4] : NULL; /* 4: usr option data, 5: number of args needed for data */ + + if (strcmp(argv[0], "0") == 0) { + ret = mount((const char *)NULL, fullpath, argv[2], mountfalgs, data); + } else { + ret = mount(argv[0], fullpath, argv[2], mountfalgs, data); /* 2: fs type */ + } + if (ret != LOS_OK) { + perror("mount error"); + } else { + PRINTK("mount ok\n"); + } + } + + free(fullpath); + return 0; +} + +int osShellCmdUmount(int argc, const char **argv) +{ + int ret; + const char *filename = NULL; + char *fullpath = NULL; + char *target_path = NULL; + int cmp_num; + char *work_path = NULL; + char *shell_working_directory = OsShellGetWorkingDirectory(); + if (shell_working_directory == NULL) { + return -1; + } + work_path = shell_working_directory; + + ERROR_OUT_IF(argc == 0, PRINTK("umount [PATH]\n"), return 0); + + filename = argv[0]; + ret = vfs_normalize_path(shell_working_directory, filename, &fullpath); + ERROR_OUT_IF(ret < 0, set_err(-ret, "umount error"), return -1); + + target_path = fullpath; + cmp_num = strlen(fullpath); + ret = strncmp(work_path, target_path, cmp_num); + if (ret == 0) { + work_path += cmp_num; + if (*work_path == '/' || *work_path == '\0') { + set_errno(EBUSY); + perror("umount error"); + free(fullpath); + return -1; + } + } + + ret = umount(fullpath); + free(fullpath); + if (ret != LOS_OK) { + perror("umount error"); + return 0; + } + + PRINTK("umount ok\n"); + return 0; +} + +int osShellCmdMkdir(int argc, const char **argv) +{ + int ret; + char *fullpath = NULL; + const char *filename = NULL; + char *shell_working_directory = OsShellGetWorkingDirectory(); + if (shell_working_directory == NULL) { + return -1; + } + + ERROR_OUT_IF(argc != 1, PRINTK("mkdir [DIRECTORY]\n"), return 0); + + filename = argv[0]; + ret = vfs_normalize_path(shell_working_directory, filename, &fullpath); + ERROR_OUT_IF(ret < 0, set_err(-ret, "mkdir error"), return -1); + + ret = mkdir(fullpath, S_IRWXU | S_IRWXG | S_IRWXO); + if (ret == -1) { + perror("mkdir error"); + } + free(fullpath); + return 0; +} + +int osShellCmdPwd(int argc, const char **argv) +{ + char buf[SHOW_MAX_LEN] = {0}; + DIR *dir = NULL; + char *shell_working_directory = OsShellGetWorkingDirectory(); + if (shell_working_directory == NULL) { + return -1; + } + + ERROR_OUT_IF(argc > 0, PRINTK("\nUsage: pwd\n"), return -1); + + dir = opendir(shell_working_directory); + if (dir == NULL) { + perror("pwd error"); + return -1; + } + + LOS_TaskLock(); + if (strncpy_s(buf, SHOW_MAX_LEN, shell_working_directory, SHOW_MAX_LEN - 1) != EOK) { + LOS_TaskUnlock(); + PRINTK("pwd error: strncpy_s error!\n"); + (void)closedir(dir); + return -1; + } + LOS_TaskUnlock(); + + PRINTK("%s\n", buf); + (void)closedir(dir); + return 0; +} + +static inline void print_statfs_usage(void) +{ + PRINTK("Usage :\n"); + PRINTK(" statfs \n"); + PRINTK(" path : Mounted file system path that requires query information\n"); + PRINTK("Example:\n"); + PRINTK(" statfs /ramfs\n"); +} + +int osShellCmdStatfs(int argc, const char **argv) +{ + struct statfs sfs; + int result; + unsigned long long total_size, free_size; + char *fullpath = NULL; + const char *filename = NULL; + char *shell_working_directory = OsShellGetWorkingDirectory(); + if (shell_working_directory == NULL) { + return -1; + } + + ERROR_OUT_IF(argc != 1, PRINTK("statfs failed! Invalid argument!\n"), return -1); + + (void)memset_s(&sfs, sizeof(sfs), 0, sizeof(sfs)); + + filename = argv[0]; + result = vfs_normalize_path(shell_working_directory, filename, &fullpath); + ERROR_OUT_IF(result < 0, set_err(-result, "statfs error"), return -1); + + result = statfs(fullpath, &sfs); + free(fullpath); + + if (result != 0 || sfs.f_type == 0) { + PRINTK("statfs failed! Invalid argument!\n"); + print_statfs_usage(); + return -1; + } + + total_size = (unsigned long long)sfs.f_bsize * sfs.f_blocks; + free_size = (unsigned long long)sfs.f_bsize * sfs.f_bfree; + + PRINTK("statfs got:\n f_type = %d\n cluster_size = %d\n", sfs.f_type, sfs.f_bsize); + PRINTK(" total_clusters = %llu\n free_clusters = %llu\n", sfs.f_blocks, sfs.f_bfree); + PRINTK(" avail_clusters = %llu\n f_namelen = %d\n", sfs.f_bavail, sfs.f_namelen); + PRINTK("\n%s\n total size: %4llu Bytes\n free size: %4llu Bytes\n", argv[0], total_size, free_size); + + return 0; +} + +int osShellCmdTouch(int argc, const char **argv) +{ + int ret; + int fd = -1; + char *fullpath = NULL; + const char *filename = NULL; + char *shell_working_directory = OsShellGetWorkingDirectory(); + if (shell_working_directory == NULL) { + return -1; + } + + ERROR_OUT_IF(argc != 1, PRINTK("touch [FILE]\n"), return -1); + + filename = argv[0]; + ret = vfs_normalize_path(shell_working_directory, filename, &fullpath); + ERROR_OUT_IF(ret < 0, set_err(-ret, "touch error"), return -1); + + fd = open(fullpath, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + free(fullpath); + if (fd == -1) { + perror("touch error"); + return -1; + } + + (void)close(fd); + return 0; +} + +#define CP_BUF_SIZE 4096 +pthread_mutex_t g_mutex_cp = PTHREAD_MUTEX_INITIALIZER; + +static int os_shell_cmd_do_cp(const char *src_filepath, const char *dst_filename) +{ + int ret; + char *src_fullpath = NULL; + char *dst_fullpath = NULL; + const char *src_filename = NULL; + char *dst_filepath = NULL; + char *buf = NULL; + const char *filename = NULL; + ssize_t r_size, w_size; + int src_fd = -1; + int dst_fd = -1; + struct stat stat_buf; + mode_t src_mode; + char *shell_working_directory = OsShellGetWorkingDirectory(); + if (shell_working_directory == NULL) { + return -1; + } + + buf = (char *)malloc(CP_BUF_SIZE); + if (buf == NULL) { + PRINTK("cp error: Out of memory!\n"); + return -1; + } + + /* Get source fullpath. */ + + ret = vfs_normalize_path(shell_working_directory, src_filepath, &src_fullpath); + if (ret < 0) { + set_errno(-ret); + PRINTK("cp error: %s\n", strerror(errno)); + free(buf); + return -1; + } + + /* Is source path exist? */ + + ret = stat(src_fullpath, &stat_buf); + if (ret == -1) { + PRINTK("cp %s error: %s\n", src_fullpath, strerror(errno)); + goto errout_with_srcpath; + } + src_mode = stat_buf.st_mode; + /* Is source path a directory? */ + + if (S_ISDIR(stat_buf.st_mode)) { + PRINTK("cp %s error: Source file can't be a directory.\n", src_fullpath); + goto errout_with_srcpath; + } + + /* Get dest fullpath. */ + + dst_fullpath = strdup(dst_filename); + if (dst_fullpath == NULL) { + PRINTK("cp error: Out of memory.\n"); + goto errout_with_srcpath; + } + + /* Is dest path exist? */ + + ret = stat(dst_fullpath, &stat_buf); + if (ret == 0) { + /* Is dest path a directory? */ + + if (S_ISDIR(stat_buf.st_mode)) { + /* Get source file name without '/'. */ + + src_filename = src_filepath; + while (1) { + filename = strchr(src_filename, '/'); + if (filename == NULL) { + break; + } + src_filename = filename + 1; + } + + /* Add the source file after dest path. */ + + ret = vfs_normalize_path(dst_fullpath, src_filename, &dst_filepath); + if (ret < 0) { + set_errno(-ret); + PRINTK("cp error. %s.\n", strerror(errno)); + goto errout_with_path; + } + free(dst_fullpath); + dst_fullpath = dst_filepath; + } + } + + /* Is dest file same as source file? */ + + if (strcmp(src_fullpath, dst_fullpath) == 0) { + PRINTK("cp error: '%s' and '%s' are the same file\n", src_fullpath, dst_fullpath); + goto errout_with_path; + } + + /* Copy begins. */ + + (void)pthread_mutex_lock(&g_mutex_cp); + src_fd = open(src_fullpath, O_RDONLY); + if (src_fd < 0) { + PRINTK("cp error: can't open %s. %s.\n", src_fullpath, strerror(errno)); + goto errout_with_mutex; + } + + dst_fd = open(dst_fullpath, O_CREAT | O_WRONLY | O_TRUNC, src_mode); + if (dst_fd < 0) { + PRINTK("cp error: can't create %s. %s.\n", dst_fullpath, strerror(errno)); + goto errout_with_srcfd; + } + + do { + (void)memset_s(buf, CP_BUF_SIZE, 0, CP_BUF_SIZE); + r_size = read(src_fd, buf, CP_BUF_SIZE); + if (r_size < 0) { + PRINTK("cp %s %s failed. %s.\n", src_fullpath, dst_fullpath, strerror(errno)); + goto errout_with_fd; + } + w_size = write(dst_fd, buf, r_size); + if (w_size != r_size) { + PRINTK("cp %s %s failed. %s.\n", src_fullpath, dst_fullpath, strerror(errno)); + goto errout_with_fd; + } + } while (r_size == CP_BUF_SIZE); + + /* Release resource. */ + + free(buf); + free(src_fullpath); + free(dst_fullpath); + (void)close(src_fd); + (void)close(dst_fd); + (void)pthread_mutex_unlock(&g_mutex_cp); + return LOS_OK; + +errout_with_fd: + (void)close(dst_fd); +errout_with_srcfd: + (void)close(src_fd); +errout_with_mutex: + (void)pthread_mutex_unlock(&g_mutex_cp); +errout_with_path: + free(dst_fullpath); +errout_with_srcpath: + free(src_fullpath); + free(buf); + return -1; +} + +/* The separator and EOF for a directory fullpath: '/'and '\0' */ + +#define SEPARATOR_EOF_LEN 2 + +static int os_shell_cmd_do_rmdir(const char *pathname) +{ + struct dirent *dirent = NULL; + struct stat stat_info; + DIR *d = NULL; + char *fullpath = NULL; + int ret; + + (void)memset_s(&stat_info, sizeof(stat_info), 0, sizeof(struct stat)); + if (stat(pathname, &stat_info) != 0) { + return -1; + } + + if (S_ISREG(stat_info.st_mode) || S_ISLNK(stat_info.st_mode)) { + return remove(pathname); + } + d = opendir(pathname); + if (d == NULL) { + return -1; + } + while (1) { + dirent = readdir(d); + if (dirent == NULL) { + break; + } + if (strcmp(dirent->d_name, "..") && strcmp(dirent->d_name, ".")) { + size_t fullpath_buf_size = strlen(pathname) + strlen(dirent->d_name) + SEPARATOR_EOF_LEN; + fullpath = (char *)malloc(fullpath_buf_size); + if (fullpath == NULL) { + PRINTK("malloc failure!\n"); + (void)closedir(d); + return -1; + } + ret = snprintf_s(fullpath, fullpath_buf_size, fullpath_buf_size - 1, "%s/%s", pathname, dirent->d_name); + if (ret < 0) { + PRINTK("name is too long!\n"); + free(fullpath); + (void)closedir(d); + return -1; + } + (void)os_shell_cmd_do_rmdir(fullpath); + free(fullpath); + } + } + (void)closedir(d); + return rmdir(pathname); +} + +/* Wildcard matching operations */ + +static int os_wildcard_match(const char *src, const char *filename) +{ + int ret; + + if (*src != '\0') { + if (*filename == '*') { + while ((*filename == '*') || (*filename == '?')) { + filename++; + } + + if (*filename == '\0') { + return 0; + } + + while (*src != '\0' && !(*src == *filename)) { + src++; + } + + if (*src == '\0') { + return -1; + } + + ret = os_wildcard_match(src, filename); + + while ((ret != 0) && (*(++src) != '\0')) { + if (*src == *filename) { + ret = os_wildcard_match(src, filename); + } + } + return ret; + } else { + if ((*src == *filename) || (*filename == '?')) { + return os_wildcard_match(++src, ++filename); + } + return -1; + } + } + + while (*filename != '\0') { + if (*filename != '*') { + return -1; + } + filename++; + } + return 0; +} + +/* To determine whether a wildcard character exists in a path */ + +static int os_is_containers_wildcard(const char *filename) +{ + while (*filename != '\0') { + if ((*filename == '*') || (*filename == '?')) { + return 1; + } + filename++; + } + return 0; +} + +/* Delete a matching file or directory */ + +static int os_wildcard_delete_file_or_dir(const char *fullpath, wildcard_type mark) +{ + int ret; + + switch (mark) { + case RM_RECURSIVER: + ret = os_shell_cmd_do_rmdir(fullpath); + break; + case RM_FILE: + ret = unlink(fullpath); + break; + case RM_DIR: + ret = rmdir(fullpath); + break; + default: + return VFS_ERROR; + } + if (ret == -1) { + PRINTK("%s ", fullpath); + perror("rm/rmdir error!"); + return ret; + } + + PRINTK("%s match successful!delete!\n", fullpath); + return 0; +} + +/* Split the path with wildcard characters */ + +static char* os_wildcard_split_path(char *fullpath, char **handle, char **wait) +{ + int n = 0; + int a = 0; + int b = 0; + int len = strlen(fullpath); + + for (n = 0; n < len; n++) { + if (fullpath[n] == '/') { + if (b != 0) { + fullpath[n] = '\0'; + *wait = fullpath + n + 1; + break; + } + a = n; + } else if (fullpath[n] == '*' || fullpath[n] == '?') { + b = n; + fullpath[a] = '\0'; + if (a == 0) { + *handle = fullpath + a + 1; + continue; + } + *handle = fullpath + a + 1; + } + } + return fullpath; +} + +/* Handling entry of the path with wildcard characters */ + +static int os_wildcard_extract_directory(char *fullpath, void *dst, wildcard_type mark) +{ + char separator[] = "/"; + char src[PATH_MAX] = {0}; + struct dirent *dirent = NULL; + char *f = NULL; + char *s = NULL; + char *t = NULL; + int ret = 0; + DIR *d = NULL; + struct stat stat_buf; + int deleteFlag = 0; + + f = os_wildcard_split_path(fullpath, &s, &t); + + if (s == NULL) { + if (mark == CP_FILE) { + ret = os_shell_cmd_do_cp(fullpath, dst); + } else if (mark == CP_COUNT) { + ret = stat(fullpath, &stat_buf); + if (ret == 0 && (S_ISREG(stat_buf.st_mode) || S_ISLNK(stat_buf.st_mode))) { + (*(int *)dst)++; + } + } else { + ret = os_wildcard_delete_file_or_dir(fullpath, mark); + } + return ret; + } + + d = (*f == '\0') ? opendir("/") : opendir(f); + if (d == NULL) { + perror("opendir error"); + return VFS_ERROR; + } + + while (1) { + dirent = readdir(d); + if (dirent == NULL) { + break; + } + + ret = strcpy_s(src, PATH_MAX, f); + if (ret != EOK) { + goto closedir_out; + } + + ret = os_wildcard_match(dirent->d_name, s); + if (ret == 0) { + ret = strcat_s(src, sizeof(src), separator); + if (ret != EOK) { + goto closedir_out; + } + ret = strcat_s(src, sizeof(src), dirent->d_name); + if (ret != EOK) { + goto closedir_out; + } + if (t == NULL) { + if (mark == CP_FILE) { + ret = os_shell_cmd_do_cp(src, dst); + } else if (mark == CP_COUNT) { + ret = stat(src, &stat_buf); + if (ret == 0 && (S_ISREG(stat_buf.st_mode) || S_ISLNK(stat_buf.st_mode))) { + (*(int *)dst)++; + if ((*(int *)dst) > 1) { + break; + } + } + } else { + ret = os_wildcard_delete_file_or_dir(src, mark); + if (ret == 0) { + deleteFlag = 1; + } + } + } else { + ret = strcat_s(src, sizeof(src), separator); + if (ret != EOK) { + goto closedir_out; + } + ret = strcat_s(src, sizeof(src), t); + if (ret != EOK) { + goto closedir_out; + } + ret = os_wildcard_extract_directory(src, dst, mark); + if (mark == CP_COUNT && (*(int *)dst) > 1) { + break; + } + } + } + } + (void)closedir(d); + if (deleteFlag == 1) { + ret = 0; + } + return ret; +closedir_out: + (void)closedir(d); + return VFS_ERROR; +} + +int osShellCmdCp(int argc, const char **argv) +{ + int ret; + const char *src = NULL; + const char *dst = NULL; + char *src_fullpath = NULL; + char *dst_fullpath = NULL; + struct stat stat_buf; + int count = 0; + char *shell_working_directory = OsShellGetWorkingDirectory(); + if (shell_working_directory == NULL) { + return -1; + } + + ERROR_OUT_IF(argc < 2, PRINTK("cp [SOURCEFILE] [DESTFILE]\n"), return -1); + + src = argv[0]; + dst = argv[1]; + + /* Get source fullpath. */ + + ret = vfs_normalize_path(shell_working_directory, src, &src_fullpath); + if (ret < 0) { + set_errno(-ret); + PRINTK("cp error:%s\n", strerror(errno)); + return -1; + } + + if (src[strlen(src) - 1] == '/') { + PRINTK("cp %s error: Source file can't be a directory.\n", src); + goto errout_with_srcpath; + } + + /* Get dest fullpath. */ + + ret = vfs_normalize_path(shell_working_directory, dst, &dst_fullpath); + if (ret < 0) { + set_errno(-ret); + PRINTK("cp error: can't open %s. %s\n", dst, strerror(errno)); + goto errout_with_srcpath; + } + + /* Is dest path exist? */ + + ret = stat(dst_fullpath, &stat_buf); + if (ret < 0) { + /* Is dest path a directory? */ + + if (dst[strlen(dst) - 1] == '/') { + PRINTK("cp error: %s, %s.\n", dst_fullpath, strerror(errno)); + goto errout_with_path; + } + } else { + if ((S_ISREG(stat_buf.st_mode) || S_ISLNK(stat_buf.st_mode)) && dst[strlen(dst) - 1] == '/') { + PRINTK("cp error: %s is not a directory.\n", dst_fullpath); + goto errout_with_path; + } + } + + if (os_is_containers_wildcard(src_fullpath)) { + if (ret < 0 || S_ISREG(stat_buf.st_mode) || S_ISLNK(stat_buf.st_mode)) { + char *src_copy = strdup(src_fullpath); + if (src_copy == NULL) { + PRINTK("cp error : Out of memory.\n"); + goto errout_with_path; + } + (void)os_wildcard_extract_directory(src_copy, &count, CP_COUNT); + free(src_copy); + if (count > 1) { + PRINTK("cp error : %s is not a directory.\n", dst_fullpath); + goto errout_with_path; + } + } + ret = os_wildcard_extract_directory(src_fullpath, dst_fullpath, CP_FILE); + } else { + ret = os_shell_cmd_do_cp(src_fullpath, dst_fullpath); + } + free(dst_fullpath); + free(src_fullpath); + return ret; + +errout_with_path: + free(dst_fullpath); +errout_with_srcpath: + free(src_fullpath); + return VFS_ERROR; +} + +static inline void print_rm_usage(void) +{ + PRINTK("rm [FILE] or rm [-r/-R] [FILE]\n"); +} + +int osShellCmdRm(int argc, const char **argv) +{ + int ret = 0; + char *fullpath = NULL; + const char *filename = NULL; + char *shell_working_directory = OsShellGetWorkingDirectory(); + if (shell_working_directory == NULL) { + return -1; + } + + ERROR_OUT_IF(argc != 1 && argc != 2, print_rm_usage(), return -1); + + if (argc == 2) { // 2: arguments include "-r" or "-R" + ERROR_OUT_IF(strcmp(argv[0], "-r") != 0 && strcmp(argv[0], "-R") != 0, print_rm_usage(), return -1); + + filename = argv[1]; + ret = vfs_normalize_path(shell_working_directory, filename, &fullpath); + ERROR_OUT_IF(ret < 0, set_err(-ret, "rm error"), return -1); + + if (os_is_containers_wildcard(fullpath)) { + ret = os_wildcard_extract_directory(fullpath, NULL, RM_RECURSIVER); + } else { + ret = os_shell_cmd_do_rmdir(fullpath); + } + } else { + filename = argv[0]; + ret = vfs_normalize_path(shell_working_directory, filename, &fullpath); + ERROR_OUT_IF(ret < 0, set_err(-ret, "rm error"), return -1); + + if (os_is_containers_wildcard(fullpath)) { + ret = os_wildcard_extract_directory(fullpath, NULL, RM_FILE); + } else { + ret = unlink(fullpath); + } + } + if (ret == -1) { + perror("rm error"); + } + free(fullpath); + return 0; +} + +int osShellCmdRmdir(int argc, const char **argv) +{ + int ret; + char *fullpath = NULL; + const char *filename = NULL; + char *shell_working_directory = OsShellGetWorkingDirectory(); + if (shell_working_directory == NULL) { + return -1; + } + + ERROR_OUT_IF(argc == 0, PRINTK("rmdir [DIRECTORY]\n"), return -1); + + filename = argv[0]; + ret = vfs_normalize_path(shell_working_directory, filename, &fullpath); + ERROR_OUT_IF(ret < 0, set_err(-ret, "rmdir error"), return -1); + + if (os_is_containers_wildcard(fullpath)) { + ret = os_wildcard_extract_directory(fullpath, NULL, RM_DIR); + } else { + ret = rmdir(fullpath); + } + if (ret == -1) { + PRINTK("rmdir %s failed. Error: %s.\n", fullpath, strerror(errno)); + } + free(fullpath); + + return 0; +} + +int osShellCmdSync(int argc, const char **argv) +{ + ERROR_OUT_IF(argc > 0, PRINTK("\nUsage: sync\n"), return -1); + + sync(); + return 0; +} + +int osShellCmdLsfd(int argc, const char **argv) +{ + ERROR_OUT_IF(argc > 0, PRINTK("\nUsage: lsfd\n"), return -1); + + lsfd(); + + return 0; +} + +int checkNum(const char *arg) +{ + int i = 0; + if (arg == NULL) { + return -1; + } + if (arg[0] == '-') { + /* exclude the '-' */ + + i = 1; + } + for (; arg[i] != 0; i++) { + if (!isdigit(arg[i])) { + return -1; + } + } + return 0; +} + +#ifdef LOSCFG_KERNEL_SYSCALL +int osShellCmdSu(int argc, const char **argv) +{ + int su_uid; + int su_gid; + + if (argc == 0) { + /* for su root */ + + su_uid = 0; + su_gid = 0; + } else { + ERROR_OUT_IF((argc != 2), PRINTK("su [uid_num] [gid_num]\n"), return -1); + ERROR_OUT_IF((checkNum(argv[0]) != 0) || (checkNum(argv[1]) != 0), /* check argv is digit */ + PRINTK("check uid_num and gid_num is digit\n"), return -1); + + su_uid = atoi(argv[0]); + su_gid = atoi(argv[1]); + + ERROR_OUT_IF((su_uid < 0) || (su_uid > 60000) || (su_gid < 0) || + (su_gid > 60000), PRINTK("uid_num or gid_num out of range!they should be [0~60000]\n"), return -1); + } + + SysSetUserID(su_uid); + SysSetGroupID(su_gid); + return 0; +} +#endif + +int osShellCmdChmod(int argc, const char **argv) +{ + int i = 0; + int mode = 0; + int ret; + char *fullpath = NULL; + const char *filename = NULL; + struct IATTR attr = {0}; + char *shell_working_directory = NULL; + const char *p = NULL; +#define MODE_BIT 3 /* 3 bits express 1 mode */ + + ERROR_OUT_IF((argc != 2), PRINTK("Usage: chmod [FILE]\n"), return -1); + + p = argv[0]; + while (p[i]) { + if ((p[i] <= '7') && (p[i] >= '0')) { + mode = ((uint)mode << MODE_BIT) | (uint)(p[i] - '0'); + } else { + PRINTK("check the input \n"); + return -1; + } + i++; + } + filename = argv[1]; + + shell_working_directory = OsShellGetWorkingDirectory(); + if (shell_working_directory == NULL) { + return -1; + } + ret = vfs_normalize_path(shell_working_directory, filename, &fullpath); + ERROR_OUT_IF(ret < 0, set_err(-ret, "chmod error\n"), return -1); + + attr.attr_chg_mode = mode; + attr.attr_chg_valid = CHG_MODE; /* change mode */ + ret = chattr(fullpath, &attr); + if (ret < 0) { + free(fullpath); + PRINTK("chmod error! %s\n", strerror(errno)); + return ret; + } + + free(fullpath); + return 0; +} + +int osShellCmdChown(int argc, const char **argv) +{ + int ret; + char *fullpath = NULL; + const char *filename = NULL; + struct IATTR attr; + uid_t owner = -1; + gid_t group = -1; + attr.attr_chg_valid = 0; + + ERROR_OUT_IF(((argc != 2) && (argc != 3)), PRINTK("Usage: chown [OWNER] [GROUP] FILE\n"), return -1); + if (argc == 2) { // 2: chown owner of file + ERROR_OUT_IF((checkNum(argv[0]) != 0), PRINTK("check OWNER is digit\n"), return -1); + owner = atoi(argv[0]); + filename = argv[1]; + } + if (argc == 3) { // 3: chown both owner and group + ERROR_OUT_IF((checkNum(argv[0]) != 0), PRINTK("check OWNER is digit\n"), return -1); + ERROR_OUT_IF((checkNum(argv[1]) != 0), PRINTK("check GROUP is digit\n"), return -1); + owner = atoi(argv[0]); + group = atoi(argv[1]); + filename = argv[2]; + } + + if (group != -1) { + attr.attr_chg_gid = group; + attr.attr_chg_valid |= CHG_GID; + } + if (owner != -1) { + attr.attr_chg_uid = owner; + attr.attr_chg_valid |= CHG_UID; + } + + char *shell_working_directory = OsShellGetWorkingDirectory(); + if (shell_working_directory == NULL) { + return -1; + } + ret = vfs_normalize_path(shell_working_directory, filename, &fullpath); + ERROR_OUT_IF(ret < 0, set_err(-ret, "chown error\n"), return -1); + + ret = chattr(fullpath, &attr); + if (ret < 0) { + free(fullpath); + PRINTK("chown error! %s\n", strerror(errno)); + return ret; + } + + free(fullpath); + return 0; +} + +int osShellCmdChgrp(int argc, const char **argv) +{ + int ret; + char *fullpath = NULL; + const char *filename = NULL; + struct IATTR attr; + gid_t group; + attr.attr_chg_valid = 0; + ERROR_OUT_IF((argc != 2), PRINTK("Usage: chgrp GROUP FILE\n"), return -1); + ERROR_OUT_IF((checkNum(argv[0]) != 0), PRINTK("check GROUP is digit\n"), return -1); + group = atoi(argv[0]); + filename = argv[1]; + + if (group != -1) { + attr.attr_chg_gid = group; + attr.attr_chg_valid |= CHG_GID; + } + + char *shell_working_directory = OsShellGetWorkingDirectory(); + if (shell_working_directory == NULL) { + return -1; + } + ret = vfs_normalize_path(shell_working_directory, filename, &fullpath); + ERROR_OUT_IF(ret < 0, set_err(-ret, "chmod error"), return -1); + + ret = chattr(fullpath, &attr); + if (ret < 0) { + free(fullpath); + PRINTK("chgrp error! %s\n", strerror(errno)); + return ret; + } + + free(fullpath); + return 0; +} + +#ifdef LOSCFG_SHELL_CMD_DEBUG +SHELLCMD_ENTRY(lsfd_shellcmd, CMD_TYPE_EX, "lsfd", XARGS, (CmdCallBackFunc)osShellCmdLsfd); +SHELLCMD_ENTRY(statfs_shellcmd, CMD_TYPE_EX, "statfs", XARGS, (CmdCallBackFunc)osShellCmdStatfs); +SHELLCMD_ENTRY(touch_shellcmd, CMD_TYPE_EX, "touch", XARGS, (CmdCallBackFunc)osShellCmdTouch); +#ifdef LOSCFG_KERNEL_SYSCALL +SHELLCMD_ENTRY(su_shellcmd, CMD_TYPE_EX, "su", XARGS, (CmdCallBackFunc)osShellCmdSu); +#endif +#endif +SHELLCMD_ENTRY(sync_shellcmd, CMD_TYPE_EX, "sync", XARGS, (CmdCallBackFunc)osShellCmdSync); +SHELLCMD_ENTRY(ls_shellcmd, CMD_TYPE_EX, "ls", XARGS, (CmdCallBackFunc)osShellCmdLs); +SHELLCMD_ENTRY(pwd_shellcmd, CMD_TYPE_EX, "pwd", XARGS, (CmdCallBackFunc)osShellCmdPwd); +SHELLCMD_ENTRY(cd_shellcmd, CMD_TYPE_EX, "cd", XARGS, (CmdCallBackFunc)osShellCmdCd); +SHELLCMD_ENTRY(cat_shellcmd, CMD_TYPE_EX, "cat", XARGS, (CmdCallBackFunc)osShellCmdCat); +SHELLCMD_ENTRY(rm_shellcmd, CMD_TYPE_EX, "rm", XARGS, (CmdCallBackFunc)osShellCmdRm); +SHELLCMD_ENTRY(rmdir_shellcmd, CMD_TYPE_EX, "rmdir", XARGS, (CmdCallBackFunc)osShellCmdRmdir); +SHELLCMD_ENTRY(mkdir_shellcmd, CMD_TYPE_EX, "mkdir", XARGS, (CmdCallBackFunc)osShellCmdMkdir); +SHELLCMD_ENTRY(chmod_shellcmd, CMD_TYPE_EX, "chmod", XARGS, (CmdCallBackFunc)osShellCmdChmod); +SHELLCMD_ENTRY(chown_shellcmd, CMD_TYPE_EX, "chown", XARGS, (CmdCallBackFunc)osShellCmdChown); +SHELLCMD_ENTRY(chgrp_shellcmd, CMD_TYPE_EX, "chgrp", XARGS, (CmdCallBackFunc)osShellCmdChgrp); +SHELLCMD_ENTRY(mount_shellcmd, CMD_TYPE_EX, "mount", XARGS, (CmdCallBackFunc)osShellCmdMount); +SHELLCMD_ENTRY(umount_shellcmd, CMD_TYPE_EX, "umount", XARGS, (CmdCallBackFunc)osShellCmdUmount); +SHELLCMD_ENTRY(cp_shellcmd, CMD_TYPE_EX, "cp", XARGS, (CmdCallBackFunc)osShellCmdCp); +#endif diff --git a/src/kernel_liteos_a/fs/vfs/vnode.c b/src/kernel_liteos_a/fs/vfs/vnode.c new file mode 100644 index 00000000..9c6f58d3 --- /dev/null +++ b/src/kernel_liteos_a/fs/vfs/vnode.c @@ -0,0 +1,786 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_mux.h" +#include "fs/dirent_fs.h" +#include "path_cache.h" +#include "vnode.h" +#include "los_process.h" +#include "los_process_pri.h" + +LIST_HEAD g_vnodeFreeList; /* free vnodes list */ +LIST_HEAD g_vnodeVirtualList; /* dev vnodes list */ +LIST_HEAD g_vnodeActiveList; /* inuse vnodes list */ +static int g_freeVnodeSize = 0; /* system free vnodes size */ +static int g_totalVnodeSize = 0; /* total vnode size */ + +static LosMux g_vnodeMux; +static struct Vnode *g_rootVnode = NULL; +static struct VnodeOps g_devfsOps; + +#define ENTRY_TO_VNODE(ptr) LOS_DL_LIST_ENTRY(ptr, struct Vnode, actFreeEntry) +#define VNODE_LRU_COUNT 10 +#define DEV_VNODE_MODE 0755 + +int VnodesInit(void) +{ + int retval = LOS_MuxInit(&g_vnodeMux, NULL); + if (retval != LOS_OK) { + PRINT_ERR("Create mutex for vnode fail, status: %d", retval); + return retval; + } + + LOS_ListInit(&g_vnodeFreeList); + LOS_ListInit(&g_vnodeVirtualList); + LOS_ListInit(&g_vnodeActiveList); + retval = VnodeAlloc(NULL, &g_rootVnode); + if (retval != LOS_OK) { + PRINT_ERR("VnodeInit failed error %d\n", retval); + return retval; + } + g_rootVnode->mode = S_IRWXU | S_IRWXG | S_IRWXO | S_IFDIR; + g_rootVnode->type = VNODE_TYPE_DIR; + g_rootVnode->filePath = "/"; + +#ifdef LOSCFG_CHROOT + LosProcessCB *processCB = OsGetKernelInitProcess(); + if (processCB->files != NULL) { + g_rootVnode->useCount++; + processCB->files->rootVnode = g_rootVnode; + } +#endif + return LOS_OK; +} + +static struct Vnode *GetFromFreeList(void) +{ + if (g_freeVnodeSize <= 0) { + return NULL; + } + struct Vnode *vnode = NULL; + + if (LOS_ListEmpty(&g_vnodeFreeList)) { + PRINT_ERR("get vnode from free list failed, list empty but g_freeVnodeSize = %d!\n", g_freeVnodeSize); + g_freeVnodeSize = 0; + return NULL; + } + + vnode = ENTRY_TO_VNODE(LOS_DL_LIST_FIRST(&g_vnodeFreeList)); + LOS_ListDelete(&vnode->actFreeEntry); + g_freeVnodeSize--; + return vnode; +} + +struct Vnode *VnodeReclaimLru(void) +{ + struct Vnode *item = NULL; + struct Vnode *nextItem = NULL; + int releaseCount = 0; + + LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &g_vnodeActiveList, struct Vnode, actFreeEntry) { + if ((item->useCount > 0) || + (item->flag & VNODE_FLAG_MOUNT_ORIGIN) || + (item->flag & VNODE_FLAG_MOUNT_NEW)) { + continue; + } + + if (VnodeFree(item) == LOS_OK) { + releaseCount++; + } + if (releaseCount >= VNODE_LRU_COUNT) { + break; + } + } + + if (releaseCount == 0) { + PRINT_ERR("VnodeAlloc failed, vnode size hit max but can't reclaim anymore!\n"); + return NULL; + } + + item = GetFromFreeList(); + if (item == NULL) { + PRINT_ERR("VnodeAlloc failed, reclaim and get from free list failed!\n"); + } + return item; +} + +int VnodeAlloc(struct VnodeOps *vop, struct Vnode **newVnode) +{ + struct Vnode* vnode = NULL; + + VnodeHold(); + vnode = GetFromFreeList(); + if ((vnode == NULL) && g_totalVnodeSize < LOSCFG_MAX_VNODE_SIZE) { + vnode = (struct Vnode *)zalloc(sizeof(struct Vnode)); + g_totalVnodeSize++; + } + + if (vnode == NULL) { + vnode = VnodeReclaimLru(); + } + + if (vnode == NULL) { + *newVnode = NULL; + VnodeDrop(); + return -ENOMEM; + } + + vnode->type = VNODE_TYPE_UNKNOWN; + LOS_ListInit((&(vnode->parentPathCaches))); + LOS_ListInit((&(vnode->childPathCaches))); + LOS_ListInit((&(vnode->hashEntry))); + LOS_ListInit((&(vnode->actFreeEntry))); + + if (vop == NULL) { + LOS_ListAdd(&g_vnodeVirtualList, &(vnode->actFreeEntry)); + vnode->vop = &g_devfsOps; + } else { + LOS_ListTailInsert(&g_vnodeActiveList, &(vnode->actFreeEntry)); + vnode->vop = vop; + } + LOS_ListInit(&vnode->mapping.page_list); + LOS_SpinInit(&vnode->mapping.list_lock); + (VOID)LOS_MuxInit(&vnode->mapping.mux_lock, NULL); + vnode->mapping.host = vnode; + + VnodeDrop(); + + *newVnode = vnode; + + return LOS_OK; +} + +int VnodeFree(struct Vnode *vnode) +{ + if (vnode == NULL) { + return LOS_OK; + } + + VnodeHold(); + if (vnode->useCount > 0) { + VnodeDrop(); + return -EBUSY; + } + + VnodePathCacheFree(vnode); + LOS_ListDelete(&(vnode->hashEntry)); + LOS_ListDelete(&vnode->actFreeEntry); + + if (vnode->vop->Reclaim) { + vnode->vop->Reclaim(vnode); + } + + if (vnode->filePath) { + free(vnode->filePath); + } + if (vnode->vop == &g_devfsOps) { + /* for dev vnode, just free it */ + free(vnode->data); + free(vnode); + g_totalVnodeSize--; + } else { + /* for normal vnode, reclaim it to g_VnodeFreeList */ + (void)memset_s(vnode, sizeof(struct Vnode), 0, sizeof(struct Vnode)); + LOS_ListAdd(&g_vnodeFreeList, &vnode->actFreeEntry); + g_freeVnodeSize++; + } + VnodeDrop(); + + return LOS_OK; +} + +int VnodeFreeAll(const struct Mount *mount) +{ + struct Vnode *vnode = NULL; + struct Vnode *nextVnode = NULL; + int ret; + + LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(vnode, nextVnode, &g_vnodeActiveList, struct Vnode, actFreeEntry) { + if ((vnode->originMount == mount) && !(vnode->flag & VNODE_FLAG_MOUNT_NEW)) { + ret = VnodeFree(vnode); + if (ret != LOS_OK) { + return ret; + } + } + } + + return LOS_OK; +} + +BOOL VnodeInUseIter(const struct Mount *mount) +{ + struct Vnode *vnode = NULL; + + LOS_DL_LIST_FOR_EACH_ENTRY(vnode, &g_vnodeActiveList, struct Vnode, actFreeEntry) { + if (vnode->originMount == mount) { + if ((vnode->useCount > 0) || (vnode->flag & VNODE_FLAG_MOUNT_ORIGIN)) { + return TRUE; + } + } + } + return FALSE; +} + +int VnodeHold(void) +{ + int ret = LOS_MuxLock(&g_vnodeMux, LOS_WAIT_FOREVER); + if (ret != LOS_OK) { + PRINT_ERR("VnodeHold lock failed !\n"); + } + return ret; +} + +int VnodeDrop(void) +{ + int ret = LOS_MuxUnlock(&g_vnodeMux); + if (ret != LOS_OK) { + PRINT_ERR("VnodeDrop unlock failed !\n"); + } + return ret; +} + +static char *NextName(char *pos, uint8_t *len) +{ + char *name = NULL; + while (*pos != 0 && *pos == '/') { + pos++; + } + if (*pos == '\0') { + return NULL; + } + name = (char *)pos; + while (*pos != '\0' && *pos != '/') { + pos++; + } + *len = pos - name; + return name; +} + +static int PreProcess(const char *originPath, struct Vnode **startVnode, char **path) +{ + int ret; + char *absolutePath = NULL; + + ret = vfs_normalize_path(NULL, originPath, &absolutePath); + if (ret == LOS_OK) { + *startVnode = GetCurrRootVnode(); + *path = absolutePath; + } + + return ret; +} + +static struct Vnode *ConvertVnodeIfMounted(struct Vnode *vnode) +{ + if ((vnode == NULL) || !(vnode->flag & VNODE_FLAG_MOUNT_ORIGIN)) { + return vnode; + } +#ifdef LOSCFG_MNT_CONTAINER + LIST_HEAD *mntList = GetMountList(); + struct Mount *mnt = NULL; + LOS_DL_LIST_FOR_EACH_ENTRY(mnt, mntList, struct Mount, mountList) { + if ((mnt != NULL) && (mnt->vnodeBeCovered == vnode)) { + return mnt->vnodeCovered; + } + } + if (strcmp(vnode->filePath, "/dev") == 0) { + return vnode->newMount->vnodeCovered; + } + return vnode; +#else + return vnode->newMount->vnodeCovered; +#endif +} + +static void RefreshLRU(struct Vnode *vnode) +{ + if (vnode == NULL || (vnode->type != VNODE_TYPE_REG && vnode->type != VNODE_TYPE_DIR) || + vnode->vop == &g_devfsOps || vnode->vop == NULL) { + return; + } + LOS_ListDelete(&(vnode->actFreeEntry)); + LOS_ListTailInsert(&g_vnodeActiveList, &(vnode->actFreeEntry)); +} + +static int ProcessVirtualVnode(struct Vnode *parent, uint32_t flags, struct Vnode **vnode) +{ + int ret = -ENOENT; + if (flags & V_CREATE) { + // only create /dev/ vnode + ret = VnodeAlloc(NULL, vnode); + } + if (ret == LOS_OK) { + (*vnode)->parent = parent; + } + return ret; +} + +static int Step(char **currentDir, struct Vnode **currentVnode, uint32_t flags) +{ + int ret; + uint8_t len = 0; + struct Vnode *nextVnode = NULL; + char *nextDir = NULL; + + if ((*currentVnode)->type != VNODE_TYPE_DIR) { + return -ENOTDIR; + } + nextDir = NextName(*currentDir, &len); + if (nextDir == NULL) { + // there is '/' at the end of the *currentDir. + *currentDir = NULL; + return LOS_OK; + } + + ret = PathCacheLookup(*currentVnode, nextDir, len, &nextVnode); + if (ret == LOS_OK) { + goto STEP_FINISH; + } + + (*currentVnode)->useCount++; + if (flags & V_DUMMY) { + ret = ProcessVirtualVnode(*currentVnode, flags, &nextVnode); + } else { + if ((*currentVnode)->vop != NULL && (*currentVnode)->vop->Lookup != NULL) { + ret = (*currentVnode)->vop->Lookup(*currentVnode, nextDir, len, &nextVnode); + } else { + ret = -ENOSYS; + } + } + (*currentVnode)->useCount--; + + if (ret == LOS_OK) { + (void)PathCacheAlloc((*currentVnode), nextVnode, nextDir, len); + } + +STEP_FINISH: + nextVnode = ConvertVnodeIfMounted(nextVnode); + RefreshLRU(nextVnode); + + *currentDir = nextDir + len; + if (ret == LOS_OK) { + *currentVnode = nextVnode; + } + + return ret; +} + +int VnodeLookupAt(const char *path, struct Vnode **result, uint32_t flags, struct Vnode *orgVnode) +{ + int ret; + int vnodePathLen; + char *vnodePath = NULL; + struct Vnode *startVnode = NULL; + char *normalizedPath = NULL; + + if (orgVnode != NULL) { + startVnode = orgVnode; + normalizedPath = strdup(path); + if (normalizedPath == NULL) { + PRINT_ERR("[VFS]lookup failed, strdup err\n"); + ret = -EINVAL; + goto OUT_FREE_PATH; + } + } else { + ret = PreProcess(path, &startVnode, &normalizedPath); + if (ret != LOS_OK) { + PRINT_ERR("[VFS]lookup failed, invalid path err = %d\n", ret); + goto OUT_FREE_PATH; + } + } + + if (normalizedPath[1] == '\0' && normalizedPath[0] == '/') { + *result = GetCurrRootVnode(); + free(normalizedPath); + return LOS_OK; + } + + char *currentDir = normalizedPath; + struct Vnode *currentVnode = startVnode; + + while (*currentDir != '\0') { + ret = Step(¤tDir, ¤tVnode, flags); + if (currentDir == NULL || *currentDir == '\0') { + // return target or parent vnode as result + *result = currentVnode; + if (currentVnode->filePath == NULL) { + currentVnode->filePath = normalizedPath; + } else { + free(normalizedPath); + } + return ret; + } else if (VfsVnodePermissionCheck(currentVnode, EXEC_OP)) { + ret = -EACCES; + goto OUT_FREE_PATH; + } + + if (ret != LOS_OK) { + // no such file, lookup failed + goto OUT_FREE_PATH; + } + if (currentVnode->filePath == NULL) { + vnodePathLen = currentDir - normalizedPath; + vnodePath = malloc(vnodePathLen + 1); + if (vnodePath == NULL) { + ret = -ENOMEM; + goto OUT_FREE_PATH; + } + ret = strncpy_s(vnodePath, vnodePathLen + 1, normalizedPath, vnodePathLen); + if (ret != EOK) { + ret = -ENAMETOOLONG; + free(vnodePath); + goto OUT_FREE_PATH; + } + currentVnode->filePath = vnodePath; + currentVnode->filePath[vnodePathLen] = 0; + } + } + +OUT_FREE_PATH: + if (normalizedPath) { + free(normalizedPath); + } + return ret; +} + +int VnodeLookup(const char *path, struct Vnode **vnode, uint32_t flags) +{ + return VnodeLookupAt(path, vnode, flags, NULL); +} + +int VnodeLookupFullpath(const char *fullpath, struct Vnode **vnode, uint32_t flags) +{ + return VnodeLookupAt(fullpath, vnode, flags, GetCurrRootVnode()); +} + +static void ChangeRootInternal(struct Vnode *rootOld, char *dirname) +{ + int ret; + struct Mount *mnt = NULL; + char *name = NULL; + struct Vnode *node = NULL; + struct Vnode *nodeInFs = NULL; + struct PathCache *item = NULL; + struct PathCache *nextItem = NULL; + + LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &rootOld->childPathCaches, struct PathCache, childEntry) { + name = item->name; + node = item->childVnode; + + if (strcmp(name, dirname)) { + continue; + } + PathCacheFree(item); + + ret = VnodeLookup(dirname, &nodeInFs, 0); + if (ret) { + PRINTK("%s-%d %s NOT exist in rootfs\n", __FUNCTION__, __LINE__, dirname); + break; + } + + mnt = node->newMount; + mnt->vnodeBeCovered = nodeInFs; + + nodeInFs->newMount = mnt; + nodeInFs->flag |= VNODE_FLAG_MOUNT_ORIGIN; + + break; + } +} + +void ChangeRoot(struct Vnode *rootNew) +{ + struct Vnode *rootOld = g_rootVnode; + g_rootVnode = rootNew; +#ifdef LOSCFG_CHROOT + LosProcessCB *curr = OsCurrProcessGet(); + if ((curr->files != NULL) && + (curr->files->rootVnode != NULL) && + (curr->files->rootVnode->useCount > 0)) { + curr->files->rootVnode->useCount--; + } + rootNew->useCount++; + curr->files->rootVnode = rootNew; +#endif + + ChangeRootInternal(rootOld, "proc"); + ChangeRootInternal(rootOld, "dev"); +} + +static int VnodeReaddir(struct Vnode *vp, struct fs_dirent_s *dir) +{ + int result; + int cnt = 0; + off_t i = 0; + off_t idx; + unsigned int dstNameSize; + + struct PathCache *item = NULL; + struct PathCache *nextItem = NULL; + + if (dir == NULL) { + return -EINVAL; + } + + LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &vp->childPathCaches, struct PathCache, childEntry) { + if (i < dir->fd_position) { + i++; + continue; + } + + idx = i - dir->fd_position; + + dstNameSize = sizeof(dir->fd_dir[idx].d_name); + result = strncpy_s(dir->fd_dir[idx].d_name, dstNameSize, item->name, item->nameLen); + if (result != EOK) { + return -ENAMETOOLONG; + } + dir->fd_dir[idx].d_off = i; + dir->fd_dir[idx].d_reclen = (uint16_t)sizeof(struct dirent); + + i++; + if (++cnt >= dir->read_cnt) { + break; + } + } + + dir->fd_position = i; + + return cnt; +} + +int VnodeOpendir(struct Vnode *vnode, struct fs_dirent_s *dir) +{ + (void)vnode; + (void)dir; + return LOS_OK; +} + +int VnodeClosedir(struct Vnode *vnode, struct fs_dirent_s *dir) +{ + (void)vnode; + (void)dir; + return LOS_OK; +} + +int VnodeCreate(struct Vnode *parent, const char *name, int mode, struct Vnode **vnode) +{ + int ret; + struct Vnode *newVnode = NULL; + + ret = VnodeAlloc(NULL, &newVnode); + if (ret != 0) { + return -ENOMEM; + } + + newVnode->type = VNODE_TYPE_CHR; + newVnode->vop = parent->vop; + newVnode->fop = parent->fop; + newVnode->data = NULL; + newVnode->parent = parent; + newVnode->originMount = parent->originMount; + newVnode->uid = parent->uid; + newVnode->gid = parent->gid; + newVnode->mode = mode; + /* The 'name' here is not full path, but for device we don't depend on this path, it's just a name for DFx. + When we have devfs, we can get a fullpath. */ + newVnode->filePath = strdup(name); + + *vnode = newVnode; + return 0; +} + +int VnodeDevInit(void) +{ + struct Vnode *devNode = NULL; + struct Mount *devMount = NULL; + + int retval = VnodeLookup("/dev", &devNode, V_CREATE | V_DUMMY); + if (retval != LOS_OK) { + PRINT_ERR("VnodeDevInit failed error %d\n", retval); + return retval; + } + devNode->mode = DEV_VNODE_MODE | S_IFDIR; + devNode->type = VNODE_TYPE_DIR; + + devMount = MountAlloc(devNode, NULL); + if (devMount == NULL) { + PRINT_ERR("VnodeDevInit failed mount point alloc failed.\n"); + return -ENOMEM; + } + devMount->vnodeCovered = devNode; + devMount->vnodeBeCovered->flag |= VNODE_FLAG_MOUNT_ORIGIN; + return LOS_OK; +} + +int VnodeGetattr(struct Vnode *vnode, struct stat *buf) +{ + (void)memset_s(buf, sizeof(struct stat), 0, sizeof(struct stat)); + buf->st_mode = vnode->mode; + buf->st_uid = vnode->uid; + buf->st_gid = vnode->gid; + + return LOS_OK; +} + +struct Vnode *VnodeGetRoot(void) +{ + return g_rootVnode; +} + +static int VnodeChattr(struct Vnode *vnode, struct IATTR *attr) +{ + mode_t tmpMode; + if (vnode == NULL || attr == NULL) { + return -EINVAL; + } + if (attr->attr_chg_valid & CHG_MODE) { + tmpMode = attr->attr_chg_mode; + tmpMode &= ~S_IFMT; + vnode->mode &= S_IFMT; + vnode->mode = tmpMode | vnode->mode; + } + if (attr->attr_chg_valid & CHG_UID) { + vnode->uid = attr->attr_chg_uid; + } + if (attr->attr_chg_valid & CHG_GID) { + vnode->gid = attr->attr_chg_gid; + } + return LOS_OK; +} + +int VnodeDevLookup(struct Vnode *parentVnode, const char *path, int len, struct Vnode **vnode) +{ + (void)parentVnode; + (void)path; + (void)len; + (void)vnode; + /* dev node must in pathCache. */ + return -ENOENT; +} + +static struct VnodeOps g_devfsOps = { + .Lookup = VnodeDevLookup, + .Getattr = VnodeGetattr, + .Readdir = VnodeReaddir, + .Opendir = VnodeOpendir, + .Closedir = VnodeClosedir, + .Create = VnodeCreate, + .Chattr = VnodeChattr, +}; + +void VnodeMemoryDump(void) +{ + struct Vnode *item = NULL; + struct Vnode *nextItem = NULL; + int vnodeCount = 0; + + LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &g_vnodeActiveList, struct Vnode, actFreeEntry) { + if ((item->useCount > 0) || + (item->flag & VNODE_FLAG_MOUNT_ORIGIN) || + (item->flag & VNODE_FLAG_MOUNT_NEW)) { + continue; + } + + vnodeCount++; + } + + PRINTK("Vnode number = %d\n", vnodeCount); + PRINTK("Vnode memory size = %d(B)\n", vnodeCount * sizeof(struct Vnode)); +} + +#ifdef LOSCFG_PROC_PROCESS_DIR +struct Vnode *VnodeFind(int fd) +{ + INT32 sysFd; + + if (fd < 0) { + PRINT_ERR("Error. fd is invalid as %d\n", fd); + return NULL; + } + + /* Process fd convert to system global fd */ + sysFd = GetAssociatedSystemFd(fd); + if (sysFd < 0) { + PRINT_ERR("Error. sysFd is invalid as %d\n", sysFd); + return NULL; + } + + return files_get_openfile((int)sysFd); +} +#endif + +LIST_HEAD* GetVnodeFreeList() +{ + return &g_vnodeFreeList; +} + +LIST_HEAD* GetVnodeVirtualList() +{ + return &g_vnodeVirtualList; +} + +LIST_HEAD* GetVnodeActiveList() +{ + return &g_vnodeActiveList; +} + +int VnodeClearCache(void) +{ + struct Vnode *item = NULL; + struct Vnode *nextItem = NULL; + int count = 0; + + VnodeHold(); + LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &g_vnodeActiveList, struct Vnode, actFreeEntry) { + if ((item->useCount > 0) || + (item->flag & VNODE_FLAG_MOUNT_ORIGIN) || + (item->flag & VNODE_FLAG_MOUNT_NEW)) { + continue; + } + + if (VnodeFree(item) == LOS_OK) { + count++; + } + } + VnodeDrop(); + + return count; +} + +struct Vnode *GetCurrRootVnode(void) +{ +#ifdef LOSCFG_CHROOT + LosProcessCB *curr = OsCurrProcessGet(); + return curr->files->rootVnode; +#else + return g_rootVnode; +#endif +} diff --git a/src/kernel_liteos_a/fs/vfs/vnode_hash.c b/src/kernel_liteos_a/fs/vfs/vnode_hash.c new file mode 100644 index 00000000..e3d2ce70 --- /dev/null +++ b/src/kernel_liteos_a/fs/vfs/vnode_hash.c @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_mux.h" +#include "vnode.h" +#include "fs/mount.h" + + +#define VNODE_HASH_BUCKETS 128 + +LIST_HEAD g_vnodeHashEntrys[VNODE_HASH_BUCKETS]; +uint32_t g_vnodeHashMask = VNODE_HASH_BUCKETS - 1; +uint32_t g_vnodeHashSize = VNODE_HASH_BUCKETS; + +static LosMux g_vnodeHashMux; + +int VnodeHashInit(void) +{ + int ret; + for (int i = 0; i < g_vnodeHashSize; i++) { + LOS_ListInit(&g_vnodeHashEntrys[i]); + } + + ret = LOS_MuxInit(&g_vnodeHashMux, NULL); + if (ret != LOS_OK) { + PRINT_ERR("Create mutex for vnode hash list fail, status: %d", ret); + return ret; + } + + return LOS_OK; +} + +void VnodeHashDump(void) +{ + PRINTK("-------->VnodeHashDump in\n"); + (void)LOS_MuxLock(&g_vnodeHashMux, LOS_WAIT_FOREVER); + for (int i = 0; i < g_vnodeHashSize; i++) { + LIST_HEAD *nhead = &g_vnodeHashEntrys[i]; + struct Vnode *node = NULL; + + LOS_DL_LIST_FOR_EACH_ENTRY(node, nhead, struct Vnode, hashEntry) { + PRINTK(" vnode dump: col %d item %p\n", i, node); + } + } + (void)LOS_MuxUnlock(&g_vnodeHashMux); + PRINTK("-------->VnodeHashDump out\n"); +} + +uint32_t VfsHashIndex(struct Vnode *vnode) +{ + if (vnode == NULL) { + return -EINVAL; + } + return (vnode->hash + vnode->originMount->hashseed); +} + +static LOS_DL_LIST *VfsHashBucket(const struct Mount *mp, uint32_t hash) +{ + return (&g_vnodeHashEntrys[(hash + mp->hashseed) & g_vnodeHashMask]); +} + +int VfsHashGet(const struct Mount *mount, uint32_t hash, struct Vnode **vnode, VfsHashCmp *fn, void *arg) +{ + struct Vnode *curVnode = NULL; + + if (mount == NULL || vnode == NULL) { + return -EINVAL; + } + + (void)LOS_MuxLock(&g_vnodeHashMux, LOS_WAIT_FOREVER); + LOS_DL_LIST *list = VfsHashBucket(mount, hash); + LOS_DL_LIST_FOR_EACH_ENTRY(curVnode, list, struct Vnode, hashEntry) { + if (curVnode->hash != hash) { + continue; + } + if (curVnode->originMount != mount) { + continue; + } + if (fn != NULL && fn(curVnode, arg)) { + continue; + } + (void)LOS_MuxUnlock(&g_vnodeHashMux); + *vnode = curVnode; + return LOS_OK; + } + (void)LOS_MuxUnlock(&g_vnodeHashMux); + *vnode = NULL; + return LOS_NOK; +} + +void VfsHashRemove(struct Vnode *vnode) +{ + if (vnode == NULL) { + return; + } + (void)LOS_MuxLock(&g_vnodeHashMux, LOS_WAIT_FOREVER); + LOS_ListDelete(&vnode->hashEntry); + (void)LOS_MuxUnlock(&g_vnodeHashMux); +} + +int VfsHashInsert(struct Vnode *vnode, uint32_t hash) +{ + if (vnode == NULL) { + return -EINVAL; + } + (void)LOS_MuxLock(&g_vnodeHashMux, LOS_WAIT_FOREVER); + vnode->hash = hash; + LOS_ListHeadInsert(VfsHashBucket(vnode->originMount, hash), &vnode->hashEntry); + (void)LOS_MuxUnlock(&g_vnodeHashMux); + return LOS_OK; +} diff --git a/src/kernel_liteos_a/fs/zpfs/BUILD.gn b/src/kernel_liteos_a/fs/zpfs/BUILD.gn new file mode 100644 index 00000000..bf2dda86 --- /dev/null +++ b/src/kernel_liteos_a/fs/zpfs/BUILD.gn @@ -0,0 +1,41 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = defined(LOSCFG_FS_ZPFS) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ + "src/vfs_zpfs.c", + "src/zpfs.c", + ] + + include_dirs = [ "include" ] +} diff --git a/src/kernel_liteos_a/fs/zpfs/Kconfig b/src/kernel_liteos_a/fs/zpfs/Kconfig new file mode 100644 index 00000000..06a0d2c1 --- /dev/null +++ b/src/kernel_liteos_a/fs/zpfs/Kconfig @@ -0,0 +1,6 @@ +config FS_ZPFS + bool "Enable ZPFS" + default y + depends on FS_VFS && PLATFORM_PATCHFS + help + Answer Y to enable LiteOS support zpfs filesystem. diff --git a/src/kernel_liteos_a/fs/zpfs/Makefile b/src/kernel_liteos_a/fs/zpfs/Makefile new file mode 100644 index 00000000..9584e738 --- /dev/null +++ b/src/kernel_liteos_a/fs/zpfs/Makefile @@ -0,0 +1,40 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := $(wildcard src/*.c) +LOCAL_INCLUDE := \ + -I $(LITEOSTOPDIR)/fs/zpfs/include + +LOCAL_FLAGS := $(LOCAL_INCLUDE) + +include $(MODULE) diff --git a/src/kernel_liteos_a/kernel/BUILD.gn b/src/kernel_liteos_a/kernel/BUILD.gn new file mode 100644 index 00000000..e0a1da6d --- /dev/null +++ b/src/kernel_liteos_a/kernel/BUILD.gn @@ -0,0 +1,49 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +group("kernel") { + deps = [ + "base", + "common", + "extended", + "user", + ] +} + +config("public") { + include_dirs = [ "include" ] + configs = [ + "base:public", + "common:public", + "extended:public", + "user:public", + ] +} diff --git a/src/kernel_liteos_a/kernel/Kconfig b/src/kernel_liteos_a/kernel/Kconfig new file mode 100644 index 00000000..03fea0d9 --- /dev/null +++ b/src/kernel_liteos_a/kernel/Kconfig @@ -0,0 +1,80 @@ +menu "Kernel" +config KERNEL_SMP + bool "Enable Kernel SMP" + default n + help + This option will enable smp support of LiteOS. + +config KERNEL_SMP_CORE_NUM + int "Multi-processing Core Numbers" + default 2 + depends on KERNEL_SMP + help + This represents the number of multi-processing cores. + +config KERNEL_SMP_LOCKDEP + bool "Enable Spinlock Lockdep Check" + default n + depends on KERNEL_SMP + help + This option will enable spinlock lockdep check. + +config KERNEL_SMP_TASK_SYNC + bool "Enable Synchronized Task Operations" + default n + depends on KERNEL_SMP + help + This option will enable task synchronized operate task across cores. + +config KERNEL_SMP_CALL + bool "Enable Function call cross Multi-core" + default n + depends on KERNEL_SMP + help + This option will enable function call on multi-core. + +config KERNEL_SCHED_STATISTICS + bool "Enable Scheduler statistics" + default n + depends on KERNEL_SMP + help + This option will enable scheduler statistics. + +config KERNEL_MMU + bool "Enable MMU" + default y + help + This option will enable mmu. + +config KERNEL_VM + bool "Enable VM" + default y + depends on KERNEL_MMU + help + This option will enable vmm, pmm, page fault, etc. + +config KERNEL_SYSCALL + bool "Enable Syscall" + default y + depends on KERNEL_VM + help + This option will enable syscall. + +config PAGE_TABLE_FINE_LOCK + bool "Enable fine lock for page table" + default n + depends on KERNEL_VM + help + This option will enable fine lock for page table. + + +######################### config options of extended ##################### +source "kernel/extended/Kconfig" + +config ENABLE_KERNEL_TEST + bool "Enable kernel test" + default n + help + This option will enable kernel test. + +endmenu diff --git a/src/kernel_liteos_a/kernel/base/BUILD.gn b/src/kernel_liteos_a/kernel/base/BUILD.gn new file mode 100644 index 00000000..f3d9b457 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/BUILD.gn @@ -0,0 +1,104 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ + "core/los_bitmap.c", + "core/los_info.c", + "core/los_process.c", + "core/los_smp.c", + "core/los_swtmr.c", + "core/los_sys.c", + "core/los_task.c", + "core/los_tick.c", + "ipc/los_event.c", + "ipc/los_futex.c", + "ipc/los_ipcdebug.c", + "ipc/los_mux.c", + "ipc/los_queue.c", + "ipc/los_queue_debug.c", + "ipc/los_rwlock.c", + "ipc/los_sem.c", + "ipc/los_sem_debug.c", + "ipc/los_signal.c", + "mem/common/los_memstat.c", + "mem/membox/los_membox.c", + "mem/tlsf/los_memory.c", + "misc/kill_shellcmd.c", + "misc/los_misc.c", + "misc/los_stackinfo.c", + "misc/mempt_shellcmd.c", + "misc/panic_shellcmd.c", + "misc/swtmr_shellcmd.c", + "misc/sysinfo_shellcmd.c", + "misc/task_shellcmd.c", + "misc/vm_shellcmd.c", + "mp/los_lockdep.c", + "mp/los_mp.c", + "mp/los_percpu.c", + "mp/los_spinlock.c", + "om/los_err.c", + "sched/los_deadline.c", + "sched/los_idle.c", + "sched/los_priority.c", + "sched/los_sched.c", + "sched/los_sortlink.c", + "sched/los_statistics.c", + "vm/los_vm_boot.c", + "vm/los_vm_dump.c", + "vm/los_vm_fault.c", + "vm/los_vm_filemap.c", + "vm/los_vm_iomap.c", + "vm/los_vm_map.c", + "vm/los_vm_page.c", + "vm/los_vm_phys.c", + "vm/los_vm_scan.c", + "vm/los_vm_syscall.c", + "vm/oom.c", + "vm/shm.c", + ] + + if (defined(LOSCFG_SHELL_CMD_DEBUG)) { + configs += [ "$HDFTOPDIR:hdf_config" ] + } + + public_configs = [ ":public" ] + configs += [ ":private" ] +} + +config("public") { + include_dirs = [ "include" ] +} + +config("private") { + cflags = [ "-Wno-frame-address" ] +} diff --git a/src/kernel_liteos_a/kernel/base/Makefile b/src/kernel_liteos_a/kernel/base/Makefile new file mode 100644 index 00000000..73fa7ceb --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/Makefile @@ -0,0 +1,46 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk +include $(LITEOSTOPDIR)/../../drivers/hdf_core/adapter/khdf/liteos/lite.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := $(wildcard ipc/*.c) $(wildcard core/*.c) $(wildcard mem/membox/*.c) $(wildcard mem/common/*.c) \ + $(wildcard om/*.c)\ + $(wildcard misc/*.c)\ + $(wildcard mem/tlsf/*.c) \ + $(wildcard mp/*.c) \ + $(wildcard sched/*.c) \ + $(wildcard vm/*.c) \ + + +LOCAL_FLAGS := $(LITEOS_CFLAGS_INTERWORK) -Wno-frame-address + +include $(MODULE) diff --git a/src/kernel_liteos_a/kernel/base/core/los_bitmap.c b/src/kernel_liteos_a/kernel/base/core/los_bitmap.c new file mode 100644 index 00000000..253af3a5 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/core/los_bitmap.c @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_bitmap.h" +#include "los_printf.h" +#include "los_toolchain.h" + +/* + function: 这部分的代码提供了位操作 + + interpretation: 位操作为可以提供对标志位的修改等功能 +*/ +#define OS_BITMAP_MASK 0x1FU +#define OS_BITMAP_WORD_MASK ~0UL + +/* + function: 返回从右开始第一个为1的下标 + + interpretation: +*/ + +/* find first zero bit starting from LSB */ +STATIC INLINE UINT16 Ffz(UINTPTR x) +{ + // gcc 自带的内建函数 + return __builtin_ffsl(~x) - 1; +} + +/* + funciton: 对状态字某一标志位进行置1操作 + + interpretation: +*/ +VOID LOS_BitmapSet(UINT32 *bitmap, UINT16 pos) +{ + if (bitmap == NULL) { + return; + } + + *bitmap |= 1U << (pos & OS_BITMAP_MASK); //00011111 +} + +/* + function: 对某一标志位进行清0操作 + + interpretation: +*/ +VOID LOS_BitmapClr(UINT32 *bitmap, UINT16 pos) +{ + if (bitmap == NULL) { + return; + } + + *bitmap &= ~(1U << (pos & OS_BITMAP_MASK)); +} + +/* + function: 用于返回参数位图当中最高的索引位 +*/ +UINT16 LOS_HighBitGet(UINT32 bitmap) +{ + if (bitmap == 0) { + return LOS_INVALID_BIT_INDEX; + } + + return (OS_BITMAP_MASK - CLZ(bitmap)); +} + +/* + function: 获取参数位图中最低位为1的索引位 +*/ +UINT16 LOS_LowBitGet(UINT32 bitmap) +{ + if (bitmap == 0) { + return LOS_INVALID_BIT_INDEX; + } + + return CTZ(bitmap); +} + +/* + function: 从start位置开始设置numsSet个bit位 置1 +*/ +VOID LOS_BitmapSetNBits(UINTPTR *bitmap, UINT32 start, UINT32 numsSet) +{ + UINTPTR *p = bitmap + BITMAP_WORD(start); + const UINT32 size = start + numsSet; + UINT16 bitsToSet = BITMAP_BITS_PER_WORD - (start % BITMAP_BITS_PER_WORD); + UINTPTR maskToSet = BITMAP_FIRST_WORD_MASK(start); + + while (numsSet > bitsToSet) { + *p |= maskToSet; + numsSet -= bitsToSet; + bitsToSet = BITMAP_BITS_PER_WORD; + maskToSet = OS_BITMAP_WORD_MASK; + p++; + } + if (numsSet) { + maskToSet &= BITMAP_LAST_WORD_MASK(size); + *p |= maskToSet; + } +} + +/* + fuction: 从start位置开始 清除numsSet个bit位置0 ,对状态字的连续标志位进行清0操作 +*/ +VOID LOS_BitmapClrNBits(UINTPTR *bitmap, UINT32 start, UINT32 numsClear) +{ + UINTPTR *p = bitmap + BITMAP_WORD(start); + const UINT32 size = start + numsClear; + UINT16 bitsToClear = BITMAP_BITS_PER_WORD - (start % BITMAP_BITS_PER_WORD); + UINTPTR maskToClear = BITMAP_FIRST_WORD_MASK(start); + + while (numsClear >= bitsToClear) { + *p &= ~maskToClear; + numsClear -= bitsToClear; + bitsToClear = BITMAP_BITS_PER_WORD; + maskToClear = OS_BITMAP_WORD_MASK; + p++; + } + if (numsClear) { + maskToClear &= BITMAP_LAST_WORD_MASK(size); + *p &= ~maskToClear; + } +} +/* + fuction: 从numBits位置开始找到第一个0位 +*/ +INT32 LOS_BitmapFfz(UINTPTR *bitmap, UINT32 numBits) +{ + INT32 bit, i; + + for (i = 0; i < BITMAP_NUM_WORDS(numBits); i++) { + if (bitmap[i] == OS_BITMAP_WORD_MASK) { + continue; + } + bit = i * BITMAP_BITS_PER_WORD + Ffz(bitmap[i]); + if (bit < numBits) { + return bit; + } + return -1; + } + return -1; +} + diff --git a/src/kernel_liteos_a/kernel/base/core/los_info.c b/src/kernel_liteos_a/kernel/base/core/los_info.c new file mode 100644 index 00000000..0999503d --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/core/los_info.c @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_info_pri.h" +#include "los_task_pri.h" +#include "los_vm_dump.h" + +// 得到父进程的pid +STATIC UINT32 GetCurrParentPid(UINT32 pid, const LosProcessCB *processCB) +{ + // 如果没有父进程 + if (processCB->parentProcess == NULL) { + return 0; + } + +#ifdef LOSCFG_PID_CONTAINER + if (pid == OS_USER_ROOT_PROCESS_ID) { + return 0; + } + + if (OS_PROCESS_CONTAINER_CHECK(processCB->parentProcess, OsCurrProcessGet())) { + return OsGetVpidFromCurrContainer(processCB->parentProcess); + } +#endif + return processCB->parentProcess->processID; +} + +// 得到当前任务ID +STATIC INLINE UINT32 GetCurrTid(const LosTaskCB *taskCB) +{ +#ifdef LOSCFG_PID_CONTAINER + if (taskCB->pidContainer != OsCurrTaskGet()->pidContainer) { + return OsGetVtidFromCurrContainer(taskCB); + } +#endif + return taskCB->taskID; +} + +// 得到进程的状态 +STATIC UINT16 GetProcessStatus(LosProcessCB *processCB) +{ + UINT16 status; + LosTaskCB *taskCB = NULL; + + if (LOS_ListEmpty(&processCB->threadSiblingList)) { + return processCB->processStatus; + } + + status = processCB->processStatus; + LOS_DL_LIST_FOR_EACH_ENTRY(taskCB, &processCB->threadSiblingList, LosTaskCB, threadList) { + status |= (taskCB->taskStatus & 0x00FF); + } + return status; +} + +// 得到进程的信息 +STATIC VOID GetProcessInfo(ProcessInfo *pcbInfo, const LosProcessCB *processCB) +{ + SchedParam param = {0}; + pcbInfo->pid = OsGetPid(processCB); + pcbInfo->ppid = GetCurrParentPid(pcbInfo->pid, processCB); + pcbInfo->status = GetProcessStatus((LosProcessCB *)processCB); + pcbInfo->mode = processCB->processMode; + if (processCB->pgroup != NULL) { + pcbInfo->pgroupID = OsGetPid(OS_GET_PGROUP_LEADER(processCB->pgroup)); + } else { + pcbInfo->pgroupID = -1; + } +#ifdef LOSCFG_SECURITY_CAPABILITY + if (processCB->user != NULL) { + pcbInfo->userID = processCB->user->userID; + } else { + pcbInfo->userID = -1; + } +#else + pcbInfo->userID = 0; +#endif + LosTaskCB *taskCB = processCB->threadGroup; + pcbInfo->threadGroupID = taskCB->taskID; + taskCB->ops->schedParamGet(taskCB, ¶m); + pcbInfo->policy = LOS_SCHED_RR; + pcbInfo->basePrio = param.basePrio; + pcbInfo->threadNumber = processCB->threadNumber; +#ifdef LOSCFG_KERNEL_CPUP + (VOID)OsGetProcessAllCpuUsageUnsafe(processCB->processCpup, pcbInfo); +#endif + (VOID)memcpy_s(pcbInfo->name, OS_PCB_NAME_LEN, processCB->processName, OS_PCB_NAME_LEN); +} + +#ifdef LOSCFG_KERNEL_VM +STATIC VOID GetProcessMemInfo(ProcessInfo *pcbInfo, const LosProcessCB *processCB, LosVmSpace *vmSpace) +{ + /* Process memory usage statistics, idle task defaults to 0 */ + if (processCB == &g_processCBArray[0]) { + pcbInfo->virtualMem = 0; + pcbInfo->shareMem = 0; + pcbInfo->physicalMem = 0; + } else if (vmSpace == LOS_GetKVmSpace()) { + (VOID)OsShellCmdProcessPmUsage(vmSpace, &pcbInfo->shareMem, &pcbInfo->physicalMem); + pcbInfo->virtualMem = pcbInfo->physicalMem; + } else { + pcbInfo->virtualMem = OsShellCmdProcessVmUsage(vmSpace); + if (pcbInfo->virtualMem == 0) { + pcbInfo->status = OS_PROCESS_FLAG_UNUSED; + return; + } + if (OsShellCmdProcessPmUsage(vmSpace, &pcbInfo->shareMem, &pcbInfo->physicalMem) == 0) { + pcbInfo->status = OS_PROCESS_FLAG_UNUSED; + } + } +} +#endif + +// 得到线程的信息 +STATIC VOID GetThreadInfo(ProcessThreadInfo *threadInfo, LosProcessCB *processCB) +{ + SchedParam param = {0}; + LosTaskCB *taskCB = NULL; + if (LOS_ListEmpty(&processCB->threadSiblingList)) { + threadInfo->threadCount = 0; + return; + } + + threadInfo->threadCount = 0; + LOS_DL_LIST_FOR_EACH_ENTRY(taskCB, &processCB->threadSiblingList, LosTaskCB, threadList) { + TaskInfo *taskInfo = &threadInfo->taskInfo[threadInfo->threadCount]; + taskInfo->tid = GetCurrTid(taskCB); + taskInfo->pid = OsGetPid(processCB); + taskInfo->status = taskCB->taskStatus; + taskCB->ops->schedParamGet(taskCB, ¶m); + taskInfo->policy = param.policy; + taskInfo->priority = param.priority; +#ifdef LOSCFG_KERNEL_SMP + taskInfo->currCpu = taskCB->currCpu; + taskInfo->cpuAffiMask = taskCB->cpuAffiMask; +#endif + taskInfo->stackPoint = (UINTPTR)taskCB->stackPointer; + taskInfo->topOfStack = taskCB->topOfStack; + taskInfo->stackSize = taskCB->stackSize; + taskInfo->waitFlag = taskCB->waitFlag; + taskInfo->waitID = taskCB->waitID; + taskInfo->taskMux = taskCB->taskMux; + (VOID)OsStackWaterLineGet((const UINTPTR *)(taskCB->topOfStack + taskCB->stackSize), + (const UINTPTR *)taskCB->topOfStack, &taskInfo->waterLine); +#ifdef LOSCFG_KERNEL_CPUP + (VOID)OsGetTaskAllCpuUsageUnsafe(&taskCB->taskCpup, taskInfo); +#endif + (VOID)memcpy_s(taskInfo->name, OS_TCB_NAME_LEN, taskCB->taskName, OS_TCB_NAME_LEN); + threadInfo->threadCount++; + } +} + +UINT32 OsGetProcessThreadInfo(UINT32 pid, ProcessThreadInfo *threadInfo) +{ + UINT32 intSave; + + if (OS_PID_CHECK_INVALID(pid) || (pid == 0) || (threadInfo == NULL)) { + return LOS_NOK; + } + + LosProcessCB *processCB = OS_PCB_FROM_PID(pid); + if (OsProcessIsUnused(processCB)) { + return LOS_NOK; + } + +#ifdef LOSCFG_KERNEL_VM + GetProcessMemInfo(&threadInfo->processInfo, processCB, processCB->vmSpace); +#endif + + SCHEDULER_LOCK(intSave); + GetProcessInfo(&threadInfo->processInfo, processCB); + GetThreadInfo(threadInfo, processCB); + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +STATIC VOID ProcessMemUsageGet(ProcessInfo *pcbArray) +{ + UINT32 intSave; +#ifdef LOSCFG_PID_CONTAINER + PidContainer *pidContainer = OsCurrTaskGet()->pidContainer; + for (UINT32 pid = 0; pid < g_processMaxNum; ++pid) { + ProcessVid *processVid = &pidContainer->pidArray[pid]; + const LosProcessCB *processCB = (LosProcessCB *)processVid->cb; +#else + for (UINT32 pid = 0; pid < g_processMaxNum; ++pid) { + const LosProcessCB *processCB = OS_PCB_FROM_RPID(pid); +#endif + ProcessInfo *pcbInfo = pcbArray + pid; + SCHEDULER_LOCK(intSave); + if (OsProcessIsUnused(processCB)) { + SCHEDULER_UNLOCK(intSave); + pcbInfo->status = OS_PROCESS_FLAG_UNUSED; + continue; + } +#ifdef LOSCFG_KERNEL_VM + LosVmSpace *vmSpace = processCB->vmSpace; +#endif + SCHEDULER_UNLOCK(intSave); + +#ifdef LOSCFG_KERNEL_VM + GetProcessMemInfo(pcbInfo, processCB, vmSpace); +#endif + } +} + +UINT32 OsGetAllProcessInfo(ProcessInfo *pcbArray) +{ + UINT32 intSave; + if (pcbArray == NULL) { + return LOS_NOK; + } + + ProcessMemUsageGet(pcbArray); + + SCHEDULER_LOCK(intSave); +#ifdef LOSCFG_PID_CONTAINER + PidContainer *pidContainer = OsCurrTaskGet()->pidContainer; + for (UINT32 index = 0; index < LOSCFG_BASE_CORE_PROCESS_LIMIT; index++) { + ProcessVid *processVid = &pidContainer->pidArray[index]; + LosProcessCB *processCB = (LosProcessCB *)processVid->cb; +#else + for (UINT32 index = 0; index < LOSCFG_BASE_CORE_PROCESS_LIMIT; index++) { + LosProcessCB *processCB = OS_PCB_FROM_RPID(index); +#endif + ProcessInfo *pcbInfo = pcbArray + index; + if (OsProcessIsUnused(processCB)) { + pcbInfo->status = OS_PROCESS_FLAG_UNUSED; + continue; + } + GetProcessInfo(pcbInfo, processCB); + } + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} diff --git a/src/kernel_liteos_a/kernel/base/core/los_process.c b/src/kernel_liteos_a/kernel/base/core/los_process.c new file mode 100644 index 00000000..1aac6412 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/core/los_process.c @@ -0,0 +1,2542 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_process_pri.h" +#include "los_sched_pri.h" +#include "los_task_pri.h" +#include "los_hw_pri.h" +#include "los_sem_pri.h" +#include "los_mp.h" +#include "los_exc.h" +#include "asm/page.h" +#ifdef LOSCFG_FS_VFS +#include "fs/fd_table.h" +#include "fs/fs_operation.h" +#include "internal.h" +#endif +#include "time.h" +#include "user_copy.h" +#include "los_signal.h" +#ifdef LOSCFG_SECURITY_VID +#include "vid_api.h" +#endif +#ifdef LOSCFG_SECURITY_CAPABILITY +#include "capability_api.h" +#endif +#ifdef LOSCFG_KERNEL_DYNLOAD +#include "los_load_elf.h" +#endif +#include "los_swtmr_pri.h" +#include "los_vm_map.h" +#include "los_vm_phys.h" +#include "los_vm_syscall.h" + +/* + @brief 进程模块主文件 + + 并发(Concurrent):多个线程在单个核心运行,同一时间只能一个线程运行,内核不停切换线程,看起来像同时运行,实际上是线程不停切换 + 并行(Parallel)每个线程分配给独立的CPU核心,线程同时运行 + 单核CPU多个进程或多个线程内能实现并发(微观上的串行,宏观上的并行) + 多核CPU线程间可以实现宏观和微观上的并行 + LITE_OS_SEC_BSS 和 LITE_OS_SEC_DATA_INIT 是告诉编译器这些全局变量放在哪个数据段 +*/ + +/* + bss 是英文 Block by Symbol 的简称。 + 通常用来存放程序中未初始化和初始化为 + 0的全局变量的一块内存区域,在程序载入时由内核清零。 +*/ + +LITE_OS_SEC_BSS LosProcessCB *g_processCBArray = NULL; //进程池数组 +LITE_OS_SEC_DATA_INIT STATIC LOS_DL_LIST g_freeProcess; //空闲状态下的进程链表 +LITE_OS_SEC_DATA_INIT STATIC LOS_DL_LIST g_processRecycleList; //需要回收的进程列表 +LITE_OS_SEC_BSS UINT32 g_processMaxNum; //进程最大数量,默认64个 +#ifndef LOSCFG_PID_CONTAINER +LITE_OS_SEC_BSS ProcessGroup *g_processGroup = NULL; //全局进程组,负责管理所有进程组 +#define OS_ROOT_PGRP(processCB) (g_processGroup) +#endif + +// 将进程插入到空闲列表当中 +STATIC INLINE VOID OsInsertPCBToFreeList(LosProcessCB *processCB) +{ +#ifdef LOSCFG_PID_CONTAINER + OsPidContainerDestroy(processCB->container, processCB); +#endif + UINT32 pid = processCB->processID; // 获取进程ID + (VOID)memset_s(processCB, sizeof(LosProcessCB), 0, sizeof(LosProcessCB)); // 进程描述符数据清0 + processCB->processID = pid; + processCB->processStatus = OS_PROCESS_FLAG_UNUSED; // 设置状态为未使用 + processCB->timerID = (timer_t)(UINTPTR)MAX_INVALID_TIMER_VID; + LOS_ListTailInsert(&g_freeProcess, &processCB->pendList); // 将进程插入到空闲列表当中 +} + +// 从进程当中删除任务 +VOID OsDeleteTaskFromProcess(LosTaskCB *taskCB) +{ + LosProcessCB *processCB = OS_PCB_FROM_TCB(taskCB); + + LOS_ListDelete(&taskCB->threadList); + processCB->threadNumber--; + OsTaskInsertToRecycleList(taskCB); +} + +// 进程当中添加任务 +UINT32 OsProcessAddNewTask(UINTPTR processID, LosTaskCB *taskCB, SchedParam *param, UINT32 *numCount) +{ + UINT32 intSave; + LosProcessCB *processCB = (LosProcessCB *)processID; + + SCHEDULER_LOCK(intSave); +#ifdef LOSCFG_PID_CONTAINER + if (OsAllocVtid(taskCB, processCB) == OS_INVALID_VALUE) { + SCHEDULER_UNLOCK(intSave); + PRINT_ERR("OsAllocVtid failed!\n"); + return LOS_NOK; + } +#endif + + taskCB->processCB = (UINTPTR)processCB; + LOS_ListTailInsert(&(processCB->threadSiblingList), &(taskCB->threadList)); + if (OsProcessIsUserMode(processCB)) { + taskCB->taskStatus |= OS_TASK_FLAG_USER_MODE; + if (processCB->threadNumber > 0) { + LosTaskCB *task = processCB->threadGroup; + task->ops->schedParamGet(task, param); + } else { + OsSchedProcessDefaultSchedParamGet(param->policy, param); + } + } else { + LosTaskCB *runTask = OsCurrTaskGet(); + runTask->ops->schedParamGet(runTask, param); + } + +#ifdef LOSCFG_KERNEL_VM + taskCB->archMmu = (UINTPTR)&processCB->vmSpace->archMmu; +#endif + if (!processCB->threadNumber) { + processCB->threadGroup = taskCB; + } + processCB->threadNumber++; + + *numCount = processCB->threadCount; + processCB->threadCount++; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +// 创建进程组 +/** + * @brief 创建进程组 + * @details + * @param argc 1 + * @param[UINT32] pid 进程ID + * @return 函数执行结果 + * - ProcessGroup 返回进程组 +*/ +ProcessGroup *OsCreateProcessGroup(LosProcessCB *processCB) +{ + ProcessGroup *pgroup = LOS_MemAlloc(m_aucSysMem1, sizeof(ProcessGroup)); + if (pgroup == NULL) { + return NULL; + } + + pgroup->pgroupLeader = (UINTPTR)processCB; + LOS_ListInit(&pgroup->processList); + LOS_ListInit(&pgroup->exitProcessList); + + LOS_ListTailInsert(&pgroup->processList, &processCB->subordinateGroupList); + processCB->pgroup = pgroup; + processCB->processStatus |= OS_PROCESS_FLAG_GROUP_LEADER; + + ProcessGroup *rootPGroup = OS_ROOT_PGRP(processCB); + if (rootPGroup == NULL) { + OS_ROOT_PGRP(processCB) = pgroup; + LOS_ListInit(&pgroup->groupList); + } else { + LOS_ListTailInsert(&rootPGroup->groupList, &pgroup->groupList); + } + return pgroup; +} + +/*! 退出进程组,参数是进程地址和进程组地址的地址 */ +STATIC VOID ExitProcessGroup(LosProcessCB *processCB, ProcessGroup **pgroup) +{ + LosProcessCB *pgroupCB = OS_GET_PGROUP_LEADER(processCB->pgroup); + LOS_ListDelete(&processCB->subordinateGroupList);//从进程组进程链表上摘出去 + if (LOS_ListEmpty(&processCB->pgroup->processList) && LOS_ListEmpty(&processCB->pgroup->exitProcessList)) {//进程组进程链表和退出进程链表都为空时 +#ifdef LOSCFG_PID_CONTAINER + if (processCB->pgroup != OS_ROOT_PGRP(processCB)) { +#endif + LOS_ListDelete(&processCB->pgroup->groupList);//从全局进程组链表上把自己摘出去 记住它是 LOS_ListTailInsert(&g_processGroup->groupList, &group->groupList) 挂上去的 + *pgroup = processCB->pgroup; +#ifdef LOSCFG_PID_CONTAINER + } +#endif + pgroupCB->processStatus &= ~OS_PROCESS_FLAG_GROUP_LEADER; + if (OsProcessIsUnused(pgroupCB) && !(pgroupCB->processStatus & OS_PROCESS_FLAG_EXIT)) { + LOS_ListDelete(&pgroupCB->pendList); //进程从全局进程链表上摘除 + OsInsertPCBToFreeList(pgroupCB); //释放进程的资源,回到freelist再利用 + } + } + + processCB->pgroup = NULL; +} + +// 根据gid 寻找进程组 +STATIC ProcessGroup *OsFindProcessGroup(UINT32 gid) +{ + ProcessGroup *pgroup = NULL; + ProcessGroup *rootPGroup = OS_ROOT_PGRP(OsCurrProcessGet()); + LosProcessCB *processCB = OS_GET_PGROUP_LEADER(rootPGroup); + if (processCB->processID == gid) { + return rootPGroup; + } + + LOS_DL_LIST_FOR_EACH_ENTRY(pgroup, &rootPGroup->groupList, ProcessGroup, groupList) { + processCB = OS_GET_PGROUP_LEADER(pgroup); + if (processCB->processID == gid) { + return pgroup; + } + } + + PRINT_INFO("%s failed! pgroup id = %u\n", __FUNCTION__, gid); + return NULL; +} + +// 发送信号去查清楚进程组状态 +STATIC INT32 OsSendSignalToSpecifyProcessGroup(ProcessGroup *pgroup, siginfo_t *info, INT32 permission) +{ + INT32 ret, success, err; + LosProcessCB *childCB = NULL; + + success = 0; + ret = -LOS_ESRCH; + LOS_DL_LIST_FOR_EACH_ENTRY(childCB, &(pgroup->processList), LosProcessCB, subordinateGroupList) { + if (childCB->processID == 0) { + continue; + } + + err = OsDispatch(childCB->processID, info, permission); + success |= !err; + ret = err; + } + /* At least one success. */ + return success ? LOS_OK : ret; +} + +// 向所有的进程发送信号 +LITE_OS_SEC_TEXT INT32 OsSendSignalToAllProcess(siginfo_t *info, INT32 permission) +{ + INT32 ret, success, err; + ProcessGroup *pgroup = NULL; + ProcessGroup *rootPGroup = OS_ROOT_PGRP(OsCurrProcessGet()); + + success = 0; + err = OsSendSignalToSpecifyProcessGroup(rootPGroup, info, permission); + success |= !err; + ret = err; + /* all processes group */ + LOS_DL_LIST_FOR_EACH_ENTRY(pgroup, &rootPGroup->groupList, ProcessGroup, groupList) { + /* all processes in the process group. */ + err = OsSendSignalToSpecifyProcessGroup(pgroup, info, permission); + success |= !err; + ret = err; + } + return success ? LOS_OK : ret; +} + +// 向进程组发送信号 +LITE_OS_SEC_TEXT INT32 OsSendSignalToProcessGroup(INT32 pid, siginfo_t *info, INT32 permission) +{ + ProcessGroup *pgroup = NULL; + /* Send SIG to all processes in process group PGRP. + If PGRP is zero, send SIG to all processes in + the current process's process group. */ + pgroup = OsFindProcessGroup(pid ? -pid : LOS_GetCurrProcessGroupID()); + if (pgroup == NULL) { + return -LOS_ESRCH; + } + /* all processes in the process group. */ + return OsSendSignalToSpecifyProcessGroup(pgroup, info, permission); +} + +// 查找推出的进程 +STATIC LosProcessCB *OsFindGroupExitProcess(ProcessGroup *pgroup, INT32 pid) +{ + LosProcessCB *childCB = NULL; + + LOS_DL_LIST_FOR_EACH_ENTRY(childCB, &(pgroup->exitProcessList), LosProcessCB, subordinateGroupList) { + if ((childCB->processID == pid) || (pid == OS_INVALID_VALUE)) { + return childCB; + } + } + + return NULL; +} + +// 找到子进程 +STATIC UINT32 OsFindChildProcess(const LosProcessCB *processCB, const LosProcessCB *wait) +{ + LosProcessCB *childCB = NULL; + + LOS_DL_LIST_FOR_EACH_ENTRY(childCB, &(processCB->childrenList), LosProcessCB, siblingList) { + if (childCB == wait) { + return LOS_OK; + } + } + + return LOS_NOK; +} + +STATIC LosProcessCB *OsFindExitChildProcess(const LosProcessCB *processCB, const LosProcessCB *wait) +{ + LosProcessCB *exitChild = NULL; + + LOS_DL_LIST_FOR_EACH_ENTRY(exitChild, &(processCB->exitChildList), LosProcessCB, siblingList) { + if ((wait == NULL) || (exitChild == wait)) { + return exitChild; + } + } + + return NULL; +} +/// @brief 唤醒等待wakepid结束的task +/// @param taskCB +/// @param wakePID +/// @return +VOID OsWaitWakeTask(LosTaskCB *taskCB, UINTPTR wakePID) +{ + taskCB->waitID = wakePID; // waitID 置为唤醒 + taskCB->ops->wake(taskCB); // 唤醒taskCB +#ifdef LOSCFG_KERNEL_SMP + LOS_MpSchedule(OS_MP_CPU_ALL); +#endif +} +/// @brief 唤醒等待参数进程结束的任务 +/// @param head +/// @param processCB +/// @param anyList +/// @return +STATIC BOOL OsWaitWakeSpecifiedProcess(LOS_DL_LIST *head, const LosProcessCB *processCB, LOS_DL_LIST **anyList) +{ + LOS_DL_LIST *list = head; + LosTaskCB *taskCB = NULL; + UINTPTR processID = 0; + BOOL find = FALSE; + + while (list->pstNext != head) { // 遍历 process->waitlist + taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(list)); + if ((taskCB->waitFlag == OS_PROCESS_WAIT_PRO) && (taskCB->waitID == (UINTPTR)processCB)) { + if (processID == 0) { + processID = taskCB->waitID; + find = TRUE; + } else { + processID = OS_INVALID_VALUE; + } + + OsWaitWakeTask(taskCB, processID);//唤醒这个任务,此时会切到 LOS_Wait runTask->waitFlag = 0;处运行 + continue; + } + + if (taskCB->waitFlag != OS_PROCESS_WAIT_PRO) { + *anyList = list; + break; + } + list = list->pstNext; + } + + return find; +} + +/// @brief 检查父进程的等待任务并唤醒父进程去处理任务 +/// @param parentCB +/// @param processCB +/// @return +STATIC VOID OsWaitCheckAndWakeParentProcess(LosProcessCB *parentCB, const LosProcessCB *processCB) +{ + LOS_DL_LIST *head = &parentCB->waitList; + LOS_DL_LIST *list = NULL; + LosTaskCB *taskCB = NULL; + BOOL findSpecified = FALSE; + + if (LOS_ListEmpty(&parentCB->waitList)) { // 父进程当中是否有在等待子进程退出的任务 + return;//没有就退出 + } + + findSpecified = OsWaitWakeSpecifiedProcess(head, processCB, &list);//找到指定的任务 + if (findSpecified == TRUE) { + /* No thread is waiting for any child process to finish */ + if (LOS_ListEmpty(&parentCB->waitList)) {//没有线程正在等待任何子进程结束 + return; + } else if (!LOS_ListEmpty(&parentCB->childrenList)) { + /* Other child processes exist, and other threads that are waiting + * for the child to finish continue to wait + *////存在其他子进程,正在等待它们的子进程结束而将继续等待 + return; + } + } + + /* Waiting threads are waiting for a specified child process to finish */ + if (list == NULL) {//等待线程正在等待指定的子进程结束 + return; + } + + /* No child processes exist and all waiting threads are awakened */ + if (findSpecified == TRUE) {//所有等待的任务都被一一唤醒 + while (list->pstNext != head) { + taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(list)); + OsWaitWakeTask(taskCB, OS_INVALID_VALUE); + } + return; + } + + while (list->pstNext != head) {//处理 OS_PROCESS_WAIT_GID 标签 + taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(list)); + if (taskCB->waitFlag == OS_PROCESS_WAIT_GID) { + if (taskCB->waitID != (UINTPTR)OS_GET_PGROUP_LEADER(processCB->pgroup)) { + list = list->pstNext; + continue; + } + } + + if (findSpecified == FALSE) { + OsWaitWakeTask(taskCB, (UINTPTR)processCB); + findSpecified = TRUE; + } else { + OsWaitWakeTask(taskCB, OS_INVALID_VALUE); + } + + if (!LOS_ListEmpty(&parentCB->childrenList)) { + break; + } + } + + return; +} +/// @brief 回收指定进程的资源 +/// @param processCB +/// @return +LITE_OS_SEC_TEXT VOID OsProcessResourcesToFree(LosProcessCB *processCB) +{ +#ifdef LOSCFG_KERNEL_VM + if (OsProcessIsUserMode(processCB)) { + (VOID)OsVmSpaceRegionFree(processCB->vmSpace); + } +#endif + +#ifdef LOSCFG_SECURITY_CAPABILITY // 安全开关 + if (processCB->user != NULL) { + (VOID)LOS_MemFree(m_aucSysMem1, processCB->user);// 删除用户 + processCB->user = NULL; // 重置指针为空 + } +#endif + +#ifdef LOSCFG_BASE_CORE_SWTMR_ENABLE + OsSwtmrRecycle((UINTPTR)processCB); + processCB->timerID = (timer_t)(UINTPTR)MAX_INVALID_TIMER_VID; +#endif + +#ifdef LOSCFG_SECURITY_VID + if (processCB->timerIdMap.bitMap != NULL) { + VidMapDestroy(processCB); + processCB->timerIdMap.bitMap = NULL; + } +#endif + +#ifdef LOSCFG_KERNEL_LITEIPC + (VOID)LiteIpcPoolDestroy(processCB->processID); +#endif + +#ifdef LOSCFG_KERNEL_CPUP + UINT32 intSave; + OsCpupBase *processCpup = processCB->processCpup; + SCHEDULER_LOCK(intSave); + processCB->processCpup = NULL; + SCHEDULER_UNLOCK(intSave); + (VOID)LOS_MemFree(m_aucSysMem1, processCpup); +#endif + +#ifdef LOSCFG_PROC_PROCESS_DIR + ProcFreeProcessDir(processCB->procDir); + processCB->procDir = NULL; +#endif + +#ifdef LOSCFG_KERNEL_CONTAINER + OsOsContainersDestroyEarly(processCB); +#endif + +#ifdef LOSCFG_FS_VFS + if (OsProcessIsUserMode(processCB)) { + delete_files(processCB->files); + } + processCB->files = NULL; +#endif + +#ifdef LOSCFG_KERNEL_CONTAINER + OsContainersDestroy(processCB); +#endif + +#ifdef LOSCFG_KERNEL_PLIMITS + OsPLimitsDeleteProcess(processCB); +#endif + if (processCB->resourceLimit != NULL) { + (VOID)LOS_MemFree((VOID *)m_aucSysMem0, processCB->resourceLimit); + processCB->resourceLimit = NULL; + } +} + +/// @brief 回收僵死状态的资源 +/// @param childCB +/// @param pgroup +/// @return +STATIC VOID OsRecycleZombiesProcess(LosProcessCB *childCB, ProcessGroup **pgroup) +{ + ExitProcessGroup(childCB, pgroup); // 推出进程组 + LOS_ListDelete(&childCB->siblingList); ////从子孙链表上摘除 + if (OsProcessIsDead(childCB)) { + OsDeleteTaskFromProcess(childCB->threadGroup);//去掉僵死标签 + childCB->processStatus &= ~OS_PROCESS_STATUS_ZOMBIES; + childCB->processStatus |= OS_PROCESS_FLAG_UNUSED;//贴上没使用标签,进程由进程池分配,进程退出后重新回到空闲进程池 + } + + LOS_ListDelete(&childCB->pendList);//将自己从阻塞链表上摘除,注意有很多原因引起阻塞,pendList挂在哪里就以为这属于哪类阻塞 + if (childCB->processStatus & OS_PROCESS_FLAG_EXIT) {//如果有退出标签 + LOS_ListHeadInsert(&g_processRecycleList, &childCB->pendList);//从头部插入,注意g_processRecyleList挂的是pendList节点,所以要通过OS_PCB_FROM_PENDLIST找. + } else if (OsProcessIsPGroupLeader(childCB)) { + LOS_ListTailInsert(&g_processRecycleList, &childCB->pendList);//从尾部插入,意思就是组长尽量最后一个处理 + } else { + OsInsertPCBToFreeList(childCB);//直接插到freeList中去,可用于重新分配了。 + } +} + +/// @brief 进程退出时子进程由其父进程处理 +/// @param processCB +/// @return +STATIC VOID OsDealAliveChildProcess(LosProcessCB *processCB) +{ + LosProcessCB *childCB = NULL; + LosProcessCB *parentCB = NULL; + LOS_DL_LIST *nextList = NULL; + LOS_DL_LIST *childHead = NULL; + +#ifdef LOSCFG_PID_CONTAINER + if (processCB->processID == OS_USER_ROOT_PROCESS_ID) { + return; + } +#endif + + if (!LOS_ListEmpty(&processCB->childrenList)) { + childHead = processCB->childrenList.pstNext; + LOS_ListDelete(&(processCB->childrenList)); + if (OsProcessIsUserMode(processCB)) { + parentCB = OS_PCB_FROM_PID(OS_USER_ROOT_PROCESS_ID); + } else { + parentCB = OsGetKernelInitProcess(); + } + + for (nextList = childHead; ;) { + childCB = OS_PCB_FROM_SIBLIST(nextList); + childCB->parentProcess = parentCB; + nextList = nextList->pstNext; + if (nextList == childHead) { + break; + } + } + + LOS_ListTailInsertList(&parentCB->childrenList, childHead); + } + + return; +} + +/// @brief 回收指定进程的已经退出(死亡)的子进程所占资源 +/// @param processCB +/// @return +STATIC VOID OsChildProcessResourcesFree(const LosProcessCB *processCB) +{ + LosProcessCB *childCB = NULL; + ProcessGroup *pgroup = NULL; + + while (!LOS_ListEmpty(&((LosProcessCB *)processCB)->exitChildList)) {//遍历直到没有了退出(死亡)的孩子进程 + childCB = LOS_DL_LIST_ENTRY(processCB->exitChildList.pstNext, LosProcessCB, siblingList);//获取孩子进程, + OsRecycleZombiesProcess(childCB, &pgroup);//其中会将childCB从exitChildList链表上摘出去 + (VOID)LOS_MemFree(m_aucSysMem1, pgroup); + } +} +/// @brief 一个进程的自然消亡过程,参数是当前运行的任务 +/// @param processCB +/// @param status +/// @return +VOID OsProcessNaturalExit(LosProcessCB *processCB, UINT32 status) +{ + OsChildProcessResourcesFree(processCB); + + /* is a child process */ + if (processCB->parentProcess != NULL) { + LosProcessCB *parentCB = processCB->parentProcess; + LOS_ListDelete(&processCB->siblingList); + if (!OsProcessExitCodeSignalIsSet(processCB)) { + OsProcessExitCodeSet(processCB, status); + } + LOS_ListTailInsert(&parentCB->exitChildList, &processCB->siblingList); + LOS_ListDelete(&processCB->subordinateGroupList); + LOS_ListTailInsert(&processCB->pgroup->exitProcessList, &processCB->subordinateGroupList); + + OsWaitCheckAndWakeParentProcess(parentCB, processCB); + + OsDealAliveChildProcess(processCB); + + processCB->processStatus |= OS_PROCESS_STATUS_ZOMBIES; +#ifdef LOSCFG_KERNEL_VM + (VOID)OsSendSigToProcess(parentCB, SIGCHLD, OS_KERNEL_KILL_PERMISSION); +#endif + LOS_ListHeadInsert(&g_processRecycleList, &processCB->pendList); + return; + } + + LOS_Panic("pid : %u is the root process exit!\n", processCB->processID); + return; +} + +STATIC VOID SystemProcessEarlyInit(LosProcessCB *processCB) +{ + LOS_ListDelete(&processCB->pendList); +#ifdef LOSCFG_KERNEL_CONTAINER + OsContainerInitSystemProcess(processCB); +#endif + if (processCB == OsGetKernelInitProcess()) { + OsSetMainTaskProcess((UINTPTR)processCB); + } +} + +/// @brief 进程模块初始化,被编译放在代码段 .init +/// @param +/// @return +UINT32 OsProcessInit(VOID) +{ + UINT32 index; + UINT32 size; + UINT32 ret; + + g_processMaxNum = LOSCFG_BASE_CORE_PROCESS_LIMIT; + size = (g_processMaxNum + 1) * sizeof(LosProcessCB); + + g_processCBArray = (LosProcessCB *)LOS_MemAlloc(m_aucSysMem1, size); + if (g_processCBArray == NULL) { + return LOS_NOK; + } + (VOID)memset_s(g_processCBArray, size, 0, size); + + LOS_ListInit(&g_freeProcess); + LOS_ListInit(&g_processRecycleList); + + for (index = 0; index < g_processMaxNum; index++) { + g_processCBArray[index].processID = index; + g_processCBArray[index].processStatus = OS_PROCESS_FLAG_UNUSED; + LOS_ListTailInsert(&g_freeProcess, &g_processCBArray[index].pendList); + } + + /* Default process to prevent thread PCB from being empty */ + g_processCBArray[index].processID = index; + g_processCBArray[index].processStatus = OS_PROCESS_FLAG_UNUSED; + + ret = OsTaskInit((UINTPTR)&g_processCBArray[g_processMaxNum]); + if (ret != LOS_OK) { + (VOID)LOS_MemFree(m_aucSysMem1, g_processCBArray); + return LOS_OK; + } + +#ifdef LOSCFG_KERNEL_CONTAINER + OsInitRootContainer(); +#endif +#ifdef LOSCFG_KERNEL_PLIMITS + OsProcLimiterSetInit(); +#endif + SystemProcessEarlyInit(OsGetIdleProcess()); + SystemProcessEarlyInit(OsGetUserInitProcess()); + SystemProcessEarlyInit(OsGetKernelInitProcess()); + return LOS_OK; +} +/// @brief 进程回收再利用过程 +/// @param +/// @return +LITE_OS_SEC_TEXT VOID OsProcessCBRecycleToFree(VOID) +{ + UINT32 intSave; + LosProcessCB *processCB = NULL; + + SCHEDULER_LOCK(intSave); + while (!LOS_ListEmpty(&g_processRecycleList)) { + processCB = OS_PCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_processRecycleList)); + if (!(processCB->processStatus & OS_PROCESS_FLAG_EXIT)) { + break; + } + SCHEDULER_UNLOCK(intSave); + + OsTaskCBRecycleToFree(); + + SCHEDULER_LOCK(intSave); + processCB->processStatus &= ~OS_PROCESS_FLAG_EXIT; +#ifdef LOSCFG_KERNEL_VM + LosVmSpace *space = NULL; + if (OsProcessIsUserMode(processCB)) { + space = processCB->vmSpace; + } + processCB->vmSpace = NULL; +#endif + /* OS_PROCESS_FLAG_GROUP_LEADER: The lead process group cannot be recycled without destroying the PCB. + * !OS_PROCESS_FLAG_UNUSED: Parent process does not reclaim child process resources. + */ + LOS_ListDelete(&processCB->pendList); + if (OsProcessIsPGroupLeader(processCB) || OsProcessIsDead(processCB)) { + LOS_ListTailInsert(&g_processRecycleList, &processCB->pendList); + } else { + /* Clear the bottom 4 bits of process status */ + OsInsertPCBToFreeList(processCB); + } +#ifdef LOSCFG_KERNEL_VM + SCHEDULER_UNLOCK(intSave); + (VOID)LOS_VmSpaceFree(space); + SCHEDULER_LOCK(intSave); +#endif + } + + SCHEDULER_UNLOCK(intSave); +} +/*! 删除PCB块 其实是 PCB块回归进程池,先进入回收链表*/ +STATIC VOID OsDeInitPCB(LosProcessCB *processCB) +{ + UINT32 intSave; + ProcessGroup *pgroup = NULL; + + if (processCB == NULL) { + return; + } + +#ifdef LOSCFG_KERNEL_CONTAINER + if (OS_PID_CHECK_INVALID(processCB->processID)) { + return; + } +#endif + + OsProcessResourcesToFree(processCB); + + SCHEDULER_LOCK(intSave); + if (processCB->parentProcess != NULL) { + LOS_ListDelete(&processCB->siblingList); + processCB->parentProcess = NULL; + } + + if (processCB->pgroup != NULL) { + ExitProcessGroup(processCB, &pgroup); + } + + processCB->processStatus &= ~OS_PROCESS_STATUS_INIT; + processCB->processStatus |= OS_PROCESS_FLAG_EXIT; + LOS_ListHeadInsert(&g_processRecycleList, &processCB->pendList); + SCHEDULER_UNLOCK(intSave); + + (VOID)LOS_MemFree(m_aucSysMem1, pgroup); + OsWriteResourceEvent(OS_RESOURCE_EVENT_FREE); + return; +} +/// @brief /*! 设置进程的名字*/ +/// @param processCB +/// @param name +/// @return +UINT32 OsSetProcessName(LosProcessCB *processCB, const CHAR *name) +{ + errno_t errRet; + + if (processCB == NULL) { + return LOS_EINVAL; + } + + if (name != NULL) { + errRet = strncpy_s(processCB->processName, OS_PCB_NAME_LEN, name, OS_PCB_NAME_LEN - 1); + if (errRet == EOK) { + return LOS_OK; + } + } + + switch (processCB->processMode) { + case OS_KERNEL_MODE: + errRet = snprintf_s(processCB->processName, OS_PCB_NAME_LEN, OS_PCB_NAME_LEN - 1, + "KerProcess%u", processCB->processID); + break; + default: + errRet = snprintf_s(processCB->processName, OS_PCB_NAME_LEN, OS_PCB_NAME_LEN - 1, + "UserProcess%u", processCB->processID); + break; + } + + if (errRet < 0) { + return LOS_NOK; + } + return LOS_OK; +} +/*! 初始化PCB(进程控制块)*/ +STATIC UINT32 OsInitPCB(LosProcessCB *processCB, UINT32 mode, const CHAR *name) +{ + processCB->processMode = mode; + processCB->processStatus = OS_PROCESS_STATUS_INIT; + processCB->parentProcess = NULL; + processCB->threadGroup = NULL; + processCB->umask = OS_PROCESS_DEFAULT_UMASK; + processCB->timerID = (timer_t)(UINTPTR)MAX_INVALID_TIMER_VID; + + LOS_ListInit(&processCB->threadSiblingList); + LOS_ListInit(&processCB->childrenList); + LOS_ListInit(&processCB->exitChildList); + LOS_ListInit(&(processCB->waitList)); + +#ifdef LOSCFG_KERNEL_VM + if (OsProcessIsUserMode(processCB)) { + processCB->vmSpace = OsCreateUserVmSpace(); + if (processCB->vmSpace == NULL) { + processCB->processStatus = OS_PROCESS_FLAG_UNUSED; + return LOS_ENOMEM; + } + } else { + processCB->vmSpace = LOS_GetKVmSpace(); + } +#endif + +#ifdef LOSCFG_KERNEL_CPUP + processCB->processCpup = (OsCpupBase *)LOS_MemAlloc(m_aucSysMem1, sizeof(OsCpupBase)); + if (processCB->processCpup == NULL) { + return LOS_ENOMEM; + } + (VOID)memset_s(processCB->processCpup, sizeof(OsCpupBase), 0, sizeof(OsCpupBase)); +#endif + +#ifdef LOSCFG_SECURITY_VID + status_t status = VidMapListInit(processCB); + if (status != LOS_OK) { + return LOS_ENOMEM; + } +#endif + +#ifdef LOSCFG_SECURITY_CAPABILITY + OsInitCapability(processCB); +#endif + + if (OsSetProcessName(processCB, name) != LOS_OK) { + return LOS_ENOMEM; + } + + return LOS_OK; +} + +#ifdef LOSCFG_SECURITY_CAPABILITY +STATIC User *OsCreateUser(UINT32 userID, UINT32 gid, UINT32 size) +{ + User *user = LOS_MemAlloc(m_aucSysMem1, sizeof(User) + (size - 1) * sizeof(UINT32)); + if (user == NULL) { + return NULL; + } + + user->userID = userID; + user->effUserID = userID; + user->gid = gid; + user->effGid = gid; + user->groupNumber = size; + user->groups[0] = gid; + return user; +} + +LITE_OS_SEC_TEXT BOOL LOS_CheckInGroups(UINT32 gid) +{ + UINT32 intSave; + UINT32 count; + User *user = NULL; + + SCHEDULER_LOCK(intSave); + user = OsCurrUserGet(); + for (count = 0; count < user->groupNumber; count++) { + if (user->groups[count] == gid) { + SCHEDULER_UNLOCK(intSave); + return TRUE; + } + } + + SCHEDULER_UNLOCK(intSave); + return FALSE; +} +#endif + +LITE_OS_SEC_TEXT INT32 LOS_GetUserID(VOID) +{ +#ifdef LOSCFG_SECURITY_CAPABILITY + UINT32 intSave; + INT32 uid; + + SCHEDULER_LOCK(intSave); +#ifdef LOSCFG_USER_CONTAINER + uid = OsFromKuidMunged(OsCurrentUserContainer(), CurrentCredentials()->uid); +#else + uid = (INT32)OsCurrUserGet()->userID; +#endif + SCHEDULER_UNLOCK(intSave); + return uid; +#else + return 0; +#endif +} + +LITE_OS_SEC_TEXT INT32 LOS_GetGroupID(VOID) +{ +#ifdef LOSCFG_SECURITY_CAPABILITY + UINT32 intSave; + INT32 gid; + + SCHEDULER_LOCK(intSave); +#ifdef LOSCFG_USER_CONTAINER + gid = OsFromKgidMunged(OsCurrentUserContainer(), CurrentCredentials()->gid); +#else + gid = (INT32)OsCurrUserGet()->gid; +#endif + SCHEDULER_UNLOCK(intSave); + + return gid; +#else + return 0; +#endif +} + +STATIC UINT32 OsSystemProcessInit(LosProcessCB *processCB, UINT32 flags, const CHAR *name) +{ + UINT32 ret = OsInitPCB(processCB, flags, name); + if (ret != LOS_OK) { + goto EXIT; + } + +#ifdef LOSCFG_FS_VFS + processCB->files = alloc_files(); + if (processCB->files == NULL) { + ret = LOS_ENOMEM; + goto EXIT; + } +#endif + + ProcessGroup *pgroup = OsCreateProcessGroup(processCB); + if (pgroup == NULL) { + ret = LOS_ENOMEM; + goto EXIT; + } + +#ifdef LOSCFG_SECURITY_CAPABILITY + processCB->user = OsCreateUser(0, 0, 1); + if (processCB->user == NULL) { + ret = LOS_ENOMEM; + goto EXIT; + } +#endif + +#ifdef LOSCFG_KERNEL_PLIMITS + ret = OsPLimitsAddProcess(NULL, processCB); + if (ret != LOS_OK) { + ret = LOS_ENOMEM; + goto EXIT; + } +#endif + return LOS_OK; + +EXIT: + OsDeInitPCB(processCB); + return ret; +} + +LITE_OS_SEC_TEXT_INIT UINT32 OsSystemProcessCreate(VOID) +{ + LosProcessCB *kerInitProcess = OsGetKernelInitProcess(); + UINT32 ret = OsSystemProcessInit(kerInitProcess, OS_KERNEL_MODE, "KProcess"); + if (ret != LOS_OK) { + return ret; + } + kerInitProcess->processStatus &= ~OS_PROCESS_STATUS_INIT; + + LosProcessCB *idleProcess = OsGetIdleProcess(); + ret = OsInitPCB(idleProcess, OS_KERNEL_MODE, "KIdle"); + if (ret != LOS_OK) { + return ret; + } + idleProcess->parentProcess = kerInitProcess; + LOS_ListTailInsert(&kerInitProcess->childrenList, &idleProcess->siblingList); + idleProcess->pgroup = kerInitProcess->pgroup; + LOS_ListTailInsert(&kerInitProcess->pgroup->processList, &idleProcess->subordinateGroupList); +#ifdef LOSCFG_SECURITY_CAPABILITY + idleProcess->user = kerInitProcess->user; +#endif +#ifdef LOSCFG_FS_VFS + idleProcess->files = kerInitProcess->files; +#endif + idleProcess->processStatus &= ~OS_PROCESS_STATUS_INIT; + + ret = OsIdleTaskCreate((UINTPTR)idleProcess); + if (ret != LOS_OK) { + return ret; + } + return LOS_OK; +} + +INT32 OsSchedulerParamCheck(UINT16 policy, BOOL isThread, const LosSchedParam *param) +{ + if (param == NULL) { + return LOS_EINVAL; + } + + if ((policy == LOS_SCHED_RR) || (isThread && (policy == LOS_SCHED_FIFO))) { + if ((param->priority < OS_PROCESS_PRIORITY_HIGHEST) || + (param->priority > OS_PROCESS_PRIORITY_LOWEST)) { + return LOS_EINVAL; + } + return LOS_OK; + } + + if (policy == LOS_SCHED_DEADLINE) { + if ((param->runTimeUs < OS_SCHED_EDF_MIN_RUNTIME) || (param->runTimeUs >= param->deadlineUs)) { + return LOS_EINVAL; + } + if ((param->deadlineUs < OS_SCHED_EDF_MIN_DEADLINE) || (param->deadlineUs > OS_SCHED_EDF_MAX_DEADLINE)) { + return LOS_EINVAL; + } + if (param->periodUs < param->deadlineUs) { + return LOS_EINVAL; + } + return LOS_OK; + } + + return LOS_EINVAL; +} + +STATIC INLINE INT32 ProcessSchedulerParamCheck(INT32 which, INT32 pid, UINT16 policy, const LosSchedParam *param) +{ + if (OS_PID_CHECK_INVALID(pid)) { + return LOS_EINVAL; + } + + if (which != LOS_PRIO_PROCESS) { + return LOS_EINVAL; + } + + return OsSchedulerParamCheck(policy, FALSE, param); +} + +#ifdef LOSCFG_SECURITY_CAPABILITY +STATIC BOOL OsProcessCapPermitCheck(const LosProcessCB *processCB, const SchedParam *param, UINT16 policy, UINT16 prio) +{ + LosProcessCB *runProcess = OsCurrProcessGet(); + + /* always trust kernel process */ + if (!OsProcessIsUserMode(runProcess)) { + return TRUE; + } + + /* user mode process can reduce the priority of itself */ + if ((runProcess->processID == processCB->processID) && (policy == LOS_SCHED_RR) && (prio > param->basePrio)) { + return TRUE; + } + + /* user mode process with privilege of CAP_SCHED_SETPRIORITY can change the priority */ + if (IsCapPermit(CAP_SCHED_SETPRIORITY)) { + return TRUE; + } + return FALSE; +} +#endif + +LITE_OS_SEC_TEXT INT32 OsSetProcessScheduler(INT32 which, INT32 pid, UINT16 policy, const LosSchedParam *schedParam) +{ + SchedParam param = { 0 }; + BOOL needSched = FALSE; + UINT32 intSave; + + INT32 ret = ProcessSchedulerParamCheck(which, pid, policy, schedParam); + if (ret != LOS_OK) { + return -ret; + } + + LosProcessCB *processCB = OS_PCB_FROM_PID(pid); + SCHEDULER_LOCK(intSave); + if (OsProcessIsInactive(processCB)) { + SCHEDULER_UNLOCK(intSave); + return -LOS_ESRCH; + } + + LosTaskCB *taskCB = processCB->threadGroup; + taskCB->ops->schedParamGet(taskCB, ¶m); + +#ifdef LOSCFG_SECURITY_CAPABILITY + if (!OsProcessCapPermitCheck(processCB, ¶m, policy, schedParam->priority)) { + SCHEDULER_UNLOCK(intSave); + return -LOS_EPERM; + } +#endif + + if (param.policy != policy) { + if (policy == LOS_SCHED_DEADLINE) { /* HPF -> EDF */ + if (processCB->threadNumber > 1) { + SCHEDULER_UNLOCK(intSave); + return -LOS_EPERM; + } + OsSchedParamInit(taskCB, policy, NULL, schedParam); + needSched = TRUE; + goto TO_SCHED; + } else if (param.policy == LOS_SCHED_DEADLINE) { /* EDF -> HPF */ + SCHEDULER_UNLOCK(intSave); + return -LOS_EPERM; + } + } + + if (policy == LOS_SCHED_DEADLINE) { + param.runTimeUs = schedParam->runTimeUs; + param.deadlineUs = schedParam->deadlineUs; + param.periodUs = schedParam->periodUs; + } else { + param.basePrio = schedParam->priority; + } + needSched = taskCB->ops->schedParamModify(taskCB, ¶m); + +TO_SCHED: + SCHEDULER_UNLOCK(intSave); + + LOS_MpSchedule(OS_MP_CPU_ALL); + if (needSched && OS_SCHEDULER_ACTIVE) { + LOS_Schedule(); + } + return LOS_OK; +} + +LITE_OS_SEC_TEXT INT32 LOS_SetProcessScheduler(INT32 pid, UINT16 policy, const LosSchedParam *schedParam) +{ + return OsSetProcessScheduler(LOS_PRIO_PROCESS, pid, policy, schedParam); +} + +LITE_OS_SEC_TEXT INT32 LOS_GetProcessScheduler(INT32 pid, INT32 *policy, LosSchedParam *schedParam) +{ + UINT32 intSave; + SchedParam param = { 0 }; + + if (OS_PID_CHECK_INVALID(pid)) { + return -LOS_EINVAL; + } + + if ((policy == NULL) && (schedParam == NULL)) { + return -LOS_EINVAL; + } + + SCHEDULER_LOCK(intSave); + LosProcessCB *processCB = OS_PCB_FROM_PID(pid); + if (OsProcessIsUnused(processCB)) { + SCHEDULER_UNLOCK(intSave); + return -LOS_ESRCH; + } + + LosTaskCB *taskCB = processCB->threadGroup; + taskCB->ops->schedParamGet(taskCB, ¶m); + SCHEDULER_UNLOCK(intSave); + + if (policy != NULL) { + if (param.policy == LOS_SCHED_FIFO) { + *policy = LOS_SCHED_RR; + } else { + *policy = param.policy; + } + } + + if (schedParam != NULL) { + if (param.policy == LOS_SCHED_DEADLINE) { + schedParam->runTimeUs = param.runTimeUs; + schedParam->deadlineUs = param.deadlineUs; + schedParam->periodUs = param.periodUs; + } else { + schedParam->priority = param.basePrio; + } + } + return LOS_OK; +} + +LITE_OS_SEC_TEXT INT32 LOS_SetProcessPriority(INT32 pid, INT32 prio) +{ + INT32 ret; + INT32 policy; + LosSchedParam param = { + .priority = prio, + }; + + ret = LOS_GetProcessScheduler(pid, &policy, NULL); + if (ret != LOS_OK) { + return ret; + } + + if (policy == LOS_SCHED_DEADLINE) { + return -LOS_EINVAL; + } + + return OsSetProcessScheduler(LOS_PRIO_PROCESS, pid, (UINT16)policy, ¶m); +} + +LITE_OS_SEC_TEXT INT32 OsGetProcessPriority(INT32 which, INT32 pid) +{ + UINT32 intSave; + SchedParam param = { 0 }; + (VOID)which; + + if (OS_PID_CHECK_INVALID(pid)) { + return -LOS_EINVAL; + } + + if (which != LOS_PRIO_PROCESS) { + return -LOS_EINVAL; + } + + LosProcessCB *processCB = OS_PCB_FROM_PID(pid); + SCHEDULER_LOCK(intSave); + if (OsProcessIsUnused(processCB)) { + SCHEDULER_UNLOCK(intSave); + return -LOS_ESRCH; + } + + LosTaskCB *taskCB = processCB->threadGroup; + taskCB->ops->schedParamGet(taskCB, ¶m); + + if (param.policy == LOS_SCHED_DEADLINE) { + SCHEDULER_UNLOCK(intSave); + return -LOS_EINVAL; + } + + SCHEDULER_UNLOCK(intSave); + return param.basePrio; +} + +LITE_OS_SEC_TEXT INT32 LOS_GetProcessPriority(INT32 pid) +{ + return OsGetProcessPriority(LOS_PRIO_PROCESS, pid); +} + +STATIC VOID OsWaitInsertWaitListInOrder(LosTaskCB *runTask, LosProcessCB *processCB) +{ + LOS_DL_LIST *head = &processCB->waitList; + LOS_DL_LIST *list = head; + LosTaskCB *taskCB = NULL; + + if (runTask->waitFlag == OS_PROCESS_WAIT_GID) { + while (list->pstNext != head) { + taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(list)); + if (taskCB->waitFlag == OS_PROCESS_WAIT_PRO) { + list = list->pstNext; + continue; + } + break; + } + } else if (runTask->waitFlag == OS_PROCESS_WAIT_ANY) { + while (list->pstNext != head) { + taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(list)); + if (taskCB->waitFlag != OS_PROCESS_WAIT_ANY) { + list = list->pstNext; + continue; + } + break; + } + } + /* if runTask->waitFlag == OS_PROCESS_WAIT_PRO, + * this node is inserted directly into the header of the waitList + */ + (VOID)runTask->ops->wait(runTask, list->pstNext, LOS_WAIT_FOREVER); + return; +} + +STATIC UINT32 WaitFindSpecifiedProcess(UINT32 pid, LosTaskCB *runTask, + const LosProcessCB *processCB, LosProcessCB **childCB) +{ + if (OS_PID_CHECK_INVALID((UINT32)pid)) { + return LOS_ECHILD; + } + + LosProcessCB *waitProcess = OS_PCB_FROM_PID(pid); + if (OsProcessIsUnused(waitProcess)) { + return LOS_ECHILD; + } + +#ifdef LOSCFG_PID_CONTAINER + if (OsPidContainerProcessParentIsRealParent(waitProcess, processCB)) { + *childCB = (LosProcessCB *)processCB; + return LOS_OK; + } +#endif + /* Wait for the child process whose process number is pid. */ + *childCB = OsFindExitChildProcess(processCB, waitProcess); + if (*childCB != NULL) { + return LOS_OK; + } + + if (OsFindChildProcess(processCB, waitProcess) != LOS_OK) { + return LOS_ECHILD; + } + + runTask->waitFlag = OS_PROCESS_WAIT_PRO; + runTask->waitID = (UINTPTR)waitProcess; + return LOS_OK; +} + +STATIC UINT32 OsWaitSetFlag(const LosProcessCB *processCB, INT32 pid, LosProcessCB **child) +{ + UINT32 ret; + LosProcessCB *childCB = NULL; + LosTaskCB *runTask = OsCurrTaskGet(); + + if (pid > 0) { + ret = WaitFindSpecifiedProcess((UINT32)pid, runTask, processCB, &childCB); + if (ret != LOS_OK) { + return ret; + } + if (childCB != NULL) { + goto WAIT_BACK; + } + } else if (pid == 0) { + /* Wait for any child process in the same process group */ + childCB = OsFindGroupExitProcess(processCB->pgroup, OS_INVALID_VALUE); + if (childCB != NULL) { + goto WAIT_BACK; + } + runTask->waitID = (UINTPTR)OS_GET_PGROUP_LEADER(processCB->pgroup); + runTask->waitFlag = OS_PROCESS_WAIT_GID; + } else if (pid == -1) { + /* Wait for any child process */ + childCB = OsFindExitChildProcess(processCB, NULL); + if (childCB != NULL) { + goto WAIT_BACK; + } + runTask->waitID = pid; + runTask->waitFlag = OS_PROCESS_WAIT_ANY; + } else { /* pid < -1 */ + /* Wait for any child process whose group number is the pid absolute value. */ + ProcessGroup *pgroup = OsFindProcessGroup(-pid); + if (pgroup == NULL) { + return LOS_ECHILD; + } + + childCB = OsFindGroupExitProcess(pgroup, OS_INVALID_VALUE); + if (childCB != NULL) { + goto WAIT_BACK; + } + + runTask->waitID = (UINTPTR)OS_GET_PGROUP_LEADER(pgroup); + runTask->waitFlag = OS_PROCESS_WAIT_GID; + } + +WAIT_BACK: + *child = childCB; + return LOS_OK; +} + +STATIC UINT32 OsWaitRecycleChildProcess(const LosProcessCB *childCB, UINT32 intSave, INT32 *status, siginfo_t *info) +{ + ProcessGroup *pgroup = NULL; + UINT32 pid = OsGetPid(childCB); + UINT16 mode = childCB->processMode; + INT32 exitCode = childCB->exitCode; + UINT32 uid = 0; + +#ifdef LOSCFG_SECURITY_CAPABILITY + if (childCB->user != NULL) { + uid = childCB->user->userID; + } +#endif + + OsRecycleZombiesProcess((LosProcessCB *)childCB, &pgroup); + SCHEDULER_UNLOCK(intSave); + + if (status != NULL) { + if (mode == OS_USER_MODE) { + (VOID)LOS_ArchCopyToUser((VOID *)status, (const VOID *)(&(exitCode)), sizeof(INT32)); + } else { + *status = exitCode; + } + } + /* get signal info */ + if (info != NULL) { + siginfo_t tempinfo = { 0 }; + + tempinfo.si_signo = SIGCHLD; + tempinfo.si_errno = 0; + tempinfo.si_pid = pid; + tempinfo.si_uid = uid; + /* + * Process exit code + * 31 15 8 7 0 + * | | exit code | core dump | signal | + */ + if ((exitCode & 0x7f) == 0) { + tempinfo.si_code = CLD_EXITED; + tempinfo.si_status = (exitCode >> 8U); + } else { + tempinfo.si_code = (exitCode & 0x80) ? CLD_DUMPED : CLD_KILLED; + tempinfo.si_status = (exitCode & 0x7f); + } + + if (mode == OS_USER_MODE) { + (VOID)LOS_ArchCopyToUser((VOID *)(info), (const VOID *)(&(tempinfo)), sizeof(siginfo_t)); + } else { + (VOID)memcpy_s((VOID *)(info), sizeof(siginfo_t), (const VOID *)(&(tempinfo)), sizeof(siginfo_t)); + } + } + (VOID)LOS_MemFree(m_aucSysMem1, pgroup); + return pid; +} + +STATIC UINT32 OsWaitChildProcessCheck(LosProcessCB *processCB, INT32 pid, LosProcessCB **childCB) +{ + if (LOS_ListEmpty(&(processCB->childrenList)) && LOS_ListEmpty(&(processCB->exitChildList))) { + return LOS_ECHILD; + } + + return OsWaitSetFlag(processCB, pid, childCB); +} + +STATIC UINT32 OsWaitOptionsCheck(UINT32 options) +{ + UINT32 flag = LOS_WAIT_WNOHANG | LOS_WAIT_WUNTRACED | LOS_WAIT_WCONTINUED; + + flag = ~flag & options; + if (flag != 0) { + return LOS_EINVAL; + } + + if ((options & (LOS_WAIT_WCONTINUED | LOS_WAIT_WUNTRACED)) != 0) { + return LOS_EOPNOTSUPP; + } + + if (OS_INT_ACTIVE) { + return LOS_EINTR; + } + + return LOS_OK; +} + +STATIC INT32 OsWait(INT32 pid, USER INT32 *status, USER siginfo_t *info, UINT32 options, VOID *rusage) +{ + (VOID)rusage; + UINT32 ret; + UINT32 intSave; + LosProcessCB *childCB = NULL; + + LosProcessCB *processCB = OsCurrProcessGet(); + LosTaskCB *runTask = OsCurrTaskGet(); + SCHEDULER_LOCK(intSave); + ret = OsWaitChildProcessCheck(processCB, pid, &childCB); + if (ret != LOS_OK) { + pid = -ret; + goto ERROR; + } + + if (childCB != NULL) { +#ifdef LOSCFG_PID_CONTAINER + if (childCB == processCB) { + SCHEDULER_UNLOCK(intSave); + if (status != NULL) { + (VOID)LOS_ArchCopyToUser((VOID *)status, (const VOID *)(&ret), sizeof(INT32)); + } + return pid; + } +#endif + return (INT32)OsWaitRecycleChildProcess(childCB, intSave, status, info); + } + + if ((options & LOS_WAIT_WNOHANG) != 0) { + runTask->waitFlag = 0; + pid = 0; + goto ERROR; + } + + OsWaitInsertWaitListInOrder(runTask, processCB); + + runTask->waitFlag = 0; + if (runTask->waitID == OS_INVALID_VALUE) { + pid = -LOS_ECHILD; + goto ERROR; + } + + childCB = (LosProcessCB *)runTask->waitID; + if (!OsProcessIsDead(childCB)) { + pid = -LOS_ESRCH; + goto ERROR; + } + + return (INT32)OsWaitRecycleChildProcess(childCB, intSave, status, info); + +ERROR: + SCHEDULER_UNLOCK(intSave); + return pid; +} + +LITE_OS_SEC_TEXT INT32 LOS_Wait(INT32 pid, USER INT32 *status, UINT32 options, VOID *rusage) +{ + (VOID)rusage; + UINT32 ret; + + ret = OsWaitOptionsCheck(options); + if (ret != LOS_OK) { + return -ret; + } + + return OsWait(pid, status, NULL, options, NULL); +} + +STATIC UINT32 OsWaitidOptionsCheck(UINT32 options) +{ + UINT32 flag = LOS_WAIT_WNOHANG | LOS_WAIT_WSTOPPED | LOS_WAIT_WCONTINUED | LOS_WAIT_WEXITED | LOS_WAIT_WNOWAIT; + + flag = ~flag & options; + if ((flag != 0) || (options == 0)) { + return LOS_EINVAL; + } + + /* + * only support LOS_WAIT_WNOHANG | LOS_WAIT_WEXITED + * notsupport LOS_WAIT_WSTOPPED | LOS_WAIT_WCONTINUED | LOS_WAIT_WNOWAIT + */ + if ((options & (LOS_WAIT_WSTOPPED | LOS_WAIT_WCONTINUED | LOS_WAIT_WNOWAIT)) != 0) { + return LOS_EOPNOTSUPP; + } + + if (OS_INT_ACTIVE) { + return LOS_EINTR; + } + + return LOS_OK; +} + +LITE_OS_SEC_TEXT INT32 LOS_Waitid(INT32 pid, USER siginfo_t *info, UINT32 options, VOID *rusage) +{ + (VOID)rusage; + UINT32 ret; + + /* check options value */ + ret = OsWaitidOptionsCheck(options); + if (ret != LOS_OK) { + return -ret; + } + + return OsWait(pid, NULL, info, options, NULL); +} + +UINT32 OsGetProcessGroupCB(UINT32 pid, UINTPTR *ppgroupLeader) +{ + UINT32 intSave; + + if (OS_PID_CHECK_INVALID(pid) || (ppgroupLeader == NULL)) { + return LOS_EINVAL; + } + + SCHEDULER_LOCK(intSave); + LosProcessCB *processCB = OS_PCB_FROM_PID(pid); + if (OsProcessIsUnused(processCB)) { + SCHEDULER_UNLOCK(intSave); + return LOS_ESRCH; + } + + *ppgroupLeader = (UINTPTR)OS_GET_PGROUP_LEADER(processCB->pgroup); + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +STATIC UINT32 OsSetProcessGroupCheck(const LosProcessCB *processCB, LosProcessCB *pgroupCB) +{ + LosProcessCB *runProcessCB = OsCurrProcessGet(); + + if (OsProcessIsInactive(processCB)) { + return LOS_ESRCH; + } + +#ifdef LOSCFG_PID_CONTAINER + if ((processCB->processID == OS_USER_ROOT_PROCESS_ID) || OS_PROCESS_CONTAINER_CHECK(processCB, runProcessCB)) { + return LOS_EPERM; + } +#endif + + if (!OsProcessIsUserMode(processCB) || !OsProcessIsUserMode(pgroupCB)) { + return LOS_EPERM; + } + + if (runProcessCB == processCB->parentProcess) { + if (processCB->processStatus & OS_PROCESS_FLAG_ALREADY_EXEC) { + return LOS_EACCES; + } + } else if (processCB->processID != runProcessCB->processID) { + return LOS_ESRCH; + } + + /* Add the process to another existing process group */ + if (processCB != pgroupCB) { + if (!OsProcessIsPGroupLeader(pgroupCB)) { + return LOS_EPERM; + } + + if ((pgroupCB->parentProcess != processCB->parentProcess) && (pgroupCB != processCB->parentProcess)) { + return LOS_EPERM; + } + } + + return LOS_OK; +} + +STATIC UINT32 OsSetProcessGroupIDUnsafe(UINT32 pid, UINT32 gid, ProcessGroup **pgroup) +{ + LosProcessCB *processCB = OS_PCB_FROM_PID(pid); + ProcessGroup *rootPGroup = OS_ROOT_PGRP(OsCurrProcessGet()); + LosProcessCB *pgroupCB = OS_PCB_FROM_PID(gid); + UINT32 ret = OsSetProcessGroupCheck(processCB, pgroupCB); + if (ret != LOS_OK) { + return ret; + } + + if (OS_GET_PGROUP_LEADER(processCB->pgroup) == pgroupCB) { + return LOS_OK; + } + + ProcessGroup *oldPGroup = processCB->pgroup; + ExitProcessGroup(processCB, pgroup); + + ProcessGroup *newPGroup = OsFindProcessGroup(gid); + if (newPGroup != NULL) { + LOS_ListTailInsert(&newPGroup->processList, &processCB->subordinateGroupList); + processCB->pgroup = newPGroup; + return LOS_OK; + } + + newPGroup = OsCreateProcessGroup(pgroupCB); + if (newPGroup == NULL) { + LOS_ListTailInsert(&oldPGroup->processList, &processCB->subordinateGroupList); + processCB->pgroup = oldPGroup; + if (*pgroup != NULL) { + LOS_ListTailInsert(&rootPGroup->groupList, &oldPGroup->groupList); + processCB = OS_GET_PGROUP_LEADER(oldPGroup); + processCB->processStatus |= OS_PROCESS_FLAG_GROUP_LEADER; + *pgroup = NULL; + } + return LOS_EPERM; + } + return LOS_OK; +} + +LITE_OS_SEC_TEXT INT32 OsSetProcessGroupID(UINT32 pid, UINT32 gid) +{ + ProcessGroup *pgroup = NULL; + UINT32 ret; + UINT32 intSave; + + if ((OS_PID_CHECK_INVALID(pid)) || (OS_PID_CHECK_INVALID(gid))) { + return -LOS_EINVAL; + } + + SCHEDULER_LOCK(intSave); + ret = OsSetProcessGroupIDUnsafe(pid, gid, &pgroup); + SCHEDULER_UNLOCK(intSave); + (VOID)LOS_MemFree(m_aucSysMem1, pgroup); + return -ret; +} + +LITE_OS_SEC_TEXT INT32 OsSetCurrProcessGroupID(UINT32 gid) +{ + return OsSetProcessGroupID(OsCurrProcessGet()->processID, gid); +} + +LITE_OS_SEC_TEXT INT32 LOS_GetProcessGroupID(UINT32 pid) +{ + INT32 gid; + UINT32 intSave; + + if (OS_PID_CHECK_INVALID(pid)) { + return -LOS_EINVAL; + } + + SCHEDULER_LOCK(intSave); + LosProcessCB *processCB = OS_PCB_FROM_PID(pid); + if (OsProcessIsUnused(processCB)) { + gid = -LOS_ESRCH; + goto EXIT; + } + + processCB = OS_GET_PGROUP_LEADER(processCB->pgroup); + gid = (INT32)processCB->processID; + +EXIT: + SCHEDULER_UNLOCK(intSave); + return gid; +} + +LITE_OS_SEC_TEXT INT32 LOS_GetCurrProcessGroupID(VOID) +{ + return LOS_GetProcessGroupID(OsCurrProcessGet()->processID); +} + +#ifdef LOSCFG_KERNEL_VM +STATIC LosProcessCB *OsGetFreePCB(VOID) +{ + LosProcessCB *processCB = NULL; + UINT32 intSave; + + SCHEDULER_LOCK(intSave); + if (LOS_ListEmpty(&g_freeProcess)) { + SCHEDULER_UNLOCK(intSave); + PRINT_ERR("No idle PCB in the system!\n"); + return NULL; + } + + processCB = OS_PCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_freeProcess)); + LOS_ListDelete(&processCB->pendList); + SCHEDULER_UNLOCK(intSave); + + return processCB; +} + +STATIC VOID *OsUserInitStackAlloc(LosProcessCB *processCB, UINT32 *size) +{ + LosVmMapRegion *region = NULL; + UINT32 stackSize = ALIGN(OS_USER_TASK_STACK_SIZE, PAGE_SIZE); + + region = LOS_RegionAlloc(processCB->vmSpace, 0, stackSize, + VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_READ | + VM_MAP_REGION_FLAG_PERM_WRITE, 0); + if (region == NULL) { + return NULL; + } + + LOS_SetRegionTypeAnon(region); + region->regionFlags |= VM_MAP_REGION_FLAG_STACK; + + *size = stackSize; + + return (VOID *)(UINTPTR)region->range.base; +} + +#ifdef LOSCFG_KERNEL_DYNLOAD +LITE_OS_SEC_TEXT VOID OsExecProcessVmSpaceRestore(LosVmSpace *oldSpace) +{ + LosProcessCB *processCB = OsCurrProcessGet(); + LosTaskCB *runTask = OsCurrTaskGet(); + + processCB->vmSpace = oldSpace; + runTask->archMmu = (UINTPTR)&processCB->vmSpace->archMmu; + LOS_ArchMmuContextSwitch((LosArchMmu *)runTask->archMmu); +} + +LITE_OS_SEC_TEXT LosVmSpace *OsExecProcessVmSpaceReplace(LosVmSpace *newSpace, UINTPTR stackBase, INT32 randomDevFD) +{ + LosProcessCB *processCB = OsCurrProcessGet(); + LosTaskCB *runTask = OsCurrTaskGet(); + + OsProcessThreadGroupDestroy(); + OsTaskCBRecycleToFree(); + + LosVmSpace *oldSpace = processCB->vmSpace; + processCB->vmSpace = newSpace; + processCB->vmSpace->heapBase += OsGetRndOffset(randomDevFD); + processCB->vmSpace->heapNow = processCB->vmSpace->heapBase; + processCB->vmSpace->mapBase += OsGetRndOffset(randomDevFD); + processCB->vmSpace->mapSize = stackBase - processCB->vmSpace->mapBase; + runTask->archMmu = (UINTPTR)&processCB->vmSpace->archMmu; + LOS_ArchMmuContextSwitch((LosArchMmu *)runTask->archMmu); + return oldSpace; +} + +LITE_OS_SEC_TEXT UINT32 OsExecRecycleAndInit(LosProcessCB *processCB, const CHAR *name, + LosVmSpace *oldSpace, UINTPTR oldFiles) +{ + UINT32 ret; + const CHAR *processName = NULL; + + if ((processCB == NULL) || (name == NULL)) { + return LOS_NOK; + } + + processName = strrchr(name, '/'); + processName = (processName == NULL) ? name : (processName + 1); /* 1: Do not include '/' */ + + ret = (UINT32)OsSetTaskName(OsCurrTaskGet(), processName, TRUE); + if (ret != LOS_OK) { + return ret; + } + +#ifdef LOSCFG_KERNEL_LITEIPC + (VOID)LiteIpcPoolDestroy(processCB->processID); +#endif + + processCB->sigHandler = 0; + OsCurrTaskGet()->sig.sigprocmask = 0; + + LOS_VmSpaceFree(oldSpace); +#ifdef LOSCFG_FS_VFS + CloseOnExec((struct files_struct *)oldFiles); + delete_files_snapshot((struct files_struct *)oldFiles); +#endif + +#ifdef LOSCFG_BASE_CORE_SWTMR_ENABLE + OsSwtmrRecycle((UINTPTR)processCB); + processCB->timerID = (timer_t)(UINTPTR)MAX_INVALID_TIMER_VID; +#endif + +#ifdef LOSCFG_SECURITY_VID + VidMapDestroy(processCB); + ret = VidMapListInit(processCB); + if (ret != LOS_OK) { + return LOS_NOK; + } +#endif + + processCB->processStatus &= ~OS_PROCESS_FLAG_EXIT; + processCB->processStatus |= OS_PROCESS_FLAG_ALREADY_EXEC; + + return LOS_OK; +} + +LITE_OS_SEC_TEXT UINT32 OsExecStart(const TSK_ENTRY_FUNC entry, UINTPTR sp, UINTPTR mapBase, UINT32 mapSize) +{ + UINT32 intSave; + + if (entry == NULL) { + return LOS_NOK; + } + + if ((sp == 0) || (LOS_Align(sp, LOSCFG_STACK_POINT_ALIGN_SIZE) != sp)) { + return LOS_NOK; + } + + if ((mapBase == 0) || (mapSize == 0) || (sp <= mapBase) || (sp > (mapBase + mapSize))) { + return LOS_NOK; + } + + LosTaskCB *taskCB = OsCurrTaskGet(); + + SCHEDULER_LOCK(intSave); + taskCB->userMapBase = mapBase; + taskCB->userMapSize = mapSize; + taskCB->taskEntry = (TSK_ENTRY_FUNC)entry; + + TaskContext *taskContext = (TaskContext *)OsTaskStackInit(taskCB->taskID, taskCB->stackSize, + (VOID *)taskCB->topOfStack, FALSE); + OsUserTaskStackInit(taskContext, (UINTPTR)taskCB->taskEntry, sp); + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} +#endif + +STATIC UINT32 OsUserInitProcessStart(LosProcessCB *processCB, TSK_INIT_PARAM_S *param) +{ + UINT32 intSave; + INT32 ret; + + UINT32 taskID = OsCreateUserTask((UINTPTR)processCB, param); + if (taskID == OS_INVALID_VALUE) { + return LOS_NOK; + } + + ret = LOS_SetProcessPriority(processCB->processID, OS_PROCESS_USERINIT_PRIORITY); + if (ret != LOS_OK) { + PRINT_ERR("User init process set priority failed! ERROR:%d \n", ret); + goto EXIT; + } + + SCHEDULER_LOCK(intSave); + processCB->processStatus &= ~OS_PROCESS_STATUS_INIT; + SCHEDULER_UNLOCK(intSave); + + ret = LOS_SetTaskScheduler(taskID, LOS_SCHED_RR, OS_TASK_PRIORITY_LOWEST); + if (ret != LOS_OK) { + PRINT_ERR("User init process set scheduler failed! ERROR:%d \n", ret); + goto EXIT; + } + + return LOS_OK; + +EXIT: + (VOID)LOS_TaskDelete(taskID); + return ret; +} + +STATIC UINT32 OsLoadUserInit(LosProcessCB *processCB) +{ + /* userInitTextStart ----- + * | user text | + * + * | user data | initSize + * userInitBssStart --- + * | user bss | initBssSize + * userInitEnd --- ----- + */ + errno_t errRet; + INT32 ret; + CHAR *userInitTextStart = (CHAR *)&__user_init_entry; + CHAR *userInitBssStart = (CHAR *)&__user_init_bss; + CHAR *userInitEnd = (CHAR *)&__user_init_end; + UINT32 initBssSize = userInitEnd - userInitBssStart; + UINT32 initSize = userInitEnd - userInitTextStart; + VOID *userBss = NULL; + VOID *userText = NULL; + + if ((LOS_Align((UINTPTR)userInitTextStart, PAGE_SIZE) != (UINTPTR)userInitTextStart) || + (LOS_Align((UINTPTR)userInitEnd, PAGE_SIZE) != (UINTPTR)userInitEnd)) { + return LOS_EINVAL; + } + + if ((initSize == 0) || (initSize <= initBssSize)) { + return LOS_EINVAL; + } + + userText = LOS_PhysPagesAllocContiguous(initSize >> PAGE_SHIFT); + if (userText == NULL) { + return LOS_NOK; + } + + errRet = memcpy_s(userText, initSize, (VOID *)&__user_init_load_addr, initSize - initBssSize); + if (errRet != EOK) { + PRINT_ERR("Load user init text, data and bss failed! err : %d\n", errRet); + goto ERROR; + } + ret = LOS_VaddrToPaddrMmap(processCB->vmSpace, (VADDR_T)(UINTPTR)userInitTextStart, LOS_PaddrQuery(userText), + initSize, VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE | + VM_MAP_REGION_FLAG_FIXED | VM_MAP_REGION_FLAG_PERM_EXECUTE | + VM_MAP_REGION_FLAG_PERM_USER); + if (ret < 0) { + PRINT_ERR("Mmap user init text, data and bss failed! err : %d\n", ret); + goto ERROR; + } + + /* The User init boot segment may not actually exist */ + if (initBssSize != 0) { + userBss = (VOID *)((UINTPTR)userText + userInitBssStart - userInitTextStart); + errRet = memset_s(userBss, initBssSize, 0, initBssSize); + if (errRet != EOK) { + PRINT_ERR("memset user init bss failed! err : %d\n", errRet); + goto ERROR; + } + } + + return LOS_OK; + +ERROR: + (VOID)LOS_PhysPagesFreeContiguous(userText, initSize >> PAGE_SHIFT); + return LOS_NOK; +} + +LITE_OS_SEC_TEXT_INIT UINT32 OsUserInitProcess(VOID) +{ + UINT32 ret; + UINT32 size; + TSK_INIT_PARAM_S param = { 0 }; + VOID *stack = NULL; + + LosProcessCB *processCB = OsGetUserInitProcess(); + ret = OsSystemProcessInit(processCB, OS_USER_MODE, "Init"); + if (ret != LOS_OK) { + return ret; + } + + ret = OsLoadUserInit(processCB); + if (ret != LOS_OK) { + goto ERROR; + } + + stack = OsUserInitStackAlloc(processCB, &size); + if (stack == NULL) { + PRINT_ERR("Alloc user init process user stack failed!\n"); + goto ERROR; + } + + param.pfnTaskEntry = (TSK_ENTRY_FUNC)(CHAR *)&__user_init_entry; + param.userParam.userSP = (UINTPTR)stack + size; + param.userParam.userMapBase = (UINTPTR)stack; + param.userParam.userMapSize = size; + param.uwResved = OS_TASK_FLAG_PTHREAD_JOIN; + ret = OsUserInitProcessStart(processCB, ¶m); + if (ret != LOS_OK) { + (VOID)OsUnMMap(processCB->vmSpace, param.userParam.userMapBase, param.userParam.userMapSize); + goto ERROR; + } + + return LOS_OK; + +ERROR: + OsDeInitPCB(processCB); + return ret; +} + +STATIC UINT32 OsCopyUser(LosProcessCB *childCB, LosProcessCB *parentCB) +{ +#ifdef LOSCFG_SECURITY_CAPABILITY + UINT32 size = sizeof(User) + sizeof(UINT32) * (parentCB->user->groupNumber - 1); + childCB->user = LOS_MemAlloc(m_aucSysMem1, size); + if (childCB->user == NULL) { + return LOS_ENOMEM; + } + + (VOID)memcpy_s(childCB->user, size, parentCB->user, size); +#endif + return LOS_OK; +} + +STATIC VOID GetCopyTaskParam(LosProcessCB *childProcessCB, UINTPTR entry, UINT32 size, + TSK_INIT_PARAM_S *taskParam, SchedParam *param) +{ + UINT32 intSave; + LosTaskCB *runTask = OsCurrTaskGet(); + + SCHEDULER_LOCK(intSave); + if (OsProcessIsUserMode(childProcessCB)) { + taskParam->pfnTaskEntry = runTask->taskEntry; + taskParam->uwStackSize = runTask->stackSize; + taskParam->userParam.userArea = runTask->userArea; + taskParam->userParam.userMapBase = runTask->userMapBase; + taskParam->userParam.userMapSize = runTask->userMapSize; + } else { + taskParam->pfnTaskEntry = (TSK_ENTRY_FUNC)entry; + taskParam->uwStackSize = size; + } + if (runTask->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) { + taskParam->uwResved = LOS_TASK_ATTR_JOINABLE; + } + + runTask->ops->schedParamGet(runTask, param); + SCHEDULER_UNLOCK(intSave); + + taskParam->policy = param->policy; + taskParam->runTimeUs = param->runTimeUs; + taskParam->deadlineUs = param->deadlineUs; + taskParam->periodUs = param->periodUs; + taskParam->usTaskPrio = param->priority; + taskParam->processID = (UINTPTR)childProcessCB; +} + +STATIC UINT32 OsCopyTask(UINT32 flags, LosProcessCB *childProcessCB, const CHAR *name, UINTPTR entry, UINT32 size) +{ + LosTaskCB *runTask = OsCurrTaskGet(); + TSK_INIT_PARAM_S taskParam = { 0 }; + UINT32 ret, taskID, intSave; + SchedParam param = { 0 }; + + taskParam.pcName = (CHAR *)name; + GetCopyTaskParam(childProcessCB, entry, size, &taskParam, ¶m); + + ret = LOS_TaskCreateOnly(&taskID, &taskParam); + if (ret != LOS_OK) { + if (ret == LOS_ERRNO_TSK_TCB_UNAVAILABLE) { + return LOS_EAGAIN; + } + return LOS_ENOMEM; + } + + LosTaskCB *childTaskCB = childProcessCB->threadGroup; + childTaskCB->taskStatus = runTask->taskStatus; + childTaskCB->ops->schedParamModify(childTaskCB, ¶m); + if (childTaskCB->taskStatus & OS_TASK_STATUS_RUNNING) { + childTaskCB->taskStatus &= ~OS_TASK_STATUS_RUNNING; + } else { + if (OS_SCHEDULER_ACTIVE) { + LOS_Panic("Clone thread status not running error status: 0x%x\n", childTaskCB->taskStatus); + } + childTaskCB->taskStatus &= ~OS_TASK_STATUS_UNUSED; + } + + if (OsProcessIsUserMode(childProcessCB)) { + SCHEDULER_LOCK(intSave); + OsUserCloneParentStack(childTaskCB->stackPointer, entry, runTask->topOfStack, runTask->stackSize); + SCHEDULER_UNLOCK(intSave); + } + return LOS_OK; +} + +STATIC UINT32 OsCopyParent(UINT32 flags, LosProcessCB *childProcessCB, LosProcessCB *runProcessCB) +{ + UINT32 intSave; + LosProcessCB *parentProcessCB = NULL; + + SCHEDULER_LOCK(intSave); + if (childProcessCB->parentProcess == NULL) { + if (flags & CLONE_PARENT) { + parentProcessCB = runProcessCB->parentProcess; + } else { + parentProcessCB = runProcessCB; + } + childProcessCB->parentProcess = parentProcessCB; + LOS_ListTailInsert(&parentProcessCB->childrenList, &childProcessCB->siblingList); + } + + if (childProcessCB->pgroup == NULL) { + childProcessCB->pgroup = parentProcessCB->pgroup; + LOS_ListTailInsert(&parentProcessCB->pgroup->processList, &childProcessCB->subordinateGroupList); + } + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +STATIC UINT32 OsCopyMM(UINT32 flags, LosProcessCB *childProcessCB, LosProcessCB *runProcessCB) +{ + status_t status; + UINT32 intSave; + + if (!OsProcessIsUserMode(childProcessCB)) { + return LOS_OK; + } + + if (flags & CLONE_VM) { + SCHEDULER_LOCK(intSave); + childProcessCB->vmSpace->archMmu.virtTtb = runProcessCB->vmSpace->archMmu.virtTtb; + childProcessCB->vmSpace->archMmu.physTtb = runProcessCB->vmSpace->archMmu.physTtb; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; + } + + status = LOS_VmSpaceClone(flags, runProcessCB->vmSpace, childProcessCB->vmSpace); + if (status != LOS_OK) { + return LOS_ENOMEM; + } + return LOS_OK; +} + +STATIC UINT32 OsCopyFile(UINT32 flags, LosProcessCB *childProcessCB, LosProcessCB *runProcessCB) +{ +#ifdef LOSCFG_FS_VFS + if (flags & CLONE_FILES) { + childProcessCB->files = runProcessCB->files; + } else { +#ifdef LOSCFG_IPC_CONTAINER + if (flags & CLONE_NEWIPC) { + OsCurrTaskGet()->cloneIpc = TRUE; + } +#endif + childProcessCB->files = dup_fd(runProcessCB->files); +#ifdef LOSCFG_IPC_CONTAINER + OsCurrTaskGet()->cloneIpc = FALSE; +#endif + } + if (childProcessCB->files == NULL) { + return LOS_ENOMEM; + } + +#ifdef LOSCFG_PROC_PROCESS_DIR + INT32 ret = ProcCreateProcessDir(OsGetRootPid(childProcessCB), (UINTPTR)childProcessCB); + if (ret < 0) { + PRINT_ERR("ProcCreateProcessDir failed, pid = %u\n", childProcessCB->processID); + return LOS_EBADF; + } +#endif +#endif + + childProcessCB->consoleID = runProcessCB->consoleID; + childProcessCB->umask = runProcessCB->umask; + return LOS_OK; +} + +STATIC UINT32 OsForkInitPCB(UINT32 flags, LosProcessCB *child, const CHAR *name, UINTPTR sp, UINT32 size) +{ + UINT32 ret; + LosProcessCB *run = OsCurrProcessGet(); + + ret = OsCopyParent(flags, child, run); + if (ret != LOS_OK) { + return ret; + } + + return OsCopyTask(flags, child, name, sp, size); +} + +STATIC UINT32 OsChildSetProcessGroupAndSched(LosProcessCB *child, LosProcessCB *run) +{ + UINT32 intSave; + UINT32 ret; + ProcessGroup *pgroup = NULL; + + SCHEDULER_LOCK(intSave); + if ((UINTPTR)OS_GET_PGROUP_LEADER(run->pgroup) == OS_USER_PRIVILEGE_PROCESS_GROUP) { + ret = OsSetProcessGroupIDUnsafe(child->processID, child->processID, &pgroup); + if (ret != LOS_OK) { + SCHEDULER_UNLOCK(intSave); + return LOS_ENOMEM; + } + } + + child->processStatus &= ~OS_PROCESS_STATUS_INIT; + LosTaskCB *taskCB = child->threadGroup; + taskCB->ops->enqueue(OsSchedRunqueue(), taskCB); + SCHEDULER_UNLOCK(intSave); + + (VOID)LOS_MemFree(m_aucSysMem1, pgroup); + return LOS_OK; +} + +STATIC UINT32 OsCopyProcessResources(UINT32 flags, LosProcessCB *child, LosProcessCB *run) +{ + UINT32 ret; + + ret = OsCopyUser(child, run); + if (ret != LOS_OK) { + return ret; + } + + ret = OsCopyMM(flags, child, run); + if (ret != LOS_OK) { + return ret; + } + + ret = OsCopyFile(flags, child, run); + if (ret != LOS_OK) { + return ret; + } + +#ifdef LOSCFG_KERNEL_LITEIPC + if (run->ipcInfo != NULL) { + child->ipcInfo = LiteIpcPoolReInit((const ProcIpcInfo *)(run->ipcInfo)); + if (child->ipcInfo == NULL) { + return LOS_ENOMEM; + } + } +#endif + +#ifdef LOSCFG_SECURITY_CAPABILITY + OsCopyCapability(run, child); +#endif + return LOS_OK; +} + +STATIC INT32 OsCopyProcess(UINT32 flags, const CHAR *name, UINTPTR sp, UINT32 size) +{ + UINT32 ret, processID; + LosProcessCB *run = OsCurrProcessGet(); // 获取当前进程 + + LosProcessCB *child = OsGetFreePCB(); // 指向新的进程块 + if (child == NULL) { + return -LOS_EAGAIN; + } + processID = child->processID; // 进程ID(cpid) + + ret = OsInitPCB(child, run->processMode, name); // 初始化PCB + if (ret != LOS_OK) { + goto ERROR_INIT; + } + +#ifdef LOSCFG_KERNEL_CONTAINER + ret = OsCopyContainers(flags, child, run, &processID); + if (ret != LOS_OK) { + goto ERROR_INIT; + } + +#ifdef LOSCFG_KERNEL_PLIMITS + ret = OsPLimitsAddProcess(run->plimits, child); + if (ret != LOS_OK) { + goto ERROR_INIT; + } +#endif +#endif + + ret = OsForkInitPCB(flags, child, name, sp, size); + if (ret != LOS_OK) { + goto ERROR_INIT; + } + + ret = OsCopyProcessResources(flags, child, run); //.. 拷贝进程的资源 + if (ret != LOS_OK) { + goto ERROR_TASK; + } + + ret = OsChildSetProcessGroupAndSched(child, run); // 设置进程组和加入进程调度就绪队列 + if (ret != LOS_OK) { + goto ERROR_TASK; + } + + LOS_MpSchedule(OS_MP_CPU_ALL); // 给CPU发送接收调度的 + if (OS_SCHEDULER_ACTIVE) { + LOS_Schedule(); + } + + return processID; + +ERROR_TASK: + (VOID)LOS_TaskDelete(child->threadGroup->taskID); +ERROR_INIT: + OsDeInitPCB(child); + return -ret; +} +/*! + * @brief OsClone 进程克隆 + * + * @param flags + * @param size 进程主任务内核栈大小 + * @param sp 进程主任务的入口函数 + * @return + * + * @see + */ +LITE_OS_SEC_TEXT INT32 OsClone(UINT32 flags, UINTPTR sp, UINT32 size) +{ + UINT32 cloneFlag = CLONE_PARENT | CLONE_THREAD | SIGCHLD; +#ifdef LOSCFG_KERNEL_CONTAINER +#ifdef LOSCFG_PID_CONTAINER + cloneFlag |= CLONE_NEWPID; + // 指向当前进程控制块的指针 + LosProcessCB *curr = OsCurrProcessGet(); + if (((flags & CLONE_NEWPID) != 0) && ((flags & (CLONE_PARENT | CLONE_THREAD)) != 0)) { + return -LOS_EINVAL; + } + + if (OS_PROCESS_PID_FOR_CONTAINER_CHECK(curr) && ((flags & CLONE_NEWPID) != 0)) { + return -LOS_EINVAL; + } + + if (OS_PROCESS_PID_FOR_CONTAINER_CHECK(curr) && ((flags & (CLONE_PARENT | CLONE_THREAD)) != 0)) { + return -LOS_EINVAL; + } +#endif +#ifdef LOSCFG_UTS_CONTAINER + cloneFlag |= CLONE_NEWUTS; +#endif +#ifdef LOSCFG_MNT_CONTAINER + cloneFlag |= CLONE_NEWNS; +#endif +#ifdef LOSCFG_IPC_CONTAINER + cloneFlag |= CLONE_NEWIPC; + if (((flags & CLONE_NEWIPC) != 0) && ((flags & CLONE_FILES) != 0)) { + return -LOS_EINVAL; + } +#endif +#ifdef LOSCFG_TIME_CONTAINER + cloneFlag |= CLONE_NEWTIME; +#endif +#ifdef LOSCFG_USER_CONTAINER + cloneFlag |= CLONE_NEWUSER; +#endif +#ifdef LOSCFG_NET_CONTAINER + cloneFlag |= CLONE_NEWNET; +#endif +#endif + + if (flags & (~cloneFlag)) { + return -LOS_EOPNOTSUPP; + } + + return OsCopyProcess(cloneFlag & flags, NULL, sp, size); +} + +LITE_OS_SEC_TEXT INT32 LOS_Fork(UINT32 flags, const CHAR *name, const TSK_ENTRY_FUNC entry, UINT32 stackSize) +{ + UINT32 cloneFlag = CLONE_PARENT | CLONE_THREAD | CLONE_VFORK | CLONE_FILES; + + if (flags & (~cloneFlag)) { + PRINT_WARN("Clone dont support some flags!\n"); + } + + flags |= CLONE_FILES; + return OsCopyProcess(cloneFlag & flags, name, (UINTPTR)entry, stackSize); +} +#else +LITE_OS_SEC_TEXT_INIT UINT32 OsUserInitProcess(VOID) +{ + return 0; +} +#endif + +LITE_OS_SEC_TEXT VOID LOS_Exit(INT32 status) +{ + UINT32 intSave; + + (void)status; + + /* The exit of a kernel - state process must be kernel - state and all threads must actively exit */ + LosProcessCB *processCB = OsCurrProcessGet(); + SCHEDULER_LOCK(intSave); + if (!OsProcessIsUserMode(processCB) && (processCB->threadNumber != 1)) { + SCHEDULER_UNLOCK(intSave); + PRINT_ERR("Kernel-state processes with multiple threads are not allowed to exit directly\n"); + return; + } + SCHEDULER_UNLOCK(intSave); + + OsProcessThreadGroupDestroy(); + OsRunningTaskToExit(OsCurrTaskGet(), OS_PRO_EXIT_OK); +} + +LITE_OS_SEC_TEXT INT32 LOS_GetUsedPIDList(UINT32 *pidList, INT32 pidMaxNum) +{ + LosProcessCB *pcb = NULL; + INT32 num = 0; + UINT32 intSave; + UINT32 pid = 1; + // TSK_ENTRY_FUNC + if (pidList == NULL) { + return 0; + } + SCHEDULER_LOCK(intSave); + while (OsProcessIDUserCheckInvalid(pid) == false) { + pcb = OS_PCB_FROM_PID(pid); + pid++; + if (OsProcessIsUnused(pcb)) { + continue; + } + pidList[num] = pcb->processID; + num++; + if (num >= pidMaxNum) { + break; + } + } + SCHEDULER_UNLOCK(intSave); + return num; +} + +#ifdef LOSCFG_FS_VFS +LITE_OS_SEC_TEXT struct fd_table_s *LOS_GetFdTable(UINT32 pid) +{ + if (OS_PID_CHECK_INVALID(pid)) { + return NULL; + } + + LosProcessCB *pcb = OS_PCB_FROM_PID(pid); + struct files_struct *files = pcb->files; + if (files == NULL) { + return NULL; + } + + return files->fdt; +} +#endif + +LITE_OS_SEC_TEXT UINT32 LOS_GetCurrProcessID(VOID) +{ + return OsCurrProcessGet()->processID; +} + +#ifdef LOSCFG_KERNEL_VM +STATIC VOID ThreadGroupActiveTaskKilled(LosTaskCB *taskCB) +{ + INT32 ret; + LosProcessCB *processCB = OS_PCB_FROM_TCB(taskCB); + taskCB->taskStatus |= OS_TASK_FLAG_EXIT_KILL; +#ifdef LOSCFG_KERNEL_SMP + /** The other core that the thread is running on and is currently running in a non-system call */ + if (!taskCB->sig.sigIntLock && (taskCB->taskStatus & OS_TASK_STATUS_RUNNING)) { + taskCB->signal = SIGNAL_KILL; + LOS_MpSchedule(taskCB->currCpu); + } else +#endif + { + ret = OsTaskKillUnsafe(taskCB->taskID, SIGKILL); + if (ret != LOS_OK) { + PRINT_ERR("pid %u exit, Exit task group %u kill %u failed! ERROR: %d\n", + processCB->processID, OsCurrTaskGet()->taskID, taskCB->taskID, ret); + } + } + + if (!(taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN)) { + taskCB->taskStatus |= OS_TASK_FLAG_PTHREAD_JOIN; + LOS_ListInit(&taskCB->joinList); + } + + ret = OsTaskJoinPendUnsafe(taskCB); + if (ret != LOS_OK) { + PRINT_ERR("pid %u exit, Exit task group %u to wait others task %u(0x%x) exit failed! ERROR: %d\n", + processCB->processID, OsCurrTaskGet()->taskID, taskCB->taskID, taskCB->taskStatus, ret); + } +} +#endif + +LITE_OS_SEC_TEXT VOID OsProcessThreadGroupDestroy(VOID) +{ +#ifdef LOSCFG_KERNEL_VM + UINT32 intSave; + + LosProcessCB *processCB = OsCurrProcessGet(); + LosTaskCB *currTask = OsCurrTaskGet(); + SCHEDULER_LOCK(intSave); + if ((processCB->processStatus & OS_PROCESS_FLAG_EXIT) || !OsProcessIsUserMode(processCB)) { + SCHEDULER_UNLOCK(intSave); + return; + } + + processCB->processStatus |= OS_PROCESS_FLAG_EXIT; + processCB->threadGroup = currTask; + + LOS_DL_LIST *list = &processCB->threadSiblingList; + LOS_DL_LIST *head = list; + do { + LosTaskCB *taskCB = LOS_DL_LIST_ENTRY(list->pstNext, LosTaskCB, threadList); + if ((OsTaskIsInactive(taskCB) || + ((taskCB->taskStatus & OS_TASK_STATUS_READY) && !taskCB->sig.sigIntLock)) && + !(taskCB->taskStatus & OS_TASK_STATUS_RUNNING)) { + OsInactiveTaskDelete(taskCB); + } else if (taskCB != currTask) { + ThreadGroupActiveTaskKilled(taskCB); + } else { + /* Skip the current task */ + list = list->pstNext; + } + } while (head != list->pstNext); + + SCHEDULER_UNLOCK(intSave); + + LOS_ASSERT(processCB->threadNumber == 1); +#endif + return; +} + +LITE_OS_SEC_TEXT UINT32 LOS_GetSystemProcessMaximum(VOID) +{ + return g_processMaxNum; +} + +LITE_OS_SEC_TEXT LosProcessCB *OsGetUserInitProcess(VOID) +{ + return &g_processCBArray[OS_USER_ROOT_PROCESS_ID]; +} + +LITE_OS_SEC_TEXT LosProcessCB *OsGetKernelInitProcess(VOID) +{ + return &g_processCBArray[OS_KERNEL_ROOT_PROCESS_ID]; +} + +LITE_OS_SEC_TEXT LosProcessCB *OsGetIdleProcess(VOID) +{ + return &g_processCBArray[OS_KERNEL_IDLE_PROCESS_ID]; +} + +LITE_OS_SEC_TEXT VOID OsSetSigHandler(UINTPTR addr) +{ + OsCurrProcessGet()->sigHandler = addr; +} + +LITE_OS_SEC_TEXT UINTPTR OsGetSigHandler(VOID) +{ + return OsCurrProcessGet()->sigHandler; +} + +LosProcessCB *OsGetDefaultProcessCB(VOID) +{ + return &g_processCBArray[g_processMaxNum]; +} diff --git a/src/kernel_liteos_a/kernel/base/core/los_smp.c b/src/kernel_liteos_a/kernel/base/core/los_smp.c new file mode 100644 index 00000000..560e54fa --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/core/los_smp.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_smp.h" +#include "arch_config.h" +#include "los_atomic.h" +#include "los_task_pri.h" +#include "los_init_pri.h" +#include "los_process_pri.h" +#include "los_sched_pri.h" +#include "los_swtmr_pri.h" + +#ifdef LOSCFG_KERNEL_SMP +STATIC struct SmpOps *g_smpOps = NULL; +/// 多核中次级CPU核初始化,每个核都会调用一次 +STATIC VOID OsSmpSecondaryInit(VOID *arg) +{ + UNUSED(arg); + + OsCurrTaskSet(OsGetMainTask()); + +#ifdef LOSCFG_BASE_CORE_SWTMR_ENABLE + OsSwtmrInit(); +#endif + + OsIdleTaskCreate((UINTPTR)OsGetIdleProcess()); + OsInitCall(LOS_INIT_LEVEL_KMOD_TASK); + + OsSchedStart(); +} +/// 设置多核操作接口, 通过外部注册 +VOID LOS_SmpOpsSet(struct SmpOps *ops) +{ + g_smpOps = ops; +} + +VOID OsSmpInit(VOID) +{ + UINT32 cpuNum = 1; /* Start the secondary cpus. */ + + if (g_smpOps == NULL) { + PRINT_ERR("Must call the interface(LOS_SmpOpsSet) to register smp operations firstly!\n"); + return; + } + + for (; cpuNum < CORE_NUM; cpuNum++) { + HalArchCpuOn(cpuNum, OsSmpSecondaryInit, g_smpOps, 0); + } + + return; +} +#endif diff --git a/src/kernel_liteos_a/kernel/base/core/los_swtmr.c b/src/kernel_liteos_a/kernel/base/core/los_swtmr.c new file mode 100644 index 00000000..893cabd0 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/core/los_swtmr.c @@ -0,0 +1,924 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/*! +* @file los_swtmr.c +* @brief 软定时器主文件 +* @details +* @attention @verbatim +基本概念 + 软件定时器,是基于系统Tick时钟中断且由软件来模拟的定时器。当经过设定的Tick数后,会触发用户自定义的回调函数。 + 硬件定时器受硬件的限制,数量上不足以满足用户的实际需求。因此为了满足用户需求,提供更多的定时器, + 软件定时器功能,支持如下特性: + 创建软件定时器。 + 启动软件定时器。 + 停止软件定时器。 + 删除软件定时器。 + 获取软件定时器剩余Tick数。 + 可配置支持的软件定时器个数。 + + 运作机制 + 软件定时器是系统资源,在模块初始化的时候已经分配了一块连续内存。 + 软件定时器使用了系统的一个队列和一个任务资源,软件定时器的触发遵循队列规则, + 先进先出。定时时间短的定时器总是比定时时间长的靠近队列头,满足优先触发的准则。 + 软件定时器以Tick为基本计时单位,当创建并启动一个软件定时器时,Huawei LiteOS会根据 + 当前系统Tick时间及设置的定时时长确定该定时器的到期Tick时间,并将该定时器控制结构挂入计时全局链表。 + 当Tick中断到来时,在Tick中断处理函数中扫描软件定时器的计时全局链表,检查是否有定时器超时, + 若有则将超时的定时器记录下来。Tick中断处理函数结束后,软件定时器任务(优先级为最高) + 被唤醒,在该任务中调用已经记录下来的定时器的回调函数。 + + 定时器状态 + OS_SWTMR_STATUS_UNUSED(定时器未使用) + 系统在定时器模块初始化时,会将系统中所有定时器资源初始化成该状态。 + + OS_SWTMR_STATUS_TICKING(定时器处于计数状态) + 在定时器创建后调用LOS_SwtmrStart接口启动,定时器将变成该状态,是定时器运行时的状态。 + + OS_SWTMR_STATUS_CREATED(定时器创建后未启动,或已停止) + 定时器创建后,不处于计数状态时,定时器将变成该状态。 + + 软件定时器提供了三类模式: + 单次触发定时器,这类定时器在启动后只会触发一次定时器事件,然后定时器自动删除。 + 周期触发定时器,这类定时器会周期性的触发定时器事件,直到用户手动停止定时器,否则将永远持续执行下去。 + 单次触发定时器,但这类定时器超时触发后不会自动删除,需要调用定时器删除接口删除定时器。 + + 使用场景 + 创建一个单次触发的定时器,超时后执行用户自定义的回调函数。 + 创建一个周期性触发的定时器,超时后执行用户自定义的回调函数。 + + 软件定时器的典型开发流程 + 通过make menuconfig配置软件定时器 + 创建定时器LOS_SwtmrCreate,设置定时器的定时时长、定时器模式、超时后的回调函数。 + 启动定时器LOS_SwtmrStart。 + 获得软件定时器剩余Tick数LOS_SwtmrTimeGet。 + 停止定时器LOS_SwtmrStop。 + 删除定时器LOS_SwtmrDelete。 + + 注意事项 + 软件定时器的回调函数中不应执行过多操作,不建议使用可能引起任务挂起或者阻塞的接口或操作, + 如果使用会导致软件定时器响应不及时,造成的影响无法确定。 + 软件定时器使用了系统的一个队列和一个任务资源。软件定时器任务的优先级设定为0,且不允许修改 。 + 系统可配置的软件定时器个数是指:整个系统可使用的软件定时器总个数,并非用户可使用的软件定时器个数。 + 例如:系统多占用一个软件定时器,那么用户能使用的软件定时器资源就会减少一个。 + 创建单次不自删除属性的定时器,用户需要自行调用定时器删除接口删除定时器,回收定时器资源,避免资源泄露。 + 软件定时器的定时精度与系统Tick时钟的周期有关。 + @endverbatim +*/ +#include "los_swtmr_pri.h" +#include "los_init.h" +#include "los_process_pri.h" +#include "los_queue_pri.h" +#include "los_sched_pri.h" +#include "los_sortlink_pri.h" +#include "los_task_pri.h" +#include "los_hook.h" + +#ifdef LOSCFG_BASE_CORE_SWTMR_ENABLE +#if (LOSCFG_BASE_CORE_SWTMR_LIMIT <= 0) +#error "swtmr maxnum cannot be zero" +#endif /* LOSCFG_BASE_CORE_SWTMR_LIMIT <= 0 */ + +STATIC INLINE VOID SwtmrDelete(SWTMR_CTRL_S *swtmr); +STATIC INLINE UINT64 SwtmrToStart(SWTMR_CTRL_S *swtmr, UINT16 cpuid); + +LITE_OS_SEC_BSS SWTMR_CTRL_S *g_swtmrCBArray = NULL; /* First address in Timer memory space */ +LITE_OS_SEC_BSS UINT8 *g_swtmrHandlerPool = NULL; /* Pool of Swtmr Handler */ +LITE_OS_SEC_BSS LOS_DL_LIST g_swtmrFreeList; /* Free list of Software Timer */ + +/* spinlock for swtmr module, only available on SMP mode */ +LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_swtmrSpin); +#define SWTMR_LOCK(state) LOS_SpinLockSave(&g_swtmrSpin, &(state)) +#define SWTMR_UNLOCK(state) LOS_SpinUnlockRestore(&g_swtmrSpin, (state)) + +typedef struct { + SortLinkAttribute swtmrSortLink; + LosTaskCB *swtmrTask; /* software timer task id */ + LOS_DL_LIST swtmrHandlerQueue; /* software timer timeout queue id */ +} SwtmrRunqueue; + +STATIC SwtmrRunqueue g_swtmrRunqueue[LOSCFG_KERNEL_CORE_NUM]; + +#ifdef LOSCFG_SWTMR_DEBUG +#define OS_SWTMR_PERIOD_TO_CYCLE(period) (((UINT64)(period) * OS_NS_PER_TICK) / OS_NS_PER_CYCLE) +STATIC SwtmrDebugData *g_swtmrDebugData = NULL; + +BOOL OsSwtmrDebugDataUsed(UINT32 swtmrID) +{ + if (swtmrID > LOSCFG_BASE_CORE_SWTMR_LIMIT) { + return FALSE; + } + + return g_swtmrDebugData[swtmrID].swtmrUsed; +} + +UINT32 OsSwtmrDebugDataGet(UINT32 swtmrID, SwtmrDebugData *data, UINT32 len, UINT8 *mode) +{ + UINT32 intSave; + errno_t ret; + + if ((swtmrID > LOSCFG_BASE_CORE_SWTMR_LIMIT) || (data == NULL) || + (mode == NULL) || (len < sizeof(SwtmrDebugData))) { + return LOS_NOK; + } + + SWTMR_CTRL_S *swtmr = &g_swtmrCBArray[swtmrID]; + SWTMR_LOCK(intSave); + ret = memcpy_s(data, len, &g_swtmrDebugData[swtmrID], sizeof(SwtmrDebugData)); + *mode = swtmr->ucMode; + SWTMR_UNLOCK(intSave); + if (ret != EOK) { + return LOS_NOK; + } + return LOS_OK; +} +#endif + +STATIC VOID SwtmrDebugDataInit(VOID) +{ +#ifdef LOSCFG_SWTMR_DEBUG + UINT32 size = sizeof(SwtmrDebugData) * LOSCFG_BASE_CORE_SWTMR_LIMIT; + g_swtmrDebugData = (SwtmrDebugData *)LOS_MemAlloc(m_aucSysMem1, size); + if (g_swtmrDebugData == NULL) { + PRINT_ERR("SwtmrDebugDataInit malloc failed!\n"); + return; + } + (VOID)memset_s(g_swtmrDebugData, size, 0, size); +#endif +} + +STATIC INLINE VOID SwtmrDebugDataUpdate(SWTMR_CTRL_S *swtmr, UINT32 ticks, UINT32 times) +{ +#ifdef LOSCFG_SWTMR_DEBUG + SwtmrDebugData *data = &g_swtmrDebugData[swtmr->usTimerID]; + if (data->period != ticks) { + (VOID)memset_s(&data->base, sizeof(SwtmrDebugBase), 0, sizeof(SwtmrDebugBase)); + data->period = ticks; + } + data->base.startTime = swtmr->startTime; + data->base.times += times; +#endif +} + +STATIC INLINE VOID SwtmrDebugDataStart(SWTMR_CTRL_S *swtmr, UINT16 cpuid) +{ +#ifdef LOSCFG_SWTMR_DEBUG + SwtmrDebugData *data = &g_swtmrDebugData[swtmr->usTimerID]; + data->swtmrUsed = TRUE; + data->handler = swtmr->pfnHandler; + data->cpuid = cpuid; +#endif +} + +STATIC INLINE VOID SwtmrDebugWaitTimeCalculate(UINT32 swtmrID, SwtmrHandlerItemPtr swtmrHandler) +{ +#ifdef LOSCFG_SWTMR_DEBUG + SwtmrDebugBase *data = &g_swtmrDebugData[swtmrID].base; + swtmrHandler->swtmrID = swtmrID; + UINT64 currTime = OsGetCurrSchedTimeCycle(); + UINT64 waitTime = currTime - data->startTime; + data->waitTime += waitTime; + if (waitTime > data->waitTimeMax) { + data->waitTimeMax = waitTime; + } + data->readyStartTime = currTime; + data->waitCount++; +#endif +} + +STATIC INLINE VOID SwtmrDebugDataClear(UINT32 swtmrID) +{ +#ifdef LOSCFG_SWTMR_DEBUG + (VOID)memset_s(&g_swtmrDebugData[swtmrID], sizeof(SwtmrDebugData), 0, sizeof(SwtmrDebugData)); +#endif +} + +STATIC INLINE VOID SwtmrHandler(SwtmrHandlerItemPtr swtmrHandle) +{ +#ifdef LOSCFG_SWTMR_DEBUG + UINT32 intSave; + SwtmrDebugBase *data = &g_swtmrDebugData[swtmrHandle->swtmrID].base; + UINT64 startTime = OsGetCurrSchedTimeCycle(); +#endif + swtmrHandle->handler(swtmrHandle->arg); +#ifdef LOSCFG_SWTMR_DEBUG + UINT64 runTime = OsGetCurrSchedTimeCycle() - startTime; + SWTMR_LOCK(intSave); + data->runTime += runTime; + if (runTime > data->runTimeMax) { + data->runTimeMax = runTime; + } + runTime = startTime - data->readyStartTime; + data->readyTime += runTime; + if (runTime > data->readyTimeMax) { + data->readyTimeMax = runTime; + } + data->runCount++; + SWTMR_UNLOCK(intSave); +#endif +} + +STATIC INLINE VOID SwtmrWake(SwtmrRunqueue *srq, UINT64 startTime, SortLinkList *sortList) +{ + UINT32 intSave; + SWTMR_CTRL_S *swtmr = LOS_DL_LIST_ENTRY(sortList, SWTMR_CTRL_S, stSortList); + SwtmrHandlerItemPtr swtmrHandler = (SwtmrHandlerItemPtr)LOS_MemboxAlloc(g_swtmrHandlerPool); + LOS_ASSERT(swtmrHandler != NULL); + + OsHookCall(LOS_HOOK_TYPE_SWTMR_EXPIRED, swtmr); + + SWTMR_LOCK(intSave); + swtmrHandler->handler = swtmr->pfnHandler; + swtmrHandler->arg = swtmr->uwArg; + LOS_ListTailInsert(&srq->swtmrHandlerQueue, &swtmrHandler->node); + SwtmrDebugWaitTimeCalculate(swtmr->usTimerID, swtmrHandler); + + if (swtmr->ucMode == LOS_SWTMR_MODE_ONCE) { + SwtmrDelete(swtmr); + + if (swtmr->usTimerID < (OS_SWTMR_MAX_TIMERID - LOSCFG_BASE_CORE_SWTMR_LIMIT)) { + swtmr->usTimerID += LOSCFG_BASE_CORE_SWTMR_LIMIT; + } else { + swtmr->usTimerID %= LOSCFG_BASE_CORE_SWTMR_LIMIT; + } + } else if (swtmr->ucMode == LOS_SWTMR_MODE_NO_SELFDELETE) { + swtmr->ucState = OS_SWTMR_STATUS_CREATED; + } else { + swtmr->uwOverrun++; + swtmr->startTime = startTime; + (VOID)SwtmrToStart(swtmr, ArchCurrCpuid()); + } + + SWTMR_UNLOCK(intSave); +} + +STATIC INLINE VOID ScanSwtmrTimeList(SwtmrRunqueue *srq) +{ + UINT32 intSave; + SortLinkAttribute *swtmrSortLink = &srq->swtmrSortLink; + LOS_DL_LIST *listObject = &swtmrSortLink->sortLink; + + /* + * it needs to be carefully coped with, since the swtmr is in specific sortlink + * while other cores still has the chance to process it, like stop the timer. + */ + LOS_SpinLockSave(&swtmrSortLink->spinLock, &intSave); + + if (LOS_ListEmpty(listObject)) { + LOS_SpinUnlockRestore(&swtmrSortLink->spinLock, intSave); + return; + } + SortLinkList *sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode); + + UINT64 currTime = OsGetCurrSchedTimeCycle(); + while (sortList->responseTime <= currTime) { + sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode); + UINT64 startTime = GET_SORTLIST_VALUE(sortList); + OsDeleteNodeSortLink(swtmrSortLink, sortList); + LOS_SpinUnlockRestore(&swtmrSortLink->spinLock, intSave); + + SwtmrWake(srq, startTime, sortList); + + LOS_SpinLockSave(&swtmrSortLink->spinLock, &intSave); + if (LOS_ListEmpty(listObject)) { + break; + } + + sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode); + } + + LOS_SpinUnlockRestore(&swtmrSortLink->spinLock, intSave); + return; +} + +STATIC VOID SwtmrTask(VOID) +{ + SwtmrHandlerItem swtmrHandle; + UINT32 intSave; + UINT64 waitTime; + + SwtmrRunqueue *srq = &g_swtmrRunqueue[ArchCurrCpuid()]; + LOS_DL_LIST *head = &srq->swtmrHandlerQueue; + for (;;) { + waitTime = OsSortLinkGetNextExpireTime(OsGetCurrSchedTimeCycle(), &srq->swtmrSortLink); + if (waitTime != 0) { + SCHEDULER_LOCK(intSave); + srq->swtmrTask->ops->delay(srq->swtmrTask, waitTime); + OsHookCall(LOS_HOOK_TYPE_MOVEDTASKTODELAYEDLIST, srq->swtmrTask); + SCHEDULER_UNLOCK(intSave); + } + + ScanSwtmrTimeList(srq); + + while (!LOS_ListEmpty(head)) { + SwtmrHandlerItemPtr swtmrHandlePtr = LOS_DL_LIST_ENTRY(LOS_DL_LIST_FIRST(head), SwtmrHandlerItem, node); + LOS_ListDelete(&swtmrHandlePtr->node); + + (VOID)memcpy_s(&swtmrHandle, sizeof(SwtmrHandlerItem), swtmrHandlePtr, sizeof(SwtmrHandlerItem)); + (VOID)LOS_MemboxFree(g_swtmrHandlerPool, swtmrHandlePtr); + SwtmrHandler(&swtmrHandle); + } + } +} + +STATIC UINT32 SwtmrTaskCreate(UINT16 cpuid, UINT32 *swtmrTaskID) +{ + UINT32 ret; + TSK_INIT_PARAM_S swtmrTask; + + (VOID)memset_s(&swtmrTask, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + swtmrTask.pfnTaskEntry = (TSK_ENTRY_FUNC)SwtmrTask; + swtmrTask.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + swtmrTask.pcName = "Swt_Task"; + swtmrTask.usTaskPrio = 0; + swtmrTask.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + swtmrTask.usCpuAffiMask = CPUID_TO_AFFI_MASK(cpuid); +#endif + ret = LOS_TaskCreate(swtmrTaskID, &swtmrTask); + if (ret == LOS_OK) { + OS_TCB_FROM_TID(*swtmrTaskID)->taskStatus |= OS_TASK_FLAG_SYSTEM_TASK; + } + + return ret; +} + +UINT32 OsSwtmrTaskIDGetByCpuid(UINT16 cpuid) +{ + return g_swtmrRunqueue[cpuid].swtmrTask->taskID; +} + +BOOL OsIsSwtmrTask(const LosTaskCB *taskCB) +{ + if (taskCB->taskEntry == (TSK_ENTRY_FUNC)SwtmrTask) { + return TRUE; + } + return FALSE; +} + +LITE_OS_SEC_TEXT_INIT VOID OsSwtmrRecycle(UINTPTR ownerID) +{ + for (UINT16 index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++) { + if (g_swtmrCBArray[index].uwOwnerPid == ownerID) { + LOS_SwtmrDelete(index); + } + } +} + +STATIC UINT32 SwtmrBaseInit(VOID) +{ + UINT32 ret; + UINT32 size = sizeof(SWTMR_CTRL_S) * LOSCFG_BASE_CORE_SWTMR_LIMIT; + SWTMR_CTRL_S *swtmr = (SWTMR_CTRL_S *)LOS_MemAlloc(m_aucSysMem0, size); /* system resident resource */ + if (swtmr == NULL) { + return LOS_ERRNO_SWTMR_NO_MEMORY; + } + + (VOID)memset_s(swtmr, size, 0, size); + g_swtmrCBArray = swtmr; + LOS_ListInit(&g_swtmrFreeList); + for (UINT16 index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++, swtmr++) { + swtmr->usTimerID = index; + LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->stSortList.sortLinkNode); + } + + size = LOS_MEMBOX_SIZE(sizeof(SwtmrHandlerItem), OS_SWTMR_HANDLE_QUEUE_SIZE); + g_swtmrHandlerPool = (UINT8 *)LOS_MemAlloc(m_aucSysMem1, size); /* system resident resource */ + if (g_swtmrHandlerPool == NULL) { + return LOS_ERRNO_SWTMR_NO_MEMORY; + } + + ret = LOS_MemboxInit(g_swtmrHandlerPool, size, sizeof(SwtmrHandlerItem)); + if (ret != LOS_OK) { + return LOS_ERRNO_SWTMR_HANDLER_POOL_NO_MEM; + } + + for (UINT16 index = 0; index < LOSCFG_KERNEL_CORE_NUM; index++) { + SwtmrRunqueue *srq = &g_swtmrRunqueue[index]; + /* The linked list of all cores must be initialized at core 0 startup for load balancing */ + OsSortLinkInit(&srq->swtmrSortLink); + LOS_ListInit(&srq->swtmrHandlerQueue); + srq->swtmrTask = NULL; + } + + SwtmrDebugDataInit(); + + return LOS_OK; +} + +LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrInit(VOID) +{ + UINT32 ret; + UINT32 cpuid = ArchCurrCpuid(); + UINT32 swtmrTaskID; + + if (cpuid == 0) { + ret = SwtmrBaseInit(); + if (ret != LOS_OK) { + goto ERROR; + } + } + + ret = SwtmrTaskCreate(cpuid, &swtmrTaskID); + if (ret != LOS_OK) { + ret = LOS_ERRNO_SWTMR_TASK_CREATE_FAILED; + goto ERROR; + } + + SwtmrRunqueue *srq = &g_swtmrRunqueue[cpuid]; + srq->swtmrTask = OsGetTaskCB(swtmrTaskID); + return LOS_OK; + +ERROR: + PRINT_ERR("OsSwtmrInit error! ret = %u\n", ret); + (VOID)LOS_MemFree(m_aucSysMem0, g_swtmrCBArray); + g_swtmrCBArray = NULL; + (VOID)LOS_MemFree(m_aucSysMem1, g_swtmrHandlerPool); + g_swtmrHandlerPool = NULL; + return ret; +} + +#ifdef LOSCFG_KERNEL_SMP +STATIC INLINE VOID FindIdleSwtmrRunqueue(UINT16 *idleCpuid) +{ + SwtmrRunqueue *idleRq = &g_swtmrRunqueue[0]; + UINT32 nodeNum = OsGetSortLinkNodeNum(&idleRq->swtmrSortLink); + UINT16 cpuid = 1; + do { + SwtmrRunqueue *srq = &g_swtmrRunqueue[cpuid]; + UINT32 temp = OsGetSortLinkNodeNum(&srq->swtmrSortLink); + if (nodeNum > temp) { + *idleCpuid = cpuid; + nodeNum = temp; + } + cpuid++; + } while (cpuid < LOSCFG_KERNEL_CORE_NUM); +} +#endif + +STATIC INLINE VOID AddSwtmr2TimeList(SortLinkList *node, UINT64 responseTime, UINT16 cpuid) +{ + SwtmrRunqueue *srq = &g_swtmrRunqueue[cpuid]; + OsAdd2SortLink(&srq->swtmrSortLink, node, responseTime, cpuid); +} + +STATIC INLINE VOID DeSwtmrFromTimeList(SortLinkList *node) +{ +#ifdef LOSCFG_KERNEL_SMP + UINT16 cpuid = OsGetSortLinkNodeCpuid(node); +#else + UINT16 cpuid = 0; +#endif + SwtmrRunqueue *srq = &g_swtmrRunqueue[cpuid]; + OsDeleteFromSortLink(&srq->swtmrSortLink, node); + return; +} + +STATIC VOID SwtmrAdjustCheck(UINT16 cpuid, UINT64 responseTime) +{ + UINT32 ret; + UINT32 intSave; + SwtmrRunqueue *srq = &g_swtmrRunqueue[cpuid]; + SCHEDULER_LOCK(intSave); + if ((srq->swtmrTask == NULL) || !OsTaskIsBlocked(srq->swtmrTask)) { + SCHEDULER_UNLOCK(intSave); + return; + } + + if (responseTime >= GET_SORTLIST_VALUE(&srq->swtmrTask->sortList)) { + SCHEDULER_UNLOCK(intSave); + return; + } + + ret = OsSchedTimeoutQueueAdjust(srq->swtmrTask, responseTime); + SCHEDULER_UNLOCK(intSave); + if (ret != LOS_OK) { + return; + } + + if (cpuid == ArchCurrCpuid()) { + OsSchedExpireTimeUpdate(); + } else { + LOS_MpSchedule(CPUID_TO_AFFI_MASK(cpuid)); + } +} + +STATIC UINT64 SwtmrToStart(SWTMR_CTRL_S *swtmr, UINT16 cpuid) +{ + UINT32 ticks; + UINT32 times = 0; + + if ((swtmr->uwOverrun == 0) && ((swtmr->ucMode == LOS_SWTMR_MODE_ONCE) || + (swtmr->ucMode == LOS_SWTMR_MODE_OPP) || + (swtmr->ucMode == LOS_SWTMR_MODE_NO_SELFDELETE))) { + ticks = swtmr->uwExpiry; + } else { + ticks = swtmr->uwInterval; + } + swtmr->ucState = OS_SWTMR_STATUS_TICKING; + + UINT64 period = (UINT64)ticks * OS_CYCLE_PER_TICK; + UINT64 responseTime = swtmr->startTime + period; + UINT64 currTime = OsGetCurrSchedTimeCycle(); + if (responseTime < currTime) { + times = (UINT32)((currTime - swtmr->startTime) / period); + swtmr->startTime += times * period; + responseTime = swtmr->startTime + period; + PRINT_WARN("Swtmr already timeout! SwtmrID: %u\n", swtmr->usTimerID); + } + + AddSwtmr2TimeList(&swtmr->stSortList, responseTime, cpuid); + SwtmrDebugDataUpdate(swtmr, ticks, times); + return responseTime; +} + +/* + * Description: Start Software Timer + * Input : swtmr --- Need to start software timer + */ +STATIC INLINE VOID SwtmrStart(SWTMR_CTRL_S *swtmr) +{ + UINT64 responseTime; + UINT16 idleCpu = 0; +#ifdef LOSCFG_KERNEL_SMP + FindIdleSwtmrRunqueue(&idleCpu); +#endif + swtmr->startTime = OsGetCurrSchedTimeCycle(); + responseTime = SwtmrToStart(swtmr, idleCpu); + + SwtmrDebugDataStart(swtmr, idleCpu); + + SwtmrAdjustCheck(idleCpu, responseTime); +} + +/* + * Description: Delete Software Timer + * Input : swtmr --- Need to delete software timer, When using, Ensure that it can't be NULL. + */ +STATIC INLINE VOID SwtmrDelete(SWTMR_CTRL_S *swtmr) +{ + /* insert to free list */ + LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->stSortList.sortLinkNode); + swtmr->ucState = OS_SWTMR_STATUS_UNUSED; + swtmr->uwOwnerPid = OS_INVALID_VALUE; + + SwtmrDebugDataClear(swtmr->usTimerID); +} + +STATIC INLINE VOID SwtmrRestart(UINT64 startTime, SortLinkList *sortList, UINT16 cpuid) +{ + UINT32 intSave; + + SWTMR_CTRL_S *swtmr = LOS_DL_LIST_ENTRY(sortList, SWTMR_CTRL_S, stSortList); + SWTMR_LOCK(intSave); + swtmr->startTime = startTime; + (VOID)SwtmrToStart(swtmr, cpuid); + SWTMR_UNLOCK(intSave); +} + +VOID OsSwtmrResponseTimeReset(UINT64 startTime) +{ + UINT16 cpuid = ArchCurrCpuid(); + SortLinkAttribute *swtmrSortLink = &g_swtmrRunqueue[cpuid].swtmrSortLink; + LOS_DL_LIST *listHead = &swtmrSortLink->sortLink; + LOS_DL_LIST *listNext = listHead->pstNext; + + LOS_SpinLock(&swtmrSortLink->spinLock); + while (listNext != listHead) { + SortLinkList *sortList = LOS_DL_LIST_ENTRY(listNext, SortLinkList, sortLinkNode); + OsDeleteNodeSortLink(swtmrSortLink, sortList); + LOS_SpinUnlock(&swtmrSortLink->spinLock); + + SwtmrRestart(startTime, sortList, cpuid); + + LOS_SpinLock(&swtmrSortLink->spinLock); + listNext = listNext->pstNext; + } + LOS_SpinUnlock(&swtmrSortLink->spinLock); +} + +STATIC INLINE BOOL SwtmrRunqueueFind(SortLinkAttribute *swtmrSortLink, SCHED_TL_FIND_FUNC checkFunc, UINTPTR arg) +{ + LOS_DL_LIST *listObject = &swtmrSortLink->sortLink; + LOS_DL_LIST *list = listObject->pstNext; + + LOS_SpinLock(&swtmrSortLink->spinLock); + while (list != listObject) { + SortLinkList *listSorted = LOS_DL_LIST_ENTRY(list, SortLinkList, sortLinkNode); + if (checkFunc((UINTPTR)listSorted, arg)) { + LOS_SpinUnlock(&swtmrSortLink->spinLock); + return TRUE; + } + list = list->pstNext; + } + + LOS_SpinUnlock(&swtmrSortLink->spinLock); + return FALSE; +} + +STATIC BOOL SwtmrTimeListFind(SCHED_TL_FIND_FUNC checkFunc, UINTPTR arg) +{ + for (UINT16 cpuid = 0; cpuid < LOSCFG_KERNEL_CORE_NUM; cpuid++) { + SortLinkAttribute *swtmrSortLink = &g_swtmrRunqueue[cpuid].swtmrSortLink; + if (SwtmrRunqueueFind(swtmrSortLink, checkFunc, arg)) { + return TRUE; + } + } + return FALSE; +} + +BOOL OsSwtmrWorkQueueFind(SCHED_TL_FIND_FUNC checkFunc, UINTPTR arg) +{ + UINT32 intSave; + + SWTMR_LOCK(intSave); + BOOL find = SwtmrTimeListFind(checkFunc, arg); + SWTMR_UNLOCK(intSave); + return find; +} + +/* + * Description: Get next timeout + * Return : Count of the Timer list + */ +LITE_OS_SEC_TEXT UINT32 OsSwtmrGetNextTimeout(VOID) +{ + UINT64 currTime = OsGetCurrSchedTimeCycle(); + SwtmrRunqueue *srq = &g_swtmrRunqueue[ArchCurrCpuid()]; + UINT64 time = (OsSortLinkGetNextExpireTime(currTime, &srq->swtmrSortLink) / OS_CYCLE_PER_TICK); + if (time > OS_INVALID_VALUE) { + time = OS_INVALID_VALUE; + } + return (UINT32)time; +} + +/* + * Description: Stop of Software Timer interface + * Input : swtmr --- the software timer control handler + */ +STATIC VOID SwtmrStop(SWTMR_CTRL_S *swtmr) +{ + swtmr->ucState = OS_SWTMR_STATUS_CREATED; + swtmr->uwOverrun = 0; + + DeSwtmrFromTimeList(&swtmr->stSortList); +} + +/* + * Description: Get next software timer expiretime + * Input : swtmr --- the software timer control handler + */ +LITE_OS_SEC_TEXT STATIC UINT32 OsSwtmrTimeGet(const SWTMR_CTRL_S *swtmr) +{ + UINT64 currTime = OsGetCurrSchedTimeCycle(); + UINT64 time = (OsSortLinkGetTargetExpireTime(currTime, &swtmr->stSortList) / OS_CYCLE_PER_TICK); + if (time > OS_INVALID_VALUE) { + time = OS_INVALID_VALUE; + } + return (UINT32)time; +} + +LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval, + UINT8 mode, + SWTMR_PROC_FUNC handler, + UINT16 *swtmrID, + UINTPTR arg) +{ + SWTMR_CTRL_S *swtmr = NULL; + UINT32 intSave; + SortLinkList *sortList = NULL; + + if (interval == 0) { + return LOS_ERRNO_SWTMR_INTERVAL_NOT_SUITED; + } + + if ((mode != LOS_SWTMR_MODE_ONCE) && (mode != LOS_SWTMR_MODE_PERIOD) && + (mode != LOS_SWTMR_MODE_NO_SELFDELETE)) { + return LOS_ERRNO_SWTMR_MODE_INVALID; + } + + if (handler == NULL) { + return LOS_ERRNO_SWTMR_PTR_NULL; + } + + if (swtmrID == NULL) { + return LOS_ERRNO_SWTMR_RET_PTR_NULL; + } + + SWTMR_LOCK(intSave); + if (LOS_ListEmpty(&g_swtmrFreeList)) { + SWTMR_UNLOCK(intSave); + return LOS_ERRNO_SWTMR_MAXSIZE; + } + + sortList = LOS_DL_LIST_ENTRY(g_swtmrFreeList.pstNext, SortLinkList, sortLinkNode); + swtmr = LOS_DL_LIST_ENTRY(sortList, SWTMR_CTRL_S, stSortList); + LOS_ListDelete(LOS_DL_LIST_FIRST(&g_swtmrFreeList)); + SWTMR_UNLOCK(intSave); + + swtmr->uwOwnerPid = (UINTPTR)OsCurrProcessGet(); + swtmr->pfnHandler = handler; + swtmr->ucMode = mode; + swtmr->uwOverrun = 0; + swtmr->uwInterval = interval; + swtmr->uwExpiry = interval; + swtmr->uwArg = arg; + swtmr->ucState = OS_SWTMR_STATUS_CREATED; + SET_SORTLIST_VALUE(&swtmr->stSortList, OS_SORT_LINK_INVALID_TIME); + *swtmrID = swtmr->usTimerID; + OsHookCall(LOS_HOOK_TYPE_SWTMR_CREATE, swtmr); + return LOS_OK; +} + +LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrID) +{ + SWTMR_CTRL_S *swtmr = NULL; + UINT32 intSave; + UINT32 ret = LOS_OK; + UINT16 swtmrCBID; + + if (swtmrID >= OS_SWTMR_MAX_TIMERID) { + return LOS_ERRNO_SWTMR_ID_INVALID; + } + + swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT; + swtmr = g_swtmrCBArray + swtmrCBID; + + SWTMR_LOCK(intSave); + if (swtmr->usTimerID != swtmrID) { + SWTMR_UNLOCK(intSave); + return LOS_ERRNO_SWTMR_ID_INVALID; + } + + switch (swtmr->ucState) { + case OS_SWTMR_STATUS_UNUSED: + ret = LOS_ERRNO_SWTMR_NOT_CREATED; + break; + /* + * If the status of swtmr is timing, it should stop the swtmr first, + * then start the swtmr again. + */ + case OS_SWTMR_STATUS_TICKING: + SwtmrStop(swtmr); + /* fall-through */ + case OS_SWTMR_STATUS_CREATED: + SwtmrStart(swtmr); + break; + default: + ret = LOS_ERRNO_SWTMR_STATUS_INVALID; + break; + } + + SWTMR_UNLOCK(intSave); + OsHookCall(LOS_HOOK_TYPE_SWTMR_START, swtmr); + return ret; +} + +LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrID) +{ + SWTMR_CTRL_S *swtmr = NULL; + UINT32 intSave; + UINT32 ret = LOS_OK; + UINT16 swtmrCBID; + + if (swtmrID >= OS_SWTMR_MAX_TIMERID) { + return LOS_ERRNO_SWTMR_ID_INVALID; + } + + swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT; + swtmr = g_swtmrCBArray + swtmrCBID; + SWTMR_LOCK(intSave); + + if (swtmr->usTimerID != swtmrID) { + SWTMR_UNLOCK(intSave); + return LOS_ERRNO_SWTMR_ID_INVALID; + } + + switch (swtmr->ucState) { + case OS_SWTMR_STATUS_UNUSED: + ret = LOS_ERRNO_SWTMR_NOT_CREATED; + break; + case OS_SWTMR_STATUS_CREATED: + ret = LOS_ERRNO_SWTMR_NOT_STARTED; + break; + case OS_SWTMR_STATUS_TICKING: + SwtmrStop(swtmr); + break; + default: + ret = LOS_ERRNO_SWTMR_STATUS_INVALID; + break; + } + + SWTMR_UNLOCK(intSave); + OsHookCall(LOS_HOOK_TYPE_SWTMR_STOP, swtmr); + return ret; +} + +LITE_OS_SEC_TEXT UINT32 LOS_SwtmrTimeGet(UINT16 swtmrID, UINT32 *tick) +{ + SWTMR_CTRL_S *swtmr = NULL; + UINT32 intSave; + UINT32 ret = LOS_OK; + UINT16 swtmrCBID; + + if (swtmrID >= OS_SWTMR_MAX_TIMERID) { + return LOS_ERRNO_SWTMR_ID_INVALID; + } + + if (tick == NULL) { + return LOS_ERRNO_SWTMR_TICK_PTR_NULL; + } + + swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT; + swtmr = g_swtmrCBArray + swtmrCBID; + SWTMR_LOCK(intSave); + + if (swtmr->usTimerID != swtmrID) { + SWTMR_UNLOCK(intSave); + return LOS_ERRNO_SWTMR_ID_INVALID; + } + switch (swtmr->ucState) { + case OS_SWTMR_STATUS_UNUSED: + ret = LOS_ERRNO_SWTMR_NOT_CREATED; + break; + case OS_SWTMR_STATUS_CREATED: + ret = LOS_ERRNO_SWTMR_NOT_STARTED; + break; + case OS_SWTMR_STATUS_TICKING: + *tick = OsSwtmrTimeGet(swtmr); + break; + default: + ret = LOS_ERRNO_SWTMR_STATUS_INVALID; + break; + } + SWTMR_UNLOCK(intSave); + return ret; +} + +LITE_OS_SEC_TEXT UINT32 LOS_SwtmrDelete(UINT16 swtmrID) +{ + SWTMR_CTRL_S *swtmr = NULL; + UINT32 intSave; + UINT32 ret = LOS_OK; + UINT16 swtmrCBID; + + if (swtmrID >= OS_SWTMR_MAX_TIMERID) { + return LOS_ERRNO_SWTMR_ID_INVALID; + } + + swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT; + swtmr = g_swtmrCBArray + swtmrCBID; + SWTMR_LOCK(intSave); + + if (swtmr->usTimerID != swtmrID) { + SWTMR_UNLOCK(intSave); + return LOS_ERRNO_SWTMR_ID_INVALID; + } + + switch (swtmr->ucState) { + case OS_SWTMR_STATUS_UNUSED: + ret = LOS_ERRNO_SWTMR_NOT_CREATED; + break; + case OS_SWTMR_STATUS_TICKING: + SwtmrStop(swtmr); + /* fall-through */ + case OS_SWTMR_STATUS_CREATED: + SwtmrDelete(swtmr); + break; + default: + ret = LOS_ERRNO_SWTMR_STATUS_INVALID; + break; + } + + SWTMR_UNLOCK(intSave); + OsHookCall(LOS_HOOK_TYPE_SWTMR_DELETE, swtmr); + return ret; +} + +#endif /* LOSCFG_BASE_CORE_SWTMR_ENABLE */ diff --git a/src/kernel_liteos_a/kernel/base/core/los_sys.c b/src/kernel_liteos_a/kernel/base/core/los_sys.c new file mode 100644 index 00000000..8a9d373a --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/core/los_sys.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_sys_pri.h" +#include "los_sched_pri.h" + + +#define OS_MAX_VALUE 0xFFFFFFFFUL + +LITE_OS_SEC_TEXT_MINOR UINT64 LOS_TickCountGet(VOID) +{ + return OsGetCurrSchedTimeCycle() / OS_CYCLE_PER_TICK; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_CyclePerTickGet(VOID) +{ + return g_sysClock / LOSCFG_BASE_CORE_TICK_PER_SECOND; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MS2Tick(UINT32 millisec) +{ + if (millisec == OS_MAX_VALUE) { + return OS_MAX_VALUE; + } + + return ((UINT64)millisec * LOSCFG_BASE_CORE_TICK_PER_SECOND) / OS_SYS_MS_PER_SECOND; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_Tick2MS(UINT32 tick) +{ + return ((UINT64)tick * OS_SYS_MS_PER_SECOND) / LOSCFG_BASE_CORE_TICK_PER_SECOND; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 OsNS2Tick(UINT64 nanoseconds) +{ + const UINT32 nsPerTick = OS_SYS_NS_PER_SECOND / LOSCFG_BASE_CORE_TICK_PER_SECOND; + + UINT64 ticks = (nanoseconds + nsPerTick - 1) / nsPerTick; + if (ticks > OS_MAX_VALUE) { + ticks = OS_MAX_VALUE; + } + return (UINT32)ticks; +} + diff --git a/src/kernel_liteos_a/kernel/base/core/los_task.c b/src/kernel_liteos_a/kernel/base/core/los_task.c new file mode 100644 index 00000000..2bd80726 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/core/los_task.c @@ -0,0 +1,1651 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_task_pri.h" +#include "los_base_pri.h" +#include "los_event_pri.h" +#include "los_exc.h" +#include "los_hw_pri.h" +#include "los_init.h" +#include "los_memstat_pri.h" +#include "los_mp.h" +#include "los_mux_pri.h" +#include "los_sched_pri.h" +#include "los_sem_pri.h" +#include "los_spinlock.h" +#include "los_strncpy_from_user.h" +#include "los_percpu_pri.h" +#include "los_process_pri.h" +#include "los_vm_map.h" +#include "los_vm_syscall.h" +#include "los_signal.h" +#include "los_hook.h" + +#ifdef LOSCFG_KERNEL_CPUP +#include "los_cpup_pri.h" +#endif +#ifdef LOSCFG_BASE_CORE_SWTMR_ENABLE +#include "los_swtmr_pri.h" +#endif +#ifdef LOSCFG_KERNEL_LITEIPC +#include "hm_liteipc.h" +#endif +#ifdef LOSCFG_ENABLE_OOM_LOOP_TASK +#include "los_oom.h" +#endif +#ifdef LOSCFG_KERNEL_CONTAINER +#include "los_container_pri.h" +#endif + +#if (LOSCFG_BASE_CORE_TSK_LIMIT <= 0) +#error "task maxnum cannot be zero" +#endif /* LOSCFG_BASE_CORE_TSK_LIMIT <= 0 */ + +LITE_OS_SEC_BSS LosTaskCB *g_taskCBArray; +LITE_OS_SEC_BSS LOS_DL_LIST g_losFreeTask; +LITE_OS_SEC_BSS LOS_DL_LIST g_taskRecycleList; +LITE_OS_SEC_BSS UINT32 g_taskMaxNum; +LITE_OS_SEC_BSS UINT32 g_taskScheduled; /* one bit for each cores */ +LITE_OS_SEC_BSS EVENT_CB_S g_resourceEvent; +/* spinlock for task module, only available on SMP mode */ +LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_taskSpin); + +STATIC VOID OsConsoleIDSetHook(UINT32 param1, + UINT32 param2) __attribute__((weakref("OsSetConsoleID"))); + +/* temp task blocks for booting procedure */ +LITE_OS_SEC_BSS STATIC LosTaskCB g_mainTask[LOSCFG_KERNEL_CORE_NUM]; + +LosTaskCB *OsGetMainTask(VOID) +{ + return (LosTaskCB *)(g_mainTask + ArchCurrCpuid()); +} + +VOID OsSetMainTask(VOID) +{ + UINT32 i; + CHAR *name = "osMain"; + SchedParam schedParam = { 0 }; + + schedParam.policy = LOS_SCHED_RR; + schedParam.basePrio = OS_PROCESS_PRIORITY_HIGHEST; + schedParam.priority = OS_TASK_PRIORITY_LOWEST; + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + g_mainTask[i].taskStatus = OS_TASK_STATUS_UNUSED; + g_mainTask[i].taskID = LOSCFG_BASE_CORE_TSK_LIMIT; + g_mainTask[i].processCB = OS_KERNEL_PROCESS_GROUP; +#ifdef LOSCFG_KERNEL_SMP_LOCKDEP + g_mainTask[i].lockDep.lockDepth = 0; + g_mainTask[i].lockDep.waitLock = NULL; +#endif + (VOID)strncpy_s(g_mainTask[i].taskName, OS_TCB_NAME_LEN, name, OS_TCB_NAME_LEN - 1); + LOS_ListInit(&g_mainTask[i].lockList); + (VOID)OsSchedParamInit(&g_mainTask[i], schedParam.policy, &schedParam, NULL); + } +} + +VOID OsSetMainTaskProcess(UINTPTR processCB) +{ + for (UINT32 i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + g_mainTask[i].processCB = processCB; +#ifdef LOSCFG_PID_CONTAINER + g_mainTask[i].pidContainer = OS_PID_CONTAINER_FROM_PCB((LosProcessCB *)processCB); +#endif + } +} + +LITE_OS_SEC_TEXT WEAK VOID OsIdleTask(VOID) +{ + while (1) { + WFI; + } +} + +VOID OsTaskInsertToRecycleList(LosTaskCB *taskCB) +{ + LOS_ListTailInsert(&g_taskRecycleList, &taskCB->pendList); +} + +LITE_OS_SEC_TEXT_INIT VOID OsTaskJoinPostUnsafe(LosTaskCB *taskCB) +{ + if (taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) { + if (!LOS_ListEmpty(&taskCB->joinList)) { + LosTaskCB *resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(taskCB->joinList))); + OsTaskWakeClearPendMask(resumedTask); + resumedTask->ops->wake(resumedTask); + } + } + taskCB->taskStatus |= OS_TASK_STATUS_EXIT; +} + +LITE_OS_SEC_TEXT UINT32 OsTaskJoinPendUnsafe(LosTaskCB *taskCB) +{ + if (taskCB->taskStatus & OS_TASK_STATUS_INIT) { + return LOS_EINVAL; + } + + if (taskCB->taskStatus & OS_TASK_STATUS_EXIT) { + return LOS_OK; + } + + if ((taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) && LOS_ListEmpty(&taskCB->joinList)) { + OsTaskWaitSetPendMask(OS_TASK_WAIT_JOIN, taskCB->taskID, LOS_WAIT_FOREVER); + LosTaskCB *runTask = OsCurrTaskGet(); + return runTask->ops->wait(runTask, &taskCB->joinList, LOS_WAIT_FOREVER); + } + + return LOS_EINVAL; +} + +LITE_OS_SEC_TEXT UINT32 OsTaskSetDetachUnsafe(LosTaskCB *taskCB) +{ + if (taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) { + if (LOS_ListEmpty(&(taskCB->joinList))) { + LOS_ListDelete(&(taskCB->joinList)); + taskCB->taskStatus &= ~OS_TASK_FLAG_PTHREAD_JOIN; + return LOS_OK; + } + /* This error code has a special purpose and is not allowed to appear again on the interface */ + return LOS_ESRCH; + } + + return LOS_EINVAL; +} + +LITE_OS_SEC_TEXT_INIT UINT32 OsTaskInit(UINTPTR processCB) +{ + UINT32 index; + UINT32 size; + UINT32 ret; + + g_taskMaxNum = LOSCFG_BASE_CORE_TSK_LIMIT; + size = (g_taskMaxNum + 1) * sizeof(LosTaskCB); + /* + * This memory is resident memory and is used to save the system resources + * of task control block and will not be freed. + */ + g_taskCBArray = (LosTaskCB *)LOS_MemAlloc(m_aucSysMem0, size); + if (g_taskCBArray == NULL) { + ret = LOS_ERRNO_TSK_NO_MEMORY; + goto EXIT; + } + (VOID)memset_s(g_taskCBArray, size, 0, size); + + LOS_ListInit(&g_losFreeTask); + LOS_ListInit(&g_taskRecycleList); + for (index = 0; index < g_taskMaxNum; index++) { + g_taskCBArray[index].taskStatus = OS_TASK_STATUS_UNUSED; + g_taskCBArray[index].taskID = index; + g_taskCBArray[index].processCB = processCB; + LOS_ListTailInsert(&g_losFreeTask, &g_taskCBArray[index].pendList); + } + + g_taskCBArray[index].taskStatus = OS_TASK_STATUS_UNUSED; + g_taskCBArray[index].taskID = index; + g_taskCBArray[index].processCB = processCB; + + ret = OsSchedInit(); + +EXIT: + if (ret != LOS_OK) { + PRINT_ERR("OsTaskInit error\n"); + } + return ret; +} + +UINT32 OsGetIdleTaskId(VOID) +{ + return OsSchedRunqueueIdleGet()->taskID; +} + +LITE_OS_SEC_TEXT_INIT UINT32 OsIdleTaskCreate(UINTPTR processID) +{ + UINT32 ret; + TSK_INIT_PARAM_S taskInitParam; + UINT32 idleTaskID; + + (VOID)memset_s((VOID *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)OsIdleTask; + taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_IDLE_STACK_SIZE; + taskInitParam.pcName = "Idle"; + taskInitParam.policy = LOS_SCHED_IDLE; + taskInitParam.usTaskPrio = OS_TASK_PRIORITY_LOWEST; + taskInitParam.processID = processID; +#ifdef LOSCFG_KERNEL_SMP + taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreateOnly(&idleTaskID, &taskInitParam); + if (ret != LOS_OK) { + return ret; + } + LosTaskCB *idleTask = OS_TCB_FROM_TID(idleTaskID); + idleTask->taskStatus |= OS_TASK_FLAG_SYSTEM_TASK; + OsSchedRunqueueIdleInit(idleTask); + + return LOS_TaskResume(idleTaskID); +} + +/* + * Description : get id of current running task. + * Return : task id + */ +LITE_OS_SEC_TEXT UINT32 LOS_CurTaskIDGet(VOID) +{ + LosTaskCB *runTask = OsCurrTaskGet(); + + if (runTask == NULL) { + return LOS_ERRNO_TSK_ID_INVALID; + } + return runTask->taskID; +} + +STATIC INLINE UINT32 TaskSyncCreate(LosTaskCB *taskCB) +{ +#ifdef LOSCFG_KERNEL_SMP_TASK_SYNC + UINT32 ret = LOS_SemCreate(0, &taskCB->syncSignal); + if (ret != LOS_OK) { + return LOS_ERRNO_TSK_MP_SYNC_RESOURCE; + } +#else + (VOID)taskCB; +#endif + return LOS_OK; +} + +STATIC INLINE VOID OsTaskSyncDestroy(UINT32 syncSignal) +{ +#ifdef LOSCFG_KERNEL_SMP_TASK_SYNC + (VOID)LOS_SemDelete(syncSignal); +#else + (VOID)syncSignal; +#endif +} + +#ifdef LOSCFG_KERNEL_SMP +STATIC INLINE UINT32 OsTaskSyncWait(const LosTaskCB *taskCB) +{ +#ifdef LOSCFG_KERNEL_SMP_TASK_SYNC + UINT32 ret = LOS_OK; + + LOS_ASSERT(LOS_SpinHeld(&g_taskSpin)); + LOS_SpinUnlock(&g_taskSpin); + /* + * gc soft timer works every OS_MP_GC_PERIOD period, to prevent this timer + * triggered right at the timeout has reached, we set the timeout as double + * of the gc period. + */ + if (LOS_SemPend(taskCB->syncSignal, OS_MP_GC_PERIOD * 2) != LOS_OK) { /* 2: Wait 200 ms */ + ret = LOS_ERRNO_TSK_MP_SYNC_FAILED; + } + + LOS_SpinLock(&g_taskSpin); + + return ret; +#else + (VOID)taskCB; + return LOS_OK; +#endif +} +#endif + +STATIC INLINE VOID OsTaskSyncWake(const LosTaskCB *taskCB) +{ +#ifdef LOSCFG_KERNEL_SMP_TASK_SYNC + (VOID)OsSemPostUnsafe(taskCB->syncSignal, NULL); +#else + (VOID)taskCB; +#endif +} + +STATIC INLINE VOID OsInsertTCBToFreeList(LosTaskCB *taskCB) +{ +#ifdef LOSCFG_PID_CONTAINER + OsFreeVtid(taskCB); +#endif + UINT32 taskID = taskCB->taskID; + (VOID)memset_s(taskCB, sizeof(LosTaskCB), 0, sizeof(LosTaskCB)); + taskCB->taskID = taskID; + taskCB->processCB = (UINTPTR)OsGetDefaultProcessCB(); + taskCB->taskStatus = OS_TASK_STATUS_UNUSED; + LOS_ListAdd(&g_losFreeTask, &taskCB->pendList); +} + +STATIC VOID OsTaskKernelResourcesToFree(UINT32 syncSignal, UINTPTR topOfStack) +{ + OsTaskSyncDestroy(syncSignal); + + (VOID)LOS_MemFree((VOID *)m_aucSysMem1, (VOID *)topOfStack); +} + +STATIC VOID OsTaskResourcesToFree(LosTaskCB *taskCB) +{ + UINT32 syncSignal = LOSCFG_BASE_IPC_SEM_LIMIT; + UINT32 intSave; + UINTPTR topOfStack; + +#ifdef LOSCFG_KERNEL_VM + if ((taskCB->taskStatus & OS_TASK_FLAG_USER_MODE) && (taskCB->userMapBase != 0)) { + SCHEDULER_LOCK(intSave); + UINT32 mapBase = (UINTPTR)taskCB->userMapBase; + UINT32 mapSize = taskCB->userMapSize; + taskCB->userMapBase = 0; + taskCB->userArea = 0; + SCHEDULER_UNLOCK(intSave); + + LosProcessCB *processCB = OS_PCB_FROM_TCB(taskCB); + LOS_ASSERT(!(OsProcessVmSpaceGet(processCB) == NULL)); + UINT32 ret = OsUnMMap(OsProcessVmSpaceGet(processCB), (UINTPTR)mapBase, mapSize); + if ((ret != LOS_OK) && (mapBase != 0) && !OsProcessIsInit(processCB)) { + PRINT_ERR("process(%u) unmmap user task(%u) stack failed! mapbase: 0x%x size :0x%x, error: %d\n", + processCB->processID, taskCB->taskID, mapBase, mapSize, ret); + } + +#ifdef LOSCFG_KERNEL_LITEIPC + LiteIpcRemoveServiceHandle(taskCB->taskID); +#endif + } +#endif + + if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { + topOfStack = taskCB->topOfStack; + taskCB->topOfStack = 0; +#ifdef LOSCFG_KERNEL_SMP_TASK_SYNC + syncSignal = taskCB->syncSignal; + taskCB->syncSignal = LOSCFG_BASE_IPC_SEM_LIMIT; +#endif + OsTaskKernelResourcesToFree(syncSignal, topOfStack); + + SCHEDULER_LOCK(intSave); +#ifdef LOSCFG_KERNEL_VM + OsClearSigInfoTmpList(&(taskCB->sig)); +#endif + OsInsertTCBToFreeList(taskCB); + SCHEDULER_UNLOCK(intSave); + } + return; +} + +LITE_OS_SEC_TEXT VOID OsTaskCBRecycleToFree(void) +{ + UINT32 intSave; + + SCHEDULER_LOCK(intSave); + while (!LOS_ListEmpty(&g_taskRecycleList)) { + LosTaskCB *taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_taskRecycleList)); + LOS_ListDelete(&taskCB->pendList); + SCHEDULER_UNLOCK(intSave); + + OsTaskResourcesToFree(taskCB); + + SCHEDULER_LOCK(intSave); + } + SCHEDULER_UNLOCK(intSave); +} + +/* + * Description : All task entry + * Input : taskID --- The ID of the task to be run + */ +LITE_OS_SEC_TEXT_INIT VOID OsTaskEntry(UINT32 taskID) +{ + LOS_ASSERT(!OS_TID_CHECK_INVALID(taskID)); + + /* + * task scheduler needs to be protected throughout the whole process + * from interrupt and other cores. release task spinlock and enable + * interrupt in sequence at the task entry. + */ + LOS_SpinUnlock(&g_taskSpin); + (VOID)LOS_IntUnLock(); + + LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID); + taskCB->joinRetval = taskCB->taskEntry(taskCB->args[0], taskCB->args[1], + taskCB->args[2], taskCB->args[3]); /* 2 & 3: just for args array index */ + if (!(taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN)) { + taskCB->joinRetval = 0; + } + + OsRunningTaskToExit(taskCB, 0); +} + +STATIC UINT32 TaskCreateParamCheck(const UINT32 *taskID, TSK_INIT_PARAM_S *initParam) +{ + UINT32 poolSize = OS_SYS_MEM_SIZE; + + if (taskID == NULL) { + return LOS_ERRNO_TSK_ID_INVALID; + } + + if (initParam == NULL) { + return LOS_ERRNO_TSK_PTR_NULL; + } + + if (!OsProcessIsUserMode((LosProcessCB *)initParam->processID)) { + if (initParam->pcName == NULL) { + return LOS_ERRNO_TSK_NAME_EMPTY; + } + } + + if (initParam->pfnTaskEntry == NULL) { + return LOS_ERRNO_TSK_ENTRY_NULL; + } + + if (initParam->usTaskPrio > OS_TASK_PRIORITY_LOWEST) { + return LOS_ERRNO_TSK_PRIOR_ERROR; + } + + if (initParam->uwStackSize > poolSize) { + return LOS_ERRNO_TSK_STKSZ_TOO_LARGE; + } + + if (initParam->uwStackSize == 0) { + initParam->uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + } + initParam->uwStackSize = (UINT32)ALIGN(initParam->uwStackSize, LOSCFG_STACK_POINT_ALIGN_SIZE); + + if (initParam->uwStackSize < LOS_TASK_MIN_STACK_SIZE) { + return LOS_ERRNO_TSK_STKSZ_TOO_SMALL; + } + + return LOS_OK; +} + +STATIC VOID TaskCBDeInit(LosTaskCB *taskCB) +{ + UINT32 intSave; +#ifdef LOSCFG_KERNEL_SMP_TASK_SYNC + if (taskCB->syncSignal != OS_INVALID_VALUE) { + OsTaskSyncDestroy(taskCB->syncSignal); + taskCB->syncSignal = OS_INVALID_VALUE; + } +#endif + + if (taskCB->topOfStack != (UINTPTR)NULL) { + (VOID)LOS_MemFree(m_aucSysMem1, (VOID *)taskCB->topOfStack); + taskCB->topOfStack = (UINTPTR)NULL; + } + + SCHEDULER_LOCK(intSave); + LosProcessCB *processCB = OS_PCB_FROM_TCB(taskCB); + if (processCB != OsGetDefaultProcessCB()) { + LOS_ListDelete(&taskCB->threadList); + processCB->threadNumber--; + processCB->threadCount--; + } + + OsInsertTCBToFreeList(taskCB); + SCHEDULER_UNLOCK(intSave); +} + +STATIC VOID TaskCBBaseInit(LosTaskCB *taskCB, const TSK_INIT_PARAM_S *initParam) +{ + taskCB->stackPointer = NULL; + taskCB->args[0] = initParam->auwArgs[0]; /* 0~3: just for args array index */ + taskCB->args[1] = initParam->auwArgs[1]; + taskCB->args[2] = initParam->auwArgs[2]; + taskCB->args[3] = initParam->auwArgs[3]; + taskCB->topOfStack = (UINTPTR)NULL; + taskCB->stackSize = initParam->uwStackSize; + taskCB->taskEntry = initParam->pfnTaskEntry; + taskCB->signal = SIGNAL_NONE; +#ifdef LOSCFG_KERNEL_SMP_TASK_SYNC + taskCB->syncSignal = OS_INVALID_VALUE; +#endif +#ifdef LOSCFG_KERNEL_SMP + taskCB->currCpu = OS_TASK_INVALID_CPUID; + taskCB->cpuAffiMask = (initParam->usCpuAffiMask) ? + initParam->usCpuAffiMask : LOSCFG_KERNEL_CPU_MASK; +#endif + taskCB->taskStatus = OS_TASK_STATUS_INIT; + if (initParam->uwResved & LOS_TASK_ATTR_JOINABLE) { + taskCB->taskStatus |= OS_TASK_FLAG_PTHREAD_JOIN; + LOS_ListInit(&taskCB->joinList); + } + + LOS_ListInit(&taskCB->lockList); + SET_SORTLIST_VALUE(&taskCB->sortList, OS_SORT_LINK_INVALID_TIME); +#ifdef LOSCFG_KERNEL_VM + taskCB->futex.index = OS_INVALID_VALUE; +#endif +} + +STATIC UINT32 TaskCBInit(LosTaskCB *taskCB, const TSK_INIT_PARAM_S *initParam) +{ + UINT32 ret; + UINT32 numCount; + SchedParam schedParam = { 0 }; + LosSchedParam initSchedParam = {0}; + UINT16 policy = (initParam->policy == LOS_SCHED_NORMAL) ? LOS_SCHED_RR : initParam->policy; + + TaskCBBaseInit(taskCB, initParam); + + schedParam.policy = policy; + ret = OsProcessAddNewTask(initParam->processID, taskCB, &schedParam, &numCount); + if (ret != LOS_OK) { + return ret; + } + + if (policy == LOS_SCHED_DEADLINE) { + initSchedParam.runTimeUs = initParam->runTimeUs; + initSchedParam.deadlineUs = initParam->deadlineUs; + initSchedParam.periodUs = initParam->periodUs; + } else { + initSchedParam.priority = initParam->usTaskPrio; + } + ret = OsSchedParamInit(taskCB, policy, &schedParam, &initSchedParam); + if (ret != LOS_OK) { + return ret; + } + + if (initParam->pcName != NULL) { + ret = (UINT32)OsSetTaskName(taskCB, initParam->pcName, FALSE); + if (ret == LOS_OK) { + return LOS_OK; + } + } + + if (snprintf_s(taskCB->taskName, OS_TCB_NAME_LEN, OS_TCB_NAME_LEN - 1, "thread%u", numCount) < 0) { + return LOS_NOK; + } + return LOS_OK; +} + +STATIC UINT32 TaskStackInit(LosTaskCB *taskCB, const TSK_INIT_PARAM_S *initParam) +{ + VOID *topStack = (VOID *)LOS_MemAllocAlign(m_aucSysMem1, initParam->uwStackSize, LOSCFG_STACK_POINT_ALIGN_SIZE); + if (topStack == NULL) { + return LOS_ERRNO_TSK_NO_MEMORY; + } + + taskCB->topOfStack = (UINTPTR)topStack; + taskCB->stackPointer = OsTaskStackInit(taskCB->taskID, initParam->uwStackSize, topStack, TRUE); +#ifdef LOSCFG_KERNEL_VM + if (taskCB->taskStatus & OS_TASK_FLAG_USER_MODE) { + taskCB->userArea = initParam->userParam.userArea; + taskCB->userMapBase = initParam->userParam.userMapBase; + taskCB->userMapSize = initParam->userParam.userMapSize; + OsUserTaskStackInit(taskCB->stackPointer, (UINTPTR)taskCB->taskEntry, initParam->userParam.userSP); + } +#endif + return LOS_OK; +} + +STATIC LosTaskCB *GetFreeTaskCB(VOID) +{ + UINT32 intSave; + + SCHEDULER_LOCK(intSave); + if (LOS_ListEmpty(&g_losFreeTask)) { + SCHEDULER_UNLOCK(intSave); + PRINT_ERR("No idle TCB in the system!\n"); + return NULL; + } + + LosTaskCB *taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_losFreeTask)); + LOS_ListDelete(LOS_DL_LIST_FIRST(&g_losFreeTask)); + SCHEDULER_UNLOCK(intSave); + + return taskCB; +} + +LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreateOnly(UINT32 *taskID, TSK_INIT_PARAM_S *initParam) +{ + UINT32 errRet = TaskCreateParamCheck(taskID, initParam); + if (errRet != LOS_OK) { + return errRet; + } + + LosTaskCB *taskCB = GetFreeTaskCB(); + if (taskCB == NULL) { + return LOS_ERRNO_TSK_TCB_UNAVAILABLE; + } + + errRet = TaskCBInit(taskCB, initParam); + if (errRet != LOS_OK) { + goto DEINIT_TCB; + } + + errRet = TaskSyncCreate(taskCB); + if (errRet != LOS_OK) { + goto DEINIT_TCB; + } + + errRet = TaskStackInit(taskCB, initParam); + if (errRet != LOS_OK) { + goto DEINIT_TCB; + } + + if (OsConsoleIDSetHook != NULL) { + OsConsoleIDSetHook(taskCB->taskID, OsCurrTaskGet()->taskID); + } + + *taskID = taskCB->taskID; + OsHookCall(LOS_HOOK_TYPE_TASK_CREATE, taskCB); + return LOS_OK; + +DEINIT_TCB: + TaskCBDeInit(taskCB); + return errRet; +} + +LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreate(UINT32 *taskID, TSK_INIT_PARAM_S *initParam) +{ + UINT32 ret; + UINT32 intSave; + + if (initParam == NULL) { + return LOS_ERRNO_TSK_PTR_NULL; + } + + if (OS_INT_ACTIVE) { + return LOS_ERRNO_TSK_YIELD_IN_INT; + } + + if (OsProcessIsUserMode(OsCurrProcessGet())) { + initParam->processID = (UINTPTR)OsGetKernelInitProcess(); + } else { + initParam->processID = (UINTPTR)OsCurrProcessGet(); + } + + ret = LOS_TaskCreateOnly(taskID, initParam); + if (ret != LOS_OK) { + return ret; + } + + LosTaskCB *taskCB = OS_TCB_FROM_TID(*taskID); + + SCHEDULER_LOCK(intSave); + taskCB->ops->enqueue(OsSchedRunqueue(), taskCB); + SCHEDULER_UNLOCK(intSave); + + /* in case created task not running on this core, + schedule or not depends on other schedulers status. */ + LOS_MpSchedule(OS_MP_CPU_ALL); + if (OS_SCHEDULER_ACTIVE) { + LOS_Schedule(); + } + + return LOS_OK; +} + +LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskResume(UINT32 taskID) +{ + UINT32 intSave; + UINT32 errRet; + BOOL needSched = FALSE; + + if (OS_TID_CHECK_INVALID(taskID)) { + return LOS_ERRNO_TSK_ID_INVALID; + } + + LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID); + SCHEDULER_LOCK(intSave); + + /* clear pending signal */ + taskCB->signal &= ~SIGNAL_SUSPEND; + + if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { + errRet = LOS_ERRNO_TSK_NOT_CREATED; + OS_GOTO_ERREND(); + } else if (!(taskCB->taskStatus & OS_TASK_STATUS_SUSPENDED)) { + errRet = LOS_ERRNO_TSK_NOT_SUSPENDED; + OS_GOTO_ERREND(); + } + + errRet = taskCB->ops->resume(taskCB, &needSched); + SCHEDULER_UNLOCK(intSave); + + LOS_MpSchedule(OS_MP_CPU_ALL); + if (OS_SCHEDULER_ACTIVE && needSched) { + LOS_Schedule(); + } + + return errRet; + +LOS_ERREND: + SCHEDULER_UNLOCK(intSave); + return errRet; +} + +/* + * Check if needs to do the suspend operation on the running task. + * Return TRUE, if needs to do the suspension. + * Return FALSE, if meets following circumstances: + * 1. Do the suspension across cores, if SMP is enabled + * 2. Do the suspension when preemption is disabled + * 3. Do the suspension in hard-irq + * then LOS_TaskSuspend will directly return with 'ret' value. + */ +LITE_OS_SEC_TEXT_INIT STATIC BOOL OsTaskSuspendCheckOnRun(LosTaskCB *taskCB, UINT32 *ret) +{ + /* init default out return value */ + *ret = LOS_OK; + +#ifdef LOSCFG_KERNEL_SMP + /* ASYNCHRONIZED. No need to do task lock checking */ + if (taskCB->currCpu != ArchCurrCpuid()) { + taskCB->signal = SIGNAL_SUSPEND; + LOS_MpSchedule(taskCB->currCpu); + return FALSE; + } +#endif + + if (!OsPreemptableInSched()) { + /* Suspending the current core's running task */ + *ret = LOS_ERRNO_TSK_SUSPEND_LOCKED; + return FALSE; + } + + if (OS_INT_ACTIVE) { + /* suspend running task in interrupt */ + taskCB->signal = SIGNAL_SUSPEND; + return FALSE; + } + + return TRUE; +} + +LITE_OS_SEC_TEXT STATIC UINT32 OsTaskSuspend(LosTaskCB *taskCB) +{ + UINT32 errRet; + UINT16 tempStatus = taskCB->taskStatus; + if (tempStatus & OS_TASK_STATUS_UNUSED) { + return LOS_ERRNO_TSK_NOT_CREATED; + } + + if (tempStatus & OS_TASK_STATUS_SUSPENDED) { + return LOS_ERRNO_TSK_ALREADY_SUSPENDED; + } + + if ((tempStatus & OS_TASK_STATUS_RUNNING) && + !OsTaskSuspendCheckOnRun(taskCB, &errRet)) { + return errRet; + } + + return taskCB->ops->suspend(taskCB); +} + +LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskSuspend(UINT32 taskID) +{ + UINT32 intSave; + UINT32 errRet; + + if (OS_TID_CHECK_INVALID(taskID)) { + return LOS_ERRNO_TSK_ID_INVALID; + } + + LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID); + if (taskCB->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) { + return LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK; + } + + SCHEDULER_LOCK(intSave); + errRet = OsTaskSuspend(taskCB); + SCHEDULER_UNLOCK(intSave); + return errRet; +} + +STATIC INLINE VOID OsTaskStatusUnusedSet(LosTaskCB *taskCB) +{ + taskCB->taskStatus |= OS_TASK_STATUS_UNUSED; + taskCB->eventMask = 0; + + OS_MEM_CLEAR(taskCB->taskID); +} + +STATIC VOID OsTaskReleaseHoldLock(LosTaskCB *taskCB) +{ + LosMux *mux = NULL; + UINT32 ret; + + while (!LOS_ListEmpty(&taskCB->lockList)) { + mux = LOS_DL_LIST_ENTRY(LOS_DL_LIST_FIRST(&taskCB->lockList), LosMux, holdList); + ret = OsMuxUnlockUnsafe(taskCB, mux, NULL); + if (ret != LOS_OK) { + LOS_ListDelete(&mux->holdList); + PRINT_ERR("mux ulock failed! : %u\n", ret); + } + } + +#ifdef LOSCFG_KERNEL_VM + if (taskCB->taskStatus & OS_TASK_FLAG_USER_MODE) { + OsFutexNodeDeleteFromFutexHash(&taskCB->futex, TRUE, NULL, NULL); + } +#endif + + OsTaskJoinPostUnsafe(taskCB); + + OsTaskSyncWake(taskCB); +} + +LITE_OS_SEC_TEXT VOID OsRunningTaskToExit(LosTaskCB *runTask, UINT32 status) +{ + UINT32 intSave; + + if (OsIsProcessThreadGroup(runTask)) { + OsProcessThreadGroupDestroy(); + } + + OsHookCall(LOS_HOOK_TYPE_TASK_DELETE, runTask); + + SCHEDULER_LOCK(intSave); + if (OsProcessThreadNumberGet(runTask) == 1) { /* 1: The last task of the process exits */ + SCHEDULER_UNLOCK(intSave); + + OsTaskResourcesToFree(runTask); + OsProcessResourcesToFree(OS_PCB_FROM_TCB(runTask)); + + SCHEDULER_LOCK(intSave); + + OsProcessNaturalExit(OS_PCB_FROM_TCB(runTask), status); + OsTaskReleaseHoldLock(runTask); + OsTaskStatusUnusedSet(runTask); + } else if (runTask->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) { + OsTaskReleaseHoldLock(runTask); + } else { + SCHEDULER_UNLOCK(intSave); + + OsTaskResourcesToFree(runTask); + + SCHEDULER_LOCK(intSave); + OsInactiveTaskDelete(runTask); + OsEventWriteUnsafe(&g_resourceEvent, OS_RESOURCE_EVENT_FREE, FALSE, NULL); + } + + OsSchedResched(); + SCHEDULER_UNLOCK(intSave); + return; +} + +LITE_OS_SEC_TEXT VOID OsInactiveTaskDelete(LosTaskCB *taskCB) +{ + UINT16 taskStatus = taskCB->taskStatus; + + OsTaskReleaseHoldLock(taskCB); + + taskCB->ops->exit(taskCB); + if (taskStatus & OS_TASK_STATUS_PENDING) { + LosMux *mux = (LosMux *)taskCB->taskMux; + if (LOS_MuxIsValid(mux) == TRUE) { + OsMuxBitmapRestore(mux, NULL, taskCB); + } + } + + OsTaskStatusUnusedSet(taskCB); + + OsDeleteTaskFromProcess(taskCB); + + OsHookCall(LOS_HOOK_TYPE_TASK_DELETE, taskCB); +} + +LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskDelete(UINT32 taskID) +{ + UINT32 intSave; + UINT32 ret = LOS_OK; + + if (OS_TID_CHECK_INVALID(taskID)) { + return LOS_ERRNO_TSK_ID_INVALID; + } + + if (OS_INT_ACTIVE) { + return LOS_ERRNO_TSK_YIELD_IN_INT; + } + + LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID); + if (taskCB == OsCurrTaskGet()) { + if (!OsPreemptable()) { + return LOS_ERRNO_TSK_DELETE_LOCKED; + } + + OsRunningTaskToExit(taskCB, OS_PRO_EXIT_OK); + return LOS_NOK; + } + + SCHEDULER_LOCK(intSave); + if (OsTaskIsNotDelete(taskCB)) { + if (OsTaskIsUnused(taskCB)) { + ret = LOS_ERRNO_TSK_NOT_CREATED; + } else { + ret = LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK; + } + OS_GOTO_ERREND(); + } + +#ifdef LOSCFG_KERNEL_SMP + if (taskCB->taskStatus & OS_TASK_STATUS_RUNNING) { + taskCB->signal = SIGNAL_KILL; + LOS_MpSchedule(taskCB->currCpu); + ret = OsTaskSyncWait(taskCB); + OS_GOTO_ERREND(); + } +#endif + + OsInactiveTaskDelete(taskCB); + OsEventWriteUnsafe(&g_resourceEvent, OS_RESOURCE_EVENT_FREE, FALSE, NULL); + +LOS_ERREND: + SCHEDULER_UNLOCK(intSave); + if (ret == LOS_OK) { + LOS_Schedule(); + } + return ret; +} + +LITE_OS_SEC_TEXT UINT32 LOS_TaskDelay(UINT32 tick) +{ + UINT32 intSave; + + if (OS_INT_ACTIVE) { + PRINT_ERR("In interrupt not allow delay task!\n"); + return LOS_ERRNO_TSK_DELAY_IN_INT; + } + + LosTaskCB *runTask = OsCurrTaskGet(); + if (runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) { + OsBackTrace(); + return LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK; + } + + if (!OsPreemptable()) { + return LOS_ERRNO_TSK_DELAY_IN_LOCK; + } + OsHookCall(LOS_HOOK_TYPE_TASK_DELAY, tick); + if (tick == 0) { + return LOS_TaskYield(); + } + + SCHEDULER_LOCK(intSave); + UINT32 ret = runTask->ops->delay(runTask, OS_SCHED_TICK_TO_CYCLE(tick)); + OsHookCall(LOS_HOOK_TYPE_MOVEDTASKTODELAYEDLIST, runTask); + SCHEDULER_UNLOCK(intSave); + return ret; +} + +LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskPriGet(UINT32 taskID) +{ + UINT32 intSave; + SchedParam param = { 0 }; + + if (OS_TID_CHECK_INVALID(taskID)) { + return (UINT16)OS_INVALID; + } + + LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID); + SCHEDULER_LOCK(intSave); + if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { + SCHEDULER_UNLOCK(intSave); + return (UINT16)OS_INVALID; + } + + taskCB->ops->schedParamGet(taskCB, ¶m); + SCHEDULER_UNLOCK(intSave); + return param.priority; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskPriSet(UINT32 taskID, UINT16 taskPrio) +{ + UINT32 intSave; + SchedParam param = { 0 }; + + if (taskPrio > OS_TASK_PRIORITY_LOWEST) { + return LOS_ERRNO_TSK_PRIOR_ERROR; + } + + if (OS_TID_CHECK_INVALID(taskID)) { + return LOS_ERRNO_TSK_ID_INVALID; + } + + LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID); + if (taskCB->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) { + return LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK; + } + + SCHEDULER_LOCK(intSave); + if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { + SCHEDULER_UNLOCK(intSave); + return LOS_ERRNO_TSK_NOT_CREATED; + } + + taskCB->ops->schedParamGet(taskCB, ¶m); + + param.priority = taskPrio; + + BOOL needSched = taskCB->ops->schedParamModify(taskCB, ¶m); + SCHEDULER_UNLOCK(intSave); + + LOS_MpSchedule(OS_MP_CPU_ALL); + if (needSched && OS_SCHEDULER_ACTIVE) { + LOS_Schedule(); + } + return LOS_OK; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_CurTaskPriSet(UINT16 taskPrio) +{ + return LOS_TaskPriSet(OsCurrTaskGet()->taskID, taskPrio); +} + +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskYield(VOID) +{ + UINT32 intSave; + + if (OS_INT_ACTIVE) { + return LOS_ERRNO_TSK_YIELD_IN_INT; + } + + if (!OsPreemptable()) { + return LOS_ERRNO_TSK_YIELD_IN_LOCK; + } + + LosTaskCB *runTask = OsCurrTaskGet(); + if (OS_TID_CHECK_INVALID(runTask->taskID)) { + return LOS_ERRNO_TSK_ID_INVALID; + } + + SCHEDULER_LOCK(intSave); + /* reset timeslice of yielded task */ + runTask->ops->yield(runTask); + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +LITE_OS_SEC_TEXT_MINOR VOID LOS_TaskLock(VOID) +{ + UINT32 intSave; + + intSave = LOS_IntLock(); + OsSchedLock(); + LOS_IntRestore(intSave); +} + +LITE_OS_SEC_TEXT_MINOR VOID LOS_TaskUnlock(VOID) +{ + UINT32 intSave; + + intSave = LOS_IntLock(); + BOOL needSched = OsSchedUnlockResch(); + LOS_IntRestore(intSave); + + if (needSched) { + LOS_Schedule(); + } +} + +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskInfoGet(UINT32 taskID, TSK_INFO_S *taskInfo) +{ + UINT32 intSave; + SchedParam param = { 0 }; + + if (taskInfo == NULL) { + return LOS_ERRNO_TSK_PTR_NULL; + } + + if (OS_TID_CHECK_INVALID(taskID)) { + return LOS_ERRNO_TSK_ID_INVALID; + } + + LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID); + SCHEDULER_LOCK(intSave); + if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { + SCHEDULER_UNLOCK(intSave); + return LOS_ERRNO_TSK_NOT_CREATED; + } + + if (!(taskCB->taskStatus & OS_TASK_STATUS_RUNNING) || OS_INT_ACTIVE) { + taskInfo->uwSP = (UINTPTR)taskCB->stackPointer; + } else { + taskInfo->uwSP = ArchSPGet(); + } + + taskCB->ops->schedParamGet(taskCB, ¶m); + taskInfo->usTaskStatus = taskCB->taskStatus; + taskInfo->usTaskPrio = param.priority; + taskInfo->uwStackSize = taskCB->stackSize; + taskInfo->uwTopOfStack = taskCB->topOfStack; + taskInfo->uwEventMask = taskCB->eventMask; + taskInfo->taskEvent = taskCB->taskEvent; + taskInfo->pTaskMux = taskCB->taskMux; + taskInfo->uwTaskID = taskID; + + if (strncpy_s(taskInfo->acName, LOS_TASK_NAMELEN, taskCB->taskName, LOS_TASK_NAMELEN - 1) != EOK) { + PRINT_ERR("Task name copy failed!\n"); + } + taskInfo->acName[LOS_TASK_NAMELEN - 1] = '\0'; + + taskInfo->uwBottomOfStack = TRUNCATE(((UINTPTR)taskCB->topOfStack + taskCB->stackSize), + OS_TASK_STACK_ADDR_ALIGN); + taskInfo->uwCurrUsed = (UINT32)(taskInfo->uwBottomOfStack - taskInfo->uwSP); + + taskInfo->bOvf = OsStackWaterLineGet((const UINTPTR *)taskInfo->uwBottomOfStack, + (const UINTPTR *)taskInfo->uwTopOfStack, &taskInfo->uwPeakUsed); + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +LITE_OS_SEC_TEXT BOOL OsTaskCpuAffiSetUnsafe(UINT32 taskID, UINT16 newCpuAffiMask, UINT16 *oldCpuAffiMask) +{ +#ifdef LOSCFG_KERNEL_SMP + LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID); + + taskCB->cpuAffiMask = newCpuAffiMask; + *oldCpuAffiMask = CPUID_TO_AFFI_MASK(taskCB->currCpu); + if (!((*oldCpuAffiMask) & newCpuAffiMask)) { + taskCB->signal = SIGNAL_AFFI; + return TRUE; + } +#else + (VOID)taskID; + (VOID)newCpuAffiMask; + (VOID)oldCpuAffiMask; +#endif /* LOSCFG_KERNEL_SMP */ + return FALSE; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskCpuAffiSet(UINT32 taskID, UINT16 cpuAffiMask) +{ + BOOL needSched = FALSE; + UINT32 intSave; + UINT16 currCpuMask; + + if (OS_TID_CHECK_INVALID(taskID)) { + return LOS_ERRNO_TSK_ID_INVALID; + } + + if (!(cpuAffiMask & LOSCFG_KERNEL_CPU_MASK)) { + return LOS_ERRNO_TSK_CPU_AFFINITY_MASK_ERR; + } + + LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID); + SCHEDULER_LOCK(intSave); + if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { + SCHEDULER_UNLOCK(intSave); + return LOS_ERRNO_TSK_NOT_CREATED; + } + needSched = OsTaskCpuAffiSetUnsafe(taskID, cpuAffiMask, &currCpuMask); + + SCHEDULER_UNLOCK(intSave); + if (needSched && OS_SCHEDULER_ACTIVE) { + LOS_MpSchedule(currCpuMask); + LOS_Schedule(); + } + + return LOS_OK; +} + +LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskCpuAffiGet(UINT32 taskID) +{ +#ifdef LOSCFG_KERNEL_SMP +#define INVALID_CPU_AFFI_MASK 0 + UINT16 cpuAffiMask; + UINT32 intSave; + + if (OS_TID_CHECK_INVALID(taskID)) { + return INVALID_CPU_AFFI_MASK; + } + + LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID); + SCHEDULER_LOCK(intSave); + if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { + SCHEDULER_UNLOCK(intSave); + return INVALID_CPU_AFFI_MASK; + } + + cpuAffiMask = taskCB->cpuAffiMask; + SCHEDULER_UNLOCK(intSave); + + return cpuAffiMask; +#else + (VOID)taskID; + return 1; +#endif +} + +/* + * Description : Process pending signals tagged by others cores + */ +LITE_OS_SEC_TEXT_MINOR VOID OsTaskProcSignal(VOID) +{ + UINT32 ret; + + /* + * private and uninterruptable, no protection needed. + * while this task is always running when others cores see it, + * so it keeps receiving signals while follow code executing. + */ + LosTaskCB *runTask = OsCurrTaskGet(); + if (runTask->signal == SIGNAL_NONE) { + return; + } + + if (runTask->signal & SIGNAL_KILL) { + /* + * clear the signal, and do the task deletion. if the signaled task has been + * scheduled out, then this deletion will wait until next run. + */ + runTask->signal = SIGNAL_NONE; + ret = LOS_TaskDelete(runTask->taskID); + if (ret != LOS_OK) { + PRINT_ERR("Task proc signal delete task(%u) failed err:0x%x\n", runTask->taskID, ret); + } + } else if (runTask->signal & SIGNAL_SUSPEND) { + runTask->signal &= ~SIGNAL_SUSPEND; + + /* suspend killed task may fail, ignore the result */ + (VOID)LOS_TaskSuspend(runTask->taskID); +#ifdef LOSCFG_KERNEL_SMP + } else if (runTask->signal & SIGNAL_AFFI) { + runTask->signal &= ~SIGNAL_AFFI; + + /* priority queue has updated, notify the target cpu */ + LOS_MpSchedule((UINT32)runTask->cpuAffiMask); +#endif + } +} + +LITE_OS_SEC_TEXT INT32 OsSetTaskName(LosTaskCB *taskCB, const CHAR *name, BOOL setPName) +{ + UINT32 intSave; + errno_t err; + const CHAR *namePtr = NULL; + CHAR nameBuff[OS_TCB_NAME_LEN] = { 0 }; + + if ((taskCB == NULL) || (name == NULL)) { + return EINVAL; + } + + if (LOS_IsUserAddress((VADDR_T)(UINTPTR)name)) { + err = LOS_StrncpyFromUser(nameBuff, (const CHAR *)name, OS_TCB_NAME_LEN); + if (err < 0) { + return -err; + } + namePtr = nameBuff; + } else { + namePtr = name; + } + + SCHEDULER_LOCK(intSave); + + err = strncpy_s(taskCB->taskName, OS_TCB_NAME_LEN, (VOID *)namePtr, OS_TCB_NAME_LEN - 1); + if (err != EOK) { + err = EINVAL; + goto EXIT; + } + + err = LOS_OK; + /* if thread is main thread, then set processName as taskName */ + if (OsIsProcessThreadGroup(taskCB) && (setPName == TRUE)) { + err = (INT32)OsSetProcessName(OS_PCB_FROM_TCB(taskCB), (const CHAR *)taskCB->taskName); + if (err != LOS_OK) { + err = EINVAL; + } + } + +EXIT: + SCHEDULER_UNLOCK(intSave); + return err; +} + +INT32 OsUserTaskOperatePermissionsCheck(const LosTaskCB *taskCB) +{ + return OsUserProcessOperatePermissionsCheck(taskCB, (UINTPTR)OsCurrProcessGet()); +} + +INT32 OsUserProcessOperatePermissionsCheck(const LosTaskCB *taskCB, UINTPTR processCB) +{ + if (taskCB == NULL) { + return LOS_EINVAL; + } + + if (processCB == (UINTPTR)OsGetDefaultProcessCB()) { + return LOS_EINVAL; + } + + if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { + return LOS_EINVAL; + } + + if (processCB != taskCB->processCB) { + return LOS_EPERM; + } + + return LOS_OK; +} + +LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsCreateUserTaskParamCheck(UINT32 processID, TSK_INIT_PARAM_S *param) +{ + UserTaskParam *userParam = NULL; + + if (param == NULL) { + return OS_INVALID_VALUE; + } + + userParam = ¶m->userParam; + if ((processID == OS_INVALID_VALUE) && !LOS_IsUserAddress(userParam->userArea)) { + return OS_INVALID_VALUE; + } + + if (!LOS_IsUserAddress((UINTPTR)param->pfnTaskEntry)) { + return OS_INVALID_VALUE; + } + + if (userParam->userMapBase && !LOS_IsUserAddressRange(userParam->userMapBase, userParam->userMapSize)) { + return OS_INVALID_VALUE; + } + + if (!LOS_IsUserAddress(userParam->userSP)) { + return OS_INVALID_VALUE; + } + + return LOS_OK; +} + +LITE_OS_SEC_TEXT_INIT UINT32 OsCreateUserTask(UINTPTR processID, TSK_INIT_PARAM_S *initParam) +{ + UINT32 taskID; + UINT32 ret; + UINT32 intSave; + INT32 policy; + SchedParam param; + + ret = OsCreateUserTaskParamCheck(processID, initParam); + if (ret != LOS_OK) { + return ret; + } + + initParam->uwStackSize = OS_USER_TASK_SYSCALL_STACK_SIZE; + initParam->usTaskPrio = OS_TASK_PRIORITY_LOWEST; + if (processID == OS_INVALID_VALUE) { + SCHEDULER_LOCK(intSave); + LosProcessCB *processCB = OsCurrProcessGet(); + initParam->processID = (UINTPTR)processCB; + initParam->consoleID = processCB->consoleID; + SCHEDULER_UNLOCK(intSave); + ret = LOS_GetProcessScheduler(processCB->processID, &policy, NULL); + if (ret != LOS_OK) { + return OS_INVALID_VALUE; + } + initParam->policy = policy; + if (policy == LOS_SCHED_DEADLINE) { + OsSchedProcessDefaultSchedParamGet((UINT16)policy, ¶m); + initParam->runTimeUs = param.runTimeUs; + initParam->deadlineUs = param.deadlineUs; + initParam->periodUs = param.periodUs; + } + } else { + initParam->policy = LOS_SCHED_RR; + initParam->processID = processID; + initParam->consoleID = 0; + } + + ret = LOS_TaskCreateOnly(&taskID, initParam); + if (ret != LOS_OK) { + return OS_INVALID_VALUE; + } + + return taskID; +} + +LITE_OS_SEC_TEXT INT32 LOS_GetTaskScheduler(INT32 taskID) +{ + UINT32 intSave; + INT32 policy; + SchedParam param = { 0 }; + + if (OS_TID_CHECK_INVALID(taskID)) { + return -LOS_EINVAL; + } + + LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID); + SCHEDULER_LOCK(intSave); + if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { + policy = -LOS_EINVAL; + OS_GOTO_ERREND(); + } + + taskCB->ops->schedParamGet(taskCB, ¶m); + policy = (INT32)param.policy; + +LOS_ERREND: + SCHEDULER_UNLOCK(intSave); + return policy; +} + +LITE_OS_SEC_TEXT INT32 LOS_SetTaskScheduler(INT32 taskID, UINT16 policy, UINT16 priority) +{ + SchedParam param = { 0 }; + UINT32 intSave; + + if (OS_TID_CHECK_INVALID(taskID)) { + return LOS_ESRCH; + } + + if (priority > OS_TASK_PRIORITY_LOWEST) { + return LOS_EINVAL; + } + + if ((policy != LOS_SCHED_FIFO) && (policy != LOS_SCHED_RR)) { + return LOS_EINVAL; + } + + LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID); + if (taskCB->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) { + return LOS_EPERM; + } + + SCHEDULER_LOCK(intSave); + if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { + SCHEDULER_UNLOCK(intSave); + return LOS_EINVAL; + } + + taskCB->ops->schedParamGet(taskCB, ¶m); + param.policy = policy; + param.priority = priority; + BOOL needSched = taskCB->ops->schedParamModify(taskCB, ¶m); + SCHEDULER_UNLOCK(intSave); + + LOS_MpSchedule(OS_MP_CPU_ALL); + if (needSched && OS_SCHEDULER_ACTIVE) { + LOS_Schedule(); + } + + return LOS_OK; +} + +STATIC UINT32 OsTaskJoinCheck(UINT32 taskID) +{ + if (OS_TID_CHECK_INVALID(taskID)) { + return LOS_EINVAL; + } + + if (OS_INT_ACTIVE) { + return LOS_EINTR; + } + + if (!OsPreemptable()) { + return LOS_EINVAL; + } + + LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID); + if (taskCB->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) { + return LOS_EPERM; + } + + if (taskCB == OsCurrTaskGet()) { + return LOS_EDEADLK; + } + + return LOS_OK; +} + +UINT32 LOS_TaskJoin(UINT32 taskID, UINTPTR *retval) +{ + UINT32 intSave; + LosTaskCB *runTask = OsCurrTaskGet(); + UINT32 errRet; + + errRet = OsTaskJoinCheck(taskID); + if (errRet != LOS_OK) { + return errRet; + } + + LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID); + SCHEDULER_LOCK(intSave); + if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { + SCHEDULER_UNLOCK(intSave); + return LOS_EINVAL; + } + + if (runTask->processCB != taskCB->processCB) { + SCHEDULER_UNLOCK(intSave); + return LOS_EPERM; + } + + errRet = OsTaskJoinPendUnsafe(taskCB); + SCHEDULER_UNLOCK(intSave); + + if (errRet == LOS_OK) { + LOS_Schedule(); + + if (retval != NULL) { + *retval = (UINTPTR)taskCB->joinRetval; + } + + (VOID)LOS_TaskDelete(taskID); + return LOS_OK; + } + + return errRet; +} + +UINT32 LOS_TaskDetach(UINT32 taskID) +{ + UINT32 intSave; + LosTaskCB *runTask = OsCurrTaskGet(); + UINT32 errRet; + + if (OS_TID_CHECK_INVALID(taskID)) { + return LOS_EINVAL; + } + + if (OS_INT_ACTIVE) { + return LOS_EINTR; + } + + LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID); + SCHEDULER_LOCK(intSave); + if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { + SCHEDULER_UNLOCK(intSave); + return LOS_EINVAL; + } + + if (runTask->processCB != taskCB->processCB) { + SCHEDULER_UNLOCK(intSave); + return LOS_EPERM; + } + + if (taskCB->taskStatus & OS_TASK_STATUS_EXIT) { + SCHEDULER_UNLOCK(intSave); + return LOS_TaskJoin(taskID, NULL); + } + + errRet = OsTaskSetDetachUnsafe(taskCB); + SCHEDULER_UNLOCK(intSave); + return errRet; +} + +LITE_OS_SEC_TEXT UINT32 LOS_GetSystemTaskMaximum(VOID) +{ + return g_taskMaxNum; +} + +LosTaskCB *OsGetDefaultTaskCB(VOID) +{ + return &g_taskCBArray[g_taskMaxNum]; +} + +LITE_OS_SEC_TEXT VOID OsWriteResourceEvent(UINT32 events) +{ + (VOID)LOS_EventWrite(&g_resourceEvent, events); +} + +LITE_OS_SEC_TEXT VOID OsWriteResourceEventUnsafe(UINT32 events) +{ + (VOID)OsEventWriteUnsafe(&g_resourceEvent, events, FALSE, NULL); +} + +STATIC VOID OsResourceRecoveryTask(VOID) +{ + UINT32 ret; + + while (1) { + ret = LOS_EventRead(&g_resourceEvent, OS_RESOURCE_EVENT_MASK, + LOS_WAITMODE_OR | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER); + if (ret & (OS_RESOURCE_EVENT_FREE | OS_RESOURCE_EVENT_OOM)) { + OsTaskCBRecycleToFree(); + + OsProcessCBRecycleToFree(); + } + +#ifdef LOSCFG_ENABLE_OOM_LOOP_TASK + if (ret & OS_RESOURCE_EVENT_OOM) { + (VOID)OomCheckProcess(); + } +#endif + } +} + +LITE_OS_SEC_TEXT UINT32 OsResourceFreeTaskCreate(VOID) +{ + UINT32 ret; + UINT32 taskID; + TSK_INIT_PARAM_S taskInitParam; + + ret = LOS_EventInit((PEVENT_CB_S)&g_resourceEvent); + if (ret != LOS_OK) { + return LOS_NOK; + } + + (VOID)memset_s((VOID *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)OsResourceRecoveryTask; + taskInitParam.uwStackSize = OS_TASK_RESOURCE_STATIC_SIZE; + taskInitParam.pcName = "ResourcesTask"; + taskInitParam.usTaskPrio = OS_TASK_RESOURCE_FREE_PRIORITY; + ret = LOS_TaskCreate(&taskID, &taskInitParam); + if (ret == LOS_OK) { + OS_TCB_FROM_TID(taskID)->taskStatus |= OS_TASK_FLAG_NO_DELETE; + } + return ret; +} + +LOS_MODULE_INIT(OsResourceFreeTaskCreate, LOS_INIT_LEVEL_KMOD_TASK); + diff --git a/src/kernel_liteos_a/kernel/base/core/los_tick.c b/src/kernel_liteos_a/kernel/base/core/los_tick.c new file mode 100644 index 00000000..b5c2794e --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/core/los_tick.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_tick_pri.h" +#include "los_swtmr_pri.h" +#include "los_sched_pri.h" +#ifdef LOSCFG_KERNEL_VDSO +#include "los_vdso.h" +#endif + + +LITE_OS_SEC_DATA_INIT UINT32 g_sysClock; +LITE_OS_SEC_DATA_INIT UINT32 g_tickPerSecond; +LITE_OS_SEC_BSS DOUBLE g_cycle2NsScale; + +/* spinlock for task module */ +LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_tickSpin); + +/* + * Description : Tick interruption handler + */ +LITE_OS_SEC_TEXT VOID OsTickHandler(VOID) +{ +#ifdef LOSCFG_SCHED_TICK_DEBUG + OsSchedDebugRecordData(); +#endif + +#ifdef LOSCFG_KERNEL_VDSO + OsVdsoTimevalUpdate(); +#endif + +#ifdef LOSCFG_BASE_CORE_TICK_HW_TIME + HalClockIrqClear(); /* diff from every platform */ +#endif + + OsSchedTick(); +} + diff --git a/src/kernel_liteos_a/kernel/base/include/los_base_pri.h b/src/kernel_liteos_a/kernel/base/include/los_base_pri.h new file mode 100644 index 00000000..24719cc7 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_base_pri.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_BASE_PRI_H +#define _LOS_BASE_PRI_H + +#include "los_base.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define OS_GOTO_ERREND() do { \ + goto LOS_ERREND; \ +} while (0) + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_BASE_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_binarytree_pri.h b/src/kernel_liteos_a/kernel/base/include/los_binarytree_pri.h new file mode 100644 index 00000000..c442f605 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_binarytree_pri.h @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_BINARYTREE_PRI_H +#define _LOS_BINARYTREE_PRI_H + +#include "los_typedef.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef struct tagBinNode { + struct tagBinNode *left; + struct tagBinNode *right; + UINT32 nodeID; + CHAR keyValue[0]; +} BinNode; + +typedef struct { + BinNode leaf; + UINTPTR linkReg1; + UINTPTR linkReg2; + UINTPTR linkReg3; +} LinkRegNode; + +#define LR_COUNT 4096 +extern LinkRegNode g_linkRegNode[LR_COUNT]; +extern UINT32 g_linkRegNodeIndex; +extern LinkRegNode *g_linkRegRoot; + +typedef struct { + BinNode leaf; + UINTPTR addr; +} AddrNode; + +#define ADDR_COUNT 40960 +extern AddrNode g_addrNode[ADDR_COUNT]; +extern UINT32 g_addrNodeIndex; +extern AddrNode *g_addrRoot; + +typedef struct { + BinNode leaf; + UINT32 reqSize; +} ReqSizeNode; + +#define REQ_SIZE_COUNT 4096 +extern ReqSizeNode g_reqSizeNode[REQ_SIZE_COUNT]; +extern UINT32 g_reqSizeNodeIndex; +extern ReqSizeNode *g_reqSizeRoot; + +typedef struct { + BinNode leaf; + UINT32 taskID; +} TaskIDNode; + +#define TASK_ID_COUNT 1024 + +extern UINT32 OsBinTreeInsert(const VOID *node, UINT32 nodeLen, BinNode **leaf, + BinNode *(*GetMyBinNode)(UINT32 *nodeID), + INT32 (*CompareNode)(const VOID *node1, const VOID *node2)); + +extern INT32 OsCompareLRNode(const VOID *node1, const VOID *node2); +extern BinNode *OsGetLRBinNode(UINT32 *nodeID); + +extern INT32 OsCompareAddrNode(const VOID *node1, const VOID *node2); +extern BinNode *OsGetAddrBinNode(UINT32 *nodeID); + +extern INT32 OsCompareReqSizeNode(const VOID *node1, const VOID *node2); +extern BinNode *OsGetReqSizeBinNode(UINT32 *nodeID); + +extern INT32 OsCompareTaskIDNode(const VOID *node1, const VOID *node2); +extern BinNode *OsGetTaskIDBinNode(UINT32 *nodeID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_BINARYTREE_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_container_pri.h b/src/kernel_liteos_a/kernel/base/include/los_container_pri.h new file mode 100644 index 00000000..d7b72c70 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_container_pri.h @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_CONTAINER_PRI_H +#define _LOS_CONTAINER_PRI_H + +#include "los_atomic.h" +#ifdef LOSCFG_KERNEL_CONTAINER +#ifdef LOSCFG_PID_CONTAINER +#include "los_pid_container_pri.h" +#endif +#ifdef LOSCFG_UTS_CONTAINER +#include "los_uts_container_pri.h" +#endif +#ifdef LOSCFG_MNT_CONTAINER +#include "los_mnt_container_pri.h" +#endif +#ifdef LOSCFG_IPC_CONTAINER +#include "los_ipc_container_pri.h" +#endif +#ifdef LOSCFG_USER_CONTAINER +#include "los_user_container_pri.h" +#endif +#ifdef LOSCFG_TIME_CONTAINER +#include "los_time_container_pri.h" +#endif +#ifdef LOSCFG_NET_CONTAINER +#include "los_net_container_pri.h" +#endif + +typedef enum { + CONTAINER = 0, + PID_CONTAINER, + PID_CHILD_CONTAINER, + UTS_CONTAINER, + MNT_CONTAINER, + IPC_CONTAINER, + USER_CONTAINER, + TIME_CONTAINER, + TIME_CHILD_CONTAINER, + NET_CONTAINER, + CONTAINER_MAX, +} ContainerType; + +typedef struct Container { + Atomic rc; +#ifdef LOSCFG_PID_CONTAINER + struct PidContainer *pidContainer; + struct PidContainer *pidForChildContainer; +#endif +#ifdef LOSCFG_UTS_CONTAINER + struct UtsContainer *utsContainer; +#endif +#ifdef LOSCFG_MNT_CONTAINER + struct MntContainer *mntContainer; +#endif +#ifdef LOSCFG_IPC_CONTAINER + struct IpcContainer *ipcContainer; +#endif +#ifdef LOSCFG_TIME_CONTAINER + struct TimeContainer *timeContainer; + struct TimeContainer *timeForChildContainer; +#endif +#ifdef LOSCFG_NET_CONTAINER + struct NetContainer *netContainer; +#endif +} Container; + +typedef struct TagContainerLimit { +#ifdef LOSCFG_PID_CONTAINER + UINT32 pidLimit; +#endif +#ifdef LOSCFG_UTS_CONTAINER + UINT32 utsLimit; +#endif +#ifdef LOSCFG_MNT_CONTAINER + UINT32 mntLimit; +#endif +#ifdef LOSCFG_IPC_CONTAINER + UINT32 ipcLimit; +#endif +#ifdef LOSCFG_TIME_CONTAINER + UINT32 timeLimit; +#endif +#ifdef LOSCFG_USER_CONTAINER + UINT32 userLimit; +#endif +#ifdef LOSCFG_NET_CONTAINER + UINT32 netLimit; +#endif +} ContainerLimit; + +VOID OsContainerInitSystemProcess(LosProcessCB *processCB); + +VOID OsInitRootContainer(VOID); + +UINT32 OsCopyContainers(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent, UINT32 *processID); + +VOID OsOsContainersDestroyEarly(LosProcessCB *processCB); + +VOID OsContainersDestroy(LosProcessCB *processCB); + +VOID OsContainerFree(LosProcessCB *processCB); + +UINT32 OsAllocContainerID(VOID); + +UINT32 OsGetContainerID(LosProcessCB *processCB, ContainerType type); + +INT32 OsUnshare(UINT32 flags); + +INT32 OsSetNs(INT32 fd, INT32 type); + +UINT32 OsGetContainerLimit(ContainerType type); + +UINT32 OsContainerLimitCheck(ContainerType type, UINT32 *containerCount); + +UINT32 OsSetContainerLimit(ContainerType type, UINT32 value); + +UINT32 OsGetContainerCount(ContainerType type); +#endif +#endif /* _LOS_CONTAINER_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_credentials_pri.h b/src/kernel_liteos_a/kernel/base/include/los_credentials_pri.h new file mode 100644 index 00000000..bbdc49fb --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_credentials_pri.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_CREDENTIALS_PRI_H +#define _LOS_CREDENTIALS_PRI_H + +#include "los_atomic.h" +#include "los_list.h" + +#ifdef LOSCFG_USER_CONTAINER +struct Container; +struct UserContainer; +typedef struct ProcessCB LosProcessCB; + +typedef struct Credentials { + Atomic rc; + UINT32 uid; + UINT32 gid; + UINT32 euid; + UINT32 egid; + struct UserContainer *userContainer; +} Credentials; + +UINT32 OsCopyCredentials(unsigned long flags, LosProcessCB *child, LosProcessCB *parent); + +UINT32 OsInitRootUserCredentials(Credentials **credentials); + +UINT32 OsUnshareUserCredentials(UINTPTR flags, LosProcessCB *curr); + +UINT32 OsSetNsUserContainer(struct UserContainer *targetContainer, LosProcessCB *runProcess); + +VOID FreeCredential(Credentials *credentials); + +VOID OsUserContainerDestroy(LosProcessCB *curr); + +UINT32 OsGetUserContainerID(Credentials *credentials); + +Credentials *PrepareCredential(LosProcessCB *runProcessCB); + +INT32 CommitCredentials(Credentials *newCredentials); + +Credentials *CurrentCredentials(VOID); + +struct UserContainer *OsCurrentUserContainer(VOID); +#endif +#endif /* _LOS_CREDENTIALS_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_err_pri.h b/src/kernel_liteos_a/kernel/base/include/los_err_pri.h new file mode 100644 index 00000000..40a667ae --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_err_pri.h @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_ERR_PRI_H +#define _LOS_ERR_PRI_H + +#include "los_err.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_err + * Define the error magic word. + */ +#define OS_ERR_MAGIC_WORD 0xa1b2c3f8 + +/** + * @ingroup los_err + * @brief Error handling macro capable of returning error codes. + * + * @par Description: + * This API is used to call the error handling function by using an error code and return the same error code. + * @attention + *
            + *
          • None.
          • + *
          + * + * @param errNo [IN] Error code. + * + * @retval errNo + * @par Dependency: + *
          • los_err_pri.h: the header file that contains the API declaration.
          + * @see None. + */ +#define OS_RETURN_ERROR(errNo) do { \ + (VOID)LOS_ErrHandle("os_unspecific_file", OS_ERR_MAGIC_WORD, errNo, 0, NULL); \ + return errNo; \ +} while (0) + +/** + * @ingroup los_err + * @brief Error handling macro capable of returning error codes. + * + * @par Description: + * This API is used to call the error handling function by using an error code and the line number of + * the erroneous line, and return the same error code. + * @attention + *
            + *
          • None.
          • + *
          + * + * @param errLine [IN] Line number of the erroneous line. + * @param errNo [IN] Error code. + * + * @retval errNo + * @par Dependency: + *
          • los_err_pri.h: the header file that contains the API declaration.
          + * @see None. + */ +#define OS_RETURN_ERROR_P2(errLine, errNo) do { \ + (VOID)LOS_ErrHandle("os_unspecific_file", errLine, errNo, 0, NULL); \ + return errNo; \ +} while (0) + +/** + * @ingroup los_err + * @brief Macro for jumping to error handler. + * + * @par Description: + * This API is used to call the error handling function by using an error code. + * @attention + *
            + *
          • None.
          • + *
          + * + * @param errorNo [IN] Error code. + * + * @retval None. + * @par Dependency: + *
          • los_err_pri.h: the header file that contains the API declaration.
          + * @see None. + */ +#define OS_GOTO_ERR_HANDLER(errorNo) do { \ + errNo = errorNo; \ + errLine = OS_ERR_MAGIC_WORD; \ + goto ERR_HANDLER; \ +} while (0) + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_ERR_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_event_pri.h b/src/kernel_liteos_a/kernel/base/include/los_event_pri.h new file mode 100644 index 00000000..22d20c9e --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_event_pri.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_EVENT_PRI_H +#define _LOS_EVENT_PRI_H + +#include "los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#ifdef LOSCFG_COMPAT_POSIX +typedef struct { + volatile INT32 *realValue; + INT32 value; + UINT32 clearEvent; +} EventCond; + +extern UINT32 OsEventReadWithCond(const EventCond *cond, PEVENT_CB_S eventCB, + UINT32 eventMask, UINT32 mode, UINT32 timeout); +#endif + +extern VOID OsEventWriteUnsafe(PEVENT_CB_S eventCB, UINT32 events, BOOL once, UINT8 *exitFlag); +extern UINT32 OsEventReadOnce(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeout); +extern UINT32 OsEventWriteOnce(PEVENT_CB_S eventCB, UINT32 events); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_EVENT_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_futex_pri.h b/src/kernel_liteos_a/kernel/base/include/los_futex_pri.h new file mode 100644 index 00000000..7671115b --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_futex_pri.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_FUTEX_PRI_H +#define _LOS_FUTEX_PRI_H +#include "los_list.h" + +#define FUTEX_WAIT 0 +#define FUTEX_WAKE 1 +#define FUTEX_REQUEUE 3 +#define FUTEX_WAKE_OP 5 +#define FUTEX_LOCK_PI 6 +#define FUTEX_UNLOCK_PI 7 +#define FUTEX_TRYLOCK_PI 8 +#define FUTEX_WAIT_BITSET 9 + +#define FUTEX_PRIVATE 128 +#define FUTEX_MASK 0x3U + +typedef struct { + UINTPTR key; /* private:uvaddr shared:paddr */ + UINT32 index; /* hash bucket index */ + UINT32 pid; /* private:process id shared:OS_INVALID(-1) */ + LOS_DL_LIST pendList; /* point to pendList in TCB struct */ + LOS_DL_LIST queueList; /* thread list blocked by this lock */ + LOS_DL_LIST futexList; /* point to the next FutexNode */ +} FutexNode; + +extern UINT32 OsFutexInit(VOID); +extern VOID OsFutexNodeDeleteFromFutexHash(FutexNode *node, BOOL isDeleteHead, FutexNode **headNode, BOOL *queueFlags); +extern INT32 OsFutexWake(const UINT32 *userVaddr, UINT32 flags, INT32 wakeNumber); +extern INT32 OsFutexWait(const UINT32 *userVaddr, UINT32 flags, UINT32 val, UINT32 absTime); +extern INT32 OsFutexRequeue(const UINT32 *userVaddr, UINT32 flags, INT32 wakeNumber, + INT32 count, const UINT32 *newUserVaddr); +#endif diff --git a/src/kernel_liteos_a/kernel/base/include/los_info_pri.h b/src/kernel_liteos_a/kernel/base/include/los_info_pri.h new file mode 100644 index 00000000..78cde1d5 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_info_pri.h @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_INFO_PRI_H +#define _LOS_INFO_PRI_H + +#include "los_process_pri.h" +#include "los_sched_pri.h" + +#ifdef __cplusplus +#if __cplusplus + extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef struct TagTaskInfo { + UINT32 tid; + UINT32 pid; + UINT16 status; + UINT16 policy; + UINT16 priority; +#ifdef LOSCFG_KERNEL_SMP + UINT16 currCpu; + UINT16 cpuAffiMask; +#endif + UINT32 stackSize; + UINTPTR stackPoint; + UINTPTR topOfStack; + UINT32 waitFlag; + UINT32 waitID; + VOID *taskMux; + UINT32 waterLine; +#ifdef LOSCFG_KERNEL_CPUP + UINT32 cpup1sUsage; + UINT32 cpup10sUsage; + UINT32 cpupAllsUsage; +#endif + CHAR name[OS_TCB_NAME_LEN]; +} TaskInfo; + +typedef struct TagProcessInfo { + UINT32 pid; + UINT32 ppid; + UINT16 status; + UINT16 mode; + UINT32 pgroupID; + UINT32 userID; + UINT16 policy; + UINT32 basePrio; + UINT32 threadGroupID; + UINT32 threadNumber; +#ifdef LOSCFG_KERNEL_VM + UINT32 virtualMem; + UINT32 shareMem; + UINT32 physicalMem; +#endif +#ifdef LOSCFG_KERNEL_CPUP + UINT32 cpup1sUsage; + UINT32 cpup10sUsage; + UINT32 cpupAllsUsage; +#endif + CHAR name[OS_PCB_NAME_LEN]; +} ProcessInfo; + +typedef struct TagProcessThreadInfo { + ProcessInfo processInfo; + UINT32 threadCount; + TaskInfo taskInfo[LOSCFG_BASE_CORE_TSK_LIMIT]; +} ProcessThreadInfo; + +UINT32 OsGetAllProcessInfo(ProcessInfo *pcbArray); + +UINT32 OsGetProcessThreadInfo(UINT32 pid, ProcessThreadInfo *threadInfo); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_INFO_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_ipc_container_pri.h b/src/kernel_liteos_a/kernel/base/include/los_ipc_container_pri.h new file mode 100644 index 00000000..42ccbf3e --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_ipc_container_pri.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _LOS_IPC_CONTAINER_PRI_H +#define _LOS_IPC_CONTAINER_PRI_H + +#include "los_atomic.h" +#include "los_list.h" +#include "mqueue.h" +#include "fs/file.h" + +#ifdef LOSCFG_IPC_CONTAINER +struct shmIDSource; +struct Container; +typedef struct TagQueueCB LosQueueCB; +typedef struct OsMux LosMux; +typedef LosMux pthread_mutex_t; +typedef struct ProcessCB LosProcessCB; + +typedef struct IpcContainer { + Atomic rc; + LosQueueCB *allQueue; + LOS_DL_LIST freeQueueList; + fd_set queueFdSet; + struct mqarray queueTable[LOSCFG_BASE_IPC_QUEUE_LIMIT]; + pthread_mutex_t mqueueMutex; + struct mqpersonal *mqPrivBuf[MAX_MQ_FD]; + struct shminfo shmInfo; + LosMux sysvShmMux; + struct shmIDSource *shmSegs; + UINT32 shmUsedPageCount; + UINT32 containerID; +} IpcContainer; + +UINT32 OsInitRootIpcContainer(IpcContainer **ipcContainer); + +UINT32 OsCopyIpcContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent); + +UINT32 OsUnshareIpcContainer(UINTPTR flags, LosProcessCB *curr, struct Container *newContainer); + +UINT32 OsSetNsIpcContainer(UINT32 flags, struct Container *container, struct Container *newContainer); + +VOID OsIpcContainerDestroy(struct Container *container); + +UINT32 OsGetIpcContainerID(IpcContainer *ipcContainer); + +IpcContainer *OsGetCurrIpcContainer(VOID); + +UINT32 OsGetIpcContainerCount(VOID); + +#define IPC_ALL_QUEUE (OsGetCurrIpcContainer()->allQueue) + +#define FREE_QUEUE_LIST (OsGetCurrIpcContainer()->freeQueueList) + +#define IPC_QUEUE_FD_SET (OsGetCurrIpcContainer()->queueFdSet) + +#define IPC_QUEUE_TABLE (OsGetCurrIpcContainer()->queueTable) + +#define IPC_QUEUE_MUTEX (OsGetCurrIpcContainer()->mqueueMutex) + +#define IPC_QUEUE_MQ_PRIV_BUF (OsGetCurrIpcContainer()->mqPrivBuf) + +#define IPC_SHM_INFO (OsGetCurrIpcContainer()->shmInfo) + +#define IPC_SHM_SYS_VSHM_MUTEX (OsGetCurrIpcContainer()->sysvShmMux) + +#define IPC_SHM_SEGS (OsGetCurrIpcContainer()->shmSegs) + +#define IPC_SHM_USED_PAGE_COUNT (OsGetCurrIpcContainer()->shmUsedPageCount) + +#endif +#endif /* _LOS_IPC_CONTAINER_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_ipcdebug_pri.h b/src/kernel_liteos_a/kernel/base/include/los_ipcdebug_pri.h new file mode 100644 index 00000000..c5d1c1cb --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_ipcdebug_pri.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_IPCDEBUG_PRI_H +#define _LOS_IPCDEBUG_PRI_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef struct { + CHAR *buf; /**< Control block array total buffer */ + size_t ipcDebugCBSize; /**< Single control block size */ + size_t ipcDebugCBCnt; /**< Number of control blocks */ + UINT32 sortElemOff; /**< The offset of the member to be compared in the control block */ +} IpcSortParam; + +/* Compare the size of the last access time */ +typedef BOOL (*OsCompareFunc)(const IpcSortParam *sortParam, UINT32 left, UINT32 right); + +/* Get the address of the comparison member variable */ +#define SORT_ELEM_ADDR(sortParam, index) \ + ((sortParam)->buf + ((index) * (sortParam)->ipcDebugCBSize) + (sortParam)->sortElemOff) + +/* Sort this index array. */ +extern VOID OsArraySortByTime(UINT32 *sortArray, UINT32 start, UINT32 end, const IpcSortParam *sortParam, + OsCompareFunc compareFunc); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_IPCDEBUG_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_membox_pri.h b/src/kernel_liteos_a/kernel/base/include/los_membox_pri.h new file mode 100644 index 00000000..9a06ddea --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_membox_pri.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_MEMBOX_PRI_H +#define _LOS_MEMBOX_PRI_H + +#include "los_membox.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_MEMBOX_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_memory_pri.h b/src/kernel_liteos_a/kernel/base/include/los_memory_pri.h new file mode 100644 index 00000000..11632870 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_memory_pri.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_MEMORY_PRI_H +#define _LOS_MEMORY_PRI_H + +#include "los_memory.h" +#include "los_spinlock.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#ifdef LOSCFG_MEM_LEAKCHECK +extern VOID OsMemUsedNodeShow(VOID *pool); +#endif + +extern UINT32 OsMemSystemInit(UINTPTR memStart); +extern STATUS_T OsKHeapInit(size_t size); +extern VOID OsDumpMemByte(size_t length, UINTPTR addr); +extern VOID OsMemResetEndNode(VOID *pool, UINTPTR preAddr); +extern UINT32 OsMemLargeNodeFree(const VOID *ptr); +extern BOOL OsMemIsHeapNode(const VOID *ptr); +extern UINT32 OsShellCmdMemCheck(INT32 argc, const CHAR *argv[]); + +/* memory expand size at least 1/8 of pool size if we can */ +#define MEM_EXPAND_SIZE(poolSize) ((poolSize) >> 3) + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_MEMORY_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_memstat_pri.h b/src/kernel_liteos_a/kernel/base/include/los_memstat_pri.h new file mode 100644 index 00000000..a2a9f581 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_memstat_pri.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_MEMSTAT_PRI_H +#define _LOS_MEMSTAT_PRI_H + +#include "los_typedef.h" +#include "los_memory.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef struct { + UINT32 memUsed; +} TskMemUsedInfo; + +extern VOID OsTaskMemUsedInc(UINT32 usedSize, UINT32 taskID); +extern VOID OsTaskMemUsedDec(UINT32 usedSize, UINT32 taskID); +extern UINT32 OsTaskMemUsage(UINT32 taskID); +extern VOID OsTaskMemClear(UINT32 taskID); +#define OS_MEM_ENABLE_MEM_STATISTICS + +#ifdef LOS_MEM_SLAB +typedef struct { + UINT32 slabUsed; +} TskSlabUsedInfo; + +extern VOID OsTaskSlabUsedInc(UINT32 usedSize, UINT32 taskID); +extern VOID OsTaskSlabUsedDec(UINT32 usedSize, UINT32 taskID); +extern UINT32 OsTaskSlabUsage(UINT32 taskID); +#endif + +#ifdef OS_MEM_ENABLE_MEM_STATISTICS +#define OS_MEM_ADD_USED(usedSize, taskID) OsTaskMemUsedInc(usedSize, taskID) +#define OS_MEM_REDUCE_USED(usedSize, taskID) OsTaskMemUsedDec(usedSize, taskID) +#define OS_MEM_CLEAR(taskID) OsTaskMemClear(taskID) +#ifdef LOS_MEM_SLAB +#define OS_SLAB_ADD_USED(usedSize, taskID) OsTaskSlabUsedInc(usedSize, taskID) +#define OS_SLAB_REDUCE_USED(usedSize, taskID) OsTaskSlabUsedDec(usedSize, taskID) +#endif +#else +#define OS_MEM_ADD_USED(usedSize, taskID) +#define OS_MEM_REDUCE_USED(usedSize, taskID) +#define OS_MEM_CLEAR(taskID) +#ifdef LOS_MEM_SLAB +#define OS_SLAB_ADD_USED(usedSize, taskID) +#define OS_SLAB_REDUCE_USED(usedSize, taskID) +#endif +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_MEMSTAT_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_mnt_container_pri.h b/src/kernel_liteos_a/kernel/base/include/los_mnt_container_pri.h new file mode 100644 index 00000000..f604c69c --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_mnt_container_pri.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_MNT_CONTAINER_PRI_H +#define _LOS_MNT_CONTAINER_PRI_H + +#include "fs/mount.h" +#include "sched.h" +#include "los_atomic.h" +#include "vnode.h" +#include "stdlib.h" + +#ifdef LOSCFG_MNT_CONTAINER +typedef struct ProcessCB LosProcessCB; +struct Container; + +typedef struct MntContainer { + Atomic rc; + UINT32 containerID; + LIST_HEAD mountList; +} MntContainer; + +LIST_HEAD *GetContainerMntList(VOID); + +UINT32 OsInitRootMntContainer(MntContainer **mntContainer); + +UINT32 OsCopyMntContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent); + +UINT32 OsUnshareMntContainer(UINTPTR flags, LosProcessCB *curr, struct Container *newContainer); + +UINT32 OsSetNsMntContainer(UINT32 flags, struct Container *container, struct Container *newContainer); + +VOID OsMntContainerDestroy(struct Container *container); + +UINT32 OsGetMntContainerID(MntContainer *mntContainer); + +UINT32 OsGetMntContainerCount(VOID); +#endif +#endif diff --git a/src/kernel_liteos_a/kernel/base/include/los_mux_pri.h b/src/kernel_liteos_a/kernel/base/include/los_mux_pri.h new file mode 100644 index 00000000..8837114c --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_mux_pri.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_MUX_PRI_H +#define _LOS_MUX_PRI_H + +#include "los_mux.h" +#include "los_task_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define OS_MUX_MAGIC 0xEBCFDEA0 + +extern VOID OsMuxBitmapRestore(const LosMux *mutex, const LOS_DL_LIST *list, const LosTaskCB *runTask); +extern UINT32 OsMuxLockUnsafe(LosMux *mutex, UINT32 timeout); +extern UINT32 OsMuxTrylockUnsafe(LosMux *mutex, UINT32 timeout); +extern UINT32 OsMuxUnlockUnsafe(LosTaskCB *taskCB, LosMux *mutex, BOOL *needSched); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_MUX_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_net_container_pri.h b/src/kernel_liteos_a/kernel/base/include/los_net_container_pri.h new file mode 100644 index 00000000..3b1d30ed --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_net_container_pri.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_NET_CONTAINER_PRI_H +#define _LOS_NET_CONTAINER_PRI_H +#include +#include +#include +#include "los_atomic.h" + +#ifdef LOSCFG_NET_CONTAINER +typedef struct ProcessCB LosProcessCB; +struct Container; + +typedef struct NetContainer { + Atomic rc; + struct net_group *group; + UINT32 containerID; +} NetContainer; + +UINT32 OsInitRootNetContainer(NetContainer **ipcContainer); + +UINT32 OsCopyNetContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent); + +UINT32 OsUnshareNetContainer(UINTPTR flags, LosProcessCB *curr, struct Container *newContainer); + +UINT32 OsSetNsNetContainer(UINT32 flags, struct Container *container, struct Container *newContainer); + +VOID OsNetContainerDestroy(struct Container *container); + +UINT32 OsGetNetContainerID(NetContainer *ipcContainer); + +UINT32 OsGetNetContainerCount(VOID); +#endif +#endif /* _LOS_NET_CONTAINER_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_oom.h b/src/kernel_liteos_a/kernel/base/include/los_oom.h new file mode 100644 index 00000000..22abcb85 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_oom.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_OOM_H +#define _LOS_OOM_H +#include "los_typedef.h" + +#define OOM_TASK_PRIORITY 9 +#define OOM_TASK_STACK_SIZE 0x1000 + +#define OOM_CHECK_MIN 10 /* 0.1s */ +#define OOM_DEFAULT_CHECK_INTERVAL 100 /* 1s */ +#define OOM_CHECK_MAX 1000 /* 10s */ + +#define OOM_DEFAULT_LOW_MEM_THRESHOLD 0x80000 /* 512KByte */ +#define OOM_DEFAULT_LOW_MEM_THRESHOLD_MIN 0 /* 0, means always no memory */ +#define OOM_DEFAULT_LOW_MEM_THRESHOLD_MAX 0x100000 /* 1MByte */ + +#define OOM_DEFAULT_RECLAIM_MEM_THRESHOLD 0x500000 /* 5MByte */ + +typedef UINT32 (*OomFn)(UINTPTR param); + +typedef struct { + UINT32 lowMemThreshold; /* byte */ + UINT32 reclaimMemThreshold; /* byte */ + UINT32 checkInterval; /* microsecond */ + OomFn processVictimCB; /* process victim process cb function */ + OomFn scoreCB; /* out of memory, the process score function */ + UINT16 swtmrID; + BOOL enabled; /* oom is enabled or not */ +} OomCB; + +LITE_OS_SEC_TEXT_MINOR UINT32 OomTaskInit(VOID); +LITE_OS_SEC_TEXT_MINOR VOID OomInfodump(VOID); +LITE_OS_SEC_TEXT_MINOR VOID OomEnable(VOID); +LITE_OS_SEC_TEXT_MINOR VOID OomDisable(VOID); +LITE_OS_SEC_TEXT_MINOR VOID OomSetLowMemThreashold(UINT32 lowMemThreshold); +LITE_OS_SEC_TEXT_MINOR VOID OomSetReclaimMemThreashold(UINT32 reclaimMemThreshold); +LITE_OS_SEC_TEXT_MINOR VOID OomSetCheckInterval(UINT32 checkInterval); +LITE_OS_SEC_TEXT_MINOR BOOL OomCheckProcess(VOID); +#endif + diff --git a/src/kernel_liteos_a/kernel/base/include/los_percpu_pri.h b/src/kernel_liteos_a/kernel/base/include/los_percpu_pri.h new file mode 100644 index 00000000..8a824ffd --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_percpu_pri.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_PERCPU_PRI_H +#define _LOS_PERCPU_PRI_H + +#include "los_base.h" +#include "los_hw_cpu.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#ifdef LOSCFG_KERNEL_SMP +typedef enum { + CPU_RUNNING = 0, /* cpu is running */ + CPU_HALT, /* cpu in the halt */ + CPU_EXC /* cpu in the exc */ +} ExcFlag; + +typedef struct { + UINT32 excFlag; /* cpu halt or exc flag */ +#ifdef LOSCFG_KERNEL_SMP_CALL + LOS_DL_LIST funcLink; /* mp function call link */ +#endif +} Percpu; + +/* the kernel per-cpu structure */ +extern Percpu g_percpu[LOSCFG_KERNEL_CORE_NUM]; + +STATIC INLINE Percpu *OsPercpuGet(VOID) +{ + return &g_percpu[ArchCurrCpuid()]; +} + +STATIC INLINE Percpu *OsPercpuGetByID(UINT32 cpuid) +{ + return &g_percpu[cpuid]; +} + +STATIC INLINE UINT32 OsCpuStatusIsHalt(UINT16 cpuid) +{ + return (OsPercpuGetByID(cpuid)->excFlag == CPU_HALT); +} + +STATIC INLINE VOID OsCpuStatusSet(ExcFlag flag) +{ + OsPercpuGet()->excFlag = flag; +} + +VOID OsAllCpuStatusOutput(VOID); +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_PERCPU_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_pid_container_pri.h b/src/kernel_liteos_a/kernel/base/include/los_pid_container_pri.h new file mode 100644 index 00000000..cc047e68 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_pid_container_pri.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_PID_CONTAINER_PRI_H +#define _LOS_PID_CONTAINER_PRI_H +#include "los_config.h" +#include "los_atomic.h" +#include "los_list.h" + +typedef struct TagTaskCB LosTaskCB; +typedef struct ProcessCB LosProcessCB; +struct ProcessGroup; +struct Container; + +typedef struct { + UINT32 vid; /* Virtual ID */ + UINT32 vpid; /* Virtual parent ID */ + UINTPTR cb; /* Control block */ + LosProcessCB *realParent; /* process real parent */ + LOS_DL_LIST node; +} ProcessVid; + +#define PID_CONTAINER_LEVEL_LIMIT 3 + +typedef struct PidContainer { + Atomic rc; + Atomic level; + Atomic lock; + BOOL referenced; + UINT32 containerID; + struct PidContainer *parent; + struct ProcessGroup *rootPGroup; + LOS_DL_LIST tidFreeList; + ProcessVid tidArray[LOSCFG_BASE_CORE_TSK_LIMIT]; + LOS_DL_LIST pidFreeList; + ProcessVid pidArray[LOSCFG_BASE_CORE_PROCESS_LIMIT]; +} PidContainer; + +#define OS_PID_CONTAINER_FROM_PCB(processCB) ((processCB)->container->pidContainer) + +#define OS_ROOT_PGRP(processCB) (OS_PID_CONTAINER_FROM_PCB(processCB)->rootPGroup) + +#define OS_PROCESS_CONTAINER_CHECK(processCB, currProcessCB) \ + ((processCB)->container->pidContainer != (currProcessCB)->container->pidContainer) + +#define OS_PROCESS_PID_FOR_CONTAINER_CHECK(processCB) \ + (((processCB)->container->pidContainer != (processCB)->container->pidForChildContainer) && \ + ((processCB)->container->pidForChildContainer->referenced == FALSE)) + +UINT32 OsAllocSpecifiedVpidUnsafe(UINT32 vpid, PidContainer *pidContainer, + LosProcessCB *processCB, LosProcessCB *parent); + +VOID OsPidContainerDestroyAllProcess(LosProcessCB *processCB); + +VOID OsPidContainerDestroy(struct Container *container, LosProcessCB *processCB); + +UINT32 OsCopyPidContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent, UINT32 *processID); + +UINT32 OsUnsharePidContainer(UINTPTR flags, LosProcessCB *curr, struct Container *newContainer); + +UINT32 OsSetNsPidContainer(UINT32 flags, struct Container *container, struct Container *newContainer); + +UINT32 OsInitRootPidContainer(PidContainer **pidContainer); + +LosProcessCB *OsGetPCBFromVpid(UINT32 vpid); + +LosTaskCB *OsGetTCBFromVtid(UINT32 vtid); + +UINT32 OsGetVpidFromCurrContainer(const LosProcessCB *processCB); + +UINT32 OsGetVpidFromRootContainer(const LosProcessCB *processCB); + +UINT32 OsGetVtidFromCurrContainer(const LosTaskCB *taskCB); + +VOID OsFreeVtid(LosTaskCB *taskCB); + +UINT32 OsAllocVtid(LosTaskCB *taskCB, const LosProcessCB *processCB); + +UINT32 OsGetPidContainerID(PidContainer *pidContainer); + +BOOL OsPidContainerProcessParentIsRealParent(const LosProcessCB *processCB, const LosProcessCB *curr); + +UINT32 OsGetPidContainerCount(VOID); +#endif /* _LOS_PID_CONTAINER_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_printf_pri.h b/src/kernel_liteos_a/kernel/base/include/los_printf_pri.h new file mode 100644 index 00000000..f86aee95 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_printf_pri.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_PRINTF_PRI_H +#define _LOS_PRINTF_PRI_H + +#include "los_printf.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +extern VOID UartVprintf(const CHAR *fmt, va_list ap); +extern VOID PrintExcInfo(const CHAR *fmt, ...); + +extern const CHAR *OsLogLvGet(INT32 level); +extern VOID LkDprintf(const CHAR *fmt, va_list ap); +#ifdef LOSCFG_SHELL_DMESG +extern VOID DmesgPrintf(const CHAR *fmt, va_list ap); +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_PRINTF_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_process_pri.h b/src/kernel_liteos_a/kernel/base/include/los_process_pri.h new file mode 100644 index 00000000..e100438d --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_process_pri.h @@ -0,0 +1,563 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_PROCESS_PRI_H +#define _LOS_PROCESS_PRI_H + +#include "los_task_pri.h" +#include "sched.h" +#include "los_sem_pri.h" +#include "los_process.h" +#include "los_vm_map.h" +#ifdef LOSCFG_KERNEL_LITEIPC +#include "hm_liteipc.h" +#endif +#ifdef LOSCFG_SECURITY_CAPABILITY +#include "capability_type.h" +#endif +#ifdef LOSCFG_SECURITY_VID +#include "vid_type.h" +#endif +#include "sys/resource.h" +#ifdef LOSCFG_KERNEL_CONTAINER +#include "los_container_pri.h" +#endif +#ifdef LOSCFG_KERNEL_PLIMITS +#include "los_plimits.h" +#endif + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define OS_PCB_NAME_LEN OS_TCB_NAME_LEN + +#ifdef LOSCFG_SECURITY_CAPABILITY +#define OS_GROUPS_NUMBER_MAX 256 + +typedef struct { + UINT32 userID; + UINT32 effUserID; + UINT32 gid; + UINT32 effGid; + UINT32 groupNumber; + UINT32 groups[1]; +} User; +#endif + +typedef struct ProcessGroup { + UINTPTR pgroupLeader; /**< Process group leader is the the process that created the group */ + LOS_DL_LIST processList; /**< List of processes under this process group */ + LOS_DL_LIST exitProcessList; /**< List of closed processes (zombie processes) under this group */ + LOS_DL_LIST groupList; /**< Process group list */ +} ProcessGroup; + +typedef struct ProcessCB { + CHAR processName[OS_PCB_NAME_LEN]; /**< Process name */ + UINT32 processID; /**< Process ID */ + UINT16 processStatus; /**< [15:4] Process Status; [3:0] The number of threads currently + running in the process */ + UINT16 consoleID; /**< The console id of task belongs */ + UINT16 processMode; /**< Kernel Mode:0; User Mode:1; */ // 用戶模式1 内核模式0 + struct ProcessCB *parentProcess; /**< Parent process */ + UINT32 exitCode; /**< Process exit status */ + LOS_DL_LIST pendList; /**< Block list to which the process belongs */ + LOS_DL_LIST childrenList; /**< Children process list */ // 存放子進程,链表 + LOS_DL_LIST exitChildList; /**< Exit children process list */ // 要退出的子进程 + LOS_DL_LIST siblingList; /**< Linkage in parent's children list */ //兄弟进程链表 + ProcessGroup *pgroup; /**< Process group to which a process belongs */ //所属进程组 + LOS_DL_LIST subordinateGroupList; /**< Linkage in group list */ // 进程是组长时有哪些组员进程 + LosTaskCB *threadGroup; // 哪个线程组是进程的主线程ID + LOS_DL_LIST threadSiblingList; /**< List of threads under this process */ // 进程的线程任务列表 + volatile UINT32 threadNumber; /**< Number of threads alive under this process */ // 此进程下的活动线程数量 + UINT32 threadCount; /**< Total number of threads created under this process */ // 在此进程下创建的线程总数 + LOS_DL_LIST waitList; /**< The process holds the waitLits to support wait/waitpid */ // 进程持有等待链表以支持wait/waitpid +#ifdef LOSCFG_KERNEL_SMP + UINT32 timerCpu; /**< CPU core number of this task is delayed or pended */ // 统计各个线程被延迟或者阻塞的时间 +#endif + UINTPTR sigHandler; /**< Signal handler */ // 信号处理函数 + sigset_t sigShare; /**< Signal share bit */ // 信号共享位 +#ifdef LOSCFG_KERNEL_LITEIPC + ProcIpcInfo *ipcInfo; /**< Memory pool for lite ipc */ //用于进程间通讯的虚拟设备文件系统,设备装载点为 /dev/lite_ipc +#endif +#ifdef LOSCFG_KERNEL_VM + LosVmSpace *vmSpace; /**< VMM space for processes */ //虚拟空间,描述进程虚拟内存的数据结构,linux称为内存描述符 +#endif +#ifdef LOSCFG_FS_VFS + struct files_struct *files; /**< Files held by the process */ +#endif + timer_t timerID; /**< ITimer */ + +#ifdef LOSCFG_SECURITY_CAPABILITY + User *user; // 进程的拥有者 + UINT32 capability; // 安全能力范围 +#endif +#ifdef LOSCFG_SECURITY_VID + TimerIdMap timerIdMap; +#endif +#ifdef LOSCFG_DRIVERS_TZDRIVER + struct Vnode *execVnode; /**< Exec bin of the process */ +#endif + mode_t umask; +#ifdef LOSCFG_KERNEL_CPUP + OsCpupBase *processCpup; /**< Process cpu usage */ +#endif + struct rlimit *resourceLimit; +#ifdef LOSCFG_KERNEL_CONTAINER + Container *container; +#ifdef LOSCFG_USER_CONTAINER + struct Credentials *credentials; +#endif +#endif +#ifdef LOSCFG_PROC_PROCESS_DIR + struct ProcDirEntry *procDir; +#endif +#ifdef LOSCFG_KERNEL_PLIMITS + ProcLimiterSet *plimits; + LOS_DL_LIST plimitsList; /* plimit process list */ + PLimitsData limitStat; +#endif +} LosProcessCB; + +extern LosProcessCB *g_processCBArray; +extern UINT32 g_processMaxNum; + +#define OS_PCB_FROM_RPID(processID) (((LosProcessCB *)g_processCBArray) + (processID)) +#ifdef LOSCFG_PID_CONTAINER +#define OS_PCB_FROM_PID(processID) OsGetPCBFromVpid(processID) +#else +#define OS_PCB_FROM_PID(processID) OS_PCB_FROM_RPID(processID) +#endif +#define OS_PCB_FROM_TCB(taskCB) ((LosProcessCB *)((taskCB)->processCB)) +#define OS_PCB_FROM_TID(taskID) ((LosProcessCB *)(OS_TCB_FROM_TID(taskID)->processCB)) +#define OS_GET_PGROUP_LEADER(pgroup) ((LosProcessCB *)((pgroup)->pgroupLeader)) +#define OS_PCB_FROM_SIBLIST(ptr) LOS_DL_LIST_ENTRY((ptr), LosProcessCB, siblingList) +#define OS_PCB_FROM_PENDLIST(ptr) LOS_DL_LIST_ENTRY((ptr), LosProcessCB, pendList) + +/** + * @ingroup los_process + * Flag that indicates the process or process control block status. + * + * The process is created but does not participate in scheduling. + */ +#define OS_PROCESS_STATUS_INIT OS_TASK_STATUS_INIT + +/** + * @ingroup los_process + * Flag that indicates the process or process control block status. + * + * The process is ready. + */ +#define OS_PROCESS_STATUS_READY OS_TASK_STATUS_READY + +/** + * @ingroup los_process + * Flag that indicates the process or process control block status. + * + * The process is running. + */ +#define OS_PROCESS_STATUS_RUNNING OS_TASK_STATUS_RUNNING + +/** + * @ingroup los_process + * Flag that indicates the process or process control block status. + * + * The process is pending + */ +#define OS_PROCESS_STATUS_PENDING (OS_TASK_STATUS_PENDING | OS_TASK_STATUS_DELAY | OS_TASK_STATUS_SUSPENDED) + +/** + * @ingroup los_process + * Flag that indicates the process or process control block status. + * + * The process is run out but the resources occupied by the process are not recovered. + */ +#define OS_PROCESS_STATUS_ZOMBIES 0x0100U + +/** + * @ingroup los_process + * Flag that indicates the process or process control block status. + * + * The process status equal this is process control block unused, + * coexisting with OS_PROCESS_STATUS_ZOMBIES means that the control block is not recovered. + */ +#define OS_PROCESS_FLAG_UNUSED 0x0200U + +/** + * @ingroup los_process + * Flag that indicates the process or process control block status. + * + * The process has been call exit, it only works with multiple cores. + */ +#define OS_PROCESS_FLAG_EXIT 0x0400U + +/** + * @ingroup los_process + * Flag that indicates the process or process control block status. + * + * The process is the leader of the process group. + */ +#define OS_PROCESS_FLAG_GROUP_LEADER 0x0800U + +/** + * @ingroup los_process + * Flag that indicates the process or process control block status. + * + * The process has performed the exec operation. + */ +#define OS_PROCESS_FLAG_ALREADY_EXEC 0x1000U + +/** + * @ingroup los_process + * Flag that indicates the process or process control block status. + * + * The process is dying or already dying. + */ +#define OS_PROCESS_STATUS_INACTIVE (OS_PROCESS_FLAG_EXIT | OS_PROCESS_STATUS_ZOMBIES) + +/** + * @ingroup los_process + * Used to check if the process control block is unused. + */ +STATIC INLINE BOOL OsProcessIsUnused(const LosProcessCB *processCB) +{ + return ((processCB->processStatus & OS_PROCESS_FLAG_UNUSED) != 0); +} + +/** + * @ingroup los_process + * Used to check if the process is inactive. + */ +STATIC INLINE BOOL OsProcessIsInactive(const LosProcessCB *processCB) +{ + return ((processCB->processStatus & (OS_PROCESS_FLAG_UNUSED | OS_PROCESS_STATUS_INACTIVE)) != 0); +} + +/** + * @ingroup los_process + * Used to check if the process is dead. + */ +STATIC INLINE BOOL OsProcessIsDead(const LosProcessCB *processCB) +{ + return ((processCB->processStatus & OS_PROCESS_STATUS_ZOMBIES) != 0); +} + +STATIC INLINE BOOL OsProcessIsInit(const LosProcessCB *processCB) +{ + return ((processCB->processStatus & OS_PROCESS_STATUS_INIT) != 0); +} + +STATIC INLINE BOOL OsProcessIsPGroupLeader(const LosProcessCB *processCB) +{ + return ((processCB->processStatus & OS_PROCESS_FLAG_GROUP_LEADER) != 0); +} + +/** + * @ingroup los_process + * The highest priority of a kernel mode process. + */ +#define OS_PROCESS_PRIORITY_HIGHEST 0 + +/** + * @ingroup los_process + * The lowest priority of a kernel mode process + */ +#define OS_PROCESS_PRIORITY_LOWEST 31 + +/** + * @ingroup los_process + * The highest priority of a user mode process. + */ +#define OS_USER_PROCESS_PRIORITY_HIGHEST 10 + +/** + * @ingroup los_process + * The lowest priority of a user mode process + */ +#define OS_USER_PROCESS_PRIORITY_LOWEST OS_PROCESS_PRIORITY_LOWEST + +/** + * @ingroup los_process + * User state root process default priority + */ +#define OS_PROCESS_USERINIT_PRIORITY 28 + +/** + * @ingroup los_process + * ID of the kernel idle process + */ +#define OS_KERNEL_IDLE_PROCESS_ID 0U + +/** + * @ingroup los_process + * ID of the user root process + */ +#define OS_USER_ROOT_PROCESS_ID 1U + +/** + * @ingroup los_process + * ID of the kernel root process + */ +#define OS_KERNEL_ROOT_PROCESS_ID 2U + +#define OS_TASK_DEFAULT_STACK_SIZE 0x2000 +#define OS_USER_TASK_SYSCALL_STACK_SIZE 0x3000 +#define OS_USER_TASK_STACK_SIZE 0x100000 + +#define OS_KERNEL_MODE 0x0U +#define OS_USER_MODE 0x1U +STATIC INLINE BOOL OsProcessIsUserMode(const LosProcessCB *processCB) +{ + return (processCB->processMode == OS_USER_MODE); +} + +#define LOS_PRIO_PROCESS 0U +#define LOS_PRIO_PGRP 1U +#define LOS_PRIO_USER 2U + +#define OS_USER_PRIVILEGE_PROCESS_GROUP ((UINTPTR)OsGetUserInitProcess()) +#define OS_KERNEL_PROCESS_GROUP ((UINTPTR)OsGetKernelInitProcess()) + +/* + * Process exit code + * 31 15 8 7 0 + * | | exit code | core dump | signal | + */ +#define OS_PRO_EXIT_OK 0 + +STATIC INLINE VOID OsProcessExitCodeCoreDumpSet(LosProcessCB *processCB) +{ + processCB->exitCode |= 0x80U; +} + +STATIC INLINE VOID OsProcessExitCodeSignalSet(LosProcessCB *processCB, UINT32 signal) +{ + processCB->exitCode |= signal & 0x7FU; +} + +STATIC INLINE VOID OsProcessExitCodeSignalClear(LosProcessCB *processCB) +{ + processCB->exitCode &= (~0x7FU); +} + +STATIC INLINE BOOL OsProcessExitCodeSignalIsSet(LosProcessCB *processCB) +{ + return (processCB->exitCode) & 0x7FU; +} + +STATIC INLINE VOID OsProcessExitCodeSet(LosProcessCB *processCB, UINT32 code) +{ + processCB->exitCode |= ((code & 0x000000FFU) << 8U) & 0x0000FF00U; /* 8: Move 8 bits to the left, exitCode */ +} + +#define OS_PID_CHECK_INVALID(pid) (((UINT32)(pid)) >= g_processMaxNum) + +STATIC INLINE BOOL OsProcessIDUserCheckInvalid(UINT32 pid) +{ + return ((pid >= g_processMaxNum) || (pid == 0)); +} + +STATIC INLINE LosProcessCB *OsCurrProcessGet(VOID) +{ + UINT32 intSave; + + intSave = LOS_IntLock(); + LosProcessCB *runProcess = OS_PCB_FROM_TCB(OsCurrTaskGet()); + LOS_IntRestore(intSave); + return runProcess; +} + +#ifdef LOSCFG_SECURITY_CAPABILITY +STATIC INLINE User *OsCurrUserGet(VOID) +{ + User *user = NULL; + UINT32 intSave; + + intSave = LOS_IntLock(); + user = OsCurrProcessGet()->user; + LOS_IntRestore(intSave); + return user; +} + +STATIC INLINE UINT32 OsProcessUserIDGet(const LosTaskCB *taskCB) +{ + UINT32 intSave = LOS_IntLock(); + UINT32 uid = OS_INVALID; + + LosProcessCB *process = OS_PCB_FROM_TCB(taskCB); + if (process->user != NULL) { + uid = process->user->userID; + } + LOS_IntRestore(intSave); + return uid; +} +#endif + +STATIC INLINE BOOL OsIsProcessThreadGroup(const LosTaskCB *taskCB) +{ + return (OS_PCB_FROM_TCB(taskCB)->threadGroup == taskCB); +} + +STATIC INLINE UINT32 OsProcessThreadNumberGet(const LosTaskCB *taskCB) +{ + return OS_PCB_FROM_TCB(taskCB)->threadNumber; +} + +#ifdef LOSCFG_KERNEL_VM +STATIC INLINE LosVmSpace *OsProcessVmSpaceGet(const LosProcessCB *processCB) +{ + return processCB->vmSpace; +} +#endif + +#ifdef LOSCFG_DRIVERS_TZDRIVER +STATIC INLINE struct Vnode *OsProcessExecVnodeGet(const LosProcessCB *processCB) +{ + return processCB->execVnode; +} +#endif + +STATIC INLINE UINT32 OsGetPid(const LosProcessCB *processCB) +{ +#ifdef LOSCFG_PID_CONTAINER + if (OS_PROCESS_CONTAINER_CHECK(processCB, OsCurrProcessGet())) { + return OsGetVpidFromCurrContainer(processCB); + } +#endif + return processCB->processID; +} + +STATIC INLINE UINT32 OsGetRootPid(const LosProcessCB *processCB) +{ +#ifdef LOSCFG_PID_CONTAINER + return OsGetVpidFromRootContainer(processCB); +#else + return processCB->processID; +#endif +} + +/* + * return immediately if no child has exited. + */ +#define LOS_WAIT_WNOHANG (1 << 0U) + +/* + * return if a child has stopped (but not traced via ptrace(2)). + * Status for traced children which have stopped is provided even + * if this option is not specified. + */ +#define LOS_WAIT_WUNTRACED (1 << 1U) +#define LOS_WAIT_WSTOPPED (1 << 1U) + +/* + * Wait for exited processes + */ +#define LOS_WAIT_WEXITED (1 << 2U) + +/* + * return if a stopped child has been resumed by delivery of SIGCONT. + * (For Linux-only options, see below.) + */ +#define LOS_WAIT_WCONTINUED (1 << 3U) + +/* + * Leave the child in a waitable state; + * a later wait call can be used to again retrieve the child status information. + */ +#define LOS_WAIT_WNOWAIT (1 << 24U) + +/* + * Indicates that you are already in a wait state + */ +#define OS_PROCESS_WAIT (1 << 15U) + +/* + * Wait for any child process to finish + */ +#define OS_PROCESS_WAIT_ANY OS_TASK_WAIT_ANYPROCESS + +/* + * Wait for the child process specified by the pid to finish + */ +#define OS_PROCESS_WAIT_PRO OS_TASK_WAIT_PROCESS + +/* + * Waits for any child process in the specified process group to finish. + */ +#define OS_PROCESS_WAIT_GID OS_TASK_WAIT_GID + +#define OS_PROCESS_INFO_ALL 1 +#define OS_PROCESS_DEFAULT_UMASK 0022 + +extern UINTPTR __user_init_entry; +extern UINTPTR __user_init_bss; +extern UINTPTR __user_init_end; +extern UINTPTR __user_init_load_addr; +extern UINT32 OsProcessInit(VOID); +extern UINT32 OsSystemProcessCreate(VOID); +extern VOID OsProcessNaturalExit(LosProcessCB *processCB, UINT32 status); +extern VOID OsProcessCBRecycleToFree(VOID); +extern VOID OsProcessResourcesToFree(LosProcessCB *processCB); +extern UINT32 OsUserInitProcess(VOID); +extern INT32 OsClone(UINT32 flags, UINTPTR sp, UINT32 size); +extern VOID OsExecProcessVmSpaceRestore(LosVmSpace *oldSpace); +extern LosVmSpace *OsExecProcessVmSpaceReplace(LosVmSpace *newSpace, UINTPTR stackBase, INT32 randomDevFD); +extern UINT32 OsExecRecycleAndInit(LosProcessCB *processCB, const CHAR *name, LosVmSpace *oldAspace, UINTPTR oldFiles); +extern UINT32 OsExecStart(const TSK_ENTRY_FUNC entry, UINTPTR sp, UINTPTR mapBase, UINT32 mapSize); +extern UINT32 OsSetProcessName(LosProcessCB *processCB, const CHAR *name); +extern INT32 OsSetProcessScheduler(INT32 which, INT32 pid, UINT16 policy, const LosSchedParam *param); +extern INT32 OsGetProcessPriority(INT32 which, INT32 pid); +extern LosProcessCB *OsGetUserInitProcess(VOID); +extern LosProcessCB *OsGetIdleProcess(VOID); +extern INT32 OsSetProcessGroupID(UINT32 pid, UINT32 gid); +extern INT32 OsSetCurrProcessGroupID(UINT32 gid); +extern LosProcessCB *OsGetKernelInitProcess(VOID); +extern VOID OsSetSigHandler(UINTPTR addr); +extern UINTPTR OsGetSigHandler(VOID); +extern VOID OsWaitWakeTask(LosTaskCB *taskCB, UINT32 wakePID); +extern INT32 OsSendSignalToProcessGroup(INT32 pid, siginfo_t *info, INT32 permission); +extern INT32 OsSendSignalToAllProcess(siginfo_t *info, INT32 permission); +extern UINT32 OsProcessAddNewTask(UINTPTR processID, LosTaskCB *taskCB, SchedParam *param, UINT32 *numCount); +extern VOID OsDeleteTaskFromProcess(LosTaskCB *taskCB); +extern VOID OsProcessThreadGroupDestroy(VOID); +extern UINT32 OsGetProcessGroupCB(UINT32 pid, UINTPTR *ppgroupLeader); +extern LosProcessCB *OsGetDefaultProcessCB(VOID); +extern ProcessGroup *OsCreateProcessGroup(LosProcessCB *processCB); +INT32 OsSchedulerParamCheck(UINT16 policy, BOOL isThread, const LosSchedParam *param); +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/src/kernel_liteos_a/kernel/base/include/los_queue_debug_pri.h b/src/kernel_liteos_a/kernel/base/include/los_queue_debug_pri.h new file mode 100644 index 00000000..b7312135 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_queue_debug_pri.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_QUEUE_DEBUG_PRI_H +#define _LOS_QUEUE_DEBUG_PRI_H + +#include "los_config.h" +#include "los_task.h" +#include "los_queue_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/* queue debug initialization interface */ +extern UINT32 OsQueueDbgInit(VOID); +STATIC INLINE UINT32 OsQueueDbgInitHook(VOID) +{ +#ifdef LOSCFG_DEBUG_QUEUE + return OsQueueDbgInit(); +#else + return LOS_OK; +#endif +} +/* Update the last time the queue was executed */ +extern VOID OsQueueDbgTimeUpdate(UINT32 queueID); +STATIC INLINE VOID OsQueueDbgTimeUpdateHook(UINT32 queueID) +{ +#ifdef LOSCFG_DEBUG_QUEUE + OsQueueDbgTimeUpdate(queueID); +#endif +} +/* Update the task entry of the queue debug info when created or deleted */ +extern VOID OsQueueDbgUpdate(UINT32 queueID, TSK_ENTRY_FUNC entry); +STATIC INLINE VOID OsQueueDbgUpdateHook(UINT32 queueID, TSK_ENTRY_FUNC entry) +{ +#ifdef LOSCFG_DEBUG_QUEUE + OsQueueDbgUpdate(queueID, entry); +#endif +} +/* check the leak of queue */ +extern VOID OsQueueCheck(VOID); +STATIC INLINE VOID OsQueueCheckHook(VOID) +{ +#ifdef LOSCFG_DEBUG_QUEUE + OsQueueCheck(); +#endif +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_QUEUE_DEBUG_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_queue_pri.h b/src/kernel_liteos_a/kernel/base/include/los_queue_pri.h new file mode 100644 index 00000000..4efafe23 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_queue_pri.h @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_QUEUE_PRI_H +#define _LOS_QUEUE_PRI_H + +#include "los_queue.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef enum { + OS_QUEUE_READ = 0, + OS_QUEUE_WRITE = 1, + OS_QUEUE_N_RW = 2 +} QueueReadWrite; + +typedef enum { + OS_QUEUE_HEAD = 0, + OS_QUEUE_TAIL = 1 +} QueueHeadTail; + +#define OS_QUEUE_OPERATE_TYPE(ReadOrWrite, HeadOrTail) (((UINT32)(HeadOrTail) << 1) | (ReadOrWrite)) +#define OS_QUEUE_READ_WRITE_GET(type) ((type) & 0x01U) +#define OS_QUEUE_READ_HEAD (OS_QUEUE_READ | (OS_QUEUE_HEAD << 1)) +#define OS_QUEUE_READ_TAIL (OS_QUEUE_READ | (OS_QUEUE_TAIL << 1)) +#define OS_QUEUE_WRITE_HEAD (OS_QUEUE_WRITE | (OS_QUEUE_HEAD << 1)) +#define OS_QUEUE_WRITE_TAIL (OS_QUEUE_WRITE | (OS_QUEUE_TAIL << 1)) +#define OS_QUEUE_OPERATE_GET(type) ((type) & 0x03U) +#define OS_QUEUE_IS_READ(type) (OS_QUEUE_READ_WRITE_GET(type) == OS_QUEUE_READ) +#define OS_QUEUE_IS_WRITE(type) (OS_QUEUE_READ_WRITE_GET(type) == OS_QUEUE_WRITE) + +/** + * @ingroup los_queue + * Queue information block structure + */ +typedef struct TagQueueCB { + UINT8 *queueHandle; /**< Pointer to a queue handle */ + UINT16 queueState; /**< Queue state */ + UINT16 queueLen; /**< Queue length */ + UINT16 queueSize; /**< Node size */ + UINT32 queueID; /**< queueID */ + UINT16 queueHead; /**< Node head */ + UINT16 queueTail; /**< Node tail */ + UINT16 readWriteableCnt[OS_QUEUE_N_RW]; /**< Count of readable or writable resources, 0:readable, 1:writable */ + LOS_DL_LIST readWriteList[OS_QUEUE_N_RW]; /**< the linked list to be read or written, 0:readlist, 1:writelist */ + LOS_DL_LIST memList; /**< Pointer to the memory linked list */ +} LosQueueCB; + +/* queue state */ +/** + * @ingroup los_queue + * Message queue state: not in use. + */ +#define OS_QUEUE_UNUSED 0 + +/** + * @ingroup los_queue + * Message queue state: used. + */ +#define OS_QUEUE_INUSED 1 + +/** + * @ingroup los_queue + * Not in use. + */ +#define OS_QUEUE_WAIT_FOR_POOL 1 + +/** + * @ingroup los_queue + * Normal message queue. + */ +#define OS_QUEUE_NORMAL 0 + +/** + * @ingroup los_queue + * Queue information control block + */ +extern LosQueueCB *g_allQueue; +#ifndef LOSCFG_IPC_CONTAINER +#define IPC_ALL_QUEUE g_allQueue +#endif + +/** + * @ingroup los_queue + * COUNT | INDEX split bit + */ +#define QUEUE_SPLIT_BIT 16 +/** + * @ingroup los_queue + * Set the queue id + */ +#define SET_QUEUE_ID(count, queueID) (((count) << QUEUE_SPLIT_BIT) | (queueID)) + +/** + * @ingroup los_queue + * get the queue index + */ +#define GET_QUEUE_INDEX(queueID) ((queueID) & ((1U << QUEUE_SPLIT_BIT) - 1)) + +/** + * @ingroup los_queue + * get the queue count + */ +#define GET_QUEUE_COUNT(queueID) ((queueID) >> QUEUE_SPLIT_BIT) + +/** + * @ingroup los_queue + * Obtain a handle of the queue that has a specified ID. + * + */ +#define GET_QUEUE_HANDLE(queueID) (((LosQueueCB *)IPC_ALL_QUEUE) + GET_QUEUE_INDEX(queueID)) + +/** + * @ingroup los_queue + * Obtain the head node in a queue doubly linked list. + */ +#define GET_QUEUE_LIST(ptr) LOS_DL_LIST_ENTRY(ptr, LosQueueCB, readWriteList[OS_QUEUE_WRITE]) + +/** + * @ingroup los_queue + * @brief Alloc a stationary memory for a mail. + * + * @par Description: + * This API is used to alloc a stationary memory for a mail according to queueID. + * @attention + *
            + *
          • Do not alloc memory in unblocking modes such as interrupt.
          • + *
          • This API cannot be called before the Huawei LiteOS is initialized.
          • + *
          • The argument timeout is a relative time.
          • + *
          + * + * @param queueID [IN] Queue ID. The value range is [1,LOSCFG_BASE_IPC_QUEUE_LIMIT]. + * @param mailPool [IN] The memory poll that stores the mail. + * @param timeout [IN] Expiry time. The value range is [0,LOS_WAIT_FOREVER]. + * + * @retval #NULL The memory allocation is failed. + * @retval #pMem The address of alloc memory. + * @par Dependency: + *
          • los_queue_pri.h: the header file that contains the API declaration.
          + * @see OsQueueMailFree + */ +extern VOID *OsQueueMailAlloc(UINT32 queueID, VOID *mailPool, UINT32 timeout); + +/** + * @ingroup los_queue + * @brief Free a stationary memory of a mail. + * + * @par Description: + * This API is used to free a stationary memory for a mail according to queueID. + * @attention + *
            + *
          • This API cannot be called before the Huawei LiteOS is initialized.
          • + *
          + * + * @param queueID [IN] Queue ID. The value range is [1,LOSCFG_BASE_IPC_QUEUE_LIMIT]. + * @param mailPool [IN] The mail memory poll address. + * @param mailMem [IN] The mail memory block address. + * + * @retval #LOS_OK 0x00000000: The memory free successfully. + * @retval #OS_ERRNO_QUEUE_MAIL_HANDLE_INVALID 0x02000619: The handle of the queue passed-in when the memory + * for the queue is being freed is invalid. + * @retval #OS_ERRNO_QUEUE_MAIL_PTR_INVALID 0x0200061a: The pointer to the memory to be freed is null. + * @retval #OS_ERRNO_QUEUE_MAIL_FREE_ERROR 0x0200061b: The memory for the queue fails to be freed. + * @par Dependency: + *
          • los_queue_pri.h: the header file that contains the API declaration.
          + * @see OsQueueMailAlloc + */ +extern UINT32 OsQueueMailFree(UINT32 queueID, VOID *mailPool, VOID *mailMem); + +extern LosQueueCB *OsAllQueueCBInit(LOS_DL_LIST *freeQueueList); + +extern UINT32 OsQueueInit(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_QUEUE_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_rwlock_pri.h b/src/kernel_liteos_a/kernel/base/include/los_rwlock_pri.h new file mode 100644 index 00000000..4b0711f7 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_rwlock_pri.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_RWLOCK_PRI_H +#define _LOS_RWLOCK_PRI_H + +#include "los_rwlock.h" +#include "los_task_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define OS_RWLOCK_MAGIC 0xEFDCAU + +enum RwlockMode { + RWLOCK_NONE_MODE, + RWLOCK_READ_MODE, + RWLOCK_WRITE_MODE, + RWLOCK_READFIRST_MODE, + RWLOCK_WRITEFIRST_MODE +}; + +extern UINT32 OsRwlockRdUnsafe(LosRwlock *rwlock, UINT32 timeout); +extern UINT32 OsRwlockTryRdUnsafe(LosRwlock *rwlock, UINT32 timeout); +extern UINT32 OsRwlockWrUnsafe(LosRwlock *rwlock, UINT32 timeout); +extern UINT32 OsRwlockTryWrUnsafe(LosRwlock *rwlock, UINT32 timeout); +extern UINT32 OsRwlockUnlockUnsafe(LosRwlock *rwlock, BOOL *needSched); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_RWLOCK_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_sched_pri.h b/src/kernel_liteos_a/kernel/base/include/los_sched_pri.h new file mode 100644 index 00000000..1bbf0070 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_sched_pri.h @@ -0,0 +1,763 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_SCHED_PRI_H +#define _LOS_SCHED_PRI_H + +#include "los_sortlink_pri.h" +#include "los_sys_pri.h" +#include "los_hwi.h" +#include "hal_timer.h" +#ifdef LOSCFG_SCHED_DEBUG +#include "los_statistics_pri.h" +#endif +#include "los_stackinfo_pri.h" +#include "los_futex_pri.h" +#ifdef LOSCFG_KERNEL_PM +#include "los_pm_pri.h" +#endif +#include "los_signal.h" +#ifdef LOSCFG_KERNEL_CPUP +#include "los_cpup_pri.h" +#endif +#ifdef LOSCFG_KERNEL_LITEIPC +#include "hm_liteipc.h" +#endif +#include "los_mp.h" +#ifdef LOSCFG_KERNEL_CONTAINER +#include "los_container_pri.h" +#endif + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define OS_SCHED_MINI_PERIOD (OS_SYS_CLOCK / LOSCFG_BASE_CORE_TICK_PER_SECOND_MINI) +#define OS_TICK_RESPONSE_PRECISION (UINT32)((OS_SCHED_MINI_PERIOD * 75) / 100) +#define OS_SCHED_MAX_RESPONSE_TIME OS_SORT_LINK_INVALID_TIME +#define OS_SCHED_TICK_TO_CYCLE(ticks) ((UINT64)ticks * OS_CYCLE_PER_TICK) +#define AFFI_MASK_TO_CPUID(mask) ((UINT16)((mask) - 1)) + +#define OS_SCHED_EDF_MIN_RUNTIME 100 /* 100 us */ +#define OS_SCHED_EDF_MIN_DEADLINE 400 /* 400 us */ +#define OS_SCHED_EDF_MAX_DEADLINE 5000000 /* 5 s */ + +extern UINT32 g_taskScheduled; +#define OS_SCHEDULER_ACTIVE (g_taskScheduled & (1U << ArchCurrCpuid())) +#define OS_SCHEDULER_ALL_ACTIVE (g_taskScheduled == LOSCFG_KERNEL_CPU_MASK) + +typedef struct TagTaskCB LosTaskCB; +typedef BOOL (*SCHED_TL_FIND_FUNC)(UINTPTR, UINTPTR); + +STATIC INLINE UINT64 OsGetCurrSchedTimeCycle(VOID) +{ + return HalClockGetCycles(); +} + +typedef enum { + INT_NO_RESCH = 0x0, /* no needs to schedule */ + INT_PEND_RESCH = 0x1, /* pending schedule flag */ + INT_PEND_TICK = 0x2, /* pending tick */ +} SchedFlag; + +#define OS_PRIORITY_QUEUE_NUM 32 +typedef struct { + LOS_DL_LIST priQueList[OS_PRIORITY_QUEUE_NUM]; + UINT32 readyTasks[OS_PRIORITY_QUEUE_NUM]; + UINT32 queueBitmap; +} HPFQueue; + +typedef struct { + HPFQueue queueList[OS_PRIORITY_QUEUE_NUM]; + UINT32 queueBitmap; +} HPFRunqueue; + +typedef struct { + LOS_DL_LIST root; + LOS_DL_LIST waitList; + UINT64 period; +} EDFRunqueue; + +typedef struct { + SortLinkAttribute timeoutQueue; /* task timeout queue */ + HPFRunqueue *hpfRunqueue; + EDFRunqueue *edfRunqueue; + UINT64 responseTime; /* Response time for current CPU tick interrupts */ + UINT32 responseID; /* The response ID of the current CPU tick interrupt */ + LosTaskCB *idleTask; /* idle task id */ + UINT32 taskLockCnt; /* task lock flag */ + UINT32 schedFlag; /* pending scheduler flag */ +} SchedRunqueue; + +extern SchedRunqueue g_schedRunqueue[LOSCFG_KERNEL_CORE_NUM]; + +VOID OsSchedExpireTimeUpdate(VOID); + +STATIC INLINE SchedRunqueue *OsSchedRunqueue(VOID) +{ + return &g_schedRunqueue[ArchCurrCpuid()]; +} + +STATIC INLINE SchedRunqueue *OsSchedRunqueueByID(UINT16 id) +{ + return &g_schedRunqueue[id]; +} + +STATIC INLINE UINT32 OsSchedLockCountGet(VOID) +{ + return OsSchedRunqueue()->taskLockCnt; +} + +STATIC INLINE VOID OsSchedLockSet(UINT32 count) +{ + OsSchedRunqueue()->taskLockCnt = count; +} + +STATIC INLINE VOID OsSchedLock(VOID) +{ + OsSchedRunqueue()->taskLockCnt++; +} + +STATIC INLINE VOID OsSchedUnlock(VOID) +{ + OsSchedRunqueue()->taskLockCnt--; +} + +STATIC INLINE BOOL OsSchedUnlockResch(VOID) +{ + SchedRunqueue *rq = OsSchedRunqueue(); + if (rq->taskLockCnt > 0) { + rq->taskLockCnt--; + if ((rq->taskLockCnt == 0) && (rq->schedFlag & INT_PEND_RESCH) && OS_SCHEDULER_ACTIVE) { + return TRUE; + } + } + + return FALSE; +} + +STATIC INLINE BOOL OsSchedIsLock(VOID) +{ + return (OsSchedRunqueue()->taskLockCnt != 0); +} + +/* Check if preemptible with counter flag */ +STATIC INLINE BOOL OsPreemptable(VOID) +{ + SchedRunqueue *rq = OsSchedRunqueue(); + /* + * Unlike OsPreemptableInSched, the int may be not disabled when OsPreemptable + * is called, needs manually disable interrupt, to prevent current task from + * being migrated to another core, and get the wrong preemptable status. + */ + UINT32 intSave = LOS_IntLock(); + BOOL preemptible = (rq->taskLockCnt == 0); + if (!preemptible) { + /* Set schedule flag if preemption is disabled */ + rq->schedFlag |= INT_PEND_RESCH; + } + LOS_IntRestore(intSave); + return preemptible; +} + +STATIC INLINE BOOL OsPreemptableInSched(VOID) +{ + BOOL preemptible = FALSE; + SchedRunqueue *rq = OsSchedRunqueue(); + +#ifdef LOSCFG_KERNEL_SMP + /* + * For smp systems, schedule must hold the task spinlock, and this counter + * will increase by 1 in that case. + */ + preemptible = (rq->taskLockCnt == 1); + +#else + preemptible = (rq->taskLockCnt == 0); +#endif + if (!preemptible) { + /* Set schedule flag if preemption is disabled */ + rq->schedFlag |= INT_PEND_RESCH; + } + + return preemptible; +} + +STATIC INLINE LosTaskCB *OsSchedRunqueueIdleGet(VOID) +{ + return OsSchedRunqueue()->idleTask; +} + +STATIC INLINE VOID OsSchedRunqueuePendingSet(VOID) +{ + OsSchedRunqueue()->schedFlag |= INT_PEND_RESCH; +} + +#define LOS_SCHED_NORMAL 0U +#define LOS_SCHED_FIFO 1U +#define LOS_SCHED_RR 2U +#define LOS_SCHED_IDLE 3U +#define LOS_SCHED_DEADLINE 6U + +typedef struct { + UINT16 policy; + /* HPF scheduling parameters */ + UINT16 basePrio; + UINT16 priority; + UINT32 timeSlice; + + /* EDF scheduling parameters */ + INT32 runTimeUs; + UINT32 deadlineUs; + UINT32 periodUs; +} SchedParam; + +typedef struct { + UINT16 policy; /* This field must be present for all scheduling policies and must be the first in the structure */ + UINT16 basePrio; + UINT16 priority; + UINT32 initTimeSlice; /* cycle */ + UINT32 priBitmap; /* Bitmap for recording the change of task priority, the priority can not be greater than 31 */ +} SchedHPF; + +#define EDF_UNUSED 0 +#define EDF_NEXT_PERIOD 1 +#define EDF_WAIT_FOREVER 2 +#define EDF_INIT 3 +typedef struct { + UINT16 policy; + UINT16 cpuid; + UINT32 flags; + INT32 runTime; /* cycle */ + UINT64 deadline; /* deadline >> runTime */ + UINT64 period; /* period >= deadline */ + UINT64 finishTime; /* startTime + deadline */ +} SchedEDF; + +typedef struct { + union { + SchedEDF edf; + SchedHPF hpf; + }; +} SchedPolicy; + +typedef struct { + VOID (*dequeue)(SchedRunqueue *rq, LosTaskCB *taskCB); + VOID (*enqueue)(SchedRunqueue *rq, LosTaskCB *taskCB); + VOID (*start)(SchedRunqueue *rq, LosTaskCB *taskCB); + VOID (*exit)(LosTaskCB *taskCB); + UINT64 (*waitTimeGet)(LosTaskCB *taskCB); + UINT32 (*wait)(LosTaskCB *runTask, LOS_DL_LIST *list, UINT32 timeout); + VOID (*wake)(LosTaskCB *taskCB); + BOOL (*schedParamModify)(LosTaskCB *taskCB, const SchedParam *param); + UINT32 (*schedParamGet)(const LosTaskCB *taskCB, SchedParam *param); + UINT32 (*delay)(LosTaskCB *taskCB, UINT64 waitTime); + VOID (*yield)(LosTaskCB *taskCB); + UINT32 (*suspend)(LosTaskCB *taskCB); + UINT32 (*resume)(LosTaskCB *taskCB, BOOL *needSched); + UINT64 (*deadlineGet)(const LosTaskCB *taskCB); + VOID (*timeSliceUpdate)(SchedRunqueue *rq, LosTaskCB *taskCB, UINT64 currTime); + INT32 (*schedParamCompare)(const SchedPolicy *sp1, const SchedPolicy *sp2); + VOID (*priorityInheritance)(LosTaskCB *owner, const SchedParam *param); + VOID (*priorityRestore)(LosTaskCB *owner, const LOS_DL_LIST *list, const SchedParam *param); +} SchedOps; + +/** + * @ingroup los_sched + * Define a usable task priority. + * + * Highest task priority. + */ +#define OS_TASK_PRIORITY_HIGHEST 0 + +/** + * @ingroup los_sched + * Define a usable task priority. + * + * Lowest task priority. + */ +#define OS_TASK_PRIORITY_LOWEST 31 + +/** + * @ingroup los_sched + * Flag that indicates the task or task control block status. + * + * The task is init. + */ +#define OS_TASK_STATUS_INIT 0x0001U + +/** + * @ingroup los_sched + * Flag that indicates the task or task control block status. + * + * The task is ready. + */ +#define OS_TASK_STATUS_READY 0x0002U + +/** + * @ingroup los_sched + * Flag that indicates the task or task control block status. + * + * The task is running. + */ +#define OS_TASK_STATUS_RUNNING 0x0004U + +/** + * @ingroup los_sched + * Flag that indicates the task or task control block status. + * + * The task is suspended. + */ +#define OS_TASK_STATUS_SUSPENDED 0x0008U + +/** + * @ingroup los_sched + * Flag that indicates the task or task control block status. + * + * The task is blocked. + */ +#define OS_TASK_STATUS_PENDING 0x0010U + +/** + * @ingroup los_sched + * Flag that indicates the task or task control block status. + * + * The task is delayed. + */ +#define OS_TASK_STATUS_DELAY 0x0020U + +/** + * @ingroup los_sched + * Flag that indicates the task or task control block status. + * + * The time for waiting for an event to occur expires. + */ +#define OS_TASK_STATUS_TIMEOUT 0x0040U + +/** + * @ingroup los_sched + * Flag that indicates the task or task control block status. + * + * The task is pend for a period of time. + */ +#define OS_TASK_STATUS_PEND_TIME 0x0080U + +/** + * @ingroup los_sched + * Flag that indicates the task or task control block status. + * + * The task is exit. + */ +#define OS_TASK_STATUS_EXIT 0x0100U + +#define OS_TASK_STATUS_BLOCKED (OS_TASK_STATUS_INIT | OS_TASK_STATUS_PENDING | \ + OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND_TIME) + +/** + * @ingroup los_task + * Flag that indicates the task or task control block status. + * + * The delayed operation of this task is frozen. + */ +#define OS_TASK_STATUS_FROZEN 0x0200U + +#define OS_TCB_NAME_LEN 32 + +typedef struct TagTaskCB { + VOID *stackPointer; /**< Task stack pointer */ + UINT16 taskStatus; /**< Task status */ + + UINT64 startTime; /**< The start time of each phase of task */ + UINT64 waitTime; /**< Task delay time, tick number */ + UINT64 irqStartTime; /**< Interrupt start time */ + UINT32 irqUsedTime; /**< Interrupt consumption time */ + INT32 timeSlice; /**< Task remaining time slice */ + SortLinkList sortList; /**< Task sortlink node */ + const SchedOps *ops; + SchedPolicy sp; + + UINT32 stackSize; /**< Task stack size */ + UINTPTR topOfStack; /**< Task stack top */ + UINT32 taskID; /**< Task ID */ + TSK_ENTRY_FUNC taskEntry; /**< Task entrance function */ + VOID *joinRetval; /**< pthread adaption */ + VOID *taskMux; /**< Task-held mutex */ + VOID *taskEvent; /**< Task-held event */ + UINTPTR args[4]; /**< Parameter, of which the maximum number is 4 */ + CHAR taskName[OS_TCB_NAME_LEN]; /**< Task name */ + LOS_DL_LIST pendList; /**< Task pend node */ + LOS_DL_LIST threadList; /**< thread list */ + UINT32 eventMask; /**< Event mask */ + UINT32 eventMode; /**< Event mode */ +#ifdef LOSCFG_KERNEL_CPUP + OsCpupBase taskCpup; /**< task cpu usage */ +#endif + INT32 errorNo; /**< Error Num */ + UINT32 signal; /**< Task signal */ + sig_cb sig; +#ifdef LOSCFG_KERNEL_SMP + UINT16 currCpu; /**< CPU core number of this task is running on */ + UINT16 lastCpu; /**< CPU core number of this task is running on last time */ + UINT16 cpuAffiMask; /**< CPU affinity mask, support up to 16 cores */ +#ifdef LOSCFG_KERNEL_SMP_TASK_SYNC + UINT32 syncSignal; /**< Synchronization for signal handling */ +#endif +#ifdef LOSCFG_KERNEL_SMP_LOCKDEP + LockDep lockDep; +#endif +#endif +#ifdef LOSCFG_SCHED_DEBUG + SchedStat schedStat; /**< Schedule statistics */ +#endif +#ifdef LOSCFG_KERNEL_VM + UINTPTR archMmu; + UINTPTR userArea; + UINTPTR userMapBase; + UINT32 userMapSize; /**< user thread stack size ,real size : userMapSize + USER_STACK_MIN_SIZE */ + FutexNode futex; +#endif + UINTPTR processCB; /**< Which belong process */ + LOS_DL_LIST joinList; /**< join list */ + LOS_DL_LIST lockList; /**< Hold the lock list */ + UINTPTR waitID; /**< Wait for the PID or GID of the child process */ + UINT16 waitFlag; /**< The type of child process that is waiting, belonging to a group or parent, + a specific child process, or any child process */ +#ifdef LOSCFG_KERNEL_LITEIPC + IpcTaskInfo *ipcTaskInfo; +#endif +#ifdef LOSCFG_KERNEL_PERF + UINTPTR pc; + UINTPTR fp; +#endif +#ifdef LOSCFG_PID_CONTAINER + PidContainer *pidContainer; +#endif +#ifdef LOSCFG_IPC_CONTAINER + BOOL cloneIpc; +#endif +} LosTaskCB; + +STATIC INLINE BOOL OsTaskIsRunning(const LosTaskCB *taskCB) +{ + return ((taskCB->taskStatus & OS_TASK_STATUS_RUNNING) != 0); +} + +STATIC INLINE BOOL OsTaskIsReady(const LosTaskCB *taskCB) +{ + return ((taskCB->taskStatus & OS_TASK_STATUS_READY) != 0); +} + +STATIC INLINE BOOL OsTaskIsInactive(const LosTaskCB *taskCB) +{ + return ((taskCB->taskStatus & (OS_TASK_STATUS_INIT | OS_TASK_STATUS_EXIT)) != 0); +} + +STATIC INLINE BOOL OsTaskIsPending(const LosTaskCB *taskCB) +{ + return ((taskCB->taskStatus & OS_TASK_STATUS_PENDING) != 0); +} + +STATIC INLINE BOOL OsTaskIsSuspended(const LosTaskCB *taskCB) +{ + return ((taskCB->taskStatus & OS_TASK_STATUS_SUSPENDED) != 0); +} + +STATIC INLINE BOOL OsTaskIsBlocked(const LosTaskCB *taskCB) +{ + return ((taskCB->taskStatus & (OS_TASK_STATUS_SUSPENDED | OS_TASK_STATUS_PENDING | OS_TASK_STATUS_DELAY)) != 0); +} + +STATIC INLINE BOOL OsSchedPolicyIsEDF(const LosTaskCB *taskCB) +{ + const SchedEDF *sched = (const SchedEDF *)&taskCB->sp; + return (sched->policy == LOS_SCHED_DEADLINE); +} + +STATIC INLINE LosTaskCB *OsCurrTaskGet(VOID) +{ + return (LosTaskCB *)ArchCurrTaskGet(); +} + +STATIC INLINE VOID OsCurrTaskSet(LosTaskCB *task) +{ + ArchCurrTaskSet(task); +} + +STATIC INLINE VOID OsCurrUserTaskSet(UINTPTR thread) +{ + ArchCurrUserTaskSet(thread); +} + +STATIC INLINE VOID OsSchedIrqUsedTimeUpdate(VOID) +{ + LosTaskCB *runTask = OsCurrTaskGet(); + runTask->irqUsedTime = OsGetCurrSchedTimeCycle() - runTask->irqStartTime; +} + +STATIC INLINE VOID OsSchedIrqStartTime(VOID) +{ + LosTaskCB *runTask = OsCurrTaskGet(); + runTask->irqStartTime = OsGetCurrSchedTimeCycle(); +} + +#ifdef LOSCFG_KERNEL_SMP +STATIC INLINE VOID IdleRunqueueFind(UINT16 *idleCpuid) +{ + SchedRunqueue *idleRq = OsSchedRunqueueByID(0); + UINT32 nodeNum = OsGetSortLinkNodeNum(&idleRq->timeoutQueue); + UINT16 cpuid = 1; + do { + SchedRunqueue *rq = OsSchedRunqueueByID(cpuid); + UINT32 temp = OsGetSortLinkNodeNum(&rq->timeoutQueue); + if (nodeNum > temp) { + *idleCpuid = cpuid; + nodeNum = temp; + } + cpuid++; + } while (cpuid < LOSCFG_KERNEL_CORE_NUM); +} +#endif + +STATIC INLINE VOID OsSchedTimeoutQueueAdd(LosTaskCB *taskCB, UINT64 responseTime) +{ +#ifdef LOSCFG_KERNEL_SMP + UINT16 cpuid = AFFI_MASK_TO_CPUID(taskCB->cpuAffiMask); + if (cpuid >= LOSCFG_KERNEL_CORE_NUM) { + cpuid = 0; + IdleRunqueueFind(&cpuid); + } +#else + UINT16 cpuid = 0; +#endif + + SchedRunqueue *rq = OsSchedRunqueueByID(cpuid); + OsAdd2SortLink(&rq->timeoutQueue, &taskCB->sortList, responseTime, cpuid); +#ifdef LOSCFG_KERNEL_SMP + if ((cpuid != ArchCurrCpuid()) && (responseTime < rq->responseTime)) { + rq->schedFlag |= INT_PEND_TICK; + LOS_MpSchedule(CPUID_TO_AFFI_MASK(cpuid)); + } +#endif +} + +STATIC INLINE VOID OsSchedTimeoutQueueDelete(LosTaskCB *taskCB) +{ + SortLinkList *node = &taskCB->sortList; +#ifdef LOSCFG_KERNEL_SMP + SchedRunqueue *rq = OsSchedRunqueueByID(node->cpuid); +#else + SchedRunqueue *rq = OsSchedRunqueueByID(0); +#endif + UINT64 oldResponseTime = GET_SORTLIST_VALUE(node); + OsDeleteFromSortLink(&rq->timeoutQueue, node); + if (oldResponseTime <= rq->responseTime) { + rq->responseTime = OS_SCHED_MAX_RESPONSE_TIME; + } +} + +STATIC INLINE UINT32 OsSchedTimeoutQueueAdjust(LosTaskCB *taskCB, UINT64 responseTime) +{ + UINT32 ret; + SortLinkList *node = &taskCB->sortList; +#ifdef LOSCFG_KERNEL_SMP + UINT16 cpuid = node->cpuid; +#else + UINT16 cpuid = 0; +#endif + SchedRunqueue *rq = OsSchedRunqueueByID(cpuid); + ret = OsSortLinkAdjustNodeResponseTime(&rq->timeoutQueue, node, responseTime); + if (ret == LOS_OK) { + rq->schedFlag |= INT_PEND_TICK; + } + return ret; +} + +STATIC INLINE VOID SchedTaskFreeze(LosTaskCB *taskCB) +{ + UINT64 responseTime; + +#ifdef LOSCFG_KERNEL_PM + if (!OsIsPmMode()) { + return; + } +#endif + + if (!(taskCB->taskStatus & (OS_TASK_STATUS_PEND_TIME | OS_TASK_STATUS_DELAY))) { + return; + } + + responseTime = GET_SORTLIST_VALUE(&taskCB->sortList); + OsSchedTimeoutQueueDelete(taskCB); + SET_SORTLIST_VALUE(&taskCB->sortList, responseTime); + taskCB->taskStatus |= OS_TASK_STATUS_FROZEN; + return; +} + +STATIC INLINE VOID SchedTaskUnfreeze(LosTaskCB *taskCB) +{ + UINT64 currTime, responseTime; + + if (!(taskCB->taskStatus & OS_TASK_STATUS_FROZEN)) { + return; + } + + taskCB->taskStatus &= ~OS_TASK_STATUS_FROZEN; + currTime = OsGetCurrSchedTimeCycle(); + responseTime = GET_SORTLIST_VALUE(&taskCB->sortList); + if (responseTime > currTime) { + OsSchedTimeoutQueueAdd(taskCB, responseTime); + return; + } + + SET_SORTLIST_VALUE(&taskCB->sortList, OS_SORT_LINK_INVALID_TIME); + if (taskCB->taskStatus & OS_TASK_STATUS_PENDING) { + LOS_ListDelete(&taskCB->pendList); + } + taskCB->taskStatus &= ~OS_TASK_STATUS_BLOCKED; + return; +} + +/* + * Schedule flag, one bit represents one core. + * This flag is used to prevent kernel scheduling before OSStartToRun. + */ +#define OS_SCHEDULER_SET(cpuid) do { \ + g_taskScheduled |= (1U << (cpuid)); \ +} while (0); + +#define OS_SCHEDULER_CLR(cpuid) do { \ + g_taskScheduled &= ~(1U << (cpuid)); \ +} while (0); + +#ifdef LOSCFG_KERNEL_SCHED_PLIMIT +BOOL OsSchedLimitCheckTime(LosTaskCB *task); +#endif + +STATIC INLINE LosTaskCB *EDFRunqueueTopTaskGet(EDFRunqueue *rq) +{ + LOS_DL_LIST *root = &rq->root; + if (LOS_ListEmpty(root)) { + return NULL; + } + + return LOS_DL_LIST_ENTRY(LOS_DL_LIST_FIRST(root), LosTaskCB, pendList); +} + +STATIC INLINE LosTaskCB *HPFRunqueueTopTaskGet(HPFRunqueue *rq) +{ + LosTaskCB *newTask = NULL; + UINT32 baseBitmap = rq->queueBitmap; +#ifdef LOSCFG_KERNEL_SMP + UINT32 cpuid = ArchCurrCpuid(); +#endif + + while (baseBitmap) { + UINT32 basePrio = CLZ(baseBitmap); + HPFQueue *queueList = &rq->queueList[basePrio]; + UINT32 bitmap = queueList->queueBitmap; + while (bitmap) { + UINT32 priority = CLZ(bitmap); + LOS_DL_LIST_FOR_EACH_ENTRY(newTask, &queueList->priQueList[priority], LosTaskCB, pendList) { +#ifdef LOSCFG_KERNEL_SCHED_PLIMIT + if (!OsSchedLimitCheckTime(newTask)) { + bitmap &= ~(1U << (OS_PRIORITY_QUEUE_NUM - priority - 1)); + continue; + } +#endif +#ifdef LOSCFG_KERNEL_SMP + if (newTask->cpuAffiMask & (1U << cpuid)) { +#endif + return newTask; +#ifdef LOSCFG_KERNEL_SMP + } +#endif + } + bitmap &= ~(1U << (OS_PRIORITY_QUEUE_NUM - priority - 1)); + } + baseBitmap &= ~(1U << (OS_PRIORITY_QUEUE_NUM - basePrio - 1)); + } + + return NULL; +} + +VOID EDFProcessDefaultSchedParamGet(SchedParam *param); +VOID EDFSchedPolicyInit(SchedRunqueue *rq); +UINT32 EDFTaskSchedParamInit(LosTaskCB *taskCB, UINT16 policy, + const SchedParam *parentParam, + const LosSchedParam *param); + +VOID HPFSchedPolicyInit(SchedRunqueue *rq); +VOID HPFTaskSchedParamInit(LosTaskCB *taskCB, UINT16 policy, + const SchedParam *parentParam, + const LosSchedParam *param); +VOID HPFProcessDefaultSchedParamGet(SchedParam *param); + +VOID IdleTaskSchedParamInit(LosTaskCB *taskCB); + +INT32 OsSchedParamCompare(const LosTaskCB *task1, const LosTaskCB *task2); +VOID OsSchedPriorityInheritance(LosTaskCB *owner, const SchedParam *param); +UINT32 OsSchedParamInit(LosTaskCB *taskCB, UINT16 policy, + const SchedParam *parentParam, + const LosSchedParam *param); +VOID OsSchedProcessDefaultSchedParamGet(UINT16 policy, SchedParam *param); + +VOID OsSchedResponseTimeReset(UINT64 responseTime); +VOID OsSchedToUserReleaseLock(VOID); +VOID OsSchedTick(VOID); +UINT32 OsSchedInit(VOID); +VOID OsSchedStart(VOID); + +VOID OsSchedRunqueueIdleInit(LosTaskCB *idleTask); +VOID OsSchedRunqueueInit(VOID); + +/* + * This function simply picks the next task and switches to it. + * Current task needs to already be in the right state or the right + * queues it needs to be in. + */ +VOID OsSchedResched(VOID); +VOID OsSchedIrqEndCheckNeedSched(VOID); + +/* +* This function inserts the runTask to the lock pending list based on the +* task priority. +*/ +LOS_DL_LIST *OsSchedLockPendFindPos(const LosTaskCB *runTask, LOS_DL_LIST *lockList); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_SCHED_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_sem_debug_pri.h b/src/kernel_liteos_a/kernel/base/include/los_sem_debug_pri.h new file mode 100644 index 00000000..f58d4bca --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_sem_debug_pri.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_SEM_DEBUG_PRI_H +#define _LOS_SEM_DEBUG_PRI_H + +#include "los_config.h" +#include "los_sem_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/* semaphore debug initialization interface */ +extern UINT32 OsSemDbgInit(VOID); +STATIC INLINE UINT32 OsSemDbgInitHook(VOID) +{ +#ifdef LOSCFG_DEBUG_SEMAPHORE + return OsSemDbgInit(); +#else + return LOS_OK; +#endif +} +/* Update the last time the semaphore was executed */ +extern VOID OsSemDbgTimeUpdate(UINT32 semID); +STATIC INLINE VOID OsSemDbgTimeUpdateHook(UINT32 semID) +{ +#ifdef LOSCFG_DEBUG_SEMAPHORE + OsSemDbgTimeUpdate(semID); +#endif + return; +} +/* Update the SEM_DEBUG_CB of the semaphore when created or deleted */ +extern VOID OsSemDbgUpdate(UINT32 semID, TSK_ENTRY_FUNC creator, UINT16 count); +STATIC INLINE VOID OsSemDbgUpdateHook(UINT32 semID, TSK_ENTRY_FUNC creator, UINT16 count) +{ +#ifdef LOSCFG_DEBUG_SEMAPHORE + OsSemDbgUpdate(semID, creator, count); +#endif + return; +} +/* get the full data of SEM_DFX_CB */ +extern UINT32 OsSemInfoGetFullData(VOID); +STATIC INLINE VOID OsSemInfoGetFullDataHook(VOID) +{ +#ifdef LOSCFG_DEBUG_SEMAPHORE + (VOID)OsSemInfoGetFullData(); +#endif + return; +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_SEM_DEBUG_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_sem_pri.h b/src/kernel_liteos_a/kernel/base/include/los_sem_pri.h new file mode 100644 index 00000000..8476a1bc --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_sem_pri.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_SEM_PRI_H +#define _LOS_SEM_PRI_H + +#include "los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_sem + * Semaphore control structure. + */ +typedef struct { + UINT8 semStat; /**< Semaphore state */ + UINT16 semCount; /**< Number of available semaphores */ + UINT16 maxSemCount; /**< Max number of available semaphores */ + UINT32 semID; /**< Semaphore control structure ID */ + LOS_DL_LIST semList; /**< Queue of tasks that are waiting on a semaphore */ +} LosSemCB; + +/** + * @ingroup los_sem + * The semaphore is not in use. + * + */ +#define OS_SEM_UNUSED 0 +/** + * @ingroup los_sem + * The semaphore is used. + * + */ +#define OS_SEM_USED 1 +/** + * @ingroup los_sem + * Obtain the head node in a semaphore doubly linked list. + * + */ +#define GET_SEM_LIST(ptr) LOS_DL_LIST_ENTRY(ptr, LosSemCB, semList) +extern LosSemCB *g_allSem; +/** + * @ingroup los_sem + * COUNT | INDEX split bit + */ +#define SEM_SPLIT_BIT 16 +/** + * @ingroup los_sem + * Set the semaphore id + */ +#define SET_SEM_ID(count, semID) (((count) << SEM_SPLIT_BIT) | (semID)) + +/** + * @ingroup los_sem + * get the semaphore index + */ +#define GET_SEM_INDEX(semID) ((semID) & ((1U << SEM_SPLIT_BIT) - 1)) + +/** + * @ingroup los_sem + * get the semaphore count + */ +#define GET_SEM_COUNT(semID) ((semID) >> SEM_SPLIT_BIT) + +/** + * @ingroup los_sem + * Obtain a semaphore ID. + * + */ +#define GET_SEM(semID) (((LosSemCB *)g_allSem) + GET_SEM_INDEX(semID)) + +/** + * @ingroup los_sem + * Maximum value of task information. + * + */ +#define OS_MAX_PENDTASK_INFO 4 + +extern UINT32 OsSemInit(VOID); +extern UINT32 OsSemPostUnsafe(UINT32 semHandle, BOOL *needSched); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_SEM_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_signal.h b/src/kernel_liteos_a/kernel/base/include/los_signal.h new file mode 100644 index 00000000..ce39c484 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_signal.h @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_SIGNAL_H +#define _LOS_SIGNAL_H + +#include +#include +#include +#include +#include "los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define LOS_BIT_SET(val, bit) ((val) = (val) | (1ULL << (UINT32)(bit))) +#define LOS_BIT_CLR(val, bit) ((val) = (val) & ~(1ULL << (UINT32)(bit))) +#define LOS_IS_BIT_SET(val, bit) (bool)((((val) >> (UINT32)(bit)) & 1ULL)) + +#define SIG_STOP_VISIT 1 + +#define OS_KERNEL_KILL_PERMISSION 0U +#define OS_USER_KILL_PERMISSION 3U + +#define OS_RETURN_IF(expr, errcode) \ + if ((expr)) { \ + return errcode; \ + } + +#define OS_RETURN_IF_VOID(expr) \ + if ((expr)) { \ + return; \ + } +#define OS_GOTO_EXIT_IF(expr, errcode) \ + if (expr) { \ + ret = errcode; \ + goto EXIT; \ + } +#define OS_GOTO_EXIT_IF_ONLY(expr) \ + if (expr) { \ + goto EXIT; \ + } + +#define OS_RETURN_VOID_IF_NULL(pPara) \ + if (NULL == (pPara)) { \ + return; \ + } +#define OS_RETURN_IF_NULL(pPara) \ + if (NULL == (pPara)) { \ + return (-EINVAL); \ + } + +#define OS_GOTO_EXIT_IF_NULL(pPara) \ + if (NULL == (pPara)) { \ + ret = -EINVAL; \ + goto EXIT; \ + } + +typedef void (*sa_sighandler_t)(int); +typedef void (*sa_siginfoaction_t)(int, siginfo_t *, void *); + +#define SIGNO2SET(s) ((sigset_t)1ULL << (s)) +#define NULL_SIGNAL_SET ((sigset_t)0ULL) +#define FULL_SIGNAL_SET ((sigset_t)~0ULL) + +static inline int GOOD_SIGNO(unsigned int sig) +{ + return (sig < _NSIG) ? 1 : 0; +} + +#define MAX_SIG_ARRAY_IN_MUSL 128 + +typedef struct { + unsigned long sig[MAX_SIG_ARRAY_IN_MUSL / sizeof(unsigned long)]; +} sigset_t_l; + +typedef struct sigaction sigaction_t; + +struct sigactq { + struct sigactq *flink; /* Forward link */ + sigaction_t act; /* Sigaction data */ + uint8_t signo; /* Signal associated with action */ +}; +typedef struct sigactq sigactq_t; + +struct sq_entry_s { + struct sq_entry_s *flink; +}; +typedef struct sq_entry_s sq_entry_t; + +struct sigpendq { + struct sigpendq *flink; /* Forward link */ + siginfo_t info; /* Signal information */ + uint8_t type; /* (Used to manage allocations) */ +}; +typedef struct sigpendq sigpendq_t; + +struct sq_queue_s { + sq_entry_t *head; + sq_entry_t *tail; +}; +typedef struct sq_queue_s sq_queue_t; + +typedef struct SigInfoListNode { + struct SigInfoListNode *next; + siginfo_t info; +} SigInfoListNode; + +typedef struct { + sigset_t sigFlag; + sigset_t sigPendFlag; + sigset_t sigprocmask; /* Signals that are blocked */ + sq_queue_t sigactionq; + LOS_DL_LIST waitList; + sigset_t sigwaitmask; /* Waiting for pending signals */ + siginfo_t sigunbinfo; /* Signal info when task unblocked */ + SigInfoListNode *tmpInfoListHead; /* Signal info List */ + unsigned int sigIntLock; + void *sigContext; + unsigned int count; +} sig_cb; + +typedef struct ProcessCB LosProcessCB; + +#define SIGEV_THREAD_ID 4 + +int sys_sigqueue(pid_t, int, const union sigval); +int sys_sigpending(sigset_t *); +int sys_rt_sigtimedwait(const sigset_t *mask, siginfo_t *si, const struct timespec *ts, size_t sigsetsize); +int sys_sigsuspend(const sigset_t *); +int OsKillLock(pid_t pid, int sig); +int OsSigAction(int sig, const sigaction_t *act, sigaction_t *oact); +int OsSigprocMask(int how, const sigset_t_l *set, sigset_t_l *oldset); +int OsPthreadKill(UINT32 tid, int signo); +int OsSigEmptySet(sigset_t *); +int OsSigAddSet(sigset_t *, int); +int OsSigIsMember(const sigset_t *, int); +int OsKill(pid_t pid, int sig, int permission); +int OsSendSigToProcess(LosProcessCB *spcb, int sig, int permission); +int OsDispatch(pid_t pid, siginfo_t *info, int permission); +int OsSigTimedWait(sigset_t *set, siginfo_t *info, unsigned int timeout); +int OsPause(void); +int OsSigPending(sigset_t *set); +int OsSigSuspend(const sigset_t *set); +VOID OsSigIntLock(VOID); +VOID OsSigIntUnlock(VOID); +INT32 OsTaskKillUnsafe(UINT32 taskID, INT32 signo); +VOID OsClearSigInfoTmpList(sig_cb *sigcb); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_SIGNAL_H */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_sortlink_pri.h b/src/kernel_liteos_a/kernel/base/include/los_sortlink_pri.h new file mode 100644 index 00000000..788947d3 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_sortlink_pri.h @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_SORTLINK_PRI_H +#define _LOS_SORTLINK_PRI_H + +#include "los_typedef.h" +#include "los_list.h" +#include "los_spinlock.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef struct { + LOS_DL_LIST sortLinkNode; + UINT64 responseTime; +#ifdef LOSCFG_KERNEL_SMP + UINT32 cpuid; +#endif +} SortLinkList; + +typedef struct { + LOS_DL_LIST sortLink; + UINT32 nodeNum; + SPIN_LOCK_S spinLock; /* swtmr sort link spin lock */ +} SortLinkAttribute; + +#define OS_SORT_LINK_INVALID_TIME ((UINT64)-1) +#define SET_SORTLIST_VALUE(sortList, value) (((SortLinkList *)(sortList))->responseTime = (value)) +#define GET_SORTLIST_VALUE(sortList) (((SortLinkList *)(sortList))->responseTime) + +STATIC INLINE VOID OsDeleteNodeSortLink(SortLinkAttribute *sortLinkHeader, SortLinkList *sortList) +{ + LOS_ListDelete(&sortList->sortLinkNode); + SET_SORTLIST_VALUE(sortList, OS_SORT_LINK_INVALID_TIME); + sortLinkHeader->nodeNum--; +} + +STATIC INLINE UINT64 OsGetSortLinkNextExpireTime(SortLinkAttribute *sortHeader, UINT64 startTime, UINT32 tickPrecision) +{ + LOS_DL_LIST *head = &sortHeader->sortLink; + LOS_DL_LIST *list = head->pstNext; + + LOS_SpinLock(&sortHeader->spinLock); + if (LOS_ListEmpty(head)) { + LOS_SpinUnlock(&sortHeader->spinLock); + return OS_SORT_LINK_INVALID_TIME - tickPrecision; + } + + SortLinkList *listSorted = LOS_DL_LIST_ENTRY(list, SortLinkList, sortLinkNode); + if (listSorted->responseTime <= (startTime + tickPrecision)) { + LOS_SpinUnlock(&sortHeader->spinLock); + return startTime + tickPrecision; + } + + LOS_SpinUnlock(&sortHeader->spinLock); + return listSorted->responseTime; +} + +STATIC INLINE UINT32 OsGetSortLinkNodeNum(const SortLinkAttribute *head) +{ + return head->nodeNum; +} + +STATIC INLINE UINT16 OsGetSortLinkNodeCpuid(const SortLinkList *node) +{ +#ifdef LOSCFG_KERNEL_SMP + return node->cpuid; +#else + return 0; +#endif +} + +VOID OsSortLinkInit(SortLinkAttribute *sortLinkHeader); +VOID OsAdd2SortLink(SortLinkAttribute *head, SortLinkList *node, UINT64 responseTime, UINT16 idleCpu); +VOID OsDeleteFromSortLink(SortLinkAttribute *head, SortLinkList *node); +UINT64 OsSortLinkGetTargetExpireTime(UINT64 currTime, const SortLinkList *targetSortList); +UINT64 OsSortLinkGetNextExpireTime(UINT64 currTime, const SortLinkAttribute *sortLinkHeader); +UINT32 OsSortLinkAdjustNodeResponseTime(SortLinkAttribute *head, SortLinkList *node, UINT64 responseTime); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_SORTLINK_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_stackinfo_pri.h b/src/kernel_liteos_a/kernel/base/include/los_stackinfo_pri.h new file mode 100644 index 00000000..74eb7ee9 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_stackinfo_pri.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_STACK_INFO_PRI_H +#define _LOS_STACK_INFO_PRI_H + +#include "los_typedef.h" +#include "arch_config.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef struct { + VOID *stackTop; + UINT32 stackSize; + CHAR *stackName; +} StackInfo; + +#define OS_INVALID_WATERLINE 0xFFFFFFFF +#define OS_STACK_MAGIC_CHECK(topstack) (*(UINTPTR *)(topstack) == OS_STACK_MAGIC_WORD) /* 1:magic valid 0:invalid */ + +extern VOID OsExcStackInfo(VOID); +extern VOID OsExcStackInfoReg(const StackInfo *stackInfo, UINT32 stackNum); +extern VOID OsStackInit(VOID *stacktop, UINT32 stacksize); + +/** + * @ingroup los_task + * @brief Get stack waterline. + * + * @par Description: + * This API is used to get stack waterline size and check stack whether overflow. + * + * @attention None + * + * @param stackBottom [IN] Type #const UINTPTR * pointer to stack bottom. + * @param stackTop [IN] Type #const UINTPTR * pointer to stack top. + * @param peakUsed [OUT] Type #UINT32 * stack waterline. + * + * @retval #LOS_NOK stack overflow + * @retval #LOS_OK stack is normal, not overflow + * @par Dependency: + *
          • los_stackinfo_pri.h: the header file that contains the API declaration.
          + * @see + */ +extern UINT32 OsStackWaterLineGet(const UINTPTR *stackBottom, const UINTPTR *stackTop, UINT32 *peakUsed); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_STACK_INFO_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_statistics_pri.h b/src/kernel_liteos_a/kernel/base/include/los_statistics_pri.h new file mode 100644 index 00000000..c1ec0d68 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_statistics_pri.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __LOS_STAT_PRI_H +#define __LOS_STAT_PRI_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef struct { + UINT64 allRuntime; + UINT64 runTime; + UINT64 switchCount; /* sched switch count */ + UINT64 timeSliceRealTime; /* The actual usage time of each time slice */ + UINT64 timeSliceTime; + UINT64 timeSliceCount; /* The number of time slices allocated */ + UINT64 pendTime; + UINT64 pendCount; + UINT64 waitSchedTime; /* task status is ready to running times */ + UINT64 waitSchedCount; +} SchedStat; + +#ifdef LOSCFG_SCHED_DEBUG +#ifdef LOSCFG_SCHED_TICK_DEBUG +VOID OsSchedDebugRecordData(VOID); +UINT32 OsShellShowTickResponse(VOID); +UINT32 OsSchedDebugInit(VOID); +#endif +UINT32 OsShellShowSchedStatistics(VOID); +UINT32 OsShellShowEdfSchedStatistics(VOID); +VOID EDFDebugRecord(UINTPTR *taskCB, UINT64 oldFinish); +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* __LOS_STAT_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_swtmr_pri.h b/src/kernel_liteos_a/kernel/base/include/los_swtmr_pri.h new file mode 100644 index 00000000..02d6c0db --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_swtmr_pri.h @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_SWTMR_PRI_H +#define _LOS_SWTMR_PRI_H + +#include "los_swtmr.h" +#include "los_spinlock.h" +#include "los_sched_pri.h" + +#ifdef LOSCFG_SECURITY_VID +#include "vid_api.h" +#else +#define MAX_INVALID_TIMER_VID OS_SWTMR_MAX_TIMERID +#endif + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_swtmr_pri + * Software timer state + */ +enum SwtmrState { + OS_SWTMR_STATUS_UNUSED, /**< The software timer is not used. */ + OS_SWTMR_STATUS_CREATED, /**< The software timer is created. */ + OS_SWTMR_STATUS_TICKING /**< The software timer is timing. */ +}; + +/** + * @ingroup los_swtmr_pri + * Structure of the callback function that handles software timer timeout + */ +typedef struct { + SWTMR_PROC_FUNC handler; /**< Callback function that handles software timer timeout */ + UINTPTR arg; /**< Parameter passed in when the callback function + that handles software timer timeout is called */ + LOS_DL_LIST node; +#ifdef LOSCFG_SWTMR_DEBUG + UINT32 swtmrID; +#endif +} SwtmrHandlerItem; + +/** + * @ingroup los_swtmr_pri + * Type of the pointer to the structure of the callback function that handles software timer timeout + */ +typedef SwtmrHandlerItem *SwtmrHandlerItemPtr; + +extern SWTMR_CTRL_S *g_swtmrCBArray; + +#define OS_SWT_FROM_SID(swtmrID) ((SWTMR_CTRL_S *)g_swtmrCBArray + ((swtmrID) % LOSCFG_BASE_CORE_SWTMR_LIMIT)) + +/** + * @ingroup los_swtmr_pri + * @brief Scan a software timer. + * + * @par Description: + *
            + *
          • This API is used to scan a software timer when a Tick interrupt occurs and determine whether + * the software timer expires.
          • + *
          + * @attention + *
            + *
          • None.
          • + *
          + * + * @param None. + * + * @retval None. + * @par Dependency: + *
          • los_swtmr_pri.h: the header file that contains the API declaration.
          + * @see LOS_SwtmrStop + */ + +extern UINT32 OsSwtmrGetNextTimeout(VOID); +extern BOOL OsIsSwtmrTask(const LosTaskCB *taskCB); +extern VOID OsSwtmrResponseTimeReset(UINT64 startTime); +extern UINT32 OsSwtmrInit(VOID); +extern VOID OsSwtmrRecycle(UINTPTR ownerID); +extern BOOL OsSwtmrWorkQueueFind(SCHED_TL_FIND_FUNC checkFunc, UINTPTR arg); +extern SPIN_LOCK_S g_swtmrSpin; +extern UINT32 OsSwtmrTaskIDGetByCpuid(UINT16 cpuid); + +#ifdef LOSCFG_SWTMR_DEBUG +typedef struct { + UINT64 startTime; + UINT64 waitTimeMax; + UINT64 waitTime; + UINT64 waitCount; + UINT64 readyStartTime; + UINT64 readyTime; + UINT64 readyTimeMax; + UINT64 runTime; + UINT64 runTimeMax; + UINT64 runCount; + UINT32 times; +} SwtmrDebugBase; + +typedef struct { + SwtmrDebugBase base; + SWTMR_PROC_FUNC handler; + UINT32 period; + UINT32 cpuid; + BOOL swtmrUsed; +} SwtmrDebugData; + +extern BOOL OsSwtmrDebugDataUsed(UINT32 swtmrID); +extern UINT32 OsSwtmrDebugDataGet(UINT32 swtmrID, SwtmrDebugData *data, UINT32 len, UINT8 *mode); +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_SWTMR_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_sys_pri.h b/src/kernel_liteos_a/kernel/base/include/los_sys_pri.h new file mode 100644 index 00000000..01a90e8b --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_sys_pri.h @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_SYS_PRI_H +#define _LOS_SYS_PRI_H + +#include "los_sys.h" +#include "los_base_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_sys + * Number of milliseconds in one second. + */ +#define OS_SYS_MS_PER_SECOND 1000 + +/** + * @ingroup los_sys + * Number of microseconds in one second. + */ +#define OS_SYS_US_PER_SECOND 1000000 + +/** + * @ingroup los_sys + * Number of nanoseconds in one second. + */ +#define OS_SYS_NS_PER_SECOND 1000000000 + +/** + * @ingroup los_sys + * Number of microseconds in one milliseconds. + */ +#define OS_SYS_US_PER_MS 1000 + +/** + * @ingroup los_sys + * Number of nanoseconds in one milliseconds. + */ +#define OS_SYS_NS_PER_MS 1000000 + +/** + * @ingroup los_sys + * Number of nanoseconds in one microsecond. + */ +#define OS_SYS_NS_PER_US 1000 + +/** + * @ingroup los_sys + * Number of cycle in one tick. + */ +#define OS_CYCLE_PER_TICK (OS_SYS_CLOCK / LOSCFG_BASE_CORE_TICK_PER_SECOND) + +/** + * @ingroup los_sys + * Number of nanoseconds in one cycle. + */ +#define OS_NS_PER_CYCLE (OS_SYS_NS_PER_SECOND / OS_SYS_CLOCK) + +/** + * @ingroup los_sys + * Number of microseconds in one tick. + */ +#define OS_US_PER_TICK (OS_SYS_US_PER_SECOND / LOSCFG_BASE_CORE_TICK_PER_SECOND) + +/** + * @ingroup los_sys + * Number of nanoseconds in one tick. + */ +#define OS_NS_PER_TICK (OS_SYS_NS_PER_SECOND / LOSCFG_BASE_CORE_TICK_PER_SECOND) + +#define OS_US_TO_CYCLE(time, freq) ((((time) / OS_SYS_US_PER_SECOND) * (freq)) + \ + (((time) % OS_SYS_US_PER_SECOND) * (freq) / OS_SYS_US_PER_SECOND)) + +#define OS_SYS_US_TO_CYCLE(time) OS_US_TO_CYCLE((time), OS_SYS_CLOCK) + +#define OS_CYCLE_TO_US(cycle, freq) ((((cycle) / (freq)) * OS_SYS_US_PER_SECOND) + \ + ((cycle) % (freq) * OS_SYS_US_PER_SECOND / (freq))) + +#define OS_SYS_CYCLE_TO_US(cycle) OS_CYCLE_TO_US((cycle), OS_SYS_CLOCK) + +/** + * @ingroup los_sys + * The maximum length of name. + */ +#define OS_SYS_APPVER_NAME_MAX 64 + +/** + * @ingroup los_sys + * The magic word. + */ +#define OS_SYS_MAGIC_WORD 0xAAAAAAAA + +/** + * @ingroup los_sys + * The initialization value of stack space. + */ +#define OS_SYS_EMPTY_STACK 0xCACACACA + +/** + * @ingroup los_sys + * Convert nanoseconds to Ticks. + */ +extern UINT32 OsNS2Tick(UINT64 nanoseconds); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_SYS_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_task_pri.h b/src/kernel_liteos_a/kernel/base/include/los_task_pri.h new file mode 100644 index 00000000..fd487a0c --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_task_pri.h @@ -0,0 +1,346 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_TASK_PRI_H +#define _LOS_TASK_PRI_H + +#include "los_task.h" +#include "los_sched_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_task + * Define task signal types. + * + * Task signal types. + */ +#define SIGNAL_NONE 0U +#define SIGNAL_KILL (1U << 0) +#define SIGNAL_SUSPEND (1U << 1) +#define SIGNAL_AFFI (1U << 2) + +/* scheduler lock */ +extern SPIN_LOCK_S g_taskSpin; +#define SCHEDULER_HELD() LOS_SpinHeld(&g_taskSpin) +#define SCHEDULER_LOCK(state) LOS_SpinLockSave(&g_taskSpin, &(state)) +#define SCHEDULER_UNLOCK(state) LOS_SpinUnlockRestore(&g_taskSpin, state) + +/* default and non-running task's ownership id */ +#define OS_TASK_INVALID_CPUID 0xFFFF + +/** + * @ingroup los_task + * Null task ID + * + */ +#define OS_TASK_ERRORID 0xFFFFFFFF + +/** + * @ingroup los_task + * Flag that indicates the task or task control block status. + * + * The task control block is unused. + */ +#define OS_TASK_STATUS_UNUSED 0x0400U + +/** + * @ingroup los_task + * Flag that indicates the task or task control block status. + * + * The task is joinable. + */ +#define OS_TASK_FLAG_PTHREAD_JOIN 0x0800U + +/** + * @ingroup los_task + * Flag that indicates the task or task control block status. + * + * The task is user mode task. + */ +#define OS_TASK_FLAG_USER_MODE 0x1000U + +/** + * @ingroup los_task + * Flag that indicates the task property. + * + * The task is system-level task, like idle, swtmr and etc. + */ +#define OS_TASK_FLAG_SYSTEM_TASK 0x2000U + +/** + * @ingroup los_task + * Flag that indicates the task property. + * + * The task is no-delete system task, like resourceTask. + */ +#define OS_TASK_FLAG_NO_DELETE 0x4000U + +/** + * @ingroup los_task + * Flag that indicates the task property. + * + * Kills the thread during process exit. + */ +#define OS_TASK_FLAG_EXIT_KILL 0x8000U + +/** + * @ingroup los_task + * Flag that indicates the task property. + * + * Specifies the process creation task. + */ +#define OS_TASK_FLAG_SPECIFIES_PROCESS 0x0U + +/** + * @ingroup los_task + * Boundary on which the stack size is aligned. + * + */ +#define OS_TASK_STACK_SIZE_ALIGN 16U + +/** + * @ingroup los_task + * Boundary on which the stack address is aligned. + * + */ +#define OS_TASK_STACK_ADDR_ALIGN 8U + +/** + * @ingroup los_task + * Number of usable task priorities. + */ +#define OS_TSK_PRINUM (OS_TASK_PRIORITY_LOWEST - OS_TASK_PRIORITY_HIGHEST + 1) + +/** +* @ingroup los_task +* @brief Check whether a task ID is valid. +* +* @par Description: +* This API is used to check whether a task ID, excluding the idle task ID, is valid. +* @attention None. +* +* @param taskID [IN] Task ID. +* +* @retval 0 or 1. One indicates that the task ID is invalid, whereas zero indicates that the task ID is valid. +* @par Dependency: +*
          • los_task_pri.h: the header file that contains the API declaration.
          +* @see +*/ +#define OS_TSK_GET_INDEX(taskID) (taskID) + +/** +* @ingroup los_task +* @brief Obtain the pointer to a task control block. +* +* @par Description: +* This API is used to obtain the pointer to a task control block using a corresponding parameter. +* @attention None. +* +* @param ptr [IN] Parameter used for obtaining the task control block. +* +* @retval Pointer to the task control block. +* @par Dependency: +*
          • los_task_pri.h: the header file that contains the API declaration.
          +* @see +*/ +#define OS_TCB_FROM_PENDLIST(ptr) LOS_DL_LIST_ENTRY(ptr, LosTaskCB, pendList) + +/** +* @ingroup los_task +* @brief Obtain the pointer to a task control block. +* +* @par Description: +* This API is used to obtain the pointer to a task control block that has a specified task ID. +* @attention None. +* +* @param TaskID [IN] Task ID. +* +* @retval Pointer to the task control block. +* @par Dependency: +*
          • los_task_pri.h: the header file that contains the API declaration.
          +* @see +*/ +#define OS_TCB_FROM_RTID(taskID) (((LosTaskCB *)g_taskCBArray) + (taskID)) +#ifdef LOSCFG_PID_CONTAINER +#define OS_TCB_FROM_TID(taskID) OsGetTCBFromVtid(taskID) +#else +#define OS_TCB_FROM_TID(taskID) OS_TCB_FROM_RTID(taskID) +#endif + +#ifndef LOSCFG_STACK_POINT_ALIGN_SIZE +#define LOSCFG_STACK_POINT_ALIGN_SIZE (sizeof(UINTPTR) * 2) +#endif + +#define OS_TASK_RESOURCE_STATIC_SIZE 0x1000 +#define OS_TASK_RESOURCE_FREE_PRIORITY 5 +#define OS_RESOURCE_EVENT_MASK 0xFF +#define OS_RESOURCE_EVENT_OOM 0x02 +#define OS_RESOURCE_EVENT_FREE 0x04 + +typedef struct { + LosTaskCB *runTask; + LosTaskCB *newTask; +} LosTask; + +struct ProcessSignalInfo { + siginfo_t *sigInfo; /**< Signal to be dispatched */ + LosTaskCB *defaultTcb; /**< Default TCB */ + LosTaskCB *unblockedTcb; /**< The signal unblock on this TCB*/ + LosTaskCB *awakenedTcb; /**< This TCB was awakened */ + LosTaskCB *receivedTcb; /**< This TCB received the signal */ +}; + +typedef int (*ForEachTaskCB)(LosTaskCB *tcb, void *arg); + +/** + * @ingroup los_task + * Maximum number of tasks. + * + */ +extern UINT32 g_taskMaxNum; + +/** + * @ingroup los_task + * Starting address of a task. + * + */ +extern LosTaskCB *g_taskCBArray; + +/** + * @ingroup los_task + * Time slice structure. + */ +typedef struct { + LosTaskCB *task; /**< Current running task */ + UINT16 time; /**< Expiration time point */ + UINT16 timeout; /**< Expiration duration */ +} OsTaskRobin; + +STATIC INLINE LosTaskCB *OsGetTaskCB(UINT32 taskID) +{ + return OS_TCB_FROM_TID(taskID); +} + +STATIC INLINE BOOL OsTaskIsUnused(const LosTaskCB *taskCB) +{ + return ((taskCB->taskStatus & OS_TASK_STATUS_UNUSED) != 0); +} + +STATIC INLINE BOOL OsTaskIsKilled(const LosTaskCB *taskCB) +{ + return((taskCB->taskStatus & OS_TASK_FLAG_EXIT_KILL) != 0); +} + +STATIC INLINE BOOL OsTaskIsNotDelete(const LosTaskCB *taskCB) +{ + return ((taskCB->taskStatus & (OS_TASK_STATUS_UNUSED | OS_TASK_FLAG_SYSTEM_TASK | OS_TASK_FLAG_NO_DELETE)) != 0); +} + +STATIC INLINE BOOL OsTaskIsUserMode(const LosTaskCB *taskCB) +{ + return ((taskCB->taskStatus & OS_TASK_FLAG_USER_MODE) != 0); +} + +#define OS_TID_CHECK_INVALID(taskID) ((UINT32)(taskID) >= g_taskMaxNum) + +/* get task info */ +#define OS_ALL_TASK_MASK 0xFFFFFFFF + +#define OS_TASK_WAIT_ANYPROCESS (1 << 0U) +#define OS_TASK_WAIT_PROCESS (1 << 1U) +#define OS_TASK_WAIT_GID (1 << 2U) +#define OS_TASK_WAIT_SEM (OS_TASK_WAIT_GID + 1) +#define OS_TASK_WAIT_QUEUE (OS_TASK_WAIT_SEM + 1) +#define OS_TASK_WAIT_JOIN (OS_TASK_WAIT_QUEUE + 1) +#define OS_TASK_WAIT_SIGNAL (OS_TASK_WAIT_JOIN + 1) +#define OS_TASK_WAIT_LITEIPC (OS_TASK_WAIT_SIGNAL + 1) +#define OS_TASK_WAIT_MUTEX (OS_TASK_WAIT_LITEIPC + 1) +#define OS_TASK_WAIT_FUTEX (OS_TASK_WAIT_MUTEX + 1) +#define OS_TASK_WAIT_EVENT (OS_TASK_WAIT_FUTEX + 1) +#define OS_TASK_WAIT_COMPLETE (OS_TASK_WAIT_EVENT + 1) + +STATIC INLINE VOID OsTaskWaitSetPendMask(UINT16 mask, UINTPTR lockID, UINT32 timeout) +{ + LosTaskCB *runTask = OsCurrTaskGet(); + runTask->waitID = lockID; + runTask->waitFlag = mask; + (VOID)timeout; +} + +STATIC INLINE VOID OsTaskWakeClearPendMask(LosTaskCB *resumeTask) +{ + resumeTask->waitID = 0; + resumeTask->waitFlag = 0; +} + +extern UINT32 OsTaskSetDetachUnsafe(LosTaskCB *taskCB); +extern VOID OsTaskJoinPostUnsafe(LosTaskCB *taskCB); +extern UINT32 OsTaskJoinPendUnsafe(LosTaskCB *taskCB); +extern BOOL OsTaskCpuAffiSetUnsafe(UINT32 taskID, UINT16 newCpuAffiMask, UINT16 *oldCpuAffiMask); +extern VOID OsTaskSchedule(LosTaskCB *, LosTaskCB *); +extern VOID OsTaskContextLoad(LosTaskCB *newTask); +extern VOID OsIdleTask(VOID); +extern UINT32 OsIdleTaskCreate(UINTPTR processID); +extern UINT32 OsTaskInit(UINTPTR processCB); +extern UINT32 OsShellCmdDumpTask(INT32 argc, const CHAR **argv); +extern UINT32 OsShellCmdTskInfoGet(UINT32 taskID, VOID *seqfile, UINT16 flag); +extern LosTaskCB *OsGetMainTask(VOID); +extern VOID OsSetMainTask(VOID); +extern UINT32 OsGetIdleTaskId(VOID); +extern VOID OsTaskEntry(UINT32 taskID); +extern VOID OsTaskProcSignal(VOID); +extern UINT32 OsCreateUserTask(UINTPTR processID, TSK_INIT_PARAM_S *initParam); +extern INT32 OsSetTaskName(LosTaskCB *taskCB, const CHAR *name, BOOL setPName); +extern VOID OsTaskCBRecycleToFree(VOID); +extern VOID OsRunningTaskToExit(LosTaskCB *runTask, UINT32 status); +extern INT32 OsUserTaskOperatePermissionsCheck(const LosTaskCB *taskCB); +extern INT32 OsUserProcessOperatePermissionsCheck(const LosTaskCB *taskCB, UINTPTR processCB); +extern INT32 OsTcbDispatch(LosTaskCB *stcb, siginfo_t *info); +extern VOID OsWriteResourceEvent(UINT32 events); +extern VOID OsWriteResourceEventUnsafe(UINT32 events); +extern UINT32 OsResourceFreeTaskCreate(VOID); +extern VOID OsTaskInsertToRecycleList(LosTaskCB *taskCB); +extern VOID OsInactiveTaskDelete(LosTaskCB *taskCB); +extern VOID OsSetMainTaskProcess(UINTPTR processCB); +extern LosTaskCB *OsGetDefaultTaskCB(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_TASK_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_tick_pri.h b/src/kernel_liteos_a/kernel/base/include/los_tick_pri.h new file mode 100644 index 00000000..4621733f --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_tick_pri.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_TICK_PRI_H +#define _LOS_TICK_PRI_H + +#include "los_base.h" +#include "los_tick.h" +#include "los_spinlock.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_tick + * Cycle to nanosecond scale + */ +extern DOUBLE g_cycle2NsScale; + +/** +* @ingroup los_tick +* @brief Handle the system tick timeout. +* +* @par Description: +* This API is called when the system tick timeout and triggers the interrupt. +* +* @attention +*
            +*
          • None.
          • +*
          +* +* @param none. +* +* @retval None. +* @par Dependency: +*
          • los_tick.h: the header file that contains the API declaration.
          +* @see None. +*/ +extern VOID OsTickHandler(VOID); + +/** + * @ingroup los_tick + * Convert from the cycle count to nanosecond. + */ +#define CYCLE_TO_NS(cycles) ((cycles) * g_cycle2NsScale) + +/** + * Current system timer register is 32 bit, therefore TIMER_MAXLOAD define just in order to avoid ambiguity. + */ +#define TIMER_MAXLOAD 0xffffffff + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_TICK_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_time_container_pri.h b/src/kernel_liteos_a/kernel/base/include/los_time_container_pri.h new file mode 100644 index 00000000..6798580b --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_time_container_pri.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_TIME_CONTAINER_PRI_H +#define _LOS_TIME_CONTAINER_PRI_H +#include "time.h" +#include "los_atomic.h" + +#ifdef LOSCFG_TIME_CONTAINER +typedef struct ProcessCB LosProcessCB; +struct Container; + +typedef struct TimeContainer { + Atomic rc; + BOOL frozenOffsets; + struct timespec64 monotonic; + UINT32 containerID; +} TimeContainer; + +UINT32 OsInitRootTimeContainer(TimeContainer **timeContainer); + +UINT32 OsCopyTimeContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent); + +UINT32 OsUnshareTimeContainer(UINTPTR flags, LosProcessCB *curr, struct Container *newContainer); + +UINT32 OsSetNsTimeContainer(UINT32 flags, struct Container *container, struct Container *newContainer); + +VOID OsTimeContainerDestroy(struct Container *container); + +UINT32 OsGetTimeContainerID(TimeContainer *timeContainer); + +TimeContainer *OsGetCurrTimeContainer(VOID); + +UINT32 OsGetTimeContainerMonotonic(LosProcessCB *processCB, struct timespec64 *offsets); + +UINT32 OsSetTimeContainerMonotonic(LosProcessCB *processCB, struct timespec64 *offsets); + +UINT32 OsGetTimeContainerCount(VOID); + +#define CLOCK_MONOTONIC_TIME_BASE (OsGetCurrTimeContainer()->monotonic) + +#endif +#endif /* _LOS_TIME_CONTAINER_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_typedef_pri.h b/src/kernel_liteos_a/kernel/base/include/los_typedef_pri.h new file mode 100644 index 00000000..eff17a91 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_typedef_pri.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_TYPEDEF_PRI_H +#define _LOS_TYPEDEF_PRI_H + +#include "los_typedef.h" + +#endif /* _LOS_TYPEDEF_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_user_container_pri.h b/src/kernel_liteos_a/kernel/base/include/los_user_container_pri.h new file mode 100644 index 00000000..a073599b --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_user_container_pri.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_USER_CONTAINER_PRI_H +#define _LOS_USER_CONTAINER_PRI_H + +#include "los_atomic.h" +#include "los_credentials_pri.h" + +#define UID_GID_MAP_MAX_EXTENTS 5 + +#ifdef LOSCFG_USER_CONTAINER +struct ProcFile; + +typedef struct UidGidExtent { + UINT32 first; + UINT32 lowerFirst; + UINT32 count; +} UidGidExtent; + +typedef struct UidGidMap { + UINT32 extentCount; + union { + UidGidExtent extent[UID_GID_MAP_MAX_EXTENTS]; + }; +} UidGidMap; + +typedef struct UserContainer { + Atomic rc; + INT32 level; + UINT32 owner; + UINT32 group; + struct UserContainer *parent; + UidGidMap uidMap; + UidGidMap gidMap; + UINT32 containerID; +} UserContainer; + +UINT32 OsCreateUserContainer(Credentials *newCredentials, UserContainer *parentUserContainer); + +VOID FreeUserContainer(UserContainer *userContainer); + +UINT32 OsFromKuidMunged(UserContainer *userContainer, UINT32 kuid); + +UINT32 OsFromKgidMunged(UserContainer *userContainer, UINT32 kgid); + +UINT32 OsMakeKuid(UserContainer *userContainer, UINT32 uid); + +UINT32 OsMakeKgid(UserContainer *userContainer, UINT32 gid); + +INT32 OsUserContainerMapWrite(struct ProcFile *fp, CHAR *buf, size_t count, + INT32 capSetid, UidGidMap *map, UidGidMap *parentMap); + +UINT32 OsGetUserContainerCount(VOID); +#endif +#endif diff --git a/src/kernel_liteos_a/kernel/base/include/los_uts_container_pri.h b/src/kernel_liteos_a/kernel/base/include/los_uts_container_pri.h new file mode 100644 index 00000000..5642286c --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_uts_container_pri.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_UTS_CONTAINER_PRI_H +#define _LOS_UTS_CONTAINER_PRI_H + +#include "sys/utsname.h" +#include "sched.h" +#include "los_atomic.h" + +#ifdef LOSCFG_UTS_CONTAINER + +typedef struct ProcessCB LosProcessCB; +struct Container; + +typedef struct UtsContainer { + Atomic rc; + UINT32 containerID; + struct utsname utsName; +} UtsContainer; + +UINT32 OsInitRootUtsContainer(UtsContainer **utsContainer); + +UINT32 OsCopyUtsContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent); + +UINT32 OsUnshareUtsContainer(UINTPTR flags, LosProcessCB *curr, struct Container *newContainer); + +UINT32 OsSetNsUtsContainer(UINT32 flags, struct Container *container, struct Container *newContainer); + +VOID OsUtsContainerDestroy(struct Container *container); + +struct utsname *OsGetCurrUtsName(VOID); + +UINT32 OsGetUtsContainerID(UtsContainer *utsContainer); + +UINT32 OsGetUtsContainerCount(VOID); +#endif +#endif /* _LOS_UTS_CONTAINER_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_vm_boot.h b/src/kernel_liteos_a/kernel/base/include/los_vm_boot.h new file mode 100644 index 00000000..fb6e714a --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_vm_boot.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* flags for initial mapping struct */ +#define MMU_INITIAL_MAPPING_TEMPORARY (0x1) +#define MMU_INITIAL_MAPPING_FLAG_UNCACHED (0x2) +#define MMU_INITIAL_MAPPING_FLAG_DEVICE (0x4) +#define MMU_INITIAL_MAPPING_FLAG_DYNAMIC (0x8) +#ifndef ASSEMBLY + +#ifndef __LOS_VM_BOOT_H__ +#define __LOS_VM_BOOT_H__ + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define OS_KHEAP_BLOCK_SIZE (512 * 1024UL) + +typedef struct ArchMmuInitMapping { + PADDR_T phys; + VADDR_T virt; + size_t size; + unsigned int flags; + const char *name; +} LosArchMmuInitMapping; + +extern LosArchMmuInitMapping g_archMmuInitMapping[]; + +extern UINTPTR g_vmBootMemBase; +extern BOOL g_kHeapInited; + +UINT32 OsVmAddrCheck(size_t tempAddr, size_t length); +VOID *OsVmBootMemAlloc(size_t len); +UINT32 OsSysMemInit(VOID); +VOID OsInitMappingStartUp(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ +#endif /* __LOS_VM_BOOT_H__ */ +#endif /* ASSEMBLY */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_vm_common.h b/src/kernel_liteos_a/kernel/base/include/los_vm_common.h new file mode 100644 index 00000000..f2dd70bf --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_vm_common.h @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_vm_map vm common definition + * @ingroup kernel + */ + +#ifndef __LOS_VM_COMMON_H__ +#define __LOS_VM_COMMON_H__ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/* user address space, defaults to below kernel space with a 16MB guard gap on either side */ +#ifndef USER_ASPACE_BASE +#define USER_ASPACE_BASE ((vaddr_t)0x01000000UL) +#endif +#ifndef USER_ASPACE_SIZE +#define USER_ASPACE_SIZE ((vaddr_t)KERNEL_ASPACE_BASE - USER_ASPACE_BASE - 0x01000000UL) +#endif + +#define USER_ASPACE_TOP_MAX ((vaddr_t)(USER_ASPACE_BASE + USER_ASPACE_SIZE)) +#define USER_HEAP_BASE ((vaddr_t)(USER_ASPACE_TOP_MAX >> 2)) +#define USER_MAP_BASE ((vaddr_t)(USER_ASPACE_TOP_MAX >> 1)) +#define USER_MAP_SIZE ((vaddr_t)(USER_ASPACE_SIZE >> 3)) + +#ifndef PAGE_SIZE +#define PAGE_SIZE (0x1000U) +#endif +#define PAGE_MASK (~(PAGE_SIZE - 1)) +#define PAGE_SHIFT (12) + +#define KB (1024UL) +#define MB (1024UL * 1024UL) +#define GB (1024UL * 1024UL * 1024UL) + +#define ROUNDUP(a, b) (((a) + ((b) - 1)) & ~((b) - 1)) +#define ROUNDDOWN(a, b) ((a) & ~((b) - 1)) +#define ROUNDOFFSET(a, b) ((a) & ((b) - 1)) +#define MIN2(a, b) (((a) < (b)) ? (a) : (b)) + +#define IS_ALIGNED(a, b) (!(((UINTPTR)(a)) & (((UINTPTR)(b)) - 1))) +#define IS_PAGE_ALIGNED(x) IS_ALIGNED(x, PAGE_SIZE) +#define IS_SECTION_ALIGNED(x) IS_ALIGNED(x, SECTION_SIZE) + +#define LOS_ERRNO_VM_NO_ERROR (0) +#define LOS_ERRNO_VM_GENERIC (-1) +#define LOS_ERRNO_VM_NOT_FOUND (-2) +#define LOS_ERRNO_VM_NOT_READY (-3) +#define LOS_ERRNO_VM_NO_MSG (-4) +#define LOS_ERRNO_VM_NO_MEMORY (-5) +#define LOS_ERRNO_VM_ALREADY_STARTED (-6) +#define LOS_ERRNO_VM_NOT_VALID (-7) +#define LOS_ERRNO_VM_INVALID_ARGS (-8) +#define LOS_ERRNO_VM_NOT_ENOUGH_BUFFER (-9) +#define LOS_ERRNO_VM_NOT_SUSPENDED (-10) +#define LOS_ERRNO_VM_OBJECT_DESTROYED (-11) +#define LOS_ERRNO_VM_NOT_BLOCKED (-12) +#define LOS_ERRNO_VM_TIMED_OUT (-13) +#define LOS_ERRNO_VM_ALREADY_EXISTS (-14) +#define LOS_ERRNO_VM_CHANNEL_CLOSED (-15) +#define LOS_ERRNO_VM_OFFLINE (-16) +#define LOS_ERRNO_VM_NOT_ALLOWED (-17) +#define LOS_ERRNO_VM_BAD_PATH (-18) +#define LOS_ERRNO_VM_ALREADY_MOUNTED (-19) +#define LOS_ERRNO_VM_IO (-20) +#define LOS_ERRNO_VM_NOT_DIR (-21) +#define LOS_ERRNO_VM_NOT_FILE (-22) +#define LOS_ERRNO_VM_RECURSE_TOO_DEEP (-23) +#define LOS_ERRNO_VM_NOT_SUPPORTED (-24) +#define LOS_ERRNO_VM_TOO_BIG (-25) +#define LOS_ERRNO_VM_CANCELLED (-26) +#define LOS_ERRNO_VM_NOT_IMPLEMENTED (-27) +#define LOS_ERRNO_VM_CHECKSUM_FAIL (-28) +#define LOS_ERRNO_VM_CRC_FAIL (-29) +#define LOS_ERRNO_VM_CMD_UNKNOWN (-30) +#define LOS_ERRNO_VM_BAD_STATE (-31) +#define LOS_ERRNO_VM_BAD_LEN (-32) +#define LOS_ERRNO_VM_BUSY (-33) +#define LOS_ERRNO_VM_THREAD_DETACHED (-34) +#define LOS_ERRNO_VM_I2C_NACK (-35) +#define LOS_ERRNO_VM_ALREADY_EXPIRED (-36) +#define LOS_ERRNO_VM_OUT_OF_RANGE (-37) +#define LOS_ERRNO_VM_NOT_CONFIGURED (-38) +#define LOS_ERRNO_VM_NOT_MOUNTED (-39) +#define LOS_ERRNO_VM_FAULT (-40) +#define LOS_ERRNO_VM_NO_RESOURCES (-41) +#define LOS_ERRNO_VM_BAD_HANDLE (-42) +#define LOS_ERRNO_VM_ACCESS_DENIED (-43) +#define LOS_ERRNO_VM_PARTIAL_WRITE (-44) +#define LOS_ERRNO_VM_LOCK (-45) +#define LOS_ERRNO_VM_MAP_FAILED (-46) + +#define VM_ERR(args...) do { \ + PRINT_ERR("%s %d ", __FUNCTION__, __LINE__); \ + if (PRINT_LEVEL == LOS_DEBUG_LEVEL) { \ + PRINTK(args); \ + } \ + PRINTK("\n"); \ +} while (0) + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* __LOS_VM_COMMON_H__ */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_vm_dump.h b/src/kernel_liteos_a/kernel/base/include/los_vm_dump.h new file mode 100644 index 00000000..01b11858 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_vm_dump.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_vm_dump virtual memory dump operation + * @ingroup kernel + */ + +#ifndef __LOS_VM_DUMP_H__ +#define __LOS_VM_DUMP_H__ + +#include "los_vm_map.h" +#include "los_process_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * These macros is used for process memory usage statistics. + * Include virtual memory, shared memory and physical memory. + */ +#define PROCESS_VM_INDEX_MAX 3 +#define PROCESS_MEMINFO_LEN (sizeof(UINT32) * PROCESS_VM_INDEX_MAX) +#define PROCESS_VM_INDEX 0 +#define PROCESS_SM_INDEX 1 +#define PROCESS_PM_INDEX 2 + +const CHAR *OsGetRegionNameOrFilePath(LosVmMapRegion *region); +INT32 OsRegionOverlapCheckUnlock(LosVmSpace *space, LosVmMapRegion *region); +UINT32 OsShellCmdProcessVmUsage(LosVmSpace *space); +UINT32 OsShellCmdProcessPmUsage(LosVmSpace *space, UINT32 *sharePm, UINT32 *actualPm); +UINT32 OsUProcessPmUsage(LosVmSpace *space, UINT32 *sharePm, UINT32 *actualPm); +UINT32 OsKProcessPmUsage(LosVmSpace *kAspace, UINT32 *actualPm); +VOID OsDumpAspace(LosVmSpace *space); +UINT32 OsCountRegionPages(LosVmSpace *space, LosVmMapRegion *region, UINT32 *pssPages); +UINT32 OsCountAspacePages(LosVmSpace *space); +VOID OsDumpAllAspace(VOID); +VOID OsVmPhysDump(VOID); +VOID OsVmPhysUsedInfoGet(UINT32 *usedCount, UINT32 *totalCount); +INT32 OsRegionOverlapCheck(LosVmSpace *space, LosVmMapRegion *region); +VOID OsDumpPte(VADDR_T vaddr); +LosProcessCB *OsGetPIDByAspace(const LosVmSpace *space); +CHAR *OsArchFlagsToStr(const UINT32 archFlags); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* __LOS_VM_DUMP_H__ */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_vm_fault.h b/src/kernel_liteos_a/kernel/base/include/los_vm_fault.h new file mode 100644 index 00000000..d3c650a2 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_vm_fault.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_vm_fault vm fault definition + * @ingroup kernel + */ + +#ifndef __LOS_VM_FAULT_H__ +#define __LOS_VM_FAULT_H__ + +#include "los_typedef.h" +#include "los_exc.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef struct { + VADDR_T excAddr; + VADDR_T fixAddr; +} LosExcTable; + +#define VM_MAP_PF_FLAG_WRITE (1U << 0) +#define VM_MAP_PF_FLAG_USER (1U << 1) +#define VM_MAP_PF_FLAG_INSTRUCTION (1U << 2) +#define VM_MAP_PF_FLAG_NOT_PRESENT (1U << 3) + +STATUS_T OsVmPageFaultHandler(VADDR_T vaddr, UINT32 flags, ExcContext *frame); +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* __LOS_VM_FAULT_H__ */ + diff --git a/src/kernel_liteos_a/kernel/base/include/los_vm_filemap.h b/src/kernel_liteos_a/kernel/base/include/los_vm_filemap.h new file mode 100644 index 00000000..c8cceb21 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_vm_filemap.h @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_vm_filemap vm filemap definition + * @ingroup kernel + */ + +#ifndef __LOS_VM_FILEMAP_H__ +#define __LOS_VM_FILEMAP_H__ + +#ifdef LOSCFG_FS_VFS +#include "fs/file.h" +#endif +#include "los_vm_map.h" +#include "los_vm_page.h" +#include "los_vm_common.h" +#include "los_vm_phys.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef struct FilePage { + LOS_DL_LIST node; + LOS_DL_LIST lru; + LOS_DL_LIST i_mmap; /* list of mappings */ + UINT32 n_maps; /* num of mapping */ + struct VmPhysSeg *physSeg; /* physical memory that file page belongs to */ + struct VmPage *vmPage; + struct page_mapping *mapping; + VM_OFFSET_T pgoff; + UINT32 flags; + UINT16 dirtyOff; + UINT16 dirtyEnd; +} LosFilePage; + +typedef struct MapInfo { + LOS_DL_LIST node; + VADDR_T vaddr; + LosFilePage *page; + LosArchMmu *archMmu; +} LosMapInfo; + +enum OsPageFlags { + FILE_PAGE_FREE, + FILE_PAGE_LOCKED, + FILE_PAGE_REFERENCED, + FILE_PAGE_DIRTY, + FILE_PAGE_LRU, + FILE_PAGE_ACTIVE, + FILE_PAGE_SHARED, +}; + +#define PGOFF_MAX 2000 +#define MAX_SHRINK_PAGECACHE_TRY 2 +#define VM_FILEMAP_MAX_SCAN (SYS_MEM_SIZE_DEFAULT >> PAGE_SHIFT) +#define VM_FILEMAP_MIN_SCAN 32 + +STATIC INLINE VOID OsSetPageLocked(LosVmPage *page) +{ + LOS_BitmapSet(&page->flags, FILE_PAGE_LOCKED); +} + +STATIC INLINE VOID OsCleanPageLocked(LosVmPage *page) +{ + LOS_BitmapClr(&page->flags, FILE_PAGE_LOCKED); +} + +STATIC INLINE VOID OsSetPageDirty(LosVmPage *page) +{ + LOS_BitmapSet(&page->flags, FILE_PAGE_DIRTY); +} + +STATIC INLINE VOID OsCleanPageDirty(LosVmPage *page) +{ + LOS_BitmapClr(&page->flags, FILE_PAGE_DIRTY); +} + +STATIC INLINE VOID OsSetPageActive(LosVmPage *page) +{ + LOS_BitmapSet(&page->flags, FILE_PAGE_ACTIVE); +} + +STATIC INLINE VOID OsCleanPageActive(LosVmPage *page) +{ + LOS_BitmapClr(&page->flags, FILE_PAGE_ACTIVE); +} + +STATIC INLINE VOID OsSetPageLRU(LosVmPage *page) +{ + LOS_BitmapSet(&page->flags, FILE_PAGE_LRU); +} + +STATIC INLINE VOID OsSetPageFree(LosVmPage *page) +{ + LOS_BitmapSet(&page->flags, FILE_PAGE_FREE); +} + +STATIC INLINE VOID OsCleanPageFree(LosVmPage *page) +{ + LOS_BitmapClr(&page->flags, FILE_PAGE_FREE); +} + +STATIC INLINE VOID OsSetPageReferenced(LosVmPage *page) +{ + LOS_BitmapSet(&page->flags, FILE_PAGE_REFERENCED); +} + +STATIC INLINE VOID OsCleanPageReferenced(LosVmPage *page) +{ + LOS_BitmapClr(&page->flags, FILE_PAGE_REFERENCED); +} + +STATIC INLINE BOOL OsIsPageActive(LosVmPage *page) +{ + return BIT_GET(page->flags, FILE_PAGE_ACTIVE); +} + +STATIC INLINE BOOL OsIsPageLocked(LosVmPage *page) +{ + return BIT_GET(page->flags, FILE_PAGE_LOCKED); +} + +STATIC INLINE BOOL OsIsPageReferenced(LosVmPage *page) +{ + return BIT_GET(page->flags, FILE_PAGE_REFERENCED); +} + +STATIC INLINE BOOL OsIsPageDirty(LosVmPage *page) +{ + return BIT_GET(page->flags, FILE_PAGE_DIRTY); +} + +STATIC INLINE BOOL OsIsPageMapped(LosFilePage *page) +{ + return (page->n_maps != 0); +} + +/* The follow three functions is used to SHM module */ +STATIC INLINE VOID OsSetPageShared(LosVmPage *page) +{ + LOS_BitmapSet(&page->flags, FILE_PAGE_SHARED); +} + +STATIC INLINE VOID OsCleanPageShared(LosVmPage *page) +{ + LOS_BitmapClr(&page->flags, FILE_PAGE_SHARED); +} + +STATIC INLINE BOOL OsIsPageShared(LosVmPage *page) +{ + return BIT_GET(page->flags, FILE_PAGE_SHARED); +} + +typedef struct ProcessCB LosProcessCB; + +#ifdef LOSCFG_FS_VFS +INT32 OsVfsFileMmap(struct file *filep, LosVmMapRegion *region); +STATUS_T OsNamedMMap(struct file *filep, LosVmMapRegion *region); +VOID OsVmmFileRegionFree(struct file *filep, LosProcessCB *processCB); +#endif + +LosFilePage *OsPageCacheAlloc(struct page_mapping *mapping, VM_OFFSET_T pgoff); +LosFilePage *OsFindGetEntry(struct page_mapping *mapping, VM_OFFSET_T pgoff); +LosMapInfo *OsGetMapInfo(const LosFilePage *page, const LosArchMmu *archMmu, VADDR_T vaddr); +VOID OsAddMapInfo(LosFilePage *page, LosArchMmu *archMmu, VADDR_T vaddr); +VOID OsDelMapInfo(LosVmMapRegion *region, LosVmPgFault *pgFault, BOOL cleanDirty); +VOID OsFileCacheFlush(struct page_mapping *mapping); +VOID OsFileCacheRemove(struct page_mapping *mapping); +VOID OsUnmapPageLocked(LosFilePage *page, LosMapInfo *info); +VOID OsUnmapAllLocked(LosFilePage *page); +VOID OsLruCacheAdd(LosFilePage *fpage, enum OsLruList lruType); +VOID OsLruCacheDel(LosFilePage *fpage); +LosFilePage *OsDumpDirtyPage(LosFilePage *oldPage); +VOID OsDoFlushDirtyPage(LosFilePage *fpage); +VOID OsDeletePageCacheLru(LosFilePage *page); +VOID OsPageRefDecNoLock(LosFilePage *page); +VOID OsPageRefIncLocked(LosFilePage *page); +int OsTryShrinkMemory(size_t nPage); +VOID OsMarkPageDirty(LosFilePage *fpage, const LosVmMapRegion *region, int off, int len); + +#ifdef LOSCFG_DEBUG_VERSION +VOID ResetPageCacheHitInfo(int *try, int *hit); +struct file_map* GetFileMappingList(void); +#endif +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* __LOS_VM_FILEMAP_H__ */ + diff --git a/src/kernel_liteos_a/kernel/base/include/los_vm_iomap.h b/src/kernel_liteos_a/kernel/base/include/los_vm_iomap.h new file mode 100644 index 00000000..bf5fea03 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_vm_iomap.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __LOS_VM_IOMAP_H__ +#define __LOS_VM_IOMAP_H__ + +#include "los_typedef.h" +#include "los_vm_zone.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +enum DmaMemType { + DMA_CACHE, + DMA_NOCACHE +}; + +/* thread safety */ +VOID *LOS_DmaMemAlloc(DMA_ADDR_T *dmaAddr, size_t size, size_t align, enum DmaMemType type); +VOID LOS_DmaMemFree(VOID *vaddr); +DMA_ADDR_T LOS_DmaVaddrToPaddr(VOID *vaddr); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* __LOS_VM_IOMAP_H__ */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_vm_lock.h b/src/kernel_liteos_a/kernel/base/include/los_vm_lock.h new file mode 100644 index 00000000..aa3c36fe --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_vm_lock.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_vm_map vm lock operation + * @ingroup kernel + */ + +#ifndef __LOS_VM_LOCK_H__ +#define __LOS_VM_LOCK_H__ + +#include "los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +STATIC INLINE STATUS_T LOS_MuxAcquire(LosMux *m) +{ + return LOS_MuxLock(m, LOS_WAIT_FOREVER); +} + +STATIC INLINE STATUS_T LOS_MuxRelease(LosMux *m) +{ + return LOS_MuxUnlock(m); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* __LOS_VM_LOCK_H__ */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_vm_map.h b/src/kernel_liteos_a/kernel/base/include/los_vm_map.h new file mode 100644 index 00000000..344e1ad8 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_vm_map.h @@ -0,0 +1,323 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_vm_map vm mapping management + * @ingroup kernel + */ + +#ifndef __LOS_VM_MAP_H__ +#define __LOS_VM_MAP_H__ + +#include "los_typedef.h" +#include "los_arch_mmu.h" +#include "los_mux.h" +#include "los_rbtree.h" +#include "los_vm_syscall.h" +#include "los_vm_zone.h" +#include "los_vm_common.h" + +struct Vnode; + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/* If the kernel malloc size is less than 16k, use heap, otherwise use physical pages */ +#define KMALLOC_LARGE_SIZE (PAGE_SIZE << 2) + +typedef struct VmMapRange { + VADDR_T base; /**< vm region base addr */ + UINT32 size; /**< vm region size */ +} LosVmMapRange; + +struct VmMapRegion; +typedef struct VmMapRegion LosVmMapRegion; +struct VmFileOps; +typedef struct VmFileOps LosVmFileOps; +struct VmSpace; +typedef struct VmSpace LosVmSpace; + +typedef struct VmFault { + UINT32 flags; /* FAULT_FLAG_xxx flags */ + unsigned long pgoff; /* Logical page offset based on region */ + VADDR_T vaddr; /* Faulting virtual address */ + VADDR_T *pageKVaddr; /* KVaddr of pagefault's vm page's paddr */ +} LosVmPgFault; + +struct VmFileOps { + void (*open)(struct VmMapRegion *region); + void (*close)(struct VmMapRegion *region); + int (*fault)(struct VmMapRegion *region, LosVmPgFault *pageFault); + void (*remove)(struct VmMapRegion *region, LosArchMmu *archMmu, VM_OFFSET_T offset); +}; + +struct VmMapRegion { + LosRbNode rbNode; /**< region red-black tree node */ + LosVmSpace *space; + LOS_DL_LIST node; /**< region dl list */ + LosVmMapRange range; /**< region address range */ + VM_OFFSET_T pgOff; /**< region page offset to file */ + UINT32 regionFlags; /**< region flags: cow, user_wired */ + UINT32 shmid; /**< shmid about shared region */ + UINT8 forkFlags; /**< vm space fork flags: COPY, ZERO, */ + UINT8 regionType; /**< vm region type: ANON, FILE, DEV */ + union { + struct VmRegionFile { + int f_oflags; + struct Vnode *vnode; + const LosVmFileOps *vmFOps; + } rf; + struct VmRegionAnon { + LOS_DL_LIST node; /**< region LosVmPage list */ + } ra; + struct VmRegionDev { + LOS_DL_LIST node; /**< region LosVmPage list */ + const LosVmFileOps *vmFOps; + } rd; + } unTypeData; +}; + +typedef struct VmSpace { + LOS_DL_LIST node; /**< vm space dl list */ + LosRbTree regionRbTree; /**< region red-black tree root */ + LosMux regionMux; /**< region red-black tree mutex lock */ + VADDR_T base; /**< vm space base addr */ + UINT32 size; /**< vm space size */ + VADDR_T heapBase; /**< vm space heap base address */ + VADDR_T heapNow; /**< vm space heap base now */ + LosVmMapRegion *heap; /**< heap region */ + VADDR_T mapBase; /**< vm space mapping area base */ + UINT32 mapSize; /**< vm space mapping area size */ + LosArchMmu archMmu; /**< vm mapping physical memory */ +#ifdef LOSCFG_DRIVERS_TZDRIVER + VADDR_T codeStart; /**< user process code area start */ + VADDR_T codeEnd; /**< user process code area end */ +#endif +} LosVmSpace; + +#define VM_MAP_REGION_TYPE_NONE (0x0) +#define VM_MAP_REGION_TYPE_ANON (0x1) +#define VM_MAP_REGION_TYPE_FILE (0x2) +#define VM_MAP_REGION_TYPE_DEV (0x4) +#define VM_MAP_REGION_TYPE_MASK (0x7) + +/* the high 8 bits(24~31) should reserved, shm will use it */ +#define VM_MAP_REGION_FLAG_CACHED (0<<0) +#define VM_MAP_REGION_FLAG_UNCACHED (1<<0) +#define VM_MAP_REGION_FLAG_UNCACHED_DEVICE (2<<0) /* only exists on some arches, otherwise UNCACHED */ +#define VM_MAP_REGION_FLAG_STRONGLY_ORDERED (3<<0) /* only exists on some arches, otherwise UNCACHED */ +#define VM_MAP_REGION_FLAG_CACHE_MASK (3<<0) +#define VM_MAP_REGION_FLAG_PERM_USER (1<<2) +#define VM_MAP_REGION_FLAG_PERM_READ (1<<3) +#define VM_MAP_REGION_FLAG_PERM_WRITE (1<<4) +#define VM_MAP_REGION_FLAG_PERM_EXECUTE (1<<5) +#define VM_MAP_REGION_FLAG_PROT_MASK (0xF<<2) +#define VM_MAP_REGION_FLAG_NS (1<<6) /* NON-SECURE */ +#define VM_MAP_REGION_FLAG_SHARED (1<<7) +#define VM_MAP_REGION_FLAG_PRIVATE (1<<8) +#define VM_MAP_REGION_FLAG_FLAG_MASK (3<<7) +#define VM_MAP_REGION_FLAG_STACK (1<<9) +#define VM_MAP_REGION_FLAG_HEAP (1<<10) +#define VM_MAP_REGION_FLAG_DATA (1<<11) +#define VM_MAP_REGION_FLAG_TEXT (1<<12) +#define VM_MAP_REGION_FLAG_BSS (1<<13) +#define VM_MAP_REGION_FLAG_VDSO (1<<14) +#define VM_MAP_REGION_FLAG_MMAP (1<<15) +#define VM_MAP_REGION_FLAG_SHM (1<<16) +#define VM_MAP_REGION_FLAG_FIXED (1<<17) +#define VM_MAP_REGION_FLAG_FIXED_NOREPLACE (1<<18) +#define VM_MAP_REGION_FLAG_INVALID (1<<19) /* indicates that flags are not specified */ + +STATIC INLINE UINT32 OsCvtProtFlagsToRegionFlags(unsigned long prot, unsigned long flags) +{ + UINT32 regionFlags = 0; + + regionFlags |= VM_MAP_REGION_FLAG_PERM_USER; + regionFlags |= (prot & PROT_READ) ? VM_MAP_REGION_FLAG_PERM_READ : 0; + regionFlags |= (prot & PROT_WRITE) ? (VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE) : 0; + regionFlags |= (prot & PROT_EXEC) ? (VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_EXECUTE) : 0; + regionFlags |= (flags & MAP_SHARED) ? VM_MAP_REGION_FLAG_SHARED : 0; + regionFlags |= (flags & MAP_PRIVATE) ? VM_MAP_REGION_FLAG_PRIVATE : 0; + regionFlags |= (flags & MAP_FIXED) ? VM_MAP_REGION_FLAG_FIXED : 0; + regionFlags |= (flags & MAP_FIXED_NOREPLACE) ? VM_MAP_REGION_FLAG_FIXED_NOREPLACE : 0; + + return regionFlags; +} + +STATIC INLINE BOOL LOS_IsKernelAddress(VADDR_T vaddr) +{ + return ((vaddr >= (VADDR_T)KERNEL_ASPACE_BASE) && + (vaddr <= ((VADDR_T)KERNEL_ASPACE_BASE + ((VADDR_T)KERNEL_ASPACE_SIZE - 1)))); +} + +STATIC INLINE BOOL LOS_IsKernelAddressRange(VADDR_T vaddr, size_t len) +{ + return (vaddr + len > vaddr) && LOS_IsKernelAddress(vaddr) && (LOS_IsKernelAddress(vaddr + len - 1)); +} + +STATIC INLINE VADDR_T LOS_RegionEndAddr(LosVmMapRegion *region) +{ + return (region->range.base + region->range.size - 1); +} + +STATIC INLINE size_t LOS_RegionSize(VADDR_T start, VADDR_T end) +{ + return (end - start + 1); +} + +STATIC INLINE BOOL LOS_IsRegionTypeFile(LosVmMapRegion* region) +{ + return region->regionType == VM_MAP_REGION_TYPE_FILE; +} + +STATIC INLINE BOOL LOS_IsRegionPermUserReadOnly(LosVmMapRegion* region) +{ + return ((region->regionFlags & VM_MAP_REGION_FLAG_PROT_MASK) == + (VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_READ)); +} + +STATIC INLINE BOOL LOS_IsRegionFlagPrivateOnly(LosVmMapRegion* region) +{ + return ((region->regionFlags & VM_MAP_REGION_FLAG_FLAG_MASK) == VM_MAP_REGION_FLAG_PRIVATE); +} + +STATIC INLINE VOID LOS_SetRegionTypeFile(LosVmMapRegion* region) +{ + region->regionType = VM_MAP_REGION_TYPE_FILE; +} + +STATIC INLINE BOOL LOS_IsRegionTypeDev(LosVmMapRegion* region) +{ + return region->regionType == VM_MAP_REGION_TYPE_DEV; +} + +STATIC INLINE VOID LOS_SetRegionTypeDev(LosVmMapRegion* region) +{ + region->regionType = VM_MAP_REGION_TYPE_DEV; +} + +STATIC INLINE BOOL LOS_IsRegionTypeAnon(LosVmMapRegion* region) +{ + return region->regionType == VM_MAP_REGION_TYPE_ANON; +} + +STATIC INLINE VOID LOS_SetRegionTypeAnon(LosVmMapRegion* region) +{ + region->regionType = VM_MAP_REGION_TYPE_ANON; +} + +STATIC INLINE BOOL LOS_IsUserAddress(VADDR_T vaddr) +{ + return ((vaddr >= USER_ASPACE_BASE) && + (vaddr <= (USER_ASPACE_BASE + (USER_ASPACE_SIZE - 1)))); +} + +STATIC INLINE BOOL LOS_IsUserAddressRange(VADDR_T vaddr, size_t len) +{ + return (vaddr + len > vaddr) && LOS_IsUserAddress(vaddr) && (LOS_IsUserAddress(vaddr + len - 1)); +} + +STATIC INLINE BOOL LOS_IsVmallocAddress(VADDR_T vaddr) +{ + return ((vaddr >= VMALLOC_START) && + (vaddr <= (VMALLOC_START + (VMALLOC_SIZE - 1)))); +} + +STATIC INLINE BOOL OsIsVmRegionEmpty(LosVmSpace *vmSpace) +{ + if (vmSpace->regionRbTree.ulNodes == 0) { + return TRUE; + } + return FALSE; +} + +LosVmSpace *LOS_GetKVmSpace(VOID); +LOS_DL_LIST *LOS_GetVmSpaceList(VOID); +LosVmSpace *LOS_GetVmallocSpace(VOID); +VOID OsInitMappingStartUp(VOID); +VOID OsKSpaceInit(VOID); +BOOL LOS_IsRangeInSpace(const LosVmSpace *space, VADDR_T vaddr, size_t size); +STATUS_T LOS_VmSpaceReserve(LosVmSpace *space, size_t size, VADDR_T vaddr); +INT32 OsUserHeapFree(LosVmSpace *vmSpace, VADDR_T addr, size_t len); +VADDR_T OsAllocRange(LosVmSpace *vmSpace, size_t len); +VADDR_T OsAllocSpecificRange(LosVmSpace *vmSpace, VADDR_T vaddr, size_t len, UINT32 regionFlags); +LosVmMapRegion *OsCreateRegion(VADDR_T vaddr, size_t len, UINT32 regionFlags, unsigned long offset); +BOOL OsInsertRegion(LosRbTree *regionRbTree, LosVmMapRegion *region); +LosVmSpace *LOS_SpaceGet(VADDR_T vaddr); +LosVmSpace *LOS_CurrSpaceGet(VOID); +BOOL LOS_IsRegionFileValid(LosVmMapRegion *region); +LosVmMapRegion *LOS_RegionRangeFind(LosVmSpace *vmSpace, VADDR_T addr, size_t len); +LosVmMapRegion *LOS_RegionFind(LosVmSpace *vmSpace, VADDR_T addr); +PADDR_T LOS_PaddrQuery(VOID *vaddr); +LosVmMapRegion *LOS_RegionAlloc(LosVmSpace *vmSpace, VADDR_T vaddr, size_t len, UINT32 regionFlags, VM_OFFSET_T pgoff); +STATUS_T OsRegionsRemove(LosVmSpace *space, VADDR_T vaddr, size_t size); +STATUS_T OsVmRegionAdjust(LosVmSpace *space, VADDR_T vaddr, size_t size); +LosVmMapRegion *OsVmRegionDup(LosVmSpace *space, LosVmMapRegion *oldRegion, VADDR_T vaddr, size_t size); +STATUS_T OsIsRegionCanExpand(LosVmSpace *space, LosVmMapRegion *region, size_t size); +STATUS_T LOS_RegionFree(LosVmSpace *space, LosVmMapRegion *region); +STATUS_T LOS_VmSpaceFree(LosVmSpace *space); +STATUS_T LOS_VaddrToPaddrMmap(LosVmSpace *space, VADDR_T vaddr, PADDR_T paddr, size_t len, UINT32 flags); +BOOL OsUserVmSpaceInit(LosVmSpace *vmSpace, VADDR_T *virtTtb); +LosVmSpace *OsCreateUserVmSpace(VOID); +STATUS_T LOS_VmSpaceClone(UINT32 cloneFlags, LosVmSpace *oldVmSpace, LosVmSpace *newVmSpace); +LosMux *OsGVmSpaceMuxGet(VOID); +STATUS_T OsUnMMap(LosVmSpace *space, VADDR_T addr, size_t size); +STATUS_T OsVmSpaceRegionFree(LosVmSpace *space); + +/** + * thread safety + * it is used to malloc continuous virtual memory, no sure for continuous physical memory. + */ +VOID *LOS_VMalloc(size_t size); +VOID LOS_VFree(const VOID *addr); + +/** + * thread safety + * these is used to malloc or free kernel memory. + * when the size is large and close to multiples of pages, + * will alloc pmm pages, otherwise alloc bestfit memory. + */ +VOID *LOS_KernelMalloc(UINT32 size); +VOID *LOS_KernelMallocAlign(UINT32 size, UINT32 boundary); +VOID *LOS_KernelRealloc(VOID *ptr, UINT32 size); +VOID LOS_KernelFree(VOID *ptr); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* __LOS_VM_MAP_H__ */ + diff --git a/src/kernel_liteos_a/kernel/base/include/los_vm_page.h b/src/kernel_liteos_a/kernel/base/include/los_vm_page.h new file mode 100644 index 00000000..c1aa9413 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_vm_page.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __LOS_VM_PAGE_H__ +#define __LOS_VM_PAGE_H__ + +#include "los_typedef.h" +#include "los_bitmap.h" +#include "los_list.h" +#include "los_atomic.h" +#include "los_spinlock.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef struct VmPage { + LOS_DL_LIST node; /**< vm object dl list */ + PADDR_T physAddr; /**< vm page physical addr */ + Atomic refCounts; /**< vm page ref count */ + UINT32 flags; /**< vm page flags */ + UINT8 order; /**< vm page in which order list */ + UINT8 segID; /**< the segment id of vm page */ + UINT16 nPages; /**< the vm page is used for kernel heap */ +#ifdef LOSCFG_PAGE_TABLE_FINE_LOCK + SPIN_LOCK_S lock; /**< lock for page table entry */ +#endif +} LosVmPage; + +extern LosVmPage *g_vmPageArray; +extern size_t g_vmPageArraySize; + +LosVmPage *LOS_VmPageGet(PADDR_T paddr); +VOID OsVmPageStartup(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* __LOS_VM_PAGE_H__ */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_vm_phys.h b/src/kernel_liteos_a/kernel/base/include/los_vm_phys.h new file mode 100644 index 00000000..75bcab08 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_vm_phys.h @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __LOS_VM_PHYS_H__ +#define __LOS_VM_PHYS_H__ + +#include "los_typedef.h" +#include "los_list.h" +#include "los_spinlock.h" +#include "los_vm_page.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define VM_LIST_ORDER_MAX 9 +#define VM_PHYS_SEG_MAX 32 + +#ifndef min +#define min(x, y) ((x) < (y) ? (x) : (y)) +#endif + +#define VM_PAGE_TO_PHYS(page) ((page)->physAddr) +#define VM_ORDER_TO_PAGES(order) (1 << (order)) +#define VM_ORDER_TO_PHYS(order) (1 << (PAGE_SHIFT + (order))) +#define VM_PHYS_TO_ORDER(phys) (min(LOS_LowBitGet((phys) >> PAGE_SHIFT), VM_LIST_ORDER_MAX - 1)) + +struct VmFreeList { + LOS_DL_LIST node; + UINT32 listCnt; +}; + +enum OsLruList { + VM_LRU_INACTIVE_ANON = 0, + VM_LRU_ACTIVE_ANON, + VM_LRU_INACTIVE_FILE, + VM_LRU_ACTIVE_FILE, + VM_LRU_UNEVICTABLE, + VM_NR_LRU_LISTS +}; + +typedef struct VmPhysSeg { + PADDR_T start; /* The start of physical memory area */ + size_t size; /* The size of physical memory area */ + LosVmPage *pageBase; /* The first page address of this area */ + + SPIN_LOCK_S freeListLock; /* The buddy list spinlock */ + struct VmFreeList freeList[VM_LIST_ORDER_MAX]; /* The free pages in the buddy list */ + + SPIN_LOCK_S lruLock; + size_t lruSize[VM_NR_LRU_LISTS]; + LOS_DL_LIST lruList[VM_NR_LRU_LISTS]; +} LosVmPhysSeg; + +struct VmPhysArea { + PADDR_T start; + size_t size; +}; + +extern struct VmPhysSeg g_vmPhysSeg[VM_PHYS_SEG_MAX]; +extern INT32 g_vmPhysSegNum; + +UINT32 OsVmPagesToOrder(size_t nPages); +struct VmPhysSeg *OsVmPhysSegGet(LosVmPage *page); +LosVmPhysSeg *OsGVmPhysSegGet(VOID); +VOID *OsVmPageToVaddr(LosVmPage *page); +VOID OsVmPhysSegAdd(VOID); +VOID OsVmPhysInit(VOID); +VOID OsVmPhysAreaSizeAdjust(size_t size); +UINT32 OsVmPhysPageNumGet(VOID); +LosVmPage *OsVmVaddrToPage(VOID *ptr); +VOID OsPhysSharePageCopy(PADDR_T oldPaddr, PADDR_T *newPaddr, LosVmPage *newPage); +VOID OsVmPhysPagesFreeContiguous(LosVmPage *page, size_t nPages); +LosVmPage *OsVmPhysToPage(paddr_t pa, UINT8 segID); +LosVmPage *OsVmPaddrToPage(paddr_t paddr); + +LosVmPage *LOS_PhysPageAlloc(VOID); +VOID LOS_PhysPageFree(LosVmPage *page); +size_t LOS_PhysPagesAlloc(size_t nPages, LOS_DL_LIST *list); +size_t LOS_PhysPagesFree(LOS_DL_LIST *list); +VOID *LOS_PhysPagesAllocContiguous(size_t nPages); +VOID LOS_PhysPagesFreeContiguous(VOID *ptr, size_t nPages); +VADDR_T *LOS_PaddrToKVaddr(PADDR_T paddr); +PADDR_T OsKVaddrToPaddr(VADDR_T kvaddr); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* __LOS_VM_PHYS_H__ */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_vm_shm_pri.h b/src/kernel_liteos_a/kernel/base/include/los_vm_shm_pri.h new file mode 100644 index 00000000..3320d569 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_vm_shm_pri.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __LOS_SHM_PRI_H__ +#define __LOS_SHM_PRI_H__ + +#include "los_typedef.h" +#include "los_vm_map.h" +#include "los_process_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/* The upper limit size of total shared memory is default 16M */ +#define SHM_MAX_PAGES 4096 +#define SHM_MAX (SHM_MAX_PAGES * PAGE_SIZE) +#define SHM_MIN 1 +#define SHM_MNI 192 +#define SHM_SEG 128 +#define SHM_ALL (SHM_MAX_PAGES) + +struct shmIDSource { + struct shmid_ds ds; + UINT32 status; + LOS_DL_LIST node; +#ifdef LOSCFG_SHELL + CHAR ownerName[OS_PCB_NAME_LEN]; +#endif +}; + +VOID OsShmFork(LosVmSpace *space, LosVmMapRegion *oldRegion, LosVmMapRegion *newRegion); +VOID OsShmRegionFree(LosVmSpace *space, LosVmMapRegion *region); +BOOL OsIsShmRegion(LosVmMapRegion *region); +struct shmIDSource *OsShmCBInit(LosMux *sysvShmMux, struct shminfo *shmInfo, UINT32 *shmUsedPageCount); +VOID OsShmCBDestroy(struct shmIDSource *shmSegs, struct shminfo *shmInfo, LosMux *sysvShmMux); +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* __LOS_SHM_PRI_H__ */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_vm_syscall.h b/src/kernel_liteos_a/kernel/base/include/los_vm_syscall.h new file mode 100644 index 00000000..dbcb3d12 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_vm_syscall.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_vm_syscall vm syscall definition + * @ingroup kernel + */ + +#ifndef __LOS_VM_SYSCALL_H__ +#define __LOS_VM_SYSCALL_H__ + +#include "sys/shm.h" +#include "sys/mman.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +STATIC INLINE BOOL LOS_IsNamedMapping(unsigned long flags) +{ + return ((flags & MAP_ANONYMOUS) == 0); +} + +STATIC INLINE BOOL LOS_IsAnonymousMapping(unsigned long flags) +{ + return ((flags & MAP_ANONYMOUS) == MAP_ANONYMOUS); +} + +VADDR_T LOS_MMap(VADDR_T vaddr, size_t len, unsigned prot, unsigned long flags, int fd, unsigned long pgoff); +STATUS_T LOS_UnMMap(VADDR_T addr, size_t size); +VOID *LOS_DoBrk(VOID *addr); +INT32 LOS_DoMprotect(VADDR_T vaddr, size_t len, unsigned long prot); +VADDR_T LOS_DoMremap(VADDR_T oldAddress, size_t oldSize, size_t newSize, int flags, VADDR_T newAddr); +VOID LOS_DumpMemRegion(VADDR_T vaddr); +UINT32 ShmInit(VOID); +UINT32 ShmDeinit(VOID); +INT32 ShmGet(key_t key, size_t size, INT32 shmflg); +VOID *ShmAt(INT32 shmid, const VOID *shmaddr, INT32 shmflg); +INT32 ShmCtl(INT32 shmid, INT32 cmd, struct shmid_ds *buf); +INT32 ShmDt(const VOID *shmaddr); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* __LOS_VM_SYSCALL_H__ */ diff --git a/src/kernel_liteos_a/kernel/base/include/los_vm_zone.h b/src/kernel_liteos_a/kernel/base/include/los_vm_zone.h new file mode 100644 index 00000000..3e3a9938 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/include/los_vm_zone.h @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __VM_ZONE_H__ +#define __VM_ZONE_H__ + +#include "target_config.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#ifdef LOSCFG_KERNEL_MMU +#ifdef LOSCFG_TEE_ENABLE +#define KERNEL_VADDR_BASE 0x41000000 +#else +#define KERNEL_VADDR_BASE 0x40000000 +#endif +#else +#define KERNEL_VADDR_BASE DDR_MEM_ADDR +#endif +#define KERNEL_VADDR_SIZE DDR_MEM_SIZE + +#define SYS_MEM_BASE DDR_MEM_ADDR +#define SYS_MEM_END (SYS_MEM_BASE + SYS_MEM_SIZE_DEFAULT) + +#define _U32_C(X) X##U +#define U32_C(X) _U32_C(X) + +#define KERNEL_VMM_BASE U32_C(KERNEL_VADDR_BASE) +#define KERNEL_VMM_SIZE U32_C(KERNEL_VADDR_SIZE) + +#define KERNEL_ASPACE_BASE KERNEL_VMM_BASE +#define KERNEL_ASPACE_SIZE KERNEL_VMM_SIZE + +/* Uncached vmm aspace */ +#define UNCACHED_VMM_BASE (KERNEL_VMM_BASE + KERNEL_VMM_SIZE) +#define UNCACHED_VMM_SIZE DDR_MEM_SIZE + +#define VMALLOC_START (UNCACHED_VMM_BASE + UNCACHED_VMM_SIZE) +#define VMALLOC_SIZE 0x08000000 + +#ifdef LOSCFG_KERNEL_MMU +#define PERIPH_DEVICE_BASE (VMALLOC_START + VMALLOC_SIZE) +#define PERIPH_DEVICE_SIZE U32_C(PERIPH_PMM_SIZE) +#define PERIPH_CACHED_BASE (PERIPH_DEVICE_BASE + PERIPH_DEVICE_SIZE) +#define PERIPH_CACHED_SIZE U32_C(PERIPH_PMM_SIZE) +#define PERIPH_UNCACHED_BASE (PERIPH_CACHED_BASE + PERIPH_CACHED_SIZE) +#define PERIPH_UNCACHED_SIZE U32_C(PERIPH_PMM_SIZE) +#else +#define PERIPH_DEVICE_BASE PERIPH_PMM_BASE +#define PERIPH_DEVICE_SIZE U32_C(PERIPH_PMM_SIZE) +#define PERIPH_CACHED_BASE PERIPH_PMM_BASE +#define PERIPH_CACHED_SIZE U32_C(PERIPH_PMM_SIZE) +#define PERIPH_UNCACHED_BASE PERIPH_PMM_BASE +#define PERIPH_UNCACHED_SIZE U32_C(PERIPH_PMM_SIZE) +#endif + +#define IO_DEVICE_ADDR(paddr) ((paddr) - PERIPH_PMM_BASE + PERIPH_DEVICE_BASE) +#define IO_CACHED_ADDR(paddr) ((paddr) - PERIPH_PMM_BASE + PERIPH_CACHED_BASE) +#define IO_UNCACHED_ADDR(paddr) ((paddr) - PERIPH_PMM_BASE + PERIPH_UNCACHED_BASE) + +#define MEM_CACHED_ADDR(paddr) ((paddr) - DDR_MEM_ADDR + KERNEL_VMM_BASE) +#define MEM_UNCACHED_ADDR(paddr) ((paddr) - DDR_MEM_ADDR + UNCACHED_VMM_BASE) + +#define VMM_TO_UNCACHED_ADDR(vaddr) ((vaddr) - KERNEL_VMM_BASE + UNCACHED_VMM_BASE) +#define UNCACHED_TO_VMM_ADDR(vaddr) ((vaddr) - UNCACHED_VMM_BASE + KERNEL_VMM_BASE) + +#define VMM_TO_DMA_ADDR(vaddr) ((vaddr) - KERNEL_VMM_BASE + SYS_MEM_BASE) +#define DMA_TO_VMM_ADDR(vaddr) ((vaddr) - SYS_MEM_BASE + KERNEL_VMM_BASE) + +#if (PERIPH_UNCACHED_BASE >= (0xFFFFFFFFU - PERIPH_UNCACHED_SIZE)) +#error "Kernel virtual memory space has overflowed!" +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/src/kernel_liteos_a/kernel/base/ipc/los_event.c b/src/kernel_liteos_a/kernel/base/ipc/los_event.c new file mode 100644 index 00000000..1503c7fb --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/ipc/los_event.c @@ -0,0 +1,343 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_event_pri.h" +#include "los_task_pri.h" +#include "los_spinlock.h" +#include "los_mp.h" +#include "los_percpu_pri.h" +#include "los_sched_pri.h" +#include "los_hook.h" +#ifdef LOSCFG_BASE_CORE_SWTMR_ENABLE +#include "los_exc.h" +#endif +/* +*/ +LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventInit(PEVENT_CB_S eventCB) +{ + UINT32 intSave; + + if (eventCB == NULL) { + return LOS_ERRNO_EVENT_PTR_NULL; + } + + intSave = LOS_IntLock(); + eventCB->uwEventID = 0; + LOS_ListInit(&eventCB->stEventList); + LOS_IntRestore(intSave); + OsHookCall(LOS_HOOK_TYPE_EVENT_INIT, eventCB); + return LOS_OK; +} + +LITE_OS_SEC_TEXT STATIC UINT32 OsEventParamCheck(const VOID *ptr, UINT32 eventMask, UINT32 mode) +{ + if (ptr == NULL) { + return LOS_ERRNO_EVENT_PTR_NULL; + } + + if (eventMask == 0) { + return LOS_ERRNO_EVENT_EVENTMASK_INVALID; + } + + if (eventMask & LOS_ERRTYPE_ERROR) { + return LOS_ERRNO_EVENT_SETBIT_INVALID; + } + + if (((mode & LOS_WAITMODE_OR) && (mode & LOS_WAITMODE_AND)) || + (mode & ~(LOS_WAITMODE_OR | LOS_WAITMODE_AND | LOS_WAITMODE_CLR)) || + !(mode & (LOS_WAITMODE_OR | LOS_WAITMODE_AND))) { + return LOS_ERRNO_EVENT_FLAGS_INVALID; + } + return LOS_OK; +} + +LITE_OS_SEC_TEXT UINT32 OsEventPoll(UINT32 *eventID, UINT32 eventMask, UINT32 mode) +{ + UINT32 ret = 0; + + LOS_ASSERT(OsIntLocked()); + LOS_ASSERT(LOS_SpinHeld(&g_taskSpin)); + + if (mode & LOS_WAITMODE_OR) { + if ((*eventID & eventMask) != 0) { + ret = *eventID & eventMask; + } + } else { + if ((eventMask != 0) && (eventMask == (*eventID & eventMask))) { + ret = *eventID & eventMask; + } + } + + if (ret && (mode & LOS_WAITMODE_CLR)) { + *eventID = *eventID & ~ret; + } + + return ret; +} + +LITE_OS_SEC_TEXT STATIC UINT32 OsEventReadCheck(const PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode) +{ + UINT32 ret; + LosTaskCB *runTask = NULL; + ret = OsEventParamCheck(eventCB, eventMask, mode); + if (ret != LOS_OK) { + return ret; + } + + if (OS_INT_ACTIVE) { + return LOS_ERRNO_EVENT_READ_IN_INTERRUPT; + } + + runTask = OsCurrTaskGet(); + if (runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) { + OsBackTrace(); + return LOS_ERRNO_EVENT_READ_IN_SYSTEM_TASK; + } + return LOS_OK; +} + +LITE_OS_SEC_TEXT STATIC UINT32 OsEventReadImp(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, + UINT32 timeout, BOOL once) +{ + UINT32 ret = 0; + LosTaskCB *runTask = OsCurrTaskGet(); + OsHookCall(LOS_HOOK_TYPE_EVENT_READ, eventCB, eventMask, mode, timeout); + + if (once == FALSE) { + ret = OsEventPoll(&eventCB->uwEventID, eventMask, mode); + } + + if (ret == 0) { + if (timeout == 0) { + return ret; + } + + if (!OsPreemptableInSched()) { + return LOS_ERRNO_EVENT_READ_IN_LOCK; + } + + runTask->eventMask = eventMask; + runTask->eventMode = mode; + runTask->taskEvent = eventCB; + OsTaskWaitSetPendMask(OS_TASK_WAIT_EVENT, eventMask, timeout); + ret = runTask->ops->wait(runTask, &eventCB->stEventList, timeout); + if (ret == LOS_ERRNO_TSK_TIMEOUT) { + return LOS_ERRNO_EVENT_READ_TIMEOUT; + } + + ret = OsEventPoll(&eventCB->uwEventID, eventMask, mode); + } + return ret; +} + +LITE_OS_SEC_TEXT STATIC UINT32 OsEventRead(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeout, + BOOL once) +{ + UINT32 ret; + UINT32 intSave; + + ret = OsEventReadCheck(eventCB, eventMask, mode); + if (ret != LOS_OK) { + return ret; + } + + SCHEDULER_LOCK(intSave); + ret = OsEventReadImp(eventCB, eventMask, mode, timeout, once); + SCHEDULER_UNLOCK(intSave); + return ret; +} + +LITE_OS_SEC_TEXT STATIC UINT8 OsEventResume(LosTaskCB *resumedTask, const PEVENT_CB_S eventCB, UINT32 events) +{ + UINT8 exitFlag = 0; + + if (((resumedTask->eventMode & LOS_WAITMODE_OR) && ((resumedTask->eventMask & events) != 0)) || + ((resumedTask->eventMode & LOS_WAITMODE_AND) && + ((resumedTask->eventMask & eventCB->uwEventID) == resumedTask->eventMask))) { + exitFlag = 1; + + resumedTask->taskEvent = NULL; + OsTaskWakeClearPendMask(resumedTask); + resumedTask->ops->wake(resumedTask); + } + + return exitFlag; +} + +LITE_OS_SEC_TEXT VOID OsEventWriteUnsafe(PEVENT_CB_S eventCB, UINT32 events, BOOL once, UINT8 *exitFlag) +{ + LosTaskCB *resumedTask = NULL; + LosTaskCB *nextTask = NULL; + BOOL schedFlag = FALSE; + OsHookCall(LOS_HOOK_TYPE_EVENT_WRITE, eventCB, events); + eventCB->uwEventID |= events; + if (!LOS_ListEmpty(&eventCB->stEventList)) { + for (resumedTask = LOS_DL_LIST_ENTRY((&eventCB->stEventList)->pstNext, LosTaskCB, pendList); + &resumedTask->pendList != &eventCB->stEventList;) { + nextTask = LOS_DL_LIST_ENTRY(resumedTask->pendList.pstNext, LosTaskCB, pendList); + if (OsEventResume(resumedTask, eventCB, events)) { + schedFlag = TRUE; + } + if (once == TRUE) { + break; + } + resumedTask = nextTask; + } + } + + if ((exitFlag != NULL) && (schedFlag == TRUE)) { + *exitFlag = 1; + } +} + +LITE_OS_SEC_TEXT STATIC UINT32 OsEventWrite(PEVENT_CB_S eventCB, UINT32 events, BOOL once) +{ + UINT32 intSave; + UINT8 exitFlag = 0; + + if (eventCB == NULL) { + return LOS_ERRNO_EVENT_PTR_NULL; + } + + if (events & LOS_ERRTYPE_ERROR) { + return LOS_ERRNO_EVENT_SETBIT_INVALID; + } + + SCHEDULER_LOCK(intSave); + OsEventWriteUnsafe(eventCB, events, once, &exitFlag); + SCHEDULER_UNLOCK(intSave); + + if (exitFlag == 1) { + LOS_MpSchedule(OS_MP_CPU_ALL); + LOS_Schedule(); + } + return LOS_OK; +} + +LITE_OS_SEC_TEXT UINT32 LOS_EventPoll(UINT32 *eventID, UINT32 eventMask, UINT32 mode) +{ + UINT32 ret; + UINT32 intSave; + + ret = OsEventParamCheck((VOID *)eventID, eventMask, mode); + if (ret != LOS_OK) { + return ret; + } + + SCHEDULER_LOCK(intSave); + ret = OsEventPoll(eventID, eventMask, mode); + SCHEDULER_UNLOCK(intSave); + return ret; +} + +LITE_OS_SEC_TEXT UINT32 LOS_EventRead(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeout) +{ + return OsEventRead(eventCB, eventMask, mode, timeout, FALSE); +} + +LITE_OS_SEC_TEXT UINT32 LOS_EventWrite(PEVENT_CB_S eventCB, UINT32 events) +{ + return OsEventWrite(eventCB, events, FALSE); +} + +LITE_OS_SEC_TEXT_MINOR UINT32 OsEventReadOnce(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, + UINT32 timeout) +{ + return OsEventRead(eventCB, eventMask, mode, timeout, TRUE); +} + +LITE_OS_SEC_TEXT_MINOR UINT32 OsEventWriteOnce(PEVENT_CB_S eventCB, UINT32 events) +{ + return OsEventWrite(eventCB, events, TRUE); +} + +LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventDestroy(PEVENT_CB_S eventCB) +{ + UINT32 intSave; + + if (eventCB == NULL) { + return LOS_ERRNO_EVENT_PTR_NULL; + } + + SCHEDULER_LOCK(intSave); + if (!LOS_ListEmpty(&eventCB->stEventList)) { + SCHEDULER_UNLOCK(intSave); + return LOS_ERRNO_EVENT_SHOULD_NOT_DESTROY; + } + + eventCB->uwEventID = 0; + LOS_ListDelInit(&eventCB->stEventList); + SCHEDULER_UNLOCK(intSave); + OsHookCall(LOS_HOOK_TYPE_EVENT_DESTROY, eventCB); + return LOS_OK; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_EventClear(PEVENT_CB_S eventCB, UINT32 eventMask) +{ + UINT32 intSave; + + if (eventCB == NULL) { + return LOS_ERRNO_EVENT_PTR_NULL; + } + OsHookCall(LOS_HOOK_TYPE_EVENT_CLEAR, eventCB, eventMask); + SCHEDULER_LOCK(intSave); + eventCB->uwEventID &= eventMask; + SCHEDULER_UNLOCK(intSave); + + return LOS_OK; +} + +#ifdef LOSCFG_COMPAT_POSIX +LITE_OS_SEC_TEXT UINT32 OsEventReadWithCond(const EventCond *cond, PEVENT_CB_S eventCB, + UINT32 eventMask, UINT32 mode, UINT32 timeout) +{ + UINT32 ret; + UINT32 intSave; + + ret = OsEventReadCheck(eventCB, eventMask, mode); + if (ret != LOS_OK) { + return ret; + } + + SCHEDULER_LOCK(intSave); + + if (*cond->realValue != cond->value) { + eventCB->uwEventID &= cond->clearEvent; + goto OUT; + } + + ret = OsEventReadImp(eventCB, eventMask, mode, timeout, FALSE); +OUT: + SCHEDULER_UNLOCK(intSave); + return ret; +} +#endif + diff --git a/src/kernel_liteos_a/kernel/base/ipc/los_futex.c b/src/kernel_liteos_a/kernel/base/ipc/los_futex.c new file mode 100644 index 00000000..384bb483 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/ipc/los_futex.c @@ -0,0 +1,1014 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_futex_pri.h" +#include "los_exc.h" +#include "los_hash.h" +#include "los_init.h" +#include "los_process_pri.h" +#include "los_sched_pri.h" +#include "los_sys_pri.h" +#include "los_mp.h" +#include "los_mux_pri.h" +#include "user_copy.h" + + +#ifdef LOSCFG_KERNEL_VM + +#define OS_FUTEX_FROM_FUTEXLIST(ptr) LOS_DL_LIST_ENTRY(ptr, FutexNode, futexList) +#define OS_FUTEX_FROM_QUEUELIST(ptr) LOS_DL_LIST_ENTRY(ptr, FutexNode, queueList) +#define OS_FUTEX_KEY_BASE USER_ASPACE_BASE +#define OS_FUTEX_KEY_MAX (USER_ASPACE_BASE + USER_ASPACE_SIZE) + +/* private: 0~63 hash index_num + * shared: 64~79 hash index_num */ +#define FUTEX_INDEX_PRIVATE_MAX 64 +#define FUTEX_INDEX_SHARED_MAX 16 +#define FUTEX_INDEX_MAX (FUTEX_INDEX_PRIVATE_MAX + FUTEX_INDEX_SHARED_MAX) + +#define FUTEX_INDEX_SHARED_POS FUTEX_INDEX_PRIVATE_MAX +#define FUTEX_HASH_PRIVATE_MASK (FUTEX_INDEX_PRIVATE_MAX - 1) +#define FUTEX_HASH_SHARED_MASK (FUTEX_INDEX_SHARED_MAX - 1) + +typedef struct { + LosMux listLock; + LOS_DL_LIST lockList; +} FutexHash; + +FutexHash g_futexHash[FUTEX_INDEX_MAX]; + +STATIC INT32 OsFutexLock(LosMux *lock) +{ + UINT32 ret = LOS_MuxLock(lock, LOS_WAIT_FOREVER); + if (ret != LOS_OK) { + PRINT_ERR("Futex lock failed! ERROR: 0x%x!\n", ret); + return LOS_EINVAL; + } + return LOS_OK; +} + +STATIC INT32 OsFutexUnlock(LosMux *lock) +{ + UINT32 ret = LOS_MuxUnlock(lock); + if (ret != LOS_OK) { + PRINT_ERR("Futex unlock failed! ERROR: 0x%x!\n", ret); + return LOS_EINVAL; + } + return LOS_OK; +} + +UINT32 OsFutexInit(VOID) +{ + INT32 count; + UINT32 ret; + + for (count = 0; count < FUTEX_INDEX_MAX; count++) { + LOS_ListInit(&g_futexHash[count].lockList); + ret = LOS_MuxInit(&(g_futexHash[count].listLock), NULL); + if (ret) { + return ret; + } + } + + return LOS_OK; +} + +LOS_MODULE_INIT(OsFutexInit, LOS_INIT_LEVEL_KMOD_EXTENDED); + +#ifdef LOS_FUTEX_DEBUG +STATIC VOID OsFutexShowTaskNodeAttr(const LOS_DL_LIST *futexList) +{ + FutexNode *tempNode = NULL; + FutexNode *lastNode = NULL; + LosTaskCB *taskCB = NULL; + LOS_DL_LIST *queueList = NULL; + + tempNode = OS_FUTEX_FROM_FUTEXLIST(futexList); + PRINTK("key(pid) : 0x%x(%u) : ->", tempNode->key, tempNode->pid); + + for (queueList = &tempNode->queueList; ;) { + lastNode = OS_FUTEX_FROM_QUEUELIST(queueList); + if (!LOS_ListEmpty(&(lastNode->pendList))) { + taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(lastNode->pendList))); + PRINTK(" %u ->", taskCB->taskID); + } else { + taskCB = LOS_DL_LIST_ENTRY(lastNode, LosTaskCB, futex); + PRINTK(" %u ->", taskCB->taskID); + } + queueList = queueList->pstNext; + if (queueList == &tempNode->queueList) { + break; + } + } + PRINTK("\n"); +} + +VOID OsFutexHashShow(VOID) +{ + LOS_DL_LIST *futexList = NULL; + INT32 count; + /* The maximum number of barrels of a hash table */ + INT32 hashNodeMax = FUTEX_INDEX_MAX; + PRINTK("#################### los_futex_pri.hash ####################\n"); + for (count = 0; count < hashNodeMax; count++) { + futexList = &(g_futexHash[count].lockList); + if (LOS_ListEmpty(futexList)) { + continue; + } + PRINTK("hash -> index : %d\n", count); + for (futexList = futexList->pstNext; + futexList != &(g_futexHash[count].lockList); + futexList = futexList->pstNext) { + OsFutexShowTaskNodeAttr(futexList); + } + } +} +#endif + +STATIC INLINE UINTPTR OsFutexFlagsToKey(const UINT32 *userVaddr, const UINT32 flags) +{ + UINTPTR futexKey; + + if (flags & FUTEX_PRIVATE) { + futexKey = (UINTPTR)userVaddr; + } else { + futexKey = (UINTPTR)LOS_PaddrQuery((UINT32 *)userVaddr); + } + + return futexKey; +} + +STATIC INLINE UINT32 OsFutexKeyToIndex(const UINTPTR futexKey, const UINT32 flags) +{ + UINT32 index = LOS_HashFNV32aBuf(&futexKey, sizeof(UINTPTR), FNV1_32A_INIT); + + if (flags & FUTEX_PRIVATE) { + index &= FUTEX_HASH_PRIVATE_MASK; + } else { + index &= FUTEX_HASH_SHARED_MASK; + index += FUTEX_INDEX_SHARED_POS; + } + + return index; +} + +STATIC INLINE VOID OsFutexSetKey(UINTPTR futexKey, UINT32 flags, FutexNode *node) +{ + node->key = futexKey; + node->index = OsFutexKeyToIndex(futexKey, flags); + node->pid = (flags & FUTEX_PRIVATE) ? LOS_GetCurrProcessID() : OS_INVALID; +} + +STATIC INLINE VOID OsFutexDeinitFutexNode(FutexNode *node) +{ + node->index = OS_INVALID_VALUE; + node->pid = 0; + LOS_ListDelete(&node->queueList); +} + +STATIC INLINE VOID OsFutexReplaceQueueListHeadNode(FutexNode *oldHeadNode, FutexNode *newHeadNode) +{ + LOS_DL_LIST *futexList = oldHeadNode->futexList.pstPrev; + LOS_ListDelete(&oldHeadNode->futexList); + LOS_ListHeadInsert(futexList, &newHeadNode->futexList); + if ((newHeadNode->queueList.pstNext == NULL) || (newHeadNode->queueList.pstPrev == NULL)) { + LOS_ListInit(&newHeadNode->queueList); + } +} + +STATIC INLINE VOID OsFutexDeleteKeyFromFutexList(FutexNode *node) +{ + LOS_ListDelete(&node->futexList); +} + +STATIC VOID OsFutexDeleteKeyNodeFromHash(FutexNode *node, BOOL isDeleteHead, FutexNode **headNode, BOOL *queueFlags) +{ + FutexNode *nextNode = NULL; + + if (node->index >= FUTEX_INDEX_MAX) { + return; + } + + if (LOS_ListEmpty(&node->queueList)) { + OsFutexDeleteKeyFromFutexList(node); + if (queueFlags != NULL) { + *queueFlags = TRUE; + } + goto EXIT; + } + + /* FutexList is not NULL, but the header node of queueList */ + if (node->futexList.pstNext != NULL) { + if (isDeleteHead == TRUE) { + nextNode = OS_FUTEX_FROM_QUEUELIST(LOS_DL_LIST_FIRST(&node->queueList)); + OsFutexReplaceQueueListHeadNode(node, nextNode); + if (headNode != NULL) { + *headNode = nextNode; + } + } else { + return; + } + } + +EXIT: + OsFutexDeinitFutexNode(node); + return; +} + +VOID OsFutexNodeDeleteFromFutexHash(FutexNode *node, BOOL isDeleteHead, FutexNode **headNode, BOOL *queueFlags) +{ + FutexHash *hashNode = NULL; + + UINT32 index = OsFutexKeyToIndex(node->key, (node->pid == OS_INVALID) ? 0 : FUTEX_PRIVATE); + if (index >= FUTEX_INDEX_MAX) { + return; + } + + hashNode = &g_futexHash[index]; + if (OsMuxLockUnsafe(&hashNode->listLock, LOS_WAIT_FOREVER)) { + return; + } + + if (node->index != index) { + goto EXIT; + } + + OsFutexDeleteKeyNodeFromHash(node, isDeleteHead, headNode, queueFlags); + +EXIT: + if (OsMuxUnlockUnsafe(OsCurrTaskGet(), &hashNode->listLock, NULL)) { + return; + } + + return; +} + +STATIC FutexNode *OsFutexDeleteAlreadyWakeTaskAndGetNext(const FutexNode *node, FutexNode **headNode, BOOL isDeleteHead) +{ + FutexNode *tempNode = (FutexNode *)node; + FutexNode *nextNode = NULL; + BOOL queueFlag = FALSE; + + while (LOS_ListEmpty(&(tempNode->pendList))) { /* already weak */ + if (!LOS_ListEmpty(&(tempNode->queueList))) { /* It's not a head node */ + nextNode = OS_FUTEX_FROM_QUEUELIST(LOS_DL_LIST_FIRST(&(tempNode->queueList))); + } + + OsFutexDeleteKeyNodeFromHash(tempNode, isDeleteHead, headNode, &queueFlag); + if (queueFlag) { + return NULL; + } + + tempNode = nextNode; + } + + return tempNode; +} + +STATIC VOID OsFutexInsertNewFutexKeyToHash(FutexNode *node) +{ + FutexNode *headNode = NULL; + FutexNode *tailNode = NULL; + LOS_DL_LIST *futexList = NULL; + FutexHash *hashNode = &g_futexHash[node->index]; + + if (LOS_ListEmpty(&hashNode->lockList)) { + LOS_ListHeadInsert(&(hashNode->lockList), &(node->futexList)); + goto EXIT; + } + + headNode = OS_FUTEX_FROM_FUTEXLIST(LOS_DL_LIST_FIRST(&(hashNode->lockList))); + /* The small key is at the front of the queue */ + if (node->key < headNode->key) { + LOS_ListHeadInsert(&(hashNode->lockList), &(node->futexList)); + goto EXIT; + } + + tailNode = OS_FUTEX_FROM_FUTEXLIST(LOS_DL_LIST_LAST(&(hashNode->lockList))); + if (node->key > tailNode->key) { + LOS_ListTailInsert(&(hashNode->lockList), &(node->futexList)); + goto EXIT; + } + + for (futexList = hashNode->lockList.pstNext; + futexList != &(hashNode->lockList); + futexList = futexList->pstNext) { + headNode = OS_FUTEX_FROM_FUTEXLIST(futexList); + if (node->key <= headNode->key) { + LOS_ListTailInsert(&(headNode->futexList), &(node->futexList)); + break; + } + } + +EXIT: + return; +} + +STATIC INT32 OsFutexInsertFindFormBackToFront(LOS_DL_LIST *queueList, const LosTaskCB *runTask, FutexNode *node) +{ + LOS_DL_LIST *listHead = queueList; + LOS_DL_LIST *listTail = queueList->pstPrev; + + for (; listHead != listTail; listTail = listTail->pstPrev) { + FutexNode *tempNode = OS_FUTEX_FROM_QUEUELIST(listTail); + tempNode = OsFutexDeleteAlreadyWakeTaskAndGetNext(tempNode, NULL, FALSE); + if (tempNode == NULL) { + return LOS_NOK; + } + LosTaskCB *taskTail = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(tempNode->pendList))); + INT32 ret = OsSchedParamCompare(runTask, taskTail); + if (ret >= 0) { + LOS_ListHeadInsert(&(tempNode->queueList), &(node->queueList)); + return LOS_OK; + } else { + if (listTail->pstPrev == listHead) { + LOS_ListTailInsert(&(tempNode->queueList), &(node->queueList)); + return LOS_OK; + } + } + } + + return LOS_NOK; +} + +STATIC INT32 OsFutexInsertFindFromFrontToBack(LOS_DL_LIST *queueList, const LosTaskCB *runTask, FutexNode *node) +{ + LOS_DL_LIST *listHead = queueList; + LOS_DL_LIST *listTail = queueList->pstPrev; + + for (; listHead != listTail; listHead = listHead->pstNext) { + FutexNode *tempNode = OS_FUTEX_FROM_QUEUELIST(listHead); + tempNode = OsFutexDeleteAlreadyWakeTaskAndGetNext(tempNode, NULL, FALSE); + if (tempNode == NULL) { + return LOS_NOK; + } + LosTaskCB *taskHead = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(tempNode->pendList))); + /* High priority comes before low priority, + * in the case of the same priority, after the current node + */ + INT32 ret = OsSchedParamCompare(runTask, taskHead); + if (ret >= 0) { + if (listHead->pstNext == listTail) { + LOS_ListHeadInsert(&(tempNode->queueList), &(node->queueList)); + return LOS_OK; + } + continue; + } else { + LOS_ListTailInsert(&(tempNode->queueList), &(node->queueList)); + return LOS_OK; + } + } + + return LOS_NOK; +} + +STATIC INT32 OsFutexRecycleAndFindHeadNode(FutexNode *headNode, FutexNode *node, FutexNode **firstNode) +{ + UINT32 intSave; + + SCHEDULER_LOCK(intSave); + *firstNode = OsFutexDeleteAlreadyWakeTaskAndGetNext(headNode, NULL, TRUE); + SCHEDULER_UNLOCK(intSave); + + /* The head node is removed and there was originally only one node under the key */ + if (*firstNode == NULL) { + OsFutexInsertNewFutexKeyToHash(node); + LOS_ListInit(&(node->queueList)); + return LOS_OK; + } + + return LOS_OK; +} + +STATIC INT32 OsFutexInsertTasktoPendList(FutexNode **firstNode, FutexNode *node, const LosTaskCB *run) +{ + LosTaskCB *taskHead = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&((*firstNode)->pendList))); + LOS_DL_LIST *queueList = &((*firstNode)->queueList); + + INT32 ret1 = OsSchedParamCompare(run, taskHead); + if (ret1 < 0) { + /* The one with the highest priority is inserted at the top of the queue */ + LOS_ListTailInsert(queueList, &(node->queueList)); + OsFutexReplaceQueueListHeadNode(*firstNode, node); + *firstNode = node; + return LOS_OK; + } + + if (LOS_ListEmpty(queueList) && (ret1 >= 0)) { + /* Insert the next position in the queue with equal priority */ + LOS_ListHeadInsert(queueList, &(node->queueList)); + return LOS_OK; + } + + FutexNode *tailNode = OS_FUTEX_FROM_QUEUELIST(LOS_DL_LIST_LAST(queueList)); + LosTaskCB *taskTail = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(tailNode->pendList))); + INT32 ret2 = OsSchedParamCompare(taskTail, run); + if ((ret2 <= 0) || (ret1 > ret2)) { + return OsFutexInsertFindFormBackToFront(queueList, run, node); + } + + return OsFutexInsertFindFromFrontToBack(queueList, run, node); +} + +STATIC FutexNode *OsFindFutexNode(const FutexNode *node) +{ + FutexHash *hashNode = &g_futexHash[node->index]; + LOS_DL_LIST *futexList = &(hashNode->lockList); + FutexNode *headNode = NULL; + + for (futexList = futexList->pstNext; + futexList != &(hashNode->lockList); + futexList = futexList->pstNext) { + headNode = OS_FUTEX_FROM_FUTEXLIST(futexList); + if ((headNode->key == node->key) && (headNode->pid == node->pid)) { + return headNode; + } + } + + return NULL; +} + +STATIC INT32 OsFindAndInsertToHash(FutexNode *node) +{ + FutexNode *headNode = NULL; + FutexNode *firstNode = NULL; + UINT32 intSave; + INT32 ret; + + headNode = OsFindFutexNode(node); + if (headNode == NULL) { + OsFutexInsertNewFutexKeyToHash(node); + LOS_ListInit(&(node->queueList)); + return LOS_OK; + } + + ret = OsFutexRecycleAndFindHeadNode(headNode, node, &firstNode); + if (ret != LOS_OK) { + return ret; + } else if (firstNode == NULL) { + return ret; + } + + SCHEDULER_LOCK(intSave); + ret = OsFutexInsertTasktoPendList(&firstNode, node, OsCurrTaskGet()); + SCHEDULER_UNLOCK(intSave); + + return ret; +} + +STATIC INT32 OsFutexKeyShmPermCheck(const UINT32 *userVaddr, const UINT32 flags) +{ + PADDR_T paddr; + + /* Check whether the futexKey is a shared lock */ + if (!(flags & FUTEX_PRIVATE)) { + paddr = (UINTPTR)LOS_PaddrQuery((UINT32 *)userVaddr); + if (paddr == 0) return LOS_NOK; + } + + return LOS_OK; +} + +STATIC INT32 OsFutexWaitParamCheck(const UINT32 *userVaddr, UINT32 flags, UINT32 absTime) +{ + VADDR_T vaddr = (VADDR_T)(UINTPTR)userVaddr; + + if (OS_INT_ACTIVE) { + return LOS_EINTR; + } + + if (flags & (~FUTEX_PRIVATE)) { + PRINT_ERR("Futex wait param check failed! error flags: 0x%x\n", flags); + return LOS_EINVAL; + } + + if ((vaddr % sizeof(INT32)) || (vaddr < OS_FUTEX_KEY_BASE) || (vaddr >= OS_FUTEX_KEY_MAX)) { + PRINT_ERR("Futex wait param check failed! error userVaddr: 0x%x\n", vaddr); + return LOS_EINVAL; + } + + if (flags && (OsFutexKeyShmPermCheck(userVaddr, flags) != LOS_OK)) { + PRINT_ERR("Futex wait param check failed! error shared memory perm userVaddr: 0x%x\n", userVaddr); + return LOS_EINVAL; + } + + if (!absTime) { + return LOS_ETIMEDOUT; + } + + return LOS_OK; +} + +STATIC INT32 OsFutexDeleteTimeoutTaskNode(FutexHash *hashNode, FutexNode *node) +{ + UINT32 intSave; + if (OsFutexLock(&hashNode->listLock)) { + return LOS_EINVAL; + } + + if (node->index < FUTEX_INDEX_MAX) { + SCHEDULER_LOCK(intSave); + (VOID)OsFutexDeleteAlreadyWakeTaskAndGetNext(node, NULL, TRUE); + SCHEDULER_UNLOCK(intSave); + } + +#ifdef LOS_FUTEX_DEBUG + OsFutexHashShow(); +#endif + + if (OsFutexUnlock(&hashNode->listLock)) { + return LOS_EINVAL; + } + return LOS_ETIMEDOUT; +} + +STATIC INT32 OsFutexInsertTaskToHash(LosTaskCB **taskCB, FutexNode **node, const UINTPTR futexKey, const UINT32 flags) +{ + INT32 ret; + *taskCB = OsCurrTaskGet(); + *node = &((*taskCB)->futex); + OsFutexSetKey(futexKey, flags, *node); + + ret = OsFindAndInsertToHash(*node); + if (ret) { + return LOS_NOK; + } + + LOS_ListInit(&((*node)->pendList)); + return LOS_OK; +} + +STATIC INT32 OsFutexWaitTask(const UINT32 *userVaddr, const UINT32 flags, const UINT32 val, const UINT32 timeout) +{ + INT32 futexRet; + UINT32 intSave, lockVal; + LosTaskCB *taskCB = NULL; + FutexNode *node = NULL; + UINTPTR futexKey = OsFutexFlagsToKey(userVaddr, flags); + UINT32 index = OsFutexKeyToIndex(futexKey, flags); + FutexHash *hashNode = &g_futexHash[index]; + + if (OsFutexLock(&hashNode->listLock)) { + return LOS_EINVAL; + } + + if (LOS_ArchCopyFromUser(&lockVal, userVaddr, sizeof(UINT32))) { + PRINT_ERR("Futex wait param check failed! copy from user failed!\n"); + futexRet = LOS_EINVAL; + goto EXIT_ERR; + } + + if (lockVal != val) { + futexRet = LOS_EBADF; + goto EXIT_ERR; + } + + if (OsFutexInsertTaskToHash(&taskCB, &node, futexKey, flags)) { + futexRet = LOS_NOK; + goto EXIT_ERR; + } + + SCHEDULER_LOCK(intSave); + OsSchedLock(); + OsTaskWaitSetPendMask(OS_TASK_WAIT_FUTEX, futexKey, timeout); + taskCB->ops->wait(taskCB, &(node->pendList), timeout); + LOS_SpinUnlock(&g_taskSpin); + + futexRet = OsFutexUnlock(&hashNode->listLock); + if (futexRet) { + OsSchedUnlock(); + LOS_IntRestore(intSave); + goto EXIT_UNLOCK_ERR; + } + + LOS_SpinLock(&g_taskSpin); + OsSchedUnlock(); + + /* + * it will immediately do the scheduling, so there's no need to release the + * task spinlock. when this task's been rescheduled, it will be holding the spinlock. + */ + OsSchedResched(); + + if (taskCB->taskStatus & OS_TASK_STATUS_TIMEOUT) { + taskCB->taskStatus &= ~OS_TASK_STATUS_TIMEOUT; + SCHEDULER_UNLOCK(intSave); + return OsFutexDeleteTimeoutTaskNode(hashNode, node); + } + + SCHEDULER_UNLOCK(intSave); + return LOS_OK; + +EXIT_ERR: + (VOID)OsFutexUnlock(&hashNode->listLock); +EXIT_UNLOCK_ERR: + return futexRet; +} + +INT32 OsFutexWait(const UINT32 *userVaddr, UINT32 flags, UINT32 val, UINT32 absTime) +{ + INT32 ret; + UINT32 timeout = LOS_WAIT_FOREVER; + + ret = OsFutexWaitParamCheck(userVaddr, flags, absTime); + if (ret) { + return ret; + } + if (absTime != LOS_WAIT_FOREVER) { + timeout = OsNS2Tick((UINT64)absTime * OS_SYS_NS_PER_US); + } + + return OsFutexWaitTask(userVaddr, flags, val, timeout); +} + +STATIC INT32 OsFutexWakeParamCheck(const UINT32 *userVaddr, UINT32 flags) +{ + VADDR_T vaddr = (VADDR_T)(UINTPTR)userVaddr; + + if ((flags & (~FUTEX_PRIVATE)) != FUTEX_WAKE) { + PRINT_ERR("Futex wake param check failed! error flags: 0x%x\n", flags); + return LOS_EINVAL; + } + + if ((vaddr % sizeof(INT32)) || (vaddr < OS_FUTEX_KEY_BASE) || (vaddr >= OS_FUTEX_KEY_MAX)) { + PRINT_ERR("Futex wake param check failed! error userVaddr: 0x%x\n", userVaddr); + return LOS_EINVAL; + } + + if (flags && (OsFutexKeyShmPermCheck(userVaddr, flags) != LOS_OK)) { + PRINT_ERR("Futex wake param check failed! error shared memory perm userVaddr: 0x%x\n", userVaddr); + return LOS_EINVAL; + } + + return LOS_OK; +} + +/* Check to see if the task to be awakened has timed out + * if time out, to weak next pend task. + */ +STATIC VOID OsFutexCheckAndWakePendTask(FutexNode *headNode, const INT32 wakeNumber, + FutexHash *hashNode, FutexNode **nextNode, BOOL *wakeAny) +{ + INT32 count; + LosTaskCB *taskCB = NULL; + FutexNode *node = headNode; + for (count = 0; count < wakeNumber; count++) { + /* Ensure the integrity of the head */ + *nextNode = OsFutexDeleteAlreadyWakeTaskAndGetNext(node, NULL, FALSE); + if (*nextNode == NULL) { + /* The last node in queuelist is invalid or the entire list is invalid */ + return; + } + node = *nextNode; + taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(node->pendList))); + OsTaskWakeClearPendMask(taskCB); + taskCB->ops->wake(taskCB); + *wakeAny = TRUE; + *nextNode = OS_FUTEX_FROM_QUEUELIST(LOS_DL_LIST_FIRST(&(node->queueList))); + if (node != headNode) { + OsFutexDeinitFutexNode(node); + } + + if (LOS_ListEmpty(&headNode->queueList)) { + /* Wakes up the entire linked list node */ + *nextNode = NULL; + return; + } + + node = *nextNode; + } + return; +} + +STATIC INT32 OsFutexWakeTask(UINTPTR futexKey, UINT32 flags, INT32 wakeNumber, FutexNode **newHeadNode, BOOL *wakeAny) +{ + UINT32 intSave; + FutexNode *node = NULL; + FutexNode *headNode = NULL; + UINT32 index = OsFutexKeyToIndex(futexKey, flags); + FutexHash *hashNode = &g_futexHash[index]; + FutexNode tempNode = { + .key = futexKey, + .index = index, + .pid = (flags & FUTEX_PRIVATE) ? LOS_GetCurrProcessID() : OS_INVALID, + }; + + node = OsFindFutexNode(&tempNode); + if (node == NULL) { + return LOS_EBADF; + } + + headNode = node; + + SCHEDULER_LOCK(intSave); + OsFutexCheckAndWakePendTask(headNode, wakeNumber, hashNode, newHeadNode, wakeAny); + if ((*newHeadNode) != NULL) { + OsFutexReplaceQueueListHeadNode(headNode, *newHeadNode); + OsFutexDeinitFutexNode(headNode); + } else if (headNode->index < FUTEX_INDEX_MAX) { + OsFutexDeleteKeyFromFutexList(headNode); + OsFutexDeinitFutexNode(headNode); + } + SCHEDULER_UNLOCK(intSave); + + return LOS_OK; +} + +INT32 OsFutexWake(const UINT32 *userVaddr, UINT32 flags, INT32 wakeNumber) +{ + INT32 ret, futexRet; + UINTPTR futexKey; + UINT32 index; + FutexHash *hashNode = NULL; + FutexNode *headNode = NULL; + BOOL wakeAny = FALSE; + + if (OsFutexWakeParamCheck(userVaddr, flags)) { + return LOS_EINVAL; + } + + futexKey = OsFutexFlagsToKey(userVaddr, flags); + index = OsFutexKeyToIndex(futexKey, flags); + + hashNode = &g_futexHash[index]; + if (OsFutexLock(&hashNode->listLock)) { + return LOS_EINVAL; + } + + ret = OsFutexWakeTask(futexKey, flags, wakeNumber, &headNode, &wakeAny); + if (ret) { + goto EXIT_ERR; + } + +#ifdef LOS_FUTEX_DEBUG + OsFutexHashShow(); +#endif + + futexRet = OsFutexUnlock(&hashNode->listLock); + if (futexRet) { + goto EXIT_UNLOCK_ERR; + } + + if (wakeAny == TRUE) { + LOS_MpSchedule(OS_MP_CPU_ALL); + LOS_Schedule(); + } + + return LOS_OK; + +EXIT_ERR: + futexRet = OsFutexUnlock(&hashNode->listLock); +EXIT_UNLOCK_ERR: + if (futexRet) { + return futexRet; + } + return ret; +} + +STATIC INT32 OsFutexRequeueInsertNewKey(UINTPTR newFutexKey, INT32 newIndex, FutexNode *oldHeadNode) +{ + BOOL queueListIsEmpty = FALSE; + INT32 ret; + UINT32 intSave; + LosTaskCB *task = NULL; + FutexNode *nextNode = NULL; + FutexNode newTempNode = { + .key = newFutexKey, + .index = newIndex, + .pid = (newIndex < FUTEX_INDEX_SHARED_POS) ? LOS_GetCurrProcessID() : OS_INVALID, + }; + LOS_DL_LIST *queueList = &oldHeadNode->queueList; + FutexNode *newHeadNode = OsFindFutexNode(&newTempNode); + if (newHeadNode == NULL) { + OsFutexInsertNewFutexKeyToHash(oldHeadNode); + return LOS_OK; + } + + do { + nextNode = OS_FUTEX_FROM_QUEUELIST(queueList); + SCHEDULER_LOCK(intSave); + if (LOS_ListEmpty(&nextNode->pendList)) { + if (LOS_ListEmpty(queueList)) { + queueListIsEmpty = TRUE; + } else { + queueList = queueList->pstNext; + } + OsFutexDeinitFutexNode(nextNode); + SCHEDULER_UNLOCK(intSave); + if (queueListIsEmpty) { + return LOS_OK; + } + + continue; + } + + task = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(nextNode->pendList))); + if (LOS_ListEmpty(queueList)) { + queueListIsEmpty = TRUE; + } else { + queueList = queueList->pstNext; + } + LOS_ListDelete(&nextNode->queueList); + ret = OsFutexInsertTasktoPendList(&newHeadNode, nextNode, task); + SCHEDULER_UNLOCK(intSave); + if (ret != LOS_OK) { + PRINT_ERR("Futex requeue insert new key failed!\n"); + } + } while (!queueListIsEmpty); + + return LOS_OK; +} + +STATIC VOID OsFutexRequeueSplitTwoLists(FutexHash *oldHashNode, FutexNode *oldHeadNode, + UINT32 flags, UINTPTR futexKey, INT32 count) +{ + LOS_DL_LIST *queueList = &oldHeadNode->queueList; + FutexNode *tailNode = OS_FUTEX_FROM_QUEUELIST(LOS_DL_LIST_LAST(queueList)); + INT32 newIndex = OsFutexKeyToIndex(futexKey, flags); + FutexNode *nextNode = NULL; + FutexNode *newHeadNode = NULL; + LOS_DL_LIST *futexList = NULL; + BOOL isAll = FALSE; + INT32 i; + + for (i = 0; i < count; i++) { + nextNode = OS_FUTEX_FROM_QUEUELIST(queueList); + nextNode->key = futexKey; + nextNode->index = newIndex; + if (queueList->pstNext == &oldHeadNode->queueList) { + isAll = TRUE; + break; + } + + queueList = queueList->pstNext; + } + + futexList = oldHeadNode->futexList.pstPrev; + LOS_ListDelete(&oldHeadNode->futexList); + if (isAll == TRUE) { + return; + } + + newHeadNode = OS_FUTEX_FROM_QUEUELIST(queueList); + LOS_ListHeadInsert(futexList, &newHeadNode->futexList); + oldHeadNode->queueList.pstPrev = &nextNode->queueList; + nextNode->queueList.pstNext = &oldHeadNode->queueList; + newHeadNode->queueList.pstPrev = &tailNode->queueList; + tailNode->queueList.pstNext = &newHeadNode->queueList; + return; +} + +STATIC FutexNode *OsFutexRequeueRemoveOldKeyAndGetHead(UINTPTR oldFutexKey, UINT32 flags, INT32 wakeNumber, + UINTPTR newFutexKey, INT32 requeueCount, BOOL *wakeAny) +{ + INT32 ret; + INT32 oldIndex = OsFutexKeyToIndex(oldFutexKey, flags); + FutexNode *oldHeadNode = NULL; + FutexHash *oldHashNode = &g_futexHash[oldIndex]; + FutexNode oldTempNode = { + .key = oldFutexKey, + .index = oldIndex, + .pid = (flags & FUTEX_PRIVATE) ? LOS_GetCurrProcessID() : OS_INVALID, + }; + + if (wakeNumber > 0) { + ret = OsFutexWakeTask(oldFutexKey, flags, wakeNumber, &oldHeadNode, wakeAny); + if ((ret != LOS_OK) || (oldHeadNode == NULL)) { + return NULL; + } + } + + if (requeueCount <= 0) { + return NULL; + } + + if (oldHeadNode == NULL) { + oldHeadNode = OsFindFutexNode(&oldTempNode); + if (oldHeadNode == NULL) { + return NULL; + } + } + + OsFutexRequeueSplitTwoLists(oldHashNode, oldHeadNode, flags, newFutexKey, requeueCount); + + return oldHeadNode; +} + +STATIC INT32 OsFutexRequeueParamCheck(const UINT32 *oldUserVaddr, UINT32 flags, const UINT32 *newUserVaddr) +{ + VADDR_T oldVaddr = (VADDR_T)(UINTPTR)oldUserVaddr; + VADDR_T newVaddr = (VADDR_T)(UINTPTR)newUserVaddr; + + if (oldVaddr == newVaddr) { + return LOS_EINVAL; + } + + if ((flags & (~FUTEX_PRIVATE)) != FUTEX_REQUEUE) { + PRINT_ERR("Futex requeue param check failed! error flags: 0x%x\n", flags); + return LOS_EINVAL; + } + + if ((oldVaddr % sizeof(INT32)) || (oldVaddr < OS_FUTEX_KEY_BASE) || (oldVaddr >= OS_FUTEX_KEY_MAX)) { + PRINT_ERR("Futex requeue param check failed! error old userVaddr: 0x%x\n", oldUserVaddr); + return LOS_EINVAL; + } + + if ((newVaddr % sizeof(INT32)) || (newVaddr < OS_FUTEX_KEY_BASE) || (newVaddr >= OS_FUTEX_KEY_MAX)) { + PRINT_ERR("Futex requeue param check failed! error new userVaddr: 0x%x\n", newUserVaddr); + return LOS_EINVAL; + } + + return LOS_OK; +} + +INT32 OsFutexRequeue(const UINT32 *userVaddr, UINT32 flags, INT32 wakeNumber, INT32 count, const UINT32 *newUserVaddr) +{ + INT32 ret; + UINTPTR oldFutexKey; + UINTPTR newFutexKey; + INT32 oldIndex; + INT32 newIndex; + FutexHash *oldHashNode = NULL; + FutexHash *newHashNode = NULL; + FutexNode *oldHeadNode = NULL; + BOOL wakeAny = FALSE; + + if (OsFutexRequeueParamCheck(userVaddr, flags, newUserVaddr)) { + return LOS_EINVAL; + } + + oldFutexKey = OsFutexFlagsToKey(userVaddr, flags); + newFutexKey = OsFutexFlagsToKey(newUserVaddr, flags); + oldIndex = OsFutexKeyToIndex(oldFutexKey, flags); + newIndex = OsFutexKeyToIndex(newFutexKey, flags); + + oldHashNode = &g_futexHash[oldIndex]; + if (OsFutexLock(&oldHashNode->listLock)) { + return LOS_EINVAL; + } + + oldHeadNode = OsFutexRequeueRemoveOldKeyAndGetHead(oldFutexKey, flags, wakeNumber, newFutexKey, count, &wakeAny); + if (oldHeadNode == NULL) { + (VOID)OsFutexUnlock(&oldHashNode->listLock); + if (wakeAny == TRUE) { + ret = LOS_OK; + goto EXIT; + } + return LOS_EBADF; + } + + newHashNode = &g_futexHash[newIndex]; + if (oldIndex != newIndex) { + if (OsFutexUnlock(&oldHashNode->listLock)) { + return LOS_EINVAL; + } + + if (OsFutexLock(&newHashNode->listLock)) { + return LOS_EINVAL; + } + } + + ret = OsFutexRequeueInsertNewKey(newFutexKey, newIndex, oldHeadNode); + + if (OsFutexUnlock(&newHashNode->listLock)) { + return LOS_EINVAL; + } + +EXIT: + if (wakeAny == TRUE) { + LOS_MpSchedule(OS_MP_CPU_ALL); + LOS_Schedule(); + } + + return ret; +} +#endif + diff --git a/src/kernel_liteos_a/kernel/base/ipc/los_ipcdebug.c b/src/kernel_liteos_a/kernel/base/ipc/los_ipcdebug.c new file mode 100644 index 00000000..b86c963f --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/ipc/los_ipcdebug.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_ipcdebug_pri.h" + + +#if defined(LOSCFG_DEBUG_SEMAPHORE) || defined(LOSCFG_DEBUG_QUEUE) + +VOID OsArraySortByTime(UINT32 *sortArray, UINT32 start, UINT32 end, const IpcSortParam *sortParam, + OsCompareFunc compareFunc) +{ + UINT32 left = start; + UINT32 right = end; + UINT32 idx = start; + UINT32 pivot = sortArray[start]; + + while (left < right) { + while ((left < right) && (sortArray[right] < sortParam->ipcDebugCBCnt) && (pivot < sortParam->ipcDebugCBCnt) && + compareFunc(sortParam, sortArray[right], pivot)) { + right--; + } + + if (left < right) { + sortArray[left] = sortArray[right]; + idx = right; + left++; + } + + while ((left < right) && (sortArray[left] < sortParam->ipcDebugCBCnt) && (pivot < sortParam->ipcDebugCBCnt) && + compareFunc(sortParam, pivot, sortArray[left])) { + left++; + } + + if (left < right) { + sortArray[right] = sortArray[left]; + idx = left; + right--; + } + } + + sortArray[idx] = pivot; + + if (start < idx) { + OsArraySortByTime(sortArray, start, idx - 1, sortParam, compareFunc); + } + if (idx < end) { + OsArraySortByTime(sortArray, idx + 1, end, sortParam, compareFunc); + } +} + +#endif + diff --git a/src/kernel_liteos_a/kernel/base/ipc/los_mux.c b/src/kernel_liteos_a/kernel/base/ipc/los_mux.c new file mode 100644 index 00000000..fa4a67b8 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/ipc/los_mux.c @@ -0,0 +1,527 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_mux_pri.h" +#include "los_bitmap.h" +#include "los_spinlock.h" +#include "los_mp.h" +#include "los_task_pri.h" +#include "los_exc.h" +#include "los_sched_pri.h" + + +#ifdef LOSCFG_BASE_IPC_MUX +#define MUTEXATTR_TYPE_MASK 0x0FU + +LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrInit(LosMuxAttr *attr) +{ + if (attr == NULL) { + return LOS_EINVAL; + } + + attr->protocol = LOS_MUX_PRIO_INHERIT; + attr->prioceiling = OS_TASK_PRIORITY_LOWEST; + attr->type = LOS_MUX_DEFAULT; + return LOS_OK; +} + +LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrDestroy(LosMuxAttr *attr) +{ + if (attr == NULL) { + return LOS_EINVAL; + } + + return LOS_OK; +} + +LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrGetType(const LosMuxAttr *attr, INT32 *outType) +{ + INT32 type; + + if ((attr == NULL) || (outType == NULL)) { + return LOS_EINVAL; + } + + type = (INT32)(attr->type & MUTEXATTR_TYPE_MASK); + if ((type < LOS_MUX_NORMAL) || (type > LOS_MUX_ERRORCHECK)) { + return LOS_EINVAL; + } + + *outType = type; + + return LOS_OK; +} + +LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrSetType(LosMuxAttr *attr, INT32 type) +{ + if ((attr == NULL) || (type < LOS_MUX_NORMAL) || (type > LOS_MUX_ERRORCHECK)) { + return LOS_EINVAL; + } + + attr->type = (UINT8)((attr->type & ~MUTEXATTR_TYPE_MASK) | (UINT32)type); + return LOS_OK; +} + +LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrGetProtocol(const LosMuxAttr *attr, INT32 *protocol) +{ + if ((attr != NULL) && (protocol != NULL)) { + *protocol = attr->protocol; + } else { + return LOS_EINVAL; + } + + return LOS_OK; +} + +LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrSetProtocol(LosMuxAttr *attr, INT32 protocol) +{ + if (attr == NULL) { + return LOS_EINVAL; + } + + switch (protocol) { + case LOS_MUX_PRIO_NONE: + case LOS_MUX_PRIO_INHERIT: + case LOS_MUX_PRIO_PROTECT: + attr->protocol = (UINT8)protocol; + return LOS_OK; + default: + return LOS_EINVAL; + } +} + +LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrGetPrioceiling(const LosMuxAttr *attr, INT32 *prioceiling) +{ + if (attr == NULL) { + return LOS_EINVAL; + } + + if (prioceiling != NULL) { + *prioceiling = attr->prioceiling; + } + + return LOS_OK; +} + +LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrSetPrioceiling(LosMuxAttr *attr, INT32 prioceiling) +{ + if ((attr == NULL) || + (prioceiling < OS_TASK_PRIORITY_HIGHEST) || + (prioceiling > OS_TASK_PRIORITY_LOWEST)) { + return LOS_EINVAL; + } + + attr->prioceiling = (UINT8)prioceiling; + + return LOS_OK; +} + +LITE_OS_SEC_TEXT UINT32 LOS_MuxSetPrioceiling(LosMux *mutex, INT32 prioceiling, INT32 *oldPrioceiling) +{ + INT32 ret; + INT32 retLock; + if ((mutex == NULL) || + (prioceiling < OS_TASK_PRIORITY_HIGHEST) || + (prioceiling > OS_TASK_PRIORITY_LOWEST)) { + return LOS_EINVAL; + } + + retLock = LOS_MuxLock(mutex, LOS_WAIT_FOREVER); + if (retLock != LOS_OK) { + return retLock; + } + + if (oldPrioceiling != NULL) { + *oldPrioceiling = mutex->attr.prioceiling; + } + + ret = LOS_MuxAttrSetPrioceiling(&mutex->attr, prioceiling); + + retLock = LOS_MuxUnlock(mutex); + if ((ret == LOS_OK) && (retLock != LOS_OK)) { + return retLock; + } + + return ret; +} + +LITE_OS_SEC_TEXT UINT32 LOS_MuxGetPrioceiling(const LosMux *mutex, INT32 *prioceiling) +{ + if ((mutex != NULL) && (prioceiling != NULL) && (mutex->magic == OS_MUX_MAGIC)) { + *prioceiling = mutex->attr.prioceiling; + return LOS_OK; + } + + return LOS_EINVAL; +} + +LITE_OS_SEC_TEXT BOOL LOS_MuxIsValid(const LosMux *mutex) +{ + if ((mutex != NULL) && (mutex->magic == OS_MUX_MAGIC)) { + return TRUE; + } + + return FALSE; +} + +STATIC UINT32 OsCheckMutexAttr(const LosMuxAttr *attr) +{ + if (((INT8)(attr->type) < LOS_MUX_NORMAL) || (attr->type > LOS_MUX_ERRORCHECK)) { + return LOS_NOK; + } + if (((INT8)(attr->prioceiling) < OS_TASK_PRIORITY_HIGHEST) || (attr->prioceiling > OS_TASK_PRIORITY_LOWEST)) { + return LOS_NOK; + } + if (((INT8)(attr->protocol) < LOS_MUX_PRIO_NONE) || (attr->protocol > LOS_MUX_PRIO_PROTECT)) { + return LOS_NOK; + } + return LOS_OK; +} + +LITE_OS_SEC_TEXT UINT32 LOS_MuxInit(LosMux *mutex, const LosMuxAttr *attr) +{ + UINT32 intSave; + + if (mutex == NULL) { + return LOS_EINVAL; + } + + if (attr == NULL) { + (VOID)LOS_MuxAttrInit(&mutex->attr); + } else { + (VOID)memcpy_s(&mutex->attr, sizeof(LosMuxAttr), attr, sizeof(LosMuxAttr)); + } + + if (OsCheckMutexAttr(&mutex->attr) != LOS_OK) { + return LOS_EINVAL; + } + + SCHEDULER_LOCK(intSave); + mutex->muxCount = 0; + mutex->owner = NULL; + LOS_ListInit(&mutex->muxList); + mutex->magic = OS_MUX_MAGIC; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +LITE_OS_SEC_TEXT UINT32 LOS_MuxDestroy(LosMux *mutex) +{ + UINT32 intSave; + + if (mutex == NULL) { + return LOS_EINVAL; + } + + SCHEDULER_LOCK(intSave); + if (mutex->magic != OS_MUX_MAGIC) { + SCHEDULER_UNLOCK(intSave); + return LOS_EBADF; + } + + if (mutex->muxCount != 0) { + SCHEDULER_UNLOCK(intSave); + return LOS_EBUSY; + } + + (VOID)memset_s(mutex, sizeof(LosMux), 0, sizeof(LosMux)); + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +STATIC VOID OsMuxBitmapSet(const LosMux *mutex, const LosTaskCB *runTask) +{ + if (mutex->attr.protocol != LOS_MUX_PRIO_INHERIT) { + return; + } + + SchedParam param = { 0 }; + LosTaskCB *owner = (LosTaskCB *)mutex->owner; + INT32 ret = OsSchedParamCompare(owner, runTask); + if (ret > 0) { + runTask->ops->schedParamGet(runTask, ¶m); + owner->ops->priorityInheritance(owner, ¶m); + } +} + +VOID OsMuxBitmapRestore(const LosMux *mutex, const LOS_DL_LIST *list, const LosTaskCB *runTask) +{ + if (mutex->attr.protocol != LOS_MUX_PRIO_INHERIT) { + return; + } + + SchedParam param = { 0 }; + LosTaskCB *owner = (LosTaskCB *)mutex->owner; + runTask->ops->schedParamGet(runTask, ¶m); + owner->ops->priorityRestore(owner, list, ¶m); +} + +STATIC UINT32 OsMuxPendOp(LosTaskCB *runTask, LosMux *mutex, UINT32 timeout) +{ + UINT32 ret; + + if ((mutex->muxList.pstPrev == NULL) || (mutex->muxList.pstNext == NULL)) { + /* This is for mutex macro initialization. */ + mutex->muxCount = 0; + mutex->owner = NULL; + LOS_ListInit(&mutex->muxList); + } + + if (mutex->muxCount == 0) { + mutex->muxCount++; + mutex->owner = (VOID *)runTask; + LOS_ListTailInsert(&runTask->lockList, &mutex->holdList); + if (mutex->attr.protocol == LOS_MUX_PRIO_PROTECT) { + SchedParam param = { 0 }; + runTask->ops->schedParamGet(runTask, ¶m); + param.priority = mutex->attr.prioceiling; + runTask->ops->priorityInheritance(runTask, ¶m); + } + return LOS_OK; + } + + if (((LosTaskCB *)mutex->owner == runTask) && (mutex->attr.type == LOS_MUX_RECURSIVE)) { + mutex->muxCount++; + return LOS_OK; + } + + if (!timeout) { + return LOS_EINVAL; + } + + if (!OsPreemptableInSched()) { + return LOS_EDEADLK; + } + + OsMuxBitmapSet(mutex, runTask); + + runTask->taskMux = (VOID *)mutex; + LOS_DL_LIST *node = OsSchedLockPendFindPos(runTask, &mutex->muxList); + if (node == NULL) { + ret = LOS_NOK; + return ret; + } + + OsTaskWaitSetPendMask(OS_TASK_WAIT_MUTEX, (UINTPTR)mutex, timeout); + ret = runTask->ops->wait(runTask, node, timeout); + if (ret == LOS_ERRNO_TSK_TIMEOUT) { + OsMuxBitmapRestore(mutex, NULL, runTask); + runTask->taskMux = NULL; + ret = LOS_ETIMEDOUT; + } + + return ret; +} + +UINT32 OsMuxLockUnsafe(LosMux *mutex, UINT32 timeout) +{ + LosTaskCB *runTask = OsCurrTaskGet(); + + if (mutex->magic != OS_MUX_MAGIC) { + return LOS_EBADF; + } + + if (OsCheckMutexAttr(&mutex->attr) != LOS_OK) { + return LOS_EINVAL; + } + + if ((mutex->attr.type == LOS_MUX_ERRORCHECK) && (mutex->owner == (VOID *)runTask)) { + return LOS_EDEADLK; + } + + return OsMuxPendOp(runTask, mutex, timeout); +} + +UINT32 OsMuxTrylockUnsafe(LosMux *mutex, UINT32 timeout) +{ + LosTaskCB *runTask = OsCurrTaskGet(); + + if (mutex->magic != OS_MUX_MAGIC) { + return LOS_EBADF; + } + + if (OsCheckMutexAttr(&mutex->attr) != LOS_OK) { + return LOS_EINVAL; + } + + if ((mutex->owner != NULL) && + (((LosTaskCB *)mutex->owner != runTask) || (mutex->attr.type != LOS_MUX_RECURSIVE))) { + return LOS_EBUSY; + } + + return OsMuxPendOp(runTask, mutex, timeout); +} + +LITE_OS_SEC_TEXT UINT32 LOS_MuxLock(LosMux *mutex, UINT32 timeout) +{ + LosTaskCB *runTask = NULL; + UINT32 intSave; + UINT32 ret; + + if (mutex == NULL) { + return LOS_EINVAL; + } + + if (OS_INT_ACTIVE) { + return LOS_EINTR; + } + + runTask = (LosTaskCB *)OsCurrTaskGet(); + /* DO NOT Call blocking API in system tasks */ + if (runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) { + PRINTK("Warning: DO NOT call %s in system tasks.\n", __FUNCTION__); + OsBackTrace(); + } + + SCHEDULER_LOCK(intSave); + ret = OsMuxLockUnsafe(mutex, timeout); + SCHEDULER_UNLOCK(intSave); + return ret; +} + +LITE_OS_SEC_TEXT UINT32 LOS_MuxTrylock(LosMux *mutex) +{ + LosTaskCB *runTask = NULL; + UINT32 intSave; + UINT32 ret; + + if (mutex == NULL) { + return LOS_EINVAL; + } + + if (OS_INT_ACTIVE) { + return LOS_EINTR; + } + + runTask = (LosTaskCB *)OsCurrTaskGet(); + /* DO NOT Call blocking API in system tasks */ + if (runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) { + PRINTK("Warning: DO NOT call %s in system tasks.\n", __FUNCTION__); + OsBackTrace(); + } + + SCHEDULER_LOCK(intSave); + ret = OsMuxTrylockUnsafe(mutex, 0); + SCHEDULER_UNLOCK(intSave); + return ret; +} + +STATIC UINT32 OsMuxPostOp(LosTaskCB *taskCB, LosMux *mutex, BOOL *needSched) +{ + if (LOS_ListEmpty(&mutex->muxList)) { + LOS_ListDelete(&mutex->holdList); + mutex->owner = NULL; + return LOS_OK; + } + + LosTaskCB *resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(mutex->muxList))); + OsMuxBitmapRestore(mutex, &mutex->muxList, resumedTask); + + mutex->muxCount = 1; + mutex->owner = (VOID *)resumedTask; + LOS_ListDelete(&mutex->holdList); + LOS_ListTailInsert(&resumedTask->lockList, &mutex->holdList); + OsTaskWakeClearPendMask(resumedTask); + resumedTask->ops->wake(resumedTask); + resumedTask->taskMux = NULL; + if (needSched != NULL) { + *needSched = TRUE; + } + + return LOS_OK; +} + +UINT32 OsMuxUnlockUnsafe(LosTaskCB *taskCB, LosMux *mutex, BOOL *needSched) +{ + if (mutex->magic != OS_MUX_MAGIC) { + return LOS_EBADF; + } + + if (OsCheckMutexAttr(&mutex->attr) != LOS_OK) { + return LOS_EINVAL; + } + + if ((LosTaskCB *)mutex->owner != taskCB) { + return LOS_EPERM; + } + + if (mutex->muxCount == 0) { + return LOS_EPERM; + } + + if ((--mutex->muxCount != 0) && (mutex->attr.type == LOS_MUX_RECURSIVE)) { + return LOS_OK; + } + + if (mutex->attr.protocol == LOS_MUX_PRIO_PROTECT) { + SchedParam param = { 0 }; + taskCB->ops->schedParamGet(taskCB, ¶m); + taskCB->ops->priorityRestore(taskCB, NULL, ¶m); + } + + /* Whether a task block the mutex lock. */ + return OsMuxPostOp(taskCB, mutex, needSched); +} + +LITE_OS_SEC_TEXT UINT32 LOS_MuxUnlock(LosMux *mutex) +{ + LosTaskCB *runTask = NULL; + BOOL needSched = FALSE; + UINT32 intSave; + UINT32 ret; + + if (mutex == NULL) { + return LOS_EINVAL; + } + + if (OS_INT_ACTIVE) { + return LOS_EINTR; + } + + runTask = (LosTaskCB *)OsCurrTaskGet(); + /* DO NOT Call blocking API in system tasks */ + if (runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) { + PRINTK("Warning: DO NOT call %s in system tasks.\n", __FUNCTION__); + OsBackTrace(); + } + + SCHEDULER_LOCK(intSave); + ret = OsMuxUnlockUnsafe(runTask, mutex, &needSched); + SCHEDULER_UNLOCK(intSave); + if (needSched == TRUE) { + LOS_MpSchedule(OS_MP_CPU_ALL); + LOS_Schedule(); + } + return ret; +} + +#endif /* LOSCFG_BASE_IPC_MUX */ + diff --git a/src/kernel_liteos_a/kernel/base/ipc/los_queue.c b/src/kernel_liteos_a/kernel/base/ipc/los_queue.c new file mode 100644 index 00000000..8fe06ba2 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/ipc/los_queue.c @@ -0,0 +1,519 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_queue_pri.h" +#include "los_queue_debug_pri.h" +#include "los_task_pri.h" +#include "los_sched_pri.h" +#include "los_spinlock.h" +#include "los_mp.h" +#include "los_percpu_pri.h" +#include "los_hook.h" +#ifdef LOSCFG_IPC_CONTAINER +#include "los_ipc_container_pri.h" +#endif + +#ifdef LOSCFG_BASE_IPC_QUEUE +#if (LOSCFG_BASE_IPC_QUEUE_LIMIT <= 0) +#error "queue maxnum cannot be zero" +#endif /* LOSCFG_BASE_IPC_QUEUE_LIMIT <= 0 */ + +#ifndef LOSCFG_IPC_CONTAINER +LITE_OS_SEC_BSS LosQueueCB *g_allQueue = NULL; +LITE_OS_SEC_BSS STATIC LOS_DL_LIST g_freeQueueList; +#define FREE_QUEUE_LIST g_freeQueueList +#endif + +LITE_OS_SEC_TEXT_INIT LosQueueCB *OsAllQueueCBInit(LOS_DL_LIST *freeQueueList) +{ + UINT32 index; + + if (freeQueueList == NULL) { + return NULL; + } + + UINT32 size = LOSCFG_BASE_IPC_QUEUE_LIMIT * sizeof(LosQueueCB); + /* system resident memory, don't free */ + LosQueueCB *allQueue = (LosQueueCB *)LOS_MemAlloc(m_aucSysMem0, size); + if (allQueue == NULL) { + return NULL; + } + (VOID)memset_s(allQueue, size, 0, size); + LOS_ListInit(freeQueueList); + for (index = 0; index < LOSCFG_BASE_IPC_QUEUE_LIMIT; index++) { + LosQueueCB *queueNode = ((LosQueueCB *)allQueue) + index; + queueNode->queueID = index; + LOS_ListTailInsert(freeQueueList, &queueNode->readWriteList[OS_QUEUE_WRITE]); + } + +#ifndef LOSCFG_IPC_CONTAINER + if (OsQueueDbgInitHook() != LOS_OK) { + (VOID)LOS_MemFree(m_aucSysMem0, allQueue); + return NULL; + } +#endif + return allQueue; +} + +/* + * Description : queue initial + * Return : LOS_OK on success or error code on failure + */ +LITE_OS_SEC_TEXT_INIT UINT32 OsQueueInit(VOID) +{ +#ifndef LOSCFG_IPC_CONTAINER + g_allQueue = OsAllQueueCBInit(&g_freeQueueList); + if (g_allQueue == NULL) { + return LOS_ERRNO_QUEUE_NO_MEMORY; + } +#endif + return LOS_OK; +} + +LITE_OS_SEC_TEXT_INIT UINT32 LOS_QueueCreate(CHAR *queueName, UINT16 len, UINT32 *queueID, + UINT32 flags, UINT16 maxMsgSize) +{ + LosQueueCB *queueCB = NULL; + UINT32 intSave; + LOS_DL_LIST *unusedQueue = NULL; + UINT8 *queue = NULL; + UINT16 msgSize; + + (VOID)queueName; + (VOID)flags; + + if (queueID == NULL) { + return LOS_ERRNO_QUEUE_CREAT_PTR_NULL; + } + + if (maxMsgSize > (OS_NULL_SHORT - sizeof(UINT32))) { + return LOS_ERRNO_QUEUE_SIZE_TOO_BIG; + } + + if ((len == 0) || (maxMsgSize == 0)) { + return LOS_ERRNO_QUEUE_PARA_ISZERO; + } + + msgSize = maxMsgSize + sizeof(UINT32); + /* + * Memory allocation is time-consuming, to shorten the time of disable interrupt, + * move the memory allocation to here. + */ + queue = (UINT8 *)LOS_MemAlloc(m_aucSysMem1, (UINT32)len * msgSize); + if (queue == NULL) { + return LOS_ERRNO_QUEUE_CREATE_NO_MEMORY; + } + + SCHEDULER_LOCK(intSave); + if (LOS_ListEmpty(&FREE_QUEUE_LIST)) { + SCHEDULER_UNLOCK(intSave); + OsQueueCheckHook(); + (VOID)LOS_MemFree(m_aucSysMem1, queue); + return LOS_ERRNO_QUEUE_CB_UNAVAILABLE; + } + + unusedQueue = LOS_DL_LIST_FIRST(&FREE_QUEUE_LIST); + LOS_ListDelete(unusedQueue); + queueCB = GET_QUEUE_LIST(unusedQueue); + queueCB->queueLen = len; + queueCB->queueSize = msgSize; + queueCB->queueHandle = queue; + queueCB->queueState = OS_QUEUE_INUSED; + queueCB->readWriteableCnt[OS_QUEUE_READ] = 0; + queueCB->readWriteableCnt[OS_QUEUE_WRITE] = len; + queueCB->queueHead = 0; + queueCB->queueTail = 0; + LOS_ListInit(&queueCB->readWriteList[OS_QUEUE_READ]); + LOS_ListInit(&queueCB->readWriteList[OS_QUEUE_WRITE]); + LOS_ListInit(&queueCB->memList); + + OsQueueDbgUpdateHook(queueCB->queueID, OsCurrTaskGet()->taskEntry); + SCHEDULER_UNLOCK(intSave); + + *queueID = queueCB->queueID; + OsHookCall(LOS_HOOK_TYPE_QUEUE_CREATE, queueCB); + return LOS_OK; +} + +STATIC LITE_OS_SEC_TEXT UINT32 OsQueueReadParameterCheck(UINT32 queueID, const VOID *bufferAddr, + const UINT32 *bufferSize, UINT32 timeout) +{ + if (GET_QUEUE_INDEX(queueID) >= LOSCFG_BASE_IPC_QUEUE_LIMIT) { + return LOS_ERRNO_QUEUE_INVALID; + } + if ((bufferAddr == NULL) || (bufferSize == NULL)) { + return LOS_ERRNO_QUEUE_READ_PTR_NULL; + } + + if ((*bufferSize == 0) || (*bufferSize > (OS_NULL_SHORT - sizeof(UINT32)))) { + return LOS_ERRNO_QUEUE_READSIZE_IS_INVALID; + } + + OsQueueDbgTimeUpdateHook(queueID); + + if (timeout != LOS_NO_WAIT) { + if (OS_INT_ACTIVE) { + return LOS_ERRNO_QUEUE_READ_IN_INTERRUPT; + } + } + return LOS_OK; +} + +STATIC LITE_OS_SEC_TEXT UINT32 OsQueueWriteParameterCheck(UINT32 queueID, const VOID *bufferAddr, + const UINT32 *bufferSize, UINT32 timeout) +{ + if (GET_QUEUE_INDEX(queueID) >= LOSCFG_BASE_IPC_QUEUE_LIMIT) { + return LOS_ERRNO_QUEUE_INVALID; + } + + if (bufferAddr == NULL) { + return LOS_ERRNO_QUEUE_WRITE_PTR_NULL; + } + + if (*bufferSize == 0) { + return LOS_ERRNO_QUEUE_WRITESIZE_ISZERO; + } + + OsQueueDbgTimeUpdateHook(queueID); + + if (timeout != LOS_NO_WAIT) { + if (OS_INT_ACTIVE) { + return LOS_ERRNO_QUEUE_WRITE_IN_INTERRUPT; + } + } + return LOS_OK; +} + +STATIC VOID OsQueueBufferOperate(LosQueueCB *queueCB, UINT32 operateType, VOID *bufferAddr, UINT32 *bufferSize) +{ + UINT8 *queueNode = NULL; + UINT32 msgDataSize; + UINT16 queuePosition; + + /* get the queue position */ + switch (OS_QUEUE_OPERATE_GET(operateType)) { + case OS_QUEUE_READ_HEAD: + queuePosition = queueCB->queueHead; + ((queueCB->queueHead + 1) == queueCB->queueLen) ? (queueCB->queueHead = 0) : (queueCB->queueHead++); + break; + case OS_QUEUE_WRITE_HEAD: + (queueCB->queueHead == 0) ? (queueCB->queueHead = queueCB->queueLen - 1) : (--queueCB->queueHead); + queuePosition = queueCB->queueHead; + break; + case OS_QUEUE_WRITE_TAIL: + queuePosition = queueCB->queueTail; + ((queueCB->queueTail + 1) == queueCB->queueLen) ? (queueCB->queueTail = 0) : (queueCB->queueTail++); + break; + default: /* read tail, reserved. */ + PRINT_ERR("invalid queue operate type!\n"); + return; + } + + queueNode = &(queueCB->queueHandle[(queuePosition * (queueCB->queueSize))]); + + if (OS_QUEUE_IS_READ(operateType)) { + if (memcpy_s(&msgDataSize, sizeof(UINT32), queueNode + queueCB->queueSize - sizeof(UINT32), + sizeof(UINT32)) != EOK) { + PRINT_ERR("get msgdatasize failed\n"); + return; + } + msgDataSize = (*bufferSize < msgDataSize) ? *bufferSize : msgDataSize; + if (memcpy_s(bufferAddr, *bufferSize, queueNode, msgDataSize) != EOK) { + PRINT_ERR("copy message to buffer failed\n"); + return; + } + + *bufferSize = msgDataSize; + } else { + if (memcpy_s(queueNode, queueCB->queueSize, bufferAddr, *bufferSize) != EOK) { + PRINT_ERR("store message failed\n"); + return; + } + if (memcpy_s(queueNode + queueCB->queueSize - sizeof(UINT32), sizeof(UINT32), bufferSize, + sizeof(UINT32)) != EOK) { + PRINT_ERR("store message size failed\n"); + return; + } + } +} + +STATIC UINT32 OsQueueOperateParamCheck(const LosQueueCB *queueCB, UINT32 queueID, + UINT32 operateType, const UINT32 *bufferSize) +{ + if ((queueCB->queueID != queueID) || (queueCB->queueState == OS_QUEUE_UNUSED)) { + return LOS_ERRNO_QUEUE_NOT_CREATE; + } + + if (OS_QUEUE_IS_WRITE(operateType) && (*bufferSize > (queueCB->queueSize - sizeof(UINT32)))) { + return LOS_ERRNO_QUEUE_WRITE_SIZE_TOO_BIG; + } + return LOS_OK; +} + +UINT32 OsQueueOperate(UINT32 queueID, UINT32 operateType, VOID *bufferAddr, UINT32 *bufferSize, UINT32 timeout) +{ + UINT32 ret; + UINT32 readWrite = OS_QUEUE_READ_WRITE_GET(operateType); + UINT32 intSave; + OsHookCall(LOS_HOOK_TYPE_QUEUE_READ, (LosQueueCB *)GET_QUEUE_HANDLE(queueID), operateType, *bufferSize, timeout); + + SCHEDULER_LOCK(intSave); + LosQueueCB *queueCB = (LosQueueCB *)GET_QUEUE_HANDLE(queueID); + ret = OsQueueOperateParamCheck(queueCB, queueID, operateType, bufferSize); + if (ret != LOS_OK) { + goto QUEUE_END; + } + + if (queueCB->readWriteableCnt[readWrite] == 0) { + if (timeout == LOS_NO_WAIT) { + ret = OS_QUEUE_IS_READ(operateType) ? LOS_ERRNO_QUEUE_ISEMPTY : LOS_ERRNO_QUEUE_ISFULL; + goto QUEUE_END; + } + + if (!OsPreemptableInSched()) { + ret = LOS_ERRNO_QUEUE_PEND_IN_LOCK; + goto QUEUE_END; + } + + LosTaskCB *runTask = OsCurrTaskGet(); + OsTaskWaitSetPendMask(OS_TASK_WAIT_QUEUE, queueCB->queueID, timeout); + ret = runTask->ops->wait(runTask, &queueCB->readWriteList[readWrite], timeout); + if (ret == LOS_ERRNO_TSK_TIMEOUT) { + ret = LOS_ERRNO_QUEUE_TIMEOUT; + goto QUEUE_END; + } + } else { + queueCB->readWriteableCnt[readWrite]--; + } + + OsQueueBufferOperate(queueCB, operateType, bufferAddr, bufferSize); + + if (!LOS_ListEmpty(&queueCB->readWriteList[!readWrite])) { + LosTaskCB *resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&queueCB->readWriteList[!readWrite])); + OsTaskWakeClearPendMask(resumedTask); + resumedTask->ops->wake(resumedTask); + SCHEDULER_UNLOCK(intSave); + LOS_MpSchedule(OS_MP_CPU_ALL); + LOS_Schedule(); + return LOS_OK; + } else { + queueCB->readWriteableCnt[!readWrite]++; + } + +QUEUE_END: + SCHEDULER_UNLOCK(intSave); + return ret; +} + +LITE_OS_SEC_TEXT UINT32 LOS_QueueReadCopy(UINT32 queueID, + VOID *bufferAddr, + UINT32 *bufferSize, + UINT32 timeout) +{ + UINT32 ret; + UINT32 operateType; + + ret = OsQueueReadParameterCheck(queueID, bufferAddr, bufferSize, timeout); + if (ret != LOS_OK) { + return ret; + } + + operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_READ, OS_QUEUE_HEAD); + return OsQueueOperate(queueID, operateType, bufferAddr, bufferSize, timeout); +} + +LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteHeadCopy(UINT32 queueID, + VOID *bufferAddr, + UINT32 bufferSize, + UINT32 timeout) +{ + UINT32 ret; + UINT32 operateType; + + ret = OsQueueWriteParameterCheck(queueID, bufferAddr, &bufferSize, timeout); + if (ret != LOS_OK) { + return ret; + } + + operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_WRITE, OS_QUEUE_HEAD); + return OsQueueOperate(queueID, operateType, bufferAddr, &bufferSize, timeout); +} + +LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteCopy(UINT32 queueID, + VOID *bufferAddr, + UINT32 bufferSize, + UINT32 timeout) +{ + UINT32 ret; + UINT32 operateType; + + ret = OsQueueWriteParameterCheck(queueID, bufferAddr, &bufferSize, timeout); + if (ret != LOS_OK) { + return ret; + } + + operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_WRITE, OS_QUEUE_TAIL); + return OsQueueOperate(queueID, operateType, bufferAddr, &bufferSize, timeout); +} + +LITE_OS_SEC_TEXT UINT32 LOS_QueueRead(UINT32 queueID, VOID *bufferAddr, UINT32 bufferSize, UINT32 timeout) +{ + return LOS_QueueReadCopy(queueID, bufferAddr, &bufferSize, timeout); +} + +LITE_OS_SEC_TEXT UINT32 LOS_QueueWrite(UINT32 queueID, VOID *bufferAddr, UINT32 bufferSize, UINT32 timeout) +{ + if (bufferAddr == NULL) { + return LOS_ERRNO_QUEUE_WRITE_PTR_NULL; + } + bufferSize = sizeof(CHAR *); + return LOS_QueueWriteCopy(queueID, &bufferAddr, bufferSize, timeout); +} + +LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteHead(UINT32 queueID, + VOID *bufferAddr, + UINT32 bufferSize, + UINT32 timeout) +{ + if (bufferAddr == NULL) { + return LOS_ERRNO_QUEUE_WRITE_PTR_NULL; + } + bufferSize = sizeof(CHAR *); + return LOS_QueueWriteHeadCopy(queueID, &bufferAddr, bufferSize, timeout); +} + +LITE_OS_SEC_TEXT_INIT UINT32 LOS_QueueDelete(UINT32 queueID) +{ + LosQueueCB *queueCB = NULL; + UINT8 *queue = NULL; + UINT32 intSave; + UINT32 ret; + + if (GET_QUEUE_INDEX(queueID) >= LOSCFG_BASE_IPC_QUEUE_LIMIT) { + return LOS_ERRNO_QUEUE_NOT_FOUND; + } + + SCHEDULER_LOCK(intSave); + queueCB = (LosQueueCB *)GET_QUEUE_HANDLE(queueID); + if ((queueCB->queueID != queueID) || (queueCB->queueState == OS_QUEUE_UNUSED)) { + ret = LOS_ERRNO_QUEUE_NOT_CREATE; + goto QUEUE_END; + } + + if (!LOS_ListEmpty(&queueCB->readWriteList[OS_QUEUE_READ])) { + ret = LOS_ERRNO_QUEUE_IN_TSKUSE; + goto QUEUE_END; + } + + if (!LOS_ListEmpty(&queueCB->readWriteList[OS_QUEUE_WRITE])) { + ret = LOS_ERRNO_QUEUE_IN_TSKUSE; + goto QUEUE_END; + } + + if (!LOS_ListEmpty(&queueCB->memList)) { + ret = LOS_ERRNO_QUEUE_IN_TSKUSE; + goto QUEUE_END; + } + + if ((queueCB->readWriteableCnt[OS_QUEUE_WRITE] + queueCB->readWriteableCnt[OS_QUEUE_READ]) != + queueCB->queueLen) { + ret = LOS_ERRNO_QUEUE_IN_TSKWRITE; + goto QUEUE_END; + } + + queue = queueCB->queueHandle; + queueCB->queueHandle = NULL; + queueCB->queueState = OS_QUEUE_UNUSED; + queueCB->queueID = SET_QUEUE_ID(GET_QUEUE_COUNT(queueCB->queueID) + 1, GET_QUEUE_INDEX(queueCB->queueID)); + OsQueueDbgUpdateHook(queueCB->queueID, NULL); + + LOS_ListTailInsert(&FREE_QUEUE_LIST, &queueCB->readWriteList[OS_QUEUE_WRITE]); + SCHEDULER_UNLOCK(intSave); + OsHookCall(LOS_HOOK_TYPE_QUEUE_DELETE, queueCB); + ret = LOS_MemFree(m_aucSysMem1, (VOID *)queue); + return ret; + +QUEUE_END: + SCHEDULER_UNLOCK(intSave); + return ret; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_QueueInfoGet(UINT32 queueID, QUEUE_INFO_S *queueInfo) +{ + UINT32 intSave; + UINT32 ret = LOS_OK; + LosQueueCB *queueCB = NULL; + LosTaskCB *tskCB = NULL; + + if (queueInfo == NULL) { + return LOS_ERRNO_QUEUE_PTR_NULL; + } + + if (GET_QUEUE_INDEX(queueID) >= LOSCFG_BASE_IPC_QUEUE_LIMIT) { + return LOS_ERRNO_QUEUE_INVALID; + } + + (VOID)memset_s((VOID *)queueInfo, sizeof(QUEUE_INFO_S), 0, sizeof(QUEUE_INFO_S)); + SCHEDULER_LOCK(intSave); + + queueCB = (LosQueueCB *)GET_QUEUE_HANDLE(queueID); + if ((queueCB->queueID != queueID) || (queueCB->queueState == OS_QUEUE_UNUSED)) { + ret = LOS_ERRNO_QUEUE_NOT_CREATE; + goto QUEUE_END; + } + + queueInfo->uwQueueID = queueID; + queueInfo->usQueueLen = queueCB->queueLen; + queueInfo->usQueueSize = queueCB->queueSize; + queueInfo->usQueueHead = queueCB->queueHead; + queueInfo->usQueueTail = queueCB->queueTail; + queueInfo->usReadableCnt = queueCB->readWriteableCnt[OS_QUEUE_READ]; + queueInfo->usWritableCnt = queueCB->readWriteableCnt[OS_QUEUE_WRITE]; + + LOS_DL_LIST_FOR_EACH_ENTRY(tskCB, &queueCB->readWriteList[OS_QUEUE_READ], LosTaskCB, pendList) { + queueInfo->uwWaitReadTask |= 1ULL << tskCB->taskID; + } + + LOS_DL_LIST_FOR_EACH_ENTRY(tskCB, &queueCB->readWriteList[OS_QUEUE_WRITE], LosTaskCB, pendList) { + queueInfo->uwWaitWriteTask |= 1ULL << tskCB->taskID; + } + + LOS_DL_LIST_FOR_EACH_ENTRY(tskCB, &queueCB->memList, LosTaskCB, pendList) { + queueInfo->uwWaitMemTask |= 1ULL << tskCB->taskID; + } + +QUEUE_END: + SCHEDULER_UNLOCK(intSave); + return ret; +} + +#endif /* LOSCFG_BASE_IPC_QUEUE */ + diff --git a/src/kernel_liteos_a/kernel/base/ipc/los_queue_debug.c b/src/kernel_liteos_a/kernel/base/ipc/los_queue_debug.c new file mode 100644 index 00000000..78fa1676 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/ipc/los_queue_debug.c @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_queue_debug_pri.h" +#include "los_hw_pri.h" +#include "los_ipcdebug_pri.h" +#ifdef LOSCFG_SHELL +#include "shcmd.h" +#endif /* LOSCFG_SHELL */ + + +#ifdef LOSCFG_DEBUG_QUEUE + +typedef struct { + TSK_ENTRY_FUNC creator; /* The task entry who created this queue */ + UINT64 lastAccessTime; /* The last access time */ +} QueueDebugCB; +STATIC QueueDebugCB *g_queueDebugArray = NULL; + +STATIC BOOL QueueCompareValue(const IpcSortParam *sortParam, UINT32 left, UINT32 right) +{ + return (*((UINT64 *)(VOID *)SORT_ELEM_ADDR(sortParam, left)) > + *((UINT64 *)(VOID *)SORT_ELEM_ADDR(sortParam, right))); +} + +UINT32 OsQueueDbgInit(VOID) +{ + UINT32 size = LOSCFG_BASE_IPC_QUEUE_LIMIT * sizeof(QueueDebugCB); + /* system resident memory, don't free */ + g_queueDebugArray = (QueueDebugCB *)LOS_MemAlloc(m_aucSysMem1, size); + if (g_queueDebugArray == NULL) { + PRINT_ERR("%s: malloc failed!\n", __FUNCTION__); + return LOS_NOK; + } + (VOID)memset_s(g_queueDebugArray, size, 0, size); + return LOS_OK; +} + +VOID OsQueueDbgTimeUpdate(UINT32 queueID) +{ + QueueDebugCB *queueDebug = &g_queueDebugArray[GET_QUEUE_INDEX(queueID)]; + queueDebug->lastAccessTime = LOS_TickCountGet(); + return; +} + +VOID OsQueueDbgUpdate(UINT32 queueID, TSK_ENTRY_FUNC entry) +{ + QueueDebugCB *queueDebug = &g_queueDebugArray[GET_QUEUE_INDEX(queueID)]; + queueDebug->creator = entry; + queueDebug->lastAccessTime = LOS_TickCountGet(); + return; +} + +STATIC INLINE VOID OsQueueInfoOutPut(const LosQueueCB *node) +{ + PRINTK("Queue ID <0x%x> may leak, queue len is 0x%x, " + "readable cnt:0x%x, writable cnt:0x%x, ", + node->queueID, + node->queueLen, + node->readWriteableCnt[OS_QUEUE_READ], + node->readWriteableCnt[OS_QUEUE_WRITE]); +} + +STATIC INLINE VOID OsQueueOpsOutput(const QueueDebugCB *node) +{ + PRINTK("TaskEntry of creator:0x%p, Latest operation time: 0x%llx\n", + node->creator, node->lastAccessTime); +} + +STATIC VOID SortQueueIndexArray(UINT32 *indexArray, UINT32 count) +{ + LosQueueCB queueNode = {0}; + QueueDebugCB queueDebugNode = {0}; + UINT32 index, intSave; + IpcSortParam queueSortParam; + queueSortParam.buf = (CHAR *)g_queueDebugArray; + queueSortParam.ipcDebugCBSize = sizeof(QueueDebugCB); + queueSortParam.ipcDebugCBCnt = LOSCFG_BASE_IPC_SEM_LIMIT; + queueSortParam.sortElemOff = LOS_OFF_SET_OF(QueueDebugCB, lastAccessTime); + + if (count > 0) { + SCHEDULER_LOCK(intSave); + OsArraySortByTime(indexArray, 0, count - 1, &queueSortParam, QueueCompareValue); + SCHEDULER_UNLOCK(intSave); + for (index = 0; index < count; index++) { + SCHEDULER_LOCK(intSave); + (VOID)memcpy_s(&queueNode, sizeof(LosQueueCB), + GET_QUEUE_HANDLE(indexArray[index]), sizeof(LosQueueCB)); + (VOID)memcpy_s(&queueDebugNode, sizeof(QueueDebugCB), + &g_queueDebugArray[indexArray[index]], sizeof(QueueDebugCB)); + SCHEDULER_UNLOCK(intSave); + if (queueNode.queueState == OS_QUEUE_UNUSED) { + continue; + } + OsQueueInfoOutPut(&queueNode); + OsQueueOpsOutput(&queueDebugNode); + } + } + (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, indexArray); +} + +VOID OsQueueCheck(VOID) +{ + LosQueueCB queueNode = {0}; + QueueDebugCB queueDebugNode = {0}; + UINT32 index, intSave; + UINT32 count = 0; + + /* + * This return value does not need to be judged immediately, + * and the following code logic has already distinguished the return value from null and non-empty, + * and there is no case of accessing the null pointer. + */ + UINT32 *indexArray = (UINT32 *)LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, LOSCFG_BASE_IPC_QUEUE_LIMIT * sizeof(UINT32)); + + for (index = 0; index < LOSCFG_BASE_IPC_QUEUE_LIMIT; index++) { + SCHEDULER_LOCK(intSave); + (VOID)memcpy_s(&queueNode, sizeof(LosQueueCB), + GET_QUEUE_HANDLE(index), sizeof(LosQueueCB)); + (VOID)memcpy_s(&queueDebugNode, sizeof(QueueDebugCB), + &g_queueDebugArray[index], sizeof(QueueDebugCB)); + SCHEDULER_UNLOCK(intSave); + if ((queueNode.queueState == OS_QUEUE_UNUSED) || + ((queueNode.queueState == OS_QUEUE_INUSED) && (queueDebugNode.creator == NULL))) { + continue; + } + if ((queueNode.queueState == OS_QUEUE_INUSED) && + (queueNode.queueLen == queueNode.readWriteableCnt[OS_QUEUE_WRITE]) && + LOS_ListEmpty(&queueNode.readWriteList[OS_QUEUE_READ]) && + LOS_ListEmpty(&queueNode.readWriteList[OS_QUEUE_WRITE]) && + LOS_ListEmpty(&queueNode.memList)) { + PRINTK("Queue ID <0x%x> may leak, No task uses it, " + "QueueLen is 0x%x, ", + queueNode.queueID, + queueNode.queueLen); + OsQueueOpsOutput(&queueDebugNode); + } else { + if (indexArray != NULL) { + *(indexArray + count) = index; + count++; + } else { + OsQueueInfoOutPut(&queueNode); + OsQueueOpsOutput(&queueDebugNode); + } + } + } + + if (indexArray != NULL) { + SortQueueIndexArray(indexArray, count); + } + + return; +} + +#ifdef LOSCFG_SHELL_CMD_DEBUG +LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdQueueInfoGet(UINT32 argc, const CHAR **argv) +{ + if (argc > 0) { + PRINTK("\nUsage: queue\n"); + return OS_ERROR; + } + PRINTK("used queues information: \n"); + OsQueueCheck(); + return LOS_OK; +} + +SHELLCMD_ENTRY(queue_shellcmd, CMD_TYPE_EX, "queue", 0, (CmdCallBackFunc)OsShellCmdQueueInfoGet); +#endif /* LOSCFG_SHELL */ +#endif /* LOSCFG_DEBUG_QUEUE */ + diff --git a/src/kernel_liteos_a/kernel/base/ipc/los_rwlock.c b/src/kernel_liteos_a/kernel/base/ipc/los_rwlock.c new file mode 100644 index 00000000..546fe831 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/ipc/los_rwlock.c @@ -0,0 +1,462 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_rwlock_pri.h" +#include "stdint.h" +#include "los_spinlock.h" +#include "los_mp.h" +#include "los_task_pri.h" +#include "los_exc.h" +#include "los_sched_pri.h" + +#ifdef LOSCFG_BASE_IPC_RWLOCK +#define RWLOCK_COUNT_MASK 0x00FFFFFFU + +BOOL LOS_RwlockIsValid(const LosRwlock *rwlock) +{ + if ((rwlock != NULL) && ((rwlock->magic & RWLOCK_COUNT_MASK) == OS_RWLOCK_MAGIC)) { + return TRUE; + } + + return FALSE; +} + +UINT32 LOS_RwlockInit(LosRwlock *rwlock) +{ + UINT32 intSave; + + if (rwlock == NULL) { + return LOS_EINVAL; + } + + SCHEDULER_LOCK(intSave); + if ((rwlock->magic & RWLOCK_COUNT_MASK) == OS_RWLOCK_MAGIC) { + SCHEDULER_UNLOCK(intSave); + return LOS_EPERM; + } + + rwlock->rwCount = 0; + rwlock->writeOwner = NULL; + LOS_ListInit(&(rwlock->readList)); + LOS_ListInit(&(rwlock->writeList)); + rwlock->magic = OS_RWLOCK_MAGIC; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +UINT32 LOS_RwlockDestroy(LosRwlock *rwlock) +{ + UINT32 intSave; + + if (rwlock == NULL) { + return LOS_EINVAL; + } + + SCHEDULER_LOCK(intSave); + if ((rwlock->magic & RWLOCK_COUNT_MASK) != OS_RWLOCK_MAGIC) { + SCHEDULER_UNLOCK(intSave); + return LOS_EBADF; + } + + if (rwlock->rwCount != 0) { + SCHEDULER_UNLOCK(intSave); + return LOS_EBUSY; + } + + (VOID)memset_s(rwlock, sizeof(LosRwlock), 0, sizeof(LosRwlock)); + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +STATIC UINT32 OsRwlockCheck(const LosRwlock *rwlock) +{ + if (rwlock == NULL) { + return LOS_EINVAL; + } + + if (OS_INT_ACTIVE) { + return LOS_EINTR; + } + + /* DO NOT Call blocking API in system tasks */ + LosTaskCB *runTask = (LosTaskCB *)OsCurrTaskGet(); + if (runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) { + return LOS_EPERM; + } + + return LOS_OK; +} + +STATIC BOOL OsRwlockPriCompare(LosTaskCB *runTask, LOS_DL_LIST *rwList) +{ + if (!LOS_ListEmpty(rwList)) { + LosTaskCB *highestTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(rwList)); + if (OsSchedParamCompare(runTask, highestTask) < 0) { + return TRUE; + } + return FALSE; + } + return TRUE; +} + +STATIC UINT32 OsRwlockRdPendOp(LosTaskCB *runTask, LosRwlock *rwlock, UINT32 timeout) +{ + UINT32 ret; + + /* + * When the rwlock mode is read mode or free mode and the priority of the current read task + * is higher than the first pended write task. current read task can obtain this rwlock. + */ + if (rwlock->rwCount >= 0) { + if (OsRwlockPriCompare(runTask, &(rwlock->writeList))) { + if (rwlock->rwCount == INT8_MAX) { + return LOS_EINVAL; + } + rwlock->rwCount++; + return LOS_OK; + } + } + + if (!timeout) { + return LOS_EINVAL; + } + + if (!OsPreemptableInSched()) { + return LOS_EDEADLK; + } + + /* The current task is not allowed to obtain the write lock when it obtains the read lock. */ + if ((LosTaskCB *)(rwlock->writeOwner) == runTask) { + return LOS_EINVAL; + } + + /* + * When the rwlock mode is write mode or the priority of the current read task + * is lower than the first pended write task, current read task will be pended. + */ + LOS_DL_LIST *node = OsSchedLockPendFindPos(runTask, &(rwlock->readList)); + ret = runTask->ops->wait(runTask, node, timeout); + if (ret == LOS_ERRNO_TSK_TIMEOUT) { + return LOS_ETIMEDOUT; + } + + return ret; +} + +STATIC UINT32 OsRwlockWrPendOp(LosTaskCB *runTask, LosRwlock *rwlock, UINT32 timeout) +{ + UINT32 ret; + + /* When the rwlock is free mode, current write task can obtain this rwlock. */ + if (rwlock->rwCount == 0) { + rwlock->rwCount = -1; + rwlock->writeOwner = (VOID *)runTask; + return LOS_OK; + } + + /* Current write task can use one rwlock once again if the rwlock owner is it. */ + if ((rwlock->rwCount < 0) && ((LosTaskCB *)(rwlock->writeOwner) == runTask)) { + if (rwlock->rwCount == INT8_MIN) { + return LOS_EINVAL; + } + rwlock->rwCount--; + return LOS_OK; + } + + if (!timeout) { + return LOS_EINVAL; + } + + if (!OsPreemptableInSched()) { + return LOS_EDEADLK; + } + + /* + * When the rwlock is read mode or other write task obtains this rwlock, current + * write task will be pended. + */ + LOS_DL_LIST *node = OsSchedLockPendFindPos(runTask, &(rwlock->writeList)); + ret = runTask->ops->wait(runTask, node, timeout); + if (ret == LOS_ERRNO_TSK_TIMEOUT) { + ret = LOS_ETIMEDOUT; + } + + return ret; +} + +UINT32 OsRwlockRdUnsafe(LosRwlock *rwlock, UINT32 timeout) +{ + if ((rwlock->magic & RWLOCK_COUNT_MASK) != OS_RWLOCK_MAGIC) { + return LOS_EBADF; + } + + return OsRwlockRdPendOp(OsCurrTaskGet(), rwlock, timeout); +} + +UINT32 OsRwlockTryRdUnsafe(LosRwlock *rwlock, UINT32 timeout) +{ + if ((rwlock->magic & RWLOCK_COUNT_MASK) != OS_RWLOCK_MAGIC) { + return LOS_EBADF; + } + + LosTaskCB *runTask = OsCurrTaskGet(); + if ((LosTaskCB *)(rwlock->writeOwner) == runTask) { + return LOS_EINVAL; + } + + /* + * When the rwlock mode is read mode or free mode and the priority of the current read task + * is lower than the first pended write task, current read task can not obtain the rwlock. + */ + if ((rwlock->rwCount >= 0) && !OsRwlockPriCompare(runTask, &(rwlock->writeList))) { + return LOS_EBUSY; + } + + /* + * When the rwlock mode is write mode, current read task can not obtain the rwlock. + */ + if (rwlock->rwCount < 0) { + return LOS_EBUSY; + } + + return OsRwlockRdPendOp(runTask, rwlock, timeout); +} + +UINT32 OsRwlockWrUnsafe(LosRwlock *rwlock, UINT32 timeout) +{ + if ((rwlock->magic & RWLOCK_COUNT_MASK) != OS_RWLOCK_MAGIC) { + return LOS_EBADF; + } + + return OsRwlockWrPendOp(OsCurrTaskGet(), rwlock, timeout); +} + +UINT32 OsRwlockTryWrUnsafe(LosRwlock *rwlock, UINT32 timeout) +{ + if ((rwlock->magic & RWLOCK_COUNT_MASK) != OS_RWLOCK_MAGIC) { + return LOS_EBADF; + } + + /* When the rwlock is read mode, current write task will be pended. */ + if (rwlock->rwCount > 0) { + return LOS_EBUSY; + } + + /* When other write task obtains this rwlock, current write task will be pended. */ + LosTaskCB *runTask = OsCurrTaskGet(); + if ((rwlock->rwCount < 0) && ((LosTaskCB *)(rwlock->writeOwner) != runTask)) { + return LOS_EBUSY; + } + + return OsRwlockWrPendOp(runTask, rwlock, timeout); +} + +UINT32 LOS_RwlockRdLock(LosRwlock *rwlock, UINT32 timeout) +{ + UINT32 intSave; + + UINT32 ret = OsRwlockCheck(rwlock); + if (ret != LOS_OK) { + return ret; + } + + SCHEDULER_LOCK(intSave); + ret = OsRwlockRdUnsafe(rwlock, timeout); + SCHEDULER_UNLOCK(intSave); + return ret; +} + +UINT32 LOS_RwlockTryRdLock(LosRwlock *rwlock) +{ + UINT32 intSave; + + UINT32 ret = OsRwlockCheck(rwlock); + if (ret != LOS_OK) { + return ret; + } + + SCHEDULER_LOCK(intSave); + ret = OsRwlockTryRdUnsafe(rwlock, 0); + SCHEDULER_UNLOCK(intSave); + return ret; +} + +UINT32 LOS_RwlockWrLock(LosRwlock *rwlock, UINT32 timeout) +{ + UINT32 intSave; + + UINT32 ret = OsRwlockCheck(rwlock); + if (ret != LOS_OK) { + return ret; + } + + SCHEDULER_LOCK(intSave); + ret = OsRwlockWrUnsafe(rwlock, timeout); + SCHEDULER_UNLOCK(intSave); + return ret; +} + +UINT32 LOS_RwlockTryWrLock(LosRwlock *rwlock) +{ + UINT32 intSave; + + UINT32 ret = OsRwlockCheck(rwlock); + if (ret != LOS_OK) { + return ret; + } + + SCHEDULER_LOCK(intSave); + ret = OsRwlockTryWrUnsafe(rwlock, 0); + SCHEDULER_UNLOCK(intSave); + return ret; +} + +STATIC UINT32 OsRwlockGetMode(LOS_DL_LIST *readList, LOS_DL_LIST *writeList) +{ + BOOL isReadEmpty = LOS_ListEmpty(readList); + BOOL isWriteEmpty = LOS_ListEmpty(writeList); + if (isReadEmpty && isWriteEmpty) { + return RWLOCK_NONE_MODE; + } + if (!isReadEmpty && isWriteEmpty) { + return RWLOCK_READ_MODE; + } + if (isReadEmpty && !isWriteEmpty) { + return RWLOCK_WRITE_MODE; + } + LosTaskCB *pendedReadTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(readList)); + LosTaskCB *pendedWriteTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(writeList)); + if (OsSchedParamCompare(pendedWriteTask, pendedReadTask) <= 0) { + return RWLOCK_WRITEFIRST_MODE; + } + return RWLOCK_READFIRST_MODE; +} + +STATIC UINT32 OsRwlockPostOp(LosRwlock *rwlock, BOOL *needSched) +{ + UINT32 rwlockMode; + LosTaskCB *resumedTask = NULL; + + rwlock->rwCount = 0; + rwlock->writeOwner = NULL; + rwlockMode = OsRwlockGetMode(&(rwlock->readList), &(rwlock->writeList)); + if (rwlockMode == RWLOCK_NONE_MODE) { + return LOS_OK; + } + /* In this case, rwlock will wake the first pended write task. */ + if ((rwlockMode == RWLOCK_WRITE_MODE) || (rwlockMode == RWLOCK_WRITEFIRST_MODE)) { + resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(rwlock->writeList))); + rwlock->rwCount = -1; + rwlock->writeOwner = (VOID *)resumedTask; + resumedTask->ops->wake(resumedTask); + if (needSched != NULL) { + *needSched = TRUE; + } + return LOS_OK; + } + + rwlock->rwCount = 1; + resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(rwlock->readList))); + resumedTask->ops->wake(resumedTask); + while (!LOS_ListEmpty(&(rwlock->readList))) { + resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(rwlock->readList))); + if (rwlockMode == RWLOCK_READFIRST_MODE) { + LosTaskCB *pendedWriteTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(rwlock->writeList))); + if (OsSchedParamCompare(resumedTask, pendedWriteTask) >= 0) { + break; + } + } + if (rwlock->rwCount == INT8_MAX) { + return EINVAL; + } + rwlock->rwCount++; + resumedTask->ops->wake(resumedTask); + } + if (needSched != NULL) { + *needSched = TRUE; + } + return LOS_OK; +} + +UINT32 OsRwlockUnlockUnsafe(LosRwlock *rwlock, BOOL *needSched) +{ + if ((rwlock->magic & RWLOCK_COUNT_MASK) != OS_RWLOCK_MAGIC) { + return LOS_EBADF; + } + + if (rwlock->rwCount == 0) { + return LOS_EPERM; + } + + LosTaskCB *runTask = OsCurrTaskGet(); + if ((rwlock->rwCount < 0) && ((LosTaskCB *)(rwlock->writeOwner) != runTask)) { + return LOS_EPERM; + } + + /* + * When the rwCount of the rwlock more than 1 or less than -1, the rwlock mode will + * not changed after current unlock operation, so pended tasks can not be waken. + */ + if (rwlock->rwCount > 1) { + rwlock->rwCount--; + return LOS_OK; + } + + if (rwlock->rwCount < -1) { + rwlock->rwCount++; + return LOS_OK; + } + + return OsRwlockPostOp(rwlock, needSched); +} + +UINT32 LOS_RwlockUnLock(LosRwlock *rwlock) +{ + UINT32 intSave; + BOOL needSched = FALSE; + + UINT32 ret = OsRwlockCheck(rwlock); + if (ret != LOS_OK) { + return ret; + } + + SCHEDULER_LOCK(intSave); + ret = OsRwlockUnlockUnsafe(rwlock, &needSched); + SCHEDULER_UNLOCK(intSave); + LOS_MpSchedule(OS_MP_CPU_ALL); + if (needSched == TRUE) { + LOS_Schedule(); + } + return ret; +} + +#endif /* LOSCFG_BASE_IPC_RWLOCK */ + diff --git a/src/kernel_liteos_a/kernel/base/ipc/los_sem.c b/src/kernel_liteos_a/kernel/base/ipc/los_sem.c new file mode 100644 index 00000000..31d484a1 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/ipc/los_sem.c @@ -0,0 +1,287 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_sem_pri.h" +#include "los_sem_debug_pri.h" +#include "los_err_pri.h" +#include "los_task_pri.h" +#include "los_exc.h" +#include "los_sched_pri.h" +#include "los_spinlock.h" +#include "los_mp.h" +#include "los_percpu_pri.h" +#include "los_hook.h" + +#ifdef LOSCFG_BASE_IPC_SEM + +#if (LOSCFG_BASE_IPC_SEM_LIMIT <= 0) +#error "sem maxnum cannot be zero" +#endif /* LOSCFG_BASE_IPC_SEM_LIMIT <= 0 */ + +LITE_OS_SEC_DATA_INIT STATIC LOS_DL_LIST g_unusedSemList; +LITE_OS_SEC_BSS LosSemCB *g_allSem = NULL; + +/* + * Description : Initialize the semaphore doubly linked list + * Return : LOS_OK on success, or error code on failure + */ +LITE_OS_SEC_TEXT_INIT UINT32 OsSemInit(VOID) +{ + LosSemCB *semNode = NULL; + UINT32 index; + + LOS_ListInit(&g_unusedSemList); + /* system resident memory, don't free */ + g_allSem = (LosSemCB *)LOS_MemAlloc(m_aucSysMem0, (LOSCFG_BASE_IPC_SEM_LIMIT * sizeof(LosSemCB))); + if (g_allSem == NULL) { + return LOS_ERRNO_SEM_NO_MEMORY; + } + + for (index = 0; index < LOSCFG_BASE_IPC_SEM_LIMIT; index++) { + semNode = ((LosSemCB *)g_allSem) + index; + semNode->semID = SET_SEM_ID(0, index); + semNode->semStat = OS_SEM_UNUSED; + LOS_ListTailInsert(&g_unusedSemList, &semNode->semList); + } + + if (OsSemDbgInitHook() != LOS_OK) { + return LOS_ERRNO_SEM_NO_MEMORY; + } + return LOS_OK; +} + +/* + * Description : Create a semaphore, + * Input : count --- semaphore count, + * maxCount --- Max number of available semaphores, + * semHandle --- Index of semaphore, + * Return : LOS_OK on success ,or error code on failure + */ +LITE_OS_SEC_TEXT_INIT UINT32 OsSemCreate(UINT16 count, UINT16 maxCount, UINT32 *semHandle) +{ + UINT32 intSave; + LosSemCB *semCreated = NULL; + LOS_DL_LIST *unusedSem = NULL; + UINT32 errNo; + UINT32 errLine; + + if (semHandle == NULL) { + return LOS_ERRNO_SEM_PTR_NULL; + } + + if (count > maxCount) { + OS_GOTO_ERR_HANDLER(LOS_ERRNO_SEM_OVERFLOW); + } + + SCHEDULER_LOCK(intSave); + + if (LOS_ListEmpty(&g_unusedSemList)) { + SCHEDULER_UNLOCK(intSave); + OsSemInfoGetFullDataHook(); + OS_GOTO_ERR_HANDLER(LOS_ERRNO_SEM_ALL_BUSY); + } + + unusedSem = LOS_DL_LIST_FIRST(&g_unusedSemList); + LOS_ListDelete(unusedSem); + SCHEDULER_UNLOCK(intSave); + semCreated = GET_SEM_LIST(unusedSem); + semCreated->semCount = count; + semCreated->semStat = OS_SEM_USED; + semCreated->maxSemCount = maxCount; + LOS_ListInit(&semCreated->semList); + *semHandle = semCreated->semID; + OsHookCall(LOS_HOOK_TYPE_SEM_CREATE, semCreated); + OsSemDbgUpdateHook(semCreated->semID, OsCurrTaskGet()->taskEntry, count); + return LOS_OK; + +ERR_HANDLER: + OS_RETURN_ERROR_P2(errLine, errNo); +} + +LITE_OS_SEC_TEXT_INIT UINT32 LOS_SemCreate(UINT16 count, UINT32 *semHandle) +{ + return OsSemCreate(count, OS_SEM_COUNT_MAX, semHandle); +} + +LITE_OS_SEC_TEXT_INIT UINT32 LOS_BinarySemCreate(UINT16 count, UINT32 *semHandle) +{ + return OsSemCreate(count, OS_SEM_BINARY_COUNT_MAX, semHandle); +} + +LITE_OS_SEC_TEXT_INIT UINT32 LOS_SemDelete(UINT32 semHandle) +{ + UINT32 intSave; + LosSemCB *semDeleted = NULL; + UINT32 errNo; + UINT32 errLine; + + if (GET_SEM_INDEX(semHandle) >= (UINT32)LOSCFG_BASE_IPC_SEM_LIMIT) { + OS_GOTO_ERR_HANDLER(LOS_ERRNO_SEM_INVALID); + } + + semDeleted = GET_SEM(semHandle); + + SCHEDULER_LOCK(intSave); + + if ((semDeleted->semStat == OS_SEM_UNUSED) || (semDeleted->semID != semHandle)) { + SCHEDULER_UNLOCK(intSave); + OS_GOTO_ERR_HANDLER(LOS_ERRNO_SEM_INVALID); + } + + if (!LOS_ListEmpty(&semDeleted->semList)) { + SCHEDULER_UNLOCK(intSave); + OS_GOTO_ERR_HANDLER(LOS_ERRNO_SEM_PENDED); + } + + LOS_ListTailInsert(&g_unusedSemList, &semDeleted->semList); + semDeleted->semStat = OS_SEM_UNUSED; + semDeleted->semID = SET_SEM_ID(GET_SEM_COUNT(semDeleted->semID) + 1, GET_SEM_INDEX(semDeleted->semID)); + + OsHookCall(LOS_HOOK_TYPE_SEM_DELETE, semDeleted); + OsSemDbgUpdateHook(semDeleted->semID, NULL, 0); + + SCHEDULER_UNLOCK(intSave); + return LOS_OK; + +ERR_HANDLER: + OS_RETURN_ERROR_P2(errLine, errNo); +} + +LITE_OS_SEC_TEXT UINT32 LOS_SemPend(UINT32 semHandle, UINT32 timeout) +{ + UINT32 intSave; + LosSemCB *semPended = GET_SEM(semHandle); + UINT32 retErr = LOS_OK; + LosTaskCB *runTask = NULL; + + if (GET_SEM_INDEX(semHandle) >= (UINT32)LOSCFG_BASE_IPC_SEM_LIMIT) { + OS_RETURN_ERROR(LOS_ERRNO_SEM_INVALID); + } + + if (OS_INT_ACTIVE) { + PRINT_ERR("!!!LOS_ERRNO_SEM_PEND_INTERR!!!\n"); + OsBackTrace(); + return LOS_ERRNO_SEM_PEND_INTERR; + } + + runTask = OsCurrTaskGet(); + if (runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) { + OsBackTrace(); + return LOS_ERRNO_SEM_PEND_IN_SYSTEM_TASK; + } + + SCHEDULER_LOCK(intSave); + + if ((semPended->semStat == OS_SEM_UNUSED) || (semPended->semID != semHandle)) { + retErr = LOS_ERRNO_SEM_INVALID; + goto OUT; + } + /* Update the operate time, no matter the actual Pend success or not */ + OsSemDbgTimeUpdateHook(semHandle); + + if (semPended->semCount > 0) { + semPended->semCount--; + OsHookCall(LOS_HOOK_TYPE_SEM_PEND, semPended, runTask, timeout); + goto OUT; + } else if (!timeout) { + retErr = LOS_ERRNO_SEM_UNAVAILABLE; + goto OUT; + } + + if (!OsPreemptableInSched()) { + PRINT_ERR("!!!LOS_ERRNO_SEM_PEND_IN_LOCK!!!\n"); + OsBackTrace(); + retErr = LOS_ERRNO_SEM_PEND_IN_LOCK; + goto OUT; + } + + OsHookCall(LOS_HOOK_TYPE_SEM_PEND, semPended, runTask, timeout); + OsTaskWaitSetPendMask(OS_TASK_WAIT_SEM, semPended->semID, timeout); + retErr = runTask->ops->wait(runTask, &semPended->semList, timeout); + if (retErr == LOS_ERRNO_TSK_TIMEOUT) { + retErr = LOS_ERRNO_SEM_TIMEOUT; + } + +OUT: + SCHEDULER_UNLOCK(intSave); + return retErr; +} + +LITE_OS_SEC_TEXT UINT32 OsSemPostUnsafe(UINT32 semHandle, BOOL *needSched) +{ + LosTaskCB *resumedTask = NULL; + LosSemCB *semPosted = GET_SEM(semHandle); + if ((semPosted->semID != semHandle) || (semPosted->semStat == OS_SEM_UNUSED)) { + return LOS_ERRNO_SEM_INVALID; + } + + /* Update the operate time, no matter the actual Post success or not */ + OsSemDbgTimeUpdateHook(semHandle); + + if (semPosted->semCount == OS_SEM_COUNT_MAX) { + return LOS_ERRNO_SEM_OVERFLOW; + } + if (!LOS_ListEmpty(&semPosted->semList)) { + resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(semPosted->semList))); + OsTaskWakeClearPendMask(resumedTask); + resumedTask->ops->wake(resumedTask); + if (needSched != NULL) { + *needSched = TRUE; + } + } else { + semPosted->semCount++; + } + OsHookCall(LOS_HOOK_TYPE_SEM_POST, semPosted, resumedTask); + return LOS_OK; +} + +LITE_OS_SEC_TEXT UINT32 LOS_SemPost(UINT32 semHandle) +{ + UINT32 intSave; + UINT32 ret; + BOOL needSched = FALSE; + + if (GET_SEM_INDEX(semHandle) >= LOSCFG_BASE_IPC_SEM_LIMIT) { + return LOS_ERRNO_SEM_INVALID; + } + + SCHEDULER_LOCK(intSave); + ret = OsSemPostUnsafe(semHandle, &needSched); + SCHEDULER_UNLOCK(intSave); + if (needSched) { + LOS_MpSchedule(OS_MP_CPU_ALL); + LOS_Schedule(); + } + + return ret; +} +#endif /* LOSCFG_BASE_IPC_SEM */ + diff --git a/src/kernel_liteos_a/kernel/base/ipc/los_sem_debug.c b/src/kernel_liteos_a/kernel/base/ipc/los_sem_debug.c new file mode 100644 index 00000000..1ed42515 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/ipc/los_sem_debug.c @@ -0,0 +1,301 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_sem_debug_pri.h" +#include "stdlib.h" +#include "los_typedef.h" +#include "los_task_pri.h" +#include "los_ipcdebug_pri.h" +#ifdef LOSCFG_SHELL +#include "shcmd.h" +#endif /* LOSCFG_SHELL */ + + +#define OS_ALL_SEM_MASK 0xffffffff + +#if defined(LOSCFG_DEBUG_SEMAPHORE) || defined(LOSCFG_SHELL_CMD_DEBUG) +STATIC VOID OsSemPendedTaskNamePrint(LosSemCB *semNode) +{ + LosTaskCB *tskCB = NULL; + CHAR *nameArr[LOSCFG_BASE_CORE_TSK_LIMIT] = {0}; + UINT32 i, intSave; + UINT32 num = 0; + + SCHEDULER_LOCK(intSave); + if ((semNode->semStat == OS_SEM_UNUSED) || (LOS_ListEmpty(&semNode->semList))) { + SCHEDULER_UNLOCK(intSave); + return; + } + + LOS_DL_LIST_FOR_EACH_ENTRY(tskCB, &semNode->semList, LosTaskCB, pendList) { + nameArr[num++] = tskCB->taskName; + if (num == LOSCFG_BASE_CORE_TSK_LIMIT) { + break; + } + } + SCHEDULER_UNLOCK(intSave); + + PRINTK("Pended task list : "); + for (i = 0; i < num; i++) { + if (i == 0) { + PRINTK("\n%s", nameArr[i]); + } else { + PRINTK(", %s", nameArr[i]); + } + } + PRINTK("\n"); +} +#endif + +#ifdef LOSCFG_DEBUG_SEMAPHORE + +typedef struct { + UINT16 origSemCount; /* Number of original available semaphores */ + UINT64 lastAccessTime; /* The last operation time */ + TSK_ENTRY_FUNC creator; /* The task entry who created this sem */ +} SemDebugCB; +STATIC SemDebugCB *g_semDebugArray = NULL; + +STATIC BOOL SemCompareValue(const IpcSortParam *sortParam, UINT32 left, UINT32 right) +{ + return (*((UINT64 *)(VOID *)SORT_ELEM_ADDR(sortParam, left)) > + *((UINT64 *)(VOID *)SORT_ELEM_ADDR(sortParam, right))); +} + +UINT32 OsSemDbgInit(VOID) +{ + UINT32 size = LOSCFG_BASE_IPC_SEM_LIMIT * sizeof(SemDebugCB); + /* system resident memory, don't free */ + g_semDebugArray = (SemDebugCB *)LOS_MemAlloc(m_aucSysMem1, size); + if (g_semDebugArray == NULL) { + PRINT_ERR("%s: malloc failed!\n", __FUNCTION__); + return LOS_NOK; + } + (VOID)memset_s(g_semDebugArray, size, 0, size); + return LOS_OK; +} + +VOID OsSemDbgTimeUpdate(UINT32 semID) +{ + SemDebugCB *semDebug = &g_semDebugArray[GET_SEM_INDEX(semID)]; + semDebug->lastAccessTime = LOS_TickCountGet(); + return; +} + +VOID OsSemDbgUpdate(UINT32 semID, TSK_ENTRY_FUNC creator, UINT16 count) +{ + SemDebugCB *semDebug = &g_semDebugArray[GET_SEM_INDEX(semID)]; + semDebug->creator = creator; + semDebug->lastAccessTime = LOS_TickCountGet(); + semDebug->origSemCount = count; + return; +} + +STATIC VOID OsSemSort(UINT32 *semIndexArray, UINT32 usedCount) +{ + UINT32 i, intSave; + LosSemCB *semCB = NULL; + LosSemCB semNode = {0}; + SemDebugCB semDebug = {0}; + IpcSortParam semSortParam; + semSortParam.buf = (CHAR *)g_semDebugArray; + semSortParam.ipcDebugCBSize = sizeof(SemDebugCB); + semSortParam.ipcDebugCBCnt = LOSCFG_BASE_IPC_SEM_LIMIT; + semSortParam.sortElemOff = LOS_OFF_SET_OF(SemDebugCB, lastAccessTime); + + /* It will Print out ALL the Used Semaphore List. */ + PRINTK("Used Semaphore List: \n"); + PRINTK("\r\n SemID Count OriginalCount Creator(TaskEntry) LastAccessTime\n"); + PRINTK(" ------ ------ ------------- ------------------ -------------- \n"); + + SCHEDULER_LOCK(intSave); + OsArraySortByTime(semIndexArray, 0, usedCount - 1, &semSortParam, SemCompareValue); + SCHEDULER_UNLOCK(intSave); + for (i = 0; i < usedCount; i++) { + semCB = GET_SEM(semIndexArray[i]); + SCHEDULER_LOCK(intSave); + (VOID)memcpy_s(&semNode, sizeof(LosSemCB), semCB, sizeof(LosSemCB)); + (VOID)memcpy_s(&semDebug, sizeof(SemDebugCB), &g_semDebugArray[semIndexArray[i]], sizeof(SemDebugCB)); + SCHEDULER_UNLOCK(intSave); + if ((semNode.semStat != OS_SEM_USED) || (semDebug.creator == NULL)) { + continue; + } + PRINTK(" 0x%-07x0x%-07u0x%-14u%-22p0x%llx\n", semNode.semID, semDebug.origSemCount, + semNode.semCount, semDebug.creator, semDebug.lastAccessTime); + if (!LOS_ListEmpty(&semNode.semList)) { + OsSemPendedTaskNamePrint(semCB); + } + } +} + +UINT32 OsSemInfoGetFullData(VOID) +{ + UINT32 usedSemCnt = 0; + LosSemCB *semNode = NULL; + SemDebugCB *semDebug = NULL; + UINT32 i; + UINT32 *semIndexArray = NULL; + UINT32 count, intSave; + + SCHEDULER_LOCK(intSave); + /* Get the used semaphore count. */ + for (i = 0; i < LOSCFG_BASE_IPC_SEM_LIMIT; i++) { + semNode = GET_SEM(i); + semDebug = &g_semDebugArray[i]; + if ((semNode->semStat == OS_SEM_USED) && (semDebug->creator != NULL)) { + usedSemCnt++; + } + } + SCHEDULER_UNLOCK(intSave); + + if (usedSemCnt > 0) { + semIndexArray = (UINT32 *)LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, usedSemCnt * sizeof(UINT32)); + if (semIndexArray == NULL) { + PRINTK("LOS_MemAlloc failed in %s \n", __func__); + return LOS_NOK; + } + + /* Fill the semIndexArray with the real index. */ + count = 0; + + SCHEDULER_LOCK(intSave); + for (i = 0; i < LOSCFG_BASE_IPC_SEM_LIMIT; i++) { + semNode = GET_SEM(i); + semDebug = &g_semDebugArray[i]; + if ((semNode->semStat != OS_SEM_USED) || (semDebug->creator == NULL)) { + continue; + } + *(semIndexArray + count) = i; + count++; + /* if the count is touched usedSemCnt break. */ + if (count >= usedSemCnt) { + break; + } + } + SCHEDULER_UNLOCK(intSave); + OsSemSort(semIndexArray, count); + + /* free the index array. */ + (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, semIndexArray); + } + return LOS_OK; +} +#endif /* LOSCFG_DEBUG_SEMAPHORE */ + +#ifdef LOSCFG_SHELL_CMD_DEBUG +STATIC UINT32 OsSemInfoOutput(size_t semID) +{ + UINT32 loop, semCnt, intSave; + LosSemCB *semCB = NULL; + LosSemCB semNode = {0}; + + if (semID == OS_ALL_SEM_MASK) { + for (loop = 0, semCnt = 0; loop < LOSCFG_BASE_IPC_SEM_LIMIT; loop++) { + semCB = GET_SEM(loop); + SCHEDULER_LOCK(intSave); + if (semCB->semStat == OS_SEM_USED) { + (VOID)memcpy_s(&semNode, sizeof(LosSemCB), semCB, sizeof(LosSemCB)); + SCHEDULER_UNLOCK(intSave); + semCnt++; + PRINTK("\r\n SemID Count\n ---------- -----\n"); + PRINTK(" 0x%08x %u\n", semNode.semID, semNode.semCount); + continue; + } + SCHEDULER_UNLOCK(intSave); + } + PRINTK(" SemUsingNum : %u\n\n", semCnt); + return LOS_OK; + } else { + if (GET_SEM_INDEX(semID) >= LOSCFG_BASE_IPC_SEM_LIMIT) { + PRINTK("\nInvalid semaphore id!\n"); + return LOS_OK; + } + + semCB = GET_SEM(semID); + SCHEDULER_LOCK(intSave); + (VOID)memcpy_s(&semNode, sizeof(LosSemCB), semCB, sizeof(LosSemCB)); + SCHEDULER_UNLOCK(intSave); + if ((semNode.semID != semID) || (semNode.semStat != OS_SEM_USED)) { + PRINTK("\nThe semaphore is not in use!\n"); + return LOS_OK; + } + + PRINTK("\r\n SemID Count\n ---------- -----\n"); + PRINTK(" 0x%08x 0x%u\n", semNode.semID, semNode.semCount); + + if (LOS_ListEmpty(&semNode.semList)) { + PRINTK("No task is pended on this semaphore!\n"); + return LOS_OK; + } else { + OsSemPendedTaskNamePrint(semCB); + } + } + return LOS_OK; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdSemInfoGet(UINT32 argc, const CHAR **argv) +{ + size_t semID; + CHAR *endPtr = NULL; + UINT32 ret; + + if (argc > 1) { +#ifdef LOSCFG_DEBUG_SEMAPHORE + PRINTK("\nUsage: sem [fulldata|ID]\n"); +#else + PRINTK("\nUsage: sem [ID]\n"); +#endif + return OS_ERROR; + } + + if (argc == 0) { + semID = OS_ALL_SEM_MASK; + } else { +#ifdef LOSCFG_DEBUG_SEMAPHORE + if (strcmp(argv[0], "fulldata") == 0) { + ret = OsSemInfoGetFullData(); + return ret; + } +#endif + semID = strtoul(argv[0], &endPtr, 0); + if ((endPtr == NULL) || (*endPtr != 0)) { + PRINTK("\nsem ID can't access %s.\n", argv[0]); + return 0; + } + } + + ret = OsSemInfoOutput(semID); + return ret; +} + +SHELLCMD_ENTRY(sem_shellcmd, CMD_TYPE_EX, "sem", 1, (CmdCallBackFunc)OsShellCmdSemInfoGet); +#endif + diff --git a/src/kernel_liteos_a/kernel/base/ipc/los_signal.c b/src/kernel_liteos_a/kernel/base/ipc/los_signal.c new file mode 100644 index 00000000..bb7bd2f7 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/ipc/los_signal.c @@ -0,0 +1,794 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_signal.h" +#include "pthread.h" +#include "los_process_pri.h" +#include "los_sched_pri.h" +#include "los_hw_pri.h" +#include "user_copy.h" +#ifdef LOSCFG_SECURITY_CAPABILITY +#include "capability_api.h" +#endif +#include "los_atomic.h" + +#ifdef LOSCFG_KERNEL_VM + +int raise(int sig) +{ + (VOID)sig; + PRINT_ERR("%s NOT SUPPORT\n", __FUNCTION__); + errno = ENOSYS; + return -1; +} + +#define GETUNMASKSET(procmask, pendFlag) ((~(procmask)) & (sigset_t)(pendFlag)) +#define UINT64_BIT_SIZE 64 + +int OsSigIsMember(const sigset_t *set, int signo) +{ + int ret = LOS_NOK; + /* In musl, sig No bits 00000100 present sig No 3, but 1<< 3 = 00001000, so signo needs minus 1 */ + signo -= 1; + /* Verify the signal */ + if (GOOD_SIGNO(signo)) { + /* Check if the signal is in the set */ + ret = ((*set & SIGNO2SET((unsigned int)signo)) != 0); + } + + return ret; +} + +STATIC VOID OsMoveTmpInfoToUnbInfo(sig_cb *sigcb, INT32 signo) +{ + SigInfoListNode *tmpInfoNode = sigcb->tmpInfoListHead; + SigInfoListNode **prevHook = &sigcb->tmpInfoListHead; + while (tmpInfoNode != NULL) { + if (tmpInfoNode->info.si_signo == signo) { + /* copy tmpinfo to unbinfo. */ + (VOID)memcpy_s(&sigcb->sigunbinfo, sizeof(siginfo_t), &tmpInfoNode->info, sizeof(siginfo_t)); + /* delete tmpinfo from tmpList. */ + *prevHook = tmpInfoNode->next; + (VOID)LOS_MemFree(m_aucSysMem0, tmpInfoNode); + break; + } + prevHook = &tmpInfoNode->next; + tmpInfoNode = tmpInfoNode->next; + } +} + +STATIC INT32 OsAddSigInfoToTmpList(sig_cb *sigcb, siginfo_t *info) +{ + /* try to find the old siginfo */ + SigInfoListNode *tmp = sigcb->tmpInfoListHead; + while (tmp != NULL) { + if (tmp->info.si_signo == info->si_signo) { + /* found it, break. */ + break; + } + tmp = tmp->next; + } + + if (tmp == NULL) { + /* none, alloc new one */ + tmp = (SigInfoListNode *)LOS_MemAlloc(m_aucSysMem0, sizeof(SigInfoListNode)); + if (tmp == NULL) { + return LOS_NOK; + } + tmp->next = sigcb->tmpInfoListHead; + sigcb->tmpInfoListHead = tmp; + } + + (VOID)memcpy_s(&tmp->info, sizeof(siginfo_t), info, sizeof(siginfo_t)); + + return LOS_OK; +} + +VOID OsClearSigInfoTmpList(sig_cb *sigcb) +{ + while (sigcb->tmpInfoListHead != NULL) { + SigInfoListNode *tmpInfoNode = sigcb->tmpInfoListHead; + sigcb->tmpInfoListHead = sigcb->tmpInfoListHead->next; + (VOID)LOS_MemFree(m_aucSysMem0, tmpInfoNode); + } +} + +STATIC INLINE VOID OsSigWaitTaskWake(LosTaskCB *taskCB, INT32 signo) +{ + sig_cb *sigcb = &taskCB->sig; + + if (!LOS_ListEmpty(&sigcb->waitList) && OsSigIsMember(&sigcb->sigwaitmask, signo)) { + OsMoveTmpInfoToUnbInfo(sigcb, signo); + OsTaskWakeClearPendMask(taskCB); + taskCB->ops->wake(taskCB); + OsSigEmptySet(&sigcb->sigwaitmask); + } +} + +STATIC UINT32 OsPendingTaskWake(LosTaskCB *taskCB, INT32 signo) +{ + if (!OsTaskIsPending(taskCB) || !OsProcessIsUserMode(OS_PCB_FROM_TCB(taskCB))) { + return 0; + } + + if ((signo != SIGKILL) && (taskCB->waitFlag != OS_TASK_WAIT_SIGNAL)) { + return 0; + } + + switch (taskCB->waitFlag) { + case OS_TASK_WAIT_PROCESS: + case OS_TASK_WAIT_GID: + case OS_TASK_WAIT_ANYPROCESS: + OsWaitWakeTask(taskCB, OS_INVALID_VALUE); + break; + case OS_TASK_WAIT_JOIN: + OsTaskWakeClearPendMask(taskCB); + taskCB->ops->wake(taskCB); + break; + case OS_TASK_WAIT_SIGNAL: + OsSigWaitTaskWake(taskCB, signo); + break; + case OS_TASK_WAIT_LITEIPC: + OsTaskWakeClearPendMask(taskCB); + taskCB->ops->wake(taskCB); + break; + case OS_TASK_WAIT_FUTEX: + OsFutexNodeDeleteFromFutexHash(&taskCB->futex, TRUE, NULL, NULL); + OsTaskWakeClearPendMask(taskCB); + taskCB->ops->wake(taskCB); + break; + default: + break; + } + + return 0; +} + +int OsTcbDispatch(LosTaskCB *stcb, siginfo_t *info) +{ + bool masked = FALSE; + sig_cb *sigcb = &stcb->sig; + + OS_RETURN_IF_NULL(sigcb); + /* If signo is 0, not send signal, just check process or pthread exist */ + if (info->si_signo == 0) { + return 0; + } + masked = (bool)OsSigIsMember(&sigcb->sigprocmask, info->si_signo); + if (masked) { + /* If signal is in wait list and mask list, need unblock it */ + if (LOS_ListEmpty(&sigcb->waitList) || + (!LOS_ListEmpty(&sigcb->waitList) && !OsSigIsMember(&sigcb->sigwaitmask, info->si_signo))) { + OsSigAddSet(&sigcb->sigPendFlag, info->si_signo); + } + } else { + /* unmasked signal actions */ + OsSigAddSet(&sigcb->sigFlag, info->si_signo); + } + + if (OsAddSigInfoToTmpList(sigcb, info) == LOS_NOK) { + return -ENOMEM; + } + + return OsPendingTaskWake(stcb, info->si_signo); +} + +void OsSigMaskSwitch(LosTaskCB * const rtcb, sigset_t set) +{ + sigset_t unmaskset; + + rtcb->sig.sigprocmask = set; + unmaskset = GETUNMASKSET(rtcb->sig.sigprocmask, rtcb->sig.sigPendFlag); + if (unmaskset != NULL_SIGNAL_SET) { + /* pendlist do */ + rtcb->sig.sigFlag |= unmaskset; + rtcb->sig.sigPendFlag ^= unmaskset; + } +} + +int OsSigprocMask(int how, const sigset_t_l *setl, sigset_t_l *oldsetl) +{ + LosTaskCB *spcb = NULL; + int ret = LOS_OK; + unsigned int intSave; + sigset_t set; + + SCHEDULER_LOCK(intSave); + spcb = OsCurrTaskGet(); + /* If requested, copy the old mask to user. */ + if (oldsetl != NULL) { + *(sigset_t *)oldsetl = spcb->sig.sigprocmask; + } + /* If requested, modify the current signal mask. */ + if (setl != NULL) { + set = *(sigset_t *)setl; + /* Okay, determine what we are supposed to do */ + switch (how) { + /* Set the union of the current set and the signal + * set pointed to by set as the new sigprocmask. + */ + case SIG_BLOCK: + spcb->sig.sigprocmask |= set; + break; + /* Set the intersection of the current set and the + * signal set pointed to by set as the new sigprocmask. + */ + case SIG_UNBLOCK: + spcb->sig.sigprocmask &= ~(set); + break; + /* Set the signal set pointed to by set as the new sigprocmask. */ + case SIG_SETMASK: + spcb->sig.sigprocmask = set; + break; + default: + ret = -EINVAL; + break; + } + /* If pending mask not in sigmask, need set sigflag. */ + OsSigMaskSwitch(spcb, spcb->sig.sigprocmask); + } + SCHEDULER_UNLOCK(intSave); + + return ret; +} + +int OsSigProcessForeachChild(LosProcessCB *spcb, ForEachTaskCB handler, void *arg) +{ + int ret; + + /* Visit the main thread last (if present) */ + LosTaskCB *taskCB = NULL; + LOS_DL_LIST_FOR_EACH_ENTRY(taskCB, &(spcb->threadSiblingList), LosTaskCB, threadList) { + ret = handler(taskCB, arg); + OS_RETURN_IF(ret != 0, ret); + } + return LOS_OK; +} + +static int SigProcessSignalHandler(LosTaskCB *tcb, void *arg) +{ + struct ProcessSignalInfo *info = (struct ProcessSignalInfo *)arg; + int ret; + int isMember; + + if (tcb == NULL) { + return 0; + } + + /* If the default tcb is not set, then set this one as default. */ + if (!info->defaultTcb) { + info->defaultTcb = tcb; + } + + isMember = OsSigIsMember(&tcb->sig.sigwaitmask, info->sigInfo->si_signo); + if (isMember && (!info->awakenedTcb)) { + /* This means the task is waiting for this signal. Stop looking for it and use this tcb. + * The requirement is: if more than one task in this task group is waiting for the signal, + * then only one indeterminate task in the group will receive the signal. + */ + ret = OsTcbDispatch(tcb, info->sigInfo); + OS_RETURN_IF(ret < 0, ret); + + /* set this tcb as awakenedTcb */ + info->awakenedTcb = tcb; + OS_RETURN_IF(info->receivedTcb != NULL, SIG_STOP_VISIT); /* Stop search */ + } + /* Is this signal unblocked on this thread? */ + isMember = OsSigIsMember(&tcb->sig.sigprocmask, info->sigInfo->si_signo); + if ((!isMember) && (!info->receivedTcb) && (tcb != info->awakenedTcb)) { + /* if unblockedTcb of this signal is not set, then set it. */ + if (!info->unblockedTcb) { + info->unblockedTcb = tcb; + } + + ret = OsTcbDispatch(tcb, info->sigInfo); + OS_RETURN_IF(ret < 0, ret); + /* set this tcb as receivedTcb */ + info->receivedTcb = tcb; + OS_RETURN_IF(info->awakenedTcb != NULL, SIG_STOP_VISIT); /* Stop search */ + } + return 0; /* Keep searching */ +} + +static int SigProcessKillSigHandler(LosTaskCB *tcb, void *arg) +{ + struct ProcessSignalInfo *info = (struct ProcessSignalInfo *)arg; + + return OsPendingTaskWake(tcb, info->sigInfo->si_signo); +} + +static void SigProcessLoadTcb(struct ProcessSignalInfo *info, siginfo_t *sigInfo) +{ + LosTaskCB *tcb = NULL; + + if (info->awakenedTcb == NULL && info->receivedTcb == NULL) { + if (info->unblockedTcb) { + tcb = info->unblockedTcb; + } else if (info->defaultTcb) { + tcb = info->defaultTcb; + } else { + return; + } + /* Deliver the signal to the selected task */ + (void)OsTcbDispatch(tcb, sigInfo); + } +} + +int OsSigProcessSend(LosProcessCB *spcb, siginfo_t *sigInfo) +{ + int ret; + struct ProcessSignalInfo info = { + .sigInfo = sigInfo, + .defaultTcb = NULL, + .unblockedTcb = NULL, + .awakenedTcb = NULL, + .receivedTcb = NULL + }; + + if (info.sigInfo == NULL) { + return -EFAULT; + } + + /* visit all taskcb and dispatch signal */ + if (info.sigInfo->si_signo == SIGKILL) { + OsSigAddSet(&spcb->sigShare, info.sigInfo->si_signo); + (void)OsSigProcessForeachChild(spcb, SigProcessKillSigHandler, &info); + return 0; + } else { + ret = OsSigProcessForeachChild(spcb, SigProcessSignalHandler, &info); + } + if (ret < 0) { + return ret; + } + SigProcessLoadTcb(&info, sigInfo); + return 0; +} + +int OsSigEmptySet(sigset_t *set) +{ + *set = NULL_SIGNAL_SET; + return 0; +} + +/* Privilege process can't send to kernel and privilege process */ +static int OsSignalPermissionToCheck(const LosProcessCB *spcb) +{ + UINTPTR gid = (UINTPTR)OS_GET_PGROUP_LEADER(spcb->pgroup); + if (gid == OS_KERNEL_PROCESS_GROUP) { + return -EPERM; + } else if (gid == OS_USER_PRIVILEGE_PROCESS_GROUP) { + return -EPERM; + } + + return 0; +} + +STATIC int SendSigPermissionCheck(LosProcessCB *spcb, int permission) +{ + if (spcb == NULL) { + return -ESRCH; + } + + if (OsProcessIsUnused(spcb)) { + return -ESRCH; + } + +#ifdef LOSCFG_SECURITY_CAPABILITY + LosProcessCB *current = OsCurrProcessGet(); + /* Kernel process always has kill permission and user process should check permission */ + if (OsProcessIsUserMode(current) && !(current->processStatus & OS_PROCESS_FLAG_EXIT)) { + if ((current != spcb) && (!IsCapPermit(CAP_KILL)) && (current->user->userID != spcb->user->userID)) { + return -EPERM; + } + } +#endif + if ((permission == OS_USER_KILL_PERMISSION) && (OsSignalPermissionToCheck(spcb) < 0)) { + return -EPERM; + } + return LOS_OK; +} + +int OsSendSigToProcess(LosProcessCB *spcb, int sig, int permission) +{ + siginfo_t info; + int ret = SendSigPermissionCheck(spcb, permission); + if (ret != LOS_OK) { + return ret; + } + + /* If the process you want to kill had been inactive, but still exist. should return LOS_OK */ + if (OsProcessIsInactive(spcb)) { + return LOS_OK; + } + + if (!GOOD_SIGNO(sig)) { + return -EINVAL; + } + + info.si_signo = sig; + info.si_code = SI_USER; + info.si_value.sival_ptr = NULL; + + return OsSigProcessSend(spcb, &info); +} + +int OsDispatch(pid_t pid, siginfo_t *info, int permission) +{ + if (OsProcessIDUserCheckInvalid(pid) || pid < 0) { + return -ESRCH; + } + + LosProcessCB *spcb = OS_PCB_FROM_PID(pid); + int ret = SendSigPermissionCheck(spcb, permission); + if (ret != LOS_OK) { + return ret; + } + + /* If the process you want to kill had been inactive, but still exist. should return LOS_OK */ + if (OsProcessIsInactive(spcb)) { + return LOS_OK; + } + + return OsSigProcessSend(spcb, info); +} + +int OsKill(pid_t pid, int sig, int permission) +{ + siginfo_t info; + int ret; + + /* Make sure that the para is valid */ + if (!GOOD_SIGNO(sig)) { + return -EINVAL; + } + + /* Create the siginfo structure */ + info.si_signo = sig; + info.si_code = SI_USER; + info.si_value.sival_ptr = NULL; + + if (pid > 0) { + /* Send the signal to the specify process */ + ret = OsDispatch(pid, &info, permission); + } else if (pid == -1) { + /* Send SIG to all processes */ + ret = OsSendSignalToAllProcess(&info, permission); + } else { + /* Send SIG to all processes in process group PGRP. + If PGRP is zero, send SIG to all processes in + the current process's process group. */ + ret = OsSendSignalToProcessGroup(pid, &info, permission); + } + return ret; +} + +int OsKillLock(pid_t pid, int sig) +{ + int ret; + unsigned int intSave; + + SCHEDULER_LOCK(intSave); + ret = OsKill(pid, sig, OS_USER_KILL_PERMISSION); + SCHEDULER_UNLOCK(intSave); + return ret; +} + +INT32 OsTaskKillUnsafe(UINT32 taskID, INT32 signo) +{ + siginfo_t info; + LosTaskCB *taskCB = OsGetTaskCB(taskID); + INT32 ret = OsUserTaskOperatePermissionsCheck(taskCB); + if (ret != LOS_OK) { + return -ret; + } + + /* Create the siginfo structure */ + info.si_signo = signo; + info.si_code = SI_USER; + info.si_value.sival_ptr = NULL; + + /* Dispatch the signal to thread, bypassing normal task group thread + * dispatch rules. */ + return OsTcbDispatch(taskCB, &info); +} + +int OsPthreadKill(UINT32 tid, int signo) +{ + int ret; + UINT32 intSave; + + /* Make sure that the signal is valid */ + OS_RETURN_IF(!GOOD_SIGNO(signo), -EINVAL); + if (OS_TID_CHECK_INVALID(tid)) { + return -ESRCH; + } + + /* Keep things stationary through the following */ + SCHEDULER_LOCK(intSave); + ret = OsTaskKillUnsafe(tid, signo); + SCHEDULER_UNLOCK(intSave); + return ret; +} + +int OsSigAddSet(sigset_t *set, int signo) +{ + /* Verify the signal */ + if (!GOOD_SIGNO(signo)) { + return -EINVAL; + } else { + /* In musl, sig No bits 00000100 present sig No 3, but 1<< 3 = 00001000, so signo needs minus 1 */ + signo -= 1; + /* Add the signal to the set */ + *set |= SIGNO2SET((unsigned int)signo); + return LOS_OK; + } +} + +int OsSigPending(sigset_t *set) +{ + LosTaskCB *tcb = NULL; + unsigned int intSave; + + if (set == NULL) { + return -EFAULT; + } + + SCHEDULER_LOCK(intSave); + tcb = OsCurrTaskGet(); + *set = tcb->sig.sigPendFlag; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +STATIC int FindFirstSetedBit(UINT64 n) +{ + int count; + + if (n == 0) { + return -1; + } + for (count = 0; (count < UINT64_BIT_SIZE) && (n ^ 1ULL); n >>= 1, count++) {} + return (count < UINT64_BIT_SIZE) ? count : (-1); +} + +int OsSigTimedWaitNoLock(sigset_t *set, siginfo_t *info, unsigned int timeout) +{ + LosTaskCB *task = NULL; + sig_cb *sigcb = NULL; + int ret; + + task = OsCurrTaskGet(); + sigcb = &task->sig; + + if (sigcb->waitList.pstNext == NULL) { + LOS_ListInit(&sigcb->waitList); + } + /* If pendingflag & set > 0, should clear pending flag */ + sigset_t clear = sigcb->sigPendFlag & *set; + if (clear) { + sigcb->sigPendFlag ^= clear; + ret = FindFirstSetedBit((UINT64)clear) + 1; + OsMoveTmpInfoToUnbInfo(sigcb, ret); + } else { + OsSigAddSet(set, SIGKILL); + OsSigAddSet(set, SIGSTOP); + + sigcb->sigwaitmask |= *set; + OsTaskWaitSetPendMask(OS_TASK_WAIT_SIGNAL, sigcb->sigwaitmask, timeout); + ret = task->ops->wait(task, &sigcb->waitList, timeout); + if (ret == LOS_ERRNO_TSK_TIMEOUT) { + ret = -EAGAIN; + } + sigcb->sigwaitmask = NULL_SIGNAL_SET; + } + if (info != NULL) { + (VOID)memcpy_s(info, sizeof(siginfo_t), &sigcb->sigunbinfo, sizeof(siginfo_t)); + } + return ret; +} + +int OsSigTimedWait(sigset_t *set, siginfo_t *info, unsigned int timeout) +{ + int ret; + unsigned int intSave; + + SCHEDULER_LOCK(intSave); + + ret = OsSigTimedWaitNoLock(set, info, timeout); + + SCHEDULER_UNLOCK(intSave); + return ret; +} + +int OsPause(void) +{ + LosTaskCB *spcb = NULL; + sigset_t oldSigprocmask; + + spcb = OsCurrTaskGet(); + oldSigprocmask = spcb->sig.sigprocmask; + return OsSigSuspend(&oldSigprocmask); +} + +int OsSigSuspend(const sigset_t *set) +{ + unsigned int intSave; + LosTaskCB *rtcb = NULL; + sigset_t setSuspend; + int ret; + + if (set == NULL) { + return -EINVAL; + } + SCHEDULER_LOCK(intSave); + rtcb = OsCurrTaskGet(); + + /* Wait signal calc */ + setSuspend = FULL_SIGNAL_SET & (~(*set)); + + /* If pending mask not in sigmask, need set sigflag */ + OsSigMaskSwitch(rtcb, *set); + + if (rtcb->sig.sigFlag > 0) { + SCHEDULER_UNLOCK(intSave); + + /* + * If rtcb->sig.sigFlag > 0, it means that some signal have been + * received, and we need to do schedule to handle the signal directly. + */ + LOS_Schedule(); + return -EINTR; + } else { + ret = OsSigTimedWaitNoLock(&setSuspend, NULL, LOS_WAIT_FOREVER); + if (ret < 0) { + PRINT_ERR("FUNC %s LINE = %d, ret = %x\n", __FUNCTION__, __LINE__, ret); + } + } + + SCHEDULER_UNLOCK(intSave); + return -EINTR; +} + +int OsSigAction(int sig, const sigaction_t *act, sigaction_t *oact) +{ + UINTPTR addr; + sigaction_t action; + + if (!GOOD_SIGNO(sig) || sig < 1 || act == NULL) { + return -EINVAL; + } + if (LOS_ArchCopyFromUser(&action, act, sizeof(sigaction_t)) != LOS_OK) { + return -EFAULT; + } + + if (sig == SIGSYS) { + addr = OsGetSigHandler(); + if (addr == 0) { + OsSetSigHandler((unsigned long)(UINTPTR)action.sa_handler); + return LOS_OK; + } + return -EINVAL; + } + + return LOS_OK; +} + +VOID OsSigIntLock(VOID) +{ + LosTaskCB *task = OsCurrTaskGet(); + sig_cb *sigcb = &task->sig; + + (VOID)LOS_AtomicAdd((Atomic *)&sigcb->sigIntLock, 1); +} + +VOID OsSigIntUnlock(VOID) +{ + LosTaskCB *task = OsCurrTaskGet(); + sig_cb *sigcb = &task->sig; + + (VOID)LOS_AtomicSub((Atomic *)&sigcb->sigIntLock, 1); +} + +VOID *OsSaveSignalContext(VOID *sp, VOID *newSp) +{ + UINTPTR sigHandler; + UINT32 intSave; + + LosTaskCB *task = OsCurrTaskGet(); + LosProcessCB *process = OsCurrProcessGet(); + sig_cb *sigcb = &task->sig; + + /* A thread is not allowed to interrupt the processing of its signals during a system call */ + if (sigcb->sigIntLock > 0) { + return sp; + } + + if (OsTaskIsKilled(task)) { + OsRunningTaskToExit(task, 0); + return sp; + } + + SCHEDULER_LOCK(intSave); + if ((sigcb->count == 0) && ((sigcb->sigFlag != 0) || (process->sigShare != 0))) { + sigHandler = OsGetSigHandler(); + if (sigHandler == 0) { + sigcb->sigFlag = 0; + process->sigShare = 0; + SCHEDULER_UNLOCK(intSave); + PRINT_ERR("The signal processing function for the current process pid =%d is NULL!\n", process->processID); + return sp; + } + /* One pthread do the share signal */ + sigcb->sigFlag |= process->sigShare; + UINT32 signo = (UINT32)FindFirstSetedBit(sigcb->sigFlag) + 1; + UINT32 sigVal = (UINT32)(UINTPTR)(sigcb->sigunbinfo.si_value.sival_ptr); + OsMoveTmpInfoToUnbInfo(sigcb, signo); + OsProcessExitCodeSignalSet(process, signo); + sigcb->sigContext = sp; + + OsInitSignalContext(sp, newSp, sigHandler, signo, sigVal); + + /* sig No bits 00000100 present sig No 3, but 1<< 3 = 00001000, so signo needs minus 1 */ + sigcb->sigFlag ^= 1ULL << (signo - 1); + sigcb->count++; + SCHEDULER_UNLOCK(intSave); + return newSp; + } + + SCHEDULER_UNLOCK(intSave); + return sp; +} + +VOID *OsRestorSignalContext(VOID *sp) +{ + UINT32 intSave; + + LosTaskCB *task = OsCurrTaskGet(); + sig_cb *sigcb = &task->sig; + + SCHEDULER_LOCK(intSave); + if (sigcb->count != 1) { + SCHEDULER_UNLOCK(intSave); + PRINT_ERR("sig error count : %d\n", sigcb->count); + return sp; + } + + LosProcessCB *process = OsCurrProcessGet(); + VOID *saveContext = sigcb->sigContext; + sigcb->sigContext = NULL; + sigcb->count--; + process->sigShare = 0; + OsProcessExitCodeSignalClear(process); + SCHEDULER_UNLOCK(intSave); + return saveContext; +} + +#endif diff --git a/src/kernel_liteos_a/kernel/base/mem/common/los_memstat.c b/src/kernel_liteos_a/kernel/base/mem/common/los_memstat.c new file mode 100644 index 00000000..91164b4c --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/mem/common/los_memstat.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_memstat_pri.h" +#include "los_task_pri.h" + + +LITE_OS_SEC_BSS_MINOR STATIC TskMemUsedInfo g_tskMemUsedInfo[LOSCFG_BASE_CORE_TSK_LIMIT]; + +LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemUsedInc(UINT32 usedSize, UINT32 taskID) +{ + if (taskID >= LOSCFG_BASE_CORE_TSK_LIMIT) { + return; + } + if (OS_INT_ACTIVE) { + return; + } + g_tskMemUsedInfo[taskID].memUsed += usedSize; +} + +LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemUsedDec(UINT32 usedSize, UINT32 taskID) +{ + if (taskID >= LOSCFG_BASE_CORE_TSK_LIMIT) { + return; + } + if (OS_INT_ACTIVE) { + return; + } + if (g_tskMemUsedInfo[taskID].memUsed < usedSize) { + PRINT_WARN("mem used of current task '%s':0x%x, decrease size:0x%x\n", + OsCurrTaskGet()->taskName, g_tskMemUsedInfo[taskID].memUsed, usedSize); + return; + } + g_tskMemUsedInfo[taskID].memUsed -= usedSize; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 OsTaskMemUsage(UINT32 taskID) +{ + if (taskID >= LOSCFG_BASE_CORE_TSK_LIMIT) { + return LOS_NOK; + } + + return g_tskMemUsedInfo[taskID].memUsed; +} + +LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemClear(UINT32 taskID) +{ + if (taskID >= LOSCFG_BASE_CORE_TSK_LIMIT) { + return; + } + if (g_tskMemUsedInfo[taskID].memUsed != 0) { + PRINT_WARN("mem used of task '%s' is:0x%x, not zero when task being deleted\n", + OS_TCB_FROM_TID(taskID)->taskName, g_tskMemUsedInfo[taskID].memUsed); + } + g_tskMemUsedInfo[taskID].memUsed = 0; +} + +#ifdef LOS_MEM_SLAB + +LITE_OS_SEC_BSS_MINOR STATIC TskSlabUsedInfo g_tskSlabUsedInfo[LOSCFG_BASE_CORE_TSK_LIMIT]; +LITE_OS_SEC_TEXT_MINOR VOID OsTaskSlabUsedInc(UINT32 usedSize, UINT32 taskID) +{ + if (taskID >= LOSCFG_BASE_CORE_TSK_LIMIT) { + return; + } + + g_tskSlabUsedInfo[taskID].slabUsed += usedSize; +} + +LITE_OS_SEC_TEXT_MINOR VOID OsTaskSlabUsedDec(UINT32 usedSize, UINT32 taskID) +{ + if (taskID >= LOSCFG_BASE_CORE_TSK_LIMIT) { + return; + } + + g_tskSlabUsedInfo[taskID].slabUsed -= usedSize; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 OsTaskSlabUsage(UINT32 taskID) +{ + if (taskID >= LOSCFG_BASE_CORE_TSK_LIMIT) { + return LOS_NOK; + } + + return g_tskSlabUsedInfo[taskID].slabUsed; +} +#endif + diff --git a/src/kernel_liteos_a/kernel/base/mem/membox/los_membox.c b/src/kernel_liteos_a/kernel/base/mem/membox/los_membox.c new file mode 100644 index 00000000..7a4b66de --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/mem/membox/los_membox.c @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_membox.h" +#include "los_hwi.h" +#include "los_spinlock.h" + + +#ifdef LOSCFG_AARCH64 +#define OS_MEMBOX_MAGIC 0xa55a5aa5a55a5aa5 +#else +#define OS_MEMBOX_MAGIC 0xa55a5aa5 +#endif +#define OS_MEMBOX_SET_MAGIC(addr) \ + ((LOS_MEMBOX_NODE *)(addr))->pstNext = (LOS_MEMBOX_NODE *)OS_MEMBOX_MAGIC +#define OS_MEMBOX_CHECK_MAGIC(addr) \ + ((((LOS_MEMBOX_NODE *)(addr))->pstNext == (LOS_MEMBOX_NODE *)OS_MEMBOX_MAGIC) ? LOS_OK : LOS_NOK) + +#define OS_MEMBOX_USER_ADDR(addr) \ + ((VOID *)((UINT8 *)(addr) + OS_MEMBOX_NODE_HEAD_SIZE)) +#define OS_MEMBOX_NODE_ADDR(addr) \ + ((LOS_MEMBOX_NODE *)(VOID *)((UINT8 *)(addr) - OS_MEMBOX_NODE_HEAD_SIZE)) +/* spinlock for mem module, only available on SMP mode */ +LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_memboxSpin); +#define MEMBOX_LOCK(state) LOS_SpinLockSave(&g_memboxSpin, &(state)) +#define MEMBOX_UNLOCK(state) LOS_SpinUnlockRestore(&g_memboxSpin, (state)) + +STATIC INLINE UINT32 OsCheckBoxMem(const LOS_MEMBOX_INFO *boxInfo, const VOID *node) +{ + UINT32 offset; + + if (boxInfo->uwBlkSize == 0) { + return LOS_NOK; + } + + offset = (UINT32)((UINTPTR)node - (UINTPTR)(boxInfo + 1)); + if ((offset % boxInfo->uwBlkSize) != 0) { + return LOS_NOK; + } + + if ((offset / boxInfo->uwBlkSize) >= boxInfo->uwBlkNum) { + return LOS_NOK; + } + + return OS_MEMBOX_CHECK_MAGIC(node); +} + +LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemboxInit(VOID *pool, UINT32 poolSize, UINT32 blkSize) +{ + LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool; + LOS_MEMBOX_NODE *node = NULL; + UINT32 index; + UINT32 intSave; + + if (pool == NULL) { + return LOS_NOK; + } + + if (blkSize == 0) { + return LOS_NOK; + } + + if (poolSize < sizeof(LOS_MEMBOX_INFO)) { + return LOS_NOK; + } + + MEMBOX_LOCK(intSave); + boxInfo->uwBlkSize = LOS_MEMBOX_ALIGNED(blkSize + OS_MEMBOX_NODE_HEAD_SIZE); + boxInfo->uwBlkNum = (poolSize - sizeof(LOS_MEMBOX_INFO)) / boxInfo->uwBlkSize; + boxInfo->uwBlkCnt = 0; + if (boxInfo->uwBlkNum == 0) { + MEMBOX_UNLOCK(intSave); + return LOS_NOK; + } + + node = (LOS_MEMBOX_NODE *)(boxInfo + 1); + + boxInfo->stFreeList.pstNext = node; + + for (index = 0; index < boxInfo->uwBlkNum - 1; ++index) { + node->pstNext = OS_MEMBOX_NEXT(node, boxInfo->uwBlkSize); + node = node->pstNext; + } + + node->pstNext = NULL; + + MEMBOX_UNLOCK(intSave); + + return LOS_OK; +} + +LITE_OS_SEC_TEXT VOID *LOS_MemboxAlloc(VOID *pool) +{ + LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool; + LOS_MEMBOX_NODE *node = NULL; + LOS_MEMBOX_NODE *nodeTmp = NULL; + UINT32 intSave; + + if (pool == NULL) { + return NULL; + } + + MEMBOX_LOCK(intSave); + node = &(boxInfo->stFreeList); + if (node->pstNext != NULL) { + nodeTmp = node->pstNext; + node->pstNext = nodeTmp->pstNext; + OS_MEMBOX_SET_MAGIC(nodeTmp); + boxInfo->uwBlkCnt++; + } + MEMBOX_UNLOCK(intSave); + + return (nodeTmp == NULL) ? NULL : OS_MEMBOX_USER_ADDR(nodeTmp); +} + +LITE_OS_SEC_TEXT UINT32 LOS_MemboxFree(VOID *pool, VOID *box) +{ + LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool; + UINT32 ret = LOS_NOK; + UINT32 intSave; + + if ((pool == NULL) || (box == NULL)) { + return LOS_NOK; + } + + MEMBOX_LOCK(intSave); + do { + LOS_MEMBOX_NODE *node = OS_MEMBOX_NODE_ADDR(box); + if (OsCheckBoxMem(boxInfo, node) != LOS_OK) { + break; + } + + node->pstNext = boxInfo->stFreeList.pstNext; + boxInfo->stFreeList.pstNext = node; + boxInfo->uwBlkCnt--; + ret = LOS_OK; + } while (0); + MEMBOX_UNLOCK(intSave); + + return ret; +} + +LITE_OS_SEC_TEXT_MINOR VOID LOS_MemboxClr(VOID *pool, VOID *box) +{ + LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool; + + if ((pool == NULL) || (box == NULL)) { + return; + } + + (VOID)memset_s(box, (boxInfo->uwBlkSize - OS_MEMBOX_NODE_HEAD_SIZE), 0, + (boxInfo->uwBlkSize - OS_MEMBOX_NODE_HEAD_SIZE)); +} + +LITE_OS_SEC_TEXT_MINOR VOID LOS_ShowBox(VOID *pool) +{ + UINT32 index; + UINT32 intSave; + LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool; + LOS_MEMBOX_NODE *node = NULL; + + if (pool == NULL) { + return; + } + MEMBOX_LOCK(intSave); + PRINT_INFO("membox(%p,0x%x,0x%x):\r\n", pool, boxInfo->uwBlkSize, boxInfo->uwBlkNum); + PRINT_INFO("free node list:\r\n"); + + for (node = boxInfo->stFreeList.pstNext, index = 0; node != NULL; + node = node->pstNext, ++index) { + PRINT_INFO("(%u,%p)\r\n", index, node); + } + + PRINT_INFO("all node list:\r\n"); + node = (LOS_MEMBOX_NODE *)(boxInfo + 1); + for (index = 0; index < boxInfo->uwBlkNum; ++index, node = OS_MEMBOX_NEXT(node, boxInfo->uwBlkSize)) { + PRINT_INFO("(%u,%p,%p)\r\n", index, node, node->pstNext); + } + MEMBOX_UNLOCK(intSave); +} + +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemboxStatisticsGet(const VOID *boxMem, UINT32 *maxBlk, + UINT32 *blkCnt, UINT32 *blkSize) +{ + if ((boxMem == NULL) || (maxBlk == NULL) || (blkCnt == NULL) || (blkSize == NULL)) { + return LOS_NOK; + } + + *maxBlk = ((OS_MEMBOX_S *)boxMem)->uwBlkNum; + *blkCnt = ((OS_MEMBOX_S *)boxMem)->uwBlkCnt; + *blkSize = ((OS_MEMBOX_S *)boxMem)->uwBlkSize; + + return LOS_OK; +} + diff --git a/src/kernel_liteos_a/kernel/base/mem/tlsf/los_memory.c b/src/kernel_liteos_a/kernel/base/mem/tlsf/los_memory.c new file mode 100644 index 00000000..3441b613 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/mem/tlsf/los_memory.c @@ -0,0 +1,2083 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_memory.h" +#include "los_memory_pri.h" +#include "sys/param.h" +#include "los_spinlock.h" +#include "los_vm_phys.h" +#include "los_vm_boot.h" +#include "los_vm_filemap.h" +#include "los_task_pri.h" +#include "los_hook.h" + +#ifdef LOSCFG_KERNEL_LMS +#include "los_lms_pri.h" +#endif + +/* Used to cut non-essential functions. */ +#define OS_MEM_FREE_BY_TASKID 0 +#ifdef LOSCFG_KERNEL_VM +#define OS_MEM_EXPAND_ENABLE 1 +#else +#define OS_MEM_EXPAND_ENABLE 0 +#endif + +/* the dump size of current broken node when memcheck error */ +#define OS_MEM_NODE_DUMP_SIZE 64 +/* column num of the output info of mem node */ +#define OS_MEM_COLUMN_NUM 8 + +UINT8 *m_aucSysMem0 = NULL; +UINT8 *m_aucSysMem1 = NULL; + +#ifdef LOSCFG_MEM_MUL_POOL +VOID *g_poolHead = NULL; +#endif + +/* The following is the macro definition and interface implementation related to the TLSF. */ + +/* Supposing a Second Level Index: SLI = 3. */ +#define OS_MEM_SLI 3 +/* Giving 1 free list for each small bucket: 4, 8, 12, up to 124. */ +#define OS_MEM_SMALL_BUCKET_COUNT 31 +#define OS_MEM_SMALL_BUCKET_MAX_SIZE 128 +/* Giving OS_MEM_FREE_LIST_NUM free lists for each large bucket. */ +#define OS_MEM_LARGE_BUCKET_COUNT 24 +#define OS_MEM_FREE_LIST_NUM (1 << OS_MEM_SLI) +/* OS_MEM_SMALL_BUCKET_MAX_SIZE to the power of 2 is 7. */ +#define OS_MEM_LARGE_START_BUCKET 7 + +/* The count of free list. */ +#define OS_MEM_FREE_LIST_COUNT (OS_MEM_SMALL_BUCKET_COUNT + (OS_MEM_LARGE_BUCKET_COUNT << OS_MEM_SLI)) +/* The bitmap is used to indicate whether the free list is empty, 1: not empty, 0: empty. */ +#define OS_MEM_BITMAP_WORDS ((OS_MEM_FREE_LIST_COUNT >> 5) + 1) + +#define OS_MEM_BITMAP_MASK 0x1FU + +/* Used to find the first bit of 1 in bitmap. */ +STATIC INLINE UINT16 OsMemFFS(UINT32 bitmap) +{ + bitmap &= ~bitmap + 1; + return (OS_MEM_BITMAP_MASK - CLZ(bitmap)); +} + +/* Used to find the last bit of 1 in bitmap. */ +STATIC INLINE UINT16 OsMemFLS(UINT32 bitmap) +{ + return (OS_MEM_BITMAP_MASK - CLZ(bitmap)); +} + +STATIC INLINE UINT32 OsMemLog2(UINT32 size) +{ + return OsMemFLS(size); +} + +/* Get the first level: f = log2(size). */ +STATIC INLINE UINT32 OsMemFlGet(UINT32 size) +{ + if (size < OS_MEM_SMALL_BUCKET_MAX_SIZE) { + return ((size >> 2) - 1); /* 2: The small bucket setup is 4. */ + } + return OsMemLog2(size); +} + +/* Get the second level: s = (size - 2^f) * 2^SLI / 2^f. */ +STATIC INLINE UINT32 OsMemSlGet(UINT32 size, UINT32 fl) +{ + return (((size << OS_MEM_SLI) >> fl) - OS_MEM_FREE_LIST_NUM); +} + +/* The following is the memory algorithm related macro definition and interface implementation. */ + +struct OsMemNodeHead { + UINT32 magic; + union { + struct OsMemNodeHead *prev; /* The prev is used for current node points to the previous node */ + struct OsMemNodeHead *next; /* The next is used for last node points to the expand node */ + } ptr; +#ifdef LOSCFG_MEM_LEAKCHECK + UINTPTR linkReg[LOS_RECORD_LR_CNT]; +#endif + UINT32 sizeAndFlag; +}; + +struct OsMemUsedNodeHead { + struct OsMemNodeHead header; +#if OS_MEM_FREE_BY_TASKID + UINT32 taskID; +#endif +}; + +struct OsMemFreeNodeHead { + struct OsMemNodeHead header; + struct OsMemFreeNodeHead *prev; + struct OsMemFreeNodeHead *next; +}; + +struct OsMemPoolInfo { + VOID *pool; + UINT32 totalSize; + UINT32 attr; +#ifdef LOSCFG_MEM_WATERLINE + UINT32 waterLine; /* Maximum usage size in a memory pool */ + UINT32 curUsedSize; /* Current usage size in a memory pool */ +#endif +}; + +struct OsMemPoolHead { + struct OsMemPoolInfo info; + UINT32 freeListBitmap[OS_MEM_BITMAP_WORDS]; + struct OsMemFreeNodeHead *freeList[OS_MEM_FREE_LIST_COUNT]; + SPIN_LOCK_S spinlock; +#ifdef LOSCFG_MEM_MUL_POOL + VOID *nextPool; +#endif +}; + +/* Spinlock for mem module, only available on SMP mode */ +#define MEM_LOCK(pool, state) LOS_SpinLockSave(&(pool)->spinlock, &(state)) +#define MEM_UNLOCK(pool, state) LOS_SpinUnlockRestore(&(pool)->spinlock, (state)) + +/* The memory pool support expand. */ +#define OS_MEM_POOL_EXPAND_ENABLE 0x01 +/* The memory pool support no lock. */ +#define OS_MEM_POOL_LOCK_ENABLE 0x02 + +#define OS_MEM_NODE_MAGIC 0xABCDDCBA +#define OS_MEM_MIN_ALLOC_SIZE (sizeof(struct OsMemFreeNodeHead) - sizeof(struct OsMemUsedNodeHead)) + +#define OS_MEM_NODE_USED_FLAG 0x80000000U +#define OS_MEM_NODE_ALIGNED_FLAG 0x40000000U +#define OS_MEM_NODE_LAST_FLAG 0x20000000U /* Sentinel Node */ +#define OS_MEM_NODE_ALIGNED_AND_USED_FLAG (OS_MEM_NODE_USED_FLAG | OS_MEM_NODE_ALIGNED_FLAG | OS_MEM_NODE_LAST_FLAG) + +#define OS_MEM_NODE_GET_ALIGNED_FLAG(sizeAndFlag) \ + ((sizeAndFlag) & OS_MEM_NODE_ALIGNED_FLAG) +#define OS_MEM_NODE_SET_ALIGNED_FLAG(sizeAndFlag) \ + ((sizeAndFlag) = ((sizeAndFlag) | OS_MEM_NODE_ALIGNED_FLAG)) +#define OS_MEM_NODE_GET_ALIGNED_GAPSIZE(sizeAndFlag) \ + ((sizeAndFlag) & ~OS_MEM_NODE_ALIGNED_FLAG) +#define OS_MEM_NODE_GET_USED_FLAG(sizeAndFlag) \ + ((sizeAndFlag) & OS_MEM_NODE_USED_FLAG) +#define OS_MEM_NODE_SET_USED_FLAG(sizeAndFlag) \ + ((sizeAndFlag) = ((sizeAndFlag) | OS_MEM_NODE_USED_FLAG)) +#define OS_MEM_NODE_GET_SIZE(sizeAndFlag) \ + ((sizeAndFlag) & ~OS_MEM_NODE_ALIGNED_AND_USED_FLAG) +#define OS_MEM_NODE_SET_LAST_FLAG(sizeAndFlag) \ + ((sizeAndFlag) = ((sizeAndFlag) | OS_MEM_NODE_LAST_FLAG)) +#define OS_MEM_NODE_GET_LAST_FLAG(sizeAndFlag) \ + ((sizeAndFlag) & OS_MEM_NODE_LAST_FLAG) + +#define OS_MEM_ALIGN_SIZE sizeof(UINTPTR) +#define OS_MEM_IS_POW_TWO(value) ((((UINTPTR)(value)) & ((UINTPTR)(value) - 1)) == 0) +#define OS_MEM_ALIGN(p, alignSize) (((UINTPTR)(p) + (alignSize) - 1) & ~((UINTPTR)((alignSize) - 1))) +#define OS_MEM_IS_ALIGNED(a, b) (!(((UINTPTR)(a)) & (((UINTPTR)(b)) - 1))) +#define OS_MEM_NODE_HEAD_SIZE sizeof(struct OsMemUsedNodeHead) +#define OS_MEM_MIN_POOL_SIZE (OS_MEM_NODE_HEAD_SIZE + sizeof(struct OsMemPoolHead)) +#define OS_MEM_NEXT_NODE(node) \ + ((struct OsMemNodeHead *)(VOID *)((UINT8 *)(node) + OS_MEM_NODE_GET_SIZE((node)->sizeAndFlag))) +#define OS_MEM_FIRST_NODE(pool) \ + (struct OsMemNodeHead *)((UINT8 *)(pool) + sizeof(struct OsMemPoolHead)) +#define OS_MEM_END_NODE(pool, size) \ + (struct OsMemNodeHead *)((UINT8 *)(pool) + (size) - OS_MEM_NODE_HEAD_SIZE) +#define OS_MEM_MIDDLE_ADDR_OPEN_END(startAddr, middleAddr, endAddr) \ + (((UINT8 *)(startAddr) <= (UINT8 *)(middleAddr)) && ((UINT8 *)(middleAddr) < (UINT8 *)(endAddr))) +#define OS_MEM_MIDDLE_ADDR(startAddr, middleAddr, endAddr) \ + (((UINT8 *)(startAddr) <= (UINT8 *)(middleAddr)) && ((UINT8 *)(middleAddr) <= (UINT8 *)(endAddr))) +#define OS_MEM_SET_MAGIC(node) ((node)->magic = OS_MEM_NODE_MAGIC) +#define OS_MEM_MAGIC_VALID(node) ((node)->magic == OS_MEM_NODE_MAGIC) + +STATIC INLINE VOID OsMemFreeNodeAdd(VOID *pool, struct OsMemFreeNodeHead *node); +STATIC INLINE UINT32 OsMemFree(struct OsMemPoolHead *pool, struct OsMemNodeHead *node); +STATIC VOID OsMemInfoPrint(VOID *pool); +#ifdef LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK +STATIC INLINE UINT32 OsMemAllocCheck(struct OsMemPoolHead *pool, UINT32 intSave); +#endif + +#if OS_MEM_FREE_BY_TASKID +STATIC INLINE VOID OsMemNodeSetTaskID(struct OsMemUsedNodeHead *node) +{ + node->taskID = LOS_CurTaskIDGet(); +} +#endif + +#ifdef LOSCFG_MEM_WATERLINE +STATIC INLINE VOID OsMemWaterUsedRecord(struct OsMemPoolHead *pool, UINT32 size) +{ + pool->info.curUsedSize += size; + if (pool->info.curUsedSize > pool->info.waterLine) { + pool->info.waterLine = pool->info.curUsedSize; + } +} +#else +STATIC INLINE VOID OsMemWaterUsedRecord(struct OsMemPoolHead *pool, UINT32 size) +{ + (VOID)pool; + (VOID)size; +} +#endif + +#if OS_MEM_EXPAND_ENABLE +STATIC INLINE struct OsMemNodeHead *OsMemLastSentinelNodeGet(const struct OsMemNodeHead *sentinelNode) +{ + struct OsMemNodeHead *node = NULL; + VOID *ptr = sentinelNode->ptr.next; + UINT32 size = OS_MEM_NODE_GET_SIZE(sentinelNode->sizeAndFlag); + + while ((ptr != NULL) && (size != 0)) { + node = OS_MEM_END_NODE(ptr, size); + ptr = node->ptr.next; + size = OS_MEM_NODE_GET_SIZE(node->sizeAndFlag); + } + + return node; +} + +STATIC INLINE BOOL OsMemSentinelNodeCheck(struct OsMemNodeHead *sentinelNode) +{ + if (!OS_MEM_NODE_GET_USED_FLAG(sentinelNode->sizeAndFlag)) { + return FALSE; + } + + if (!OS_MEM_MAGIC_VALID(sentinelNode)) { + return FALSE; + } + + return TRUE; +} + +STATIC INLINE BOOL OsMemIsLastSentinelNode(struct OsMemNodeHead *sentinelNode) +{ + if (OsMemSentinelNodeCheck(sentinelNode) == FALSE) { + PRINT_ERR("%s %d, The current sentinel node is invalid\n", __FUNCTION__, __LINE__); + return TRUE; + } + + if ((OS_MEM_NODE_GET_SIZE(sentinelNode->sizeAndFlag) == 0) || + (sentinelNode->ptr.next == NULL)) { + return TRUE; + } + + return FALSE; +} + +STATIC INLINE VOID OsMemSentinelNodeSet(struct OsMemNodeHead *sentinelNode, VOID *newNode, UINT32 size) +{ + if (sentinelNode->ptr.next != NULL) { + sentinelNode = OsMemLastSentinelNodeGet(sentinelNode); + } + + sentinelNode->sizeAndFlag = size; + sentinelNode->ptr.next = newNode; + OS_MEM_NODE_SET_USED_FLAG(sentinelNode->sizeAndFlag); + OS_MEM_NODE_SET_LAST_FLAG(sentinelNode->sizeAndFlag); +} + +STATIC INLINE VOID *OsMemSentinelNodeGet(struct OsMemNodeHead *node) +{ + return node->ptr.next; +} + +STATIC INLINE struct OsMemNodeHead *PreSentinelNodeGet(const VOID *pool, const struct OsMemNodeHead *node) +{ + UINT32 nextSize; + struct OsMemNodeHead *nextNode = NULL; + struct OsMemNodeHead *sentinelNode = NULL; + + sentinelNode = OS_MEM_END_NODE(pool, ((struct OsMemPoolHead *)pool)->info.totalSize); + while (sentinelNode != NULL) { + if (OsMemIsLastSentinelNode(sentinelNode)) { + PRINT_ERR("PreSentinelNodeGet can not find node %#x\n", node); + return NULL; + } + nextNode = OsMemSentinelNodeGet(sentinelNode); + if (nextNode == node) { + return sentinelNode; + } + nextSize = OS_MEM_NODE_GET_SIZE(sentinelNode->sizeAndFlag); + sentinelNode = OS_MEM_END_NODE(nextNode, nextSize); + } + + return NULL; +} + +UINT32 OsMemLargeNodeFree(const VOID *ptr) +{ + LosVmPage *page = OsVmVaddrToPage((VOID *)ptr); + if ((page == NULL) || (page->nPages == 0)) { + return LOS_NOK; + } + LOS_PhysPagesFreeContiguous((VOID *)ptr, page->nPages); + + return LOS_OK; +} + +STATIC INLINE BOOL TryShrinkPool(const VOID *pool, const struct OsMemNodeHead *node) +{ + struct OsMemNodeHead *mySentinel = NULL; + struct OsMemNodeHead *preSentinel = NULL; + size_t totalSize = (UINTPTR)node->ptr.prev - (UINTPTR)node; + size_t nodeSize = OS_MEM_NODE_GET_SIZE(node->sizeAndFlag); + + if (nodeSize != totalSize) { + return FALSE; + } + + preSentinel = PreSentinelNodeGet(pool, node); + if (preSentinel == NULL) { + return FALSE; + } + + mySentinel = node->ptr.prev; + if (OsMemIsLastSentinelNode(mySentinel)) { /* prev node becomes sentinel node */ + preSentinel->ptr.next = NULL; + OsMemSentinelNodeSet(preSentinel, NULL, 0); + } else { + preSentinel->sizeAndFlag = mySentinel->sizeAndFlag; + preSentinel->ptr.next = mySentinel->ptr.next; + } + + if (OsMemLargeNodeFree(node) != LOS_OK) { + PRINT_ERR("TryShrinkPool free %#x failed!\n", node); + return FALSE; + } +#ifdef LOSCFG_KERNEL_LMS + LOS_LmsCheckPoolDel(node); +#endif + return TRUE; +} + +STATIC INLINE INT32 OsMemPoolExpandSub(VOID *pool, UINT32 size, UINT32 intSave) +{ + UINT32 tryCount = MAX_SHRINK_PAGECACHE_TRY; + struct OsMemPoolHead *poolInfo = (struct OsMemPoolHead *)pool; + struct OsMemNodeHead *newNode = NULL; + struct OsMemNodeHead *endNode = NULL; + + size = ROUNDUP(size + OS_MEM_NODE_HEAD_SIZE, PAGE_SIZE); + endNode = OS_MEM_END_NODE(pool, poolInfo->info.totalSize); + +RETRY: + newNode = (struct OsMemNodeHead *)LOS_PhysPagesAllocContiguous(size >> PAGE_SHIFT); + if (newNode == NULL) { + if (tryCount > 0) { + tryCount--; + MEM_UNLOCK(poolInfo, intSave); + OsTryShrinkMemory(size >> PAGE_SHIFT); + MEM_LOCK(poolInfo, intSave); + goto RETRY; + } + + PRINT_ERR("OsMemPoolExpand alloc failed size = %u\n", size); + return -1; + } +#ifdef LOSCFG_KERNEL_LMS + UINT32 resize = 0; + if (g_lms != NULL) { + /* + * resize == 0, shadow memory init failed, no shadow memory for this pool, set poolSize as original size. + * resize != 0, shadow memory init successful, set poolSize as resize. + */ + resize = g_lms->init(newNode, size); + size = (resize == 0) ? size : resize; + } +#endif + newNode->sizeAndFlag = (size - OS_MEM_NODE_HEAD_SIZE); + newNode->ptr.prev = OS_MEM_END_NODE(newNode, size); + OsMemSentinelNodeSet(endNode, newNode, size); + OsMemFreeNodeAdd(pool, (struct OsMemFreeNodeHead *)newNode); + + endNode = OS_MEM_END_NODE(newNode, size); + (VOID)memset(endNode, 0, sizeof(*endNode)); + endNode->ptr.next = NULL; + endNode->magic = OS_MEM_NODE_MAGIC; + OsMemSentinelNodeSet(endNode, NULL, 0); + OsMemWaterUsedRecord(poolInfo, OS_MEM_NODE_HEAD_SIZE); + + return 0; +} + +STATIC INLINE INT32 OsMemPoolExpand(VOID *pool, UINT32 allocSize, UINT32 intSave) +{ + UINT32 expandDefault = MEM_EXPAND_SIZE(LOS_MemPoolSizeGet(pool)); + UINT32 expandSize = MAX(expandDefault, allocSize); + UINT32 tryCount = 1; + UINT32 ret; + + do { + ret = OsMemPoolExpandSub(pool, expandSize, intSave); + if (ret == 0) { + return 0; + } + + if (allocSize > expandDefault) { + break; + } + expandSize = allocSize; + } while (tryCount--); + + return -1; +} + +VOID LOS_MemExpandEnable(VOID *pool) +{ + if (pool == NULL) { + return; + } + + ((struct OsMemPoolHead *)pool)->info.attr |= OS_MEM_POOL_EXPAND_ENABLE; +} +#endif + +#ifdef LOSCFG_KERNEL_LMS +STATIC INLINE VOID OsLmsFirstNodeMark(VOID *pool, struct OsMemNodeHead *node) +{ + if (g_lms == NULL) { + return; + } + + g_lms->simpleMark((UINTPTR)pool, (UINTPTR)node, LMS_SHADOW_PAINT_U8); + g_lms->simpleMark((UINTPTR)node, (UINTPTR)node + OS_MEM_NODE_HEAD_SIZE, LMS_SHADOW_REDZONE_U8); + g_lms->simpleMark((UINTPTR)OS_MEM_NEXT_NODE(node), (UINTPTR)OS_MEM_NEXT_NODE(node) + OS_MEM_NODE_HEAD_SIZE, + LMS_SHADOW_REDZONE_U8); + g_lms->simpleMark((UINTPTR)node + OS_MEM_NODE_HEAD_SIZE, (UINTPTR)OS_MEM_NEXT_NODE(node), + LMS_SHADOW_AFTERFREE_U8); +} + +STATIC INLINE VOID OsLmsAllocAlignMark(VOID *ptr, VOID *alignedPtr, UINT32 size) +{ + struct OsMemNodeHead *allocNode = NULL; + + if ((g_lms == NULL) || (ptr == NULL)) { + return; + } + allocNode = (struct OsMemNodeHead *)((struct OsMemUsedNodeHead *)ptr - 1); + if (ptr != alignedPtr) { + g_lms->simpleMark((UINTPTR)ptr, (UINTPTR)ptr + sizeof(UINT32), LMS_SHADOW_PAINT_U8); + g_lms->simpleMark((UINTPTR)ptr + sizeof(UINT32), (UINTPTR)alignedPtr, LMS_SHADOW_REDZONE_U8); + } + + /* mark remaining as redzone */ + g_lms->simpleMark(LMS_ADDR_ALIGN((UINTPTR)alignedPtr + size), (UINTPTR)OS_MEM_NEXT_NODE(allocNode), + LMS_SHADOW_REDZONE_U8); +} + +STATIC INLINE VOID OsLmsReallocMergeNodeMark(struct OsMemNodeHead *node) +{ + if (g_lms == NULL) { + return; + } + + g_lms->simpleMark((UINTPTR)node + OS_MEM_NODE_HEAD_SIZE, (UINTPTR)OS_MEM_NEXT_NODE(node), + LMS_SHADOW_ACCESSIBLE_U8); +} + +STATIC INLINE VOID OsLmsReallocSplitNodeMark(struct OsMemNodeHead *node) +{ + if (g_lms == NULL) { + return; + } + /* mark next node */ + g_lms->simpleMark((UINTPTR)OS_MEM_NEXT_NODE(node), + (UINTPTR)OS_MEM_NEXT_NODE(node) + OS_MEM_NODE_HEAD_SIZE, LMS_SHADOW_REDZONE_U8); + g_lms->simpleMark((UINTPTR)OS_MEM_NEXT_NODE(node) + OS_MEM_NODE_HEAD_SIZE, + (UINTPTR)OS_MEM_NEXT_NODE(OS_MEM_NEXT_NODE(node)), LMS_SHADOW_AFTERFREE_U8); +} + +STATIC INLINE VOID OsLmsReallocResizeMark(struct OsMemNodeHead *node, UINT32 resize) +{ + if (g_lms == NULL) { + return; + } + /* mark remaining as redzone */ + g_lms->simpleMark((UINTPTR)node + resize, (UINTPTR)OS_MEM_NEXT_NODE(node), LMS_SHADOW_REDZONE_U8); +} +#endif + +#ifdef LOSCFG_MEM_LEAKCHECK +STATIC INLINE VOID OsMemLinkRegisterRecord(struct OsMemNodeHead *node) +{ + LOS_RecordLR(node->linkReg, LOS_RECORD_LR_CNT, LOS_RECORD_LR_CNT, LOS_OMIT_LR_CNT); +} + +STATIC INLINE VOID OsMemUsedNodePrint(struct OsMemNodeHead *node) +{ + UINT32 count; + + if (OS_MEM_NODE_GET_USED_FLAG(node->sizeAndFlag)) { +#ifdef __LP64__ + PRINTK("0x%018x: ", node); +#else + PRINTK("0x%010x: ", node); +#endif + for (count = 0; count < LOS_RECORD_LR_CNT; count++) { +#ifdef __LP64__ + PRINTK(" 0x%018x ", node->linkReg[count]); +#else + PRINTK(" 0x%010x ", node->linkReg[count]); +#endif + } + PRINTK("\n"); + } +} + +VOID OsMemUsedNodeShow(VOID *pool) +{ + if (pool == NULL) { + PRINTK("input param is NULL\n"); + return; + } + if (LOS_MemIntegrityCheck(pool)) { + PRINTK("LOS_MemIntegrityCheck error\n"); + return; + } + struct OsMemPoolHead *poolInfo = (struct OsMemPoolHead *)pool; + struct OsMemNodeHead *tmpNode = NULL; + struct OsMemNodeHead *endNode = NULL; + UINT32 size; + UINT32 intSave; + UINT32 count; + +#ifdef __LP64__ + PRINTK("\n\rnode "); +#else + PRINTK("\n\rnode "); +#endif + for (count = 0; count < LOS_RECORD_LR_CNT; count++) { +#ifdef __LP64__ + PRINTK(" LR[%u] ", count); +#else + PRINTK(" LR[%u] ", count); +#endif + } + PRINTK("\n"); + + MEM_LOCK(poolInfo, intSave); + endNode = OS_MEM_END_NODE(pool, poolInfo->info.totalSize); +#if OS_MEM_EXPAND_ENABLE + for (tmpNode = OS_MEM_FIRST_NODE(pool); tmpNode <= endNode; + tmpNode = OS_MEM_NEXT_NODE(tmpNode)) { + if (tmpNode == endNode) { + if (OsMemIsLastSentinelNode(endNode) == FALSE) { + size = OS_MEM_NODE_GET_SIZE(endNode->sizeAndFlag); + tmpNode = OsMemSentinelNodeGet(endNode); + endNode = OS_MEM_END_NODE(tmpNode, size); + continue; + } else { + break; + } + } else { + OsMemUsedNodePrint(tmpNode); + } + } +#else + for (tmpNode = OS_MEM_FIRST_NODE(pool); tmpNode < endNode; + tmpNode = OS_MEM_NEXT_NODE(tmpNode)) { + OsMemUsedNodePrint(tmpNode); + } +#endif + MEM_UNLOCK(poolInfo, intSave); +} + +STATIC VOID OsMemNodeBacktraceInfo(const struct OsMemNodeHead *tmpNode, + const struct OsMemNodeHead *preNode) +{ + int i; + PRINTK("\n broken node head LR info: \n"); + for (i = 0; i < LOS_RECORD_LR_CNT; i++) { + PRINTK(" LR[%d]:%#x\n", i, tmpNode->linkReg[i]); + } + + PRINTK("\n pre node head LR info: \n"); + for (i = 0; i < LOS_RECORD_LR_CNT; i++) { + PRINTK(" LR[%d]:%#x\n", i, preNode->linkReg[i]); + } +} +#endif + +STATIC INLINE UINT32 OsMemFreeListIndexGet(UINT32 size) +{ + UINT32 fl = OsMemFlGet(size); + if (size < OS_MEM_SMALL_BUCKET_MAX_SIZE) { + return fl; + } + + UINT32 sl = OsMemSlGet(size, fl); + return (OS_MEM_SMALL_BUCKET_COUNT + ((fl - OS_MEM_LARGE_START_BUCKET) << OS_MEM_SLI) + sl); +} + +STATIC INLINE struct OsMemFreeNodeHead *OsMemFindCurSuitableBlock(struct OsMemPoolHead *poolHead, + UINT32 index, UINT32 size) +{ + struct OsMemFreeNodeHead *node = NULL; + + for (node = poolHead->freeList[index]; node != NULL; node = node->next) { + if (node->header.sizeAndFlag >= size) { + return node; + } + } + + return NULL; +} + +#define BITMAP_INDEX(index) ((index) >> 5) +STATIC INLINE UINT32 OsMemNotEmptyIndexGet(struct OsMemPoolHead *poolHead, UINT32 index) +{ + UINT32 mask; + + mask = poolHead->freeListBitmap[BITMAP_INDEX(index)]; + mask &= ~((1 << (index & OS_MEM_BITMAP_MASK)) - 1); + if (mask != 0) { + index = OsMemFFS(mask) + (index & ~OS_MEM_BITMAP_MASK); + return index; + } + + return OS_MEM_FREE_LIST_COUNT; +} + +STATIC INLINE struct OsMemFreeNodeHead *OsMemFindNextSuitableBlock(VOID *pool, UINT32 size, UINT32 *outIndex) +{ + struct OsMemPoolHead *poolHead = (struct OsMemPoolHead *)pool; + UINT32 fl = OsMemFlGet(size); + UINT32 sl; + UINT32 index, tmp; + UINT32 curIndex = OS_MEM_FREE_LIST_COUNT; + UINT32 mask; + + do { + if (size < OS_MEM_SMALL_BUCKET_MAX_SIZE) { + index = fl; + } else { + sl = OsMemSlGet(size, fl); + curIndex = ((fl - OS_MEM_LARGE_START_BUCKET) << OS_MEM_SLI) + sl + OS_MEM_SMALL_BUCKET_COUNT; + index = curIndex + 1; + } + + tmp = OsMemNotEmptyIndexGet(poolHead, index); + if (tmp != OS_MEM_FREE_LIST_COUNT) { + index = tmp; + goto DONE; + } + + for (index = LOS_Align(index + 1, 32); index < OS_MEM_FREE_LIST_COUNT; index += 32) { /* 32: align size */ + mask = poolHead->freeListBitmap[BITMAP_INDEX(index)]; + if (mask != 0) { + index = OsMemFFS(mask) + index; + goto DONE; + } + } + } while (0); + + if (curIndex == OS_MEM_FREE_LIST_COUNT) { + return NULL; + } + + *outIndex = curIndex; + return OsMemFindCurSuitableBlock(poolHead, curIndex, size); +DONE: + *outIndex = index; + return poolHead->freeList[index]; +} + +STATIC INLINE VOID OsMemSetFreeListBit(struct OsMemPoolHead *head, UINT32 index) +{ + head->freeListBitmap[BITMAP_INDEX(index)] |= 1U << (index & 0x1f); +} + +STATIC INLINE VOID OsMemClearFreeListBit(struct OsMemPoolHead *head, UINT32 index) +{ + head->freeListBitmap[BITMAP_INDEX(index)] &= ~(1U << (index & 0x1f)); +} + +STATIC INLINE VOID OsMemListAdd(struct OsMemPoolHead *pool, UINT32 listIndex, struct OsMemFreeNodeHead *node) +{ + struct OsMemFreeNodeHead *firstNode = pool->freeList[listIndex]; + if (firstNode != NULL) { + firstNode->prev = node; + } + node->prev = NULL; + node->next = firstNode; + pool->freeList[listIndex] = node; + OsMemSetFreeListBit(pool, listIndex); + node->header.magic = OS_MEM_NODE_MAGIC; +} + +STATIC INLINE VOID OsMemListDelete(struct OsMemPoolHead *pool, UINT32 listIndex, struct OsMemFreeNodeHead *node) +{ + if (node == pool->freeList[listIndex]) { + pool->freeList[listIndex] = node->next; + if (node->next == NULL) { + OsMemClearFreeListBit(pool, listIndex); + } else { + node->next->prev = NULL; + } + } else { + node->prev->next = node->next; + if (node->next != NULL) { + node->next->prev = node->prev; + } + } + node->header.magic = OS_MEM_NODE_MAGIC; +} + +STATIC INLINE VOID OsMemFreeNodeAdd(VOID *pool, struct OsMemFreeNodeHead *node) +{ + UINT32 index = OsMemFreeListIndexGet(node->header.sizeAndFlag); + if (index >= OS_MEM_FREE_LIST_COUNT) { + LOS_Panic("The index of free lists is error, index = %u\n", index); + return; + } + OsMemListAdd(pool, index, node); +} + +STATIC INLINE VOID OsMemFreeNodeDelete(VOID *pool, struct OsMemFreeNodeHead *node) +{ + UINT32 index = OsMemFreeListIndexGet(node->header.sizeAndFlag); + if (index >= OS_MEM_FREE_LIST_COUNT) { + LOS_Panic("The index of free lists is error, index = %u\n", index); + return; + } + OsMemListDelete(pool, index, node); +} + +STATIC INLINE struct OsMemNodeHead *OsMemFreeNodeGet(VOID *pool, UINT32 size) +{ + struct OsMemPoolHead *poolHead = (struct OsMemPoolHead *)pool; + UINT32 index; + struct OsMemFreeNodeHead *firstNode = OsMemFindNextSuitableBlock(pool, size, &index); + if (firstNode == NULL) { + return NULL; + } + + OsMemListDelete(poolHead, index, firstNode); + + return &firstNode->header; +} + +STATIC INLINE VOID OsMemMergeNode(struct OsMemNodeHead *node) +{ + struct OsMemNodeHead *nextNode = NULL; + + node->ptr.prev->sizeAndFlag += node->sizeAndFlag; + nextNode = (struct OsMemNodeHead *)((UINTPTR)node + node->sizeAndFlag); + if (!OS_MEM_NODE_GET_LAST_FLAG(nextNode->sizeAndFlag)) { + nextNode->ptr.prev = node->ptr.prev; + } +} + +STATIC INLINE VOID OsMemSplitNode(VOID *pool, struct OsMemNodeHead *allocNode, UINT32 allocSize) +{ + struct OsMemFreeNodeHead *newFreeNode = NULL; + struct OsMemNodeHead *nextNode = NULL; + + newFreeNode = (struct OsMemFreeNodeHead *)(VOID *)((UINT8 *)allocNode + allocSize); + newFreeNode->header.ptr.prev = allocNode; + newFreeNode->header.sizeAndFlag = allocNode->sizeAndFlag - allocSize; + allocNode->sizeAndFlag = allocSize; + nextNode = OS_MEM_NEXT_NODE(&newFreeNode->header); + if (!OS_MEM_NODE_GET_LAST_FLAG(nextNode->sizeAndFlag)) { + nextNode->ptr.prev = &newFreeNode->header; + if (!OS_MEM_NODE_GET_USED_FLAG(nextNode->sizeAndFlag)) { + OsMemFreeNodeDelete(pool, (struct OsMemFreeNodeHead *)nextNode); + OsMemMergeNode(nextNode); + } + } + + OsMemFreeNodeAdd(pool, newFreeNode); +} + +STATIC INLINE VOID *OsMemCreateUsedNode(VOID *addr) +{ + struct OsMemUsedNodeHead *node = (struct OsMemUsedNodeHead *)addr; + +#if OS_MEM_FREE_BY_TASKID + OsMemNodeSetTaskID(node); +#endif + +#ifdef LOSCFG_KERNEL_LMS + struct OsMemNodeHead *newNode = (struct OsMemNodeHead *)node; + if (g_lms != NULL) { + g_lms->mallocMark(newNode, OS_MEM_NEXT_NODE(newNode), OS_MEM_NODE_HEAD_SIZE); + } +#endif + return node + 1; +} + +STATIC UINT32 OsMemPoolInit(VOID *pool, UINT32 size) +{ + struct OsMemPoolHead *poolHead = (struct OsMemPoolHead *)pool; + struct OsMemNodeHead *newNode = NULL; + struct OsMemNodeHead *endNode = NULL; + + (VOID)memset_s(poolHead, sizeof(struct OsMemPoolHead), 0, sizeof(struct OsMemPoolHead)); + +#ifdef LOSCFG_KERNEL_LMS + UINT32 resize = 0; + if (g_lms != NULL) { + /* + * resize == 0, shadow memory init failed, no shadow memory for this pool, set poolSize as original size. + * resize != 0, shadow memory init successful, set poolSize as resize. + */ + resize = g_lms->init(pool, size); + size = (resize == 0) ? size : resize; + } +#endif + + LOS_SpinInit(&poolHead->spinlock); + poolHead->info.pool = pool; + poolHead->info.totalSize = size; + poolHead->info.attr = OS_MEM_POOL_LOCK_ENABLE; /* default attr: lock, not expand. */ + + newNode = OS_MEM_FIRST_NODE(pool); + newNode->sizeAndFlag = (size - sizeof(struct OsMemPoolHead) - OS_MEM_NODE_HEAD_SIZE); + newNode->ptr.prev = NULL; + newNode->magic = OS_MEM_NODE_MAGIC; + OsMemFreeNodeAdd(pool, (struct OsMemFreeNodeHead *)newNode); + + /* The last mem node */ + endNode = OS_MEM_END_NODE(pool, size); + endNode->magic = OS_MEM_NODE_MAGIC; +#if OS_MEM_EXPAND_ENABLE + endNode->ptr.next = NULL; + OsMemSentinelNodeSet(endNode, NULL, 0); +#else + endNode->sizeAndFlag = 0; + endNode->ptr.prev = newNode; + OS_MEM_NODE_SET_USED_FLAG(endNode->sizeAndFlag); +#endif +#ifdef LOSCFG_MEM_WATERLINE + poolHead->info.curUsedSize = sizeof(struct OsMemPoolHead) + OS_MEM_NODE_HEAD_SIZE; + poolHead->info.waterLine = poolHead->info.curUsedSize; +#endif +#ifdef LOSCFG_KERNEL_LMS + if (resize != 0) { + OsLmsFirstNodeMark(pool, newNode); + } +#endif + return LOS_OK; +} + +#ifdef LOSCFG_MEM_MUL_POOL +STATIC VOID OsMemPoolDeinit(const VOID *pool, UINT32 size) +{ +#ifdef LOSCFG_KERNEL_LMS + if (g_lms != NULL) { + g_lms->deInit(pool); + } +#endif + (VOID)memset_s(pool, size, 0, sizeof(struct OsMemPoolHead)); +} + +STATIC UINT32 OsMemPoolAdd(VOID *pool, UINT32 size) +{ + VOID *nextPool = g_poolHead; + VOID *curPool = g_poolHead; + UINTPTR poolEnd; + while (nextPool != NULL) { + poolEnd = (UINTPTR)nextPool + LOS_MemPoolSizeGet(nextPool); + if (((pool <= nextPool) && (((UINTPTR)pool + size) > (UINTPTR)nextPool)) || + (((UINTPTR)pool < poolEnd) && (((UINTPTR)pool + size) >= poolEnd))) { + PRINT_ERR("pool [%#x, %#x) conflict with pool [%#x, %#x)\n", + pool, (UINTPTR)pool + size, + nextPool, (UINTPTR)nextPool + LOS_MemPoolSizeGet(nextPool)); + return LOS_NOK; + } + curPool = nextPool; + nextPool = ((struct OsMemPoolHead *)nextPool)->nextPool; + } + + if (g_poolHead == NULL) { + g_poolHead = pool; + } else { + ((struct OsMemPoolHead *)curPool)->nextPool = pool; + } + + ((struct OsMemPoolHead *)pool)->nextPool = NULL; + return LOS_OK; +} + +STATIC UINT32 OsMemPoolDelete(const VOID *pool) +{ + UINT32 ret = LOS_NOK; + VOID *nextPool = NULL; + VOID *curPool = NULL; + + do { + if (pool == g_poolHead) { + g_poolHead = ((struct OsMemPoolHead *)g_poolHead)->nextPool; + ret = LOS_OK; + break; + } + + curPool = g_poolHead; + nextPool = g_poolHead; + while (nextPool != NULL) { + if (pool == nextPool) { + ((struct OsMemPoolHead *)curPool)->nextPool = ((struct OsMemPoolHead *)nextPool)->nextPool; + ret = LOS_OK; + break; + } + curPool = nextPool; + nextPool = ((struct OsMemPoolHead *)nextPool)->nextPool; + } + } while (0); + + return ret; +} +#endif + +UINT32 LOS_MemInit(VOID *pool, UINT32 size) +{ + if ((pool == NULL) || (size <= OS_MEM_MIN_POOL_SIZE)) { + return OS_ERROR; + } + + size = OS_MEM_ALIGN(size, OS_MEM_ALIGN_SIZE); + if (OsMemPoolInit(pool, size)) { + return OS_ERROR; + } + +#ifdef LOSCFG_MEM_MUL_POOL + if (OsMemPoolAdd(pool, size)) { + (VOID)OsMemPoolDeInit(pool, size); + return OS_ERROR; + } +#endif + + OsHookCall(LOS_HOOK_TYPE_MEM_INIT, pool, size); + return LOS_OK; +} + +#ifdef LOSCFG_MEM_MUL_POOL +UINT32 LOS_MemDeInit(VOID *pool) +{ + struct OsMemPoolHead *tmpPool = (struct OsMemPoolHead *)pool; + + if ((tmpPool == NULL) || + (tmpPool->info.pool != pool) || + (tmpPool->info.totalSize <= OS_MEM_MIN_POOL_SIZE)) { + return OS_ERROR; + } + + if (OsMemPoolDelete(tmpPool)) { + return OS_ERROR; + } + + OsMemPoolDeInit(tmpPool, tmpPool->info.totalSize); + + OsHookCall(LOS_HOOK_TYPE_MEM_DEINIT, tmpPool); + return LOS_OK; +} + +UINT32 LOS_MemPoolList(VOID) +{ + VOID *nextPool = g_poolHead; + UINT32 index = 0; + while (nextPool != NULL) { + PRINTK("pool%u :\n", index); + index++; + OsMemInfoPrint(nextPool); + nextPool = ((struct OsMemPoolHead *)nextPool)->nextPool; + } + return index; +} +#endif + +STATIC INLINE VOID *OsMemAlloc(struct OsMemPoolHead *pool, UINT32 size, UINT32 intSave) +{ + struct OsMemNodeHead *allocNode = NULL; + +#ifdef LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK + if (OsMemAllocCheck(pool, intSave) == LOS_NOK) { + return NULL; + } +#endif + + UINT32 allocSize = OS_MEM_ALIGN(size + OS_MEM_NODE_HEAD_SIZE, OS_MEM_ALIGN_SIZE); +#if OS_MEM_EXPAND_ENABLE +retry: +#endif + allocNode = OsMemFreeNodeGet(pool, allocSize); + if (allocNode == NULL) { +#if OS_MEM_EXPAND_ENABLE + if (pool->info.attr & OS_MEM_POOL_EXPAND_ENABLE) { + INT32 ret = OsMemPoolExpand(pool, allocSize, intSave); + if (ret == 0) { + goto retry; + } + } +#endif + MEM_UNLOCK(pool, intSave); + PRINT_ERR("---------------------------------------------------" + "--------------------------------------------------------\n"); + OsMemInfoPrint(pool); + PRINT_ERR("[%s] No suitable free block, require free node size: 0x%x\n", __FUNCTION__, allocSize); + PRINT_ERR("----------------------------------------------------" + "-------------------------------------------------------\n"); + MEM_LOCK(pool, intSave); + return NULL; + } + + if ((allocSize + OS_MEM_NODE_HEAD_SIZE + OS_MEM_MIN_ALLOC_SIZE) <= allocNode->sizeAndFlag) { + OsMemSplitNode(pool, allocNode, allocSize); + } + + OS_MEM_NODE_SET_USED_FLAG(allocNode->sizeAndFlag); + OsMemWaterUsedRecord(pool, OS_MEM_NODE_GET_SIZE(allocNode->sizeAndFlag)); + +#ifdef LOSCFG_MEM_LEAKCHECK + OsMemLinkRegisterRecord(allocNode); +#endif + return OsMemCreateUsedNode((VOID *)allocNode); +} + +VOID *LOS_MemAlloc(VOID *pool, UINT32 size) +{ + if ((pool == NULL) || (size == 0)) { + return (size > 0) ? OsVmBootMemAlloc(size) : NULL; + } + + if (size < OS_MEM_MIN_ALLOC_SIZE) { + size = OS_MEM_MIN_ALLOC_SIZE; + } + + struct OsMemPoolHead *poolHead = (struct OsMemPoolHead *)pool; + VOID *ptr = NULL; + UINT32 intSave; + + do { + if (OS_MEM_NODE_GET_USED_FLAG(size) || OS_MEM_NODE_GET_ALIGNED_FLAG(size)) { + break; + } + MEM_LOCK(poolHead, intSave); + ptr = OsMemAlloc(poolHead, size, intSave); + MEM_UNLOCK(poolHead, intSave); + } while (0); + + OsHookCall(LOS_HOOK_TYPE_MEM_ALLOC, pool, ptr, size); + return ptr; +} + +VOID *LOS_MemAllocAlign(VOID *pool, UINT32 size, UINT32 boundary) +{ + UINT32 gapSize; + + if ((pool == NULL) || (size == 0) || (boundary == 0) || !OS_MEM_IS_POW_TWO(boundary) || + !OS_MEM_IS_ALIGNED(boundary, sizeof(VOID *))) { + return NULL; + } + + if (size < OS_MEM_MIN_ALLOC_SIZE) { + size = OS_MEM_MIN_ALLOC_SIZE; + } + + /* + * sizeof(gapSize) bytes stores offset between alignedPtr and ptr, + * the ptr has been OS_MEM_ALIGN_SIZE(4 or 8) aligned, so maximum + * offset between alignedPtr and ptr is boundary - OS_MEM_ALIGN_SIZE + */ + if ((boundary - sizeof(gapSize)) > ((UINT32)(-1) - size)) { + return NULL; + } + + UINT32 useSize = (size + boundary) - sizeof(gapSize); + if (OS_MEM_NODE_GET_USED_FLAG(useSize) || OS_MEM_NODE_GET_ALIGNED_FLAG(useSize)) { + return NULL; + } + + struct OsMemPoolHead *poolHead = (struct OsMemPoolHead *)pool; + UINT32 intSave; + VOID *ptr = NULL; + VOID *alignedPtr = NULL; + + do { + MEM_LOCK(poolHead, intSave); + ptr = OsMemAlloc(pool, useSize, intSave); + MEM_UNLOCK(poolHead, intSave); + alignedPtr = (VOID *)OS_MEM_ALIGN(ptr, boundary); + if (ptr == alignedPtr) { +#ifdef LOSCFG_KERNEL_LMS + OsLmsAllocAlignMark(ptr, alignedPtr, size); +#endif + break; + } + + /* store gapSize in address (ptr - 4), it will be checked while free */ + gapSize = (UINT32)((UINTPTR)alignedPtr - (UINTPTR)ptr); + struct OsMemUsedNodeHead *allocNode = (struct OsMemUsedNodeHead *)ptr - 1; + OS_MEM_NODE_SET_ALIGNED_FLAG(allocNode->header.sizeAndFlag); + OS_MEM_NODE_SET_ALIGNED_FLAG(gapSize); + *(UINT32 *)((UINTPTR)alignedPtr - sizeof(gapSize)) = gapSize; +#ifdef LOSCFG_KERNEL_LMS + OsLmsAllocAlignMark(ptr, alignedPtr, size); +#endif + ptr = alignedPtr; + } while (0); + + OsHookCall(LOS_HOOK_TYPE_MEM_ALLOCALIGN, pool, ptr, size, boundary); + return ptr; +} + +STATIC INLINE BOOL OsMemAddrValidCheck(const struct OsMemPoolHead *pool, const VOID *addr) +{ + UINT32 size; + + /* First node prev is NULL */ + if (addr == NULL) { + return TRUE; + } + + size = pool->info.totalSize; + if (OS_MEM_MIDDLE_ADDR_OPEN_END(pool + 1, addr, (UINTPTR)pool + size)) { + return TRUE; + } +#if OS_MEM_EXPAND_ENABLE + struct OsMemNodeHead *node = NULL; + struct OsMemNodeHead *sentinel = OS_MEM_END_NODE(pool, size); + while (OsMemIsLastSentinelNode(sentinel) == FALSE) { + size = OS_MEM_NODE_GET_SIZE(sentinel->sizeAndFlag); + node = OsMemSentinelNodeGet(sentinel); + sentinel = OS_MEM_END_NODE(node, size); + if (OS_MEM_MIDDLE_ADDR_OPEN_END(node, addr, (UINTPTR)node + size)) { + return TRUE; + } + } +#endif + return FALSE; +} + +STATIC INLINE BOOL OsMemIsNodeValid(const struct OsMemNodeHead *node, const struct OsMemNodeHead *startNode, + const struct OsMemNodeHead *endNode, + const struct OsMemPoolHead *poolInfo) +{ + if (!OS_MEM_MIDDLE_ADDR(startNode, node, endNode)) { + return FALSE; + } + + if (OS_MEM_NODE_GET_USED_FLAG(node->sizeAndFlag)) { + if (!OS_MEM_MAGIC_VALID(node)) { + return FALSE; + } + return TRUE; + } + + if (!OsMemAddrValidCheck(poolInfo, node->ptr.prev)) { + return FALSE; + } + + return TRUE; +} + +STATIC BOOL MemCheckUsedNode(const struct OsMemPoolHead *pool, const struct OsMemNodeHead *node, + const struct OsMemNodeHead *startNode, const struct OsMemNodeHead *endNode) +{ + if (!OsMemIsNodeValid(node, startNode, endNode, pool)) { + return FALSE; + } + + if (!OS_MEM_NODE_GET_USED_FLAG(node->sizeAndFlag)) { + return FALSE; + } + + const struct OsMemNodeHead *nextNode = OS_MEM_NEXT_NODE(node); + if (!OsMemIsNodeValid(nextNode, startNode, endNode, pool)) { + return FALSE; + } + + if (!OS_MEM_NODE_GET_LAST_FLAG(nextNode->sizeAndFlag)) { + if (nextNode->ptr.prev != node) { + return FALSE; + } + } + + if ((node != startNode) && + ((!OsMemIsNodeValid(node->ptr.prev, startNode, endNode, pool)) || + (OS_MEM_NEXT_NODE(node->ptr.prev) != node))) { + return FALSE; + } + + return TRUE; +} + +STATIC UINT32 OsMemCheckUsedNode(const struct OsMemPoolHead *pool, const struct OsMemNodeHead *node) +{ + struct OsMemNodeHead *startNode = (struct OsMemNodeHead *)OS_MEM_FIRST_NODE(pool); + struct OsMemNodeHead *endNode = (struct OsMemNodeHead *)OS_MEM_END_NODE(pool, pool->info.totalSize); + BOOL doneFlag = FALSE; + + do { + doneFlag = MemCheckUsedNode(pool, node, startNode, endNode); + if (!doneFlag) { +#if OS_MEM_EXPAND_ENABLE + if (OsMemIsLastSentinelNode(endNode) == FALSE) { + startNode = OsMemSentinelNodeGet(endNode); + endNode = OS_MEM_END_NODE(startNode, OS_MEM_NODE_GET_SIZE(endNode->sizeAndFlag)); + continue; + } +#endif + return LOS_NOK; + } + } while (!doneFlag); + + return LOS_OK; +} + +STATIC INLINE UINT32 OsMemFree(struct OsMemPoolHead *pool, struct OsMemNodeHead *node) +{ + UINT32 ret = OsMemCheckUsedNode(pool, node); + if (ret != LOS_OK) { + PRINT_ERR("OsMemFree check error!\n"); + return ret; + } + +#ifdef LOSCFG_MEM_WATERLINE + pool->info.curUsedSize -= OS_MEM_NODE_GET_SIZE(node->sizeAndFlag); +#endif + + node->sizeAndFlag = OS_MEM_NODE_GET_SIZE(node->sizeAndFlag); +#ifdef LOSCFG_MEM_LEAKCHECK + OsMemLinkRegisterRecord(node); +#endif +#ifdef LOSCFG_KERNEL_LMS + struct OsMemNodeHead *nextNodeBackup = OS_MEM_NEXT_NODE(node); + struct OsMemNodeHead *curNodeBackup = node; + if (g_lms != NULL) { + g_lms->check((UINTPTR)node + OS_MEM_NODE_HEAD_SIZE, TRUE); + } +#endif + struct OsMemNodeHead *preNode = node->ptr.prev; /* merage preNode */ + if ((preNode != NULL) && !OS_MEM_NODE_GET_USED_FLAG(preNode->sizeAndFlag)) { + OsMemFreeNodeDelete(pool, (struct OsMemFreeNodeHead *)preNode); + OsMemMergeNode(node); + node = preNode; + } + + struct OsMemNodeHead *nextNode = OS_MEM_NEXT_NODE(node); /* merage nextNode */ + if ((nextNode != NULL) && !OS_MEM_NODE_GET_USED_FLAG(nextNode->sizeAndFlag)) { + OsMemFreeNodeDelete(pool, (struct OsMemFreeNodeHead *)nextNode); + OsMemMergeNode(nextNode); + } + +#if OS_MEM_EXPAND_ENABLE + if (pool->info.attr & OS_MEM_POOL_EXPAND_ENABLE) { + /* if this is a expand head node, and all unused, free it to pmm */ + if ((node->ptr.prev != NULL) && (node->ptr.prev > node)) { + if (TryShrinkPool(pool, node)) { + return LOS_OK; + } + } + } +#endif + OsMemFreeNodeAdd(pool, (struct OsMemFreeNodeHead *)node); +#ifdef LOSCFG_KERNEL_LMS + if (g_lms != NULL) { + g_lms->freeMark(curNodeBackup, nextNodeBackup, OS_MEM_NODE_HEAD_SIZE); + } +#endif + return ret; +} + +UINT32 LOS_MemFree(VOID *pool, VOID *ptr) +{ + UINT32 intSave; + UINT32 ret = LOS_NOK; + + if ((pool == NULL) || (ptr == NULL) || !OS_MEM_IS_ALIGNED(pool, sizeof(VOID *)) || + !OS_MEM_IS_ALIGNED(ptr, sizeof(VOID *))) { + return ret; + } + OsHookCall(LOS_HOOK_TYPE_MEM_FREE, pool, ptr); + + struct OsMemPoolHead *poolHead = (struct OsMemPoolHead *)pool; + struct OsMemNodeHead *node = NULL; + + do { + UINT32 gapSize = *(UINT32 *)((UINTPTR)ptr - sizeof(UINT32)); + if (OS_MEM_NODE_GET_ALIGNED_FLAG(gapSize) && OS_MEM_NODE_GET_USED_FLAG(gapSize)) { + PRINT_ERR("[%s:%d]gapSize:0x%x error\n", __FUNCTION__, __LINE__, gapSize); + break; + } + + node = (struct OsMemNodeHead *)((UINTPTR)ptr - OS_MEM_NODE_HEAD_SIZE); + + if (OS_MEM_NODE_GET_ALIGNED_FLAG(gapSize)) { + gapSize = OS_MEM_NODE_GET_ALIGNED_GAPSIZE(gapSize); + if ((gapSize & (OS_MEM_ALIGN_SIZE - 1)) || (gapSize > ((UINTPTR)ptr - OS_MEM_NODE_HEAD_SIZE))) { + PRINT_ERR("illegal gapSize: 0x%x\n", gapSize); + break; + } + node = (struct OsMemNodeHead *)((UINTPTR)ptr - gapSize - OS_MEM_NODE_HEAD_SIZE); + } + MEM_LOCK(poolHead, intSave); + ret = OsMemFree(poolHead, node); + MEM_UNLOCK(poolHead, intSave); + } while (0); + + return ret; +} + +STATIC INLINE VOID OsMemReAllocSmaller(VOID *pool, UINT32 allocSize, struct OsMemNodeHead *node, UINT32 nodeSize) +{ +#ifdef LOSCFG_MEM_WATERLINE + struct OsMemPoolHead *poolInfo = (struct OsMemPoolHead *)pool; +#endif + node->sizeAndFlag = nodeSize; + if ((allocSize + OS_MEM_NODE_HEAD_SIZE + OS_MEM_MIN_ALLOC_SIZE) <= nodeSize) { + OsMemSplitNode(pool, node, allocSize); + OS_MEM_NODE_SET_USED_FLAG(node->sizeAndFlag); +#ifdef LOSCFG_MEM_WATERLINE + poolInfo->info.curUsedSize -= nodeSize - allocSize; +#endif +#ifdef LOSCFG_KERNEL_LMS + OsLmsReallocSplitNodeMark(node); + } else { + OsLmsReallocResizeMark(node, allocSize); +#endif + } + OS_MEM_NODE_SET_USED_FLAG(node->sizeAndFlag); +#ifdef LOSCFG_MEM_LEAKCHECK + OsMemLinkRegisterRecord(node); +#endif +} + +STATIC INLINE VOID OsMemMergeNodeForReAllocBigger(VOID *pool, UINT32 allocSize, struct OsMemNodeHead *node, + UINT32 nodeSize, struct OsMemNodeHead *nextNode) +{ + node->sizeAndFlag = nodeSize; + OsMemFreeNodeDelete(pool, (struct OsMemFreeNodeHead *)nextNode); + OsMemMergeNode(nextNode); +#ifdef LOSCFG_KERNEL_LMS + OsLmsReallocMergeNodeMark(node); +#endif + if ((allocSize + OS_MEM_NODE_HEAD_SIZE + OS_MEM_MIN_ALLOC_SIZE) <= node->sizeAndFlag) { + OsMemSplitNode(pool, node, allocSize); +#ifdef LOSCFG_KERNEL_LMS + OsLmsReallocSplitNodeMark(node); + } else { + OsLmsReallocResizeMark(node, allocSize); +#endif + } + OS_MEM_NODE_SET_USED_FLAG(node->sizeAndFlag); + OsMemWaterUsedRecord((struct OsMemPoolHead *)pool, node->sizeAndFlag - nodeSize); +#ifdef LOSCFG_MEM_LEAKCHECK + OsMemLinkRegisterRecord(node); +#endif +} + +STATIC INLINE VOID *OsGetRealPtr(const VOID *pool, VOID *ptr) +{ + VOID *realPtr = ptr; + UINT32 gapSize = *((UINT32 *)((UINTPTR)ptr - sizeof(UINT32))); + + if (OS_MEM_NODE_GET_ALIGNED_FLAG(gapSize) && OS_MEM_NODE_GET_USED_FLAG(gapSize)) { + PRINT_ERR("[%s:%d]gapSize:0x%x error\n", __FUNCTION__, __LINE__, gapSize); + return NULL; + } + if (OS_MEM_NODE_GET_ALIGNED_FLAG(gapSize)) { + gapSize = OS_MEM_NODE_GET_ALIGNED_GAPSIZE(gapSize); + if ((gapSize & (OS_MEM_ALIGN_SIZE - 1)) || + (gapSize > ((UINTPTR)ptr - OS_MEM_NODE_HEAD_SIZE - (UINTPTR)pool))) { + PRINT_ERR("[%s:%d]gapSize:0x%x error\n", __FUNCTION__, __LINE__, gapSize); + return NULL; + } + realPtr = (VOID *)((UINTPTR)ptr - (UINTPTR)gapSize); + } + return realPtr; +} + +STATIC INLINE VOID *OsMemRealloc(struct OsMemPoolHead *pool, const VOID *ptr, + struct OsMemNodeHead *node, UINT32 size, UINT32 intSave) +{ + struct OsMemNodeHead *nextNode = NULL; + UINT32 allocSize = OS_MEM_ALIGN(size + OS_MEM_NODE_HEAD_SIZE, OS_MEM_ALIGN_SIZE); + UINT32 nodeSize = OS_MEM_NODE_GET_SIZE(node->sizeAndFlag); + VOID *tmpPtr = NULL; + + if (nodeSize >= allocSize) { + OsMemReAllocSmaller(pool, allocSize, node, nodeSize); + return (VOID *)ptr; + } + + nextNode = OS_MEM_NEXT_NODE(node); + if (!OS_MEM_NODE_GET_USED_FLAG(nextNode->sizeAndFlag) && + ((nextNode->sizeAndFlag + nodeSize) >= allocSize)) { + OsMemMergeNodeForReAllocBigger(pool, allocSize, node, nodeSize, nextNode); + return (VOID *)ptr; + } + + tmpPtr = OsMemAlloc(pool, size, intSave); + if (tmpPtr != NULL) { + if (memcpy_s(tmpPtr, size, ptr, (nodeSize - OS_MEM_NODE_HEAD_SIZE)) != EOK) { + MEM_UNLOCK(pool, intSave); + (VOID)LOS_MemFree((VOID *)pool, (VOID *)tmpPtr); + MEM_LOCK(pool, intSave); + return NULL; + } + (VOID)OsMemFree(pool, node); + } + return tmpPtr; +} + +VOID *LOS_MemRealloc(VOID *pool, VOID *ptr, UINT32 size) +{ + if ((pool == NULL) || OS_MEM_NODE_GET_USED_FLAG(size) || OS_MEM_NODE_GET_ALIGNED_FLAG(size)) { + return NULL; + } + OsHookCall(LOS_HOOK_TYPE_MEM_REALLOC, pool, ptr, size); + if (size < OS_MEM_MIN_ALLOC_SIZE) { + size = OS_MEM_MIN_ALLOC_SIZE; + } + + if (ptr == NULL) { + return LOS_MemAlloc(pool, size); + } + + if (size == 0) { + (VOID)LOS_MemFree(pool, ptr); + return NULL; + } + + struct OsMemPoolHead *poolHead = (struct OsMemPoolHead *)pool; + struct OsMemNodeHead *node = NULL; + VOID *newPtr = NULL; + UINT32 intSave; + + MEM_LOCK(poolHead, intSave); + do { + ptr = OsGetRealPtr(pool, ptr); + if (ptr == NULL) { + break; + } + + node = (struct OsMemNodeHead *)((UINTPTR)ptr - OS_MEM_NODE_HEAD_SIZE); + if (OsMemCheckUsedNode(pool, node) != LOS_OK) { + break; + } + + newPtr = OsMemRealloc(pool, ptr, node, size, intSave); + } while (0); + MEM_UNLOCK(poolHead, intSave); + + return newPtr; +} + +#if OS_MEM_FREE_BY_TASKID +UINT32 LOS_MemFreeByTaskID(VOID *pool, UINT32 taskID) +{ + if (pool == NULL) { + return OS_ERROR; + } + + if (taskID >= LOSCFG_BASE_CORE_TSK_LIMIT) { + return OS_ERROR; + } + + struct OsMemPoolHead *poolHead = (struct OsMemPoolHead *)pool; + struct OsMemNodeHead *tmpNode = NULL; + struct OsMemUsedNodeHead *node = NULL; + struct OsMemNodeHead *endNode = NULL; + UINT32 size; + UINT32 intSave; + + MEM_LOCK(poolHead, intSave); + endNode = OS_MEM_END_NODE(pool, poolHead->info.totalSize); + for (tmpNode = OS_MEM_FIRST_NODE(pool); tmpNode <= endNode;) { + if (tmpNode == endNode) { + if (OsMemIsLastSentinelNode(endNode) == FALSE) { + size = OS_MEM_NODE_GET_SIZE(endNode->sizeAndFlag); + tmpNode = OsMemSentinelNodeGet(endNode); + endNode = OS_MEM_END_NODE(tmpNode, size); + continue; + } else { + break; + } + } else { + if (!OS_MEM_NODE_GET_USED_FLAG(tmpNode->sizeAndFlag)) { + tmpNode = OS_MEM_NEXT_NODE(tmpNode); + continue; + } + + node = (struct OsMemUsedNodeHead *)tmpNode; + tmpNode = OS_MEM_NEXT_NODE(tmpNode); + + if (node->taskID == taskID) { + OsMemFree(poolHead, &node->header); + } + } + } + MEM_UNLOCK(poolHead, intSave); + + return LOS_OK; +} +#endif + +UINT32 LOS_MemPoolSizeGet(const VOID *pool) +{ + UINT32 count = 0; + + if (pool == NULL) { + return LOS_NOK; + } + + count += ((struct OsMemPoolHead *)pool)->info.totalSize; + +#if OS_MEM_EXPAND_ENABLE + UINT32 size; + struct OsMemNodeHead *node = NULL; + struct OsMemNodeHead *sentinel = OS_MEM_END_NODE(pool, count); + + while (OsMemIsLastSentinelNode(sentinel) == FALSE) { + size = OS_MEM_NODE_GET_SIZE(sentinel->sizeAndFlag); + node = OsMemSentinelNodeGet(sentinel); + sentinel = OS_MEM_END_NODE(node, size); + count += size; + } +#endif + return count; +} + +UINT32 LOS_MemTotalUsedGet(VOID *pool) +{ + struct OsMemNodeHead *tmpNode = NULL; + struct OsMemPoolHead *poolInfo = (struct OsMemPoolHead *)pool; + struct OsMemNodeHead *endNode = NULL; + UINT32 memUsed = 0; + UINT32 intSave; + + if (pool == NULL) { + return LOS_NOK; + } + + MEM_LOCK(poolInfo, intSave); + endNode = OS_MEM_END_NODE(pool, poolInfo->info.totalSize); +#if OS_MEM_EXPAND_ENABLE + UINT32 size; + for (tmpNode = OS_MEM_FIRST_NODE(pool); tmpNode <= endNode;) { + if (tmpNode == endNode) { + memUsed += OS_MEM_NODE_HEAD_SIZE; + if (OsMemIsLastSentinelNode(endNode) == FALSE) { + size = OS_MEM_NODE_GET_SIZE(endNode->sizeAndFlag); + tmpNode = OsMemSentinelNodeGet(endNode); + endNode = OS_MEM_END_NODE(tmpNode, size); + continue; + } else { + break; + } + } else { + if (OS_MEM_NODE_GET_USED_FLAG(tmpNode->sizeAndFlag)) { + memUsed += OS_MEM_NODE_GET_SIZE(tmpNode->sizeAndFlag); + } + tmpNode = OS_MEM_NEXT_NODE(tmpNode); + } + } +#else + for (tmpNode = OS_MEM_FIRST_NODE(pool); tmpNode < endNode;) { + if (OS_MEM_NODE_GET_USED_FLAG(tmpNode->sizeAndFlag)) { + memUsed += OS_MEM_NODE_GET_SIZE(tmpNode->sizeAndFlag); + } + tmpNode = OS_MEM_NEXT_NODE(tmpNode); + } +#endif + MEM_UNLOCK(poolInfo, intSave); + + return memUsed; +} + +STATIC INLINE VOID OsMemMagicCheckPrint(struct OsMemNodeHead **tmpNode) +{ + PRINT_ERR("[%s], %d, memory check error!\n" + "memory used but magic num wrong, magic num = %#x\n", + __FUNCTION__, __LINE__, (*tmpNode)->magic); +} + +STATIC UINT32 OsMemAddrValidCheckPrint(const VOID *pool, struct OsMemFreeNodeHead **tmpNode) +{ + if (((*tmpNode)->prev != NULL) && !OsMemAddrValidCheck(pool, (*tmpNode)->prev)) { + PRINT_ERR("[%s], %d, memory check error!\n" + " freeNode.prev:%#x is out of legal mem range\n", + __FUNCTION__, __LINE__, (*tmpNode)->prev); + return LOS_NOK; + } + if (((*tmpNode)->next != NULL) && !OsMemAddrValidCheck(pool, (*tmpNode)->next)) { + PRINT_ERR("[%s], %d, memory check error!\n" + " freeNode.next:%#x is out of legal mem range\n", + __FUNCTION__, __LINE__, (*tmpNode)->next); + return LOS_NOK; + } + return LOS_OK; +} + +STATIC UINT32 OsMemIntegrityCheckSub(struct OsMemNodeHead **tmpNode, const VOID *pool, + const struct OsMemNodeHead *endNode) +{ + if (!OS_MEM_MAGIC_VALID(*tmpNode)) { + OsMemMagicCheckPrint(tmpNode); + return LOS_NOK; + } + + if (!OS_MEM_NODE_GET_USED_FLAG((*tmpNode)->sizeAndFlag)) { /* is free node, check free node range */ + if (OsMemAddrValidCheckPrint(pool, (struct OsMemFreeNodeHead **)tmpNode)) { + return LOS_NOK; + } + } + return LOS_OK; +} + +STATIC UINT32 OsMemFreeListNodeCheck(const struct OsMemPoolHead *pool, + const struct OsMemFreeNodeHead *node) +{ + if (!OsMemAddrValidCheck(pool, node) || + !OsMemAddrValidCheck(pool, node->prev) || + !OsMemAddrValidCheck(pool, node->next) || + !OsMemAddrValidCheck(pool, node->header.ptr.prev)) { + return LOS_NOK; + } + + if (!OS_MEM_IS_ALIGNED(node, sizeof(VOID *)) || + !OS_MEM_IS_ALIGNED(node->prev, sizeof(VOID *)) || + !OS_MEM_IS_ALIGNED(node->next, sizeof(VOID *)) || + !OS_MEM_IS_ALIGNED(node->header.ptr.prev, sizeof(VOID *))) { + return LOS_NOK; + } + + return LOS_OK; +} + +STATIC VOID OsMemPoolHeadCheck(const struct OsMemPoolHead *pool) +{ + struct OsMemFreeNodeHead *tmpNode = NULL; + UINT32 index; + UINT32 flag = 0; + + if ((pool->info.pool != pool) || !OS_MEM_IS_ALIGNED(pool, sizeof(VOID *))) { + PRINT_ERR("wrong mem pool addr: %#x, func:%s, line:%d\n", pool, __FUNCTION__, __LINE__); + return; + } + + for (index = 0; index < OS_MEM_FREE_LIST_COUNT; index++) { + for (tmpNode = pool->freeList[index]; tmpNode != NULL; tmpNode = tmpNode->next) { + if (OsMemFreeListNodeCheck(pool, tmpNode)) { + flag = 1; + PRINT_ERR("FreeListIndex: %u, node: %#x, bNode: %#x, prev: %#x, next: %#x\n", + index, tmpNode, tmpNode->header.ptr.prev, tmpNode->prev, tmpNode->next); + goto OUT; + } + } + } + +OUT: + if (flag) { + PRINTK("mem pool info: poolAddr: %#x, poolSize: 0x%x\n", pool, pool->info.totalSize); +#ifdef LOSCFG_MEM_WATERLINE + PRINTK("mem pool info: poolWaterLine: 0x%x, poolCurUsedSize: 0x%x\n", pool->info.waterLine, + pool->info.curUsedSize); +#endif +#if OS_MEM_EXPAND_ENABLE + UINT32 size; + struct OsMemNodeHead *node = NULL; + struct OsMemNodeHead *sentinel = OS_MEM_END_NODE(pool, pool->info.totalSize); + while (OsMemIsLastSentinelNode(sentinel) == FALSE) { + size = OS_MEM_NODE_GET_SIZE(sentinel->sizeAndFlag); + node = OsMemSentinelNodeGet(sentinel); + sentinel = OS_MEM_END_NODE(node, size); + PRINTK("expand node info: nodeAddr: %#x, nodeSize: 0x%x\n", node, size); + } +#endif + } +} + +STATIC UINT32 OsMemIntegrityCheck(const struct OsMemPoolHead *pool, struct OsMemNodeHead **tmpNode, + struct OsMemNodeHead **preNode) +{ + struct OsMemNodeHead *endNode = OS_MEM_END_NODE(pool, pool->info.totalSize); + + OsMemPoolHeadCheck(pool); + + *preNode = OS_MEM_FIRST_NODE(pool); + do { + for (*tmpNode = *preNode; *tmpNode < endNode; *tmpNode = OS_MEM_NEXT_NODE(*tmpNode)) { + if (OsMemIntegrityCheckSub(tmpNode, pool, endNode) == LOS_NOK) { + return LOS_NOK; + } + *preNode = *tmpNode; + } +#if OS_MEM_EXPAND_ENABLE + if (OsMemIsLastSentinelNode(*tmpNode) == FALSE) { + *preNode = OsMemSentinelNodeGet(*tmpNode); + endNode = OS_MEM_END_NODE(*preNode, OS_MEM_NODE_GET_SIZE((*tmpNode)->sizeAndFlag)); + } else +#endif + { + break; + } + } while (1); + return LOS_OK; +} + +STATIC VOID OsMemNodeInfo(const struct OsMemNodeHead *tmpNode, + const struct OsMemNodeHead *preNode) +{ + struct OsMemUsedNodeHead *usedNode = NULL; + struct OsMemFreeNodeHead *freeNode = NULL; + + if (tmpNode == preNode) { + PRINTK("\n the broken node is the first node\n"); + } + + if (OS_MEM_NODE_GET_USED_FLAG(tmpNode->sizeAndFlag)) { + usedNode = (struct OsMemUsedNodeHead *)tmpNode; + PRINTK("\n broken node head: %#x %#x %#x, ", + usedNode->header.ptr.prev, usedNode->header.magic, usedNode->header.sizeAndFlag); + } else { + freeNode = (struct OsMemFreeNodeHead *)tmpNode; + PRINTK("\n broken node head: %#x %#x %#x %#x, %#x", + freeNode->header.ptr.prev, freeNode->next, freeNode->prev, freeNode->header.magic, + freeNode->header.sizeAndFlag); + } + + if (OS_MEM_NODE_GET_USED_FLAG(preNode->sizeAndFlag)) { + usedNode = (struct OsMemUsedNodeHead *)preNode; + PRINTK("prev node head: %#x %#x %#x\n", + usedNode->header.ptr.prev, usedNode->header.magic, usedNode->header.sizeAndFlag); + } else { + freeNode = (struct OsMemFreeNodeHead *)preNode; + PRINTK("prev node head: %#x %#x %#x %#x, %#x", + freeNode->header.ptr.prev, freeNode->next, freeNode->prev, freeNode->header.magic, + freeNode->header.sizeAndFlag); + } + +#ifdef LOSCFG_MEM_LEAKCHECK + OsMemNodeBacktraceInfo(tmpNode, preNode); +#endif + + PRINTK("\n---------------------------------------------\n"); + PRINTK(" dump mem tmpNode:%#x ~ %#x\n", tmpNode, ((UINTPTR)tmpNode + OS_MEM_NODE_DUMP_SIZE)); + OsDumpMemByte(OS_MEM_NODE_DUMP_SIZE, (UINTPTR)tmpNode); + PRINTK("\n---------------------------------------------\n"); + if (preNode != tmpNode) { + PRINTK(" dump mem :%#x ~ tmpNode:%#x\n", ((UINTPTR)tmpNode - OS_MEM_NODE_DUMP_SIZE), tmpNode); + OsDumpMemByte(OS_MEM_NODE_DUMP_SIZE, ((UINTPTR)tmpNode - OS_MEM_NODE_DUMP_SIZE)); + PRINTK("\n---------------------------------------------\n"); + } +} + +STATIC VOID OsMemIntegrityCheckError(struct OsMemPoolHead *pool, + const struct OsMemNodeHead *tmpNode, + const struct OsMemNodeHead *preNode, + UINT32 intSave) +{ + OsMemNodeInfo(tmpNode, preNode); + +#if OS_MEM_FREE_BY_TASKID + LosTaskCB *taskCB = NULL; + if (OS_MEM_NODE_GET_USED_FLAG(preNode->sizeAndFlag)) { + struct OsMemUsedNodeHead *usedNode = (struct OsMemUsedNodeHead *)preNode; + UINT32 taskID = usedNode->taskID; + if (OS_TID_CHECK_INVALID(taskID)) { + MEM_UNLOCK(pool, intSave); + LOS_Panic("Task ID %u in pre node is invalid!\n", taskID); + return; + } + + taskCB = OS_TCB_FROM_TID(taskID); + if (OsTaskIsUnused(taskCB) || (taskCB->taskEntry == NULL)) { + MEM_UNLOCK(pool, intSave); + LOS_Panic("\r\nTask ID %u in pre node is not created!\n", taskID); + return; + } + } else { + PRINTK("The prev node is free\n"); + } + MEM_UNLOCK(pool, intSave); + LOS_Panic("cur node: %#x\npre node: %#x\npre node was allocated by task:%s\n", + tmpNode, preNode, taskCB->taskName); +#else + MEM_UNLOCK(pool, intSave); + LOS_Panic("Memory integrity check error, cur node: %#x, pre node: %#x\n", tmpNode, preNode); +#endif +} + +#ifdef LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK +STATIC INLINE UINT32 OsMemAllocCheck(struct OsMemPoolHead *pool, UINT32 intSave) +{ + struct OsMemNodeHead *tmpNode = NULL; + struct OsMemNodeHead *preNode = NULL; + + if (OsMemIntegrityCheck(pool, &tmpNode, &preNode)) { + OsMemIntegrityCheckError(pool, tmpNode, preNode, intSave); + return LOS_NOK; + } + return LOS_OK; +} +#endif + +UINT32 LOS_MemIntegrityCheck(const VOID *pool) +{ + if (pool == NULL) { + return LOS_NOK; + } + + struct OsMemPoolHead *poolHead = (struct OsMemPoolHead *)pool; + struct OsMemNodeHead *tmpNode = NULL; + struct OsMemNodeHead *preNode = NULL; + UINT32 intSave = 0; + + MEM_LOCK(poolHead, intSave); + if (OsMemIntegrityCheck(poolHead, &tmpNode, &preNode)) { + goto ERROR_OUT; + } + MEM_UNLOCK(poolHead, intSave); + return LOS_OK; + +ERROR_OUT: + OsMemIntegrityCheckError(poolHead, tmpNode, preNode, intSave); + return LOS_NOK; +} + +STATIC INLINE VOID OsMemInfoGet(struct OsMemPoolHead *poolInfo, struct OsMemNodeHead *node, + LOS_MEM_POOL_STATUS *poolStatus) +{ + UINT32 totalUsedSize = 0; + UINT32 totalFreeSize = 0; + UINT32 usedNodeNum = 0; + UINT32 freeNodeNum = 0; + UINT32 maxFreeSize = 0; + UINT32 size; + + if (!OS_MEM_NODE_GET_USED_FLAG(node->sizeAndFlag)) { + size = OS_MEM_NODE_GET_SIZE(node->sizeAndFlag); + ++freeNodeNum; + totalFreeSize += size; + if (maxFreeSize < size) { + maxFreeSize = size; + } + } else { + size = OS_MEM_NODE_GET_SIZE(node->sizeAndFlag); + ++usedNodeNum; + totalUsedSize += size; + } + + poolStatus->totalUsedSize += totalUsedSize; + poolStatus->totalFreeSize += totalFreeSize; + poolStatus->maxFreeNodeSize = MAX(poolStatus->maxFreeNodeSize, maxFreeSize); + poolStatus->usedNodeNum += usedNodeNum; + poolStatus->freeNodeNum += freeNodeNum; +} + +UINT32 LOS_MemInfoGet(VOID *pool, LOS_MEM_POOL_STATUS *poolStatus) +{ + struct OsMemPoolHead *poolInfo = pool; + + if (poolStatus == NULL) { + PRINT_ERR("can't use NULL addr to save info\n"); + return LOS_NOK; + } + + if ((pool == NULL) || (poolInfo->info.pool != pool)) { + PRINT_ERR("wrong mem pool addr: %#x, line:%d\n", poolInfo, __LINE__); + return LOS_NOK; + } + + (VOID)memset_s(poolStatus, sizeof(LOS_MEM_POOL_STATUS), 0, sizeof(LOS_MEM_POOL_STATUS)); + + struct OsMemNodeHead *tmpNode = NULL; + struct OsMemNodeHead *endNode = NULL; + UINT32 intSave; + + MEM_LOCK(poolInfo, intSave); + endNode = OS_MEM_END_NODE(pool, poolInfo->info.totalSize); +#if OS_MEM_EXPAND_ENABLE + UINT32 size; + for (tmpNode = OS_MEM_FIRST_NODE(pool); tmpNode <= endNode; tmpNode = OS_MEM_NEXT_NODE(tmpNode)) { + if (tmpNode == endNode) { + poolStatus->totalUsedSize += OS_MEM_NODE_HEAD_SIZE; + poolStatus->usedNodeNum++; + if (OsMemIsLastSentinelNode(endNode) == FALSE) { + size = OS_MEM_NODE_GET_SIZE(endNode->sizeAndFlag); + tmpNode = OsMemSentinelNodeGet(endNode); + endNode = OS_MEM_END_NODE(tmpNode, size); + continue; + } else { + break; + } + } else { + OsMemInfoGet(poolInfo, tmpNode, poolStatus); + } + } +#else + for (tmpNode = OS_MEM_FIRST_NODE(pool); tmpNode < endNode; tmpNode = OS_MEM_NEXT_NODE(tmpNode)) { + OsMemInfoGet(poolInfo, tmpNode, poolStatus); + } +#endif +#ifdef LOSCFG_MEM_WATERLINE + poolStatus->usageWaterLine = poolInfo->info.waterLine; +#endif + MEM_UNLOCK(poolInfo, intSave); + + return LOS_OK; +} + +STATIC VOID OsMemInfoPrint(VOID *pool) +{ + struct OsMemPoolHead *poolInfo = (struct OsMemPoolHead *)pool; + LOS_MEM_POOL_STATUS status = {0}; + + if (LOS_MemInfoGet(pool, &status) == LOS_NOK) { + return; + } + +#ifdef LOSCFG_MEM_WATERLINE + PRINTK("pool addr pool size used size free size " + "max free node size used node num free node num UsageWaterLine\n"); + PRINTK("--------------- -------- ------- -------- " + "-------------- ------------- ------------ ------------\n"); + PRINTK("%-16#x 0x%-8x 0x%-8x 0x%-8x 0x%-16x 0x%-13x 0x%-13x 0x%-13x\n", + poolInfo->info.pool, LOS_MemPoolSizeGet(pool), status.totalUsedSize, + status.totalFreeSize, status.maxFreeNodeSize, status.usedNodeNum, + status.freeNodeNum, status.usageWaterLine); +#else + PRINTK("pool addr pool size used size free size " + "max free node size used node num free node num\n"); + PRINTK("--------------- -------- ------- -------- " + "-------------- ------------- ------------\n"); + PRINTK("%-16#x 0x%-8x 0x%-8x 0x%-8x 0x%-16x 0x%-13x 0x%-13x\n", + poolInfo->info.pool, LOS_MemPoolSizeGet(pool), status.totalUsedSize, + status.totalFreeSize, status.maxFreeNodeSize, status.usedNodeNum, + status.freeNodeNum); +#endif +} + +UINT32 LOS_MemFreeNodeShow(VOID *pool) +{ + struct OsMemPoolHead *poolInfo = (struct OsMemPoolHead *)pool; + + if ((poolInfo == NULL) || ((UINTPTR)pool != (UINTPTR)poolInfo->info.pool)) { + PRINT_ERR("wrong mem pool addr: %#x, line:%d\n", poolInfo, __LINE__); + return LOS_NOK; + } + + struct OsMemFreeNodeHead *node = NULL; + UINT32 countNum[OS_MEM_FREE_LIST_COUNT] = {0}; + UINT32 index; + UINT32 intSave; + + MEM_LOCK(poolInfo, intSave); + for (index = 0; index < OS_MEM_FREE_LIST_COUNT; index++) { + node = poolInfo->freeList[index]; + while (node) { + node = node->next; + countNum[index]++; + } + } + MEM_UNLOCK(poolInfo, intSave); + + PRINTK("\n ************************ left free node number**********************\n"); + for (index = 0; index < OS_MEM_FREE_LIST_COUNT; index++) { + if (countNum[index] == 0) { + continue; + } + + PRINTK("free index: %03u, ", index); + if (index < OS_MEM_SMALL_BUCKET_COUNT) { + PRINTK("size: [%#x], num: %u\n", (index + 1) << 2, countNum[index]); /* 2: setup is 4. */ + } else { + UINT32 val = 1 << (((index - OS_MEM_SMALL_BUCKET_COUNT) >> OS_MEM_SLI) + OS_MEM_LARGE_START_BUCKET); + UINT32 offset = val >> OS_MEM_SLI; + PRINTK("size: [%#x, %#x], num: %u\n", + (offset * ((index - OS_MEM_SMALL_BUCKET_COUNT) % (1 << OS_MEM_SLI))) + val, + ((offset * (((index - OS_MEM_SMALL_BUCKET_COUNT) % (1 << OS_MEM_SLI)) + 1)) + val - 1), + countNum[index]); + } + } + PRINTK("\n ********************************************************************\n\n"); + + return LOS_OK; +} + +STATUS_T OsKHeapInit(size_t size) +{ + STATUS_T ret; + VOID *ptr = NULL; + /* + * roundup to MB aligned in order to set kernel attributes. kernel text/code/data attributes + * should page mapping, remaining region should section mapping. so the boundary should be + * MB aligned. + */ + UINTPTR end = ROUNDUP(g_vmBootMemBase + size, MB); + size = end - g_vmBootMemBase; + + ptr = OsVmBootMemAlloc(size); + if (!ptr) { + PRINT_ERR("vmm_kheap_init boot_alloc_mem failed! %d\n", size); + return -1; + } + + m_aucSysMem0 = m_aucSysMem1 = ptr; + ret = LOS_MemInit(m_aucSysMem0, size); + if (ret != LOS_OK) { + PRINT_ERR("vmm_kheap_init LOS_MemInit failed!\n"); + g_vmBootMemBase -= size; + return ret; + } +#if OS_MEM_EXPAND_ENABLE + LOS_MemExpandEnable(OS_SYS_MEM_ADDR); +#endif + return LOS_OK; +} + +BOOL OsMemIsHeapNode(const VOID *ptr) +{ + struct OsMemPoolHead *pool = (struct OsMemPoolHead *)m_aucSysMem1; + struct OsMemNodeHead *firstNode = OS_MEM_FIRST_NODE(pool); + struct OsMemNodeHead *endNode = OS_MEM_END_NODE(pool, pool->info.totalSize); + + if (OS_MEM_MIDDLE_ADDR(firstNode, ptr, endNode)) { + return TRUE; + } + +#if OS_MEM_EXPAND_ENABLE + UINT32 intSave; + UINT32 size; + MEM_LOCK(pool, intSave); + while (OsMemIsLastSentinelNode(endNode) == FALSE) { + size = OS_MEM_NODE_GET_SIZE(endNode->sizeAndFlag); + firstNode = OsMemSentinelNodeGet(endNode); + endNode = OS_MEM_END_NODE(firstNode, size); + if (OS_MEM_MIDDLE_ADDR(firstNode, ptr, endNode)) { + MEM_UNLOCK(pool, intSave); + return TRUE; + } + } + MEM_UNLOCK(pool, intSave); +#endif + return FALSE; +} diff --git a/src/kernel_liteos_a/kernel/base/misc/kill_shellcmd.c b/src/kernel_liteos_a/kernel/base/misc/kill_shellcmd.c new file mode 100644 index 00000000..e21dca7d --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/misc/kill_shellcmd.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "stdio.h" +#include "stdlib.h" +#include "los_signal.h" +#include "los_printf.h" +#include "los_task_pri.h" +#include "los_process_pri.h" + +#ifdef LOSCFG_BASE_CORE_HILOG +#include "log.h" +#else +#define HILOG_INFO(type, fmt, ...) PRINT_INFO(fmt, __VA_ARGS__) +#define HILOG_ERROR(type, fmt, ...) PRINT_ERR(fmt, __VA_ARGS__) +#endif + +#ifdef LOSCFG_SHELL +#include "shcmd.h" +#include "shell.h" +#endif + +LITE_OS_SEC_TEXT_MINOR VOID OsPrintKillUsage(VOID) +{ + PRINTK("\nkill: usage: kill [sigspec] [pid]\n"); +} + +LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdKill(INT32 argc, const CHAR **argv) +{ +#define ARG_NUM 2 + INT32 sigNo = 0; + INT32 pidNo = 0; + INT32 ret; + CHAR *endPtr = NULL; + + if (argc == ARG_NUM) { + sigNo = strtoul(argv[0], &endPtr, 0); + if (*endPtr != 0) { + PRINT_ERR("\nsigNo can't access %s.\n", argv[0]); + goto ERROR; + } + endPtr = NULL; + pidNo = strtoul(argv[1], &endPtr, 0); + if (*endPtr != 0) { + PRINT_ERR("\npidNo can't access %s.\n", argv[1]); + goto ERROR; + } + + ret = OsKill(pidNo, abs(sigNo), OS_USER_KILL_PERMISSION); + HILOG_INFO(LOG_CORE, "Send signal(%d) to pidNo = %d!\n", abs(sigNo), pidNo); + if (ret == -1) { + HILOG_ERROR(LOG_CORE, "Kill fail ret = %d! Operation not permitted\n", ret); + goto ERROR; + } + if (ret < 0) { + PRINT_ERR("\n Kill fail ret = %d! process not exist or sigNo is invalid\n", ret); + goto ERROR; + } + } else { + PRINT_ERR("\nPara number errno!\n"); + goto ERROR; + } + return 0; +ERROR: + OsPrintKillUsage(); + return 0; +} + +#ifdef LOSCFG_SHELL +SHELLCMD_ENTRY(kill_shellcmd, CMD_TYPE_EX, "kill", 2, (CmdCallBackFunc)OsShellCmdKill); +#endif + diff --git a/src/kernel_liteos_a/kernel/base/misc/los_misc.c b/src/kernel_liteos_a/kernel/base/misc/los_misc.c new file mode 100644 index 00000000..05a083ee --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/misc/los_misc.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_task_pri.h" + + +LITE_OS_SEC_TEXT UINTPTR LOS_Align(UINTPTR addr, UINT32 boundary) +{ + if ((addr + boundary - 1) > addr) { + return (addr + boundary - 1) & ~((UINTPTR)(boundary - 1)); + } else { + return addr & ~((UINTPTR)(boundary - 1)); + } +} + +LITE_OS_SEC_TEXT_MINOR VOID LOS_Msleep(UINT32 msecs) +{ + UINT32 interval; + + if (msecs == 0) { + interval = 0; + } else { + interval = LOS_MS2Tick(msecs); + if (interval == 0) { + interval = 1; + } + } + + (VOID)LOS_TaskDelay(interval); +} + diff --git a/src/kernel_liteos_a/kernel/base/misc/los_stackinfo.c b/src/kernel_liteos_a/kernel/base/misc/los_stackinfo.c new file mode 100644 index 00000000..6f96a8a5 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/misc/los_stackinfo.c @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_stackinfo_pri.h" +#include "los_printf_pri.h" +#include "los_config.h" +#include "securec.h" +#ifdef LOSCFG_SHELL +#include "shcmd.h" +#include "shell.h" +#endif + +const StackInfo *g_stackInfo = NULL; +UINT32 g_stackNum; + +UINT32 OsStackWaterLineGet(const UINTPTR *stackBottom, const UINTPTR *stackTop, UINT32 *peakUsed) +{ + UINT32 size; + const UINTPTR *tmp = NULL; + if (*stackTop == OS_STACK_MAGIC_WORD) { + tmp = stackTop + 1; + while ((tmp < stackBottom) && (*tmp == OS_STACK_INIT)) { + tmp++; + } + size = (UINT32)((UINTPTR)stackBottom - (UINTPTR)tmp); + *peakUsed = (size == 0) ? size : (size + sizeof(CHAR *)); + return LOS_OK; + } else { + *peakUsed = OS_INVALID_WATERLINE; + return LOS_NOK; + } +} + +VOID OsExcStackCheck(VOID) +{ + UINT32 index; + UINT32 cpuid; + UINTPTR *stackTop = NULL; + + if (g_stackInfo == NULL) { + return; + } + for (index = 0; index < g_stackNum; index++) { + for (cpuid = 0; cpuid < LOSCFG_KERNEL_CORE_NUM; cpuid++) { + stackTop = (UINTPTR *)((UINTPTR)g_stackInfo[index].stackTop + cpuid * g_stackInfo[index].stackSize); + if (*stackTop != OS_STACK_MAGIC_WORD) { + PRINT_ERR("cpu:%u %s overflow , magic word changed to 0x%x\n", + LOSCFG_KERNEL_CORE_NUM - 1 - cpuid, g_stackInfo[index].stackName, *stackTop); + } + } + } +} + +VOID OsExcStackInfo(VOID) +{ + UINT32 index; + UINT32 cpuid; + UINT32 size; + UINTPTR *stackTop = NULL; + UINTPTR *stack = NULL; + + if (g_stackInfo == NULL) { + return; + } + + PrintExcInfo("\n stack name cpu id stack addr total size used size\n" + " ---------- ------ --------- -------- --------\n"); + + for (index = 0; index < g_stackNum; index++) { + for (cpuid = 0; cpuid < LOSCFG_KERNEL_CORE_NUM; cpuid++) { + stackTop = (UINTPTR *)((UINTPTR)g_stackInfo[index].stackTop + cpuid * g_stackInfo[index].stackSize); + stack = (UINTPTR *)((UINTPTR)stackTop + g_stackInfo[index].stackSize); + (VOID)OsStackWaterLineGet(stack, stackTop, &size); + + PrintExcInfo("%11s %-5d %-10p 0x%-8x 0x%-4x\n", g_stackInfo[index].stackName, + LOSCFG_KERNEL_CORE_NUM - 1 - cpuid, stackTop, g_stackInfo[index].stackSize, size); + } + } + + OsExcStackCheck(); +} + +VOID OsExcStackInfoReg(const StackInfo *stackInfo, UINT32 stackNum) +{ + g_stackInfo = stackInfo; + g_stackNum = stackNum; +} + +VOID OsStackInit(VOID *stacktop, UINT32 stacksize) +{ + /* initialize the task stack, write magic num to stack top */ + errno_t ret = memset_s(stacktop, stacksize, (INT32)OS_STACK_INIT, stacksize); + if (ret == EOK) { + *((UINTPTR *)stacktop) = OS_STACK_MAGIC_WORD; + } +} + +#ifdef LOSCFG_SHELL_CMD_DEBUG +SHELLCMD_ENTRY(stack_shellcmd, CMD_TYPE_EX, "stack", 1, (CmdCallBackFunc)OsExcStackInfo); +#endif diff --git a/src/kernel_liteos_a/kernel/base/misc/mempt_shellcmd.c b/src/kernel_liteos_a/kernel/base/misc/mempt_shellcmd.c new file mode 100644 index 00000000..0e8ec47b --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/misc/mempt_shellcmd.c @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "stdlib.h" +#include "los_memory_pri.h" +#ifdef LOSCFG_SAVE_EXCINFO +#include "los_excinfo_pri.h" +#endif +#ifdef LOSCFG_SHELL +#include "shcmd.h" +#include "shell.h" +#endif +#include "los_vm_common.h" +#include "los_vm_boot.h" +#include "los_vm_map.h" +#include "los_vm_dump.h" + + +#define MEM_SIZE_1K 0x400 +#define MEM_SIZE_1M 0x100000 + +#define MEM_SIZE_TO_KB(size) (((size) + (MEM_SIZE_1K >> 1)) / MEM_SIZE_1K) +#define MEM_SIZE_TO_MB(size) (((size) + (MEM_SIZE_1M >> 1)) / MEM_SIZE_1M) + +VOID OsDumpMemByte(size_t length, UINTPTR addr) +{ + size_t dataLen; + UINTPTR *alignAddr = NULL; + UINT32 count = 0; + + dataLen = ALIGN(length, sizeof(UINTPTR)); + alignAddr = (UINTPTR *)TRUNCATE(addr, sizeof(UINTPTR)); + if ((dataLen == 0) || (alignAddr == NULL)) { + return; + } + while (dataLen) { + if (IS_ALIGNED(count, sizeof(CHAR *))) { + PRINTK("\n 0x%lx :", alignAddr); +#ifdef LOSCFG_SAVE_EXCINFO + WriteExcInfoToBuf("\n 0x%lx :", alignAddr); +#endif + } +#ifdef __LP64__ + PRINTK("%0+16lx ", *alignAddr); +#else + PRINTK("%0+8lx ", *alignAddr); +#endif +#ifdef LOSCFG_SAVE_EXCINFO +#ifdef __LP64__ + WriteExcInfoToBuf("0x%0+16x ", *alignAddr); +#else + WriteExcInfoToBuf("0x%0+8x ", *alignAddr); +#endif +#endif + alignAddr++; + dataLen -= sizeof(CHAR *); + count++; + } + PRINTK("\n"); +#ifdef LOSCFG_SAVE_EXCINFO + WriteExcInfoToBuf("\n"); +#endif + + return; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdMemCheck(INT32 argc, const CHAR *argv[]) +{ + if (argc > 0) { + PRINTK("\nUsage: memcheck\n"); + return OS_ERROR; + } + + if (LOS_MemIntegrityCheck(m_aucSysMem1) == LOS_OK) { + PRINTK("system memcheck over, all passed!\n"); +#ifdef LOSCFG_SAVE_EXCINFO + WriteExcInfoToBuf("system memcheck over, all passed!\n"); +#endif + } + + return 0; +} + +#ifdef LOSCFG_SHELL +LITE_OS_SEC_TEXT_MINOR STATIC VOID OsShellCmdSectionInfo(INT32 argc, const CHAR *argv[]) +{ + size_t textLen = &__text_end - &__text_start; + size_t dataLen = &__ram_data_end - &__ram_data_start; + size_t rodataLen = &__rodata_end - &__rodata_start; + size_t bssLen = &__bss_end - &__bss_start; + + PRINTK("\r\n text data rodata bss\n"); + if ((argc == 1) && (strcmp(argv[0], "-k") == 0)) { + PRINTK("Mem: %-9lu %-10lu %-10lu %-10lu\n", MEM_SIZE_TO_KB(textLen), MEM_SIZE_TO_KB(dataLen), + MEM_SIZE_TO_KB(rodataLen), MEM_SIZE_TO_KB(bssLen)); + } else if ((argc == 1) && (strcmp(argv[0], "-m") == 0)) { + PRINTK("Mem: %-9lu %-10lu %-10lu %-10lu\n", MEM_SIZE_TO_MB(textLen), MEM_SIZE_TO_MB(dataLen), + MEM_SIZE_TO_MB(rodataLen), MEM_SIZE_TO_MB(bssLen)); + } else { + PRINTK("Mem: %-9lu %-10lu %-10lu %-10lu\n", textLen, dataLen, rodataLen, bssLen); + } +} + +LITE_OS_SEC_TEXT_MINOR STATIC UINT32 OsShellCmdFreeInfo(INT32 argc, const CHAR *argv[]) +{ + UINT32 memUsed = LOS_MemTotalUsedGet(m_aucSysMem1); + UINT32 totalMem = LOS_MemPoolSizeGet(m_aucSysMem1); + UINT32 freeMem = totalMem - memUsed; + UINT32 memUsedHeap = memUsed; + +#ifdef LOSCFG_KERNEL_VM + UINT32 usedCount, totalCount; + OsVmPhysUsedInfoGet(&usedCount, &totalCount); + totalMem = SYS_MEM_SIZE_DEFAULT; + memUsed = SYS_MEM_SIZE_DEFAULT - (totalCount << PAGE_SHIFT); + memUsed += (usedCount << PAGE_SHIFT) - freeMem; + freeMem = totalMem - memUsed; +#else + totalMem = SYS_MEM_SIZE_DEFAULT; + memUsed = g_vmBootMemBase - KERNEL_ASPACE_BASE; + memUsed -= freeMem; + freeMem -= totalMem - memUsed; +#endif + + if ((argc == 0) || + ((argc == 1) && (strcmp(argv[0], "-k") == 0)) || + ((argc == 1) && (strcmp(argv[0], "-m") == 0))) { + PRINTK("\r\n total used free heap\n"); + } + + if ((argc == 1) && (strcmp(argv[0], "-k") == 0)) { + PRINTK("Mem: %-9u %-10u %-10u %-10u\n", MEM_SIZE_TO_KB(totalMem), MEM_SIZE_TO_KB(memUsed), + MEM_SIZE_TO_KB(freeMem), MEM_SIZE_TO_KB(memUsedHeap)); + } else if ((argc == 1) && (strcmp(argv[0], "-m") == 0)) { + PRINTK("Mem: %-9u %-10u %-10u %-10u\n", MEM_SIZE_TO_MB(totalMem), MEM_SIZE_TO_MB(memUsed), + MEM_SIZE_TO_MB(freeMem), MEM_SIZE_TO_MB(memUsedHeap)); + } else if (argc == 0) { + PRINTK("Mem: %-9u %-10u %-10u %-10u\n", totalMem, memUsed, freeMem, memUsedHeap); + } else { + PRINTK("\nUsage: free or free [-k/-m]\n"); + return OS_ERROR; + } + return 0; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdFree(INT32 argc, const CHAR *argv[]) +{ + if (argc > 1) { + PRINTK("\nUsage: free or free [-k/-m]\n"); + return OS_ERROR; + } + if (OsShellCmdFreeInfo(argc, argv) != 0) { + return OS_ERROR; + } + OsShellCmdSectionInfo(argc, argv); + return 0; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdUname(INT32 argc, const CHAR *argv[]) +{ + if (argc == 0) { + PRINTK("%s\n", KERNEL_NAME); + return 0; + } + + if (argc == 1) { + if (strcmp(argv[0], "-a") == 0) { + PRINTK("%s %d.%d.%d.%d %s %s\n", KERNEL_NAME, KERNEL_MAJOR, KERNEL_MINOR, KERNEL_PATCH, KERNEL_ITRE, \ + __DATE__, __TIME__); + return 0; + } else if (strcmp(argv[0], "-s") == 0) { + PRINTK("%s\n", KERNEL_NAME); + return 0; + } else if (strcmp(argv[0], "-t") == 0) { + PRINTK("build date : %s %s\n", __DATE__, __TIME__); + return 0; + } else if (strcmp(argv[0], "-v") == 0) { + PRINTK("%d.%d.%d.%d\n", KERNEL_MAJOR, KERNEL_MINOR, KERNEL_PATCH, KERNEL_ITRE); + return 0; + } else if (strcmp(argv[0], "--help") == 0) { + PRINTK("-a, print all information\n" + "-s, print the kernel name\n" + "-t, print the build date\n" + "-v, print the kernel version\n"); + return 0; + } + } + + PRINTK("uname: invalid option %s\n" + "Try 'uname --help' for more information.\n", + argv[0]); + return OS_ERROR; +} +#ifdef LOSCFG_MEM_LEAKCHECK +LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdMemUsed(INT32 argc, const CHAR *argv[]) +{ + if (argc > 0) { + PRINTK("\nUsage: memused\n"); + return OS_ERROR; + } + + OsMemUsedNodeShow(m_aucSysMem1); + + return 0; +} +#endif + +#ifdef LOSCFG_MEM_LEAKCHECK +SHELLCMD_ENTRY(memused_shellcmd, CMD_TYPE_EX, "memused", 0, (CmdCallBackFunc)OsShellCmdMemUsed); +#endif + +#ifdef LOSCFG_SHELL_CMD_DEBUG +SHELLCMD_ENTRY(memcheck_shellcmd, CMD_TYPE_EX, "memcheck", 0, (CmdCallBackFunc)OsShellCmdMemCheck); +#endif +SHELLCMD_ENTRY(free_shellcmd, CMD_TYPE_EX, "free", XARGS, (CmdCallBackFunc)OsShellCmdFree); +SHELLCMD_ENTRY(uname_shellcmd, CMD_TYPE_EX, "uname", XARGS, (CmdCallBackFunc)OsShellCmdUname); +#endif + diff --git a/src/kernel_liteos_a/kernel/base/misc/panic_shellcmd.c b/src/kernel_liteos_a/kernel/base/misc/panic_shellcmd.c new file mode 100644 index 00000000..e059436b --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/misc/panic_shellcmd.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_config.h" +#ifdef LOSCFG_SHELL +#include "shcmd.h" +#include "shell.h" +#endif +#include "los_swtmr_pri.h" + + +#ifdef LOSCFG_SHELL_CMD_DEBUG +STATIC BOOL systemExcReset = FALSE; + +LITE_OS_SEC_TEXT_MINOR BOOL OsSystemExcIsReset(VOID) +{ + return systemExcReset; +} +#ifdef LOSCFG_DRIVERS_HDF_PLATFORM_WATCHDOG +#include "watchdog_if.h" + +#define WATCHDOG_TIMER_INTERVAL 5 // 5 seconds +#define WATCHDOG_TIMER_INTERVAL_HALF (WATCHDOG_TIMER_INTERVAL / 2) + +STATIC UINT16 g_swtmrID; +STATIC BOOL g_wdStarted = FALSE; +STATIC DevHandle g_wdHandle; + +STATIC void StartWatchdog(void) +{ + int32_t ret; + if (g_wdStarted) { + return; + } + + ret = WatchdogOpen(0, &g_wdHandle); + if (ret != HDF_SUCCESS) { + return; + } + WatchdogSetTimeout(g_wdHandle, WATCHDOG_TIMER_INTERVAL); + + if (LOS_SwtmrCreate(LOSCFG_BASE_CORE_TICK_PER_SECOND * WATCHDOG_TIMER_INTERVAL_HALF, LOS_SWTMR_MODE_PERIOD, + (SWTMR_PROC_FUNC)WatchdogFeed, &g_swtmrID, (UINTPTR)g_wdHandle) != LOS_OK) { + WatchdogClose(g_wdHandle); + g_wdHandle = NULL; + return; + } + + WatchdogStart(g_wdHandle); + LOS_SwtmrStart(g_swtmrID); + g_wdStarted = TRUE; +} + +STATIC void StopWatchdog(void) +{ + if (!g_wdStarted) { + return; + } + + LOS_SwtmrStop(g_swtmrID); + LOS_SwtmrDelete(g_swtmrID); + g_swtmrID = 0; + + WatchdogStop(g_wdHandle); + WatchdogClose(g_wdHandle); + g_wdHandle = NULL; + + g_wdStarted = FALSE; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdSystemExcReset(INT32 argc, const CHAR **argv) +{ + if (argc != 1) { + goto EXC_RESET_HELP; + } + + if (strcmp(argv[0], "on") == 0) { + systemExcReset = TRUE; + StartWatchdog(); + PRINTK("panicreset on!\n"); + return LOS_OK; + } + + if (strcmp(argv[0], "off") == 0) { + systemExcReset = FALSE; + StopWatchdog(); + PRINTK("panicreset off!\n"); + return LOS_OK; + } + +EXC_RESET_HELP: + PRINTK("usage: panicreset [on/off]\n"); + return LOS_OK; +} + +SHELLCMD_ENTRY(panic_reset_shellcmd, CMD_TYPE_EX, "panicreset", 1, (CmdCallBackFunc)OsShellCmdSystemExcReset); +#endif +#endif + diff --git a/src/kernel_liteos_a/kernel/base/misc/swtmr_shellcmd.c b/src/kernel_liteos_a/kernel/base/misc/swtmr_shellcmd.c new file mode 100644 index 00000000..81573ef4 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/misc/swtmr_shellcmd.c @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_config.h" +#ifdef LOSCFG_SHELL_CMD_DEBUG +#include "stdlib.h" +#include "los_swtmr_pri.h" +#include "shcmd.h" +#include "shell.h" + +#define OS_ALL_SWTMR_MASK 0xffffffff +#define SWTMR_STRLEN 12 + +LITE_OS_SEC_DATA_MINOR STATIC CHAR g_shellSwtmrMode[][SWTMR_STRLEN] = { + "Once", + "Period", + "NSD", + "OPP", +}; + +LITE_OS_SEC_DATA_MINOR STATIC CHAR g_shellSwtmrStatus[][SWTMR_STRLEN] = { + "UnUsed", + "Created", + "Ticking", +}; + +STATIC VOID OsPrintSwtmrMsg(const SWTMR_CTRL_S *swtmr) +{ + UINT32 ticks = 0; + (VOID)LOS_SwtmrTimeGet(swtmr->usTimerID, &ticks); + + PRINTK("%7u%10s%8s%12u%7u%#12x%#12x\n", + swtmr->usTimerID % LOSCFG_BASE_CORE_SWTMR_LIMIT, + g_shellSwtmrStatus[swtmr->ucState], + g_shellSwtmrMode[swtmr->ucMode], + swtmr->uwInterval, + ticks, + swtmr->uwArg, + swtmr->pfnHandler); +} + +STATIC INLINE VOID OsPrintSwtmrMsgHead(VOID) +{ + PRINTK("\r\nSwTmrID State Mode Interval Count Arg handlerAddr\n"); +} + +STATIC UINT32 SwtmrBaseInfoGet(UINT32 timerID) +{ + SWTMR_CTRL_S *swtmr = g_swtmrCBArray; + SWTMR_CTRL_S *swtmr1 = g_swtmrCBArray; + UINT16 index; + UINT16 num = 0; + + for (index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++, swtmr1++) { + if (swtmr1->ucState == 0) { + num = num + 1; + } + } + + if (num == LOSCFG_BASE_CORE_SWTMR_LIMIT) { + PRINTK("\r\nThere is no swtmr was created!\n"); + return LOS_NOK; + } + + if (timerID == OS_ALL_SWTMR_MASK) { + OsPrintSwtmrMsgHead(); + for (index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++, swtmr++) { + if (swtmr->ucState != 0) { + OsPrintSwtmrMsg(swtmr); + } + } + } else { + for (index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++, swtmr++) { + if ((timerID == (size_t)(swtmr->usTimerID % LOSCFG_BASE_CORE_SWTMR_LIMIT)) && (swtmr->ucState != 0)) { + OsPrintSwtmrMsgHead(); + OsPrintSwtmrMsg(swtmr); + return LOS_OK; + } + } + PRINTK("\r\nThe SwTimerID is not exist.\n"); + } + return LOS_OK; +} + +#ifdef LOSCFG_SWTMR_DEBUG +STATIC VOID OsSwtmrTimeInfoShow(VOID) +{ + UINT8 mode; + SwtmrDebugData data; + + PRINTK("SwtmrID Cpuid Mode Period(us) WaitTime(us) WaitMax(us) RTime(us) RTimeMax(us) ReTime(us)" + " ReTimeMax(us) RunCount LostNum Handler\n"); + for (UINT32 index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++) { + if (!OsSwtmrDebugDataUsed(index)) { + continue; + } + + UINT32 ret = OsSwtmrDebugDataGet(index, &data, sizeof(SwtmrDebugData), &mode); + if (ret != LOS_OK) { + break; + } + + SwtmrDebugBase *base = &data.base; + UINT64 waitTime = ((base->waitTime / base->waitCount) * OS_NS_PER_CYCLE) / OS_SYS_NS_PER_US; + UINT64 waitTimeMax = (base->waitTimeMax * OS_NS_PER_CYCLE) / OS_SYS_NS_PER_US; + UINT64 runTime = ((base->runTime / base->runCount) * OS_NS_PER_CYCLE) / OS_SYS_NS_PER_US; + UINT64 runTimeMax = (base->runTimeMax * OS_NS_PER_CYCLE) / OS_SYS_NS_PER_US; + UINT64 readyTime = ((base->readyTime / base->runCount) * OS_NS_PER_CYCLE) / OS_SYS_NS_PER_US; + UINT64 readyTimeMax = (base->readyTimeMax * OS_NS_PER_CYCLE) / OS_SYS_NS_PER_US; + PRINTK("%4u%10u%7s%14u%13llu%12llu%10llu%13llu%10llu%14llu%15llu%11u%#12x\n", + index, data.cpuid, g_shellSwtmrMode[mode], data.period * OS_US_PER_TICK, waitTime, waitTimeMax, + runTime, runTimeMax, readyTime, readyTimeMax, base->runCount, base->times, data.handler); + } +} +#endif + +LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdSwtmrInfoGet(INT32 argc, const CHAR **argv) +{ + UINT32 timerID; + CHAR *endPtr = NULL; + + if (argc > 1) { + goto SWTMR_HELP; + } + + if (argc == 0) { + timerID = OS_ALL_SWTMR_MASK; +#ifdef LOSCFG_SWTMR_DEBUG + } else if (strcmp("-t", argv[0]) == 0) { + OsSwtmrTimeInfoShow(); + return LOS_OK; +#endif + } else { + timerID = strtoul(argv[0], &endPtr, 0); + if ((endPtr == NULL) || (*endPtr != 0) || (timerID > LOSCFG_BASE_CORE_SWTMR_LIMIT)) { + PRINTK("\nswtmr ID can't access %s.\n", argv[0]); + return LOS_NOK; + } + } + + return SwtmrBaseInfoGet(timerID); +SWTMR_HELP: + PRINTK("Usage:\n"); + PRINTK(" swtmr --- Information about all created software timers.\n"); + PRINTK(" swtmr ID --- Specifies information about a software timer.\n"); + return LOS_OK; +} + +SHELLCMD_ENTRY(swtmr_shellcmd, CMD_TYPE_EX, "swtmr", 1, (CmdCallBackFunc)OsShellCmdSwtmrInfoGet); + +#endif /* LOSCFG_SHELL */ diff --git a/src/kernel_liteos_a/kernel/base/misc/sysinfo_shellcmd.c b/src/kernel_liteos_a/kernel/base/misc/sysinfo_shellcmd.c new file mode 100644 index 00000000..b7c56f84 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/misc/sysinfo_shellcmd.c @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_config.h" +#include "los_swtmr.h" +#include "los_sem_pri.h" +#include "los_queue_pri.h" +#include "los_swtmr_pri.h" +#include "los_task_pri.h" +#ifdef LOSCFG_IPC_CONTAINER +#include "los_ipc_container_pri.h" +#endif + +#ifdef LOSCFG_SHELL +#include "shcmd.h" +#include "shell.h" +#endif + + +#define SYSINFO_ENABLED(x) (((x) == TRUE) ? "YES" : "NO") +UINT32 OsShellCmdTaskCntGet(VOID) +{ + UINT32 loop; + UINT32 taskCnt = 0; + UINT32 intSave; + LosTaskCB *taskCB = NULL; + + intSave = LOS_IntLock(); + for (loop = 0; loop < g_taskMaxNum; loop++) { + taskCB = (LosTaskCB *)g_taskCBArray + loop; + if (OsTaskIsUnused(taskCB)) { + continue; + } + taskCnt++; + } + LOS_IntRestore(intSave); + return taskCnt; +} + +UINT32 OsShellCmdSemCntGet(VOID) +{ + UINT32 loop; + UINT32 semCnt = 0; + UINT32 intSave; + LosSemCB *semNode = NULL; + + intSave = LOS_IntLock(); + for (loop = 0; loop < LOSCFG_BASE_IPC_SEM_LIMIT; loop++) { + semNode = GET_SEM(loop); + if (semNode->semStat == OS_SEM_USED) { + semCnt++; + } + } + LOS_IntRestore(intSave); + return semCnt; +} + +UINT32 OsShellCmdQueueCntGet(VOID) +{ + UINT32 loop; + UINT32 queueCnt = 0; + UINT32 intSave; + LosQueueCB *queueCB = NULL; + + intSave = LOS_IntLock(); + queueCB = IPC_ALL_QUEUE; + for (loop = 0; loop < LOSCFG_BASE_IPC_QUEUE_LIMIT; loop++, queueCB++) { + if (queueCB->queueState == OS_QUEUE_INUSED) { + queueCnt++; + } + } + LOS_IntRestore(intSave); + return queueCnt; +} + +UINT32 OsShellCmdSwtmrCntGet(VOID) +{ + UINT32 loop; + UINT32 swtmrCnt = 0; + UINT32 intSave; + SWTMR_CTRL_S *swtmrCB = NULL; + + intSave = LOS_IntLock(); + swtmrCB = g_swtmrCBArray; + for (loop = 0; loop < LOSCFG_BASE_CORE_SWTMR_LIMIT; loop++, swtmrCB++) { + if (swtmrCB->ucState != OS_SWTMR_STATUS_UNUSED) { + swtmrCnt++; + } + } + LOS_IntRestore(intSave); + return swtmrCnt; +} + +LITE_OS_SEC_TEXT_MINOR VOID OsShellCmdSystemInfoGet(VOID) +{ + UINT8 isTaskEnable = TRUE; +#ifdef LOSCFG_BASE_IPC_SEM + UINT8 isSemEnable = TRUE; +#else + UINT8 isSemEnable = FALSE; +#endif +#ifdef LOSCFG_BASE_IPC_QUEUE + UINT8 isQueueEnable = TRUE; +#else + UINT8 isQueueEnable = FALSE; +#endif +#ifdef LOSCFG_BASE_CORE_SWTMR_ENABLE + UINT8 isSwtmrEnable = TRUE; +#else + UINT8 isSwtmrEnable = FALSE; +#endif + + PRINTK("\n Module Used Total Enabled\n"); + PRINTK("--------------------------------------------\n"); + PRINTK(" Task %-10u%-10d%s\n", + OsShellCmdTaskCntGet(), + LOSCFG_BASE_CORE_TSK_LIMIT, + SYSINFO_ENABLED(isTaskEnable)); + PRINTK(" Sem %-10u%-10d%s\n", + OsShellCmdSemCntGet(), + LOSCFG_BASE_IPC_SEM_LIMIT, + SYSINFO_ENABLED(isSemEnable)); + PRINTK(" Queue %-10u%-10d%s\n", + OsShellCmdQueueCntGet(), + LOSCFG_BASE_IPC_QUEUE_LIMIT, + SYSINFO_ENABLED(isQueueEnable)); + PRINTK(" SwTmr %-10u%-10d%s\n", + OsShellCmdSwtmrCntGet(), + LOSCFG_BASE_CORE_SWTMR_LIMIT, + SYSINFO_ENABLED(isSwtmrEnable)); +} + +INT32 OsShellCmdSystemInfo(INT32 argc, const CHAR **argv) +{ + if (argc == 0) { + OsShellCmdSystemInfoGet(); + return 0; + } + PRINTK("systeminfo: invalid option %s\n" + "Systeminfo has NO ARGS.\n", + argv[0]); + return -1; +} + +#ifdef LOSCFG_SHELL +SHELLCMD_ENTRY(systeminfo_shellcmd, CMD_TYPE_EX, "systeminfo", 1, (CmdCallBackFunc)OsShellCmdSystemInfo); +#endif /* LOSCFG_SHELL */ + diff --git a/src/kernel_liteos_a/kernel/base/misc/task_shellcmd.c b/src/kernel_liteos_a/kernel/base/misc/task_shellcmd.c new file mode 100644 index 00000000..4b78af58 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/misc/task_shellcmd.c @@ -0,0 +1,452 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "stdlib.h" +#include "los_config.h" +#include "los_exc.h" +#include "los_memstat_pri.h" +#include "los_sem_pri.h" +#include "los_seq_buf.h" +#include "los_task_pri.h" +#ifdef LOSCFG_SHELL +#include "shcmd.h" +#include "shell.h" +#endif +#ifdef LOSCFG_KERNEL_CPUP +#include "los_cpup_pri.h" +#endif +#ifdef LOSCFG_SAVE_EXCINFO +#include "los_excinfo_pri.h" +#endif +#include "los_process_pri.h" +#ifdef LOSCFG_FS_VFS +#include "fs/file.h" +#endif +#include "los_sched_pri.h" +#include "los_swtmr_pri.h" +#include "los_info_pri.h" +#ifdef LOSCFG_SCHED_DEBUG +#include "los_statistics_pri.h" +#endif + +#define OS_PROCESS_MEM_INFO 0x2U +#undef SHOW +#ifdef LOSCFG_FS_VFS +#if defined(LOSCFG_BLACKBOX) && defined(LOSCFG_SAVE_EXCINFO) +#define SaveExcInfo(arg, ...) WriteExcInfoToBuf(arg, ##__VA_ARGS__) +#else +#define SaveExcInfo(arg, ...) +#endif +#define SHOW(arg...) do { \ + if (seqBuf != NULL) { \ + (void)LosBufPrintf((struct SeqBuf *)seqBuf, ##arg); \ + } else { \ + PRINTK(arg); \ + } \ + SaveExcInfo(arg); \ +} while (0) +#else +#define SHOW(arg...) PRINTK(arg) +#endif + +#define CPUP_MULT LOS_CPUP_PRECISION_MULT + +STATIC UINT8 *ConvertProcessModeToString(UINT16 mode) +{ + if (mode == OS_KERNEL_MODE) { + return (UINT8 *)"kernel"; + } else if (mode == OS_USER_MODE) { + return (UINT8 *)"user"; + } + + return (UINT8 *)"ERROR"; +} + +STATIC UINT8 *ConvertSchedPolicyToString(UINT16 policy) +{ + if (policy == LOS_SCHED_RR) { + return (UINT8 *)"RR"; + } else if (policy == LOS_SCHED_FIFO) { + return (UINT8 *)"FIFO"; + } else if (policy == LOS_SCHED_DEADLINE) { + return (UINT8 *)"EDF"; + } else if (policy == LOS_SCHED_IDLE) { + return (UINT8 *)"IDLE"; + } + + return (UINT8 *)"ERROR"; +} + +STATIC UINT8 *ConvertProcessStatusToString(UINT16 status) +{ + if (status & OS_PROCESS_STATUS_ZOMBIES) { + return (UINT8 *)"Zombies"; + } else if (status & OS_PROCESS_STATUS_INIT) { + return (UINT8 *)"Init"; + } else if (status & OS_PROCESS_STATUS_RUNNING) { + return (UINT8 *)"Running"; + } else if (status & OS_PROCESS_STATUS_READY) { + return (UINT8 *)"Ready"; + } + return (UINT8 *)"Pending"; +} + +STATIC VOID ProcessInfoTitle(VOID *seqBuf, UINT16 flag) +{ + SHOW("\r\n PID PPID PGID UID Mode Status Policy Priority MTID TTotal"); + if (flag & OS_PROCESS_INFO_ALL) { +#ifdef LOSCFG_KERNEL_VM + if (flag & OS_PROCESS_MEM_INFO) { + SHOW(" VirtualMem ShareMem PhysicalMem"); + } +#endif +#ifdef LOSCFG_KERNEL_CPUP + SHOW(" CPUUSE CPUUSE10s CPUUSE1s"); +#endif /* LOSCFG_KERNEL_CPUP */ + } else { +#ifdef LOSCFG_KERNEL_CPUP + SHOW(" CPUUSE10s"); +#endif /* LOSCFG_KERNEL_CPUP */ + } + SHOW(" PName\n"); +} + +STATIC VOID ProcessDataShow(const ProcessInfo *processInfo, VOID *seqBuf, UINT16 flag) +{ + SHOW("%5u%6u%5d%6d%7s%8s%7s%9u%5u%7u", processInfo->pid, processInfo->ppid, processInfo->pgroupID, + processInfo->userID, ConvertProcessModeToString(processInfo->mode), + ConvertProcessStatusToString(processInfo->status), + ConvertSchedPolicyToString(processInfo->policy), processInfo->basePrio, + processInfo->threadGroupID, processInfo->threadNumber); + + if (flag & OS_PROCESS_INFO_ALL) { +#ifdef LOSCFG_KERNEL_VM + if (flag & OS_PROCESS_MEM_INFO) { + SHOW("%#11x%#9x%#12x", processInfo->virtualMem, processInfo->shareMem, processInfo->physicalMem); + } +#endif +#ifdef LOSCFG_KERNEL_CPUP + SHOW("%4u.%-2u%7u.%-2u%6u.%-2u ", + processInfo->cpupAllsUsage / CPUP_MULT, processInfo->cpupAllsUsage % CPUP_MULT, + processInfo->cpup10sUsage / CPUP_MULT, processInfo->cpup10sUsage % CPUP_MULT, + processInfo->cpup1sUsage / CPUP_MULT, processInfo->cpup1sUsage % CPUP_MULT); +#endif /* LOSCFG_KERNEL_CPUP */ + } else { +#ifdef LOSCFG_KERNEL_CPUP + SHOW("%7u.%-2u ", processInfo->cpup10sUsage / CPUP_MULT, processInfo->cpup10sUsage % CPUP_MULT); +#endif /* LOSCFG_KERNEL_CPUP */ + } + SHOW("%-32s\n", processInfo->name); +} + +STATIC VOID AllProcessDataShow(const ProcessInfo *pcbArray, VOID *seqBuf, UINT16 flag) +{ + for (UINT32 pid = 1; pid < g_processMaxNum; ++pid) { + const ProcessInfo *processInfo = pcbArray + pid; + if (processInfo->status & OS_PROCESS_FLAG_UNUSED) { + continue; + } + ProcessDataShow(processInfo, seqBuf, flag); + } +} + +STATIC VOID ProcessInfoShow(const ProcessInfo *pcbArray, VOID *seqBuf, UINT16 flag) +{ +#ifdef LOSCFG_KERNEL_CPUP + UINT32 pid = OS_KERNEL_IDLE_PROCESS_ID; + UINT32 sysUsage = LOS_CPUP_PRECISION - pcbArray[pid].cpup10sUsage; + SHOW("\n allCpu(%%): %4u.%02u sys, %4u.%02u idle\n", sysUsage / CPUP_MULT, sysUsage % CPUP_MULT, + pcbArray[pid].cpup10sUsage / CPUP_MULT, pcbArray[pid].cpup10sUsage % CPUP_MULT); +#endif + + ProcessInfoTitle(seqBuf, flag); + AllProcessDataShow(pcbArray, seqBuf, flag); +} + +STATIC UINT8 *ConvertTaskStatusToString(UINT16 taskStatus) +{ + if (taskStatus & OS_TASK_STATUS_INIT) { + return (UINT8 *)"Init"; + } else if (taskStatus & OS_TASK_STATUS_RUNNING) { + return (UINT8 *)"Running"; + } else if (taskStatus & OS_TASK_STATUS_READY) { + return (UINT8 *)"Ready"; + } else if (taskStatus & OS_TASK_STATUS_FROZEN) { + return (UINT8 *)"Frozen"; + } else if (taskStatus & OS_TASK_STATUS_SUSPENDED) { + return (UINT8 *)"Suspended"; + } else if (taskStatus & OS_TASK_STATUS_DELAY) { + return (UINT8 *)"Delay"; + } else if (taskStatus & OS_TASK_STATUS_PEND_TIME) { + return (UINT8 *)"PendTime"; + } else if (taskStatus & OS_TASK_STATUS_PENDING) { + return (UINT8 *)"Pending"; + } else if (taskStatus & OS_TASK_STATUS_EXIT) { + return (UINT8 *)"Exit"; + } + + return (UINT8 *)"Invalid"; +} + +#ifdef LOSCFG_SHELL_CMD_DEBUG +#define OS_PEND_REASON_MAX_LEN 20 + +STATIC CHAR *CheckTaskWaitFlag(const TaskInfo *taskInfo, UINTPTR *lockID) +{ + *lockID = taskInfo->waitID; + switch (taskInfo->waitFlag) { + case OS_TASK_WAIT_PROCESS: + return "Child"; + case OS_TASK_WAIT_GID: + return "PGroup"; + case OS_TASK_WAIT_ANYPROCESS: + return "AnyChild"; + case OS_TASK_WAIT_SEM: + return "Semaphore"; + case OS_TASK_WAIT_QUEUE: + return "Queue"; + case OS_TASK_WAIT_JOIN: + return "Join"; + case OS_TASK_WAIT_SIGNAL: + return "Signal"; + case OS_TASK_WAIT_LITEIPC: + return "LiteIPC"; + case OS_TASK_WAIT_MUTEX: + return "Mutex"; + case OS_TASK_WAIT_EVENT: + return "Event"; + case OS_TASK_WAIT_FUTEX: + return "Futex"; + case OS_TASK_WAIT_COMPLETE: + return "Complete"; + default: + break; + } + + return NULL; +} + +STATIC VOID TaskPendingReasonInfoGet(const TaskInfo *taskInfo, CHAR *pendReason, UINT32 maxLen, UINTPTR *lockID) +{ + CHAR *reason = NULL; + + if (!(taskInfo->status & OS_TASK_STATUS_PENDING)) { + reason = (CHAR *)ConvertTaskStatusToString(taskInfo->status); + goto EXIT; + } + + reason = CheckTaskWaitFlag(taskInfo, lockID); + if (reason == NULL) { + reason = "Others"; + } + + if (taskInfo->taskMux != NULL) { + *lockID = (UINTPTR)taskInfo->taskMux; + LosTaskCB *owner = ((LosMux *)taskInfo->taskMux)->owner; + if (owner != NULL) { + if (snprintf_s(pendReason, maxLen, maxLen - 1, "Mutex-%u", owner->taskID) == EOK) { + return; + } + } + } + +EXIT: + if (strcpy_s(pendReason, maxLen, reason) != EOK) { + PRINT_ERR("Get pend reason copy failed !\n"); + } +} +#endif + +STATIC VOID TaskInfoTitle(VOID *seqBuf, UINT16 flag) +{ + SHOW("\r\n TID PID"); +#ifdef LOSCFG_KERNEL_SMP + SHOW(" Affi CPU"); +#endif + SHOW(" Status Policy Priority StackSize WaterLine"); + if (flag & OS_PROCESS_INFO_ALL) { +#ifdef LOSCFG_KERNEL_CPUP + SHOW(" CPUUSE CPUUSE10s CPUUSE1s"); +#endif /* LOSCFG_KERNEL_CPUP */ +#ifdef LOSCFG_SHELL_CMD_DEBUG + SHOW(" StackPoint TopOfStack PendReason LockID"); +#endif + } else { +#ifdef LOSCFG_KERNEL_CPUP + SHOW(" CPUUSE10s "); +#endif /* LOSCFG_KERNEL_CPUP */ + } + SHOW(" TaskName\n"); +} + +STATIC VOID TaskInfoDataShow(const TaskInfo *taskInfo, VOID *seqBuf, UINT16 flag) +{ +#ifdef LOSCFG_SHELL_CMD_DEBUG + UINTPTR lockID = 0; + CHAR pendReason[OS_PEND_REASON_MAX_LEN] = { 0 }; +#endif + SHOW(" %4u%5u", taskInfo->tid, taskInfo->pid); + +#ifdef LOSCFG_KERNEL_SMP + SHOW("%#5x%4d ", taskInfo->cpuAffiMask, (INT16)(taskInfo->currCpu)); +#endif + SHOW("%9s%7s%9u%#10x%#10x", ConvertTaskStatusToString(taskInfo->status), + ConvertSchedPolicyToString(taskInfo->policy), taskInfo->priority, taskInfo->stackSize, taskInfo->waterLine); + if (flag & OS_PROCESS_INFO_ALL) { +#ifdef LOSCFG_KERNEL_CPUP + SHOW("%4u.%-2u%7u.%-2u%6u.%-2u ", taskInfo->cpupAllsUsage / CPUP_MULT, taskInfo->cpupAllsUsage % CPUP_MULT, + taskInfo->cpup10sUsage / CPUP_MULT, taskInfo->cpup10sUsage % CPUP_MULT, + taskInfo->cpup1sUsage / CPUP_MULT, taskInfo->cpup1sUsage % CPUP_MULT); +#endif /* LOSCFG_KERNEL_CPUP */ +#ifdef LOSCFG_SHELL_CMD_DEBUG + TaskPendingReasonInfoGet(taskInfo, pendReason, OS_PEND_REASON_MAX_LEN, &lockID); + SHOW("%#12x%#12x%11s%#11x", taskInfo->stackPoint, taskInfo->topOfStack, pendReason, lockID); +#endif + } else { +#ifdef LOSCFG_KERNEL_CPUP + SHOW("%8u.%-2u ", taskInfo->cpup10sUsage / CPUP_MULT, taskInfo->cpup10sUsage % CPUP_MULT); +#endif /* LOSCFG_KERNEL_CPUP */ + } + SHOW(" %-32s\n", taskInfo->name); +} + +STATIC VOID ProcessTaskInfoDataShow(const ProcessThreadInfo *allTaskInfo, VOID *seqBuf, UINT16 flag) +{ + for (UINT32 index = 0; index < allTaskInfo->threadCount; index++) { + const TaskInfo *taskInfo = &allTaskInfo->taskInfo[index]; + TaskInfoDataShow(taskInfo, seqBuf, flag); + } +} + +STATIC VOID TaskInfoData(const ProcessThreadInfo *allTaskInfo, VOID *seqBuf, UINT16 flag) +{ + ProcessInfoTitle(seqBuf, flag); + ProcessDataShow(&allTaskInfo->processInfo, seqBuf, flag); + TaskInfoTitle(seqBuf, flag); + ProcessTaskInfoDataShow(allTaskInfo, seqBuf, flag); +} + +LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdTskInfoGet(UINT32 processID, VOID *seqBuf, UINT16 flag) +{ + UINT32 size; + + if (processID == OS_ALL_TASK_MASK) { + size = sizeof(ProcessInfo) * g_processMaxNum; + ProcessInfo *pcbArray = (ProcessInfo *)LOS_MemAlloc(m_aucSysMem1, size); + if (pcbArray == NULL) { + PRINT_ERR("Memory is not enough to save task info!\n"); + return LOS_NOK; + } + (VOID)memset_s(pcbArray, size, 0, size); + OsGetAllProcessInfo(pcbArray); + ProcessInfoShow((const ProcessInfo *)pcbArray, seqBuf, flag); + (VOID)LOS_MemFree(m_aucSysMem1, pcbArray); + return LOS_OK; + } + + ProcessThreadInfo *threadInfo = (ProcessThreadInfo *)LOS_MemAlloc(m_aucSysMem1, sizeof(ProcessThreadInfo)); + if (threadInfo == NULL) { + return LOS_NOK; + } + (VOID)memset_s(threadInfo, sizeof(ProcessThreadInfo), 0, sizeof(ProcessThreadInfo)); + + if (OsGetProcessThreadInfo(processID, threadInfo) != LOS_OK) { + return LOS_NOK; + } + + TaskInfoData(threadInfo, seqBuf, flag); + (VOID)LOS_MemFree(m_aucSysMem1, threadInfo); + return LOS_OK; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdDumpTask(INT32 argc, const CHAR **argv) +{ + INT32 processID = OS_ALL_TASK_MASK; + UINT32 flag = 0; +#ifdef LOSCFG_KERNEL_VM + flag |= OS_PROCESS_MEM_INFO; +#endif + + if (argc == 0) { + return OsShellCmdTskInfoGet((UINT32)processID, NULL, flag); + } + + if (argc >= 3) { /* 3: The task shell name restricts the parameters */ + goto TASK_HELP; + } + + if ((argc == 1) && (strcmp("-a", argv[0]) == 0)) { + flag |= OS_PROCESS_INFO_ALL; + } else if ((argc == 2) && (strcmp("-p", argv[0]) == 0)) { /* 2: Two parameters */ + flag |= OS_PROCESS_INFO_ALL; + processID = atoi(argv[1]); +#ifdef LOSCFG_SCHED_DEBUG +#ifdef LOSCFG_SCHED_TICK_DEBUG + } else if (strcmp("-i", argv[0]) == 0) { + if (!OsShellShowTickResponse()) { + return LOS_OK; + } + goto TASK_HELP; +#endif +#ifdef LOSCFG_SCHED_HPF_DEBUG + } else if (strcmp("-t", argv[0]) == 0) { + if (!OsShellShowSchedStatistics()) { + return LOS_OK; + } + goto TASK_HELP; +#endif +#ifdef LOSCFG_SCHED_EDF_DEBUG + } else if (strcmp("-e", argv[0]) == 0) { + if (!OsShellShowEdfSchedStatistics()) { + return LOS_OK; + } + goto TASK_HELP; +#endif +#endif + } else { + goto TASK_HELP; + } + + return OsShellCmdTskInfoGet((UINT32)processID, NULL, flag); + +TASK_HELP: + PRINTK("Unknown option: %s\n", argv[0]); + PRINTK("Usage:\n"); + PRINTK(" task --- Basic information about all created processes.\n"); + PRINTK(" task -a --- Complete information about all created processes.\n"); + PRINTK(" task -p [pid] --- Complete information about specifies processes and its task.\n"); + return LOS_NOK; +} + +#ifdef LOSCFG_SHELL +SHELLCMD_ENTRY(task_shellcmd, CMD_TYPE_EX, "task", 1, (CmdCallBackFunc)OsShellCmdDumpTask); +#endif + diff --git a/src/kernel_liteos_a/kernel/base/misc/vm_shellcmd.c b/src/kernel_liteos_a/kernel/base/misc/vm_shellcmd.c new file mode 100644 index 00000000..445014b3 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/misc/vm_shellcmd.c @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "stdlib.h" +#include "stdio.h" +#include "ctype.h" +#include "los_printf.h" +#include "string.h" +#include "securec.h" +#ifdef LOSCFG_SHELL +#include "shcmd.h" +#include "shell.h" +#endif +#include "los_oom.h" +#include "los_vm_dump.h" +#include "los_process_pri.h" +#ifdef LOSCFG_FS_VFS +#include "path_cache.h" +#endif + +#ifdef LOSCFG_KERNEL_VM + +#define ARGC_2 2 +#define ARGC_1 1 +#define ARGC_0 0 +#define VMM_CMD "vmm" +#define OOM_CMD "oom" +#define VMM_PMM_CMD "v2p" + +LITE_OS_SEC_TEXT_MINOR VOID OsDumpKernelAspace(VOID) +{ + LosVmSpace *kAspace = LOS_GetKVmSpace(); + if (kAspace != NULL) { + OsDumpAspace(kAspace); + } else { + VM_ERR("kernel aspace is NULL"); + } + return; +} + +LITE_OS_SEC_TEXT_MINOR INT32 OsPid(const CHAR *str) +{ + UINT32 len = strlen(str); + if (len <= 2) { // pid range is 0~63, max pid string length is 2 + for (UINT32 i = 0; i < len; i++) { + if (isdigit(str[i]) == 0) { + return -1; + } + } + return atoi(str); + } + return -1; +} + +LITE_OS_SEC_TEXT_MINOR VOID OsPrintUsage(VOID) +{ + PRINTK("-a, print all vm address space information\n" + "-k, print the kernel vm address space information\n" + "pid(0~63), print process[pid] vm address space information\n" + "-h | --help, print vmm command usage\n"); +} + +LITE_OS_SEC_TEXT_MINOR VOID OsDoDumpVm(pid_t pid) +{ + LosProcessCB *processCB = NULL; + + if (OsProcessIDUserCheckInvalid(pid)) { + PRINTK("\tThe process [%d] not valid\n", pid); + return; + } + + processCB = OS_PCB_FROM_PID(pid); + if (!OsProcessIsUnused(processCB) && (processCB->vmSpace != NULL)) { + OsDumpAspace(processCB->vmSpace); + } else { + PRINTK("\tThe process [%d] not active\n", pid); + } +} + +LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdDumpVm(INT32 argc, const CHAR *argv[]) +{ + if (argc == 0) { + OsDumpAllAspace(); + } else if (argc == 1) { + pid_t pid = OsPid(argv[0]); + if (strcmp(argv[0], "-a") == 0) { + OsDumpAllAspace(); + } else if (strcmp(argv[0], "-k") == 0) { + OsDumpKernelAspace(); + } else if (pid >= 0) { + OsDoDumpVm(pid); + } else if (strcmp(argv[0], "-h") == 0 || strcmp(argv[0], "--help") == 0) { + OsPrintUsage(); + } else { + PRINTK("%s: invalid option: %s\n", VMM_CMD, argv[0]); + OsPrintUsage(); + } + } else { + OsPrintUsage(); + } + + return OS_ERROR; +} + +LITE_OS_SEC_TEXT_MINOR VOID V2PPrintUsage(VOID) +{ + PRINTK("pid vaddr(0x1000000~0x3e000000), print physical address of virtual address\n" + "-h | --help, print v2p command usage\n"); +} + +LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdV2P(INT32 argc, const CHAR *argv[]) +{ + UINT32 vaddr; + PADDR_T paddr; + CHAR *endPtr = NULL; + + if (argc == 0) { + V2PPrintUsage(); + } else if (argc == 1) { + if (strcmp(argv[0], "-h") == 0 || strcmp(argv[0], "--help") == 0) { + V2PPrintUsage(); + } + } else if (argc == 2) { + pid_t pid = OsPid(argv[0]); + vaddr = strtoul((CHAR *)argv[1], &endPtr, 0); + if ((endPtr == NULL) || (*endPtr != 0) || !LOS_IsUserAddress(vaddr)) { + PRINTK("vaddr %s invalid. should be in range(0x1000000~0x3e000000) \n", argv[1]); + return OS_ERROR; + } else { + if (pid >= 0) { + if (pid < g_taskMaxNum) { + LosProcessCB *processCB = OS_PCB_FROM_PID(pid); + if (!OsProcessIsUnused(processCB)) { + paddr = 0; + LOS_ArchMmuQuery(&processCB->vmSpace->archMmu, (VADDR_T)vaddr, &paddr, 0); + if (paddr == 0) { + PRINTK("vaddr %#x is not in range or mapped\n", vaddr); + } else { + PRINTK("vaddr %#x is paddr %#x\n", vaddr, paddr); + } + } else { + PRINTK("\tThe process [%d] not active\n", pid); + } + } else { + PRINTK("\tThe process [%d] not valid\n", pid); + } + } else { + PRINTK("%s: invalid option: %s %s\n", VMM_PMM_CMD, argv[0], argv[1]); + } + } + } + + return LOS_OK; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdDumpPmm(VOID) +{ + OsVmPhysDump(); + + PathCacheMemoryDump(); + VnodeMemoryDump(); + return OS_ERROR; +} + +LITE_OS_SEC_TEXT_MINOR VOID OomPrintUsage(VOID) +{ + PRINTK("\t-i [interval], set oom check interval (ms)\n" + "\t-m [mem byte], set oom low memory threshold (Byte)\n" + "\t-r [mem byte], set page cache reclaim memory threshold (Byte)\n" + "\t-h | --help, print vmm command usage\n"); +} + +LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdOom(INT32 argc, const CHAR *argv[]) +{ + UINT32 lowMemThreshold; + UINT32 reclaimMemThreshold; + UINT32 checkInterval; + CHAR *endPtr = NULL; + + if (argc == ARGC_0) { + OomInfodump(); + } else if (argc == ARGC_1) { + if (strcmp(argv[0], "-h") != 0 && strcmp(argv[0], "--help") != 0) { + PRINTK("%s: invalid option: %s\n", OOM_CMD, argv[0]); + } + OomPrintUsage(); + } else if (argc == ARGC_2) { + if (strcmp(argv[0], "-m") == 0) { + lowMemThreshold = strtoul((CHAR *)argv[1], &endPtr, 0); + if ((endPtr == NULL) || (*endPtr != 0)) { + PRINTK("[oom] low mem threshold %s(byte) invalid.\n", argv[1]); + return OS_ERROR; + } else { + OomSetLowMemThreashold(lowMemThreshold); + } + } else if (strcmp(argv[0], "-i") == 0) { + checkInterval = strtoul((CHAR *)argv[1], &endPtr, 0); + if ((endPtr == NULL) || (*endPtr != 0)) { + PRINTK("[oom] check interval %s(us) invalid.\n", argv[1]); + return OS_ERROR; + } else { + OomSetCheckInterval(checkInterval); + } + } else if (strcmp(argv[0], "-r") == 0) { + reclaimMemThreshold = strtoul((CHAR *)argv[1], &endPtr, 0); + if ((endPtr == NULL) || (*endPtr != 0)) { + PRINTK("[oom] reclaim mem threshold %s(byte) invalid.\n", argv[1]); + return OS_ERROR; + } else { + OomSetReclaimMemThreashold(reclaimMemThreshold); + } + } else { + PRINTK("%s: invalid option: %s %s\n", OOM_CMD, argv[0], argv[1]); + OomPrintUsage(); + } + } else { + PRINTK("%s: invalid option\n", OOM_CMD); + OomPrintUsage(); + } + + return OS_ERROR; +} + +#ifdef LOSCFG_SHELL_CMD_DEBUG +SHELLCMD_ENTRY(oom_shellcmd, CMD_TYPE_SHOW, OOM_CMD, 2, (CmdCallBackFunc)OsShellCmdOom); +SHELLCMD_ENTRY(vm_shellcmd, CMD_TYPE_SHOW, VMM_CMD, 1, (CmdCallBackFunc)OsShellCmdDumpVm); +SHELLCMD_ENTRY(v2p_shellcmd, CMD_TYPE_SHOW, VMM_PMM_CMD, 1, (CmdCallBackFunc)OsShellCmdV2P); +#endif + +#ifdef LOSCFG_SHELL +SHELLCMD_ENTRY(pmm_shellcmd, CMD_TYPE_SHOW, "pmm", 0, (CmdCallBackFunc)OsShellCmdDumpPmm); +#endif +#endif + diff --git a/src/kernel_liteos_a/kernel/base/mp/los_lockdep.c b/src/kernel_liteos_a/kernel/base/mp/los_lockdep.c new file mode 100644 index 00000000..fb093591 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/mp/los_lockdep.c @@ -0,0 +1,366 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_base.h" +#include "los_spinlock.h" +#include "los_task_pri.h" +#include "los_printf_pri.h" +#include "los_atomic.h" +#include "los_exc.h" + +#ifdef LOSCFG_KERNEL_SMP_LOCKDEP + +#define PRINT_BUF_SIZE 256 + +#define LOCKDEP_GET_NAME(lockDep, index) (((SPIN_LOCK_S *)((lockDep)->heldLocks[(index)].lockPtr))->name) +#define LOCKDEP_GET_ADDR(lockDep, index) ((lockDep)->heldLocks[(index)].lockAddr) + +STATIC Atomic g_lockdepAvailable = 1; + +/* atomic insurance for lockdep check */ +STATIC INLINE VOID OsLockDepRequire(UINT32 *intSave) +{ + *intSave = LOS_IntLock(); + while (LOS_AtomicCmpXchg32bits(&g_lockdepAvailable, 0, 1)) { + /* busy waiting */ + } +} + +STATIC INLINE VOID OsLockDepRelease(UINT32 intSave) +{ + LOS_AtomicSet(&g_lockdepAvailable, 1); + LOS_IntRestore(intSave); +} + +STATIC INLINE UINT64 OsLockDepGetCycles(VOID) +{ + UINT32 high, low; + + LOS_GetCpuCycle(&high, &low); + /* combine cycleHi and cycleLo into 8 bytes cycles */ + return (((UINT64)high << 32) + low); // 32 bits for lower half of UINT64 +} + +STATIC INLINE CHAR *OsLockDepErrorStringGet(enum LockDepErrType type) +{ + CHAR *errorString = NULL; + + switch (type) { + case LOCKDEP_ERR_DOUBLE_LOCK: + errorString = "double lock"; + break; + case LOCKDEP_ERR_DEAD_LOCK: + errorString = "dead lock"; + break; + case LOCKDEP_ERR_UNLOCK_WITOUT_LOCK: + errorString = "unlock without lock"; + break; + case LOCKDEP_ERR_OVERFLOW: + errorString = "lockdep overflow"; + break; + default: + errorString = "unknown error code"; + break; + } + + return errorString; +} + +WEAK VOID OsLockDepPanic(enum LockDepErrType errType) +{ + /* halt here */ + (VOID)errType; + (VOID)LOS_IntLock(); + OsBackTrace(); + while (1) {} +} + +STATIC VOID OsLockDepPrint(const CHAR *fmt, va_list ap) +{ + UINT32 len; + CHAR buf[PRINT_BUF_SIZE] = {0}; + + len = vsnprintf_s(buf, PRINT_BUF_SIZE, PRINT_BUF_SIZE - 1, fmt, ap); + if ((len == -1) && (*buf == '\0')) { + /* parameter is illegal or some features in fmt dont support */ + UartPuts("OsLockDepPrint is error\n", strlen("OsLockDepPrint is error\n"), 0); + return; + } + *(buf + len) = '\0'; + + UartPuts(buf, len, 0); +} + +STATIC VOID OsPrintLockDepInfo(const CHAR *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + OsLockDepPrint(fmt, ap); + va_end(ap); +} + +STATIC VOID OsLockDepDumpLock(const LosTaskCB *task, const SPIN_LOCK_S *lock, + const VOID *requestAddr, enum LockDepErrType errType) +{ + INT32 i; + const LockDep *lockDep = &task->lockDep; + const LosTaskCB *temp = task; + + OsPrintLockDepInfo("lockdep check failed\n"); + OsPrintLockDepInfo("error type : %s\n", OsLockDepErrorStringGet(errType)); + OsPrintLockDepInfo("request addr : 0x%x\n", requestAddr); + + while (1) { + OsPrintLockDepInfo("task name : %s\n", temp->taskName); + OsPrintLockDepInfo("task id : %u\n", temp->taskID); + OsPrintLockDepInfo("cpu num : %u\n", temp->currCpu); + OsPrintLockDepInfo("start dumping lockdep information\n"); + for (i = 0; i < lockDep->lockDepth; i++) { + if (lockDep->heldLocks[i].lockPtr == lock) { + OsPrintLockDepInfo("[%d] %s <-- addr:0x%x\n", i, LOCKDEP_GET_NAME(lockDep, i), + LOCKDEP_GET_ADDR(lockDep, i)); + } else { + OsPrintLockDepInfo("[%d] %s \n", i, LOCKDEP_GET_NAME(lockDep, i)); + } + } + OsPrintLockDepInfo("[%d] %s <-- now\n", i, lock->name); + + if (errType == LOCKDEP_ERR_DEAD_LOCK) { + temp = lock->owner; + lock = temp->lockDep.waitLock; + lockDep = &temp->lockDep; + } + + if (temp == task) { + break; + } + } +} + +STATIC BOOL OsLockDepCheckDependency(const LosTaskCB *current, LosTaskCB *lockOwner) +{ + BOOL checkResult = TRUE; + SPIN_LOCK_S *lockTemp = NULL; + + do { + if (current == lockOwner) { + checkResult = FALSE; + return checkResult; + } + if (lockOwner->lockDep.waitLock != NULL) { + lockTemp = lockOwner->lockDep.waitLock; + lockOwner = lockTemp->owner; + } else { + break; + } + } while (lockOwner != SPINLOCK_OWNER_INIT); + + return checkResult; +} + +VOID OsLockDepCheckIn(SPIN_LOCK_S *lock) +{ + UINT32 intSave; + enum LockDepErrType checkResult = LOCKDEP_SUCCESS; + VOID *requestAddr = (VOID *)__builtin_return_address(1); + LosTaskCB *current = OsCurrTaskGet(); + LockDep *lockDep = ¤t->lockDep; + LosTaskCB *lockOwner = NULL; + + OsLockDepRequire(&intSave); + + if (lockDep->lockDepth >= (INT32)MAX_LOCK_DEPTH) { + checkResult = LOCKDEP_ERR_OVERFLOW; + goto OUT; + } + + lockOwner = lock->owner; + /* not owned by any tasks yet, not doing following checks */ + if (lockOwner == SPINLOCK_OWNER_INIT) { + goto OUT; + } + + if (current == lockOwner) { + checkResult = LOCKDEP_ERR_DOUBLE_LOCK; + goto OUT; + } + + if (OsLockDepCheckDependency(current, lockOwner) != TRUE) { + checkResult = LOCKDEP_ERR_DEAD_LOCK; + goto OUT; + } + +OUT: + if (checkResult == LOCKDEP_SUCCESS) { + /* + * though the check may succeed, the waitLock still need to be set. + * because the OsLockDepCheckIn and OsLockDepRecord is not strictly multi-core + * sequential, there would be more than two tasks can pass the checking, but + * only one task can successfully obtain the lock. + */ + lockDep->waitLock = lock; + lockDep->heldLocks[lockDep->lockDepth].lockAddr = requestAddr; + lockDep->heldLocks[lockDep->lockDepth].waitTime = OsLockDepGetCycles(); /* start time */ + OsLockDepRelease(intSave); + return; + } + OsLockDepDumpLock(current, lock, requestAddr, checkResult); + OsLockDepRelease(intSave); + OsLockDepPanic(checkResult); +} + +VOID OsLockDepRecord(SPIN_LOCK_S *lock) +{ + UINT32 intSave; + UINT64 cycles; + LosTaskCB *current = OsCurrTaskGet(); + LockDep *lockDep = ¤t->lockDep; + HeldLocks *heldlock = &lockDep->heldLocks[lockDep->lockDepth]; + + OsLockDepRequire(&intSave); + + /* + * OsLockDepCheckIn records start time t1, after the lock is obtained, we + * get the time t2, (t2 - t1) is the time of waiting for the lock + */ + cycles = OsLockDepGetCycles(); + heldlock->waitTime = cycles - heldlock->waitTime; + heldlock->holdTime = cycles; + + /* record lock info */ + lock->owner = current; + lock->cpuid = ArchCurrCpuid(); + + /* record lockdep info */ + heldlock->lockPtr = lock; + lockDep->lockDepth++; + lockDep->waitLock = NULL; + + OsLockDepRelease(intSave); +} + +VOID OsLockDepCheckOut(SPIN_LOCK_S *lock) +{ + UINT32 intSave; + INT32 depth; + enum LockDepErrType checkResult; + VOID *requestAddr = (VOID *)__builtin_return_address(1); + LosTaskCB *current = OsCurrTaskGet(); + LosTaskCB *owner = NULL; + LockDep *lockDep = NULL; + HeldLocks *heldlocks = NULL; + + OsLockDepRequire(&intSave); + + owner = lock->owner; + if (owner == SPINLOCK_OWNER_INIT) { + checkResult = LOCKDEP_ERR_UNLOCK_WITOUT_LOCK; + OsLockDepDumpLock(current, lock, requestAddr, checkResult); + OsLockDepRelease(intSave); + OsLockDepPanic(checkResult); + return; + } + + lockDep = &owner->lockDep; + heldlocks = &lockDep->heldLocks[0]; + depth = lockDep->lockDepth; + + /* find the lock position */ + while (--depth >= 0) { + if (heldlocks[depth].lockPtr == lock) { + break; + } + } + + LOS_ASSERT(depth >= 0); + + /* record lock holding time */ + heldlocks[depth].holdTime = OsLockDepGetCycles() - heldlocks[depth].holdTime; + + /* if unlock an older lock, needs move heldLock records */ + while (depth < lockDep->lockDepth - 1) { + lockDep->heldLocks[depth] = lockDep->heldLocks[depth + 1]; + depth++; + } + + lockDep->lockDepth--; + lock->cpuid = (UINT32)(-1); + lock->owner = SPINLOCK_OWNER_INIT; + + OsLockDepRelease(intSave); +} + +VOID OsLockdepClearSpinlocks(VOID) +{ + LosTaskCB *task = OsCurrTaskGet(); + LockDep *lockDep = &task->lockDep; + SPIN_LOCK_S *lock = NULL; + + /* + * Unlock spinlocks that running task has held. + * lockDepth will decrease after each spinlock is unlockded. + */ + while (lockDep->lockDepth) { + lock = lockDep->heldLocks[lockDep->lockDepth - 1].lockPtr; + LOS_SpinUnlock(lock); + } +} + +#else /* LOSCFG_KERNEL_SMP_LOCKDEP */ + +VOID OsLockDepCheckIn(SPIN_LOCK_S *lock) +{ + (VOID)lock; + + return; +} + +VOID OsLockDepRecord(SPIN_LOCK_S *lock) +{ + (VOID)lock; + + return; +} + +VOID OsLockDepCheckOut(SPIN_LOCK_S *lock) +{ + (VOID)lock; + + return; +} + +VOID OsLockdepClearSpinlocks(VOID) +{ + return; +} + +#endif + diff --git a/src/kernel_liteos_a/kernel/base/mp/los_mp.c b/src/kernel_liteos_a/kernel/base/mp/los_mp.c new file mode 100644 index 00000000..67bc7012 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/mp/los_mp.c @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_mp.h" +#include "los_init.h" +#include "los_percpu_pri.h" +#include "los_sched_pri.h" +#include "los_swtmr.h" +#include "los_task_pri.h" + +#ifdef LOSCFG_KERNEL_SMP + +#ifdef LOSCFG_KERNEL_SMP_CALL +LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_mpCallSpin); +#define MP_CALL_LOCK(state) LOS_SpinLockSave(&g_mpCallSpin, &(state)) +#define MP_CALL_UNLOCK(state) LOS_SpinUnlockRestore(&g_mpCallSpin, (state)) +#endif + +VOID LOS_MpSchedule(UINT32 target) +{ + UINT32 cpuid = ArchCurrCpuid(); + target &= ~(1U << cpuid); + HalIrqSendIpi(target, LOS_MP_IPI_SCHEDULE); +} + +VOID OsMpWakeHandler(VOID) +{ + /* generic wakeup ipi, do nothing */ +} + +VOID OsMpScheduleHandler(VOID) +{ + /* + * set schedule flag to differ from wake function, + * so that the scheduler can be triggered at the end of irq. + */ + OsSchedRunqueuePendingSet(); +} + +VOID OsMpHaltHandler(VOID) +{ + (VOID)LOS_IntLock(); + OsPercpuGet()->excFlag = CPU_HALT; + + while (1) {} +} + +VOID OsMpCollectTasks(VOID) +{ + LosTaskCB *taskCB = NULL; + UINT32 taskID = 0; + UINT32 ret; + + /* recursive checking all the available task */ + for (; taskID <= g_taskMaxNum; taskID++) { + taskCB = &g_taskCBArray[taskID]; + + if (OsTaskIsUnused(taskCB) || OsTaskIsRunning(taskCB)) { + continue; + } + + /* + * though task status is not atomic, this check may success but not accomplish + * the deletion; this deletion will be handled until the next run. + */ + if (taskCB->signal & SIGNAL_KILL) { + ret = LOS_TaskDelete(taskID); + if (ret != LOS_OK) { + PRINT_WARN("GC collect task failed err:0x%x\n", ret); + } + } + } +} + +#ifdef LOSCFG_KERNEL_SMP_CALL +VOID OsMpFuncCall(UINT32 target, SMP_FUNC_CALL func, VOID *args) +{ + UINT32 index; + UINT32 intSave; + + if (func == NULL) { + return; + } + + if (!(target & OS_MP_CPU_ALL)) { + return; + } + + for (index = 0; index < LOSCFG_KERNEL_CORE_NUM; index++) { + if (CPUID_TO_AFFI_MASK(index) & target) { + MpCallFunc *mpCallFunc = (MpCallFunc *)LOS_MemAlloc(m_aucSysMem0, sizeof(MpCallFunc)); + if (mpCallFunc == NULL) { + PRINT_ERR("smp func call malloc failed\n"); + return; + } + mpCallFunc->func = func; + mpCallFunc->args = args; + + MP_CALL_LOCK(intSave); + LOS_ListAdd(&g_percpu[index].funcLink, &(mpCallFunc->node)); + MP_CALL_UNLOCK(intSave); + } + } + HalIrqSendIpi(target, LOS_MP_IPI_FUNC_CALL); +} + +VOID OsMpFuncCallHandler(VOID) +{ + UINT32 intSave; + UINT32 cpuid = ArchCurrCpuid(); + LOS_DL_LIST *list = NULL; + MpCallFunc *mpCallFunc = NULL; + + MP_CALL_LOCK(intSave); + while (!LOS_ListEmpty(&g_percpu[cpuid].funcLink)) { + list = LOS_DL_LIST_FIRST(&g_percpu[cpuid].funcLink); + LOS_ListDelete(list); + MP_CALL_UNLOCK(intSave); + + mpCallFunc = LOS_DL_LIST_ENTRY(list, MpCallFunc, node); + mpCallFunc->func(mpCallFunc->args); + (VOID)LOS_MemFree(m_aucSysMem0, mpCallFunc); + + MP_CALL_LOCK(intSave); + } + MP_CALL_UNLOCK(intSave); +} + +VOID OsMpFuncCallInit(VOID) +{ + UINT32 index; + /* init funclink for each core */ + for (index = 0; index < LOSCFG_KERNEL_CORE_NUM; index++) { + LOS_ListInit(&g_percpu[index].funcLink); + } +} +#endif /* LOSCFG_KERNEL_SMP_CALL */ + +UINT32 OsMpInit(VOID) +{ + UINT16 swtmrId; + + (VOID)LOS_SwtmrCreate(OS_MP_GC_PERIOD, LOS_SWTMR_MODE_PERIOD, + (SWTMR_PROC_FUNC)OsMpCollectTasks, &swtmrId, 0); + (VOID)LOS_SwtmrStart(swtmrId); +#ifdef LOSCFG_KERNEL_SMP_CALL + OsMpFuncCallInit(); +#endif + return LOS_OK; +} + +LOS_MODULE_INIT(OsMpInit, LOS_INIT_LEVEL_KMOD_TASK); + +#endif + diff --git a/src/kernel_liteos_a/kernel/base/mp/los_percpu.c b/src/kernel_liteos_a/kernel/base/mp/los_percpu.c new file mode 100644 index 00000000..4d883916 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/mp/los_percpu.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_percpu_pri.h" +#include "los_printf.h" + +#ifdef LOSCFG_KERNEL_SMP +Percpu g_percpu[LOSCFG_KERNEL_CORE_NUM]; + +VOID OsAllCpuStatusOutput(VOID) +{ + UINT32 i; + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + switch (g_percpu[i].excFlag) { + case CPU_RUNNING: + PrintExcInfo("cpu%u is running.\n", i); + break; + case CPU_HALT: + PrintExcInfo("cpu%u is halted.\n", i); + break; + case CPU_EXC: + PrintExcInfo("cpu%u is in exc.\n", i); + break; + default: + break; + } + } + PrintExcInfo("The current handling the exception is cpu%u !\n", ArchCurrCpuid()); +} +#endif diff --git a/src/kernel_liteos_a/kernel/base/mp/los_spinlock.c b/src/kernel_liteos_a/kernel/base/mp/los_spinlock.c new file mode 100644 index 00000000..63d7fb50 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/mp/los_spinlock.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_spinlock.h" +#ifdef LOSCFG_KERNEL_SMP +#include "los_sched_pri.h" + + +VOID LOS_SpinInit(SPIN_LOCK_S *lock) +{ + lock->rawLock = 0; + lock->cpuid = (UINT32)-1; + lock->owner = SPINLOCK_OWNER_INIT; + lock->name = "spinlock"; +} + +BOOL LOS_SpinHeld(const SPIN_LOCK_S *lock) +{ + return (lock->rawLock != 0); +} + +VOID LOS_SpinLock(SPIN_LOCK_S *lock) +{ + UINT32 intSave = LOS_IntLock(); + OsSchedLock(); + LOS_IntRestore(intSave); + + LOCKDEP_CHECK_IN(lock); + ArchSpinLock(&lock->rawLock); + LOCKDEP_RECORD(lock); +} + +INT32 LOS_SpinTrylock(SPIN_LOCK_S *lock) +{ + UINT32 intSave = LOS_IntLock(); + OsSchedLock(); + LOS_IntRestore(intSave); + + INT32 ret = ArchSpinTrylock(&lock->rawLock); + if (ret == LOS_OK) { + LOCKDEP_CHECK_IN(lock); + LOCKDEP_RECORD(lock); + return ret; + } + + intSave = LOS_IntLock(); + BOOL needSched = OsSchedUnlockResch(); + LOS_IntRestore(intSave); + if (needSched) { + LOS_Schedule(); + } + + return ret; +} + +VOID LOS_SpinUnlock(SPIN_LOCK_S *lock) +{ + UINT32 intSave; + LOCKDEP_CHECK_OUT(lock); + ArchSpinUnlock(&lock->rawLock); + + intSave = LOS_IntLock(); + BOOL needSched = OsSchedUnlockResch(); + LOS_IntRestore(intSave); + if (needSched) { + LOS_Schedule(); + } +} + +VOID LOS_SpinLockSave(SPIN_LOCK_S *lock, UINT32 *intSave) +{ + *intSave = LOS_IntLock(); + OsSchedLock(); + + LOCKDEP_CHECK_IN(lock); + ArchSpinLock(&lock->rawLock); + LOCKDEP_RECORD(lock); +} + +VOID LOS_SpinUnlockRestore(SPIN_LOCK_S *lock, UINT32 intSave) +{ + LOCKDEP_CHECK_OUT(lock); + ArchSpinUnlock(&lock->rawLock); + + BOOL needSched = OsSchedUnlockResch(); + LOS_IntRestore(intSave); + if (needSched) { + LOS_Schedule(); + } +} +#endif + diff --git a/src/kernel_liteos_a/kernel/base/om/los_err.c b/src/kernel_liteos_a/kernel/base/om/los_err.c new file mode 100644 index 00000000..6267a9d1 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/om/los_err.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_err.h" + + +LITE_OS_SEC_BSS STATIC LOS_ERRORHANDLE_FUNC g_errHandleHook = NULL; + +LITE_OS_SEC_TEXT_INIT UINT32 LOS_ErrHandle(CHAR *fileName, UINT32 lineNo, UINT32 errorNo, + UINT32 paraLen, VOID *para) +{ + if (g_errHandleHook != NULL) { + g_errHandleHook(fileName, lineNo, errorNo, paraLen, para); + } + + return LOS_OK; +} + +LITE_OS_SEC_TEXT_INIT VOID LOS_SetErrHandleHook(LOS_ERRORHANDLE_FUNC fun) +{ + g_errHandleHook = fun; +} + diff --git a/src/kernel_liteos_a/kernel/base/sched/los_deadline.c b/src/kernel_liteos_a/kernel/base/sched/los_deadline.c new file mode 100644 index 00000000..ed6d0c20 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/sched/los_deadline.c @@ -0,0 +1,403 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_sched_pri.h" +#include "los_task_pri.h" +#include "los_process_pri.h" +#include "los_hook.h" +#include "los_tick_pri.h" +#include "los_sys_pri.h" + +STATIC EDFRunqueue g_schedEDF; + +STATIC VOID EDFDequeue(SchedRunqueue *rq, LosTaskCB *taskCB); +STATIC VOID EDFEnqueue(SchedRunqueue *rq, LosTaskCB *taskCB); +STATIC UINT64 EDFWaitTimeGet(LosTaskCB *taskCB); +STATIC UINT32 EDFWait(LosTaskCB *runTask, LOS_DL_LIST *list, UINT32 ticks); +STATIC VOID EDFWake(LosTaskCB *resumedTask); +STATIC BOOL EDFSchedParamModify(LosTaskCB *taskCB, const SchedParam *param); +STATIC UINT32 EDFSchedParamGet(const LosTaskCB *taskCB, SchedParam *param); +STATIC UINT32 EDFDelay(LosTaskCB *runTask, UINT64 waitTime); +STATIC VOID EDFYield(LosTaskCB *runTask); +STATIC VOID EDFExit(LosTaskCB *taskCB); +STATIC UINT32 EDFSuspend(LosTaskCB *taskCB); +STATIC UINT32 EDFResume(LosTaskCB *taskCB, BOOL *needSched); +STATIC UINT64 EDFTimeSliceGet(const LosTaskCB *taskCB); +STATIC VOID EDFTimeSliceUpdate(SchedRunqueue *rq, LosTaskCB *taskCB, UINT64 currTime); +STATIC INT32 EDFParamCompare(const SchedPolicy *sp1, const SchedPolicy *sp2); +STATIC VOID EDFPriorityInheritance(LosTaskCB *owner, const SchedParam *param); +STATIC VOID EDFPriorityRestore(LosTaskCB *owner, const LOS_DL_LIST *list, const SchedParam *param); + +const STATIC SchedOps g_deadlineOps = { + .dequeue = EDFDequeue, + .enqueue = EDFEnqueue, + .waitTimeGet = EDFWaitTimeGet, + .wait = EDFWait, + .wake = EDFWake, + .schedParamModify = EDFSchedParamModify, + .schedParamGet = EDFSchedParamGet, + .delay = EDFDelay, + .yield = EDFYield, + .start = EDFDequeue, + .exit = EDFExit, + .suspend = EDFSuspend, + .resume = EDFResume, + .deadlineGet = EDFTimeSliceGet, + .timeSliceUpdate = EDFTimeSliceUpdate, + .schedParamCompare = EDFParamCompare, + .priorityInheritance = EDFPriorityInheritance, + .priorityRestore = EDFPriorityRestore, +}; + +STATIC VOID EDFTimeSliceUpdate(SchedRunqueue *rq, LosTaskCB *taskCB, UINT64 currTime) +{ + SchedEDF *sched = (SchedEDF *)&taskCB->sp; + + LOS_ASSERT(currTime >= taskCB->startTime); + + if (taskCB->timeSlice <= 0) { + taskCB->irqUsedTime = 0; + return; + } + + INT32 incTime = (currTime - taskCB->startTime - taskCB->irqUsedTime); + LOS_ASSERT(incTime >= 0); + +#ifdef LOSCFG_SCHED_EDF_DEBUG + taskCB->schedStat.timeSliceRealTime += incTime; + taskCB->schedStat.allRuntime += (currTime - taskCB->startTime); +#endif + + taskCB->timeSlice -= incTime; + taskCB->irqUsedTime = 0; + taskCB->startTime = currTime; + + if ((sched->finishTime > currTime) && (taskCB->timeSlice > 0)) { + return; + } + + rq->schedFlag |= INT_PEND_RESCH; + if (sched->finishTime <= currTime) { +#ifdef LOSCFG_SCHED_EDF_DEBUG + EDFDebugRecord((UINTPTR *)taskCB, sched->finishTime); +#endif + + taskCB->timeSlice = 0; + PrintExcInfo("EDF task %u is timeout, runTime: %d us period: %llu us\n", taskCB->taskID, + (INT32)OS_SYS_CYCLE_TO_US((UINT64)sched->runTime), OS_SYS_CYCLE_TO_US(sched->period)); + } +} + +STATIC UINT64 EDFTimeSliceGet(const LosTaskCB *taskCB) +{ + SchedEDF *sched = (SchedEDF *)&taskCB->sp; + UINT64 endTime = taskCB->startTime + taskCB->timeSlice; + return (endTime > sched->finishTime) ? sched->finishTime : endTime; +} + +STATIC VOID DeadlineQueueInsert(EDFRunqueue *rq, LosTaskCB *taskCB) +{ + LOS_DL_LIST *root = &rq->root; + if (LOS_ListEmpty(root)) { + LOS_ListTailInsert(root, &taskCB->pendList); + return; + } + + LOS_DL_LIST *list = root->pstNext; + do { + LosTaskCB *readyTask = LOS_DL_LIST_ENTRY(list, LosTaskCB, pendList); + if (EDFParamCompare(&readyTask->sp, &taskCB->sp) > 0) { + LOS_ListHeadInsert(list, &taskCB->pendList); + return; + } + list = list->pstNext; + } while (list != root); + + LOS_ListHeadInsert(list, &taskCB->pendList); +} + +STATIC VOID EDFEnqueue(SchedRunqueue *rq, LosTaskCB *taskCB) +{ + LOS_ASSERT(!(taskCB->taskStatus & OS_TASK_STATUS_READY)); + + EDFRunqueue *erq = rq->edfRunqueue; + SchedEDF *sched = (SchedEDF *)&taskCB->sp; + if (taskCB->timeSlice <= 0) { +#ifdef LOSCFG_SCHED_EDF_DEBUG + UINT64 oldFinish = sched->finishTime; +#endif + UINT64 currTime = OsGetCurrSchedTimeCycle(); + if (sched->flags == EDF_INIT) { + sched->finishTime = currTime; + } else if (sched->flags != EDF_NEXT_PERIOD) { + /* The start time of the next period */ + sched->finishTime = (sched->finishTime - sched->deadline) + sched->period; + } + + /* Calculate the start time of the next period */ + while (1) { + /* The deadline of the next period */ + UINT64 finishTime = sched->finishTime + sched->deadline; + if ((finishTime <= currTime) || ((sched->finishTime + sched->runTime) > finishTime)) { + /* This period cannot meet the minimum running time, so it is migrated to the next period */ + sched->finishTime += sched->period; + continue; + } + break; + } + + if (sched->finishTime > currTime) { + /* Wait for the next period to start */ + LOS_ListTailInsert(&erq->waitList, &taskCB->pendList); + taskCB->waitTime = OS_SCHED_MAX_RESPONSE_TIME; + if (!OsTaskIsRunning(taskCB)) { + OsSchedTimeoutQueueAdd(taskCB, sched->finishTime); + } +#ifdef LOSCFG_SCHED_EDF_DEBUG + if (oldFinish != sched->finishTime) { + EDFDebugRecord((UINTPTR *)taskCB, oldFinish); + taskCB->schedStat.allRuntime = 0; + taskCB->schedStat.timeSliceRealTime = 0; + taskCB->schedStat.pendTime = 0; + } +#endif + taskCB->taskStatus |= OS_TASK_STATUS_PEND_TIME; + sched->flags = EDF_NEXT_PERIOD; + return; + } + + sched->finishTime += sched->deadline; + taskCB->timeSlice = sched->runTime; + sched->flags = EDF_UNUSED; + } + + DeadlineQueueInsert(erq, taskCB); + taskCB->taskStatus &= ~(OS_TASK_STATUS_BLOCKED | OS_TASK_STATUS_TIMEOUT); + taskCB->taskStatus |= OS_TASK_STATUS_READY; +} + +STATIC VOID EDFDequeue(SchedRunqueue *rq, LosTaskCB *taskCB) +{ + (VOID)rq; + LOS_ListDelete(&taskCB->pendList); + taskCB->taskStatus &= ~OS_TASK_STATUS_READY; +} + +STATIC VOID EDFExit(LosTaskCB *taskCB) +{ + if (taskCB->taskStatus & OS_TASK_STATUS_READY) { + EDFDequeue(OsSchedRunqueue(), taskCB); + } else if (taskCB->taskStatus & OS_TASK_STATUS_PENDING) { + LOS_ListDelete(&taskCB->pendList); + taskCB->taskStatus &= ~OS_TASK_STATUS_PENDING; + } + if (taskCB->taskStatus & (OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND_TIME)) { + OsSchedTimeoutQueueDelete(taskCB); + taskCB->taskStatus &= ~(OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND_TIME); + } +} + +STATIC VOID EDFYield(LosTaskCB *runTask) +{ + SchedRunqueue *rq = OsSchedRunqueue(); + runTask->timeSlice = 0; + + runTask->startTime = OsGetCurrSchedTimeCycle(); + EDFEnqueue(rq, runTask); + OsSchedResched(); +} + +STATIC UINT32 EDFDelay(LosTaskCB *runTask, UINT64 waitTime) +{ + runTask->taskStatus |= OS_TASK_STATUS_DELAY; + runTask->waitTime = waitTime; + OsSchedResched(); + return LOS_OK; +} + +STATIC UINT64 EDFWaitTimeGet(LosTaskCB *taskCB) +{ + const SchedEDF *sched = (const SchedEDF *)&taskCB->sp; + if (sched->flags != EDF_WAIT_FOREVER) { + taskCB->waitTime += taskCB->startTime; + } + return (taskCB->waitTime >= sched->finishTime) ? sched->finishTime : taskCB->waitTime; +} + +STATIC UINT32 EDFWait(LosTaskCB *runTask, LOS_DL_LIST *list, UINT32 ticks) +{ + SchedEDF *sched = (SchedEDF *)&runTask->sp; + runTask->taskStatus |= (OS_TASK_STATUS_PENDING | OS_TASK_STATUS_PEND_TIME); + LOS_ListTailInsert(list, &runTask->pendList); + + if (ticks != LOS_WAIT_FOREVER) { + runTask->waitTime = OS_SCHED_TICK_TO_CYCLE(ticks); + } else { + sched->flags = EDF_WAIT_FOREVER; + runTask->waitTime = OS_SCHED_MAX_RESPONSE_TIME; + } + + if (OsPreemptableInSched()) { + OsSchedResched(); + if (runTask->taskStatus & OS_TASK_STATUS_TIMEOUT) { + runTask->taskStatus &= ~OS_TASK_STATUS_TIMEOUT; + return LOS_ERRNO_TSK_TIMEOUT; + } + } + + return LOS_OK; +} + +STATIC VOID EDFWake(LosTaskCB *resumedTask) +{ + LOS_ListDelete(&resumedTask->pendList); + resumedTask->taskStatus &= ~OS_TASK_STATUS_PENDING; + + if (resumedTask->taskStatus & OS_TASK_STATUS_PEND_TIME) { + OsSchedTimeoutQueueDelete(resumedTask); + resumedTask->taskStatus &= ~OS_TASK_STATUS_PEND_TIME; + } + + if (!(resumedTask->taskStatus & OS_TASK_STATUS_SUSPENDED)) { +#ifdef LOSCFG_SCHED_EDF_DEBUG + resumedTask->schedStat.pendTime += OsGetCurrSchedTimeCycle() - resumedTask->startTime; + resumedTask->schedStat.pendCount++; +#endif + EDFEnqueue(OsSchedRunqueue(), resumedTask); + } +} + +STATIC BOOL EDFSchedParamModify(LosTaskCB *taskCB, const SchedParam *param) +{ + SchedRunqueue *rq = OsSchedRunqueue(); + SchedEDF *sched = (SchedEDF *)&taskCB->sp; + + taskCB->timeSlice = 0; + sched->runTime = (INT32)OS_SYS_US_TO_CYCLE(param->runTimeUs); + sched->period = OS_SYS_US_TO_CYCLE(param->periodUs); + + if (taskCB->taskStatus & OS_TASK_STATUS_READY) { + EDFDequeue(rq, taskCB); + sched->deadline = OS_SYS_US_TO_CYCLE(param->deadlineUs); + EDFEnqueue(rq, taskCB); + return TRUE; + } + + sched->deadline = OS_SYS_US_TO_CYCLE(param->deadlineUs); + if (taskCB->taskStatus & OS_TASK_STATUS_INIT) { + EDFEnqueue(rq, taskCB); + return TRUE; + } + + if (taskCB->taskStatus & OS_TASK_STATUS_RUNNING) { + return TRUE; + } + + return FALSE; +} + +STATIC UINT32 EDFSchedParamGet(const LosTaskCB *taskCB, SchedParam *param) +{ + SchedEDF *sched = (SchedEDF *)&taskCB->sp; + param->policy = sched->policy; + param->runTimeUs = (INT32)OS_SYS_CYCLE_TO_US((UINT64)sched->runTime); + param->deadlineUs = OS_SYS_CYCLE_TO_US(sched->deadline); + param->periodUs = OS_SYS_CYCLE_TO_US(sched->period); + return LOS_OK; +} + +STATIC UINT32 EDFSuspend(LosTaskCB *taskCB) +{ + return LOS_EOPNOTSUPP; +} + +STATIC UINT32 EDFResume(LosTaskCB *taskCB, BOOL *needSched) +{ + return LOS_EOPNOTSUPP; +} + +STATIC INT32 EDFParamCompare(const SchedPolicy *sp1, const SchedPolicy *sp2) +{ + const SchedEDF *param1 = (const SchedEDF *)sp1; + const SchedEDF *param2 = (const SchedEDF *)sp2; + + return (INT32)(param1->finishTime - param2->finishTime); +} + +STATIC VOID EDFPriorityInheritance(LosTaskCB *owner, const SchedParam *param) +{ + (VOID)owner; + (VOID)param; +} + +STATIC VOID EDFPriorityRestore(LosTaskCB *owner, const LOS_DL_LIST *list, const SchedParam *param) +{ + (VOID)owner; + (VOID)list; + (VOID)param; +} + +UINT32 EDFTaskSchedParamInit(LosTaskCB *taskCB, UINT16 policy, + const SchedParam *parentParam, + const LosSchedParam *param) +{ + (VOID)parentParam; + SchedEDF *sched = (SchedEDF *)&taskCB->sp; + sched->flags = EDF_INIT; + sched->policy = policy; + sched->runTime = (INT32)OS_SYS_US_TO_CYCLE((UINT64)param->runTimeUs); + sched->deadline = OS_SYS_US_TO_CYCLE(param->deadlineUs); + sched->period = OS_SYS_US_TO_CYCLE(param->periodUs); + sched->finishTime = 0; + taskCB->timeSlice = 0; + taskCB->ops = &g_deadlineOps; + return LOS_OK; +} + +VOID EDFProcessDefaultSchedParamGet(SchedParam *param) +{ + param->runTimeUs = OS_SCHED_EDF_MIN_RUNTIME; + param->deadlineUs = OS_SCHED_EDF_MAX_DEADLINE; + param->periodUs = param->deadlineUs; +} + +VOID EDFSchedPolicyInit(SchedRunqueue *rq) +{ + if (ArchCurrCpuid() > 0) { + rq->edfRunqueue = &g_schedEDF; + return; + } + + EDFRunqueue *erq = &g_schedEDF; + erq->period = OS_SCHED_MAX_RESPONSE_TIME; + LOS_ListInit(&erq->root); + LOS_ListInit(&erq->waitList); + rq->edfRunqueue = erq; +} diff --git a/src/kernel_liteos_a/kernel/base/sched/los_idle.c b/src/kernel_liteos_a/kernel/base/sched/los_idle.c new file mode 100644 index 00000000..d2538595 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/sched/los_idle.c @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_sched_pri.h" +#include "los_process_pri.h" + +STATIC VOID IdleDequeue(SchedRunqueue *rq, LosTaskCB *taskCB); +STATIC VOID IdleEnqueue(SchedRunqueue *rq, LosTaskCB *taskCB); +STATIC UINT32 IdleWait(LosTaskCB *runTask, LOS_DL_LIST *list, UINT32 ticks); +STATIC VOID IdleWake(LosTaskCB *resumedTask); +STATIC UINT32 IdleSchedParamGet(const LosTaskCB *taskCB, SchedParam *param); +STATIC VOID IdleYield(LosTaskCB *runTask); +STATIC VOID IdleStartToRun(SchedRunqueue *rq, LosTaskCB *taskCB); +STATIC UINT32 IdleResume(LosTaskCB *taskCB, BOOL *needSched); +STATIC UINT64 IdleTimeSliceGet(const LosTaskCB *taskCB); +STATIC VOID IdleTimeSliceUpdate(SchedRunqueue *rq, LosTaskCB *taskCB, UINT64 currTime); +STATIC INT32 IdleParamCompare(const SchedPolicy *sp1, const SchedPolicy *sp2); +STATIC VOID IdlePriorityInheritance(LosTaskCB *owner, const SchedParam *param); +STATIC VOID IdlePriorityRestore(LosTaskCB *owner, const LOS_DL_LIST *list, const SchedParam *param); + +const STATIC SchedOps g_idleOps = { + .dequeue = IdleDequeue, + .enqueue = IdleEnqueue, + .waitTimeGet = NULL, + .wait = IdleWait, + .wake = IdleWake, + .schedParamModify = NULL, + .schedParamGet = IdleSchedParamGet, + .delay = NULL, + .yield = IdleYield, + .start = IdleStartToRun, + .exit = NULL, + .suspend = NULL, + .resume = IdleResume, + .deadlineGet = IdleTimeSliceGet, + .timeSliceUpdate = IdleTimeSliceUpdate, + .schedParamCompare = IdleParamCompare, + .priorityInheritance = IdlePriorityInheritance, + .priorityRestore = IdlePriorityRestore, +}; + +STATIC VOID IdleTimeSliceUpdate(SchedRunqueue *rq, LosTaskCB *taskCB, UINT64 currTime) +{ + (VOID)rq; + + taskCB->startTime = currTime; +} + +STATIC UINT64 IdleTimeSliceGet(const LosTaskCB *taskCB) +{ + (VOID)taskCB; + return (OS_SCHED_MAX_RESPONSE_TIME - OS_TICK_RESPONSE_PRECISION); +} + +STATIC VOID IdleEnqueue(SchedRunqueue *rq, LosTaskCB *taskCB) +{ + (VOID)rq; + + taskCB->taskStatus &= ~OS_TASK_STATUS_BLOCKED; + taskCB->taskStatus |= OS_TASK_STATUS_READY; +} + +STATIC VOID IdleDequeue(SchedRunqueue *rq, LosTaskCB *taskCB) +{ + (VOID)rq; + + taskCB->taskStatus &= ~OS_TASK_STATUS_READY; +} + +STATIC VOID IdleStartToRun(SchedRunqueue *rq, LosTaskCB *taskCB) +{ + IdleDequeue(rq, taskCB); +} + +STATIC VOID IdleYield(LosTaskCB *runTask) +{ + (VOID)runTask; + return; +} + +STATIC UINT32 IdleWait(LosTaskCB *runTask, LOS_DL_LIST *list, UINT32 ticks) +{ + (VOID)runTask; + (VOID)list; + (VOID)ticks; + + return LOS_NOK; +} + +STATIC VOID IdleWake(LosTaskCB *resumedTask) +{ + LOS_ListDelete(&resumedTask->pendList); + resumedTask->taskStatus &= ~OS_TASK_STATUS_PENDING; + + if (resumedTask->taskStatus & OS_TASK_STATUS_PEND_TIME) { + OsSchedTimeoutQueueDelete(resumedTask); + resumedTask->taskStatus &= ~OS_TASK_STATUS_PEND_TIME; + } + + if (!(resumedTask->taskStatus & OS_TASK_STATUS_SUSPENDED)) { +#ifdef LOSCFG_SCHED_DEBUG + resumedTask->schedStat.pendTime += OsGetCurrSchedTimeCycle() - resumedTask->startTime; + resumedTask->schedStat.pendCount++; +#endif + resumedTask->ops->enqueue(OsSchedRunqueue(), resumedTask); + } +} + +STATIC UINT32 IdleResume(LosTaskCB *taskCB, BOOL *needSched) +{ + *needSched = FALSE; + + taskCB->taskStatus &= ~OS_TASK_STATUS_SUSPENDED; + if (!OsTaskIsBlocked(taskCB)) { + taskCB->ops->enqueue(OsSchedRunqueue(), taskCB); + *needSched = TRUE; + } + return LOS_OK; +} + +STATIC UINT32 IdleSchedParamGet(const LosTaskCB *taskCB, SchedParam *param) +{ + SchedHPF *sched = (SchedHPF *)&taskCB->sp; + param->policy = sched->policy; + param->basePrio = sched->basePrio; + param->priority = sched->priority; + param->timeSlice = 0; + return LOS_OK; +} + +STATIC INT32 IdleParamCompare(const SchedPolicy *sp1, const SchedPolicy *sp2) +{ + return 0; +} + +STATIC VOID IdlePriorityInheritance(LosTaskCB *owner, const SchedParam *param) +{ + (VOID)owner; + (VOID)param; + return; +} + +STATIC VOID IdlePriorityRestore(LosTaskCB *owner, const LOS_DL_LIST *list, const SchedParam *param) +{ + (VOID)owner; + (VOID)list; + (VOID)param; + return; +} + +VOID IdleTaskSchedParamInit(LosTaskCB *taskCB) +{ + SchedHPF *sched = (SchedHPF *)&taskCB->sp; + sched->policy = LOS_SCHED_IDLE; + sched->basePrio = OS_PROCESS_PRIORITY_LOWEST; + sched->priority = OS_TASK_PRIORITY_LOWEST; + sched->initTimeSlice = 0; + taskCB->timeSlice = sched->initTimeSlice; + taskCB->taskStatus = OS_TASK_STATUS_SUSPENDED; + taskCB->ops = &g_idleOps; +} diff --git a/src/kernel_liteos_a/kernel/base/sched/los_priority.c b/src/kernel_liteos_a/kernel/base/sched/los_priority.c new file mode 100644 index 00000000..610ba119 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/sched/los_priority.c @@ -0,0 +1,557 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_sched_pri.h" +#include "los_task_pri.h" +#include "los_process_pri.h" +#include "los_hook.h" +#include "los_tick_pri.h" +#include "los_mp.h" + +#define OS_SCHED_FIFO_TIMEOUT 0x7FFFFFFF +#define PRIQUEUE_PRIOR0_BIT 0x80000000U +#define OS_SCHED_TIME_SLICES_MIN ((5000 * OS_SYS_NS_PER_US) / OS_NS_PER_CYCLE) /* 5ms */ +#define OS_SCHED_TIME_SLICES_MAX ((LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT * OS_SYS_NS_PER_US) / OS_NS_PER_CYCLE) +#define OS_SCHED_TIME_SLICES_DIFF (OS_SCHED_TIME_SLICES_MAX - OS_SCHED_TIME_SLICES_MIN) +#define OS_SCHED_READY_MAX 30 +#define OS_TIME_SLICE_MIN (INT32)((50 * OS_SYS_NS_PER_US) / OS_NS_PER_CYCLE) /* 50us */ + +STATIC HPFRunqueue g_schedHPF; + +STATIC VOID HPFDequeue(SchedRunqueue *rq, LosTaskCB *taskCB); +STATIC VOID HPFEnqueue(SchedRunqueue *rq, LosTaskCB *taskCB); +STATIC UINT64 HPFWaitTimeGet(LosTaskCB *taskCB); +STATIC UINT32 HPFWait(LosTaskCB *runTask, LOS_DL_LIST *list, UINT32 ticks); +STATIC VOID HPFWake(LosTaskCB *resumedTask); +STATIC BOOL HPFSchedParamModify(LosTaskCB *taskCB, const SchedParam *param); +STATIC UINT32 HPFSchedParamGet(const LosTaskCB *taskCB, SchedParam *param); +STATIC UINT32 HPFDelay(LosTaskCB *runTask, UINT64 waitTime); +STATIC VOID HPFYield(LosTaskCB *runTask); +STATIC VOID HPFStartToRun(SchedRunqueue *rq, LosTaskCB *taskCB); +STATIC VOID HPFExit(LosTaskCB *taskCB); +STATIC UINT32 HPFSuspend(LosTaskCB *taskCB); +STATIC UINT32 HPFResume(LosTaskCB *taskCB, BOOL *needSched); +STATIC UINT64 HPFTimeSliceGet(const LosTaskCB *taskCB); +STATIC VOID HPFTimeSliceUpdate(SchedRunqueue *rq, LosTaskCB *taskCB, UINT64 currTime); +STATIC INT32 HPFParamCompare(const SchedPolicy *sp1, const SchedPolicy *sp2); +STATIC VOID HPFPriorityInheritance(LosTaskCB *owner, const SchedParam *param); +STATIC VOID HPFPriorityRestore(LosTaskCB *owner, const LOS_DL_LIST *list, const SchedParam *param); + +const STATIC SchedOps g_priorityOps = { + .dequeue = HPFDequeue, + .enqueue = HPFEnqueue, + .waitTimeGet = HPFWaitTimeGet, + .wait = HPFWait, + .wake = HPFWake, + .schedParamModify = HPFSchedParamModify, + .schedParamGet = HPFSchedParamGet, + .delay = HPFDelay, + .yield = HPFYield, + .start = HPFStartToRun, + .exit = HPFExit, + .suspend = HPFSuspend, + .resume = HPFResume, + .deadlineGet = HPFTimeSliceGet, + .timeSliceUpdate = HPFTimeSliceUpdate, + .schedParamCompare = HPFParamCompare, + .priorityInheritance = HPFPriorityInheritance, + .priorityRestore = HPFPriorityRestore, +}; + +STATIC VOID HPFTimeSliceUpdate(SchedRunqueue *rq, LosTaskCB *taskCB, UINT64 currTime) +{ + SchedHPF *sched = (SchedHPF *)&taskCB->sp; + LOS_ASSERT(currTime >= taskCB->startTime); + + INT32 incTime = (currTime - taskCB->startTime - taskCB->irqUsedTime); + + LOS_ASSERT(incTime >= 0); + + if (sched->policy == LOS_SCHED_RR) { + taskCB->timeSlice -= incTime; +#ifdef LOSCFG_SCHED_HPF_DEBUG + taskCB->schedStat.timeSliceRealTime += incTime; +#endif + } +#ifdef LOSCFG_KERNEL_SCHED_PLIMIT + OsSchedLimitUpdateRuntime(taskCB, currTime, incTime); +#endif + taskCB->irqUsedTime = 0; + taskCB->startTime = currTime; + if (taskCB->timeSlice <= OS_TIME_SLICE_MIN) { + rq->schedFlag |= INT_PEND_RESCH; + } + +#ifdef LOSCFG_SCHED_HPF_DEBUG + taskCB->schedStat.allRuntime += incTime; +#endif +} + +STATIC UINT64 HPFTimeSliceGet(const LosTaskCB *taskCB) +{ + SchedHPF *sched = (SchedHPF *)&taskCB->sp; + INT32 timeSlice = taskCB->timeSlice; + + timeSlice = (timeSlice <= OS_TIME_SLICE_MIN) ? sched->initTimeSlice : timeSlice; + return (taskCB->startTime + timeSlice); +} + +STATIC INLINE UINT32 TimeSliceCalculate(HPFRunqueue *rq, UINT16 basePrio, UINT16 priority) +{ + UINT32 time; + UINT32 readyTasks; + + HPFQueue *queueList = &rq->queueList[basePrio]; + readyTasks = queueList->readyTasks[priority]; + if (readyTasks > OS_SCHED_READY_MAX) { + return OS_SCHED_TIME_SLICES_MIN; + } + time = ((OS_SCHED_READY_MAX - readyTasks) * OS_SCHED_TIME_SLICES_DIFF) / OS_SCHED_READY_MAX; + return (time + OS_SCHED_TIME_SLICES_MIN); +} + +STATIC INLINE VOID PriQueHeadInsert(HPFRunqueue *rq, UINT32 basePrio, LOS_DL_LIST *priQue, UINT32 priority) +{ + HPFQueue *queueList = &rq->queueList[basePrio]; + LOS_DL_LIST *priQueList = &queueList->priQueList[0]; + UINT32 *bitmap = &queueList->queueBitmap; + + /* + * Task control blocks are inited as zero. And when task is deleted, + * and at the same time would be deleted from priority queue or + * other lists, task pend node will restored as zero. + */ + LOS_ASSERT(priQue->pstNext == NULL); + + if (*bitmap == 0) { + rq->queueBitmap |= PRIQUEUE_PRIOR0_BIT >> basePrio; + } + + if (LOS_ListEmpty(&priQueList[priority])) { + *bitmap |= PRIQUEUE_PRIOR0_BIT >> priority; + } + + LOS_ListHeadInsert(&priQueList[priority], priQue); + queueList->readyTasks[priority]++; +} + +STATIC INLINE VOID PriQueTailInsert(HPFRunqueue *rq, UINT32 basePrio, LOS_DL_LIST *priQue, UINT32 priority) +{ + HPFQueue *queueList = &rq->queueList[basePrio]; + LOS_DL_LIST *priQueList = &queueList->priQueList[0]; + UINT32 *bitmap = &queueList->queueBitmap; + + /* + * Task control blocks are inited as zero. And when task is deleted, + * and at the same time would be deleted from priority queue or + * other lists, task pend node will restored as zero. + */ + LOS_ASSERT(priQue->pstNext == NULL); + + if (*bitmap == 0) { + rq->queueBitmap |= PRIQUEUE_PRIOR0_BIT >> basePrio; + } + + if (LOS_ListEmpty(&priQueList[priority])) { + *bitmap |= PRIQUEUE_PRIOR0_BIT >> priority; + } + + LOS_ListTailInsert(&priQueList[priority], priQue); + queueList->readyTasks[priority]++; +} + +STATIC INLINE VOID PriQueDelete(HPFRunqueue *rq, UINT32 basePrio, LOS_DL_LIST *priQue, UINT32 priority) +{ + HPFQueue *queueList = &rq->queueList[basePrio]; + LOS_DL_LIST *priQueList = &queueList->priQueList[0]; + UINT32 *bitmap = &queueList->queueBitmap; + + LOS_ListDelete(priQue); + queueList->readyTasks[priority]--; + if (LOS_ListEmpty(&priQueList[priority])) { + *bitmap &= ~(PRIQUEUE_PRIOR0_BIT >> priority); + } + + if (*bitmap == 0) { + rq->queueBitmap &= ~(PRIQUEUE_PRIOR0_BIT >> basePrio); + } +} + +STATIC INLINE VOID PriQueInsert(HPFRunqueue *rq, LosTaskCB *taskCB) +{ + LOS_ASSERT(!(taskCB->taskStatus & OS_TASK_STATUS_READY)); + SchedHPF *sched = (SchedHPF *)&taskCB->sp; + + switch (sched->policy) { + case LOS_SCHED_RR: { + if (taskCB->timeSlice > OS_TIME_SLICE_MIN) { + PriQueHeadInsert(rq, sched->basePrio, &taskCB->pendList, sched->priority); + } else { + sched->initTimeSlice = TimeSliceCalculate(rq, sched->basePrio, sched->priority); + taskCB->timeSlice = sched->initTimeSlice; + PriQueTailInsert(rq, sched->basePrio, &taskCB->pendList, sched->priority); +#ifdef LOSCFG_SCHED_HPF_DEBUG + taskCB->schedStat.timeSliceTime = taskCB->schedStat.timeSliceRealTime; + taskCB->schedStat.timeSliceCount++; +#endif + } + break; + } + case LOS_SCHED_FIFO: { + /* The time slice of FIFO is always greater than 0 unless the yield is called */ + if ((taskCB->timeSlice > OS_TIME_SLICE_MIN) && (taskCB->taskStatus & OS_TASK_STATUS_RUNNING)) { + PriQueHeadInsert(rq, sched->basePrio, &taskCB->pendList, sched->priority); + } else { + sched->initTimeSlice = OS_SCHED_FIFO_TIMEOUT; + taskCB->timeSlice = sched->initTimeSlice; + PriQueTailInsert(rq, sched->basePrio, &taskCB->pendList, sched->priority); + } + break; + } + default: + LOS_ASSERT(0); + break; + } + + taskCB->taskStatus &= ~OS_TASK_STATUS_BLOCKED; + taskCB->taskStatus |= OS_TASK_STATUS_READY; +} + +STATIC VOID HPFEnqueue(SchedRunqueue *rq, LosTaskCB *taskCB) +{ +#ifdef LOSCFG_SCHED_HPF_DEBUG + if (!(taskCB->taskStatus & OS_TASK_STATUS_RUNNING)) { + taskCB->startTime = OsGetCurrSchedTimeCycle(); + } +#endif + PriQueInsert(rq->hpfRunqueue, taskCB); +} + +STATIC VOID HPFDequeue(SchedRunqueue *rq, LosTaskCB *taskCB) +{ + SchedHPF *sched = (SchedHPF *)&taskCB->sp; + + if (taskCB->taskStatus & OS_TASK_STATUS_READY) { + PriQueDelete(rq->hpfRunqueue, sched->basePrio, &taskCB->pendList, sched->priority); + taskCB->taskStatus &= ~OS_TASK_STATUS_READY; + } +} + +STATIC VOID HPFStartToRun(SchedRunqueue *rq, LosTaskCB *taskCB) +{ + HPFDequeue(rq, taskCB); +} + +STATIC VOID HPFExit(LosTaskCB *taskCB) +{ + if (taskCB->taskStatus & OS_TASK_STATUS_READY) { + HPFDequeue(OsSchedRunqueue(), taskCB); + } else if (taskCB->taskStatus & OS_TASK_STATUS_PENDING) { + LOS_ListDelete(&taskCB->pendList); + taskCB->taskStatus &= ~OS_TASK_STATUS_PENDING; + } + + if (taskCB->taskStatus & (OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND_TIME)) { + OsSchedTimeoutQueueDelete(taskCB); + taskCB->taskStatus &= ~(OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND_TIME); + } +} + +STATIC VOID HPFYield(LosTaskCB *runTask) +{ + SchedRunqueue *rq = OsSchedRunqueue(); + runTask->timeSlice = 0; + + runTask->startTime = OsGetCurrSchedTimeCycle(); + HPFEnqueue(rq, runTask); + OsSchedResched(); +} + +STATIC UINT32 HPFDelay(LosTaskCB *runTask, UINT64 waitTime) +{ + runTask->taskStatus |= OS_TASK_STATUS_DELAY; + runTask->waitTime = waitTime; + + OsSchedResched(); + return LOS_OK; +} + +STATIC UINT64 HPFWaitTimeGet(LosTaskCB *taskCB) +{ + taskCB->waitTime += taskCB->startTime; + return taskCB->waitTime; +} + +STATIC UINT32 HPFWait(LosTaskCB *runTask, LOS_DL_LIST *list, UINT32 ticks) +{ + runTask->taskStatus |= OS_TASK_STATUS_PENDING; + LOS_ListTailInsert(list, &runTask->pendList); + + if (ticks != LOS_WAIT_FOREVER) { + runTask->taskStatus |= OS_TASK_STATUS_PEND_TIME; + runTask->waitTime = OS_SCHED_TICK_TO_CYCLE(ticks); + } + + if (OsPreemptableInSched()) { + OsSchedResched(); + if (runTask->taskStatus & OS_TASK_STATUS_TIMEOUT) { + runTask->taskStatus &= ~OS_TASK_STATUS_TIMEOUT; + return LOS_ERRNO_TSK_TIMEOUT; + } + } + + return LOS_OK; +} + +STATIC VOID HPFWake(LosTaskCB *resumedTask) +{ + LOS_ListDelete(&resumedTask->pendList); + resumedTask->taskStatus &= ~OS_TASK_STATUS_PENDING; + + if (resumedTask->taskStatus & OS_TASK_STATUS_PEND_TIME) { + OsSchedTimeoutQueueDelete(resumedTask); + resumedTask->taskStatus &= ~OS_TASK_STATUS_PEND_TIME; + } + + if (!(resumedTask->taskStatus & OS_TASK_STATUS_SUSPENDED)) { +#ifdef LOSCFG_SCHED_HPF_DEBUG + resumedTask->schedStat.pendTime += OsGetCurrSchedTimeCycle() - resumedTask->startTime; + resumedTask->schedStat.pendCount++; +#endif + HPFEnqueue(OsSchedRunqueue(), resumedTask); + } +} + +STATIC BOOL BasePriorityModify(SchedRunqueue *rq, LosTaskCB *taskCB, UINT16 priority) +{ + LosProcessCB *processCB = OS_PCB_FROM_TCB(taskCB); + BOOL needSched = FALSE; + + LOS_DL_LIST_FOR_EACH_ENTRY(taskCB, &processCB->threadSiblingList, LosTaskCB, threadList) { + SchedHPF *sched = (SchedHPF *)&taskCB->sp; + if (taskCB->taskStatus & OS_TASK_STATUS_READY) { + taskCB->ops->dequeue(rq, taskCB); + sched->basePrio = priority; + taskCB->ops->enqueue(rq, taskCB); + } else { + sched->basePrio = priority; + } + if (taskCB->taskStatus & (OS_TASK_STATUS_READY | OS_TASK_STATUS_RUNNING)) { + needSched = TRUE; + } + } + + return needSched; +} + +STATIC BOOL HPFSchedParamModify(LosTaskCB *taskCB, const SchedParam *param) +{ + SchedRunqueue *rq = OsSchedRunqueue(); + BOOL needSched = FALSE; + SchedHPF *sched = (SchedHPF *)&taskCB->sp; + + if (sched->policy != param->policy) { + sched->policy = param->policy; + taskCB->timeSlice = 0; + } + + if (sched->basePrio != param->basePrio) { + needSched = BasePriorityModify(rq, taskCB, param->basePrio); + } + + if (taskCB->taskStatus & OS_TASK_STATUS_READY) { + HPFDequeue(rq, taskCB); + sched->priority = param->priority; + HPFEnqueue(rq, taskCB); + return TRUE; + } + + sched->priority = param->priority; + OsHookCall(LOS_HOOK_TYPE_TASK_PRIMODIFY, taskCB, sched->priority); + if (taskCB->taskStatus & OS_TASK_STATUS_INIT) { + HPFEnqueue(rq, taskCB); + return TRUE; + } + + if (taskCB->taskStatus & OS_TASK_STATUS_RUNNING) { + return TRUE; + } + + return needSched; +} + +STATIC UINT32 HPFSchedParamGet(const LosTaskCB *taskCB, SchedParam *param) +{ + SchedHPF *sched = (SchedHPF *)&taskCB->sp; + param->policy = sched->policy; + param->basePrio = sched->basePrio; + param->priority = sched->priority; + param->timeSlice = sched->initTimeSlice; + return LOS_OK; +} + +STATIC UINT32 HPFSuspend(LosTaskCB *taskCB) +{ + if (taskCB->taskStatus & OS_TASK_STATUS_READY) { + HPFDequeue(OsSchedRunqueue(), taskCB); + } + + SchedTaskFreeze(taskCB); + + taskCB->taskStatus |= OS_TASK_STATUS_SUSPENDED; + OsHookCall(LOS_HOOK_TYPE_MOVEDTASKTOSUSPENDEDLIST, taskCB); + if (taskCB == OsCurrTaskGet()) { + OsSchedResched(); + } + return LOS_OK; +} + +STATIC UINT32 HPFResume(LosTaskCB *taskCB, BOOL *needSched) +{ + *needSched = FALSE; + + SchedTaskUnfreeze(taskCB); + + taskCB->taskStatus &= ~OS_TASK_STATUS_SUSPENDED; + if (!OsTaskIsBlocked(taskCB)) { + HPFEnqueue(OsSchedRunqueue(), taskCB); + *needSched = TRUE; + } + + return LOS_OK; +} + +STATIC INT32 HPFParamCompare(const SchedPolicy *sp1, const SchedPolicy *sp2) +{ + SchedHPF *param1 = (SchedHPF *)sp1; + SchedHPF *param2 = (SchedHPF *)sp2; + + if (param1->basePrio != param2->basePrio) { + return (param1->basePrio - param2->basePrio); + } + + return (param1->priority - param2->priority); +} + +STATIC VOID HPFPriorityInheritance(LosTaskCB *owner, const SchedParam *param) +{ + SchedHPF *sp = (SchedHPF *)&owner->sp; + + if ((param->policy != LOS_SCHED_RR) && (param->policy != LOS_SCHED_FIFO)) { + return; + } + + if (sp->priority <= param->priority) { + return; + } + + LOS_BitmapSet(&sp->priBitmap, sp->priority); + sp->priority = param->priority; +} + +STATIC VOID HPFPriorityRestore(LosTaskCB *owner, const LOS_DL_LIST *list, const SchedParam *param) +{ + UINT16 priority; + LosTaskCB *pendedTask = NULL; + + if ((param->policy != LOS_SCHED_RR) && (param->policy != LOS_SCHED_FIFO)) { + return; + } + + SchedHPF *sp = (SchedHPF *)&owner->sp; + if (sp->priority < param->priority) { + if (LOS_HighBitGet(sp->priBitmap) != param->priority) { + LOS_BitmapClr(&sp->priBitmap, param->priority); + } + return; + } + + if (sp->priBitmap == 0) { + return; + } + + if ((list != NULL) && !LOS_ListEmpty((LOS_DL_LIST *)list)) { + priority = LOS_HighBitGet(sp->priBitmap); + LOS_DL_LIST_FOR_EACH_ENTRY(pendedTask, list, LosTaskCB, pendList) { + SchedHPF *pendSp = (SchedHPF *)&pendedTask->sp; + if ((pendedTask->ops == owner->ops) && (priority != pendSp->priority)) { + LOS_BitmapClr(&sp->priBitmap, pendSp->priority); + } + } + } + + priority = LOS_LowBitGet(sp->priBitmap); + if (priority != LOS_INVALID_BIT_INDEX) { + LOS_BitmapClr(&sp->priBitmap, priority); + sp->priority = priority; + } +} + +VOID HPFTaskSchedParamInit(LosTaskCB *taskCB, UINT16 policy, + const SchedParam *parentParam, + const LosSchedParam *param) +{ + SchedHPF *sched = (SchedHPF *)&taskCB->sp; + + sched->policy = policy; + if (param != NULL) { + sched->priority = param->priority; + } else { + sched->priority = parentParam->priority; + } + sched->basePrio = parentParam->basePrio; + + sched->initTimeSlice = 0; + taskCB->timeSlice = sched->initTimeSlice; + taskCB->ops = &g_priorityOps; +} + +VOID HPFProcessDefaultSchedParamGet(SchedParam *param) +{ + param->basePrio = OS_USER_PROCESS_PRIORITY_HIGHEST; +} + +VOID HPFSchedPolicyInit(SchedRunqueue *rq) +{ + if (ArchCurrCpuid() > 0) { + rq->hpfRunqueue = &g_schedHPF; + return; + } + + for (UINT16 index = 0; index < OS_PRIORITY_QUEUE_NUM; index++) { + HPFQueue *queueList = &g_schedHPF.queueList[index]; + LOS_DL_LIST *priQue = &queueList->priQueList[0]; + for (UINT16 prio = 0; prio < OS_PRIORITY_QUEUE_NUM; prio++) { + LOS_ListInit(&priQue[prio]); + } + } + + rq->hpfRunqueue = &g_schedHPF; +} diff --git a/src/kernel_liteos_a/kernel/base/sched/los_sched.c b/src/kernel_liteos_a/kernel/base/sched/los_sched.c new file mode 100644 index 00000000..10de1b7d --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/sched/los_sched.c @@ -0,0 +1,563 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_sched_pri.h" +#include "los_hw_pri.h" +#include "los_task_pri.h" +#include "los_swtmr_pri.h" +#include "los_process_pri.h" +#include "los_arch_mmu.h" +#include "los_hook.h" +#ifdef LOSCFG_KERNEL_CPUP +#include "los_cpup_pri.h" +#endif +#include "los_hw_tick_pri.h" +#include "los_tick_pri.h" +#ifdef LOSCFG_BASE_CORE_TSK_MONITOR +#include "los_stackinfo_pri.h" +#endif +#include "los_mp.h" + +SchedRunqueue g_schedRunqueue[LOSCFG_KERNEL_CORE_NUM]; + +STATIC INLINE VOID SchedNextExpireTimeSet(UINT32 responseID, UINT64 taskEndTime, UINT32 oldResponseID) +{ + SchedRunqueue *rq = OsSchedRunqueue(); + BOOL isTimeSlice = FALSE; + UINT64 currTime = OsGetCurrSchedTimeCycle(); + UINT64 nextExpireTime = OsGetSortLinkNextExpireTime(&rq->timeoutQueue, currTime, OS_TICK_RESPONSE_PRECISION); + + rq->schedFlag &= ~INT_PEND_TICK; + if (rq->responseID == oldResponseID) { + /* This time has expired, and the next time the theory has expired is infinite */ + rq->responseTime = OS_SCHED_MAX_RESPONSE_TIME; + } + + /* The current thread's time slice has been consumed, but the current system lock task cannot + * trigger the schedule to release the CPU + */ + if ((nextExpireTime > taskEndTime) && ((nextExpireTime - taskEndTime) > OS_SCHED_MINI_PERIOD)) { + nextExpireTime = taskEndTime; + isTimeSlice = TRUE; + } + + if ((rq->responseTime <= nextExpireTime) || + ((rq->responseTime - nextExpireTime) < OS_TICK_RESPONSE_PRECISION)) { + return; + } + + if (isTimeSlice) { + /* The expiration time of the current system is the thread's slice expiration time */ + rq->responseID = responseID; + } else { + rq->responseID = OS_INVALID_VALUE; + } + + UINT64 nextResponseTime = nextExpireTime - currTime; + rq->responseTime = currTime + HalClockTickTimerReload(nextResponseTime); +} + +VOID OsSchedExpireTimeUpdate(VOID) +{ + UINT32 intSave; + if (!OS_SCHEDULER_ACTIVE || OS_INT_ACTIVE) { + OsSchedRunqueuePendingSet(); + return; + } + + LosTaskCB *runTask = OsCurrTaskGet(); + SCHEDULER_LOCK(intSave); + UINT64 deadline = runTask->ops->deadlineGet(runTask); + SCHEDULER_UNLOCK(intSave); + SchedNextExpireTimeSet(runTask->taskID, deadline, runTask->taskID); +} + +STATIC INLINE VOID SchedTimeoutTaskWake(SchedRunqueue *rq, UINT64 currTime, LosTaskCB *taskCB, BOOL *needSched) +{ + LOS_SpinLock(&g_taskSpin); + if (OsSchedPolicyIsEDF(taskCB)) { + SchedEDF *sched = (SchedEDF *)&taskCB->sp; + if (sched->finishTime <= currTime) { + if (taskCB->timeSlice >= 0) { + PrintExcInfo("EDF task: %u name: %s is timeout, timeout for %llu us.\n", + taskCB->taskID, taskCB->taskName, OS_SYS_CYCLE_TO_US(currTime - sched->finishTime)); + } + taskCB->timeSlice = 0; + } + if (sched->flags == EDF_WAIT_FOREVER) { + taskCB->taskStatus &= ~OS_TASK_STATUS_PEND_TIME; + sched->flags = EDF_UNUSED; + } + } + + UINT16 tempStatus = taskCB->taskStatus; + if (tempStatus & (OS_TASK_STATUS_PEND_TIME | OS_TASK_STATUS_DELAY)) { + taskCB->taskStatus &= ~(OS_TASK_STATUS_PENDING | OS_TASK_STATUS_PEND_TIME | OS_TASK_STATUS_DELAY); + if (tempStatus & OS_TASK_STATUS_PEND_TIME) { + taskCB->taskStatus |= OS_TASK_STATUS_TIMEOUT; + LOS_ListDelete(&taskCB->pendList); + taskCB->taskMux = NULL; + OsTaskWakeClearPendMask(taskCB); + } + + if (!(tempStatus & OS_TASK_STATUS_SUSPENDED)) { +#ifdef LOSCFG_SCHED_HPF_DEBUG + taskCB->schedStat.pendTime += currTime - taskCB->startTime; + taskCB->schedStat.pendCount++; +#endif + taskCB->ops->enqueue(rq, taskCB); + *needSched = TRUE; + } + } + + LOS_SpinUnlock(&g_taskSpin); +} + +STATIC INLINE BOOL SchedTimeoutQueueScan(SchedRunqueue *rq) +{ + BOOL needSched = FALSE; + SortLinkAttribute *timeoutQueue = &rq->timeoutQueue; + LOS_DL_LIST *listObject = &timeoutQueue->sortLink; + /* + * When task is pended with timeout, the task block is on the timeout sortlink + * (per cpu) and ipc(mutex,sem and etc.)'s block at the same time, it can be waken + * up by either timeout or corresponding ipc it's waiting. + * + * Now synchronize sortlink procedure is used, therefore the whole task scan needs + * to be protected, preventing another core from doing sortlink deletion at same time. + */ + LOS_SpinLock(&timeoutQueue->spinLock); + + if (LOS_ListEmpty(listObject)) { + LOS_SpinUnlock(&timeoutQueue->spinLock); + return needSched; + } + + SortLinkList *sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode); + UINT64 currTime = OsGetCurrSchedTimeCycle(); + while (sortList->responseTime <= currTime) { + LosTaskCB *taskCB = LOS_DL_LIST_ENTRY(sortList, LosTaskCB, sortList); + OsDeleteNodeSortLink(timeoutQueue, &taskCB->sortList); + LOS_SpinUnlock(&timeoutQueue->spinLock); + + SchedTimeoutTaskWake(rq, currTime, taskCB, &needSched); + + LOS_SpinLock(&timeoutQueue->spinLock); + if (LOS_ListEmpty(listObject)) { + break; + } + + sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode); + } + + LOS_SpinUnlock(&timeoutQueue->spinLock); + + return needSched; +} + +VOID OsSchedTick(VOID) +{ + SchedRunqueue *rq = OsSchedRunqueue(); + + if (rq->responseID == OS_INVALID_VALUE) { + if (SchedTimeoutQueueScan(rq)) { + LOS_MpSchedule(OS_MP_CPU_ALL); + rq->schedFlag |= INT_PEND_RESCH; + } + } + rq->schedFlag |= INT_PEND_TICK; + rq->responseTime = OS_SCHED_MAX_RESPONSE_TIME; +} + +VOID OsSchedResponseTimeReset(UINT64 responseTime) +{ + OsSchedRunqueue()->responseTime = responseTime; +} + +VOID OsSchedRunqueueInit(VOID) +{ + if (ArchCurrCpuid() != 0) { + return; + } + + for (UINT16 index = 0; index < LOSCFG_KERNEL_CORE_NUM; index++) { + SchedRunqueue *rq = OsSchedRunqueueByID(index); + OsSortLinkInit(&rq->timeoutQueue); + rq->responseTime = OS_SCHED_MAX_RESPONSE_TIME; + } +} + +VOID OsSchedRunqueueIdleInit(LosTaskCB *idleTask) +{ + SchedRunqueue *rq = OsSchedRunqueue(); + rq->idleTask = idleTask; +} + +UINT32 OsSchedInit(VOID) +{ + for (UINT16 cpuid = 0; cpuid < LOSCFG_KERNEL_CORE_NUM; cpuid++) { + SchedRunqueue *rq = OsSchedRunqueueByID(cpuid); + EDFSchedPolicyInit(rq); + HPFSchedPolicyInit(rq); + } + +#ifdef LOSCFG_SCHED_TICK_DEBUG + UINT32 ret = OsSchedDebugInit(); + if (ret != LOS_OK) { + return ret; + } +#endif + return LOS_OK; +} + +/* + * If the return value greater than 0, task1 has a lower priority than task2. + * If the return value less than 0, task1 has a higher priority than task2. + * If the return value is 0, task1 and task2 have the same priority. + */ +INT32 OsSchedParamCompare(const LosTaskCB *task1, const LosTaskCB *task2) +{ + SchedHPF *rp1 = (SchedHPF *)&task1->sp; + SchedHPF *rp2 = (SchedHPF *)&task2->sp; + + if (rp1->policy == rp2->policy) { + return task1->ops->schedParamCompare(&task1->sp, &task2->sp); + } + + if (rp1->policy == LOS_SCHED_IDLE) { + return 1; + } else if (rp2->policy == LOS_SCHED_IDLE) { + return -1; + } + return 0; +} + +UINT32 OsSchedParamInit(LosTaskCB *taskCB, UINT16 policy, const SchedParam *parentParam, const LosSchedParam *param) +{ + switch (policy) { + case LOS_SCHED_FIFO: + case LOS_SCHED_RR: + HPFTaskSchedParamInit(taskCB, policy, parentParam, param); + break; + case LOS_SCHED_DEADLINE: + return EDFTaskSchedParamInit(taskCB, policy, parentParam, param); + case LOS_SCHED_IDLE: + IdleTaskSchedParamInit(taskCB); + break; + default: + return LOS_NOK; + } + + return LOS_OK; +} + +VOID OsSchedProcessDefaultSchedParamGet(UINT16 policy, SchedParam *param) +{ + switch (policy) { + case LOS_SCHED_FIFO: + case LOS_SCHED_RR: + HPFProcessDefaultSchedParamGet(param); + break; + case LOS_SCHED_DEADLINE: + EDFProcessDefaultSchedParamGet(param); + break; + case LOS_SCHED_IDLE: + default: + PRINT_ERR("Invalid process-level scheduling policy, %u\n", policy); + break; + } + return; +} + +STATIC LosTaskCB *TopTaskGet(SchedRunqueue *rq) +{ + LosTaskCB *newTask = EDFRunqueueTopTaskGet(rq->edfRunqueue); + if (newTask != NULL) { + goto FIND; + } + + newTask = HPFRunqueueTopTaskGet(rq->hpfRunqueue); + if (newTask != NULL) { + goto FIND; + } + + newTask = rq->idleTask; + +FIND: + newTask->ops->start(rq, newTask); + return newTask; +} + +VOID OsSchedStart(VOID) +{ + UINT32 cpuid = ArchCurrCpuid(); + UINT32 intSave; + + PRINTK("cpu %d entering scheduler\n", cpuid); + + SCHEDULER_LOCK(intSave); + + OsTickStart(); + + SchedRunqueue *rq = OsSchedRunqueue(); + LosTaskCB *newTask = TopTaskGet(rq); + newTask->taskStatus |= OS_TASK_STATUS_RUNNING; + +#ifdef LOSCFG_KERNEL_SMP + /* + * attention: current cpu needs to be set, in case first task deletion + * may fail because this flag mismatch with the real current cpu. + */ + newTask->currCpu = cpuid; +#endif + + OsCurrTaskSet((VOID *)newTask); + + newTask->startTime = OsGetCurrSchedTimeCycle(); + + OsSwtmrResponseTimeReset(newTask->startTime); + + /* System start schedule */ + OS_SCHEDULER_SET(cpuid); + + rq->responseID = OS_INVALID; + UINT64 deadline = newTask->ops->deadlineGet(newTask); + SchedNextExpireTimeSet(newTask->taskID, deadline, OS_INVALID); + OsTaskContextLoad(newTask); +} + +#ifdef LOSCFG_KERNEL_SMP +VOID OsSchedToUserReleaseLock(VOID) +{ + /* The scheduling lock needs to be released before returning to user mode */ + LOCKDEP_CHECK_OUT(&g_taskSpin); + ArchSpinUnlock(&g_taskSpin.rawLock); + + OsSchedUnlock(); +} +#endif + +#ifdef LOSCFG_BASE_CORE_TSK_MONITOR +STATIC VOID TaskStackCheck(LosTaskCB *runTask, LosTaskCB *newTask) +{ + if (!OS_STACK_MAGIC_CHECK(runTask->topOfStack)) { + LOS_Panic("CURRENT task ID: %s:%d stack overflow!\n", runTask->taskName, runTask->taskID); + } + + if (((UINTPTR)(newTask->stackPointer) <= newTask->topOfStack) || + ((UINTPTR)(newTask->stackPointer) > (newTask->topOfStack + newTask->stackSize))) { + LOS_Panic("HIGHEST task ID: %s:%u SP error! StackPointer: %p TopOfStack: %p\n", + newTask->taskName, newTask->taskID, newTask->stackPointer, newTask->topOfStack); + } +} +#endif + +STATIC INLINE VOID SchedSwitchCheck(LosTaskCB *runTask, LosTaskCB *newTask) +{ +#ifdef LOSCFG_BASE_CORE_TSK_MONITOR + TaskStackCheck(runTask, newTask); +#endif /* LOSCFG_BASE_CORE_TSK_MONITOR */ + OsHookCall(LOS_HOOK_TYPE_TASK_SWITCHEDIN, newTask, runTask); +} + +STATIC VOID SchedTaskSwitch(SchedRunqueue *rq, LosTaskCB *runTask, LosTaskCB *newTask) +{ + SchedSwitchCheck(runTask, newTask); + + runTask->taskStatus &= ~OS_TASK_STATUS_RUNNING; + newTask->taskStatus |= OS_TASK_STATUS_RUNNING; + +#ifdef LOSCFG_KERNEL_SMP + /* mask new running task's owner processor */ + runTask->currCpu = OS_TASK_INVALID_CPUID; + newTask->currCpu = ArchCurrCpuid(); +#endif + + OsCurrTaskSet((VOID *)newTask); +#ifdef LOSCFG_KERNEL_VM + if (newTask->archMmu != runTask->archMmu) { + LOS_ArchMmuContextSwitch((LosArchMmu *)newTask->archMmu); + } +#endif + +#ifdef LOSCFG_KERNEL_CPUP + OsCpupCycleEndStart(runTask, newTask); +#endif + +#ifdef LOSCFG_SCHED_HPF_DEBUG + UINT64 waitStartTime = newTask->startTime; +#endif + if (runTask->taskStatus & OS_TASK_STATUS_READY) { + /* When a thread enters the ready queue, its slice of time is updated */ + newTask->startTime = runTask->startTime; + } else { + /* The currently running task is blocked */ + newTask->startTime = OsGetCurrSchedTimeCycle(); + /* The task is in a blocking state and needs to update its time slice before pend */ + runTask->ops->timeSliceUpdate(rq, runTask, newTask->startTime); + + if (runTask->taskStatus & (OS_TASK_STATUS_PEND_TIME | OS_TASK_STATUS_DELAY)) { + OsSchedTimeoutQueueAdd(runTask, runTask->ops->waitTimeGet(runTask)); + } + } + + UINT64 deadline = newTask->ops->deadlineGet(newTask); + SchedNextExpireTimeSet(newTask->taskID, deadline, runTask->taskID); + +#ifdef LOSCFG_SCHED_HPF_DEBUG + newTask->schedStat.waitSchedTime += newTask->startTime - waitStartTime; + newTask->schedStat.waitSchedCount++; + runTask->schedStat.runTime = runTask->schedStat.allRuntime; + runTask->schedStat.switchCount++; +#endif + /* do the task context switch */ + OsTaskSchedule(newTask, runTask); +} + +VOID OsSchedIrqEndCheckNeedSched(VOID) +{ + SchedRunqueue *rq = OsSchedRunqueue(); + LosTaskCB *runTask = OsCurrTaskGet(); + + runTask->ops->timeSliceUpdate(rq, runTask, OsGetCurrSchedTimeCycle()); + + if (OsPreemptable() && (rq->schedFlag & INT_PEND_RESCH)) { + rq->schedFlag &= ~INT_PEND_RESCH; + + LOS_SpinLock(&g_taskSpin); + + runTask->ops->enqueue(rq, runTask); + + LosTaskCB *newTask = TopTaskGet(rq); + if (runTask != newTask) { + SchedTaskSwitch(rq, runTask, newTask); + LOS_SpinUnlock(&g_taskSpin); + return; + } + + LOS_SpinUnlock(&g_taskSpin); + } + + if (rq->schedFlag & INT_PEND_TICK) { + OsSchedExpireTimeUpdate(); + } +} + +VOID OsSchedResched(VOID) +{ + LOS_ASSERT(LOS_SpinHeld(&g_taskSpin)); + SchedRunqueue *rq = OsSchedRunqueue(); +#ifdef LOSCFG_KERNEL_SMP + LOS_ASSERT(rq->taskLockCnt == 1); +#else + LOS_ASSERT(rq->taskLockCnt == 0); +#endif + + rq->schedFlag &= ~INT_PEND_RESCH; + LosTaskCB *runTask = OsCurrTaskGet(); + LosTaskCB *newTask = TopTaskGet(rq); + if (runTask == newTask) { + return; + } + + SchedTaskSwitch(rq, runTask, newTask); +} + +VOID LOS_Schedule(VOID) +{ + UINT32 intSave; + LosTaskCB *runTask = OsCurrTaskGet(); + SchedRunqueue *rq = OsSchedRunqueue(); + + if (OS_INT_ACTIVE) { + OsSchedRunqueuePendingSet(); + return; + } + + if (!OsPreemptable()) { + return; + } + + /* + * trigger schedule in task will also do the slice check + * if necessary, it will give up the timeslice more in time. + * otherwise, there's no other side effects. + */ + SCHEDULER_LOCK(intSave); + + runTask->ops->timeSliceUpdate(rq, runTask, OsGetCurrSchedTimeCycle()); + + /* add run task back to ready queue */ + runTask->ops->enqueue(rq, runTask); + + /* reschedule to new thread */ + OsSchedResched(); + + SCHEDULER_UNLOCK(intSave); +} + +STATIC INLINE LOS_DL_LIST *SchedLockPendFindPosSub(const LosTaskCB *runTask, const LOS_DL_LIST *lockList) +{ + LosTaskCB *pendedTask = NULL; + + LOS_DL_LIST_FOR_EACH_ENTRY(pendedTask, lockList, LosTaskCB, pendList) { + INT32 ret = OsSchedParamCompare(pendedTask, runTask); + if (ret < 0) { + continue; + } else if (ret > 0) { + return &pendedTask->pendList; + } else { + return pendedTask->pendList.pstNext; + } + } + return NULL; +} + +LOS_DL_LIST *OsSchedLockPendFindPos(const LosTaskCB *runTask, LOS_DL_LIST *lockList) +{ + if (LOS_ListEmpty(lockList)) { + return lockList; + } + + LosTaskCB *pendedTask1 = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(lockList)); + INT32 ret = OsSchedParamCompare(pendedTask1, runTask); + if (ret > 0) { + return lockList->pstNext; + } + + LosTaskCB *pendedTask2 = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_LAST(lockList)); + ret = OsSchedParamCompare(pendedTask2, runTask); + if (ret <= 0) { + return lockList; + } + + return SchedLockPendFindPosSub(runTask, lockList); +} diff --git a/src/kernel_liteos_a/kernel/base/sched/los_sortlink.c b/src/kernel_liteos_a/kernel/base/sched/los_sortlink.c new file mode 100644 index 00000000..4f68436f --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/sched/los_sortlink.c @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_sortlink_pri.h" + +VOID OsSortLinkInit(SortLinkAttribute *sortLinkHeader) +{ + LOS_ListInit(&sortLinkHeader->sortLink); + LOS_SpinInit(&sortLinkHeader->spinLock); + sortLinkHeader->nodeNum = 0; +} + +STATIC INLINE VOID AddNode2SortLink(SortLinkAttribute *sortLinkHeader, SortLinkList *sortList) +{ + LOS_DL_LIST *head = (LOS_DL_LIST *)&sortLinkHeader->sortLink; + + if (LOS_ListEmpty(head)) { + LOS_ListHeadInsert(head, &sortList->sortLinkNode); + sortLinkHeader->nodeNum++; + return; + } + + SortLinkList *listSorted = LOS_DL_LIST_ENTRY(head->pstNext, SortLinkList, sortLinkNode); + if (listSorted->responseTime > sortList->responseTime) { + LOS_ListAdd(head, &sortList->sortLinkNode); + sortLinkHeader->nodeNum++; + return; + } else if (listSorted->responseTime == sortList->responseTime) { + LOS_ListAdd(head->pstNext, &sortList->sortLinkNode); + sortLinkHeader->nodeNum++; + return; + } + + LOS_DL_LIST *prevNode = head->pstPrev; + do { + listSorted = LOS_DL_LIST_ENTRY(prevNode, SortLinkList, sortLinkNode); + if (listSorted->responseTime <= sortList->responseTime) { + LOS_ListAdd(prevNode, &sortList->sortLinkNode); + sortLinkHeader->nodeNum++; + break; + } + + prevNode = prevNode->pstPrev; + } while (1); +} + +VOID OsAdd2SortLink(SortLinkAttribute *head, SortLinkList *node, UINT64 responseTime, UINT16 idleCpu) +{ + LOS_SpinLock(&head->spinLock); + SET_SORTLIST_VALUE(node, responseTime); + AddNode2SortLink(head, node); +#ifdef LOSCFG_KERNEL_SMP + node->cpuid = idleCpu; +#endif + LOS_SpinUnlock(&head->spinLock); +} + +VOID OsDeleteFromSortLink(SortLinkAttribute *head, SortLinkList *node) +{ + LOS_SpinLock(&head->spinLock); + if (node->responseTime != OS_SORT_LINK_INVALID_TIME) { + OsDeleteNodeSortLink(head, node); + } + LOS_SpinUnlock(&head->spinLock); +} + +UINT32 OsSortLinkAdjustNodeResponseTime(SortLinkAttribute *head, SortLinkList *node, UINT64 responseTime) +{ + UINT32 ret = LOS_NOK; + + LOS_SpinLock(&head->spinLock); + if (node->responseTime != OS_SORT_LINK_INVALID_TIME) { + OsDeleteNodeSortLink(head, node); + SET_SORTLIST_VALUE(node, responseTime); + AddNode2SortLink(head, node); + ret = LOS_OK; + } + LOS_SpinUnlock(&head->spinLock); + return ret; +} + +UINT64 OsSortLinkGetTargetExpireTime(UINT64 currTime, const SortLinkList *targetSortList) +{ + if (currTime >= targetSortList->responseTime) { + return 0; + } + + return (UINT32)(targetSortList->responseTime - currTime); +} + +UINT64 OsSortLinkGetNextExpireTime(UINT64 currTime, const SortLinkAttribute *sortLinkHeader) +{ + LOS_DL_LIST *head = (LOS_DL_LIST *)&sortLinkHeader->sortLink; + + if (LOS_ListEmpty(head)) { + return OS_SORT_LINK_INVALID_TIME; + } + + SortLinkList *listSorted = LOS_DL_LIST_ENTRY(head->pstNext, SortLinkList, sortLinkNode); + return OsSortLinkGetTargetExpireTime(currTime, listSorted); +} + diff --git a/src/kernel_liteos_a/kernel/base/sched/los_statistics.c b/src/kernel_liteos_a/kernel/base/sched/los_statistics.c new file mode 100644 index 00000000..8494bc6f --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/sched/los_statistics.c @@ -0,0 +1,345 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_statistics_pri.h" +#include "los_task_pri.h" +#include "los_process_pri.h" + +#ifdef LOSCFG_SCHED_DEBUG +#ifdef LOSCFG_SCHED_TICK_DEBUG +typedef struct { + UINT64 responseTime; + UINT64 responseTimeMax; + UINT64 count; +} SchedTickDebug; +STATIC SchedTickDebug *g_schedTickDebug = NULL; + +UINT32 OsSchedDebugInit(VOID) +{ + UINT32 size = sizeof(SchedTickDebug) * LOSCFG_KERNEL_CORE_NUM; + g_schedTickDebug = (SchedTickDebug *)LOS_MemAlloc(m_aucSysMem0, size); + if (g_schedTickDebug == NULL) { + return LOS_ERRNO_TSK_NO_MEMORY; + } + + (VOID)memset_s(g_schedTickDebug, size, 0, size); + return LOS_OK; +} + +VOID OsSchedDebugRecordData(VOID) +{ + SchedRunqueue *rq = OsSchedRunqueue(); + SchedTickDebug *schedDebug = &g_schedTickDebug[ArchCurrCpuid()]; + UINT64 currTime = OsGetCurrSchedTimeCycle(); + LOS_ASSERT(currTime >= rq->responseTime); + UINT64 usedTime = currTime - rq->responseTime; + schedDebug->responseTime += usedTime; + if (usedTime > schedDebug->responseTimeMax) { + schedDebug->responseTimeMax = usedTime; + } + schedDebug->count++; +} + +UINT32 OsShellShowTickResponse(VOID) +{ + UINT32 intSave; + UINT16 cpu; + + UINT32 tickSize = sizeof(SchedTickDebug) * LOSCFG_KERNEL_CORE_NUM; + SchedTickDebug *schedDebug = (SchedTickDebug *)LOS_MemAlloc(m_aucSysMem1, tickSize); + if (schedDebug == NULL) { + return LOS_NOK; + } + + SCHEDULER_LOCK(intSave); + (VOID)memcpy_s((CHAR *)schedDebug, tickSize, (CHAR *)g_schedTickDebug, tickSize); + SCHEDULER_UNLOCK(intSave); + + PRINTK("cpu ATRTime(us) ATRTimeMax(us) TickCount\n"); + for (cpu = 0; cpu < LOSCFG_KERNEL_CORE_NUM; cpu++) { + SchedTickDebug *schedData = &schedDebug[cpu]; + UINT64 averTime = 0; + if (schedData->count > 0) { + averTime = schedData->responseTime / schedData->count; + averTime = (averTime * OS_NS_PER_CYCLE) / OS_SYS_NS_PER_US; + } + UINT64 timeMax = (schedData->responseTimeMax * OS_NS_PER_CYCLE) / OS_SYS_NS_PER_US; + PRINTK("%3u%14llu%15llu%11llu\n", cpu, averTime, timeMax, schedData->count); + } + + (VOID)LOS_MemFree(m_aucSysMem1, schedDebug); + return LOS_OK; +} +#endif + +#ifdef LOSCFG_SCHED_HPF_DEBUG +STATIC VOID SchedDataGet(const LosTaskCB *taskCB, UINT64 *runTime, UINT64 *timeSlice, + UINT64 *pendTime, UINT64 *schedWait) +{ + if (taskCB->schedStat.switchCount >= 1) { + UINT64 averRunTime = taskCB->schedStat.runTime / taskCB->schedStat.switchCount; + *runTime = (averRunTime * OS_NS_PER_CYCLE) / OS_SYS_NS_PER_US; + } + + if (taskCB->schedStat.timeSliceCount > 1) { + UINT64 averTimeSlice = taskCB->schedStat.timeSliceTime / (taskCB->schedStat.timeSliceCount - 1); + *timeSlice = (averTimeSlice * OS_NS_PER_CYCLE) / OS_SYS_NS_PER_US; + } + + if (taskCB->schedStat.pendCount > 1) { + UINT64 averPendTime = taskCB->schedStat.pendTime / taskCB->schedStat.pendCount; + *pendTime = (averPendTime * OS_NS_PER_CYCLE) / OS_SYS_NS_PER_US; + } + + if (taskCB->schedStat.waitSchedCount > 0) { + UINT64 averSchedWait = taskCB->schedStat.waitSchedTime / taskCB->schedStat.waitSchedCount; + *schedWait = (averSchedWait * OS_NS_PER_CYCLE) / OS_SYS_NS_PER_US; + } +} + +UINT32 OsShellShowSchedStatistics(VOID) +{ + UINT32 taskLinkNum[LOSCFG_KERNEL_CORE_NUM]; + UINT32 intSave; + LosTaskCB task; + SchedEDF *sched = NULL; + + SCHEDULER_LOCK(intSave); + for (UINT16 cpu = 0; cpu < LOSCFG_KERNEL_CORE_NUM; cpu++) { + SchedRunqueue *rq = OsSchedRunqueueByID(cpu); + taskLinkNum[cpu] = OsGetSortLinkNodeNum(&rq->timeoutQueue); + } + SCHEDULER_UNLOCK(intSave); + + for (UINT16 cpu = 0; cpu < LOSCFG_KERNEL_CORE_NUM; cpu++) { + PRINTK("cpu: %u Task SortMax: %u\n", cpu, taskLinkNum[cpu]); + } + + PRINTK(" Tid AverRunTime(us) SwitchCount AverTimeSlice(us) TimeSliceCount AverReadyWait(us) " + "AverPendTime(us) TaskName \n"); + for (UINT32 tid = 0; tid < g_taskMaxNum; tid++) { + LosTaskCB *taskCB = g_taskCBArray + tid; + SCHEDULER_LOCK(intSave); + if (OsTaskIsUnused(taskCB) || (taskCB->processCB == (UINTPTR)OsGetIdleProcess())) { + SCHEDULER_UNLOCK(intSave); + continue; + } + + sched = (SchedEDF *)&taskCB->sp; + if (sched->policy == LOS_SCHED_DEADLINE) { + SCHEDULER_UNLOCK(intSave); + continue; + } + + (VOID)memcpy_s(&task, sizeof(LosTaskCB), taskCB, sizeof(LosTaskCB)); + SCHEDULER_UNLOCK(intSave); + + UINT64 averRunTime = 0; + UINT64 averTimeSlice = 0; + UINT64 averPendTime = 0; + UINT64 averSchedWait = 0; + + SchedDataGet(&task, &averRunTime, &averTimeSlice, &averPendTime, &averSchedWait); + + PRINTK("%5u%19llu%15llu%19llu%18llu%19llu%18llu %-32s\n", taskCB->taskID, + averRunTime, taskCB->schedStat.switchCount, + averTimeSlice, taskCB->schedStat.timeSliceCount - 1, + averSchedWait, averPendTime, taskCB->taskName); + } + + return LOS_OK; +} +#endif + +#ifdef LOSCFG_SCHED_EDF_DEBUG +#define EDF_DEBUG_NODE 20 +typedef struct { + UINT32 tid; + INT32 runTimeUs; + UINT64 deadlineUs; + UINT64 periodUs; + UINT64 startTime; + UINT64 finishTime; + UINT64 nextfinishTime; + UINT64 timeSliceUnused; + UINT64 timeSliceRealTime; + UINT64 allRuntime; + UINT64 pendTime; +} EDFDebug; + +STATIC EDFDebug g_edfNode[EDF_DEBUG_NODE]; +STATIC INT32 g_edfNodePointer = 0; + +VOID EDFDebugRecord(UINTPTR *task, UINT64 oldFinish) +{ + LosTaskCB *taskCB = (LosTaskCB *)task; + SchedEDF *sched = (SchedEDF *)&taskCB->sp; + SchedParam param; + + // when print edf info, will stop record + if (g_edfNodePointer == (EDF_DEBUG_NODE + 1)) { + return; + } + + taskCB->ops->schedParamGet(taskCB, ¶m); + g_edfNode[g_edfNodePointer].tid = taskCB->taskID; + g_edfNode[g_edfNodePointer].runTimeUs =param.runTimeUs; + g_edfNode[g_edfNodePointer].deadlineUs =param.deadlineUs; + g_edfNode[g_edfNodePointer].periodUs =param.periodUs; + g_edfNode[g_edfNodePointer].startTime = taskCB->startTime; + if (taskCB->timeSlice <= 0) { + taskCB->irqUsedTime = 0; + g_edfNode[g_edfNodePointer].timeSliceUnused = 0; + } else { + g_edfNode[g_edfNodePointer].timeSliceUnused = taskCB->timeSlice; + } + g_edfNode[g_edfNodePointer].finishTime = oldFinish; + g_edfNode[g_edfNodePointer].nextfinishTime = sched->finishTime; + g_edfNode[g_edfNodePointer].timeSliceRealTime = taskCB->schedStat.timeSliceRealTime; + g_edfNode[g_edfNodePointer].allRuntime = taskCB->schedStat.allRuntime; + g_edfNode[g_edfNodePointer].pendTime = taskCB->schedStat.pendTime; + + g_edfNodePointer++; + if (g_edfNodePointer == EDF_DEBUG_NODE) { + g_edfNodePointer = 0; + } +} + +STATIC VOID EDFInfoPrint(int idx) +{ + INT32 runTimeUs; + UINT64 deadlineUs; + UINT64 periodUs; + UINT64 startTime; + UINT64 timeSlice; + UINT64 finishTime; + UINT64 nextfinishTime; + UINT64 pendTime; + UINT64 allRuntime; + UINT64 timeSliceRealTime; + CHAR *status = NULL; + + startTime = OS_SYS_CYCLE_TO_US(g_edfNode[idx].startTime); + timeSlice = OS_SYS_CYCLE_TO_US(g_edfNode[idx].timeSliceUnused); + finishTime = OS_SYS_CYCLE_TO_US(g_edfNode[idx].finishTime); + nextfinishTime = OS_SYS_CYCLE_TO_US(g_edfNode[idx].nextfinishTime); + pendTime = OS_SYS_CYCLE_TO_US(g_edfNode[idx].pendTime); + allRuntime = OS_SYS_CYCLE_TO_US(g_edfNode[idx].allRuntime); + timeSliceRealTime = OS_SYS_CYCLE_TO_US(g_edfNode[idx].timeSliceRealTime); + runTimeUs = g_edfNode[idx].runTimeUs; + deadlineUs = g_edfNode[idx].deadlineUs; + periodUs = g_edfNode[idx].periodUs; + + if (timeSlice > 0) { + status = "TIMEOUT"; + } else if (nextfinishTime == finishTime) { + status = "NEXT PERIOD"; + } else { + status = "WAIT RUN"; + } + + PRINTK("%4u%9d%9llu%9llu%12llu%12llu%12llu%9llu%9llu%9llu%9llu %-12s\n", + g_edfNode[idx].tid, runTimeUs, deadlineUs, periodUs, + startTime, finishTime, nextfinishTime, allRuntime, timeSliceRealTime, + timeSlice, pendTime, status); +} + +VOID OsEDFDebugPrint(VOID) +{ + INT32 max; + UINT32 intSave; + INT32 i; + + SCHEDULER_LOCK(intSave); + max = g_edfNodePointer; + g_edfNodePointer = EDF_DEBUG_NODE + 1; + SCHEDULER_UNLOCK(intSave); + + PRINTK("\r\nlast %d sched is: (in microsecond)\r\n", EDF_DEBUG_NODE); + + PRINTK(" TID RunTime Deadline Period StartTime " + "CurPeriod NextPeriod AllRun RealRun TimeOut WaitTime Status\n"); + + for (i = max; i < EDF_DEBUG_NODE; i++) { + EDFInfoPrint(i); + } + + for (i = 0; i < max; i++) { + EDFInfoPrint(i); + } + + SCHEDULER_LOCK(intSave); + g_edfNodePointer = max; + SCHEDULER_UNLOCK(intSave); +} + +UINT32 OsShellShowEdfSchedStatistics(VOID) +{ + UINT32 intSave; + LosTaskCB task; + UINT64 curTime; + UINT64 deadline; + UINT64 finishTime; + SchedEDF *sched = NULL; + + PRINTK("Now Alive EDF Thread:\n"); + PRINTK("TID CurTime DeadTime FinishTime taskName\n"); + + for (UINT32 tid = 0; tid < g_taskMaxNum; tid++) { + LosTaskCB *taskCB = g_taskCBArray + tid; + SCHEDULER_LOCK(intSave); + if (OsTaskIsUnused(taskCB)) { + SCHEDULER_UNLOCK(intSave); + continue; + } + + sched = (SchedEDF *)&taskCB->sp; + if (sched->policy != LOS_SCHED_DEADLINE) { + SCHEDULER_UNLOCK(intSave); + continue; + } + + (VOID)memcpy_s(&task, sizeof(LosTaskCB), taskCB, sizeof(LosTaskCB)); + + curTime = OS_SYS_CYCLE_TO_US(HalClockGetCycles()); + finishTime = OS_SYS_CYCLE_TO_US(sched->finishTime); + deadline = OS_SYS_CYCLE_TO_US(taskCB->ops->deadlineGet(taskCB)); + SCHEDULER_UNLOCK(intSave); + + PRINTK("%3u%15llu%15llu%15llu %-32s\n", + task.taskID, curTime, deadline, finishTime, task.taskName); + } + + OsEDFDebugPrint(); + + return LOS_OK; +} +#endif +#endif diff --git a/src/kernel_liteos_a/kernel/base/vm/los_vm_boot.c b/src/kernel_liteos_a/kernel/base/vm/los_vm_boot.c new file mode 100644 index 00000000..81287a26 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/vm/los_vm_boot.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_vm_boot.h" +#include "los_config.h" +#include "los_base.h" +#include "los_vm_zone.h" +#include "los_vm_map.h" +#include "los_memory_pri.h" +#include "los_vm_page.h" +#include "los_arch_mmu.h" + + +UINTPTR g_vmBootMemBase = (UINTPTR)&__bss_end; +BOOL g_kHeapInited = FALSE; + +VOID *OsVmBootMemAlloc(size_t len) +{ + UINTPTR ptr; + + if (g_kHeapInited) { + VM_ERR("kernel heap has been initialized, do not to use boot memory allocation!"); + return NULL; + } + + ptr = LOS_Align(g_vmBootMemBase, sizeof(UINTPTR)); + g_vmBootMemBase = ptr + LOS_Align(len, sizeof(UINTPTR)); + + return (VOID *)ptr; +} + +UINT32 OsSysMemInit(VOID) +{ + STATUS_T ret; + +#ifdef LOSCFG_KERNEL_VM + OsKSpaceInit(); +#endif + + ret = OsKHeapInit(OS_KHEAP_BLOCK_SIZE); + if (ret != LOS_OK) { + VM_ERR("OsKHeapInit fail\n"); + return LOS_NOK; + } + +#ifdef LOSCFG_KERNEL_VM + OsVmPageStartup(); + g_kHeapInited = TRUE; + OsInitMappingStartUp(); +#else + g_kHeapInited = TRUE; +#endif + + return LOS_OK; +} diff --git a/src/kernel_liteos_a/kernel/base/vm/los_vm_dump.c b/src/kernel_liteos_a/kernel/base/vm/los_vm_dump.c new file mode 100644 index 00000000..f326ea12 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/vm/los_vm_dump.c @@ -0,0 +1,564 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_vm_dump virtual memory dump operation + * @ingroup kernel + */ + +#include "los_vm_dump.h" +#include "los_mmu_descriptor_v6.h" +#ifdef LOSCFG_FS_VFS +#include "fs/file.h" +#include "vnode.h" +#endif +#include "los_printf.h" +#include "los_vm_page.h" +#include "los_vm_phys.h" +#include "los_process_pri.h" +#include "los_atomic.h" +#include "los_vm_lock.h" +#include "los_memory_pri.h" + + +#ifdef LOSCFG_KERNEL_VM + +#define FLAG_SIZE 4 +#define FLAG_START 2 + +const CHAR *OsGetRegionNameOrFilePath(LosVmMapRegion *region) +{ + struct Vnode *vnode = NULL; + if (region == NULL) { + return ""; +#ifdef LOSCFG_FS_VFS + } else if (LOS_IsRegionFileValid(region)) { + vnode = region->unTypeData.rf.vnode; + return vnode->filePath; +#endif + } else if (region->regionFlags & VM_MAP_REGION_FLAG_HEAP) { + return "HEAP"; + } else if (region->regionFlags & VM_MAP_REGION_FLAG_STACK) { + return "STACK"; + } else if (region->regionFlags & VM_MAP_REGION_FLAG_TEXT) { + return "Text"; + } else if (region->regionFlags & VM_MAP_REGION_FLAG_VDSO) { + return "VDSO"; + } else if (region->regionFlags & VM_MAP_REGION_FLAG_MMAP) { + return "MMAP"; + } else if (region->regionFlags & VM_MAP_REGION_FLAG_SHM) { + return "SHM"; + } else { + return ""; + } + return ""; +} + +INT32 OsRegionOverlapCheckUnlock(LosVmSpace *space, LosVmMapRegion *region) +{ + LosVmMapRegion *regionTemp = NULL; + LosRbNode *pstRbNode = NULL; + LosRbNode *pstRbNodeNext = NULL; + + /* search the region list */ + RB_SCAN_SAFE(&space->regionRbTree, pstRbNode, pstRbNodeNext) + regionTemp = (LosVmMapRegion *)pstRbNode; + if (region->range.base == regionTemp->range.base && region->range.size == regionTemp->range.size) { + continue; + } + if (((region->range.base + region->range.size) > regionTemp->range.base) && + (region->range.base < (regionTemp->range.base + regionTemp->range.size))) { + VM_ERR("overlap between regions:\n" + "flags:%#x base:%p size:%08x space:%p\n" + "flags:%#x base:%p size:%08x space:%p", + region->regionFlags, region->range.base, region->range.size, region->space, + regionTemp->regionFlags, regionTemp->range.base, regionTemp->range.size, regionTemp->space); + return -1; + } + RB_SCAN_SAFE_END(&space->regionRbTree, pstRbNode, pstRbNodeNext) + + return 0; +} + +UINT32 OsShellCmdProcessVmUsage(LosVmSpace *space) +{ + LosVmMapRegion *region = NULL; + LosRbNode *pstRbNode = NULL; + LosRbNode *pstRbNodeNext = NULL; + UINT32 used = 0; + + if (space == NULL) { + return 0; + } + + if (space == LOS_GetKVmSpace()) { + OsShellCmdProcessPmUsage(space, NULL, &used); + return used; + } + UINT32 ret = LOS_MuxAcquire(&space->regionMux); + if (ret != 0) { + return 0; + } + + RB_SCAN_SAFE(&space->regionRbTree, pstRbNode, pstRbNodeNext) + region = (LosVmMapRegion *)pstRbNode; + used += region->range.size; + RB_SCAN_SAFE_END(&space->regionRbTree, pstRbNode, pstRbNodeNext) + (VOID)LOS_MuxRelease(&space->regionMux); + return used; +} + +UINT32 OsKProcessPmUsage(LosVmSpace *kSpace, UINT32 *actualPm) +{ + UINT32 memUsed; + UINT32 totalMem; + UINT32 freeMem; + UINT32 usedCount = 0; + UINT32 totalCount = 0; + LosVmSpace *space = NULL; + LOS_DL_LIST *spaceList = NULL; + UINT32 UProcessUsed = 0; + + if (actualPm == NULL) { + return 0; + } + + memUsed = LOS_MemTotalUsedGet(m_aucSysMem1); + totalMem = LOS_MemPoolSizeGet(m_aucSysMem1); + freeMem = totalMem - memUsed; + + OsVmPhysUsedInfoGet(&usedCount, &totalCount); + /* Kernel resident memory, include default heap memory */ + memUsed = SYS_MEM_SIZE_DEFAULT - (totalCount << PAGE_SHIFT); + + spaceList = LOS_GetVmSpaceList(); + LosMux *vmSpaceListMux = OsGVmSpaceMuxGet(); + (VOID)LOS_MuxAcquire(vmSpaceListMux); + LOS_DL_LIST_FOR_EACH_ENTRY(space, spaceList, LosVmSpace, node) { + if (space == LOS_GetKVmSpace()) { + continue; + } + UProcessUsed += OsUProcessPmUsage(space, NULL, NULL); + } + (VOID)LOS_MuxRelease(vmSpaceListMux); + + /* Kernel dynamic memory, include extended heap memory */ + memUsed += ((usedCount << PAGE_SHIFT) - UProcessUsed); + /* Remaining heap memory */ + memUsed -= freeMem; + + *actualPm = memUsed; + return memUsed; +} + +UINT32 OsShellCmdProcessPmUsage(LosVmSpace *space, UINT32 *sharePm, UINT32 *actualPm) +{ + if (space == NULL) { + return 0; + } + + if ((sharePm == NULL) && (actualPm == NULL)) { + return 0; + } + + if (space == LOS_GetKVmSpace()) { + return OsKProcessPmUsage(space, actualPm); + } + return OsUProcessPmUsage(space, sharePm, actualPm); +} + +UINT32 OsUProcessPmUsage(LosVmSpace *space, UINT32 *sharePm, UINT32 *actualPm) +{ + LosVmMapRegion *region = NULL; + LosRbNode *pstRbNode = NULL; + LosRbNode *pstRbNodeNext = NULL; + LosVmPage *page = NULL; + VADDR_T vaddr; + size_t size; + PADDR_T paddr; + STATUS_T ret; + INT32 shareRef; + UINT32 pmSize = 0; + + if (sharePm != NULL) { + *sharePm = 0; + } + + ret = LOS_MuxAcquire(&space->regionMux); + if (ret != 0) { + return 0; + } + RB_SCAN_SAFE(&space->regionRbTree, pstRbNode, pstRbNodeNext) + region = (LosVmMapRegion *)pstRbNode; + vaddr = region->range.base; + size = region->range.size; + for (; size > 0; vaddr += PAGE_SIZE, size -= PAGE_SIZE) { + ret = LOS_ArchMmuQuery(&space->archMmu, vaddr, &paddr, NULL); + if (ret < 0) { + continue; + } + page = LOS_VmPageGet(paddr); + if (page == NULL) { + continue; + } + + shareRef = LOS_AtomicRead(&page->refCounts); + if (shareRef > 1) { + if (sharePm != NULL) { + *sharePm += PAGE_SIZE; + } + pmSize += PAGE_SIZE / shareRef; + } else { + pmSize += PAGE_SIZE; + } + } + RB_SCAN_SAFE_END(&oldVmSpace->regionRbTree, pstRbNode, pstRbNodeNext) + + (VOID)LOS_MuxRelease(&space->regionMux); + + if (actualPm != NULL) { + *actualPm = pmSize; + } + + return pmSize; +} + +LosProcessCB *OsGetPIDByAspace(const LosVmSpace *space) +{ + UINT32 pid; + UINT32 intSave; + LosProcessCB *processCB = NULL; + + SCHEDULER_LOCK(intSave); + for (pid = 0; pid < g_processMaxNum; ++pid) { + processCB = g_processCBArray + pid; + if (OsProcessIsUnused(processCB)) { + continue; + } + + if (processCB->vmSpace == space) { + SCHEDULER_UNLOCK(intSave); + return processCB; + } + } + SCHEDULER_UNLOCK(intSave); + return NULL; +} + +UINT32 OsCountRegionPages(LosVmSpace *space, LosVmMapRegion *region, UINT32 *pssPages) +{ + UINT32 regionPages = 0; + PADDR_T paddr; + VADDR_T vaddr; + UINT32 ref; + STATUS_T status; + float pss = 0; + LosVmPage *page = NULL; + + for (vaddr = region->range.base; vaddr < region->range.base + region->range.size; vaddr = vaddr + PAGE_SIZE) { + status = LOS_ArchMmuQuery(&space->archMmu, vaddr, &paddr, NULL); + if (status == LOS_OK) { + regionPages++; + if (pssPages == NULL) { + continue; + } + page = LOS_VmPageGet(paddr); + if (page != NULL) { + ref = LOS_AtomicRead(&page->refCounts); + pss += ((ref > 0) ? (1.0 / ref) : 1); + } else { + pss += 1; + } + } + } + + if (pssPages != NULL) { + *pssPages = (UINT32)(pss + 0.5); /* 0.5, for page alignment */ + } + + return regionPages; +} + +UINT32 OsCountAspacePages(LosVmSpace *space) +{ + UINT32 spacePages = 0; + LosVmMapRegion *region = NULL; + LosRbNode *pstRbNode = NULL; + LosRbNode *pstRbNodeNext = NULL; + + RB_SCAN_SAFE(&space->regionRbTree, pstRbNode, pstRbNodeNext) + region = (LosVmMapRegion *)pstRbNode; + spacePages += OsCountRegionPages(space, region, NULL); + RB_SCAN_SAFE_END(&space->regionRbTree, pstRbNode, pstRbNodeNext) + return spacePages; +} + +CHAR *OsArchFlagsToStr(const UINT32 archFlags) +{ + UINT32 index; + UINT32 cacheFlags = archFlags & VM_MAP_REGION_FLAG_CACHE_MASK; + UINT32 flagSize = FLAG_SIZE * BITMAP_BITS_PER_WORD * sizeof(CHAR); + CHAR *archMmuFlagsStr = (CHAR *)LOS_MemAlloc(m_aucSysMem0, flagSize); + if (archMmuFlagsStr == NULL) { + return NULL; + } + (VOID)memset_s(archMmuFlagsStr, flagSize, 0, flagSize); + switch (cacheFlags) { + case 0UL: + (VOID)strcat_s(archMmuFlagsStr, flagSize, " CH\0"); + break; + case 1UL: + (VOID)strcat_s(archMmuFlagsStr, flagSize, " UC\0"); + break; + case 2UL: + (VOID)strcat_s(archMmuFlagsStr, flagSize, " UD\0"); + break; + case 3UL: + (VOID)strcat_s(archMmuFlagsStr, flagSize, " WC\0"); + break; + default: + break; + } + + static const CHAR FLAGS[BITMAP_BITS_PER_WORD][FLAG_SIZE] = { + [0 ... (__builtin_ffsl(VM_MAP_REGION_FLAG_PERM_USER) - 2)] = "???\0", + [__builtin_ffsl(VM_MAP_REGION_FLAG_PERM_USER) - 1] = " US\0", + [__builtin_ffsl(VM_MAP_REGION_FLAG_PERM_READ) - 1] = " RD\0", + [__builtin_ffsl(VM_MAP_REGION_FLAG_PERM_WRITE) - 1] = " WR\0", + [__builtin_ffsl(VM_MAP_REGION_FLAG_PERM_EXECUTE) - 1] = " EX\0", + [__builtin_ffsl(VM_MAP_REGION_FLAG_NS) - 1] = " NS\0", + [__builtin_ffsl(VM_MAP_REGION_FLAG_INVALID) - 1] = " IN\0", + [__builtin_ffsl(VM_MAP_REGION_FLAG_INVALID) ... (BITMAP_BITS_PER_WORD - 1)] = "???\0", + }; + + for (index = FLAG_START; index < BITMAP_BITS_PER_WORD; index++) { + if (FLAGS[index][0] == '?') { + continue; + } + + if (archFlags & (1UL << index)) { + UINT32 status = strcat_s(archMmuFlagsStr, flagSize, FLAGS[index]); + if (status != 0) { + PRINTK("error\n"); + } + } + } + + return archMmuFlagsStr; +} + +VOID OsDumpRegion2(LosVmSpace *space, LosVmMapRegion *region) +{ + UINT32 pssPages = 0; + UINT32 regionPages; + + regionPages = OsCountRegionPages(space, region, &pssPages); + CHAR *flagsStr = OsArchFlagsToStr(region->regionFlags); + if (flagsStr == NULL) { + return; + } + PRINTK("\t %#010x %-32.32s %#010x %#010x %-15.15s %4d %4d\n", + region, OsGetRegionNameOrFilePath(region), region->range.base, + region->range.size, flagsStr, regionPages, pssPages); + (VOID)LOS_MemFree(m_aucSysMem0, flagsStr); +} + +VOID OsDumpAspace(LosVmSpace *space) +{ + LosVmMapRegion *region = NULL; + LosRbNode *pstRbNode = NULL; + LosRbNode *pstRbNodeNext = NULL; + UINT32 spacePages; + LosProcessCB *pcb = OsGetPIDByAspace(space); + + if (pcb == NULL) { + return; + } + + spacePages = OsCountAspacePages(space); + PRINTK("\r\n PID aspace name base size pages \n"); + PRINTK(" ---- ------ ---- ---- ----- ----\n"); + PRINTK(" %-4d %#010x %-10.10s %#010x %#010x %d\n", pcb->processID, space, pcb->processName, + space->base, space->size, spacePages); + PRINTK("\r\n\t region name base size mmu_flags pages pg/ref\n"); + PRINTK("\t ------ ---- ---- ---- --------- ----- -----\n"); + RB_SCAN_SAFE(&space->regionRbTree, pstRbNode, pstRbNodeNext) + region = (LosVmMapRegion *)pstRbNode; + if (region != NULL) { + OsDumpRegion2(space, region); + (VOID)OsRegionOverlapCheck(space, region); + } else { + PRINTK("region is NULL\n"); + } + RB_SCAN_SAFE_END(&space->regionRbTree, pstRbNode, pstRbNodeNext) + return; +} + +VOID OsDumpAllAspace(VOID) +{ + LosVmSpace *space = NULL; + LOS_DL_LIST *aspaceList = LOS_GetVmSpaceList(); + LOS_DL_LIST_FOR_EACH_ENTRY(space, aspaceList, LosVmSpace, node) { + (VOID)LOS_MuxAcquire(&space->regionMux); + OsDumpAspace(space); + (VOID)LOS_MuxRelease(&space->regionMux); + } + return; +} + +STATUS_T OsRegionOverlapCheck(LosVmSpace *space, LosVmMapRegion *region) +{ + int ret; + + if (space == NULL || region == NULL) { + return -1; + } + + (VOID)LOS_MuxAcquire(&space->regionMux); + ret = OsRegionOverlapCheckUnlock(space, region); + (VOID)LOS_MuxRelease(&space->regionMux); + return ret; +} + +VOID OsDumpPte(VADDR_T vaddr) +{ + UINT32 l1Index = vaddr >> MMU_DESCRIPTOR_L1_SMALL_SHIFT; + LosVmSpace *space = LOS_SpaceGet(vaddr); + UINT32 ttEntry; + LosVmPage *page = NULL; + PTE_T *l2Table = NULL; + UINT32 l2Index; + + if (space == NULL) { + return; + } + + ttEntry = space->archMmu.virtTtb[l1Index]; + if (ttEntry) { + l2Table = LOS_PaddrToKVaddr(MMU_DESCRIPTOR_L1_PAGE_TABLE_ADDR(ttEntry)); + l2Index = (vaddr % MMU_DESCRIPTOR_L1_SMALL_SIZE) >> PAGE_SHIFT; + if (l2Table == NULL) { + goto ERR; + } + page = LOS_VmPageGet(l2Table[l2Index] & ~(PAGE_SIZE - 1)); + if (page == NULL) { + goto ERR; + } + PRINTK("vaddr %p, l1Index %d, ttEntry %p, l2Table %p, l2Index %d, pfn %p count %d\n", + vaddr, l1Index, ttEntry, l2Table, l2Index, l2Table[l2Index], LOS_AtomicRead(&page->refCounts)); + } else { + PRINTK("vaddr %p, l1Index %d, ttEntry %p\n", vaddr, l1Index, ttEntry); + } + return; +ERR: + PRINTK("%s, error vaddr: %#x, l2Table: %#x, l2Index: %#x\n", __FUNCTION__, vaddr, l2Table, l2Index); +} + +UINT32 OsVmPhySegPagesGet(LosVmPhysSeg *seg) +{ + UINT32 intSave; + UINT32 flindex; + UINT32 segFreePages = 0; + + LOS_SpinLockSave(&seg->freeListLock, &intSave); + for (flindex = 0; flindex < VM_LIST_ORDER_MAX; flindex++) { + segFreePages += ((1 << flindex) * seg->freeList[flindex].listCnt); + } + LOS_SpinUnlockRestore(&seg->freeListLock, intSave); + + return segFreePages; +} + +VOID OsVmPhysDump(VOID) +{ + LosVmPhysSeg *seg = NULL; + UINT32 segFreePages; + UINT32 totalFreePages = 0; + UINT32 totalPages = 0; + UINT32 segIndex; + UINT32 intSave; + UINT32 flindex; + UINT32 listCount[VM_LIST_ORDER_MAX] = {0}; + + for (segIndex = 0; segIndex < g_vmPhysSegNum; segIndex++) { + seg = &g_vmPhysSeg[segIndex]; + if (seg->size > 0) { + segFreePages = OsVmPhySegPagesGet(seg); +#ifdef LOSCFG_SHELL_CMD_DEBUG + PRINTK("\r\n phys_seg base size free_pages \n"); + PRINTK(" -------- ------- ---------- --------- \n"); +#endif + PRINTK(" 0x%08x 0x%08x 0x%08x %8u \n", seg, seg->start, seg->size, segFreePages); + totalFreePages += segFreePages; + totalPages += (seg->size >> PAGE_SHIFT); + + LOS_SpinLockSave(&seg->freeListLock, &intSave); + for (flindex = 0; flindex < VM_LIST_ORDER_MAX; flindex++) { + listCount[flindex] = seg->freeList[flindex].listCnt; + } + LOS_SpinUnlockRestore(&seg->freeListLock, intSave); + for (flindex = 0; flindex < VM_LIST_ORDER_MAX; flindex++) { + PRINTK("order = %d, free_count = %d\n", flindex, listCount[flindex]); + } + + PRINTK("active anon %d\n", seg->lruSize[VM_LRU_ACTIVE_ANON]); + PRINTK("inactive anon %d\n", seg->lruSize[VM_LRU_INACTIVE_ANON]); + PRINTK("active file %d\n", seg->lruSize[VM_LRU_ACTIVE_FILE]); + PRINTK("inactive file %d\n", seg->lruSize[VM_LRU_INACTIVE_FILE]); + } + } + PRINTK("\n\rpmm pages: total = %u, used = %u, free = %u\n", + totalPages, (totalPages - totalFreePages), totalFreePages); +} + +VOID OsVmPhysUsedInfoGet(UINT32 *usedCount, UINT32 *totalCount) +{ + UINT32 index; + UINT32 segFreePages; + LosVmPhysSeg *physSeg = NULL; + + if (usedCount == NULL || totalCount == NULL) { + return; + } + *usedCount = 0; + *totalCount = 0; + + for (index = 0; index < g_vmPhysSegNum; index++) { + physSeg = &g_vmPhysSeg[index]; + if (physSeg->size > 0) { + *totalCount += physSeg->size >> PAGE_SHIFT; + segFreePages = OsVmPhySegPagesGet(physSeg); + *usedCount += (*totalCount - segFreePages); + } + } +} +#endif + diff --git a/src/kernel_liteos_a/kernel/base/vm/los_vm_fault.c b/src/kernel_liteos_a/kernel/base/vm/los_vm_fault.c new file mode 100644 index 00000000..86b08199 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/vm/los_vm_fault.c @@ -0,0 +1,467 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_vm_fault vm fault definition + * @ingroup kernel + */ +#include "los_vm_fault.h" +#include "los_vm_map.h" +#include "los_vm_dump.h" +#include "los_vm_filemap.h" +#include "los_vm_page.h" +#include "los_vm_lock.h" +#include "los_exc.h" +#include "los_oom.h" +#include "los_printf.h" +#include "los_process_pri.h" +#include "arm.h" + +#ifdef LOSCFG_FS_VFS +#include "vnode.h" +#endif + + +#ifdef LOSCFG_KERNEL_VM + +extern char __exc_table_start[]; +extern char __exc_table_end[]; + +STATIC STATUS_T OsVmRegionPermissionCheck(LosVmMapRegion *region, UINT32 flags) +{ + if ((region->regionFlags & VM_MAP_REGION_FLAG_PERM_READ) != VM_MAP_REGION_FLAG_PERM_READ) { + VM_ERR("read permission check failed operation flags %x, region flags %x", flags, region->regionFlags); + return LOS_NOK; + } + + if ((flags & VM_MAP_PF_FLAG_WRITE) == VM_MAP_PF_FLAG_WRITE) { + if ((region->regionFlags & VM_MAP_REGION_FLAG_PERM_WRITE) != VM_MAP_REGION_FLAG_PERM_WRITE) { + VM_ERR("write permission check failed operation flags %x, region flags %x", flags, region->regionFlags); + return LOS_NOK; + } + } + + if ((flags & VM_MAP_PF_FLAG_INSTRUCTION) == VM_MAP_PF_FLAG_INSTRUCTION) { + if ((region->regionFlags & VM_MAP_REGION_FLAG_PERM_EXECUTE) != VM_MAP_REGION_FLAG_PERM_EXECUTE) { + VM_ERR("exec permission check failed operation flags %x, region flags %x", flags, region->regionFlags); + return LOS_NOK; + } + } + + return LOS_OK; +} + +STATIC VOID OsFaultTryFixup(ExcContext *frame, VADDR_T excVaddr, STATUS_T *status) +{ + INT32 tableNum = (__exc_table_end - __exc_table_start) / sizeof(LosExcTable); + LosExcTable *excTable = (LosExcTable *)__exc_table_start; + + if ((frame->regCPSR & CPSR_MODE_MASK) != CPSR_MODE_USR) { + for (int i = 0; i < tableNum; ++i, ++excTable) { + if (frame->PC == (UINTPTR)excTable->excAddr) { + frame->PC = (UINTPTR)excTable->fixAddr; + frame->R2 = (UINTPTR)excVaddr; + *status = LOS_OK; + return; + } + } + } +} + +#ifdef LOSCFG_FS_VFS +STATIC STATUS_T OsDoReadFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault) +{ + status_t ret; + PADDR_T paddr; + LosVmPage *page = NULL; + VADDR_T vaddr = (VADDR_T)vmPgFault->vaddr; + LosVmSpace *space = region->space; + + ret = LOS_ArchMmuQuery(&space->archMmu, vaddr, NULL, NULL); + if (ret == LOS_OK) { + return LOS_OK; + } + if (region->unTypeData.rf.vmFOps == NULL || region->unTypeData.rf.vmFOps->fault == NULL) { + VM_ERR("region args invalid, file path: %s", region->unTypeData.rf.vnode->filePath); + return LOS_ERRNO_VM_INVALID_ARGS; + } + + (VOID)LOS_MuxAcquire(®ion->unTypeData.rf.vnode->mapping.mux_lock); + ret = region->unTypeData.rf.vmFOps->fault(region, vmPgFault); + if (ret == LOS_OK) { + paddr = LOS_PaddrQuery(vmPgFault->pageKVaddr); + page = LOS_VmPageGet(paddr); + if (page != NULL) { /* just incase of page null */ + LOS_AtomicInc(&page->refCounts); + OsCleanPageLocked(page); + } + ret = LOS_ArchMmuMap(&space->archMmu, vaddr, paddr, 1, + region->regionFlags & (~VM_MAP_REGION_FLAG_PERM_WRITE)); + if (ret < 0) { + VM_ERR("LOS_ArchMmuMap failed"); + OsDelMapInfo(region, vmPgFault, false); + (VOID)LOS_MuxRelease(®ion->unTypeData.rf.vnode->mapping.mux_lock); + return LOS_ERRNO_VM_NO_MEMORY; + } + + (VOID)LOS_MuxRelease(®ion->unTypeData.rf.vnode->mapping.mux_lock); + return LOS_OK; + } + (VOID)LOS_MuxRelease(®ion->unTypeData.rf.vnode->mapping.mux_lock); + + return LOS_ERRNO_VM_NO_MEMORY; +} + +/* unmap a page when cow happened only */ +STATIC LosVmPage *OsCowUnmapOrg(LosArchMmu *archMmu, LosVmMapRegion *region, LosVmPgFault *vmf) +{ + UINT32 intSave; + LosVmPage *oldPage = NULL; + LosMapInfo *mapInfo = NULL; + LosFilePage *fpage = NULL; + VADDR_T vaddr = (VADDR_T)vmf->vaddr; + + LOS_SpinLockSave(®ion->unTypeData.rf.vnode->mapping.list_lock, &intSave); + fpage = OsFindGetEntry(®ion->unTypeData.rf.vnode->mapping, vmf->pgoff); + if (fpage != NULL) { + oldPage = fpage->vmPage; + OsSetPageLocked(oldPage); + mapInfo = OsGetMapInfo(fpage, archMmu, vaddr); + if (mapInfo != NULL) { + OsUnmapPageLocked(fpage, mapInfo); + } else { + LOS_ArchMmuUnmap(archMmu, vaddr, 1); + } + } else { + LOS_ArchMmuUnmap(archMmu, vaddr, 1); + } + LOS_SpinUnlockRestore(®ion->unTypeData.rf.vnode->mapping.list_lock, intSave); + + return oldPage; +} +#endif + +status_t OsDoCowFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault) +{ + STATUS_T ret; + VOID *kvaddr = NULL; + PADDR_T oldPaddr = 0; + PADDR_T newPaddr; + LosVmPage *oldPage = NULL; + LosVmPage *newPage = NULL; + LosVmSpace *space = NULL; + + if ((vmPgFault == NULL) || (region == NULL) || + (region->unTypeData.rf.vmFOps == NULL) || (region->unTypeData.rf.vmFOps->fault == NULL)) { + VM_ERR("region args invalid"); + return LOS_ERRNO_VM_INVALID_ARGS; + } + + space = region->space; + ret = LOS_ArchMmuQuery(&space->archMmu, (VADDR_T)vmPgFault->vaddr, &oldPaddr, NULL); + if (ret == LOS_OK) { + oldPage = OsCowUnmapOrg(&space->archMmu, region, vmPgFault); + } + + newPage = LOS_PhysPageAlloc(); + if (newPage == NULL) { + VM_ERR("LOS_PhysPageAlloc failed"); + ret = LOS_ERRNO_VM_NO_MEMORY; + goto ERR_OUT; + } + + newPaddr = VM_PAGE_TO_PHYS(newPage); + kvaddr = OsVmPageToVaddr(newPage); + + (VOID)LOS_MuxAcquire(®ion->unTypeData.rf.vnode->mapping.mux_lock); + ret = region->unTypeData.rf.vmFOps->fault(region, vmPgFault); + if (ret != LOS_OK) { + VM_ERR("call region->vm_ops->fault fail"); + (VOID)LOS_MuxRelease(®ion->unTypeData.rf.vnode->mapping.mux_lock); + goto ERR_OUT; + } + + /** + * here we get two conditions, 1.this page hasn't mapped or mapped from pagecache, + * we can take it as a normal file cow map. 2.this page has done file cow map, + * we can take it as a anonymous cow map. + */ + if ((oldPaddr == 0) || (LOS_PaddrToKVaddr(oldPaddr) == vmPgFault->pageKVaddr)) { + (VOID)memcpy_s(kvaddr, PAGE_SIZE, vmPgFault->pageKVaddr, PAGE_SIZE); + LOS_AtomicInc(&newPage->refCounts); + OsCleanPageLocked(LOS_VmPageGet(LOS_PaddrQuery(vmPgFault->pageKVaddr))); + } else { + OsPhysSharePageCopy(oldPaddr, &newPaddr, newPage); + /* use old page free the new one */ + if (newPaddr == oldPaddr) { + LOS_PhysPageFree(newPage); + newPage = NULL; + } + } + + ret = LOS_ArchMmuMap(&space->archMmu, (VADDR_T)vmPgFault->vaddr, newPaddr, 1, region->regionFlags); + if (ret < 0) { + VM_ERR("LOS_ArchMmuMap failed"); + ret = LOS_ERRNO_VM_NO_MEMORY; + (VOID)LOS_MuxRelease(®ion->unTypeData.rf.vnode->mapping.mux_lock); + goto ERR_OUT; + } + (VOID)LOS_MuxRelease(®ion->unTypeData.rf.vnode->mapping.mux_lock); + + if (oldPage != NULL) { + OsCleanPageLocked(oldPage); + } + + return LOS_OK; + +ERR_OUT: + if (newPage != NULL) { + LOS_PhysPageFree(newPage); + } + if (oldPage != NULL) { + OsCleanPageLocked(oldPage); + } + + return ret; +} + +status_t OsDoSharedFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault) +{ + STATUS_T ret; + UINT32 intSave; + PADDR_T paddr = 0; + VADDR_T vaddr = (VADDR_T)vmPgFault->vaddr; + LosVmSpace *space = region->space; + LosVmPage *page = NULL; + LosFilePage *fpage = NULL; + + if ((region->unTypeData.rf.vmFOps == NULL) || (region->unTypeData.rf.vmFOps->fault == NULL)) { + VM_ERR("region args invalid"); + return LOS_ERRNO_VM_INVALID_ARGS; + } + + ret = LOS_ArchMmuQuery(&space->archMmu, vmPgFault->vaddr, &paddr, NULL); + if (ret == LOS_OK) { + LOS_ArchMmuUnmap(&space->archMmu, vmPgFault->vaddr, 1); + ret = LOS_ArchMmuMap(&space->archMmu, vaddr, paddr, 1, region->regionFlags); + if (ret < 0) { + VM_ERR("LOS_ArchMmuMap failed. ret=%d", ret); + return LOS_ERRNO_VM_NO_MEMORY; + } + + LOS_SpinLockSave(®ion->unTypeData.rf.vnode->mapping.list_lock, &intSave); + fpage = OsFindGetEntry(®ion->unTypeData.rf.vnode->mapping, vmPgFault->pgoff); + if (fpage) { + OsMarkPageDirty(fpage, region, 0, 0); + } + LOS_SpinUnlockRestore(®ion->unTypeData.rf.vnode->mapping.list_lock, intSave); + + return LOS_OK; + } + + (VOID)LOS_MuxAcquire(®ion->unTypeData.rf.vnode->mapping.mux_lock); + ret = region->unTypeData.rf.vmFOps->fault(region, vmPgFault); + if (ret == LOS_OK) { + paddr = LOS_PaddrQuery(vmPgFault->pageKVaddr); + page = LOS_VmPageGet(paddr); + /* just in case of page null */ + if (page != NULL) { + LOS_AtomicInc(&page->refCounts); + OsCleanPageLocked(page); + } + ret = LOS_ArchMmuMap(&space->archMmu, vaddr, paddr, 1, region->regionFlags); + if (ret < 0) { + VM_ERR("LOS_ArchMmuMap failed. ret=%d", ret); + OsDelMapInfo(region, vmPgFault, TRUE); + (VOID)LOS_MuxRelease(®ion->unTypeData.rf.vnode->mapping.mux_lock); + return LOS_ERRNO_VM_NO_MEMORY; + } + + (VOID)LOS_MuxRelease(®ion->unTypeData.rf.vnode->mapping.mux_lock); + return LOS_OK; + } + (VOID)LOS_MuxRelease(®ion->unTypeData.rf.vnode->mapping.mux_lock); + return ret; +} + +/** + * Page read operation is a simple case, just share the pagecache(save memory) + * and make a read permission mmapping (region->arch_mmu_flags & (~ARCH_MMU_FLAG_PERM_WRITE)). + * However for write operation, vmflag (VM_PRIVATE|VM_SHREAD) decides COW or SHARED fault. + * For COW fault, pagecache is copied to private anonyous pages and the changes on this page + * won't write through to the underlying file. For SHARED fault, pagecache is mapping with + * region->arch_mmu_flags and the changes on this page will write through to the underlying file + */ +STATIC STATUS_T OsDoFileFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault, UINT32 flags) +{ + STATUS_T ret; + + if (flags & VM_MAP_PF_FLAG_WRITE) { + if (region->regionFlags & VM_MAP_REGION_FLAG_SHARED) { + ret = OsDoSharedFault(region, vmPgFault); + } else { + ret = OsDoCowFault(region, vmPgFault); + } + } else { + ret = OsDoReadFault(region, vmPgFault); + } + return ret; +} + +STATUS_T OsVmPageFaultHandler(VADDR_T vaddr, UINT32 flags, ExcContext *frame) +{ + LosVmSpace *space = LOS_SpaceGet(vaddr); + LosVmMapRegion *region = NULL; + STATUS_T status; + PADDR_T oldPaddr; + PADDR_T newPaddr; + VADDR_T excVaddr = vaddr; + LosVmPage *newPage = NULL; + LosVmPgFault vmPgFault = { 0 }; + + if (space == NULL) { + VM_ERR("vm space not exists, vaddr: %#x", vaddr); + status = LOS_ERRNO_VM_NOT_FOUND; + OsFaultTryFixup(frame, excVaddr, &status); + return status; + } + + if (((flags & VM_MAP_PF_FLAG_USER) != 0) && (!LOS_IsUserAddress(vaddr))) { + VM_ERR("user space not allowed to access invalid address: %#x", vaddr); + return LOS_ERRNO_VM_ACCESS_DENIED; + } + +#ifdef LOSCFG_KERNEL_PLIMITS + if (OsMemLimitCheckAndMemAdd(PAGE_SIZE) != LOS_OK) { + return LOS_ERRNO_VM_NO_MEMORY; + } +#endif + + (VOID)LOS_MuxAcquire(&space->regionMux); + region = LOS_RegionFind(space, vaddr); + if (region == NULL) { + VM_ERR("region not exists, vaddr: %#x", vaddr); + status = LOS_ERRNO_VM_NOT_FOUND; + goto CHECK_FAILED; + } + + status = OsVmRegionPermissionCheck(region, flags); + if (status != LOS_OK) { + status = LOS_ERRNO_VM_ACCESS_DENIED; + goto CHECK_FAILED; + } + + if (OomCheckProcess()) { + /* + * under low memory, when user process request memory allocation + * it will fail, and result is LOS_NOK and current user process + * will be deleted. memory usage detail will be printed. + */ + status = LOS_ERRNO_VM_NO_MEMORY; + goto CHECK_FAILED; + } + + vaddr = ROUNDDOWN(vaddr, PAGE_SIZE); +#ifdef LOSCFG_FS_VFS + if (LOS_IsRegionFileValid(region)) { + if (region->unTypeData.rf.vnode == NULL) { + goto CHECK_FAILED; + } + vmPgFault.vaddr = vaddr; + vmPgFault.pgoff = ((vaddr - region->range.base) >> PAGE_SHIFT) + region->pgOff; + vmPgFault.flags = flags; + vmPgFault.pageKVaddr = NULL; + + status = OsDoFileFault(region, &vmPgFault, flags); + if (status) { + VM_ERR("vm fault error, status=%d", status); + goto CHECK_FAILED; + } + goto DONE; + } +#endif + + newPage = LOS_PhysPageAlloc(); + if (newPage == NULL) { + status = LOS_ERRNO_VM_NO_MEMORY; + goto CHECK_FAILED; + } + + newPaddr = VM_PAGE_TO_PHYS(newPage); + (VOID)memset_s(OsVmPageToVaddr(newPage), PAGE_SIZE, 0, PAGE_SIZE); + status = LOS_ArchMmuQuery(&space->archMmu, vaddr, &oldPaddr, NULL); + if (status >= 0) { + LOS_ArchMmuUnmap(&space->archMmu, vaddr, 1); + OsPhysSharePageCopy(oldPaddr, &newPaddr, newPage); + /* use old page free the new one */ + if (newPaddr == oldPaddr) { + LOS_PhysPageFree(newPage); + newPage = NULL; + } + + /* map all of the pages */ + status = LOS_ArchMmuMap(&space->archMmu, vaddr, newPaddr, 1, region->regionFlags); + if (status < 0) { + VM_ERR("failed to map replacement page, status:%d", status); + status = LOS_ERRNO_VM_MAP_FAILED; + goto VMM_MAP_FAILED; + } + + status = LOS_OK; + goto DONE; + } else { + /* map all of the pages */ + LOS_AtomicInc(&newPage->refCounts); + status = LOS_ArchMmuMap(&space->archMmu, vaddr, newPaddr, 1, region->regionFlags); + if (status < 0) { + VM_ERR("failed to map page, status:%d", status); + status = LOS_ERRNO_VM_MAP_FAILED; + goto VMM_MAP_FAILED; + } + } + + status = LOS_OK; + goto DONE; +VMM_MAP_FAILED: + if (newPage != NULL) { + LOS_PhysPageFree(newPage); + } +CHECK_FAILED: + OsFaultTryFixup(frame, excVaddr, &status); +#ifdef LOSCFG_KERNEL_PLIMITS + OsMemLimitMemFree(PAGE_SIZE); +#endif +DONE: + (VOID)LOS_MuxRelease(&space->regionMux); + return status; +} +#endif + diff --git a/src/kernel_liteos_a/kernel/base/vm/los_vm_filemap.c b/src/kernel_liteos_a/kernel/base/vm/los_vm_filemap.c new file mode 100644 index 00000000..e95cd826 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/vm/los_vm_filemap.c @@ -0,0 +1,612 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_vm_filemap vm filemap definition + * @ingroup kernel + */ + +#include "los_vm_filemap.h" +#include "los_vm_page.h" +#include "los_vm_phys.h" +#include "los_vm_common.h" +#include "los_vm_fault.h" +#include "los_process_pri.h" +#include "los_vm_lock.h" +#ifdef LOSCFG_FS_VFS +#include "vnode.h" +#endif + +#ifndef UNUSED +#define UNUSED(x) (VOID)(x) +#endif + +#ifdef LOSCFG_DEBUG_VERSION +static int g_totalPageCacheTry = 0; +static int g_totalPageCacheHit = 0; +#define TRACE_TRY_CACHE() do { g_totalPageCacheTry++; } while (0) +#define TRACE_HIT_CACHE() do { g_totalPageCacheHit++; } while (0) + +VOID ResetPageCacheHitInfo(int *try, int *hit) +{ + *try = g_totalPageCacheTry; + *hit = g_totalPageCacheHit; + g_totalPageCacheHit = 0; + g_totalPageCacheTry = 0; +} +#else +#define TRACE_TRY_CACHE() +#define TRACE_HIT_CACHE() +#endif + +#ifdef LOSCFG_KERNEL_VM + +STATIC VOID OsPageCacheAdd(LosFilePage *page, struct page_mapping *mapping, VM_OFFSET_T pgoff) +{ + LosFilePage *fpage = NULL; + + LOS_DL_LIST_FOR_EACH_ENTRY(fpage, &mapping->page_list, LosFilePage, node) { + if (fpage->pgoff > pgoff) { + LOS_ListTailInsert(&fpage->node, &page->node); + goto done_add; + } + } + + LOS_ListTailInsert(&mapping->page_list, &page->node); + +done_add: + mapping->nrpages++; +} + +VOID OsAddToPageacheLru(LosFilePage *page, struct page_mapping *mapping, VM_OFFSET_T pgoff) +{ + OsPageCacheAdd(page, mapping, pgoff); + OsLruCacheAdd(page, VM_LRU_ACTIVE_FILE); +} + +VOID OsPageCacheDel(LosFilePage *fpage) +{ + /* delete from file cache list */ + LOS_ListDelete(&fpage->node); + fpage->mapping->nrpages--; + + /* unmap and remove map info */ + if (OsIsPageMapped(fpage)) { + OsUnmapAllLocked(fpage); + } + + LOS_PhysPageFree(fpage->vmPage); + + LOS_MemFree(m_aucSysMem0, fpage); +} + +VOID OsAddMapInfo(LosFilePage *page, LosArchMmu *archMmu, VADDR_T vaddr) +{ + LosMapInfo *info = NULL; + + info = (LosMapInfo *)LOS_MemAlloc(m_aucSysMem0, sizeof(LosMapInfo)); + if (info == NULL) { + VM_ERR("OsAddMapInfo alloc memory failed!"); + return; + } + info->page = page; + info->archMmu = archMmu; + info->vaddr = vaddr; + + LOS_ListAdd(&page->i_mmap, &info->node); + page->n_maps++; +} + +LosMapInfo *OsGetMapInfo(const LosFilePage *page, const LosArchMmu *archMmu, VADDR_T vaddr) +{ + LosMapInfo *info = NULL; + const LOS_DL_LIST *immap = &page->i_mmap; + + LOS_DL_LIST_FOR_EACH_ENTRY(info, immap, LosMapInfo, node) { + if ((info->archMmu == archMmu) && (info->vaddr == vaddr) && (info->page == page)) { + return info; + } + } + + return NULL; +} + +VOID OsDeletePageCacheLru(LosFilePage *page) +{ + /* delete from lru list */ + OsLruCacheDel(page); + /* delete from cache list and free pmm if needed */ + OsPageCacheDel(page); +} + +STATIC VOID OsPageCacheUnmap(LosFilePage *fpage, LosArchMmu *archMmu, VADDR_T vaddr) +{ + UINT32 intSave; + LosMapInfo *info = NULL; + + LOS_SpinLockSave(&fpage->physSeg->lruLock, &intSave); + info = OsGetMapInfo(fpage, archMmu, vaddr); + if (info == NULL) { + VM_ERR("OsPageCacheUnmap get map info failed!"); + } else { + OsUnmapPageLocked(fpage, info); + } + if (!(OsIsPageMapped(fpage) && ((fpage->flags & VM_MAP_REGION_FLAG_PERM_EXECUTE) || + OsIsPageDirty(fpage->vmPage)))) { + OsPageRefDecNoLock(fpage); + } + + LOS_SpinUnlockRestore(&fpage->physSeg->lruLock, intSave); +} + +VOID OsVmmFileRemove(LosVmMapRegion *region, LosArchMmu *archMmu, VM_OFFSET_T pgoff) +{ + UINT32 intSave; + vaddr_t vaddr; + paddr_t paddr = 0; + struct Vnode *vnode = NULL; + struct page_mapping *mapping = NULL; + LosFilePage *fpage = NULL; + LosFilePage *tmpPage = NULL; + LosVmPage *mapPage = NULL; + + if (!LOS_IsRegionFileValid(region) || (region->unTypeData.rf.vnode == NULL)) { + return; + } + vnode = region->unTypeData.rf.vnode; + mapping = &vnode->mapping; + vaddr = region->range.base + ((UINT32)(pgoff - region->pgOff) << PAGE_SHIFT); + + status_t status = LOS_ArchMmuQuery(archMmu, vaddr, &paddr, NULL); + if (status != LOS_OK) { + return; + } + + mapPage = LOS_VmPageGet(paddr); + + /* is page is in cache list */ + LOS_SpinLockSave(&mapping->list_lock, &intSave); + fpage = OsFindGetEntry(mapping, pgoff); + /* no cache or have cache but not map(cow), free it direct */ + if ((fpage == NULL) || (fpage->vmPage != mapPage)) { + LOS_PhysPageFree(mapPage); + LOS_ArchMmuUnmap(archMmu, vaddr, 1); + /* this is a page cache map! */ + } else { + OsPageCacheUnmap(fpage, archMmu, vaddr); + if (OsIsPageDirty(fpage->vmPage)) { + tmpPage = OsDumpDirtyPage(fpage); + } + } + LOS_SpinUnlockRestore(&mapping->list_lock, intSave); + + if (tmpPage) { + OsDoFlushDirtyPage(tmpPage); + } + return; +} + +VOID OsMarkPageDirty(LosFilePage *fpage, const LosVmMapRegion *region, INT32 off, INT32 len) +{ + if (region != NULL) { + OsSetPageDirty(fpage->vmPage); + fpage->dirtyOff = off; + fpage->dirtyEnd = len; + } else { + OsSetPageDirty(fpage->vmPage); + if ((off + len) > fpage->dirtyEnd) { + fpage->dirtyEnd = off + len; + } + + if (off < fpage->dirtyOff) { + fpage->dirtyOff = off; + } + } +} + +STATIC UINT32 GetDirtySize(LosFilePage *fpage, struct Vnode *vnode) +{ + UINT32 fileSize; + UINT32 dirtyBegin; + UINT32 dirtyEnd; + struct stat buf_stat; + + if (stat(vnode->filePath, &buf_stat) != OK) { + VM_ERR("FlushDirtyPage get file size failed. (filePath=%s)", vnode->filePath); + return 0; + } + + fileSize = buf_stat.st_size; + dirtyBegin = ((UINT32)fpage->pgoff << PAGE_SHIFT); + dirtyEnd = dirtyBegin + PAGE_SIZE; + + if (dirtyBegin >= fileSize) { + return 0; + } + + if (dirtyEnd >= fileSize) { + return fileSize - dirtyBegin; + } + + return PAGE_SIZE; +} + +STATIC INT32 OsFlushDirtyPage(LosFilePage *fpage) +{ + UINT32 ret; + size_t len; + char *buff = NULL; + struct Vnode *vnode = fpage->mapping->host; + if (vnode == NULL) { + VM_ERR("page cache vnode error"); + return LOS_NOK; + } + + len = fpage->dirtyEnd - fpage->dirtyOff; + len = (len == 0) ? GetDirtySize(fpage, vnode) : len; + if (len == 0) { + OsCleanPageDirty(fpage->vmPage); + return LOS_OK; + } + + buff = (char *)OsVmPageToVaddr(fpage->vmPage); + + /* actually, we did not update the fpage->dirtyOff */ + ret = vnode->vop->WritePage(vnode, (VOID *)buff, fpage->pgoff, len); + if (ret <= 0) { + VM_ERR("WritePage error ret %d", ret); + } else { + OsCleanPageDirty(fpage->vmPage); + } + ret = (ret <= 0) ? LOS_NOK : LOS_OK; + + return ret; +} + +LosFilePage *OsDumpDirtyPage(LosFilePage *oldFPage) +{ + LosFilePage *newFPage = NULL; + + newFPage = (LosFilePage *)LOS_MemAlloc(m_aucSysMem0, sizeof(LosFilePage)); + if (newFPage == NULL) { + VM_ERR("Failed to allocate for temp page!"); + return NULL; + } + + OsCleanPageDirty(oldFPage->vmPage); + (VOID)memcpy_s(newFPage, sizeof(LosFilePage), oldFPage, sizeof(LosFilePage)); + + return newFPage; +} + +VOID OsDoFlushDirtyPage(LosFilePage *fpage) +{ + if (fpage == NULL) { + return; + } + (VOID)OsFlushDirtyPage(fpage); + LOS_MemFree(m_aucSysMem0, fpage); +} + +STATIC VOID OsReleaseFpage(struct page_mapping *mapping, LosFilePage *fpage) +{ + UINT32 intSave; + UINT32 lruSave; + SPIN_LOCK_S *lruLock = &fpage->physSeg->lruLock; + LOS_SpinLockSave(&mapping->list_lock, &intSave); + LOS_SpinLockSave(lruLock, &lruSave); + OsCleanPageLocked(fpage->vmPage); + OsDeletePageCacheLru(fpage); + LOS_SpinUnlockRestore(lruLock, lruSave); + LOS_SpinUnlockRestore(&mapping->list_lock, intSave); +} + +VOID OsDelMapInfo(LosVmMapRegion *region, LosVmPgFault *vmf, BOOL cleanDirty) +{ + UINT32 intSave; + LosMapInfo *info = NULL; + LosFilePage *fpage = NULL; + struct page_mapping *mapping = NULL; + + if (!LOS_IsRegionFileValid(region) || (region->unTypeData.rf.vnode == NULL) || (vmf == NULL)) { + return; + } + + mapping = ®ion->unTypeData.rf.vnode->mapping; + LOS_SpinLockSave(&mapping->list_lock, &intSave); + fpage = OsFindGetEntry(mapping, vmf->pgoff); + if (fpage == NULL) { + LOS_SpinUnlockRestore(&mapping->list_lock, intSave); + return; + } + + if (cleanDirty) { + OsCleanPageDirty(fpage->vmPage); + } + info = OsGetMapInfo(fpage, ®ion->space->archMmu, (vaddr_t)vmf->vaddr); + if (info != NULL) { + fpage->n_maps--; + LOS_ListDelete(&info->node); + LOS_AtomicDec(&fpage->vmPage->refCounts); + LOS_SpinUnlockRestore(&mapping->list_lock, intSave); + LOS_MemFree(m_aucSysMem0, info); + return; + } + LOS_SpinUnlockRestore(&mapping->list_lock, intSave); +} + +INT32 OsVmmFileFault(LosVmMapRegion *region, LosVmPgFault *vmf) +{ + INT32 ret; + VOID *kvaddr = NULL; + + UINT32 intSave; + bool newCache = false; + struct Vnode *vnode = NULL; + struct page_mapping *mapping = NULL; + LosFilePage *fpage = NULL; + + if (!LOS_IsRegionFileValid(region) || (region->unTypeData.rf.vnode == NULL) || (vmf == NULL)) { + VM_ERR("Input param is NULL"); + return LOS_NOK; + } + vnode = region->unTypeData.rf.vnode; + mapping = &vnode->mapping; + + /* get or create a new cache node */ + LOS_SpinLockSave(&mapping->list_lock, &intSave); + fpage = OsFindGetEntry(mapping, vmf->pgoff); + TRACE_TRY_CACHE(); + if (fpage != NULL) { + TRACE_HIT_CACHE(); + OsPageRefIncLocked(fpage); + } else { + fpage = OsPageCacheAlloc(mapping, vmf->pgoff); + if (fpage == NULL) { + LOS_SpinUnlockRestore(&mapping->list_lock, intSave); + VM_ERR("Failed to alloc a page frame"); + return LOS_NOK; + } + newCache = true; + } + OsSetPageLocked(fpage->vmPage); + LOS_SpinUnlockRestore(&mapping->list_lock, intSave); + kvaddr = OsVmPageToVaddr(fpage->vmPage); + + /* read file to new page cache */ + if (newCache) { + ret = vnode->vop->ReadPage(vnode, kvaddr, fpage->pgoff << PAGE_SHIFT); + if (ret == 0) { + VM_ERR("Failed to read from file!"); + OsReleaseFpage(mapping, fpage); + return LOS_NOK; + } + LOS_SpinLockSave(&mapping->list_lock, &intSave); + OsAddToPageacheLru(fpage, mapping, vmf->pgoff); + LOS_SpinUnlockRestore(&mapping->list_lock, intSave); + } + + LOS_SpinLockSave(&mapping->list_lock, &intSave); + /* cow fault case no need to save mapinfo */ + if (!((vmf->flags & VM_MAP_PF_FLAG_WRITE) && !(region->regionFlags & VM_MAP_REGION_FLAG_SHARED))) { + OsAddMapInfo(fpage, ®ion->space->archMmu, (vaddr_t)vmf->vaddr); + fpage->flags = region->regionFlags; + } + + /* share page fault, mark the page dirty */ + if ((vmf->flags & VM_MAP_PF_FLAG_WRITE) && (region->regionFlags & VM_MAP_REGION_FLAG_SHARED)) { + OsMarkPageDirty(fpage, region, 0, 0); + } + + vmf->pageKVaddr = kvaddr; + LOS_SpinUnlockRestore(&mapping->list_lock, intSave); + return LOS_OK; +} + +VOID OsFileCacheFlush(struct page_mapping *mapping) +{ + UINT32 intSave; + UINT32 lruLock; + LOS_DL_LIST_HEAD(dirtyList); + LosFilePage *ftemp = NULL; + LosFilePage *fpage = NULL; + + if (mapping == NULL) { + return; + } + LOS_SpinLockSave(&mapping->list_lock, &intSave); + LOS_DL_LIST_FOR_EACH_ENTRY(fpage, &mapping->page_list, LosFilePage, node) { + LOS_SpinLockSave(&fpage->physSeg->lruLock, &lruLock); + if (OsIsPageDirty(fpage->vmPage)) { + ftemp = OsDumpDirtyPage(fpage); + if (ftemp != NULL) { + LOS_ListTailInsert(&dirtyList, &ftemp->node); + } + } + LOS_SpinUnlockRestore(&fpage->physSeg->lruLock, lruLock); + } + LOS_SpinUnlockRestore(&mapping->list_lock, intSave); + + LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(fpage, ftemp, &dirtyList, LosFilePage, node) { + OsDoFlushDirtyPage(fpage); + } +} + +VOID OsFileCacheRemove(struct page_mapping *mapping) +{ + UINT32 intSave; + UINT32 lruSave; + SPIN_LOCK_S *lruLock = NULL; + LOS_DL_LIST_HEAD(dirtyList); + LosFilePage *ftemp = NULL; + LosFilePage *fpage = NULL; + LosFilePage *fnext = NULL; + + LOS_SpinLockSave(&mapping->list_lock, &intSave); + LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(fpage, fnext, &mapping->page_list, LosFilePage, node) { + lruLock = &fpage->physSeg->lruLock; + LOS_SpinLockSave(lruLock, &lruSave); + if (OsIsPageDirty(fpage->vmPage)) { + ftemp = OsDumpDirtyPage(fpage); + if (ftemp != NULL) { + LOS_ListTailInsert(&dirtyList, &ftemp->node); + } + } + + OsDeletePageCacheLru(fpage); + LOS_SpinUnlockRestore(lruLock, lruSave); + } + LOS_SpinUnlockRestore(&mapping->list_lock, intSave); + + LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(fpage, fnext, &dirtyList, LosFilePage, node) { + OsDoFlushDirtyPage(fpage); + } +} + +LosVmFileOps g_commVmOps = { + .open = NULL, + .close = NULL, + .fault = OsVmmFileFault, + .remove = OsVmmFileRemove, +}; + +INT32 OsVfsFileMmap(struct file *filep, LosVmMapRegion *region) +{ + region->unTypeData.rf.vmFOps = &g_commVmOps; + region->unTypeData.rf.vnode = filep->f_vnode; + region->unTypeData.rf.f_oflags = filep->f_oflags; + + return ENOERR; +} + +STATUS_T OsNamedMMap(struct file *filep, LosVmMapRegion *region) +{ + struct Vnode *vnode = NULL; + if (filep == NULL) { + return LOS_ERRNO_VM_MAP_FAILED; + } + file_hold(filep); + vnode = filep->f_vnode; + VnodeHold(); + vnode->useCount++; + VnodeDrop(); + if (filep->ops != NULL && filep->ops->mmap != NULL) { + if (vnode->type == VNODE_TYPE_CHR || vnode->type == VNODE_TYPE_BLK) { + LOS_SetRegionTypeDev(region); + } else { + LOS_SetRegionTypeFile(region); + } + int ret = filep->ops->mmap(filep, region); + if (ret != LOS_OK) { + file_release(filep); + return LOS_ERRNO_VM_MAP_FAILED; + } + } else { + VM_ERR("mmap file type unknown"); + file_release(filep); + return LOS_ERRNO_VM_MAP_FAILED; + } + file_release(filep); + return LOS_OK; +} + +LosFilePage *OsFindGetEntry(struct page_mapping *mapping, VM_OFFSET_T pgoff) +{ + LosFilePage *fpage = NULL; + + LOS_DL_LIST_FOR_EACH_ENTRY(fpage, &mapping->page_list, LosFilePage, node) { + if (fpage->pgoff == pgoff) { + return fpage; + } + + if (fpage->pgoff > pgoff) { + break; + } + } + + return NULL; +} + +/* need mutex & change memory to dma zone. */ +LosFilePage *OsPageCacheAlloc(struct page_mapping *mapping, VM_OFFSET_T pgoff) +{ + VOID *kvaddr = NULL; + LosVmPhysSeg *physSeg = NULL; + LosVmPage *vmPage = NULL; + LosFilePage *fpage = NULL; + + vmPage = LOS_PhysPageAlloc(); + if (vmPage == NULL) { + VM_ERR("alloc vm page failed"); + return NULL; + } + physSeg = OsVmPhysSegGet(vmPage); + kvaddr = OsVmPageToVaddr(vmPage); + if ((physSeg == NULL) || (kvaddr == NULL)) { + LOS_PhysPageFree(vmPage); + VM_ERR("alloc vm page failed!"); + return NULL; + } + + fpage = (LosFilePage *)LOS_MemAlloc(m_aucSysMem0, sizeof(LosFilePage)); + if (fpage == NULL) { + LOS_PhysPageFree(vmPage); + VM_ERR("Failed to allocate for page!"); + return NULL; + } + + (VOID)memset_s((VOID *)fpage, sizeof(LosFilePage), 0, sizeof(LosFilePage)); + + LOS_ListInit(&fpage->i_mmap); + LOS_ListInit(&fpage->node); + LOS_ListInit(&fpage->lru); + fpage->n_maps = 0; + fpage->dirtyOff = PAGE_SIZE; + fpage->dirtyEnd = 0; + fpage->physSeg = physSeg; + fpage->vmPage = vmPage; + fpage->mapping = mapping; + fpage->pgoff = pgoff; + (VOID)memset_s(kvaddr, PAGE_SIZE, 0, PAGE_SIZE); + + return fpage; +} + +#ifndef LOSCFG_FS_VFS +INT32 OsVfsFileMmap(struct file *filep, LosVmMapRegion *region) +{ + UNUSED(filep); + UNUSED(region); + return ENOERR; +} +#endif + +#endif diff --git a/src/kernel_liteos_a/kernel/base/vm/los_vm_iomap.c b/src/kernel_liteos_a/kernel/base/vm/los_vm_iomap.c new file mode 100644 index 00000000..a313da14 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/vm/los_vm_iomap.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_vm_iomap.h" +#include "los_printf.h" +#include "los_vm_zone.h" +#include "los_vm_common.h" +#include "los_vm_map.h" +#include "los_memory.h" + + +VOID *LOS_DmaMemAlloc(DMA_ADDR_T *dmaAddr, size_t size, size_t align, enum DmaMemType type) +{ + VOID *kVaddr = NULL; + + if (size == 0) { + return NULL; + } + + if ((type != DMA_CACHE) && (type != DMA_NOCACHE)) { + VM_ERR("The dma type = %d is not supported!", type); + return NULL; + } + +#ifdef LOSCFG_KERNEL_VM + kVaddr = LOS_KernelMallocAlign(size, align); +#else + kVaddr = LOS_MemAllocAlign(OS_SYS_MEM_ADDR, size, align); +#endif + if (kVaddr == NULL) { + VM_ERR("failed, size = %u, align = %u", size, align); + return NULL; + } + + if (dmaAddr != NULL) { + *dmaAddr = (DMA_ADDR_T)LOS_PaddrQuery(kVaddr); + } + + if (type == DMA_NOCACHE) { + kVaddr = (VOID *)VMM_TO_UNCACHED_ADDR((UINTPTR)kVaddr); + } + + return kVaddr; +} + +VOID LOS_DmaMemFree(VOID *vaddr) +{ + UINTPTR addr; + + if (vaddr == NULL) { + return; + } + addr = (UINTPTR)vaddr; + + if ((addr >= UNCACHED_VMM_BASE) && (addr < UNCACHED_VMM_BASE + UNCACHED_VMM_SIZE)) { + addr = UNCACHED_TO_VMM_ADDR(addr); +#ifdef LOSCFG_KERNEL_VM + LOS_KernelFree((VOID *)addr); +#else + LOS_MemFree(OS_SYS_MEM_ADDR, (VOID *)addr); +#endif + } else if ((addr >= KERNEL_VMM_BASE) && (addr < KERNEL_VMM_BASE + KERNEL_VMM_SIZE)) { +#ifdef LOSCFG_KERNEL_VM + LOS_KernelFree((VOID *)addr); +#else + LOS_MemFree(OS_SYS_MEM_ADDR, (VOID *)addr); +#endif + } else { + VM_ERR("addr %#x not in dma area!!!", vaddr); + } + return; +} + +DMA_ADDR_T LOS_DmaVaddrToPaddr(VOID *vaddr) +{ + return (DMA_ADDR_T)LOS_PaddrQuery(vaddr); +} + diff --git a/src/kernel_liteos_a/kernel/base/vm/los_vm_map.c b/src/kernel_liteos_a/kernel/base/vm/los_vm_map.c new file mode 100644 index 00000000..5d4f62b3 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/vm/los_vm_map.c @@ -0,0 +1,1212 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_vm_map.h" +#include "los_vm_page.h" +#include "los_vm_phys.h" +#include "los_vm_dump.h" +#include "los_vm_lock.h" +#include "los_vm_zone.h" +#include "los_vm_common.h" +#include "los_vm_filemap.h" +#include "los_vm_shm_pri.h" +#include "los_arch_mmu.h" +#include "los_process_pri.h" +#ifdef LOSCFG_FS_VFS +#include "fs/file.h" +#include "vnode.h" +#endif +#include "los_task.h" +#include "los_memory_pri.h" +#include "los_vm_boot.h" + + +#ifdef LOSCFG_KERNEL_VM + +#define VM_MAP_WASTE_MEM_LEVEL (PAGE_SIZE >> 2) +LosMux g_vmSpaceListMux; +LOS_DL_LIST_HEAD(g_vmSpaceList); +LosVmSpace g_kVmSpace; +LosVmSpace g_vMallocSpace; + +LosVmSpace *LOS_CurrSpaceGet(VOID) +{ + return OsCurrProcessGet()->vmSpace; +} + +LosVmSpace *LOS_SpaceGet(VADDR_T vaddr) +{ + if (LOS_IsKernelAddress(vaddr)) { + return LOS_GetKVmSpace(); + } else if (LOS_IsUserAddress(vaddr)) { + return LOS_CurrSpaceGet(); + } else if (LOS_IsVmallocAddress(vaddr)) { + return LOS_GetVmallocSpace(); + } else { + return NULL; + } +} + +LosVmSpace *LOS_GetKVmSpace(VOID) +{ + return &g_kVmSpace; +} + +LOS_DL_LIST *LOS_GetVmSpaceList(VOID) +{ + return &g_vmSpaceList; +} + +LosVmSpace *LOS_GetVmallocSpace(VOID) +{ + return &g_vMallocSpace; +} + +ULONG_T OsRegionRbFreeFn(LosRbNode *pstNode) +{ + LOS_MemFree(m_aucSysMem0, pstNode); + return LOS_OK; +} + +VOID *OsRegionRbGetKeyFn(LosRbNode *pstNode) +{ + LosVmMapRegion *region = (LosVmMapRegion *)LOS_DL_LIST_ENTRY(pstNode, LosVmMapRegion, rbNode); + return (VOID *)®ion->range; +} + +ULONG_T OsRegionRbCmpKeyFn(const VOID *pNodeKeyA, const VOID *pNodeKeyB) +{ + LosVmMapRange rangeA = *(LosVmMapRange *)pNodeKeyA; + LosVmMapRange rangeB = *(LosVmMapRange *)pNodeKeyB; + UINT32 startA = rangeA.base; + UINT32 endA = rangeA.base + rangeA.size - 1; + UINT32 startB = rangeB.base; + UINT32 endB = rangeB.base + rangeB.size - 1; + + if (startA > endB) { + return RB_BIGGER; + } else if (startA >= startB) { + if (endA <= endB) { + return RB_EQUAL; + } else { + return RB_BIGGER; + } + } else if (startA <= startB) { + if (endA >= endB) { + return RB_EQUAL; + } else { + return RB_SMALLER; + } + } else if (endA < startB) { + return RB_SMALLER; + } + return RB_EQUAL; +} + +STATIC BOOL OsVmSpaceInitCommon(LosVmSpace *vmSpace, VADDR_T *virtTtb) +{ + LOS_RbInitTree(&vmSpace->regionRbTree, OsRegionRbCmpKeyFn, OsRegionRbFreeFn, OsRegionRbGetKeyFn); + + status_t retval = LOS_MuxInit(&vmSpace->regionMux, NULL); + if (retval != LOS_OK) { + VM_ERR("Create mutex for vm space failed, status: %d", retval); + return FALSE; + } + + (VOID)LOS_MuxAcquire(&g_vmSpaceListMux); + LOS_ListAdd(&g_vmSpaceList, &vmSpace->node); + (VOID)LOS_MuxRelease(&g_vmSpaceListMux); + + return OsArchMmuInit(&vmSpace->archMmu, virtTtb); +} + +VOID OsVmMapInit(VOID) +{ + status_t retval = LOS_MuxInit(&g_vmSpaceListMux, NULL); + if (retval != LOS_OK) { + VM_ERR("Create mutex for g_vmSpaceList failed, status: %d", retval); + } +} + +BOOL OsKernVmSpaceInit(LosVmSpace *vmSpace, VADDR_T *virtTtb) +{ + vmSpace->base = KERNEL_ASPACE_BASE; + vmSpace->size = KERNEL_ASPACE_SIZE; + vmSpace->mapBase = KERNEL_VMM_BASE; + vmSpace->mapSize = KERNEL_VMM_SIZE; +#ifdef LOSCFG_DRIVERS_TZDRIVER + vmSpace->codeStart = 0; + vmSpace->codeEnd = 0; +#endif + return OsVmSpaceInitCommon(vmSpace, virtTtb); +} + +BOOL OsVMallocSpaceInit(LosVmSpace *vmSpace, VADDR_T *virtTtb) +{ + vmSpace->base = VMALLOC_START; + vmSpace->size = VMALLOC_SIZE; + vmSpace->mapBase = VMALLOC_START; + vmSpace->mapSize = VMALLOC_SIZE; +#ifdef LOSCFG_DRIVERS_TZDRIVER + vmSpace->codeStart = 0; + vmSpace->codeEnd = 0; +#endif + return OsVmSpaceInitCommon(vmSpace, virtTtb); +} + +VOID OsKSpaceInit(VOID) +{ + OsVmMapInit(); + OsKernVmSpaceInit(&g_kVmSpace, OsGFirstTableGet()); + OsVMallocSpaceInit(&g_vMallocSpace, OsGFirstTableGet()); +} + +BOOL OsUserVmSpaceInit(LosVmSpace *vmSpace, VADDR_T *virtTtb) +{ + vmSpace->base = USER_ASPACE_BASE; + vmSpace->size = USER_ASPACE_SIZE; + vmSpace->mapBase = USER_MAP_BASE; + vmSpace->mapSize = USER_MAP_SIZE; + vmSpace->heapBase = USER_HEAP_BASE; + vmSpace->heapNow = USER_HEAP_BASE; + vmSpace->heap = NULL; +#ifdef LOSCFG_DRIVERS_TZDRIVER + vmSpace->codeStart = 0; + vmSpace->codeEnd = 0; +#endif + return OsVmSpaceInitCommon(vmSpace, virtTtb); +} + +LosVmSpace *OsCreateUserVmSpace(VOID) +{ + BOOL retVal = FALSE; + + LosVmSpace *space = LOS_MemAlloc(m_aucSysMem0, sizeof(LosVmSpace)); + if (space == NULL) { + return NULL; + } + + VADDR_T *ttb = LOS_PhysPagesAllocContiguous(1); + if (ttb == NULL) { + (VOID)LOS_MemFree(m_aucSysMem0, space); + return NULL; + } + + (VOID)memset_s(ttb, PAGE_SIZE, 0, PAGE_SIZE); + retVal = OsUserVmSpaceInit(space, ttb); + LosVmPage *vmPage = OsVmVaddrToPage(ttb); + if ((retVal == FALSE) || (vmPage == NULL)) { + (VOID)LOS_MemFree(m_aucSysMem0, space); + LOS_PhysPagesFreeContiguous(ttb, 1); + return NULL; + } + LOS_ListAdd(&space->archMmu.ptList, &(vmPage->node)); + + return space; +} + +STATIC BOOL OsVmSpaceParamCheck(const LosVmSpace *vmSpace) +{ + if (vmSpace == NULL) { + return FALSE; + } + return TRUE; +} + +STATUS_T LOS_VmSpaceClone(UINT32 cloneFlags, LosVmSpace *oldVmSpace, LosVmSpace *newVmSpace) +{ + LosRbNode *pstRbNode = NULL; + LosRbNode *pstRbNodeNext = NULL; + STATUS_T ret = LOS_OK; + PADDR_T paddr; + VADDR_T vaddr; + LosVmPage *page = NULL; + UINT32 flags, i, intSave, numPages; + + if ((OsVmSpaceParamCheck(oldVmSpace) == FALSE) || (OsVmSpaceParamCheck(newVmSpace) == FALSE)) { + return LOS_ERRNO_VM_INVALID_ARGS; + } + + if ((OsIsVmRegionEmpty(oldVmSpace) == TRUE) || (oldVmSpace == &g_kVmSpace)) { + return LOS_ERRNO_VM_INVALID_ARGS; + } + + /* search the region list */ + newVmSpace->mapBase = oldVmSpace->mapBase; + newVmSpace->heapBase = oldVmSpace->heapBase; + newVmSpace->heapNow = oldVmSpace->heapNow; + (VOID)LOS_MuxAcquire(&oldVmSpace->regionMux); + RB_SCAN_SAFE(&oldVmSpace->regionRbTree, pstRbNode, pstRbNodeNext) + LosVmMapRegion *oldRegion = (LosVmMapRegion *)pstRbNode; +#if defined(LOSCFG_KERNEL_SHM) && defined(LOSCFG_IPC_CONTAINER) + if ((oldRegion->regionFlags & VM_MAP_REGION_FLAG_SHM) && (cloneFlags & CLONE_NEWIPC)) { + continue; + } +#endif + LosVmMapRegion *newRegion = OsVmRegionDup(newVmSpace, oldRegion, oldRegion->range.base, oldRegion->range.size); + if (newRegion == NULL) { + VM_ERR("dup new region failed"); + ret = LOS_ERRNO_VM_NO_MEMORY; + break; + } + +#ifdef LOSCFG_KERNEL_SHM + if (oldRegion->regionFlags & VM_MAP_REGION_FLAG_SHM) { + OsShmFork(newVmSpace, oldRegion, newRegion); + continue; + } +#endif + + if (oldRegion == oldVmSpace->heap) { + newVmSpace->heap = newRegion; + } + + numPages = newRegion->range.size >> PAGE_SHIFT; + for (i = 0; i < numPages; i++) { + vaddr = newRegion->range.base + (i << PAGE_SHIFT); + if (LOS_ArchMmuQuery(&oldVmSpace->archMmu, vaddr, &paddr, &flags) != LOS_OK) { + continue; + } + + page = LOS_VmPageGet(paddr); + if (page != NULL) { + LOS_AtomicInc(&page->refCounts); + } + if (flags & VM_MAP_REGION_FLAG_PERM_WRITE) { + LOS_ArchMmuUnmap(&oldVmSpace->archMmu, vaddr, 1); + LOS_ArchMmuMap(&oldVmSpace->archMmu, vaddr, paddr, 1, flags & ~VM_MAP_REGION_FLAG_PERM_WRITE); + } + LOS_ArchMmuMap(&newVmSpace->archMmu, vaddr, paddr, 1, flags & ~VM_MAP_REGION_FLAG_PERM_WRITE); + +#ifdef LOSCFG_FS_VFS + if (LOS_IsRegionFileValid(oldRegion)) { + LosFilePage *fpage = NULL; + LOS_SpinLockSave(&oldRegion->unTypeData.rf.vnode->mapping.list_lock, &intSave); + fpage = OsFindGetEntry(&oldRegion->unTypeData.rf.vnode->mapping, newRegion->pgOff + i); + if ((fpage != NULL) && (fpage->vmPage == page)) { /* cow page no need map */ + OsAddMapInfo(fpage, &newVmSpace->archMmu, vaddr); + } + LOS_SpinUnlockRestore(&oldRegion->unTypeData.rf.vnode->mapping.list_lock, intSave); + } +#endif + } + RB_SCAN_SAFE_END(&oldVmSpace->regionRbTree, pstRbNode, pstRbNodeNext) + (VOID)LOS_MuxRelease(&oldVmSpace->regionMux); + return ret; +} + +LosVmMapRegion *OsFindRegion(LosRbTree *regionRbTree, VADDR_T vaddr, size_t len) +{ + LosVmMapRegion *regionRst = NULL; + LosRbNode *pstRbNode = NULL; + LosVmMapRange rangeKey; + rangeKey.base = vaddr; + rangeKey.size = len; + + if (LOS_RbGetNode(regionRbTree, (VOID *)&rangeKey, &pstRbNode)) { + regionRst = (LosVmMapRegion *)LOS_DL_LIST_ENTRY(pstRbNode, LosVmMapRegion, rbNode); + } + return regionRst; +} + +LosVmMapRegion *LOS_RegionFind(LosVmSpace *vmSpace, VADDR_T addr) +{ + LosVmMapRegion *region = NULL; + + (VOID)LOS_MuxAcquire(&vmSpace->regionMux); + region = OsFindRegion(&vmSpace->regionRbTree, addr, 1); + (VOID)LOS_MuxRelease(&vmSpace->regionMux); + + return region; +} + +LosVmMapRegion *LOS_RegionRangeFind(LosVmSpace *vmSpace, VADDR_T addr, size_t len) +{ + LosVmMapRegion *region = NULL; + + (VOID)LOS_MuxAcquire(&vmSpace->regionMux); + region = OsFindRegion(&vmSpace->regionRbTree, addr, len); + (VOID)LOS_MuxRelease(&vmSpace->regionMux); + + return region; +} + +VADDR_T OsAllocRange(LosVmSpace *vmSpace, size_t len) +{ + LosVmMapRegion *curRegion = NULL; + LosRbNode *pstRbNode = NULL; + LosRbNode *pstRbNodeTmp = NULL; + LosRbTree *regionRbTree = &vmSpace->regionRbTree; + VADDR_T curEnd = vmSpace->mapBase; + VADDR_T nextStart; + + curRegion = LOS_RegionFind(vmSpace, vmSpace->mapBase); + if (curRegion != NULL) { + pstRbNode = &curRegion->rbNode; + curEnd = curRegion->range.base + curRegion->range.size; + RB_MID_SCAN(regionRbTree, pstRbNode) + curRegion = (LosVmMapRegion *)pstRbNode; + nextStart = curRegion->range.base; + if (nextStart < curEnd) { + continue; + } + if ((nextStart - curEnd) >= len) { + return curEnd; + } else { + curEnd = curRegion->range.base + curRegion->range.size; + } + RB_MID_SCAN_END(regionRbTree, pstRbNode) + } else { + /* rbtree scan is sorted, from small to big */ + RB_SCAN_SAFE(regionRbTree, pstRbNode, pstRbNodeTmp) + curRegion = (LosVmMapRegion *)pstRbNode; + nextStart = curRegion->range.base; + if (nextStart < curEnd) { + continue; + } + if ((nextStart - curEnd) >= len) { + return curEnd; + } else { + curEnd = curRegion->range.base + curRegion->range.size; + } + RB_SCAN_SAFE_END(regionRbTree, pstRbNode, pstRbNodeTmp) + } + + nextStart = vmSpace->mapBase + vmSpace->mapSize; + if ((nextStart >= curEnd) && ((nextStart - curEnd) >= len)) { + return curEnd; + } + + return 0; +} + +VADDR_T OsAllocSpecificRange(LosVmSpace *vmSpace, VADDR_T vaddr, size_t len, UINT32 regionFlags) +{ + STATUS_T status; + + if (LOS_IsRangeInSpace(vmSpace, vaddr, len) == FALSE) { + return 0; + } + + if ((LOS_RegionFind(vmSpace, vaddr) != NULL) || + (LOS_RegionFind(vmSpace, vaddr + len - 1) != NULL) || + (LOS_RegionRangeFind(vmSpace, vaddr, len - 1) != NULL)) { + if ((regionFlags & VM_MAP_REGION_FLAG_FIXED_NOREPLACE) != 0) { + return 0; + } else if ((regionFlags & VM_MAP_REGION_FLAG_FIXED) != 0) { + status = LOS_UnMMap(vaddr, len); + if (status != LOS_OK) { + VM_ERR("unmap specific range va: %#x, len: %#x failed, status: %d", vaddr, len, status); + return 0; + } + } else { + return OsAllocRange(vmSpace, len); + } + } + + return vaddr; +} + +BOOL LOS_IsRegionFileValid(LosVmMapRegion *region) +{ + if ((region != NULL) && (LOS_IsRegionTypeFile(region)) && + (region->unTypeData.rf.vnode != NULL)) { + return TRUE; + } + return FALSE; +} + +BOOL OsInsertRegion(LosRbTree *regionRbTree, LosVmMapRegion *region) +{ + if (LOS_RbAddNode(regionRbTree, (LosRbNode *)region) == FALSE) { + VM_ERR("insert region failed, base: %#x, size: %#x", region->range.base, region->range.size); + OsDumpAspace(region->space); + return FALSE; + } + return TRUE; +} + +LosVmMapRegion *OsCreateRegion(VADDR_T vaddr, size_t len, UINT32 regionFlags, unsigned long offset) +{ + LosVmMapRegion *region = LOS_MemAlloc(m_aucSysMem0, sizeof(LosVmMapRegion)); + if (region == NULL) { + VM_ERR("memory allocate for LosVmMapRegion failed"); + return region; + } + + (void)memset_s(region, sizeof(LosVmMapRegion), 0, sizeof(LosVmMapRegion)); + region->range.base = vaddr; + region->range.size = len; + region->pgOff = offset; + region->regionFlags = regionFlags; + region->regionType = VM_MAP_REGION_TYPE_NONE; + region->forkFlags = 0; + region->shmid = -1; + return region; +} + +PADDR_T LOS_PaddrQuery(VOID *vaddr) +{ + PADDR_T paddr = 0; + STATUS_T status; + LosVmSpace *space = NULL; + LosArchMmu *archMmu = NULL; + + if (LOS_IsKernelAddress((VADDR_T)(UINTPTR)vaddr)) { + archMmu = &g_kVmSpace.archMmu; + } else if (LOS_IsUserAddress((VADDR_T)(UINTPTR)vaddr)) { + space = OsCurrProcessGet()->vmSpace; + archMmu = &space->archMmu; + } else if (LOS_IsVmallocAddress((VADDR_T)(UINTPTR)vaddr)) { + archMmu = &g_vMallocSpace.archMmu; + } else { + VM_ERR("vaddr is beyond range"); + return 0; + } + + status = LOS_ArchMmuQuery(archMmu, (VADDR_T)(UINTPTR)vaddr, &paddr, 0); + if (status == LOS_OK) { + return paddr; + } else { + return 0; + } +} + +LosVmMapRegion *LOS_RegionAlloc(LosVmSpace *vmSpace, VADDR_T vaddr, size_t len, UINT32 regionFlags, VM_OFFSET_T pgoff) +{ + VADDR_T rstVaddr; + LosVmMapRegion *newRegion = NULL; + BOOL isInsertSucceed = FALSE; + /** + * If addr is NULL, then the kernel chooses the address at which to create the mapping; + * this is the most portable method of creating a new mapping. If addr is not NULL, + * then the kernel takes it as where to place the mapping; + */ + (VOID)LOS_MuxAcquire(&vmSpace->regionMux); + if (vaddr == 0) { + rstVaddr = OsAllocRange(vmSpace, len); + } else { + /* if it is already mmapped here, we unmmap it */ + rstVaddr = OsAllocSpecificRange(vmSpace, vaddr, len, regionFlags); + if (rstVaddr == 0) { + VM_ERR("alloc specific range va: %#x, len: %#x failed", vaddr, len); + goto OUT; + } + } + if (rstVaddr == 0) { + goto OUT; + } + + newRegion = OsCreateRegion(rstVaddr, len, regionFlags, pgoff); + if (newRegion == NULL) { + goto OUT; + } + newRegion->space = vmSpace; + isInsertSucceed = OsInsertRegion(&vmSpace->regionRbTree, newRegion); + if (isInsertSucceed == FALSE) { + (VOID)LOS_MemFree(m_aucSysMem0, newRegion); + newRegion = NULL; + } + +OUT: + (VOID)LOS_MuxRelease(&vmSpace->regionMux); + return newRegion; +} + +STATIC VOID OsAnonPagesRemove(LosArchMmu *archMmu, VADDR_T vaddr, UINT32 count) +{ + status_t status; + paddr_t paddr; + LosVmPage *page = NULL; + + if ((archMmu == NULL) || (vaddr == 0) || (count == 0)) { + VM_ERR("OsAnonPagesRemove invalid args, archMmu %p, vaddr %p, count %d", archMmu, vaddr, count); + return; + } + + while (count > 0) { + count--; + status = LOS_ArchMmuQuery(archMmu, vaddr, &paddr, NULL); + if (status != LOS_OK) { + vaddr += PAGE_SIZE; + continue; + } + + LOS_ArchMmuUnmap(archMmu, vaddr, 1); + + page = LOS_VmPageGet(paddr); + if (page != NULL) { + if (!OsIsPageShared(page)) { + LOS_PhysPageFree(page); + } + } + vaddr += PAGE_SIZE; + } +} + +STATIC VOID OsDevPagesRemove(LosArchMmu *archMmu, VADDR_T vaddr, UINT32 count) +{ + status_t status; + + if ((archMmu == NULL) || (vaddr == 0) || (count == 0)) { + VM_ERR("OsDevPagesRemove invalid args, archMmu %p, vaddr %p, count %d", archMmu, vaddr, count); + return; + } + + status = LOS_ArchMmuQuery(archMmu, vaddr, NULL, NULL); + if (status != LOS_OK) { + return; + } + + /* in order to unmap section */ + LOS_ArchMmuUnmap(archMmu, vaddr, count); +} + +#ifdef LOSCFG_FS_VFS +STATIC VOID OsFilePagesRemove(LosVmSpace *space, LosVmMapRegion *region) +{ + VM_OFFSET_T offset; + size_t size; + + if ((space == NULL) || (region == NULL) || (region->unTypeData.rf.vmFOps == NULL)) { + return; + } + + offset = region->pgOff; + size = region->range.size; + while (size >= PAGE_SIZE) { + region->unTypeData.rf.vmFOps->remove(region, &space->archMmu, offset); + offset++; + size -= PAGE_SIZE; + } +} +#endif + +STATUS_T LOS_RegionFree(LosVmSpace *space, LosVmMapRegion *region) +{ + if ((space == NULL) || (region == NULL)) { + VM_ERR("args error, aspace %p, region %p", space, region); + return LOS_ERRNO_VM_INVALID_ARGS; + } + + (VOID)LOS_MuxAcquire(&space->regionMux); + +#ifdef LOSCFG_FS_VFS + if (LOS_IsRegionFileValid(region)) { + OsFilePagesRemove(space, region); + VnodeHold(); + region->unTypeData.rf.vnode->useCount--; + VnodeDrop(); + } else +#endif + +#ifdef LOSCFG_KERNEL_SHM + if (OsIsShmRegion(region)) { + OsShmRegionFree(space, region); + } else if (LOS_IsRegionTypeDev(region)) { +#else + if (LOS_IsRegionTypeDev(region)) { +#endif + OsDevPagesRemove(&space->archMmu, region->range.base, region->range.size >> PAGE_SHIFT); + } else { + OsAnonPagesRemove(&space->archMmu, region->range.base, region->range.size >> PAGE_SHIFT); + } + + /* remove it from space */ + LOS_RbDelNode(&space->regionRbTree, ®ion->rbNode); + /* free it */ + LOS_MemFree(m_aucSysMem0, region); + (VOID)LOS_MuxRelease(&space->regionMux); + return LOS_OK; +} + +LosVmMapRegion *OsVmRegionDup(LosVmSpace *space, LosVmMapRegion *oldRegion, VADDR_T vaddr, size_t size) +{ + LosVmMapRegion *newRegion = NULL; + UINT32 regionFlags; + + (VOID)LOS_MuxAcquire(&space->regionMux); + regionFlags = oldRegion->regionFlags; + if (vaddr == 0) { + regionFlags &= ~(VM_MAP_REGION_FLAG_FIXED | VM_MAP_REGION_FLAG_FIXED_NOREPLACE); + } else { + regionFlags |= VM_MAP_REGION_FLAG_FIXED; + } + newRegion = LOS_RegionAlloc(space, vaddr, size, regionFlags, oldRegion->pgOff); + if (newRegion == NULL) { + VM_ERR("LOS_RegionAlloc failed"); + goto REGIONDUPOUT; + } + newRegion->regionType = oldRegion->regionType; + +#ifdef LOSCFG_KERNEL_SHM + if (OsIsShmRegion(oldRegion)) { + newRegion->shmid = oldRegion->shmid; + } +#endif + +#ifdef LOSCFG_FS_VFS + if (LOS_IsRegionTypeFile(oldRegion)) { + newRegion->unTypeData.rf.vmFOps = oldRegion->unTypeData.rf.vmFOps; + newRegion->unTypeData.rf.vnode = oldRegion->unTypeData.rf.vnode; + newRegion->unTypeData.rf.f_oflags = oldRegion->unTypeData.rf.f_oflags; + VnodeHold(); + newRegion->unTypeData.rf.vnode->useCount++; + VnodeDrop(); + } +#endif + +REGIONDUPOUT: + (VOID)LOS_MuxRelease(&space->regionMux); + return newRegion; +} + +STATIC LosVmMapRegion *OsVmRegionSplit(LosVmMapRegion *oldRegion, VADDR_T newRegionStart) +{ + LosVmMapRegion *newRegion = NULL; + LosVmSpace *space = oldRegion->space; + size_t size = LOS_RegionSize(newRegionStart, LOS_RegionEndAddr(oldRegion)); + + oldRegion->range.size = LOS_RegionSize(oldRegion->range.base, newRegionStart - 1); + if (oldRegion->range.size == 0) { + LOS_RbDelNode(&space->regionRbTree, &oldRegion->rbNode); + } + + newRegion = OsVmRegionDup(oldRegion->space, oldRegion, newRegionStart, size); + if (newRegion == NULL) { + VM_ERR("OsVmRegionDup fail"); + return NULL; + } +#ifdef LOSCFG_FS_VFS + newRegion->pgOff = oldRegion->pgOff + ((newRegionStart - oldRegion->range.base) >> PAGE_SHIFT); +#endif + return newRegion; +} + +STATUS_T OsVmRegionAdjust(LosVmSpace *space, VADDR_T newRegionStart, size_t size) +{ + LosVmMapRegion *region = NULL; + VADDR_T nextRegionBase = newRegionStart + size; + LosVmMapRegion *newRegion = NULL; + + region = LOS_RegionFind(space, newRegionStart); + if ((region != NULL) && (newRegionStart > region->range.base)) { + newRegion = OsVmRegionSplit(region, newRegionStart); + if (newRegion == NULL) { + VM_ERR("region split fail"); + return LOS_ERRNO_VM_NO_MEMORY; + } + } + + region = LOS_RegionFind(space, nextRegionBase - 1); + if ((region != NULL) && (nextRegionBase < LOS_RegionEndAddr(region))) { + newRegion = OsVmRegionSplit(region, nextRegionBase); + if (newRegion == NULL) { + VM_ERR("region split fail"); + return LOS_ERRNO_VM_NO_MEMORY; + } + } + + return LOS_OK; +} + +STATUS_T OsRegionsRemove(LosVmSpace *space, VADDR_T regionBase, size_t size) +{ + STATUS_T status; + VADDR_T regionEnd = regionBase + size - 1; + LosVmMapRegion *regionTemp = NULL; + LosRbNode *pstRbNodeTemp = NULL; + LosRbNode *pstRbNodeNext = NULL; + + (VOID)LOS_MuxAcquire(&space->regionMux); + + status = OsVmRegionAdjust(space, regionBase, size); + if (status != LOS_OK) { + goto ERR_REGION_SPLIT; + } + + RB_SCAN_SAFE(&space->regionRbTree, pstRbNodeTemp, pstRbNodeNext) + regionTemp = (LosVmMapRegion *)pstRbNodeTemp; + if (regionTemp->range.base > regionEnd) { + break; + } + if (regionBase <= regionTemp->range.base && regionEnd >= LOS_RegionEndAddr(regionTemp)) { + status = LOS_RegionFree(space, regionTemp); + if (status != LOS_OK) { + VM_ERR("fail to free region, status=%d", status); + goto ERR_REGION_SPLIT; + } + } + + RB_SCAN_SAFE_END(&space->regionRbTree, pstRbNodeTemp, pstRbNodeNext) + +ERR_REGION_SPLIT: + (VOID)LOS_MuxRelease(&space->regionMux); + return status; +} + +INT32 OsUserHeapFree(LosVmSpace *vmSpace, VADDR_T addr, size_t len) +{ + LosVmMapRegion *vmRegion = NULL; + LosVmPage *vmPage = NULL; + PADDR_T paddr = 0; + VADDR_T vaddr; + STATUS_T ret; + + if (vmSpace == LOS_GetKVmSpace() || vmSpace->heap == NULL) { + return -1; + } + + vmRegion = LOS_RegionFind(vmSpace, addr); + if (vmRegion == NULL) { + return -1; + } + + if (vmRegion == vmSpace->heap) { + vaddr = addr; + while (len > 0) { + if (LOS_ArchMmuQuery(&vmSpace->archMmu, vaddr, &paddr, 0) == LOS_OK) { + ret = LOS_ArchMmuUnmap(&vmSpace->archMmu, vaddr, 1); + if (ret <= 0) { + VM_ERR("unmap failed, ret = %d", ret); + } + vmPage = LOS_VmPageGet(paddr); + LOS_PhysPageFree(vmPage); + } + vaddr += PAGE_SIZE; + len -= PAGE_SIZE; + } + return 0; + } + + return -1; +} + +STATUS_T OsIsRegionCanExpand(LosVmSpace *space, LosVmMapRegion *region, size_t size) +{ + LosVmMapRegion *nextRegion = NULL; + + if ((space == NULL) || (region == NULL)) { + return LOS_NOK; + } + + nextRegion = (LosVmMapRegion *)LOS_RbSuccessorNode(&space->regionRbTree, ®ion->rbNode); + /* if the gap is larger than size, then we can expand */ + if ((nextRegion != NULL) && ((nextRegion->range.base - region->range.base) >= size)) { + return LOS_OK; + } + + return LOS_NOK; +} + +STATUS_T OsUnMMap(LosVmSpace *space, VADDR_T addr, size_t size) +{ + size = LOS_Align(size, PAGE_SIZE); + addr = LOS_Align(addr, PAGE_SIZE); + (VOID)LOS_MuxAcquire(&space->regionMux); + STATUS_T status = OsRegionsRemove(space, addr, size); + if (status != LOS_OK) { + status = -EINVAL; + VM_ERR("region_split failed"); + goto ERR_REGION_SPLIT; + } + +ERR_REGION_SPLIT: + (VOID)LOS_MuxRelease(&space->regionMux); + return status; +} + +STATIC VOID OsVmSpaceAllRegionFree(LosVmSpace *space) +{ + LosRbNode *pstRbNode = NULL; + LosRbNode *pstRbNodeNext = NULL; + + /* free all of the regions */ + RB_SCAN_SAFE(&space->regionRbTree, pstRbNode, pstRbNodeNext) + LosVmMapRegion *region = (LosVmMapRegion *)pstRbNode; + if (region->range.size == 0) { + VM_ERR("space free, region: %#x flags: %#x, base:%#x, size: %#x", + region, region->regionFlags, region->range.base, region->range.size); + } + STATUS_T ret = LOS_RegionFree(space, region); + if (ret != LOS_OK) { + VM_ERR("free region error, space %p, region %p", space, region); + } + RB_SCAN_SAFE_END(&space->regionRbTree, pstRbNode, pstRbNodeNext) + + return; +} + +STATUS_T OsVmSpaceRegionFree(LosVmSpace *space) +{ + if (space == NULL) { + return LOS_ERRNO_VM_INVALID_ARGS; + } + + if (space == &g_kVmSpace) { + VM_ERR("try to free kernel aspace, not allowed"); + return LOS_OK; + } + + (VOID)LOS_MuxAcquire(&space->regionMux); + OsVmSpaceAllRegionFree(space); + (VOID)LOS_MuxRelease(&space->regionMux); + + return LOS_OK; +} + +STATUS_T LOS_VmSpaceFree(LosVmSpace *space) +{ + if (space == NULL) { + return LOS_ERRNO_VM_INVALID_ARGS; + } + + if (space == &g_kVmSpace) { + VM_ERR("try to free kernel aspace, not allowed"); + return LOS_OK; + } + + /* pop it out of the global aspace list */ + (VOID)LOS_MuxAcquire(&space->regionMux); + + LOS_ListDelete(&space->node); + + OsVmSpaceAllRegionFree(space); + + /* make sure the current thread does not map the aspace */ + LosProcessCB *currentProcess = OsCurrProcessGet(); + if (currentProcess->vmSpace == space) { + LOS_TaskLock(); + currentProcess->vmSpace = NULL; + LOS_ArchMmuContextSwitch(&space->archMmu); + LOS_TaskUnlock(); + } + + /* destroy the arch portion of the space */ + LOS_ArchMmuDestroy(&space->archMmu); + + (VOID)LOS_MuxRelease(&space->regionMux); + (VOID)LOS_MuxDestroy(&space->regionMux); + + /* free the aspace */ + LOS_MemFree(m_aucSysMem0, space); + return LOS_OK; +} + +BOOL LOS_IsRangeInSpace(const LosVmSpace *space, VADDR_T vaddr, size_t size) +{ + /* is the starting address within the address space */ + if (vaddr < space->base || vaddr > space->base + space->size - 1) { + return FALSE; + } + if (size == 0) { + return TRUE; + } + /* see if the size is enough to wrap the integer */ + if (vaddr + size - 1 < vaddr) { + return FALSE; + } + /* see if the end address is within the address space's */ + if (vaddr + size - 1 > space->base + space->size - 1) { + return FALSE; + } + return TRUE; +} + +STATUS_T LOS_VmSpaceReserve(LosVmSpace *space, size_t size, VADDR_T vaddr) +{ + UINT32 regionFlags = 0; + + if ((space == NULL) || (size == 0) || (!IS_PAGE_ALIGNED(vaddr) || !IS_PAGE_ALIGNED(size))) { + return LOS_ERRNO_VM_INVALID_ARGS; + } + + if (!LOS_IsRangeInSpace(space, vaddr, size)) { + return LOS_ERRNO_VM_OUT_OF_RANGE; + } + + /* lookup how it's already mapped */ + (VOID)LOS_ArchMmuQuery(&space->archMmu, vaddr, NULL, ®ionFlags); + + /* build a new region structure */ + LosVmMapRegion *region = LOS_RegionAlloc(space, vaddr, size, regionFlags | VM_MAP_REGION_FLAG_FIXED, 0); + + return region ? LOS_OK : LOS_ERRNO_VM_NO_MEMORY; +} + +STATUS_T LOS_VaddrToPaddrMmap(LosVmSpace *space, VADDR_T vaddr, PADDR_T paddr, size_t len, UINT32 flags) +{ + STATUS_T ret; + LosVmMapRegion *region = NULL; + LosVmPage *vmPage = NULL; + + if ((vaddr != ROUNDUP(vaddr, PAGE_SIZE)) || + (paddr != ROUNDUP(paddr, PAGE_SIZE)) || + (len != ROUNDUP(len, PAGE_SIZE))) { + VM_ERR("vaddr :0x%x paddr:0x%x len: 0x%x not page size align", vaddr, paddr, len); + return LOS_ERRNO_VM_NOT_VALID; + } + + if (space == NULL) { + space = OsCurrProcessGet()->vmSpace; + } + + region = LOS_RegionFind(space, vaddr); + if (region != NULL) { + VM_ERR("vaddr : 0x%x already used!", vaddr); + return LOS_ERRNO_VM_BUSY; + } + + region = LOS_RegionAlloc(space, vaddr, len, flags, 0); + if (region == NULL) { + VM_ERR("failed"); + return LOS_ERRNO_VM_NO_MEMORY; + } + + while (len > 0) { + vmPage = LOS_VmPageGet(paddr); + if (vmPage == NULL) { + LOS_RegionFree(space, region); + VM_ERR("Page is NULL"); + return LOS_ERRNO_VM_NOT_VALID; + } + LOS_AtomicInc(&vmPage->refCounts); + + ret = LOS_ArchMmuMap(&space->archMmu, vaddr, paddr, 1, region->regionFlags); + if (ret <= 0) { + VM_ERR("LOS_ArchMmuMap failed: %d", ret); + LOS_RegionFree(space, region); + return ret; + } + + paddr += PAGE_SIZE; + vaddr += PAGE_SIZE; + len -= PAGE_SIZE; + } + return LOS_OK; +} + +VOID *LOS_VMalloc(size_t size) +{ + LosVmSpace *space = &g_vMallocSpace; + LosVmMapRegion *region = NULL; + size_t sizeCount; + size_t count; + LosVmPage *vmPage = NULL; + VADDR_T va; + PADDR_T pa; + STATUS_T ret; + + size = LOS_Align(size, PAGE_SIZE); + if ((size == 0) || (size > space->size)) { + return NULL; + } + sizeCount = size >> PAGE_SHIFT; + + LOS_DL_LIST_HEAD(pageList); + (VOID)LOS_MuxAcquire(&space->regionMux); + + count = LOS_PhysPagesAlloc(sizeCount, &pageList); + if (count < sizeCount) { + VM_ERR("failed to allocate enough pages (ask %zu, got %zu)", sizeCount, count); + goto ERROR; + } + + /* allocate a region and put it in the aspace list */ + region = LOS_RegionAlloc(space, 0, size, VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE, 0); + if (region == NULL) { + VM_ERR("alloc region failed, size = %x", size); + goto ERROR; + } + + va = region->range.base; + while ((vmPage = LOS_ListRemoveHeadType(&pageList, LosVmPage, node))) { + pa = vmPage->physAddr; + LOS_AtomicInc(&vmPage->refCounts); + ret = LOS_ArchMmuMap(&space->archMmu, va, pa, 1, region->regionFlags); + if (ret != 1) { + VM_ERR("LOS_ArchMmuMap failed!, err;%d", ret); + } + va += PAGE_SIZE; + } + + (VOID)LOS_MuxRelease(&space->regionMux); + return (VOID *)(UINTPTR)region->range.base; + +ERROR: + (VOID)LOS_PhysPagesFree(&pageList); + (VOID)LOS_MuxRelease(&space->regionMux); + return NULL; +} + +VOID LOS_VFree(const VOID *addr) +{ + LosVmSpace *space = &g_vMallocSpace; + LosVmMapRegion *region = NULL; + STATUS_T ret; + + if (addr == NULL) { + VM_ERR("addr is NULL!"); + return; + } + + (VOID)LOS_MuxAcquire(&space->regionMux); + + region = LOS_RegionFind(space, (VADDR_T)(UINTPTR)addr); + if (region == NULL) { + VM_ERR("find region failed"); + goto DONE; + } + + ret = LOS_RegionFree(space, region); + if (ret) { + VM_ERR("free region failed, ret = %d", ret); + } + +DONE: + (VOID)LOS_MuxRelease(&space->regionMux); +} + +LosMux *OsGVmSpaceMuxGet(VOID) +{ + return &g_vmSpaceListMux; +} + +STATIC INLINE BOOL OsMemLargeAlloc(UINT32 size) +{ + if (g_kHeapInited == FALSE) { + return FALSE; + } + + if (size < KMALLOC_LARGE_SIZE) { + return FALSE; + } + + return TRUE; +} +#else +PADDR_T LOS_PaddrQuery(VOID *vaddr) +{ + if (!LOS_IsKernelAddress((VADDR_T)vaddr)) { + return 0; + } + + return (PADDR_T)VMM_TO_DMA_ADDR((VADDR_T)vaddr); +} +#endif + +VOID *LOS_KernelMalloc(UINT32 size) +{ + VOID *ptr = NULL; + +#ifdef LOSCFG_KERNEL_VM + if (OsMemLargeAlloc(size)) { + ptr = LOS_PhysPagesAllocContiguous(ROUNDUP(size, PAGE_SIZE) >> PAGE_SHIFT); + } else +#endif + { + ptr = LOS_MemAlloc(OS_SYS_MEM_ADDR, size); + } + + return ptr; +} + +VOID *LOS_KernelMallocAlign(UINT32 size, UINT32 boundary) +{ + VOID *ptr = NULL; + +#ifdef LOSCFG_KERNEL_VM + if (OsMemLargeAlloc(size) && IS_ALIGNED(PAGE_SIZE, boundary)) { + ptr = LOS_PhysPagesAllocContiguous(ROUNDUP(size, PAGE_SIZE) >> PAGE_SHIFT); + } else +#endif + { + ptr = LOS_MemAllocAlign(OS_SYS_MEM_ADDR, size, boundary); + } + + return ptr; +} + +VOID *LOS_KernelRealloc(VOID *ptr, UINT32 size) +{ + VOID *tmpPtr = NULL; + +#ifdef LOSCFG_KERNEL_VM + LosVmPage *page = NULL; + errno_t ret; + if (ptr == NULL) { + tmpPtr = LOS_KernelMalloc(size); + } else { + if (OsMemIsHeapNode(ptr) == FALSE) { + page = OsVmVaddrToPage(ptr); + if (page == NULL) { + VM_ERR("page of ptr(%#x) is null", ptr); + return NULL; + } + tmpPtr = LOS_KernelMalloc(size); + if (tmpPtr == NULL) { + VM_ERR("alloc memory failed"); + return NULL; + } + ret = memcpy_s(tmpPtr, size, ptr, page->nPages << PAGE_SHIFT); + if (ret != EOK) { + LOS_KernelFree(tmpPtr); + VM_ERR("KernelRealloc memcpy error"); + return NULL; + } + OsMemLargeNodeFree(ptr); + } else { + tmpPtr = LOS_MemRealloc(OS_SYS_MEM_ADDR, ptr, size); + } + } +#else + tmpPtr = LOS_MemRealloc(OS_SYS_MEM_ADDR, ptr, size); +#endif + + return tmpPtr; +} + +VOID LOS_KernelFree(VOID *ptr) +{ +#ifdef LOSCFG_KERNEL_VM + UINT32 ret; + if (OsMemIsHeapNode(ptr) == FALSE) { + ret = OsMemLargeNodeFree(ptr); + if (ret != LOS_OK) { + VM_ERR("KernelFree %p failed", ptr); + return; + } + } else +#endif + { + (VOID)LOS_MemFree(OS_SYS_MEM_ADDR, ptr); + } +} diff --git a/src/kernel_liteos_a/kernel/base/vm/los_vm_page.c b/src/kernel_liteos_a/kernel/base/vm/los_vm_page.c new file mode 100644 index 00000000..650fd0b0 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/vm/los_vm_page.c @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_vm_page.h" +#include "los_vm_common.h" +#include "los_vm_phys.h" +#include "los_vm_boot.h" +#include "los_vm_filemap.h" +#ifdef LOSCFG_KERNEL_MEM_PLIMIT +#include "los_plimits.h" +#endif + +#ifdef LOSCFG_KERNEL_VM + +LosVmPage *g_vmPageArray = NULL; +size_t g_vmPageArraySize; + +STATIC VOID OsVmPageInit(LosVmPage *page, paddr_t pa, UINT8 segID) +{ + LOS_ListInit(&page->node); + page->flags = FILE_PAGE_FREE; + LOS_AtomicSet(&page->refCounts, 0); + page->physAddr = pa; + page->segID = segID; + page->order = VM_LIST_ORDER_MAX; + page->nPages = 0; +#ifdef LOSCFG_PAGE_TABLE_FINE_LOCK + LOS_SpinInit(&page->lock); +#endif +} + +STATIC INLINE VOID OsVmPageOrderListInit(LosVmPage *page, size_t nPages) +{ + OsVmPhysPagesFreeContiguous(page, nPages); +} + +#define VMPAGEINIT(page, pa, segID) do { \ + OsVmPageInit(page, pa, segID); \ + (page)++; \ + (pa) += PAGE_SIZE; \ +} while (0) + +VOID OsVmPageStartup(VOID) +{ + struct VmPhysSeg *seg = NULL; + LosVmPage *page = NULL; + paddr_t pa; + UINT32 nPage; + INT32 segID; + + OsVmPhysAreaSizeAdjust(ROUNDUP((g_vmBootMemBase - KERNEL_ASPACE_BASE), PAGE_SIZE)); + + /* + * Pages getting from OsVmPhysPageNumGet() interface here contain the memory + * struct LosVmPage occupied, which satisfies the equation: + * nPage * sizeof(LosVmPage) + nPage * PAGE_SIZE = OsVmPhysPageNumGet() * PAGE_SIZE. + */ + UINT32 pageNum = OsVmPhysPageNumGet(); + nPage = pageNum * PAGE_SIZE / (sizeof(LosVmPage) + PAGE_SIZE); + g_vmPageArraySize = nPage * sizeof(LosVmPage); + g_vmPageArray = (LosVmPage *)OsVmBootMemAlloc(g_vmPageArraySize); + + OsVmPhysAreaSizeAdjust(ROUNDUP(g_vmPageArraySize, PAGE_SIZE)); + + OsVmPhysSegAdd(); + OsVmPhysInit(); +#ifdef LOSCFG_KERNEL_PLIMITS + OsMemLimitSetLimit(pageNum * PAGE_SIZE); +#endif + + for (segID = 0; segID < g_vmPhysSegNum; segID++) { + seg = &g_vmPhysSeg[segID]; + nPage = seg->size >> PAGE_SHIFT; + UINT32 count = nPage >> 3; /* 3: 2 ^ 3, nPage / 8, cycle count */ + UINT32 left = nPage & 0x7; /* 0x7: nPage % 8, left page */ + + for (page = seg->pageBase, pa = seg->start; count > 0; count--) { + /* note: process large amount of data, optimize performance */ + VMPAGEINIT(page, pa, segID); + VMPAGEINIT(page, pa, segID); + VMPAGEINIT(page, pa, segID); + VMPAGEINIT(page, pa, segID); + VMPAGEINIT(page, pa, segID); + VMPAGEINIT(page, pa, segID); + VMPAGEINIT(page, pa, segID); + VMPAGEINIT(page, pa, segID); + } + for (; left > 0; left--) { + VMPAGEINIT(page, pa, segID); + } + OsVmPageOrderListInit(seg->pageBase, nPage); + } +} + +LosVmPage *LOS_VmPageGet(PADDR_T paddr) +{ + INT32 segID; + LosVmPage *page = NULL; + + for (segID = 0; segID < g_vmPhysSegNum; segID++) { + page = OsVmPhysToPage(paddr, segID); + if (page != NULL) { + break; + } + } + + return page; +} +#endif + diff --git a/src/kernel_liteos_a/kernel/base/vm/los_vm_phys.c b/src/kernel_liteos_a/kernel/base/vm/los_vm_phys.c new file mode 100644 index 00000000..2c581456 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/vm/los_vm_phys.c @@ -0,0 +1,635 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_vm_phys.h" +#include "los_vm_boot.h" +#include "los_vm_common.h" +#include "los_vm_map.h" +#include "los_vm_dump.h" +#include "los_process_pri.h" + + +#ifdef LOSCFG_KERNEL_VM + +#define ONE_PAGE 1 + +/* Physical memory area array */ +STATIC struct VmPhysArea g_physArea[] = { + { + .start = SYS_MEM_BASE, + .size = SYS_MEM_SIZE_DEFAULT, + }, +}; + +struct VmPhysSeg g_vmPhysSeg[VM_PHYS_SEG_MAX]; +INT32 g_vmPhysSegNum = 0; + +LosVmPhysSeg *OsGVmPhysSegGet(void) +{ + return g_vmPhysSeg; +} + +STATIC VOID OsVmPhysLruInit(struct VmPhysSeg *seg) +{ + INT32 i; + UINT32 intSave; + LOS_SpinInit(&seg->lruLock); + + LOS_SpinLockSave(&seg->lruLock, &intSave); + for (i = 0; i < VM_NR_LRU_LISTS; i++) { + seg->lruSize[i] = 0; + LOS_ListInit(&seg->lruList[i]); + } + LOS_SpinUnlockRestore(&seg->lruLock, intSave); +} + +STATIC INT32 OsVmPhysSegCreate(paddr_t start, size_t size) +{ + struct VmPhysSeg *seg = NULL; + + if (g_vmPhysSegNum >= VM_PHYS_SEG_MAX) { + return -1; + } + + seg = &g_vmPhysSeg[g_vmPhysSegNum++]; + for (; (seg > g_vmPhysSeg) && ((seg - 1)->start > (start + size)); seg--) { + *seg = *(seg - 1); + } + seg->start = start; + seg->size = size; + + return 0; +} + +VOID OsVmPhysSegAdd(VOID) +{ + INT32 i, ret; + + LOS_ASSERT(g_vmPhysSegNum < VM_PHYS_SEG_MAX); + + for (i = 0; i < (sizeof(g_physArea) / sizeof(g_physArea[0])); i++) { + ret = OsVmPhysSegCreate(g_physArea[i].start, g_physArea[i].size); + if (ret != 0) { + VM_ERR("create phys seg failed"); + } + } +} + +VOID OsVmPhysAreaSizeAdjust(size_t size) +{ + /* + * The first physics memory segment is used for kernel image and kernel heap, + * so just need to adjust the first one here. + */ + g_physArea[0].start += size; + g_physArea[0].size -= size; +} + +UINT32 OsVmPhysPageNumGet(VOID) +{ + UINT32 nPages = 0; + INT32 i; + + for (i = 0; i < (sizeof(g_physArea) / sizeof(g_physArea[0])); i++) { + nPages += g_physArea[i].size >> PAGE_SHIFT; + } + + return nPages; +} + +STATIC INLINE VOID OsVmPhysFreeListInit(struct VmPhysSeg *seg) +{ + int i; + UINT32 intSave; + struct VmFreeList *list = NULL; + + LOS_SpinInit(&seg->freeListLock); + + LOS_SpinLockSave(&seg->freeListLock, &intSave); + for (i = 0; i < VM_LIST_ORDER_MAX; i++) { + list = &seg->freeList[i]; + LOS_ListInit(&list->node); + list->listCnt = 0; + } + LOS_SpinUnlockRestore(&seg->freeListLock, intSave); +} + +VOID OsVmPhysInit(VOID) +{ + struct VmPhysSeg *seg = NULL; + UINT32 nPages = 0; + int i; + + for (i = 0; i < g_vmPhysSegNum; i++) { + seg = &g_vmPhysSeg[i]; + seg->pageBase = &g_vmPageArray[nPages]; + nPages += seg->size >> PAGE_SHIFT; + OsVmPhysFreeListInit(seg); + OsVmPhysLruInit(seg); + } +} + +STATIC VOID OsVmPhysFreeListAddUnsafe(LosVmPage *page, UINT8 order) +{ + struct VmPhysSeg *seg = NULL; + struct VmFreeList *list = NULL; + + if (page->segID >= VM_PHYS_SEG_MAX) { + LOS_Panic("The page segment id(%d) is invalid\n", page->segID); + } + + page->order = order; + seg = &g_vmPhysSeg[page->segID]; + + list = &seg->freeList[order]; + LOS_ListTailInsert(&list->node, &page->node); + list->listCnt++; +} + +STATIC VOID OsVmPhysFreeListDelUnsafe(LosVmPage *page) +{ + struct VmPhysSeg *seg = NULL; + struct VmFreeList *list = NULL; + + if ((page->segID >= VM_PHYS_SEG_MAX) || (page->order >= VM_LIST_ORDER_MAX)) { + LOS_Panic("The page segment id(%u) or order(%u) is invalid\n", page->segID, page->order); + } + + seg = &g_vmPhysSeg[page->segID]; + list = &seg->freeList[page->order]; + list->listCnt--; + LOS_ListDelete(&page->node); + page->order = VM_LIST_ORDER_MAX; +} + +STATIC VOID OsVmPhysPagesSpiltUnsafe(LosVmPage *page, UINT8 oldOrder, UINT8 newOrder) +{ + UINT32 order; + LosVmPage *buddyPage = NULL; + + for (order = newOrder; order > oldOrder;) { + order--; + buddyPage = &page[VM_ORDER_TO_PAGES(order)]; + LOS_ASSERT(buddyPage->order == VM_LIST_ORDER_MAX); + OsVmPhysFreeListAddUnsafe(buddyPage, order); + } +} + +LosVmPage *OsVmPhysToPage(paddr_t pa, UINT8 segID) +{ + struct VmPhysSeg *seg = NULL; + paddr_t offset; + + if (segID >= VM_PHYS_SEG_MAX) { + LOS_Panic("The page segment id(%d) is invalid\n", segID); + } + seg = &g_vmPhysSeg[segID]; + if ((pa < seg->start) || (pa >= (seg->start + seg->size))) { + return NULL; + } + + offset = pa - seg->start; + return (seg->pageBase + (offset >> PAGE_SHIFT)); +} + +LosVmPage *OsVmPaddrToPage(paddr_t paddr) +{ + INT32 segID; + LosVmPage *vmPage = NULL; + + for (segID = 0; segID < g_vmPhysSegNum; segID++) { + vmPage = OsVmPhysToPage(paddr, segID); + if (vmPage != NULL) { + return vmPage; + } + } + return NULL; +} + +VOID *OsVmPageToVaddr(LosVmPage *page) +{ + VADDR_T vaddr; + vaddr = KERNEL_ASPACE_BASE + page->physAddr - SYS_MEM_BASE; + + return (VOID *)(UINTPTR)vaddr; +} + +LosVmPage *OsVmVaddrToPage(VOID *ptr) +{ + struct VmPhysSeg *seg = NULL; + PADDR_T pa = LOS_PaddrQuery(ptr); + UINT32 segID; + + for (segID = 0; segID < g_vmPhysSegNum; segID++) { + seg = &g_vmPhysSeg[segID]; + if ((pa >= seg->start) && (pa < (seg->start + seg->size))) { + return seg->pageBase + ((pa - seg->start) >> PAGE_SHIFT); + } + } + + return NULL; +} + +STATIC INLINE VOID OsVmRecycleExtraPages(LosVmPage *page, size_t startPage, size_t endPage) +{ + if (startPage >= endPage) { + return; + } + + OsVmPhysPagesFreeContiguous(page, endPage - startPage); +} + +STATIC LosVmPage *OsVmPhysLargeAlloc(struct VmPhysSeg *seg, size_t nPages) +{ + struct VmFreeList *list = NULL; + LosVmPage *page = NULL; + LosVmPage *tmp = NULL; + PADDR_T paStart; + PADDR_T paEnd; + size_t size = nPages << PAGE_SHIFT; + + list = &seg->freeList[VM_LIST_ORDER_MAX - 1]; + LOS_DL_LIST_FOR_EACH_ENTRY(page, &list->node, LosVmPage, node) { + paStart = page->physAddr; + paEnd = paStart + size; + if (paEnd > (seg->start + seg->size)) { + continue; + } + + for (;;) { + paStart += PAGE_SIZE << (VM_LIST_ORDER_MAX - 1); + if ((paStart >= paEnd) || (paStart < seg->start) || + (paStart >= (seg->start + seg->size))) { + break; + } + tmp = &seg->pageBase[(paStart - seg->start) >> PAGE_SHIFT]; + if (tmp->order != (VM_LIST_ORDER_MAX - 1)) { + break; + } + } + if (paStart >= paEnd) { + return page; + } + } + + return NULL; +} + +STATIC LosVmPage *OsVmPhysPagesAlloc(struct VmPhysSeg *seg, size_t nPages) +{ + struct VmFreeList *list = NULL; + LosVmPage *page = NULL; + LosVmPage *tmp = NULL; + UINT32 order; + UINT32 newOrder; + + order = OsVmPagesToOrder(nPages); + if (order < VM_LIST_ORDER_MAX) { + for (newOrder = order; newOrder < VM_LIST_ORDER_MAX; newOrder++) { + list = &seg->freeList[newOrder]; + if (LOS_ListEmpty(&list->node)) { + continue; + } + page = LOS_DL_LIST_ENTRY(LOS_DL_LIST_FIRST(&list->node), LosVmPage, node); + goto DONE; + } + } else { + newOrder = VM_LIST_ORDER_MAX - 1; + page = OsVmPhysLargeAlloc(seg, nPages); + if (page != NULL) { + goto DONE; + } + } + return NULL; +DONE: + + for (tmp = page; tmp < &page[nPages]; tmp = &tmp[1 << newOrder]) { + OsVmPhysFreeListDelUnsafe(tmp); + } + OsVmPhysPagesSpiltUnsafe(page, order, newOrder); + OsVmRecycleExtraPages(&page[nPages], nPages, ROUNDUP(nPages, (1 << min(order, newOrder)))); + + return page; +} + +VOID OsVmPhysPagesFree(LosVmPage *page, UINT8 order) +{ + paddr_t pa; + LosVmPage *buddyPage = NULL; + + if ((page == NULL) || (order >= VM_LIST_ORDER_MAX)) { + return; + } + + if (order < VM_LIST_ORDER_MAX - 1) { + pa = VM_PAGE_TO_PHYS(page); + do { + pa ^= VM_ORDER_TO_PHYS(order); + buddyPage = OsVmPhysToPage(pa, page->segID); + if ((buddyPage == NULL) || (buddyPage->order != order)) { + break; + } + OsVmPhysFreeListDelUnsafe(buddyPage); + order++; + pa &= ~(VM_ORDER_TO_PHYS(order) - 1); + page = OsVmPhysToPage(pa, page->segID); + } while (order < VM_LIST_ORDER_MAX - 1); + } + + OsVmPhysFreeListAddUnsafe(page, order); +} + +VOID OsVmPhysPagesFreeContiguous(LosVmPage *page, size_t nPages) +{ + paddr_t pa; + UINT32 order; + size_t n; + + while (TRUE) { + pa = VM_PAGE_TO_PHYS(page); + order = VM_PHYS_TO_ORDER(pa); + n = VM_ORDER_TO_PAGES(order); + if (n > nPages) { + break; + } + OsVmPhysPagesFree(page, order); + nPages -= n; + page += n; + } + + while (nPages > 0) { + order = LOS_HighBitGet(nPages); + n = VM_ORDER_TO_PAGES(order); + OsVmPhysPagesFree(page, order); + nPages -= n; + page += n; + } +} + +STATIC LosVmPage *OsVmPhysPagesGet(size_t nPages) +{ + UINT32 intSave; + struct VmPhysSeg *seg = NULL; + LosVmPage *page = NULL; + UINT32 segID; + + for (segID = 0; segID < g_vmPhysSegNum; segID++) { + seg = &g_vmPhysSeg[segID]; + LOS_SpinLockSave(&seg->freeListLock, &intSave); + page = OsVmPhysPagesAlloc(seg, nPages); + if (page != NULL) { + /* the first page of continuous physical addresses holds refCounts */ + LOS_AtomicSet(&page->refCounts, 0); + page->nPages = nPages; + LOS_SpinUnlockRestore(&seg->freeListLock, intSave); + return page; + } + LOS_SpinUnlockRestore(&seg->freeListLock, intSave); + } + return NULL; +} + +VOID *LOS_PhysPagesAllocContiguous(size_t nPages) +{ + LosVmPage *page = NULL; + + if (nPages == 0) { + return NULL; + } + + page = OsVmPhysPagesGet(nPages); + if (page == NULL) { + return NULL; + } + + return OsVmPageToVaddr(page); +} + +VOID LOS_PhysPagesFreeContiguous(VOID *ptr, size_t nPages) +{ + UINT32 intSave; + struct VmPhysSeg *seg = NULL; + LosVmPage *page = NULL; + + if (ptr == NULL) { + return; + } + + page = OsVmVaddrToPage(ptr); + if (page == NULL) { + VM_ERR("vm page of ptr(%#x) is null", ptr); + return; + } + page->nPages = 0; + + seg = &g_vmPhysSeg[page->segID]; + LOS_SpinLockSave(&seg->freeListLock, &intSave); + + OsVmPhysPagesFreeContiguous(page, nPages); + + LOS_SpinUnlockRestore(&seg->freeListLock, intSave); +#ifdef LOSCFG_KERNEL_PLIMITS + OsMemLimitMemFree(nPages * PAGE_SIZE); +#endif +} + +PADDR_T OsKVaddrToPaddr(VADDR_T kvaddr) +{ + if (kvaddr == 0) { + return 0; + } + return (kvaddr - KERNEL_ASPACE_BASE + SYS_MEM_BASE); +} + +VADDR_T *LOS_PaddrToKVaddr(PADDR_T paddr) +{ + struct VmPhysSeg *seg = NULL; + UINT32 segID; + + if (paddr == 0) { + return NULL; + } + + for (segID = 0; segID < g_vmPhysSegNum; segID++) { + seg = &g_vmPhysSeg[segID]; + if ((paddr >= seg->start) && (paddr < (seg->start + seg->size))) { + return (VADDR_T *)(UINTPTR)(paddr - SYS_MEM_BASE + KERNEL_ASPACE_BASE); + } + } + + return (VADDR_T *)(UINTPTR)(paddr - SYS_MEM_BASE + KERNEL_ASPACE_BASE); +} + +VOID LOS_PhysPageFree(LosVmPage *page) +{ + UINT32 intSave; + struct VmPhysSeg *seg = NULL; + + if (page == NULL) { + return; + } + + if (LOS_AtomicDecRet(&page->refCounts) <= 0) { + seg = &g_vmPhysSeg[page->segID]; + LOS_SpinLockSave(&seg->freeListLock, &intSave); + + OsVmPhysPagesFreeContiguous(page, ONE_PAGE); + LOS_AtomicSet(&page->refCounts, 0); + + LOS_SpinUnlockRestore(&seg->freeListLock, intSave); + } +#ifdef LOSCFG_KERNEL_PLIMITS + OsMemLimitMemFree(PAGE_SIZE); +#endif +} + +LosVmPage *LOS_PhysPageAlloc(VOID) +{ + return OsVmPhysPagesGet(ONE_PAGE); +} + +size_t LOS_PhysPagesAlloc(size_t nPages, LOS_DL_LIST *list) +{ + LosVmPage *page = NULL; + size_t count = 0; + + if ((list == NULL) || (nPages == 0)) { + return 0; + } + + while (nPages--) { + page = OsVmPhysPagesGet(ONE_PAGE); + if (page == NULL) { + break; + } + LOS_ListTailInsert(list, &page->node); + count++; + } + + return count; +} + +VOID OsPhysSharePageCopy(PADDR_T oldPaddr, PADDR_T *newPaddr, LosVmPage *newPage) +{ + UINT32 intSave; + LosVmPage *oldPage = NULL; + VOID *newMem = NULL; + VOID *oldMem = NULL; + LosVmPhysSeg *seg = NULL; + + if ((newPage == NULL) || (newPaddr == NULL)) { + VM_ERR("new Page invalid"); + return; + } + + oldPage = LOS_VmPageGet(oldPaddr); + if (oldPage == NULL) { + VM_ERR("invalid oldPaddr %p", oldPaddr); + return; + } + + seg = &g_vmPhysSeg[oldPage->segID]; + LOS_SpinLockSave(&seg->freeListLock, &intSave); + if (LOS_AtomicRead(&oldPage->refCounts) == 1) { + *newPaddr = oldPaddr; + } else { + newMem = LOS_PaddrToKVaddr(*newPaddr); + oldMem = LOS_PaddrToKVaddr(oldPaddr); + if ((newMem == NULL) || (oldMem == NULL)) { + LOS_SpinUnlockRestore(&seg->freeListLock, intSave); + return; + } + if (memcpy_s(newMem, PAGE_SIZE, oldMem, PAGE_SIZE) != EOK) { + VM_ERR("memcpy_s failed"); + } + + LOS_AtomicInc(&newPage->refCounts); + LOS_AtomicDec(&oldPage->refCounts); + } + LOS_SpinUnlockRestore(&seg->freeListLock, intSave); + return; +} + +struct VmPhysSeg *OsVmPhysSegGet(LosVmPage *page) +{ + if ((page == NULL) || (page->segID >= VM_PHYS_SEG_MAX)) { + return NULL; + } + + return (OsGVmPhysSegGet() + page->segID); +} + +UINT32 OsVmPagesToOrder(size_t nPages) +{ + UINT32 order; + + for (order = 0; VM_ORDER_TO_PAGES(order) < nPages; order++); + + return order; +} + +size_t LOS_PhysPagesFree(LOS_DL_LIST *list) +{ + UINT32 intSave; + LosVmPage *page = NULL; + LosVmPage *nPage = NULL; + LosVmPhysSeg *seg = NULL; + size_t count = 0; + + if (list == NULL) { + return 0; + } + + LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(page, nPage, list, LosVmPage, node) { + LOS_ListDelete(&page->node); + if (LOS_AtomicDecRet(&page->refCounts) <= 0) { + seg = &g_vmPhysSeg[page->segID]; + LOS_SpinLockSave(&seg->freeListLock, &intSave); + OsVmPhysPagesFreeContiguous(page, ONE_PAGE); + LOS_AtomicSet(&page->refCounts, 0); + LOS_SpinUnlockRestore(&seg->freeListLock, intSave); + } + count++; + } + + return count; +} +#else +VADDR_T *LOS_PaddrToKVaddr(PADDR_T paddr) +{ + if ((paddr < DDR_MEM_ADDR) || (paddr >= ((PADDR_T)DDR_MEM_ADDR + DDR_MEM_SIZE))) { + return NULL; + } + + return (VADDR_T *)DMA_TO_VMM_ADDR(paddr); +} +#endif + diff --git a/src/kernel_liteos_a/kernel/base/vm/los_vm_scan.c b/src/kernel_liteos_a/kernel/base/vm/los_vm_scan.c new file mode 100644 index 00000000..ab467818 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/vm/los_vm_scan.c @@ -0,0 +1,343 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef LOSCFG_FS_VFS + +#include "fs/file.h" +#include "los_vm_filemap.h" + +#ifdef LOSCFG_KERNEL_VM + +/* unmap a lru page by map record info caller need lru lock */ +VOID OsUnmapPageLocked(LosFilePage *page, LosMapInfo *info) +{ + if (page == NULL || info == NULL) { + VM_ERR("UnmapPage error input null!"); + return; + } + page->n_maps--; + LOS_ListDelete(&info->node); + LOS_AtomicDec(&page->vmPage->refCounts); + LOS_ArchMmuUnmap(info->archMmu, info->vaddr, 1); + LOS_MemFree(m_aucSysMem0, info); +} + +VOID OsUnmapAllLocked(LosFilePage *page) +{ + LosMapInfo *info = NULL; + LosMapInfo *next = NULL; + LOS_DL_LIST *immap = &page->i_mmap; + + LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(info, next, immap, LosMapInfo, node) { + OsUnmapPageLocked(page, info); + } +} + +/* add a new lru node to lru list, lruType can be file or anon */ +VOID OsLruCacheAdd(LosFilePage *fpage, enum OsLruList lruType) +{ + UINT32 intSave; + LosVmPhysSeg *physSeg = fpage->physSeg; + LosVmPage *page = fpage->vmPage; + + LOS_SpinLockSave(&physSeg->lruLock, &intSave); + OsSetPageActive(page); + OsCleanPageReferenced(page); + physSeg->lruSize[lruType]++; + LOS_ListTailInsert(&physSeg->lruList[lruType], &fpage->lru); + + LOS_SpinUnlockRestore(&physSeg->lruLock, intSave); +} + +/* delete a lru node, caller need hold lru_lock */ +VOID OsLruCacheDel(LosFilePage *fpage) +{ + LosVmPhysSeg *physSeg = fpage->physSeg; + int type = OsIsPageActive(fpage->vmPage) ? VM_LRU_ACTIVE_FILE : VM_LRU_INACTIVE_FILE; + + physSeg->lruSize[type]--; + LOS_ListDelete(&fpage->lru); +} + +BOOL OsInactiveListIsLow(LosVmPhysSeg *physSeg) +{ + return (physSeg->lruSize[VM_LRU_ACTIVE_FILE] > + physSeg->lruSize[VM_LRU_INACTIVE_FILE]) ? TRUE : FALSE; +} + +/* move a page from inactive list to active list head */ +STATIC INLINE VOID OsMoveToActiveList(LosFilePage *fpage) +{ + LosVmPhysSeg *physSeg = fpage->physSeg; + + physSeg->lruSize[VM_LRU_ACTIVE_FILE]++; + physSeg->lruSize[VM_LRU_INACTIVE_FILE]--; + LOS_ListDelete(&fpage->lru); + LOS_ListTailInsert(&physSeg->lruList[VM_LRU_ACTIVE_FILE], &fpage->lru); +} + +/* move a page from active list to inactive list head */ +STATIC INLINE VOID OsMoveToInactiveList(LosFilePage *fpage) +{ + LosVmPhysSeg *physSeg = fpage->physSeg; + + physSeg->lruSize[VM_LRU_ACTIVE_FILE]--; + physSeg->lruSize[VM_LRU_INACTIVE_FILE]++; + LOS_ListDelete(&fpage->lru); + LOS_ListTailInsert(&physSeg->lruList[VM_LRU_INACTIVE_FILE], &fpage->lru); +} + +/* move a page to the most active pos in lru list(active head) */ +STATIC INLINE VOID OsMoveToActiveHead(LosFilePage *fpage) +{ + LosVmPhysSeg *physSeg = fpage->physSeg; + LOS_ListDelete(&fpage->lru); + LOS_ListTailInsert(&physSeg->lruList[VM_LRU_ACTIVE_FILE], &fpage->lru); +} + +/* move a page to the most active pos in lru list(inactive head) */ +STATIC INLINE VOID OsMoveToInactiveHead(LosFilePage *fpage) +{ + LosVmPhysSeg *physSeg = fpage->physSeg; + LOS_ListDelete(&fpage->lru); + LOS_ListTailInsert(&physSeg->lruList[VM_LRU_INACTIVE_FILE], &fpage->lru); +} + +/* page referced add: (call by page cache get) +----------inactive----------|----------active------------ +[ref:0,act:0], [ref:1,act:0]|[ref:0,act:1], [ref:1,act:1] +ref:0, act:0 --> ref:1, act:0 +ref:1, act:0 --> ref:0, act:1 +ref:0, act:1 --> ref:1, act:1 +*/ +VOID OsPageRefIncLocked(LosFilePage *fpage) +{ + BOOL isOrgActive; + UINT32 intSave; + LosVmPage *page = NULL; + + if (fpage == NULL) { + return; + } + + LOS_SpinLockSave(&fpage->physSeg->lruLock, &intSave); + + page = fpage->vmPage; + isOrgActive = OsIsPageActive(page); + + if (OsIsPageReferenced(page) && !OsIsPageActive(page)) { + OsCleanPageReferenced(page); + OsSetPageActive(page); + } else if (!OsIsPageReferenced(page)) { + OsSetPageReferenced(page); + } + + if (!isOrgActive && OsIsPageActive(page)) { + /* move inactive to active */ + OsMoveToActiveList(fpage); + /* no change, move head */ + } else { + if (OsIsPageActive(page)) { + OsMoveToActiveHead(fpage); + } else { + OsMoveToInactiveHead(fpage); + } + } + + LOS_SpinUnlockRestore(&fpage->physSeg->lruLock, intSave); +} + +/* page referced dec: (call by shrinker) +----------inactive----------|----------active------------ +[ref:0,act:0], [ref:1,act:0]|[ref:0,act:1], [ref:1,act:1] +ref:1, act:1 --> ref:0, act:1 +ref:0, act:1 --> ref:1, act:0 +ref:1, act:0 --> ref:0, act:0 +*/ +VOID OsPageRefDecNoLock(LosFilePage *fpage) +{ + BOOL isOrgActive; + LosVmPage *page = NULL; + + if (fpage == NULL) { + return; + } + + page = fpage->vmPage; + isOrgActive = OsIsPageActive(page); + + if (!OsIsPageReferenced(page) && OsIsPageActive(page)) { + OsCleanPageActive(page); + OsSetPageReferenced(page); + } else if (OsIsPageReferenced(page)) { + OsCleanPageReferenced(page); + } + + if (isOrgActive && !OsIsPageActive(page)) { + OsMoveToInactiveList(fpage); + } +} + +VOID OsShrinkActiveList(LosVmPhysSeg *physSeg, int nScan) +{ + LosFilePage *fpage = NULL; + LosFilePage *fnext = NULL; + LOS_DL_LIST *activeFile = &physSeg->lruList[VM_LRU_ACTIVE_FILE]; + + LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(fpage, fnext, activeFile, LosFilePage, lru) { + if (LOS_SpinTrylock(&fpage->mapping->list_lock) != LOS_OK) { + continue; + } + + /* happened when caller hold cache lock and try reclaim this page */ + if (OsIsPageLocked(fpage->vmPage)) { + LOS_SpinUnlock(&fpage->mapping->list_lock); + continue; + } + + if (OsIsPageMapped(fpage) && (fpage->flags & VM_MAP_REGION_FLAG_PERM_EXECUTE)) { + LOS_SpinUnlock(&fpage->mapping->list_lock); + continue; + } + + OsPageRefDecNoLock(fpage); + + LOS_SpinUnlock(&fpage->mapping->list_lock); + + if (--nScan <= 0) { + break; + } + } +} + +int OsShrinkInactiveList(LosVmPhysSeg *physSeg, int nScan, LOS_DL_LIST *list) +{ + UINT32 nrReclaimed = 0; + LosVmPage *page = NULL; + SPIN_LOCK_S *flock = NULL; + LosFilePage *fpage = NULL; + LosFilePage *fnext = NULL; + LosFilePage *ftemp = NULL; + LOS_DL_LIST *inactive_file = &physSeg->lruList[VM_LRU_INACTIVE_FILE]; + + LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(fpage, fnext, inactive_file, LosFilePage, lru) { + flock = &fpage->mapping->list_lock; + + if (LOS_SpinTrylock(flock) != LOS_OK) { + continue; + } + + page = fpage->vmPage; + if (OsIsPageLocked(page)) { + LOS_SpinUnlock(flock); + continue; + } + + if (OsIsPageMapped(fpage) && (OsIsPageDirty(page) || (fpage->flags & VM_MAP_REGION_FLAG_PERM_EXECUTE))) { + LOS_SpinUnlock(flock); + continue; + } + + if (OsIsPageDirty(page)) { + ftemp = OsDumpDirtyPage(fpage); + if (ftemp != NULL) { + LOS_ListTailInsert(list, &ftemp->node); + } + } + + OsDeletePageCacheLru(fpage); + LOS_SpinUnlock(flock); + nrReclaimed++; + + if (--nScan <= 0) { + break; + } + } + + return nrReclaimed; +} + +#ifdef LOSCFG_FS_VFS +int OsTryShrinkMemory(size_t nPage) +{ + UINT32 intSave; + size_t totalPages; + size_t nReclaimed = 0; + LosVmPhysSeg *physSeg = NULL; + UINT32 index; + LOS_DL_LIST_HEAD(dirtyList); + LosFilePage *fpage = NULL; + LosFilePage *fnext = NULL; + + if (nPage == 0) { + nPage = VM_FILEMAP_MIN_SCAN; + } + + if (nPage > VM_FILEMAP_MAX_SCAN) { + nPage = VM_FILEMAP_MAX_SCAN; + } + + for (index = 0; index < g_vmPhysSegNum; index++) { + physSeg = &g_vmPhysSeg[index]; + LOS_SpinLockSave(&physSeg->lruLock, &intSave); + totalPages = physSeg->lruSize[VM_LRU_ACTIVE_FILE] + physSeg->lruSize[VM_LRU_INACTIVE_FILE]; + if (totalPages < VM_FILEMAP_MIN_SCAN) { + LOS_SpinUnlockRestore(&physSeg->lruLock, intSave); + continue; + } + + if (OsInactiveListIsLow(physSeg)) { + OsShrinkActiveList(physSeg, (nPage < VM_FILEMAP_MIN_SCAN) ? VM_FILEMAP_MIN_SCAN : nPage); + } + + nReclaimed += OsShrinkInactiveList(physSeg, nPage, &dirtyList); + LOS_SpinUnlockRestore(&physSeg->lruLock, intSave); + + if (nReclaimed >= nPage) { + break; + } + } + + LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(fpage, fnext, &dirtyList, LosFilePage, node) { + OsDoFlushDirtyPage(fpage); + } + + return nReclaimed; +} +#else +int OsTryShrinkMemory(size_t nPage) +{ + return 0; +} +#endif +#endif + +#endif diff --git a/src/kernel_liteos_a/kernel/base/vm/los_vm_syscall.c b/src/kernel_liteos_a/kernel/base/vm/los_vm_syscall.c new file mode 100644 index 00000000..6aa23993 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/vm/los_vm_syscall.c @@ -0,0 +1,517 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_vm_syscall vm syscall definition + * @ingroup kernel + */ + +#include "los_typedef.h" +#include "los_vm_syscall.h" +#include "los_vm_common.h" +#include "los_rbtree.h" +#include "los_vm_map.h" +#include "los_vm_dump.h" +#include "los_vm_lock.h" +#include "los_vm_filemap.h" +#include "los_process_pri.h" + + +#ifdef LOSCFG_KERNEL_VM + +STATUS_T OsCheckMMapParams(VADDR_T *vaddr, unsigned long flags, size_t len, unsigned long pgoff) +{ + if ((len == 0) || (len > USER_ASPACE_SIZE)) { + return -EINVAL; + } + if (len > OsCurrProcessGet()->vmSpace->mapSize) { + return -ENOMEM; + } + + if (((flags & MAP_FIXED) == 0) && ((flags & MAP_FIXED_NOREPLACE) == 0)) { + *vaddr = ROUNDUP(*vaddr, PAGE_SIZE); + if ((*vaddr != 0) && (!LOS_IsUserAddressRange(*vaddr, len))) { + *vaddr = 0; + } + } else if ((!LOS_IsUserAddressRange(*vaddr, len)) || (!IS_ALIGNED(*vaddr, PAGE_SIZE))) { + return -EINVAL; + } + + if ((flags & MAP_SUPPORT_MASK) == 0) { + return -EINVAL; + } + if (((flags & MAP_SHARED_PRIVATE) == 0) || ((flags & MAP_SHARED_PRIVATE) == MAP_SHARED_PRIVATE)) { + return -EINVAL; + } + + if (((len >> PAGE_SHIFT) + pgoff) < pgoff) { + return -EINVAL; + } + + return LOS_OK; +} + +STATUS_T OsNamedMmapingPermCheck(struct file *filep, unsigned long flags, unsigned prot) +{ + if (!((unsigned int)filep->f_oflags & O_RDWR) && (((unsigned int)filep->f_oflags & O_ACCMODE) ^ O_RDONLY)) { + return -EACCES; + } + if (flags & MAP_SHARED) { + if (((unsigned int)filep->f_oflags & O_APPEND) && (prot & PROT_WRITE)) { + return -EACCES; + } + if ((prot & PROT_WRITE) && !((unsigned int)filep->f_oflags & O_RDWR)) { + return -EACCES; + } + } + + return LOS_OK; +} + +STATUS_T OsAnonMMap(LosVmMapRegion *region) +{ + LOS_SetRegionTypeAnon(region); + return LOS_OK; +} + +VADDR_T LOS_MMap(VADDR_T vaddr, size_t len, unsigned prot, unsigned long flags, int fd, unsigned long pgoff) +{ + STATUS_T status; + VADDR_T resultVaddr; + UINT32 regionFlags; + LosVmMapRegion *newRegion = NULL; + struct file *filep = NULL; + LosVmSpace *vmSpace = OsCurrProcessGet()->vmSpace; + + len = ROUNDUP(len, PAGE_SIZE); + STATUS_T checkRst = OsCheckMMapParams(&vaddr, flags, len, pgoff); + if (checkRst != LOS_OK) { + return checkRst; + } + + if (LOS_IsNamedMapping(flags)) { + status = fs_getfilep(fd, &filep); + if (status < 0) { + return -EBADF; + } + + status = OsNamedMmapingPermCheck(filep, flags, prot); + if (status < 0) { + return status; + } + } + + (VOID)LOS_MuxAcquire(&vmSpace->regionMux); + /* user mode calls mmap to release heap physical memory without releasing heap virtual space */ + status = OsUserHeapFree(vmSpace, vaddr, len); + if (status == LOS_OK) { + resultVaddr = vaddr; + goto MMAP_DONE; + } + + regionFlags = OsCvtProtFlagsToRegionFlags(prot, flags); + newRegion = LOS_RegionAlloc(vmSpace, vaddr, len, regionFlags, pgoff); + if (newRegion == NULL) { + resultVaddr = (VADDR_T)-ENOMEM; + goto MMAP_DONE; + } + newRegion->regionFlags |= VM_MAP_REGION_FLAG_MMAP; + resultVaddr = newRegion->range.base; + + if (LOS_IsNamedMapping(flags)) { + status = OsNamedMMap(filep, newRegion); + } else { + status = OsAnonMMap(newRegion); + } + + if (status != LOS_OK) { + LOS_RbDelNode(&vmSpace->regionRbTree, &newRegion->rbNode); + LOS_RegionFree(vmSpace, newRegion); + resultVaddr = (VADDR_T)-ENOMEM; + goto MMAP_DONE; + } + +MMAP_DONE: + (VOID)LOS_MuxRelease(&vmSpace->regionMux); + return resultVaddr; +} + +STATUS_T LOS_UnMMap(VADDR_T addr, size_t size) +{ + if ((addr <= 0) || (size == 0)) { + return -EINVAL; + } + + return OsUnMMap(OsCurrProcessGet()->vmSpace, addr, size); +} + +STATIC INLINE BOOL OsProtMprotectPermCheck(unsigned long prot, LosVmMapRegion *region) +{ + UINT32 protFlags = 0; + UINT32 permFlags = 0; + UINT32 fileFlags = region->unTypeData.rf.f_oflags; + permFlags |= ((fileFlags & O_ACCMODE) ^ O_RDONLY) ? 0 : VM_MAP_REGION_FLAG_PERM_READ; + permFlags |= (fileFlags & O_WRONLY) ? VM_MAP_REGION_FLAG_PERM_WRITE : 0; + permFlags |= (fileFlags & O_RDWR) ? (VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE) : 0; + protFlags |= (prot & PROT_READ) ? VM_MAP_REGION_FLAG_PERM_READ : 0; + protFlags |= (prot & PROT_WRITE) ? VM_MAP_REGION_FLAG_PERM_WRITE : 0; + + return ((protFlags & permFlags) == protFlags); +} + +VOID *OsShrinkHeap(VOID *addr, LosVmSpace *space) +{ + VADDR_T newBrk, oldBrk; + + newBrk = LOS_Align((VADDR_T)(UINTPTR)addr, PAGE_SIZE); + oldBrk = LOS_Align(space->heapNow, PAGE_SIZE); + if (LOS_UnMMap(newBrk, (oldBrk - newBrk)) < 0) { + return (void *)(UINTPTR)space->heapNow; + } + space->heapNow = (VADDR_T)(UINTPTR)addr; + return addr; +} + +VOID *LOS_DoBrk(VOID *addr) +{ + LosVmSpace *space = OsCurrProcessGet()->vmSpace; + size_t size; + VOID *ret = NULL; + LosVmMapRegion *region = NULL; + VOID *alignAddr = NULL; + VOID *shrinkAddr = NULL; + + if (addr == NULL) { + return (void *)(UINTPTR)space->heapNow; + } + + if ((UINTPTR)addr < (UINTPTR)space->heapBase) { + return (VOID *)-ENOMEM; + } + + size = (UINTPTR)addr - (UINTPTR)space->heapBase; + size = ROUNDUP(size, PAGE_SIZE); + alignAddr = (CHAR *)(UINTPTR)(space->heapBase) + size; + PRINT_INFO("brk addr %p , size 0x%x, alignAddr %p, align %d\n", addr, size, alignAddr, PAGE_SIZE); + + (VOID)LOS_MuxAcquire(&space->regionMux); + if (addr < (VOID *)(UINTPTR)space->heapNow) { + shrinkAddr = OsShrinkHeap(addr, space); + (VOID)LOS_MuxRelease(&space->regionMux); + return shrinkAddr; + } + + if ((UINTPTR)alignAddr >= space->mapBase) { + VM_ERR("Process heap memory space is insufficient"); + ret = (VOID *)-ENOMEM; + goto REGION_ALLOC_FAILED; + } + + if (space->heapBase == space->heapNow) { + region = LOS_RegionAlloc(space, space->heapBase, size, + VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE | + VM_MAP_REGION_FLAG_FIXED | VM_MAP_REGION_FLAG_PERM_USER, 0); + if (region == NULL) { + ret = (VOID *)-ENOMEM; + VM_ERR("LOS_RegionAlloc failed"); + goto REGION_ALLOC_FAILED; + } + region->regionFlags |= VM_MAP_REGION_FLAG_HEAP; + space->heap = region; + } + + space->heapNow = (VADDR_T)(UINTPTR)alignAddr; + space->heap->range.size = size; + ret = (VOID *)(UINTPTR)space->heapNow; + +REGION_ALLOC_FAILED: + (VOID)LOS_MuxRelease(&space->regionMux); + return ret; +} + +STATIC UINT32 OsInheritOldRegionName(UINT32 oldRegionFlags) +{ + UINT32 vmFlags = 0; + + if (oldRegionFlags & VM_MAP_REGION_FLAG_HEAP) { + vmFlags |= VM_MAP_REGION_FLAG_HEAP; + } else if (oldRegionFlags & VM_MAP_REGION_FLAG_STACK) { + vmFlags |= VM_MAP_REGION_FLAG_STACK; + } else if (oldRegionFlags & VM_MAP_REGION_FLAG_TEXT) { + vmFlags |= VM_MAP_REGION_FLAG_TEXT; + } else if (oldRegionFlags & VM_MAP_REGION_FLAG_VDSO) { + vmFlags |= VM_MAP_REGION_FLAG_VDSO; + } else if (oldRegionFlags & VM_MAP_REGION_FLAG_MMAP) { + vmFlags |= VM_MAP_REGION_FLAG_MMAP; + } else if (oldRegionFlags & VM_MAP_REGION_FLAG_SHM) { + vmFlags |= VM_MAP_REGION_FLAG_SHM; + } + + return vmFlags; +} + +INT32 LOS_DoMprotect(VADDR_T vaddr, size_t len, unsigned long prot) +{ + LosVmSpace *space = OsCurrProcessGet()->vmSpace; + LosVmMapRegion *region = NULL; + UINT32 vmFlags; + UINT32 count; + int ret; + + (VOID)LOS_MuxAcquire(&space->regionMux); + region = LOS_RegionFind(space, vaddr); + if (!IS_ALIGNED(vaddr, PAGE_SIZE) || (region == NULL) || (vaddr > vaddr + len)) { + ret = -EINVAL; + goto OUT_MPROTECT; + } + + if ((prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC))) { + ret = -EINVAL; + goto OUT_MPROTECT; + } + + if ((region->regionFlags & VM_MAP_REGION_FLAG_VDSO) || (region->regionFlags & VM_MAP_REGION_FLAG_HEAP)) { + ret = -EPERM; + goto OUT_MPROTECT; + } + + if (LOS_IsRegionTypeFile(region) && (region->regionFlags & VM_MAP_REGION_FLAG_SHARED)) { + if (!OsProtMprotectPermCheck(prot, region)) { + ret = -EACCES; + goto OUT_MPROTECT; + } + } + + len = LOS_Align(len, PAGE_SIZE); + /* can't operation cross region */ + if ((region->range.base + region->range.size) < (vaddr + len)) { + ret = -EINVAL; + goto OUT_MPROTECT; + } + + /* if only move some part of region, we need to split first */ + if (region->range.size > len) { + OsVmRegionAdjust(space, vaddr, len); + } + + vmFlags = OsCvtProtFlagsToRegionFlags(prot, 0); + vmFlags |= (region->regionFlags & VM_MAP_REGION_FLAG_SHARED) ? VM_MAP_REGION_FLAG_SHARED : 0; + vmFlags |= OsInheritOldRegionName(region->regionFlags); + region = LOS_RegionFind(space, vaddr); + if (region == NULL) { + ret = -ENOMEM; + goto OUT_MPROTECT; + } + region->regionFlags = vmFlags; + count = len >> PAGE_SHIFT; + ret = LOS_ArchMmuChangeProt(&space->archMmu, vaddr, count, region->regionFlags); + if (ret) { + ret = -ENOMEM; + goto OUT_MPROTECT; + } + ret = LOS_OK; + +OUT_MPROTECT: +#ifdef LOSCFG_VM_OVERLAP_CHECK + if (VmmAspaceRegionsOverlapCheck(aspace) < 0) { + (VOID)OsShellCmdDumpVm(0, NULL); + ret = -ENOMEM; + } +#endif + + (VOID)LOS_MuxRelease(&space->regionMux); + return ret; +} + +STATUS_T OsMremapCheck(VADDR_T addr, size_t oldLen, VADDR_T newAddr, size_t newLen, unsigned int flags) +{ + LosVmSpace *space = OsCurrProcessGet()->vmSpace; + LosVmMapRegion *region = LOS_RegionFind(space, addr); + VADDR_T regionEnd; + + if ((region == NULL) || (region->range.base > addr) || (newLen == 0)) { + return -EINVAL; + } + + if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE)) { + return -EINVAL; + } + + if (((flags & MREMAP_FIXED) == MREMAP_FIXED) && ((flags & MREMAP_MAYMOVE) == 0)) { + return -EINVAL; + } + + if (!IS_ALIGNED(addr, PAGE_SIZE)) { + return -EINVAL; + } + + regionEnd = region->range.base + region->range.size; + + /* we can't operate across region */ + if (oldLen > regionEnd - addr) { + return -EFAULT; + } + + /* avoiding overflow */ + if (newLen > oldLen) { + if ((addr + newLen) < addr) { + return -EINVAL; + } + } + + /* avoid new region overlapping with the old one */ + if (flags & MREMAP_FIXED) { + if (((region->range.base + region->range.size) > newAddr) && + (region->range.base < (newAddr + newLen))) { + return -EINVAL; + } + + if (!IS_ALIGNED(newAddr, PAGE_SIZE)) { + return -EINVAL; + } + } + + return LOS_OK; +} + +VADDR_T LOS_DoMremap(VADDR_T oldAddress, size_t oldSize, size_t newSize, int flags, VADDR_T newAddr) +{ + LosVmMapRegion *regionOld = NULL; + LosVmMapRegion *regionNew = NULL; + STATUS_T status; + VADDR_T ret; + LosVmSpace *space = OsCurrProcessGet()->vmSpace; + + oldSize = LOS_Align(oldSize, PAGE_SIZE); + newSize = LOS_Align(newSize, PAGE_SIZE); + + (VOID)LOS_MuxAcquire(&space->regionMux); + + status = OsMremapCheck(oldAddress, oldSize, newAddr, newSize, (unsigned int)flags); + if (status) { + ret = status; + goto OUT_MREMAP; + } + + /* if only move some part of region, we need to split first */ + status = OsVmRegionAdjust(space, oldAddress, oldSize); + if (status) { + ret = -ENOMEM; + goto OUT_MREMAP; + } + + regionOld = LOS_RegionFind(space, oldAddress); + if (regionOld == NULL) { + ret = -ENOMEM; + goto OUT_MREMAP; + } + + if ((unsigned int)flags & MREMAP_FIXED) { + regionNew = OsVmRegionDup(space, regionOld, newAddr, newSize); + if (!regionNew) { + ret = -ENOMEM; + goto OUT_MREMAP; + } + status = LOS_ArchMmuMove(&space->archMmu, oldAddress, newAddr, + ((newSize < regionOld->range.size) ? newSize : regionOld->range.size) >> PAGE_SHIFT, + regionOld->regionFlags); + if (status) { + LOS_RegionFree(space, regionNew); + ret = -ENOMEM; + goto OUT_MREMAP; + } + LOS_RegionFree(space, regionOld); + ret = newAddr; + goto OUT_MREMAP; + } + // take it as shrink operation + if (oldSize > newSize) { + LOS_UnMMap(oldAddress + newSize, oldSize - newSize); + ret = oldAddress; + goto OUT_MREMAP; + } + status = OsIsRegionCanExpand(space, regionOld, newSize); + // we can expand directly. + if (!status) { + regionOld->range.size = newSize; + ret = oldAddress; + goto OUT_MREMAP; + } + + if ((unsigned int)flags & MREMAP_MAYMOVE) { + regionNew = OsVmRegionDup(space, regionOld, 0, newSize); + if (regionNew == NULL) { + ret = -ENOMEM; + goto OUT_MREMAP; + } + status = LOS_ArchMmuMove(&space->archMmu, oldAddress, regionNew->range.base, + regionOld->range.size >> PAGE_SHIFT, regionOld->regionFlags); + if (status) { + LOS_RegionFree(space, regionNew); + ret = -ENOMEM; + goto OUT_MREMAP; + } + LOS_RegionFree(space, regionOld); + ret = regionNew->range.base; + goto OUT_MREMAP; + } + + ret = -EINVAL; +OUT_MREMAP: +#ifdef LOSCFG_VM_OVERLAP_CHECK + if (VmmAspaceRegionsOverlapCheck(aspace) < 0) { + (VOID)OsShellCmdDumpVm(0, NULL); + ret = -ENOMEM; + } +#endif + + (VOID)LOS_MuxRelease(&space->regionMux); + return ret; +} + +VOID LOS_DumpMemRegion(VADDR_T vaddr) +{ + LosVmSpace *space = NULL; + + space = OsCurrProcessGet()->vmSpace; + if (space == NULL) { + return; + } + + if (LOS_IsRangeInSpace(space, ROUNDDOWN(vaddr, MB), MB) == FALSE) { + return; + } + + OsDumpPte(vaddr); + OsDumpAspace(space); +} +#endif + diff --git a/src/kernel_liteos_a/kernel/base/vm/oom.c b/src/kernel_liteos_a/kernel/base/vm/oom.c new file mode 100644 index 00000000..72996781 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/vm/oom.c @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_oom.h" +#include "los_init.h" +#include "los_vm_dump.h" +#include "los_vm_lock.h" +#include "los_vm_phys.h" +#include "los_vm_filemap.h" +#include "los_process_pri.h" +#ifdef LOSCFG_BASE_CORE_SWTMR_ENABLE +#include "los_swtmr_pri.h" +#endif + +#ifdef LOSCFG_FS_VFS +#include "console.h" +#endif + + +#ifdef LOSCFG_KERNEL_VM + +LITE_OS_SEC_BSS OomCB *g_oomCB = NULL; +static SPIN_LOCK_INIT(g_oomSpinLock); + +LITE_OS_SEC_TEXT_MINOR STATIC UINT32 OomScoreProcess(LosProcessCB *candidateProcess) +{ + UINT32 actualPm; + +#ifndef LOSCFG_KERNEL_SMP + (VOID)LOS_MuxAcquire(&candidateProcess->vmSpace->regionMux); +#endif + /* we only consider actual physical memory here. */ + OsUProcessPmUsage(candidateProcess->vmSpace, NULL, &actualPm); +#ifndef LOSCFG_KERNEL_SMP + (VOID)LOS_MuxRelease(&candidateProcess->vmSpace->regionMux); +#endif + return actualPm; +} + +LITE_OS_SEC_TEXT_MINOR STATIC UINT32 OomKillProcess(UINTPTR param) +{ + /* we will not kill process, and do nothing here */ + return LOS_OK; +} + +LITE_OS_SEC_TEXT_MINOR STATIC UINT32 OomForceShrinkMemory(VOID) +{ + UINT32 i; + UINT32 reclaimMemPages = 0; + + /* + * TryShrinkMemory maybe reclaim 0 pages in the first time from active list + * to inactive list, and in the second time reclaim memory from inactive list. + */ + for (i = 0; i < MAX_SHRINK_PAGECACHE_TRY; i++) { + reclaimMemPages += OsTryShrinkMemory(0); + } + + return reclaimMemPages; +} + +LITE_OS_SEC_TEXT_MINOR STATIC BOOL OomReclaimPageCache(VOID) +{ + UINT32 totalPm = 0; + UINT32 usedPm = 0; + BOOL isReclaimMemory = FALSE; + UINT32 reclaimMemPages; + UINT32 i; + + for (i = 0; i < MAX_SHRINK_PAGECACHE_TRY; i++) { + OsVmPhysUsedInfoGet(&usedPm, &totalPm); + isReclaimMemory = ((totalPm - usedPm) << PAGE_SHIFT) < g_oomCB->reclaimMemThreshold; + if (isReclaimMemory) { + /* + * we do force memory reclaim from page cache here. + * if we get memory, we will reclaim pagecache memory again. + * if there is no memory to reclaim, we will return. + */ + reclaimMemPages = OomForceShrinkMemory(); + if (reclaimMemPages > 0) { + continue; + } + } + break; + } + + return isReclaimMemory; +} + +/* + * check is low memory or not, if low memory, try to kill process. + * return is kill process or not. + */ +LITE_OS_SEC_TEXT_MINOR BOOL OomCheckProcess(VOID) +{ + UINT32 totalPm; + UINT32 usedPm; + BOOL isLowMemory = FALSE; + + /* + * spinlock the current core schedule, make sure oom process atomic + * spinlock other place entering OomCheckProcess, make sure oom process mutex + */ + LOS_SpinLock(&g_oomSpinLock); + + /* first we will check if we need to reclaim pagecache memory */ + if (OomReclaimPageCache() == FALSE) { + LOS_SpinUnlock(&g_oomSpinLock); + goto NO_VICTIM_PROCESS; + } + + /* get free bytes */ + OsVmPhysUsedInfoGet(&usedPm, &totalPm); + isLowMemory = ((totalPm - usedPm) << PAGE_SHIFT) < g_oomCB->lowMemThreshold; + + LOS_SpinUnlock(&g_oomSpinLock); + + if (isLowMemory) { + PRINTK("[oom] OS is in low memory state\n" + "total physical memory: %#x(byte), used: %#x(byte)," + "free: %#x(byte), low memory threshold: %#x(byte)\n", + totalPm << PAGE_SHIFT, usedPm << PAGE_SHIFT, + (totalPm - usedPm) << PAGE_SHIFT, g_oomCB->lowMemThreshold); + } + +NO_VICTIM_PROCESS: + return isLowMemory; +} + +#ifdef LOSCFG_ENABLE_OOM_LOOP_TASK +STATIC VOID OomWriteEvent(VOID) +{ + OsWriteResourceEvent(OS_RESOURCE_EVENT_OOM); +} +#endif + +LITE_OS_SEC_TEXT_MINOR VOID OomInfodump(VOID) +{ + PRINTK("[oom] oom loop task status: %s\n" + " oom low memory threshold: %#x(byte)\n" + " oom reclaim memory threshold: %#x(byte)\n" + " oom check interval: %d(microsecond)\n", + g_oomCB->enabled ? "enabled" : "disabled", + g_oomCB->lowMemThreshold, g_oomCB->reclaimMemThreshold, + g_oomCB->checkInterval); +} + +LITE_OS_SEC_TEXT_MINOR VOID OomSetLowMemThreashold(UINT32 lowMemThreshold) +{ + if ((lowMemThreshold > OOM_DEFAULT_LOW_MEM_THRESHOLD_MAX)) { + PRINTK("[oom] low memory threshold %#x(byte) invalid," + "should be in [%#x, %#x](byte)\n", + lowMemThreshold, OOM_DEFAULT_LOW_MEM_THRESHOLD_MIN, + OOM_DEFAULT_LOW_MEM_THRESHOLD_MAX); + } else { + g_oomCB->lowMemThreshold = lowMemThreshold; + PRINTK("[oom] set oom low memory threshold %#x(byte) successful\n", + g_oomCB->lowMemThreshold); + } +} + +LITE_OS_SEC_TEXT_MINOR VOID OomSetReclaimMemThreashold(UINT32 reclaimMemThreshold) +{ + UINT32 totalPm = 0; + UINT32 usedPm = 0; + + OsVmPhysUsedInfoGet(&usedPm, &totalPm); + if ((reclaimMemThreshold >= (totalPm << PAGE_SHIFT)) || + (reclaimMemThreshold < g_oomCB->lowMemThreshold)) { + PRINTK("[oom] reclaim memory threshold %#x(byte) invalid," + "should be in [%#x, %#x)(byte)\n", + reclaimMemThreshold, g_oomCB->lowMemThreshold, (totalPm << PAGE_SHIFT)); + } else { + g_oomCB->reclaimMemThreshold = reclaimMemThreshold; + PRINTK("[oom] set oom reclaim memory threshold %#x(byte) successful\n", + g_oomCB->reclaimMemThreshold); + } +} + +LITE_OS_SEC_TEXT_MINOR VOID OomSetCheckInterval(UINT32 checkInterval) +{ + if ((checkInterval >= OOM_CHECK_MIN) && (checkInterval <= OOM_CHECK_MAX)) { + g_oomCB->checkInterval = checkInterval; + PRINTK("[oom] set oom check interval (%d)ms successful\n", + g_oomCB->checkInterval); + } else { + PRINTK("[oom] set oom check interval (%d)ms failed, should be in [%d, %d]\n", + g_oomCB->checkInterval, OOM_CHECK_MIN, OOM_CHECK_MAX); + } +} + +LITE_OS_SEC_TEXT_MINOR UINT32 OomTaskInit(VOID) +{ + g_oomCB = (OomCB *)LOS_MemAlloc(m_aucSysMem0, sizeof(OomCB)); + if (g_oomCB == NULL) { + VM_ERR("oom task init failed, malloc OomCB failed."); + return LOS_NOK; + } + + g_oomCB->lowMemThreshold = OOM_DEFAULT_LOW_MEM_THRESHOLD; + g_oomCB->reclaimMemThreshold = OOM_DEFAULT_RECLAIM_MEM_THRESHOLD; + g_oomCB->checkInterval = OOM_DEFAULT_CHECK_INTERVAL; + g_oomCB->processVictimCB = (OomFn)OomKillProcess; + g_oomCB->scoreCB = (OomFn)OomScoreProcess; + g_oomCB->enabled = FALSE; + +#ifdef LOSCFG_ENABLE_OOM_LOOP_TASK + g_oomCB->enabled = TRUE; + UINT32 ret = LOS_SwtmrCreate(g_oomCB->checkInterval, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)OomWriteEvent, + &g_oomCB->swtmrID, (UINTPTR)g_oomCB); + if (ret != LOS_OK) { + return ret; + } + + return LOS_SwtmrStart(g_oomCB->swtmrID); +#else + return LOS_OK; +#endif +} + +LOS_MODULE_INIT(OomTaskInit, LOS_INIT_LEVEL_KMOD_TASK); + +#endif + diff --git a/src/kernel_liteos_a/kernel/base/vm/shm.c b/src/kernel_liteos_a/kernel/base/vm/shm.c new file mode 100644 index 00000000..637c6167 --- /dev/null +++ b/src/kernel_liteos_a/kernel/base/vm/shm.c @@ -0,0 +1,914 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "stdio.h" +#include "string.h" +#include "time.h" +#include "sys/types.h" +#include "sys/stat.h" +#include "los_config.h" +#include "los_init.h" +#include "los_vm_map.h" +#include "los_vm_filemap.h" +#include "los_vm_phys.h" +#include "los_arch_mmu.h" +#include "los_vm_page.h" +#include "los_vm_lock.h" +#include "los_process.h" +#include "los_process_pri.h" +#include "user_copy.h" +#include "los_vm_shm_pri.h" +#include "sys/shm.h" +#ifdef LOSCFG_SHELL +#include "shcmd.h" +#include "shell.h" +#endif + + +#ifdef LOSCFG_KERNEL_SHM + +#define SHM_SEG_FREE 0x2000 +#define SHM_SEG_USED 0x4000 +#define SHM_SEG_REMOVE 0x8000 + +#ifndef SHM_M +#define SHM_M 010000 +#endif + +#ifndef SHM_X +#define SHM_X 0100 +#endif + +#ifndef ACCESSPERMS +#define ACCESSPERMS (S_IRWXU | S_IRWXG | S_IRWXO) +#endif + +#define SHM_S_IRUGO (S_IRUSR | S_IRGRP | S_IROTH) +#define SHM_S_IWUGO (S_IWUSR | S_IWGRP | S_IWOTH) +#define SHM_S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH) + +#define SHM_GROUPE_TO_USER 3 +#define SHM_OTHER_TO_USER 6 + +#ifndef LOSCFG_IPC_CONTAINER +STATIC LosMux g_sysvShmMux; + +/* private data */ +STATIC struct shminfo g_shmInfo; +STATIC struct shmIDSource *g_shmSegs = NULL; +STATIC UINT32 g_shmUsedPageCount; + +#define IPC_SHM_INFO g_shmInfo +#define IPC_SHM_SYS_VSHM_MUTEX g_sysvShmMux +#define IPC_SHM_SEGS g_shmSegs +#define IPC_SHM_USED_PAGE_COUNT g_shmUsedPageCount +#endif + +/* private macro */ +#define SYSV_SHM_LOCK() (VOID)LOS_MuxLock(&IPC_SHM_SYS_VSHM_MUTEX, LOS_WAIT_FOREVER) +#define SYSV_SHM_UNLOCK() (VOID)LOS_MuxUnlock(&IPC_SHM_SYS_VSHM_MUTEX) + +struct shmIDSource *OsShmCBInit(LosMux *sysvShmMux, struct shminfo *shmInfo, UINT32 *shmUsedPageCount) +{ + UINT32 ret; + UINT32 i; + + if ((sysvShmMux == NULL) || (shmInfo == NULL) || (shmUsedPageCount == NULL)) { + return NULL; + } + + ret = LOS_MuxInit(sysvShmMux, NULL); + if (ret != LOS_OK) { + goto ERROR; + } + + shmInfo->shmmax = SHM_MAX; + shmInfo->shmmin = SHM_MIN; + shmInfo->shmmni = SHM_MNI; + shmInfo->shmseg = SHM_SEG; + shmInfo->shmall = SHM_ALL; + + struct shmIDSource *shmSegs = LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, sizeof(struct shmIDSource) * shmInfo->shmmni); + if (shmSegs == NULL) { + (VOID)LOS_MuxDestroy(sysvShmMux); + goto ERROR; + } + (VOID)memset_s(shmSegs, (sizeof(struct shmIDSource) * shmInfo->shmmni), + 0, (sizeof(struct shmIDSource) * shmInfo->shmmni)); + + for (i = 0; i < shmInfo->shmmni; i++) { + shmSegs[i].status = SHM_SEG_FREE; + shmSegs[i].ds.shm_perm.seq = i + 1; + LOS_ListInit(&shmSegs[i].node); + } + *shmUsedPageCount = 0; + + return shmSegs; + +ERROR: + VM_ERR("ShmInit fail\n"); + return NULL; +} + +UINT32 ShmInit(VOID) +{ +#ifndef LOSCFG_IPC_CONTAINER + g_shmSegs = OsShmCBInit(&IPC_SHM_SYS_VSHM_MUTEX, &IPC_SHM_INFO, &IPC_SHM_USED_PAGE_COUNT); + if (g_shmSegs == NULL) { + return LOS_NOK; + } +#endif + return LOS_OK; +} + +LOS_MODULE_INIT(ShmInit, LOS_INIT_LEVEL_VM_COMPLETE); + +UINT32 ShmDeinit(VOID) +{ + UINT32 ret; + + (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, IPC_SHM_SEGS); + IPC_SHM_SEGS = NULL; + + ret = LOS_MuxDestroy(&IPC_SHM_SYS_VSHM_MUTEX); + if (ret != LOS_OK) { + return -1; + } + + return 0; +} + +STATIC inline VOID ShmSetSharedFlag(struct shmIDSource *seg) +{ + LosVmPage *page = NULL; + + LOS_DL_LIST_FOR_EACH_ENTRY(page, &seg->node, LosVmPage, node) { + OsSetPageShared(page); + } +} + +STATIC inline VOID ShmClearSharedFlag(struct shmIDSource *seg) +{ + LosVmPage *page = NULL; + + LOS_DL_LIST_FOR_EACH_ENTRY(page, &seg->node, LosVmPage, node) { + OsCleanPageShared(page); + } +} + +STATIC VOID ShmPagesRefDec(struct shmIDSource *seg) +{ + LosVmPage *page = NULL; + + LOS_DL_LIST_FOR_EACH_ENTRY(page, &seg->node, LosVmPage, node) { + LOS_AtomicDec(&page->refCounts); + } +} + +STATIC INT32 ShmAllocSegCheck(key_t key, size_t *size, INT32 *segNum) +{ + INT32 i; + if ((*size == 0) || (*size < IPC_SHM_INFO.shmmin) || + (*size > IPC_SHM_INFO.shmmax)) { + return -EINVAL; + } + + *size = LOS_Align(*size, PAGE_SIZE); + if ((IPC_SHM_USED_PAGE_COUNT + (*size >> PAGE_SHIFT)) > IPC_SHM_INFO.shmall) { + return -ENOMEM; + } + +#ifdef LOSCFG_KERNEL_IPC_PLIMIT + if (OsIPCLimitShmAlloc(*size) != LOS_OK) { + return -ENOMEM; + } +#endif + + for (i = 0; i < IPC_SHM_INFO.shmmni; i++) { + if (IPC_SHM_SEGS[i].status & SHM_SEG_FREE) { + IPC_SHM_SEGS[i].status &= ~SHM_SEG_FREE; + *segNum = i; + break; + } + } + + if (*segNum < 0) { + return -ENOSPC; + } + return 0; +} + +STATIC INT32 ShmAllocSeg(key_t key, size_t size, INT32 shmflg) +{ + INT32 segNum = -1; + struct shmIDSource *seg = NULL; + size_t count; + + INT32 ret = ShmAllocSegCheck(key, &size, &segNum); + if (ret < 0) { + return ret; + } + + seg = &IPC_SHM_SEGS[segNum]; + count = LOS_PhysPagesAlloc(size >> PAGE_SHIFT, &seg->node); + if (count != (size >> PAGE_SHIFT)) { + (VOID)LOS_PhysPagesFree(&seg->node); + seg->status = SHM_SEG_FREE; +#ifdef LOSCFG_KERNEL_IPC_PLIMIT + OsIPCLimitShmFree(size); +#endif + return -ENOMEM; + } + + ShmSetSharedFlag(seg); + IPC_SHM_USED_PAGE_COUNT += size >> PAGE_SHIFT; + + seg->status |= SHM_SEG_USED; + seg->ds.shm_perm.mode = (UINT32)shmflg & ACCESSPERMS; + seg->ds.shm_perm.key = key; + seg->ds.shm_segsz = size; + seg->ds.shm_perm.cuid = LOS_GetUserID(); + seg->ds.shm_perm.uid = LOS_GetUserID(); + seg->ds.shm_perm.cgid = LOS_GetGroupID(); + seg->ds.shm_perm.gid = LOS_GetGroupID(); + seg->ds.shm_lpid = 0; + seg->ds.shm_nattch = 0; + seg->ds.shm_cpid = LOS_GetCurrProcessID(); + seg->ds.shm_atime = 0; + seg->ds.shm_dtime = 0; + seg->ds.shm_ctime = time(NULL); +#ifdef LOSCFG_SHELL + (VOID)memcpy_s(seg->ownerName, OS_PCB_NAME_LEN, OsCurrProcessGet()->processName, OS_PCB_NAME_LEN); +#endif + + return segNum; +} + +STATIC INLINE VOID ShmFreeSeg(struct shmIDSource *seg, UINT32 *shmUsedPageCount) +{ + UINT32 count; + + ShmClearSharedFlag(seg); + count = LOS_PhysPagesFree(&seg->node); + if (count != (seg->ds.shm_segsz >> PAGE_SHIFT)) { + VM_ERR("free physical pages failed, count = %d, size = %d", count, seg->ds.shm_segsz >> PAGE_SHIFT); + return; + } +#ifdef LOSCFG_KERNEL_IPC_PLIMIT + OsIPCLimitShmFree(seg->ds.shm_segsz); +#endif + if (shmUsedPageCount != NULL) { + (*shmUsedPageCount) -= seg->ds.shm_segsz >> PAGE_SHIFT; + } + seg->status = SHM_SEG_FREE; + LOS_ListInit(&seg->node); +} + +STATIC INT32 ShmFindSegByKey(key_t key) +{ + INT32 i; + struct shmIDSource *seg = NULL; + + for (i = 0; i < IPC_SHM_INFO.shmmni; i++) { + seg = &IPC_SHM_SEGS[i]; + if ((seg->status & SHM_SEG_USED) && + (seg->ds.shm_perm.key == key)) { + return i; + } + } + + return -1; +} + +STATIC INT32 ShmSegValidCheck(INT32 segNum, size_t size, INT32 shmFlg) +{ + struct shmIDSource *seg = &IPC_SHM_SEGS[segNum]; + + if (size > seg->ds.shm_segsz) { + return -EINVAL; + } + + if (((UINT32)shmFlg & (IPC_CREAT | IPC_EXCL)) == + (IPC_CREAT | IPC_EXCL)) { + return -EEXIST; + } + + return segNum; +} + +STATIC struct shmIDSource *ShmFindSeg(int shmid) +{ + struct shmIDSource *seg = NULL; + + if ((shmid < 0) || (shmid >= IPC_SHM_INFO.shmmni)) { + set_errno(EINVAL); + return NULL; + } + + seg = &IPC_SHM_SEGS[shmid]; + if ((seg->status & SHM_SEG_FREE) || ((seg->ds.shm_nattch == 0) && (seg->status & SHM_SEG_REMOVE))) { + set_errno(EIDRM); + return NULL; + } + + return seg; +} + +STATIC VOID ShmVmmMapping(LosVmSpace *space, LOS_DL_LIST *pageList, VADDR_T vaddr, UINT32 regionFlags) +{ + LosVmPage *vmPage = NULL; + VADDR_T va = vaddr; + PADDR_T pa; + STATUS_T ret; + + LOS_DL_LIST_FOR_EACH_ENTRY(vmPage, pageList, LosVmPage, node) { + pa = VM_PAGE_TO_PHYS(vmPage); + LOS_AtomicInc(&vmPage->refCounts); + ret = LOS_ArchMmuMap(&space->archMmu, va, pa, 1, regionFlags); + if (ret != 1) { + VM_ERR("LOS_ArchMmuMap failed, ret = %d", ret); + } + va += PAGE_SIZE; + } +} + +VOID OsShmFork(LosVmSpace *space, LosVmMapRegion *oldRegion, LosVmMapRegion *newRegion) +{ + struct shmIDSource *seg = NULL; + + SYSV_SHM_LOCK(); + seg = ShmFindSeg(oldRegion->shmid); + if (seg == NULL) { + SYSV_SHM_UNLOCK(); + VM_ERR("shm fork failed!"); + return; + } + + newRegion->shmid = oldRegion->shmid; + newRegion->forkFlags = oldRegion->forkFlags; + ShmVmmMapping(space, &seg->node, newRegion->range.base, newRegion->regionFlags); + seg->ds.shm_nattch++; + SYSV_SHM_UNLOCK(); +} + +VOID OsShmRegionFree(LosVmSpace *space, LosVmMapRegion *region) +{ + struct shmIDSource *seg = NULL; + + SYSV_SHM_LOCK(); + seg = ShmFindSeg(region->shmid); + if (seg == NULL) { + SYSV_SHM_UNLOCK(); + return; + } + + LOS_ArchMmuUnmap(&space->archMmu, region->range.base, region->range.size >> PAGE_SHIFT); + ShmPagesRefDec(seg); + seg->ds.shm_nattch--; + if (seg->ds.shm_nattch <= 0 && (seg->status & SHM_SEG_REMOVE)) { + ShmFreeSeg(seg, &IPC_SHM_USED_PAGE_COUNT); + } else { + seg->ds.shm_dtime = time(NULL); + seg->ds.shm_lpid = LOS_GetCurrProcessID(); /* may not be the space's PID. */ + } + SYSV_SHM_UNLOCK(); +} + +BOOL OsIsShmRegion(LosVmMapRegion *region) +{ + return (region->regionFlags & VM_MAP_REGION_FLAG_SHM) ? TRUE : FALSE; +} + +STATIC INT32 ShmSegUsedCount(VOID) +{ + INT32 i; + INT32 count = 0; + struct shmIDSource *seg = NULL; + + for (i = 0; i < IPC_SHM_INFO.shmmni; i++) { + seg = &IPC_SHM_SEGS[i]; + if (seg->status & SHM_SEG_USED) { + count++; + } + } + return count; +} + +STATIC INT32 ShmPermCheck(struct shmIDSource *seg, mode_t mode) +{ + INT32 uid = LOS_GetUserID(); + UINT32 tmpMode = 0; + mode_t privMode = seg->ds.shm_perm.mode; + mode_t accMode; + + if ((uid == seg->ds.shm_perm.uid) || (uid == seg->ds.shm_perm.cuid)) { + tmpMode |= SHM_M; + accMode = mode & S_IRWXU; + } else if (LOS_CheckInGroups(seg->ds.shm_perm.gid) || + LOS_CheckInGroups(seg->ds.shm_perm.cgid)) { + privMode <<= SHM_GROUPE_TO_USER; + accMode = (mode & S_IRWXG) << SHM_GROUPE_TO_USER; + } else { + privMode <<= SHM_OTHER_TO_USER; + accMode = (mode & S_IRWXO) << SHM_OTHER_TO_USER; + } + + if (privMode & SHM_R) { + tmpMode |= SHM_R; + } + + if (privMode & SHM_W) { + tmpMode |= SHM_W; + } + + if (privMode & SHM_X) { + tmpMode |= SHM_X; + } + + if ((mode == SHM_M) && (tmpMode & SHM_M)) { + return 0; + } else if (mode == SHM_M) { + return EACCES; + } + + if ((tmpMode & accMode) == accMode) { + return 0; + } else { + return EACCES; + } +} + +INT32 ShmGet(key_t key, size_t size, INT32 shmflg) +{ + INT32 ret; + INT32 shmid; + + SYSV_SHM_LOCK(); + + if (key == IPC_PRIVATE) { + ret = ShmAllocSeg(key, size, shmflg); + } else { + ret = ShmFindSegByKey(key); + if (ret < 0) { + if (((UINT32)shmflg & IPC_CREAT) == 0) { + ret = -ENOENT; + goto ERROR; + } else { + ret = ShmAllocSeg(key, size, shmflg); + } + } else { + shmid = ret; + if (((UINT32)shmflg & IPC_CREAT) && + ((UINT32)shmflg & IPC_EXCL)) { + ret = -EEXIST; + goto ERROR; + } + ret = ShmPermCheck(ShmFindSeg(shmid), (UINT32)shmflg & ACCESSPERMS); + if (ret != 0) { + ret = -ret; + goto ERROR; + } + ret = ShmSegValidCheck(shmid, size, shmflg); + } + } + if (ret < 0) { + goto ERROR; + } + + SYSV_SHM_UNLOCK(); + + return ret; +ERROR: + set_errno(-ret); + SYSV_SHM_UNLOCK(); + PRINT_DEBUG("%s %d, ret = %d\n", __FUNCTION__, __LINE__, ret); + return -1; +} + +INT32 ShmatParamCheck(const VOID *shmaddr, INT32 shmflg) +{ + if (((UINT32)shmflg & SHM_REMAP) && (shmaddr == NULL)) { + return EINVAL; + } + + if ((shmaddr != NULL) && !IS_PAGE_ALIGNED(shmaddr) && + (((UINT32)shmflg & SHM_RND) == 0)) { + return EINVAL; + } + + return 0; +} + +LosVmMapRegion *ShmatVmmAlloc(struct shmIDSource *seg, const VOID *shmaddr, + INT32 shmflg, UINT32 prot) +{ + LosVmSpace *space = OsCurrProcessGet()->vmSpace; + LosVmMapRegion *region = NULL; + UINT32 flags = MAP_ANONYMOUS | MAP_SHARED; + UINT32 mapFlags = flags | MAP_FIXED; + VADDR_T vaddr; + UINT32 regionFlags; + INT32 ret; + + if (shmaddr != NULL) { + flags |= MAP_FIXED_NOREPLACE; + } + regionFlags = OsCvtProtFlagsToRegionFlags(prot, flags); + (VOID)LOS_MuxAcquire(&space->regionMux); + if (shmaddr == NULL) { + region = LOS_RegionAlloc(space, 0, seg->ds.shm_segsz, regionFlags, 0); + } else { + if ((UINT32)shmflg & SHM_RND) { + vaddr = ROUNDDOWN((VADDR_T)(UINTPTR)shmaddr, SHMLBA); + } else { + vaddr = (VADDR_T)(UINTPTR)shmaddr; + } + if (!((UINT32)shmflg & SHM_REMAP) && (LOS_RegionFind(space, vaddr) || + LOS_RegionFind(space, vaddr + seg->ds.shm_segsz - 1) || + LOS_RegionRangeFind(space, vaddr, seg->ds.shm_segsz - 1))) { + ret = EINVAL; + goto ERROR; + } + vaddr = (VADDR_T)LOS_MMap(vaddr, seg->ds.shm_segsz, prot, mapFlags, -1, 0); + region = LOS_RegionFind(space, vaddr); + } + + if (region == NULL) { + ret = ENOMEM; + goto ERROR; + } + ShmVmmMapping(space, &seg->node, region->range.base, regionFlags); + (VOID)LOS_MuxRelease(&space->regionMux); + return region; +ERROR: + set_errno(ret); + (VOID)LOS_MuxRelease(&space->regionMux); + return NULL; +} + +VOID *ShmAt(INT32 shmid, const VOID *shmaddr, INT32 shmflg) +{ + INT32 ret; + UINT32 prot = PROT_READ; + mode_t acc_mode = SHM_S_IRUGO; + struct shmIDSource *seg = NULL; + LosVmMapRegion *r = NULL; + + ret = ShmatParamCheck(shmaddr, shmflg); + if (ret != 0) { + set_errno(ret); + return (VOID *)-1; + } + + if ((UINT32)shmflg & SHM_EXEC) { + prot |= PROT_EXEC; + acc_mode |= SHM_S_IXUGO; + } else if (((UINT32)shmflg & SHM_RDONLY) == 0) { + prot |= PROT_WRITE; + acc_mode |= SHM_S_IWUGO; + } + + SYSV_SHM_LOCK(); + seg = ShmFindSeg(shmid); + if (seg == NULL) { + SYSV_SHM_UNLOCK(); + return (VOID *)-1; + } + + ret = ShmPermCheck(seg, acc_mode); + if (ret != 0) { + goto ERROR; + } + + seg->ds.shm_nattch++; + r = ShmatVmmAlloc(seg, shmaddr, shmflg, prot); + if (r == NULL) { + seg->ds.shm_nattch--; + SYSV_SHM_UNLOCK(); + return (VOID *)-1; + } + + r->shmid = shmid; + r->regionFlags |= VM_MAP_REGION_FLAG_SHM; + seg->ds.shm_atime = time(NULL); + seg->ds.shm_lpid = LOS_GetCurrProcessID(); + SYSV_SHM_UNLOCK(); + + return (VOID *)(UINTPTR)r->range.base; +ERROR: + set_errno(ret); + SYSV_SHM_UNLOCK(); + PRINT_DEBUG("%s %d, ret = %d\n", __FUNCTION__, __LINE__, ret); + return (VOID *)-1; +} + +INT32 ShmCtl(INT32 shmid, INT32 cmd, struct shmid_ds *buf) +{ + struct shmIDSource *seg = NULL; + INT32 ret = 0; + struct shm_info shmInfo = { 0 }; + struct ipc_perm shm_perm; + + cmd = ((UINT32)cmd & ~IPC_64); + + SYSV_SHM_LOCK(); + + if ((cmd != IPC_INFO) && (cmd != SHM_INFO)) { + seg = ShmFindSeg(shmid); + if (seg == NULL) { + SYSV_SHM_UNLOCK(); + return -1; + } + } + + if ((buf == NULL) && (cmd != IPC_RMID)) { + ret = EINVAL; + goto ERROR; + } + + switch (cmd) { + case IPC_STAT: + case SHM_STAT: + ret = ShmPermCheck(seg, SHM_S_IRUGO); + if (ret != 0) { + goto ERROR; + } + + ret = LOS_ArchCopyToUser(buf, &seg->ds, sizeof(struct shmid_ds)); + if (ret != 0) { + ret = EFAULT; + goto ERROR; + } + if (cmd == SHM_STAT) { + ret = (unsigned int)((unsigned int)seg->ds.shm_perm.seq << 16) | (unsigned int)((unsigned int)shmid & 0xffff); /* 16: use the seq as the upper 16 bits */ + } + break; + case IPC_SET: + ret = ShmPermCheck(seg, SHM_M); + if (ret != 0) { + ret = EPERM; + goto ERROR; + } + + ret = LOS_ArchCopyFromUser(&shm_perm, &buf->shm_perm, sizeof(struct ipc_perm)); + if (ret != 0) { + ret = EFAULT; + goto ERROR; + } + seg->ds.shm_perm.uid = shm_perm.uid; + seg->ds.shm_perm.gid = shm_perm.gid; + seg->ds.shm_perm.mode = (seg->ds.shm_perm.mode & ~ACCESSPERMS) | + (shm_perm.mode & ACCESSPERMS); + seg->ds.shm_ctime = time(NULL); +#ifdef LOSCFG_SHELL + (VOID)memcpy_s(seg->ownerName, OS_PCB_NAME_LEN, OS_PCB_FROM_PID(shm_perm.uid)->processName, + OS_PCB_NAME_LEN); +#endif + break; + case IPC_RMID: + ret = ShmPermCheck(seg, SHM_M); + if (ret != 0) { + ret = EPERM; + goto ERROR; + } + + seg->status |= SHM_SEG_REMOVE; + if (seg->ds.shm_nattch <= 0) { + ShmFreeSeg(seg, &IPC_SHM_USED_PAGE_COUNT); + } + break; + case IPC_INFO: + ret = LOS_ArchCopyToUser(buf, &IPC_SHM_INFO, sizeof(struct shminfo)); + if (ret != 0) { + ret = EFAULT; + goto ERROR; + } + ret = IPC_SHM_INFO.shmmni; + break; + case SHM_INFO: + shmInfo.shm_rss = 0; + shmInfo.shm_swp = 0; + shmInfo.shm_tot = 0; + shmInfo.swap_attempts = 0; + shmInfo.swap_successes = 0; + shmInfo.used_ids = ShmSegUsedCount(); + ret = LOS_ArchCopyToUser(buf, &shmInfo, sizeof(struct shm_info)); + if (ret != 0) { + ret = EFAULT; + goto ERROR; + } + ret = IPC_SHM_INFO.shmmni; + break; + default: + VM_ERR("the cmd(%d) is not supported!", cmd); + ret = EINVAL; + goto ERROR; + } + + SYSV_SHM_UNLOCK(); + return ret; + +ERROR: + set_errno(ret); + SYSV_SHM_UNLOCK(); + PRINT_DEBUG("%s %d, ret = %d\n", __FUNCTION__, __LINE__, ret); + return -1; +} + +INT32 ShmDt(const VOID *shmaddr) +{ + LosVmSpace *space = OsCurrProcessGet()->vmSpace; + struct shmIDSource *seg = NULL; + LosVmMapRegion *region = NULL; + INT32 shmid; + INT32 ret; + + if (IS_PAGE_ALIGNED(shmaddr) == 0) { + ret = EINVAL; + goto ERROR; + } + + (VOID)LOS_MuxAcquire(&space->regionMux); + region = LOS_RegionFind(space, (VADDR_T)(UINTPTR)shmaddr); + if (region == NULL) { + ret = EINVAL; + goto ERROR_WITH_LOCK; + } + shmid = region->shmid; + + if (region->range.base != (VADDR_T)(UINTPTR)shmaddr) { + ret = EINVAL; + goto ERROR_WITH_LOCK; + } + + /* remove it from aspace */ + LOS_RbDelNode(&space->regionRbTree, ®ion->rbNode); + LOS_ArchMmuUnmap(&space->archMmu, region->range.base, region->range.size >> PAGE_SHIFT); + (VOID)LOS_MuxRelease(&space->regionMux); + /* free it */ + free(region); + + SYSV_SHM_LOCK(); + seg = ShmFindSeg(shmid); + if (seg == NULL) { + ret = EINVAL; + SYSV_SHM_UNLOCK(); + goto ERROR; + } + + ShmPagesRefDec(seg); + seg->ds.shm_nattch--; + if ((seg->ds.shm_nattch <= 0) && + (seg->status & SHM_SEG_REMOVE)) { + ShmFreeSeg(seg, &IPC_SHM_USED_PAGE_COUNT); + } else { + seg->ds.shm_dtime = time(NULL); + seg->ds.shm_lpid = LOS_GetCurrProcessID(); + } + SYSV_SHM_UNLOCK(); + + return 0; + +ERROR_WITH_LOCK: + (VOID)LOS_MuxRelease(&space->regionMux); +ERROR: + set_errno(ret); + PRINT_DEBUG("%s %d, ret = %d\n", __FUNCTION__, __LINE__, ret); + return -1; +} + +VOID OsShmCBDestroy(struct shmIDSource *shmSegs, struct shminfo *shmInfo, LosMux *sysvShmMux) +{ + if ((shmSegs == NULL) || (shmInfo == NULL) || (sysvShmMux == NULL)) { + return; + } + + for (UINT32 index = 0; index < shmInfo->shmmni; index++) { + struct shmIDSource *seg = &shmSegs[index]; + if (seg->status == SHM_SEG_FREE) { + continue; + } + + (VOID)LOS_MuxLock(sysvShmMux, LOS_WAIT_FOREVER); + ShmFreeSeg(seg, NULL); + (VOID)LOS_MuxUnlock(sysvShmMux); + } + + (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, shmSegs); + (VOID)LOS_MuxDestroy(sysvShmMux); +} + +#ifdef LOSCFG_SHELL +STATIC VOID OsShmInfoCmd(VOID) +{ + INT32 i; + struct shmIDSource *seg = NULL; + + PRINTK("\r\n------- Shared Memory Segments -------\n"); + PRINTK("key shmid perms bytes nattch status owner\n"); + SYSV_SHM_LOCK(); + for (i = 0; i < IPC_SHM_INFO.shmmni; i++) { + seg = &IPC_SHM_SEGS[i]; + if (!(seg->status & SHM_SEG_USED)) { + continue; + } + PRINTK("%08x %-8d %-10o %-10u %-10u %-10x %s\n", seg->ds.shm_perm.key, + i, seg->ds.shm_perm.mode, seg->ds.shm_segsz, seg->ds.shm_nattch, + seg->status, seg->ownerName); + + } + SYSV_SHM_UNLOCK(); +} + +STATIC VOID OsShmDeleteCmd(INT32 shmid) +{ + struct shmIDSource *seg = NULL; + + if ((shmid < 0) || (shmid >= IPC_SHM_INFO.shmmni)) { + PRINT_ERR("shmid is invalid: %d\n", shmid); + return; + } + + SYSV_SHM_LOCK(); + seg = ShmFindSeg(shmid); + if (seg == NULL) { + SYSV_SHM_UNLOCK(); + return; + } + + if (seg->ds.shm_nattch <= 0) { + ShmFreeSeg(seg, &IPC_SHM_USED_PAGE_COUNT); + } + SYSV_SHM_UNLOCK(); +} + +STATIC VOID OsShmCmdUsage(VOID) +{ + PRINTK("\tnone option, print shm usage info\n" + "\t-r [shmid], Recycle the specified shared memory about shmid\n" + "\t-h | --help, print shm command usage\n"); +} + +UINT32 OsShellCmdShm(INT32 argc, const CHAR *argv[]) +{ + INT32 shmid; + CHAR *endPtr = NULL; + + if (argc == 0) { + OsShmInfoCmd(); + } else if (argc == 1) { + if ((strcmp(argv[0], "-h") != 0) && (strcmp(argv[0], "--help") != 0)) { + PRINTK("Invalid option: %s\n", argv[0]); + } + OsShmCmdUsage(); + } else if (argc == 2) { /* 2: two parameter */ + if (strcmp(argv[0], "-r") != 0) { + PRINTK("Invalid option: %s\n", argv[0]); + goto DONE; + } + shmid = strtoul((CHAR *)argv[1], &endPtr, 0); + if ((endPtr == NULL) || (*endPtr != 0)) { + PRINTK("check shmid %s(us) invalid\n", argv[1]); + goto DONE; + } + /* try to delete shm about shmid */ + OsShmDeleteCmd(shmid); + } + return 0; +DONE: + OsShmCmdUsage(); + return -1; +} + +SHELLCMD_ENTRY(shm_shellcmd, CMD_TYPE_SHOW, "shm", 2, (CmdCallBackFunc)OsShellCmdShm); +#endif +#endif + diff --git a/src/kernel_liteos_a/kernel/common/BUILD.gn b/src/kernel_liteos_a/kernel/common/BUILD.gn new file mode 100644 index 00000000..476ab6d7 --- /dev/null +++ b/src/kernel_liteos_a/kernel/common/BUILD.gn @@ -0,0 +1,55 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ + "los_config.c", + "los_excinfo.c", + "los_init.c", + "los_magickey.c", + "los_printf.c", + "main.c", + ] + + if (defined(LOSCFG_FS_VFS)) { + sources += [ + "console.c", + "virtual_serial.c", + ] + } + + public_configs = [ ":public" ] +} + +config("public") { + include_dirs = [ "." ] +} diff --git a/src/kernel_liteos_a/kernel/common/Makefile b/src/kernel_liteos_a/kernel/common/Makefile new file mode 100644 index 00000000..4a474095 --- /dev/null +++ b/src/kernel_liteos_a/kernel/common/Makefile @@ -0,0 +1,46 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := common + +LOCAL_SRCS = $(wildcard ./main.c) + +LOCAL_INCLUDE += -I $(LITEOSTOPDIR)/compat/posix/src \ + -I $(LITEOSTOPDIR)/bsd/dev/random + +LOCAL_SRCS += $(wildcard *.c) +ifneq ($(LOSCFG_FS_VFS), y) +LOCAL_SRCS := $(filter-out console.c virtual_serial.c, $(LOCAL_SRCS)) +endif + +LOCAL_FLAGS := $(LOCAL_INCLUDE) + +include $(MODULE) diff --git a/src/kernel_liteos_a/kernel/common/console.c b/src/kernel_liteos_a/kernel/common/console.c new file mode 100644 index 00000000..bfaa4c59 --- /dev/null +++ b/src/kernel_liteos_a/kernel/common/console.c @@ -0,0 +1,1640 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "console.h" +#include "fcntl.h" +#include "sys/ioctl.h" +#ifdef LOSCFG_FILE_MODE +#include "stdarg.h" +#endif +#include "unistd.h" +#include "securec.h" +#ifdef LOSCFG_SHELL_DMESG +#include "dmesg_pri.h" +#endif +#ifdef LOSCFG_SHELL +#include "shcmd.h" +#include "shell_pri.h" +#endif +#include "los_exc_pri.h" +#include "los_process_pri.h" +#include "los_sched_pri.h" +#include "user_copy.h" +#include "fs/driver.h" + +#define EACH_CHAR 1 +#define UART_IOC_MAGIC 'u' +#define UART_CFG_ATTR _IOW(UART_IOC_MAGIC, 5, int) +#define UART_CFG_PRIVATE _IOW(UART_IOC_MAGIC, 6, int) +/* Inter-module variable */ +extern UINT32 g_uart_fputc_en; +STATIC UINT32 ConsoleSendTask(UINTPTR param); + +STATIC UINT8 g_taskConsoleIDArray[LOSCFG_BASE_CORE_TSK_LIMIT]; +STATIC SPIN_LOCK_INIT(g_consoleSpin); +STATIC SPIN_LOCK_INIT(g_consoleWriteSpinLock); + +#define SHELL_ENTRYID_INVALID 0xFFFFFFFF +#define SHELL_TASK_PRIORITY 9 +#define CONSOLE_CIRBUF_EVENT 0x02U +#define CONSOLE_SEND_TASK_EXIT 0x04U +#define CONSOLE_SEND_TASK_RUNNING 0x10U + +#define SHELL_ENTRY_NAME "ShellEntry" +#define SHELL_ENTRY_NAME_LEN 10 + +CONSOLE_CB *g_console[CONSOLE_NUM]; +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + +/* + * acquire uart driver function and filep of /dev/console, + * then store uart driver function in *filepOps + * and store filep of /dev/console in *privFilep. + */ +INT32 GetFilepOps(const struct file *filep, struct file **privFilep, const struct file_operations_vfs **filepOps) +{ + INT32 ret; + + if ((filep == NULL) || (filep->f_vnode == NULL) || (filep->f_vnode->data == NULL)) { + ret = EINVAL; + goto ERROUT; + } + + /* to find console device's filep(now it is *privFilep) through i_private */ + struct drv_data *drv = (struct drv_data *)filep->f_vnode->data; + *privFilep = (struct file *)drv->priv; + if (((*privFilep)->f_vnode == NULL) || ((*privFilep)->f_vnode->data == NULL)) { + ret = EINVAL; + goto ERROUT; + } + + /* to find uart driver operation function through u.i_opss */ + + drv = (struct drv_data *)(*privFilep)->f_vnode->data; + + *filepOps = (const struct file_operations_vfs *)drv->ops; + + return ENOERR; +ERROUT: + set_errno(ret); + return VFS_ERROR; +} + +INT32 ConsoleTcGetAttr(INT32 fd, struct termios *termios) +{ + struct file *filep = NULL; + CONSOLE_CB *consoleCB = NULL; + + INT32 ret = fs_getfilep(fd, &filep); + if (ret < 0) { + return -EPERM; + } + + consoleCB = (CONSOLE_CB *)filep->f_priv; + if (consoleCB == NULL) { + return -EFAULT; + } + + (VOID)memcpy_s(termios, sizeof(struct termios), &consoleCB->consoleTermios, sizeof(struct termios)); + return LOS_OK; +} + +INT32 ConsoleTcSetAttr(INT32 fd, INT32 actions, const struct termios *termios) +{ + struct file *filep = NULL; + CONSOLE_CB *consoleCB = NULL; + + (VOID)actions; + + INT32 ret = fs_getfilep(fd, &filep); + if (ret < 0) { + return -EPERM; + } + + consoleCB = (CONSOLE_CB *)filep->f_priv; + if (consoleCB == NULL) { + return -EFAULT; + } + + (VOID)memcpy_s(&consoleCB->consoleTermios, sizeof(struct termios), termios, sizeof(struct termios)); + return LOS_OK; +} + +STATIC UINT32 ConsoleRefcountGet(const CONSOLE_CB *consoleCB) +{ + return consoleCB->refCount; +} + +STATIC VOID ConsoleRefcountSet(CONSOLE_CB *consoleCB, BOOL flag) +{ + (consoleCB->refCount) += flag ? 1 : -1; +} + +BOOL IsConsoleOccupied(const CONSOLE_CB *consoleCB) +{ + return ConsoleRefcountGet(consoleCB); +} + +STATIC INT32 ConsoleCtrlCaptureLine(CONSOLE_CB *consoleCB) +{ + struct termios consoleTermios = {0}; + UINT32 intSave; + + LOS_SpinLockSave(&g_consoleSpin, &intSave); + (VOID)ConsoleTcGetAttr(consoleCB->fd, &consoleTermios); + consoleTermios.c_lflag |= ICANON | ECHO; + (VOID)ConsoleTcSetAttr(consoleCB->fd, 0, &consoleTermios); + LOS_SpinUnlockRestore(&g_consoleSpin, intSave); + + return LOS_OK; +} + +STATIC INT32 ConsoleCtrlCaptureChar(CONSOLE_CB *consoleCB) +{ + struct termios consoleTermios = {0}; + UINT32 intSave; + + LOS_SpinLockSave(&g_consoleSpin, &intSave); + (VOID)ConsoleTcGetAttr(consoleCB->fd, &consoleTermios); + consoleTermios.c_lflag &= ~(ICANON | ECHO); + (VOID)ConsoleTcSetAttr(consoleCB->fd, 0, &consoleTermios); + LOS_SpinUnlockRestore(&g_consoleSpin, intSave); + + return LOS_OK; +} + +STATIC INT32 ConsoleCtrlRightsCapture(CONSOLE_CB *consoleCB) +{ + (VOID)LOS_SemPend(consoleCB->consoleSem, LOS_WAIT_FOREVER); + if ((ConsoleRefcountGet(consoleCB) == 0) && + (OsCurrTaskGet()->taskID != consoleCB->shellEntryId)) { + /* not 0:indicate that shellentry is in uart_read, suspend shellentry task directly */ + (VOID)LOS_TaskSuspend(consoleCB->shellEntryId); + } + ConsoleRefcountSet(consoleCB, TRUE); + return LOS_OK; +} + +STATIC INT32 ConsoleCtrlRightsRelease(CONSOLE_CB *consoleCB) +{ + if (ConsoleRefcountGet(consoleCB) == 0) { + PRINT_ERR("console is free\n"); + (VOID)LOS_SemPost(consoleCB->consoleSem); + return LOS_NOK; + } else { + ConsoleRefcountSet(consoleCB, FALSE); + if ((ConsoleRefcountGet(consoleCB) == 0) && + (OsCurrTaskGet()->taskID != consoleCB->shellEntryId)) { + (VOID)LOS_TaskResume(consoleCB->shellEntryId); + } + } + (VOID)LOS_SemPost(consoleCB->consoleSem); + return LOS_OK; +} + +STATIC CONSOLE_CB *OsGetConsoleByDevice(const CHAR *deviceName) +{ + INT32 ret; + struct Vnode *vnode = NULL; + + VnodeHold(); + ret = VnodeLookup(deviceName, &vnode, 0); + VnodeDrop(); + if (ret < 0) { + set_errno(EACCES); + return NULL; + } + + if (g_console[CONSOLE_SERIAL - 1]->devVnode == vnode) { + return g_console[CONSOLE_SERIAL - 1]; + } else if (g_console[CONSOLE_TELNET - 1]->devVnode == vnode) { + return g_console[CONSOLE_TELNET - 1]; + } else { + set_errno(ENOENT); + return NULL; + } +} + +STATIC INT32 OsGetConsoleID(const CHAR *deviceName) +{ + if ((deviceName != NULL) && + (strlen(deviceName) == strlen(SERIAL)) && + (!strncmp(deviceName, SERIAL, strlen(SERIAL)))) { + return CONSOLE_SERIAL; + } +#ifdef LOSCFG_NET_TELNET + else if ((deviceName != NULL) && + (strlen(deviceName) == strlen(TELNET)) && + (!strncmp(deviceName, TELNET, strlen(TELNET)))) { + return CONSOLE_TELNET; + } +#endif + return -1; +} + +STATIC INT32 OsConsoleFullpathToID(const CHAR *fullpath) +{ +#define CONSOLE_SERIAL_1 "/dev/console1" +#define CONSOLE_TELNET_2 "/dev/console2" + + size_t len; + + if (fullpath == NULL) { + return -1; + } + + len = strlen(fullpath); + if ((len == strlen(CONSOLE_SERIAL_1)) && + (!strncmp(fullpath, CONSOLE_SERIAL_1, strlen(CONSOLE_SERIAL_1)))) { + return CONSOLE_SERIAL; + } +#ifdef LOSCFG_NET_TELNET + else if ((len == strlen(CONSOLE_TELNET_2)) && + (!strncmp(fullpath, CONSOLE_TELNET_2, strlen(CONSOLE_TELNET_2)))) { + return CONSOLE_TELNET; + } +#endif + return -1; +} + +STATIC BOOL ConsoleFifoEmpty(const CONSOLE_CB *console) +{ + return console->fifoOut == console->fifoIn; +} + +STATIC VOID ConsoleFifoClearup(CONSOLE_CB *console) +{ + console->fifoOut = 0; + console->fifoIn = 0; + (VOID)memset_s(console->fifo, CONSOLE_FIFO_SIZE, 0, CONSOLE_FIFO_SIZE); +} + +STATIC VOID ConsoleFifoLenUpdate(CONSOLE_CB *console) +{ + console->currentLen = console->fifoIn - console->fifoOut; +} + +STATIC INT32 ConsoleReadFifo(CHAR *buffer, CONSOLE_CB *console, size_t bufLen) +{ + INT32 ret; + UINT32 readNum; + + readNum = MIN(bufLen, console->currentLen); + ret = memcpy_s(buffer, bufLen, console->fifo + console->fifoOut, readNum); + if (ret != EOK) { + PRINTK("%s,%d memcpy_s failed\n", __FUNCTION__, __LINE__); + return -1; + } + console->fifoOut += readNum; + if (ConsoleFifoEmpty(console)) { + ConsoleFifoClearup(console); + } + ConsoleFifoLenUpdate(console); + return (INT32)readNum; +} + +INT32 FilepOpen(struct file *filep, const struct file_operations_vfs *fops) +{ + INT32 ret; + if (fops->open == NULL) { + return -EFAULT; + } + + /* + * adopt uart open function to open filep (filep is + * corresponding to filep of /dev/console) + */ + ret = fops->open(filep); + return (ret < 0) ? -EPERM : ret; +} + +STATIC INLINE VOID UserEndOfRead(CONSOLE_CB *consoleCB, struct file *filep, + const struct file_operations_vfs *fops) +{ + CHAR ch; + if (consoleCB->consoleTermios.c_lflag & ECHO) { + ch = '\r'; + (VOID)fops->write(filep, &ch, 1); + } + consoleCB->fifo[consoleCB->fifoIn++] = '\n'; + consoleCB->fifo[consoleCB->fifoIn] = '\0'; + consoleCB->currentLen = consoleCB->fifoIn; +} + +enum { + STAT_NORMAL_KEY, + STAT_ESC_KEY, + STAT_MULTI_KEY +}; + +STATIC INT32 UserShellCheckUDRL(const CHAR ch, INT32 *lastTokenType) +{ + INT32 ret = LOS_OK; + if (ch == 0x1b) { /* 0x1b: ESC */ + *lastTokenType = STAT_ESC_KEY; + return ret; + } else if (ch == 0x5b) { /* 0x5b: first Key combination */ + if (*lastTokenType == STAT_ESC_KEY) { + *lastTokenType = STAT_MULTI_KEY; + return ret; + } + } else if (ch == 0x41) { /* up */ + if (*lastTokenType == STAT_MULTI_KEY) { + *lastTokenType = STAT_NORMAL_KEY; + return ret; + } + } else if (ch == 0x42) { /* down */ + if (*lastTokenType == STAT_MULTI_KEY) { + *lastTokenType = STAT_NORMAL_KEY; + return ret; + } + } else if (ch == 0x43) { /* right */ + if (*lastTokenType == STAT_MULTI_KEY) { + *lastTokenType = STAT_NORMAL_KEY; + return ret; + } + } else if (ch == 0x44) { /* left */ + if (*lastTokenType == STAT_MULTI_KEY) { + *lastTokenType = STAT_NORMAL_KEY; + return ret; + } + } + return LOS_NOK; +} + +STATIC INT32 IsNeedContinue(CONSOLE_CB *consoleCB, char ch, INT32 *lastTokenType) +{ + if (((ch == '\b') && (consoleCB->consoleTermios.c_lflag & ECHO) && (ConsoleFifoEmpty(consoleCB))) || + (UserShellCheckUDRL(ch, lastTokenType) == LOS_OK)) { /* parse the up/down/right/left key */ + return LOS_NOK; + } + + return LOS_OK; +} + +STATIC VOID EchoToTerminal(CONSOLE_CB *consoleCB, struct file *filep, const struct file_operations_vfs *fops, char ch) +{ + if (consoleCB->consoleTermios.c_lflag & ECHO) { + if (ch == '\b') { + (VOID)fops->write(filep, "\b \b", 3); // 3: length of "\b \b" + } else { + (VOID)fops->write(filep, &ch, EACH_CHAR); + } + } +} + +STATIC VOID StoreReadChar(CONSOLE_CB *consoleCB, char ch, INT32 readcount) +{ + /* 3, store read char len need to minus \b */ + if ((readcount == EACH_CHAR) && (consoleCB->fifoIn <= (CONSOLE_FIFO_SIZE - 3))) { + if (ch == '\b') { + if (!ConsoleFifoEmpty(consoleCB)) { + consoleCB->fifo[--consoleCB->fifoIn] = '\0'; + } + } else { + consoleCB->fifo[consoleCB->fifoIn] = (UINT8)ch; + consoleCB->fifoIn++; + } + } +} + +VOID KillPgrp(UINT16 consoleId) +{ + if ((consoleId > CONSOLE_NUM) || (consoleId <= 0)) { + return; + } + + CONSOLE_CB *consoleCB = g_console[consoleId - 1]; + /* the default of consoleCB->pgrpId is -1, may not be set yet, avoid killing all processes */ + if (consoleCB->pgrpId < 0) { + return; + } + (VOID)OsKillLock(consoleCB->pgrpId, SIGINT); +} + +STATIC INT32 UserFilepRead(CONSOLE_CB *consoleCB, struct file *filep, const struct file_operations_vfs *fops, + CHAR *buffer, size_t bufLen) +{ + INT32 ret; + INT32 needreturn = LOS_NOK; + CHAR ch; + INT32 lastTokenType = STAT_NORMAL_KEY; + + if (fops->read == NULL) { + return -EFAULT; + } + + /* Non-ICANON mode */ + if ((consoleCB->consoleTermios.c_lflag & ICANON) == 0) { + ret = fops->read(filep, buffer, bufLen); + return (ret < 0) ? -EPERM : ret; + } + /* ICANON mode: store data to console buffer, read data and stored data into console fifo */ + if (consoleCB->currentLen == 0) { + while (1) { + ret = fops->read(filep, &ch, EACH_CHAR); + if (ret <= 0) { + return ret; + } + + if (IsNeedContinue(consoleCB, ch, &lastTokenType)) + continue; + + switch (ch) { + case '\r': + ch = '\n'; + case '\n': + EchoToTerminal(consoleCB, filep, fops, ch); + UserEndOfRead(consoleCB, filep, fops); + ret = ConsoleReadFifo(buffer, consoleCB, bufLen); + + needreturn = LOS_OK; + break; + case '\b': + default: + EchoToTerminal(consoleCB, filep, fops, ch); + StoreReadChar(consoleCB, ch, ret); + break; + } + + if (needreturn == LOS_OK) + break; + } + } else { + /* if data is already in console fifo, we return them immediately */ + ret = ConsoleReadFifo(buffer, consoleCB, bufLen); + } + + return ret; +} + +INT32 FilepRead(struct file *filep, const struct file_operations_vfs *fops, CHAR *buffer, size_t bufLen) +{ + INT32 ret; + if (fops->read == NULL) { + return -EFAULT; + } + /* + * adopt uart read function to read data from filep + * and write data to buffer (filep is + * corresponding to filep of /dev/console) + */ + ret = fops->read(filep, buffer, bufLen); + return (ret < 0) ? -EPERM : ret; +} + +INT32 FilepWrite(struct file *filep, const struct file_operations_vfs *fops, const CHAR *buffer, size_t bufLen) +{ + INT32 ret; + if (fops->write == NULL) { + return -EFAULT; + } + + ret = fops->write(filep, buffer, bufLen); + return (ret < 0) ? -EPERM : ret; +} + +INT32 FilepClose(struct file *filep, const struct file_operations_vfs *fops) +{ + INT32 ret; + if ((fops == NULL) || (fops->close == NULL)) { + return -EFAULT; + } + + /* + * adopt uart close function to open filep (filep is + * corresponding to filep of /dev/console) + */ + ret = fops->close(filep); + return ret < 0 ? -EPERM : ret; +} + +INT32 FilepIoctl(struct file *filep, const struct file_operations_vfs *fops, INT32 cmd, unsigned long arg) +{ + INT32 ret; + if (fops->ioctl == NULL) { + return -EFAULT; + } + + ret = fops->ioctl(filep, cmd, arg); + return (ret < 0) ? -EPERM : ret; +} + +INT32 FilepPoll(struct file *filep, const struct file_operations_vfs *fops, poll_table *fds) +{ + INT32 ret; + if (fops->poll == NULL) { + return -EFAULT; + } + + /* + * adopt uart poll function to poll filep (filep is + * corresponding to filep of /dev/serial) + */ + ret = fops->poll(filep, fds); + return (ret < 0) ? -EPERM : ret; +} + +STATIC INT32 ConsoleOpen(struct file *filep) +{ + INT32 ret; + UINT32 consoleID; + struct file *privFilep = NULL; + const struct file_operations_vfs *fileOps = NULL; + + consoleID = (UINT32)OsConsoleFullpathToID(filep->f_path); + if (consoleID == (UINT32)-1) { + ret = EPERM; + goto ERROUT; + } + filep->f_priv = g_console[consoleID - 1]; + + ret = GetFilepOps(filep, &privFilep, &fileOps); + if (ret != ENOERR) { + ret = EINVAL; + goto ERROUT; + } + ret = FilepOpen(privFilep, fileOps); + if (ret < 0) { + ret = EPERM; + goto ERROUT; + } + return ENOERR; + +ERROUT: + set_errno(ret); + return VFS_ERROR; +} + +STATIC INT32 ConsoleClose(struct file *filep) +{ + INT32 ret; + struct file *privFilep = NULL; + const struct file_operations_vfs *fileOps = NULL; + + ret = GetFilepOps(filep, &privFilep, &fileOps); + if (ret != ENOERR) { + ret = EINVAL; + goto ERROUT; + } + ret = FilepClose(privFilep, fileOps); + if (ret < 0) { + ret = EPERM; + goto ERROUT; + } + + return ENOERR; + +ERROUT: + set_errno(ret); + return VFS_ERROR; +} + +STATIC ssize_t DoRead(CONSOLE_CB *consoleCB, CHAR *buffer, size_t bufLen, + struct file *privFilep, + const struct file_operations_vfs *fileOps) +{ + INT32 ret; + +#ifdef LOSCFG_SHELL + if (OsCurrTaskGet()->taskID == consoleCB->shellEntryId) { + ret = FilepRead(privFilep, fileOps, buffer, bufLen); + } else { +#endif + (VOID)ConsoleCtrlRightsCapture(consoleCB); + ret = UserFilepRead(consoleCB, privFilep, fileOps, buffer, bufLen); + (VOID)ConsoleCtrlRightsRelease(consoleCB); +#ifdef LOSCFG_SHELL + } +#endif + + return ret; +} + +STATIC ssize_t ConsoleRead(struct file *filep, CHAR *buffer, size_t bufLen) +{ + INT32 ret; + struct file *privFilep = NULL; + CONSOLE_CB *consoleCB = NULL; + CHAR *sbuffer = NULL; + BOOL userBuf = FALSE; + const struct file_operations_vfs *fileOps = NULL; + + if ((buffer == NULL) || (bufLen == 0)) { + ret = EINVAL; + goto ERROUT; + } + + if (bufLen > CONSOLE_FIFO_SIZE) { + bufLen = CONSOLE_FIFO_SIZE; + } + + userBuf = LOS_IsUserAddressRange((vaddr_t)(UINTPTR)buffer, bufLen); + ret = GetFilepOps(filep, &privFilep, &fileOps); + if (ret != ENOERR) { + ret = -EINVAL; + goto ERROUT; + } + consoleCB = (CONSOLE_CB *)filep->f_priv; + if (consoleCB == NULL) { + consoleCB = OsGetConsoleByTaskID(OsCurrTaskGet()->taskID); + if (consoleCB == NULL) { + return -EFAULT; + } + } + + /* + * shell task use FilepRead function to get data, + * user task use UserFilepRead to get data + */ + sbuffer = userBuf ? LOS_MemAlloc(m_aucSysMem0, bufLen) : buffer; + if (sbuffer == NULL) { + ret = -ENOMEM; + goto ERROUT; + } + + ret = DoRead(consoleCB, sbuffer, bufLen, privFilep, fileOps); + if (ret < 0) { + goto ERROUT; + } + + if (userBuf) { + if (LOS_ArchCopyToUser(buffer, sbuffer, bufLen) != 0) { + ret = -EFAULT; + goto ERROUT; + } + + LOS_MemFree(m_aucSysMem0, sbuffer); + } + + return ret; + +ERROUT: + if ((userBuf) && (sbuffer != NULL)) { + LOS_MemFree(m_aucSysMem0, sbuffer); + } + set_errno(-ret); + return VFS_ERROR; +} + +STATIC ssize_t DoWrite(CirBufSendCB *cirBufSendCB, CHAR *buffer, size_t bufLen) +{ + INT32 cnt; + size_t written = 0; + UINT32 intSave; + +#ifdef LOSCFG_SHELL_DMESG + (VOID)OsLogMemcpyRecord(buffer, bufLen); + if (OsCheckConsoleLock()) { + return 0; + } +#endif + + LOS_SpinLockSave(&g_consoleWriteSpinLock, &intSave); + while (written < (INT32)bufLen) { + /* Transform for CR/LR mode */ + if ((buffer[written] == '\n') || (buffer[written] == '\r')) { + (VOID)LOS_CirBufWrite(&cirBufSendCB->cirBufCB, "\r", 1); + } + + cnt = LOS_CirBufWrite(&cirBufSendCB->cirBufCB, &buffer[written], 1); + if (cnt <= 0) { + break; + } + written += cnt; + } + LOS_SpinUnlockRestore(&g_consoleWriteSpinLock, intSave); + + /* Log is cached but not printed when a system exception occurs */ + if (OsGetSystemStatus() == OS_SYSTEM_NORMAL) { + (VOID)LOS_EventWrite(&cirBufSendCB->sendEvent, CONSOLE_CIRBUF_EVENT); + } + + return written; +} + +STATIC ssize_t ConsoleWrite(struct file *filep, const CHAR *buffer, size_t bufLen) +{ + INT32 ret; + CHAR *sbuffer = NULL; + BOOL userBuf = FALSE; + CirBufSendCB *cirBufSendCB = NULL; + struct file *privFilep = NULL; + const struct file_operations_vfs *fileOps = NULL; + + if ((buffer == NULL) || (bufLen == 0)) { + ret = EINVAL; + goto ERROUT; + } + + if (bufLen > CONSOLE_FIFO_SIZE) { + bufLen = CONSOLE_FIFO_SIZE; + } + + userBuf = LOS_IsUserAddressRange((vaddr_t)(UINTPTR)buffer, bufLen); + + ret = GetFilepOps(filep, &privFilep, &fileOps); + if ((ret != ENOERR) || (fileOps->write == NULL) || (filep->f_priv == NULL)) { + ret = EINVAL; + goto ERROUT; + } + cirBufSendCB = ((CONSOLE_CB *)filep->f_priv)->cirBufSendCB; + + /* + * adopt uart open function to read data from buffer + * and write data to filep (filep is + * corresponding to filep of /dev/console) + */ + sbuffer = userBuf ? LOS_MemAlloc(m_aucSysMem0, bufLen) : (CHAR *)buffer; + if (sbuffer == NULL) { + ret = ENOMEM; + goto ERROUT; + } + + if (userBuf && (LOS_ArchCopyFromUser(sbuffer, buffer, bufLen) != 0)) { + ret = EFAULT; + goto ERROUT; + } + ret = DoWrite(cirBufSendCB, sbuffer, bufLen); + + if (userBuf) { + LOS_MemFree(m_aucSysMem0, sbuffer); + } + + return ret; + +ERROUT: + if (userBuf && sbuffer != NULL) { + LOS_MemFree(m_aucSysMem0, sbuffer); + } + + set_errno(ret); + return VFS_ERROR; +} + +STATIC INT32 ConsoleSetSW(CONSOLE_CB *consoleCB, unsigned long arg) +{ + struct termios kerTermios; + UINT32 intSave; + + if (LOS_ArchCopyFromUser(&kerTermios, (struct termios *)arg, sizeof(struct termios)) != 0) { + return -EFAULT; + } + + LOS_SpinLockSave(&g_consoleSpin, &intSave); + (VOID)ConsoleTcSetAttr(consoleCB->fd, 0, &kerTermios); + LOS_SpinUnlockRestore(&g_consoleSpin, intSave); + return LOS_OK; +} + +#define DEFAULT_WINDOW_SIZE_COL 80 +#define DEFAULT_WINDOW_SIZE_ROW 24 +STATIC INT32 ConsoleGetWinSize(unsigned long arg) +{ + struct winsize kws = { + .ws_col = DEFAULT_WINDOW_SIZE_COL, + .ws_row = DEFAULT_WINDOW_SIZE_ROW + }; + + return (LOS_CopyFromKernel((VOID *)arg, sizeof(struct winsize), &kws, sizeof(struct winsize)) != 0) ? + -EFAULT : LOS_OK; +} + +STATIC INT32 ConsoleGetTermios(unsigned long arg) +{ + struct file *filep = NULL; + CONSOLE_CB *consoleCB = NULL; + + INT32 ret = fs_getfilep(0, &filep); + if (ret < 0) { + return -EPERM; + } + + consoleCB = (CONSOLE_CB *)filep->f_priv; + if (consoleCB == NULL) { + return -EFAULT; + } + + return (LOS_ArchCopyToUser((VOID *)arg, &consoleCB->consoleTermios, sizeof(struct termios)) != 0) ? + -EFAULT : LOS_OK; +} + +INT32 ConsoleSetPgrp(CONSOLE_CB *consoleCB, unsigned long arg) +{ + if (LOS_ArchCopyFromUser(&consoleCB->pgrpId, (INT32 *)(UINTPTR)arg, sizeof(INT32)) != 0) { + return -EFAULT; + } + return LOS_OK; +} + +INT32 ConsoleGetPgrp(CONSOLE_CB *consoleCB, unsigned long arg) +{ + return (LOS_ArchCopyToUser((VOID *)arg, &consoleCB->pgrpId, sizeof(INT32)) != 0) ? -EFAULT : LOS_OK; +} + +STATIC INT32 ConsoleIoctl(struct file *filep, INT32 cmd, unsigned long arg) +{ + INT32 ret; + struct file *privFilep = NULL; + CONSOLE_CB *consoleCB = NULL; + const struct file_operations_vfs *fileOps = NULL; + + ret = GetFilepOps(filep, &privFilep, &fileOps); + if (ret != ENOERR) { + ret = EINVAL; + goto ERROUT; + } + + if (fileOps->ioctl == NULL) { + ret = EFAULT; + goto ERROUT; + } + + consoleCB = (CONSOLE_CB *)filep->f_priv; + if (consoleCB == NULL) { + ret = EINVAL; + goto ERROUT; + } + + switch (cmd) { + case CONSOLE_CONTROL_RIGHTS_CAPTURE: + ret = ConsoleCtrlRightsCapture(consoleCB); + break; + case CONSOLE_CONTROL_RIGHTS_RELEASE: + ret = ConsoleCtrlRightsRelease(consoleCB); + break; + case CONSOLE_CONTROL_CAPTURE_LINE: + ret = ConsoleCtrlCaptureLine(consoleCB); + break; + case CONSOLE_CONTROL_CAPTURE_CHAR: + ret = ConsoleCtrlCaptureChar(consoleCB); + break; + case CONSOLE_CONTROL_REG_USERTASK: + ret = ConsoleTaskReg(consoleCB->consoleID, arg); + break; + case TIOCGWINSZ: + ret = ConsoleGetWinSize(arg); + break; + case TCSETSW: + ret = ConsoleSetSW(consoleCB, arg); + break; + case TCGETS: + ret = ConsoleGetTermios(arg); + break; + case TIOCGPGRP: + ret = ConsoleGetPgrp(consoleCB, arg); + break; + case TIOCSPGRP: + ret = ConsoleSetPgrp(consoleCB, arg); + break; + default: + if ((cmd == UART_CFG_ATTR || cmd == UART_CFG_PRIVATE) + && !LOS_IsUserAddress(arg)) { + ret = EINVAL; + goto ERROUT; + } + ret = fileOps->ioctl(privFilep, cmd, arg); + break; + } + + if (ret < 0) { + ret = EPERM; + goto ERROUT; + } + + return ret; +ERROUT: + set_errno(ret); + return VFS_ERROR; +} + +STATIC INT32 ConsolePoll(struct file *filep, poll_table *fds) +{ + INT32 ret; + struct file *privFilep = NULL; + const struct file_operations_vfs *fileOps = NULL; + + ret = GetFilepOps(filep, &privFilep, &fileOps); + if (ret != ENOERR) { + ret = EINVAL; + goto ERROUT; + } + + ret = FilepPoll(privFilep, fileOps, fds); + if (ret < 0) { + ret = EPERM; + goto ERROUT; + } + return ret; + +ERROUT: + set_errno(ret); + return VFS_ERROR; +} + +/* console device driver function structure */ +STATIC const struct file_operations_vfs g_consoleDevOps = { + .open = ConsoleOpen, /* open */ + .close = ConsoleClose, /* close */ + .read = ConsoleRead, /* read */ + .write = ConsoleWrite, /* write */ + .seek = NULL, + .ioctl = ConsoleIoctl, + .mmap = NULL, +#ifndef CONFIG_DISABLE_POLL + .poll = ConsolePoll, +#endif +}; + +STATIC VOID OsConsoleTermiosInit(CONSOLE_CB *consoleCB, const CHAR *deviceName) +{ + struct termios consoleTermios = {0}; + + if ((deviceName != NULL) && + (strlen(deviceName) == strlen(SERIAL)) && + (!strncmp(deviceName, SERIAL, strlen(SERIAL)))) { + consoleCB->isNonBlock = SetSerialBlock(consoleCB); + + /* set console to have a buffer for user */ + (VOID)ConsoleTcGetAttr(consoleCB->fd, &consoleTermios); + consoleTermios.c_lflag |= ICANON | ECHO; + consoleTermios.c_cc[VINTR] = 3; /* /003 for ^C */ + (VOID)ConsoleTcSetAttr(consoleCB->fd, 0, &consoleTermios); + } +#ifdef LOSCFG_NET_TELNET + else if ((deviceName != NULL) && + (strlen(deviceName) == strlen(TELNET)) && + (!strncmp(deviceName, TELNET, strlen(TELNET)))) { + consoleCB->isNonBlock = SetTelnetBlock(consoleCB); + /* set console to have a buffer for user */ + (VOID)ConsoleTcGetAttr(consoleCB->fd, &consoleTermios); + consoleTermios.c_lflag |= ICANON | ECHO; + consoleTermios.c_cc[VINTR] = 3; /* /003 for ^C */ + (VOID)ConsoleTcSetAttr(consoleCB->fd, 0, &consoleTermios); + } +#endif +} + +STATIC INT32 OsConsoleFileInit(CONSOLE_CB *consoleCB) +{ + INT32 ret; + struct Vnode *vnode = NULL; + struct file *filep = NULL; + + VnodeHold(); + ret = VnodeLookup(consoleCB->name, &vnode, 0); + if (ret != LOS_OK) { + ret = EACCES; + goto ERROUT; + } + + filep = files_allocate(vnode, O_RDWR, 0, consoleCB, FILE_START_FD); + if (filep == NULL) { + ret = EMFILE; + goto ERROUT; + } + filep->ops = (struct file_operations_vfs *)((struct drv_data *)vnode->data)->ops; + consoleCB->fd = filep->fd; + +ERROUT: + VnodeDrop(); + return ret; +} + +/* + * Initialized console control platform so that when we operate /dev/console + * as if we are operating /dev/ttyS0 (uart0). + */ +STATIC INT32 OsConsoleDevInit(CONSOLE_CB *consoleCB, const CHAR *deviceName) +{ + INT32 ret; + struct file *filep = NULL; + struct Vnode *vnode = NULL; + struct file_operations_vfs *devOps = NULL; + + /* allocate memory for filep,in order to unchange the value of filep */ + filep = (struct file *)LOS_MemAlloc(m_aucSysMem0, sizeof(struct file)); + if (filep == NULL) { + ret = ENOMEM; + goto ERROUT; + } + + VnodeHold(); + ret = VnodeLookup(deviceName, &vnode, V_DUMMY); + VnodeDrop(); // not correct, but can't fix perfectly here + if (ret != LOS_OK) { + ret = EACCES; + PRINTK("!! can not find %s\n", consoleCB->name); + goto ERROUT; + } + + consoleCB->devVnode = vnode; + + /* + * initialize the console filep which is associated with /dev/console, + * assign the uart0 vnode of /dev/ttyS0 to console inod of /dev/console, + * then we can operate console's filep as if we operate uart0 filep of + * /dev/ttyS0. + */ + (VOID)memset_s(filep, sizeof(struct file), 0, sizeof(struct file)); + filep->f_oflags = O_RDWR; + filep->f_pos = 0; + filep->f_vnode = vnode; + filep->f_path = NULL; + filep->f_priv = NULL; + /* + * Use filep to connect console and uart, we can find uart driver function through filep. + * now we can operate /dev/console to operate /dev/ttyS0 through filep. + */ + devOps = (struct file_operations_vfs *)((struct drv_data*)vnode->data)->ops; + if (devOps != NULL && devOps->open != NULL) { + (VOID)devOps->open(filep); + } else { + ret = ENOSYS; + goto ERROUT; + } + + ret = register_driver(consoleCB->name, &g_consoleDevOps, DEFFILEMODE, filep); + if (ret != LOS_OK) { + goto ERROUT; + } + + return LOS_OK; + +ERROUT: + if (filep) { + (VOID)LOS_MemFree(m_aucSysMem0, filep); + } + + set_errno(ret); + return LOS_NOK; +} + +STATIC UINT32 OsConsoleDevDeinit(const CONSOLE_CB *consoleCB) +{ + return unregister_driver(consoleCB->name); +} + +STATIC CirBufSendCB *ConsoleCirBufCreate(VOID) +{ + UINT32 ret; + CHAR *fifo = NULL; + CirBufSendCB *cirBufSendCB = NULL; + CirBuf *cirBufCB = NULL; + + cirBufSendCB = (CirBufSendCB *)LOS_MemAlloc(m_aucSysMem0, sizeof(CirBufSendCB)); + if (cirBufSendCB == NULL) { + return NULL; + } + (VOID)memset_s(cirBufSendCB, sizeof(CirBufSendCB), 0, sizeof(CirBufSendCB)); + + fifo = (CHAR *)LOS_MemAlloc(m_aucSysMem0, CONSOLE_CIRCBUF_SIZE); + if (fifo == NULL) { + goto ERROR_WITH_SENDCB; + } + (VOID)memset_s(fifo, CONSOLE_CIRCBUF_SIZE, 0, CONSOLE_CIRCBUF_SIZE); + + cirBufCB = &cirBufSendCB->cirBufCB; + ret = LOS_CirBufInit(cirBufCB, fifo, CONSOLE_CIRCBUF_SIZE); + if (ret != LOS_OK) { + goto ERROR_WITH_FIFO; + } + + (VOID)LOS_EventInit(&cirBufSendCB->sendEvent); + return cirBufSendCB; + +ERROR_WITH_FIFO: + (VOID)LOS_MemFree(m_aucSysMem0, cirBufCB->fifo); +ERROR_WITH_SENDCB: + (VOID)LOS_MemFree(m_aucSysMem0, cirBufSendCB); + return NULL; +} + +STATIC VOID ConsoleCirBufDelete(CirBufSendCB *cirBufSendCB) +{ + CirBuf *cirBufCB = &cirBufSendCB->cirBufCB; + + (VOID)LOS_MemFree(m_aucSysMem0, cirBufCB->fifo); + LOS_CirBufDeinit(cirBufCB); + (VOID)LOS_EventDestroy(&cirBufSendCB->sendEvent); + (VOID)LOS_MemFree(m_aucSysMem0, cirBufSendCB); +} + +STATIC UINT32 OsConsoleBufInit(CONSOLE_CB *consoleCB) +{ + UINT32 ret; + TSK_INIT_PARAM_S initParam = {0}; + + consoleCB->cirBufSendCB = ConsoleCirBufCreate(); + if (consoleCB->cirBufSendCB == NULL) { + return LOS_NOK; + } + + initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)ConsoleSendTask; + initParam.usTaskPrio = SHELL_TASK_PRIORITY; + initParam.auwArgs[0] = (UINTPTR)consoleCB; + initParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + initParam.pcName = (consoleCB->consoleID == CONSOLE_SERIAL) ? "SendToSer" : "SendToTelnet"; + initParam.uwResved = LOS_TASK_STATUS_DETACHED; + + ret = LOS_TaskCreate(&consoleCB->sendTaskID, &initParam); + if (ret != LOS_OK) { + ConsoleCirBufDelete(consoleCB->cirBufSendCB); + consoleCB->cirBufSendCB = NULL; + return LOS_NOK; + } + (VOID)LOS_EventRead(&consoleCB->cirBufSendCB->sendEvent, CONSOLE_SEND_TASK_RUNNING, + LOS_WAITMODE_OR | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER); + + return LOS_OK; +} + +STATIC VOID OsConsoleBufDeinit(CONSOLE_CB *consoleCB) +{ + CirBufSendCB *cirBufSendCB = consoleCB->cirBufSendCB; + + consoleCB->cirBufSendCB = NULL; + (VOID)LOS_EventWrite(&cirBufSendCB->sendEvent, CONSOLE_SEND_TASK_EXIT); +} + +STATIC CONSOLE_CB *OsConsoleCBInit(UINT32 consoleID) +{ + CONSOLE_CB *consoleCB = (CONSOLE_CB *)LOS_MemAlloc((VOID *)m_aucSysMem0, sizeof(CONSOLE_CB)); + if (consoleCB == NULL) { + return NULL; + } + (VOID)memset_s(consoleCB, sizeof(CONSOLE_CB), 0, sizeof(CONSOLE_CB)); + + consoleCB->consoleID = consoleID; + consoleCB->pgrpId = -1; + consoleCB->shellEntryId = SHELL_ENTRYID_INVALID; /* initialize shellEntryId to an invalid value */ + consoleCB->name = LOS_MemAlloc((VOID *)m_aucSysMem0, CONSOLE_NAMELEN); + if (consoleCB->name == NULL) { + PRINT_ERR("consoleCB->name malloc failed\n"); + (VOID)LOS_MemFree((VOID *)m_aucSysMem0, consoleCB); + return NULL; + } + return consoleCB; +} + +STATIC VOID OsConsoleCBDeinit(CONSOLE_CB *consoleCB) +{ + (VOID)LOS_MemFree((VOID *)m_aucSysMem0, consoleCB->name); + consoleCB->name = NULL; + (VOID)LOS_MemFree((VOID *)m_aucSysMem0, consoleCB); +} + +STATIC CONSOLE_CB *OsConsoleCreate(UINT32 consoleID, const CHAR *deviceName) +{ + INT32 ret; + CONSOLE_CB *consoleCB = OsConsoleCBInit(consoleID); + if (consoleCB == NULL) { + PRINT_ERR("console malloc error.\n"); + return NULL; + } + + ret = snprintf_s(consoleCB->name, CONSOLE_NAMELEN, CONSOLE_NAMELEN - 1, + "%s%u", CONSOLE, consoleCB->consoleID); + if (ret == -1) { + PRINT_ERR("consoleCB->name snprintf_s failed\n"); + goto ERR_WITH_NAME; + } + + ret = (INT32)OsConsoleBufInit(consoleCB); + if (ret != LOS_OK) { + PRINT_ERR("console OsConsoleBufInit error. %d\n", ret); + goto ERR_WITH_NAME; + } + + ret = (INT32)LOS_SemCreate(1, &consoleCB->consoleSem); + if (ret != LOS_OK) { + PRINT_ERR("create sem for uart failed\n"); + goto ERR_WITH_BUF; + } + + ret = OsConsoleDevInit(consoleCB, deviceName); + if (ret != LOS_OK) { + PRINT_ERR("console OsConsoleDevInit error. %d\n", ret); + goto ERR_WITH_SEM; + } + + ret = OsConsoleFileInit(consoleCB); + if (ret != LOS_OK) { + PRINT_ERR("console OsConsoleFileInit error. %d\n", ret); + goto ERR_WITH_DEV; + } + + OsConsoleTermiosInit(consoleCB, deviceName); + return consoleCB; + +ERR_WITH_DEV: + ret = (INT32)OsConsoleDevDeinit(consoleCB); + if (ret != LOS_OK) { + PRINT_ERR("OsConsoleDevDeinit failed!\n"); + } +ERR_WITH_SEM: + (VOID)LOS_SemDelete(consoleCB->consoleSem); +ERR_WITH_BUF: + OsConsoleBufDeinit(consoleCB); +ERR_WITH_NAME: + OsConsoleCBDeinit(consoleCB); + return NULL; +} + +STATIC UINT32 OsConsoleDelete(CONSOLE_CB *consoleCB) +{ + UINT32 ret; + + (VOID)files_close(consoleCB->fd); + ret = OsConsoleDevDeinit(consoleCB); + if (ret != LOS_OK) { + PRINT_ERR("OsConsoleDevDeinit failed!\n"); + } + OsConsoleBufDeinit((CONSOLE_CB *)consoleCB); + (VOID)LOS_SemDelete(consoleCB->consoleSem); + (VOID)LOS_MemFree(m_aucSysMem0, consoleCB->name); + consoleCB->name = NULL; + (VOID)LOS_MemFree(m_aucSysMem0, consoleCB); + + return ret; +} + +/* Initialized system console and return stdinfd stdoutfd stderrfd */ +INT32 system_console_init(const CHAR *deviceName) +{ +#ifdef LOSCFG_SHELL + UINT32 ret; +#endif + INT32 consoleID; + UINT32 intSave; + CONSOLE_CB *consoleCB = NULL; + + consoleID = OsGetConsoleID(deviceName); + if (consoleID == -1) { + PRINT_ERR("device is full.\n"); + return VFS_ERROR; + } + + consoleCB = OsConsoleCreate((UINT32)consoleID, deviceName); + if (consoleCB == NULL) { + PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__); + return VFS_ERROR; + } + + LOS_SpinLockSave(&g_consoleSpin, &intSave); + g_console[consoleID - 1] = consoleCB; + if (OsCurrTaskGet() != NULL) { + g_taskConsoleIDArray[OsCurrTaskGet()->taskID] = (UINT8)consoleID; + } + LOS_SpinUnlockRestore(&g_consoleSpin, intSave); + +#ifdef LOSCFG_SHELL + ret = OsShellInit(consoleID); + if (ret != LOS_OK) { + PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__); + LOS_SpinLockSave(&g_consoleSpin, &intSave); + (VOID)OsConsoleDelete(consoleCB); + g_console[consoleID - 1] = NULL; + if (OsCurrTaskGet() != NULL) { + g_taskConsoleIDArray[OsCurrTaskGet()->taskID] = 0; + } + LOS_SpinUnlockRestore(&g_consoleSpin, intSave); + return VFS_ERROR; + } +#endif + + return ENOERR; +} + +INT32 system_console_deinit(const CHAR *deviceName) +{ + UINT32 ret; + CONSOLE_CB *consoleCB = NULL; + UINT32 taskIdx; + LosTaskCB *taskCB = NULL; + UINT32 intSave; + + consoleCB = OsGetConsoleByDevice(deviceName); + if (consoleCB == NULL) { + return VFS_ERROR; + } + +#ifdef LOSCFG_SHELL + (VOID)OsShellDeinit((INT32)consoleCB->consoleID); +#endif + + LOS_SpinLockSave(&g_consoleSpin, &intSave); + /* Redirect all tasks to serial as telnet was unavailable after deinitializing */ + for (taskIdx = 0; taskIdx < g_taskMaxNum; taskIdx++) { + taskCB = ((LosTaskCB *)g_taskCBArray) + taskIdx; + if (OsTaskIsUnused(taskCB)) { + continue; + } else { + g_taskConsoleIDArray[taskCB->taskID] = CONSOLE_SERIAL; + } + } + g_console[consoleCB->consoleID - 1] = NULL; + LOS_SpinUnlockRestore(&g_consoleSpin, intSave); + + ret = OsConsoleDelete(consoleCB); + if (ret != LOS_OK) { + PRINT_ERR("%s, Failed to system_console_deinit\n", __FUNCTION__); + return VFS_ERROR; + } + + return ENOERR; +} + +BOOL ConsoleEnable(VOID) +{ + INT32 consoleID; + + if (OsCurrTaskGet() != NULL) { + consoleID = g_taskConsoleIDArray[OsCurrTaskGet()->taskID]; + if (g_uart_fputc_en == 0) { + if ((g_console[CONSOLE_TELNET - 1] != NULL) && OsPreemptable()) { + return TRUE; + } + } + + if (consoleID == 0) { + return FALSE; + } else if ((consoleID == CONSOLE_TELNET) || (consoleID == CONSOLE_SERIAL)) { + return ((OsGetSystemStatus() == OS_SYSTEM_NORMAL) && !OsPreemptable()) ? FALSE : TRUE; + } +#if defined (LOSCFG_DRIVERS_USB_SERIAL_GADGET) || defined (LOSCFG_DRIVERS_USB_ETH_SER_GADGET) + else if ((SerialTypeGet() == SERIAL_TYPE_USBTTY_DEV) && (userial_mask_get() == 1)) { + return TRUE; + } +#endif + } + + return FALSE; +} + +BOOL IsShellEntryRunning(UINT32 shellEntryId) +{ + LosTaskCB *taskCB = NULL; + if (shellEntryId == SHELL_ENTRYID_INVALID) { + return FALSE; + } + taskCB = OsGetTaskCB(shellEntryId); + return !OsTaskIsUnused(taskCB) && + (strlen(taskCB->taskName) == SHELL_ENTRY_NAME_LEN && + strncmp(taskCB->taskName, SHELL_ENTRY_NAME, SHELL_ENTRY_NAME_LEN) == 0); +} + +INT32 ConsoleTaskReg(INT32 consoleID, UINT32 taskID) +{ + UINT32 intSave; + + LOS_SpinLockSave(&g_consoleSpin, &intSave); + if (!IsShellEntryRunning(g_console[consoleID - 1]->shellEntryId)) { + g_console[consoleID - 1]->shellEntryId = taskID; + LOS_SpinUnlockRestore(&g_consoleSpin, intSave); + (VOID)OsSetCurrProcessGroupID(OS_USER_ROOT_PROCESS_ID); + return LOS_OK; + } + LOS_SpinUnlockRestore(&g_consoleSpin, intSave); + return (g_console[consoleID - 1]->shellEntryId == taskID) ? LOS_OK : LOS_NOK; +} + +BOOL SetSerialNonBlock(const CONSOLE_CB *consoleCB) +{ + if (consoleCB == NULL) { + PRINT_ERR("%s: Input parameter is illegal\n", __FUNCTION__); + return FALSE; + } + return ioctl(consoleCB->fd, CONSOLE_CMD_RD_BLOCK_SERIAL, CONSOLE_RD_NONBLOCK) == 0; +} + +BOOL SetSerialBlock(const CONSOLE_CB *consoleCB) +{ + if (consoleCB == NULL) { + PRINT_ERR("%s: Input parameter is illegal\n", __FUNCTION__); + return TRUE; + } + return ioctl(consoleCB->fd, CONSOLE_CMD_RD_BLOCK_SERIAL, CONSOLE_RD_BLOCK) != 0; +} + +BOOL SetTelnetNonBlock(const CONSOLE_CB *consoleCB) +{ + if (consoleCB == NULL) { + PRINT_ERR("%s: Input parameter is illegal\n", __FUNCTION__); + return FALSE; + } + return ioctl(consoleCB->fd, CONSOLE_CMD_RD_BLOCK_TELNET, CONSOLE_RD_NONBLOCK) == 0; +} + +BOOL SetTelnetBlock(const CONSOLE_CB *consoleCB) +{ + if (consoleCB == NULL) { + PRINT_ERR("%s: Input parameter is illegal\n", __FUNCTION__); + return TRUE; + } + return ioctl(consoleCB->fd, CONSOLE_CMD_RD_BLOCK_TELNET, CONSOLE_RD_BLOCK) != 0; +} + +BOOL is_nonblock(const CONSOLE_CB *consoleCB) +{ + if (consoleCB == NULL) { + PRINT_ERR("%s: Input parameter is illegal\n", __FUNCTION__); + return FALSE; + } + return consoleCB->isNonBlock; +} + +INT32 ConsoleUpdateFd(VOID) +{ + INT32 consoleID; + + if (OsCurrTaskGet() != NULL) { + consoleID = g_taskConsoleIDArray[(OsCurrTaskGet())->taskID]; + } else { + return -1; + } + + if (g_uart_fputc_en == 0) { + if (g_console[CONSOLE_TELNET - 1] != NULL) { + consoleID = CONSOLE_TELNET; + } + } else if (consoleID == 0) { + if (g_console[CONSOLE_SERIAL - 1] != NULL) { + consoleID = CONSOLE_SERIAL; + } else if (g_console[CONSOLE_TELNET - 1] != NULL) { + consoleID = CONSOLE_TELNET; + } else { + PRINTK("No console dev used.\n"); + return -1; + } + } + + return (g_console[consoleID - 1] != NULL) ? g_console[consoleID - 1]->fd : -1; +} + +CONSOLE_CB *OsGetConsoleByID(INT32 consoleID) +{ + if (consoleID != CONSOLE_TELNET) { + consoleID = CONSOLE_SERIAL; + } + return g_console[consoleID - 1]; +} + +CONSOLE_CB *OsGetConsoleByTaskID(UINT32 taskID) +{ + INT32 consoleID = g_taskConsoleIDArray[taskID]; + + return OsGetConsoleByID(consoleID); +} + +VOID OsSetConsoleID(UINT32 newTaskID, UINT32 curTaskID) +{ + if ((newTaskID >= LOSCFG_BASE_CORE_TSK_LIMIT) || (curTaskID >= LOSCFG_BASE_CORE_TSK_LIMIT)) { + return; + } + + g_taskConsoleIDArray[newTaskID] = g_taskConsoleIDArray[curTaskID]; +} + +STATIC ssize_t WriteToTerminal(const CONSOLE_CB *consoleCB, const CHAR *buffer, size_t bufLen) +{ + INT32 ret, fd; + INT32 cnt = 0; + struct file *privFilep = NULL; + struct file *filep = NULL; + const struct file_operations_vfs *fileOps = NULL; + + fd = consoleCB->fd; + ret = fs_getfilep(fd, &filep); + if (ret < 0) { + ret = -EPERM; + goto ERROUT; + } + ret = GetFilepOps(filep, &privFilep, &fileOps); + if (ret != ENOERR) { + ret = -EINVAL; + goto ERROUT; + } + + if ((fileOps == NULL) || (fileOps->write == NULL)) { + ret = EFAULT; + goto ERROUT; + } + (VOID)fileOps->write(privFilep, buffer, bufLen); + + return cnt; + +ERROUT: + set_errno(ret); + return VFS_ERROR; +} + +STATIC UINT32 ConsoleSendTask(UINTPTR param) +{ + CONSOLE_CB *consoleCB = (CONSOLE_CB *)param; + CirBufSendCB *cirBufSendCB = consoleCB->cirBufSendCB; + CirBuf *cirBufCB = &cirBufSendCB->cirBufCB; + UINT32 ret, size; + CHAR *buf = NULL; + + (VOID)LOS_EventWrite(&cirBufSendCB->sendEvent, CONSOLE_SEND_TASK_RUNNING); + + while (1) { + ret = LOS_EventRead(&cirBufSendCB->sendEvent, CONSOLE_CIRBUF_EVENT | CONSOLE_SEND_TASK_EXIT, + LOS_WAITMODE_OR | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER); + if (ret == CONSOLE_CIRBUF_EVENT) { + size = LOS_CirBufUsedSize(cirBufCB); + if (size == 0) { + continue; + } + buf = (CHAR *)LOS_MemAlloc(m_aucSysMem1, size + 1); + if (buf == NULL) { + continue; + } + (VOID)memset_s(buf, size + 1, 0, size + 1); + + (VOID)LOS_CirBufRead(cirBufCB, buf, size); + + (VOID)WriteToTerminal(consoleCB, buf, size); + (VOID)LOS_MemFree(m_aucSysMem1, buf); + } else if (ret == CONSOLE_SEND_TASK_EXIT) { + break; + } + } + + ConsoleCirBufDelete(cirBufSendCB); + return LOS_OK; +} + +#ifdef LOSCFG_KERNEL_SMP +VOID OsWaitConsoleSendTaskPend(UINT32 taskID) +{ + UINT32 i; + CONSOLE_CB *console = NULL; + LosTaskCB *taskCB = NULL; + INT32 waitTime = 3000; /* 3000: 3 seconds */ + + for (i = 0; i < CONSOLE_NUM; i++) { + console = g_console[i]; + if (console == NULL) { + continue; + } + + if (OS_TID_CHECK_INVALID(console->sendTaskID)) { + continue; + } + + taskCB = OS_TCB_FROM_TID(console->sendTaskID); + while ((waitTime > 0) && (taskCB->taskEvent == NULL) && (taskID != console->sendTaskID)) { + LOS_Mdelay(1); /* 1: wait console task pend */ + --waitTime; + } + } +} + +VOID OsWakeConsoleSendTask(VOID) +{ + UINT32 i; + CONSOLE_CB *console = NULL; + + for (i = 0; i < CONSOLE_NUM; i++) { + console = g_console[i]; + if (console == NULL) { + continue; + } + + if (console->cirBufSendCB != NULL) { + (VOID)LOS_EventWrite(&console->cirBufSendCB->sendEvent, CONSOLE_CIRBUF_EVENT); + } + } +} +#endif + diff --git a/src/kernel_liteos_a/kernel/common/console.h b/src/kernel_liteos_a/kernel/common/console.h new file mode 100644 index 00000000..b95ac48a --- /dev/null +++ b/src/kernel_liteos_a/kernel/common/console.h @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _CONSOLE_H +#define _CONSOLE_H + +#include "sys/ioctl.h" +#include "los_config.h" +#ifdef LOSCFG_FS_VFS +#include "termios.h" +#ifdef LOSCFG_NET_TELNET +#include "telnet_dev.h" +#endif +#include "virtual_serial.h" +#include "los_cir_buf.h" +#endif + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#ifdef LOSCFG_FS_VFS + +/* Define two fixed console id for Console ID. */ +#define CONSOLE_SERIAL 1 +#define CONSOLE_TELNET 2 + +#define LOSCFG_PLATFORM_CONSOLE +#define STDIN 0 +#define STDOUT 1 +#define STDERR 2 + +#define CONSOLE "/dev/console" +#define CONSOLE_NAMELEN 16 +#define CONSOLE_RD_BLOCK 1 +#define CONSOLE_RD_NONBLOCK 0 +#define CONSOLE_SHELL_KEY_EVENT 0x112 +#define CONSOLE_SHELL_EXITED 0x400 +#define CONSOLE_FIFO_SIZE 0x400 +#define CONSOLE_NUM 2 + +#define CONSOLE_CIRCBUF_SIZE 0x400 + +typedef struct { + CirBuf cirBufCB; /* Circular buffer CB */ + EVENT_CB_S sendEvent; /* Inform telnet send task */ +} CirBufSendCB; + +typedef struct { + UINT32 consoleID; + UINT32 consoleType; + UINT32 consoleSem; + UINT32 consoleMask; + struct Vnode *devVnode; + CHAR *name; + INT32 fd; + UINT32 refCount; + UINT32 shellEntryId; + INT32 pgrpId; + BOOL isNonBlock; +#ifdef LOSCFG_SHELL + VOID *shellHandle; +#endif + UINT32 sendTaskID; + CirBufSendCB *cirBufSendCB; + UINT8 fifo[CONSOLE_FIFO_SIZE]; + UINT32 fifoOut; + UINT32 fifoIn; + UINT32 currentLen; + struct termios consoleTermios; +} CONSOLE_CB; + +extern INT32 system_console_init(const CHAR *deviceName); +extern INT32 system_console_deinit(const CHAR *deviceName); +extern BOOL SetSerialNonBlock(const CONSOLE_CB *consoleCB); +extern BOOL SetSerialBlock(const CONSOLE_CB *consoleCB); +extern BOOL SetTelnetNonBlock(const CONSOLE_CB *consoleCB); +extern BOOL SetTelnetBlock(const CONSOLE_CB *consoleCB); +extern CONSOLE_CB *OsGetConsoleByID(INT32 consoleID); +extern CONSOLE_CB *OsGetConsoleByTaskID(UINT32 taskID); +extern INT32 ConsoleTaskReg(INT32 consoleID, UINT32 taskID); +extern INT32 ConsoleUpdateFd(VOID); +extern BOOL ConsoleEnable(VOID); +extern BOOL is_nonblock(const CONSOLE_CB *consoleCB); +extern BOOL IsConsoleOccupied(const CONSOLE_CB *consoleCB); +extern INT32 FilepOpen(struct file *filep, const struct file_operations_vfs *fops); +extern INT32 FilepClose(struct file *filep, const struct file_operations_vfs *fops); +extern INT32 FilepRead(struct file *filep, const struct file_operations_vfs *fops, CHAR *buffer, size_t bufLen); +extern INT32 FilepWrite(struct file *filep, const struct file_operations_vfs *fops, const CHAR *buffer, size_t bufLen); +extern INT32 FilepPoll(struct file *filep, const struct file_operations_vfs *fops, poll_table *fds); +extern INT32 FilepIoctl(struct file *filep, const struct file_operations_vfs *fops, INT32 cmd, unsigned long arg); +extern INT32 GetFilepOps(const struct file *filep, struct file **privFilep, const struct file_operations_vfs **fops); +#ifdef LOSCFG_KERNEL_SMP +extern VOID OsWaitConsoleSendTaskPend(UINT32 taskID); +extern VOID OsWakeConsoleSendTask(VOID); +#endif +extern VOID KillPgrp(UINT16 consoleId); + +/* console ioctl */ +#define CONSOLE_IOC_MAGIC 'c' +#define CONSOLE_CMD_RD_BLOCK_SERIAL _IO(CONSOLE_IOC_MAGIC, 1) +#define CONSOLE_CMD_RD_BLOCK_TELNET _IO(CONSOLE_IOC_MAGIC, 2) +#define CONSOLE_CONTROL_RIGHTS_CAPTURE _IO(CONSOLE_IOC_MAGIC, 3) +#define CONSOLE_CONTROL_RIGHTS_RELEASE _IO(CONSOLE_IOC_MAGIC, 4) +#define CONSOLE_CONTROL_CAPTURE_LINE _IO(CONSOLE_IOC_MAGIC, 5) +#define CONSOLE_CONTROL_CAPTURE_CHAR _IO(CONSOLE_IOC_MAGIC, 6) +#define CONSOLE_CONTROL_REG_USERTASK _IO(CONSOLE_IOC_MAGIC, 7) + +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _CONSOLE_H */ diff --git a/src/kernel_liteos_a/kernel/common/los_config.c b/src/kernel_liteos_a/kernel/common/los_config.c new file mode 100644 index 00000000..02723ee0 --- /dev/null +++ b/src/kernel_liteos_a/kernel/common/los_config.c @@ -0,0 +1,320 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_config.h" +#include "stdio.h" +#include "string.h" +#include "gic_common.h" +#include "los_atomic.h" +#include "los_exc_pri.h" +#include "los_hwi_pri.h" +#include "los_hw_tick_pri.h" +#include "los_init_pri.h" +#include "los_memory_pri.h" +#include "los_mp.h" +#include "los_mux_pri.h" +#include "los_printf.h" +#include "los_process_pri.h" +#include "los_queue_pri.h" +#include "los_sem_pri.h" +#include "los_spinlock.h" +#include "los_swtmr_pri.h" +#include "los_task_pri.h" +#include "los_sched_pri.h" +#include "los_tick.h" +#include "los_vm_boot.h" +#include "los_smp.h" + +STATIC SystemRebootFunc g_rebootHook = NULL; + +VOID OsSetRebootHook(SystemRebootFunc func) +{ + g_rebootHook = func; +} + +SystemRebootFunc OsGetRebootHook(VOID) +{ + return g_rebootHook; +} + +LITE_OS_SEC_TEXT_INIT STATIC UINT32 EarliestInit(VOID) +{ + /* Must be placed at the beginning of the boot process */ + OsSetMainTask(); + OsCurrTaskSet(OsGetMainTask()); + OsSchedRunqueueInit(); + + g_sysClock = OS_SYS_CLOCK; + g_tickPerSecond = LOSCFG_BASE_CORE_TICK_PER_SECOND; + + return LOS_OK; +} + +LITE_OS_SEC_TEXT_INIT STATIC UINT32 ArchEarlyInit(VOID) +{ + UINT32 ret; + + /* set system counter freq */ +#ifndef LOSCFG_TEE_ENABLE + HalClockFreqWrite(OS_SYS_CLOCK); +#endif + +#ifdef LOSCFG_PLATFORM_HWI + OsHwiInit(); +#endif + + OsExcInit(); + + ret = OsTickInit(g_sysClock, LOSCFG_BASE_CORE_TICK_PER_SECOND); + if (ret != LOS_OK) { + PRINT_ERR("OsTickInit error!\n"); + return ret; + } + + return LOS_OK; +} + +LITE_OS_SEC_TEXT_INIT STATIC UINT32 PlatformEarlyInit(VOID) +{ +#if defined(LOSCFG_PLATFORM_UART_WITHOUT_VFS) && defined(LOSCFG_DRIVERS) + uart_init(); +#endif /* LOSCFG_PLATFORM_UART_WITHOUT_VFS */ + + return LOS_OK; +} + +LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsIpcInit(VOID) +{ + UINT32 ret; + +#ifdef LOSCFG_BASE_IPC_SEM + ret = OsSemInit(); + if (ret != LOS_OK) { + PRINT_ERR("OsSemInit error\n"); + return ret; + } +#endif + +#ifdef LOSCFG_BASE_IPC_QUEUE + ret = OsQueueInit(); + if (ret != LOS_OK) { + PRINT_ERR("OsQueueInit error\n"); + return ret; + } +#endif + return LOS_OK; +} + +LITE_OS_SEC_TEXT_INIT STATIC UINT32 ArchInit(VOID) +{ +#ifdef LOSCFG_KERNEL_MMU + OsArchMmuInitPerCPU(); +#endif + return LOS_OK; +} + +LITE_OS_SEC_TEXT_INIT STATIC UINT32 PlatformInit(VOID) +{ + return LOS_OK; +} + +LITE_OS_SEC_TEXT_INIT STATIC UINT32 KModInit(VOID) +{ +#ifdef LOSCFG_BASE_CORE_SWTMR_ENABLE + OsSwtmrInit(); +#endif + return LOS_OK; +} + +LITE_OS_SEC_TEXT_INIT VOID OsSystemInfo(VOID) +{ +#ifdef LOSCFG_DEBUG_VERSION + const CHAR *buildType = "debug"; +#else + const CHAR *buildType = "release"; +#endif /* LOSCFG_DEBUG_VERSION */ + + PRINT_RELEASE("\n******************Welcome******************\n\n" + "Processor : %s" +#ifdef LOSCFG_KERNEL_SMP + " * %d\n" + "Run Mode : SMP\n" +#else + "\n" + "Run Mode : UP\n" +#endif + "GIC Rev : %s\n" + "build time : %s %s\n" + "Kernel : %s %d.%d.%d.%d/%s\n" + "\n*******************************************\n", + LOS_CpuInfo(), +#ifdef LOSCFG_KERNEL_SMP + LOSCFG_KERNEL_SMP_CORE_NUM, +#endif + HalIrqVersion(), __DATE__, __TIME__, \ + KERNEL_NAME, KERNEL_MAJOR, KERNEL_MINOR, KERNEL_PATCH, KERNEL_ITRE, buildType); +} + +LITE_OS_SEC_TEXT_INIT UINT32 OsMain(VOID) +{ + UINT32 ret; +#ifdef LOS_INIT_STATISTICS + UINT64 startNsec, endNsec, durationUsec; +#endif + + ret = EarliestInit(); + if (ret != LOS_OK) { + return ret; + } + OsInitCall(LOS_INIT_LEVEL_EARLIEST); + + ret = ArchEarlyInit(); + if (ret != LOS_OK) { + return ret; + } + OsInitCall(LOS_INIT_LEVEL_ARCH_EARLY); + + ret = PlatformEarlyInit(); + if (ret != LOS_OK) { + return ret; + } + OsInitCall(LOS_INIT_LEVEL_PLATFORM_EARLY); + + /* system and chip info */ + OsSystemInfo(); + + PRINT_RELEASE("\nmain core booting up...\n"); + +#ifdef LOS_INIT_STATISTICS + startNsec = LOS_CurrNanosec(); +#endif + + ret = OsProcessInit(); + if (ret != LOS_OK) { + return ret; + } + + OsInitCall(LOS_INIT_LEVEL_KMOD_PREVM); + + ret = OsSysMemInit(); + if (ret != LOS_OK) { + return ret; + } + + OsInitCall(LOS_INIT_LEVEL_VM_COMPLETE); + + ret = OsIpcInit(); + if (ret != LOS_OK) { + return ret; + } + + ret = OsSystemProcessCreate(); + if (ret != LOS_OK) { + return ret; + } + + ret = ArchInit(); + if (ret != LOS_OK) { + return ret; + } + OsInitCall(LOS_INIT_LEVEL_ARCH); + + ret = PlatformInit(); + if (ret != LOS_OK) { + return ret; + } + OsInitCall(LOS_INIT_LEVEL_PLATFORM); + + ret = KModInit(); + if (ret != LOS_OK) { + return ret; + } + + OsInitCall(LOS_INIT_LEVEL_KMOD_BASIC); + + OsInitCall(LOS_INIT_LEVEL_KMOD_EXTENDED); + +#ifdef LOSCFG_KERNEL_SMP + OsSmpInit(); +#endif + + OsInitCall(LOS_INIT_LEVEL_KMOD_TASK); + +#ifdef LOS_INIT_STATISTICS + endNsec = LOS_CurrNanosec(); + durationUsec = (endNsec - startNsec) / OS_SYS_NS_PER_US; + PRINTK("The main core takes %lluus to start.\n", durationUsec); +#endif + + return LOS_OK; +} + +#ifndef LOSCFG_PLATFORM_ADAPT +STATIC VOID SystemInit(VOID) +{ + PRINTK("dummy: *** %s ***\n", __FUNCTION__); +} +#else +extern VOID SystemInit(VOID); +#endif + +#ifndef LOSCFG_ENABLE_KERNEL_TEST +STATIC UINT32 OsSystemInitTaskCreate(VOID) +{ + UINT32 taskID; + TSK_INIT_PARAM_S sysTask; + + (VOID)memset_s(&sysTask, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + sysTask.pfnTaskEntry = (TSK_ENTRY_FUNC)SystemInit; + sysTask.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + sysTask.pcName = "SystemInit"; + sysTask.usTaskPrio = LOSCFG_BASE_CORE_TSK_DEFAULT_PRIO; + sysTask.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + sysTask.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + return LOS_TaskCreate(&taskID, &sysTask); +} + +STATIC UINT32 OsSystemInit(VOID) +{ + UINT32 ret; + + ret = OsSystemInitTaskCreate(); + if (ret != LOS_OK) { + return ret; + } + + return 0; +} + +LOS_MODULE_INIT(OsSystemInit, LOS_INIT_LEVEL_KMOD_TASK); +#endif diff --git a/src/kernel_liteos_a/kernel/common/los_config.h b/src/kernel_liteos_a/kernel/common/los_config.h new file mode 100644 index 00000000..f06ae174 --- /dev/null +++ b/src/kernel_liteos_a/kernel/common/los_config.h @@ -0,0 +1,486 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_config System configuration items + */ + +#ifndef _LOS_CONFIG_H +#define _LOS_CONFIG_H + +#include "los_tick.h" +#include "los_vm_zone.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_config + * int stack start addr + */ +extern CHAR __int_stack_start; +extern CHAR __rodata_start; +extern CHAR __rodata_end; +extern CHAR __bss_start; +extern CHAR __bss_end; +extern CHAR __text_start; +extern CHAR __text_end; +extern CHAR __ram_data_start; +extern CHAR __ram_data_end; +extern UINT32 __heap_start; +extern UINT32 __heap_end; + +/****************************** System clock module configuration ****************************/ +/** + * @ingroup los_config + * System clock (unit: HZ) + */ +#ifndef OS_SYS_CLOCK +#define OS_SYS_CLOCK (get_bus_clk()) +#endif +/** + * @ingroup los_config + * time timer clock (unit: HZ) + */ +#ifndef OS_TIME_TIMER_CLOCK +#define OS_TIME_TIMER_CLOCK OS_SYS_CLOCK +#endif + +/** + * @ingroup los_config + * limit addr range when search for 'func local(frame pointer)' or 'func name' + */ +#ifndef OS_SYS_FUNC_ADDR_START +#define OS_SYS_FUNC_ADDR_START ((UINTPTR)&__int_stack_start) +#endif +#ifndef OS_SYS_FUNC_ADDR_END +#define OS_SYS_FUNC_ADDR_END (KERNEL_VMM_BASE + SYS_MEM_SIZE_DEFAULT) +#endif + +/** + * @ingroup los_config + * Number of Ticks in one second + */ +#ifndef LOSCFG_BASE_CORE_TICK_PER_SECOND +#define LOSCFG_BASE_CORE_TICK_PER_SECOND 1000 /* 1ms per tick */ +#endif + +/** + * @ingroup los_config + * Minimum response error accuracy of tick interrupts, number of ticks in one second + */ +#ifndef LOSCFG_BASE_CORE_TICK_PER_SECOND_MINI +#define LOSCFG_BASE_CORE_TICK_PER_SECOND_MINI 1000UL /* 1ms */ +#endif + +#if (LOSCFG_BASE_CORE_TICK_PER_SECOND > LOSCFG_BASE_CORE_TICK_PER_SECOND_MINI) + #error "LOSCFG_BASE_CORE_TICK_PER_SECOND_MINI must be greater than LOSCFG_BASE_CORE_TICK_PER_SECOND" +#endif + +#if (LOSCFG_BASE_CORE_TICK_PER_SECOND_MINI > 1000UL) + #error "LOSCFG_BASE_CORE_TICK_PER_SECOND_MINI must be less than or equal to 1000" +#endif + +/** + * @ingroup los_config + * Microseconds of adjtime in one second + */ +#ifndef LOSCFG_BASE_CORE_ADJ_PER_SECOND +#define LOSCFG_BASE_CORE_ADJ_PER_SECOND 500 +#endif + +/** + * @ingroup los_config + * Sched clock interval + */ +#define SCHED_CLOCK_INTETRVAL_TICKS LOSCFG_BASE_CORE_TICK_PER_SECOND + +/** + * @ingroup los_config + * External configuration item for timer tailoring + */ +#if defined(LOSCFG_BASE_CORE_TICK_HW_TIME) && (LOSCFG_BASE_CORE_TICK_HW_TIME == 0) +#undef LOSCFG_BASE_CORE_TICK_HW_TIME +#endif +/****************************** Hardware interrupt module configuration ******************************/ +/** + * @ingroup los_config + * Configuration item for hardware interrupt tailoring + */ +#ifndef LOSCFG_PLATFORM_HWI +#define LOSCFG_PLATFORM_HWI +#endif + +/** + * @ingroup los_config + * Maximum number of used hardware interrupts, including Tick timer interrupts. + */ +#ifndef LOSCFG_PLATFORM_HWI_LIMIT +#define LOSCFG_PLATFORM_HWI_LIMIT 96 +#endif + +/** + * @ingroup los_config + * The binary point value decide the maximum preemption level. + * If preemption supported, the config value is [0, 1, 2, 3, 4, 5, 6], + * to the corresponding preemption level value is [128, 64, 32, 16, 8, 4, 2]. + */ +#ifdef LOSCFG_ARCH_INTERRUPT_PREEMPTION +#ifndef MAX_BINARY_POINT_VALUE +#define MAX_BINARY_POINT_VALUE 4 +#endif +#endif + +/****************************** Task module configuration ********************************/ +/** + * @ingroup los_config + * Minimum stack size. + * + * 0x800 bytes, aligned on a boundary of 8. + * 0x800 bytes, aligned on a boundary of 4. + */ +#ifndef LOS_TASK_MIN_STACK_SIZE +#ifdef __LP64__ +#define LOS_TASK_MIN_STACK_SIZE (ALIGN(0x800, 8)) +#else +#define LOS_TASK_MIN_STACK_SIZE (ALIGN(0x800, 4)) +#endif +#endif + +/** + * @ingroup los_config + * Default task priority + */ +#ifndef LOSCFG_BASE_CORE_TSK_DEFAULT_PRIO +#define LOSCFG_BASE_CORE_TSK_DEFAULT_PRIO 10 +#endif + +/** + * @ingroup los_config + * Maximum supported number of tasks except the idle task rather than the number of usable tasks + */ +#ifndef LOSCFG_BASE_CORE_TSK_LIMIT +#define LOSCFG_BASE_CORE_TSK_LIMIT 128 +#endif + +/** + * @ingroup los_config + * Maximum supported number of process rather than the number of usable processes. + */ +#ifndef LOSCFG_BASE_CORE_PROCESS_LIMIT +#define LOSCFG_BASE_CORE_PROCESS_LIMIT 64 +#endif + +#if (LOSCFG_BASE_CORE_TSK_LIMIT < LOSCFG_BASE_CORE_PROCESS_LIMIT) +#error "The number of tasks must be greater than or equal to the number of processes!" +#endif + +/** + * @ingroup los_config + * Size of the idle task stack + */ +#ifndef LOSCFG_BASE_CORE_TSK_IDLE_STACK_SIZE +#define LOSCFG_BASE_CORE_TSK_IDLE_STACK_SIZE SIZE(0x800) +#endif + +/** + * @ingroup los_config + * Default task stack size + */ +#ifndef LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE +#define LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE SIZE(0x4000) +#endif + +/** + * @ingroup los_config + * Longest execution time of tasks with the same priorities + */ +#ifndef LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT +#define LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT 20000 /* 20ms */ +#endif + +/** + * @ingroup los_config + * Configuration item for task (stack) monitoring module tailoring + */ +#ifndef LOSCFG_BASE_CORE_TSK_MONITOR +#define LOSCFG_BASE_CORE_TSK_MONITOR +#endif + +/****************************** Semaphore module configuration ******************************/ +/** + * @ingroup los_config + * Configuration item for semaphore module tailoring + */ +#ifndef LOSCFG_BASE_IPC_SEM +#define LOSCFG_BASE_IPC_SEM +#endif + +/** + * @ingroup los_config + * Maximum supported number of semaphores + */ +#ifndef LOSCFG_BASE_IPC_SEM_LIMIT +#define LOSCFG_BASE_IPC_SEM_LIMIT 1024 +#endif + +/** + * @ingroup los_config + * Maximum number of semaphores. + */ +#ifndef OS_SEM_COUNT_MAX +#define OS_SEM_COUNT_MAX 0xFFFE +#endif + +/****************************** Mutex module configuration ******************************/ +/** + * @ingroup los_config + * Configuration item for mutex module tailoring + */ +#ifndef LOSCFG_BASE_IPC_MUX +#define LOSCFG_BASE_IPC_MUX +#endif + +/****************************** rwlock module configuration ******************************/ +/** + * @ingroup los_config + * Configuration item for rwlock module tailoring + */ +#ifndef LOSCFG_BASE_IPC_RWLOCK +#define LOSCFG_BASE_IPC_RWLOCK +#endif + +/****************************** Queue module configuration ********************************/ +/** + * @ingroup los_config + * Configuration item for queue module tailoring + */ +#ifndef LOSCFG_BASE_IPC_QUEUE +#define LOSCFG_BASE_IPC_QUEUE +#endif + +/** + * @ingroup los_config + * Maximum supported number of queues rather than the number of usable queues + */ +#ifndef LOSCFG_BASE_IPC_QUEUE_LIMIT +#define LOSCFG_BASE_IPC_QUEUE_LIMIT 1024 +#endif +/****************************** Software timer module configuration **************************/ +#ifdef LOSCFG_BASE_IPC_QUEUE + +/** + * @ingroup los_config + * Configuration item for software timer module tailoring + */ +#ifndef LOSCFG_BASE_CORE_SWTMR_ENABLE +#define LOSCFG_BASE_CORE_SWTMR_ENABLE +#endif + +#ifdef LOSCFG_BASE_CORE_SWTMR_ENABLE +#define LOSCFG_BASE_CORE_SWTMR 1 +#else +#define LOSCFG_BASE_CORE_SWTMR 0 +#endif + +/** + * @ingroup los_config + * Maximum supported number of software timers rather than the number of usable software timers + */ +#ifndef LOSCFG_BASE_CORE_SWTMR_LIMIT +#define LOSCFG_BASE_CORE_SWTMR_LIMIT 1024 +#endif +/** + * @ingroup los_config + * Max number of software timers ID + * + * 0xFFFF: max number of all software timers + */ +#ifndef OS_SWTMR_MAX_TIMERID +#define OS_SWTMR_MAX_TIMERID ((0xFFFF / LOSCFG_BASE_CORE_SWTMR_LIMIT) * LOSCFG_BASE_CORE_SWTMR_LIMIT) +#endif +/** + * @ingroup los_config + * Maximum size of a software timer queue + */ +#ifndef OS_SWTMR_HANDLE_QUEUE_SIZE +#define OS_SWTMR_HANDLE_QUEUE_SIZE LOSCFG_BASE_CORE_SWTMR_LIMIT +#endif +#endif + + +/****************************** Memory module configuration **************************/ +/** + * @ingroup los_config + * Starting address of the system memory + */ +#ifndef OS_SYS_MEM_ADDR +#define OS_SYS_MEM_ADDR (&m_aucSysMem1[0]) +#endif + +/** + * @ingroup los_config + * Memory size + */ +#ifndef OS_SYS_MEM_SIZE +#define OS_SYS_MEM_SIZE \ + ((OS_SYS_FUNC_ADDR_END) - (((UINTPTR)&__bss_end + (64 - 1)) & ~(64 - 1))) +#endif + +/****************************** SMP module configuration **************************/ +#ifdef LOSCFG_KERNEL_SMP +#define LOSCFG_KERNEL_CORE_NUM LOSCFG_KERNEL_SMP_CORE_NUM +#else +#define LOSCFG_KERNEL_CORE_NUM 1 +#endif + +#define LOSCFG_KERNEL_CPU_MASK ((1 << LOSCFG_KERNEL_CORE_NUM) - 1) + +/** + * @ingroup los_config + * Version number + */ +#define _T(x) x +#define KERNEL_NAME "Huawei LiteOS" +#define KERNEL_NODE_NAME "hisilicon" +#define KERNEL_SEP " " +#define _V(v) _T(KERNEL_NAME)_T(KERNEL_SEP)_T(v) + +/** + * @ingroup los_config + * The Version number of Public + */ +#define KERNEL_MAJOR 2 +#define KERNEL_MINOR 0 +#define KERNEL_PATCH 0 +#define KERNEL_ITRE 37 + +#define VERSION_NUM(a, b, c, d) (((a) << 24) | ((b) << 16) | (c) << 8 | (d)) +#define KERNEL_OPEN_VERSION_NUM VERSION_NUM(KERNEL_MAJOR, KERNEL_MINOR, KERNEL_PATCH, KERNEL_ITRE) + +/** + * @ingroup los_config + * The container limit + */ +#ifndef LOSCFG_KERNEL_CONTAINER_DEFAULT_LIMIT +#define LOSCFG_KERNEL_CONTAINER_DEFAULT_LIMIT 10 +#endif + +/****************************** Exception information configuration ******************************/ +#ifdef LOSCFG_SAVE_EXCINFO +/** + * @ingroup los_config + * the size of space for recording exception information + */ +#define EXCINFO_RECORD_BUF_SIZE (16 * 1024) + +/** + * @ingroup los_config + * the address of space for recording exception information + * @attention + *
            + *
          • if uses, the address must be valid in flash, and it should not overlap with other addresses + * used to store valid information.
          • + *
          + * + */ +#define EXCINFO_RECORD_ADDR (0xffffffff) + +/** + * @ingroup los_config + * @brief define the type of functions for reading or writing exception information. + * + * @par Description: + *
            + *
          • This definition is used to declare the type of functions for reading or writing exception information
          • + *
          + * @attention + *
            + *
          • "startAddr" must be left to save the exception address space, the size of "buf" is "space"
          • + *
          + * + * @param startAddr [IN] Address of storage ,its must be left to save the exception address space + * @param space [IN] size of storage.its is also the size of "buf" + * @param rwFlag [IN] writer-read flag, 0 for writing,1 for reading, other number is to do nothing. + * @param buf [IN] the buffer of storing data. + * + * @retval none. + * @par Dependency: + *
          • los_config.h: the header file that contains the type definition.
          + * @see + */ +typedef VOID (*log_read_write_fn)(UINT32 startAddr, UINT32 space, UINT32 rwFlag, CHAR *buf); + +/** + * @ingroup los_config + * @brief Register recording exception information function. + * + * @par Description: + *
            + *
          • This API is used to Register recording exception information function, + * and specify location and space and size
          • + *
          + * @attention + *
            + *
          • "startAddr" must be left to save the exception address space, the size of "buf" is "space", + * the space of "buf" is malloc or free in user's code
          • + *
          + * + * @param startAddr [IN] Address of storage, it must be left to save the exception address space + * @param space [IN] size of storage space, it is also the size of "buf" + * @param buf [IN] the buffer of storing exception information, the space of "buf" is malloc or free + in user's code + * @param hook [IN] the function for reading or writing exception information. + * + * @retval none. + * @par Dependency: + *
          • los_config.h: the header file that contains the API declaration.
          + * @see + */ +VOID LOS_ExcInfoRegHook(UINT32 startAddr, UINT32 space, CHAR *buf, log_read_write_fn hook); +#endif + +extern UINT32 OsMain(VOID); + +typedef VOID (*SystemRebootFunc)(VOID); +VOID OsSetRebootHook(SystemRebootFunc func); +SystemRebootFunc OsGetRebootHook(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_CONFIG_H */ diff --git a/src/kernel_liteos_a/kernel/common/los_excinfo.c b/src/kernel_liteos_a/kernel/common/los_excinfo.c new file mode 100644 index 00000000..fbcf4f42 --- /dev/null +++ b/src/kernel_liteos_a/kernel/common/los_excinfo.c @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_base.h" +#include "los_hwi.h" +#ifdef LOSCFG_SHELL +#include "shcmd.h" +#endif +#ifdef LOSCFG_FS_VFS +#include "fs/fs.h" +#include "fs/fs_operation.h" +#endif + +#ifdef LOSCFG_SAVE_EXCINFO +STATIC log_read_write_fn g_excInfoRW = NULL; /* the hook of read-writing exception information */ +STATIC CHAR *g_excInfoBuf = NULL; /* pointer to the buffer for storing the exception information */ +STATIC UINT32 g_excInfoIndex = 0xFFFFFFFF; /* the index of the buffer for storing the exception information */ +STATIC UINT32 g_recordAddr = 0; /* the address of storing the exception information */ +STATIC UINT32 g_recordSpace = 0; /* the size of storing the exception information */ + +VOID SetExcInfoRW(log_read_write_fn func) +{ + g_excInfoRW = func; +} + +log_read_write_fn GetExcInfoRW(VOID) +{ + return g_excInfoRW; +} + +VOID SetExcInfoBuf(CHAR *buf) +{ + g_excInfoBuf = buf; +} + +CHAR *GetExcInfoBuf(VOID) +{ + return g_excInfoBuf; +} + +VOID SetExcInfoIndex(UINT32 index) +{ + g_excInfoIndex = index; +} + +UINT32 GetExcInfoIndex(VOID) +{ + return g_excInfoIndex; +} + +VOID SetRecordAddr(UINT32 addr) +{ + g_recordAddr = addr; +} + +UINT32 GetRecordAddr(VOID) +{ + return g_recordAddr; +} + +VOID SetRecordSpace(UINT32 space) +{ + g_recordSpace = space; +} + +UINT32 GetRecordSpace(VOID) +{ + return g_recordSpace; +} + +VOID WriteExcBufVa(const CHAR *format, va_list arglist) +{ + errno_t ret; + + if (g_recordSpace > g_excInfoIndex) { + ret = vsnprintf_s((g_excInfoBuf + g_excInfoIndex), (g_recordSpace - g_excInfoIndex), + (g_recordSpace - g_excInfoIndex - 1), format, arglist); + if (ret == -1) { + PRINT_ERR("exc info buffer is not enough or vsnprintf_s is error.\n"); + return; + } + g_excInfoIndex += ret; + } +} + +VOID WriteExcInfoToBuf(const CHAR *format, ...) +{ + va_list arglist; + + va_start(arglist, format); + WriteExcBufVa(format, arglist); + va_end(arglist); +} + +VOID LOS_ExcInfoRegHook(UINT32 startAddr, UINT32 space, CHAR *buf, log_read_write_fn hook) +{ + if ((hook == NULL) || (buf == NULL)) { + PRINT_ERR("Buf or hook is null.\n"); + return; + } + + g_recordAddr = startAddr; + g_recordSpace = space; + g_excInfoBuf = buf; + g_excInfoRW = hook; + +#ifdef LOSCFG_FS_VFS + los_vfs_init(); +#endif +} + +/* Be called in the exception. */ +VOID OsReadWriteExceptionInfo(UINT32 startAddr, UINT32 space, UINT32 flag, CHAR *buf) +{ + if ((buf == NULL) || (space == 0)) { + PRINT_ERR("buffer is null or space is zero\n"); + return; + } + // user can write exception information to files here +} + +VOID OsRecordExcInfoTime(VOID) +{ +#ifdef LOSCFG_FS_VFS +#define NOW_TIME_LENGTH 24 + time_t t; + struct tm *tmTime = NULL; + CHAR nowTime[NOW_TIME_LENGTH]; + + (VOID)time(&t); + tmTime = localtime(&t); + if (tmTime == NULL) { + return; + } + (VOID)memset_s(nowTime, sizeof(nowTime), 0, sizeof(nowTime)); + (VOID)strftime(nowTime, NOW_TIME_LENGTH, "%Y-%m-%d %H:%M:%S", tmTime); +#undef NOW_TIME_LENGTH + WriteExcInfoToBuf("%s \n", nowTime); +#endif +} + +#ifdef LOSCFG_SHELL +INT32 OsShellCmdReadExcInfo(INT32 argc, CHAR **argv) +{ +#define EXCINFO_ALIGN_SIZE 64 + UINT32 recordSpace = GetRecordSpace(); + + (VOID)argc; + (VOID)argv; + + CHAR *buf = (CHAR *)LOS_MemAllocAlign((VOID *)OS_SYS_MEM_ADDR, recordSpace + 1, EXCINFO_ALIGN_SIZE); + if (buf == NULL) { + return LOS_NOK; + } + (VOID)memset_s(buf, recordSpace + 1, 0, recordSpace + 1); + + log_read_write_fn hook = GetExcInfoRW(); + if (hook != NULL) { + hook(GetRecordAddr(), recordSpace, 1, buf); + } + PRINTK("%s\n", buf); + (VOID)LOS_MemFree((void *)OS_SYS_MEM_ADDR, buf); + buf = NULL; + return LOS_OK; +} + +SHELLCMD_ENTRY(readExcInfo_shellcmd, CMD_TYPE_EX, "excInfo", 0, (CmdCallBackFunc)OsShellCmdReadExcInfo); +#endif + +#endif + diff --git a/src/kernel_liteos_a/kernel/common/los_excinfo_pri.h b/src/kernel_liteos_a/kernel/common/los_excinfo_pri.h new file mode 100644 index 00000000..ba68d5f4 --- /dev/null +++ b/src/kernel_liteos_a/kernel/common/los_excinfo_pri.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_EXCINFO_PRI_H +#define _LOS_EXCINFO_PRI_H + +#include "los_config.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#ifdef LOSCFG_SAVE_EXCINFO +extern VOID SetExcInfoRW(log_read_write_fn func); +extern log_read_write_fn GetExcInfoRW(VOID); +extern VOID SetExcInfoBuf(CHAR *buf); +extern CHAR *GetExcInfoBuf(VOID); +extern VOID SetExcInfoIndex(UINT32 index); +extern UINT32 GetExcInfoIndex(VOID); +extern VOID SetRecordAddr(UINT32 addr); +extern UINT32 GetRecordAddr(VOID); +extern VOID SetRecordSpace(UINT32 space); +extern UINT32 GetRecordSpace(VOID); +extern VOID WriteExcBufVa(const CHAR *format, va_list arg); +extern VOID WriteExcInfoToBuf(const CHAR *format, ...); +extern VOID OsRecordExcInfoTime(VOID); +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_EXCINFO_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/common/los_init.c b/src/kernel_liteos_a/kernel/common/los_init.c new file mode 100644 index 00000000..3b9c4b41 --- /dev/null +++ b/src/kernel_liteos_a/kernel/common/los_init.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_init_pri.h" +#include "los_atomic.h" +#include "los_config.h" +#include "los_hw.h" +#include "los_printf.h" +#include "los_spinlock.h" +#include "los_typedef.h" + +#ifdef LOS_INIT_DEBUG +#include "los_sys_pri.h" +#include "los_tick.h" +#endif + +/** + * Register kernel init level labels. + */ +OS_INIT_LEVEL_REG(kernel, 10, g_kernInitLevelList); + +STATIC volatile UINT32 g_initCurrentLevel = OS_INVALID_VALUE; +STATIC volatile struct ModuleInitInfo *g_initCurrentModule = 0; +STATIC Atomic g_initCount = 0; +STATIC SPIN_LOCK_INIT(g_initLock); + +/** + * It is recommended that each startup framework encapsulate a layer of its own calling interface. + */ +STATIC VOID InitLevelCall(const CHAR *name, const UINT32 level, struct ModuleInitInfo *initLevelList[]) +{ + struct ModuleInitInfo *module = NULL; +#ifdef LOS_INIT_DEBUG + UINT64 startNsec, endNsec; + UINT64 totalTime = 0; + UINT64 singleTime; + UINT32 ret = LOS_OK; +#endif + + if (ArchCurrCpuid() == 0) { +#ifdef LOS_INIT_DEBUG + PRINTK("-------- %s Module Init... level = %u --------\n", name, level); +#endif + g_initCurrentLevel = level; + g_initCurrentModule = initLevelList[level]; + } else { + while (g_initCurrentLevel < level) { + } + } + + do { + LOS_SpinLock(&g_initLock); + if (g_initCurrentModule >= initLevelList[level + 1]) { + LOS_SpinUnlock(&g_initLock); + break; + } + module = (struct ModuleInitInfo *)g_initCurrentModule; + g_initCurrentModule++; + LOS_SpinUnlock(&g_initLock); + if (module->hook != NULL) { +#ifdef LOS_INIT_DEBUG + startNsec = LOS_CurrNanosec(); + ret = (UINT32)module->hook(); + endNsec = LOS_CurrNanosec(); + singleTime = endNsec - startNsec; + totalTime += singleTime; + PRINTK("Starting %s module consumes %llu ns. Run on cpu %u\n", module->name, singleTime, ArchCurrCpuid()); +#else + module->hook(); +#endif + } +#ifdef LOS_INIT_DEBUG + if (ret != LOS_OK) { + PRINT_ERR("%s initialization failed at module %s, function addr at 0x%x, ret code is %u\n", + name, module->name, module->hook, ret); + } +#endif + } while (1); + + if (level >= LOS_INIT_LEVEL_KMOD_TASK) { + LOS_AtomicInc(&g_initCount); + while ((LOS_AtomicRead(&g_initCount) % LOSCFG_KERNEL_CORE_NUM) != 0) { + } + } + +#ifdef LOS_INIT_DEBUG + PRINTK("%s initialization at level %u consumes %lluns on cpu %u.\n", name, level, totalTime, ArchCurrCpuid()); +#endif +} + +VOID OsInitCall(const UINT32 level) +{ + if (level >= LOS_INIT_LEVEL_FINISH) { + return; + } + + InitLevelCall("Kernel", level, g_kernInitLevelList); +} diff --git a/src/kernel_liteos_a/kernel/common/los_init_info.h b/src/kernel_liteos_a/kernel/common/los_init_info.h new file mode 100644 index 00000000..dcf493e3 --- /dev/null +++ b/src/kernel_liteos_a/kernel/common/los_init_info.h @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_INIT_INFO_H +#define _LOS_INIT_INFO_H + +#include "stdalign.h" +#include "los_toolchain.h" +#include "los_typedef.h" + +/** + * @ingroup los_init_info + * Macro LOS_INIT_DEBUG needs to be defined here, used to debug the init framework. + * #define LOS_INIT_DEBUG + */ + +/** + * @ingroup los_init_info + * Macro LOS_INIT_STATISTICS needs to be defined here, used to count the kernel startup time. + * @attention + *
            + *
          • if uses, the macro LOS_INIT_DEBUG must be undefined.
          • + *
          + * #define LOS_INIT_STATISTICS + */ + +#if defined(LOS_INIT_STATISTICS) && defined(LOS_INIT_DEBUG) +#error "LOS_INIT_STATISTICS needs LOS_INIT_DEBUG to be undefined" +#endif + +#define INIT_SECTION(_type, _level, _hook) __attribute__((section(".rodata.init."#_type"."#_level"."#_hook))) +#define INIT_ALIGN __attribute__((aligned(alignof(struct ModuleInitInfo)))) + +typedef UINT32 (*OsInitHook)(VOID); + +struct ModuleInitInfo { + OsInitHook hook; +#ifdef LOS_INIT_DEBUG + const CHAR *name; +#endif +}; + +#ifdef LOS_INIT_DEBUG +#define SET_MODULE_NAME(_hook) .name = #_hook, +#else +#define SET_MODULE_NAME(_hook) +#endif + +/** +* @ingroup los_init_info +* @brief Add a registration module to the specified level in a startup framework. +* +* @par Description: +* This API is used to add a registration module to the specified level in a startup framework. +* @attention + *
            + *
          • It is not recommended to call directly, it is recommended that each startup framework + * encapsulate a layer of interface in los_init.h.
          • + *
          +* +* @param _type [IN] Type name of startup framework. +* @param _hook [IN] Register function. +* @param _level [IN] At which _level do you want to register. +* +* @retval None +* @par Dependency: +*
          • los_task_info.h: the header file that contains the API declaration.
          +* @see +*/ +#define OS_INIT_HOOK_REG(_type, _hook, _level) \ + STATIC const struct ModuleInitInfo ModuleInitInfo_##_hook \ + USED INIT_SECTION(_type, _level, _hook) INIT_ALIGN = { \ + .hook = (UINT32 (*)(VOID))&_hook, \ + SET_MODULE_NAME(_hook) \ + }; + +#define EXTERN_LABEL(_type, _level) extern struct ModuleInitInfo __##_type##_init_level_##_level; +#define GET_LABEL(_type, _level) &__##_type##_init_level_##_level, + +#define INIT_LABEL_REG_0(_op, _type) \ + _op(_type, 0) +#define INIT_LABEL_REG_1(_op, _type) \ + INIT_LABEL_REG_0(_op, _type) \ + _op(_type, 1) +#define INIT_LABEL_REG_2(_op, _type) \ + INIT_LABEL_REG_1(_op, _type) \ + _op(_type, 2) +#define INIT_LABEL_REG_3(_op, _type) \ + INIT_LABEL_REG_2(_op, _type) \ + _op(_type, 3) +#define INIT_LABEL_REG_4(_op, _type) \ + INIT_LABEL_REG_3(_op, _type) \ + _op(_type, 4) +#define INIT_LABEL_REG_5(_op, _type) \ + INIT_LABEL_REG_4(_op, _type) \ + _op(_type, 5) +#define INIT_LABEL_REG_6(_op, _type) \ + INIT_LABEL_REG_5(_op, _type) \ + _op(_type, 6) +#define INIT_LABEL_REG_7(_op, _type) \ + INIT_LABEL_REG_6(_op, _type) \ + _op(_type, 7) +#define INIT_LABEL_REG_8(_op, _type) \ + INIT_LABEL_REG_7(_op, _type) \ + _op(_type, 8) +#define INIT_LABEL_REG_9(_op, _type) \ + INIT_LABEL_REG_8(_op, _type) \ + _op(_type, 9) +#define INIT_LABEL_REG_10(_op, _type) \ + INIT_LABEL_REG_9(_op, _type) \ + _op(_type, 10) + +/** +* @ingroup los_init_info +* @brief Define a set of levels and initialize the labels of each level. +* +* @par Description: +* This API is used to define a set of levels and initialize the labels of each level. +* @attention + *
            + *
          • This interface is used to add a new startup framework.
          • + *
          • To use this interface, you need to add a corresponding section description in + * the liteos.ld and liteos_llvm.ld files to match
          • + *
          +* +* @param _type [IN] Type name of startup framework. +* @param _num [IN] The maximum effective level of the startup framework, the level range is [0, _num]. +* @param _list [IN] Static global array, used to manage labels at all levels. +* +* @retval None +* @par Dependency: +*
          • los_task_info.h: the header file that contains the API declaration.
          +* @see +*/ +#define OS_INIT_LEVEL_REG(_type, _num, _list) \ + INIT_LABEL_REG_##_num(EXTERN_LABEL, _type) \ + STATIC struct ModuleInitInfo *_list[] = { \ + INIT_LABEL_REG_##_num(GET_LABEL, _type) \ + } + +#endif /* _LOS_INIT_INFO_H */ diff --git a/src/kernel_liteos_a/kernel/common/los_init_pri.h b/src/kernel_liteos_a/kernel/common/los_init_pri.h new file mode 100644 index 00000000..9258c631 --- /dev/null +++ b/src/kernel_liteos_a/kernel/common/los_init_pri.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_INIT_PRI_H +#define _LOS_INIT_PRI_H + +#include "los_init.h" +#include "los_typedef.h" + +VOID OsInitCall(const UINT32 level); + +#endif /* _LOS_INIT_PRI_H */ \ No newline at end of file diff --git a/src/kernel_liteos_a/kernel/common/los_magickey.c b/src/kernel_liteos_a/kernel/common/los_magickey.c new file mode 100644 index 00000000..af2f79e0 --- /dev/null +++ b/src/kernel_liteos_a/kernel/common/los_magickey.c @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_magickey.h" +#include "console.h" +#include "los_task_pri.h" +#include "los_process_pri.h" + +#ifdef LOSCFG_ENABLE_MAGICKEY + +#define MAGIC_KEY_NUM 5 +STATIC VOID OsMagicHelp(VOID); +STATIC VOID OsMagicTaskShow(VOID); +STATIC VOID OsMagicPanic(VOID); +STATIC VOID OsMagicMemCheck(VOID); + +STATIC MagicKeyOp g_magicMemCheckOp = { + .opHandler = OsMagicMemCheck, + .helpMsg = "Check system memory(ctrl+e) ", + .magicKey = 0x05 /* ctrl + e */ +}; + +STATIC MagicKeyOp g_magicPanicOp = { + .opHandler = OsMagicPanic, + .helpMsg = "System panic(ctrl+p) ", + .magicKey = 0x10 /* ctrl + p */ +}; + +STATIC MagicKeyOp g_magicTaskShowOp = { + .opHandler = OsMagicTaskShow, + .helpMsg = "Show task information(ctrl+t) ", + .magicKey = 0x14 /* ctrl + t */ +}; + +STATIC MagicKeyOp g_magicHelpOp = { + .opHandler = OsMagicHelp, + .helpMsg = "Show all magic op key(ctrl+z) ", + .magicKey = 0x1a /* ctrl + z */ +}; + +/* + * NOTICE:Suggest don't use + * ctrl+h/backspace=0x8, + * ctrl+i/tab=0x9, + * ctrl+m/enter=0xd, + * ctrl+n/shift out=0xe, + * ctrl+o/shift in=0xf, + * ctrl+[/esc=0x1b, + * ctrl+] used for telnet command mode; + */ +STATIC MagicKeyOp *g_magicOpTable[MAGIC_KEY_NUM] = { + &g_magicMemCheckOp, /* ctrl + e */ + &g_magicPanicOp, /* ctrl + p */ + &g_magicTaskShowOp, /* ctrl + t */ + &g_magicHelpOp, /* ctrl + z */ + NULL +}; + +STATIC VOID OsMagicHelp(VOID) +{ + INT32 i; + PRINTK("HELP: "); + for (i = 0; g_magicOpTable[i] != NULL; ++i) { + PRINTK("%s ", g_magicOpTable[i]->helpMsg); + } + PRINTK("\n"); + return; +} + +STATIC VOID OsMagicTaskShow(VOID) +{ + (VOID)OsShellCmdTskInfoGet(OS_ALL_TASK_MASK, NULL, OS_PROCESS_INFO_ALL); + return; +} + +STATIC VOID OsMagicPanic(VOID) +{ + LOS_Panic("Magic key :\n"); + return; +} + +STATIC VOID OsMagicMemCheck(VOID) +{ + if (LOS_MemIntegrityCheck(m_aucSysMem1) == LOS_OK) { + PrintExcInfo("system memcheck over, all passed!\n"); + } + return; +} +#endif + +INT32 CheckMagicKey(CHAR key, UINT16 consoleId) +{ +#ifdef LOSCFG_ENABLE_MAGICKEY + INT32 i; + STATIC UINT32 magicKeySwitch = 0; + + if (key == 0x03) { /* ctrl + c */ + KillPgrp(consoleId); + return 0; + } else if (key == 0x12) { /* ctrl + r */ + magicKeySwitch = ~magicKeySwitch; + if (magicKeySwitch != 0) { + PrintExcInfo("Magic key on\n"); + } else { + PrintExcInfo("Magic key off\n"); + } + return 1; + } + if (magicKeySwitch != 0) { + for (i = 0; i < MAGIC_KEY_NUM; i++) { + if (g_magicOpTable[i] != NULL && key == g_magicOpTable[i]->magicKey) { + (g_magicOpTable[i])->opHandler(); + return 1; + } + } + } +#endif + return 0; +} diff --git a/src/kernel_liteos_a/kernel/common/los_magickey.h b/src/kernel_liteos_a/kernel/common/los_magickey.h new file mode 100644 index 00000000..f04b7a7c --- /dev/null +++ b/src/kernel_liteos_a/kernel/common/los_magickey.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_MAGICKEY_H +#define _LOS_MAGICKEY_H + +#include "los_exc.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef struct { + VOID (*opHandler)(VOID); + CHAR *helpMsg; + CHAR magicKey; +} MagicKeyOp; + +extern INT32 CheckMagicKey(CHAR key, UINT16 consoleId); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif \ No newline at end of file diff --git a/src/kernel_liteos_a/kernel/common/los_printf.c b/src/kernel_liteos_a/kernel/common/los_printf.c new file mode 100644 index 00000000..e0126544 --- /dev/null +++ b/src/kernel_liteos_a/kernel/common/los_printf.c @@ -0,0 +1,299 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_base.h" +#ifdef LOSCFG_LIB_LIBC +#include "stdlib.h" +#include "unistd.h" +#endif +#include "los_hwi.h" +#include "los_memory_pri.h" +#include "los_process_pri.h" +#ifdef LOSCFG_FS_VFS +#include "console.h" +#endif +#ifdef LOSCFG_SHELL_DMESG +#include "dmesg_pri.h" +#endif +#ifdef LOSCFG_SAVE_EXCINFO +#include "los_excinfo_pri.h" +#endif +#include "los_exc_pri.h" +#include "los_sched_pri.h" + +#define SIZEBUF 256 + +const CHAR *g_logString[] = { + "EMG", + "COMMON", + "ERR", + "WARN", + "INFO", + "DEBUG", + "TRACE" +}; + +const CHAR *OsLogLvGet(INT32 level) +{ + return g_logString[level]; +} + +STATIC VOID ErrorMsg(VOID) +{ + const CHAR *p = "Output illegal string! vsnprintf_s failed!\n"; + UartPuts(p, (UINT32)strlen(p), UART_WITH_LOCK); +} + +STATIC VOID UartOutput(const CHAR *str, UINT32 len, BOOL isLock) +{ +#ifdef LOSCFG_SHELL_DMESG + if (!OsCheckUartLock()) { + UartPuts(str, len, isLock); + } + if (isLock != UART_WITHOUT_LOCK) { + (VOID)OsLogMemcpyRecord(str, len); + } +#else + UartPuts(str, len, isLock); +#endif +} + +#ifdef LOSCFG_PLATFORM_CONSOLE +STATIC VOID ConsoleOutput(const CHAR *str, UINT32 len) +{ + ssize_t written = 0; + ssize_t cnt; + ssize_t toWrite = len; + + for (;;) { + cnt = write(STDOUT_FILENO, str + written, (size_t)toWrite); + if ((cnt < 0) || ((cnt == 0) && ((!OsPreemptable()) || (OS_INT_ACTIVE))) || (toWrite == cnt)) { + break; + } + written += cnt; + toWrite -= cnt; + } +} +#endif + +VOID OutputControl(const CHAR *str, UINT32 len, OutputType type) +{ + switch (type) { + case CONSOLE_OUTPUT: +#ifdef LOSCFG_PLATFORM_CONSOLE + if (ConsoleEnable() == TRUE) { + ConsoleOutput(str, len); + break; + } +#endif + /* fall-through */ + case UART_OUTPUT: + UartOutput(str, len, UART_WITH_LOCK); + break; + case EXC_OUTPUT: + UartPuts(str, len, UART_WITH_LOCK); + break; + default: + break; + } + return; +} + +STATIC VOID OsVprintfFree(CHAR *buf, UINT32 bufLen) +{ + if (bufLen != SIZEBUF) { + (VOID)LOS_MemFree(m_aucSysMem0, buf); + } +} + +VOID OsVprintf(const CHAR *fmt, va_list ap, OutputType type) +{ + INT32 len; + const CHAR *errMsgMalloc = "OsVprintf, malloc failed!\n"; + const CHAR *errMsgLen = "OsVprintf, length overflow!\n"; + CHAR aBuf[SIZEBUF] = {0}; + CHAR *bBuf = NULL; + UINT32 bufLen = SIZEBUF; + UINT32 systemStatus; + + bBuf = aBuf; + len = vsnprintf_s(bBuf, bufLen, bufLen - 1, fmt, ap); + if ((len == -1) && (*bBuf == '\0')) { + /* parameter is illegal or some features in fmt dont support */ + ErrorMsg(); + return; + } + + while (len == -1) { + /* bBuf is not enough */ + OsVprintfFree(bBuf, bufLen); + + bufLen = bufLen << 1; + if ((INT32)bufLen <= 0) { + UartPuts(errMsgLen, (UINT32)strlen(errMsgLen), UART_WITH_LOCK); + return; + } + bBuf = (CHAR *)LOS_MemAlloc(m_aucSysMem0, bufLen); + if (bBuf == NULL) { + UartPuts(errMsgMalloc, (UINT32)strlen(errMsgMalloc), UART_WITH_LOCK); + return; + } + len = vsnprintf_s(bBuf, bufLen, bufLen - 1, fmt, ap); + if (*bBuf == '\0') { + /* parameter is illegal or some features in fmt dont support */ + (VOID)LOS_MemFree(m_aucSysMem0, bBuf); + ErrorMsg(); + return; + } + } + *(bBuf + len) = '\0'; + + systemStatus = OsGetSystemStatus(); + if ((systemStatus == OS_SYSTEM_NORMAL) || (systemStatus == OS_SYSTEM_EXC_OTHER_CPU)) { + OutputControl(bBuf, len, type); + } else if (systemStatus == OS_SYSTEM_EXC_CURR_CPU) { + OutputControl(bBuf, len, EXC_OUTPUT); + } + OsVprintfFree(bBuf, bufLen); +} + +VOID UartVprintf(const CHAR *fmt, va_list ap) +{ + OsVprintf(fmt, ap, UART_OUTPUT); +} + +__attribute__((noinline)) VOID UartPrintf(const CHAR *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + OsVprintf(fmt, ap, UART_OUTPUT); + va_end(ap); +} + +#ifndef LOSCFG_LIBC_NEWLIB +__attribute__((noinline)) VOID dprintf(const CHAR *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + OsVprintf(fmt, ap, CONSOLE_OUTPUT); +#ifdef LOSCFG_SAVE_EXCINFO + if (OsGetSystemStatus() == OS_SYSTEM_EXC_CURR_CPU) { + WriteExcBufVa(fmt, ap); + } +#endif + va_end(ap); +} +#endif + +VOID LkDprintf(const CHAR *fmt, va_list ap) +{ + OsVprintf(fmt, ap, CONSOLE_OUTPUT); +#ifdef LOSCFG_SAVE_EXCINFO + if (OsGetSystemStatus() == OS_SYSTEM_EXC_CURR_CPU) { + WriteExcBufVa(fmt, ap); + } +#endif +} + +#ifdef LOSCFG_SHELL_DMESG +VOID DmesgPrintf(const CHAR *fmt, va_list ap) +{ + OsVprintf(fmt, ap, CONSOLE_OUTPUT); +} +#endif + +#ifdef LOSCFG_PLATFORM_UART_WITHOUT_VFS +__attribute__((noinline)) INT32 printf(const CHAR *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + OsVprintf(fmt, ap, UART_OUTPUT); + va_end(ap); + return 0; +} +#endif + +__attribute__((noinline)) VOID syslog(INT32 level, const CHAR *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + OsVprintf(fmt, ap, CONSOLE_OUTPUT); + va_end(ap); + (VOID)level; +} + +__attribute__((noinline)) VOID ExcPrintf(const CHAR *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + /* uart output without print-spinlock */ + OsVprintf(fmt, ap, EXC_OUTPUT); + va_end(ap); +} + +VOID PrintExcInfo(const CHAR *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + /* uart output without print-spinlock */ + OsVprintf(fmt, ap, EXC_OUTPUT); +#ifdef LOSCFG_SAVE_EXCINFO + WriteExcBufVa(fmt, ap); +#endif + va_end(ap); +} + +#ifndef LOSCFG_SHELL_LK +VOID LOS_LkPrint(INT32 level, const CHAR *func, INT32 line, const CHAR *fmt, ...) +{ + va_list ap; + + if (level > PRINT_LEVEL) { + return; + } + + if ((level != LOS_COMMON_LEVEL) && ((level > LOS_EMG_LEVEL) && (level <= LOS_TRACE_LEVEL))) { + PRINTK("[%s][%s:%s]", g_logString[level], + ((OsCurrProcessGet() == NULL) ? "NULL" : OsCurrProcessGet()->processName), + ((OsCurrTaskGet() == NULL) ? "NULL" : OsCurrTaskGet()->taskName)); + } + + va_start(ap, fmt); + OsVprintf(fmt, ap, CONSOLE_OUTPUT); +#ifdef LOSCFG_SAVE_EXCINFO + if (OsGetSystemStatus() == OS_SYSTEM_EXC_CURR_CPU) { + WriteExcBufVa(fmt, ap); + } +#endif + va_end(ap); +} +#endif + diff --git a/src/kernel_liteos_a/kernel/common/main.c b/src/kernel_liteos_a/kernel/common/main.c new file mode 100644 index 00000000..66f9e986 --- /dev/null +++ b/src/kernel_liteos_a/kernel/common/main.c @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_config.h" +#include "los_sched_pri.h" + +LITE_OS_SEC_TEXT_INIT INT32 main(VOID) +{ + UINT32 ret = OsMain(); + if (ret != LOS_OK) { + return (INT32)LOS_NOK; + } + CPU_MAP_SET(0, OsHwIDGet()); + + OsSchedStart(); + + while (1) { + __asm volatile("wfi"); + } +} diff --git a/src/kernel_liteos_a/kernel/common/virtual_serial.c b/src/kernel_liteos_a/kernel/common/virtual_serial.c new file mode 100644 index 00000000..995d15a1 --- /dev/null +++ b/src/kernel_liteos_a/kernel/common/virtual_serial.c @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "virtual_serial.h" +#include "fcntl.h" +#ifdef LOSCFG_FILE_MODE +#include "stdarg.h" +#endif +#ifdef LOSCFG_FS_VFS +#include "console.h" +#include "fs/driver.h" +#endif + +STATIC volatile UINT32 g_serialType = 0; +STATIC struct file g_serialFilep; + + +UINT32 SerialTypeGet(VOID) +{ + return g_serialType; +} + +STATIC VOID SerialTypeSet(const CHAR *deviceName) +{ + if (!strncmp(deviceName, SERIAL_UARTDEV, strlen(SERIAL_UARTDEV))) { + g_serialType = SERIAL_TYPE_UART_DEV; + } else if (!strncmp(deviceName, SERIAL_TTYGS0, strlen(SERIAL_TTYGS0))) { + g_serialType = SERIAL_TYPE_USBTTY_DEV; + } +} + +STATIC INT32 SerialOpen(struct file *filep) +{ + INT32 ret; + struct file *privFilep = NULL; + const struct file_operations_vfs *fileOps = NULL; + + ret = GetFilepOps(filep, &privFilep, &fileOps); + if (ret != ENOERR) { + ret = EINVAL; + goto ERROUT; + } + + ret = FilepOpen(privFilep, fileOps); + if (ret < 0) { + ret = EPERM; + goto ERROUT; + } + + if (g_serialType == SERIAL_TYPE_UART_DEV) { + HalIrqUnmask(NUM_HAL_INTERRUPT_UART); + } + return ENOERR; + +ERROUT: + set_errno(ret); + return VFS_ERROR; +} + +STATIC INT32 SerialClose(struct file *filep) +{ + (VOID)filep; + + if (g_serialType == SERIAL_TYPE_UART_DEV) { + HalIrqMask(NUM_HAL_INTERRUPT_UART); + } +#if defined(LOSCFG_DRIVERS_USB_SERIAL_GADGET) || defined(LOSCFG_DRIVERS_USB_ETH_SER_GADGET) + else if (g_serialType == SERIAL_TYPE_USBTTY_DEV) { + userial_mask_set(0); + } +#endif + + return ENOERR; +} + +STATIC ssize_t SerialRead(struct file *filep, CHAR *buffer, size_t bufLen) +{ + INT32 ret; + struct file *privFilep = NULL; + const struct file_operations_vfs *fileOps = NULL; + + ret = GetFilepOps(filep, &privFilep, &fileOps); + if (ret != ENOERR) { + ret = -EINVAL; + goto ERROUT; + } + + ret = FilepRead(privFilep, fileOps, buffer, bufLen); + if (ret < 0) { + goto ERROUT; + } + return ret; + +ERROUT: + set_errno(-ret); + return VFS_ERROR; +} + +/* Note: do not add print function in this module! */ +STATIC ssize_t SerialWrite(struct file *filep, const CHAR *buffer, size_t bufLen) +{ + INT32 ret; + struct file *privFilep = NULL; + const struct file_operations_vfs *fileOps = NULL; + + ret = GetFilepOps(filep, &privFilep, &fileOps); + if (ret != ENOERR) { + ret = -EINVAL; + goto ERROUT; + } + + ret = FilepWrite(privFilep, fileOps, buffer, bufLen); + if (ret < 0) { + goto ERROUT; + } + return ret; + +ERROUT: + set_errno(-ret); + return VFS_ERROR; +} + +STATIC INT32 SerialIoctl(struct file *filep, INT32 cmd, unsigned long arg) +{ + INT32 ret; + struct file *privFilep = NULL; + const struct file_operations_vfs *fileOps = NULL; + + ret = GetFilepOps(filep, &privFilep, &fileOps); + if (ret != ENOERR) { + ret = -EINVAL; + goto ERROUT; + } + + ret = FilepIoctl(privFilep, fileOps, cmd, arg); + if (ret < 0) { + goto ERROUT; + } + return ret; + +ERROUT: + set_errno(-ret); + return VFS_ERROR; +} + +STATIC INT32 SerialPoll(struct file *filep, poll_table *fds) +{ + INT32 ret; + struct file *privFilep = NULL; + const struct file_operations_vfs *fileOps = NULL; + + ret = GetFilepOps(filep, &privFilep, &fileOps); + if (ret != ENOERR) { + ret = -EINVAL; + goto ERROUT; + } + ret = FilepPoll(privFilep, fileOps, fds); + if (ret < 0) { + goto ERROUT; + } + return ret; + +ERROUT: + set_errno(-ret); + return VFS_ERROR; +} + +STATIC const struct file_operations_vfs g_serialDevOps = { + SerialOpen, /* open */ + SerialClose, /* close */ + SerialRead, /* read */ + SerialWrite, + NULL, + SerialIoctl, + NULL, +#ifndef CONFIG_DISABLE_POLL + SerialPoll, +#endif + NULL, +}; + +INT32 virtual_serial_init(const CHAR *deviceName) +{ + INT32 ret; + struct Vnode *vnode = NULL; + + if (deviceName == NULL) { + ret = EINVAL; + goto ERROUT; + } + + SerialTypeSet(deviceName); + + VnodeHold(); + ret = VnodeLookup(deviceName, &vnode, V_DUMMY); + if (ret != LOS_OK) { + ret = EACCES; + goto ERROUT; + } + + (VOID)memset_s(&g_serialFilep, sizeof(struct file), 0, sizeof(struct file)); + g_serialFilep.f_oflags = O_RDWR; + g_serialFilep.f_vnode = vnode; + g_serialFilep.ops = ((struct drv_data *)vnode->data)->ops; + + if (g_serialFilep.ops->open != NULL) { + (VOID)g_serialFilep.ops->open(&g_serialFilep); + } else { + ret = EFAULT; + PRINTK("virtual_serial_init %s open is NULL\n", deviceName); + goto ERROUT; + } + (VOID)register_driver(SERIAL, &g_serialDevOps, DEFFILEMODE, &g_serialFilep); + + VnodeDrop(); + return ENOERR; + +ERROUT: + VnodeDrop(); + set_errno(ret); + return VFS_ERROR; +} + +INT32 virtual_serial_deinit(VOID) +{ + return unregister_driver(SERIAL); +} + diff --git a/src/kernel_liteos_a/kernel/common/virtual_serial.h b/src/kernel_liteos_a/kernel/common/virtual_serial.h new file mode 100644 index 00000000..b0ae6e46 --- /dev/null +++ b/src/kernel_liteos_a/kernel/common/virtual_serial.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _VIRTUAL_SERIAL_H +#define _VIRTUAL_SERIAL_H + +#include "los_config.h" +#include "fs/file.h" +#if defined(LOSCFG_DRIVERS_USB_SERIAL_GADGET) || defined(LOSCFG_DRIVERS_USB_ETH_SER_GADGET) +#include "implementation/usb_api_pri.h" +#endif + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#ifdef LOSCFG_FS_VFS +#define SERIAL "/dev/serial" +#define SERIAL_TTYGS0 "/dev/ttyGS0" +#define SERIAL_UARTDEV "/dev/uartdev" + +#define SERIAL_TYPE_UART_DEV 1 +#define SERIAL_TYPE_USBTTY_DEV 2 + +extern INT32 virtual_serial_init(const CHAR *deviceName); +extern INT32 virtual_serial_deinit(VOID); + +extern UINT32 SerialTypeGet(VOID); + +typedef struct { + struct file *filep; + UINT32 mask; +} LOS_VIRSERIAL_CB; + +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _VIRTUAL_SERIAL_H */ diff --git a/src/kernel_liteos_a/kernel/extended/BUILD.gn b/src/kernel_liteos_a/kernel/extended/BUILD.gn new file mode 100644 index 00000000..0a322355 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/BUILD.gn @@ -0,0 +1,70 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +group("extended") { + deps = [ + "blackbox", + "container", + "cppsupport", + "cpup", + "dynload", + "hidumper", + "hilog", + "hook", + "liteipc", + "lms", + "perf", + "pipes", + "plimit", + "power", + "trace", + "vdso", + ] +} + +config("public") { + configs = [ + "blackbox:public", + "container:public", + "cpup:public", + "dynload:public", + "hidumper:public", + "hilog:public", + "hook:public", + "liteipc:public", + "pipes:public", + "vdso:public", + "perf:public", + "lms:public", + "power:public", + "plimit:public", + ] +} diff --git a/src/kernel_liteos_a/kernel/extended/Kconfig b/src/kernel_liteos_a/kernel/extended/Kconfig new file mode 100644 index 00000000..d7d133ec --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/Kconfig @@ -0,0 +1,180 @@ +config KERNEL_EXTKERNEL + bool "Enable Extend Kernel" + default y + help + This option will enable extend Kernel of LiteOS. Extend kernel include + cppsupport, cpup, and dynload. You can select one or some + of them. + +config KERNEL_CPPSUPPORT + bool "Enable C++ Support" + default y + depends on KERNEL_EXTKERNEL + help + If you wish to build LiteOS with support for C++. + +config KERNEL_CPUP + bool "Enable Cpup" + default y + depends on KERNEL_EXTKERNEL + help + If you wish to build LiteOS with support for cpup. + +config CPUP_INCLUDE_IRQ + bool "Enable Cpup include irq" + default y + depends on KERNEL_CPUP + help + If you wish to include irq usage for cpup. + +config KERNEL_DYNLOAD + bool "Enable Dynamic Load Feature" + default y + depends on KERNEL_EXTKERNEL && KERNEL_VM && KERNEL_SYSCALL + help + If you wish to build LiteOS with support for dynamic load. + +config ASLR + bool "Enable Address Space Layout Randomization" + default n + depends on KERNEL_DYNLOAD && HW_RANDOM_ENABLE + help + If you wish to enable ASLR for user aspace. + +config KERNEL_PM + bool "Enable Power Management" + default y + depends on KERNEL_EXTKERNEL + help + If you wish to build LiteOS with support for power management. + +config KERNEL_VDSO + bool "Enable VDSO Feature" + default n + depends on KERNEL_EXTKERNEL && KERNEL_VM && KERNEL_SYSCALL + help + If you wish to speed up some system calls. + +config KERNEL_SHM + bool "Enable Shared Memory" + default y + depends on KERNEL_EXTKERNEL && KERNEL_VM && KERNEL_SYSCALL + help + Answer Y to enable LiteOS support shared memory. + +config KERNEL_LITEIPC + bool "Enable liteipc" + default y + depends on KERNEL_EXTKERNEL && KERNEL_VM + help + Answer Y to enable LiteOS support liteipc. + +config KERNEL_PIPE + bool "Enable pipes" + default y + depends on KERNEL_EXTKERNEL + help + Answer Y to enable LiteOS support pipes. + +config KERNEL_PLIMITS + bool "Enable plimits Feature" + default n + depends on KERNEL_EXTKERNEL + +config KERNEL_MEM_PLIMIT + bool "Enable mem limits Feature" + default n + depends on KERNEL_PLIMITS + +config KERNEL_IPC_PLIMIT + bool "Enable ipc limits Feature" + default n + depends on KERNEL_PLIMITS + +config KERNEL_DEV_PLIMIT + bool "Enable dev limits Feature" + default n + depends on KERNEL_PLIMITS + +config KERNEL_SCHED_PLIMIT + bool "Enable sched limits Feature" + default n + depends on KERNEL_PLIMITS + +config BASE_CORE_HILOG + bool "Enable Hilog" + default y + depends on KERNEL_EXTKERNEL + help + If you wish to include hilog. + +config KERNEL_HOOK + bool "Enable Hook Feature" + default n + depends on KERNEL_EXTKERNEL && DEBUG_VERSION + + +######################### config options of container #################### +config KERNEL_CONTAINER + bool "Enable container Feature" + default n + depends on KERNEL_VM + +config PID_CONTAINER + bool "Enable pid container Feature" + default n + depends on KERNEL_CONTAINER + +config UTS_CONTAINER + bool "Enable uts container Feature" + default n + depends on KERNEL_CONTAINER + +config MNT_CONTAINER + bool "Enable mnt container Feature" + default n + depends on KERNEL_CONTAINER + +config CHROOT + bool "Enable chroot" + default n + depends on MNT_CONTAINER + +config IPC_CONTAINER + bool "Enable ipc container Feature" + default n + depends on KERNEL_CONTAINER + +config TIME_CONTAINER + bool "Enable time container" + default n + depends on KERNEL_CONTAINER + +config USER_CONTAINER + bool "Enable user container" + default n + depends on KERNEL_CONTAINER + +config NET_CONTAINER + bool "Enable net container" + default n + depends on KERNEL_CONTAINER + + +######################### config options of trace ######################### +source "kernel/extended/trace/Kconfig" + +######################### config options of blackbox ######################### +source "kernel/extended/blackbox/Kconfig" + +######################### config options of hidumper ######################### +source "kernel/extended/hidumper/Kconfig" + +######################### config options of perf ######################### +source "kernel/extended/perf/Kconfig" + +######################### config options of lms ######################### +source "kernel/extended/lms/Kconfig" + +######################### config options of hilog ######################### +source "kernel/extended/hilog/Kconfig" diff --git a/src/kernel_liteos_a/kernel/extended/blackbox/BUILD.gn b/src/kernel_liteos_a/kernel/extended/blackbox/BUILD.gn new file mode 100644 index 00000000..b1327cf3 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/blackbox/BUILD.gn @@ -0,0 +1,47 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = defined(LOSCFG_BLACKBOX) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ + "los_blackbox_common.c", + "los_blackbox_core.c", + "los_blackbox_detector.c", + "los_blackbox_system_adapter.c", + ] + include_dirs = [ "$LITEOSTOPDIR/syscall" ] + public_configs = [ ":public" ] +} + +config("public") { + include_dirs = [ "." ] +} diff --git a/src/kernel_liteos_a/kernel/extended/blackbox/Kconfig b/src/kernel_liteos_a/kernel/extended/blackbox/Kconfig new file mode 100644 index 00000000..0a06a656 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/blackbox/Kconfig @@ -0,0 +1,35 @@ +config BLACKBOX + bool "Enable BlackBox" + default n + depends on KERNEL_EXTKERNEL + help + Answer Y to enable LiteOS support blackbox + +config BLACKBOX_LOG_PART_MOUNT_POINT + string "unknown" + default "/storage" + depends on BLACKBOX + help + Define the default log part representative of blackbox + +config BLACKBOX_LOG_ROOT_PATH + string "unknown" + default "/storage/data/log" + depends on BLACKBOX + help + Define the default log path of blackbox + +config BLACKBOX_RESERVE_MEM_ADDR + int "The address of the reserve mem for blackbox in hex" + default 0 + depends on BLACKBOX + help + Define the address of the reserve mem for blackbox in hex. + +config BLACKBOX_LOG_SIZE + int "The size of log saved by blackbox in hex" + range 1024 1048576 + default 65536 + depends on BLACKBOX + help + Define the size of log saved by blackbox in decimal. diff --git a/src/kernel_liteos_a/kernel/extended/blackbox/Makefile b/src/kernel_liteos_a/kernel/extended/blackbox/Makefile new file mode 100644 index 00000000..cc7a3cc4 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/blackbox/Makefile @@ -0,0 +1,11 @@ +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := $(wildcard *.c) + +LOCAL_INCLUDE := -I $(LITEOSTOPDIR)/syscall + +LOCAL_FLAGS := $(LOCAL_INCLUDE) + +include $(MODULE) diff --git a/src/kernel_liteos_a/kernel/extended/blackbox/los_blackbox.h b/src/kernel_liteos_a/kernel/extended/blackbox/los_blackbox.h new file mode 100644 index 00000000..5afd3e7d --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/blackbox/los_blackbox.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LOS_BLACKBOX_H +#define LOS_BLACKBOX_H + +#include "stdarg.h" +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define PATH_MAX_LEN 256 +#define EVENT_MAX_LEN 32 +#define MODULE_MAX_LEN 32 +#define ERROR_DESC_MAX_LEN 512 +#define KERNEL_FAULT_LOG_PATH LOSCFG_BLACKBOX_LOG_ROOT_PATH "/kernel_fault.log" +#define USER_FAULT_LOG_PATH LOSCFG_BLACKBOX_LOG_ROOT_PATH "/user_fault.log" + +#define MODULE_SYSTEM "SYSTEM" +#define EVENT_SYSREBOOT "SYSREBOOT" +#define EVENT_LONGPRESS "LONGPRESS" +#define EVENT_COMBINATIONKEY "COMBINATIONKEY" +#define EVENT_SUBSYSREBOOT "SUBSYSREBOOT" +#define EVENT_POWEROFF "POWEROFF" +#define EVENT_PANIC "PANIC" +#define EVENT_SYS_WATCHDOG "SYSWATCHDOG" +#define EVENT_HUNGTASK "HUNGTASK" +#define EVENT_BOOTFAIL "BOOTFAIL" + +struct ErrorInfo { + char event[EVENT_MAX_LEN]; + char module[MODULE_MAX_LEN]; + char errorDesc[ERROR_DESC_MAX_LEN]; +}; + +struct ModuleOps { + char module[MODULE_MAX_LEN]; + void (*Dump)(const char *logDir, struct ErrorInfo *info); + void (*Reset)(struct ErrorInfo *info); + int (*GetLastLogInfo)(struct ErrorInfo *info); + int (*SaveLastLog)(const char *logDir, struct ErrorInfo *info); +}; + +int BBoxRegisterModuleOps(struct ModuleOps *ops); +int BBoxNotifyError(const char event[EVENT_MAX_LEN], + const char module[MODULE_MAX_LEN], + const char errorDesc[ERROR_DESC_MAX_LEN], + int needSysReset); +int OsBBoxDriverInit(void); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif \ No newline at end of file diff --git a/src/kernel_liteos_a/kernel/extended/blackbox/los_blackbox_common.c b/src/kernel_liteos_a/kernel/extended/blackbox/los_blackbox_common.c new file mode 100644 index 00000000..471861b0 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/blackbox/los_blackbox_common.c @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* ------------ includes ------------ */ +#include "los_blackbox_common.h" +#ifdef LOSCFG_LIB_LIBC +#include "stdlib.h" +#include "unistd.h" +#endif +#ifdef LOSCFG_FS_VFS +#include "fs/fs.h" +#include "fs/mount.h" +#endif +#include "securec.h" +#include "los_memory.h" + +/* ------------ local macroes ------------ */ +#ifdef LOSCFG_FS_VFS +#define BBOX_DIR_MODE 0750 +#define BBOX_FILE_MODE 0640 +#endif + +/* ------------ local prototypes ------------ */ +/* ------------ local function declarations ------------ */ +/* ------------ global function declarations ------------ */ +/* ------------ local variables ------------ */ +static bool g_isLogPartReady = FALSE; + +/* ------------ function definitions ------------ */ +int FullWriteFile(const char *filePath, const char *buf, size_t bufSize, int isAppend) +{ +#ifdef LOSCFG_FS_VFS + int fd; + int totalToWrite = (int)bufSize; + int totalWrite = 0; + + if (filePath == NULL || buf == NULL || bufSize == 0) { + BBOX_PRINT_ERR("filePath: %p, buf: %p, bufSize: %lu!\n", filePath, buf, bufSize); + return -1; + } + + if (!IsLogPartReady()) { + BBOX_PRINT_ERR("log path [%s] isn't ready to be written!\n", LOSCFG_BLACKBOX_LOG_ROOT_PATH); + return -1; + } + fd = open(filePath, O_CREAT | O_RDWR | (isAppend ? O_APPEND : O_TRUNC), BBOX_FILE_MODE); + if (fd < 0) { + BBOX_PRINT_ERR("Create file [%s] failed, fd: %d!\n", filePath, fd); + return -1; + } + while (totalToWrite > 0) { + int writeThisTime = write(fd, buf, totalToWrite); + if (writeThisTime < 0) { + BBOX_PRINT_ERR("Failed to write file [%s]!\n", filePath); + (void)close(fd); + return -1; + } + buf += writeThisTime; + totalToWrite -= writeThisTime; + totalWrite += writeThisTime; + } + (void)fsync(fd); + (void)close(fd); + + return (totalWrite == (int)bufSize) ? 0 : -1; +#else + (VOID)filePath; + (VOID)buf; + (VOID)bufSize; + (VOID)isAppend; + return -1; +#endif +} + +int SaveBasicErrorInfo(const char *filePath, const struct ErrorInfo *info) +{ + char *buf = NULL; + + if (filePath == NULL || info == NULL) { + BBOX_PRINT_ERR("filePath: %p, event: %p!\n", filePath, info); + return -1; + } + + buf = LOS_MemAlloc(m_aucSysMem1, ERROR_INFO_MAX_LEN); + if (buf == NULL) { + BBOX_PRINT_ERR("LOS_MemAlloc failed!\n"); + return -1; + } + (void)memset_s(buf, ERROR_INFO_MAX_LEN, 0, ERROR_INFO_MAX_LEN); + if (snprintf_s(buf, ERROR_INFO_MAX_LEN, ERROR_INFO_MAX_LEN - 1, + ERROR_INFO_HEADER_FORMAT, info->event, info->module, info->errorDesc) != -1) { + *(buf + ERROR_INFO_MAX_LEN - 1) = '\0'; + (void)FullWriteFile(filePath, buf, strlen(buf), 0); + } else { + BBOX_PRINT_ERR("buf is not enough or snprintf_s failed!\n"); + } + + (void)LOS_MemFree(m_aucSysMem1, buf); + + return 0; +} + +#ifdef LOSCFG_FS_VFS +static int IsLogPartMounted(const char *devPoint, const char *mountPoint, struct statfs *statBuf, void *arg) +{ + (void)devPoint; + (void)statBuf; + (void)arg; + if (mountPoint != NULL && arg != NULL) { + if (strcmp(mountPoint, (char *)arg) == 0) { + g_isLogPartReady = TRUE; + } + } + return 0; +} + +bool IsLogPartReady(void) +{ + if (!g_isLogPartReady) { + (void)foreach_mountpoint((foreach_mountpoint_t)IsLogPartMounted, LOSCFG_BLACKBOX_LOG_PART_MOUNT_POINT); + } + return g_isLogPartReady; +} +#else +bool IsLogPartReady(void) +{ + return TRUE; +} +#endif + +#ifdef LOSCFG_FS_VFS +int CreateNewDir(const char *dirPath) +{ + int ret; + + if (dirPath == NULL) { + BBOX_PRINT_ERR("dirPath is NULL!\n"); + return -1; + } + + ret = access(dirPath, 0); + if (ret == 0) { + return 0; + } + ret = mkdir(dirPath, BBOX_DIR_MODE); + if (ret != 0) { + BBOX_PRINT_ERR("mkdir [%s] failed!\n", dirPath); + return -1; + } + + return 0; +} + +int CreateLogDir(const char *dirPath) +{ + const char *temp = dirPath; + char curPath[PATH_MAX_LEN]; + int idx = 0; + + if (dirPath == NULL) { + BBOX_PRINT_ERR("dirPath is NULL!\n"); + return -1; + } + if (*dirPath != '/') { + BBOX_PRINT_ERR("Invalid dirPath: %s\n", dirPath); + return -1; + } + (void)memset_s(curPath, sizeof(curPath), 0, sizeof(curPath)); + curPath[idx++] = *dirPath++; + while (*dirPath != '\0' && idx < sizeof(curPath)) { + if (*dirPath == '/') { + if (CreateNewDir(curPath) != 0) { + return -1; + } + } + curPath[idx] = *dirPath; + dirPath++; + idx++; + } + if (*dirPath != '\0') { + BBOX_PRINT_ERR("dirPath [%s] is too long!\n", temp); + return -1; + } + + return CreateNewDir(curPath); +} +#else +int CreateLogDir(const char *dirPath) +{ + (void)dirPath; + return -1; +} +#endif diff --git a/src/kernel_liteos_a/kernel/extended/blackbox/los_blackbox_common.h b/src/kernel_liteos_a/kernel/extended/blackbox/los_blackbox_common.h new file mode 100644 index 00000000..cfbb28a8 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/blackbox/los_blackbox_common.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LOS_BLACKBOX_COMMON_H +#define LOS_BLACKBOX_COMMON_H + +#include "los_blackbox.h" +#include "los_printf.h" +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define ERROR_INFO_HEADER_FORMAT "#### error info ####\nevent: %s\nmodule: %s\nerrorDesc: %s\n" +#define ERROR_INFO_MAX_LEN 768 +#define Min(a, b) (((a) > (b)) ? (b) : (a)) +#define BBOX_PRINT_ERR(format, ...) PRINTK("bbox: func: %s, line: %d, Err: " \ + format, __func__, __LINE__, ##__VA_ARGS__) +#define BBOX_PRINT_INFO(format, ...) PRINTK("bbox: Info: " format, ##__VA_ARGS__) + +int FullWriteFile(const char *filePath, const char *buf, size_t bufSize, int isAppend); +int SaveBasicErrorInfo(const char *filePath, const struct ErrorInfo *info); +int CreateLogDir(const char *dirPath); +bool IsLogPartReady(void); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif \ No newline at end of file diff --git a/src/kernel_liteos_a/kernel/extended/blackbox/los_blackbox_core.c b/src/kernel_liteos_a/kernel/extended/blackbox/los_blackbox_core.c new file mode 100644 index 00000000..6e0fef4e --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/blackbox/los_blackbox_core.c @@ -0,0 +1,478 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* ------------ includes ------------ */ +#include "los_blackbox.h" +#include "los_blackbox_common.h" +#include "los_blackbox_detector.h" +#ifdef LOSCFG_LIB_LIBC +#include "stdlib.h" +#include "unistd.h" +#endif +#include "los_base.h" +#include "los_config.h" +#include "los_excinfo_pri.h" +#include "los_hw.h" +#include "los_init.h" +#include "los_memory.h" +#include "los_sem.h" +#include "los_syscall.h" +#include "los_task_pri.h" +#include "securec.h" +#include "sys/reboot.h" + +/* ------------ local macroes ------------ */ +#define LOG_WAIT_TIMES 10 +#define LOG_PART_WAIT_TIME 1000 + +/* ------------ local prototypes ------------ */ +typedef struct BBoxOps { + LOS_DL_LIST opsList; + struct ModuleOps ops; +} BBoxOps; + +/* ------------ local function declarations ------------ */ +/* ------------ global function declarations ------------ */ +/* ------------ local variables ------------ */ +static bool g_bboxInitSucc = FALSE; +static UINT32 g_opsListSem = 0; +static UINT32 g_tempErrInfoSem = 0; +static UINT32 g_tempErrLogSaveSem = 0; +static LOS_DL_LIST_HEAD(g_opsList); +struct ErrorInfo *g_tempErrInfo; + +/* ------------ function definitions ------------ */ +static void FormatErrorInfo(struct ErrorInfo *info, + const char event[EVENT_MAX_LEN], + const char module[MODULE_MAX_LEN], + const char errorDesc[ERROR_DESC_MAX_LEN]) +{ + if (info == NULL || event == NULL || module == NULL || errorDesc == NULL) { + BBOX_PRINT_ERR("info: %p, event: %p, module: %p, errorDesc: %p!\n", info, event, module, errorDesc); + return; + } + + (void)memset_s(info, sizeof(*info), 0, sizeof(*info)); + if (strncpy_s(info->event, sizeof(info->event), event, Min(strlen(event), sizeof(info->event) - 1)) != EOK) { + BBOX_PRINT_ERR("info->event is not enough or strncpy_s failed!\n"); + } + if (strncpy_s(info->module, sizeof(info->module), module, Min(strlen(module), sizeof(info->module) - 1)) != EOK) { + BBOX_PRINT_ERR("info->module is not enough or strncpy_s failed!\n"); + } + if (strncpy_s(info->errorDesc, sizeof(info->errorDesc), errorDesc, + Min(strlen(errorDesc), sizeof(info->errorDesc) - 1)) != EOK) { + BBOX_PRINT_ERR("info->errorDesc is not enough or strncpy_s failed!\n"); + } +} + +#ifdef LOSCFG_FS_VFS +static void WaitForLogPart(void) +{ + BBOX_PRINT_INFO("wait for log part [%s] begin!\n", LOSCFG_BLACKBOX_LOG_PART_MOUNT_POINT); + while (!IsLogPartReady()) { + LOS_Msleep(LOG_PART_WAIT_TIME); + } + BBOX_PRINT_INFO("wait for log part [%s] end!\n", LOSCFG_BLACKBOX_LOG_PART_MOUNT_POINT); +} +#else +static void WaitForLogPart(void) +{ + int i = 0; + + BBOX_PRINT_INFO("wait for log part [%s] begin!\n", LOSCFG_BLACKBOX_LOG_PART_MOUNT_POINT); + while (i++ < LOG_WAIT_TIMES) { + LOS_Msleep(LOG_PART_WAIT_TIME); + } + BBOX_PRINT_INFO("wait for log part [%s] end!\n", LOSCFG_BLACKBOX_LOG_PART_MOUNT_POINT); +} +#endif + +static bool FindModuleOps(struct ErrorInfo *info, BBoxOps **ops) +{ + bool found = false; + + if (info == NULL || ops == NULL) { + BBOX_PRINT_ERR("info: %p, ops: %p!\n", info, ops); + return found; + } + + LOS_DL_LIST_FOR_EACH_ENTRY(*ops, &g_opsList, BBoxOps, opsList) { + if (*ops != NULL && strcmp((*ops)->ops.module, info->module) == 0) { + found = true; + break; + } + } + if (!found) { + BBOX_PRINT_ERR("[%s] hasn't been registered!\n", info->module); + } + + return found; +} + +static void InvokeModuleOps(struct ErrorInfo *info, const BBoxOps *ops) +{ + if (info == NULL || ops == NULL) { + BBOX_PRINT_ERR("info: %p, ops: %p!\n", info, ops); + return; + } + + if (ops->ops.Dump != NULL) { + BBOX_PRINT_INFO("[%s] starts dumping log!\n", ops->ops.module); + ops->ops.Dump(LOSCFG_BLACKBOX_LOG_ROOT_PATH, info); + BBOX_PRINT_INFO("[%s] ends dumping log!\n", ops->ops.module); + } + if (ops->ops.Reset != NULL) { + BBOX_PRINT_INFO("[%s] starts resetting!\n", ops->ops.module); + ops->ops.Reset(info); + BBOX_PRINT_INFO("[%s] ends resetting!\n", ops->ops.module); + } +} + +static void SaveLastLog(const char *logDir) +{ + struct ErrorInfo *info = NULL; + BBoxOps *ops = NULL; + + info = LOS_MemAlloc(m_aucSysMem1, sizeof(*info)); + if (info == NULL) { + BBOX_PRINT_ERR("LOS_MemAlloc failed!\n"); + return; + } + + if (LOS_SemPend(g_opsListSem, LOS_WAIT_FOREVER) != LOS_OK) { + BBOX_PRINT_ERR("Request g_opsListSem failed!\n"); + (void)LOS_MemFree(m_aucSysMem1, info); + return; + } + if (CreateLogDir(LOSCFG_BLACKBOX_LOG_ROOT_PATH) != 0) { + (void)LOS_SemPost(g_opsListSem); + (void)LOS_MemFree(m_aucSysMem1, info); + BBOX_PRINT_ERR("Create log dir [%s] failed!\n", LOSCFG_BLACKBOX_LOG_ROOT_PATH); + return; + } + LOS_DL_LIST_FOR_EACH_ENTRY(ops, &g_opsList, BBoxOps, opsList) { + if (ops == NULL) { + BBOX_PRINT_ERR("ops: NULL, please check it!\n"); + continue; + } + if (ops->ops.GetLastLogInfo != NULL && ops->ops.SaveLastLog != NULL) { + (void)memset_s(info, sizeof(*info), 0, sizeof(*info)); + if (ops->ops.GetLastLogInfo(info) != 0) { + BBOX_PRINT_ERR("[%s] failed to get log info!\n", ops->ops.module); + continue; + } + BBOX_PRINT_INFO("[%s] starts saving log!\n", ops->ops.module); + if (ops->ops.SaveLastLog(logDir, info) != 0) { + BBOX_PRINT_ERR("[%s] failed to save log!\n", ops->ops.module); + } else { + BBOX_PRINT_INFO("[%s] ends saving log!\n", ops->ops.module); + BBOX_PRINT_INFO("[%s] starts uploading event [%s]\n", info->module, info->event); +#ifdef LOSCFG_FS_VFS + (void)UploadEventByFile(KERNEL_FAULT_LOG_PATH); +#else + BBOX_PRINT_INFO("LOSCFG_FS_VFS isn't defined!\n"); +#endif + BBOX_PRINT_INFO("[%s] ends uploading event [%s]\n", info->module, info->event); + } + } else { + BBOX_PRINT_ERR("module [%s], GetLastLogInfo: %p, SaveLastLog: %p!\n", + ops->ops.module, ops->ops.GetLastLogInfo, ops->ops.SaveLastLog); + } + } + (void)LOS_SemPost(g_opsListSem); + (void)LOS_MemFree(m_aucSysMem1, info); +} + +static void SaveLogWithoutReset(struct ErrorInfo *info) +{ + BBoxOps *ops = NULL; + + if (info == NULL) { + BBOX_PRINT_ERR("info is NULL!\n"); + return; + } + + if (LOS_SemPend(g_opsListSem, LOS_WAIT_FOREVER) != LOS_OK) { + BBOX_PRINT_ERR("Request g_opsListSem failed!\n"); + return; + } + if (!FindModuleOps(info, &ops)) { + (void)LOS_SemPost(g_opsListSem); + return; + } + if (CreateLogDir(LOSCFG_BLACKBOX_LOG_ROOT_PATH) != 0) { + (void)LOS_SemPost(g_opsListSem); + BBOX_PRINT_ERR("Create log dir [%s] failed!\n", LOSCFG_BLACKBOX_LOG_ROOT_PATH); + return; + } + if (ops->ops.Dump == NULL && ops->ops.Reset == NULL) { + (void)LOS_SemPost(g_opsListSem); + if (SaveBasicErrorInfo(USER_FAULT_LOG_PATH, info) == 0) { + BBOX_PRINT_INFO("[%s] starts uploading event [%s]\n", info->module, info->event); +#ifdef LOSCFG_FS_VFS + (void)UploadEventByFile(USER_FAULT_LOG_PATH); +#else + BBOX_PRINT_INFO("LOSCFG_FS_VFS isn't defined!\n"); +#endif + BBOX_PRINT_INFO("[%s] ends uploading event [%s]\n", info->module, info->event); + } + return; + } + InvokeModuleOps(info, ops); + (void)LOS_SemPost(g_opsListSem); +} + +static void SaveTempErrorLog(void) +{ + if (LOS_SemPend(g_tempErrInfoSem, LOS_WAIT_FOREVER) != LOS_OK) { + BBOX_PRINT_ERR("Request g_tempErrInfoSem failed!\n"); + return; + } + if (g_tempErrInfo == NULL) { + BBOX_PRINT_ERR("g_tempErrInfo is NULL!\n"); + (void)LOS_SemPost(g_tempErrInfoSem); + return; + } + if (strlen(g_tempErrInfo->event) != 0) { + SaveLogWithoutReset(g_tempErrInfo); + } + (void)LOS_SemPost(g_tempErrInfoSem); +} + +static void SaveLogWithReset(struct ErrorInfo *info) +{ + int ret; + BBoxOps *ops = NULL; + + if (info == NULL) { + BBOX_PRINT_ERR("info is NULL!\n"); + return; + } + + if (!FindModuleOps(info, &ops)) { + return; + } + InvokeModuleOps(info, ops); + ret = SysReboot(0, 0, RB_AUTOBOOT); + BBOX_PRINT_INFO("SysReboot, ret: %d\n", ret); +} + +static void SaveTempErrorInfo(const char event[EVENT_MAX_LEN], + const char module[MODULE_MAX_LEN], + const char errorDesc[ERROR_DESC_MAX_LEN]) +{ + if (event == NULL || module == NULL || errorDesc == NULL) { + BBOX_PRINT_ERR("event: %p, module: %p, errorDesc: %p!\n", event, module, errorDesc); + return; + } + if (LOS_SemPend(g_tempErrInfoSem, LOS_NO_WAIT) != LOS_OK) { + BBOX_PRINT_ERR("Request g_tempErrInfoSem failed!\n"); + return; + } + FormatErrorInfo(g_tempErrInfo, event, module, errorDesc); + (void)LOS_SemPost(g_tempErrInfoSem); +} + +static int SaveErrorLog(UINTPTR uwParam1, UINTPTR uwParam2, UINTPTR uwParam3, UINTPTR uwParam4) +{ + const char *logDir = (const char *)uwParam1; + (void)uwParam2; + (void)uwParam3; + (void)uwParam4; + +#ifdef LOSCFG_FS_VFS + WaitForLogPart(); +#endif + SaveLastLog(logDir); + while (1) { + if (LOS_SemPend(g_tempErrLogSaveSem, LOS_WAIT_FOREVER) != LOS_OK) { + BBOX_PRINT_ERR("Request g_tempErrLogSaveSem failed!\n"); + continue; + } + SaveTempErrorLog(); + } + return 0; +} + +#ifdef LOSCFG_BLACKBOX_DEBUG +static void PrintModuleOps(void) +{ + struct BBoxOps *ops = NULL; + + BBOX_PRINT_INFO("The following modules have been registered!\n"); + LOS_DL_LIST_FOR_EACH_ENTRY(ops, &g_opsList, BBoxOps, opsList) { + if (ops == NULL) { + continue; + } + BBOX_PRINT_INFO("module: %s, Dump: %p, Reset: %p, GetLastLogInfo: %p, SaveLastLog: %p\n", + ops->ops.module, ops->ops.Dump, ops->ops.Reset, ops->ops.GetLastLogInfo, ops->ops.SaveLastLog); + } +} +#endif + +int BBoxRegisterModuleOps(struct ModuleOps *ops) +{ + BBoxOps *newOps = NULL; + BBoxOps *temp = NULL; + + if (!g_bboxInitSucc) { + BBOX_PRINT_ERR("BlackBox isn't initialized successfully!\n"); + return -1; + } + if (ops == NULL) { + BBOX_PRINT_ERR("ops is NULL!\n"); + return -1; + } + + newOps = LOS_MemAlloc(m_aucSysMem1, sizeof(*newOps)); + if (newOps == NULL) { + BBOX_PRINT_ERR("LOS_MemAlloc failed!\n"); + return -1; + } + (void)memset_s(newOps, sizeof(*newOps), 0, sizeof(*newOps)); + if (memcpy_s(&newOps->ops, sizeof(newOps->ops), ops, sizeof(*ops)) != EOK) { + BBOX_PRINT_ERR("newOps->ops is not enough or memcpy_s failed!\n"); + (void)LOS_MemFree(m_aucSysMem1, newOps); + return -1; + } + if (LOS_SemPend(g_opsListSem, LOS_WAIT_FOREVER) != LOS_OK) { + BBOX_PRINT_ERR("Request g_opsListSem failed!\n"); + (void)LOS_MemFree(m_aucSysMem1, newOps); + return -1; + } + if (LOS_ListEmpty(&g_opsList)) { + goto __out; + } + + LOS_DL_LIST_FOR_EACH_ENTRY(temp, &g_opsList, BBoxOps, opsList) { + if (temp == NULL) { + continue; + } + if (strcmp(temp->ops.module, ops->module) == 0) { + BBOX_PRINT_ERR("module [%s] has been registered!\n", ops->module); + (void)LOS_SemPost(g_opsListSem); + (void)LOS_MemFree(m_aucSysMem1, newOps); + return -1; + } + } + +__out: + LOS_ListTailInsert(&g_opsList, &newOps->opsList); + (void)LOS_SemPost(g_opsListSem); + BBOX_PRINT_INFO("module [%s] is registered successfully!\n", ops->module); +#ifdef LOSCFG_BLACKBOX_DEBUG + PrintModuleOps(); +#endif + + return 0; +} + +int BBoxNotifyError(const char event[EVENT_MAX_LEN], + const char module[MODULE_MAX_LEN], + const char errorDesc[ERROR_DESC_MAX_LEN], + int needSysReset) +{ + if (event == NULL || module == NULL || errorDesc == NULL) { + BBOX_PRINT_ERR("event: %p, module: %p, errorDesc: %p!\n", event, module, errorDesc); + return -1; + } + if (!g_bboxInitSucc) { + BBOX_PRINT_ERR("BlackBox isn't initialized successfully!\n"); + return -1; + } + + if (needSysReset == 0) { + SaveTempErrorInfo(event, module, errorDesc); + (void)LOS_SemPost(g_tempErrLogSaveSem); + } else { + struct ErrorInfo *info = LOS_MemAlloc(m_aucSysMem1, sizeof(struct ErrorInfo)); + if (info == NULL) { + BBOX_PRINT_ERR("LOS_MemAlloc failed!\n"); + return -1; + } + FormatErrorInfo(info, event, module, errorDesc); + SaveLogWithReset(info); + (void)LOS_MemFree(m_aucSysMem1, info); + } + + return 0; +} + +int OsBBoxDriverInit(void) +{ + UINT32 taskID; + TSK_INIT_PARAM_S taskParam; + + if (LOS_BinarySemCreate(1, &g_opsListSem) != LOS_OK) { + BBOX_PRINT_ERR("Create g_opsListSem failed!\n"); + return LOS_NOK; + } + if (LOS_BinarySemCreate(1, &g_tempErrInfoSem) != LOS_OK) { + BBOX_PRINT_ERR("Create g_tempErrInfoSem failed!\n"); + goto __err; + } + if (LOS_BinarySemCreate(0, &g_tempErrLogSaveSem) != LOS_OK) { + BBOX_PRINT_ERR("Create g_tempErrLogSaveSem failed!\n"); + goto __err; + } + LOS_ListInit(&g_opsList); + g_tempErrInfo = LOS_MemAlloc(m_aucSysMem1, sizeof(*g_tempErrInfo)); + if (g_tempErrInfo == NULL) { + BBOX_PRINT_ERR("LOS_MemAlloc failed!\n"); + goto __err; + } + (void)memset_s(g_tempErrInfo, sizeof(*g_tempErrInfo), 0, sizeof(*g_tempErrInfo)); + (void)memset_s(&taskParam, sizeof(taskParam), 0, sizeof(taskParam)); + taskParam.auwArgs[0] = (UINTPTR)LOSCFG_BLACKBOX_LOG_ROOT_PATH; + taskParam.pfnTaskEntry = (TSK_ENTRY_FUNC)SaveErrorLog; + taskParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + taskParam.pcName = "SaveErrorLog"; + taskParam.usTaskPrio = LOSCFG_BASE_CORE_TSK_DEFAULT_PRIO; + taskParam.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + taskParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + (void)LOS_TaskCreate(&taskID, &taskParam); + g_bboxInitSucc = TRUE; + return LOS_OK; + +__err: + if (g_opsListSem != 0) { + (void)LOS_SemDelete(g_opsListSem); + } + if (g_tempErrInfoSem != 0) { + (void)LOS_SemDelete(g_tempErrInfoSem); + } + if (g_tempErrLogSaveSem != 0) { + (void)LOS_SemDelete(g_tempErrLogSaveSem); + } + return LOS_NOK; +} +LOS_MODULE_INIT(OsBBoxDriverInit, LOS_INIT_LEVEL_ARCH); \ No newline at end of file diff --git a/src/kernel_liteos_a/kernel/extended/blackbox/los_blackbox_detector.c b/src/kernel_liteos_a/kernel/extended/blackbox/los_blackbox_detector.c new file mode 100644 index 00000000..ea14c9ea --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/blackbox/los_blackbox_detector.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* ------------ includes ------------ */ +#include "los_blackbox_detector.h" +#include "los_blackbox_common.h" +#ifdef LOSCFG_LIB_LIBC +#include "stdlib.h" +#include "unistd.h" +#endif + +/* ------------ local macroes ------------ */ +/* ------------ local prototypes ------------ */ +/* ------------ local function declarations ------------ */ +/* ------------ global function declarations ------------ */ +/* ------------ local variables ------------ */ +/* ------------ function definitions ------------ */ +int UploadEventByFile(const char *filePath) +{ + if (filePath == NULL) { + BBOX_PRINT_ERR("filePath is NULL\n"); + return -1; + } + + return 0; +} + +int UploadEventByStream(const char *buf, size_t bufSize) +{ + if (buf == NULL || bufSize == 0) { + BBOX_PRINT_ERR("buf: %p, bufSize: %u\n", buf, (UINT32)bufSize); + return -1; + } + + return 0; +} \ No newline at end of file diff --git a/src/kernel_liteos_a/kernel/extended/blackbox/los_blackbox_detector.h b/src/kernel_liteos_a/kernel/extended/blackbox/los_blackbox_detector.h new file mode 100644 index 00000000..9e630d52 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/blackbox/los_blackbox_detector.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LOS_BLACKBOX_DETECTOR_H +#define LOS_BLACKBOX_DETECTOR_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +int UploadEventByFile(const char *filePath); +int UploadEventByStream(const char *buf, size_t bufSize); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif \ No newline at end of file diff --git a/src/kernel_liteos_a/kernel/extended/blackbox/los_blackbox_system_adapter.c b/src/kernel_liteos_a/kernel/extended/blackbox/los_blackbox_system_adapter.c new file mode 100644 index 00000000..647d5858 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/blackbox/los_blackbox_system_adapter.c @@ -0,0 +1,265 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* ------------ includes ------------ */ +#include "los_blackbox_system_adapter.h" +#include "los_blackbox_common.h" +#include "los_blackbox_detector.h" +#ifdef LOSCFG_LIB_LIBC +#include "stdlib.h" +#include "unistd.h" +#endif +#include "los_base.h" +#include "los_config.h" +#ifdef LOSCFG_SAVE_EXCINFO +#include "los_excinfo_pri.h" +#endif +#include "los_hw.h" +#include "los_init.h" +#include "los_memory.h" +#include "los_vm_common.h" +#include "los_vm_phys.h" +#include "los_vm_zone.h" +#include "securec.h" + +/* ------------ local macroes ------------ */ +#define LOG_FLAG "GOODLOG" + +/* ------------ local prototypes ------------ */ +struct FaultLogInfo { + char flag[8]; /* 8 is the length of the flag */ + int len; /* length of the fault log saved by the module excinfo */ + struct ErrorInfo info; +}; + +/* ------------ local function declarations ------------ */ +/* ------------ global function declarations ------------ */ +/* ------------ local variables ------------ */ +static char *g_logBuffer = NULL; + +/* ------------ function definitions ------------ */ +static void SaveFaultLog(const char *filePath, const char *dataBuf, size_t bufSize, struct ErrorInfo *info) +{ + (void)SaveBasicErrorInfo(filePath, info); + (void)FullWriteFile(filePath, dataBuf, bufSize, 1); +} + +#ifdef LOSCFG_SAVE_EXCINFO +static void WriteExcFile(UINT32 startAddr, UINT32 space, UINT32 rwFlag, char *buf) +{ + (void)startAddr; + (void)space; + (void)rwFlag; + (void)buf; +} +#endif + +static void RegisterExcInfoHook(void) +{ + if (g_logBuffer != NULL) { +#ifdef LOSCFG_SAVE_EXCINFO + LOS_ExcInfoRegHook(0, LOSCFG_BLACKBOX_LOG_SIZE - sizeof(struct FaultLogInfo), + g_logBuffer + sizeof(struct FaultLogInfo), WriteExcFile); +#endif + } else { + BBOX_PRINT_ERR("Alloc mem failed!\n"); + } +} + +static int AllocLogBuffer(void) +{ + if (LOSCFG_BLACKBOX_LOG_SIZE < sizeof(struct FaultLogInfo)) { + BBOX_PRINT_ERR("LOSCFG_BLACKBOX_LOG_SIZE [%d] is too short, it must be >= %u\n", + LOSCFG_BLACKBOX_LOG_SIZE, sizeof(struct FaultLogInfo)); + return -1; + } + + /* + * The physical memory pointed to by LOSCFG_BLACKBOX_RESERVE_MEM_ADDR is + * exclusive to blackbox and cannot be occupied by other modules during + * system running and cannot overlap with the memory area of other systems + * during startup. + */ + g_logBuffer = (char *)MEM_CACHED_ADDR(LOSCFG_BLACKBOX_RESERVE_MEM_ADDR); + BBOX_PRINT_INFO("g_logBuffer: %p, len: 0x%x for blackbox!\n", g_logBuffer, (UINT32)LOSCFG_BLACKBOX_LOG_SIZE); + + return (g_logBuffer != NULL) ? 0 : -1; +} + +static void Dump(const char *logDir, struct ErrorInfo *info) +{ + struct FaultLogInfo *pLogInfo = NULL; + + if (logDir == NULL || info == NULL) { + BBOX_PRINT_ERR("logDir: %p, info: %p!\n", logDir, info); + return; + } + if (g_logBuffer == NULL) { + BBOX_PRINT_ERR("g_logBuffer is NULL, alloc physical pages failed!\n"); + return; + } + + if (strcmp(info->event, EVENT_PANIC) == 0) { + pLogInfo = (struct FaultLogInfo *)g_logBuffer; + (void)memset_s(pLogInfo, sizeof(*pLogInfo), 0, sizeof(*pLogInfo)); +#ifdef LOSCFG_SAVE_EXCINFO + pLogInfo->len = GetExcInfoIndex(); +#else + pLogInfo->len = 0; +#endif + (void)memcpy_s(&pLogInfo->flag, sizeof(pLogInfo->flag), LOG_FLAG, strlen(LOG_FLAG)); + (void)memcpy_s(&pLogInfo->info, sizeof(pLogInfo->info), info, sizeof(*info)); + DCacheFlushRange((UINTPTR)g_logBuffer, (UINTPTR)(g_logBuffer + LOSCFG_BLACKBOX_LOG_SIZE)); + } else { +#ifdef LOSCFG_SAVE_EXCINFO + SaveFaultLog(USER_FAULT_LOG_PATH, g_logBuffer + sizeof(struct FaultLogInfo), + Min(LOSCFG_BLACKBOX_LOG_SIZE - sizeof(struct FaultLogInfo), GetExcInfoIndex()), info); +#else + SaveFaultLog(USER_FAULT_LOG_PATH, g_logBuffer + sizeof(struct FaultLogInfo), 0, info); +#endif + } +} + +static void Reset(struct ErrorInfo *info) +{ + if (info == NULL) { + BBOX_PRINT_ERR("info is NULL!\n"); + return; + } + + if (strcmp(info->event, EVENT_PANIC) != 0) { + BBOX_PRINT_INFO("[%s] starts uploading event [%s]\n", info->module, info->event); + (void)UploadEventByFile(USER_FAULT_LOG_PATH); + BBOX_PRINT_INFO("[%s] ends uploading event [%s]\n", info->module, info->event); + } +} + +static int GetLastLogInfo(struct ErrorInfo *info) +{ + struct FaultLogInfo *pLogInfo = NULL; + + if (info == NULL) { + BBOX_PRINT_ERR("info is NULL!\n"); + return -1; + } + if (g_logBuffer == NULL) { + BBOX_PRINT_ERR("g_logBuffer is NULL, alloc physical pages failed!\n"); + return -1; + } + + pLogInfo = (struct FaultLogInfo *)g_logBuffer; + if (memcmp(pLogInfo->flag, LOG_FLAG, strlen(LOG_FLAG)) == 0) { + (void)memcpy_s(info, sizeof(*info), &pLogInfo->info, sizeof(pLogInfo->info)); + return 0; + } + + return -1; +} + +static int SaveLastLog(const char *logDir, struct ErrorInfo *info) +{ +#ifdef LOSCFG_FS_VFS + struct FaultLogInfo *pLogInfo = NULL; + + if (logDir == NULL || info == NULL) { + BBOX_PRINT_ERR("logDir: %p, info: %p!\n", logDir, info); + return -1; + } + if (g_logBuffer == NULL) { + BBOX_PRINT_ERR("g_logBuffer is NULL, alloc physical pages failed!\n"); + return -1; + } + + pLogInfo = (struct FaultLogInfo *)g_logBuffer; + if (memcmp(pLogInfo->flag, LOG_FLAG, strlen(LOG_FLAG)) == 0) { + SaveFaultLog(KERNEL_FAULT_LOG_PATH, g_logBuffer + sizeof(*pLogInfo), + Min(LOSCFG_BLACKBOX_LOG_SIZE - sizeof(*pLogInfo), pLogInfo->len), info); + } + (void)memset_s(g_logBuffer, LOSCFG_BLACKBOX_LOG_SIZE, 0, LOSCFG_BLACKBOX_LOG_SIZE); + BBOX_PRINT_INFO("[%s] starts uploading event [%s]\n", info->module, info->event); + (void)UploadEventByFile(KERNEL_FAULT_LOG_PATH); + BBOX_PRINT_INFO("[%s] ends uploading event [%s]\n", info->module, info->event); + return 0; +#else + (VOID)logDir; + (VOID)info; + BBOX_PRINT_ERR("LOSCFG_FS_VFS isn't defined!\n"); + return -1; +#endif +} + +#ifdef LOSCFG_BLACKBOX_TEST +static void BBoxTest(void) +{ + struct ModuleOps ops = { + .module = "MODULE_TEST", + .Dump = NULL, + .Reset = NULL, + .GetLastLogInfo = NULL, + .SaveLastLog = NULL, + }; + + if (BBoxRegisterModuleOps(&ops) != 0) { + BBOX_PRINT_ERR("BBoxRegisterModuleOps failed!\n"); + return; + } + BBoxNotifyError("EVENT_TEST1", "MODULE_TEST", "Test BBoxNotifyError111", 0); +} +#endif + +int OsBBoxSystemAdapterInit(void) +{ + struct ModuleOps ops = { + .module = MODULE_SYSTEM, + .Dump = Dump, + .Reset = Reset, + .GetLastLogInfo = GetLastLogInfo, + .SaveLastLog = SaveLastLog, + }; + + /* allocate buffer for kmsg */ + if (AllocLogBuffer() == 0) { + RegisterExcInfoHook(); + if (BBoxRegisterModuleOps(&ops) != 0) { + BBOX_PRINT_ERR("BBoxRegisterModuleOps failed!\n"); + g_logBuffer = NULL; + return LOS_NOK; + } + } else { + BBOX_PRINT_ERR("AllocLogBuffer failed!\n"); + } + +#ifdef LOSCFG_BLACKBOX_TEST + BBoxTest(); +#endif + + return LOS_OK; +} +LOS_MODULE_INIT(OsBBoxSystemAdapterInit, LOS_INIT_LEVEL_PLATFORM); diff --git a/src/kernel_liteos_a/kernel/extended/blackbox/los_blackbox_system_adapter.h b/src/kernel_liteos_a/kernel/extended/blackbox/los_blackbox_system_adapter.h new file mode 100644 index 00000000..2f1e7128 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/blackbox/los_blackbox_system_adapter.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LOS_BLACKBOX_SYSTEM_ADAPTER_H +#define LOS_BLACKBOX_SYSTEM_ADAPTER_H + +#include "los_blackbox.h" +#include "los_blackbox_common.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +int OsBBoxSystemAdapterInit(void); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif \ No newline at end of file diff --git a/src/kernel_liteos_a/kernel/extended/container/BUILD.gn b/src/kernel_liteos_a/kernel/extended/container/BUILD.gn new file mode 100644 index 00000000..85bc8ea8 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/container/BUILD.gn @@ -0,0 +1,65 @@ +# Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = defined(LOSCFG_KERNEL_CONTAINER) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ "los_container.c" ] + if (defined(LOSCFG_IPC_CONTAINER)) { + sources += [ "los_ipc_container.c" ] + } + if (defined(LOSCFG_MNT_CONTAINER)) { + sources += [ "los_mnt_container.c" ] + } + if (defined(LOSCFG_NET_CONTAINER)) { + sources += [ "los_net_container.c" ] + } + if (defined(LOSCFG_PID_CONTAINER)) { + sources += [ "los_pid_container.c" ] + } + if (defined(LOSCFG_TIME_CONTAINER)) { + sources += [ "los_time_container.c" ] + } + if (defined(LOSCFG_USER_CONTAINER)) { + sources += [ + "los_credentials.c", + "los_user_container.c", + ] + } + if (defined(LOSCFG_UTS_CONTAINER)) { + sources += [ "los_uts_container.c" ] + } + + public_configs = [ ":public" ] +} + +config("public") { + include_dirs = [ "." ] +} diff --git a/src/kernel_liteos_a/kernel/extended/container/Makefile b/src/kernel_liteos_a/kernel/extended/container/Makefile new file mode 100644 index 00000000..194ff867 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/container/Makefile @@ -0,0 +1,63 @@ +# Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := $(wildcard *.c) + +ifneq ($(LOSCFG_IPC_CONTAINER), y) +LOCAL_SRCS += $(filter-out los_ipc_container.c, $(LOCAL_SRCS)) +endif + +ifneq ($(LOSCFG_MNT_CONTAINER), y) +LOCAL_SRCS += $(filter-out los_mnt_container.c, $(LOCAL_SRCS)) +endif + +ifneq ($(LOSCFG_NET_CONTAINER), y) +LOCAL_SRCS += $(filter-out los_net_container.c, $(LOCAL_SRCS)) +endif + +ifneq ($(LOSCFG_PID_CONTAINER), y) +LOCAL_SRCS += $(filter-out los_pid_container.c, $(LOCAL_SRCS)) +endif + +ifneq ($(LOSCFG_TIME_CONTAINER), y) +LOCAL_SRCS += $(filter-out los_time_container.c, $(LOCAL_SRCS)) +endif + +ifneq ($(LOSCFG_USER_CONTAINER), y) +LOCAL_SRCS += $(filter-out los_credentials.c los_user_container.c, $(LOCAL_SRCS)) +endif + +ifneq ($(LOSCFG_UTS_CONTAINER), y) +LOCAL_SRCS += $(filter-out los_uts_container.c, $(LOCAL_SRCS)) +endif + +include $(MODULE) \ No newline at end of file diff --git a/src/kernel_liteos_a/kernel/extended/container/los_container.c b/src/kernel_liteos_a/kernel/extended/container/los_container.c new file mode 100644 index 00000000..9bb59ba9 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/container/los_container.c @@ -0,0 +1,755 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef LOSCFG_KERNEL_CONTAINER +#include "los_container_pri.h" +#include "los_process_pri.h" +#include "internal.h" + +STATIC Container g_rootContainer; +STATIC ContainerLimit g_containerLimit; +STATIC Atomic g_containerCount = 0xF0000000U; +#ifdef LOSCFG_USER_CONTAINER +STATIC Credentials *g_rootCredentials = NULL; +#endif + +UINT32 OsAllocContainerID(VOID) +{ + return LOS_AtomicIncRet(&g_containerCount); +} + +VOID OsContainerInitSystemProcess(LosProcessCB *processCB) +{ + processCB->container = &g_rootContainer; +#ifdef LOSCFG_USER_CONTAINER + processCB->credentials = g_rootCredentials; +#endif + LOS_AtomicInc(&processCB->container->rc); +#ifdef LOSCFG_PID_CONTAINER + (VOID)OsAllocSpecifiedVpidUnsafe(processCB->processID, processCB->container->pidContainer, processCB, NULL); +#endif + return; +} + +UINT32 OsGetContainerLimit(ContainerType type) +{ + switch (type) { +#ifdef LOSCFG_PID_CONTAINER + case PID_CONTAINER: + case PID_CHILD_CONTAINER: + return g_containerLimit.pidLimit; +#endif +#ifdef LOSCFG_USER_CONTAINER + case USER_CONTAINER: + return g_containerLimit.userLimit; +#endif +#ifdef LOSCFG_UTS_CONTAINER + case UTS_CONTAINER: + return g_containerLimit.utsLimit; +#endif +#ifdef LOSCFG_MNT_CONTAINER + case MNT_CONTAINER: + return g_containerLimit.mntLimit; +#endif +#ifdef LOSCFG_IPC_CONTAINER + case IPC_CONTAINER: + return g_containerLimit.ipcLimit; +#endif +#ifdef LOSCFG_TIME_CONTAINER + case TIME_CONTAINER: + case TIME_CHILD_CONTAINER: + return g_containerLimit.timeLimit; +#endif +#ifdef LOSCFG_NET_CONTAINER + case NET_CONTAINER: + return g_containerLimit.netLimit; +#endif + default: + break; + } + return OS_INVALID_VALUE; +} + +UINT32 OsContainerLimitCheck(ContainerType type, UINT32 *containerCount) +{ + UINT32 intSave; + SCHEDULER_LOCK(intSave); + if ((*containerCount) >= OsGetContainerLimit(type)) { + SCHEDULER_UNLOCK(intSave); + return EINVAL; + } + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +UINT32 OsSetContainerLimit(ContainerType type, UINT32 value) +{ + UINT32 intSave; + + if (value > LOSCFG_KERNEL_CONTAINER_DEFAULT_LIMIT) { + return EINVAL; + } + + SCHEDULER_LOCK(intSave); + switch (type) { +#ifdef LOSCFG_PID_CONTAINER + case PID_CONTAINER: + case PID_CHILD_CONTAINER: + g_containerLimit.pidLimit = value; + break; +#endif +#ifdef LOSCFG_USER_CONTAINER + case USER_CONTAINER: + g_containerLimit.userLimit = value; + break; +#endif +#ifdef LOSCFG_UTS_CONTAINER + case UTS_CONTAINER: + g_containerLimit.utsLimit = value; + break; +#endif +#ifdef LOSCFG_MNT_CONTAINER + case MNT_CONTAINER: + g_containerLimit.mntLimit = value; + break; +#endif +#ifdef LOSCFG_IPC_CONTAINER + case IPC_CONTAINER: + g_containerLimit.ipcLimit = value; + break; +#endif +#ifdef LOSCFG_TIME_CONTAINER + case TIME_CONTAINER: + case TIME_CHILD_CONTAINER: + g_containerLimit.timeLimit = value; + break; +#endif +#ifdef LOSCFG_NET_CONTAINER + case NET_CONTAINER: + g_containerLimit.netLimit = value; + break; +#endif + default: + SCHEDULER_UNLOCK(intSave); + return EINVAL; + } + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +UINT32 OsGetContainerCount(ContainerType type) +{ + switch (type) { +#ifdef LOSCFG_PID_CONTAINER + case PID_CONTAINER: + case PID_CHILD_CONTAINER: + return OsGetPidContainerCount(); +#endif +#ifdef LOSCFG_USER_CONTAINER + case USER_CONTAINER: + return OsGetUserContainerCount(); +#endif +#ifdef LOSCFG_UTS_CONTAINER + case UTS_CONTAINER: + return OsGetUtsContainerCount(); +#endif +#ifdef LOSCFG_MNT_CONTAINER + case MNT_CONTAINER: + return OsGetMntContainerCount(); +#endif +#ifdef LOSCFG_IPC_CONTAINER + case IPC_CONTAINER: + return OsGetIpcContainerCount(); +#endif +#ifdef LOSCFG_TIME_CONTAINER + case TIME_CONTAINER: + case TIME_CHILD_CONTAINER: + return OsGetTimeContainerCount(); +#endif +#ifdef LOSCFG_NET_CONTAINER + case NET_CONTAINER: + return OsGetNetContainerCount(); +#endif + default: + break; + } + return OS_INVALID_VALUE; +} + +VOID OsInitRootContainer(VOID) +{ +#ifdef LOSCFG_USER_CONTAINER + g_containerLimit.userLimit = LOSCFG_KERNEL_CONTAINER_DEFAULT_LIMIT; + OsInitRootUserCredentials(&g_rootCredentials); +#endif +#ifdef LOSCFG_PID_CONTAINER + g_containerLimit.pidLimit = LOSCFG_KERNEL_CONTAINER_DEFAULT_LIMIT; + (VOID)OsInitRootPidContainer(&g_rootContainer.pidContainer); + g_rootContainer.pidForChildContainer = g_rootContainer.pidContainer; +#endif +#ifdef LOSCFG_UTS_CONTAINER + g_containerLimit.utsLimit = LOSCFG_KERNEL_CONTAINER_DEFAULT_LIMIT; + (VOID)OsInitRootUtsContainer(&g_rootContainer.utsContainer); +#endif +#ifdef LOSCFG_MNT_CONTAINER + g_containerLimit.mntLimit = LOSCFG_KERNEL_CONTAINER_DEFAULT_LIMIT; + (VOID)OsInitRootMntContainer(&g_rootContainer.mntContainer); +#endif +#ifdef LOSCFG_IPC_CONTAINER + g_containerLimit.ipcLimit = LOSCFG_KERNEL_CONTAINER_DEFAULT_LIMIT; + (VOID)OsInitRootIpcContainer(&g_rootContainer.ipcContainer); +#endif +#ifdef LOSCFG_TIME_CONTAINER + g_containerLimit.timeLimit = LOSCFG_KERNEL_CONTAINER_DEFAULT_LIMIT; + (VOID)OsInitRootTimeContainer(&g_rootContainer.timeContainer); + g_rootContainer.timeForChildContainer = g_rootContainer.timeContainer; +#endif +#ifdef LOSCFG_NET_CONTAINER + g_containerLimit.netLimit = LOSCFG_KERNEL_CONTAINER_DEFAULT_LIMIT; + (VOID)OsInitRootNetContainer(&g_rootContainer.netContainer); +#endif + return; +} + +STATIC INLINE Container *CreateContainer(VOID) +{ + Container *container = (Container *)LOS_MemAlloc(m_aucSysMem1, sizeof(Container)); + if (container == NULL) { + return NULL; + } + + (VOID)memset_s(container, sizeof(Container), 0, sizeof(Container)); + + LOS_AtomicInc(&container->rc); + return container; +} + +STATIC UINT32 CopyContainers(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent, UINT32 *processID) +{ + UINT32 ret = LOS_OK; + /* Pid container initialization must precede other container initialization. */ +#ifdef LOSCFG_PID_CONTAINER + ret = OsCopyPidContainer(flags, child, parent, processID); + if (ret != LOS_OK) { + return ret; + } +#endif +#ifdef LOSCFG_USER_CONTAINER + ret = OsCopyCredentials(flags, child, parent); + if (ret != LOS_OK) { + return ret; + } +#endif +#ifdef LOSCFG_UTS_CONTAINER + ret = OsCopyUtsContainer(flags, child, parent); + if (ret != LOS_OK) { + return ret; + } +#endif +#ifdef LOSCFG_MNT_CONTAINER + ret = OsCopyMntContainer(flags, child, parent); + if (ret != LOS_OK) { + return ret; + } +#endif +#ifdef LOSCFG_IPC_CONTAINER + ret = OsCopyIpcContainer(flags, child, parent); + if (ret != LOS_OK) { + return ret; + } +#endif +#ifdef LOSCFG_TIME_CONTAINER + ret = OsCopyTimeContainer(flags, child, parent); + if (ret != LOS_OK) { + return ret; + } +#endif +#ifdef LOSCFG_NET_CONTAINER + ret = OsCopyNetContainer(flags, child, parent); + if (ret != LOS_OK) { + return ret; + } +#endif + return ret; +} + +STATIC INLINE UINT32 GetContainerFlagsMask(VOID) +{ + UINT32 mask = 0; +#ifdef LOSCFG_PID_CONTAINER + mask |= CLONE_NEWPID; +#endif +#ifdef LOSCFG_MNT_CONTAINER + mask |= CLONE_NEWNS; +#endif +#ifdef LOSCFG_IPC_CONTAINER + mask |= CLONE_NEWIPC; +#endif +#ifdef LOSCFG_USER_CONTAINER + mask |= CLONE_NEWUSER; +#endif +#ifdef LOSCFG_TIME_CONTAINER + mask |= CLONE_NEWTIME; +#endif +#ifdef LOSCFG_NET_CONTAINER + mask |= CLONE_NEWNET; +#endif +#ifdef LOSCFG_UTS_CONTAINER + mask |= CLONE_NEWUTS; +#endif + return mask; +} + +/* + * called from clone. This now handles copy for Container and all + * namespaces therein. + */ +UINT32 OsCopyContainers(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent, UINT32 *processID) +{ + UINT32 intSave; + +#ifdef LOSCFG_TIME_CONTAINER + flags &= ~CLONE_NEWTIME; +#endif + + if (!(flags & GetContainerFlagsMask())) { +#ifdef LOSCFG_PID_CONTAINER + if (parent->container->pidContainer != parent->container->pidForChildContainer) { + goto CREATE_CONTAINER; + } +#endif +#ifdef LOSCFG_TIME_CONTAINER + if (parent->container->timeContainer != parent->container->timeForChildContainer) { + goto CREATE_CONTAINER; + } +#endif + SCHEDULER_LOCK(intSave); + child->container = parent->container; + LOS_AtomicInc(&child->container->rc); + SCHEDULER_UNLOCK(intSave); + goto COPY_CONTAINERS; + } + +#if defined(LOSCFG_PID_CONTAINER) || defined(LOSCFG_TIME_CONTAINER) +CREATE_CONTAINER: +#endif + child->container = CreateContainer(); + if (child->container == NULL) { + return ENOMEM; + } + +COPY_CONTAINERS: + return CopyContainers(flags, child, parent, processID); +} + +VOID OsContainerFree(LosProcessCB *processCB) +{ + LOS_AtomicDec(&processCB->container->rc); + if (LOS_AtomicRead(&processCB->container->rc) == 0) { + (VOID)LOS_MemFree(m_aucSysMem1, processCB->container); + processCB->container = NULL; + } +} + +VOID OsOsContainersDestroyEarly(LosProcessCB *processCB) +{ + /* All processes in the container must be destroyed before the container is destroyed. */ +#ifdef LOSCFG_PID_CONTAINER + if (processCB->processID == OS_USER_ROOT_PROCESS_ID) { + OsPidContainerDestroyAllProcess(processCB); + } +#endif + +#ifdef LOSCFG_MNT_CONTAINER + OsMntContainerDestroy(processCB->container); +#endif +} + +VOID OsContainersDestroy(LosProcessCB *processCB) +{ +#ifdef LOSCFG_USER_CONTAINER + OsUserContainerDestroy(processCB); +#endif + +#ifdef LOSCFG_UTS_CONTAINER + OsUtsContainerDestroy(processCB->container); +#endif + +#ifdef LOSCFG_IPC_CONTAINER + OsIpcContainerDestroy(processCB->container); +#endif + +#ifdef LOSCFG_TIME_CONTAINER + OsTimeContainerDestroy(processCB->container); +#endif + +#ifdef LOSCFG_NET_CONTAINER + OsNetContainerDestroy(processCB->container); +#endif + +#ifndef LOSCFG_PID_CONTAINER + UINT32 intSave; + SCHEDULER_LOCK(intSave); + OsContainerFree(processCB); + SCHEDULER_UNLOCK(intSave); +#endif +} + +STATIC VOID DeInitContainers(UINT32 flags, Container *container, LosProcessCB *processCB) +{ + UINT32 intSave; + if (container == NULL) { + return; + } + +#ifdef LOSCFG_PID_CONTAINER + SCHEDULER_LOCK(intSave); + if ((flags & CLONE_NEWPID) != 0) { + OsPidContainerDestroy(container, processCB); + } else { + OsPidContainerDestroy(container, NULL); + } + SCHEDULER_UNLOCK(intSave); +#endif + +#ifdef LOSCFG_UTS_CONTAINER + OsUtsContainerDestroy(container); +#endif +#ifdef LOSCFG_MNT_CONTAINER + OsMntContainerDestroy(container); +#endif +#ifdef LOSCFG_IPC_CONTAINER + OsIpcContainerDestroy(container); +#endif + +#ifdef LOSCFG_TIME_CONTAINER + OsTimeContainerDestroy(container); +#endif + +#ifdef LOSCFG_NET_CONTAINER + OsNetContainerDestroy(container); +#endif + + SCHEDULER_LOCK(intSave); + LOS_AtomicDec(&container->rc); + if (LOS_AtomicRead(&container->rc) == 0) { + (VOID)LOS_MemFree(m_aucSysMem1, container); + } + SCHEDULER_UNLOCK(intSave); +} + +UINT32 OsGetContainerID(LosProcessCB *processCB, ContainerType type) +{ + Container *container = processCB->container; + if (container == NULL) { + return OS_INVALID_VALUE; + } + + switch (type) { +#ifdef LOSCFG_PID_CONTAINER + case PID_CONTAINER: + return OsGetPidContainerID(container->pidContainer); + case PID_CHILD_CONTAINER: + return OsGetPidContainerID(container->pidForChildContainer); +#endif +#ifdef LOSCFG_USER_CONTAINER + case USER_CONTAINER: + return OsGetUserContainerID(processCB->credentials); +#endif +#ifdef LOSCFG_UTS_CONTAINER + case UTS_CONTAINER: + return OsGetUtsContainerID(container->utsContainer); +#endif +#ifdef LOSCFG_MNT_CONTAINER + case MNT_CONTAINER: + return OsGetMntContainerID(container->mntContainer); +#endif +#ifdef LOSCFG_IPC_CONTAINER + case IPC_CONTAINER: + return OsGetIpcContainerID(container->ipcContainer); +#endif +#ifdef LOSCFG_TIME_CONTAINER + case TIME_CONTAINER: + return OsGetTimeContainerID(container->timeContainer); + case TIME_CHILD_CONTAINER: + return OsGetTimeContainerID(container->timeForChildContainer); +#endif +#ifdef LOSCFG_NET_CONTAINER + case NET_CONTAINER: + return OsGetNetContainerID(container->netContainer); +#endif + default: + break; + } + return OS_INVALID_VALUE; +} + +STATIC UINT32 UnshareCreateNewContainers(UINT32 flags, LosProcessCB *curr, Container *newContainer) +{ + UINT32 ret = LOS_OK; +#ifdef LOSCFG_PID_CONTAINER + ret = OsUnsharePidContainer(flags, curr, newContainer); + if (ret != LOS_OK) { + return ret; + } +#endif +#ifdef LOSCFG_UTS_CONTAINER + ret = OsUnshareUtsContainer(flags, curr, newContainer); + if (ret != LOS_OK) { + return ret; + } +#endif +#ifdef LOSCFG_MNT_CONTAINER + ret = OsUnshareMntContainer(flags, curr, newContainer); + if (ret != LOS_OK) { + return ret; + } +#endif +#ifdef LOSCFG_IPC_CONTAINER + ret = OsUnshareIpcContainer(flags, curr, newContainer); + if (ret != LOS_OK) { + return ret; + } +#endif +#ifdef LOSCFG_TIME_CONTAINER + ret = OsUnshareTimeContainer(flags, curr, newContainer); + if (ret != LOS_OK) { + return ret; + } +#endif +#ifdef LOSCFG_NET_CONTAINER + ret = OsUnshareNetContainer(flags, curr, newContainer); + if (ret != LOS_OK) { + return ret; + } +#endif + return ret; +} + +INT32 OsUnshare(UINT32 flags) +{ + UINT32 ret; + UINT32 intSave; + LosProcessCB *curr = OsCurrProcessGet(); + Container *oldContainer = curr->container; + UINT32 unshareFlags = GetContainerFlagsMask(); + if (!(flags & unshareFlags) || ((flags & (~unshareFlags)) != 0)) { + return -EINVAL; + } + +#ifdef LOSCFG_USER_CONTAINER + ret = OsUnshareUserCredentials(flags, curr); + if (ret != LOS_OK) { + return ret; + } + if (flags == CLONE_NEWUSER) { + return LOS_OK; + } +#endif + + Container *newContainer = CreateContainer(); + if (newContainer == NULL) { + return -ENOMEM; + } + + ret = UnshareCreateNewContainers(flags, curr, newContainer); + if (ret != LOS_OK) { + goto EXIT; + } + + SCHEDULER_LOCK(intSave); + oldContainer = curr->container; + curr->container = newContainer; + SCHEDULER_UNLOCK(intSave); + + DeInitContainers(flags, oldContainer, NULL); + return LOS_OK; + +EXIT: + DeInitContainers(flags, newContainer, NULL); + return -ret; +} + +STATIC UINT32 SetNsGetFlagByContainerType(UINT32 containerType) +{ + if (containerType >= (UINT32)CONTAINER_MAX) { + return 0; + } + ContainerType type = (ContainerType)containerType; + switch (type) { + case PID_CONTAINER: + case PID_CHILD_CONTAINER: + return CLONE_NEWPID; + case USER_CONTAINER: + return CLONE_NEWUSER; + case UTS_CONTAINER: + return CLONE_NEWUTS; + case MNT_CONTAINER: + return CLONE_NEWNS; + case IPC_CONTAINER: + return CLONE_NEWIPC; + case TIME_CONTAINER: + case TIME_CHILD_CONTAINER: + return CLONE_NEWTIME; + case NET_CONTAINER: + return CLONE_NEWNET; + default: + break; + } + return 0; +} + +STATIC UINT32 SetNsCreateNewContainers(UINT32 flags, Container *newContainer, Container *container) +{ + UINT32 ret = LOS_OK; +#ifdef LOSCFG_PID_CONTAINER + ret = OsSetNsPidContainer(flags, container, newContainer); + if (ret != LOS_OK) { + return ret; + } +#endif +#ifdef LOSCFG_UTS_CONTAINER + ret = OsSetNsUtsContainer(flags, container, newContainer); + if (ret != LOS_OK) { + return ret; + } +#endif +#ifdef LOSCFG_MNT_CONTAINER + ret = OsSetNsMntContainer(flags, container, newContainer); + if (ret != LOS_OK) { + return ret; + } +#endif +#ifdef LOSCFG_IPC_CONTAINER + ret = OsSetNsIpcContainer(flags, container, newContainer); + if (ret != LOS_OK) { + return ret; + } +#endif +#ifdef LOSCFG_TIME_CONTAINER + ret = OsSetNsTimeContainer(flags, container, newContainer); + if (ret != LOS_OK) { + return ret; + } +#endif +#ifdef LOSCFG_NET_CONTAINER + ret = OsSetNsNetContainer(flags, container, newContainer); + if (ret != LOS_OK) { + return ret; + } +#endif + return LOS_OK; +} + +STATIC UINT32 SetNsParamCheck(INT32 fd, INT32 type, UINT32 *flag, LosProcessCB **target) +{ + UINT32 typeMask = GetContainerFlagsMask(); + *flag = (UINT32)(type & typeMask); + UINT32 containerType = 0; + + if (((type & (~typeMask)) != 0)) { + return EINVAL; + } + + LosProcessCB *processCB = (LosProcessCB *)ProcfsContainerGet(fd, &containerType); + if (processCB == NULL) { + return EBADF; + } + + if (*flag == 0) { + *flag = SetNsGetFlagByContainerType(containerType); + } + + if ((*flag == 0) || (*flag != SetNsGetFlagByContainerType(containerType))) { + return EINVAL; + } + + if (processCB == OsCurrProcessGet()) { + return EINVAL; + } + *target = processCB; + return LOS_OK; +} + +INT32 OsSetNs(INT32 fd, INT32 type) +{ + UINT32 intSave, ret; + UINT32 flag = 0; + LosProcessCB *curr = OsCurrProcessGet(); + LosProcessCB *processCB = NULL; + + ret = SetNsParamCheck(fd, type, &flag, &processCB); + if (ret != LOS_OK) { + return -ret; + } + +#ifdef LOSCFG_USER_CONTAINER + if (flag == CLONE_NEWUSER) { + SCHEDULER_LOCK(intSave); + if ((processCB->credentials == NULL) || (processCB->credentials->userContainer == NULL)) { + SCHEDULER_UNLOCK(intSave); + return -EBADF; + } + UserContainer *userContainer = processCB->credentials->userContainer; + ret = OsSetNsUserContainer(userContainer, curr); + SCHEDULER_UNLOCK(intSave); + return ret; + } +#endif + + Container *newContainer = CreateContainer(); + if (newContainer == NULL) { + return -ENOMEM; + } + + SCHEDULER_LOCK(intSave); + Container *targetContainer = processCB->container; + if (targetContainer == NULL) { + SCHEDULER_UNLOCK(intSave); + return -EBADF; + } + + ret = SetNsCreateNewContainers(flag, newContainer, targetContainer); + if (ret != LOS_OK) { + SCHEDULER_UNLOCK(intSave); + goto EXIT; + } + + Container *oldContainer = curr->container; + curr->container = newContainer; + SCHEDULER_UNLOCK(intSave); + DeInitContainers(flag, oldContainer, NULL); + return LOS_OK; + +EXIT: + DeInitContainers(flag, newContainer, curr); + return ret; +} +#endif diff --git a/src/kernel_liteos_a/kernel/extended/container/los_credentials.c b/src/kernel_liteos_a/kernel/extended/container/los_credentials.c new file mode 100644 index 00000000..0a7c3a66 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/container/los_credentials.c @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "los_credentials_pri.h" +#include "los_user_container_pri.h" +#include "los_config.h" +#include "los_memory.h" +#include "los_process_pri.h" + +#ifdef LOSCFG_USER_CONTAINER +STATIC Credentials *CreateNewCredential(LosProcessCB *parent) +{ + UINT32 size = sizeof(Credentials); + Credentials *newCredentials = LOS_MemAlloc(m_aucSysMem1, size); + if (newCredentials == NULL) { + return NULL; + } + + if (parent != NULL) { + const Credentials *oldCredentials = parent->credentials; + (VOID)memcpy_s(newCredentials, sizeof(Credentials), oldCredentials, sizeof(Credentials)); + LOS_AtomicSet(&newCredentials->rc, 1); + } else { + (VOID)memset_s(newCredentials, sizeof(Credentials), 0, sizeof(Credentials)); + LOS_AtomicSet(&newCredentials->rc, 3); /* 3: Three system processes */ + } + newCredentials->userContainer = NULL; + return newCredentials; +} + +Credentials *PrepareCredential(LosProcessCB *runProcessCB) +{ + Credentials *newCredentials = CreateNewCredential(runProcessCB); + if (newCredentials == NULL) { + return NULL; + } + + newCredentials->userContainer = runProcessCB->credentials->userContainer; + LOS_AtomicInc(&newCredentials->userContainer->rc); + return newCredentials; +} + +VOID FreeCredential(Credentials *credentials) +{ + if (credentials == NULL) { + return; + } + + if (credentials->userContainer != NULL) { + LOS_AtomicDec(&credentials->userContainer->rc); + if (LOS_AtomicRead(&credentials->userContainer->rc) <= 0) { + FreeUserContainer(credentials->userContainer); + credentials->userContainer = NULL; + } + } + + LOS_AtomicDec(&credentials->rc); + if (LOS_AtomicRead(&credentials->rc) <= 0) { + (VOID)LOS_MemFree(m_aucSysMem1, credentials); + } +} + +VOID OsUserContainerDestroy(LosProcessCB *curr) +{ + UINT32 intSave; + SCHEDULER_LOCK(intSave); + FreeCredential(curr->credentials); + curr->credentials = NULL; + SCHEDULER_UNLOCK(intSave); + return; +} + +STATIC Credentials *CreateCredentials(unsigned long flags, LosProcessCB *parent) +{ + UINT32 ret; + Credentials *newCredentials = CreateNewCredential(parent); + if (newCredentials == NULL) { + return NULL; + } + + if (!(flags & CLONE_NEWUSER)) { + newCredentials->userContainer = parent->credentials->userContainer; + LOS_AtomicInc(&newCredentials->userContainer->rc); + return newCredentials; + } + + if (parent != NULL) { + ret = OsCreateUserContainer(newCredentials, parent->credentials->userContainer); + } else { + ret = OsCreateUserContainer(newCredentials, NULL); + } + if (ret != LOS_OK) { + FreeCredential(newCredentials); + return NULL; + } + return newCredentials; +} + +UINT32 OsCopyCredentials(unsigned long flags, LosProcessCB *child, LosProcessCB *parent) +{ + UINT32 intSave; + + SCHEDULER_LOCK(intSave); + child->credentials = CreateCredentials(flags, parent); + SCHEDULER_UNLOCK(intSave); + if (child->credentials == NULL) { + return ENOMEM; + } + return LOS_OK; +} + +UINT32 OsInitRootUserCredentials(Credentials **credentials) +{ + *credentials = CreateCredentials(CLONE_NEWUSER, NULL); + if (*credentials == NULL) { + return ENOMEM; + } + return LOS_OK; +} + +UINT32 OsUnshareUserCredentials(UINTPTR flags, LosProcessCB *curr) +{ + UINT32 intSave; + if (!(flags & CLONE_NEWUSER)) { + return LOS_OK; + } + + SCHEDULER_LOCK(intSave); + UINT32 ret = OsCreateUserContainer(curr->credentials, curr->credentials->userContainer); + SCHEDULER_UNLOCK(intSave); + return ret; +} + +UINT32 OsSetNsUserContainer(struct UserContainer *targetContainer, LosProcessCB *runProcess) +{ + Credentials *oldCredentials = runProcess->credentials; + Credentials *newCredentials = CreateNewCredential(runProcess); + if (newCredentials == NULL) { + return ENOMEM; + } + + runProcess->credentials = newCredentials; + newCredentials->userContainer = targetContainer; + LOS_AtomicInc(&targetContainer->rc); + FreeCredential(oldCredentials); + return LOS_OK; +} + +UINT32 OsGetUserContainerID(Credentials *credentials) +{ + if ((credentials == NULL) || (credentials->userContainer == NULL)) { + return OS_INVALID_VALUE; + } + + return credentials->userContainer->containerID; +} + +INT32 CommitCredentials(Credentials *newCredentials) +{ + Credentials *oldCredentials = OsCurrProcessGet()->credentials; + + if (LOS_AtomicRead(&newCredentials->rc) < 1) { + return -EINVAL; + } + + OsCurrProcessGet()->credentials = newCredentials; + FreeCredential(oldCredentials); + return 0; +} + +Credentials *CurrentCredentials(VOID) +{ + return OsCurrProcessGet()->credentials; +} + +UserContainer *OsCurrentUserContainer(VOID) +{ + UserContainer *userContainer = OsCurrProcessGet()->credentials->userContainer; + return userContainer; +} +#endif diff --git a/src/kernel_liteos_a/kernel/extended/container/los_ipc_container.c b/src/kernel_liteos_a/kernel/extended/container/los_ipc_container.c new file mode 100644 index 00000000..d63e2b4f --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/container/los_ipc_container.c @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifdef LOSCFG_IPC_CONTAINER +#include "los_ipc_container_pri.h" +#include "los_config.h" +#include "los_queue_pri.h" +#include "los_vm_shm_pri.h" +#include "los_process_pri.h" +#include "vnode.h" +#include "proc_fs.h" +#include "pthread.h" + +#define IPC_INIT_NUM 3 + +STATIC UINT32 g_currentIpcContainerNum = 0; + +STATIC IpcContainer *CreateNewIpcContainer(IpcContainer *parent) +{ + pthread_mutexattr_t attr; + UINT32 size = sizeof(IpcContainer); + IpcContainer *ipcContainer = (IpcContainer *)LOS_MemAlloc(m_aucSysMem1, size); + if (ipcContainer == NULL) { + return NULL; + } + (VOID)memset_s(ipcContainer, size, 0, size); + + ipcContainer->allQueue = OsAllQueueCBInit(&ipcContainer->freeQueueList); + if (ipcContainer->allQueue == NULL) { + (VOID)LOS_MemFree(m_aucSysMem1, ipcContainer); + return NULL; + } + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP); + pthread_mutex_init(&ipcContainer->mqueueMutex, &attr); + + ipcContainer->shmSegs = OsShmCBInit(&ipcContainer->sysvShmMux, &ipcContainer->shmInfo, + &ipcContainer->shmUsedPageCount); + if (ipcContainer->shmSegs == NULL) { + (VOID)LOS_MemFree(m_aucSysMem1, ipcContainer->allQueue); + (VOID)LOS_MemFree(m_aucSysMem1, ipcContainer); + return NULL; + } + ipcContainer->containerID = OsAllocContainerID(); + + if (parent != NULL) { + LOS_AtomicSet(&ipcContainer->rc, 1); + } else { + LOS_AtomicSet(&ipcContainer->rc, 3); /* 3: Three system processes */ + } + return ipcContainer; +} + +STATIC UINT32 CreateIpcContainer(LosProcessCB *child, LosProcessCB *parent) +{ + UINT32 intSave; + IpcContainer *parentContainer = parent->container->ipcContainer; + IpcContainer *newIpcContainer = CreateNewIpcContainer(parentContainer); + if (newIpcContainer == NULL) { + return ENOMEM; + } + + SCHEDULER_LOCK(intSave); + g_currentIpcContainerNum++; + child->container->ipcContainer = newIpcContainer; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +UINT32 OsInitRootIpcContainer(IpcContainer **ipcContainer) +{ + UINT32 intSave; + IpcContainer *newIpcContainer = CreateNewIpcContainer(NULL); + if (newIpcContainer == NULL) { + return ENOMEM; + } + + SCHEDULER_LOCK(intSave); + g_currentIpcContainerNum++; + *ipcContainer = newIpcContainer; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +UINT32 OsCopyIpcContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent) +{ + UINT32 intSave; + IpcContainer *currIpcContainer = parent->container->ipcContainer; + + if (!(flags & CLONE_NEWIPC)) { + SCHEDULER_LOCK(intSave); + LOS_AtomicInc(&currIpcContainer->rc); + child->container->ipcContainer = currIpcContainer; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; + } + + if (OsContainerLimitCheck(IPC_CONTAINER, &g_currentIpcContainerNum) != LOS_OK) { + return EPERM; + } + + return CreateIpcContainer(child, parent); +} + +UINT32 OsUnshareIpcContainer(UINTPTR flags, LosProcessCB *curr, Container *newContainer) +{ + UINT32 intSave; + IpcContainer *parentContainer = curr->container->ipcContainer; + + if (!(flags & CLONE_NEWIPC)) { + SCHEDULER_LOCK(intSave); + newContainer->ipcContainer = parentContainer; + LOS_AtomicInc(&parentContainer->rc); + SCHEDULER_UNLOCK(intSave); + return LOS_OK; + } + + if (OsContainerLimitCheck(IPC_CONTAINER, &g_currentIpcContainerNum) != LOS_OK) { + return EPERM; + } + + IpcContainer *ipcContainer = CreateNewIpcContainer(parentContainer); + if (ipcContainer == NULL) { + return ENOMEM; + } + + SCHEDULER_LOCK(intSave); + newContainer->ipcContainer = ipcContainer; + g_currentIpcContainerNum++; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +UINT32 OsSetNsIpcContainer(UINT32 flags, Container *container, Container *newContainer) +{ + if (flags & CLONE_NEWIPC) { + newContainer->ipcContainer = container->ipcContainer; + LOS_AtomicInc(&container->ipcContainer->rc); + return LOS_OK; + } + + newContainer->ipcContainer = OsCurrProcessGet()->container->ipcContainer; + LOS_AtomicInc(&newContainer->ipcContainer->rc); + return LOS_OK; +} + +VOID OsIpcContainerDestroy(Container *container) +{ + UINT32 intSave; + if (container == NULL) { + return; + } + + SCHEDULER_LOCK(intSave); + IpcContainer *ipcContainer = container->ipcContainer; + if (ipcContainer == NULL) { + SCHEDULER_UNLOCK(intSave); + return; + } + + LOS_AtomicDec(&ipcContainer->rc); + if (LOS_AtomicRead(&ipcContainer->rc) > 0) { + SCHEDULER_UNLOCK(intSave); + return; + } + + g_currentIpcContainerNum--; + container->ipcContainer = NULL; + SCHEDULER_UNLOCK(intSave); + OsShmCBDestroy(ipcContainer->shmSegs, &ipcContainer->shmInfo, &ipcContainer->sysvShmMux); + ipcContainer->shmSegs = NULL; + OsMqueueCBDestroy(ipcContainer->queueTable); + (VOID)LOS_MemFree(m_aucSysMem1, ipcContainer->allQueue); + (VOID)LOS_MemFree(m_aucSysMem1, ipcContainer); + return; +} + +UINT32 OsGetIpcContainerID(IpcContainer *ipcContainer) +{ + if (ipcContainer == NULL) { + return OS_INVALID_VALUE; + } + + return ipcContainer->containerID; +} + +IpcContainer *OsGetCurrIpcContainer(VOID) +{ + return OsCurrProcessGet()->container->ipcContainer; +} + +UINT32 OsGetIpcContainerCount(VOID) +{ + return g_currentIpcContainerNum; +} +#endif diff --git a/src/kernel_liteos_a/kernel/extended/container/los_mnt_container.c b/src/kernel_liteos_a/kernel/extended/container/los_mnt_container.c new file mode 100644 index 00000000..efa88836 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/container/los_mnt_container.c @@ -0,0 +1,253 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef LOSCFG_MNT_CONTAINER +#include +#include "los_mnt_container_pri.h" +#include "los_container_pri.h" +#include "los_process_pri.h" +#include "sys/mount.h" +#include "vnode.h" +#include "internal.h" + +STATIC UINT32 g_currentMntContainerNum; + +LIST_HEAD *GetContainerMntList(VOID) +{ + return &OsCurrProcessGet()->container->mntContainer->mountList; +} + +STATIC MntContainer *CreateNewMntContainer(MntContainer *parent) +{ + MntContainer *mntContainer = (MntContainer *)LOS_MemAlloc(m_aucSysMem1, sizeof(MntContainer)); + if (mntContainer == NULL) { + return NULL; + } + mntContainer->containerID = OsAllocContainerID(); + LOS_ListInit(&mntContainer->mountList); + + if (parent != NULL) { + LOS_AtomicSet(&mntContainer->rc, 1); + } else { + LOS_AtomicSet(&mntContainer->rc, 3); /* 3: Three system processes */ + } + return mntContainer; +} + +STATIC UINT32 CreateMntContainer(LosProcessCB *child, LosProcessCB *parent) +{ + UINT32 intSave; + MntContainer *parentContainer = parent->container->mntContainer; + MntContainer *newMntContainer = CreateNewMntContainer(parentContainer); + if (newMntContainer == NULL) { + return ENOMEM; + } + + SCHEDULER_LOCK(intSave); + g_currentMntContainerNum++; + child->container->mntContainer = newMntContainer; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +UINT32 OsInitRootMntContainer(MntContainer **mntContainer) +{ + UINT32 intSave; + MntContainer *newMntContainer = CreateNewMntContainer(NULL); + if (newMntContainer == NULL) { + return ENOMEM; + } + + SCHEDULER_LOCK(intSave); + g_currentMntContainerNum++; + *mntContainer = newMntContainer; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +STATIC UINT32 CopyMountList(MntContainer *parentContainer, MntContainer *newContainer) +{ + struct Mount *mnt = NULL; + VnodeHold(); + LOS_DL_LIST_FOR_EACH_ENTRY(mnt, &parentContainer->mountList, struct Mount, mountList) { + struct Mount *newMnt = (struct Mount *)zalloc(sizeof(struct Mount)); + if (newMnt == NULL) { + VnodeDrop(); + return ENOMEM; + } + *newMnt = *mnt; + LOS_ListTailInsert(&newContainer->mountList, &newMnt->mountList); + newMnt->vnodeCovered->mntCount++; + } + VnodeDrop(); + return LOS_OK; +} + +UINT32 OsCopyMntContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent) +{ + UINT32 ret; + UINT32 intSave; + MntContainer *currMntContainer = parent->container->mntContainer; + + if (!(flags & CLONE_NEWNS)) { + SCHEDULER_LOCK(intSave); + LOS_AtomicInc(&currMntContainer->rc); + child->container->mntContainer = currMntContainer; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; + } + + if (OsContainerLimitCheck(MNT_CONTAINER, &g_currentMntContainerNum) != LOS_OK) { + return EPERM; + } + + ret = CreateMntContainer(child, parent); + if (ret != LOS_OK) { + return ret; + } + + return CopyMountList(currMntContainer, child->container->mntContainer); +} + +UINT32 OsUnshareMntContainer(UINTPTR flags, LosProcessCB *curr, Container *newContainer) +{ + UINT32 intSave; + UINT32 ret; + MntContainer *parentContainer = curr->container->mntContainer; + + if (!(flags & CLONE_NEWNS)) { + SCHEDULER_LOCK(intSave); + newContainer->mntContainer = parentContainer; + LOS_AtomicInc(&parentContainer->rc); + SCHEDULER_UNLOCK(intSave); + return LOS_OK; + } + + if (OsContainerLimitCheck(MNT_CONTAINER, &g_currentMntContainerNum) != LOS_OK) { + return EPERM; + } + + MntContainer *mntContainer = CreateNewMntContainer(parentContainer); + if (mntContainer == NULL) { + return ENOMEM; + } + + ret = CopyMountList(parentContainer, mntContainer); + if (ret != LOS_OK) { + (VOID)LOS_MemFree(m_aucSysMem1, mntContainer); + return ret; + } + + SCHEDULER_LOCK(intSave); + newContainer->mntContainer = mntContainer; + g_currentMntContainerNum++; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +UINT32 OsSetNsMntContainer(UINT32 flags, Container *container, Container *newContainer) +{ + if (flags & CLONE_NEWNS) { + newContainer->mntContainer = container->mntContainer; + LOS_AtomicInc(&container->mntContainer->rc); + return LOS_OK; + } + + newContainer->mntContainer = OsCurrProcessGet()->container->mntContainer; + LOS_AtomicInc(&newContainer->mntContainer->rc); + return LOS_OK; +} + +STATIC VOID FreeMountList(LIST_HEAD *mountList) +{ + struct Mount *mnt = NULL; + struct Mount *nextMnt = NULL; + + VnodeHold(); + if (LOS_ListEmpty(mountList)) { + VnodeDrop(); + return; + } + + LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(mnt, nextMnt, mountList, struct Mount, mountList) { + if (mnt->vnodeCovered->mntCount > 0) { + mnt->vnodeCovered->mntCount--; + LOS_ListDelete(&mnt->mountList); + free(mnt); + } else { + umount(mnt->pathName); + } + } + VnodeDrop(); + return; +} + +VOID OsMntContainerDestroy(Container *container) +{ + UINT32 intSave; + if (container == NULL) { + return; + } + + SCHEDULER_LOCK(intSave); + MntContainer *mntContainer = container->mntContainer; + if (mntContainer == NULL) { + SCHEDULER_UNLOCK(intSave); + return; + } + + LOS_AtomicDec(&mntContainer->rc); + if (LOS_AtomicRead(&mntContainer->rc) > 0) { + SCHEDULER_UNLOCK(intSave); + return; + } + + g_currentMntContainerNum--; + SCHEDULER_UNLOCK(intSave); + FreeMountList(&mntContainer->mountList); + container->mntContainer = NULL; + (VOID)LOS_MemFree(m_aucSysMem1, mntContainer); + return; +} + +UINT32 OsGetMntContainerID(MntContainer *mntContainer) +{ + if (mntContainer == NULL) { + return OS_INVALID_VALUE; + } + + return mntContainer->containerID; +} + +UINT32 OsGetMntContainerCount(VOID) +{ + return g_currentMntContainerNum; +} +#endif diff --git a/src/kernel_liteos_a/kernel/extended/container/los_net_container.c b/src/kernel_liteos_a/kernel/extended/container/los_net_container.c new file mode 100644 index 00000000..96dca1f3 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/container/los_net_container.c @@ -0,0 +1,344 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef LOSCFG_NET_CONTAINER +#include +#include "los_net_container_pri.h" +#include "los_config.h" +#include "los_memory.h" +#include "los_process_pri.h" + +STATIC UINT32 g_currentNetContainerNum = 0; +STATIC NetContainer *g_rootNetContainer = NULL; + +STATIC struct netif *NetifAlloc(VOID) +{ + UINT32 size = sizeof(struct netif); + struct netif *netif = LOS_MemAlloc(m_aucSysMem1, size); + if (netif == NULL) { + return NULL; + } + (VOID)memset_s(netif, size, 0, size); + + return netif; +} + +STATIC VOID FreeNetif(struct netif *netif) +{ + if (netif != NULL) { + if (netif->peer != NULL) { + netif_remove(netif->peer); + (VOID)LOS_MemFree(m_aucSysMem1, netif->peer); + } + netif_remove(netif); + (VOID)LOS_MemFree(m_aucSysMem1, netif); + } +} + +STATIC UINT32 CreateVethNetif(NetContainer *netContainer, struct netif **veth) +{ + struct netif *netif = NetifAlloc(); + if (netif == NULL) { + return ENOMEM; + } + + veth_init(netif, netContainer->group); + + *veth = netif; + return LOS_OK; +} + +STATIC UINT32 InitVethPair(NetContainer *netContainer) +{ + struct netif *vethOfNetContainer = NULL; + struct netif *vethOfRootNetContainer = NULL; + + UINT32 ret = CreateVethNetif(netContainer, &vethOfNetContainer); + if (ret != LOS_OK) { + return ret; + } + + ret = CreateVethNetif(g_rootNetContainer, &vethOfRootNetContainer); + if (ret != LOS_OK) { + FreeNetif(vethOfNetContainer); + return ret; + } + + vethOfNetContainer->peer = vethOfRootNetContainer; + vethOfRootNetContainer->peer = vethOfNetContainer; + return LOS_OK; +} + +STATIC UINT32 InitLoopNetif(NetContainer *netContainer) +{ + struct netif *loop_netif = NetifAlloc(); + if (loop_netif == NULL) { + return ENOMEM; + } + + netContainer->group->loop_netif = loop_netif; + netif_init(netContainer->group); + return LOS_OK; +} + +STATIC UINT32 InitContainerNetifs(NetContainer *netContainer) +{ + UINT32 ret = InitLoopNetif(netContainer); + if (ret != LOS_OK) { + return ret; + } + return InitVethPair(netContainer); +} + +STATIC UINT32 InitNetGroup(NetContainer *netContainer) +{ + UINT32 size = sizeof(struct net_group); + struct net_group *group = LOS_MemAlloc(m_aucSysMem1, size); + if (group == NULL) { + return ENOMEM; + } + (VOID)memset_s(group, size, 0, size); + + netContainer->group = group; + return LOS_OK; +} + +STATIC VOID FreeNetContainerGroup(struct net_group *group) +{ + if (group == NULL) { + return; + } + + struct netif *freeNetif = group->netif_list; + struct netif *nextNetif = NULL; + + while (freeNetif != NULL) { + nextNetif = freeNetif->next; + FreeNetif(freeNetif); + freeNetif = nextNetif; + } +} + +VOID OsNetContainerDestroy(Container *container) +{ + UINT32 intSave; + if (container == NULL) { + return; + } + + SCHEDULER_LOCK(intSave); + NetContainer *netContainer = container->netContainer; + if (netContainer == NULL) { + SCHEDULER_UNLOCK(intSave); + return; + } + + LOS_AtomicDec(&netContainer->rc); + if (LOS_AtomicRead(&netContainer->rc) > 0) { + SCHEDULER_UNLOCK(intSave); + return; + } + + g_currentNetContainerNum--; + SCHEDULER_UNLOCK(intSave); + FreeNetContainerGroup(netContainer->group); + container->netContainer = NULL; + (VOID)LOS_MemFree(m_aucSysMem1, netContainer->group); + (VOID)LOS_MemFree(m_aucSysMem1, netContainer); + return; +} + +STATIC NetContainer *CreateNewNetContainer(NetContainer *parent) +{ + NetContainer *netContainer = LOS_MemAlloc(m_aucSysMem1, sizeof(NetContainer)); + if (netContainer == NULL) { + return NULL; + } + (VOID)memset_s(netContainer, sizeof(NetContainer), 0, sizeof(NetContainer)); + + netContainer->containerID = OsAllocContainerID(); + + if (parent != NULL) { + LOS_AtomicSet(&netContainer->rc, 1); + } else { + LOS_AtomicSet(&netContainer->rc, 3); /* 3: Three system processes */ + } + return netContainer; +} + +STATIC UINT32 CreateNetContainer(Container *container, NetContainer *parentContainer) +{ + UINT32 intSave, ret; + NetContainer *newNetContainer = CreateNewNetContainer(parentContainer); + if (newNetContainer == NULL) { + return ENOMEM; + } + + ret = InitNetGroup(newNetContainer); + if (ret != LOS_OK) { + (VOID)LOS_MemFree(m_aucSysMem1, newNetContainer); + return ret; + } + + ret = InitContainerNetifs(newNetContainer); + if (ret != LOS_OK) { + (VOID)LOS_MemFree(m_aucSysMem1, newNetContainer->group); + (VOID)LOS_MemFree(m_aucSysMem1, newNetContainer); + return ret; + } + + SCHEDULER_LOCK(intSave); + g_currentNetContainerNum++; + container->netContainer = newNetContainer; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +UINT32 OsCopyNetContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent) +{ + UINT32 intSave; + NetContainer *currNetContainer = parent->container->netContainer; + + if (!(flags & CLONE_NEWNET)) { + SCHEDULER_LOCK(intSave); + LOS_AtomicInc(&currNetContainer->rc); + child->container->netContainer = currNetContainer; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; + } + + if (OsContainerLimitCheck(NET_CONTAINER, &g_currentNetContainerNum) != LOS_OK) { + return EPERM; + } + + return CreateNetContainer(child->container, currNetContainer); +} + +UINT32 OsUnshareNetContainer(UINTPTR flags, LosProcessCB *curr, Container *newContainer) +{ + UINT32 intSave; + NetContainer *parentContainer = curr->container->netContainer; + + if (!(flags & CLONE_NEWNET)) { + SCHEDULER_LOCK(intSave); + newContainer->netContainer = parentContainer; + LOS_AtomicInc(&parentContainer->rc); + SCHEDULER_UNLOCK(intSave); + return LOS_OK; + } + + if (OsContainerLimitCheck(NET_CONTAINER, &g_currentNetContainerNum) != LOS_OK) { + return EPERM; + } + + return CreateNetContainer(newContainer, parentContainer); +} + +UINT32 OsSetNsNetContainer(UINT32 flags, Container *container, Container *newContainer) +{ + if (flags & CLONE_NEWNET) { + newContainer->netContainer = container->netContainer; + LOS_AtomicInc(&container->netContainer->rc); + return LOS_OK; + } + + newContainer->netContainer = OsCurrProcessGet()->container->netContainer; + LOS_AtomicInc(&newContainer->netContainer->rc); + return LOS_OK; +} + +UINT32 OsGetNetContainerID(NetContainer *netContainer) +{ + if (netContainer == NULL) { + return OS_INVALID_VALUE; + } + + return netContainer->containerID; +} + +STATIC struct net_group *DoGetNetGroupFromCurrProcess(VOID) +{ + LosProcessCB *processCB = OsCurrProcessGet(); + NetContainer *netContainer = processCB->container->netContainer; + return netContainer->group; +} + +STATIC VOID DoSetNetifNetGroup(struct netif *netif, struct net_group *group) +{ + netif->group = group; +} + +STATIC struct net_group *DoGetNetGroupFromNetif(struct netif *netif) +{ + return netif != NULL ? netif->group : NULL; +} + +STATIC VOID DoSetIppcbNetGroup(struct ip_pcb *pcb, struct net_group *group) +{ + pcb->group = group; +} + +STATIC struct net_group *DoGetNetGroupFromIppcb(struct ip_pcb *pcb) +{ + return pcb != NULL ? pcb->group : NULL; +} + +struct net_group_ops netGroupOps = { + .get_curr_process_net_group = DoGetNetGroupFromCurrProcess, + .set_netif_net_group = DoSetNetifNetGroup, + .get_net_group_from_netif = DoGetNetGroupFromNetif, + .set_ippcb_net_group = DoSetIppcbNetGroup, + .get_net_group_from_ippcb = DoGetNetGroupFromIppcb, +}; + +UINT32 OsInitRootNetContainer(NetContainer **netContainer) +{ + UINT32 intSave; + NetContainer *newNetContainer = CreateNewNetContainer(NULL); + if (newNetContainer == NULL) { + return ENOMEM; + } + + newNetContainer->group = get_root_net_group(); + set_default_net_group_ops(&netGroupOps); + + SCHEDULER_LOCK(intSave); + g_currentNetContainerNum++; + *netContainer = newNetContainer; + g_rootNetContainer = newNetContainer; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +UINT32 OsGetNetContainerCount(VOID) +{ + return g_currentNetContainerNum; +} +#endif diff --git a/src/kernel_liteos_a/kernel/extended/container/los_pid_container.c b/src/kernel_liteos_a/kernel/extended/container/los_pid_container.c new file mode 100644 index 00000000..ba0bf9e4 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/container/los_pid_container.c @@ -0,0 +1,623 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "los_pid_container_pri.h" +#include "los_config.h" +#include "los_process_pri.h" +#include "los_container_pri.h" + +#ifdef LOSCFG_PID_CONTAINER + +STATIC UINT32 g_currentPidContainerNum; +STATIC LosProcessCB *g_defaultProcessCB = NULL; +STATIC LosTaskCB *g_defaultTaskCB = NULL; + +STATIC VOID FreeVpid(LosProcessCB *processCB) +{ + PidContainer *pidContainer = processCB->container->pidContainer; + UINT32 vpid = processCB->processID; + + while ((pidContainer != NULL) && !OS_PID_CHECK_INVALID(vpid)) { + ProcessVid *processVid = &pidContainer->pidArray[vpid]; + processVid->cb = (UINTPTR)g_defaultProcessCB; + vpid = processVid->vpid; + processVid->vpid = OS_INVALID_VALUE; + LOS_ListTailInsert(&pidContainer->pidFreeList, &processVid->node); + LOS_AtomicDec(&pidContainer->rc); + PidContainer *parentPidContainer = pidContainer->parent; + if (LOS_AtomicRead(&pidContainer->rc) > 0) { + pidContainer = parentPidContainer; + continue; + } + g_currentPidContainerNum--; + (VOID)LOS_MemFree(m_aucSysMem1, pidContainer->rootPGroup); + (VOID)LOS_MemFree(m_aucSysMem1, pidContainer); + if (pidContainer == processCB->container->pidContainer) { + processCB->container->pidContainer = NULL; + } + pidContainer = parentPidContainer; + } +} + +STATIC ProcessVid *OsGetFreeVpid(PidContainer *pidContainer) +{ + if (LOS_ListEmpty(&pidContainer->pidFreeList)) { + return NULL; + } + + ProcessVid *vpid = LOS_DL_LIST_ENTRY(LOS_DL_LIST_FIRST(&pidContainer->pidFreeList), ProcessVid, node); + LOS_ListDelete(&vpid->node); + return vpid; +} + +UINT32 OsAllocSpecifiedVpidUnsafe(UINT32 vpid, PidContainer *pidContainer, + LosProcessCB *processCB, LosProcessCB *parent) +{ + if ((pidContainer == NULL) || OS_PID_CHECK_INVALID(vpid)) { + return OS_INVALID_VALUE; + } + + if (LOS_AtomicRead(&pidContainer->lock) > 0) { + return OS_INVALID_VALUE; + } + + ProcessVid *processVid = &pidContainer->pidArray[vpid]; + if (processVid->cb != (UINTPTR)g_defaultProcessCB) { + return OS_INVALID_VALUE; + } + + processVid->cb = (UINTPTR)processCB; + processVid->realParent = parent; + processCB->processID = vpid; + LOS_ListDelete(&processVid->node); + LOS_AtomicInc(&pidContainer->rc); + + if (vpid == OS_USER_ROOT_PROCESS_ID) { + if (parent != NULL) { + ProcessVid *vppidItem = &pidContainer->pidArray[0]; + LOS_ListDelete(&vppidItem->node); + vppidItem->cb = (UINTPTR)parent; + } + + if (OsCreateProcessGroup(processCB) == NULL) { + return OS_INVALID_VALUE; + } + } + + pidContainer = pidContainer->parent; + while (pidContainer != NULL) { + ProcessVid *item = OsGetFreeVpid(pidContainer); + if (item == NULL) { + break; + } + + item->cb = (UINTPTR)processCB; + processVid->vpid = item->vid; + LOS_AtomicInc(&pidContainer->rc); + processVid = item; + pidContainer = pidContainer->parent; + } + return processCB->processID; +} + +STATIC UINT32 OsAllocVpid(LosProcessCB *processCB, LosProcessCB *parent) +{ + ProcessVid *oldProcessVid = NULL; + PidContainer *pidContainer = processCB->container->pidContainer; + if ((pidContainer == NULL) || (LOS_AtomicRead(&pidContainer->lock) > 0)) { + return OS_INVALID_VALUE; + } + + processCB->processID = OS_INVALID_VALUE; + do { + ProcessVid *vpid = OsGetFreeVpid(pidContainer); + if (vpid == NULL) { + break; + } + vpid->cb = (UINTPTR)processCB; + if (processCB->processID == OS_INVALID_VALUE) { + processCB->processID = vpid->vid; + vpid->realParent = parent; + } else { + oldProcessVid->vpid = vpid->vid; + } + LOS_AtomicInc(&pidContainer->rc); + oldProcessVid = vpid; + pidContainer = pidContainer->parent; + } while (pidContainer != NULL); + return processCB->processID; +} + +STATIC ProcessVid *OsGetFreeVtid(PidContainer *pidContainer) +{ + if (LOS_ListEmpty(&pidContainer->tidFreeList)) { + return NULL; + } + + ProcessVid *vtid = LOS_DL_LIST_ENTRY(LOS_DL_LIST_FIRST(&pidContainer->tidFreeList), ProcessVid, node); + LOS_ListDelete(&vtid->node); + return vtid; +} + +VOID OsFreeVtid(LosTaskCB *taskCB) +{ + PidContainer *pidContainer = taskCB->pidContainer; + UINT32 vtid = taskCB->taskID; + + while ((pidContainer != NULL) && !OS_TID_CHECK_INVALID(vtid)) { + ProcessVid *item = &pidContainer->tidArray[vtid]; + item->cb = (UINTPTR)g_defaultTaskCB; + vtid = item->vpid; + item->vpid = OS_INVALID_VALUE; + item->realParent = NULL; + LOS_ListTailInsert(&pidContainer->tidFreeList, &item->node); + pidContainer = pidContainer->parent; + } + taskCB->pidContainer = NULL; +} + +UINT32 OsAllocVtid(LosTaskCB *taskCB, const LosProcessCB *processCB) +{ + PidContainer *pidContainer = processCB->container->pidContainer; + ProcessVid *oldTaskVid = NULL; + + do { + ProcessVid *item = OsGetFreeVtid(pidContainer); + if (item == NULL) { + return OS_INVALID_VALUE; + } + + if ((pidContainer->parent != NULL) && (item->vid == 0)) { + item->cb = (UINTPTR)OsCurrTaskGet(); + item->vpid = OsCurrTaskGet()->taskID; + continue; + } + + item->cb = (UINTPTR)taskCB; + if (taskCB->pidContainer == NULL) { + taskCB->pidContainer = pidContainer; + taskCB->taskID = item->vid; + } else { + oldTaskVid->vpid = item->vid; + } + oldTaskVid = item; + pidContainer = pidContainer->parent; + } while (pidContainer != NULL); + + return taskCB->taskID; +} + +VOID OsPidContainerDestroyAllProcess(LosProcessCB *curr) +{ + INT32 ret; + UINT32 intSave; + PidContainer *pidContainer = curr->container->pidContainer; + LOS_AtomicInc(&pidContainer->lock); + + for (UINT32 index = 2; index < LOSCFG_BASE_CORE_PROCESS_LIMIT; index++) { /* 2: ordinary process */ + SCHEDULER_LOCK(intSave); + LosProcessCB *processCB = OS_PCB_FROM_PID(index); + if (OsProcessIsUnused(processCB) || (processCB->parentProcess == NULL)) { + SCHEDULER_UNLOCK(intSave); + continue; + } + + if (curr != processCB->parentProcess) { + LOS_ListDelete(&processCB->siblingList); + if (OsProcessIsInactive(processCB)) { + LOS_ListTailInsert(&curr->exitChildList, &processCB->siblingList); + } else { + LOS_ListTailInsert(&curr->childrenList, &processCB->siblingList); + } + processCB->parentProcess = curr; + } + SCHEDULER_UNLOCK(intSave); + + ret = OsKillLock(index, SIGKILL); + if (ret < 0) { + PRINT_ERR("Pid container kill all process failed, pid %u, errno=%d\n", index, -ret); + } + + ret = LOS_Wait(index, NULL, 0, NULL); + if (ret != index) { + PRINT_ERR("Pid container wait pid %d failed, errno=%d\n", index, -ret); + } + } +} + +STATIC PidContainer *CreateNewPidContainer(PidContainer *parent) +{ + UINT32 index; + PidContainer *newPidContainer = (PidContainer *)LOS_MemAlloc(m_aucSysMem1, sizeof(PidContainer)); + if (newPidContainer == NULL) { + return NULL; + } + (VOID)memset_s(newPidContainer, sizeof(PidContainer), 0, sizeof(PidContainer)); + + newPidContainer->containerID = OsAllocContainerID(); + LOS_ListInit(&newPidContainer->pidFreeList); + for (index = 0; index < LOSCFG_BASE_CORE_PROCESS_LIMIT; index++) { + ProcessVid *vpid = &newPidContainer->pidArray[index]; + vpid->vid = index; + vpid->vpid = OS_INVALID_VALUE; + vpid->cb = (UINTPTR)g_defaultProcessCB; + LOS_ListTailInsert(&newPidContainer->pidFreeList, &vpid->node); + } + + LOS_ListInit(&newPidContainer->tidFreeList); + for (index = 0; index < LOSCFG_BASE_CORE_TSK_LIMIT; index++) { + ProcessVid *vtid = &newPidContainer->tidArray[index]; + vtid->vid = index; + vtid->vpid = OS_INVALID_VALUE; + vtid->cb = (UINTPTR)g_defaultTaskCB; + LOS_ListTailInsert(&newPidContainer->tidFreeList, &vtid->node); + } + + newPidContainer->parent = parent; + if (parent != NULL) { + LOS_AtomicSet(&newPidContainer->level, parent->level + 1); + newPidContainer->referenced = FALSE; + } else { + LOS_AtomicSet(&newPidContainer->level, 0); + newPidContainer->referenced = TRUE; + } + return newPidContainer; +} + +VOID OsPidContainerDestroy(Container *container, LosProcessCB *processCB) +{ + if (container == NULL) { + return; + } + + PidContainer *pidContainer = container->pidContainer; + if (pidContainer == NULL) { + return; + } + + if (processCB != NULL) { + FreeVpid(processCB); + } + + if ((container->pidForChildContainer != NULL) && (pidContainer != container->pidForChildContainer)) { + LOS_AtomicDec(&container->pidForChildContainer->rc); + if (LOS_AtomicRead(&container->pidForChildContainer->rc) <= 0) { + g_currentPidContainerNum--; + (VOID)LOS_MemFree(m_aucSysMem1, container->pidForChildContainer); + container->pidForChildContainer = NULL; + } + } + + if ((container->pidContainer != NULL) && (LOS_AtomicRead(&pidContainer->rc) <= 0)) { + g_currentPidContainerNum--; + container->pidContainer = NULL; + container->pidForChildContainer = NULL; + (VOID)LOS_MemFree(m_aucSysMem1, pidContainer->rootPGroup); + (VOID)LOS_MemFree(m_aucSysMem1, pidContainer); + } + + if (processCB != NULL) { + OsContainerFree(processCB); + } +} + +STATIC UINT32 CreatePidContainer(LosProcessCB *child, LosProcessCB *parent) +{ + UINT32 ret; + UINT32 intSave; + + PidContainer *parentContainer = parent->container->pidContainer; + PidContainer *newPidContainer = CreateNewPidContainer(parentContainer); + if (newPidContainer == NULL) { + return ENOMEM; + } + + SCHEDULER_LOCK(intSave); + if ((parentContainer->level + 1) >= PID_CONTAINER_LEVEL_LIMIT) { + (VOID)LOS_MemFree(m_aucSysMem1, newPidContainer); + SCHEDULER_UNLOCK(intSave); + return EINVAL; + } + + g_currentPidContainerNum++; + newPidContainer->referenced = TRUE; + child->container->pidContainer = newPidContainer; + child->container->pidForChildContainer = newPidContainer; + ret = OsAllocSpecifiedVpidUnsafe(OS_USER_ROOT_PROCESS_ID, newPidContainer, child, parent); + if (ret == OS_INVALID_VALUE) { + g_currentPidContainerNum--; + FreeVpid(child); + child->container->pidContainer = NULL; + child->container->pidForChildContainer = NULL; + SCHEDULER_UNLOCK(intSave); + (VOID)LOS_MemFree(m_aucSysMem1, newPidContainer); + return ENOSPC; + } + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +STATIC UINT32 AllocVpidFormPidForChildContainer(LosProcessCB *child, LosProcessCB *parent) +{ + UINT32 ret; + PidContainer *pidContainer = parent->container->pidForChildContainer; + child->container->pidContainer = pidContainer; + child->container->pidForChildContainer = pidContainer; + + if (!pidContainer->referenced) { + pidContainer->referenced = TRUE; + ret = OsAllocSpecifiedVpidUnsafe(OS_USER_ROOT_PROCESS_ID, pidContainer, child, parent); + } else { + ret = OsAllocVpid(child, parent); + if (ret != OS_INVALID_VALUE) { + LosProcessCB *parentProcessCB = (LosProcessCB *)pidContainer->pidArray[OS_USER_ROOT_PROCESS_ID].cb; + child->parentProcess = parentProcessCB; + LOS_ListTailInsert(&parentProcessCB->childrenList, &child->siblingList); + child->pgroup = parentProcessCB->pgroup; + LOS_ListTailInsert(&parentProcessCB->pgroup->processList, &child->subordinateGroupList); + } + } + + if (ret == OS_INVALID_VALUE) { + FreeVpid(child); + child->container->pidContainer = NULL; + child->container->pidForChildContainer = NULL; + return ENOSPC; + } + + return LOS_OK; +} + +UINT32 OsCopyPidContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent, UINT32 *processID) +{ + UINT32 ret; + UINT32 intSave; + + SCHEDULER_LOCK(intSave); + PidContainer *parentPidContainer = parent->container->pidContainer; + PidContainer *parentPidContainerForChild = parent->container->pidForChildContainer; + if (parentPidContainer == parentPidContainerForChild) { + /* The current process is not executing unshare */ + if (!(flags & CLONE_NEWPID)) { + child->container->pidContainer = parentPidContainer; + child->container->pidForChildContainer = parentPidContainer; + ret = OsAllocVpid(child, parent); + SCHEDULER_UNLOCK(intSave); + if (ret == OS_INVALID_VALUE) { + PRINT_ERR("[%s] alloc vpid failed\n", __FUNCTION__); + return ENOSPC; + } + *processID = child->processID; + return LOS_OK; + } + SCHEDULER_UNLOCK(intSave); + + if (OsContainerLimitCheck(PID_CONTAINER, &g_currentPidContainerNum) != LOS_OK) { + return EPERM; + } + + ret = CreatePidContainer(child, parent); + if (ret != LOS_OK) { + return ret; + } + } else { + /* Create the first process after unshare */ + ret = AllocVpidFormPidForChildContainer(child, parent); + SCHEDULER_UNLOCK(intSave); + if (ret != LOS_OK) { + return ret; + } + } + + PidContainer *pidContainer = child->container->pidContainer; + if (pidContainer->pidArray[child->processID].vpid == OS_INVALID_VALUE) { + *processID = child->processID; + } else { + *processID = pidContainer->pidArray[child->processID].vpid; + } + return LOS_OK; +} + +UINT32 OsUnsharePidContainer(UINTPTR flags, LosProcessCB *curr, Container *newContainer) +{ + UINT32 intSave; + if (!(flags & CLONE_NEWPID)) { + SCHEDULER_LOCK(intSave); + newContainer->pidContainer = curr->container->pidContainer; + newContainer->pidForChildContainer = curr->container->pidForChildContainer; + if (newContainer->pidContainer != newContainer->pidForChildContainer) { + LOS_AtomicInc(&newContainer->pidForChildContainer->rc); + } + SCHEDULER_UNLOCK(intSave); + return LOS_OK; + } + + if (OsContainerLimitCheck(PID_CONTAINER, &g_currentPidContainerNum) != LOS_OK) { + return EPERM; + } + + PidContainer *pidForChild = CreateNewPidContainer(curr->container->pidContainer); + if (pidForChild == NULL) { + return ENOMEM; + } + + SCHEDULER_LOCK(intSave); + if (curr->container->pidContainer != curr->container->pidForChildContainer) { + SCHEDULER_UNLOCK(intSave); + (VOID)LOS_MemFree(m_aucSysMem1, pidForChild); + return EINVAL; + } + + if (pidForChild->level >= PID_CONTAINER_LEVEL_LIMIT) { + SCHEDULER_UNLOCK(intSave); + (VOID)LOS_MemFree(m_aucSysMem1, pidForChild); + return EINVAL; + } + + g_currentPidContainerNum++; + newContainer->pidContainer = curr->container->pidContainer; + newContainer->pidForChildContainer = pidForChild; + LOS_AtomicSet(&pidForChild->rc, 1); + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +UINT32 OsSetNsPidContainer(UINT32 flags, Container *container, Container *newContainer) +{ + UINT32 ret = LOS_OK; + LosProcessCB *curr = OsCurrProcessGet(); + newContainer->pidContainer = curr->container->pidContainer; + + if (flags & CLONE_NEWPID) { + newContainer->pidForChildContainer = container->pidContainer; + LOS_AtomicInc(&container->pidContainer->rc); + return ret; + } + + newContainer->pidForChildContainer = curr->container->pidForChildContainer; + if (newContainer->pidContainer != newContainer->pidForChildContainer) { + LOS_AtomicInc(&newContainer->pidForChildContainer->rc); + } + return LOS_OK; +} + +UINT32 OsInitRootPidContainer(PidContainer **pidContainer) +{ + UINT32 intSave; + g_defaultTaskCB = OsGetDefaultTaskCB(); + g_defaultProcessCB = OsGetDefaultProcessCB(); + + PidContainer *newPidContainer = CreateNewPidContainer(NULL); + if (newPidContainer == NULL) { + return ENOMEM; + } + + SCHEDULER_LOCK(intSave); + g_currentPidContainerNum++; + *pidContainer = newPidContainer; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +UINT32 OsGetVpidFromCurrContainer(const LosProcessCB *processCB) +{ + UINT32 vpid = processCB->processID; + PidContainer *pidContainer = processCB->container->pidContainer; + PidContainer *currPidContainer = OsCurrTaskGet()->pidContainer; + while (pidContainer != NULL) { + ProcessVid *vid = &pidContainer->pidArray[vpid]; + if (currPidContainer != pidContainer) { + vpid = vid->vpid; + pidContainer = pidContainer->parent; + continue; + } + + return vid->vid; + } + return OS_INVALID_VALUE; +} + +UINT32 OsGetVpidFromRootContainer(const LosProcessCB *processCB) +{ + UINT32 vpid = processCB->processID; + PidContainer *pidContainer = processCB->container->pidContainer; + while (pidContainer != NULL) { + ProcessVid *vid = &pidContainer->pidArray[vpid]; + if (pidContainer->parent != NULL) { + vpid = vid->vpid; + pidContainer = pidContainer->parent; + continue; + } + + return vid->vid; + } + return OS_INVALID_VALUE; +} + +UINT32 OsGetVtidFromCurrContainer(const LosTaskCB *taskCB) +{ + UINT32 vtid = taskCB->taskID; + PidContainer *pidContainer = taskCB->pidContainer; + PidContainer *currPidContainer = OsCurrTaskGet()->pidContainer; + while (pidContainer != NULL) { + ProcessVid *vid = &pidContainer->tidArray[vtid]; + if (currPidContainer != pidContainer) { + vtid = vid->vpid; + pidContainer = pidContainer->parent; + continue; + } + return vid->vid; + } + return OS_INVALID_VALUE; +} + +LosProcessCB *OsGetPCBFromVpid(UINT32 vpid) +{ + PidContainer *pidContainer = OsCurrTaskGet()->pidContainer; + ProcessVid *processVid = &pidContainer->pidArray[vpid]; + return (LosProcessCB *)processVid->cb; +} + +LosTaskCB *OsGetTCBFromVtid(UINT32 vtid) +{ + PidContainer *pidContainer = OsCurrTaskGet()->pidContainer; + ProcessVid *taskVid = &pidContainer->tidArray[vtid]; + return (LosTaskCB *)taskVid->cb; +} + +BOOL OsPidContainerProcessParentIsRealParent(const LosProcessCB *processCB, const LosProcessCB *curr) +{ + if (curr == processCB->parentProcess) { + return FALSE; + } + + PidContainer *pidContainer = processCB->container->pidContainer; + ProcessVid *processVid = &pidContainer->pidArray[processCB->processID]; + if (processVid->realParent == curr) { + return TRUE; + } + return FALSE; +} + +UINT32 OsGetPidContainerID(PidContainer *pidContainer) +{ + if (pidContainer == NULL) { + return OS_INVALID_VALUE; + } + + return pidContainer->containerID; +} + +UINT32 OsGetPidContainerCount(VOID) +{ + return g_currentPidContainerNum; +} +#endif diff --git a/src/kernel_liteos_a/kernel/extended/container/los_time_container.c b/src/kernel_liteos_a/kernel/extended/container/los_time_container.c new file mode 100644 index 00000000..78bc8482 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/container/los_time_container.c @@ -0,0 +1,258 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "los_time_container_pri.h" +#include "los_process_pri.h" + +#ifdef LOSCFG_TIME_CONTAINER +STATIC UINT32 g_currentTimeContainerNum; + +STATIC TimeContainer *CreateNewTimeContainer(TimeContainer *parent) +{ + UINT32 size = sizeof(TimeContainer); + TimeContainer *timeContainer = (TimeContainer *)LOS_MemAlloc(m_aucSysMem1, size); + if (timeContainer == NULL) { + return NULL; + } + (VOID)memset_s(timeContainer, size, 0, size); + + timeContainer->containerID = OsAllocContainerID(); + if (parent != NULL) { + timeContainer->frozenOffsets = FALSE; + LOS_AtomicSet(&timeContainer->rc, 1); + } else { + timeContainer->frozenOffsets = TRUE; + LOS_AtomicSet(&timeContainer->rc, 3); /* 3: Three system processes */ + } + return timeContainer; +} + +STATIC UINT32 CreateTimeContainer(LosProcessCB *child, LosProcessCB *parent) +{ + UINT32 intSave; + + SCHEDULER_LOCK(intSave); + TimeContainer *newTimeContainer = parent->container->timeForChildContainer; + LOS_AtomicInc(&newTimeContainer->rc); + newTimeContainer->frozenOffsets = TRUE; + child->container->timeContainer = newTimeContainer; + child->container->timeForChildContainer = newTimeContainer; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +UINT32 OsInitRootTimeContainer(TimeContainer **timeContainer) +{ + UINT32 intSave; + TimeContainer *newTimeContainer = CreateNewTimeContainer(NULL); + if (newTimeContainer == NULL) { + return ENOMEM; + } + + SCHEDULER_LOCK(intSave); + *timeContainer = newTimeContainer; + g_currentTimeContainerNum++; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +UINT32 OsCopyTimeContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent) +{ + UINT32 intSave; + TimeContainer *currTimeContainer = parent->container->timeContainer; + + if (currTimeContainer == parent->container->timeForChildContainer) { + SCHEDULER_LOCK(intSave); + LOS_AtomicInc(&currTimeContainer->rc); + child->container->timeContainer = currTimeContainer; + child->container->timeForChildContainer = currTimeContainer; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; + } + + if (OsContainerLimitCheck(TIME_CONTAINER, &g_currentTimeContainerNum) != LOS_OK) { + return EPERM; + } + + return CreateTimeContainer(child, parent); +} + +UINT32 OsUnshareTimeContainer(UINTPTR flags, LosProcessCB *curr, Container *newContainer) +{ + UINT32 intSave; + if (!(flags & CLONE_NEWTIME)) { + SCHEDULER_LOCK(intSave); + newContainer->timeContainer = curr->container->timeContainer; + newContainer->timeForChildContainer = curr->container->timeForChildContainer; + LOS_AtomicInc(&newContainer->timeContainer->rc); + if (newContainer->timeContainer != newContainer->timeForChildContainer) { + LOS_AtomicInc(&newContainer->timeForChildContainer->rc); + } + SCHEDULER_UNLOCK(intSave); + return LOS_OK; + } + + if (OsContainerLimitCheck(TIME_CONTAINER, &g_currentTimeContainerNum) != LOS_OK) { + return EPERM; + } + + TimeContainer *timeForChild = CreateNewTimeContainer(curr->container->timeContainer); + if (timeForChild == NULL) { + return ENOMEM; + } + + SCHEDULER_LOCK(intSave); + if (curr->container->timeContainer != curr->container->timeForChildContainer) { + SCHEDULER_UNLOCK(intSave); + (VOID)LOS_MemFree(m_aucSysMem1, timeForChild); + return EINVAL; + } + + (VOID)memcpy_s(&timeForChild->monotonic, sizeof(struct timespec64), + &curr->container->timeContainer->monotonic, sizeof(struct timespec64)); + newContainer->timeContainer = curr->container->timeContainer; + LOS_AtomicInc(&newContainer->timeContainer->rc); + newContainer->timeForChildContainer = timeForChild; + g_currentTimeContainerNum++; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +UINT32 OsSetNsTimeContainer(UINT32 flags, Container *container, Container *newContainer) +{ + LosProcessCB *curr = OsCurrProcessGet(); + if (flags & CLONE_NEWTIME) { + container->timeContainer->frozenOffsets = TRUE; + newContainer->timeContainer = container->timeContainer; + newContainer->timeForChildContainer = container->timeContainer; + LOS_AtomicInc(&container->timeContainer->rc); + return LOS_OK; + } + + newContainer->timeContainer = curr->container->timeContainer; + LOS_AtomicInc(&curr->container->timeContainer->rc); + newContainer->timeForChildContainer = curr->container->timeForChildContainer; + if (curr->container->timeContainer != curr->container->timeForChildContainer) { + LOS_AtomicInc(&curr->container->timeForChildContainer->rc); + } + return LOS_OK; +} + +VOID OsTimeContainerDestroy(Container *container) +{ + UINT32 intSave; + TimeContainer *timeContainer = NULL; + TimeContainer *timeForChild = NULL; + + if (container == NULL) { + return; + } + + SCHEDULER_LOCK(intSave); + if (container->timeContainer == NULL) { + SCHEDULER_UNLOCK(intSave); + return; + } + + if ((container->timeForChildContainer != NULL) && (container->timeContainer != container->timeForChildContainer)) { + LOS_AtomicDec(&container->timeForChildContainer->rc); + if (LOS_AtomicRead(&container->timeForChildContainer->rc) <= 0) { + g_currentTimeContainerNum--; + timeForChild = container->timeForChildContainer; + container->timeForChildContainer = NULL; + } + } + + LOS_AtomicDec(&container->timeContainer->rc); + if (LOS_AtomicRead(&container->timeContainer->rc) <= 0) { + g_currentTimeContainerNum--; + timeContainer = container->timeContainer; + container->timeContainer = NULL; + container->timeForChildContainer = NULL; + } + SCHEDULER_UNLOCK(intSave); + (VOID)LOS_MemFree(m_aucSysMem1, timeForChild); + (VOID)LOS_MemFree(m_aucSysMem1, timeContainer); + return; +} + +UINT32 OsGetTimeContainerID(TimeContainer *timeContainer) +{ + if (timeContainer == NULL) { + return OS_INVALID_VALUE; + } + + return timeContainer->containerID; +} + +TimeContainer *OsGetCurrTimeContainer(VOID) +{ + return OsCurrProcessGet()->container->timeContainer; +} + +UINT32 OsGetTimeContainerMonotonic(LosProcessCB *processCB, struct timespec64 *offsets) +{ + if ((processCB == NULL) || (offsets == NULL)) { + return EINVAL; + } + + if (OsProcessIsInactive(processCB)) { + return ESRCH; + } + + TimeContainer *timeContainer = processCB->container->timeForChildContainer; + (VOID)memcpy_s(offsets, sizeof(struct timespec64), &timeContainer->monotonic, sizeof(struct timespec64)); + return LOS_OK; +} + +UINT32 OsSetTimeContainerMonotonic(LosProcessCB *processCB, struct timespec64 *offsets) +{ + if ((processCB == NULL) || (offsets == NULL)) { + return EINVAL; + } + + if (OsProcessIsInactive(processCB)) { + return ESRCH; + } + + TimeContainer *timeContainer = processCB->container->timeForChildContainer; + if (timeContainer->frozenOffsets) { + return EACCES; + } + + timeContainer->monotonic.tv_sec = offsets->tv_sec; + timeContainer->monotonic.tv_nsec = offsets->tv_nsec; + return LOS_OK; +} + +UINT32 OsGetTimeContainerCount(VOID) +{ + return g_currentTimeContainerNum; +} +#endif diff --git a/src/kernel_liteos_a/kernel/extended/container/los_user_container.c b/src/kernel_liteos_a/kernel/extended/container/los_user_container.c new file mode 100644 index 00000000..8ca9c258 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/container/los_user_container.c @@ -0,0 +1,439 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef LOSCFG_USER_CONTAINER +#include "los_user_container_pri.h" +#include "errno.h" +#include "ctype.h" +#include "los_config.h" +#include "los_memory.h" +#include "proc_fs.h" +#include "user_copy.h" +#include "los_seq_buf.h" +#include "capability_type.h" +#include "capability_api.h" +#include "internal.h" + +#define DEFAULT_OVERFLOWUID 65534 +#define DEFAULT_OVERFLOWGID 65534 +#define LEVEL_MAX 3 +#define HEX 16 +#define OCT 8 +#define DEC 10 + +UINT32 g_currentUserContainerNum = 0; + +UINT32 OsCreateUserContainer(Credentials *newCredentials, UserContainer *parentUserContainer) +{ + if (g_currentUserContainerNum >= OsGetContainerLimit(USER_CONTAINER)) { + return EPERM; + } + + if ((parentUserContainer != NULL) && (parentUserContainer->level >= LEVEL_MAX)) { + return EINVAL; + } + + if ((newCredentials->euid < 0) || (newCredentials->egid < 0)) { + return EINVAL; + } + + UserContainer *userContainer = LOS_MemAlloc(m_aucSysMem1, sizeof(UserContainer)); + if (userContainer == NULL) { + return ENOMEM; + } + (VOID)memset_s(userContainer, sizeof(UserContainer), 0, sizeof(UserContainer)); + + g_currentUserContainerNum++; + userContainer->containerID = OsAllocContainerID(); + userContainer->parent = parentUserContainer; + newCredentials->userContainer = userContainer; + if (parentUserContainer != NULL) { + LOS_AtomicInc(&parentUserContainer->rc); + LOS_AtomicSet(&userContainer->rc, 1); + userContainer->level = parentUserContainer->level + 1; + userContainer->owner = newCredentials->euid; + userContainer->group = newCredentials->egid; + } else { + LOS_AtomicSet(&userContainer->rc, 3); /* 3: Three system processes */ + userContainer->uidMap.extentCount = 1; + userContainer->uidMap.extent[0].count = 4294967295U; + userContainer->gidMap.extentCount = 1; + userContainer->gidMap.extent[0].count = 4294967295U; + } + return LOS_OK; +} + +VOID FreeUserContainer(UserContainer *userContainer) +{ + UserContainer *parent = NULL; + do { + parent = userContainer->parent; + (VOID)LOS_MemFree(m_aucSysMem1, userContainer); + userContainer->parent = NULL; + userContainer = parent; + g_currentUserContainerNum--; + if (userContainer == NULL) { + break; + } + LOS_AtomicDec(&userContainer->rc); + } while (LOS_AtomicRead(&userContainer->rc) <= 0); +} + +STATIC UidGidExtent *MapIdUpBase(UINT32 extents, UidGidMap *map, UINT32 id) +{ + UINT32 idx; + UINT32 first; + UINT32 last; + + for (idx = 0; idx < extents; idx++) { + first = map->extent[idx].lowerFirst; + last = first + map->extent[idx].count - 1; + if ((id >= first) && (id <= last)) { + return &map->extent[idx]; + } + } + return NULL; +} + +STATIC UINT32 MapIdUp(UidGidMap *map, UINT32 id) +{ + UINT32 extents = map->extentCount; + if (extents > UID_GID_MAP_MAX_EXTENTS) { + return (UINT32)-1; + } + + UidGidExtent *extent = MapIdUpBase(extents, map, id); + if (extent != NULL) { + return ((id - extent->lowerFirst) + extent->first); + } + + return (UINT32)-1; +} + +UINT32 FromKuid(UserContainer *userContainer, UINT32 kuid) +{ + return MapIdUp(&userContainer->uidMap, kuid); +} + +UINT32 FromKgid(UserContainer *userContainer, UINT32 kgid) +{ + return MapIdUp(&userContainer->gidMap, kgid); +} + +UINT32 OsFromKuidMunged(UserContainer *userContainer, UINT32 kuid) +{ + UINT32 uid = FromKuid(userContainer, kuid); + if (uid == (UINT32)-1) { + uid = DEFAULT_OVERFLOWUID; + } + return uid; +} + +UINT32 OsFromKgidMunged(UserContainer *userContainer, UINT32 kgid) +{ + UINT32 gid = FromKgid(userContainer, kgid); + if (gid == (UINT32)-1) { + gid = DEFAULT_OVERFLOWGID; + } + return gid; +} + +STATIC UidGidExtent *MapIdRangeDownBase(UINT32 extents, UidGidMap *map, UINT32 id, UINT32 count) +{ + UINT32 idx; + UINT32 first; + UINT32 last; + UINT32 id2; + + id2 = id + count - 1; + for (idx = 0; idx < extents; idx++) { + first = map->extent[idx].first; + last = first + map->extent[idx].count - 1; + if ((id >= first && id <= last) && (id2 >= first && id2 <= last)) { + return &map->extent[idx]; + } + } + return NULL; +} + +STATIC UINT32 MapIdRangeDown(UidGidMap *map, UINT32 id, UINT32 count) +{ + UINT32 extents = map->extentCount; + if (extents > UID_GID_MAP_MAX_EXTENTS) { + return (UINT32)-1; + } + + UidGidExtent *extent = MapIdRangeDownBase(extents, map, id, count); + if (extent != NULL) { + return ((id - extent->first) + extent->lowerFirst); + } + + return (UINT32)-1; +} + +STATIC UINT32 MapIdDown(UidGidMap *map, UINT32 id) +{ + return MapIdRangeDown(map, id, 1); +} + +UINT32 OsMakeKuid(UserContainer *userContainer, UINT32 uid) +{ + return MapIdDown(&userContainer->uidMap, uid); +} + +UINT32 OsMakeKgid(UserContainer *userContainer, UINT32 gid) +{ + return MapIdDown(&userContainer->gidMap, gid); +} + +STATIC INT32 InsertExtent(UidGidMap *idMap, UidGidExtent *extent) +{ + if (idMap->extentCount > UID_GID_MAP_MAX_EXTENTS) { + return -EINVAL; + } + + UidGidExtent *dest = &idMap->extent[idMap->extentCount]; + *dest = *extent; + idMap->extentCount++; + + return 0; +} + +STATIC BOOL MappingsOverlap(UidGidMap *idMap, UidGidExtent *extent) +{ + UINT32 upperFirst = extent->first; + UINT32 lowerFirst = extent->lowerFirst; + UINT32 upperLast = upperFirst + extent->count - 1; + UINT32 lowerLast = lowerFirst + extent->count - 1; + INT32 idx; + + for (idx = 0; idx < idMap->extentCount; idx++) { + if (idMap->extentCount > UID_GID_MAP_MAX_EXTENTS) { + return TRUE; + } + UidGidExtent *prev = &idMap->extent[idx]; + UINT32 prevUpperFirst = prev->first; + UINT32 prevLowerFirst = prev->lowerFirst; + UINT32 prevUpperLast = prevUpperFirst + prev->count - 1; + UINT32 prevLowerLast = prevLowerFirst + prev->count - 1; + + if ((prevUpperFirst <= upperLast) && (prevUpperLast >= upperFirst)) { + return TRUE; + } + + if ((prevLowerFirst <= lowerLast) && (prevLowerLast >= lowerFirst)) { + return TRUE; + } + } + return FALSE; +} + +STATIC CHAR *SkipSpaces(const CHAR *str) +{ + while (isspace(*str)) { + ++str; + } + + return (CHAR *)str; +} + +STATIC UINTPTR StrToUInt(const CHAR *str, CHAR **endp, UINT32 base) +{ + unsigned long result = 0; + unsigned long value; + + if (*str == '0') { + str++; + if ((*str == 'x') && isxdigit(str[1])) { + base = HEX; + str++; + } + if (!base) { + base = OCT; + } + } + if (!base) { + base = DEC; + } + while (isxdigit(*str) && (value = isdigit(*str) ? *str - '0' : (islower(*str) ? + toupper(*str) : *str) - 'A' + DEC) < base) { + result = result * base + value; + str++; + } + if (endp != NULL) { + *endp = (CHAR *)str; + } + return result; +} + +STATIC INT32 ParsePosData(CHAR *pos, UidGidExtent *extent) +{ + INT32 ret = -EINVAL; + pos = SkipSpaces(pos); + extent->first = StrToUInt(pos, &pos, DEC); + if (!isspace(*pos)) { + return ret; + } + + pos = SkipSpaces(pos); + extent->lowerFirst = StrToUInt(pos, &pos, DEC); + if (!isspace(*pos)) { + return ret; + } + + pos = SkipSpaces(pos); + extent->count = StrToUInt(pos, &pos, DEC); + if (*pos && !isspace(*pos)) { + return ret; + } + + pos = SkipSpaces(pos); + if (*pos != '\0') { + return ret; + } + return LOS_OK; +} + +STATIC INT32 ParseUserData(CHAR *kbuf, UidGidExtent *extent, UidGidMap *newMap) +{ + INT32 ret = -EINVAL; + CHAR *pos = NULL; + CHAR *nextLine = NULL; + + for (pos = kbuf; pos != NULL; pos = nextLine) { + nextLine = strchr(pos, '\n'); + if (nextLine != NULL) { + *nextLine = '\0'; + nextLine++; + if (*nextLine == '\0') { + nextLine = NULL; + } + } + + if (ParsePosData(pos, extent) != LOS_OK) { + return ret; + } + + if ((extent->first == (UINT32)-1) || (extent->lowerFirst == (UINT32)-1)) { + return ret; + } + + if ((extent->first + extent->count) <= extent->first) { + return ret; + } + + if ((extent->lowerFirst + extent->count) <= extent->lowerFirst) { + return ret; + } + + if (MappingsOverlap(newMap, extent)) { + return ret; + } + + if ((newMap->extentCount + 1) == UID_GID_MAP_MAX_EXTENTS && (nextLine != NULL)) { + return ret; + } + + ret = InsertExtent(newMap, extent); + if (ret < 0) { + return ret; + } + ret = 0; + } + + if (newMap->extentCount == 0) { + return -EINVAL; + } + + return ret; +} + +STATIC INT32 ParentMapIdRange(UidGidMap *newMap, UidGidMap *parentMap) +{ + UINT32 idx; + INT32 ret = -EPERM; + for (idx = 0; idx < newMap->extentCount; idx++) { + if (newMap->extentCount > UID_GID_MAP_MAX_EXTENTS) { + return ret; + } + + UidGidExtent *extent = &newMap->extent[idx]; + UINT32 lowerFirst = MapIdRangeDown(parentMap, extent->lowerFirst, extent->count); + if (lowerFirst == (UINT32) -1) { + return ret; + } + + extent->lowerFirst = lowerFirst; + } + return 0; +} + +INT32 OsUserContainerMapWrite(struct ProcFile *fp, CHAR *kbuf, size_t count, + INT32 capSetid, UidGidMap *map, UidGidMap *parentMap) +{ + UidGidMap newMap = {0}; + UidGidExtent extent; + INT32 ret; + + if (map->extentCount != 0) { + return -EPERM; + } + + if (!IsCapPermit(capSetid)) { + return -EPERM; + } + + ret = ParseUserData(kbuf, &extent, &newMap); + if (ret < 0) { + return -EPERM; + } + + ret = ParentMapIdRange(&newMap, parentMap); + if (ret < 0) { + return -EPERM; + } + + if (newMap.extentCount <= UID_GID_MAP_MAX_EXTENTS) { + size_t mapSize = newMap.extentCount * sizeof(newMap.extent[0]); + ret = memcpy_s(map->extent, sizeof(map->extent), newMap.extent, mapSize); + if (ret != EOK) { + return -EPERM; + } + } + + map->extentCount = newMap.extentCount; + return count; +} + +UINT32 OsGetUserContainerCount(VOID) +{ + return g_currentUserContainerNum; +} +#endif diff --git a/src/kernel_liteos_a/kernel/extended/container/los_uts_container.c b/src/kernel_liteos_a/kernel/extended/container/los_uts_container.c new file mode 100644 index 00000000..ee483928 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/container/los_uts_container.c @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef LOSCFG_UTS_CONTAINER +#include "internal.h" +#include "los_uts_container_pri.h" +#include "los_process_pri.h" + +STATIC UINT32 g_currentUtsContainerNum; + +STATIC UINT32 InitUtsContainer(struct utsname *name) +{ + INT32 ret = sprintf_s(name->sysname, sizeof(name->sysname), "%s", KERNEL_NAME); + if (ret < 0) { + return LOS_NOK; + } + ret = sprintf_s(name->nodename, sizeof(name->nodename), "%s", KERNEL_NODE_NAME); + if (ret < 0) { + return LOS_NOK; + } + ret = sprintf_s(name->version, sizeof(name->version), "%s %u.%u.%u.%u %s %s", + KERNEL_NAME, KERNEL_MAJOR, KERNEL_MINOR, KERNEL_PATCH, KERNEL_ITRE, __DATE__, __TIME__); + if (ret < 0) { + return LOS_NOK; + } + const char *cpuInfo = LOS_CpuInfo(); + ret = sprintf_s(name->machine, sizeof(name->machine), "%s", cpuInfo); + if (ret < 0) { + return LOS_NOK; + } + ret = sprintf_s(name->release, sizeof(name->release), "%u.%u.%u.%u", + KERNEL_MAJOR, KERNEL_MINOR, KERNEL_PATCH, KERNEL_ITRE); + if (ret < 0) { + return LOS_NOK; + } + name->domainname[0] = '\0'; + return LOS_OK; +} + +STATIC UtsContainer *CreateNewUtsContainer(UtsContainer *parent) +{ + UINT32 ret; + UINT32 size = sizeof(UtsContainer); + UtsContainer *utsContainer = (UtsContainer *)LOS_MemAlloc(m_aucSysMem1, size); + if (utsContainer == NULL) { + return NULL; + } + (VOID)memset_s(utsContainer, sizeof(UtsContainer), 0, sizeof(UtsContainer)); + + utsContainer->containerID = OsAllocContainerID(); + if (parent != NULL) { + LOS_AtomicSet(&utsContainer->rc, 1); + return utsContainer; + } + LOS_AtomicSet(&utsContainer->rc, 3); /* 3: Three system processes */ + ret = InitUtsContainer(&utsContainer->utsName); + if (ret != LOS_OK) { + (VOID)LOS_MemFree(m_aucSysMem1, utsContainer); + return NULL; + } + return utsContainer; +} + +STATIC UINT32 CreateUtsContainer(LosProcessCB *child, LosProcessCB *parent) +{ + UINT32 intSave; + UtsContainer *parentContainer = parent->container->utsContainer; + UtsContainer *newUtsContainer = CreateNewUtsContainer(parentContainer); + if (newUtsContainer == NULL) { + return ENOMEM; + } + + SCHEDULER_LOCK(intSave); + g_currentUtsContainerNum++; + (VOID)memcpy_s(&newUtsContainer->utsName, sizeof(newUtsContainer->utsName), + &parentContainer->utsName, sizeof(parentContainer->utsName)); + child->container->utsContainer = newUtsContainer; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +UINT32 OsInitRootUtsContainer(UtsContainer **utsContainer) +{ + UINT32 intSave; + UtsContainer *newUtsContainer = CreateNewUtsContainer(NULL); + if (newUtsContainer == NULL) { + return ENOMEM; + } + + SCHEDULER_LOCK(intSave); + g_currentUtsContainerNum++; + *utsContainer = newUtsContainer; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +UINT32 OsCopyUtsContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent) +{ + UINT32 intSave; + UtsContainer *currUtsContainer = parent->container->utsContainer; + + if (!(flags & CLONE_NEWUTS)) { + SCHEDULER_LOCK(intSave); + LOS_AtomicInc(&currUtsContainer->rc); + child->container->utsContainer = currUtsContainer; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; + } + + if (OsContainerLimitCheck(UTS_CONTAINER, &g_currentUtsContainerNum) != LOS_OK) { + return EPERM; + } + + return CreateUtsContainer(child, parent); +} + +UINT32 OsUnshareUtsContainer(UINTPTR flags, LosProcessCB *curr, Container *newContainer) +{ + UINT32 intSave; + UtsContainer *parentContainer = curr->container->utsContainer; + + if (!(flags & CLONE_NEWUTS)) { + SCHEDULER_LOCK(intSave); + newContainer->utsContainer = parentContainer; + LOS_AtomicInc(&parentContainer->rc); + SCHEDULER_UNLOCK(intSave); + return LOS_OK; + } + + if (OsContainerLimitCheck(UTS_CONTAINER, &g_currentUtsContainerNum) != LOS_OK) { + return EPERM; + } + + UtsContainer *utsContainer = CreateNewUtsContainer(parentContainer); + if (utsContainer == NULL) { + return ENOMEM; + } + + SCHEDULER_LOCK(intSave); + newContainer->utsContainer = utsContainer; + g_currentUtsContainerNum++; + (VOID)memcpy_s(&utsContainer->utsName, sizeof(utsContainer->utsName), + &parentContainer->utsName, sizeof(parentContainer->utsName)); + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +UINT32 OsSetNsUtsContainer(UINT32 flags, Container *container, Container *newContainer) +{ + if (flags & CLONE_NEWUTS) { + newContainer->utsContainer = container->utsContainer; + LOS_AtomicInc(&container->utsContainer->rc); + return LOS_OK; + } + + newContainer->utsContainer = OsCurrProcessGet()->container->utsContainer; + LOS_AtomicInc(&newContainer->utsContainer->rc); + return LOS_OK; +} + +VOID OsUtsContainerDestroy(Container *container) +{ + UINT32 intSave; + if (container == NULL) { + return; + } + + SCHEDULER_LOCK(intSave); + UtsContainer *utsContainer = container->utsContainer; + if (utsContainer == NULL) { + SCHEDULER_UNLOCK(intSave); + return; + } + + LOS_AtomicDec(&utsContainer->rc); + if (LOS_AtomicRead(&utsContainer->rc) > 0) { + SCHEDULER_UNLOCK(intSave); + return; + } + g_currentUtsContainerNum--; + container->utsContainer = NULL; + SCHEDULER_UNLOCK(intSave); + (VOID)LOS_MemFree(m_aucSysMem1, utsContainer); + return; +} + +struct utsname *OsGetCurrUtsName(VOID) +{ + Container *container = OsCurrProcessGet()->container; + if (container == NULL) { + return NULL; + } + UtsContainer *utsContainer = container->utsContainer; + if (utsContainer == NULL) { + return NULL; + } + return &utsContainer->utsName; +} + +UINT32 OsGetUtsContainerID(UtsContainer *utsContainer) +{ + if (utsContainer == NULL) { + return OS_INVALID_VALUE; + } + + return utsContainer->containerID; +} + +UINT32 OsGetUtsContainerCount(VOID) +{ + return g_currentUtsContainerNum; +} +#endif diff --git a/src/kernel_liteos_a/kernel/extended/cppsupport/BUILD.gn b/src/kernel_liteos_a/kernel/extended/cppsupport/BUILD.gn new file mode 100644 index 00000000..d264cd20 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/cppsupport/BUILD.gn @@ -0,0 +1,36 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = defined(LOSCFG_KERNEL_CPPSUPPORT) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ "los_cppsupport.c" ] +} diff --git a/src/kernel_liteos_a/kernel/extended/cppsupport/Makefile b/src/kernel_liteos_a/kernel/extended/cppsupport/Makefile new file mode 100644 index 00000000..7d3a2662 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/cppsupport/Makefile @@ -0,0 +1,40 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# A Makefile for cppsupport + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := $(wildcard *.c) + +LOCAL_FLAGS := $(LITEOS_CFLAGS_INTERWORK) + +include $(MODULE) diff --git a/src/kernel_liteos_a/kernel/extended/cppsupport/los_cppsupport.c b/src/kernel_liteos_a/kernel/extended/cppsupport/los_cppsupport.c new file mode 100644 index 00000000..bda498ad --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/cppsupport/los_cppsupport.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_cppsupport.h" +#include "los_printf.h" + + +typedef VOID (*InitFunc)(VOID); + +LITE_OS_SEC_TEXT_MINOR INT32 LOS_CppSystemInit(UINTPTR initArrayStart, UINTPTR initArrayEnd, INT32 flag) +{ + UINTPTR *start = (UINTPTR *)initArrayStart; + InitFunc initFunc = NULL; + + for (; start != (UINTPTR *)initArrayEnd; ++start) { + initFunc = (InitFunc)(*start); + initFunc(); + } + + return 0; +} + diff --git a/src/kernel_liteos_a/kernel/extended/cpup/BUILD.gn b/src/kernel_liteos_a/kernel/extended/cpup/BUILD.gn new file mode 100644 index 00000000..2482774f --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/cpup/BUILD.gn @@ -0,0 +1,45 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = defined(LOSCFG_KERNEL_CPUP) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ + "cpup_shellcmd.c", + "los_cpup.c", + ] + + public_configs = [ ":public" ] +} + +config("public") { + include_dirs = [ "." ] +} diff --git a/src/kernel_liteos_a/kernel/extended/cpup/Makefile b/src/kernel_liteos_a/kernel/extended/cpup/Makefile new file mode 100644 index 00000000..8d11bbf2 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/cpup/Makefile @@ -0,0 +1,36 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := $(wildcard *.c) + +include $(MODULE) diff --git a/src/kernel_liteos_a/kernel/extended/cpup/cpup_shellcmd.c b/src/kernel_liteos_a/kernel/extended/cpup/cpup_shellcmd.c new file mode 100644 index 00000000..edaec5d6 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/cpup/cpup_shellcmd.c @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_config.h" +#ifdef LOSCFG_SHELL +#include "stdlib.h" +#include "los_cpup_pri.h" +#include "los_process_pri.h" +#include "shcmd.h" +#include "shell.h" + + +VOID OsCmdCpupOperateOneParam(UINT32 mode) +{ + UINT32 ret; + + if (mode == CPUP_LAST_TEN_SECONDS) { + PRINTK("\nSysCpuUsage in 10s: "); + } else if (mode == CPUP_LAST_ONE_SECONDS) { + PRINTK("\nSysCpuUsage in 1s: "); + } else { + PRINTK("\nSysCpuUsage in all time: "); + } + ret = LOS_HistorySysCpuUsage(mode); + PRINTK("%u.%u\n", ret / LOS_CPUP_PRECISION_MULT, ret % LOS_CPUP_PRECISION_MULT); +} + +VOID OsCmdCpupOperateTwoParam(UINT32 mode, UINT32 pid) +{ + UINT32 ret; + + if (mode == CPUP_LAST_TEN_SECONDS) { + PRINTK("\npid %u CpuUsage in 10s: ", pid); + } else if (mode == CPUP_LAST_ONE_SECONDS) { + PRINTK("\npid %u CpuUsage in 1s: ", pid); + } else { + PRINTK("\npid %u CpuUsage in all time: ", pid); + } + ret = LOS_HistoryProcessCpuUsage(pid, mode); + PRINTK("%u.%u\n", ret / LOS_CPUP_PRECISION_MULT, ret % LOS_CPUP_PRECISION_MULT); +} + +LITE_OS_SEC_TEXT STATIC VOID OsCpupCmdHelp(VOID) +{ + PRINTK("usage:\n"); + PRINTK(" cpup\n" + " cpup [MODE]\n" + " cpup [MODE] [PID] \n"); + PRINTK("\r\nMode parameter description:\n" + " 0 SysCpuUsage in 10s\n" + " 1 SysCpuUsage in 1s\n" + " others SysCpuUsage in all time\n"); +} + +LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdCpup(INT32 argc, const CHAR **argv) +{ + size_t mode, pid; + CHAR *bufMode = NULL; + CHAR *bufID = NULL; + UINT32 ret; + + if (argc == 0) { + ret = LOS_HistorySysCpuUsage(CPUP_LAST_TEN_SECONDS); + PRINTK("\nSysCpuUsage in 10s: %u.%u\n", ret / LOS_CPUP_PRECISION_MULT, ret % LOS_CPUP_PRECISION_MULT); + return LOS_OK; + } + + if (!strcmp(argv[0], "-h") || !strcmp(argv[0], "--help")) { + OsCpupCmdHelp(); + return LOS_OK; + } + + mode = strtoul(argv[0], &bufMode, 0); + if ((bufMode == NULL) || (*bufMode != 0)) { + PRINTK("\nUnknown mode: %s\n", argv[0]); + OsCpupCmdHelp(); + return LOS_OK; + } + + if (mode > CPUP_ALL_TIME) { + mode = CPUP_ALL_TIME; + } + + if (argc == 1) { + OsCmdCpupOperateOneParam(mode); + return LOS_OK; + } + + pid = strtoul(argv[1], &bufID, 0); + if (OsProcessIDUserCheckInvalid(pid) || (*bufID != 0)) { + PRINTK("\nUnknown pid: %s\n", argv[1]); + return LOS_OK; + } + + if (OsProcessIsUnused(OS_PCB_FROM_PID(pid)) || OsProcessIsDead(OS_PCB_FROM_PID(pid))) { + PRINTK("\nUnknown pid: %u\n", pid); + return LOS_OK; + } + + /* when the parameters number is two */ + if (argc == 2) { + OsCmdCpupOperateTwoParam(mode, pid); + return LOS_OK; + } + + OsCpupCmdHelp(); + return LOS_OK; +} + +SHELLCMD_ENTRY(cpup_shellcmd, CMD_TYPE_EX, "cpup", XARGS, (CmdCallBackFunc)OsShellCmdCpup); +#endif /* LOSCFG_SHELL */ diff --git a/src/kernel_liteos_a/kernel/extended/cpup/los_cpup.c b/src/kernel_liteos_a/kernel/extended/cpup/los_cpup.c new file mode 100644 index 00000000..4563a9b8 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/cpup/los_cpup.c @@ -0,0 +1,611 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_cpup_pri.h" +#include "los_base.h" +#include "los_init.h" +#include "los_process_pri.h" +#include "los_info_pri.h" +#include "los_swtmr.h" + + +#ifdef LOSCFG_KERNEL_CPUP + +LITE_OS_SEC_BSS STATIC UINT16 cpupSwtmrID; +LITE_OS_SEC_BSS STATIC UINT16 cpupInitFlg = 0; +LITE_OS_SEC_BSS OsIrqCpupCB *g_irqCpup = NULL; +LITE_OS_SEC_BSS STATIC UINT32 cpupMaxNum; +LITE_OS_SEC_BSS STATIC UINT16 cpupHisPos = 0; /* current Sampling point of historyTime */ +LITE_OS_SEC_BSS STATIC UINT64 cpuHistoryTime[OS_CPUP_HISTORY_RECORD_NUM + 1]; +LITE_OS_SEC_BSS STATIC LosTaskCB *runningTasks[LOSCFG_KERNEL_CORE_NUM]; +LITE_OS_SEC_BSS STATIC UINT64 cpupStartCycles = 0; +#ifdef LOSCFG_CPUP_INCLUDE_IRQ +LITE_OS_SEC_BSS UINT64 timeInIrqSwitch[LOSCFG_KERNEL_CORE_NUM]; +LITE_OS_SEC_BSS STATIC UINT64 cpupIntTimeStart[LOSCFG_KERNEL_CORE_NUM]; +#endif + +#define INVALID_ID ((UINT32)-1) + +#define OS_CPUP_UNUSED 0x0U +#define OS_CPUP_USED 0x1U +#define HIGH_BITS 32 + +#define CPUP_PRE_POS(pos) (((pos) == 0) ? (OS_CPUP_HISTORY_RECORD_NUM - 1) : ((pos) - 1)) +#define CPUP_POST_POS(pos) (((pos) == (OS_CPUP_HISTORY_RECORD_NUM - 1)) ? 0 : ((pos) + 1)) + +STATIC UINT64 OsGetCpuCycle(VOID) +{ + UINT32 high; + UINT32 low; + UINT64 cycles; + + LOS_GetCpuCycle(&high, &low); + cycles = ((UINT64)high << HIGH_BITS) + low; + if (cpupStartCycles == 0) { + cpupStartCycles = cycles; + } + + /* + * The cycles should keep growing, if the checking failed, + * it mean LOS_GetCpuCycle has the problem which should be fixed. + */ + LOS_ASSERT(cycles >= cpupStartCycles); + + return (cycles - cpupStartCycles); +} + +LITE_OS_SEC_TEXT_INIT VOID OsCpupGuard(VOID) +{ + UINT16 prevPos; + UINT32 loop; + UINT32 intSave; + UINT64 cycle, cycleIncrement; + LosProcessCB *processCB = NULL; + + SCHEDULER_LOCK(intSave); + + cycle = OsGetCpuCycle(); + prevPos = cpupHisPos; + cpupHisPos = CPUP_POST_POS(cpupHisPos); + cpuHistoryTime[prevPos] = cycle; + +#ifdef LOSCFG_CPUP_INCLUDE_IRQ + for (loop = 0; loop < cpupMaxNum; loop++) { + if (g_irqCpup[loop].status == OS_CPUP_UNUSED) { + continue; + } + g_irqCpup[loop].cpup.historyTime[prevPos] = g_irqCpup[loop].cpup.allTime; + } +#endif + + for (loop = 0; loop < g_processMaxNum; loop++) { + processCB = OS_PCB_FROM_RPID(loop); + if (processCB->processCpup == NULL) { + continue; + } + processCB->processCpup->historyTime[prevPos] = processCB->processCpup->allTime; + } + + for (loop = 0; loop < g_taskMaxNum; loop++) { + LosTaskCB *taskCB = OS_TCB_FROM_RTID(loop); + taskCB->taskCpup.historyTime[prevPos] = taskCB->taskCpup.allTime; + } + + for (loop = 0; loop < LOSCFG_KERNEL_CORE_NUM; loop++) { + LosTaskCB *runTask = runningTasks[loop]; + if (runTask == NULL) { + continue; + } + + /* reacquire the cycle to prevent flip */ + cycle = OsGetCpuCycle(); + cycleIncrement = cycle - runTask->taskCpup.startTime; +#ifdef LOSCFG_CPUP_INCLUDE_IRQ + cycleIncrement -= timeInIrqSwitch[loop]; +#endif + runTask->taskCpup.historyTime[prevPos] += cycleIncrement; + processCB = OS_PCB_FROM_TCB(runTask); + if (processCB->processCpup != NULL) { + processCB->processCpup->historyTime[prevPos] += cycleIncrement; + } + } + + SCHEDULER_UNLOCK(intSave); +} + +LITE_OS_SEC_TEXT_INIT UINT32 OsCpupGuardCreator(VOID) +{ + (VOID)LOS_SwtmrCreate(LOSCFG_BASE_CORE_TICK_PER_SECOND, LOS_SWTMR_MODE_PERIOD, + (SWTMR_PROC_FUNC)OsCpupGuard, &cpupSwtmrID, 0); + + (VOID)LOS_SwtmrStart(cpupSwtmrID); + + return LOS_OK; +} + +LOS_MODULE_INIT(OsCpupGuardCreator, LOS_INIT_LEVEL_KMOD_TASK); + +/* + * Description: initialization of CPUP + * Return : LOS_OK or Error Information + */ +LITE_OS_SEC_TEXT_INIT UINT32 OsCpupInit(VOID) +{ + UINT16 loop; +#ifdef LOSCFG_CPUP_INCLUDE_IRQ + UINT32 size; + + cpupMaxNum = OS_HWI_MAX_NUM * LOSCFG_KERNEL_CORE_NUM; + + /* every process has only one record, and it won't operated at the same time */ + size = cpupMaxNum * sizeof(OsIrqCpupCB); + g_irqCpup = (OsIrqCpupCB *)LOS_MemAlloc(m_aucSysMem0, size); + if (g_irqCpup == NULL) { + PRINT_ERR("OsCpupInit error\n"); + return LOS_ERRNO_CPUP_NO_MEMORY; + } + + (VOID)memset_s(g_irqCpup, size, 0, size); +#endif + + for (loop = 0; loop < LOSCFG_KERNEL_CORE_NUM; loop++) { + runningTasks[loop] = NULL; + } + cpupInitFlg = 1; + return LOS_OK; +} + +LOS_MODULE_INIT(OsCpupInit, LOS_INIT_LEVEL_KMOD_EXTENDED); + +STATIC VOID OsResetCpup(OsCpupBase *cpup, UINT64 cycle) +{ + UINT16 loop; + + cpup->startTime = cycle; + cpup->allTime = cycle; + for (loop = 0; loop < (OS_CPUP_HISTORY_RECORD_NUM + 1); loop++) { + cpup->historyTime[loop] = cycle; + } +} + +LITE_OS_SEC_TEXT_INIT VOID LOS_CpupReset(VOID) +{ + LosProcessCB *processCB = NULL; + LosTaskCB *taskCB = NULL; + UINT32 index; + UINT64 cycle; + UINT32 intSave; + + cpupInitFlg = 0; + intSave = LOS_IntLock(); + (VOID)LOS_SwtmrStop(cpupSwtmrID); + cycle = OsGetCpuCycle(); + + for (index = 0; index < (OS_CPUP_HISTORY_RECORD_NUM + 1); index++) { + cpuHistoryTime[index] = cycle; + } + + for (index = 0; index < g_processMaxNum; index++) { + processCB = OS_PCB_FROM_PID(index); + if (processCB->processCpup == NULL) { + continue; + } + OsResetCpup(processCB->processCpup, cycle); + } + + for (index = 0; index < g_taskMaxNum; index++) { + taskCB = OS_TCB_FROM_TID(index); + OsResetCpup(&taskCB->taskCpup, cycle); + } + +#ifdef LOSCFG_CPUP_INCLUDE_IRQ + if (g_irqCpup != NULL) { + for (index = 0; index < cpupMaxNum; index++) { + OsResetCpup(&g_irqCpup[index].cpup, cycle); + g_irqCpup[index].timeMax = 0; + } + + for (index = 0; index < LOSCFG_KERNEL_CORE_NUM; index++) { + timeInIrqSwitch[index] = 0; + } + } +#endif + + (VOID)LOS_SwtmrStart(cpupSwtmrID); + LOS_IntRestore(intSave); + cpupInitFlg = 1; + + return; +} + +VOID OsCpupCycleEndStart(LosTaskCB *runTask, LosTaskCB *newTask) +{ + /* OsCurrTaskGet and OsCurrProcessGet are not allowed to be called. */ + OsCpupBase *runTaskCpup = &runTask->taskCpup; + OsCpupBase *newTaskCpup = &newTask->taskCpup; + OsCpupBase *processCpup = OS_PCB_FROM_TCB(runTask)->processCpup; + UINT64 cpuCycle, cycleIncrement; + UINT16 cpuid = ArchCurrCpuid(); + + if (cpupInitFlg == 0) { + return; + } + + cpuCycle = OsGetCpuCycle(); + if (runTaskCpup->startTime != 0) { + cycleIncrement = cpuCycle - runTaskCpup->startTime; +#ifdef LOSCFG_CPUP_INCLUDE_IRQ + cycleIncrement -= timeInIrqSwitch[cpuid]; + timeInIrqSwitch[cpuid] = 0; +#endif + runTaskCpup->allTime += cycleIncrement; + if (processCpup != NULL) { + processCpup->allTime += cycleIncrement; + } + runTaskCpup->startTime = 0; + } + + newTaskCpup->startTime = cpuCycle; + runningTasks[cpuid] = newTask; +} + +LITE_OS_SEC_TEXT_MINOR STATIC VOID OsCpupGetPos(UINT16 mode, UINT16 *curPosPointer, UINT16 *prePosPointer) +{ + UINT16 curPos; + UINT16 tmpPos; + UINT16 prePos; + + tmpPos = cpupHisPos; + curPos = CPUP_PRE_POS(tmpPos); + + /* + * The current position has nothing to do with the CPUP modes, + * however, the previous position differs. + */ + switch (mode) { + case CPUP_LAST_ONE_SECONDS: + prePos = CPUP_PRE_POS(curPos); + break; + case CPUP_LAST_TEN_SECONDS: + prePos = tmpPos; + break; + case CPUP_ALL_TIME: + /* fall-through */ + default: + prePos = OS_CPUP_HISTORY_RECORD_NUM; + break; + } + + *curPosPointer = curPos; + *prePosPointer = prePos; + + return; +} + +STATIC INLINE UINT32 OsCalculateCpupUsage(const OsCpupBase *cpup, UINT16 pos, UINT16 prePos, UINT64 allCycle) +{ + UINT32 usage = 0; + UINT64 cpuCycle = cpup->historyTime[pos] - cpup->historyTime[prePos]; + + if (allCycle) { + usage = (UINT32)((LOS_CPUP_SINGLE_CORE_PRECISION * cpuCycle) / allCycle); + } + return usage; +} + +STATIC UINT32 OsHistorySysCpuUsageUnsafe(UINT16 mode) +{ + UINT64 cpuAllCycle; + UINT16 pos; + UINT16 prePos; + OsCpupBase *processCpup = NULL; + + if (cpupInitFlg == 0) { + return LOS_ERRNO_CPUP_NO_INIT; + } + + OsCpupGetPos(mode, &pos, &prePos); + cpuAllCycle = cpuHistoryTime[pos] - cpuHistoryTime[prePos]; + + processCpup = OS_PCB_FROM_PID(OS_KERNEL_IDLE_PROCESS_ID)->processCpup; + return (LOS_CPUP_PRECISION - OsCalculateCpupUsage(processCpup, pos, prePos, cpuAllCycle)); +} + +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_HistorySysCpuUsage(UINT16 mode) +{ + UINT32 cpup; + UINT32 intSave; + + /* get end time of current process */ + SCHEDULER_LOCK(intSave); + cpup = OsHistorySysCpuUsageUnsafe(mode); + SCHEDULER_UNLOCK(intSave); + return cpup; +} + +STATIC UINT32 OsHistoryProcessCpuUsageUnsafe(UINT32 pid, UINT16 mode) +{ + LosProcessCB *processCB = NULL; + UINT64 cpuAllCycle; + UINT16 pos, prePos; + + if (cpupInitFlg == 0) { + return LOS_ERRNO_CPUP_NO_INIT; + } + + if (OS_PID_CHECK_INVALID(pid)) { + return LOS_ERRNO_CPUP_ID_INVALID; + } + + processCB = OS_PCB_FROM_PID(pid); + if (OsProcessIsUnused(processCB)) { + return LOS_ERRNO_CPUP_NO_CREATED; + } + + if (processCB->processCpup == NULL) { + return LOS_ERRNO_CPUP_ID_INVALID; + } + + OsCpupGetPos(mode, &pos, &prePos); + cpuAllCycle = cpuHistoryTime[pos] - cpuHistoryTime[prePos]; + + return OsCalculateCpupUsage(processCB->processCpup, pos, prePos, cpuAllCycle); +} + +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_HistoryProcessCpuUsage(UINT32 pid, UINT16 mode) +{ + UINT32 cpup; + UINT32 intSave; + + SCHEDULER_LOCK(intSave); + cpup = OsHistoryProcessCpuUsageUnsafe(pid, mode); + SCHEDULER_UNLOCK(intSave); + return cpup; +} + +STATIC UINT32 OsHistoryTaskCpuUsageUnsafe(UINT32 tid, UINT16 mode) +{ + LosTaskCB *taskCB = NULL; + UINT64 cpuAllCycle; + UINT16 pos, prePos; + + if (cpupInitFlg == 0) { + return LOS_ERRNO_CPUP_NO_INIT; + } + + if (OS_TID_CHECK_INVALID(tid)) { + return LOS_ERRNO_CPUP_ID_INVALID; + } + + taskCB = OS_TCB_FROM_TID(tid); + if (OsTaskIsUnused(taskCB)) { + return LOS_ERRNO_CPUP_NO_CREATED; + } + + OsCpupGetPos(mode, &pos, &prePos); + cpuAllCycle = cpuHistoryTime[pos] - cpuHistoryTime[prePos]; + + return OsCalculateCpupUsage(&taskCB->taskCpup, pos, prePos, cpuAllCycle); +} + +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_HistoryTaskCpuUsage(UINT32 tid, UINT16 mode) +{ + UINT32 intSave; + UINT32 cpup; + + SCHEDULER_LOCK(intSave); + cpup = OsHistoryTaskCpuUsageUnsafe(tid, mode); + SCHEDULER_UNLOCK(intSave); + return cpup; +} + +STATIC UINT32 OsCpupUsageParamCheckAndReset(CPUP_INFO_S *cpupInfo, UINT32 len, UINT32 number) +{ + if (cpupInitFlg == 0) { + return LOS_ERRNO_CPUP_NO_INIT; + } + + if ((cpupInfo == NULL) || (len < (sizeof(CPUP_INFO_S) * number))) { + return LOS_ERRNO_CPUP_PTR_ERR; + } + + (VOID)memset_s(cpupInfo, len, 0, len); + return LOS_OK; +} + +STATIC UINT32 GetAllProcessCpuUsageUnsafe(UINT16 mode, CPUP_INFO_S *cpupInfo, UINT32 len) +{ + LosProcessCB *processCB = NULL; + UINT64 cpuAllCycle; + UINT16 pos, prePos; + UINT32 processID; + UINT32 ret; + + ret = OsCpupUsageParamCheckAndReset(cpupInfo, len, g_processMaxNum); + if (ret != LOS_OK) { + return ret; + } + + OsCpupGetPos(mode, &pos, &prePos); + cpuAllCycle = cpuHistoryTime[pos] - cpuHistoryTime[prePos]; + + for (processID = 0; processID < g_processMaxNum; processID++) { + processCB = OS_PCB_FROM_PID(processID); + if (OsProcessIsUnused(processCB) || (processCB->processCpup == NULL)) { + continue; + } + + cpupInfo[processID].usage = OsCalculateCpupUsage(processCB->processCpup, pos, prePos, cpuAllCycle); + cpupInfo[processID].status = OS_CPUP_USED; + } + + return LOS_OK; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_GetAllProcessCpuUsage(UINT16 mode, CPUP_INFO_S *cpupInfo, UINT32 len) +{ + UINT32 intSave; + UINT32 ret; + + SCHEDULER_LOCK(intSave); + ret = GetAllProcessCpuUsageUnsafe(mode, cpupInfo, len); + SCHEDULER_UNLOCK(intSave); + return ret; +} + +UINT32 OsGetProcessAllCpuUsageUnsafe(OsCpupBase *processCpup, ProcessInfo *processInfo) +{ + UINT64 cpuAllCycle; + UINT16 pos, prePos; + if ((processCpup == NULL) || (processInfo == NULL)) { + return LOS_ERRNO_CPUP_PTR_ERR; + } + + OsCpupGetPos(CPUP_LAST_ONE_SECONDS, &pos, &prePos); + cpuAllCycle = cpuHistoryTime[pos] - cpuHistoryTime[prePos]; + processInfo->cpup1sUsage = OsCalculateCpupUsage(processCpup, pos, prePos, cpuAllCycle); + + OsCpupGetPos(CPUP_LAST_TEN_SECONDS, &pos, &prePos); + cpuAllCycle = cpuHistoryTime[pos] - cpuHistoryTime[prePos]; + processInfo->cpup10sUsage = OsCalculateCpupUsage(processCpup, pos, prePos, cpuAllCycle); + + OsCpupGetPos(CPUP_ALL_TIME, &pos, &prePos); + cpuAllCycle = cpuHistoryTime[pos] - cpuHistoryTime[prePos]; + processInfo->cpupAllsUsage = OsCalculateCpupUsage(processCpup, pos, prePos, cpuAllCycle); + return LOS_OK; +} + +UINT32 OsGetTaskAllCpuUsageUnsafe(OsCpupBase *taskCpup, TaskInfo *taskInfo) +{ + UINT64 cpuAllCycle; + UINT16 pos, prePos; + if ((taskCpup == NULL) || (taskInfo == NULL)) { + return LOS_ERRNO_CPUP_PTR_ERR; + } + + OsCpupGetPos(CPUP_LAST_ONE_SECONDS, &pos, &prePos); + cpuAllCycle = cpuHistoryTime[pos] - cpuHistoryTime[prePos]; + taskInfo->cpup1sUsage = OsCalculateCpupUsage(taskCpup, pos, prePos, cpuAllCycle); + + OsCpupGetPos(CPUP_LAST_TEN_SECONDS, &pos, &prePos); + cpuAllCycle = cpuHistoryTime[pos] - cpuHistoryTime[prePos]; + taskInfo->cpup10sUsage = OsCalculateCpupUsage(taskCpup, pos, prePos, cpuAllCycle); + + OsCpupGetPos(CPUP_ALL_TIME, &pos, &prePos); + cpuAllCycle = cpuHistoryTime[pos] - cpuHistoryTime[prePos]; + taskInfo->cpupAllsUsage = OsCalculateCpupUsage(taskCpup, pos, prePos, cpuAllCycle); + return LOS_OK; +} + +#ifdef LOSCFG_CPUP_INCLUDE_IRQ +LITE_OS_SEC_TEXT_MINOR VOID OsCpupIrqStart(UINT16 cpuid) +{ + UINT32 high; + UINT32 low; + + LOS_GetCpuCycle(&high, &low); + cpupIntTimeStart[cpuid] = ((UINT64)high << HIGH_BITS) + low; + return; +} + +LITE_OS_SEC_TEXT_MINOR VOID OsCpupIrqEnd(UINT16 cpuid, UINT32 intNum) +{ + UINT32 high; + UINT32 low; + UINT64 intTimeEnd; + UINT64 usedTime; + + LOS_GetCpuCycle(&high, &low); + intTimeEnd = ((UINT64)high << HIGH_BITS) + low; + OsIrqCpupCB *irqCb = &g_irqCpup[(intNum * LOSCFG_KERNEL_CORE_NUM) + cpuid]; + irqCb->id = intNum; + irqCb->status = OS_CPUP_USED; + usedTime = intTimeEnd - cpupIntTimeStart[cpuid]; + timeInIrqSwitch[cpuid] += usedTime; + irqCb->cpup.allTime += usedTime; + if (irqCb->count <= 100) { /* Take 100 samples */ + irqCb->allTime += usedTime; + irqCb->count++; + } else { + irqCb->allTime = 0; + irqCb->count = 0; + } + if (usedTime > irqCb->timeMax) { + irqCb->timeMax = usedTime; + } + return; +} + +LITE_OS_SEC_TEXT_MINOR OsIrqCpupCB *OsGetIrqCpupArrayBase(VOID) +{ + return g_irqCpup; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 OsGetAllIrqCpuUsageUnsafe(UINT16 mode, CPUP_INFO_S *cpupInfo, UINT32 len) +{ + UINT16 pos, prePos; + UINT64 cpuAllCycle; + UINT32 loop; + UINT32 ret; + + ret = OsCpupUsageParamCheckAndReset(cpupInfo, len, cpupMaxNum); + if (ret != LOS_OK) { + return ret; + } + + OsCpupGetPos(mode, &pos, &prePos); + cpuAllCycle = cpuHistoryTime[pos] - cpuHistoryTime[prePos]; + + for (loop = 0; loop < cpupMaxNum; loop++) { + if (g_irqCpup[loop].status == OS_CPUP_UNUSED) { + continue; + } + + cpupInfo[loop].usage = OsCalculateCpupUsage(&g_irqCpup[loop].cpup, pos, prePos, cpuAllCycle); + cpupInfo[loop].status = g_irqCpup[loop].status; + } + + return LOS_OK; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_GetAllIrqCpuUsage(UINT16 mode, CPUP_INFO_S *cpupInfo, UINT32 len) +{ + UINT32 intSave; + UINT32 ret; + + SCHEDULER_LOCK(intSave); + ret = OsGetAllIrqCpuUsageUnsafe(mode, cpupInfo, len); + SCHEDULER_UNLOCK(intSave); + return ret; +} +#endif + +#endif /* LOSCFG_KERNEL_CPUP */ diff --git a/src/kernel_liteos_a/kernel/extended/cpup/los_cpup_pri.h b/src/kernel_liteos_a/kernel/extended/cpup/los_cpup_pri.h new file mode 100644 index 00000000..341997b9 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/cpup/los_cpup_pri.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_CPUP_PRI_H +#define _LOS_CPUP_PRI_H + +#include "los_cpup.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** +* @ingroup los_cpup +* Number of historical running time records +*/ +#define OS_CPUP_HISTORY_RECORD_NUM 11 + +typedef struct { + UINT64 allTime; /**< Total running time */ + UINT64 startTime; /**< Time before a task is invoked */ + UINT64 historyTime[OS_CPUP_HISTORY_RECORD_NUM + 1]; /**< Historical running time, the last one saves zero */ +} OsCpupBase; + +/** + * @ingroup los_cpup + * Count the CPU usage structures of a task. + */ +typedef struct { + UINT32 id; /**< irq ID */ + UINT16 status; /**< irq status */ + UINT64 allTime; + UINT64 timeMax; + UINT64 count; + OsCpupBase cpup; /**< irq cpup base */ +} OsIrqCpupCB; + +typedef struct TagTaskCB LosTaskCB; +typedef struct TagTaskInfo TaskInfo; +typedef struct TagProcessInfo ProcessInfo; + +extern UINT32 OsCpupInit(VOID); +extern UINT32 OsCpupGuardCreator(VOID); +extern VOID OsCpupCycleEndStart(LosTaskCB *runTask, LosTaskCB *newTask); +extern UINT32 OsGetProcessAllCpuUsageUnsafe(OsCpupBase *processCpup, ProcessInfo *processInfo); +extern UINT32 OsGetTaskAllCpuUsageUnsafe(OsCpupBase *taskCpup, TaskInfo *taskInfo); +#ifdef LOSCFG_CPUP_INCLUDE_IRQ +extern UINT32 OsGetAllIrqCpuUsageUnsafe(UINT16 mode, CPUP_INFO_S *cpupInfo, UINT32 len); +extern VOID OsCpupIrqStart(UINT16); +extern VOID OsCpupIrqEnd(UINT16, UINT32); +extern OsIrqCpupCB *OsGetIrqCpupArrayBase(VOID); +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_CPUP_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/extended/dynload/BUILD.gn b/src/kernel_liteos_a/kernel/extended/dynload/BUILD.gn new file mode 100644 index 00000000..110abc4c --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/dynload/BUILD.gn @@ -0,0 +1,45 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = defined(LOSCFG_KERNEL_DYNLOAD) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ + "src/los_exec_elf.c", + "src/los_load_elf.c", + ] + + public_configs = [ ":public" ] +} + +config("public") { + include_dirs = [ "include" ] +} diff --git a/src/kernel_liteos_a/kernel/extended/dynload/Makefile b/src/kernel_liteos_a/kernel/extended/dynload/Makefile new file mode 100644 index 00000000..a0ffc4d0 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/dynload/Makefile @@ -0,0 +1,38 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := $(wildcard src/*.c) + +LOCAL_FLAGS := $(LITEOS_CFLAGS_INTERWORK) + +include $(MODULE) diff --git a/src/kernel_liteos_a/kernel/extended/dynload/include/los_elf_auxvec_pri.h b/src/kernel_liteos_a/kernel/extended/dynload/include/los_elf_auxvec_pri.h new file mode 100644 index 00000000..a7a485ee --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/dynload/include/los_elf_auxvec_pri.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_ELF_AUXVEC_H +#define _LOS_ELF_AUXVEC_H + +#define AUX_VECTOR_SIZE_ARCH 1 +#define AUX_VECTOR_SIZE_BASE 20 +#define AUX_VECTOR_SIZE ((AUX_VECTOR_SIZE_ARCH + AUX_VECTOR_SIZE_BASE + 1) << 1) + +/* AUX VECTOR */ +#define AUX_NULL 0 +#define AUX_IGNORE 1 +#define AUX_EXECFD 2 +#define AUX_PHDR 3 +#define AUX_PHENT 4 +#define AUX_PHNUM 5 +#define AUX_PAGESZ 6 +#define AUX_BASE 7 +#define AUX_FLAGS 8 +#define AUX_ENTRY 9 +#define AUX_NOTELF 10 +#define AUX_UID 11 +#define AUX_EUID 12 +#define AUX_GID 13 +#define AUX_EGID 14 +#define AUX_PLATFORM 15 +#define AUX_HWCAP 16 +#define AUX_CLKTCK 17 +#define AUX_SECURE 23 +#define AUX_BASE_PLATFORM 24 +#define AUX_RANDOM 25 +#define AUX_HWCAP2 26 +#define AUX_EXECFN 31 +#define AUX_SYSINFO_EHDR 33 + +#define AUX_VEC_ENTRY(vecEnt, vecId, auxId, auxVal) do { \ + (vecEnt)[(vecId)++] = (auxId); \ + (vecEnt)[(vecId)++] = (auxVal); \ +} while (0) + +#endif /* _LOS_ELF_AUXVEC_H */ diff --git a/src/kernel_liteos_a/kernel/extended/dynload/include/los_exec_elf.h b/src/kernel_liteos_a/kernel/extended/dynload/include/los_exec_elf.h new file mode 100644 index 00000000..3a4314f8 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/dynload/include/los_exec_elf.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_EXEC_ELF_H +#define _LOS_EXEC_ELF_H + +#include "los_load_elf.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +extern INT32 LOS_DoExecveFile(const CHAR *fileName, CHAR * const *argv, CHAR * const *envp); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_EXEC_ELF_H */ \ No newline at end of file diff --git a/src/kernel_liteos_a/kernel/extended/dynload/include/los_ld_elf_pri.h b/src/kernel_liteos_a/kernel/extended/dynload/include/los_ld_elf_pri.h new file mode 100644 index 00000000..39e85949 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/dynload/include/los_ld_elf_pri.h @@ -0,0 +1,422 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_LD_ELH_PRI_H +#define _LOS_LD_ELH_PRI_H + +#include "los_base.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/* Elf header */ +#define LD_EI_NIDENT 16 + +typedef struct { + UINT8 elfIdent[LD_EI_NIDENT]; /* Magic number and other info */ + UINT16 elfType; /* Object file type */ + UINT16 elfMachine; /* Architecture */ + UINT32 elfVersion; /* Object file version */ + UINT32 elfEntry; /* Entry point virtual address */ + UINT32 elfPhoff; /* Program header table file offset */ + UINT32 elfShoff; /* Section header table file offset */ + UINT32 elfFlags; /* Processor-specific flags */ + UINT16 elfHeadSize; /* ELF header size in bytes */ + UINT16 elfPhEntSize; /* Program header table entry size */ + UINT16 elfPhNum; /* Program header table entry count */ + UINT16 elfShEntSize; /* Section header table entry size */ + UINT16 elfShNum; /* Section header table entry count */ + UINT16 elfShStrIndex; /* Section header string table index */ +} LDElf32Ehdr; + +typedef struct { + UINT8 elfIdent[LD_EI_NIDENT]; /* Magic number and other info */ + UINT16 elfType; /* Object file type */ + UINT16 elfMachine; /* Architecture */ + UINT32 elfVersion; /* Object file version */ + UINT64 elfEntry; /* Entry point virtual address */ + UINT64 elfPhoff; /* Program header table file offset */ + UINT64 elfShoff; /* Section header table file offset */ + UINT32 elfFlags; /* Processor-specific flags */ + UINT16 elfHeadSize; /* ELF header size in bytes */ + UINT16 elfPhEntSize; /* Program header table entry size */ + UINT16 elfPhNum; /* Program header table entry count */ + UINT16 elfShEntSize; /* Section header table entry size */ + UINT16 elfShNum; /* Section header table entry count */ + UINT16 elfShStrIndex; /* Section header string table index */ +} LDElf64Ehdr; + +#ifdef LOSCFG_AARCH64 +#define LD_ELF_EHDR LDElf64Ehdr +#else +#define LD_ELF_EHDR LDElf32Ehdr +#endif + +/* e_ident[] values */ +#define LD_EI_MAG0 0 +#define LD_EI_MAG1 1 +#define LD_EI_MAG2 2 +#define LD_EI_MAG3 3 +#define LD_EI_CLASS 4 +#define LD_EI_DATA 5 +#define LD_EI_VERSION 6 +#define LD_EI_PAD 7 + +#define LD_ELFMAG0 0x7f +#define LD_ELFMAG1 'E' +#define LD_ELFMAG2 'L' +#define LD_ELFMAG3 'F' +#define LD_ELFMAG "\177ELF" +#define LD_SELFMAG 4 + +/* EI_CLASS */ +#define LD_ELF_CLASS_NONE 0 +#define LD_ELF_CLASS32 1 +#define LD_ELF_CLASS64 2 + +#ifdef LOSCFG_AARCH64 +#define LD_ELF_CLASS LD_ELF_CLASS64 +#else +#define LD_ELF_CLASS LD_ELF_CLASS32 +#endif + +/* EI_DATA */ +#define LD_ELF_DATA_NONE 0 +#define LD_ELF_DATA2LSB 1 +#define LD_ELF_DATA2MSB 2 + +/* e_type */ +#define LD_ET_NONE 0 +#define LD_ET_REL 1 +#define LD_ET_EXEC 2 +#define LD_ET_DYN 3 +#define LD_ET_CORE 4 +#define LD_ET_LOPROC 0xff00 +#define LD_ET_HIPROC 0xffff + +/* e_machine */ +#define LD_EM_NONE 0 /* No machine */ +#define LD_EM_M32 1 /* AT&T WE 32100 */ +#define LD_EM_SPARC 2 /* SPARC */ +#define LD_EM_386 3 /* Intel 80386 */ +#define LD_EM_68K 4 /* Motorola 68000 */ +#define LD_EM_88K 5 /* Motorola 88000 */ +#define LD_EM_486 6 /* Intel 80486 */ +#define LD_EM_860 7 /* Intel 80860 */ +#define LD_EM_MIPS 8 /* MIPS RS3000 Big-Endian */ +#define LD_EM_MIPS_RS4_BE 10 /* MIPS RS4000 Big-Endian */ +#define LD_EM_PPC_OLD 17 /* PowerPC - old */ +#define LD_EM_PPC 20 /* PowerPC */ +#define LD_EM_RCE_OLD 25 /* RCE - old */ +#define LD_EM_RCE 39 /* RCE */ +#define LD_EM_MCORE 39 /* MCORE */ +#define LD_EM_SH 42 /* SH */ +#define LD_EM_M32R 36929 /* M32R */ +#define LD_EM_NEC 36992 /* NEC 850 series */ +#define LD_EM_NEC_830 36 /* NEC 830 series */ +#define LD_EM_SC 58 /* SC */ +#define LD_EM_ARM 40 /* ARM */ +#define LD_EM_XTENSA 0x5E /* XTENSA */ +#define LD_EM_AARCH64 183 /* ARM AARCH64 */ + +#ifdef LOSCFG_AARCH64 +#define LD_EM_TYPE LD_EM_AARCH64 +#else +#define LD_EM_TYPE LD_EM_ARM +#endif + +/* e_flags */ +#define LD_EF_PPC_EMB 0x80000000 + +#define LD_EF_MIPS_NOREORDER 0x00000001 +#define LD_EF_MIPS_PIC 0x00000002 +#define LD_EF_MIPS_CPIC 0x00000004 +#define LD_EF_MIPS_ARCH 0xf0000000 +#define LD_EF_MIPS_ARCH_MIPS_2 0x10000000 +#define LD_EF_MIPS_ARCH_MIPS_3 0x20000000 + +#define LD_PT_NULL 0 +#define LD_PT_LOAD 1 +#define LD_PT_DYNAMIC 2 +#define LD_PT_INTERP 3 +#define LD_PT_NOTE 4 +#define LD_PT_SHLIB 5 +#define LD_PT_PHDR 6 +#define LD_PT_GNU_STACK 0x6474e551 + +/* e_version and EI_VERSION */ +#define LD_EV_NONE 0 +#define LD_EV_CURRENT 1 + +/* Program Header */ +typedef struct { + UINT32 type; /* Segment type */ + UINT32 offset; /* Segment file offset */ + UINT32 vAddr; /* Segment virtual address */ + UINT32 phyAddr; /* Segment physical address */ + UINT32 fileSize; /* Segment size in file */ + UINT32 memSize; /* Segment size in memory */ + UINT32 flags; /* Segment flags */ + UINT32 align; /* Segment alignment */ +} LDElf32Phdr; + +typedef struct { + UINT32 type; /* Segment type */ + UINT32 flags; /* Segment flags */ + UINT64 offset; /* Segment file offset */ + UINT64 vAddr; /* Segment virtual address */ + UINT64 phyAddr; /* Segment physical address */ + UINT64 fileSize; /* Segment size in file */ + UINT64 memSize; /* Segment size in memory */ + UINT64 align; /* Segment alignment */ +} LDElf64Phdr; + +#ifdef LOSCFG_AARCH64 +#define LD_ELF_PHDR LDElf64Phdr +#else +#define LD_ELF_PHDR LDElf32Phdr +#endif + +/* Special section indexes */ +#define LD_SHN_UNDEF 0 +#define LD_SHN_LORESERVE 0xff00 +#define LD_SHN_LOPROC 0xff00 +#define LD_SHN_HIPROC 0xff1f +#define LD_SHN_ABS 0xfff1 +#define LD_SHN_COMMON 0xfff2 +#define LD_SHN_HIRESERVE 0xffff +#define LD_SHN_GHCOMMON 0xff00 + +/* Section header */ +typedef struct { + UINT32 shName; /* Section name (string tbl index) */ + UINT32 shType; /* Section type */ + UINT32 shFlags; /* Section flags */ + UINT32 shAddr; /* Section virtual addr at execution */ + UINT32 shOffset; /* Section file offset */ + UINT32 shSize; /* Section size in bytes */ + UINT32 shLink; /* Link to another section */ + UINT32 shInfo; /* Additional section information */ + UINT32 shAddrAlign; /* Section alignment */ + UINT32 shEntSize; /* Entry size if section holds table */ +} LDElf32Shdr; + +typedef struct { + UINT32 shName; /* Section name (string tbl index) */ + UINT32 shType; /* Section type */ + UINT64 shFlags; /* Section flags */ + UINT64 shAddr; /* Section virtual addr at execution */ + UINT64 shOffset; /* Section file offset */ + UINT64 shSize; /* Section size in bytes */ + UINT32 shLink; /* Link to another section */ + UINT32 shInfo; /* Additional section information */ + UINT64 shAddrAlign; /* Section alignment */ + UINT64 shEntSize; /* Entry size if section holds table */ +} LDElf64Shdr; + +#ifdef LOSCFG_AARCH64 +#define LD_ELF_SHDR LDElf64Shdr +#else +#define LD_ELF_SHDR LDElf32Shdr +#endif + +/* sh_type */ +#define LD_SHT_NULL 0U +#define LD_SHT_PROGBITS 1U +#define LD_SHT_SYMTAB 2U +#define LD_SHT_STRTAB 3U +#define LD_SHT_RELA 4U +#define LD_SHT_HASH 5U +#define LD_SHT_DYNAMIC 6U +#define LD_SHT_NOTE 7U +#define LD_SHT_NOBITS 8U +#define LD_SHT_REL 9U +#define LD_SHT_SHLIB 10U +#define LD_SHT_DYNSYM 11U +#define LD_SHT_COMDAT 12U +#define LD_SHT_LOPROC 0x70000000U +#define LD_SHT_HIPROC 0x7fffffffU +#define LD_SHT_LOUSER 0x80000000U +#define LD_SHT_HIUSER 0xffffffffU + +/* sh_flags */ +#define LD_SHF_WRITE 0x1U +#define LD_SHF_ALLOC 0x2U +#define LD_SHF_EXECINSTR 0x4U +#define LD_SHF_MASKPROC 0xf0000000U + +/* Symbol table */ +typedef struct { + UINT32 stName; /* Symbol table name (string tbl index) */ + UINT32 stValue; /* Symbol table value */ + UINT32 stSize; /* Symbol table size */ + UINT8 stInfo; /* Symbol table type and binding */ + UINT8 stOther; /* Symbol table visibility */ + UINT16 stShndx; /* Section table index */ +} LDElf32Sym; + +typedef struct { + UINT32 stName; /* Symbol table name (string tbl index) */ + UINT8 stInfo; /* Symbol table type and binding */ + UINT8 stOther; /* Symbol table visibility */ + UINT16 stShndx; /* Section table index */ + UINT64 stValue; /* Symbol table value */ + UINT64 stSize; /* Symbol table size */ +} LDElf64Sym; + +#ifdef LOSCFG_AARCH64 +#define LD_ELF_SYM LDElf64Sym +#else +#define LD_ELF_SYM LDElf32Sym +#endif + +#define LD_STN_UNDEF 0U + +#define LD_STB_LOCAL 0U +#define LD_STB_GLOBAL 1U +#define LD_STB_WEAK 2U +#define LD_STB_LOPROC 13U +#define LD_STB_HIPROC 15U + +#define LD_STT_NOTYPE 0U +#define LD_STT_OBJECT 1U +#define LD_STT_FUNC 2U +#define LD_STT_SECTION 3U +#define LD_STT_FILE 4U +#define LD_STT_LOPROC 13U +#define LD_STT_HIPROC 15U +#define LD_STT_THUMB 0x80U + +#define LD_ELF_ST_BIND(info) ((info) >> 4) /* Obtain the binding information of the symbol table */ +#define LD_ELF_ST_TYPE(info) ((info) & 0xFU) /* Obtain the type of the symbol table */ +#define LD_ELF_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xFU)) + +/* Dynamic */ +typedef struct { + UINT32 dynTag; /* Dynamic entry type */ + union { + UINT32 val; /* Integer value */ + UINT32 ptr; /* Address value */ + } dyn; +} LDElf32Dyn; + +typedef struct { + UINT64 dynTag; /* Dynamic entry type */ + union { + UINT64 val; /* Integer value */ + UINT64 ptr; /* Address value */ + } dyn; +} LDElf64Dyn; + +#ifdef LOSCFG_AARCH64 +#define LD_ELF_DYN LDElf64Dyn +#else +#define LD_ELF_DYN LDElf32Dyn +#endif + +/* This is the info that is needed to parse the dynamic section of the file */ +#define LD_DT_NULL 0 +#define LD_DT_NEEDED 1 +#define LD_DT_PLTRELSZ 2 +#define LD_DT_PLTGOT 3 +#define LD_DT_HASH 4 +#define LD_DT_STRTAB 5 +#define LD_DT_SYMTAB 6 +#define LD_DT_RELA 7 +#define LD_DT_RELASZ 8 +#define LD_DT_RELAENT 9 +#define LD_DT_STRSZ 10 +#define LD_DT_SYMENT 11 +#define LD_DT_INIT 12 +#define LD_DT_FINI 13 +#define LD_DT_SONAME 14 +#define LD_DT_RPATH 15 +#define LD_DT_SYMBOLIC 16 +#define LD_DT_REL 17 +#define LD_DT_RELSZ 18 +#define LD_DT_RELENT 19 +#define LD_DT_PLTREL 20 +#define LD_DT_DEBUG 21 +#define LD_DT_TEXTREL 22 +#define LD_DT_JMPREL 23 +#define LD_DT_ENCODING 32 + +/* Relocation */ +typedef struct { + UINT32 offset; /* Address */ + UINT32 info; /* Relocation type and symbol index */ +} LDElf32Rel; + +typedef struct { + UINT32 offset; /* Address */ + UINT32 info; /* Relocation type and symbol index */ + INT32 addend; /* Addend */ +} LDElf32Rela; + +typedef struct { + UINT64 offset; /* Address */ + UINT64 info; /* Relocation type and symbol index */ +} LDElf64Rel; + +typedef struct { + UINT64 offset; /* Address */ + UINT64 info; /* Relocation type and symbol index */ + INT64 addend; /* Addend */ +} LDElf64Rela; + +#ifdef LOSCFG_AARCH64 +#define LD_ELF_REL LDElf64Rel +#define LD_ELF_RELA LDElf64Rela +#else +#define LD_ELF_REL LDElf32Rel +#define LD_ELF_RELA LDElf32Rela +#endif + +#ifdef LOSCFG_AARCH64 +#define LD_ELF_R_SYM(info) ((info) >> 32) +#define LD_ELF_R_TYPE(info) ((info) & 0xFFFFFFFFUL) +#define LD_ELF_R_INFO(sym, type) ((((UINT64)(sym)) << 32) + (type)) +#else +#define LD_ELF_R_SYM(info) ((info) >> 8) +#define LD_ELF_R_TYPE(info) ((info) & 0xFFU) +#define LD_ELF_R_INFO(sym, type) (((sym) << 8) + (UINT8)(type)) +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_LD_ELH_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/extended/dynload/include/los_load_elf.h b/src/kernel_liteos_a/kernel/extended/dynload/include/los_load_elf.h new file mode 100644 index 00000000..4c31ab06 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/dynload/include/los_load_elf.h @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_LOAD_ELF_H +#define _LOS_LOAD_ELF_H + +#include "los_ld_elf_pri.h" +#include "los_elf_auxvec_pri.h" +#include "los_process_pri.h" +#include "los_memory.h" +#include "los_strncpy_from_user.h" +#include "los_strnlen_user.h" +#include "los_user_put.h" +#include "los_user_get.h" +#include "user_copy.h" +#include "sys/stat.h" +#ifdef LOSCFG_DRIVERS_TZDRIVER +#include "fs/file.h" +#endif +#include "unistd.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define INTERP_FULL_PATH "/lib/libc.so" +#define INVALID_FD (-1) +#define STRINGS_COUNT_MAX 256 +#define ELF_PHDR_NUM_MAX 128 +#define FILE_LENGTH_MAX 0x1000000 +#define MEM_SIZE_MAX 0x1000000 + +#ifndef FILE_PATH_MAX +#define FILE_PATH_MAX PATH_MAX +#endif +#ifndef FILE_PATH_MIN +#define FILE_PATH_MIN 2 +#endif + +#define USER_STACK_SIZE 0x100000 +#define USER_PARAM_BYTE_MAX 0x1000 +#define USER_STACK_TOP_MAX USER_ASPACE_TOP_MAX + +#define EXEC_MMAP_BASE 0x02000000 + +#ifdef LOSCFG_ASLR +#define RANDOM_MASK ((((USER_ASPACE_TOP_MAX + GB - 1) & (-GB)) >> 3) - 1) +#endif + +#define STACK_ALIGN_SIZE 0x10 +#define RANDOM_VECTOR_SIZE 1 + +/* The permissions on sections in the program header. */ +#define PF_R 0x4 +#define PF_W 0x2 +#define PF_X 0x1 + +typedef struct { + LD_ELF_EHDR elfEhdr; + LD_ELF_PHDR *elfPhdr; + UINT32 fileLen; + INT32 procfd; +} ELFInfo; + +typedef struct { + ELFInfo execInfo; + ELFInfo interpInfo; + const CHAR *fileName; + CHAR *execName; + INT32 argc; + INT32 envc; + CHAR * const *argv; + CHAR * const *envp; + UINTPTR stackTop; + UINTPTR stackTopMax; + UINTPTR stackBase; + UINTPTR stackParamBase; + UINT32 stackSize; + INT32 stackProt; + UINTPTR argStart; + UINTPTR loadAddr; + UINTPTR elfEntry; + UINTPTR topOfMem; + UINTPTR oldFiles; + LosVmSpace *newSpace; + LosVmSpace *oldSpace; + INT32 randomDevFD; +} ELFLoadInfo; + +STATIC INLINE BOOL OsIsBadUserAddress(VADDR_T vaddr) +{ + return (vaddr >= USER_STACK_TOP_MAX); +} + +extern UINT32 OsGetRndOffset(INT32 randomDevFD); +extern INT32 OsLoadELFFile(ELFLoadInfo *loadInfo); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_ELF_LIB_H */ diff --git a/src/kernel_liteos_a/kernel/extended/dynload/src/los_exec_elf.c b/src/kernel_liteos_a/kernel/extended/dynload/src/los_exec_elf.c new file mode 100644 index 00000000..44b572cc --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/dynload/src/los_exec_elf.c @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_exec_elf.h" +#ifdef LOSCFG_SHELL +#include "show.h" +#endif +#include "los_vm_phys.h" +#include "los_vm_map.h" +#include "los_vm_dump.h" + +STATIC INT32 OsExecve(const ELFLoadInfo *loadInfo) +{ + if ((loadInfo == NULL) || (loadInfo->elfEntry == 0)) { + return LOS_NOK; + } + + return OsExecStart((TSK_ENTRY_FUNC)(loadInfo->elfEntry), (UINTPTR)loadInfo->stackTop, + loadInfo->stackBase, loadInfo->stackSize); +} + +#ifdef LOSCFG_SHELL +STATIC INT32 OsGetRealPath(const CHAR *fileName, CHAR *buf, UINT32 maxLen) +{ + CHAR *workingDirectory = NULL; + UINT32 len, workPathLen, newLen; + + if (access(fileName, F_OK) < 0) { + workingDirectory = OsShellGetWorkingDirectory(); + if (workingDirectory == NULL) { + goto ERR_FILE; + } + len = strlen(fileName); + workPathLen = strlen(workingDirectory); + newLen = len + 1 + workPathLen + 1; + if (newLen >= maxLen) { + return -ENOENT; + } + if (strncpy_s(buf, maxLen, workingDirectory, workPathLen) != EOK) { + PRINT_ERR("strncpy_s failed, errline: %d!\n", __LINE__); + return -ENOENT; + } + buf[workPathLen] = '/'; + if (strncpy_s(buf + workPathLen + 1, maxLen - workPathLen - 1, fileName, len) != EOK) { + PRINT_ERR("strncpy_s failed, errline: %d!\n", __LINE__); + return -ENOENT; + } + buf[newLen] = '\0'; + if (access(buf, F_OK) < 0) { + goto ERR_FILE; + } + } + + return LOS_OK; + +ERR_FILE: + return -ENOENT; +} +#endif + +STATIC INT32 OsCopyUserParam(ELFLoadInfo *loadInfo, const CHAR *fileName, CHAR *kfileName, UINT32 maxSize) +{ + UINT32 strLen; + errno_t err; + + if (LOS_IsUserAddress((VADDR_T)(UINTPTR)fileName)) { + err = LOS_StrncpyFromUser(kfileName, fileName, PATH_MAX + 1); + if (err == -EFAULT) { + return err; + } else if (err > PATH_MAX) { + PRINT_ERR("%s[%d], filename len exceeds maxlen: %d\n", __FUNCTION__, __LINE__, PATH_MAX); + return -ENAMETOOLONG; + } + } else if (LOS_IsKernelAddress((VADDR_T)(UINTPTR)fileName)) { + strLen = strlen(fileName); + err = memcpy_s(kfileName, PATH_MAX, fileName, strLen); + if (err != EOK) { + PRINT_ERR("%s[%d], Copy failed! err: %d\n", __FUNCTION__, __LINE__, err); + return -EFAULT; + } + } else { + return -EINVAL; + } + + loadInfo->fileName = kfileName; + return LOS_OK; +} + +INT32 LOS_DoExecveFile(const CHAR *fileName, CHAR * const *argv, CHAR * const *envp) +{ + ELFLoadInfo loadInfo = { 0 }; + CHAR kfileName[PATH_MAX + 1] = { 0 }; + INT32 ret; +#ifdef LOSCFG_SHELL + CHAR buf[PATH_MAX + 1] = { 0 }; +#endif + + if ((fileName == NULL) || ((argv != NULL) && !LOS_IsUserAddress((VADDR_T)(UINTPTR)argv)) || + ((envp != NULL) && !LOS_IsUserAddress((VADDR_T)(UINTPTR)envp))) { + return -EINVAL; + } + ret = OsCopyUserParam(&loadInfo, fileName, kfileName, PATH_MAX); + if (ret != LOS_OK) { + return ret; + } + +#ifdef LOSCFG_SHELL + if (OsGetRealPath(kfileName, buf, (PATH_MAX + 1)) != LOS_OK) { + return -ENOENT; + } + if (buf[0] != '\0') { + loadInfo.fileName = buf; + } +#endif + + loadInfo.newSpace = OsCreateUserVmSpace(); + if (loadInfo.newSpace == NULL) { + PRINT_ERR("%s %d, failed to allocate new vm space\n", __FUNCTION__, __LINE__); + return -ENOMEM; + } + + loadInfo.argv = argv; + loadInfo.envp = envp; + + ret = OsLoadELFFile(&loadInfo); + if (ret != LOS_OK) { + return ret; + } + + ret = OsExecRecycleAndInit(OsCurrProcessGet(), loadInfo.fileName, loadInfo.oldSpace, loadInfo.oldFiles); + if (ret != LOS_OK) { + (VOID)LOS_VmSpaceFree(loadInfo.oldSpace); + goto OUT; + } + + ret = OsExecve(&loadInfo); + if (ret != LOS_OK) { + goto OUT; + } + + return loadInfo.stackTop; + +OUT: + (VOID)LOS_Exit(OS_PRO_EXIT_OK); + return ret; +} diff --git a/src/kernel_liteos_a/kernel/extended/dynload/src/los_load_elf.c b/src/kernel_liteos_a/kernel/extended/dynload/src/los_load_elf.c new file mode 100644 index 00000000..4fed46b4 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/dynload/src/los_load_elf.c @@ -0,0 +1,1085 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_load_elf.h" +#include "fcntl.h" +#include "fs/fd_table.h" +#include "fs/file.h" +#include "fs/fs_operation.h" +#include "los_config.h" +#include "los_vm_map.h" +#include "los_vm_syscall.h" +#include "los_vm_phys.h" +#include "los_vm_dump.h" +#include "los_vm_lock.h" +#ifdef LOSCFG_KERNEL_VDSO +#include "los_vdso.h" +#endif +#ifdef LOSCFG_DRIVERS_TZDRIVER +#include "tzdriver.h" +#endif + +STATIC BOOL g_srandInit; + +STATIC INT32 OsELFOpen(const CHAR *fileName, INT32 oflags) +{ + INT32 ret; + INT32 procFd; + + procFd = AllocProcessFd(); + if (procFd < 0) { + return -EMFILE; + } + + if (oflags & O_CLOEXEC) { + SetCloexecFlag(procFd); + } + + ret = open(fileName, oflags); + if (ret < 0) { + FreeProcessFd(procFd); + return -get_errno(); + } + + AssociateSystemFd(procFd, ret); + return procFd; +} + +STATIC INT32 OsELFClose(INT32 procFd) +{ + INT32 ret; + /* Process procfd convert to system global procfd */ + INT32 sysfd = DisassociateProcessFd(procFd); + if (sysfd < 0) { + return -EBADF; + } + + ret = close(sysfd); + if (ret < 0) { + AssociateSystemFd(procFd, sysfd); + return -get_errno(); + } + FreeProcessFd(procFd); + return ret; +} + +STATIC INT32 OsGetFileLength(UINT32 *fileLen, const CHAR *fileName) +{ + struct stat buf; + INT32 ret; + + ret = stat(fileName, &buf); + if (ret < 0) { +#ifndef LOSCFG_SHELL + if (strcmp(fileName, "/bin/shell") != 0) { +#endif + PRINT_ERR("%s[%d], Failed to stat file: %s, errno: %d\n", __FUNCTION__, __LINE__, fileName, errno); +#ifndef LOSCFG_SHELL + } +#endif + return LOS_NOK; + } + + if (S_ISREG(buf.st_mode) == 0) { + PRINT_ERR("%s[%d], The file: %s is invalid!\n", __FUNCTION__, __LINE__, fileName); + return LOS_NOK; + } + if (buf.st_size > FILE_LENGTH_MAX) { + PRINT_ERR("%s[%d], The file: %s length is out of limit!\n", __FUNCTION__, __LINE__, fileName); + return LOS_NOK; + } + + *fileLen = (UINT32)buf.st_size; + return LOS_OK; +} + +STATIC INT32 OsReadELFInfo(INT32 procfd, UINT8 *buffer, size_t readSize, off_t offset) +{ + ssize_t byteNum; + off_t returnPos; + INT32 fd = GetAssociatedSystemFd(procfd); + if (fd < 0) { + PRINT_ERR("%s[%d], Invalid procfd!\n", __FUNCTION__, __LINE__); + return LOS_NOK; + } + + if (readSize > 0) { + returnPos = lseek(fd, offset, SEEK_SET); + if (returnPos != offset) { + PRINT_ERR("%s[%d], Failed to seek the position!, offset: %#x\n", __FUNCTION__, __LINE__, offset); + return LOS_NOK; + } + + byteNum = read(fd, buffer, readSize); + if (byteNum <= 0) { + PRINT_ERR("%s[%d], Failed to read from offset: %#x!\n", __FUNCTION__, __LINE__, offset); + return LOS_NOK; + } + } + return LOS_OK; +} + +STATIC INT32 OsVerifyELFEhdr(const LD_ELF_EHDR *ehdr, UINT32 fileLen) +{ + if (memcmp(ehdr->elfIdent, LD_ELFMAG, LD_SELFMAG) != 0) { + PRINT_ERR("%s[%d], The file is not elf!\n", __FUNCTION__, __LINE__); + return LOS_NOK; + } + if ((ehdr->elfType != LD_ET_EXEC) && (ehdr->elfType != LD_ET_DYN)) { + PRINT_ERR("%s[%d], The type of file is not ET_EXEC or ET_DYN!\n", __FUNCTION__, __LINE__); + return LOS_NOK; + } + if (ehdr->elfMachine != LD_EM_ARM) { + PRINT_ERR("%s[%d], The type of machine is not EM_ARM!\n", __FUNCTION__, __LINE__); + return LOS_NOK; + } + if (ehdr->elfPhNum > ELF_PHDR_NUM_MAX) { + PRINT_ERR("%s[%d], The num of program header is out of limit\n", __FUNCTION__, __LINE__); + return LOS_NOK; + } + if (ehdr->elfPhoff > fileLen) { + PRINT_ERR("%s[%d], The offset of program header is invalid, elf file is bad\n", __FUNCTION__, __LINE__); + return LOS_NOK; + } + if (OsIsBadUserAddress((VADDR_T)ehdr->elfEntry)) { + PRINT_ERR("%s[%d], The entry of program is invalid\n", __FUNCTION__, __LINE__); + return LOS_NOK; + } + + return LOS_OK; +} + +STATIC INT32 OsVerifyELFPhdr(const LD_ELF_PHDR *phdr) +{ + if ((phdr->fileSize > FILE_LENGTH_MAX) || (phdr->offset > FILE_LENGTH_MAX)) { + PRINT_ERR("%s[%d], The size of phdr is out of limit\n", __FUNCTION__, __LINE__); + return LOS_NOK; + } + if (phdr->memSize > MEM_SIZE_MAX) { + PRINT_ERR("%s[%d], The mem size of phdr is out of limit\n", __FUNCTION__, __LINE__); + return LOS_NOK; + } + if (OsIsBadUserAddress((VADDR_T)phdr->vAddr)) { + PRINT_ERR("%s[%d], The vaddr of phdr is invalid\n", __FUNCTION__, __LINE__); + return LOS_NOK; + } + + return LOS_OK; +} + +STATIC VOID OsLoadInit(ELFLoadInfo *loadInfo) +{ +#ifdef LOSCFG_FS_VFS + const struct files_struct *oldFiles = OsCurrProcessGet()->files; + loadInfo->oldFiles = (UINTPTR)create_files_snapshot(oldFiles); +#else + loadInfo->oldFiles = NULL; +#endif + loadInfo->execInfo.procfd = INVALID_FD; + loadInfo->interpInfo.procfd = INVALID_FD; +} + +STATIC INT32 OsReadEhdr(const CHAR *fileName, ELFInfo *elfInfo, BOOL isExecFile) +{ + INT32 ret; + + ret = OsGetFileLength(&elfInfo->fileLen, fileName); + if (ret != LOS_OK) { + return -ENOENT; + } + + ret = OsELFOpen(fileName, O_RDONLY | O_EXECVE | O_CLOEXEC); + if (ret < 0) { + PRINT_ERR("%s[%d], Failed to open ELF file: %s!\n", __FUNCTION__, __LINE__, fileName); + return ret; + } + elfInfo->procfd = ret; + +#ifdef LOSCFG_DRIVERS_TZDRIVER + if (isExecFile) { + struct file *filep = NULL; + ret = fs_getfilep(GetAssociatedSystemFd(elfInfo->procfd), &filep); + if (ret) { + PRINT_ERR("%s[%d], Failed to get struct file %s!\n", __FUNCTION__, __LINE__, fileName); + /* File will be closed by OsLoadELFFile */ + return ret; + } + OsCurrProcessGet()->execVnode = filep->f_vnode; + } +#endif + ret = OsReadELFInfo(elfInfo->procfd, (UINT8 *)&elfInfo->elfEhdr, sizeof(LD_ELF_EHDR), 0); + if (ret != LOS_OK) { + PRINT_ERR("%s[%d]\n", __FUNCTION__, __LINE__); + return -EIO; + } + + ret = OsVerifyELFEhdr(&elfInfo->elfEhdr, elfInfo->fileLen); + if (ret != LOS_OK) { + PRINT_ERR("%s[%d]\n", __FUNCTION__, __LINE__); + return isExecFile ? -ENOEXEC : -ELIBBAD; + } + + return LOS_OK; +} + +STATIC INT32 OsReadPhdrs(ELFInfo *elfInfo, BOOL isExecFile) +{ + LD_ELF_EHDR *elfEhdr = &elfInfo->elfEhdr; + UINT32 size; + INT32 ret; + + if (elfEhdr->elfPhNum < 1) { + goto OUT; + } + + if (elfEhdr->elfPhEntSize != sizeof(LD_ELF_PHDR)) { + goto OUT; + } + + size = sizeof(LD_ELF_PHDR) * elfEhdr->elfPhNum; + if ((elfEhdr->elfPhoff + size) > elfInfo->fileLen) { + goto OUT; + } + + elfInfo->elfPhdr = LOS_MemAlloc(m_aucSysMem0, size); + if (elfInfo->elfPhdr == NULL) { + PRINT_ERR("%s[%d], Failed to allocate for elfPhdr!\n", __FUNCTION__, __LINE__); + return -ENOMEM; + } + + ret = OsReadELFInfo(elfInfo->procfd, (UINT8 *)elfInfo->elfPhdr, size, elfEhdr->elfPhoff); + if (ret != LOS_OK) { + (VOID)LOS_MemFree(m_aucSysMem0, elfInfo->elfPhdr); + elfInfo->elfPhdr = NULL; + PRINT_ERR("%s[%d]\n", __FUNCTION__, __LINE__); + return -EIO; + } + + return LOS_OK; +OUT: + PRINT_ERR("%s[%d], elf file is bad!\n", __FUNCTION__, __LINE__); + return isExecFile ? -ENOEXEC : -ELIBBAD; +} + +STATIC INT32 OsReadInterpInfo(ELFLoadInfo *loadInfo) +{ + LD_ELF_PHDR *elfPhdr = loadInfo->execInfo.elfPhdr; + CHAR *elfInterpName = NULL; + INT32 ret, i; + + for (i = 0; i < loadInfo->execInfo.elfEhdr.elfPhNum; ++i, ++elfPhdr) { + if (elfPhdr->type != LD_PT_INTERP) { + continue; + } + + if (OsVerifyELFPhdr(elfPhdr) != LOS_OK) { + return -ENOEXEC; + } + + if ((elfPhdr->fileSize > FILE_PATH_MAX) || (elfPhdr->fileSize < FILE_PATH_MIN) || + (elfPhdr->offset + elfPhdr->fileSize > loadInfo->execInfo.fileLen)) { + PRINT_ERR("%s[%d], The size of file is out of limit!\n", __FUNCTION__, __LINE__); + return -ENOEXEC; + } + + elfInterpName = LOS_MemAlloc(m_aucSysMem0, elfPhdr->fileSize); + if (elfInterpName == NULL) { + PRINT_ERR("%s[%d], Failed to allocate for elfInterpName!\n", __FUNCTION__, __LINE__); + return -ENOMEM; + } + + ret = OsReadELFInfo(loadInfo->execInfo.procfd, (UINT8 *)elfInterpName, elfPhdr->fileSize, elfPhdr->offset); + if (ret != LOS_OK) { + PRINT_ERR("%s[%d]\n", __FUNCTION__, __LINE__); + ret = -EIO; + goto OUT; + } + + if (elfInterpName[elfPhdr->fileSize - 1] != '\0') { + PRINT_ERR("%s[%d], The name of interpreter is invalid!\n", __FUNCTION__, __LINE__); + ret = -ENOEXEC; + goto OUT; + } + + ret = OsReadEhdr(INTERP_FULL_PATH, &loadInfo->interpInfo, FALSE); + if (ret != LOS_OK) { + PRINT_ERR("%s[%d]\n", __FUNCTION__, __LINE__); + goto OUT; + } + + ret = OsReadPhdrs(&loadInfo->interpInfo, FALSE); + if (ret != LOS_OK) { + goto OUT; + } + + (VOID)LOS_MemFree(m_aucSysMem0, elfInterpName); + break; + } + + return LOS_OK; + +OUT: + (VOID)LOS_MemFree(m_aucSysMem0, elfInterpName); + return ret; +} + +STATIC UINT32 OsGetProt(UINT32 pFlags) +{ + UINT32 prot; + + prot = (((pFlags & PF_R) ? PROT_READ : 0) | + ((pFlags & PF_W) ? PROT_WRITE : 0) | + ((pFlags & PF_X) ? PROT_EXEC : 0)); + return prot; +} + +STATIC UINT32 OsGetAllocSize(const LD_ELF_PHDR *elfPhdr, INT32 phdrNum) +{ + const LD_ELF_PHDR *elfPhdrTemp = elfPhdr; + UINTPTR addrMin = SIZE_MAX; + UINTPTR addrMax = 0; + UINT32 offStart = 0; + UINT64 size; + INT32 i; + + for (i = 0; i < phdrNum; ++i, ++elfPhdrTemp) { + if (elfPhdrTemp->type != LD_PT_LOAD) { + continue; + } + + if (OsVerifyELFPhdr(elfPhdrTemp) != LOS_OK) { + return 0; + } + + if (elfPhdrTemp->vAddr < addrMin) { + addrMin = elfPhdrTemp->vAddr; + offStart = elfPhdrTemp->offset; + } + if ((elfPhdrTemp->vAddr + elfPhdrTemp->memSize) > addrMax) { + addrMax = elfPhdrTemp->vAddr + elfPhdrTemp->memSize; + } + } + + if (OsIsBadUserAddress((VADDR_T)addrMax) || OsIsBadUserAddress((VADDR_T)addrMin) || (addrMax < addrMin)) { + return 0; + } + size = ROUNDUP(addrMax, PAGE_SIZE) - ROUNDDOWN(addrMin, PAGE_SIZE) + ROUNDDOWN(offStart, PAGE_SIZE); + + return (size > UINT_MAX) ? 0 : (UINT32)size; +} + +STATIC UINTPTR OsDoMmapFile(INT32 fd, UINTPTR addr, const LD_ELF_PHDR *elfPhdr, UINT32 prot, UINT32 flags, + UINT32 mapSize) +{ + UINTPTR mapAddr; + UINT32 size; + UINT32 offset = elfPhdr->offset - ROUNDOFFSET(elfPhdr->vAddr, PAGE_SIZE); + addr = ROUNDDOWN(addr, PAGE_SIZE); + + if (mapSize != 0) { + mapAddr = (UINTPTR)LOS_MMap(addr, mapSize, prot, flags, fd, offset >> PAGE_SHIFT); + } else { + size = elfPhdr->memSize + ROUNDOFFSET(elfPhdr->vAddr, PAGE_SIZE); + if (size == 0) { + return addr; + } + mapAddr = (UINTPTR)LOS_MMap(addr, size, prot, flags, fd, offset >> PAGE_SHIFT); + } + if (!LOS_IsUserAddress((VADDR_T)mapAddr)) { + PRINT_ERR("%s %d, Failed to map a valid addr\n", __FUNCTION__, __LINE__); + return 0; + } + return mapAddr; +} + +INT32 OsGetKernelVaddr(LosVmSpace *space, VADDR_T vaddr, VADDR_T *kvaddr) +{ + INT32 ret; + PADDR_T paddr = 0; + + if ((space == NULL) || (vaddr == 0) || (kvaddr == NULL)) { + PRINT_ERR("%s[%d], space: %#x, vaddr: %#x\n", __FUNCTION__, __LINE__, space, vaddr); + return LOS_NOK; + } + + if (LOS_IsKernelAddress(vaddr)) { + *kvaddr = vaddr; + return LOS_OK; + } + + ret = LOS_ArchMmuQuery(&space->archMmu, vaddr, &paddr, NULL); + if (ret != LOS_OK) { + PRINT_ERR("%s[%d], Failed to query the vaddr: %#x, status: %d\n", __FUNCTION__, __LINE__, vaddr, ret); + return LOS_NOK; + } + *kvaddr = (VADDR_T)(UINTPTR)LOS_PaddrToKVaddr(paddr); + if (*kvaddr == 0) { + PRINT_ERR("%s[%d], kvaddr is null\n", __FUNCTION__, __LINE__); + return LOS_NOK; + } + + return LOS_OK; +} + +STATIC INT32 OsSetBss(const LD_ELF_PHDR *elfPhdr, INT32 fd, UINTPTR bssStart, UINT32 bssEnd, UINT32 elfProt) +{ + UINTPTR bssStartPageAlign, bssEndPageAlign; + UINTPTR mapBase; + UINT32 bssMapSize; + INT32 stackFlags; + INT32 ret; + + bssStartPageAlign = ROUNDUP(bssStart, PAGE_SIZE); + bssEndPageAlign = ROUNDUP(bssEnd, PAGE_SIZE); + + ret = LOS_UserMemClear((VOID *)bssStart, PAGE_SIZE - ROUNDOFFSET(bssStart, PAGE_SIZE)); + if (ret != 0) { + PRINT_ERR("%s[%d], Failed to clear bss\n", __FUNCTION__, __LINE__); + return -EFAULT; + } + + bssMapSize = bssEndPageAlign - bssStartPageAlign; + if (bssMapSize > 0) { + stackFlags = MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS; + mapBase = (UINTPTR)LOS_MMap(bssStartPageAlign, bssMapSize, elfProt, stackFlags, -1, 0); + if (!LOS_IsUserAddress((VADDR_T)mapBase)) { + PRINT_ERR("%s[%d], Failed to map bss\n", __FUNCTION__, __LINE__); + return -ENOMEM; + } + } + + return LOS_OK; +} + +STATIC INT32 OsMmapELFFile(INT32 procfd, const LD_ELF_PHDR *elfPhdr, const LD_ELF_EHDR *elfEhdr, UINTPTR *elfLoadAddr, + UINT32 mapSize, UINTPTR *loadBase) +{ + const LD_ELF_PHDR *elfPhdrTemp = elfPhdr; + UINTPTR vAddr, mapAddr, bssStart; + UINT32 bssEnd, elfProt, elfFlags; + INT32 ret, i; + INT32 fd = GetAssociatedSystemFd(procfd); + + for (i = 0; i < elfEhdr->elfPhNum; ++i, ++elfPhdrTemp) { + if (elfPhdrTemp->type != LD_PT_LOAD) { + continue; + } + if (elfEhdr->elfType == LD_ET_EXEC) { + if (OsVerifyELFPhdr(elfPhdrTemp) != LOS_OK) { + return -ENOEXEC; + } + } + + elfProt = OsGetProt(elfPhdrTemp->flags); + if ((elfProt & PROT_READ) == 0) { + return -ENOEXEC; + } + elfFlags = MAP_PRIVATE | MAP_FIXED; + vAddr = elfPhdrTemp->vAddr; + if ((vAddr == 0) && (*loadBase == 0)) { + elfFlags &= ~MAP_FIXED; + } + + mapAddr = OsDoMmapFile(fd, (vAddr + *loadBase), elfPhdrTemp, elfProt, elfFlags, mapSize); + if (!LOS_IsUserAddress((VADDR_T)mapAddr)) { + return -ENOMEM; + } +#ifdef LOSCFG_DRIVERS_TZDRIVER + if ((elfPhdrTemp->flags & PF_R) && (elfPhdrTemp->flags & PF_X) && !(elfPhdrTemp->flags & PF_W)) { + SetVmmRegionCodeStart(vAddr + *loadBase, elfPhdrTemp->memSize); + } +#endif + mapSize = 0; + + if (*elfLoadAddr == 0) { + *elfLoadAddr = mapAddr + ROUNDOFFSET(vAddr, PAGE_SIZE); + } + + if ((*loadBase == 0) && (elfEhdr->elfType == LD_ET_DYN)) { + *loadBase = mapAddr; + } + + if ((elfPhdrTemp->memSize > elfPhdrTemp->fileSize) && (elfPhdrTemp->flags & PF_W)) { + bssStart = mapAddr + ROUNDOFFSET(vAddr, PAGE_SIZE) + elfPhdrTemp->fileSize; + bssEnd = mapAddr + ROUNDOFFSET(vAddr, PAGE_SIZE) + elfPhdrTemp->memSize; + ret = OsSetBss(elfPhdrTemp, fd, bssStart, bssEnd, elfProt); + if (ret != LOS_OK) { + return ret; + } + } + } + + return LOS_OK; +} + +STATIC INT32 OsLoadInterpBinary(ELFLoadInfo *loadInfo, UINTPTR *interpMapBase) +{ + UINTPTR loadBase = 0; + UINT32 mapSize; + INT32 ret; + + mapSize = OsGetAllocSize(loadInfo->interpInfo.elfPhdr, loadInfo->interpInfo.elfEhdr.elfPhNum); + if (mapSize == 0) { + PRINT_ERR("%s[%d], Failed to get interp allocation size!\n", __FUNCTION__, __LINE__); + return -EINVAL; + } + + ret = OsMmapELFFile(loadInfo->interpInfo.procfd, loadInfo->interpInfo.elfPhdr, &loadInfo->interpInfo.elfEhdr, + interpMapBase, mapSize, &loadBase); + if (ret != LOS_OK) { + PRINT_ERR("%s[%d]\n", __FUNCTION__, __LINE__); + } + + return ret; +} + +STATIC CHAR *OsGetParamPtr(CHAR * const *ptr, INT32 index) +{ + UINTPTR userStrPtr = 0; + INT32 ret; + + if (ptr == NULL) { + return NULL; + } + + if (LOS_IsKernelAddress((UINTPTR)ptr)) { + return ptr[index]; + } + ret = LOS_GetUser(&userStrPtr, (UINTPTR *)(ptr + index)); + if (ret != LOS_OK) { + PRINT_ERR("%s[%d], %#x\n", __FUNCTION__, __LINE__, ptr); + return NULL; + } + + return (CHAR *)userStrPtr; +} + +STATIC INT32 OsPutUserArg(INT32 val, const UINTPTR *sp) +{ + INT32 ret; + + if (sp == NULL) { + return LOS_NOK; + } + + ret = LOS_PutUser((INT32 *)&val, (INT32 *)sp); + if (ret != LOS_OK) { + PRINT_ERR("%s[%d]\n", __FUNCTION__, __LINE__); + return -EFAULT; + } + + return LOS_OK; +} + +STATIC INT32 OsPutUserArgv(UINTPTR *strPtr, UINTPTR **sp, INT32 count) +{ + INT32 len; + INT32 i; + CHAR *ptr = NULL; + + if ((strPtr == NULL) || (sp == NULL)) { + return LOS_NOK; + } + + for (i = 0; i < count; ++i) { + /* put the addr of arg strings to user stack */ + if (OsPutUserArg(*strPtr, *sp) != LOS_OK) { + return LOS_NOK; + } + ptr = OsGetParamPtr((CHAR **)strPtr, 0); + if (ptr == NULL) { + return LOS_NOK; + } + len = LOS_StrnlenUser(ptr, PATH_MAX); + if (len == 0) { + return LOS_NOK; + } + *strPtr += len; + ++(*sp); + } + /* put zero to end of argv */ + if (OsPutUserArg(0, *sp) != LOS_OK) { + return LOS_NOK; + } + ++(*sp); + + return LOS_OK; +} + +STATIC INT32 OsCopyParams(ELFLoadInfo *loadInfo, INT32 argc, CHAR *const *argv) +{ + CHAR *strPtr = NULL; + UINT32 offset, strLen; + errno_t err; + INT32 ret, i; + vaddr_t kvaddr = 0; + + if ((argc > 0) && (argv == NULL)) { + return -EINVAL; + } + + ret = OsGetKernelVaddr(loadInfo->newSpace, loadInfo->stackParamBase, &kvaddr); + if (ret != LOS_OK) { + PRINT_ERR("%s[%d]\n", __FUNCTION__, __LINE__); + return -EFAULT; + } + + for (i = argc - 1; i >= 0; --i) { + strPtr = OsGetParamPtr(argv, i); + if (LOS_IsKernelAddress((VADDR_T)(UINTPTR)strPtr)) { + strLen = strlen(strPtr) + 1; + } else { + strLen = LOS_StrnlenUser(strPtr, PATH_MAX); + } + if (strLen < 1) { + continue; + } + + offset = loadInfo->topOfMem - loadInfo->stackParamBase; + if (offset < strLen) { + PRINT_ERR("%s[%d], The size of param is out of limit: %#x bytes!\n", __FUNCTION__, __LINE__, + USER_PARAM_BYTE_MAX); + return -E2BIG; + } + loadInfo->topOfMem -= strLen; + offset -= strLen; + + /* copy strings to user stack */ + if (LOS_IsKernelAddress((VADDR_T)(UINTPTR)strPtr)) { + err = memcpy_s((VOID *)(UINTPTR)(kvaddr + offset), strLen, strPtr, strLen); + } else { + err = LOS_ArchCopyFromUser((VOID *)(UINTPTR)(kvaddr + offset), strPtr, strLen); + } + + if (err != EOK) { + PRINT_ERR("%s[%d], copy strings failed! err: %d\n", __FUNCTION__, __LINE__, err); + return -EFAULT; + } + } + + return LOS_OK; +} + +STATIC INT32 OsGetParamNum(CHAR *const *argv) +{ + CHAR *argPtr = NULL; + INT32 count = 0; + INT32 ret; + + if (argv == NULL) { + return count; + } + + argPtr = OsGetParamPtr(argv, count); + while (argPtr != NULL) { + ret = LOS_StrnlenUser(argPtr, PATH_MAX); + if ((ret == 0) || (ret > PATH_MAX)) { + PRINT_ERR("%s[%d], the len of string of argv is invalid, index: %d, len: %d\n", __FUNCTION__, + __LINE__, count, ret); + break; + } + ++count; + if (count >= STRINGS_COUNT_MAX) { + break; + } + argPtr = OsGetParamPtr(argv, count); + } + + return count; +} + +UINT32 OsGetRndOffset(INT32 randomDevFD) +{ + UINT32 randomValue = 0; + +#ifdef LOSCFG_ASLR + if (read(randomDevFD, &randomValue, sizeof(UINT32)) == sizeof(UINT32)) { + randomValue &= RANDOM_MASK; + } else { + randomValue = (UINT32)random() & RANDOM_MASK; + } +#else + (VOID)randomDevFD; +#endif + + return ROUNDDOWN(randomValue, PAGE_SIZE); +} + +STATIC VOID OsGetStackProt(ELFLoadInfo *loadInfo) +{ + LD_ELF_PHDR *elfPhdrTemp = loadInfo->execInfo.elfPhdr; + INT32 i; + + for (i = 0; i < loadInfo->execInfo.elfEhdr.elfPhNum; ++i, ++elfPhdrTemp) { + if (elfPhdrTemp->type == LD_PT_GNU_STACK) { + loadInfo->stackProt = OsGetProt(elfPhdrTemp->flags); + } + } +} + +STATIC UINT32 OsStackAlloc(LosVmSpace *space, VADDR_T vaddr, UINT32 vsize, UINT32 psize, UINT32 regionFlags) +{ + LosVmPage *vmPage = NULL; + VADDR_T *kvaddr = NULL; + LosVmMapRegion *region = NULL; + VADDR_T vaddrTemp; + PADDR_T paddrTemp; + UINT32 len; + + (VOID)LOS_MuxAcquire(&space->regionMux); + kvaddr = LOS_PhysPagesAllocContiguous(psize >> PAGE_SHIFT); + if (kvaddr == NULL) { + goto OUT; + } + + region = LOS_RegionAlloc(space, vaddr, vsize, regionFlags | VM_MAP_REGION_FLAG_FIXED, 0); + if (region == NULL) { + goto PFREE; + } + + len = psize; + vaddrTemp = region->range.base + vsize - psize; + paddrTemp = LOS_PaddrQuery(kvaddr); + while (len > 0) { + vmPage = LOS_VmPageGet(paddrTemp); + LOS_AtomicInc(&vmPage->refCounts); + + (VOID)LOS_ArchMmuMap(&space->archMmu, vaddrTemp, paddrTemp, 1, region->regionFlags); + + paddrTemp += PAGE_SIZE; + vaddrTemp += PAGE_SIZE; + len -= PAGE_SIZE; + } + (VOID)LOS_MuxRelease(&space->regionMux); + return LOS_OK; + +PFREE: + (VOID)LOS_PhysPagesFreeContiguous(kvaddr, psize >> PAGE_SHIFT); +OUT: + (VOID)LOS_MuxRelease(&space->regionMux); + return LOS_NOK; +} + +STATIC INT32 OsSetArgParams(ELFLoadInfo *loadInfo, CHAR *const *argv, CHAR *const *envp) +{ + UINT32 vmFlags; + INT32 ret; + + loadInfo->randomDevFD = open("/dev/urandom", O_RDONLY); + if (loadInfo->randomDevFD < 0) { + if (!g_srandInit) { + srand((UINT32)time(NULL)); + g_srandInit = TRUE; + } + } + + (VOID)OsGetStackProt(loadInfo); + if (((UINT32)loadInfo->stackProt & (PROT_READ | PROT_WRITE)) != (PROT_READ | PROT_WRITE)) { + return -ENOEXEC; + } + loadInfo->stackTopMax = USER_STACK_TOP_MAX - OsGetRndOffset(loadInfo->randomDevFD); + loadInfo->stackBase = loadInfo->stackTopMax - USER_STACK_SIZE; + loadInfo->stackSize = USER_STACK_SIZE; + loadInfo->stackParamBase = loadInfo->stackTopMax - USER_PARAM_BYTE_MAX; + vmFlags = OsCvtProtFlagsToRegionFlags(loadInfo->stackProt, MAP_FIXED); + vmFlags |= VM_MAP_REGION_FLAG_STACK; + ret = OsStackAlloc((VOID *)loadInfo->newSpace, loadInfo->stackBase, USER_STACK_SIZE, + USER_PARAM_BYTE_MAX, vmFlags); + if (ret != LOS_OK) { + PRINT_ERR("%s[%d], Failed to alloc memory for user stack!\n", __FUNCTION__, __LINE__); + return -ENOMEM; + } + loadInfo->topOfMem = loadInfo->stackTopMax - sizeof(UINTPTR); + + loadInfo->argc = OsGetParamNum(argv); + loadInfo->envc = OsGetParamNum(envp); + ret = OsCopyParams(loadInfo, 1, (CHAR *const *)&loadInfo->fileName); + if (ret != LOS_OK) { + PRINT_ERR("%s[%d], Failed to copy filename to user stack!\n", __FUNCTION__, __LINE__); + return ret; + } + loadInfo->execName = (CHAR *)loadInfo->topOfMem; + + ret = OsCopyParams(loadInfo, loadInfo->envc, envp); + if (ret != LOS_OK) { + return ret; + } + ret = OsCopyParams(loadInfo, loadInfo->argc, argv); + if (ret != LOS_OK) { + return ret; + } + loadInfo->argStart = loadInfo->topOfMem; + + return LOS_OK; +} + +STATIC INT32 OsPutParamToStack(ELFLoadInfo *loadInfo, const UINTPTR *auxVecInfo, INT32 vecIndex) +{ + UINTPTR *topMem = (UINTPTR *)ROUNDDOWN(loadInfo->topOfMem, sizeof(UINTPTR)); + UINTPTR *argsPtr = NULL; + INT32 items = (loadInfo->argc + 1) + (loadInfo->envc + 1) + 1; + size_t size; + + loadInfo->topOfMem = ROUNDDOWN((UINTPTR)(topMem - vecIndex - items), STACK_ALIGN_SIZE); + argsPtr = (UINTPTR *)loadInfo->topOfMem; + loadInfo->stackTop = (UINTPTR)argsPtr; + + if ((loadInfo->stackTopMax - loadInfo->stackTop) > USER_PARAM_BYTE_MAX) { + return -E2BIG; + } + + if (OsPutUserArg(loadInfo->argc, argsPtr)) { + PRINT_ERR("%s[%d], Failed to put argc to user stack!\n", __FUNCTION__, __LINE__); + return -EFAULT; + } + + argsPtr++; + + if ((OsPutUserArgv(&loadInfo->argStart, &argsPtr, loadInfo->argc) != LOS_OK) || + (OsPutUserArgv(&loadInfo->argStart, &argsPtr, loadInfo->envc) != LOS_OK)) { + PRINT_ERR("%s[%d], Failed to put argv or envp to user stack!\n", __FUNCTION__, __LINE__); + return -EFAULT; + } + + size = LOS_ArchCopyToUser(argsPtr, auxVecInfo, vecIndex * sizeof(UINTPTR)); + if (size != 0) { + PRINT_ERR("%s[%d], Failed to copy strings! Bytes not copied: %d\n", __FUNCTION__, __LINE__, size); + return -EFAULT; + } + + return LOS_OK; +} + +STATIC INT32 OsGetRndNum(const ELFLoadInfo *loadInfo, UINT32 *rndVec, UINT32 vecSize) +{ + UINT32 randomValue = 0; + UINT32 i, ret; + + for (i = 0; i < vecSize; ++i) { + ret = read(loadInfo->randomDevFD, &randomValue, sizeof(UINT32)); + if (ret != sizeof(UINT32)) { + rndVec[i] = (UINT32)random(); + continue; + } + rndVec[i] = randomValue; + } + + return LOS_OK; +} + +STATIC INT32 OsMakeArgsStack(ELFLoadInfo *loadInfo, UINTPTR interpMapBase) +{ + UINTPTR auxVector[AUX_VECTOR_SIZE] = { 0 }; + UINTPTR *auxVecInfo = (UINTPTR *)auxVector; + INT32 vecIndex = 0; + UINT32 rndVec[RANDOM_VECTOR_SIZE]; + UINTPTR rndVecStart; + INT32 ret; +#ifdef LOSCFG_KERNEL_VDSO + vaddr_t vdsoLoadAddr; +#endif + + ret = OsGetRndNum(loadInfo, rndVec, sizeof(rndVec)); + if (ret != LOS_OK) { + return ret; + } + loadInfo->topOfMem -= sizeof(rndVec); + rndVecStart = loadInfo->topOfMem; + + ret = LOS_ArchCopyToUser((VOID *)loadInfo->topOfMem, rndVec, sizeof(rndVec)); + if (ret != 0) { + return -EFAULT; + } + + AUX_VEC_ENTRY(auxVector, vecIndex, AUX_PHDR, loadInfo->loadAddr + loadInfo->execInfo.elfEhdr.elfPhoff); + AUX_VEC_ENTRY(auxVector, vecIndex, AUX_PHENT, sizeof(LD_ELF_PHDR)); + AUX_VEC_ENTRY(auxVector, vecIndex, AUX_PHNUM, loadInfo->execInfo.elfEhdr.elfPhNum); + AUX_VEC_ENTRY(auxVector, vecIndex, AUX_PAGESZ, PAGE_SIZE); + AUX_VEC_ENTRY(auxVector, vecIndex, AUX_BASE, interpMapBase); + AUX_VEC_ENTRY(auxVector, vecIndex, AUX_FLAGS, 0); + AUX_VEC_ENTRY(auxVector, vecIndex, AUX_ENTRY, loadInfo->execInfo.elfEhdr.elfEntry); + AUX_VEC_ENTRY(auxVector, vecIndex, AUX_UID, 0); + AUX_VEC_ENTRY(auxVector, vecIndex, AUX_EUID, 0); + AUX_VEC_ENTRY(auxVector, vecIndex, AUX_GID, 0); + AUX_VEC_ENTRY(auxVector, vecIndex, AUX_EGID, 0); + AUX_VEC_ENTRY(auxVector, vecIndex, AUX_HWCAP, 0); + AUX_VEC_ENTRY(auxVector, vecIndex, AUX_CLKTCK, 0); + AUX_VEC_ENTRY(auxVector, vecIndex, AUX_SECURE, 0); + AUX_VEC_ENTRY(auxVector, vecIndex, AUX_RANDOM, rndVecStart); + AUX_VEC_ENTRY(auxVector, vecIndex, AUX_EXECFN, (UINTPTR)loadInfo->execName); + +#ifdef LOSCFG_KERNEL_VDSO + vdsoLoadAddr = OsVdsoLoad(OsCurrProcessGet()); + if (vdsoLoadAddr != 0) { + AUX_VEC_ENTRY(auxVector, vecIndex, AUX_SYSINFO_EHDR, vdsoLoadAddr); + } +#endif + AUX_VEC_ENTRY(auxVector, vecIndex, AUX_NULL, 0); + + ret = OsPutParamToStack(loadInfo, auxVecInfo, vecIndex); + if (ret != LOS_OK) { + PRINT_ERR("%s[%d], Failed to put param to user stack\n", __FUNCTION__, __LINE__); + return ret; + } + + return LOS_OK; +} + +STATIC INT32 OsLoadELFSegment(ELFLoadInfo *loadInfo) +{ + LD_ELF_PHDR *elfPhdrTemp = loadInfo->execInfo.elfPhdr; + UINTPTR loadBase = 0; + UINTPTR interpMapBase = 0; + UINT32 mapSize = 0; + INT32 ret; + loadInfo->loadAddr = 0; + + if (loadInfo->execInfo.elfEhdr.elfType == LD_ET_DYN) { + loadBase = EXEC_MMAP_BASE + OsGetRndOffset(loadInfo->randomDevFD); + mapSize = OsGetAllocSize(elfPhdrTemp, loadInfo->execInfo.elfEhdr.elfPhNum); + if (mapSize == 0) { + PRINT_ERR("%s[%d], Failed to get allocation size of file: %s!\n", __FUNCTION__, __LINE__, + loadInfo->fileName); + return -EINVAL; + } + } + + ret = OsMmapELFFile(loadInfo->execInfo.procfd, loadInfo->execInfo.elfPhdr, &loadInfo->execInfo.elfEhdr, + &loadInfo->loadAddr, mapSize, &loadBase); + OsELFClose(loadInfo->execInfo.procfd); + loadInfo->execInfo.procfd = INVALID_FD; + if (ret != LOS_OK) { + PRINT_ERR("%s[%d]\n", __FUNCTION__, __LINE__); + return ret; + } + + if (loadInfo->interpInfo.procfd != INVALID_FD) { + ret = OsLoadInterpBinary(loadInfo, &interpMapBase); + OsELFClose(loadInfo->interpInfo.procfd); + loadInfo->interpInfo.procfd = INVALID_FD; + if (ret != LOS_OK) { + return ret; + } + + loadInfo->elfEntry = loadInfo->interpInfo.elfEhdr.elfEntry + interpMapBase; + loadInfo->execInfo.elfEhdr.elfEntry = loadInfo->execInfo.elfEhdr.elfEntry + loadBase; + } else { + loadInfo->elfEntry = loadInfo->execInfo.elfEhdr.elfEntry; + } + + ret = OsMakeArgsStack(loadInfo, interpMapBase); + if (ret != LOS_OK) { + return ret; + } + if (!LOS_IsUserAddress((VADDR_T)loadInfo->stackTop)) { + PRINT_ERR("%s[%d], StackTop is out of limit!\n", __FUNCTION__, __LINE__); + return -EINVAL; + } + + return LOS_OK; +} + +STATIC VOID OsFlushAspace(ELFLoadInfo *loadInfo) +{ + loadInfo->oldSpace = OsExecProcessVmSpaceReplace(loadInfo->newSpace, loadInfo->stackBase, loadInfo->randomDevFD); +} + +STATIC VOID OsDeInitLoadInfo(ELFLoadInfo *loadInfo) +{ + (VOID)close(loadInfo->randomDevFD); + + if (loadInfo->execInfo.elfPhdr != NULL) { + (VOID)LOS_MemFree(m_aucSysMem0, loadInfo->execInfo.elfPhdr); + } + + if (loadInfo->interpInfo.elfPhdr != NULL) { + (VOID)LOS_MemFree(m_aucSysMem0, loadInfo->interpInfo.elfPhdr); + } +} + +STATIC VOID OsDeInitFiles(ELFLoadInfo *loadInfo) +{ + if (loadInfo->execInfo.procfd != INVALID_FD) { + (VOID)OsELFClose(loadInfo->execInfo.procfd); + } + + if (loadInfo->interpInfo.procfd != INVALID_FD) { + (VOID)OsELFClose(loadInfo->interpInfo.procfd); + } +#ifdef LOSCFG_FS_VFS + delete_files_snapshot((struct files_struct *)loadInfo->oldFiles); +#endif +} + +INT32 OsLoadELFFile(ELFLoadInfo *loadInfo) +{ + INT32 ret; + + OsLoadInit(loadInfo); + + ret = OsReadEhdr(loadInfo->fileName, &loadInfo->execInfo, TRUE); + if (ret != LOS_OK) { + goto OUT; + } + + ret = OsReadPhdrs(&loadInfo->execInfo, TRUE); + if (ret != LOS_OK) { + goto OUT; + } + + ret = OsReadInterpInfo(loadInfo); + if (ret != LOS_OK) { + goto OUT; + } + + ret = OsSetArgParams(loadInfo, loadInfo->argv, loadInfo->envp); + if (ret != LOS_OK) { + goto OUT; + } + + OsFlushAspace(loadInfo); + + ret = OsLoadELFSegment(loadInfo); + if (ret != LOS_OK) { + OsExecProcessVmSpaceRestore(loadInfo->oldSpace); + goto OUT; + } + + OsDeInitLoadInfo(loadInfo); + + return LOS_OK; + +OUT: + OsDeInitFiles(loadInfo); + (VOID)LOS_VmSpaceFree(loadInfo->newSpace); + (VOID)OsDeInitLoadInfo(loadInfo); + return ret; +} diff --git a/src/kernel_liteos_a/kernel/extended/hidumper/BUILD.gn b/src/kernel_liteos_a/kernel/extended/hidumper/BUILD.gn new file mode 100644 index 00000000..93f74119 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/hidumper/BUILD.gn @@ -0,0 +1,41 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = defined(LOSCFG_HIDUMPER) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ "los_hidumper.c" ] + public_configs = [ ":public" ] +} + +config("public") { + include_dirs = [ "." ] +} diff --git a/src/kernel_liteos_a/kernel/extended/hidumper/Kconfig b/src/kernel_liteos_a/kernel/extended/hidumper/Kconfig new file mode 100644 index 00000000..068290fc --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/hidumper/Kconfig @@ -0,0 +1,6 @@ +config HIDUMPER + bool "Enable hidumper" + default n + depends on KERNEL_EXTKERNEL + help + Answer Y to enable LiteOS support hidumper diff --git a/src/kernel_liteos_a/kernel/extended/hidumper/Makefile b/src/kernel_liteos_a/kernel/extended/hidumper/Makefile new file mode 100644 index 00000000..eab29ad3 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/hidumper/Makefile @@ -0,0 +1,7 @@ +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := $(wildcard *.c) + +include $(MODULE) diff --git a/src/kernel_liteos_a/kernel/extended/hidumper/los_hidumper.c b/src/kernel_liteos_a/kernel/extended/hidumper/los_hidumper.c new file mode 100644 index 00000000..ce86ec8a --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/hidumper/los_hidumper.c @@ -0,0 +1,381 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* ------------ includes ------------ */ +#include "los_hidumper.h" +#ifdef LOSCFG_BLACKBOX +#include "los_blackbox.h" +#endif +#ifdef LOSCFG_CPUP_INCLUDE_IRQ +#include "los_cpup_pri.h" +#endif +#include "los_hwi_pri.h" +#include "los_init.h" +#include "los_mp.h" +#include "los_mux.h" +#include "los_printf.h" +#include "los_process_pri.h" +#include "los_task_pri.h" +#include "los_vm_dump.h" +#include "los_vm_lock.h" +#include "los_vm_map.h" +#ifdef LOSCFG_FS_VFS +#include "fs/file.h" +#endif +#include "fs/driver.h" +#include "securec.h" +#ifdef LOSCFG_LIB_LIBC +#include "unistd.h" +#endif +#include "user_copy.h" + +/* ------------ local macroes ------------ */ +#define CPUP_TYPE_COUNT 3 +#define HIDUMPER_DEVICE "/dev/hidumper" +#define HIDUMPER_DEVICE_MODE 0666 +#define KERNEL_FAULT_ADDR 0x1 +#define KERNEL_FAULT_VALUE 0x2 +#define READ_BUF_SIZE 128 +#define SYS_INFO_HEADER "************ sys info ***********" +#define CPU_USAGE_HEADER "************ cpu usage ***********" +#define MEM_USAGE_HEADER "************ mem usage ***********" +#define PAGE_USAGE_HEADER "************ physical page usage ***********" +#define TASK_INFO_HEADER "************ task info ***********" +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0])) +#endif +#define REPLACE_INTERFACE(dst, src, type, func) { \ + if (((type *)src)->func != NULL) { \ + ((type *)dst)->func = ((type *)src)->func; \ + } else { \ + PRINT_ERR("%s->%s is NULL!\n", #src, #func); \ + } \ +} +#define INVOKE_INTERFACE(adapter, type, func) { \ + if (((type *)adapter)->func != NULL) { \ + ((type *)adapter)->func(); \ + } else { \ + PRINT_ERR("%s->%s is NULL!\n", #adapter, #func); \ + } \ +} + +/* ------------ local prototypes ------------ */ +/* ------------ local function declarations ------------ */ +STATIC INT32 HiDumperOpen(struct file *filep); +STATIC INT32 HiDumperClose(struct file *filep); +STATIC INT32 HiDumperIoctl(struct file *filep, INT32 cmd, unsigned long arg); + +/* ------------ global function declarations ------------ */ +#ifdef LOSCFG_SHELL +extern VOID OsShellCmdSystemInfoGet(VOID); +extern UINT32 OsShellCmdFree(INT32 argc, const CHAR *argv[]); +extern UINT32 OsShellCmdUname(INT32 argc, const CHAR *argv[]); +extern UINT32 OsShellCmdDumpPmm(VOID); +#endif + +/* ------------ local variables ------------ */ +static struct HiDumperAdapter g_adapter; +STATIC struct file_operations_vfs g_hidumperDevOps = { + HiDumperOpen, /* open */ + HiDumperClose, /* close */ + NULL, /* read */ + NULL, /* write */ + NULL, /* seek */ + HiDumperIoctl, /* ioctl */ + NULL, /* mmap */ +#ifndef CONFIG_DISABLE_POLL + NULL, /* poll */ +#endif + NULL, /* unlink */ +}; + +/* ------------ function definitions ------------ */ +STATIC INT32 HiDumperOpen(struct file *filep) +{ + (VOID)filep; + return 0; +} + +STATIC INT32 HiDumperClose(struct file *filep) +{ + (VOID)filep; + return 0; +} + +static void DumpSysInfo(void) +{ + PRINTK("\n%s\n", SYS_INFO_HEADER); +#ifdef LOSCFG_SHELL + const char *argv[1] = {"-a"}; + (VOID)OsShellCmdUname(ARRAY_SIZE(argv), &argv[0]); + (VOID)OsShellCmdSystemInfoGet(); +#else + PRINTK("\nUnsupported!\n"); +#endif +} + +#ifdef LOSCFG_KERNEL_CPUP +static void DoDumpCpuUsageUnsafe(CPUP_INFO_S *processCpupAll, + CPUP_INFO_S *processCpup10s, + CPUP_INFO_S *processCpup1s) +{ + UINT32 pid; + + PRINTK("%-32s PID CPUUSE CPUUSE10S CPUUSE1S\n", "PName"); + for (pid = 0; pid < g_processMaxNum; pid++) { + LosProcessCB *processCB = g_processCBArray + pid; + if (OsProcessIsUnused(processCB)) { + continue; + } + PRINTK("%-32s %u %5u.%1u%8u.%1u%7u.%-1u\n", + processCB->processName, processCB->processID, + processCpupAll[pid].usage / LOS_CPUP_PRECISION_MULT, + processCpupAll[pid].usage % LOS_CPUP_PRECISION_MULT, + processCpup10s[pid].usage / LOS_CPUP_PRECISION_MULT, + processCpup10s[pid].usage % LOS_CPUP_PRECISION_MULT, + processCpup1s[pid].usage / LOS_CPUP_PRECISION_MULT, + processCpup1s[pid].usage % LOS_CPUP_PRECISION_MULT); + } +} +#endif + +static void DumpCpuUsageUnsafe(void) +{ + PRINTK("\n%s\n", CPU_USAGE_HEADER); +#ifdef LOSCFG_KERNEL_CPUP + UINT32 size; + CPUP_INFO_S *processCpup = NULL; + CPUP_INFO_S *processCpupAll = NULL; + CPUP_INFO_S *processCpup10s = NULL; + CPUP_INFO_S *processCpup1s = NULL; + + size = sizeof(*processCpup) * g_processMaxNum * CPUP_TYPE_COUNT; + processCpup = LOS_MemAlloc(m_aucSysMem1, size); + if (processCpup == NULL) { + PRINT_ERR("func: %s, LOS_MemAlloc failed, Line: %d\n", __func__, __LINE__); + return; + } + processCpupAll = processCpup; + processCpup10s = processCpupAll + g_processMaxNum; + processCpup1s = processCpup10s + g_processMaxNum; + (VOID)memset_s(processCpup, size, 0, size); + LOS_GetAllProcessCpuUsage(CPUP_ALL_TIME, processCpupAll, g_processMaxNum * sizeof(CPUP_INFO_S)); + LOS_GetAllProcessCpuUsage(CPUP_LAST_TEN_SECONDS, processCpup10s, g_processMaxNum * sizeof(CPUP_INFO_S)); + LOS_GetAllProcessCpuUsage(CPUP_LAST_ONE_SECONDS, processCpup1s, g_processMaxNum * sizeof(CPUP_INFO_S)); + DoDumpCpuUsageUnsafe(processCpupAll, processCpup10s, processCpup1s); + (VOID)LOS_MemFree(m_aucSysMem1, processCpup); +#else + PRINTK("\nUnsupported!\n"); +#endif +} + +static void DumpMemUsage(void) +{ + PRINTK("\n%s\n", MEM_USAGE_HEADER); +#ifdef LOSCFG_SHELL + PRINTK("Unit: KB\n"); + const char *argv[1] = {"-k"}; + (VOID)OsShellCmdFree(ARRAY_SIZE(argv), &argv[0]); + PRINTK("%s\n", PAGE_USAGE_HEADER); + (VOID)OsShellCmdDumpPmm(); +#else + PRINTK("\nUnsupported!\n"); +#endif +} + +static void DumpTaskInfo(void) +{ + PRINTK("\n%s\n", TASK_INFO_HEADER); +#ifdef LOSCFG_SHELL + (VOID)OsShellCmdTskInfoGet(OS_ALL_TASK_MASK, NULL, OS_PROCESS_INFO_ALL); +#else + PRINTK("\nUnsupported!\n"); +#endif +} + +#ifdef LOSCFG_BLACKBOX +static void PrintFileData(INT32 fd) +{ +#ifdef LOSCFG_FS_VFS + CHAR buf[READ_BUF_SIZE]; + + if (fd < 0) { + PRINT_ERR("fd: %d!\n", fd); + return; + } + + (void)memset_s(buf, sizeof(buf), 0, sizeof(buf)); + while (read(fd, buf, sizeof(buf) - 1) > 0) { + PRINTK("%s", buf); + (void)memset_s(buf, sizeof(buf), 0, sizeof(buf)); + } +#else + (VOID)fd; + PRINT_ERR("LOSCFG_FS_VFS isn't defined!\n"); +#endif +} + +static void PrintFile(const char *filePath, const char *pHeader) +{ +#ifdef LOSCFG_FS_VFS + int fd; + + if (filePath == NULL || pHeader == NULL) { + PRINT_ERR("filePath: %p, pHeader: %p\n", filePath, pHeader); + return; + } + + fd = open(filePath, O_RDONLY); + if (fd >= 0) { + PRINTK("\n%s\n", pHeader); + PrintFileData(fd); + (void)close(fd); + } else { + PRINT_ERR("Open [%s] failed or there's no fault log!\n", filePath); + } +#else + (VOID)filePath; + (VOID)pHeader; + PRINT_ERR("LOSCFG_FS_VFS isn't defined!\n"); +#endif +} +#endif + +static void DumpFaultLog(void) +{ +#ifdef LOSCFG_BLACKBOX + PrintFile(KERNEL_FAULT_LOG_PATH, "************kernel fault info************"); + PrintFile(USER_FAULT_LOG_PATH, "************user fault info************"); +#endif +} + +static void DumpMemData(struct MemDumpParam *param) +{ + PRINTK("\nDumpType: %d\n", param->type); + PRINTK("Unsupported now!\n"); +} + +static void InjectKernelCrash(void) +{ +#ifdef LOSCFG_DEBUG_VERSION + *((INT32 *)KERNEL_FAULT_ADDR) = KERNEL_FAULT_VALUE; +#else + PRINTK("\nUnsupported!\n"); +#endif +} + +static INT32 HiDumperIoctl(struct file *filep, INT32 cmd, unsigned long arg) +{ + INT32 ret = 0; + + switch (cmd) { + case HIDUMPER_DUMP_ALL: + INVOKE_INTERFACE(&g_adapter, struct HiDumperAdapter, DumpSysInfo); + INVOKE_INTERFACE(&g_adapter, struct HiDumperAdapter, DumpCpuUsage); + INVOKE_INTERFACE(&g_adapter, struct HiDumperAdapter, DumpMemUsage); + INVOKE_INTERFACE(&g_adapter, struct HiDumperAdapter, DumpTaskInfo); + break; + case HIDUMPER_CPU_USAGE: + INVOKE_INTERFACE(&g_adapter, struct HiDumperAdapter, DumpCpuUsage); + break; + case HIDUMPER_MEM_USAGE: + INVOKE_INTERFACE(&g_adapter, struct HiDumperAdapter, DumpMemUsage); + break; + case HIDUMPER_TASK_INFO: + INVOKE_INTERFACE(&g_adapter, struct HiDumperAdapter, DumpTaskInfo); + break; + case HIDUMPER_INJECT_KERNEL_CRASH: + INVOKE_INTERFACE(&g_adapter, struct HiDumperAdapter, InjectKernelCrash); + break; + case HIDUMPER_DUMP_FAULT_LOG: + INVOKE_INTERFACE(&g_adapter, struct HiDumperAdapter, DumpFaultLog); + break; + case HIDUMPER_MEM_DATA: + if (g_adapter.DumpMemData != NULL) { + g_adapter.DumpMemData((struct MemDumpParam *)((UINTPTR)arg)); + } + break; + default: + ret = EPERM; + PRINTK("Invalid CMD: 0x%x\n", (UINT32)cmd); + break; + } + + return ret; +} + +static void RegisterCommonAdapter(void) +{ + struct HiDumperAdapter adapter; + + adapter.DumpSysInfo = DumpSysInfo; + adapter.DumpCpuUsage = DumpCpuUsageUnsafe; + adapter.DumpMemUsage = DumpMemUsage; + adapter.DumpTaskInfo = DumpTaskInfo; + adapter.DumpFaultLog = DumpFaultLog; + adapter.DumpMemData = DumpMemData; + adapter.InjectKernelCrash = InjectKernelCrash; + HiDumperRegisterAdapter(&adapter); +} + +int HiDumperRegisterAdapter(struct HiDumperAdapter *pAdapter) +{ + if (pAdapter == NULL) { + PRINT_ERR("pAdapter: %p\n", pAdapter); + return -1; + } + + REPLACE_INTERFACE(&g_adapter, pAdapter, struct HiDumperAdapter, DumpSysInfo); + REPLACE_INTERFACE(&g_adapter, pAdapter, struct HiDumperAdapter, DumpCpuUsage); + REPLACE_INTERFACE(&g_adapter, pAdapter, struct HiDumperAdapter, DumpMemUsage); + REPLACE_INTERFACE(&g_adapter, pAdapter, struct HiDumperAdapter, DumpTaskInfo); + REPLACE_INTERFACE(&g_adapter, pAdapter, struct HiDumperAdapter, DumpFaultLog); + REPLACE_INTERFACE(&g_adapter, pAdapter, struct HiDumperAdapter, DumpMemData); + REPLACE_INTERFACE(&g_adapter, pAdapter, struct HiDumperAdapter, InjectKernelCrash); + + return 0; +} + +int OsHiDumperDriverInit(void) +{ + INT32 ret; + +#ifdef LOSCFG_DEBUG_VERSION + RegisterCommonAdapter(); + ret = register_driver(HIDUMPER_DEVICE, &g_hidumperDevOps, HIDUMPER_DEVICE_MODE, NULL); + if (ret != 0) { + PRINT_ERR("Hidumper register driver failed!\n"); + return -1; + } +#endif + + return 0; +} +LOS_MODULE_INIT(OsHiDumperDriverInit, LOS_INIT_LEVEL_KMOD_EXTENDED); diff --git a/src/kernel_liteos_a/kernel/extended/hidumper/los_hidumper.h b/src/kernel_liteos_a/kernel/extended/hidumper/los_hidumper.h new file mode 100644 index 00000000..ab48f302 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/hidumper/los_hidumper.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LOS_HIDUMPER_H +#define LOS_HIDUMPER_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#ifndef __user +#define __user +#endif + +#define PATH_MAX_LEN 256 + +enum MemDumpType { + DUMP_TO_STDOUT, + DUMP_REGION_TO_STDOUT, + DUMP_TO_FILE, + DUMP_REGION_TO_FILE +}; + +struct MemDumpParam { + enum MemDumpType type; + unsigned long long start; + unsigned long long size; + char filePath[PATH_MAX_LEN]; +}; + +struct HiDumperAdapter { + void (*DumpSysInfo)(void); + void (*DumpCpuUsage)(void); + void (*DumpMemUsage)(void); + void (*DumpTaskInfo)(void); + void (*DumpFaultLog)(void); + void (*DumpMemData)(struct MemDumpParam *param); + void (*InjectKernelCrash)(void); +}; + +#define HIDUMPER_IOC_BASE 'd' +#define HIDUMPER_DUMP_ALL _IO(HIDUMPER_IOC_BASE, 1) +#define HIDUMPER_CPU_USAGE _IO(HIDUMPER_IOC_BASE, 2) +#define HIDUMPER_MEM_USAGE _IO(HIDUMPER_IOC_BASE, 3) +#define HIDUMPER_TASK_INFO _IO(HIDUMPER_IOC_BASE, 4) +#define HIDUMPER_INJECT_KERNEL_CRASH _IO(HIDUMPER_IOC_BASE, 5) +#define HIDUMPER_DUMP_FAULT_LOG _IO(HIDUMPER_IOC_BASE, 6) +#define HIDUMPER_MEM_DATA _IOW(HIDUMPER_IOC_BASE, 7, struct MemDumpParam) + +int HiDumperRegisterAdapter(struct HiDumperAdapter *pAdapter); +int OsHiDumperDriverInit(void); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif \ No newline at end of file diff --git a/src/kernel_liteos_a/kernel/extended/hilog/BUILD.gn b/src/kernel_liteos_a/kernel/extended/hilog/BUILD.gn new file mode 100644 index 00000000..857a3c3c --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/hilog/BUILD.gn @@ -0,0 +1,49 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = defined(LOSCFG_BASE_CORE_HILOG) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ + "$HIVIEWDFX_HILOG_LITE_DIR/frameworks/featured/hiview_log.c", + "los_hilog.c", + ] + + public_configs = [ ":public" ] +} + +config("public") { + include_dirs = [ + "$HIVIEWDFX_HILOG_LITE_DIR/interfaces/native/kits", + "$HIVIEWDFX_HILOG_LITE_DIR/interfaces/native/kits/hilog", + ".", + ] +} diff --git a/src/kernel_liteos_a/kernel/extended/hilog/Kconfig b/src/kernel_liteos_a/kernel/extended/hilog/Kconfig new file mode 100644 index 00000000..26831655 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/hilog/Kconfig @@ -0,0 +1,15 @@ +config HILOG + tristate "Hilog support" + default y + help + hilog buffer manager. + + Hilog is a simple log manager for OpenHarmonyOS. + log string write to /dev/hilog, and the hilog driver copy it + to the ring buffer. Ring buffer can be read from userspace. + +config HILOG_BUFFER_SIZE + int "hilog buffer size" + default 4096 + help + Define the default ring buffer size of hilog \ No newline at end of file diff --git a/src/kernel_liteos_a/kernel/extended/hilog/Makefile b/src/kernel_liteos_a/kernel/extended/hilog/Makefile new file mode 100644 index 00000000..1ae10896 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/hilog/Makefile @@ -0,0 +1,38 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := $(wildcard *.c) + +LOCAL_FLAGS := $(LITEOS_CFLAGS_INTERWORK) + +include $(MODULE) diff --git a/src/kernel_liteos_a/kernel/extended/hilog/los_hilog.c b/src/kernel_liteos_a/kernel/extended/hilog/los_hilog.c new file mode 100644 index 00000000..8ad4eb27 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/hilog/los_hilog.c @@ -0,0 +1,354 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_hilog.h" +#include "los_init.h" +#include "los_mp.h" +#include "los_mux.h" +#include "los_process_pri.h" +#include "los_task_pri.h" +#include "fs/file.h" +#include "fs/driver.h" +#include "los_vm_map.h" +#include "los_vm_lock.h" +#include "user_copy.h" + +#define HILOG_BUFFER LOSCFG_HILOG_BUFFER_SIZE +#define DRIVER_MODE 0666 +#define HILOG_DRIVER "/dev/hilog" + +struct HiLogEntry { + unsigned int len; + unsigned int hdrSize; + unsigned int pid : 16; + unsigned int taskId : 16; + unsigned int sec; + unsigned int nsec; + unsigned int reserved; + char msg[0]; +}; + +ssize_t HilogRead(struct file *filep, char __user *buf, size_t count); +ssize_t HilogWrite(struct file *filep, const char __user *buf, size_t count); +int HiLogOpen(struct file *filep); +int HiLogClose(struct file *filep); + +static ssize_t HiLogWrite(struct file *filep, const char *buffer, size_t bufLen); +static ssize_t HiLogRead(struct file *filep, char *buffer, size_t bufLen); + +STATIC struct file_operations_vfs g_hilogFops = { + HiLogOpen, /* open */ + HiLogClose, /* close */ + HiLogRead, /* read */ + HiLogWrite, /* write */ + NULL, /* seek */ + NULL, /* ioctl */ + NULL, /* mmap */ +#ifndef CONFIG_DISABLE_POLL + NULL, /* poll */ +#endif + NULL, /* unlink */ +}; + +struct HiLogCharDevice { + int flag; + LosMux mtx; + unsigned char *buffer; + wait_queue_head_t wq; + size_t writeOffset; + size_t headOffset; + size_t size; + size_t count; +} g_hiLogDev; + +static inline unsigned char *HiLogBufferHead(void) +{ + return g_hiLogDev.buffer + g_hiLogDev.headOffset; +} + +int HiLogOpen(struct file *filep) +{ + (void)filep; + return 0; +} + +int HiLogClose(struct file *filep) +{ + (void)filep; + return 0; +} + +static void HiLogBufferInc(size_t sz) +{ + if (g_hiLogDev.size + sz <= HILOG_BUFFER) { + g_hiLogDev.size += sz; + g_hiLogDev.writeOffset += sz; + g_hiLogDev.writeOffset %= HILOG_BUFFER; + g_hiLogDev.count++; + } +} + +static void HiLogBufferDec(size_t sz) +{ + if (g_hiLogDev.size >= sz) { + g_hiLogDev.size -= sz; + g_hiLogDev.headOffset += sz; + g_hiLogDev.headOffset %= HILOG_BUFFER; + g_hiLogDev.count--; + } +} + +static int HiLogBufferCopy(unsigned char *dst, unsigned dstLen, const unsigned char *src, size_t srcLen) +{ + int retval = -1; + size_t minLen = (dstLen > srcLen) ? srcLen : dstLen; + + if (LOS_IsUserAddressRange((VADDR_T)(UINTPTR)dst, minLen) && + LOS_IsUserAddressRange((VADDR_T)(UINTPTR)src, minLen)) { + return retval; + } + + if (LOS_IsUserAddressRange((VADDR_T)(UINTPTR)dst, minLen)) { + retval = LOS_ArchCopyToUser(dst, src, minLen); + } else if (LOS_IsUserAddressRange((VADDR_T)(UINTPTR)src, minLen)) { + retval = LOS_ArchCopyFromUser(dst, src, minLen); + } else { + retval = memcpy_s(dst, dstLen, src, srcLen); + } + return retval; +} + +static int HiLogReadRingBuffer(unsigned char *buffer, size_t bufLen) +{ + int retval; + size_t bufLeft = HILOG_BUFFER - g_hiLogDev.headOffset; + if (bufLeft > bufLen) { + retval = HiLogBufferCopy(buffer, bufLen, HiLogBufferHead(), bufLen); + } else { + retval = HiLogBufferCopy(buffer, bufLen, HiLogBufferHead(), bufLeft); + if (retval < 0) { + return retval; + } + + retval = HiLogBufferCopy(buffer + bufLeft, bufLen - bufLeft, g_hiLogDev.buffer, bufLen - bufLeft); + } + return retval; +} + +static ssize_t HiLogRead(struct file *filep, char *buffer, size_t bufLen) +{ + int retval; + struct HiLogEntry header; + + (void)filep; + wait_event_interruptible(g_hiLogDev.wq, (g_hiLogDev.size > 0)); + + (VOID)LOS_MuxAcquire(&g_hiLogDev.mtx); + retval = HiLogReadRingBuffer((unsigned char *)&header, sizeof(header)); + if (retval < 0) { + retval = -EINVAL; + goto out; + } + + if (bufLen < header.len + sizeof(header)) { + PRINTK("buffer too small,bufLen=%d, header.len=%d,%d\n", bufLen, header.len, header.hdrSize); + retval = -ENOMEM; + goto out; + } + + HiLogBufferDec(sizeof(header)); + + retval = HiLogBufferCopy((unsigned char *)buffer, bufLen, (unsigned char *)&header, sizeof(header)); + if (retval < 0) { + retval = -EINVAL; + goto out; + } + + retval = HiLogReadRingBuffer((unsigned char *)(buffer + sizeof(header)), header.len); + if (retval < 0) { + retval = -EINVAL; + goto out; + } + + HiLogBufferDec(header.len); + retval = header.len + sizeof(header); +out: + if (retval == -ENOMEM) { + // clean ring buffer + g_hiLogDev.writeOffset = 0; + g_hiLogDev.headOffset = 0; + g_hiLogDev.size = 0; + g_hiLogDev.count = 0; + } + (VOID)LOS_MuxRelease(&g_hiLogDev.mtx); + return (ssize_t)retval; +} + +static int HiLogWriteRingBuffer(unsigned char *buffer, size_t bufLen) +{ + int retval; + size_t bufLeft = HILOG_BUFFER - g_hiLogDev.writeOffset; + if (bufLen > bufLeft) { + retval = HiLogBufferCopy(g_hiLogDev.buffer + g_hiLogDev.writeOffset, bufLeft, buffer, bufLeft); + if (retval) { + return -1; + } + retval = HiLogBufferCopy(g_hiLogDev.buffer, HILOG_BUFFER, buffer + bufLeft, bufLen - bufLeft); + } else { + retval = HiLogBufferCopy(g_hiLogDev.buffer + g_hiLogDev.writeOffset, bufLeft, buffer, bufLen); + } + if (retval < 0) { + return -1; + } + return 0; +} + +static void HiLogHeadInit(struct HiLogEntry *header, size_t len) +{ + struct timespec now = {0}; + (void)clock_gettime(CLOCK_REALTIME, &now); + + header->len = len; + header->pid = LOS_GetCurrProcessID(); + header->taskId = LOS_CurTaskIDGet(); + header->sec = now.tv_sec; + header->nsec = now.tv_nsec; + header->hdrSize = sizeof(struct HiLogEntry); +} + +static void HiLogCoverOldLog(size_t bufLen) +{ + int retval; + struct HiLogEntry header; + size_t totalSize = bufLen + sizeof(struct HiLogEntry); + static int dropLogLines = 0; + static int isLastTimeFull = 0; + int isThisTimeFull = 0; + + while (totalSize + g_hiLogDev.size > HILOG_BUFFER) { + retval = HiLogReadRingBuffer((unsigned char *)&header, sizeof(header)); + if (retval < 0) { + break; + } + + dropLogLines++; + isThisTimeFull = 1; + isLastTimeFull = 1; + HiLogBufferDec(sizeof(header)); + HiLogBufferDec(header.len); + } + if (isLastTimeFull == 1 && isThisTimeFull == 0) { + /* so we can only print one log if hilog ring buffer is full in a short time */ + if (dropLogLines > 0) { + PRINTK("hilog ringbuffer full, drop %d line(s) log\n", dropLogLines); + } + isLastTimeFull = 0; + dropLogLines = 0; + } +} + +int HiLogWriteInternal(const char *buffer, size_t bufLen) +{ + struct HiLogEntry header; + int retval; + LosTaskCB *runTask = (LosTaskCB *)OsCurrTaskGet(); + + if ((g_hiLogDev.buffer == NULL) || (OS_INT_ACTIVE) || (runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK)) { + PRINTK("%s\n", buffer); + return -EAGAIN; + } + + (VOID)LOS_MuxAcquire(&g_hiLogDev.mtx); + HiLogCoverOldLog(bufLen); + HiLogHeadInit(&header, bufLen); + + retval = HiLogWriteRingBuffer((unsigned char *)&header, sizeof(header)); + if (retval) { + retval = -ENODATA; + goto out; + } + HiLogBufferInc(sizeof(header)); + + retval = HiLogWriteRingBuffer((unsigned char *)(buffer), header.len); + if (retval) { + retval = -ENODATA; + goto out; + } + + HiLogBufferInc(header.len); + + retval = header.len; + +out: + (VOID)LOS_MuxRelease(&g_hiLogDev.mtx); + if (retval > 0) { + wake_up_interruptible(&g_hiLogDev.wq); + } + if (retval < 0) { + PRINTK("write fail retval=%d\n", retval); + } + return retval; +} + +static ssize_t HiLogWrite(struct file *filep, const char *buffer, size_t bufLen) +{ + (void)filep; + if (bufLen + sizeof(struct HiLogEntry) > HILOG_BUFFER) { + PRINTK("input too large\n"); + return -ENOMEM; + } + + return HiLogWriteInternal(buffer, bufLen); +} + +static void HiLogDeviceInit(void) +{ + g_hiLogDev.buffer = LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, HILOG_BUFFER); + if (g_hiLogDev.buffer == NULL) { + PRINTK("In %s line %d,LOS_MemAlloc fail\n", __FUNCTION__, __LINE__); + } + + init_waitqueue_head(&g_hiLogDev.wq); + LOS_MuxInit(&g_hiLogDev.mtx, NULL); + + g_hiLogDev.writeOffset = 0; + g_hiLogDev.headOffset = 0; + g_hiLogDev.size = 0; + g_hiLogDev.count = 0; +} + +int OsHiLogDriverInit(VOID) +{ + HiLogDeviceInit(); + return register_driver(HILOG_DRIVER, &g_hilogFops, DRIVER_MODE, NULL); +} + +LOS_MODULE_INIT(OsHiLogDriverInit, LOS_INIT_LEVEL_KMOD_EXTENDED); diff --git a/src/kernel_liteos_a/kernel/extended/hilog/los_hilog.h b/src/kernel_liteos_a/kernel/extended/hilog/los_hilog.h new file mode 100644 index 00000000..e719e5e7 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/hilog/los_hilog.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LOS_HILOG_H +#define LOS_HILOG_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#ifndef __user +#define __user +#endif + +extern int OsHiLogDriverInit(void); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/src/kernel_liteos_a/kernel/extended/hook/BUILD.gn b/src/kernel_liteos_a/kernel/extended/hook/BUILD.gn new file mode 100644 index 00000000..71a4fa4e --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/hook/BUILD.gn @@ -0,0 +1,42 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = defined(LOSCFG_KERNEL_HOOK) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ "los_hook.c" ] + + public_configs = [ ":public" ] +} + +config("public") { + include_dirs = [ "include" ] +} diff --git a/src/kernel_liteos_a/kernel/extended/hook/Makefile b/src/kernel_liteos_a/kernel/extended/hook/Makefile new file mode 100644 index 00000000..8d11bbf2 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/hook/Makefile @@ -0,0 +1,36 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := $(wildcard *.c) + +include $(MODULE) diff --git a/src/kernel_liteos_a/kernel/extended/hook/include/los_hook_types.h b/src/kernel_liteos_a/kernel/extended/hook/include/los_hook_types.h new file mode 100644 index 00000000..8fa0bac1 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/hook/include/los_hook_types.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_HOOK_TYPES_H +#define _LOS_HOOK_TYPES_H + +#include "los_config.h" +#include "los_event_pri.h" +#include "los_mux_pri.h" +#include "los_queue_pri.h" +#include "los_sem_pri.h" +#include "los_task_pri.h" +#include "los_swtmr_pri.h" +#include "hm_liteipc.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#ifdef LOSCFG_KERNEL_HOOK +#define LOS_HOOK_ALL_TYPES_DEF \ + /* Hook types supported by memory modules */ \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_MEM_INIT, (VOID *pool, UINT32 size)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_MEM_DEINIT, (VOID *pool)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_MEM_ALLOC, (VOID *pool, VOID *ptr, UINT32 size)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_MEM_FREE, (VOID *pool, VOID *ptr)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_MEM_REALLOC, (VOID *pool, VOID *ptr, UINT32 size)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_MEM_ALLOCALIGN, (VOID *pool, VOID *ptr, UINT32 size, UINT32 boundary)) \ + /* Hook types supported by event modules */ \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_EVENT_INIT, (PEVENT_CB_S eventCB)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_EVENT_READ, (PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, \ + UINT32 timeout)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_EVENT_WRITE, (PEVENT_CB_S eventCB, UINT32 events)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_EVENT_CLEAR, (PEVENT_CB_S eventCB, UINT32 events)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_EVENT_DESTROY, (PEVENT_CB_S eventCB)) \ + /* Hook types supported by queue modules */ \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_QUEUE_CREATE, (const LosQueueCB *queueCB)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_QUEUE_READ, (const LosQueueCB *queueCB, UINT32 operateType, \ + UINT32 bufferSize, UINT32 timeout)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_QUEUE_WRITE, (const LosQueueCB *queueCB, UINT32 operateType, \ + UINT32 bufferSize, UINT32 timeout)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_QUEUE_DELETE, (const LosQueueCB *queueCB)) \ + /* Hook types supported by semaphore modules */ \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_SEM_CREATE, (const LosSemCB *semCreated)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_SEM_POST, (const LosSemCB *semPosted, const LosTaskCB *resumedTask)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_SEM_PEND, (const LosSemCB *semPended, const LosTaskCB *runningTask, \ + UINT32 timeout)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_SEM_DELETE, (const LosSemCB *semDeleted)) \ + /* Hook types supported by mutex modules */ \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_MUX_CREATE, (const LosMux *muxCreated)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_MUX_POST, (const LosMux *muxPosted)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_MUX_PEND, (const LosMux *muxPended, UINT32 timeout)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_MUX_DELETE, (const LosMux *muxDeleted)) \ + /* Hook types supported by task modules */ \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_TASK_CREATE, (const LosTaskCB *taskCB)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_TASK_DELAY, (UINT32 tick)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_TASK_PRIMODIFY, (const LosTaskCB *pxTask, UINT32 uxNewPriority)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_TASK_DELETE, (const LosTaskCB *taskCB)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_TASK_SWITCHEDIN, (const LosTaskCB *newTask, const LosTaskCB *runTask)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_MOVEDTASKTOREADYSTATE, (const LosTaskCB *pstTaskCB)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_MOVEDTASKTODELAYEDLIST, (const LosTaskCB *pstTaskCB)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_MOVEDTASKTOSUSPENDEDLIST, (const LosTaskCB *pstTaskCB)) \ + /* Hook types supported by interrupt modules */ \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_ISR_EXITTOSCHEDULER, (VOID)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_ISR_ENTER, (UINT32 hwiIndex)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_ISR_EXIT, (UINT32 hwiIndex)) \ + /* Hook types supported by swtmr modules */ \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_SWTMR_CREATE, (const SWTMR_CTRL_S *swtmr)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_SWTMR_DELETE, (const SWTMR_CTRL_S *swtmr)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_SWTMR_EXPIRED, (const SWTMR_CTRL_S *swtmr)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_SWTMR_START, (const SWTMR_CTRL_S *swtmr)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_SWTMR_STOP, (const SWTMR_CTRL_S *swtmr)) \ + /* Hook types supported by liteipc modules */ \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_IPC_WRITE_DROP, (const IpcMsg *msg, UINT32 dstTid, UINT32 dstPid, \ + UINT32 ipcStatus)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_IPC_WRITE, (const IpcMsg *msg, UINT32 dstTid, UINT32 dstPid, \ + UINT32 ipcStatus)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_IPC_READ_DROP, (const IpcMsg *msg, UINT32 ipcStatus)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_IPC_READ, (const IpcMsg *msg, UINT32 ipcStatus)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_IPC_TRY_READ, (UINT32 msgType, UINT32 ipcStatus)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_IPC_READ_TIMEOUT, (UINT32 msgType, UINT32 ipcStatus)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_IPC_KILL, (UINT32 msgType, UINT32 ipcStatus)) \ + /* Hook types supported by usr modules */ \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_USR_EVENT, (VOID *buffer, UINT32 len)) + +/** + * Defines the types of all hooks. + */ +#define LOS_HOOK_TYPE_DEF(type, paramList) type, + +typedef enum { + /* Used to manage hook pools */ + LOS_HOOK_TYPE_START = 0, + /* All supported hook types */ + LOS_HOOK_ALL_TYPES_DEF + /* Used to manage hook pools */ + LOS_HOOK_TYPE_END +} HookType; + +#undef LOS_HOOK_TYPE_DEF + +/** + * Declare the type and interface of the hook functions. + */ +#define LOS_HOOK_TYPE_DEF(type, paramList) \ + typedef VOID (*type##_FN) paramList; \ + extern UINT32 type##_RegHook(type##_FN func); \ + extern UINT32 type##_UnRegHook(type##_FN func); \ + extern VOID type##_CallHook paramList; + +LOS_HOOK_ALL_TYPES_DEF + +#undef LOS_HOOK_TYPE_DEF + +#endif /* LOSCFG_KERNEL_HOOK */ + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_HOOK_TYPES_H */ diff --git a/src/kernel_liteos_a/kernel/extended/hook/include/los_hook_types_parse.h b/src/kernel_liteos_a/kernel/extended/hook/include/los_hook_types_parse.h new file mode 100644 index 00000000..ad082c1b --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/hook/include/los_hook_types_parse.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_HOOK_TYPES_PARSE_H +#define _LOS_HOOK_TYPES_PARSE_H + +#define ADDR(a) (&(a)) +#define ARGS(a) (a) +#define ADDRn(...) _CONCAT(ADDR, _NARGS(__VA_ARGS__))(__VA_ARGS__) +#define ARGSn(...) _CONCAT(ARGS, _NARGS(__VA_ARGS__))(__VA_ARGS__) +#define ARGS0() +#define ADDR0() +#define ARGS1(a) ARGS(a) +#define ADDR1(a) ADDR(a) + +#define ARG_const _ARG_const( +#define _ARG_const(a) ARG_CP_##a) +#define ARG_CP_LosSemCB ADDR( +#define ARG_CP_LosTaskCB ADDR( +#define ARG_CP_UINT32 ADDR( +#define ARG_CP_LosMux ADDR( +#define ARG_CP_LosQueueCB ADDR( +#define ARG_CP_SWTMR_CTRL_S ADDR( +#define ARG_CP_IpcMsg ADDR( +#define ARG_UINT32 ARGS( +#define ARG_PEVENT_CB_S ARGS( +#define ARG_void ADDRn( +#define ARG(a) ARG_##a) + +#define PARAM_TO_ARGS1(a) ARG(a) +#define PARAM_TO_ARGS2(a, b) ARG(a), PARAM_TO_ARGS1(b) +#define PARAM_TO_ARGS3(a, b, c) ARG(a), PARAM_TO_ARGS2(b, c) +#define PARAM_TO_ARGS4(a, b, c, d) ARG(a), PARAM_TO_ARGS3(b, c, d) +#define PARAM_TO_ARGS5(a, b, c, d, e) ARG(a), PARAM_TO_ARGS4(b, c, d, e) +#define PARAM_TO_ARGS6(a, b, c, d, e, f) ARG(a), PARAM_TO_ARGS5(b, c, d, e, f) +#define PARAM_TO_ARGS7(a, b, c, d, e, f, g) ARG(a), PARAM_TO_ARGS6(b, c, d, e, f, g) + +#define _ZERO_ARGS 7, 6, 5, 4, 3, 2, 1, 0 +#define ___NARGS(a, b, c, d, e, f, g, h, n, ...) n +#define __NARGS(...) ___NARGS(__VA_ARGS__) +#define _NARGS(...) __NARGS(x, __VA_ARGS__##_ZERO_ARGS, 7, 6, 5, 4, 3, 2, 1, 0) +#define __CONCAT(a, b) a##b +#define _CONCAT(a, b) __CONCAT(a, b) + +#define PARAM_TO_ARGS(...) _CONCAT(PARAM_TO_ARGS, _NARGS(__VA_ARGS__))(__VA_ARGS__) +#define OS_HOOK_PARAM_TO_ARGS(paramList) (PARAM_TO_ARGS paramList) + +#endif /* _LOS_HOOK_TYPES_PARSE_H */ diff --git a/src/kernel_liteos_a/kernel/extended/hook/los_hook.c b/src/kernel_liteos_a/kernel/extended/hook/los_hook.c new file mode 100644 index 00000000..82d97246 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/hook/los_hook.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_hook.h" +#include "los_hook_types_parse.h" + +#ifdef LOSCFG_KERNEL_HOOK +#define LOS_HOOK_TYPE_DEF(type, paramList) \ + STATIC type##_FN g_fn##type; \ + UINT32 type##_RegHook(type##_FN func) { \ + if ((func) == NULL) { \ + return LOS_ERRNO_HOOK_REG_INVALID; \ + } \ + if (g_fn##type) { \ + return LOS_ERRNO_HOOK_POOL_IS_FULL; \ + } \ + g_fn##type = (func); \ + return LOS_OK; \ + } \ + UINT32 type##_UnRegHook(type##_FN func) { \ + if (((func) == NULL) || (g_fn##type != (func))) { \ + return LOS_ERRNO_HOOK_UNREG_INVALID; \ + } \ + g_fn##type = NULL; \ + return LOS_OK; \ + } \ + VOID type##_CallHook paramList { \ + if (g_fn##type) { \ + g_fn##type(PARAM_TO_ARGS paramList); \ + } \ + } + +LOS_HOOK_ALL_TYPES_DEF; + +#undef LOS_HOOK_TYPE_DEF + +#endif /* LOSCFG_DEBUG_HOOK */ + diff --git a/src/kernel_liteos_a/kernel/extended/liteipc/BUILD.gn b/src/kernel_liteos_a/kernel/extended/liteipc/BUILD.gn new file mode 100644 index 00000000..5074fe3a --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/liteipc/BUILD.gn @@ -0,0 +1,41 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = defined(LOSCFG_KERNEL_LITEIPC) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ "hm_liteipc.c" ] + public_configs = [ ":public" ] +} + +config("public") { + include_dirs = [ "." ] +} diff --git a/src/kernel_liteos_a/kernel/extended/liteipc/Makefile b/src/kernel_liteos_a/kernel/extended/liteipc/Makefile new file mode 100644 index 00000000..f94e8b8c --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/liteipc/Makefile @@ -0,0 +1,35 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := $(wildcard ./*.c) + +include $(MODULE) diff --git a/src/kernel_liteos_a/kernel/extended/liteipc/hm_liteipc.c b/src/kernel_liteos_a/kernel/extended/liteipc/hm_liteipc.c new file mode 100644 index 00000000..2f2fbf71 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/liteipc/hm_liteipc.c @@ -0,0 +1,1381 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "hm_liteipc.h" +#include "linux/kernel.h" +#include "fs/file.h" +#include "fs/driver.h" +#include "los_init.h" +#include "los_mp.h" +#include "los_mux.h" +#include "los_process_pri.h" +#include "los_sched_pri.h" +#include "los_spinlock.h" +#include "los_task_pri.h" +#include "los_vm_lock.h" +#include "los_vm_map.h" +#include "los_vm_page.h" +#include "los_vm_phys.h" +#include "los_hook.h" + +#define USE_TASKID_AS_HANDLE 1 +#define USE_MMAP 1 +#define IPC_IO_DATA_MAX 8192UL +#define IPC_MSG_DATA_SZ_MAX (IPC_IO_DATA_MAX * sizeof(SpecialObj) / (sizeof(SpecialObj) + sizeof(size_t))) +#define IPC_MSG_OBJECT_NUM_MAX (IPC_MSG_DATA_SZ_MAX / sizeof(SpecialObj)) + +#define LITE_IPC_POOL_NAME "liteipc" +#define LITE_IPC_POOL_PAGE_MAX_NUM 64 /* 256KB */ +#define LITE_IPC_POOL_PAGE_DEFAULT_NUM 16 /* 64KB */ +#define LITE_IPC_POOL_MAX_SIZE (LITE_IPC_POOL_PAGE_MAX_NUM << PAGE_SHIFT) +#define LITE_IPC_POOL_DEFAULT_SIZE (LITE_IPC_POOL_PAGE_DEFAULT_NUM << PAGE_SHIFT) +#define LITE_IPC_POOL_UVADDR 0x10000000 +#define INVAILD_ID (-1) + +#define LITEIPC_TIMEOUT_MS 5000UL +#define LITEIPC_TIMEOUT_NS 5000000000ULL + +#define MAJOR_VERSION (2) +#define MINOR_VERSION (0) +#define DRIVER_VERSION (MAJOR_VERSION | MINOR_VERSION << 16) + +typedef struct { + LOS_DL_LIST list; + VOID *ptr; +} IpcUsedNode; + +STATIC LosMux g_serviceHandleMapMux; +#if (USE_TASKID_AS_HANDLE == 1) +STATIC HandleInfo g_cmsTask; +#else +STATIC HandleInfo g_serviceHandleMap[MAX_SERVICE_NUM]; +#endif +STATIC LOS_DL_LIST g_ipcPendlist; + +/* ipc lock */ +SPIN_LOCK_INIT(g_ipcSpin); +#define IPC_LOCK(state) LOS_SpinLockSave(&g_ipcSpin, &(state)) +#define IPC_UNLOCK(state) LOS_SpinUnlockRestore(&g_ipcSpin, state) + +STATIC int LiteIpcOpen(struct file *filep); +STATIC int LiteIpcClose(struct file *filep); +STATIC int LiteIpcIoctl(struct file *filep, int cmd, unsigned long arg); +STATIC int LiteIpcMmap(struct file* filep, LosVmMapRegion *region); +STATIC UINT32 LiteIpcWrite(IpcContent *content); +STATIC UINT32 GetTid(UINT32 serviceHandle, UINT32 *taskID); +STATIC UINT32 HandleSpecialObjects(UINT32 dstTid, IpcListNode *node, BOOL isRollback); +STATIC ProcIpcInfo *LiteIpcPoolCreate(VOID); + +STATIC const struct file_operations_vfs g_liteIpcFops = { + .open = LiteIpcOpen, /* open */ + .close = LiteIpcClose, /* close */ + .ioctl = LiteIpcIoctl, /* ioctl */ + .mmap = LiteIpcMmap, /* mmap */ +}; + +LITE_OS_SEC_TEXT_INIT UINT32 OsLiteIpcInit(VOID) +{ + UINT32 ret; +#if (USE_TASKID_AS_HANDLE == 1) + g_cmsTask.status = HANDLE_NOT_USED; +#else + (void)memset_s(g_serviceHandleMap, sizeof(g_serviceHandleMap), 0, sizeof(g_serviceHandleMap)); +#endif + ret = LOS_MuxInit(&g_serviceHandleMapMux, NULL); + if (ret != LOS_OK) { + return ret; + } + ret = (UINT32)register_driver(LITEIPC_DRIVER, &g_liteIpcFops, LITEIPC_DRIVER_MODE, NULL); + if (ret != LOS_OK) { + PRINT_ERR("register lite_ipc driver failed:%d\n", ret); + } + LOS_ListInit(&(g_ipcPendlist)); + + return ret; +} + +LOS_MODULE_INIT(OsLiteIpcInit, LOS_INIT_LEVEL_KMOD_EXTENDED); + +LITE_OS_SEC_TEXT STATIC int LiteIpcOpen(struct file *filep) +{ + LosProcessCB *pcb = OsCurrProcessGet(); + if (pcb->ipcInfo != NULL) { + return 0; + } + + pcb->ipcInfo = LiteIpcPoolCreate(); + if (pcb->ipcInfo == NULL) { + return -ENOMEM; + } + + return 0; +} + +LITE_OS_SEC_TEXT STATIC int LiteIpcClose(struct file *filep) +{ + return 0; +} + +LITE_OS_SEC_TEXT STATIC BOOL IsPoolMapped(ProcIpcInfo *ipcInfo) +{ + return (ipcInfo->pool.uvaddr != NULL) && (ipcInfo->pool.kvaddr != NULL) && + (ipcInfo->pool.poolSize != 0); +} + +LITE_OS_SEC_TEXT STATIC INT32 DoIpcMmap(LosProcessCB *pcb, LosVmMapRegion *region) +{ + UINT32 i; + INT32 ret = 0; + PADDR_T pa; + UINT32 uflags = VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_USER; + LosVmPage *vmPage = NULL; + VADDR_T uva = (VADDR_T)(UINTPTR)pcb->ipcInfo->pool.uvaddr; + VADDR_T kva = (VADDR_T)(UINTPTR)pcb->ipcInfo->pool.kvaddr; + + (VOID)LOS_MuxAcquire(&pcb->vmSpace->regionMux); + + for (i = 0; i < (region->range.size >> PAGE_SHIFT); i++) { + pa = LOS_PaddrQuery((VOID *)(UINTPTR)(kva + (i << PAGE_SHIFT))); + if (pa == 0) { + PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__); + ret = -EINVAL; + break; + } + vmPage = LOS_VmPageGet(pa); + if (vmPage == NULL) { + PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__); + ret = -EINVAL; + break; + } + STATUS_T err = LOS_ArchMmuMap(&pcb->vmSpace->archMmu, uva + (i << PAGE_SHIFT), pa, 1, uflags); + if (err < 0) { + ret = err; + PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__); + break; + } + } + /* if any failure happened, rollback */ + if (i != (region->range.size >> PAGE_SHIFT)) { + while (i--) { + pa = LOS_PaddrQuery((VOID *)(UINTPTR)(kva + (i << PAGE_SHIFT))); + vmPage = LOS_VmPageGet(pa); + (VOID)LOS_ArchMmuUnmap(&pcb->vmSpace->archMmu, uva + (i << PAGE_SHIFT), 1); + LOS_PhysPageFree(vmPage); + } + } + + (VOID)LOS_MuxRelease(&pcb->vmSpace->regionMux); + return ret; +} + +LITE_OS_SEC_TEXT STATIC int LiteIpcMmap(struct file *filep, LosVmMapRegion *region) +{ + int ret = 0; + LosVmMapRegion *regionTemp = NULL; + LosProcessCB *pcb = OsCurrProcessGet(); + ProcIpcInfo *ipcInfo = pcb->ipcInfo; + + if ((ipcInfo == NULL) || (region == NULL) || (region->range.size > LITE_IPC_POOL_MAX_SIZE) || + (!LOS_IsRegionPermUserReadOnly(region)) || (!LOS_IsRegionFlagPrivateOnly(region))) { + ret = -EINVAL; + goto ERROR_REGION_OUT; + } + if (IsPoolMapped(ipcInfo)) { + return -EEXIST; + } + if (ipcInfo->pool.uvaddr != NULL) { + regionTemp = LOS_RegionFind(pcb->vmSpace, (VADDR_T)(UINTPTR)ipcInfo->pool.uvaddr); + if (regionTemp != NULL) { + (VOID)LOS_RegionFree(pcb->vmSpace, regionTemp); + } + } + ipcInfo->pool.uvaddr = (VOID *)(UINTPTR)region->range.base; + if (ipcInfo->pool.kvaddr != NULL) { + LOS_VFree(ipcInfo->pool.kvaddr); + ipcInfo->pool.kvaddr = NULL; + } + /* use vmalloc to alloc phy mem */ + ipcInfo->pool.kvaddr = LOS_VMalloc(region->range.size); + if (ipcInfo->pool.kvaddr == NULL) { + ret = -ENOMEM; + goto ERROR_REGION_OUT; + } + /* do mmap */ + ret = DoIpcMmap(pcb, region); + if (ret) { + goto ERROR_MAP_OUT; + } + /* ipc pool init */ + if (LOS_MemInit(ipcInfo->pool.kvaddr, region->range.size) != LOS_OK) { + ret = -EINVAL; + goto ERROR_MAP_OUT; + } + ipcInfo->pool.poolSize = region->range.size; + return 0; +ERROR_MAP_OUT: + LOS_VFree(ipcInfo->pool.kvaddr); +ERROR_REGION_OUT: + if (ipcInfo != NULL) { + ipcInfo->pool.uvaddr = NULL; + ipcInfo->pool.kvaddr = NULL; + } + return ret; +} + +LITE_OS_SEC_TEXT_INIT STATIC UINT32 LiteIpcPoolInit(ProcIpcInfo *ipcInfo) +{ + ipcInfo->pool.uvaddr = NULL; + ipcInfo->pool.kvaddr = NULL; + ipcInfo->pool.poolSize = 0; + ipcInfo->ipcTaskID = INVAILD_ID; + LOS_ListInit(&ipcInfo->ipcUsedNodelist); + return LOS_OK; +} + +LITE_OS_SEC_TEXT_INIT STATIC ProcIpcInfo *LiteIpcPoolCreate(VOID) +{ + ProcIpcInfo *ipcInfo = LOS_MemAlloc(m_aucSysMem1, sizeof(ProcIpcInfo)); + if (ipcInfo == NULL) { + return NULL; + } + + (VOID)memset_s(ipcInfo, sizeof(ProcIpcInfo), 0, sizeof(ProcIpcInfo)); + + (VOID)LiteIpcPoolInit(ipcInfo); + return ipcInfo; +} + +LITE_OS_SEC_TEXT ProcIpcInfo *LiteIpcPoolReInit(const ProcIpcInfo *parent) +{ + ProcIpcInfo *ipcInfo = LiteIpcPoolCreate(); + if (ipcInfo == NULL) { + return NULL; + } + + ipcInfo->pool.uvaddr = parent->pool.uvaddr; + ipcInfo->pool.kvaddr = NULL; + ipcInfo->pool.poolSize = 0; + ipcInfo->ipcTaskID = INVAILD_ID; + return ipcInfo; +} + +STATIC VOID LiteIpcPoolDelete(ProcIpcInfo *ipcInfo, UINT32 processID) +{ + UINT32 intSave; + IpcUsedNode *node = NULL; + if (ipcInfo->pool.kvaddr != NULL) { + LOS_VFree(ipcInfo->pool.kvaddr); + ipcInfo->pool.kvaddr = NULL; + IPC_LOCK(intSave); + while (!LOS_ListEmpty(&ipcInfo->ipcUsedNodelist)) { + node = LOS_DL_LIST_ENTRY(ipcInfo->ipcUsedNodelist.pstNext, IpcUsedNode, list); + LOS_ListDelete(&node->list); + free(node); + } + IPC_UNLOCK(intSave); + } + /* remove process access to service */ + for (UINT32 i = 0; i < MAX_SERVICE_NUM; i++) { + if (ipcInfo->access[i] == TRUE) { + ipcInfo->access[i] = FALSE; + if (OS_TCB_FROM_TID(i)->ipcTaskInfo != NULL) { + OS_TCB_FROM_TID(i)->ipcTaskInfo->accessMap[processID] = FALSE; + } + } + } +} + +LITE_OS_SEC_TEXT UINT32 LiteIpcPoolDestroy(UINT32 processID) +{ + LosProcessCB *pcb = OS_PCB_FROM_PID(processID); + if (pcb->ipcInfo == NULL) { + return LOS_NOK; + } + + LiteIpcPoolDelete(pcb->ipcInfo, pcb->processID); + LOS_MemFree(m_aucSysMem1, pcb->ipcInfo); + pcb->ipcInfo = NULL; + return LOS_OK; +} + +LITE_OS_SEC_TEXT_INIT STATIC IpcTaskInfo *LiteIpcTaskInit(VOID) +{ + IpcTaskInfo *taskInfo = LOS_MemAlloc((VOID *)m_aucSysMem1, sizeof(IpcTaskInfo)); + if (taskInfo == NULL) { + return NULL; + } + + (VOID)memset_s(taskInfo, sizeof(IpcTaskInfo), 0, sizeof(IpcTaskInfo)); + LOS_ListInit(&taskInfo->msgListHead); + return taskInfo; +} + +/* Only when kernenl no longer access ipc node content, can user free the ipc node */ +LITE_OS_SEC_TEXT STATIC VOID EnableIpcNodeFreeByUser(LosProcessCB *pcb, VOID *buf) +{ + UINT32 intSave; + ProcIpcInfo *ipcInfo = pcb->ipcInfo; + IpcUsedNode *node = (IpcUsedNode *)malloc(sizeof(IpcUsedNode)); + if (node != NULL) { + node->ptr = buf; + IPC_LOCK(intSave); + LOS_ListAdd(&ipcInfo->ipcUsedNodelist, &node->list); + IPC_UNLOCK(intSave); + } +} + +LITE_OS_SEC_TEXT STATIC VOID *LiteIpcNodeAlloc(LosProcessCB *pcb, UINT32 size) +{ + VOID *ptr = LOS_MemAlloc(pcb->ipcInfo->pool.kvaddr, size); + PRINT_INFO("LiteIpcNodeAlloc pid:%d, pool:%x buf:%x size:%d\n", + pcb->processID, pcb->ipcInfo->pool.kvaddr, ptr, size); + return ptr; +} + +LITE_OS_SEC_TEXT STATIC UINT32 LiteIpcNodeFree(LosProcessCB *pcb, VOID *buf) +{ + PRINT_INFO("LiteIpcNodeFree pid:%d, pool:%x buf:%x\n", + pcb->processID, pcb->ipcInfo->pool.kvaddr, buf); + return LOS_MemFree(pcb->ipcInfo->pool.kvaddr, buf); +} + +LITE_OS_SEC_TEXT STATIC BOOL IsIpcNode(LosProcessCB *pcb, const VOID *buf) +{ + IpcUsedNode *node = NULL; + UINT32 intSave; + ProcIpcInfo *ipcInfo = pcb->ipcInfo; + IPC_LOCK(intSave); + LOS_DL_LIST_FOR_EACH_ENTRY(node, &ipcInfo->ipcUsedNodelist, IpcUsedNode, list) { + if (node->ptr == buf) { + LOS_ListDelete(&node->list); + IPC_UNLOCK(intSave); + free(node); + return TRUE; + } + } + IPC_UNLOCK(intSave); + return FALSE; +} + +LITE_OS_SEC_TEXT STATIC INTPTR GetIpcUserAddr(const LosProcessCB *pcb, INTPTR kernelAddr) +{ + IpcPool pool = pcb->ipcInfo->pool; + INTPTR offset = (INTPTR)(pool.uvaddr) - (INTPTR)(pool.kvaddr); + return kernelAddr + offset; +} + +LITE_OS_SEC_TEXT STATIC INTPTR GetIpcKernelAddr(const LosProcessCB *pcb, INTPTR userAddr) +{ + IpcPool pool = pcb->ipcInfo->pool; + INTPTR offset = (INTPTR)(pool.uvaddr) - (INTPTR)(pool.kvaddr); + return userAddr - offset; +} + +LITE_OS_SEC_TEXT STATIC UINT32 CheckUsedBuffer(const VOID *node, IpcListNode **outPtr) +{ + VOID *ptr = NULL; + LosProcessCB *pcb = OsCurrProcessGet(); + IpcPool pool = pcb->ipcInfo->pool; + if ((node == NULL) || ((INTPTR)node < (INTPTR)(pool.uvaddr)) || + ((INTPTR)node > (INTPTR)(pool.uvaddr) + pool.poolSize)) { + return -EINVAL; + } + ptr = (VOID *)GetIpcKernelAddr(pcb, (INTPTR)(node)); + if (IsIpcNode(pcb, ptr) != TRUE) { + return -EFAULT; + } + *outPtr = (IpcListNode *)ptr; + return LOS_OK; +} + +LITE_OS_SEC_TEXT STATIC UINT32 GetTid(UINT32 serviceHandle, UINT32 *taskID) +{ + if (serviceHandle >= MAX_SERVICE_NUM) { + return -EINVAL; + } + (VOID)LOS_MuxLock(&g_serviceHandleMapMux, LOS_WAIT_FOREVER); +#if (USE_TASKID_AS_HANDLE == 1) + *taskID = serviceHandle ? serviceHandle : g_cmsTask.taskID; + (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux); + return LOS_OK; +#else + if (g_serviceHandleMap[serviceHandle].status == HANDLE_REGISTED) { + *taskID = g_serviceHandleMap[serviceHandle].taskID; + (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux); + return LOS_OK; + } + (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux); + return -EINVAL; +#endif +} + +LITE_OS_SEC_TEXT STATIC UINT32 GenerateServiceHandle(UINT32 taskID, HandleStatus status, UINT32 *serviceHandle) +{ + (VOID)LOS_MuxLock(&g_serviceHandleMapMux, LOS_WAIT_FOREVER); +#if (USE_TASKID_AS_HANDLE == 1) + *serviceHandle = taskID ? taskID : LOS_CurTaskIDGet(); /* if taskID is 0, return curTaskID */ + if (*serviceHandle != g_cmsTask.taskID) { + (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux); + return LOS_OK; + } +#else + for (UINT32 i = 1; i < MAX_SERVICE_NUM; i++) { + if (g_serviceHandleMap[i].status == HANDLE_NOT_USED) { + g_serviceHandleMap[i].taskID = taskID; + g_serviceHandleMap[i].status = status; + *serviceHandle = i; + (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux); + return LOS_OK; + } + } +#endif + (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux); + return -EINVAL; +} + +LITE_OS_SEC_TEXT STATIC VOID RefreshServiceHandle(UINT32 serviceHandle, UINT32 result) +{ +#if (USE_TASKID_AS_HANDLE == 0) + (VOID)LOS_MuxLock(&g_serviceHandleMapMux, LOS_WAIT_FOREVER); + if ((result == LOS_OK) && (g_serviceHandleMap[serviceHandle].status == HANDLE_REGISTING)) { + g_serviceHandleMap[serviceHandle].status = HANDLE_REGISTED; + } else { + g_serviceHandleMap[serviceHandle].status = HANDLE_NOT_USED; + } + (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux); +#endif +} + +LITE_OS_SEC_TEXT STATIC UINT32 AddServiceAccess(UINT32 taskID, UINT32 serviceHandle) +{ + UINT32 serviceTid = 0; + UINT32 ret = GetTid(serviceHandle, &serviceTid); + if (ret != LOS_OK) { + PRINT_ERR("Liteipc AddServiceAccess GetTid failed\n"); + return ret; + } + + LosTaskCB *tcb = OS_TCB_FROM_TID(serviceTid); + LosProcessCB *pcb = OS_PCB_FROM_TID(taskID); + if ((tcb->ipcTaskInfo == NULL) || (pcb->ipcInfo == NULL)) { + PRINT_ERR("Liteipc AddServiceAccess ipc not create! pid %u tid %u\n", pcb->processID, tcb->taskID); + return -EINVAL; + } + tcb->ipcTaskInfo->accessMap[pcb->processID] = TRUE; + pcb->ipcInfo->access[serviceTid] = TRUE; + return LOS_OK; +} + +LITE_OS_SEC_TEXT STATIC BOOL HasServiceAccess(UINT32 serviceHandle) +{ + UINT32 serviceTid = 0; + LosProcessCB *curr = OsCurrProcessGet(); + UINT32 ret; + if (serviceHandle >= MAX_SERVICE_NUM) { + return FALSE; + } + if (serviceHandle == 0) { + return TRUE; + } + ret = GetTid(serviceHandle, &serviceTid); + if (ret != LOS_OK) { + PRINT_ERR("Liteipc HasServiceAccess GetTid failed\n"); + return FALSE; + } + LosTaskCB *taskCB = OS_TCB_FROM_TID(serviceTid); + if (taskCB->processCB == (UINTPTR)curr) { + return TRUE; + } + + if (taskCB->ipcTaskInfo == NULL) { + return FALSE; + } + + return taskCB->ipcTaskInfo->accessMap[curr->processID]; +} + +LITE_OS_SEC_TEXT STATIC UINT32 SetIpcTask(VOID) +{ + if (OsCurrProcessGet()->ipcInfo->ipcTaskID == INVAILD_ID) { + OsCurrProcessGet()->ipcInfo->ipcTaskID = LOS_CurTaskIDGet(); + return OsCurrProcessGet()->ipcInfo->ipcTaskID; + } + PRINT_ERR("Liteipc curprocess %d IpcTask already set!\n", OsCurrProcessGet()->processID); + return -EINVAL; +} + +LITE_OS_SEC_TEXT BOOL IsIpcTaskSet(VOID) +{ + if (OsCurrProcessGet()->ipcInfo->ipcTaskID == INVAILD_ID) { + return FALSE; + } + return TRUE; +} + +LITE_OS_SEC_TEXT STATIC UINT32 GetIpcTaskID(LosProcessCB *pcb, UINT32 *ipcTaskID) +{ + if (pcb->ipcInfo->ipcTaskID == INVAILD_ID) { + return LOS_NOK; + } + *ipcTaskID = pcb->ipcInfo->ipcTaskID; + return LOS_OK; +} + +LITE_OS_SEC_TEXT STATIC UINT32 SendDeathMsg(UINT32 processID, UINT32 serviceHandle) +{ + UINT32 ipcTaskID; + UINT32 ret; + IpcContent content; + IpcMsg msg; + LosProcessCB *pcb = OS_PCB_FROM_PID(processID); + + if (pcb->ipcInfo == NULL) { + return -EINVAL; + } + + pcb->ipcInfo->access[serviceHandle] = FALSE; + + ret = GetIpcTaskID(pcb, &ipcTaskID); + if (ret != LOS_OK) { + return -EINVAL; + } + content.flag = SEND; + content.outMsg = &msg; + (void)memset_s(content.outMsg, sizeof(IpcMsg), 0, sizeof(IpcMsg)); + content.outMsg->type = MT_DEATH_NOTIFY; + content.outMsg->target.handle = ipcTaskID; + content.outMsg->target.token = serviceHandle; + content.outMsg->code = 0; + return LiteIpcWrite(&content); +} + +LITE_OS_SEC_TEXT VOID LiteIpcRemoveServiceHandle(UINT32 taskID) +{ + UINT32 j; + LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID); + IpcTaskInfo *ipcTaskInfo = taskCB->ipcTaskInfo; + if (ipcTaskInfo == NULL) { + return; + } + +#if (USE_TASKID_AS_HANDLE == 1) + + UINT32 intSave; + LOS_DL_LIST *listHead = NULL; + LOS_DL_LIST *listNode = NULL; + IpcListNode *node = NULL; + LosProcessCB *pcb = OS_PCB_FROM_TCB(taskCB); + + listHead = &(ipcTaskInfo->msgListHead); + do { + SCHEDULER_LOCK(intSave); + if (LOS_ListEmpty(listHead)) { + SCHEDULER_UNLOCK(intSave); + break; + } else { + listNode = LOS_DL_LIST_FIRST(listHead); + LOS_ListDelete(listNode); + node = LOS_DL_LIST_ENTRY(listNode, IpcListNode, listNode); + SCHEDULER_UNLOCK(intSave); + (VOID)HandleSpecialObjects(taskCB->taskID, node, TRUE); + (VOID)LiteIpcNodeFree(pcb, (VOID *)node); + } + } while (1); + + ipcTaskInfo->accessMap[pcb->processID] = FALSE; + for (j = 0; j < LOSCFG_BASE_CORE_PROCESS_LIMIT; j++) { + if (ipcTaskInfo->accessMap[j] == TRUE) { + ipcTaskInfo->accessMap[j] = FALSE; + (VOID)SendDeathMsg(j, taskCB->taskID); + } + } +#else + (VOID)LOS_MuxLock(&g_serviceHandleMapMux, LOS_WAIT_FOREVER); + for (UINT32 i = 1; i < MAX_SERVICE_NUM; i++) { + if ((g_serviceHandleMap[i].status != HANDLE_NOT_USED) && (g_serviceHandleMap[i].taskID == taskCB->taskID)) { + g_serviceHandleMap[i].status = HANDLE_NOT_USED; + g_serviceHandleMap[i].taskID = INVAILD_ID; + break; + } + } + (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux); + /* run deathHandler */ + if (i < MAX_SERVICE_NUM) { + for (j = 0; j < LOSCFG_BASE_CORE_PROCESS_LIMIT; j++) { + if (ipcTaskInfo->accessMap[j] == TRUE) { + (VOID)SendDeathMsg(j, i); + } + } + } +#endif + + (VOID)LOS_MemFree(m_aucSysMem1, ipcTaskInfo); + taskCB->ipcTaskInfo = NULL; +} + +LITE_OS_SEC_TEXT STATIC UINT32 SetCms(UINTPTR maxMsgSize) +{ + if (maxMsgSize < sizeof(IpcMsg)) { + return -EINVAL; + } + (VOID)LOS_MuxLock(&g_serviceHandleMapMux, LOS_WAIT_FOREVER); +#if (USE_TASKID_AS_HANDLE == 1) + if (g_cmsTask.status == HANDLE_NOT_USED) { + g_cmsTask.status = HANDLE_REGISTED; + g_cmsTask.taskID = LOS_CurTaskIDGet(); + g_cmsTask.maxMsgSize = maxMsgSize; + (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux); + return LOS_OK; + } +#else + if (g_serviceHandleMap[0].status == HANDLE_NOT_USED) { + g_serviceHandleMap[0].status = HANDLE_REGISTED; + g_serviceHandleMap[0].taskID = LOS_CurTaskIDGet(); + (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux); + return LOS_OK; + } +#endif + (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux); + return -EEXIST; +} + +LITE_OS_SEC_TEXT STATIC BOOL IsCmsSet(VOID) +{ + BOOL ret; + (VOID)LOS_MuxLock(&g_serviceHandleMapMux, LOS_WAIT_FOREVER); +#if (USE_TASKID_AS_HANDLE == 1) + ret = g_cmsTask.status == HANDLE_REGISTED; +#else + ret = g_serviceHandleMap[0].status == HANDLE_REGISTED; +#endif + (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux); + return ret; +} + +LITE_OS_SEC_TEXT STATIC BOOL IsCmsTask(UINT32 taskID) +{ + BOOL ret; + (VOID)LOS_MuxLock(&g_serviceHandleMapMux, LOS_WAIT_FOREVER); +#if (USE_TASKID_AS_HANDLE == 1) + ret = IsCmsSet() ? (OS_TCB_FROM_TID(taskID)->processCB == OS_TCB_FROM_TID(g_cmsTask.taskID)->processCB) : FALSE; +#else + ret = IsCmsSet() ? (OS_TCB_FROM_TID(taskID)->processCB == + OS_TCB_FROM_TID(g_serviceHandleMap[0].taskID)->processCB) : FALSE; +#endif + (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux); + return ret; +} + +LITE_OS_SEC_TEXT STATIC BOOL IsTaskAlive(UINT32 taskID) +{ + LosTaskCB *tcb = NULL; + if (OS_TID_CHECK_INVALID(taskID)) { + return FALSE; + } + tcb = OS_TCB_FROM_TID(taskID); + if (OsTaskIsUnused(tcb)) { + return FALSE; + } + if (OsTaskIsInactive(tcb)) { + return FALSE; + } + if (!OsTaskIsUserMode(tcb)) { + return FALSE; + } + return TRUE; +} + +LITE_OS_SEC_TEXT STATIC UINT32 HandleFd(const LosProcessCB *pcb, SpecialObj *obj, BOOL isRollback) +{ + int ret; + if (isRollback == FALSE) { + ret = CopyFdToProc(obj->content.fd, pcb->processID); + if (ret < 0) { + return ret; + } + obj->content.fd = ret; + } else { + ret = CloseProcFd(obj->content.fd, pcb->processID); + if (ret < 0) { + return ret; + } + } + + return LOS_OK; +} + +LITE_OS_SEC_TEXT STATIC UINT32 HandlePtr(LosProcessCB *pcb, SpecialObj *obj, BOOL isRollback) +{ + VOID *buf = NULL; + UINT32 ret; + if ((obj->content.ptr.buff == NULL) || (obj->content.ptr.buffSz == 0)) { + return -EINVAL; + } + if (isRollback == FALSE) { + if (LOS_IsUserAddress((vaddr_t)(UINTPTR)(obj->content.ptr.buff)) == FALSE) { + PRINT_ERR("Liteipc Bad ptr address\n"); + return -EINVAL; + } + buf = LiteIpcNodeAlloc(pcb, obj->content.ptr.buffSz); + if (buf == NULL) { + PRINT_ERR("Liteipc DealPtr alloc mem failed\n"); + return -EINVAL; + } + ret = copy_from_user(buf, obj->content.ptr.buff, obj->content.ptr.buffSz); + if (ret != LOS_OK) { + LiteIpcNodeFree(pcb, buf); + return ret; + } + obj->content.ptr.buff = (VOID *)GetIpcUserAddr(pcb, (INTPTR)buf); + EnableIpcNodeFreeByUser(pcb, (VOID *)buf); + } else { + (VOID)LiteIpcNodeFree(pcb, (VOID *)GetIpcKernelAddr(pcb, (INTPTR)obj->content.ptr.buff)); + } + return LOS_OK; +} + +LITE_OS_SEC_TEXT STATIC UINT32 HandleSvc(UINT32 dstTid, SpecialObj *obj, BOOL isRollback) +{ + UINT32 taskID = 0; + if (isRollback == FALSE) { + if (obj->content.svc.handle == -1) { + if (obj->content.svc.token != 1) { + PRINT_ERR("Liteipc HandleSvc wrong svc token\n"); + return -EINVAL; + } + UINT32 selfTid = LOS_CurTaskIDGet(); + LosTaskCB *tcb = OS_TCB_FROM_TID(selfTid); + if (tcb->ipcTaskInfo == NULL) { + tcb->ipcTaskInfo = LiteIpcTaskInit(); + } + uint32_t serviceHandle = 0; + UINT32 ret = GenerateServiceHandle(selfTid, HANDLE_REGISTED, &serviceHandle); + if (ret != LOS_OK) { + PRINT_ERR("Liteipc GenerateServiceHandle failed.\n"); + return ret; + } + obj->content.svc.handle = serviceHandle; + (VOID)LOS_MuxLock(&g_serviceHandleMapMux, LOS_WAIT_FOREVER); + AddServiceAccess(dstTid, serviceHandle); + (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux); + } + if (IsTaskAlive(obj->content.svc.handle) == FALSE) { + PRINT_ERR("Liteipc HandleSvc wrong svctid\n"); + return -EINVAL; + } + if (HasServiceAccess(obj->content.svc.handle) == FALSE) { + PRINT_ERR("Liteipc %s, %d, svchandle:%d, tid:%d\n", __FUNCTION__, __LINE__, obj->content.svc.handle, LOS_CurTaskIDGet()); + return -EACCES; + } + LosTaskCB *taskCb = OS_TCB_FROM_TID(obj->content.svc.handle); + if (taskCb->ipcTaskInfo == NULL) { + taskCb->ipcTaskInfo = LiteIpcTaskInit(); + } + if (GetTid(obj->content.svc.handle, &taskID) == 0) { + AddServiceAccess(dstTid, obj->content.svc.handle); + } + } + return LOS_OK; +} + +LITE_OS_SEC_TEXT STATIC UINT32 HandleObj(UINT32 dstTid, SpecialObj *obj, BOOL isRollback) +{ + UINT32 ret; + LosProcessCB *pcb = OS_PCB_FROM_TID(dstTid); + switch (obj->type) { + case OBJ_FD: + ret = HandleFd(pcb, obj, isRollback); + break; + case OBJ_PTR: + ret = HandlePtr(pcb, obj, isRollback); + break; + case OBJ_SVC: + ret = HandleSvc(dstTid, (SpecialObj *)obj, isRollback); + break; + default: + ret = -EINVAL; + break; + } + return ret; +} + +LITE_OS_SEC_TEXT STATIC UINT32 HandleSpecialObjects(UINT32 dstTid, IpcListNode *node, BOOL isRollback) +{ + UINT32 ret = LOS_OK; + IpcMsg *msg = &(node->msg); + INT32 i; + SpecialObj *obj = NULL; + UINT32 *offset = (UINT32 *)(UINTPTR)(msg->offsets); + if (isRollback) { + i = msg->spObjNum; + goto EXIT; + } + for (i = 0; i < msg->spObjNum; i++) { + if (offset[i] > msg->dataSz - sizeof(SpecialObj)) { + ret = -EINVAL; + goto EXIT; + } + if ((i > 0) && (offset[i] < offset[i - 1] + sizeof(SpecialObj))) { + ret = -EINVAL; + goto EXIT; + } + obj = (SpecialObj *)((UINTPTR)msg->data + offset[i]); + if (obj == NULL) { + ret = -EINVAL; + goto EXIT; + } + ret = HandleObj(dstTid, obj, FALSE); + if (ret != LOS_OK) { + goto EXIT; + } + } + return LOS_OK; +EXIT: + for (i--; i >= 0; i--) { + obj = (SpecialObj *)((UINTPTR)msg->data + offset[i]); + (VOID)HandleObj(dstTid, obj, TRUE); + } + return ret; +} + +LITE_OS_SEC_TEXT STATIC UINT32 CheckMsgSize(IpcMsg *msg) +{ + UINT64 totalSize; + UINT32 i; + UINT32 *offset = (UINT32 *)(UINTPTR)(msg->offsets); + SpecialObj *obj = NULL; + if (msg->target.handle != 0) { + return LOS_OK; + } + /* msg send to cms, check the msg size */ + totalSize = (UINT64)sizeof(IpcMsg) + msg->dataSz + msg->spObjNum * sizeof(UINT32); + for (i = 0; i < msg->spObjNum; i++) { + if (offset[i] > msg->dataSz - sizeof(SpecialObj)) { + return -EINVAL; + } + if ((i > 0) && (offset[i] < offset[i - 1] + sizeof(SpecialObj))) { + return -EINVAL; + } + obj = (SpecialObj *)((UINTPTR)msg->data + offset[i]); + if (obj == NULL) { + return -EINVAL; + } + if (obj->type == OBJ_PTR) { + totalSize += obj->content.ptr.buffSz; + } + } + (VOID)LOS_MuxLock(&g_serviceHandleMapMux, LOS_WAIT_FOREVER); + if (totalSize > g_cmsTask.maxMsgSize) { + (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux); + return -EINVAL; + } + (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux); + return LOS_OK; +} + +LITE_OS_SEC_TEXT STATIC UINT32 CopyDataFromUser(IpcListNode *node, UINT32 bufSz, const IpcMsg *msg) +{ + UINT32 ret; + ret = (UINT32)memcpy_s((VOID *)(&node->msg), bufSz - sizeof(LOS_DL_LIST), (const VOID *)msg, sizeof(IpcMsg)); + if (ret != LOS_OK) { + PRINT_DEBUG("%s, %d, %u\n", __FUNCTION__, __LINE__, ret); + return ret; + } + + if (msg->dataSz) { + node->msg.data = (VOID *)((UINTPTR)node + sizeof(IpcListNode)); + ret = copy_from_user((VOID *)(node->msg.data), msg->data, msg->dataSz); + if (ret != LOS_OK) { + PRINT_DEBUG("%s, %d\n", __FUNCTION__, __LINE__); + return ret; + } + } else { + node->msg.data = NULL; + } + + if (msg->spObjNum) { + node->msg.offsets = (VOID *)((UINTPTR)node + sizeof(IpcListNode) + msg->dataSz); + ret = copy_from_user((VOID *)(node->msg.offsets), msg->offsets, msg->spObjNum * sizeof(UINT32)); + if (ret != LOS_OK) { + PRINT_DEBUG("%s, %d, %x, %x, %d\n", __FUNCTION__, __LINE__, node->msg.offsets, msg->offsets, msg->spObjNum); + return ret; + } + } else { + node->msg.offsets = NULL; + } + ret = CheckMsgSize(&node->msg); + if (ret != LOS_OK) { + PRINT_DEBUG("%s, %d\n", __FUNCTION__, __LINE__); + return ret; + } + node->msg.taskID = LOS_CurTaskIDGet(); + node->msg.processID = OsCurrProcessGet()->processID; +#ifdef LOSCFG_SECURITY_CAPABILITY + node->msg.userID = OsCurrProcessGet()->user->userID; + node->msg.gid = OsCurrProcessGet()->user->gid; +#endif + return LOS_OK; +} + +LITE_OS_SEC_TEXT STATIC BOOL IsValidReply(const IpcContent *content) +{ + LosProcessCB *curr = OsCurrProcessGet(); + IpcListNode *node = (IpcListNode *)GetIpcKernelAddr(curr, (INTPTR)(content->buffToFree)); + IpcMsg *requestMsg = &node->msg; + IpcMsg *replyMsg = content->outMsg; + UINT32 reqDstTid = 0; + /* Check whether the reply matches the request */ + if ((requestMsg->type != MT_REQUEST) || + (requestMsg->flag == LITEIPC_FLAG_ONEWAY) || + (replyMsg->timestamp != requestMsg->timestamp) || + (replyMsg->target.handle != requestMsg->taskID) || + (GetTid(requestMsg->target.handle, &reqDstTid) != 0) || + (OS_TCB_FROM_TID(reqDstTid)->processCB != (UINTPTR)curr)) { + return FALSE; + } + return TRUE; +} + +LITE_OS_SEC_TEXT STATIC UINT32 CheckPara(IpcContent *content, UINT32 *dstTid) +{ + UINT32 ret; + IpcMsg *msg = content->outMsg; + UINT32 flag = content->flag; +#if (USE_TIMESTAMP == 1) + UINT64 now = LOS_CurrNanosec(); +#endif + if (((msg->dataSz > 0) && (msg->data == NULL)) || + ((msg->spObjNum > 0) && (msg->offsets == NULL)) || + (msg->dataSz > IPC_MSG_DATA_SZ_MAX) || + (msg->spObjNum > IPC_MSG_OBJECT_NUM_MAX) || + (msg->dataSz < msg->spObjNum * sizeof(SpecialObj))) { + return -EINVAL; + } + switch (msg->type) { + case MT_REQUEST: + if (HasServiceAccess(msg->target.handle)) { + ret = GetTid(msg->target.handle, dstTid); + if (ret != LOS_OK) { + return -EINVAL; + } + } else { + PRINT_ERR("Liteipc %s, %d\n", __FUNCTION__, __LINE__); + return -EACCES; + } +#if (USE_TIMESTAMP == 1) + msg->timestamp = now; +#endif + break; + case MT_REPLY: + case MT_FAILED_REPLY: + if ((flag & BUFF_FREE) != BUFF_FREE) { + return -EINVAL; + } + if (!IsValidReply(content)) { + return -EINVAL; + } +#if (USE_TIMESTAMP == 1) + if (now > msg->timestamp + LITEIPC_TIMEOUT_NS) { +#ifdef LOSCFG_KERNEL_HOOK + ret = GetTid(msg->target.handle, dstTid); + if (ret != LOS_OK) { + *dstTid = INVAILD_ID; + } +#endif + OsHookCall(LOS_HOOK_TYPE_IPC_WRITE_DROP, msg, *dstTid, + (*dstTid == INVAILD_ID) ? INVAILD_ID : OS_PCB_FROM_TID(*dstTid)->processID, 0); + PRINT_ERR("Liteipc A timeout reply, request timestamp:%lld, now:%lld\n", msg->timestamp, now); + return -ETIME; + } +#endif + *dstTid = msg->target.handle; + break; + case MT_DEATH_NOTIFY: + *dstTid = msg->target.handle; +#if (USE_TIMESTAMP == 1) + msg->timestamp = now; +#endif + break; + default: + PRINT_DEBUG("Unknown msg type:%d\n", msg->type); + return -EINVAL; + } + + if (IsTaskAlive(*dstTid) == FALSE) { + return -EINVAL; + } + return LOS_OK; +} + +LITE_OS_SEC_TEXT STATIC UINT32 LiteIpcWrite(IpcContent *content) +{ + UINT32 ret, intSave; + UINT32 dstTid; + + IpcMsg *msg = content->outMsg; + + ret = CheckPara(content, &dstTid); + if (ret != LOS_OK) { + return ret; + } + + LosTaskCB *tcb = OS_TCB_FROM_TID(dstTid); + LosProcessCB *pcb = OS_PCB_FROM_TCB(tcb); + if (pcb->ipcInfo == NULL) { + PRINT_ERR("pid %u Liteipc not create\n", pcb->processID); + return -EINVAL; + } + + UINT32 bufSz = sizeof(IpcListNode) + msg->dataSz + msg->spObjNum * sizeof(UINT32); + IpcListNode *buf = (IpcListNode *)LiteIpcNodeAlloc(pcb, bufSz); + if (buf == NULL) { + PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__); + return -ENOMEM; + } + ret = CopyDataFromUser(buf, bufSz, (const IpcMsg *)msg); + if (ret != LOS_OK) { + PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__); + goto ERROR_COPY; + } + + if (tcb->ipcTaskInfo == NULL) { + tcb->ipcTaskInfo = LiteIpcTaskInit(); + } + + ret = HandleSpecialObjects(dstTid, buf, FALSE); + if (ret != LOS_OK) { + PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__); + goto ERROR_COPY; + } + /* add data to list and wake up dest task */ + SCHEDULER_LOCK(intSave); + LOS_ListTailInsert(&(tcb->ipcTaskInfo->msgListHead), &(buf->listNode)); + OsHookCall(LOS_HOOK_TYPE_IPC_WRITE, &buf->msg, dstTid, pcb->processID, tcb->waitFlag); + if (tcb->waitFlag == OS_TASK_WAIT_LITEIPC) { + OsTaskWakeClearPendMask(tcb); + tcb->ops->wake(tcb); + SCHEDULER_UNLOCK(intSave); + LOS_MpSchedule(OS_MP_CPU_ALL); + LOS_Schedule(); + } else { + SCHEDULER_UNLOCK(intSave); + } + return LOS_OK; +ERROR_COPY: + LiteIpcNodeFree(pcb, buf); + return ret; +} + +LITE_OS_SEC_TEXT STATIC UINT32 CheckReceivedMsg(IpcListNode *node, IpcContent *content, LosTaskCB *tcb) +{ + UINT32 ret = LOS_OK; + if (node == NULL) { + return -EINVAL; + } + switch (node->msg.type) { + case MT_REQUEST: + if ((content->flag & SEND) == SEND) { + PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__); + ret = -EINVAL; + } + break; + case MT_FAILED_REPLY: + ret = -ENOENT; + /* fall-through */ + case MT_REPLY: + if ((content->flag & SEND) != SEND) { + PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__); + ret = -EINVAL; + } +#if (USE_TIMESTAMP == 1) + if (node->msg.timestamp != content->outMsg->timestamp) { + PRINT_ERR("Receive a unmatch reply, drop it\n"); + ret = -EINVAL; + } +#else + if ((node->msg.code != content->outMsg->code) || + (node->msg.target.token != content->outMsg->target.token)) { + PRINT_ERR("Receive a unmatch reply, drop it\n"); + ret = -EINVAL; + } +#endif + break; + case MT_DEATH_NOTIFY: + break; + default: + PRINT_ERR("Unknown msg type:%d\n", node->msg.type); + ret = -EINVAL; + } + if (ret != LOS_OK) { + OsHookCall(LOS_HOOK_TYPE_IPC_READ_DROP, &node->msg, tcb->waitFlag); + (VOID)HandleSpecialObjects(LOS_CurTaskIDGet(), node, TRUE); + (VOID)LiteIpcNodeFree(OsCurrProcessGet(), (VOID *)node); + } else { + OsHookCall(LOS_HOOK_TYPE_IPC_READ, &node->msg, tcb->waitFlag); + } + return ret; +} + +LITE_OS_SEC_TEXT STATIC UINT32 LiteIpcRead(IpcContent *content) +{ + UINT32 intSave, ret; + UINT32 selfTid = LOS_CurTaskIDGet(); + LOS_DL_LIST *listHead = NULL; + LOS_DL_LIST *listNode = NULL; + IpcListNode *node = NULL; + UINT32 syncFlag = (content->flag & SEND) && (content->flag & RECV); + UINT32 timeout = syncFlag ? LOS_MS2Tick(LITEIPC_TIMEOUT_MS) : LOS_WAIT_FOREVER; + + LosTaskCB *tcb = OS_TCB_FROM_TID(selfTid); + if (tcb->ipcTaskInfo == NULL) { + tcb->ipcTaskInfo = LiteIpcTaskInit(); + } + + listHead = &(tcb->ipcTaskInfo->msgListHead); + do { + SCHEDULER_LOCK(intSave); + if (LOS_ListEmpty(listHead)) { + OsTaskWaitSetPendMask(OS_TASK_WAIT_LITEIPC, OS_INVALID_VALUE, timeout); + OsHookCall(LOS_HOOK_TYPE_IPC_TRY_READ, syncFlag ? MT_REPLY : MT_REQUEST, tcb->waitFlag); + ret = tcb->ops->wait(tcb, &g_ipcPendlist, timeout); + if (ret == LOS_ERRNO_TSK_TIMEOUT) { + OsHookCall(LOS_HOOK_TYPE_IPC_READ_TIMEOUT, syncFlag ? MT_REPLY : MT_REQUEST, tcb->waitFlag); + SCHEDULER_UNLOCK(intSave); + return -ETIME; + } + + if (OsTaskIsKilled(tcb)) { + OsHookCall(LOS_HOOK_TYPE_IPC_KILL, syncFlag ? MT_REPLY : MT_REQUEST, tcb->waitFlag); + SCHEDULER_UNLOCK(intSave); + return -ERFKILL; + } + + SCHEDULER_UNLOCK(intSave); + } else { + listNode = LOS_DL_LIST_FIRST(listHead); + LOS_ListDelete(listNode); + node = LOS_DL_LIST_ENTRY(listNode, IpcListNode, listNode); + SCHEDULER_UNLOCK(intSave); + ret = CheckReceivedMsg(node, content, tcb); + if (ret == LOS_OK) { + break; + } + if (ret == -ENOENT) { /* It means that we've received a failed reply */ + return ret; + } + } + } while (1); + node->msg.data = (VOID *)GetIpcUserAddr(OsCurrProcessGet(), (INTPTR)(node->msg.data)); + node->msg.offsets = (VOID *)GetIpcUserAddr(OsCurrProcessGet(), (INTPTR)(node->msg.offsets)); + content->inMsg = (VOID *)GetIpcUserAddr(OsCurrProcessGet(), (INTPTR)(&(node->msg))); + EnableIpcNodeFreeByUser(OsCurrProcessGet(), (VOID *)node); + return LOS_OK; +} + +LITE_OS_SEC_TEXT STATIC UINT32 LiteIpcMsgHandle(IpcContent *con) +{ + UINT32 ret = LOS_OK; + IpcContent localContent; + IpcContent *content = &localContent; + IpcMsg localMsg; + IpcMsg *msg = &localMsg; + IpcListNode *nodeNeedFree = NULL; + + if (copy_from_user((void *)content, (const void *)con, sizeof(IpcContent)) != LOS_OK) { + PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__); + return -EINVAL; + } + + if ((content->flag & BUFF_FREE) == BUFF_FREE) { + ret = CheckUsedBuffer(content->buffToFree, &nodeNeedFree); + if (ret != LOS_OK) { + PRINT_ERR("CheckUsedBuffer failed:%d\n", ret); + return ret; + } + } + + if ((content->flag & SEND) == SEND) { + if (content->outMsg == NULL) { + PRINT_ERR("content->outmsg is null\n"); + ret = -EINVAL; + goto BUFFER_FREE; + } + if (copy_from_user((void *)msg, (const void *)content->outMsg, sizeof(IpcMsg)) != LOS_OK) { + PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__); + ret = -EINVAL; + goto BUFFER_FREE; + } + content->outMsg = msg; + if ((content->outMsg->type < 0) || (content->outMsg->type >= MT_DEATH_NOTIFY)) { + PRINT_ERR("LiteIpc unknown msg type:%d\n", content->outMsg->type); + ret = -EINVAL; + goto BUFFER_FREE; + } + ret = LiteIpcWrite(content); + if (ret != LOS_OK) { + PRINT_ERR("LiteIpcWrite failed\n"); + goto BUFFER_FREE; + } + } +BUFFER_FREE: + if (nodeNeedFree != NULL) { + UINT32 freeRet = LiteIpcNodeFree(OsCurrProcessGet(), nodeNeedFree); + ret = (freeRet == LOS_OK) ? ret : freeRet; + } + if (ret != LOS_OK) { + return ret; + } + + if ((content->flag & RECV) == RECV) { + ret = LiteIpcRead(content); + if (ret != LOS_OK) { + PRINT_ERR("LiteIpcRead failed ERROR: %d\n", (INT32)ret); + return ret; + } + UINT32 offset = LOS_OFF_SET_OF(IpcContent, inMsg); + ret = copy_to_user((char*)con + offset, (char*)content + offset, sizeof(IpcMsg *)); + if (ret != LOS_OK) { + PRINT_ERR("%s, %d, %d\n", __FUNCTION__, __LINE__, ret); + return -EINVAL; + } + } + return ret; +} + +LITE_OS_SEC_TEXT STATIC UINT32 HandleCmsCmd(CmsCmdContent *content) +{ + UINT32 ret = LOS_OK; + CmsCmdContent localContent; + if (content == NULL) { + return -EINVAL; + } + if (IsCmsTask(LOS_CurTaskIDGet()) == FALSE) { + return -EACCES; + } + if (copy_from_user((void *)(&localContent), (const void *)content, sizeof(CmsCmdContent)) != LOS_OK) { + PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__); + return -EINVAL; + } + switch (localContent.cmd) { + case CMS_GEN_HANDLE: + if ((localContent.taskID != 0) && (IsTaskAlive(localContent.taskID) == FALSE)) { + return -EINVAL; + } + ret = GenerateServiceHandle(localContent.taskID, HANDLE_REGISTED, &(localContent.serviceHandle)); + if (ret == LOS_OK) { + ret = copy_to_user((void *)content, (const void *)(&localContent), sizeof(CmsCmdContent)); + } + (VOID)LOS_MuxLock(&g_serviceHandleMapMux, LOS_WAIT_FOREVER); + AddServiceAccess(g_cmsTask.taskID, localContent.serviceHandle); + (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux); + break; + case CMS_REMOVE_HANDLE: + if (localContent.serviceHandle >= MAX_SERVICE_NUM) { + return -EINVAL; + } + RefreshServiceHandle(localContent.serviceHandle, -1); + break; + case CMS_ADD_ACCESS: + if (IsTaskAlive(localContent.taskID) == FALSE) { + return -EINVAL; + } + return AddServiceAccess(localContent.taskID, localContent.serviceHandle); + default: + PRINT_DEBUG("Unknown cmd cmd:%d\n", localContent.cmd); + return -EINVAL; + } + return ret; +} + +LITE_OS_SEC_TEXT STATIC UINT32 HandleGetVersion(IpcVersion *version) +{ + UINT32 ret = LOS_OK; + IpcVersion localIpcVersion; + if (version == NULL) { + return -EINVAL; + } + + localIpcVersion.driverVersion = DRIVER_VERSION; + ret = copy_to_user((void *)version, (const void *)(&localIpcVersion), sizeof(IpcVersion)); + if (ret != LOS_OK) { + PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__); + } + return ret; +} + +LITE_OS_SEC_TEXT int LiteIpcIoctl(struct file *filep, int cmd, unsigned long arg) +{ + UINT32 ret = LOS_OK; + LosProcessCB *pcb = OsCurrProcessGet(); + ProcIpcInfo *ipcInfo = pcb->ipcInfo; + + if (ipcInfo == NULL) { + PRINT_ERR("Liteipc pool not create!\n"); + return -EINVAL; + } + + if (IsPoolMapped(ipcInfo) == FALSE) { + PRINT_ERR("Liteipc Ipc pool not init, need to mmap first!\n"); + return -ENOMEM; + } + + switch (cmd) { + case IPC_SET_CMS: + return (INT32)SetCms(arg); + case IPC_CMS_CMD: + return (INT32)HandleCmsCmd((CmsCmdContent *)(UINTPTR)arg); + case IPC_GET_VERSION: + return (INT32)HandleGetVersion((IpcVersion *)(UINTPTR)arg); + case IPC_SET_IPC_THREAD: + if (IsCmsSet() == FALSE) { + PRINT_ERR("Liteipc ServiceManager not set!\n"); + return -EINVAL; + } + return (INT32)SetIpcTask(); + case IPC_SEND_RECV_MSG: + if (arg == 0) { + return -EINVAL; + } + if (IsCmsSet() == FALSE) { + PRINT_ERR("Liteipc ServiceManager not set!\n"); + return -EINVAL; + } + ret = LiteIpcMsgHandle((IpcContent *)(UINTPTR)arg); + if (ret != LOS_OK) { + return (INT32)ret; + } + break; + default: + PRINT_ERR("Unknown liteipc ioctl cmd:%d\n", cmd); + return -EINVAL; + } + return (INT32)ret; +} diff --git a/src/kernel_liteos_a/kernel/extended/liteipc/hm_liteipc.h b/src/kernel_liteos_a/kernel/extended/liteipc/hm_liteipc.h new file mode 100644 index 00000000..9b82f90c --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/liteipc/hm_liteipc.h @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef HM_LITEIPC_H +#define HM_LITEIPC_H + +#include "sys/ioctl.h" +#include "los_config.h" +#include "los_typedef.h" +#include "los_vm_map.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define LITEIPC_DRIVER "/dev/lite_ipc" +#define LITEIPC_DRIVER_MODE 0644 +#define MAX_SERVICE_NUM LOSCFG_BASE_CORE_TSK_LIMIT +#define USE_TIMESTAMP 1 + +typedef enum { + HANDLE_NOT_USED, + HANDLE_REGISTING, + HANDLE_REGISTED +} HandleStatus; + +typedef struct { + HandleStatus status; + UINT32 taskID; + UINTPTR maxMsgSize; +} HandleInfo; + +typedef struct { + VOID *uvaddr; + VOID *kvaddr; + UINT32 poolSize; +} IpcPool; + +typedef struct { + IpcPool pool; + UINT32 ipcTaskID; + LOS_DL_LIST ipcUsedNodelist; + UINT32 access[LOSCFG_BASE_CORE_TSK_LIMIT]; +} ProcIpcInfo; + +typedef struct { + LOS_DL_LIST msgListHead; + BOOL accessMap[LOSCFG_BASE_CORE_PROCESS_LIMIT]; +} IpcTaskInfo; + +typedef enum { + OBJ_FD, + OBJ_PTR, + OBJ_SVC +} ObjType; + +typedef struct { + UINT32 buffSz; + VOID *buff; +} BuffPtr; + +typedef struct { + UINT32 handle; + UINT32 token; + UINT32 cookie; +} SvcIdentity; + +typedef union { + UINT32 fd; + BuffPtr ptr; + SvcIdentity svc; +} ObjContent; + +typedef struct { + ObjType type; + ObjContent content; +} SpecialObj; + +typedef enum { + MT_REQUEST, + MT_REPLY, + MT_FAILED_REPLY, + MT_DEATH_NOTIFY, + MT_NUM +} MsgType; + +typedef struct { + int32_t driverVersion; +} IpcVersion; + +/* lite ipc ioctl */ +#define IPC_IOC_MAGIC 'i' +#define IPC_SET_CMS _IO(IPC_IOC_MAGIC, 1) +#define IPC_CMS_CMD _IOWR(IPC_IOC_MAGIC, 2, CmsCmdContent) +#define IPC_SET_IPC_THREAD _IO(IPC_IOC_MAGIC, 3) +#define IPC_SEND_RECV_MSG _IOWR(IPC_IOC_MAGIC, 4, IpcContent) +#define IPC_GET_VERSION _IOR(IPC_IOC_MAGIC, 5, IpcVersion) + +typedef enum { + CMS_GEN_HANDLE, + CMS_REMOVE_HANDLE, + CMS_ADD_ACCESS +} CmsCmd; + +typedef struct { + CmsCmd cmd; + UINT32 taskID; + UINT32 serviceHandle; +} CmsCmdContent; + +typedef enum { + LITEIPC_FLAG_DEFAULT = 0, // send and reply + LITEIPC_FLAG_ONEWAY, // send message only +} IpcFlag; + +typedef struct { + MsgType type; /**< cmd type, decide the data structure below*/ + SvcIdentity target; /**< serviceHandle or targetTaskId, depending on type */ + UINT32 code; /**< service function code */ + UINT32 flag; +#if (USE_TIMESTAMP == 1) + UINT64 timestamp; +#endif + UINT32 dataSz; /**< size of data */ + VOID *data; + UINT32 spObjNum; + VOID *offsets; + UINT32 processID; /**< filled by kernel, processId of sender/receiver */ + UINT32 taskID; /**< filled by kernel, taskId of sender/receiver */ +#ifdef LOSCFG_SECURITY_CAPABILITY + UINT32 userID; + UINT32 gid; +#endif +} IpcMsg; + +typedef struct { + IpcMsg msg; + LOS_DL_LIST listNode; +} IpcListNode; + +#define SEND (1 << 0) +#define RECV (1 << 1) +#define BUFF_FREE (1 << 2) + +typedef struct { + UINT32 flag; /**< size of writeData */ + IpcMsg *outMsg; /**< data to send to target */ + IpcMsg *inMsg; /**< data reply by target */ + VOID *buffToFree; +} IpcContent; + +/* init liteipc driver */ +extern UINT32 OsLiteIpcInit(VOID); + +/* reinit process liteipc memory pool, using in fork situation */ +extern ProcIpcInfo *LiteIpcPoolReInit(const ProcIpcInfo *parentIpcInfo); + +/* remove service handle and send death notify */ +extern VOID LiteIpcRemoveServiceHandle(UINT32 taskID); + +extern UINT32 LiteIpcPoolDestroy(UINT32 processID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/src/kernel_liteos_a/kernel/extended/lms/BUILD.gn b/src/kernel_liteos_a/kernel/extended/lms/BUILD.gn new file mode 100644 index 00000000..e0dd2cd2 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/lms/BUILD.gn @@ -0,0 +1,43 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = defined(LOSCFG_KERNEL_LMS) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ + "lms_libc.c", + "los_lms.c", + ] +} + +config("public") { + include_dirs = [ "." ] +} diff --git a/src/kernel_liteos_a/kernel/extended/lms/Kconfig b/src/kernel_liteos_a/kernel/extended/lms/Kconfig new file mode 100644 index 00000000..77648874 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/lms/Kconfig @@ -0,0 +1,41 @@ +config KERNEL_LMS + bool "Enable Lite Memory Sanitizer" + default n + depends on KERNEL_EXTKERNEL && DEBUG_VERSION && LIB_LIBC + help + Select y to build LiteOS with memory sanitizer. + +config LMS_MAX_RECORD_POOL_NUM + int "Lms check pool max num" + default 50 + depends on KERNEL_LMS + help + The Max num of lms check pool + +config LMS_LOAD_CHECK + bool "Enable lms read check" + default y + depends on KERNEL_LMS + help + Select y to enable read check. + +config LMS_STORE_CHECK + bool "Enable lms write check" + default y + depends on KERNEL_LMS + help + Select y to enable write check. + +config LMS_CHECK_STRICT + bool "Enable lms strict check, byte-by-byte" + default n + depends on KERNEL_LMS + help + Select y to enable byte-by-byte check in lms + +config LMS_LIBC_FULL_CHECK + bool "Enable libc all function do lms check" + default n + depends on KERNEL_LMS + help + Select y to enable libc full check diff --git a/src/kernel_liteos_a/kernel/extended/lms/Makefile b/src/kernel_liteos_a/kernel/extended/lms/Makefile new file mode 100644 index 00000000..304e9c6c --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/lms/Makefile @@ -0,0 +1,10 @@ +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := $(wildcard *.c) + +LOCAL_FLAGS := $(LOCAL_INCLUDE) + +include $(MODULE) + diff --git a/src/kernel_liteos_a/kernel/extended/lms/lms_libc.c b/src/kernel_liteos_a/kernel/extended/lms/lms_libc.c new file mode 100644 index 00000000..8be9810f --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/lms/lms_libc.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "string.h" +#include "los_lms_pri.h" + +#undef memset +void *memset(void *addr, int c, size_t len) +{ + __asan_storeN_noabort((UINTPTR)addr, len); + return __memset(addr, c, len); +} + +#undef memmove +void *memmove(void *dest, const void *src, size_t len) +{ + __asan_loadN_noabort((UINTPTR)src, len); + __asan_storeN_noabort((UINTPTR)dest, len); + return __memmove(dest, src, len); +} + +#undef memcpy +void *memcpy(void *dest, const void *src, size_t len) +{ + __asan_loadN_noabort((UINTPTR)src, len); + __asan_storeN_noabort((UINTPTR)dest, len); + return __memcpy(dest, src, len); +} + +#undef strcat +char *strcat(char *s, const char *append) +{ + if ((s == NULL) || (append == NULL)) { + return NULL; + } + + CHAR *end = s; + size_t len = strlen(append); + for (; *end != '\0'; ++end) { + } + + __asan_storeN_noabort((UINTPTR)end, len + 1); + __asan_loadN_noabort((UINTPTR)append, len + 1); + + return __strcat(s, append); +} + +#undef strcpy +char *strcpy(char *dest, const char *src) +{ + if ((dest == NULL) || (src == NULL)) { + return NULL; + } + + size_t len = strlen(src); + __asan_storeN_noabort((UINTPTR)dest, len + 1); + __asan_loadN_noabort((UINTPTR)src, len + 1); + + return __strcpy(dest, src); +} + +#undef strncat +char *strncat(char *dest, const char *src, size_t n) +{ + if ((dest == NULL) || (src == NULL)) { + return NULL; + } + + CHAR *end = dest; + size_t len = strlen(src); + size_t size = len > n ? n : len; + for (; *end != '\0'; ++end) { + } + + __asan_storeN_noabort((UINTPTR)end, size + 1); + __asan_loadN_noabort((UINTPTR)src, size + 1); + + return __strncat(dest, src, n); +} + +#undef strncpy +char *strncpy(char *dest, const char *src, size_t n) +{ + if ((dest == NULL) || (src == NULL)) { + return NULL; + } + + size_t len = strlen(src); + size_t size = len > n ? n : len; + + __asan_storeN_noabort((UINTPTR)dest, n); + __asan_loadN_noabort((UINTPTR)src, size + 1); + return __strncpy(dest, src, n); +} diff --git a/src/kernel_liteos_a/kernel/extended/lms/los_lms.c b/src/kernel_liteos_a/kernel/extended/lms/los_lms.c new file mode 100644 index 00000000..81dd963e --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/lms/los_lms.c @@ -0,0 +1,770 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_lms_pri.h" +#include "los_spinlock.h" +#include "los_exc.h" +#include "los_sched_pri.h" +#include "los_atomic.h" +#include "los_init.h" + +LITE_OS_SEC_BSS STATIC LmsMemListNode g_lmsCheckPoolArray[LOSCFG_LMS_MAX_RECORD_POOL_NUM]; +LITE_OS_SEC_BSS STATIC LOS_DL_LIST g_lmsCheckPoolList; +STATIC Atomic g_checkDepth = 0; +LmsHook *g_lms = NULL; + +LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_lmsSpin); +#define LMS_LOCK(state) LOS_SpinLockSave(&g_lmsSpin, &(state)) +#define LMS_UNLOCK(state) LOS_SpinUnlockRestore(&g_lmsSpin, (state)) + +#define OS_MEM_ALIGN_BACK(value, align) (((UINT32)(value)) & ~((UINT32)((align) - 1))) +#define OS_MEM_ALIGN_SIZE sizeof(UINTPTR) +#define POOL_ADDR_ALIGNSIZE 64 +#define LMS_POOL_UNUSED 0 +#define LMS_POOL_USED 1 +#define INVALID_SHADOW_VALUE 0xFFFFFFFF + +STATIC UINT32 OsLmsPoolResize(UINT32 size) +{ + return OS_MEM_ALIGN_BACK(LMS_POOL_RESIZE(size), POOL_ADDR_ALIGNSIZE); +} + +STATIC LmsMemListNode *OsLmsGetPoolNode(const VOID *pool) +{ + UINTPTR poolAddr = (UINTPTR)pool; + LmsMemListNode *current = NULL; + LOS_DL_LIST *listHead = &g_lmsCheckPoolList; + + if (LOS_ListEmpty(&g_lmsCheckPoolList)) { + goto EXIT; + } + + LOS_DL_LIST_FOR_EACH_ENTRY(current, listHead, LmsMemListNode, node) { + if (current->poolAddr == poolAddr) { + return current; + } + } + +EXIT: + return NULL; +} + +STATIC LmsMemListNode *OsLmsGetPoolNodeFromAddr(UINTPTR addr) +{ + LmsMemListNode *current = NULL; + LmsMemListNode *previous = NULL; + LOS_DL_LIST *listHead = &g_lmsCheckPoolList; + + if (LOS_ListEmpty(&g_lmsCheckPoolList)) { + return NULL; + } + + LOS_DL_LIST_FOR_EACH_ENTRY(current, listHead, LmsMemListNode, node) { + if ((addr < current->poolAddr) || (addr >= (current->poolAddr + current->poolSize))) { + continue; + } + if ((previous == NULL) || + ((previous->poolAddr <= current->poolAddr) && + ((current->poolAddr + current->poolSize) <= (previous->poolAddr + previous->poolSize)))) { + previous = current; + } + } + + return previous; +} + +STATIC LmsMemListNode *OsLmsCheckPoolCreate(VOID) +{ + UINT32 i; + LmsMemListNode *current = NULL; + for (i = 0; i < LOSCFG_LMS_MAX_RECORD_POOL_NUM; i++) { + current = &g_lmsCheckPoolArray[i]; + if (current->used == LMS_POOL_UNUSED) { + current->used = LMS_POOL_USED; + return current; + } + } + return NULL; +} + +UINT32 LOS_LmsCheckPoolAdd(const VOID *pool, UINT32 size) +{ + UINT32 intSave; + UINTPTR poolAddr = (UINTPTR)pool; + UINT32 realSize; + LmsMemListNode *lmsPoolNode = NULL; + + if (pool == NULL) { + return 0; + } + + LMS_LOCK(intSave); + + lmsPoolNode = OsLmsGetPoolNode(pool); + if (lmsPoolNode != NULL) { /* if pool already on checklist */ + /* Re-initialize the same pool, maybe with different size */ + /* delete the old node, then add a new one */ + lmsPoolNode->used = LMS_POOL_UNUSED; + LOS_ListDelete(&(lmsPoolNode->node)); + } + + lmsPoolNode = OsLmsCheckPoolCreate(); + if (lmsPoolNode == NULL) { + PRINT_DEBUG("[LMS]the num of lms check pool is max already !\n"); + LMS_UNLOCK(intSave); + return 0; + } + realSize = OsLmsPoolResize(size); + + lmsPoolNode->poolAddr = poolAddr; + lmsPoolNode->poolSize = realSize; + lmsPoolNode->shadowStart = (UINTPTR)poolAddr + realSize; + lmsPoolNode->shadowSize = poolAddr + size - lmsPoolNode->shadowStart; + /* init shadow value */ + (VOID)memset_s((VOID *)lmsPoolNode->shadowStart, lmsPoolNode->shadowSize, + LMS_SHADOW_AFTERFREE_U8, lmsPoolNode->shadowSize); + + LOS_ListAdd(&g_lmsCheckPoolList, &(lmsPoolNode->node)); + + LMS_UNLOCK(intSave); + return realSize; +} + +VOID LOS_LmsCheckPoolDel(const VOID *pool) +{ + UINT32 intSave; + if (pool == NULL) { + return; + } + + LMS_LOCK(intSave); + LmsMemListNode *delNode = OsLmsGetPoolNode(pool); + if (delNode == NULL) { + PRINT_ERR("[LMS]pool %p is not on lms checklist !\n", pool); + goto Release; + } + delNode->used = LMS_POOL_UNUSED; + LOS_ListDelete(&(delNode->node)); +Release: + LMS_UNLOCK(intSave); +} + +STATIC UINT32 OsLmsInit(VOID) +{ + (VOID)memset_s(g_lmsCheckPoolArray, sizeof(g_lmsCheckPoolArray), 0, sizeof(g_lmsCheckPoolArray)); + LOS_ListInit(&g_lmsCheckPoolList); + static LmsHook hook = { + .init = LOS_LmsCheckPoolAdd, + .deInit = LOS_LmsCheckPoolDel, + .mallocMark = OsLmsLosMallocMark, + .freeMark = OsLmsLosFreeMark, + .simpleMark = OsLmsSimpleMark, + .check = OsLmsCheckValid, + }; + g_lms = &hook; + return LOS_OK; +} + +STATIC INLINE UINT32 OsLmsMem2Shadow(LmsMemListNode *node, UINTPTR memAddr, UINTPTR *shadowAddr, UINT32 *shadowOffset) +{ + if ((memAddr < node->poolAddr) || (memAddr >= node->poolAddr + node->poolSize)) { /* check ptr valid */ + PRINT_ERR("[LMS]memAddr %p is not in pool region [%p, %p)\n", memAddr, node->poolAddr, + node->poolAddr + node->poolSize); + return LOS_NOK; + } + + UINT32 memOffset = memAddr - node->poolAddr; + *shadowAddr = node->shadowStart + memOffset / LMS_SHADOW_U8_REFER_BYTES; + *shadowOffset = ((memOffset % LMS_SHADOW_U8_REFER_BYTES) / LMS_SHADOW_U8_CELL_NUM) * + LMS_SHADOW_BITS_PER_CELL; /* (memOffset % 16) / 4 */ + return LOS_OK; +} + +STATIC INLINE VOID OsLmsGetShadowInfo(LmsMemListNode *node, UINTPTR memAddr, LmsAddrInfo *info) +{ + UINTPTR shadowAddr; + UINT32 shadowOffset; + UINT32 shadowValue; + + if (OsLmsMem2Shadow(node, memAddr, &shadowAddr, &shadowOffset) != LOS_OK) { + return; + } + + shadowValue = ((*(UINT8 *)shadowAddr) >> shadowOffset) & LMS_SHADOW_MASK; + info->memAddr = memAddr; + info->shadowAddr = shadowAddr; + info->shadowOffset = shadowOffset; + info->shadowValue = shadowValue; +} + +VOID OsLmsSetShadowValue(LmsMemListNode *node, UINTPTR startAddr, UINTPTR endAddr, UINT8 value) +{ + UINTPTR shadowStart; + UINTPTR shadowEnd; + UINT32 startOffset; + UINT32 endOffset; + + UINT8 shadowValueMask; + UINT8 shadowValue; + + /* endAddr -1, then we mark [startAddr, endAddr) to value */ + if (OsLmsMem2Shadow(node, startAddr, &shadowStart, &startOffset) || + OsLmsMem2Shadow(node, endAddr - 1, &shadowEnd, &endOffset)) { + return; + } + + if (shadowStart == shadowEnd) { /* in the same u8 */ + /* because endAddr - 1, the endOffset falls into the previous cell, + so endOffset + 2 is required for calculation */ + shadowValueMask = LMS_SHADOW_MASK_U8; + shadowValueMask = + (shadowValueMask << startOffset) & (~(shadowValueMask << (endOffset + LMS_SHADOW_BITS_PER_CELL))); + shadowValue = value & shadowValueMask; + *(UINT8 *)shadowStart &= ~shadowValueMask; + *(UINT8 *)shadowStart |= shadowValue; + } else { + /* Adjust startAddr to left util it reach the beginning of a u8 */ + if (startOffset > 0) { + shadowValueMask = LMS_SHADOW_MASK_U8; + shadowValueMask = shadowValueMask << startOffset; + shadowValue = value & shadowValueMask; + *(UINT8 *)shadowStart &= ~shadowValueMask; + *(UINT8 *)shadowStart |= shadowValue; + shadowStart += 1; + } + + /* Adjust endAddr to right util it reach the end of a u8 */ + if (endOffset < (LMS_SHADOW_U8_CELL_NUM - 1) * LMS_SHADOW_BITS_PER_CELL) { + shadowValueMask = LMS_SHADOW_MASK_U8; + shadowValueMask &= ~(shadowValueMask << (endOffset + LMS_SHADOW_BITS_PER_CELL)); + shadowValue = value & shadowValueMask; + *(UINT8 *)shadowEnd &= ~shadowValueMask; + *(UINT8 *)shadowEnd |= shadowValue; + shadowEnd -= 1; + } + + if (shadowEnd + 1 > shadowStart) { + (VOID)memset((VOID *)shadowStart, value & LMS_SHADOW_MASK_U8, shadowEnd + 1 - shadowStart); + } + } +} + +VOID OsLmsGetShadowValue(LmsMemListNode *node, UINTPTR addr, UINT32 *shadowValue) +{ + UINTPTR shadowAddr; + UINT32 shadowOffset; + if (OsLmsMem2Shadow(node, addr, &shadowAddr, &shadowOffset) != LOS_OK) { + return; + } + + *shadowValue = ((*(UINT8 *)shadowAddr) >> shadowOffset) & LMS_SHADOW_MASK; +} + +VOID OsLmsSimpleMark(UINTPTR startAddr, UINTPTR endAddr, UINT32 value) +{ + UINT32 intSave; + if (endAddr <= startAddr) { + PRINT_DEBUG("[LMS]mark 0x%x, 0x%x, 0x%x\n", startAddr, endAddr, (UINTPTR)__builtin_return_address(0)); + return; + } + + if (!IS_ALIGNED(startAddr, OS_MEM_ALIGN_SIZE) || !IS_ALIGNED(endAddr, OS_MEM_ALIGN_SIZE)) { + PRINT_ERR("[LMS]mark addr is not aligned! 0x%x, 0x%x\n", startAddr, endAddr); + return; + } + + LMS_LOCK(intSave); + + LmsMemListNode *node = OsLmsGetPoolNodeFromAddr(startAddr); + if (node == NULL) { + LMS_UNLOCK(intSave); + return; + } + + OsLmsSetShadowValue(node, startAddr, endAddr, value); + LMS_UNLOCK(intSave); +} + +VOID OsLmsLosMallocMark(const VOID *curNodeStart, const VOID *nextNodeStart, UINT32 nodeHeadSize) +{ + UINT32 intSave; + UINTPTR curNodeStartAddr = (UINTPTR)curNodeStart; + UINTPTR nextNodeStartAddr = (UINTPTR)nextNodeStart; + + LMS_LOCK(intSave); + LmsMemListNode *node = OsLmsGetPoolNodeFromAddr((UINTPTR)curNodeStart); + if (node == NULL) { + LMS_UNLOCK(intSave); + return; + } + + OsLmsSetShadowValue(node, curNodeStartAddr, curNodeStartAddr + nodeHeadSize, LMS_SHADOW_REDZONE_U8); + OsLmsSetShadowValue(node, curNodeStartAddr + nodeHeadSize, nextNodeStartAddr, LMS_SHADOW_ACCESSIBLE_U8); + OsLmsSetShadowValue(node, nextNodeStartAddr, nextNodeStartAddr + nodeHeadSize, LMS_SHADOW_REDZONE_U8); + LMS_UNLOCK(intSave); +} + +VOID OsLmsCheckValid(UINTPTR checkAddr, BOOL isFreeCheck) +{ + UINT32 intSave; + UINT32 shadowValue = INVALID_SHADOW_VALUE; + LMS_LOCK(intSave); + LmsMemListNode *node = OsLmsGetPoolNodeFromAddr(checkAddr); + if (node == NULL) { + LMS_UNLOCK(intSave); + return; + } + + OsLmsGetShadowValue(node, checkAddr, &shadowValue); + LMS_UNLOCK(intSave); + if ((shadowValue == LMS_SHADOW_ACCESSIBLE) || ((isFreeCheck) && (shadowValue == LMS_SHADOW_PAINT))) { + return; + } + + OsLmsReportError(checkAddr, MEM_REGION_SIZE_1, isFreeCheck ? FREE_ERRORMODE : COMMON_ERRMODE); +} + +VOID OsLmsLosFreeMark(const VOID *curNodeStart, const VOID *nextNodeStart, UINT32 nodeHeadSize) +{ + UINT32 intSave; + UINT32 shadowValue = INVALID_SHADOW_VALUE; + + LMS_LOCK(intSave); + LmsMemListNode *node = OsLmsGetPoolNodeFromAddr((UINTPTR)curNodeStart); + if (node == NULL) { + LMS_UNLOCK(intSave); + return; + } + + UINTPTR curNodeStartAddr = (UINTPTR)curNodeStart; + UINTPTR nextNodeStartAddr = (UINTPTR)nextNodeStart; + + OsLmsGetShadowValue(node, curNodeStartAddr + nodeHeadSize, &shadowValue); + if ((shadowValue != LMS_SHADOW_ACCESSIBLE) && (shadowValue != LMS_SHADOW_PAINT)) { + LMS_UNLOCK(intSave); + OsLmsReportError(curNodeStartAddr + nodeHeadSize, MEM_REGION_SIZE_1, FREE_ERRORMODE); + return; + } + + if (*((UINT8 *)curNodeStart) == 0) { /* if merge the node has memset with 0 */ + OsLmsSetShadowValue(node, curNodeStartAddr, curNodeStartAddr + nodeHeadSize, LMS_SHADOW_AFTERFREE_U8); + } + OsLmsSetShadowValue(node, curNodeStartAddr + nodeHeadSize, nextNodeStartAddr, LMS_SHADOW_AFTERFREE_U8); + + if (*((UINT8 *)nextNodeStart) == 0) { /* if merge the node has memset with 0 */ + OsLmsSetShadowValue(node, nextNodeStartAddr, nextNodeStartAddr + nodeHeadSize, LMS_SHADOW_AFTERFREE_U8); + } + + LMS_UNLOCK(intSave); +} + +VOID LOS_LmsAddrProtect(UINTPTR addrStart, UINTPTR addrEnd) +{ + UINT32 intSave; + if (addrEnd <= addrStart) { + return; + } + LMS_LOCK(intSave); + LmsMemListNode *node = OsLmsGetPoolNodeFromAddr(addrStart); + if (node != NULL) { + OsLmsSetShadowValue(node, addrStart, addrEnd, LMS_SHADOW_REDZONE_U8); + } + LMS_UNLOCK(intSave); +} + +VOID LOS_LmsAddrDisableProtect(UINTPTR addrStart, UINTPTR addrEnd) +{ + UINT32 intSave; + if (addrEnd <= addrStart) { + return; + } + LMS_LOCK(intSave); + LmsMemListNode *node = OsLmsGetPoolNodeFromAddr(addrStart); + if (node != NULL) { + OsLmsSetShadowValue(node, addrStart, addrEnd, LMS_SHADOW_ACCESSIBLE_U8); + } + LMS_UNLOCK(intSave); +} + +STATIC UINT32 OsLmsCheckAddr(UINTPTR addr) +{ + UINT32 intSave; + UINT32 shadowValue = INVALID_SHADOW_VALUE; + /* do not check nested or before all cpu start */ + if ((LOS_AtomicRead(&g_checkDepth)) || (!OS_SCHEDULER_ALL_ACTIVE)) { + return 0; + } + + LMS_LOCK(intSave); + LmsMemListNode *node = OsLmsGetPoolNodeFromAddr(addr); + if (node == NULL) { + LMS_UNLOCK(intSave); + return LMS_SHADOW_ACCESSIBLE_U8; + } + + OsLmsGetShadowValue(node, addr, &shadowValue); + LMS_UNLOCK(intSave); + return shadowValue; +} + +#ifdef LOSCFG_LMS_CHECK_STRICT +STATIC INLINE UINT32 OsLmsCheckAddrRegion(UINTPTR addr, UINT32 size) +{ + UINT32 i; + for (i = 0; i < size; i++) { + if (OsLmsCheckAddr(addr + i)) { + return LOS_NOK; + } + } + return LOS_OK; +} + +#else +STATIC INLINE UINT32 OsLmsCheckAddrRegion(UINTPTR addr, UINT32 size) +{ + if (OsLmsCheckAddr(addr) || OsLmsCheckAddr(addr + size - 1)) { + return LOS_NOK; + } else { + return LOS_OK; + } +} +#endif + +VOID OsLmsPrintPoolListInfo(VOID) +{ + UINT32 count = 0; + UINT32 intSave; + LmsMemListNode *current = NULL; + LOS_DL_LIST *listHead = &g_lmsCheckPoolList; + + LMS_LOCK(intSave); + LOS_DL_LIST_FOR_EACH_ENTRY(current, listHead, LmsMemListNode, node) + { + count++; + PRINT_DEBUG( + "[LMS]memory pool[%1u]: totalsize 0x%-8x memstart 0x%-8x memstop 0x%-8x memsize 0x%-8x shadowstart 0x%-8x " + "shadowSize 0x%-8x\n", + count, current->poolSize + current->shadowSize, current->poolAddr, current->poolAddr + current->poolSize, + current->poolSize, current->shadowStart, current->shadowSize); + } + + LMS_UNLOCK(intSave); +} + +VOID OsLmsPrintMemInfo(UINTPTR addr) +{ +#define LMS_DUMP_OFFSET 16 +#define LMS_DUMP_RANGE_DOUBLE 2 + + PRINTK("\n[LMS] Dump info around address [0x%8x]:\n", addr); + const UINT32 printY = LMS_DUMP_OFFSET * LMS_DUMP_RANGE_DOUBLE + 1; + const UINT32 printX = LMS_MEM_BYTES_PER_SHADOW_CELL * LMS_DUMP_RANGE_DOUBLE; + UINTPTR dumpAddr = addr - addr % printX - LMS_DUMP_OFFSET * printX; + UINT32 shadowValue = 0; + UINTPTR shadowAddr = 0; + UINT32 shadowOffset = 0; + LmsMemListNode *nodeInfo = NULL; + INT32 isCheckAddr, x, y; + + nodeInfo = OsLmsGetPoolNodeFromAddr(addr); + if (nodeInfo == NULL) { + PRINT_ERR("[LMS]addr is not in checkpool\n"); + return; + } + + for (y = 0; y < printY; y++, dumpAddr += printX) { + if (dumpAddr < nodeInfo->poolAddr) { /* find util dumpAddr in pool region */ + continue; + } + + if ((dumpAddr + printX) >= + nodeInfo->poolAddr + nodeInfo->poolSize) { /* finish if dumpAddr exceeds pool's upper region */ + goto END; + } + + PRINTK("\n\t[0x%x]: ", dumpAddr); + for (x = 0; x < printX; x++) { + if ((dumpAddr + x) == addr) { + PRINTK("[%02x]", *(UINT8 *)(dumpAddr + x)); + } else { + PRINTK(" %02x ", *(UINT8 *)(dumpAddr + x)); + } + } + + if (OsLmsMem2Shadow(nodeInfo, dumpAddr, &shadowAddr, &shadowOffset) != LOS_OK) { + goto END; + } + + PRINTK("|\t[0x%x | %2u]: ", shadowAddr, shadowOffset); + + for (x = 0; x < printX; x += LMS_MEM_BYTES_PER_SHADOW_CELL) { + OsLmsGetShadowValue(nodeInfo, dumpAddr + x, &shadowValue); + isCheckAddr = dumpAddr + x - (UINTPTR)addr + LMS_MEM_BYTES_PER_SHADOW_CELL; + if ((isCheckAddr > 0) && (isCheckAddr <= LMS_MEM_BYTES_PER_SHADOW_CELL)) { + PRINTK("[%1x]", shadowValue); + } else { + PRINTK(" %1x ", shadowValue); + } + } + } +END: + PRINTK("\n"); +} + +STATIC VOID OsLmsGetErrorInfo(UINTPTR addr, UINT32 size, LmsAddrInfo *info) +{ + LmsMemListNode *node = OsLmsGetPoolNodeFromAddr(addr); + OsLmsGetShadowInfo(node, addr, info); + if (info->shadowValue != LMS_SHADOW_ACCESSIBLE_U8) { + return; + } else { + OsLmsGetShadowInfo(node, addr + size - 1, info); + } +} + +STATIC VOID OsLmsPrintErrInfo(LmsAddrInfo *info, UINT32 errMod) +{ + switch (info->shadowValue) { + case LMS_SHADOW_AFTERFREE: + PRINT_ERR("Use after free error detected\n"); + break; + case LMS_SHADOW_REDZONE: + PRINT_ERR("Heap buffer overflow error detected\n"); + break; + case LMS_SHADOW_ACCESSIBLE: + PRINT_ERR("No error\n"); + break; + default: + PRINT_ERR("UnKnown Error detected\n"); + break; + } + + switch (errMod) { + case FREE_ERRORMODE: + PRINT_ERR("Illegal Double free address at: [0x%lx]\n", info->memAddr); + break; + case LOAD_ERRMODE: + PRINT_ERR("Illegal READ address at: [0x%lx]\n", info->memAddr); + break; + case STORE_ERRMODE: + PRINT_ERR("Illegal WRITE address at: [0x%lx]\n", info->memAddr); + break; + case COMMON_ERRMODE: + PRINT_ERR("Common Error at: [0x%lx]\n", info->memAddr); + break; + default: + PRINT_ERR("UnKnown Error mode at: [0x%lx]\n", info->memAddr); + break; + } + + PRINT_ERR("Shadow memory address: [0x%lx : %1u] Shadow memory value: [%u] \n", info->shadowAddr, + info->shadowOffset, info->shadowValue); +} + +VOID OsLmsReportError(UINTPTR p, UINT32 size, UINT32 errMod) +{ + UINT32 intSave; + LmsAddrInfo info; + + (VOID)LOS_AtomicAdd(&g_checkDepth, 1); + LMS_LOCK(intSave); + (VOID)memset_s(&info, sizeof(LmsAddrInfo), 0, sizeof(LmsAddrInfo)); + + PRINT_ERR("***** Kernel Address Sanitizer Error Detected Start *****\n"); + + OsLmsGetErrorInfo(p, size, &info); + + OsLmsPrintErrInfo(&info, errMod); + + OsBackTrace(); + + OsLmsPrintMemInfo(info.memAddr); + LMS_UNLOCK(intSave); + PRINT_ERR("***** Kernel Address Sanitizer Error Detected End *****\n"); + (VOID)LOS_AtomicSub(&g_checkDepth, 1); +} + +#ifdef LOSCFG_LMS_STORE_CHECK +VOID __asan_store1_noabort(UINTPTR p) +{ + if (OsLmsCheckAddr(p) != LMS_SHADOW_ACCESSIBLE_U8) { + OsLmsReportError(p, MEM_REGION_SIZE_1, STORE_ERRMODE); + } +} + +VOID __asan_store2_noabort(UINTPTR p) +{ + if (OsLmsCheckAddrRegion(p, MEM_REGION_SIZE_2) != LOS_OK) { + OsLmsReportError(p, MEM_REGION_SIZE_2, STORE_ERRMODE); + } +} + +VOID __asan_store4_noabort(UINTPTR p) +{ + if (OsLmsCheckAddrRegion(p, MEM_REGION_SIZE_4) != LOS_OK) { + OsLmsReportError(p, MEM_REGION_SIZE_4, STORE_ERRMODE); + } +} + +VOID __asan_store8_noabort(UINTPTR p) +{ + if (OsLmsCheckAddrRegion(p, MEM_REGION_SIZE_8) != LOS_OK) { + OsLmsReportError(p, MEM_REGION_SIZE_8, STORE_ERRMODE); + } +} + +VOID __asan_store16_noabort(UINTPTR p) +{ + if (OsLmsCheckAddrRegion(p, MEM_REGION_SIZE_16) != LOS_OK) { + OsLmsReportError(p, MEM_REGION_SIZE_16, STORE_ERRMODE); + } +} + +VOID __asan_storeN_noabort(UINTPTR p, UINT32 size) +{ + if (OsLmsCheckAddrRegion(p, size) != LOS_OK) { + OsLmsReportError(p, size, STORE_ERRMODE); + } +} +#else +VOID __asan_store1_noabort(UINTPTR p) +{ + (VOID)p; +} + +VOID __asan_store2_noabort(UINTPTR p) +{ + (VOID)p; +} + +VOID __asan_store4_noabort(UINTPTR p) +{ + (VOID)p; +} + +VOID __asan_store8_noabort(UINTPTR p) +{ + (VOID)p; +} + +VOID __asan_store16_noabort(UINTPTR p) +{ + (VOID)p; +} + +VOID __asan_storeN_noabort(UINTPTR p, UINT32 size) +{ + (VOID)p; + (VOID)size; +} + +#endif + +#ifdef LOSCFG_LMS_LOAD_CHECK +VOID __asan_load1_noabort(UINTPTR p) +{ + if (OsLmsCheckAddr(p) != LMS_SHADOW_ACCESSIBLE_U8) { + OsLmsReportError(p, MEM_REGION_SIZE_1, LOAD_ERRMODE); + } +} + +VOID __asan_load2_noabort(UINTPTR p) +{ + if (OsLmsCheckAddrRegion(p, MEM_REGION_SIZE_2) != LOS_OK) { + OsLmsReportError(p, MEM_REGION_SIZE_2, LOAD_ERRMODE); + } +} + +VOID __asan_load4_noabort(UINTPTR p) +{ + if (OsLmsCheckAddrRegion(p, MEM_REGION_SIZE_4) != LOS_OK) { + OsLmsReportError(p, MEM_REGION_SIZE_4, LOAD_ERRMODE); + } +} + +VOID __asan_load8_noabort(UINTPTR p) +{ + if (OsLmsCheckAddrRegion(p, MEM_REGION_SIZE_8) != LOS_OK) { + OsLmsReportError(p, MEM_REGION_SIZE_8, LOAD_ERRMODE); + } +} + +VOID __asan_load16_noabort(UINTPTR p) +{ + if (OsLmsCheckAddrRegion(p, MEM_REGION_SIZE_16) != LOS_OK) { + OsLmsReportError(p, MEM_REGION_SIZE_16, LOAD_ERRMODE); + } +} + +VOID __asan_loadN_noabort(UINTPTR p, UINT32 size) +{ + if (OsLmsCheckAddrRegion(p, size) != LOS_OK) { + OsLmsReportError(p, size, LOAD_ERRMODE); + } +} +#else +VOID __asan_load1_noabort(UINTPTR p) +{ + (VOID)p; +} + +VOID __asan_load2_noabort(UINTPTR p) +{ + (VOID)p; +} + +VOID __asan_load4_noabort(UINTPTR p) +{ + (VOID)p; +} + +VOID __asan_load8_noabort(UINTPTR p) +{ + (VOID)p; +} + +VOID __asan_load16_noabort(UINTPTR p) +{ + (VOID)p; +} + +VOID __asan_loadN_noabort(UINTPTR p, UINT32 size) +{ + (VOID)p; + (VOID)size; +} +#endif +VOID __asan_handle_no_return(VOID) +{ + return; +} + +LOS_MODULE_INIT(OsLmsInit, LOS_INIT_LEVEL_KMOD_PREVM); diff --git a/src/kernel_liteos_a/kernel/extended/lms/los_lms_pri.h b/src/kernel_liteos_a/kernel/extended/lms/los_lms_pri.h new file mode 100644 index 00000000..bb0cec13 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/lms/los_lms_pri.h @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_LMS_PRI_H +#define _LOS_LMS_PRI_H + +#include "los_lms.h" +#include "los_typedef.h" +#include "los_list.h" +#include "securec.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define COMMON_ERRMODE 3 +#define FREE_ERRORMODE 2 +#define STORE_ERRMODE 1 +#define LOAD_ERRMODE 0 + +#define SANITIZER_INTERFACE_ATTRIBUTE +#define ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address)) + +#define LMS_SHADOW_BITS_PER_CELL 2 +#define LMS_MEM_BYTES_PER_SHADOW_CELL 4 +#define LMS_SHADOW_U8_CELL_NUM 4 +#define LMS_SHADOW_U8_REFER_BYTES 16 + +#define LMS_POOL_RESIZE(size) ((size) / (LMS_SHADOW_U8_REFER_BYTES + 1) * LMS_SHADOW_U8_REFER_BYTES) +#define LMS_ADDR_ALIGN(p) (((UINTPTR)(p) + sizeof(UINTPTR) - 1) & ~((UINTPTR)(sizeof(UINTPTR) - 1))) + +#define LMS_SHADOW_ACCESSIBLE 0x00 +#define LMS_SHADOW_AFTERFREE 0x03 +#define LMS_SHADOW_REDZONE 0x02 +#define LMS_SHADOW_PAINT 0x01 +#define LMS_SHADOW_MASK 0x03 + +#define LMS_SHADOW_ACCESSIBLE_U8 0x00 +#define LMS_SHADOW_AFTERFREE_U8 0xFF +#define LMS_SHADOW_REDZONE_U8 0xAA +#define LMS_SHADOW_MASK_U8 0xFF +#define LMS_SHADOW_PAINT_U8 0x55 + +#define MEM_REGION_SIZE_1 1 +#define MEM_REGION_SIZE_2 2 +#define MEM_REGION_SIZE_4 4 +#define MEM_REGION_SIZE_8 8 +#define MEM_REGION_SIZE_16 16 + +typedef struct { + LOS_DL_LIST node; + UINT32 used; + UINTPTR poolAddr; + UINT32 poolSize; + UINTPTR shadowStart; + UINT32 shadowSize; +} LmsMemListNode; + +typedef struct { + UINTPTR memAddr; + UINTPTR shadowAddr; + UINT32 shadowOffset; + UINT32 shadowValue; +} LmsAddrInfo; + +typedef struct { + UINT32 (*init)(const VOID *pool, UINT32 size); + VOID (*deInit)(const VOID *pool); + VOID (*mallocMark)(const VOID *curNodeStart, const VOID *nextNodeStart, UINT32 nodeHeadSize); + VOID (*freeMark)(const VOID *curNodeStart, const VOID *nextNodeStart, UINT32 nodeHeadSize); + VOID (*simpleMark)(UINTPTR startAddr, UINTPTR endAddr, UINT32 value); + VOID (*check)(UINTPTR checkAddr, BOOL isFreeCheck); +} LmsHook; +extern LmsHook* g_lms; + +VOID OsLmsCheckValid(UINTPTR checkAddr, BOOL isFreeCheck); +VOID OsLmsLosMallocMark(const VOID *curNodeStart, const VOID *nextNodeStart, UINT32 nodeHeadSize); +VOID OsLmsLosFreeMark(const VOID *curNodeStart, const VOID *nextNodeStart, UINT32 nodeHeadSize); +VOID OsLmsSimpleMark(UINTPTR startAddr, UINTPTR endAddr, UINT32 value); + +VOID OsLmsPrintPoolListInfo(VOID); +VOID OsLmsReportError(UINTPTR p, UINT32 size, UINT32 errMod); + +VOID CheckValid(const CHAR *dest, const CHAR *src); + +extern SANITIZER_INTERFACE_ATTRIBUTE VOID __asan_store1_noabort(UINTPTR p); +extern SANITIZER_INTERFACE_ATTRIBUTE VOID __asan_store4_noabort(UINTPTR p); +extern SANITIZER_INTERFACE_ATTRIBUTE VOID __asan_load4_noabort(UINTPTR p); +extern SANITIZER_INTERFACE_ATTRIBUTE VOID __asan_load1_noabort(UINTPTR p); +extern SANITIZER_INTERFACE_ATTRIBUTE VOID __asan_loadN_noabort(UINTPTR p, UINT32 size); +extern SANITIZER_INTERFACE_ATTRIBUTE VOID __asan_storeN_noabort(UINTPTR p, UINT32 size); +extern SANITIZER_INTERFACE_ATTRIBUTE VOID __asan_store2_noabort(UINTPTR p); +extern SANITIZER_INTERFACE_ATTRIBUTE VOID __asan_load2_noabort(UINTPTR p); +extern SANITIZER_INTERFACE_ATTRIBUTE VOID __asan_store8_noabort(UINTPTR p); +extern SANITIZER_INTERFACE_ATTRIBUTE VOID __asan_load8_noabort(UINTPTR p); +extern SANITIZER_INTERFACE_ATTRIBUTE VOID __asan_load16_noabort(UINTPTR p); +extern SANITIZER_INTERFACE_ATTRIBUTE VOID __asan_store16_noabort(UINTPTR p); +extern SANITIZER_INTERFACE_ATTRIBUTE VOID __asan_handle_no_return(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_LMS_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/extended/lms/usr/BUILD.gn b/src/kernel_liteos_a/kernel/extended/lms/usr/BUILD.gn new file mode 100644 index 00000000..69433d1d --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/lms/usr/BUILD.gn @@ -0,0 +1,59 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//build/lite/config/component/lite_component.gni") + +copy("usrlmslib") { + deps = [ ":usrlms" ] + sources = [ get_path_info(".", "out_dir") + "/libusrlms.a" ] + outputs = [ "$root_out_dir/libusrlms.a" ] +} + +lite_library("usrlms") { + target_type = "static_library" + sources = [ + "los_lms.c", + "los_lmslibc.c", + ] + + include_dirs = [ "." ] + + cflags = [ + "-fPIC", + "-funwind-tables", + "-fasynchronous-unwind-tables", + ] + + ldflags = [ + "-rdynamic", + "-lunwind", + ] + + output_dir = target_out_dir +} diff --git a/src/kernel_liteos_a/kernel/extended/lms/usr/los_lms.c b/src/kernel_liteos_a/kernel/extended/lms/usr/los_lms.c new file mode 100644 index 00000000..3d0b5d0b --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/lms/usr/los_lms.c @@ -0,0 +1,486 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "los_lms_pri.h" +#include "debug.h" + +#define LMS_FREE_NODE_SIZE 16 + +struct MmapNode { + uintptr_t addr; + size_t mapSize; + struct MmapNode *next; +}; + +struct MmapNode g_freeNode[LMS_FREE_NODE_SIZE]; + +struct MmapNode *g_mmapNode = NULL; + +uint32_t g_shadowStartAddr = SHADOW_BASE; + +pthread_mutex_t g_lmsMutex = PTHREAD_MUTEX_INITIALIZER; + +ATTRIBUTE_NO_SANITIZE_ADDRESS void LmsMem2Shadow(uintptr_t memAddr, uintptr_t *shadowAddr, uint32_t *shadowOffset) +{ + uint32_t memOffset = memAddr - USPACE_MAP_BASE; + *shadowAddr = g_shadowStartAddr + memOffset / LMS_SHADOW_U8_REFER_BYTES; + *shadowOffset = ((memOffset % LMS_SHADOW_U8_REFER_BYTES) / LMS_SHADOW_U8_CELL_NUM) * LMS_SHADOW_BITS_PER_CELL; +} + +ATTRIBUTE_NO_SANITIZE_ADDRESS uint32_t LmsIsShadowAddrMapped(uintptr_t sdStartAddr, uintptr_t sdEndAddr) +{ + struct MmapNode *node = g_mmapNode; + while (node != NULL) { + if ((sdStartAddr >= node->addr) && (sdEndAddr < node->addr + node->mapSize)) { + return LMS_OK; + } + node = node->next; + } + return LMS_NOK; +} + +ATTRIBUTE_NO_SANITIZE_ADDRESS void LmsAddMapNode(uintptr_t sdStartAddr, uintptr_t sdEndAddr) +{ + static uint32_t freeNodeIdx = 0; + struct MmapNode *node = g_mmapNode; + size_t mapSize; + uintptr_t shadowPageStartAddr = LMS_MEM_ALIGN_DOWN(sdStartAddr, 0x1000); + uintptr_t shadowPageEndAddr = LMS_MEM_ALIGN_UP(sdEndAddr, 0x1000); + + struct MmapNode *expandNode = NULL; + + while (node != NULL) { + if ((shadowPageStartAddr >= node->addr) && (shadowPageStartAddr <= node->addr + node->mapSize)) { + expandNode = node; + break; + } + node = node->next; + } + + if (expandNode != NULL) { + shadowPageStartAddr = expandNode->addr + expandNode->mapSize; + expandNode->mapSize = shadowPageEndAddr - expandNode->addr; + } + + mapSize = shadowPageEndAddr - shadowPageStartAddr; + void *mapPtr = + mmap((void *)shadowPageStartAddr, mapSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (mapPtr == (void *)-1) { + LMS_OUTPUT_INFO("mmap error! file:%s line:%d\n", __FILE__, __LINE__); + return; + } + __real_memset(mapPtr, 0, mapSize); + + if (expandNode != NULL) { + return; + } + + if (freeNodeIdx >= LMS_FREE_NODE_SIZE) { + LMS_OUTPUT_INFO("Add new mmap node error! file:%s line:%d\n", __FILE__, __LINE__); + return; + } + + struct MmapNode *newNode = &g_freeNode[freeNodeIdx]; + freeNodeIdx++; + newNode->addr = shadowPageStartAddr; + newNode->mapSize = mapSize; + newNode->next = g_mmapNode; + g_mmapNode = newNode; +} + +ATTRIBUTE_NO_SANITIZE_ADDRESS void LmsSetShadowValue(uintptr_t startAddr, uintptr_t endAddr, char value) +{ + uintptr_t shadowStart; + uintptr_t shadowEnd; + uint32_t startOffset; + uint32_t endOffset; + + unsigned char shadowValueMask; + unsigned char shadowValue; + + /* endAddr - 1, then we mark [startAddr, endAddr) to value */ + LmsMem2Shadow(startAddr, &shadowStart, &startOffset); + LmsMem2Shadow(endAddr - 1, &shadowEnd, &endOffset); + + if (shadowStart == shadowEnd) { /* in the same u8 */ + /* because endAddr - 1, the endOffset falls into the previous cell, + so endOffset + 2 is required for calculation */ + shadowValueMask = LMS_SHADOW_MASK_U8; + shadowValueMask = + (shadowValueMask << startOffset) & (~(shadowValueMask << (endOffset + LMS_SHADOW_BITS_PER_CELL))); + shadowValue = value & shadowValueMask; + *(char *)shadowStart &= ~shadowValueMask; + *(char *)shadowStart |= shadowValue; + } else { + /* Adjust startAddr to left util it reach the beginning of a u8 */ + if (startOffset > 0) { + shadowValueMask = LMS_SHADOW_MASK_U8; + shadowValueMask = shadowValueMask << startOffset; + shadowValue = value & shadowValueMask; + *(char *)shadowStart &= ~shadowValueMask; + *(char *)shadowStart |= shadowValue; + shadowStart += 1; + } + + /* Adjust endAddr to right util it reach the end of a u8 */ + if (endOffset < (LMS_SHADOW_U8_CELL_NUM - 1) * LMS_SHADOW_BITS_PER_CELL) { + shadowValueMask = LMS_SHADOW_MASK_U8; + shadowValueMask &= ~(shadowValueMask << (endOffset + LMS_SHADOW_BITS_PER_CELL)); + shadowValue = value & shadowValueMask; + *(char *)shadowEnd &= ~shadowValueMask; + *(char *)shadowEnd |= shadowValue; + shadowEnd -= 1; + } + + if (shadowEnd + 1 > shadowStart) { + (void)__real_memset((void *)shadowStart, value & LMS_SHADOW_MASK_U8, shadowEnd + 1 - shadowStart); + } + } +} + +ATTRIBUTE_NO_SANITIZE_ADDRESS void LmsGetShadowValue(uintptr_t addr, uint32_t *shadowValue) +{ + uintptr_t shadowAddr; + uint32_t shadowOffset; + LmsMem2Shadow(addr, &shadowAddr, &shadowOffset); + /* If the shadow addr is not mapped then regarded as legal access */ + if (LmsIsShadowAddrMapped(shadowAddr, shadowAddr) != LMS_OK) { + *shadowValue = LMS_SHADOW_ACCESSIBLE_U8; + return; + } + + *shadowValue = ((*(char *)shadowAddr) >> shadowOffset) & LMS_SHADOW_MASK; +} + +ATTRIBUTE_NO_SANITIZE_ADDRESS void LmsMallocMark(uintptr_t preRzStart, uintptr_t accessMemStart, uintptr_t nextRzStart, + uintptr_t RzEndAddr) +{ + LmsSetShadowValue(preRzStart, accessMemStart, LMS_SHADOW_REDZONE_U8); + LmsSetShadowValue(accessMemStart, nextRzStart, LMS_SHADOW_ACCESSIBLE_U8); + LmsSetShadowValue(nextRzStart, RzEndAddr, LMS_SHADOW_REDZONE_U8); +} + +ATTRIBUTE_NO_SANITIZE_ADDRESS void *LmsTagMem(void *ptr, size_t origSize) +{ + g_shadowStartAddr = SHADOW_BASE; + size_t mSize = malloc_usable_size(ptr); + uint32_t memOffset = (uintptr_t)ptr + mSize + OVERHEAD - USPACE_MAP_BASE; + uintptr_t shadowEndAddr = g_shadowStartAddr + memOffset / LMS_SHADOW_U8_REFER_BYTES; + LMS_OUTPUT_INFO("SHADOW_BASE:%x g_shadowStartAddr:%x memOffset: %x\n", SHADOW_BASE, g_shadowStartAddr, memOffset); + memOffset = (uintptr_t)ptr - OVERHEAD - USPACE_MAP_BASE; + uintptr_t shadowStartAddr = g_shadowStartAddr + memOffset / LMS_SHADOW_U8_REFER_BYTES; + + LmsLock(&g_lmsMutex); + if (LmsIsShadowAddrMapped(shadowStartAddr, shadowEndAddr) != LMS_OK) { + LmsAddMapNode(shadowStartAddr, shadowEndAddr); + } + + LmsMallocMark((uintptr_t)ptr - OVERHEAD, (uintptr_t)ptr, (uintptr_t)ptr + LMS_MEM_ALIGN_UP(origSize, LMS_RZ_SIZE), + (uintptr_t)((uintptr_t)ptr + mSize + OVERHEAD)); + LmsUnlock(&g_lmsMutex); + + return ptr; +} + +ATTRIBUTE_NO_SANITIZE_ADDRESS uint32_t LmsCheckAddr(uintptr_t addr) +{ + LmsLock(&g_lmsMutex); + uint32_t shadowValue = -1; + LmsGetShadowValue(addr, &shadowValue); + LmsUnlock(&g_lmsMutex); + return shadowValue; +} + +ATTRIBUTE_NO_SANITIZE_ADDRESS uint32_t LmsCheckAddrRegion(uintptr_t addr, size_t size) +{ + if (LmsCheckAddr(addr) || LmsCheckAddr(addr + size - 1)) { + return LMS_NOK; + } else { + return LMS_OK; + } +} + +ATTRIBUTE_NO_SANITIZE_ADDRESS void LmsPrintMemInfo(uintptr_t addr) +{ +#define LMS_DUMP_OFFSET 4 +#define LMS_DUMP_RANGE_DOUBLE 2 + + LMS_OUTPUT_INFO("\nDump info around address [0x%8x]:\n", addr); + uint32_t printY = LMS_DUMP_OFFSET * LMS_DUMP_RANGE_DOUBLE + 1; + uint32_t printX = LMS_MEM_BYTES_PER_SHADOW_CELL * LMS_DUMP_RANGE_DOUBLE; + uintptr_t dumpAddr = addr - addr % printX - LMS_DUMP_OFFSET * printX; + uint32_t shadowValue = 0; + uintptr_t shadowAddr = 0; + uint32_t shadowOffset = 0; + int isCheckAddr; + + for (int y = 0; y < printY; y++, dumpAddr += printX) { + LmsMem2Shadow(dumpAddr, &shadowAddr, &shadowOffset); + /* find util dumpAddr in pool region */ + if (LmsIsShadowAddrMapped(shadowAddr, shadowAddr) != LMS_OK) { + continue; + } + uintptr_t maxShadowAddr; + uint32_t maxShadowOffset; + LmsMem2Shadow(dumpAddr + printX, &maxShadowAddr, &maxShadowOffset); + /* finish if dumpAddr exceeds pool's upper region */ + if (LmsIsShadowAddrMapped(maxShadowAddr, maxShadowAddr) != LMS_OK) { + goto END; + } + + LMS_OUTPUT_INFO("\n\t[0x%x]: ", dumpAddr); + for (int x = 0; x < printX; x++) { + if (dumpAddr + x == addr) { + LMS_OUTPUT_INFO("[%02x]", *(uint8_t *)(dumpAddr + x)); + } else { + LMS_OUTPUT_INFO(" %02x ", *(uint8_t *)(dumpAddr + x)); + } + } + + LMS_OUTPUT_INFO("|\t[0x%x | %2u]: ", shadowAddr, shadowOffset); + + for (int x = 0; x < printX; x += LMS_MEM_BYTES_PER_SHADOW_CELL) { + LmsGetShadowValue(dumpAddr + x, &shadowValue); + isCheckAddr = dumpAddr + x - (uintptr_t)addr + LMS_MEM_BYTES_PER_SHADOW_CELL; + if (isCheckAddr > 0 && isCheckAddr <= LMS_MEM_BYTES_PER_SHADOW_CELL) { + LMS_OUTPUT_INFO("[%1x]", shadowValue); + } else { + LMS_OUTPUT_INFO(" %1x ", shadowValue); + } + } + } +END: + LMS_OUTPUT_INFO("\n"); +} + +ATTRIBUTE_NO_SANITIZE_ADDRESS static inline void LmsGetShadowInfo(uintptr_t memAddr, LmsAddrInfo *info) +{ + uintptr_t shadowAddr; + uint32_t shadowOffset; + uint32_t shadowValue; + + LmsMem2Shadow(memAddr, &shadowAddr, &shadowOffset); + + shadowValue = ((*(char *)shadowAddr) >> shadowOffset) & LMS_SHADOW_MASK; + info->memAddr = memAddr; + info->shadowAddr = shadowAddr; + info->shadowOffset = shadowOffset; + info->shadowValue = shadowValue; +} + +ATTRIBUTE_NO_SANITIZE_ADDRESS static void LmsGetErrorInfo(uintptr_t addr, size_t size, LmsAddrInfo *info) +{ + LmsGetShadowInfo(addr, info); + if (info->shadowValue != LMS_SHADOW_ACCESSIBLE_U8) { + return; + } else { + LmsGetShadowInfo(addr + size - 1, info); + } +} + +ATTRIBUTE_NO_SANITIZE_ADDRESS static void LmsPrintErrInfo(LmsAddrInfo *info, uint32_t errMod) +{ + switch (info->shadowValue) { + case LMS_SHADOW_AFTERFREE: + LMS_OUTPUT_ERROR("Use after free error detected!\n"); + break; + case LMS_SHADOW_REDZONE: + LMS_OUTPUT_ERROR("Heap buffer overflow error detected!\n"); + break; + case LMS_SHADOW_ACCESSIBLE: + LMS_OUTPUT_ERROR("No error!\n"); + break; + default: + LMS_OUTPUT_ERROR("UnKnown Error detected!\n"); + break; + } + + switch (errMod) { + case FREE_ERRORMODE: + LMS_OUTPUT_ERROR("Illegal Double free address at: [0x%x]\n", info->memAddr); + break; + case LOAD_ERRMODE: + LMS_OUTPUT_ERROR("Illegal READ address at: [0x%x]\n", info->memAddr); + break; + case STORE_ERRMODE: + LMS_OUTPUT_ERROR("Illegal WRITE address at: [0x%x]\n", info->memAddr); + break; + default: + LMS_OUTPUT_ERROR("UnKnown Error mode at: [0x%x]\n", info->memAddr); + break; + } + + LMS_OUTPUT_INFO("Shadow memory address: [0x%x : %u] Shadow memory value: [%u] \n", info->shadowAddr, + info->shadowOffset, info->shadowValue); + + LMS_OUTPUT_INFO("\n"); + LMS_OUTPUT_INFO("%-25s%d\n", "Accessible heap addr", LMS_SHADOW_ACCESSIBLE); + LMS_OUTPUT_INFO("%-25s%d\n", "Heap red zone", LMS_SHADOW_REDZONE); + LMS_OUTPUT_INFO("%-25s%d\n", "Heap freed buffer", LMS_SHADOW_AFTERFREE); + LMS_OUTPUT_INFO("\n"); +} + +ATTRIBUTE_NO_SANITIZE_ADDRESS void LmsReportError(uintptr_t p, size_t size, uint32_t errMod) +{ + LmsAddrInfo info; + (void)__real_memset(&info, 0, sizeof(LmsAddrInfo)); + + int locked = LmsTrylock(&g_lmsMutex); + LMS_OUTPUT_ERROR("\n***** Lite Memory Sanitizer Error Detected *****\n"); + LmsGetErrorInfo(p, size, &info); + LmsPrintErrInfo(&info, errMod); + LmsPrintMemInfo(info.memAddr); + LMS_OUTPUT_ERROR("***** Lite Memory Sanitizer Error Detected End *****\n"); + if (!locked) { + LmsUnlock(&g_lmsMutex); + } + + if (LMS_CRASH_MODE > 0) { + LmsCrash(); + } else { + print_trace(); + } +} + +void LmsCheckValid(const char *dest, const char *src) +{ + if (LmsCheckAddr((uintptr_t)dest) != LMS_SHADOW_ACCESSIBLE_U8) { + LmsReportError((uintptr_t)dest, MEM_REGION_SIZE_1, STORE_ERRMODE); + return; + } + + if (LmsCheckAddr((uintptr_t)src) != LMS_SHADOW_ACCESSIBLE_U8) { + LmsReportError((uintptr_t)src, MEM_REGION_SIZE_1, LOAD_ERRMODE); + return; + } + + for (uint32_t i = 0; *(src + i) != '\0'; i++) { + if (LmsCheckAddr((uintptr_t)dest + i + 1) != LMS_SHADOW_ACCESSIBLE_U8) { + LmsReportError((uintptr_t)dest + i + 1, MEM_REGION_SIZE_1, STORE_ERRMODE); + return; + } + + if (LmsCheckAddr((uintptr_t)src + i + 1) != LMS_SHADOW_ACCESSIBLE_U8) { + LmsReportError((uintptr_t)src + i + 1, MEM_REGION_SIZE_1, LOAD_ERRMODE); + return; + } + } +} + +void __asan_store1_noabort(uintptr_t p) +{ + if (LmsCheckAddr(p) != LMS_SHADOW_ACCESSIBLE_U8) { + LmsReportError(p, MEM_REGION_SIZE_1, STORE_ERRMODE); + } +} + +void __asan_store2_noabort(uintptr_t p) +{ + if (LmsCheckAddrRegion(p, MEM_REGION_SIZE_2) != LMS_OK) { + LmsReportError(p, MEM_REGION_SIZE_2, STORE_ERRMODE); + } +} + +void __asan_store4_noabort(uintptr_t p) +{ + if (LmsCheckAddrRegion(p, MEM_REGION_SIZE_4) != LMS_OK) { + LmsReportError(p, MEM_REGION_SIZE_4, STORE_ERRMODE); + } +} + +void __asan_store8_noabort(uintptr_t p) +{ + if (LmsCheckAddrRegion(p, MEM_REGION_SIZE_8) != LMS_OK) { + LmsReportError(p, MEM_REGION_SIZE_8, STORE_ERRMODE); + } +} + +void __asan_store16_noabort(uintptr_t p) +{ + if (LmsCheckAddrRegion(p, MEM_REGION_SIZE_16) != LMS_OK) { /* 16 byte memory for check */ + LmsReportError(p, MEM_REGION_SIZE_16, STORE_ERRMODE); + } +} + +void __asan_storeN_noabort(uintptr_t p, size_t size) +{ + if (LmsCheckAddrRegion(p, size) != LMS_OK) { + LmsReportError(p, size, STORE_ERRMODE); + } +} + +void __asan_load1_noabort(uintptr_t p) +{ + if (LmsCheckAddr(p) != LMS_SHADOW_ACCESSIBLE_U8) { + LmsReportError(p, MEM_REGION_SIZE_1, LOAD_ERRMODE); + } +} + +void __asan_load2_noabort(uintptr_t p) +{ + if (LmsCheckAddrRegion(p, MEM_REGION_SIZE_2) != LMS_OK) { + LmsReportError(p, MEM_REGION_SIZE_2, LOAD_ERRMODE); + } +} + +void __asan_load4_noabort(uintptr_t p) +{ + if (LmsCheckAddrRegion(p, MEM_REGION_SIZE_4) != LMS_OK) { + LmsReportError(p, MEM_REGION_SIZE_4, LOAD_ERRMODE); + } +} + +void __asan_load8_noabort(uintptr_t p) +{ + if (LmsCheckAddrRegion(p, MEM_REGION_SIZE_8) != LMS_OK) { + LmsReportError(p, MEM_REGION_SIZE_8, LOAD_ERRMODE); + } +} + +void __asan_load16_noabort(uintptr_t p) +{ + if (LmsCheckAddrRegion(p, MEM_REGION_SIZE_16) != LMS_OK) { + LmsReportError(p, MEM_REGION_SIZE_16, LOAD_ERRMODE); + } +} + +void __asan_loadN_noabort(uintptr_t p, size_t size) +{ + if (LmsCheckAddrRegion(p, size) != LMS_OK) { + LmsReportError(p, size, LOAD_ERRMODE); + } +} + +void __asan_handle_no_return(void) +{ + return; +} \ No newline at end of file diff --git a/src/kernel_liteos_a/kernel/extended/lms/usr/los_lms.h b/src/kernel_liteos_a/kernel/extended/lms/usr/los_lms.h new file mode 100644 index 00000000..5296d8a3 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/lms/usr/los_lms.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_LMS_H +#define _LOS_LMS_H + +#include +#include +#include + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/* + * If LMS_CRASH_MODE == 0 + * the program would NOT be crashed once the sanitizer detected an error. + * If LMS_CRASM_MODE > 0 + * the program would be crashed once the sanitizer detected an error. + */ +#define LMS_CRASH_MODE 0 + +/* + * USPACE_MAP_BASE + * is the start address of user space. + */ +#define USPACE_MAP_BASE 0x00000000 + +/* + * USPACE_MAP_SIZE + * is the address size of the user space, and [USPACE_MAP_BASE, USPACE_MAP_BASE + USPACE_MAP_SIZE] + * must cover the HEAP section. + */ +#define USPACE_MAP_SIZE 0x3ef00000 + +/* + * LMS_OUTPUT_ERROR can be redefined to redirect output logs. + */ +#ifndef LMS_OUTPUT_ERROR +#define LMS_OUTPUT_ERROR(fmt, ...) \ + do { \ + (printf("\033[31;1m"), printf(fmt, ##__VA_ARGS__), printf("\033[0m")); \ + } while (0) +#endif + +/* + * LMS_OUTPUT_INFO can be redefined to redirect output logs. + */ +#ifndef LMS_OUTPUT_INFO +#define LMS_OUTPUT_INFO(fmt, ...) \ + do { \ + (printf("\033[33;1m"), printf(fmt, ##__VA_ARGS__), printf("\033[0m")); \ + } while (0) +#endif + + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_LMS_H */ \ No newline at end of file diff --git a/src/kernel_liteos_a/kernel/extended/lms/usr/los_lms_pri.h b/src/kernel_liteos_a/kernel/extended/lms/usr/los_lms_pri.h new file mode 100644 index 00000000..012c0dc6 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/lms/usr/los_lms_pri.h @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_LMS_PRI_H +#define _LOS_LMS_PRI_H + +#include +#include +#include "los_lms.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define UNKNOWN_ERROR 3 +#define FREE_ERRORMODE 2 +#define STORE_ERRMODE 1 +#define LOAD_ERRMODE 0 + +#define SANITIZER_INTERFACE_ATTRIBUTE +#define ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address)) + +#define LMS_SHADOW_ACCESSIBLE 0x00 +#define LMS_SHADOW_AFTERFREE 0x03 +#define LMS_SHADOW_REDZONE 0x02 +#define LMS_SHADOW_PAINT 0x01 +#define LMS_SHADOW_MASK 0x03 + +#define LMS_SHADOW_BITS_PER_CELL 2 +#define LMS_MEM_BYTES_PER_SHADOW_CELL 4 +#define LMS_SHADOW_U8_CELL_NUM 4 +#define LMS_SHADOW_U8_REFER_BYTES 16 + +#define LMS_SHADOW_ACCESSIBLE_U8 0x00 +#define LMS_SHADOW_AFTERFREE_U8 0xFF +#define LMS_SHADOW_REDZONE_U8 0xAA +#define LMS_SHADOW_MASK_U8 0xFF +#define LMS_SHADOW_PAINT_U8 0x55 + +#define MEM_REGION_SIZE_1 1 +#define MEM_REGION_SIZE_2 2 +#define MEM_REGION_SIZE_4 4 +#define MEM_REGION_SIZE_8 8 +#define MEM_REGION_SIZE_16 16 + +#define LMS_RZ_SIZE 4 +#define LMS_OK 0 +#define LMS_NOK 1 + +#define PAGE_ADDR_MASK 0xFFFFE000 +#define SHADOW_BASE \ + ((USPACE_MAP_BASE + (USPACE_MAP_SIZE / (LMS_SHADOW_U8_REFER_BYTES + 1)) * LMS_SHADOW_U8_REFER_BYTES) & \ + PAGE_ADDR_MASK) +#define OVERHEAD (2 * sizeof(size_t)) + +#define LMS_MEM_ALIGN_DOWN(value, align) (((uint32_t)(value)) & ~((uint32_t)((align) - 1))) +#define LMS_MEM_ALIGN_UP(value, align) (((uint32_t)(value) + ((align) - 1)) & ~((uint32_t)((align) - 1))) + +typedef struct { + uintptr_t memAddr; + uintptr_t shadowAddr; + uint32_t shadowOffset; + uint32_t shadowValue; +} LmsAddrInfo; + +extern pthread_mutex_t g_lmsMutex; + +ATTRIBUTE_NO_SANITIZE_ADDRESS static inline void LmsLock(pthread_mutex_t *lock) +{ + (void)pthread_mutex_lock(lock); +} + +ATTRIBUTE_NO_SANITIZE_ADDRESS static inline int LmsTrylock(pthread_mutex_t *lock) +{ + return pthread_mutex_trylock(lock); +} + +ATTRIBUTE_NO_SANITIZE_ADDRESS static inline void LmsUnlock(pthread_mutex_t *lock) +{ + (void)pthread_mutex_unlock(lock); +} + +ATTRIBUTE_NO_SANITIZE_ADDRESS static inline void LmsCrash(void) +{ + *(volatile char *)(SHADOW_BASE - 1) = 0; +} + +uint32_t LmsIsShadowAddrMapped(uintptr_t sdStartAddr, uintptr_t sdEndAddr); + +void LmsSetShadowValue(uintptr_t startAddr, uintptr_t endAddr, char value); + +void LmsGetShadowValue(uintptr_t addr, uint32_t *shadowValue); + +void LmsReportError(uintptr_t p, size_t size, uint32_t errMod); + +void LmsMem2Shadow(uintptr_t memAddr, uintptr_t *shadowAddr, uint32_t *shadowOffset); + +void LmsCheckValid(const char *dest, const char *src); + +void *__real_malloc(size_t); + +void __real_free(void *); + +void *__real_calloc(size_t, size_t); + +void *__real_realloc(void *, size_t); + +void *__real_valloc(size_t); + +void *__real_aligned_alloc(size_t, size_t); + +void *__real_memcpy(void *__restrict, const void *__restrict, size_t); + +void *__real_memmove(void *, const void *, size_t); + +char *__real_strcat(char *, const char *); + +char *__real_strcpy(char *, const char *); + +void *__real_memset(void *, int, size_t); + +SANITIZER_INTERFACE_ATTRIBUTE void __asan_store1_noabort(uintptr_t p); +SANITIZER_INTERFACE_ATTRIBUTE void __asan_store4_noabort(uintptr_t p); +SANITIZER_INTERFACE_ATTRIBUTE void __asan_load4_noabort(uintptr_t p); +SANITIZER_INTERFACE_ATTRIBUTE void __asan_load1_noabort(uintptr_t p); +SANITIZER_INTERFACE_ATTRIBUTE void __asan_loadN_noabort(uintptr_t p, uint32_t size); +SANITIZER_INTERFACE_ATTRIBUTE void __asan_storeN_noabort(uintptr_t p, uint32_t size); +SANITIZER_INTERFACE_ATTRIBUTE void __asan_store2_noabort(uintptr_t p); +SANITIZER_INTERFACE_ATTRIBUTE void __asan_load2_noabort(uintptr_t p); +SANITIZER_INTERFACE_ATTRIBUTE void __asan_store8_noabort(uintptr_t p); +SANITIZER_INTERFACE_ATTRIBUTE void __asan_load8_noabort(uintptr_t p); +SANITIZER_INTERFACE_ATTRIBUTE void __asan_load16_noabort(uintptr_t p); +SANITIZER_INTERFACE_ATTRIBUTE void __asan_store16_noabort(uintptr_t p); +SANITIZER_INTERFACE_ATTRIBUTE void __asan_handle_no_return(void); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_LMS_PRI_H */ \ No newline at end of file diff --git a/src/kernel_liteos_a/kernel/extended/lms/usr/los_lmslibc.c b/src/kernel_liteos_a/kernel/extended/lms/usr/los_lmslibc.c new file mode 100644 index 00000000..9fea4dc7 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/lms/usr/los_lmslibc.c @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_lms_pri.h" + +ATTRIBUTE_NO_SANITIZE_ADDRESS void LmsFree(void *ptr) +{ + if (ptr == NULL) { + return; + } + + size_t allocSize = malloc_usable_size(ptr); + uintptr_t shadowAddr, offset; + LmsMem2Shadow((uintptr_t)ptr, &shadowAddr, &offset); + + LmsLock(&g_lmsMutex); + if (LmsIsShadowAddrMapped(shadowAddr, shadowAddr) == LMS_OK) { + uint32_t acShadowValue; + LmsGetShadowValue((uintptr_t)ptr, &acShadowValue); + if (acShadowValue != LMS_SHADOW_ACCESSIBLE) { + char erroMode = (acShadowValue == LMS_SHADOW_AFTERFREE ? FREE_ERRORMODE : UNKNOWN_ERROR); + LmsReportError((uintptr_t)ptr, MEM_REGION_SIZE_1, erroMode); + goto UNLOCK_OUT; + } + } else { + LMS_OUTPUT_ERROR("Error! Free an unallocated memory:%p!\n", ptr); + goto UNLOCK_OUT; + } + + __real_free(ptr); + LmsSetShadowValue((uintptr_t)ptr, (uintptr_t)ptr + allocSize, LMS_SHADOW_AFTERFREE_U8); + +UNLOCK_OUT: + LmsUnlock(&g_lmsMutex); +} + +ATTRIBUTE_NO_SANITIZE_ADDRESS void *LmsMalloc(size_t size) +{ + void *ptr = __real_malloc(size); + if (ptr == NULL) { + return ptr; + } + return LmsTagMem(ptr, size); +} + +ATTRIBUTE_NO_SANITIZE_ADDRESS void *LmsRealloc(void *ptr, size_t size) +{ + void *p = __real_realloc(ptr, size); + if (p == NULL) { + return p; + } + return LmsTagMem(p, size); +} + +ATTRIBUTE_NO_SANITIZE_ADDRESS void *LmsCalloc(size_t m, size_t n) +{ + void *p = __real_calloc(m, n); + if (p == NULL) { + return p; + } + return LmsTagMem(p, n * m); +} + +ATTRIBUTE_NO_SANITIZE_ADDRESS void *LmsValloc(size_t size) +{ + void *p = __real_valloc(size); + if (p == NULL) { + return p; + } + return LmsTagMem(p, size); +} + +ATTRIBUTE_NO_SANITIZE_ADDRESS void *LmsAlignedAlloc(size_t align, size_t len) +{ + void *p = __real_aligned_alloc(align, len); + if (p == NULL) { + return p; + } + return LmsTagMem(p, len); +} + +ATTRIBUTE_NO_SANITIZE_ADDRESS void *__wrap_aligned_alloc(size_t align, size_t len) +{ + return LmsAlignedAlloc(align, len); +} + +ATTRIBUTE_NO_SANITIZE_ADDRESS void *__wrap_valloc(size_t size) +{ + return LmsValloc(size); +} + +ATTRIBUTE_NO_SANITIZE_ADDRESS void *__wrap_calloc(size_t m, size_t n) +{ + return LmsCalloc(m, n); +} + +ATTRIBUTE_NO_SANITIZE_ADDRESS void *__wrap_realloc(void *p, size_t n) +{ + return LmsRealloc(p, n); +} + +ATTRIBUTE_NO_SANITIZE_ADDRESS void *__wrap_malloc(size_t size) +{ + return LmsMalloc(size); +} + +ATTRIBUTE_NO_SANITIZE_ADDRESS void __wrap_free(void *ptr) +{ + return LmsFree(ptr); +} + +ATTRIBUTE_NO_SANITIZE_ADDRESS void *LmsMemset(void *p, int n, size_t size) +{ + __asan_storeN_noabort((uintptr_t)p, size); + + return __real_memset(p, n, size); +} + +ATTRIBUTE_NO_SANITIZE_ADDRESS void *__wrap_memset(void *p, int n, size_t size) +{ + return LmsMemset(p, n, size); +} + +ATTRIBUTE_NO_SANITIZE_ADDRESS void *LmsMemcpy(void *__restrict dest, const void *__restrict src, size_t size) +{ + __asan_loadN_noabort((uintptr_t)src, size); + __asan_storeN_noabort((uintptr_t)dest, size); + + return __real_memcpy(dest, src, size); +} + +ATTRIBUTE_NO_SANITIZE_ADDRESS void *__wrap_memcpy(void *__restrict dest, const void *__restrict src, size_t size) +{ + return LmsMemcpy(dest, src, size); +} + +ATTRIBUTE_NO_SANITIZE_ADDRESS void *LmsMemmove(void *dest, const void *src, size_t len) +{ + __asan_loadN_noabort((uintptr_t)src, len); + __asan_storeN_noabort((uintptr_t)dest, len); + + return __real_memmove(dest, src, len); +} + +ATTRIBUTE_NO_SANITIZE_ADDRESS void *__wrap_memmove(void *dest, const void *src, size_t len) +{ + return LmsMemmove(dest, src, len); +} + +ATTRIBUTE_NO_SANITIZE_ADDRESS char *LmsStrcat(char *s, const char *append) +{ + if ((s == NULL) || (append == NULL)) { + return NULL; + } + + char *save = s; + for (; *s != '\0'; ++s) { + } + LmsCheckValid(s, append); + + return __real_strcat(save, append); +} + +ATTRIBUTE_NO_SANITIZE_ADDRESS char *__wrap_strcat(char *s, const char *append) +{ + return LmsStrcat(s, append); +} + +ATTRIBUTE_NO_SANITIZE_ADDRESS char *LmsStrcpy(char *dest, const char *src) +{ + if ((dest == NULL) || (src == NULL)) { + return NULL; + } + + LmsCheckValid(dest, src); + return __real_strcpy(dest, src); +} + +ATTRIBUTE_NO_SANITIZE_ADDRESS char *__wrap_strcpy(char *dest, const char *src) +{ + return LmsStrcpy(dest, src); +} \ No newline at end of file diff --git a/src/kernel_liteos_a/kernel/extended/perf/BUILD.gn b/src/kernel_liteos_a/kernel/extended/perf/BUILD.gn new file mode 100644 index 00000000..d5011834 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/perf/BUILD.gn @@ -0,0 +1,56 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = defined(LOSCFG_KERNEL_PERF) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ + "los_perf.c", + "perf_output.c", + "perf_pmu.c", + ] + + if (defined(LOSCFG_PERF_HW_PMU)) { + sources += [ "pmu/perf_hw_pmu.c" ] + } + + if (defined(LOSCFG_PERF_TIMED_PMU)) { + sources += [ "pmu/perf_timed_pmu.c" ] + } + + if (defined(LOSCFG_PERF_SW_PMU)) { + sources += [ "pmu/perf_sw_pmu.c" ] + } +} + +config("public") { + include_dirs = [ "." ] +} diff --git a/src/kernel_liteos_a/kernel/extended/perf/Kconfig b/src/kernel_liteos_a/kernel/extended/perf/Kconfig new file mode 100644 index 00000000..2860f078 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/perf/Kconfig @@ -0,0 +1,38 @@ +config KERNEL_PERF + bool "Enable Perf Feature" + default n + depends on KERNEL_EXTKERNEL + select KERNEL_SMP_CALL if KERNEL_SMP + help + If you wish to build LiteOS with support for perf. + +choice + prompt "Time-consuming Calc Methods" + depends on KERNEL_PERF + +config PERF_CALC_TIME_BY_TICK + bool "By Tick" + +config PERF_CALC_TIME_BY_CYCLE + bool "By Cpu Cycle" +endchoice + +config PERF_BUFFER_SIZE + int "Perf Sampling Buffer Size" + default 20480 + depends on KERNEL_PERF + +config PERF_HW_PMU + bool "Enable Hardware Pmu Events for Sampling" + default n + depends on KERNEL_PERF + +config PERF_TIMED_PMU + bool "Enable Hrtimer Period Events for Sampling" + default n + depends on KERNEL_PERF && HRTIMER_ENABLE + +config PERF_SW_PMU + bool "Enable Software Events for Sampling" + default y + depends on KERNEL_PERF && KERNEL_HOOK \ No newline at end of file diff --git a/src/kernel_liteos_a/kernel/extended/perf/Makefile b/src/kernel_liteos_a/kernel/extended/perf/Makefile new file mode 100644 index 00000000..a7bce008 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/perf/Makefile @@ -0,0 +1,22 @@ +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := $(wildcard *.c) + +ifeq ($(LOSCFG_PERF_HW_PMU), y) +LOCAL_SRCS += $(wildcard pmu/perf_hw_pmu.c) +endif + +ifeq ($(LOSCFG_PERF_TIMED_PMU), y) +LOCAL_SRCS += $(wildcard pmu/perf_timed_pmu.c) +endif + +ifeq ($(LOSCFG_PERF_SW_PMU), y) +LOCAL_SRCS += $(wildcard pmu/perf_sw_pmu.c) +endif + +LOCAL_FLAGS := $(LOCAL_INCLUDE) + +include $(MODULE) + diff --git a/src/kernel_liteos_a/kernel/extended/perf/los_perf.c b/src/kernel_liteos_a/kernel/extended/perf/los_perf.c new file mode 100644 index 00000000..ecb2644c --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/perf/los_perf.c @@ -0,0 +1,544 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_perf_pri.h" +#include "perf_pmu_pri.h" +#include "perf_output_pri.h" +#include "los_init.h" +#include "los_process.h" +#include "los_tick.h" +#include "los_sys.h" +#include "los_spinlock.h" + +STATIC Pmu *g_pmu = NULL; +STATIC PerfCB g_perfCb = {0}; + +LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_perfSpin); +#define PERF_LOCK(state) LOS_SpinLockSave(&g_perfSpin, &(state)) +#define PERF_UNLOCK(state) LOS_SpinUnlockRestore(&g_perfSpin, (state)) + +#define MIN(x, y) ((x) < (y) ? (x) : (y)) + +STATIC INLINE UINT64 OsPerfGetCurrTime(VOID) +{ +#ifdef LOSCFG_PERF_CALC_TIME_BY_TICK + return LOS_TickCountGet(); +#else + return HalClockGetCycles(); +#endif +} + +STATIC UINT32 OsPmuInit(VOID) +{ +#ifdef LOSCFG_PERF_HW_PMU + if (OsHwPmuInit() != LOS_OK) { + return LOS_ERRNO_PERF_HW_INIT_ERROR; + } +#endif + +#ifdef LOSCFG_PERF_TIMED_PMU + if (OsTimedPmuInit() != LOS_OK) { + return LOS_ERRNO_PERF_TIMED_INIT_ERROR; + } +#endif + +#ifdef LOSCFG_PERF_SW_PMU + if (OsSwPmuInit() != LOS_OK) { + return LOS_ERRNO_PERF_SW_INIT_ERROR; + } +#endif + return LOS_OK; +} + +STATIC UINT32 OsPerfConfig(PerfEventConfig *eventsCfg) +{ + UINT32 i; + UINT32 ret; + + g_pmu = OsPerfPmuGet(eventsCfg->type); + if (g_pmu == NULL) { + PRINT_ERR("perf config type error %u!\n", eventsCfg->type); + return LOS_ERRNO_PERF_INVALID_PMU; + } + + UINT32 eventNum = MIN(eventsCfg->eventsNr, PERF_MAX_EVENT); + + (VOID)memset_s(&g_pmu->events, sizeof(PerfEvent), 0, sizeof(PerfEvent)); + + for (i = 0; i < eventNum; i++) { + g_pmu->events.per[i].eventId = eventsCfg->events[i].eventId; + g_pmu->events.per[i].period = eventsCfg->events[i].period; + } + g_pmu->events.nr = i; + g_pmu->events.cntDivided = eventsCfg->predivided; + g_pmu->type = eventsCfg->type; + + ret = g_pmu->config(); + if (ret != LOS_OK) { + PRINT_ERR("perf config failed!\n"); + (VOID)memset_s(&g_pmu->events, sizeof(PerfEvent), 0, sizeof(PerfEvent)); + return LOS_ERRNO_PERF_PMU_CONFIG_ERROR; + } + return LOS_OK; +} + +STATIC VOID OsPerfPrintCount(VOID) +{ + UINT32 index; + UINT32 intSave; + UINT32 cpuid = ArchCurrCpuid(); + + PerfEvent *events = &g_pmu->events; + UINT32 eventNum = events->nr; + + PERF_LOCK(intSave); + for (index = 0; index < eventNum; index++) { + Event *event = &(events->per[index]); + + /* filter out event counter with no event binded. */ + if (event->period == 0) { + continue; + } + PRINT_EMG("[%s] eventType: 0x%x [core %u]: %llu\n", g_pmu->getName(event), event->eventId, cpuid, + event->count[cpuid]); + } + PERF_UNLOCK(intSave); +} + +STATIC INLINE VOID OsPerfPrintTs(VOID) +{ +#ifdef LOSCFG_PERF_CALC_TIME_BY_TICK + DOUBLE time = (g_perfCb.endTime - g_perfCb.startTime) * 1.0 / LOSCFG_BASE_CORE_TICK_PER_SECOND; +#else + DOUBLE time = (g_perfCb.endTime - g_perfCb.startTime) * 1.0 / OS_SYS_CLOCK; +#endif + PRINT_EMG("time used: %.6f(s)\n", time); +} + +STATIC VOID OsPerfStart(VOID) +{ + UINT32 cpuid = ArchCurrCpuid(); + + if (g_pmu == NULL) { + PRINT_ERR("pmu not registered!\n"); + return; + } + + if (g_perfCb.pmuStatusPerCpu[cpuid] != PERF_PMU_STARTED) { + UINT32 ret = g_pmu->start(); + if (ret != LOS_OK) { + PRINT_ERR("perf start on core:%u failed, ret = 0x%x\n", cpuid, ret); + return; + } + + g_perfCb.pmuStatusPerCpu[cpuid] = PERF_PMU_STARTED; + } else { + PRINT_ERR("percpu status err %d\n", g_perfCb.pmuStatusPerCpu[cpuid]); + } +} + +STATIC VOID OsPerfStop(VOID) +{ + UINT32 cpuid = ArchCurrCpuid(); + + if (g_pmu == NULL) { + PRINT_ERR("pmu not registered!\n"); + return; + } + + if (g_perfCb.pmuStatusPerCpu[cpuid] != PERF_PMU_STOPED) { + UINT32 ret = g_pmu->stop(); + if (ret != LOS_OK) { + PRINT_ERR("perf stop on core:%u failed, ret = 0x%x\n", cpuid, ret); + return; + } + + if (!g_perfCb.needSample) { + OsPerfPrintCount(); + } + + g_perfCb.pmuStatusPerCpu[cpuid] = PERF_PMU_STOPED; + } else { + PRINT_ERR("percpu status err %d\n", g_perfCb.pmuStatusPerCpu[cpuid]); + } +} + +STATIC INLINE UINT32 OsPerfSaveIpInfo(CHAR *buf, IpInfo *info) +{ + UINT32 size = 0; +#ifdef LOSCFG_KERNEL_VM + UINT32 len = ALIGN(info->len, sizeof(size_t)); + + *(UINTPTR *)buf = info->ip; /* save ip */ + size += sizeof(UINTPTR); + + *(UINT32 *)(buf + size) = len; /* save f_path length */ + size += sizeof(UINT32); + + if (strncpy_s(buf + size, REGION_PATH_MAX, info->f_path, info->len) != EOK) { /* save f_path */ + PRINT_ERR("copy f_path failed, %s\n", info->f_path); + } + size += len; +#else + *(UINTPTR *)buf = info->ip; /* save ip */ + size += sizeof(UINTPTR); +#endif + return size; +} + +STATIC UINT32 OsPerfBackTrace(PerfBackTrace *callChain, UINT32 maxDepth, PerfRegs *regs) +{ + UINT32 count = BackTraceGet(regs->fp, (IpInfo *)(callChain->ip), maxDepth); + PRINT_DEBUG("backtrace depth = %u, fp = 0x%x\n", count, regs->fp); + return count; +} + +STATIC INLINE UINT32 OsPerfSaveBackTrace(CHAR *buf, PerfBackTrace *callChain, UINT32 count) +{ + UINT32 i; + *(UINT32 *)buf = count; + UINT32 size = sizeof(UINT32); + for (i = 0; i < count; i++) { + size += OsPerfSaveIpInfo(buf + size, &(callChain->ip[i])); + } + return size; +} + +STATIC UINT32 OsPerfCollectData(Event *event, PerfSampleData *data, PerfRegs *regs) +{ + UINT32 size = 0; + UINT32 depth; + IpInfo pc = {0}; + PerfBackTrace callChain = {0}; + UINT32 sampleType = g_perfCb.sampleType; + CHAR *p = (CHAR *)data; + + if (sampleType & PERF_RECORD_CPU) { + *(UINT32 *)(p + size) = ArchCurrCpuid(); + size += sizeof(data->cpuid); + } + + if (sampleType & PERF_RECORD_TID) { + *(UINT32 *)(p + size) = LOS_CurTaskIDGet(); + size += sizeof(data->taskId); + } + + if (sampleType & PERF_RECORD_PID) { + *(UINT32 *)(p + size) = LOS_GetCurrProcessID(); + size += sizeof(data->processId); + } + + if (sampleType & PERF_RECORD_TYPE) { + *(UINT32 *)(p + size) = event->eventId; + size += sizeof(data->eventId); + } + + if (sampleType & PERF_RECORD_PERIOD) { + *(UINT32 *)(p + size) = event->period; + size += sizeof(data->period); + } + + if (sampleType & PERF_RECORD_TIMESTAMP) { + *(UINT64 *)(p + size) = OsPerfGetCurrTime(); + size += sizeof(data->time); + } + + if (sampleType & PERF_RECORD_IP) { + OsGetUsrIpInfo(regs->pc, &pc); + size += OsPerfSaveIpInfo(p + size, &pc); + } + + if (sampleType & PERF_RECORD_CALLCHAIN) { + depth = OsPerfBackTrace(&callChain, PERF_MAX_CALLCHAIN_DEPTH, regs); + size += OsPerfSaveBackTrace(p + size, &callChain, depth); + } + + return size; +} + +/* + * return TRUE if the taskId in the task filter list, return FALSE otherwise; + * return TRUE if user haven't specified any taskId(which is supposed + * to instrument the whole system) + */ +STATIC INLINE BOOL OsFilterId(UINT32 id, const UINT32 *ids, UINT8 idsNr) +{ + UINT32 i; + if (!idsNr) { + return TRUE; + } + + for (i = 0; i < idsNr; i++) { + if (ids[i] == id) { + return TRUE; + } + } + return FALSE; +} + +STATIC INLINE BOOL OsPerfFilter(UINT32 taskId, UINT32 processId) +{ + return OsFilterId(taskId, g_perfCb.taskIds, g_perfCb.taskIdsNr) && + OsFilterId(processId, g_perfCb.processIds, g_perfCb.processIdsNr); +} + +STATIC INLINE UINT32 OsPerfParamValid(VOID) +{ + UINT32 index; + UINT32 res = 0; + + if (g_pmu == NULL) { + return 0; + } + PerfEvent *events = &g_pmu->events; + UINT32 eventNum = events->nr; + + for (index = 0; index < eventNum; index++) { + res |= events->per[index].period; + } + return res; +} + +STATIC UINT32 OsPerfHdrInit(UINT32 id) +{ + PerfDataHdr head = { + .magic = PERF_DATA_MAGIC_WORD, + .sampleType = g_perfCb.sampleType, + .sectionId = id, + .eventType = g_pmu->type, + .len = sizeof(PerfDataHdr), + }; + return OsPerfOutputWrite((CHAR *)&head, head.len); +} + +VOID OsPerfUpdateEventCount(Event *event, UINT32 value) +{ + if (event == NULL) { + return; + } + event->count[ArchCurrCpuid()] += (value & 0xFFFFFFFF); /* event->count is UINT64 */ +} + +VOID OsPerfHandleOverFlow(Event *event, PerfRegs *regs) +{ + PerfSampleData data; + UINT32 len; + + (VOID)memset_s(&data, sizeof(PerfSampleData), 0, sizeof(PerfSampleData)); + if ((g_perfCb.needSample) && OsPerfFilter(LOS_CurTaskIDGet(), LOS_GetCurrProcessID())) { + len = OsPerfCollectData(event, &data, regs); + OsPerfOutputWrite((CHAR *)&data, len); + } +} + +STATIC UINT32 OsPerfInit(VOID) +{ + UINT32 ret; + if (g_perfCb.status != PERF_UNINIT) { + ret = LOS_ERRNO_PERF_STATUS_INVALID; + goto PERF_INIT_ERROR; + } + + ret = OsPmuInit(); + if (ret != LOS_OK) { + goto PERF_INIT_ERROR; + } + + ret = OsPerfOutputInit(NULL, LOSCFG_PERF_BUFFER_SIZE); + if (ret != LOS_OK) { + ret = LOS_ERRNO_PERF_BUF_ERROR; + goto PERF_INIT_ERROR; + } + g_perfCb.status = PERF_STOPPED; +PERF_INIT_ERROR: + return ret; +} + +STATIC VOID PerfInfoDump(VOID) +{ + UINT32 i; + if (g_pmu != NULL) { + PRINTK("type: %d\n", g_pmu->type); + for (i = 0; i < g_pmu->events.nr; i++) { + PRINTK("events[%d]: %d, 0x%x\n", i, g_pmu->events.per[i].eventId, g_pmu->events.per[i].period); + } + PRINTK("predivided: %d\n", g_pmu->events.cntDivided); + } else { + PRINTK("pmu is NULL\n"); + } + + PRINTK("sampleType: 0x%x\n", g_perfCb.sampleType); + for (i = 0; i < g_perfCb.taskIdsNr; i++) { + PRINTK("filter taskIds[%d]: %d\n", i, g_perfCb.taskIds[i]); + } + for (i = 0; i < g_perfCb.processIdsNr; i++) { + PRINTK("filter processIds[%d]: %d\n", i, g_perfCb.processIds[i]); + } + PRINTK("needSample: %d\n", g_perfCb.needSample); +} + +STATIC INLINE VOID OsPerfSetFilterIds(UINT32 *dstIds, UINT8 *dstIdsNr, UINT32 *ids, UINT32 idsNr) +{ + errno_t ret; + if (idsNr) { + ret = memcpy_s(dstIds, PERF_MAX_FILTER_TSKS * sizeof(UINT32), ids, idsNr * sizeof(UINT32)); + if (ret != EOK) { + PRINT_ERR("In %s At line:%d execute memcpy_s error\n", __FUNCTION__, __LINE__); + *dstIdsNr = 0; + return; + } + *dstIdsNr = MIN(idsNr, PERF_MAX_FILTER_TSKS); + } else { + *dstIdsNr = 0; + } +} + +UINT32 LOS_PerfConfig(PerfConfigAttr *attr) +{ + UINT32 ret; + UINT32 intSave; + + if (attr == NULL) { + return LOS_ERRNO_PERF_CONFIG_NULL; + } + + PERF_LOCK(intSave); + if (g_perfCb.status != PERF_STOPPED) { + ret = LOS_ERRNO_PERF_STATUS_INVALID; + PRINT_ERR("perf config status error : 0x%x\n", g_perfCb.status); + goto PERF_CONFIG_ERROR; + } + + g_pmu = NULL; + + g_perfCb.needSample = attr->needSample; + g_perfCb.sampleType = attr->sampleType; + + OsPerfSetFilterIds(g_perfCb.taskIds, &g_perfCb.taskIdsNr, attr->taskIds, attr->taskIdsNr); + OsPerfSetFilterIds(g_perfCb.processIds, &g_perfCb.processIdsNr, attr->processIds, attr->processIdsNr); + + ret = OsPerfConfig(&attr->eventsCfg); + PerfInfoDump(); +PERF_CONFIG_ERROR: + PERF_UNLOCK(intSave); + return ret; +} + +VOID LOS_PerfStart(UINT32 sectionId) +{ + UINT32 intSave; + UINT32 ret; + + PERF_LOCK(intSave); + if (g_perfCb.status != PERF_STOPPED) { + PRINT_ERR("perf start status error : 0x%x\n", g_perfCb.status); + goto PERF_START_ERROR; + } + + if (!OsPerfParamValid()) { + PRINT_ERR("forgot call `LOS_PerfConfig(...)` before perf start?\n"); + goto PERF_START_ERROR; + } + + if (g_perfCb.needSample) { + ret = OsPerfHdrInit(sectionId); /* section header init */ + if (ret != LOS_OK) { + PRINT_ERR("perf hdr init error 0x%x\n", ret); + goto PERF_START_ERROR; + } + } + + SMP_CALL_PERF_FUNC(OsPerfStart); /* send to all cpu to start pmu */ + g_perfCb.status = PERF_STARTED; + g_perfCb.startTime = OsPerfGetCurrTime(); +PERF_START_ERROR: + PERF_UNLOCK(intSave); + return; +} + +VOID LOS_PerfStop(VOID) +{ + UINT32 intSave; + + PERF_LOCK(intSave); + if (g_perfCb.status != PERF_STARTED) { + PRINT_ERR("perf stop status error : 0x%x\n", g_perfCb.status); + goto PERF_STOP_ERROR; + } + + SMP_CALL_PERF_FUNC(OsPerfStop); /* send to all cpu to stop pmu */ + + OsPerfOutputFlush(); + + if (g_perfCb.needSample) { + OsPerfOutputInfo(); + } + + g_perfCb.status = PERF_STOPPED; + g_perfCb.endTime = OsPerfGetCurrTime(); + + OsPerfPrintTs(); +PERF_STOP_ERROR: + PERF_UNLOCK(intSave); + return; +} + +UINT32 LOS_PerfDataRead(CHAR *dest, UINT32 size) +{ + return OsPerfOutputRead(dest, size); +} + +VOID LOS_PerfNotifyHookReg(const PERF_BUF_NOTIFY_HOOK func) +{ + UINT32 intSave; + + PERF_LOCK(intSave); + OsPerfNotifyHookReg(func); + PERF_UNLOCK(intSave); +} + +VOID LOS_PerfFlushHookReg(const PERF_BUF_FLUSH_HOOK func) +{ + UINT32 intSave; + + PERF_LOCK(intSave); + OsPerfFlushHookReg(func); + PERF_UNLOCK(intSave); +} + +VOID OsPerfSetIrqRegs(UINTPTR pc, UINTPTR fp) +{ + LosTaskCB *runTask = (LosTaskCB *)ArchCurrTaskGet(); + runTask->pc = pc; + runTask->fp = fp; +} + +LOS_MODULE_INIT(OsPerfInit, LOS_INIT_LEVEL_KMOD_EXTENDED); diff --git a/src/kernel_liteos_a/kernel/extended/perf/los_perf_pri.h b/src/kernel_liteos_a/kernel/extended/perf/los_perf_pri.h new file mode 100644 index 00000000..a57bd81f --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/perf/los_perf_pri.h @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_PERF_PRI_H +#define _LOS_PERF_PRI_H + +#include "los_perf.h" +#include "perf.h" +#include "los_mp.h" +#include "los_task_pri.h" +#include "los_exc_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define PERF_EVENT_TO_CODE 0 +#define PERF_CODE_TO_EVENT 1 +#define PERF_DATA_MAGIC_WORD 0xEFEFEF00 + +#define SMP_CALL_PERF_FUNC(func) OsMpFuncCall(OS_MP_CPU_ALL, (SMP_FUNC_CALL)func, NULL) + +enum PmuStatus { + PERF_PMU_STOPED, + PERF_PMU_STARTED, +}; + +typedef struct { + UINTPTR pc; + UINTPTR fp; +} PerfRegs; + +typedef struct { + UINT32 ipNr; + IpInfo ip[PERF_MAX_CALLCHAIN_DEPTH]; +} PerfBackTrace; + +typedef struct { + UINT32 cpuid; /* cpu id */ + UINT32 taskId; /* task id */ + UINT32 processId; /* process id */ + UINT32 eventId; /* record type */ + UINT32 period; /* record period */ + UINT64 time; /* record time */ + IpInfo pc; /* instruction pointer */ + PerfBackTrace callChain; /* number of callChain ips */ +} PerfSampleData; + +typedef struct { + UINT32 magic; /* magic number */ + UINT32 eventType; /* enum PerfEventType */ + UINT32 len; /* sample data file length */ + UINT32 sampleType; /* IP | TID | TIMESTAMP... */ + UINT32 sectionId; /* section id */ +} PerfDataHdr; + +typedef struct { + UINT32 counter; + UINT32 eventId; + UINT32 period; + UINT64 count[LOSCFG_KERNEL_CORE_NUM]; +} Event; + +typedef struct { + Event per[PERF_MAX_EVENT]; + UINT8 nr; + UINT8 cntDivided; +} PerfEvent; + +typedef struct { + enum PerfEventType type; + PerfEvent events; + UINT32 (*config)(VOID); + UINT32 (*start)(VOID); + UINT32 (*stop)(VOID); + CHAR *(*getName)(Event *event); +} Pmu; + +typedef struct { + /* time info */ + UINT64 startTime; + UINT64 endTime; + + /* instrumentation status */ + enum PerfStatus status; + enum PmuStatus pmuStatusPerCpu[LOSCFG_KERNEL_CORE_NUM]; + + /* configuration info */ + UINT32 sampleType; + UINT32 taskIds[PERF_MAX_FILTER_TSKS]; + UINT8 taskIdsNr; + UINT32 processIds[PERF_MAX_FILTER_TSKS]; + UINT8 processIdsNr; + UINT8 needSample; +} PerfCB; + +#ifndef OsPerfArchFetchIrqRegs +STATIC INLINE VOID OsPerfArchFetchIrqRegs(PerfRegs *regs, LosTaskCB *curTask) {} +#endif + +STATIC INLINE VOID OsPerfFetchIrqRegs(PerfRegs *regs) +{ + LosTaskCB *curTask = OsCurrTaskGet(); + OsPerfArchFetchIrqRegs(regs, curTask); + PRINT_DEBUG("pc = 0x%x, fp = 0x%x\n", regs->pc, regs->fp); +} + +#ifndef OsPerfArchFetchCallerRegs +STATIC INLINE VOID OsPerfArchFetchCallerRegs(PerfRegs *regs) {} +#endif + +STATIC INLINE VOID OsPerfFetchCallerRegs(PerfRegs *regs) +{ + OsPerfArchFetchCallerRegs(regs); + PRINT_DEBUG("pc = 0x%x, fp = 0x%x\n", regs->pc, regs->fp); +} + +extern VOID OsPerfSetIrqRegs(UINTPTR pc, UINTPTR fp); +extern VOID OsPerfUpdateEventCount(Event *event, UINT32 value); +extern VOID OsPerfHandleOverFlow(Event *event, PerfRegs *regs); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_PERF_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/extended/perf/perf_output.c b/src/kernel_liteos_a/kernel/extended/perf/perf_output.c new file mode 100644 index 00000000..e9e9ca10 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/perf/perf_output.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "perf_output_pri.h" + +STATIC PERF_BUF_NOTIFY_HOOK g_perfBufNotifyHook = NULL; +STATIC PERF_BUF_FLUSH_HOOK g_perfBufFlushHook = NULL; +STATIC PerfOutputCB g_perfOutputCb; + +STATIC VOID OsPerfDefaultNotify(VOID) +{ + PRINT_INFO("perf buf waterline notify!\n"); +} + +UINT32 OsPerfOutputInit(VOID *buf, UINT32 size) +{ + UINT32 ret; + BOOL releaseFlag = FALSE; + if (buf == NULL) { + buf = LOS_MemAlloc(m_aucSysMem1, size); + if (buf == NULL) { + return LOS_NOK; + } else { + releaseFlag = TRUE; + } + } + ret = LOS_CirBufInit(&g_perfOutputCb.ringbuf, buf, size); + if (ret != LOS_OK) { + goto RELEASE; + } + g_perfOutputCb.waterMark = size / PERF_BUFFER_WATERMARK_ONE_N; + g_perfBufNotifyHook = OsPerfDefaultNotify; + return ret; +RELEASE: + if (releaseFlag) { + (VOID)LOS_MemFree(m_aucSysMem1, buf); + } + return ret; +} + +VOID OsPerfOutputFlush(VOID) +{ + if (g_perfBufFlushHook != NULL) { + g_perfBufFlushHook(g_perfOutputCb.ringbuf.fifo, g_perfOutputCb.ringbuf.size); + } +} + +UINT32 OsPerfOutputRead(CHAR *dest, UINT32 size) +{ + OsPerfOutputFlush(); + return LOS_CirBufRead(&g_perfOutputCb.ringbuf, dest, size); +} + +STATIC BOOL OsPerfOutputBegin(UINT32 size) +{ + if (g_perfOutputCb.ringbuf.remain < size) { + PRINT_INFO("perf buf has no enough space for 0x%x\n", size); + return FALSE; + } + return TRUE; +} + +STATIC VOID OsPerfOutputEnd(VOID) +{ + OsPerfOutputFlush(); + if (LOS_CirBufUsedSize(&g_perfOutputCb.ringbuf) >= g_perfOutputCb.waterMark) { + if (g_perfBufNotifyHook != NULL) { + g_perfBufNotifyHook(); + } + } +} + +UINT32 OsPerfOutputWrite(CHAR *data, UINT32 size) +{ + if (!OsPerfOutputBegin(size)) { + return LOS_NOK; + } + + LOS_CirBufWrite(&g_perfOutputCb.ringbuf, data, size); + + OsPerfOutputEnd(); + return LOS_OK; +} + +VOID OsPerfOutputInfo(VOID) +{ + PRINT_EMG("dump perf data, addr: %p length: %#x\n", g_perfOutputCb.ringbuf.fifo, g_perfOutputCb.ringbuf.size); +} + +VOID OsPerfNotifyHookReg(const PERF_BUF_NOTIFY_HOOK func) +{ + g_perfBufNotifyHook = func; +} + +VOID OsPerfFlushHookReg(const PERF_BUF_FLUSH_HOOK func) +{ + g_perfBufFlushHook = func; +} diff --git a/src/kernel_liteos_a/kernel/extended/perf/perf_output_pri.h b/src/kernel_liteos_a/kernel/extended/perf/perf_output_pri.h new file mode 100644 index 00000000..c9c8c9c1 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/perf/perf_output_pri.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _PERF_OUTPUT_PRI_H +#define _PERF_OUTPUT_PRI_H + +#include "los_perf_pri.h" +#include "los_cir_buf.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef struct { + CirBuf ringbuf; /* ring buffer */ + UINT32 waterMark; /* notify water mark */ +} PerfOutputCB; + +extern UINT32 OsPerfOutputInit(VOID *buf, UINT32 size); +extern UINT32 OsPerfOutputRead(CHAR *dest, UINT32 size); +extern UINT32 OsPerfOutputWrite(CHAR *data, UINT32 size); +extern VOID OsPerfOutputInfo(VOID); +extern VOID OsPerfOutputFlush(VOID); +extern VOID OsPerfNotifyHookReg(const PERF_BUF_NOTIFY_HOOK func); +extern VOID OsPerfFlushHookReg(const PERF_BUF_FLUSH_HOOK func); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _PERF_OUTPUT_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/extended/perf/perf_pmu.c b/src/kernel_liteos_a/kernel/extended/perf/perf_pmu.c new file mode 100644 index 00000000..1ad54746 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/perf/perf_pmu.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "perf_pmu_pri.h" + +STATIC Pmu *g_pmuMgr[PERF_EVENT_TYPE_MAX] = { NULL }; + +UINT32 OsPerfPmuRegister(Pmu *pmu) +{ + UINT32 type; + + if ((pmu == NULL) || (pmu->type >= PERF_EVENT_TYPE_MAX)) { + return LOS_NOK; + } + + type = pmu->type; + if (g_pmuMgr[type] == NULL) { + g_pmuMgr[type] = pmu; + return LOS_OK; + } + return LOS_NOK; +} + +Pmu *OsPerfPmuGet(UINT32 type) +{ + if (type >= PERF_EVENT_TYPE_MAX) { + return NULL; + } + + if (type == PERF_EVENT_TYPE_RAW) { /* process hardware raw events with hard pmu */ + type = PERF_EVENT_TYPE_HW; + } + return g_pmuMgr[type]; +} + +VOID OsPerfPmuRm(UINT32 type) +{ + if (type >= PERF_EVENT_TYPE_MAX) { + return; + } + g_pmuMgr[type] = NULL; +} diff --git a/src/kernel_liteos_a/kernel/extended/perf/perf_pmu_pri.h b/src/kernel_liteos_a/kernel/extended/perf/perf_pmu_pri.h new file mode 100644 index 00000000..34f2dfa9 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/perf/perf_pmu_pri.h @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _PERF_PMU_PRI_H +#define _PERF_PMU_PRI_H + +#include "los_perf_pri.h" + +#ifdef LOSCFG_HRTIMER_ENABLE +#include "linux/hrtimer.h" +#endif + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef struct { + Pmu pmu; + BOOL canDivided; + UINT32 cntDivided; + VOID (*enable)(Event *event); + VOID (*disable)(Event *event); + VOID (*start)(VOID); + VOID (*stop)(VOID); + VOID (*clear)(VOID); + VOID (*setPeriod)(Event *event); + UINTPTR (*readCnt)(Event *event); + UINT32 (*mapEvent)(UINT32 eventType, BOOL reverse); +} HwPmu; + +typedef struct { + Pmu pmu; + union { + struct { /* trace event */ + BOOL enable; + }; +#ifdef LOSCFG_HRTIMER_ENABLE + struct { /* timer event */ + struct hrtimer hrtimer; + union ktime time; + union ktime cfgTime; + }; +#endif + }; +} SwPmu; + +#define GET_HW_PMU(item) LOS_DL_LIST_ENTRY(item, HwPmu, pmu) + +#define TIMER_PERIOD_LOWER_BOUND_US 100 + +#define CCNT_FULL 0xFFFFFFFF +#define CCNT_PERIOD_LOWER_BOUND 0x00000000 +#define CCNT_PERIOD_UPPER_BOUND 0xFFFFFF00 +#define PERIOD_CALC(p) (CCNT_FULL - (p)) +#define VALID_PERIOD(p) ((PERIOD_CALC(p) > CCNT_PERIOD_LOWER_BOUND) \ + && (PERIOD_CALC(p) < CCNT_PERIOD_UPPER_BOUND)) + +#define PERF_HW_INVALID_EVENT_TYPE 0xFFFFFFFF + +#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0])) + +#define PMU_LABEL_INT_1 \ + NUM_HAL_INTERRUPT_PMU_0, +#define PMU_LABEL_INT_2 \ + PMU_LABEL_INT_1 \ + NUM_HAL_INTERRUPT_PMU_1, +#define PMU_LABEL_INT_3 \ + PMU_LABEL_INT_2 \ + NUM_HAL_INTERRUPT_PMU_2, +#define PMU_LABEL_INT_4 \ + PMU_LABEL_INT_3 \ + NUM_HAL_INTERRUPT_PMU_3, + +#define PMU_INT(_num) PMU_LABEL_INT_##_num + +#define OS_PMU_INTS(_num, _list) \ + STATIC UINT32 _list[_num] = { \ + PMU_INT(_num) \ + } + +extern UINT32 OsPerfPmuRegister(Pmu *pmu); +extern VOID OsPerfPmuRm(UINT32 type); +extern Pmu *OsPerfPmuGet(UINT32 type); + +extern UINT32 OsHwPmuInit(VOID); +extern UINT32 OsSwPmuInit(VOID); +extern UINT32 OsTimedPmuInit(VOID); + +extern UINT32 OsGetPmuCounter0(VOID); +extern UINT32 OsGetPmuMaxCounter(VOID); +extern UINT32 OsGetPmuCycleCounter(VOID); +extern UINT32 OsPerfHwInit(HwPmu *hwPmu); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _PERF_PMU_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/extended/perf/pmu/perf_hw_pmu.c b/src/kernel_liteos_a/kernel/extended/perf/pmu/perf_hw_pmu.c new file mode 100644 index 00000000..0c5e9e1b --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/perf/pmu/perf_hw_pmu.c @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "perf_pmu_pri.h" + +STATIC Pmu *g_perfHw = NULL; + +STATIC CHAR *g_eventName[PERF_COUNT_HW_MAX] = { + [PERF_COUNT_HW_CPU_CYCLES] = "cycles", + [PERF_COUNT_HW_INSTRUCTIONS] = "instructions", + [PERF_COUNT_HW_ICACHE_REFERENCES] = "icache", + [PERF_COUNT_HW_ICACHE_MISSES] = "icache-misses", + [PERF_COUNT_HW_DCACHE_REFERENCES] = "dcache", + [PERF_COUNT_HW_DCACHE_MISSES] = "dcache-misses", + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = "branches", + [PERF_COUNT_HW_BRANCH_MISSES] = "branches-misses", +}; + +/** + * 1.If config event is PERF_EVENT_TYPE_HW, then map it to the real eventId first, otherwise use the configured + * eventId directly. + * 2.Find available counter for each event. + * 3.Decide whether this hardware pmu need prescaler (once every 64 cycle counts). + */ +STATIC UINT32 OsPerfHwConfig(VOID) +{ + UINT32 i; + HwPmu *armPmu = GET_HW_PMU(g_perfHw); + + UINT32 maxCounter = OsGetPmuMaxCounter(); + UINT32 counter = OsGetPmuCounter0(); + UINT32 cycleCounter = OsGetPmuCycleCounter(); + UINT32 cycleCode = armPmu->mapEvent(PERF_COUNT_HW_CPU_CYCLES, PERF_EVENT_TO_CODE); + if (cycleCode == PERF_HW_INVALID_EVENT_TYPE) { + return LOS_NOK; + } + + PerfEvent *events = &g_perfHw->events; + UINT32 eventNum = events->nr; + + for (i = 0; i < eventNum; i++) { + Event *event = &(events->per[i]); + + if (!VALID_PERIOD(event->period)) { + PRINT_ERR("Config period: 0x%x invalid, should be in (%#x, %#x)\n", event->period, + PERIOD_CALC(CCNT_PERIOD_UPPER_BOUND), PERIOD_CALC(CCNT_PERIOD_LOWER_BOUND)); + return LOS_NOK; + } + + if (g_perfHw->type == PERF_EVENT_TYPE_HW) { /* do map */ + UINT32 eventId = armPmu->mapEvent(event->eventId, PERF_EVENT_TO_CODE); + if (eventId == PERF_HW_INVALID_EVENT_TYPE) { + return LOS_NOK; + } + event->eventId = eventId; + } + + if (event->eventId == cycleCode) { + event->counter = cycleCounter; + } else { + event->counter = counter; + counter++; + } + + if (counter >= maxCounter) { + PRINT_ERR("max events: %u excluding cycle event\n", maxCounter - 1); + return LOS_NOK; + } + + PRINT_DEBUG("Perf Config %u eventId = 0x%x, counter = 0x%x, period = 0x%x\n", i, event->eventId, event->counter, + event->period); + } + + armPmu->cntDivided = events->cntDivided & armPmu->canDivided; + return LOS_OK; +} + +STATIC UINT32 OsPerfHwStart(VOID) +{ + UINT32 i; + UINT32 cpuid = ArchCurrCpuid(); + HwPmu *armPmu = GET_HW_PMU(g_perfHw); + + PerfEvent *events = &g_perfHw->events; + UINT32 eventNum = events->nr; + + armPmu->clear(); + + for (i = 0; i < eventNum; i++) { + Event *event = &(events->per[i]); + armPmu->setPeriod(event); + armPmu->enable(event); + event->count[cpuid] = 0; + } + + armPmu->start(); + return LOS_OK; +} + +STATIC UINT32 OsPerfHwStop(VOID) +{ + UINT32 i; + UINT32 cpuid = ArchCurrCpuid(); + HwPmu *armPmu = GET_HW_PMU(g_perfHw); + + PerfEvent *events = &g_perfHw->events; + UINT32 eventNum = events->nr; + + armPmu->stop(); + + for (i = 0; i < eventNum; i++) { + Event *event = &(events->per[i]); + UINTPTR value = armPmu->readCnt(event); + PRINT_DEBUG("perf stop readCnt value = 0x%x\n", value); + event->count[cpuid] += value; + + /* multiplier of cycle counter */ + UINT32 eventId = armPmu->mapEvent(event->eventId, PERF_CODE_TO_EVENT); + if ((eventId == PERF_COUNT_HW_CPU_CYCLES) && (armPmu->cntDivided != 0)) { + PRINT_DEBUG("perf stop is cycle\n"); + event->count[cpuid] = event->count[cpuid] << 6; /* CCNT counts every 64th cpu cycle */ + } + PRINT_DEBUG("perf stop eventCount[0x%x] : [%s] = %llu\n", event->eventId, g_eventName[eventId], + event->count[cpuid]); + } + return LOS_OK; +} + +STATIC CHAR *OsPerfGetEventName(Event *event) +{ + UINT32 eventId; + HwPmu *armPmu = GET_HW_PMU(g_perfHw); + eventId = armPmu->mapEvent(event->eventId, PERF_CODE_TO_EVENT); + if (eventId < PERF_COUNT_HW_MAX) { + return g_eventName[eventId]; + } else { + return "unknown"; + } +} + +UINT32 OsPerfHwInit(HwPmu *hwPmu) +{ + UINT32 ret; + if (hwPmu == NULL) { + return LOS_NOK; + } + + hwPmu->pmu.type = PERF_EVENT_TYPE_HW; + hwPmu->pmu.config = OsPerfHwConfig; + hwPmu->pmu.start = OsPerfHwStart; + hwPmu->pmu.stop = OsPerfHwStop; + hwPmu->pmu.getName = OsPerfGetEventName; + + (VOID)memset_s(&hwPmu->pmu.events, sizeof(PerfEvent), 0, sizeof(PerfEvent)); + ret = OsPerfPmuRegister(&hwPmu->pmu); + + g_perfHw = OsPerfPmuGet(PERF_EVENT_TYPE_HW); + return ret; +} diff --git a/src/kernel_liteos_a/kernel/extended/perf/pmu/perf_sw_pmu.c b/src/kernel_liteos_a/kernel/extended/perf/pmu/perf_sw_pmu.c new file mode 100644 index 00000000..971a2b26 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/perf/pmu/perf_sw_pmu.c @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "perf_pmu_pri.h" +#include "los_hook.h" + +STATIC SwPmu g_perfSw; +STATIC CHAR *g_eventName[PERF_COUNT_SW_MAX] = { + [PERF_COUNT_SW_TASK_SWITCH] = "task switch", + [PERF_COUNT_SW_IRQ_RESPONSE] = "irq response", + [PERF_COUNT_SW_MEM_ALLOC] = "mem alloc", + [PERF_COUNT_SW_MUX_PEND] = "mux pend", +}; + +STATIC UINT32 g_traceEventMap[PERF_COUNT_SW_MAX] = { + [PERF_COUNT_SW_TASK_SWITCH] = LOS_HOOK_TYPE_TASK_SWITCHEDIN, + [PERF_COUNT_SW_IRQ_RESPONSE] = LOS_HOOK_TYPE_ISR_ENTER, + [PERF_COUNT_SW_MEM_ALLOC] = LOS_HOOK_TYPE_MEM_ALLOC, + [PERF_COUNT_SW_MUX_PEND] = LOS_HOOK_TYPE_MUX_PEND, +}; + +VOID OsPerfHook(UINT32 eventType) +{ + if (!g_perfSw.enable) { + return; + } + + PerfEvent *events = &g_perfSw.pmu.events; + UINT32 eventNum = events->nr; + + UINT32 i; + PerfRegs regs; + + (VOID)memset_s(®s, sizeof(PerfRegs), 0, sizeof(PerfRegs)); + + for (i = 0; i < eventNum; i++) { + Event *event = &(events->per[i]); + if (event->counter == eventType) { + OsPerfUpdateEventCount(event, 1); + if (event->count[ArchCurrCpuid()] % event->period == 0) { + OsPerfFetchCallerRegs(®s); + OsPerfHandleOverFlow(event, ®s); + } + return; + } + } +} + +STATIC VOID LOS_PerfMemAlloc(VOID *pool, VOID *ptr, UINT32 size) +{ + OsPerfHook(LOS_HOOK_TYPE_MEM_ALLOC); +} + +STATIC VOID LOS_PerfMuxPend(const LosMux *muxCB, UINT32 timeout) +{ + OsPerfHook(LOS_HOOK_TYPE_MUX_PEND); +} + +STATIC VOID LOS_PerfIsrEnter(UINT32 hwiNum) +{ + OsPerfHook(LOS_HOOK_TYPE_ISR_ENTER); +} + +STATIC VOID LOS_PerfTaskSwitchedIn(const LosTaskCB *newTask, const LosTaskCB *runTask) +{ + OsPerfHook(LOS_HOOK_TYPE_TASK_SWITCHEDIN); +} + +STATIC VOID OsPerfCnvInit(VOID) +{ + LOS_HookReg(LOS_HOOK_TYPE_MEM_ALLOC, LOS_PerfMemAlloc); + LOS_HookReg(LOS_HOOK_TYPE_MUX_PEND, LOS_PerfMuxPend); + LOS_HookReg(LOS_HOOK_TYPE_ISR_ENTER, LOS_PerfIsrEnter); + LOS_HookReg(LOS_HOOK_TYPE_TASK_SWITCHEDIN, LOS_PerfTaskSwitchedIn); +} + +STATIC UINT32 OsPerfSwConfig(VOID) +{ + UINT32 i; + PerfEvent *events = &g_perfSw.pmu.events; + UINT32 eventNum = events->nr; + + for (i = 0; i < eventNum; i++) { + Event *event = &(events->per[i]); + if ((event->eventId < PERF_COUNT_SW_TASK_SWITCH) || (event->eventId >= PERF_COUNT_SW_MAX) || + (event->period == 0)) { + return LOS_NOK; + } + event->counter = g_traceEventMap[event->eventId]; + } + return LOS_OK; +} + +STATIC UINT32 OsPerfSwStart(VOID) +{ + UINT32 i; + UINT32 cpuid = ArchCurrCpuid(); + PerfEvent *events = &g_perfSw.pmu.events; + UINT32 eventNum = events->nr; + + for (i = 0; i < eventNum; i++) { + Event *event = &(events->per[i]); + event->count[cpuid] = 0; + } + + g_perfSw.enable = TRUE; + return LOS_OK; +} + +STATIC UINT32 OsPerfSwStop(VOID) +{ + g_perfSw.enable = FALSE; + return LOS_OK; +} + +STATIC CHAR *OsPerfGetEventName(Event *event) +{ + UINT32 eventId = event->eventId; + if (eventId < PERF_COUNT_SW_MAX) { + return g_eventName[eventId]; + } + return "unknown"; +} + +UINT32 OsSwPmuInit(VOID) +{ + g_perfSw.pmu = (Pmu) { + .type = PERF_EVENT_TYPE_SW, + .config = OsPerfSwConfig, + .start = OsPerfSwStart, + .stop = OsPerfSwStop, + .getName = OsPerfGetEventName, + }; + + g_perfSw.enable = FALSE; + + OsPerfCnvInit(); + + (VOID)memset_s(&g_perfSw.pmu.events, sizeof(PerfEvent), 0, sizeof(PerfEvent)); + return OsPerfPmuRegister(&g_perfSw.pmu); +} diff --git a/src/kernel_liteos_a/kernel/extended/perf/pmu/perf_timed_pmu.c b/src/kernel_liteos_a/kernel/extended/perf/pmu/perf_timed_pmu.c new file mode 100644 index 00000000..abe640d9 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/perf/pmu/perf_timed_pmu.c @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "perf_pmu_pri.h" + +#define US_PER_SECOND 1000000 +#define HRTIMER_DEFAULT_PERIOD_US 1000 + +STATIC SwPmu g_perfTimed; + +STATIC BOOL OsPerfTimedPeriodValid(UINT32 period) +{ + return period >= TIMER_PERIOD_LOWER_BOUND_US; +} + +STATIC UINT32 OsPerfTimedStart(VOID) +{ + UINT32 i; + UINT32 cpuid = ArchCurrCpuid(); + PerfEvent *events = &g_perfTimed.pmu.events; + UINT32 eventNum = events->nr; + + for (i = 0; i < eventNum; i++) { + Event *event = &(events->per[i]); + event->count[cpuid] = 0; + } + + if (cpuid != 0) { /* only need start on one core */ + return LOS_OK; + } + + if (hrtimer_start(&g_perfTimed.hrtimer, g_perfTimed.time, HRTIMER_MODE_REL) != 0) { + PRINT_ERR("Hrtimer start failed\n"); + return LOS_NOK; + } + + if (hrtimer_forward(&g_perfTimed.hrtimer, g_perfTimed.cfgTime) == 0) { + PRINT_ERR("Hrtimer forward failed\n"); + return LOS_NOK; + } + + g_perfTimed.time = g_perfTimed.cfgTime; + return LOS_OK; +} + +STATIC UINT32 OsPerfTimedConfig(VOID) +{ + UINT32 i; + PerfEvent *events = &g_perfTimed.pmu.events; + UINT32 eventNum = events->nr; + + for (i = 0; i < eventNum; i++) { + Event *event = &(events->per[i]); + UINT32 period = event->period; + if (event->eventId == PERF_COUNT_CPU_CLOCK) { + if (!OsPerfTimedPeriodValid(period)) { + period = TIMER_PERIOD_LOWER_BOUND_US; + PRINT_ERR("config period invalid, should be >= 100, use default period:%u us\n", period); + } + + g_perfTimed.cfgTime = (union ktime) { + .tv.sec = period / US_PER_SECOND, + .tv.usec = period % US_PER_SECOND + }; + PRINT_INFO("hrtimer config period - sec:%d, usec:%d\n", g_perfTimed.cfgTime.tv.sec, + g_perfTimed.cfgTime.tv.usec); + return LOS_OK; + } + } + return LOS_NOK; +} + +STATIC UINT32 OsPerfTimedStop(VOID) +{ + UINT32 ret; + + if (ArchCurrCpuid() != 0) { /* only need stop on one core */ + return LOS_OK; + } + + ret = hrtimer_cancel(&g_perfTimed.hrtimer); + if (ret != 1) { + PRINT_ERR("Hrtimer stop failed!, 0x%x\n", ret); + return LOS_NOK; + } + return LOS_OK; +} + +STATIC VOID OsPerfTimedHandle(VOID) +{ + UINT32 index; + PerfRegs regs; + + PerfEvent *events = &g_perfTimed.pmu.events; + UINT32 eventNum = events->nr; + + (VOID)memset_s(®s, sizeof(PerfRegs), 0, sizeof(PerfRegs)); + OsPerfFetchIrqRegs(®s); + + for (index = 0; index < eventNum; index++) { + Event *event = &(events->per[index]); + OsPerfUpdateEventCount(event, 1); /* eventCount += 1 every once */ + OsPerfHandleOverFlow(event, ®s); + } +} + +STATIC enum hrtimer_restart OsPerfHrtimer(struct hrtimer *hrtimer) +{ + SMP_CALL_PERF_FUNC(OsPerfTimedHandle); /* send to all cpu to collect data */ + return HRTIMER_RESTART; +} + +STATIC CHAR *OsPerfGetEventName(Event *event) +{ + if (event->eventId == PERF_COUNT_CPU_CLOCK) { + return "timed"; + } else { + return "unknown"; + } +} + +UINT32 OsTimedPmuInit(VOID) +{ + UINT32 ret; + + g_perfTimed.time = (union ktime) { + .tv.sec = 0, + .tv.usec = HRTIMER_DEFAULT_PERIOD_US, + }; + + hrtimer_init(&g_perfTimed.hrtimer, 1, HRTIMER_MODE_REL); + + ret = hrtimer_create(&g_perfTimed.hrtimer, g_perfTimed.time, OsPerfHrtimer); + if (ret != LOS_OK) { + return ret; + } + + g_perfTimed.pmu = (Pmu) { + .type = PERF_EVENT_TYPE_TIMED, + .config = OsPerfTimedConfig, + .start = OsPerfTimedStart, + .stop = OsPerfTimedStop, + .getName = OsPerfGetEventName, + }; + + (VOID)memset_s(&g_perfTimed.pmu.events, sizeof(PerfEvent), 0, sizeof(PerfEvent)); + ret = OsPerfPmuRegister(&g_perfTimed.pmu); + return ret; +} diff --git a/src/kernel_liteos_a/kernel/extended/pipes/BUILD.gn b/src/kernel_liteos_a/kernel/extended/pipes/BUILD.gn new file mode 100644 index 00000000..c70cf4df --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/pipes/BUILD.gn @@ -0,0 +1,43 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") +import("$THIRDPARTY_NUTTX_DIR/NuttX.gni") + +module_switch = defined(LOSCFG_KERNEL_PIPE) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = NUTTX_DRIVERS_PIPES_SRC_FILES + + public_configs = [ ":public" ] +} + +config("public") { + include_dirs = NUTTX_DRIVERS_PIPES_INCLUDE_DIRS +} diff --git a/src/kernel_liteos_a/kernel/extended/pipes/Makefile b/src/kernel_liteos_a/kernel/extended/pipes/Makefile new file mode 100644 index 00000000..72b274bd --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/pipes/Makefile @@ -0,0 +1,37 @@ +# Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +LOCAL_DIR := $(LITEOSTOPDIR)/../../third_party/NuttX/drivers/pipes + +LOCAL_SRCS := $(wildcard $(LOCAL_DIR)/*.c) + +include $(MODULE) diff --git a/src/kernel_liteos_a/kernel/extended/plimit/BUILD.gn b/src/kernel_liteos_a/kernel/extended/plimit/BUILD.gn new file mode 100644 index 00000000..8632073c --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/plimit/BUILD.gn @@ -0,0 +1,46 @@ +# Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = true +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ + "los_devicelimit.c", + "los_ipclimit.c", + "los_memlimit.c", + "los_plimits.c", + "los_processlimit.c", + "los_schedlimit.c", + ] +} + +config("public") { + include_dirs = [ "." ] +} diff --git a/src/kernel_liteos_a/kernel/extended/plimit/Makefile b/src/kernel_liteos_a/kernel/extended/plimit/Makefile new file mode 100644 index 00000000..c2f9209e --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/plimit/Makefile @@ -0,0 +1,35 @@ +# Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := $(wildcard *.c) + +include $(MODULE) diff --git a/src/kernel_liteos_a/kernel/extended/plimit/los_devicelimit.c b/src/kernel_liteos_a/kernel/extended/plimit/los_devicelimit.c new file mode 100644 index 00000000..2cebaa3b --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/plimit/los_devicelimit.c @@ -0,0 +1,605 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef LOSCFG_KERNEL_DEV_PLIMIT +#include "los_seq_buf.h" +#include "los_bitmap.h" +#include "los_process_pri.h" +#include "los_devicelimit.h" + +#define TYPE_CHAR_LEN (1) +#define DEVICE_NAME_PREFIX_SPACE (1) +#define DEVICE_ACCESS_MAXLEN (3) +#define BUF_SEPARATOR (5) + +STATIC ProcDevLimit *g_procDevLimit = NULL; + +VOID OsDevLimitInit(UINTPTR limit) +{ + ProcDevLimit *deviceLimit = (ProcDevLimit *)limit; + deviceLimit->behavior = DEVLIMIT_DEFAULT_ALLOW; + LOS_ListInit(&(deviceLimit->accessList)); + g_procDevLimit = deviceLimit; +} + +VOID *OsDevLimitAlloc(VOID) +{ + ProcDevLimit *plimit = (ProcDevLimit *)LOS_MemAlloc(m_aucSysMem1, sizeof(ProcDevLimit)); + if (plimit == NULL) { + return NULL; + } + (VOID)memset_s(plimit, sizeof(ProcDevLimit), 0, sizeof(ProcDevLimit)); + LOS_ListInit(&(plimit->accessList)); + plimit->behavior = DEVLIMIT_DEFAULT_NONE; + return (VOID *)plimit; +} + +STATIC VOID DevAccessListDelete(ProcDevLimit *devLimit) +{ + DevAccessItem *delItem = NULL; + DevAccessItem *tmpItem = NULL; + LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(delItem, tmpItem, &devLimit->accessList, DevAccessItem, list) { + LOS_ListDelete(&delItem->list); + (VOID)LOS_MemFree(m_aucSysMem1, (VOID *)delItem); + } +} + +VOID OsDevLimitFree(UINTPTR limit) +{ + ProcDevLimit *devLimit = (ProcDevLimit *)limit; + if (devLimit == NULL) { + return; + } + + DevAccessListDelete(devLimit); + (VOID)LOS_MemFree(m_aucSysMem1, devLimit); +} + +STATIC UINT32 DevLimitCopyAccess(ProcDevLimit *devLimitDest, ProcDevLimit *devLimitSrc) +{ + DevAccessItem *tmpItem = NULL; + INT32 itemSize = sizeof(DevAccessItem); + devLimitDest->behavior = devLimitSrc->behavior; + LOS_DL_LIST_FOR_EACH_ENTRY(tmpItem, &devLimitSrc->accessList, DevAccessItem, list) { + DevAccessItem *newItem = (DevAccessItem *)LOS_MemAlloc(m_aucSysMem1, itemSize); + if (newItem == NULL) { + return ENOMEM; + } + (VOID)memcpy_s(newItem, sizeof(DevAccessItem), tmpItem, sizeof(DevAccessItem)); + LOS_ListTailInsert(&devLimitDest->accessList, &newItem->list); + } + return LOS_OK; +} + +VOID OsDevLimitCopy(UINTPTR dest, UINTPTR src) +{ + ProcDevLimit *devLimitDest = (ProcDevLimit *)dest; + ProcDevLimit *devLimitSrc = (ProcDevLimit *)src; + (VOID)DevLimitCopyAccess(devLimitDest, devLimitSrc); + devLimitDest->parent = (ProcDevLimit *)src; +} + +STATIC INLINE INT32 IsSpace(INT32 c) +{ + return (c == ' ' || (unsigned)c - '\t' < BUF_SEPARATOR); +} + +STATIC UINT32 ParseItemAccess(const CHAR *buf, DevAccessItem *item) +{ + switch (*buf) { + case 'a': + item->type = DEVLIMIT_DEV_ALL; + return LOS_OK; + case 'b': + item->type = DEVLIMIT_DEV_BLOCK; + break; + case 'c': + item->type = DEVLIMIT_DEV_CHAR; + break; + default: + return EINVAL; + } + buf += DEVICE_NAME_PREFIX_SPACE; + if (!IsSpace(*buf)) { + return EINVAL; + } + buf += DEVICE_NAME_PREFIX_SPACE; + + for (INT32 count = 0; count < sizeof(item->name) - 1; count++) { + if (IsSpace(*buf)) { + break; + } + item->name[count] = *buf; + buf += TYPE_CHAR_LEN; + } + if (!IsSpace(*buf)) { + return EINVAL; + } + + buf += DEVICE_NAME_PREFIX_SPACE; + for (INT32 i = 0; i < DEVICE_ACCESS_MAXLEN; i++) { + switch (*buf) { + case 'r': + item->access |= DEVLIMIT_ACC_READ; + break; + case 'w': + item->access |= DEVLIMIT_ACC_WRITE; + break; + case 'm': + item->access |= DEVLIMIT_ACC_MKNOD; + break; + case '\n': + case '\0': + i = DEVICE_ACCESS_MAXLEN; + break; + default: + return EINVAL; + } + buf += TYPE_CHAR_LEN; + } + return LOS_OK; +} + +STATIC BOOL DevLimitMayAllowAll(ProcDevLimit *parent) +{ + if (parent == NULL) { + return TRUE; + } + return (parent->behavior == DEVLIMIT_DEFAULT_ALLOW); +} + +STATIC BOOL DevLimitHasChildren(ProcLimitSet *procLimitSet, ProcDevLimit *devLimit) +{ + ProcLimitSet *parent = procLimitSet; + ProcLimitSet *childProcLimitSet = NULL; + if (devLimit == NULL) { + return FALSE; + } + + LOS_DL_LIST_FOR_EACH_ENTRY(childProcLimitSet, &(procLimitSet->childList), ProcLimitSet, childList) { + if (childProcLimitSet == NULL) { + continue; + } + if (childProcLimitSet->parent != parent) { + continue; + } + if (!((childProcLimitSet->mask) & BIT(PROCESS_LIMITER_ID_DEV))) { + continue; + } + return TRUE; + } + return FALSE; +} + +STATIC UINT32 DealItemAllAccess(ProcLimitSet *procLimitSet, ProcDevLimit *devLimit, + ProcDevLimit *devParentLimit, INT32 filetype) +{ + switch (filetype) { + case DEVLIMIT_ALLOW: { + if (DevLimitHasChildren(procLimitSet, devLimit)) { + return EINVAL; + } + if (!DevLimitMayAllowAll(devParentLimit)) { + return EPERM; + } + DevAccessListDelete(devLimit); + devLimit->behavior = DEVLIMIT_DEFAULT_ALLOW; + if (devParentLimit == NULL) { + break; + } + DevLimitCopyAccess(devLimit, devParentLimit); + break; + } + case DEVLIMIT_DENY: { + if (DevLimitHasChildren(procLimitSet, devLimit)) { + return EINVAL; + } + DevAccessListDelete(devLimit); + devLimit->behavior = DEVLIMIT_DEFAULT_DENY; + break; + } + default: + return EINVAL; + } + return LOS_OK; +} + +STATIC BOOL DevLimitMatchItemPartial(LOS_DL_LIST *list, DevAccessItem *item) +{ + if ((list == NULL) || (item == NULL)) { + return FALSE; + } + if (LOS_ListEmpty(list)) { + return FALSE; + } + DevAccessItem *walk = NULL; + LOS_DL_LIST_FOR_EACH_ENTRY(walk, list, DevAccessItem, list) { + if (item->type != walk->type) { + continue; + } + if ((strcmp(walk->name, "*") != 0) && (strcmp(item->name, "*") != 0) + && (strcmp(walk->name, item->name) != 0)) { + continue; + } + if (!(item->access & ~(walk->access))) { + return TRUE; + } + } + return FALSE; +} + +STATIC BOOL DevLimitParentAllowsRmItem(ProcDevLimit *devParentLimit, DevAccessItem *item) +{ + if (devParentLimit == NULL) { + return TRUE; + } + /* Make sure you're not removing part or a whole item existing in the parent plimits */ + return !DevLimitMatchItemPartial(&devParentLimit->accessList, item); +} + +STATIC BOOL DevLimitMatchItem(LOS_DL_LIST *list, DevAccessItem *item) +{ + if ((list == NULL) || (item == NULL)) { + return FALSE; + } + if (LOS_ListEmpty(list)) { + return FALSE; + } + DevAccessItem *walk = NULL; + LOS_DL_LIST_FOR_EACH_ENTRY(walk, list, DevAccessItem, list) { + if (item->type != walk->type) { + continue; + } + if ((strcmp(walk->name, "*") != 0) && (strcmp(walk->name, item->name) != 0)) { + continue; + } + if (!(item->access & ~(walk->access))) { + return TRUE; + } + } + return FALSE; +} + +/** + * This is used to make sure a child plimits won't have more privileges than its parent + */ +STATIC BOOL DevLimitVerifyNewItem(ProcDevLimit *parent, DevAccessItem *item, INT32 currBehavior) +{ + if (parent == NULL) { + return TRUE; + } + + if (parent->behavior == DEVLIMIT_DEFAULT_ALLOW) { + if (currBehavior == DEVLIMIT_DEFAULT_ALLOW) { + return TRUE; + } + return !DevLimitMatchItemPartial(&parent->accessList, item); + } + return DevLimitMatchItem(&parent->accessList, item); +} + +STATIC BOOL DevLimitParentAllowsAddItem(ProcDevLimit *devParentLimit, DevAccessItem *item, INT32 currBehavior) +{ + return DevLimitVerifyNewItem(devParentLimit, item, currBehavior); +} + +STATIC VOID DevLimitAccessListRm(ProcDevLimit *devLimit, DevAccessItem *item) +{ + if ((item == NULL) || (devLimit == NULL)) { + return; + } + DevAccessItem *walk, *tmp = NULL; + LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(walk, tmp, &devLimit->accessList, DevAccessItem, list) { + if (walk->type != item->type) { + continue; + } + if (strcmp(walk->name, item->name) != 0) { + continue; + } + walk->access &= ~item->access; + if (!walk->access) { + LOS_ListDelete(&walk->list); + (VOID)LOS_MemFree(m_aucSysMem1, (VOID *)walk); + } + } +} + +STATIC UINT32 DevLimitAccessListAdd(ProcDevLimit *devLimit, DevAccessItem *item) +{ + if ((item == NULL) || (devLimit == NULL)) { + return ENOMEM; + } + + DevAccessItem *walk = NULL; + DevAccessItem *newItem = (DevAccessItem *)LOS_MemAlloc(m_aucSysMem1, sizeof(DevAccessItem)); + if (newItem == NULL) { + return ENOMEM; + } + (VOID)memcpy_s(newItem, sizeof(DevAccessItem), item, sizeof(DevAccessItem)); + LOS_DL_LIST_FOR_EACH_ENTRY(walk, &devLimit->accessList, DevAccessItem, list) { + if (walk->type != item->type) { + continue; + } + if (strcmp(walk->name, item->name) != 0) { + continue; + } + walk->access |= item->access; + (VOID)LOS_MemFree(m_aucSysMem1, (VOID *)newItem); + newItem = NULL; + } + + if (newItem != NULL) { + LOS_ListTailInsert(&devLimit->accessList, &newItem->list); + } + return LOS_OK; +} + +/** + * Revalidate permissions + */ +STATIC VOID DevLimitRevalidateActiveItems(ProcDevLimit *devLimit, ProcDevLimit *devParentLimit) +{ + if ((devLimit == NULL) || (devParentLimit == NULL)) { + return; + } + DevAccessItem *walK = NULL; + DevAccessItem *tmp = NULL; + LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(walK, tmp, &devLimit->accessList, DevAccessItem, list) { + if (!DevLimitParentAllowsAddItem(devParentLimit, walK, devLimit->behavior)) { + DevLimitAccessListRm(devLimit, walK); + } + } +} + +/** + * propagates a new item to the children + */ +STATIC UINT32 DevLimitPropagateItem(ProcLimitSet *procLimitSet, ProcDevLimit *devLimit, DevAccessItem *item) +{ + UINT32 ret = LOS_OK; + ProcLimitSet *parent = procLimitSet; + ProcLimitSet *childProcLimitSet = NULL; + + if ((procLimitSet == NULL) || (item == NULL)) { + return ENOMEM; + } + + if (devLimit == NULL) { + return LOS_OK; + } + + LOS_DL_LIST_FOR_EACH_ENTRY(childProcLimitSet, &procLimitSet->childList, ProcLimitSet, childList) { + if (childProcLimitSet == NULL) { + continue; + } + if (childProcLimitSet->parent != parent) { + continue; + } + if (!((childProcLimitSet->mask) & BIT(PROCESS_LIMITER_ID_DEV))) { + continue; + } + ProcDevLimit *devLimitChild = (ProcDevLimit *)childProcLimitSet->limitsList[PROCESS_LIMITER_ID_DEV]; + if (devLimit->behavior == DEVLIMIT_DEFAULT_ALLOW && + devLimitChild->behavior == DEVLIMIT_DEFAULT_ALLOW) { + ret = DevLimitAccessListAdd(devLimitChild, item); + } else { + DevLimitAccessListRm(devLimitChild, item); + } + DevLimitRevalidateActiveItems(devLimitChild, (ProcDevLimit *)parent->limitsList[PROCESS_LIMITER_ID_DEV]); + } + return ret; +} + +STATIC UINT32 DevLimitUpdateAccess(ProcLimitSet *procLimitSet, const CHAR *buf, INT32 filetype) +{ + UINT32 ret; + UINT32 intSave; + DevAccessItem item = {0}; + + SCHEDULER_LOCK(intSave); + ProcDevLimit *devLimit = (ProcDevLimit *)(procLimitSet->limitsList[PROCESS_LIMITER_ID_DEV]); + ProcDevLimit *devParentLimit = devLimit->parent; + + ret = ParseItemAccess(buf, &item); + if (ret != LOS_OK) { + SCHEDULER_UNLOCK(intSave); + return ret; + } + if (item.type == DEVLIMIT_DEV_ALL) { + ret = DealItemAllAccess(procLimitSet, devLimit, devParentLimit, filetype); + SCHEDULER_UNLOCK(intSave); + return ret; + } + switch (filetype) { + case DEVLIMIT_ALLOW: { + if (devLimit->behavior == DEVLIMIT_DEFAULT_ALLOW) { + if (!DevLimitParentAllowsRmItem(devParentLimit, &item)) { + SCHEDULER_UNLOCK(intSave); + return EPERM; + } + DevLimitAccessListRm(devLimit, &item); + break; + } + if (!DevLimitParentAllowsAddItem(devParentLimit, &item, devLimit->behavior)) { + SCHEDULER_UNLOCK(intSave); + return EPERM; + } + ret = DevLimitAccessListAdd(devLimit, &item); + break; + } + case DEVLIMIT_DENY: { + if (devLimit->behavior == DEVLIMIT_DEFAULT_DENY) { + DevLimitAccessListRm(devLimit, &item); + } else { + ret = DevLimitAccessListAdd(devLimit, &item); + } + // update child access list + ret = DevLimitPropagateItem(procLimitSet, devLimit, &item); + break; + } + default: + ret = EINVAL; + break; + } + SCHEDULER_UNLOCK(intSave); + return ret; +} + + +UINT32 OsDevLimitWriteAllow(ProcLimitSet *plimit, const CHAR *buf, UINT32 size) +{ + (VOID)size; + return DevLimitUpdateAccess(plimit, buf, DEVLIMIT_ALLOW); +} + +UINT32 OsDevLimitWriteDeny(ProcLimitSet *plimit, const CHAR *buf, UINT32 size) +{ + (VOID)size; + return DevLimitUpdateAccess(plimit, buf, DEVLIMIT_DENY); +} + +STATIC VOID DevLimitItemSetAccess(CHAR *accArray, INT16 access) +{ + INT32 index = 0; + (VOID)memset_s(acc, ACCLEN, 0, ACCLEN); + if (access & DEVLIMIT_ACC_READ) { + accArray[index] = 'r'; + index++; + } + if (access & DEVLIMIT_ACC_WRITE) { + accArray[index] = 'w'; + index++; + } + if (access & DEVLIMIT_ACC_MKNOD) { + accArray[index] = 'm'; + index++; + } +} + +STATIC CHAR DevLimitItemTypeToChar(INT16 type) +{ + switch (type) { + case DEVLIMIT_DEV_ALL: + return 'a'; + case DEVLIMIT_DEV_CHAR: + return 'c'; + case DEVLIMIT_DEV_BLOCK: + return 'b'; + default: + break; + } + return 'X'; +} + +UINT32 OsDevLimitShow(ProcDevLimit *devLimit, struct SeqBuf *seqBuf) +{ + DevAccessItem *item = NULL; + CHAR acc[ACCLEN]; + UINT32 intSave; + + if ((devLimit == NULL) || (seqBuf == NULL)) { + return EINVAL; + } + + SCHEDULER_LOCK(intSave); + if (devLimit->behavior == DEVLIMIT_DEFAULT_ALLOW) { + DevLimitItemSetAccess(acc, DEVLIMIT_ACC_MASK); + SCHEDULER_UNLOCK(intSave); + LosBufPrintf(seqBuf, "%c %s %s\n", DevLimitItemTypeToChar(DEVLIMIT_DEV_ALL), "*", acc); + return LOS_OK; + } + LOS_DL_LIST_FOR_EACH_ENTRY(item, &devLimit->accessList, DevAccessItem, list) { + DevLimitItemSetAccess(acc, item->access); + LosBufPrintf(seqBuf, "%c %s %s\n", DevLimitItemTypeToChar(item->type), item->name, acc); + } + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +STATIC INLINE INT16 ConversionDevType(INT32 vnodeType) +{ + INT16 type = 0; + if (vnodeType == VNODE_TYPE_BLK) { + type = DEVLIMIT_DEV_BLOCK; + } else if (vnodeType == VNODE_TYPE_CHR) { + type = DEVLIMIT_DEV_CHAR; + } + return type; +} + +STATIC INLINE INT16 ConversionDevAccess(INT32 flags) +{ + INT16 access = 0; + if ((flags & O_ACCMODE) == O_RDONLY) { + access |= DEVLIMIT_ACC_READ; + } + if (flags & O_WRONLY) { + access |= DEVLIMIT_ACC_WRITE; + } + if (flags & O_RDWR) { + access |= DEVLIMIT_ACC_WRITE | DEVLIMIT_ACC_READ; + } + if (flags & O_CREAT) { + access |= DEVLIMIT_ACC_MKNOD; + } + return access; +} + +UINT32 OsDevLimitCheckPermission(INT32 vnodeType, const CHAR *pathName, INT32 flags) +{ + BOOL matched = FALSE; + DevAccessItem item = {0}; + LosProcessCB *run = OsCurrProcessGet(); + if ((run == NULL) || (run->plimits == NULL)) { + return LOS_OK; + } + + if (pathName == NULL) { + return EINVAL; + } + + ProcDevLimit *devLimit = (ProcDevLimit *)run->plimits->limitsList[PROCESS_LIMITER_ID_DEV]; + + item.type = ConversionDevType(vnodeType); + item.access = ConversionDevAccess(flags); + LOS_ListInit(&(item.list)); + (VOID)strncpy_s(item.name, PATH_MAX, pathName, PATH_MAX); + + if (devLimit->behavior == DEVLIMIT_DEFAULT_ALLOW) { + matched = !DevLimitMatchItemPartial(&devLimit->accessList, &item); + } else { + matched = DevLimitMatchItem(&devLimit->accessList, &item); + } + if (!matched) { + return EPERM; + } + return LOS_OK; +} +#endif diff --git a/src/kernel_liteos_a/kernel/extended/plimit/los_devicelimit.h b/src/kernel_liteos_a/kernel/extended/plimit/los_devicelimit.h new file mode 100644 index 00000000..06247398 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/plimit/los_devicelimit.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_DEVICELIMIT_H +#define _LOS_DEVICELIMIT_H + +#include "los_typedef.h" +#include "los_list.h" +#include "vfs_config.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define DEVLIMIT_ACC_MKNOD 1 +#define DEVLIMIT_ACC_READ 2 +#define DEVLIMIT_ACC_WRITE 4 +#define DEVLIMIT_ACC_MASK (DEVLIMIT_ACC_MKNOD | DEVLIMIT_ACC_READ | DEVLIMIT_ACC_WRITE) + +#define DEVLIMIT_DEV_BLOCK 1 +#define DEVLIMIT_DEV_CHAR 2 +#define DEVLIMIT_DEV_ALL 4 /* all devices */ + +#define DEVLIMIT_ALLOW 1 +#define DEVLIMIT_DENY 2 + +#define ACCLEN 4 + +struct SeqBuf; +typedef struct TagPLimiterSet ProcLimitSet; + +enum DevLimitBehavior { + DEVLIMIT_DEFAULT_NONE, + DEVLIMIT_DEFAULT_ALLOW, + DEVLIMIT_DEFAULT_DENY, +}; + +typedef struct DevAccessItem { + INT16 type; + INT16 access; + LOS_DL_LIST list; + CHAR name[PATH_MAX]; +} DevAccessItem; + +typedef struct ProcDevLimit { + struct ProcDevLimit *parent; + UINT8 allowFile; + UINT8 denyFile; + LOS_DL_LIST accessList; // device belong to devicelimite + enum DevLimitBehavior behavior; +} ProcDevLimit; + +VOID OsDevLimitInit(UINTPTR limit); +VOID *OsDevLimitAlloc(VOID); +VOID OsDevLimitFree(UINTPTR limit); +VOID OsDevLimitCopy(UINTPTR dest, UINTPTR src); +UINT32 OsDevLimitWriteAllow(ProcLimitSet *plimit, const CHAR *buf, UINT32 size); +UINT32 OsDevLimitWriteDeny(ProcLimitSet *plimit, const CHAR *buf, UINT32 size); +UINT32 OsDevLimitShow(ProcDevLimit *devLimit, struct SeqBuf *seqBuf); +UINT32 OsDevLimitCheckPermission(INT32 vnodeType, const CHAR *pathName, INT32 flags); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ +#endif /* _LOS_DEVICELIMIT_H */ diff --git a/src/kernel_liteos_a/kernel/extended/plimit/los_ipclimit.c b/src/kernel_liteos_a/kernel/extended/plimit/los_ipclimit.c new file mode 100644 index 00000000..746d0452 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/plimit/los_ipclimit.c @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef LOSCFG_KERNEL_IPC_PLIMIT +#include "los_ipclimit.h" +#include "los_process_pri.h" + +STATIC ProcIPCLimit *g_rootIPCLimit = NULL; +#define PLIMIT_IPC_SHM_LIMIT_MAX 0xFFFFFFFF + +VOID OsIPCLimitInit(UINTPTR limite) +{ + ProcIPCLimit *plimite = (ProcIPCLimit *)limite; + plimite->mqCountLimit = LOSCFG_BASE_IPC_QUEUE_LIMIT; + plimite->shmSizeLimit = PLIMIT_IPC_SHM_LIMIT_MAX; + g_rootIPCLimit = plimite; +} + +VOID *OsIPCLimitAlloc(VOID) +{ + ProcIPCLimit *plimite = (ProcIPCLimit *)LOS_MemAlloc(m_aucSysMem1, sizeof(ProcIPCLimit)); + if (plimite == NULL) { + return NULL; + } + (VOID)memset_s(plimite, sizeof(ProcIPCLimit), 0, sizeof(ProcIPCLimit)); + return (VOID *)plimite; +} + +VOID OsIPCLimitFree(UINTPTR limite) +{ + ProcIPCLimit *plimite = (ProcIPCLimit *)limite; + if (plimite == NULL) { + return; + } + + (VOID)LOS_MemFree(m_aucSysMem1, (VOID *)plimite); +} + +VOID OsIPCLimitCopy(UINTPTR dest, UINTPTR src) +{ + ProcIPCLimit *plimiteDest = (ProcIPCLimit *)dest; + ProcIPCLimit *plimiteSrc = (ProcIPCLimit *)src; + plimiteDest->mqCountLimit = plimiteSrc->mqCountLimit; + plimiteDest->shmSizeLimit = plimiteSrc->shmSizeLimit; + return; +} + +BOOL OsIPCLimiteMigrateCheck(UINTPTR curr, UINTPTR parent) +{ + ProcIPCLimit *currIpcLimit = (ProcIPCLimit *)curr; + ProcIPCLimit *parentIpcLimit = (ProcIPCLimit *)parent; + if ((currIpcLimit->mqCount + parentIpcLimit->mqCount) >= parentIpcLimit->mqCountLimit) { + return FALSE; + } + + if ((currIpcLimit->shmSize + parentIpcLimit->shmSize) >= parentIpcLimit->shmSizeLimit) { + return FALSE; + } + return TRUE; +} + +VOID OsIPCLimitMigrate(UINTPTR currLimit, UINTPTR parentLimit, UINTPTR process) +{ + ProcIPCLimit *currIpcLimit = (ProcIPCLimit *)currLimit; + ProcIPCLimit *parentIpcLimit = (ProcIPCLimit *)parentLimit; + LosProcessCB *pcb = (LosProcessCB *)process; + + if (pcb == NULL) { + parentIpcLimit->mqCount += currIpcLimit->mqCount; + parentIpcLimit->mqFailedCount += currIpcLimit->mqFailedCount; + parentIpcLimit->shmSize += currIpcLimit->shmSize; + parentIpcLimit->shmFailedCount += currIpcLimit->shmFailedCount; + return; + } + + parentIpcLimit->mqCount -= pcb->limitStat.mqCount; + parentIpcLimit->shmSize -= pcb->limitStat.shmSize; + currIpcLimit->mqCount += pcb->limitStat.mqCount; + currIpcLimit->shmSize += pcb->limitStat.shmSize; +} + +BOOL OsIPCLimitAddProcessCheck(UINTPTR limit, UINTPTR process) +{ + ProcIPCLimit *ipcLimit = (ProcIPCLimit *)limit; + LosProcessCB *pcb = (LosProcessCB *)process; + if ((ipcLimit->mqCount + pcb->limitStat.mqCount) >= ipcLimit->mqCountLimit) { + return FALSE; + } + + if ((ipcLimit->shmSize + pcb->limitStat.shmSize) >= ipcLimit->shmSizeLimit) { + return FALSE; + } + + return TRUE; +} + +VOID OsIPCLimitAddProcess(UINTPTR limit, UINTPTR process) +{ + LosProcessCB *pcb = (LosProcessCB *)process; + ProcIPCLimit *plimits = (ProcIPCLimit *)limit; + plimits->mqCount += pcb->limitStat.mqCount; + plimits->shmSize += pcb->limitStat.shmSize; + return; +} + +VOID OsIPCLimitDelProcess(UINTPTR limit, UINTPTR process) +{ + LosProcessCB *pcb = (LosProcessCB *)process; + ProcIPCLimit *plimits = (ProcIPCLimit *)limit; + + plimits->mqCount -= pcb->limitStat.mqCount; + plimits->shmSize -= pcb->limitStat.shmSize; + return; +} + +UINT32 OsIPCLimitSetMqLimit(ProcIPCLimit *ipcLimit, UINT32 value) +{ + UINT32 intSave; + + if ((ipcLimit == NULL) || (value == 0) || (value > LOSCFG_BASE_IPC_QUEUE_LIMIT)) { + return EINVAL; + } + + if (ipcLimit == g_rootIPCLimit) { + return EPERM; + } + + SCHEDULER_LOCK(intSave); + if (value < ipcLimit->mqCount) { + SCHEDULER_UNLOCK(intSave); + return EINVAL; + } + + ipcLimit->mqCountLimit = value; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +UINT32 OsIPCLimitSetShmLimit(ProcIPCLimit *ipcLimit, UINT32 value) +{ + UINT32 intSave; + + if ((ipcLimit == NULL) || (value == 0) || (value > PLIMIT_IPC_SHM_LIMIT_MAX)) { + return EINVAL; + } + + if (ipcLimit == g_rootIPCLimit) { + return EPERM; + } + + SCHEDULER_LOCK(intSave); + if (value < ipcLimit->shmSize) { + SCHEDULER_UNLOCK(intSave); + return EINVAL; + } + + ipcLimit->shmSizeLimit = value; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +UINT32 OsIPCLimitMqAlloc(VOID) +{ + UINT32 intSave; + SCHEDULER_LOCK(intSave); + LosProcessCB *run = OsCurrProcessGet(); + ProcIPCLimit *ipcLimit = (ProcIPCLimit *)run->plimits->limitsList[PROCESS_LIMITER_ID_IPC]; + if (ipcLimit->mqCount >= ipcLimit->mqCountLimit) { + ipcLimit->mqFailedCount++; + SCHEDULER_UNLOCK(intSave); + return EINVAL; + } + + run->limitStat.mqCount++; + ipcLimit->mqCount++; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +VOID OsIPCLimitMqFree(VOID) +{ + UINT32 intSave; + SCHEDULER_LOCK(intSave); + LosProcessCB *run = OsCurrProcessGet(); + ProcIPCLimit *ipcLimit = (ProcIPCLimit *)run->plimits->limitsList[PROCESS_LIMITER_ID_IPC]; + ipcLimit->mqCount--; + run->limitStat.mqCount--; + SCHEDULER_UNLOCK(intSave); + return; +} + +UINT32 OsIPCLimitShmAlloc(UINT32 size) +{ + UINT32 intSave; + SCHEDULER_LOCK(intSave); + LosProcessCB *run = OsCurrProcessGet(); + ProcIPCLimit *ipcLimit = (ProcIPCLimit *)run->plimits->limitsList[PROCESS_LIMITER_ID_IPC]; + if ((ipcLimit->shmSize + size) >= ipcLimit->shmSizeLimit) { + ipcLimit->shmFailedCount++; + SCHEDULER_UNLOCK(intSave); + return EINVAL; + } + + run->limitStat.shmSize += size; + ipcLimit->shmSize += size; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +VOID OsIPCLimitShmFree(UINT32 size) +{ + UINT32 intSave; + SCHEDULER_LOCK(intSave); + LosProcessCB *run = OsCurrProcessGet(); + ProcIPCLimit *ipcLimit = (ProcIPCLimit *)run->plimits->limitsList[PROCESS_LIMITER_ID_IPC]; + ipcLimit->shmSize -= size; + run->limitStat.shmSize -= size; + SCHEDULER_UNLOCK(intSave); + return; +} + +#endif diff --git a/src/kernel_liteos_a/kernel/extended/plimit/los_ipclimit.h b/src/kernel_liteos_a/kernel/extended/plimit/los_ipclimit.h new file mode 100644 index 00000000..b91da73d --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/plimit/los_ipclimit.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_IPCLIMIT_H +#define _LOS_IPCLIMIT_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef struct ProcIPCLimit { + UINT32 mqCount; + UINT32 mqFailedCount; + UINT32 mqCountLimit; + UINT32 shmSize; + UINT32 shmFailedCount; + UINT32 shmSizeLimit; +} ProcIPCLimit; + +enum IPCStatType { + IPC_STAT_TYPE_MQ = 0, + IPC_STAT_TYPE_SHM = 3, + IPC_STAT_TYPE_BUT // buttock +}; + +enum IPCStatOffset { + IPC_STAT_OFFSET_MQ = 0, + IPC_STAT_OFFSET_SHM = 3, + IPC_STAT_OFFSET_BUT // buttock +}; + +enum StatItem { + STAT_ITEM_TOTAL, + STAT_ITEM_FAILED, + STAT_ITEM_LIMIT, + STAT_ITEM_BUT // buttock +}; + +VOID OsIPCLimitInit(UINTPTR limite); +VOID *OsIPCLimitAlloc(VOID); +VOID OsIPCLimitFree(UINTPTR limite); +VOID OsIPCLimitCopy(UINTPTR dest, UINTPTR src); +BOOL OsIPCLimiteMigrateCheck(UINTPTR curr, UINTPTR parent); +VOID OsIPCLimitMigrate(UINTPTR currLimit, UINTPTR parentLimit, UINTPTR process); +BOOL OsIPCLimitAddProcessCheck(UINTPTR limit, UINTPTR process); +VOID OsIPCLimitAddProcess(UINTPTR limit, UINTPTR process); +VOID OsIPCLimitDelProcess(UINTPTR limit, UINTPTR process); +UINT32 OsIPCLimitSetMqLimit(ProcIPCLimit *ipcLimit, UINT32 value); +UINT32 OsIPCLimitSetShmLimit(ProcIPCLimit *ipcLimit, UINT32 value); +UINT32 OsIPCLimitMqAlloc(VOID); +VOID OsIPCLimitMqFree(VOID); +UINT32 OsIPCLimitShmAlloc(UINT32 size); +VOID OsIPCLimitShmFree(UINT32 size); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_IPCIMIT_H */ diff --git a/src/kernel_liteos_a/kernel/extended/plimit/los_memlimit.c b/src/kernel_liteos_a/kernel/extended/plimit/los_memlimit.c new file mode 100644 index 00000000..4a034274 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/plimit/los_memlimit.c @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef LOSCFG_KERNEL_MEM_PLIMIT +#include +#include +#include "los_config.h" +#include "los_hook.h" +#include "los_process_pri.h" +#include "los_plimits.h" + +STATIC ProcMemLimiter *g_procMemLimiter = NULL; + +VOID OsMemLimiterInit(UINTPTR limite) +{ + ProcMemLimiter *procMemLimiter = (ProcMemLimiter *)limite; + procMemLimiter->limit = OS_NULL_INT; + g_procMemLimiter = procMemLimiter; +} + +VOID OsMemLimitSetLimit(UINT32 limit) +{ + g_procMemLimiter->limit = limit; +} + +VOID *OsMemLimiterAlloc(VOID) +{ + ProcMemLimiter *plimite = (ProcMemLimiter *)LOS_MemAlloc(m_aucSysMem1, sizeof(ProcMemLimiter)); + if (plimite == NULL) { + return NULL; + } + (VOID)memset_s(plimite, sizeof(ProcMemLimiter), 0, sizeof(ProcMemLimiter)); + return (VOID *)plimite; +} + +VOID OsMemLimiterFree(UINTPTR limite) +{ + ProcMemLimiter *plimite = (ProcMemLimiter *)limite; + if (plimite == NULL) { + return; + } + + (VOID)LOS_MemFree(m_aucSysMem1, (VOID *)limite); +} + +VOID OsMemLimiterCopy(UINTPTR dest, UINTPTR src) +{ + ProcMemLimiter *plimiteDest = (ProcMemLimiter *)dest; + ProcMemLimiter *plimiteSrc = (ProcMemLimiter *)src; + plimiteDest->limit = plimiteSrc->limit; + return; +} + +BOOL MemLimiteMigrateCheck(UINTPTR curr, UINTPTR parent) +{ + ProcMemLimiter *currMemLimit = (ProcMemLimiter *)curr; + ProcMemLimiter *parentMemLimit = (ProcMemLimiter *)parent; + if ((currMemLimit->usage + parentMemLimit->usage) >= parentMemLimit->limit) { + return FALSE; + } + return TRUE; +} + +VOID OsMemLimiterMigrate(UINTPTR currLimit, UINTPTR parentLimit, UINTPTR process) +{ + ProcMemLimiter *currMemLimit = (ProcMemLimiter *)currLimit; + ProcMemLimiter *parentMemLimit = (ProcMemLimiter *)parentLimit; + LosProcessCB *pcb = (LosProcessCB *)process; + + if (pcb == NULL) { + parentMemLimit->usage += currMemLimit->usage; + parentMemLimit->failcnt += currMemLimit->failcnt; + if (parentMemLimit->peak < parentMemLimit->usage) { + parentMemLimit->peak = parentMemLimit->usage; + } + return; + } + + parentMemLimit->usage -= pcb->limitStat.memUsed; + currMemLimit->usage += pcb->limitStat.memUsed; +} + +BOOL OsMemLimitAddProcessCheck(UINTPTR limit, UINTPTR process) +{ + ProcMemLimiter *memLimit = (ProcMemLimiter *)limit; + LosProcessCB *pcb = (LosProcessCB *)process; + if ((memLimit->usage + pcb->limitStat.memUsed) > memLimit->limit) { + return FALSE; + } + return TRUE; +} + +VOID OsMemLimitAddProcess(UINTPTR limit, UINTPTR process) +{ + LosProcessCB *pcb = (LosProcessCB *)process; + ProcMemLimiter *plimits = (ProcMemLimiter *)limit; + plimits->usage += pcb->limitStat.memUsed; + if (plimits->peak < plimits->usage) { + plimits->peak = plimits->usage; + } + return; +} + +VOID OsMemLimitDelProcess(UINTPTR limit, UINTPTR process) +{ + LosProcessCB *pcb = (LosProcessCB *)process; + ProcMemLimiter *plimits = (ProcMemLimiter *)limit; + + plimits->usage -= pcb->limitStat.memUsed; + return; +} + +UINT32 OsMemLimitSetMemLimit(ProcMemLimiter *memLimit, UINT64 value) +{ + UINT32 intSave; + if ((memLimit == NULL) || (value == 0)) { + return EINVAL; + } + + if (memLimit == g_procMemLimiter) { + return EPERM; + } + + SCHEDULER_LOCK(intSave); + if (value < memLimit->usage) { + SCHEDULER_UNLOCK(intSave); + return EINVAL; + } + + memLimit->limit = value; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +#define MEM_LIMIT_LOCK(state, locked) do { \ + if (SCHEDULER_HELD()) { \ + locked = TRUE; \ + } else { \ + SCHEDULER_LOCK(state); \ + } \ +} while (0) + +#define MEM_LIMIT_UNLOCK(state, locked) do { \ + if (!locked) { \ + SCHEDULER_UNLOCK(state); \ + } \ +} while (0) + +UINT32 OsMemLimitCheckAndMemAdd(UINT32 size) +{ + UINT32 intSave; + BOOL locked = FALSE; + MEM_LIMIT_LOCK(intSave, locked); + LosProcessCB *run = OsCurrProcessGet(); + UINT32 currProcessID = run->processID; + if ((run == NULL) || (run->plimits == NULL)) { + MEM_LIMIT_UNLOCK(intSave, locked); + return LOS_OK; + } + + ProcMemLimiter *memLimit = (ProcMemLimiter *)run->plimits->limitsList[PROCESS_LIMITER_ID_MEM]; + if ((memLimit->usage + size) > memLimit->limit) { + memLimit->failcnt++; + MEM_LIMIT_UNLOCK(intSave, locked); + PRINT_ERR("plimits: process %u adjust the memory limit of Plimits group\n", currProcessID); + return ENOMEM; + } + + memLimit->usage += size; + run->limitStat.memUsed += size; + if (memLimit->peak < memLimit->usage) { + memLimit->peak = memLimit->usage; + } + MEM_LIMIT_UNLOCK(intSave, locked); + return LOS_OK; +} + +VOID OsMemLimitMemFree(UINT32 size) +{ + UINT32 intSave; + BOOL locked = FALSE; + MEM_LIMIT_LOCK(intSave, locked); + LosProcessCB *run = OsCurrProcessGet(); + if ((run == NULL) || (run->plimits == NULL)) { + MEM_LIMIT_UNLOCK(intSave, locked); + return; + } + + ProcMemLimiter *memLimit = (ProcMemLimiter *)run->plimits->limitsList[PROCESS_LIMITER_ID_MEM]; + if (run->limitStat.memUsed > size) { + run->limitStat.memUsed -= size; + memLimit->usage -= size; + } + MEM_LIMIT_UNLOCK(intSave, locked); +} +#endif diff --git a/src/kernel_liteos_a/kernel/extended/plimit/los_memlimit.h b/src/kernel_liteos_a/kernel/extended/plimit/los_memlimit.h new file mode 100644 index 00000000..f176cc01 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/plimit/los_memlimit.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_MEMLIMIT_H +#define _LOS_MEMLIMIT_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef struct ProcMemLimiter { + UINT64 usage; + UINT64 limit; + UINT64 peak; + UINT32 failcnt; +} ProcMemLimiter; + +VOID OsMemLimiterInit(UINTPTR limite); +VOID *OsMemLimiterAlloc(VOID); +VOID OsMemLimiterFree(UINTPTR limite); +VOID OsMemLimiterCopy(UINTPTR dest, UINTPTR src); +BOOL MemLimiteMigrateCheck(UINTPTR curr, UINTPTR parent); +VOID OsMemLimiterMigrate(UINTPTR currLimit, UINTPTR parentLimit, UINTPTR process); +BOOL OsMemLimitAddProcessCheck(UINTPTR limit, UINTPTR process); +VOID OsMemLimitAddProcess(UINTPTR limit, UINTPTR process); +VOID OsMemLimitDelProcess(UINTPTR limit, UINTPTR process); +UINT32 OsMemLimitSetMemLimit(ProcMemLimiter *memLimit, UINT64 value); +VOID OsMemLimitSetLimit(UINTPTR limit); +UINT32 OsMemLimitCheckAndMemAdd(UINT32 size); +VOID OsMemLimitMemFree(UINT32 size); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_MEMLIMIT_H */ diff --git a/src/kernel_liteos_a/kernel/extended/plimit/los_plimits.c b/src/kernel_liteos_a/kernel/extended/plimit/los_plimits.c new file mode 100644 index 00000000..50299eb7 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/plimit/los_plimits.c @@ -0,0 +1,434 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef LOSCFG_KERNEL_PLIMITS +#include "los_base.h" +#include "los_process_pri.h" +#include "hal_timer.h" +#include "los_plimits.h" + +typedef struct PlimiteOperations { + VOID (*LimiterInit)(UINTPTR); + VOID *(*LimiterAlloc)(VOID); + VOID (*LimiterFree)(UINTPTR); + VOID (*LimiterCopy)(UINTPTR, UINTPTR); + BOOL (*LimiterAddProcessCheck)(UINTPTR, UINTPTR); + VOID (*LimiterAddProcess)(UINTPTR, UINTPTR); + VOID (*LimiterDelProcess)(UINTPTR, UINTPTR); + BOOL (*LimiterMigrateCheck)(UINTPTR, UINTPTR); + VOID (*LimiterMigrate)(UINTPTR, UINTPTR, UINTPTR); +} PlimiteOperations; + +static PlimiteOperations g_limiteOps[PROCESS_LIMITER_COUNT] = { + [PROCESS_LIMITER_ID_PIDS] = { + .LimiterInit = PidLimiterInit, + .LimiterAlloc = PidLimiterAlloc, + .LimiterFree = PidLimterFree, + .LimiterCopy = PidLimiterCopy, + .LimiterAddProcessCheck = OsPidLimitAddProcessCheck, + .LimiterAddProcess = OsPidLimitAddProcess, + .LimiterDelProcess = OsPidLimitDelProcess, + .LimiterMigrateCheck = PidLimitMigrateCheck, + .LimiterMigrate = NULL, + }, +#ifdef LOSCFG_KERNEL_MEM_PLIMIT + [PROCESS_LIMITER_ID_MEM] = { + .LimiterInit = OsMemLimiterInit, + .LimiterAlloc = OsMemLimiterAlloc, + .LimiterFree = OsMemLimiterFree, + .LimiterCopy = OsMemLimiterCopy, + .LimiterAddProcessCheck = OsMemLimitAddProcessCheck, + .LimiterAddProcess = OsMemLimitAddProcess, + .LimiterDelProcess = OsMemLimitDelProcess, + .LimiterMigrateCheck = MemLimiteMigrateCheck, + .LimiterMigrate = OsMemLimiterMigrate, + }, +#endif +#ifdef LOSCFG_KERNEL_SCHED_PLIMIT + [PROCESS_LIMITER_ID_SCHED] = { + .LimiterInit = OsSchedLimitInit, + .LimiterAlloc = OsSchedLimitAlloc, + .LimiterFree = OsSchedLimitFree, + .LimiterCopy = OsSchedLimitCopy, + .LimiterAddProcessCheck = NULL, + .LimiterAddProcess = NULL, + .LimiterDelProcess = NULL, + .LimiterMigrateCheck = NULL, + .LimiterMigrate = NULL, + }, +#endif +#ifdef LOSCFG_KERNEL_DEV_PLIMIT + [PROCESS_LIMITER_ID_DEV] = { + .LimiterInit = OsDevLimitInit, + .LimiterAlloc = OsDevLimitAlloc, + .LimiterFree = OsDevLimitFree, + .LimiterCopy = OsDevLimitCopy, + .LimiterAddProcessCheck = NULL, + .LimiterAddProcess = NULL, + .LimiterDelProcess = NULL, + .LimiterMigrateCheck = NULL, + .LimiterMigrate = NULL, + }, +#endif +#ifdef LOSCFG_KERNEL_IPC_PLIMIT + [PROCESS_LIMITER_ID_IPC] = { + .LimiterInit = OsIPCLimitInit, + .LimiterAlloc = OsIPCLimitAlloc, + .LimiterFree = OsIPCLimitFree, + .LimiterCopy = OsIPCLimitCopy, + .LimiterAddProcessCheck = OsIPCLimitAddProcessCheck, + .LimiterAddProcess = OsIPCLimitAddProcess, + .LimiterDelProcess = OsIPCLimitDelProcess, + .LimiterMigrateCheck = OsIPCLimiteMigrateCheck, + .LimiterMigrate = OsIPCLimitMigrate, + }, +#endif +}; + +STATIC ProcLimiterSet *g_rootPLimite = NULL; + +ProcLimiterSet *OsRootPLimitsGet(VOID) +{ + return g_rootPLimite; +} + +UINT32 OsProcLimiterSetInit(VOID) +{ + g_rootPLimite = (ProcLimiterSet *)LOS_MemAlloc(m_aucSysMem1, sizeof(ProcLimiterSet)); + if (g_rootPLimite == NULL) { + return ENOMEM; + } + (VOID)memset_s(g_rootPLimite, sizeof(ProcLimiterSet), 0, sizeof(ProcLimiterSet)); + + LOS_ListInit(&g_rootPLimite->childList); + LOS_ListInit(&g_rootPLimite->processList); + + ProcLimiterSet *procLimiterSet = g_rootPLimite; + for (INT32 plimiteID = 0; plimiteID < PROCESS_LIMITER_COUNT; ++plimiteID) { + procLimiterSet->limitsList[plimiteID] = (UINTPTR)g_limiteOps[plimiteID].LimiterAlloc(); + if (procLimiterSet->limitsList[plimiteID] == (UINTPTR)NULL) { + OsPLimitsFree(procLimiterSet); + return ENOMEM; + } + + if (g_limiteOps[plimiteID].LimiterInit != NULL) { + g_limiteOps[plimiteID].LimiterInit(procLimiterSet->limitsList[plimiteID]); + } + } + return LOS_OK; +} + +STATIC VOID PLimitsDeleteProcess(LosProcessCB *processCB) +{ + if ((processCB == NULL) || (processCB->plimits == NULL)) { + return; + } + + ProcLimiterSet *plimits = processCB->plimits; + for (UINT32 limitsID = 0; limitsID < PROCESS_LIMITER_COUNT; limitsID++) { + if (g_limiteOps[limitsID].LimiterDelProcess == NULL) { + continue; + } + g_limiteOps[limitsID].LimiterDelProcess(plimits->limitsList[limitsID], (UINTPTR)processCB); + } + plimits->pidCount--; + LOS_ListDelete(&processCB->plimitsList); + processCB->plimits = NULL; + return; +} + +STATIC UINT32 PLimitsAddProcess(ProcLimiterSet *plimits, LosProcessCB *processCB) +{ + UINT32 limitsID; + if (plimits == NULL) { + plimits = g_rootPLimite; + } + + if (processCB->plimits == g_rootPLimite) { + return EPERM; + } + + if (processCB->plimits == plimits) { + return LOS_OK; + } + + for (limitsID = 0; limitsID < PROCESS_LIMITER_COUNT; limitsID++) { + if (g_limiteOps[limitsID].LimiterAddProcessCheck == NULL) { + continue; + } + + if (!g_limiteOps[limitsID].LimiterAddProcessCheck(plimits->limitsList[limitsID], (UINTPTR)processCB)) { + return EACCES; + } + } + + PLimitsDeleteProcess(processCB); + + for (limitsID = 0; limitsID < PROCESS_LIMITER_COUNT; limitsID++) { + if (g_limiteOps[limitsID].LimiterAddProcess == NULL) { + continue; + } + g_limiteOps[limitsID].LimiterAddProcess(plimits->limitsList[limitsID], (UINTPTR)processCB); + } + + LOS_ListTailInsert(&plimits->processList, &processCB->plimitsList); + plimits->pidCount++; + processCB->plimits = plimits; + return LOS_OK; +} + +UINT32 OsPLimitsAddProcess(ProcLimiterSet *plimits, LosProcessCB *processCB) +{ + UINT32 intSave; + SCHEDULER_LOCK(intSave); + UINT32 ret = PLimitsAddProcess(plimits, processCB); + SCHEDULER_UNLOCK(intSave); + return ret; +} + +UINT32 OsPLimitsAddPid(ProcLimiterSet *plimits, UINT32 pid) +{ + UINT32 intSave, ret; + if ((plimits == NULL) || OS_PID_CHECK_INVALID(pid) || (pid == 0)) { + return EINVAL; + } + + if (plimits == g_rootPLimite) { + return EPERM; + } + + SCHEDULER_LOCK(intSave); + LosProcessCB *processCB = OS_PCB_FROM_PID((unsigned int)pid); + if (OsProcessIsInactive(processCB)) { + SCHEDULER_UNLOCK(intSave); + return EINVAL; + } + + ret = PLimitsAddProcess(plimits, processCB); + SCHEDULER_UNLOCK(intSave); + return ret; +} + +VOID OsPLimitsDeleteProcess(LosProcessCB *processCB) +{ + UINT32 intSave; + SCHEDULER_LOCK(intSave); + PLimitsDeleteProcess(processCB); + SCHEDULER_UNLOCK(intSave); +} + +UINT32 OsPLimitsPidsGet(const ProcLimiterSet *plimits, UINT32 *pids, UINT32 size) +{ + UINT32 intSave; + LosProcessCB *processCB = NULL; + UINT32 minSize = LOS_GetSystemProcessMaximum() * sizeof(UINT32); + if ((plimits == NULL) || (pids == NULL) || (size < minSize)) { + return EINVAL; + } + + SCHEDULER_LOCK(intSave); + LOS_DL_LIST *listHead = (LOS_DL_LIST *)&plimits->processList; + if (LOS_ListEmpty(listHead)) { + SCHEDULER_UNLOCK(intSave); + return EINVAL; + } + + LOS_DL_LIST_FOR_EACH_ENTRY(processCB, listHead, LosProcessCB, plimitsList) { + pids[OsGetPid(processCB)] = 1; + } + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +STATIC VOID PLimitsProcessMerge(ProcLimiterSet *currPLimits, ProcLimiterSet *parentPLimits) +{ + LOS_DL_LIST *head = &currPLimits->processList; + while (!LOS_ListEmpty(head)) { + LosProcessCB *processCB = LOS_DL_LIST_ENTRY(head->pstNext, LosProcessCB, plimitsList); + PLimitsDeleteProcess(processCB); + PLimitsAddProcess(parentPLimits, processCB); + } + LOS_ListDelete(&currPLimits->childList); + currPLimits->parent = NULL; + return; +} + +STATIC UINT32 PLimitsMigrateCheck(ProcLimiterSet *currPLimits, ProcLimiterSet *parentPLimits) +{ + for (UINT32 limiteID = 0; limiteID < PROCESS_LIMITER_COUNT; limiteID++) { + UINTPTR currLimit = currPLimits->limitsList[limiteID]; + UINTPTR parentLimit = parentPLimits->limitsList[limiteID]; + if (g_limiteOps[limiteID].LimiterMigrateCheck == NULL) { + continue; + } + + if (!g_limiteOps[limiteID].LimiterMigrateCheck(currLimit, parentLimit)) { + return EPERM; + } + } + return LOS_OK; +} + +UINT32 OsPLimitsFree(ProcLimiterSet *currPLimits) +{ + UINT32 intSave, ret; + if (currPLimits == NULL) { + return EINVAL; + } + + SCHEDULER_LOCK(intSave); + ProcLimiterSet *parentPLimits = currPLimits->parent; + ret = PLimitsMigrateCheck(currPLimits, parentPLimits); + if (ret != LOS_OK) { + SCHEDULER_UNLOCK(intSave); + return ret; + } + + PLimitsProcessMerge(currPLimits, parentPLimits); + SCHEDULER_UNLOCK(intSave); + + for (INT32 limiteID = 0; limiteID < PROCESS_LIMITER_COUNT; ++limiteID) { + UINTPTR procLimiter = currPLimits->limitsList[limiteID]; + if (g_limiteOps[limiteID].LimiterFree != NULL) { + g_limiteOps[limiteID].LimiterFree(procLimiter); + } + } + (VOID)LOS_MemFree(m_aucSysMem1, currPLimits); + return LOS_OK; +} + +ProcLimiterSet *OsPLimitsCreate(ProcLimiterSet *parentPLimits) +{ + UINT32 intSave; + + ProcLimiterSet *newPLimits = (ProcLimiterSet *)LOS_MemAlloc(m_aucSysMem1, sizeof(ProcLimiterSet)); + if (newPLimits == NULL) { + return NULL; + } + (VOID)memset_s(newPLimits, sizeof(ProcLimiterSet), 0, sizeof(ProcLimiterSet)); + LOS_ListInit(&newPLimits->childList); + LOS_ListInit(&newPLimits->processList); + + SCHEDULER_LOCK(intSave); + newPLimits->parent = parentPLimits; + newPLimits->level = parentPLimits->level + 1; + newPLimits->mask = parentPLimits->mask; + + for (INT32 plimiteID = 0; plimiteID < PROCESS_LIMITER_COUNT; ++plimiteID) { + newPLimits->limitsList[plimiteID] = (UINTPTR)g_limiteOps[plimiteID].LimiterAlloc(); + if (newPLimits->limitsList[plimiteID] == (UINTPTR)NULL) { + SCHEDULER_UNLOCK(intSave); + OsPLimitsFree(newPLimits); + return NULL; + } + + if (g_limiteOps[plimiteID].LimiterCopy != NULL) { + g_limiteOps[plimiteID].LimiterCopy(newPLimits->limitsList[plimiteID], + parentPLimits->limitsList[plimiteID]); + } + } + LOS_ListTailInsert(&g_rootPLimite->childList, &newPLimits->childList); + + (VOID)PLimitsDeleteProcess(OsCurrProcessGet()); + (VOID)PLimitsAddProcess(newPLimits, OsCurrProcessGet()); + SCHEDULER_UNLOCK(intSave); + return newPLimits; +} + +#ifdef LOSCFG_KERNEL_MEM_PLIMIT +UINT32 OsPLimitsMemUsageGet(ProcLimiterSet *plimits, UINT64 *usage, UINT32 size) +{ + UINT32 intSave; + LosProcessCB *processCB = NULL; + UINT32 minSize = LOS_GetSystemProcessMaximum() * sizeof(UINT64) + sizeof(ProcMemLimiter); + ProcMemLimiter *memLimit = (ProcMemLimiter *)usage; + UINT64 *memSuage = (UINT64 *)((UINTPTR)usage + sizeof(ProcMemLimiter)); + if ((plimits == NULL) || (usage == NULL) || (size < minSize)) { + return EINVAL; + } + + SCHEDULER_LOCK(intSave); + (VOID)memcpy_s(memLimit, sizeof(ProcMemLimiter), + (VOID *)plimits->limitsList[PROCESS_LIMITER_ID_MEM], sizeof(ProcMemLimiter)); + LOS_DL_LIST *listHead = (LOS_DL_LIST *)&plimits->processList; + if (LOS_ListEmpty(listHead)) { + SCHEDULER_UNLOCK(intSave); + return EINVAL; + } + + LOS_DL_LIST_FOR_EACH_ENTRY(processCB, listHead, LosProcessCB, plimitsList) { + memSuage[OsGetPid(processCB)] = processCB->limitStat.memUsed; + } + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} +#endif + +#ifdef LOSCFG_KERNEL_IPC_PLIMIT +UINT32 OsPLimitsIPCStatGet(ProcLimiterSet *plimits, ProcIPCLimit *ipc, UINT32 size) +{ + UINT32 intSave; + if ((plimits == NULL) || (ipc == NULL) || (size != sizeof(ProcIPCLimit))) { + return EINVAL; + } + + SCHEDULER_LOCK(intSave); + (VOID)memcpy_s(ipc, sizeof(ProcIPCLimit), + (VOID *)plimits->limitsList[PROCESS_LIMITER_ID_IPC], sizeof(ProcIPCLimit)); + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} +#endif + +#ifdef LOSCFG_KERNEL_SCHED_PLIMIT +UINT32 OsPLimitsSchedUsageGet(ProcLimiterSet *plimits, UINT64 *usage, UINT32 size) +{ + UINT32 intSave; + LosProcessCB *processCB = NULL; + UINT32 minSize = LOS_GetSystemProcessMaximum() * sizeof(UINT64); + if ((plimits == NULL) || (usage == NULL) || (size < minSize)) { + return EINVAL; + } + + SCHEDULER_LOCK(intSave); + LOS_DL_LIST *listHead = (LOS_DL_LIST *)&plimits->processList; + if (LOS_ListEmpty(listHead)) { + SCHEDULER_UNLOCK(intSave); + return EINVAL; + } + + LOS_DL_LIST_FOR_EACH_ENTRY(processCB, listHead, LosProcessCB, plimitsList) { + usage[OsGetPid(processCB)] = processCB->limitStat.allRuntime; + } + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} +#endif +#endif diff --git a/src/kernel_liteos_a/kernel/extended/plimit/los_plimits.h b/src/kernel_liteos_a/kernel/extended/plimit/los_plimits.h new file mode 100644 index 00000000..f3c44fda --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/plimit/los_plimits.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_PLIMITS_H +#define _LOS_PLIMITS_H + +#include "los_list.h" +#include "los_typedef.h" +#include "los_processlimit.h" +#include "los_memlimit.h" +#include "los_ipclimit.h" +#include "los_devicelimit.h" +#include "los_schedlimit.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/* proc limit set lock */ +#define PLIMITS_MIN_PERIOD_IN_US 1000000 +#define PLIMITS_MIN_QUOTA_IN_US 1 +#define PLIMITS_DELETE_WAIT_TIME 1000 +typedef struct ProcessCB LosProcessCB; + +enum ProcLimiterID { + PROCESS_LIMITER_ID_PIDS = 0, +#ifdef LOSCFG_KERNEL_MEM_PLIMIT + PROCESS_LIMITER_ID_MEM, +#endif +#ifdef LOSCFG_KERNEL_SCHED_PLIMIT + PROCESS_LIMITER_ID_SCHED, +#endif +#ifdef LOSCFG_KERNEL_DEV_PLIMIT + PROCESS_LIMITER_ID_DEV, +#endif +#ifdef LOSCFG_KERNEL_IPC_PLIMIT + PROCESS_LIMITER_ID_IPC, +#endif + PROCESS_LIMITER_COUNT, +}; + +typedef struct { +#ifdef LOSCFG_KERNEL_MEM_PLIMIT + UINT64 memUsed; +#endif +#ifdef LOSCFG_KERNEL_IPC_PLIMIT + UINT32 mqCount; + UINT32 shmSize; +#endif +#ifdef LOSCFG_KERNEL_SCHED_PLIMIT + UINT64 allRuntime; +#endif +} PLimitsData; + +typedef struct TagPLimiterSet { + struct TagPLimiterSet *parent; /* plimite parent */ + LOS_DL_LIST childList; /* plimite childList */ + LOS_DL_LIST processList; + UINT32 pidCount; + UINTPTR limitsList[PROCESS_LIMITER_COUNT]; /* plimite list */ + UINT32 mask; /* each bit indicates that a limite exists */ + UINT8 level; /* plimits hierarchy level */ +} ProcLimiterSet; + +typedef struct ProcessCB LosProcessCB; +ProcLimiterSet *OsRootPLimitsGet(VOID); +UINT32 OsPLimitsAddProcess(ProcLimiterSet *plimits, LosProcessCB *processCB); +UINT32 OsPLimitsAddPid(ProcLimiterSet *plimits, UINT32 pid); +VOID OsPLimitsDeleteProcess(LosProcessCB *processCB); +UINT32 OsPLimitsPidsGet(const ProcLimiterSet *plimits, UINT32 *pids, UINT32 size); +UINT32 OsPLimitsFree(ProcLimiterSet *currPLimits); +ProcLimiterSet *OsPLimitsCreate(ProcLimiterSet *parentProcLimiterSet); +UINT32 OsProcLimiterSetInit(VOID); + +UINT32 OsPLimitsMemUsageGet(ProcLimiterSet *plimits, UINT64 *usage, UINT32 size); +UINT32 OsPLimitsIPCStatGet(ProcLimiterSet *plimits, ProcIPCLimit *ipc, UINT32 size); +UINT32 OsPLimitsSchedUsageGet(ProcLimiterSet *plimits, UINT64 *usage, UINT32 size); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_PLIMITS_H */ diff --git a/src/kernel_liteos_a/kernel/extended/plimit/los_processlimit.c b/src/kernel_liteos_a/kernel/extended/plimit/los_processlimit.c new file mode 100644 index 00000000..a335b19b --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/plimit/los_processlimit.c @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef LOSCFG_KERNEL_PLIMITS +#include "los_config.h" +#include "los_process_pri.h" +#include "los_process.h" +#include "los_plimits.h" +#include "los_task_pri.h" +#include "los_processlimit.h" + +STATIC PidLimit *g_rootPidLimit = NULL; + +VOID PidLimiterInit(UINTPTR limit) +{ + PidLimit *pidLimit = (PidLimit *)limit; + if (pidLimit == NULL) { + return; + } + + pidLimit->pidLimit = LOS_GetSystemProcessMaximum(); + pidLimit->priorityLimit = OS_USER_PROCESS_PRIORITY_HIGHEST; + g_rootPidLimit = pidLimit; +} + +VOID *PidLimiterAlloc(VOID) +{ + PidLimit *plimite = (PidLimit *)LOS_MemAlloc(m_aucSysMem1, sizeof(PidLimit)); + if (plimite == NULL) { + return NULL; + } + (VOID)memset_s(plimite, sizeof(PidLimit), 0, sizeof(PidLimit)); + return (VOID *)plimite; +} + +VOID PidLimterFree(UINTPTR limit) +{ + PidLimit *pidLimit = (PidLimit *)limit; + if (pidLimit == NULL) { + return; + } + + (VOID)LOS_MemFree(m_aucSysMem1, (VOID *)limit); +} + +BOOL PidLimitMigrateCheck(UINTPTR curr, UINTPTR parent) +{ + PidLimit *currPidLimit = (PidLimit *)curr; + PidLimit *parentPidLimit = (PidLimit *)parent; + if ((currPidLimit == NULL) || (parentPidLimit == NULL)) { + return FALSE; + } + + if ((currPidLimit->pidCount + parentPidLimit->pidCount) >= parentPidLimit->pidLimit) { + return FALSE; + } + return TRUE; +} + +BOOL OsPidLimitAddProcessCheck(UINTPTR limit, UINTPTR process) +{ + (VOID)process; + PidLimit *pidLimit = (PidLimit *)limit; + if (pidLimit->pidCount >= pidLimit->pidLimit) { + return FALSE; + } + return TRUE; +} + +VOID OsPidLimitAddProcess(UINTPTR limit, UINTPTR process) +{ + (VOID)process; + PidLimit *plimits = (PidLimit *)limit; + + plimits->pidCount++; + return; +} + +VOID OsPidLimitDelProcess(UINTPTR limit, UINTPTR process) +{ + (VOID)process; + PidLimit *plimits = (PidLimit *)limit; + + plimits->pidCount--; + return; +} + +VOID PidLimiterCopy(UINTPTR curr, UINTPTR parent) +{ + PidLimit *currPidLimit = (PidLimit *)curr; + PidLimit *parentPidLimit = (PidLimit *)parent; + if ((currPidLimit == NULL) || (parentPidLimit == NULL)) { + return; + } + + currPidLimit->pidLimit = parentPidLimit->pidLimit; + currPidLimit->priorityLimit = parentPidLimit->priorityLimit; + currPidLimit->pidCount = 0; + return; +} + +UINT32 PidLimitSetPidLimit(PidLimit *pidLimit, UINT32 pidMax) +{ + UINT32 intSave; + + if ((pidLimit == NULL) || (pidMax > LOS_GetSystemProcessMaximum())) { + return EINVAL; + } + + if (pidLimit == g_rootPidLimit) { + return EPERM; + } + + SCHEDULER_LOCK(intSave); + if (pidLimit->pidCount >= pidMax) { + SCHEDULER_UNLOCK(intSave); + return EPERM; + } + + pidLimit->pidLimit = pidMax; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +UINT32 PidLimitSetPriorityLimit(PidLimit *pidLimit, UINT32 priority) +{ + UINT32 intSave; + + if ((pidLimit == NULL) || + (priority < OS_USER_PROCESS_PRIORITY_HIGHEST) || + (priority > OS_PROCESS_PRIORITY_LOWEST)) { + return EINVAL; + } + + if (pidLimit == g_rootPidLimit) { + return EPERM; + } + + SCHEDULER_LOCK(intSave); + pidLimit->priorityLimit = priority; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +UINT16 OsPidLimitGetPriorityLimit(VOID) +{ + UINT32 intSave; + SCHEDULER_LOCK(intSave); + LosProcessCB *run = OsCurrProcessGet(); + PidLimit *pidLimit = (PidLimit *)run->plimits->limitsList[PROCESS_LIMITER_ID_PIDS]; + UINT16 priority = pidLimit->priorityLimit; + SCHEDULER_UNLOCK(intSave); + return priority; +} +#endif diff --git a/src/kernel_liteos_a/kernel/extended/plimit/los_processlimit.h b/src/kernel_liteos_a/kernel/extended/plimit/los_processlimit.h new file mode 100644 index 00000000..b18908de --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/plimit/los_processlimit.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_PROCESSLIMIT_H +#define _LOS_PROCESSLIMIT_H + +#include "los_list.h" +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef struct PidLimit { + UINT32 pidLimit; + UINT32 priorityLimit; + UINT32 pidCount; +} PidLimit; + +VOID PidLimiterInit(UINTPTR limit); +VOID *PidLimiterAlloc(VOID); +VOID PidLimterFree(UINTPTR limit); +VOID PidLimiterCopy(UINTPTR curr, UINTPTR parent); +BOOL PidLimitMigrateCheck(UINTPTR curr, UINTPTR parent); +BOOL OsPidLimitAddProcessCheck(UINTPTR limit, UINTPTR process); +VOID OsPidLimitAddProcess(UINTPTR limit, UINTPTR process); +VOID OsPidLimitDelProcess(UINTPTR limit, UINTPTR process); +UINT32 PidLimitSetPidLimit(PidLimit *pidLimit, UINT32 pidMax); +UINT32 PidLimitSetPriorityLimit(PidLimit *pidLimit, UINT32 priority); +UINT16 OsPidLimitGetPriorityLimit(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/src/kernel_liteos_a/kernel/extended/plimit/los_schedlimit.c b/src/kernel_liteos_a/kernel/extended/plimit/los_schedlimit.c new file mode 100644 index 00000000..ef25f48d --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/plimit/los_schedlimit.c @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef LOSCFG_KERNEL_SCHED_PLIMIT +#include "los_schedlimit.h" +#include "los_process_pri.h" + +STATIC ProcSchedLimiter *g_procSchedLimit = NULL; + +VOID OsSchedLimitInit(UINTPTR limit) +{ + ProcSchedLimiter *schedLimit = (ProcSchedLimiter *)limit; + schedLimit->period = 0; + schedLimit->quota = 0; + g_procSchedLimit = schedLimit; +} + +VOID *OsSchedLimitAlloc(VOID) +{ + ProcSchedLimiter *plimit = (ProcSchedLimiter *)LOS_MemAlloc(m_aucSysMem1, sizeof(ProcSchedLimiter)); + if (plimit == NULL) { + return NULL; + } + (VOID)memset_s(plimit, sizeof(ProcSchedLimiter), 0, sizeof(ProcSchedLimiter)); + return (VOID *)plimit; +} + +VOID OsSchedLimitFree(UINTPTR limit) +{ + ProcSchedLimiter *schedLimit = (ProcSchedLimiter *)limit; + if (schedLimit == NULL) { + return; + } + + (VOID)LOS_MemFree(m_aucSysMem1, (VOID *)limit); +} + +VOID OsSchedLimitCopy(UINTPTR dest, UINTPTR src) +{ + ProcSchedLimiter *plimitDest = (ProcSchedLimiter *)dest; + ProcSchedLimiter *plimitSrc = (ProcSchedLimiter *)src; + plimitDest->period = plimitSrc->period; + plimitDest->quota = plimitSrc->quota; + return; +} + +VOID OsSchedLimitUpdateRuntime(LosTaskCB *runTask, UINT64 currTime, INT32 incTime) +{ + LosProcessCB *run = (LosProcessCB *)runTask->processCB; + if ((run == NULL) || (run->plimits == NULL)) { + return; + } + + ProcSchedLimiter *schedLimit = (ProcSchedLimiter *)run->plimits->limitsList[PROCESS_LIMITER_ID_SCHED]; + + run->limitStat.allRuntime += incTime; + if ((schedLimit->period <= 0) || (schedLimit->quota <= 0)) { + return; + } + + if ((schedLimit->startTime <= currTime) && (schedLimit->allRuntime < schedLimit->quota)) { + schedLimit->allRuntime += incTime; + return; + } + + if (schedLimit->startTime <= currTime) { + schedLimit->startTime = currTime + schedLimit->period; + schedLimit->allRuntime = 0; + } +} + +BOOL OsSchedLimitCheckTime(LosTaskCB *task) +{ + UINT64 currTime = OsGetCurrSchedTimeCycle(); + LosProcessCB *processCB = (LosProcessCB *)task->processCB; + if ((processCB == NULL) || (processCB->plimits == NULL)) { + return TRUE; + } + ProcSchedLimiter *schedLimit = (ProcSchedLimiter *)processCB->plimits->limitsList[PROCESS_LIMITER_ID_SCHED]; + if (schedLimit->startTime >= currTime) { + return FALSE; + } + return TRUE; +} + +UINT32 OsSchedLimitSetPeriod(ProcSchedLimiter *schedLimit, UINT64 value) +{ + UINT32 intSave; + if (schedLimit == NULL) { + return EINVAL; + } + + if (schedLimit == g_procSchedLimit) { + return EPERM; + } + + SCHEDULER_LOCK(intSave); + schedLimit->period = value; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +UINT32 OsSchedLimitSetQuota(ProcSchedLimiter *schedLimit, UINT64 value) +{ + UINT32 intSave; + if (schedLimit == NULL) { + return EINVAL; + } + + if (schedLimit == g_procSchedLimit) { + return EPERM; + } + + SCHEDULER_LOCK(intSave); + if (value > (UINT64)schedLimit->period) { + SCHEDULER_UNLOCK(intSave); + return EINVAL; + } + + schedLimit->quota = value; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} +#endif diff --git a/src/kernel_liteos_a/kernel/extended/plimit/los_schedlimit.h b/src/kernel_liteos_a/kernel/extended/plimit/los_schedlimit.h new file mode 100644 index 00000000..7d958bd2 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/plimit/los_schedlimit.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_SCHEDLIMIT_H +#define _LOS_SCHEDLIMIT_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define CORE_US_PER_SECOND (1000 * 1000) /* 1000 * 1000 us per second */ +typedef struct TagTaskCB LosTaskCB; + +typedef struct ProcSchedLimiter { + UINT64 startTime; + UINT64 endTime; + UINT64 period; + UINT64 quota; + UINT64 allRuntime; +} ProcSchedLimiter; + +VOID OsSchedLimitInit(UINTPTR limit); +VOID *OsSchedLimitAlloc(VOID); +VOID OsSchedLimitFree(UINTPTR limit); +VOID OsSchedLimitCopy(UINTPTR dest, UINTPTR src); +VOID OsSchedLimitUpdateRuntime(LosTaskCB *runTask, UINT64 currTime, INT32 incTime); +UINT32 OsSchedLimitSetPeriod(ProcSchedLimiter *schedLimit, UINT64 value); +UINT32 OsSchedLimitSetQuota(ProcSchedLimiter *schedLimit, UINT64 value); +BOOL OsSchedLimitCheckTime(LosTaskCB *task); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_SCHEDLIMIT_H */ diff --git a/src/kernel_liteos_a/kernel/extended/power/BUILD.gn b/src/kernel_liteos_a/kernel/extended/power/BUILD.gn new file mode 100644 index 00000000..4cdd59e8 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/power/BUILD.gn @@ -0,0 +1,40 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = defined(LOSCFG_KERNEL_PM) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ "los_pm.c" ] +} + +config("public") { + include_dirs = [ "." ] +} diff --git a/src/kernel_liteos_a/kernel/extended/power/Makefile b/src/kernel_liteos_a/kernel/extended/power/Makefile new file mode 100644 index 00000000..8d11bbf2 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/power/Makefile @@ -0,0 +1,36 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := $(wildcard *.c) + +include $(MODULE) diff --git a/src/kernel_liteos_a/kernel/extended/power/los_pm.c b/src/kernel_liteos_a/kernel/extended/power/los_pm.c new file mode 100644 index 00000000..d34c9788 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/power/los_pm.c @@ -0,0 +1,691 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_pm.h" +#include "securec.h" +#include "los_sched_pri.h" +#include "los_init.h" +#include "los_memory.h" +#include "los_spinlock.h" +#include "los_swtmr.h" +#include "los_mp.h" + +#define OS_MS_PER_TICK (OS_SYS_MS_PER_SECOND / LOSCFG_BASE_CORE_TICK_PER_SECOND) + +#ifdef LOSCFG_KERNEL_PM +#define PM_INFO_SHOW(seqBuf, arg...) do { \ + if (seqBuf != NULL) { \ + (void)LosBufPrintf((struct SeqBuf *)seqBuf, ##arg); \ + } else { \ + PRINTK(arg); \ + } \ +} while (0) + +#define OS_PM_LOCK_MAX 0xFFFFU +#define OS_PM_LOCK_NAME_MAX 28 +#define OS_PM_SYS_EARLY 1 +#define OS_PM_SYS_DEVICE_EARLY 2 + +typedef UINT32 (*Suspend)(UINT32 mode); + +typedef struct { + CHAR name[OS_PM_LOCK_NAME_MAX]; + UINT32 count; + UINT32 swtmrID; + LOS_DL_LIST list; +} OsPmLockCB; + +typedef struct { + LOS_SysSleepEnum pmMode; + LOS_SysSleepEnum sysMode; + UINT16 lock; + BOOL isWake; + LosPmDevice *device; + LosPmSysctrl *sysctrl; + UINT64 enterSleepTime; + LOS_DL_LIST lockList; +} LosPmCB; + +#define PM_EVENT_LOCK_MASK 0xF +#define PM_EVENT_LOCK_RELEASE 0x1 +STATIC EVENT_CB_S g_pmEvent; +STATIC LosPmCB g_pmCB; +STATIC SPIN_LOCK_INIT(g_pmSpin); +STATIC LosPmSysctrl g_sysctrl; + +STATIC VOID OsPmSysctrlInit(VOID); + +STATIC VOID OsPmTickTimerStart(LosPmCB *pm) +{ + (VOID)pm; + return; +} + +STATIC BOOL OsPmTickTimerStop(LosPmCB *pm) +{ + (VOID)pm; + return FALSE; +} + +STATIC VOID OsPmCpuResume(LosPmCB *pm) +{ + if ((pm->sysMode == LOS_SYS_NORMAL_SLEEP) && (pm->sysctrl->normalResume != NULL)) { + pm->sysctrl->normalResume(); + } else if ((pm->sysMode == LOS_SYS_LIGHT_SLEEP) && (pm->sysctrl->lightResume != NULL)) { + pm->sysctrl->lightResume(); + } else if ((pm->sysMode == LOS_SYS_DEEP_SLEEP) && (pm->sysctrl->deepResume != NULL)) { + pm->sysctrl->deepResume(); + } +} + +VOID OsPmCpuSuspend(LosPmCB *pm) +{ + /* cpu enter low power mode */ + LOS_ASSERT(pm->sysctrl != NULL); + + if (pm->sysMode == LOS_SYS_NORMAL_SLEEP) { + pm->sysctrl->normalSuspend(); + } else if (pm->sysMode == LOS_SYS_LIGHT_SLEEP) { + pm->sysctrl->lightSuspend(); + } else if (pm->sysMode == LOS_SYS_DEEP_SLEEP) { + pm->sysctrl->deepSuspend(); + } else { + pm->sysctrl->shutdownSuspend(); + } +} + +STATIC VOID OsPmResumePrepare(LosPmCB *pm, UINT32 mode, UINT32 prepare) +{ + if ((prepare == 0) && (pm->device != NULL) && (pm->device->resume != NULL)) { + pm->device->resume(mode); + } + + if (((prepare == 0) || (prepare == OS_PM_SYS_DEVICE_EARLY)) && (pm->sysctrl->late != NULL)) { + pm->sysctrl->late(mode); + } +} + +STATIC UINT32 OsPmSuspendPrepare(Suspend sysSuspendEarly, Suspend deviceSuspend, UINT32 mode, UINT32 *prepare) +{ + UINT32 ret; + + if (sysSuspendEarly != NULL) { + ret = sysSuspendEarly(mode); + if (ret != LOS_OK) { + *prepare = OS_PM_SYS_EARLY; + return ret; + } + } + + if (deviceSuspend != NULL) { + ret = deviceSuspend(mode); + if (ret != LOS_OK) { + *prepare = OS_PM_SYS_DEVICE_EARLY; + return ret; + } + } + + return LOS_OK; +} + +STATIC UINT32 OsPmSuspendCheck(LosPmCB *pm, Suspend *sysSuspendEarly, Suspend *deviceSuspend, LOS_SysSleepEnum *mode) +{ + LOS_SpinLock(&g_pmSpin); + pm->sysMode = pm->pmMode; + if (pm->lock > 0) { + pm->sysMode = LOS_SYS_NORMAL_SLEEP; + LOS_SpinUnlock(&g_pmSpin); + return LOS_NOK; + } + + pm->isWake = FALSE; + *mode = pm->sysMode; + *sysSuspendEarly = pm->sysctrl->early; + if (pm->device != NULL) { + *deviceSuspend = pm->device->suspend; + } else { + *deviceSuspend = NULL; + } + LOS_SpinUnlock(&g_pmSpin); + return LOS_OK; +} + +STATIC UINT32 OsPmSuspendSleep(LosPmCB *pm) +{ + UINT32 ret, intSave; + Suspend sysSuspendEarly, deviceSuspend; + LOS_SysSleepEnum mode; + UINT32 prepare = 0; + BOOL tickTimerStop = FALSE; + + ret = OsPmSuspendCheck(pm, &sysSuspendEarly, &deviceSuspend, &mode); + if (ret != LOS_OK) { + PRINT_ERR("Pm suspend mode is normal sleep! lock count %d\n", pm->lock); + return ret; + } + + ret = OsPmSuspendPrepare(sysSuspendEarly, deviceSuspend, (UINT32)mode, &prepare); + if (ret != LOS_OK) { + LOS_SpinLockSave(&g_pmSpin, &intSave); + LOS_TaskLock(); + goto EXIT; + } + + LOS_SpinLockSave(&g_pmSpin, &intSave); + LOS_TaskLock(); + if (pm->isWake || (pm->lock > 0)) { + goto EXIT; + } + + tickTimerStop = OsPmTickTimerStop(pm); + if (!tickTimerStop) { + OsSchedResponseTimeReset(0); + OsSchedExpireTimeUpdate(); + } + + OsPmCpuSuspend(pm); + + OsPmCpuResume(pm); + + OsPmTickTimerStart(pm); + +EXIT: + pm->sysMode = LOS_SYS_NORMAL_SLEEP; + OsPmResumePrepare(pm, (UINT32)mode, prepare); + + LOS_SpinUnlockRestore(&g_pmSpin, intSave); + LOS_TaskUnlock(); + return ret; +} + +STATIC UINT32 OsPmDeviceRegister(LosPmCB *pm, LosPmDevice *device) +{ + if ((device->suspend == NULL) || (device->resume == NULL)) { + return LOS_EINVAL; + } + + LOS_SpinLock(&g_pmSpin); + pm->device = device; + LOS_SpinUnlock(&g_pmSpin); + + return LOS_OK; +} + +STATIC UINT32 OsPmSysctrlRegister(LosPmCB *pm, LosPmSysctrl *sysctrl) +{ + LOS_SpinLock(&g_pmSpin); + if (sysctrl->early != NULL) { + pm->sysctrl->early = sysctrl->early; + } + if (sysctrl->late != NULL) { + pm->sysctrl->late = sysctrl->late; + } + if (sysctrl->normalSuspend != NULL) { + pm->sysctrl->normalSuspend = sysctrl->normalSuspend; + } + if (sysctrl->normalResume != NULL) { + pm->sysctrl->normalResume = sysctrl->normalResume; + } + if (sysctrl->lightSuspend != NULL) { + pm->sysctrl->lightSuspend = sysctrl->lightSuspend; + } + if (sysctrl->lightResume != NULL) { + pm->sysctrl->lightResume = sysctrl->lightResume; + } + if (sysctrl->deepSuspend != NULL) { + pm->sysctrl->deepSuspend = sysctrl->deepSuspend; + } + if (sysctrl->deepResume != NULL) { + pm->sysctrl->deepResume = sysctrl->deepResume; + } + if (sysctrl->shutdownSuspend != NULL) { + pm->sysctrl->shutdownSuspend = sysctrl->shutdownSuspend; + } + if (sysctrl->shutdownResume != NULL) { + pm->sysctrl->shutdownResume = sysctrl->shutdownResume; + } + LOS_SpinUnlock(&g_pmSpin); + + return LOS_OK; +} + +UINT32 LOS_PmRegister(LOS_PmNodeType type, VOID *node) +{ + LosPmCB *pm = &g_pmCB; + + if (node == NULL) { + return LOS_EINVAL; + } + + switch (type) { + case LOS_PM_TYPE_DEVICE: + return OsPmDeviceRegister(pm, (LosPmDevice *)node); + case LOS_PM_TYPE_TICK_TIMER: + PRINT_ERR("Pm, %d is an unsupported type\n", type); + return LOS_EINVAL; + case LOS_PM_TYPE_SYSCTRL: + return OsPmSysctrlRegister(pm, (LosPmSysctrl *)node); + default: + break; + } + + return LOS_EINVAL; +} + +STATIC UINT32 OsPmDeviceUnregister(LosPmCB *pm, const LosPmDevice *device) +{ + LOS_SpinLock(&g_pmSpin); + if (pm->device == device) { + pm->device = NULL; + pm->pmMode = LOS_SYS_NORMAL_SLEEP; + LOS_SpinUnlock(&g_pmSpin); + return LOS_OK; + } + + LOS_SpinUnlock(&g_pmSpin); + return LOS_EINVAL; +} + +STATIC UINT32 OsPmSysctrlUnregister(LosPmCB *pm, LosPmSysctrl *sysctrl) +{ + (VOID)sysctrl; + LOS_SpinLock(&g_pmSpin); + OsPmSysctrlInit(); + pm->pmMode = LOS_SYS_NORMAL_SLEEP; + LOS_SpinUnlock(&g_pmSpin); + + return LOS_OK; +} + +UINT32 LOS_PmUnregister(LOS_PmNodeType type, VOID *node) +{ + LosPmCB *pm = &g_pmCB; + + if (node == NULL) { + return LOS_EINVAL; + } + + switch (type) { + case LOS_PM_TYPE_DEVICE: + return OsPmDeviceUnregister(pm, (LosPmDevice *)node); + case LOS_PM_TYPE_TICK_TIMER: + PRINT_ERR("Pm, %d is an unsupported type\n", type); + return LOS_EINVAL; + case LOS_PM_TYPE_SYSCTRL: + return OsPmSysctrlUnregister(pm, (LosPmSysctrl *)node); + default: + break; + } + + return LOS_EINVAL; +} + +VOID LOS_PmWakeSet(VOID) +{ + LosPmCB *pm = &g_pmCB; + + LOS_SpinLock(&g_pmSpin); + pm->isWake = TRUE; + LOS_SpinUnlock(&g_pmSpin); + return; +} + +LOS_SysSleepEnum LOS_PmModeGet(VOID) +{ + LOS_SysSleepEnum mode; + LosPmCB *pm = &g_pmCB; + + LOS_SpinLock(&g_pmSpin); + mode = pm->pmMode; + LOS_SpinUnlock(&g_pmSpin); + + return mode; +} + +UINT32 LOS_PmModeSet(LOS_SysSleepEnum mode) +{ + LosPmCB *pm = &g_pmCB; + INT32 sleepMode = (INT32)mode; + + if ((sleepMode < 0) || (sleepMode > LOS_SYS_SHUTDOWN)) { + return LOS_EINVAL; + } + + LOS_SpinLock(&g_pmSpin); + if ((mode == LOS_SYS_LIGHT_SLEEP) && (pm->sysctrl->lightSuspend == NULL)) { + LOS_SpinUnlock(&g_pmSpin); + return LOS_EINVAL; + } + + if ((mode == LOS_SYS_DEEP_SLEEP) && (pm->sysctrl->deepSuspend == NULL)) { + LOS_SpinUnlock(&g_pmSpin); + return LOS_EINVAL; + } + + if ((mode == LOS_SYS_SHUTDOWN) && (pm->sysctrl->shutdownSuspend == NULL)) { + LOS_SpinUnlock(&g_pmSpin); + return LOS_EINVAL; + } + + pm->pmMode = mode; + LOS_SpinUnlock(&g_pmSpin); + + return LOS_OK; +} + +UINT32 LOS_PmLockCountGet(VOID) +{ + UINT16 count; + LosPmCB *pm = &g_pmCB; + + LOS_SpinLock(&g_pmSpin); + count = pm->lock; + LOS_SpinUnlock(&g_pmSpin); + + return (UINT32)count; +} + +VOID LOS_PmLockInfoShow(struct SeqBuf *m) +{ + LosPmCB *pm = &g_pmCB; + OsPmLockCB *lock = NULL; + LOS_DL_LIST *head = &pm->lockList; + LOS_DL_LIST *list = head->pstNext; + + LOS_SpinLock(&g_pmSpin); + while (list != head) { + lock = LOS_DL_LIST_ENTRY(list, OsPmLockCB, list); + PM_INFO_SHOW(m, "%-30s%5u\n\r", lock->name, lock->count); + list = list->pstNext; + } + LOS_SpinUnlock(&g_pmSpin); + + return; +} + +UINT32 OsPmLockRequest(const CHAR *name, UINT32 swtmrID) +{ + INT32 len; + errno_t err; + UINT32 ret = LOS_EINVAL; + LosPmCB *pm = &g_pmCB; + OsPmLockCB *lock = NULL; + LOS_DL_LIST *head = &pm->lockList; + LOS_DL_LIST *list = head->pstNext; + + if (OS_INT_ACTIVE) { + return LOS_EINTR; + } + + len = strlen(name); + if (len <= 0) { + return LOS_EINVAL; + } + + LOS_SpinLock(&g_pmSpin); + if (pm->lock >= OS_PM_LOCK_MAX) { + LOS_SpinUnlock(&g_pmSpin); + return LOS_EINVAL; + } + + while (list != head) { + OsPmLockCB *listNode = LOS_DL_LIST_ENTRY(list, OsPmLockCB, list); + if (strcmp(name, listNode->name) == 0) { + lock = listNode; + break; + } + + list = list->pstNext; + } + + if (lock == NULL) { + lock = LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, sizeof(OsPmLockCB)); + if (lock == NULL) { + LOS_SpinUnlock(&g_pmSpin); + return LOS_ENOMEM; + } + err = memcpy_s(lock->name, OS_PM_LOCK_NAME_MAX, name, len + 1); + if (err != EOK) { + LOS_SpinUnlock(&g_pmSpin); + (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, lock); + return err; + } + lock->count = 1; + lock->swtmrID = swtmrID; + LOS_ListTailInsert(head, &lock->list); + } else if (lock->count < OS_PM_LOCK_MAX) { + lock->count++; + } + + if ((lock->swtmrID != OS_INVALID) && (lock->count > 1)) { + lock->count--; + LOS_SpinUnlock(&g_pmSpin); + return LOS_EINVAL; + } + + if (pm->lock < OS_PM_LOCK_MAX) { + pm->lock++; + ret = LOS_OK; + } + + LOS_SpinUnlock(&g_pmSpin); + return ret; +} + +UINT32 LOS_PmLockRequest(const CHAR *name) +{ + if (name == NULL) { + return LOS_EINVAL; + } + + return OsPmLockRequest(name, OS_INVALID); +} + +UINT32 LOS_PmLockRelease(const CHAR *name) +{ + UINT32 ret = LOS_EINVAL; + LosPmCB *pm = &g_pmCB; + OsPmLockCB *lock = NULL; + LOS_DL_LIST *head = &pm->lockList; + LOS_DL_LIST *list = head->pstNext; + OsPmLockCB *lockFree = NULL; + BOOL isRelease = FALSE; + UINT32 mode; + + if (name == NULL) { + return LOS_EINVAL; + } + + if (OS_INT_ACTIVE) { + return LOS_EINTR; + } + + LOS_SpinLock(&g_pmSpin); + if (pm->lock == 0) { + LOS_SpinUnlock(&g_pmSpin); + return LOS_EINVAL; + } + + mode = (UINT32)pm->pmMode; + while (list != head) { + OsPmLockCB *listNode = LOS_DL_LIST_ENTRY(list, OsPmLockCB, list); + if (strcmp(name, listNode->name) == 0) { + lock = listNode; + break; + } + + list = list->pstNext; + } + + if (lock == NULL) { + LOS_SpinUnlock(&g_pmSpin); + return LOS_EINVAL; + } else if (lock->count > 0) { + lock->count--; + if (lock->count == 0) { + LOS_ListDelete(&lock->list); + lockFree = lock; + } + } + + if (pm->lock > 0) { + pm->lock--; + if (pm->lock == 0) { + isRelease = TRUE; + } + ret = LOS_OK; + } + LOS_SpinUnlock(&g_pmSpin); + + if (lockFree != NULL) { + (VOID)LOS_SwtmrDelete(lockFree->swtmrID); + (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, lockFree); + } + + if (isRelease && (mode > LOS_SYS_NORMAL_SLEEP)) { + (VOID)LOS_EventWrite(&g_pmEvent, PM_EVENT_LOCK_RELEASE); + } + + return ret; +} + +STATIC VOID OsPmSwtmrHandler(UINT32 arg) +{ + const CHAR *name = (const CHAR *)arg; + UINT32 ret = LOS_PmLockRelease(name); + if (ret != LOS_OK) { + PRINT_ERR("Pm delay lock %s release faled! : 0x%x\n", name, ret); + } +} + +UINT32 LOS_PmTimeLockRequest(const CHAR *name, UINT64 millisecond) +{ + UINT32 ticks; + UINT16 swtmrID; + UINT32 ret; + + if ((name == NULL) || !millisecond) { + return LOS_EINVAL; + } + + ticks = (UINT32)((millisecond + OS_MS_PER_TICK - 1) / OS_MS_PER_TICK); +#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == 1) + ret = LOS_SwtmrCreate(ticks, LOS_SWTMR_MODE_ONCE, OsPmSwtmrHandler, &swtmrID, (UINT32)(UINTPTR)name, + OS_SWTMR_ROUSES_ALLOW, OS_SWTMR_ALIGN_INSENSITIVE); +#else + ret = LOS_SwtmrCreate(ticks, LOS_SWTMR_MODE_ONCE, OsPmSwtmrHandler, &swtmrID, (UINT32)(UINTPTR)name); +#endif + if (ret != LOS_OK) { + return ret; + } + + ret = OsPmLockRequest(name, swtmrID); + if (ret != LOS_OK) { + (VOID)LOS_SwtmrDelete(swtmrID); + return ret; + } + + ret = LOS_SwtmrStart(swtmrID); + if (ret != LOS_OK) { + (VOID)LOS_PmLockRelease(name); + } + + return ret; +} + +UINT32 LOS_PmReadLock(VOID) +{ + UINT32 ret = LOS_EventRead(&g_pmEvent, PM_EVENT_LOCK_MASK, LOS_WAITMODE_OR | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER); + if (ret > PM_EVENT_LOCK_MASK) { + PRINT_ERR("%s event read failed! ERROR: 0x%x\n", __FUNCTION__, ret); + } + + return LOS_OK; +} + +UINT32 LOS_PmSuspend(UINT32 wakeCount) +{ + (VOID)wakeCount; + return OsPmSuspendSleep(&g_pmCB); +} + +BOOL OsIsPmMode(VOID) +{ + LosPmCB *pm = &g_pmCB; + + LOS_SpinLock(&g_pmSpin); + if ((pm->sysMode != LOS_SYS_NORMAL_SLEEP) && (pm->lock == 0)) { + LOS_SpinUnlock(&g_pmSpin); + return TRUE; + } + LOS_SpinUnlock(&g_pmSpin); + return FALSE; +} + +STATIC UINT32 OsPmSuspendDefaultHandler(VOID) +{ + PRINTK("Enter pm default handler!!!\n"); + WFI; + return LOS_OK; +} + +STATIC VOID OsPmSysctrlInit(VOID) +{ + /* Default handler functions, which are implemented by the product */ + g_sysctrl.early = NULL; + g_sysctrl.late = NULL; + g_sysctrl.normalSuspend = OsPmSuspendDefaultHandler; + g_sysctrl.normalResume = NULL; + g_sysctrl.lightSuspend = OsPmSuspendDefaultHandler; + g_sysctrl.lightResume = NULL; + g_sysctrl.deepSuspend = OsPmSuspendDefaultHandler; + g_sysctrl.deepResume = NULL; + g_sysctrl.shutdownSuspend = NULL; + g_sysctrl.shutdownResume = NULL; +} + +UINT32 OsPmInit(VOID) +{ + LosPmCB *pm = &g_pmCB; + + (VOID)memset_s(pm, sizeof(LosPmCB), 0, sizeof(LosPmCB)); + + pm->pmMode = LOS_SYS_NORMAL_SLEEP; + LOS_ListInit(&pm->lockList); + (VOID)LOS_EventInit(&g_pmEvent); + + OsPmSysctrlInit(); + pm->sysctrl = &g_sysctrl; + return LOS_OK; +} + +LOS_MODULE_INIT(OsPmInit, LOS_INIT_LEVEL_KMOD_EXTENDED); +#endif diff --git a/src/kernel_liteos_a/kernel/extended/power/los_pm_pri.h b/src/kernel_liteos_a/kernel/extended/power/los_pm_pri.h new file mode 100644 index 00000000..03cd7dcc --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/power/los_pm_pri.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_PM_PRI_H +#define _LOS_PM_PRI_H + +#include "los_config.h" +#include "los_typedef.h" + +#ifdef LOSCFG_KERNEL_PM + +BOOL OsIsPmMode(VOID); + +#else + +STATIC INLINE BOOL OsIsPmMode(VOID) +{ + return FALSE; +} + +#endif +#endif diff --git a/src/kernel_liteos_a/kernel/extended/trace/BUILD.gn b/src/kernel_liteos_a/kernel/extended/trace/BUILD.gn new file mode 100644 index 00000000..04cf9a5d --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/trace/BUILD.gn @@ -0,0 +1,65 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = defined(LOSCFG_KERNEL_TRACE) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ + "cnv/trace_cnv.c", + "los_trace.c", + ] + + include_dirs = [ + ".", + "cnv", + "pipeline", + ] + + if (defined(LOSCFG_RECORDER_MODE_OFFLINE)) { + sources += [ "trace_offline.c" ] + } + + if (defined(LOSCFG_RECORDER_MODE_ONLINE)) { + sources += [ "trace_online.c" ] + } + + if (defined(LOSCFG_TRACE_CLIENT_INTERACT)) { + sources += [ + "pipeline/trace_pipeline.c", + "pipeline/trace_tlv.c", + ] + } + + if (defined(LOSCFG_TRACE_PIPELINE_SERIAL)) { + sources += [ "pipeline/serial/trace_pipeline_serial.c" ] + include_dirs += [ "pipeline/serial" ] + } +} diff --git a/src/kernel_liteos_a/kernel/extended/trace/Kconfig b/src/kernel_liteos_a/kernel/extended/trace/Kconfig new file mode 100644 index 00000000..636eb04a --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/trace/Kconfig @@ -0,0 +1,78 @@ +config KERNEL_TRACE + bool "Enable Trace Feature" + default n + depends on KERNEL_HOOK + +config TRACE_MSG_EXTEND + bool "Enable Record more extended content" + default n + depends on KERNEL_TRACE + +config TRACE_FRAME_CORE_MSG + bool "Record cpuid, hardware interrupt status, task lock status" + default n + depends on TRACE_MSG_EXTEND + +config TRACE_FRAME_EVENT_COUNT + bool "Record event count, which indicate the sequence of happened events" + default n + depends on TRACE_MSG_EXTEND + +config TRACE_FRAME_MAX_PARAMS + int "Record max params" + default 3 + depends on KERNEL_TRACE + help + Make sure the max value is bigger than the number defined by each #MODULE#_#TYPE#_PARAMS in los_trace.h, e.g. TASK_SWITCH_PARAMS + +choice + prompt "Trace work mode" + default RECORDER_MODE_OFFLINE + depends on KERNEL_TRACE + +config RECORDER_MODE_ONLINE + bool "Online mode" + select TRACE_CLIENT_INTERACT + +config RECORDER_MODE_OFFLINE + bool "Offline mode" + +endchoice + +config TRACE_BUFFER_SIZE + int "Trace record buffer size" + default 10000 + depends on RECORDER_MODE_OFFLINE + +config TRACE_CLIENT_INTERACT + bool "Enable Trace Client Visualization and Control" + default n + depends on KERNEL_TRACE + +choice + prompt "Trace Pipeline for Data Transmission" + depends on TRACE_CLIENT_INTERACT + +config TRACE_PIPELINE_SERIAL + bool "Via Serial" + +endchoice + +choice + prompt "Trace Control" + default TRACE_CONTROL_VIA_SHELL + depends on TRACE_CLIENT_INTERACT + help + If you wish to control Trace's start/stop etc.,dynamically by Trace Client. + +config TRACE_CONTROL_VIA_SHELL + bool "Via Shell" + select LOSCFG_SHELL + +config TRACE_CONTROL_AGENT + bool "Via Trace Agent Task" + +config TRACE_NO_CONTROL + bool "No Control" + +endchoice \ No newline at end of file diff --git a/src/kernel_liteos_a/kernel/extended/trace/Makefile b/src/kernel_liteos_a/kernel/extended/trace/Makefile new file mode 100644 index 00000000..68fa8315 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/trace/Makefile @@ -0,0 +1,62 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := los_trace.c +LOCAL_SRCS += $(wildcard cnv/*.c) + +LOCAL_INCLUDE := \ + -I $(LITEOSTOPDIR)/kernel/extended/trace \ + -I $(LITEOSTOPDIR)/kernel/extended/trace/pipeline \ + -I $(LITEOSTOPDIR)/kernel/extended/trace/cnv + +ifeq ($(LOSCFG_RECORDER_MODE_OFFLINE), y) +LOCAL_SRCS += trace_offline.c +endif + +ifeq ($(LOSCFG_RECORDER_MODE_ONLINE), y) +LOCAL_SRCS += trace_online.c +endif + +ifeq ($(LOSCFG_TRACE_CLIENT_INTERACT), y) +LOCAL_SRCS += $(wildcard pipeline/*.c) +endif + +ifeq ($(LOSCFG_TRACE_PIPELINE_SERIAL), y) +LOCAL_SRCS += $(wildcard pipeline/serial/*.c) +LOCAL_INCLUDE += -I $(LITEOSTOPDIR)/kernel/extended/trace/pipeline/serial +endif + +LOCAL_FLAGS := $(LOCAL_INCLUDE) + +include $(MODULE) + diff --git a/src/kernel_liteos_a/kernel/extended/trace/cnv/trace_cnv.c b/src/kernel_liteos_a/kernel/extended/trace/cnv/trace_cnv.c new file mode 100644 index 00000000..1ade59c6 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/trace/cnv/trace_cnv.c @@ -0,0 +1,344 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "trace_cnv.h" +#include "los_trace.h" +#include "los_task.h" +#include "los_sem.h" +#include "los_mux.h" +#include "los_queue.h" +#include "los_event.h" +#include "los_swtmr.h" +#include "hm_liteipc.h" +#include "los_hook.h" + +STATIC VOID LOS_TraceMemInit(VOID *pool, UINT32 size) +{ + LOS_TRACE(MEM_INFO_REQ, pool); +} + +STATIC VOID LOS_TraceMemAlloc(VOID *pool, VOID *ptr, UINT32 size) +{ + LOS_TRACE(MEM_ALLOC, pool, (UINTPTR)ptr, size); +} + +STATIC VOID LOS_TraceMemFree(VOID *pool, VOID *ptr) +{ + LOS_TRACE(MEM_FREE, pool, (UINTPTR)ptr); +} + +STATIC VOID LOS_TraceMemRealloc(VOID *pool, VOID *ptr, UINT32 size) +{ + LOS_TRACE(MEM_REALLOC, pool, (UINTPTR)ptr, size); +} + +STATIC VOID LOS_TraceMemAllocAlign(VOID *pool, VOID *ptr, UINT32 size, UINT32 boundary) +{ + LOS_TRACE(MEM_ALLOC_ALIGN, pool, (UINTPTR)ptr, size, boundary); +} + +STATIC VOID LOS_TraceEventInit(PEVENT_CB_S eventCB) +{ + LOS_TRACE(EVENT_CREATE, (UINTPTR)eventCB); +} + +STATIC VOID LOS_TraceEventRead(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeout) +{ + LOS_TRACE(EVENT_READ, (UINTPTR)eventCB, eventCB->uwEventID, eventMask, mode, timeout); +} + +STATIC VOID LOS_TraceEventWrite(PEVENT_CB_S eventCB, UINT32 events) +{ + LOS_TRACE(EVENT_WRITE, (UINTPTR)eventCB, eventCB->uwEventID, events); +} + +STATIC VOID LOS_TraceEventClear(PEVENT_CB_S eventCB, UINT32 events) +{ + LOS_TRACE(EVENT_CLEAR, (UINTPTR)eventCB, eventCB->uwEventID, events); +} + +STATIC VOID LOS_TraceEventDestroy(PEVENT_CB_S eventCB) +{ + LOS_TRACE(EVENT_DELETE, (UINTPTR)eventCB, LOS_OK); +} + +STATIC VOID LOS_TraceQueueCreate(const LosQueueCB *queueCB) +{ + LOS_TRACE(QUEUE_CREATE, queueCB->queueID, queueCB->queueLen, queueCB->queueSize - sizeof(UINT32), + (UINTPTR)queueCB, 0); +} + +STATIC VOID LOS_TraceQueueRW(const LosQueueCB *queueCB, UINT32 operateType, + UINT32 bufferSize, UINT32 timeout) +{ + LOS_TRACE(QUEUE_RW, queueCB->queueID, queueCB->queueSize, bufferSize, operateType, + queueCB->readWriteableCnt[OS_QUEUE_READ], queueCB->readWriteableCnt[OS_QUEUE_WRITE], timeout); +} + +STATIC VOID LOS_TraceQueueDelete(const LosQueueCB *queueCB) +{ + LOS_TRACE(QUEUE_DELETE, queueCB->queueID, queueCB->queueState, queueCB->readWriteableCnt[OS_QUEUE_READ]); +} + +STATIC VOID LOS_TraceSemCreate(const LosSemCB *semCB) +{ + LOS_TRACE(SEM_CREATE, semCB->semID, 0, semCB->semCount); +} + +STATIC VOID LOS_TraceSemPost(const LosSemCB *semCB, const LosTaskCB *resumedTask) +{ + (VOID)resumedTask; + LOS_TRACE(SEM_POST, semCB->semID, 0, semCB->semCount); +} + +STATIC VOID LOS_TraceSemPend(const LosSemCB *semCB, const LosTaskCB *runningTask, UINT32 timeout) +{ + (VOID)runningTask; + LOS_TRACE(SEM_PEND, semCB->semID, semCB->semCount, timeout); +} + +STATIC VOID LOS_TraceSemDelete(const LosSemCB *semCB) +{ + LOS_TRACE(SEM_DELETE, semCB->semID, LOS_OK); +} + +STATIC VOID LOS_TraceMuxCreate(const LosMux *muxCB) +{ + LOS_TRACE(MUX_CREATE, (UINTPTR)muxCB); +} + +STATIC VOID LOS_TraceMuxPost(const LosMux *muxCB) +{ + LOS_TRACE(MUX_POST, (UINTPTR)muxCB, muxCB->muxCount, + (muxCB->owner == NULL) ? 0xffffffff : ((LosTaskCB *)muxCB->owner)->taskID); +} + +STATIC VOID LOS_TraceMuxPend(const LosMux *muxCB, UINT32 timeout) +{ + LOS_TRACE(MUX_PEND, (UINTPTR)muxCB, muxCB->muxCount, + (muxCB->owner == NULL) ? 0xffffffff : ((LosTaskCB *)muxCB->owner)->taskID, timeout); +} + +STATIC VOID LOS_TraceMuxDelete(const LosMux *muxCB) +{ + LOS_TRACE(MUX_DELETE, (UINTPTR)muxCB, muxCB->attr.type, muxCB->muxCount, + (muxCB->owner == NULL) ? 0xffffffff : ((LosTaskCB *)muxCB->owner)->taskID); +} + +STATIC VOID LOS_TraceTaskCreate(const LosTaskCB *taskCB) +{ +#ifdef LOSCFG_KERNEL_TRACE + SchedParam param = { 0 }; + taskCB->ops->schedParamGet(taskCB, ¶m); + LOS_TRACE(TASK_CREATE, taskCB->taskID, taskCB->taskStatus, param.priority); +#else + (VOID)taskCB; +#endif +} + +STATIC VOID LOS_TraceTaskPriModify(const LosTaskCB *taskCB, UINT32 prio) +{ +#ifdef LOSCFG_KERNEL_TRACE + SchedParam param = { 0 }; + taskCB->ops->schedParamGet(taskCB, ¶m); + LOS_TRACE(TASK_PRIOSET, taskCB->taskID, taskCB->taskStatus, param.priority, prio); +#else + (VOID)taskCB; + (VOID)prio; +#endif +} + +STATIC VOID LOS_TraceTaskDelete(const LosTaskCB *taskCB) +{ + LOS_TRACE(TASK_DELETE, taskCB->taskID, taskCB->taskStatus, (UINTPTR)taskCB->stackPointer); +} + +STATIC VOID LOS_TraceTaskSwitchedIn(const LosTaskCB *newTask, const LosTaskCB *runTask) +{ +#ifdef LOSCFG_KERNEL_TRACE + SchedParam runParam = { 0 }; + SchedParam newParam = { 0 }; + runTask->ops->schedParamGet(runTask, &runParam); + newTask->ops->schedParamGet(newTask, &newParam); + LOS_TRACE(TASK_SWITCH, newTask->taskID, runParam.priority, runTask->taskStatus, + newParam.priority, newTask->taskStatus); +#else + (VOID)newTask; + (VOID)runTask; +#endif +} + +STATIC VOID LOS_TraceTaskResume(const LosTaskCB *taskCB) +{ +#ifdef LOSCFG_KERNEL_TRACE + SchedParam param = { 0 }; + taskCB->ops->schedParamGet(taskCB, ¶m); + LOS_TRACE(TASK_RESUME, taskCB->taskID, taskCB->taskStatus, param.priority); +#else + (VOID)taskCB; +#endif +} + +STATIC VOID LOS_TraceTaskSuspend(const LosTaskCB *taskCB) +{ + LOS_TRACE(TASK_SUSPEND, taskCB->taskID, taskCB->taskStatus, OsCurrTaskGet()->taskID); +} + +STATIC VOID LOS_TraceIsrEnter(UINT32 hwiNum) +{ + LOS_TRACE(HWI_RESPONSE_IN, hwiNum); +} + +STATIC VOID LOS_TraceIsrExit(UINT32 hwiNum) +{ + LOS_TRACE(HWI_RESPONSE_OUT, hwiNum); +} + +STATIC VOID LOS_TraceSwtmrCreate(const SWTMR_CTRL_S *swtmr) +{ + LOS_TRACE(SWTMR_CREATE, swtmr->usTimerID); +} + +STATIC VOID LOS_TraceSwtmrDelete(const SWTMR_CTRL_S *swtmr) +{ + LOS_TRACE(SWTMR_DELETE, swtmr->usTimerID); +} + +STATIC VOID LOS_TraceSwtmrExpired(const SWTMR_CTRL_S *swtmr) +{ + LOS_TRACE(SWTMR_EXPIRED, swtmr->usTimerID); +} + +STATIC VOID LOS_TraceSwtmrStart(const SWTMR_CTRL_S *swtmr) +{ + LOS_TRACE(SWTMR_START, swtmr->usTimerID, swtmr->ucMode, swtmr->uwInterval); +} + +STATIC VOID LOS_TraceSwtmrStop(const SWTMR_CTRL_S *swtmr) +{ + LOS_TRACE(SWTMR_STOP, swtmr->usTimerID); +} + +STATIC VOID LOS_TraceIpcWriteDrop(const IpcMsg *msg, UINT32 dstTid, UINT32 dstPid, UINT32 ipcStatus) +{ + LOS_TRACE(IPC_WRITE_DROP, dstTid, dstPid, msg->type, msg->code, ipcStatus); +} + +STATIC VOID LOS_TraceIpcWrite(const IpcMsg *msg, UINT32 dstTid, UINT32 dstPid, UINT32 ipcStatus) +{ + LOS_TRACE(IPC_WRITE, dstTid, dstPid, msg->type, msg->code, ipcStatus); +} + +STATIC VOID LOS_TraceIpcReadDrop(const IpcMsg *msg, UINT32 ipcStatus) +{ + LOS_TRACE(IPC_READ_DROP, msg->taskID, msg->processID, msg->type, msg->code, ipcStatus); +} + +STATIC VOID LOS_TraceIpcRead(const IpcMsg *msg, UINT32 ipcStatus) +{ + LOS_TRACE(IPC_READ_DROP, msg->taskID, msg->processID, msg->type, msg->code, ipcStatus); +} + +STATIC VOID LOS_TraceIpcTryRead(UINT32 msgType, UINT32 ipcStatus) +{ + LOS_TRACE(IPC_TRY_READ, msgType, ipcStatus); +} + +STATIC VOID LOS_TraceIpcReadTimeout(UINT32 msgType, UINT32 ipcStatus) +{ + LOS_TRACE(IPC_READ_TIMEOUT, msgType, ipcStatus); +} + +STATIC VOID LOS_TraceIpcKill(UINT32 msgType, UINT32 ipcStatus) +{ + LOS_TRACE(IPC_KILL, msgType, ipcStatus); +} + +STATIC VOID LOS_TraceUsrEvent(VOID *buffer, UINT32 len) +{ +#ifdef LOSCFG_DRIVERS_TRACE + UsrEventInfo *info = (UsrEventInfo *)buffer; + if ((info == NULL) || (len != sizeof(UsrEventInfo))) { + return; + } + LOS_TRACE_EASY(info->eventType & (~TRACE_USER_DEFAULT_FLAG), info->identity, info->params[0], info->params[1], + info->params[2]); /* 2, params num, no special meaning */ + LOS_MemFree(m_aucSysMem0, buffer); +#endif +} + +VOID OsTraceCnvInit(VOID) +{ + LOS_HookReg(LOS_HOOK_TYPE_MEM_ALLOC, LOS_TraceMemAlloc); + LOS_HookReg(LOS_HOOK_TYPE_MEM_FREE, LOS_TraceMemFree); + LOS_HookReg(LOS_HOOK_TYPE_MEM_INIT, LOS_TraceMemInit); + LOS_HookReg(LOS_HOOK_TYPE_MEM_REALLOC, LOS_TraceMemRealloc); + LOS_HookReg(LOS_HOOK_TYPE_MEM_ALLOCALIGN, LOS_TraceMemAllocAlign); + LOS_HookReg(LOS_HOOK_TYPE_EVENT_INIT, LOS_TraceEventInit); + LOS_HookReg(LOS_HOOK_TYPE_EVENT_READ, LOS_TraceEventRead); + LOS_HookReg(LOS_HOOK_TYPE_EVENT_WRITE, LOS_TraceEventWrite); + LOS_HookReg(LOS_HOOK_TYPE_EVENT_CLEAR, LOS_TraceEventClear); + LOS_HookReg(LOS_HOOK_TYPE_EVENT_DESTROY, LOS_TraceEventDestroy); + LOS_HookReg(LOS_HOOK_TYPE_QUEUE_CREATE, LOS_TraceQueueCreate); + LOS_HookReg(LOS_HOOK_TYPE_QUEUE_DELETE, LOS_TraceQueueDelete); + LOS_HookReg(LOS_HOOK_TYPE_QUEUE_READ, LOS_TraceQueueRW); + LOS_HookReg(LOS_HOOK_TYPE_QUEUE_WRITE, LOS_TraceQueueRW); + LOS_HookReg(LOS_HOOK_TYPE_SEM_CREATE, LOS_TraceSemCreate); + LOS_HookReg(LOS_HOOK_TYPE_SEM_DELETE, LOS_TraceSemDelete); + LOS_HookReg(LOS_HOOK_TYPE_SEM_POST, LOS_TraceSemPost); + LOS_HookReg(LOS_HOOK_TYPE_SEM_PEND, LOS_TraceSemPend); + LOS_HookReg(LOS_HOOK_TYPE_MUX_CREATE, LOS_TraceMuxCreate); + LOS_HookReg(LOS_HOOK_TYPE_MUX_POST, LOS_TraceMuxPost); + LOS_HookReg(LOS_HOOK_TYPE_MUX_PEND, LOS_TraceMuxPend); + LOS_HookReg(LOS_HOOK_TYPE_MUX_DELETE, LOS_TraceMuxDelete); + LOS_HookReg(LOS_HOOK_TYPE_TASK_PRIMODIFY, LOS_TraceTaskPriModify); + LOS_HookReg(LOS_HOOK_TYPE_TASK_DELETE, LOS_TraceTaskDelete); + LOS_HookReg(LOS_HOOK_TYPE_TASK_CREATE, LOS_TraceTaskCreate); + LOS_HookReg(LOS_HOOK_TYPE_TASK_SWITCHEDIN, LOS_TraceTaskSwitchedIn); + LOS_HookReg(LOS_HOOK_TYPE_MOVEDTASKTOREADYSTATE, LOS_TraceTaskResume); + LOS_HookReg(LOS_HOOK_TYPE_MOVEDTASKTOSUSPENDEDLIST, LOS_TraceTaskSuspend); + LOS_HookReg(LOS_HOOK_TYPE_ISR_ENTER, LOS_TraceIsrEnter); + LOS_HookReg(LOS_HOOK_TYPE_ISR_EXIT, LOS_TraceIsrExit); + LOS_HookReg(LOS_HOOK_TYPE_SWTMR_CREATE, LOS_TraceSwtmrCreate); + LOS_HookReg(LOS_HOOK_TYPE_SWTMR_DELETE, LOS_TraceSwtmrDelete); + LOS_HookReg(LOS_HOOK_TYPE_SWTMR_EXPIRED, LOS_TraceSwtmrExpired); + LOS_HookReg(LOS_HOOK_TYPE_SWTMR_START, LOS_TraceSwtmrStart); + LOS_HookReg(LOS_HOOK_TYPE_SWTMR_STOP, LOS_TraceSwtmrStop); + LOS_HookReg(LOS_HOOK_TYPE_USR_EVENT, LOS_TraceUsrEvent); + LOS_HookReg(LOS_HOOK_TYPE_IPC_WRITE_DROP, LOS_TraceIpcWriteDrop); + LOS_HookReg(LOS_HOOK_TYPE_IPC_WRITE, LOS_TraceIpcWrite); + LOS_HookReg(LOS_HOOK_TYPE_IPC_READ_DROP, LOS_TraceIpcReadDrop); + LOS_HookReg(LOS_HOOK_TYPE_IPC_READ, LOS_TraceIpcRead); + LOS_HookReg(LOS_HOOK_TYPE_IPC_TRY_READ, LOS_TraceIpcTryRead); + LOS_HookReg(LOS_HOOK_TYPE_IPC_READ_TIMEOUT, LOS_TraceIpcReadTimeout); + LOS_HookReg(LOS_HOOK_TYPE_IPC_KILL, LOS_TraceIpcKill); +} + diff --git a/src/kernel_liteos_a/kernel/extended/trace/cnv/trace_cnv.h b/src/kernel_liteos_a/kernel/extended/trace/cnv/trace_cnv.h new file mode 100644 index 00000000..f9f27b59 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/trace/cnv/trace_cnv.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _TRACE_CNV_H +#define _TRACE_CNV_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +extern VOID OsTraceCnvInit(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _TRACE_CNV_H */ diff --git a/src/kernel_liteos_a/kernel/extended/trace/los_trace.c b/src/kernel_liteos_a/kernel/extended/trace/los_trace.c new file mode 100644 index 00000000..7ece4516 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/trace/los_trace.c @@ -0,0 +1,427 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_trace_pri.h" +#include "trace_pipeline.h" +#include "los_memory.h" +#include "los_config.h" +#include "securec.h" +#include "trace_cnv.h" +#include "los_init.h" +#include "los_process.h" +#include "los_sched_pri.h" + +#ifdef LOSCFG_KERNEL_SMP +#include "los_mp.h" +#endif + +#ifdef LOSCFG_SHELL +#include "shcmd.h" +#include "shell.h" +#endif + +LITE_OS_SEC_BSS STATIC UINT32 g_traceEventCount; +LITE_OS_SEC_BSS STATIC volatile enum TraceState g_traceState = TRACE_UNINIT; +LITE_OS_SEC_DATA_INIT STATIC volatile BOOL g_enableTrace = FALSE; +LITE_OS_SEC_BSS STATIC UINT32 g_traceMask = TRACE_DEFAULT_MASK; + +TRACE_EVENT_HOOK g_traceEventHook = NULL; +TRACE_DUMP_HOOK g_traceDumpHook = NULL; + +#ifdef LOSCFG_TRACE_CONTROL_AGENT +LITE_OS_SEC_BSS STATIC UINT32 g_traceTaskId; +#endif + +#define EVENT_MASK 0xFFFFFFF0 +#define MIN(x, y) ((x) < (y) ? (x) : (y)) + +LITE_OS_SEC_BSS STATIC TRACE_HWI_FILTER_HOOK g_traceHwiFilterHook = NULL; + +#ifdef LOSCFG_KERNEL_SMP +LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_traceSpin); +#endif + +STATIC_INLINE BOOL OsTraceHwiFilter(UINT32 hwiNum) +{ + BOOL ret = ((hwiNum == NUM_HAL_INTERRUPT_UART) || (hwiNum == OS_TICK_INT_NUM)); +#ifdef LOSCFG_KERNEL_SMP + ret |= (hwiNum == LOS_MP_IPI_SCHEDULE); +#endif + if (g_traceHwiFilterHook != NULL) { + ret |= g_traceHwiFilterHook(hwiNum); + } + return ret; +} + +STATIC VOID OsTraceSetFrame(TraceEventFrame *frame, UINT32 eventType, UINTPTR identity, const UINTPTR *params, + UINT16 paramCount) +{ + INT32 i; + UINT32 intSave; + + (VOID)memset_s(frame, sizeof(TraceEventFrame), 0, sizeof(TraceEventFrame)); + + if (paramCount > LOSCFG_TRACE_FRAME_MAX_PARAMS) { + paramCount = LOSCFG_TRACE_FRAME_MAX_PARAMS; + } + + TRACE_LOCK(intSave); + frame->curTask = OsTraceGetMaskTid(LOS_CurTaskIDGet()); + frame->curPid = LOS_GetCurrProcessID(); + frame->identity = identity; + frame->curTime = HalClockGetCycles(); + frame->eventType = eventType; + +#ifdef LOSCFG_TRACE_FRAME_CORE_MSG + frame->core.cpuid = ArchCurrCpuid(); + frame->core.hwiActive = OS_INT_ACTIVE ? TRUE : FALSE; + frame->core.taskLockCnt = MIN(OsSchedLockCountGet(), 0xF); /* taskLockCnt is 4 bits, max value = 0xF */ + frame->core.paramCount = paramCount; +#endif + +#ifdef LOS_TRACE_FRAME_LR + /* Get the linkreg from stack fp and storage to frame */ + LOS_RecordLR(frame->linkReg, LOS_TRACE_LR_RECORD, LOS_TRACE_LR_RECORD, LOS_TRACE_LR_IGNORE); +#endif + +#ifdef LOSCFG_TRACE_FRAME_EVENT_COUNT + frame->eventCount = g_traceEventCount; + g_traceEventCount++; +#endif + TRACE_UNLOCK(intSave); + + for (i = 0; i < paramCount; i++) { + frame->params[i] = params[i]; + } +} + +VOID OsTraceSetObj(ObjData *obj, const LosTaskCB *tcb) +{ + errno_t ret; + SchedParam param = { 0 }; + (VOID)memset_s(obj, sizeof(ObjData), 0, sizeof(ObjData)); + + obj->id = OsTraceGetMaskTid(tcb->taskID); + tcb->ops->schedParamGet(tcb, ¶m); + obj->prio = param.priority; + + ret = strncpy_s(obj->name, LOSCFG_TRACE_OBJ_MAX_NAME_SIZE, tcb->taskName, LOSCFG_TRACE_OBJ_MAX_NAME_SIZE - 1); + if (ret != EOK) { + TRACE_ERROR("Task name copy failed!\n"); + } +} + +VOID OsTraceHook(UINT32 eventType, UINTPTR identity, const UINTPTR *params, UINT16 paramCount) +{ + TraceEventFrame frame; + if ((eventType == TASK_CREATE) || (eventType == TASK_PRIOSET)) { + OsTraceObjAdd(eventType, identity); /* handle important obj info, these can not be filtered */ + } + + if ((g_enableTrace == TRUE) && (eventType & g_traceMask)) { + UINTPTR id = identity; + if (TRACE_GET_MODE_FLAG(eventType) == TRACE_HWI_FLAG) { + if (OsTraceHwiFilter(identity)) { + return; + } + } else if (TRACE_GET_MODE_FLAG(eventType) == TRACE_TASK_FLAG) { + id = OsTraceGetMaskTid(identity); + } else if (eventType == MEM_INFO_REQ) { + LOS_MEM_POOL_STATUS status; + LOS_MemInfoGet((VOID *)identity, &status); + LOS_TRACE(MEM_INFO, identity, status.totalUsedSize, status.totalFreeSize); + return; + } + + OsTraceSetFrame(&frame, eventType, id, params, paramCount); + OsTraceWriteOrSendEvent(&frame); + } +} + +BOOL OsTraceIsEnable(VOID) +{ + return g_enableTrace; +} + +STATIC VOID OsTraceHookInstall(VOID) +{ + g_traceEventHook = OsTraceHook; +#ifdef LOSCFG_RECORDER_MODE_OFFLINE + g_traceDumpHook = OsTraceRecordDump; +#endif +} + +#ifdef LOSCFG_TRACE_CONTROL_AGENT +STATIC BOOL OsTraceCmdIsValid(const TraceClientCmd *msg) +{ + return ((msg->end == TRACE_CMD_END_CHAR) && (msg->cmd < TRACE_CMD_MAX_CODE)); +} + +STATIC VOID OsTraceCmdHandle(const TraceClientCmd *msg) +{ + if (!OsTraceCmdIsValid(msg)) { + return; + } + + switch (msg->cmd) { + case TRACE_CMD_START: + LOS_TraceStart(); + break; + case TRACE_CMD_STOP: + LOS_TraceStop(); + break; + case TRACE_CMD_SET_EVENT_MASK: + /* 4 params(UINT8) composition the mask(UINT32) */ + LOS_TraceEventMaskSet(TRACE_MASK_COMBINE(msg->param1, msg->param2, msg->param3, msg->param4)); + break; + case TRACE_CMD_RECODE_DUMP: + LOS_TraceRecordDump(TRUE); + break; + default: + break; + } +} + +VOID TraceAgent(VOID) +{ + UINT32 ret; + TraceClientCmd msg; + + while (1) { + (VOID)memset_s(&msg, sizeof(TraceClientCmd), 0, sizeof(TraceClientCmd)); + ret = OsTraceDataWait(); + if (ret == LOS_OK) { + OsTraceDataRecv((UINT8 *)&msg, sizeof(TraceClientCmd), 0); + OsTraceCmdHandle(&msg); + } + } +} + +STATIC UINT32 OsCreateTraceAgentTask(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S taskInitParam; + + (VOID)memset_s((VOID *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)TraceAgent; + taskInitParam.usTaskPrio = LOSCFG_TRACE_TASK_PRIORITY; + taskInitParam.pcName = "TraceAgent"; + taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; +#ifdef LOSCFG_KERNEL_SMP + taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_traceTaskId, &taskInitParam); + return ret; +} +#endif + +STATIC UINT32 OsTraceInit(VOID) +{ + UINT32 ret; + + if (g_traceState != TRACE_UNINIT) { + TRACE_ERROR("trace has been initialized already, the current state is :%d\n", g_traceState); + ret = LOS_ERRNO_TRACE_ERROR_STATUS; + goto LOS_ERREND; + } + +#ifdef LOSCFG_TRACE_CLIENT_INTERACT + ret = OsTracePipelineInit(); + if (ret != LOS_OK) { + goto LOS_ERREND; + } +#endif + +#ifdef LOSCFG_TRACE_CONTROL_AGENT + ret = OsCreateTraceAgentTask(); + if (ret != LOS_OK) { + TRACE_ERROR("trace init create agentTask error :0x%x\n", ret); + goto LOS_ERREND; + } +#endif + +#ifdef LOSCFG_RECORDER_MODE_OFFLINE + ret = OsTraceBufInit(LOSCFG_TRACE_BUFFER_SIZE); + if (ret != LOS_OK) { +#ifdef LOSCFG_TRACE_CONTROL_AGENT + (VOID)LOS_TaskDelete(g_traceTaskId); +#endif + goto LOS_ERREND; + } +#endif + + OsTraceHookInstall(); + OsTraceCnvInit(); + + g_traceEventCount = 0; + +#ifdef LOSCFG_RECORDER_MODE_ONLINE /* Wait trace client to start trace */ + g_enableTrace = FALSE; + g_traceState = TRACE_INITED; +#else + g_enableTrace = TRUE; + g_traceState = TRACE_STARTED; +#endif + return LOS_OK; +LOS_ERREND: + return ret; +} + +UINT32 LOS_TraceStart(VOID) +{ + UINT32 intSave; + UINT32 ret = LOS_OK; + + TRACE_LOCK(intSave); + if (g_traceState == TRACE_STARTED) { + goto START_END; + } + + if (g_traceState == TRACE_UNINIT) { + TRACE_ERROR("trace not inited, be sure LOS_TraceInit excute success\n"); + ret = LOS_ERRNO_TRACE_ERROR_STATUS; + goto START_END; + } + + OsTraceNotifyStart(); + + g_enableTrace = TRUE; + g_traceState = TRACE_STARTED; + + TRACE_UNLOCK(intSave); + LOS_TRACE(MEM_INFO_REQ, m_aucSysMem0); + return ret; +START_END: + TRACE_UNLOCK(intSave); + return ret; +} + +VOID LOS_TraceStop(VOID) +{ + UINT32 intSave; + + TRACE_LOCK(intSave); + if (g_traceState != TRACE_STARTED) { + goto STOP_END; + } + + g_enableTrace = FALSE; + g_traceState = TRACE_STOPED; + OsTraceNotifyStop(); +STOP_END: + TRACE_UNLOCK(intSave); +} + +VOID LOS_TraceEventMaskSet(UINT32 mask) +{ + g_traceMask = mask & EVENT_MASK; +} + +VOID LOS_TraceRecordDump(BOOL toClient) +{ + if (g_traceState != TRACE_STOPED) { + TRACE_ERROR("trace dump must after trace stopped , the current state is : %d\n", g_traceState); + return; + } + OsTraceRecordDump(toClient); +} + +OfflineHead *LOS_TraceRecordGet(VOID) +{ + return OsTraceRecordGet(); +} + +VOID LOS_TraceReset(VOID) +{ + if (g_traceState == TRACE_UNINIT) { + TRACE_ERROR("trace not inited, be sure LOS_TraceInit excute success\n"); + return; + } + + OsTraceReset(); +} + +VOID LOS_TraceHwiFilterHookReg(TRACE_HWI_FILTER_HOOK hook) +{ + UINT32 intSave; + + TRACE_LOCK(intSave); + g_traceHwiFilterHook = hook; + TRACE_UNLOCK(intSave); +} + +#ifdef LOSCFG_SHELL +LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdTraceSetMask(INT32 argc, const CHAR **argv) +{ + size_t mask; + CHAR *endPtr = NULL; + + if (argc >= 2) { /* 2:Just as number of parameters */ + PRINTK("\nUsage: trace_mask or trace_mask ID\n"); + return OS_ERROR; + } + + if (argc == 0) { + mask = TRACE_DEFAULT_MASK; + } else { + mask = strtoul(argv[0], &endPtr, 0); + } + LOS_TraceEventMaskSet((UINT32)mask); + return LOS_OK; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdTraceDump(INT32 argc, const CHAR **argv) +{ + BOOL toClient; + CHAR *endPtr = NULL; + + if (argc >= 2) { /* 2:Just as number of parameters */ + PRINTK("\nUsage: trace_dump or trace_dump [1/0]\n"); + return OS_ERROR; + } + + if (argc == 0) { + toClient = FALSE; + } else { + toClient = strtoul(argv[0], &endPtr, 0) != 0 ? TRUE : FALSE; + } + LOS_TraceRecordDump(toClient); + return LOS_OK; +} + +SHELLCMD_ENTRY(tracestart_shellcmd, CMD_TYPE_EX, "trace_start", 0, (CmdCallBackFunc)LOS_TraceStart); +SHELLCMD_ENTRY(tracestop_shellcmd, CMD_TYPE_EX, "trace_stop", 0, (CmdCallBackFunc)LOS_TraceStop); +SHELLCMD_ENTRY(tracesetmask_shellcmd, CMD_TYPE_EX, "trace_mask", 1, (CmdCallBackFunc)OsShellCmdTraceSetMask); +SHELLCMD_ENTRY(tracereset_shellcmd, CMD_TYPE_EX, "trace_reset", 0, (CmdCallBackFunc)LOS_TraceReset); +SHELLCMD_ENTRY(tracedump_shellcmd, CMD_TYPE_EX, "trace_dump", 1, (CmdCallBackFunc)OsShellCmdTraceDump); +#endif + +LOS_MODULE_INIT(OsTraceInit, LOS_INIT_LEVEL_KMOD_EXTENDED); diff --git a/src/kernel_liteos_a/kernel/extended/trace/los_trace_pri.h b/src/kernel_liteos_a/kernel/extended/trace/los_trace_pri.h new file mode 100644 index 00000000..7220327b --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/trace/los_trace_pri.h @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_TRACE_PRI_H +#define _LOS_TRACE_PRI_H + +#include "los_trace.h" +#include "los_task_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#ifdef LOSCFG_TRACE_CONTROL_AGENT +#define TRACE_CMD_END_CHAR 0xD +#endif + +#define TRACE_ERROR PRINT_ERR +#define TRACE_MODE_OFFLINE 0 +#define TRACE_MODE_ONLINE 1 + +/* just task and hwi were traced */ +#define TRACE_DEFAULT_MASK (TRACE_HWI_FLAG | TRACE_TASK_FLAG) +#define TRACE_CTL_MAGIC_NUM 0xDEADBEEF +#define TRACE_BIGLITTLE_WORD 0x12345678 +#define TRACE_VERSION(MODE) (0xFFFFFFFF & (MODE)) +#define TRACE_MASK_COMBINE(c1, c2, c3, c4) (((c1) << 24) | ((c2) << 16) | ((c3) << 8) | (c4)) + +#define TRACE_GET_MODE_FLAG(type) ((type) & 0xFFFFFFF0) + +#ifdef LOSCFG_KERNEL_SMP +extern SPIN_LOCK_S g_traceSpin; +#define TRACE_LOCK(state) LOS_SpinLockSave(&g_traceSpin, &(state)) +#define TRACE_UNLOCK(state) LOS_SpinUnlockRestore(&g_traceSpin, (state)) +#else +#define TRACE_LOCK(state) (state) = LOS_IntLock() +#define TRACE_UNLOCK(state) LOS_IntRestore(state) +#endif + +typedef VOID (*TRACE_DUMP_HOOK)(BOOL toClient); +extern TRACE_DUMP_HOOK g_traceDumpHook; + +enum TraceCmd { + TRACE_CMD_START = 1, + TRACE_CMD_STOP, + TRACE_CMD_SET_EVENT_MASK, + TRACE_CMD_RECODE_DUMP, + TRACE_CMD_MAX_CODE, +}; + +/** + * @ingroup los_trace + * struct to store the trace cmd from traceClient. + */ +typedef struct { + UINT8 cmd; + UINT8 param1; + UINT8 param2; + UINT8 param3; + UINT8 param4; + UINT8 param5; + UINT8 end; +} TraceClientCmd; + +/** + * @ingroup los_trace + * struct to store the event information + */ +typedef struct { + UINT32 cmd; /* trace start or stop cmd */ + UINT32 param; /* magic numb stand for notify msg */ +} TraceNotifyFrame; + +/** + * @ingroup los_trace + * struct to store the trace config information. + */ +typedef struct { + struct WriteCtrl { + UINT16 curIndex; /* The current record index */ + UINT16 maxRecordCount; /* The max num of track items */ + UINT16 curObjIndex; /* The current obj index */ + UINT16 maxObjCount; /* The max num of obj index */ + ObjData *objBuf; /* Pointer to obj info data */ + TraceEventFrame *frameBuf; /* Pointer to the track items */ + } ctrl; + OfflineHead *head; +} TraceOfflineHeaderInfo; + +extern UINT32 OsTraceGetMaskTid(UINT32 taskId); +extern VOID OsTraceSetObj(ObjData *obj, const LosTaskCB *tcb); +extern VOID OsTraceWriteOrSendEvent(const TraceEventFrame *frame); +extern VOID OsTraceObjAdd(UINT32 eventType, UINT32 taskId); +extern BOOL OsTraceIsEnable(VOID); +extern OfflineHead *OsTraceRecordGet(VOID); + +#ifdef LOSCFG_RECORDER_MODE_ONLINE +extern VOID OsTraceSendHead(VOID); +extern VOID OsTraceSendObjTable(VOID); +extern VOID OsTraceSendNotify(UINT32 type, UINT32 value); + +#define OsTraceNotifyStart() do { \ + OsTraceSendNotify(SYS_START, TRACE_CTL_MAGIC_NUM); \ + OsTraceSendHead(); \ + OsTraceSendObjTable(); \ + } while (0) + +#define OsTraceNotifyStop() do { \ + OsTraceSendNotify(SYS_STOP, TRACE_CTL_MAGIC_NUM); \ + } while (0) + +#define OsTraceReset() +#define OsTraceRecordDump(toClient) +#else +extern UINT32 OsTraceBufInit(UINT32 size); +extern VOID OsTraceReset(VOID); +extern VOID OsTraceRecordDump(BOOL toClient); +#define OsTraceNotifyStart() +#define OsTraceNotifyStop() +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_TRACE_PRI_H */ diff --git a/src/kernel_liteos_a/kernel/extended/trace/pipeline/serial/trace_pipeline_serial.c b/src/kernel_liteos_a/kernel/extended/trace/pipeline/serial/trace_pipeline_serial.c new file mode 100644 index 00000000..8c0c26f8 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/trace/pipeline/serial/trace_pipeline_serial.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "trace_pipeline_serial.h" +#include "trace_pipeline.h" + +#ifdef LOSCFG_TRACE_CONTROL_AGENT +UINT32 SerialPipelineInit(VOID) +{ + return uart_hwiCreate(); +} + +UINT32 SerialDataReceive(UINT8 *data, UINT32 size, UINT32 timeout) +{ + return uart_read(data, size, timeout); +} + +UINT32 SerialWait(VOID) +{ + return uart_wait_adapt(); +} + +#else + +UINT32 SerialPipelineInit(VOID) +{ + return LOS_OK; +} + +UINT32 SerialDataReceive(UINT8 *data, UINT32 size, UINT32 timeout) +{ + (VOID)data; + (VOID)size; + (VOID)timeout; + return LOS_OK; +} + +UINT32 SerialWait(VOID) +{ + return LOS_OK; +} +#endif + +VOID SerialDataSend(UINT16 len, UINT8 *data) +{ + UartPuts((CHAR *)data, len, 1); +} + +STATIC const TracePipelineOps g_serialOps = { + .init = SerialPipelineInit, + .dataSend = SerialDataSend, + .dataRecv = SerialDataReceive, + .wait = SerialWait, +}; + +UINT32 OsTracePipelineInit(VOID) +{ + OsTracePipelineReg(&g_serialOps); + return g_serialOps.init(); +} + diff --git a/src/kernel_liteos_a/kernel/extended/trace/pipeline/serial/trace_pipeline_serial.h b/src/kernel_liteos_a/kernel/extended/trace/pipeline/serial/trace_pipeline_serial.h new file mode 100644 index 00000000..3f2da50d --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/trace/pipeline/serial/trace_pipeline_serial.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _TRACE_PIPELINE_SERIAL_H +#define _TRACE_PIPELINE_SERIAL_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +extern VOID UartPuts(const CHAR *s, UINT32 len, BOOL isLock); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _TRACE_PIPELINE_SERIAL_H */ diff --git a/src/kernel_liteos_a/kernel/extended/trace/pipeline/trace_pipeline.c b/src/kernel_liteos_a/kernel/extended/trace/pipeline/trace_pipeline.c new file mode 100644 index 00000000..6ec57213 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/trace/pipeline/trace_pipeline.c @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "trace_pipeline.h" +#include "trace_tlv.h" +#include "los_trace_pri.h" + +#ifdef LOSCFG_KERNEL_SMP +LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_pipeSpin); +#define PIPE_LOCK(state) LOS_SpinLockSave(&g_pipeSpin, &(state)) +#define PIPE_UNLOCK(state) LOS_SpinUnlockRestore(&g_pipeSpin, (state)) +#else +#define PIPE_LOCK(state) (state) = LOS_IntLock() +#define PIPE_UNLOCK(state) LOS_IntRestore(state) +#endif + +STATIC TlvTable g_traceTlvTblNotify[] = { + { CMD, LOS_OFF_SET_OF(TraceNotifyFrame, cmd), sizeof(UINT32) }, + { PARAMS, LOS_OFF_SET_OF(TraceNotifyFrame, param), sizeof(UINT32) }, + { TRACE_TLV_TYPE_NULL, 0, 0 }, +}; + +STATIC TlvTable g_traceTlvTblHead[] = { + { ENDIAN, LOS_OFF_SET_OF(TraceBaseHeaderInfo, bigLittleEndian), sizeof(UINT32) }, + { VERSION, LOS_OFF_SET_OF(TraceBaseHeaderInfo, version), sizeof(UINT32) }, + { CLOCK_FREQ, LOS_OFF_SET_OF(TraceBaseHeaderInfo, clockFreq), sizeof(UINT32) }, + { TRACE_TLV_TYPE_NULL, 0, 0 }, +}; + +STATIC TlvTable g_traceTlvTblObj[] = { + { ADDR, LOS_OFF_SET_OF(ObjData, id), sizeof(UINT32) }, + { PRIO, LOS_OFF_SET_OF(ObjData, prio), sizeof(UINT32) }, + { NAME, LOS_OFF_SET_OF(ObjData, name), sizeof(CHAR) * LOSCFG_TRACE_OBJ_MAX_NAME_SIZE }, + { TRACE_TLV_TYPE_NULL, 0, 0 }, +}; + +STATIC TlvTable g_traceTlvTblEvent[] = { +#ifdef LOSCFG_TRACE_FRAME_CORE_MSG + { CORE, LOS_OFF_SET_OF(TraceEventFrame, core), sizeof(UINT32) }, +#endif + { EVENT_CODE, LOS_OFF_SET_OF(TraceEventFrame, eventType), sizeof(UINT32) }, + { CUR_TIME, LOS_OFF_SET_OF(TraceEventFrame, curTime), sizeof(UINT64) }, + +#ifdef LOSCFG_TRACE_FRAME_EVENT_COUNT + { EVENT_COUNT, LOS_OFF_SET_OF(TraceEventFrame, eventCount), sizeof(UINT32) }, +#endif + { CUR_TASK, LOS_OFF_SET_OF(TraceEventFrame, curTask), sizeof(UINT32) }, + { IDENTITY, LOS_OFF_SET_OF(TraceEventFrame, identity), sizeof(UINTPTR) }, + { EVENT_PARAMS, LOS_OFF_SET_OF(TraceEventFrame, params), sizeof(UINTPTR) * LOSCFG_TRACE_FRAME_MAX_PARAMS }, + { CUR_PID, LOS_OFF_SET_OF(TraceEventFrame, curPid), sizeof(UINT32) }, +#ifdef LOS_TRACE_FRAME_LR + { EVENT_LR, LOS_OFF_SET_OF(TraceEventFrame, linkReg), sizeof(UINTPTR) * LOS_TRACE_LR_RECORD }, +#endif + { TRACE_TLV_TYPE_NULL, 0, 0 }, +}; + +STATIC TlvTable *g_traceTlvTbl[] = { + g_traceTlvTblNotify, + g_traceTlvTblHead, + g_traceTlvTblObj, + g_traceTlvTblEvent +}; + +STATIC UINT32 DefaultPipelineInit(VOID) +{ + return LOS_OK; +} + +STATIC VOID DefaultDataSend(UINT16 len, UINT8 *data) +{ + (VOID)len; + (VOID)data; +} + +STATIC UINT32 DefaultDataReceive(UINT8 *data, UINT32 size, UINT32 timeout) +{ + (VOID)data; + (VOID)size; + (VOID)timeout; + return LOS_OK; +} + +STATIC UINT32 DefaultWait(VOID) +{ + return LOS_OK; +} + +STATIC TracePipelineOps g_defaultOps = { + .init = DefaultPipelineInit, + .dataSend = DefaultDataSend, + .dataRecv = DefaultDataReceive, + .wait = DefaultWait, +}; + +STATIC const TracePipelineOps *g_tracePipelineOps = &g_defaultOps; + +VOID OsTracePipelineReg(const TracePipelineOps *ops) +{ + g_tracePipelineOps = ops; +} + +VOID OsTraceDataSend(UINT8 type, UINT16 len, UINT8 *data) +{ + UINT32 intSave; + UINT8 outBuf[LOSCFG_TRACE_TLV_BUF_SIZE] = {0}; + + if ((type >= TRACE_MSG_MAX) || (len > LOSCFG_TRACE_TLV_BUF_SIZE)) { + return; + } + + len = OsTraceDataEncode(type, g_traceTlvTbl[type], data, &outBuf[0], sizeof(outBuf)); + + PIPE_LOCK(intSave); + g_tracePipelineOps->dataSend(len, &outBuf[0]); + PIPE_UNLOCK(intSave); +} + +UINT32 OsTraceDataRecv(UINT8 *data, UINT32 size, UINT32 timeout) +{ + return g_tracePipelineOps->dataRecv(data, size, timeout); +} + +UINT32 OsTraceDataWait(VOID) +{ + return g_tracePipelineOps->wait(); +} diff --git a/src/kernel_liteos_a/kernel/extended/trace/pipeline/trace_pipeline.h b/src/kernel_liteos_a/kernel/extended/trace/pipeline/trace_pipeline.h new file mode 100644 index 00000000..10c02967 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/trace/pipeline/trace_pipeline.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _TRACE_PIPELINE_H +#define _TRACE_PIPELINE_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef struct { + UINT32 (*init)(VOID); + VOID (*dataSend)(UINT16 len, UINT8 *data); + UINT32 (*dataRecv)(UINT8 *data, UINT32 size, UINT32 timeout); + UINT32 (*wait)(VOID); +} TracePipelineOps; + +/* used as tlv's tag */ +enum TraceMsgType { + NOTIFY, + HEAD, + OBJ, + EVENT, + TRACE_MSG_MAX, +}; + +enum TraceNotifySubType { + CMD = 0x1, + PARAMS, +}; + +enum TraceHeadSubType { + ENDIAN = 0x1, + VERSION, + OBJ_SIZE, + OBJ_COUNT, + CUR_INDEX, + MAX_RECODE, + CUR_OBJ_INDEX, + CLOCK_FREQ, +}; + +enum TraceObjSubType { + ADDR = 0x1, + PRIO, + NAME, +}; + +enum TraceEvtSubType { + CORE = 0x1, + EVENT_CODE, + CUR_TIME, + EVENT_COUNT, + CUR_TASK, + IDENTITY, + EVENT_PARAMS, + CUR_PID, + EVENT_LR, +}; + +extern VOID OsTracePipelineReg(const TracePipelineOps *ops); +extern UINT32 OsTracePipelineInit(VOID); + +extern VOID OsTraceDataSend(UINT8 type, UINT16 len, UINT8 *data); +extern UINT32 OsTraceDataRecv(UINT8 *data, UINT32 size, UINT32 timeout); +extern UINT32 OsTraceDataWait(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _TRACE_PIPELINE_H */ diff --git a/src/kernel_liteos_a/kernel/extended/trace/pipeline/trace_tlv.c b/src/kernel_liteos_a/kernel/extended/trace/pipeline/trace_tlv.c new file mode 100644 index 00000000..3fbc409c --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/trace/pipeline/trace_tlv.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "trace_tlv.h" +#include "securec.h" + +#define CRC_WIDTH 8 +#define CRC_POLY 0x1021 +#define CRC_TOPBIT 0x8000 + +STATIC UINT16 CalcCrc16(const UINT8 *buf, UINT32 len) +{ + UINT32 i; + UINT16 crc = 0; + + for (; len > 0; len--) { + crc = crc ^ (*buf++ << CRC_WIDTH); + for (i = 0; i < CRC_WIDTH; i++) { + if (crc & CRC_TOPBIT) { + crc = (crc << 1) ^ CRC_POLY; + } else { + crc <<= 1; + } + } + } + return crc; +} + +STATIC UINT32 OsWriteTlv(UINT8 *tlvBuf, UINT8 type, UINT8 len, UINT8 *value) +{ + TraceMsgTlvBody *body = (TraceMsgTlvBody *)tlvBuf; + + if (len == 0) { + return 0; + } + + body->type = type; + body->len = len; + /* Do not check return value for performance, if copy failed, only this package will be discarded */ + (VOID)memcpy_s(body->value, len, value, len); + return len + sizeof(body->type) + sizeof(body->len); +} + +STATIC UINT32 OsTlvEncode(const TlvTable *table, UINT8 *srcBuf, UINT8 *tlvBuf, INT32 tlvBufLen) +{ + UINT32 len = 0; + const TlvTable *tlvTableItem = table; + + while (tlvTableItem->tag != TRACE_TLV_TYPE_NULL) { + if ((len + tlvTableItem->elemSize + sizeof(UINT8) + sizeof(UINT8)) > tlvBufLen) { + break; + } + len += OsWriteTlv(tlvBuf + len, tlvTableItem->tag, tlvTableItem->elemSize, srcBuf + tlvTableItem->elemOffset); + tlvTableItem++; + } + return len; +} + +UINT32 OsTraceDataEncode(UINT8 type, const TlvTable *table, UINT8 *src, UINT8 *dest, INT32 destLen) +{ + UINT16 crc; + INT32 len; + INT32 tlvBufLen; + UINT8 *tlvBuf = NULL; + + TraceMsgTlvHead *head = (TraceMsgTlvHead *)dest; + tlvBufLen = destLen - sizeof(TraceMsgTlvHead); + + if ((tlvBufLen <= 0) || (table == NULL)) { + return 0; + } + + tlvBuf = dest + sizeof(TraceMsgTlvHead); + len = OsTlvEncode(table, src, tlvBuf, tlvBufLen); + crc = CalcCrc16(tlvBuf, len); + + head->magicNum = TRACE_TLV_MSG_HEAD; + head->msgType = type; + head->len = len; + head->crc = crc; + return len + sizeof(TraceMsgTlvHead); +} diff --git a/src/kernel_liteos_a/kernel/extended/trace/pipeline/trace_tlv.h b/src/kernel_liteos_a/kernel/extended/trace/pipeline/trace_tlv.h new file mode 100644 index 00000000..45d16f93 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/trace/pipeline/trace_tlv.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _TRACE_TLV_H +#define _TRACE_TLV_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define TRACE_TLV_MSG_HEAD 0xFF +#define TRACE_TLV_TYPE_NULL 0xFF + +typedef struct { + UINT8 magicNum; + UINT8 msgType; + UINT16 len; + UINT16 crc; +} TraceMsgTlvHead; + +typedef struct { + UINT8 type; + UINT8 len; + UINT8 value[]; +} TraceMsgTlvBody; + +typedef struct { + UINT8 tag; + UINT8 elemOffset; + UINT8 elemSize; +} TlvTable; + +/** + * @ingroup los_trace + * @brief Encode trace raw data. + * + * @par Description: + * This API is used to encode trace raw data to tlv data. + * @attention + *
            + *
          • Encade trace data
          • + *
          + * + * @param type [IN] Type #UINT8. The type stands for different struct of src data. + * @param src [IN] Type #UINT8 *. The raw trace data. + * @param table [IN] Type #const TlvTable *. The tlv table descript elemOffset and elemSize. + * @param dest [OUT] Type #UINT8 *. The tlv data. + * @param destLen [IN] Type #UINT8 *. The tlv buf max len. + + * @retval #0 convert failed. + * @retval #UINT32 convert success bytes. + * + * @par Dependency: + *
          • trace_tlv.h: the header file that contains the API declaration.
          + * @see OsTraceDataEncode + */ +extern UINT32 OsTraceDataEncode(UINT8 type, const TlvTable *table, UINT8 *src, UINT8 *dest, INT32 destLen); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _TRACE_TLV_H */ diff --git a/src/kernel_liteos_a/kernel/extended/trace/trace_offline.c b/src/kernel_liteos_a/kernel/extended/trace/trace_offline.c new file mode 100644 index 00000000..ad80087c --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/trace/trace_offline.c @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_trace_pri.h" +#include "trace_pipeline.h" + +#define BITS_NUM_FOR_TASK_ID 16 + +LITE_OS_SEC_BSS STATIC TraceOfflineHeaderInfo g_traceRecoder; +LITE_OS_SEC_BSS STATIC UINT32 g_tidMask[LOSCFG_BASE_CORE_TSK_LIMIT] = {0}; + +UINT32 OsTraceGetMaskTid(UINT32 tid) +{ + return tid | ((tid < LOSCFG_BASE_CORE_TSK_LIMIT) ? g_tidMask[tid] << BITS_NUM_FOR_TASK_ID : 0); /* tid < 65535 */ +} + +UINT32 OsTraceBufInit(UINT32 size) +{ + UINT32 headSize; + VOID *buf = NULL; + headSize = sizeof(OfflineHead) + sizeof(ObjData) * LOSCFG_TRACE_OBJ_MAX_NUM; + if (size <= headSize) { + TRACE_ERROR("trace buf size not enough than 0x%x\n", headSize); + return LOS_ERRNO_TRACE_BUF_TOO_SMALL; + } + + + buf = LOS_MemAlloc(m_aucSysMem0, size); + if (buf == NULL) { + return LOS_ERRNO_TRACE_NO_MEMORY; + } + + (VOID)memset_s(buf, size, 0, size); + g_traceRecoder.head = (OfflineHead *)buf; + g_traceRecoder.head->baseInfo.bigLittleEndian = TRACE_BIGLITTLE_WORD; + g_traceRecoder.head->baseInfo.version = TRACE_VERSION(TRACE_MODE_OFFLINE); + g_traceRecoder.head->baseInfo.clockFreq = OS_SYS_CLOCK; + g_traceRecoder.head->objSize = sizeof(ObjData); + g_traceRecoder.head->frameSize = sizeof(TraceEventFrame); + g_traceRecoder.head->objOffset = sizeof(OfflineHead); + g_traceRecoder.head->frameOffset = headSize; + g_traceRecoder.head->totalLen = size; + + g_traceRecoder.ctrl.curIndex = 0; + g_traceRecoder.ctrl.curObjIndex = 0; + g_traceRecoder.ctrl.maxObjCount = LOSCFG_TRACE_OBJ_MAX_NUM; + g_traceRecoder.ctrl.maxRecordCount = (size - headSize) / sizeof(TraceEventFrame); + g_traceRecoder.ctrl.objBuf = (ObjData *)((UINTPTR)buf + g_traceRecoder.head->objOffset); + g_traceRecoder.ctrl.frameBuf = (TraceEventFrame *)((UINTPTR)buf + g_traceRecoder.head->frameOffset); + + return LOS_OK; +} + +VOID OsTraceObjAdd(UINT32 eventType, UINT32 taskId) +{ + UINT32 intSave; + UINT32 index; + ObjData *obj = NULL; + + TRACE_LOCK(intSave); + /* add obj begin */ + index = g_traceRecoder.ctrl.curObjIndex; + if (index >= LOSCFG_TRACE_OBJ_MAX_NUM) { /* do nothing when config LOSCFG_TRACE_OBJ_MAX_NUM = 0 */ + TRACE_UNLOCK(intSave); + return; + } + obj = &g_traceRecoder.ctrl.objBuf[index]; + + if (taskId < LOSCFG_BASE_CORE_TSK_LIMIT) { + g_tidMask[taskId]++; + } + + OsTraceSetObj(obj, OS_TCB_FROM_TID(taskId)); + + g_traceRecoder.ctrl.curObjIndex++; + if (g_traceRecoder.ctrl.curObjIndex >= g_traceRecoder.ctrl.maxObjCount) { + g_traceRecoder.ctrl.curObjIndex = 0; /* turn around */ + } + /* add obj end */ + TRACE_UNLOCK(intSave); +} + +VOID OsTraceWriteOrSendEvent(const TraceEventFrame *frame) +{ + UINT16 index; + UINT32 intSave; + + TRACE_LOCK(intSave); + index = g_traceRecoder.ctrl.curIndex; + (VOID)memcpy_s(&g_traceRecoder.ctrl.frameBuf[index], sizeof(TraceEventFrame), frame, sizeof(TraceEventFrame)); + + g_traceRecoder.ctrl.curIndex++; + if (g_traceRecoder.ctrl.curIndex >= g_traceRecoder.ctrl.maxRecordCount) { + g_traceRecoder.ctrl.curIndex = 0; + } + TRACE_UNLOCK(intSave); +} + +VOID OsTraceReset(VOID) +{ + UINT32 intSave; + UINT32 bufLen; + + TRACE_LOCK(intSave); + bufLen = sizeof(TraceEventFrame) * g_traceRecoder.ctrl.maxRecordCount; + (VOID)memset_s(g_traceRecoder.ctrl.frameBuf, bufLen, 0, bufLen); + g_traceRecoder.ctrl.curIndex = 0; + TRACE_UNLOCK(intSave); +} + +STATIC VOID OsTraceInfoObj(VOID) +{ + UINT32 i; + ObjData *obj = &g_traceRecoder.ctrl.objBuf[0]; + + if (g_traceRecoder.ctrl.maxObjCount > 0) { + PRINTK("CurObjIndex = %u\n", g_traceRecoder.ctrl.curObjIndex); + PRINTK("Index TaskID TaskPrio TaskName \n"); + for (i = 0; i < g_traceRecoder.ctrl.maxObjCount; i++, obj++) { + PRINTK("%-7u 0x%-6x %-10u %s\n", i, obj->id, obj->prio, obj->name); + } + PRINTK("\n"); + } +} + +STATIC VOID OsTraceInfoEventTitle(VOID) +{ + PRINTK("CurEvtIndex = %u\n", g_traceRecoder.ctrl.curIndex); + + PRINTK("Index Time(cycles) EventType CurPid CurTask Identity "); +#ifdef LOSCFG_TRACE_FRAME_CORE_MSG + PRINTK("cpuid hwiActive taskLockCnt "); +#endif +#ifdef LOSCFG_TRACE_FRAME_EVENT_COUNT + PRINTK("eventCount "); +#endif +#ifdef LOS_TRACE_FRAME_LR + UINT32 i; + PRINTK("backtrace "); + for (i = 0; i < LOS_TRACE_LR_RECORD; i++) { + PRINTK(" "); + } +#endif + if (LOSCFG_TRACE_FRAME_MAX_PARAMS > 0) { + PRINTK("params "); + } + PRINTK("\n"); +} + +STATIC VOID OsTraceInfoEventData(VOID) +{ + UINT32 i, j; + TraceEventFrame *frame = &g_traceRecoder.ctrl.frameBuf[0]; + + for (i = 0; i < g_traceRecoder.ctrl.maxRecordCount; i++, frame++) { + PRINTK("%-7u 0x%-15llx 0x%-12x 0x%-7x 0x%-7x 0x%-11x ", i, frame->curTime, frame->eventType, + frame->curPid, frame->curTask, frame->identity); +#ifdef LOSCFG_TRACE_FRAME_CORE_MSG + UINT32 taskLockCnt = frame->core.taskLockCnt; +#ifdef LOSCFG_KERNEL_SMP + /* + * For smp systems, TRACE_LOCK will request taskLock, and this counter + * will increase by 1 in that case. + */ + taskLockCnt -= 1; +#endif + PRINTK("%-11u %-11u %-11u", frame->core.cpuid, frame->core.hwiActive, taskLockCnt); +#endif +#ifdef LOSCFG_TRACE_FRAME_EVENT_COUNT + PRINTK("%-11u", frame->eventCount); +#endif +#ifdef LOS_TRACE_FRAME_LR + for (j = 0; j < LOS_TRACE_LR_RECORD; j++) { + PRINTK("0x%-11x", frame->linkReg[j]); + } +#endif + for (j = 0; j < LOSCFG_TRACE_FRAME_MAX_PARAMS; j++) { + PRINTK("0x%-11x", frame->params[j]); + } + PRINTK("\n"); + } +} + +STATIC VOID OsTraceInfoDisplay(VOID) +{ + OfflineHead *head = g_traceRecoder.head; + + PRINTK("*******TraceInfo begin*******\n"); + PRINTK("clockFreq = %u\n", head->baseInfo.clockFreq); + + OsTraceInfoObj(); + + OsTraceInfoEventTitle(); + OsTraceInfoEventData(); + + PRINTK("*******TraceInfo end*******\n"); +} + +#ifdef LOSCFG_TRACE_CLIENT_INTERACT +STATIC VOID OsTraceSendInfo(VOID) +{ + UINT32 i; + ObjData *obj = NULL; + TraceEventFrame *frame = NULL; + + OsTraceDataSend(HEAD, sizeof(OfflineHead), (UINT8 *)g_traceRecoder.head); + + obj = &g_traceRecoder.ctrl.objBuf[0]; + for (i = 0; i < g_traceRecoder.ctrl.maxObjCount; i++) { + OsTraceDataSend(OBJ, sizeof(ObjData), (UINT8 *)(obj + i)); + } + + frame = &g_traceRecoder.ctrl.frameBuf[0]; + for (i = 0; i < g_traceRecoder.ctrl.maxRecordCount; i++) { + OsTraceDataSend(EVENT, sizeof(TraceEventFrame), (UINT8 *)(frame + i)); + } +} +#endif + +VOID OsTraceRecordDump(BOOL toClient) +{ + if (!toClient) { + OsTraceInfoDisplay(); + return; + } + +#ifdef LOSCFG_TRACE_CLIENT_INTERACT + OsTraceSendInfo(); +#endif +} + +OfflineHead *OsTraceRecordGet(VOID) +{ + return g_traceRecoder.head; +} diff --git a/src/kernel_liteos_a/kernel/extended/trace/trace_online.c b/src/kernel_liteos_a/kernel/extended/trace/trace_online.c new file mode 100644 index 00000000..f24d5eb0 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/trace/trace_online.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_trace_pri.h" +#include "trace_pipeline.h" + +UINT32 OsTraceGetMaskTid(UINT32 taskId) +{ + return taskId; +} + +VOID OsTraceSendHead(VOID) +{ + TraceBaseHeaderInfo head = { + .bigLittleEndian = TRACE_BIGLITTLE_WORD, + .version = TRACE_VERSION(TRACE_MODE_ONLINE), + .clockFreq = OS_SYS_CLOCK, + }; + + OsTraceDataSend(HEAD, sizeof(TraceBaseHeaderInfo), (UINT8 *)&head); +} + +VOID OsTraceSendNotify(UINT32 type, UINT32 value) +{ + TraceNotifyFrame frame = { + .cmd = type, + .param = value, + }; + + OsTraceDataSend(NOTIFY, sizeof(TraceNotifyFrame), (UINT8 *)&frame); +} + +STATIC VOID OsTraceSendObj(const LosTaskCB *tcb) +{ + ObjData obj; + + OsTraceSetObj(&obj, tcb); + OsTraceDataSend(OBJ, sizeof(ObjData), (UINT8 *)&obj); +} + +VOID OsTraceSendObjTable(VOID) +{ + UINT32 loop; + LosTaskCB *tcb = NULL; + + for (loop = 0; loop < g_taskMaxNum; ++loop) { + tcb = g_taskCBArray + loop; + if (tcb->taskStatus & OS_TASK_STATUS_UNUSED) { + continue; + } + OsTraceSendObj(tcb); + } +} + +VOID OsTraceObjAdd(UINT32 eventType, UINT32 taskId) +{ + if (OsTraceIsEnable()) { + OsTraceSendObj(OS_TCB_FROM_TID(taskId)); + } +} + +VOID OsTraceWriteOrSendEvent(const TraceEventFrame *frame) +{ + OsTraceDataSend(EVENT, sizeof(TraceEventFrame), (UINT8 *)frame); +} + +OfflineHead *OsTraceRecordGet(VOID) +{ + return NULL; +} diff --git a/src/kernel_liteos_a/kernel/extended/vdso/BUILD.gn b/src/kernel_liteos_a/kernel/extended/vdso/BUILD.gn new file mode 100644 index 00000000..5df0a132 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/vdso/BUILD.gn @@ -0,0 +1,55 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = defined(LOSCFG_KERNEL_VDSO) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ + "src/los_vdso.c", + "src/los_vdso_text.S", + ] + + asmflags = [ "-DOHOS_VDSO_SO=\"OHOS-vdso.so\"" ] + deps = [ ":copy_ohos_vdso" ] + public_configs = [ ":public" ] +} + +config("public") { + include_dirs = [ "include" ] +} + +if (module_switch) { + copy("copy_ohos_vdso") { + deps = [ "usr:OHOS-vdso" ] + sources = [ get_path_info("usr/", "out_dir") + "/libOHOS-vdso.so" ] + outputs = [ "$root_out_dir/OHOS-vdso.so" ] + } +} diff --git a/src/kernel_liteos_a/kernel/extended/vdso/include/los_vdso.h b/src/kernel_liteos_a/kernel/extended/vdso/include/los_vdso.h new file mode 100644 index 00000000..aedc4592 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/vdso/include/los_vdso.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_VDSO_H +#define _LOS_VDSO_H + +#include "los_typedef.h" +#include "los_process_pri.h" +#include "los_hw.h" +#include "los_vdso_datapage.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +extern UINT32 OsVdsoInit(VOID); +extern vaddr_t OsVdsoLoad(const LosProcessCB *); +extern VOID OsVdsoTimevalUpdate(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_VDSO_H */ diff --git a/src/kernel_liteos_a/kernel/extended/vdso/include/los_vdso_datapage.h b/src/kernel_liteos_a/kernel/extended/vdso/include/los_vdso_datapage.h new file mode 100644 index 00000000..3df321a4 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/vdso/include/los_vdso_datapage.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_VDSO_DATAPAGE_H +#define _LOS_VDSO_DATAPAGE_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef struct { + /* Timeval */ + INT64 realTimeSec; + INT64 realTimeNsec; + INT64 monoTimeSec; + INT64 monoTimeNsec; + /* lock DataPage 0:Unlock State 1:Lock State */ + UINT64 lockCount; +} VdsoDataPage; + +#define ELF_HEAD "\177ELF" +#define ELF_HEAD_LEN 4 +#define MAX_PAGES 5 + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_VDSO_DATAPAGE_H */ \ No newline at end of file diff --git a/src/kernel_liteos_a/kernel/extended/vdso/include/los_vdso_pri.h b/src/kernel_liteos_a/kernel/extended/vdso/include/los_vdso_pri.h new file mode 100644 index 00000000..3e56a487 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/vdso/include/los_vdso_pri.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_VDSO_PRI_H +#define _LOS_VDSO_PRI_H + +#include "los_vdso.h" +#include "los_printf.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define LITE_VDSO_DATAPAGE __attribute__((section(".data.vdso.datapage"))) + +extern VOID OsVdsoTimeGet(VdsoDataPage *); + +extern CHAR __vdso_data_start; +extern CHAR __vdso_text_start; +extern CHAR __vdso_text_end; + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ +#endif /* _LOS_VDSO_PRI_H */ \ No newline at end of file diff --git a/src/kernel_liteos_a/kernel/extended/vdso/src/Makefile b/src/kernel_liteos_a/kernel/extended/vdso/src/Makefile new file mode 100644 index 00000000..ee2c229d --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/vdso/src/Makefile @@ -0,0 +1,38 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)/../vdso) + +LOCAL_SRCS := $(wildcard *.c) $(wildcard *.S) + +LOCAL_FLAGS := -DOHOS_VDSO_SO=\"$(OUT)/lib/OHOS-vdso.so\" + +include $(MODULE) \ No newline at end of file diff --git a/src/kernel_liteos_a/kernel/extended/vdso/src/los_vdso.c b/src/kernel_liteos_a/kernel/extended/vdso/src/los_vdso.c new file mode 100644 index 00000000..80b2cc56 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/vdso/src/los_vdso.c @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_vdso_pri.h" +#include "los_vdso_datapage.h" +#include "los_init.h" +#include "los_vm_map.h" +#include "los_vm_lock.h" +#include "los_vm_phys.h" +#include "los_process_pri.h" + +LITE_VDSO_DATAPAGE VdsoDataPage g_vdsoDataPage __attribute__((__used__)); + +STATIC size_t g_vdsoSize; + +UINT32 OsVdsoInit(VOID) +{ + g_vdsoSize = &__vdso_text_end - &__vdso_data_start; + + if (memcmp((CHAR *)(&__vdso_text_start), ELF_HEAD, ELF_HEAD_LEN)) { + PRINT_ERR("VDSO Init Failed!\n"); + return LOS_NOK; + } + return LOS_OK; +} + +LOS_MODULE_INIT(OsVdsoInit, LOS_INIT_LEVEL_KMOD_EXTENDED); + +STATIC INT32 OsVdsoMap(LosVmSpace *space, size_t len, PADDR_T paddr, VADDR_T vaddr, UINT32 flag) +{ + STATUS_T ret; + + while (len > 0) { + ret = LOS_ArchMmuMap(&(space->archMmu), vaddr, paddr, 1, flag); + if (ret != 1) { + PRINT_ERR("VDSO Load Failed! : LOS_ArchMmuMap!\n"); + return LOS_NOK; + } + paddr += PAGE_SIZE; + vaddr += PAGE_SIZE; + len -= PAGE_SIZE; + } + return LOS_OK; +} + +vaddr_t OsVdsoLoad(const LosProcessCB *processCB) +{ + INT32 ret = -1; + LosVmMapRegion *vdsoRegion = NULL; + UINT32 flag = VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_EXECUTE; + + if ((processCB == NULL) || (processCB->vmSpace == NULL)) { + return 0; + } + + (VOID)LOS_MuxAcquire(&processCB->vmSpace->regionMux); + + vdsoRegion = LOS_RegionAlloc(processCB->vmSpace, 0, g_vdsoSize, flag, 0); + if (vdsoRegion == NULL) { + PRINT_ERR("%s %d, region alloc failed in vdso load\n", __FUNCTION__, __LINE__); + goto LOCK_RELEASE; + } + vdsoRegion->regionFlags |= VM_MAP_REGION_FLAG_VDSO; + + ret = OsVdsoMap(processCB->vmSpace, g_vdsoSize, LOS_PaddrQuery((VOID *)(&__vdso_data_start)), + vdsoRegion->range.base, flag); + if (ret != LOS_OK) { + ret = LOS_RegionFree(processCB->vmSpace, vdsoRegion); + if (ret) { + PRINT_ERR("%s %d, free region failed, ret = %d\n", __FUNCTION__, __LINE__, ret); + } + ret = -1; + } + +LOCK_RELEASE: + (VOID)LOS_MuxRelease(&processCB->vmSpace->regionMux); + if (ret == LOS_OK) { + return (vdsoRegion->range.base + PAGE_SIZE); + } + return 0; +} + +STATIC VOID LockVdsoDataPage(VdsoDataPage *vdsoDataPage) +{ + vdsoDataPage->lockCount = 1; + DMB; +} + +STATIC VOID UnlockVdsoDataPage(VdsoDataPage *vdsoDataPage) +{ + DMB; + vdsoDataPage->lockCount = 0; +} + +VOID OsVdsoTimevalUpdate(VOID) +{ + VdsoDataPage *kVdsoDataPage = (VdsoDataPage *)(&__vdso_data_start); + + LockVdsoDataPage(kVdsoDataPage); + OsVdsoTimeGet(kVdsoDataPage); + UnlockVdsoDataPage(kVdsoDataPage); +} diff --git a/src/kernel_liteos_a/kernel/extended/vdso/src/los_vdso_text.S b/src/kernel_liteos_a/kernel/extended/vdso/src/los_vdso_text.S new file mode 100644 index 00000000..c8e1f268 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/vdso/src/los_vdso_text.S @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + .globl __vdso_text_start + .section .data.vdso.text +__vdso_text_start: + .incbin OHOS_VDSO_SO \ No newline at end of file diff --git a/src/kernel_liteos_a/kernel/extended/vdso/usr/BUILD.gn b/src/kernel_liteos_a/kernel/extended/vdso/usr/BUILD.gn new file mode 100644 index 00000000..3a3702a4 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/vdso/usr/BUILD.gn @@ -0,0 +1,51 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +shared_library("OHOS-vdso") { + sources = [ "los_vdso_sys.c" ] + + include_dirs = [ + "$LITEOSTOPDIR/kernel/extended/vdso/include", + "$LITEOSTOPDIR/kernel/include", + "$LITEOSTOPDIR/bsd/compat/linuxkpi/include", + ] + + configs -= [ "//build/lite/config:security" ] + + ldflags = [ + "-nostdlib", + "-Wl,-Bsymbolic", + "-Wl,-T" + rebase_path("los_vdso.ld", root_build_dir), + ] + + inputs = [ "los_vdso.ld" ] + output_dir = target_out_dir +} diff --git a/src/kernel_liteos_a/kernel/extended/vdso/usr/Makefile b/src/kernel_liteos_a/kernel/extended/vdso/usr/Makefile new file mode 100644 index 00000000..1a52dc33 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/vdso/usr/Makefile @@ -0,0 +1,50 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +VDSO_SO = $(OUT)/lib/OHOS-vdso.so + +VDSO_SRCS := los_vdso_sys.c +VDSO_INCLUDE := -I $(LITEOSTOPDIR)/kernel/extended/vdso/include \ + -I $(LITEOSTOPDIR)/kernel/include \ + -I $(LITEOSTOPDIR)/platform \ + -I $(LITEOSTOPDIR)/bsd/compat/linuxkpi/include + +VDSO_CCFLAGS := $(filter-out -nostdinc,$(LITEOS_COPTS)) +VDSO_CCFLAGS += -fPIC -O2 -D_XOPEN_SOURCE=700 + +VDSO_LDFLAGS := -shared -Wl,-s,-Bsymbolic,-Tlos_vdso.ld + +all: $(VDSO_SO) +$(VDSO_SO): $(VDSO_SRCS) + $(HIDE)$(CC) $(VDSO_INCLUDE) $(VDSO_CCFLAGS) $(VDSO_LDFLAGS) -o $@ $^ + +clean: + $(HIDE)$(RM) $(VDSO_SO) diff --git a/src/kernel_liteos_a/kernel/extended/vdso/usr/los_vdso.ld b/src/kernel_liteos_a/kernel/extended/vdso/usr/los_vdso.ld new file mode 100644 index 00000000..5aa7b9d1 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/vdso/usr/los_vdso.ld @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") +OUTPUT_ARCH(arm) + +SECTIONS +{ + . = SIZEOF_HEADERS; + + .hash : { *(.hash) } :text + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + + .dynamic : { *(.dynamic) } :text :dynamic + + .rodata : { *(.rodata*) } :text + + .text : { *(.text*) } :text + + /DISCARD/ : { + *(.data .data.* .sdata*) + *(.bss .sbss .dynbss .dynsbss) + } +} + +PHDRS +{ + text PT_LOAD FLAGS(5) FILEHDR PHDRS; + dynamic PT_DYNAMIC FLAGS(4); +} + +VERSION +{ + OHOS { + global: + VdsoClockGettime; + local: *; + }; +} diff --git a/src/kernel_liteos_a/kernel/extended/vdso/usr/los_vdso_sys.c b/src/kernel_liteos_a/kernel/extended/vdso/usr/los_vdso_sys.c new file mode 100644 index 00000000..14a72109 --- /dev/null +++ b/src/kernel_liteos_a/kernel/extended/vdso/usr/los_vdso_sys.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "asm/page.h" +#include "time.h" +#include "sys/time.h" +#include "los_typedef.h" +#include "los_vdso_datapage.h" + +STATIC INT32 VdsoGetRealtimeCoarse(struct timespec *ts, const VdsoDataPage *usrVdsoDataPage) +{ + do { + if (!usrVdsoDataPage->lockCount) { + ts->tv_sec = usrVdsoDataPage->realTimeSec; + ts->tv_nsec = usrVdsoDataPage->realTimeNsec; + return 0; + } + } while (1); +} + +STATIC INT32 VdsoGetMonotimeCoarse(struct timespec *ts, const VdsoDataPage *usrVdsoDataPage) +{ + do { + if (!usrVdsoDataPage->lockCount) { + ts->tv_sec = usrVdsoDataPage->monoTimeSec; + ts->tv_nsec = usrVdsoDataPage->monoTimeNsec; + return 0; + } + } while (1); +} + +STATIC size_t LocVdsoStart(size_t vdsoStart, const CHAR *elfHead, const size_t len) +{ + CHAR *head = NULL; + INT32 i; + INT32 loop; + + for (i = 1; i <= MAX_PAGES; i++) { + head = (CHAR *)((UINTPTR)vdsoStart); + for (loop = len; loop >= 1; loop--) { + if (*head++ != *(elfHead + len - loop)) { + break; + } + } + if (loop) { + vdsoStart -= PAGE_SIZE; + } else { + break; + } + } + + if (i > MAX_PAGES) { + return 0; + } + return (vdsoStart - PAGE_SIZE); +} + +INT32 VdsoClockGettime(clockid_t clk, struct timespec *ts) +{ + INT32 ret; + size_t vdsoStart; + + __asm__ __volatile__("mov %0, pc" : "=r"(vdsoStart)); + vdsoStart = vdsoStart - (vdsoStart & (PAGE_SIZE - 1)); + vdsoStart = LocVdsoStart(vdsoStart, ELF_HEAD, ELF_HEAD_LEN); + if (vdsoStart == 0) { + return -1; + } + + VdsoDataPage *usrVdsoDataPage = (VdsoDataPage *)(UINTPTR)vdsoStart; + + switch (clk) { + case CLOCK_REALTIME_COARSE: + ret = VdsoGetRealtimeCoarse(ts, usrVdsoDataPage); + break; + case CLOCK_MONOTONIC_COARSE: + ret = VdsoGetMonotimeCoarse(ts, usrVdsoDataPage); + break; + default: + ret = -1; + break; + } + + return ret; +} diff --git a/src/kernel_liteos_a/kernel/include/los_base.h b/src/kernel_liteos_a/kernel/include/los_base.h new file mode 100644 index 00000000..bf3ceed6 --- /dev/null +++ b/src/kernel_liteos_a/kernel/include/los_base.h @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup kernel Kernel + * @defgroup los_base Basic definitions + * @ingroup kernel + */ + +#ifndef _LOS_BASE_H +#define _LOS_BASE_H + +#include "los_builddef.h" +#include "los_typedef.h" +#include "los_config.h" +#include "los_printf.h" +#include "los_list.h" +#include "los_err.h" +#include "los_errno.h" +#include "los_hw.h" +#include "los_hwi.h" +#include "securec.h" +#include "los_exc.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + + +#define SIZE(a) (a) + +#define LOS_ASSERT_COND(expression) LOS_ASSERT(expression) + +extern VOID PrintExcInfo(const CHAR *fmt, ...); + +/** + * @ingroup los_base + * Define the timeout interval as LOS_NO_WAIT. + */ +#define LOS_NO_WAIT 0 + +/** + * @ingroup los_base + * Define the timeout interval as LOS_WAIT_FOREVER. + */ +#define LOS_WAIT_FOREVER 0xFFFFFFFF + +/** + * @ingroup los_base + * Align the beginning of the object with the base address addr, with boundary bytes being the smallest unit of + * alignment. + */ +#ifndef ALIGN +#define ALIGN(addr, boundary) LOS_Align(addr, boundary) +#endif + +/** + * @ingroup los_base + * Align the tail of the object with the base address addr, with size bytes being the smallest unit of alignment. + */ +#define TRUNCATE(addr, size) ((UINTPTR)(addr) & ~((size) - 1)) + +/** + * @ingroup los_base + * Read a UINT8 value from addr and stored in value. + */ +#define READ_UINT8(value, addr) ({ (value) = *((volatile UINT8 *)((UINTPTR)(addr))); DSB; }) + +/** + * @ingroup los_base + * Read a UINT16 value from addr and stored in addr. + */ +#define READ_UINT16(value, addr) ({ (value) = *((volatile UINT16 *)((UINTPTR)(addr))); DSB; }) + +/** + * @ingroup los_base + * Read a UINT32 value from addr and stored in value. + */ +#define READ_UINT32(value, addr) ({ (value) = *((volatile UINT32 *)((UINTPTR)(addr))); DSB; }) + +/** + * @ingroup los_base + * Read a UINT64 value from addr and stored in value. + */ +#define READ_UINT64(value, addr) ({ (value) = *((volatile UINT64 *)((UINTPTR)(addr))); DSB; }) + +/** + * @ingroup los_base + * Write a UINT8 value to addr. + */ +#define WRITE_UINT8(value, addr) ({ DSB; *((volatile UINT8 *)((UINTPTR)(addr))) = (value); }) + +/** + * @ingroup los_base + * Write a UINT16 value to addr. + */ +#define WRITE_UINT16(value, addr) ({ DSB; *((volatile UINT16 *)((UINTPTR)(addr))) = (value); }) + +/** + * @ingroup los_base + * Write a UINT32 value to addr. + */ +#define WRITE_UINT32(value, addr) ({ DSB; *((volatile UINT32 *)((UINTPTR)(addr))) = (value); }) + +/** + * @ingroup los_base + * Write a UINT64 addr to addr. + */ +#define WRITE_UINT64(value, addr) ({ DSB; *((volatile UINT64 *)((UINTPTR)(addr))) = (value); }) + +/** + * @ingroup los_base + * Get a UINT8 value from addr. + */ +#define GET_UINT8(addr) ({ UINT8 r = *((volatile UINT8 *)((UINTPTR)(addr))); DSB; r; }) + +/** + * @ingroup los_base + * Get a UINT16 value from addr. + */ +#define GET_UINT16(addr) ({ UINT16 r = *((volatile UINT16 *)((UINTPTR)(addr))); DSB; r; }) + +/** + * @ingroup los_base + * Get a UINT32 value from addr. + */ +#define GET_UINT32(addr) ({ UINT32 r = *((volatile UINT32 *)((UINTPTR)(addr))); DSB; r; }) + +/** + * @ingroup los_base + * Get a UINT64 value from addr. + */ +#define GET_UINT64(addr) ({ UINT64 r = *((volatile UINT64 *)((UINTPTR)(addr))); l; r; }) + +#ifdef LOSCFG_DEBUG_VERSION +#define LOS_ASSERT(judge) do { \ + if ((UINT32)(judge) == 0) { \ + (VOID)LOS_IntLock(); \ + PRINT_ERR("ASSERT ERROR! %s, %d, %s\n", __FILE__, __LINE__, __FUNCTION__); \ + OsBackTrace(); \ + while (1) {} \ + } \ +} while (0) + +#define LOS_ASSERT_MSG(judge, msg) do { \ + if ((UINT32)(judge) == 0) { \ + (VOID)LOS_IntLock(); \ + PRINT_ERR("ASSERT ERROR! %s, %d, %s\n", __FILE__, __LINE__, __FUNCTION__); \ + PRINT_ERR msg; \ + OsBackTrace(); \ + while (1) {} \ + } \ +} while (0) + +#else +#define LOS_ASSERT(judge) +#define LOS_ASSERT_MSG(judge, msg) +#endif + +#define STATIC_ASSERT _Static_assert + +/** + * @ingroup los_base + * @brief Align the value (addr) by some bytes (boundary) you specify. + * + * @par Description: + * This API is used to align the value (addr) by some bytes (boundary) you specify. + * + * @attention + *
            + *
          • the value of boundary usually is 4,8,16,32.
          • + *
          + * + * @param addr [IN] The variable what you want to align. + * @param boundary [IN] The align size what you want to align. + * + * @retval #UINTPTR The variable what have been aligned. + * @par Dependency: + *
          • los_base.h: the header file that contains the API declaration.
          + * @see + */ +extern UINTPTR LOS_Align(UINTPTR addr, UINT32 boundary); + +/** + * @ingroup los_base + * @brief Sleep the current task. + * + * @par Description: + * This API is used to delay the execution of the current task. The task is able to be scheduled after it is delayed + * for a specified number of Ticks. + * + * @attention + *
            + *
          • The task fails to be delayed if it is being delayed during interrupt processing or it is locked.
          • + *
          • If 0 is passed in and the task scheduling is not locked, execute the next task in the queue of tasks with the + * priority of the current task. + * If no ready task with the priority of the current task is available, the task scheduling will not occur, and the + * current task continues to be executed.
          • + *
          • The parameter passed in can not be equal to LOS_WAIT_FOREVER(0xFFFFFFFF). + * If that happens, the task will not sleep 0xFFFFFFFF milliseconds or sleep forever but sleep 0xFFFFFFFF Ticks.
          • + *
          + * + * @param msecs [IN] Type #UINT32 Number of MS for which the task is delayed. + * + * @retval None + * @par Dependency: + *
          • los_base.h: the header file that contains the API declaration.
          + * @see None + */ +extern VOID LOS_Msleep(UINT32 msecs); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_BASE_H */ diff --git a/src/kernel_liteos_a/kernel/include/los_bitmap.h b/src/kernel_liteos_a/kernel/include/los_bitmap.h new file mode 100644 index 00000000..617c84cd --- /dev/null +++ b/src/kernel_liteos_a/kernel/include/los_bitmap.h @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_bitmap Bitmap + * @ingroup kernel + */ + +#ifndef _LOS_BITMAP_H +#define _LOS_BITMAP_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/* Trick to get a 1 of the right size */ +#define _ONE(x) (1 + ((x) - (x))) +#define BIT(n) (1U << (n)) +#define BIT_GET(x, bit) ((x) & (_ONE(x) << (bit))) +#define BIT_SHIFT(x, bit) (((x) >> (bit)) & 1) +#define BITS_GET(x, high, low) ((x) & (((_ONE(x) << ((high) + 1)) - 1) & ~((_ONE(x) << (low)) - 1))) +#define BITS_SHIFT(x, high, low) (((x) >> (low)) & ((_ONE(x) << ((high) - (low) + 1)) - 1)) +#define BIT_SET(x, bit) (((x) & (_ONE(x) << (bit))) ? 1 : 0) +#define BITMAP_BITS_PER_WORD (sizeof(UINTPTR) * 8) +#define BITMAP_NUM_WORDS(x) (((x) + BITMAP_BITS_PER_WORD - 1) / BITMAP_BITS_PER_WORD) +#define BITMAP_WORD(x) ((x) / BITMAP_BITS_PER_WORD) +#define BITMAP_BIT_IN_WORD(x) ((x) & (BITMAP_BITS_PER_WORD - 1)) +#define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) % BITMAP_BITS_PER_WORD)) +#define BITMAP_LAST_WORD_MASK(nbits) \ + (((nbits) % BITMAP_BITS_PER_WORD) ? (1UL << ((nbits) % BITMAP_BITS_PER_WORD)) - 1 : ~0UL) +#define BITMAP_BITS_PER_INT (sizeof(INTPTR) * 8) +#define BITMAP_BIT_IN_INT(x) ((x) & (BITMAP_BITS_PER_INT - 1)) +#define BITMAP_INT(x) ((x) / BITMAP_BITS_PER_INT) +#define BIT_MASK(x) (((x) >= sizeof(UINTPTR) * 8) ? (0UL - 1) : ((1UL << (x)) - 1)) + +/** + * @ingroup los_bitmap + * Flag that indicates the invalid bit index. + * + * The effective bit index is from 0 to 31. + */ +#define LOS_INVALID_BIT_INDEX 32 + +/** + * @ingroup los_bitmap + * @brief Set one bit. + * + * @par Description: + * This API is used to set one bit of variable according to the parameter. + * @attention + *
            + *
          • When the value of pos is greater than 31, the bit (pos & 0x1f) of bitmap will be set.
          • + *
          + * @param bitmap [IN] The bitmap variable pointer. + * @param pos [IN] The number bit to be set. + * + * @retval None + * @par Dependency: + *
          • los_bitmap.h: the header file that contains the API declaration.
          + * @see LOS_BitmapClr + */ +VOID LOS_BitmapSet(UINT32 *bitmap, UINT16 pos); + +/** + * @ingroup los_bitmap + * @brief Clear one bit. + * + * @par Description: + * This API is used to clear one bit of variable according to the parameter. + * @attention + *
            + *
          • When the value of pos is greater than 31, the bit (pos & 0x1f) of bitmap will be clear.
          • + *
          + * @param bitmap [IN] The bitmap variable pointer. + * @param pos [IN] The number bit to be cleared. + * + * @retval none. + * @par Dependency: + *
          • los_bitmap.h: the header file that contains the API declaration.
          + * @see LOS_BitmapSet. + */ +VOID LOS_BitmapClr(UINT32 *bitmap, UINT16 pos); + +/** + * @ingroup los_bitmap + * @brief Find the lowest one bit that is set. + * + * @par Description: + * This API is used to find the lowest one bit that is set and return the bit index. + * @attention + *
            + *
          • None
          • + *
          + * @param bitmap [IN] The bitmap variable. + * + * @retval UINT16 The bit index of the lowest one bit that is set. + * @par Dependency: + *
          • los_bitmap.h: the header file that contains the API declaration.
          + * @see LOS_HighBitGet + */ +UINT16 LOS_LowBitGet(UINT32 bitmap); + +/** + * @ingroup los_bitmap + * @brief Find the highest one bit that is set. + * + * @par Description: + * This API is used to find the highest one bit that is set and return the bit index. + * @attention + *
            + *
          • None
          • + *
          + * @param bitmap [IN] The bitmap variable. + * + * @retval UINT16 The bit index of the highest one bit that is set. + * @par Dependency: + *
          • los_bitmap.h: the header file that contains the API declaration.
          + * @see LOS_LowBitGet + */ +UINT16 LOS_HighBitGet(UINT32 bitmap); + +/** + * @ingroup los_bitmap + * @brief Find the first zero bit starting from LSB. + * + * @par Description: + * This API is used to find the first zero bit starting from LSB and return the bit index. + * @attention + *
            + *
          • None
          • + *
          + * @param *bitmap [IN] The bitmap pointer. + * @param numBits [IN] The number of bits that is used to limit the bitmap range. + * + * @retval int The bit index of the first zero bit from LSB. + * @par Dependency: + *
          • los_bitmap.h: the header file that contains the API declaration.
          + * @see LOS_BitmapFfz + */ +int LOS_BitmapFfz(UINTPTR *bitmap, UINT32 numBits); + +/** + * @ingroup los_bitmap + * @brief Set the number of bit to 1 from start. + * + * @par Description: + * This API is used to set the number of bit to 1 from start. + * @attention + *
            + *
          • None
          • + *
          + * @param *bitmap [IN] The bitmap pointer. + * @param start [IN] The start bit. + * @param numsSet [IN] The number of set bits + * + * @retval none. + * @par Dependency: + *
          • los_bitmap.h: the header file that contains the API declaration.
          + * @see LOS_BitmapSetNBits + */ +VOID LOS_BitmapSetNBits(UINTPTR *bitmap, UINT32 start, UINT32 numsSet); + +/** + * @ingroup los_bitmap + * @brief Clear the number of bit to zero from start. + * + * @par Description: + * This API is used to set the number of bit to zero from start. + * @attention + *
            + *
          • None
          • + *
          + * @param *bitmap [IN] The bitmap pointer. + * @param start [IN] The start bit. + * @param numsClear [IN] The number of clear bits + * + * @retval none. + * @par Dependency: + *
          • los_bitmap.h: the header file that contains the API declaration.
          + * @see LOS_BitmapClrNBits + */ +VOID LOS_BitmapClrNBits(UINTPTR *bitmap, UINT32 start, UINT32 numsClear); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_BITMAP_H */ diff --git a/src/kernel_liteos_a/kernel/include/los_builddef.h b/src/kernel_liteos_a/kernel/include/los_builddef.h new file mode 100644 index 00000000..2a91bc84 --- /dev/null +++ b/src/kernel_liteos_a/kernel/include/los_builddef.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_BUILDEF_H +#define _LOS_BUILDEF_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define OS_LITTLE_ENDIAN 0x1234 /* Little endian */ +#define OS_BIG_ENDIAN 0x4321 /* Big endian */ + +#ifndef OS_BYTE_ORDER +#define OS_BYTE_ORDER OS_LITTLE_ENDIAN +#endif + +/* Define OS code data sections */ +/* The indicator function is inline */ +#ifndef LITE_OS_SEC_ALW_INLINE +#define LITE_OS_SEC_ALW_INLINE /* __attribute__((always_inline)) */ +#endif + +#ifndef LITE_OS_SEC_TEXT +#define LITE_OS_SEC_TEXT /* __attribute__((section(".text.sram"))) */ +#endif + +#ifndef LITE_OS_SEC_TEXT_MINOR +#define LITE_OS_SEC_TEXT_MINOR /* __attribute__((section(".text.ddr"))) */ +#endif + +#ifndef LITE_OS_SEC_TEXT_INIT +#define LITE_OS_SEC_TEXT_INIT /* __attribute__((section(".text.init"))) */ +#endif + +#ifndef LITE_OS_SEC_DATA +#define LITE_OS_SEC_DATA /* __attribute__((section(".data.sram"))) */ +#endif + +#ifndef LITE_OS_SEC_DATA_MINOR +#define LITE_OS_SEC_DATA_MINOR /* __attribute__((section(".data.ddr"))) */ +#endif + +#ifndef LITE_OS_SEC_DATA_INIT +#define LITE_OS_SEC_DATA_INIT /* __attribute__((section(".data.init"))) */ +#endif + +#ifndef LITE_OS_SEC_BSS +#define LITE_OS_SEC_BSS /* __attribute__((section(".bss.sram"))) */ +#endif + +#ifndef LITE_OS_SEC_BSS_MINOR +#define LITE_OS_SEC_BSS_MINOR /* __attribute__((section(".bss.ddr"))) */ +#endif + +#ifndef LITE_OS_SEC_BSS_INIT +#define LITE_OS_SEC_BSS_INIT /* __attribute__((section(".bss.init"))) */ +#endif + +#ifndef LITE_OS_SEC_ITCM +#define LITE_OS_SEC_ITCM /* __attribute__((section(".itcm "))) */ +#endif +#ifndef LITE_OS_SEC_DTCM +#define LITE_OS_SEC_DTCM /* __attribute__((section(".dtcm"))) */ +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_BUILDEF_H */ diff --git a/src/kernel_liteos_a/kernel/include/los_cppsupport.h b/src/kernel_liteos_a/kernel/include/los_cppsupport.h new file mode 100644 index 00000000..f905d449 --- /dev/null +++ b/src/kernel_liteos_a/kernel/include/los_cppsupport.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_cppsupport c++ + * @ingroup kernel + */ + +#ifndef _LOS_CPPSUPPORT_H +#define _LOS_CPPSUPPORT_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_cppsupport + * If scatter load is disabled, this flag should be passed as the third parameter when LOS_CppSystemInit() is called. + */ +#define NO_SCATTER 2 + +/** + * @ingroup los_cppsupport + * @brief System cppsupport initialization. + * + * @par Description: + * This API is used to initialize the cppsupport . + * @attention + *
            + *
          • initArrayStart is the start address of .init_array section, + * initArrayEnd is the end address of .init_array section.
          • + *
          • initArrayStart must be smaller than initArrayEnd, + * initArrayStart and initArrayEnd should be 4(32 bits platform) or 8(64 bits platform) bytes alignment.
          • + *
          + * + * @param initArrayStart [IN] Start address of init_array section. + * @param initArrayEnd [IN] End address of init_array section. + * @param flag [IN] Under what circumstances when LOS_CppSystemInit() is called, + * BEFORE_SCATTER, AFTER_SCATTER or NO_SCATTER. + * + * @retval 0 always return 0. + * @par Dependency: + *
          • los_cppsupport.h: the header file that contains the API declaration.
          + * @see None. + */ +extern INT32 LOS_CppSystemInit(UINTPTR initArrayStart, UINTPTR initArrayEnd, INT32 flag); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_CPPSUPPORT_H */ diff --git a/src/kernel_liteos_a/kernel/include/los_cpup.h b/src/kernel_liteos_a/kernel/include/los_cpup.h new file mode 100644 index 00000000..7873fb4f --- /dev/null +++ b/src/kernel_liteos_a/kernel/include/los_cpup.h @@ -0,0 +1,314 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_cpup CPU usage + * @ingroup kernel + */ + +#ifndef _LOS_CPUP_H +#define _LOS_CPUP_H + +#include "los_hwi.h" +#include "los_base.h" +#include "los_sys.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_cpup + * CPU usage error code: The request for memory fails. + * + * Value: 0x02001e00 + * + * Solution: Decrease the maximum number of processes. + */ +#define LOS_ERRNO_CPUP_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_CPUP, 0x00) + +/** + * @ingroup los_cpup + * CPU usage error code: The pointer to an input parameter is error. + * + * Value: 0x02001e01 + * + * Solution: Check whether input parameter is valid. + */ +#define LOS_ERRNO_CPUP_PTR_ERR LOS_ERRNO_OS_ERROR(LOS_MOD_CPUP, 0x01) + +/** + * @ingroup los_cpup + * CPU usage error code: The CPU usage is not initialized. + * + * Value: 0x02001e02 + * + * Solution: Check whether the CPU usage is initialized. + */ +#define LOS_ERRNO_CPUP_NO_INIT LOS_ERRNO_OS_ERROR(LOS_MOD_CPUP, 0x02) + +/** + * @ingroup los_cpup + * CPU usage error code: The target cpup is not created. + * + * Value: 0x02001e03 + * + * Solution: Check whether the target cpup is created. + */ +#define LOS_ERRNO_CPUP_NO_CREATED LOS_ERRNO_OS_ERROR(LOS_MOD_CPUP, 0x03) + +/** + * @ingroup los_cpup + * CPU usage error code: The target cpup ID is invalid. + * + * Value: 0x02001e04 + * + * Solution: Check whether the target cpup ID is applicable for the current operation. + */ +#define LOS_ERRNO_CPUP_ID_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_CPUP, 0x04) + +/** + * @ingroup los_cpup + * Sum of single core cpup with all processes and tasks. It means the value of cpup is a permillage. + */ +#define LOS_CPUP_SINGLE_CORE_PRECISION 10000 + +/** + * @ingroup los_cpup + * Multiple of current cpup precision change to percent. + */ +#define LOS_CPUP_PRECISION_MULT (LOS_CPUP_SINGLE_CORE_PRECISION / 100) + +/** + * @ingroup los_cpup + * Sum of all core cpup with all processes. It means the value of cpup is a permillage. + */ +#define LOS_CPUP_PRECISION (LOS_CPUP_SINGLE_CORE_PRECISION * LOSCFG_KERNEL_CORE_NUM) + +/** + * @ingroup los_cpup + * Count the CPU usage structures of all cpup. + */ +typedef struct tagCpupInfo { + UINT16 status; /**< Save the cur cpup status */ + UINT32 usage; /**< Usage. The value range is [0, LOS_CPUP_SINGLE_CORE_PRECISION]. */ +} CPUP_INFO_S; + +/** + * @ingroup los_cpup + * Query the CPU usage of the system. + */ +enum { + CPUP_LAST_TEN_SECONDS = 0, /**< Display CPU usage in the last ten seconds. */ + CPUP_LAST_ONE_SECONDS = 1, /**< Display CPU usage in the last one seconds. */ + CPUP_ALL_TIME = 0xffff /**< Display CPU usage from system startup to now. */ +}; + +/** + * @ingroup los_cpup + * @brief Obtain the historical CPU usage. + * + * @par Description: + * This API is used to obtain the historical CPU usage. + * @attention + *
            + *
          • This API can be called only after the CPU usage is initialized. Otherwise, the CPU usage fails to be + * obtained.
          • + *
          + * + * @param mode [IN] UINT16. process mode. The parameter value 0 indicates that the CPU usage within 10s will be + * obtained, and the parameter value 1 indicates that the CPU usage in the former 1s will + * be obtained. Other values indicate that the CPU usage in all time will be obtained. + * + * @retval #LOS_ERRNO_CPUP_NO_INIT The CPU usage is not initialized. + * @retval #UINT32 [0, LOS_CPUP_SINGLE_CORE_PRECISION], historical CPU usage, + * of which the precision is adjustable. + * @par Dependency: + *
          • los_cpup.h: the header file that contains the API declaration.
          + * @see + */ +extern UINT32 LOS_HistorySysCpuUsage(UINT16 mode); + +/** + * @ingroup los_cpup + * @brief Obtain the historical CPU usage of a specified process. + * + * @par Description: + * This API is used to obtain the historical CPU usage of a process specified by a passed-in process ID. + * @attention + *
            + *
          • This API can be called only after the CPU usage is initialized. Otherwise, + * the CPU usage fails to be obtained.
          • + *
          • The passed-in process ID must be valid and the process specified by the process ID must be created. Otherwise, + * the CPU usage fails to be obtained.
          • + *
          + * + * @param pid [IN] UINT32. process ID. + * @param mode [IN] UINT16. cpup mode. The parameter value 0 indicates that the CPU usage within 10s will be + * obtained, and the parameter value 1 indicates that the CPU usage in the former 1s will + * be obtained. Other values indicate that the CPU usage in the period that is less than + * 1s will be obtained. + * + * @retval #LOS_ERRNO_CPUP_NO_INIT The CPU usage is not initialized. + * @retval #LOS_ERRNO_CPUP_ID_INVALID The target process ID is invalid. + * @retval #LOS_ERRNO_CPUP_NO_CREATED The target process is not created. + * @retval #UINT32 [0, LOS_CPUP_PRECISION], CPU usage of the specified process. + * @par Dependency: + *
          • los_cpup.h: the header file that contains the API declaration.
          + * @see + */ +extern UINT32 LOS_HistoryProcessCpuUsage(UINT32 pid, UINT16 mode); + +/** + * @ingroup los_cpup + * @brief Obtain the historical CPU usage of a specified task. + * + * @par Description: + * This API is used to obtain the historical CPU usage of a task specified by a passed-in task ID. + * @attention + *
            + *
          • This API can be called only after the CPU usage is initialized. Otherwise, + * the CPU usage fails to be obtained.
          • + *
          • The passed-in task ID must be valid and the task specified by the task ID must be created. Otherwise, + * the CPU usage fails to be obtained.
          • + *
          + * + * @param tid [IN] UINT32. task ID. + * @param mode [IN] UINT16. cpup mode. The parameter value 0 indicates that the CPU usage within 10s will be + * obtained, and the parameter value 1 indicates that the CPU usage in the former 1s will + * be obtained. Other values indicate that the CPU usage in the period that is less than + * 1s will be obtained. + * + * @retval #LOS_ERRNO_CPUP_NO_INIT The CPU usage is not initialized. + * @retval #LOS_ERRNO_CPUP_ID_INVALID The target task ID is invalid. + * @retval #LOS_ERRNO_CPUP_NO_CREATED The target task is not created. + * @retval #UINT32 [0, LOS_CPUP_SINGLE_CORE_PRECISION], CPU usage of the specified process. + * @par Dependency: + *
          • los_cpup.h: the header file that contains the API declaration.
          + * @see + */ +extern UINT32 LOS_HistoryTaskCpuUsage(UINT32 tid, UINT16 mode); + +/** + * @ingroup los_cpup + * @brief Obtain the CPU usage of processes. + * + * @par Description: + * This API is used to obtain the CPU usage of processes. + * @attention + *
            + *
          • This API can be called only after the CPU usage is initialized. Otherwise, the CPU usage fails to be + * obtained.
          • + *
          • The input parameter pointer must not be NULL, Otherwise, the CPU usage fails to be obtained.
          • + *
          • The input parameter pointer should point to the structure array whose size be greater than + * (LOS_GetSystemProcessMaximum() * sizeof (CPUP_INFO_S)).
          • + *
          + * + * @param mode [IN] UINT16. Time mode. The parameter value 0 indicates that the CPU usage within 10s will be + * obtained, and the parameter value 1 indicates that the CPU usage in the former 1s + * will be obtained.Other values indicate that the CPU usage in all time will be + * obtained. + * @param cpupInfo [OUT]Type. CPUP_INFO_S* Pointer to the CPUP information structure to be obtained. + * @param len [IN] UINT32. The Maximum length of processes. + * + * @retval #LOS_ERRNO_CPUP_NO_INIT The CPU usage is not initialized. + * @retval #LOS_ERRNO_CPUP_PROCESS_PTR_ERR The input parameter pointer is NULL or + * len less than LOS_GetSystemProcessMaximum() * sizeof (CPUP_INFO_S). + * @retval #LOS_OK The CPU usage of all processes is successfully obtained. + * @par Dependency: + *
          • los_cpup.h: the header file that contains the API declaration.
          + * @see + */ +extern UINT32 LOS_GetAllProcessCpuUsage(UINT16 mode, CPUP_INFO_S *cpupInfo, UINT32 len); + +#ifdef LOSCFG_CPUP_INCLUDE_IRQ +/** + * @ingroup los_cpup + * @brief Obtain the CPU usage of hwi. + * + * @par Description: + * This API is used to obtain the CPU usage of hwi. + * @attention + *
            + *
          • This API can be called only after the CPU usage is initialized. Otherwise, the CPU usage fails to be + * obtained.
          • + *
          • The input parameter pointer must not be NULL, Otherwise, the CPU usage fails to be obtained.
          • + *
          • The input parameter pointer should point to the structure array whose size be greater than + * (LOS_GetSystemHwiMaximum() * sizeof (CPUP_INFO_S)).
          • + *
          + * + * @param mode [IN] UINT16. Time mode. The parameter value 0 indicates that the CPU usage within 10s will be + * obtained, and the parameter value 1 indicates that the CPU usage in the former 1s + * will be obtained.Other values indicate that the CPU usage in all time will be + * obtained. + * @param cpupInfo [OUT]Type. CPUP_INFO_S* Pointer to the CPUP information structure to be obtained. + * @param len [IN] UINT32. The Maximum length of hwis. + * + * @retval #LOS_ERRNO_CPUP_NO_INIT The CPU usage is not initialized. + * @retval #LOS_ERRNO_CPUP_PROCESS_PTR_ERR The input parameter pointer is NULL or + * len less than LOS_GetSystemHwiMaximum() * sizeof (CPUP_INFO_S). + * @retval #LOS_OK The CPU usage of all hwis is successfully obtained. + * @par Dependency: + *
          • los_cpup.h: the header file that contains the API declaration.
          + * @see + */ +extern UINT32 LOS_GetAllIrqCpuUsage(UINT16 mode, CPUP_INFO_S *cpupInfo, UINT32 len); +#endif + +/** + * @ingroup los_cpup + * @brief Reset the data of CPU usage. + * + * @par Description: + * This API is used to reset the data of CPU usage. + * @attention + *
            + *
          • None.
          • + *
          + * + * @param None. + * + * @retval #None. + * + * @par Dependency: + *
          • los_cpup.h: the header file that contains the API declaration.
          + * @see + */ +extern VOID LOS_CpupReset(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ +#endif diff --git a/src/kernel_liteos_a/kernel/include/los_err.h b/src/kernel_liteos_a/kernel/include/los_err.h new file mode 100644 index 00000000..f85e6ca4 --- /dev/null +++ b/src/kernel_liteos_a/kernel/include/los_err.h @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_err Error handling + * @ingroup kernel + */ + +#ifndef _LOS_ERR_H +#define _LOS_ERR_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_err + * @brief Define the pointer to the error handling function. + * + * @par Description: + * This API is used to define the pointer to the error handling function. + * @attention + *
            + *
          • None.
          • + *
          + * + * @param fileName [IN] Log file that stores error information. + * @param lineNo [IN] Line number of the erroneous line. + * @param errorNo [IN] Error code. + * @param paraLen [IN] Length of the input parameter pPara. + * @param para [IN] User label of the error. + * + * @retval None. + * @par Dependency: + *
          • los_err.h: the header file that contains the API declaration.
          + * @see None. + */ +typedef VOID (*LOS_ERRORHANDLE_FUNC)(CHAR *fileName, + UINT32 lineNo, + UINT32 errorNo, + UINT32 paraLen, + VOID *para); + +/** + * @ingroup los_err + * @brief Error handling function. + * + * @par Description: + * This API is used to perform different operations according to error types. + * @attention + *
            + *
          • None
          • + *
          + * + * @param fileName [IN] Log file that stores error information. + * @param lineNo [IN] Line number of the erroneous line which should not be OS_ERR_MAGIC_WORD. + * @param errorNo [IN] Error code. + * @param paraLen [IN] Length of the input parameter pPara. + * @param para [IN] User label of the error. + * + * @retval LOS_OK The error is successfully processed. + * @par Dependency: + *
          • los_err.h: the header file that contains the API declaration.
          + * @see None + */ +extern UINT32 LOS_ErrHandle(CHAR *fileName, UINT32 lineNo, + UINT32 errorNo, UINT32 paraLen, + VOID *para); + +/** + * @ingroup los_err + * @brief set Error handling function. + * + * @param fun [IN] the error handle function. + */ +extern VOID LOS_SetErrHandleHook(LOS_ERRORHANDLE_FUNC fun); + +enum LOS_MOUDLE_ID { + LOS_MOD_SYS = 0x0, + LOS_MOD_MEM = 0x1, + LOS_MOD_TSK = 0x2, + LOS_MOD_SWTMR = 0x3, + LOS_MOD_TICK = 0x4, + LOS_MOD_MSG = 0x5, + LOS_MOD_QUE = 0x6, + LOS_MOD_SEM = 0x7, + LOS_MOD_MBOX = 0x8, + LOS_MOD_HWI = 0x9, + LOS_MOD_HWWDG = 0xa, + LOS_MOD_CACHE = 0xb, + LOS_MOD_HWTMR = 0xc, + LOS_MOD_MMU = 0xd, + + LOS_MOD_LOG = 0xe, + LOS_MOD_ERR = 0xf, + + LOS_MOD_EXC = 0x10, + LOS_MOD_CSTK = 0x11, + + LOS_MOD_MPU = 0x12, + LOS_MOD_NMHWI = 0x13, + LOS_MOD_TRACE = 0x14, + LOS_MOD_KNLSTAT = 0x15, + LOS_MOD_EVTTIME = 0x16, + LOS_MOD_THRDCPUP = 0x17, + LOS_MOD_IPC = 0x18, + LOS_MOD_STKMON = 0x19, + LOS_MOD_TIMER = 0x1a, + LOS_MOD_RESLEAKMON = 0x1b, + LOS_MOD_EVENT = 0x1c, + LOS_MOD_MUX = 0X1d, + LOS_MOD_CPUP = 0x1e, + LOS_MOD_HOOK = 0x1f, + LOS_MOD_PERF = 0x20, + LOS_MOD_PM = 0x21, + LOS_MOD_SHELL = 0x31, + LOS_MOD_DRIVER = 0x41, + LOS_MOD_BUTT +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_ERR_H */ diff --git a/src/kernel_liteos_a/kernel/include/los_errno.h b/src/kernel_liteos_a/kernel/include/los_errno.h new file mode 100644 index 00000000..c001a330 --- /dev/null +++ b/src/kernel_liteos_a/kernel/include/los_errno.h @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_errno Error code + * @ingroup kernel + */ + +#ifndef _LOS_ERRNO_H +#define _LOS_ERRNO_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_errno + * OS error code flag. + */ +#define LOS_ERRNO_OS_ID (0x00U << 16) + +/** + * @ingroup los_errno + * Define the error level as informative. + */ +#define LOS_ERRTYPE_NORMAL (0x00U << 24) + +/** + * @ingroup los_errno + * Define the error level as warning. + */ +#define LOS_ERRTYPE_WARN (0x01U << 24) + +/** + * @ingroup los_errno + * Define the error level as critical. + */ +#define LOS_ERRTYPE_ERROR (0x02U << 24) + +/** + * @ingroup los_errno + * Define the error level as fatal. + */ +#define LOS_ERRTYPE_FATAL (0x03U << 24) + +/** + * @ingroup los_errno + * Define fatal OS errors. + */ +#define LOS_ERRNO_OS_FATAL(MID, ERRNO) \ + (LOS_ERRTYPE_FATAL | LOS_ERRNO_OS_ID | ((UINT32)(MID) << 8) | ((UINT32)(ERRNO))) + +/** + * @ingroup los_errno + * Define critical OS errors. + */ +#define LOS_ERRNO_OS_ERROR(MID, ERRNO) \ + (LOS_ERRTYPE_ERROR | LOS_ERRNO_OS_ID | ((UINT32)(MID) << 8) | ((UINT32)(ERRNO))) + +/** + * @ingroup los_errno + * Define warning OS errors. + */ +#define LOS_ERRNO_OS_WARN(MID, ERRNO) \ + (LOS_ERRTYPE_WARN | LOS_ERRNO_OS_ID | ((UINT32)(MID) << 8) | ((UINT32)(ERRNO))) + +/** + * @ingroup los_errno + * Define informative OS errors. + */ +#define LOS_ERRNO_OS_NORMAL(MID, ERRNO) \ + (LOS_ERRTYPE_NORMAL | LOS_ERRNO_OS_ID | ((UINT32)(MID) << 8) | ((UINT32)(ERRNO))) + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_ERRNO_H */ diff --git a/src/kernel_liteos_a/kernel/include/los_event.h b/src/kernel_liteos_a/kernel/include/los_event.h new file mode 100644 index 00000000..36411416 --- /dev/null +++ b/src/kernel_liteos_a/kernel/include/los_event.h @@ -0,0 +1,342 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_event Event + * @ingroup kernel + */ + +#ifndef _LOS_EVENT_H +#define _LOS_EVENT_H + +#include "los_base.h" +#include "los_list.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_event + * Event reading mode: The task waits for all its expected events to occur. + */ +#define LOS_WAITMODE_AND 4U + +/** + * @ingroup los_event + * Event reading mode: The task waits for any of its expected events to occur. + */ +#define LOS_WAITMODE_OR 2U + +/** + * @ingroup los_event + * Event reading mode: The event flag is immediately cleared after the event is read. + */ +#define LOS_WAITMODE_CLR 1U + +/** + * @ingroup los_event + * Bit 25 of the event mask cannot be set to an event because it is set to an error code. + * + * Value: 0x02001c00 + * + * Solution: Set bits excluding bit 25 of the event mask to events. + */ +#define LOS_ERRNO_EVENT_SETBIT_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x00) + +/** + * @ingroup los_event + * Event reading error code: Event reading times out. + * + * Value: 0x02001c01 + * + * Solution: Increase the waiting time for event reading, or make another task write a mask for the event. + */ +#define LOS_ERRNO_EVENT_READ_TIMEOUT LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x01) + +/** + * @ingroup los_event + * Event reading error code: The EVENTMASK input parameter value is valid. The input parameter value must not be 0. + * + * Value: 0x02001c02 + * + * Solution: Pass in a valid EVENTMASK value. + */ +#define LOS_ERRNO_EVENT_EVENTMASK_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x02) + +/** + * @ingroup los_event + * Event reading error code: The event is being read during an interrupt. + * + * Value: 0x02001c03 + * + * Solution: Read the event in a task. + */ +#define LOS_ERRNO_EVENT_READ_IN_INTERRUPT LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x03) + +/** + * @ingroup los_event + * Event reading error code: The flag input parameter value used in the event reading API is invalid. + * This input parameter value is obtained by performing an OR operation on corresponding bits of either OS_EVENT_ANY or + * OS_EVENT_ANY and corresponding bits of either OS_EVENT_WAIT or OS_EVENT_NOWAIT. The waiting time must be set to + * a nonzero value when an event is read in the mode of OS_EVENT_WAIT. + * + * Value: 0x02001c04 + * + * Solution: Pass in a valid flag value. + */ +#define LOS_ERRNO_EVENT_FLAGS_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x04) + +/** + * @ingroup los_event + * Event reading error code: The task is locked and is unable to read the event. + * + * Value: 0x02001c05 + * + * Solution: Unlock the task and read the event. + */ +#define LOS_ERRNO_EVENT_READ_IN_LOCK LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x05) + +/** + * @ingroup los_event + * Event reading error code: Null pointer. + * + * Value: 0x02001c06 + * + * Solution: Check whether the input parameter is null. + */ +#define LOS_ERRNO_EVENT_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x06) + +/** + * @ingroup los_event + * Event reading error code: The event is being read in system-level task. + * old usage: The event is being read in software timer task. (LOS_ERRNO_EVENT_READ_IN_SWTMR_TSK) + * Value: 0x02001c07 + * + * Solution: Read the event in a vailid task. + */ +#define LOS_ERRNO_EVENT_READ_IN_SYSTEM_TASK LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x07) + +/** + * @ingroup los_event + * Event reading error code: should not be destroy. + * + * Value: 0x02001c08 + * + * Solution: Check whether the event list is not empty. + */ +#define LOS_ERRNO_EVENT_SHOULD_NOT_DESTROY LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x08) + +/** + * @ingroup los_event + * Event control structure + */ +typedef struct tagEvent { + UINT32 uwEventID; /**< Event mask in the event control block, + indicating the event that has been logically processed. */ + LOS_DL_LIST stEventList; /**< Event control block linked list */ +} EVENT_CB_S, *PEVENT_CB_S; + +/** + * @ingroup los_event + * @brief Initialize an event control block. + * + * @par Description: + * This API is used to initialize the event control block pointed to by eventCB. + * @attention + *
            + *
          • None.
          • + *
          + * + * @param eventCB [IN/OUT] Pointer to the event control block to be initialized. + * + * @retval #LOS_ERRNO_EVENT_PTR_NULL Null pointer. + * @retval #LOS_OK The event control block is successfully initialized. + * @par Dependency: + *
          • los_event.h: the header file that contains the API declaration.
          + * @see LOS_EventClear + */ +extern UINT32 LOS_EventInit(PEVENT_CB_S eventCB); + +/** + * @ingroup los_event + * @brief Obtain an event specified by the event ID. + * + * @par Description: + * This API is used to check whether an event expected by the user occurs according to the event ID, event mask, + * and event reading mode, and process the event based on the event reading mode. The event ID must point to + * valid memory. + * @attention + *
            + *
          • When the mode is LOS_WAITMODE_CLR, the eventID is passed-out.
          • + *
          • Otherwise the eventID is passed-in.
          • + *
          • An error code and an event return value can be same. To differentiate the error code and return value, bit 25 of + * the event mask is forbidden to be used.
          • + *
          + * + * @param eventID [IN/OUT] Pointer to the ID of the event to be checked. + * @param eventMask [IN] Mask of the event expected to occur by the user, indicating the event obtained after + * it is logically processed that matches the ID pointed to by eventID. + * @param mode [IN] Event reading mode. The modes include LOS_WAITMODE_AND, LOS_WAITMODE_OR, LOS_WAITMODE_CLR. + * + * @retval #LOS_ERRNO_EVENT_SETBIT_INVALID Bit 25 of the event mask cannot be set because it is set to an + * error number. + * @retval #LOS_ERRNO_EVENT_EVENTMASK_INVALID The passed-in event mask is incorrect. + * @retval #LOS_ERRNO_EVENT_FLAGS_INVALID The passed-in event mode is invalid. + * @retval #LOS_ERRNO_EVENT_PTR_NULL The passed-in pointer is null. + * @retval 0 The event expected by the user does not occur. + * @retval #UINT32 The event expected by the user occurs. + * @par Dependency: + *
          • los_event.h: the header file that contains the API declaration.
          + * @see LOS_EventRead | LOS_EventWrite + */ +extern UINT32 LOS_EventPoll(UINT32 *eventID, UINT32 eventMask, UINT32 mode); + +/** + * @ingroup los_event + * @brief Read an event. + * + * @par Description: + * This API is used to block or schedule a task that reads an event of which the event control block, event mask, + * reading mode, and timeout information are specified. + *
        + * @attention + *
          + *
        • An error code and an event return value can be same. To differentiate the error code and return value, bit 25 of + * the event mask is forbidden to be used.
        • + *
        + * + * @param eventCB [IN/OUT] Pointer to the event control block to be checked. This parameter must point + * to valid memory. + * @param eventMask [IN] Mask of the event expected to occur by the user, indicating the event obtained after + * it is logically processed that matches the ID pointed to by eventID. + * @param mode [IN] Event reading mode. + * @param timeout [IN] Timeout interval of event reading (unit: Tick). + * + * @retval #LOS_ERRNO_EVENT_SETBIT_INVALID Bit 25 of the event mask cannot be set because it is set to an + * error number. + * @retval #LOS_ERRNO_EVENT_EVENTMASK_INVALID The passed-in event reading mode is incorrect. + * @retval #LOS_ERRNO_EVENT_READ_IN_INTERRUPT The event is being read during an interrupt. + * @retval #LOS_ERRNO_EVENT_FLAGS_INVALID The event mode is invalid. + * @retval #LOS_ERRNO_EVENT_READ_IN_LOCK The event reading task is locked. + * @retval #LOS_ERRNO_EVENT_PTR_NULL The passed-in pointer is null. + * @retval 0 The event expected by the user does not occur. + * @retval #UINT32 The event expected by the user occurs. + * @par Dependency: + *
        • los_event.h: the header file that contains the API declaration.
        + * @see LOS_EventPoll | LOS_EventWrite + */ +extern UINT32 LOS_EventRead(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeout); + +/** + * @ingroup los_event + * @brief Write an event. + * + * @par Description: + * This API is used to write an event specified by the passed-in event mask into an event control block + * pointed to by eventCB. + * @attention + *
          + *
        • To determine whether the LOS_EventRead API returns an event or an error code, bit 25 of the event mask + * is forbidden to be used.
        • + *
        + * + * @param eventCB [IN/OUT] Pointer to the event control block into which an event is to be written. + * This parameter must point to valid memory. + * @param events [IN] Event mask to be written. + * + * @retval #LOS_ERRNO_EVENT_SETBIT_INVALID Bit 25 of the event mask cannot be set to an event + * because it is set to an error code. + * @retval #LOS_ERRNO_EVENT_PTR_NULL Null pointer. + * @retval #LOS_OK The event is successfully written. + * @par Dependency: + *
        • los_event.h: the header file that contains the API declaration.
        + * @see LOS_EventPoll | LOS_EventRead + */ +extern UINT32 LOS_EventWrite(PEVENT_CB_S eventCB, UINT32 events); + +/** + * @ingroup los_event + * @brief Clear the event of the eventCB by a specified eventMask. + * + * @par Description: + *
          + *
        • This API is used to set the ID of an event that has a specified mask and of which the information is stored in + * an event control block pointed to by eventCB to 0. eventCB must point to valid memory.
        • + *
        + * @attention + *
          + *
        • The value of events needs to be reversed when it is passed-in.
        • + *
        + * + * @param eventCB [IN/OUT] Pointer to the event control block to be cleared. + * @param eventMask [IN] Mask of the event to be cleared. + * + * @retval #LOS_ERRNO_EVENT_PTR_NULL Null pointer. + * @retval #LOS_OK The event is successfully cleared. + * @par Dependency: + *
        • los_event.h: the header file that contains the API declaration.
        + * @see LOS_EventPoll | LOS_EventRead | LOS_EventWrite + */ +extern UINT32 LOS_EventClear(PEVENT_CB_S eventCB, UINT32 eventMask); + +/** + * @ingroup los_event + * @brief Destroy an event. + * + * @par Description: + *
          + *
        • This API is used to Destroy an event.
        • + *
        + * @attention + *
          + *
        • The specific event should be a valid one.
        • + *
        + * + * @param eventCB [IN/OUT] Pointer to the event control block to be destroyed. + * + * @retval #LOS_ERRNO_EVENT_PTR_NULL Null pointer. + * @retval #LOS_OK The event is successfully cleared. + * @par Dependency: + *
        • los_event.h: the header file that contains the API declaration.
        + * @see LOS_EventPoll | LOS_EventRead | LOS_EventWrite + */ +extern UINT32 LOS_EventDestroy(PEVENT_CB_S eventCB); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_EVENT_H */ diff --git a/src/kernel_liteos_a/kernel/include/los_hash.h b/src/kernel_liteos_a/kernel/include/los_hash.h new file mode 100644 index 00000000..7cbf257b --- /dev/null +++ b/src/kernel_liteos_a/kernel/include/los_hash.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_HASH_H +#define _LOS_HASH_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define FNV1_32A_INIT ((UINT32)0x811c9dc5) + +/* + * 32 bit magic FNV-1 prime + */ +#define FNV_32_PRIME ((UINT32)0x01000193) + +LITE_OS_SEC_ALW_INLINE STATIC INLINE UINT32 LOS_HashFNV32aBuf(const VOID *buf, size_t len, UINT32 hval) +{ + const UINT8 *hashbuf = (const UINT8 *)buf; + + /* + * FNV-1a hash each octet in the buffer + */ + while (len-- != 0) { + /* xor the bottom with the current octet */ + hval ^= (UINT32)*hashbuf++; + + /* multiply by the 32 bit FNV magic prime mod 2^32 */ + hval *= FNV_32_PRIME; + } + + /* return our new hash value */ + return hval; +} + +LITE_OS_SEC_ALW_INLINE STATIC INLINE UINT32 LOS_HashFNV32aStr(CHAR *str, UINT32 hval) +{ + UINT8 *s = (UINT8 *)str; + + /* + * FNV-1a hash each octet in the buffer + */ + while (*s) { + /* xor the bottom with the current octet */ + hval ^= (UINT32)*s++; + + /* multiply by the 32 bit FNV magic prime mod 2^32 */ + hval *= FNV_32_PRIME; + } + + /* return our new hash value */ + return hval; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_HASH_H */ diff --git a/src/kernel_liteos_a/kernel/include/los_hook.h b/src/kernel_liteos_a/kernel/include/los_hook.h new file mode 100644 index 00000000..7df33ca8 --- /dev/null +++ b/src/kernel_liteos_a/kernel/include/los_hook.h @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_HOOK_H +#define _LOS_HOOK_H + +#include "los_config.h" +#include "los_err.h" +#include "los_errno.h" + +#ifdef LOSCFG_KERNEL_HOOK +#include "los_hook_types.h" +#endif + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#ifdef LOSCFG_KERNEL_HOOK +/** + * @ingroup los_hook + * Hook error code: The hook pool is insufficient. + * + * Value: 0x02001f00 + * + * Solution: Deregister the registered hook. + */ +#define LOS_ERRNO_HOOK_POOL_IS_FULL LOS_ERRNO_OS_ERROR(LOS_MOD_HOOK, 0x00) + +/** + * @ingroup los_hook + * Hook error code: Invalid parameter. + * + * Value: 0x02001f01 + * + * Solution: Check the input parameters of LOS_HookReg. + */ +#define LOS_ERRNO_HOOK_REG_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HOOK, 0x01) + +/** + * @ingroup los_hook + * Hook error code: Invalid parameter. + * + * Value: 0x02001f02 + * + * Solution: Check the input parameters of LOS_HookUnReg. + */ +#define LOS_ERRNO_HOOK_UNREG_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HOOK, 0x02) + +/** + * @ingroup los_hook + * @brief Registration of hook function. + * + * @par Description: + * This API is used to register hook function. + * + * @attention + *
          + *
        • None.
        • + *
        + * + * @param hookType [IN] Register the type of the hook. + * @param hookFn [IN] The function to be registered. + * + * @retval None. + * @par Dependency: + *
        • los_hook.h: the header file that contains the API declaration.
        + * @see + */ +#define LOS_HookReg(hookType, hookFn) hookType##_RegHook(hookFn) + +/** + * @ingroup los_hook + * @brief Deregistration of hook function. + * + * @par Description: + * This API is used to deregister hook function. + * + * @attention + *
          + *
        • None.
        • + *
        + * + * @param hookType [IN] Deregister the type of the hook. + * @param hookFn [IN] The function to be deregistered. + * + * @retval None. + * @par Dependency: + *
        • los_hook.h: the header file that contains the API declaration.
        + * @see + */ +#define LOS_HookUnReg(hookType, hookFn) hookType##_UnRegHook(hookFn) + +/** + * Call hook functions. + */ +#define OsHookCall(hookType, ...) hookType##_CallHook(__VA_ARGS__) + +#else +#define LOS_HookReg(hookType, hookFn) +#define LOS_HookUnReg(hookType, hookFn) +#define OsHookCall(hookType, ...) +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_HOOK_H */ diff --git a/src/kernel_liteos_a/kernel/include/los_init.h b/src/kernel_liteos_a/kernel/include/los_init.h new file mode 100644 index 00000000..632207cd --- /dev/null +++ b/src/kernel_liteos_a/kernel/include/los_init.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_INIT_H +#define _LOS_INIT_H + +#include "los_init_info.h" + +/** + * Kernel Module Init Level + */ +#define LOS_INIT_LEVEL_EARLIEST 0 +#define LOS_INIT_LEVEL_ARCH_EARLY 1 +#define LOS_INIT_LEVEL_PLATFORM_EARLY 2 +#define LOS_INIT_LEVEL_KMOD_PREVM 3 +#define LOS_INIT_LEVEL_VM_COMPLETE 4 +#define LOS_INIT_LEVEL_ARCH 5 +#define LOS_INIT_LEVEL_PLATFORM 6 +#define LOS_INIT_LEVEL_KMOD_BASIC 7 +#define LOS_INIT_LEVEL_KMOD_EXTENDED 8 +#define LOS_INIT_LEVEL_KMOD_TASK 9 +#define LOS_INIT_LEVEL_FINISH 10 + +/** + * @ingroup los_init + * @brief Register a startup module to the startup process. + * + * @par Description: + * This API is used to register a startup module to the startup process. + * + * @attention + *
          + *
        • Register a new module in the boot process of the kernel as part of the kernel capability component.
        • + *
        • In the startup framework, within the same _level, the startup sequence is sorted by + * the registered function name
        • + *
        • If the registration is not accompanied by the startup process after calling this interface, + * try to add -u_hook to liteos_tables_ldflags.mk
        • + *
        + * + * @param _hook [IN] Type #UINT32 (*)(VOID) Register function. + * @param _level [IN] Type #UINT32 Init level in the kernel. + * + * @retval None + * @par Dependency: + *
        • los_init.h: the header file that contains the API declaration.
        + * @see + */ +#define LOS_MODULE_INIT(_hook, _level) OS_INIT_HOOK_REG(kernel, _hook, _level) + +#endif /* _LOS_INIT_H */ diff --git a/src/kernel_liteos_a/kernel/include/los_ld_elflib.h b/src/kernel_liteos_a/kernel/include/los_ld_elflib.h new file mode 100644 index 00000000..b85f7934 --- /dev/null +++ b/src/kernel_liteos_a/kernel/include/los_ld_elflib.h @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup dynload Dynamic loading + * @ingroup kernel + */ + +#ifndef _LOS_LD_ELFLIB_H +#define _LOS_LD_ELFLIB_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup dynload + * @brief Set the memory pool address used by dynload + * + * @par Description: + * This API is used to set the memory pool address used by dynload. + * @attention + *
          + *
        • The parameter passed to this API should be a legal memory pool address by managed with LiteOS's memory + * algorithm, and whose value is outside of the LiteOS system memory
        • + *
        + * + * @param memPool [IN] the memory pool address. + * + * @retval TRUE Set successful. + * @retval FLASE Set failed. + * @par Dependency: + *
        • los_ld_elflib.h: the header file that contains the API declaration.
        + * @see LOS_ModuleUnload + */ +extern BOOL LOS_DynMemPoolSet(VOID *memPool); + +/** + * @ingroup dynload + * @brief Load a shared object file. + * + * @par Description: + * This API is used to load a shared object file under a particular module file path. + * @attention + *
          + *
        • The parameter passed to this API should be a legal path of a shared object file.
        • + *
        + * + * @param elfFileName [IN] Shared object file path. + * + * @retval NULL The shared object file fails to be loaded. + * @retval VOID* The shared object file is successfully loaded. + * @par Dependency: + *
        • los_ld_elflib.h: the header file that contains the API declaration.
        + * @see LOS_ModuleUnload + */ +extern VOID *LOS_SoLoad(CHAR *elfFileName); + +/** + * @ingroup dynload + * @brief Load an object file. + * + * @par Description: + * This API is used to load an object file under a particular module file path. + * @attention + *
          + *
        • The parameter passed to this API should be a legal path of an object file.
        • + *
        + * + * @param elfFileName [IN] Object file path. + * + * @retval NULL The object file fails to be loaded. + * @retval VOID* The object file is successfully loaded. + * @par Dependency: + *
        • los_ld_elflib.h: the header file that contains the API declaration.
        + * @see LOS_ModuleUnload + */ +extern VOID *LOS_ObjLoad(CHAR *elfFileName); + +/** + * @ingroup dynload + * @brief Unload a module. + * + * @par Description: + * This API is used to unload a module with a particular module handle. + * @attention + *
          + *
        • None.
        • + *
        + * + * @param handle [IN] Module handle. + * + * @retval #LOS_NOK The module fails to be unloaded. + * @retval #LOS_OK The module is successfully unloaded. + * @par Dependency: + *
        • los_ld_elflib.h: the header file that contains the API declaration.
        + * @see LOS_ObjLoad + */ +extern INT32 LOS_ModuleUnload(VOID *handle); + +/** + * @ingroup dynload + * @brief Destroy a dynamic loader. + * + * @par Description: + * This API is used to destroy a dynamic linker. + * @attention + *
          + *
        • When dynamic loading is no longer needed, call this API to destroy the dynamic linker.
        • + *
        + * + * @param None. + * + * @retval None. + * @par Dependency: + *
        • los_ld_elflib.h: the header file that contains the API declaration.
        + * @see LOS_FindSymByName + */ +extern VOID LOS_LdDestroy(VOID); + +/** + * @ingroup dynload + * @brief Search for a symbol address. + * + * @par Description: + * This API is used to search for the address of a symbol according to a particular module handle and symbol name. + * @attention + *
          + *
        • If the value of handle is NULL, Huawei LiteOS searches for symbols (including system symbols) in the global + * symbol table. If handle is set to a valid module handle, Huawei LiteOS searches for symbols in the module that + * comes with the module handle.
        • + *
        + * + * @param handle [IN] Module handle. + * @param name [IN] Name of the symbol to be searched for. + * + * @retval NULL The symbol address is not found. + * @retval VOID* Symbol address. + * @par Dependency: + *
        • los_ld_elflib.h: the header file that contains the API declaration.
        + * @see LOS_LdDestroy + */ +extern VOID *LOS_FindSymByName(VOID *handle, CHAR *name); + +/** + * @ingroup dynload + * @brief Add a default path. + * + * @par Description: + * This API is used to add a path to default paths. + * @attention + *
          + *
        • + *
        + * + * @param path [IN] Path to be added to default paths. + * + * @retval #LOS_NOK The path is added unsuccessfully. + * @retval #LOS_OK The path is added successfully. + * @par Dependency: + *
        • los_ld_elflib.h: the header file that contains the API declaration.
        + * @see LOS_FindSymByName | LOS_LdDestroy + */ +extern INT32 LOS_PathAdd(CHAR *path); + +/** + * @ingroup dynload + * Define an enum type indicates load strategy. + * + * Type of load strategy of dynamic load, ZIP means using zipped shared object, NOZIP means using normal shared object. + */ +enum LOAD_STRATEGY { + ZIP, + NOZIP +}; + +/** + * @ingroup dynload + * Define the structure of the parameters used for dynamic. + * + * Information of specified parameters passed in during dynamic load. + */ +typedef struct tagDynloadParam { + enum LOAD_STRATEGY enLoadStrategy; +} DYNLOAD_PARAM_S; + +/** + * @ingroup dynload + * @brief Register the dynamic parameters. + * + * @par Description: + * This API is used to register the dynamic load parameters. + * @attention + *
          + *
        • + *
        + * + * @param dynloadParam [IN] dynamic load parameters to be registered. + * + * @par Dependency: + *
        • los_ld_elflib.h: the header file that contains the API declaration.
        + * @see LOS_FindSymByName | LOS_LdDestroy + */ +extern VOID LOS_DynParamReg(DYNLOAD_PARAM_S *dynloadParam); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_LD_ELFLIB_H */ diff --git a/src/kernel_liteos_a/kernel/include/los_list.h b/src/kernel_liteos_a/kernel/include/los_list.h new file mode 100644 index 00000000..899cc348 --- /dev/null +++ b/src/kernel_liteos_a/kernel/include/los_list.h @@ -0,0 +1,609 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_list Doubly linked list + * @ingroup kernel + */ + +#ifndef _LOS_LIST_H +#define _LOS_LIST_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_list + * Structure of a node in a doubly linked list. + */ +typedef struct LOS_DL_LIST { + struct LOS_DL_LIST *pstPrev; /**< Current node's pointer to the previous node */ + struct LOS_DL_LIST *pstNext; /**< Current node's pointer to the next node */ +} LOS_DL_LIST; + +/** + * @ingroup los_list + * + * @par Description: + * This API is used to initialize a doubly linked list. + * @attention + *
          + *
        • The parameter passed in should be ensured to be a legal pointer.
        • + *
        + * + * @param list [IN] Node in a doubly linked list. + * + * @retval None. + * @par Dependency: + *
        • los_list.h: the header file that contains the API declaration.
        + * @see + */ +LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListInit(LOS_DL_LIST *list) +{ + list->pstNext = list; + list->pstPrev = list; +} + +/** + * @ingroup los_list + * @brief Point to the next node pointed to by the current node. + * + * @par Description: + *
          + *
        • This API is used to point to the next node pointed to by the current node.
        • + *
        + * @attention + *
          + *
        • None.
        • + *
        + * + * @param object [IN] Node in the doubly linked list. + * + * @retval None. + * @par Dependency: + *
        • los_list.h: the header file that contains the API declaration.
        + * @see + */ +#define LOS_DL_LIST_FIRST(object) ((object)->pstNext) + +/** + * @ingroup los_list + * @brief Node is the end of the list. + * + * @par Description: + *
          + *
        • This API is used to test node is the end of the list.
        • + *
        + * @attention + *
          + *
        • None.
        • + *
        + * + * @param list [IN] Doubly linked list. + * @param node [IN] The node to be tested if the end of the list. + * + * @retval None. + * @par Dependency: + *
        • los_list.h: the header file that contains the API declaration.
        + * @see + */ +#define LOS_DL_LIST_IS_END(list, node) ((list) == (node) ? TRUE : FALSE) + +/** + * @ingroup los_list + * @brief Node is on the list. + * + * @par Description: + *
          + *
        • This API is used to test node is on the list.
        • + *
        + * @attention + *
          + *
        • None.
        • + *
        + * + * @param object [IN] Node in the doubly linked list. + * + * @retval None. + * @par Dependency: + *
        • los_list.h: the header file that contains the API declaration.
        + * @see + */ +#define LOS_DL_LIST_IS_ON_QUEUE(node) ((node)->pstPrev != NULL && (node)->pstNext != NULL) + +/** + * @ingroup los_list + * @brief Point to the previous node pointed to by the current node. + * + * @par Description: + *
          + *
        • This API is used to point to the previous node pointed to by the current node.
        • + *
        + * @attention + *
          + *
        • None.
        • + *
        + * + * @param object [IN] Node in the doubly linked list. + * + * @retval None. + * @par Dependency: + *
        • los_list.h: the header file that contains the API declaration.
        + * @see + */ +#define LOS_DL_LIST_LAST(object) ((object)->pstPrev) + +/** + * @ingroup los_list + * @brief Insert a new node to a doubly linked list. + * + * @par Description: + * This API is used to insert a new node to a doubly linked list. + * @attention + *
          + *
        • The parameters passed in should be ensured to be legal pointers.
        • + *
        + * + * @param list [IN] Doubly linked list where the new node is inserted. + * @param node [IN] New node to be inserted. + * + * @retval None + * @par Dependency: + *
        • los_list.h: the header file that contains the API declaration.
        + * @see LOS_ListDelete + */ +LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListAdd(LOS_DL_LIST *list, LOS_DL_LIST *node) +{ + node->pstNext = list->pstNext; + node->pstPrev = list; + list->pstNext->pstPrev = node; + list->pstNext = node; +} + +/** + * @ingroup los_list + * @brief Insert a node to the tail of a doubly linked list. + * + * @par Description: + * This API is used to insert a new node to the tail of a doubly linked list. + * @attention + *
          + *
        • The parameters passed in should be ensured to be legal pointers.
        • + *
        + * + * @param list [IN] Doubly linked list where the new node is inserted. + * @param node [IN] New node to be inserted. + * + * @retval None. + * @par Dependency: + *
        • los_list.h: the header file that contains the API declaration.
        + * @see LOS_ListAdd | LOS_ListHeadInsert + */ +LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListTailInsert(LOS_DL_LIST *list, LOS_DL_LIST *node) +{ + LOS_ListAdd(list->pstPrev, node); +} + +/** + * @ingroup los_list + * @brief Insert a node to the head of a doubly linked list. + * + * @par Description: + * This API is used to insert a new node to the head of a doubly linked list. + * @attention + *
          + *
        • The parameters passed in should be ensured to be legal pointers.
        • + *
        + * + * @param list [IN] Doubly linked list where the new node is inserted. + * @param node [IN] New node to be inserted. + * + * @retval None. + * @par Dependency: + *
        • los_list.h: the header file that contains the API declaration.
        + * @see LOS_ListAdd | LOS_ListTailInsert + */ +LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListHeadInsert(LOS_DL_LIST *list, LOS_DL_LIST *node) +{ + LOS_ListAdd(list, node); +} + +/** + * @ingroup los_list + * + * @par Description: + *
          + *
        • This API is used to delete a specified node from a doubly linked list.
        • + *
        + * @attention + *
          + *
        • The parameter passed in should be ensured to be a legal pointer.
        • + *
        + * + * @param node [IN] Node to be deleted. + * + * @retval None. + * @par Dependency: + *
        • los_list.h: the header file that contains the API declaration.
        + * @see LOS_ListAdd + */ +LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListDelete(LOS_DL_LIST *node) +{ + node->pstNext->pstPrev = node->pstPrev; + node->pstPrev->pstNext = node->pstNext; + node->pstNext = NULL; + node->pstPrev = NULL; +} + +/** + * @ingroup los_list + * @brief Identify whether a specified doubly linked list is empty. + * + * @par Description: + *
          + *
        • This API is used to return whether a doubly linked list is empty.
        • + *
        + * @attention + *
          + *
        • The parameter passed in should be ensured to be a legal pointer.
        • + *
        + * + * @param list [IN] Doubly linked list. + * + * @retval TRUE The doubly linked list is empty. + * @retval FALSE The doubly linked list is not empty. + * @par Dependency: + *
        • los_list.h: the header file that contains the API declaration.
        + * @see + */ +LITE_OS_SEC_ALW_INLINE STATIC INLINE BOOL LOS_ListEmpty(LOS_DL_LIST *list) +{ + return (BOOL)(list->pstNext == list); +} + +/** + * @ingroup los_list + * @brief Insert a new list to a doubly linked list. + * + * @par Description: + * This API is used to insert a new list to a doubly linked list. + * @attention + *
          + *
        • The parameters passed in should be ensured to be legal pointers.
        • + *
        + * + * @param oldList [IN] Doubly linked list where the new list is inserted. + * @param newList [IN] New list to be inserted. + * + * @retval None + * @par Dependency: + *
        • los_list.h: the header file that contains the API declaration.
        + * @see LOS_ListDelete + */ +LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListAddList(LOS_DL_LIST *oldList, LOS_DL_LIST *newList) +{ + LOS_DL_LIST *oldListHead = oldList->pstNext; + LOS_DL_LIST *oldListTail = oldList; + LOS_DL_LIST *newListHead = newList; + LOS_DL_LIST *newListTail = newList->pstPrev; + + oldListTail->pstNext = newListHead; + newListHead->pstPrev = oldListTail; + oldListHead->pstPrev = newListTail; + newListTail->pstNext = oldListHead; +} + +/** + * @ingroup los_list + * @brief Insert a doubly list to the tail of a doubly linked list. + * + * @par Description: + * This API is used to insert a new doubly list to the tail of a doubly linked list. + * @attention + *
          + *
        • The parameters passed in should be ensured to be legal pointers.
        • + *
        + * + * @param oldList [IN] Doubly linked list where the new list is inserted. + * @param newList [IN] New list to be inserted. + * + * @retval None. + * @par Dependency: + *
        • los_list.h: the header file that contains the API declaration.
        + * @see LOS_ListAddList | LOS_ListHeadInsertList + */ +LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListTailInsertList(LOS_DL_LIST *oldList, LOS_DL_LIST *newList) +{ + LOS_ListAddList(oldList->pstPrev, newList); +} + +/** + * @ingroup los_list + * @brief Insert a doubly list to the head of a doubly linked list. + * + * @par Description: + * This API is used to insert a new doubly list to the head of a doubly linked list. + * @attention + *
          + *
        • The parameters passed in should be ensured to be legal pointers.
        • + *
        + * + * @param oldList [IN] Doubly linked list where the new list is inserted. + * @param newList [IN] New list to be inserted. + * + * @retval None. + * @par Dependency: + *
        • los_list.h: the header file that contains the API declaration.
        + * @see LOS_ListAddList | LOS_ListTailInsertList + */ +LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListHeadInsertList(LOS_DL_LIST *oldList, LOS_DL_LIST *newList) +{ + LOS_ListAddList(oldList, newList); +} + +/** + * @ingroup los_list + * @brief Obtain the offset of a field to a structure address. + * + * @par Description: + * This API is used to obtain the offset of a field to a structure address. + * @attention + *
          + *
        • None.
        • + *
        + * + * @param type [IN] Structure name. + * @param member [IN] Name of the member of which the offset is to be measured. + * + * @retval Offset of the field to the structure address. + * @par Dependency: + *
        • los_list.h: the header file that contains the API declaration.
        + * @see + */ +#define LOS_OFF_SET_OF(type, member) ((UINTPTR)&((type *)0)->member) + +/** + * @ingroup los_list + * @brief Obtain the pointer to a structure that contains a doubly linked list. + * + * @par Description: + * This API is used to obtain the pointer to a structure that contains a doubly linked list. + *
          + *
        • None.
        • + *
        + * @attention + *
          + *
        • None.
        • + *
        + * + * @param item [IN] Current node's pointer to the next node. + * @param type [IN] Structure name. + * @param member [IN] Member name of the doubly linked list in the structure. + * + * @retval Pointer to the structure that contains the doubly linked list. + * @par Dependency: + *
        • los_list.h: the header file that contains the API declaration.
        + * @see + */ +#define LOS_DL_LIST_ENTRY(item, type, member) \ + ((type *)(VOID *)((CHAR *)(item) - LOS_OFF_SET_OF(type, member))) + +/** + * @ingroup los_list + * @brief Iterate over a doubly linked list of given type. + * + * @par Description: + * This API is used to iterate over a doubly linked list of given type. + * @attention + *
          + *
        • None.
        • + *
        + * + * @param item [IN] Pointer to the structure that contains the doubly linked list that is to be traversed. + * @param list [IN] Pointer to the doubly linked list to be traversed. + * @param type [IN] Structure name. + * @param member [IN] Member name of the doubly linked list in the structure. + * + * @retval None. + * @par Dependency: + *
        • los_list.h: the header file that contains the API declaration.
        + * @see + */ +#define LOS_DL_LIST_FOR_EACH_ENTRY(item, list, type, member) \ + for (item = LOS_DL_LIST_ENTRY((list)->pstNext, type, member); \ + &(item)->member != (list); \ + item = LOS_DL_LIST_ENTRY((item)->member.pstNext, type, member)) + +/** + * @ingroup los_list + * @brief iterate over a doubly linked list safe against removal of list entry. + * + * @par Description: + * This API is used to iterate over a doubly linked list safe against removal of list entry. + * @attention + *
          + *
        • None.
        • + *
        + * + * @param item [IN] Pointer to the structure that contains the doubly linked list that is to be traversed. + * @param next [IN] Save the next node. + * @param list [IN] Pointer to the doubly linked list to be traversed. + * @param type [IN] Structure name. + * @param member [IN] Member name of the doubly linked list in the structure. + * + * @retval None. + * @par Dependency: + *
        • los_list.h: the header file that contains the API declaration.
        + * @see + */ +#define LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, next, list, type, member) \ + for (item = LOS_DL_LIST_ENTRY((list)->pstNext, type, member), \ + next = LOS_DL_LIST_ENTRY((item)->member.pstNext, type, member); \ + &(item)->member != (list); \ + item = next, next = LOS_DL_LIST_ENTRY((item)->member.pstNext, type, member)) + +/** + * @ingroup los_list + * @brief Delete initialize a doubly linked list. + * + * @par Description: + * This API is used to delete initialize a doubly linked list. + * @attention + *
          + *
        • The parameter passed in should be ensured to be s legal pointer.
        • + *
        + * + * @param list [IN] Doubly linked list. + * + * @retval None. + * @par Dependency: + *
        • los_list.h: the header file that contains the API declaration.
        + * @see + */ +LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListDelInit(LOS_DL_LIST *list) +{ + list->pstNext->pstPrev = list->pstPrev; + list->pstPrev->pstNext = list->pstNext; + LOS_ListInit(list); +} + +/** + * @ingroup los_list + * @brief iterate over a doubly linked list. + * + * @par Description: + * This API is used to iterate over a doubly linked list. + * @attention + *
          + *
        • None.
        • + *
        + * + * @param item [IN] Pointer to the structure that contains the doubly linked list that is to be traversed. + * @param list [IN] Pointer to the doubly linked list to be traversed. + * + * @retval None. + * @par Dependency: + *
        • los_list.h: the header file that contains the API declaration.
        + * @see + */ +#define LOS_DL_LIST_FOR_EACH(item, list) \ + for (item = (list)->pstNext; \ + (item) != (list); \ + item = (item)->pstNext) + +/** + * @ingroup los_list + * @brief Iterate over a doubly linked list safe against removal of list entry. + * + * @par Description: + * This API is used to iterate over a doubly linked list safe against removal of list entry. + * @attention + *
          + *
        • None.
        • + *
        + * + * @param item [IN] Pointer to the structure that contains the doubly linked list that is to be traversed. + * @param next [IN] Save the next node. + * @param list [IN] Pointer to the doubly linked list to be traversed. + * + * @retval None. + * @par Dependency: + *
        • los_list.h: the header file that contains the API declaration.
        + * @see + */ +#define LOS_DL_LIST_FOR_EACH_SAFE(item, next, list) \ + for (item = (list)->pstNext, next = (item)->pstNext; \ + (item) != (list); \ + item = next, next = (item)->pstNext) + +/** + * @ingroup los_list + * @brief Initialize a double linked list. + * + * @par Description: + * This API is used to initialize a double linked list. + * @attention + *
          + *
        • None.
        • + *
        + * + * @param list [IN] Pointer to the doubly linked list to be traversed. + * + * @retval None. + * @par Dependency: + *
        • los_list.h: the header file that contains the API declaration.
        + * @see + */ +#define LOS_DL_LIST_HEAD(list) LOS_DL_LIST list = { &(list), &(list) } + +#define LOS_ListPeekHeadType(list, type, element) ({ \ + type *__t; \ + if ((list)->pstNext == list) { \ + __t = NULL; \ + } else { \ + __t = LOS_DL_LIST_ENTRY((list)->pstNext, type, element); \ + } \ + __t; \ +}) + +#define LOS_ListRemoveHeadType(list, type, element) ({ \ + type *__t; \ + if ((list)->pstNext == list) { \ + __t = NULL; \ + } else { \ + __t = LOS_DL_LIST_ENTRY((list)->pstNext, type, element); \ + LOS_ListDelete((list)->pstNext); \ + } \ + __t; \ +}) + +#define LOS_ListNextType(list, item, type, element) ({ \ + type *__t; \ + if ((item)->pstNext == list) { \ + __t = NULL; \ + } else { \ + __t = LOS_DL_LIST_ENTRY((item)->pstNext, type, element); \ + } \ + __t; \ +}) + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_LIST_H */ diff --git a/src/kernel_liteos_a/kernel/include/los_lms.h b/src/kernel_liteos_a/kernel/include/los_lms.h new file mode 100644 index 00000000..b4775dac --- /dev/null +++ b/src/kernel_liteos_a/kernel/include/los_lms.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_LMS_H +#define _LOS_LMS_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#ifdef LOSCFG_KERNEL_LMS + +UINT32 LOS_LmsCheckPoolAdd(const VOID *pool, UINT32 size); +VOID LOS_LmsCheckPoolDel(const VOID *pool); +VOID LOS_LmsAddrProtect(UINTPTR addrStart, UINTPTR addrEnd); +VOID LOS_LmsAddrDisableProtect(UINTPTR addrStart, UINTPTR addrEnd); + +#endif /* LOSCFG_KERNEL_LMS */ + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_LMS_H */ \ No newline at end of file diff --git a/src/kernel_liteos_a/kernel/include/los_lockdep.h b/src/kernel_liteos_a/kernel/include/los_lockdep.h new file mode 100644 index 00000000..860da0c5 --- /dev/null +++ b/src/kernel_liteos_a/kernel/include/los_lockdep.h @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_LOCKDEP_H +#define _LOS_LOCKDEP_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef struct Spinlock SPIN_LOCK_S; + +#define MAX_LOCK_DEPTH 16U + +enum LockDepErrType { + LOCKDEP_SUCCESS = 0, + LOCKDEP_ERR_DOUBLE_LOCK, + LOCKDEP_ERR_DEAD_LOCK, + LOCKDEP_ERR_UNLOCK_WITOUT_LOCK, + /* overflow, needs expand */ + LOCKDEP_ERR_OVERFLOW, +}; + +typedef struct { + VOID *lockPtr; + VOID *lockAddr; + UINT64 waitTime; + UINT64 holdTime; +} HeldLocks; + +typedef struct { + VOID *waitLock; + INT32 lockDepth; + HeldLocks heldLocks[MAX_LOCK_DEPTH]; +} LockDep; + +/** + * @ingroup los_lockdep + * + * @par Description: + * This API is used to check dead lock in spinlock. + * @attention + *
          + *
        • The parameter passed in should be ensured to be a legal pointer.
        • + *
        + * + * @param lock [IN] point to a SPIN_LOCK_S. + * + * @retval None. + * @par Dependency: + *
        • los_lockdep.h: the header file that contains the API declaration.
        + * @see + */ +extern VOID OsLockDepCheckIn(SPIN_LOCK_S *lock); + +/** + * @ingroup los_lockdep + * + * @par Description: + * This API is used to trace when a spinlock locked. + * @attention + *
          + *
        • The parameter passed in should be ensured to be a legal pointer.
        • + *
        + * + * @param lock [IN] point to a SPIN_LOCK_S. + * + * @retval None. + * @par Dependency: + *
        • los_lockdep.h: the header file that contains the API declaration.
        + * @see + */ +extern VOID OsLockDepRecord(SPIN_LOCK_S *lock); + +/** + * @ingroup los_lockdep + * + * @par Description: + * This API is used to trace when a spinlock unlocked. + * @attention + *
          + *
        • The parameter passed in should be ensured to be a legal pointer.
        • + *
        + * + * @param lock [IN] point to a SPIN_LOCK_S. + * + * @retval None. + * @par Dependency: + *
        • los_lockdep.h: the header file that contains the API declaration.
        + * @see + */ +extern VOID OsLockDepCheckOut(SPIN_LOCK_S *lock); + +/** + * @ingroup los_lockdep + * + * @par Description: + * This API is used to clear lockdep record of current task. + * @attention + *
          + *
        • None.
        • + *
        + * + * @param None + * @retval None. + * @par Dependency: + *
        • los_lockdep.h: the header file that contains the API declaration.
        + * @see + */ +extern VOID OsLockdepClearSpinlocks(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ +#endif /* _LOS_LOCKDEP_H */ diff --git a/src/kernel_liteos_a/kernel/include/los_membox.h b/src/kernel_liteos_a/kernel/include/los_membox.h new file mode 100644 index 00000000..94c7c4d6 --- /dev/null +++ b/src/kernel_liteos_a/kernel/include/los_membox.h @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_membox Static memory + * @ingroup kernel + */ + +#ifndef _LOS_MEMBOX_H +#define _LOS_MEMBOX_H + +#include "los_config.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define OS_MEMBOX_NEXT(addr, blkSize) (LOS_MEMBOX_NODE *)(VOID *)((UINT8 *)(addr) + (blkSize)) + +#define OS_MEMBOX_NODE_HEAD_SIZE sizeof(LOS_MEMBOX_NODE) + +/** + * @ingroup los_membox + * Structure of a free node in a memory pool + */ +typedef struct tagMEMBOX_NODE { + struct tagMEMBOX_NODE *pstNext; /**< Free node's pointer to the next node in a memory pool */ +} LOS_MEMBOX_NODE; + +/** + * @ingroup los_membox + * Memory pool information structure + */ +typedef struct { + UINT32 uwBlkSize; /**< Block size */ + UINT32 uwBlkNum; /**< Block number */ + UINT32 uwBlkCnt; /**< The number of allocated blocks */ + LOS_MEMBOX_NODE stFreeList; /**< Free list */ +} LOS_MEMBOX_INFO; + +typedef LOS_MEMBOX_INFO OS_MEMBOX_S; + +/** + * @ingroup los_membox + * Memory pool alignment + */ +#define LOS_MEMBOX_ALIGNED(memAddr) (((UINTPTR)(memAddr) + sizeof(UINTPTR) - 1) & (~(sizeof(UINTPTR) - 1))) + +/** + * @ingroup los_membox + * Memory pool size + */ +#define LOS_MEMBOX_SIZE(blkSize, blkNum) \ + (sizeof(LOS_MEMBOX_INFO) + (LOS_MEMBOX_ALIGNED((blkSize) + OS_MEMBOX_NODE_HEAD_SIZE) * (blkNum))) + +/** + * @ingroup los_membox + * @brief Initialize a memory pool. + * + * @par Description: + *
          + *
        • This API is used to initialize a memory pool.
        • + *
        + * @attention + *
          + *
        • The poolSize parameter value should match the following two conditions : + * 1) Be less than or equal to the Memory pool size; + * 2) Be greater than the size of LOS_MEMBOX_INFO.
        • + *
        + * + * @param pool [IN] Memory pool address. + * @param poolSize [IN] Memory pool size. + * @param blkSize [IN] Memory block size. + * + * @retval #LOS_NOK The memory pool fails to be initialized. + * @retval #LOS_OK The memory pool is successfully initialized. + * @par Dependency: + *
          + *
        • los_membox.h: the header file that contains the API declaration.
        • + *
        + * @see None. + */ +extern UINT32 LOS_MemboxInit(VOID *pool, UINT32 poolSize, UINT32 blkSize); + +/** + * @ingroup los_membox + * @brief Request a memory block. + * + * @par Description: + *
          + *
        • This API is used to request a memory block.
        • + *
        + * @attention + *
          + *
        • The input pool parameter must be initialized via func LOS_MemboxInit.
        • + *
        + * + * @param pool [IN] Memory pool address. + * + * @retval #VOID* The request is accepted, and return a memory block address. + * @retval #NULL The request fails. + * @par Dependency: + *
          + *
        • los_membox.h: the header file that contains the API declaration.
        • + *
        + * @see LOS_MemboxFree + */ +extern VOID *LOS_MemboxAlloc(VOID *pool); + +/** + * @ingroup los_membox + * @brief Free a memory block. + * + * @par Description: + *
          + *
        • This API is used to free a memory block.
        • + *
        + * @attention + *
          + *
        • The input pool parameter must be initialized via func LOS_MemboxInit.
        • + *
        • The input box parameter must be allocated by LOS_MemboxAlloc.
        • + *
        + * + * @param pool [IN] Memory pool address. + * @param box [IN] Memory block address. + * + * @retval #LOS_NOK This memory block fails to be freed. + * @retval #LOS_OK This memory block is successfully freed. + * @par Dependency: + *
          + *
        • los_membox.h: the header file that contains the API declaration.
        • + *
        + * @see LOS_MemboxAlloc + */ +extern UINT32 LOS_MemboxFree(VOID *pool, VOID *box); + +/** + * @ingroup los_membox + * @brief Clear a memory block. + * + * @par Description: + *
          + *
        • This API is used to set the memory block value to be 0.
        • + *
        + * @attention + *
          + *
        • The input pool parameter must be initialized via func LOS_MemboxInit.
        • + *
        • The input box parameter must be allocated by LOS_MemboxAlloc.
        • + *
        + * + * @param pool [IN] Memory pool address. + * @param box [IN] Memory block address. + * + * @retval VOID + * @par Dependency: + *
          + *
        • los_membox.h: the header file that contains the API declaration.
        • + *
        + * @see None. + */ +extern VOID LOS_MemboxClr(VOID *pool, VOID *box); + +/** + * @ingroup los_membox + * @brief show membox info. + * + * @par Description: + *
          + *
        • This API is used to show the memory pool info.
        • + *
        + * @attention + *
          + *
        • The input pool parameter must be initialized via func LOS_MemboxInit.
        • + *
        + * + * @param pool [IN] Memory pool address. + * + * @retval VOID + * @par Dependency: + *
          + *
        • los_membox.h: the header file that contains the API declaration.
        • + *
        + * @see None. + */ +extern VOID LOS_ShowBox(VOID *pool); + +/** + * @ingroup los_membox + * @brief calculate membox information. + * + * @par Description: + *
          + *
        • This API is used to calculate membox information.
        • + *
        + * @attention + *
          + *
        • One parameter of this interface is a pointer, it should be a correct value, otherwise, the system may + * be abnormal.
        • + *
        + * + * @param boxMem [IN] Type #VOID* Pointer to the calculate membox. + * @param maxBlk [OUT] Type #UINT32* Record membox max block. + * @param blkCnt [OUT] Type #UINT32* Record membox block count already allocated. + * @param blkSize [OUT] Type #UINT32* Record membox block size. + * + * @retval #LOS_OK The heap status calculate success. + * @retval #LOS_NOK The membox status calculate with some error. + * @par Dependency: + *
        • los_memory.h: the header file that contains the API declaration.
        + * @see LOS_MemAlloc | LOS_MemRealloc | LOS_MemFree + */ +extern UINT32 LOS_MemboxStatisticsGet(const VOID *boxMem, UINT32 *maxBlk, UINT32 *blkCnt, UINT32 *blkSize); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_MEMBOX_H */ diff --git a/src/kernel_liteos_a/kernel/include/los_memory.h b/src/kernel_liteos_a/kernel/include/los_memory.h new file mode 100644 index 00000000..935d00f9 --- /dev/null +++ b/src/kernel_liteos_a/kernel/include/los_memory.h @@ -0,0 +1,433 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_memory Dynamic memory + * @ingroup kernel + */ + +#ifndef _LOS_MEMORY_H +#define _LOS_MEMORY_H + +#include "los_config.h" +#include "los_base.h" +#include "los_toolchain.h" +#include "los_membox.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#ifdef LOSCFG_MEM_LEAKCHECK + +/** + * @ingroup los_memory + * The omit layers of function call from call kernel memory interfaces + * such as LOS_MemAlloc/LOS_MemAllocAlign/LOS_MemRealloc/LOS_MemFree. + */ +#define LOS_OMIT_LR_CNT 2 + +/** + * @ingroup los_memory + * The recorded layers of function call. + */ +#define LOS_RECORD_LR_CNT 3 +#endif + +/** + * @ingroup los_memory + * The start address of exc interaction dynamic memory pool address, when the exc + * interaction feature not support, m_aucSysMem0 equals to m_aucSysMem1. + */ +extern UINT8 *m_aucSysMem0; + +/** + * @ingroup los_memory + * The start address of system dynamic memory pool address. + */ +extern UINT8 *m_aucSysMem1; + +#ifdef LOSCFG_MEM_MUL_POOL +/** + * @ingroup los_memory + * @brief Deinitialize dynamic memory. + * + * @par Description: + *
          + *
        • This API is used to deinitialize the dynamic memory of a doubly linked list.
        • + *
        + * + * @param pool [IN] Starting address of memory. + * + * @retval #OS_ERROR The dynamic memory fails to be deinitialized. + * @retval #LOS_OK The dynamic memory is successfully deinitialized. + * @par Dependency: + *
          + *
        • los_memory.h: the header file that contains the API declaration.
        • + *
        + * @see None. + */ +extern UINT32 LOS_MemDeInit(VOID *pool); + +/** + * @ingroup los_memory + * @brief Print information about all pools. + * + * @par Description: + *
          + *
        • This API is used to print information about all pools.
        • + *
        + * + * @retval #UINT32 The pool number. + * @par Dependency: + *
          + *
        • los_memory.h: the header file that contains the API declaration.
        • + *
        + * @see None. + */ +extern UINT32 LOS_MemPoolList(VOID); +#endif + +/** + * @ingroup los_memory + * Memory pool extern information structure + */ +typedef struct { + UINT32 totalUsedSize; + UINT32 totalFreeSize; + UINT32 maxFreeNodeSize; + UINT32 usedNodeNum; + UINT32 freeNodeNum; +#ifdef LOSCFG_MEM_WATERLINE + UINT32 usageWaterLine; +#endif +} LOS_MEM_POOL_STATUS; + +/** + * @ingroup los_memory + * @brief Initialize dynamic memory. + * + * @par Description: + *
          + *
        • This API is used to initialize the dynamic memory of a doubly linked list.
        • + *
        + * @attention + *
          + *
        • The size parameter value should match the following two conditions : + * 1) Be less than or equal to the Memory pool size; + * 2) Be greater than the size of OS_MEM_MIN_POOL_SIZE.
        • + *
        • Call this API when dynamic memory needs to be initialized during the startup of Huawei LiteOS.
        • + *
        • The parameter input must be four byte-aligned.
        • + *
        • The init area [pool, pool + size] should not conflict with other pools.
        • + *
        + * + * @param pool [IN] Starting address of memory. + * @param size [IN] Memory size. + * + * @retval #OS_ERROR The dynamic memory fails to be initialized. + * @retval #LOS_OK The dynamic memory is successfully initialized. + * @par Dependency: + *
          + *
        • los_memory.h: the header file that contains the API declaration.
        • + *
        + * @see None. + */ +extern UINT32 LOS_MemInit(VOID *pool, UINT32 size); + +/** + * @ingroup los_memory + * @brief Enable memory pool to support dynamic expansion. + * + * @par Description: + *
          + *
        • This API is used to enable the dynamic memory to expand size dynamically.
        • + *
        + * @attention + *
          + *
        • The memory pool is default diabled dynamic expansion. + *
        + * + * @param pool [IN] Starting address of memory. + * + * @retval node. + * @par Dependency: + *
          + *
        • los_memory.h: the header file that contains the API declaration.
        • + *
        + * @see None. + */ +extern VOID LOS_MemExpandEnable(VOID *pool); + +/** + * @ingroup los_memory + * @brief Allocate dynamic memory. + * + * @par Description: + *
          + *
        • This API is used to allocate a memory block of which the size is specified.
        • + *
        + * @attention + *
          + *
        • The input pool parameter must be initialized via func LOS_MemInit.
        • + *
        • The size of the input parameter size can not be greater than the memory pool size that specified at the second + * input parameter of LOS_MemInit.
        • + *
        • The size of the input parameter size must be four byte-aligned.
        • + *
        + * + * @param pool [IN] Pointer to the memory pool that contains the memory block to be allocated. + * @param size [IN] Size of the memory block to be allocated (unit: byte). + * + * @retval #NULL The memory fails to be allocated. + * @retval #VOID* The memory is successfully allocated with the starting address of the allocated memory block + * returned. + * @par Dependency: + *
        • los_memory.h: the header file that contains the API declaration.
        + * @see LOS_MemRealloc | LOS_MemAllocAlign | LOS_MemFree + */ +extern VOID *LOS_MemAlloc(VOID *pool, UINT32 size); + +/** + * @ingroup los_memory + * @brief Free dynamic memory. + * + * @par Description: + *
      • This API is used to free specified dynamic memory that has been allocated.
      • + * @attention + *
          + *
        • The input pool parameter must be initialized via func LOS_MemInit.
        • + *
        • The input ptr parameter must be allocated by LOS_MemAlloc or LOS_MemAllocAlign or LOS_MemRealloc.
        • + *
        + * + * @param pool [IN] Pointer to the memory pool that contains the dynamic memory block to be freed. + * @param ptr [IN] Starting address of the memory block to be freed. + * + * @retval #LOS_NOK The memory block fails to be freed because the starting address of the memory block is + * invalid, or the memory overwriting occurs. + * @retval #LOS_OK The memory block is successfully freed. + * @par Dependency: + *
        • los_memory.h: the header file that contains the API declaration.
        + * @see LOS_MemAlloc | LOS_MemRealloc | LOS_MemAllocAlign + */ +extern UINT32 LOS_MemFree(VOID *pool, VOID *ptr); + +/** + * @ingroup los_memory + * @brief Re-allocate a memory block. + * + * @par Description: + *
          + *
        • This API is used to allocate a new memory block of which the size is specified by size if the original memory + * block size is insufficient. The new memory block will copy the data in the original memory block of which the + * address is specified by ptr. The size of the new memory block determines the maximum size of data to be copied. + * After the new memory block is created, the original one is freed.
        • + *
        + * @attention + *
          + *
        • The input pool parameter must be initialized via func LOS_MemInit.
        • + *
        • The input ptr parameter must be allocated by LOS_MemAlloc or LOS_MemAllocAlign.
        • + *
        • The size of the input parameter size can not be greater than the memory pool size that specified at the second + * input parameter of LOS_MemInit.
        • + *
        • The size of the input parameter size must be aligned as follows: 1) if the ptr is allocated by LOS_MemAlloc, + * it must be four byte-aligned; 2) if the ptr is allocated by LOS_MemAllocAlign, it must be aligned with the size of + * the input parameter boundary of LOS_MemAllocAlign.
        • + *
        + * + * @param pool [IN] Pointer to the memory pool that contains the original and new memory blocks. + * @param ptr [IN] Address of the original memory block. + * @param size [IN] Size of the new memory block. + * + * @retval #NULL The memory fails to be re-allocated. + * @retval #VOID* The memory is successfully re-allocated with the starting address of the new memory block returned. + * @par Dependency: + *
        • los_memory.h: the header file that contains the API declaration.
        + * @see LOS_MemAlloc | LOS_MemAllocAlign | LOS_MemFree + */ +extern VOID *LOS_MemRealloc(VOID *pool, VOID *ptr, UINT32 size); + +/** + * @ingroup los_memory + * @brief Allocate aligned memory. + * + * @par Description: + *
          + *
        • This API is used to allocate memory blocks of specified size and of which the starting addresses are aligned on + * a specified boundary.
        • + *
        + * @attention + *
          + *
        • The input pool parameter must be initialized via func LOS_MemInit.
        • + *
        • The size of the input parameter size can not be greater than the memory pool size that specified at the second + * input parameter of LOS_MemInit.
        • + *
        • The alignment parameter value must be a power of 2 with the minimum value being 4.
        • + *
        + * + * @param pool [IN] Pointer to the memory pool that contains the memory blocks to be allocated. + * @param size [IN] Size of the memory to be allocated. + * @param boundary [IN] Boundary on which the memory is aligned. + * + * @retval #NULL The memory fails to be allocated. + * @retval #VOID* The memory is successfully allocated with the starting address of the allocated memory returned. + * @par Dependency: + *
        • los_memory.h: the header file that contains the API declaration.
        + * @see LOS_MemAlloc | LOS_MemRealloc | LOS_MemFree + */ +extern VOID *LOS_MemAllocAlign(VOID *pool, UINT32 size, UINT32 boundary); + +/** + * @ingroup los_memory + * @brief Get the size of memory pool's size. + * + * @par Description: + *
          + *
        • This API is used to get the size of memory pool' total size.
        • + *
        + * @attention + *
          + *
        • The input pool parameter must be initialized via func LOS_MemInit.
        • + *
        + * + * @param pool [IN] A pointer pointed to the memory pool. + * + * @retval #LOS_NOK The incoming parameter pool is NULL. + * @retval #UINT32 The size of the memory pool. + * @par Dependency: + *
        • los_memory.h: the header file that contains the API declaration.
        + * @see None. + */ +extern UINT32 LOS_MemPoolSizeGet(const VOID *pool); + +/** + * @ingroup los_memory + * @brief Get the size of memory totally used. + * + * @par Description: + *
          + *
        • This API is used to get the size of memory totally used in memory pool.
        • + *
        + * @attention + *
          + *
        • The input pool parameter must be initialized via func LOS_MemInit.
        • + *
        + * + * @param pool [IN] A pointer pointed to the memory pool. + * + * @retval #LOS_NOK The incoming parameter pool is NULL. + * @retval #UINT32 The size of the memory pool used. + * @par Dependency: + *
        • los_memory.h: the header file that contains the API declaration.
        + * @see None. + */ +extern UINT32 LOS_MemTotalUsedGet(VOID *pool); + +/** + * @ingroup los_memory + * @brief Get the information of memory pool. + * + * @par Description: + *
          + *
        • This API is used to get the information of memory pool.
        • + *
        + * @attention + *
          + *
        • The input pool parameter must be initialized via func LOS_MemInit.
        • + *
        + * + * @param pool [IN] A pointer pointed to the memory pool. + * @param poolStatus [IN] A pointer for storage the pool status + * + * @retval #LOS_NOK The incoming parameter pool is NULL or invalid. + * @retval #LOS_OK Success to get memory information. + * @par Dependency: + *
        • los_memory.h: the header file that contains the API declaration.
        + * @see None. + */ +extern UINT32 LOS_MemInfoGet(VOID *pool, LOS_MEM_POOL_STATUS *poolStatus); + +/** + * @ingroup los_memory + * @brief Get the number of free node in every size. + * + * @par Description: + *
          + *
        • This API is used to get the number of free node in every size.
        • + *
        + * @attention + *
          + *
        • The input pool parameter must be initialized via func LOS_MemInit.
        • + *
        + * + * @param pool [IN] A pointer pointed to the memory pool. + * + * @retval #LOS_NOK The incoming parameter pool is NULL. + * @retval #UINT32 The address of the last used node that casts to UINT32. + * @par Dependency: + *
        • los_memory.h: the header file that contains the API declaration.
        + * @see None. + */ +extern UINT32 LOS_MemFreeNodeShow(VOID *pool); + +/** + * @ingroup los_memory + * @brief Check the memory pool integrity. + * + * @par Description: + *
          + *
        • This API is used to check the memory pool integrity.
        • + *
        + * @attention + *
          + *
        • The input pool parameter must be initialized via func LOS_MemInit.
        • + *
        • LOS_MemIntegrityCheck will be called by malloc function when the macro of LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK + * is defined in LiteOS.
        • + *
        • LOS_MemIntegrityCheck function can be called by user anytime.
        • + *
        + * + * @param pool [IN] A pointer pointed to the memory pool. + * + * @retval #LOS_NOK The memory pool (pool) is impaired. + * @retval #LOS_OK The memory pool (pool) is integrated. + * @par Dependency: + *
        • los_memory.h: the header file that contains the API declaration.
        + * @see None. + */ +extern UINT32 LOS_MemIntegrityCheck(const VOID *pool); + +extern void *boot_alloc_mem(size_t len); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_MEMORY_H */ diff --git a/src/kernel_liteos_a/kernel/include/los_mp.h b/src/kernel_liteos_a/kernel/include/los_mp.h new file mode 100644 index 00000000..67bbd39c --- /dev/null +++ b/src/kernel_liteos_a/kernel/include/los_mp.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_MP_H +#define _LOS_MP_H + +#include "los_config.h" +#include "los_list.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define OS_MP_CPU_ALL LOSCFG_KERNEL_CPU_MASK + +#define OS_MP_GC_PERIOD 100 /* ticks */ + +typedef enum { + LOS_MP_IPI_WAKEUP, + LOS_MP_IPI_SCHEDULE, + LOS_MP_IPI_HALT, +#ifdef LOSCFG_KERNEL_SMP_CALL + LOS_MP_IPI_FUNC_CALL, +#endif +} MP_IPI_TYPE; + +typedef VOID (*SMP_FUNC_CALL)(VOID *args); + +#ifdef LOSCFG_KERNEL_SMP +extern VOID LOS_MpSchedule(UINT32 target); +extern VOID OsMpWakeHandler(VOID); +extern VOID OsMpScheduleHandler(VOID); +extern VOID OsMpHaltHandler(VOID); +extern UINT32 OsMpInit(VOID); +#else +STATIC INLINE VOID LOS_MpSchedule(UINT32 target) +{ + (VOID)target; +} +#endif + +#ifdef LOSCFG_KERNEL_SMP_CALL +typedef struct { + LOS_DL_LIST node; + SMP_FUNC_CALL func; + VOID *args; +} MpCallFunc; + +/** + * It is used to call function on target cpus by sending ipi, and the first param is target cpu mask value. + */ +extern VOID OsMpFuncCall(UINT32 target, SMP_FUNC_CALL func, VOID *args); +extern VOID OsMpFuncCallHandler(VOID); +#else +INLINE VOID OsMpFuncCall(UINT32 target, SMP_FUNC_CALL func, VOID *args) +{ + (VOID)target; + if (func != NULL) { + func(args); + } +} +#endif /* LOSCFG_KERNEL_SMP_CALL */ + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_MP_H_ */ diff --git a/src/kernel_liteos_a/kernel/include/los_mux.h b/src/kernel_liteos_a/kernel/include/los_mux.h new file mode 100644 index 00000000..37c7efca --- /dev/null +++ b/src/kernel_liteos_a/kernel/include/los_mux.h @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_mux Mutex + * @ingroup kernel + */ + +#ifndef _LOS_MUX_H +#define _LOS_MUX_H + +#include "los_base.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +enum { + LOS_MUX_PRIO_NONE = 0, + LOS_MUX_PRIO_INHERIT = 1, + LOS_MUX_PRIO_PROTECT = 2 +}; + +enum { + LOS_MUX_NORMAL = 0, + LOS_MUX_RECURSIVE = 1, + LOS_MUX_ERRORCHECK = 2, + LOS_MUX_DEFAULT = LOS_MUX_RECURSIVE +}; + +typedef struct { + UINT8 protocol; + UINT8 prioceiling; + UINT8 type; + UINT8 reserved; +} LosMuxAttr; + +/** + * @ingroup los_mux + * Mutex object. + */ +typedef struct OsMux { + UINT32 magic; /**< magic number */ + LosMuxAttr attr; /**< Mutex attribute */ + LOS_DL_LIST holdList; /**< The task holding the lock change */ + LOS_DL_LIST muxList; /**< Mutex linked list */ + VOID *owner; /**< The current thread that is locking a mutex */ + UINT16 muxCount; /**< Times of locking a mutex */ +} LosMux; + +extern UINT32 LOS_MuxAttrInit(LosMuxAttr *attr); +extern UINT32 LOS_MuxAttrDestroy(LosMuxAttr *attr); +extern UINT32 LOS_MuxAttrGetType(const LosMuxAttr *attr, INT32 *outType); +extern UINT32 LOS_MuxAttrSetType(LosMuxAttr *attr, INT32 type); +extern UINT32 LOS_MuxAttrGetProtocol(const LosMuxAttr *attr, INT32 *protocol); +extern UINT32 LOS_MuxAttrSetProtocol(LosMuxAttr *attr, INT32 protocol); +extern UINT32 LOS_MuxAttrGetPrioceiling(const LosMuxAttr *attr, INT32 *prioceiling); +extern UINT32 LOS_MuxAttrSetPrioceiling(LosMuxAttr *attr, INT32 prioceiling); +extern UINT32 LOS_MuxSetPrioceiling(LosMux *mutex, INT32 prioceiling, INT32 *oldPrioceiling); +extern UINT32 LOS_MuxGetPrioceiling(const LosMux *mutex, INT32 *prioceiling); +extern BOOL LOS_MuxIsValid(const LosMux *mutex); + +/** + * @ingroup los_mux + * @brief Init a mutex. + * + * @par Description: + * This API is used to Init a mutex. A mutex handle is assigned to muxHandle when the mutex is init successfully. + * Return LOS_OK on creating successful, return specific error code otherwise. + * @attention + *
          + *
        • The total number of mutexes is pre-configured. If there are no available mutexes, the mutex creation fails.
        • + *
        + * + * @param mutex [IN] Handle pointer of the successfully init mutex. + * @param attr [IN] The mutex attribute. + * + * @retval #LOS_EINVAL The mutex pointer is NULL. + * @retval #LOS_OK The mutex is successfully created. + * @par Dependency: + *
        • los_mux.h: the header file that contains the API declaration.
        + * @see LOS_MuxDestroy + */ +extern UINT32 LOS_MuxInit(LosMux *mutex, const LosMuxAttr *attr); + +/** + * @ingroup los_mux + * @brief Destroy a mutex. + * + * @par Description: + * This API is used to delete a specified mutex. Return LOS_OK on deleting successfully, return specific error code + * otherwise. + * @attention + *
          + *
        • The specific mutex should be created firstly.
        • + *
        • The mutex can be deleted successfully only if no other tasks pend on it.
        • + *
        + * + * @param mutex [IN] Handle of the mutex to be deleted. + * + * @retval #LOS_EINVAL The mutex pointer is NULL. + * @retval #LOS_EBUSY Tasks pended on this mutex. + * @retval #LOS_EBADF The lock has been destroyed or broken. + * @retval #LOS_OK The mutex is successfully deleted. + * @par Dependency: + *
        • los_mux.h: the header file that contains the API declaration.
        + * @see LOS_MuxInit + */ +extern UINT32 LOS_MuxDestroy(LosMux *mutex); + +/** + * @ingroup los_mux + * @brief Wait to lock a mutex. + * + * @par Description: + * This API is used to wait for a specified period of time to lock a mutex. + * @attention + *
          + *
        • The specific mutex should be created firstly.
        • + *
        • The function fails if the mutex that is waited on is already locked by another thread when the task scheduling + * is disabled.
        • + *
        • Do not wait on a mutex during an interrupt.
        • + *
        • The priority inheritance protocol is supported. If a higher-priority thread is waiting on a mutex, it changes + * the priority of the thread that owns the mutex to avoid priority inversion.
        • + *
        • A recursive mutex can be locked more than once by the same thread.
        • + *
        • Do not call this API in software timer callback.
        • + *
        + * + * @param mutex [IN] Handle of the mutex to be waited on. + * @param timeout [IN] Waiting time. The value range is [0, LOS_WAIT_FOREVER](unit: Tick). + * + * @retval #LOS_EINVAL The mutex pointer is NULL, The timeout is zero or Lock status error. + * @retval #LOS_EINTR The mutex is being locked during an interrupt. + * @retval #LOS_EBUSY Tasks pended on this mutex. + * @retval #LOS_EBADF The lock has been destroyed or broken. + * @retval #LOS_EDEADLK Mutex error check failed or System locked task scheduling. + * @retval #LOS_ETIMEDOUT The mutex waiting times out. + * @retval #LOS_OK The mutex is successfully locked. + * @par Dependency: + *
        • los_mux.h: the header file that contains the API declaration.
        + * @see LOS_MuxInit | LOS_MuxUnlock + */ +extern UINT32 LOS_MuxLock(LosMux *mutex, UINT32 timeout); + +/** + * @ingroup los_mux + * @brief Try wait to lock a mutex. + * + * @par Description: + * This API is used to wait for a specified period of time to lock a mutex. + * @attention + *
          + *
        • The specific mutex should be created firstly.
        • + *
        • The function fails if the mutex that is waited on is already locked by another thread when the task scheduling + * is disabled.
        • + *
        • Do not wait on a mutex during an interrupt.
        • + *
        • The priority inheritance protocol is supported. If a higher-priority thread is waiting on a mutex, it changes + * the priority of the thread that owns the mutex to avoid priority inversion.
        • + *
        • A recursive mutex can be locked more than once by the same thread.
        • + *
        • Do not call this API in software timer callback.
        • + *
        + * + * @param mutex [IN] Handle of the mutex to be waited on. + * + * @retval #LOS_EINVAL The mutex pointer is NULL or Lock status error. + * @retval #LOS_EINTR The mutex is being locked during an interrupt. + * @retval #LOS_EBUSY Tasks pended on this mutex. + * @retval #LOS_EBADF The lock has been destroyed or broken. + * @retval #LOS_EDEADLK Mutex error check failed or System locked task scheduling. + * @retval #LOS_ETIMEDOUT The mutex waiting times out. + * @retval #LOS_OK The mutex is successfully locked. + * @par Dependency: + *
        • los_mux.h: the header file that contains the API declaration.
        + * @see LOS_MuxInit | LOS_MuxUnlock + */ +extern UINT32 LOS_MuxTrylock(LosMux *mutex); + +/** + * @ingroup los_mux + * @brief Release a mutex. + * + * @par Description: + * This API is used to release a specified mutex. + * @attention + *
          + *
        • The specific mutex should be created firstly.
        • + *
        • Do not release a mutex during an interrupt.
        • + *
        • If a recursive mutex is locked for many times, it must be unlocked for the same times to be released.
        • + *
        + * + * @param mutex [IN] Handle of the mutex to be released. + * + * @retval #LOS_EINVAL The mutex pointer is NULL, The timeout is zero or Lock status error. + * @retval #LOS_EINTR The mutex is being locked during an interrupt. + * @retval #LOS_EBUSY Tasks pended on this mutex. + * @retval #LOS_EBADF The lock has been destroyed or broken. + * @retval #LOS_EDEADLK Mutex error check failed or System locked task scheduling. + * @retval #LOS_ETIMEDOUT The mutex waiting times out. + * @retval #LOS_OK The mutex is successfully locked. + * @par Dependency: + *
        • los_mux.h: the header file that contains the API declaration.
        + * @see LOS_MuxInit | LOS_MuxLock + */ +extern UINT32 LOS_MuxUnlock(LosMux *mutex); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif /* _LOS_MUX_H */ diff --git a/src/kernel_liteos_a/kernel/include/los_perf.h b/src/kernel_liteos_a/kernel/include/los_perf.h new file mode 100644 index 00000000..a28dca76 --- /dev/null +++ b/src/kernel_liteos_a/kernel/include/los_perf.h @@ -0,0 +1,439 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_perf Perf + * @ingroup kernel + */ + +#ifndef _LOS_PERF_H +#define _LOS_PERF_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_perf + * Perf max sample filter task number. + */ +#define PERF_MAX_FILTER_TSKS 32 + +/** + * @ingroup los_perf + * Perf max sample event counter's number. + */ +#define PERF_MAX_EVENT 7 + +/** + * @ingroup los_perf + * Perf max backtrace depth. + */ +#define PERF_MAX_CALLCHAIN_DEPTH 10 + +/** + * @ingroup los_perf + * Perf sample data buffer's water mark 1/N. + */ +#define PERF_BUFFER_WATERMARK_ONE_N 2 + +/** + * @ingroup los_perf + * Perf status. + */ +enum PerfStatus { + PERF_UNINIT, /* perf isn't inited */ + PERF_STARTED, /* perf is started */ + PERF_STOPPED, /* perf is stopped */ +}; + +/** + * @ingroup los_perf + * Define the type of the perf sample data buffer water mark hook function. + * + */ +typedef VOID (*PERF_BUF_NOTIFY_HOOK)(VOID); + +/** + * @ingroup los_perf + * Define the type of the perf sample data buffer flush hook function. + * + */ +typedef VOID (*PERF_BUF_FLUSH_HOOK)(VOID *addr, UINT32 size); + +/** + * @ingroup los_perf + * Perf error code: Bad status. + * + * Value: 0x02002000 + * + * Solution: Follow the perf state machine. + */ +#define LOS_ERRNO_PERF_STATUS_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_PERF, 0x00) + +/** + * @ingroup los_perf + * Perf error code: Hardware pmu init failed. + * + * Value: 0x02002001 + * + * Solution: Check the pmu hwi irq. + */ +#define LOS_ERRNO_PERF_HW_INIT_ERROR LOS_ERRNO_OS_ERROR(LOS_MOD_PERF, 0x01) + +/** + * @ingroup los_perf + * Perf error code: Hrtimer init failed for hrtimer timed pmu init. + * + * Value: 0x02002002 + * + * Solution: Check the Hrtimer init. + */ +#define LOS_ERRNO_PERF_TIMED_INIT_ERROR LOS_ERRNO_OS_ERROR(LOS_MOD_PERF, 0x02) + +/** + * @ingroup los_perf + * Perf error code: Software pmu init failed. + * + * Value: 0x02002003 + * + * Solution: Check the Perf software events init. + */ +#define LOS_ERRNO_PERF_SW_INIT_ERROR LOS_ERRNO_OS_ERROR(LOS_MOD_PERF, 0x03) + +/** + * @ingroup los_perf + * Perf error code: Perf buffer init failed. + * + * Value: 0x02002004 + * + * Solution: Check the buffer init size. + */ +#define LOS_ERRNO_PERF_BUF_ERROR LOS_ERRNO_OS_ERROR(LOS_MOD_PERF, 0x04) + +/** + * @ingroup los_perf + * Perf error code: Perf pmu type error. + * + * Value: 0x02002005 + * + * Solution: Check whether the corresponding pmu is enabled in the menuconfig. + */ +#define LOS_ERRNO_PERF_INVALID_PMU LOS_ERRNO_OS_ERROR(LOS_MOD_PERF, 0x05) + +/** + * @ingroup los_perf + * Perf error code: Perf pmu config error. + * + * Value: 0x02002006 + * + * Solution: Check the config attr of event id and event period. + */ +#define LOS_ERRNO_PERF_PMU_CONFIG_ERROR LOS_ERRNO_OS_ERROR(LOS_MOD_PERF, 0x06) + +/** + * @ingroup los_perf + * Perf error code: Perf pmu config attr is NULL. + * + * Value: 0x02002007 + * + * Solution: Check if the input params of attr is NULL. + */ +#define LOS_ERRNO_PERF_CONFIG_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_PERF, 0x07) + +/** + * @ingroup los_perf + * Perf types + */ +enum PerfEventType { + PERF_EVENT_TYPE_HW, /* boards common hw events */ + PERF_EVENT_TYPE_TIMED, /* hrtimer timed events */ + PERF_EVENT_TYPE_SW, /* software trace events */ + PERF_EVENT_TYPE_RAW, /* boards special hw events, see enum PmuEventType in corresponding arch headfile */ + + PERF_EVENT_TYPE_MAX +}; + +/** + * @ingroup los_perf + * Common hardware pmu events + */ +enum PmuHwId { + PERF_COUNT_HW_CPU_CYCLES = 0, /* cpu cycle event */ + PERF_COUNT_HW_INSTRUCTIONS, /* instruction event */ + PERF_COUNT_HW_DCACHE_REFERENCES, /* dcache access event */ + PERF_COUNT_HW_DCACHE_MISSES, /* dcache miss event */ + PERF_COUNT_HW_ICACHE_REFERENCES, /* icache access event */ + PERF_COUNT_HW_ICACHE_MISSES, /* icache miss event */ + PERF_COUNT_HW_BRANCH_INSTRUCTIONS, /* software change of pc event */ + PERF_COUNT_HW_BRANCH_MISSES, /* branch miss event */ + + PERF_COUNT_HW_MAX, +}; + +/** + * @ingroup los_perf + * Common hrtimer timed events + */ +enum PmuTimedId { + PERF_COUNT_CPU_CLOCK = 0, /* hrtimer timed event */ +}; + +/** + * @ingroup los_perf + * Common software pmu events + */ +enum PmuSwId { + PERF_COUNT_SW_TASK_SWITCH = 1, /* task switch event */ + PERF_COUNT_SW_IRQ_RESPONSE, /* irq response event */ + PERF_COUNT_SW_MEM_ALLOC, /* memory alloc event */ + PERF_COUNT_SW_MUX_PEND, /* mutex pend event */ + + PERF_COUNT_SW_MAX, +}; + +/** + * @ingroup los_perf + * perf sample data types + * Config it through PerfConfigAttr->sampleType. + */ +enum PerfSampleType { + PERF_RECORD_CPU = 1U << 0, /* record current cpuid */ + PERF_RECORD_TID = 1U << 1, /* record current task id */ + PERF_RECORD_TYPE = 1U << 2, /* record event type */ + PERF_RECORD_PERIOD = 1U << 3, /* record event period */ + PERF_RECORD_TIMESTAMP = 1U << 4, /* record timestamp */ + PERF_RECORD_IP = 1U << 5, /* record instruction pointer */ + PERF_RECORD_CALLCHAIN = 1U << 6, /* record backtrace */ + PERF_RECORD_PID = 1U << 7, /* record current process id */ +}; + +/** + * @ingroup los_perf + * perf configuration sub event information + * + * This structure is used to config specific events attributes. + */ +typedef struct { + UINT32 type; /* enum PerfEventType */ + struct { + UINT32 eventId; /* the specific event corresponds to the PerfEventType */ + UINT32 period; /* event period, for every "period"th occurrence of the event a + sample will be recorded */ + } events[PERF_MAX_EVENT]; /* perf event list */ + UINT32 eventsNr; /* total perf event number */ + BOOL predivided; /* whether to prescaler (once every 64 counts), + which only take effect on cpu cycle hardware event */ +} PerfEventConfig; + +/** + * @ingroup los_perf + * perf configuration main information + * + * This structure is used to set perf sampling attributes, including events, tasks and other information. + */ +typedef struct { + PerfEventConfig eventsCfg; /* perf event config */ + UINT32 taskIds[PERF_MAX_FILTER_TSKS]; /* perf task filter list (allowlist) */ + UINT32 taskIdsNr; /* task numbers of task filter allowlist, + if set 0 perf will sample all tasks */ + UINT32 processIds[PERF_MAX_FILTER_TSKS]; /* perf process filter list (allowlist) */ + UINT32 processIdsNr; /* process numbers of process filter allowlist, + if set 0 perf will sample all processes */ + UINT32 sampleType; /* type of data to sample defined in PerfSampleType */ + BOOL needSample; /* whether to sample data */ +} PerfConfigAttr; + +/** + * @ingroup los_perf + * @brief Init perf. + * + * @par Description: + *
          + *
        • Used to initialize the perf module, including initializing the PMU, allocating memory, + * etc.,which is called during the phase of system initialization.
        • + *
        + * @attention + *
          + *
        • If buf is not NULL, user must ensure size is not bigger than buf's length.
        • + *
        + * + * @param buf [IN] Pointer of sample data buffer;Use the dynamically allocated memory if the pointer is NULL. + * @param size [IN] Length of sample data buffer. + * + * @retval #LOS_ERRNO_PERF_STATUS_INVALID Perf in a wrong status. + * @retval #LOS_ERRNO_PERF_HW_INIT_ERROR Perf hardware pmu init fail. + * @retval #LOS_ERRNO_PERF_TIMED_INIT_ERROR Perf timed pmu init fail. + * @retval #LOS_ERRNO_PERF_SW_INIT_ERROR Perf software pmu init fail. + * @retval #LOS_ERRNO_PERF_BUF_ERROR Perf buffer init fail. + * @retval #LOS_OK Perf init success. + * @par Dependency: + *
          + *
        • los_perf.h: the header file that contains the API declaration.
        • + *
        + */ +UINT32 LOS_PerfInit(VOID *buf, UINT32 size); + +/** + * @ingroup los_perf + * @brief Start perf sampling. + * + * @par Description + * Start perf sampling. + * @attention + * None. + * + * @param sectionId [IN] Set the section id for marking this piece of data in the perf sample data buffer. + * @retval None. + * @par Dependency: + *
          + *
        • los_perf.h: the header file that contains the API declaration.
        • + *
        + */ +VOID LOS_PerfStart(UINT32 sectionId); + +/** + * @ingroup los_perf + * @brief Stop perf sampling. + * + * @par Description + * Stop perf sampling. + * @attention + * None. + * + * @param None. + * + * @retval None. + * @par Dependency: + *
          + *
        • los_perf.h: the header file that contains the API declaration.
        • + *
        + */ +VOID LOS_PerfStop(VOID); + +/** + * @ingroup los_perf + * @brief Config perf parameters. + * + * @par Description + * Config perf parameters before sample, for example, sample event, sample task, etc. This interface need to be called + * before LOS_PerfStart. + * @attention + * None. + * + * @param attr [IN] Address of a perf event attr struct. + * + * @retval #LOS_ERRNO_PERF_STATUS_INVALID Perf in a wrong status. + * @retval #LOS_ERRNO_PERF_CONFIG_NULL Attr is NULL. + * @retval #LOS_ERRNO_PERF_INVALID_PMU Config perf pmu with error type. + * @retval #LOS_ERRNO_PERF_PMU_CONFIG_ERROR Config perf events fail with invalid event id or event period. + * @retval #LOS_OK Config success. + * @par Dependency: + *
          + *
        • los_perf.h: the header file that contains the API declaration.
        • + *
        + */ +UINT32 LOS_PerfConfig(PerfConfigAttr *attr); + +/** + * @ingroup los_perf + * @brief Read data from perf sample data buffer. + * + * @par Description + * Because perf sample data buffer is a ringbuffer, the data may be covered after user read ringbuffer. + * @attention + * None. + * + * @param dest [IN] The destination address. + * @param size [IN] Read size. + * @retval #UINT32 The really read bytes. + * @par Dependency: + *
          + *
        • los_perf.h: the header file that contains the API declaration.
        • + *
        + */ +UINT32 LOS_PerfDataRead(CHAR *dest, UINT32 size); + +/** + * @ingroup los_perf + * @brief Register perf sample data buffer water mark hook function. + * + * @par Description + *
          + *
        • Register perf sample data buffer water mark hook function.
        • + *
        • The registered hook will be called when buffer reaches the water mark./li> + *
        + * @attention + * None. + * + * @param func [IN] Buffer water mark hook function. + * + * @retval None. + * @par Dependency: + *
          + *
        • los_perf.h: the header file that contains the API declaration.
        • + *
        + */ +VOID LOS_PerfNotifyHookReg(const PERF_BUF_NOTIFY_HOOK func); + +/** + * @ingroup los_perf + * @brief Register perf sample data buffer flush hook function. + * + * @par Description + *
          + *
        • Register perf sample data buffer flush hook function.
        • + *
        • The flush hook will be called when the buffer be read or written.
        • + *
        + * @attention + * None. + * + * @param func [IN] Buffer flush hook function. + * + * @retval None. + * @par Dependency: + *
          + *
        • los_perf.h: the header file that contains the API declaration.
        • + *
        + */ +VOID LOS_PerfFlushHookReg(const PERF_BUF_FLUSH_HOOK func); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_PERF_H */ diff --git a/src/kernel_liteos_a/kernel/include/los_pm.h b/src/kernel_liteos_a/kernel/include/los_pm.h new file mode 100644 index 00000000..6bfdb3e5 --- /dev/null +++ b/src/kernel_liteos_a/kernel/include/los_pm.h @@ -0,0 +1,327 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_PM_H +#define _LOS_PM_H + +#include "los_config.h" +#include "los_typedef.h" +#include "los_list.h" +#include "los_seq_buf.h" +#include "los_errno.h" + +typedef enum { + LOS_SYS_NORMAL_SLEEP = 0, + LOS_SYS_LIGHT_SLEEP, + LOS_SYS_DEEP_SLEEP, + LOS_SYS_SHUTDOWN, +} LOS_SysSleepEnum; + +typedef enum { + LOS_PM_TYPE_DEVICE = 0, + LOS_PM_TYPE_TICK_TIMER, /* reserved */ + LOS_PM_TYPE_SYSCTRL, +} LOS_PmNodeType; + +typedef struct { + UINT32 (*suspend)(UINT32 mode); /* The device enters low power consumption, Unlocked task scheduling. */ + VOID (*resume)(UINT32 mode); /* The device exits from low power consumption, Unlocked task scheduling. */ +} LosPmDevice; + +typedef struct { + /* Preparations before the CPU enters low power consumption. + * All modes except normal mode are invoked. + * Unlocked task scheduling. + */ + UINT32 (*early)(UINT32 mode); + /* The system performs low-power recovery. + * All modes except normal mode are invoked. + * Unlocked task scheduling. + */ + VOID (*late)(UINT32 mode); + /* The system enters the Normal sleep mode. + * In normal mode, the value cannot be NULL. + */ + UINT32 (*normalSuspend)(VOID); + /* The system recovers from normal sleep. + * The value can be NULL. + */ + VOID (*normalResume)(VOID); + /* The system enters the light sleep mode. + * In light sleep mode, the value cannot be NULL. + */ + UINT32 (*lightSuspend)(VOID); + /* The system recovers from light sleep. + * The value can be NULL. + */ + VOID (*lightResume)(VOID); + /* The system enters the deep sleep mode. + * In deep sleep mode, the value cannot be NULL. + */ + UINT32 (*deepSuspend)(VOID); + /* The system recovers from deep sleep. + * The value can be NULL. + */ + VOID (*deepResume)(VOID); + /* The system enters the shutdown mode. + * In shutdown mode, the value cannot be NULL. + */ + UINT32 (*shutdownSuspend)(VOID); + /* The system recovers from shutdown. + * In shutdown mode, the value cannot be NULL. + */ + VOID (*shutdownResume)(VOID); +} LosPmSysctrl; + +/** + * @ingroup los_pm + * @brief Register a power management node. + * + * @par Description: + * This API is used to register a power management node. + * + * @attention None. + * + * @param type [IN] The types supported by the PM module. + * @param node [IN] power management node. + * + * @retval error code, LOS_OK means success. + * @par Dependency: + *
        • los_pm.h: the header file that contains the API declaration.
        + * @see LOS_PmUnregister + */ +UINT32 LOS_PmRegister(LOS_PmNodeType type, VOID *node); + +/** + * @ingroup los_pm + * @brief Unregister a power management node. + * + * @par Description: + * This API is used to unregister a power management node. + * + * @attention None. + * + * @param type [IN] The types supported by the PM module. + * @param node [IN] power management node. + * + * @retval error code, LOS_OK means success. + * @par Dependency: + *
        • los_pm.h: the header file that contains the API declaration.
        + * @see LOS_PmRegister + */ +UINT32 LOS_PmUnregister(LOS_PmNodeType type, VOID *node); + +/** + * @ingroup los_pm + * @brief Set the system wake up flag. + * + * @par Description: + * This API is used to set the system wake-up flag. + * + * @attention None. + * + * @param None. + * + * @retval None. + * @par Dependency: + *
        • los_pm.h: the header file that contains the API declaration.
        + * @see + */ +VOID LOS_PmWakeSet(VOID); + +/** + * @ingroup los_pm + * @brief Get the low power mode of the current system. + * + * @par Description: + * This API is used to get the low power mode of the current system. + * + * @attention None. + * + * @param None. + * + * @retval error code, LOS_OK means success. + * @par Dependency: + *
        • los_pm.h: the header file that contains the API declaration.
        + * @see + */ +LOS_SysSleepEnum LOS_PmModeGet(VOID); + +/** + * @ingroup los_pm + * @brief Set low power mode. + * + * @par Description: + * This API is used to set low power mode. + * + * @attention None. + * + * @param mode [IN] low power mode. + * + * @retval error code, LOS_OK means success. + * @par Dependency: + *
        • los_pm.h: the header file that contains the API declaration.
        + * @see LOS_PmModeGet + */ +UINT32 LOS_PmModeSet(LOS_SysSleepEnum mode); + +/** + * @ingroup los_pm + * @brief Get the low power mode of the current system. + * + * @par Description: + * This API is used to get the low power mode of the current system. + * + * @attention None. + * + * @param None. + * + * @retval Number of locks held. + * @par Dependency: + *
        • los_pm.h: the header file that contains the API declaration.
        + * @see + */ +UINT32 LOS_PmLockCountGet(VOID); + +/** + * @ingroup los_pm + * @brief Request to obtain the lock in current mode, so that the system will not enter + * this mode when it enters the idle task next time. + * + * @par Description: + * This API is used to obtain the lock in current mode. + * + * @attention None. + * + * @param name [IN] Who requests the lock. + * + * @retval error code, LOS_OK means success. + * @par Dependency: + *
        • los_pm.h: the header file that contains the API declaration.
        + * @see LOS_PmLockRelease + */ +UINT32 LOS_PmLockRequest(const CHAR *name); + +/** + * @ingroup los_pm + * @brief Request to obtain the lock in current mode, so that the system will not enter + * this mode when it enters the idle task next time. After the specified interval, the + * lock is automatically released. + * + * @par Description: + * This API is used to obtain the delay lock in current mode. + * + * @attention None. + * + * @param name [IN] Who requests the lock. + * @param millisecond [IN] Specifies the time to automatically release the lock. + * + * @retval error code, LOS_OK means success. + * @par Dependency: + *
        • los_pm.h: the header file that contains the API declaration.
        + * @see LOS_PmLockRelease + */ +UINT32 LOS_PmTimeLockRequest(const CHAR *name, UINT64 millisecond); + +/** + * @ingroup los_pm + * @brief Release the lock in current mode so that the next time the system enters + * the idle task, it will enter this mode. + * + * @par Description: + * This API is used to release the lock in current mode. + * + * @attention None. + * + * @param name [IN] Who releases the lock. + * + * @retval error code, LOS_OK means success. + * @par Dependency: + *
        • los_pm.h: the header file that contains the API declaration.
        + * @see LOS_PmLockRequest + */ +UINT32 LOS_PmLockRelease(const CHAR *name); + +/** + * @ingroup los_pm + * @brief Gets the current PM lock status. + * + * @par Description: + * This API is used to Get the current PM lock status. + * + * @attention None. + * + * @param None. + * + * @retval Number of awakening sources of the device. + * @par Dependency: + *
        • los_pm.h: the header file that contains the API declaration.
        + * @see + */ +UINT32 LOS_PmReadLock(VOID); + +/** + * @ingroup los_pm + * @brief The system enters the low-power flow. + * + * @par Description: + * This API is used to enter the system into a low-power process. + * + * @attention None. + * + * @param wakeCount [IN] Number of wake sources. + * + * @retval error code, LOS_OK means success. + * @par Dependency: + *
        • los_pm.h: the header file that contains the API declaration.
        + * @see + */ +UINT32 LOS_PmSuspend(UINT32 wakeCount); + +/** + * @ingroup los_pm + * @brief Output the locking information of the pm lock. + * + * @par Description: + * This API is used to output the locking information of the pm lock. + * + * @attention None. + * + * @param m [IN] . + * + * @retval error code, LOS_OK means success. + * @par Dependency: + *
        • los_pm.h: the header file that contains the API declaration.
        + * @see LOS_PmLockRequest + */ +VOID LOS_PmLockInfoShow(struct SeqBuf *m); + +#endif diff --git a/src/kernel_liteos_a/kernel/include/los_printf.h b/src/kernel_liteos_a/kernel/include/los_printf.h new file mode 100644 index 00000000..69f759e6 --- /dev/null +++ b/src/kernel_liteos_a/kernel/include/los_printf.h @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_printf Printf + * @ingroup kernel + */ + +#ifndef _LOS_PRINTF_H +#define _LOS_PRINTF_H + +#ifdef LOSCFG_LIB_LIBC +#include "stdarg.h" +#endif +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +extern VOID LOS_LkPrint(INT32 level, const CHAR *func, INT32 line, const CHAR *fmt, ...); + +#define LOS_EMG_LEVEL 0 + +#define LOS_COMMON_LEVEL (LOS_EMG_LEVEL + 1) + +#define LOS_ERR_LEVEL (LOS_COMMON_LEVEL + 1) + +#define LOS_WARN_LEVEL (LOS_ERR_LEVEL + 1) + +#define LOS_INFO_LEVEL (LOS_WARN_LEVEL + 1) + +#define LOS_DEBUG_LEVEL (LOS_INFO_LEVEL + 1) + +#define LOS_TRACE_LEVEL (LOS_DEBUG_LEVEL + 1) + +#define PRINT_LEVEL LOS_ERR_LEVEL + +typedef VOID (*pf_OUTPUT)(const CHAR *fmt, ...); + +/** + * @ingroup los_printf + * @brief Format and print data. + * + * @par Description: + * Print argument(s) according to fmt. + * + * @attention + *
          + *
        • None
        • + *
        + * + * @param fmt [IN] Type char* controls the output as in C printf. + * + * @retval None + * @par Dependency: + *
        • los_printf.h: the header file that contains the API declaration.
        + * @see printf + */ +#ifndef LOSCFG_LIBC_NEWLIB +extern void dprintf(const char *fmt, ...); +#endif + +#define PRINT_DEBUG(fmt, args...) LOS_LkPrint(LOS_DEBUG_LEVEL, __FUNCTION__, __LINE__, fmt, ##args) +#define PRINT_INFO(fmt, args...) LOS_LkPrint(LOS_INFO_LEVEL, __FUNCTION__, __LINE__, fmt, ##args) +#define PRINT_WARN(fmt, args...) LOS_LkPrint(LOS_WARN_LEVEL, __FUNCTION__, __LINE__, fmt, ##args) +#define PRINT_ERR(fmt, args...) LOS_LkPrint(LOS_ERR_LEVEL, __FUNCTION__, __LINE__, fmt, ##args) +#define PRINTK(fmt, args...) LOS_LkPrint(LOS_COMMON_LEVEL, __FUNCTION__, __LINE__, fmt, ##args) +#define PRINT_EMG(fmt, args...) LOS_LkPrint(LOS_EMG_LEVEL, __FUNCTION__, __LINE__, fmt, ##args) +#define PRINT_RELEASE(fmt, args...) LOS_LkPrint(LOS_COMMON_LEVEL, __FUNCTION__, __LINE__, fmt, ##args) +#define PRINT_TRACE(fmt, args...) LOS_LkPrint(LOS_TRACE_LEVEL, __FUNCTION__, __LINE__, fmt, ##args) + +typedef enum { + NO_OUTPUT = 0, + UART_OUTPUT = 1, + CONSOLE_OUTPUT = 2, + EXC_OUTPUT = 3 +} OutputType; + +extern VOID OsVprintf(const CHAR *fmt, va_list ap, OutputType type); + +#define UART_WITHOUT_LOCK 0 +#define UART_WITH_LOCK 1 +extern VOID UartPuts(const CHAR *s, UINT32 len, BOOL isLock); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_PRINTF_H */ diff --git a/src/kernel_liteos_a/kernel/include/los_process.h b/src/kernel_liteos_a/kernel/include/los_process.h new file mode 100644 index 00000000..af1a9e2e --- /dev/null +++ b/src/kernel_liteos_a/kernel/include/los_process.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_PROCESS_H +#define _LOS_PROCESS_H + +#include "los_task.h" +#include + +#ifdef LOSCFG_FS_VFS +#include "fs/fd_table.h" +#endif + +#ifdef __cplusplus +#if __cplusplus + extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +extern INT32 LOS_Fork(UINT32 flags, const CHAR *name, const TSK_ENTRY_FUNC entry, UINT32 stackSize); + +extern INT32 LOS_SetProcessPriority(INT32 pid, INT32 prio); + +extern INT32 LOS_GetProcessPriority(INT32 pid); + +extern INT32 LOS_GetProcessScheduler(INT32 pid, INT32 *policy, LosSchedParam *schedParam); + +extern INT32 LOS_SetProcessScheduler(INT32 pid, UINT16 policy, const LosSchedParam *schedParam); + +extern UINT32 LOS_GetCurrProcessID(VOID); + +extern INT32 LOS_Wait(INT32 pid, USER INT32 *status, UINT32 options, VOID *rusage); + +extern INT32 LOS_Waitid(INT32 pid, USER siginfo_t *info, UINT32 options, VOID *rusage); + +extern INT32 LOS_GetCurrProcessGroupID(VOID); + +extern INT32 LOS_GetProcessGroupID(UINT32 pid); + +extern VOID LOS_Exit(INT32 status); + +extern UINT32 LOS_GetSystemProcessMaximum(VOID); + +#ifdef LOSCFG_SECURITY_CAPABILITY +extern BOOL LOS_CheckInGroups(UINT32 gid); +#endif +extern INT32 LOS_GetUserID(VOID); +extern INT32 LOS_GetGroupID(VOID); + +extern INT32 LOS_GetUsedPIDList(UINT32 *pidList, INT32 pidMaxNum); + +#ifdef LOSCFG_FS_VFS +struct fd_table_s *LOS_GetFdTable(UINT32 pid); +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/src/kernel_liteos_a/kernel/include/los_queue.h b/src/kernel_liteos_a/kernel/include/los_queue.h new file mode 100644 index 00000000..4beaffdf --- /dev/null +++ b/src/kernel_liteos_a/kernel/include/los_queue.h @@ -0,0 +1,735 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_queue Queue + * @ingroup kernel + */ + +#ifndef _LOS_QUEUE_H +#define _LOS_QUEUE_H + +#include "los_base.h" +#include "los_list.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_queue + * Queue error code: The maximum number of queue resources is configured to 0. + * + * Value: 0x02000600 + * + * Solution: Configure the maximum number of queue resources to be greater than 0. If queue modules are not used, + * set the configuration item for the tailoring of the maximum number of queue resources to NO. + */ +#define LOS_ERRNO_QUEUE_MAXNUM_ZERO LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x00) + +/** + * @ingroup los_queue + * Queue error code: The queue block memory fails to be initialized. + * + * Value: 0x02000601 + * + * Solution: Allocate the queue block bigger memory partition, or decrease the maximum number of queue resources. + */ +#define LOS_ERRNO_QUEUE_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x01) + +/** + * @ingroup los_queue + * Queue error code: The memory for queue creation fails to be requested. + * + * Value: 0x02000602 + * + * Solution: Allocate more memory for queue creation, or decrease the queue length and the number of nodes + * in the queue to be created. + */ +#define LOS_ERRNO_QUEUE_CREATE_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x02) + +/** + * @ingroup los_queue + * Queue error code: The size of the biggest message in the created queue is too big. + * + * Value: 0x02000603 + * + * Solution: Change the size of the biggest message in the created queue. + */ +#define LOS_ERRNO_QUEUE_SIZE_TOO_BIG LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x03) + +/** + * @ingroup los_queue + * Queue error code: The upper limit of the number of created queues is exceeded. + * + * Value: 0x02000604 + * + * Solution: Increase the configured number of resources for queues. + */ +#define LOS_ERRNO_QUEUE_CB_UNAVAILABLE LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x04) + +/** + * @ingroup los_queue + * Queue error code: Invalid queue. + * + * Value: 0x02000605 + * + * Solution: Ensure that the passed-in queue ID is valid. + */ +#define LOS_ERRNO_QUEUE_NOT_FOUND LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x05) + +/** + * @ingroup los_queue + * Queue error code: The task is forbidden to be blocked on a queue when the task is locked. + * + * Value: 0x02000606 + * + * Solution: Unlock the task before using a queue. + */ +#define LOS_ERRNO_QUEUE_PEND_IN_LOCK LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x06) + +/** + * @ingroup los_queue + * Queue error code: The time set for waiting to processing the queue expires. + * + * Value: 0x02000607 + * + * Solution: Check whether the expiry time setting is appropriate. + */ +#define LOS_ERRNO_QUEUE_TIMEOUT LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x07) + +/** + * @ingroup los_queue + * Queue error code: The queue that blocks a task cannot be deleted. + * + * Value: 0x02000608 + * + * Solution: Enable the task to obtain resources rather than be blocked on the queue. + */ +#define LOS_ERRNO_QUEUE_IN_TSKUSE LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x08) + +/** + * @ingroup los_queue + * Queue error code: The queue cannot be written during an interrupt when the time for waiting to + * processing the queue expires. + * + * Value: 0x02000609 + * + * Solution: Set the expiry time to the never-waiting mode, or use asynchronous queues. + */ +#define LOS_ERRNO_QUEUE_WRITE_IN_INTERRUPT LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x09) + +/** + * @ingroup los_queue + * Queue error code: The queue is not created. + * + * Value: 0x0200060a + * + * Solution: Check whether the passed-in queue handle value is valid. + */ +#define LOS_ERRNO_QUEUE_NOT_CREATE LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x0a) + +/** + * @ingroup los_queue + * Queue error code: Queue reading and writing are not synchronous. + * + * Value: 0x0200060b + * + * Solution: Synchronize queue reading with queue writing. + */ +#define LOS_ERRNO_QUEUE_IN_TSKWRITE LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x0b) + +/** + * @ingroup los_queue + * Queue error code: Parameters passed in during queue creation are null pointers. + * + * Value: 0x0200060c + * + * Solution: Ensure the passed-in parameters are not null pointers. + */ +#define LOS_ERRNO_QUEUE_CREAT_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x0c) + +/** + * @ingroup los_queue + * Queue error code: The queue length or message node size passed in during queue creation is 0. + * + * Value: 0x0200060d + * + * Solution: Pass in correct queue length and message node size. + */ +#define LOS_ERRNO_QUEUE_PARA_ISZERO LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x0d) + +/** + * @ingroup los_queue + * Queue error code: The handle of the queue is invalid. + * + * Value: 0x0200060e + * + * Solution: Check whether the passed-in queue handle value is valid. + */ +#define LOS_ERRNO_QUEUE_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x0e) + +/** + * @ingroup los_queue + * Queue error code: The pointer passed in during queue reading is null. + * + * Value: 0x0200060f + * + * Solution: Check whether the passed-in pointer is null. + */ +#define LOS_ERRNO_QUEUE_READ_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x0f) + +/** + * @ingroup los_queue + * Queue error code: The buffer size passed in during queue reading is too small or too big. + * + * Value: 0x02000610 + * + * Solution: Pass in a correct buffer size between [sizeof(CHAR*), OS_NULL_SHORT - sizeof(UINT32)]. + */ +#define LOS_ERRNO_QUEUE_READSIZE_IS_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x10) + +/** + * @ingroup los_queue + * Queue error code: The pointer passed in during queue writing is null. + * + * Value: 0x02000612 + * + * Solution: Check whether the passed-in pointer is null. + */ +#define LOS_ERRNO_QUEUE_WRITE_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x12) + +/** + * @ingroup los_queue + * Queue error code: The buffer size passed in during queue writing is 0. + * + * Value: 0x02000613 + * + * Solution: Pass in a correct buffer size. + */ +#define LOS_ERRNO_QUEUE_WRITESIZE_ISZERO LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x13) + +/** + * @ingroup los_queue + * Queue error code: The buffer size passed in during queue writing is bigger than the queue size. + * + * Value: 0x02000615 + * + * Solution: Decrease the buffer size, or use a queue in which nodes are bigger. + */ +#define LOS_ERRNO_QUEUE_WRITE_SIZE_TOO_BIG LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x15) + +/** + * @ingroup los_queue + * Queue error code: No free node is available during queue writing. + * + * Value: 0x02000616 + * + * Solution: Ensure that free nodes are available before queue writing. + */ +#define LOS_ERRNO_QUEUE_ISFULL LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x16) + +/** + * @ingroup los_queue + * Queue error code: The pointer passed in when the queue information is being obtained is null. + * + * Value: 0x02000617 + * + * Solution: Check whether the passed-in pointer is null. + */ +#define LOS_ERRNO_QUEUE_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x17) + +/** + * @ingroup los_queue + * Queue error code: The queue cannot be read during an interrupt + * when the time for waiting to processing the queue expires. + * + * Value: 0x02000618 + * + * Solution: Set the expiry time to the never-waiting mode, or use asynchronous queues. + */ +#define LOS_ERRNO_QUEUE_READ_IN_INTERRUPT LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x18) + +/** + * @ingroup los_queue + * Queue error code: The handle of the queue passed-in when the memory for the queue is being freed is invalid. + * + * Value: 0x02000619 + * + * Solution: Check whether the passed-in queue handle value is valid. + */ +#define LOS_ERRNO_QUEUE_MAIL_HANDLE_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x19) + +/** + * @ingroup los_queue + * Queue error code: The pointer to the memory to be freed is null. + * + * Value: 0x0200061a + * + * Solution: Check whether the passed-in pointer is null. + */ +#define LOS_ERRNO_QUEUE_MAIL_PTR_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x1a) + +/** + * @ingroup los_queue + * Queue error code: The memory for the queue fails to be freed. + * + * Value: 0x0200061b + * + * Solution: Pass in correct input parameters. + */ +#define LOS_ERRNO_QUEUE_MAIL_FREE_ERROR LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x1b) + +/** + * @ingroup los_queue + * Queue error code: No resource is in the queue that is being read when the + * time for waiting to processing the queue expires. + * + * Value: 0x0200061d + * + * Solution: Ensure that the queue contains messages when it is being read. + */ +#define LOS_ERRNO_QUEUE_ISEMPTY LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x1d) + +/** + * @ingroup los_queue + * Queue error code: The buffer size passed in during queue reading is smaller than the queue size. + * + * Value: 0x0200061f + * + * Solution: Increase the buffer size, or use a queue in which nodes are smaller. + */ +#define LOS_ERRNO_QUEUE_READ_SIZE_TOO_SMALL LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x1f) + +/** + * @ingroup los_queue + * Structure of the block for queue information query + */ +typedef struct tagQueueInfo { + UINT32 uwQueueID; /**< Queue ID */ + UINT16 usQueueLen; /**< Queue length */ + UINT16 usQueueSize; /**< Node size */ + UINT16 usQueueHead; /**< Node head */ + UINT16 usQueueTail; /**< Node tail */ + UINT16 usWritableCnt; /**< Count of writable resources */ + UINT16 usReadableCnt; /**< Count of readable resources */ + UINT64 uwWaitReadTask; /**< Resource reading task */ + UINT64 uwWaitWriteTask; /**< Resource writing task */ + UINT64 uwWaitMemTask; /**< Memory task */ +} QUEUE_INFO_S; + +/** + * @ingroup los_queue + * @brief Create a message queue. + * + * @par Description: + * This API is used to create a message queue. + * @attention + *
          + *
        • There are LOSCFG_BASE_IPC_QUEUE_LIMIT queues available, change it's value when necessary.
        • + *
        + * @param queueName [IN] Message queue name. Reserved parameter, not used for now. + * @param len [IN] Queue length. The value range is [1,0xffff]. + * @param queueID [OUT] ID of the queue control structure that is successfully created. + * @param flags [IN] Queue mode. Reserved parameter, not used for now. + * @param maxMsgSize [IN] Node size. The value range is [1,0xffff-4]. + * + * @retval #LOS_OK The message queue is successfully created. + * @retval #LOS_ERRNO_QUEUE_CB_UNAVAILABLE The upper limit of the number of created queues is exceeded. + * @retval #LOS_ERRNO_QUEUE_CREATE_NO_MEMORY Insufficient memory for queue creation. + * @retval #LOS_ERRNO_QUEUE_CREAT_PTR_NULL Null pointer, queueID is NULL. + * @retval #LOS_ERRNO_QUEUE_PARA_ISZERO The queue length or message node size passed in during queue + * creation is 0. + * @retval #LOS_ERRNO_QUEUE_SIZE_TOO_BIG The parameter usMaxMsgSize is larger than 0xffff - 4. + * @par Dependency: + *
        • los_queue.h: the header file that contains the API declaration.
        + * @see LOS_QueueDelete + */ +extern UINT32 LOS_QueueCreate(CHAR *queueName, + UINT16 len, + UINT32 *queueID, + UINT32 flags, + UINT16 maxMsgSize); + +/** + * @ingroup los_queue + * @brief Read a queue. + * + * @par Description: + * This API is used to read data in a specified queue, and store the obtained data to the address specified + * by bufferAddr. The address and the size of the data to be read are defined by users. + * @attention + *
          + *
        • The specific queue should be created firstly.
        • + *
        • Queue reading adopts the fist in first out (FIFO) mode. The data that is first stored in the queue is read + * first.
        • + *
        • bufferAddr stores the obtained data.
        • + *
        • Do not read or write a queue in unblocking modes such as an interrupt.
        • + *
        • This API cannot be called before the Huawei LiteOS is initialized.
        • + *
        • The argument timeout is a relative time.
        • + *
        • Do not call this API in software timer callback.
        • + *
        + * + * @param queueID [IN] Queue ID created by LOS_QueueCreate. The value range is + * [1,LOSCFG_BASE_IPC_QUEUE_LIMIT]. + * @param bufferAddr [OUT] Starting address that stores the obtained data. The starting address must not be + * null. + * @param bufferSize [IN/OUT] Where to maintain the buffer wanted-size before read, and the real-size after read. + * @param timeout [IN] Expiry time. The value range is [0,LOS_WAIT_FOREVER](unit: Tick). + * + * @retval #LOS_OK The queue is successfully read. + * @retval #LOS_ERRNO_QUEUE_INVALID The handle of the queue that is being read is invalid. + * @retval #LOS_ERRNO_QUEUE_READ_PTR_NULL The pointer passed in during queue reading is null. + * @retval #LOS_ERRNO_QUEUE_READSIZE_IS_INVALID The buffer size passed in during queue reading is invalid. + * @retval #LOS_ERRNO_QUEUE_READ_IN_INTERRUPT The queue cannot be read during an interrupt when the time for + * waiting to processing the queue expires. + * @retval #LOS_ERRNO_QUEUE_NOT_CREATE The queue to be read is not created. + * @retval #LOS_ERRNO_QUEUE_ISEMPTY No resource is in the queue that is being read when the time for + * waiting to processing the queue expires. + * @retval #LOS_ERRNO_QUEUE_PEND_IN_LOCK The task is forbidden to be blocked on a queue when the task is + * locked. + * @retval #LOS_ERRNO_QUEUE_TIMEOUT The time set for waiting to processing the queue expires. + * @retval #LOS_ERRNO_QUEUE_READ_SIZE_TOO_SMALL The buffer size passed in during queue reading is less than + * the queue size. + * @par Dependency: + *
        • los_queue.h: the header file that contains the API declaration.
        + * @see LOS_QueueWriteCopy | LOS_QueueCreate + */ +extern UINT32 LOS_QueueReadCopy(UINT32 queueID, + VOID *bufferAddr, + UINT32 *bufferSize, + UINT32 timeout); + +/** + * @ingroup los_queue + * @brief Write data into a queue. + * + * @par Description: + * This API is used to write the data of the size specified by bufferSize and stored at the address specified by + * bufferAddr into a queue. + * @attention + *
          + *
        • The specific queue should be created firstly.
        • + *
        • Do not read or write a queue in unblocking modes such as interrupt.
        • + *
        • This API cannot be called before the Huawei LiteOS is initialized.
        • + *
        • The data to be written is of the size specified by bufferSize and is stored at the address specified by + * bufferAddr.
        • + *
        • The argument timeout is a relative time.
        • + *
        • Do not call this API in software timer callback.
        • + *
        + * + * @param queueID [IN] Queue ID created by LOS_QueueCreate. The value range is + * [1,LOSCFG_BASE_IPC_QUEUE_LIMIT]. + * @param bufferAddr [IN] Starting address that stores the data to be written.The starting address must + * not be null. + * @param bufferSize [IN] Passed-in buffer size. The value range is [1,USHRT_MAX - sizeof(UINT32)]. + * @param timeout [IN] Expiry time. The value range is [0,LOS_WAIT_FOREVER](unit: Tick). + * + * @retval #LOS_OK The data is successfully written into the queue. + * @retval #LOS_ERRNO_QUEUE_INVALID The queue handle passed in during queue writing is invalid. + * @retval #LOS_ERRNO_QUEUE_WRITE_PTR_NULL The pointer passed in during queue writing is null. + * @retval #LOS_ERRNO_QUEUE_WRITESIZE_ISZERO The buffer size passed in during queue writing is 0. + * @retval #LOS_ERRNO_QUEUE_WRITE_IN_INTERRUPT The queue cannot be written during an interrupt when the time + * for waiting to processing the queue expires. + * @retval #LOS_ERRNO_QUEUE_NOT_CREATE The queue into which the data is written is not created. + * @retval #LOS_ERRNO_QUEUE_WRITE_SIZE_TOO_BIG The buffer size passed in during queue writing is bigger than + * the queue size. + * @retval #LOS_ERRNO_QUEUE_ISFULL No free node is available during queue writing. + * @retval #LOS_ERRNO_QUEUE_PEND_IN_LOCK The task is forbidden to be blocked on a queue when + * the task is locked. + * @retval #LOS_ERRNO_QUEUE_TIMEOUT The time set for waiting to processing the queue expires. + * @par Dependency: + *
        • los_queue.h: the header file that contains the API declaration.
        + * @see LOS_QueueReadCopy | LOS_QueueCreate + */ +extern UINT32 LOS_QueueWriteCopy(UINT32 queueID, + VOID *bufferAddr, + UINT32 bufferSize, + UINT32 timeout); + +/** + * @ingroup los_queue + * @brief Read a queue. + * + * @par Description: + * This API is used to read the address of data in a specified queue, and store it to the address specified by + * bufferAddr. + * @attention + *
          + *
        • The specific queue should be created firstly.
        • + *
        • Queue reading adopts the fist in first out (FIFO) mode. The data that is first stored in the queue is + * read first.
        • + *
        • bufferAddr stores the obtained data address.
        • + *
        • Do not read or write a queue in unblocking modes such as an interrupt.
        • + *
        • This API cannot be called before the Huawei LiteOS is initialized.
        • + *
        • The argument timeout is a relative time.
        • + *
        • The bufferSize is not really used in LOS_QueueRead, because the interface is only used to + * obtain the address of data.
        • + *
        • The buffer which the bufferAddr pointing to must be greater than or equal to 4 bytes.
        • + *
        • Do not call this API in software timer callback.
        • + *
        + * + * @param queueID [IN] Queue ID created by LOS_QueueCreate. The value range is + * [1,LOSCFG_BASE_IPC_QUEUE_LIMIT]. + * @param bufferAddr [OUT] Starting address that stores the obtained data. The starting address must + * not be null. + * @param bufferSize [IN] Passed-in buffer size,The value range is + * [sizeof(CHAR*),OS_NULL_SHORT - sizeof(UINT32)]. + * @param timeout [IN] Expiry time. The value range is [0,LOS_WAIT_FOREVER](unit: Tick). + * + * @retval #LOS_OK The queue is successfully read. + * @retval #LOS_ERRNO_QUEUE_INVALID The handle of the queue that is being read is invalid. + * @retval #LOS_ERRNO_QUEUE_READ_PTR_NULL The pointer passed in during queue reading is null. + * @retval #LOS_ERRNO_QUEUE_READSIZE_IS_INVALID The buffer size passed in during queue reading is invalid. + * @retval #LOS_ERRNO_QUEUE_READ_IN_INTERRUPT The queue cannot be read during an interrupt when the time for + * waiting to processing the queue expires. + * @retval #LOS_ERRNO_QUEUE_NOT_CREATE The queue to be read is not created. + * @retval #LOS_ERRNO_QUEUE_ISEMPTY No resource is in the queue that is being read when the time for + * waiting to processing the queue expires. + * @retval #LOS_ERRNO_QUEUE_PEND_IN_LOCK The task is forbidden to be blocked on a queue when the task is + * locked. + * @retval #LOS_ERRNO_QUEUE_TIMEOUT The time set for waiting to processing the queue expires. + * @par Dependency: + *
        • los_queue.h: The header file that contains the API declaration.
        + * @see LOS_QueueWrite | LOS_QueueCreate + */ +extern UINT32 LOS_QueueRead(UINT32 queueID, + VOID *bufferAddr, + UINT32 bufferSize, + UINT32 timeout); + +/** + * @ingroup los_queue + * @brief Write data into a queue. + * + * @par Description: + * This API is used to write the address of data specified by bufferAddr into a queue. + * @attention + *
          + *
        • The specific queue should be created firstly.
        • + *
        • Do not read or write a queue in unblocking modes such as an interrupt.
        • + *
        • This API cannot be called before the Huawei LiteOS is initialized.
        • + *
        • The address of the data of the size specified by bufferSize and stored at the address specified by + * bufferAddr is to be written.
        • + *
        • The argument timeout is a relative time.
        • + *
        • The bufferSize is not really used in LOS_QueueWrite, because the interface is only used to write the address + * of data specified by bufferAddr into a queue.
        • + *
        • Do not call this API in software timer callback.
        • + *
        + * + * @param queueID [IN] Queue ID created by LOS_QueueCreate. The value range is + * [1,LOSCFG_BASE_IPC_QUEUE_LIMIT]. + * @param bufferAddr [IN] Starting address that stores the data to be written. The starting address + * must not be null. + * @param bufferSize [IN] This parameter is not in use temporarily. + * @param timeout [IN] Expiry time. The value range is [0,LOS_WAIT_FOREVER](unit: Tick). + * + * @retval #LOS_OK The data is successfully written into the queue. + * @retval #LOS_ERRNO_QUEUE_INVALID The queue handle passed in during queue writing is invalid. + * @retval #LOS_ERRNO_QUEUE_WRITE_PTR_NULL The pointer passed in during queue writing is null. + * @retval #LOS_ERRNO_QUEUE_WRITESIZE_ISZERO The buffer size passed in during queue writing is 0. + * @retval #LOS_ERRNO_QUEUE_WRITE_IN_INTERRUPT The queue cannot be written during an interrupt when the time for + * waiting to processing the queue expires. + * @retval #LOS_ERRNO_QUEUE_NOT_CREATE The queue into which the data is written is not created. + * @retval #LOS_ERRNO_QUEUE_WRITE_SIZE_TOO_BIG The buffer size passed in during queue writing is bigger than + * the queue size. + * @retval #LOS_ERRNO_QUEUE_ISFULL No free node is available during queue writing. + * @retval #LOS_ERRNO_QUEUE_PEND_IN_LOCK The task is forbidden to be blocked on a queue when the task is + * locked. + * @retval #LOS_ERRNO_QUEUE_TIMEOUT The time set for waiting to processing the queue expires. + * @par Dependency: + *
        • los_queue.h: The header file that contains the API declaration.
        + * @see LOS_QueueRead | LOS_QueueCreate + */ +extern UINT32 LOS_QueueWrite(UINT32 queueID, + VOID *bufferAddr, + UINT32 bufferSize, + UINT32 timeout); + +/** + * @ingroup los_queue + * @brief Write data into a queue header. + * + * @par Description: + * This API is used to write the data of the size specified by bufferSize and stored at the address specified by + * bufferAddr into a queue header. + * @attention + *
          + *
        • Do not read or write a queue in unblocking modes such as an interrupt.
        • + *
        • This API cannot be called before the Huawei LiteOS is initialized.
        • + *
        • The address of the data of the size specified by bufferSize and stored at the address specified by + * bufferAddr is to be written.
        • + *
        • The argument timeout is a relative time.
        • + *
        • LOS_QueueRead and LOS_QueueWriteHead are a set of interfaces, and the two groups of interfaces need to + * be used.
        • + *
        • Do not call this API in software timer callback.
        • + *
        + * + * @param queueID [IN] Queue ID created by LOS_QueueCreate. The value range is + * [1,LOSCFG_BASE_IPC_QUEUE_LIMIT]. + * @param bufferAddr [OUT] Starting address that stores the data to be written. The starting address + * must not be null. + * @param bufferSize [IN] This parameter is not in use temporarily. + * @param timeout [IN] Expiry time. The value range is [0,LOS_WAIT_FOREVER](unit: Tick). + * + * @retval #LOS_OK The data is successfully written into the queue. + * @retval #LOS_ERRNO_QUEUE_INVALID The queue handle passed in during queue writing is invalid. + * @retval #LOS_ERRNO_QUEUE_WRITE_PTR_NULL The pointer passed in during queue writing is null. + * @retval #LOS_ERRNO_QUEUE_WRITESIZE_ISZERO The buffer size passed in during queue writing is 0. + * @retval #LOS_ERRNO_QUEUE_WRITE_IN_INTERRUPT The queue cannot be written during an interrupt when the time for + * waiting to processing the queue expires. waiting to processing the queue expires. + * @retval #LOS_ERRNO_QUEUE_NOT_CREATE The queue into which the data is written is not created. + * @retval #LOS_ERRNO_QUEUE_WRITE_SIZE_TOO_BIG The buffer size passed in during queue writing is bigger than + * the queue size. + * @retval #LOS_ERRNO_QUEUE_ISFULL No free node is available during queue writing. + * @retval #LOS_ERRNO_QUEUE_PEND_IN_LOCK The task is forbidden to be blocked on a queue when the task is + * locked. + * @retval #LOS_ERRNO_QUEUE_TIMEOUT The time set for waiting to processing the queue expires. + * @par Dependency: + *
        • los_queue.h: The header file that contains the API declaration.
        + * @see LOS_QueueRead | LOS_QueueCreate + */ +extern UINT32 LOS_QueueWriteHead(UINT32 queueID, + VOID *bufferAddr, + UINT32 bufferSize, + UINT32 timeout); + +/** + * @ingroup los_queue + * @brief Write data into a queue header. + * + * @par Description: + * This API is used to write the data of the size specified by bufferSize and stored at the address specified by + * bufferAddr into a queue header. + * @attention + *
          + *
        • Do not read or write a queue in unblocking modes such as an interrupt.
        • + *
        • This API cannot be called before the Huawei LiteOS is initialized.
        • + *
        • The address of the data of the size specified by bufferSize and stored at the address specified by + * bufferAddr is to be written.
        • + *
        • The argument timeout is a relative time.
        • + *
        • LOS_QueueRead and LOS_QueueWriteHead are a set of interfaces, and the two groups of interfaces need to be + * used.
        • + *
        • Do not call this API in software timer callback.
        • + *
        + * + * @param queueID [IN] Queue ID created by LOS_QueueCreate. The value range is + * [1,LOSCFG_BASE_IPC_QUEUE_LIMIT]. + * @param bufferAddr [OUT] Starting address that stores the data to be written. + * The starting address must not be null. + * @param bufferSize [IN] Passed-in buffer size, which must not be 0. The value range is [1,0xffffffff]. + * @param timeout [IN] Expiry time. The value range is [0,LOS_WAIT_FOREVER](unit: Tick). + * + * @retval #LOS_OK The data is successfully written into the queue. + * @retval #LOS_ERRNO_QUEUE_INVALID The queue handle passed in during queue writing is invalid. + * @retval #LOS_ERRNO_QUEUE_WRITE_PTR_NULL The pointer passed in during queue writing is null. + * @retval #LOS_ERRNO_QUEUE_WRITESIZE_ISZERO The buffer size passed in during queue writing is 0. + * @retval #LOS_ERRNO_QUEUE_WRITE_IN_INTERRUPT The queue cannot be written during an interrupt when the time for + * waiting to processing the queue expires. + * @retval #LOS_ERRNO_QUEUE_NOT_CREATE The queue into which the data is written is not created. + * @retval #LOS_ERRNO_QUEUE_WRITE_SIZE_TOO_BIG The buffer size passed in during queue writing is bigger than + * the queue size. + * @retval #LOS_ERRNO_QUEUE_ISFULL No free node is available during queue writing. + * @retval #LOS_ERRNO_QUEUE_PEND_IN_LOCK The task is forbidden to be blocked on a queue when the task is + * locked. + * @retval #LOS_ERRNO_QUEUE_TIMEOUT The time set for waiting to processing the queue expires. + * @par Dependency: + *
        • los_queue.h: The header file that contains the API declaration.
        + * @see LOS_QueueWrite | LOS_QueueWriteHead + */ +extern UINT32 LOS_QueueWriteHeadCopy(UINT32 queueID, + VOID *bufferAddr, + UINT32 bufferSize, + UINT32 timeout); + +/** + * @ingroup los_queue + * @brief Delete a queue. + * + * @par Description: + * This API is used to delete a queue. + * @attention + *
          + *
        • This API cannot be used to delete a queue that is not created.
        • + *
        • A synchronous queue fails to be deleted if any tasks are blocked on it, or some queues are being read or + * written.
        • + *
        + * + * @param queueID [IN] Queue ID created by LOS_QueueCreate. The value range is + * [1,LOSCFG_BASE_IPC_QUEUE_LIMIT]. + * + * @retval #LOS_OK The queue is successfully deleted. + * @retval #LOS_ERRNO_QUEUE_NOT_FOUND The queue cannot be found. + * @retval #LOS_ERRNO_QUEUE_NOT_CREATE The queue handle passed in when the queue is being deleted is + * incorrect. + * @retval #LOS_ERRNO_QUEUE_IN_TSKUSE The queue that blocks a task cannot be deleted. + * @retval #LOS_ERRNO_QUEUE_IN_TSKWRITE Queue reading and writing are not synchronous. + * @par Dependency: + *
        • los_queue.h: the header file that contains the API declaration.
        + * @see LOS_QueueCreate | LOS_QueueCreate + */ +extern UINT32 LOS_QueueDelete(UINT32 queueID); + +/** + * @ingroup los_queue + * @brief Obtain queue information. + * + * @par Description: + * This API is used to obtain queue information. + * @attention + *
          + *
        • The specific queue should be created firstly.
        • + *
        + * @param queueID [IN] Queue ID created by LOS_QueueCreate. The value range is + * [1,LOSCFG_BASE_IPC_QUEUE_LIMIT]. + * @param queueInfo [OUT] The queue information to be read must not be null. + * + * @retval #LOS_OK The queue information is successfully obtained. + * @retval #LOS_ERRNO_QUEUE_PTR_NULL The pointer to the queue information to be obtained is null. + * @retval #LOS_ERRNO_QUEUE_INVALID The handle of the queue that is being read is invalid. + * @retval #LOS_ERRNO_QUEUE_NOT_CREATE The queue in which the information to be obtained is stored is + * not created. + * + * @par Dependency: + *
        • los_queue.h: the header file that contains the API declaration.
        + * @see LOS_QueueCreate + */ +extern UINT32 LOS_QueueInfoGet(UINT32 queueID, QUEUE_INFO_S *queueInfo); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_QUEUE_H */ diff --git a/src/kernel_liteos_a/kernel/include/los_rwlock.h b/src/kernel_liteos_a/kernel/include/los_rwlock.h new file mode 100644 index 00000000..9a20b8f6 --- /dev/null +++ b/src/kernel_liteos_a/kernel/include/los_rwlock.h @@ -0,0 +1,286 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_rwlock Rwlock + * @ingroup kernel + */ + +#ifndef _LOS_RWLOCK_H +#define _LOS_RWLOCK_H + +#include "los_base.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_rwlock + * Rwlock object. + */ +typedef struct OsRwlock { + INT32 magic : 24; /**< Magic number */ + INT32 rwCount : 8; /**< Times of locking the rwlock, rwCount > 0 when rwkick is read mode, rwCount < 0 + when the rwlock is write mode, rwCount = 0 when the lock is free. */ + VOID *writeOwner; /**< The current write thread that is locking the rwlock */ + LOS_DL_LIST readList; /**< Read waiting list */ + LOS_DL_LIST writeList; /**< Write waiting list */ +} LosRwlock; + +extern BOOL LOS_RwlockIsValid(const LosRwlock *rwlock); + +/** + * @ingroup los_rwlock + * @brief Init a rwlock. + * + * @par Description: + * This API is used to Init a rwlock. A rwlock handle is assigned to rwlockHandle when the rwlock is init successfully. + * Return LOS_OK on creating successful, return specific error code otherwise. + * @param rwlock [IN] Handle pointer of the successfully init rwlock. + * + * @retval #LOS_EINVAL The rwlock pointer is NULL. + * @retval #LOS_EPERM Multiply initialization. + * @retval #LOS_OK The rwlock is successfully created. + * @par Dependency: + *
        • los_rwlock.h: the header file that contains the API declaration.
        + * @see LOS_RwlockDestroy + */ +extern UINT32 LOS_RwlockInit(LosRwlock *rwlock); + +/** + * @ingroup los_rwlock + * @brief Destroy a rwlock. + * + * @par Description: + * This API is used to delete a specified rwlock. Return LOS_OK on deleting successfully, return specific error code + * otherwise. + * @attention + *
          + *
        • The specific rwlock should be created firstly.
        • + *
        • The rwlock can be deleted successfully only if no other tasks pend on it.
        • + *
        + * + * @param rwlock [IN] Handle of the rwlock to be deleted. + * + * @retval #LOS_EINVAL The rwlock pointer is NULL. + * @retval #LOS_EBUSY Tasks pended on this rwlock. + * @retval #LOS_EBADF The lock has been destroyed or broken. + * @retval #LOS_OK The rwlock is successfully deleted. + * @par Dependency: + *
        • los_rwlock.h: the header file that contains the API declaration.
        + * @see LOS_RwlockInit + */ +extern UINT32 LOS_RwlockDestroy(LosRwlock *rwlock); + +/** + * @ingroup los_rwlock + * @brief Wait to lock a read lock. + * + * @par Description: + * This API is used to wait for a specified period of time to lock a read lock. + * @attention + *
          + *
        • The specific rwlock should be created firstly.
        • + *
        • The function fails if the rwlock that is waited on is already locked by another thread when the task scheduling + * is disabled.
        • + *
        • Do not wait on a rwlock during an interrupt.
        • + *
        • The function fails when other tasks have the write lock or there are some task pending on the write list with + * the higher priority.
        • + *
        • A recursive rwlock can be locked more than once by the same thread.
        • + *
        • Do not call this API in software timer callback.
        • + *
        + * + * @param rwlock [IN] Handle of the rwlock to be waited on. + * @param timeout [IN] Waiting time. The value range is [0, LOS_WAIT_FOREVER](unit: Tick). + * + * @retval #LOS_EINVAL The rwlock pointer is NULL, The timeout is zero or Lock status error. + * @retval #LOS_EINTR The rwlock is being locked during an interrupt. + * @retval #LOS_EBADF The lock has been destroyed or broken. + * @retval #LOS_EDEADLK Rwlock error check failed or System locked task scheduling. + * @retval #LOS_ETIMEDOUT The rwlock waiting times out. + * @retval #LOS_EPERM The rwlock is used in system tasks. + * @retval #LOS_OK The rwlock is successfully locked. + * @par Dependency: + *
        • los_rwlock.h: the header file that contains the API declaration.
        + * @see LOS_RwlockInit | LOS_RwlockUnLock + */ +extern UINT32 LOS_RwlockRdLock(LosRwlock *rwlock, UINT32 timeout); + +/** + * @ingroup los_rwlock + * @brief Try wait to lock a read lock. + * + * @par Description: + * This API is used to wait for a specified period of time to lock a read lock. + * @attention + *
          + *
        • The specific rwlock should be created firstly.
        • + *
        • The function fails if the rwlock that is waited on is already locked by another thread when the task scheduling + * is disabled.
        • + *
        • Do not wait on a rwlock during an interrupt.
        • + *
        • The function fails when other tasks have the write lock or there are some task pending on the write list with + * the higher priority.
        • + *
        • A recursive rwlock can be locked more than once by the same thread.
        • + *
        • Do not call this API in software timer callback.
        • + *
        + * + * @param rwlock [IN] Handle of the rwlock to be waited on. + * + * @retval #LOS_EINVAL The rwlock pointer is NULL or Lock status error. + * @retval #LOS_EINTR The rwlock is being locked during an interrupt. + * @retval #LOS_EBUSY Fail to get the rwlock, the rwlock has been used. + * @retval #LOS_EBADF The lock has been destroyed or broken. + * @retval #LOS_EDEADLK rwlock error check failed or System locked task scheduling. + * @retval #LOS_ETIMEDOUT The rwlock waiting times out. + * @retval #LOS_EPERM The rwlock is used in system tasks. + * @retval #LOS_OK The rwlock is successfully locked. + * @par Dependency: + *
        • los_rwlock.h: the header file that contains the API declaration.
        + * @see LOS_RwlockInit | LOS_RwlockUnLock + */ +extern UINT32 LOS_RwlockTryRdLock(LosRwlock *rwlock); + +/** + * @ingroup los_rwlock + * @brief Wait to lock a write lock. + * + * @par Description: + * This API is used to wait for a specified period of time to lock a write lock. + * @attention + *
          + *
        • The specific rwlock should be created firstly.
        • + *
        • The function fails if the rwlock that is waited on is already locked by another thread when + * the task scheduling.
        • + * is disabled. + *
        • Do not wait on a rwlock during an interrupt.
        • + *
        • The function fails when other tasks have the read or write lock.
        • + *
        • A recursive rwlock can be locked more than once by the same thread.
        • + *
        • Do not call this API in software timer callback.
        • + *
        + * + * @param rwlock [IN] Handle of the rwlock to be waited on. + * @param timeout [IN] Waiting time. The value range is [0, LOS_WAIT_FOREVER](unit: Tick). + * + * @retval #LOS_EINVAL The rwlock pointer is NULL, The timeout is zero or Lock status error. + * @retval #LOS_EINTR The rwlock is being locked during an interrupt. + * @retval #LOS_EBADF The lock has been destroyed or broken. + * @retval #LOS_EDEADLK Rwlock error check failed or System locked task scheduling. + * @retval #LOS_ETIMEDOUT The rwlock waiting times out. + * @retval #LOS_EPERM The rwlock is used in system tasks. + * @retval #LOS_OK The rwlock is successfully locked. + * @par Dependency: + *
        • los_rwlock.h: the header file that contains the API declaration.
        + * @see LOS_MuxInit | LOS_MuxUnlock + */ +extern UINT32 LOS_RwlockWrLock(LosRwlock *rwlock, UINT32 timeout); + +/** + * @ingroup los_rwlock + * @brief Try wait to lock a write lock. + * + * @par Description: + * This API is used to wait for a specified period of time to lock a write lock. + * @attention + *
          + *
        • The specific rwlock should be created firstly.
        • + *
        • The function fails if the rwlock that is waited on is already locked by another thread + * when the task scheduling.
        • + * is disabled. + *
        • Do not wait on a rwlock during an interrupt.
        • + *
        • The function fails when other tasks have the read or write lock.
        • + *
        • A recursive rwlock can be locked more than once by the same thread.
        • + *
        • Do not call this API in software timer callback.
        • + *
        + * + * @param rwlock [IN] Handle of the rwlock to be waited on. + * + * @retval #LOS_EINVAL The rwlock pointer is NULL or Lock status error. + * @retval #LOS_EINTR The rwlock is being locked during an interrupt. + * @retval #LOS_EBUSY Fail to get the rwlock, the rwlock has been used. + * @retval #LOS_EBADF The lock has been destroyed or broken. + * @retval #LOS_EDEADLK rwlock error check failed or System locked task scheduling. + * @retval #LOS_ETIMEDOUT The rwlock waiting times out. + * @retval #LOS_EPERM The rwlock is used in system tasks. + * @retval #LOS_OK The rwlock is successfully locked. + * @par Dependency: + *
        • los_rwlock.h: the header file that contains the API declaration.
        + * @see LOS_RwlockInit | LOS_RwlockUnLock + */ +extern UINT32 LOS_RwlockTryWrLock(LosRwlock *rwlock); + +/** + * @ingroup los_rwlock + * @brief Release a rwlock. + * + * @par Description: + * This API is used to release a specified rwlock. + * @attention + *
          + *
        • The specific rwlock should be created firstly.
        • + *
        • Do not release a rwlock during an interrupt.
        • + *
        • When the write list is null and the read list is not null, all the task pending on the read list + * will be waken.
        • + *
        • When the write list is not null and the read list is null, the task pending on the read list will be + * waken by the priority.
        • + *
        • When the write list and the read list are not null, all the task pending on the both list will be waken + * by the priority.
        • + * If the task on the write list has the same priority as the task on the read list, the forth will + * be waken.
        • + *
        • If a recursive rwlock is locked for many times, it must be unlocked for the same times to be + * released.
        • + *
        + * + * @param rwlock [IN] Handle of the rwlock to be released. + * + * @retval #LOS_EINVAL The rwlock pointer is NULL, The timeout is zero or Lock status error. + * @retval #LOS_EINTR The rwlock is being locked during an interrupt. + * @retval #LOS_EPERM The rwlock is not locked or has been used. + * @retval #LOS_EBADF The lock has been destroyed or broken. + * @retval #LOS_EDEADLK rwlock error check failed or System locked task scheduling. + * @retval #LOS_ETIMEDOUT The rwlock waiting times out. + * @retval #LOS_EPERM The rwlock is used in system tasks. + * @retval #LOS_OK The rwlock is successfully locked. + * @par Dependency: + *
        • los_mux.h: the header file that contains the API declaration.
        + * @see LOS_RwlockInit | LOS_ReadLock | LOS_WriteLock + */ +extern UINT32 LOS_RwlockUnLock(LosRwlock *rwlock); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif /* _LOS_MUX_H */ diff --git a/src/kernel_liteos_a/kernel/include/los_sem.h b/src/kernel_liteos_a/kernel/include/los_sem.h new file mode 100644 index 00000000..3f60fb2b --- /dev/null +++ b/src/kernel_liteos_a/kernel/include/los_sem.h @@ -0,0 +1,305 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_sem Semaphore + * @ingroup kernel + */ + +#ifndef _LOS_SEM_H +#define _LOS_SEM_H + +#include "los_base.h" +#include "los_err.h" +#include "los_list.h" +#include "los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_sem + * Semaphore error code: The memory is insufficient. + * + * Value: 0x02000700 + * + * Solution: Allocate more memory. + */ +#define LOS_ERRNO_SEM_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x00) + +/** + * @ingroup los_sem + * Semaphore error code: Invalid parameter. + * + * Value: 0x02000701 + * + * Solution: Change the passed-in invalid parameter value to a valid value. + */ +#define LOS_ERRNO_SEM_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x01) + +/** + * @ingroup los_sem + * Semaphore error code: Null pointer. + * + * Value: 0x02000702 + * + * Solution: Change the passed-in null pointer to a valid non-null pointer. + */ +#define LOS_ERRNO_SEM_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x02) + +/** + * @ingroup los_sem + * Semaphore error code: No semaphore control structure is available. + * + * Value: 0x02000703 + * + * Solution: Perform corresponding operations based on the requirements in the code context. + */ +#define LOS_ERRNO_SEM_ALL_BUSY LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x03) + +/** + * @ingroup los_sem + * Semaphore error code: Invalid parameter that specifies the timeout interval. + * + * Value: 0x02000704 + * + * + * Solution: Change the passed-in parameter value to a valid nonzero value. + */ +#define LOS_ERRNO_SEM_UNAVAILABLE LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x04) + +/** + * @ingroup los_sem + * Semaphore error code: The API is called during an interrupt, which is forbidden. + * + * Value: 0x02000705 + * + * Solution: Do not call the API during an interrupt. + */ +#define LOS_ERRNO_SEM_PEND_INTERR LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x05) + +/** + * @ingroup los_sem + * Semaphore error code: The task is unable to request a semaphore because task scheduling is locked. + * + * Value: 0x02000706 + * + * Solution: Do not call LOS_SemPend when task scheduling is locked. + */ +#define LOS_ERRNO_SEM_PEND_IN_LOCK LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x06) + +/** + * @ingroup los_sem + * Semaphore error code: The request for a semaphore times out. + * + * Value: 0x02000707 + * + * Solution: Change the passed-in parameter value to the value within the valid range. + */ +#define LOS_ERRNO_SEM_TIMEOUT LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x07) + +/** + * @ingroup los_sem + * Semaphore error code: The times of semaphore release exceed the maximum times permitted. + * + * Value: 0x02000708 + * + * Solution: Perform corresponding operations based on the requirements in the code context. + */ +#define LOS_ERRNO_SEM_OVERFLOW LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x08) + +/** + * @ingroup los_sem + * Semaphore error code: The queue of the tasks that are waiting on the semaphore control structure is not null. + * + * Value: 0x02000709 + * + * Solution: Delete the semaphore after awaking all tasks that are waiting on the semaphore. + */ +#define LOS_ERRNO_SEM_PENDED LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x09) + +/** +* @ingroup los_sem +* Semaphore error code: The API is called in system-level callback, which is forbidden. +* old usage: The API is called in software timer callback, which is forbidden. (LOS_ERRNO_SEM_PEND_SWTERR) +* Value: 0x0200070A +* +* Solution: Do not call the API during an interrupt. +*/ +#define LOS_ERRNO_SEM_PEND_IN_SYSTEM_TASK LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x0A) + +/** + * @ingroup los_sem + * Maximum number of binary semaphores. + * + */ +#define OS_SEM_BINARY_COUNT_MAX 1 + +/** + * @ingroup los_sem + * @brief Create a semaphore. + * + * @par Description: + * This API is used to create a semaphore control structure according to the initial number of available semaphores + * specified by count and return the ID of this semaphore control structure. + * @attention + *
          + *
        • None.
        • + *
        + * + * @param count [IN] Initial number of available semaphores. The value range is [0, OS_SEM_COUNT_MAX]. + * @param semHandle [OUT] ID of the semaphore control structure that is initialized. + * + * @retval #LOS_ERRNO_SEM_PTR_NULL The passed-in semHandle value is NULL. + * @retval #LOS_ERRNO_SEM_OVERFLOW The passed-in count value is greater than the maximum number of available + * semaphores. + * @retval #LOS_ERRNO_SEM_ALL_BUSY No semaphore control structure is available. + * @retval #LOS_OK The semaphore is successfully created. + * @par Dependency: + *
        • los_sem.h: the header file that contains the API declaration.
        + * @see LOS_SemDelete + */ +extern UINT32 LOS_SemCreate(UINT16 count, UINT32 *semHandle); + +/** + * @ingroup los_sem + * @brief Create a binary semaphore. + * + * @par Description: + * This API is used to create a binary semaphore control structure according to the initial number of + * available semaphores specified by count and return the ID of this semaphore control structure. + * @attention + *
          + *
        • None.
        • + *
        + * + * @param count [IN] Initial number of available semaphores. The value range is [0, 1]. + * @param semHandle [OUT] ID of the semaphore control structure that is initialized. + * + * @retval #LOS_ERRNO_SEM_PTR_NULL The passed-in semHandle value is NULL. + * @retval #LOS_ERRNO_SEM_OVERFLOW The passed-in count value is greater than the maximum number of + * available semaphores. + * @retval #LOS_ERRNO_SEM_ALL_BUSY No semaphore control structure is available. + * @retval #LOS_OK The semaphore is successfully created. + * @par Dependency: + *
        • los_sem.h: the header file that contains the API declaration.
        + * @see LOS_SemDelete + */ +extern UINT32 LOS_BinarySemCreate(UINT16 count, UINT32 *semHandle); + +/** + * @ingroup los_sem + * @brief Delete a semaphore. + * + * @par Description: + * This API is used to delete a semaphore control structure that has an ID specified by semHandle. + * @attention + *
          + *
        • The specified sem id must be created first.
        • + *
        + * + * @param semHandle [IN] ID of the semaphore control structure to be deleted. The ID of the semaphore + * control structure is obtained from semaphore creation. + * + * @retval #LOS_ERRNO_SEM_INVALID The passed-in semHandle value is invalid. + * @retval #LOS_ERRNO_SEM_PENDED The queue of the tasks that are waiting on the semaphore control structure is + * not null. + * @retval #LOS_OK The semaphore control structure is successfully deleted. + * @par Dependency: + *
        • los_sem.h: the header file that contains the API declaration.
        + * @see LOS_SemCreate + */ +extern UINT32 LOS_SemDelete(UINT32 semHandle); + +/** + * @ingroup los_sem + * @brief Request a semaphore. + * + * @par Description: + * This API is used to request a semaphore based on the semaphore control structure ID specified by semHandle and the + * parameter that specifies the timeout period. + * @attention + *
          + *
        • The specified sem id must be created first.
        • + *
        • Do not call this API in software timer callback.
        • + *
        + * + * @param semHandle [IN] ID of the semaphore control structure to be requested. The ID of the semaphore control + * structure is obtained from semaphore creation. + * @param timeout [IN] Timeout interval for waiting on the semaphore. The value range is [0, 0xFFFFFFFF]. + * If the value is set to 0, the semaphore is not waited on. If the value is set to 0xFFFFFFFF, + * the semaphore is waited on forever(unit: Tick). + * + * @retval #LOS_ERRNO_SEM_INVALID The passed-in semHandle value is invalid. + * @retval #LOS_ERRNO_SEM_UNAVAILABLE There is no available semaphore resource. + * @retval #LOS_ERRNO_SEM_PEND_INTERR The API is called during an interrupt, which is forbidden. + * @retval #LOS_ERRNO_SEM_PEND_IN_LOCK The task is unable to request a semaphore because task scheduling is locked. + * @retval #LOS_ERRNO_SEM_TIMEOUT The request for the semaphore times out. + * @retval #LOS_OK The semaphore request succeeds. + * @par Dependency: + *
        • los_sem.h: the header file that contains the API declaration.
        + * @see LOS_SemPost | LOS_SemCreate + */ +extern UINT32 LOS_SemPend(UINT32 semHandle, UINT32 timeout); + +/** + * @ingroup los_sem + * @brief Release a semaphore. + * + * @par Description: + * This API is used to release a semaphore that has a semaphore control structure ID specified by semHandle. + * @attention + *
          + *
        • The specified sem id must be created first.
        • + *
        + * + * @param semHandle [IN] ID of the semaphore control structure to be released.The ID of the semaphore control + * structure is obtained from semaphore creation. + * + * @retval #LOS_ERRNO_SEM_INVALID The passed-in semHandle value is invalid. + * @retval #LOS_ERRNO_SEM_OVERFLOW The times of semaphore release exceed the maximum times permitted. + * @retval #LOS_OK The semaphore is successfully released. + * @par Dependency: + *
        • los_sem.h: the header file that contains the API declaration.
        + * @see LOS_SemPend | LOS_SemCreate + */ +extern UINT32 LOS_SemPost(UINT32 semHandle); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_SEM_H */ diff --git a/src/kernel_liteos_a/kernel/include/los_smp.h b/src/kernel_liteos_a/kernel/include/los_smp.h new file mode 100644 index 00000000..6d3946cb --- /dev/null +++ b/src/kernel_liteos_a/kernel/include/los_smp.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_SMP_H +#define _LOS_SMP_H + +#include "smp.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +VOID LOS_SmpOpsSet(struct SmpOps *ops); +VOID OsSmpInit(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_SMP_H */ + diff --git a/src/kernel_liteos_a/kernel/include/los_spinlock.h b/src/kernel_liteos_a/kernel/include/los_spinlock.h new file mode 100644 index 00000000..e3af5922 --- /dev/null +++ b/src/kernel_liteos_a/kernel/include/los_spinlock.h @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_SPINLOCK_H +#define _LOS_SPINLOCK_H +#include "los_typedef.h" +#include "los_config.h" +#include "los_hwi.h" +#include "los_task.h" +#include "los_lockdep.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +extern VOID ArchSpinLock(size_t *lock); +extern VOID ArchSpinUnlock(size_t *lock); +extern INT32 ArchSpinTrylock(size_t *lock); + +typedef struct Spinlock { + size_t rawLock; +#ifdef LOSCFG_KERNEL_SMP + UINT32 cpuid; + VOID *owner; + const CHAR *name; +#endif +} SPIN_LOCK_S; + +#ifdef LOSCFG_KERNEL_SMP_LOCKDEP +#define LOCKDEP_CHECK_IN(lock) OsLockDepCheckIn(lock) +#define LOCKDEP_RECORD(lock) OsLockDepRecord(lock) +#define LOCKDEP_CHECK_OUT(lock) OsLockDepCheckOut(lock) +#define LOCKDEP_CLEAR_LOCKS() OsLockdepClearSpinlocks() +#else +#define LOCKDEP_CHECK_IN(lock) +#define LOCKDEP_RECORD(lock) +#define LOCKDEP_CHECK_OUT(lock) +#define LOCKDEP_CLEAR_LOCKS() +#endif + +#ifdef LOSCFG_KERNEL_SMP +#define SPINLOCK_OWNER_INIT NULL + +#define SPIN_LOCK_INITIALIZER(lockName) \ +{ \ + .rawLock = 0U, \ + .cpuid = (UINT32)(-1), \ + .owner = SPINLOCK_OWNER_INIT, \ + .name = #lockName, \ +} + +/** + * @ingroup los_spinlock + * @brief Lock the spinlock. + * + * @par Description: + * This API is used to lock the spin lock. + * + * @attention None. + * + * @param lock [IN] Type #SPIN_LOCK_S spinlock pointer. + * + * @retval None. + * @par Dependency: + *
        • los_spinlock.h: the header file that contains the API declaration.
        + * @see LOS_SpinUnlock + */ +extern VOID LOS_SpinLock(SPIN_LOCK_S *lock); + +/** + * @ingroup los_spinlock + * @brief Trying lock the spinlock. + * + * @par Description: + * This API is used to trying lock the spin lock. + * + * @attention None. + * + * @param lock [IN] Type #SPIN_LOCK_S spinlock pointer. + * + * @retval LOS_OK Got the spinlock. + * @retval LOS_NOK Not getting the spinlock. + * @par Dependency: + *
        • los_spinlock.h: the header file that contains the API declaration.
        + * @see LOS_SpinLock + */ +extern INT32 LOS_SpinTrylock(SPIN_LOCK_S *lock); + +/** + * @ingroup los_spinlock + * @brief Unlock the spinlock. + * + * @par Description: + * This API is used to unlock the spin lock. + * + * @attention None. + * + * @param lock [IN] Type #SPIN_LOCK_S spinlock pointer. + * + * @retval None. + * @par Dependency: + *
        • los_spinlock.h: the header file that contains the API declaration.
        + * @see LOS_SpinLock + */ +extern VOID LOS_SpinUnlock(SPIN_LOCK_S *lock); + +/** + * @ingroup los_spinlock + * @brief Lock the spinlock and disable all interrupts. + * + * @par Description: + * This API is used to lock the spin lock and disable all interrupts. + * + * @attention None. + * + * @param lock [IN] Type #SPIN_LOCK_S spinlock pointer. + * @param intSave [OUT] Type #UINT32 Saved interrupt flag for latter restored. + * + * @retval None. + * @par Dependency: + *
        • los_spinlock.h: the header file that contains the API declaration.
        + * @see LOS_SpinLock + */ +extern VOID LOS_SpinLockSave(SPIN_LOCK_S *lock, UINT32 *intSave); + +/** + * @ingroup los_spinlock + * @brief Unlock the spinlock and restore interrupt flag. + * + * @par Description: + * This API is used to unlock the spin lock and restore interrupt flag. + * + * @attention None. + * + * @param lock [IN] Type #SPIN_LOCK_S spinlock pointer. + * @param intSave [IN] Type #UINT32 Interrupt flag to be restored. + * + * @retval None. + * @par Dependency: + *
        • los_spinlock.h: the header file that contains the API declaration.
        + * @see LOS_SpinUnlock + */ +extern VOID LOS_SpinUnlockRestore(SPIN_LOCK_S *lock, UINT32 intSave); + +/** + * @ingroup los_spinlock + * @brief Check if holding the spinlock. + * + * @par Description: + * This API is used to check if holding the spinlock. + * + * @attention None. + * + * @param lock [IN] Type #SPIN_LOCK_S spinlock pointer. + * + * @retval TRUE Holding the spinlock. + * @retval FALSE Not Holding the spinlock. + * @par Dependency: + *
        • los_spinlock.h: the header file that contains the API declaration.
        + */ +extern BOOL LOS_SpinHeld(const SPIN_LOCK_S *lock); + +/** + * @ingroup los_spinlock + * @brief Spinlock initialization. + * + * @par Description: + * This API is used to initialize a spinlock. + * + * @attention None. + * + * @param lock [IN] Type #SPIN_LOCK_S spinlock pointer. + * + * @retval None. + * + * @par Dependency: + *
        • los_spinlock.h: the header file that contains the API declaration.
        + */ +extern VOID LOS_SpinInit(SPIN_LOCK_S *lock); + +#else +#define SPIN_LOCK_INITIALIZER(lockName) \ +{ \ + .rawLock = 0U, \ +} + +/* + * For Non-SMP system, these apis does not handle with spinlocks, + * but for unifying the code of drivers, vendors and etc. + */ +LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_SpinLock(SPIN_LOCK_S *lock) +{ + (VOID)lock; +} + +LITE_OS_SEC_ALW_INLINE STATIC INLINE INT32 LOS_SpinTrylock(SPIN_LOCK_S *lock) +{ + (VOID)lock; + return LOS_OK; +} + +LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_SpinUnlock(SPIN_LOCK_S *lock) +{ + (VOID)lock; +} + +LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_SpinLockSave(SPIN_LOCK_S *lock, UINT32 *intSave) +{ + (VOID)lock; + *intSave = LOS_IntLock(); +} + +LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_SpinUnlockRestore(SPIN_LOCK_S *lock, UINT32 intSave) +{ + (VOID)lock; + LOS_IntRestore(intSave); +} + +LITE_OS_SEC_ALW_INLINE STATIC INLINE BOOL LOS_SpinHeld(const SPIN_LOCK_S *lock) +{ + (VOID)lock; + return TRUE; +} + +LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_SpinInit(SPIN_LOCK_S *lock) +{ + (VOID)lock; +} + +#endif + +#define SPIN_LOCK_INIT(lock) SPIN_LOCK_S lock = SPIN_LOCK_INITIALIZER(lock) + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/src/kernel_liteos_a/kernel/include/los_swtmr.h b/src/kernel_liteos_a/kernel/include/los_swtmr.h new file mode 100644 index 00000000..c846ed62 --- /dev/null +++ b/src/kernel_liteos_a/kernel/include/los_swtmr.h @@ -0,0 +1,423 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_swtmr Software timer + * @ingroup kernel + */ + +#ifndef _LOS_SWTMR_H +#define _LOS_SWTMR_H + +#include "los_base.h" +#include "los_task.h" +#include "los_sortlink_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_swtmr + * Software timer error code: The timeout handling function is NULL. + * + * Value: 0x02000300 + * + * Solution: Define the timeout handling function. + */ +#define LOS_ERRNO_SWTMR_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x00) + +/** + * @ingroup los_swtmr + * Software timer error code: The expiration time is 0. + * + * Value: 0x02000301 + * + * Solution: Re-define the expiration time. + */ +#define LOS_ERRNO_SWTMR_INTERVAL_NOT_SUITED LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x01) + +/** + * @ingroup los_swtmr + * Software timer error code: Invalid software timer mode. + * + * Value: 0x02000302 + * + * Solution: Check the mode value. The value range is [0,3]. + */ +#define LOS_ERRNO_SWTMR_MODE_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x02) + +/** + * @ingroup los_swtmr + * Software timer error code: The passed-in software timer ID is NULL. + * + * Value: 0x02000303 + * + * Solution: Define the software timer ID before passing it in. + */ +#define LOS_ERRNO_SWTMR_RET_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x03) + +/** + * @ingroup los_swtmr + * Software timer error code: The number of software timers exceeds the configured permitted maximum number. + * + * Value: 0x02000304 + * + * Solution: Re-configure the permitted maximum number of software timers, or wait for a software timer to become + * available. + */ +#define LOS_ERRNO_SWTMR_MAXSIZE LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x04) + +/** + * @ingroup los_swtmr + * Software timer error code: Invalid software timer ID. + * + * Value: 0x02000305 + * + * Solution: Pass in a valid software timer ID. + */ +#define LOS_ERRNO_SWTMR_ID_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x05) + +/** + * @ingroup los_swtmr + * Software timer error code: The software timer is not created. + * + * Value: 0x02000306 + * + * Solution: Create a software timer. + */ +#define LOS_ERRNO_SWTMR_NOT_CREATED LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x06) + +/** + * @ingroup los_swtmr + * Software timer error code: Insufficient memory for software timer linked list creation. + * + * Value: 0x02000307 + * + * Solution: Allocate bigger memory partition to software timer linked list creation. + */ +#define LOS_ERRNO_SWTMR_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x07) + +/** + * @ingroup los_swtmr + * Software timer error code: Invalid configured number of software timers. + * + * Value: 0x02000308 + * + * Solution: Re-configure the number of software timers. + */ +#define LOS_ERRNO_SWTMR_MAXSIZE_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x08) + +/** + * @ingroup los_swtmr + * Software timer error code: The software timer is being used during an interrupt. + * + * Value: 0x02000309 + * + * Solution: Change the source code and do not use the software timer during an interrupt. + */ +#define LOS_ERRNO_SWTMR_HWI_ACTIVE LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x09) + +/** + * @ingroup los_swtmr + * Software timer error code: Insufficient memory allocated by membox. + * + * Value: 0x0200030a + * + * Solution: Expand the memory allocated by membox. + */ +#define LOS_ERRNO_SWTMR_HANDLER_POOL_NO_MEM LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x0a) + +/** + * @ingroup los_swtmr + * Software timer error code: The software timer queue fails to be created. + * + * Value: 0x0200030b + * + * Solution: Check whether more memory can be allocated to the queue to be created. + */ +#define LOS_ERRNO_SWTMR_QUEUE_CREATE_FAILED LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x0b) + +/** + * @ingroup los_swtmr + * Software timer error code: The software timer task fails to be created. + * + * Value: 0x0200030c + * + * Solution: Check whether the memory is sufficient and re-create the task. + */ +#define LOS_ERRNO_SWTMR_TASK_CREATE_FAILED LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x0c) + +/** + * @ingroup los_swtmr + * Software timer error code: The software timer is not started. + * + * Value: 0x0200030d + * + * Solution: Start the software timer. + */ +#define LOS_ERRNO_SWTMR_NOT_STARTED LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x0d) + +/** + * @ingroup los_swtmr + * Software timer error code: Invalid software timer state. + * + * Value: 0x0200030e + * + * Solution: Check the software timer state. + */ +#define LOS_ERRNO_SWTMR_STATUS_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x0e) + +/** + * @ingroup los_swtmr + * This error code is not in use temporarily. + */ +#define LOS_ERRNO_SWTMR_SORTLIST_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x0f) + +/** + * @ingroup los_swtmr + * Software timer error code: The passed-in number of remaining Ticks configured on the software timer is NULL. + * + * Value: 0x02000310 + * + * Solution: Define a variable of the number of remaining Ticks before passing in the number of remaining Ticks. + */ +#define LOS_ERRNO_SWTMR_TICK_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x10) + +/** + * @ingroup los_swtmr + * Software timer error code: The software sortlink fails to be created. + * + * Value: 0x02000311 + * + * Solution: Check whether the memory is sufficient and re-create the sortlink. + */ +#define LOS_ERRNO_SWTMR_SORTLINK_CREATE_FAILED LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x11) + +/** + * @ingroup los_swtmr + * Software timer mode + */ +enum enSwTmrType { + LOS_SWTMR_MODE_ONCE, /**< One-off software timer */ + LOS_SWTMR_MODE_PERIOD, /**< Periodic software timer */ + LOS_SWTMR_MODE_NO_SELFDELETE, /**< One-off software timer, but not self-delete */ + LOS_SWTMR_MODE_OPP /**< After the one-off timer finishes timing, + the periodic software timer is enabled. + This mode is not supported temporarily. */ +}; + +/** +* @ingroup los_swtmr +* @brief Define the type of a callback function that handles software timer timeout. +* +* @par Description: +* This API is used to define the type of a callback function that handles software timer timeout, so that it can be +* called when software timer timeout. +* +* @attention +*
          +*
        • None.
        • +*
        +* +* @param arg [IN] the parameter of the callback function that handles software timer timeout. +* +* @retval None. +* @par Dependency: +*
        • los_swtmr.h: the header file that contains the API declaration.
        +* @see None. +*/ +typedef VOID (*SWTMR_PROC_FUNC)(UINTPTR arg); + +/** + * @ingroup los_swtmr + * Software timer control structure + */ +typedef struct tagSwTmrCtrl { + SortLinkList stSortList; + UINT8 ucState; /**< Software timer state */ + UINT8 ucMode; /**< Software timer mode */ + UINT16 usTimerID; /**< Software timer ID */ + UINT32 uwOverrun; /**< Times that a software timer repeats timing */ + UINT32 uwCount; /**< Times that a software timer works */ + UINT32 uwInterval; /**< Timeout interval of a periodic software timer */ + UINT32 uwExpiry; /**< Timeout interval of an one-off software timer */ + UINTPTR uwArg; /**< Parameter passed in when the callback function + that handles software timer timeout is called */ + SWTMR_PROC_FUNC pfnHandler; /**< Callback function that handles software timer timeout */ + UINTPTR uwOwnerPid; /** Owner of this software timer */ + UINT64 startTime; /**< Software timer start time */ +} SWTMR_CTRL_S; + +/** + * @ingroup los_swtmr + * @brief Start a software timer. + * + * @par Description: + * This API is used to start a software timer that has a specified ID. + * @attention + *
          + *
        • The specific timer must be created first
        • + *
        + * + * @param swtmrID [IN] Software timer ID created by LOS_SwtmrCreate. The value of ID should be in + * [0, LOSCFG_BASE_CORE_SWTMR_LIMIT - 1]. + * + * @retval #LOS_ERRNO_SWTMR_ID_INVALID Invalid software timer ID. + * @retval #LOS_ERRNO_SWTMR_NOT_CREATED The software timer is not created. + * @retval #LOS_ERRNO_SWTMR_STATUS_INVALID Invalid software timer state. + * @retval #LOS_OK The software timer is successfully started. + * @par Dependency: + *
        • los_swtmr.h: the header file that contains the API declaration.
        + * @see LOS_SwtmrStop | LOS_SwtmrCreate + */ +extern UINT32 LOS_SwtmrStart(UINT16 swtmrID); + +/** + * @ingroup los_swtmr + * @brief Stop a software timer. + * + * @par Description: + * This API is used to stop a software timer that has a specified ID. + * @attention + *
          + *
        • The specific timer should be created and started firstly.
        • + *
        + * + * @param swtmrID [IN] Software timer ID created by LOS_SwtmrCreate. The value of ID should be in + * [0, LOSCFG_BASE_CORE_SWTMR_LIMIT - 1]. + * + * @retval #LOS_ERRNO_SWTMR_ID_INVALID Invalid software timer ID. + * @retval #LOS_ERRNO_SWTMR_NOT_CREATED The software timer is not created. + * @retval #LOS_ERRNO_SWTMR_NOT_STARTED The software timer is not started. + * @retval #LOS_ERRNO_SWTMR_STATUS_INVALID Invalid software timer state. + * @retval #LOS_OK The software timer is successfully stopped. + * @par Dependency: + *
        • los_swtmr.h: the header file that contains the API declaration.
        + * @see LOS_SwtmrStart | LOS_SwtmrCreate + */ +extern UINT32 LOS_SwtmrStop(UINT16 swtmrID); + +/** + * @ingroup los_swtmr + * @brief Obtain the number of remaining Ticks configured on a software timer. + * + * @par Description: + * This API is used to obtain the number of remaining Ticks configured on the software timer of which the ID is + * specified by usSwTmrID. + * @attention + *
          + *
        • The specific timer should be created and started successfully, error happeneds otherwise.
        • + *
        + * + * @param swtmrID [IN] Software timer ID created by LOS_SwtmrCreate. The value of ID should be in + * [0, LOSCFG_BASE_CORE_SWTMR_LIMIT - 1]. + * @param tick [OUT] Number of remaining Ticks configured on the software timer. + * + * @retval #LOS_ERRNO_SWTMR_ID_INVALID Invalid software timer ID. + * @retval #LOS_ERRNO_SWTMR_NOT_CREATED The software timer is not created. + * @retval #LOS_ERRNO_SWTMR_NOT_STARTED The software timer is not started. + * @retval #LOS_ERRNO_SWTMR_STATUS_INVALID Invalid software timer state. + * @retval #LOS_OK The number of remaining Ticks is successfully obtained. + * @par Dependency: + *
        • los_swtmr.h: the header file that contains the API declaration.
        + * @see LOS_SwtmrCreate + */ +extern UINT32 LOS_SwtmrTimeGet(UINT16 swtmrID, UINT32 *tick); + +/** + * @ingroup los_swtmr + * @brief Create a software timer. + * + * @par Description: + * This API is used to create a software timer that has specified timing duration, timeout handling function, + * and trigger mode, and to return a handle by which the software timer can be referenced. + * @attention + *
          + *
        • Do not use the delay interface in the callback function that handles software timer timeout.
        • + *
        • There are LOSCFG_BASE_CORE_SWTMR_LIMIT timers available, change it's value when necessary.
        • + *
        + * + * @param interval [IN] Timing duration of the software timer to be created (unit: tick). + * @param mode [IN] Software timer mode. Pass in one of the modes specified by enSwTmrType. There are three + * types of modes, one-off, periodic, and continuously periodic after one-off, of which the third mode is not + * supported temporarily. + * @param handler [IN] Callback function that handles software timer timeout. + * @param swtmrID [OUT] Software timer ID created by LOS_SwtmrCreate. + * @param arg [IN] Parameter passed in when the callback function that handles software timer timeout is + * called. + * + * @retval #LOS_ERRNO_SWTMR_INTERVAL_NOT_SUITED The software timer timeout interval is 0. + * @retval #LOS_ERRNO_SWTMR_MODE_INVALID Invalid software timer mode. + * @retval #LOS_ERRNO_SWTMR_PTR_NULL The callback function that handles software timer timeout is NULL. + * @retval #LOS_ERRNO_SWTMR_RET_PTR_NULL The passed-in software timer ID is NULL. + * @retval #LOS_ERRNO_SWTMR_MAXSIZE The number of software timers exceeds the configured permitted + * maximum number. + * @retval #LOS_OK The software timer is successfully created. + * @par Dependency: + *
        • los_swtmr.h: the header file that contains the API declaration.
        + * @see LOS_SwtmrDelete + */ +extern UINT32 LOS_SwtmrCreate(UINT32 interval, UINT8 mode, SWTMR_PROC_FUNC handler, UINT16 *swtmrID, UINTPTR arg); + +/** + * @ingroup los_swtmr + * @brief Delete a software timer. + * + * @par Description: + * This API is used to delete a software timer. + * @attention + *
          + *
        • The specific timer should be created and then stopped firstly.
        • + *
        + * + * @param swtmrID [IN] Software timer ID created by LOS_SwtmrCreate. The value of ID should be in + * [0, LOSCFG_BASE_CORE_SWTMR_LIMIT - 1]. + * + * @retval #LOS_ERRNO_SWTMR_ID_INVALID Invalid software timer ID. + * @retval #LOS_ERRNO_SWTMR_NOT_CREATED The software timer is not created. + * @retval #LOS_ERRNO_SWTMR_STATUS_INVALID Invalid software timer state. + * @retval #LOS_OK The software timer is successfully deleted. + * @par Dependency: + *
        • los_swtmr.h: the header file that contains the API declaration.
        + * @see LOS_SwtmrCreate + */ +extern UINT32 LOS_SwtmrDelete(UINT16 swtmrID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_SWTMR_H */ diff --git a/src/kernel_liteos_a/kernel/include/los_sys.h b/src/kernel_liteos_a/kernel/include/los_sys.h new file mode 100644 index 00000000..26475697 --- /dev/null +++ b/src/kernel_liteos_a/kernel/include/los_sys.h @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_sys System time + * @ingroup kernel + */ + +#ifndef _LOS_SYS_H +#define _LOS_SYS_H + +#include "los_base.h" +#include "los_hwi.h" +#include "los_hw.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_sys + * System time basic function error code: Null pointer. + * + * Value: 0x02000010 + * + * Solution: Check whether the input parameter is null. + */ +#define LOS_ERRNO_SYS_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_SYS, 0x10) + +/** + * @ingroup los_sys + * System time basic function error code: Invalid system clock configuration. + * + * Value: 0x02000011 + * + * Solution: Configure a valid system clock in los_config.h. + */ +#define LOS_ERRNO_SYS_CLOCK_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SYS, 0x11) + +/** + * @ingroup los_sys + * System time basic function error code: This error code is not in use temporarily. + * + * Value: 0x02000012 + * + * Solution: None. + */ +#define LOS_ERRNO_SYS_MAXNUMOFCORES_IS_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SYS, 0x12) + +/** + * @ingroup los_sys + * System time error code: This error code is not in use temporarily. + * + * Value: 0x02000013 + * + * Solution: None. + */ +#define LOS_ERRNO_SYS_PERIERRCOREID_IS_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SYS, 0x13) + +/** + * @ingroup los_sys + * System time error code: This error code is not in use temporarily. + * + * Value: 0x02000014 + * + * Solution: None. + */ +#define LOS_ERRNO_SYS_HOOK_IS_FULL LOS_ERRNO_OS_ERROR(LOS_MOD_SYS, 0x14) + +/** + * @ingroup los_typedef + * system time structure. + */ +typedef struct tagSysTime { + UINT16 uwYear; /**< value 1970 ~ 2038 or 1970 ~ 2100 */ + UINT8 ucMonth; /**< value 1 - 12 */ + UINT8 ucDay; /**< value 1 - 31 */ + UINT8 ucHour; /**< value 0 - 23 */ + UINT8 ucMinute; /**< value 0 - 59 */ + UINT8 ucSecond; /**< value 0 - 59 */ + UINT8 ucWeek; /**< value 0 - 6 */ +} SYS_TIME_S; + +/** + * @ingroup los_sys + * @brief Obtain the number of Ticks. + * + * @par Description: + * This API is used to obtain the number of Ticks. + * @attention + *
          + *
        • None
        • + *
        + * + * @param None + * + * @retval UINT64 The number of Ticks. + * @par Dependency: + *
        • los_sys.h: the header file that contains the API declaration.
        + * @see None + */ +extern UINT64 LOS_TickCountGet(VOID); + +/** + * @ingroup los_sys + * @brief Obtain the number of cycles in one second. + * + * @par Description: + * This API is used to obtain the number of cycles in one second. + * @attention + *
          + *
        • None
        • + *
        + * + * @param None + * + * @retval UINT32 Number of cycles obtained in one second. + * @par Dependency: + *
        • los_sys.h: the header file that contains the API declaration.
        + * @see None + */ +extern UINT32 LOS_CyclePerTickGet(VOID); + +/** + * @ingroup los_sys + * @brief Convert Ticks to milliseconds. + * + * @par Description: + * This API is used to convert Ticks to milliseconds. + * @attention + *
          + *
        • The number of milliseconds obtained through the conversion is 32-bit.
        • + *
        + * + * @param tick [IN] Number of Ticks. The value range is (0,OS_SYS_CLOCK). + * + * @retval UINT32 Number of milliseconds obtained through the conversion. Ticks are successfully converted to + * milliseconds. + * @par Dependency: + *
        • los_sys.h: the header file that contains the API declaration.
        + * @see LOS_MS2Tick + */ +extern UINT32 LOS_Tick2MS(UINT32 tick); + +/** + * @ingroup los_sys + * @brief Convert milliseconds to Ticks. + * + * @par Description: + * This API is used to convert milliseconds to Ticks. + * @attention + *
          + *
        • If the parameter passed in is equal to 0xFFFFFFFF, the retval is 0xFFFFFFFF. Pay attention to the value to be + * converted because data possibly overflows.
        • + *
        + * + * @param millisec [IN] Number of milliseconds. + * + * @retval UINT32 Number of Ticks obtained through the conversion. + * @par Dependency: + *
        • los_sys.h: the header file that contains the API declaration.
        + * @see LOS_Tick2MS + */ +extern UINT32 LOS_MS2Tick(UINT32 millisec); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_SYS_H */ diff --git a/src/kernel_liteos_a/kernel/include/los_tables.h b/src/kernel_liteos_a/kernel/include/los_tables.h new file mode 100644 index 00000000..5b67ac88 --- /dev/null +++ b/src/kernel_liteos_a/kernel/include/los_tables.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_TABLES_H +#define _LOS_TABLES_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#ifndef LOS_HAL_TABLE_BEGIN +#define LOS_HAL_TABLE_BEGIN(label, name) \ + __asm__(".section \".liteos.table." X_STRING(name) ".begin\",\"aw\"\n" \ + ".globl " X_STRING(LOS_LABEL_DEFN(label)) "\n" \ + ".type " X_STRING(LOS_LABEL_DEFN(label)) ",object\n" \ + ".p2align " X_STRING(LOSARC_P2ALIGNMENT) "\n" \ + X_STRING(LOS_LABEL_DEFN(label)) ":\n" \ + ".previous\n" \ + ) +#endif + +#ifndef LOS_HAL_TABLE_END +#define LOS_HAL_TABLE_END(label, name) \ + __asm__(".section \".liteos.table." X_STRING(name) ".finish\",\"aw\"\n" \ + ".globl " X_STRING(LOS_LABEL_DEFN(label)) "\n" \ + ".type " X_STRING(LOS_LABEL_DEFN(label)) ",object\n" \ + ".p2align " X_STRING(LOSARC_P2ALIGNMENT) "\n" \ + X_STRING(LOS_LABEL_DEFN(label)) ":\n" \ + ".previous\n" \ + ) +#endif + +/* This macro must be applied to any types whose objects are to be placed in tables */ +#ifndef LOS_HAL_TABLE_TYPE +#define LOS_HAL_TABLE_TYPE LOSBLD_ATTRIB_ALIGN(LOSARC_ALIGNMENT) +#endif + +#ifndef LOS_HAL_TABLE_EXTRA +#define LOS_HAL_TABLE_EXTRA(name) \ + LOSBLD_ATTRIB_SECTION(".liteos.table." X_STRING(name) ".extra") +#endif + +#ifndef LOS_HAL_TABLE_ENTRY +#define LOS_HAL_TABLE_ENTRY(name) \ + LOSBLD_ATTRIB_SECTION(".liteos.table." X_STRING(name) ".data") \ + LOSBLD_ATTRIB_USED +#endif + +#ifndef LOS_HAL_TABLE_QUALIFIED_ENTRY +#define LOS_HAL_TABLE_QUALIFIED_ENTRY(name, _qual) \ + LOSBLD_ATTRIB_SECTION(".liteos.table." X_STRING(name) ".data." X_STRING(_qual)) \ + LOSBLD_ATTRIB_USED +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_TABLES_H */ diff --git a/src/kernel_liteos_a/kernel/include/los_task.h b/src/kernel_liteos_a/kernel/include/los_task.h new file mode 100644 index 00000000..73c40eb3 --- /dev/null +++ b/src/kernel_liteos_a/kernel/include/los_task.h @@ -0,0 +1,1138 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_task Task + * @ingroup kernel + */ + +#ifndef _LOS_TASK_H +#define _LOS_TASK_H + +#include "los_base.h" +#include "los_list.h" +#include "los_sys.h" +#include "los_tick.h" +#include "los_event.h" +#include "los_memory.h" +#include "los_err.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define CPUID_TO_AFFI_MASK(cpuid) (0x1u << (cpuid)) + +/** + * @ingroup los_task + * Flag that indicates the task or task control block status. + * + * The task is automatically deleted. + */ +#define LOS_TASK_STATUS_DETACHED 0x0U + +/** + * @ingroup los_task + * Flag that indicates the task or task control block status. + * + * The task is joinable. + */ +#define LOS_TASK_ATTR_JOINABLE 0x80000000 + +/** + * @ingroup los_task + * Task error code: Insufficient memory for task creation. + * + * Value: 0x03000200 + * + * Solution: Allocate bigger memory partition to task creation. + */ +#define LOS_ERRNO_TSK_NO_MEMORY LOS_ERRNO_OS_FATAL(LOS_MOD_TSK, 0x00) + +/** + * @ingroup los_task + * Task error code: Null parameter. + * + * Value: 0x02000201 + * + * Solution: Check the parameter. + */ +#define LOS_ERRNO_TSK_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x01) + +/** + * @ingroup los_task + * Task error code: The task stack is not aligned. + * + * Value: 0x02000202 + * + * Solution: Align the task stack. + */ +#define LOS_ERRNO_TSK_STKSZ_NOT_ALIGN LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x02) + +/** + * @ingroup los_task + * Task error code: Incorrect task priority. + * + * Value: 0x02000203 + * + * Solution: Re-configure the task priority by referring to the priority range. + */ +#define LOS_ERRNO_TSK_PRIOR_ERROR LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x03) + +/** + * @ingroup los_task + * Task error code: The task entrance is NULL. + * + * Value: 0x02000204 + * + * Solution: Define the task entrance function. + */ +#define LOS_ERRNO_TSK_ENTRY_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x04) + +/** + * @ingroup los_task + * Task error code: The task name is NULL. + * + * Value: 0x02000205 + * + * Solution: Set the task name. + */ +#define LOS_ERRNO_TSK_NAME_EMPTY LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x05) + +/** + * @ingroup los_task + * Task error code: The task stack size is too small. + * + * Value: 0x02000206 + * + * Solution: Expand the task stack. + */ +#define LOS_ERRNO_TSK_STKSZ_TOO_SMALL LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x06) + +/** + * @ingroup los_task + * Task error code: Invalid task ID. + * + * Value: 0x02000207 + * + * Solution: Check the task ID. + */ +#define LOS_ERRNO_TSK_ID_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x07) + +/** + * @ingroup los_task + * Task error code: The task is already suspended. + * + * Value: 0x02000208 + * + * Solution: Suspend the task after it is resumed. + */ +#define LOS_ERRNO_TSK_ALREADY_SUSPENDED LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x08) + +/** + * @ingroup los_task + * Task error code: The task is not suspended. + * + * Value: 0x02000209 + * + * Solution: Suspend the task. + */ +#define LOS_ERRNO_TSK_NOT_SUSPENDED LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x09) + +/** + * @ingroup los_task + * Task error code: The task is not created. + * + * Value: 0x0200020a + * + * Solution: Create the task. + */ +#define LOS_ERRNO_TSK_NOT_CREATED LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x0a) + +/** + * @ingroup los_task + * Task error code: The task is locked when it is being deleted. + * + * Value: 0x0300020b + * + * Solution: Unlock the task. + */ +#define LOS_ERRNO_TSK_DELETE_LOCKED LOS_ERRNO_OS_FATAL(LOS_MOD_TSK, 0x0b) + +/** + * @ingroup los_task + * Task error code: The task message is nonzero. + * + * Value: 0x0200020c + * + * Solution: This error code is not in use temporarily. + */ +#define LOS_ERRNO_TSK_MSG_NONZERO LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x0c) + +/** + * @ingroup los_task + * Task error code: The task delay occurs during an interrupt. + * + * Value: 0x0300020d + * + * Solution: Perform this operation after exiting from the interrupt. + */ +#define LOS_ERRNO_TSK_DELAY_IN_INT LOS_ERRNO_OS_FATAL(LOS_MOD_TSK, 0x0d) + +/** + * @ingroup los_task + * Task error code: The task delay occurs when the task is locked. + * + * Value: 0x0200020e + * + * Solution: Perform this operation after unlocking the task. + */ +#define LOS_ERRNO_TSK_DELAY_IN_LOCK LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x0e) + +/** + * @ingroup los_task + * Task error code: The task yield occurs when the task is locked. + * Value: 0x0200020f + * + * Solution: Check the task. + */ +#define LOS_ERRNO_TSK_YIELD_IN_LOCK LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x0f) + +/** + * @ingroup los_task + * Task error code: Only one task or no task is available for scheduling. + * + * Value: 0x02000210 + * + * Solution: Increase the number of tasks. + */ +#define LOS_ERRNO_TSK_YIELD_NOT_ENOUGH_TASK LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x10) + +/** + * @ingroup los_task + * Task error code: No free task control block is available. + * + * Value: 0x02000211 + * + * Solution: Increase the number of task control blocks. + */ +#define LOS_ERRNO_TSK_TCB_UNAVAILABLE LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x11) + +/** + * @ingroup los_task + * Task error code: The task hook function is not matchable. + * + * Value: 0x02000212 + * + * Solution: This error code is not in use temporarily. + */ +#define LOS_ERRNO_TSK_HOOK_NOT_MATCH LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x12) + +/** + * @ingroup los_task + * Task error code: The number of task hook functions exceeds the permitted upper limit. + * + * Value: 0x02000213 + * + * Solution: This error code is not in use temporarily. + */ +#define LOS_ERRNO_TSK_HOOK_IS_FULL LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x13) + +/** + * @ingroup los_task + * Task error code: The operation is performed on the system-level task. + * old usage: The operation is performed on the idle task (LOS_ERRNO_TSK_OPERATE_IDLE) + * + * Value: 0x02000214 + * + * Solution: Check the task ID and do not operate on the system-level task. + */ +#define LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x14) + +/** + * @ingroup los_task + * Task error code: The task that is being suspended is locked. + * + * Value: 0x03000215 + * + * Solution: Suspend the task after unlocking the task. + */ +#define LOS_ERRNO_TSK_SUSPEND_LOCKED LOS_ERRNO_OS_FATAL(LOS_MOD_TSK, 0x15) + +/** + * @ingroup los_task + * Task error code: The task stack fails to be freed. + * + * Value: 0x02000217 + * + * Solution: This error code is not in use temporarily. + */ +#define LOS_ERRNO_TSK_FREE_STACK_FAILED LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x17) + +/** + * @ingroup los_task + * Task error code: The task stack area is too small. + * + * Value: 0x02000218 + * + * Solution: This error code is not in use temporarily. + */ +#define LOS_ERRNO_TSK_STKAREA_TOO_SMALL LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x18) + +/** + * @ingroup los_task + * Task error code: The task fails to be activated. + * + * Value: 0x03000219 + * + * Solution: Perform task switching after creating an idle task. + */ +#define LOS_ERRNO_TSK_ACTIVE_FAILED LOS_ERRNO_OS_FATAL(LOS_MOD_TSK, 0x19) + +/** + * @ingroup los_task + * Task error code: Too many task configuration items. + * + * Value: 0x0200021a + * + * Solution: This error code is not in use temporarily. + */ +#define LOS_ERRNO_TSK_CONFIG_TOO_MANY LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x1a) + +/** + * @ingroup los_task + * Task error code: + * + * Value: 0x0200021b + * + * Solution: This error code is not in use temporarily. + */ +#define LOS_ERRNO_TSK_CP_SAVE_AREA_NOT_ALIGN LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x1b) + +/** + * @ingroup los_task + * Task error code: + * + * Value: 0x0200021d + * + * Solution: This error code is not in use temporarily. + */ +#define LOS_ERRNO_TSK_MSG_Q_TOO_MANY LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x1d) + +/** + * @ingroup los_task + * Task error code: + * + * Value: 0x0200021e + * + * Solution: This error code is not in use temporarily. + */ +#define LOS_ERRNO_TSK_CP_SAVE_AREA_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x1e) + +/** + * @ingroup los_task + * Task error code: + * + * Value: 0x0200021f + * + * Solution: This error code is not in use temporarily. + */ +#define LOS_ERRNO_TSK_SELF_DELETE_ERR LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x1f) + +/** + * @ingroup los_task + * Task error code: The task stack size is too large. + * + * Value: 0x02000220 + * + * Solution: shrink the task stack size parameter. + */ +#define LOS_ERRNO_TSK_STKSZ_TOO_LARGE LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x20) + +/** + * @ingroup los_task + * Task error code: Suspending software timer task is not allowed. + * + * Value: 0x02000221 + * + * Solution: Check the task ID and do not suspend software timer task. + */ +#define LOS_ERRNO_TSK_SUSPEND_SWTMR_NOT_ALLOWED LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x21) + +/** + * @ingroup los_task + * Task error code: The task delay occurs in software timer task. + * + * Value: 0x03000222 + * + * Solution: Don't call Los_TaskDelay in software timer callback. + */ +#define LOS_ERRNO_TSK_DELAY_IN_SWTMR_TSK LOS_ERRNO_OS_FATAL(LOS_MOD_TSK, 0x22) + +/** + * @ingroup los_task + * Task error code: The cpu affinity mask is incorrect. + * + * Value: 0x03000223 + * + * Solution: Please set the correct cpu affinity mask. + */ +#define LOS_ERRNO_TSK_CPU_AFFINITY_MASK_ERR LOS_ERRNO_OS_FATAL(LOS_MOD_TSK, 0x23) + +/** + * @ingroup los_task + * Task error code: Task yield in int is not permited, which will result in unexpected result. + * + * Value: 0x02000224 + * + * Solution: Don't call LOS_TaskYield in Interrupt. + */ +#define LOS_ERRNO_TSK_YIELD_IN_INT LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x24) + +/** +* @ingroup los_task +* Task error code: Task sync resource (semaphore) allocated failed. +* +* Value: 0x02000225 +* +* Solution: Expand LOSCFG_BASE_IPC_SEM_LIMIT. +*/ +#define LOS_ERRNO_TSK_MP_SYNC_RESOURCE LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x25) + +/** +* @ingroup los_task +* Task error code: Task sync failed on operating running task across cores. +* +* Value: 0x02000226 +* +* Solution: Check task delete can be handled in user's scenario. +*/ +#define LOS_ERRNO_TSK_MP_SYNC_FAILED LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x26) + +/** +* @ingroup los_task +* Task error code: Task wait and timeout. +* +* Value: 0x02000227 +* +* Solution: Returns the timeout. +*/ +#define LOS_ERRNO_TSK_TIMEOUT LOS_ERRNO_OS_FATAL(LOS_MOD_TSK, 0x27) + +/** +* @ingroup los_task +* Task error code: A task that is not in the current process. +* +* Value: 0x02000228 +* +* Solution: tasks that are not part of the current process are not allowed to operate. +*/ +#define LOS_ERRNO_TSK_NOT_SELF_PROCESS LOS_ERRNO_OS_FATAL(LOS_MOD_TSK, 0x28) + +/** +* @ingroup los_task +* @brief Define the type of a task entrance function. +* +* @par Description: +* This API is used to define the type of a task entrance function and call it after a task is created and triggered. +* @attention None. +* +* @param param1 [IN] Type #UINTPTR The first parameter passed to the task handling function. +* @param param2 [IN] Type #UINTPTR The second parameter passed to the task handling function. +* @param param3 [IN] Type #UINTPTR The third parameter passed to the task handling function. +* @param param4 [IN] Type #UINTPTR The fourth parameter passed to the task handling function. +* +* @retval None. +* @par Dependency: +*
        • los_task.h: the header file that contains the API declaration.
        +* @see +*/ +typedef VOID *(*TSK_ENTRY_FUNC)(UINTPTR param1, + UINTPTR param2, + UINTPTR param3, + UINTPTR param4); + +/** + * @ingroup los_task + * You are not allowed to add any fields and adjust fields to the structure + */ +typedef struct { + UINTPTR userArea; + UINTPTR userSP; + UINTPTR userMapBase; + UINT32 userMapSize; +} UserTaskParam; + +/** + * @ingroup los_task + * Define the structure of the parameters used for task creation. + * + * Information of specified parameters passed in during task creation. + */ +typedef struct tagTskInitParam { + TSK_ENTRY_FUNC pfnTaskEntry; /**< Task entrance function */ + UINT16 usTaskPrio; /**< Task priority */ + UINT16 policy; /**< Task policy */ + UINTPTR auwArgs[4]; /**< Task parameters, of which the maximum number is four */ + UINT32 uwStackSize; /**< Task stack size */ + CHAR *pcName; /**< Task name */ +#ifdef LOSCFG_KERNEL_SMP + UINT16 usCpuAffiMask; /**< Task cpu affinity mask */ +#endif + UINT32 uwResved; /**< It is automatically deleted if set to LOS_TASK_STATUS_DETACHED. + It is unable to be deleted if set to 0. */ + UINT16 consoleID; /**< The console id of task belongs */ + UINTPTR processID; + UserTaskParam userParam; + /* edf parameters */ + UINT32 runTimeUs; + UINT64 deadlineUs; + UINT64 periodUs; +} TSK_INIT_PARAM_S; + +typedef struct { + union { + INT32 priority; + INT32 runTimeUs; + }; + INT32 deadlineUs; + INT32 periodUs; +} LosSchedParam; + +/** + * @ingroup los_task + * Task name length + * + */ +#define LOS_TASK_NAMELEN 32 + +/** + * @ingroup los_task + * Task information structure. + * + */ +typedef struct tagTskInfo { + CHAR acName[LOS_TASK_NAMELEN]; /**< Task entrance function */ + UINT32 uwTaskID; /**< Task ID */ + UINT16 usTaskStatus; /**< Task status */ + UINT16 usTaskPrio; /**< Task priority */ + VOID *pTaskSem; /**< Semaphore pointer */ + VOID *pTaskMux; /**< Mutex pointer */ + VOID *taskEvent; /**< Event */ + UINT32 uwEventMask; /**< Event mask */ + UINT32 uwStackSize; /**< Task stack size */ + UINTPTR uwTopOfStack; /**< Task stack top */ + UINTPTR uwBottomOfStack; /**< Task stack bottom */ + UINTPTR uwSP; /**< Task SP pointer */ + UINT32 uwCurrUsed; /**< Current task stack usage */ + UINT32 uwPeakUsed; /**< Task stack usage peak */ + BOOL bOvf; /**< Flag that indicates whether a task stack overflow occurs */ +} TSK_INFO_S; + +/** + * @ingroup los_task + * @brief Create a task and suspend. + * + * @par Description: + * This API is used to create a task and suspend it. This task will not be added to the queue of ready tasks + * before resume it. + * + * @attention + *
          + *
        • During task creation, the task control block and task stack of the task that is previously automatically deleted + * are deallocated.
        • + *
        • The task name is a pointer and is not allocated memory.
        • + *
        • If the size of the task stack of the task to be created is 0, configure #LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE + * to specify the default task stack size. The stack size should be a reasonable value, if the size is too large, may + * cause memory exhaustion.
        • + *
        • The task stack size must be aligned on the boundary of 8 bytes. The size is determined by whether it is big + * enough to avoid task stack overflow.
        • + *
        • Less parameter value indicates higher task priority.
        • + *
        • The task name cannot be null.
        • + *
        • The pointer to the task executing function cannot be null.
        • + *
        • The two parameters of this interface is pointer, it should be a correct value, otherwise, the system may be + * abnormal.
        • + *
        + * + * @param taskID [OUT] Type #UINT32 * Task ID. + * @param initParam [IN] Type #TSK_INIT_PARAM_S * Parameter for task creation. + * + * @retval #LOS_ERRNO_TSK_ID_INVALID Invalid Task ID, param taskID is NULL. + * @retval #LOS_ERRNO_TSK_PTR_NULL Param initParam is NULL. + * @retval #LOS_ERRNO_TSK_NAME_EMPTY The task name is NULL. + * @retval #LOS_ERRNO_TSK_ENTRY_NULL The task entrance is NULL. + * @retval #LOS_ERRNO_TSK_PRIOR_ERROR Incorrect task priority. + * @retval #LOS_ERRNO_TSK_STKSZ_TOO_LARGE The task stack size is too large. + * @retval #LOS_ERRNO_TSK_STKSZ_TOO_SMALL The task stack size is too small. + * @retval #LOS_ERRNO_TSK_TCB_UNAVAILABLE No free task control block is available. + * @retval #LOS_ERRNO_TSK_NO_MEMORY Insufficient memory for task creation. + * @retval #LOS_OK The task is successfully created. + * @par Dependency: + *
        • los_task.h: the header file that contains the API declaration.
        + *
        • los_config.h: the header file that contains system configuration items.
        + * @see LOS_TaskDelete + */ +extern UINT32 LOS_TaskCreateOnly(UINT32 *taskID, TSK_INIT_PARAM_S *initParam); + +/** + * @ingroup los_task + * @brief Create a task. + * + * @par Description: + * This API is used to create a task. If the priority of the task created after system initialized is higher than + * the current task and task scheduling is not locked, it is scheduled for running. + * If not, the created task is added to the queue of ready tasks. + * + * @attention + *
          + *
        • During task creation, the task control block and task stack of the task that is previously automatically + * deleted are deallocated.
        • + *
        • The task name is a pointer and is not allocated memory.
        • + *
        • If the size of the task stack of the task to be created is 0, configure #LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE + * to specify the default task stack size.
        • + *
        • The task stack size must be aligned on the boundary of 8 bytes. The size is determined by whether it is big + * enough to avoid task stack overflow.
        • + *
        • Less parameter value indicates higher task priority.
        • + *
        • The task name cannot be null.
        • + *
        • The pointer to the task executing function cannot be null.
        • + *
        • The two parameters of this interface is pointer, it should be a correct value, otherwise, the system may be + * abnormal.
        • + *
        + * + * @param taskID [OUT] Type #UINT32 * Task ID. + * @param initParam [IN] Type #TSK_INIT_PARAM_S * Parameter for task creation. + * + * @retval #LOS_ERRNO_TSK_ID_INVALID Invalid Task ID, param taskID is NULL. + * @retval #LOS_ERRNO_TSK_PTR_NULL Param initParam is NULL. + * @retval #LOS_ERRNO_TSK_NAME_EMPTY The task name is NULL. + * @retval #LOS_ERRNO_TSK_ENTRY_NULL The task entrance is NULL. + * @retval #LOS_ERRNO_TSK_PRIOR_ERROR Incorrect task priority. + * @retval #LOS_ERRNO_TSK_STKSZ_TOO_LARGE The task stack size is too large. + * @retval #LOS_ERRNO_TSK_STKSZ_TOO_SMALL The task stack size is too small. + * @retval #LOS_ERRNO_TSK_TCB_UNAVAILABLE No free task control block is available. + * @retval #LOS_ERRNO_TSK_NO_MEMORY Insufficient memory for task creation. + * @retval #LOS_OK The task is successfully created. + * @par Dependency: + *
        • los_task.h: the header file that contains the API declaration.
        + *
        • los_config.h: the header file that contains system configuration items.
        + * @see LOS_TaskDelete + */ +extern UINT32 LOS_TaskCreate(UINT32 *taskID, TSK_INIT_PARAM_S *initParam); + +/** + * @ingroup los_task + * @brief Resume a task. + * + * @par Description: + * This API is used to resume a suspended task. + * + * @attention + *
          + *
        • If the task is delayed or blocked, resume the task without adding it to the queue of ready tasks.
        • + *
        • If the priority of the task resumed after system initialized is higher than the current task and task scheduling + * is not locked, it is scheduled for running.
        • + *
        + * + * @param taskID [IN] Type #UINT32 Task ID. The task id value is obtained from task creation. + * + * @retval #LOS_ERRNO_TSK_ID_INVALID Invalid Task ID + * @retval #LOS_ERRNO_TSK_NOT_CREATED The task is not created. + * @retval #LOS_ERRNO_TSK_NOT_SUSPENDED The task is not suspended. + * @retval #LOS_OK The task is successfully resumed. + * @par Dependency: + *
        • los_task.h: the header file that contains the API declaration.
        + * @see LOS_TaskSuspend + */ +extern UINT32 LOS_TaskResume(UINT32 taskID); + +/** + * @ingroup los_task + * @brief Suspend a task. + * + * @par Description: + * This API is used to suspend a specified task, and the task will be removed from the queue of ready tasks. + * + * @attention + *
          + *
        • The task that is running and locked cannot be suspended.
        • + *
        • The idle task and swtmr task cannot be suspended.
        • + *
        + * + * @param taskID [IN] Type #UINT32 Task ID. The task id value is obtained from task creation. + * + * @retval #LOS_ERRNO_TSK_OPERATE_IDLE Check the task ID and do not operate on the idle task. + * @retval #LOS_ERRNO_TSK_SUSPEND_SWTMR_NOT_ALLOWED Check the task ID and do not operate on the swtmr task. + * @retval #LOS_ERRNO_TSK_ID_INVALID Invalid Task ID + * @retval #LOS_ERRNO_TSK_NOT_CREATED The task is not created. + * @retval #LOS_ERRNO_TSK_ALREADY_SUSPENDED The task is already suspended. + * @retval #LOS_ERRNO_TSK_SUSPEND_LOCKED The task being suspended is current task and task scheduling + * is locked. + * @retval #LOS_OK The task is successfully suspended. + * @par Dependency: + *
        • los_task.h: the header file that contains the API declaration.
        + * @see LOS_TaskResume + */ +extern UINT32 LOS_TaskSuspend(UINT32 taskID); + +/** + * @ingroup los_task + * @brief Delete a task. + * + * @par Description: + * This API is used to delete a specified task and release the resources for its task stack and task control block. + * + * @attention + *
          + *
        • The idle task and swtmr task cannot be deleted.
        • + *
        • If delete current task maybe cause unexpected error.
        • + *
        • If a task get a mutex is deleted or automatically deleted before release this mutex, other tasks pended + * this mutex maybe never be shchduled.
        • + *
        + * + * @param taskID [IN] Type #UINT32 Task ID. The task id value is obtained from task creation. + * + * @retval #LOS_ERRNO_TSK_OPERATE_IDLE Check the task ID and do not operate on the idle task. + * @retval #LOS_ERRNO_TSK_SUSPEND_SWTMR_NOT_ALLOWED Check the task ID and do not operate on the swtmr task. + * @retval #LOS_ERRNO_TSK_ID_INVALID Invalid Task ID + * @retval #LOS_ERRNO_TSK_NOT_CREATED The task is not created. + * @retval #LOS_ERRNO_TSK_DELETE_LOCKED The task being deleted is current task and task scheduling + * is locked. + * @retval #LOS_OK The task is successfully deleted. + * @par Dependency: + *
        • los_task.h: the header file that contains the API declaration.
        + * @see LOS_TaskCreate | LOS_TaskCreateOnly + */ +extern UINT32 LOS_TaskDelete(UINT32 taskID); + +/** + * @ingroup los_task + * @brief Delay a task. + * + * @par Description: + * This API is used to delay the execution of the current task. The task is able to be scheduled after it is delayed + * for a specified number of Ticks. + * + * @attention + *
          + *
        • The task fails to be delayed if it is being delayed during interrupt processing or it is locked.
        • + *
        • If 0 is passed in and the task scheduling is not locked, execute the next task in the queue of tasks with + * the same priority of the current task. + * If no ready task with the priority of the current task is available, the task scheduling will not occur, and the + * current task continues to be executed.
        • + *
        • Using the interface before system initialized is not allowed.
        • + *
        • DO NOT call this API in software timer callback.
        • + *
        + * + * @param tick [IN] Type #UINT32 Number of Ticks for which the task is delayed. + * + * @retval #LOS_ERRNO_TSK_DELAY_IN_INT The task delay occurs during an interrupt. + * @retval #LOS_ERRNO_TSK_DELAY_IN_LOCK The task delay occurs when the task scheduling is locked. + * @retval #LOS_ERRNO_TSK_ID_INVALID Invalid Task ID + * @retval #LOS_ERRNO_TSK_YIELD_NOT_ENOUGH_TASK No tasks with the same priority is available for scheduling. + * @retval #LOS_OK The task is successfully delayed. + * @par Dependency: + *
        • los_task.h: the header file that contains the API declaration.
        + * @see + */ +extern UINT32 LOS_TaskDelay(UINT32 tick); + +/** + * @ingroup los_task + * @brief Lock the task scheduling. + * + * @par Description: + * This API is used to lock the task scheduling. Task switching will not occur if the task scheduling is locked. + * + * @attention + *
          + *
        • If the task scheduling is locked, but interrupts are not disabled, tasks are still able to be interrupted.
        • + *
        • One is added to the number of task scheduling locks if this API is called. The number of locks is decreased by + * one if the task scheduling is unlocked. Therefore, this API should be used together with LOS_TaskUnlock.
        • + *
        + * + * @param None. + * + * @retval None. + * @par Dependency: + *
        • los_task.h: the header file that contains the API declaration.
        + * @see LOS_TaskUnlock + */ +extern VOID LOS_TaskLock(VOID); + +/** + * @ingroup los_task + * @brief Unlock the task scheduling. + * + * @par Description: + * This API is used to unlock the task scheduling. Calling this API will decrease the number of task locks by one. + * If a task is locked more than once, the task scheduling will be unlocked only when the number of locks becomes zero. + * + * @attention + *
          + *
        • The number of locks is decreased by one if this API is called. One is added to the number of task scheduling + * locks if the task scheduling is locked. Therefore, this API should be used together with LOS_TaskLock.
        • + *
        + * + * @param None. + * + * @retval None. + * @par Dependency: + *
        • los_task.h: the header file that contains the API declaration.
        + * @see LOS_TaskLock + */ +extern VOID LOS_TaskUnlock(VOID); + +/** + * @ingroup los_task + * @brief Set a task priority. + * + * @par Description: + * This API is used to set the priority of a specified task. + * + * @attention + *
          + *
        • If the set priority is higher than the priority of the current running task, task scheduling + * probably occurs.
        • + *
        • Changing the priority of the current running task also probably causes task scheduling.
        • + *
        • Using the interface to change the priority of software timer task and idle task is not allowed.
        • + *
        • Using the interface in the interrupt is not allowed.
        • + *
        + * + * @param taskID [IN] Type #UINT32 Task ID. The task id value is obtained from task creation. + * @param taskPrio [IN] Type #UINT16 Task priority. + * + * @retval #LOS_ERRNO_TSK_PRIOR_ERROR Incorrect task priority.Re-configure the task priority + * @retval #LOS_ERRNO_TSK_OPERATE_IDLE Check the task ID and do not operate on the idle task. + * @retval #LOS_ERRNO_TSK_ID_INVALID Invalid Task ID + * @retval #LOS_ERRNO_TSK_NOT_CREATED The task is not created. + * @retval #LOS_OK The task priority is successfully set to a specified priority. + * @par Dependency: + *
        • los_task.h: the header file that contains the API declaration.
        + * @see LOS_TaskPriSet + */ +extern UINT32 LOS_TaskPriSet(UINT32 taskID, UINT16 taskPrio); + +/** + * @ingroup los_task + * @brief Set the priority of the current running task to a specified priority. + * + * @par Description: + * This API is used to set the priority of the current running task to a specified priority. + * + * @attention + *
          + *
        • Changing the priority of the current running task probably causes task scheduling.
        • + *
        • Using the interface to change the priority of software timer task and idle task is not allowed.
        • + *
        • Using the interface in the interrupt is not allowed.
        • + *
        + * + * @param taskPrio [IN] Type #UINT16 Task priority. + * + * @retval #LOS_ERRNO_TSK_PRIOR_ERROR Incorrect task priority.Re-configure the task priority + * @retval #LOS_ERRNO_TSK_OPERATE_IDLE Check the task ID and do not operate on the idle task. + * @retval #LOS_ERRNO_TSK_ID_INVALID Invalid Task ID + * @retval #LOS_ERRNO_TSK_NOT_CREATED The task is not created. + * @retval #LOS_OK The priority of the current running task is successfully set to a specified + * priority. + * @par Dependency: + *
        • los_task.h: the header file that contains the API declaration.
        + * @see LOS_TaskPriGet + */ +extern UINT32 LOS_CurTaskPriSet(UINT16 taskPrio); + +/** + * @ingroup los_task + * @brief Change the scheduling sequence of tasks with the same priority. + * + * @par Description: + * This API is used to move current task in a queue of tasks with the same priority to the tail of the queue of ready + * tasks. + * + * @attention + *
          + *
        • At least two ready tasks need to be included in the queue of ready tasks with the same priority. If the + * less than two ready tasks are included in the queue, an error is reported.
        • + *
        + * + * @param None. + * + * @retval #LOS_ERRNO_TSK_ID_INVALID Invalid Task ID + * @retval #LOS_ERRNO_TSK_YIELD_NOT_ENOUGH_TASK No tasks with the same priority is available for scheduling. + * @retval #LOS_OK The scheduling sequence of tasks with same priority is + * successfully changed. + * @par Dependency: + *
        • los_task.h: the header file that contains the API declaration.
        + * @see + */ +extern UINT32 LOS_TaskYield(VOID); + +/** + * @ingroup los_task + * @brief Obtain a task priority. + * + * @par Description: + * This API is used to obtain the priority of a specified task. + * + * @attention None. + * + * @param taskID [IN] Type #UINT32 Task ID. The task id value is obtained from task creation. + * + * @retval #OS_INVALID The task priority fails to be obtained. + * @retval #UINT16 The task priority. + * @par Dependency: + *
        • los_task.h: the header file that contains the API declaration.
        + * @see LOS_TaskPriSet + */ +extern UINT16 LOS_TaskPriGet(UINT32 taskID); + +/** + * @ingroup los_task + * @brief Obtain current running task ID. + * + * @par Description: + * This API is used to obtain the ID of current running task. + * + * @attention + *
          + *
        • This interface should not be called before system initialized.
        • + *
        + * + * @retval #LOS_ERRNO_TSK_ID_INVALID Invalid Task ID. + * @retval #UINT32 Task ID. + * @par Dependency: + *
        • los_task.h: the header file that contains the API declaration.
        + * @see + */ +extern UINT32 LOS_CurTaskIDGet(VOID); + +/** + * @ingroup los_task + * @brief Gets the maximum number of threads supported by the system. + * + * @par Description: + * This API is used to gets the maximum number of threads supported by the system. + * + * @attention + *
          + *
        • This interface should not be called before system initialized.
        • + *
        + * + * @retval None. + * @par Dependency: + *
        • los_task.h: the header file that contains the API declaration.
        + * @see + */ +extern UINT32 LOS_GetSystemTaskMaximum(VOID); + +/** + * @ingroup los_task + * @brief Obtain a task information structure. + * + * @par Description: + * This API is used to obtain a task information structure. + * + * @attention + *
          + *
        • One parameter of this interface is a pointer, it should be a correct value, otherwise, the system may be + * abnormal.
        • + *
        + * + * @param taskID [IN] Type #UINT32 Task ID. The task id value is obtained from task creation. + * @param taskInfo [OUT] Type #TSK_INFO_S* Pointer to the task information structure to be obtained. + * + * @retval #LOS_ERRNO_TSK_PTR_NULL Null parameter. + * @retval #LOS_ERRNO_TSK_ID_INVALID Invalid task ID. + * @retval #LOS_ERRNO_TSK_NOT_CREATED The task is not created. + * @retval #LOS_OK The task information structure is successfully obtained. + * @par Dependency: + *
        • los_task.h: the header file that contains the API declaration.
        + * @see + */ +extern UINT32 LOS_TaskInfoGet(UINT32 taskID, TSK_INFO_S *taskInfo); + + +/** + * @ingroup los_task + * @brief Set the affinity mask of the task scheduling cpu. + * + * @par Description: + * This API is used to set the affinity mask of the task scheduling cpu. + * + * @attention + *
          + *
        • If any low LOSCFG_KERNEL_CORE_NUM bit of the mask is not set, an error is reported.
        • + *
        + * + * @param uwTaskID [IN] Type #UINT32 Task ID. The task id value is obtained from task creation. + * @param usCpuAffiMask [IN] Type #UINT32 The scheduling cpu mask.The low to high bit of the mask corresponds to + * the cpu number, the high bit that exceeding the CPU number is ignored. + * + * @retval #LOS_ERRNO_TSK_ID_INVALID Invalid task ID. + * @retval #LOS_ERRNO_TSK_NOT_CREATED The task is not created. + * @retval #LOS_ERRNO_TSK_CPU_AFFINITY_MASK_ERR The task cpu affinity mask is incorrect. + * @retval #LOS_OK The task cpu affinity mask is successfully set. + * @par Dependency: + *
        • los_task.h: the header file that contains the API declaration.
        + * @see LOS_TaskCpuAffiGet + */ +extern UINT32 LOS_TaskCpuAffiSet(UINT32 uwTaskID, UINT16 usCpuAffiMask); + +/** + * @ingroup los_task + * @brief Get the affinity mask of the task scheduling cpu. + * + * @par Description: + * This API is used to get the affinity mask of the task scheduling cpu. + * + * @attention None. + * + * @param taskID [IN] Type #UINT32 Task ID. The task id value is obtained from task creation. + * + * @retval #0 The cpu affinity mask fails to be obtained. + * @retval #UINT16 The scheduling cpu mask. The low to high bit of the mask corresponds to the cpu number. + * @par Dependency: + *
        • los_task.h: the header file that contains the API declaration.
        + * @see LOS_TaskCpuAffiSet + */ +extern UINT16 LOS_TaskCpuAffiGet(UINT32 taskID); + +/** + * @ingroup los_task + * @brief Get the scheduling policy for the task. + * + * @par Description: + * This API is used to get the scheduling policy for the task. + * + * @attention None. + * + * @param taskID [IN] Type #UINT32 Task ID. The task id value is obtained from task creation. + * + * @retval #-LOS_ESRCH Invalid task id. + * @retval #-LOS_EPERM The process is not currently running. + * @retval #INT32 the scheduling policy. + * @par Dependency: + *
        • los_task.h: the header file that contains the API declaration.
        + * @see LOS_SetTaskScheduler + */ +extern INT32 LOS_GetTaskScheduler(INT32 taskID); + +/** + * @ingroup los_task + * @brief Set the scheduling policy and priority for the task. + * + * @par Description: + * This API is used to set the scheduling policy and priority for the task. + * + * @attention None. + * + * @param taskID [IN] Type #UINT32 Task ID. The task id value is obtained from task creation. + * @param policy [IN] Type #UINT16 Task scheduling policy. + * @param priority [IN] Type #UINT16 Task scheduling priority. + * + * @retval -LOS_ESRCH Invalid task id. + * @retval -LOS_EOPNOTSUPP Unsupported fields. + * @retval -LOS_EPERM The process is not currently running. + * @retval #0 Set up the success. + * @par Dependency: + *
        • los_task.h: the header file that contains the API declaration.
        + * @see LOS_GetTaskScheduler + */ +extern INT32 LOS_SetTaskScheduler(INT32 taskID, UINT16 policy, UINT16 priority); + +/** + * @ingroup los_task + * @brief Trigger active task scheduling. + * + * @par Description: + * This API is used to trigger active task scheduling. + * + * @attention None. + * + * @param None + * + * @retval Nobe + * @par Dependency: + *
        • los_task.h: the header file that contains the API declaration.
        + */ +extern VOID LOS_Schedule(VOID); + +/** + * @ingroup los_task + * @brief Wait for the specified task to finish and reclaim its resources. + * + * @par Description: + * This API is used to wait for the specified task to finish and reclaim its resources. + * + * @attention None. + * + * @param taskID [IN] task ID. + * @param retval [OUT] wait for the return value of the task. + * + * @retval LOS_OK successful + * @retval LOS_EINVAL Invalid parameter or invalid operation + * @retval LOS_EINTR Disallow calls in interrupt handlers + * @retval LOS_EPERM Waiting tasks and calling tasks do not belong to the same process + * @retval LOS_EDEADLK The waiting task is the same as the calling task + * @par Dependency: + *
        • los_task.h: the header file that contains the API declaration.
        + */ +extern UINT32 LOS_TaskJoin(UINT32 taskID, UINTPTR *retval); + +/** + * @ingroup los_task + * @brief Change the joinable attribute of the task to detach. + * + * @par Description: + * This API is used to change the joinable attribute of the task to detach. + * + * @attention None. + * + * @param taskID [IN] task ID. + * + * @retval LOS_OK successful + * @retval LOS_EINVAL Invalid parameter or invalid operation + * @retval LOS_EINTR Disallow calls in interrupt handlers + * @retval LOS_EPERM Waiting tasks and calling tasks do not belong to the same process + * @retval LOS_ESRCH Cannot modify the Joinable attribute of a task that is waiting for completion. + * @par Dependency: + *
        • los_task.h: the header file that contains the API declaration.
        + */ +extern UINT32 LOS_TaskDetach(UINT32 taskID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_TASK_H */ diff --git a/src/kernel_liteos_a/kernel/include/los_tick.h b/src/kernel_liteos_a/kernel/include/los_tick.h new file mode 100644 index 00000000..80b3006d --- /dev/null +++ b/src/kernel_liteos_a/kernel/include/los_tick.h @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_tick Tick + * @ingroup kernel + */ + +#ifndef _LOS_TICK_H +#define _LOS_TICK_H + +#include "los_err.h" +#include "los_errno.h" +#include "hal_timer.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_tick + * Tick error code: The Tick configuration is incorrect. + * + * Value: 0x02000400 + * + * Solution: Change values of the OS_SYS_CLOCK and LOSCFG_BASE_CORE_TICK_PER_SECOND system time configuration modules + * in Los_config.h. + */ +#define LOS_ERRNO_TICK_CFG_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_TICK, 0x00) + +/** + * @ingroup los_tick + * Tick error code: This error code is not in use temporarily. + * + * Value: 0x02000401 + * + * Solution: None. + */ +#define LOS_ERRNO_TICK_NO_HWTIMER LOS_ERRNO_OS_ERROR(LOS_MOD_TICK, 0x01) + +/** + * @ingroup los_tick + * Tick error code: The number of Ticks is too small. + * + * Value: 0x02000402 + * + * Solution: Change values of the OS_SYS_CLOCK and LOSCFG_BASE_CORE_TICK_PER_SECOND system time configuration modules + * according to the SysTick_Config function. + */ +#define LOS_ERRNO_TICK_PER_SEC_TOO_SMALL LOS_ERRNO_OS_ERROR(LOS_MOD_TICK, 0x02) + +/** + * @ingroup los_config + * system clock + */ +extern UINT32 g_sysClock; + +/** + * @ingroup los_config + * ticks per second + */ +extern UINT32 g_tickPerSecond; + +/** + * @ingroup los_tick + * @brief Obtain system cycle count. + * + * @par Description: + * This API is used to obtain system cycle count. + * + * @attention + *
          + *
        • This count is determined by the tick source.
        • + *
        + * + * @param puwCntHi [OUT] Type #UINT32 Pointer to the higher 32bit of cycles to be obtained. + * @param puwCntLo [OUT] Type #UINT32 Pointer to the lower 32bit of cycles to be obtained. + * + * @retval None. + * + * @par Dependency: + *
        • los_tick.h: the header file that contains the API declaration.
        + * @see + */ +extern VOID LOS_GetCpuCycle(UINT32 *puwCntHi, UINT32 *puwCntLo); + +/** + * @ingroup los_tick + * @brief Obtain system time in nanoseconds. + * + * @par Description: + * This API is used to obtain system time in nanoseconds. + * + * @attention None. + * + * @param None. + * + * @retval #UINT64 system time in nanoseconds. + * + * @par Dependency: + *
        • los_tick.h: the header file that contains the API declaration.
        + * @see + */ +extern UINT64 LOS_CurrNanosec(VOID); + +/** + * @ingroup los_tick + * @brief spinning-delay in microsecond (us). + * + * @par Description: + * This API is used to delay in microsecond. + * + * @attention None. + * + * @param #UINT32 microsecond needs to delay. + * + * @retval None. + * + * @par Dependency: + *
        • los_tick.h: the header file that contains the API declaration.
        + * @see + */ +extern VOID LOS_Udelay(UINT32 usecs); + +/** + * @ingroup los_tick + * @brief spinning-delay in millisecond (ms). + * + * @par Description: + * This API is used to delay in millisecond. + * + * @attention None. + * + * @param #UINT32 millisecond needs to delay. + * + * @retval None. + * + * @par Dependency: + *
        • los_tick.h: the header file that contains the API declaration.
        + * @see + */ +extern VOID LOS_Mdelay(UINT32 usecs); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_TICK_H */ diff --git a/src/kernel_liteos_a/kernel/include/los_toolchain.h b/src/kernel_liteos_a/kernel/include/los_toolchain.h new file mode 100644 index 00000000..8ae90ca3 --- /dev/null +++ b/src/kernel_liteos_a/kernel/include/los_toolchain.h @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_toolchain + * @ingroup kernel + */ + +#ifndef _LOS_TOOLCHAIN_H +#define _LOS_TOOLCHAIN_H + +#if defined ( __ICCARM__ ) +#include "iccarm_builtin.h" +#endif + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#ifndef UNUSED +#define UNUSED(var) \ + do { \ + (void)var; \ + } while (0) +#endif + +/* for ARM Compiler */ +#if defined ( __CC_ARM ) +#ifndef ASM +#define ASM __asm +#endif + +#ifndef INLINE +#define INLINE __inline +#endif + +#ifndef STATIC_INLINE +#define STATIC_INLINE static __inline +#endif + +#ifndef USED +#define USED __attribute__((used)) +#endif + +#ifndef WEAK +#define WEAK __attribute__((weak)) +#endif + +#ifndef CLZ +#define CLZ(value) (__clz(value)) +#endif + +#ifndef NORETURN +#define NORETURN __declspec(noreturn) +#endif + +#ifndef DEPRECATED +#define DEPRECATED __attribute__((deprecated)) +#endif + +/* for IAR Compiler */ +#elif defined ( __ICCARM__ ) + +#ifndef ASM +#define ASM __asm +#endif + +#ifndef INLINE +#define INLINE inline +#endif + +#ifndef STATIC_INLINE +#define STATIC_INLINE static inline +#endif + +#ifndef USED +#define USED __root +#endif + +#ifndef WEAK +#define WEAK __weak +#endif + +#ifndef CLZ +#define CLZ(value) (__iar_builtin_CLZ(value)) +#endif + +#ifndef CTZ +#define CTZ(value) (__UNDEFINED(value)) +#endif + +#ifndef NORETURN +#define NORETURN __attribute__ ((__noreturn__)) +#endif + +#ifndef DEPRECATED +#define DEPRECATED __attribute__((deprecated)) +#endif + +/* for GNU Compiler */ +#elif defined ( __GNUC__ ) + +#ifndef ASM +#define ASM __asm +#endif + +#ifndef INLINE +#define INLINE __inline +#endif + +#ifndef STATIC_INLINE +#define STATIC_INLINE static inline +#endif + +#ifndef USED +#define USED __attribute__((used)) +#endif + +#ifndef WEAK +#define WEAK __attribute__((weak)) +#endif + +#ifndef CLZ +#define CLZ(value) (__builtin_clz(value)) +#endif + +#ifndef CTZ +#define CTZ(value) (__builtin_ctz(value)) +#endif + +#ifndef NORETURN +#define NORETURN __attribute__ ((__noreturn__)) +#endif + +#ifndef DEPRECATED +#define DEPRECATED __attribute__((deprecated)) +#endif + +#else +#error Unknown compiler. +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_TOOLCHAIN_H */ diff --git a/src/kernel_liteos_a/kernel/include/los_trace.h b/src/kernel_liteos_a/kernel/include/los_trace.h new file mode 100644 index 00000000..3d9652c9 --- /dev/null +++ b/src/kernel_liteos_a/kernel/include/los_trace.h @@ -0,0 +1,629 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_trace Trace + * @ingroup kernel + */ + +#ifndef _LOS_TRACE_H +#define _LOS_TRACE_H + +#include "los_task.h" +#include "los_base.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#ifdef LOSCFG_TRACE_CONTROL_AGENT + +/** + * @ingroup los_trace + * Trace Control agent task's priority. + */ +#define LOSCFG_TRACE_TASK_PRIORITY 2 +#endif + +#define LOSCFG_TRACE_OBJ_MAX_NAME_SIZE LOS_TASK_NAMELEN + +#define LOS_TRACE_LR_RECORD 5 +#define LOS_TRACE_LR_IGNORE 0 +/** + * @ingroup los_trace + * Trace records the max number of objects(kernel object, like tasks), range is [0, LOSCFG_BASE_CORE_TSK_LIMIT]. + * if set to 0, trace will not record any object. + */ +#define LOSCFG_TRACE_OBJ_MAX_NUM 0 + +/** + * @ingroup los_trace + * Trace tlv encode buffer size, the buffer is used to encode one piece raw frame to tlv message in online mode. + */ +#define LOSCFG_TRACE_TLV_BUF_SIZE 100 + +/** + * @ingroup los_trace + * Trace error code: init trace failed. + * + * Value: 0x02001400 + * + * Solution: Follow the trace State Machine. + */ +#define LOS_ERRNO_TRACE_ERROR_STATUS LOS_ERRNO_OS_ERROR(LOS_MOD_TRACE, 0x00) + +/** + * @ingroup los_trace + * Trace error code: Insufficient memory for trace buf init. + * + * Value: 0x02001401 + * + * Solution: Expand the configured system memory or decrease the value defined by LOS_TRACE_BUFFER_SIZE. + */ +#define LOS_ERRNO_TRACE_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_TRACE, 0x01) + +/** + * @ingroup los_trace + * Trace error code: Insufficient memory for trace struct. + * + * Value: 0x02001402 + * + * Solution: Increase trace buffer's size. + */ +#define LOS_ERRNO_TRACE_BUF_TOO_SMALL LOS_ERRNO_OS_ERROR(LOS_MOD_TRACE, 0x02) + +/** + * @ingroup los_trace + * Trace state. + */ +enum TraceState { + TRACE_UNINIT = 0, /**< trace isn't inited */ + TRACE_INITED, /**< trace is inited but not started yet */ + TRACE_STARTED, /**< trace is started and system is tracing */ + TRACE_STOPED, /**< trace is stopped */ +}; + +/** + * @ingroup los_trace + * Trace mask is used to filter events in runtime. Each mask keep only one unique bit to 1, and user can define own + * module's trace mask. + */ +typedef enum { + TRACE_SYS_FLAG = 0x10, + TRACE_HWI_FLAG = 0x20, + TRACE_TASK_FLAG = 0x40, + TRACE_SWTMR_FLAG = 0x80, + TRACE_MEM_FLAG = 0x100, + TRACE_QUE_FLAG = 0x200, + TRACE_EVENT_FLAG = 0x400, + TRACE_SEM_FLAG = 0x800, + TRACE_MUX_FLAG = 0x1000, + TRACE_IPC_FLAG = 0x2000, + + TRACE_MAX_FLAG = 0x80000000, + TRACE_USER_DEFAULT_FLAG = 0xFFFFFFF0, +} LOS_TRACE_MASK; + +/** + * @ingroup los_trace + * Trace event type which indicate the exactly happened events, user can define own module's event type like + * TRACE_#MODULE#_FLAG | NUMBER. + * 28 4 + * 0 0 0 0 0 0 0 0 X X X X X X X X 0 0 0 0 0 0 + * | | | + * trace_module_flag number + * + */ +typedef enum { + /* 0x10~0x1F */ + SYS_ERROR = TRACE_SYS_FLAG | 0, + SYS_START = TRACE_SYS_FLAG | 1, + SYS_STOP = TRACE_SYS_FLAG | 2, + + /* 0x20~0x2F */ + HWI_CREATE = TRACE_HWI_FLAG | 0, + HWI_CREATE_SHARE = TRACE_HWI_FLAG | 1, + HWI_DELETE = TRACE_HWI_FLAG | 2, + HWI_DELETE_SHARE = TRACE_HWI_FLAG | 3, + HWI_RESPONSE_IN = TRACE_HWI_FLAG | 4, + HWI_RESPONSE_OUT = TRACE_HWI_FLAG | 5, + HWI_ENABLE = TRACE_HWI_FLAG | 6, + HWI_DISABLE = TRACE_HWI_FLAG | 7, + HWI_TRIGGER = TRACE_HWI_FLAG | 8, + HWI_SETPRI = TRACE_HWI_FLAG | 9, + HWI_CLEAR = TRACE_HWI_FLAG | 10, + HWI_SETAFFINITY = TRACE_HWI_FLAG | 11, + HWI_SENDIPI = TRACE_HWI_FLAG | 12, + + /* 0x40~0x4F */ + TASK_CREATE = TRACE_TASK_FLAG | 0, + TASK_PRIOSET = TRACE_TASK_FLAG | 1, + TASK_DELETE = TRACE_TASK_FLAG | 2, + TASK_SUSPEND = TRACE_TASK_FLAG | 3, + TASK_RESUME = TRACE_TASK_FLAG | 4, + TASK_SWITCH = TRACE_TASK_FLAG | 5, + TASK_SIGNAL = TRACE_TASK_FLAG | 6, + + /* 0x80~0x8F */ + SWTMR_CREATE = TRACE_SWTMR_FLAG | 0, + SWTMR_DELETE = TRACE_SWTMR_FLAG | 1, + SWTMR_START = TRACE_SWTMR_FLAG | 2, + SWTMR_STOP = TRACE_SWTMR_FLAG | 3, + SWTMR_EXPIRED = TRACE_SWTMR_FLAG | 4, + + /* 0x100~0x10F */ + MEM_ALLOC = TRACE_MEM_FLAG | 0, + MEM_ALLOC_ALIGN = TRACE_MEM_FLAG | 1, + MEM_REALLOC = TRACE_MEM_FLAG | 2, + MEM_FREE = TRACE_MEM_FLAG | 3, + MEM_INFO_REQ = TRACE_MEM_FLAG | 4, + MEM_INFO = TRACE_MEM_FLAG | 5, + + /* 0x200~0x20F */ + QUEUE_CREATE = TRACE_QUE_FLAG | 0, + QUEUE_DELETE = TRACE_QUE_FLAG | 1, + QUEUE_RW = TRACE_QUE_FLAG | 2, + + /* 0x400~0x40F */ + EVENT_CREATE = TRACE_EVENT_FLAG | 0, + EVENT_DELETE = TRACE_EVENT_FLAG | 1, + EVENT_READ = TRACE_EVENT_FLAG | 2, + EVENT_WRITE = TRACE_EVENT_FLAG | 3, + EVENT_CLEAR = TRACE_EVENT_FLAG | 4, + + /* 0x800~0x80F */ + SEM_CREATE = TRACE_SEM_FLAG | 0, + SEM_DELETE = TRACE_SEM_FLAG | 1, + SEM_PEND = TRACE_SEM_FLAG | 2, + SEM_POST = TRACE_SEM_FLAG | 3, + + /* 0x1000~0x100F */ + MUX_CREATE = TRACE_MUX_FLAG | 0, + MUX_DELETE = TRACE_MUX_FLAG | 1, + MUX_PEND = TRACE_MUX_FLAG | 2, + MUX_POST = TRACE_MUX_FLAG | 3, + + /* 0x2000~0x200F */ + IPC_WRITE_DROP = TRACE_IPC_FLAG | 0, + IPC_WRITE = TRACE_IPC_FLAG | 1, + IPC_READ_DROP = TRACE_IPC_FLAG | 2, + IPC_READ = TRACE_IPC_FLAG | 3, + IPC_TRY_READ = TRACE_IPC_FLAG | 4, + IPC_READ_TIMEOUT = TRACE_IPC_FLAG | 5, + IPC_KILL = TRACE_IPC_FLAG | 6, +} LOS_TRACE_TYPE; + +/** + * @ingroup los_trace + * struct to store the trace config information. + */ +typedef struct { + UINT32 bigLittleEndian; /**< big little endian flag */ + UINT32 clockFreq; /**< system clock frequency */ + UINT32 version; /**< trace version */ +} TraceBaseHeaderInfo; + +/** + * @ingroup los_trace + * struct to store the event information + */ +typedef struct { + UINT32 eventType; /**< event type */ + UINT32 curTask; /**< current running task */ + UINT32 curPid; /**< current running processID */ + UINT64 curTime; /**< current timestamp */ + UINTPTR identity; /**< subject of the event description */ +#ifdef LOSCFG_TRACE_FRAME_CORE_MSG + struct CoreStatus { + UINT32 cpuid : 8, /**< cpuid */ + hwiActive : 4, /**< whether is in hwi response */ + taskLockCnt : 4, /**< task lock count */ + paramCount : 4, /**< event frame params' number */ + reserves : 12; /**< reserves */ + } core; +#endif + +#ifdef LOSCFG_TRACE_FRAME_EVENT_COUNT + UINT32 eventCount; /**< the sequence of happened events */ +#endif + +#ifdef LOS_TRACE_FRAME_LR + UINTPTR linkReg[LOS_TRACE_LR_RECORD]; +#endif + +#ifdef LOSCFG_TRACE_FRAME_MAX_PARAMS + UINTPTR params[LOSCFG_TRACE_FRAME_MAX_PARAMS]; /**< event frame's params */ +#endif +} TraceEventFrame; + +#ifdef LOSCFG_DRIVERS_TRACE +typedef struct { + UINT32 eventType; + UINTPTR identity; + UINTPTR params[3]; +} UsrEventInfo; +#endif + +/** + * @ingroup los_trace + * struct to store the kernel obj information, we defined task as kernel obj in this system. + */ +typedef struct { + UINT32 id; /**< kernel obj's id */ + UINT32 prio; /**< kernel obj's priority */ + CHAR name[LOSCFG_TRACE_OBJ_MAX_NAME_SIZE]; /**< kernel obj's name */ +} ObjData; + +/** + * @ingroup los_trace + * struct to store the trace data. + */ +typedef struct { + TraceBaseHeaderInfo baseInfo; /**< basic info, include bigLittleEndian flag, system clock freq */ + UINT16 totalLen; /**< trace data's total length */ + UINT16 objSize; /**< sizeof #ObjData */ + UINT16 frameSize; /**< sizeof #TraceEventFrame */ + UINT16 objOffset; /**< the offset of the first obj data to record beginning */ + UINT16 frameOffset; /**< the offset of the first event frame data to record beginning */ +} OfflineHead; + +/** + * @ingroup los_trace + * @brief Define the type of trace hardware interrupt filter hook function. + * + * @par Description: + * User can register filter function by LOS_TraceHwiFilterHookReg to filter hardware interrupt events. Return true if + * user don't need trace the certain number. + * + * @attention + * None. + * + * @param hwiNum [IN] Type #UINT32. The hardware interrupt number. + * @retval #TRUE 0x00000001: Not record the certain number. + * @retval #FALSE 0x00000000: Need record the certain number. + * + * @par Dependency: + *
        • los_trace.h: the header file that contains the API declaration.
        + */ +typedef BOOL (*TRACE_HWI_FILTER_HOOK)(UINT32 hwiNum); + +typedef VOID (*TRACE_EVENT_HOOK)(UINT32 eventType, UINTPTR identity, const UINTPTR *params, UINT16 paramCount); +extern TRACE_EVENT_HOOK g_traceEventHook; + +/** + * @ingroup los_trace + * Trace event params: + 1. Configure the macro without parameters so as not to record events of this type; + 2. Configure the macro at least with one parameter to record this type of event; + 3. User can delete unnecessary parameters which defined in corresponding marco; + * @attention + *
          + *
        • The first param is treat as key, keep at least this param if you want trace this event.
        • + *
        • All parameters were treated as UINTPTR.
        • + *
        + * eg. Trace an event as: + * #define TASK_PRIOSET_PARAMS(taskId, taskStatus, oldPrio, newPrio) taskId, taskStatus, oldPrio, newPrio + * eg. Not Trace an event as: + * #define TASK_PRIOSET_PARAMS(taskId, taskStatus, oldPrio, newPrio) + * eg. Trace only you need parmas as: + * #define TASK_PRIOSET_PARAMS(taskId, taskStatus, oldPrio, newPrio) taskId + */ +#define TASK_SWITCH_PARAMS(taskId, oldPriority, oldTaskStatus, newPriority, newTaskStatus) \ + taskId, oldPriority, oldTaskStatus, newPriority, newTaskStatus +#define TASK_PRIOSET_PARAMS(taskId, taskStatus, oldPrio, newPrio) taskId, taskStatus, oldPrio, newPrio +#define TASK_CREATE_PARAMS(taskId, taskStatus, prio) taskId, taskStatus, prio +#define TASK_DELETE_PARAMS(taskId, taskStatus, usrStack) taskId, taskStatus, usrStack +#define TASK_SUSPEND_PARAMS(taskId, taskStatus, runTaskId) taskId, taskStatus, runTaskId +#define TASK_RESUME_PARAMS(taskId, taskStatus, prio) taskId, taskStatus, prio +#define TASK_SIGNAL_PARAMS(taskId, signal, schedFlag) // taskId, signal, schedFlag + +#define SWTMR_START_PARAMS(swtmrId, mode, interval) swtmrId, mode, interval +#define SWTMR_DELETE_PARAMS(swtmrId) swtmrId +#define SWTMR_EXPIRED_PARAMS(swtmrId) swtmrId +#define SWTMR_STOP_PARAMS(swtmrId) swtmrId +#define SWTMR_CREATE_PARAMS(swtmrId) swtmrId + +#define HWI_CREATE_PARAMS(hwiNum, hwiPrio, hwiMode, hwiHandler) hwiNum, hwiPrio, hwiMode, hwiHandler +#define HWI_CREATE_SHARE_PARAMS(hwiNum, pDevId, ret) hwiNum, pDevId, ret +#define HWI_DELETE_PARAMS(hwiNum) hwiNum +#define HWI_DELETE_SHARE_PARAMS(hwiNum, pDevId, ret) hwiNum, pDevId, ret +#define HWI_RESPONSE_IN_PARAMS(hwiNum) hwiNum +#define HWI_RESPONSE_OUT_PARAMS(hwiNum) hwiNum +#define HWI_ENABLE_PARAMS(hwiNum) hwiNum +#define HWI_DISABLE_PARAMS(hwiNum) hwiNum +#define HWI_TRIGGER_PARAMS(hwiNum) hwiNum +#define HWI_SETPRI_PARAMS(hwiNum, priority) hwiNum, priority +#define HWI_CLEAR_PARAMS(hwiNum) hwiNum +#define HWI_SETAFFINITY_PARAMS(hwiNum, cpuMask) hwiNum, cpuMask +#define HWI_SENDIPI_PARAMS(hwiNum, cpuMask) hwiNum, cpuMask + +#define EVENT_CREATE_PARAMS(eventCB) eventCB +#define EVENT_DELETE_PARAMS(eventCB, delRetCode) eventCB, delRetCode +#define EVENT_READ_PARAMS(eventCB, eventId, mask, mode, timeout) \ + eventCB, eventId, mask, mode, timeout +#define EVENT_WRITE_PARAMS(eventCB, eventId, events) eventCB, eventId, events +#define EVENT_CLEAR_PARAMS(eventCB, eventId, events) eventCB, eventId, events + +#define QUEUE_CREATE_PARAMS(queueId, queueSz, itemSz, queueAddr, memType) \ + queueId, queueSz, itemSz, queueAddr, memType +#define QUEUE_DELETE_PARAMS(queueId, state, readable) queueId, state, readable +#define QUEUE_RW_PARAMS(queueId, queueSize, bufSize, operateType, readable, writable, timeout) \ + queueId, queueSize, bufSize, operateType, readable, writable, timeout + +#define SEM_CREATE_PARAMS(semId, type, count) semId, type, count +#define SEM_DELETE_PARAMS(semId, delRetCode) semId, delRetCode +#define SEM_PEND_PARAMS(semId, count, timeout) semId, count, timeout +#define SEM_POST_PARAMS(semId, type, count) semId, type, count + +#define MUX_CREATE_PARAMS(muxId) muxId +#define MUX_DELETE_PARAMS(muxId, state, count, owner) muxId, state, count, owner +#define MUX_PEND_PARAMS(muxId, count, owner, timeout) muxId, count, owner, timeout +#define MUX_POST_PARAMS(muxId, count, owner) muxId, count, owner + +#define MEM_ALLOC_PARAMS(pool, ptr, size) pool, ptr, size +#define MEM_ALLOC_ALIGN_PARAMS(pool, ptr, size, boundary) pool, ptr, size, boundary +#define MEM_REALLOC_PARAMS(pool, ptr, size) pool, ptr, size +#define MEM_FREE_PARAMS(pool, ptr) pool, ptr +#define MEM_INFO_REQ_PARAMS(pool) pool +#define MEM_INFO_PARAMS(pool, usedSize, freeSize) pool, usedSize, freeSize + +#define IPC_WRITE_DROP_PARAMS(dstTid, dstPid, msgType, code, ipcStatus) \ + dstTid, dstPid, msgType, code, ipcStatus +#define IPC_WRITE_PARAMS(dstTid, dstPid, msgType, code, ipcStatus) \ + dstTid, dstPid, msgType, code, ipcStatus +#define IPC_READ_DROP_PARAMS(srcTid, srcPid, msgType, code, ipcStatus) \ + srcTid, srcPid, msgType, code, ipcStatus +#define IPC_READ_PARAMS(srcTid, srcPid, msgType, code, ipcStatus) \ + srcTid, srcPid, msgType, code, ipcStatus +#define IPC_TRY_READ_PARAMS(msgType, ipcStatus) msgType, ipcStatus +#define IPC_READ_TIMEOUT_PARAMS(msgType, ipcStatus) msgType, ipcStatus +#define IPC_KILL_PARAMS(msgType, ipcStatus) msgType, ipcStatus + +#define SYS_ERROR_PARAMS(errno) errno + +#ifdef LOSCFG_KERNEL_TRACE + +/** + * @ingroup los_trace + * @brief Trace static code stub. + * + * @par Description: + * This API is used to instrument trace code stub in source code, to track events. + * @attention + * None. + * + * @param TYPE [IN] Type #LOS_TRACE_TYPE. The event type. + * @param IDENTITY [IN] Type #UINTPTR. The subject of this event description. + * @param ... [IN] Type #UINTPTR. This piece of event's params. + * @retval None. + * + * @par Dependency: + *
        • los_trace.h: the header file that contains the API declaration.
        + */ +#define LOS_TRACE(TYPE, IDENTITY, ...) \ + do { \ + UINTPTR _inner[] = {0, TYPE##_PARAMS((UINTPTR)IDENTITY, ##__VA_ARGS__)}; \ + UINTPTR _n = sizeof(_inner) / sizeof(UINTPTR); \ + if ((_n > 1) && (g_traceEventHook != NULL)) { \ + g_traceEventHook(TYPE, _inner[1], _n > 2 ? &_inner[2] : NULL, _n - 2); \ + } \ + } while (0) +#else +#define LOS_TRACE(TYPE, ...) +#endif + +#ifdef LOSCFG_KERNEL_TRACE + +/** + * @ingroup los_trace + * @brief Trace static easier user-defined code stub. + * + * @par Description: + * This API is used to instrument user-defined trace code stub in source code, to track events simply. + * @attention + * None. + * + * @param TYPE [IN] Type #UINT32. The event type, only low 4 bits take effect. + * @param IDENTITY [IN] Type #UINTPTR. The subject of this event description. + * @param ... [IN] Type #UINTPTR. This piece of event's params. + * @retval None. + * + * @par Dependency: + *
        • los_trace.h: the header file that contains the API declaration.
        + */ +#define LOS_TRACE_EASY(TYPE, IDENTITY, ...) \ + do { \ + UINTPTR _inner[] = {0, ##__VA_ARGS__}; \ + UINTPTR _n = sizeof(_inner) / sizeof(UINTPTR); \ + if (g_traceEventHook != NULL) { \ + g_traceEventHook(TRACE_USER_DEFAULT_FLAG | TYPE, (UINTPTR)IDENTITY, _n > 1 ? &_inner[1] : NULL, _n - 1); \ + } \ + } while (0) +#else +#define LOS_TRACE_EASY(...) +#endif + +/** + * @ingroup los_trace + * @brief Start trace. + * + * @par Description: + * This API is used to start trace. + * @attention + *
          + *
        • Start trace
        • + *
        + * + * @param None. + * @retval #LOS_ERRNO_TRACE_ERROR_STATUS 0x02001400: Trace start failed. + * @retval #LOS_OK 0x00000000: Trace start success. + * + * @par Dependency: + *
        • los_trace.h: the header file that contains the API declaration.
        + * @see LOS_TraceStart + */ +extern UINT32 LOS_TraceStart(VOID); + +/** + * @ingroup los_trace + * @brief Stop trace. + * + * @par Description: + * This API is used to stop trace. + * @attention + *
          + *
        • Stop trace
        • + *
        + * + * @param None. + * @retval #None. + * + * @par Dependency: + *
        • los_trace.h: the header file that contains the API declaration.
        + * @see LOS_TraceStop + */ +extern VOID LOS_TraceStop(VOID); + +/** + * @ingroup los_trace + * @brief Clear the trace buf. + * + * @par Description: + * Clear the event frames in trace buf only at offline mode. + * @attention + *
          + *
        • This API can be called only after that trace buffer has been established.
        • + * Otherwise, the trace will be failed. + *
        + * + * @param None. + * @retval #NA + * @par Dependency: + *
        • los_trace.h: the header file that contains the API declaration.
        + * @see LOS_TraceReset + */ +extern VOID LOS_TraceReset(VOID); + +/** + * @ingroup los_trace + * @brief Set trace event mask. + * + * @par Description: + * Set trace event mask. + * @attention + *
          + *
        • Set trace event filter mask.
        • + *
        • The Default mask is (TRACE_HWI_FLAG | TRACE_TASK_FLAG), stands for switch on task and hwi events.
        • + *
        • Customize mask according to the type defined in enum LOS_TRACE_MASK to switch on corresponding module's + * trace.
        • + *
        • The system's trace mask will be overrode by the input parameter.
        • + *
        + * + * @param mask [IN] Type #UINT32. The mask used to filter events of LOS_TRACE_MASK. + * @retval #NA. + * @par Dependency: + *
        • los_trace.h: the header file that contains the API declaration.
        + * @see LOS_TraceEventMaskSet + */ +extern VOID LOS_TraceEventMaskSet(UINT32 mask); + +/** + * @ingroup los_trace + * @brief Offline trace buffer display. + * + * @par Description: + * Display trace buf data only at offline mode. + * @attention + *
          + *
        • This API can be called only after that trace stopped. Otherwise the trace dump will be failed.
        • + *
        • Trace data will be send to pipeline when user set toClient = TRUE. Otherwise it will be formatted and printed + * out.
        • + *
        + * + * @param toClient [IN] Type #BOOL. Whether send trace data to Client through pipeline. + * @retval #NA + * + * @par Dependency: + *
        • los_trace.h: the header file that contains the API declaration.
        + * @see LOS_TraceRecordDump + */ +extern VOID LOS_TraceRecordDump(BOOL toClient); + +/** + * @ingroup los_trace + * @brief Offline trace buffer export. + * + * @par Description: + * Return the trace buf only at offline mode. + * @attention + *
          + *
        • This API can be called only after that trace buffer has been established.
        • + *
        • The return buffer's address is a critical resource, user can only ready.
        • + *
        + * + * @param NA + * @retval #OfflineHead* The trace buffer's address, analyze this buffer according to the structure of + * OfflineHead. + * + * @par Dependency: + *
        • los_trace.h: the header file that contains the API declaration.
        + * @see LOS_TraceRecordGet + */ +extern OfflineHead *LOS_TraceRecordGet(VOID); + +/** + * @ingroup los_trace + * @brief Hwi num filter hook. + * + * @par Description: + * Hwi filter function. + * @attention + *
          + *
        • Filter the hwi events by hwi num
        • + *
        + * + * @param hook [IN] Type #TRACE_HWI_FILTER_HOOK. The user defined hook for hwi num filter, + * the hook should return true if you don't want trace this hwi num. + * @retval #None + * @par Dependency: + *
        • los_trace.h: the header file that contains the API declaration.
        + * @see LOS_TraceHwiFilterHookReg + */ +extern VOID LOS_TraceHwiFilterHookReg(TRACE_HWI_FILTER_HOOK hook); +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_TRACE_H */ diff --git a/src/kernel_liteos_a/kernel/include/los_typedef.h b/src/kernel_liteos_a/kernel/include/los_typedef.h new file mode 100644 index 00000000..7c47e9a0 --- /dev/null +++ b/src/kernel_liteos_a/kernel/include/los_typedef.h @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_typedef Type define + * @ingroup kernel + */ + +#ifndef _LOS_TYPEDEF_H +#define _LOS_TYPEDEF_H +#include "stddef.h" +#include "stdbool.h" +#include "stdint.h" +#include "los_builddef.h" +#include "los_toolchain.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define OS_STRING(x) #x +#define X_STRING(x) OS_STRING(x) + +/* type definitions */ +typedef unsigned char UINT8; +typedef unsigned short UINT16; +typedef unsigned int UINT32; +typedef signed char INT8; +typedef signed short INT16; +typedef signed int INT32; +typedef float FLOAT; +typedef double DOUBLE; +typedef char CHAR; + +#ifdef __LP64__ +typedef long unsigned int UINT64; +typedef long signed int INT64; +typedef unsigned long UINTPTR; +typedef signed long INTPTR; +#else +typedef unsigned long long UINT64; +typedef signed long long INT64; +typedef unsigned int UINTPTR; +typedef signed int INTPTR; +#endif + +#ifdef __LP64__ +typedef __uint128_t UINT128; +typedef INT64 ssize_t; +typedef UINT64 size_t; +#define LOSCFG_AARCH64 +#else +typedef INT32 ssize_t; +typedef UINT32 size_t; +#endif + +typedef UINTPTR AARCHPTR; +typedef size_t BOOL; + +#define VOID void +#define STATIC static + +#ifndef FALSE +#define FALSE 0U +#endif + +#ifndef TRUE +#define TRUE 1U +#endif + +#ifndef NULL +#define NULL ((VOID *)0) +#endif + +#define OS_NULL_BYTE ((UINT8)0xFF) +#define OS_NULL_SHORT ((UINT16)0xFFFF) +#define OS_NULL_INT ((UINT32)0xFFFFFFFF) + +#ifndef USER +#define USER +#endif + +#ifndef LOS_OK +#define LOS_OK 0 +#endif + +#ifndef LOS_NOK +#define LOS_NOK 1 +#endif + +#ifndef LOS_EPERM +#define LOS_EPERM 1 +#endif + +#ifndef LOS_ESRCH +#define LOS_ESRCH 3 +#endif + +#ifndef LOS_EINTR +#define LOS_EINTR 4 +#endif + +#ifndef LOS_EBADF +#define LOS_EBADF 9 +#endif + +#ifndef LOS_ECHILD +#define LOS_ECHILD 10 +#endif + +#ifndef LOS_EAGAIN +#define LOS_EAGAIN 11 +#endif + +#ifndef LOS_ENOMEM +#define LOS_ENOMEM 12 +#endif + +#ifndef LOS_EACCES +#define LOS_EACCES 13 +#endif + +#ifndef LOS_EFAULT +#define LOS_EFAULT 14 +#endif + +#ifndef LOS_EBUSY +#define LOS_EBUSY 16 +#endif + +#ifndef LOS_EINVAL +#define LOS_EINVAL 22 +#endif + +#ifndef LOS_EDEADLK +#define LOS_EDEADLK 35 +#endif + +#ifndef LOS_EOPNOTSUPP +#define LOS_EOPNOTSUPP 95 +#endif + +#ifndef LOS_ETIMEDOUT +#define LOS_ETIMEDOUT 110 +#endif + +#define OS_FAIL 1 +#define OS_ERROR (UINT32)(-1) +#define OS_INVALID (UINT32)(-1) +#define OS_INVALID_VALUE ((UINT32)0xFFFFFFFF) +#define OS_64BIT_MAX 0xFFFFFFFFFFFFFFFFULL + +#define asm __asm +#ifdef typeof +#undef typeof +#endif +#define typeof __typeof__ + +#ifndef LOS_LABEL_DEFN +#define LOS_LABEL_DEFN(label) label +#endif + +#ifndef LOSARC_ALIGNMENT +#define LOSARC_ALIGNMENT 8 +#endif +/* And corresponding power of two alignment */ +#ifndef LOSARC_P2ALIGNMENT +#ifdef LOSCFG_AARCH64 +#define LOSARC_P2ALIGNMENT 3 +#else +#define LOSARC_P2ALIGNMENT 2 +#endif +#endif + +typedef int status_t; +typedef unsigned long vaddr_t; +typedef unsigned long PADDR_T; +typedef unsigned long VADDR_T; +typedef unsigned long paddr_t; +typedef unsigned long DMA_ADDR_T; +typedef unsigned long ADDR_T; +typedef unsigned long VM_OFFSET_T; +typedef unsigned long PTE_T; +typedef unsigned int ULONG_T; +typedef int STATUS_T; + +/* Give a type or object explicit minimum alignment */ +#if !defined(LOSBLD_ATTRIB_ALIGN) +#define LOSBLD_ATTRIB_ALIGN(__align__) __attribute__((aligned(__align__))) +#endif + +/* Assign a defined variable to a specific section */ +#if !defined(LOSBLD_ATTRIB_SECTION) +#define LOSBLD_ATTRIB_SECTION(__sect__) __attribute__((section(__sect__))) +#endif + +/* + * Tell the compiler not to throw away a variable or function. Only known + * available on 3.3.2 or above. Old version's didn't throw them away, + * but using the unused attribute should stop warnings. + */ +#define LOSBLD_ATTRIB_USED __attribute__((used)) + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_TYPEDEF_H */ diff --git a/src/kernel_liteos_a/kernel/user/BUILD.gn b/src/kernel_liteos_a/kernel/user/BUILD.gn new file mode 100644 index 00000000..922f2db4 --- /dev/null +++ b/src/kernel_liteos_a/kernel/user/BUILD.gn @@ -0,0 +1,64 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_name = "userinit" +kernel_module(module_name) { + sources = [ "src/los_user_init.c" ] + + include_dirs = [ + "include", + "$LITEOSTOPDIR/syscall", + ] +} + +config("public") { +} + +userinit = "lib$module_name.O" +executable(userinit) { + output_dir = target_out_dir + deps = [ ":$module_name" ] + ldflags = [ + "-nostdlib", + "-static", + "-Wl,-r", + ] +} + +copy("copy_userinit") { + deps = [ ":$userinit" ] + sources = [ "$target_out_dir/unstripped/bin/$userinit" ] + outputs = [ "$root_out_dir/$userinit" ] +} + +group("user") { + deps = [ ":copy_userinit" ] +} diff --git a/src/kernel_liteos_a/kernel/user/Makefile b/src/kernel_liteos_a/kernel/user/Makefile new file mode 100644 index 00000000..3136ff5b --- /dev/null +++ b/src/kernel_liteos_a/kernel/user/Makefile @@ -0,0 +1,55 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := userinit + +LOCAL_INCLUDE := \ + -I $(LITEOSTOPDIR)/syscall \ + -I include + +LOCAL_SRCS := $(wildcard src/*.c) \ + $(wildcard src/*.S) + +LOCAL_FLAGS := $(LOCAL_INCLUDE) + +include $(MODULE) + +USERINIT := $(OUT)/lib/lib$(MODULE_NAME).O + +$(USERINIT): $(TARGET) + $(HIDE)$(LD) -r -o $@ --whole-archive $< --no-whole-archive + +clean_userinit: + $(HIDE)$(RM) $(USERINIT) + +all: $(USERINIT) +clean: clean_userinit +.PHONY: clean_userinit diff --git a/src/kernel_liteos_a/kernel/user/include/los_user_init.h b/src/kernel_liteos_a/kernel/user/include/los_user_init.h new file mode 100644 index 00000000..225ccbe3 --- /dev/null +++ b/src/kernel_liteos_a/kernel/user/include/los_user_init.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_USER_INIT_H +#define _LOS_USER_INIT_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#ifndef LITE_USER_SEC_TEXT +#define LITE_USER_SEC_TEXT __attribute__((section(".user.text"))) +#endif + +#ifndef LITE_USER_SEC_ENTRY +#define LITE_USER_SEC_ENTRY __attribute__((section(".user.entry"))) +#endif + +#ifndef LITE_USER_SEC_DATA +#define LITE_USER_SEC_DATA __attribute__((section(".user.data"))) +#endif + +#ifndef LITE_USER_SEC_RODATA +#define LITE_USER_SEC_RODATA __attribute__((section(".user.rodata"))) +#endif + +#ifndef LITE_USER_SEC_BSS +#define LITE_USER_SEC_BSS __attribute__((section(".user.bss"))) +#endif + + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/src/kernel_liteos_a/kernel/user/src/los_user_init.c b/src/kernel_liteos_a/kernel/user/src/los_user_init.c new file mode 100644 index 00000000..bd36882d --- /dev/null +++ b/src/kernel_liteos_a/kernel/user/src/los_user_init.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_user_init.h" +#include "los_syscall.h" + +#ifdef LOSCFG_KERNEL_SYSCALL + +#define SYS_CALL_VALUE 0x900001 + +#ifdef LOSCFG_QUICK_START +LITE_USER_SEC_RODATA STATIC CHAR *g_initPath = "/dev/shm/init"; +#else +LITE_USER_SEC_RODATA STATIC CHAR *g_initPath = "/bin/init"; +#endif + +LITE_USER_SEC_TEXT STATIC UINT32 sys_call3(UINT32 nbr, UINT32 parm1, UINT32 parm2, UINT32 parm3) +{ + register UINT32 reg7 __asm__("r7") = (UINT32)(nbr); + register UINT32 reg2 __asm__("r2") = (UINT32)(parm3); + register UINT32 reg1 __asm__("r1") = (UINT32)(parm2); + register UINT32 reg0 __asm__("r0") = (UINT32)(parm1); + + __asm__ __volatile__ + ( + "svc %1" + : "=r"(reg0) + : "i"(SYS_CALL_VALUE), "r"(reg7), "r"(reg0), "r"(reg1), "r"(reg2) + : "memory", "r14" + ); + + return reg0; +} + +LITE_USER_SEC_ENTRY VOID OsUserInit(VOID *args) +{ +#ifdef LOSCFG_KERNEL_DYNLOAD + sys_call3(__NR_execve, (UINTPTR)g_initPath, 0, 0); +#endif + while (true) { + } +} +#endif diff --git a/src/kernel_liteos_a/lib/BUILD.gn b/src/kernel_liteos_a/lib/BUILD.gn new file mode 100644 index 00000000..03142ff2 --- /dev/null +++ b/src/kernel_liteos_a/lib/BUILD.gn @@ -0,0 +1,50 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +group("lib") { + deps = [ + "libc", + "libmbedtls", + "libscrew", + "libsec", + "zlib", + ] +} + +config("public") { + configs = [ + "libc:public", + "libmbedtls:public", + "libscrew:public", + "libsec:public", + "zlib:public", + ] +} diff --git a/src/kernel_liteos_a/lib/Kconfig b/src/kernel_liteos_a/lib/Kconfig new file mode 100644 index 00000000..d9f3b54e --- /dev/null +++ b/src/kernel_liteos_a/lib/Kconfig @@ -0,0 +1,29 @@ +menu "Lib" +config LIB_LIBC + bool "Enable Libc" + default y + help + Answer Y to enable libc for full code. + +choice + prompt "choose libc" + default LIBC_MUSL + depends on LIB_LIBC + help + Choose libc. + +config LIBC_NEWLIB + bool "newlibc" + +config LIBC_MUSL + bool "musl libc" +endchoice + +config LIB_ZLIB + bool "Enable Zlib" + default y + depends on LIB_LIBC + help + Answer Y to enable LiteOS support compress file library. +endmenu + diff --git a/src/kernel_liteos_a/lib/libc/BUILD.gn b/src/kernel_liteos_a/lib/libc/BUILD.gn new file mode 100644 index 00000000..d61e4185 --- /dev/null +++ b/src/kernel_liteos_a/lib/libc/BUILD.gn @@ -0,0 +1,44 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +group("libc") { + deps = [ + "musl", + "newlib", + ] +} + +config("public") { + configs = [ + "musl:public", + "newlib:public", + ] +} diff --git a/src/kernel_liteos_a/lib/libc/musl/BUILD.gn b/src/kernel_liteos_a/lib/libc/musl/BUILD.gn new file mode 100644 index 00000000..0fdde2b3 --- /dev/null +++ b/src/kernel_liteos_a/lib/libc/musl/BUILD.gn @@ -0,0 +1,119 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") +import("$THIRDPARTY_MUSL_DIR/porting/liteos_a/kernel/musl.gni") +import("$THIRDPARTY_OPTIMIZED_ROUTINES_DIR/optimized-routines.gni") + +module_switch = defined(LOSCFG_LIBC_MUSL) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = MUSL_SRC_COMMON + + if (defined(LOSCFG_ARCH_ARM_AARCH32)) { + sources += MUSL_SRC_ARM + foreach(f, MUSL_SRC_ARM) { + sources -= [ string_replace(f, "/arm/", "/") ] + } + } + + if (LOSCFG_ARCH_ARM_VER == "armv7-a") { + sources -= [ + "$MUSLPORTINGDIR/src/string/memchr.c", + "$MUSLPORTINGDIR/src/string/memcpy.c", + "$MUSLPORTINGDIR/src/string/strcmp.c", + "$MUSLPORTINGDIR/src/string/strcpy.c", + "$MUSLPORTINGDIR/src/string/strlen.c", + ] + sources += [ + "src/arch/arm/memcmp.S", + "src/arch/arm/memset.S", + ] + sources += OPTRT_STRING_ARM_SRC_FILES_FOR_ARMV7_A + asmflags = [ + "-D__strlen_armv6t2=strlen", + "-D__strcmp_arm=strcmp", + "-D__memchr_arm=memchr", + ] + if (defined(LOSCFG_KERNEL_LMS)) { + asmflags += [ + "-D__memcpy_arm=__memcpy", + "-D__strcpy_arm=__strcpy", + ] + } else { + asmflags += [ + "-D__memcpy_arm=memcpy", + "-D__strcpy_arm=strcpy", + ] + } + } else { + # arch is not armv7-a + sources += [ + "src/memcmp.c", + "src/memset.c", + ] + } + + include_dirs = [ + "$MUSLPORTINGDIR/src/include", + "$MUSLPORTINGDIR/src/internal", + ] + + public_configs = [ ":public" ] + configs += [ ":private" ] +} + +config("public") { + cflags = [ + "-isystem", + rebase_path("$MUSLPORTINGDIR/include"), + ] +} + +config("private") { + if (defined(LOSCFG_COMPILER_CLANG_LLVM)) { + cflags = [ + "-Wno-char-subscripts", + "-Wno-ignored-pragmas", + "-Wno-strict-prototypes", + ] + } else { + cflags = [ + "-frounding-math", + "-Wno-unused-but-set-variable", + ] + } + + cflags += [ + "-Wno-shift-op-parentheses", + "-Wno-logical-op-parentheses", + "-Wno-bitwise-op-parentheses", + "-Wno-unknown-pragmas", + ] +} diff --git a/src/kernel_liteos_a/lib/libc/musl/Makefile b/src/kernel_liteos_a/lib/libc/musl/Makefile new file mode 100644 index 00000000..bb7fc68f --- /dev/null +++ b/src/kernel_liteos_a/lib/libc/musl/Makefile @@ -0,0 +1,69 @@ +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := c + +TOPDIR = $(LITEOSTOPDIR)/../.. +MUSLDIR = $(TOPDIR)/third_party/musl +MUSLPORTINGDIR = $(MUSLDIR)/porting/liteos_a/kernel +OPTRTDIR = $(TOPDIR)/third_party/optimized-routines + +MUSL_SRCS = +LOCAL_OPT_DIR = src/arch/$(ARCH) +LOCAL_OPT_SRCS = +LOCAL_FILTER_SRCS = + +MUSLPORTING_SRCS = \ + src/*/$(ARCH)/*.[csS] \ + src/*/*.c + +LOCAL_SRCS = $(wildcard $(addprefix $(MUSLPORTINGDIR)/,$(MUSLPORTING_SRCS))) +LOCAL_SRCS := $(filter-out $(subst $(MUSLPORTINGDIR),$(MUSLDIR),$(LOCAL_SRCS)),$(addprefix $(MUSLDIR)/,$(MUSL_SRCS)) $(LOCAL_SRCS)) +LOCAL_SRCS += $(wildcard src/*.c src/*.S) +# Sources optimized for specific architectures +LOCAL_OPT_SRCS := $(wildcard $(LOCAL_OPT_DIR)/*.c, $(LOCAL_OPT_DIR)/*.S) +# Enumerate common src files with the same name as the optimized srcs +LOCAL_FILTER_SRCS := $(addprefix $(MUSLPORTINGDIR)/src/string/,$(subst $(LOCAL_OPT_DIR)/,,$(LOCAL_OPT_SRCS))) +LOCAL_FILTER_SRCS += $(addprefix src/,$(subst $(LOCAL_OPT_DIR)/,,$(LOCAL_OPT_SRCS))) +LOCAL_FILTER_SRCS := $(subst .S,.c, $(LOCAL_FILTER_SRCS)) + +ifeq ($(LOSCFG_ARCH_ARM_VER), "armv7-a") +LOCAL_SRCS := $(filter-out $(addprefix $(MUSLPORTINGDIR)/src/string/,memchr.c memcpy.c strcmp.c strcpy.c strlen.c), $(LOCAL_SRCS)) +LOCAL_SRCS += \ + $(OPTRTDIR)/string/arm/memchr.S \ + $(OPTRTDIR)/string/arm/memcpy.S \ + $(OPTRTDIR)/string/arm/strcmp.S \ + $(OPTRTDIR)/string/arm/strcpy.c \ + $(OPTRTDIR)/string/arm/strlen-armv6t2.S + +LOCAL_CMACRO = \ + -D__strlen_armv6t2=strlen \ + -D__strcmp_arm=strcmp \ + -D__memchr_arm=memchr + +ifeq ($(LOSCFG_KERNEL_LMS), y) +LOCAL_CMACRO += -D__memcpy_arm=__memcpy -D__strcpy_arm=__strcpy +else +LOCAL_CMACRO += -D__memcpy_arm=memcpy -D__strcpy_arm=strcpy +endif + +# Replace the general srcs of the same name with specially optimized srcs +LOCAL_SRCS += $(LOCAL_OPT_SRCS) +LOCAL_SRCS := $(filter-out $(LOCAL_FILTER_SRCS),$(LOCAL_SRCS)) +endif + +LOCAL_INCLUDE := \ + -I $(LITEOSTOPDIR)/syscall \ + -I $(LITEOSTOPDIR)/bsd/dev/random + +LOCAL_INCLUDE += $(addprefix -I$(MUSLPORTINGDIR)/, src/include src/internal) + +LOCAL_FLAGS := $(LOCAL_INCLUDE) $(LOCAL_CMACRO) +ifeq ($(LOSCFG_COMPILER_CLANG_LLVM), y) +LOCAL_FLAGS +=-Wno-char-subscripts -Wno-ignored-pragmas -Wno-strict-prototypes +else +LOCAL_FLAGS += -frounding-math -Wno-unused-but-set-variable +endif +LOCAL_FLAGS += -Wno-shift-op-parentheses -Wno-logical-op-parentheses -Wno-bitwise-op-parentheses -Wno-unknown-pragmas +LOCAL_FLAGS += -Wno-unused-but-set-variable + +include $(MODULE) diff --git a/src/kernel_liteos_a/lib/libc/musl/src/arch/arm/memcmp.S b/src/kernel_liteos_a/lib/libc/musl/src/arch/arm/memcmp.S new file mode 100644 index 00000000..ed077ada --- /dev/null +++ b/src/kernel_liteos_a/lib/libc/musl/src/arch/arm/memcmp.S @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + .syntax unified + .arch armv7-a + .fpu neon + .globl memcmp @ -- Begin function memcmp + .p2align 2 + .type memcmp,%function + .code 32 @memcmp +memcmp: + @ r0 = str1 + @ r1 = str2 + @ r2 = count + .fnstart + push {r4, r5, r6, r7, lr} + pld [r0, #0] + pld [r1, #0] + /** + * if (str1 == str2) || (n == 0) return; + */ + cmp r0, r1 + cmpne r2, #0 + beq Lreturn_0 + /** + * Determine whether the first byte is different. + */ + ldrb r3, [r0] @ r3 = *str1 + ldrb r4, [r1] @ r4 = *str2 + pld [r0, #64] + pld [r1, #64] + cmp r3, r4 + subne r0, r3, r4 + bne Lreturn + +/** + * Comparing 32 bytes each time, using floating-point registers to improve efficiency. + */ +L32_byte_cmp: + cmp r2, #32 + blo L16_byte_cmp + sub r2, r2, #32 + vld1.8 {d0 - d3}, [r0]! + vld1.8 {d4 - d7}, [r1]! + vsub.i8 q0, q0, q2 @ q0: Difference of the first 16 bytes + vsub.i8 q1, q1, q3 @ q1: Difference of the last 16 bytes + pld [r0, #64] + pld [r1, #64] + + vorr d4, d0, d1 @ d4: Save the result of calculating whether the first 16 bytes are equal. + vorr d5, d2, d3 @ d5: Save the result of calculating whether the last 16 bytes are equal. + vorr d6, d4, d5 @ d6: Save the result of 32 bytes calculation whether they are equal. + vmov r3, r4, d6 + orr r5, r3, r4 + cmp r5, #0 + beq L32_byte_cmp + +/** + * Going to the diff branch shows that a certain byte must be different at this time. + * We use r3 to indicate whether the first half of the multibytes are equal, + * and r4 to indicate whether the second half of the multibytes are equal. + */ +L32_byte_diff: + vmov r3, r4, d4 + orr r3, r3, r4 + /** + * Adjust the two pointers back. + */ + sub r0, #32 + sub r1, #32 + cmp r3, #0 + addeq r0, #16 + addeq r1, #16 + beq L16_byte_diff_back + vmov r3, r4, d0 + vmov r5, r6, d1 + b L16_byte_diff + +L16_byte_diff_back: + vmov r3, r4, d2 + vmov r5, r6, d3 + +L16_byte_diff: + orr r7, r3, r4 + cmp r7, #0 + addeq r0, #8 + addeq r1, #8 + beq L8_byte_diff_back + b L8_byte_diff + +L8_byte_diff_back: + mov r3, r5 + mov r4, r6 + +L8_byte_diff: + cmp r3, #0 + addeq r0, #4 + addeq r1, #4 + beq L4_byte_diff + +L4_byte_diff: + ldrb r5, [r0], #1 + ldrb r6, [r1], #1 + subs r5, r5, r6 + beq L4_byte_diff + mov r0, r5 + b Lreturn + +/** + * The dichotomy handles the case of less than 32 bytes. + */ +L16_byte_cmp: + cmp r2, #16 + blo L8_byte_cmp + sub r2, r2, #16 + vld1.8 {d0 - d1}, [r0]! + vld1.8 {d4 - d5}, [r1]! + vsub.i8 q0, q0, q2 + pld [r0, #64] + pld [r1, #64] + + vorr d4, d0, d1 + vmov r3, r4, d4 + orr r3, r3, r4 + cmp r3, #0 + beq L8_byte_cmp + sub r0, #16 + sub r1, #16 + vmov r3, r4, d0 + vmov r5, r6, d1 + b L16_byte_diff + +L8_byte_cmp: + cmp r2, #8 + blo L4_byte_cmp + sub r2, r2, #8 + vld1.8 {d0}, [r0]! + vld1.8 {d4}, [r1]! + vsub.i8 d0, d0, d4 + + vmov r3, r4, d0 + orr r7, r3, r4 + cmp r7, #0 + beq L4_byte_cmp + sub r0, #8 + sub r1, #8 + b L8_byte_diff + +L4_byte_cmp: + cmp r2, #4 + blo Lless_4_byte_cmp + sub r2, r2, #4 + ldr r3, [r0], #4 + ldr r4, [r1], #4 + cmp r3, r4 + beq Lless_4_byte_cmp + sub r0, #4 + sub r1, #4 + b L4_byte_diff + +Lless_4_byte_cmp: + cmp r2, #0 + beq Lreturn_0 + sub r2, r2, #1 + ldrb r3, [r0], #1 + ldrb r4, [r1], #1 + sub r5, r3, r4 + cmp r5, #0 + movne r0, r5 + bne Lreturn + b Lless_4_byte_cmp + +Lreturn_0: + mov r0, #0 +Lreturn: + pop {r4, r5, r6, r7, pc} +Lfunc_end: + .size memcmp, Lfunc_end - memcmp + .cantunwind + .fnend @ -- End function \ No newline at end of file diff --git a/src/kernel_liteos_a/lib/libc/musl/src/arch/arm/memset.S b/src/kernel_liteos_a/lib/libc/musl/src/arch/arm/memset.S new file mode 100644 index 00000000..60819cf6 --- /dev/null +++ b/src/kernel_liteos_a/lib/libc/musl/src/arch/arm/memset.S @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + .syntax unified + .arch armv7-a + .fpu neon + +#define FUNCTION(x) \ +.globl x; \ +.p2align 2; \ +.type x,%function; \ +x: + +#if defined(LOSCFG_KERNEL_LMS) +FUNCTION(__memset) +#else +FUNCTION(memset) +#endif + @ r0 = address + @ r1 = char + @ r2 = count + @ returns original address in r0 + .fnstart + + push {r4} + cmp r2, #0 + beq Lreturn + vdup.8 q0, r1 + mov r4, r0 @ r4 = r0 = address + +L64_byte_alignment: + ands r3, r0, #7 + beq L64_byte_aligned + rsb r3, r3, #8 @ r3 = unalignedCnt = 8 - (address % 7) + cmp r2, r3 + movlo r3, r2 + sub r2, r2, r3 + +Lloop1: + strb r1, [r4], #1 + subs r3, r3, #1 + bgt Lloop1 + +/** + * Set 64 bytes each time, and use floating-point registers to improve efficiency. + */ +L64_byte_aligned: + vmov q1, q0 + vmov q2, q0 + cmp r2, #64 + blo L32_byte_aligned + vmov q3, q0 + sub r2, r2, #64 +Lloop2: + vstmia r4!, {d0 - d7} + subs r2, r2, #64 + bgt Lloop2 + +/** + * The dichotomy handles the case of less than 64 bytes, + * and the front will subtract 64 more, and you need to make it up at this time. + */ + add r2, r2, #64 +L32_byte_aligned: + cmp r2, #0 + beq Lreturn + cmp r2, #32 + blo L16_byte_aligned + sub r2, r2, #32 + vstmia r4!, {d0 - d3} + +L16_byte_aligned: + cmp r2, #0 + beq Lreturn + cmp r2, #16 + blo L8_byte_aligned + sub r2, r2, #16 + vstmia r4!, {d0 - d1} + +L8_byte_aligned: + cmp r2, #0 + beq Lreturn + cmp r2, #8 + blo L4_byte_aligned + sub r2, r2, #8 + vstmia r4!, {d0} + +L4_byte_aligned: + cmp r2, #0 + beq Lreturn + cmp r2, #4 + blo Lless_4_byte + sub r2, r2, #4 + vst1.32 {d0[0]}, [r4]! + +Lless_4_byte: + cmp r2, #0 + beq Lreturn + strb r1, [r4], #1 + sub r2, r2, #1 + b Lless_4_byte + +Lreturn: + pop {r4} + bx lr +Lfunc_end: +#if defined(LOSCFG_KERNEL_LMS) + .size __memset, Lfunc_end - __memset +#else + .size memset, Lfunc_end - memset +#endif + .cantunwind + .fnend @ -- End function diff --git a/src/kernel_liteos_a/lib/libc/musl/src/memcmp.c b/src/kernel_liteos_a/lib/libc/musl/src/memcmp.c new file mode 100644 index 00000000..1583eff8 --- /dev/null +++ b/src/kernel_liteos_a/lib/libc/musl/src/memcmp.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +#define SIZE_U64 (sizeof(uint64_t)) +#define SIZE_U32 (sizeof(uint32_t)) + +int memcmp(const void *str1, const void *str2, size_t n) +{ + + const unsigned char *s1 = str1; + const unsigned char *s2 = str2; + size_t num = n; + + while (num >= SIZE_U64) { + if (*(const uint64_t *)(s1) != *(const uint64_t *)(s2)) { + goto L4_byte_cmp; + } + s1 += SIZE_U64; + s2 += SIZE_U64; + num -= SIZE_U64; + } + if (num == 0) { + return 0; + } + +L4_byte_cmp: + if (num >= SIZE_U32) { + if (*(const uint32_t *)(s1) != *(const uint32_t *)(s2)) { + goto L4_byte_diff; + } + s1 += SIZE_U32; + s2 += SIZE_U32; + num -= SIZE_U32; + } + if (num == 0) { + return 0; + } +L4_byte_diff: + for (; num && (*s1 == *s2); num--, s1++, s2++) { + } + return num ? *s1 - *s2 : 0; +} \ No newline at end of file diff --git a/src/kernel_liteos_a/lib/libc/musl/src/memset.c b/src/kernel_liteos_a/lib/libc/musl/src/memset.c new file mode 100644 index 00000000..8bf07fc9 --- /dev/null +++ b/src/kernel_liteos_a/lib/libc/musl/src/memset.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +void *memset(void *dest, int c, size_t n) +{ + char *pos = dest; + uint32_t c32 = 0; + uint64_t c64 = 0; + size_t num = n; + + if (num == 0) { + return dest; + } + + c = c & 0xFF; + if (c) { + c32 = c; + c32 |= c32 << 8; /* 8, Processed bits */ + c32 |= c32 << 16; /* 16, Processed bits */ + c64 = c32; + c64 |= c64 << 32; /* 32, Processed bits */ + } + + if (((uintptr_t)(pos) & 7) != 0) { /* 7, Processed align */ + int unalignedCnt = 8 - ((uintptr_t)(pos) & 7); /* 7, 8, for calculate addr bits align */ + if (num >= unalignedCnt) { + num = num - unalignedCnt; + } else { + unalignedCnt = num; + num = 0; + } + for (int loop = 1; loop <= unalignedCnt; ++loop) { + *pos = (char)c; + pos++; + } + } + + /* L32_byte_aligned */ + while (num >= 32) { /* 32, byte aligned */ + *(uint64_t *)(pos) = c64; + *(uint64_t *)(pos + 8) = c64; /* 8, size of uint64_t */ + *(uint64_t *)(pos + 16) = c64; /* 16, size of two uint64_t data */ + *(uint64_t *)(pos + 24) = c64; /* 24, size of three uint64_t data */ + num -= 32; /* 32, size of four uint64_t data */ + pos += 32; /* 32, size of four uint64_t data */ + } + if (num == 0) { + return dest; + } + + /* L16_byte_aligned */ + if (num >= 16) { /* 16, byte aligned */ + *(uint64_t *)(pos) = c64; + *(uint64_t *)(pos + 8) = c64; /* 8, size of uint64_t */ + num -= 16; /* 16, size of two uint64_t data */ + pos += 16; /* 16, size of two uint64_t data */ + if (num == 0) { + return dest; + } + } + + /* L8_byte_aligned */ + if (num >= 8) { /* 8, byte aligned */ + *(uint64_t *)(pos) = c64; + num -= 8; /* 8, size of uint64_t */ + pos += 8; /* 8, size of uint64_t */ + if (num == 0) { + return dest; + } + } + + /* L4_byte_aligned */ + if (num >= 4) { /* 4, byte aligned */ + *(uint32_t *)(pos) = c32; + num -= 4; /* 4, size of uint32_t */ + pos += 4; /* 4, size of uint32_t */ + if (num == 0) { + return dest; + } + } + while (num--) { + *pos++ = c; + } + + return dest; +} \ No newline at end of file diff --git a/src/kernel_liteos_a/lib/libc/newlib/BUILD.gn b/src/kernel_liteos_a/lib/libc/newlib/BUILD.gn new file mode 100644 index 00000000..7560d4fc --- /dev/null +++ b/src/kernel_liteos_a/lib/libc/newlib/BUILD.gn @@ -0,0 +1,58 @@ +# Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") +import("$THIRDPARTY_MUSL_DIR/porting/liteos_a_newlib/kernel/newlib.gni") + +module_switch = defined(LOSCFG_LIBC_NEWLIB) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = NEWLIB_ADAPT_SRC_COMMON + configs += [ "$LITEOSTOPDIR:warn_config" ] + + configs += [ ":private" ] +} + +config("public") { + include_dirs = [ "porting/include" ] + include_dirs += NEWLIB_ADAPT_INCLUDE_DIRS +} + +config("private") { + cflags = [ + "-frounding-math", + "-Wno-unused-but-set-variable", + "-Wno-unknown-pragmas", + ] + + cflags += [ + "-Wno-shift-op-parentheses", + "-Wno-logical-op-parentheses", + "-Wno-bitwise-op-parentheses", + ] +} diff --git a/src/kernel_liteos_a/lib/libmbedtls/BUILD.gn b/src/kernel_liteos_a/lib/libmbedtls/BUILD.gn new file mode 100644 index 00000000..d9aa20af --- /dev/null +++ b/src/kernel_liteos_a/lib/libmbedtls/BUILD.gn @@ -0,0 +1,122 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = defined(LOSCFG_DRIVERS_TZDRIVER) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ + "$LITEOSTHIRDPARTY/mbedtls/library/aes.c", + "$LITEOSTHIRDPARTY/mbedtls/library/aesni.c", + "$LITEOSTHIRDPARTY/mbedtls/library/arc4.c", + "$LITEOSTHIRDPARTY/mbedtls/library/aria.c", + "$LITEOSTHIRDPARTY/mbedtls/library/asn1parse.c", + "$LITEOSTHIRDPARTY/mbedtls/library/asn1write.c", + "$LITEOSTHIRDPARTY/mbedtls/library/base64.c", + "$LITEOSTHIRDPARTY/mbedtls/library/bignum.c", + "$LITEOSTHIRDPARTY/mbedtls/library/blowfish.c", + "$LITEOSTHIRDPARTY/mbedtls/library/camellia.c", + "$LITEOSTHIRDPARTY/mbedtls/library/ccm.c", + "$LITEOSTHIRDPARTY/mbedtls/library/certs.c", + "$LITEOSTHIRDPARTY/mbedtls/library/chacha20.c", + "$LITEOSTHIRDPARTY/mbedtls/library/chachapoly.c", + "$LITEOSTHIRDPARTY/mbedtls/library/cipher.c", + "$LITEOSTHIRDPARTY/mbedtls/library/cipher_wrap.c", + "$LITEOSTHIRDPARTY/mbedtls/library/cmac.c", + "$LITEOSTHIRDPARTY/mbedtls/library/ctr_drbg.c", + "$LITEOSTHIRDPARTY/mbedtls/library/debug.c", + "$LITEOSTHIRDPARTY/mbedtls/library/des.c", + "$LITEOSTHIRDPARTY/mbedtls/library/dhm.c", + "$LITEOSTHIRDPARTY/mbedtls/library/ecdh.c", + "$LITEOSTHIRDPARTY/mbedtls/library/ecdsa.c", + "$LITEOSTHIRDPARTY/mbedtls/library/ecjpake.c", + "$LITEOSTHIRDPARTY/mbedtls/library/ecp.c", + "$LITEOSTHIRDPARTY/mbedtls/library/ecp_curves.c", + "$LITEOSTHIRDPARTY/mbedtls/library/entropy.c", + "$LITEOSTHIRDPARTY/mbedtls/library/entropy_poll.c", + "$LITEOSTHIRDPARTY/mbedtls/library/error.c", + "$LITEOSTHIRDPARTY/mbedtls/library/gcm.c", + "$LITEOSTHIRDPARTY/mbedtls/library/havege.c", + "$LITEOSTHIRDPARTY/mbedtls/library/hkdf.c", + "$LITEOSTHIRDPARTY/mbedtls/library/hmac_drbg.c", + "$LITEOSTHIRDPARTY/mbedtls/library/md.c", + "$LITEOSTHIRDPARTY/mbedtls/library/md2.c", + "$LITEOSTHIRDPARTY/mbedtls/library/md4.c", + "$LITEOSTHIRDPARTY/mbedtls/library/md5.c", + "$LITEOSTHIRDPARTY/mbedtls/library/md_wrap.c", + "$LITEOSTHIRDPARTY/mbedtls/library/memory_buffer_alloc.c", + "$LITEOSTHIRDPARTY/mbedtls/library/net_sockets.c", + "$LITEOSTHIRDPARTY/mbedtls/library/nist_kw.c", + "$LITEOSTHIRDPARTY/mbedtls/library/oid.c", + "$LITEOSTHIRDPARTY/mbedtls/library/padlock.c", + "$LITEOSTHIRDPARTY/mbedtls/library/pem.c", + "$LITEOSTHIRDPARTY/mbedtls/library/pk.c", + "$LITEOSTHIRDPARTY/mbedtls/library/pk_wrap.c", + "$LITEOSTHIRDPARTY/mbedtls/library/pkcs11.c", + "$LITEOSTHIRDPARTY/mbedtls/library/pkcs12.c", + "$LITEOSTHIRDPARTY/mbedtls/library/pkcs5.c", + "$LITEOSTHIRDPARTY/mbedtls/library/pkparse.c", + "$LITEOSTHIRDPARTY/mbedtls/library/pkwrite.c", + "$LITEOSTHIRDPARTY/mbedtls/library/platform.c", + "$LITEOSTHIRDPARTY/mbedtls/library/platform_util.c", + "$LITEOSTHIRDPARTY/mbedtls/library/poly1305.c", + "$LITEOSTHIRDPARTY/mbedtls/library/ripemd160.c", + "$LITEOSTHIRDPARTY/mbedtls/library/rsa.c", + "$LITEOSTHIRDPARTY/mbedtls/library/rsa_internal.c", + "$LITEOSTHIRDPARTY/mbedtls/library/sha1.c", + "$LITEOSTHIRDPARTY/mbedtls/library/sha256.c", + "$LITEOSTHIRDPARTY/mbedtls/library/sha512.c", + "$LITEOSTHIRDPARTY/mbedtls/library/ssl_cache.c", + "$LITEOSTHIRDPARTY/mbedtls/library/ssl_ciphersuites.c", + "$LITEOSTHIRDPARTY/mbedtls/library/ssl_cli.c", + "$LITEOSTHIRDPARTY/mbedtls/library/ssl_cookie.c", + "$LITEOSTHIRDPARTY/mbedtls/library/ssl_srv.c", + "$LITEOSTHIRDPARTY/mbedtls/library/ssl_ticket.c", + "$LITEOSTHIRDPARTY/mbedtls/library/ssl_tls.c", + "$LITEOSTHIRDPARTY/mbedtls/library/threading.c", + "$LITEOSTHIRDPARTY/mbedtls/library/timing.c", + "$LITEOSTHIRDPARTY/mbedtls/library/version.c", + "$LITEOSTHIRDPARTY/mbedtls/library/version_features.c", + "$LITEOSTHIRDPARTY/mbedtls/library/x509.c", + "$LITEOSTHIRDPARTY/mbedtls/library/x509_create.c", + "$LITEOSTHIRDPARTY/mbedtls/library/x509_crl.c", + "$LITEOSTHIRDPARTY/mbedtls/library/x509_crt.c", + "$LITEOSTHIRDPARTY/mbedtls/library/x509_csr.c", + "$LITEOSTHIRDPARTY/mbedtls/library/x509write_crt.c", + "$LITEOSTHIRDPARTY/mbedtls/library/x509write_csr.c", + "$LITEOSTHIRDPARTY/mbedtls/library/xtea.c", + ] + + public_configs = [ ":public" ] +} + +config("public") { + include_dirs = [ "$LITEOSTHIRDPARTY/mbedtls/include" ] +} diff --git a/src/kernel_liteos_a/lib/libmbedtls/Makefile b/src/kernel_liteos_a/lib/libmbedtls/Makefile new file mode 100644 index 00000000..dd0f6f06 --- /dev/null +++ b/src/kernel_liteos_a/lib/libmbedtls/Makefile @@ -0,0 +1,8 @@ +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := mbedtls +LOCAL_SRCS := $(wildcard $(LITEOSTOPDIR)/../../third_party/mbedtls/library/*.c) +LOCAL_INCLUDE := -I$(LITEOSTOPDIR)/../../third_party/mbedtls/include/ +LOCAL_FLAGS := $(LOCAL_INCLUDE) + +include $(MODULE) diff --git a/src/kernel_liteos_a/lib/libscrew/BUILD.gn b/src/kernel_liteos_a/lib/libscrew/BUILD.gn new file mode 100644 index 00000000..691915b0 --- /dev/null +++ b/src/kernel_liteos_a/lib/libscrew/BUILD.gn @@ -0,0 +1,49 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") +import("$THIRDPARTY_FREEBSD_DIR/FreeBSD.gni") + +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ + "src/los_cir_buf.c", + "src/los_crc32.c", + "src/los_rbtree.c", + "src/los_seq_buf.c", + ] + + sources += FREEBSD_SYS_LIBKERN_SRC_FILES + + public_configs = [ ":public" ] +} + +config("public") { + include_dirs = [ "include" ] +} diff --git a/src/kernel_liteos_a/lib/libscrew/Makefile b/src/kernel_liteos_a/lib/libscrew/Makefile new file mode 100644 index 00000000..2fbea2e2 --- /dev/null +++ b/src/kernel_liteos_a/lib/libscrew/Makefile @@ -0,0 +1,9 @@ +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := screw + +LOCAL_SRCS := \ + $(wildcard src/*.c) \ + $(LITEOSTOPDIR)/../../third_party/FreeBSD/sys/libkern/crc32.c + +include $(MODULE) diff --git a/src/kernel_liteos_a/lib/libscrew/include/los_cir_buf.h b/src/kernel_liteos_a/lib/libscrew/include/los_cir_buf.h new file mode 100644 index 00000000..62def915 --- /dev/null +++ b/src/kernel_liteos_a/lib/libscrew/include/los_cir_buf.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_CIRBUF_PRI_H +#define _LOS_CIRBUF_PRI_H + +#include "los_typedef.h" +#include "los_spinlock.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef enum { + CBUF_UNUSED, + CBUF_USED +} CirBufStatus; + +typedef struct { + UINT32 startIdx; + UINT32 endIdx; + UINT32 size; + UINT32 remain; + SPIN_LOCK_S lock; + CirBufStatus status; + CHAR *fifo; +} CirBuf; + +extern UINT32 LOS_CirBufInit(CirBuf *cirbufCB, CHAR *fifo, UINT32 size); +extern VOID LOS_CirBufDeinit(CirBuf *cirbufCB); +extern UINT32 LOS_CirBufWrite(CirBuf *cirbufCB, const CHAR *buf, UINT32 size); +extern UINT32 LOS_CirBufRead(CirBuf *cirbufCB, CHAR *buf, UINT32 size); +extern UINT32 LOS_CirBufUsedSize(CirBuf *cirbufCB); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_CIRBUF_PRI_H */ diff --git a/src/kernel_liteos_a/lib/libscrew/include/los_crc32.h b/src/kernel_liteos_a/lib/libscrew/include/los_crc32.h new file mode 100644 index 00000000..7101e2d1 --- /dev/null +++ b/src/kernel_liteos_a/lib/libscrew/include/los_crc32.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_CRC32_H +#define _LOS_CRC32_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ +extern UINT32 LOS_EtherCrc32Accumulate(UINT32 val, UINT8 *src, INT32 len); +extern UINT32 LOS_Crc32Accumulate(UINT32 val, UINT8 *src, INT32 len); +extern const UINT32 crc32_tab[]; + +#define crc32(val, src, len) LOS_Crc32Accumulate(val, (UINT8 *)src, len) +#define ether_crc32(val, src, len) LOS_EtherCrc32Accumulate(val, (UINT8 *)src, len) + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif \ No newline at end of file diff --git a/src/kernel_liteos_a/lib/libscrew/include/los_rbtree.h b/src/kernel_liteos_a/lib/libscrew/include/los_rbtree.h new file mode 100644 index 00000000..7919f689 --- /dev/null +++ b/src/kernel_liteos_a/lib/libscrew/include/los_rbtree.h @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* * + * @defgroup los_rbtree Rbtree + * @ingroup kernel + */ + +#ifndef _LOS_RBTREE_H +#define _LOS_RBTREE_H + +#include "los_list.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define LOS_RB_RED 0 +#define LOS_RB_BLACK 1 + +typedef struct TagRbNode { + struct TagRbNode *pstParent; + struct TagRbNode *pstRight; + struct TagRbNode *pstLeft; + ULONG_T lColor; +} LosRbNode; + +typedef ULONG_T (*pfRBCmpKeyFn)(const VOID *, const VOID *); +typedef ULONG_T (*pfRBFreeFn)(LosRbNode *); +typedef VOID *(*pfRBGetKeyFn)(LosRbNode *); + +typedef struct TagRbTree { + LosRbNode *pstRoot; + LosRbNode stNilT; + LOS_DL_LIST stWalkHead; + ULONG_T ulNodes; + + pfRBCmpKeyFn pfCmpKey; + pfRBFreeFn pfFree; + pfRBGetKeyFn pfGetKey; +} LosRbTree; + +typedef struct TagRbWalk { + LOS_DL_LIST stLink; + LosRbNode *pstCurrNode; + struct TagRbTree *pstTree; +} LosRbWalk; + +#define RB_EQUAL (0) +#define RB_BIGGER (1) +#define RB_SMALLER (2) + +#define RB_SCAN(pstTree, pstNode) do { \ + (pstNode) = LOS_RbFirstNode((pstTree)); \ + for (; NULL != (pstNode); (pstNode) = LOS_RbSuccessorNode((pstTree), (pstNode))) { + +#define RB_SCAN_END(pstTree, pstNode) } \ + } \ + while (0); + +#define RB_SCAN_SAFE(pstTree, pstNode, pstNodeTemp) do { \ + (pstNode) = LOS_RbFirstNode((pstTree)); \ + (pstNodeTemp) = LOS_RbSuccessorNode((pstTree), (pstNode)); \ + for (; NULL != (pstNode); (pstNode) = (pstNodeTemp), (pstNodeTemp) = LOS_RbSuccessorNode((pstTree), (pstNode))) { + +#define RB_SCAN_SAFE_END(pstTree, pstNode, pstNodeTemp) } \ + } \ + while (0); + +#define RB_MID_SCAN(pstTree, pstNode) do { \ + for (; NULL != (pstNode); (pstNode) = LOS_RbSuccessorNode((pstTree), (pstNode))) { + +#define RB_MID_SCAN_END(pstTree, pstNode) } \ + } \ + while (0); + +#define RB_WALK(pstTree, pstNode, pstRbWalk) do { \ + LosRbWalk *(pstRbWalk) = NULL; \ + pstRbWalk = LOS_RbCreateWalk(pstTree); \ + (pstNode) = LOS_RbWalkNext(pstRbWalk); \ + for (; NULL != (pstNode); (pstNode) = LOS_RbWalkNext(pstRbWalk)) { + +#define RB_WALK_END(pstTree, pstNode, pstRbWalk) } \ + LOS_RbDeleteWalk(pstRbWalk); \ + } \ + while (0); + +#define RB_WALK_TERMINATE(pstRbWalk) LOS_RbDeleteWalk(pstRbWalk); +#define RB_COUNT(pstTree) ((pstTree)->ulNodes) +#define RB_IS_NOT_NILT(pstX) ((NULL != (pstX)->pstLeft) && (NULL != (pstX)->pstRight)) + +VOID *LOS_RbFirstNode(LosRbTree *pstTree); +VOID *LOS_RbSuccessorNode(LosRbTree *pstTree, VOID *pstData); +VOID LOS_RbInitTree(LosRbTree *pstTree, pfRBCmpKeyFn pfCmpKey, pfRBFreeFn pfFree, pfRBGetKeyFn pfGetKey); +VOID LOS_RbDestroyTree(LosRbTree *pstTree); +LosRbNode *LOS_RbGetNextNode(LosRbTree *pstTree, VOID *pKey); +ULONG_T LOS_RbGetNode(LosRbTree *pstTree, VOID *pKey, LosRbNode **ppstNode); +VOID LOS_RbDelNode(LosRbTree *pstTree, LosRbNode *pstNode); +ULONG_T LOS_RbAddNode(LosRbTree *pstTree, LosRbNode *pstNew); + +/* Following 3 functions support protection walk. */ +LosRbWalk *LOS_RbCreateWalk(LosRbTree *pstTree); +VOID *LOS_RbWalkNext(LosRbWalk *pstWalk); +VOID LOS_RbDeleteWalk(LosRbWalk *pstWalk); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_RBTREE_H */ diff --git a/src/kernel_liteos_a/lib/libscrew/include/los_seq_buf.h b/src/kernel_liteos_a/lib/libscrew/include/los_seq_buf.h new file mode 100644 index 00000000..88e63fa2 --- /dev/null +++ b/src/kernel_liteos_a/lib/libscrew/include/los_seq_buf.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __LOS_SEQ_BUF_H__ +#define __LOS_SEQ_BUF_H__ + +#include "stdarg.h" +#include "stddef.h" + + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define SEQBUF_PAGE_SIZE 4096 +#define SEQBUF_LIMIT_SIZE (256 * SEQBUF_PAGE_SIZE) + +struct SeqBuf { + char *buf; + size_t size; + size_t count; + void *private; +}; + +struct SeqBuf *LosBufCreat(void); +int LosBufPrintf(struct SeqBuf *seqBuf, const char *fmt, ...); +int LosBufVprintf(struct SeqBuf *seqBuf, const char *fmt, va_list argList); +int LosBufRelease(struct SeqBuf *seqBuf); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/src/kernel_liteos_a/lib/libscrew/src/los_cir_buf.c b/src/kernel_liteos_a/lib/libscrew/src/los_cir_buf.c new file mode 100644 index 00000000..27462913 --- /dev/null +++ b/src/kernel_liteos_a/lib/libscrew/src/los_cir_buf.c @@ -0,0 +1,226 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_cir_buf.h" +#include "los_spinlock.h" + + +UINT32 LOS_CirBufUsedSize(CirBuf *cirbufCB) +{ + UINT32 size; + UINT32 intSave; + + LOS_SpinLockSave(&cirbufCB->lock, &intSave); + size = cirbufCB->size - cirbufCB->remain; + LOS_SpinUnlockRestore(&cirbufCB->lock, intSave); + + return size; +} + +/* + * startIdx + * | + * 0 0 0 0 0 0 0 0 X X X X X X X X 0 0 0 0 0 0 + * | + * endIdx + */ +STATIC UINT32 OsCirBufWriteLinear(CirBuf *cirbufCB, const CHAR *buf, UINT32 size) +{ + UINT32 cpSize; + errno_t err; + + cpSize = (cirbufCB->remain < size) ? cirbufCB->remain : size; + + if (cpSize == 0) { + return 0; + } + + err = memcpy_s(cirbufCB->fifo + cirbufCB->endIdx, cirbufCB->remain, buf, cpSize); + if (err != EOK) { + return 0; + } + + cirbufCB->remain -= cpSize; + cirbufCB->endIdx += cpSize; + + return cpSize; +} + +STATIC UINT32 OsCirBufWriteLoop(CirBuf *cirbufCB, const CHAR *buf, UINT32 size) +{ + UINT32 right, cpSize; + errno_t err; + + right = cirbufCB->size - cirbufCB->endIdx; + cpSize = (right < size) ? right : size; + + err = memcpy_s(cirbufCB->fifo + cirbufCB->endIdx, right, buf, cpSize); + if (err != EOK) { + return 0; + } + + cirbufCB->remain -= cpSize; + cirbufCB->endIdx += cpSize; + if (cirbufCB->endIdx == cirbufCB->size) { + cirbufCB->endIdx = 0; + } + + if (cpSize == size) { + return size; + } else { + cpSize += OsCirBufWriteLinear(cirbufCB, buf + cpSize, size - cpSize); + } + + return cpSize; +} + +UINT32 LOS_CirBufWrite(CirBuf *cirbufCB, const CHAR *buf, UINT32 size) +{ + UINT32 cpSize = 0; + UINT32 intSave; + + if ((cirbufCB == NULL) || (buf == NULL) || (size == 0) || (cirbufCB->status != CBUF_USED)) { + return 0; + } + + LOS_SpinLockSave(&cirbufCB->lock, &intSave); + + if ((cirbufCB->fifo == NULL) || (cirbufCB->remain == 0)) { + goto EXIT;; + } + + if (cirbufCB->startIdx <= cirbufCB->endIdx) { + cpSize = OsCirBufWriteLoop(cirbufCB, buf, size); + } else { + cpSize = OsCirBufWriteLinear(cirbufCB, buf, size); + } + +EXIT: + LOS_SpinUnlockRestore(&cirbufCB->lock, intSave); + return cpSize; +} + +STATIC UINT32 OsCirBufReadLinear(CirBuf *cirbufCB, CHAR *buf, UINT32 size) +{ + UINT32 cpSize, remain; + errno_t err; + + remain = cirbufCB->endIdx - cirbufCB->startIdx; + cpSize = (remain < size) ? remain : size; + + if (cpSize == 0) { + return 0; + } + + err = memcpy_s(buf, size, cirbufCB->fifo + cirbufCB->startIdx, cpSize); + if (err != EOK) { + return 0; + } + + cirbufCB->remain += cpSize; + cirbufCB->startIdx += cpSize; + + return cpSize; +} + +STATIC UINT32 OsCirBufReadLoop(CirBuf *cirbufCB, CHAR *buf, UINT32 size) +{ + UINT32 right, cpSize; + errno_t err; + + right = cirbufCB->size - cirbufCB->startIdx; + cpSize = (right < size) ? right : size; + + err = memcpy_s(buf, size, cirbufCB->fifo + cirbufCB->startIdx, cpSize); + if (err != EOK) { + return 0; + } + + cirbufCB->remain += cpSize; + cirbufCB->startIdx += cpSize; + if (cirbufCB->startIdx == cirbufCB->size) { + cirbufCB->startIdx = 0; + } + + if (cpSize < size) { + cpSize += OsCirBufReadLinear(cirbufCB, buf + cpSize, size - cpSize); + } + + return cpSize; +} + +UINT32 LOS_CirBufRead(CirBuf *cirbufCB, CHAR *buf, UINT32 size) +{ + UINT32 cpSize = 0; + UINT32 intSave; + + if ((cirbufCB == NULL) || (buf == NULL) || (size == 0) || (cirbufCB->status != CBUF_USED)) { + return 0; + } + + LOS_SpinLockSave(&cirbufCB->lock, &intSave); + + if ((cirbufCB->fifo == NULL) || (cirbufCB->remain == cirbufCB->size)) { + goto EXIT; + } + + if (cirbufCB->startIdx >= cirbufCB->endIdx) { + cpSize = OsCirBufReadLoop(cirbufCB, buf, size); + } else { + cpSize = OsCirBufReadLinear(cirbufCB, buf, size); + } + +EXIT: + LOS_SpinUnlockRestore(&cirbufCB->lock, intSave); + return cpSize; +} + +UINT32 LOS_CirBufInit(CirBuf *cirbufCB, CHAR *fifo, UINT32 size) +{ + if ((cirbufCB == NULL) || (fifo == NULL)) { + return LOS_NOK; + } + + (VOID)memset_s(cirbufCB, sizeof(CirBuf), 0, sizeof(CirBuf)); + LOS_SpinInit(&cirbufCB->lock); + cirbufCB->size = size; + cirbufCB->remain = size; + cirbufCB->status = CBUF_USED; + cirbufCB->fifo = fifo; + + return LOS_OK; +} + +VOID LOS_CirBufDeinit(CirBuf *cirbufCB) +{ + (VOID)memset_s(cirbufCB, sizeof(CirBuf), 0, sizeof(CirBuf)); +} + diff --git a/src/kernel_liteos_a/lib/libscrew/src/los_crc32.c b/src/kernel_liteos_a/lib/libscrew/src/los_crc32.c new file mode 100644 index 00000000..6bc6e66e --- /dev/null +++ b/src/kernel_liteos_a/lib/libscrew/src/los_crc32.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_crc32.h" + + +#define COUNT1 val = crc32_tab[(val ^ (*src++)) & 0xff] ^ (val >> 8) +#define COUNT2 COUNT1; COUNT1 +#define COUNT4 COUNT2; COUNT2 +#define COUNT8 COUNT4; COUNT4 + +#define ACCRATIO 8 + +UINT32 LOS_EtherCrc32Accumulate(UINT32 val, UINT8 *src, INT32 len) +{ + if (src == 0) { + return 0L; + } + + val = val ^ 0xffffffffUL; + while (len >= ACCRATIO) { + COUNT8; + len -= ACCRATIO; + } + while (len--) { + COUNT1; + } + + return val ^ 0xffffffffUL; +} + +UINT32 LOS_Crc32Accumulate(UINT32 val, UINT8 *src, INT32 len) +{ + while (len >= ACCRATIO) { + COUNT8; + len -= ACCRATIO; + } + while (len--) { + COUNT1; + } + + return val; +} + diff --git a/src/kernel_liteos_a/lib/libscrew/src/los_rbtree.c b/src/kernel_liteos_a/lib/libscrew/src/los_rbtree.c new file mode 100644 index 00000000..437a2257 --- /dev/null +++ b/src/kernel_liteos_a/lib/libscrew/src/los_rbtree.c @@ -0,0 +1,731 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* * + * @defgroup los_rbtree Rbtree + * @ingroup kernel + */ + +#include "los_rbtree.h" +#include "los_memory.h" + + +STATIC VOID OsRbLeftRotateNode(LosRbTree *pstTree, LosRbNode *pstX); +STATIC VOID OsRbRightRotateNode(LosRbTree *pstTree, LosRbNode *pstY); +STATIC VOID OsRbInsertNodeFixup(LosRbTree *pstTree, VOID *pstData); +STATIC VOID OsRbDeleteNodeFixup(LosRbTree *pstTree, LosRbNode *pstNode); +STATIC VOID OsRbDeleteNode(LosRbTree *pstTree, VOID *pstData); +STATIC VOID OsRbInitTree(LosRbTree *pstTree); +STATIC VOID OsRbClearTree(LosRbTree *pstTree); + +STATIC VOID OsRbLeftRotateNode(LosRbTree *pstTree, LosRbNode *pstX) +{ + LosRbNode *pstY = NULL; + LosRbNode *pstNilT = NULL; + LosRbNode *pstParent = NULL; + + if (pstTree == NULL || pstX == NULL) { + return; + } + pstNilT = &(pstTree->stNilT); + /* If pstX or pstY node's either child is NilT node: + * Left / right rotation might change the NilT's parent. + * NilT's parent shouldn't be changed. + * If NilT's parent node changes, + * then Delete_FixUp function might access NilT's parent's right/left child, + * which might lead to error. + * Solution: So we record the NilT's parent and at the end of the rotaion, + * replace the NilT's parent with the recorded node. + */ + pstParent = pstNilT->pstParent; + pstY = pstX->pstRight; + pstX->pstRight = pstY->pstLeft; + pstY->pstLeft->pstParent = pstX; + pstY->pstParent = pstX->pstParent; + if (pstNilT == pstX->pstParent) { + pstTree->pstRoot = pstY; + } else { + if (pstX == pstX->pstParent->pstLeft) { + pstX->pstParent->pstLeft = pstY; + } else { + pstX->pstParent->pstRight = pstY; + } + } + pstX->pstParent = pstY; + pstY->pstLeft = pstX; + pstNilT->pstParent = pstParent; + return; +} + +STATIC VOID OsRbRightRotateNode(LosRbTree *pstTree, LosRbNode *pstY) +{ + LosRbNode *pstX = NULL; + LosRbNode *pstNilT = NULL; + LosRbNode *pstParent = NULL; + if (NULL == pstTree || NULL == pstY) { + return; + } + + pstNilT = &(pstTree->stNilT); + + /* If pstX or pstY node's either child is NilT node: + * Left / right rotation might change the NilT's parent. + * NilT's parent shouldn't be changed. + * If NilT's parent node changes, + * then Delete_FixUp function might access NilT's parent's right/left child, + * which might lead to error. + * Solution: So we record the NilT's parent and at the end of the rotaion, + * replace the NilT's parent with the recorded node. + */ + pstParent = pstNilT->pstParent; + pstX = pstY->pstLeft; + pstY->pstLeft = pstX->pstRight; + pstX->pstRight->pstParent = pstY; + pstX->pstParent = pstY->pstParent; + if (pstNilT == pstY->pstParent) { + pstTree->pstRoot = pstX; + } else { + if (pstY == pstY->pstParent->pstRight) { + pstY->pstParent->pstRight = pstX; + } else { + pstY->pstParent->pstLeft = pstX; + } + } + pstY->pstParent = pstX; + pstX->pstRight = pstY; + pstNilT->pstParent = pstParent; + return; +} + +STATIC VOID OsRbInsertNodeFixup(LosRbTree *pstTree, VOID *pstData) +{ + LosRbNode *pstParent = NULL; + LosRbNode *pstGParent = NULL; + LosRbNode *pstY = NULL; + LosRbNode *pstX = NULL; + + if ((NULL == pstTree) || (NULL == pstData)) { + return; + } + + pstX = (LosRbNode *)pstData; + /* NilT is forbidden. */ + (pstTree->ulNodes)++; + while (LOS_RB_RED == pstX->pstParent->lColor) { + pstParent = pstX->pstParent; + pstGParent = pstParent->pstParent; + + if (pstParent == pstGParent->pstLeft) { + pstY = pstGParent->pstRight; + if (LOS_RB_RED == pstY->lColor) { + pstY->lColor = LOS_RB_BLACK; + pstParent->lColor = LOS_RB_BLACK; + pstGParent->lColor = LOS_RB_RED; + pstX = pstGParent; + continue; + } + + if (pstParent->pstRight == pstX) { + pstX = pstParent; + OsRbLeftRotateNode(pstTree, pstX); + } + + pstX->pstParent->lColor = LOS_RB_BLACK; + pstGParent->lColor = LOS_RB_RED; + OsRbRightRotateNode(pstTree, pstGParent); + } else { + pstY = pstGParent->pstLeft; + if (LOS_RB_RED == pstY->lColor) { + pstY->lColor = LOS_RB_BLACK; + pstParent->lColor = LOS_RB_BLACK; + pstGParent->lColor = LOS_RB_RED; + pstX = pstGParent; + continue; + } + + if (pstParent->pstLeft == pstX) { + pstX = pstParent; + OsRbRightRotateNode(pstTree, pstX); + } + + pstX->pstParent->lColor = LOS_RB_BLACK; + pstGParent->lColor = LOS_RB_RED; + OsRbLeftRotateNode(pstTree, pstGParent); + } + } + + pstTree->pstRoot->lColor = LOS_RB_BLACK; + + return; +} + +STATIC VOID OsRbDeleteNodeFixup(LosRbTree *pstTree, LosRbNode *pstNode) +{ + LosRbNode *pstW = NULL; + + if (NULL == pstTree || NULL == pstNode) { + return; + } + while ((pstNode != pstTree->pstRoot) && (LOS_RB_BLACK == pstNode->lColor)) { + if (pstNode->pstParent->pstLeft == pstNode) { + pstW = pstNode->pstParent->pstRight; + if (LOS_RB_RED == pstW->lColor) { + pstW->lColor = LOS_RB_BLACK; + pstNode->pstParent->lColor = LOS_RB_RED; + OsRbLeftRotateNode(pstTree, pstNode->pstParent); + pstW = pstNode->pstParent->pstRight; + } + + if ((LOS_RB_BLACK == pstW->pstLeft->lColor) && (LOS_RB_BLACK == pstW->pstRight->lColor)) { + pstW->lColor = LOS_RB_RED; + pstNode = pstNode->pstParent; + } else { + if (LOS_RB_BLACK == pstW->pstRight->lColor) { + pstW->pstLeft->lColor = LOS_RB_BLACK; + pstW->lColor = LOS_RB_RED; + OsRbRightRotateNode(pstTree, pstW); + pstW = pstNode->pstParent->pstRight; + } + pstW->lColor = pstNode->pstParent->lColor; + pstNode->pstParent->lColor = LOS_RB_BLACK; + pstW->pstRight->lColor = LOS_RB_BLACK; + OsRbLeftRotateNode(pstTree, pstNode->pstParent); + pstNode = pstTree->pstRoot; + } + } else { + pstW = pstNode->pstParent->pstLeft; + if (LOS_RB_RED == pstW->lColor) { + pstW->lColor = LOS_RB_BLACK; + pstNode->pstParent->lColor = LOS_RB_RED; + OsRbRightRotateNode(pstTree, pstNode->pstParent); + pstW = pstNode->pstParent->pstLeft; + } + if ((LOS_RB_BLACK == pstW->pstLeft->lColor) && (LOS_RB_BLACK == pstW->pstRight->lColor)) { + pstW->lColor = LOS_RB_RED; + pstNode = pstNode->pstParent; + } else { + if (LOS_RB_BLACK == pstW->pstLeft->lColor) { + pstW->pstRight->lColor = LOS_RB_BLACK; + pstW->lColor = LOS_RB_RED; + OsRbLeftRotateNode(pstTree, pstW); + pstW = pstNode->pstParent->pstLeft; + } + pstW->lColor = pstNode->pstParent->lColor; + pstNode->pstParent->lColor = LOS_RB_BLACK; + pstW->pstLeft->lColor = LOS_RB_BLACK; + OsRbRightRotateNode(pstTree, pstNode->pstParent); + pstNode = pstTree->pstRoot; + } + } + } + pstNode->lColor = LOS_RB_BLACK; + if (0 == pstTree->ulNodes) { + OsRbClearTree(pstTree); + } + + return; +} + +STATIC VOID OsRbDeleteNode(LosRbTree *pstTree, VOID *pstData) +{ + LosRbNode *pstChild = NULL; + LosRbNode *pstDel = NULL; + ULONG_T lColor; + LosRbWalk *pstWalk = NULL; + LosRbNode *pstNilT = NULL; + LosRbNode *pstZ = NULL; + LOS_DL_LIST *pstNode = NULL; + + if ((NULL == pstTree) || (NULL == pstData)) { + return; + } + + pstZ = (LosRbNode *)pstData; + pstNilT = &(pstTree->stNilT); + + /* NilT is forbidden. */ + if (!RB_IS_NOT_NILT(pstZ)) { + return; + } + + /* check whether the Node is in a tree */ + if ((pstZ->pstParent == pstNilT) && (pstZ->pstLeft == pstNilT) && (pstZ->pstRight == pstNilT) && + (pstTree->pstRoot != pstZ)) { + return; + } + + (pstTree->ulNodes)--; + + if (!LOS_ListEmpty(&pstTree->stWalkHead)) { + LOS_DL_LIST_FOR_EACH(pstNode, &pstTree->stWalkHead) + { + pstWalk = LOS_DL_LIST_ENTRY(pstNode, LosRbWalk, stLink); + if (pstWalk->pstCurrNode == pstZ) { + pstWalk->pstCurrNode = LOS_RbSuccessorNode(pstTree, pstZ); + } + } + } + + if ((pstNilT == pstZ->pstLeft) || (pstNilT == pstZ->pstRight)) { + pstChild = ((pstNilT != pstZ->pstLeft) ? pstZ->pstLeft : pstZ->pstRight); + if (NULL == pstChild) { /* Edit by r60958 for Coverity */ + return; + } + + pstChild->pstParent = pstZ->pstParent; + + if (pstNilT == pstZ->pstParent) { + pstTree->pstRoot = pstChild; + } else { + if (pstZ->pstParent->pstLeft == pstZ) { + pstZ->pstParent->pstLeft = pstChild; + } else { + pstZ->pstParent->pstRight = pstChild; + } + } + + if (LOS_RB_BLACK == pstZ->lColor) { + OsRbDeleteNodeFixup(pstTree, pstChild); + } + + /* re-initialize the pstZ */ + pstZ->lColor = LOS_RB_RED; + pstZ->pstLeft = pstZ->pstRight = pstZ->pstParent = pstNilT; + + return; + } + + /* Here is some different with book "Introduction to Algorithms, + * Second Edition", book's arithmetic won't delete pstZ, and it deletes + * pstZ's successor node instead. But we delete pstZ because + * our data structure has no internal node. So code is some complex. + */ + pstDel = pstZ; + + /* Get pstZ's successor node */ + pstZ = pstZ->pstRight; + while (pstNilT != pstZ->pstLeft) { + pstZ = pstZ->pstLeft; + } + + /* Because left is nilT, so child must be right. */ + pstChild = pstZ->pstRight; + if (NULL == pstChild) { /* Edit by r60958 for Coverity */ + return; + } + + lColor = pstZ->lColor; + + /* Remove successor node out of tree. */ + pstChild->pstParent = pstZ->pstParent; + + if (pstNilT == pstZ->pstParent) { + /* In fact, we never go here. */ + pstTree->pstRoot = pstChild; + } else { + if (pstZ->pstParent->pstLeft == pstZ) { + pstZ->pstParent->pstLeft = pstChild; + } else { + pstZ->pstParent->pstRight = pstChild; + } + } + + /* Insert successor node into tree and remove pstZ out of tree. */ + pstZ->pstParent = pstDel->pstParent; + pstZ->lColor = pstDel->lColor; + pstZ->pstRight = pstDel->pstRight; + pstZ->pstLeft = pstDel->pstLeft; + + if (pstNilT == pstDel->pstParent) { + /* if we arrive here, pstTree is no NULL */ + pstTree->pstRoot = pstZ; + } else { + if (pstDel->pstParent->pstLeft == pstDel) { + pstDel->pstParent->pstLeft = pstZ; + } else { + pstDel->pstParent->pstRight = pstZ; + } + } + + pstDel->pstLeft->pstParent = pstZ; + pstDel->pstRight->pstParent = pstZ; + + if (LOS_RB_BLACK == lColor) { + OsRbDeleteNodeFixup(pstTree, pstChild); + } + + /* re-initialize the pstDel */ + pstDel->lColor = LOS_RB_RED; + pstDel->pstLeft = pstDel->pstRight = pstDel->pstParent = pstNilT; + return; +} + + +STATIC VOID OsRbInitTree(LosRbTree *pstTree) +{ + if (NULL == pstTree) { + return; + } + + pstTree->ulNodes = 0; + pstTree->pstRoot = &(pstTree->stNilT); + pstTree->stNilT.lColor = LOS_RB_BLACK; + pstTree->stNilT.pstLeft = NULL; /* Always NULL */ + pstTree->stNilT.pstRight = NULL; /* Always NULL */ + pstTree->stNilT.pstParent = NULL; /* Not NULL when tree isn't empty */ + LOS_ListInit(&pstTree->stWalkHead); + + pstTree->pfCmpKey = NULL; + pstTree->pfFree = NULL; + pstTree->pfGetKey = NULL; + + return; +} + +STATIC VOID OsRbClearTree(LosRbTree *pstTree) +{ + LosRbWalk *pstWalk = NULL; + LOS_DL_LIST *pstNode = NULL; + + if (NULL == pstTree) { + return; + } + + pstNode = LOS_DL_LIST_FIRST(&pstTree->stWalkHead); + while (!LOS_DL_LIST_IS_END(&pstTree->stWalkHead, pstNode)) { + pstWalk = LOS_DL_LIST_ENTRY(pstNode, LosRbWalk, stLink); + pstWalk->pstCurrNode = NULL; + pstWalk->pstTree = NULL; + + LOS_ListDelete(pstNode); + pstNode = LOS_DL_LIST_FIRST(&pstTree->stWalkHead); + } + + return; +} + +LosRbWalk *LOS_RbCreateWalk(LosRbTree *pstTree) +{ + LosRbNode *pstNode = NULL; + LosRbWalk *pstWalk = NULL; + + if (NULL == pstTree) { + return NULL; + } + + pstNode = LOS_RbFirstNode(pstTree); + if (NULL == pstNode) { + return NULL; + } + + pstWalk = (LosRbWalk *)LOS_MemAlloc(m_aucSysMem0, sizeof(LosRbWalk)); + if (NULL == pstWalk) { + return NULL; + } + + LOS_ListAdd(&pstTree->stWalkHead, &pstWalk->stLink); + pstWalk->pstCurrNode = pstNode; + pstWalk->pstTree = pstTree; + return pstWalk; +} + +VOID *LOS_RbWalkNext(LosRbWalk *pstWalk) +{ + LosRbNode *pstNode = NULL; + + /* + * Here, in the previous code, we didn't check pstCurrNode + * pstTree, but in some circumstance, we will delete a tree + * (by calling function RB_ClearTree), meanwhile, we will + * evaluate pstCurrNode and pstTree to NULL, but at present, + * if we are walking groups and ports, then we will call this + * function(LOS_RbWalkNext), but the tree has been deleted already + */ + if ((NULL == pstWalk) || (NULL == pstWalk->pstCurrNode) || (NULL == pstWalk->pstTree)) { + return NULL; + } + + pstNode = pstWalk->pstCurrNode; + pstWalk->pstCurrNode = LOS_RbSuccessorNode(pstWalk->pstTree, pstNode); + return pstNode; +} + +VOID LOS_RbDeleteWalk(LosRbWalk *pstWalk) +{ + if (NULL == pstWalk) { + return; + } + + if (LOS_DL_LIST_IS_ON_QUEUE(&pstWalk->stLink)) { + LOS_ListDelete(&pstWalk->stLink); + } + pstWalk->pstCurrNode = NULL; + pstWalk->pstTree = NULL; + LOS_MemFree(m_aucSysMem0, pstWalk); + + return; +} + +VOID LOS_RbInsertOneNodeProcess(LosRbTree *pstTree, LosRbNode *pstParent, LosRbNode *pstNew) +{ + LosRbNode *pstNilT = &pstTree->stNilT; + VOID *pNodeKey = NULL; + VOID *pKey = NULL; + ULONG_T ulCmpResult; + + pstNew->lColor = LOS_RB_RED; + pstNew->pstLeft = pstNew->pstRight = pstNilT; + if ((pstNew->pstParent = pstParent) == pstNilT) { + pstTree->pstRoot = pstNew; + } else { + pNodeKey = pstTree->pfGetKey(pstNew); + pKey = pstTree->pfGetKey(pstParent); + ulCmpResult = pstTree->pfCmpKey(pNodeKey, pKey); + if (RB_SMALLER == ulCmpResult) { + pstParent->pstLeft = pstNew; + } else { + pstParent->pstRight = pstNew; + } + } + + OsRbInsertNodeFixup(pstTree, pstNew); + + return; +} + +VOID LOS_RbInitTree(LosRbTree *pstTree, pfRBCmpKeyFn pfCmpKey, pfRBFreeFn pfFree, pfRBGetKeyFn pfGetKey) +{ + if (NULL == pstTree) { + return; + } + + OsRbInitTree(pstTree); + + pstTree->pfCmpKey = pfCmpKey; + pstTree->pfFree = pfFree; + pstTree->pfGetKey = pfGetKey; + + return; +} + +VOID LOS_RbDestroyTree(LosRbTree *pstTree) +{ + LosRbNode *pstNode = NULL; + + if (NULL == pstTree) { + return; + } + if (NULL == pstTree->pfFree) { + return; + } + + RB_WALK(pstTree, pstNode, pstWalk) + { + OsRbDeleteNode(pstTree, pstNode); + (VOID)pstTree->pfFree(pstNode); + } + RB_WALK_END(pstTree, pstNode, pstWalk); + + OsRbClearTree(pstTree); + + return; +} + +VOID *LOS_RbFirstNode(LosRbTree *pstTree) +{ + LosRbNode *pstNode = NULL; + LosRbNode *pstNilT = NULL; + + if (NULL == pstTree) { + return NULL; + } + + pstNode = pstTree->pstRoot; + if (pstNode == NULL) { + return NULL; + } + pstNilT = &(pstTree->stNilT); + + if (pstNilT == pstNode) { + return NULL; + } + + while (pstNilT != pstNode->pstLeft) { + pstNode = pstNode->pstLeft; + } + + return pstNode; +} + +VOID *LOS_RbSuccessorNode(LosRbTree *pstTree, VOID *pstData) +{ + LosRbNode *pstY = NULL; + LosRbNode *pstNilT = NULL; + LosRbNode *pstNode = NULL; + + if (NULL == pstTree) { + return NULL; + } + + pstNode = (LosRbNode *)pstData; + + if (NULL == pstNode) { + return NULL; + } + + /* NilT is forbidden. */ + if (!RB_IS_NOT_NILT(pstNode)) { + return NULL; + } + + /* if we arrive here, pstTree is no NULL */ + pstNilT = &(pstTree->stNilT); + + if (pstNilT != pstNode->pstRight) { + pstNode = pstNode->pstRight; + while (pstNilT != pstNode->pstLeft) { + pstNode = pstNode->pstLeft; + } + + return pstNode; + } + + pstY = pstNode->pstParent; + + while ((pstNilT != pstY) && (pstNode == pstY->pstRight)) { + pstNode = pstY; + pstY = pstY->pstParent; + } + + return ((pstNilT == pstY) ? NULL : pstY); +} + +LosRbNode *LOS_RbGetNextNode(LosRbTree *pstTree, VOID *pKey) +{ + LosRbNode *pNode = NULL; + + if (TRUE == LOS_RbGetNode(pstTree, pKey, &pNode)) { + return LOS_RbSuccessorNode(pstTree, pNode); + } else if ((NULL == pNode) || (&pstTree->stNilT == pNode)) { + return NULL; + } else if (RB_BIGGER == pstTree->pfCmpKey(pKey, pstTree->pfGetKey(pNode))) { + while (NULL != pNode) { + pNode = LOS_RbSuccessorNode(pstTree, pNode); + if (NULL == pNode) { + return NULL; + } + + if (RB_SMALLER == pstTree->pfCmpKey(pKey, pstTree->pfGetKey(pNode))) { + break; + } + } + return pNode; + } else { + return pNode; + } +} + +ULONG_T LOS_RbGetNode(LosRbTree *pstTree, VOID *pKey, LosRbNode **ppstNode) +{ + LosRbNode *pstNilT = NULL; + LosRbNode *pstX = NULL; + LosRbNode *pstY = NULL; + VOID *pNodeKey = NULL; + ULONG_T ulCmpResult; + + if ((NULL == pstTree) || (NULL == pKey) || (NULL == ppstNode)) { + if (NULL != ppstNode) { + *ppstNode = NULL; + } + return FALSE; + } + if ((NULL == pstTree->pfGetKey) || (NULL == pstTree->pfCmpKey)) { + *ppstNode = NULL; + return FALSE; + } + + pstNilT = &pstTree->stNilT; + pstY = pstTree->pstRoot; + pstX = pstY; + + while (pstX != pstNilT) { + pNodeKey = pstTree->pfGetKey(pstX); + + ulCmpResult = pstTree->pfCmpKey(pKey, pNodeKey); + if (RB_EQUAL == ulCmpResult) { + *ppstNode = pstX; + return TRUE; + } + if (RB_SMALLER == ulCmpResult) { + pstY = pstX; + pstX = pstX->pstLeft; + } else { + pstY = pstX; + pstX = pstX->pstRight; + } + } + + *ppstNode = pstY; + return FALSE; +} + +VOID LOS_RbDelNode(LosRbTree *pstTree, LosRbNode *pstNode) +{ + OsRbDeleteNode(pstTree, pstNode); +} + +ULONG_T LOS_RbAddNode(LosRbTree *pstTree, LosRbNode *pstNew) +{ + ULONG_T ulSearchNode; + VOID *pNodeKey = NULL; + LosRbNode *pstX = NULL; + + if ((NULL == pstTree) || (NULL == pstNew)) { + return FALSE; + } + if ((NULL == pstTree->pfGetKey) || (NULL == pstTree->pfCmpKey)) { + return FALSE; + } + + pNodeKey = pstTree->pfGetKey(pstNew); + ulSearchNode = LOS_RbGetNode(pstTree, pNodeKey, &pstX); + if (TRUE == ulSearchNode) { + return FALSE; + } + + if (NULL == pstX) { + return FALSE; + } + + LOS_RbInsertOneNodeProcess(pstTree, pstX, pstNew); + + return TRUE; +} diff --git a/src/kernel_liteos_a/lib/libscrew/src/los_seq_buf.c b/src/kernel_liteos_a/lib/libscrew/src/los_seq_buf.c new file mode 100644 index 00000000..00ab78c4 --- /dev/null +++ b/src/kernel_liteos_a/lib/libscrew/src/los_seq_buf.c @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_seq_buf.h" +#include "los_typedef.h" +#include +#include "securec.h" + +static int ExpandSeqBuf(struct SeqBuf *seqBuf, size_t oldCount) +{ + char *newBuf = NULL; + int ret; + + if ((seqBuf == NULL) || (seqBuf->buf == NULL)) { + return -LOS_NOK; + } + + if (seqBuf->size >= SEQBUF_LIMIT_SIZE) { + goto EXPAND_FAILED; + } + + newBuf = (char*)malloc(seqBuf->size <<= 1); + if (newBuf == NULL) { + goto EXPAND_FAILED; + } + (void)memset_s(newBuf + oldCount, seqBuf->size - oldCount, 0, seqBuf->size - oldCount); + + ret = memcpy_s(newBuf, seqBuf->size, seqBuf->buf, oldCount); + if (ret != LOS_OK) { + free(newBuf); + goto EXPAND_FAILED; + } + seqBuf->count = oldCount; + + free(seqBuf->buf); + seqBuf->buf = newBuf; + + return LOS_OK; +EXPAND_FAILED: + free(seqBuf->buf); + seqBuf->buf = NULL; + seqBuf->count = 0; + seqBuf->size = 0; + + return -LOS_NOK; +} + +struct SeqBuf *LosBufCreat(void) +{ + struct SeqBuf *seqBuf = NULL; + + seqBuf = (struct SeqBuf *)malloc(sizeof(struct SeqBuf)); + if (seqBuf == NULL) { + errno = -LOS_ENOMEM; + return NULL; + } + (void)memset_s(seqBuf, sizeof(struct SeqBuf), 0, sizeof(struct SeqBuf)); + + return seqBuf; +} + +int LosBufVprintf(struct SeqBuf *seqBuf, const char *fmt, va_list argList) +{ + bool needreprintf = FALSE; + int bufLen; + + if (seqBuf == NULL) { + return -LOS_EPERM; + } + + if (seqBuf->buf == NULL) { + seqBuf->size = SEQBUF_PAGE_SIZE; + seqBuf->buf = (char *)malloc(seqBuf->size); + if (seqBuf->buf == NULL) { + return -LOS_ENOMEM; + } + (void)memset_s(seqBuf->buf, seqBuf->size, 0, seqBuf->size); + seqBuf->count = 0; + } + + do { + bufLen = vsnprintf_s(seqBuf->buf + seqBuf->count, seqBuf->size - seqBuf->count, + seqBuf->size - seqBuf->count - 1, fmt, argList); + if (bufLen >= 0) { + /* succeed write. */ + seqBuf->count += bufLen; + return 0; + } + if (seqBuf->buf[seqBuf->count] == '\0') { + free(seqBuf->buf); + seqBuf->buf = NULL; + break; + } + + needreprintf = TRUE; + + if (ExpandSeqBuf(seqBuf, seqBuf->count) != 0) { + break; + } + } while (needreprintf); + + return -LOS_NOK; +} + +int LosBufPrintf(struct SeqBuf *seqBuf, const char *fmt, ...) +{ + va_list argList; + int ret; + + va_start(argList, fmt); + ret = LosBufVprintf(seqBuf, fmt, argList); + va_end(argList); + + return ret; +} + +int LosBufRelease(struct SeqBuf *seqBuf) +{ + if (seqBuf == NULL) { + return -LOS_EPERM; + } + + if (seqBuf->buf != NULL) { + free(seqBuf->buf); + seqBuf->buf = NULL; + } + free(seqBuf); + + return LOS_OK; +} diff --git a/src/kernel_liteos_a/lib/libsec/BUILD.gn b/src/kernel_liteos_a/lib/libsec/BUILD.gn new file mode 100644 index 00000000..523cb219 --- /dev/null +++ b/src/kernel_liteos_a/lib/libsec/BUILD.gn @@ -0,0 +1,60 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") +import("$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR/libsec_src.gni") + +module_switch = defined(LOSCFG_LIB_LIBC) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = libsec_sources + + if (defined(LOSCFG_KERNEL_LMS)) { + if (ohos_build_compiler == "gcc") { + cflags_c = [ "-fsanitize=kernel-address" ] + } else { + cflags_c = [ + "-fsanitize=kernel-address", + "-mllvm", + "-asan-instrumentation-with-call-threshold=0", + "-mllvm", + "-asan-stack=0", + "-mllvm", + "-asan-globals=0", + ] + } + } + + public_configs = [ ":public" ] +} + +config("public") { + include_dirs = libsec_include_dirs + defines = [ "SECUREC_IN_KERNEL=0" ] +} diff --git a/src/kernel_liteos_a/lib/libsec/Makefile b/src/kernel_liteos_a/lib/libsec/Makefile new file mode 100644 index 00000000..55377471 --- /dev/null +++ b/src/kernel_liteos_a/lib/libsec/Makefile @@ -0,0 +1,6 @@ +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := sec +LOCAL_SRCS := $(wildcard $(LITEOSTHIRDPARTY)/bounds_checking_function/src/*.c) + +include $(MODULE) diff --git a/src/kernel_liteos_a/lib/zlib/BUILD.gn b/src/kernel_liteos_a/lib/zlib/BUILD.gn new file mode 100644 index 00000000..af3aec07 --- /dev/null +++ b/src/kernel_liteos_a/lib/zlib/BUILD.gn @@ -0,0 +1,58 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = defined(LOSCFG_LIB_ZLIB) +module_name = "z" +kernel_module(module_name) { + sources = [ + "$LITEOSTHIRDPARTY/zlib/adler32.c", + "$LITEOSTHIRDPARTY/zlib/compress.c", + "$LITEOSTHIRDPARTY/zlib/crc32.c", + "$LITEOSTHIRDPARTY/zlib/deflate.c", + "$LITEOSTHIRDPARTY/zlib/gzclose.c", + "$LITEOSTHIRDPARTY/zlib/gzlib.c", + "$LITEOSTHIRDPARTY/zlib/gzread.c", + "$LITEOSTHIRDPARTY/zlib/gzwrite.c", + "$LITEOSTHIRDPARTY/zlib/infback.c", + "$LITEOSTHIRDPARTY/zlib/inffast.c", + "$LITEOSTHIRDPARTY/zlib/inflate.c", + "$LITEOSTHIRDPARTY/zlib/inftrees.c", + "$LITEOSTHIRDPARTY/zlib/trees.c", + "$LITEOSTHIRDPARTY/zlib/uncompr.c", + "$LITEOSTHIRDPARTY/zlib/zutil.c", + ] + + public_configs = [ ":public" ] +} + +config("public") { + include_dirs = [ "$LITEOSTHIRDPARTY/zlib" ] +} diff --git a/src/kernel_liteos_a/lib/zlib/Makefile b/src/kernel_liteos_a/lib/zlib/Makefile new file mode 100644 index 00000000..a6e9d643 --- /dev/null +++ b/src/kernel_liteos_a/lib/zlib/Makefile @@ -0,0 +1,7 @@ +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := z + +LOCAL_SRCS := $(wildcard $(LITEOSTHIRDPARTY)/zlib/*.c) + +include $(MODULE) diff --git a/src/kernel_liteos_a/liteos.gni b/src/kernel_liteos_a/liteos.gni new file mode 100644 index 00000000..6deef994 --- /dev/null +++ b/src/kernel_liteos_a/liteos.gni @@ -0,0 +1,156 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("$root_out_dir/config.gni") + +LITEOSTOPDIR = "//kernel/liteos_a" +LITEOSTHIRDPARTY = "//third_party" +HDFTOPDIR = "//drivers/hdf_core/adapter/khdf/liteos" +HIVIEWDFX_HILOG_LITE_DIR = "//base/hiviewdfx/hilog_lite" +DRIVERS_LITEOS_DIR = "//drivers/liteos" +THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR = + "//third_party/bounds_checking_function" +THIRDPARTY_FATFS_DIR = "//third_party/FatFs" +THIRDPARTY_NUTTX_DIR = "//third_party/NuttX" +THIRDPARTY_MUSL_DIR = "//third_party/musl" +THIRDPARTY_TOYBOX_DIR = "//third_party/toybox" +THIRDPARTY_MKSH_DIR = "//third_party/mksh" +THIRDPARTY_FREEBSD_DIR = "//third_party/FreeBSD" +THIRDPARTY_OPTIMIZED_ROUTINES_DIR = "//third_party/optimized-routines" +THIRDPARTY_GOOGLETEST_DIR = "//third_party/googletest" +KERNEL_LINUX_DIR = "//kernel/linux/linux-5.10" + +ARCH = "" +if (defined(LOSCFG_ARCH_ARM_AARCH32)) { + ARCH = "arm" +} else if (defined(LOSCFG_ARCH_ARM_AARCH64)) { + ARCH = "aarch64" +} + +template("kernel_module") { + build_gn = rebase_path("BUILD.gn") + cmd = "grep -c '^\s*\(kernel_module\|hdf_driver\)\s*(\s*\S*\s*)\s*{\s*\$' $build_gn" + modules_count = exec_script("//build/lite/run_shell_cmd.py", [ cmd ], "value") + if (modules_count == 1) { + auto_config = true + } + + cmd = "if grep -q '^\s*\(config\s*(\s*\"public\"\s*)\|module_group\s*(\s*\"\S*\"\s*)\)\s*{\s*\$' $build_gn; then echo true; else echo false; fi" + has_public_config = + exec_script("//build/lite/run_shell_cmd.py", [ cmd ], "value") + if (!has_public_config && defined(auto_config)) { + config("public") { + configs = [] + } + } + + current_dir_name = get_path_info(rebase_path("."), "file") + if (target_name != current_dir_name) { + cmd = "if grep -q '^\s*\(module_group\|group\)\s*(\s*\"$current_dir_name\"\s*)\s*{\s*\$' $build_gn; then echo true; else echo false; fi" + has_current_dir_group = + exec_script("//build/lite/run_shell_cmd.py", [ cmd ], "value") + if (!has_current_dir_group && defined(auto_config)) { + module_name = target_name + group(current_dir_name) { + public_deps = [ ":$module_name" ] + } + } + } + + if (defined(invoker.module_switch) && !invoker.module_switch) { + group(target_name) { + not_needed(invoker, "*") + } + } else { + source_set(target_name) { + public_configs = [] + forward_variables_from(invoker, "*") + if (has_public_config) { + included_public_config = false + foreach(cfg, public_configs) { + what = "label_no_toolchain" + if (get_label_info(cfg, what) == get_label_info(":public", what)) { + included_public_config = true + } + } + if (!included_public_config) { + public_configs += [ ":public" ] + } + } + } + } + not_needed([ "auto_config" ]) +} + +template("config") { + config(target_name) { + if (defined(invoker.module_switch) && !invoker.module_switch && + target_name == "public") { + not_needed(invoker, "*") + forward_variables_from(invoker, [ "configs" ]) + } else { + forward_variables_from(invoker, "*") + } + } +} + +template("module_group") { + assert(defined(invoker.modules), "modules are must") + group(target_name) { + deps = [] + foreach(m, invoker.modules) { + deps += [ m ] + } + if (defined(invoker.deps)) { + deps += invoker.deps + } + } + config("public") { + configs = [] + foreach(m, invoker.modules) { + configs += [ "$m:public" ] + } + if (defined(invoker.configs)) { + configs += invoker.configs + } + } +} + +set_defaults("kernel_module") { + configs = [ + "$LITEOSTOPDIR:public", + "$LITEOSTOPDIR:los_config", + ] + visibility = [ + ":*", + "$LITEOSTOPDIR:*", + "..:*", + "../..:*", + ] +} diff --git a/src/kernel_liteos_a/net/BUILD.gn b/src/kernel_liteos_a/net/BUILD.gn new file mode 100644 index 00000000..26085a4a --- /dev/null +++ b/src/kernel_liteos_a/net/BUILD.gn @@ -0,0 +1,48 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +group("net") { + deps = [ "telnet" ] + if (defined(LOSCFG_NET_LWIP_SACK_2_0)) { + deps += [ "$LITEOSTHIRDPARTY/lwip_enhanced/src" ] + } else if (defined(LOSCFG_NET_LWIP_SACK_2_1)) { + deps += [ "lwip-2.1" ] + } +} + +config("public") { + configs = [ "telnet:public" ] + if (defined(LOSCFG_NET_LWIP_SACK_2_0)) { + configs += [ "$LITEOSTHIRDPARTY/lwip_enhanced/src:public" ] + } else if (defined(LOSCFG_NET_LWIP_SACK_2_1)) { + configs += [ "lwip-2.1:public" ] + } +} diff --git a/src/kernel_liteos_a/net/Kconfig b/src/kernel_liteos_a/net/Kconfig new file mode 100644 index 00000000..ca7f8458 --- /dev/null +++ b/src/kernel_liteos_a/net/Kconfig @@ -0,0 +1,36 @@ +menu "Net" +#config NET_LWIP +# bool "Enable Lwip" +# default y + +# help +# extend kernel include runstop, dynload, scatter and cppsupport. +# It can support all or some. + +config NET_LWIP_SACK + bool "Enable Lwipsack" + default y + + help + Answer Y to enable LiteOS support lwip. + +choice + depends on NET_LWIP_SACK + prompt "Lwipsack" + default NET_LWIP_SACK_2_1 + help + Enable Lwipsack for 2.x + +config NET_LWIP_SACK_2_1 + bool "Enable Lwipsack (2.1)" + depends on NET_LWIP_SACK + +config NET_LWIP_SACK_2_0 + bool "Enable Lwipsack (2.0)" + depends on NET_LWIP_SACK + +endchoice +endmenu + + + diff --git a/src/kernel_liteos_a/net/lwip-2.1/BUILD.gn b/src/kernel_liteos_a/net/lwip-2.1/BUILD.gn new file mode 100644 index 00000000..dcc7934f --- /dev/null +++ b/src/kernel_liteos_a/net/lwip-2.1/BUILD.gn @@ -0,0 +1,59 @@ +# Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") +import("$LITEOSTHIRDPARTY/lwip/lwip.gni") +import("lwip_porting.gni") + +module_switch = defined(LOSCFG_NET_LWIP_SACK_2_1) +module_name = "lwip" +kernel_module(module_name) { + include_dirs = [ "$LWIP_PORTING_DIR/enhancement/include" ] + + sources = LWIP_PORTING_FILES + LWIPNOAPPSFILES + + sources -= [ + "$LWIPDIR/api/sockets.c", + "$LWIPDIR/core/ipv4/dhcp.c", + "$LWIPDIR/core/ipv4/etharp.c", + ] + + public_configs = [ ":public" ] + + defines = [ + "__LWIP__", + "LWIP_NOASSERT", + "_BSD_SOURCE=1", + ] +} + +config("public") { + include_dirs = [ "../mac" ] + include_dirs += LWIP_PORTING_INCLUDE_DIRS + include_dirs += LWIP_INCLUDE_DIRS +} diff --git a/src/kernel_liteos_a/net/lwip-2.1/Makefile b/src/kernel_liteos_a/net/lwip-2.1/Makefile new file mode 100644 index 00000000..c38e9119 --- /dev/null +++ b/src/kernel_liteos_a/net/lwip-2.1/Makefile @@ -0,0 +1,51 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +ifeq ($(LWIPDIR), ) +$(error "LWIPDIR not defined") +endif + +include $(LWIPDIR)/Filelists.mk + +MODULE_NAME := lwip + +LOCAL_INCLUDE := -I $(LITEOSTOPDIR)/net/lwip-2.1/enhancement/include + +LOCAL_FLAGS := -D__LWIP__ -DLWIP_NOASSERT +LOCAL_FLAGS += $(LOCAL_INCLUDE) + +LOCAL_SRCS := $(wildcard porting/src/*.c $(LWIPNOAPPSFILES)) +LOCAL_SRCS += $(wildcard enhancement/src/*.c) +LOCAL_SRCS := $(filter-out $(LWIPDIR)/core/ipv4/dhcp.c, $(LOCAL_SRCS)) +LOCAL_SRCS := $(filter-out $(LWIPDIR)/core/ipv4/etharp.c, $(LOCAL_SRCS)) +LOCAL_SRCS := $(filter-out $(LWIPDIR)/api/sockets.c, $(LOCAL_SRCS)) + +include $(MODULE) diff --git a/src/kernel_liteos_a/net/lwip-2.1/enhancement/include/lwip/api_shell.h b/src/kernel_liteos_a/net/lwip-2.1/enhancement/include/lwip/api_shell.h new file mode 100644 index 00000000..7b212301 --- /dev/null +++ b/src/kernel_liteos_a/net/lwip-2.1/enhancement/include/lwip/api_shell.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LWIP_HDR_API_SHELL_H +#define LWIP_HDR_API_SHELL_H + +#include "arch/cc.h" +#include "lwip/opt.h" + +#if defined (__cplusplus) && __cplusplus +extern "C" { +#endif + +u32_t lwip_ifconfig(int argc, const char **argv); +u32_t lwip_arp(int argc, const char **argv); +u32_t osShellNetIfUp(int argc, const char **argv); +u32_t osShellNetIfDown(int argc, const char **argv); +u32_t osShellPing(int argc, const char **argv); +u32_t osShellTftp(int argc, const char **argv); +#if LWIP_SNTP +u32_t osShellNtpdate(int argc, const char **argv); +#endif +#if LWIP_DNS +u32_t osShellDns(int argc, const char **argv); +#endif /* LWIP_DNS */ +u32_t osShellNetstat(int argc, const char **argv); +void netstat_internal(void *ctx); + +#if defined (__cplusplus) && __cplusplus +} +#endif + +#endif /* LWIP_HDR_API_SHELL_H */ diff --git a/src/kernel_liteos_a/net/lwip-2.1/enhancement/include/lwip/dhcps.h b/src/kernel_liteos_a/net/lwip-2.1/enhancement/include/lwip/dhcps.h new file mode 100644 index 00000000..bab711a4 --- /dev/null +++ b/src/kernel_liteos_a/net/lwip-2.1/enhancement/include/lwip/dhcps.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LWIP_HDR_DHCPS_H +#define LWIP_HDR_DHCPS_H + +#include "lwip/opt.h" +#include "lwip/prot/dhcp.h" +#if LWIP_DHCPS /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/netif.h" +#include "lwip/udp.h" + +#if defined (__cplusplus) && __cplusplus +extern "C" { +#endif + + +#ifndef LWIP_DHCPS_MAX_LEASE +#define LWIP_DHCPS_MAX_LEASE 30 +#endif + +#ifndef LWIP_DHCPS_LEASE_TIME +#define LWIP_DHCPS_LEASE_TIME ~0 +#endif + +/* Offer time in seconds */ +#ifndef LWIP_DHCPS_OFFER_TIME +#define LWIP_DHCPS_OFFER_TIME 300 +#endif + +#ifndef LWIP_DHCPS_DECLINE_TIME +#define LWIP_DHCPS_DECLINE_TIME 500 +#endif + +err_t dhcps_start(struct netif *netif, const char *start_ip, u16_t ip_num); +void dhcps_stop(struct netif *netif); + +#if defined (__cplusplus) && __cplusplus +} +#endif +#endif /* LWIP_DHCPS */ +#endif /* LWIP_HDR_DHCPS_H */ diff --git a/src/kernel_liteos_a/net/lwip-2.1/enhancement/include/lwip/fixme.h b/src/kernel_liteos_a/net/lwip-2.1/enhancement/include/lwip/fixme.h new file mode 100644 index 00000000..41b535df --- /dev/null +++ b/src/kernel_liteos_a/net/lwip-2.1/enhancement/include/lwip/fixme.h @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LWIP_HDR_FIXME_H +#define LWIP_HDR_FIXME_H + +#include "lwip/opt.h" +#include "netif/etharp.h" +#include "lwip/netif.h" + +#define link_rx_drop cachehit +#define link_tx_drop cachehit +#define link_rx_overrun cachehit +#define link_tx_overrun cachehit + +#define ip_rx_err cachehit +#define ip_tx_err cachehit +#define ip_rx_bytes cachehit +#define ip_tx_bytes cachehit + +#define DUP_ARP_DETECT_TIME 2000 /* 2 seconds period */ +#define NETCONN_PKT_RAW 0x80 +#define SYS_ARCH_ERROR 0x7fffffffUL + +#define LWIP_ENABLE_LOS_SHELL_CMD LOSCFG_SHELL +#define LWIP_SHELL_CMD_PING_RETRY_TIMES 4 +#define LWIP_SHELL_CMD_PING_TIMEOUT 2000 +#define LWIP_MAX_UDP_RAW_SEND_SIZE 65332 +#define LWIP_EXT_POLL_SUPPORT LWIP_SOCKET_POLL + +#define ip_addr_set_val(dest, src) do { \ + IP_SET_TYPE_VAL(*dest, IP_GET_TYPE(src)); \ + if (IP_IS_V6_VAL(*(src))) { \ + ip6_addr_set(ip_2_ip6(dest), ip_2_ip6(src)); \ + } else { \ + ip4_addr_set(ip_2_ip4(dest), ip_2_ip4(src)); \ + } \ + } while (0) + +#define ip_addr_ismulticast_val(ipaddr) ((IP_IS_V6_VAL(*ipaddr)) ? \ + ip6_addr_ismulticast(ip_2_ip6(ipaddr)) : \ + ip4_addr_ismulticast(ip_2_ip4(ipaddr))) + +#define ip_addr_isbroadcast_val(ipaddr, netif) ((IP_IS_V6_VAL(*ipaddr)) ? \ + 0 : \ + ip4_addr_isbroadcast(ip_2_ip4(ipaddr), netif)) + +#define ip_addr_netcmp_val(addr1, addr2, mask) ((IP_IS_V6_VAL(*(addr1)) && IP_IS_V6_VAL(*(addr2))) ? \ + 0 : \ + ip4_addr_netcmp(ip_2_ip4(addr1), ip_2_ip4(addr2), mask)) + +#define ip6_addr_isnone_val(ip6addr) (((ip6addr).addr[0] == 0xffffffffUL) && \ + ((ip6addr).addr[1] == 0xffffffffUL) && \ + ((ip6addr).addr[2] == 0xffffffffUL) && \ + ((ip6addr).addr[3] == 0xffffffffUL)) + +#define ip6_addr_isnone(ip6addr) (((ip6addr) == NULL) || ip6_addr_isnone_val(*(ip6addr))) + +#define ipaddr_ntoa_unsafe(addr) ((IP_IS_V6_VAL(*addr)) ? ip6addr_ntoa(ip_2_ip6(addr)) : ip4addr_ntoa(ip_2_ip4(addr))) + +#ifdef ip6_addr_cmp +#undef ip6_addr_cmp +#define ip6_addr_cmp(addr1, addr2) (((addr1)->addr[0] == (addr2)->addr[0]) && \ + ((addr1)->addr[1] == (addr2)->addr[1]) && \ + ((addr1)->addr[2] == (addr2)->addr[2]) && \ + ((addr1)->addr[3] == (addr2)->addr[3])) +#endif + +err_t netif_dhcp_off(struct netif *netif); + +err_t netif_do_rmv_ipv6_addr(struct netif *netif, void *arguments); + +err_t netif_set_mtu(struct netif *netif, u16_t netif_mtu); + +err_t netif_set_hwaddr(struct netif *netif, const unsigned char *hw_addr, int hw_len); + +err_t etharp_update_arp_entry(struct netif *netif, const ip4_addr_t *ipaddr, struct eth_addr *ethaddr, u8_t flags); + +err_t etharp_delete_arp_entry(struct netif *netif, ip4_addr_t *ipaddr); + +err_t lwip_dns_setserver(u8_t numdns, ip_addr_t *dnsserver); + +err_t lwip_dns_getserver(u8_t numdns, ip_addr_t *dnsserver); + +#if PF_PKT_SUPPORT +extern struct raw_pcb *pkt_raw_pcbs; +#endif + +#if LWIP_RAW +extern struct raw_pcb *raw_pcbs; +#endif + +#endif /* LWIP_HDR_FIXME_H */ diff --git a/src/kernel_liteos_a/net/lwip-2.1/enhancement/src/api_shell.c b/src/kernel_liteos_a/net/lwip-2.1/enhancement/src/api_shell.c new file mode 100644 index 00000000..ebe65624 --- /dev/null +++ b/src/kernel_liteos_a/net/lwip-2.1/enhancement/src/api_shell.c @@ -0,0 +1,3932 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "../core/ipv4/etharp.c" /* for arp_table */ +#define icmp6_hdr netinet_icmp6_hdr +#include +#undef icmp6_hdr +#include "lwip/fixme.h" +#include "lwip/opt.h" + +#if LWIP_ENABLE_LOS_SHELL_CMD +#include "lwip/api.h" +#include "lwip/tcpip.h" +#include "lwip/netif.h" +#include "lwip/netdb.h" +#include "lwip/stats.h" +#include "lwip/err.h" +#include "lwip/inet.h" +#include "netif/etharp.h" +#include "lwip/ip_addr.h" +#include "lwip/ip6_addr.h" +#include "lwip/icmp.h" +#include "lwip/priv/nd6_priv.h" +#include "lwip/sockets.h" +#include "lwip/inet_chksum.h" +#include "lwip/raw.h" +#include "los_config.h" +#include +#include "limits.h" +#include +#include +#include +#include +#include +#include + +#include "lwip/api_shell.h" + +#include "lwip/dns.h" +#include "lwip/udp.h" +#include "lwip/priv/tcp_priv.h" + +#include "lwip/dhcp.h" +#include "lwip/netifapi.h" +#include "los_strnlen_user.h" +#include "linux/kernel.h" +#ifdef LOSCFG_SHELL +#include "shcmd.h" +#include "shell.h" +#endif + +#define LWIP_STATIC static + +#if LWIP_ARP +extern sys_sem_t ip_conflict_detect; +#endif +extern volatile int tcpip_init_finish; +extern const char *const tcp_state_str[]; +extern int get_unused_socket_num(void); + +#if LWIP_IPV6 +#define LWIP_MAX_PING6_ARG_COUNT 64 +#define LWIP_PING6_STANDARD_PKT_SIZE 56 +#define LWIP_PING6_STARTING_SEQ_NUM 0x2255 +#define LWIP_PING6_OUT_OF_ORDER_MAGNITUDE 1 + +#define LWIP_PING6_COUNT_ARG 1 +#define LWIP_PING6_SOURCE_ADDRESS_ARG 2 +#define LWIP_PING6_INTERFACE_ARG 4 +#define LWIP_PING6_HOSTNAME_ARG 8 +#define LWIP_PING6_DEFAULT_SOCKET 16 +#endif + +/* Forward Declarations [START] */ +#ifndef LWIP_TESTBED +LWIP_STATIC +#endif +int print_netif(struct netif *netif, char *print_buf, unsigned int buf_len); + +#ifndef LWIP_TESTBED +LWIP_STATIC +#endif +void lwip_ifconfig_show_internal(void *arg); + +#ifndef LWIP_TESTBED +LWIP_STATIC +#endif +void lwip_ifconfig_internal(void *arg); + +void lwip_printsize(size_t size); +LWIP_STATIC void lwip_ifconfig_usage(const char *cmd); + +#ifndef LWIP_TESTBED +LWIP_STATIC +#endif +void lwip_arp_show_internal(struct netif *netif, char *printf_buf, unsigned int buf_len); + +#ifndef LWIP_TESTBED +LWIP_STATIC +#endif +void lwip_arp_internal(void *arg); + +LWIP_STATIC void lwip_arp_usage(const char *cmd); +void ifup_internal(void *arg); +void ifdown_internal(void *arg); + +#if LWIP_DNS +LWIP_STATIC unsigned int get_hostip(const char *hname); + +#ifndef LWIP_TESTBED +LWIP_STATIC +#endif +struct hostent *gethostnameinfo(const char *host); + +#endif /* LWIP_DNS */ + +#ifdef LWIP_DEBUG_INFO +LWIP_STATIC u32_t netdebug_memp(int argc, const char **argv); +LWIP_STATIC u32_t netdebug_sock(int argc, const char **argv); +u32_t osShellNetDebug(int argc, const char **argv); +u32_t osShellIpDebug(int argc, const char **argv); +#endif /* LWIP_DEBUG_INFO */ +#if LWIP_IPV6 +/* Holds params for ping6 task */ +typedef struct ping6_args { + u8_t args_found; + u8_t interface_index; + u8_t host_index; + u8_t pad; + u32_t pingcount; + ip6_addr_t src_addr; + ip6_addr_t dst_addr; +} ping6_args_t; + +/* Holds stats for ongoing ping6 task */ +typedef struct ping6_stats { + u32_t flag; + u32_t min_rtt; + u32_t max_rtt; + float avg_rtt; +} ping6_stats_t; +LWIP_STATIC void update_ping6_stats(ping6_stats_t *ping6_stats, u32_t rtt, u32_t nreceived); +LWIP_STATIC int parse_args_ping6(int argc, const char **argv, ping6_args_t *ping6_params); + +u32_t osShellPing6(int argc, const char **argv); +LWIP_STATIC int create_ping6_socket(u8_t type, const void *param); +LWIP_STATIC const char *convert_icmpv6_err_to_string(u8_t err_type); +#endif /* LWIP_IPV6 */ +u32_t osTcpserver(int argc, const char **argv); +void udpserver(int argc, const char **argv); +void tcp_access(int sockfd); +#if LWIP_IPV6 +int netstat_get_udp_sendQLen6(struct udp_pcb *udppcb, struct pbuf *udpbuf); +int netstat_udp_sendq6(struct udp_pcb *upcb); +#endif +#if LWIP_IPV4 +int netstat_get_udp_sendQLen(struct udp_pcb *udppcb, struct pbuf *udpbuf); +#endif +int netstat_tcp_sendq(struct tcp_pcb *tpcb); +int netstat_tcp_recvq(struct tcp_pcb *tpcb); +int netstat_netconn_recvq(const struct netconn *conn); + +int netstat_udp_sendq(struct udp_pcb *upcb); +int netstat_netconn_sendq(struct netconn *conn); +/* Forward Declarations [END] */ + +#define IFCONFIG_OPTION_SET_IP (1) +#define IFCONFIG_OPTION_SET_NETMASK (1 << 1) +#define IFCONFIG_OPTION_SET_GW (1 << 2) +#define IFCONFIG_OPTION_SET_HW (1 << 3) +#define IFCONFIG_OPTION_SET_UP (1 << 4) +#define IFCONFIG_OPTION_SET_DOWN (1 << 5) +#define IFCONFIG_OPTION_SET_MTU (1 << 6) +#define IFCONFIG_OPTION_DEL_IP (1 << 7) + +#define NETSTAT_ENTRY_SIZE 120 +#define MAX_NETSTAT_ENTRY (NETSTAT_ENTRY_SIZE * (MEMP_NUM_TCP_PCB + MEMP_NUM_UDP_PCB + MEMP_NUM_TCP_PCB_LISTEN + 1)) + +#define PRINT_BUF_LEN 1024 +#define MAX_MACADDR_STRING_LENGTH 18 /* including NULL */ + +#define CONVERT_STRING_TO_HEX(_src, _dest) \ +{ \ + const char *_srcString = (char *)_src; \ + _dest = 0; \ + while (*_srcString) { \ + _dest = (unsigned char)((_dest << 4) & 0xFF); \ + if ((*_srcString >= 48) && (*_srcString <= 57)) /* between 0 to 9 */ \ + _dest |= (unsigned char)(*_srcString - 48); \ + else if ((*_srcString >= 65 && *_srcString <= 70)) /* between A to F */ \ + _dest |= (unsigned char)((*_srcString - 65) + 10); \ + else if ((*_srcString >= 97 && *_srcString <= 102)) /* between a to f */ \ + _dest |= (unsigned char)((*_srcString - 97) + 10); \ + else break; \ + ++_srcString; \ + } \ +} + +#define ERR_IFCONFIG_STRING_PUT(ret, str) \ + do { \ + (ret) = snprintf_s(ifconfig_cmd->cb_print_buf + ifconfig_cmd->print_len, \ + PRINT_BUF_LEN - ifconfig_cmd->print_len, \ + ((PRINT_BUF_LEN - ifconfig_cmd->print_len) - 1), (str)); \ + if (((ret) > 0) && ((unsigned int)(ret) < (PRINT_BUF_LEN - ifconfig_cmd->print_len))) \ + ifconfig_cmd->print_len += (unsigned int)(ret); \ + } while (0) \ + +#define LWIP_MSECS_TO_SECS(time_in_msecs) (time_in_msecs / 1000) +struct ifconfig_option { + char iface[IFNAMSIZ]; + unsigned int option; + ip_addr_t ip_addr; + ip_addr_t netmask; + ip_addr_t gw; + unsigned char ethaddr[6]; + u16_t mtu; + /* when using telnet, print to the telnet socket will result in system */ + /* deadlock. So we cache the print data to a buf, and when the tcpip */ + /* callback returns, then print the data out to the telnet socket */ + sys_sem_t cb_completed; + char cb_print_buf[PRINT_BUF_LEN]; + unsigned int print_len; +}; + +struct netstat_data { + s8_t *netstat_out_buf; + u32_t netstat_out_buf_len; + u32_t netstat_out_buf_updated_len; + sys_sem_t cb_completed; +}; + +struct if_cmd_data { + char *if_name; + err_t err; + sys_sem_t cb_completed; +}; + +#ifndef LWIP_TESTBED +LWIP_STATIC +#endif +int print_netif(struct netif *netif, char *print_buf, unsigned int buf_len) +{ + int i, ret; + char *tmp = print_buf; +#if LWIP_IPV6 + char *addr = NULL; +#endif +#ifdef LOSCFG_NET_CONTAINER + struct net_group *group = get_net_group_from_netif(netif); +#endif + if (buf_len < 1) { + goto out; + } + if (netif->link_layer_type == LOOPBACK_IF) { + ret = snprintf_s(tmp, buf_len, (buf_len - 1), "%.2s\t", netif->name); + } else { + ret = snprintf_s(tmp, buf_len, (buf_len - 1), "%s\t", netif_get_name(netif)); + } + if ((ret <= 0) || ((unsigned int)ret >= buf_len)) + goto out; + tmp += ret; + buf_len -= (unsigned int)ret; +#if LWIP_IPV4 + ret = snprintf_s(tmp, buf_len, (buf_len - 1), "ip:%s ", ipaddr_ntoa(&netif->ip_addr)); + if ((ret <= 0) || ((unsigned int)ret >= buf_len)) + goto out; + tmp += ret; + buf_len -= (unsigned int)ret; + + ret = snprintf_s(tmp, buf_len, (buf_len - 1), "netmask:%s ", ipaddr_ntoa(&netif->netmask)); + if ((ret <= 0) || ((unsigned int)ret >= buf_len)) + goto out; + tmp += ret; + buf_len -= (unsigned int)ret; + + ret = snprintf_s(tmp, buf_len, (buf_len - 1), "gateway:%s\n", ipaddr_ntoa(&netif->gw)); + if ((ret <= 0) || ((unsigned int)ret >= buf_len)) + goto out; + tmp += ret; + buf_len -= (unsigned int)ret; +#endif + +#if LWIP_IPV6 + for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { + /* only PREFERRED addresses are displyaed */ + if (!ip6_addr_isvalid(netif->ip6_addr_state[i])) { + continue; + } + addr = ip6addr_ntoa((const ip6_addr_t *)&netif->ip6_addr[i]); + ret = snprintf_s(tmp, buf_len, (buf_len - 1), "\tip6: %s/64\n", addr ? addr : "::"); + if ((ret <= 0) || ((unsigned int)ret >= buf_len)) + goto out; + tmp += ret; + buf_len -= (unsigned int)ret; + } +#endif + + ret = snprintf_s(tmp, buf_len, (buf_len - 1), "\tHWaddr "); + if ((ret <= 0) || ((unsigned int)ret >= buf_len)) + goto out; + tmp += ret; + buf_len -= (unsigned int)ret; + + for (i = 0; i < netif->hwaddr_len - 1; i++) { + ret = snprintf_s(tmp, buf_len, (buf_len - 1), "%02x:", netif->hwaddr[i]); + if ((ret <= 0) || ((unsigned int)ret >= buf_len)) + goto out; + tmp += ret; + buf_len -= (unsigned int)ret; + } + + ret = snprintf_s(tmp, buf_len, (buf_len - 1), "%02x", netif->hwaddr[i]); + if ((ret <= 0) || ((unsigned int)ret >= buf_len)) + goto out; + tmp += ret; + buf_len -= (unsigned int)ret; + + ret = snprintf_s(tmp, buf_len, (buf_len - 1), " MTU:%d %s", netif->mtu, + (netif->flags & NETIF_FLAG_UP) ? "Running" : "Stop"); + if ((ret <= 0) || ((unsigned int)ret >= buf_len)) + goto out; + tmp += ret; + buf_len -= (unsigned int)ret; + +#ifdef LOSCFG_NET_CONTAINER + if ((group->netif_default == netif) && (netif_is_up(netif))) { +#else + if (netif_default == netif && netif_is_up(netif)) { +#endif + ret = snprintf_s(tmp, buf_len, (buf_len - 1), " %s", "Default"); + if ((ret <= 0) || ((unsigned int)ret >= buf_len)) + goto out; + tmp += ret; + buf_len -= (unsigned int)ret; + } + + ret = snprintf_s(tmp, buf_len, (buf_len - 1), " %s\n", + (netif->flags & NETIF_FLAG_LINK_UP) ? "Link UP" : "Link Down"); + if ((ret <= 0) || ((unsigned int)ret >= buf_len)) + goto out; + tmp += ret; + +#if MIB2_STATS + ret = snprintf_s(tmp, buf_len, (buf_len - 1), "\tRX packets:%u ", + netif->mib2_counters.ifinucastpkts + netif->mib2_counters.ifinnucastpkts); + if ((ret <= 0) || ((unsigned int)ret >= buf_len)) + goto out; + tmp += ret; + buf_len -= (unsigned int)ret; + + ret = snprintf_s(tmp, buf_len, (buf_len - 1), "errors:%u ", netif->mib2_counters.ifinerrors); + if ((ret <= 0) || ((unsigned int)ret >= buf_len)) + goto out; + tmp += ret; + buf_len -= (unsigned int)ret; + + ret = snprintf_s(tmp, buf_len, (buf_len - 1), "dropped:%u ", netif->mib2_counters.ifindiscards); + if ((ret <= 0) || ((unsigned int)ret >= buf_len)) + goto out; + tmp += ret; + buf_len -= (unsigned int)ret; + + ret = snprintf_s(tmp, buf_len, (buf_len - 1), "overruns:%u\n", netif->mib2_counters.ifinoverruns); + if ((ret <= 0) || ((unsigned int)ret >= buf_len)) + goto out; + tmp += ret; + buf_len -= (unsigned int)ret; + + ret = snprintf_s(tmp, buf_len, (buf_len - 1), "\tTX packets:%u ", + netif->mib2_counters.ifoutucastpkts + netif->mib2_counters.ifoutnucastpkts); + if ((ret <= 0) || ((unsigned int)ret >= buf_len)) + goto out; + tmp += ret; + buf_len -= (unsigned int)ret; + + ret = snprintf_s(tmp, buf_len, (buf_len - 1), "errors:%u ", netif->mib2_counters.ifouterrors); + if ((ret <= 0) || ((unsigned int)ret >= buf_len)) + goto out; + tmp += ret; + buf_len -= (unsigned int)ret; + + ret = snprintf_s(tmp, buf_len, (buf_len - 1), "dropped:%u\n", netif->mib2_counters.ifoutdiscards); + if ((ret <= 0) || ((unsigned int)ret >= buf_len)) + goto out; + tmp += ret; + buf_len -= (unsigned int)ret; + + ret = snprintf_s(tmp, buf_len, (buf_len - 1), "\tRX bytes:%u ", netif->mib2_counters.ifinoctets); + if ((ret <= 0) || ((unsigned int)ret >= buf_len)) + goto out; + tmp += ret; + buf_len -= (unsigned int)ret; + + ret = snprintf_s(tmp, buf_len, (buf_len - 1), "TX bytes:%u\n", netif->mib2_counters.ifoutoctets); + if ((ret <= 0) || ((unsigned int)ret >= buf_len)) + goto out; + tmp += ret; + buf_len -= (unsigned int)ret; +#endif + +out: + return (int)(tmp - print_buf); +} + +#ifndef LWIP_TESTBED +LWIP_STATIC +#endif +void lwip_ifconfig_show_internal(void *arg) +{ + struct netif *netif = NULL; + struct ifconfig_option *ifconfig_cmd = (struct ifconfig_option *)arg; + int ret; +#ifdef LOSCFG_NET_CONTAINER + struct net_group *group = get_curr_process_net_group(); + if (group->netif_list == NULL) { +#else + if (netif_list == NULL) { +#endif + ret = snprintf_s(ifconfig_cmd->cb_print_buf, PRINT_BUF_LEN - ifconfig_cmd->print_len, + ((PRINT_BUF_LEN - ifconfig_cmd->print_len) - 1), "Device not init\n"); + if ((ret > 0) && ((unsigned int)ret < (PRINT_BUF_LEN - ifconfig_cmd->print_len))) { + ifconfig_cmd->print_len += (unsigned int)ret; + } + sys_sem_signal(&ifconfig_cmd->cb_completed); + return; + } + + if (ifconfig_cmd->iface[0] == '\0') { + /* display all netif */ +#ifdef LOSCFG_NET_CONTAINER + for (netif = group->netif_list; netif != NULL; netif = netif->next) { +#else + for (netif = netif_list; netif != NULL; netif = netif->next) { +#endif + ret = print_netif(netif, ifconfig_cmd->cb_print_buf + ifconfig_cmd->print_len, + PRINT_BUF_LEN - ifconfig_cmd->print_len); + ifconfig_cmd->print_len += (unsigned int)ret; + } + } else { + netif = netif_find(ifconfig_cmd->iface); + if (netif == NULL) { + ret = snprintf_s(ifconfig_cmd->cb_print_buf + ifconfig_cmd->print_len, + (PRINT_BUF_LEN - ifconfig_cmd->print_len), + ((PRINT_BUF_LEN - ifconfig_cmd->print_len) - 1), "Device not found\n"); + if ((ret > 0) && ((unsigned int)ret < (PRINT_BUF_LEN - ifconfig_cmd->print_len))) { + ifconfig_cmd->print_len += (unsigned int)ret; + } + + sys_sem_signal(&ifconfig_cmd->cb_completed); + return; + } + + ret = print_netif(netif, ifconfig_cmd->cb_print_buf + ifconfig_cmd->print_len, + PRINT_BUF_LEN - ifconfig_cmd->print_len); + ifconfig_cmd->print_len += (unsigned int)ret; + } + sys_sem_signal(&ifconfig_cmd->cb_completed); +} + +#ifndef LWIP_TESTBED +LWIP_STATIC +#endif +void lwip_ifconfig_internal(void *arg) +{ + struct ifconfig_option *ifconfig_cmd = NULL; + struct netif *netif = NULL; + ip_addr_t ip_addr; + ip_addr_t netmask; + ip_addr_t gw; + unsigned short mtu; + struct netif *loc_netif = NULL; + int ret; + s8_t idx; + err_t err; +#ifdef LOSCFG_NET_CONTAINER + struct net_group *group = get_curr_process_net_group(); +#endif + ifconfig_cmd = (struct ifconfig_option *)arg; + netif = netif_find(ifconfig_cmd->iface); + if (netif == NULL) { + ERR_IFCONFIG_STRING_PUT(ret, "Device not found\n"); + goto out; + } + + if (ifconfig_cmd->option & IFCONFIG_OPTION_SET_UP) { + (void)netif_set_up(netif); + goto out; + } else if (ifconfig_cmd->option & IFCONFIG_OPTION_SET_DOWN) { + (void)netif_set_down(netif); + goto out; + } + + if ((ifconfig_cmd->option & IFCONFIG_OPTION_SET_IP) || + (ifconfig_cmd->option & IFCONFIG_OPTION_SET_NETMASK) || + (ifconfig_cmd->option & IFCONFIG_OPTION_SET_HW)) { + (void)netif_set_down(netif); + } + + if (ifconfig_cmd->option & IFCONFIG_OPTION_SET_IP) { + ip_addr_set_val(&ip_addr, &(ifconfig_cmd->ip_addr)); + if (IP_IS_V4_VAL(ifconfig_cmd->ip_addr)) { + /* check the address is not multicast/broadcast/0/loopback */ + if (ip_addr_ismulticast_val(&ip_addr) || ip_addr_isbroadcast_val(&ip_addr, netif) || + ip_addr_isany(&ip_addr) || ip_addr_isloopback(&ip_addr)) { + ERR_IFCONFIG_STRING_PUT(ret, "Don't set ip as a multicast/broadcast/0/loopback address!\n"); + goto out; + } + + /* reset gateway if new and previous ipaddr not in same net */ + if (!ip_addr_netcmp_val(&ip_addr, &netif->ip_addr, ip_2_ip4(&netif->netmask))) { + ip_addr_set_zero(&netif->gw); +#ifdef LOSCFG_NET_CONTAINER + if (netif == group->netif_default) { + (void)netif_set_default(NULL, group); +#else + if (netif == netif_default) { + (void)netif_set_default(NULL); +#endif + } + } + + /* lwip disallow two netif sit in same net at the same time */ +#ifdef LOSCFG_NET_CONTAINER + loc_netif = group->netif_list; +#else + loc_netif = netif_list; +#endif + while (loc_netif != NULL) { + if (loc_netif == netif) { + loc_netif = loc_netif->next; + continue; + } + if (IP_IS_V4_VAL(ifconfig_cmd->ip_addr) && ip_addr_cmp(&netif->netmask, &loc_netif->netmask) && + ip_addr_netcmp_val(&loc_netif->ip_addr, &ip_addr, ip_2_ip4(&netif->netmask))) { + ERR_IFCONFIG_STRING_PUT(ret, "Duplicate network!\n"); + goto out; + } + loc_netif = loc_netif->next; + } + +#if LWIP_DHCP + if (netif_dhcp_data(netif) && netif_dhcp_data(netif)->state != DHCP_STATE_OFF) { + (void)netif_dhcp_off(netif); + } +#endif + netif_set_ipaddr(netif, ip_2_ip4(&ip_addr)); + } else if (IP_IS_V6_VAL(ifconfig_cmd->ip_addr)) { + idx = -1; + err = netif_add_ip6_address(netif, ip_2_ip6(&ip_addr), &idx); + if (err != ERR_OK || idx == -1) { + ERR_IFCONFIG_STRING_PUT(ret, "The IPv6 has reached the Global address limit, " + "you should delete one address before add!\n"); + goto out; + } + } + } + + if (ifconfig_cmd->option & IFCONFIG_OPTION_DEL_IP) { + (void)netif_do_rmv_ipv6_addr(netif, &ifconfig_cmd->ip_addr); + } + + if (ifconfig_cmd->option & IFCONFIG_OPTION_SET_NETMASK) { + ip_addr_set_val(&netmask, &(ifconfig_cmd->netmask)); + /* check data valid */ + if (!ip_addr_netmask_valid(ip_2_ip4(&netmask))) { + ERR_IFCONFIG_STRING_PUT(ret, "ifconfig: netmask is invalid!\n"); + goto out; + } + +#if LWIP_DHCP + if (netif_dhcp_data(netif) && netif_dhcp_data(netif)->state != DHCP_STATE_OFF) { + (void)netif_dhcp_off(netif); + } +#endif + if (netif_ip4_netmask(netif)->addr != ip_2_ip4(&netmask)->addr) { + /* lwip disallow two netif sit in same net at the same time */ +#ifdef LOSCFG_NET_CONTAINER + loc_netif = group->netif_list; +#else + loc_netif = netif_list; +#endif + while (loc_netif != NULL) { + if (loc_netif == netif) { + loc_netif = loc_netif->next; + continue; + } + if (ip_addr_cmp(&loc_netif->netmask, &netmask) && + ip_addr_netcmp(&loc_netif->ip_addr, &netif->ip_addr, ip_2_ip4(&netmask))) { + ERR_IFCONFIG_STRING_PUT(ret, "Duplicate network!\n"); + goto out; + } + loc_netif = loc_netif->next; + } + netif_set_netmask(netif, ip_2_ip4(&netmask)); + /* check if gateway still reachable */ + if (!ip_addr_netcmp(&netif->gw, &netif->ip_addr, ip_2_ip4(&netmask))) { + ip_addr_set_zero(&(netif->gw)); +#ifdef LOSCFG_NET_CONTAINER + if (netif == group->netif_default) { + (void)netif_set_default(NULL, group); +#else + if (netif == netif_default) { + (void)netif_set_default(NULL); +#endif + } + } + } + } + + if ((ifconfig_cmd->option & IFCONFIG_OPTION_SET_HW) && + netif_set_hwaddr(netif, ifconfig_cmd->ethaddr, NETIF_MAX_HWADDR_LEN) != ERR_OK) { + ERR_IFCONFIG_STRING_PUT(ret, "Failed to update the hwaddr of the device!\n"); + (void)netif_set_up(netif); + goto out; + } + + if ((ifconfig_cmd->option & IFCONFIG_OPTION_SET_IP) || + (ifconfig_cmd->option & IFCONFIG_OPTION_SET_NETMASK) || + (ifconfig_cmd->option & IFCONFIG_OPTION_SET_HW)) { + (void)netif_set_up(netif); + } + + if (ifconfig_cmd->option & IFCONFIG_OPTION_SET_GW) { + ip_addr_set_val(&gw, &ifconfig_cmd->gw); + + /* check the address multicast/0/loopback */ + if (ip_addr_ismulticast_val(&gw) || ip_addr_isbroadcast_val(&gw, netif) || + ip_addr_isany(&gw) || ip_addr_isloopback(&gw)) { + ERR_IFCONFIG_STRING_PUT(ret, "Don't set gateway as a multicast/broadcast/0/loopback address!\n"); + goto out; + } + + /* check if reachable */ + if (!ip_addr_netcmp_val(&gw, &netif->ip_addr, ip_2_ip4(&netif->netmask))) { + ERR_IFCONFIG_STRING_PUT(ret, "The address is unreachable!\n"); + goto out; + } + +#ifdef LOSCFG_NET_CONTAINER + if (group->netif_default != netif) { + ip_addr_set_zero(&netif->gw); + (void)netif_set_default(netif, group); +#else + if (netif_default != netif) { + ip_addr_set_zero(&netif->gw); + (void)netif_set_default(netif); +#endif + } + +#if LWIP_DHCP + if (netif_dhcp_data(netif) && netif_dhcp_data(netif)->state != DHCP_STATE_OFF) { + (void)netif_dhcp_off(netif); + } +#endif + netif_set_gw(netif, ip_2_ip4(&gw)); + } + + if (ifconfig_cmd->option & IFCONFIG_OPTION_SET_MTU) { + mtu = ifconfig_cmd->mtu; + if (netif_set_mtu(netif, mtu) != ERR_OK) { + ERR_IFCONFIG_STRING_PUT(ret, "Invalid MTU\n"); + } + } +out: + sys_sem_signal(&ifconfig_cmd->cb_completed); +} + + +void lwip_printsize(size_t size) +{ + static const char *SIZES[] = {"B", "KB", "MB", "GB"}; + size_t divis = 0; + size_t rem = 0; + + while ((size >= 1024) && (divis < ((sizeof(SIZES) / sizeof(char *)) - 1))) { + rem = (size % 1024); + divis++; + size /= 1024; + } + + PRINTK("(%.1f %s) \r\n", (float)size + (float)rem / 1024.0, SIZES[divis]); +} + +LWIP_STATIC void lwip_ifconfig_usage(const char *cmd) +{ + PRINTK("Usage:"\ + "\n%s [-a] "\ + "\n[interface]"\ + "\n[interface ipaddr] "\ + "\n[interface inet6 add|del ipaddr]"\ + "\n[interface hw ether MAC]"\ + "\n[interface mtu NN]"\ + "\n[interface up|down]\n", + cmd); +} + +u32_t lwip_ifconfig(int argc, const char **argv) +{ + int i; + static struct ifconfig_option ifconfig_cmd; + err_t ret; + +#if LWIP_STATS + u32_t stat_err_cnt; + u32_t stat_drop_cnt; + u32_t stat_rx_or_tx_cnt; + u32_t stat_rx_or_tx_bytes; +#endif + +#if LWIP_ARP + u32_t retval; + struct netif *netiftmp = NULL; +#if LWIP_ENABLE_IP_CONFLICT_SIGNAL + u32_t old_ip4addr; + err_t err; + extern sys_sem_t ip_conflict_detect; + extern u32_t is_ip_conflict_signal; +#endif /* LWIP_ENABLE_IP_CONFLICT_SIGNAL */ +#endif /* LWIP_ARP */ +#if LWIP_IPV6 + extern sys_sem_t dup_addr_detect; + extern u32_t is_dup_detect_initialized; +#endif + if (!tcpip_init_finish) { + PRINTK("%s: tcpip_init have not been called\n", __FUNCTION__); + return 2; + } + /* To support "ifconfig -a" command + RX packets:XXXX errors:X dropped:X overruns:X bytes:XXXX (Human readable format) + TX packets:XXXX errors:X dropped:X overruns:X bytes:XXXX (Human readable format) + + Below is assumed for 'overrun' stat. + Linux Kernel: + RX: FIFO overrun + Data structure: net_device->stats->rx_fifo_errors + Flag which is marked when FIFO overrun: ENRSR_FO + + Function: ei_receive->ENRSR_FO + + TX: A "FIFO underrun" occurred during transmit. + Data structure: net_device->stats->tx_fifo_errors + Flag which is marked when FIFO underrun: ENTSR_FU + + Function: ei_tx_intr->ENTSR_FU + + LWIP: + So in our case, + while receiving a packet RX case, if the buffer is full (trypost - it is sys_mbox_trypost) + the error will be returned, we can consider that an overflow has happened. + So this can be RX overrun. + + But while transmitting a packet TX case, underrun cannot happen because it block on the + message Q if it is full (NOT trypost - it is sys_mbox_post). So TX overrun is always 0. + */ + if (argc) { + if (strcmp("-a", argv[0]) == 0) { +#if LWIP_STATS + stat_rx_or_tx_cnt = lwip_stats.ip.recv; + stat_err_cnt = (u32_t)(lwip_stats.ip.ip_rx_err + + lwip_stats.ip.lenerr + + lwip_stats.ip.chkerr + + lwip_stats.ip.opterr + + lwip_stats.ip.proterr); + stat_drop_cnt = (u32_t)(lwip_stats.ip.drop + lwip_stats.link.link_rx_drop); + stat_rx_or_tx_bytes = lwip_stats.ip.ip_rx_bytes; + + PRINTK("%18s:%u\t errors:%u\t ip dropped:%u\t link dropped:%u\t overrun:%d\t bytes:%u ", + "RX packets", + stat_rx_or_tx_cnt, + stat_err_cnt, + stat_drop_cnt, + lwip_stats.link.link_rx_drop, + lwip_stats.ip.link_rx_overrun, + stat_rx_or_tx_bytes); + + /* Print in Human readable format of the incoming bytes */ + lwip_printsize(lwip_stats.ip.ip_rx_bytes); +#if IP6_STATS + stat_rx_or_tx_cnt = lwip_stats.ip6.recv; + stat_err_cnt = (u32_t)(lwip_stats.ip6.ip_rx_err + + lwip_stats.ip6.lenerr + + lwip_stats.ip6.chkerr + + lwip_stats.ip6.opterr + + lwip_stats.ip6.proterr); + stat_drop_cnt = lwip_stats.ip6.drop; + stat_rx_or_tx_bytes = lwip_stats.ip6.ip_rx_bytes; + + PRINTK("%18s:%u\t errors:%u\t dropped:%u\t overrun:%d\t bytes:%u ", + "RX packets(ip6)", + stat_rx_or_tx_cnt, + stat_err_cnt, + stat_drop_cnt, + lwip_stats.ip.link_rx_overrun, + stat_rx_or_tx_bytes); + + /* Print in Human readable format of the incoming bytes */ + lwip_printsize(lwip_stats.ip6.ip_rx_bytes); +#endif + stat_rx_or_tx_cnt = (u32_t)(lwip_stats.ip.fw + lwip_stats.ip.xmit); + stat_err_cnt = (u32_t)(lwip_stats.ip.rterr + lwip_stats.ip.ip_tx_err); + /* IP layer drop stat param is not maintained, failure at IP is considered in 'errors' stat */ + stat_drop_cnt = lwip_stats.link.link_tx_drop; + stat_rx_or_tx_bytes = lwip_stats.ip.ip_tx_bytes; + + PRINTK("%18s:%u\t errors:%u\t link dropped:%u\t overrun:0\t bytes:%u", + "TX packets", + stat_rx_or_tx_cnt, + stat_err_cnt, + stat_drop_cnt, + stat_rx_or_tx_bytes); + + /* Print in Human readable format of the outgoing bytes */ + lwip_printsize(lwip_stats.ip.ip_tx_bytes); + + stat_rx_or_tx_cnt = (u32_t)(lwip_stats.ip6.fw + lwip_stats.ip6.xmit); + stat_err_cnt = (u32_t)(lwip_stats.ip6.rterr + lwip_stats.ip6.ip_tx_err); + stat_rx_or_tx_bytes = lwip_stats.ip6.ip_tx_bytes; + + PRINTK("%18s:%u\t errors:%u\t overrun:0\t bytes:%u", + "TX packets(ip6)", + stat_rx_or_tx_cnt, + stat_err_cnt, + stat_rx_or_tx_bytes); + + /* Print in Human readable format of the outgoing bytes */ + lwip_printsize(lwip_stats.ip6.ip_tx_bytes); +#endif /* LWIP_STATS */ + return 0; + } + } + + (void)memset_s(&ifconfig_cmd, sizeof(ifconfig_cmd), 0, sizeof(ifconfig_cmd)); + if (sys_sem_new(&ifconfig_cmd.cb_completed, 0) != ERR_OK) { + PRINTK("%s: sys_sem_new fail\n", __FUNCTION__); + return 1; + } + + i = 0; + /* Get the interface */ + if (argc > 0) { + if (strlen(argv[i]) < IFNAMSIZ) { + if (strncpy_s(ifconfig_cmd.iface, IFNAMSIZ, argv[i], (strlen(argv[i]))) != EOK) { + sys_sem_free(&ifconfig_cmd.cb_completed); + PRINTK("ifconfig : strncpy_s error\n"); + return 1; + } + ifconfig_cmd.iface[IFNAMSIZ - 1] = '\0'; + } else { + sys_sem_free(&ifconfig_cmd.cb_completed); + PRINTK("ifconfig : interface name is too big\n"); + return 1; + } + i++; + argc--; + if (argc == 0) { + /* no more arguments, show the interface state. */ + ret = tcpip_callback(lwip_ifconfig_show_internal, &ifconfig_cmd); + if (ret != ERR_OK) { + sys_sem_free(&ifconfig_cmd.cb_completed); + PRINTK("ifconfig : internal error, l:%d err:%d\n", __LINE__, ret); + return 1; + } + (void)sys_arch_sem_wait(&ifconfig_cmd.cb_completed, 0); + sys_sem_free(&ifconfig_cmd.cb_completed); + ifconfig_cmd.cb_print_buf[PRINT_BUF_LEN - 1] = '\0'; + PRINTK("%s", ifconfig_cmd.cb_print_buf); + return 0; + } + } else { + /* no more arguments, show all the interface state. */ + ret = tcpip_callback(lwip_ifconfig_show_internal, &ifconfig_cmd); + if (ret != ERR_OK) { + sys_sem_free(&ifconfig_cmd.cb_completed); + PRINTK("ifconfig : internal error, l:%d err:%d\n", __LINE__, ret); + return 1; + } + (void)sys_arch_sem_wait(&ifconfig_cmd.cb_completed, 0); + sys_sem_free(&ifconfig_cmd.cb_completed); + ifconfig_cmd.cb_print_buf[PRINT_BUF_LEN - 1] = '\0'; + PRINTK("%s", ifconfig_cmd.cb_print_buf); + + return 0; + } + + /* ifup/ifdown */ + if (strcmp("up", argv[i]) == 0) { + ifconfig_cmd.option |= IFCONFIG_OPTION_SET_UP; + /* setup the interface, other arguments is ignored. */ + ret = tcpip_callback(lwip_ifconfig_internal, &ifconfig_cmd); + if (ret != ERR_OK) { + sys_sem_free(&ifconfig_cmd.cb_completed); + PRINTK("ifconfig : internal error, l:%d err:%d\n", __LINE__, ret); + return 1; + } + (void)sys_arch_sem_wait(&ifconfig_cmd.cb_completed, 0); + sys_sem_free(&ifconfig_cmd.cb_completed); + ifconfig_cmd.cb_print_buf[PRINT_BUF_LEN - 1] = '\0'; + PRINTK("%s", ifconfig_cmd.cb_print_buf); + return 0; + } else if (strcmp("down", argv[i]) == 0) { + ifconfig_cmd.option |= IFCONFIG_OPTION_SET_DOWN; + /* setdown the interface, other arguments is ignored. */ + ret = tcpip_callback(lwip_ifconfig_internal, &ifconfig_cmd); + if (ret != ERR_OK) { + sys_sem_free(&ifconfig_cmd.cb_completed); + PRINTK("ifconfig : internal error, l:%d err:%d\n", __LINE__, ret); + return 1; + } + (void)sys_arch_sem_wait(&ifconfig_cmd.cb_completed, 0); + sys_sem_free(&ifconfig_cmd.cb_completed); + ifconfig_cmd.cb_print_buf[PRINT_BUF_LEN - 1] = '\0'; + PRINTK("%s", ifconfig_cmd.cb_print_buf); + return 0; + } + /* check if set the ip address. */ +#if LWIP_ARP + netiftmp = netifapi_netif_find_by_name(ifconfig_cmd.iface); + if (netiftmp == NULL) { + sys_sem_free(&ifconfig_cmd.cb_completed); + PRINTK("ifconfig : Interface %s not found\n", ifconfig_cmd.iface); + return 1; + } +#if LWIP_ENABLE_IP_CONFLICT_SIGNAL + old_ip4addr = ipaddr_addr(ipaddr_ntoa(&netiftmp->ip_addr)); +#endif /* LWIP_ENABLE_IP_CONFLICT_SIGNAL */ +#endif /* LWIP_ARP */ + if (!strcmp(argv[i], "inet") || ip4addr_aton(argv[i], ip_2_ip4(&ifconfig_cmd.ip_addr))) { + if (!strcmp(argv[i], "inet")) { + if (argc <= 1) { + sys_sem_free(&ifconfig_cmd.cb_completed); + goto ifconfig_error; + } + + if (!ip4addr_aton(argv[i + 1], ip_2_ip4(&ifconfig_cmd.ip_addr))) { + sys_sem_free(&ifconfig_cmd.cb_completed); + PRINTK("ifconfig : Invalid IPv4 Address\n"); + return 1; + } + argc--; + i++; + } + IP_SET_TYPE_VAL((ifconfig_cmd.ip_addr), IPADDR_TYPE_V4); +#if LWIP_ARP + if (!ip_addr_cmp(&ifconfig_cmd.ip_addr, &netiftmp->ip_addr)) { + ifconfig_cmd.option |= IFCONFIG_OPTION_SET_IP; + } +#else + ifconfig_cmd.option |= IFCONFIG_OPTION_SET_IP; +#endif /* LWIP_ARP */ + argc--; + i++; + } else if (!strcmp(argv[i], "inet6")) { + if (argc < 3) { + sys_sem_free(&ifconfig_cmd.cb_completed); + goto ifconfig_error; + } + if (strcmp(argv[i + 1], "add") && strcmp(argv[i + 1], "del")) { + sys_sem_free(&ifconfig_cmd.cb_completed); + goto ifconfig_error; + } + + if (!ip6addr_aton(argv[i + 2], ip_2_ip6(&ifconfig_cmd.ip_addr))) { + sys_sem_free(&ifconfig_cmd.cb_completed); + PRINTK("ifconfig : Invalid IPv6 Address\n"); + return 1; + } + + IP_SET_TYPE_VAL((ifconfig_cmd.ip_addr), IPADDR_TYPE_V6); + ifconfig_cmd.option |= (!strcmp(argv[i + 1], "add") ? IFCONFIG_OPTION_SET_IP : IFCONFIG_OPTION_DEL_IP); + argc -= 3; + i += 3; + } + + if (ifconfig_cmd.option & IFCONFIG_OPTION_DEL_IP) { + if (argc != 0) { + sys_sem_free(&ifconfig_cmd.cb_completed); + goto ifconfig_error; + } + } + + while (argc > 0) { + if (strcmp("netmask", argv[i]) == 0 && (argc > 1) && (ipaddr_addr(argv[i + 1]) != IPADDR_NONE)) { + /* if set netmask */ + ip_addr_set_ip4_u32_val((ifconfig_cmd.netmask), ipaddr_addr(argv[i + 1])); + ifconfig_cmd.option |= IFCONFIG_OPTION_SET_NETMASK; + i += 2; + argc -= 2; + } else if (strcmp("gateway", argv[i]) == 0 && (argc > 1) && (ipaddr_addr(argv[i + 1]) != IPADDR_NONE)) { + /* if set gateway */ + ip_addr_set_ip4_u32_val((ifconfig_cmd.gw), ipaddr_addr(argv[i + 1])); + ifconfig_cmd.option |= IFCONFIG_OPTION_SET_GW; + i += 2; + argc -= 2; + } else if (strcmp("hw", argv[i]) == 0 && argc > 2 && strcmp("ether", argv[i + 1]) == 0) { + /* if set HWaddr */ + char *digit = NULL; + u32_t macaddrlen = strlen(argv[i + 2]) + 1; + char tmpStr[MAX_MACADDR_STRING_LENGTH]; + char *tmpStr1 = NULL; + char *saveptr = NULL; + int j; + + if (macaddrlen != MAX_MACADDR_STRING_LENGTH) { + sys_sem_free(&ifconfig_cmd.cb_completed); + PRINTK("ifconfig : wrong MAC address format\n"); + return 1; + } + + if (strncpy_s(tmpStr, MAX_MACADDR_STRING_LENGTH, argv[i + 2], macaddrlen - 1) != 0) { + sys_sem_free(&ifconfig_cmd.cb_completed); + PRINTK("ifconfig : wrong MAC address\n"); + return 1; + } + for (j = 0, tmpStr1 = tmpStr; j < 6; j++, tmpStr1 = NULL) { + digit = strtok_r(tmpStr1, ":", &saveptr); + if ((digit == NULL) || (strlen(digit) > 2)) { + sys_sem_free(&ifconfig_cmd.cb_completed); + PRINTK("ifconfig : wrong MAC address format\n"); + return 1; + } + CONVERT_STRING_TO_HEX(digit, ifconfig_cmd.ethaddr[j]); + } + ifconfig_cmd.option |= IFCONFIG_OPTION_SET_HW; + i += 3; + argc -= 3; + } else if (!strcmp("mtu", argv[i]) && (argc > 1)) { + /* if set mtu */ + if ((atoi(argv[i + 1]) < 0) || (atoi(argv[i + 1]) > 0xFFFF)) { + sys_sem_free(&ifconfig_cmd.cb_completed); + PRINTK("\nifconfig: Invalid argument for mtu\n"); + goto ifconfig_error; + } + + ifconfig_cmd.mtu = (u16_t)(atoi(argv[i + 1])); + ifconfig_cmd.option |= IFCONFIG_OPTION_SET_MTU; + i += 2; + argc -= 2; + } else { + sys_sem_free(&ifconfig_cmd.cb_completed); + goto ifconfig_error; + } + } + +#if LWIP_ARP && LWIP_ENABLE_IP_CONFLICT_SIGNAL + if ((ifconfig_cmd.option & IFCONFIG_OPTION_SET_IP) && IP_IS_V4_VAL((ifconfig_cmd.ip_addr))) { + /* Create the semaphore for ip conflict detection. */ + if (sys_sem_new(&ip_conflict_detect, 0) != ERR_OK) { + sys_sem_free(&ifconfig_cmd.cb_completed); + PRINTK("ifconfig: internal error\n"); + return 1; + } + is_ip_conflict_signal = 1; + } +#endif /* LWIP_ARP && LWIP_ENABLE_IP_CONFLICT_SIGNAL */ + +#if LWIP_IPV6 + if ((ifconfig_cmd.option & IFCONFIG_OPTION_SET_IP) && IP_IS_V6_VAL((ifconfig_cmd.ip_addr))) { + /* Create the semaphore for duplicate address detection. */ + if (sys_sem_new(&dup_addr_detect, 0) != ERR_OK) { + sys_sem_free(&ifconfig_cmd.cb_completed); + PRINTK("ifconfig: internal error\n"); + return 1; + } + is_dup_detect_initialized = 1; + } +#endif /* LWIP_IPV6 */ + + ret = tcpip_callback(lwip_ifconfig_internal, &ifconfig_cmd); + if (ret != ERR_OK) { + sys_sem_free(&ifconfig_cmd.cb_completed); +#if LWIP_ARP && LWIP_ENABLE_IP_CONFLICT_SIGNAL + if ((ifconfig_cmd.option & IFCONFIG_OPTION_SET_IP) && IP_IS_V4_VAL((ifconfig_cmd.ip_addr))) { + is_ip_conflict_signal = 0; + sys_sem_free(&ip_conflict_detect); + } +#endif /* LWIP_ARP && LWIP_ENABLE_IP_CONFLICT_SIGNAL */ + +#if LWIP_IPV6 + if ((ifconfig_cmd.option & IFCONFIG_OPTION_SET_IP) && IP_IS_V6_VAL((ifconfig_cmd.ip_addr))) { + is_dup_detect_initialized = 0; + sys_sem_free(&dup_addr_detect); + } +#endif /* LWIP_IPV6 */ + + PRINTK("%s : tcpip_callback failed in line %d : errnu %d", __FUNCTION__, __LINE__, ret); + return 1; + } + (void)sys_arch_sem_wait(&ifconfig_cmd.cb_completed, 0); + ifconfig_cmd.cb_print_buf[PRINT_BUF_LEN - 1] = '\0'; + PRINTK("%s", ifconfig_cmd.cb_print_buf); +#if LWIP_ARP && LWIP_ENABLE_IP_CONFLICT_SIGNAL + /* Pend 2 seconds for waiting the arp reply if the ip is already in use. */ + if ((ifconfig_cmd.option & IFCONFIG_OPTION_SET_IP) && IP_IS_V4_VAL((ifconfig_cmd.ip_addr))) { + err = (err_t)sys_arch_sem_wait(&ip_conflict_detect, DUP_ARP_DETECT_TIME); + is_ip_conflict_signal = 0; + sys_sem_free(&ip_conflict_detect); + if (err < 0) { + /* The result neither conflict nor timeout. */ + PRINT_ERR("ifconfig: internal error\n"); + sys_sem_free(&ifconfig_cmd.cb_completed); + return 1; + } else if (err < DUP_ARP_DETECT_TIME) { + /* Duplicate use of new ip, restore it to the old one. */ + PRINT_ERR("ifconfig: ip conflict!\n"); + ip_addr_set_ip4_u32_val(ifconfig_cmd.ip_addr, old_ip4addr); + ret = tcpip_callback(lwip_ifconfig_internal, &ifconfig_cmd); + if (ret != ERR_OK) { + sys_sem_free(&ifconfig_cmd.cb_completed); + PRINTK("%s : tcpip_callback failed in line %d : errnu %d", __FUNCTION__, __LINE__, ret); + return 1; + } + (void)sys_arch_sem_wait(&ifconfig_cmd.cb_completed, 0); + sys_sem_free(&ifconfig_cmd.cb_completed); + ifconfig_cmd.cb_print_buf[PRINT_BUF_LEN - 1] = '\0'; + PRINTK("%s", ifconfig_cmd.cb_print_buf); + return 1; + } + } +#endif /* LWIP_ARP && LWIP_ENABLE_IP_CONFLICT_SIGNAL */ +#if LWIP_IPV6 + if ((ifconfig_cmd.option & IFCONFIG_OPTION_SET_IP) && IP_IS_V6_VAL(ifconfig_cmd.ip_addr)) { + /* Pend 2 seconds for waiting the arp reply if the ip is already in use. */ + retval = sys_arch_sem_wait(&dup_addr_detect, DUP_ARP_DETECT_TIME); + is_dup_detect_initialized = 0; + sys_sem_free(&dup_addr_detect); + if (retval == SYS_ARCH_ERROR) { + sys_sem_free(&ifconfig_cmd.cb_completed); + /* The result neither conflict nor timeout. */ + PRINT_ERR("ifconfig: internal error\n"); + return 1; + } else if (retval < DUP_ARP_DETECT_TIME) { + /* Duplicate use of new ip, restore it to the old one. */ + struct netif *netif = NULL; + PRINT_ERR("ifconfig: IP conflict!\n"); + netif = netifapi_netif_find_by_name(ifconfig_cmd.iface); + i = netif_get_ip6_addr_match(netif, &ifconfig_cmd.ip_addr.u_addr.ip6); + if (i >= 0) { + netif->ip6_addr_state[i] = IP6_ADDR_INVALID; + } + + sys_sem_free(&ifconfig_cmd.cb_completed); + ifconfig_cmd.cb_print_buf[PRINT_BUF_LEN - 1] = '\0'; + PRINTK("%s", ifconfig_cmd.cb_print_buf); + return 1; + } + } +#endif /* LWIP_IPV6 */ + sys_sem_free(&ifconfig_cmd.cb_completed); + return 0; +ifconfig_error: + lwip_ifconfig_usage("ifconfig"); + return 1; +} + +#ifdef LOSCFG_SHELL +SHELLCMD_ENTRY(ifconfig_shellcmd, CMD_TYPE_EX, "ifconfig", XARGS, (CmdCallBackFunc)lwip_ifconfig); +#endif /* LOSCFG_SHELL */ +/* add arp entry to arp cache */ +#define ARP_OPTION_ADD 1 +/* delete arp entry to arp cache */ +#define ARP_OPTION_DEL 2 +/* print all arp entry in arp cache */ +#define ARP_OPTION_SHOW 3 + +struct arp_option { + /* see the ARP_OPTION_ above */ + int option; + /* descriptive abbreviation of network interface */ + char iface[IFNAMSIZ]; + /* ip addr */ + unsigned int ipaddr; + /* hw addr */ + unsigned char ethaddr[6]; + /* when using telnet, print to the telnet socket will result in system */ + /* deadlock.so don't do it. cache the data to print to a buf, and when */ + /* callback returns, then print the data out to the telnet socket */ + sys_sem_t cb_completed; + char cb_print_buf[PRINT_BUF_LEN]; + int print_buf_len; +}; + +#ifndef LWIP_TESTBED +LWIP_STATIC +#endif +void lwip_arp_show_internal(struct netif *netif, char *printf_buf, unsigned int buf_len) +{ + u8_t state, i; + int ret; + char *tmp = printf_buf; + if (buf_len < 1) { + return; + } + ret = snprintf_s(tmp, buf_len, (buf_len - 1), "%-24s%-24s%-12s%-12s\n", "Address", "HWaddress", "Iface", "Type"); + if ((ret <= 0) || ((unsigned int)ret >= buf_len)) + return; + tmp += ret; + buf_len -= (unsigned int)ret; + + if (netif != NULL) { + for (i = 0; i < ARP_TABLE_SIZE; ++i) { + state = arp_table[i].state; + if (((state == ETHARP_STATE_STABLE) + #if ETHARP_SUPPORT_STATIC_ENTRIES + || (state == ETHARP_STATE_STATIC) +#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ + ) && arp_table[i].netif) { + if (strcmp(netif_get_name(netif), netif_get_name(arp_table[i].netif)) != 0) { + continue; + } + + ret = snprintf_s(tmp, buf_len, (buf_len - 1), "%-24s%02X:%02X:%02X:%02X:%02X:%02X %s %s\n", + ip4addr_ntoa(&arp_table[i].ipaddr), + arp_table[i].ethaddr.addr[0], arp_table[i].ethaddr.addr[1], + arp_table[i].ethaddr.addr[2], arp_table[i].ethaddr.addr[3], + arp_table[i].ethaddr.addr[4], arp_table[i].ethaddr.addr[5], + netif_get_name(netif), +#if ETHARP_SUPPORT_STATIC_ENTRIES + ((state == ETHARP_STATE_STATIC) ? "static" : "dynamic") +#else + "dynamic" +#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ + ); + if ((ret <= 0) || ((unsigned int)ret >= buf_len)) + return; + tmp += ret; + buf_len -= (unsigned int)ret; + } + } + } else { + for (i = 0; i < ARP_TABLE_SIZE; ++i) { + state = arp_table[i].state; + if (((state == ETHARP_STATE_STABLE) + #if ETHARP_SUPPORT_STATIC_ENTRIES + || (state == ETHARP_STATE_STATIC) +#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ + ) && arp_table[i].netif) { + ret = snprintf_s(tmp, buf_len, (buf_len - 1), "%-24s%02X:%02X:%02X:%02X:%02X:%02X %s %s\n", + ip4addr_ntoa(&arp_table[i].ipaddr), + arp_table[i].ethaddr.addr[0], arp_table[i].ethaddr.addr[1], + arp_table[i].ethaddr.addr[2], arp_table[i].ethaddr.addr[3], + arp_table[i].ethaddr.addr[4], arp_table[i].ethaddr.addr[5], + netif_get_name(arp_table[i].netif), +#if ETHARP_SUPPORT_STATIC_ENTRIES + ((state == ETHARP_STATE_STATIC) ? "static" : "dynamic") +#else + "dynamic" +#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ + ); + if ((ret <= 0) || ((unsigned int)ret >= buf_len)) + return; + tmp += ret; + buf_len -= (unsigned int)ret; + } + } + } +} + +#ifndef LWIP_TESTBED +LWIP_STATIC +#endif +void lwip_arp_internal(void *arg) +{ +#if LWIP_IPV4 + struct arp_option *arp_cmd = (struct arp_option *)arg; + struct netif *netif = NULL; + struct eth_addr ethaddr; + ip4_addr_t ipaddr; + err_t ret = 0; + int type = 0; +#ifdef LOSCFG_NET_CONTAINER + struct net_group *group = get_curr_process_net_group(); +#endif + if (arp_cmd->iface[0] == 'd' && arp_cmd->iface[1] == 'e') { + netif = NULL; + } else { + /* find the specified netif by it's name */ + netif = netif_find(arp_cmd->iface); + if (netif == NULL) { + (void)snprintf_s(arp_cmd->cb_print_buf, PRINT_BUF_LEN, (PRINT_BUF_LEN - 1), "No such device\n"); + goto out; + } + } + + type = arp_cmd->option; + switch (type) { + case ARP_OPTION_SHOW: + if (netif != NULL) { + lwip_arp_show_internal(netif, arp_cmd->cb_print_buf, PRINT_BUF_LEN); + } else { + lwip_arp_show_internal(NULL, arp_cmd->cb_print_buf, PRINT_BUF_LEN); + } + break; + + case ARP_OPTION_ADD: +#if ETHARP_SUPPORT_STATIC_ENTRIES + ipaddr.addr = arp_cmd->ipaddr; + (void)memcpy_s(ethaddr.addr, sizeof(ethaddr.addr), arp_cmd->ethaddr, 6); + if (netif != NULL) { + if (ip4_addr_netcmp(&ipaddr, ip_2_ip4(&(netif->ip_addr)), ip_2_ip4(&(netif->netmask)))) { + ret = etharp_update_arp_entry(netif, &ipaddr, ðaddr, + ETHARP_FLAG_TRY_HARD | ETHARP_FLAG_STATIC_ENTRY); + } else { + ret = ERR_RTE; + } + } else { + ret = etharp_add_static_entry(&ipaddr, ðaddr); + } +#else + ret = ERR_ARG; +#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ + break; + + case ARP_OPTION_DEL: + ipaddr.addr = arp_cmd->ipaddr; + (void)memcpy_s(ethaddr.addr, sizeof(ethaddr.addr), arp_cmd->ethaddr, 6); + if (netif != NULL) { + ret = etharp_delete_arp_entry(netif, &ipaddr); + } else { +#ifdef LOSCFG_NET_CONTAINER + for (netif = group->netif_list; netif != NULL; netif = netif->next) { +#else + for (netif = netif_list; netif != NULL; netif = netif->next) { +#endif + ret = etharp_delete_arp_entry(netif, &ipaddr); + if (ret == ERR_OK) { + /* only can del success one time */ + break; + } + } + } + break; + + default: + (void)snprintf_s(arp_cmd->cb_print_buf, PRINT_BUF_LEN, (PRINT_BUF_LEN - 1), "Error\n"); + goto out; + } + +out: + if (type == ARP_OPTION_ADD || type == ARP_OPTION_DEL) { + if (ret == ERR_MEM) { + (void)snprintf_s(arp_cmd->cb_print_buf, PRINT_BUF_LEN, (PRINT_BUF_LEN - 1), "Out of memory error\n"); + } else if (ret == ERR_ARG) { + (void)snprintf_s(arp_cmd->cb_print_buf, PRINT_BUF_LEN, (PRINT_BUF_LEN - 1), "Illegal argument\n"); + } else if (ret == ERR_RTE) { + (void)snprintf_s(arp_cmd->cb_print_buf, PRINT_BUF_LEN, (PRINT_BUF_LEN - 1), "Network is unreachable\n"); + } else { + (void)snprintf_s(arp_cmd->cb_print_buf, PRINT_BUF_LEN, (PRINT_BUF_LEN - 1), "Succeeded\n"); + } + } +#endif + + sys_sem_signal(&arp_cmd->cb_completed); +} + + +LWIP_STATIC void lwip_arp_usage(const char *cmd) +{ + PRINTK("Usage:" + "\n%s" + "\n%s [-i IF] -s IPADDR HWADDR" + "\n%s [-i IF] -d IPADDR\n", + cmd, cmd, cmd); +} + +u32_t lwip_arp(int argc, const char **argv) +{ + int i; + struct arp_option arp_cmd; + err_t ret; + size_t interface_len = 0; + + (void)memset_s(&arp_cmd, sizeof(struct arp_option), 0, sizeof(struct arp_option)); + if (!tcpip_init_finish) { + PRINTK("%s: tcpip_init have not been called\n", __FUNCTION__); + return LOS_NOK; + } + + arp_cmd.iface[0] = 'd'; + arp_cmd.iface[1] = 'e'; + arp_cmd.iface[2] = '0'; + arp_cmd.option = ARP_OPTION_SHOW; + arp_cmd.print_buf_len = 0; + if (sys_sem_new(&arp_cmd.cb_completed, 0) != ERR_OK) { + PRINTK("%s: sys_sem_new fail\n", __FUNCTION__); + return 1; + } + + i = 0; + while (argc > 0) { + if (strcmp("-i", argv[i]) == 0 && (argc > 1)) { + /* get the network interface's name */ + interface_len = strlen(argv[i + 1]); + if (interface_len < IFNAMSIZ) { + if (strncmp(argv[i + 1], "lo", (sizeof("lo") - 1)) == 0) { + PRINTK("Illegal operation\n"); + goto arp_error; + } + if (strncpy_s(arp_cmd.iface, IFNAMSIZ, argv[i + 1], interface_len) != EOK) { + PRINTK("strncpy_s error\n"); + goto arp_error; + } + arp_cmd.iface[interface_len] = '\0'; + } else { + PRINTK("Iface name is big \n"); + goto arp_error; + } + i += 2; + argc -= 2; // 2: number of used parameters + } else if (strcmp("-d", argv[i]) == 0 && (argc > 1)) { + /* arp delete */ + arp_cmd.option = ARP_OPTION_DEL; + arp_cmd.ipaddr = inet_addr(argv[i + 1]); + + if (arp_cmd.ipaddr == IPADDR_NONE) { + PRINTK("IP address is not correct!\n"); + goto arp_error; + } + + i += 2; + argc -= 2; // 2: number of used parameters + } else if (strcmp("-s", argv[i]) == 0 && (argc > 2)) { // 2: require more than 2 parameters + /* arp add */ + char *digit = NULL; + u32_t macaddrlen = strlen(argv[i + 2]) + 1; + char tmpStr[MAX_MACADDR_STRING_LENGTH]; + char *tmpStr1 = NULL; + char *saveptr1 = NULL; + char *temp = NULL; + int j; + + arp_cmd.option = ARP_OPTION_ADD; + arp_cmd.ipaddr = inet_addr(argv[i + 1]); + + if (arp_cmd.ipaddr == IPADDR_NONE) { + PRINTK("IP address is not correct!\n"); + goto arp_error; + } + + /* cannot add an arp entry of 127.*.*.* */ + if ((arp_cmd.ipaddr & (u32_t)0x0000007fUL) == (u32_t)0x0000007fUL) { + PRINTK("IP address is not correct!\n"); + goto arp_error; + } + + if (macaddrlen != MAX_MACADDR_STRING_LENGTH) { + PRINTK("Wrong MAC address length\n"); + goto arp_error; + } + + if (strncpy_s(tmpStr, MAX_MACADDR_STRING_LENGTH, argv[i + 2], macaddrlen - 1) != 0) { + PRINTK("Wrong MAC address\n"); + goto arp_error; + } + + for (j = 0, tmpStr1 = tmpStr; j < 6; j++, tmpStr1 = NULL) { + digit = strtok_r(tmpStr1, ":", &saveptr1); + if ((digit == NULL) || (strlen(digit) > 2)) { + PRINTK("MAC address is not correct\n"); + goto arp_error; + } + + for (temp = digit; *temp != '\0'; temp++) { + if (!isxdigit(*temp)) { + PRINTK("MAC address is not correct\n"); + goto arp_error; + } + } + + CONVERT_STRING_TO_HEX(digit, arp_cmd.ethaddr[j]); + } + + i += 3; + argc -= 3; // 3: number of used parameters + } else { + goto arp_error; + } + } + + ret = tcpip_callback(lwip_arp_internal, &arp_cmd); + if (ret != ERR_OK) { + PRINTK("%s : tcpip_callback failed in line %d : errnu %d", __FUNCTION__, __LINE__, ret); + sys_sem_free(&arp_cmd.cb_completed); + return 1; + } + (void)sys_arch_sem_wait(&arp_cmd.cb_completed, 0); + sys_sem_free(&arp_cmd.cb_completed); + arp_cmd.cb_print_buf[PRINT_BUF_LEN - 1] = '\0'; + PRINTK("%s", arp_cmd.cb_print_buf); + return 0; + +arp_error: + lwip_arp_usage("arp"); + sys_sem_free(&arp_cmd.cb_completed); + return 1; +} + +#ifdef LOSCFG_SHELL_CMD_DEBUG +SHELLCMD_ENTRY(arp_shellcmd, CMD_TYPE_EX, "arp", 1, (CmdCallBackFunc)lwip_arp); +#endif /* LOSCFG_SHELL_CMD_DEBUG */ + +void ifup_internal(void *arg) +{ + struct netif *netif = NULL; + struct if_cmd_data *ifcmd_data; + + ifcmd_data = (struct if_cmd_data *)arg; + if (ifcmd_data == NULL) { + return; + } + netif = netif_find(ifcmd_data->if_name); + if (netif == NULL) { + ifcmd_data->err = ERR_VAL; + } else { + (void)netif_set_up(netif); + ifcmd_data->err = ERR_OK; + } + + sys_sem_signal(&ifcmd_data->cb_completed); +} + +void ifdown_internal(void *arg) +{ + struct netif *netif = NULL; + struct if_cmd_data *ifcmd_data = NULL; + + ifcmd_data = (struct if_cmd_data *)arg; + if (ifcmd_data == NULL) { + return; + } + netif = netif_find(ifcmd_data->if_name); + if (netif == NULL) { + ifcmd_data->err = ERR_VAL; + } else { + (void)netif_set_down(netif); + ifcmd_data->err = ERR_OK; + } + + sys_sem_signal(&ifcmd_data->cb_completed); +} + +#if LWIP_DNS +#ifndef LWIP_TESTBED +LWIP_STATIC +#endif +struct hostent *gethostnameinfo(const char *host) +{ + static struct hostent hostbuf; + struct hostent *hp = NULL; + const size_t hstbuflen = 1024; + char tmphstbuf[1024]; + int res; + int herr; + + res = lwip_gethostbyname_r(host, &hostbuf, tmphstbuf, hstbuflen, &hp, &herr); + /* Check for errors. */ + if (res || hp == NULL) + return NULL; + return hp; +} + +LWIP_STATIC unsigned int get_hostip(const char *hname) +{ + unsigned int ip = 0; + int ret; + + struct hostent *pent = gethostnameinfo(hname); + if (pent == NULL || pent->h_addr == NULL) + return 0; + ret = memcpy_s(&ip, sizeof(ip), pent->h_addr, 4); + if (ret != 0) { + return 0; + } + return ip; +} +#endif + +#if LWIP_EXT_POLL_SUPPORT +static int ping_taskid = -1; +static int ping_kill = 0; +#define PING_ZERO_DATA_LEN 8 +static void lwip_ping_usage(void) +{ + PRINTK("Usage:"\ + "\n ping" + "\n ping [-n cnt] [-w interval] [-l data_len] destination" + "\n ping [-t] [-w interval] destination" + "\n ping -k"); + PRINTK("\n -t means ping forever, user can use -k to stop the forever ping\n"); +} + +LWIP_STATIC int osPingFunc(u32_t destip, u32_t cnt, u32_t interval, u32_t data_len) +{ + int sfd; + struct sockaddr_in to; + struct pbuf *pbuf_resp = NULL; + struct icmp_echo_hdr *iecho = NULL; + struct icmp_echo_hdr *iecho_resp = NULL; + struct ip_hdr *iphdr_resp = NULL; + u32_t iecho_len; + s16_t ip_hlen; + u32_t forever; + u32_t i = 0; + u32_t succ_cnt = 0; + u32_t failed_cnt = 0; + struct timespec start, end; + long timout_ms = 0; + struct pollfd pfd; + long rtt; + int ret = 0; + u32_t intrvl = 0; + char *data_buf = NULL; + BOOL timeout_flag = false; + char buf[50]; + + iecho_len = sizeof(struct icmp_echo_hdr) + data_len; + sfd = lwip_socket(PF_INET, SOCK_RAW, IPPROTO_ICMP); + if (sfd < 0) { + perror("Ping socket"); + return -1; + } + pbuf_resp = pbuf_alloc(PBUF_RAW, IP_HLEN + sizeof(struct icmp_echo_hdr), PBUF_RAM); + if (pbuf_resp == NULL) { + PRINTK("Ping: pbuf_resp malloc failed\n"); + ret = -1; + goto FAILURE; + } + iecho = (struct icmp_echo_hdr *)mem_malloc(iecho_len); + if (iecho == NULL) { + PRINTK("Ping: echo request malloc failed\n"); + ret = -1; + goto FAILURE; + } + + to.sin_family = AF_INET; + to.sin_addr.s_addr = destip; /* already in network order */ + to.sin_port = 0; + + if (data_len > PING_ZERO_DATA_LEN) { + (void)memset_s(iecho, sizeof(struct icmp_echo_hdr) + PING_ZERO_DATA_LEN, + 0, sizeof(struct icmp_echo_hdr) + PING_ZERO_DATA_LEN); + data_buf = (char *)iecho + sizeof(struct icmp_echo_hdr) + PING_ZERO_DATA_LEN; + for (i = 0; i < data_len - PING_ZERO_DATA_LEN; i++) { + *(data_buf + i) = i + 0x10; + } + } else { + (void)memset_s(iecho, sizeof(struct icmp_echo_hdr) + data_len, 0, sizeof(struct icmp_echo_hdr) + data_len); + } + iecho->id = htons((u16_t)LOS_CurTaskIDGet()); + ICMPH_TYPE_SET(iecho, (u8_t)ICMP_ECHO); + forever = (cnt ? 0 : 1); + i = 0; + while (!ping_kill && (forever || (i < cnt))) { + iecho->seqno = htons((u16_t)i); + iecho->chksum = 0; + iecho->chksum = inet_chksum((void *)iecho, iecho_len); + + ret = sendto(sfd, iecho, iecho_len, 0, (struct sockaddr *)&to, (socklen_t)sizeof(to)); + if (ret < 0) { + perror("Ping: sending ICMP echo request failed\n"); + goto FAILURE; + } + + /* capture the start time to calculate RTT */ + (void)clock_gettime(CLOCK_MONOTONIC_RAW, &start); + + /* poll for ICMP echo response msg */ + pfd.fd = sfd; + + do { + pfd.events = POLLIN; + pfd.revents = 0; + timeout_flag = false; + ret = poll(&pfd, 1, LWIP_SHELL_CMD_PING_TIMEOUT); + if (ret < 0) { + perror("Ping: poll\n"); + goto FAILURE; + } else if (ret == 0) { + /* first type timeout event */ + timeout_flag = true; + break; + } + + ret = recv(sfd, pbuf_resp->payload, pbuf_resp->len, MSG_DONTWAIT); + if (ret < 0) { + perror("Ping: recv echo reply failed\n"); + goto FAILURE; + } + + /* Accessing ip header and icmp header */ + iphdr_resp = pbuf_resp->payload; + + ip_hlen = (IPH_HL(iphdr_resp) << 2); + if (pbuf_header(pbuf_resp, -ip_hlen)) { + /* this failure will never happen, but failure handle is written just to be in safe side */ + PRINTK("Ping : memory management failure\n"); + goto FAILURE; + } + iecho_resp = (struct icmp_echo_hdr *)pbuf_resp->payload; + /* Reverting back pbuf to its original state */ + if (pbuf_header(pbuf_resp, ip_hlen)) { + /* this failure will never happen, but failure handle is written just to be in safe side */ + PRINTK("ping : memory management failure\n"); + goto FAILURE; + } + + if ((iphdr_resp->src.addr != to.sin_addr.s_addr) || + ((ICMPH_TYPE(iecho_resp) == ICMP_ECHO) && (iphdr_resp->src.addr == to.sin_addr.s_addr))) { + /* second type timeout event */ + (void)clock_gettime(CLOCK_MONOTONIC_RAW, &end); + timout_ms = ((end.tv_sec - start.tv_sec) * 1000 + (end.tv_nsec - start.tv_nsec) / 1000000); + timout_ms = LWIP_SHELL_CMD_PING_TIMEOUT - timout_ms; + } else { + timout_ms = 0; + break; + } + } while (timout_ms >= 0); + + /* all timeout events are true timeout */ + if ((timout_ms < 0) || (timeout_flag == true)) { + failed_cnt++; + i++; + PRINTK("\nPing: destination unreachable ..."); + continue; + } + /* capture the end time to calculate round trip time */ + (void)clock_gettime(CLOCK_MONOTONIC_RAW, &end); + rtt = ((end.tv_sec - start.tv_sec) * 1000 + (end.tv_nsec - start.tv_nsec) / 1000000); + + if (iphdr_resp->src.addr == to.sin_addr.s_addr) { + switch (ICMPH_TYPE(iecho_resp)) { + case ICMP_ER: + PRINTK("\n[%u]Reply from %s: ", i, inet_ntop(AF_INET, &to.sin_addr, buf, sizeof(buf))); + if (rtt > 0) { + PRINTK("time=%ims ", rtt); + } else { + PRINTK("time<1ms "); + } + PRINTK("TTL=%u", iphdr_resp->_ttl); + + /* delay 1s for every successful ping */ + intrvl = interval; + do { + if (intrvl < 1000) { + sys_msleep(intrvl); + break; + } + intrvl -= 1000; + sys_msleep(1000); // 1000: delay 1 s + if (ping_kill == 1) + break; + } while (intrvl > 0); + succ_cnt++; + break; + case ICMP_DUR: + PRINTK("\nPing: destination host unreachable ..."); + break; + case ICMP_SQ: + PRINTK("\nPing: source quench ..."); + break; + case ICMP_RD: + PRINTK("\nPing: redirect ..."); + break; + case ICMP_TE: + PRINTK("\nPing: time exceeded ..."); + break; + case ICMP_PP: + PRINTK("\nPing: parameter problem ..."); + break; + default : + PRINTK("\nPing: unknown error ..."); + break; + } + i++; + } + } + + PRINTK("\n--- %s ping statistics ---\n", inet_ntop(AF_INET, &to.sin_addr, buf, sizeof(buf))); + PRINTK("%u packets transmitted, %u received, %u loss\n", i, succ_cnt, failed_cnt); + +FAILURE: + ping_kill = 0; + (void)lwip_close(sfd); + if (pbuf_resp != NULL) { + (void)pbuf_free(pbuf_resp); + } + if (iecho != NULL) { + mem_free(iecho); + } + return ret; +} + +static void ping_cmd(unsigned int p0, unsigned int p1, unsigned int p2, unsigned int p3) +{ + u32_t destip = p0; + u32_t count = p1; + u32_t interval = p2; + u32_t data_len = p3; + int ret; + + ret = osPingFunc(destip, count, interval, data_len); + if (ret < 0) { + PRINTK("Ping cmd failed due to some errors\n"); + } + + ping_taskid = -1; +} + +u32_t osShellPing(int argc, const char **argv) +{ + int ret; + u32_t i = 0; + u32_t count = 0; + int count_set = 0; + u32_t interval = 1000; /* default ping interval */ + u32_t data_len = 48; /* default data length */ + ip4_addr_t dst_ipaddr; + TSK_INIT_PARAM_S stPingTask; + + if (!tcpip_init_finish) { + PRINTK("Ping: tcpip_init have not been called\n"); + return LOS_NOK; + } + + if ((argc < 1) || (argv == NULL)) { + PRINTK("Ping: require dest ipaddr at least\n"); + goto ping_error; + } + + /* could add more param support */ + while (argc > 0) { + if (strcmp("-n", argv[i]) == 0 && (argc > 1)) { + ret = atoi(argv[i + 1]); + if (ret <= 0) { + PRINTK("Ping count should be greater than 0 \n"); + goto ping_error; + } + count = ret; + count_set = 1; + i += 2; + argc -= 2; // 2: nuber of arguments that has been checked + } else if (strcmp("-t", argv[i]) == 0) { + count = 0; /* ping forerver */ + count_set = 1; + i++; + argc--; + } else if (strcmp("-w", argv[i]) == 0 && (argc > 1)) { + ret = atoi(argv[i + 1]); + if (ret <= 0) { + PRINTK("Ping interval should be greater than 0 \n"); + goto ping_error; + } + + interval = ret; + i += 2; + argc -= 2; // 2:number of arguments that has been checked + } else if (strcmp("-l", argv[i]) == 0 && (argc > 1)) { + ret = atoi(argv[i + 1]); + if (ret < 0 || ret > (int)(LWIP_MAX_UDP_RAW_SEND_SIZE - sizeof(struct icmp_echo_hdr))) { + PRINTK("Ping data length error, should be in range of [0, %d] \n", + LWIP_MAX_UDP_RAW_SEND_SIZE - sizeof(struct icmp_echo_hdr)); + goto ping_error; + } + data_len = ret; + i += 2; + argc -= 2; // 2: number of elements has been checked + } else if (strcmp("-k", argv[i]) == 0) { + if (ping_taskid > 0) { + ping_kill = 1; /* stop the current ping task */ + return LOS_OK; + } else { + PRINTK("No ping task running...\n"); + return LOS_NOK; + } + } else { + if (argc == 1) { + break; + } else { + PRINTK("Invalid Ping param\n"); + goto ping_error; + } + } + } + + if (!count_set) { + count = LWIP_SHELL_CMD_PING_RETRY_TIMES; + } + + /* initialize dst IP address */ + if (argc <= 0) { + goto ping_error; + } +#if LWIP_DNS + dst_ipaddr.addr = get_hostip(argv[i]); +#else /* LWIP_DNS */ + dst_ipaddr.addr = inet_addr(argv[i]); +#endif /* LWIP_DNS */ + + if (dst_ipaddr.addr == IPADDR_NONE || dst_ipaddr.addr == IPADDR_ANY) { + PRINTK("Invalid dest ipaddr: NONE or ANY\n"); + return LOS_NOK; + } + + /* start one task if ping forever or ping count greater than 60 */ + if (count == 0 || count > LWIP_SHELL_CMD_PING_RETRY_TIMES) { + if (ping_taskid > 0) { + PRINTK("Ping task already running and only support one now\n"); + return LOS_NOK; + } + stPingTask.pfnTaskEntry = (TSK_ENTRY_FUNC)ping_cmd; + stPingTask.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + stPingTask.pcName = "ping_task"; + stPingTask.usTaskPrio = 8; /* higher than shell */ + stPingTask.uwResved = LOS_TASK_STATUS_DETACHED; + stPingTask.auwArgs[0] = dst_ipaddr.addr; /* network order */ + stPingTask.auwArgs[1] = count; + stPingTask.auwArgs[2] = interval; + stPingTask.auwArgs[3] = data_len; // 3: index of data length + ret = LOS_TaskCreate((UINT32 *)(&ping_taskid), &stPingTask); + if (ret != LOS_OK) { + PRINTK("ping_task create failed 0x%08x.\n", ret); + count = LWIP_SHELL_CMD_PING_RETRY_TIMES; + } else { + return LOS_OK; + } + } + + /* two cases: + 1, ping cout less than LWIP_SHELL_CMD_PING_RETRY_TIMES; + 2, ping task create failed; + */ + if (osPingFunc(dst_ipaddr.addr, count, interval, data_len) < 0) { + PRINTK("Ping cmd failed due some errors\n"); + } + + return LOS_OK; +ping_error: + lwip_ping_usage(); + return LOS_NOK; +} +#ifdef LOSCFG_SHELL +SHELLCMD_ENTRY(ping_shellcmd, CMD_TYPE_EX, "ping", XARGS, (CmdCallBackFunc)osShellPing); +#endif /* LOSCFG_SHELL */ + +#else /* LWIP_EXT_POLL_SUPPORT */ + +u32_t osShellPing(int argc, const char **argv) +{ + int sfd; + struct sockaddr_in to; + struct icmp_echo_hdr iecho; + struct pbuf *pbuf_resp = NULL; + struct icmp_echo_hdr *iecho_resp = NULL; + struct ip_hdr *iphdr_resp = NULL; + s16_t ip_hlen; + ip_addr_t dst_ipaddr; + fd_set fdReadSet; + struct timeval stTimeVal; + struct timespec start, end; + int ret; + s32_t i; + long rtt; + s32_t pingcount; + char buf[50]; + + if (!tcpip_init_finish) { + PRINTK("ping: tcpip_init have not been called\n"); + return LOS_NOK; + } + + if ((argc < 1) || (argv == NULL)) { + PRINTK("ping : invalid arguments, ping command receives ip as command line argument \n"); + return LOS_NOK; + } + + if (argc == 2) { + pingcount = atoi(argv[1]); + if (pingcount < 1) + pingcount = LWIP_SHELL_CMD_PING_RETRY_TIMES; + } else { + pingcount = LWIP_SHELL_CMD_PING_RETRY_TIMES; + } + PRINTK("ping %u packets start.\n", pingcount); + + /* initialize dst IP address */ +#if LWIP_DNS + ip_2_ip4(&dst_ipaddr)->addr = get_hostip(argv[0]); +#else /* LWIP_DNS */ + ip_2_ip4(&dst_ipaddr)->addr = inet_addr(argv[0]); +#endif /* LWIP_DNS */ + + to.sin_family = AF_INET; + to.sin_addr.s_addr = ip_2_ip4(&dst_ipaddr)->addr; + to.sin_port = 0; + + if (to.sin_addr.s_addr == IPADDR_NONE || to.sin_addr.s_addr == IPADDR_ANY) { + PRINTK("ping : invalid ip address : NONE or ANY\n"); + return LOS_NOK; + } + + sfd = lwip_socket(PF_INET, SOCK_RAW, IPPROTO_ICMP); + if (sfd == -1) { + PRINTK("ping : failed, socket creation failed\n"); + return LOS_NOK; + } + + pbuf_resp = pbuf_alloc(PBUF_RAW, IP_HLEN + sizeof(struct icmp_echo_hdr), PBUF_RAM); + if (pbuf_resp == NULL) { + PRINTK("ping : memory allocation failed\n"); + goto FAILURE; + } + + for (i = 0; i < pingcount; i++) { + (void)memset_s(&iecho, sizeof(iecho), 0, sizeof(iecho)); + ICMPH_TYPE_SET(&iecho, (u8_t)ICMP_ECHO); + iecho.chksum = inet_chksum(&iecho, sizeof(struct icmp_echo_hdr)); + + ret = lwip_sendto(sfd, &iecho, sizeof(struct icmp_echo_hdr), 0, (struct sockaddr *)&to, (socklen_t)sizeof(to)); + if (ret == -1) { + PRINTK("ping : sending ICMP echo msg failed\n"); + goto FAILURE; + } + + /* capture the start time to calculate round trip time */ + (void)clock_gettime(CLOCK_MONOTONIC_RAW, &start); + /* Wait in select for ICMP response msg */ + FD_ZERO(&fdReadSet); + FD_SET(sfd, &fdReadSet); + stTimeVal.tv_sec = LWIP_SHELL_CMD_PING_TIMEOUT / 1000; + stTimeVal.tv_usec = 0; + +DO_SELECT: + ret = select(sfd + 1, &fdReadSet, 0, 0, &stTimeVal); + if (ret < 0) { + PRINTK("ping : select failure\n"); + goto FAILURE; + } else if (ret == 0) { + PRINTK("Request timed out.\n"); + continue; + } + + /* capture the end time to calculate round trip time */ + (void)clock_gettime(CLOCK_MONOTONIC_RAW, &end); + rtt = ((end.tv_sec - start.tv_sec) * 1000 + (end.tv_nsec - start.tv_nsec) / 1000000); + + ret = lwip_recv(sfd, pbuf_resp->payload, pbuf_resp->len, 0); + if (ret == -1) { + PRINTK("ping : receiving ICMP echo response msg failed\n"); + goto FAILURE; + } + + /* Accessing ip header and icmp header */ + iphdr_resp = (struct ip_hdr *)(pbuf_resp->payload); + ip_hlen = (s16_t)(IPH_HL(iphdr_resp) * 4); + if (pbuf_header(pbuf_resp, (s16_t)(-ip_hlen))) { + /* this failure will never happen, but failure handle is written just to be in safe side */ + PRINTK("ping : memory management failure\n"); + goto FAILURE; + } + iecho_resp = (struct icmp_echo_hdr *)pbuf_resp->payload; + + /* Reverting back pbuf to its original state */ + if (pbuf_header(pbuf_resp, ip_hlen)) { + /* this failure will never happen, but failure handle is written just to be in safe side */ + PRINTK("ping : memory management failure\n"); + goto FAILURE; + } + + if (iphdr_resp->src.addr == to.sin_addr.s_addr) { + if (ICMPH_TYPE(iecho_resp) == ICMP_ER) { + PRINTK("[%u]Reply from %s: time=%ims TTL=%u\n", i, + inet_ntoa_r(to.sin_addr.s_addr, buf, sizeof(buf)), rtt, iphdr_resp->_ttl); + } else if (ICMPH_TYPE(iecho_resp) == ICMP_ECHO) { + /* If ping self, stack will receive a ICMP_ECHO request message flowing a ICMP_ER reply message, + and we need reply only, do select again */ + goto DO_SELECT; + } + } + } + + (void)lwip_close(sfd); + (void)pbuf_free(pbuf_resp); + return LOS_OK; + +FAILURE: + (void)lwip_close(sfd); + if (pbuf_resp != NULL) { + (void)pbuf_free(pbuf_resp); + } + + return LOS_NOK; +} + +#ifdef LOSCFG_SHELL +SHELLCMD_ENTRY(ping_shellcmd, CMD_TYPE_EX, "ping", XARGS, (CmdCallBackFunc)osShellPing); +#endif /* LOSCFG_SHELL */ + +#endif /* LWIP_EXT_POLL_SUPPORT */ + +#if LWIP_IPV6 +u32_t osShellPing6(int argc, const char **argv) +{ + u16_t icmpv6_id; + u16_t icmpv6_seq; + u32_t nsent; + u32_t nrecieve; + u32_t last_received; + struct timespec start, end, start_in_reply; + struct timespec first, last; + long rtt; + int ret; + fd_set fdReadSet; + void *param = NULL; + ping6_args_t ping6_params; + ping6_stats_t ping6_stats; + struct sockaddr_in6 to; + struct icmp6_echo_hdr *iecho_resp = NULL; + struct icmp6_echo_hdr *iecho = NULL; + struct timeval stTimeVal; + struct timeval deltaTimeVal; + struct pbuf *pbuf_resp = NULL; + struct pbuf *pbuf_req = NULL; + int sfd = -1; + u8_t type; + u8_t select_on_socket = 0; + char buf[INET6_ADDRSTRLEN]; + + if (!tcpip_init_finish) { + PRINTK("%s: tcpip_init have not been called\n", __FUNCTION__); + ret = -1; + goto exit; + } + + if ((argc < 1) || (argc > LWIP_MAX_PING6_ARG_COUNT) || (argv == NULL)) { + goto usage; + } + + ret = parse_args_ping6(argc, argv, &ping6_params); + if (ret == -1) { + goto exit; + } + + if (ping6_params.args_found & LWIP_PING6_SOURCE_ADDRESS_ARG) { + type = LWIP_PING6_SOURCE_ADDRESS_ARG; + param = (void *)(&ping6_params.src_addr); + } else if (ping6_params.args_found & LWIP_PING6_INTERFACE_ARG) { + type = LWIP_PING6_INTERFACE_ARG; + param = (void *)(argv[ping6_params.interface_index]); + } else { + type = LWIP_PING6_DEFAULT_SOCKET; + param = NULL; + } + + /* Create a socket for sending and receiving pings with appropriate bindings */ + sfd = create_ping6_socket(type, param); + if (sfd == -1) { + ret = -1; + goto exit; + } + + pbuf_req = pbuf_alloc(PBUF_RAW, LWIP_PING6_STANDARD_PKT_SIZE, PBUF_RAM); + pbuf_resp = pbuf_alloc(PBUF_RAW, LWIP_PING6_STANDARD_PKT_SIZE, PBUF_RAM); + if ((pbuf_resp == NULL) || (pbuf_req == NULL)) { + PRINTK("ping6 : Memory Allocation Failed\n"); + ret = -1; + goto exit; + } + + to.sin6_family = AF_INET6; + inet6_addr_from_ip6addr(&to.sin6_addr, &(ping6_params.dst_addr)); + to.sin6_port = htons(IPPROTO_ICMPV6); + +#if LWIP_DNS + if (lwip_strnicmp(inet_ntop(AF_INET6, &to.sin6_addr, buf, sizeof(buf)), argv[ping6_params.host_index], + sizeof(to.sin6_addr))) { + /* If There Was A DNS Resolution */ + PRINTK("PING %s (%s) with %d bytes of data.\n", + argv[ping6_params.host_index], buf, LWIP_PING6_STANDARD_PKT_SIZE); + } else { + PRINTK("PING %s with %d bytes of data.\n", buf, LWIP_PING6_STANDARD_PKT_SIZE); + } +#else + PRINTK("PING %s with %d bytes of data\n", inet_ntop(AF_INET6, &to.sin6_addr, buf, sizeof(buf)), LWIP_PING6_STANDARD_PKT_SIZE); +#endif /* LWIP_DNS */ + + nrecieve = 0; + ping6_stats.flag = 0; + ping6_stats.avg_rtt = 0; + ping6_stats.max_rtt = 0; + ping6_stats.min_rtt = 0; + last_received = LWIP_PING6_STARTING_SEQ_NUM + LWIP_PING6_OUT_OF_ORDER_MAGNITUDE + 1; + icmpv6_id = (u16_t)LWIP_RAND(); + icmpv6_seq = LWIP_PING6_STARTING_SEQ_NUM; + /* Setting the start time of the entire ping task for statistics */ + (void)clock_gettime(CLOCK_MONOTONIC_RAW, &first); + + for (nsent = 0; nsent < ping6_params.pingcount; nsent++) { + /* capture the start tick to calculate rtt */ + (void)clock_gettime(CLOCK_MONOTONIC_RAW, &start); + /* Initialize Memory To Prevent Uninitialized Memory Read Write Issues */ + if (memset_s(pbuf_req->payload, pbuf_req->len, (int)(start.tv_nsec), pbuf_req->len) != 0) { + goto exit; + } + + iecho = (struct icmp6_echo_hdr *)pbuf_req->payload; + iecho->type = ICMP6_TYPE_EREQ; + iecho->id = icmpv6_id; + icmpv6_seq++; + iecho->seqno = icmpv6_seq; + iecho->code = 0; + + /* Embedding the start_tick as data into the icmp_payload */ + (void)pbuf_header(pbuf_req, (s16_t)(-(s16_t)(sizeof(struct icmp6_echo_hdr)))); + if (memcpy_s(pbuf_req->payload, pbuf_req->len, (void *)&start, sizeof(start)) != 0) { + goto exit; + } + (void)pbuf_header(pbuf_req, (s16_t)((s16_t)(sizeof(struct icmp6_echo_hdr)))); + + ret = lwip_sendto(sfd, iecho, pbuf_req->len, 0, (struct sockaddr *)&to, (socklen_t)sizeof(to)); + if (ret == -1) { + PRINTK("ping6 : Sending ICMP Echo message failed\n"); + goto exit; + } + + /* Wait in select for ICMP response msg */ + FD_ZERO(&fdReadSet); + FD_SET(sfd, &fdReadSet); + stTimeVal.tv_sec = LWIP_MSECS_TO_SECS(LWIP_SHELL_CMD_PING_TIMEOUT); + stTimeVal.tv_usec = 0; + select_on_socket = 1; + + while (select_on_socket) { + select_on_socket = 0; + ret = select(sfd + 1, &fdReadSet, 0, 0, &stTimeVal); + if (ret < 0) { + PRINTK("ping6 : select failure\n"); + goto exit; + } else if (ret == 0) { + (void)clock_gettime(CLOCK_MONOTONIC_RAW, &end); + PRINTK("Request timed out\n"); + continue; + } + + /* capture the end time to calculate round trip time */ + (void)clock_gettime(CLOCK_MONOTONIC_RAW, &end); + + ret = lwip_recv(sfd, pbuf_resp->payload, pbuf_resp->len, 0); + if (ret == -1) { + PRINTK("ping6 : receiving ICMP echo response msg failed\n"); + goto exit; + } + + if ((u32_t)ret < sizeof(struct icmp6_echo_hdr *)) { + /* Drop the packet if its too short [Doesn't contain even the header !!] */ + PRINTK("ping6 : received ICMP echo response too short\n"); + goto REDUCE_SELECT_TIME; + } + + /* Acceping the ICMPv6 payload. */ + /* Here, pbuf_resp->payload won't contain IPv6 Header since its an AF_INET6 RAW Socket */ + iecho_resp = (struct icmp6_echo_hdr *)pbuf_resp->payload; + + if (iecho_resp->id == icmpv6_id) { + if (iecho_resp->type == ICMP6_TYPE_EREP) { + if (ret < LWIP_PING6_STANDARD_PKT_SIZE) { + /* Drop the packet if its too short */ + PRINTK("ping6 : received ICMP echo response too short\n"); + goto REDUCE_SELECT_TIME; + } + /* Accept and process only those delayed EREP only if its sequence num is within out-of-order magnitude */ + if (nsent && iecho_resp->seqno != icmpv6_seq && + (iecho_resp->seqno<(u16_t)(last_received - LWIP_PING6_OUT_OF_ORDER_MAGNITUDE) || + iecho_resp->seqno>(u16_t)( + last_received + LWIP_PING6_OUT_OF_ORDER_MAGNITUDE))) { + /* Otherwise drop it and wait for more packets */ + goto REDUCE_SELECT_TIME; + } + ++nrecieve; + last_received = iecho_resp->seqno; + /* Retrieving the start_tick from the packet which was embedded when the request was transmitted */ + (void)pbuf_header(pbuf_resp, (s16_t)(-(s16_t)(sizeof(struct icmp6_echo_hdr)))); + if (memcpy_s((void *)&start_in_reply, sizeof(start_in_reply), + pbuf_resp->payload, sizeof(start_in_reply)) != EOK) { + goto REDUCE_SELECT_TIME; + } + (void)pbuf_header(pbuf_resp, (s16_t)((s16_t)(sizeof(struct icmp6_echo_hdr)))); + + rtt = ((end.tv_sec - start.tv_sec) * 1000 + (end.tv_nsec - start.tv_nsec) / 1000000); + + PRINTK("%d bytes from %s : icmp_seq=%d time", ret, + inet_ntop(AF_INET6, &to.sin6_addr, buf, sizeof(buf)), + ((iecho_resp->seqno) - LWIP_PING6_STARTING_SEQ_NUM)); + if (rtt < 1) { + PRINTK("<1 ms\n"); + } else { + PRINTK("=%i ms\n", rtt); + } + + update_ping6_stats(&ping6_stats, (u32_t)(rtt), nrecieve); + + /* Checking if its a delayed packet */ + if ((iecho_resp->seqno != icmpv6_seq) && (nsent < ping6_params.pingcount)) { + /* In case of delayed packet wait on socket for other response before sending a new PING */ + /* We have to reduce the timeout value now when selecting on socket */ + goto REDUCE_SELECT_TIME; + } + } else { + PRINTK("[%u]ping6 : %s\n", nsent, convert_icmpv6_err_to_string(iecho_resp->type)); + } + } else { + /* If incoming packet does not matches with icmp_id, it should be ignored */ + /* Reduce the timeout for select on socket */ +REDUCE_SELECT_TIME: + deltaTimeVal.tv_sec = (long)(end.tv_sec - start.tv_sec); + deltaTimeVal.tv_usec = (long)((end.tv_nsec - start.tv_nsec) / 1000); + /* Subtract deltaTime from stTime and store in stTime */ + /* This will reduce the select time on the socket */ + timersub(&stTimeVal, &deltaTimeVal, &stTimeVal); + select_on_socket = 1; + } + } + } + + ret = ERR_OK; + + (void)clock_gettime(CLOCK_MONOTONIC_RAW, &last); + /* Display ping stats */ + PRINTK("--- %s ping statistics ---\n", argv[ping6_params.host_index]); + PRINTK("%d packets transmitted, %d received, %.2f%% packet loss, time %dms\n", + nsent, nrecieve, (float)(((float)(nsent - nrecieve)) * ((float)(100)) / ((float)(nsent))), + /* 1000: convert seconds to milliseconds, 1000000: convert nanoseconds to milliseconds */ + ((last.tv_sec - first.tv_sec) * 1000 + (last.tv_nsec - first.tv_nsec) / 1000000)); + if (nrecieve) { + /* Display rtt stats only if at least one packet is received */ + PRINTK("rtt min/avg/max = %u/%.2f/%u ms\n", ping6_stats.min_rtt, ping6_stats.avg_rtt, ping6_stats.max_rtt); + } + +exit: + if (sfd != -1) { + (void)lwip_close(sfd); + } + + if (pbuf_resp != NULL) { + (void)pbuf_free(pbuf_resp); + } + + if (pbuf_req != NULL) { + (void)pbuf_free(pbuf_req); + } + return (u32_t)((ret == (int)ERR_OK) ? LOS_OK : LOS_NOK); + +usage: + PRINTK("Usage:\n"); + PRINTK("\tping6 [-c count] [-I interface/sourceAddress] destination\n"); + return LOS_NOK; +} + +LWIP_STATIC int create_ping6_socket(u8_t type, const void *param) +{ + int sfd; + int ret; + struct sockaddr_in6 stHostAddr6; + struct icmp6_filter icmp6_sock_filter; + + sfd = lwip_socket(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6); + if (sfd == -1) { + PRINTK("ping6 : Failed, socket creation failed\n"); + return -1; + } + + if (param != NULL) { + if (type == LWIP_PING6_SOURCE_ADDRESS_ARG) { + /* Binding socket to the provided source address */ + (void)memset_s(&stHostAddr6, sizeof(stHostAddr6), 0, sizeof(stHostAddr6)); + stHostAddr6.sin6_family = AF_INET6; + inet6_addr_from_ip6addr(&stHostAddr6.sin6_addr, (ip6_addr_t *)param); + stHostAddr6.sin6_port = htons(IPPROTO_ICMPV6); + stHostAddr6.sin6_scope_id = 0; + + ret = lwip_bind(sfd, (struct sockaddr *)&stHostAddr6, sizeof(stHostAddr6)); + if (ret == -1) { + (void)lwip_close(sfd); + PRINTK("ping6 : bind icmp socket: cannot assign requested address\n"); + return ret; + } + } else if (type == LWIP_PING6_INTERFACE_ARG) { + /* Binding socket to the provided netif */ + ret = lwip_setsockopt(sfd, SOL_SOCKET, SO_BINDTODEVICE, (char *)(param), strlen((char *)(param))); + if (ret == -1) { + (void)lwip_close(sfd); + PRINTK("ping6: unknownn iface %s\n", (char *)(param)); + return ret; + } + } + } + + /* Setting socket filter since we are interested only in ECHO REPLY and ERROR messages */ + ICMP6_FILTER_SETBLOCKALL(&icmp6_sock_filter); + ICMP6_FILTER_SETPASS(ICMP6_TYPE_EREP, &icmp6_sock_filter); + ICMP6_FILTER_SETPASS(ICMP6_TYPE_DUR, &icmp6_sock_filter); + ICMP6_FILTER_SETPASS(ICMP6_TYPE_PTB, &icmp6_sock_filter); + ICMP6_FILTER_SETPASS(ICMP6_TYPE_TE, &icmp6_sock_filter); + + ret = lwip_setsockopt(sfd, IPPROTO_ICMPV6, ICMP6_FILTER, &icmp6_sock_filter, sizeof(struct icmp6_filter)); + if (ret == -1) { + (void)lwip_close(sfd); + PRINTK("ping6 : setsockopt: Invalid Argument\n"); + return -1; + } + + return sfd; +} + +/* + * Function to parse the command line args for ping6 shell utility + * @return: + * Success: ERR_OK + * Failure: -1 + */ +LWIP_STATIC int parse_args_ping6(int argc, const char **argv, ping6_args_t *ping6_params) +{ + int pingcount; + int ret = -1; +#if LWIP_DNS + struct addrinfo *res = NULL; + struct addrinfo hints_structure; +#endif + u8_t i = 0; + + IP6_ADDR(&(ping6_params->dst_addr), 0, 0, 0, 0); + IP6_ADDR(&(ping6_params->src_addr), 0, 0, 0, 0); + + ping6_params->pingcount = LWIP_SHELL_CMD_PING_RETRY_TIMES; + ping6_params->host_index = 0; + ping6_params->args_found = 0; + + while (i < argc) { + if (strcmp("-c", argv[i]) == 0) { + /* Handle number of ICMP packets to transmit :: -c [number_of_packets] */ + if (ping6_params->args_found & LWIP_PING6_COUNT_ARG) { + PRINTK("ping6: -c option present multiple times \n"); + ret = -1; + goto exit; + } + + if (i + 2 > argc) { + PRINTK("ping6: ping count(-c) should require an argument \n"); + ret = -1; + goto exit; + } + + pingcount = atoi(argv[i + 1]); + if (pingcount <= 0) { + PRINTK("ping6: bad number of packets to transmit \n"); + ret = -1; + goto exit; + } + + ping6_params->args_found |= LWIP_PING6_COUNT_ARG; + ping6_params->pingcount = (u32_t)pingcount; + i = (u8_t)(i + 2); + } else if (strcmp("-I", argv[i]) == 0) { + /* Handle interface ID / sourceAddress using which the ICMP Packets has to be transmitted :: -I [interface_id/source_address] */ + + if ((ping6_params->args_found & LWIP_PING6_SOURCE_ADDRESS_ARG) || + (ping6_params->args_found & LWIP_PING6_INTERFACE_ARG)) { + PRINTK("ping6: -I option present multiple times \n"); + ret = -1; + goto exit; + } + + if (i + 2 > argc) { + PRINTK("ping6: interface/source address(-I) should require an argument \n"); + ret = -1; + goto exit; + } + + /* Check whether the given argument to -I is source address */ + if (ip6addr_aton(argv[i + 1], &(ping6_params->src_addr))) { + ping6_params->args_found |= LWIP_PING6_SOURCE_ADDRESS_ARG; + i = (u8_t)(i + 2); + continue; + } + + /* Storing the index where interface name is found */ + /* If this name is not valid, then it will fail later in setsockopt(BIND_TO_DEVICE) */ + ping6_params->interface_index = (u8_t)(i + 1); + ping6_params->args_found |= LWIP_PING6_INTERFACE_ARG; + + i = (u8_t)(i + 2); + } else { + if (argv[i][0] == '-') { + /* Check whether its a bad option */ + PRINTK("ping6: bad option %s\n", argv[i]); + ret = -1; + goto exit; + } else if (ping6_params->args_found & LWIP_PING6_HOSTNAME_ARG) { + /* Check whether hostname is already found and there are extra arguments */ + PRINTK("ping6: bad parameter %s\n", argv[i]); + ret = -1; + goto exit; + } + +#if LWIP_DNS + /* Resolve the given hostname */ + hints_structure.ai_family = AF_INET6; + hints_structure.ai_flags = 0; + ret = lwip_getaddrinfo(argv[i], NULL, &hints_structure, &res); + if (ret != ERR_OK) { + PRINTK("ping6 : Host : %s can't be resolved to IPv6 address\n", argv[i]); + ret = -1; + goto exit; + } + + inet6_addr_to_ip6addr(&(ping6_params->dst_addr), + &(((const struct sockaddr_in6 *)(res->ai_addr))->sin6_addr)); +#else + /* Convert the string representation to network form */ + if (!ip6addr_aton(argv[i], &(ping6_params->dst_addr))) { + PRINTK("ping6 : Invalid IPv6 Address : %s\n", argv[i]); + ret = -1; + goto exit; + } +#endif /* LWIP_DNS */ + if (ip6_addr_isany(&(ping6_params->dst_addr)) || ip6_addr_isnone(&(ping6_params->dst_addr))) { +#if LWIP_DNS + PRINTK("ping6 : IPv6 address of host : %s (%s) is invalid\n", argv[i], + ip6addr_ntoa((const ip6_addr_t *)&(ping6_params->dst_addr))); +#else + PRINTK("ping6 : Invalid IPv6 address : %s\n", argv[i]); +#endif /* LWIP_DNS */ + goto exit; + } + /* Setting host_index to the index of argv[] where the host/IP is present */ + ping6_params->args_found |= LWIP_PING6_HOSTNAME_ARG; + ping6_params->host_index = (u8_t)(i); + i = (u8_t)(i + 1); + } + } + + if (!(ping6_params->args_found & LWIP_PING6_HOSTNAME_ARG)) { + /* Hostname/IPv6 address not found */ + PRINTK("ping6 : Hostname/IPv6 address to ping is not specified\n"); + ret = -1; + goto exit; + } + + if (ip6_addr_islinklocal(&(ping6_params->dst_addr)) && + !(ping6_params->args_found & (LWIP_PING6_INTERFACE_ARG | LWIP_PING6_SOURCE_ADDRESS_ARG))) { + /* For link-local addresses, -I is mandatory */ + PRINTK("ping6 : Interface specification is mandatory for link-local addresses\n"); + ret = -1; + goto exit; + } + + ret = ERR_OK; + +exit: +#if LWIP_DNS + lwip_freeaddrinfo(res); +#endif /* LWIP_DNS */ + + return ret; +} + +/* + * Function to update ping6_stats + * stats is maintained in ping6_stats structure + */ +LWIP_STATIC void update_ping6_stats(ping6_stats_t *ping6_stats, u32_t rtt, u32_t nreceived) +{ + if (rtt > ping6_stats->max_rtt) { + ping6_stats->max_rtt = rtt; + } + + if (ping6_stats->flag == 0 || rtt < ping6_stats->min_rtt) { + ping6_stats->min_rtt = rtt; + ping6_stats->flag = 1; + } + + ping6_stats->avg_rtt = (float)(ping6_stats->avg_rtt + + (float)((float)((float)rtt - ping6_stats->avg_rtt) / (float)(nreceived))); +} + +LWIP_STATIC const char *convert_icmpv6_err_to_string(u8_t err_type) +{ + switch (err_type) { + case ICMP6_TYPE_DUR: + return "Destination Unreachable"; + case ICMP6_TYPE_PTB: + return "Packet too big"; + case ICMP6_TYPE_TE: + return "Time Exceeded"; + case ICMP6_TYPE_PP: + return "Parameter Problem"; + default: + break; + } + return "Unknown Error"; +} + +#ifdef LOSCFG_SHELL_CMD_DEBUG +SHELLCMD_ENTRY(ping6_shellcmd, CMD_TYPE_EX, "ping6", XARGS, (CmdCallBackFunc)osShellPing6); +#endif /* LOSCFG_SHELL_CMD_DEBUG */ +#endif /* LWIP_IPV6 */ + +#if LWIP_SNTP +u32_t osShellNtpdate(int argc, const char **argv) +{ + int server_num = 0; + char *ret = NULL; + struct timeval get_time; + char buf[50]; + + (void)memset_s(&get_time, sizeof(struct timeval), 0, sizeof(struct timeval)); + + if (!tcpip_init_finish) { + PRINTK("%s: tcpip_init have not been called\n", __FUNCTION__); + return LOS_NOK; + } + + if (argc < 1 || argv == NULL) { + goto usage; + } + + server_num = lwip_sntp_start(argc, (char **)argv, &get_time); + if (server_num >= 0 && server_num < argc) { + ret = ctime_r((time_t *)&get_time.tv_sec, buf); + if (ret != NULL) { + PRINTK("time server %s: %s\n", argv[server_num], ret); + } else { + PRINTK("ctime return null error\n"); + } + } else { + PRINTK("no server suitable for synchronization found\n"); + } + + return LOS_OK; + +usage: + PRINTK("\nUsage:\n"); + PRINTK("ntpdate [SERVER_IP1] [SERVER_IP2] ...\n"); + return LOS_NOK; +} + +#ifdef LOSCFG_SHELL_CMD_DEBUG +SHELLCMD_ENTRY(ntpdate_shellcmd, CMD_TYPE_EX, "ntpdate", XARGS, (CmdCallBackFunc)osShellNtpdate); +#endif /* LOSCFG_SHELL_CMD_DEBUG */ + +#endif /* LWIP_SNTP */ + +#if LWIP_DNS +u32_t osShellDns(int argc, const char **argv) +{ + ip_addr_t dns = {0}; + err_t err; + int i; + if (argc < 1 || argv == NULL) { + goto usage; + } + + if (tcpip_init_finish == 0) { + PRINTK("%s: tcpip_init have not been called\n", __FUNCTION__); + return LOS_NOK; + } + + if (argc == 1 && (strcmp(argv[0], "-a") == 0)) { + for (i = 0; i < DNS_MAX_SERVERS; i++) { + err = lwip_dns_getserver((u8_t)i, &dns); + if (err == ERR_OK) { + PRINTK("dns %d: %s\n", i + 1, ipaddr_ntoa_unsafe(&dns)); + } else { + PRINTK("dns: failed\n"); + return LOS_NOK; + } + } + return LOS_OK; + } else if (argc == 2) { + i = atoi(argv[0]); + if ((i <= 0) || (i > DNS_MAX_SERVERS)) + goto usage; +#if LWIP_IPV6 + if (ip6addr_aton(argv[1], ((ip6_addr_t *)&dns))) { +#if LWIP_IPV4 && LWIP_IPV6 + dns.type = IPADDR_TYPE_V6; +#endif + if (!ip6_addr_isglobal((ip6_addr_t *)&dns)) { + PRINTK("ip address<%s> is wrong\n", argv[1]); + return LOS_NOK; + } + } else +#endif + { +#if LWIP_IPV4 + ((ip4_addr_t *)&dns)->addr = ipaddr_addr(argv[1]); + if (((ip4_addr_t *)&dns)->addr == IPADDR_NONE) { + PRINTK("ip address<%s> is wrong\n", argv[1]); + return LOS_NOK; + } +#if LWIP_IPV4 && LWIP_IPV6 + dns.type = IPADDR_TYPE_V4; +#endif +#endif + } + + err = lwip_dns_setserver((u8_t)(i - 1), &dns); + if (err != ERR_OK) { + PRINTK("dns : failed\n"); + return LOS_NOK; + } + return LOS_OK; + } +usage: + PRINTK("usage:\n"); + PRINTK("\tdns <1-%d> \n", DNS_MAX_SERVERS); + PRINTK("\tdns -a\n"); + return LOS_NOK; +} + +#ifdef LOSCFG_SHELL_CMD_DEBUG +SHELLCMD_ENTRY(dns_shellcmd, CMD_TYPE_EX, "dns", XARGS, (CmdCallBackFunc)osShellDns); +#endif /* LOSCFG_SHELL_CMD_DEBUG */ +#endif /* LWIP_DNS */ +#if LWIP_IPV6 +extern struct nd6_neighbor_cache_entry neighbor_cache[LWIP_ND6_NUM_NEIGHBORS]; +#endif +#if LWIP_IPV6 +int netstat_get_udp_sendQLen6(struct udp_pcb *udppcb, struct pbuf *udpbuf) +{ + int sendLen = -1; + u16_t offset = 0, len; + struct ip6_hdr *iphdr = NULL; + struct udp_hdr *udphdr = NULL; + struct ip6_dest_hdr *dest_hdr = NULL; + struct ip6_frag_hdr *frag_hdr = NULL; + u8_t nexth; + u16_t hlen = 0; + + LWIP_ERROR("netstat_get_udp6_sendQLen: NULL pcb received\n", (udppcb != NULL), return -1); + LWIP_ERROR("netstat_get_udp6_sendQLen: NULL pbuf received\n", (udpbuf != NULL), return -1); + + iphdr = (struct ip6_hdr *)udpbuf->payload; + + if (!(ip6_addr_cmp(&iphdr->dest, ip_2_ip6(&udppcb->remote_ip)) && + (ip_addr_isany(&udppcb->local_ip) || + ip6_addr_cmp(&iphdr->src, ip_2_ip6(&udppcb->local_ip))))) { + goto FUNC_OUT; + } + + len = IP6_HLEN; + if (pbuf_header(udpbuf, (s16_t)(-(s16_t)(len)))) { + goto FUNC_OUT; + } + + offset = len; + + nexth = IP6H_NEXTH(iphdr); + while (offset < udpbuf->tot_len) { + if (nexth == IP6_NEXTH_NONE || nexth == IP6_NEXTH_UDP || nexth == IP6_NEXTH_UDPLITE) { + break; + } + switch (nexth) { + case IP6_NEXTH_HOPBYHOP: + case IP6_NEXTH_ROUTING: + nexth = *((u8_t *)udpbuf->payload); + hlen = (u16_t)(8 * (1 + *((u8_t *)udpbuf->payload + 1))); + break; + case IP6_NEXTH_DESTOPTS: + nexth = *((u8_t *)udpbuf->payload); + dest_hdr = (struct ip6_dest_hdr *)udpbuf->payload; + hlen = (u16_t)(8 * (1 + dest_hdr->_hlen)); + break; + case IP6_NEXTH_FRAGMENT: + frag_hdr = (struct ip6_frag_hdr *)udpbuf->payload; + nexth = frag_hdr->_nexth; + hlen = IP6_FRAG_HLEN; + break; + default: + /* Unknown next_header */ + goto FUNC_OUT; + } + + (void)pbuf_header(udpbuf, (s16_t)(-(s16_t)hlen)); + offset = (u16_t)(offset + hlen); + } + + /* If the while loop test condition failed , then revert the last offset change */ + if (offset >= udpbuf->tot_len) { + offset = (u16_t)(offset - hlen); + goto FUNC_OUT; + } + + LWIP_ERROR("Transport option should be UDP", (nexth == IP6_NEXTH_UDP || nexth == IP6_NEXTH_UDPLITE), goto FUNC_OUT); + + if (offset > iphdr->_plen) { + goto FUNC_OUT; + } + + /* check if there is enough space for at least udp header available */ + if (udpbuf->tot_len < UDP_HLEN) { + goto FUNC_OUT; + } + + udphdr = (struct udp_hdr *)udpbuf->payload; + if ((ntohs(udphdr->dest) == udppcb->remote_port) && (ntohs(udphdr->src) == udppcb->local_port)) { + if (ntohs(udphdr->len) > UDP_HLEN) { + sendLen = ntohs(udphdr->len) - UDP_HLEN; + } else { + sendLen = udpbuf->tot_len - UDP_HLEN; + } + } + +FUNC_OUT: + (void)pbuf_header(udpbuf, (s16_t)offset); // can not cross max limit of s16_t + return sendLen; +} +#endif + +#if LWIP_IPV4 +int netstat_get_udp_sendQLen(struct udp_pcb *udppcb, struct pbuf *udpbuf) +{ + int sendLen = -1; + u16_t offset = 0, len; + struct ip_hdr *iphdr = NULL; + struct udp_hdr *udphdr = NULL; + + LWIP_ERROR("netstat_get_udp_sendQLen: NULL pcb received\n", (udppcb != NULL), return -1); + LWIP_ERROR("netstat_get_udp_sendQLen: NULL pbuf received\n", (udpbuf != NULL), return -1); + + iphdr = (struct ip_hdr *)udpbuf->payload; + + if (!(ip4_addr_cmp(&iphdr->dest, ip_2_ip4(&udppcb->remote_ip)) && + (ip_addr_isany(&udppcb->local_ip) || + ip4_addr_cmp(&iphdr->src, ip_2_ip4(&udppcb->local_ip))))) { + goto FUNC_OUT; + } +#if LWIP_UDPLITE + if ((IPH_PROTO(iphdr) != IP_PROTO_UDP) && (IPH_PROTO(iphdr) != IP_PROTO_UDPLITE)) { +#else + if (IPH_PROTO(iphdr) != IP_PROTO_UDP) { +#endif + goto FUNC_OUT; + } + + if ((ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK) != 0) { + goto FUNC_OUT; + } + + len = (u16_t)(IPH_HL(iphdr) * 4); + if (pbuf_header(udpbuf, (s16_t)(-len))) { + goto FUNC_OUT; + } + + offset = (u16_t)(offset + len); + + udphdr = (struct udp_hdr *)udpbuf->payload; + if ((ntohs(udphdr->dest) == udppcb->remote_port) && (ntohs(udphdr->src) == udppcb->local_port)) { + sendLen = ntohs(udphdr->len) - UDP_HLEN; + } + +FUNC_OUT: + (void)pbuf_header(udpbuf, (s16_t)offset); + return sendLen; +} +#endif + +int netstat_tcp_recvq(struct tcp_pcb *tpcb) +{ + unsigned int retVal = 0; +#if LWIP_SO_RCVBUF + struct netconn *conn = NULL; +#endif + + LWIP_ERROR("netstat_tcp_recvq: Received NULL pcb\n", (tpcb != NULL), return 0); + +#if LWIP_SO_RCVBUF + conn = (struct netconn *)tpcb->callback_arg; + if (conn != NULL) { + switch (conn->type) { + case NETCONN_TCP: + case NETCONN_RAW: +#if LWIP_IPV6 + case NETCONN_RAW_IPV6: + case NETCONN_UDP_IPV6: +#endif + case NETCONN_UDP: + SYS_ARCH_GET(((unsigned int)conn->recv_avail), retVal); // + conn->lrcv_left + break; + default: + retVal = 0; /* ur... very ugly, damn DHCP DNS and SNTP */ + } + } +#endif + + return (int)retVal; +} + +int netstat_tcp_sendq(struct tcp_pcb *tpcb) +{ + int retVal = 0; + struct tcp_seg *useg = NULL; + + LWIP_ERROR("netstat_tcp_sendq: Received NULL pcb\n", (tpcb != NULL), return 0); + + for (useg = tpcb->unacked; useg != NULL; useg = useg->next) { + retVal = retVal + useg->len; + } + + return retVal; +} + +#if LWIP_IPV6 +int netstat_udp_sendq6(struct udp_pcb *upcb) +{ + int retLen = 0; + int ret; + int idx = 0; + int i; +#if LWIP_ND6_QUEUEING + struct nd6_q_entry *neibq = NULL; +#endif + + LWIP_ERROR("netstat_udp_sendq6: Received NULL pcb\n", (upcb != NULL), return 0); + + for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { + if (neighbor_cache[i].state != ND6_NO_ENTRY) { + if (ip6_addr_cmp(&upcb->remote_ip.u_addr.ip6, &neighbor_cache[i].next_hop_address)) { + idx = i; + break; + } + } + } +#if LWIP_ND6_QUEUEING + for (neibq = neighbor_cache[idx].q; neibq != NULL; neibq = neibq->next) { + ret = netstat_get_udp_sendQLen6(upcb, neibq->p); + if (ret >= 0) { + retLen += ret; + } + } +#else + ret = netstat_get_udp_sendQLen6(upcb, neighbor_cache[idx].q); + if (ret >= 0) { + retLen += ret; + } +#endif + return retLen; +} +#endif + +#if LWIP_IPV4 +int netstat_udp_sendq(struct udp_pcb *upcb) +{ + int retLen = 0; + int ret; + int arpidx = -1; + int i; +#if ARP_QUEUEING + struct etharp_q_entry *arpq = NULL; +#endif + + LWIP_ERROR("netstat_udp_sendq: Received NULL pcb\n", (upcb != NULL), return 0); + + for (i = 0; i < ARP_TABLE_SIZE; ++i) { + if (arp_table[i].state != ETHARP_STATE_EMPTY) { + if (ip4_addr_cmp(ip_2_ip4(&upcb->remote_ip), &arp_table[i].ipaddr)) { + arpidx = i; + break; + } + } + } + + if (arpidx >= 0) { +#if ARP_QUEUEING + for (arpq = arp_table[arpidx].q; arpq != NULL; arpq = arpq->next) { + ret = netstat_get_udp_sendQLen(upcb, arpq->p); + if (ret > 0) { + retLen += ret; + if (retLen <= 0) { // overflow, set rteLen = -1 to indicate + retLen = -1; + break; + } + } + } +#else + ret = netstat_get_udp_sendQLen(upcb, arp_table[arpidx].q); + if (ret > 0) { + retLen += ret; + if (retLen <= 0) { // overflow, set rteLen = -1 to indicate + retLen = -1; + } + } +#endif + } + return retLen; +} +#endif +int netstat_netconn_recvq(const struct netconn *conn) +{ + unsigned int retVal = 0; + +#if LWIP_SO_RCVBUF + if (conn == NULL) { + return 0; + } + + switch (NETCONNTYPE_GROUP((unsigned int)(conn->type))) { + case NETCONN_TCP: + case NETCONN_RAW: +#if PF_PKT_SUPPORT + case NETCONN_PKT_RAW: +#endif + case NETCONN_UDP: + SYS_ARCH_GET(((unsigned int)conn->recv_avail), retVal); // + conn->lrcv_left + break; + default: + retVal = 0; /* ur... very ugly, damn DHCP DNS and SNTP */ + } +#endif + return (int)retVal; +} + +int netstat_netconn_sendq(struct netconn *conn) +{ + int retVal = 0; + + if (conn == NULL) { + return 0; + } + + switch (NETCONNTYPE_GROUP((unsigned int)(conn->type))) { + case NETCONN_TCP: + retVal = netstat_tcp_sendq(conn->pcb.tcp); + break; + case NETCONN_RAW: + retVal = 0; + break; +#if PF_PKT_SUPPORT + case NETCONN_PKT_RAW: + retVal = 0; /* always be 0 as frame send to driver directly */ + break; +#endif + case NETCONN_UDP: + retVal = netstat_udp_sendq(conn->pcb.udp); + break; + default: + retVal = 0; /* ur... very ugly, damn DHCP DNS and SNTP */ + } + + return retVal; +} +void netstat_internal(void *ctx) +{ + s8_t local_ip_port[64] = {0}; + s8_t remote_ip_port[64] = {0}; + struct tcp_pcb *tpcb = NULL; + struct tcp_pcb_listen *lpcb = NULL; + struct udp_pcb *upcb = NULL; + struct raw_pcb *rpcb = NULL; + s8_t *entry_buf = NULL; + u32_t entry_buf_len; + u32_t entry_buf_offset; + struct netstat_data *ndata = (struct netstat_data *)ctx; + int iRet; + int recvQlen = 0; + int sendQlen = 0; + u_int proto; +#if PF_PKT_SUPPORT + u8_t netif_name[IFNAMSIZ]; + struct netif *netif = NULL; +#endif + + if (ndata == NULL) { + return; + } + entry_buf = ndata->netstat_out_buf; + entry_buf_len = ndata->netstat_out_buf_len; + entry_buf_offset = 0; + + if (entry_buf == NULL) { + goto out; + } + iRet = snprintf_s((char *)(entry_buf + entry_buf_offset), entry_buf_len, entry_buf_len - 1, + "========== total sockets %d ====== unused sockets %d ==========\n", + LWIP_CONFIG_NUM_SOCKETS, get_unused_socket_num()); + if ((iRet <= 0) || ((u32_t)(iRet) >= entry_buf_len)) { + goto out; + } + entry_buf_len -= (u32_t)(iRet); + entry_buf_offset += (u32_t)(iRet); + +#if LWIP_TCP + if (tcp_active_pcbs != NULL || tcp_bound_pcbs != NULL || tcp_tw_pcbs != NULL || tcp_listen_pcbs.pcbs != NULL) { + iRet = snprintf_s((char *)(entry_buf + entry_buf_offset), entry_buf_len, entry_buf_len - 1, + "%-8s%-12s%-12s%-24s%-24s%-16s\n", + "Proto", "Recv-Q", "Send-Q", "Local Address", "Foreign Address", "State"); + if ((iRet <= 0) || ((u32_t)(iRet) >= entry_buf_len)) { + goto out; + } + entry_buf_len -= (u32_t)(iRet); + entry_buf_offset += (u32_t)(iRet); + + for (tpcb = tcp_active_pcbs; tpcb != NULL; tpcb = tpcb->next) { + iRet = snprintf_s((char *)local_ip_port, sizeof(local_ip_port), (sizeof(local_ip_port) - 1), + "%s:%d", ipaddr_ntoa(&tpcb->local_ip), tpcb->local_port); + if ((iRet <= 0) || ((u32_t)(iRet) >= sizeof(local_ip_port))) { + goto out; + } + + iRet = snprintf_s((char *)remote_ip_port, sizeof(remote_ip_port), (sizeof(remote_ip_port) - 1), + "%s:%d", ipaddr_ntoa(&tpcb->remote_ip), tpcb->remote_port); + if ((iRet <= 0) || ((u32_t)(iRet) >= sizeof(remote_ip_port))) { + goto out; + } + if (tpcb->state == SYN_RCVD) { + recvQlen = 0; + sendQlen = 0; + } else { + recvQlen = netstat_netconn_recvq(tpcb->callback_arg); + sendQlen = netstat_netconn_sendq(tpcb->callback_arg); + } + iRet = snprintf_s((char *)(entry_buf + entry_buf_offset), entry_buf_len, entry_buf_len - 1, + IP_IS_V6(&tpcb->local_ip) ? "%-8s%-12d%-12d%-39s%-39s%-16s\n" : + "%-8s%-12d%-12d%-24s%-24s%-16s\n", + IP_IS_V6(&tpcb->local_ip) ? "tcp-ip6" : "tcp", + recvQlen, sendQlen, local_ip_port, remote_ip_port, tcp_state_str[tpcb->state]); + if ((iRet <= 0) || ((u32_t)(iRet) >= entry_buf_len)) { + goto out; + } + entry_buf_len -= (u32_t)(iRet); + entry_buf_offset += (u32_t)(iRet); + } + + /* For bound PCBs */ + sendQlen = 0; + recvQlen = 0; + + for (tpcb = tcp_bound_pcbs; tpcb != NULL; tpcb = tpcb->next) { + iRet = snprintf_s((char *)local_ip_port, sizeof(local_ip_port), (sizeof(local_ip_port) - 1), + "%s:%d", ipaddr_ntoa(&tpcb->local_ip), tpcb->local_port); + if ((iRet <= 0) || ((u32_t)(iRet) >= sizeof(local_ip_port))) { + goto out; + } + + iRet = snprintf_s((char *)remote_ip_port, sizeof(remote_ip_port), (sizeof(remote_ip_port) - 1), + "%s:%d", ipaddr_ntoa(&tpcb->remote_ip), tpcb->remote_port); + if ((iRet <= 0) || ((u32_t)(iRet) >= sizeof(remote_ip_port))) { + goto out; + } + + iRet = snprintf_s((char *)(entry_buf + entry_buf_offset), entry_buf_len, entry_buf_len - 1, + IP_IS_V6(&tpcb->local_ip) ? "%-8s%-12d%-12d%-39s%-39s%-16s\n" : + "%-8s%-12d%-12d%-24s%-24s%-16s\n", + IP_IS_V6(&tpcb->local_ip) ? "tcp-ip6" : "tcp", + recvQlen, sendQlen, local_ip_port, remote_ip_port, tcp_state_str[tpcb->state]); + if ((iRet <= 0) || ((u32_t)(iRet) >= entry_buf_len)) { + goto out; + } + entry_buf_len -= (u32_t)(iRet); + entry_buf_offset += (u32_t)(iRet); + } + + for (tpcb = tcp_tw_pcbs; tpcb != NULL; tpcb = tpcb->next) { + iRet = snprintf_s((char *)local_ip_port, sizeof(local_ip_port), (sizeof(local_ip_port) - 1), + "%s:%d", ipaddr_ntoa(&tpcb->local_ip), tpcb->local_port); + if ((iRet <= 0) || ((u32_t)(iRet) >= sizeof(local_ip_port))) { + goto out; + } + + iRet = snprintf_s((char *)remote_ip_port, sizeof(remote_ip_port), (sizeof(remote_ip_port) - 1), + "%s:%d", ipaddr_ntoa(&tpcb->remote_ip), tpcb->remote_port); + if ((iRet <= 0) || ((u32_t)(iRet) >= sizeof(remote_ip_port))) { + goto out; + } + + recvQlen = netstat_netconn_recvq(tpcb->callback_arg); + sendQlen = netstat_netconn_sendq(tpcb->callback_arg); + iRet = snprintf_s((char *)(entry_buf + entry_buf_offset), entry_buf_len, entry_buf_len - 1, + IP_IS_V6(&tpcb->local_ip) ? "%-8s%-12d%-12d%-39s%-39s%-16s\n" : + "%-8s%-12d%-12d%-24s%-24s%-16s\n", + IP_IS_V6(&tpcb->local_ip) ? "tcp-ip6" : "tcp", + recvQlen, sendQlen, local_ip_port, remote_ip_port, tcp_state_str[tpcb->state]); + if ((iRet <= 0) || ((u32_t)(iRet) >= entry_buf_len)) { + goto out; + } + entry_buf_len -= (u32_t)(iRet); + entry_buf_offset += (u32_t)(iRet); + } + + /* For listen PCBs */ + sendQlen = 0; + + for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { + iRet = snprintf_s((char *)local_ip_port, sizeof(local_ip_port), (sizeof(local_ip_port) - 1), + "%s:%d", ipaddr_ntoa(&lpcb->local_ip), lpcb->local_port); + if ((iRet <= 0) || ((u32_t)(iRet) >= sizeof(local_ip_port))) { + goto out; + } + + iRet = snprintf_s((char *)remote_ip_port, sizeof(remote_ip_port), (sizeof(remote_ip_port) - 1), + "%s:%d", ipaddr_ntoa(&lpcb->remote_ip), 0); + if ((iRet <= 0) || ((u32_t)(iRet) >= sizeof(remote_ip_port))) { + goto out; + } + + recvQlen = netstat_netconn_recvq(lpcb->callback_arg); + + iRet = snprintf_s((char *)(entry_buf + entry_buf_offset), entry_buf_len, entry_buf_len - 1, + IP_IS_V6(&lpcb->local_ip) ? "%-8s%-12d%-12d%-39s%-39s%-16s\n" : + "%-8s%-12d%-12d%-24s%-24s%-16s\n", + IP_IS_V6(&lpcb->local_ip) ? "tcp-ip6" : "tcp", + recvQlen, sendQlen, local_ip_port, remote_ip_port, tcp_state_str[lpcb->state]); + if ((iRet <= 0) || ((u32_t)(iRet) >= entry_buf_len)) { + goto out; + } + entry_buf_len -= (u32_t)(iRet); + entry_buf_offset += (u32_t)(iRet); + } + } +#endif +#if LWIP_UDP + if (udp_pcbs != NULL) { + iRet = snprintf_s((char *)(entry_buf + entry_buf_offset), entry_buf_len, entry_buf_len - 1, + "\n%-8s%-12s%-12s%-24s%-24s\n", + "Proto", "Recv-Q", "Send-Q", "Local Address", "Foreign Address"); + if ((iRet <= 0) || ((u32_t)(iRet) >= entry_buf_len)) { + goto out; + } + entry_buf_len -= (u32_t)(iRet); + entry_buf_offset += (u32_t)(iRet); + + for (upcb = udp_pcbs; upcb != NULL; upcb = upcb->next) { + iRet = snprintf_s((char *)local_ip_port, sizeof(local_ip_port), (sizeof(local_ip_port) - 1), + "%s:%d", ipaddr_ntoa(&upcb->local_ip), upcb->local_port); + if ((iRet <= 0) || ((u32_t)(iRet) >= sizeof(local_ip_port))) { + goto out; + } + + iRet = snprintf_s((char *)remote_ip_port, sizeof(remote_ip_port), (sizeof(remote_ip_port) - 1), + "%s:%d", ipaddr_ntoa(&upcb->remote_ip), upcb->remote_port); + if ((iRet <= 0) || ((u32_t)(iRet) >= sizeof(remote_ip_port))) { + goto out; + } + + recvQlen = netstat_netconn_recvq(upcb->recv_arg); +#if LWIP_IPV6 + sendQlen = IP_IS_V6(&upcb->local_ip) ? netstat_udp_sendq6(upcb) : netstat_netconn_sendq(upcb->recv_arg); +#else + sendQlen = netstat_netconn_sendq(upcb->recv_arg); +#endif + iRet = snprintf_s((char *)(entry_buf + entry_buf_offset), entry_buf_len, entry_buf_len - 1, + IP_IS_V6(&upcb->local_ip) ? "%-8s%-12d%-12d%-39s%-39s%-16s\n" : + "%-8s%-12d%-12d%-24s%-24s%-16s\n", + IP_IS_V6(&upcb->local_ip) ? "udp-ip6" : "udp", + recvQlen, sendQlen, local_ip_port, remote_ip_port, " "); + if ((iRet <= 0) || ((u32_t)(iRet) >= entry_buf_len)) { + goto out; + } + entry_buf_len -= (u32_t)(iRet); + entry_buf_offset += (u32_t)(iRet); + } + } +#endif + +#if LWIP_RAW + if (raw_pcbs != NULL) { + iRet = snprintf_s((char *)(entry_buf + entry_buf_offset), entry_buf_len, entry_buf_len - 1, + "\n%-8s%-12s%-12s%-20s%-20s%-16s%-16s\n", + "Type", "Recv-Q", "Send-Q", "Local Address", "Foreign Address", "Protocol", "HDRINCL"); + if ((iRet <= 0) || ((u32_t)(iRet) >= entry_buf_len)) { + goto out; + } + entry_buf_len -= (u32_t)(iRet); + entry_buf_offset += (u32_t)(iRet); + + for (rpcb = raw_pcbs; rpcb != NULL; rpcb = rpcb->next) { + iRet = snprintf_s((char *)local_ip_port, sizeof(local_ip_port), (sizeof(local_ip_port) - 1), + "%s", ipaddr_ntoa(&rpcb->local_ip)); + if ((iRet <= 0) || ((u32_t)(iRet) >= sizeof(local_ip_port))) { + goto out; + } + + iRet = snprintf_s((char *)remote_ip_port, sizeof(remote_ip_port), (sizeof(remote_ip_port) - 1), + "%s", ipaddr_ntoa(&rpcb->remote_ip)); + if ((iRet <= 0) || ((u32_t)(iRet) >= sizeof(remote_ip_port))) { + goto out; + } + + recvQlen = netstat_netconn_recvq(rpcb->recv_arg); + sendQlen = netstat_netconn_sendq(rpcb->recv_arg); + + proto = rpcb->protocol; // raw_proto; + iRet = snprintf_s((char *)(entry_buf + entry_buf_offset), entry_buf_len, entry_buf_len - 1, + "%-8s%-12d%-12d%-20s%-20s%-16u%-16d\n", + "raw", recvQlen, sendQlen, local_ip_port, remote_ip_port, proto, 0); // rpcb->hdrincl + if ((iRet <= 0) || ((u32_t)(iRet) >= entry_buf_len)) { + goto out; + } + entry_buf_len -= (u32_t)(iRet); + entry_buf_offset += (u32_t)(iRet); + } + } +#if PF_PKT_SUPPORT + if (pkt_raw_pcbs != NULL) { + iRet = snprintf_s((char *)(entry_buf + entry_buf_offset), entry_buf_len, entry_buf_len - 1, + "\n%-12s%-12s%-12s%-16s%-12s\n", "Type", "Recv-Q", "Send-Q", "Protocol", "netif"); + if ((iRet <= 0) || ((u32_t)(iRet) >= entry_buf_len)) { + goto out; + } + entry_buf_len -= (u32_t)(iRet); + entry_buf_offset += (u32_t)(iRet); + + for (rpcb = pkt_raw_pcbs; rpcb != NULL; rpcb = rpcb->next) { + recvQlen = netstat_netconn_recvq(rpcb->recv_arg); + sendQlen = netstat_netconn_sendq(rpcb->recv_arg); + + for (netif = netif_list; netif != NULL; netif = netif->next) { + /* netif->ifindex and index */ + if (netif_get_index(netif) == rpcb->netif_idx) { + (void)snprintf_s((char *)netif_name, IFNAMSIZ, IFNAMSIZ - 1, "%s", netif_get_name(netif)); + break; + } + } + + if (netif == NULL) { + (void)snprintf_s((char *)netif_name, IFNAMSIZ, IFNAMSIZ - 1, "%s", "None"); + } + + proto = rpcb->protocol; // ntohs(rpcb->proto.eth_proto); + + iRet = snprintf_s((char *)(entry_buf + entry_buf_offset), entry_buf_len, entry_buf_len - 1, + "%-12s%-12d%-12d%-16x%-12s\n", "pkt-raw", recvQlen, sendQlen, proto, netif_name); + if ((iRet <= 0) || ((u32_t)(iRet) >= entry_buf_len)) { + goto out; + } + entry_buf_len -= (u32_t)(iRet); + entry_buf_offset += (u32_t)(iRet); + } + } +#endif +#endif + +out: + ndata->netstat_out_buf_updated_len = entry_buf_offset; + sys_sem_signal(&ndata->cb_completed); + return; +} + +u32_t osShellNetstat(int argc, const char **argv) +{ + struct netstat_data ndata; + err_t err; + + if (argc > 0) { + PRINTK("\nUsage: netstat\n"); + return LOS_NOK; + } + + if (tcpip_init_finish == 0) { + PRINTK("%s: tcpip_init have not been called\n", __FUNCTION__); + return LOS_NOK; + } + + ndata.netstat_out_buf = mem_malloc(MAX_NETSTAT_ENTRY); + if (ndata.netstat_out_buf == NULL) { + PRINTK("%s: no free mem\n", __FUNCTION__); + return LOS_NOK; + } + ndata.netstat_out_buf_len = MAX_NETSTAT_ENTRY; + ndata.netstat_out_buf_updated_len = 0; + + if (sys_sem_new(&ndata.cb_completed, 0) != ERR_OK) { + goto err_hand; + } + + err = tcpip_callback(netstat_internal, &ndata); + if (err != ERR_OK) { + sys_sem_free(&ndata.cb_completed); + goto err_hand; + } + + (void)sys_arch_sem_wait(&ndata.cb_completed, 0); + sys_sem_free(&ndata.cb_completed); + if ((ndata.netstat_out_buf_updated_len > 0) && (ndata.netstat_out_buf_updated_len < MAX_NETSTAT_ENTRY)) { + PRINTK("%s\n", (char *)(ndata.netstat_out_buf)); + mem_free(ndata.netstat_out_buf); + return LOS_OK; + } + +err_hand: + mem_free(ndata.netstat_out_buf); + ndata.netstat_out_buf = NULL; + (void)(argv); + return LOS_NOK; +} +#ifdef LOSCFG_SHELL +SHELLCMD_ENTRY(netstat_shellcmd, CMD_TYPE_EX, "netstat", XARGS, (CmdCallBackFunc)osShellNetstat); +#endif /* LOSCFG_SHELL */ + +#define NETIF_NAME_LEN 10 +STATIC VOID OsShellDhclientUsage(VOID) +{ + PRINTK(", start dhcp for netif name\n" + "-x , stop dhcp for netif name\n" + "-h | --help, print dhclient command usage\n"); +} + +u32_t OsShellDhclient(int argc, const char **argv) +{ + struct netif *netif = NULL; + + if (argc == 0) { + OsShellDhclientUsage(); + } else if (argc == 1) { + if (strcmp(argv[0], "-h") == 0 || strcmp(argv[0], "--help") == 0) { + OsShellDhclientUsage(); + } else { + netif = netif_find(argv[0]); + if (netif != NULL) { + (VOID)netifapi_dhcp_start(netif); + } else { + PRINTK("dhclient: invalid option: %s\n", argv[0]); + OsShellDhclientUsage(); + } + } + } else if (argc == 2) { + if (strcmp(argv[0], "-x") == 0) { + netif = netif_find(argv[1]); + if (netif != NULL) { + (VOID)netifapi_dhcp_stop(netif); + } else { + PRINTK("dhclient: invalid option: %s\n", argv[1]); + OsShellDhclientUsage(); + } + } else { + PRINTK("dhclient: invalid option: %s\n", argv[0]); + OsShellDhclientUsage(); + } + } else { + OsShellDhclientUsage(); + } + + return 0; +} + +#ifdef LOSCFG_SHELL +SHELLCMD_ENTRY(dhclient_shellcmd, CMD_TYPE_EX, "dhclient", XARGS, (CmdCallBackFunc)OsShellDhclient); +#endif /* LOSCFG_SHELL */ + +#ifdef LWIP_DEBUG_TCPSERVER + +#define MAX_SIZE 1024 +void tcp_access(int sockfd) +{ + size_t n, i; + ssize_t ret; + char msg[MAX_SIZE] = {0}; + while (1) { + PRINTK("waiting for recv\n"); + (void)memset_s(msg, MAX_SIZE, 0, MAX_SIZE); + ret = recv(sockfd, msg, MAX_SIZE - 1, 0); + if (ret < 0) { + PRINTK("recv failed, %d.\n", (u32_t)ret); + (void)closesocket(sockfd); + return; + } else if (ret == 0) { + (void)closesocket(sockfd); + PRINTK("client disconnect.\n"); + return; + } + + n = strlen(msg); + for (i = 0; i < n; ++i) { + if (msg[i] >= 'a' && msg[i] <= 'z') { + msg[i] = (char)(msg[i] + ('A' - 'a')); + } else if (msg[i] >= 'A' && msg[i] <= 'Z') { + msg[i] = (char)(msg[i] + ('a' - 'A')); + } + } + + if (send(sockfd, msg, n, 0) < 0) { + PRINTK("send failed!\r\n"); + continue; + } + } +} + +u32_t osTcpserver(int argc, const char **argv) +{ + uint16_t port; + int sockfd = -1; + int ret; + struct sockaddr_in seraddr; + struct sockaddr_in cliaddr; + u32_t cliaddr_size = (u32_t)sizeof(cliaddr); + int reuse, iPortVal; + + if (tcpip_init_finish == 0) { + PRINTK("tcpip_init have not been called\n"); + return LOS_NOK; + } + + if (argc < 1 || argv == NULL) { + PRINTK("\nUsage: tcpserver \n"); + return LOS_NOK; + } + + iPortVal = atoi(argv[0]); + /* Port 0 not supported , negative values not supported , max port limit is 65535 */ + if (iPortVal <= 0 || iPortVal > 65535) { + PRINTK("\nUsage: Invalid port\n"); + return LOS_NOK; + } + + port = (uint16_t)iPortVal; + + /* removed the print of argv[1] as its accessing argv[1] without verifying argc and + * argv[1] not used anywhere else */ + PRINTK("argv[0]:%s, argc:%d\r\n", argv[0], argc); + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd < 0) { + PRINTK("\nUsage: create socket fail!\n"); + return LOS_NOK; + } + reuse = 1; + if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char *)&reuse, sizeof(reuse)) != 0) { + (void)closesocket(sockfd); + PRINTK("set SO_REUSEADDR failed\n"); + return LOS_NOK; + } + + (void)memset_s(&seraddr, sizeof(seraddr), 0, sizeof(seraddr)); + seraddr.sin_family = AF_INET; + seraddr.sin_addr.s_addr = htonl(INADDR_ANY); + seraddr.sin_port = htons(port); + + ret = bind(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr)); + if (ret < 0) { + PRINTK("bind ip and port failed"); + (void)closesocket(sockfd); + return LOS_NOK; + } + + ret = listen(sockfd, 5); + if (ret < 0) { + (void)closesocket(sockfd); + PRINTK("listen failed\n"); + return LOS_NOK; + } + while (1) { + PRINTK("waiting for accept\n"); + (void)memset_s(&cliaddr, sizeof(struct sockaddr_in), 0, sizeof(struct sockaddr_in)); + ret = (int)accept(sockfd, (struct sockaddr *)&cliaddr, &cliaddr_size); + if (ret < 0) { + (void)closesocket(sockfd); + PRINTK("Accept failed, %d\n", ret); + break; + } + tcp_access(ret); + } + return LOS_NOK; // Hits Only If Accept Fails +} + +#ifdef LOSCFG_SHELL_CMD_DEBUG +SHELLCMD_ENTRY(tcpserver_shellcmd, CMD_TYPE_EX, "tcpserver", XARGS, (CmdCallBackFunc)osTcpserver); +#endif /* LOSCFG_SHELL_CMD_DEBUG */ +#endif /* LWIP_DEBUG_TCPSERVER */ + +#ifdef LWIP_DEBUG_UDPSERVER +void udpserver(int argc, const char **argv) +{ + int sockfd, fromlen; + int ret, iPortVal; + struct sockaddr_in seraddr; + struct sockaddr_in cliaddr; + size_t n, i; + + char msg[MAX_SIZE] = {0}; + uint16_t port; + + if (argc < 1) { + PRINTK("\nUsage: udpserver \n"); + return; + } + + iPortVal = atoi(argv[0]); + /* Port 0 not supported , negative values not supported , max port limit is 65535 */ + if (iPortVal <= 0 || iPortVal > 65535) { + PRINTK("\nUsage: Invalid Port\n"); + return; + } + + port = (uint16_t)iPortVal; + + PRINTK("port:%d\r\n", port); + + sockfd = lwip_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (sockfd == -1) { + PRINTK("\ncreate socket fail\n"); + return; + } + + (void)memset_s(&seraddr, sizeof(seraddr), 0, sizeof(seraddr)); + (void)memset_s(&cliaddr, sizeof(cliaddr), 0, sizeof(cliaddr)); + seraddr.sin_family = AF_INET; + seraddr.sin_addr.s_addr = htonl(INADDR_ANY); + seraddr.sin_port = htons(port); + ret = lwip_bind(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr)); + if (ret < 0) { + PRINTK("bind ip and port failed:%d\n", errno); + (void)closesocket(sockfd); + return; + } + + while (1) { + ret = recvfrom(sockfd, msg, MAX_SIZE - 1, 0, (struct sockaddr *)&cliaddr, (socklen_t *)&fromlen); + if (ret >= 0) { + n = strlen(msg); + for (i = 0; i < n; ++i) { + if (msg[i] >= 'a' && msg[i] <= 'z') { + msg[i] = (char)(msg[i] + 'A' - 'a'); + } else if (msg[i] >= 'A' && msg[i] <= 'Z') { + msg[i] = (char)(msg[i] + 'a' - 'A'); + } + } + ret = sendto(sockfd, msg, n + 1, 0, (struct sockaddr *)&cliaddr, (socklen_t)fromlen); + if (ret <= 0 && errno == EPIPE) { + break; + } + } else { + break; + } + } + + (void)closesocket(sockfd); + return; +} + +#ifdef LOSCFG_SHELL_CMD_DEBUG +SHELLCMD_ENTRY(udpserver_shellcmd, CMD_TYPE_EX, "udpserver", XARGS, (CmdCallBackFunc)udpserver); +#endif /* LOSCFG_SHELL_CMD_DEBUG */ +#endif /* LWIP_DEBUG_UDPSERVER */ + +#ifdef LWIP_DEBUG_INFO +LWIP_STATIC +u32_t netdebug_memp(int argc, const char **argv) +{ + u32_t ret = LOS_OK; + int type; + + if (argc == 2) { + if (!strcmp("-i", argv[1])) { + debug_memp_info(); + } else if (!strcmp("-udp", argv[1])) { + debug_memp_type_info(MEMP_UDP_PCB); + } else if (!strcmp("-tcp", argv[1])) { + debug_memp_type_info(MEMP_TCP_PCB); + } else if (!strcmp("-raw", argv[1])) { + debug_memp_type_info(MEMP_RAW_PCB); + } else if (!strcmp("-conn", argv[1])) { + debug_memp_type_info(MEMP_NETCONN); + } else { + ret = LOS_NOK; + } + } else if (argc == 3) { + if (!strcmp("-d", argv[1])) { + type = atoi(argv[2]); + if (type >= 0) { + debug_memp_detail(type); + } else { + PRINTK("Error: type < 0\n"); + ret = LOS_NOK; + } + } else { + ret = LOS_NOK; + } + } else { + ret = LOS_NOK; + } + + return ret; +} + +LWIP_STATIC +u32_t netdebug_sock(int argc, const char **argv) +{ + int idx; + u32_t ret = LOS_NOK; + + if (argc == 2) { /* 2: Number of command parameters */ + if (!strcmp("-i", argv[1])) { + /* netdebug sock -i */ + for (idx = 0; idx < (int)LWIP_CONFIG_NUM_SOCKETS; idx++) { + debug_socket_info(idx, 1, 0); + } + ret = LOS_OK; + } + } else if (argc == 3) { /* 3: Number of command parameters */ + if (!strcmp("-d", argv[1])) { + idx = atoi(argv[2]); /* 2: netdebug sock -d */ + if (idx >= 0) { + debug_socket_info(idx, 1, 1); + ret = LOS_OK; + } else { + PRINTK("Error: idx < 0\n"); + } + } + } + + return ret; +} + + +u32_t osShellNetDebug(int argc, const char **argv) +{ + u32_t ret = LOS_NOK; + + if (argc < 1 || argv == NULL) { + goto usage; + } + + if (!strcmp("memp", argv[0])) { + ret = netdebug_memp(argc, argv); + if (ret != LOS_OK) { + goto usage_memp; + } + } else if (!strcmp("sock", argv[0])) { + /* netdebug sock {-i | -d } */ + ret = netdebug_sock(argc, argv); + if (ret != LOS_OK) { + goto usage_sock; + } + } else { + goto usage; + } + return ret; + +usage: + /* Cmd help */ + PRINTK("\nUsage:\n"); + PRINTK("netdebug memp {-i | -d | -udp | -tcp | -raw |-conn}\n"); + PRINTK("netdebug sock {-i | -d }\n"); + return LOS_NOK; + +usage_memp: + /* netdebug memp help */ + PRINTK("\nUsage:\n"); + PRINTK("netdebug memp {-i | -d | -udp | -tcp | -raw |-conn}\n"); + return LOS_NOK; + +usage_sock: + /* netdebug sock help */ + PRINTK("\nUsage:\n"); + PRINTK("netdebug sock {-i | -d }\n"); + return LOS_NOK; +} +#endif /* LWIP_DEBUG_INFO */ + +#if defined(LOSCFG_SHELL_CMD_DEBUG) && defined(LWIP_DEBUG_INFO) +SHELLCMD_ENTRY(netdebug_shellcmd, CMD_TYPE_EX, "netdebug", XARGS, (CmdCallBackFunc)osShellNetDebug); +#endif /* LOSCFG_SHELL_CMD_DEBUG && LWIP_DEBUG_INFO */ + +u32_t osShellIpDebug(int argc, const char **argv) +{ + u8_t i = 0; + char acIPv6Addr[IP6ADDR_STRLEN_MAX + 1] = {0}; + char aclladdr[20] = {0}; + const char *acStates[] = {"NO_ENTRY", "INCOMPLETE", "REACHABLE", "STALE", "DELAY", "PROBE"}; + u8_t atleastOneEntry = 0; + + if (!tcpip_init_finish) { + PRINTK("%s: tcpip_init have not been called\n", __FUNCTION__); + goto exit; + } + + /* Display prefix */ + PRINTK("=================\n"); + PRINTK("|| Prefix List ||\n"); + PRINTK("=================\n"); + PRINTK("%-50s %-16s %-20s\n", "Prefix", "netif", "validLifetime"); + PRINTK("---------------------------------------------------------------------------------\n"); + /* Display neighbour Cache Entry */ + for (i = 0; i < LWIP_ND6_NUM_PREFIXES; i++) { + if (prefix_list[i].netif != NULL && prefix_list[i].invalidation_timer > 0) { + atleastOneEntry = 1; + (void)ip6addr_ntoa_r((const ip6_addr_t *)(prefix_list[i].prefix.addr), (acIPv6Addr), sizeof(acIPv6Addr)); + PRINTK("%-50s ", acIPv6Addr); + PRINTK("%-16s ", netif_get_name(prefix_list[i].netif)); + PRINTK("%-20u\n", prefix_list[i].invalidation_timer); + } + } + + if (!atleastOneEntry) { + PRINTK("**** NO VALID PREFIXES FOUND CONFIGURED ****\n"); + } + PRINTK("---------------------------------------------------------------------------------\n"); + + atleastOneEntry = 0; + + PRINTK("\n\n"); + PRINTK("============================\n"); + PRINTK("|| Neighbor Cache Entries ||\n"); + PRINTK("============================\n"); + PRINTK("%-50s %-25s %-16s %-15s %-10s\n", "Neighbor", "MAC", "netif", "state", "IsRouter"); + PRINTK("------------------------------------------------------------" + "----------------------------------------------------------\n"); + + /* Display neighbour Cache Entry */ + for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { + if (neighbor_cache[i].state != ND6_NO_ENTRY) { + atleastOneEntry = 1; + (void)ip6addr_ntoa_r((const ip6_addr_t *)(neighbor_cache[i].next_hop_address.addr), (acIPv6Addr), + sizeof(acIPv6Addr)); + PRINTK("%-50s ", acIPv6Addr); + + if (snprintf_s(aclladdr, sizeof(aclladdr), sizeof(aclladdr) - 1, "%02X:%02X:%02X:%02X:%02X:%02X", + neighbor_cache[i].lladdr[0], neighbor_cache[i].lladdr[1], /* 0, 1, member number */ + neighbor_cache[i].lladdr[2], neighbor_cache[i].lladdr[3], /* 2, 3, member number */ + neighbor_cache[i].lladdr[4], neighbor_cache[i].lladdr[5]) < 0) { /* 4, 5, member number */ + return LOS_NOK; + } + PRINTK("%-25s ", aclladdr); + PRINTK("%-16s ", netif_get_name(neighbor_cache[i].netif)); + PRINTK("%-15s ", acStates[neighbor_cache[i].state]); + PRINTK("%-10s\n", (neighbor_cache[i].isrouter ? "Yes" : "No")); + } + } + if (!atleastOneEntry) { + PRINTK("**** NO NEIGHBOURS FOUND ****\n"); + } + PRINTK("------------------------------------------------------------" + "----------------------------------------------------------\n"); + + atleastOneEntry = 0; + + PRINTK("\n\n"); + PRINTK("===============================\n"); + PRINTK("|| Destination Cache Entries ||\n"); + PRINTK("===============================\n"); + PRINTK("%-50s %-50s %-10s %-10s\n", "Destination", "NextHop", "PMTU", "age"); + PRINTK("------------------------------------------------------------" + "--------------------------------------------------------\n"); + /* Display destination Cache Entry */ + for (i = 0; i < LWIP_ND6_NUM_DESTINATIONS; i++) { + if (!ip6_addr_isany(&(destination_cache[i].destination_addr))) { + atleastOneEntry = 1; + (void)ip6addr_ntoa_r((const ip6_addr_t *)(destination_cache[i].destination_addr.addr), (acIPv6Addr), + sizeof(acIPv6Addr)); + PRINTK("%-50s ", acIPv6Addr); + (void)ip6addr_ntoa_r((const ip6_addr_t *)(destination_cache[i].next_hop_addr.addr), (acIPv6Addr), + sizeof(acIPv6Addr)); + PRINTK("%-50s ", acIPv6Addr); + PRINTK("%-10u ", destination_cache[i].pmtu); + PRINTK("%-10u\n", destination_cache[i].age); + } + } + if (!atleastOneEntry) { + PRINTK("**** NO DESTINATION CACHE FOUND ****\n"); + } + PRINTK("------------------------------------------------------------" + "--------------------------------------------------------\n"); + + atleastOneEntry = 0; + PRINTK("\n\n"); + PRINTK("============================\n"); + PRINTK("|| Default Router Entries ||\n"); + PRINTK("============================\n"); + PRINTK("%-50s %-20s %-10s\n", "Router", "invalidation_timer", "flags"); + PRINTK("-----------------------------------------------------------------------------\n"); + /* Display Default Router Cache Entry */ + for (i = 0; i < LWIP_ND6_NUM_ROUTERS; i++) { + if (default_router_list[i].neighbor_entry) { + atleastOneEntry = 1; + (void)ip6addr_ntoa_r((const ip6_addr_t *)((default_router_list[i].neighbor_entry)->next_hop_address.addr), + (acIPv6Addr), sizeof(acIPv6Addr)); + PRINTK("%-50s ", acIPv6Addr); + PRINTK("%-20u ", default_router_list[i].invalidation_timer); + PRINTK("%-10u\n", default_router_list[i].flags); + } + } + if (!atleastOneEntry) { + PRINTK("**** NO DEFAULT ROUTERS FOUND ****\n"); + } + PRINTK("-----------------------------------------------------------------------------\n"); + +exit: + return LOS_OK; +} + +#ifdef LOSCFG_SHELL_CMD_DEBUG +SHELLCMD_ENTRY(ipdebug_shellcmd, CMD_TYPE_EX, "ipdebug", XARGS, (CmdCallBackFunc)osShellIpDebug); +#endif +#ifdef LWIP_TESTBED +extern void cmd_reset(void); + +void osShellReboot(int argc, const char **argv) +{ + cmd_reset(); +} + +#ifdef LOSCFG_SHELL_CMD_DEBUG +SHELLCMD_ENTRY(reboot_shellcmd, CMD_TYPE_EX, "reboot", XARGS, (CmdCallBackFunc)osShellReboot); +#endif /* LOSCFG_SHELL_CMD_DEBUG */ +#endif + +#endif // LWIP_ENABLE_LOS_SHELL_CMD diff --git a/src/kernel_liteos_a/net/lwip-2.1/enhancement/src/dhcps.c b/src/kernel_liteos_a/net/lwip-2.1/enhancement/src/dhcps.c new file mode 100644 index 00000000..602432a4 --- /dev/null +++ b/src/kernel_liteos_a/net/lwip-2.1/enhancement/src/dhcps.c @@ -0,0 +1,982 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Dynamic Host Configuration Protocol Server + * + */ + +#include "../core/ipv4/dhcp.c" /* for enum dhcp_option_idx/dhcp_option_xx/dhcp_parse_reply etc. */ + +#include "lwip/opt.h" + +#if (LWIP_DHCP) && (LWIP_DHCPS) /* don't build if not configured for use in lwipopts.h */ +#include + +#include "lwip/stats.h" +#include "lwip/mem.h" +#include "lwip/udp.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" +#include "lwip/def.h" +#include "lwip/prot/dhcp.h" +#include "lwip/dhcp.h" +#include "lwip/dhcps.h" +#include "lwip/sys.h" +#include "netif/etharp.h" + +#define DHCPS_ADDRESS_FREE 0x0 +#define DHCPS_ADDRESS_OFFERRED 0x1 +#define DHCPS_ADDRESS_BOUND 0x2 +#define DHCPS_ADDRESS_DECLINED 0x3 + +#define LWIP_STATIC static +#define DHCP_OPTION_ROUTER_SIZE 4 +#define DHCP_OPTION_SUBNET_MASK_SIZE 4 +#define DHCP_OPTION_LEASE_TIME_SIZE 4 +#define DHCP_OPTION_SERVER_ID_LEN 4 +#define DHCP_OPTION_T1_LEN 4 +#define DHCP_OPTION_T2_LEN 4 + +#define DHCP_CLIENT_PORT 68 +#define DHCP_SERVER_PORT 67 + +#define DHCP_BROADCAST_FLAG 0x8000 + +struct dyn_lease_addr { + u8_t cli_hwaddr[DHCP_CHADDR_LEN]; + u32_t flags; + u32_t leasetime; + u32_t proposed_leasetime; + ip4_addr_t cli_addr; +}; + +struct dhcps { + struct dhcp dhcp; + struct udp_pcb *pcb; + struct dyn_lease_addr leasearr[LWIP_DHCPS_MAX_LEASE]; + u8_t pcb_allocated; + u8_t lease_num; + struct netif *netif; + ip4_addr_t start_addr; + ip4_addr_t end_addr; +}; + +#define dhcps_option_given(dhcps, idx) dhcp_option_given(&(dhcps)->dhcp, idx) +#define dhcps_got_option(dhcps, idx) dhcp_got_option(&(dhcps)->dhcp, idx) +#define dhcps_clear_option(dhcps, idx) dhcp_clear_option(&(dhcps)->dhcp, idx) +#define dhcps_clear_all_options(dhcps) dhcp_clear_all_options(&(dhcps)->dhcp) +#define dhcps_get_option_value(dhcps, idx) dhcp_get_option_value(&(dhcps)->dhcp, idx) +#define dhcps_set_option_value(dhcps, idx, val) dhcp_set_option_value(&(dhcps)->dhcp, idx, val) + +#define netif_get_dhcps(netif) ((struct dhcps*)netif_get_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCPS)) +#define netif_set_dhcps(netif, dhcps) netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCPS, dhcps) + +LWIP_STATIC void dhcp_common_option(struct dhcp_msg *msg_out, u8_t option_type, u8_t option_len, u16_t *options_out_len); +LWIP_STATIC void dhcp_common_option_byte(struct dhcp_msg *msg_out, u8_t value, u16_t *options_out_len); +LWIP_STATIC void dhcp_common_option_long(struct dhcp_msg *msg_out, u32_t value, u16_t *options_out_len); +LWIP_STATIC void dhcp_common_option_trailer(struct dhcp_msg *msg_out, u16_t options_out_len, struct pbuf *p_out); +LWIP_STATIC err_t dhcps_parse_options(struct pbuf *p, struct dhcps *dhcps); + +LWIP_STATIC struct pbuf *dhcps_create_base_msg(struct dhcp_msg *client_msg); +LWIP_STATIC void remove_stale_entries(struct dhcps *dhcps); +LWIP_STATIC void add_client_entry(struct dhcps *dhcps, unsigned int idx, struct dhcp_msg *client_msg); +LWIP_STATIC int find_free_slot(struct dhcps *dhcps); +LWIP_STATIC struct dyn_lease_addr *find_client_lease(struct dhcps *dhcps, struct dhcp_msg *client_msg); +LWIP_STATIC ip4_addr_t validate_discover(struct dhcps *dhcps, struct dhcp_msg *client_msg, + struct dyn_lease_addr **client_lease); +LWIP_STATIC void handle_discover(struct netif *netif, struct dhcps *dhcps, struct dhcp_msg *client_msg, + struct dyn_lease_addr *client_lease); +LWIP_STATIC ip4_addr_t validate_request_message(struct netif *netif, struct dhcp_msg *client_msg, + struct dyn_lease_addr *client_lease, ip4_addr_t serverid); +LWIP_STATIC void handle_request(struct netif *netif, struct dhcps *dhcps, struct dhcp_msg *client_msg, + struct dyn_lease_addr *client_lease, ip4_addr_t serverid); +LWIP_STATIC void handle_decline(struct netif *netif, struct dhcps *dhcps, struct dhcp_msg *client_msg, + struct dyn_lease_addr *client_lease); +LWIP_STATIC void handle_inform(struct netif *netif, struct dhcps *dhcps, struct dhcp_msg *client_msg); +LWIP_STATIC void handle_client_messages(struct netif *netif, struct dhcps *dhcps, + struct dhcp_msg *client_msg, ip4_addr_t serverid, u8_t msg_type); +LWIP_STATIC void dhcps_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, + const ip_addr_t *ip_addr, u16_t port); + +LWIP_STATIC struct pbuf *dhcps_create_base_msg(struct dhcp_msg *client_msg) +{ + struct pbuf *srvr_msg_pbuf = NULL; + struct dhcp_msg *srvr_msg = NULL; + + srvr_msg_pbuf = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcp_msg), PBUF_RAM); + if (srvr_msg_pbuf == NULL) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, + ("dhcps_create_base_msg(): could not allocate pbuf\n")); + return NULL; + } + + LWIP_ASSERT("dhcps_create_base_msg: check that first pbuf can hold struct dhcp_msg", + (srvr_msg_pbuf->len >= sizeof(struct dhcp_msg))); +#if DRIVER_STATUS_CHECK + srvr_msg_pbuf->flags |= PBUF_FLAG_DHCP_BUF; +#endif + + srvr_msg = (struct dhcp_msg *)srvr_msg_pbuf->payload; + srvr_msg->op = DHCP_BOOTREPLY; + srvr_msg->htype = client_msg->htype; + srvr_msg->hlen = client_msg->hlen; + srvr_msg->hops = 0; + srvr_msg->xid = client_msg->xid; + srvr_msg->secs = 0; + srvr_msg->flags = client_msg->flags; + ip4_addr_set_zero(&srvr_msg->ciaddr); + ip4_addr_set_zero(&srvr_msg->yiaddr); + ip4_addr_set_zero(&srvr_msg->siaddr); + ip4_addr_copy(srvr_msg->giaddr, client_msg->giaddr); + if (memcpy_s(srvr_msg->chaddr, sizeof(srvr_msg->chaddr), client_msg->chaddr, DHCP_CHADDR_LEN) != EOK) { + (void)pbuf_free(srvr_msg_pbuf); + return NULL; + } + (void)memset_s(srvr_msg->sname, sizeof(srvr_msg->sname), 0, DHCP_SNAME_LEN); + (void)memset_s(srvr_msg->file, sizeof(srvr_msg->file), 0, DHCP_FILE_LEN); + srvr_msg->cookie = PP_HTONL(DHCP_MAGIC_COOKIE); + + return srvr_msg_pbuf; +} + +LWIP_STATIC void remove_stale_entries(struct dhcps *dhcps) +{ + int i = 0; + u32_t curr_time = sys_now(); + + for (i = 0; i < dhcps->lease_num; i++) { + /* Slot should not be free or have infinite lease time */ + if ((dhcps->leasearr[i].flags != DHCPS_ADDRESS_FREE) && (dhcps->leasearr[i].leasetime != (u32_t)~0)) { + if (dhcps->leasearr[i].leasetime < curr_time) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, + ("remove_stale_entries: Removing Client Entry at Index = %"U32_F"\n", i)); + (void)memset_s(&(dhcps->leasearr[i]), sizeof(struct dyn_lease_addr), 0, sizeof(struct dyn_lease_addr)); + dhcps->leasearr[i].flags = DHCPS_ADDRESS_FREE; + } + } + } +} + +LWIP_STATIC void add_client_entry(struct dhcps *dhcps, unsigned int idx, struct dhcp_msg *client_msg) +{ + u32_t client_lease_time = (u32_t)(LWIP_DHCPS_LEASE_TIME); + + if ((dhcps_option_given(dhcps, DHCP_OPTION_IDX_LEASE_TIME)) +#if (LWIP_DHCPS_LEASE_TIME != ~0) + && (dhcps_get_option_value(dhcps, DHCP_OPTION_IDX_LEASE_TIME) < LWIP_DHCPS_LEASE_TIME) +#endif + ) { + client_lease_time = (u32_t)dhcps_get_option_value(dhcps, DHCP_OPTION_IDX_LEASE_TIME); + } + + (void)memset_s(&(dhcps->leasearr[idx]), sizeof(struct dyn_lease_addr), 0, sizeof(struct dyn_lease_addr)); + if (memcpy_s(dhcps->leasearr[idx].cli_hwaddr, DHCP_CHADDR_LEN, + client_msg->chaddr, sizeof(client_msg->chaddr)) != EOK) { + return; + } + /* This is called only during offer message, so adding offer time. + This is later updated to lease time when request message is handled */ + dhcps->leasearr[idx].leasetime = sys_now() + (LWIP_DHCPS_OFFER_TIME * 1000); + dhcps->leasearr[idx].cli_addr.addr = dhcps->start_addr.addr + idx; + dhcps->leasearr[idx].flags = DHCPS_ADDRESS_OFFERRED; + dhcps->leasearr[idx].proposed_leasetime = client_lease_time; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("add_client_entry: Adding Client Entry at Index = %"U32_F"\n", idx)); +} + +LWIP_STATIC int find_free_slot(struct dhcps *dhcps) +{ + int i; + for (i = 0; i < dhcps->lease_num; i++) { + if ((dhcps->leasearr[i].flags == DHCPS_ADDRESS_FREE) && + (htonl(dhcps->start_addr.addr + (u32_t)i) != ip_2_ip4(&dhcps->netif->ip_addr)->addr)) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("find_free_slot: Found Free Slot at Index = %"U32_F"\n", i)); + return i; + } + } + + return -1; +} + +LWIP_STATIC struct dyn_lease_addr *find_client_lease(struct dhcps *dhcps, struct dhcp_msg *client_msg) +{ + int i; + for (i = 0; i < dhcps->lease_num; i++) { + if (dhcps->leasearr[i].flags != DHCPS_ADDRESS_FREE) { + if (memcmp(dhcps->leasearr[i].cli_hwaddr, client_msg->chaddr, client_msg->hlen) == 0) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, + ("find_client_lease: Found Client Lease at Index = %"U32_F"\n", i)); + return &(dhcps->leasearr[i]); + } + } + } + + return NULL; +} + +LWIP_STATIC ip4_addr_t validate_discover(struct dhcps *dhcps, struct dhcp_msg *client_msg, + struct dyn_lease_addr **client_lease) +{ + ip4_addr_t client_ip; + int idx = -1; + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("validate_discover: Validating Discover Message\n")); + + client_ip.addr = 0; + if (*client_lease == NULL) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("validate_discover: Existing Client Lease not Found\n")); + if (dhcps_option_given(dhcps, DHCP_OPTION_IDX_REQUESTED_IP)) { + client_ip.addr = (u32_t)dhcps_get_option_value(dhcps, DHCP_OPTION_IDX_REQUESTED_IP); +#ifdef LWIP_DEV_DEBUG + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, + ("validate_discover function: Requested IP from client = %"U32_F"\n", client_ip.addr)); +#endif + + if ((client_ip.addr >= dhcps->start_addr.addr) && (client_ip.addr <= dhcps->end_addr.addr)) { + idx = (int)(client_ip.addr - dhcps->start_addr.addr); + if ((dhcps->leasearr[idx].flags != DHCPS_ADDRESS_FREE) || + (ntohl(client_ip.addr) == ip_2_ip4(&dhcps->netif->ip_addr)->addr)) { + /* Requested IP is not available */ +#ifdef LWIP_DEV_DEBUG + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, + ("validate_discover function: Requested IP from client = %"U32_F" Not available \n", client_ip.addr)); +#endif + idx = -1; + } + } + } + + if (idx == -1) { + idx = find_free_slot(dhcps); + if (idx == -1) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, + ("validate_discover function: No Free Slot available for Storing addresses\n")); + client_ip.addr = 0; + return client_ip; + } + client_ip.addr = dhcps->start_addr.addr + (u32_t)idx; +#ifdef LWIP_DEV_DEBUG + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, + ("validate_discover function: New IP = %"U32_F" is being assigned\n", client_ip.addr)); +#endif + } + + add_client_entry(dhcps, (unsigned int)idx, client_msg); + (*client_lease) = &(dhcps->leasearr[idx]); + } else { + client_ip.addr = (*client_lease)->cli_addr.addr; +#ifdef LWIP_DEV_DEBUG + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, + ("validate_discover: Existing Client Lease Found. Existing IP =%"U32_F"\n", client_ip.addr)); +#endif + + if ((dhcps_option_given(dhcps, DHCP_OPTION_IDX_LEASE_TIME)) +#if (~0 != LWIP_DHCPS_LEASE_TIME) + && (dhcps_get_option_value(dhcps, DHCP_OPTION_IDX_LEASE_TIME) < LWIP_DHCPS_LEASE_TIME) +#endif + ) { + /* Assign the newly requested time or else use the existing lease time as-is */ + (*client_lease)->proposed_leasetime = (u32_t)dhcps_get_option_value(dhcps, DHCP_OPTION_IDX_LEASE_TIME); + } + } + + return client_ip; +} + +void dhcp_common_option(struct dhcp_msg *msg_out, u8_t option_type, u8_t option_len, u16_t *options_out_len) +{ + *options_out_len = dhcp_option(*options_out_len, msg_out->options, option_type, option_len); +} + +void dhcp_common_option_byte(struct dhcp_msg *msg_out, u8_t value, u16_t *options_out_len) +{ + *options_out_len = dhcp_option_byte(*options_out_len, msg_out->options, value); +} + +void dhcp_common_option_long(struct dhcp_msg *msg_out, u32_t value, u16_t *options_out_len) +{ + *options_out_len = dhcp_option_long(*options_out_len, msg_out->options, value); +} + +void dhcp_common_option_trailer(struct dhcp_msg *msg_out, u16_t options_out_len, struct pbuf *p_out) +{ + dhcp_option_trailer(options_out_len, msg_out->options, p_out); +} + +LWIP_STATIC void handle_discover(struct netif *netif, struct dhcps *dhcps, + struct dhcp_msg *client_msg, struct dyn_lease_addr *client_lease) +{ +#if !LWIP_DHCPS_DISCOVER_BROADCAST + ip_addr_t client_ipaddr; +#endif + + ip4_addr_t client_ip; + ip_addr_t dst_addr; + struct pbuf *out_msg = NULL; + struct dhcp_msg *srvr_msg = NULL; + u16_t options_len = 0; +#if !LWIP_DHCPS_DISCOVER_BROADCAST +#if ETHARP_SUPPORT_STATIC_ENTRIES + struct eth_addr ethaddr; +#endif +#endif + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("handle_discover: Processing Discover Message\n")); + + client_ip = validate_discover(dhcps, client_msg, &client_lease); + if (client_ip.addr == 0) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, + ("handle_discover: Returning as unable to get a proper address for client\n")); + return; + } + + out_msg = dhcps_create_base_msg(client_msg); + if (out_msg == NULL) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, + ("handle_discover function: Memory allocation for base message failed\n")); + return; + } + + srvr_msg = (struct dhcp_msg *)out_msg->payload; + // no need check msg pointer from payload here + srvr_msg->yiaddr.addr = htonl(client_ip.addr); + + dhcp_common_option(srvr_msg, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN, &options_len); + dhcp_common_option_byte(srvr_msg, DHCP_OFFER, &options_len); + + /* hilink need this router option */ + dhcp_common_option(srvr_msg, DHCP_OPTION_ROUTER, DHCP_OPTION_ROUTER_SIZE, &options_len); + dhcp_common_option_long(srvr_msg, ntohl(ip_2_ip4(&netif->ip_addr)->addr), &options_len); + + /* netif already holds the Server ID in network order. so, no need to convert it again */ + dhcp_common_option(srvr_msg, DHCP_OPTION_SERVER_ID, DHCP_OPTION_SERVER_ID_LEN, &options_len); + dhcp_common_option_long(srvr_msg, ntohl(ip_2_ip4(&netif->ip_addr)->addr), &options_len); + + dhcp_common_option(srvr_msg, DHCP_OPTION_LEASE_TIME, DHCP_OPTION_LEASE_TIME_SIZE, &options_len); + dhcp_common_option_long(srvr_msg, client_lease->proposed_leasetime, &options_len); + + dhcp_common_option(srvr_msg, DHCP_OPTION_T1, DHCP_OPTION_T1_LEN, &options_len); + dhcp_common_option_long(srvr_msg, (client_lease->proposed_leasetime / 2), &options_len); + + dhcp_common_option(srvr_msg, DHCP_OPTION_T2, DHCP_OPTION_T2_LEN, &options_len); + /* calculate safe periods for lease (proposed_leasetime * 0.875 -> 87.5%) */ + dhcp_common_option_long(srvr_msg, ((client_lease->proposed_leasetime * 7) / 8), &options_len); + + /* No need to convert netmask into network order as it is already stored in network order */ + dhcp_common_option(srvr_msg, DHCP_OPTION_SUBNET_MASK, DHCP_OPTION_SUBNET_MASK_SIZE, &options_len); + dhcp_common_option_long(srvr_msg, ntohl(ip4_addr_get_u32(ip_2_ip4(&netif->netmask))), &options_len); + + dhcp_common_option_trailer(srvr_msg, options_len, out_msg); + + if (client_msg->ciaddr.addr != 0) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("handle_discover: sendto(OFFER, ciaddr, DHCP_CLIENT_PORT)\n")); + ip_addr_set_ip4_u32_val(dst_addr, (u32_t)(client_msg->ciaddr.addr)); + (void)udp_sendto_if_src(dhcps->pcb, out_msg, &dst_addr, DHCP_CLIENT_PORT, netif, &(netif->ip_addr)); + } +#if !LWIP_DHCPS_DISCOVER_BROADCAST + else if (ntohs(client_msg->flags) & DHCP_BROADCAST_FLAG) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, + ("handle_discover: sendto(OFFER, IP_ADDR_BROADCAST, DHCP_CLIENT_PORT)\n")); + (void)udp_sendto_if_src(dhcps->pcb, out_msg, IP_ADDR_BROADCAST, DHCP_CLIENT_PORT, netif, &(netif->ip_addr)); + } else { + client_ip.addr = htonl(client_ip.addr); + +#if ETHARP_SUPPORT_STATIC_ENTRIES + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("handle_discover: Updating ARP Static Entry for unicast reply\n")); + if (memcpy_s(ethaddr.addr, ETHARP_HWADDR_LEN, client_msg->chaddr, client_msg->hlen) != EOK) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("memcpy_s failed\n")); + (void)pbuf_free(out_msg); + return; + } + if (etharp_add_static_entry(&client_ip, ðaddr) != ERR_OK) { + (void)pbuf_free(out_msg); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("handle_discover: Adding static entry to arp cache failed\n")); + return; + } +#endif + + /* Need to check and add an arp entry to make this pass through smoothly */ + ip_addr_copy_from_ip4(client_ipaddr, client_ip); + (void)udp_sendto_if_src(dhcps->pcb, out_msg, &client_ipaddr, DHCP_CLIENT_PORT, netif, &(netif->ip_addr)); +#if ETHARP_SUPPORT_STATIC_ENTRIES + /* We just added the entry above and checked for it's success too. so, the below function call cannot fail */ + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, + ("handle_discover: Removing ARP Static Entry added for unicast reply\n")); + (void)etharp_remove_static_entry(&client_ip); +#endif + } +#else + else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, + ("handle_discover: sendto(OFFER, IP_ADDR_BROADCAST, DHCP_CLIENT_PORT)\n")); + (void)udp_sendto_if_src(dhcps->pcb, out_msg, IP_ADDR_BROADCAST, DHCP_CLIENT_PORT, netif, &(netif->ip_addr)); + } +#endif + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("handle_discover: deleting()ing\n")); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("handle_discover: Sending Reply has been successful\n")); + + (void)pbuf_free(out_msg); + return; +} + +LWIP_STATIC ip4_addr_t validate_request_message(struct netif *netif, struct dhcp_msg *client_msg, + struct dyn_lease_addr *client_lease, ip4_addr_t serverid) +{ + struct dhcps *dhcps = netif_get_dhcps(netif); + ip4_addr_t requested_ip; + requested_ip.addr = 0; + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("validate_request_message: Processing Request Message\n")); + + if ((client_lease != NULL) && (client_lease->flags == DHCPS_ADDRESS_OFFERRED)) { + /* Now, we are in selecting state */ + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("validate_request_message: In Selecting State\n")); + + if ((serverid.addr == 0) || (client_msg->ciaddr.addr != 0) || + (!dhcps_option_given(dhcps, DHCP_OPTION_IDX_REQUESTED_IP))) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, + ("Server ID or ciaddr or requested ip option is not present\n")); + return requested_ip; + } + + if (serverid.addr != ip_2_ip4(&netif->ip_addr)->addr) { + /* This message is not meant for us. The client intends to talk to some other server */ + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, + ("validate_request_message: Server id doesn't match with ours. Message not for us\n")); + requested_ip.addr = 1; + return requested_ip; + } + + requested_ip.addr = (u32_t)dhcps_get_option_value(dhcps, DHCP_OPTION_IDX_REQUESTED_IP); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, + ("validate_request_message: In Init-Reboot, Renew or Rebinding State\n")); + + /* Now, we can be either in Init-reboot state or renew state or rebinding state */ + if (dhcps_option_given(dhcps, DHCP_OPTION_IDX_REQUESTED_IP)) { + /* Requested IP option is filled in. Indicates we are mostly in Init-Reboot State */ + if (client_lease == NULL) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, + ("validate_request_message: No Configuration found corresponding to request message\n")); + return requested_ip; + } + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, + ("validate_request_message: Requested IP Option is present. So, considering as Init-Reboot State\n")); + + if (client_msg->ciaddr.addr != 0) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, + ("validate_request_message: Error: ciaddr is filled in the Init-Reboot state. \n")); + return requested_ip; + } + + requested_ip.addr = (u32_t)dhcps_get_option_value(dhcps, DHCP_OPTION_IDX_REQUESTED_IP); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("validate_request_message: \ + Requested IP Option is not present. So, considering as Renewing or Rebinding State\n")); + + if (client_msg->ciaddr.addr == 0) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, + ("validate_request_message: Error: ciaddr is not filled in the Renewing or Rebinding state. \n")); + return requested_ip; + } + + requested_ip.addr = ntohl(client_msg->ciaddr.addr); + } + } + + /* requested_ip is in host order and DHCP Server IP is in network order, + so converting the former to network order for check */ + if (htonl(requested_ip.addr) == ip_2_ip4(&netif->ip_addr)->addr) { + /* This requested_ip is the dhcp server is using, it is invalid */ + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("validate_request_message: Requested IP addr is invalid\n")); + requested_ip.addr = 1; + } + + return requested_ip; +} + +LWIP_STATIC void handle_request(struct netif *netif, struct dhcps *dhcps, struct dhcp_msg *client_msg, + struct dyn_lease_addr *client_lease, ip4_addr_t serverid) +{ + ip4_addr_t requested_ip; + struct pbuf *out_msg = NULL; + struct dhcp_msg *srvr_msg = NULL; + u16_t options_len = 0; + ip_addr_t dst_addr; + ip_addr_t ip_send; +#if ETHARP_SUPPORT_STATIC_ENTRIES + struct eth_addr ethaddr; +#endif + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("handle_request: Processing Request Message\n")); + + requested_ip = validate_request_message(netif, client_msg, client_lease, serverid); + if (requested_ip.addr == 1) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, + ("handle_request: Validation of request message failed. Dropping the packet.\n")); + return; + } + + out_msg = dhcps_create_base_msg(client_msg); + if (out_msg == NULL) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("handle_request: Creating base message failed\n")); + return; + } + + srvr_msg = (struct dhcp_msg *)out_msg->payload; + dhcp_common_option(srvr_msg, DHCP_OPTION_SERVER_ID, DHCP_OPTION_SERVER_ID_LEN, &options_len); + dhcp_common_option_long(srvr_msg, ntohl(ip_2_ip4(&netif->ip_addr)->addr), &options_len); + + /* hilink need this router option */ + dhcp_common_option(srvr_msg, DHCP_OPTION_ROUTER, DHCP_OPTION_ROUTER_SIZE, &options_len); + dhcp_common_option_long(srvr_msg, ntohl(ip_2_ip4(&netif->ip_addr)->addr), &options_len); + + if ((client_lease != NULL) && (client_lease->cli_addr.addr == requested_ip.addr)) { + if (client_lease->proposed_leasetime != (u32_t)(~0)) { + if (client_lease->flags == DHCPS_ADDRESS_OFFERRED) { + client_lease->leasetime = sys_now() + (client_lease->proposed_leasetime * 1000); + } else { + client_lease->leasetime += (client_lease->proposed_leasetime * 1000); + } + } else { + client_lease->leasetime = client_lease->proposed_leasetime; + } + + client_lease->flags = DHCPS_ADDRESS_BOUND; + srvr_msg->yiaddr.addr = htonl(client_lease->cli_addr.addr); + + dhcp_common_option(srvr_msg, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN, &options_len); + dhcp_common_option_byte(srvr_msg, DHCP_ACK, &options_len); + + dhcp_common_option(srvr_msg, DHCP_OPTION_LEASE_TIME, DHCP_OPTION_LEASE_TIME_SIZE, &options_len); + dhcp_common_option_long(srvr_msg, client_lease->proposed_leasetime, &options_len); + + dhcp_common_option(srvr_msg, DHCP_OPTION_T1, DHCP_OPTION_T1_LEN, &options_len); + dhcp_common_option_long(srvr_msg, (client_lease->proposed_leasetime / 2), &options_len); + + dhcp_common_option(srvr_msg, DHCP_OPTION_T2, DHCP_OPTION_T2_LEN, &options_len); + /* calculate safe periods for lease (proposed_leasetime * 0.875 -> 87.5%) */ + dhcp_common_option_long(srvr_msg, ((client_lease->proposed_leasetime * 7) / 8), &options_len); + + dhcp_common_option(srvr_msg, DHCP_OPTION_SUBNET_MASK, DHCP_OPTION_SUBNET_MASK_SIZE, &options_len); + dhcp_common_option_long(srvr_msg, ntohl(ip_2_ip4(&netif->netmask)->addr), &options_len); + +#ifdef LWIP_DEV_DEBUG + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, + ("handle_request: Send ACK. to=%"U32_F" lease time=%"U32_F"\n", + requested_ip.addr, client_lease->proposed_leasetime)); +#endif + } else { + dhcp_common_option(srvr_msg, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN, &options_len); + dhcp_common_option_byte(srvr_msg, DHCP_NAK, &options_len); + + /* Just set this here, so that the NAK message is brcasted. + The correct flags has already been added in the response message during base message creation */ + client_msg->flags |= htons(DHCP_BROADCAST_FLAG); + client_msg->ciaddr.addr = 0; /* This is done so that NAK Gets brcasted */ +#ifdef LWIP_DEV_DEBUG + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, + ("handle_request: Send NAK. Requested from=%"U32_F"\n", requested_ip.addr)); +#endif + } + + requested_ip.addr = htonl(requested_ip.addr); + dhcp_common_option_trailer(srvr_msg, options_len, out_msg); + + if (client_msg->ciaddr.addr != 0) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("handle_request: sendto(ACK, ciaddr, DHCP_CLIENT_PORT)\n")); + ip_addr_set_ip4_u32_val(dst_addr, (u32_t)(client_msg->ciaddr.addr)); + (void)udp_sendto_if_src(dhcps->pcb, out_msg, &dst_addr, DHCP_CLIENT_PORT, netif, &(netif->ip_addr)); + } else if (ntohs(client_msg->flags) & DHCP_BROADCAST_FLAG) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("handle_request: sending reply using brdcast \n")); + (void)udp_sendto_if_src(dhcps->pcb, out_msg, IP_ADDR_BROADCAST, DHCP_CLIENT_PORT, netif, &(netif->ip_addr)); + } else { +#if ETHARP_SUPPORT_STATIC_ENTRIES + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("handle_request: Updating ARP Static Entry for unicast reply\n")); + if (memcpy_s(ethaddr.addr, ETHARP_HWADDR_LEN, client_msg->chaddr, client_msg->hlen) != EOK) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("handle_request: Copy chaddr failed\n")); + (void)pbuf_free(out_msg); + return; + } + if (ERR_OK != etharp_add_static_entry(&requested_ip, ðaddr)) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("handle_request: Adding static entry to arp cache failed\n")); + (void)pbuf_free(out_msg); + return; + } +#endif + /* Need to check and add an arp entry to make this pass through smoothly */ +#ifdef LWIP_DEV_DEBUG + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, + ("handle_request: sending reply using unicast Client IP =%"U32_F"\n", requested_ip.addr)); +#endif + ip_send.u_addr.ip4.addr = requested_ip.addr; + ip_send.type = IPADDR_TYPE_V4; + (void)udp_sendto_if_src(dhcps->pcb, out_msg, &ip_send, DHCP_CLIENT_PORT, netif, &(netif->ip_addr)); + +#if ETHARP_SUPPORT_STATIC_ENTRIES + /* We just added the entry above and checked for it's success too. so, the below function call cannot fail */ + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, + ("handle_request: Removing ARP Static Entry added for unicast reply\n")); + (void)etharp_remove_static_entry(&requested_ip); +#endif + } + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("handle_request: deleting\n")); + + (void)pbuf_free(out_msg); + return; +} + +LWIP_STATIC void handle_decline(struct netif *netif, struct dhcps *dhcps, struct dhcp_msg *client_msg, + struct dyn_lease_addr *client_lease) +{ + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("handle_decline: Processing Decline Message\n")); + + if ((client_lease != NULL) && (dhcps_option_given(dhcps, DHCP_OPTION_IDX_REQUESTED_IP)) && + (client_msg->ciaddr.addr == 0)) { + if (client_lease->cli_addr.addr == (u32_t)dhcps_get_option_value(dhcps, DHCP_OPTION_IDX_REQUESTED_IP)) { +#ifdef LWIP_DEV_DEBUG + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, + ("handle_decline: Marking Client Entry as declined. Client IP =%"U32_F"\n", + client_lease->cli_addr.addr)); +#endif + (void)memset_s(client_lease->cli_hwaddr, sizeof(client_lease->cli_hwaddr), 0, DHCP_CHADDR_LEN); + client_lease->proposed_leasetime = 0; + client_lease->leasetime = sys_now() + (LWIP_DHCPS_DECLINE_TIME * 1000); + client_lease->flags = DHCPS_ADDRESS_DECLINED; + } + } +} + +LWIP_STATIC void handle_inform(struct netif *netif, struct dhcps *dhcps, struct dhcp_msg *client_msg) +{ + struct pbuf *out_msg = NULL; + struct dhcp_msg *srvr_msg = NULL; + u16_t options_len = 0; + ip_addr_t dst_addr; + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("handle_inform: Processing Inform Message\n")); + + if (client_msg->ciaddr.addr == 0) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("handle_inform: ciaddr is empty. Can't send back a response\n")); + return; + } + + out_msg = dhcps_create_base_msg(client_msg); + if (out_msg == NULL) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("handle_inform: Creating base message failed\n")); + return; + } + + srvr_msg = (struct dhcp_msg *)out_msg->payload; + dhcp_common_option(srvr_msg, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN, &options_len); + dhcp_common_option_byte(srvr_msg, DHCP_ACK, &options_len); + + dhcp_common_option_trailer(srvr_msg, options_len, out_msg); + +#ifdef LWIP_DEV_DEBUG + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, + ("handle_inform: Send ACK to Client. Client is=%"U32_F"\n", client_msg->ciaddr.addr)); +#endif + ip_addr_set_ip4_u32_val(dst_addr, client_msg->ciaddr.addr); + (void)udp_sendto_if_src(dhcps->pcb, out_msg, &dst_addr, DHCP_CLIENT_PORT, netif, &(netif->ip_addr)); + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("handle_inform: deleting pbuf\n")); + (void)pbuf_free(out_msg); + + return; +} + +LWIP_STATIC void handle_client_messages(struct netif *netif, struct dhcps *dhcps, + struct dhcp_msg *client_msg, ip4_addr_t serverid, u8_t msg_type) +{ + struct dyn_lease_addr *client_lease = NULL; + + client_lease = find_client_lease(dhcps, client_msg); + switch (msg_type) { + case DHCP_DISCOVER: + handle_discover(netif, dhcps, client_msg, client_lease); + break; + case DHCP_REQUEST: + handle_request(netif, dhcps, client_msg, client_lease, serverid); + break; + case DHCP_DECLINE: + handle_decline(netif, dhcps, client_msg, client_lease); + break; + case DHCP_RELEASE: + if ((client_lease != NULL) && (client_lease->cli_addr.addr == ntohl(client_msg->ciaddr.addr))) { +#ifdef LWIP_DEV_DEBUG + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP Release: Client IPAdd =%"U32_F"\n", client_msg->ciaddr.addr)); +#endif + (void)memset_s(client_lease, sizeof(struct dyn_lease_addr), 0, sizeof(struct dyn_lease_addr)); + client_lease->flags = DHCPS_ADDRESS_FREE; + } + break; + case DHCP_INFORM: + handle_inform(netif, dhcps, client_msg); + break; + default: + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, + ("DHCP Server. Invalid message type received %d\n", msg_type)); + } +} + +err_t dhcps_parse_options(struct pbuf *p, struct dhcps *dhcps) +{ + return dhcp_parse_reply(p, &dhcps->dhcp); +} + +LWIP_STATIC void dhcps_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *ip_addr, u16_t port) +{ + struct netif *netif = (struct netif *)arg; + struct dhcps *dhcps = netif_get_dhcps(netif); + struct dhcp_msg *client_msg = (struct dhcp_msg *)p->payload; + u8_t msg_type; + ip4_addr_t serverid; + ip4_addr_t addr; + + if (client_msg == NULL) { + return; + } + addr.addr = ip_addr->u_addr.ip4.addr; + serverid.addr = 0; +#ifdef LWIP_DEV_DEBUG + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, + ("dhcps_recv(pbuf = %p) from DHCP Client %"U16_F".%"U16_F".%"U16_F".%"U16_F" port %"U16_F"\n", (void*)p, + ip4_addr1_16(&addr), ip4_addr2_16(&addr), ip4_addr3_16(&addr), ip4_addr4_16(&addr), port)); +#endif + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("pbuf->len = %"U16_F"\n", p->len)); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("pbuf->tot_len = %"U16_F"\n", p->tot_len)); + /* prevent warnings about unused arguments */ + LWIP_UNUSED_ARG(pcb); + LWIP_UNUSED_ARG(addr); + LWIP_UNUSED_ARG(port); + + dhcps_clear_all_options(dhcps); + + /* Check and remove old entries on each call to dhcp_recv. This way, we don't need to maintain timers */ + remove_stale_entries(dhcps); + + if (p->len < DHCP_OPTIONS_OFS) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, + ("DHCP client message or pbuf too short. pbuf len =%"U16_F" DHCP MIN Reply Len = %"U32_F"\n", + p->len, DHCP_MIN_REPLY_LEN)); + goto free_pbuf_and_return; + } + + if (client_msg->op != DHCP_BOOTREQUEST) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, + ("Not a DHCP reply message, Type %"U16_F"\n", (u16_t)client_msg->op)); + goto free_pbuf_and_return; + } + + if (client_msg->cookie != PP_HTONL(DHCP_MAGIC_COOKIE)) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, + ("DHCP Server. Cookie Value is incorrect. %"U32_F"\n", (u32_t)client_msg->cookie)); + goto free_pbuf_and_return; + } + + if (client_msg->hlen != ETHARP_HWADDR_LEN) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, + ("DHCP Server. Invalid hardware address length %"U16_F"\n", (u16_t)client_msg->hlen)); + goto free_pbuf_and_return; + } + + if (dhcps_parse_options(p, dhcps) != ERR_OK) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, + ("Parsing of Options failed in DHCP Client Message\n")); + goto free_pbuf_and_return; + } + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("Searching DHCP_OPTION_MESSAGE_TYPE\n")); + /* obtain pointer to DHCP message type */ + if (!dhcps_option_given(dhcps, DHCP_OPTION_IDX_MSG_TYPE)) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, + ("DHCP_OPTION_MESSAGE_TYPE option not found\n")); + goto free_pbuf_and_return; + } + + /* read DHCP message type */ + msg_type = (u8_t)dhcps_get_option_value(dhcps, DHCP_OPTION_IDX_MSG_TYPE); + + if (dhcps_option_given(dhcps, DHCP_OPTION_IDX_SERVER_ID)) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, + ("DHCP_OPTION_SERVER_ID option found\n")); + /* Parse options would have changed it to host order. But, we have our IP stored in netif in network order */ + serverid.addr = htonl((u32_t)dhcps_get_option_value(dhcps, DHCP_OPTION_IDX_SERVER_ID)); + } + + if ((serverid.addr != 0) && ((msg_type == DHCP_DISCOVER) || (msg_type == DHCP_INFORM))) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, + ("Serverid present in DHCP_DISCOVER and DHCP_INFORM messages\n")); + goto free_pbuf_and_return; + } + + if ((!ip4_addr_cmp(&serverid, ip_2_ip4(&netif->ip_addr))) && + ((msg_type == DHCP_DECLINE) || (msg_type == DHCP_RELEASE))) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, + ("Serverid not present in DHCP_RELEASE and DHCP_DECLINE messages\n")); + goto free_pbuf_and_return; + } + + handle_client_messages(netif, dhcps, client_msg, serverid, msg_type); + +free_pbuf_and_return: + (void)pbuf_free(p); +} + +err_t dhcps_start(struct netif *netif, const char *start_ip, u16_t ip_num) +{ + struct dhcps *dhcps = NULL; + ip4_addr_t address_in_hton; + int err; + + LWIP_ERROR("netif != NULL", (netif != NULL), return ERR_ARG); + dhcps = netif_get_dhcps(netif); + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("dhcps_start(netif=%p) %s\n", (void *)netif, netif_get_name(netif))); + + if (netif->mtu < DHCP_MAX_MSG_LEN_MIN_REQUIRED) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, + ("MTU =%"U16_F",DHCP Msg Len Required =%"U32_F"\n", netif->mtu, DHCP_MAX_MSG_LEN_MIN_REQUIRED)); + return ERR_MEM; + } + + if (dhcps != NULL) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcps_start(): DHCP Server is already started\n")); + return ERR_MEM; + } + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcps_start(): starting new DHCP Server\n")); + dhcps = (struct dhcps *)mem_malloc(sizeof(struct dhcps)); + if (dhcps == NULL) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcps_start(): could not allocate dhcp\n")); + return ERR_MEM; + } + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcps_start(): allocated dhcp")); + + (void)memset_s(dhcps, sizeof(struct dhcps), 0, sizeof(struct dhcps)); + + dhcps->pcb = udp_new(); + if (dhcps->pcb == NULL) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): could not allocate pcb\n")); + mem_free((void *)dhcps); + return ERR_MEM; + } + +#if LWIP_SO_BINDTODEVICE + /* bind dhcp udp_pcb to specific netif, this could make dhcp server start on multiple netif */ + dhcps->pcb->ifindex = netif->ifindex; +#endif + if ((start_ip == NULL) || (ip_num == 0)) { + /* use default ip lease configuration. */ + dhcps->start_addr.addr = ntohl(ip_2_ip4(&netif->ip_addr)->addr & ip_2_ip4(&netif->netmask)->addr) + 1; + dhcps->end_addr.addr = ntohl(ip_2_ip4(&netif->ip_addr)->addr | (~ip_2_ip4(&netif->netmask)->addr)) - 1; + dhcps->lease_num = (u8_t)(dhcps->end_addr.addr - dhcps->start_addr.addr + 1); + if (dhcps->lease_num > LWIP_DHCPS_MAX_LEASE) { + dhcps->lease_num = LWIP_DHCPS_MAX_LEASE; + dhcps->end_addr.addr = dhcps->start_addr.addr + LWIP_DHCPS_MAX_LEASE - 1; + } + } else { + dhcps->start_addr.addr = ntohl(ipaddr_addr(start_ip)); + dhcps->end_addr.addr = (u32_t)(dhcps->start_addr.addr + + (u32_t)(LWIP_MIN(ip_num - 1, LWIP_DHCPS_MAX_LEASE - 1))); + + ip4_addr_set_hton(&address_in_hton, &dhcps->start_addr); + + if (!ip4_addr_netcmp((&address_in_hton), ip_2_ip4(&netif->ip_addr), ip_2_ip4(&netif->netmask)) || + ip4_addr_isbroadcast((&address_in_hton), netif)) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): %s in not a valid ip lease\n", start_ip)); + udp_remove(dhcps->pcb); + mem_free((void *)dhcps); + return ERR_ARG; + } + + ip4_addr_set_hton(&address_in_hton, &dhcps->end_addr); + + if (!ip4_addr_netcmp((&address_in_hton), ip_2_ip4(&netif->ip_addr), ip_2_ip4(&netif->netmask)) || + ip4_addr_isbroadcast((&address_in_hton), netif)) { + dhcps->end_addr.addr = ntohl(ip_2_ip4(&netif->ip_addr)->addr | (~ip_2_ip4(&netif->netmask)->addr)) - 1; + } + dhcps->lease_num = (u8_t)(dhcps->end_addr.addr - dhcps->start_addr.addr + 1); + } + + dhcps->netif = netif; + dhcps->pcb->so_options |= SOF_BROADCAST; + err = udp_bind(dhcps->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT); + if (err != ERR_OK) { + udp_remove(dhcps->pcb); + mem_free((void *)dhcps); + return ERR_MEM; + } + + err = udp_connect(dhcps->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT); + if (err != ERR_OK) { + udp_remove(dhcps->pcb); + mem_free((void *)dhcps); + return ERR_MEM; + } + udp_recv(dhcps->pcb, dhcps_recv, netif); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcps_start(): starting DHCPS Successfully\n")); +#ifdef LWIP_DEV_DEBUG + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, + ("dhcps_start(): DHCPS Conf:: netif addr = %"U32_F" dhcps start addr%"U32_F" dhcp end addr%"U32_F"\n", + ip_2_ip4(&netif->ip_addr)->addr, dhcps->start_addr.addr, dhcps->end_addr.addr)); +#endif + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, + ("dhcps_start(): DHCPS Lease Conf:: Lease Time = %"U32_F" Offer Time = %"U32_F"\n", + LWIP_DHCPS_LEASE_TIME, LWIP_DHCPS_OFFER_TIME)); + netif_set_dhcps(netif, dhcps); + return ERR_OK; +} + +void dhcps_stop(struct netif *netif) +{ + LWIP_ERROR("dhcps_stop: netif != NULL", (netif != NULL), return); + struct dhcps *dhcps = netif_get_dhcps(netif); + if (dhcps != NULL) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcps_stop(): Stopping DHCP Server\n")); + if (dhcps->pcb != NULL) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcps_stop(): Removing UDP PCB\n")); + udp_remove(dhcps->pcb); + dhcps->pcb = NULL; + } + + mem_free(dhcps); + netif_set_dhcps(netif, NULL); + } +} + +#endif + diff --git a/src/kernel_liteos_a/net/lwip-2.1/enhancement/src/fixme.c b/src/kernel_liteos_a/net/lwip-2.1/enhancement/src/fixme.c new file mode 100644 index 00000000..f52b73ef --- /dev/null +++ b/src/kernel_liteos_a/net/lwip-2.1/enhancement/src/fixme.c @@ -0,0 +1,497 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "lwip/fixme.h" + +#include +#include +#include +#include +#include + +#define NETIFAPI_VAR_REF(name) API_VAR_REF(name) +#define NETIFAPI_VAR_DECLARE(name) API_VAR_DECLARE(struct netifapi_msg, name) +#define NETIFAPI_VAR_ALLOC(name) API_VAR_ALLOC(struct netifapi_msg, MEMP_NETIFAPI_MSG, name, ERR_MEM) +#define NETIFAPI_VAR_FREE(name) API_VAR_FREE(MEMP_NETIFAPI_MSG, name) + +#if LWIP_DHCP + +#include + +/* + * Close DHCP and set static network. + * @param netif a pre-allocated netif structure + * @return ERR_OK, or ERR_VAL if failed. + */ +err_t netif_dhcp_off(struct netif *netif) +{ + ip_addr_t old_ipaddr; + ip_addr_t old_netmask; + ip_addr_t old_gateway; + + if (netif == NULL) { + return ERR_VAL; + } + old_ipaddr = netif->ip_addr; + old_netmask = netif->netmask; + old_gateway = netif->gw; + + if (netif_dhcp_data(netif)) { + (void)dhcp_release(netif); + (void)dhcp_stop(netif); + (void)dhcp_cleanup(netif); + LWIP_DEBUGF(NETIF_DEBUG, ("DHCP is close;set static IP\n")); + } + + ip_addr_set_val(&netif->ip_addr, &old_ipaddr); + ip_addr_set_val(&netif->netmask, &old_netmask); + ip_addr_set_val(&netif->gw, &old_gateway); + (void)netif_set_up(netif); + + return ERR_OK; +} + +err_t dhcp_is_bound(struct netif *netif) +{ + struct dhcp *dhcp = NULL; + + LWIP_ERROR("netif != NULL", (netif != NULL), return ERR_ARG); + + dhcp = netif_dhcp_data(netif); + LWIP_ERROR("netif->dhcp != NULL", (dhcp != NULL), return ERR_ARG); + + if (dhcp->state == DHCP_STATE_BOUND) { + return ERR_OK; + } else { + return ERR_INPROGRESS; + } +} + +#endif /* LWIP_DHCP */ + +#if LWIP_DHCPS + +#include "lwip/dhcps.h" + +static err_t netifapi_do_dhcps_start(struct tcpip_api_call_data *m) +{ + /* cast through void* to silence alignment warnings. + * We know it works because the structs have been instantiated as struct netifapi_msg */ + err_t ret; + struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m; + ret = dhcps_start(msg->netif, msg->msg.dhcp_start_params.start_ip, msg->msg.dhcp_start_params.ip_num); + return ret; +} + +err_t netifapi_dhcps_start(struct netif *netif, char *start_ip, u16_t ip_num) +{ + err_t err; + NETIFAPI_VAR_DECLARE(msg); + + LWIP_ERROR("netifapi_dhcps_start : invalid arguments", (netif != NULL), return ERR_VAL); + NETIFAPI_VAR_ALLOC(msg); + + NETIFAPI_VAR_REF(msg).netif = netif; + NETIFAPI_VAR_REF(msg).msg.dhcp_start_params.start_ip = start_ip; + NETIFAPI_VAR_REF(msg).msg.dhcp_start_params.ip_num = ip_num; + + err = tcpip_api_call(netifapi_do_dhcps_start, &API_VAR_REF(msg).call); + + NETIFAPI_VAR_FREE(msg); + return err; +} + +err_t netifapi_dhcps_stop(struct netif *netif) +{ + LWIP_ERROR("netifapi_dhcps_stop : invalid arguments", (netif != NULL), return ERR_VAL); + + return netifapi_netif_common(netif, dhcps_stop, NULL); +} + +#endif /* LWIP_DHCPS */ + +/* + * This function is for making sure that accept() should not block indefinetely + * when removing IPv6 address used for accept() by using API[netifapi_netif_rmv_ip6_address]. + */ +static void tcp_unlock_accept(ip6_addr_t *ipaddr) +{ + (void)ipaddr; +} + +static void netif_ip6_addr_setinvalid(struct netif *netif, const ip6_addr_t *addr6) +{ + s8_t idx; + LWIP_ERROR("netif_ip6_addr_set : invalid arguments", (netif != NULL), return); + LWIP_ERROR("netif_ip6_addr_set : invalid arguments", (addr6 != NULL), return); + + idx = netif_get_ip6_addr_match(netif, addr6); + if (idx < 0) { + return; + } + + netif_ip6_addr_set_state(netif, idx, IP6_ADDR_INVALID); + return; +} + +err_t netif_do_rmv_ipv6_addr(struct netif *netif, void *arguments) +{ + ip_addr_t *ipaddr = (ip_addr_t *)arguments; + + if (IP_IS_V6(ipaddr)) { +#if LWIP_TCP + tcp_unlock_accept(ip_2_ip6(ipaddr)); +#endif + netif_ip6_addr_setinvalid(netif, ip_2_ip6(ipaddr)); + } + return ERR_OK; +} + +static err_t netif_do_rmv_ip6_address(struct tcpip_api_call_data *m) +{ + /* cast through void* to silence alignment warnings. + * We know it works because the structs have been instantiated as struct netifapi_msg */ + struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m; + + return netif_do_rmv_ipv6_addr(msg->netif, (void *)msg->msg.add.ipaddr); +} + +void netifapi_netif_rmv_ip6_address(struct netif *netif, ip_addr_t *ipaddr) +{ + err_t err; + if (netif == NULL) { + return; + } + NETIFAPI_VAR_DECLARE(msg); + NETIFAPI_VAR_ALLOC(msg); + + NETIFAPI_VAR_REF(msg).netif = netif; + NETIFAPI_VAR_REF(msg).msg.add.ipaddr = (void *)ipaddr; + + err = tcpip_api_call(netif_do_rmv_ip6_address, &API_VAR_REF(msg).call); + + NETIFAPI_VAR_FREE(msg); + (void)err; +} + +#ifdef LOSCFG_NET_CONTAINER +static struct netif *netif_find_by_name(const char *name, struct net_group *group) +#else +static struct netif *netif_find_by_name(const char *name) +#endif +{ + struct netif *netif = NULL; + + LWIP_ASSERT_CORE_LOCKED(); + + if (name == NULL) { + return NULL; + } + +#ifdef LOSCFG_NET_CONTAINER + NETIF_FOREACH(netif, group) { +#else + NETIF_FOREACH(netif) { +#endif + if (strcmp("lo", name) == 0 && (netif->name[0] == 'l' && netif->name[1] == 'o')) { + LWIP_DEBUGF(NETIF_DEBUG, ("netif_find_by_name: found lo\n")); + return netif; + } + + if (strcmp(netif->full_name, name) == 0) { + LWIP_DEBUGF(NETIF_DEBUG, ("netif_find_by_name: found %s\n", name)); + return netif; + } + } + + LWIP_DEBUGF(NETIF_DEBUG, ("netif_find_by_name: didn't find %s\n", name)); + return NULL; +} + +static err_t netifapi_do_find_by_name(struct tcpip_api_call_data *m) +{ + /* cast through void* to silence alignment warnings. + * We know it works because the structs have been instantiated as struct netifapi_msg */ + struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m; + +#ifdef LOSCFG_NET_CONTAINER + struct net_group *group = get_curr_process_net_group(); + msg->netif = netif_find_by_name(msg->msg.ifs.name, group); +#else + msg->netif = netif_find_by_name(msg->msg.ifs.name); +#endif + return ERR_OK; +} + +struct netif *netifapi_netif_find_by_name(const char *name) +{ + struct netif *netif = NULL; + NETIFAPI_VAR_DECLARE(msg); + NETIFAPI_VAR_ALLOC(msg); + + NETIFAPI_VAR_REF(msg).netif = NULL; +#if LWIP_MPU_COMPATIBLE + if (strncpy_s(NETIFAPI_VAR_REF(msg).msg.ifs.name, NETIF_NAMESIZE, name, NETIF_NAMESIZE - 1)) { + NETIFAPI_VAR_FREE(msg); + return netif; + } + NETIFAPI_VAR_REF(msg).msg.ifs.name[NETIF_NAMESIZE - 1] = '\0'; +#else + NETIFAPI_VAR_REF(msg).msg.ifs.name = (char *)name; +#endif /* LWIP_MPU_COMPATIBLE */ + + (void)tcpip_api_call(netifapi_do_find_by_name, &API_VAR_REF(msg).call); + + netif = msg.netif; + NETIFAPI_VAR_FREE(msg); + return netif; +} + +#define NETIF_MTU_MIN 1280 +#ifndef IP_FRAG_MIN_MTU +#define IP_FRAG_MIN_MTU 68 +#endif + +err_t netif_set_mtu(struct netif *netif, u16_t netif_mtu) +{ + /* + * As per RFC 791, "Every internet module must be able to forward a datagram of 68 + * octets without further fragmentation. This is because an internet header + * may be up to 60 octets, and the minimum fragment is 8 octets." + */ + LWIP_ERROR("netif_set_mtu: invalid arguments", (netif != NULL), return ERR_VAL); + +#if LWIP_IPV6 + LWIP_ERROR("netif_set_mtu: invalid arguments", (netif_mtu >= NETIF_MTU_MIN) && (netif_mtu <= IP_FRAG_MAX_MTU), + return ERR_ARG); +#else + LWIP_ERROR("netif_set_mtu: invalid arguments", (netif_mtu >= IP_FRAG_MIN_MTU) && (netif_mtu <= IP_FRAG_MAX_MTU), + return ERR_ARG); +#endif + + netif->mtu = netif_mtu; +#if LWIP_IPV6 && LWIP_ND6_ALLOW_RA_UPDATES + netif->mtu6 = netif_mtu; +#endif /* LWIP_IPV6 && LWIP_ND6_ALLOW_RA_UPDATES */ + + LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif: MTU of interface %s is changed to %d\n", + netif_get_name(netif), netif->mtu)); + return ERR_OK; +} + +err_t netif_set_hwaddr(struct netif *netif, const unsigned char *hw_addr, int hw_len) +{ + LWIP_ERROR("netif_set_hwaddr : invalid arguments", (netif != NULL), return ERR_VAL); + + LWIP_ERROR("netif_set_hwaddr : invalid arguments", (hw_addr != NULL), return ERR_VAL); + + LWIP_ERROR("netif_set_hwaddr: invalid arguments", + ((unsigned int)hw_len == NETIF_MAX_HWADDR_LEN), return ERR_VAL); + + if (netif->drv_set_hwaddr == NULL) { + return ERR_IF; // ERR_OPNOTSUPP; + } + + if (netif->drv_set_hwaddr(netif, (u8_t *)hw_addr, hw_len) != ERR_OK) { + return ERR_VAL; + } + + if (memcpy_s(netif->hwaddr, NETIF_MAX_HWADDR_LEN, hw_addr, hw_len) != EOK) { + LWIP_DEBUGF(NETIF_DEBUG, ("netif_set_hwaddr: memcpy_s error\n")); + return ERR_VAL; + } + + LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("netif: HW address of interface %s set to %02X:%02X:%02X:%02X:%02X:%02X\n", + netif_get_name(netif), + netif->hwaddr[0], netif->hwaddr[1], netif->hwaddr[2], + netif->hwaddr[3], netif->hwaddr[4], netif->hwaddr[5])); + + return ERR_OK; +} + +err_t etharp_update_arp_entry(struct netif *netif, const ip4_addr_t *ipaddr, struct eth_addr *ethaddr, u8_t flags) +{ + (void)netif; + (void)ipaddr; + (void)ethaddr; + (void)flags; + return 0; +} + +err_t etharp_delete_arp_entry(struct netif *netif, ip4_addr_t *ipaddr) +{ + (void)netif; + (void)ipaddr; + return 0; +} + +err_t lwip_dns_setserver(u8_t numdns, ip_addr_t *dnsserver) +{ + (void)numdns; + (void)dnsserver; + return 0; +} + +err_t lwip_dns_getserver(u8_t numdns, ip_addr_t *dnsserver) +{ + (void)numdns; + (void)dnsserver; + return 0; +} + +#if PF_PKT_SUPPORT +struct raw_pcb *pkt_raw_pcbs; +#endif + +#if LWIP_RAW +struct raw_pcb *raw_pcbs; /* already defined in raw.c, but is static */ +#endif + +#if LWIP_ENABLE_IP_CONFLICT_SIGNAL +u32_t is_ip_conflict_signal = 0; +sys_sem_t ip_conflict_detect; +#endif + +u32_t is_dup_detect_initialized = 0; +sys_sem_t dup_addr_detect; + +#if LWIP_SNTP + +#include + +int lwip_sntp_start(int server_num, char **sntp_server, struct timeval *time) +{ + (void)server_num; + (void)sntp_server; + (void)time; + return 0; +} + +#endif + +const char *const tcp_state_str[] = { + "CLOSED", + "LISTEN", + "SYN_SENT", + "SYN_RCVD", + "ESTABLISHED", + "FIN_WAIT_1", + "FIN_WAIT_2", + "CLOSE_WAIT", + "CLOSING", + "LAST_ACK", + "TIME_WAIT" +}; + +volatile int tcpip_init_finish = 1; // needed by api_shell.c + +int ip6addr_aton(const char *cp, ip6_addr_t *addr) +{ + const int ipv6_blocks = 8; + u16_t current_block_index = 0; + u16_t current_block_value = 0; + u16_t addr16[ipv6_blocks]; + u16_t *a16 = (u16_t *)addr->addr; + int squash_pos = ipv6_blocks; + int i; + const char *s = cp; + const char *ss = cp - 1; + + for (; ; s++) { + if (current_block_index >= ipv6_blocks) { + return 0; // address too long + } + if (*s == 0) { + if (s - ss == 1) { + if (squash_pos != current_block_index) { + return 0; // empty address or address ends with a single ':' + } // else address ends with one valid "::" + } else { + addr16[current_block_index++] = current_block_value; + } + break; + } else if (*s == ':') { + if (s - ss == 1) { + if (s != cp || s[1] != ':') { + return 0; // address begins with a single ':' or contains ":::" + } // else address begins with one valid "::" + } else { + addr16[current_block_index++] = current_block_value; + } + if (s[1] == ':') { + if (squash_pos != ipv6_blocks) { + return 0; // more than one "::" + } + squash_pos = current_block_index; + s++; + } + ss = s; // ss points to the recent ':' position + current_block_value = 0; + } else if (lwip_isxdigit(*s) && (s - ss) < 5) { // 4 hex-digits at most + current_block_value = (current_block_value << 4) + + ((u8_t)(*s) | ('a' - 'A')) - '0' - ('a' - '9' - 1) * (*s >= 'A'); +#if LWIP_IPV4 + } else if (*s == '.' && current_block_index < ipv6_blocks - 1) { + ip4_addr_t ip4; + int ret = ip4addr_aton(ss+1, &ip4); + if (!ret) { + return 0; + } + ip4.addr = lwip_ntohl(ip4.addr); + addr16[current_block_index++] = (u16_t)(ip4.addr >> 16); + addr16[current_block_index++] = (u16_t)(ip4.addr); + break; +#endif /* LWIP_IPV4 */ + } else { + return 0; // unexpected char or too many digits + } + } + + if (squash_pos == ipv6_blocks && current_block_index != ipv6_blocks) { + return 0; // address too short + } + if (squash_pos != ipv6_blocks && current_block_index == ipv6_blocks) { + return 0; // unexpected "::" in address + } + + for (i = 0; i < squash_pos; ++i) { + a16[i] = lwip_htons(addr16[i]); + } + for (; i < ipv6_blocks - current_block_index + squash_pos; ++i) { + a16[i] = 0; + } + for (; i < ipv6_blocks; ++i) { + a16[i] = lwip_htons(addr16[i - ipv6_blocks + current_block_index]); + } + + return 1; +} diff --git a/src/kernel_liteos_a/net/lwip-2.1/lwip_porting.gni b/src/kernel_liteos_a/net/lwip-2.1/lwip_porting.gni new file mode 100644 index 00000000..14422e24 --- /dev/null +++ b/src/kernel_liteos_a/net/lwip-2.1/lwip_porting.gni @@ -0,0 +1,40 @@ +# Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +LWIP_PORTING_DIR = get_path_info(".", "abspath") + +LWIP_PORTING_INCLUDE_DIRS = [ "$LWIP_PORTING_DIR/porting/include" ] + +LWIP_PORTING_FILES = [ + "$LWIP_PORTING_DIR/porting/src/driverif.c", + "$LWIP_PORTING_DIR/porting/src/sockets.c", + "$LWIP_PORTING_DIR/porting/src/sys_arch.c", + "$LWIP_PORTING_DIR/enhancement/src/api_shell.c", + "$LWIP_PORTING_DIR/enhancement/src/fixme.c", + "$LWIP_PORTING_DIR/enhancement/src/dhcps.c", +] diff --git a/src/kernel_liteos_a/net/lwip-2.1/porting/include/arch/cc.h b/src/kernel_liteos_a/net/lwip-2.1/porting/include/arch/cc.h new file mode 100644 index 00000000..9dd49830 --- /dev/null +++ b/src/kernel_liteos_a/net/lwip-2.1/porting/include/arch/cc.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LWIP_PORTING_CC_H_ +#define _LWIP_PORTING_CC_H_ + +#ifdef LITTLE_ENDIAN +#undef LITTLE_ENDIAN +#endif + +#ifdef BIG_ENDIAN +#undef BIG_ENDIAN +#endif + +#include +#include +#include + +#ifdef htons +#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS +#endif + +#define SOCKLEN_T_DEFINED +#define SA_FAMILY_T_DEFINED +#define IN_PORT_T_DEFINED + +#define LWIP_TIMEVAL_PRIVATE 0 +#define LWIP_ERRNO_STDINCLUDE +#define LWIP_SOCKET_STDINCLUDE + +/* Provide Thumb-2 routines for GCC to improve performance */ +#if defined(TOOLCHAIN_GCC) && defined(__thumb2__) +#define LWIP_CHKSUM thumb2_checksum +u16_t thumb2_checksum(void* pData, int length); +#else +#define LWIP_CHKSUM_ALGORITHM 4 +#endif + +#define LWIP_RAND rand +#define LWIP_PLATFORM_DIAG(vars) dprintf vars +#define LWIP_PLATFORM_ASSERT(x) do { \ + LWIP_PLATFORM_DIAG(("Assertion \"%s\" failed at line %d in %s\n", x, __LINE__, __FILE__)); \ + abort(); \ + } while (0) + +#endif /* _LWIP_PORTING_CC_H_ */ diff --git a/src/kernel_liteos_a/net/lwip-2.1/porting/include/arch/perf.h b/src/kernel_liteos_a/net/lwip-2.1/porting/include/arch/perf.h new file mode 100644 index 00000000..cc200260 --- /dev/null +++ b/src/kernel_liteos_a/net/lwip-2.1/porting/include/arch/perf.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LWIP_PORTING_PERF_H_ +#define _LWIP_PORTING_PERF_H_ + +#if LWIP_PERF + +#define PERF_START do {} while (0) /* something to do */ +#define PERF_STOP(x) do {} while (0) /* something to do */ + +#endif + +#endif /* _LWIP_PORTING_PERF_H_ */ diff --git a/src/kernel_liteos_a/net/lwip-2.1/porting/include/arch/sys_arch.h b/src/kernel_liteos_a/net/lwip-2.1/porting/include/arch/sys_arch.h new file mode 100644 index 00000000..19e76bee --- /dev/null +++ b/src/kernel_liteos_a/net/lwip-2.1/porting/include/arch/sys_arch.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LWIP_PORTING_SYS_ARCH_H_ +#define _LWIP_PORTING_SYS_ARCH_H_ + +#include +#include "los_mux.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * Mutex + */ +typedef LosMux sys_mutex_t; + + +/** + * Semaphore + */ +typedef uint32_t sys_sem_t; + + +/** + * MessageBox + */ +typedef uint32_t sys_mbox_t; + + +/** + * Protector + */ +typedef void *sys_prot_t; + + +/** + * Thread + */ +typedef uint32_t sys_thread_t; + + +#ifdef __cplusplus +} +#endif + +#endif /* _LWIP_PORTING_SYS_ARCH_H_ */ diff --git a/src/kernel_liteos_a/net/lwip-2.1/porting/include/lwip/dhcp.h b/src/kernel_liteos_a/net/lwip-2.1/porting/include/lwip/dhcp.h new file mode 100644 index 00000000..59b52e70 --- /dev/null +++ b/src/kernel_liteos_a/net/lwip-2.1/porting/include/lwip/dhcp.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LWIP_PORTING_DHCP_H_ +#define _LWIP_PORTING_DHCP_H_ + +#include + +#if LWIP_DHCPS +#define DHCP_OPTION_IDX_SERVER_ID DHCP_OPTION_IDX_SERVER_ID, \ + DHCP_OPTION_IDX_REQUESTED_IP +#endif +#include_next +#if LWIP_DHCPS +#undef DHCP_OPTION_IDX_SERVER_ID +#endif + +#include // For DHCP_STATE_BOUND, DHCP_DISCOVER etc. by `mac/common/mac_data.c' + +#ifdef __cplusplus +extern "C" { +#endif + +#if LWIP_DHCPS +#define LWIP_HOOK_DHCP_PARSE_OPTION(netif, dhcp, state, msg, msg_type, option, len, pbuf, offset) \ + LWIP_UNUSED_ARG(msg); \ + break; \ + case (DHCP_OPTION_REQUESTED_IP): \ + LWIP_ERROR("len == 4", len == 4, return ERR_VAL); \ + decode_idx = DHCP_OPTION_IDX_REQUESTED_IP; +#endif + +err_t dhcp_is_bound(struct netif *netif); + +#ifdef __cplusplus +} +#endif + +#endif /* _LWIP_PORTING_DHCP_H_ */ diff --git a/src/kernel_liteos_a/net/lwip-2.1/porting/include/lwip/inet.h b/src/kernel_liteos_a/net/lwip-2.1/porting/include/lwip/inet.h new file mode 100644 index 00000000..414b6bc6 --- /dev/null +++ b/src/kernel_liteos_a/net/lwip-2.1/porting/include/lwip/inet.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LWIP_PORTING_INET_H_ +#define _LWIP_PORTING_INET_H_ + +#include +#include +#include_next + +#ifdef __LWIP__ +#if LWIP_IPV4 +#define inet_addr_from_ip4addr(target_inaddr, source_ipaddr) \ + ((target_inaddr)->s_addr = ip4_addr_get_u32(source_ipaddr)) +#define inet_addr_to_ip4addr(target_ipaddr, source_inaddr) \ + (ip4_addr_set_u32(target_ipaddr, (source_inaddr)->s_addr)) +#endif /* LWIP_IPV4 */ +#if LWIP_IPV6 +#define inet6_addr_from_ip6addr(target_in6addr, source_ip6addr) \ + {(target_in6addr)->s6_addr32[0] = (source_ip6addr)->addr[0]; \ + (target_in6addr)->s6_addr32[1] = (source_ip6addr)->addr[1]; \ + (target_in6addr)->s6_addr32[2] = (source_ip6addr)->addr[2]; \ + (target_in6addr)->s6_addr32[3] = (source_ip6addr)->addr[3];} +#define inet6_addr_to_ip6addr(target_ip6addr, source_in6addr) \ + {(target_ip6addr)->addr[0] = (source_in6addr)->s6_addr32[0]; \ + (target_ip6addr)->addr[1] = (source_in6addr)->s6_addr32[1]; \ + (target_ip6addr)->addr[2] = (source_in6addr)->s6_addr32[2]; \ + (target_ip6addr)->addr[3] = (source_in6addr)->s6_addr32[3]; \ + ip6_addr_clear_zone(target_ip6addr);} +#endif /* LWIP_IPV6 */ +#endif /* __LWIP__ */ + +#endif /* _LWIP_PORTING_INET_H_ */ diff --git a/src/kernel_liteos_a/net/lwip-2.1/porting/include/lwip/ip.h b/src/kernel_liteos_a/net/lwip-2.1/porting/include/lwip/ip.h new file mode 100644 index 00000000..4a480c08 --- /dev/null +++ b/src/kernel_liteos_a/net/lwip-2.1/porting/include/lwip/ip.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LWIP_PORTING_IP_H_ +#define _LWIP_PORTING_IP_H_ + +#define IP_PCB_NETGROUP ;struct net_group *group + +#include_next + +#ifdef __cplusplus +extern "C" { +#endif +#ifdef __cplusplus +} +#endif + +#endif /* _LWIP_PORTING_IP_H_ */ diff --git a/src/kernel_liteos_a/net/lwip-2.1/porting/include/lwip/lwipopts.h b/src/kernel_liteos_a/net/lwip-2.1/porting/include/lwip/lwipopts.h new file mode 100644 index 00000000..b3a8d316 --- /dev/null +++ b/src/kernel_liteos_a/net/lwip-2.1/porting/include/lwip/lwipopts.h @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LWIP_PORTING_LWIPOPTS_H_ +#define _LWIP_PORTING_LWIPOPTS_H_ + + +// lwIP debug options, comment the ones you don't want +#if LWIP_DEBUG +#define ETHARP_DEBUG LWIP_DBG_ON +#define NETIF_DEBUG LWIP_DBG_ON +#define PBUF_DEBUG LWIP_DBG_ON +#define API_LIB_DEBUG LWIP_DBG_ON +#define API_MSG_DEBUG LWIP_DBG_ON +#define SOCKETS_DEBUG LWIP_DBG_ON +#define ICMP_DEBUG LWIP_DBG_ON +#define IGMP_DEBUG LWIP_DBG_ON +#define INET_DEBUG LWIP_DBG_ON +#define IP_DEBUG LWIP_DBG_ON +#define DRIVERIF_DEBUG LWIP_DBG_ON +#define IP_REASS_DEBUG LWIP_DBG_ON +#define RAW_DEBUG LWIP_DBG_ON +#define MEM_DEBUG LWIP_DBG_ON +#define MEMP_DEBUG LWIP_DBG_ON +#define SYS_DEBUG LWIP_DBG_ON +#define TIMERS_DEBUG LWIP_DBG_ON +#define TCP_DEBUG LWIP_DBG_ON +#define TCP_ERR_DEBUG LWIP_DBG_ON +#define TCP_INPUT_DEBUG LWIP_DBG_ON +#define TCP_FR_DEBUG LWIP_DBG_ON +#define TCP_RTO_DEBUG LWIP_DBG_ON +#define TCP_CWND_DEBUG LWIP_DBG_ON +#define TCP_WND_DEBUG LWIP_DBG_ON +#define TCP_OUTPUT_DEBUG LWIP_DBG_ON +#define TCP_RST_DEBUG LWIP_DBG_ON +#define TCP_QLEN_DEBUG LWIP_DBG_ON +#define TCP_SACK_DEBUG LWIP_DBG_ON +#define TCP_TLP_DEBUG LWIP_DBG_ON +#define UDP_DEBUG LWIP_DBG_ON +#define TCPIP_DEBUG LWIP_DBG_ON +#define SLIP_DEBUG LWIP_DBG_ON +#define DHCP_DEBUG LWIP_DBG_ON +#define AUTOIP_DEBUG LWIP_DBG_ON +#define DNS_DEBUG LWIP_DBG_ON +#define TFTP_DEBUG LWIP_DBG_ON +#define SYS_ARCH_DEBUG LWIP_DBG_ON +#define SNTP_DEBUG LWIP_DBG_ON +#define IP6_DEBUG LWIP_DBG_ON +#define DHCP6_DEBUG LWIP_DBG_ON +#define DRV_STS_DEBUG LWIP_DBG_ON +#endif + + +// Options only in new opt.h +#define LWIP_SOCKET_SELECT 0 +#define LWIP_SOCKET_POLL 1 + + +// Options in old opt.h that differs from new opt.h +#define MEM_ALIGNMENT __SIZEOF_POINTER__ +#define MEMP_NUM_NETDB 8 +#define IP_REASS_MAXAGE 3 +#define IP_SOF_BROADCAST 1 +#define IP_SOF_BROADCAST_RECV 1 +#define LWIP_MULTICAST_PING 1 +#define LWIP_RAW 1 +#define LWIP_DHCP_AUTOIP_COOP_TRIES 64 +#define TCP_LISTEN_BACKLOG 1 +#define TCP_DEFAULT_LISTEN_BACKLOG 16 + +#define LWIP_WND_SCALE 1 +#define TCP_RCV_SCALE 7 + +#define LWIP_NETIF_HOSTNAME 1 +#define LWIP_NETIF_TX_SINGLE_PBUF 1 +#define LWIP_NETCONN_FULLDUPLEX 1 // Caution +#define LWIP_COMPAT_SOCKETS 2 +#define LWIP_POSIX_SOCKETS_IO_NAMES 0 +#define LWIP_TCP_KEEPALIVE 1 +#define RECV_BUFSIZE_DEFAULT 65535 +#define SO_REUSE_RXTOALL 1 + +#define LWIP_CHECKSUM_ON_COPY 1 +#define LWIP_IPV6 1 +#define LWIP_IPV6_NUM_ADDRESSES 5 +#define LWIP_ND6_NUM_PREFIXES 10 +#define LWIP_IPV6_DHCP6 1 +#define LWIP_IPV6_DHCP6_STATEFUL 1 + + +// Options in old lwipopts.h +#define ARP_QUEUEING 1 +#define DEFAULT_ACCEPTMBOX_SIZE 32 +#define DEFAULT_RAW_RECVMBOX_SIZE 128 +#define DEFAULT_TCP_RECVMBOX_SIZE 128 +#define DEFAULT_UDP_RECVMBOX_SIZE 128 +#define ETHARP_SUPPORT_STATIC_ENTRIES 1 +#define ETH_PAD_SIZE 2 +#define IP_REASS_MAX_PBUFS (((65535) / (IP_FRAG_MAX_MTU - 20 - 8) + 1) * MEMP_NUM_REASSDATA) +#define LWIP_COMPAT_SOCKETS 2 +#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_OFF +#define LWIP_DHCP 1 +#define LWIP_DNS 1 +#define LWIP_ETHERNET 1 +#define LWIP_HAVE_LOOPIF 1 +#define LWIP_IGMP 1 +#define LWIP_NETIF_API 1 +#define LWIP_NETIF_LINK_CALLBACK 1 +#define LWIP_NETIF_EXT_STATUS_CALLBACK 1 +#define LWIP_NETIF_LOOPBACK 1 +#define LWIP_POSIX_SOCKETS_IO_NAMES 0 +#define LWIP_RAW 1 +#define LWIP_SOCKET_OFFSET CONFIG_NFILE_DESCRIPTORS +#define LWIP_SO_RCVBUF 1 +#define LWIP_SO_RCVTIMEO 1 +#define LWIP_SO_SNDTIMEO 1 +#define LWIP_STATS_DISPLAY 1 +#define MEM_LIBC_MALLOC 1 +#define MEMP_NUM_ARP_QUEUE (65535 * LWIP_CONFIG_NUM_SOCKETS / (IP_FRAG_MAX_MTU - 20 - 8)) +#define MEMP_NUM_NETBUF (65535 * 3 * LWIP_CONFIG_NUM_SOCKETS / (IP_FRAG_MAX_MTU - 20 - 8)) +#define MEMP_NUM_NETCONN LWIP_CONFIG_NUM_SOCKETS +#define MEMP_NUM_PBUF LWIP_CONFIG_NUM_SOCKETS*2 +#define MEMP_NUM_RAW_PCB LWIP_CONFIG_NUM_SOCKETS +#define MEMP_NUM_REASSDATA (IP_REASS_MAX_MEM_SIZE / 65535) +#define MEMP_NUM_TCPIP_MSG_API 64 +#define MEMP_NUM_TCPIP_MSG_INPKT 512 +#define MEMP_NUM_TCP_PCB LWIP_CONFIG_NUM_SOCKETS +#define MEMP_NUM_TCP_PCB_LISTEN LWIP_CONFIG_NUM_SOCKETS +#define MEMP_NUM_TCP_SEG (((TCP_SND_BUF * 3 / 2) + TCP_WND) * LWIP_CONFIG_NUM_SOCKETS / TCP_MSS) +#define MEMP_NUM_UDP_PCB LWIP_CONFIG_NUM_SOCKETS +#define MEM_SIZE (4*1024*1024) // (512*1024) +#define PBUF_POOL_BUFSIZE 1550 +#define PBUF_POOL_SIZE 64 +#define SO_REUSE 1 +#define TCPIP_MBOX_SIZE 512 +#define TCPIP_THREAD_PRIO 5 +#define TCPIP_THREAD_STACKSIZE 0x6000 +#define TCP_MAXRTX 64 +#define TCP_MSS 1400 +#define TCP_SND_BUF 65535 +#define TCP_SND_QUEUELEN (8 * TCP_SND_BUF) / TCP_MSS +#define TCP_TTL 255 +#define TCP_WND 32768 +#define UDP_TTL 255 + + +// Options in old lwipopts.h but kept in Defaults with new opt.h +#define IP_FORWARD 0 +#define LWIP_DBG_TYPES_ON LWIP_DBG_ON +#define LWIP_ICMP 1 +#define LWIP_NETCONN 1 +#define LWIP_SOCKET 1 +#define LWIP_STATS 1 +#define LWIP_TCP 1 +#define LWIP_UDP 1 +#define NO_SYS 0 +#define TCP_QUEUE_OOSEQ LWIP_TCP + + +// Change some options for lwIP 2.1.2 +#undef TCP_MAXRTX +#define TCP_MAXRTX 12 + +#undef LWIP_COMPAT_SOCKETS +#define LWIP_COMPAT_SOCKETS 0 + +#define MEMP_NUM_SYS_TIMEOUT (LWIP_NUM_SYS_TIMEOUT_INTERNAL + (LWIP_IPV6 * LWIP_IPV6_DHCP6)) + +#undef DEFAULT_ACCEPTMBOX_SIZE +#define DEFAULT_ACCEPTMBOX_SIZE LWIP_CONFIG_NUM_SOCKETS + +#undef TCP_MSS +#define TCP_MSS (IP_FRAG_MAX_MTU - 20 - 20) + +#undef IP_SOF_BROADCAST_RECV +#define IP_SOF_BROADCAST_RECV 0 + +/** + * Defines whether to enable debugging for driver module. + */ +#ifndef DRIVERIF_DEBUG +#define DRIVERIF_DEBUG LWIP_DBG_OFF +#endif + + +// Options for old lwipopts.h +#define IP_FRAG_MAX_MTU 1500 +#define LWIP_CONFIG_NUM_SOCKETS 128 +#define IP_REASS_MAX_MEM_SIZE (MEM_SIZE / 4) + +// Options for enhancement code, same for old lwipopts.h +#define LWIP_NETIF_PROMISC 1 +#define LWIP_DHCPS 1 +#define LWIP_ENABLE_NET_CAPABILITY 1 +#define LWIP_ENABLE_CAP_NET_BROADCAST 0 + +#endif /* _LWIP_PORTING_LWIPOPTS_H_ */ diff --git a/src/kernel_liteos_a/net/lwip-2.1/porting/include/lwip/netif.h b/src/kernel_liteos_a/net/lwip-2.1/porting/include/lwip/netif.h new file mode 100644 index 00000000..6109193f --- /dev/null +++ b/src/kernel_liteos_a/net/lwip-2.1/porting/include/lwip/netif.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LWIP_PORTING_NETIF_H_ +#define _LWIP_PORTING_NETIF_H_ + +#include // For IFNAMSIZ/IF_NAMESIZE and `struct ifreq', by `lwip/netif.h' and `api/sockets.c' +#include // For IP_OFFMASK, by `core/ipv4/ip4_frag.c' + +#define netif_find netifapi_netif_find_by_name + +#if LWIP_DHCPS +#define LWIP_NETIF_CLIENT_DATA_INDEX_DHCP LWIP_NETIF_CLIENT_DATA_INDEX_DHCP, \ + LWIP_NETIF_CLIENT_DATA_INDEX_DHCPS +#endif + +#ifdef LOSCFG_NET_CONTAINER +#include "lwip/net_group.h" +#define VETH_DRIVER_IF 2 +void veth_init(struct netif *netif, struct net_group *group); +#define linkoutput linkoutput; \ + void (*drv_send)(struct netif *netif, struct pbuf *p); \ + u8_t (*drv_set_hwaddr)(struct netif *netif, u8_t *addr, u8_t len); \ + void (*drv_config)(struct netif *netif, u32_t config_flags, u8_t setBit); \ + char full_name[IFNAMSIZ]; \ + struct net_group *group; \ + struct netif *peer; \ + u16_t link_layer_type +#else +#define linkoutput linkoutput; \ + void (*drv_send)(struct netif *netif, struct pbuf *p); \ + u8_t (*drv_set_hwaddr)(struct netif *netif, u8_t *addr, u8_t len); \ + void (*drv_config)(struct netif *netif, u32_t config_flags, u8_t setBit); \ + char full_name[IFNAMSIZ]; \ + u16_t link_layer_type +#endif +#include_next +#undef linkoutput +#if LWIP_DHCPS +#undef LWIP_NETIF_CLIENT_DATA_INDEX_DHCP +#endif + +#include // For ETHARP_HWADDR_LEN, by `hieth-sf src/interface.c' and `wal/wal_net.c' + +#ifdef __cplusplus +extern "C" { +#endif + +// redefine NETIF_NAMESIZE which was defined in netif.h +#undef NETIF_NAMESIZE +#define NETIF_NAMESIZE IFNAMSIZ + +#define LOOPBACK_IF 0 // 772 +#define ETHERNET_DRIVER_IF 1 +#define WIFI_DRIVER_IF 801 + +err_t driverif_init(struct netif *netif); +void driverif_input(struct netif *netif, struct pbuf *p); + +#ifndef __LWIP__ +#define PF_PKT_SUPPORT LWIP_NETIF_PROMISC +#define netif_add(a, b, c, d) netif_add(a, b, c, d, (a)->state, driverif_init, tcpip_input) +#else /* __LWIP__ */ +#define netif_get_name(netif) ((netif)->full_name) +#endif /* __LWIP__ */ + +#ifdef __cplusplus +} +#endif + +#endif /* _LWIP_PORTING_NETIF_H_ */ diff --git a/src/kernel_liteos_a/net/lwip-2.1/porting/include/lwip/netifapi.h b/src/kernel_liteos_a/net/lwip-2.1/porting/include/lwip/netifapi.h new file mode 100644 index 00000000..4bfcc835 --- /dev/null +++ b/src/kernel_liteos_a/net/lwip-2.1/porting/include/lwip/netifapi.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LWIP_PORTING_NETIFAPI_H_ +#define _LWIP_PORTING_NETIFAPI_H_ + +#include_next + +#ifdef __cplusplus +extern "C" { +#endif + +err_t netifapi_dhcps_start(struct netif *netif, char *start_ip, u16_t ip_num); +err_t netifapi_dhcps_stop(struct netif *netif); + +#define netifapi_dhcp_cleanup(n) netifapi_netif_common(n, dhcp_cleanup, NULL) +#define netifapi_dhcp_is_bound(n) netifapi_netif_common(n, NULL, dhcp_is_bound) + +void netifapi_netif_rmv_ip6_address(struct netif *netif, ip_addr_t *ipaddr); +struct netif *netifapi_netif_find_by_name(const char *name); + +#ifndef __LWIP__ +#define netifapi_netif_add(a, b, c, d) netifapi_netif_add(a, b, c, d, (a)->state, driverif_init, tcpip_input) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _LWIP_PORTING_NETIFAPI_H_ */ diff --git a/src/kernel_liteos_a/net/lwip-2.1/porting/include/lwip/pbuf.h b/src/kernel_liteos_a/net/lwip-2.1/porting/include/lwip/pbuf.h new file mode 100644 index 00000000..79968178 --- /dev/null +++ b/src/kernel_liteos_a/net/lwip-2.1/porting/include/lwip/pbuf.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LWIP_PORTING_PBUF_H_ +#define _LWIP_PORTING_PBUF_H_ + +#include_next + +#ifdef __cplusplus +extern "C" { +#endif + +struct pbuf_dma_info { + void *dma; + void *mac_header; + u16_t dma_len; + u16_t link_len; +}; + +#define pbuf_dma_ref(dma_info) // ERR_OK +#define pbuf_dma_free(dma_info) + +#define dma_info payload + +#ifdef __cplusplus +} +#endif + +#endif /* _LWIP_PORTING_PBUF_H_ */ diff --git a/src/kernel_liteos_a/net/lwip-2.1/porting/include/lwip/priv/api_msg.h b/src/kernel_liteos_a/net/lwip-2.1/porting/include/lwip/priv/api_msg.h new file mode 100644 index 00000000..573aac6b --- /dev/null +++ b/src/kernel_liteos_a/net/lwip-2.1/porting/include/lwip/priv/api_msg.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LWIP_PORTING_API_MSG_H_ +#define _LWIP_PORTING_API_MSG_H_ + +#if LWIP_DHCPS +#define common common; \ + struct { \ + char *start_ip; \ + u16_t ip_num; \ + } dhcp_start_params +#else +#define common common +#endif +#include_next +#undef common + +#endif /* _LWIP_PORTING_API_MSG_H_ */ diff --git a/src/kernel_liteos_a/net/lwip-2.1/porting/include/lwip/priv/sockets_priv.h b/src/kernel_liteos_a/net/lwip-2.1/porting/include/lwip/priv/sockets_priv.h new file mode 100644 index 00000000..dfab001e --- /dev/null +++ b/src/kernel_liteos_a/net/lwip-2.1/porting/include/lwip/priv/sockets_priv.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LWIP_PORTING_SOCKETS_PRIV_H_ +#define _LWIP_PORTING_SOCKETS_PRIV_H_ + +#define select_waiting select_waiting; \ + wait_queue_head_t wq; \ + unsigned long s_refcount +#include_next +#undef select_waiting + +#endif /* _LWIP_PORTING_SOCKETS_PRIV_H_ */ diff --git a/src/kernel_liteos_a/net/lwip-2.1/porting/include/lwip/sockets.h b/src/kernel_liteos_a/net/lwip-2.1/porting/include/lwip/sockets.h new file mode 100644 index 00000000..af3dcb25 --- /dev/null +++ b/src/kernel_liteos_a/net/lwip-2.1/porting/include/lwip/sockets.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LWIP_PORTING_SOCKETS_H_ +#define _LWIP_PORTING_SOCKETS_H_ + +#include +#include // For poll_table +#include // For TCP_NODELAY etc. +#include +#include // For FIONREAD etc. +#include // For FD_SET +#include // For IOV_MAX +#include_next + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __LWIP__ + +#if FD_SETSIZE < (LWIP_SOCKET_OFFSET + MEMP_NUM_NETCONN) +#error "external FD_SETSIZE too small for number of sockets" +#else +#define LWIP_SELECT_MAXNFDS FD_SETSIZE +#endif + +#if IOV_MAX > 0xFFFF +#error "IOV_MAX larger than supported by LwIP" +#endif + +#if LWIP_UDP && LWIP_UDPLITE +#define UDPLITE_SEND_CSCOV 0x01 /* sender checksum coverage */ +#define UDPLITE_RECV_CSCOV 0x02 /* minimal receiver checksum coverage */ +#endif + +// For BSD 4.4 socket sa_len compatibility +#define DF_NADDR(addr) ip_addr_t naddr = addr +#define SA_LEN(addr, _) (IP_IS_V4_VAL(addr) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6)) +#define sa_len sa_data[0] * 0 + SA_LEN(naddr, _) +#define sin_len sin_zero[0] +#define sin6_len sin6_addr.s6_addr[0] + +// for sockets.c, TCP_KEEPALIVE is not supported currently +#define TCP_KEEPALIVE 0xFF +#define SIN_ZERO_LEN 8 + +#else +int closesocket(int sockfd); +#endif /* __LWIP__ */ + +int socks_poll(int sockfd, poll_table *wait); +int socks_ioctl(int sockfd, long cmd, void *argp); +int socks_close(int sockfd); +void socks_refer(int sockfd); + +#ifdef __cplusplus +} +#endif + +#endif /* _LWIP_PORTING_SOCKETS_H_ */ diff --git a/src/kernel_liteos_a/net/lwip-2.1/porting/include/lwipopts.h b/src/kernel_liteos_a/net/lwip-2.1/porting/include/lwipopts.h new file mode 100644 index 00000000..5a2d3545 --- /dev/null +++ b/src/kernel_liteos_a/net/lwip-2.1/porting/include/lwipopts.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __LITEOS_A_LWIPOPTS_H__ +#define __LITEOS_A_LWIPOPTS_H__ + +// Just redirect +#include "lwip/lwipopts.h" + +#endif //__LITEOS_A_LWIPOPTS_H__ diff --git a/src/kernel_liteos_a/net/lwip-2.1/porting/src/driverif.c b/src/kernel_liteos_a/net/lwip-2.1/porting/src/driverif.c new file mode 100644 index 00000000..bb387124 --- /dev/null +++ b/src/kernel_liteos_a/net/lwip-2.1/porting/src/driverif.c @@ -0,0 +1,380 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#ifdef LOSCFG_NET_CONTAINER +#include +#endif + +#define LWIP_NETIF_HOSTNAME_DEFAULT "default" +#define LINK_SPEED_OF_YOUR_NETIF_IN_BPS 100000000 // 100Mbps + +#define link_rx_drop cachehit +#define link_rx_overrun cachehit + +#define LWIP_STATIC static + +#ifndef LWIP_NETIF_IFINDEX_MAX_EX +#define LWIP_NETIF_IFINDEX_MAX_EX 255 +#endif + +LWIP_STATIC void +driverif_init_ifname(struct netif *netif) +{ + struct netif *tmpnetif = NULL; + const char *prefix = (netif->link_layer_type == WIFI_DRIVER_IF) ? "wlan" : "eth"; + + netif->name[0] = prefix[0]; + netif->name[1] = prefix[1]; + + for (int i = 0; i < LWIP_NETIF_IFINDEX_MAX_EX; ++i) { + if (snprintf_s(netif->full_name, sizeof(netif->full_name), sizeof(netif->full_name) - 1, + "%s%d", prefix, i) < 0) { + break; + } +#ifdef LOSCFG_NET_CONTAINER + NETIF_FOREACH(tmpnetif, get_net_group_from_netif(netif)) { +#else + NETIF_FOREACH(tmpnetif) { +#endif + if (strcmp(tmpnetif->full_name, netif->full_name) == 0) { + break; + } + } + if (tmpnetif == NULL) { + return; + } + } + netif->full_name[0] = '\0'; +} + +/* + * This function should do the actual transmission of the packet. The packet is + * contained in the pbuf that is passed to the function. This pbuf + * might be chained. + * + * @param netif the lwip network interface structure for this driverif + * @param p the MAC packet to send (e.g. IP packet including MAC_addresses and type) + * @return ERR_OK if the packet could be sent + * an err_t value if the packet couldn't be sent + * + * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to + * strange results. You might consider waiting for space in the DMA queue + * to become available since the stack doesn't retry to send a packet + * dropped because of memory failure (except for the TCP timers). + */ + +LWIP_STATIC err_t +driverif_output(struct netif *netif, struct pbuf *p) +{ + LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_output : going to send packet pbuf 0x%p of length %"U16_F" through netif 0x%p\n", \ + (void *)p, p->tot_len, (void *)netif)); + +#if PF_PKT_SUPPORT + if (all_pkt_raw_pcbs != NULL) { + p->flags = (u16_t)(p->flags & ~(PBUF_FLAG_LLMCAST | PBUF_FLAG_LLBCAST | PBUF_FLAG_HOST)); + p->flags |= PBUF_FLAG_OUTGOING; + (void)raw_pkt_input(p, netif, NULL); + } +#endif + +#if ETH_PAD_SIZE + (void)pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ +#endif + + netif->drv_send(netif, p); + +#if ETH_PAD_SIZE + (void)pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ +#endif + MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p->tot_len); + LINK_STATS_INC(link.xmit); + + return ERR_OK; +} + +/* + * This function should be called by network driver to pass the input packet to LwIP. + * Before calling this API, driver has to keep the packet in pbuf structure. Driver has to + * call pbuf_alloc() with type as PBUF_RAM to create pbuf structure. Then driver + * has to pass the pbuf structure to this API. This will add the pbuf into the TCPIP thread. + * Once this packet is processed by TCPIP thread, pbuf will be freed. Driver is not required to + * free the pbuf. + * + * @param netif the lwip network interface structure for this driverif + * @param p packet in pbuf structure format + */ +void +driverif_input(struct netif *netif, struct pbuf *p) +{ +#if PF_PKT_SUPPORT +#if (DRIVERIF_DEBUG & LWIP_DBG_OFF) + u16_t ethhdr_type; + struct eth_hdr* ethhdr = NULL; +#endif +#else + u16_t ethhdr_type; + struct eth_hdr *ethhdr = NULL; +#endif + err_t ret = ERR_VAL; + + LWIP_ERROR("driverif_input : invalid arguments", ((netif != NULL) && (p != NULL)), return); + + LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input : going to receive input packet. netif 0x%p, pbuf 0x%p, \ + packet_length %"U16_F"\n", (void *)netif, (void *)p, p->tot_len)); + + /* points to packet payload, which starts with an Ethernet header */ + MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len); + if (p->len < SIZEOF_ETH_HDR) { + (void)pbuf_free(p); + LINK_STATS_INC(link.drop); + LINK_STATS_INC(link.link_rx_drop); + return; + } + +#if PF_PKT_SUPPORT +#if (DRIVERIF_DEBUG & LWIP_DBG_OFF) + ethhdr = (struct eth_hdr *)p->payload; + ethhdr_type = ntohs(ethhdr->type); + LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input : received packet of type %"U16_F" netif->input=%p\n", ethhdr_type, netif->input)); +#endif + + /* full packet send to tcpip_thread to process */ + if (netif->input) { + ret = netif->input(p, netif); + } + if (ret != ERR_OK) { + LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input: IP input error\n")); + (void)pbuf_free(p); + LINK_STATS_INC(link.drop); + LINK_STATS_INC(link.link_rx_drop); + if (ret == ERR_MEM) { + LINK_STATS_INC(link.link_rx_overrun); + } + } else { + LINK_STATS_INC(link.recv); + } + +#else + ethhdr = (struct eth_hdr *)p->payload; + ethhdr_type = ntohs(ethhdr->type); + + switch (ethhdr_type) { + /* IP or ARP packet? */ + case ETHTYPE_IP: + case ETHTYPE_IPV6: + case ETHTYPE_ARP: +#if ETHARP_SUPPORT_VLAN + case ETHTYPE_VLAN: +#endif /* ETHARP_SUPPORT_VLAN */ + LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input : received packet of type %"U16_F"\n", ethhdr_type)); + /* full packet send to tcpip_thread to process */ + if (netif->input != NULL) { + ret = netif->input(p, netif); + } + + if (ret != ERR_OK) { + LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input: IP input error\n")); + (void)pbuf_free(p); + LINK_STATS_INC(link.drop); + LINK_STATS_INC(link.link_rx_drop); + if (ret == ERR_MEM) { + MIB2_STATS_NETIF_INC(netif, ifinoverruns); + LINK_STATS_INC(link.link_rx_overrun); + } + } else { + LINK_STATS_INC(link.recv); + } + break; + + default: + LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input : received packet is of unsupported type %"U16_F"\n", ethhdr_type)); + (void)pbuf_free(p); + LINK_STATS_INC(link.drop); + LINK_STATS_INC(link.link_rx_drop); + break; + } +#endif + + LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input : received packet is processed\n")); +} + +/* + * Should be called at the beginning of the program to set up the + * network interface. It calls the function low_level_init() to do the + * actual setup of the hardware. + * + * This function should be passed as a parameter to netif_add(). + * + * @param netif the lwip network interface structure for this driverif + * @return ERR_OK if the loopif is initialized + * ERR_MEM on Allocation Failure + * any other err_t on error + */ +err_t +driverif_init(struct netif *netif) +{ + u16_t link_layer_type; + + if (netif == NULL) { + return ERR_IF; + } + link_layer_type = netif->link_layer_type; + LWIP_ERROR("driverif_init : invalid link_layer_type in netif", \ + ((link_layer_type == ETHERNET_DRIVER_IF) || (link_layer_type == WIFI_DRIVER_IF)), \ + return ERR_IF); + + LWIP_ERROR("driverif_init : netif hardware length is greater than maximum supported", \ + (netif->hwaddr_len <= NETIF_MAX_HWADDR_LEN), return ERR_IF); + + LWIP_ERROR("driverif_init : drv_send is null", (netif->drv_send != NULL), return ERR_IF); + +#if LWIP_NETIF_PROMISC + LWIP_ERROR("driverif_init : drv_config is null", (netif->drv_config != NULL), return ERR_IF); +#endif + +#if LWIP_NETIF_HOSTNAME + /* Initialize interface hostname */ + netif->hostname = LWIP_NETIF_HOSTNAME_DEFAULT; +#endif /* LWIP_NETIF_HOSTNAME */ + + /* + * Initialize the snmp variables and counters inside the struct netif. + * The last argument should be replaced with your link speed, in units + * of bits per second. + */ + NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS); + + netif->output = etharp_output; + netif->linkoutput = driverif_output; + + /* init the netif's full name */ + driverif_init_ifname(netif); + + /* maximum transfer unit */ + netif->mtu = IP_FRAG_MAX_MTU; + + /* device capabilities */ + /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */ + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | + #if DRIVER_STATUS_CHECK + NETIF_FLAG_DRIVER_RDY | + #endif + #if LWIP_IGMP + NETIF_FLAG_IGMP | + #endif + + /** + @page RFC-2710 RFC-2710 + @par Compliant Sections + Section 5. Node State Transition Diagram + @par Behavior Description + MLD messages are sent for multicast addresses whose scope is 2 + (link-local), including Solicited-Node multicast addresses.\n + Behavior:Stack will send MLD6 report /Done to solicited node multicast address + if the LWIP_MLD6_ENABLE_MLD_ON_DAD is enabled. By default, this is disabled. + */ + /* Enable sending MLD report /done for solicited address during neighbour discovery */ + #if LWIP_IPV6 && LWIP_IPV6_MLD + #if LWIP_MLD6_ENABLE_MLD_ON_DAD + NETIF_FLAG_MLD6 | + #endif /* LWIP_MLD6_ENABLE_MLD_ON_DAD */ + #endif + NETIF_FLAG_LINK_UP; + +#if DRIVER_STATUS_CHECK + netif->waketime = -1; +#endif /* DRIVER_STATUS_CHECK */ + LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_init : Initialized netif 0x%p\n", (void *)netif)); + return ERR_OK; +} + +#ifdef LOSCFG_NET_CONTAINER +static err_t netif_veth_output(struct netif *netif, struct pbuf *p, const ip4_addr_t *addr) +{ + LWIP_UNUSED_ARG(addr); + return netif_loop_output(netif->peer, p); +} + +static void veth_init_fullname(struct netif *netif) +{ + struct netif *tmpnetif = NULL; + + for (int i = 0; i < LWIP_NETIF_IFINDEX_MAX_EX; ++i) { + if (snprintf_s(netif->full_name, sizeof(netif->full_name), sizeof(netif->full_name) - 1, + "%s%d", "veth", i) < 0) { + break; + } + NETIF_FOREACH(tmpnetif, get_net_group_from_netif(netif)) { + if (strcmp(tmpnetif->full_name, netif->full_name) == 0) { + break; + } + } + if (tmpnetif == NULL) { + return; + } + } + netif->full_name[0] = '\0'; +} + +static err_t netif_vethif_init(struct netif *netif) +{ + LWIP_ASSERT("netif_vethif_init: invalid netif", netif != NULL); + + /* initialize the snmp variables and counters inside the struct netif + * ifSpeed: no assumption can be made! + */ + MIB2_INIT_NETIF(netif, snmp_ifType_other, 0); + netif->link_layer_type = VETH_DRIVER_IF; + + netif->name[0] = 'v'; + netif->name[1] = 'e'; + + veth_init_fullname(netif); + netif->output = netif_veth_output; + + netif_set_flags(netif, NETIF_FLAG_IGMP); + NETIF_SET_CHECKSUM_CTRL(netif, NETIF_CHECKSUM_DISABLE_ALL); + return ERR_OK; +} + +void veth_init(struct netif *netif, struct net_group *group) +{ + netif_add_noaddr(netif, group, NULL, netif_vethif_init, tcpip_input); + netif_set_link_up(netif); + netif_set_up(netif); +} +#endif diff --git a/src/kernel_liteos_a/net/lwip-2.1/porting/src/sockets.c b/src/kernel_liteos_a/net/lwip-2.1/porting/src/sockets.c new file mode 100644 index 00000000..cae2fc7a --- /dev/null +++ b/src/kernel_liteos_a/net/lwip-2.1/porting/src/sockets.c @@ -0,0 +1,1741 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +#if LWIP_ENABLE_NET_CAPABILITY +#include "capability_type.h" +#include "capability_api.h" +#define BIND_SERVICE_CAP_MIN_PORT 1024 +#endif + +#define IOCTL_CMD_CASE_HANDLER() \ + { \ + err_t err; \ + struct lwip_ioctl_apimsg msg; \ + msg.sock = sock; \ + msg.cmd = cmd; \ + msg.argp = argp; \ + \ + err = tcpip_api_call(lwip_do_ioctl_impl, &msg.call); \ + if (err != ENOSYS) { \ + sock_set_errno(sock, err); \ + done_socket(sock); \ + return -(err != ERR_OK); \ + } \ + } + +struct lwip_ioctl_apimsg { + struct tcpip_api_call_data call; + struct lwip_sock *sock; + long cmd; + void *argp; +}; + +static err_t lwip_do_ioctl_impl(struct tcpip_api_call_data *call); + +static void poll_check_waiters(int s, int check_waiters); + +static int lwip_socket_wrap(int domain, int type, int protocol); +int lwip_socket(int domain, int type, int protocol) +{ + return lwip_socket_wrap(domain, type, protocol); +} + +static int lwip_setsockopt_wrap(int s, int level, int optname, const void *optval, socklen_t optlen); +int lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen) +{ + return lwip_setsockopt_wrap(s, level, optname, optval, optlen); +} + +static int lwip_bind_wrap(int s, const struct sockaddr *name, socklen_t namelen); +int lwip_bind(int s, const struct sockaddr *name, socklen_t namelen) +{ + return lwip_bind_wrap(s, name, namelen); +} + +static ssize_t lwip_sendto_wrap(int s, const void *dataptr, size_t size, int flags, + const struct sockaddr *to, socklen_t tolen); +ssize_t lwip_sendto(int s, const void *dataptr, size_t size, int flags, const struct sockaddr *to, socklen_t tolen) +{ + return lwip_sendto_wrap(s, dataptr, size, flags, to, tolen); +} + +#ifdef lwip_socket +#undef lwip_socket +#endif +#define lwip_socket static lwip_socket2 +static int lwip_socket2(int domain, int type, int protocol); + +#ifdef lwip_setsockopt +#undef lwip_setsockopt +#endif +#define lwip_setsockopt static lwip_setsockopt2 +static int lwip_setsockopt2(int s, int level, int optname, const void *optval, socklen_t optlen); + +#ifdef lwip_bind +#undef lwip_bind +#endif +#define lwip_bind static lwip_bind2 +static int lwip_bind2(int s, const struct sockaddr *name, socklen_t namelen); + +#ifdef lwip_sendto +#undef lwip_sendto +#endif +#define lwip_sendto lwip_sendto2 +ssize_t lwip_sendto2(int s, const void *dataptr, size_t size, int flags, const struct sockaddr *to, socklen_t tolen); + +#include "../api/sockets.c" + +#undef lwip_socket +#undef lwip_setsockopt +#undef lwip_bind +#undef lwip_sendto + +static int lwip_socket_wrap(int domain, int type, int protocol) +{ + if (domain != AF_INET && domain != AF_INET6) { + set_errno(EAFNOSUPPORT); + return -1; + } +#if LWIP_ENABLE_NET_CAPABILITY + if (type == SOCK_RAW && !IsCapPermit(CAP_NET_RAW)) { + set_errno(EPERM); + return -1; + } +#endif + return lwip_socket2(domain, type, protocol); +} + +static int lwip_setsockopt_wrap(int s, int level, int optname, const void *optval, socklen_t optlen) +{ +#if LWIP_ENABLE_NET_CAPABILITY + if (level == SOL_SOCKET) { + switch (optname) { +#if LWIP_ENABLE_CAP_NET_BROADCAST + case SO_BROADCAST: + if (!IsCapPermit(CAP_NET_BROADCAST)) { + set_errno(EPERM); + return -1; + } + break; +#endif + case SO_DEBUG: + case SO_MARK: + case SO_PRIORITY: + case SO_RCVBUFFORCE: + case SO_SNDBUFFORCE: + if (!IsCapPermit(CAP_NET_ADMIN)) { + set_errno(EPERM); + return -1; + } + break; + default: + break; + } + } +#endif + return lwip_setsockopt2(s, level, optname, optval, optlen); +} + +#if LWIP_ENABLE_NET_CAPABILITY && LWIP_ENABLE_CAP_NET_BROADCAST +static int ip_addr_isbroadcast_bysock(const ip_addr_t *ipaddr, int s) +{ + struct sockaddr sa; + socklen_t salen = sizeof(sa); + + if (ipaddr == NULL) { + return 0; + } + + if (lwip_getsockname(s, &sa, &salen) == -1) { + return 0; + } + + ip_addr_t addr; + u16_t port; + + SOCKADDR_TO_IPADDR_PORT(&sa, &addr, port); + + struct netif *netif = NULL; + NETIF_FOREACH(netif) { + if (ip_addr_cmp(&netif->ip_addr, &addr)) { + return ip_addr_isbroadcast(ipaddr, netif); + } + for (int i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { + if (ip_addr_cmp(&netif->ip6_addr[i], &addr)) { + return ip_addr_isbroadcast(ipaddr, netif); + } + } + } + + return 0; +} +#endif + +static int lwip_bind_wrap(int s, const struct sockaddr *name, socklen_t namelen) +{ +#if LWIP_ENABLE_NET_CAPABILITY + if ((name->sa_family == AF_INET && namelen >= sizeof(struct sockaddr_in)) || + (name->sa_family == AF_INET6 && namelen >= sizeof(struct sockaddr_in6))) { + ip_addr_t ipaddr; + u16_t port; + + SOCKADDR_TO_IPADDR_PORT(name, &ipaddr, port); + + if (port != 0 && port < BIND_SERVICE_CAP_MIN_PORT) { + LWIP_ERROR("permission deny: NET_BIND_SERVICE\n", IsCapPermit(CAP_NET_BIND_SERVICE), + set_errno(EPERM); return -1); + } +#if LWIP_ENABLE_CAP_NET_BROADCAST + if (ip_addr_ismulticast(&ipaddr) || ip_addr_isbroadcast_bysock(&ipaddr, s)) { + LWIP_ERROR("permission deny: NET_BROADCAST\n", IsCapPermit(CAP_NET_BROADCAST), + set_errno(EPERM); return -1); + } +#endif + } +#endif + + return lwip_bind2(s, name, namelen); +} + +static ssize_t lwip_sendto_wrap(int s, const void *dataptr, size_t size, int flags, + const struct sockaddr *to, socklen_t tolen) +{ +#if LWIP_ENABLE_NET_CAPABILITY + if (to && + ((to->sa_family == AF_INET && tolen >= sizeof(struct sockaddr_in)) || + (to->sa_family == AF_INET6 && tolen >= sizeof(struct sockaddr_in6)))) { + ip_addr_t ipaddr; + u16_t port; + + SOCKADDR_TO_IPADDR_PORT(to, &ipaddr, port); +#if LWIP_ENABLE_CAP_NET_BROADCAST + if (ip_addr_ismulticast(&ipaddr) || ip_addr_isbroadcast_bysock(&ipaddr, s)) { + LWIP_ERROR("permission deny: NET_BROADCAST\n", IsCapPermit(CAP_NET_BROADCAST), + set_errno(EPERM); return -1); + } +#endif + } +#endif + + return lwip_sendto2(s, dataptr, size, flags, to, tolen); +} + +#if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL + +struct file; +extern void poll_wait(struct file *filp, wait_queue_head_t *wait_address, poll_table *p); +extern void __wake_up_interruptible_poll(wait_queue_head_t *wait, pollevent_t key); + +static void poll_check_waiters(int s, int check_waiters) +{ + unsigned long int_save, wq_empty; + pollevent_t mask = 0; + struct lwip_sock *sock; + SYS_ARCH_DECL_PROTECT(lev); + + if (!check_waiters) { + return; + } + + sock = get_socket(s); + if (!sock) { + return; + } + + SYS_ARCH_PROTECT(lev); + + mask |= (sock->rcvevent > 0) ? (POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND) : 0; + mask |= (sock->sendevent != 0) ? (POLLOUT | POLLWRNORM | POLLWRBAND) : 0; + mask |= (sock->errevent != 0) ? (POLLERR) : 0; + + SYS_ARCH_UNPROTECT(lev); + + spin_lock_irqsave(&sock->wq.lock, int_save); + wq_empty = LOS_ListEmpty(&(sock->wq.poll_queue)); + spin_unlock_irqrestore(&sock->wq.lock, int_save); + + if (mask && !wq_empty) { + __wake_up_interruptible_poll(&sock->wq, mask); + } + + done_socket(sock); +} + +int socks_poll(int s, poll_table *wait) +{ + int ret; + pollevent_t mask = 0; + struct lwip_sock *sock; + SYS_ARCH_DECL_PROTECT(lev); + + LWIP_ERROR("sock_poll: invalid poll_table", (wait != NULL), return -EINVAL;); + + sock = get_socket(s); + if (!sock) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("sock_poll: Invalid socket")); + set_errno(EBADF); + return -EBADF; /* compatible with file poll */ + } + + SYS_ARCH_PROTECT(lev); + + mask |= (sock->rcvevent > 0 || sock->lastdata.pbuf) ? (POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND) : 0; + mask |= (sock->sendevent != 0) ? (POLLOUT | POLLWRNORM | POLLWRBAND) : 0; + mask |= (sock->errevent != 0) ? (POLLERR) : 0; + + SYS_ARCH_UNPROTECT(lev); + + ret = wait->key & mask; + if (!ret) { + poll_wait(NULL, &sock->wq, wait); + } + + done_socket(sock); + return ret; +} + +#endif /* LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL */ + +#if !LWIP_COMPAT_SOCKETS + +#define API_ALIAS(old, new) \ + extern __typeof(old) new __attribute__((__weak__, __alias__(#old))) + +API_ALIAS(lwip_ioctl, ioctlsocket); + +#endif /* !LWIP_COMPAT_SOCKETS */ + +#if LWIP_ENABLE_LOS_SHELL_CMD +/* get numbers of unused sockets */ +int get_unused_socket_num(void) +{ + int unused = 0; + SYS_ARCH_DECL_PROTECT(lev); + + SYS_ARCH_PROTECT(lev); + + for (int i = 0; i < NUM_SOCKETS; i++) { + if (sockets[i].conn == NULL) { +#if LWIP_NETCONN_FULLDUPLEX + if (sockets[i].fd_used) { + continue; + } +#endif + unused++; + } + } + + SYS_ARCH_UNPROTECT(lev); + + return unused; +} +#endif + +/** + * socket ioctl + */ + +// Options for lwip ioctl +#define LWIP_IOCTL_ROUTE 1 +#define LWIP_IOCTL_IF 1 +#define LWIP_NETIF_ETHTOOL 0 +#define LWIP_IOCTL_IPV6DPCTD 0 +#undef LWIP_IPV6_DUP_DETECT_ATTEMPTS +#define LWIP_IPV6_DUP_DETECT_ATTEMPTS 0 + +#ifndef SIOCSIPV6DAD +#define SIOCSIPV6DAD _IOW('z', 0, unsigned long) /* set DAD enable/disable on netif */ +#endif + +#ifndef SIOCGIPV6DAD +#define SIOCGIPV6DAD _IOR('z', 1, unsigned long) /* get DAD status on netif */ +#endif + +#ifndef SIOCSIPV6DPCTD +#define SIOCSIPV6DPCTD _IOW('z', 2, unsigned long) +#endif + +#ifndef SIOCGIPV6DPCTD +#define SIOCGIPV6DPCTD _IOR('z', 3, unsigned long) +#endif + +#ifndef SIOCETHTOOL +#define SIOCETHTOOL 0x8946 +#endif + +#if LWIP_NETIF_PROMISC +#define NETIF_FLAG_PROMISC 0x80U +#endif /* LWIP_NETIF_PROMISC */ + + +#if LWIP_IOCTL_ROUTE + +#include + +#ifdef LOSCFG_NET_CONTAINER +static u8_t lwip_ioctl_internal_SIOCADDRT(struct rtentry *rmten, struct net_group *group) +#else +static u8_t lwip_ioctl_internal_SIOCADDRT(struct rtentry *rmten) +#endif +{ + struct netif *netif = NULL; + ip_addr_t rtgw_addr; + u16_t rtgw_port; + +#if LWIP_ENABLE_NET_CAPABILITY + if (!IsCapPermit(CAP_NET_ADMIN)) { + return EPERM; + } +#endif + + SOCKADDR_TO_IPADDR_PORT(&rmten->rt_gateway, &rtgw_addr, rtgw_port); + + if (!IP_IS_V4_VAL(rtgw_addr)) { + return EINVAL; + } + + /* check if multicast/0/loopback */ + if (ip_addr_ismulticast(&rtgw_addr) || ip_addr_isany(&rtgw_addr) || + ip_addr_isloopback(&rtgw_addr)) { + return EINVAL; + } + + /* check if reachable */ +#ifdef LOSCFG_NET_CONTAINER + for (netif = group->netif_list; netif != NULL; netif = netif->next) { +#else + for (netif = netif_list; netif != NULL; netif = netif->next) { +#endif + if (ip_addr_netcmp(&rtgw_addr, &netif->ip_addr, ip_2_ip4(&netif->netmask))) { + break; + } + } + + if (netif == NULL) { + return EHOSTUNREACH; + } + + /* check if broadcast */ + if (ip_addr_isbroadcast(&rtgw_addr, netif) != 0) { + return EINVAL; + } + + /* Check flags */ + if ((rmten->rt_flags & RTF_GATEWAY) == 0) { + return EINVAL; + } + + /* Add validation */ +#ifdef LOSCFG_NET_CONTAINER + if ((group->netif_default != NULL) && (group->netif_default != netif)) { + ip_addr_set_zero(&group->netif_default->gw); + (void)netif_set_default(netif, group); +#else + if ((netif_default != NULL) && (netif_default != netif)) { + ip_addr_set_zero(&netif_default->gw); + (void)netif_set_default(netif); +#endif + } + netif_set_gw(netif, ip_2_ip4(&rtgw_addr)); + + return 0; +} + +#endif + +#if LWIP_IOCTL_IF +#ifdef LOSCFG_NET_CONTAINER +static u8_t lwip_ioctl_internal_SIOCGIFCONF(struct ifreq *ifr, struct net_group *group) +#else +static u8_t lwip_ioctl_internal_SIOCGIFCONF(struct ifreq *ifr) +#endif +{ + struct ifconf *ifc = NULL; + struct netif *netif = NULL; + struct ifreq ifreq; + struct sockaddr_in *sock_in = NULL; + int pos; + int len; + int ret; + + /* Format the caller's buffer. */ + ifc = (struct ifconf *)ifr; + len = ifc->ifc_len; + + /* Loop over the interfaces, and write an info block for each. */ + pos = 0; +#ifdef LOSCFG_NET_CONTAINER + for (netif = group->netif_list; netif != NULL; netif = netif->next) { +#else + for (netif = netif_list; netif != NULL; netif = netif->next) { +#endif + if (ifc->ifc_buf == NULL) { + pos = (pos + (int)sizeof(struct ifreq)); + continue; + } + + if (len < (int)sizeof(ifreq)) { + break; + } + (void)memset_s(&ifreq, sizeof(struct ifreq), 0, sizeof(struct ifreq)); + if (netif->link_layer_type == LOOPBACK_IF) { + ret = snprintf_s(ifreq.ifr_name, IFNAMSIZ, (IFNAMSIZ - 1), "%.2s", netif->name); + if ((ret <= 0) || (ret >= IFNAMSIZ)) { + LWIP_DEBUGF(NETIF_DEBUG, ("lwip_ioctl: snprintf_s ifr_name failed.")); + return ENOBUFS; + } + } else { + ret = snprintf_s(ifreq.ifr_name, IFNAMSIZ, (IFNAMSIZ - 1), "%s", netif_get_name(netif)); + if ((ret <= 0) || (ret >= IFNAMSIZ)) { + LWIP_DEBUGF(NETIF_DEBUG, ("lwip_ioctl: snprintf_s ifr_name failed.")); + return ENOBUFS; + } + } + + sock_in = (struct sockaddr_in *)&ifreq.ifr_addr; + sock_in->sin_family = AF_INET; + sock_in->sin_addr.s_addr = ip_2_ip4(&netif->ip_addr)->addr; + if (memcpy_s(ifc->ifc_buf + pos, sizeof(struct ifreq), &ifreq, sizeof(struct ifreq)) != EOK) { + return ENOBUFS; + } + pos = pos + (int)sizeof(struct ifreq); + len = len - (int)sizeof(struct ifreq); + } + + ifc->ifc_len = pos; + + return 0; +} + +static u8_t lwip_ioctl_internal_SIOCGIFADDR(struct ifreq *ifr) +{ + struct netif *netif = NULL; + struct sockaddr_in *sock_in = NULL; + + /* get netif ipaddr */ + netif = netif_find(ifr->ifr_name); + if (netif == NULL) { + return ENODEV; + } else { + sock_in = (struct sockaddr_in *)&ifr->ifr_addr; + sock_in->sin_family = AF_INET; + sock_in->sin_addr.s_addr = ip_2_ip4(&netif->ip_addr)->addr; + return 0; + } +} + +#ifndef LWIP_IPV6_PREFIX_LEN +#define LWIP_IPV6_PREFIX_LEN 64 +#endif + +#ifndef LWIP_NETIF_IFINDEX_MAX_EX +#define LWIP_NETIF_IFINDEX_MAX_EX 255 +#endif + +#include "lwip/dhcp.h" +#include "lwip/dhcp6.h" +#include "lwip/prot/dhcp.h" +#include "lwip/prot/dhcp6.h" + +static u8_t lwip_ioctl_internal_SIOCSIFADDR_6(struct ifreq *ifr) +{ + (void)ifr; + return ENOSYS; +} + +#ifdef LOSCFG_NET_CONTAINER +static u8_t lwip_ioctl_internal_SIOCSIFADDR(struct ifreq *ifr, struct net_group *group) +#else +static u8_t lwip_ioctl_internal_SIOCSIFADDR(struct ifreq *ifr) +#endif +{ + struct netif *netif = NULL; + + struct netif *loc_netif = NULL; + ip_addr_t taget_addr; + u16_t taget_port; + SOCKADDR_TO_IPADDR_PORT(&ifr->ifr_addr, &taget_addr, taget_port); + +#if LWIP_ENABLE_NET_CAPABILITY + if (!IsCapPermit(CAP_NET_ADMIN)) { + return EPERM; + } +#endif + + /* set netif ipaddr */ + netif = netif_find(ifr->ifr_name); + if (netif == NULL) { + return ENODEV; + } +#if LWIP_HAVE_LOOPIF + else if (netif->link_layer_type == LOOPBACK_IF) { + return EPERM; + } +#endif + else { + /* check the address is not multicast/broadcast/0/loopback */ + if (!IP_IS_V4(&taget_addr) || ip_addr_ismulticast(&taget_addr) || + ip_addr_isbroadcast(&taget_addr, netif) || + ip_addr_isany(&taget_addr) || + ip_addr_isloopback(&taget_addr)) { + return EINVAL; + } + + /* reset gateway if new and previous ipaddr not in same net */ + if (ip_addr_netcmp(&taget_addr, &netif->ip_addr, ip_2_ip4(&netif->netmask)) == 0) { + ip_addr_set_zero(&netif->gw); +#ifdef LOSCFG_NET_CONTAINER + if (netif == group->netif_default) { + (void)netif_set_default(NULL, group); +#else + if (netif == netif_default) { + (void)netif_set_default(NULL); +#endif + } + } + + /* lwip disallow two netif sit in same net at the same time */ +#ifdef LOSCFG_NET_CONTAINER + loc_netif = group->netif_list; +#else + loc_netif = netif_list; +#endif + while (loc_netif != NULL) { + if (loc_netif == netif) { + loc_netif = loc_netif->next; + continue; + } + if (ip_addr_cmp(&netif->netmask, &loc_netif->netmask) && + ip_addr_netcmp(&loc_netif->ip_addr, &taget_addr, + ip_2_ip4(&netif->netmask))) { + return EINVAL; + } + loc_netif = loc_netif->next; + } + +#if LWIP_DHCP + if ((netif_dhcp_data(netif) != NULL) && + (netif_dhcp_data(netif)->state != DHCP_STATE_OFF)) { + (void)netif_dhcp_off(netif); + } +#endif + +#if LWIP_ARP + /* clear ARP cache when IP address changed */ + if ((netif->flags & NETIF_FLAG_ETHARP) != 0) { + etharp_cleanup_netif(netif); + } +#endif /* LWIP_ARP */ + + netif_set_ipaddr(netif, ip_2_ip4(&taget_addr)); + + return 0; + } +} + +static u8_t lwip_ioctl_internal_SIOCDIFADDR_6(struct ifreq *ifr) +{ + (void)ifr; + return ENOSYS; +} + +#ifdef LOSCFG_NET_CONTAINER +static u8_t lwip_ioctl_internal_SIOCDIFADDR(struct ifreq *ifr, struct net_group *group) +#else +static u8_t lwip_ioctl_internal_SIOCDIFADDR(struct ifreq *ifr) +#endif +{ + struct netif *netif = NULL; + + ip_addr_t target_addr; + u16_t target_port; + + SOCKADDR_TO_IPADDR_PORT(&ifr->ifr_addr, &target_addr, target_port); + +#if LWIP_ENABLE_NET_CAPABILITY + if (!IsCapPermit(CAP_NET_ADMIN)) { + return EPERM; + } +#endif + + /* set netif ipaddr */ + netif = netif_find(ifr->ifr_name); + if (netif == NULL) { + return ENODEV; + } +#if LWIP_HAVE_LOOPIF + else if (netif->link_layer_type == LOOPBACK_IF) { + return EPERM; + } +#endif + + /* check the address is not loopback */ + if (!IP_IS_V4(&target_addr) || ip_addr_isloopback(&target_addr)) { + return EINVAL; + } + +#if LWIP_DHCP + if ((netif_dhcp_data(netif) != NULL) && + (netif_dhcp_data(netif)->state != DHCP_STATE_OFF)) { + (void)netif_dhcp_off(netif); + } +#endif + + ip_addr_set_zero(&netif->gw); + ip_addr_set_zero(&netif->ip_addr); + ip_addr_set_zero(&netif->netmask); +#ifdef LOSCFG_NET_CONTAINER + if (netif == group->netif_default) { + (void)netif_set_default(NULL, group); +#else + if (netif == netif_default) { + (void)netif_set_default(NULL); +#endif + } + +#if LWIP_IPV4 && LWIP_ARP + if ((netif->flags & NETIF_FLAG_ETHARP) != 0) { + etharp_cleanup_netif(netif); + } +#endif /* LWIP_IPV4 && LWIP_ARP */ + + return ERR_OK; +} + +static u8_t lwip_ioctl_internal_SIOCGIFNETMASK(struct ifreq *ifr) +{ + struct netif *netif = NULL; + struct sockaddr_in *sock_in = NULL; + + /* get netif netmask */ + netif = netif_find(ifr->ifr_name); + if (netif == NULL) { + return ENODEV; + } else { + sock_in = (struct sockaddr_in *)&ifr->ifr_netmask; + sock_in->sin_family = AF_INET; + sock_in->sin_addr.s_addr = ip_2_ip4(&netif->netmask)->addr; + return 0; + } +} + +#ifdef LOSCFG_NET_CONTAINER +static u8_t lwip_ioctl_internal_SIOCSIFNETMASK(struct ifreq *ifr, struct net_group *group) +#else +static u8_t lwip_ioctl_internal_SIOCSIFNETMASK(struct ifreq *ifr) +#endif +{ + struct netif *netif = NULL; + + struct netif *loc_netif = NULL; + ip_addr_t taget_addr; + u16_t taget_port; + SOCKADDR_TO_IPADDR_PORT(&ifr->ifr_addr, &taget_addr, taget_port); + +#if LWIP_ENABLE_NET_CAPABILITY + if (!IsCapPermit(CAP_NET_ADMIN)) { + return EPERM; + } +#endif + + if (!IP_IS_V4(&taget_addr)) { + return EINVAL; + } + + /* set netif netmask */ + netif = netif_find(ifr->ifr_name); + if (netif == NULL) { + return ENODEV; + } +#if LWIP_HAVE_LOOPIF + else if (netif->link_layer_type == LOOPBACK_IF) { + return EPERM; + } +#endif + else { + if (ip_addr_cmp(&netif->netmask, &taget_addr)) { + return 0; + } + /* check data valid */ +#ifdef LOSCFG_NET_CONTAINER + if (ip_addr_netmask_valid(ip_2_ip4(&taget_addr)) == 0) { +#else + if (ip_addr_netmask_valid(ip_2_ip4(&taget_addr)) != 0) { +#endif + return EINVAL; + } + + /* lwip disallow two netif sit in same net at the same time */ +#ifdef LOSCFG_NET_CONTAINER + loc_netif = group->netif_list; +#else + loc_netif = netif_list; +#endif + while (loc_netif != NULL) { + if (loc_netif == netif) { + loc_netif = loc_netif->next; + continue; + } + if (ip_addr_cmp(&loc_netif->netmask, &taget_addr) && + ip_addr_netcmp(&loc_netif->ip_addr, + &netif->ip_addr, ip_2_ip4(&loc_netif->netmask))) { + return EINVAL; + } + loc_netif = loc_netif->next; + } + +#if LWIP_DHCP + if ((netif_dhcp_data(netif) != NULL) && + (netif_dhcp_data(netif)->state != DHCP_STATE_OFF)) { + (void)netif_dhcp_off(netif); + } +#endif + + netif_set_netmask(netif, ip_2_ip4(&taget_addr)); + + /* check if gateway still reachable */ + if (!ip_addr_netcmp(&netif->gw, &netif->ip_addr, ip_2_ip4(&taget_addr))) { + ip_addr_set_zero(&(netif->gw)); +#ifdef LOSCFG_NET_CONTAINER + if (netif == group->netif_default) { + (void)netif_set_default(NULL, group); +#else + if (netif == netif_default) { + (void)netif_set_default(NULL); +#endif + } + } + return 0; + } +} + +static u8_t lwip_ioctl_internal_SIOCSIFHWADDR(struct ifreq *ifr) +{ + struct netif *netif = NULL; + err_t ret; + +#if LWIP_ENABLE_NET_CAPABILITY + if (!IsCapPermit(CAP_NET_ADMIN)) { + return EPERM; + } +#endif + + /* set netif hw addr */ + netif = netif_find(ifr->ifr_name); + if (netif == NULL) { + return ENODEV; + } +#if LWIP_HAVE_LOOPIF + else if (netif->link_layer_type == LOOPBACK_IF) { + return EPERM; + } +#endif + else { + /* bring netif down to clear all Neighbor Cache Entry */ + (void)netif_set_down(netif); + + ret = netif_set_hwaddr(netif, (const unsigned char *)ifr->ifr_hwaddr.sa_data, netif->hwaddr_len); + if (ret != ERR_OK) { + (void)netif_set_up(netif); + return err_to_errno(ret); + } + + /* + * bring netif up to try to send GARP/IGMP/NA/MLD/RS. GARP and NA would + * make the neighboring nodes update their Neighbor Cache immediately. + */ + (void)netif_set_up(netif); + return 0; + } +} + +static u8_t lwip_ioctl_internal_SIOCGIFHWADDR(struct ifreq *ifr) +{ + struct netif *netif = NULL; + + /* get netif hw addr */ + netif = netif_find(ifr->ifr_name); + if (netif == NULL) { + return ENODEV; + } +#if LWIP_HAVE_LOOPIF + else if (netif->link_layer_type == LOOPBACK_IF) { + return EPERM; + } +#endif /* LWIP_HAVE_LOOPIF */ + else { + if (memcpy_s((void *)ifr->ifr_hwaddr.sa_data, sizeof(ifr->ifr_hwaddr.sa_data), + (void *)netif->hwaddr, netif->hwaddr_len) != EOK) { + return EINVAL; + } + return 0; + } +} + +static u8_t lwip_ioctl_internal_SIOCSIFFLAGS(struct ifreq *ifr) +{ + struct netif *netif = NULL; + +#if LWIP_ENABLE_NET_CAPABILITY + if (!IsCapPermit(CAP_NET_ADMIN)) { + return EPERM; + } +#endif + + /* set netif hw addr */ + netif = netif_find(ifr->ifr_name); + if (netif == NULL) { + return ENODEV; + } +#if LWIP_HAVE_LOOPIF + else if (netif->link_layer_type == LOOPBACK_IF) { + return EPERM; + } +#endif /* LWIP_HAVE_LOOPIF */ + else { + if (((unsigned short)ifr->ifr_flags & IFF_UP) && !(netif->flags & NETIF_FLAG_UP)) { + (void)netif_set_up(netif); + } else if (!((unsigned short)ifr->ifr_flags & IFF_UP) && (netif->flags & NETIF_FLAG_UP)) { + (void)netif_set_down(netif); + } + if (((unsigned short)ifr->ifr_flags & IFF_RUNNING) && !(netif->flags & NETIF_FLAG_LINK_UP)) { + (void)netif_set_link_up(netif); + } else if (!((unsigned short)ifr->ifr_flags & IFF_RUNNING) && (netif->flags & NETIF_FLAG_LINK_UP)) { + (void)netif_set_link_down(netif); + } + + if ((unsigned short)ifr->ifr_flags & IFF_BROADCAST) { + netif->flags |= NETIF_FLAG_BROADCAST; + } else { + netif->flags = netif->flags & (~NETIF_FLAG_BROADCAST); + } + if ((unsigned short)ifr->ifr_flags & IFF_NOARP) { + netif->flags = (netif->flags & (~NETIF_FLAG_ETHARP)); + } else { + netif->flags |= NETIF_FLAG_ETHARP; + } + + if ((unsigned short)ifr->ifr_flags & IFF_MULTICAST) { +#if LWIP_IGMP + netif->flags |= NETIF_FLAG_IGMP; +#endif /* LWIP_IGMP */ +#if LWIP_IPV6 && LWIP_IPV6_MLD + netif->flags |= NETIF_FLAG_MLD6; +#endif /* LWIP_IPV6_MLD */ + } else { +#if LWIP_IGMP + netif->flags = (netif->flags & ~NETIF_FLAG_IGMP); +#endif /* LWIP_IGMP */ +#if LWIP_IPV6 && LWIP_IPV6_MLD + netif->flags = (netif->flags & ~NETIF_FLAG_MLD6); +#endif /* LWIP_IPV6_MLD */ + } + +#if LWIP_DHCP + if ((unsigned short)ifr->ifr_flags & IFF_DYNAMIC) { + (void)dhcp_start(netif); + } else { + dhcp_stop(netif); +#if !LWIP_DHCP_SUBSTITUTE + dhcp_cleanup(netif); +#endif + } +#endif + +#if LWIP_NETIF_PROMISC + if (((unsigned short)ifr->ifr_flags & IFF_PROMISC)) { + netif->flags |= NETIF_FLAG_PROMISC; + } else { + netif->flags &= ~NETIF_FLAG_PROMISC; + } + if (netif->drv_config) { + netif->drv_config(netif, IFF_PROMISC, !!((unsigned short)ifr->ifr_flags & IFF_PROMISC)); + } +#endif /* LWIP_NETIF_PROMISC */ + return 0; + } +} + +static u8_t lwip_ioctl_internal_SIOCGIFFLAGS(struct ifreq *ifr) +{ + struct netif *netif = NULL; + + /* set netif hw addr */ + netif = netif_find(ifr->ifr_name); + if (netif == NULL) { + return ENODEV; + } else { + if (netif->flags & NETIF_FLAG_UP) { + ifr->ifr_flags = ((unsigned short)(ifr->ifr_flags)) | IFF_UP; + } else { + ifr->ifr_flags = ((unsigned short)(ifr->ifr_flags)) & ~IFF_UP; + } + if (netif->flags & NETIF_FLAG_LINK_UP) { + ifr->ifr_flags = ((unsigned short)(ifr->ifr_flags)) | IFF_RUNNING; + } else { + ifr->ifr_flags = ((unsigned short)(ifr->ifr_flags)) & ~IFF_RUNNING; + } + if (netif->flags & NETIF_FLAG_BROADCAST) { + ifr->ifr_flags = ((unsigned short)(ifr->ifr_flags)) | IFF_BROADCAST; + } else { + ifr->ifr_flags = ((unsigned short)(ifr->ifr_flags)) & ~IFF_BROADCAST; + } + if (netif->flags & NETIF_FLAG_ETHARP) { + ifr->ifr_flags = ((unsigned short)(ifr->ifr_flags)) & ~IFF_NOARP; + } else { + ifr->ifr_flags = ((unsigned short)(ifr->ifr_flags)) | IFF_NOARP; + } + +#if LWIP_IGMP || LWIP_IPV6_MLD + if ( +#if LWIP_IGMP + (netif->flags & NETIF_FLAG_IGMP) +#endif /* LWIP_IGMP */ +#if LWIP_IGMP && LWIP_IPV6_MLD + || +#endif /* LWIP_IGMP && LWIP_IPV6_MLD */ +#if LWIP_IPV6_MLD + (netif->flags & NETIF_FLAG_MLD6) +#endif /* LWIP_IPV6_MLD */ + ) { + ifr->ifr_flags = (short)((unsigned short)ifr->ifr_flags | IFF_MULTICAST); + } else { + ifr->ifr_flags = (short)((unsigned short)ifr->ifr_flags & (~IFF_MULTICAST)); + } +#endif /* LWIP_IGMP || LWIP_IPV6_MLD */ + +#if LWIP_DHCP + if (dhcp_supplied_address(netif)) { + ifr->ifr_flags = (short)((unsigned short)ifr->ifr_flags | IFF_DYNAMIC); + } else { + ifr->ifr_flags = (short)((unsigned short)ifr->ifr_flags & (~IFF_DYNAMIC)); + } +#endif + +#if LWIP_HAVE_LOOPIF + if (netif->link_layer_type == LOOPBACK_IF) { + ifr->ifr_flags = ((unsigned short)(ifr->ifr_flags)) | IFF_LOOPBACK; + } +#endif + +#if LWIP_NETIF_PROMISC + if (netif->flags & NETIF_FLAG_PROMISC) { + ifr->ifr_flags = ((unsigned short)(ifr->ifr_flags)) | IFF_PROMISC; + } else { + ifr->ifr_flags = ((unsigned short)(ifr->ifr_flags)) & ~IFF_PROMISC; + } +#endif /* LWIP_NETIF_PROMISC */ + + return 0; + } +} + +#ifdef LOSCFG_NET_CONTAINER +static u8_t lwip_ioctl_internal_SIOCGIFNAME(struct ifreq *ifr, struct net_group *group) +#else +static u8_t lwip_ioctl_internal_SIOCGIFNAME(struct ifreq *ifr) +#endif +{ + struct netif *netif = NULL; + int ret; +#ifdef LOSCFG_NET_CONTAINER + for (netif = group->netif_list; netif != NULL; netif = netif->next) { +#else + for (netif = netif_list; netif != NULL; netif = netif->next) { +#endif + if (ifr->ifr_ifindex == netif_get_index(netif)) { + break; + } + } + + if (netif == NULL) { + return ENODEV; + } else { + if (netif->link_layer_type == LOOPBACK_IF) { + ret = snprintf_s(ifr->ifr_name, IFNAMSIZ, (IFNAMSIZ - 1), "%.2s", netif->name); + if ((ret <= 0) || (ret >= IFNAMSIZ)) { + return ENOBUFS; + } + } else { + ret = snprintf_s(ifr->ifr_name, IFNAMSIZ, (IFNAMSIZ - 1), "%s", netif_get_name(netif)); + if ((ret <= 0) || (ret >= IFNAMSIZ)) { + return ENOBUFS; + } + } + return 0; + } +} + +static bool lwip_validate_ifname(const char *name, u8_t *let_pos) +{ + unsigned short num_pos = 0; + unsigned short letter_pos = 0; + unsigned short pos = 0; + bool have_num = 0; + + /* if the first position of variable name is not letter, such as '6eth2' */ + if (((*name >= 'a') && (*name <= 'z')) || ((*name >= 'A') && (*name <= 'Z'))) { + return 0; + } + + /* check if the position of letter is bigger than the the position of digital */ + while (*name != '\0') { + if ((*name >= '0') && (*name <= '9')) { + num_pos = pos; + have_num = 1; + } else if (((*name >= 'a') && (*name <= 'z')) || ((*name >= 'A') && (*name <= 'Z'))) { + letter_pos = pos; + if (have_num != 0) { + return 0; + } + } else { + return 0; + } + pos++; + name++; + } + + /* for the speacil case as all position of variable name is letter, such as 'ethabc' */ + if (num_pos == 0) { + return 0; + } + + /* cheak if the digital in the variable name is bigger than 255, such as 'eth266' */ + if (atoi(name - (pos - letter_pos - 1)) > 255) { + return 0; + } + + *let_pos = (u8_t)letter_pos; + + return 1; +} + +static u8_t lwip_ioctl_internal_SIOCSIFNAME(struct ifreq *ifr) +{ + struct netif *netif = NULL; + u8_t letter_pos = 0; + +#if LWIP_ENABLE_NET_CAPABILITY + if (!IsCapPermit(CAP_NET_ADMIN)) { + return EPERM; + } +#endif + + netif = netif_find(ifr->ifr_name); + if (netif == NULL) { + return ENODEV; + } else if (netif->link_layer_type == LOOPBACK_IF) { + return EPERM; + } else if ((netif->flags & IFF_UP) != 0) { + return EBUSY; + } else { + if (strncmp(ifr->ifr_name, ifr->ifr_newname, IFNAMSIZ) == 0) { + /* not change */ + return 0; + } + + ifr->ifr_newname[IFNAMSIZ - 1] = '\0'; + if ((lwip_validate_ifname(ifr->ifr_newname, &letter_pos) == 0) || (strlen(ifr->ifr_newname) > (IFNAMSIZ - 1))) { + return EINVAL; + } + + if (strncpy_s(netif->full_name, sizeof(netif->full_name), ifr->ifr_newname, strlen(ifr->ifr_newname)) != EOK) { + return EINVAL; + } + } + + return 0; +} + +static u8_t lwip_ioctl_internal_SIOCGIFINDEX(struct ifreq *ifr) +{ + struct netif *netif = NULL; + + netif = netif_find(ifr->ifr_name); + if (netif == NULL) { + return ENODEV; + } else { + ifr->ifr_ifindex = netif_get_index(netif); + return 0; + } +} + +static u8_t lwip_ioctl_internal_SIOCSIFMTU(struct ifreq *ifr) +{ + struct netif *netif = NULL; + +#if LWIP_ENABLE_NET_CAPABILITY + if (!IsCapPermit(CAP_NET_ADMIN)) { + return EPERM; + } +#endif + + /* set netif hw addr */ + netif = netif_find(ifr->ifr_name); + if (netif == NULL) { + return ENODEV; + } +#if LWIP_HAVE_LOOPIF + /* the mtu of loopif is not used. */ + else if (netif->link_layer_type == LOOPBACK_IF) { + return EPERM; + } +#endif + else { + if (ERR_OK != netif_set_mtu(netif, (u16_t)ifr->ifr_mtu)) { + return EINVAL; + } + + return 0; + } +} + +static u8_t lwip_ioctl_internal_SIOCGIFMTU(struct ifreq *ifr) +{ + struct netif *netif = NULL; + + /* get netif hw addr */ + netif = netif_find(ifr->ifr_name); + if (netif == NULL) { + return ENODEV; + } else { + ifr->ifr_mtu = netif->mtu; + return 0; + } +} + +static u8_t lwip_ioctl_internal_SIOCGIFBRDADDR(struct ifreq *ifr) +{ + struct netif *netif = NULL; + struct sockaddr_in *sock_in = NULL; + + /* get netif subnet broadcast addr */ + netif = netif_find(ifr->ifr_name); + if (netif == NULL) { + return ENODEV; + } + if (ip4_addr_isany_val(*(ip_2_ip4(&netif->netmask)))) { + return ENXIO; + } + sock_in = (struct sockaddr_in *)&ifr->ifr_addr; + sock_in->sin_family = AF_INET; + sock_in->sin_addr.s_addr = (ip_2_ip4(&((netif)->ip_addr))->addr | ~(ip_2_ip4(&netif->netmask)->addr)); + return 0; +} + +#endif /* LWIP_IOCTL_IF */ + +#if LWIP_NETIF_ETHTOOL + +static s32_t lwip_ioctl_internal_SIOCETHTOOL(struct ifreq *ifr) +{ + struct netif *netif; + +#if LWIP_ENABLE_NET_CAPABILITY + if (!IsCapPermit(CAP_NET_ADMIN)) { + return EPERM; + } +#endif + + netif = netif_find(ifr->ifr_name); + if (netif == NULL) { + return ENODEV; + } else { + return dev_ethtool(netif, ifr); + } +} + +#endif + +#if LWIP_IPV6 +#if LWIP_IPV6_DUP_DETECT_ATTEMPTS + +static u8_t lwip_ioctl_internal_SIOCSIPV6DAD(struct ifreq *ifr) +{ +#if LWIP_ENABLE_NET_CAPABILITY + if (!IsCapPermit(CAP_NET_ADMIN)) { + return EPERM; + } +#endif + + struct netif *tmpnetif = netif_find(ifr->ifr_name); + if (tmpnetif == NULL) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("Interface not found.\n")); + return ENODEV; + } + + if ((ifr->ifr_ifru.ifru_ivalue != 0) && (ifr->ifr_ifru.ifru_ivalue != 1)) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("Invalid ioctl argument(ifru_ivalue 0/1).\n")); + return EBADRQC; + } + + if (ifr->ifr_ifru.ifru_ivalue == 1) { + tmpnetif->ipv6_flags = (tmpnetif->ipv6_flags | LWIP_IPV6_ND6_FLAG_DAD); + + LWIP_DEBUGF(SOCKETS_DEBUG, ("DAD turned on through ioctl for %s iface index %u \n", + tmpnetif->name, tmpnetif->num)); + } else { + tmpnetif->ipv6_flags = (tmpnetif->ipv6_flags & ((~LWIP_IPV6_ND6_FLAG_DAD) & 0xffU)); + + LWIP_DEBUGF(SOCKETS_DEBUG, ("DAD turned off through ioctl for %s iface index %u \n", + tmpnetif->name, tmpnetif->num)); + } + return 0; +} + +static u8_t lwip_ioctl_internal_SIOCGIPV6DAD(struct ifreq *ifr) +{ + struct netif *tmpnetif = netif_find(ifr->ifr_name); + if (tmpnetif == NULL) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("Interface not found.\n")); + return ENODEV; + } + ifr->ifr_ifru.ifru_ivalue = (tmpnetif->ipv6_flags & LWIP_IPV6_ND6_FLAG_DAD) ? 1 : 0; + return 0; +} + +#endif + +#if LWIP_IOCTL_IPV6DPCTD + +static u8_t lwip_ioctl_internal_SIOCSIPV6DPCTD(struct ifreq *ifr) +{ +#if LWIP_ENABLE_NET_CAPABILITY + if (!IsCapPermit(CAP_NET_ADMIN)) { + return EPERM; + } +#endif + + struct netif *tmpnetif = netif_find(ifr->ifr_name); + if (tmpnetif == NULL) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("Interface not found.\n")); + return ENODEV; + } + if ((ifr->ifr_ifru.ifru_ivalue != 0) && (ifr->ifr_ifru.ifru_ivalue != 1)) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("Invalid ioctl argument(ifru_ivalue 0/1).\n")); + return EBADRQC; + } + if (ifr->ifr_ifru.ifru_ivalue == 1) { + tmpnetif->ipv6_flags = (tmpnetif->ipv6_flags | LWIP_IPV6_ND6_FLAG_DEPRECATED); + LWIP_DEBUGF(SOCKETS_DEBUG, ("Deprecation turned on through ioctl for %s iface index %u \n", + tmpnetif->name, tmpnetif->num)); + } else { + tmpnetif->ipv6_flags = (tmpnetif->ipv6_flags & ((~LWIP_IPV6_ND6_FLAG_DEPRECATED) & 0xffU)); + LWIP_DEBUGF(SOCKETS_DEBUG, ("Deprecation turned off through ioctl for %s iface index %u \n", + tmpnetif->name, tmpnetif->num)); + } + return 0; +} + +static u8_t lwip_ioctl_internal_SIOCGIPV6DPCTD(struct ifreq *ifr) +{ + struct netif *tmpnetif = netif_find(ifr->ifr_name); + if (tmpnetif == NULL) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("Interface not found.\n")); + return ENODEV; + } + + ifr->ifr_ifru.ifru_ivalue = (tmpnetif->ipv6_flags & LWIP_IPV6_ND6_FLAG_DEPRECATED) ? 1 : 0; + return 0; +} + +#endif /* LWIP_IOCTL_IPV6DPCTD */ +#endif + +static u8_t lwip_ioctl_impl(const struct lwip_sock *sock, long cmd, void *argp) +{ + u8_t err = 0; +#if LWIP_NETIF_ETHTOOL + s32_t ret; +#endif +#if LWIP_IPV6_DUP_DETECT_ATTEMPTS || LWIP_IOCTL_IPV6DPCTD || LWIP_IOCTL_IF || LWIP_NETIF_ETHTOOL + struct ifreq *ifr = (struct ifreq *)argp; +#endif +#if LWIP_IOCTL_ROUTE + struct rtentry *rmten = (struct rtentry *)argp; +#endif +#if LWIP_IPV6_DUP_DETECT_ATTEMPTS || LWIP_IOCTL_IPV6DPCTD || LWIP_IOCTL_ROUTE || LWIP_IOCTL_IF + bool is_ipv6 = 0; + + /* allow it only on IPv6 sockets... */ + is_ipv6 = NETCONNTYPE_ISIPV6((unsigned int)(sock->conn->type)); +#endif +#ifdef LOSCFG_NET_CONTAINER + struct net_group *group = get_net_group_from_ippcb(sock->conn->pcb.ip); +#endif + switch ((u32_t)cmd) { +#if LWIP_IPV6 +#if LWIP_IPV6_DUP_DETECT_ATTEMPTS + case SIOCSIPV6DAD: + /* allow it only on IPv6 sockets... */ + if (is_ipv6 == 0) { + err = EINVAL; + } else { + err = lwip_ioctl_internal_SIOCSIPV6DAD(ifr); + } + break; + case SIOCGIPV6DAD: + /* allow it only on IPv6 sockets... */ + if (is_ipv6 == 0) { + err = EINVAL; + } else { + err = lwip_ioctl_internal_SIOCGIPV6DAD(ifr); + } + break; +#endif /* LWIP_IPV6_DUP_DETECT_ATTEMPTS */ +#if LWIP_IOCTL_IPV6DPCTD + case SIOCSIPV6DPCTD: + /* allow it only on IPv6 sockets... */ + if (is_ipv6 == 0) { + err = EINVAL; + } else { + err = lwip_ioctl_internal_SIOCSIPV6DPCTD(ifr); + } + break; + case SIOCGIPV6DPCTD: + /* allow it only on IPv6 sockets... */ + if (is_ipv6 == 0) { + err = EINVAL; + } else { + err = lwip_ioctl_internal_SIOCGIPV6DPCTD(ifr); + } + break; +#endif +#endif /* LWIP_IPV6 */ +#if LWIP_IOCTL_ROUTE + case SIOCADDRT: + /* Do not allow if socket is AF_INET6 */ + if (is_ipv6 != 0) { + err = EINVAL; + } else { +#ifdef LOSCFG_NET_CONTAINER + err = lwip_ioctl_internal_SIOCADDRT(rmten, group); +#else + err = lwip_ioctl_internal_SIOCADDRT(rmten); +#endif + } + break; +#endif +#if LWIP_IOCTL_IF + case SIOCGIFCONF: + /* Do not allow if socket is AF_INET6 */ + if (is_ipv6 != 0) { + err = EINVAL; + } else { +#ifdef LOSCFG_NET_CONTAINER + err = lwip_ioctl_internal_SIOCGIFCONF(ifr, group); +#else + err = lwip_ioctl_internal_SIOCGIFCONF(ifr); +#endif + } + break; + case SIOCGIFADDR: + if (is_ipv6 != 0) { + err = EINVAL; + } else { + err = lwip_ioctl_internal_SIOCGIFADDR(ifr); + } + break; + case SIOCSIFADDR: + if (is_ipv6 != 0) { + err = lwip_ioctl_internal_SIOCSIFADDR_6(ifr); + } else { +#ifdef LOSCFG_NET_CONTAINER + err = lwip_ioctl_internal_SIOCSIFADDR(ifr, group); +#else + err = lwip_ioctl_internal_SIOCSIFADDR(ifr); +#endif + } + break; + case SIOCDIFADDR: + /* Delete interface address */ + if (is_ipv6 != 0) { + err = lwip_ioctl_internal_SIOCDIFADDR_6(ifr); + } else { +#ifdef LOSCFG_NET_CONTAINER + err = lwip_ioctl_internal_SIOCDIFADDR(ifr, group); +#else + err = lwip_ioctl_internal_SIOCDIFADDR(ifr); +#endif + } + break; + case SIOCGIFNETMASK: + if (is_ipv6 != 0) { + err = EINVAL; + } else { + err = lwip_ioctl_internal_SIOCGIFNETMASK(ifr); + } + break; + case SIOCSIFNETMASK: + if (is_ipv6 != 0) { + err = EINVAL; + } else { +#ifdef LOSCFG_NET_CONTAINER + err = lwip_ioctl_internal_SIOCSIFNETMASK(ifr, group); +#else + err = lwip_ioctl_internal_SIOCSIFNETMASK(ifr); +#endif + } + break; + case SIOCSIFHWADDR: + err = lwip_ioctl_internal_SIOCSIFHWADDR(ifr); + break; + case SIOCGIFHWADDR: + err = lwip_ioctl_internal_SIOCGIFHWADDR(ifr); + break; + case SIOCSIFFLAGS: + err = lwip_ioctl_internal_SIOCSIFFLAGS(ifr); + break; + case SIOCGIFFLAGS: + err = lwip_ioctl_internal_SIOCGIFFLAGS(ifr); + break; + case SIOCGIFNAME: +#ifdef LOSCFG_NET_CONTAINER + err = lwip_ioctl_internal_SIOCGIFNAME(ifr, group); +#else + err = lwip_ioctl_internal_SIOCGIFNAME(ifr); +#endif + break; + case SIOCSIFNAME: + err = lwip_ioctl_internal_SIOCSIFNAME(ifr); + break; + /* Need to support the get index through ioctl + * As of now the options is restricted to PF_PACKET scenario , so removed the compiler flag Begin + */ + case SIOCGIFINDEX: + err = lwip_ioctl_internal_SIOCGIFINDEX(ifr); + break; + case SIOCGIFMTU: + err = lwip_ioctl_internal_SIOCGIFMTU(ifr); + break; + case SIOCSIFMTU: + err = lwip_ioctl_internal_SIOCSIFMTU(ifr); + break; + case SIOCGIFBRDADDR: + if (is_ipv6 != 0) { + err = EINVAL; + } else { + err = lwip_ioctl_internal_SIOCGIFBRDADDR(ifr); + } + break; +#endif /* LWIP_IOCTL_IF */ +#if LWIP_NETIF_ETHTOOL + case SIOCETHTOOL: + ret = lwip_ioctl_internal_SIOCETHTOOL(ifr); + if (ret != 0) { + /* an IO error happened */ + err = EIO; + } + break; +#endif + /* START For cmd = -1 stack has to treat it as Invalid Input and return EINVAL */ + case 0xFFFFFFFF: + err = EINVAL; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl_impl(INVALID: 0x%lx)\n", cmd)); + break; + default: + err = ENOSYS; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(UNIMPL: 0x%lx)\n", cmd)); + break; + } + + return err; +} + +static err_t lwip_do_ioctl_impl(struct tcpip_api_call_data *call) +{ + struct lwip_ioctl_apimsg *msg = (struct lwip_ioctl_apimsg *)(void *)call; + return lwip_ioctl_impl(msg->sock, msg->cmd, msg->argp); +} + +#include "los_vm_map.h" +#include "user_copy.h" +static int do_ioctl_SIOCGIFCONF(int sockfd, long cmd, void *argp) +{ + int nbytes; + struct ifconf ifc; + char *buf_bak = NULL; + int ret; + + if (LOS_ArchCopyFromUser(&ifc, argp, sizeof(struct ifconf)) != 0) { + set_errno(EFAULT); + return -1; + } + nbytes = ifc.ifc_len; + if (nbytes <= 0) { + set_errno(EINVAL); + return -1; + } + buf_bak = ifc.ifc_buf; + if (!LOS_IsUserAddress((VADDR_T)(uintptr_t)buf_bak)) { + set_errno(EFAULT); + return -1; + } + ifc.ifc_buf = malloc(nbytes); + if (ifc.ifc_buf == NULL) { + set_errno(ENOMEM); + return -1; + } + (void)memset_s(ifc.ifc_buf, nbytes, 0, nbytes); + + ret = lwip_ioctl(sockfd, cmd, &ifc); + if (ret == 0) { + if (LOS_ArchCopyToUser(buf_bak, ifc.ifc_buf, nbytes) != 0) { + set_errno(EFAULT); + ret = -1; + } + } + + free(ifc.ifc_buf); + ifc.ifc_buf = buf_bak; + if (LOS_ArchCopyToUser(argp, &ifc, sizeof(struct ifconf)) != 0) { + set_errno(EFAULT); + ret = -1; + } + return ret; +} + +int socks_ioctl(int sockfd, long cmd, void *argp) +{ + void *argpbak = argp; + int ret; + size_t nbytes = 0; + + if (LOS_IsUserAddress((VADDR_T)(uintptr_t)argp)) { + switch (cmd) { + case FIONREAD: + case FIONBIO: + nbytes = sizeof(int); + break; + case SIOCADDRT: + nbytes = sizeof(struct rtentry); + break; + case SIOCGIFCONF: + return do_ioctl_SIOCGIFCONF(sockfd, cmd, argp); + case SIOCSIPV6DAD: + case SIOCGIPV6DAD: + case SIOCSIPV6DPCTD: + case SIOCGIPV6DPCTD: + case SIOCGIFADDR: + case SIOCSIFADDR: + case SIOCDIFADDR: + case SIOCGIFNETMASK: + case SIOCSIFNETMASK: + case SIOCSIFHWADDR: + case SIOCGIFHWADDR: + case SIOCSIFFLAGS: + case SIOCGIFFLAGS: + case SIOCGIFNAME: + case SIOCSIFNAME: + case SIOCGIFINDEX: + case SIOCGIFMTU: + case SIOCSIFMTU: + case SIOCETHTOOL: + case SIOCGIFBRDADDR: + nbytes = sizeof(struct ifreq); + break; + default: + nbytes = 0; + } + if (argp != NULL && nbytes > 0) { + argp = malloc(nbytes); + if (argp == NULL) { + set_errno(ENOMEM); + return -1; + } + if (LOS_ArchCopyFromUser(argp, argpbak, nbytes) != 0) { + free(argp); + set_errno(EFAULT); + return -1; + } + } + } + ret = lwip_ioctl(sockfd, cmd, argp); + if (ret == 0 && argp != argpbak) { + if (LOS_ArchCopyToUser(argpbak, argp, nbytes) != 0) { + /* how to rollback ioctl ? */ + set_errno(EFAULT); + ret = -1; + } + } + if (argp != argpbak) { + free(argp); + } + return ret; +} + +void socks_refer(int sockfd) +{ + struct lwip_sock *sock = NULL; + SYS_ARCH_DECL_PROTECT(lev); + + sock = get_socket(sockfd); + if (!sock) { + return; + } + + SYS_ARCH_PROTECT(lev); + + sock->s_refcount++; + + SYS_ARCH_UNPROTECT(lev); + + done_socket(sock); +} + +int socks_close(int sockfd) +{ + struct lwip_sock *sock = NULL; + SYS_ARCH_DECL_PROTECT(lev); + + sock = get_socket(sockfd); + if (!sock) { + return -1; + } + + SYS_ARCH_PROTECT(lev); + + if (sock->s_refcount == 0) { + SYS_ARCH_UNPROTECT(lev); + done_socket(sock); + return lwip_close(sockfd); + } + + sock->s_refcount--; + + SYS_ARCH_UNPROTECT(lev); + done_socket(sock); + return 0; +} diff --git a/src/kernel_liteos_a/net/lwip-2.1/porting/src/sys_arch.c b/src/kernel_liteos_a/net/lwip-2.1/porting/src/sys_arch.c new file mode 100644 index 00000000..5ea9bb4a --- /dev/null +++ b/src/kernel_liteos_a/net/lwip-2.1/porting/src/sys_arch.c @@ -0,0 +1,334 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef LOSCFG_KERNEL_SMP +SPIN_LOCK_INIT(arch_protect_spin); +static u32_t lwprot_thread = LOS_ERRNO_TSK_ID_INVALID; +static int lwprot_count = 0; +#endif /* LOSCFG_KERNEL_SMP */ + +#define ROUND_UP_DIV(val, div) (((val) + (div) - 1) / (div)) + +/** + * Thread and System misc + */ + +sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stackSize, int prio) +{ + UINT32 taskID = LOS_ERRNO_TSK_ID_INVALID; + UINT32 ret; + TSK_INIT_PARAM_S task = {0}; + + /* Create host Task */ + task.pfnTaskEntry = (TSK_ENTRY_FUNC)thread; + task.uwStackSize = stackSize; + task.pcName = (char *)name; + task.usTaskPrio = prio; + task.auwArgs[0] = (UINTPTR)arg; + task.uwResved = LOS_TASK_STATUS_DETACHED; + ret = LOS_TaskCreate(&taskID, &task); + if (ret != LOS_OK) { + LWIP_DEBUGF(SYS_DEBUG, ("sys_thread_new: LOS_TaskCreate error %u\n", ret)); + return -1; + } + + return taskID; +} + +void sys_init(void) +{ + /* set rand seed to make random sequence diff on every startup */ + UINT32 seedhsb, seedlsb; + LOS_GetCpuCycle(&seedhsb, &seedlsb); + srand(seedlsb); +} + +u32_t sys_now(void) +{ + /* Lwip docs mentioned like wraparound is not a problem in this function */ + return (u32_t)((LOS_TickCountGet() * OS_SYS_MS_PER_SECOND) / LOSCFG_BASE_CORE_TICK_PER_SECOND); +} + +#if (LWIP_CHKSUM_ALGORITHM == 4) /* version #4, asm based */ +#include "in_cksum.h" +u16_t lwip_standard_chksum(const void *dataptr, int len) +{ + return ~(u16_t)(in_cksum(dataptr, len)); +} +#endif + + +/** + * Protector + */ + +sys_prot_t sys_arch_protect(void) +{ +#ifdef LOSCFG_KERNEL_SMP + /* Note that we are using spinlock instead of mutex for LiteOS-SMP here: + * 1. spinlock is more effective for short critical region protection. + * 2. this function is called only in task context, not in interrupt handler. + * so it's not needed to disable interrupt. + */ + if (lwprot_thread != LOS_CurTaskIDGet()) { + /* We are locking the spinlock where it has not been locked before + * or is being locked by another thread */ + LOS_SpinLock(&arch_protect_spin); + lwprot_thread = LOS_CurTaskIDGet(); + lwprot_count = 1; + } else { + /* It is already locked by THIS thread */ + lwprot_count++; + } +#else + LOS_TaskLock(); +#endif /* LOSCFG_KERNEL_SMP */ + return 0; /* return value is unused */ +} + +void sys_arch_unprotect(sys_prot_t pval) +{ + LWIP_UNUSED_ARG(pval); +#ifdef LOSCFG_KERNEL_SMP + if (lwprot_thread == LOS_CurTaskIDGet()) { + lwprot_count--; + if (lwprot_count == 0) { + lwprot_thread = LOS_ERRNO_TSK_ID_INVALID; + LOS_SpinUnlock(&arch_protect_spin); + } + } +#else + LOS_TaskUnlock(); +#endif /* LOSCFG_KERNEL_SMP */ +} + + +/** + * MessageBox + */ + +err_t sys_mbox_new(sys_mbox_t *mbox, int size) +{ + CHAR qName[] = "lwIP"; + UINT32 ret = LOS_QueueCreate(qName, (UINT16)size, mbox, 0, sizeof(void *)); + switch (ret) { + case LOS_OK: + return ERR_OK; + case LOS_ERRNO_QUEUE_CB_UNAVAILABLE: + case LOS_ERRNO_QUEUE_CREATE_NO_MEMORY: + return ERR_MEM; + default: + break; + } + LWIP_DEBUGF(SYS_DEBUG, ("%s: LOS_QueueCreate error %u\n", __FUNCTION__, ret)); + return ERR_ARG; +} + +void sys_mbox_post(sys_mbox_t *mbox, void *msg) +{ + /* Caution: the second parameter is NOT &msg */ + UINT32 ret = LOS_QueueWrite(*mbox, msg, sizeof(char *), LOS_WAIT_FOREVER); + if (ret != LOS_OK) { + LWIP_DEBUGF(SYS_DEBUG, ("%s: LOS_QueueWrite error %u\n", __FUNCTION__, ret)); + } +} + +err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg) +{ + /* Caution: the second parameter is NOT &msg */ + UINT32 ret = LOS_QueueWrite(*mbox, msg, sizeof(char *), 0); + switch (ret) { + case LOS_OK: + return ERR_OK; + case LOS_ERRNO_QUEUE_ISFULL: + return ERR_MEM; + default: + break; + } + LWIP_DEBUGF(SYS_DEBUG, ("%s: LOS_QueueWrite error %u\n", __FUNCTION__, ret)); + return ERR_ARG; +} + +err_t sys_mbox_trypost_fromisr(sys_mbox_t *mbox, void *msg); + +u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeoutMs) +{ + void *ignore = 0; /* if msg==NULL, the fetched msg should be dropped */ + UINT64 tick = ROUND_UP_DIV((UINT64)timeoutMs * LOSCFG_BASE_CORE_TICK_PER_SECOND, OS_SYS_MS_PER_SECOND); + UINT32 ret = LOS_QueueRead(*mbox, msg ? msg : &ignore, sizeof(void *), tick ? (UINT32)tick : LOS_WAIT_FOREVER); + switch (ret) { + case LOS_OK: + return ERR_OK; + case LOS_ERRNO_QUEUE_ISEMPTY: + case LOS_ERRNO_QUEUE_TIMEOUT: + return SYS_ARCH_TIMEOUT; + default: + break; + } + LWIP_DEBUGF(SYS_DEBUG, ("%s: LOS_QueueRead error %u\n", __FUNCTION__, ret)); + return SYS_ARCH_TIMEOUT; /* Errors should be treated as timeout */ +} + +u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) +{ + void *ignore = 0; /* if msg==NULL, the fetched msg should be dropped */ + UINT32 ret = LOS_QueueRead(*mbox, msg ? msg : &ignore, sizeof(void *), 0); + switch (ret) { + case LOS_OK: + return ERR_OK; + case LOS_ERRNO_QUEUE_ISEMPTY: + return SYS_MBOX_EMPTY; + case LOS_ERRNO_QUEUE_TIMEOUT: + return SYS_ARCH_TIMEOUT; + default: + break; + } + LWIP_DEBUGF(SYS_DEBUG, ("%s: LOS_QueueRead error %u\n", __FUNCTION__, ret)); + return SYS_MBOX_EMPTY; /* Errors should be treated as timeout */ +} + +void sys_mbox_free(sys_mbox_t *mbox) +{ + (void)LOS_QueueDelete(*mbox); +} + +int sys_mbox_valid(sys_mbox_t *mbox) +{ + QUEUE_INFO_S queueInfo; + return LOS_OK == LOS_QueueInfoGet(*mbox, &queueInfo); +} + +void sys_mbox_set_invalid(sys_mbox_t *mbox) +{ + *mbox = LOSCFG_BASE_IPC_QUEUE_LIMIT; +} + + +/** + * Semaphore + */ + +err_t sys_sem_new(sys_sem_t *sem, u8_t count) +{ + UINT32 ret = LOS_SemCreate(count, sem); + if (ret != LOS_OK) { + return ERR_ARG; + } + + return ERR_OK; +} + +void sys_sem_signal(sys_sem_t *sem) +{ + (void)LOS_SemPost(*sem); +} + +u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeoutMs) +{ + UINT64 tick = ROUND_UP_DIV((UINT64)timeoutMs * LOSCFG_BASE_CORE_TICK_PER_SECOND, OS_SYS_MS_PER_SECOND); + UINT32 ret = LOS_SemPend(*sem, tick ? (UINT32)tick : LOS_WAIT_FOREVER); // timeoutMs 0 means wait forever + switch (ret) { + case LOS_OK: + return ERR_OK; + case LOS_ERRNO_SEM_TIMEOUT: + return SYS_ARCH_TIMEOUT; + default: + break; + } + LWIP_DEBUGF(SYS_DEBUG, ("%s: LOS_SemPend error %u\n", __FUNCTION__, ret)); + return SYS_ARCH_TIMEOUT; /* Errors should be treated as timeout */ +} + +void sys_sem_free(sys_sem_t *sem) +{ + (void)LOS_SemDelete(*sem); +} + +int sys_sem_valid(sys_sem_t *sem) +{ + return *sem != LOSCFG_BASE_IPC_SEM_LIMIT; +} + +void sys_sem_set_invalid(sys_sem_t *sem) +{ + *sem = LOSCFG_BASE_IPC_SEM_LIMIT; +} + + +/** + * Mutex + */ + +err_t sys_mutex_new(sys_mutex_t *mutex) +{ + UINT32 ret = LOS_MuxInit(mutex, NULL); + if (ret != LOS_OK) { + return ERR_ARG; + } + + return ERR_OK; +} + +void sys_mutex_lock(sys_mutex_t *mutex) +{ + (void)LOS_MuxLock(mutex, LOS_WAIT_FOREVER); +} + +void sys_mutex_unlock(sys_mutex_t *mutex) +{ + (void)LOS_MuxUnlock(mutex); +} + +void sys_mutex_free(sys_mutex_t *mutex) +{ + (void)LOS_MuxDestroy(mutex); +} + +int sys_mutex_valid(sys_mutex_t *mutex) +{ + return LOS_MuxIsValid(mutex); +} + +void sys_mutex_set_invalid(sys_mutex_t *mutex) +{ + (void)LOS_MuxDestroy(mutex); +} diff --git a/src/kernel_liteos_a/net/mac/los_mac.h b/src/kernel_liteos_a/net/mac/los_mac.h new file mode 100644 index 00000000..88d36a14 --- /dev/null +++ b/src/kernel_liteos_a/net/mac/los_mac.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_MAC_H +#define _LOS_MAC_H + +#include "lwip/netif.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +struct los_eth_driver { + void* driver_context; + struct netif ac_if; +}; + +struct los_eth_funs { + void (*init)(struct los_eth_driver *drv, unsigned char *mac_addr); + void (*recv)(struct los_eth_driver *drv, int len); + void (*send_complete)(struct los_eth_driver *drv, unsigned int key, int state); +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_MAC_H */ diff --git a/src/kernel_liteos_a/net/telnet/BUILD.gn b/src/kernel_liteos_a/net/telnet/BUILD.gn new file mode 100644 index 00000000..0601c60a --- /dev/null +++ b/src/kernel_liteos_a/net/telnet/BUILD.gn @@ -0,0 +1,45 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = defined(LOSCFG_NET_TELNET) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ + "src/telnet_dev.c", + "src/telnet_loop.c", + ] + + public_configs = [ ":public" ] +} + +config("public") { + include_dirs = [ "include" ] +} diff --git a/src/kernel_liteos_a/net/telnet/Kconfig b/src/kernel_liteos_a/net/telnet/Kconfig new file mode 100644 index 00000000..a3d7cfad --- /dev/null +++ b/src/kernel_liteos_a/net/telnet/Kconfig @@ -0,0 +1,6 @@ +config NET_TELNET + bool "Enable Telnet" + default y + depends on NET_LWIP_SACK && SHELL && DEBUG_VERSION + help + Answer Y to enable LiteOS support telnet tool. \ No newline at end of file diff --git a/src/kernel_liteos_a/net/telnet/Makefile b/src/kernel_liteos_a/net/telnet/Makefile new file mode 100644 index 00000000..dbe06730 --- /dev/null +++ b/src/kernel_liteos_a/net/telnet/Makefile @@ -0,0 +1,36 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := $(wildcard src/*.c) + +include $(MODULE) diff --git a/src/kernel_liteos_a/net/telnet/include/telnet_dev.h b/src/kernel_liteos_a/net/telnet/include/telnet_dev.h new file mode 100644 index 00000000..7a6da243 --- /dev/null +++ b/src/kernel_liteos_a/net/telnet/include/telnet_dev.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _TELNET_DEV_H +#define _TELNET_DEV_H + +#include "los_config.h" +#include "linux/wait.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#ifdef LOSCFG_NET_TELNET + +#define TELNET "/dev/telnet" + +#define FIFO_MAX 1024 +#define TELNET_IOC_MAGIC 't' +#define CFG_TELNET_SET_FD _IO(TELNET_IOC_MAGIC, 1) +#define CFG_TELNET_EVENT_PEND CONSOLE_CMD_RD_BLOCK_TELNET +#define BLOCK_DISABLE 0 +#define BLOCK_ENABLE 1 + +typedef struct { + UINT32 rxIndex; /* index for receiving user's commands */ + UINT32 rxOutIndex; /* index for taking out commands by a shell task to run */ + UINT32 fifoNum; /* unused size of the cmdBuf */ + UINT32 lock; + CHAR rxBuf[FIFO_MAX]; /* the real buffer to store user's commands */ +} TELNTE_FIFO_S; + +typedef struct { + INT32 clientFd; + UINT32 id; + BOOL eventPend; + EVENT_CB_S eventTelnet; + wait_queue_head_t wait; + TELNTE_FIFO_S *cmdFifo; /* use a FIFO to store user's commands */ +} TELNET_DEV_S; + +extern INT32 TelnetTx(const CHAR *buf, UINT32 len); +extern INT32 TelnetDevInit(INT32 fd); +extern INT32 TelnetDevDeinit(VOID); +extern INT32 TelnetedRegister(VOID); +extern INT32 TelnetedUnregister(VOID); +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/src/kernel_liteos_a/net/telnet/include/telnet_loop.h b/src/kernel_liteos_a/net/telnet/include/telnet_loop.h new file mode 100644 index 00000000..c8ef2f1f --- /dev/null +++ b/src/kernel_liteos_a/net/telnet/include/telnet_loop.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _TELNET_LOOP_H +#define _TELNET_LOOP_H + +#include "los_config.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#ifdef LOSCFG_NET_TELNET +#define TELNETD_PORT 23 +#define TELNET_KEEPALIVE 1 +#define TELNET_KEEPIDLE 60 +#define TELNET_KEEPINTV 2 +#define TELNET_KEEPCNT 5 + +extern INT32 TelnetCmd(UINT32 argc, const CHAR **argv); +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/src/kernel_liteos_a/net/telnet/include/telnet_pri.h b/src/kernel_liteos_a/net/telnet/include/telnet_pri.h new file mode 100644 index 00000000..e710c910 --- /dev/null +++ b/src/kernel_liteos_a/net/telnet/include/telnet_pri.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _TELNET_PRI_H +#define _TELNET_PRI_H + +#include "los_config.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#ifdef LOSCFG_NET_TELNET + +VOID TelnetLock(VOID); +VOID TelnetUnlock(VOID); + +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/src/kernel_liteos_a/net/telnet/src/telnet_dev.c b/src/kernel_liteos_a/net/telnet/src/telnet_dev.c new file mode 100644 index 00000000..e1e31452 --- /dev/null +++ b/src/kernel_liteos_a/net/telnet/src/telnet_dev.c @@ -0,0 +1,409 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "telnet_dev.h" +#ifdef LOSCFG_NET_TELNET +#include "unistd.h" +#include "stdlib.h" +#include "sys/ioctl.h" +#include "sys/types.h" +#include "pthread.h" + +#include "los_printf.h" +#ifdef LOSCFG_BASE_CORE_SWTMR_ENABLE +#include "los_swtmr_pri.h" +#endif +#include "los_sched_pri.h" +#include "console.h" +#include "lwip/opt.h" +#include "lwip/sockets.h" +#include "telnet_pri.h" + +#include "fs/driver.h" + +/* event: there are more commands left in the FIFO to run */ +#define TELNET_EVENT_MORE_CMD 0x01 +#define TELNET_DEV_DRV_MODE 0666 + +STATIC TELNET_DEV_S g_telnetDev; +STATIC EVENT_CB_S *g_event; +STATIC struct Vnode *g_currentVnode; + +STATIC INLINE TELNET_DEV_S *GetTelnetDevByFile(const struct file *file, BOOL isOpenOp) +{ + struct Vnode *telnetInode = NULL; + TELNET_DEV_S *telnetDev = NULL; + + if (file == NULL) { + return NULL; + } + telnetInode = file->f_vnode; + if (telnetInode == NULL) { + return NULL; + } + /* + * Check if the f_vnode is valid here for non-open ops (open is supposed to get invalid f_vnode): + * when telnet is disconnected, there still may be 'TelentShellTask' tasks trying to write + * to the file, but the file has illegal f_vnode because the file is used by others. + */ + if (!isOpenOp) { + if (telnetInode != g_currentVnode) { + return NULL; + } + } + telnetDev = (TELNET_DEV_S *)((struct drv_data*)telnetInode->data)->priv; + return telnetDev; +} + +/* + * Description : When receive user's input commands, first copy commands to the FIFO of the telnet device. + * Then, notify a command resolver task (an individual shell task) to take out and run commands. + * Return : -1 --- On failure + * Non-negative integer --- length of written commands + */ +INT32 TelnetTx(const CHAR *buf, UINT32 bufLen) +{ + UINT32 i; + TELNET_DEV_S *telnetDev = NULL; + + TelnetLock(); + + telnetDev = &g_telnetDev; + if ((buf == NULL) || (telnetDev->cmdFifo == NULL)) { + TelnetUnlock(); + return -1; + } + + /* size limited */ + if (bufLen > telnetDev->cmdFifo->fifoNum) { + bufLen = telnetDev->cmdFifo->fifoNum; + } + + if (bufLen == 0) { + TelnetUnlock(); + return 0; + } + + /* copy commands to the fifo of the telnet device */ + for (i = 0; i < bufLen; i++) { + telnetDev->cmdFifo->rxBuf[telnetDev->cmdFifo->rxIndex] = *buf; + telnetDev->cmdFifo->rxIndex++; + telnetDev->cmdFifo->rxIndex %= FIFO_MAX; + buf++; + } + telnetDev->cmdFifo->fifoNum -= bufLen; + + if (telnetDev->eventPend) { + /* signal that there are some works to do */ + (VOID)LOS_EventWrite(&telnetDev->eventTelnet, TELNET_EVENT_MORE_CMD); + } + /* notify the command resolver task */ + notify_poll(&telnetDev->wait); + TelnetUnlock(); + + return (INT32)bufLen; +} + +/* + * Description : When open the telnet device, init the FIFO, wait queue etc. + */ +STATIC INT32 TelnetOpen(struct file *file) +{ + struct wait_queue_head *wait = NULL; + TELNET_DEV_S *telnetDev = NULL; + + TelnetLock(); + + telnetDev = GetTelnetDevByFile(file, TRUE); + if (telnetDev == NULL) { + TelnetUnlock(); + return -1; + } + + if (telnetDev->cmdFifo == NULL) { + wait = &telnetDev->wait; + (VOID)LOS_EventInit(&telnetDev->eventTelnet); + g_event = &telnetDev->eventTelnet; + telnetDev->cmdFifo = (TELNTE_FIFO_S *)malloc(sizeof(TELNTE_FIFO_S)); + if (telnetDev->cmdFifo == NULL) { + TelnetUnlock(); + return -1; + } + (VOID)memset_s(telnetDev->cmdFifo, sizeof(TELNTE_FIFO_S), 0, sizeof(TELNTE_FIFO_S)); + telnetDev->cmdFifo->fifoNum = FIFO_MAX; + LOS_ListInit(&wait->poll_queue); + } + g_currentVnode = file->f_vnode; + TelnetUnlock(); + return 0; +} + +/* + * Description : When close the telnet device, free the FIFO, wait queue etc. + */ +STATIC INT32 TelnetClose(struct file *file) +{ + struct wait_queue_head *wait = NULL; + TELNET_DEV_S *telnetDev = NULL; + + TelnetLock(); + + telnetDev = GetTelnetDevByFile(file, FALSE); + if (telnetDev != NULL) { + wait = &telnetDev->wait; + LOS_ListDelete(&wait->poll_queue); + free(telnetDev->cmdFifo); + telnetDev->cmdFifo = NULL; + (VOID)LOS_EventDestroy(&telnetDev->eventTelnet); + g_event = NULL; + } + g_currentVnode = NULL; + TelnetUnlock(); + return 0; +} + +/* + * Description : When a command resolver task tries to read the telnet device, + * this method is called, and it will take out user's commands from the FIFO to run. + * Return : -1 --- On failure + * Non-negative integer --- length of commands taken out from the FIFO of the telnet device. + */ +STATIC ssize_t TelnetRead(struct file *file, CHAR *buf, size_t bufLen) +{ + UINT32 i; + TELNET_DEV_S *telnetDev = NULL; + + TelnetLock(); + + telnetDev = GetTelnetDevByFile(file, FALSE); + if ((buf == NULL) || (telnetDev == NULL) || (telnetDev->cmdFifo == NULL)) { + TelnetUnlock(); + return -1; + } + + if (telnetDev->eventPend) { + TelnetUnlock(); + (VOID)LOS_EventRead(g_event, TELNET_EVENT_MORE_CMD, LOS_WAITMODE_OR, LOS_WAIT_FOREVER); + TelnetLock(); + } + + if (bufLen > (FIFO_MAX - telnetDev->cmdFifo->fifoNum)) { + bufLen = FIFO_MAX - telnetDev->cmdFifo->fifoNum; + } + + for (i = 0; i < bufLen; i++) { + *buf++ = telnetDev->cmdFifo->rxBuf[telnetDev->cmdFifo->rxOutIndex++]; + if (telnetDev->cmdFifo->rxOutIndex >= FIFO_MAX) { + telnetDev->cmdFifo->rxOutIndex = 0; + } + } + telnetDev->cmdFifo->fifoNum += bufLen; + /* check if no more commands left to run */ + if (telnetDev->cmdFifo->fifoNum == FIFO_MAX) { + (VOID)LOS_EventClear(&telnetDev->eventTelnet, ~TELNET_EVENT_MORE_CMD); + } + + TelnetUnlock(); + return (ssize_t)bufLen; +} + +/* + * Description : When a command resolver task tries to write command results to the telnet device, + * just use lwIP send function to send out results. + * Return : -1 --- buffer is NULL + * Non-negative integer --- length of written data, maybe 0. + */ +STATIC ssize_t TelnetWrite(struct file *file, const CHAR *buf, const size_t bufLen) +{ + INT32 ret = 0; + TELNET_DEV_S *telnetDev = NULL; + + TelnetLock(); + + telnetDev = GetTelnetDevByFile(file, FALSE); + if ((buf == NULL) || (telnetDev == NULL) || (telnetDev->cmdFifo == NULL)) { + TelnetUnlock(); + return -1; + } + + if (OS_INT_ACTIVE) { + TelnetUnlock(); + return ret; + } + + if (!OsPreemptable()) { + TelnetUnlock(); + return ret; + } + + if (telnetDev->clientFd != 0) { +#ifdef LOSCFG_BASE_CORE_SWTMR_ENABLE + /* DO NOT call blocking API in software timer task */ + if (OsIsSwtmrTask(OsCurrTaskGet())) { + TelnetUnlock(); + return ret; + } +#endif + ret = send(telnetDev->clientFd, buf, bufLen, 0); + } + TelnetUnlock(); + return ret; +} + +STATIC INT32 TelnetIoctl(struct file *file, const INT32 cmd, unsigned long arg) +{ + TELNET_DEV_S *telnetDev = NULL; + + TelnetLock(); + + telnetDev = GetTelnetDevByFile(file, FALSE); + if (telnetDev == NULL) { + TelnetUnlock(); + return -1; + } + + if (cmd == CFG_TELNET_EVENT_PEND) { + if (arg == 0) { + telnetDev->eventPend = FALSE; + (VOID)LOS_EventWrite(&(telnetDev->eventTelnet), TELNET_EVENT_MORE_CMD); + (VOID)LOS_EventClear(&(telnetDev->eventTelnet), ~TELNET_EVENT_MORE_CMD); + } else { + telnetDev->eventPend = TRUE; + } + } else if (cmd == CFG_TELNET_SET_FD) { + if (arg >= (FD_SETSIZE - 1)) { + TelnetUnlock(); + return -1; + } + telnetDev->clientFd = (INT32)arg; + } + TelnetUnlock(); + return 0; +} + +STATIC INT32 TelnetPoll(struct file *file, poll_table *table) +{ + TELNET_DEV_S *telnetDev = NULL; + + TelnetLock(); + + telnetDev = GetTelnetDevByFile(file, FALSE); + if ((telnetDev == NULL) || (telnetDev->cmdFifo == NULL)) { + TelnetUnlock(); + return -1; + } + + poll_wait(file, &telnetDev->wait, table); + + /* check if there are some commands to run */ + if (telnetDev->cmdFifo->fifoNum != FIFO_MAX) { + TelnetUnlock(); + return POLLIN | POLLRDNORM; + } + TelnetUnlock(); + return 0; +} + +STATIC const struct file_operations_vfs g_telnetOps = { + TelnetOpen, + TelnetClose, + TelnetRead, + TelnetWrite, + NULL, + TelnetIoctl, + NULL, +#ifndef CONFIG_DISABLE_POLL + TelnetPoll, +#endif + NULL, +}; + +/* Once the telnet server stopped, remove the telnet device file. */ +INT32 TelnetedUnregister(VOID) +{ + free(g_telnetDev.cmdFifo); + g_telnetDev.cmdFifo = NULL; + (VOID)unregister_driver(TELNET); + + return 0; +} + +/* Once the telnet server started, setup the telnet device file. */ +INT32 TelnetedRegister(VOID) +{ + INT32 ret; + + g_telnetDev.id = 0; + g_telnetDev.cmdFifo = NULL; + g_telnetDev.eventPend = TRUE; + + ret = register_driver(TELNET, &g_telnetOps, TELNET_DEV_DRV_MODE, &g_telnetDev); + if (ret != 0) { + PRINT_ERR("Telnet register driver error.\n"); + } + return ret; +} + +/* When a telnet client connection established, update the output console for tasks. */ +INT32 TelnetDevInit(INT32 clientFd) +{ + INT32 ret; + + if (clientFd < 0) { + PRINT_ERR("Invalid telnet clientFd.\n"); + return -1; + } + ret = system_console_init(TELNET); + if (ret != 0) { + PRINT_ERR("Telnet console init error.\n"); + return ret; + } + ret = ioctl(STDIN_FILENO, CFG_TELNET_SET_FD, clientFd); + if (ret != 0) { + PRINT_ERR("Telnet device ioctl error.\n"); + (VOID)system_console_deinit(TELNET); + } + return ret; +} + +/* When closing the telnet client connection, reset the output console for tasks. */ +INT32 TelnetDevDeinit(VOID) +{ + INT32 ret; + + ret = system_console_deinit(TELNET); + if (ret != 0) { + PRINT_ERR("Telnet console deinit error.\n"); + } + return ret; +} +#endif + diff --git a/src/kernel_liteos_a/net/telnet/src/telnet_loop.c b/src/kernel_liteos_a/net/telnet/src/telnet_loop.c new file mode 100644 index 00000000..87bb188f --- /dev/null +++ b/src/kernel_liteos_a/net/telnet/src/telnet_loop.c @@ -0,0 +1,584 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "telnet_loop.h" +#ifdef LOSCFG_NET_TELNET +#include "stdio.h" +#include "stdlib.h" +#include "unistd.h" +#include "pthread.h" +#include "netinet/tcp.h" +#include "sys/select.h" +#include "sys/types.h" +#include "sys/prctl.h" + +#include "los_task.h" +#include "linux/atomic.h" +#include "lwip/sockets.h" +#include "lwip/inet.h" +#include "lwip/netif.h" +#include "console.h" +#ifdef LOSCFG_SHELL +#include "shell.h" +#include "shcmd.h" +#endif +#include "telnet_pri.h" +#include "telnet_dev.h" + + +/* TELNET commands in RFC854 */ +#define TELNET_SB 250 /* Indicates that what follows is subnegotiation of the indicated option */ +#define TELNET_WILL 251 /* Indicates the desire to perform the indicated option */ +#define TELNET_DO 253 /* Indicates the request for the other party to perform the indicated option */ +#define TELNET_IAC 255 /* Interpret as Command */ + +/* telnet options in IANA */ +#define TELNET_ECHO 1 /* Echo */ +#define TELNET_SGA 3 /* Suppress Go Ahead */ +#define TELNET_NAWS 31 /* Negotiate About Window Size */ +#define TELNET_NOP 0xf1 /* Unassigned in IANA, putty use this to keepalive */ + +#define LEN_IAC_CMD 2 /* Only 2 char: |IAC|cmd| */ +#define LEN_IAC_CMD_OPT 3 /* Only 3 char: |IAC|cmd|option| */ +#define LEN_IAC_CMD_NAWS 9 /* NAWS: |IAC|SB|NAWS|x1|x2|x3|x4|IAC|SE| */ + +/* server/client settings */ +#define TELNET_TASK_STACK_SIZE 0x2000 +#define TELNET_TASK_PRIORITY 9 + +/* server settings */ +#define TELNET_LISTEN_BACKLOG 128 +#define TELNET_ACCEPT_INTERVAL 200 + +/* client settings */ +#define TELNET_CLIENT_POLL_TIMEOUT 2000 +#define TELNET_CLIENT_READ_BUF_SIZE 256 +#define TELNET_CLIENT_READ_FILTER_BUF_SIZE (8 * 1024) + +/* limitation: only support 1 telnet client connection */ +STATIC volatile INT32 g_telnetClientFd = -1; /* client fd */ + +/* limitation: only support 1 telnet server */ +STATIC volatile INT32 g_telnetListenFd = -1; /* listen fd of telnetd */ + +/* each bit for a client connection, although only support 1 connection for now */ +STATIC volatile UINT32 g_telnetMask = 0; +/* taskID of telnetd */ +STATIC atomic_t g_telnetTaskId = 0; +/* protect listenFd, clientFd etc. */ +pthread_mutex_t g_telnetMutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; + +VOID TelnetLock(VOID) +{ + (VOID)pthread_mutex_lock(&g_telnetMutex); +} + +VOID TelnetUnlock(VOID) +{ + (VOID)pthread_mutex_unlock(&g_telnetMutex); +} + +/* filter out iacs from client stream */ +STATIC UINT8 *ReadFilter(const UINT8 *src, UINT32 srcLen, UINT32 *dstLen) +{ + STATIC UINT8 buf[TELNET_CLIENT_READ_FILTER_BUF_SIZE]; + UINT8 *dst = buf; + UINT32 left = srcLen; + + while (left > 0) { + if (*src != TELNET_IAC) { + *dst = *src; + dst++; + src++; + left--; + continue; + } + + /* + * if starting with IAC, filter out IAC as following + * |IAC| --> skip + * |IAC|NOP|... --> ... : skip for putty keepalive etc. + * |IAC|x| --> skip + * |IAC|IAC|x|... --> |IAC|... : skip for literal cmds + * |IAC|SB|NAWS|x1|x2|x3|x4|IAC|SE|... --> ... : skip NAWS(unsupported) + * |IAC|x|x|... --> ... : skip unsupported IAC + */ + if (left == 1) { + break; + } + /* left no less than 2 */ + if (*(src + 1) == TELNET_NOP) { + src += LEN_IAC_CMD; + left -= LEN_IAC_CMD; + continue; + } + if (left == LEN_IAC_CMD) { + break; + } + /* left no less than 3 */ + if (*(src + 1) == TELNET_IAC) { + *dst = TELNET_IAC; + dst++; + src += LEN_IAC_CMD; + left -= LEN_IAC_CMD; + continue; + } + if ((*(src + 1) == TELNET_SB) && (*(src + LEN_IAC_CMD) == TELNET_NAWS)) { + if (left > LEN_IAC_CMD_NAWS) { + src += LEN_IAC_CMD_NAWS; + left -= LEN_IAC_CMD_NAWS; + continue; + } + break; + } + src += LEN_IAC_CMD_OPT; + left -= LEN_IAC_CMD_OPT; + } + + if (dstLen != NULL) { + *dstLen = dst - buf; + } + return buf; +} + +/* + * Description : Write data to fd. + * Input : fd --- the fd to write. + * : src --- data pointer. + * : srcLen --- data length. + * Return : length of written data. + */ +STATIC ssize_t WriteToFd(INT32 fd, const CHAR *src, size_t srcLen) +{ + size_t sizeLeft; + ssize_t sizeWritten; + + sizeLeft = srcLen; + while (sizeLeft > 0) { + sizeWritten = write(fd, src, sizeLeft); + if (sizeWritten < 0) { + /* last write failed */ + if (sizeLeft == srcLen) { + /* nothing was written in any loop */ + return -1; + } else { + /* something was written in previous loop */ + break; + } + } else if (sizeWritten == 0) { + break; + } + sizeLeft -= (size_t)sizeWritten; + src += sizeWritten; + } + + return (ssize_t)(srcLen - sizeLeft); +} + +/* Try to remove the client device if there is any client connection */ +STATIC VOID TelnetClientClose(VOID) +{ + /* check if there is any client connection */ + if (g_telnetMask == 0) { + return; + } + (VOID)TelnetDevDeinit(); + g_telnetMask = 0; + printf("telnet client disconnected.\n"); +} + +/* Release the client and server fd */ +STATIC VOID TelnetRelease(VOID) +{ + if (g_telnetClientFd >= 0) { + (VOID)close(g_telnetClientFd); + g_telnetClientFd = -1; + } + + if (g_telnetListenFd >= 0) { + (VOID)close(g_telnetListenFd); + g_telnetListenFd = -1; + } +} + +/* Stop telnet server */ +STATIC VOID TelnetdDeinit(VOID) +{ + if (atomic_read(&g_telnetTaskId) == 0) { + PRINTK("telnet server is not running!\n"); + return; + } + + TelnetRelease(); + (VOID)TelnetedUnregister(); + atomic_set(&g_telnetTaskId, 0); + PRINTK("telnet server closed.\n"); +} + +/* + * Description : Setup the listen fd for telnetd with specific port. + * Input : port --- the port at which telnet server listens. + * Return : -1 --- on error + * : non-negative --- listen fd if OK + */ +STATIC INT32 TelnetdInit(UINT16 port) +{ + INT32 listenFd; + INT32 reuseAddr = 1; + struct sockaddr_in inTelnetAddr; + + listenFd = socket(AF_INET, SOCK_STREAM, 0); + if (listenFd == -1) { + PRINT_ERR("TelnetdInit : socket error.\n"); + goto ERR_OUT; + } + + /* reuse listen port */ + if (setsockopt(listenFd, SOL_SOCKET, SO_REUSEADDR, &reuseAddr, sizeof(reuseAddr)) != 0) { + PRINT_ERR("TelnetdInit : setsockopt REUSEADDR error.\n"); + goto ERR_CLOSE_FD; + } + + (VOID)memset_s(&inTelnetAddr, sizeof(struct sockaddr_in), 0, sizeof(struct sockaddr_in)); + inTelnetAddr.sin_family = AF_INET; + inTelnetAddr.sin_addr.s_addr = INADDR_ANY; + inTelnetAddr.sin_port = htons(port); + + if (bind(listenFd, (const struct sockaddr *)&inTelnetAddr, sizeof(struct sockaddr_in)) == -1) { + PRINT_ERR("TelnetdInit : bind error.\n"); + goto ERR_CLOSE_FD; + } + + if (listen(listenFd, TELNET_LISTEN_BACKLOG) == -1) { + PRINT_ERR("TelnetdInit : listen error.\n"); + goto ERR_CLOSE_FD; + } + + return listenFd; + +ERR_CLOSE_FD: + (VOID)close(listenFd); +ERR_OUT: + return -1; +} + +STATIC INT32 TelnetClientPrepare(INT32 clientFd) +{ + INT32 keepAlive = TELNET_KEEPALIVE; + INT32 keepIdle = TELNET_KEEPIDLE; + INT32 keepInterval = TELNET_KEEPINTV; + INT32 keepCnt = TELNET_KEEPCNT; + const UINT8 doEcho[] = { TELNET_IAC, TELNET_DO, TELNET_ECHO }; + const UINT8 doNaws[] = { TELNET_IAC, TELNET_DO, TELNET_NAWS }; + const UINT8 willEcho[] = { TELNET_IAC, TELNET_WILL, TELNET_ECHO }; + const UINT8 willSga[] = { TELNET_IAC, TELNET_WILL, TELNET_SGA }; + + if (g_telnetListenFd == -1) { + return -1; + } + g_telnetClientFd = clientFd; + if (TelnetDevInit(clientFd) != 0) { + g_telnetClientFd = -1; + return -1; + } + g_telnetMask = 1; + + /* negotiate with client */ + (VOID)WriteToFd(clientFd, (CHAR *)doEcho, sizeof(doEcho)); + (VOID)WriteToFd(clientFd, (CHAR *)doNaws, sizeof(doNaws)); + (VOID)WriteToFd(clientFd, (CHAR *)willEcho, sizeof(willEcho)); + (VOID)WriteToFd(clientFd, (CHAR *)willSga, sizeof(willSga)); + + /* enable TCP keepalive to check whether telnet link is alive */ + if (setsockopt(clientFd, SOL_SOCKET, SO_KEEPALIVE, (VOID *)&keepAlive, sizeof(keepAlive)) < 0) { + PRINT_ERR("telnet setsockopt SO_KEEPALIVE error.\n"); + } + if (setsockopt(clientFd, IPPROTO_TCP, TCP_KEEPIDLE, (VOID *)&keepIdle, sizeof(keepIdle)) < 0) { + PRINT_ERR("telnet setsockopt TCP_KEEPIDLE error.\n"); + } + if (setsockopt(clientFd, IPPROTO_TCP, TCP_KEEPINTVL, (VOID *)&keepInterval, sizeof(keepInterval)) < 0) { + PRINT_ERR("telnet setsockopt TCP_KEEPINTVL error.\n"); + } + if (setsockopt(clientFd, IPPROTO_TCP, TCP_KEEPCNT, (VOID *)&keepCnt, sizeof(keepCnt)) < 0) { + PRINT_ERR("telnet setsockopt TCP_KEEPCNT error.\n"); + } + return 0; +} + +STATIC VOID *TelnetClientLoop(VOID *arg) +{ + struct pollfd pollFd; + INT32 ret; + INT32 nRead; + UINT32 len; + UINT8 buf[TELNET_CLIENT_READ_BUF_SIZE]; + UINT8 *cmdBuf = NULL; + INT32 clientFd = (INT32)(UINTPTR)arg; + + (VOID)prctl(PR_SET_NAME, "TelnetClientLoop", 0, 0, 0); + TelnetLock(); + if (TelnetClientPrepare(clientFd) != 0) { + TelnetUnlock(); + (VOID)close(clientFd); + return NULL; + } + TelnetUnlock(); + + while (1) { + pollFd.fd = clientFd; + pollFd.events = POLLIN | POLLRDHUP; + pollFd.revents = 0; + + ret = poll(&pollFd, 1, TELNET_CLIENT_POLL_TIMEOUT); + if (ret < 0) { + break; + } + if (ret == 0) { + continue; + } + /* connection reset, maybe keepalive failed or reset by peer */ + if ((UINT16)pollFd.revents & (POLLERR | POLLHUP | POLLRDHUP)) { + break; + } + + if ((UINT16)pollFd.revents & POLLIN) { + nRead = read(clientFd, buf, sizeof(buf)); + if (nRead <= 0) { + /* telnet client shutdown */ + break; + } + cmdBuf = ReadFilter(buf, (UINT32)nRead, &len); + if (len > 0) { + (VOID)TelnetTx((CHAR *)cmdBuf, len); + } + } + } + TelnetLock(); + TelnetClientClose(); + (VOID)close(clientFd); + clientFd = -1; + g_telnetClientFd = -1; + TelnetUnlock(); + return NULL; +} + +STATIC VOID TelnetClientTaskAttr(pthread_attr_t *threadAttr) +{ + (VOID)pthread_attr_init(threadAttr); + threadAttr->inheritsched = PTHREAD_EXPLICIT_SCHED; + threadAttr->schedparam.sched_priority = TELNET_TASK_PRIORITY; + threadAttr->detachstate = PTHREAD_CREATE_DETACHED; + (VOID)pthread_attr_setstacksize(threadAttr, TELNET_TASK_STACK_SIZE); +} + +/* + * Description : Handle the client connection request. + * Create a client connection if permitted. + * Return : 0 --- please continue the server accept loop + * : -1 --- please stop the server accept loop. + */ +STATIC INT32 TelnetdAcceptClient(INT32 clientFd, const struct sockaddr_in *inTelnetAddr) +{ + INT32 ret = 0; + pthread_t tmp; + pthread_attr_t useAttr; + + TelnetClientTaskAttr(&useAttr); + + if (clientFd < 0) { + ret = -1; + goto ERROUT; + } + + TelnetLock(); + + if (g_telnetListenFd == -1) { + /* server already has been closed, so quit this task now */ + ret = -1; + goto ERROUT_UNLOCK; + } + + if (g_telnetClientFd >= 0) { + /* already connected and support only one */ + goto ERROUT_UNLOCK; + } + + g_telnetClientFd = clientFd; + + if (pthread_create(&tmp, &useAttr, TelnetClientLoop, (VOID *)(UINTPTR)clientFd) != 0) { + PRINT_ERR("Failed to create client handle task\n"); + g_telnetClientFd = -1; + goto ERROUT_UNLOCK; + } + TelnetUnlock(); + return ret; + +ERROUT_UNLOCK: + (VOID)close(clientFd); + clientFd = -1; + TelnetUnlock(); +ERROUT: + return ret; +} + +/* + * Waiting for client's connection. Only allow 1 connection, and others will be discarded. + */ +STATIC VOID TelnetdAcceptLoop(INT32 listenFd) +{ + INT32 clientFd = -1; + struct sockaddr_in inTelnetAddr; + INT32 len = sizeof(inTelnetAddr); + + TelnetLock(); + g_telnetListenFd = listenFd; + + while (g_telnetListenFd >= 0) { + TelnetUnlock(); + + (VOID)memset_s(&inTelnetAddr, sizeof(inTelnetAddr), 0, sizeof(inTelnetAddr)); + clientFd = accept(listenFd, (struct sockaddr *)&inTelnetAddr, (socklen_t *)&len); + if (TelnetdAcceptClient(clientFd, &inTelnetAddr) == 0) { + /* + * Sleep sometime before next loop: mostly we already have one connection here, + * and the next connection will be declined. So don't waste our cpu. + */ + LOS_Msleep(TELNET_ACCEPT_INTERVAL); + } else { + return; + } + TelnetLock(); + } + TelnetUnlock(); +} + +STATIC INT32 TelnetdMain(VOID) +{ + INT32 sock; + INT32 ret; + + sock = TelnetdInit(TELNETD_PORT); + if (sock == -1) { + PRINT_ERR("telnet init error.\n"); + return -1; + } + + TelnetLock(); + ret = TelnetedRegister(); + TelnetUnlock(); + + if (ret != 0) { + PRINT_ERR("telnet register error.\n"); + (VOID)close(sock); + return -1; + } + + PRINTK("start telnet server successfully, waiting for connection.\n"); + TelnetdAcceptLoop(sock); + return 0; +} + +/* + * Try to create telnetd task. + */ +STATIC VOID TelnetdTaskInit(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S initParam = {0}; + + initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)TelnetdMain; + initParam.uwStackSize = TELNET_TASK_STACK_SIZE; + initParam.pcName = "TelnetServer"; + initParam.usTaskPrio = TELNET_TASK_PRIORITY; + initParam.uwResved = LOS_TASK_STATUS_DETACHED; + + if (atomic_read(&g_telnetTaskId) != 0) { + PRINT_ERR("telnet server is already running!\n"); + return; + } + + ret = LOS_TaskCreate((UINT32 *)&g_telnetTaskId, &initParam); + if (ret != LOS_OK) { + PRINT_ERR("failed to create telnet server task!\n"); + } +} + +/* + * Try to destroy telnetd task. + */ +STATIC VOID TelnetdTaskDeinit(VOID) +{ + if (atomic_read(&g_telnetTaskId) == 0) { + PRINTK("telnet server is not running, please start up telnet server first.\n"); + return; + } + + TelnetLock(); + TelnetClientClose(); + TelnetdDeinit(); + TelnetUnlock(); +} + +STATIC VOID TelnetUsage(VOID) +{ + PRINTK("Usage: telnet [OPTION]...\n"); + PRINTK("Start or close telnet server.\n\n"); + PRINTK(" on Init the telnet server\n"); + PRINTK(" off Deinit the telnet server\n"); +} + +INT32 TelnetCmd(UINT32 argc, const CHAR **argv) +{ + if (argc != 1) { + TelnetUsage(); + return 0; + } + + if (strcmp(argv[0], "on") == 0) { + /* telnet on: try to start telnet server task */ + TelnetdTaskInit(); + return 0; + } + if (strcmp(argv[0], "off") == 0) { + /* telnet off: try to stop clients, then stop server task */ + TelnetdTaskDeinit(); + return 0; + } + + TelnetUsage(); + return 0; +} + +#ifdef LOSCFG_SHELL_CMD_DEBUG +SHELLCMD_ENTRY(telnet_shellcmd, CMD_TYPE_EX, "telnet", 1, (CmdCallBackFunc)TelnetCmd); +#endif /* LOSCFG_SHELL_CMD_DEBUG */ +#endif + diff --git a/src/kernel_liteos_a/platform/BUILD.gn b/src/kernel_liteos_a/platform/BUILD.gn new file mode 100644 index 00000000..f8eec886 --- /dev/null +++ b/src/kernel_liteos_a/platform/BUILD.gn @@ -0,0 +1,44 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +kernel_module("board.ld") { + sources = [ "board.ld.S" ] + asmflags = [ + "-P", + "-E", + ] +} + +copy("copy_board.ld") { + deps = [ ":board.ld" ] + sources = [ "$target_out_dir/board.ld.board.ld.o" ] + outputs = [ "$root_out_dir/board.ld" ] +} diff --git a/src/kernel_liteos_a/platform/Kconfig b/src/kernel_liteos_a/platform/Kconfig new file mode 100644 index 00000000..57f14f37 --- /dev/null +++ b/src/kernel_liteos_a/platform/Kconfig @@ -0,0 +1,88 @@ +config PLATFORM + string + default "hi3516dv300" if PLATFORM_HI3516DV300 + default "hi3518ev300" if PLATFORM_HI3518EV300 + default "virt" if PLATFORM_QEMU_ARM_VIRT_CA7 + +config PRODUCT_NAME + string "product name" + default "ipcamera_hi3516dv300_liteos" if PRODUCT_IPCAMERA_HI3516DV300_LITEOS + default "ipcamera_hi3518ev300_liteos" if PRODUCT_IPCAMERA_HI3518EV300_LITEOS + default "hispark_taurus" if PRODUCT_HISPARK_TAURUS + default "hispark_aries" if PRODUCT_HISPARK_ARIES + default "arm_virt" if PRODUCT_QEMU_ARM + +config DEVICE_COMPANY + string "vendor name" + default "hisilicon" if PLATFORM_HI3516DV300 + default "hisilicon" if PLATFORM_HI3518EV300 + default "qemu" if PLATFORM_QEMU_ARM_VIRT_CA7 + +choice + prompt "Chip" + default PLATFORM_HI3516DV300 + help + IP Camera has several chips: + - hi3516dv300 + - hi3518ev300 + Qemu ARM Virt variants (based on different CPU types): + - qemu_arm_virt_ca7 + - stm32mp157 + +config PLATFORM_HI3516DV300 + bool "hi3516dv300" + select ARCH_CORTEX_A7 + +config PLATFORM_HI3518EV300 + bool "hi3518ev300" + select ARCH_CORTEX_A7 + +config PLATFORM_QEMU_ARM_VIRT_CA7 + bool "qemu_arm_virt_ca7" + select ARCH_CORTEX_A7 + help + QEMU ARM Virtual Platform using Cortex-A7 CPU. +config PLATFORM_STM32MP157 + bool "stm32mp157" + select ARCH_CORTEX_A7 +endchoice + +choice + prompt "Product" + help + Select your target board. + +config PRODUCT_IPCAMERA_HI3516DV300_LITEOS + bool "ipcamera_hi3516dv300_liteos" if PLATFORM_HI3516DV300 +config PRODUCT_HISPARK_TAURUS + bool "hispark_taurus" if PLATFORM_HI3516DV300 + +config PRODUCT_IPCAMERA_HI3518EV300_LITEOS + bool "ipcamera_hi3518ev300_liteos" if PLATFORM_HI3518EV300 +config PRODUCT_HISPARK_ARIES + bool "hispark_aries" if PLATFORM_HI3518EV300 + +config PRODUCT_QEMU_ARM + bool "arm_virt" if PLATFORM_QEMU_ARM_VIRT_CA7 + +config LOSCFG_PRODUCT_BEARPI_HM_MICRO + bool "bearpi_hm_micro" if PLATFORM_STM32MP157 +endchoice + +config BOARD_CONFIG_PATH + string "Board config path" + default "config/board" + +config TEE_ENABLE + bool "Enable TEE" + default n + depends on PLATFORM_HI3516DV300 + help + Enable teeos in platform + +config HRTIMER_ENABLE + bool "HR TIMER enable" + default y + help + Enable High-resolution timer support + diff --git a/src/kernel_liteos_a/platform/Makefile b/src/kernel_liteos_a/platform/Makefile new file mode 100644 index 00000000..cd1eeef8 --- /dev/null +++ b/src/kernel_liteos_a/platform/Makefile @@ -0,0 +1,40 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +BOARD_LD = $(OUT)/lib/board.ld +$(BOARD_LD): board.ld.S + $(HIDE)$(CC) $(LITEOS_CFLAGS) -P -E $< -o $@ + +.PHONY: all clean +clean: + $(HIDE)$(RM) $(BOARD_LD) + +all: $(BOARD_LD) diff --git a/src/kernel_liteos_a/platform/board.ld.S b/src/kernel_liteos_a/platform/board.ld.S new file mode 100644 index 00000000..92788d04 --- /dev/null +++ b/src/kernel_liteos_a/platform/board.ld.S @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_vm_zone.h" + +#define TEXT_BASE KERNEL_VADDR_BASE + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) + +MEMORY +{ + ram : ORIGIN = KERNEL_VADDR_BASE, LENGTH = KERNEL_VADDR_SIZE + sram : ORIGIN = 0x40000000, LENGTH = 0x1000 + user_ram : ORIGIN = 0x1000000, LENGTH = 0x100000 +} +SECTIONS +{ + /DISCARD/ : { *(.comment .note) } + + .ram_vectors TEXT_BASE : { + __ram_vectors_vma = .; + KEEP (*(.vectors)) + } > ram + __ram_vectors_lma = LOADADDR(.ram_vectors); +} + +USER_INIT_VM_START = 0x1000000; diff --git a/src/kernel_liteos_a/platform/bsp.mk b/src/kernel_liteos_a/platform/bsp.mk new file mode 100644 index 00000000..c497e9d8 --- /dev/null +++ b/src/kernel_liteos_a/platform/bsp.mk @@ -0,0 +1,38 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +LITEOS_BASELIB += -lbsp_config + +PLATFORM_BSP_BASE := $(LITEOSTOPDIR)/platform + +PLATFORM_INCLUDE := -I $(LITEOSTOPDIR)/../../$(LOSCFG_BOARD_CONFIG_PATH) \ + -I $(LITEOSTOPDIR)/../../$(LOSCFG_BOARD_CONFIG_PATH)/include \ + +LIB_SUBDIRS += $(PLATFORM_BSP_BASE) $(LITEOSTOPDIR)/../../$(LOSCFG_BOARD_CONFIG_PATH) +LITEOS_PLATFORM_INCLUDE += $(PLATFORM_INCLUDE) diff --git a/src/kernel_liteos_a/security/BUILD.gn b/src/kernel_liteos_a/security/BUILD.gn new file mode 100644 index 00000000..1a7f6f3f --- /dev/null +++ b/src/kernel_liteos_a/security/BUILD.gn @@ -0,0 +1,44 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +group("security") { + deps = [ + "cap", + "vid", + ] +} + +config("public") { + configs = [ + "cap:public", + "vid:public", + ] +} diff --git a/src/kernel_liteos_a/security/Kconfig b/src/kernel_liteos_a/security/Kconfig new file mode 100644 index 00000000..4db2381b --- /dev/null +++ b/src/kernel_liteos_a/security/Kconfig @@ -0,0 +1,30 @@ +config SECURITY + bool "Enable Security Module" + default y + help + This option will enable security module. This is a basic feature, + so you should say Y here. + +config SECURITY_CAPABILITY + bool "Enable Syscall Capability" + default y + depends on SECURITY + help + This option will enable capability control for syscalls. This is a basic feature, + so you should say Y here. + +config SECURITY_VID + bool "Enable visual ID" + default y + depends on SECURITY + help + This option will enable visual ID for timer. This is a basic feature, + so you should say Y here. + +config SECURITY_BOOT + bool "Enable security boot" + default n + depends on SECURITY + help + This option will enable security boot. + diff --git a/src/kernel_liteos_a/security/Makefile b/src/kernel_liteos_a/security/Makefile new file mode 100644 index 00000000..e17501e9 --- /dev/null +++ b/src/kernel_liteos_a/security/Makefile @@ -0,0 +1,48 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) +LOCAL_SRCS := +LOCAL_INCLUDE := + +ifeq ($(LOSCFG_SECURITY_CAPABILITY), y) +LOCAL_SRCS += $(wildcard cap/*.c) +LOCAL_INCLUDE += -I $(LITEOSTOPDIR)/security/cap +endif + +ifeq ($(LOSCFG_SECURITY_VID), y) +LOCAL_SRCS += $(wildcard vid/*.c) +LOCAL_INCLUDE += -I $(LITEOSTOPDIR)/security/vid +endif + +LOCAL_FLAGS := $(LOCAL_INCLUDE) + +include $(MODULE) diff --git a/src/kernel_liteos_a/security/cap/BUILD.gn b/src/kernel_liteos_a/security/cap/BUILD.gn new file mode 100644 index 00000000..a4e95342 --- /dev/null +++ b/src/kernel_liteos_a/security/cap/BUILD.gn @@ -0,0 +1,41 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = defined(LOSCFG_SECURITY_CAPABILITY) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ "capability.c" ] + public_configs = [ ":public" ] +} + +config("public") { + include_dirs = [ "." ] +} diff --git a/src/kernel_liteos_a/security/cap/Makefile b/src/kernel_liteos_a/security/cap/Makefile new file mode 100644 index 00000000..8d11bbf2 --- /dev/null +++ b/src/kernel_liteos_a/security/cap/Makefile @@ -0,0 +1,36 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := $(wildcard *.c) + +include $(MODULE) diff --git a/src/kernel_liteos_a/security/cap/capability.c b/src/kernel_liteos_a/security/cap/capability.c new file mode 100644 index 00000000..28e7a9ff --- /dev/null +++ b/src/kernel_liteos_a/security/cap/capability.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "capability_type.h" +#include "los_memory.h" +#include "los_process_pri.h" +#include "user_copy.h" +#include "los_printf.h" + +#define CAPABILITY_INIT_STAT 0xffffffff +#define CAPABILITY_GET_CAP_MASK(x) (1 << ((x) & 31)) +#define CAPABILITY_MAX 31 +#define VALID_CAPS(a, b) (((a) & (~(b))) != 0) + +BOOL IsCapPermit(UINT32 capIndex) +{ + UINT32 capability = OsCurrProcessGet()->capability; + if (capIndex > CAPABILITY_MAX || capIndex < 0) { + PRINTK("%s,%d, get invalid capIndex %u\n", __FUNCTION__, __LINE__, capIndex); + return FALSE; + } + + return (capability & (CAPABILITY_GET_CAP_MASK(capIndex))); +} + +VOID OsInitCapability(LosProcessCB *processCB) +{ + processCB->capability = CAPABILITY_INIT_STAT; +} + +VOID OsCopyCapability(LosProcessCB *from, LosProcessCB *to) +{ + UINT32 intSave; + + SCHEDULER_LOCK(intSave); + to->capability = from->capability; + SCHEDULER_UNLOCK(intSave); +} + +UINT32 SysCapSet(UINT32 caps) +{ + UINT32 intSave; + + SCHEDULER_LOCK(intSave); + if (!IsCapPermit(CAP_CAPSET)) { + SCHEDULER_UNLOCK(intSave); + return -EPERM; + } + + if (VALID_CAPS(caps, OsCurrProcessGet()->capability)) { + SCHEDULER_UNLOCK(intSave); + return -EPERM; + } + + OsCurrProcessGet()->capability = caps; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +UINT32 SysCapGet(pid_t pid, UINT32 *caps) +{ + UINT32 intSave; + UINT32 kCaps; + LosProcessCB *processCB = NULL; + + if ((OS_PID_CHECK_INVALID((UINT32)pid))) { + return -EINVAL; + } + + if (pid == 0) { + processCB = OsCurrProcessGet(); + } else { + processCB = OS_PCB_FROM_PID(pid); + } + + SCHEDULER_LOCK(intSave); + if (OsProcessIsInactive(processCB)) { + SCHEDULER_UNLOCK(intSave); + return -ESRCH; + } + + kCaps = processCB->capability; + SCHEDULER_UNLOCK(intSave); + + if (LOS_ArchCopyToUser(caps, &kCaps, sizeof(UINT32)) != LOS_OK) { + return -EFAULT; + } + + return LOS_OK; +} diff --git a/src/kernel_liteos_a/security/cap/capability_api.h b/src/kernel_liteos_a/security/cap/capability_api.h new file mode 100644 index 00000000..51e7233d --- /dev/null +++ b/src/kernel_liteos_a/security/cap/capability_api.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef CAPABILITY_API_H +#define CAPABILITY_API_H +#include "los_process_pri.h" + +BOOL IsCapPermit(UINT32 capIndex); +VOID OsInitCapability(LosProcessCB *processCB); +VOID OsCopyCapability(LosProcessCB *from, LosProcessCB *to); +UINT32 SysCapSet(UINT32 caps); +UINT32 SysCapGet(pid_t pid, UINT32 *caps); +#endif diff --git a/src/kernel_liteos_a/security/cap/capability_type.h b/src/kernel_liteos_a/security/cap/capability_type.h new file mode 100644 index 00000000..dc239e34 --- /dev/null +++ b/src/kernel_liteos_a/security/cap/capability_type.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef CAPABILITY_TYPE_H +#define CAPABILITY_TYPE_H + +// posix capabilities +#define CAP_CHOWN 0 +#define CAP_DAC_EXECUTE 1 +#define CAP_DAC_WRITE 2 +#define CAP_DAC_READ_SEARCH 3 +#define CAP_FOWNER 4 +#define CAP_KILL 5 +#define CAP_SETGID 6 +#define CAP_SETUID 7 + +// socket capabilities +#define CAP_NET_BIND_SERVICE 8 +#define CAP_NET_BROADCAST 9 +#define CAP_NET_ADMIN 10 +#define CAP_NET_RAW 11 + +// fs capabilities +#define CAP_FS_MOUNT 12 +#define CAP_FS_FORMAT 13 + +// process capabilities +#define CAP_SCHED_SETPRIORITY 14 + +// time capabilities +#define CAP_SET_TIMEOFDAY 15 +#define CAP_CLOCK_SETTIME 16 + +// process capabilities +#define CAP_CAPSET 17 + +// reboot capability +#define CAP_REBOOT 18 +// self deined privileged syscalls +#define CAP_SHELL_EXEC 19 +#endif diff --git a/src/kernel_liteos_a/security/vid/BUILD.gn b/src/kernel_liteos_a/security/vid/BUILD.gn new file mode 100644 index 00000000..7b53edc7 --- /dev/null +++ b/src/kernel_liteos_a/security/vid/BUILD.gn @@ -0,0 +1,41 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = defined(LOSCFG_SECURITY_VID) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ "vid.c" ] + public_configs = [ ":public" ] +} + +config("public") { + include_dirs = [ "." ] +} diff --git a/src/kernel_liteos_a/security/vid/vid.c b/src/kernel_liteos_a/security/vid/vid.c new file mode 100644 index 00000000..98071cb7 --- /dev/null +++ b/src/kernel_liteos_a/security/vid/vid.c @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "vid_type.h" +#include "vid_api.h" +#include "los_memory.h" + +UINT32 VidMapListInit(LosProcessCB *processCB) +{ + (void)memset_s(&processCB->timerIdMap, sizeof(TimerIdMap), 0, sizeof(TimerIdMap)); + LOS_ListInit(&processCB->timerIdMap.head); + processCB->timerIdMap.bitMap = (UINT32*)LOS_MemAlloc(m_aucSysMem0, sizeof(UINT32)); + if (processCB->timerIdMap.bitMap == NULL) { + PRINT_ERR("%s %d, alloc memory failed\n", __FUNCTION__, __LINE__); + return LOS_NOK; + } + + processCB->timerIdMap.mapCount = 1; + (void)memset_s(processCB->timerIdMap.bitMap, sizeof(UINT32), 0, sizeof(UINT32)); + if (LOS_MuxInit(&processCB->timerIdMap.vidMapLock, NULL) != LOS_OK) { + PRINT_ERR("%s %d, Create mutex for vmm failed\n", __FUNCTION__, __LINE__); + LOS_MemFree(m_aucSysMem0, processCB->timerIdMap.bitMap); + processCB->timerIdMap.bitMap = NULL; + return LOS_NOK; + } + return LOS_OK; +} + +void VidMapDestroy(LosProcessCB *processCB) +{ + TimerIdMapNode *idNode = NULL; + TimerIdMapNode *idNodeNext = NULL; + + LOS_MuxLock(&processCB->timerIdMap.vidMapLock, LOS_WAIT_FOREVER); + LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(idNode, idNodeNext, &processCB->timerIdMap.head, TimerIdMapNode, node) { + LOS_ListDelete(&idNode->node); + LOS_MemFree(m_aucSysMem0, idNode); + } + + LOS_MuxUnlock(&processCB->timerIdMap.vidMapLock); + LOS_MemFree(m_aucSysMem0, processCB->timerIdMap.bitMap); + LOS_MuxDestroy(&processCB->timerIdMap.vidMapLock); +} + +static TimerIdMapNode *FindListNodeByVid(UINT16 vid) +{ + TimerIdMapNode *idNode = NULL; + LosProcessCB *processCB = OsCurrProcessGet(); + + LOS_MuxLock(&processCB->timerIdMap.vidMapLock, LOS_WAIT_FOREVER); + LOS_DL_LIST_FOR_EACH_ENTRY(idNode, &processCB->timerIdMap.head, TimerIdMapNode, node) { + if (vid == idNode->vid) { + LOS_MuxUnlock(&processCB->timerIdMap.vidMapLock); + return idNode; + } + } + LOS_MuxUnlock(&processCB->timerIdMap.vidMapLock); + + return NULL; +} + +static TimerIdMapNode *FindListNodeByRid(UINT32 rid) +{ + TimerIdMapNode *idNode = NULL; + LosProcessCB *processCB = OsCurrProcessGet(); + + LOS_MuxLock(&processCB->timerIdMap.vidMapLock, LOS_WAIT_FOREVER); + LOS_DL_LIST_FOR_EACH_ENTRY(idNode, &processCB->timerIdMap.head, TimerIdMapNode, node) { + if (rid == idNode->rid) { + LOS_MuxUnlock(&processCB->timerIdMap.vidMapLock); + return idNode; + } + } + LOS_MuxUnlock(&processCB->timerIdMap.vidMapLock); + + return NULL; +} + +static UINT16 GetFreeVid(VOID) +{ + UINT16 i, j; + UINT32 num; + UINT32 *tmp = NULL; + LosProcessCB *processCB = OsCurrProcessGet(); + TimerIdMap *idMap = &processCB->timerIdMap; + UINT16 mapMaxNum = idMap->mapCount; + + for (i = 0; i < mapMaxNum; i++) { + num = idMap->bitMap[i]; + for (j = 0; j < INT_BIT_COUNT; j++) { + if ((num & (1U << j)) == 0) { + num |= 1U << j; + idMap->bitMap[i] = num; + return (INT_BIT_COUNT * i + j); + } + } + } + + /* expand bit map */ + mapMaxNum++; + if (mapMaxNum > VID_MAP_MAX_NUM) { + PRINT_ERR("%s %d, timer vid run out\n", __FUNCTION__, __LINE__); + return MAX_INVALID_TIMER_VID; + } + + tmp = (UINT32*)LOS_MemAlloc(m_aucSysMem0, mapMaxNum * sizeof(UINT32)); + if (tmp == NULL) { + PRINT_ERR("%s %d, alloc memory failed\n", __FUNCTION__, __LINE__); + return MAX_INVALID_TIMER_VID; + } + + (void)memcpy_s(tmp, mapMaxNum * sizeof(UINT32), idMap->bitMap, (mapMaxNum - 1) * sizeof(UINT32)); + LOS_MemFree(m_aucSysMem0, idMap->bitMap); + idMap->bitMap = tmp; + idMap->mapCount = mapMaxNum; + idMap->bitMap[i] = 1; + return (INT_BIT_COUNT * i); +} + +static VOID ReleaseVid(UINT16 vid) +{ + UINT16 a, b; + UINT32 *tmpMap = NULL; + LosProcessCB *processCB = OsCurrProcessGet(); + TimerIdMap *idMap = &processCB->timerIdMap; + UINT16 mapMaxNum = idMap->mapCount; + + if (vid >= (VID_MAP_MAX_NUM * INT_BIT_COUNT)) { + return; + } + + a = vid >> INT_BIT_SHIFT; + b = vid & (INT_BIT_COUNT - 1); + + idMap->bitMap[a] &= ~(1U << b); + + /* shrink bit map */ + if (mapMaxNum > 1) { + if (idMap->bitMap[mapMaxNum - 1] == 0) { + mapMaxNum--; + tmpMap = LOS_MemRealloc(m_aucSysMem0, idMap->bitMap, mapMaxNum * sizeof(UINT32)); + if (tmpMap) { + idMap->bitMap = tmpMap; + idMap->mapCount = mapMaxNum; + } + } + } +} + +UINT16 AddNodeByRid(UINT16 rid) +{ + TimerIdMapNode *tmp = NULL; + LosProcessCB *processCB = OsCurrProcessGet(); + UINT16 vid; + + tmp = FindListNodeByRid(rid); + if (tmp) { + return tmp->vid; + } + + LOS_MuxLock(&processCB->timerIdMap.vidMapLock, LOS_WAIT_FOREVER); + vid = GetFreeVid(); + if (vid == MAX_INVALID_TIMER_VID) { + LOS_MuxUnlock(&processCB->timerIdMap.vidMapLock); + errno = ENOMEM; + return MAX_INVALID_TIMER_VID; + } + tmp = (TimerIdMapNode *)LOS_MemAlloc(m_aucSysMem0, sizeof(TimerIdMapNode)); + if (tmp == NULL) { + PRINT_ERR("%s %d, alloc memory failed\n", __FUNCTION__, __LINE__); + LOS_MuxUnlock(&processCB->timerIdMap.vidMapLock); + errno = ENOMEM; + return MAX_INVALID_TIMER_VID; + } + tmp->rid = rid; + tmp->vid = vid; + + LOS_ListTailInsert(&processCB->timerIdMap.head, &tmp->node); + LOS_MuxUnlock(&processCB->timerIdMap.vidMapLock); + + return vid; +} + +UINT16 GetRidByVid(UINT16 vid) +{ + TimerIdMapNode *tmp = FindListNodeByVid(vid); + if (tmp) { + return tmp->rid; + } + return 0xffff; +} + +void RemoveNodeByVid(UINT16 vid) +{ + TimerIdMapNode *tmp = NULL; + LosProcessCB *processCB = OsCurrProcessGet(); + + tmp = FindListNodeByVid(vid); + if (tmp == NULL) { + return; + } + + LOS_MuxLock(&processCB->timerIdMap.vidMapLock, LOS_WAIT_FOREVER); + LOS_ListDelete(&tmp->node); + ReleaseVid(tmp->vid); + LOS_MuxUnlock(&processCB->timerIdMap.vidMapLock); + LOS_MemFree(m_aucSysMem0, tmp); + + return; +} diff --git a/src/kernel_liteos_a/security/vid/vid_api.h b/src/kernel_liteos_a/security/vid/vid_api.h new file mode 100644 index 00000000..ade2baac --- /dev/null +++ b/src/kernel_liteos_a/security/vid/vid_api.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef VID_API_H +#define VID_API_H +#include "los_typedef.h" +#include "los_process_pri.h" + +#define INT_BIT_COUNT 32U +#define INT_BIT_SHIFT 5U +#define VID_MAP_MAX_NUM 32U + +#define MAX_INVALID_TIMER_VID (VID_MAP_MAX_NUM * INT_BIT_COUNT) + +UINT32 VidMapListInit(LosProcessCB *processCB); +VOID VidMapDestroy(LosProcessCB *processCB); +UINT16 AddNodeByRid(UINT16 rid); +UINT16 GetRidByVid(UINT16 vid); +VOID RemoveNodeByVid(UINT16 vid); +#endif \ No newline at end of file diff --git a/src/kernel_liteos_a/security/vid/vid_type.h b/src/kernel_liteos_a/security/vid/vid_type.h new file mode 100644 index 00000000..835e4716 --- /dev/null +++ b/src/kernel_liteos_a/security/vid/vid_type.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef VID_TYPE_H +#define VID_TYPE_H +#include "los_mux.h" + +typedef struct { + LosMux vidMapLock; + LOS_DL_LIST head; + UINT16 mapCount; + UINT32 *bitMap; +} TimerIdMap; + +typedef struct { + LOS_DL_LIST node; + UINT16 rid; + UINT16 vid; +} TimerIdMapNode; +#endif diff --git a/src/kernel_liteos_a/shell/BUILD.gn b/src/kernel_liteos_a/shell/BUILD.gn new file mode 100644 index 00000000..0eaa2922 --- /dev/null +++ b/src/kernel_liteos_a/shell/BUILD.gn @@ -0,0 +1,53 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = defined(LOSCFG_SHELL) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ + "full/src/base/shcmd.c", + "full/src/base/shcmdparse.c", + "full/src/base/shell_lk.c", + "full/src/base/shmsg.c", + "full/src/base/show.c", + "full/src/cmds/date_shellcmd.c", + "full/src/cmds/dmesg.c", + "full/src/cmds/hwi_shellcmd.c", + "full/src/cmds/shell_shellcmd.c", + "full/src/cmds/watch_shellcmd.c", + ] + + public_configs = [ ":public" ] +} + +config("public") { + include_dirs = [ "full/include" ] +} diff --git a/src/kernel_liteos_a/shell/Kconfig b/src/kernel_liteos_a/shell/Kconfig new file mode 100644 index 00000000..641c740a --- /dev/null +++ b/src/kernel_liteos_a/shell/Kconfig @@ -0,0 +1,25 @@ +config SHELL + bool "Enable Shell" + default y + depends on DEBUG_VERSION + help + Answer Y to enable LiteOS support shell cmd. + +menu "Functionality of Shell" + depends on SHELL + +config SHELL_LK + bool "Enable Shell lk" + default y + depends on DEBUG_VERSION && SHELL + help + Answer Y to enable LiteOS support shell lk. + +config SHELL_DMESG + bool "Enable Shell dmesg" + default n + depends on DEBUG_VERSION && SHELL && SHELL_CMD_DEBUG + help + Answer Y to enable LiteOS support shell dmesg. + +endmenu diff --git a/src/kernel_liteos_a/shell/Makefile b/src/kernel_liteos_a/shell/Makefile new file mode 100644 index 00000000..662229b4 --- /dev/null +++ b/src/kernel_liteos_a/shell/Makefile @@ -0,0 +1,44 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +ifeq ($(LOSCFG_SHELL), y) +LOCAL_SRCS := $(wildcard full/src/base/*.c) $(wildcard full/src/cmds/*.c) +LOCAL_INCLUDE := \ + -I $(LITEOSTOPDIR)/fs/nfs \ + -I $(LITEOSTOPDIR)/fs/ramfs + +endif + +LOCAL_FLAGS := $(LOCAL_INCLUDE) + +include $(MODULE) diff --git a/src/kernel_liteos_a/shell/full/include/dmesg.h b/src/kernel_liteos_a/shell/full/include/dmesg.h new file mode 100644 index 00000000..370d3271 --- /dev/null +++ b/src/kernel_liteos_a/shell/full/include/dmesg.h @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _HWLITEOS_SHELL_DMESG_H +#define _HWLITEOS_SHELL_DMESG_H +#include "los_config.h" +#ifdef LOSCFG_SHELL_DMESG + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup dmesg + * Defalut dmesg buffer size. + */ +#define KERNEL_LOG_BUF_SIZE (8 * 1024) + +/** + * @ingroup dmesg + * Max dmesg buffer size to set. + */ +#define MAX_KERNEL_LOG_BUF_SIZE (8 * 1024 * 10) + +/** + * @ingroup dmesg + * @brief Set dmesg buffer. + * + * @par Description: + * This API is used to set dmesg buffer to memory-assigned, or just change the buffer size. + * + * @attention + *
          + *
        • If the addr is NULL, this function will only change the buffer size.
        • + *
        + * + * @param addr [IN] Type #VOID* The addr of memory space to set. + * @param size [IN] Type #UINT32 The dmesg buffer size to set, depend on the app user, should be a valid value, + * otherwise system will crash, and should not larger than MAX_KERNEL_LOG_BUF_SIZE. + * + * @retval #LOS_NOK Set dmesg buffer fail. + * @retval #LOS_OK Set dmesg buffer success. + * @par Dependency: + *
        • dmesg.h: the header file that contains the API declaration.
        + * @see LOS_DmesgMemSet + */ +extern UINT32 LOS_DmesgMemSet(const VOID *addr, UINT32 size); + +/** + * @ingroup dmesg + * @brief Read log from dmesg buffer. + * + * @par Description: + * This API is used to get log from dmesg buffer in core and copy to the point buffer. + * + * @attention + *
          + *
        • Length of log been read may be less than the len if log in dmesg buffer is not enough.
        • + *
        + * + * @param buf [IN] Type #CHAR* The buffer expected copy to. + * @param len [IN] Type #UINT32 The maximum number of bytes that can be accommodated in the buf. + * + * @retval #-1 Read log from dmesg buffer fail. + * @retval #0 Nothing has been read. + * @retval #INT32 The length of log has been read. + * @par Dependency: + *
        • dmesg.h: the header file that contains the API declaration.
        + * @see LOS_DmesgRead + */ +extern INT32 LOS_DmesgRead(CHAR *buf, UINT32 len); + +/** + * @ingroup dmesg + * @brief Clear dmesg log. + * + * @par Description: + * This API is used to clear dmesg log. + * + * @attention None. + * + * @param None. + * + * @retval None. + * @par Dependency: + *
        • dmesg.h: the header file that contains the API declaration.
        + * @see LOS_DmesgClear + */ +extern VOID LOS_DmesgClear(VOID); + +/** + * @ingroup dmesg + * @brief Copy log to file. + * + * @par Description: + * This API is used to copy all log from dmesg buffer and write it to the file. + * + * @attention + *
          + *
        • Files rely on file system, the file system of filename dependent must be already mounted.
        • + *
        + * + * @param filename [IN] Type #CHAR* The buffer expected copy to. + * + * @retval #-1 Copy log to file fail. + * @retval #0 Maybe there is no log in the buffer. + * @retval #INT32 The length of log has been written to file. + * @par Dependency: + *
        • dmesg.h: the header file that contains the API declaration.
        + * @see LOS_DmesgToFile + */ +extern INT32 LOS_DmesgToFile(const CHAR *filename); + +/** + * @ingroup dmesg + * @brief Set the dmesg level + * + * @par Description: + * This API is used to set the level of log that want to stored in dmesg buffer. + * + * @attention + *
          + *
        • It would be useless if the level is less than print level.
        • + *
        + * + * @param level [IN] Type #UINT32 The level expected to set, range from 0 to 5. + * + * @retval #1 Set dmesg level fail. + * @retval #0 Set dmesg level success. + * @par Dependency: + *
        • dmesg.h: the header file that contains the API declaration.
        + * @see LOS_DmesgLvSet + */ +extern UINT32 LOS_DmesgLvSet(UINT32 level); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ +#endif +#endif /* _HWLITEOS_SHELL_DMESG_H */ diff --git a/src/kernel_liteos_a/shell/full/include/dmesg_pri.h b/src/kernel_liteos_a/shell/full/include/dmesg_pri.h new file mode 100644 index 00000000..b6afcc53 --- /dev/null +++ b/src/kernel_liteos_a/shell/full/include/dmesg_pri.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _HWLITEOS_SHELL_DMESG_PRI_H +#define _HWLITEOS_SHELL_DMESG_PRI_H + +#ifdef LOSCFG_SHELL_DMESG +#include "dmesg.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/* + * The dmesg buffer is start with this info structure, then the log. + */ +typedef struct { + UINT32 logSize; /* The size of log in buffer */ + UINT32 logHead; /* The index of the first log data. Data_out_flag */ + UINT32 logTail; /* The index where to write, write in and plus one. Data_it_flag */ + CHAR *logBuf; /* The log buffer addr */ +} DmesgInfo; + +extern UINT32 OsDmesgInit(VOID); +extern UINT32 OsDmesgLvGet(VOID); +extern UINT32 OsCheckConsoleLock(VOID); +extern UINT32 OsCheckUartLock(VOID); +extern VOID OsLogShow(VOID); +extern UINT32 OsLogRecordStr(const CHAR *str, UINT32 len); +extern INT32 OsLogMemcpyRecord(const CHAR *buf, UINT32 logLen); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ +#endif +#endif /* _HWLITEOS_SHELL_DMESG_PRI_H */ \ No newline at end of file diff --git a/src/kernel_liteos_a/shell/full/include/shcmd.h b/src/kernel_liteos_a/shell/full/include/shcmd.h new file mode 100644 index 00000000..c38a3875 --- /dev/null +++ b/src/kernel_liteos_a/shell/full/include/shcmd.h @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _HWLITEOS_SHELL_SHCMD_H +#define _HWLITEOS_SHELL_SHCMD_H + +#include "string.h" +#include "stdlib.h" +#include "los_base.h" +#include "los_list.h" +#include "shcmdparse.h" +#include "show.h" + +#include "los_tables.h" +#include "console.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef BOOL (*CmdVerifyTransID)(UINT32 transID); + +typedef struct { + CmdType cmdType; + const CHAR *cmdKey; + UINT32 paraNum; + CmdCallBackFunc cmdHook; +} CmdItem; + +typedef struct { + LOS_DL_LIST list; + CmdItem *cmd; +} CmdItemNode; + +/* global info for shell module */ +typedef struct { + CmdItemNode cmdList; + UINT32 listNum; + UINT32 initMagicFlag; + LosMux muxLock; + CmdVerifyTransID transIdHook; +} CmdModInfo; + +typedef struct { + UINT32 count; + LOS_DL_LIST list; + CHAR cmdString[0]; +} CmdKeyLink; + +#define SHELLCMD_ENTRY(l, cmdType, cmdKey, paraNum, cmdHook) \ + CmdItem l LOS_HAL_TABLE_ENTRY(shellcmd) = { \ + cmdType, \ + cmdKey, \ + paraNum, \ + cmdHook \ + } + +#define NEED_NEW_LINE(timesPrint, lineCap) ((timesPrint) % (lineCap) == 0) +#define SCREEN_IS_FULL(timesPrint, lineCap) ((timesPrint) >= ((lineCap) * DEFAULT_SCREEN_HEIGHT)) + +extern UINT32 OsCmdInit(VOID); +extern CmdModInfo *OsCmdInfoGet(VOID); +extern UINT32 OsCmdExec(CmdParsed *cmdParsed, CHAR *cmdStr); +extern UINT32 OsCmdKeyShift(const CHAR *cmdKey, CHAR *cmdOut, UINT32 size); +extern INT32 OsTabCompletion(CHAR *cmdKey, UINT32 *len); +extern VOID OsShellCmdPush(const CHAR *string, CmdKeyLink *cmdKeyLink); +extern VOID OsShellHistoryShow(UINT32 value, ShellCB *shellCB); +extern UINT32 OsShellKeyInit(ShellCB *shellCB); +extern VOID OsShellKeyDeInit(CmdKeyLink *cmdKeyLink); +extern UINT32 OsShellSysCmdRegister(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif + +#endif /* _HWLITEOS_SHELL_SHCMD_H */ diff --git a/src/kernel_liteos_a/shell/full/include/shcmdparse.h b/src/kernel_liteos_a/shell/full/include/shcmdparse.h new file mode 100644 index 00000000..0bd690ce --- /dev/null +++ b/src/kernel_liteos_a/shell/full/include/shcmdparse.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _HWLITEOS_SHELL_SHCMDPARSE_H +#define _HWLITEOS_SHELL_SHCMDPARSE_H + +#include "string.h" +#include "show.h" +#include "los_base.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#define CMD_PARSED_RETCODE_BASE LOS_OK +#define CMD_PARSED_RETCODE_TYPE_INVALID (CMD_PARSED_RETCODE_BASE + 1) +#define CMD_PARSED_RETCODE_PARAM_OVERTOP (CMD_PARSED_RETCODE_BASE + 3) +#define CMD_PARSED_RETCODE_CMDKEY_NOTFOUND (CMD_PARSED_RETCODE_BASE + 4) + +typedef UINT32 (*FUNC_ONE_TOKEN)(VOID *ctx, UINT32 index, CHAR *token); + +/* + * Description: the info struct after cmd parser + */ +typedef struct { + UINT32 paramCnt; /* count of para */ + CmdType cmdType; /* cmd type, judge cmd keyword */ + CHAR cmdKeyword[CMD_KEY_LEN]; /* cmd keyword str */ + CHAR *paramArray[CMD_MAX_PARAS]; +} CmdParsed; + +extern UINT32 OsCmdParse(CHAR *cmdStr, CmdParsed *cmdParsed); +extern CHAR *OsCmdParseStrdup(const CHAR *str); +extern UINT32 OsCmdParseOneToken(CmdParsed *cmdParsed, UINT32 index, const CHAR *token); +extern UINT32 OsCmdTokenSplit(CHAR *cmdStr, CHAR split, CmdParsed *cmdParsed); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif + +#endif /* _HWLITEOS_SHELL_SHCMDPARSE_H */ diff --git a/src/kernel_liteos_a/shell/full/include/shell.h b/src/kernel_liteos_a/shell/full/include/shell.h new file mode 100644 index 00000000..765bd84e --- /dev/null +++ b/src/kernel_liteos_a/shell/full/include/shell.h @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _HWLITEOS_SHELL_H +#define _HWLITEOS_SHELL_H + +#include "pthread.h" +#include "limits.h" +#include "los_base.h" +#include "los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define OS_ERRNO_SHELL_NO_HOOK LOS_ERRNO_OS_ERROR(LOS_MOD_SHELL, 0x00) +#define OS_ERRNO_SHELL_CMDREG_PARA_ERROR LOS_ERRNO_OS_ERROR(LOS_MOD_SHELL, 0x01) +#define OS_ERRNO_SHELL_CMDREG_CMD_ERROR LOS_ERRNO_OS_ERROR(LOS_MOD_SHELL, 0x02) +#define OS_ERRNO_SHELL_CMDREG_CMD_EXIST LOS_ERRNO_OS_ERROR(LOS_MOD_SHELL, 0x03) +#define OS_ERRNO_SHELL_CMDREG_MEMALLOC_ERROR LOS_ERRNO_OS_ERROR(LOS_MOD_SHELL, 0x04) +#define OS_ERRNO_SHELL_SHOW_HOOK_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_SHELL, 0x05) +#define OS_ERRNO_SHELL_SHOW_HOOK_EXIST LOS_ERRNO_OS_ERROR(LOS_MOD_SHELL, 0x06) +#define OS_ERRNO_SHELL_SHOW_HOOK_TOO_MUCH LOS_ERRNO_OS_ERROR(LOS_MOD_SHELL, 0x07) +#define OS_ERRNO_SHELL_NOT_INIT LOS_ERRNO_OS_ERROR(LOS_MOD_SHELL, 0x08) +#define OS_ERRNO_SHELL_CMD_HOOK_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_SHELL, 0x09) +#define OS_ERRNO_SHELL_FIFO_ERROR LOS_ERRNO_OS_ERROR(LOS_MOD_SHELL, 0x10) + +/* Max len of show str */ +#define SHOW_MAX_LEN CMD_MAX_LEN + +#define XARGS 0xFFFFFFFF /* default args */ + +#define CMD_MAX_PARAS 32 +#define CMD_KEY_LEN 16U +#define CMD_MAX_LEN (256U + CMD_KEY_LEN) +#define CMD_KEY_NUM 32 +#define CMD_HISTORY_LEN 10 +#define CMD_MAX_PATH 256 +#define DEFAULT_SCREEN_WIDTH 80 +#define DEFAULT_SCREEN_HEIGHT 24 + +#define SHELL_MODE 0 +#define OTHER_MODE 1 + +#define SWITCH_QUOTES_STATUS(qu) do { \ + if ((qu) == TRUE) { \ + (qu) = FALSE; \ + } else { \ + (qu) = TRUE; \ + } \ +} while (0) + +#define QUOTES_STATUS_CLOSE(qu) ((qu) == FALSE) +#define QUOTES_STATUS_OPEN(qu) ((qu) == TRUE) + +typedef struct { + UINT32 consoleID; + UINT32 shellTaskHandle; + UINT32 shellEntryHandle; + VOID *cmdKeyLink; + VOID *cmdHistoryKeyLink; + VOID *cmdMaskKeyLink; + UINT32 shellBufOffset; + UINT32 shellKeyType; + EVENT_CB_S shellEvent; + pthread_mutex_t keyMutex; + pthread_mutex_t historyMutex; + CHAR shellBuf[SHOW_MAX_LEN]; + CHAR shellWorkingDirectory[PATH_MAX]; +} ShellCB; + +/* All support cmd types */ +typedef enum { + CMD_TYPE_SHOW = 0, + CMD_TYPE_STD = 1, + CMD_TYPE_EX = 2, + CMD_TYPE_BUTT +} CmdType; + +typedef enum { + CMD_KEY_UP = 0, + CMD_KEY_DOWN = 1, + CMD_KEY_RIGHT = 2, + CMD_KEY_LEFT = 4, + CMD_KEY_BUTT +} CmdKeyDirection; + +/* + * Hook for user-defined debug function + * Unify different module's func for registration + */ +typedef UINT32 (*CmdCallBackFunc)(UINT32 argc, const CHAR **argv); + +/* External interface, need reserved */ +typedef CmdCallBackFunc CMD_CBK_FUNC; +typedef CmdType CMD_TYPE_E; + +extern UINT32 osCmdReg(CmdType cmdType, const CHAR *cmdKey, UINT32 paraNum, CmdCallBackFunc cmdProc); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _HWLITEOS_SHELL_H */ diff --git a/src/kernel_liteos_a/shell/full/include/shell_lk.h b/src/kernel_liteos_a/shell/full/include/shell_lk.h new file mode 100644 index 00000000..288331a7 --- /dev/null +++ b/src/kernel_liteos_a/shell/full/include/shell_lk.h @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _HWLITEOS_SHELL_LK_H +#define _HWLITEOS_SHELL_LK_H + +/** + * @defgroup shell_lk lk + * @ingroup shell + */ +#include "stdarg.h" +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup shell_lk + * define sys default print level + */ +#define TRACE_DEFAULT PRINT_LEVEL + +/** + * @ingroup shell_lk + * @brief Define an printf handling function hook. + * + * @par Description: + * This API is used to define the printf handling function hook. + * @attention None. + * + * @param level [IN] print level. + * @param func [IN] means which func calls print func. + * @param line [IN] means which line calls print func. + * @param fmt [IN] other information by user define. + * @param ap [IN] the para list. + * + * @retval None. + * + * @par Dependency: + * shell_lk.h: the header file that contains the API declaration. + * @see None. + */ +typedef VOID (*LK_FUNC)(INT32 level, const CHAR *func, INT32 line, const CHAR *fmt, va_list ap); + +/** + * @ingroup shell_lk + * @brief print log. + * + * @par Description: + *
          + *
        • This API is used to LK print function.
        • + *
        + * + * @param level [IN] print level. + * @param func [IN] means which func calls print func. + * @param line [IN] means which line calls print func. + * @param fmt [IN] other information by user define + * + * @retval NONE + * @par Dependency: + *
        • shell_lk.h: the header file that contains the API declaration.
        + */ +extern VOID LOS_LkPrint(INT32 level, const CHAR *func, INT32 line, const CHAR *fmt, ...); + +/** + * @ingroup shell_lk + * @brief register print func. + * + * @par Description: + *
          + *
        • This API is used to register a hook function to LK.
        • + *
        + * + * @param LK_FUNC [IN] the print func. + * + * @retval NONE + * @par Dependency: + *
        • shell_lk.h: the header file that contains the API declaration.
        + */ +extern VOID LOS_LkRegHook(LK_FUNC hook); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _HWLITEOS_SHELL_LK_H */ diff --git a/src/kernel_liteos_a/shell/full/include/shell_pri.h b/src/kernel_liteos_a/shell/full/include/shell_pri.h new file mode 100644 index 00000000..603e79d9 --- /dev/null +++ b/src/kernel_liteos_a/shell/full/include/shell_pri.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _HWLITEOS_SHELL_PRI_H +#define _HWLITEOS_SHELL_PRI_H + +#include "shcmd.h" +#include "los_config.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#ifdef LOSCFG_SHELL_LK +extern UINT32 OsLkLoggerInit(VOID); +#endif + +extern CmdItem g_shellcmd[]; +extern CmdItem g_shellcmdEnd; + +extern UINT32 ShellEntry(UINTPTR param); +extern UINT32 ShellTask(UINTPTR param1, UINTPTR param2, UINTPTR param3, UINTPTR param4); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _HWLITEOS_SHELL_PRI_H */ \ No newline at end of file diff --git a/src/kernel_liteos_a/shell/full/include/shmsg.h b/src/kernel_liteos_a/shell/full/include/shmsg.h new file mode 100644 index 00000000..87babf53 --- /dev/null +++ b/src/kernel_liteos_a/shell/full/include/shmsg.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _HWLITEOS_SHELL_SHMSG_H +#define _HWLITEOS_SHELL_SHMSG_H + +#include "shell.h" +#include "shcmdparse.h" +#include "console.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +extern UINT32 ShellMsgParse(const VOID *msg); +extern UINT32 ShellTaskInit(ShellCB *shellCB); +extern UINT32 ShellEntryInit(ShellCB *shellCB); +extern VOID ShellCmdLineParse(CHAR c, pf_OUTPUT outputFunc, ShellCB *shellCB); +extern UINT32 ShellMsgTypeGet(CmdParsed *cmdParsed, const CHAR *cmdType); +#define SHELL_CMD_PARSE_EVENT 0x111 + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _HWLITEOS_SHELL_SHMSG_H */ diff --git a/src/kernel_liteos_a/shell/full/include/show.h b/src/kernel_liteos_a/shell/full/include/show.h new file mode 100644 index 00000000..469637e4 --- /dev/null +++ b/src/kernel_liteos_a/shell/full/include/show.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _HWLITEOS_SHELL_SHOW_H +#define _HWLITEOS_SHELL_SHOW_H + +#include "shell.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +extern CHAR *OsShellGetWorkingDirectory(VOID); +extern UINT32 OsShellInit(INT32 consoleId); +extern INT32 OsShellDeinit(INT32 consoleId); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _HWLITEOS_SHELL_SHOW_H */ \ No newline at end of file diff --git a/src/kernel_liteos_a/shell/full/src/base/shcmd.c b/src/kernel_liteos_a/shell/full/src/base/shcmd.c new file mode 100644 index 00000000..9e6e7894 --- /dev/null +++ b/src/kernel_liteos_a/shell/full/src/base/shcmd.c @@ -0,0 +1,866 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "shcmd.h" +#include "shell_pri.h" +#include "show.h" +#include "stdlib.h" +#include "unistd.h" +#include "dirent.h" +#include "securec.h" +#include "los_mux.h" +#include "los_memory.h" +#include "los_typedef.h" + + +#define SHELL_INIT_MAGIC_FLAG 0xABABABAB +#define CTRL_C 0x03 /* 0x03: ctrl+c ASCII */ + +STATIC CmdModInfo g_cmdInfo; + +LOS_HAL_TABLE_BEGIN(g_shellcmd, shellcmd); +LOS_HAL_TABLE_END(g_shellcmdEnd, shellcmd); + +CmdModInfo *OsCmdInfoGet(VOID) +{ + return &g_cmdInfo; +} + +STATIC VOID OsFreeCmdPara(CmdParsed *cmdParsed) +{ + UINT32 i; + for (i = 0; i < cmdParsed->paramCnt; i++) { + if ((cmdParsed->paramArray[i]) != NULL) { + (VOID)LOS_MemFree(m_aucSysMem0, (cmdParsed->paramArray[i])); + cmdParsed->paramArray[i] = NULL; + } + } +} + +STATIC INT32 OsStrSeparateTabStrGet(CHAR **tabStr, CmdParsed *parsed, UINT32 tabStrLen) +{ + CHAR *shiftStr = NULL; + CHAR *tempStr = (CHAR *)LOS_MemAlloc(m_aucSysMem0, SHOW_MAX_LEN << 1); + if (tempStr == NULL) { + return (INT32)OS_ERROR; + } + + (VOID)memset_s(tempStr, SHOW_MAX_LEN << 1, 0, SHOW_MAX_LEN << 1); + shiftStr = tempStr + SHOW_MAX_LEN; + + if (strncpy_s(tempStr, SHOW_MAX_LEN - 1, *tabStr, tabStrLen)) { + (VOID)LOS_MemFree(m_aucSysMem0, tempStr); + return (INT32)OS_ERROR; + } + + parsed->cmdType = CMD_TYPE_STD; + + /* cut useless or repeat space */ + if (OsCmdKeyShift(tempStr, shiftStr, SHOW_MAX_LEN - 1)) { + (VOID)LOS_MemFree(m_aucSysMem0, tempStr); + return (INT32)OS_ERROR; + } + + /* get exact position of string to complete */ + /* situation different if end space lost or still exist */ + if ((strlen(shiftStr) == 0) || (tempStr[strlen(tempStr) - 1] != shiftStr[strlen(shiftStr) - 1])) { + *tabStr = ""; + } else { + if (OsCmdTokenSplit(shiftStr, ' ', parsed)) { + (VOID)LOS_MemFree(m_aucSysMem0, tempStr); + return (INT32)OS_ERROR; + } + *tabStr = parsed->paramArray[parsed->paramCnt - 1]; + } + + (VOID)LOS_MemFree(m_aucSysMem0, tempStr); + return LOS_OK; +} + +STATIC INT32 OsStrSeparate(CHAR *tabStr, CHAR *strPath, CHAR *nameLooking, UINT32 tabStrLen) +{ + CHAR *strEnd = NULL; + CHAR *cutPos = NULL; + CmdParsed parsed = {0}; + CHAR *shellWorkingDirectory = OsShellGetWorkingDirectory(); + INT32 ret; + + ret = OsStrSeparateTabStrGet(&tabStr, &parsed, tabStrLen); + if (ret != LOS_OK) { + return ret; + } + + /* get fullpath str */ + if (*tabStr != '/') { + if (strncpy_s(strPath, CMD_MAX_PATH, shellWorkingDirectory, CMD_MAX_PATH - 1)) { + OsFreeCmdPara(&parsed); + return (INT32)OS_ERROR; + } + if (strcmp(shellWorkingDirectory, "/")) { + if (strncat_s(strPath, CMD_MAX_PATH, "/", CMD_MAX_PATH - strlen(strPath) - 1)) { + OsFreeCmdPara(&parsed); + return (INT32)OS_ERROR; + } + } + } + + if (strncat_s(strPath, CMD_MAX_PATH, tabStr, CMD_MAX_PATH - strlen(strPath) - 1)) { + OsFreeCmdPara(&parsed); + return (INT32)OS_ERROR; + } + + /* split str by last '/' */ + strEnd = strrchr(strPath, '/'); + cutPos = strEnd; + if (strEnd != NULL) { + if (strncpy_s(nameLooking, CMD_MAX_PATH, strEnd + 1, CMD_MAX_PATH - 1)) { /* get cmp str */ + OsFreeCmdPara(&parsed); + return (INT32)OS_ERROR; + } + *(cutPos + 1) = '\0'; + } + + OsFreeCmdPara(&parsed); + return LOS_OK; +} + +STATIC INT32 OsShowPageInputControl(VOID) +{ + CHAR readChar; + + while (1) { + if (read(STDIN_FILENO, &readChar, 1) != 1) { /* get one CHAR from stdin */ + PRINTK("\n"); + return (INT32)OS_ERROR; + } + if ((readChar == 'q') || (readChar == 'Q') || (readChar == CTRL_C)) { + PRINTK("\n"); + return 0; + } else if (readChar == '\r') { + PRINTK("\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b"); + return 1; + } + } +} + +STATIC INT32 OsShowPageControl(UINT32 timesPrint, UINT32 lineCap, UINT32 count) +{ + if (NEED_NEW_LINE(timesPrint, lineCap)) { + PRINTK("\n"); + if (SCREEN_IS_FULL(timesPrint, lineCap) && (timesPrint < count)) { + PRINTK("--More--"); + return OsShowPageInputControl(); + } + } + return 1; +} + +STATIC INT32 OsSurePrintAll(UINT32 count) +{ + CHAR readChar = 0; + PRINTK("\nDisplay all %u possibilities?(y/n)", count); + while (1) { + if (read(0, &readChar, 1) != 1) { + return (INT32)OS_ERROR; + } + if ((readChar == 'n') || (readChar == 'N') || (readChar == CTRL_C)) { + PRINTK("\n"); + return 0; + } else if ((readChar == 'y') || (readChar == 'Y') || (readChar == '\r')) { + return 1; + } + } +} + +STATIC INT32 OsPrintMatchList(UINT32 count, const CHAR *strPath, const CHAR *nameLooking, UINT32 printLen) +{ + UINT32 timesPrint = 0; + UINT32 lineCap; + INT32 ret; + DIR *openDir = NULL; + struct dirent *readDir = NULL; + CHAR formatChar[10] = {0}; /* 10:for formatChar length */ + + printLen = (printLen > (DEFAULT_SCREEN_WIDTH - 2)) ? (DEFAULT_SCREEN_WIDTH - 2) : printLen; /* 2:revered 2 bytes */ + lineCap = DEFAULT_SCREEN_WIDTH / (printLen + 2); /* 2:DEFAULT_SCREEN_WIDTH revered 2 bytes */ + if (snprintf_s(formatChar, sizeof(formatChar) - 1, 7, "%%-%us ", printLen) < 0) { /* 7:format-len */ + return (INT32)OS_ERROR; + } + + if (count > (lineCap * DEFAULT_SCREEN_HEIGHT)) { + ret = OsSurePrintAll(count); + if (ret != 1) { + return ret; + } + } + openDir = opendir(strPath); + if (openDir == NULL) { + return (INT32)OS_ERROR; + } + + PRINTK("\n"); + for (readDir = readdir(openDir); readDir != NULL; readDir = readdir(openDir)) { + if (strncmp(nameLooking, readDir->d_name, strlen(nameLooking)) != 0) { + continue; + } + PRINTK(formatChar, readDir->d_name); + timesPrint++; + ret = OsShowPageControl(timesPrint, lineCap, count); + if (ret != 1) { + if (closedir(openDir) < 0) { + return (INT32)OS_ERROR; + } + return ret; + } + } + + PRINTK("\n"); + if (closedir(openDir) < 0) { + return (INT32)OS_ERROR; + } + + return LOS_OK; +} + +STATIC VOID strncmp_cut(const CHAR *s1, CHAR *s2, size_t n) +{ + if ((n == 0) || (s1 == NULL) || (s2 == NULL)) { + return; + } + do { + if (*s1 && *s2 && (*s1 == *s2)) { + s1++; + s2++; + } else { + break; + } + } while (--n != 0); + if (n > 0) { + /* NULL pad the remaining n-1 bytes */ + while (n-- != 0) + *s2++ = 0; + } + return; +} +STATIC INT32 OsExecNameMatch(const CHAR *strPath, const CHAR *nameLooking, CHAR *strObj, UINT32 *maxLen) +{ + INT32 count = 0; + DIR *openDir = NULL; + struct dirent *readDir = NULL; + + openDir = opendir(strPath); + if (openDir == NULL) { + return (INT32)OS_ERROR; + } + + for (readDir = readdir(openDir); readDir != NULL; readDir = readdir(openDir)) { + if (strncmp(nameLooking, readDir->d_name, strlen(nameLooking)) != 0) { + continue; + } + if (count == 0) { + if (strncpy_s(strObj, CMD_MAX_PATH, readDir->d_name, CMD_MAX_PATH - 1)) { + (VOID)closedir(openDir); + return (INT32)OS_ERROR; + } + *maxLen = strlen(readDir->d_name); + } else { + /* strncmp&cut the same strings of name matched */ + strncmp_cut(readDir->d_name, strObj, strlen(strObj)); + if (strlen(readDir->d_name) > *maxLen) { + *maxLen = strlen(readDir->d_name); + } + } + count++; + } + + if (closedir(openDir) < 0) { + return (INT32)OS_ERROR; + } + + return count; +} + +STATIC VOID OsCompleteStr(const CHAR *result, const CHAR *target, CHAR *cmdKey, UINT32 *len) +{ + UINT32 size = strlen(result) - strlen(target); + CHAR *des = cmdKey + *len; + CHAR *src = (CHAR *)result + strlen(target); + + while (size-- > 0) { + PRINTK("%c", *src); + if (*len == (SHOW_MAX_LEN - 1)) { + *des = '\0'; + break; + } + *des++ = *src++; + (*len)++; + } +} + +STATIC INT32 OsTabMatchCmd(CHAR *cmdKey, UINT32 *len) +{ + INT32 count = 0; + INT32 ret; + CmdItemNode *cmdItemGuard = NULL; + CmdItemNode *curCmdItem = NULL; + const CHAR *cmdMajor = (const CHAR *)cmdKey; + + while (*cmdMajor == 0x20) { /* cut left space */ + cmdMajor++; + } + + if (LOS_ListEmpty(&(g_cmdInfo.cmdList.list))) { + return (INT32)OS_ERROR; + } + + LOS_DL_LIST_FOR_EACH_ENTRY(curCmdItem, &(g_cmdInfo.cmdList.list), CmdItemNode, list) { + if ((curCmdItem == NULL) || (curCmdItem->cmd == NULL)) { + return -1; + } + + if (strncmp(cmdMajor, curCmdItem->cmd->cmdKey, strlen(cmdMajor)) > 0) { + continue; + } + + if (strncmp(cmdMajor, curCmdItem->cmd->cmdKey, strlen(cmdMajor)) != 0) { + break; + } + + if (count == 0) { + cmdItemGuard = curCmdItem; + } + ++count; + } + + if (cmdItemGuard == NULL) { + return 0; + } + + if (count == 1) { + OsCompleteStr(cmdItemGuard->cmd->cmdKey, cmdMajor, cmdKey, len); + } + + ret = count; + if (count > 1) { + PRINTK("\n"); + while (count--) { + PRINTK("%s ", cmdItemGuard->cmd->cmdKey); + cmdItemGuard = LOS_DL_LIST_ENTRY(cmdItemGuard->list.pstNext, CmdItemNode, list); + } + PRINTK("\n"); + } + + return ret; +} + +STATIC INT32 OsTabMatchFile(CHAR *cmdKey, UINT32 *len) +{ + UINT32 maxLen = 0; + INT32 count; + CHAR *strOutput = NULL; + CHAR *strCmp = NULL; + CHAR *dirOpen = (CHAR *)LOS_MemAlloc(m_aucSysMem0, CMD_MAX_PATH * 3); /* 3:dirOpen\strOutput\strCmp */ + if (dirOpen == NULL) { + return (INT32)OS_ERROR; + } + + (VOID)memset_s(dirOpen, CMD_MAX_PATH * 3, 0, CMD_MAX_PATH * 3); /* 3:dirOpen\strOutput\strCmp */ + strOutput = dirOpen + CMD_MAX_PATH; + strCmp = strOutput + CMD_MAX_PATH; + + if (OsStrSeparate(cmdKey, dirOpen, strCmp, *len)) { + (VOID)LOS_MemFree(m_aucSysMem0, dirOpen); + return (INT32)OS_ERROR; + } + + count = OsExecNameMatch(dirOpen, strCmp, strOutput, &maxLen); + /* one or more matched */ + if (count >= 1) { + OsCompleteStr(strOutput, strCmp, cmdKey, len); + + if (count == 1) { + (VOID)LOS_MemFree(m_aucSysMem0, dirOpen); + return 1; + } + if (OsPrintMatchList((UINT32)count, dirOpen, strCmp, maxLen) == -1) { + (VOID)LOS_MemFree(m_aucSysMem0, dirOpen); + return (INT32)OS_ERROR; + } + } + + (VOID)LOS_MemFree(m_aucSysMem0, dirOpen); + return count; +} + +/* + * Description: Pass in the string and clear useless space, which include: + * 1) The overmatch space which is not be marked by Quote's area + * Squeeze the overmatch space into one space + * 2) Clear all space before first valid character + * Input: cmdKey : Pass in the buff string, which is ready to be operated + * cmdOut : Pass out the buffer string ,which has already been operated + * size : cmdKey length + */ +LITE_OS_SEC_TEXT_MINOR UINT32 OsCmdKeyShift(const CHAR *cmdKey, CHAR *cmdOut, UINT32 size) +{ + CHAR *output = NULL; + CHAR *outputBak = NULL; + UINT32 len; + INT32 ret; + BOOL quotes = FALSE; + + if ((cmdKey == NULL) || (cmdOut == NULL)) { + return (UINT32)OS_ERROR; + } + + len = strlen(cmdKey); + if (len >= size) { + return (UINT32)OS_ERROR; + } + output = (CHAR*)LOS_MemAlloc(m_aucSysMem0, len + 1); + if (output == NULL) { + PRINTK("malloc failure in %s[%d]", __FUNCTION__, __LINE__); + return (UINT32)OS_ERROR; + } + /* Backup the 'output' start address */ + outputBak = output; + /* Scan each character in 'cmdKey',and squeeze the overmuch space and ignore invalid character */ + for (; *cmdKey != '\0'; cmdKey++) { + /* Detected a Double Quotes, switch the matching status */ + if (*(cmdKey) == '\"') { + SWITCH_QUOTES_STATUS(quotes); + } + /* Ignore the current character in following situation */ + /* 1) Quotes matching status is FALSE (which said that the space is not been marked by double quotes) */ + /* 2) Current character is a space */ + /* 3) Next character is a space too, or the string is been seeked to the end already(\0) */ + /* 4) Invalid character, such as single quotes */ + if ((*cmdKey == ' ') && ((*(cmdKey + 1) == ' ') || (*(cmdKey + 1) == '\0')) && QUOTES_STATUS_CLOSE(quotes)) { + continue; + } + if (*cmdKey == '\'') { + continue; + } + *output = *cmdKey; + output++; + } + *output = '\0'; + /* Restore the 'output' start address */ + output = outputBak; + len = strlen(output); + /* Clear the space which is located at the first character in buffer */ + if (*outputBak == ' ') { + output++; + len--; + } + /* Copy out the buffer which is been operated already */ + ret = strncpy_s(cmdOut, size, output, len); + if (ret != EOK) { + PRINT_ERR("%s,%d strncpy_s failed, err:%d!\n", __FUNCTION__, __LINE__, ret); + (VOID)LOS_MemFree(m_aucSysMem0, output); + return OS_ERROR; + } + cmdOut[len] = '\0'; + + (VOID)LOS_MemFree(m_aucSysMem0, output); + + return LOS_OK; +} + +LITE_OS_SEC_TEXT_MINOR BOOL OsCmdKeyCheck(const CHAR *cmdKey) +{ + const CHAR *temp = cmdKey; + enum Stat { + STAT_NONE, + STAT_DIGIT, + STAT_OTHER + } state = STAT_NONE; + + if (strlen(cmdKey) >= CMD_KEY_LEN) { + return FALSE; + } + + while (*temp != '\0') { + if (!((*temp <= '9') && (*temp >= '0')) && + !((*temp <= 'z') && (*temp >= 'a')) && + !((*temp <= 'Z') && (*temp >= 'A')) && + (*temp != '_') && (*temp != '-')) { + return FALSE; + } + + if ((*temp >= '0') && (*temp <= '9')) { + if (state == STAT_NONE) { + state = STAT_DIGIT; + } + } else { + state = STAT_OTHER; + } + + temp++; + } + + if (state == STAT_DIGIT) { + return FALSE; + } + + return TRUE; +} + +LITE_OS_SEC_TEXT_MINOR INT32 OsTabCompletion(CHAR *cmdKey, UINT32 *len) +{ + INT32 count = 0; + CHAR *space = NULL; + CHAR *cmdMainStr = cmdKey; + + if ((cmdKey == NULL) || (len == NULL)) { + return (INT32)OS_ERROR; + } + + /* cut left space */ + while (*cmdMainStr == 0x20) { + cmdMainStr++; + } + + /* try to find space in remain */ + space = strrchr(cmdMainStr, 0x20); + if ((space == NULL) && (*cmdMainStr != '\0')) { + count = OsTabMatchCmd(cmdKey, len); + } + + if (count == 0) { + count = OsTabMatchFile(cmdKey, len); + } + + return count; +} + +LITE_OS_SEC_TEXT_MINOR VOID OsCmdAscendingInsert(CmdItemNode *cmd) +{ + CmdItemNode *cmdItem = NULL; + CmdItemNode *cmdNext = NULL; + + if (cmd == NULL) { + return; + } + + for (cmdItem = LOS_DL_LIST_ENTRY((&g_cmdInfo.cmdList.list)->pstPrev, CmdItemNode, list); + &cmdItem->list != &(g_cmdInfo.cmdList.list);) { + cmdNext = LOS_DL_LIST_ENTRY(cmdItem->list.pstPrev, CmdItemNode, list); + if (&cmdNext->list != &(g_cmdInfo.cmdList.list)) { + if ((strncmp(cmdItem->cmd->cmdKey, cmd->cmd->cmdKey, strlen(cmd->cmd->cmdKey)) >= 0) && + (strncmp(cmdNext->cmd->cmdKey, cmd->cmd->cmdKey, strlen(cmd->cmd->cmdKey)) < 0)) { + LOS_ListTailInsert(&(cmdItem->list), &(cmd->list)); + return; + } + cmdItem = cmdNext; + } else { + if (strncmp(cmd->cmd->cmdKey, cmdItem->cmd->cmdKey, strlen(cmd->cmd->cmdKey)) > 0) { + cmdItem = cmdNext; + } + break; + } + } + + LOS_ListTailInsert(&(cmdItem->list), &(cmd->list)); +} + +LITE_OS_SEC_TEXT_MINOR UINT32 OsShellKeyInit(ShellCB *shellCB) +{ + CmdKeyLink *cmdKeyLink = NULL; + CmdKeyLink *cmdHistoryLink = NULL; + + if (shellCB == NULL) { + return OS_ERROR; + } + cmdKeyLink = (CmdKeyLink *)LOS_MemAlloc(m_aucSysMem0, sizeof(CmdKeyLink)); + if (cmdKeyLink == NULL) { + PRINT_ERR("Shell CmdKeyLink memory alloc error!\n"); + return OS_ERROR; + } + cmdHistoryLink = (CmdKeyLink *)LOS_MemAlloc(m_aucSysMem0, sizeof(CmdKeyLink)); + if (cmdHistoryLink == NULL) { + (VOID)LOS_MemFree(m_aucSysMem0, cmdKeyLink); + PRINT_ERR("Shell CmdHistoryLink memory alloc error!\n"); + return OS_ERROR; + } + + cmdKeyLink->count = 0; + LOS_ListInit(&(cmdKeyLink->list)); + shellCB->cmdKeyLink = (VOID *)cmdKeyLink; + + cmdHistoryLink->count = 0; + LOS_ListInit(&(cmdHistoryLink->list)); + shellCB->cmdHistoryKeyLink = (VOID *)cmdHistoryLink; + shellCB->cmdMaskKeyLink = (VOID *)cmdHistoryLink; + return LOS_OK; +} + +LITE_OS_SEC_TEXT_MINOR VOID OsShellKeyDeInit(CmdKeyLink *cmdKeyLink) +{ + CmdKeyLink *cmdtmp = NULL; + if (cmdKeyLink == NULL) { + return; + } + + while (!LOS_ListEmpty(&(cmdKeyLink->list))) { + cmdtmp = LOS_DL_LIST_ENTRY(cmdKeyLink->list.pstNext, CmdKeyLink, list); + LOS_ListDelete(&cmdtmp->list); + (VOID)LOS_MemFree(m_aucSysMem0, cmdtmp); + } + + cmdKeyLink->count = 0; + (VOID)LOS_MemFree(m_aucSysMem0, cmdKeyLink); +} + +LITE_OS_SEC_TEXT_MINOR UINT32 OsShellSysCmdRegister(VOID) +{ + UINT32 i; + UINT8 *cmdItemGroup = NULL; + UINT32 index = ((UINTPTR)(&g_shellcmdEnd) - (UINTPTR)(&g_shellcmd[0])) / sizeof(CmdItem); + CmdItemNode *cmdItem = NULL; + + cmdItemGroup = (UINT8 *)LOS_MemAlloc(m_aucSysMem0, index * sizeof(CmdItemNode)); + if (cmdItemGroup == NULL) { + PRINT_ERR("[%s]System memory allocation failure!\n", __FUNCTION__); + return (UINT32)OS_ERROR; + } + + for (i = 0; i < index; ++i) { + cmdItem = (CmdItemNode *)(cmdItemGroup + i * sizeof(CmdItemNode)); + cmdItem->cmd = &g_shellcmd[i]; + OsCmdAscendingInsert(cmdItem); + } + g_cmdInfo.listNum += index; + return LOS_OK; +} + +LITE_OS_SEC_TEXT_MINOR VOID OsShellCmdPush(const CHAR *string, CmdKeyLink *cmdKeyLink) +{ + CmdKeyLink *cmdNewNode = NULL; + UINT32 len; + + if ((string == NULL) || (strlen(string) == 0)) { + return; + } + + len = strlen(string); + cmdNewNode = (CmdKeyLink *)LOS_MemAlloc(m_aucSysMem0, sizeof(CmdKeyLink) + len + 1); + if (cmdNewNode == NULL) { + return; + } + + (VOID)memset_s(cmdNewNode, sizeof(CmdKeyLink) + len + 1, 0, sizeof(CmdKeyLink) + len + 1); + if (strncpy_s(cmdNewNode->cmdString, len + 1, string, len)) { + (VOID)LOS_MemFree(m_aucSysMem0, cmdNewNode); + return; + } + + LOS_ListTailInsert(&(cmdKeyLink->list), &(cmdNewNode->list)); + + return; +} + +LITE_OS_SEC_TEXT_MINOR VOID OsShellHistoryShow(UINT32 value, ShellCB *shellCB) +{ + CmdKeyLink *cmdtmp = NULL; + CmdKeyLink *cmdNode = shellCB->cmdHistoryKeyLink; + CmdKeyLink *cmdMask = shellCB->cmdMaskKeyLink; + errno_t ret; + + (VOID)pthread_mutex_lock(&shellCB->historyMutex); + if (value == CMD_KEY_DOWN) { + if (cmdMask == cmdNode) { + goto END; + } + + cmdtmp = LOS_DL_LIST_ENTRY(cmdMask->list.pstNext, CmdKeyLink, list); + if (cmdtmp != cmdNode) { + cmdMask = cmdtmp; + } else { + goto END; + } + } else if (value == CMD_KEY_UP) { + cmdtmp = LOS_DL_LIST_ENTRY(cmdMask->list.pstPrev, CmdKeyLink, list); + if (cmdtmp != cmdNode) { + cmdMask = cmdtmp; + } else { + goto END; + } + } + + while (shellCB->shellBufOffset--) { + PRINTK("\b \b"); + } + PRINTK("%s", cmdMask->cmdString); + shellCB->shellBufOffset = strlen(cmdMask->cmdString); + (VOID)memset_s(shellCB->shellBuf, SHOW_MAX_LEN, 0, SHOW_MAX_LEN); + ret = memcpy_s(shellCB->shellBuf, SHOW_MAX_LEN, cmdMask->cmdString, shellCB->shellBufOffset); + if (ret != EOK) { + PRINT_ERR("%s, %d memcpy failed!\n", __FUNCTION__, __LINE__); + goto END; + } + shellCB->cmdMaskKeyLink = (VOID *)cmdMask; + +END: + (VOID)pthread_mutex_unlock(&shellCB->historyMutex); + return; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 OsCmdExec(CmdParsed *cmdParsed, CHAR *cmdStr) +{ + UINT32 ret; + CmdCallBackFunc cmdHook = NULL; + CmdItemNode *curCmdItem = NULL; + UINT32 i; + const CHAR *cmdKey = NULL; + + if ((cmdParsed == NULL) || (cmdStr == NULL) || (strlen(cmdStr) == 0)) { + return (UINT32)OS_ERROR; + } + + ret = OsCmdParse(cmdStr, cmdParsed); + if (ret != LOS_OK) { + goto OUT; + } + + LOS_DL_LIST_FOR_EACH_ENTRY(curCmdItem, &(g_cmdInfo.cmdList.list), CmdItemNode, list) { + cmdKey = curCmdItem->cmd->cmdKey; + if ((cmdParsed->cmdType == curCmdItem->cmd->cmdType) && + (strlen(cmdKey) == strlen(cmdParsed->cmdKeyword)) && + (strncmp(cmdKey, (CHAR *)(cmdParsed->cmdKeyword), strlen(cmdKey)) == 0)) { + cmdHook = curCmdItem->cmd->cmdHook; + break; + } + } + + ret = OS_ERROR; + if (cmdHook != NULL) { + ret = (cmdHook)(cmdParsed->paramCnt, (const CHAR **)cmdParsed->paramArray); + } + +OUT: + for (i = 0; i < cmdParsed->paramCnt; i++) { + if (cmdParsed->paramArray[i] != NULL) { + (VOID)LOS_MemFree(m_aucSysMem0, cmdParsed->paramArray[i]); + cmdParsed->paramArray[i] = NULL; + } + } + + return (UINT32)ret; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 OsCmdInit(VOID) +{ + UINT32 ret; + LOS_ListInit(&(g_cmdInfo.cmdList.list)); + g_cmdInfo.listNum = 0; + g_cmdInfo.initMagicFlag = SHELL_INIT_MAGIC_FLAG; + ret = LOS_MuxInit(&g_cmdInfo.muxLock, NULL); + if (ret != LOS_OK) { + PRINT_ERR("Create mutex for shell cmd info failed\n"); + return OS_ERROR; + } + return LOS_OK; +} + +STATIC UINT32 OsCmdItemCreate(CmdType cmdType, const CHAR *cmdKey, UINT32 paraNum, CmdCallBackFunc cmdProc) +{ + CmdItem *cmdItem = NULL; + CmdItemNode *cmdItemNode = NULL; + + cmdItem = (CmdItem *)LOS_MemAlloc(m_aucSysMem0, sizeof(CmdItem)); + if (cmdItem == NULL) { + return OS_ERRNO_SHELL_CMDREG_MEMALLOC_ERROR; + } + (VOID)memset_s(cmdItem, sizeof(CmdItem), '\0', sizeof(CmdItem)); + + cmdItemNode = (CmdItemNode *)LOS_MemAlloc(m_aucSysMem0, sizeof(CmdItemNode)); + if (cmdItemNode == NULL) { + (VOID)LOS_MemFree(m_aucSysMem0, cmdItem); + return OS_ERRNO_SHELL_CMDREG_MEMALLOC_ERROR; + } + (VOID)memset_s(cmdItemNode, sizeof(CmdItemNode), '\0', sizeof(CmdItemNode)); + cmdItemNode->cmd = cmdItem; + cmdItemNode->cmd->cmdHook = cmdProc; + cmdItemNode->cmd->paraNum = paraNum; + cmdItemNode->cmd->cmdType = cmdType; + cmdItemNode->cmd->cmdKey = cmdKey; + + (VOID)LOS_MuxLock(&g_cmdInfo.muxLock, LOS_WAIT_FOREVER); + OsCmdAscendingInsert(cmdItemNode); + g_cmdInfo.listNum++; + (VOID)LOS_MuxUnlock(&g_cmdInfo.muxLock); + + return LOS_OK; +} + +/* open API */ +LITE_OS_SEC_TEXT_MINOR UINT32 osCmdReg(CmdType cmdType, const CHAR *cmdKey, UINT32 paraNum, CmdCallBackFunc cmdProc) +{ + CmdItemNode *cmdItemNode = NULL; + + (VOID)LOS_MuxLock(&g_cmdInfo.muxLock, LOS_WAIT_FOREVER); + if (g_cmdInfo.initMagicFlag != SHELL_INIT_MAGIC_FLAG) { + (VOID)LOS_MuxUnlock(&g_cmdInfo.muxLock); + PRINT_ERR("[%s] shell is not yet initialized!\n", __FUNCTION__); + return OS_ERRNO_SHELL_NOT_INIT; + } + (VOID)LOS_MuxUnlock(&g_cmdInfo.muxLock); + + if ((cmdProc == NULL) || (cmdKey == NULL) || + (cmdType >= CMD_TYPE_BUTT) || (strlen(cmdKey) >= CMD_KEY_LEN) || !strlen(cmdKey)) { + return OS_ERRNO_SHELL_CMDREG_PARA_ERROR; + } + + if (paraNum > CMD_MAX_PARAS) { + if (paraNum != XARGS) { + return OS_ERRNO_SHELL_CMDREG_PARA_ERROR; + } + } + + if (OsCmdKeyCheck(cmdKey) != TRUE) { + return OS_ERRNO_SHELL_CMDREG_CMD_ERROR; + } + + (VOID)LOS_MuxLock(&g_cmdInfo.muxLock, LOS_WAIT_FOREVER); + LOS_DL_LIST_FOR_EACH_ENTRY(cmdItemNode, &(g_cmdInfo.cmdList.list), CmdItemNode, list) { + if ((cmdType == cmdItemNode->cmd->cmdType) && + ((strlen(cmdKey) == strlen(cmdItemNode->cmd->cmdKey)) && + (strncmp((CHAR *)(cmdItemNode->cmd->cmdKey), cmdKey, strlen(cmdKey)) == 0))) { + (VOID)LOS_MuxUnlock(&g_cmdInfo.muxLock); + return OS_ERRNO_SHELL_CMDREG_CMD_EXIST; + } + } + (VOID)LOS_MuxUnlock(&g_cmdInfo.muxLock); + + return OsCmdItemCreate(cmdType, cmdKey, paraNum, cmdProc); +} + diff --git a/src/kernel_liteos_a/shell/full/src/base/shcmdparse.c b/src/kernel_liteos_a/shell/full/src/base/shcmdparse.c new file mode 100644 index 00000000..676f55d8 --- /dev/null +++ b/src/kernel_liteos_a/shell/full/src/base/shcmdparse.c @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "shcmd.h" +#include "los_memory.h" + + +/* + * Filter out double quote or single-quoted strings at both ends + */ +LITE_OS_SEC_TEXT_MINOR CHAR *OsCmdParseStrdup(const CHAR *str) +{ + CHAR *tempStr = NULL; + CHAR *newStr = NULL; + + newStr = (CHAR *)LOS_MemAlloc(m_aucSysMem0, strlen(str) + 1); + if (newStr == NULL) { + return NULL; + } + + tempStr = newStr; + for (; *str != '\0'; str++) { + if ((*str == '\"') || (*str == '\'')) { + continue; + } + *newStr = *str; + newStr++; + } + *newStr = '\0'; + return tempStr; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 OsCmdParseParaGet(CHAR **value, const CHAR *paraTokenStr) +{ + if ((paraTokenStr == NULL) || (value == NULL)) { + return (UINT32)OS_ERROR; + } + + *value = OsCmdParseStrdup(paraTokenStr); + if (*value == NULL) { + return LOS_NOK; + } + return LOS_OK; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 OsCmdParseOneToken(CmdParsed *cmdParsed, UINT32 index, const CHAR *token) +{ + UINT32 ret = LOS_OK; + UINT32 tempLen; + + if (cmdParsed == NULL) { + return (UINT32)OS_ERROR; + } + + if (index == 0) { + if (cmdParsed->cmdType != CMD_TYPE_STD) { + return ret; + } + } + + if ((token != NULL) && (cmdParsed->paramCnt < CMD_MAX_PARAS)) { + tempLen = cmdParsed->paramCnt; + ret = OsCmdParseParaGet(&(cmdParsed->paramArray[tempLen]), token); + if (ret != LOS_OK) { + return ret; + } + cmdParsed->paramCnt++; + } + return ret; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 OsCmdTokenSplit(CHAR *cmdStr, CHAR split, CmdParsed *cmdParsed) +{ + enum { + STAT_INIT, + STAT_TOKEN_IN, + STAT_TOKEN_OUT + } state = STAT_INIT; + UINT32 count = 0; + CHAR *p = NULL; + CHAR *token = cmdStr; + UINT32 ret = LOS_OK; + BOOL quotes = FALSE; + + if (cmdStr == NULL) { + return (UINT32)OS_ERROR; + } + + for (p = cmdStr; (*p != '\0') && (ret == LOS_OK); p++) { + if (*p == '\"') { + SWITCH_QUOTES_STATUS(quotes); + } + switch (state) { + case STAT_INIT: + case STAT_TOKEN_IN: + if ((*p == split) && QUOTES_STATUS_CLOSE(quotes)) { + *p = '\0'; + ret = OsCmdParseOneToken(cmdParsed, count++, token); + state = STAT_TOKEN_OUT; + } + break; + case STAT_TOKEN_OUT: + if (*p != split) { + token = p; + state = STAT_TOKEN_IN; + } + break; + default: + break; + } + } + + if (((ret == LOS_OK) && (state == STAT_TOKEN_IN)) || (state == STAT_INIT)) { + ret = OsCmdParseOneToken(cmdParsed, count, token); + } + + return ret; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 OsCmdParse(CHAR *cmdStr, CmdParsed *cmdParsed) +{ + if ((cmdStr == NULL) || (cmdParsed == NULL) || (strlen(cmdStr) == 0)) { + return (UINT32)OS_ERROR; + } + return OsCmdTokenSplit(cmdStr, ' ', cmdParsed); +} + diff --git a/src/kernel_liteos_a/shell/full/src/base/shell_lk.c b/src/kernel_liteos_a/shell/full/src/base/shell_lk.c new file mode 100644 index 00000000..88dad16a --- /dev/null +++ b/src/kernel_liteos_a/shell/full/src/base/shell_lk.c @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "shell_lk.h" +#include "securec.h" +#include "stdio.h" +#include "stdlib.h" +#include "unistd.h" +#include "shcmd.h" +#ifdef LOSCFG_SHELL_DMESG +#include "dmesg_pri.h" +#endif +#include "los_init.h" +#include "los_printf_pri.h" +#include "los_process_pri.h" + +#ifdef LOSCFG_SHELL_LK + +typedef enum { + MODULE0 = 0, + MODULE1 = 1, + MODULE2 = 2, + MODULE3 = 3, + MODULE4 = 4, +} MODULE_FLAG; + +typedef struct { + INT32 module_level; + INT32 trace_level; + FILE *fp; +} Logger; + +STATIC INT32 g_tracelevel; +STATIC INT32 g_modulelevel; + +STATIC Logger g_logger = { 0 }; + +VOID OsLkDefaultFunc(INT32 level, const CHAR *func, INT32 line, const CHAR *fmt, va_list ap); + +LK_FUNC g_osLkHook = (LK_FUNC)OsLkDefaultFunc; + +STATIC INLINE INT32 OsLkTraceLvGet(VOID) +{ + return g_tracelevel; +} + +const CHAR *OsLkCurLogLvGet(VOID) +{ + return OsLogLvGet(g_tracelevel); +} + +VOID OsLkTraceLvSet(INT32 level) +{ + g_tracelevel = level; + g_logger.trace_level = level; + return; +} + +VOID OsLkModuleLvSet(INT32 level) +{ + g_modulelevel = level; + g_logger.module_level = level; + return; +} + +INT32 OsLkModuleLvGet(VOID) +{ + return g_modulelevel; +} + +VOID OsLkLogFileSet(const CHAR *str) +{ + FILE *fp = NULL; + FILE *oldfp = g_logger.fp; + + if (str == NULL) { + return; + } + fp = fopen(str, "w+"); + if (fp == NULL) { + printf("Error can't open the %s file\n", str); + return; + } + + g_logger.fp = fp; + if (oldfp != NULL) { + fclose(oldfp); + } +} + +FILE *OsLogFpGet(VOID) +{ + return g_logger.fp; +} + +INT32 CmdLog(INT32 argc, const CHAR **argv) +{ + size_t level; + size_t module; + CHAR *p = NULL; + + if ((argc != 2) || (argv == NULL)) { /* 2:count of parameter */ + PRINTK("Usage: log level \n"); + PRINTK("Usage: log module \n"); + PRINTK("Usage: log path \n"); + return -1; + } + + if (!strncmp(argv[0], "level", strlen(argv[0]) + 1)) { + level = strtoul(argv[1], &p, 0); + if ((*p != 0) || (level > LOS_TRACE_LEVEL) || (level < LOS_EMG_LEVEL)) { + PRINTK("current log level %s\n", OsLkCurLogLvGet()); + PRINTK("log %s [num] can access as 0:EMG 1:COMMON 2:ERROR 3:WARN 4:INFO 5:DEBUG\n", argv[0]); + } else { + OsLkTraceLvSet(level); + PRINTK("Set current log level %s\n", OsLkCurLogLvGet()); + } + } else if (!strncmp(argv[0], "module", strlen(argv[0]) + 1)) { + module = strtoul(argv[1], &p, 0); + if ((*p != 0) || (module > MODULE4)) { + PRINTK("log %s can't access %s\n", argv[0], argv[1]); + PRINTK("not support yet\n"); + return -1; + } else { + OsLkModuleLvSet(module); + PRINTK("not support yet\n"); + } + } else if (!strncmp(argv[0], "path", strlen(argv[0]) + 1)) { + OsLkLogFileSet(argv[1]); + PRINTK("not support yet\n"); + } else { + PRINTK("Usage: log level \n"); + PRINTK("Usage: log module \n"); + PRINTK("Usage: log path \n"); + return -1; + } + + return 0; +} + +#ifdef LOSCFG_SHELL_DMESG +STATIC INLINE VOID OsLogCycleRecord(INT32 level) +{ + UINT32 tmpLen; + if (level != LOS_COMMON_LEVEL && (level > LOS_EMG_LEVEL && level <= LOS_TRACE_LEVEL)) { + tmpLen = strlen(OsLogLvGet(level)); + const CHAR* tmpPtr = OsLogLvGet(level); + (VOID)OsLogRecordStr(tmpPtr, tmpLen); + } +} +#endif + +VOID OsLkDefaultFunc(INT32 level, const CHAR *func, INT32 line, const CHAR *fmt, va_list ap) +{ + if (level > OsLkTraceLvGet()) { +#ifdef LOSCFG_SHELL_DMESG + if ((UINT32)level <= OsDmesgLvGet()) { + OsLogCycleRecord(level); + DmesgPrintf(fmt, ap); + } +#endif + return; + } + if ((level != LOS_COMMON_LEVEL) && ((level > LOS_EMG_LEVEL) && (level <= LOS_TRACE_LEVEL))) { + dprintf("[%s][%s:%s]", OsLogLvGet(level), + ((OsCurrProcessGet() == NULL) ? "NULL" : OsCurrProcessGet()->processName), + ((OsCurrTaskGet() == NULL) ? "NULL" : OsCurrTaskGet()->taskName)); + } + LkDprintf(fmt, ap); +} + +VOID LOS_LkPrint(INT32 level, const CHAR *func, INT32 line, const CHAR *fmt, ...) +{ + va_list ap; + if (g_osLkHook != NULL) { + va_start(ap, fmt); + g_osLkHook(level, func, line, fmt, ap); + va_end(ap); + } +} + +VOID LOS_LkRegHook(LK_FUNC hook) +{ + g_osLkHook = hook; +} + +UINT32 OsLkLoggerInit(VOID) +{ + (VOID)memset_s(&g_logger, sizeof(Logger), 0, sizeof(Logger)); + OsLkTraceLvSet(TRACE_DEFAULT); + LOS_LkRegHook(OsLkDefaultFunc); +#ifdef LOSCFG_SHELL_DMESG + (VOID)LOS_DmesgLvSet(TRACE_DEFAULT); +#endif + return LOS_OK; +} + +#ifdef LOSCFG_SHELL_CMD_DEBUG +SHELLCMD_ENTRY(log_shellcmd, CMD_TYPE_EX, "log", 1, (CmdCallBackFunc)CmdLog); +#endif + +LOS_MODULE_INIT(OsLkLoggerInit, LOS_INIT_LEVEL_EARLIEST); + +#endif diff --git a/src/kernel_liteos_a/shell/full/src/base/shmsg.c b/src/kernel_liteos_a/shell/full/src/base/shmsg.c new file mode 100644 index 00000000..52f80ff0 --- /dev/null +++ b/src/kernel_liteos_a/shell/full/src/base/shmsg.c @@ -0,0 +1,462 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "shmsg.h" +#include "shell_pri.h" +#include "shcmd.h" +#include "stdlib.h" +#include "stdio.h" +#include "unistd.h" +#include "securec.h" +#include "los_base.h" +#include "los_task.h" +#include "los_event.h" +#include "los_list.h" +#include "los_printf.h" + +#ifdef LOSCFG_FS_VFS +#include "console.h" +#endif + + +CHAR *ShellGetInputBuf(ShellCB *shellCB) +{ + CmdKeyLink *cmdkey = shellCB->cmdKeyLink; + CmdKeyLink *cmdNode = NULL; + + (VOID)pthread_mutex_lock(&shellCB->keyMutex); + if ((cmdkey == NULL) || LOS_ListEmpty(&cmdkey->list)) { + (VOID)pthread_mutex_unlock(&shellCB->keyMutex); + return NULL; + } + + cmdNode = LOS_DL_LIST_ENTRY(cmdkey->list.pstNext, CmdKeyLink, list); + LOS_ListDelete(&(cmdNode->list)); /* 'cmdNode' freed in history save process */ + (VOID)pthread_mutex_unlock(&shellCB->keyMutex); + + return cmdNode->cmdString; +} + +STATIC VOID ShellSaveHistoryCmd(const CHAR *string, ShellCB *shellCB) +{ + CmdKeyLink *cmdHistory = shellCB->cmdHistoryKeyLink; + CmdKeyLink *cmdkey = LOS_DL_LIST_ENTRY(string, CmdKeyLink, cmdString); + CmdKeyLink *cmdNxt = NULL; + + if ((string == NULL) || (strlen(string) == 0)) { + return; + } + + (VOID)pthread_mutex_lock(&shellCB->historyMutex); + if (cmdHistory->count != 0) { + cmdNxt = LOS_DL_LIST_ENTRY(cmdHistory->list.pstPrev, CmdKeyLink, list); + if (strcmp(string, cmdNxt->cmdString) == 0) { + (VOID)LOS_MemFree(m_aucSysMem0, (VOID *)cmdkey); + (VOID)pthread_mutex_unlock(&shellCB->historyMutex); + return; + } + } + + if (cmdHistory->count == CMD_HISTORY_LEN) { + cmdNxt = LOS_DL_LIST_ENTRY(cmdHistory->list.pstNext, CmdKeyLink, list); + LOS_ListDelete(&(cmdNxt->list)); + LOS_ListTailInsert(&(cmdHistory->list), &(cmdkey->list)); + (VOID)LOS_MemFree(m_aucSysMem0, (VOID *)cmdNxt); + (VOID)pthread_mutex_unlock(&shellCB->historyMutex); + return; + } + + LOS_ListTailInsert(&(cmdHistory->list), &(cmdkey->list)); + cmdHistory->count++; + + (VOID)pthread_mutex_unlock(&shellCB->historyMutex); + return; +} + +STATIC VOID ShellNotify(ShellCB *shellCB) +{ + (VOID)LOS_EventWrite(&shellCB->shellEvent, SHELL_CMD_PARSE_EVENT); +} + +enum { + STAT_NORMAL_KEY, + STAT_ESC_KEY, + STAT_MULTI_KEY +}; + +STATIC INT32 ShellCmdLineCheckUDRL(const CHAR ch, ShellCB *shellCB) +{ + INT32 ret = LOS_OK; + if (ch == 0x1b) { /* 0x1b: ESC */ + shellCB->shellKeyType = STAT_ESC_KEY; + return ret; + } else if (ch == 0x5b) { /* 0x5b: first Key combination */ + if (shellCB->shellKeyType == STAT_ESC_KEY) { + shellCB->shellKeyType = STAT_MULTI_KEY; + return ret; + } + } else if (ch == 0x41) { /* up */ + if (shellCB->shellKeyType == STAT_MULTI_KEY) { + OsShellHistoryShow(CMD_KEY_UP, shellCB); + shellCB->shellKeyType = STAT_NORMAL_KEY; + return ret; + } + } else if (ch == 0x42) { /* down */ + if (shellCB->shellKeyType == STAT_MULTI_KEY) { + shellCB->shellKeyType = STAT_NORMAL_KEY; + OsShellHistoryShow(CMD_KEY_DOWN, shellCB); + return ret; + } + } else if (ch == 0x43) { /* right */ + if (shellCB->shellKeyType == STAT_MULTI_KEY) { + shellCB->shellKeyType = STAT_NORMAL_KEY; + return ret; + } + } else if (ch == 0x44) { /* left */ + if (shellCB->shellKeyType == STAT_MULTI_KEY) { + shellCB->shellKeyType = STAT_NORMAL_KEY; + return ret; + } + } + return LOS_NOK; +} + +LITE_OS_SEC_TEXT_MINOR VOID ShellCmdLineParse(CHAR c, pf_OUTPUT outputFunc, ShellCB *shellCB) +{ + const CHAR ch = c; + INT32 ret; + + if ((shellCB->shellBufOffset == 0) && (ch != '\n') && (ch != '\0')) { + (VOID)memset_s(shellCB->shellBuf, SHOW_MAX_LEN, 0, SHOW_MAX_LEN); + } + + if ((ch == '\r') || (ch == '\n')) { + if (shellCB->shellBufOffset < (SHOW_MAX_LEN - 1)) { + shellCB->shellBuf[shellCB->shellBufOffset] = '\0'; + } + shellCB->shellBufOffset = 0; + (VOID)pthread_mutex_lock(&shellCB->keyMutex); + OsShellCmdPush(shellCB->shellBuf, shellCB->cmdKeyLink); + (VOID)pthread_mutex_unlock(&shellCB->keyMutex); + ShellNotify(shellCB); + return; + } else if ((ch == '\b') || (ch == 0x7F)) { /* backspace or delete(0x7F) */ + if ((shellCB->shellBufOffset > 0) && (shellCB->shellBufOffset < (SHOW_MAX_LEN - 1))) { + shellCB->shellBuf[shellCB->shellBufOffset - 1] = '\0'; + shellCB->shellBufOffset--; + outputFunc("\b \b"); + } + return; + } else if (ch == 0x09) { /* 0x09: tab */ + if ((shellCB->shellBufOffset > 0) && (shellCB->shellBufOffset < (SHOW_MAX_LEN - 1))) { + ret = OsTabCompletion(shellCB->shellBuf, &shellCB->shellBufOffset); + if (ret > 1) { + outputFunc("OHOS # %s", shellCB->shellBuf); + } + } + return; + } + /* parse the up/down/right/left key */ + ret = ShellCmdLineCheckUDRL(ch, shellCB); + if (ret == LOS_OK) { + return; + } + + if ((ch != '\n') && (ch != '\0')) { + if (shellCB->shellBufOffset < (SHOW_MAX_LEN - 1)) { + shellCB->shellBuf[shellCB->shellBufOffset] = ch; + } else { + shellCB->shellBuf[SHOW_MAX_LEN - 1] = '\0'; + } + shellCB->shellBufOffset++; + outputFunc("%c", ch); + } + + shellCB->shellKeyType = STAT_NORMAL_KEY; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 ShellMsgTypeGet(CmdParsed *cmdParsed, const CHAR *cmdType) +{ + CmdItemNode *curCmdItem = (CmdItemNode *)NULL; + UINT32 len; + UINT32 minLen; + CmdModInfo *cmdInfo = OsCmdInfoGet(); + + if ((cmdParsed == NULL) || (cmdType == NULL)) { + return OS_INVALID; + } + + len = strlen(cmdType); + LOS_DL_LIST_FOR_EACH_ENTRY(curCmdItem, &(cmdInfo->cmdList.list), CmdItemNode, list) { + if ((len == strlen(curCmdItem->cmd->cmdKey)) && + (strncmp((CHAR *)(curCmdItem->cmd->cmdKey), cmdType, len) == 0)) { + minLen = (len < CMD_KEY_LEN) ? len : CMD_KEY_LEN; + (VOID)memcpy_s((CHAR *)(cmdParsed->cmdKeyword), CMD_KEY_LEN, cmdType, minLen); + cmdParsed->cmdType = curCmdItem->cmd->cmdType; + return LOS_OK; + } + } + + return OS_INVALID; +} + +STATIC UINT32 ShellMsgNameGetAndExec(CmdParsed *cmdParsed, const CHAR *output, UINT32 len) +{ + UINT32 loop; + UINT32 ret; + const CHAR *tmpStr = NULL; + BOOL quotes = FALSE; + CHAR *msgName = (CHAR *)LOS_MemAlloc(m_aucSysMem0, len + 1); + if (msgName == NULL) { + PRINTK("malloc failure in %s[%d]\n", __FUNCTION__, __LINE__); + return OS_INVALID; + } + /* Scan the 'output' string for command */ + /* Notice: Command string must not have any special name */ + for (tmpStr = output, loop = 0; (*tmpStr != '\0') && (loop < len);) { + /* If reach a double quotes, switch the quotes matching status */ + if (*tmpStr == '\"') { + SWITCH_QUOTES_STATUS(quotes); + /* Ignore the double quote CHARactor itself */ + tmpStr++; + continue; + } + /* If detected a space which the quotes matching status is false */ + /* which said has detected the first space for separator, finish this scan operation */ + if ((*tmpStr == ' ') && (QUOTES_STATUS_CLOSE(quotes))) { + break; + } + msgName[loop] = *tmpStr++; + loop++; + } + msgName[loop] = '\0'; + /* Scan the command list to check whether the command can be found */ + ret = ShellMsgTypeGet(cmdParsed, msgName); + PRINTK("\n"); + if (ret != LOS_OK) { + PRINTK("%s:command not found", msgName); + } else { + (VOID)OsCmdExec(cmdParsed, (CHAR *)output); + } + (VOID)LOS_MemFree(m_aucSysMem0, msgName); + return ret; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 ShellMsgParse(const VOID *msg) +{ + CHAR *output = NULL; + UINT32 len, cmdLen, newLen; + CmdParsed cmdParsed; + UINT32 ret = OS_INVALID; + CHAR *buf = (CHAR *)msg; + CHAR *newMsg = NULL; + CHAR *cmd = "exec"; + + if (msg == NULL) { + goto END; + } + + len = strlen(msg); + /* 2: strlen("./") */ + if ((len > 2) && (buf[0] == '.') && (buf[1] == '/')) { + cmdLen = strlen(cmd); + newLen = len + 1 + cmdLen + 1; + newMsg = (CHAR *)LOS_MemAlloc(m_aucSysMem0, newLen); + if (newMsg == NULL) { + PRINTK("malloc failure in %s[%d]\n", __FUNCTION__, __LINE__); + goto END; + } + (VOID)memcpy_s(newMsg, newLen, cmd, cmdLen); + newMsg[cmdLen] = ' '; + (VOID)memcpy_s(newMsg + cmdLen + 1, newLen - cmdLen - 1, (CHAR *)msg + 1, len); + msg = newMsg; + len = newLen - 1; + } + output = (CHAR *)LOS_MemAlloc(m_aucSysMem0, len + 1); + if (output == NULL) { + PRINTK("malloc failure in %s[%d]\n", __FUNCTION__, __LINE__); + goto END; + } + /* Call function 'OsCmdKeyShift' to squeeze and clear useless or overmuch space if string buffer */ + ret = OsCmdKeyShift((CHAR *)msg, output, len + 1); + if ((ret != LOS_OK) || (strlen(output) == 0)) { + ret = OS_INVALID; + goto END_FREE_OUTPUT; + } + + (VOID)memset_s(&cmdParsed, sizeof(CmdParsed), 0, sizeof(CmdParsed)); + + ret = ShellMsgNameGetAndExec(&cmdParsed, output, len); + +END_FREE_OUTPUT: + (VOID)LOS_MemFree(m_aucSysMem0, output); +END: + if (newMsg != NULL) { + (VOID)LOS_MemFree(m_aucSysMem0, newMsg); + } + return ret; +} + +#ifdef LOSCFG_FS_VFS +LITE_OS_SEC_TEXT_MINOR UINT32 ShellEntry(UINTPTR param) +{ + CHAR ch; + INT32 n; + ShellCB *shellCB = (ShellCB *)param; + + CONSOLE_CB *consoleCB = OsGetConsoleByID((INT32)shellCB->consoleID); + if (consoleCB == NULL) { + PRINT_ERR("Shell task init error!\n"); + return 1; + } + + (VOID)memset_s(shellCB->shellBuf, SHOW_MAX_LEN, 0, SHOW_MAX_LEN); + + while (1) { +#ifdef LOSCFG_PLATFORM_CONSOLE + if (!IsConsoleOccupied(consoleCB)) { +#endif + /* is console ready for shell ? */ + n = read(consoleCB->fd, &ch, 1); + if (n == 1) { + ShellCmdLineParse(ch, (pf_OUTPUT)dprintf, shellCB); + } + if (is_nonblock(consoleCB)) { + LOS_Msleep(50); /* 50: 50MS for sleep */ + } +#ifdef LOSCFG_PLATFORM_CONSOLE + } +#endif + } +} +#endif + +STATIC VOID ShellCmdProcess(ShellCB *shellCB) +{ + CHAR *buf = NULL; + while (1) { + buf = ShellGetInputBuf(shellCB); + if (buf == NULL) { + break; + } + (VOID)ShellMsgParse(buf); + ShellSaveHistoryCmd(buf, shellCB); + shellCB->cmdMaskKeyLink = shellCB->cmdHistoryKeyLink; + } +} + +LITE_OS_SEC_TEXT_MINOR UINT32 ShellTask(UINTPTR param1, + UINTPTR param2, + UINTPTR param3, + UINTPTR param4) +{ + UINT32 ret; + ShellCB *shellCB = (ShellCB *)param1; + (VOID)param2; + (VOID)param3; + (VOID)param4; + + while (1) { + PRINTK("\nOHOS # "); + ret = LOS_EventRead(&shellCB->shellEvent, + 0xFFF, LOS_WAITMODE_OR | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER); + if (ret == SHELL_CMD_PARSE_EVENT) { + ShellCmdProcess(shellCB); + } else if (ret == CONSOLE_SHELL_KEY_EVENT) { + break; + } + } + OsShellKeyDeInit((CmdKeyLink *)shellCB->cmdKeyLink); + OsShellKeyDeInit((CmdKeyLink *)shellCB->cmdHistoryKeyLink); + (VOID)LOS_EventDestroy(&shellCB->shellEvent); + (VOID)LOS_MemFree((VOID *)m_aucSysMem0, shellCB); + return 0; +} + +#define SERIAL_SHELL_TASK_NAME "SerialShellTask" +#define SERIAL_ENTRY_TASK_NAME "SerialEntryTask" +#define TELNET_SHELL_TASK_NAME "TelnetShellTask" +#define TELNET_ENTRY_TASK_NAME "TelnetEntryTask" + +LITE_OS_SEC_TEXT_MINOR UINT32 ShellTaskInit(ShellCB *shellCB) +{ + CHAR *name = NULL; + TSK_INIT_PARAM_S initParam = {0}; + + if (shellCB->consoleID == CONSOLE_SERIAL) { + name = SERIAL_SHELL_TASK_NAME; + } else if (shellCB->consoleID == CONSOLE_TELNET) { + name = TELNET_SHELL_TASK_NAME; + } else { + return LOS_NOK; + } + + initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)ShellTask; + initParam.usTaskPrio = 9; /* 9:shell task priority */ + initParam.auwArgs[0] = (UINTPTR)shellCB; + initParam.uwStackSize = 0x3000; + initParam.pcName = name; + initParam.uwResved = LOS_TASK_STATUS_DETACHED; + + (VOID)LOS_EventInit(&shellCB->shellEvent); + + return LOS_TaskCreate(&shellCB->shellTaskHandle, &initParam); +} + +LITE_OS_SEC_TEXT_MINOR UINT32 ShellEntryInit(ShellCB *shellCB) +{ + UINT32 ret; + CHAR *name = NULL; + TSK_INIT_PARAM_S initParam = {0}; + + if (shellCB->consoleID == CONSOLE_SERIAL) { + name = SERIAL_ENTRY_TASK_NAME; + } else if (shellCB->consoleID == CONSOLE_TELNET) { + name = TELNET_ENTRY_TASK_NAME; + } else { + return LOS_NOK; + } + + initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)ShellEntry; + initParam.usTaskPrio = 9; /* 9:shell task priority */ + initParam.auwArgs[0] = (UINTPTR)shellCB; + initParam.uwStackSize = 0x1000; + initParam.pcName = name; + initParam.uwResved = LOS_TASK_STATUS_DETACHED; + + ret = LOS_TaskCreate(&shellCB->shellEntryHandle, &initParam); +#ifdef LOSCFG_PLATFORM_CONSOLE + (VOID)ConsoleTaskReg((INT32)shellCB->consoleID, shellCB->shellEntryHandle); +#endif + + return ret; +} + diff --git a/src/kernel_liteos_a/shell/full/src/base/show.c b/src/kernel_liteos_a/shell/full/src/base/show.c new file mode 100644 index 00000000..28f438c1 --- /dev/null +++ b/src/kernel_liteos_a/shell/full/src/base/show.c @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "show.h" +#include "shmsg.h" +#include "shcmd.h" +#include "console.h" + + +STATIC BOOL g_shellSourceFlag = FALSE; + +STATIC UINT32 OsShellCmdInit(VOID) +{ + UINT32 ret = OsCmdInit(); + if (ret != LOS_OK) { + return ret; + } + + return OsShellSysCmdRegister(); +} + +STATIC UINT32 OsShellCreateTask(ShellCB *shellCB) +{ + UINT32 ret = ShellTaskInit(shellCB); + if (ret != LOS_OK) { + return ret; + } + + return ShellEntryInit(shellCB); +} + +STATIC UINT32 OsShellSourceInit(INT32 consoleId) +{ + UINT32 ret = LOS_NOK; + CONSOLE_CB *consoleCB = OsGetConsoleByID(consoleId); + if ((consoleCB == NULL) || (consoleCB->shellHandle != NULL)) { + return LOS_NOK; + } + consoleCB->shellHandle = LOS_MemAlloc((VOID *)m_aucSysMem0, sizeof(ShellCB)); + if (consoleCB->shellHandle == NULL) { + return LOS_NOK; + } + ShellCB *shellCB = (ShellCB *)consoleCB->shellHandle; + if (memset_s(shellCB, sizeof(ShellCB), 0, sizeof(ShellCB)) != EOK) { + goto ERR_OUT1; + } + + shellCB->consoleID = (UINT32)consoleId; + ret = (UINT32)pthread_mutex_init(&shellCB->keyMutex, NULL); + if (ret != LOS_OK) { + goto ERR_OUT1; + } + ret = (UINT32)pthread_mutex_init(&shellCB->historyMutex, NULL); + if (ret != LOS_OK) { + goto ERR_OUT2; + } + + ret = OsShellKeyInit(shellCB); + if (ret != LOS_OK) { + goto ERR_OUT3; + } + if (strncpy_s(shellCB->shellWorkingDirectory, PATH_MAX, "/", 2) != EOK) { /* 2:space for "/" */ + ret = LOS_NOK; + goto ERR_OUT4; + } +#if !defined(LOSCFG_PLATFORM_ROOTFS) + /* + * In case of ROOTFS disabled but + * serial console enabled, it is required + * to create Shell task in kernel for it. + */ + if (consoleId == CONSOLE_TELNET || consoleId == CONSOLE_SERIAL) { +#else + if (consoleId == CONSOLE_TELNET) { +#endif + ret = OsShellCreateTask(shellCB); + if (ret != LOS_OK) { + goto ERR_OUT4; + } + } + + return LOS_OK; +ERR_OUT4: + (VOID)LOS_MemFree((VOID *)m_aucSysMem0, shellCB->cmdKeyLink); + (VOID)LOS_MemFree((VOID *)m_aucSysMem0, shellCB->cmdHistoryKeyLink); +ERR_OUT3: + (VOID)pthread_mutex_destroy(&shellCB->historyMutex); +ERR_OUT2: + (VOID)pthread_mutex_destroy(&shellCB->keyMutex); +ERR_OUT1: + (VOID)LOS_MemFree((VOID *)m_aucSysMem0, shellCB); + consoleCB->shellHandle = NULL; + return ret; +} + +UINT32 OsShellInit(INT32 consoleId) +{ + if (g_shellSourceFlag == FALSE) { + UINT32 ret = OsShellCmdInit(); + if (ret == LOS_OK) { + g_shellSourceFlag = TRUE; + } else { + return ret; + } + } + return OsShellSourceInit(consoleId); +} + +INT32 OsShellDeinit(INT32 consoleId) +{ + CONSOLE_CB *consoleCB = NULL; + ShellCB *shellCB = NULL; + + consoleCB = OsGetConsoleByID(consoleId); + if (consoleCB == NULL) { + PRINT_ERR("shell deinit error.\n"); + return -1; + } + + shellCB = (ShellCB *)consoleCB->shellHandle; + consoleCB->shellHandle = NULL; + if (shellCB == NULL) { + PRINT_ERR("shell deinit error.\n"); + return -1; + } + + (VOID)LOS_TaskDelete(shellCB->shellEntryHandle); + (VOID)LOS_EventWrite(&shellCB->shellEvent, CONSOLE_SHELL_KEY_EVENT); + + return 0; +} + +CHAR *OsShellGetWorkingDirectory(VOID) +{ + CONSOLE_CB *consoleCB = OsGetConsoleByTaskID(OsCurrTaskGet()->taskID); + ShellCB *shellCB = NULL; + + if (consoleCB == NULL) { + return NULL; + } + shellCB = (ShellCB *)consoleCB->shellHandle; + if (shellCB == NULL) { + return NULL; + } + return shellCB->shellWorkingDirectory; +} + diff --git a/src/kernel_liteos_a/shell/full/src/cmds/date_shellcmd.c b/src/kernel_liteos_a/shell/full/src/cmds/date_shellcmd.c new file mode 100644 index 00000000..3436edc3 --- /dev/null +++ b/src/kernel_liteos_a/shell/full/src/cmds/date_shellcmd.c @@ -0,0 +1,301 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "shcmd.h" +#include "shell.h" +#include "stdlib.h" +#include "time.h" +#include "los_typedef.h" +#include "sys/stat.h" +#include "securec.h" + +#if defined(__LP64__) +#define timeval64 timeval +#define settimeofday64 settimeofday +#define gettimeofday64 gettimeofday +#endif + +#define localtime64 localtime +#define ctime64 ctime +#define mktime64 mktime + +#define DATE_ERR_INFO 1 +#define DATE_HELP_INFO 0 +#define DATE_ERR (-1) +#define DATE_OK 0 +#define DATE_BASE_YEAR 1900 +#define LEAPYEAR(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) + +STATIC const INT32 g_monLengths[2][12] = { /* 2: 2 Column,Contains leap year; 12: 12 months */ + {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, + {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} +}; + +STATIC VOID OsCopyTm(struct tm *destTm, const struct tm *srcTm) +{ + if (srcTm == NULL) { + (VOID)memset_s(destTm, sizeof(struct tm), 0, sizeof(struct tm)); + } else { + destTm->tm_sec = srcTm->tm_sec; + destTm->tm_min = srcTm->tm_min; + destTm->tm_hour = srcTm->tm_hour; + destTm->tm_mday = srcTm->tm_mday; + destTm->tm_mon = srcTm->tm_mon; + destTm->tm_year = srcTm->tm_year; + destTm->tm_wday = srcTm->tm_wday; + destTm->tm_yday = srcTm->tm_yday; + destTm->tm_isdst = srcTm->tm_isdst; + destTm->tm_gmtoff = srcTm->tm_gmtoff; + destTm->tm_zone = srcTm->tm_zone; + } +} + +STATIC VOID OsCmdUsageDate(INT32 order) +{ + if (order) { + PRINTK("date: invalid option or parameter.\n"); + PRINTK("Try 'date --help' for more information.\n"); + return; + } + PRINTK("\nUsage: date [+FORMAT]\n"); + PRINTK(" or: date [-s] [YY/MM/DD] [hh:mm:ss]\n"); + PRINTK("Display the current time in the given FORMAT, or set the system date.\n"); + PRINTK("FORMAT controls the output. Interpreted sequences are:\n"); + PRINTK(" %%b The abbreviated month name according to the current locale.\n"); + PRINTK(" %%B The full month name according to the current locale.\n"); + PRINTK(" %%C The century number (year/100) as a 2-digit integer. (SU)\n"); + PRINTK(" %%d The day of the month as a decimal number (range 01 to 31).\n"); + PRINTK(" %%e Like %%d, the day of the month as a decimal number, \n"); + PRINTK(" but a leading zero is replaced by a space.\n"); + PRINTK(" %%h Equivalent to %%b. (SU)\n"); + PRINTK(" %%H The hour as a decimal number using a 24-hour clock (range 00 to 23).\n"); + PRINTK(" %%I The hour as a decimal number using a 12-hour clock (range 01 to 12).\n"); + PRINTK(" %%j The day of the year as a decimal number (range 001 to 366).\n"); + PRINTK(" %%k The hour (24-hour clock) as a decimal number (range 0 to 23); \n"); + PRINTK(" single digits are preceded by a blank. (See also %H.) (TZ)\n"); + PRINTK(" %%l The hour (12-hour clock) as a decimal number (range 1 to 12); \n"); + PRINTK(" single digits are preceded by a blank. (See also %I.) (TZ)\n"); + PRINTK(" %%m The month as a decimal number (range 01 to 12).\n"); + PRINTK(" %%M The minute as a decimal number (range 00 to 59).\n"); + PRINTK(" %%n A newline character. (SU)\n"); + PRINTK(" %%p Either \"AM\" or \"PM\" according to the given time value, \n"); + PRINTK(" or the corresponding strings for the current locale.\n"); + PRINTK(" Noon is treated as \"PM\" and midnight as \"AM\".\n"); + PRINTK(" %%P Like %%p but in lowercase: \"am\" or \"pm\" \n"); + PRINTK(" or a corresponding string for the current locale. (GNU)\n"); + PRINTK(" %%s The number of seconds since the Epoch, that is,\n"); + PRINTK(" since 1970-01-01 00:00:00 UTC. (TZ)\n"); + PRINTK(" %%S The second as a decimal number (range 00 to 60).\n"); + PRINTK(" (The range is up to 60 to allow for occasional leap seconds.)\n"); + PRINTK(" %%t A tab character. (SU)\n"); + PRINTK(" %%y The year as a decimal number without a century (range 00 to 99).\n"); + PRINTK(" %%Y The year as a decimal number including the century.\n"); + PRINTK(" %%%% A literal '%%' character.\n"); + PRINTK("\nExamples:\n"); + PRINTK("Set system date (2017-01-01)\n"); + PRINTK("$ date -s 20170101\n"); + PRINTK("Set system time (12:00:00)\n"); + PRINTK("$ date -s 12:00:00\n"); + PRINTK("Show the time with format Year-Month-Day\n"); + PRINTK("$ date +%%Y-%%m-%%d\n"); +} + +STATIC INT32 OsStrToTm(const CHAR *str, struct tm *tm) +{ + CHAR *ret = NULL; + UINT32 strLen = strlen(str); + if (strLen == 8) { /* 8:Time format string length, such as hh:mm:ss or yyyymmdd */ + if (str[2] == ':') { /* 2:Index of Eigenvalues */ + ret = strptime(str, "%H:%M:%S", tm); + } else { + ret = strptime(str, "%Y%m%d", tm); + } + } else if (strLen == 10) { /* 10:Time format string length,such as yyyy/mm/dd */ + ret = strptime(str, "%Y/%m/%d", tm); + } else if (strLen == 5) { /* 5:Time format string length,such as hh:mm or mm/dd */ + if (str[2] == ':') { /* 2:Index of Eigenvalues */ + ret = strptime(str, "%H:%M", tm); + } else if (str[2] == '/') { /* 2:Index of Eigenvalues */ + ret = strptime(str, "%m/%d", tm); + } + } else if (strLen == 7) { /* 7:Time format string length,such as yyyy/mm */ + if (str[4] == '/') { /* 4:Index of Eigenvalues */ + ret = strptime(str, "%Y/%m", tm); + } + } + + if (tm->tm_year < 70) { /* 70:the year is starting in 1970,tm_year must be greater than 70 */ + PRINTK("\nUsage: date -s set system time starting from 1970.\n"); + return DATE_ERR; + } + + if (tm->tm_mday > g_monLengths[(INT32)LEAPYEAR(tm->tm_year + DATE_BASE_YEAR)][tm->tm_mon]) { + return DATE_ERR; + } + + if ((tm->tm_sec < 0) || (tm->tm_sec > 59)) { /* Seconds (0-59), leap seconds shall not be used when set time. */ + return DATE_ERR; + } + return (ret == NULL) ? DATE_ERR : DATE_OK; +} + +STATIC INT32 OsFormatPrintTime(const CHAR *formatStr) +{ + CHAR timebuf[SHOW_MAX_LEN] = {0}; + struct tm *tm = NULL; + struct timeval64 nowTime = {0}; + + if (strlen(formatStr) < 2) { /* 2:check format string length */ + OsCmdUsageDate(DATE_ERR_INFO); + return DATE_ERR; + } + + if (gettimeofday64(&nowTime, NULL)) { + return DATE_ERR; + } + tm = localtime64(&nowTime.tv_sec); + if (tm == NULL) { + return DATE_ERR; + } + + if (strftime(timebuf, SHOW_MAX_LEN - 1, formatStr + 1, tm)) { + PRINTK("%s\n", timebuf); + } else { + OsCmdUsageDate(DATE_ERR_INFO); + return DATE_ERR; + } + return DATE_OK; +} + +STATIC INT32 OsDateSetTime(const CHAR *timeStr) +{ + struct tm tm = {0}; + struct timeval64 nowTime = {0}; + struct timeval64 setTime = {0}; + + if (gettimeofday64(&nowTime, NULL)) { + PRINTK("Setting time failed...\n"); + return DATE_ERR; + } + + setTime.tv_usec = nowTime.tv_usec; + OsCopyTm(&tm, localtime64(&nowTime.tv_sec)); + + if (OsStrToTm(timeStr, &tm)) { + OsCmdUsageDate(DATE_ERR_INFO); + return DATE_ERR; + } + + setTime.tv_sec = mktime64(&tm); + + if (settimeofday64(&setTime, NULL)) { + PRINTK("setting time failed...\n"); + return DATE_ERR; + } + + return DATE_OK; +} + +#ifdef LOSCFG_FS_VFS +STATIC INT32 OsViewFileTime(const CHAR *filename) +{ +#define BUFFER_SIZE 26 /* The buffer size is equal to the size used by the asctime_r interface */ + struct stat statBuf = {0}; + CHAR *fullpath = NULL; + INT32 ret; + CHAR buf[BUFFER_SIZE]; + CHAR *shellWorkingDirectory = OsShellGetWorkingDirectory(); + + ret = vfs_normalize_path(shellWorkingDirectory, filename, &fullpath); + if (ret < 0) { + set_errno(-ret); + perror("date error"); + return DATE_ERR; + } + + if (stat(fullpath, &statBuf) != 0) { + OsCmdUsageDate(DATE_ERR_INFO); + free(fullpath); + return DATE_ERR; + } + PRINTK("%s\n", ctime_r(&(statBuf.st_mtim.tv_sec), buf)); + free(fullpath); + return DATE_OK; +} +#endif + +INT32 OsShellCmdDate(INT32 argc, const CHAR **argv) +{ + struct timeval64 nowTime = {0}; + + if (argc == 1) { /* 1:count of parameters */ + if (gettimeofday64(&nowTime, NULL)) { + return DATE_ERR; + } + PRINTK("%s\n", ctime64(&nowTime.tv_sec)); + return DATE_OK; + } + + if (argc == 2) { /* 2:count of parameters */ + if (argv == NULL) { + OsCmdUsageDate(DATE_HELP_INFO); + return DATE_ERR; + } + + if (!(strcmp(argv[1], "--help"))) { + OsCmdUsageDate(DATE_HELP_INFO); + return DATE_OK; + } + if (!(strncmp(argv[1], "+", 1))) { + return OsFormatPrintTime(argv[1]); + } + } + + if (argc > 2) { /* 2:count of parameters */ + if (argv == NULL) { + OsCmdUsageDate(DATE_HELP_INFO); + return DATE_ERR; + } + + if (!(strcmp(argv[1], "-s"))) { + return OsDateSetTime(argv[2]); /* 2:index of parameters */ + } else if (!(strcmp(argv[1], "-r"))) { +#ifdef LOSCFG_FS_VFS + return OsViewFileTime(argv[2]); /* 2:index of parameters */ +#endif + } + } + + OsCmdUsageDate(DATE_ERR_INFO); + return DATE_OK; +} + +SHELLCMD_ENTRY(date_shellcmd, CMD_TYPE_STD, "date", XARGS, (CmdCallBackFunc)OsShellCmdDate); diff --git a/src/kernel_liteos_a/shell/full/src/cmds/dmesg.c b/src/kernel_liteos_a/shell/full/src/cmds/dmesg.c new file mode 100644 index 00000000..114669e0 --- /dev/null +++ b/src/kernel_liteos_a/shell/full/src/cmds/dmesg.c @@ -0,0 +1,792 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + +-------------------------------------------------------+ + | Info | log_space | + +-------------------------------------------------------+ + | + |__buffer_space + +Case A: + +-------------------------------------------------------+ + | |#############################| | + +-------------------------------------------------------+ + | | + Head Tail +Case B: + +-------------------------------------------------------+ + |##########| |#######| + +-------------------------------------------------------+ + | | + Tail Head +*/ + +#ifdef LOSCFG_SHELL_DMESG +#include "dmesg_pri.h" +#include "show.h" +#include "shcmd.h" +#include "securec.h" +#include "stdlib.h" +#include "unistd.h" +#include "los_init.h" +#include "los_task.h" + + +#define BUF_MAX_INDEX (g_logBufSize - 1) + +LITE_OS_SEC_BSS STATIC SPIN_LOCK_INIT(g_dmesgSpin); + +STATIC DmesgInfo *g_dmesgInfo = NULL; +STATIC UINT32 g_logBufSize = 0; +STATIC VOID *g_mallocAddr = NULL; +STATIC UINT32 g_dmesgLogLevel = 3; +STATIC UINT32 g_consoleLock = 0; +STATIC UINT32 g_uartLock = 0; +STATIC const CHAR *g_levelString[] = { + "EMG", + "COMMON", + "ERR", + "WARN", + "INFO", + "DEBUG" +}; + +STATIC VOID OsLockConsole(VOID) +{ + g_consoleLock = 1; +} + +STATIC VOID OsUnlockConsole(VOID) +{ + g_consoleLock = 0; +} + +STATIC VOID OsLockUart(VOID) +{ + g_uartLock = 1; +} + +STATIC VOID OsUnlockUart(VOID) +{ + g_uartLock = 0; +} + +STATIC UINT32 OsCheckError(VOID) +{ + if (g_dmesgInfo == NULL) { + return LOS_NOK; + } + + if (g_dmesgInfo->logSize > g_logBufSize) { + return LOS_NOK; + } + + if (((g_dmesgInfo->logSize == g_logBufSize) || (g_dmesgInfo->logSize == 0)) && + (g_dmesgInfo->logTail != g_dmesgInfo->logHead)) { + return LOS_NOK; + } + + return LOS_OK; +} + +STATIC INT32 OsDmesgRead(CHAR *buf, UINT32 len) +{ + UINT32 readLen; + UINT32 logSize = g_dmesgInfo->logSize; + UINT32 head = g_dmesgInfo->logHead; + UINT32 tail = g_dmesgInfo->logTail; + CHAR *logBuf = g_dmesgInfo->logBuf; + errno_t ret; + + if (OsCheckError()) { + return -1; + } + if (logSize == 0) { + return 0; + } + + readLen = len < logSize ? len : logSize; + + if (head < tail) { /* Case A */ + ret = memcpy_s(buf, len, logBuf + head, readLen); + if (ret != EOK) { + return -1; + } + g_dmesgInfo->logHead += readLen; + g_dmesgInfo->logSize -= readLen; + } else { /* Case B */ + if (readLen <= (g_logBufSize - head)) { + ret = memcpy_s(buf, len, logBuf + head, readLen); + if (ret != EOK) { + return -1; + } + g_dmesgInfo->logHead += readLen; + g_dmesgInfo->logSize -= readLen; + } else { + ret = memcpy_s(buf, len, logBuf + head, g_logBufSize - head); + if (ret != EOK) { + return -1; + } + + ret = memcpy_s(buf + g_logBufSize - head, len - (g_logBufSize - head), + logBuf, readLen - (g_logBufSize - head)); + if (ret != EOK) { + return -1; + } + g_dmesgInfo->logHead = readLen - (g_logBufSize - head); + g_dmesgInfo->logSize -= readLen; + } + } + return (INT32)readLen; +} + +STATIC INT32 OsCopyToNew(const VOID *addr, UINT32 size) +{ + UINT32 copyStart = 0; + UINT32 copyLen; + CHAR *temp = NULL; + CHAR *newBuf = (CHAR *)addr + sizeof(DmesgInfo); + UINT32 bufSize = size - sizeof(DmesgInfo); + INT32 ret; + UINT32 intSave; + + LOS_SpinLockSave(&g_dmesgSpin, &intSave); + if (g_dmesgInfo->logSize == 0) { + LOS_SpinUnlockRestore(&g_dmesgSpin, intSave); + return 0; + } + + temp = (CHAR *)malloc(g_dmesgInfo->logSize); + if (temp == NULL) { + LOS_SpinUnlockRestore(&g_dmesgSpin, intSave); + return -1; + } + + (VOID)memset_s(temp, g_dmesgInfo->logSize, 0, g_dmesgInfo->logSize); + copyLen = ((bufSize < g_dmesgInfo->logSize) ? bufSize : g_dmesgInfo->logSize); + if (bufSize < g_dmesgInfo->logSize) { + copyStart = g_dmesgInfo->logSize - bufSize; + } + + ret = OsDmesgRead(temp, g_dmesgInfo->logSize); + if (ret <= 0) { + goto FREE_OUT; + } + + /* if new buf size smaller than logSize */ + ret = memcpy_s(newBuf, bufSize, temp + copyStart, copyLen); + if (ret != EOK) { + goto FREE_OUT; + } + LOS_SpinUnlockRestore(&g_dmesgSpin, intSave); + free(temp); + + return (INT32)copyLen; + +FREE_OUT: + LOS_SpinUnlockRestore(&g_dmesgSpin, intSave); + PRINT_ERR("%s,%d failed, err:%d!\n", __FUNCTION__, __LINE__, ret); + free(temp); + return -1; +} + +STATIC UINT32 OsDmesgResetMem(const VOID *addr, UINT32 size) +{ + VOID *temp = NULL; + INT32 copyLen; + UINT32 intSave; + + if (size <= sizeof(DmesgInfo)) { + return LOS_NOK; + } + + LOS_SpinLockSave(&g_dmesgSpin, &intSave); + temp = g_dmesgInfo; + LOS_SpinUnlockRestore(&g_dmesgSpin, intSave); + copyLen = OsCopyToNew(addr, size); + if (copyLen < 0) { + return LOS_NOK; + } + + LOS_SpinLockSave(&g_dmesgSpin, &intSave); + g_logBufSize = size - sizeof(DmesgInfo); + g_dmesgInfo = (DmesgInfo *)addr; + g_dmesgInfo->logBuf = (CHAR *)addr + sizeof(DmesgInfo); + g_dmesgInfo->logSize = copyLen; + g_dmesgInfo->logTail = ((copyLen == g_logBufSize) ? 0 : copyLen); + g_dmesgInfo->logHead = 0; + + /* if old mem came from malloc */ + if (temp == g_mallocAddr) { + goto FREE_OUT; + } + LOS_SpinUnlockRestore(&g_dmesgSpin, intSave); + + return LOS_OK; + +FREE_OUT: + g_mallocAddr = NULL; + LOS_SpinUnlockRestore(&g_dmesgSpin, intSave); + free(temp); + return LOS_OK; +} + +STATIC UINT32 OsDmesgChangeSize(UINT32 size) +{ + VOID *temp = NULL; + INT32 copyLen; + CHAR *newString = NULL; + UINT32 intSave; + + if (size == 0) { + return LOS_NOK; + } + + newString = (CHAR *)malloc(size + sizeof(DmesgInfo)); + if (newString == NULL) { + return LOS_NOK; + } + + LOS_SpinLockSave(&g_dmesgSpin, &intSave); + temp = g_dmesgInfo; + LOS_SpinUnlockRestore(&g_dmesgSpin, intSave); + + copyLen = OsCopyToNew(newString, size + sizeof(DmesgInfo)); + if (copyLen < 0) { + goto ERR_OUT; + } + + LOS_SpinLockSave(&g_dmesgSpin, &intSave); + g_logBufSize = size; + g_dmesgInfo = (DmesgInfo *)newString; + g_dmesgInfo->logBuf = (CHAR *)newString + sizeof(DmesgInfo); + g_dmesgInfo->logSize = copyLen; + g_dmesgInfo->logTail = ((copyLen == g_logBufSize) ? 0 : copyLen); + g_dmesgInfo->logHead = 0; + + if (temp == g_mallocAddr) { + goto FREE_OUT; + } + g_mallocAddr = newString; + LOS_SpinUnlockRestore(&g_dmesgSpin, intSave); + + return LOS_OK; + +ERR_OUT: + free(newString); + return LOS_NOK; +FREE_OUT: + g_mallocAddr = newString; + LOS_SpinUnlockRestore(&g_dmesgSpin, intSave); + free(temp); + return LOS_OK; +} + +UINT32 OsCheckConsoleLock(VOID) +{ + return g_consoleLock; +} + +UINT32 OsCheckUartLock(VOID) +{ + return g_uartLock; +} + +UINT32 OsDmesgInit(VOID) +{ + CHAR* buffer = NULL; + + buffer = (CHAR *)malloc(KERNEL_LOG_BUF_SIZE + sizeof(DmesgInfo)); + if (buffer == NULL) { + return LOS_NOK; + } + g_mallocAddr = buffer; + g_dmesgInfo = (DmesgInfo *)buffer; + g_dmesgInfo->logHead = 0; + g_dmesgInfo->logTail = 0; + g_dmesgInfo->logSize = 0; + g_dmesgInfo->logBuf = buffer + sizeof(DmesgInfo); + g_logBufSize = KERNEL_LOG_BUF_SIZE; + + return LOS_OK; +} + +STATIC CHAR OsLogRecordChar(CHAR c) +{ + *(g_dmesgInfo->logBuf + g_dmesgInfo->logTail++) = c; + + if (g_dmesgInfo->logTail > BUF_MAX_INDEX) { + g_dmesgInfo->logTail = 0; + } + + if (g_dmesgInfo->logSize < g_logBufSize) { + (g_dmesgInfo->logSize)++; + } else { + g_dmesgInfo->logHead = g_dmesgInfo->logTail; + } + return c; +} + +UINT32 OsLogRecordStr(const CHAR *str, UINT32 len) +{ + UINT32 i = 0; + UINTPTR intSave; + + LOS_SpinLockSave(&g_dmesgSpin, &intSave); + while (len--) { + (VOID)OsLogRecordChar(str[i]); + i++; + } + LOS_SpinUnlockRestore(&g_dmesgSpin, intSave); + return i; +} + +STATIC VOID OsBufFullWrite(const CHAR *dst, UINT32 logLen) +{ + UINT32 bufSize = g_logBufSize; + UINT32 tail = g_dmesgInfo->logTail; + CHAR *buf = g_dmesgInfo->logBuf; + errno_t ret; + + if (!logLen || (dst == NULL)) { + return; + } + if (logLen > bufSize) { /* full re-write */ + ret = memcpy_s(buf + tail, bufSize - tail, dst, bufSize - tail); + if (ret != EOK) { + PRINT_ERR("%s,%d memcpy_s failed, err:%d!\n", __FUNCTION__, __LINE__, ret); + return; + } + ret = memcpy_s(buf, bufSize, dst + bufSize - tail, tail); + if (ret != EOK) { + PRINT_ERR("%s,%d memcpy_s failed, err:%d!\n", __FUNCTION__, __LINE__, ret); + return; + } + + OsBufFullWrite(dst + bufSize, logLen - bufSize); + } else { + if (logLen > (bufSize - tail)) { /* need cycle back to start */ + ret = memcpy_s(buf + tail, bufSize - tail, dst, bufSize - tail); + if (ret != EOK) { + PRINT_ERR("%s,%d memcpy_s failed, err:%d!\n", __FUNCTION__, __LINE__, ret); + return; + } + ret = memcpy_s(buf, bufSize, dst + bufSize - tail, logLen - (bufSize - tail)); + if (ret != EOK) { + PRINT_ERR("%s,%d memcpy_s failed, err:%d!\n", __FUNCTION__, __LINE__, ret); + return; + } + + g_dmesgInfo->logTail = logLen - (bufSize - tail); + g_dmesgInfo->logHead = g_dmesgInfo->logTail; + } else { /* no need cycle back to start */ + ret = memcpy_s(buf + tail, bufSize - tail, dst, logLen); + if (ret != EOK) { + PRINT_ERR("%s,%d memcpy_s failed, err:%d!\n", __FUNCTION__, __LINE__, ret); + return; + } + g_dmesgInfo->logTail += logLen; + if (g_dmesgInfo->logTail > BUF_MAX_INDEX) { + g_dmesgInfo->logTail = 0; + } + g_dmesgInfo->logHead = g_dmesgInfo->logTail; + } + } +} + +STATIC VOID OsWriteTailToHead(const CHAR *dst, UINT32 logLen) +{ + UINT32 writeLen; + UINT32 bufSize = g_logBufSize; + UINT32 logSize = g_dmesgInfo->logSize; + UINT32 tail = g_dmesgInfo->logTail; + CHAR *buf = g_dmesgInfo->logBuf; + errno_t ret; + + if ((!logLen) || (dst == NULL)) { + return; + } + if (logLen > (bufSize - logSize)) { /* space-need > space-remain */ + writeLen = bufSize - logSize; + ret = memcpy_s(buf + tail, bufSize - tail, dst, writeLen); + if (ret != EOK) { + PRINT_ERR("%s,%d memcpy_s failed, err:%d!\n", __FUNCTION__, __LINE__, ret); + return; + } + + g_dmesgInfo->logTail = g_dmesgInfo->logHead; + g_dmesgInfo->logSize = g_logBufSize; + OsBufFullWrite(dst + writeLen, logLen - writeLen); + } else { + ret = memcpy_s(buf + tail, bufSize - tail, dst, logLen); + if (ret != EOK) { + PRINT_ERR("%s,%d memcpy_s failed, err:%d!\n", __FUNCTION__, __LINE__, ret); + return; + } + + g_dmesgInfo->logTail += logLen; + g_dmesgInfo->logSize += logLen; + } +} + +STATIC VOID OsWriteTailToEnd(const CHAR *dst, UINT32 logLen) +{ + UINT32 writeLen; + UINT32 bufSize = g_logBufSize; + UINT32 tail = g_dmesgInfo->logTail; + CHAR *buf = g_dmesgInfo->logBuf; + errno_t ret; + + if ((!logLen) || (dst == NULL)) { + return; + } + if (logLen >= (bufSize - tail)) { /* need cycle to start ,then became B */ + writeLen = bufSize - tail; + ret = memcpy_s(buf + tail, writeLen, dst, writeLen); + if (ret != EOK) { + PRINT_ERR("%s,%d memcpy_s failed, err:%d!\n", __FUNCTION__, __LINE__, ret); + return; + } + + g_dmesgInfo->logSize += writeLen; + g_dmesgInfo->logTail = 0; + if (g_dmesgInfo->logSize == g_logBufSize) { /* Tail = Head is 0 */ + OsBufFullWrite(dst + writeLen, logLen - writeLen); + } else { + OsWriteTailToHead(dst + writeLen, logLen - writeLen); + } + } else { /* just do serial copy */ + ret = memcpy_s(buf + tail, bufSize - tail, dst, logLen); + if (ret != EOK) { + PRINT_ERR("%s,%d memcpy_s failed, err:%d!\n", __FUNCTION__, __LINE__, ret); + return; + } + + g_dmesgInfo->logTail += logLen; + g_dmesgInfo->logSize += logLen; + } +} + +INT32 OsLogMemcpyRecord(const CHAR *buf, UINT32 logLen) +{ + UINT32 intSave; + + LOS_SpinLockSave(&g_dmesgSpin, &intSave); + if (OsCheckError()) { + LOS_SpinUnlockRestore(&g_dmesgSpin, intSave); + return -1; + } + if (g_dmesgInfo->logSize < g_logBufSize) { + if (g_dmesgInfo->logHead <= g_dmesgInfo->logTail) { + OsWriteTailToEnd(buf, logLen); + } else { + OsWriteTailToHead(buf, logLen); + } + } else { + OsBufFullWrite(buf, logLen); + } + LOS_SpinUnlockRestore(&g_dmesgSpin, intSave); + + return LOS_OK; +} + +VOID OsLogShow(VOID) +{ + UINT32 intSave; + UINT32 index; + UINT32 i = 0; + CHAR *p = NULL; + + LOS_SpinLockSave(&g_dmesgSpin, &intSave); + index = g_dmesgInfo->logHead; + + p = (CHAR *)malloc(g_dmesgInfo->logSize + 1); + if (p == NULL) { + LOS_SpinUnlockRestore(&g_dmesgSpin, intSave); + return; + } + (VOID)memset_s(p, g_dmesgInfo->logSize + 1, 0, g_dmesgInfo->logSize + 1); + + while (i < g_dmesgInfo->logSize) { + *(p + i) = *(g_dmesgInfo->logBuf + index++); + if (index > BUF_MAX_INDEX) { + index = 0; + } + i++; + if (index == g_dmesgInfo->logTail) { + break; + } + } + LOS_SpinUnlockRestore(&g_dmesgSpin, intSave); + UartPuts(p, i, UART_WITH_LOCK); + free(p); +} + +STATIC INT32 OsDmesgLvSet(const CHAR *level) +{ + UINT32 levelNum, ret; + CHAR *p = NULL; + + levelNum = strtoul(level, &p, 0); + if (*p != 0) { + PRINTK("dmesg: invalid option or parameter.\n"); + return -1; + } + + ret = LOS_DmesgLvSet(levelNum); + if (ret == LOS_OK) { + PRINTK("Set current dmesg log level %s\n", g_levelString[g_dmesgLogLevel]); + return LOS_OK; + } else { + PRINTK("current dmesg log level %s\n", g_levelString[g_dmesgLogLevel]); + PRINTK("dmesg -l [num] can access as 0:EMG 1:COMMON 2:ERROR 3:WARN 4:INFO 5:DEBUG\n"); + return -1; + } +} + +STATIC INT32 OsDmesgMemSizeSet(const CHAR *size) +{ + UINT32 sizeVal; + CHAR *p = NULL; + + sizeVal = strtoul(size, &p, 0); + if (sizeVal > MAX_KERNEL_LOG_BUF_SIZE) { + goto ERR_OUT; + } + + if (!(LOS_DmesgMemSet(NULL, sizeVal))) { + PRINTK("Set dmesg buf size %u success\n", sizeVal); + return LOS_OK; + } else { + goto ERR_OUT; + } + +ERR_OUT: + PRINTK("Set dmesg buf size %u fail\n", sizeVal); + return LOS_NOK; +} +UINT32 OsDmesgLvGet(VOID) +{ + return g_dmesgLogLevel; +} + +UINT32 LOS_DmesgLvSet(UINT32 level) +{ + if (level > 5) { /* 5: count of level */ + return LOS_NOK; + } + + g_dmesgLogLevel = level; + return LOS_OK; +} + +VOID LOS_DmesgClear(VOID) +{ + UINT32 intSave; + + LOS_SpinLockSave(&g_dmesgSpin, &intSave); + (VOID)memset_s(g_dmesgInfo->logBuf, g_logBufSize, 0, g_logBufSize); + g_dmesgInfo->logHead = 0; + g_dmesgInfo->logTail = 0; + g_dmesgInfo->logSize = 0; + LOS_SpinUnlockRestore(&g_dmesgSpin, intSave); +} + +UINT32 LOS_DmesgMemSet(const VOID *addr, UINT32 size) +{ + UINT32 ret = 0; + + if (addr == NULL) { + ret = OsDmesgChangeSize(size); + } else { + ret = OsDmesgResetMem(addr, size); + } + return ret; +} + +INT32 LOS_DmesgRead(CHAR *buf, UINT32 len) +{ + INT32 ret; + UINT32 intSave; + + if (buf == NULL) { + return -1; + } + if (len == 0) { + return 0; + } + + LOS_SpinLockSave(&g_dmesgSpin, &intSave); + ret = OsDmesgRead(buf, len); + LOS_SpinUnlockRestore(&g_dmesgSpin, intSave); + return ret; +} + +INT32 OsDmesgWrite2File(const CHAR *fullpath, const CHAR *buf, UINT32 logSize) +{ + INT32 ret; + + INT32 fd = open(fullpath, O_CREAT | O_RDWR | O_APPEND, 0644); /* 0644:file right */ + if (fd < 0) { + return -1; + } + ret = write(fd, buf, logSize); + (VOID)close(fd); + return ret; +} + +#ifdef LOSCFG_FS_VFS +INT32 LOS_DmesgToFile(const CHAR *filename) +{ + CHAR *fullpath = NULL; + CHAR *buf = NULL; + INT32 ret; + CHAR *shellWorkingDirectory = OsShellGetWorkingDirectory(); + UINT32 logSize, bufSize, head, tail, intSave; + CHAR *logBuf = NULL; + + LOS_SpinLockSave(&g_dmesgSpin, &intSave); + if (OsCheckError()) { + LOS_SpinUnlockRestore(&g_dmesgSpin, intSave); + return -1; + } + logSize = g_dmesgInfo->logSize; + bufSize = g_logBufSize; + head = g_dmesgInfo->logHead; + tail = g_dmesgInfo->logTail; + logBuf = g_dmesgInfo->logBuf; + LOS_SpinUnlockRestore(&g_dmesgSpin, intSave); + + ret = vfs_normalize_path(shellWorkingDirectory, filename, &fullpath); + if (ret != 0) { + return -1; + } + + buf = (CHAR *)malloc(logSize); + if (buf == NULL) { + goto ERR_OUT2; + } + + if (head < tail) { + ret = memcpy_s(buf, logSize, logBuf + head, logSize); + if (ret != EOK) { + goto ERR_OUT3; + } + } else { + ret = memcpy_s(buf, logSize, logBuf + head, bufSize - head); + if (ret != EOK) { + goto ERR_OUT3; + } + ret = memcpy_s(buf + bufSize - head, logSize - (bufSize - head), logBuf, tail); + if (ret != EOK) { + goto ERR_OUT3; + } + } + + ret = OsDmesgWrite2File(fullpath, buf, logSize); +ERR_OUT3: + free(buf); +ERR_OUT2: + free(fullpath); + return ret; +} +#else +INT32 LOS_DmesgToFile(CHAR *filename) +{ + (VOID)filename; + PRINTK("File operation need VFS\n"); + return -1; +} +#endif + + +INT32 OsShellCmdDmesg(INT32 argc, const CHAR **argv) +{ + if (argc == 1) { + PRINTK("\n"); + OsLogShow(); + return LOS_OK; + } else if (argc == 2) { /* 2: count of parameters */ + if (argv == NULL) { + goto ERR_OUT; + } + + if (!strcmp(argv[1], "-c")) { + PRINTK("\n"); + OsLogShow(); + LOS_DmesgClear(); + return LOS_OK; + } else if (!strcmp(argv[1], "-C")) { + LOS_DmesgClear(); + return LOS_OK; + } else if (!strcmp(argv[1], "-D")) { + OsLockConsole(); + return LOS_OK; + } else if (!strcmp(argv[1], "-E")) { + OsUnlockConsole(); + return LOS_OK; + } else if (!strcmp(argv[1], "-L")) { + OsLockUart(); + return LOS_OK; + } else if (!strcmp(argv[1], "-U")) { + OsUnlockUart(); + return LOS_OK; + } + } else if (argc == 3) { /* 3: count of parameters */ + if (argv == NULL) { + goto ERR_OUT; + } + + if (!strcmp(argv[1], ">")) { + if (LOS_DmesgToFile((CHAR *)argv[2]) < 0) { /* 2:index of parameters */ + PRINTK("Dmesg write log to %s fail \n", argv[2]); /* 2:index of parameters */ + return -1; + } else { + PRINTK("Dmesg write log to %s success \n", argv[2]); /* 2:index of parameters */ + return LOS_OK; + } + } else if (!strcmp(argv[1], "-l")) { + return OsDmesgLvSet(argv[2]); /* 2:index of parameters */ + } else if (!strcmp(argv[1], "-s")) { + return OsDmesgMemSizeSet(argv[2]); /* 2:index of parameters */ + } + } + +ERR_OUT: + PRINTK("dmesg: invalid option or parameter.\n"); + return -1; +} + +SHELLCMD_ENTRY(dmesg_shellcmd, CMD_TYPE_STD, "dmesg", XARGS, (CmdCallBackFunc)OsShellCmdDmesg); +LOS_MODULE_INIT(OsDmesgInit, LOS_INIT_LEVEL_EARLIEST); + +#endif diff --git a/src/kernel_liteos_a/shell/full/src/cmds/hwi_shellcmd.c b/src/kernel_liteos_a/shell/full/src/cmds/hwi_shellcmd.c new file mode 100644 index 00000000..74f34d5f --- /dev/null +++ b/src/kernel_liteos_a/shell/full/src/cmds/hwi_shellcmd.c @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_config.h" +#ifdef LOSCFG_SHELL_CMD_DEBUG +#ifdef LOSCFG_CPUP_INCLUDE_IRQ +#include "los_cpup_pri.h" +#endif +#include "los_hwi_pri.h" +#include "los_sys_pri.h" +#include "shcmd.h" + + +#ifdef LOSCFG_CPUP_INCLUDE_IRQ +#define IRQ_CPUP_INFO_SIZE (sizeof(CPUP_INFO_S) * OS_HWI_MAX_NUM * LOSCFG_KERNEL_CORE_NUM) +#define IRQ_CPUP_ALL_INFO_SIZE (3 * IRQ_CPUP_INFO_SIZE) +#define IRQ_DATA_SZIE (sizeof(OsIrqCpupCB) * LOSCFG_KERNEL_CORE_NUM) +#define CPUP_PRECISION_MULT LOS_CPUP_PRECISION_MULT + +STATIC VOID ShellCmdHwiInfoShow(OsIrqCpupCB *irqData, CPUP_INFO_S *hwiCpup1s, + CPUP_INFO_S *hwiCpup10s, CPUP_INFO_S *hwiCpupAll) +{ + UINT32 intSave; + OsIrqCpupCB *irqDataBase = OsGetIrqCpupArrayBase(); + + for (UINT32 i = OS_HWI_FORM_EXC_NUM; i < OS_HWI_MAX_NUM + OS_HWI_FORM_EXC_NUM; i++) { + if (!HWI_IS_REGISTED(i)) { + continue; + } + + intSave = LOS_IntLock(); + (VOID)memcpy_s(irqData, IRQ_DATA_SZIE, &irqDataBase[i * LOSCFG_KERNEL_CORE_NUM], IRQ_DATA_SZIE); + LOS_IntRestore(intSave); + + for (UINT32 cpu = 0; cpu < LOSCFG_KERNEL_CORE_NUM; cpu++) { + UINT64 cycles = 0; + UINT64 timeMax = 0; + OsIrqCpupCB *data = &irqData[cpu]; + if (data->status == 0) { + continue; + } + UINT32 count = OsGetHwiFormCnt(cpu, i); + if (count != 0) { + if (data->count != 0) { + cycles = (data->allTime * OS_NS_PER_CYCLE) / (data->count * OS_SYS_NS_PER_US); + } + timeMax = (data->timeMax * OS_NS_PER_CYCLE) / 1000; + } + CHAR *irqName = OsGetHwiFormName(i); + UINT32 index = (i * LOSCFG_KERNEL_CORE_NUM) + cpu; + PRINTK(" %10u:%5u%11u%11llu%10llu%6u.%-2u%8u.%-2u%7u.%-2u%7s %-12s\n", i, cpu, count, cycles, timeMax, + hwiCpupAll[index].usage / CPUP_PRECISION_MULT, hwiCpupAll[index].usage % CPUP_PRECISION_MULT, + hwiCpup10s[index].usage / CPUP_PRECISION_MULT, hwiCpup10s[index].usage % CPUP_PRECISION_MULT, + hwiCpup1s[index].usage / CPUP_PRECISION_MULT, hwiCpup1s[index].usage % CPUP_PRECISION_MULT, + (g_hwiForm[index].uwParam == IRQF_SHARED) ? "shared" : "normal", (irqName != NULL) ? irqName : ""); + } + } +} + +LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdHwi(INT32 argc, const CHAR **argv) +{ + UINT32 size; + + (VOID)argv; + if (argc > 0) { + PRINTK("\nUsage: hwi\n"); + return OS_ERROR; + } + + size = IRQ_CPUP_ALL_INFO_SIZE + IRQ_DATA_SZIE; + CHAR *irqCpup = LOS_MemAlloc(m_aucSysMem0, size); + if (irqCpup == NULL) { + return OS_ERROR; + } + + CPUP_INFO_S *hwiCpupAll = (CPUP_INFO_S *)irqCpup; + CPUP_INFO_S *hwiCpup10s = (CPUP_INFO_S *)(irqCpup + IRQ_CPUP_INFO_SIZE); + CPUP_INFO_S *hwiCpup1s = (CPUP_INFO_S *)(irqCpup + 2 * IRQ_CPUP_INFO_SIZE); /* 2: offset */ + OsIrqCpupCB *irqData = (OsIrqCpupCB *)(irqCpup + IRQ_CPUP_ALL_INFO_SIZE); + + (VOID)LOS_GetAllIrqCpuUsage(CPUP_ALL_TIME, hwiCpupAll, IRQ_CPUP_INFO_SIZE); + (VOID)LOS_GetAllIrqCpuUsage(CPUP_LAST_TEN_SECONDS, hwiCpup10s, IRQ_CPUP_INFO_SIZE); + (VOID)LOS_GetAllIrqCpuUsage(CPUP_LAST_ONE_SECONDS, hwiCpup1s, IRQ_CPUP_INFO_SIZE); + + PRINTK(" InterruptNo cpu Count ATime(us) MTime(us) CPUUSE CPUUSE10s CPUUSE1s Mode Name\n"); + ShellCmdHwiInfoShow(irqData, hwiCpup1s, hwiCpup10s, hwiCpupAll); + (VOID)LOS_MemFree(m_aucSysMem0, irqCpup); + return 0; +} +#else +LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdHwi(INT32 argc, const CHAR **argv) +{ + UINT32 i; + + (VOID)argv; + if (argc > 0) { + PRINTK("\nUsage: hwi\n"); + return OS_ERROR; + } + + PRINTK(" InterruptNo Count Name\n"); + for (i = OS_HWI_FORM_EXC_NUM; i < OS_HWI_MAX_NUM + OS_HWI_FORM_EXC_NUM; i++) { + /* Different cores has different hwi form implementation */ + if (HWI_IS_REGISTED(i) && (OsGetHwiFormName(i) != NULL)) { + PRINTK(" %8d:%10d: %-s\n", i, OsGetHwiFormCnt(i), OsGetHwiFormName(i)); + } else if (HWI_IS_REGISTED(i)) { + PRINTK(" %8d:%10d:\n", i, OsGetHwiFormCnt(i)); + } + } + return 0; +} +#endif + +SHELLCMD_ENTRY(hwi_shellcmd, CMD_TYPE_EX, "hwi", 0, (CmdCallBackFunc)OsShellCmdHwi); + +#endif /* LOSCFG_SHELL */ diff --git a/src/kernel_liteos_a/shell/full/src/cmds/shell_shellcmd.c b/src/kernel_liteos_a/shell/full/src/cmds/shell_shellcmd.c new file mode 100644 index 00000000..989f0713 --- /dev/null +++ b/src/kernel_liteos_a/shell/full/src/cmds/shell_shellcmd.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "shcmd.h" + +#define DEFAULT_SCREEN_WIDTH 80 +#define MAX_CMD_KEY_WIDTH 12 +#define CMD_ITEM_PER_LINE (DEFAULT_SCREEN_WIDTH / (MAX_CMD_KEY_WIDTH + 1)) + +UINT32 OsShellCmdHelp(UINT32 argc, const CHAR **argv) +{ + UINT32 loop = 0; + CmdItemNode *curCmdItem = NULL; + CmdModInfo *cmdInfo = OsCmdInfoGet(); + + (VOID)argv; + if (argc > 0) { + PRINTK("\nUsage: help\n"); + return OS_ERROR; + } + + PRINTK("*******************shell commands:*************************\n"); + LOS_DL_LIST_FOR_EACH_ENTRY(curCmdItem, &(cmdInfo->cmdList.list), CmdItemNode, list) { + if ((loop % CMD_ITEM_PER_LINE) == 0) { /* just align print */ + PRINTK("\n"); + } + PRINTK("%-12s ", curCmdItem->cmd->cmdKey); + + loop++; + } + PRINTK("\n\nAfter shell prompt \"OHOS # \":\n" + "Use ` [args ...]` to run built-in shell commands listed above.\n" + "Use `exec [args ...]` or `./ [args ...]` to run external commands.\n"); + return 0; +} + +SHELLCMD_ENTRY(help_shellcmd, CMD_TYPE_EX, "help", 0, (CmdCallBackFunc)OsShellCmdHelp); \ No newline at end of file diff --git a/src/kernel_liteos_a/shell/full/src/cmds/watch_shellcmd.c b/src/kernel_liteos_a/shell/full/src/cmds/watch_shellcmd.c new file mode 100644 index 00000000..cd018ef1 --- /dev/null +++ b/src/kernel_liteos_a/shell/full/src/cmds/watch_shellcmd.c @@ -0,0 +1,276 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "shcmd.h" +#include "shmsg.h" +#include "unistd.h" +#include "stdio.h" +#include "time.h" +#include "los_event.h" +#include "los_tick.h" + +#include "securec.h" + +#define timeval64 timeval +#define gettimeofday64 gettimeofday +#define ctime64 ctime + +#ifdef LOSCFG_SHELL_CMD_DEBUG +typedef struct { + BOOL title; /* whether to hide the timestamps */ + UINT32 count; /* the total number of command executions */ + UINT32 interval; /* running cycle of the command */ + EVENT_CB_S watchEvent; /* event handle of the watch structure */ + CHAR cmdbuf[CMD_MAX_LEN]; /* the command to watch */ +} WatchCB; + +STATIC WatchCB *g_watchCmd; + +#define WATCH_COUNT_MAX 0xFFFFFF +#define WATCH_INTERTVAL_MAX 0xFFFFFF + +STATIC VOID PrintTime(VOID) +{ + struct timeval64 stNowTime = {0}; + + if (gettimeofday64(&stNowTime, NULL) == 0) { + PRINTK("%s", ctime64(&(stNowTime.tv_sec))); + } +} + +STATIC VOID OsShellCmdDoWatch(UINTPTR arg1) +{ + WatchCB *watchItem = (WatchCB *)arg1; + UINT32 ret; + g_watchCmd = watchItem; + + while (watchItem->count--) { + printf("\033[2J\n"); + if (watchItem->title) { + PrintTime(); + } + (VOID)ShellMsgParse(watchItem->cmdbuf); + ret = LOS_EventRead(&watchItem->watchEvent, 0x01, LOS_WAITMODE_OR | LOS_WAITMODE_CLR, watchItem->interval); + if (ret == 0x01) { + break; + } + } + + (VOID)LOS_EventDestroy(&watchItem->watchEvent); + free(g_watchCmd); + g_watchCmd = NULL; +} + +STATIC INLINE VOID OsWatchCmdUsage(VOID) +{ + PRINTK("\nUsage: watch\n"); + PRINTK("watch [options] command\n"); +} + +STATIC UINT32 OsWatchOverFunc(VOID) +{ + UINT32 ret; + if (g_watchCmd != NULL) { + ret = LOS_EventWrite(&g_watchCmd->watchEvent, 0x01); + if (ret != LOS_OK) { + PRINT_ERR("Write event failed in %s,%d\n", __FUNCTION__, __LINE__); + return OS_ERROR; + } + return LOS_OK; + } else { + PRINTK("No watch task to turn off.\n"); + return OS_ERROR; + } +} + +INT32 OsWatchOptionParsed(UINT32 argc, UINT32 *argoff, const CHAR **argv, WatchCB *watchItem) +{ + long tmpVal; + CHAR *strPtr = NULL; + UINT32 argcount = argc; + + while (argv[*argoff][0] == '-') { + if (argcount <= 1) { + OsWatchCmdUsage(); + return -1; + } + + if ((strcmp(argv[*argoff], "-n") == 0) || (strcmp(argv[*argoff], "--interval") == 0)) { + if (argcount <= 2) { /* 2:count of parameter */ + OsWatchCmdUsage(); + return -1; + } + tmpVal = (long)strtoul(argv[*argoff + 1], &strPtr, 0); + if ((*strPtr != 0) || (tmpVal <= 0) || (tmpVal > WATCH_INTERTVAL_MAX)) { + PRINTK("\ninterval time is invalid\n"); + OsWatchCmdUsage(); + return -1; + } + watchItem->interval = g_tickPerSecond * (UINT32)tmpVal; + argcount -= 2; /* 2:offset of argv */ + (*argoff) += 2; /* 2:offset of argv */ + } else if ((strcmp(argv[*argoff], "-t") == 0) || (strcmp(argv[*argoff], "-no-title") == 0)) { + watchItem->title = FALSE; + argcount--; + (*argoff)++; + } else if ((strcmp(argv[*argoff], "-c") == 0) || (strcmp(argv[*argoff], "--count") == 0)) { + if (argcount <= 2) { /* 2:count of parameter */ + OsWatchCmdUsage(); + return -1; + } + tmpVal = (long)strtoul(argv[*argoff + 1], &strPtr, 0); + if ((*strPtr != 0) || (tmpVal <= 0) || (tmpVal > WATCH_COUNT_MAX)) { + PRINTK("\ncount is invalid\n"); + OsWatchCmdUsage(); + return -1; + } + watchItem->count = (UINT32)tmpVal; + argcount -= 2; /* 2:offset of argv */ + (*argoff) += 2; /* 2:offset of argv */ + } else { + PRINTK("Unknown option.\n"); + return -1; + } + } + return 0; +} + +INT32 OsWatchCmdSplice(UINT32 argc, UINT32 argoff, const CHAR **argv, WatchCB *watchItem) +{ + INT32 err = 0; + if ((argc - argoff) == 0) { + PRINT_ERR("no watch command!\n"); + return -1; + } + while (argc - argoff) { + err = strcat_s(watchItem->cmdbuf, sizeof(watchItem->cmdbuf), argv[argoff]); + if (err != EOK) { + PRINT_ERR("%s, %d strcat_s failed!\n", __FUNCTION__, __LINE__); + return -1; + } + err = strcat_s(watchItem->cmdbuf, sizeof(watchItem->cmdbuf), " "); + if (err != EOK) { + PRINT_ERR("%s, %d strcat_s failed!\n", __FUNCTION__, __LINE__); + return -1; + } + argoff++; + } + return err; +} + +UINT32 OsWatchTaskCreate(WatchCB *watchItem) +{ + TSK_INIT_PARAM_S initParam = {0}; + UINT32 watchTaskId = 0; + UINT32 ret; + + ret = LOS_EventInit(&watchItem->watchEvent); + if (ret != 0) { + PRINT_ERR("Watch event init failed in %s, %d\n", __FUNCTION__, __LINE__); + return ret; + } + + initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)OsShellCmdDoWatch; + initParam.usTaskPrio = 10; /* 10:shellcmd_watch task priority */ + initParam.auwArgs[0] = (UINTPTR)watchItem; + initParam.uwStackSize = 0x3000; /* 0x3000:stack size of shellcmd_watch task */ + initParam.pcName = "shellcmd_watch"; + initParam.uwResved = LOS_TASK_STATUS_DETACHED; + + ret = LOS_TaskCreate(&watchTaskId, &initParam); + if (ret != 0) { + PRINT_ERR("Watch task init failed in %s, %d\n", __FUNCTION__, __LINE__); + return ret; + } + return ret; +} + +UINT32 OsShellCmdWatch(UINT32 argc, const CHAR **argv) +{ + WatchCB *watchItem = NULL; + UINT32 argoff = 0; + UINT32 ret; + INT32 err; + + if (argc == 0) { + OsWatchCmdUsage(); + return OS_ERROR; + } + + if (argv == NULL) { + OsWatchCmdUsage(); + return OS_ERROR; + } + + if ((argc == 1) && (strcmp(argv[0], "--over") == 0)) { + ret = OsWatchOverFunc(); + return ret; + } + + if (g_watchCmd != NULL) { + PRINTK("Please turn off previous watch before to start a new watch.\n"); + return OS_ERROR; + } + + watchItem = (WatchCB *)malloc(sizeof(WatchCB)); + if (watchItem == NULL) { + PRINTK("Malloc error!\n"); + return OS_ERROR; + } + (VOID)memset_s(watchItem, sizeof(WatchCB), 0, sizeof(WatchCB)); + watchItem->title = TRUE; + watchItem->count = WATCH_COUNT_MAX; + watchItem->interval = g_tickPerSecond; + + err = OsWatchOptionParsed(argc, &argoff, argv, watchItem); + if (err != 0) { + goto WATCH_ERROR; + } + + err = OsWatchCmdSplice(argc, argoff, argv, watchItem); + if (err != 0) { + goto WATCH_ERROR; + } + + ret = OsWatchTaskCreate(watchItem); + if (ret != 0) { + goto WATCH_ERROR; + } + + return LOS_OK; + +WATCH_ERROR: + free(watchItem); + return OS_ERROR; +} + +SHELLCMD_ENTRY(watch_shellcmd, CMD_TYPE_EX, "watch", XARGS, (CmdCallBackFunc)OsShellCmdWatch); +#endif diff --git a/src/kernel_liteos_a/syscall/BUILD.gn b/src/kernel_liteos_a/syscall/BUILD.gn new file mode 100644 index 00000000..b3f2b3e9 --- /dev/null +++ b/src/kernel_liteos_a/syscall/BUILD.gn @@ -0,0 +1,46 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = defined(LOSCFG_KERNEL_SYSCALL) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ + "fs_syscall.c", + "ipc_syscall.c", + "los_syscall.c", + "misc_syscall.c", + "net_syscall.c", + "process_syscall.c", + "syscall_pub.c", + "time_syscall.c", + "vm_syscall.c", + ] +} diff --git a/src/kernel_liteos_a/syscall/Makefile b/src/kernel_liteos_a/syscall/Makefile new file mode 100644 index 00000000..cf93130d --- /dev/null +++ b/src/kernel_liteos_a/syscall/Makefile @@ -0,0 +1,40 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := $(wildcard *.c) + +ifneq ($(LOSCFG_NET_LWIP_SACK), y) +LOCAL_SRCS := $(filter-out net_syscall.c, $(LOCAL_SRCS)) +endif + +include $(MODULE) diff --git a/src/kernel_liteos_a/syscall/fs_syscall.c b/src/kernel_liteos_a/syscall/fs_syscall.c new file mode 100644 index 00000000..eec9b5b4 --- /dev/null +++ b/src/kernel_liteos_a/syscall/fs_syscall.c @@ -0,0 +1,2880 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "syscall_pub.h" +#ifdef LOSCFG_FS_VFS +#include "errno.h" +#include "unistd.h" +#include "fs/fd_table.h" +#include "fs/file.h" +#include "fs/fs.h" +#include "fs/fs_operation.h" +#include "sys/mount.h" +#include "los_task_pri.h" +#include "sys/utsname.h" +#include "sys/uio.h" +#include "poll.h" +#include "sys/prctl.h" +#include "epoll.h" +#ifdef LOSCFG_KERNEL_DYNLOAD +#include "los_exec_elf.h" +#endif +#include "los_syscall.h" +#include "dirent.h" +#include "user_copy.h" +#include "los_vm_map.h" +#include "los_memory.h" +#include "los_strncpy_from_user.h" +#include "capability_type.h" +#include "capability_api.h" +#include "sys/statfs.h" + +#define HIGH_SHIFT_BIT 32 +#define TIMESPEC_TIMES_NUM 2 + +static int CheckNewAttrTime(struct IATTR *attr, struct timespec times[TIMESPEC_TIMES_NUM]) +{ + int ret = ENOERR; + struct timespec stp = {0}; + + if (times) { + if (times[0].tv_nsec == UTIME_OMIT) { + attr->attr_chg_valid &= ~CHG_ATIME; + } else if (times[0].tv_nsec == UTIME_NOW) { + ret = clock_gettime(CLOCK_REALTIME, &stp); + if (ret < 0) { + return -get_errno(); + } + attr->attr_chg_atime = (unsigned int)stp.tv_sec; + attr->attr_chg_valid |= CHG_ATIME; + } else { + attr->attr_chg_atime = (unsigned int)times[0].tv_sec; + attr->attr_chg_valid |= CHG_ATIME; + } + + if (times[1].tv_nsec == UTIME_OMIT) { + attr->attr_chg_valid &= ~CHG_MTIME; + } else if (times[1].tv_nsec == UTIME_NOW) { + ret = clock_gettime(CLOCK_REALTIME, &stp); + if (ret < 0) { + return -get_errno(); + } + attr->attr_chg_mtime = (unsigned int)stp.tv_sec; + attr->attr_chg_valid |= CHG_MTIME; + } else { + attr->attr_chg_mtime = (unsigned int)times[1].tv_sec; + attr->attr_chg_valid |= CHG_MTIME; + } + } else { + ret = clock_gettime(CLOCK_REALTIME, &stp); + if (ret < 0) { + return -get_errno(); + } + attr->attr_chg_atime = (unsigned int)stp.tv_sec; + attr->attr_chg_mtime = (unsigned int)stp.tv_sec; + attr->attr_chg_valid |= CHG_ATIME; + attr->attr_chg_valid |= CHG_MTIME; + } + + return ret; +} + +static int GetFullpathNull(int fd, const char *path, char **filePath) +{ + int ret; + char *fullPath = NULL; + struct file *file = NULL; + + if ((fd != AT_FDCWD) && (path == NULL)) { + fd = GetAssociatedSystemFd(fd); + ret = fs_getfilep(fd, &file); + if (ret < 0) { + return -get_errno(); + } + fullPath = strdup(file->f_path); + if (fullPath == NULL) { + ret = -ENOMEM; + } + } else { + ret = GetFullpath(fd, path, &fullPath); + if (ret < 0) { + return ret; + } + } + + *filePath = fullPath; + return ret; +} + +static int UserIovItemCheck(const struct iovec *iov, const int iovcnt) +{ + int i; + for (i = 0; i < iovcnt; ++i) { + if (iov[i].iov_len == 0) { + continue; + } + + if (!LOS_IsUserAddressRange((vaddr_t)(UINTPTR)iov[i].iov_base, iov[i].iov_len)) { + return i; + } + } + return iovcnt; +} + +static int UserIovCopy(struct iovec **iovBuf, const struct iovec *iov, const int iovcnt, int *valid_iovcnt) +{ + int ret; + int bufLen = iovcnt * sizeof(struct iovec); + if (bufLen < 0) { + return -EINVAL; + } + + *iovBuf = (struct iovec*)LOS_MemAlloc(OS_SYS_MEM_ADDR, bufLen); + if (*iovBuf == NULL) { + return -ENOMEM; + } + + if (LOS_ArchCopyFromUser(*iovBuf, iov, bufLen) != 0) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, *iovBuf); + return -EFAULT; + } + + ret = UserIovItemCheck(*iovBuf, iovcnt); + if (ret == 0) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, *iovBuf); + return -EFAULT; + } + + *valid_iovcnt = ret; + return 0; +} + +static int PollfdToSystem(struct pollfd *fds, nfds_t nfds, int **pollFdsBak) +{ + if ((nfds != 0 && fds == NULL) || (pollFdsBak == NULL)) { + set_errno(EINVAL); + return -1; + } + if (nfds == 0) { + return 0; + } + int *pollFds = (int *)malloc(sizeof(int) * nfds); + if (pollFds == NULL) { + set_errno(ENOMEM); + return -1; + } + for (int i = 0; i < nfds; ++i) { + struct pollfd *p_fds = &fds[i]; + pollFds[i] = p_fds->fd; + if (p_fds->fd < 0) { + set_errno(EBADF); + free(pollFds); + return -1; + } + p_fds->fd = GetAssociatedSystemFd(p_fds->fd); + } + *pollFdsBak = pollFds; + return 0; +} + +static void RestorePollfd(struct pollfd *fds, nfds_t nfds, const int *pollFds) +{ + if ((fds == NULL) || (pollFds == NULL)) { + return; + } + for (int i = 0; i < nfds; ++i) { + struct pollfd *p_fds = &fds[i]; + p_fds->fd = pollFds[i]; + } +} + +static int UserPoll(struct pollfd *fds, nfds_t nfds, int timeout) +{ + int *pollFds = NULL; + int ret = PollfdToSystem(fds, nfds, &pollFds); + if (ret < 0) { + return -1; + } + + ret = poll(fds, nfds, timeout); + + RestorePollfd(fds, nfds, pollFds); + + free(pollFds); + return ret; +} + +int SysClose(int fd) +{ + int ret; + + /* Process fd convert to system global fd */ + int sysfd = DisassociateProcessFd(fd); + + ret = close(sysfd); + if (ret < 0) { + AssociateSystemFd(fd, sysfd); + return -get_errno(); + } + FreeProcessFd(fd); + return ret; +} + +ssize_t SysRead(int fd, void *buf, size_t nbytes) +{ + int ret; + + if (nbytes == 0) { + return 0; + } + + if (!LOS_IsUserAddressRange((vaddr_t)(UINTPTR)buf, nbytes)) { + return -EFAULT; + } + + /* Process fd convert to system global fd */ + fd = GetAssociatedSystemFd(fd); + + ret = read(fd, buf, nbytes); + if (ret < 0) { + return -get_errno(); + } + return ret; +} + +ssize_t SysWrite(int fd, const void *buf, size_t nbytes) +{ + int ret; + + if (nbytes == 0) { + return 0; + } + + if (!LOS_IsUserAddressRange((vaddr_t)(UINTPTR)buf, nbytes)) { + return -EFAULT; + } + + /* Process fd convert to system global fd */ + int sysfd = GetAssociatedSystemFd(fd); + ret = write(sysfd, buf, nbytes); + if (ret < 0) { + return -get_errno(); + } + return ret; +} + +// int vfs_normalize_path(const char *directory, const char *filename, char **pathname) +#ifdef LOSCFG_PID_CONTAINER +#ifdef LOSCFG_PROC_PROCESS_DIR +#define PROCESS_DIR_ROOT "/proc" +static char *NextName(char *pos, uint8_t *len) +{ + char *name = NULL; + while (*pos != 0 && *pos == '/') { + pos++; + } + if (*pos == '\0') { + return NULL; + } + name = (char *)pos; + while (*pos != '\0' && *pos != '/') { + pos++; + } + *len = pos - name; + return name; +} + +static unsigned int ProcRealProcessIDGet(unsigned int pid) +{ + unsigned int intSave; + if (OS_PID_CHECK_INVALID(pid)) { + return 0; + } + + SCHEDULER_LOCK(intSave); + LosProcessCB *pcb = OsGetPCBFromVpid(pid); + if (OsProcessIsInactive(pcb)) { + SCHEDULER_UNLOCK(intSave); + return 0; + } + + int rootPid = OsGetRootPid(pcb); + SCHEDULER_UNLOCK(intSave); + if ((rootPid == OS_INVALID_VALUE) || (rootPid == pid)) { + return 0; + } + + return rootPid; +} + +static int ProcRealProcessDirGet(char *path) +{ + char pidBuf[PATH_MAX] = {0}; + char *fullPath = NULL; + uint8_t strLen = 0; + int pid, rootPid; + int ret = vfs_normalize_path(NULL, path, &fullPath); + if (ret < 0) { + return ret; + } + + int procLen = strlen(PROCESS_DIR_ROOT); + if (strncmp(fullPath, PROCESS_DIR_ROOT, procLen) != 0) { + free(fullPath); + return 0; + } + + char *pidStr = NextName(fullPath + procLen, &strLen); + if (pidStr == NULL) { + free(fullPath); + return 0; + } + + if ((*pidStr <= '0') || (*pidStr > '9')) { + free(fullPath); + return 0; + } + + if (memcpy_s(pidBuf, PATH_MAX, pidStr, strLen) != EOK) { + free(fullPath); + return 0; + } + pidBuf[strLen] = '\0'; + + pid = atoi(pidBuf); + if (pid == 0) { + free(fullPath); + return 0; + } + + rootPid = ProcRealProcessIDGet((unsigned)pid); + if (rootPid == 0) { + free(fullPath); + return 0; + } + + if (snprintf_s(path, PATH_MAX + 1, PATH_MAX, "/proc/%d%s", rootPid, (pidStr + strLen)) < 0) { + free(fullPath); + return -EFAULT; + } + + free(fullPath); + return 0; +} +#endif +#endif + +static int GetPath(const char *path, char **pathRet) +{ + int ret = UserPathCopy(path, pathRet); + if (ret != 0) { + return ret; + } +#ifdef LOSCFG_PID_CONTAINER +#ifdef LOSCFG_PROC_PROCESS_DIR + ret = ProcRealProcessDirGet(*pathRet); + if (ret != 0) { + return ret; + } +#endif +#endif + return 0; +} + +int SysOpen(const char *path, int oflags, ...) +{ + int ret; + int procFd = -1; + mode_t mode = DEFAULT_FILE_MODE; /* 0666: File read-write properties. */ + char *pathRet = NULL; + + if (path != NULL) { + ret = GetPath(path, &pathRet); + if (ret != 0) { + goto ERROUT; + } + } + + procFd = AllocProcessFd(); + if (procFd < 0) { + ret = -EMFILE; + goto ERROUT; + } + + if (oflags & O_CLOEXEC) { + SetCloexecFlag(procFd); + } + + if ((unsigned int)oflags & O_DIRECTORY) { + ret = do_opendir(pathRet, oflags); + } else { +#ifdef LOSCFG_FILE_MODE + va_list ap; + va_start(ap, oflags); + mode = va_arg(ap, int); + va_end(ap); +#endif + + ret = do_open(AT_FDCWD, pathRet, oflags, mode); + } + + if (ret < 0) { + ret = -get_errno(); + goto ERROUT; + } + + AssociateSystemFd(procFd, ret); + if (pathRet != NULL) { + LOS_MemFree(OS_SYS_MEM_ADDR, pathRet); + } + return procFd; + +ERROUT: + if (pathRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet); + } + if (procFd >= 0) { + FreeProcessFd(procFd); + } + return ret; +} + +int SysCreat(const char *pathname, mode_t mode) +{ + int ret = 0; + char *pathRet = NULL; + + if (pathname != NULL) { + ret = UserPathCopy(pathname, &pathRet); + if (ret != 0) { + goto OUT; + } + } + + int procFd = AllocProcessFd(); + if (procFd < 0) { + ret = -EMFILE; + goto OUT; + } + + ret = open((pathname ? pathRet : NULL), O_CREAT | O_TRUNC | O_WRONLY, mode); + if (ret < 0) { + FreeProcessFd(procFd); + ret = -get_errno(); + } else { + AssociateSystemFd(procFd, ret); + ret = procFd; + } + +OUT: + if (pathRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet); + } + return ret; +} + +int SysLink(const char *oldpath, const char *newpath) +{ + int ret; + char *oldpathRet = NULL; + char *newpathRet = NULL; + + if (oldpath != NULL) { + ret = UserPathCopy(oldpath, &oldpathRet); + if (ret != 0) { + goto OUT; + } + } + + if (newpath != NULL) { + ret = UserPathCopy(newpath, &newpathRet); + if (ret != 0) { + goto OUT; + } + } + + ret = link(oldpathRet, newpathRet); + if (ret < 0) { + ret = -get_errno(); + } + +OUT: + if (oldpathRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, oldpathRet); + } + if (newpathRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, newpathRet); + } + return ret; +} + +ssize_t SysReadlink(const char *pathname, char *buf, size_t bufsize) +{ + ssize_t ret; + char *pathRet = NULL; + + if (bufsize == 0) { + return -EINVAL; + } + + if (pathname != NULL) { + ret = UserPathCopy(pathname, &pathRet); + if (ret != 0) { + goto OUT; + } + +#ifdef LOSCFG_PID_CONTAINER +#ifdef LOSCFG_PROC_PROCESS_DIR + ret = ProcRealProcessDirGet(pathRet); + if (ret != 0) { + goto OUT; + } +#endif +#endif + } + + if (!LOS_IsUserAddressRange((vaddr_t)(UINTPTR)buf, bufsize)) { + ret = -EFAULT; + goto OUT; + } + + ret = readlink(pathRet, buf, bufsize); + if (ret < 0) { + ret = -get_errno(); + } + +OUT: + if (pathRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet); + } + return ret; +} + +int SysSymlink(const char *target, const char *linkpath) +{ + int ret; + char *targetRet = NULL; + char *pathRet = NULL; + + if (target != NULL) { + ret = UserPathCopy(target, &targetRet); + if (ret != 0) { + goto OUT; + } + } + + if (linkpath != NULL) { + ret = UserPathCopy(linkpath, &pathRet); + if (ret != 0) { + goto OUT; + } + } + + ret = symlink(targetRet, pathRet); + if (ret < 0) { + ret = -get_errno(); + } + +OUT: + if (pathRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet); + } + + if (targetRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, targetRet); + } + return ret; +} + +int SysUnlink(const char *pathname) +{ + int ret; + char *pathRet = NULL; + + if (pathname != NULL) { + ret = UserPathCopy(pathname, &pathRet); + if (ret != 0) { + goto OUT; + } + } + + ret = do_unlink(AT_FDCWD, (pathname ? pathRet : NULL)); + if (ret < 0) { + ret = -get_errno(); + } + +OUT: + if (pathRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet); + } + return ret; +} + +#ifdef LOSCFG_KERNEL_DYNLOAD +int SysExecve(const char *fileName, char *const *argv, char *const *envp) +{ + return LOS_DoExecveFile(fileName, argv, envp); +} +#endif + +int SysFchdir(int fd) +{ + int ret; + int sysFd; + struct file *file = NULL; + + sysFd = GetAssociatedSystemFd(fd); + if (sysFd < 0) { + return -EBADF; + } + + ret = fs_getfilep(sysFd, &file); + if (ret < 0) { + return -get_errno(); + } + + ret = chdir(file->f_path); + if (ret < 0) { + ret = -get_errno(); + } + + return ret; +} + +int SysChdir(const char *path) +{ + int ret; + char *pathRet = NULL; + + if (path != NULL) { + ret = UserPathCopy(path, &pathRet); + if (ret != 0) { + goto OUT; + } + } + + ret = chdir(path ? pathRet : NULL); + if (ret < 0) { + ret = -get_errno(); + } + +OUT: + if (pathRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet); + } + return ret; +} + +off_t SysLseek(int fd, off_t offset, int whence) +{ + /* Process fd convert to system global fd */ + fd = GetAssociatedSystemFd(fd); + + return _lseek(fd, offset, whence); +} + +off64_t SysLseek64(int fd, int offsetHigh, int offsetLow, off64_t *result, int whence) +{ + off64_t ret; + off64_t res; + int retVal; + + /* Process fd convert to system global fd */ + fd = GetAssociatedSystemFd(fd); + + ret = _lseek64(fd, offsetHigh, offsetLow, &res, whence); + if (ret != 0) { + return ret; + } + + retVal = LOS_ArchCopyToUser(result, &res, sizeof(off64_t)); + if (retVal != 0) { + return -EFAULT; + } + + return 0; +} + +#ifdef LOSCFG_FS_NFS +static int NfsMountRef(const char *serverIpAndPath, const char *mountPath, + unsigned int uid, unsigned int gid) __attribute__((weakref("nfs_mount"))); + +static int NfsMount(const char *serverIpAndPath, const char *mountPath, + unsigned int uid, unsigned int gid) +{ + int ret; + + if ((serverIpAndPath == NULL) || (mountPath == NULL)) { + return -EINVAL; + } + ret = NfsMountRef(serverIpAndPath, mountPath, uid, gid); + if (ret < 0) { + ret = -get_errno(); + } + return ret; +} +#endif + +int SysMount(const char *source, const char *target, const char *filesystemtype, unsigned long mountflags, + const void *data) +{ + int ret; + char *sourceRet = NULL; + char *targetRet = NULL; + char *dataRet = NULL; + char fstypeRet[FILESYSTEM_TYPE_MAX + 1] = {0}; + + if (!IsCapPermit(CAP_FS_MOUNT)) { + return -EPERM; + } + + if (target != NULL) { + ret = UserPathCopy(target, &targetRet); + if (ret != 0) { + goto OUT; + } + } + + if (filesystemtype != NULL) { + ret = LOS_StrncpyFromUser(fstypeRet, filesystemtype, FILESYSTEM_TYPE_MAX + 1); + if (ret < 0) { + goto OUT; + } else if (ret > FILESYSTEM_TYPE_MAX) { + ret = -ENODEV; + goto OUT; + } + + if (strcmp(fstypeRet, "ramfs") && (source != NULL)) { + ret = UserPathCopy(source, &sourceRet); + if (ret != 0) { + goto OUT; + } + } +#ifdef LOSCFG_FS_NFS + if (strcmp(fstypeRet, "nfs") == 0) { + ret = NfsMount(sourceRet, targetRet, 0, 0); + goto OUT; + } +#endif + } + + if (data != NULL) { + ret = UserPathCopy(data, &dataRet); + if (ret != 0) { + goto OUT; + } + } + + ret = mount(sourceRet, targetRet, (filesystemtype ? fstypeRet : NULL), mountflags, dataRet); + if (ret < 0) { + ret = -get_errno(); + } + +OUT: + if (sourceRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, sourceRet); + } + if (targetRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, targetRet); + } + if (dataRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, dataRet); + } + return ret; +} + +int SysUmount(const char *target) +{ + int ret; + char *pathRet = NULL; + + if (!IsCapPermit(CAP_FS_MOUNT)) { + return -EPERM; + } + + if (target != NULL) { + ret = UserPathCopy(target, &pathRet); + if (ret != 0) { + goto OUT; + } + } + + ret = umount(target ? pathRet : NULL); + if (ret < 0) { + ret = -get_errno(); + } + +OUT: + if (pathRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet); + } + return ret; +} + +int SysAccess(const char *path, int amode) +{ + int ret; + char *pathRet = NULL; + + if (path != NULL) { + ret = UserPathCopy(path, &pathRet); + if (ret != 0) { + goto OUT; + } + } + + ret = access(pathRet, amode); + if (ret < 0) { + ret = -get_errno(); + } + +OUT: + if (pathRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet); + } + + return ret; +} + +int SysRename(const char *oldpath, const char *newpath) +{ + int ret; + char *pathOldRet = NULL; + char *pathNewRet = NULL; + + if (oldpath != NULL) { + ret = UserPathCopy(oldpath, &pathOldRet); + if (ret != 0) { + goto OUT; + } + } + + if (newpath != NULL) { + ret = UserPathCopy(newpath, &pathNewRet); + if (ret != 0) { + goto OUT; + } + } + + ret = do_rename(AT_FDCWD, (oldpath ? pathOldRet : NULL), AT_FDCWD, + (newpath ? pathNewRet : NULL)); + if (ret < 0) { + ret = -get_errno(); + } + +OUT: + if (pathOldRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathOldRet); + } + if (pathNewRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathNewRet); + } + return ret; +} + +int SysMkdir(const char *pathname, mode_t mode) +{ + int ret; + char *pathRet = NULL; + + if (pathname != NULL) { + ret = UserPathCopy(pathname, &pathRet); + if (ret != 0) { + goto OUT; + } + } + + ret = do_mkdir(AT_FDCWD, (pathname ? pathRet : NULL), mode); + if (ret < 0) { + ret = -get_errno(); + } + +OUT: + if (pathRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet); + } + return ret; +} + +int SysRmdir(const char *pathname) +{ + int ret; + char *pathRet = NULL; + + if (pathname != NULL) { + ret = UserPathCopy(pathname, &pathRet); + if (ret != 0) { + goto OUT; + } + } + + ret = do_rmdir(AT_FDCWD, (pathname ? pathRet : NULL)); + if (ret < 0) { + ret = -get_errno(); + } + +OUT: + if (pathRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet); + } + return ret; +} + +int SysDup(int fd) +{ + int sysfd = GetAssociatedSystemFd(fd); + /* Check if the param is valid, note that: socket fd is not support dup2 */ + if ((sysfd < 0) || (sysfd >= CONFIG_NFILE_DESCRIPTORS)) { + return -EBADF; + } + + int dupfd = AllocProcessFd(); + if (dupfd < 0) { + return -EMFILE; + } + + files_refer(sysfd); + AssociateSystemFd(dupfd, sysfd); + return dupfd; +} + +void SysSync(void) +{ + sync(); +} + +int SysUmount2(const char *target, int flags) +{ + if (flags != 0) { + return -EINVAL; + } + return SysUmount(target); +} + +int SysIoctl(int fd, int req, void *arg) +{ + int ret; + unsigned int size = _IOC_SIZE((unsigned int)req); + unsigned int dir = _IOC_DIR((unsigned int)req); + if ((size == 0) && (dir != _IOC_NONE)) { + return -EINVAL; + } + + if ((dir != _IOC_NONE) && (((void *)(uintptr_t)arg) == NULL)) { + return -EINVAL; + } + + if ((dir & _IOC_READ) || (dir & _IOC_WRITE)) { + if (!LOS_IsUserAddressRange((uintptr_t)arg, size)) { + return -EFAULT; + } + } + + /* Process fd convert to system global fd */ + fd = GetAssociatedSystemFd(fd); + + ret = ioctl(fd, req, arg); + if (ret < 0) { + return -get_errno(); + } + return ret; +} + +int SysFcntl(int fd, int cmd, void *arg) +{ + /* Process fd convert to system global fd */ + int sysfd = GetAssociatedSystemFd(fd); + + int ret = VfsFcntl(fd, cmd, arg); + if (ret == CONTINE_NUTTX_FCNTL) { + ret = fcntl(sysfd, cmd, arg); + } + + if (ret < 0) { + return -get_errno(); + } + return ret; +} + +#ifdef LOSCFG_KERNEL_PIPE +int SysPipe(int pipefd[2]) /* 2 : pipe fds for read and write */ +{ + int ret; + int pipeFdIntr[2] = {0}; /* 2 : pipe fds for read and write */ + + int procFd0 = AllocProcessFd(); + if (procFd0 < 0) { + return -EMFILE; + } + int procFd1 = AllocProcessFd(); + if (procFd1 < 0) { + FreeProcessFd(procFd0); + return -EMFILE; + } + + ret = pipe(pipeFdIntr); + if (ret < 0) { + FreeProcessFd(procFd0); + FreeProcessFd(procFd1); + return -get_errno(); + } + int sysPipeFd0 = pipeFdIntr[0]; + int sysPipeFd1 = pipeFdIntr[1]; + + AssociateSystemFd(procFd0, sysPipeFd0); + AssociateSystemFd(procFd1, sysPipeFd1); + + pipeFdIntr[0] = procFd0; + pipeFdIntr[1] = procFd1; + + ret = LOS_ArchCopyToUser(pipefd, pipeFdIntr, sizeof(pipeFdIntr)); + if (ret != 0) { + FreeProcessFd(procFd0); + FreeProcessFd(procFd1); + close(sysPipeFd0); + close(sysPipeFd1); + return -EFAULT; + } + return ret; +} +#endif + +int SysDup2(int fd1, int fd2) +{ + int ret; + int sysfd1 = GetAssociatedSystemFd(fd1); + int sysfd2 = GetAssociatedSystemFd(fd2); + + /* Check if the param is valid, note that: socket fd is not support dup2 */ + if ((sysfd1 < 0) || (sysfd1 >= CONFIG_NFILE_DESCRIPTORS) || (CheckProcessFd(fd2) != OK)) { + return -EBADF; + } + + /* Handle special circumstances */ + if (fd1 == fd2) { + return fd2; + } + + ret = AllocSpecifiedProcessFd(fd2); + if (ret != OK) { + return ret; + } + + /* close the sysfd2 in need */ + if (sysfd2 >= 0) { + ret = close(sysfd2); + if (ret < 0) { + AssociateSystemFd(fd2, sysfd2); + return -get_errno(); + } + } + + files_refer(sysfd1); + AssociateSystemFd(fd2, sysfd1); + + /* if fd1 is not equal to fd2, the FD_CLOEXEC flag associated with fd2 shall be cleared */ + ClearCloexecFlag(fd2); + return fd2; +} + +static int SelectParamCheckCopy(fd_set *readfds, fd_set *writefds, fd_set *exceptfds, fd_set **fdsBuf) +{ + fd_set *readfdsRet = NULL; + fd_set *writefdsRet = NULL; + fd_set *exceptfdsRet = NULL; + + *fdsBuf = (fd_set *)LOS_MemAlloc(OS_SYS_MEM_ADDR, sizeof(fd_set) * 3); /* 3: three param need check and copy */ + if (*fdsBuf == NULL) { + return -ENOMEM; + } + + readfdsRet = *fdsBuf; /* LOS_MemAlloc 3 sizeof(fd_set) space,first use for readfds */ + writefdsRet = *fdsBuf + 1; /* 1: LOS_MemAlloc 3 sizeof(fd_set) space,second use for writefds */ + exceptfdsRet = *fdsBuf + 2; /* 2: LOS_MemAlloc 3 sizeof(fd_set) space,thired use for exceptfds */ + + if (readfds != NULL) { + if (LOS_ArchCopyFromUser(readfdsRet, readfds, sizeof(fd_set)) != 0) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, *fdsBuf); + return -EFAULT; + } + } + + if (writefds != NULL) { + if (LOS_ArchCopyFromUser(writefdsRet, writefds, sizeof(fd_set)) != 0) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, *fdsBuf); + return -EFAULT; + } + } + + if (exceptfds != NULL) { + if (LOS_ArchCopyFromUser(exceptfdsRet, exceptfds, sizeof(fd_set)) != 0) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, *fdsBuf); + return -EFAULT; + } + } + + return 0; +} + +int SysSelect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) +{ + int ret; + fd_set *fdsRet = NULL; + fd_set *readfdsRet = NULL; + fd_set *writefdsRet = NULL; + fd_set *exceptfdsRet = NULL; + struct timeval timeoutRet = {0}; + + ret = SelectParamCheckCopy(readfds, writefds, exceptfds, &fdsRet); + if (ret != 0) { + return ret; + } + + readfdsRet = fdsRet; /* LOS_MemAlloc 3 sizeof(fd_set) space,first use for readfds */ + writefdsRet = fdsRet + 1; /* 1: LOS_MemAlloc 3 sizeof(fd_set) space,second use for writefds */ + exceptfdsRet = fdsRet + 2; /* 2: LOS_MemAlloc 3 sizeof(fd_set) space,thired use for exceptfds */ + + if (timeout != NULL) { + if (LOS_ArchCopyFromUser(&timeoutRet, timeout, sizeof(struct timeval)) != 0) { + goto ERROUT; + } + } + + ret = do_select(nfds, (readfds ? readfdsRet : NULL), (writefds ? writefdsRet : NULL), + (exceptfds ? exceptfdsRet : NULL), (timeout ? (&timeoutRet) : NULL), UserPoll); + if (ret < 0) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, fdsRet); + return -get_errno(); + } + + if (readfds != NULL) { + if (LOS_ArchCopyToUser(readfds, readfdsRet, sizeof(fd_set)) != 0) { + goto ERROUT; + } + } + + if (writefds != NULL) { + if (LOS_ArchCopyToUser(writefds, writefdsRet, sizeof(fd_set)) != 0) { + goto ERROUT; + } + } + + if (exceptfds != 0) { + if (LOS_ArchCopyToUser(exceptfds, exceptfdsRet, sizeof(fd_set)) != 0) { + goto ERROUT; + } + } + + (void)LOS_MemFree(OS_SYS_MEM_ADDR, fdsRet); + return ret; + +ERROUT: + (void)LOS_MemFree(OS_SYS_MEM_ADDR, fdsRet); + return -EFAULT; +} + +int SysTruncate(const char *path, off_t length) +{ + int ret; + int fd = -1; + char *pathRet = NULL; + + if (path != NULL) { + ret = UserPathCopy(path, &pathRet); + if (ret != 0) { + goto OUT; + } + } + + fd = open((path ? pathRet : NULL), O_RDWR); + if (fd < 0) { + /* The errno value has already been set */ + ret = -get_errno(); + goto OUT; + } + + ret = ftruncate(fd, length); + close(fd); + if (ret < 0) { + ret = -get_errno(); + } + +OUT: + if (pathRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet); + } + return ret; +} + +int SysTruncate64(const char *path, off64_t length) +{ + int ret; + int fd = -1; + char *pathRet = NULL; + + if (path != NULL) { + ret = UserPathCopy(path, &pathRet); + if (ret != 0) { + goto OUT; + } + } + + fd = open((path ? pathRet : NULL), O_RDWR); + if (fd < 0) { + /* The errno value has already been set */ + ret = -get_errno(); + goto OUT; + } + + ret = ftruncate64(fd, length); + close(fd); + if (ret < 0) { + ret = -get_errno(); + } + +OUT: + if (pathRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet); + } + return ret; +} + +int SysFtruncate(int fd, off_t length) +{ + int ret; + + /* Process fd convert to system global fd */ + fd = GetAssociatedSystemFd(fd); + + ret = ftruncate(fd, length); + if (ret < 0) { + return -get_errno(); + } + return ret; +} + +int SysStatfs(const char *path, struct statfs *buf) +{ + int ret; + char *pathRet = NULL; + struct statfs bufRet = {0}; + + if (path != NULL) { + ret = UserPathCopy(path, &pathRet); + if (ret != 0) { + goto OUT; + } + } + + ret = statfs((path ? pathRet : NULL), (buf ? (&bufRet) : NULL)); + if (ret < 0) { + ret = -get_errno(); + goto OUT; + } + + ret = LOS_ArchCopyToUser(buf, &bufRet, sizeof(struct statfs)); + if (ret != 0) { + ret = -EFAULT; + } + +OUT: + if (pathRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet); + } + return ret; +} + +int SysStatfs64(const char *path, size_t sz, struct statfs *buf) +{ + int ret; + char *pathRet = NULL; + struct statfs bufRet = {0}; + + if (path != NULL) { + ret = UserPathCopy(path, &pathRet); + if (ret != 0) { + goto OUT; + } + } + + if (sz != sizeof(*buf)) { + ret = -EINVAL; + goto OUT; + } + + ret = statfs((path ? pathRet : NULL), (buf ? (&bufRet) : NULL)); + if (ret < 0) { + ret = -get_errno(); + goto OUT; + } + + ret = LOS_ArchCopyToUser(buf, &bufRet, sizeof(struct statfs)); + if (ret != 0) { + ret = -EFAULT; + } + +OUT: + if (pathRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet); + } + return ret; +} + +int SysStat(const char *path, struct kstat *buf) +{ + int ret; + char *pathRet = NULL; + struct stat bufRet = {0}; + + if (path != NULL) { + ret = UserPathCopy(path, &pathRet); + if (ret != 0) { + goto OUT; + } + } + + ret = stat((path ? pathRet : NULL), (buf ? (&bufRet) : NULL)); + if (ret < 0) { + ret = -get_errno(); + goto OUT; + } + + ret = LOS_ArchCopyToUser(buf, &bufRet, sizeof(struct kstat)); + if (ret != 0) { + ret = -EFAULT; + } + +OUT: + if (pathRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet); + } + return ret; +} + +int SysLstat(const char *path, struct kstat *buffer) +{ + int ret; + char *pathRet = NULL; + struct stat bufRet = {0}; + + if (path != NULL) { + ret = UserPathCopy(path, &pathRet); + if (ret != 0) { + goto OUT; + } + } + + ret = stat((path ? pathRet : NULL), (buffer ? (&bufRet) : NULL)); + if (ret < 0) { + ret = -get_errno(); + goto OUT; + } + + ret = LOS_ArchCopyToUser(buffer, &bufRet, sizeof(struct kstat)); + if (ret != 0) { + ret = -EFAULT; + } + +OUT: + if (pathRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet); + } + return ret; +} + +int SysFstat(int fd, struct kstat *buf) +{ + int ret; + struct stat bufRet = {0}; + struct file *filep = NULL; + + /* Process fd convert to system global fd */ + fd = GetAssociatedSystemFd(fd); + + ret = fs_getfilep(fd, &filep); + if (ret < 0) { + return -get_errno(); + } + + if (filep->f_oflags & O_DIRECTORY) { + return -EBADF; + } + + ret = stat(filep->f_path, (buf ? (&bufRet) : NULL)); + if (ret < 0) { + return -get_errno(); + } + + ret = LOS_ArchCopyToUser(buf, &bufRet, sizeof(struct kstat)); + if (ret != 0) { + return -EFAULT; + } + + return ret; +} + +int SysStatx(int fd, const char *restrict path, int flag, unsigned mask, struct statx *restrict stx) +{ + return -ENOSYS; +} + +int SysFsync(int fd) +{ + int ret; + struct file *filep = NULL; + + /* Process fd convert to system global fd */ + fd = GetAssociatedSystemFd(fd); + + /* Get the file structure corresponding to the file descriptor. */ + ret = fs_getfilep(fd, &filep); + if (ret < 0) { + /* The errno value has already been set */ + return -get_errno(); + } + + if (filep->f_oflags & O_DIRECTORY) { + return -EBADF; + } + + /* Perform the fsync operation */ + ret = file_fsync(filep); + if (ret < 0) { + return -get_errno(); + } + return ret; +} + +ssize_t SysReadv(int fd, const struct iovec *iov, int iovcnt) +{ + int ret; + int valid_iovcnt = -1; + struct iovec *iovRet = NULL; + + /* Process fd convert to system global fd */ + fd = GetAssociatedSystemFd(fd); + if ((iov == NULL) || (iovcnt < 0) || (iovcnt > IOV_MAX)) { + return -EINVAL; + } + + if (iovcnt == 0) { + return 0; + } + + ret = UserIovCopy(&iovRet, iov, iovcnt, &valid_iovcnt); + if (ret != 0) { + return ret; + } + + if (valid_iovcnt <= 0) { + ret = -EFAULT; + goto OUT; + } + + ret = vfs_readv(fd, iovRet, valid_iovcnt, NULL); + if (ret < 0) { + ret = -get_errno(); + } + +OUT: + (void)LOS_MemFree(OS_SYS_MEM_ADDR, iovRet); + return ret; +} + +ssize_t SysWritev(int fd, const struct iovec *iov, int iovcnt) +{ + int ret; + int valid_iovcnt = -1; + struct iovec *iovRet = NULL; + + /* Process fd convert to system global fd */ + int sysfd = GetAssociatedSystemFd(fd); + if ((iovcnt < 0) || (iovcnt > IOV_MAX)) { + return -EINVAL; + } + + if (iovcnt == 0) { + return 0; + } + + if (iov == NULL) { + return -EFAULT; + } + + ret = UserIovCopy(&iovRet, iov, iovcnt, &valid_iovcnt); + if (ret != 0) { + return ret; + } + + if (valid_iovcnt != iovcnt) { + ret = -EFAULT; + goto OUT_FREE; + } + + ret = writev(sysfd, iovRet, valid_iovcnt); + if (ret < 0) { + ret = -get_errno(); + } + +OUT_FREE: + (void)LOS_MemFree(OS_SYS_MEM_ADDR, iovRet); + return ret; +} + +int SysPoll(struct pollfd *fds, nfds_t nfds, int timeout) +{ + int ret; + struct pollfd *kfds = NULL; + + if ((nfds >= MAX_POLL_NFDS) || (nfds == 0) || (fds == NULL)) { + return -EINVAL; + } + + kfds = (struct pollfd *)malloc(sizeof(struct pollfd) * nfds); + if (kfds != NULL) { + if (LOS_ArchCopyFromUser(kfds, fds, sizeof(struct pollfd) * nfds) != 0) { + ret = -EFAULT; + goto OUT_KFD; + } + } + + int *pollFds = NULL; + ret = PollfdToSystem(kfds, nfds, &pollFds); + if (ret < 0) { + ret = -get_errno(); + goto OUT_KFD; + } + + ret = poll(kfds, nfds, timeout); + if (ret < 0) { + ret = -get_errno(); + goto OUT; + } + + if (kfds != NULL) { + RestorePollfd(kfds, nfds, pollFds); + if (LOS_ArchCopyToUser(fds, kfds, sizeof(struct pollfd) * nfds) != 0) { + ret = -EFAULT; + goto OUT; + } + } + +OUT: + free(pollFds); +OUT_KFD: + free(kfds); + return ret; +} + +int SysPrctl(int option, ...) +{ + unsigned long name; + va_list ap; + errno_t err; + + va_start(ap, option); + if (option != PR_SET_NAME) { + PRINT_ERR("%s: %d, no support option : 0x%x\n", __FUNCTION__, __LINE__, option); + err = EOPNOTSUPP; + goto ERROR; + } + + name = va_arg(ap, unsigned long); + if (!LOS_IsUserAddress(name)) { + err = EFAULT; + goto ERROR; + } + + err = OsSetTaskName(OsCurrTaskGet(), (const char *)(uintptr_t)name, TRUE); + if (err != LOS_OK) { + goto ERROR; + } + + va_end(ap); + return ENOERR; + +ERROR: + va_end(ap); + return -err; +} + +ssize_t SysPread64(int fd, void *buf, size_t nbytes, off64_t offset) +{ + int ret, retVal; + char *bufRet = NULL; + + /* Process fd convert to system global fd */ + fd = GetAssociatedSystemFd(fd); + + if (nbytes == 0) { + ret = pread64(fd, buf, nbytes, offset); + if (ret < 0) { + return -get_errno(); + } else { + return ret; + } + } + + bufRet = (char *)LOS_MemAlloc(OS_SYS_MEM_ADDR, nbytes); + if (bufRet == NULL) { + return -ENOMEM; + } + (void)memset_s(bufRet, nbytes, 0, nbytes); + ret = pread64(fd, (buf ? bufRet : NULL), nbytes, offset); + if (ret < 0) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, bufRet); + return -get_errno(); + } + + retVal = LOS_ArchCopyToUser(buf, bufRet, ret); + if (retVal != 0) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, bufRet); + return -EFAULT; + } + + (void)LOS_MemFree(OS_SYS_MEM_ADDR, bufRet); + return ret; +} + +ssize_t SysPwrite64(int fd, const void *buf, size_t nbytes, off64_t offset) +{ + int ret; + char *bufRet = NULL; + + /* Process fd convert to system global fd */ + fd = GetAssociatedSystemFd(fd); + + if (nbytes == 0) { + ret = pwrite64(fd, buf, nbytes, offset); + if (ret < 0) { + return -get_errno(); + } + return ret; + } + + bufRet = (char *)LOS_MemAlloc(OS_SYS_MEM_ADDR, nbytes); + if (bufRet == NULL) { + return -ENOMEM; + } + + if (buf != NULL) { + ret = LOS_ArchCopyFromUser(bufRet, buf, nbytes); + if (ret != 0) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, bufRet); + return -EFAULT; + } + } + + ret = pwrite64(fd, (buf ? bufRet : NULL), nbytes, offset); + if (ret < 0) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, bufRet); + return -get_errno(); + } + + (void)LOS_MemFree(OS_SYS_MEM_ADDR, bufRet); + return ret; +} + +char *SysGetcwd(char *buf, size_t n) +{ + char *ret = NULL; + char *bufRet = NULL; + size_t bufLen = n; + int retVal; + + if (bufLen > PATH_MAX) { + bufLen = PATH_MAX; + } + + bufRet = (char *)LOS_MemAlloc(OS_SYS_MEM_ADDR, bufLen); + if (bufRet == NULL) { + return (char *)(intptr_t)-ENOMEM; + } + (void)memset_s(bufRet, bufLen, 0, bufLen); + + ret = getcwd((buf ? bufRet : NULL), bufLen); + if (ret == NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, bufRet); + return (char *)(intptr_t)-get_errno(); + } + + retVal = LOS_ArchCopyToUser(buf, bufRet, bufLen); + if (retVal != 0) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, bufRet); + return (char *)(intptr_t)-EFAULT; + } + ret = buf; + + (void)LOS_MemFree(OS_SYS_MEM_ADDR, bufRet); + return ret; +} + +ssize_t SysSendFile(int outfd, int infd, off_t *offset, size_t count) +{ + int ret, retVal; + off_t offsetRet; + + retVal = LOS_ArchCopyFromUser(&offsetRet, offset, sizeof(off_t)); + if (retVal != 0) { + return -EFAULT; + } + + /* Process fd convert to system global fd */ + outfd = GetAssociatedSystemFd(outfd); + infd = GetAssociatedSystemFd(infd); + + ret = sendfile(outfd, infd, (offset ? (&offsetRet) : NULL), count); + if (ret < 0) { + return -get_errno(); + } + + retVal = LOS_ArchCopyToUser(offset, &offsetRet, sizeof(off_t)); + if (retVal != 0) { + return -EFAULT; + } + + return ret; +} + +int SysFtruncate64(int fd, off64_t length) +{ + int ret; + + /* Process fd convert to system global fd */ + fd = GetAssociatedSystemFd(fd); + + ret = ftruncate64(fd, length); + if (ret < 0) { + return -get_errno(); + } + return ret; +} + +int SysOpenat(int dirfd, const char *path, int oflags, ...) +{ + int ret; + int procFd; + char *pathRet = NULL; + mode_t mode; +#ifdef LOSCFG_FILE_MODE + va_list ap; + + va_start(ap, oflags); + mode = va_arg(ap, int); + va_end(ap); +#else + mode = 0666; /* 0666: File read-write properties. */ +#endif + + if (path != NULL) { + ret = UserPathCopy(path, &pathRet); + if (ret != 0) { + return ret; + } + } + + procFd = AllocProcessFd(); + if (procFd < 0) { + ret = -EMFILE; + goto ERROUT; + } + + if (oflags & O_CLOEXEC) { + SetCloexecFlag(procFd); + } + + if (dirfd != AT_FDCWD) { + /* Process fd convert to system global fd */ + dirfd = GetAssociatedSystemFd(dirfd); + } + + ret = do_open(dirfd, (path ? pathRet : NULL), oflags, mode); + if (ret < 0) { + ret = -get_errno(); + goto ERROUT; + } + + AssociateSystemFd(procFd, ret); + if (pathRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet); + } + return procFd; + +ERROUT: + if (pathRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet); + } + if (procFd >= 0) { + FreeProcessFd(procFd); + } + return ret; +} + +int SysMkdirat(int dirfd, const char *pathname, mode_t mode) +{ + int ret; + char *pathRet = NULL; + + if (pathname != NULL) { + ret = UserPathCopy(pathname, &pathRet); + if (ret != 0) { + goto OUT; + } + } + + if (dirfd != AT_FDCWD) { + /* Process fd convert to system global fd */ + dirfd = GetAssociatedSystemFd(dirfd); + } + + ret = do_mkdir(dirfd, (pathname ? pathRet : NULL), mode); + if (ret < 0) { + ret = -get_errno(); + } + +OUT: + if (pathRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet); + } + return ret; +} + +int SysLinkat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath, int flags) +{ + int ret; + char *oldpathRet = NULL; + char *newpathRet = NULL; + + if (oldpath != NULL) { + ret = UserPathCopy(oldpath, &oldpathRet); + if (ret != 0) { + goto OUT; + } + } + + if (newpath != NULL) { + ret = UserPathCopy(newpath, &newpathRet); + if (ret != 0) { + goto OUT; + } + } + + if (olddirfd != AT_FDCWD) { + /* Process fd convert to system global fd */ + olddirfd = GetAssociatedSystemFd(olddirfd); + } + + if (newdirfd != AT_FDCWD) { + /* Process fd convert to system global fd */ + newdirfd = GetAssociatedSystemFd(newdirfd); + } + + ret = linkat(olddirfd, oldpathRet, newdirfd, newpathRet, flags); + if (ret < 0) { + ret = -get_errno(); + } + +OUT: + if (oldpathRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, oldpathRet); + } + if (newpathRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, newpathRet); + } + return ret; +} + +int SysSymlinkat(const char *target, int dirfd, const char *linkpath) +{ + int ret; + char *pathRet = NULL; + char *targetRet = NULL; + + if (target != NULL) { + ret = UserPathCopy(target, &targetRet); + if (ret != 0) { + goto OUT; + } + } + + if (linkpath != NULL) { + ret = UserPathCopy(linkpath, &pathRet); + if (ret != 0) { + goto OUT; + } + } + + if (dirfd != AT_FDCWD) { + /* Process fd convert to system global fd */ + dirfd = GetAssociatedSystemFd(dirfd); + } + + ret = symlinkat(targetRet, dirfd, pathRet); + if (ret < 0) { + ret = -get_errno(); + } + +OUT: + if (pathRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet); + } + + if (targetRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, targetRet); + } + return ret; +} + +ssize_t SysReadlinkat(int dirfd, const char *pathname, char *buf, size_t bufsize) +{ + ssize_t ret; + char *pathRet = NULL; + + if (bufsize == 0) { + return -EINVAL; + } + + if (pathname != NULL) { + ret = UserPathCopy(pathname, &pathRet); + if (ret != 0) { + goto OUT; + } + +#ifdef LOSCFG_PID_CONTAINER +#ifdef LOSCFG_PROC_PROCESS_DIR + ret = ProcRealProcessDirGet(pathRet); + if (ret != 0) { + goto OUT; + } +#endif +#endif + } + + if (dirfd != AT_FDCWD) { + /* Process fd convert to system global fd */ + dirfd = GetAssociatedSystemFd(dirfd); + } + + if (!LOS_IsUserAddressRange((vaddr_t)(UINTPTR)buf, bufsize)) { + ret = -EFAULT; + goto OUT; + } + + ret = readlinkat(dirfd, pathRet, buf, bufsize); + if (ret < 0) { + ret = -get_errno(); + } + +OUT: + if (pathRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet); + } + return ret; +} + +int SysUnlinkat(int dirfd, const char *pathname, int flag) +{ + int ret; + char *pathRet = NULL; + + if (pathname != NULL) { + ret = UserPathCopy(pathname, &pathRet); + if (ret != 0) { + goto OUT; + } + } + + if (dirfd != AT_FDCWD) { + /* Process fd convert to system global fd */ + dirfd = GetAssociatedSystemFd(dirfd); + } + + ret = unlinkat(dirfd, (pathname ? pathRet : NULL), flag); + if (ret < 0) { + ret = -get_errno(); + } + +OUT: + if (pathRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet); + } + return ret; +} + +int SysRenameat(int oldfd, const char *oldpath, int newdfd, const char *newpath) +{ + int ret; + char *pathOldRet = NULL; + char *pathNewRet = NULL; + + if (oldpath != NULL) { + ret = UserPathCopy(oldpath, &pathOldRet); + if (ret != 0) { + goto OUT; + } + } + + if (newpath != NULL) { + ret = UserPathCopy(newpath, &pathNewRet); + if (ret != 0) { + goto OUT; + } + } + + if (oldfd != AT_FDCWD) { + /* Process fd convert to system global fd */ + oldfd = GetAssociatedSystemFd(oldfd); + } + if (newdfd != AT_FDCWD) { + /* Process fd convert to system global fd */ + newdfd = GetAssociatedSystemFd(newdfd); + } + + ret = do_rename(oldfd, (oldpath ? pathOldRet : NULL), newdfd, (newpath ? pathNewRet : NULL)); + if (ret < 0) { + ret = -get_errno(); + } + +OUT: + if (pathOldRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathOldRet); + } + if (pathNewRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathNewRet); + } + return ret; +} + +int SysFallocate(int fd, int mode, off_t offset, off_t len) +{ + int ret; + + /* Process fd convert to system global fd */ + fd = GetAssociatedSystemFd(fd); + + ret = fallocate(fd, mode, offset, len); + if (ret < 0) { + return -get_errno(); + } + return ret; +} + +int SysFallocate64(int fd, int mode, off64_t offset, off64_t len) +{ + int ret; + + /* Process fd convert to system global fd */ + fd = GetAssociatedSystemFd(fd); + + ret = fallocate64(fd, mode, offset, len); + if (ret < 0) { + return -get_errno(); + } + return ret; +} + +ssize_t SysPreadv(int fd, const struct iovec *iov, int iovcnt, long loffset, long hoffset) +{ + off_t offsetflag; + offsetflag = (off_t)((unsigned long long)loffset | (((unsigned long long)hoffset) << HIGH_SHIFT_BIT)); + + int ret; + int valid_iovcnt = -1; + struct iovec *iovRet = NULL; + + /* Process fd convert to system global fd */ + fd = GetAssociatedSystemFd(fd); + if ((iov == NULL) || (iovcnt < 0) || (iovcnt > IOV_MAX)) { + return -EINVAL; + } + + if (iovcnt == 0) { + return 0; + } + + ret = UserIovCopy(&iovRet, iov, iovcnt, &valid_iovcnt); + if (ret != 0) { + return ret; + } + + if (valid_iovcnt <= 0) { + ret = -EFAULT; + goto OUT_FREE; + } + + ret = preadv(fd, iovRet, valid_iovcnt, offsetflag); + if (ret < 0) { + ret = -get_errno(); + } + +OUT_FREE: + (void)(void)LOS_MemFree(OS_SYS_MEM_ADDR, iovRet); + return ret; +} + +ssize_t SysPwritev(int fd, const struct iovec *iov, int iovcnt, long loffset, long hoffset) +{ + off_t offsetflag; + offsetflag = (off_t)((unsigned long long)loffset | (((unsigned long long)hoffset) << HIGH_SHIFT_BIT)); + int ret; + int valid_iovcnt = -1; + struct iovec *iovRet = NULL; + + /* Process fd convert to system global fd */ + fd = GetAssociatedSystemFd(fd); + if ((iov == NULL) || (iovcnt < 0) || (iovcnt > IOV_MAX)) { + return -EINVAL; + } + + if (iovcnt == 0) { + return 0; + } + + ret = UserIovCopy(&iovRet, iov, iovcnt, &valid_iovcnt); + if (ret != 0) { + return ret; + } + + if (valid_iovcnt != iovcnt) { + ret = -EFAULT; + goto OUT_FREE; + } + + ret = pwritev(fd, iovRet, valid_iovcnt, offsetflag); + if (ret < 0) { + ret = -get_errno(); + } + +OUT_FREE: + (void)LOS_MemFree(OS_SYS_MEM_ADDR, iovRet); + return ret; +} + +#ifdef LOSCFG_FS_FAT +int SysFormat(const char *dev, int sectors, int option) +{ + int ret; + char *devRet = NULL; + + if (!IsCapPermit(CAP_FS_FORMAT)) { + return -EPERM; + } + + if (dev != NULL) { + ret = UserPathCopy(dev, &devRet); + if (ret != 0) { + goto OUT; + } + } + + ret = format((dev ? devRet : NULL), sectors, option); + if (ret < 0) { + ret = -get_errno(); + } + +OUT: + if (devRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, devRet); + } + return ret; +} +#endif + +int SysFstat64(int fd, struct kstat *buf) +{ + int ret; + struct stat64 bufRet = {0}; + + /* Process fd convert to system global fd */ + fd = GetAssociatedSystemFd(fd); + + ret = fstat64(fd, (buf ? (&bufRet) : NULL)); + if (ret < 0) { + return -get_errno(); + } + + ret = LOS_ArchCopyToUser(buf, &bufRet, sizeof(struct kstat)); + if (ret != 0) { + return -EFAULT; + } + + return ret; +} + +int SysFcntl64(int fd, int cmd, void *arg) +{ + /* Process fd convert to system global fd */ + int sysfd = GetAssociatedSystemFd(fd); + + int ret = VfsFcntl(fd, cmd, arg); + if (ret == CONTINE_NUTTX_FCNTL) { + ret = fcntl64(sysfd, cmd, arg); + } + + if (ret < 0) { + return -get_errno(); + } + return ret; +} + +int SysGetdents64(int fd, struct dirent *de_user, unsigned int count) +{ + if (!LOS_IsUserAddressRange((VADDR_T)(UINTPTR)de_user, count)) { + return -EFAULT; + } + + struct dirent *de_knl = NULL; + + /* Process fd convert to system global fd */ + fd = GetAssociatedSystemFd(fd); + + int ret = do_readdir(fd, &de_knl, count); + if (ret < 0) { + return ret; + } + if (de_knl != NULL) { + int cpy_ret = LOS_ArchCopyToUser(de_user, de_knl, ret); + if (cpy_ret != 0) + { + return -EFAULT; + } + } + return ret; +} + +char *SysRealpath(const char *path, char *resolved_path) +{ + char *pathRet = NULL; + char *resolved_pathRet = NULL; + char *result = NULL; + int ret; + + if (resolved_path == NULL) { + return (char *)(intptr_t)-EINVAL; + } + + if (path != NULL) { + ret = UserPathCopy(path, &pathRet); + if (ret != 0) { + result = (char *)(intptr_t)ret; + goto OUT; + } + } + + resolved_pathRet = realpath((path ? pathRet : NULL), NULL); + if (resolved_pathRet == NULL) { + result = (char *)(intptr_t)-get_errno(); + goto OUT; + } + + ret = LOS_ArchCopyToUser(resolved_path, resolved_pathRet, strlen(resolved_pathRet) + 1); + if (ret != 0) { + result = (char *)(intptr_t)-EFAULT; + goto OUT; + } + result = resolved_path; + +OUT: + if (pathRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet); + } + if (resolved_pathRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, resolved_pathRet); + } + return result; +} + +int SysUtimensat(int fd, const char *path, struct timespec times[TIMESPEC_TIMES_NUM], int flag) +{ + int ret; + int timeLen; + struct IATTR attr = {0}; + char *filePath = NULL; + + timeLen = TIMESPEC_TIMES_NUM * sizeof(struct timespec); + CHECK_ASPACE(times, timeLen); + DUP_FROM_USER(times, timeLen); + ret = CheckNewAttrTime(&attr, times); + FREE_DUP(times); + if (ret < 0) { + goto OUT; + } + + ret = GetFullpathNull(fd, path, &filePath); + if (ret < 0) { + goto OUT; + } + + ret = chattr(filePath, &attr); + if (ret < 0) { + ret = -get_errno(); + } + +OUT: + PointerFree(filePath); + return ret; +} + +int SysChmod(const char *pathname, mode_t mode) +{ + int ret; + char *pathRet = NULL; + + if (pathname != NULL) { + ret = UserPathCopy(pathname, &pathRet); + if (ret != 0) { + goto OUT; + } + } + + ret = chmod(pathRet, mode); + if (ret < 0) { + ret = -get_errno(); + } + +OUT: + if (pathRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet); + } + return ret; +} + +int SysFchmodat(int fd, const char *path, mode_t mode, int flag) +{ + int ret; + char *pathRet = NULL; + char *fullpath = NULL; + struct IATTR attr = { + .attr_chg_mode = mode, + .attr_chg_valid = CHG_MODE, + }; + + if (path != NULL) { + ret = UserPathCopy(path, &pathRet); + if (ret != 0) { + goto OUT; + } + } + + if (fd != AT_FDCWD) { + /* Process fd convert to system global fd */ + fd = GetAssociatedSystemFd(fd); + } + + ret = vfs_normalize_pathat(fd, pathRet, &fullpath); + if (ret < 0) { + goto OUT; + } + + ret = chattr(fullpath, &attr); + if (ret < 0) { + ret = -get_errno(); + } + +OUT: + PointerFree(pathRet); + PointerFree(fullpath); + + return ret; +} + +int SysFchmod(int fd, mode_t mode) +{ + int ret; + int sysFd; + struct IATTR attr = { + .attr_chg_mode = mode, + .attr_chg_valid = CHG_MODE, /* change mode */ + }; + struct file *file = NULL; + + sysFd = GetAssociatedSystemFd(fd); + if (sysFd < 0) { + return -EBADF; + } + + ret = fs_getfilep(sysFd, &file); + if (ret < 0) { + return -get_errno(); + } + + ret = chattr(file->f_path, &attr); + if (ret < 0) { + return -get_errno(); + } + + return ret; +} + +int SysFchownat(int fd, const char *path, uid_t owner, gid_t group, int flag) +{ + int ret; + char *fullpath = NULL; + struct IATTR attr = { + .attr_chg_valid = 0, + }; + + ret = GetFullpath(fd, path, &fullpath); + if (ret < 0) { + goto OUT; + } + + if (owner != (uid_t)-1) { + attr.attr_chg_uid = owner; + attr.attr_chg_valid |= CHG_UID; + } + if (group != (gid_t)-1) { + attr.attr_chg_gid = group; + attr.attr_chg_valid |= CHG_GID; + } + + ret = chattr(fullpath, &attr); + if (ret < 0) { + ret = -get_errno(); + } + +OUT: + PointerFree(fullpath); + + return ret; +} + +int SysFchown(int fd, uid_t owner, gid_t group) +{ + int ret; + int sysFd; + struct IATTR attr = {0}; + attr.attr_chg_valid = 0; + struct file *file = NULL; + + sysFd = GetAssociatedSystemFd(fd); + if (sysFd < 0) { + return -EBADF; + } + + ret = fs_getfilep(sysFd, &file); + if (ret < 0) { + return -get_errno(); + } + + if (owner != (uid_t)-1) { + attr.attr_chg_uid = owner; + attr.attr_chg_valid |= CHG_UID; + } + if (group != (gid_t)-1) { + attr.attr_chg_gid = group; + attr.attr_chg_valid |= CHG_GID; + } + ret = chattr(file->f_path, &attr); + if (ret < 0) { + ret = -get_errno(); + } + + return ret; +} + +int SysChown(const char *pathname, uid_t owner, gid_t group) +{ + int ret; + char *pathRet = NULL; + + if (pathname != NULL) { + ret = UserPathCopy(pathname, &pathRet); + if (ret != 0) { + goto OUT; + } + } + + ret = chown(pathRet, owner, group); + if (ret < 0) { + ret = -get_errno(); + } + +OUT: + if (pathRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet); + } + return ret; +} + +int SysFstatat64(int dirfd, const char *restrict path, struct kstat *restrict buf, int flag) +{ + int ret; + struct stat bufRet = {0}; + char *pathRet = NULL; + char *fullpath = NULL; + + if (path != NULL) { + ret = UserPathCopy(path, &pathRet); + if (ret != 0) { + goto OUT; + } + } + + if (dirfd != AT_FDCWD) { + /* Process fd convert to system global fd */ + dirfd = GetAssociatedSystemFd(dirfd); + } + + ret = vfs_normalize_pathat(dirfd, pathRet, &fullpath); + if (ret < 0) { + goto OUT; + } + + ret = stat(fullpath, &bufRet); + if (ret < 0) { + ret = -get_errno(); + goto OUT; + } + + ret = LOS_ArchCopyToUser(buf, &bufRet, sizeof(struct kstat)); + if (ret != 0) { + ret = -EFAULT; + goto OUT; + } + +OUT: + if (pathRet != NULL) { + LOS_MemFree(OS_SYS_MEM_ADDR, pathRet); + } + + if (fullpath != NULL) { + free(fullpath); + } + return ret; +} + +int SysFaccessat(int fd, const char *filename, int amode, int flag) +{ + int ret; + struct stat buf; + struct statfs fsBuf; + char *fullDirectory = NULL; + + ret = GetFullpath(fd, filename, &fullDirectory); + if (ret < 0) { + goto OUT; + } + + ret = statfs(fullDirectory, &fsBuf); + if (ret != 0) { + ret = -get_errno(); + goto OUT; + } + + if ((fsBuf.f_flags & MS_RDONLY) && ((unsigned int)amode & W_OK)) { + ret = -EROFS; + goto OUT; + } + + ret = stat(fullDirectory, &buf); + if (ret != 0) { + ret = -get_errno(); + goto OUT; + } + + if (VfsPermissionCheck(buf.st_uid, buf.st_gid, buf.st_mode, amode)) { + ret = -EACCES; + } + +OUT: + PointerFree(fullDirectory); + + return ret; +} + +int SysFstatfs(int fd, struct statfs *buf) +{ + int ret; + struct file *filep = NULL; + struct statfs bufRet = {0}; + + /* Process fd convert to system global fd */ + fd = GetAssociatedSystemFd(fd); + + ret = fs_getfilep(fd, &filep); + if (ret < 0) { + ret = -get_errno(); + return ret; + } + + ret = statfs(filep->f_path, &bufRet); + if (ret < 0) { + ret = -get_errno(); + return ret; + } + + ret = LOS_ArchCopyToUser(buf, &bufRet, sizeof(struct statfs)); + if (ret != 0) { + ret = -EFAULT; + } + + return ret; +} + +int SysFstatfs64(int fd, size_t sz, struct statfs *buf) +{ + int ret; + + if (sz != sizeof(struct statfs)) { + ret = -EINVAL; + return ret; + } + + ret = SysFstatfs(fd, buf); + + return ret; +} + +int SysPpoll(struct pollfd *fds, nfds_t nfds, const struct timespec *tmo_p, const sigset_t *sigMask, int nsig) +{ + int timeout, retVal; + sigset_t_l origMask = {0}; + sigset_t_l set = {0}; + + CHECK_ASPACE(tmo_p, sizeof(struct timespec)); + CPY_FROM_USER(tmo_p); + + if (tmo_p != NULL) { + timeout = tmo_p->tv_sec * OS_SYS_US_PER_MS + tmo_p->tv_nsec / OS_SYS_NS_PER_MS; + if (timeout < 0) { + return -EINVAL; + } + } else { + timeout = -1; + } + + if (sigMask != NULL) { + retVal = LOS_ArchCopyFromUser(&set, sigMask, sizeof(sigset_t)); + if (retVal != 0) { + return -EFAULT; + } + (VOID)OsSigprocMask(SIG_SETMASK, &set, &origMask); + } else { + (VOID)OsSigprocMask(SIG_SETMASK, NULL, &origMask); + } + + retVal = SysPoll(fds, nfds, timeout); + (VOID)OsSigprocMask(SIG_SETMASK, &origMask, NULL); + + return retVal; +} + +int SysPselect6(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, + const struct timespec *timeout, const long data[2]) +{ + int ret; + int retVal; + sigset_t_l origMask; + sigset_t_l setl; + + CHECK_ASPACE(readfds, sizeof(fd_set)); + CHECK_ASPACE(writefds, sizeof(fd_set)); + CHECK_ASPACE(exceptfds, sizeof(fd_set)); + CHECK_ASPACE(timeout, sizeof(struct timeval)); + + CPY_FROM_USER(readfds); + CPY_FROM_USER(writefds); + CPY_FROM_USER(exceptfds); + DUP_FROM_USER(timeout, sizeof(struct timeval)); + + if (timeout != NULL) { + ((struct timeval *)timeout)->tv_usec = timeout->tv_nsec / 1000; /* 1000, convert ns to us */ + } + + if (data != NULL) { + retVal = LOS_ArchCopyFromUser(&(setl.sig[0]), (int *)((UINTPTR)data[0]), sizeof(sigset_t)); + if (retVal != 0) { + ret = -EFAULT; + FREE_DUP(timeout); + return ret; + } + } + + OsSigprocMask(SIG_SETMASK, &setl, &origMask); + ret = do_select(nfds, readfds, writefds, exceptfds, (struct timeval *)timeout, UserPoll); + if (ret < 0) { + /* do not copy parameter back to user mode if do_select failed */ + ret = -get_errno(); + FREE_DUP(timeout); + return ret; + } + OsSigprocMask(SIG_SETMASK, &origMask, NULL); + + CPY_TO_USER(readfds); + CPY_TO_USER(writefds); + CPY_TO_USER(exceptfds); + FREE_DUP(timeout); + + return ret; +} + +static int DoEpollCreate1(int flags) +{ + int ret; + int procFd; + + ret = epoll_create1(flags); + if (ret < 0) { + ret = -get_errno(); + return ret; + } + + procFd = AllocAndAssocProcessFd((INTPTR)(ret), MIN_START_FD); + if (procFd == -1) { + epoll_close(ret); + return -EMFILE; + } + + return procFd; +} + +int SysEpollCreate(int size) +{ + (void)size; + return DoEpollCreate1(0); +} + +int SysEpollCreate1(int flags) +{ + return DoEpollCreate1(flags); +} + +int SysEpollCtl(int epfd, int op, int fd, struct epoll_event *ev) +{ + int ret; + + CHECK_ASPACE(ev, sizeof(struct epoll_event)); + CPY_FROM_USER(ev); + + fd = GetAssociatedSystemFd(fd); + epfd = GetAssociatedSystemFd(epfd); + if ((fd < 0) || (epfd < 0)) { + ret = -EBADF; + goto OUT; + } + + ret = epoll_ctl(epfd, op, fd, ev); + if (ret < 0) { + ret = -EBADF; + goto OUT; + } + + CPY_TO_USER(ev); +OUT: + return (ret == -1) ? -get_errno() : ret; +} + +int SysEpollWait(int epfd, struct epoll_event *evs, int maxevents, int timeout) +{ + int ret = 0; + + CHECK_ASPACE(evs, sizeof(struct epoll_event)); + CPY_FROM_USER(evs); + + epfd = GetAssociatedSystemFd(epfd); + if (epfd < 0) { + ret = -EBADF; + goto OUT; + } + + ret = epoll_wait(epfd, evs, maxevents, timeout); + if (ret < 0) { + ret = -get_errno(); + } + + CPY_TO_USER(evs); +OUT: + return (ret == -1) ? -get_errno() : ret; +} + +int SysEpollPwait(int epfd, struct epoll_event *evs, int maxevents, int timeout, const sigset_t *mask) +{ + sigset_t_l origMask; + sigset_t_l setl; + int ret = 0; + + CHECK_ASPACE(mask, sizeof(sigset_t)); + + if (mask != NULL) { + ret = LOS_ArchCopyFromUser(&setl, mask, sizeof(sigset_t)); + if (ret != 0) { + return -EFAULT; + } + } + + CHECK_ASPACE(evs, sizeof(struct epoll_event)); + CPY_FROM_USER(evs); + + epfd = GetAssociatedSystemFd(epfd); + if (epfd < 0) { + ret = -EBADF; + goto OUT; + } + + OsSigprocMask(SIG_SETMASK, &setl, &origMask); + ret = epoll_wait(epfd, evs, maxevents, timeout); + if (ret < 0) { + ret = -get_errno(); + } + + OsSigprocMask(SIG_SETMASK, &origMask, NULL); + + CPY_TO_USER(evs); +OUT: + return (ret == -1) ? -get_errno() : ret; +} + +#ifdef LOSCFG_CHROOT +int SysChroot(const char *path) +{ + int ret; + char *pathRet = NULL; + + if (path != NULL) { + ret = UserPathCopy(path, &pathRet); + if (ret != 0) { + goto OUT; + } + } + + ret = chroot(path ? pathRet : NULL); + if (ret < 0) { + ret = -get_errno(); + } +OUT: + if (pathRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet); + } + return ret; +} +#endif +#endif diff --git a/src/kernel_liteos_a/syscall/ipc_syscall.c b/src/kernel_liteos_a/syscall/ipc_syscall.c new file mode 100644 index 00000000..ca337def --- /dev/null +++ b/src/kernel_liteos_a/syscall/ipc_syscall.c @@ -0,0 +1,349 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "syscall_pub.h" +#include "mqueue.h" +#include +#include +#include +#include "time_posix.h" +#include "user_copy.h" +#include "los_signal.h" +#include "los_process_pri.h" +#include "los_strncpy_from_user.h" +#include "fs/file.h" + +#define MQUEUE_FD_U2K(id) \ + do { \ + int sysFd = GetAssociatedSystemFd((INTPTR)(id)); \ + (id) = (mqd_t)sysFd; \ + } while (0) +#define MQUEUE_FD_K2U(id) \ + do { \ + int procFd = AllocAndAssocProcessFd((INTPTR)(id), MIN_START_FD); \ + if (procFd == -1) { \ + mq_close(id); \ + set_errno(EMFILE); \ + (id) = (mqd_t)(-EMFILE); \ + } else { \ + (id) = (mqd_t)procFd; \ + } \ + } while (0) + +mqd_t SysMqOpen(const char *mqName, int openFlag, mode_t mode, struct mq_attr *attr) +{ + mqd_t ret; + int retValue; + char kMqName[PATH_MAX + 1] = { 0 }; + + retValue = LOS_StrncpyFromUser(kMqName, mqName, PATH_MAX); + if (retValue < 0) { + return retValue; + } + ret = mq_open(kMqName, openFlag, mode, attr); + if (ret == -1) { + return (mqd_t)-get_errno(); + } + /* SysFd to procFd */ + MQUEUE_FD_K2U(ret); + return ret; +} + +int SysMqClose(mqd_t personal) +{ + int ret; + int ufd = (INTPTR)personal; + + MQUEUE_FD_U2K(personal); + ret = mq_close(personal); + if (ret < 0) { + return -get_errno(); + } + FreeProcessFd(ufd); + return ret; +} + +int SysMqNotify(mqd_t personal, const struct sigevent *sigev) +{ + int ret; + struct sigevent ksigev; + + ret = LOS_ArchCopyFromUser(&ksigev, sigev, sizeof(struct sigevent)); + if (ret != 0) { + return -EFAULT; + } + + MQUEUE_FD_U2K(personal); + ret = OsMqNotify(personal, &ksigev); + if (ret < 0) { + return -get_errno(); + } + return ret; +} + +int SysMqGetSetAttr(mqd_t mqd, const struct mq_attr *new, struct mq_attr *old) +{ + int ret; + struct mq_attr knew; + struct mq_attr kold = { 0 }; + + if (new != NULL) { + ret = LOS_ArchCopyFromUser(&knew, new, sizeof(struct mq_attr)); + if (ret != 0) { + return -EFAULT; + } + } + MQUEUE_FD_U2K(mqd); + ret = mq_getsetattr(mqd, new ? &knew : NULL, old ? &kold : NULL); + if (ret < 0) { + return -get_errno(); + } + if (old != NULL) { + ret = LOS_ArchCopyToUser(old, &kold, sizeof(struct mq_attr)); + if (ret != 0) { + return -EFAULT; + } + } + return ret; +} + +int SysMqUnlink(const char *mqName) +{ + int ret; + int retValue; + char kMqName[PATH_MAX + 1] = { 0 }; + + retValue = LOS_StrncpyFromUser(kMqName, mqName, PATH_MAX); + if (retValue < 0) { + return retValue; + } + + ret = mq_unlink(kMqName); + if (ret < 0) { + return -get_errno(); + } + return ret; +} + +int SysMqTimedSend(mqd_t personal, const char *msg, size_t msgLen, unsigned int msgPrio, + const struct timespec *absTimeout) +{ + int ret; + struct timespec timeout; + char *msgIntr = NULL; + + if (absTimeout != NULL) { + ret = LOS_ArchCopyFromUser(&timeout, absTimeout, sizeof(struct timespec)); + if (ret != 0) { + return -EFAULT; + } + } + if (msgLen == 0) { + return -EINVAL; + } + msgIntr = (char *)malloc(msgLen); + if (msgIntr == NULL) { + return -ENOMEM; + } + ret = LOS_ArchCopyFromUser(msgIntr, msg, msgLen); + if (ret != 0) { + free(msgIntr); + return -EFAULT; + } + MQUEUE_FD_U2K(personal); + ret = mq_timedsend(personal, msgIntr, msgLen, msgPrio, absTimeout ? &timeout : NULL); + free(msgIntr); + if (ret < 0) { + return -get_errno(); + } + return ret; +} + +ssize_t SysMqTimedReceive(mqd_t personal, char *msg, size_t msgLen, unsigned int *msgPrio, + const struct timespec *absTimeout) +{ + int ret, receiveLen; + struct timespec timeout; + char *msgIntr = NULL; + unsigned int kMsgPrio; + + if (absTimeout != NULL) { + ret = LOS_ArchCopyFromUser(&timeout, absTimeout, sizeof(struct timespec)); + if (ret != 0) { + return -EFAULT; + } + } + if (msgLen == 0) { + return -EINVAL; + } + msgIntr = (char *)malloc(msgLen); + if (msgIntr == NULL) { + return -ENOMEM; + } + MQUEUE_FD_U2K(personal); + receiveLen = mq_timedreceive(personal, msgIntr, msgLen, &kMsgPrio, absTimeout ? &timeout : NULL); + if (receiveLen < 0) { + free(msgIntr); + return -get_errno(); + } + + if (msgPrio != NULL) { + ret = LOS_ArchCopyToUser(msgPrio, &kMsgPrio, sizeof(unsigned int)); + if (ret != 0) { + free(msgIntr); + return -EFAULT; + } + } + + ret = LOS_ArchCopyToUser(msg, msgIntr, receiveLen); + free(msgIntr); + if (ret != 0) { + return -EFAULT; + } + return receiveLen; +} + +int SysSigAction(int sig, const sigaction_t *restrict sa, sigaction_t *restrict old, size_t sigsetsize) +{ + return OsSigAction(sig, sa, old); +} + +int SysSigprocMask(int how, const sigset_t_l *restrict setl, sigset_t_l *restrict oldl, size_t sigsetsize) +{ + CHECK_ASPACE(setl, sizeof(sigset_t_l)); + CHECK_ASPACE(oldl, sizeof(sigset_t_l)); + CPY_FROM_USER(setl); + CPY_FROM_USER(oldl); + /* Let OsSigprocMask do all of the work */ + int ret = OsSigprocMask(how, setl, oldl); + CPY_TO_USER(oldl); + return ret; +} + +int SysKill(pid_t pid, int sig) +{ + return OsKillLock(pid, sig); +} + +int SysPthreadKill(pid_t pid, int sig) +{ + return OsPthreadKill(pid, sig); +} + +int SysSigTimedWait(const sigset_t_l *setl, siginfo_t *info, const struct timespec *timeout, size_t sigsetsize) +{ + sigset_t set; + unsigned int tick; + int retVal, ret; + siginfo_t infoIntr = { 0 }; + struct timespec timeoutIntr; + + retVal = LOS_ArchCopyFromUser(&set, &(setl->sig[0]), sizeof(sigset_t)); + if (retVal != 0) { + return -EFAULT; + } + + if (timeout == NULL) { + tick = LOS_WAIT_FOREVER; + } else { + retVal = LOS_ArchCopyFromUser(&timeoutIntr, timeout, sizeof(struct timespec)); + if (retVal != 0) { + return -EFAULT; + } + if (!ValidTimeSpec(&timeoutIntr)) { + return -EINVAL; + } + tick = OsTimeSpec2Tick(&timeoutIntr); + } + ret = OsSigTimedWait(&set, &infoIntr, tick); + if (ret < 0) { + return ret; + } + if (info != NULL) { + retVal = LOS_ArchCopyToUser(info, &infoIntr, sizeof(siginfo_t)); + if (retVal != 0) { + return -EFAULT; + } + } + return (ret == 0 ? infoIntr.si_signo : ret); +} + +int SysPause(void) +{ + return OsPause(); +} + +int SysSigPending(sigset_t_l *setl) +{ + sigset_t set; + int ret; + + ret = LOS_ArchCopyFromUser(&set, &(setl->sig[0]), sizeof(sigset_t)); + if (ret != 0) { + return -EFAULT; + } + ret = OsSigPending(&set); + if (ret != LOS_OK) { + return ret; + } + ret = LOS_ArchCopyToUser(&(setl->sig[0]), &set, sizeof(sigset_t)); + if (ret != LOS_OK) { + return -EFAULT; + } + return ret; +} + +int SysSigSuspend(sigset_t_l *setl) +{ + sigset_t set; + int retVal; + + retVal = LOS_ArchCopyFromUser(&set, &(setl->sig[0]), sizeof(sigset_t)); + if (retVal != 0) { + return -EFAULT; + } + + return OsSigSuspend(&set); +} + +#ifdef LOSCFG_KERNEL_PIPE +int SysMkFifo(const char *pathName, mode_t mode) +{ + int retValue; + char kPathName[PATH_MAX + 1] = { 0 }; + + retValue = LOS_StrncpyFromUser(kPathName, pathName, PATH_MAX); + if (retValue < 0) { + return retValue; + } + return mkfifo(kPathName, mode); +} +#endif diff --git a/src/kernel_liteos_a/syscall/los_syscall.c b/src/kernel_liteos_a/syscall/los_syscall.c new file mode 100644 index 00000000..ba8d5540 --- /dev/null +++ b/src/kernel_liteos_a/syscall/los_syscall.c @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#define _GNU_SOURCE +#ifdef LOSCFG_FS_VFS +#include "fs/file.h" +#endif +#include "los_init.h" +#include "los_signal.h" +#include "los_syscall.h" +#include "los_task_pri.h" +#include "los_process_pri.h" +#include "los_hw_pri.h" +#include "los_printf.h" +#include "time.h" +#include "utime.h" +#include "poll.h" +#include "mqueue.h" +#include "los_futex_pri.h" +#include "sys/times.h" +#include "dirent.h" +#include "fcntl.h" +#include "unistd.h" + +#include "sys/mount.h" +#include "sys/resource.h" +#include "sys/mman.h" +#include "sys/uio.h" +#include "sys/prctl.h" +#include "sys/socket.h" +#include "sys/utsname.h" +#ifdef LOSCFG_SHELL +#include "shmsg.h" +#endif +#ifdef LOSCFG_SECURITY_CAPABILITY +#include "capability_api.h" +#endif +#include "sys/shm.h" + + +#define SYS_CALL_NUM (__NR_syscallend + 1) +#define NARG_BITS 4 +#define NARG_MASK 0x0F +#define NARG_PER_BYTE 2 + +typedef UINT32 (*SyscallFun1)(UINT32); +typedef UINT32 (*SyscallFun3)(UINT32, UINT32, UINT32); +typedef UINT32 (*SyscallFun5)(UINT32, UINT32, UINT32, UINT32, UINT32); +typedef UINT32 (*SyscallFun7)(UINT32, UINT32, UINT32, UINT32, UINT32, UINT32, UINT32); + +static UINTPTR g_syscallHandle[SYS_CALL_NUM] = {0}; +static UINT8 g_syscallNArgs[(SYS_CALL_NUM + 1) / NARG_PER_BYTE] = {0}; + +void OsSyscallHandleInit(void) +{ +#define SYSCALL_HAND_DEF(id, fun, rType, nArg) \ + if ((id) < SYS_CALL_NUM) { \ + g_syscallHandle[(id)] = (UINTPTR)(fun); \ + g_syscallNArgs[(id) / NARG_PER_BYTE] |= ((id) & 1) ? (nArg) << NARG_BITS : (nArg); \ + } \ + + #include "syscall_lookup.h" +#undef SYSCALL_HAND_DEF +} + +LOS_MODULE_INIT(OsSyscallHandleInit, LOS_INIT_LEVEL_KMOD_EXTENDED); + +/* The SYSCALL ID is in R7 on entry. Parameters follow in R0..R6 */ +VOID OsArmA32SyscallHandle(TaskContext *regs) +{ + UINT32 ret; + UINT8 nArgs; + UINTPTR handle; + UINT32 cmd = regs->reserved2; + + if (cmd >= SYS_CALL_NUM) { + PRINT_ERR("Syscall ID: error %d !!!\n", cmd); + return; + } + + handle = g_syscallHandle[cmd]; + nArgs = g_syscallNArgs[cmd / NARG_PER_BYTE]; /* 4bit per nargs */ + nArgs = (cmd & 1) ? (nArgs >> NARG_BITS) : (nArgs & NARG_MASK); + if ((handle == 0) || (nArgs > ARG_NUM_7)) { + PRINT_ERR("Unsupported syscall ID: %d nArgs: %d\n", cmd, nArgs); + regs->R0 = -ENOSYS; + return; + } + + OsSigIntLock(); + switch (nArgs) { + case ARG_NUM_0: + case ARG_NUM_1: + ret = (*(SyscallFun1)handle)(regs->R0); + break; + case ARG_NUM_2: + case ARG_NUM_3: + ret = (*(SyscallFun3)handle)(regs->R0, regs->R1, regs->R2); + break; + case ARG_NUM_4: + case ARG_NUM_5: + ret = (*(SyscallFun5)handle)(regs->R0, regs->R1, regs->R2, regs->R3, regs->R4); + break; + default: + ret = (*(SyscallFun7)handle)(regs->R0, regs->R1, regs->R2, regs->R3, regs->R4, regs->R5, regs->R6); + } + + regs->R0 = ret; + OsSigIntUnlock(); + + return; +} diff --git a/src/kernel_liteos_a/syscall/los_syscall.h b/src/kernel_liteos_a/syscall/los_syscall.h new file mode 100644 index 00000000..94267398 --- /dev/null +++ b/src/kernel_liteos_a/syscall/los_syscall.h @@ -0,0 +1,326 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_SYSCALL_H +#define _LOS_SYSCALL_H + +#include +#include "los_typedef.h" +#include "los_task.h" +#include "los_mux.h" +#include "los_signal.h" +#include "syscall.h" +#include "sysinfo.h" +#include "time_posix.h" +#ifdef LOSCFG_KERNEL_DYNLOAD +#include "los_exec_elf.h" +#endif +#include "sys/resource.h" +#include "sys/times.h" +#include "sys/utsname.h" +#include "sys/shm.h" +#include "poll.h" +#include "utime.h" +#ifdef LOSCFG_COMPAT_POSIX +#include "mqueue.h" +#endif +#include "time.h" +#include "sys/time.h" +#include "sys/stat.h" +#include "sys/kstat.h" +#ifdef LOSCFG_FS_VFS +#include "sys/socket.h" +#include "dirent.h" +#include "fs/file.h" +#include "epoll.h" +#endif +#include +#ifdef LOSCFG_FS_VFS +#include "vnode.h" +#endif + +/* process */ +extern unsigned int SysGetGroupId(void); +extern unsigned int SysGetTid(void); +extern void SysSchedYield(int type); +extern int SysSchedGetScheduler(int id, int flag); +extern int SysSchedSetScheduler(int id, int policy, const LosSchedParam *userParam, int flag); +extern int SysSchedGetParam(int id, LosSchedParam *userParam, int flag); +extern int SysSchedSetParam(int id, const LosSchedParam *userParam, int flag); +extern int SysSetProcessPriority(int which, int who, int prio); +extern int SysGetProcessPriority(int which, int who); +extern int SysSchedGetPriorityMin(int policy); +extern int SysSchedGetPriorityMax(int policy); +extern int SysSchedRRGetInterval(int pid, struct timespec *tp); +extern int SysWait(int pid, USER int *status, int options, void *rusage); +extern int SysWaitid(idtype_t type, int pid, USER siginfo_t *info, int options, void *rusage); +extern int SysFork(void); +extern int SysVfork(void); +extern int SysClone(int flags, void *stack, int *parentTid, unsigned long tls, int *childTid); +extern int SysUnshare(int flags); +extern int SysSetns(int fd, int type); +extern unsigned int SysGetPID(void); +extern unsigned int SysGetPPID(void); +extern int SysSetGroupID(unsigned int gid); +extern int SysGetGroupID(void); +extern int SysGetUserID(void); +extern int SysGetEffUserID(void); +extern int SysGetEffGID(void); +extern int SysSetUserID(int uid); +extern int SysGetRealEffSaveUserID(int *ruid, int *euid, int *suid); +extern int SysGetRealEffSaveGroupID(int *rgid, int *egid, int *sgid); +extern int SysSetRealEffUserID(int ruid, int euid); +extern int SysSetRealEffGroupID(int rgid, int egid); +extern int SysSetRealEffSaveGroupID(int rgid, int egid, int sgid); +extern int SysSetRealEffSaveUserID(int ruid, int euid, int suid); +extern int SysGetGroups(int size, int list[]); +extern int SysSetGroups(int size, int list[]); +extern int SysGetCurrProcessGroupID(void); +extern int SysGetProcessGroupID(unsigned int pid); +extern int SysSetProcessGroupID(unsigned int pid, unsigned int gid); +extern unsigned int SysCreateUserThread(const TSK_ENTRY_FUNC func, const UserTaskParam *userParam, bool joinable); +extern int SysSetThreadArea(const char *area); +extern char *SysGetThreadArea(void); +extern int SysUserThreadSetDetach(unsigned int taskID); +extern int SysUserThreadDetach(unsigned int taskID); +extern int SysThreadJoin(unsigned int taskID); +extern void SysUserExitGroup(int status); +extern void SysThreadExit(int status); +extern int SysFutex(const unsigned int *uAddr, unsigned int flags, int val, + unsigned int absTime, const unsigned int *newUserAddr); +extern int SysSchedGetAffinity(int id, unsigned int *cpuset, int flag); +extern int SysSchedSetAffinity(int id, const unsigned short cpuset, int flag); + +#ifdef LOSCFG_COMPAT_POSIX +extern mqd_t SysMqOpen(const char *mqName, int openFlag, mode_t mode, struct mq_attr *attr); +extern int SysMqClose(mqd_t personal); +extern int SysMqGetSetAttr(mqd_t mqd, const struct mq_attr *new, struct mq_attr *old); +extern int SysMqUnlink(const char *mqName); +extern int SysMqSend(mqd_t personal, const char *msgPtr, size_t msgLen, unsigned int msgPrio); +extern int SysMqTimedSend(mqd_t personal, const char *msg, size_t msgLen, unsigned int msgPrio, + const struct timespec *absTimeout); +extern ssize_t SysMqTimedReceive(mqd_t personal, char *msg, size_t msgLen, unsigned int *msgPrio, + const struct timespec *absTimeout); +extern int SysMqNotify(mqd_t personal, const struct sigevent *sigev); +#endif + +extern int SysSigAction(int sig, const sigaction_t *restrict sa, sigaction_t *restrict old, size_t sigsetsize); +extern int SysSigprocMask(int how, const sigset_t_l *restrict setl, sigset_t_l *restrict oldl, size_t sigsetsize); +extern int SysKill(pid_t pid, int sig); +extern int SysPthreadKill(pid_t pid, int sig); +extern int SysSigTimedWait(const sigset_t_l *setl, siginfo_t *info, + const struct timespec *timeout, size_t sigsetsize); +extern int SysPause(void); +extern int SysSigPending(sigset_t_l *setl); +extern int SysSigSuspend(sigset_t_l *setl); +extern int SysMkFifo(const char *pathName, mode_t mode); + +/* net */ +#ifdef LOSCFG_NET_LWIP_SACK +extern int SysSocket(int domain, int type, int protocol); +extern int SysBind(int s, const struct sockaddr *name, socklen_t namelen); +extern int SysConnect(int s, const struct sockaddr *name, socklen_t namelen); +extern int SysListen(int sockfd, int backlog); +extern int SysAccept(int socket, struct sockaddr *address, socklen_t *addressLen); +extern int SysGetSockName(int s, struct sockaddr *name, socklen_t *namelen); +extern int SysGetPeerName(int s, struct sockaddr *name, socklen_t *namelen); +extern ssize_t SysSend(int s, const void *dataptr, size_t size, int flags); +extern ssize_t SysSendTo(int s, const void *dataptr, size_t size, int flags, + const struct sockaddr *to, socklen_t tolen); +extern ssize_t SysRecv(int socket, void *buffer, size_t length, int flags); +extern ssize_t SysRecvFrom(int socket, void *buffer, size_t length, int flags, + struct sockaddr *address, socklen_t *addressLen); +extern int SysShutdown(int socket, int how); +extern int SysSetSockOpt(int socket, int level, int optName, + const void *optValue, socklen_t optLen); +extern int SysGetSockOpt(int sockfd, int level, int optName, + void *optValue, socklen_t *optLen); +extern ssize_t SysSendMsg(int s, const struct msghdr *message, int flags); +extern ssize_t SysRecvMsg(int s, struct msghdr *message, int flags); +#endif + +/* vmm */ +extern void *SysMmap(void *addr, size_t size, int prot, int flags, int fd, size_t offset); +extern int SysMunmap(void *addr, size_t size); +extern int SysMprotect(void *vaddr, size_t len, int prot); +extern void *SysMremap(void *oldAddr, size_t oldLen, size_t newLen, int flags, void *newAddr); +extern void *SysBrk(void *addr); +extern int SysShmGet(key_t key, size_t size, int shmflg); +extern void *SysShmAt(int shmid, const void *shmaddr, int shmflg); +extern int SysShmCtl(int shmid, int cmd, struct shmid_ds *buf); +extern int SysShmDt(const void *shmaddr); + +/* misc */ +#ifdef LOSCFG_UTS_CONTAINER +extern int SysSetHostName(const char *name, size_t len); +#endif +extern int SysUname(struct utsname *name); +extern int SysInfo(struct sysinfo *info); + +/* time */ +extern int SysNanoSleep(const struct timespec *rqtp, struct timespec *rmtp); +extern clock_t SysTimes(struct tms *buf); +extern time_t SysTime(time_t *tloc); +extern int SysSetiTimer(int which, const struct itimerval *value, struct itimerval *ovalue); +extern int SysGetiTimer(int which, struct itimerval *value); +extern int SysTimerCreate(clockid_t clockID, struct ksigevent *evp, timer_t *timerID); +extern int SysTimerGettime(timer_t timerID, struct itimerspec *value); +extern int SysTimerGetoverrun(timer_t timerID); +extern int SysTimerDelete(timer_t timerID); +extern int SysClockSettime(clockid_t clockID, const struct timespec *tp); +extern int SysClockGettime(clockid_t clockID, struct timespec *tp); +extern int SysClockGetres(clockid_t clockID, struct timespec *tp); +extern int SysClockNanoSleep(clockid_t clk, int flags, const struct timespec *req, struct timespec *rem); +extern int SysUtime(const char *path, const struct utimbuf *ptimes); +extern int SysTimerSettime(timer_t timerID, int flags, const struct itimerspec *value, struct itimerspec *oldValue); + +extern int SysClockSettime64(clockid_t clockID, const struct timespec64 *tp); +extern int SysClockGettime64(clockid_t clockID, struct timespec64 *tp); +extern int SysClockGetres64(clockid_t clockID, struct timespec64 *tp); +extern int SysClockNanoSleep64(clockid_t clk, int flags, const struct timespec64 *req, struct timespec64 *rem); +extern int SysTimerGettime64(timer_t timerID, struct itimerspec64 *value); +extern int SysTimerSettime64(timer_t timerID, int flags, const struct itimerspec64 *value, struct itimerspec64 *oldValue); + +/* filesystem */ +#ifdef LOSCFG_FS_VFS +typedef int (*PollFun)(struct pollfd *fds, nfds_t nfds, int timeout); +extern int fp_open(char *fullpath, int oflags, mode_t mode); +extern int do_open(int dirfd, const char *path, int oflags, mode_t mode); +extern int do_unlink(int dirfd, const char *pathname); +extern int do_mkdir(int dirfd, const char *pathname, mode_t mode); +extern int do_rmdir(int dirfd, const char *pathname); +extern int do_rename(int oldfd, const char *oldpath, int newfd, const char *newpath); +extern int do_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, + struct timeval *timeout, PollFun poll); +extern int do_readdir(int fd, struct dirent **de, unsigned int count); +extern ssize_t preadv(int __fd, const struct iovec *__iov, int __count, off_t __offset); +extern ssize_t pwritev(int __fd, const struct iovec *__iov, int __count, off_t __offset); +extern int chattr(const char *pathname, struct IATTR *attr); + +extern int SysClose(int fd); +extern ssize_t SysRead(int fd, void *buf, size_t nbytes); +extern ssize_t SysWrite(int fd, const void *buf, size_t nbytes); +extern int SysOpen(const char *path, int oflags, ...); +extern int SysCreat(const char *pathname, mode_t mode); +extern int SysLink(const char *path1, const char *path2); +extern ssize_t SysReadlink(const char *pathname, char *buf, size_t bufsize); +extern int SysSymlink(const char *target, const char *linkpath); +extern int SysLinkat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath, int flags); +extern int SysSymlinkat(const char *target, int dirfd, const char *linkpath); +extern ssize_t SysReadlinkat(int dirfd, const char *pathname, char *buf, size_t bufsize); +extern int SysUnlink( const char *pathname); +extern int SysExecve(const char *fileName, char *const *argv, char *const *envp); +extern int SysFchdir(int fd); +extern int SysChdir(const char *path); +extern int SysUtimensat(int fd, const char *path, struct timespec times[2], int flag); +extern int SysFchmodat(int fd, const char *path, mode_t mode, int flag); +extern int SysFchmod(int fd, mode_t mode); +extern int SysChmod(const char *path, mode_t mode); +extern int SysFchownat(int fd, const char *path, uid_t owner, gid_t group, int flag); +extern int SysFchown(int fd, uid_t owner, gid_t group); +extern int SysChown(const char *pathname, uid_t owner, gid_t group); +extern off_t SysLseek(int fd, off_t offset, int whence); +extern off64_t SysLseek64(int fd, int offsetHigh, int offsetLow, off64_t *result, int whence); +extern int SysMount(const char *source, const char *target, const char *filesystemtype, unsigned long mountflags, + const void *data); +extern int SysUmount(const char *target); +extern int SysAccess(const char *path, int amode); +extern int SysFaccessat(int fd, const char *filename, int amode, int flag); +extern int SysRename(const char *oldpath, const char *newpath); +extern int SysMkdir(const char *pathname, mode_t mode); +extern int SysRmdir(const char *pathname); +extern int SysDup(int fd); +extern int SysUmount2(const char *target, int flags); +extern int SysIoctl(int fd, int req, void *arg); +extern int SysFcntl(int fd, int cmd, void *arg); +extern int SysDup2(int fd1, int fd2); +extern int SysSelect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); +extern int SysPselect6(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, + const struct timespec *timeout, const long data[2]); +extern int SysTruncate(const char *path, off_t length); +extern int SysFtruncate(int fd, off_t length); +extern int SysStatfs(const char *path, struct statfs *buf); +extern int SysStatfs64(const char *path, size_t sz, struct statfs *buf); +extern int SysFstatfs(int fd, struct statfs *buf); +extern int SysFstatfs64(int fd, size_t sz, struct statfs *buf); + +extern int SysStat(const char *path, struct kstat *buf); +extern int SysLstat(const char *path, struct kstat *buffer); +extern int SysFstat(int fields, struct kstat *buf); +extern int SysStatx(int fd, const char *restrict path, int flag, unsigned mask, struct statx *restrict stx); +extern int SysFsync(int fd); +extern ssize_t SysReadv(int fd, const struct iovec *iov, int iovcnt); +extern ssize_t SysWritev(int fd, const struct iovec *iov, int iovcnt); +extern int SysPipe(int pipefd[2]); /* 2 : pipe fds for read and write */ +extern int SysFormat(const char *dev, int sectors, int option); +extern int SysFstat64(int fd, struct kstat *buf); +extern int SysFstatat64(int fd, const char *restrict path, struct kstat *restrict buf, int flag); +extern int SysFcntl64(int fd, int cmd, void *arg); +extern int SysPoll(struct pollfd *fds, nfds_t nfds, int timeout); +extern int SysPpoll(struct pollfd *fds, nfds_t nfds, const struct timespec *tmo_p, + const sigset_t *sigmask, int nsig); +extern int SysPrctl(int option, ...); +extern ssize_t SysPread64(int fd, void *buf, size_t nbytes, off64_t offset); +extern ssize_t SysPwrite64(int fd, const void *buf, size_t nbytes, off64_t offset); +extern int SysEpollCreate(int size); +extern int SysEpollCreate1(int size); +extern int SysEpollCtl(int epfd, int op, int fd, struct epoll_event *ev); +extern int SysEpollWait(int epfd, struct epoll_event *evs, int maxevents, int timeout); +extern int SysEpollPwait(int epfd, struct epoll_event *evs, int maxevents, int timeout, const sigset_t *mask); +extern char *SysGetcwd(char *buf, size_t n); +extern ssize_t SysSendFile(int outfd, int infd, off_t *offset, size_t count); +extern int SysTruncate(const char *path, off_t length); +extern int SysTruncate64(const char *path, off64_t length); +extern int SysFtruncate64(int fd, off64_t length); +extern int SysOpenat(int dirfd, const char *path, int oflags, ...); +extern int SysMkdirat(int dirfd, const char *pathname, mode_t mode); +extern int SysUnlinkat(int dirfd, const char *pathname, int flag); +extern int SysRenameat(int oldfd, const char *oldpath, int newdfd, const char *newpath); +extern int SysFallocate(int fd, int mode, off_t offset, off_t len); +extern int SysFallocate64(int fd, int mode, off64_t offset, off64_t len); +extern ssize_t SysPreadv(int fd, const struct iovec *iov, int iovcnt, long loffset, long hoffset); +extern ssize_t SysPwritev(int fd, const struct iovec *iov, int iovcnt, long loffset, long hoffset); +extern void SysSync(void); +extern int SysGetdents64(int fd, struct dirent *de_user, unsigned int count); +extern int do_opendir(const char *path, int oflags); +extern char *SysRealpath(const char *path, char *resolvedPath); +extern int SysUmask(int mask); +extern int SysShellExec(const char *msgName, const char *cmdString); +extern int SysReboot(int magic, int magic2, int type); +extern int SysGetrusage(int what, struct rusage *ru); +extern long SysSysconf(int name); +extern int SysUgetrlimit(int resource, unsigned long long k_rlim[2]); +extern int SysSetrlimit(int resource, unsigned long long k_rlim[2]); +#ifdef LOSCFG_CHROOT +extern int SysChroot(const char *path); +#endif +#endif +#endif /* _LOS_SYSCALL_H */ diff --git a/src/kernel_liteos_a/syscall/misc_syscall.c b/src/kernel_liteos_a/syscall/misc_syscall.c new file mode 100644 index 00000000..154e2890 --- /dev/null +++ b/src/kernel_liteos_a/syscall/misc_syscall.c @@ -0,0 +1,280 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "errno.h" +#include "sysinfo.h" +#include "sys/reboot.h" +#include "sys/resource.h" +#include "sys/times.h" +#include "sys/utsname.h" +#include "capability_type.h" +#include "capability_api.h" +#include "los_process_pri.h" +#include "los_strncpy_from_user.h" +#ifdef LOSCFG_SHELL +#include "shcmd.h" +#include "shmsg.h" +#endif +#include "user_copy.h" +#include "unistd.h" + +#ifdef LOSCFG_UTS_CONTAINER +#define HOST_NAME_MAX_LEN 65 +int SysSetHostName(const char *name, size_t len) +{ + int ret; + char tmpName[HOST_NAME_MAX_LEN]; + unsigned int intSave; + + if (name == NULL) { + return -EFAULT; + } + + if ((len < 0) || (len > HOST_NAME_MAX_LEN)) { + return -EINVAL; + } + + ret = LOS_ArchCopyFromUser(&tmpName, name, len); + if (ret != 0) { + return -EFAULT; + } + + SCHEDULER_LOCK(intSave); + struct utsname *currentUtsName = OsGetCurrUtsName(); + if (currentUtsName == NULL) { + SCHEDULER_UNLOCK(intSave); + return -EFAULT; + } + + (VOID)memset_s(currentUtsName->nodename, sizeof(currentUtsName->nodename), 0, sizeof(currentUtsName->nodename)); + ret = memcpy_s(currentUtsName->nodename, sizeof(currentUtsName->nodename), tmpName, len); + if (ret != EOK) { + SCHEDULER_UNLOCK(intSave); + return -EFAULT; + } + SCHEDULER_UNLOCK(intSave); + return 0; +} +#endif + +int SysUname(struct utsname *name) +{ + int ret; + struct utsname tmpName; + ret = LOS_ArchCopyFromUser(&tmpName, name, sizeof(struct utsname)); + if (ret != 0) { + return -EFAULT; + } + ret = uname(&tmpName); + if (ret < 0) { + return ret; + } + ret = LOS_ArchCopyToUser(name, &tmpName, sizeof(struct utsname)); + if (ret != 0) { + return -EFAULT; + } + return ret; +} + +int SysInfo(struct sysinfo *info) +{ + int ret; + struct sysinfo tmpInfo = { 0 }; + + tmpInfo.totalram = LOS_MemPoolSizeGet(m_aucSysMem1); + tmpInfo.freeram = LOS_MemPoolSizeGet(m_aucSysMem1) - LOS_MemTotalUsedGet(m_aucSysMem1); + tmpInfo.sharedram = 0; + tmpInfo.bufferram = 0; + tmpInfo.totalswap = 0; + tmpInfo.freeswap = 0; + + ret = LOS_ArchCopyToUser(info, &tmpInfo, sizeof(struct sysinfo)); + if (ret != 0) { + return -EFAULT; + } + return 0; +} + +int SysReboot(int magic, int magic2, int type) +{ + (void)magic; + (void)magic2; + if (!IsCapPermit(CAP_REBOOT)) { + return -EPERM; + } + SystemRebootFunc rebootHook = OsGetRebootHook(); + if ((type == RB_AUTOBOOT) && (rebootHook != NULL)) { + rebootHook(); + return 0; + } + return -EFAULT; +} + +#ifdef LOSCFG_SHELL +int SysShellExec(const char *msgName, const char *cmdString) +{ + int ret; + unsigned int uintRet; + errno_t err; + CmdParsed cmdParsed; + char msgNameDup[CMD_KEY_LEN + 1] = { 0 }; + char cmdStringDup[CMD_MAX_LEN + 1] = { 0 }; + + if (!IsCapPermit(CAP_SHELL_EXEC)) { + return -EPERM; + } + + ret = LOS_StrncpyFromUser(msgNameDup, msgName, CMD_KEY_LEN + 1); + if (ret < 0) { + return -EFAULT; + } else if (ret > CMD_KEY_LEN) { + return -ENAMETOOLONG; + } + + ret = LOS_StrncpyFromUser(cmdStringDup, cmdString, CMD_MAX_LEN + 1); + if (ret < 0) { + return -EFAULT; + } else if (ret > CMD_MAX_LEN) { + return -ENAMETOOLONG; + } + + err = memset_s(&cmdParsed, sizeof(CmdParsed), 0, sizeof(CmdParsed)); + if (err != EOK) { + return -EFAULT; + } + + uintRet = ShellMsgTypeGet(&cmdParsed, msgNameDup); + if (uintRet != LOS_OK) { + PRINTK("%s:command not found\n", msgNameDup); + return -EFAULT; + } else { + (void)OsCmdExec(&cmdParsed, (char *)cmdStringDup); + } + + return 0; +} +#endif + +#define USEC_PER_SEC 1000000 + +static void ConvertClocks(struct timeval *time, clock_t clk) +{ + time->tv_usec = (clk % CLOCKS_PER_SEC) * USEC_PER_SEC / CLOCKS_PER_SEC; + time->tv_sec = (clk) / CLOCKS_PER_SEC; +} + +int SysGetrusage(int what, struct rusage *ru) +{ + int ret; + struct tms time; + clock_t usec, sec; + struct rusage kru; + + ret = LOS_ArchCopyFromUser(&kru, ru, sizeof(struct rusage)); + if (ret != 0) { + return -EFAULT; + } + + if (times(&time) == -1) { + return -EFAULT; + } + + switch (what) { + case RUSAGE_SELF: { + usec = time.tms_utime; + sec = time.tms_stime; + break; + } + case RUSAGE_CHILDREN: { + usec = time.tms_cutime; + sec = time.tms_cstime; + break; + } + default: + return -EINVAL; + } + ConvertClocks(&kru.ru_utime, usec); + ConvertClocks(&kru.ru_stime, sec); + + ret = LOS_ArchCopyToUser(ru, &kru, sizeof(struct rusage)); + if (ret != 0) { + return -EFAULT; + } + return 0; +} + +long SysSysconf(int name) +{ + long ret; + + ret = sysconf(name); + if (ret == -1) { + return -get_errno(); + } + + return ret; +} + +int SysUgetrlimit(int resource, unsigned long long k_rlim[2]) +{ + int ret; + struct rlimit lim = { 0 }; + + ret = getrlimit(resource, &lim); + if (ret < 0) { + return ret; + } + + ret = LOS_ArchCopyToUser(k_rlim, &lim, sizeof(struct rlimit)); + if (ret != 0) { + return -EFAULT; + } + + return ret; +} + +int SysSetrlimit(int resource, unsigned long long k_rlim[2]) +{ + int ret; + struct rlimit lim; + + if(!IsCapPermit(CAP_CAPSET)) { + return -EPERM; + } + + ret = LOS_ArchCopyFromUser(&lim, k_rlim, sizeof(struct rlimit)); + if (ret != 0) { + return -EFAULT; + } + ret = setrlimit(resource, &lim); + + return ret; +} diff --git a/src/kernel_liteos_a/syscall/net_syscall.c b/src/kernel_liteos_a/syscall/net_syscall.c new file mode 100644 index 00000000..b8b6aed2 --- /dev/null +++ b/src/kernel_liteos_a/syscall/net_syscall.c @@ -0,0 +1,497 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "syscall_pub.h" +#include "stdlib.h" +#include "fs/file.h" +#include "los_process_pri.h" +#include "los_signal.h" +#include "los_syscall.h" +#include "los_vm_map.h" +#include "user_copy.h" + +#ifdef LOSCFG_NET_LWIP_SACK +#include "lwip/sockets.h" + +#define SOCKET_U2K(s) \ + do { \ + s = GetAssociatedSystemFd(s); \ + if (s == VFS_ERROR) { \ + set_errno(EBADF); \ + return -get_errno(); \ + } \ + } while (0) + +#define SOCKET_K2U(s) \ + do { \ + int fd = AllocAndAssocProcessFd(s, MIN_START_FD); \ + if (fd == -1) { \ + closesocket(s); \ + set_errno(EMFILE); \ + s = -EMFILE; \ + } else { \ + s = fd; \ + } \ + } while (0) + +int SysSocket(int domain, int type, int protocol) +{ + int ret; + + ret = socket(domain, type, protocol); + if (ret == -1) { + return -get_errno(); + } + + SOCKET_K2U(ret); + return ret; +} + +int SysBind(int s, const struct sockaddr *name, socklen_t namelen) +{ + int ret; + + SOCKET_U2K(s); + CHECK_ASPACE(name, namelen); + + DUP_FROM_USER(name, namelen); + + if (name == NULL) { + set_errno(EFAULT); + ret = -1; + } else { + ret = bind(s, name, namelen); + } + FREE_DUP(name); + if (ret == -1) { + return -get_errno(); + } + + return ret; +} + +int SysConnect(int s, const struct sockaddr *name, socklen_t namelen) +{ + int ret; + + SOCKET_U2K(s); + CHECK_ASPACE(name, namelen); + + DUP_FROM_USER(name, namelen); + + if (name == NULL) { + set_errno(EFAULT); + ret = -1; + } else { + ret = connect(s, name, namelen); + } + FREE_DUP(name); + if (ret == -1) { + return -get_errno(); + } + + return ret; +} + +int SysListen(int sockfd, int backlog) +{ + int ret; + + SOCKET_U2K(sockfd); + ret = listen(sockfd, backlog); + if (ret == -1) { + return -get_errno(); + } + + return ret; +} + +int SysAccept(int socket, struct sockaddr *address, + socklen_t *addressLen) +{ + int ret; + + SOCKET_U2K(socket); + + CHECK_ASPACE(addressLen, sizeof(socklen_t)); + CPY_FROM_USER(addressLen); + + CHECK_ASPACE(address, LEN(addressLen)); + DUP_FROM_USER_NOCOPY(address, LEN(addressLen)); + + ret = accept(socket, address, addressLen); + if (ret == -1) { + FREE_DUP(address); + return -get_errno(); + } + + CPY_TO_USER(addressLen, close(ret); FREE_DUP(address)); + DUP_TO_USER(address, LEN(addressLen), close(ret); FREE_DUP(address)); + FREE_DUP(address); + + SOCKET_K2U(ret); + return ret; +} + +int SysGetSockName(int s, struct sockaddr *name, socklen_t *namelen) +{ + int ret; + + SOCKET_U2K(s); + + CHECK_ASPACE(namelen, sizeof(socklen_t)); + CPY_FROM_USER(namelen); + + CHECK_ASPACE(name, LEN(namelen)); + DUP_FROM_USER_NOCOPY(name, LEN(namelen)); + + if (name == NULL || namelen == NULL) { + set_errno(EFAULT); + ret = -1; + } else { + ret = getsockname(s, name, namelen); + } + if (ret == -1) { + FREE_DUP(name); + return -get_errno(); + } + + CPY_TO_USER(namelen, FREE_DUP(name)); + DUP_TO_USER(name, LEN(namelen), FREE_DUP(name)); + FREE_DUP(name); + return ret; +} + +int SysGetPeerName(int s, struct sockaddr *name, socklen_t *namelen) +{ + int ret; + + SOCKET_U2K(s); + + CHECK_ASPACE(namelen, sizeof(socklen_t)); + CPY_FROM_USER(namelen); + + CHECK_ASPACE(name, LEN(namelen)); + DUP_FROM_USER_NOCOPY(name, LEN(namelen)); + + if (name == NULL || namelen == NULL) { + set_errno(EFAULT); + ret = -1; + } else { + ret = getpeername(s, name, namelen); + } + if (ret == -1) { + FREE_DUP(name); + return -get_errno(); + } + + CPY_TO_USER(namelen, FREE_DUP(name)); + DUP_TO_USER(name, LEN(namelen), FREE_DUP(name)); + FREE_DUP(name); + return ret; +} + +ssize_t SysSend(int s, const void *dataptr, size_t size, int flags) +{ + int ret; + + SOCKET_U2K(s); + CHECK_ASPACE(dataptr, size); + + DUP_FROM_USER(dataptr, size); + + if (dataptr == NULL) { + set_errno(EFAULT); + ret = -1; + } else { + ret = send(s, dataptr, size, flags); + } + FREE_DUP(dataptr); + if (ret == -1) { + return -get_errno(); + } + + return ret; +} + +ssize_t SysSendTo(int s, const void *dataptr, size_t size, int flags, + const struct sockaddr *to, socklen_t tolen) +{ + int ret; + + SOCKET_U2K(s); + CHECK_ASPACE(dataptr, size); + CHECK_ASPACE(to, tolen); + + DUP_FROM_USER(dataptr, size); + DUP_FROM_USER(to, tolen, FREE_DUP(dataptr)); + + if (dataptr == NULL) { + set_errno(EFAULT); + ret = -1; + } else { + ret = sendto(s, dataptr, size, flags, to, tolen); + } + FREE_DUP(dataptr); + FREE_DUP(to); + if (ret == -1) { + return -get_errno(); + } + + return ret; +} + +ssize_t SysRecv(int socket, void *buffer, size_t length, int flags) +{ + int ret; + + SOCKET_U2K(socket); + CHECK_ASPACE(buffer, length); + + DUP_FROM_USER_NOCOPY(buffer, length); + + if (buffer == NULL) { + set_errno(EFAULT); + ret = -1; + } else { + ret = recv(socket, buffer, length, flags); + } + if (ret == -1) { + FREE_DUP(buffer); + return -get_errno(); + } + + DUP_TO_USER(buffer, ret, FREE_DUP(buffer)); + FREE_DUP(buffer); + return ret; +} + +ssize_t SysRecvFrom(int socket, void *buffer, size_t length, + int flags, struct sockaddr *address, + socklen_t *addressLen) +{ + int ret; + + SOCKET_U2K(socket); + CHECK_ASPACE(buffer, length); + + CHECK_ASPACE(addressLen, sizeof(socklen_t)); + CPY_FROM_USER(addressLen); + + CHECK_ASPACE(address, LEN(addressLen)); + DUP_FROM_USER_NOCOPY(address, LEN(addressLen)); + + DUP_FROM_USER_NOCOPY(buffer, length, FREE_DUP(address)); + + if (buffer == NULL || (address != NULL && addressLen == NULL)) { + set_errno(EFAULT); + ret = -1; + } else { + ret = recvfrom(socket, buffer, length, flags, address, addressLen); + } + if (ret == -1) { + FREE_DUP(address); + FREE_DUP(buffer); + return -get_errno(); + } + + CPY_TO_USER(addressLen, FREE_DUP(address); FREE_DUP(buffer)); + DUP_TO_USER(address, LEN(addressLen), FREE_DUP(address); FREE_DUP(buffer)); + DUP_TO_USER(buffer, ret, FREE_DUP(address); FREE_DUP(buffer)); + FREE_DUP(address); + FREE_DUP(buffer); + return ret; +} + +int SysShutdown(int socket, int how) +{ + int ret; + + SOCKET_U2K(socket); + ret = shutdown(socket, how); + if (ret == -1) { + return -get_errno(); + } + + return ret; +} + +int SysSetSockOpt(int socket, int level, int optName, + const void *optValue, socklen_t optLen) +{ + int ret; + + SOCKET_U2K(socket); + CHECK_ASPACE(optValue, optLen); + + DUP_FROM_USER(optValue, optLen); + ret = setsockopt(socket, level, optName, optValue, optLen); + FREE_DUP(optValue); + if (ret == -1) { + return -get_errno(); + } + + return ret; +} + +int SysGetSockOpt(int sockfd, int level, int optName, + void *optValue, socklen_t *optLen) +{ + int ret; + + SOCKET_U2K(sockfd); + + CHECK_ASPACE(optLen, sizeof(socklen_t)); + CPY_FROM_USER(optLen); + + CHECK_ASPACE(optValue, LEN(optLen)); + DUP_FROM_USER_NOCOPY(optValue, LEN(optLen)); + + if (optLen == NULL) { + set_errno(EFAULT); + ret = -1; + } else { + ret = getsockopt(sockfd, level, optName, optValue, optLen); + } + if (ret == -1) { + FREE_DUP(optValue); + return -get_errno(); + } + + CPY_TO_USER(optLen, FREE_DUP(optValue)); + DUP_TO_USER(optValue, LEN(optLen), FREE_DUP(optValue)); + FREE_DUP(optValue); + return ret; +} + +ssize_t SysSendMsg(int s, const struct msghdr *message, int flags) +{ + int ret; + + SOCKET_U2K(s); + + CHECK_ASPACE(message, sizeof(struct msghdr)); + CPY_FROM_CONST_USER(struct msghdr, message); + + if (message && message->msg_iovlen > IOV_MAX) { + set_errno(EMSGSIZE); + return -get_errno(); + } + + CHECK_FIELD_ASPACE(message, msg_name, message->msg_namelen); + CHECK_FIELD_ASPACE(message, msg_iov, message->msg_iovlen * sizeof(struct iovec)); + CHECK_FIELD_ASPACE(message, msg_control, message->msg_controllen); + + DUP_FIELD_FROM_USER(message, msg_iov, message->msg_iovlen * sizeof(struct iovec)); + CHECK_ARRAY_FIELD_ASPACE(message, msg_iov, message->msg_iovlen, iov_base, iov_len, + FREE_DUP_FIELD(message, msg_iov)); + DUP_FIELD_FROM_USER(message, msg_name, message->msg_namelen, + FREE_DUP_FIELD(message, msg_iov)); + DUP_FIELD_FROM_USER(message, msg_control, message->msg_controllen, + FREE_DUP_FIELD(message, msg_iov); + FREE_DUP_FIELD(message, msg_name)); + DUP_ARRAY_FIELD_FROM_USER(message, msg_iov, message->msg_iovlen, iov_base, iov_len, + FREE_DUP_FIELD(message, msg_control); + FREE_DUP_FIELD(message, msg_iov); + FREE_DUP_FIELD(message, msg_name)); + + if (message == NULL) { + set_errno(EFAULT); + ret = -1; + } else { + ret = sendmsg(s, message, flags); + } + FREE_DUP_ARRAY_FIELD(message, msg_iov, message->msg_iovlen, iov_base); + FREE_DUP_FIELD(message, msg_control); + FREE_DUP_FIELD(message, msg_iov); + FREE_DUP_FIELD(message, msg_name); + if (ret == -1) { + return -get_errno(); + } + + return ret; +} + +ssize_t SysRecvMsg(int s, struct msghdr *message, int flags) +{ + int ret; + + SOCKET_U2K(s); + + CHECK_ASPACE(message, sizeof(struct msghdr)); + CPY_FROM_NONCONST_USER(message); + + if (message && message->msg_iovlen > IOV_MAX) { + set_errno(EMSGSIZE); + return -get_errno(); + } + + CHECK_FIELD_ASPACE(message, msg_name, message->msg_namelen); + CHECK_FIELD_ASPACE(message, msg_iov, message->msg_iovlen * sizeof(struct iovec)); + CHECK_FIELD_ASPACE(message, msg_control, message->msg_controllen); + + DUP_FIELD_FROM_USER(message, msg_iov, message->msg_iovlen * sizeof(struct iovec)); + CHECK_ARRAY_FIELD_ASPACE(message, msg_iov, message->msg_iovlen, iov_base, iov_len, + FREE_DUP_FIELD(message, msg_iov)); + DUP_FIELD_FROM_USER_NOCOPY(message, msg_name, message->msg_namelen, + FREE_DUP_FIELD(message, msg_iov)); + DUP_FIELD_FROM_USER_NOCOPY(message, msg_control, message->msg_controllen, + FREE_DUP_FIELD(message, msg_iov); + FREE_DUP_FIELD(message, msg_name)); + DUP_ARRAY_FIELD_FROM_USER_NOCOPY(message, msg_iov, message->msg_iovlen, iov_base, iov_len, + FREE_DUP_FIELD(message, msg_control); + FREE_DUP_FIELD(message, msg_iov); + FREE_DUP_FIELD(message, msg_name)); + + if (message == NULL) { + set_errno(EFAULT); + ret = -1; + } else { + ret = recvmsg(s, message, flags); + } + if (ret == -1) { + goto OUT; + } + + CPY_TO_USER(message, ret = -1; goto OUT); + DUP_FIELD_TO_USER(message, msg_control, message->msg_controllen, ret = -1; goto OUT); + DUP_FIELD_TO_USER(message, msg_iov, message->msg_iovlen * sizeof(struct iovec), ret = -1; goto OUT); + DUP_FIELD_TO_USER(message, msg_name, message->msg_namelen, ret = -1; goto OUT); + DUP_ARRAY_FIELD_TO_USER(message, msg_iov, message->msg_iovlen, iov_base, iov_len, ret = -1; goto OUT); +OUT: + FREE_DUP_ARRAY_FIELD(message, msg_iov, message->msg_iovlen, iov_base); + FREE_DUP_FIELD(message, msg_control); + FREE_DUP_FIELD(message, msg_iov); + FREE_DUP_FIELD(message, msg_name); + return (ret == -1) ? -get_errno() : ret; +} + +#endif diff --git a/src/kernel_liteos_a/syscall/process_syscall.c b/src/kernel_liteos_a/syscall/process_syscall.c new file mode 100644 index 00000000..48c5f817 --- /dev/null +++ b/src/kernel_liteos_a/syscall/process_syscall.c @@ -0,0 +1,1414 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_process_pri.h" +#include "los_task_pri.h" +#include "los_sched_pri.h" +#include "los_hw_pri.h" +#include "los_sys_pri.h" +#include "los_futex_pri.h" +#include "los_mp.h" +#include "sys/wait.h" +#include "user_copy.h" +#include "time.h" +#ifdef LOSCFG_SECURITY_CAPABILITY +#include "capability_api.h" +#endif + +static int OsPermissionToCheck(unsigned int pid, unsigned int who) +{ + uintptr_t pgroupID = 0; + unsigned int ret = OsGetProcessGroupCB(pid, &pgroupID); + if (ret != 0) { + return -ret; + } else if (pgroupID == OS_KERNEL_PROCESS_GROUP) { + return -EPERM; + } else if ((pgroupID == OS_USER_PRIVILEGE_PROCESS_GROUP) && (pid != who)) { + return -EPERM; + } else if ((UINTPTR)OS_PCB_FROM_PID(pid) == OS_USER_PRIVILEGE_PROCESS_GROUP) { + return -EPERM; + } + + return 0; +} + +static int UserTaskSchedulerCheck(unsigned int tid, int policy, const LosSchedParam *schedParam, bool policyFlag) +{ + int ret; + int processPolicy; + + if (OS_TID_CHECK_INVALID(tid)) { + return EINVAL; + } + + ret = OsSchedulerParamCheck(policy, TRUE, schedParam); + if (ret != 0) { + return ret; + } + + if (policyFlag) { + ret = LOS_GetProcessScheduler(LOS_GetCurrProcessID(), &processPolicy, NULL); + if (ret < 0) { + return -ret; + } + if ((processPolicy != LOS_SCHED_DEADLINE) && (policy == LOS_SCHED_DEADLINE)) { + return EPERM; + } else if ((processPolicy == LOS_SCHED_DEADLINE) && (policy != LOS_SCHED_DEADLINE)) { + return EPERM; + } + } + return 0; +} + +static int OsUserTaskSchedulerSet(unsigned int tid, int policy, const LosSchedParam *schedParam, bool policyFlag) +{ + int ret; + unsigned int intSave; + bool needSched = false; + SchedParam param = { 0 }; + + ret = UserTaskSchedulerCheck(tid, policy, schedParam, policyFlag); + if (ret != 0) { + return ret; + } + + LosTaskCB *taskCB = OS_TCB_FROM_TID(tid); + SCHEDULER_LOCK(intSave); + ret = OsUserTaskOperatePermissionsCheck(taskCB); + if (ret != LOS_OK) { + SCHEDULER_UNLOCK(intSave); + return ret; + } + + taskCB->ops->schedParamGet(taskCB, ¶m); + param.policy = (policyFlag == true) ? (UINT16)policy : param.policy; + if ((param.policy == LOS_SCHED_RR) || (param.policy == LOS_SCHED_FIFO)) { + param.priority = schedParam->priority; + } else if (param.policy == LOS_SCHED_DEADLINE) { +#ifdef LOSCFG_SECURITY_CAPABILITY + /* user mode process with privilege of CAP_SCHED_SETPRIORITY can change the priority */ + if (!IsCapPermit(CAP_SCHED_SETPRIORITY)) { + SCHEDULER_UNLOCK(intSave); + return EPERM; + } +#endif + param.runTimeUs = schedParam->runTimeUs; + param.deadlineUs = schedParam->deadlineUs; + param.periodUs = schedParam->periodUs; + } + + needSched = taskCB->ops->schedParamModify(taskCB, ¶m); + SCHEDULER_UNLOCK(intSave); + + LOS_MpSchedule(OS_MP_CPU_ALL); + if (needSched && OS_SCHEDULER_ACTIVE) { + LOS_Schedule(); + } + + return LOS_OK; +} + +void SysSchedYield(int type) +{ + (void)type; + + (void)LOS_TaskYield(); + return; +} + +int SysSchedGetScheduler(int id, int flag) +{ + unsigned int intSave; + SchedParam param = { 0 }; + int policy; + int ret; + + if (flag < 0) { + if (OS_TID_CHECK_INVALID(id)) { + return -EINVAL; + } + + LosTaskCB *taskCB = OS_TCB_FROM_TID(id); + SCHEDULER_LOCK(intSave); + ret = OsUserTaskOperatePermissionsCheck(taskCB); + if (ret != LOS_OK) { + SCHEDULER_UNLOCK(intSave); + return -ret; + } + + taskCB->ops->schedParamGet(taskCB, ¶m); + SCHEDULER_UNLOCK(intSave); + return (int)param.policy; + } + + if (id == 0) { + id = (int)LOS_GetCurrProcessID(); + } + + ret = LOS_GetProcessScheduler(id, &policy, NULL); + if (ret < 0) { + return ret; + } + + return policy; +} + +int SysSchedSetScheduler(int id, int policy, const LosSchedParam *userParam, int flag) +{ + int ret; + LosSchedParam param; + + if (LOS_ArchCopyFromUser(¶m, userParam, sizeof(LosSchedParam)) != 0) { + return -EFAULT; + } + + if (flag < 0) { + return -OsUserTaskSchedulerSet(id, policy, ¶m, true); + } + + if (policy == LOS_SCHED_RR) { +#ifdef LOSCFG_KERNEL_PLIMITS + if (param.priority < OsPidLimitGetPriorityLimit()) { + return -EINVAL; + } +#else + if (param.priority < OS_USER_PROCESS_PRIORITY_HIGHEST) { + return -EINVAL; + } +#endif + } + + if (id == 0) { + id = (int)LOS_GetCurrProcessID(); + } + + ret = OsPermissionToCheck(id, LOS_GetCurrProcessID()); + if (ret < 0) { + return ret; + } + + return OsSetProcessScheduler(LOS_PRIO_PROCESS, id, policy, ¶m); +} + +int SysSchedGetParam(int id, LosSchedParam *userParam, int flag) +{ + LosSchedParam schedParam = {0}; + SchedParam param = { 0 }; + unsigned int intSave; + int ret; + + if (flag < 0) { + if (OS_TID_CHECK_INVALID(id)) { + return -EINVAL; + } + + LosTaskCB *taskCB = OS_TCB_FROM_TID(id); + SCHEDULER_LOCK(intSave); + ret = OsUserTaskOperatePermissionsCheck(taskCB); + if (ret != LOS_OK) { + SCHEDULER_UNLOCK(intSave); + return -ret; + } + + taskCB->ops->schedParamGet(taskCB, ¶m); + SCHEDULER_UNLOCK(intSave); + if (param.policy == LOS_SCHED_DEADLINE) { + schedParam.runTimeUs = param.runTimeUs; + schedParam.deadlineUs = param.deadlineUs; + schedParam.periodUs = param.periodUs; + } else { + schedParam.priority = param.priority; + } + } else { + if (id == 0) { + id = (int)LOS_GetCurrProcessID(); + } + + if (OS_PID_CHECK_INVALID(id)) { + return -EINVAL; + } + + ret = LOS_GetProcessScheduler(id, NULL, &schedParam); + if (ret < 0) { + return ret; + } + } + + if (LOS_ArchCopyToUser(userParam, &schedParam, sizeof(LosSchedParam))) { + return -EFAULT; + } + return 0; +} + +int SysSetProcessPriority(int which, int who, int prio) +{ + int ret; + + if (which != LOS_PRIO_PROCESS) { + return -EINVAL; + } + + if (who == 0) { + who = (int)LOS_GetCurrProcessID(); + } + +#ifdef LOSCFG_KERNEL_PLIMITS + if (prio < OsPidLimitGetPriorityLimit()) { + return -EINVAL; + } +#else + if (prio < OS_USER_PROCESS_PRIORITY_HIGHEST) { + return -EINVAL; + } +#endif + + ret = OsPermissionToCheck(who, LOS_GetCurrProcessID()); + if (ret < 0) { + return ret; + } + + return LOS_SetProcessPriority(who, prio); +} + +int SysSchedSetParam(int id, const LosSchedParam *userParam, int flag) +{ + int ret, policy; + LosSchedParam param; + + if (flag < 0) { + if (LOS_ArchCopyFromUser(¶m, userParam, sizeof(LosSchedParam)) != 0) { + return -EFAULT; + } + return -OsUserTaskSchedulerSet(id, LOS_SCHED_RR, ¶m, false); + } + + if (id == 0) { + id = (int)LOS_GetCurrProcessID(); + } + + ret = LOS_GetProcessScheduler(id, &policy, NULL); + if (ret < 0) { + return ret; + } + + return SysSchedSetScheduler(id, policy, userParam, flag); +} + +int SysGetProcessPriority(int which, int who) +{ + if (who == 0) { + who = (int)LOS_GetCurrProcessID(); + } + + return OsGetProcessPriority(which, who); +} + +int SysSchedGetPriorityMin(int policy) +{ + if (policy != LOS_SCHED_RR) { + return -EINVAL; + } + + return OS_USER_PROCESS_PRIORITY_HIGHEST; +} + +int SysSchedGetPriorityMax(int policy) +{ + if (policy != LOS_SCHED_RR) { + return -EINVAL; + } + + return OS_USER_PROCESS_PRIORITY_LOWEST; +} + +int SysSchedRRGetInterval(int pid, struct timespec *tp) +{ + unsigned int intSave; + int ret; + SchedParam param = { 0 }; + time_t timeSlice = 0; + struct timespec tv = { 0 }; + LosTaskCB *taskCB = NULL; + LosProcessCB *processCB = NULL; + + if (tp == NULL) { + return -EINVAL; + } + + if (OS_PID_CHECK_INVALID(pid)) { + return -EINVAL; + } + + if (pid == 0) { + processCB = OsCurrProcessGet(); + } else { + processCB = OS_PCB_FROM_PID(pid); + } + + SCHEDULER_LOCK(intSave); + /* if can not find process by pid return ESRCH */ + if (OsProcessIsInactive(processCB)) { + SCHEDULER_UNLOCK(intSave); + return -ESRCH; + } + + LOS_DL_LIST_FOR_EACH_ENTRY(taskCB, &processCB->threadSiblingList, LosTaskCB, threadList) { + if (!OsTaskIsInactive(taskCB)) { + taskCB->ops->schedParamGet(taskCB, ¶m); + if (param.policy == LOS_SCHED_RR) { + timeSlice += param.timeSlice; + } + } + } + + SCHEDULER_UNLOCK(intSave); + + timeSlice = timeSlice * OS_NS_PER_CYCLE; + tv.tv_sec = timeSlice / OS_SYS_NS_PER_SECOND; + tv.tv_nsec = timeSlice % OS_SYS_NS_PER_SECOND; + ret = LOS_ArchCopyToUser(tp, &tv, sizeof(struct timespec)); + if (ret != 0) { + return -EFAULT; + } + + return 0; +} + +int SysWait(int pid, USER int *status, int options, void *rusage) +{ + (void)rusage; + + return LOS_Wait(pid, status, (unsigned int)options, NULL); +} + +int SysWaitid(idtype_t type, int pid, USER siginfo_t *info, int options, void *rusage) +{ + (void)rusage; + int ret; + int truepid = 0; + + switch (type) { + case P_ALL: + /* Wait for any child; id is ignored. */ + truepid = -1; + break; + case P_PID: + /* Wait for the child whose process ID matches id */ + if (pid <= 0) { + return -EINVAL; + } + truepid = pid; + break; + case P_PGID: + /* Wait for any child whose process group ID matches id */ + if (pid <= 1) { + return -EINVAL; + } + truepid = -pid; + break; + default: + return -EINVAL; + } + + ret = LOS_Waitid(truepid, info, (unsigned int)options, NULL); + if (ret > 0) { + ret = 0; + } + return ret; +} + +int SysFork(void) +{ + return OsClone(0, 0, 0); +} + +int SysVfork(void) +{ + return OsClone(CLONE_VFORK, 0, 0); +} + +int SysClone(int flags, void *stack, int *parentTid, unsigned long tls, int *childTid) +{ + (void)parentTid; + (void)tls; + (void)childTid; + + return OsClone((UINT32)flags, (UINTPTR)stack, 0); +} + +int SysUnshare(int flags) +{ +#ifdef LOSCFG_KERNEL_CONTAINER + return OsUnshare(flags); +#else + return -ENOSYS; +#endif +} + +int SysSetns(int fd, int type) +{ +#ifdef LOSCFG_KERNEL_CONTAINER + return OsSetNs(fd, type); +#else + return -ENOSYS; +#endif +} + +unsigned int SysGetPPID(void) +{ +#ifdef LOSCFG_PID_CONTAINER + if (OsCurrProcessGet()->processID == OS_USER_ROOT_PROCESS_ID) { + return 0; + } +#endif + return OsCurrProcessGet()->parentProcess->processID; +} + +unsigned int SysGetPID(void) +{ + return LOS_GetCurrProcessID(); +} + +int SysSetProcessGroupID(unsigned int pid, unsigned int gid) +{ + int ret; + + if (pid == 0) { + pid = LOS_GetCurrProcessID(); + } + + if (gid == 0) { + gid = pid; + } + + ret = OsPermissionToCheck(pid, gid); + if (ret < 0) { + return ret; + } + + return OsSetProcessGroupID(pid, gid); +} + +int SysGetProcessGroupID(unsigned int pid) +{ + if (pid == 0) { + pid = LOS_GetCurrProcessID(); + } + + return LOS_GetProcessGroupID(pid); +} + +int SysGetCurrProcessGroupID(void) +{ + return LOS_GetCurrProcessGroupID(); +} + +int SysGetUserID(void) +{ + return LOS_GetUserID(); +} + +int SysGetEffUserID(void) +{ +#ifdef LOSCFG_SECURITY_CAPABILITY + UINT32 intSave; + int euid; + + SCHEDULER_LOCK(intSave); +#ifdef LOSCFG_USER_CONTAINER + euid = OsFromKuidMunged(OsCurrentUserContainer(), CurrentCredentials()->euid); +#else + euid = (int)OsCurrUserGet()->effUserID; +#endif + SCHEDULER_UNLOCK(intSave); + return euid; +#else + return 0; +#endif +} + +int SysGetEffGID(void) +{ +#ifdef LOSCFG_SECURITY_CAPABILITY + UINT32 intSave; + int egid; + + SCHEDULER_LOCK(intSave); +#ifdef LOSCFG_USER_CONTAINER + egid = OsFromKuidMunged(OsCurrentUserContainer(), CurrentCredentials()->egid); +#else + egid = (int)OsCurrUserGet()->effGid; +#endif + SCHEDULER_UNLOCK(intSave); + return egid; +#else + return 0; +#endif +} + +int SysGetRealEffSaveUserID(int *ruid, int *euid, int *suid) +{ + int ret; + int realUserID, effUserID, saveUserID; +#ifdef LOSCFG_SECURITY_CAPABILITY + unsigned int intSave; + + SCHEDULER_LOCK(intSave); +#ifdef LOSCFG_USER_CONTAINER + realUserID = OsFromKuidMunged(OsCurrentUserContainer(), CurrentCredentials()->uid); + effUserID = OsFromKuidMunged(OsCurrentUserContainer(), CurrentCredentials()->euid); + saveUserID = OsFromKuidMunged(OsCurrentUserContainer(), CurrentCredentials()->euid); +#else + realUserID = OsCurrUserGet()->userID; + effUserID = OsCurrUserGet()->effUserID; + saveUserID = OsCurrUserGet()->effUserID; +#endif + SCHEDULER_UNLOCK(intSave); +#else + realUserID = 0; + effUserID = 0; + saveUserID = 0; +#endif + + ret = LOS_ArchCopyToUser(ruid, &realUserID, sizeof(int)); + if (ret != 0) { + return -EFAULT; + } + + ret = LOS_ArchCopyToUser(euid, &effUserID, sizeof(int)); + if (ret != 0) { + return -EFAULT; + } + + ret = LOS_ArchCopyToUser(suid, &saveUserID, sizeof(int)); + if (ret != 0) { + return -EFAULT; + } + + return 0; +} + +#ifdef LOSCFG_USER_CONTAINER +long SysSetUserID(int uid) +{ +#ifdef LOSCFG_SECURITY_CAPABILITY + UserContainer *userContainer = CurrentCredentials()->userContainer; + int retval = -EPERM; + unsigned int intSave; + + if (uid < 0) { + return -EINVAL; + } + + UINT32 kuid = OsMakeKuid(userContainer, uid); + if (kuid == (UINT32)-1) { + return -EINVAL; + } + + Credentials *newCredentials = PrepareCredential(OsCurrProcessGet()); + if (newCredentials == NULL) { + return -ENOMEM; + } + + Credentials *oldCredentials = CurrentCredentials(); + + SCHEDULER_LOCK(intSave); + User *user = OsCurrUserGet(); + if (IsCapPermit(CAP_SETUID)) { + newCredentials->uid = kuid; + if (kuid != oldCredentials->uid) { + user->userID = kuid; + user->effUserID = kuid; + } + retval = LOS_OK; + } else if (kuid != oldCredentials->uid) { + goto ERROR; + } + newCredentials->euid = kuid; + + retval = CommitCredentials(newCredentials); + SCHEDULER_UNLOCK(intSave); + return retval; + +ERROR: + FreeCredential(newCredentials); + SCHEDULER_UNLOCK(intSave); + return retval; +#else + if (uid != 0) { + return -EPERM; + } + return 0; +#endif +} + +#else + +int SysSetUserID(int uid) +{ +#ifdef LOSCFG_SECURITY_CAPABILITY + int ret = -EPERM; + unsigned int intSave; + + if (uid < 0) { + return -EINVAL; + } + + SCHEDULER_LOCK(intSave); + User *user = OsCurrUserGet(); + if (IsCapPermit(CAP_SETUID)) { + user->userID = uid; + user->effUserID = uid; + /* add process to a user */ + } else if (user->userID != uid) { + goto EXIT; + } + + ret = LOS_OK; + /* add process to a user */ +EXIT: + SCHEDULER_UNLOCK(intSave); + return ret; +#else + if (uid != 0) { + return -EPERM; + } + + return 0; +#endif +} +#endif + +#ifdef LOSCFG_SECURITY_CAPABILITY +static int SetRealEffSaveUserIDCheck(int ruid, int euid, int suid) +{ + if ((ruid < 0) && (ruid != -1)) { + return -EINVAL; + } + + if ((euid < 0) && (euid != -1)) { + return -EINVAL; + } + + if ((suid < 0) && (suid != -1)) { + return -EINVAL; + } + + return 0; +} +#endif + +int SysSetRealEffSaveUserID(int ruid, int euid, int suid) +{ +#ifdef LOSCFG_SECURITY_CAPABILITY + int ret; + + if ((ruid == -1) && (euid == -1) && (suid == -1)) { + return 0; + } + + ret = SetRealEffSaveUserIDCheck(ruid, euid, suid); + if (ret != 0) { + return ret; + } + + if (ruid >= 0) { + if (((euid != -1) && (euid != ruid)) || ((suid != -1) && (suid != ruid))) { + return -EPERM; + } + return SysSetUserID(ruid); + } else if (euid >= 0) { + if ((suid != -1) && (suid != euid)) { + return -EPERM; + } + return SysSetUserID(euid); + } else { + return SysSetUserID(suid); + } +#else + if ((ruid != 0) || (euid != 0) || (suid != 0)) { + return -EPERM; + } + return 0; +#endif +} + +int SysSetRealEffUserID(int ruid, int euid) +{ +#ifdef LOSCFG_SECURITY_CAPABILITY + return SysSetRealEffSaveUserID(ruid, euid, -1); +#else + if ((ruid != 0) || (euid != 0)) { + return -EPERM; + } + return 0; +#endif +} + +#ifdef LOSCFG_USER_CONTAINER +int SysSetGroupID(int gid) +{ +#ifdef LOSCFG_SECURITY_CAPABILITY + UserContainer *userContainer = CurrentCredentials()->userContainer; + int retval = -EPERM; + unsigned int oldGid; + unsigned int intSave; + int count; + + if (gid < 0) { + return -EINVAL; + } + + unsigned int kgid = OsMakeKgid(userContainer, gid); + if (kgid == (UINT32)-1) { + return -EINVAL; + } + + Credentials *newCredentials = PrepareCredential(OsCurrProcessGet()); + if (newCredentials == NULL) { + return -ENOMEM; + } + + SCHEDULER_LOCK(intSave); + User *user = OsCurrUserGet(); + if (IsCapPermit(CAP_SETGID)) { + newCredentials->gid = kgid; + newCredentials->egid = kgid; + oldGid = user->gid; + user->gid = kgid; + user->effGid = kgid; + for (count = 0; count < user->groupNumber; count++) { + if (user->groups[count] == oldGid) { + user->groups[count] = kgid; + retval = LOS_OK; + break; + } + } + } else if (user->gid != kgid) { + goto ERROR; + } + + retval = CommitCredentials(newCredentials); + SCHEDULER_UNLOCK(intSave); + return retval; + +ERROR: + FreeCredential(newCredentials); + SCHEDULER_UNLOCK(intSave); + return retval; + +#else + if (gid != 0) { + return -EPERM; + } + return 0; +#endif +} +#else +int SysSetGroupID(int gid) +{ +#ifdef LOSCFG_SECURITY_CAPABILITY + int ret = -EPERM; + unsigned int intSave; + unsigned int count; + unsigned int oldGid; + User *user = NULL; + + if (gid < 0) { + return -EINVAL; + } + + SCHEDULER_LOCK(intSave); + user = OsCurrUserGet(); + if (IsCapPermit(CAP_SETGID)) { + oldGid = user->gid; + user->gid = gid; + user->effGid = gid; + for (count = 0; count < user->groupNumber; count++) { + if (user->groups[count] == oldGid) { + user->groups[count] = gid; + ret = LOS_OK; + goto EXIT; + } + } + } else if (user->gid != gid) { + goto EXIT; + } + + ret = LOS_OK; + /* add process to a user */ +EXIT: + SCHEDULER_UNLOCK(intSave); + return ret; + +#else + if (gid != 0) { + return -EPERM; + } + + return 0; +#endif +} +#endif + +int SysGetRealEffSaveGroupID(int *rgid, int *egid, int *sgid) +{ + int ret; + int realGroupID, effGroupID, saveGroupID; +#ifdef LOSCFG_SECURITY_CAPABILITY + unsigned int intSave; + + SCHEDULER_LOCK(intSave); +#ifdef LOSCFG_USER_CONTAINER + realGroupID = OsFromKuidMunged(OsCurrentUserContainer(), CurrentCredentials()->gid); + effGroupID = OsFromKuidMunged(OsCurrentUserContainer(), CurrentCredentials()->egid); + saveGroupID = OsFromKuidMunged(OsCurrentUserContainer(), CurrentCredentials()->egid); +#else + realGroupID = OsCurrUserGet()->gid; + effGroupID = OsCurrUserGet()->effGid; + saveGroupID = OsCurrUserGet()->effGid; +#endif + SCHEDULER_UNLOCK(intSave); +#else + realGroupID = 0; + effGroupID = 0; + saveGroupID = 0; +#endif + + ret = LOS_ArchCopyToUser(rgid, &realGroupID, sizeof(int)); + if (ret != 0) { + return -EFAULT; + } + + ret = LOS_ArchCopyToUser(egid, &effGroupID, sizeof(int)); + if (ret != 0) { + return -EFAULT; + } + + ret = LOS_ArchCopyToUser(sgid, &saveGroupID, sizeof(int)); + if (ret != 0) { + return -EFAULT; + } + + return 0; +} + +#ifdef LOSCFG_SECURITY_CAPABILITY +static int SetRealEffSaveGroupIDCheck(int rgid, int egid, int sgid) +{ + if ((rgid < 0) && (rgid != -1)) { + return -EINVAL; + } + + if ((egid < 0) && (egid != -1)) { + return -EINVAL; + } + + if ((sgid < 0) && (sgid != -1)) { + return -EINVAL; + } + + return 0; +} +#endif + +int SysSetRealEffSaveGroupID(int rgid, int egid, int sgid) +{ +#ifdef LOSCFG_SECURITY_CAPABILITY + int ret; + + if ((rgid == -1) && (egid == -1) && (sgid == -1)) { + return 0; + } + + ret = SetRealEffSaveGroupIDCheck(rgid, egid, sgid); + if (ret != 0) { + return ret; + } + + if (rgid >= 0) { + if (((egid != -1) && (egid != rgid)) || ((sgid != -1) && (sgid != rgid))) { + return -EPERM; + } + return SysSetGroupID(rgid); + } else if (egid >= 0) { + if ((sgid != -1) && (sgid != egid)) { + return -EPERM; + } + return SysSetGroupID(egid); + } else { + return SysSetGroupID(sgid); + } + +#else + if ((rgid != 0) || (egid != 0) || (sgid != 0)) { + return -EPERM; + } + return 0; +#endif +} + +int SysSetRealEffGroupID(int rgid, int egid) +{ +#ifdef LOSCFG_SECURITY_CAPABILITY + return SysSetRealEffSaveGroupID(rgid, egid, -1); +#else + if ((rgid != 0) || (egid != 0)) { + return -EPERM; + } + return 0; +#endif +} + +int SysGetGroupID(void) +{ + return LOS_GetGroupID(); +} + +#ifdef LOSCFG_SECURITY_CAPABILITY +static int SetGroups(int listSize, const int *safeList, int size) +{ + User *oldUser = NULL; + unsigned int intSave; + + User *newUser = LOS_MemAlloc(m_aucSysMem1, sizeof(User) + listSize * sizeof(int)); + if (newUser == NULL) { + return -ENOMEM; + } + + SCHEDULER_LOCK(intSave); + oldUser = OsCurrUserGet(); + (VOID)memcpy_s(newUser, sizeof(User), oldUser, sizeof(User)); + if (safeList != NULL) { + (VOID)memcpy_s(newUser->groups, size * sizeof(int), safeList, size * sizeof(int)); + } + if (listSize == size) { + newUser->groups[listSize] = oldUser->gid; + } + + newUser->groupNumber = listSize + 1; + OsCurrProcessGet()->user = newUser; + SCHEDULER_UNLOCK(intSave); + + (void)LOS_MemFree(m_aucSysMem1, oldUser); + return 0; +} + +static int GetGroups(int size, int list[]) +{ + unsigned int intSave; + int groupCount; + int ret; + int *safeList = NULL; + unsigned int listSize; + + SCHEDULER_LOCK(intSave); + groupCount = OsCurrUserGet()->groupNumber; + SCHEDULER_UNLOCK(intSave); + + listSize = groupCount * sizeof(int); + if (size == 0) { + return groupCount; + } else if (list == NULL) { + return -EFAULT; + } else if (size < groupCount) { + return -EINVAL; + } + + safeList = LOS_MemAlloc(m_aucSysMem1, listSize); + if (safeList == NULL) { + return -ENOMEM; + } + + SCHEDULER_LOCK(intSave); + (void)memcpy_s(safeList, listSize, &OsCurrProcessGet()->user->groups[0], listSize); + SCHEDULER_UNLOCK(intSave); + + ret = LOS_ArchCopyToUser(list, safeList, listSize); + if (ret != 0) { + groupCount = -EFAULT; + } + + (void)LOS_MemFree(m_aucSysMem1, safeList); + return groupCount; +} +#endif + +int SysGetGroups(int size, int list[]) +{ +#ifdef LOSCFG_SECURITY_CAPABILITY + return GetGroups(size, list); +#else + int group = 0; + int groupCount = 1; + int ret; + + if (size == 0) { + return groupCount; + } else if (list == NULL) { + return -EFAULT; + } else if (size < groupCount) { + return -EINVAL; + } + + ret = LOS_ArchCopyToUser(list, &group, sizeof(int)); + if (ret != 0) { + return -EFAULT; + } + + return groupCount; +#endif +} + +int SysSetGroups(int size, const int list[]) +{ +#ifdef LOSCFG_SECURITY_CAPABILITY + int ret; + int gid; + int listSize = size; + unsigned int count; + int *safeList = NULL; +#endif + + if ((size != 0) && (list == NULL)) { + return -EFAULT; + } + + if ((size < 0) || (size > OS_GROUPS_NUMBER_MAX)) { + return -EINVAL; + } + +#ifdef LOSCFG_SECURITY_CAPABILITY + if (!IsCapPermit(CAP_SETGID)) { + return -EPERM; + } + + if (size != 0) { + safeList = LOS_MemAlloc(m_aucSysMem1, size * sizeof(int)); + if (safeList == NULL) { + return -ENOMEM; + } + + ret = LOS_ArchCopyFromUser(safeList, list, size * sizeof(int)); + if (ret != 0) { + ret = -EFAULT; + goto EXIT; + } + gid = OsCurrUserGet()->gid; + for (count = 0; count < size; count++) { + if (safeList[count] == gid) { + listSize = size - 1; + } else if (safeList[count] < 0) { + ret = -EINVAL; + goto EXIT; + } + } + } + + ret = SetGroups(listSize, safeList, size); +EXIT: + if (safeList != NULL) { + (void)LOS_MemFree(m_aucSysMem1, safeList); + } + + return ret; +#else + return 0; +#endif +} + +unsigned int SysCreateUserThread(const TSK_ENTRY_FUNC func, const UserTaskParam *userParam, bool joinable) +{ + TSK_INIT_PARAM_S param = { 0 }; + int ret; + + ret = LOS_ArchCopyFromUser(&(param.userParam), userParam, sizeof(UserTaskParam)); + if (ret != 0) { + return OS_INVALID_VALUE; + } + + param.pfnTaskEntry = func; + if (joinable == TRUE) { + param.uwResved = LOS_TASK_ATTR_JOINABLE; + } else { + param.uwResved = LOS_TASK_STATUS_DETACHED; + } + + return OsCreateUserTask(OS_INVALID_VALUE, ¶m); +} + +int SysSetThreadArea(const char *area) +{ + unsigned int intSave; + int ret = LOS_OK; + + if (!LOS_IsUserAddress((unsigned long)(uintptr_t)area)) { + return EINVAL; + } + + LosTaskCB *taskCB = OsCurrTaskGet(); + SCHEDULER_LOCK(intSave); + LosProcessCB *processCB = OS_PCB_FROM_TCB(taskCB); + if (processCB->processMode != OS_USER_MODE) { + ret = EPERM; + goto OUT; + } + + taskCB->userArea = (unsigned long)(uintptr_t)area; +OUT: + SCHEDULER_UNLOCK(intSave); + return ret; +} + +char *SysGetThreadArea(void) +{ + return (char *)(OsCurrTaskGet()->userArea); +} + +int SysUserThreadSetDetach(unsigned int taskID) +{ + unsigned int intSave; + int ret; + + if (OS_TID_CHECK_INVALID(taskID)) { + return EINVAL; + } + + LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID); + SCHEDULER_LOCK(intSave); + ret = OsUserTaskOperatePermissionsCheck(taskCB); + if (ret != LOS_OK) { + goto EXIT; + } + + ret = (int)OsTaskSetDetachUnsafe(taskCB); + +EXIT: + SCHEDULER_UNLOCK(intSave); + return ret; +} + +int SysUserThreadDetach(unsigned int taskID) +{ + unsigned int intSave; + int ret; + + if (OS_TID_CHECK_INVALID(taskID)) { + return EINVAL; + } + + SCHEDULER_LOCK(intSave); + ret = OsUserTaskOperatePermissionsCheck(OS_TCB_FROM_TID(taskID)); + SCHEDULER_UNLOCK(intSave); + if (ret != LOS_OK) { + return ret; + } + + if (LOS_TaskDelete(taskID) != LOS_OK) { + return ESRCH; + } + + return LOS_OK; +} + +int SysThreadJoin(unsigned int taskID) +{ + unsigned int intSave; + int ret; + + if (OS_TID_CHECK_INVALID(taskID)) { + return EINVAL; + } + + LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID); + SCHEDULER_LOCK(intSave); + ret = OsUserTaskOperatePermissionsCheck(taskCB); + if (ret != LOS_OK) { + goto EXIT; + } + + ret = (int)OsTaskJoinPendUnsafe(OS_TCB_FROM_TID(taskID)); + +EXIT: + SCHEDULER_UNLOCK(intSave); + return ret; +} + +void SysUserExitGroup(int status) +{ + (void)status; + OsProcessThreadGroupDestroy(); +} + +void SysThreadExit(int status) +{ + OsRunningTaskToExit(OsCurrTaskGet(), (unsigned int)status); +} + +int SysFutex(const unsigned int *uAddr, unsigned int flags, int val, + unsigned int absTime, const unsigned int *newUserAddr) +{ + if ((flags & FUTEX_MASK) == FUTEX_REQUEUE) { + return -OsFutexRequeue(uAddr, flags, val, absTime, newUserAddr); + } + + if ((flags & FUTEX_MASK) == FUTEX_WAKE) { + return -OsFutexWake(uAddr, flags, val); + } + + return -OsFutexWait(uAddr, flags, val, absTime); +} + +unsigned int SysGetTid(void) +{ + return OsCurrTaskGet()->taskID; +} + +/* If flag >= 0, the process mode is used. If flag < 0, the thread mode is used. */ +static int SchedAffinityParameterPreprocess(int id, int flag, unsigned int *taskID, unsigned int *processID) +{ + if (flag >= 0) { + if (OS_PID_CHECK_INVALID(id)) { + return -ESRCH; + } + LosProcessCB *ProcessCB = OS_PCB_FROM_PID((UINT32)id); + if (ProcessCB->threadGroup == NULL) { + return -ESRCH; + } + *taskID = (id == 0) ? (OsCurrTaskGet()->taskID) : (ProcessCB->threadGroup->taskID); + *processID = (id == 0) ? (OS_PCB_FROM_TID(*taskID)->processID) : id; + } else { + if (OS_TID_CHECK_INVALID(id)) { + return -ESRCH; + } + *taskID = id; + *processID = OS_INVALID_VALUE; + } + return LOS_OK; +} + +/* If flag >= 0, the process mode is used. If flag < 0, the thread mode is used. */ +int SysSchedGetAffinity(int id, unsigned int *cpuset, int flag) +{ + int ret; + unsigned int processID; + unsigned int taskID; + unsigned int intSave; + unsigned int cpuAffiMask; + + ret = SchedAffinityParameterPreprocess(id, flag, &taskID, &processID); + if (ret != LOS_OK) { + return ret; + } + + SCHEDULER_LOCK(intSave); + if (flag >= 0) { + if (OsProcessIsInactive(OS_PCB_FROM_PID(processID))) { + SCHEDULER_UNLOCK(intSave); + return -ESRCH; + } + } else { + ret = OsUserTaskOperatePermissionsCheck(OS_TCB_FROM_TID(taskID)); + if (ret != LOS_OK) { + SCHEDULER_UNLOCK(intSave); + if (ret == EINVAL) { + return -ESRCH; + } + return -ret; + } + } + +#ifdef LOSCFG_KERNEL_SMP + cpuAffiMask = (unsigned int)OS_TCB_FROM_TID(taskID)->cpuAffiMask; +#else + cpuAffiMask = 1; +#endif /* LOSCFG_KERNEL_SMP */ + + SCHEDULER_UNLOCK(intSave); + ret = LOS_ArchCopyToUser(cpuset, &cpuAffiMask, sizeof(unsigned int)); + if (ret != LOS_OK) { + return -EFAULT; + } + + return LOS_OK; +} + +/* If flag >= 0, the process mode is used. If flag < 0, the thread mode is used. */ +int SysSchedSetAffinity(int id, const unsigned short cpuset, int flag) +{ + int ret; + unsigned int processID; + unsigned int taskID; + unsigned int intSave; + unsigned short currCpuMask; + bool needSched = FALSE; + + if (cpuset > LOSCFG_KERNEL_CPU_MASK) { + return -EINVAL; + } + + ret = SchedAffinityParameterPreprocess(id, flag, &taskID, &processID); + if (ret != LOS_OK) { + return ret; + } + + if (flag >= 0) { + ret = OsPermissionToCheck(processID, LOS_GetCurrProcessID()); + if (ret != LOS_OK) { + return ret; + } + SCHEDULER_LOCK(intSave); + if (OsProcessIsInactive(OS_PCB_FROM_PID(processID))) { + SCHEDULER_UNLOCK(intSave); + return -ESRCH; + } + } else { + SCHEDULER_LOCK(intSave); + ret = OsUserTaskOperatePermissionsCheck(OS_TCB_FROM_TID(taskID)); + if (ret != LOS_OK) { + SCHEDULER_UNLOCK(intSave); + if (ret == EINVAL) { + return -ESRCH; + } + return -ret; + } + } + + needSched = OsTaskCpuAffiSetUnsafe(taskID, cpuset, &currCpuMask); + SCHEDULER_UNLOCK(intSave); + if (needSched && OS_SCHEDULER_ACTIVE) { + LOS_MpSchedule(currCpuMask); + LOS_Schedule(); + } + + return LOS_OK; +} + diff --git a/src/kernel_liteos_a/syscall/syscall_lookup.h b/src/kernel_liteos_a/syscall/syscall_lookup.h new file mode 100644 index 00000000..c5fcdb30 --- /dev/null +++ b/src/kernel_liteos_a/syscall/syscall_lookup.h @@ -0,0 +1,280 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* SYSCALL_HAND_DEF must be defined before including this file. */ +/* SYSCALL_HAND_DEF(id, fun, rtype, narg); note if we have 64bit arg, narg should be ARG_NUM_7 */ +#ifdef LOSCFG_FS_VFS +SYSCALL_HAND_DEF(__NR_read, SysRead, ssize_t, ARG_NUM_3) +SYSCALL_HAND_DEF(__NR_write, SysWrite, ssize_t, ARG_NUM_3) +SYSCALL_HAND_DEF(__NR_open, SysOpen, int, ARG_NUM_7) +SYSCALL_HAND_DEF(__NR_close, SysClose, int, ARG_NUM_1) +SYSCALL_HAND_DEF(__NR_creat, SysCreat, int, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_link, SysLink, int, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_readlink, SysReadlink, ssize_t, ARG_NUM_3) +SYSCALL_HAND_DEF(__NR_symlink, SysSymlink, int, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_unlink, SysUnlink, int, ARG_NUM_1) + +#ifdef LOSCFG_KERNEL_DYNLOAD +SYSCALL_HAND_DEF(__NR_execve, SysExecve, int, ARG_NUM_3) +#endif + +SYSCALL_HAND_DEF(__NR_sysinfo, SysInfo, int, ARG_NUM_1) +SYSCALL_HAND_DEF(__NR_fchdir, SysFchdir, int, ARG_NUM_1) +SYSCALL_HAND_DEF(__NR_chdir, SysChdir, int, ARG_NUM_1) +SYSCALL_HAND_DEF(__NR_utimensat, SysUtimensat, int, ARG_NUM_4) +SYSCALL_HAND_DEF(__NR_fchmodat, SysFchmodat, int, ARG_NUM_4) +SYSCALL_HAND_DEF(__NR_fchmod, SysFchmod, int, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_utimensat, SysUtimensat, int, ARG_NUM_4) +SYSCALL_HAND_DEF(__NR_chmod, SysChmod, int, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_lseek, SysLseek, off_t, ARG_NUM_7) /* current only support 32bit max 4G file */ +SYSCALL_HAND_DEF(__NR_mount, SysMount, int, ARG_NUM_5) +SYSCALL_HAND_DEF(__NR_umount, SysUmount, int, ARG_NUM_1) +SYSCALL_HAND_DEF(__NR_access, SysAccess, int, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_faccessat, SysFaccessat, int, ARG_NUM_4) +SYSCALL_HAND_DEF(__NR_sync, SysSync, void, ARG_NUM_0) +SYSCALL_HAND_DEF(__NR_rename, SysRename, int, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_mkdir, SysMkdir, int, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_rmdir, SysRmdir, int, ARG_NUM_1) +SYSCALL_HAND_DEF(__NR_dup, SysDup, int, ARG_NUM_1) +#ifdef LOSCFG_KERNEL_PIPE +SYSCALL_HAND_DEF(__NR_pipe, SysPipe, int, ARG_NUM_1) +#endif +SYSCALL_HAND_DEF(__NR_umount2, SysUmount2, int, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_ioctl, SysIoctl, int, ARG_NUM_3) +SYSCALL_HAND_DEF(__NR_fcntl, SysFcntl, int, ARG_NUM_3) +SYSCALL_HAND_DEF(__NR_dup2, SysDup2, int, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_truncate, SysTruncate, int, ARG_NUM_7) +SYSCALL_HAND_DEF(__NR_ftruncate, SysFtruncate, int, ARG_NUM_7) +SYSCALL_HAND_DEF(__NR_statfs, SysStatfs, int, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_fstatfs, SysFstatfs, int, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_fstatfs64, SysFstatfs64, int, ARG_NUM_3) +SYSCALL_HAND_DEF(__NR_stat, SysStat, int, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_lstat, SysLstat, int, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_fstat, SysFstat, int, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_fstatat64, SysFstatat64, int, ARG_NUM_4) +SYSCALL_HAND_DEF(__NR_fsync, SysFsync, int, ARG_NUM_1) +SYSCALL_HAND_DEF(__NR__llseek, SysLseek64, off64_t, ARG_NUM_5) /* current only support 32bit max 4G file */ +SYSCALL_HAND_DEF(__NR__newselect, SysSelect, int, ARG_NUM_5) +SYSCALL_HAND_DEF(__NR_pselect6, SysPselect6, int, ARG_NUM_6) +SYSCALL_HAND_DEF(__NR_readv, SysReadv, ssize_t, ARG_NUM_3) +SYSCALL_HAND_DEF(__NR_writev, SysWritev, ssize_t, ARG_NUM_3) +SYSCALL_HAND_DEF(__NR_poll, SysPoll, int, ARG_NUM_3) +SYSCALL_HAND_DEF(__NR_ppoll, SysPpoll, int, ARG_NUM_5) +SYSCALL_HAND_DEF(__NR_prctl, SysPrctl, int, ARG_NUM_7) +SYSCALL_HAND_DEF(__NR_pread64, SysPread64, ssize_t, ARG_NUM_7) +SYSCALL_HAND_DEF(__NR_pwrite64, SysPwrite64, ssize_t, ARG_NUM_7) +SYSCALL_HAND_DEF(__NR_epoll_create, SysEpollCreate, int, ARG_NUM_1) +SYSCALL_HAND_DEF(__NR_epoll_create1, SysEpollCreate1, int, ARG_NUM_1) +SYSCALL_HAND_DEF(__NR_epoll_ctl, SysEpollCtl, int, ARG_NUM_4) +SYSCALL_HAND_DEF(__NR_epoll_wait, SysEpollWait, int, ARG_NUM_4) +SYSCALL_HAND_DEF(__NR_epoll_pwait, SysEpollPwait, int, ARG_NUM_5) +SYSCALL_HAND_DEF(__NR_getcwd, SysGetcwd, char *, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_sendfile, SysSendFile, ssize_t, ARG_NUM_4) +SYSCALL_HAND_DEF(__NR_truncate64, SysTruncate64, int, ARG_NUM_7) +SYSCALL_HAND_DEF(__NR_ftruncate64, SysFtruncate64, int, ARG_NUM_7) +SYSCALL_HAND_DEF(__NR_stat64, SysStat, int, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_lstat64, SysLstat, int, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_fstat64, SysFstat64, int, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_fcntl64, SysFcntl64, int, ARG_NUM_3) +SYSCALL_HAND_DEF(__NR_sendfile64, SysSendFile, ssize_t, ARG_NUM_4) +SYSCALL_HAND_DEF(__NR_preadv, SysPreadv, ssize_t, ARG_NUM_7) +SYSCALL_HAND_DEF(__NR_pwritev, SysPwritev, ssize_t, ARG_NUM_7) +SYSCALL_HAND_DEF(__NR_fallocate, SysFallocate64, int, ARG_NUM_7) +SYSCALL_HAND_DEF(__NR_getdents64, SysGetdents64, int, ARG_NUM_3) + +#ifdef LOSCFG_FS_FAT +SYSCALL_HAND_DEF(__NR_format, SysFormat, int, ARG_NUM_3) +#endif + +SYSCALL_HAND_DEF(__NR_linkat, SysLinkat, int, ARG_NUM_5) +SYSCALL_HAND_DEF(__NR_symlinkat, SysSymlinkat, int, ARG_NUM_3) +SYSCALL_HAND_DEF(__NR_readlinkat, SysReadlinkat, ssize_t, ARG_NUM_4) +SYSCALL_HAND_DEF(__NR_unlinkat, SysUnlinkat, int, ARG_NUM_3) +SYSCALL_HAND_DEF(__NR_renameat, SysRenameat, int, ARG_NUM_4) +SYSCALL_HAND_DEF(__NR_openat, SysOpenat, int, ARG_NUM_7) +SYSCALL_HAND_DEF(__NR_mkdirat, SysMkdirat, int, ARG_NUM_3) +SYSCALL_HAND_DEF(__NR_statfs64, SysStatfs64, int, ARG_NUM_3) +#ifdef LOSCFG_DEBUG_VERSION +SYSCALL_HAND_DEF(__NR_dumpmemory, LOS_DumpMemRegion, void, ARG_NUM_1) +#endif +#ifdef LOSCFG_KERNEL_PIPE +SYSCALL_HAND_DEF(__NR_mkfifo, SysMkFifo, int, ARG_NUM_2) +#endif +SYSCALL_HAND_DEF(__NR_mqclose, SysMqClose, int, ARG_NUM_1) +SYSCALL_HAND_DEF(__NR_realpath, SysRealpath, char *, ARG_NUM_2) + +#ifdef LOSCFG_SHELL +SYSCALL_HAND_DEF(__NR_shellexec, SysShellExec, UINT32, ARG_NUM_2) +#endif +#endif + +SYSCALL_HAND_DEF(__NR_exit, SysThreadExit, void, ARG_NUM_1) +SYSCALL_HAND_DEF(__NR_fork, SysFork, int, ARG_NUM_0) +SYSCALL_HAND_DEF(__NR_vfork, SysVfork, int, ARG_NUM_0) +SYSCALL_HAND_DEF(__NR_clone, SysClone, int, ARG_NUM_5) +SYSCALL_HAND_DEF(__NR_unshare, SysUnshare, int, ARG_NUM_1) +SYSCALL_HAND_DEF(__NR_setns, SysSetns, int, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_getpid, SysGetPID, unsigned int, ARG_NUM_0) +SYSCALL_HAND_DEF(__NR_pause, SysPause, int, ARG_NUM_0) + +SYSCALL_HAND_DEF(__NR_kill, SysKill, int, ARG_NUM_2) + +SYSCALL_HAND_DEF(__NR_reboot, SysReboot, int, ARG_NUM_3) +SYSCALL_HAND_DEF(__NR_times, SysTimes, clock_t, ARG_NUM_1) +SYSCALL_HAND_DEF(__NR_brk, SysBrk, void *, ARG_NUM_1) +SYSCALL_HAND_DEF(__NR_setgid, SysSetGroupID, int, ARG_NUM_1) +SYSCALL_HAND_DEF(__NR_getgid, SysGetGroupID, int, ARG_NUM_0) +SYSCALL_HAND_DEF(__NR_setpgid, SysSetProcessGroupID, int, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_getppid, SysGetPPID, unsigned int, ARG_NUM_0) +SYSCALL_HAND_DEF(__NR_getpgrp, SysGetProcessGroupID, int, ARG_NUM_1) +SYSCALL_HAND_DEF(__NR_munmap, SysMunmap, int, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_getpriority, SysGetProcessPriority, int, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_setpriority, SysSetProcessPriority, int, ARG_NUM_3) +SYSCALL_HAND_DEF(__NR_setitimer, SysSetiTimer, int, ARG_NUM_3) +SYSCALL_HAND_DEF(__NR_getitimer, SysGetiTimer, int, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_wait4, SysWait, int, ARG_NUM_4) +SYSCALL_HAND_DEF(__NR_waitid, SysWaitid, int, ARG_NUM_5) +SYSCALL_HAND_DEF(__NR_uname, SysUname, int, ARG_NUM_1) +#ifdef LOSCFG_UTS_CONTAINER +SYSCALL_HAND_DEF(__NR_sethostname, SysSetHostName, int, ARG_NUM_2) +#endif +SYSCALL_HAND_DEF(__NR_mprotect, SysMprotect, int, ARG_NUM_3) +SYSCALL_HAND_DEF(__NR_getpgid, SysGetProcessGroupID, int, ARG_NUM_1) +SYSCALL_HAND_DEF(__NR_sched_setparam, SysSchedSetParam, int, ARG_NUM_3) +SYSCALL_HAND_DEF(__NR_sched_getparam, SysSchedGetParam, int, ARG_NUM_3) +SYSCALL_HAND_DEF(__NR_sched_setscheduler, SysSchedSetScheduler, int, ARG_NUM_4) +SYSCALL_HAND_DEF(__NR_sched_getscheduler, SysSchedGetScheduler, int, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_sched_yield, SysSchedYield, void, ARG_NUM_1) +SYSCALL_HAND_DEF(__NR_sched_get_priority_max, SysSchedGetPriorityMax, int, ARG_NUM_1) +SYSCALL_HAND_DEF(__NR_sched_get_priority_min, SysSchedGetPriorityMin, int, ARG_NUM_1) +SYSCALL_HAND_DEF(__NR_sched_setaffinity, SysSchedSetAffinity, int, ARG_NUM_3) +SYSCALL_HAND_DEF(__NR_sched_getaffinity, SysSchedGetAffinity, int, ARG_NUM_3) +SYSCALL_HAND_DEF(__NR_sched_rr_get_interval, SysSchedRRGetInterval, int, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_nanosleep, SysNanoSleep, int, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_mremap, SysMremap, void *, ARG_NUM_5) +SYSCALL_HAND_DEF(__NR_umask, SysUmask, mode_t, ARG_NUM_1) + +SYSCALL_HAND_DEF(__NR_rt_sigaction, SysSigAction, int, ARG_NUM_4) +SYSCALL_HAND_DEF(__NR_rt_sigprocmask, SysSigprocMask, int, ARG_NUM_4) +SYSCALL_HAND_DEF(__NR_rt_sigpending, SysSigPending, int, ARG_NUM_1) +SYSCALL_HAND_DEF(__NR_rt_sigtimedwait, SysSigTimedWait, int, ARG_NUM_4) +SYSCALL_HAND_DEF(__NR_rt_sigsuspend, SysSigSuspend, int, ARG_NUM_1) + +SYSCALL_HAND_DEF(__NR_fchownat, SysFchownat, int, ARG_NUM_5) +SYSCALL_HAND_DEF(__NR_fchown32, SysFchown, int, ARG_NUM_3) +SYSCALL_HAND_DEF(__NR_chown, SysChown, int, ARG_NUM_3) +SYSCALL_HAND_DEF(__NR_chown32, SysChown, int, ARG_NUM_3) +#ifdef LOSCFG_SECURITY_CAPABILITY +SYSCALL_HAND_DEF(__NR_ohoscapget, SysCapGet, UINT32, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_ohoscapset, SysCapSet, UINT32, ARG_NUM_1) +#endif + +SYSCALL_HAND_DEF(__NR_mmap2, SysMmap, void*, ARG_NUM_6) +SYSCALL_HAND_DEF(__NR_getuid32, SysGetUserID, int, ARG_NUM_0) +SYSCALL_HAND_DEF(__NR_getgid32, SysGetGroupID, unsigned int, ARG_NUM_0) +SYSCALL_HAND_DEF(__NR_geteuid32, SysGetEffUserID, int, ARG_NUM_0) +SYSCALL_HAND_DEF(__NR_getegid32, SysGetEffGID, unsigned int, ARG_NUM_0) +SYSCALL_HAND_DEF(__NR_getresuid32, SysGetRealEffSaveUserID, int, ARG_NUM_3) +SYSCALL_HAND_DEF(__NR_getresgid32, SysGetRealEffSaveGroupID, int, ARG_NUM_3) +SYSCALL_HAND_DEF(__NR_setresuid32, SysSetRealEffSaveUserID, int, ARG_NUM_3) +SYSCALL_HAND_DEF(__NR_setresgid32, SysSetRealEffSaveGroupID, int, ARG_NUM_3) +SYSCALL_HAND_DEF(__NR_setreuid32, SysSetRealEffUserID, int, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_setregid32, SysSetRealEffGroupID, int, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_setgroups32, SysSetGroups, int, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_getgroups32, SysGetGroups, int, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_setuid32, SysSetUserID, int, ARG_NUM_1) +SYSCALL_HAND_DEF(__NR_setgid32, SysSetGroupID, int, ARG_NUM_1) + +SYSCALL_HAND_DEF(__NR_gettid, SysGetTid, unsigned int, ARG_NUM_0) + +SYSCALL_HAND_DEF(__NR_tkill, SysPthreadKill, int, ARG_NUM_2) + +SYSCALL_HAND_DEF(__NR_futex, SysFutex, int, ARG_NUM_4) +SYSCALL_HAND_DEF(__NR_exit_group, SysUserExitGroup, void, ARG_NUM_1) +SYSCALL_HAND_DEF(__NR_set_thread_area, SysSetThreadArea, int, ARG_NUM_1) +SYSCALL_HAND_DEF(__NR_get_thread_area, SysGetThreadArea, char *, ARG_NUM_0) +SYSCALL_HAND_DEF(__NR_timer_create, SysTimerCreate, int, ARG_NUM_3) +SYSCALL_HAND_DEF(__NR_timer_settime32, SysTimerSettime, int, ARG_NUM_4) +SYSCALL_HAND_DEF(__NR_timer_gettime32, SysTimerGettime, int, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_timer_getoverrun, SysTimerGetoverrun, int, ARG_NUM_1) +SYSCALL_HAND_DEF(__NR_timer_delete, SysTimerDelete, int, ARG_NUM_1) +SYSCALL_HAND_DEF(__NR_clock_settime32, SysClockSettime, int, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_clock_gettime32, SysClockGettime, int, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_clock_getres_time32, SysClockGetres, int, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_clock_nanosleep_time32, SysClockNanoSleep, int, ARG_NUM_4) +SYSCALL_HAND_DEF(__NR_mq_open, SysMqOpen, mqd_t, ARG_NUM_4) +SYSCALL_HAND_DEF(__NR_mq_unlink, SysMqUnlink, int, ARG_NUM_1) +SYSCALL_HAND_DEF(__NR_mq_timedsend, SysMqTimedSend, int, ARG_NUM_5) +SYSCALL_HAND_DEF(__NR_mq_timedreceive, SysMqTimedReceive, ssize_t, ARG_NUM_5) +SYSCALL_HAND_DEF(__NR_mq_notify, SysMqNotify, int, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_mq_getsetattr, SysMqGetSetAttr, int, ARG_NUM_3) + +#ifdef LOSCFG_NET_LWIP_SACK +SYSCALL_HAND_DEF(__NR_socket, SysSocket, int, ARG_NUM_3) +SYSCALL_HAND_DEF(__NR_bind, SysBind, int, ARG_NUM_3) +SYSCALL_HAND_DEF(__NR_connect, SysConnect, int, ARG_NUM_3) +SYSCALL_HAND_DEF(__NR_listen, SysListen, int, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_accept, SysAccept, int, ARG_NUM_3) +SYSCALL_HAND_DEF(__NR_getsockname, SysGetSockName, int, ARG_NUM_3) +SYSCALL_HAND_DEF(__NR_getpeername, SysGetPeerName, int, ARG_NUM_3) +SYSCALL_HAND_DEF(__NR_send, SysSend, ssize_t, ARG_NUM_4) +SYSCALL_HAND_DEF(__NR_sendto, SysSendTo, ssize_t, ARG_NUM_6) +SYSCALL_HAND_DEF(__NR_recv, SysRecv, ssize_t, ARG_NUM_4) +SYSCALL_HAND_DEF(__NR_recvfrom, SysRecvFrom, ssize_t, ARG_NUM_6) +SYSCALL_HAND_DEF(__NR_shutdown, SysShutdown, int, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_setsockopt, SysSetSockOpt, int, ARG_NUM_5) +SYSCALL_HAND_DEF(__NR_getsockopt, SysGetSockOpt, int, ARG_NUM_5) +SYSCALL_HAND_DEF(__NR_sendmsg, SysSendMsg, ssize_t, ARG_NUM_3) +SYSCALL_HAND_DEF(__NR_recvmsg, SysRecvMsg, ssize_t, ARG_NUM_3) +#endif + +#ifdef LOSCFG_KERNEL_SHM +SYSCALL_HAND_DEF(__NR_shmat, SysShmAt, void *, ARG_NUM_3) +SYSCALL_HAND_DEF(__NR_shmdt, SysShmDt, int, ARG_NUM_1) +SYSCALL_HAND_DEF(__NR_shmget, SysShmGet, int, ARG_NUM_3) +SYSCALL_HAND_DEF(__NR_shmctl, SysShmCtl, int, ARG_NUM_3) +#endif + +SYSCALL_HAND_DEF(__NR_statx, SysStatx, int, ARG_NUM_5) + +#ifdef LOSCFG_CHROOT +SYSCALL_HAND_DEF(__NR_chroot, SysChroot, int, ARG_NUM_1) +#endif + +/* LiteOS customized syscalls, not compatible with ARM EABI */ +SYSCALL_HAND_DEF(__NR_pthread_set_detach, SysUserThreadSetDetach, int, ARG_NUM_1) +SYSCALL_HAND_DEF(__NR_pthread_join, SysThreadJoin, int, ARG_NUM_1) +SYSCALL_HAND_DEF(__NR_pthread_deatch, SysUserThreadDetach, int, ARG_NUM_1) +SYSCALL_HAND_DEF(__NR_create_user_thread, SysCreateUserThread, unsigned int, ARG_NUM_3) +SYSCALL_HAND_DEF(__NR_getrusage, SysGetrusage, int, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_sysconf, SysSysconf, long, ARG_NUM_1) +SYSCALL_HAND_DEF(__NR_ugetrlimit, SysUgetrlimit, int, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_setrlimit, SysSetrlimit, int, ARG_NUM_2) diff --git a/src/kernel_liteos_a/syscall/syscall_pub.c b/src/kernel_liteos_a/syscall/syscall_pub.c new file mode 100644 index 00000000..6934e880 --- /dev/null +++ b/src/kernel_liteos_a/syscall/syscall_pub.c @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "syscall_pub.h" + +int CheckRegion(const LosVmSpace *space, VADDR_T ptr, size_t len) +{ + LosVmMapRegion *region = LOS_RegionFind((LosVmSpace *)space, ptr); + if (region == NULL) { + return -1; + } + if (ptr + len <= region->range.base + region->range.size) { + return 0; + } + return CheckRegion(space, region->range.base + region->range.size, + (ptr + len) - (region->range.base + region->range.size)); +} + +void *DupUserMem(const void *ptr, size_t len, int needCopy) +{ + void *p = LOS_MemAlloc(OS_SYS_MEM_ADDR, len); + if (p == NULL) { + set_errno(ENOMEM); + return NULL; + } + + if (needCopy && LOS_ArchCopyFromUser(p, ptr, len) != 0) { + LOS_MemFree(OS_SYS_MEM_ADDR, p); + set_errno(EFAULT); + return NULL; + } + + return p; +} + +int GetFullpath(int fd, const char *path, char **fullpath) +{ + int ret = 0; + char *pathRet = NULL; + struct file *file = NULL; + struct stat bufRet = {0}; + + if (path != NULL) { + ret = UserPathCopy(path, &pathRet); + if (ret != 0) { + goto OUT; + } + } + + if ((pathRet != NULL) && (*pathRet == '/')) { + *fullpath = pathRet; + pathRet = NULL; + } else { + if (fd != AT_FDCWD) { + /* Process fd convert to system global fd */ + fd = GetAssociatedSystemFd(fd); + } + ret = fs_getfilep(fd, &file); + if (ret < 0) { + ret = -EPERM; + goto OUT; + } + if (file) { + ret = stat(file->f_path, &bufRet); + if (!ret) { + if (!S_ISDIR(bufRet.st_mode)) { + set_errno(ENOTDIR); + ret = -ENOTDIR; + goto OUT; + } + } + } + ret = vfs_normalize_pathat(fd, pathRet, fullpath); + } + +OUT: + PointerFree(pathRet); + return ret; +} + +int UserPathCopy(const char *userPath, char **pathBuf) +{ + int ret; + + *pathBuf = (char *)LOS_MemAlloc(OS_SYS_MEM_ADDR, PATH_MAX + 1); + if (*pathBuf == NULL) { + return -ENOMEM; + } + + ret = LOS_StrncpyFromUser(*pathBuf, userPath, PATH_MAX + 1); + if (ret < 0) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, *pathBuf); + *pathBuf = NULL; + return ret; + } else if (ret > PATH_MAX) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, *pathBuf); + *pathBuf = NULL; + return -ENAMETOOLONG; + } + (*pathBuf)[ret] = '\0'; + + return 0; +} diff --git a/src/kernel_liteos_a/syscall/syscall_pub.h b/src/kernel_liteos_a/syscall/syscall_pub.h new file mode 100644 index 00000000..62081ba8 --- /dev/null +++ b/src/kernel_liteos_a/syscall/syscall_pub.h @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _SYSCALL_PUB_H +#define _SYSCALL_PUB_H + +#include +#include "los_memory.h" +#include "los_vm_lock.h" +#include "los_vm_map.h" +#include "user_copy.h" +#include "fs/fs.h" +#include "fcntl.h" +#include "los_strncpy_from_user.h" + +extern int CheckRegion(const LosVmSpace *space, VADDR_T ptr, size_t len); +extern void *DupUserMem(const void *ptr, size_t len, int needCopy); +extern int GetFullpath(int fd, const char *path, char **fullpath); +extern int UserPathCopy(const char *userPath, char **pathBuf); + +#define CHECK_ASPACE(ptr, len, ...) \ + do { \ + if (ptr != NULL && len != 0) { \ + if (!LOS_IsUserAddressRange((VADDR_T)(UINTPTR)ptr, len)) { \ + set_errno(EFAULT); \ + __VA_ARGS__; \ + return -get_errno(); \ + } \ + LosVmSpace *__aspace = OsCurrProcessGet()->vmSpace; \ + (VOID)LOS_MuxAcquire(&__aspace->regionMux); \ + if (CheckRegion(__aspace, (VADDR_T)(UINTPTR)ptr, len) == -1) { \ + (VOID)LOS_MuxRelease(&__aspace->regionMux); \ + set_errno(EFAULT); \ + __VA_ARGS__; \ + return -get_errno(); \ + } \ + (VOID)LOS_MuxRelease(&__aspace->regionMux); \ + } \ + } while (0) + +#define LEN(ptr) ((ptr) ? *(ptr) : 0) + +#define DUP_FROM_USER_(ptr, size, copy, ...) \ + __typeof(ptr) ptr##bak = ptr; \ + if (ptr != NULL && (size) != 0) { \ + ptr = DupUserMem(ptr, size, copy); \ + if (ptr == NULL) { \ + ptr = ptr##bak; \ + __VA_ARGS__; \ + return -get_errno(); \ + } \ + } + +/* +DUP_FROM_USER(ptr, size, ...) can not deal with "char *"; +Please deal with the "char *" by function:UserPathCopy. +*/ +#define DUP_FROM_USER(ptr, size, ...) \ + DUP_FROM_USER_(ptr, size, 1, ##__VA_ARGS__) + +#define DUP_FROM_USER_NOCOPY(ptr, size, ...) \ + DUP_FROM_USER_(ptr, size, 0, ##__VA_ARGS__) + +#define DUP_TO_USER(ptr, size, ...) \ + do { \ + if (ptr != NULL && (size) != 0) { \ + if (LOS_ArchCopyToUser(ptr##bak, ptr, size) != 0) { \ + set_errno(EFAULT); \ + __VA_ARGS__; \ + return -get_errno(); \ + } \ + } \ + } while (0) + +#define FREE_DUP(ptr) \ + do { \ + if (ptr != ptr##bak) { \ + LOS_MemFree(OS_SYS_MEM_ADDR, (void*)ptr); \ + ptr = ptr##bak; \ + } \ + } while (0) + +#define CPY_FROM_USER(ptr) \ + __typeof(*ptr) ptr##cpy = {0}, *ptr##bak = ptr; \ + if (ptr != NULL) { \ + if (LOS_ArchCopyFromUser((void*)&ptr##cpy, ptr##bak, sizeof(*ptr##bak)) != 0) { \ + set_errno(EFAULT); \ + return -get_errno(); \ + } \ + ptr = &ptr##cpy; \ + } + +#define CPY_TO_USER(ptr, ...) \ + if (ptr != NULL) { \ + if (LOS_ArchCopyToUser(ptr##bak, ptr, sizeof(*ptr)) != 0) { \ + set_errno(EFAULT); \ + __VA_ARGS__; \ + return -get_errno(); \ + } \ + } + +/** Macros for sendmsg and recvmsg */ + +#define CONST_CAST(ptr) ((__typeof(ptr##_NONCONST))ptr) + +#define CHECK_FIELD_ASPACE(ptr, field, len) \ + do { \ + if (ptr != NULL) { \ + CHECK_ASPACE(ptr->field, len); \ + } \ + } while (0) + +#define CHECK_ARRAY_FIELD_ASPACE(ptr, arr, arrlen, field, len, ...) \ + do { \ + if (ptr != NULL && ptr->arr != NULL) { \ + for (size_t i = 0; i < arrlen; i++) { \ + CHECK_ASPACE(ptr->arr[i].field, ptr->arr[i].len, ##__VA_ARGS__); \ + } \ + } \ + } while (0) + +#define DUP_FIELD_FROM_USER_(ptr, field, size, copy, ...) \ + do { \ + if (ptr != NULL && ptr->field != NULL && (size) != 0) { \ + CONST_CAST(ptr)->field = DupUserMem(ptr->field, size, copy); \ + if (ptr->field == NULL) { \ + __VA_ARGS__; \ + return -get_errno(); \ + } \ + } \ + } while (0) + +#define DUP_FIELD_FROM_USER(ptr, field, size, ...) \ + DUP_FIELD_FROM_USER_(ptr, field, size, 1, ##__VA_ARGS__) + +#define DUP_FIELD_FROM_USER_NOCOPY(ptr, field, size, ...) \ + DUP_FIELD_FROM_USER_(ptr, field, size, 0, ##__VA_ARGS__) + +/* backup the arr to ptr##arr */ +#define DUP_ARRAY_FIELD_FROM_USER_(ext, ptr, arr, arrlen, field, len, ...) \ + __typeof(*ptr##_NONCONST) ptr##arr##cpy = ptr##cpybak, ptr##arr##cpybak = ptr##cpybak; \ + __typeof(ptr##_NONCONST) ptr##arr = ptr ? &ptr##arr##cpy : NULL, ptr##arr##_NONCONST = NULL; \ + DUP_FIELD_FROM_USER(ptr##arr, arr, arrlen * sizeof(ptr->arr[0]), ##__VA_ARGS__); \ + if (ptr != NULL && ptr->arr != NULL) { \ + size_t i = 0; \ + for (; i < arrlen; i++) { \ + DUP_FIELD_FROM_USER##ext(ptr, arr[i].field, ptr->arr[i].len, break); \ + } \ + if (i != arrlen) { \ + FREE_DUP_ARRAY_FIELD(ptr, arr, i, field); \ + __VA_ARGS__; \ + return -get_errno(); \ + } \ + } + +#define DUP_ARRAY_FIELD_FROM_USER(ptr, arr, arrlen, field, len, ...) \ + DUP_ARRAY_FIELD_FROM_USER_(, ptr, arr, arrlen, field, len, ##__VA_ARGS__) + +#define DUP_ARRAY_FIELD_FROM_USER_NOCOPY(ptr, arr, arrlen, field, len, ...) \ + DUP_ARRAY_FIELD_FROM_USER_(_NOCOPY, ptr, arr, arrlen, field, len, ##__VA_ARGS__) + +#define FREE_DUP_FIELD(ptr, field) \ + do { \ + if (ptr != NULL && ptr->field != ptr##cpybak.field) { \ + LOS_MemFree(OS_SYS_MEM_ADDR, (void*)ptr->field); \ + CONST_CAST(ptr)->field = ptr##cpybak.field; \ + } \ + } while (0) + +/* use and free the backuped arr in ptr##arr */ +#define FREE_DUP_ARRAY_FIELD(ptr, arr, arrlen, field) \ + if (ptr != NULL && ptr->arr != NULL && arrlen != 0) { \ + __typeof(ptr##cpybak.arr) tmp = ptr##cpybak.arr; \ + ptr##cpybak.arr = ptr##arr->arr; \ + for (size_t j = 0; j < arrlen; j++) { \ + FREE_DUP_FIELD(ptr, arr[j].field); \ + } \ + ptr##cpybak.arr = tmp; \ + } \ + FREE_DUP_FIELD(ptr##arr, arr); + +#define CPY_FROM_CONST_USER(NonConstType, ptr) \ + CPY_FROM_USER(ptr); \ + NonConstType *ptr##_NONCONST = NULL, ptr##cpybak = ptr##cpy; \ + (void)ptr##bak; + +#define CPY_FROM_NONCONST_USER(ptr) \ + CPY_FROM_USER(ptr); \ + __typeof(*ptr) *ptr##_NONCONST = NULL, ptr##cpybak = ptr##cpy; + +#define DUP_FIELD_TO_USER(ptr, field, size, ...) \ + do { \ + if (ptr != NULL && ptr->field != NULL && (size) != 0) { \ + if (LOS_ArchCopyToUser(ptr##cpybak.field, ptr->field, size) != 0 || \ + LOS_ArchCopyToUser(&ptr##bak->field, &ptr##cpybak.field, sizeof(__typeof(ptr##cpybak.field))) != 0) { \ + set_errno(EFAULT); \ + __VA_ARGS__; \ + return -get_errno(); \ + } \ + } \ + } while (0) + +/* use the backuped arr from ptr##arr */ +#define DUP_ARRAY_FIELD_TO_USER(ptr, arr, arrlen, field, len, ...) \ + if (ptr != NULL && ptr->arr != NULL) { \ + __typeof(ptr##cpybak.arr) tmp = ptr##cpybak.arr; \ + __typeof(ptr##bak) tmp2 = ptr##bak; \ + ptr##cpybak.arr = ptr##arr->arr; \ + ptr##arr->arr = tmp; \ + ptr##bak = ptr##arr; \ + for (size_t i = 0; i < arrlen; i++) { \ + DUP_FIELD_TO_USER(ptr, arr[i].field, ptr->arr[i].len, ##__VA_ARGS__); \ + } \ + ptr##bak = tmp2; \ + ptr##arr->arr = ptr##cpybak.arr; \ + ptr##cpybak.arr = tmp; \ + } + +#define PointerFree(ptr) \ + do { \ + if (ptr != NULL) { \ + LOS_MemFree(OS_SYS_MEM_ADDR, (void*)ptr); \ + } \ + } while (0) +#endif diff --git a/src/kernel_liteos_a/syscall/time_syscall.c b/src/kernel_liteos_a/syscall/time_syscall.c new file mode 100644 index 00000000..4b59748f --- /dev/null +++ b/src/kernel_liteos_a/syscall/time_syscall.c @@ -0,0 +1,600 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "errno.h" +#include "unistd.h" +#include "limits.h" +#include "utime.h" +#include "time.h" +#include "user_copy.h" +#include "sys/times.h" +#include "los_signal.h" +#include "los_memory.h" +#include "los_strncpy_from_user.h" +#include "time_posix.h" + +#ifdef LOSCFG_FS_VFS +int SysUtime(const char *path, const struct utimbuf *ptimes) +{ + int ret; + char *spath = NULL; + struct utimbuf sptimes; + + if (path == NULL) { + errno = EINVAL; + return -EINVAL; + } + + spath = LOS_MemAlloc(m_aucSysMem0, PATH_MAX + 1); + if (spath == NULL) { + errno = ENOMEM; + return -ENOMEM; + } + + ret = LOS_StrncpyFromUser(spath, path, PATH_MAX + 1); + if (ret == -EFAULT) { + LOS_MemFree(m_aucSysMem0, spath); + return ret; + } else if (ret > PATH_MAX) { + LOS_MemFree(m_aucSysMem0, spath); + PRINT_ERR("%s[%d], path exceeds maxlen: %d\n", __FUNCTION__, __LINE__, PATH_MAX); + return -ENAMETOOLONG; + } + spath[ret] = '\0'; + + if (ptimes && LOS_ArchCopyFromUser(&sptimes, ptimes, sizeof(struct utimbuf))) { + LOS_MemFree(m_aucSysMem0, spath); + errno = EFAULT; + return -EFAULT; + } + + ret = utime(spath, ptimes ? &sptimes : NULL); + if (ret < 0) { + ret = -get_errno(); + } + + LOS_MemFree(m_aucSysMem0, spath); + + return ret; +} +#endif + +time_t SysTime(time_t *tloc) +{ + int ret; + time_t stloc; + + ret = time(tloc ? &stloc : NULL); + if (ret < 0) { + return -get_errno(); + } + + if (tloc && LOS_ArchCopyToUser(tloc, &stloc, sizeof(time_t))) { + errno = EFAULT; + ret = -EFAULT; + } + + return ret; +} + +int SysSetiTimer(int which, const struct itimerval *value, struct itimerval *ovalue) +{ + int ret; + struct itimerval svalue; + struct itimerval sovalue = { 0 }; + + if (value == NULL) { + errno = EINVAL; + return -EINVAL; + } + + if (LOS_ArchCopyFromUser(&svalue, value, sizeof(struct itimerval))) { + errno = EFAULT; + return -EFAULT; + } + + ret = setitimer(which, &svalue, &sovalue); + if (ret < 0) { + return -get_errno(); + } + + if (ovalue && LOS_ArchCopyToUser(ovalue, &sovalue, sizeof(struct itimerval))) { + errno = EFAULT; + return -EFAULT; + } + + return ret; +} + +int SysGetiTimer(int which, struct itimerval *value) +{ + int ret; + struct itimerval svalue = { 0 }; + + if (value == NULL) { + errno = EINVAL; + return -EINVAL; + } + + ret = getitimer(which, &svalue); + if (ret < 0) { + return -get_errno(); + } + + if (LOS_ArchCopyToUser(value, &svalue, sizeof(struct itimerval))) { + errno = EFAULT; + return -EFAULT; + } + + return ret; +} + +int SysTimerCreate(clockid_t clockID, struct ksigevent *evp, timer_t *timerID) +{ + int ret; + timer_t stimerID; + struct ksigevent ksevp; + + if (timerID == NULL) { + errno = EINVAL; + return -EINVAL; + } + + if (evp && LOS_ArchCopyFromUser(&ksevp, evp, sizeof(struct ksigevent))) { + errno = EFAULT; + return -EFAULT; + } + + ret = OsTimerCreate(clockID, evp ? &ksevp : NULL, &stimerID); + if (ret < 0) { + return -get_errno(); + } + + if (LOS_ArchCopyToUser(timerID, &stimerID, sizeof(timer_t))) { + errno = EFAULT; + return -EFAULT; + } + + return ret; +} + +int SysTimerGettime(timer_t timerID, struct itimerspec *value) +{ + int ret; + struct itimerspec svalue = { 0 }; + + if (value == NULL) { + errno = EINVAL; + return -EINVAL; + } + + ret = timer_gettime(timerID, &svalue); + if (ret < 0) { + return -get_errno(); + } + + if (LOS_ArchCopyToUser(value, &svalue, sizeof(struct itimerspec))) { + errno = EFAULT; + return -EFAULT; + } + + return ret; +} + +int SysTimerSettime(timer_t timerID, int flags, const struct itimerspec *value, struct itimerspec *oldValue) +{ + int ret; + struct itimerspec svalue; + struct itimerspec soldValue = { 0 }; + + if (value == NULL) { + errno = EINVAL; + return -EINVAL; + } + + if (LOS_ArchCopyFromUser(&svalue, value, sizeof(struct itimerspec))) { + errno = EFAULT; + return -EFAULT; + } + + ret = timer_settime(timerID, flags, &svalue, &soldValue); + if (ret < 0) { + return -get_errno(); + } + + if (oldValue && LOS_ArchCopyToUser(oldValue, &soldValue, sizeof(struct itimerspec))) { + errno = EFAULT; + return -EFAULT; + } + + return ret; +} + +int SysTimerGetoverrun(timer_t timerID) +{ + int ret; + + ret = timer_getoverrun(timerID); + if (ret < 0) { + return -get_errno(); + } + return ret; +} + +int SysTimerDelete(timer_t timerID) +{ + int ret; + + ret = timer_delete(timerID); + if (ret < 0) { + return -get_errno(); + } + return ret; +} + +int SysClockSettime(clockid_t clockID, const struct timespec *tp) +{ + int ret; + struct timespec stp; + + if (tp == NULL) { + errno = EINVAL; + return -EINVAL; + } + + if (LOS_ArchCopyFromUser(&stp, tp, sizeof(struct timespec))) { + errno = EFAULT; + return -EFAULT; + } + + ret = clock_settime(clockID, &stp); + if (ret < 0) { + return -get_errno(); + } + return ret; +} + +int SysClockGettime(clockid_t clockID, struct timespec *tp) +{ + int ret; + struct timespec stp = { 0 }; + + if (tp == NULL) { + errno = EINVAL; + return -EINVAL; + } + + ret = clock_gettime(clockID, &stp); + if (ret < 0) { + return -get_errno(); + } + + if (LOS_ArchCopyToUser(tp, &stp, sizeof(struct timespec))) { + errno = EFAULT; + return -EFAULT; + } + + return ret; +} + +int SysClockGetres(clockid_t clockID, struct timespec *tp) +{ + int ret; + struct timespec stp = { 0 }; + + if (tp == NULL) { + errno = EINVAL; + return -EINVAL; + } + + ret = clock_getres(clockID, &stp); + if (ret < 0) { + return -get_errno(); + } + + if (LOS_ArchCopyToUser(tp, &stp, sizeof(struct timespec))) { + errno = EFAULT; + return -EFAULT; + } + + return ret; +} + +int SysClockNanoSleep(clockid_t clk, int flags, const struct timespec *req, struct timespec *rem) +{ + int ret; + struct timespec sreq; + struct timespec srem = { 0 }; + + if (!req || LOS_ArchCopyFromUser(&sreq, req, sizeof(struct timespec))) { + errno = EFAULT; + return -EFAULT; + } + + ret = clock_nanosleep(clk, flags, &sreq, rem ? &srem : NULL); + if (ret < 0) { + return -get_errno(); + } + + if (rem && LOS_ArchCopyToUser(rem, &srem, sizeof(struct timespec))) { + errno = EFAULT; + return -EFAULT; + } + + return ret; +} + +int SysNanoSleep(const struct timespec *rqtp, struct timespec *rmtp) +{ + int ret; + struct timespec srqtp; + struct timespec srmtp = { 0 }; + + if (!rqtp || LOS_ArchCopyFromUser(&srqtp, rqtp, sizeof(struct timespec))) { + errno = EFAULT; + return -EFAULT; + } + + if (rmtp && LOS_ArchCopyFromUser(&srmtp, rmtp, sizeof(struct timespec))) { + errno = EFAULT; + return -EFAULT; + } + + ret = nanosleep(&srqtp, rmtp ? &srmtp : NULL); + if (ret < 0) { + return -get_errno(); + } + + if (rmtp && LOS_ArchCopyToUser(rmtp, &srmtp, sizeof(struct timespec))) { + errno = EFAULT; + return -EFAULT; + } + + return ret; +} + +clock_t SysTimes(struct tms *buf) +{ + clock_t ret; + struct tms sbuf = { 0 }; + + if (buf == NULL) { + errno = EFAULT; + return -EFAULT; + } + ret = times(&sbuf); + if (ret == -1) { + return -get_errno(); + } + if (LOS_ArchCopyToUser(buf, &sbuf, sizeof(struct tms))) { + errno = EFAULT; + return -EFAULT; + } + + return ret; +} + +int SysClockSettime64(clockid_t clockID, const struct timespec64 *tp) +{ + int ret; + struct timespec t; + struct timespec64 stp; + + if (tp == NULL) { + errno = EINVAL; + return -EINVAL; + } + + if (LOS_ArchCopyFromUser(&stp, tp, sizeof(struct timespec64))) { + errno = EFAULT; + return -EFAULT; + } + + if (stp.tv_sec > UINT32_MAX) { + errno = ENOSYS; + return -ENOSYS; + } + t.tv_sec = stp.tv_sec; + t.tv_nsec = stp.tv_nsec; + + ret = clock_settime(clockID, &t); + if (ret < 0) { + return -get_errno(); + } + return ret; +} + +int SysClockGettime64(clockid_t clockID, struct timespec64 *tp) +{ + int ret; + struct timespec t; + struct timespec64 stp = { 0 }; + + if (tp == NULL) { + errno = EINVAL; + return -EINVAL; + } + + ret = clock_gettime(clockID, &t); + if (ret < 0) { + return -get_errno(); + } + + stp.tv_sec = t.tv_sec; + stp.tv_nsec = t.tv_nsec; + + if (LOS_ArchCopyToUser(tp, &stp, sizeof(struct timespec64))) { + errno = EFAULT; + return -EFAULT; + } + + return ret; +} + +int SysClockGetres64(clockid_t clockID, struct timespec64 *tp) +{ + int ret; + struct timespec t; + struct timespec64 stp = { 0 }; + + if (tp == NULL) { + errno = EINVAL; + return -EINVAL; + } + + ret = clock_getres(clockID, &t); + if (ret < 0) { + return -get_errno(); + } + + stp.tv_sec = t.tv_sec; + stp.tv_nsec = t.tv_nsec; + + if (LOS_ArchCopyToUser(tp, &stp, sizeof(struct timespec64))) { + errno = EFAULT; + return -EFAULT; + } + + return ret; +} + +int SysClockNanoSleep64(clockid_t clk, int flags, const struct timespec64 *req, struct timespec64 *rem) +{ + int ret; + struct timespec rq; + struct timespec rm = { 0 }; + struct timespec64 sreq; + struct timespec64 srem = { 0 }; + + if (!req || LOS_ArchCopyFromUser(&sreq, req, sizeof(struct timespec64))) { + errno = EFAULT; + return -EFAULT; + } + + if (req != NULL) { + rq.tv_sec = (sreq.tv_sec > UINT32_MAX) ? UINT32_MAX : sreq.tv_sec; + rq.tv_nsec = sreq.tv_nsec; + } + + ret = clock_nanosleep(clk, flags, &rq, rem ? &rm : NULL); + if (ret < 0) { + return -get_errno(); + } + + if (rem != NULL) { + srem.tv_sec = rm.tv_sec; + srem.tv_nsec = rm.tv_nsec; + if (LOS_ArchCopyToUser(rem, &srem, sizeof(struct timespec64))) { + errno = EFAULT; + return -EFAULT; + } + } + + return ret; +} + +int SysTimerGettime64(timer_t timerID, struct itimerspec64 *value) +{ + int ret; + struct itimerspec val; + struct itimerspec64 svalue = { 0 }; + + if (value == NULL) { + errno = EINVAL; + return -EINVAL; + } + + ret = timer_gettime(timerID, &val); + if (ret < 0) { + return -get_errno(); + } + + svalue.it_interval.tv_sec = val.it_interval.tv_sec; + svalue.it_interval.tv_nsec = val.it_interval.tv_nsec; + svalue.it_value.tv_sec = val.it_value.tv_sec; + svalue.it_value.tv_nsec = val.it_value.tv_nsec; + + if (LOS_ArchCopyToUser(value, &svalue, sizeof(struct itimerspec64))) { + errno = EFAULT; + return -EFAULT; + } + + return ret; +} + +int SysTimerSettime64(timer_t timerID, int flags, const struct itimerspec64 *value, struct itimerspec64 *oldValue) +{ + int ret; + struct itimerspec val; + struct itimerspec oldVal; + struct itimerspec64 svalue; + struct itimerspec64 soldValue; + + if (value == NULL) { + errno = EINVAL; + return -EINVAL; + } + + if (LOS_ArchCopyFromUser(&svalue, value, sizeof(struct itimerspec64))) { + errno = EFAULT; + return -EFAULT; + } + + if (svalue.it_interval.tv_sec > UINT32_MAX || svalue.it_value.tv_sec > UINT32_MAX) { + errno = ENOSYS; + return -ENOSYS; + } + + val.it_interval.tv_sec = svalue.it_interval.tv_sec; + val.it_interval.tv_nsec = svalue.it_interval.tv_nsec; + val.it_value.tv_sec = svalue.it_value.tv_sec; + val.it_value.tv_nsec = svalue.it_value.tv_nsec; + + ret = timer_settime(timerID, flags, &val, oldValue ? &oldVal : NULL); + if (ret < 0) { + return -get_errno(); + } + + if (oldValue != NULL) { + (void)memset_s(&soldValue, sizeof(struct itimerspec64), 0, sizeof(struct itimerspec64)); + soldValue.it_interval.tv_sec = oldVal.it_interval.tv_sec; + soldValue.it_interval.tv_nsec = oldVal.it_interval.tv_nsec; + soldValue.it_value.tv_sec = oldVal.it_value.tv_sec; + soldValue.it_value.tv_nsec = oldVal.it_value.tv_nsec; + + if (LOS_ArchCopyToUser(oldValue, &soldValue, sizeof(struct itimerspec64))) { + errno = EFAULT; + return -EFAULT; + } + } + + return ret; +} diff --git a/src/kernel_liteos_a/syscall/vm_syscall.c b/src/kernel_liteos_a/syscall/vm_syscall.c new file mode 100644 index 00000000..3c02e6cd --- /dev/null +++ b/src/kernel_liteos_a/syscall/vm_syscall.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "sys/types.h" +#include "sys/shm.h" +#include "errno.h" +#include "unistd.h" +#include "los_vm_syscall.h" +#include "fs/file.h" + + +void *SysMmap(void *addr, size_t size, int prot, int flags, int fd, size_t offset) +{ + /* Process fd convert to system global fd */ + fd = GetAssociatedSystemFd(fd); + + return (void *)LOS_MMap((uintptr_t)addr, size, prot, flags, fd, offset); +} + +int SysMunmap(void *addr, size_t size) +{ + return LOS_UnMMap((uintptr_t)addr, size); +} + +void *SysMremap(void *oldAddr, size_t oldLen, size_t newLen, int flags, void *newAddr) +{ + return (void *)LOS_DoMremap((vaddr_t)oldAddr, oldLen, newLen, flags, (vaddr_t)newAddr); +} + +int SysMprotect(void *vaddr, size_t len, int prot) +{ + return LOS_DoMprotect((uintptr_t)vaddr, len, (unsigned long)prot); +} + +void *SysBrk(void *addr) +{ + return LOS_DoBrk(addr); +} + +#ifdef LOSCFG_KERNEL_SHM +int SysShmGet(key_t key, size_t size, int shmflg) +{ + int ret; + + ret = ShmGet(key, size, shmflg); + if (ret < 0) { + return -get_errno(); + } + + return ret; +} + +void *SysShmAt(int shmid, const void *shmaddr, int shmflg) +{ + void *ret = NULL; + + ret = ShmAt(shmid, shmaddr, shmflg); + if (ret == (void *)-1) { + return (void *)(intptr_t)-get_errno(); + } + + return ret; +} + +int SysShmCtl(int shmid, int cmd, struct shmid_ds *buf) +{ + int ret; + + ret = ShmCtl(shmid, cmd, buf); + if (ret < 0) { + return -get_errno(); + } + + return ret; +} + +int SysShmDt(const void *shmaddr) +{ + int ret; + + ret = ShmDt(shmaddr); + if (ret < 0) { + return -get_errno(); + } + + return ret; +} +#endif + diff --git a/src/kernel_liteos_a/testsuites/BUILD.gn b/src/kernel_liteos_a/testsuites/BUILD.gn new file mode 100644 index 00000000..c09cb41c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/BUILD.gn @@ -0,0 +1,41 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +declare_args() { + liteos_kernel_unittest = true +} + +group("testsuites") { + deps = [] + if (liteos_kernel_unittest) { + deps += [ "unittest" ] + } +} diff --git a/src/kernel_liteos_a/testsuites/Kconfig b/src/kernel_liteos_a/testsuites/Kconfig new file mode 100644 index 00000000..a6ea6fae --- /dev/null +++ b/src/kernel_liteos_a/testsuites/Kconfig @@ -0,0 +1,49 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +# +# For a description of the syntax of this configuration file, +# see extra/config/Kconfig-language.txt +# +mainmenu "Huawei LiteOS Configuration" + +menu "Enable Kernel TestSuit" + +config KERNEL_TEST + bool "Enable Kernel Testsuit" + +config TEST + bool "Enable Auto TestSuit" + default y + depends on KERNEL_TEST + +source "./kernel/Kconfig" +endmenu + diff --git a/src/kernel_liteos_a/testsuites/LICENSE b/src/kernel_liteos_a/testsuites/LICENSE new file mode 100644 index 00000000..b6ffd6e6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/LICENSE @@ -0,0 +1,28 @@ +Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors may be used + to endorse or promote products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/kernel_liteos_a/testsuites/Makefile b/src/kernel_liteos_a/testsuites/Makefile new file mode 100644 index 00000000..4d79c100 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/Makefile @@ -0,0 +1,121 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +LITEOSTESTTOPDIR := $(shell pwd) +LITEOSTOPDIR ?= $(LITEOSTESTTOPDIR)/.. +export LITEOSTOPDIR +export LITEOSTESTTOPDIR + +include $(LITEOSTESTTOPDIR)/config.mk + +RM = -rm -rf +MAKE = make +__LIBS = libs +APPS = apps +KERNEL = kernel +TEST = test +TEST_KERNEL = test_kernel +TEST_APPS = test_apps +ROOTFSDIR = rootfsdir +ROOTFS = rootfs +HIDE := @ + +LITEOS_TEST_TARGET = liteos_ktest +LITEOS_TEST_LIBC = test_libs +LITEOS_LIBS_TARGET = libs_target + +LITEOS_TEST_AUTOCONFIG_H = $(LITEOSTESTTOPDIR)/include/generated/autoconf.h +LITEOS_TEST_KERNEL_MENUCONFIG_H = $(LITEOSTESTTOPDIR)/kernel/include +#######LITEOS_TEST_USER_MENUCONFIG_H = $(LITEOSTESTTOPDIR)/apps/include +ifeq ($(LOSCFG_KERNEL_TEST), y) +LITEOS_TEST_MENUCONFIG_H = $(LITEOS_TEST_KERNEL_MENUCONFIG_H)/test_menuconfig.h +#######else +#######LITEOS_TEST_MENUCONFIG_H = $(LITEOS_TEST_USER_MENUCONFIG_H)/test_menuconfig.h +endif + +ifeq ($(LOSCFG_STORAGE_SPINOR), y) +FSTYPE = jffs2 +endif +ifeq ($(LOSCFG_STORAGE_EMMC), y) +FSTYPE = vfat +endif +ROOTFS_DIR = $(OUT)/rootfs +ROOTFS_ZIP = $(OUT)/rootfs.zip +VERSION = + +LITEOS_LIBDEP := $(LITEOS_BASELIB) + +$(TEST_KERNEL): $(LITEOS_TEST_TARGET) + +$(LITEOS_TEST_TARGET): $(LITEOS_TEST_LIBC) + $(LD) $(LITEOS_LDFLAGS) $(LITEOS_TABLES_LDFLAGS) $(LITEOS_DYNLDFLAGS) -Map=$(OUT)/$@.map -o $(OUT)/$@ --start-group $(LITEOS_LIBDEP) --end-group + $(OBJCOPY) -O binary $(OUT)/$@ $(OUT)/$@.bin + $(OBJDUMP) -t $(OUT)/$@ |sort >$(OUT)/$@.sym.sorted + $(OBJDUMP) -d $(OUT)/$@ >$(OUT)/$@.asm + +$(LITEOS_TEST_LIBC): $(KERNEL) + $(HIDE)for dir in $(TESTLIB_SUBDIRS); \ + do $(MAKE) -C $$dir all || exit 1; \ + done + $(HIDE)echo "=============== make lib done ===============" + +$(KERNEL): $(LITEOS_TEST_AUTOCONFIG_H) + $(HIDE)$(MAKE) -C ../ lib || exit 1 + +##### make test menuconfig ##### +export CONFIG_=LOSCFG_ +MENUCONFIG_PATH = $(LITEOSTOPDIR)/tools/menuconfig +TEST_KCONFIG_FILE_PATH = $(LITEOSTESTTOPDIR)/Kconfig + +menuconfig:$(MENUCONFIG_PATH)/mconf + $< $(TEST_KCONFIG_FILE_PATH) + +genconfig:$(MENUCONFIG_PATH)/conf + $(HIDE)mkdir -p include/config include/generated + $< --silentoldconfig $(TEST_KCONFIG_FILE_PATH) + mv -f $(LITEOS_TEST_AUTOCONFIG_H) $(LITEOS_TEST_MENUCONFIG_H) + +##### menuconfig end ####### + +genconfig:$(MENUCONFIG_PATH)/conf + +$(LITEOS_TEST_AUTOCONFIG_H): +ifneq ($(LITEOS_TEST_MENUCONFIG_H), $(wildcard $(LITEOS_TEST_MENUCONFIG_H))) + $(HIDE)$(MAKE) genconfig +endif + +clean: + $(HIDE)$(MAKE) -C ../ clean || exit 1 + $(HIDE)for dir in $(TESTLIB_SUBDIRS); \ + do $(MAKE) -C $$dir clean || exit 1; \ + done + $(HIDE)$(RM) include + $(HIDE)$(RM) $(LITEOS_TEST_MENUCONFIG_H) + $(HIDE)$(RM) $(OUT) +.PHONY: test_apps test_kernel clean diff --git a/src/kernel_liteos_a/testsuites/build/los_test_config.mk b/src/kernel_liteos_a/testsuites/build/los_test_config.mk new file mode 100644 index 00000000..18d8808d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/build/los_test_config.mk @@ -0,0 +1,43 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +TESTLIB_SUBDIRS := + +-include $(LITEOSTESTTOPDIR)/.config +ifeq ($(LOSCFG_KERNEL_TEST), y) +-include $(LITEOSTESTTOPDIR)/kernel/test.mk +endif + +ifeq ($(LOSCFG_LLTREPORT) ,y) +# -fprofile-arcs may introduce false alarm on 'maybe-uninitialized' +LITEOS_GCOV_OPTS := -fprofile-arcs -ftest-coverage -Wno-maybe-uninitialized +LITEOS_BASELIB += -lgcov +endif + diff --git a/src/kernel_liteos_a/testsuites/config.mk b/src/kernel_liteos_a/testsuites/config.mk new file mode 100644 index 00000000..4a8d9587 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/config.mk @@ -0,0 +1,46 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +include $(LITEOSTOPDIR)/config.mk +include $(LITEOSTESTTOPDIR)/build/los_test_config.mk +LITEOS_CFLAGS += \ + -I $(LITEOSTHIRDPARTY)/bounds_checking_function/include \ + -I $(LITEOSTOPDIR)/security/cap/ \ + -I $(LITEOSTOPDIR)/security/vid/ \ + -I $(LITEOSTOPDIR)/platform/include \ + -I $(LITEOSTOPDIR)/kernel/base/include\ + -I $(LITEOSTOPDIR)/kernel/include \ + -I $(LITEOSTOPDIR)/kernel/extended/include \ + -I $(LITEOSTOPDIR)/fs/vfs \ + -I $(LITEOSTHIRDPARTY)/FatFs/source \ + -I $(LITEOSTOPDIR)/fs/proc/include \ + -I $(LITEOSTOPDIR)/fs/jffs2/os_adapt \ + -I $(LITEOSTHIRDPARTY)/NuttX/fs/nfs/ \ + -I $(LITEOSTOPDIR)/bsd/compat/linuxkpi/include diff --git a/src/kernel_liteos_a/testsuites/kernel/BUILD.gn b/src/kernel_liteos_a/testsuites/kernel/BUILD.gn new file mode 100644 index 00000000..79cc074e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/BUILD.gn @@ -0,0 +1,99 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +declare_args() { + LOSCFG_ENABLE_KERNEL_TEST = false + LOSCFG_TEST_KERNEL_BASE = true + LOSCFG_TEST_KERNEL_EXTEND_CPUP = false + LOSCFG_TEST_POSIX = false +} + +config("liteos_kernel_test_public") { + cflags = [ "-Wno-error" ] + include_dirs = [ + "$LITEOSTOPDIR/kernel/include", + "$LITEOSTOPDIR/kernel/base/include", + "$LITEOSTOPDIR/kernel/common", + "$LITEOSTOPDIR/arch/arm/arm/include", + "$LITEOSTOPDIR/arch/arm/include", + "$LITEOSTOPDIR/extended/include", + "$THIRDPARTY_MUSL_DIR/porting/liteos_a/kernel/include", + "$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR/include/", + "$LITEOSTOPDIR/lib/libscrew/include", + "$LITEOSTOPDIR/fs/vfs", + "$LITEOSTOPDIR/fs/proc/include", + "$LITEOSTOPDIR/fs/jffs2/include", + "$LITEOSTOPDIR/fs/nfs/include", + "$LITEOSTOPDIR/bsd/compat/linuxkpi/include", + "include", + ] + + if (LOSCFG_TEST_KERNEL_BASE) { + cflags += [ "-DLOSCFG_TEST_KERNEL_BASE=1" ] + } + if (LOSCFG_TEST_KERNEL_EXTEND_CPUP) { + cflags += [ "-DLOSCFG_TEST_KERNEL_EXTEND_CPUP=1" ] + } + if (LOSCFG_TEST_POSIX) { + cflags += [ "-DLOSCFG_TEST_POSIX=1" ] + } +} + +group("kernel_test") { + deps = [] + + if (LOSCFG_ENABLE_KERNEL_TEST) { + deps += [ ":test_base" ] + + if (LOSCFG_TEST_KERNEL_BASE) { + deps += [ "sample/kernel_base:kernel_base" ] + } + + # KERNEL EXTEND TEST + if (LOSCFG_TEST_KERNEL_EXTEND_CPUP) { + deps += [ "sample/kernel_extend/cpup:test_cpup" ] + } + + # COMPAT TEST + if (LOSCFG_TEST_POSIX) { + deps += [ "sample/posix:test_posix" ] + } + } +} + +kernel_module("test_base") { + sources = [ + "src/iCunit.c", + "src/osTest.c", + ] + + public_configs = [ ":liteos_kernel_test_public" ] +} diff --git a/src/kernel_liteos_a/testsuites/kernel/Kconfig b/src/kernel_liteos_a/testsuites/kernel/Kconfig new file mode 100644 index 00000000..9ff05b0d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/Kconfig @@ -0,0 +1,79 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +config TEST_LEVEL + bool "Enable Test Level" + default y + depends on TEST + +config TEST_SMOKE + bool "Enable Test smoke" + default y + depends on TEST && TEST_LEVEL + +config TEST_FULL + bool "Enable Test full" + default y + depends on TEST && TEST_LEVEL + +config TEST_KERNEL_BASE + bool "Enable Kernel Testsuit" + default y + depends on KERNEL_TEST && TEST +config TEST_KERNEL_BASE_IPC + bool "Enable IPC Testsuit" + default y + depends on KERNEL_TEST && TEST_KERNEL_BASE && TEST +config TEST_KERNEL_BASE_CORE + bool "Enable CORE Testsuit" + default y + depends on KERNEL_TEST && TEST_KERNEL_BASE && TEST +config TEST_KERNEL_EXTEND + bool "Enable Extended Kernel Testsuit" + default y + depends on KERNEL_TEST && TEST +config TEST_KERNEL_EXTEND_CPUP + bool "Enable CPUP Testsuit" + default y + depends on KERNEL_TEST && TEST_KERNEL_EXTEND && TEST +config TEST_POSIX + bool "Enable Posix Testsuit" + default y + depends on KERNEL_TEST && TEST +config TEST_POSIX_MUTEX + bool "Enable Mutex Testsuit" + default y + depends on KERNEL_TEST && TEST_POSIX && TEST +config TEST_POSIX_PTHREAD + bool "Enable Pthread Testsuit" + default y + depends on KERNEL_TEST && TEST_POSIX && TEST + + diff --git a/src/kernel_liteos_a/testsuites/kernel/Makefile b/src/kernel_liteos_a/testsuites/kernel/Makefile new file mode 100644 index 00000000..6112372c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/Makefile @@ -0,0 +1,43 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +include $(LITEOSTESTTOPDIR)/config.mk + +MODULE_NAME := ktest + +LOCAL_INCLUDE := -I $(LITEOSTESTTOPDIR)/kernel/include + +LOCAL_SRCS := $(wildcard src/osTest.c) \ + $(wildcard src/iCunit.c) \ + +LOCAL_FLAGS := $(LOCAL_INCLUDE) -Wno-error -I $(LITEOSTOPDIR)/../../$(LOSCFG_BOARD_CONFIG_PATH)/include \ + -I $(LITEOSTOPDIR)/fs/fat/os_adapt + +include $(MODULE) diff --git a/src/kernel_liteos_a/testsuites/kernel/include/iCunit.h b/src/kernel_liteos_a/testsuites/kernel/include/iCunit.h new file mode 100644 index 00000000..31d355e6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/include/iCunit.h @@ -0,0 +1,464 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _UNI_ICUNIT_H +#define _UNI_ICUNIT_H + +#include +#include +#include "los_typedef.h" +#include "los_spinlock.h" + +#ifdef TST_DRVPRINT +#include "VOS_typdef.h" +#include "uartdriver.h" +#endif + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +typedef unsigned short iUINT16; +typedef unsigned int iUINT32; +typedef signed short iINT16; +typedef signed long iINT32; +typedef char iCHAR; +typedef void iVOID; + +typedef unsigned long iiUINT32; + + +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE 1 +#endif + +#define FUNCTION_TEST (1 << 0) + +#define PRESSURE_TEST (1 << 1) + +#define PERFORMANCE_TEST (1 << 2) + +#define TEST_MODE (FUNCTION_TEST) + +#define TEST_LESSER_MEM 0 + + +typedef iUINT32 (*CASE_FUNCTION)(void); + +typedef struct { + const iCHAR *pcCaseID; + CASE_FUNCTION pstCaseFunc; + iUINT16 testcase_layer; + iUINT16 testcase_module; + iUINT16 testcase_level; + iUINT16 testcase_type; + iiUINT32 retCode; + iUINT16 errLine; +} ICUNIT_CASE_S; + +typedef struct { + iUINT16 uwCaseCnt; + iCHAR *pcSuitID; + iCHAR *pucFilename; + ICUNIT_CASE_S *pstCaseList; + iUINT16 passCnt; + iUINT16 failCnt; +} ICUNIT_SUIT_S; + +typedef enum { + TEST_TASK = 0, + TEST_MEM, + TEST_VM, + TEST_SEM, + TEST_MUX, + TEST_RWLOCK, + TEST_EVENT, + TEST_QUE, + TEST_SWTMR, + TEST_HWI, + TEST_MP, + TEST_ATO, + TEST_CPUP, + TEST_SCATTER, + TEST_RUNSTOP, + TEST_TIMER, + TEST_MMU, + TEST_ROBIN, + TEST_LIBC, + TEST_WAIT, + TEST_VFAT, + TEST_JFFS, + TEST_RAMFS, + TEST_NFS, + TEST_PROC, + TEST_FS, + TEST_UART, + TEST_PTHREAD, + TEST_COMP, + TEST_HWI_HALFBOTTOM, + TEST_WORKQ, + TEST_WAKELOCK, + TEST_TIMES, + TEST_LIBM, + TEST_SUPPORT, + TEST_STL, + TEST_MAIL, + TEST_MSG, + TEST_CP, + TEST_SIGNAL, + TEST_SCHED, + TEST_MTDCHAR, + TEST_TIME, + TEST_WRITE, + TEST_READ, + TEST_DYNLOAD, + TEST_REGISTER, + TEST_UNAME, + TEST_ERR, + TEST_CMD, + TEST_TICKLESS, + TEST_TRACE, + TEST_UNALIGNACCESS, + TEST_EXC, + TEST_REQULATOR, + TEST_DEVFREQ, + TEST_CPUFREQ, + TEST_MISC, +#if defined(LOSCFG_3RDPARTY_TEST) + TEST_THTTPD, + TEST_BIDIREFC, + TEST_CJSON, + TEST_CURL, + TEST_FFMPEG, + TEST_FREETYPE, + TEST_INIPARSER, + TEST_JSONCPP, + TEST_LIBICONV, + TEST_LIBJPEG, + TEST_LIBPNG, + TEST_OPENEXIF, + TEST_OPENSSL, + TEST_OPUS, + TEST_SQLITE, + TEST_TINYXML, + TEST_XML2, + TEST_ZBAR, + TEST_HARFBUZZ, +#endif + TEST_DRIVERBASE, + TEST_UDP, + TEST_TCP, + TEST_MODULE_ALL, +} LiteOS_test_module; + +typedef enum { + TEST_LOS = 0, + TEST_POSIX, + TEST_LIB, + TEST_VFS, + TEST_EXTEND, + TEST_PARTITION, + TEST_CPP, + TEST_SHELL, + TEST_LINUX, + TEST_USB, +#if defined(LOSCFG_3RDPARTY_TEST) + TEST_3RDPARTY, +#endif + TEST_DRIVERFRAME, + TEST_NET_LWIP, + TEST_LAYER_ALL, +} LiteOS_test_layer; + +typedef enum { + TEST_LEVEL0 = 0, + TEST_LEVEL1, + TEST_LEVEL2, + TEST_LEVEL3, + TEST_LEVEL4, + TEST_LEVEL_ALL, +} LiteOS_test_level; + +typedef enum { + TEST_FUNCTION = 0, + TEST_PRESSURE, + TEST_PERFORMANCE, + TEST_TYPE_ALL, +} LiteOS_test_type; + +typedef enum { + TEST_SEQUENCE = 0, + TEST_RANDOM +} LiteOS_test_sequence; + +extern iUINT16 g_iCunitErrLineNo; +extern iiUINT32 g_iCunitErrCode; +extern void ICunitSaveErr(iiUINT32 line, iiUINT32 retCode); + +#define ICUNIT_UNINIT 0x0EF00000 +#define ICUNIT_OPENFILE_FAILED 0x0EF00001 +#define ICUNIT_ALLOC_FAIL 0x0EF00002 +#define ICUNIT_SUIT_FULL 0x0EF00002 +#define ICUNIT_CASE_FULL 0x0EF00003 +#define ICUNIT_SUIT_ALL 0x0EF0FFFF + +#define ICUNIT_SUCCESS 0x00000000 + +#define ICUNIT_TRACK_EQUAL(param, g_value, retcode) \ + do { \ + if ((param) != (g_value)) { \ + ICunitSaveErr(__LINE__, (iiUINT32)retcode); \ + } \ + } while (0) + + +#define ICUNIT_TRACK_NOT_EQUAL(param, g_value, retcode) \ + do { \ + if ((param) == (g_value)) { \ + ICunitSaveErr(__LINE__, (iiUINT32)retcode); \ + } \ + } while (0) + +#define ICUNIT_ASSERT_NOT_EQUAL_NULL(param, g_value, retcode) \ + do { \ + if ((param) == (g_value)) { \ + ICunitSaveErr(__LINE__, (iiUINT32)retcode); \ + return NULL; \ + } \ + } while (0) + +#define ICUNIT_ASSERT_EQUAL_NULL(param, g_value, retcode) \ + do { \ + if ((param) != (g_value)) { \ + ICunitSaveErr(__LINE__, (iiUINT32)retcode); \ + return NULL; \ + } \ + } while (0) + +#define ICUNIT_ASSERT_EQUAL_VOID(param, g_value, retcode) \ + do { \ + if ((param) != (g_value)) { \ + ICunitSaveErr(__LINE__, (iiUINT32)retcode); \ + return; \ + } \ + } while (0) + +#define ICUNIT_ASSERT_NOT_EQUAL_VOID(param, g_value, retcode) \ + do { \ + if ((param) == (g_value)) { \ + ICunitSaveErr(__LINE__, (iiUINT32)retcode); \ + return; \ + } \ + } while (0) + +#define ICUNIT_ASSERT_EQUAL(param, g_value, retcode) \ + do { \ + if ((param) != (g_value)) { \ + ICunitSaveErr(__LINE__, (iiUINT32)retcode); \ + return 1; \ + } \ + } while (0) + +#define ICUNIT_ASSERT_NOT_EQUAL(param, g_value, retcode) \ + do { \ + if ((param) == (g_value)) { \ + ICunitSaveErr(__LINE__, (iiUINT32)retcode); \ + return 1; \ + } \ + } while (0) + +#define ICUNIT_ASSERT_WITHIN_EQUAL(param, value1, value2, retcode) \ + do { \ + if ((param) < (value1) || (param) > (value2)) { \ + ICunitSaveErr(__LINE__, (iiUINT32)retcode); \ + return 1; \ + } \ + } while (0) + +#define ICUNIT_ASSERT_WITHIN_EQUAL_VOID(param, value1, value2, retcode) \ + do { \ + if ((param) < (value1) || (param) > (value2)) { \ + ICunitSaveErr(__LINE__, (iiUINT32)retcode); \ + return; \ + } \ + } while (0) + +#define ICUNIT_ASSERT_WITHIN_EQUAL_NULL(param, value1, value2, retcode) \ + do { \ + if ((param) < (value1) || (param) > (value2)) { \ + ICunitSaveErr(__LINE__, (iiUINT32)retcode); \ + return; \ + } \ + } while (0) + +#define ICUNIT_ASSERT_SIZE_STRING_EQUAL(str1, str2, strsize, retcode) \ + do { \ + if (strncmp((str1), (str2), (strsize)) != 0) { \ + ICunitSaveErr(__LINE__, (iiUINT32)retcode); \ + return 1; \ + } \ + } while (0) + +#define ICUNIT_ASSERT_EQUAL_TIME(param, g_value, retcode, label) \ + do { \ + if ((param) < (g_value - 1) || (param) > (g_value + 1)) { \ + ICunitSaveErr(__LINE__, (iiUINT32)retcode); \ + goto label; \ + } \ + } while (0) + +#define ICUNIT_ASSERT_STRING_EQUAL(str1, str2, retcode) \ + do { \ + if (strcmp(str1, str2) != 0) { \ + ICunitSaveErr(__LINE__, (iiUINT32)retcode); \ + return 1; \ + } \ + } while (0) + +#define ICUNIT_ASSERT_STRING_EQUAL_VOID(str1, str2, retcode) \ + do { \ + if (strcmp(str1, str2) != 0) { \ + ICunitSaveErr(__LINE__, (iiUINT32)retcode); \ + return; \ + } \ + } while (0) + +#define ICUNIT_ASSERT_STRING_NOT_EQUAL(str1, str2, retcode) \ + do { \ + if (strcmp(str1, str2) == 0) { \ + ICunitSaveErr(__LINE__, (iiUINT32)retcode); \ + return 1; \ + } \ + } while (0) + +#define ICUNIT_GOTO_EQUAL(param, g_value, retcode, label) \ + do { \ + if ((param) != (g_value)) { \ + ICunitSaveErr(__LINE__, (iiUINT32)retcode); \ + goto label; \ + } \ + } while (0) + +#define ICUNIT_GOTO_EQUAL_IN(param, value1, value2, retcode, label) \ + do { \ + if (((param) != (value1)) && ((param) != (value2))) { \ + ICunitSaveErr(__LINE__, (iiUINT32)retcode); \ + goto label; \ + } \ + } while (0) + +#define ICUNIT_GOTO_NOT_EQUAL(param, g_value, retcode, label) \ + do { \ + if ((param) == (g_value)) { \ + ICunitSaveErr(__LINE__, (iiUINT32)retcode); \ + goto label; \ + } \ + } while (0) + +#define ICUNIT_GOTO_WITHIN_EQUAL(param, value1, value2, retcode, label) \ + do { \ + if ((param) < (value1) || (param) > (value2)) { \ + ICunitSaveErr(__LINE__, (iiUINT32)retcode); \ + goto label; \ + } \ + } while (0) + +#define ICUNIT_GOTO_STRING_EQUAL(str1, str2, retcode, label) \ + do { \ + if (strcmp(str1, str2) != 0) { \ + ICunitSaveErr(__LINE__, (iiUINT32)retcode); \ + goto label; \ + } \ + } while (0) + +#define ICUNIT_GOTO_STRING_NOT_EQUAL(str1, str2, retcode, label) \ + do { \ + if (strcmp(str1, str2) == 0) { \ + ICunitSaveErr(__LINE__, (iiUINT32)retcode); \ + goto label; \ + } \ + } while (0) + +#ifdef LOSCFG_KERNEL_SMP +extern SPIN_LOCK_S g_testSuitSpin; +#define TESTSUIT_LOCK(state) LOS_SpinLockSave(&g_testSuitSpin, &(state)) +#define TESTSUIT_UNLOCK(state) LOS_SpinUnlockRestore(&g_testSuitSpin, state) +#endif + +extern iUINT32 iCunitAddSuit_F(iCHAR *suitName, iCHAR *pfileName); +#define iCunitAddSuit(suitName) iCunitAddSuit_F(suitName, __FILE__) +extern iUINT32 ICunitAddCase(const iCHAR *caseName, CASE_FUNCTION caseFunc, iUINT16 testcaseLayer, + iUINT16 testcaseModule, iUINT16 testcaseLevel, iUINT16 testcaseType); + +extern iUINT32 ICunitRunTestOne(const char *tcId); +extern INT32 ICunitRunTestArray(const char *tcSequence, const char *tcNum, const char *tcLayer, const char *tcModule, + const char *tcLevel, const char *tcType); +extern iUINT32 ICunitRunTestArraySequence(iUINT32 testcaseNum, iUINT32 testcaseLayer, iUINT32 testcaseModule, + iUINT32 testcaseLevel, iUINT32 testcaseType); +extern iUINT32 ICunitRunTestArrayRandom(iUINT32 testcaseNum, iUINT32 testcaseLayer, iUINT32 testcaseModule, + iUINT32 testcaseLevel, iUINT32 testcaseType); +extern iUINT32 ICunitRunTestcaseSatisfied(ICUNIT_CASE_S *testCase, iUINT32 testcaseLayer, iUINT32 testcaseModule, + iUINT32 testcaseLevel, iUINT32 testcaseType); + +extern iUINT32 ICunitInit(void); +extern iUINT32 ICunitRunSingle(ICUNIT_CASE_S *psubCase); +extern iUINT32 ICunitRunF(ICUNIT_CASE_S *psubCase); + +extern iUINT32 iCunitPrintReport(void); + + +#define TEST_ADD_CASE(name, casefunc, testcase_layer, testcase_module, testcase_level, testcase_type) \ +do { \ + iUINT32 uwRet = 1; \ + uwRet = ICunitAddCase(name, (CASE_FUNCTION)casefunc, testcase_layer, testcase_module, testcase_level, \ + testcase_type); \ + ICUNIT_ASSERT_EQUAL_VOID(uwRet, ICUNIT_SUCCESS, uwRet); \ + } while (0) + +#define TEST_RUN_SUITE() \ +do { \ + UINT32 uiRet; \ + uiRet = iCunitRun(); \ + ICUNIT_ASSERT_NOT_EQUAL_VOID(uiRet, ICUNIT_UNINIT, ICUNIT_UNINIT); \ + } while (0) + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#endif /* _UNI_ICUNIT_H */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/include/iCunit.inc b/src/kernel_liteos_a/testsuites/kernel/include/iCunit.inc new file mode 100644 index 00000000..9ad1f18b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/include/iCunit.inc @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _ICUNIT_ICUNIT_INC +#define _ICUNIT_ICUNIT_INC + +#include "iCunit_config.h" +#include "los_builddef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +ICUNIT_CASE_S g_iCunitRandArray[1]; +ICUNIT_CASE_S g_iCunitCaseArray[ICUNIT_CASE_SIZE]; + +iUINT32 g_iCunitInitSuccess = 0x0000FFFF; +iUINT32 g_iCunitCaseCnt = 0xFFFF; +iUINT32 g_iCunitCaseFailedCnt = 0; +iUINT32 g_iCunitErrLogAddCase = 0; + +iUINT16 g_iCunitErrLineNo; +iiUINT32 g_iCunitErrCode; + +iUINT32 g_iCunitCaseRun = 0; + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +#endif /* _UNI_ICUNIT_INC */ diff --git a/src/kernel_liteos_a/testsuites/kernel/include/iCunit_config.h b/src/kernel_liteos_a/testsuites/kernel/include/iCunit_config.h new file mode 100644 index 00000000..dc128734 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/include/iCunit_config.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_builddef.h" +#ifndef _ICUNIT_CONFIG_H +#define _ICUNIT_CONFIG_H + +#include "los_builddef.h" +#include "los_config.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#if defined(LITEOS_TEST_AUTO) && !defined(LOSCFG_TEST_MUTIL) +#define ICUNIT_CASE_SIZE LOSCFG_BASE_CORE_TSK_LIMIT +#else +#define ICUNIT_CASE_SIZE 20000 +#endif + +#define ICUNIT_SUIT_SIZE 1 + + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#endif diff --git a/src/kernel_liteos_a/testsuites/kernel/include/los_test_pri.h b/src/kernel_liteos_a/testsuites/kernel/include/los_test_pri.h new file mode 100644 index 00000000..b7b8de4e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/include/los_test_pri.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_TEST_PRI_H +#define _LOS_TEST_PRI_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +extern UINT32 TestSystemInit(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_TEST_PRI_H */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/include/osTest.h b/src/kernel_liteos_a/testsuites/kernel/include/osTest.h new file mode 100644 index 00000000..3486e4b1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/include/osTest.h @@ -0,0 +1,379 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _OSTEST_H +#define _OSTEST_H + +#ifndef SWTMR_TEST +#define SWTMR_TEST +#endif + +#include "stdarg.h" +#include "los_config.h" +#include "iCunit.h" +#include "stdio.h" +#include "stdlib.h" +#include "limits.h" +#include "string.h" +#include "los_base.h" +#include "los_config.h" +#include "los_typedef.h" +#include "los_hwi.h" +#include "los_vm_map.h" +#include "los_task.h" +#include "los_sched_pri.h" +#include "los_task_pri.h" +#include "los_sys_pri.h" +#include "los_sem_pri.h" +#include "los_event.h" +#include "los_memory.h" +#include "los_queue.h" +#include "los_swtmr.h" +#include "los_mux.h" +#include "los_queue_pri.h" +#include "los_atomic.h" +#if !defined(TEST1980) && !defined(TESTISP) +#include "console.h" +#endif + +#ifndef LOSCFG_AARCH64 +#ifdef LOSCFG_LIB_LIBC +#include "time.h" +#endif +#include "target_config.h" +#endif +#include "los_process_pri.h" +#include "pthread.h" + +#define LOSCFG_TEST 1 +#ifdef LOSCFG_PLATFORM_HI3516DV300 +#define TEST3516DV300 +#elif LOSCFG_PLATFORM_HI3518EV300 +#define TEST3518EV300 +#endif + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#define TEST_TASK_PARAM_INIT(testTask, task_name, entry, prio) \ + do { \ + (void)memset_s(&(testTask), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); \ + testTask.pfnTaskEntry = (TSK_ENTRY_FUNC)entry; \ + testTask.uwStackSize = 0x1000; \ + testTask.pcName = task_name; \ + testTask.usTaskPrio = prio; \ + testTask.uwResved = LOS_TASK_STATUS_DETACHED; \ + } while (0); + +#ifdef LOSCFG_KERNEL_SMP +#define TEST_TASK_PARAM_INIT_AFFI(testTask, task_name, entry, prio, affi) \ + TEST_TASK_PARAM_INIT(testTask, task_name, entry, prio) \ + testTask.usCpuAffiMask = affi; +#else +#define TEST_TASK_PARAM_INIT_AFFI(stTestTask, task_name, entry, prio, affi) \ + TEST_TASK_PARAM_INIT(stTestTask, task_name, entry, prio) +#endif +#define JFFS_BASE_MTD_ADDR 0x100000 +#define JFFS_BASE_MTD_LEN 0x600000 + + +#define TASK_PRIO_TEST (LOS_TaskPriGet(LOS_CurTaskIDGet())) // 25 +#define TASK_PRIO_TEST_TASK 25 +#define TASK_PRIO_TEST_SWTMR 4 +#ifdef LOSCFG_AARCH64 +#define TASK_STACK_SIZE_TEST (LOS_TASK_MIN_STACK_SIZE * 3) +#else +#define TASK_STACK_SIZE_TEST LOS_TASK_MIN_STACK_SIZE +#endif +#define LOS_MS_PER_TICK (OS_SYS_MS_PER_SECOND / LOSCFG_BASE_CORE_TICK_PER_SECOND) +#define LOS_US_PER_TICK (OS_SYS_US_PER_SECOND / LOSCFG_BASE_CORE_TICK_PER_SECOND) + +#define HWI_NUM_INTVALID OS_HWI_MAX_NUM +#define writel(g_value, address) WRITE_UINT32(g_value, address) +#ifdef TESTPBXA9 +extern int vsnprintf(char *str, size_t n, const char *fmt, va_list ap); +#endif + +#if defined(LOSCFG_TEST_POSIX) +extern UINT32 PosixPthreadInit(pthread_attr_t *attr, int pri); +extern UINT32 PosixPthreadDestroy(pthread_attr_t *attr, pthread_t thread); +#endif + +extern UINT32 TaskCountGetTest(VOID); +extern UINT32 SemCountGetTest(VOID); +extern UINT32 QueueCountGetTest(VOID); +extern UINT32 SwtmrCountGetTest(VOID); +extern void hal_interrupt_set_affinity(uint32_t irq, uint32_t cpuMask); + +#define TASK_EXISTED_NUM (TaskCountGetTest()) +#define QUEUE_EXISTED_NUM (QueueCountGetTest()) +#define SWTMR_EXISTED_NUM (SwtmrCountGetTest()) +#define SEM_EXISTED_NUM (SemCountGetTest()) + +extern void TestTestHwiDelete(unsigned int irq, void *devId); +extern void TestHwiTrigger(unsigned int irq); +extern void TestExtraTaskDelay(UINT32 tick); +extern UINT64 TestTickCountGet(void); +extern UINT64 TestTickCountByCurrCpuid(void); +extern void TestBusyTaskDelay(UINT32 tick); +extern void *malloc(size_t size); +extern void TestDumpCpuid(void); +extern u_long TRandom(void); + +#define TEST_HwiDelete(ID) TestTestHwiDelete(ID, NULL) +#define TEST_HwiClear(ID) HalIrqMask(ID) +#define TEST_HwiTriggerDelay LOS_TaskDelay(200 * LOSCFG_BASE_CORE_TICK_PER_SECOND / 1000) +#define TEST_HwiCreate(ID, prio, mode, Func, arg) LOS_HwiCreate(ID, prio, mode, Func, arg) + + +#define HWI_NUM_INT0 0 +#define HWI_NUM_INT1 1 +#define HWI_NUM_INT2 2 +#define HWI_NUM_INT3 3 +#define HWI_NUM_INT4 4 +#define HWI_NUM_INT5 5 +#define HWI_NUM_INT6 6 +#define HWI_NUM_INT7 7 +#define HWI_NUM_INT11 11 +#define HWI_NUM_INT12 12 +#define HWI_NUM_INT13 13 +#define HWI_NUM_INT14 14 +#define HWI_NUM_INT15 15 +#define HWI_NUM_INT16 16 +#define HWI_NUM_INT17 17 +#define HWI_NUM_INT18 18 +#define HWI_NUM_INT19 19 +#define HWI_NUM_INT21 21 +#define HWI_NUM_INT22 22 +#define HWI_NUM_INT23 23 +#define HWI_NUM_INT24 24 +#define HWI_NUM_INT25 25 +#define HWI_NUM_INT26 26 +#define HWI_NUM_INT27 27 +#define HWI_NUM_INT28 28 +#define HWI_NUM_INT30 30 +#define HWI_NUM_INT31 31 +#define HWI_NUM_INT32 32 +#define HWI_NUM_INT33 33 +#define HWI_NUM_INT34 34 +#define HWI_NUM_INT35 35 +#define HWI_NUM_INT42 42 +#define HWI_NUM_INT45 45 +#define HWI_NUM_INT46 46 +#define HWI_NUM_INT50 50 +#define HWI_NUM_INT55 55 +#define HWI_NUM_INT56 56 +#define HWI_NUM_INT57 57 +#define HWI_NUM_INT58 58 +#define HWI_NUM_INT59 59 +#define HWI_NUM_INT60 60 +#define HWI_NUM_INT61 61 +#define HWI_NUM_INT63 63 +#define HWI_NUM_INT62 62 +#define HWI_NUM_INT68 68 +#define HWI_NUM_INT69 69 + +#define HWI_NUM_INT95 95 +#define HWI_NUM_INT114 114 +#define HWI_NUM_INT169 169 + +#if defined TESTPBXA9 +#define HWI_NUM_TEST HWI_NUM_INT56 +#define HWI_NUM_TEST1 HWI_NUM_INT57 +#define HWI_NUM_TEST0 HWI_NUM_INT58 +#define HWI_NUM_TEST2 HWI_NUM_INT59 +#define HWI_NUM_TEST3 HWI_NUM_INT60 +#elif defined TEST3518EV300 +#define HWI_NUM_TEST0 HWI_NUM_INT58 +#define HWI_NUM_TEST HWI_NUM_INT59 +#define HWI_NUM_TEST1 HWI_NUM_INT60 +#define HWI_NUM_TEST2 HWI_NUM_INT61 +#define HWI_NUM_TEST3 HWI_NUM_INT68 +#elif defined TEST3516DV300 +#define HWI_NUM_TEST HWI_NUM_INT56 +#define HWI_NUM_TEST1 HWI_NUM_INT57 +#define HWI_NUM_TEST0 HWI_NUM_INT58 +#define HWI_NUM_TEST2 HWI_NUM_INT59 +#define HWI_NUM_TEST3 HWI_NUM_INT60 +#endif + +#define TEST_TASKDELAY_1TICK 1 +#define TEST_TASKDELAY_2TICK 2 +#define TEST_TASKDELAY_4TICK 4 +#define TEST_TASKDELAY_10TICK 10 +#define TEST_TASKDELAY_20TICK 20 +#define TEST_TASKDELAY_50TICK 50 + +#ifdef TEST3731 +#define TestTimer2ValueGet(temp) READ_UINT32(temp, TIMER1_REG_BASE + TIMER_VALUE) +#elif defined TEST3559 +#define TestTimer2ValueGet(temp) READ_UINT32(temp, TIMER3_REG_BASE + TIMER_VALUE) +#else +#define TestTimer2ValueGet(temp) READ_UINT32(temp, TIMER2_REG_BASE + TIMER_VALUE) +#endif + +#define REALTIME(time) (UINT32)((UINT64)(0xffffffff - time) * 1000 / OS_SYS_CLOCK) /* accuracy:ms */ +#define HW_TMI(time) (UINT32)((UINT64)(0xffffffff - time) * 1000 / (OS_SYS_CLOCK / 1000000)) /* accuracy:ns */ + +#define uart_printf_func dprintf + +#ifndef VFS_STAT_PRINTF +#define VFS_STAT_PRINTF 0 +#endif + +#ifndef VFS_STATFS_PRINTF +#define VFS_STATFS_PRINTF 0 +#endif + +#define OPEN_FILE_MAX 20 + +#define HUAWEI_ENV_NFS 0 + +#ifndef TEST_RESOURCELEAK_CHECK +#define TEST_RESOURCELEAK_CHECK 1 +#endif + +#ifndef TEST_MODULE_CHECK +#define TEST_MODULE_CHECK 1 +#endif + +#define OS_PROCESS_STATUS_PEND OS_PROCESS_STATUS_PENDING +#define OS_TASK_STATUS_SUSPEND OS_TASK_STATUS_SUSPENDED +#define OS_TASK_STATUS_PEND OS_TASK_STATUS_PENDING + +extern UINT32 volatile g_testCount; +extern UINT32 g_testCount1; +extern UINT32 g_testCount2; +extern UINT32 g_testCount3; +extern UINT32 g_flowcheck; +extern UINT32 g_failResult; +extern UINT32 g_passResult; +extern UINT32 g_testTskHandle; +extern UINT32 g_testTaskID01; +extern UINT32 g_testTaskID02; +extern UINT32 g_testTaskID03; +extern UINT32 g_testTaskID04; +extern UINT32 g_hwiNum1; +extern UINT32 g_hwiNum2; +extern UINT32 g_semID; +extern UINT32 g_semID2; +extern LosMux g_mutexkernelTest; +extern UINT32 g_cpupTestCount; +extern UINT16 g_swTmrID; +extern UINT32 g_semID; +extern UINT32 g_testQueueID01; +extern UINT32 g_testQueueID02; +extern UINT32 g_testQueueID03; +extern UINT32 g_testTskHandle; +extern UINT32 g_leavingTaskNum; +extern UINT32 g_semID3[]; +extern EVENT_CB_S g_eventCB; +extern EVENT_CB_S g_event; +extern UINT32 g_testPeriod; +extern BOOL g_isAddArray; +extern BOOL g_isSdInit; +extern BOOL g_isSpinorInit; +extern UINT32 g_getTickConsume; +extern UINT32 g_waitTestCount; +extern INT32 g_libFileSystem; +extern UINT32 LosMuxCreate(LosMux *mutex); +extern INT32 g_performanceStart; + +extern void msleep(unsigned int msecs); +extern unsigned int sleep(unsigned int seconds); +extern int usleep(unsigned useconds); + +#define OS_TASK_STATUS_DETACHED 0 +extern UINT32 LOS_MemTotalUsedGet(VOID *pool); +extern VOID ptestTickConsume(VOID); +extern UINT32 TEST_TskDelete(UINT32 taskID); +extern UINT32 TEST_SemDelete(UINT32 semHandle); + +extern VOID ItSuiteLosQueue(VOID); +extern VOID ItSuiteLosSwtmr(VOID); +extern VOID ItSuiteLosTask(VOID); +extern VOID ItSuiteLosEvent(VOID); + +extern VOID ItSuiteLosMux(VOID); +extern VOID ItSuiteLosRwlock(VOID); +extern VOID ItSuiteLosSem(VOID); +extern VOID ItSuiteSmpHwi(VOID); +extern VOID ItSuiteHwiNesting(VOID); + +extern VOID ItSuiteExtendCpup(VOID); + +extern VOID ItSuitePosixMutex(VOID); +extern VOID ItSuitePosixPthread(VOID); + +extern VOID TestRunShell(VOID); + +extern void TestSystemInit(void); + +extern void TEST_DT_COMMON(void); +extern VOID dprintf(const char *fmt, ...); + +extern UINT32 OsSwtmrTaskIDGetByCpuid(UINT16 cpuid); + +#define BIG_FD 512 +typedef struct testrunParam { + CHAR testcase_sequence[16]; + CHAR testcase_num[16]; + CHAR testcase_layer[32]; + CHAR testcase_module[32]; + CHAR testcase_level[16]; + CHAR testcase_type[16]; + CHAR testcase_id[128]; +} TEST_RUN_PARAM; + +#define LOSCFG_BASE_CORE_TSK_CONFIG LOSCFG_BASE_CORE_TSK_LIMIT +#define LOSCFG_BASE_IPC_SEM_CONFIG LOSCFG_BASE_IPC_SEM_LIMIT +#define LOSCFG_BASE_IPC_QUEUE_CONFIG LOSCFG_BASE_IPC_QUEUE_LIMIT +#define LOSCFG_BASE_CORE_SWTMR_CONFIG LOSCFG_BASE_CORE_SWTMR_LIMIT + +#define HAL_READ_UINT8(addr, data) READ_UINT8(data, addr) +#define HAL_WRITE_UINT8(addr, data) WRITE_UINT8(data, addr) +#define HAL_READ_UINT32(addr, data) READ_UINT32(data, addr) +#define HAL_WRITE_UINT32(addr, data) WRITE_UINT32(data, addr) + +extern void InitRebootHook(void); + +#define LOSCFG_TEST_SMOKE +#define LOSCFG_TEST_FULL +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#endif /* _OSTEST_H */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/BUILD.gn b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/BUILD.gn new file mode 100644 index 00000000..8fc1e6f8 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/BUILD.gn @@ -0,0 +1,37 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +group("kernel_base") { + deps = [ + "core:test_core", + "ipc:test_ipc", + ] +} diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/BUILD.gn b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/BUILD.gn new file mode 100644 index 00000000..075fd3ab --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/BUILD.gn @@ -0,0 +1,264 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/liteos.gni") + +kernel_module("test_core") { + sources = [ + "swtmr/It_los_swtmr.c", + "swtmr/full/It_los_swtmr_001.c", + "swtmr/full/It_los_swtmr_002.c", + "swtmr/full/It_los_swtmr_003.c", + "swtmr/full/It_los_swtmr_005.c", + "swtmr/full/It_los_swtmr_006.c", + "swtmr/full/It_los_swtmr_007.c", + "swtmr/full/It_los_swtmr_008.c", + "swtmr/full/It_los_swtmr_009.c", + "swtmr/full/It_los_swtmr_010.c", + "swtmr/full/It_los_swtmr_011.c", + "swtmr/full/It_los_swtmr_012.c", + "swtmr/full/It_los_swtmr_013.c", + "swtmr/full/It_los_swtmr_014.c", + "swtmr/full/It_los_swtmr_015.c", + "swtmr/full/It_los_swtmr_016.c", + "swtmr/full/It_los_swtmr_017.c", + "swtmr/full/It_los_swtmr_018.c", + "swtmr/full/It_los_swtmr_019.c", + "swtmr/full/It_los_swtmr_020.c", + "swtmr/full/It_los_swtmr_021.c", + "swtmr/full/It_los_swtmr_030.c", + "swtmr/full/It_los_swtmr_036.c", + "swtmr/full/It_los_swtmr_037.c", + "swtmr/full/It_los_swtmr_042.c", + "swtmr/full/It_los_swtmr_044.c", + "swtmr/full/It_los_swtmr_045.c", + "swtmr/full/It_los_swtmr_046.c", + "swtmr/full/It_los_swtmr_047.c", + "swtmr/full/It_los_swtmr_048.c", + "swtmr/full/It_los_swtmr_049.c", + "swtmr/full/It_los_swtmr_050.c", + "swtmr/full/It_los_swtmr_051.c", + "swtmr/full/It_los_swtmr_052.c", + "swtmr/full/It_los_swtmr_054.c", + "swtmr/full/It_los_swtmr_055.c", + "swtmr/full/It_los_swtmr_056.c", + "swtmr/full/It_los_swtmr_057.c", + "swtmr/full/It_los_swtmr_059.c", + "swtmr/full/It_los_swtmr_061.c", + "swtmr/full/It_los_swtmr_062.c", + "swtmr/full/It_los_swtmr_063.c", + "swtmr/full/It_los_swtmr_066.c", + "swtmr/full/It_los_swtmr_067.c", + "swtmr/full/It_los_swtmr_068.c", + "swtmr/full/It_los_swtmr_069.c", + "swtmr/full/It_los_swtmr_070.c", + "swtmr/full/It_los_swtmr_071.c", + "swtmr/full/It_los_swtmr_075.c", + "swtmr/full/It_los_swtmr_076.c", + "swtmr/full/It_los_swtmr_077.c", + "swtmr/full/It_los_swtmr_078.c", + "swtmr/smoke/It_los_swtmr_053.c", + "swtmr/smoke/It_los_swtmr_058.c", + "swtmr/smp/It_smp_los_swtmr_001.c", + "swtmr/smp/It_smp_los_swtmr_002.c", + "swtmr/smp/It_smp_los_swtmr_003.c", + "swtmr/smp/It_smp_los_swtmr_004.c", + "swtmr/smp/It_smp_los_swtmr_005.c", + "swtmr/smp/It_smp_los_swtmr_006.c", + "swtmr/smp/It_smp_los_swtmr_007.c", + "swtmr/smp/It_smp_los_swtmr_008.c", + "swtmr/smp/It_smp_los_swtmr_009.c", + "swtmr/smp/It_smp_los_swtmr_010.c", + "swtmr/smp/It_smp_los_swtmr_011.c", + "swtmr/smp/It_smp_los_swtmr_012.c", + "swtmr/smp/It_smp_los_swtmr_013.c", + "swtmr/smp/It_smp_los_swtmr_014.c", + "swtmr/smp/It_smp_los_swtmr_015.c", + "swtmr/smp/It_smp_los_swtmr_016.c", + "swtmr/smp/It_smp_los_swtmr_017.c", + "swtmr/smp/It_smp_los_swtmr_018.c", + "swtmr/smp/It_smp_los_swtmr_019.c", + "swtmr/smp/It_smp_los_swtmr_020.c", + "swtmr/smp/It_smp_los_swtmr_021.c", + "swtmr/smp/It_smp_los_swtmr_022.c", + "swtmr/smp/It_smp_los_swtmr_023.c", + "swtmr/smp/It_smp_los_swtmr_024.c", + "swtmr/smp/It_smp_los_swtmr_025.c", + "swtmr/smp/It_smp_los_swtmr_026.c", + "swtmr/smp/It_smp_los_swtmr_027.c", + "swtmr/smp/It_smp_los_swtmr_028.c", + "swtmr/smp/It_smp_los_swtmr_029.c", + "swtmr/smp/It_smp_los_swtmr_030.c", + "swtmr/smp/It_smp_los_swtmr_031.c", + "swtmr/smp/It_smp_los_swtmr_032.c", + "swtmr/smp/It_smp_los_swtmr_033.c", + "swtmr/smp/It_smp_los_swtmr_034.c", + "swtmr/smp/It_smp_los_swtmr_035.c", + "task/It_los_task.c", + "task/smoke/It_los_task_045.c", + "task/smoke/It_los_task_046.c", + "task/smoke/It_los_task_049.c", + "task/smoke/It_los_task_081.c", + "task/smoke/It_los_task_089.c", + "task/smoke/It_los_task_097.c", + "task/smoke/It_los_task_099.c", + "task/smoke/It_los_task_101.c", + "task/smoke/It_los_task_105.c", + "task/smoke/It_los_task_timeslice_001.c", + "task/smp/It_smp_los_task_001.c", + "task/smp/It_smp_los_task_002.c", + "task/smp/It_smp_los_task_003.c", + "task/smp/It_smp_los_task_004.c", + "task/smp/It_smp_los_task_021.c", + "task/smp/It_smp_los_task_022.c", + "task/smp/It_smp_los_task_023.c", + "task/smp/It_smp_los_task_024.c", + "task/smp/It_smp_los_task_025.c", + "task/smp/It_smp_los_task_026.c", + "task/smp/It_smp_los_task_027.c", + "task/smp/It_smp_los_task_028.c", + "task/smp/It_smp_los_task_029.c", + "task/smp/It_smp_los_task_030.c", + "task/smp/It_smp_los_task_032.c", + "task/smp/It_smp_los_task_033.c", + "task/smp/It_smp_los_task_034.c", + "task/smp/It_smp_los_task_035.c", + "task/smp/It_smp_los_task_036.c", + "task/smp/It_smp_los_task_037.c", + "task/smp/It_smp_los_task_040.c", + "task/smp/It_smp_los_task_042.c", + "task/smp/It_smp_los_task_043.c", + "task/smp/It_smp_los_task_044.c", + "task/smp/It_smp_los_task_046.c", + "task/smp/It_smp_los_task_047.c", + "task/smp/It_smp_los_task_048.c", + "task/smp/It_smp_los_task_049.c", + "task/smp/It_smp_los_task_050.c", + "task/smp/It_smp_los_task_052.c", + "task/smp/It_smp_los_task_053.c", + "task/smp/It_smp_los_task_054.c", + "task/smp/It_smp_los_task_055.c", + "task/smp/It_smp_los_task_056.c", + "task/smp/It_smp_los_task_057.c", + "task/smp/It_smp_los_task_058.c", + "task/smp/It_smp_los_task_059.c", + "task/smp/It_smp_los_task_060.c", + "task/smp/It_smp_los_task_061.c", + "task/smp/It_smp_los_task_062.c", + "task/smp/It_smp_los_task_063.c", + "task/smp/It_smp_los_task_064.c", + "task/smp/It_smp_los_task_065.c", + "task/smp/It_smp_los_task_066.c", + "task/smp/It_smp_los_task_067.c", + "task/smp/It_smp_los_task_068.c", + "task/smp/It_smp_los_task_069.c", + "task/smp/It_smp_los_task_070.c", + "task/smp/It_smp_los_task_071.c", + "task/smp/It_smp_los_task_072.c", + "task/smp/It_smp_los_task_073.c", + "task/smp/It_smp_los_task_074.c", + "task/smp/It_smp_los_task_075.c", + "task/smp/It_smp_los_task_076.c", + "task/smp/It_smp_los_task_077.c", + "task/smp/It_smp_los_task_078.c", + "task/smp/It_smp_los_task_079.c", + "task/smp/It_smp_los_task_081.c", + "task/smp/It_smp_los_task_084.c", + "task/smp/It_smp_los_task_087.c", + "task/smp/It_smp_los_task_088.c", + "task/smp/It_smp_los_task_089.c", + "task/smp/It_smp_los_task_090.c", + "task/smp/It_smp_los_task_091.c", + "task/smp/It_smp_los_task_092.c", + "task/smp/It_smp_los_task_093.c", + "task/smp/It_smp_los_task_094.c", + "task/smp/It_smp_los_task_095.c", + "task/smp/It_smp_los_task_096.c", + "task/smp/It_smp_los_task_098.c", + "task/smp/It_smp_los_task_099.c", + "task/smp/It_smp_los_task_100.c", + "task/smp/It_smp_los_task_101.c", + "task/smp/It_smp_los_task_102.c", + "task/smp/It_smp_los_task_103.c", + "task/smp/It_smp_los_task_105.c", + "task/smp/It_smp_los_task_106.c", + "task/smp/It_smp_los_task_107.c", + "task/smp/It_smp_los_task_108.c", + "task/smp/It_smp_los_task_109.c", + "task/smp/It_smp_los_task_110.c", + "task/smp/It_smp_los_task_112.c", + "task/smp/It_smp_los_task_113.c", + "task/smp/It_smp_los_task_114.c", + "task/smp/It_smp_los_task_115.c", + "task/smp/It_smp_los_task_117.c", + "task/smp/It_smp_los_task_126.c", + "task/smp/It_smp_los_task_127.c", + "task/smp/It_smp_los_task_128.c", + "task/smp/It_smp_los_task_129.c", + "task/smp/It_smp_los_task_130.c", + "task/smp/It_smp_los_task_131.c", + "task/smp/It_smp_los_task_132.c", + "task/smp/It_smp_los_task_133.c", + "task/smp/It_smp_los_task_134.c", + "task/smp/It_smp_los_task_135.c", + "task/smp/It_smp_los_task_136.c", + "task/smp/It_smp_los_task_137.c", + "task/smp/It_smp_los_task_138.c", + "task/smp/It_smp_los_task_139.c", + "task/smp/It_smp_los_task_141.c", + "task/smp/It_smp_los_task_142.c", + "task/smp/It_smp_los_task_143.c", + "task/smp/It_smp_los_task_144.c", + "task/smp/It_smp_los_task_145.c", + "task/smp/It_smp_los_task_146.c", + "task/smp/It_smp_los_task_147.c", + "task/smp/It_smp_los_task_148.c", + "task/smp/It_smp_los_task_149.c", + "task/smp/It_smp_los_task_150.c", + "task/smp/It_smp_los_task_151.c", + "task/smp/It_smp_los_task_152.c", + "task/smp/It_smp_los_task_153.c", + "task/smp/It_smp_los_task_154.c", + "task/smp/It_smp_los_task_155.c", + "task/smp/It_smp_los_task_156.c", + "task/smp/It_smp_los_task_157.c", + "task/smp/It_smp_los_task_158.c", + "task/smp/It_smp_los_task_159.c", + "task/smp/It_smp_los_task_160.c", + "task/smp/It_smp_los_task_161.c", + ] + + include_dirs = [ + "task", + "swtmr", + ] + + public_configs = + [ "$LITEOSTOPDIR/testsuites/kernel:liteos_kernel_test_public" ] +} diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/Makefile b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/Makefile new file mode 100644 index 00000000..aa2a22eb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/Makefile @@ -0,0 +1,46 @@ + +include $(LITEOSTESTTOPDIR)/config.mk + +MODULE_NAME := coretest + +LOCAL_INCLUDE := \ + -I $(LITEOSTESTTOPDIR)/kernel/include \ + -I $(LITEOSTESTTOPDIR)/kernel/sample/kernel_base/core/task \ + -I $(LITEOSTESTTOPDIR)/kernel/sample/kernel_base/core/swtmr \ + -I $(LITEOSTESTTOPDIR)/kernel/sample/kernel_base/core/hwi \ + -I $(LITEOSTESTTOPDIR)/kernel/sample/kernel_base/core/hwi_nesting + +SRC_MODULES := task swtmr hwi hwi_nesting + +ifeq ($(LOSCFG_KERNEL_SMP), y) +SMP_MODULES := task/smp swtmr/smp hwi/smp task/float +endif + +ifeq ($(LOSCFG_TEST_LLT), y) +LLT_MODULES := task/llt swtmr/llt +endif + +ifeq ($(LOSCFG_TEST_PRESSURE), y) +PRESSURE_MODULES := task/pressure swtmr/pressure +endif + +ifeq ($(LOSCFG_TEST_SMOKE), y) +SMOKE_MODULES := task/smoke swtmr/smoke +endif + +ifeq ($(LOSCFG_TEST_FULL), y) +FULL_MODULES := task/full swtmr/full hwi_nesting/full +endif + +ifeq ($(LOSCFG_TEST_MANUAL_SHELL), y) +MANUAL_MODULES :=task/manual +endif + +LOCAL_MODULES := $(SRC_MODULES) $(LLT_MODULES) $(PRESSURE_MODULES) $(SMOKE_MODULES) $(FULL_MODULES) $(SMP_MODULES) $(MANUAL_MODULES) + +LOCAL_SRCS := $(foreach dir,$(LOCAL_MODULES),$(wildcard $(dir)/*.c)) +LOCAL_CHS := $(foreach dir,$(LOCAL_MODULES),$(wildcard $(dir)/*.h)) + +LOCAL_FLAGS := $(LOCAL_INCLUDE) -Wno-error + +include $(MODULE) diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/It_smp_hwi.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/It_smp_hwi.c new file mode 100644 index 00000000..68d45192 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/It_smp_hwi.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_smp_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +VOID ItSuiteSmpHwi(VOID) +{ +#ifdef LOSCFG_KERNEL_SMP + ItSmpLosHwi001(); + ItSmpLosHwi002(); + ItSmpLosHwi003(); + ItSmpLosHwi004(); + ItSmpLosHwi005(); + ItSmpLosHwi006(); + ItSmpLosHwi007(); + ItSmpLosHwi008(); + ItSmpLosHwi009(); + ItSmpLosHwi010(); + ItSmpLosHwi011(); + ItSmpLosHwi012(); + ItSmpLosHwi013(); + +#ifndef LOSCFG_NO_SHARED_IRQ + ItSmpLosHwiShare001(); + ItSmpLosHwiShare002(); + ItSmpLosHwiShare003(); + ItSmpLosHwiShare004(); + ItSmpLosHwiShare005(); + ItSmpLosHwiShare006(); + ItSmpLosHwiShare007(); + ItSmpLosHwiShare008(); + ItSmpLosHwiShare009(); + ItSmpLosHwiShare010(); +#endif + ItSmpLosHwiIpi001(); + ItSmpLosHwiIpi002(); + ItSmpLosHwiIpi003(); + ItSmpLosHwiIpi004(); + ItSmpLosHwiIpi005(); + + ItSmpLosHwiIpi006(); + ItSmpLosHwiIpi007(); + ItSmpLosHwiIpi008(); + + ItSmpLosHwiNest001(); + ItSmpLosHwiNest002(); + ItSmpLosHwiNest003(); + ItSmpLosHwiNest004(); + ItSmpLosHwiNest005(); + ItSmpLosHwiNest006(); + ItSmpLosHwiNest007(); + ItSmpLosHwiNest008(); +#endif +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, 1); + HalIrqSetAffinity(HWI_NUM_TEST1, 1); + HalIrqSetAffinity(HWI_NUM_TEST2, 1); + HalIrqSetAffinity(HWI_NUM_TEST3, 1); +#endif +} + + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/It_smp_hwi.h b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/It_smp_hwi.h new file mode 100644 index 00000000..403a64f4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/It_smp_hwi.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LOS_SMP_HWI_H +#define LOS_SMP_HWI_H + +#include "los_hwi.h" +#include "osTest.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#define LOOP 100 + +#if defined(LOSCFG_TEST_SMP) +VOID ItSmpLosHwi001(VOID); +VOID ItSmpLosHwi002(VOID); +VOID ItSmpLosHwi003(VOID); +VOID ItSmpLosHwi004(VOID); +VOID ItSmpLosHwi005(VOID); +VOID ItSmpLosHwi006(VOID); +VOID ItSmpLosHwi007(VOID); +VOID ItSmpLosHwi008(VOID); +VOID ItSmpLosHwi009(VOID); +VOID ItSmpLosHwi010(VOID); +VOID ItSmpLosHwi011(VOID); +VOID ItSmpLosHwi012(VOID); +VOID ItSmpLosHwi013(VOID); + +#ifndef LOSCFG_NO_SHARED_IRQ +VOID ItSmpLosHwiShare001(VOID); +VOID ItSmpLosHwiShare002(VOID); +VOID ItSmpLosHwiShare003(VOID); +VOID ItSmpLosHwiShare004(VOID); +VOID ItSmpLosHwiShare005(VOID); +VOID ItSmpLosHwiShare006(VOID); +VOID ItSmpLosHwiShare007(VOID); +VOID ItSmpLosHwiShare008(VOID); +VOID ItSmpLosHwiShare009(VOID); +VOID ItSmpLosHwiShare010(VOID); +#endif + +VOID ItSmpLosHwiIpi001(VOID); +VOID ItSmpLosHwiIpi002(VOID); +VOID ItSmpLosHwiIpi003(VOID); +VOID ItSmpLosHwiIpi004(VOID); +VOID ItSmpLosHwiIpi005(VOID); +VOID ItSmpLosHwiIpi006(VOID); +VOID ItSmpLosHwiIpi007(VOID); +VOID ItSmpLosHwiIpi008(VOID); + +VOID ItSmpLosHwiNest001(VOID); +VOID ItSmpLosHwiNest002(VOID); +VOID ItSmpLosHwiNest003(VOID); +VOID ItSmpLosHwiNest004(VOID); +VOID ItSmpLosHwiNest005(VOID); +VOID ItSmpLosHwiNest006(VOID); +VOID ItSmpLosHwiNest007(VOID); +VOID ItSmpLosHwiNest008(VOID); +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#endif /* LOS_SMP_HWI_H */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_001.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_001.c new file mode 100644 index 00000000..a60728b6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_001.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_smp_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#ifdef LOSCFG_KERNEL_SMP +static UINT32 g_testTimes; + +static VOID HwiF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static VOID TaskF01(void) +{ +#ifdef TEST1980 + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + TestHwiTrigger(HWI_NUM_TEST); + + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, testid; + + g_testCount = 0; + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_hwi_001_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + ret = LOS_TaskCreate(&testid, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); +EXIT: + TEST_HwiDelete(HWI_NUM_TEST); + return LOS_OK; +} + +VOID ItSmpLosHwi001(VOID) +{ + TEST_ADD_CASE("ItSmpLosHwi001", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_002.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_002.c new file mode 100644 index 00000000..bc8bbf94 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_002.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_smp_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#ifdef LOSCFG_KERNEL_SMP +static VOID HwiF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static VOID TaskF01(void) +{ +#ifdef TEST1980 + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(0)); +#endif + + TestHwiTrigger(HWI_NUM_TEST); + + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, testid, currCpuid; + + g_testCount = 0; + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_hwi_002_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // cross task + ret = LOS_TaskCreate(&testid, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + do { + __asm__ volatile("nop"); + } while (g_testCount != 1); + + TEST_HwiDelete(HWI_NUM_TEST); + return LOS_OK; +} + +VOID ItSmpLosHwi002(VOID) +{ + TEST_ADD_CASE("ItSmpLosHwi002", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_003.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_003.c new file mode 100644 index 00000000..c7cb8f1e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_003.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_smp_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#ifdef LOSCFG_KERNEL_SMP +static UINT32 g_testTimes; + +static VOID HwiF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static VOID TaskF01(void) +{ + UINT32 ret; + + TestDumpCpuid(); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); +#ifndef LOSCFG_NO_SHARED_IRQ + ICUNIT_ASSERT_EQUAL_VOID(ret, OS_ERRNO_HWI_SHARED_ERROR, ret); +#else + ICUNIT_ASSERT_EQUAL_VOID(ret, OS_ERRNO_HWI_ALREADY_CREATED, ret); +#endif + + return; + +EXIT: + TEST_HwiDelete(HWI_NUM_TEST); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, testid; + + g_testCount = 0; + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestDumpCpuid(); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_hwi_001_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(1); + +#ifdef TEST1980 + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + TestHwiTrigger(HWI_NUM_TEST); + + LOS_TaskDelay(1); + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); +EXIT: + TEST_HwiDelete(HWI_NUM_TEST); + return LOS_OK; +} + +VOID ItSmpLosHwi003(VOID) +{ + TEST_ADD_CASE("ItSmpLosHwi003", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_004.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_004.c new file mode 100644 index 00000000..8a6e5138 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_004.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_smp_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#ifdef LOSCFG_KERNEL_SMP +static UINT32 g_testTimes; + +static VOID HwiF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static VOID TaskF01(void) +{ + UINT32 ret; + + TestDumpCpuid(); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); +#ifndef LOSCFG_NO_SHARED_IRQ + ICUNIT_ASSERT_EQUAL_VOID(ret, OS_ERRNO_HWI_SHARED_ERROR, ret); +#else + ICUNIT_ASSERT_EQUAL_VOID(ret, OS_ERRNO_HWI_ALREADY_CREATED, ret); +#endif + + return; + +EXIT: + TEST_HwiDelete(HWI_NUM_TEST); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, testid, currCpuid; + + g_testCount = 0; + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TestDumpCpuid(); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_hwi_002_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // cross task + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(1); + +#ifdef TEST1980 + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + TestHwiTrigger(HWI_NUM_TEST); + + LOS_TaskDelay(1); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); +EXIT: + TEST_HwiDelete(HWI_NUM_TEST); + return LOS_OK; +} + +VOID ItSmpLosHwi004(VOID) +{ + TEST_ADD_CASE("ItSmpLosHwi004", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_005.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_005.c new file mode 100644 index 00000000..3811c4e1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_005.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_smp_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#ifdef LOSCFG_KERNEL_SMP + +static VOID HwiF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static VOID TaskF01(void) +{ + UINT32 ret; + + TestDumpCpuid(); + + TEST_HwiDelete(HWI_NUM_TEST); + + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, testid; + + g_testCount = 0; + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestDumpCpuid(); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_hwi_001_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(1); + +#ifdef TEST1980 + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + TestHwiTrigger(HWI_NUM_TEST); + + LOS_TaskDelay(1); + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); +EXIT: + TEST_HwiDelete(HWI_NUM_TEST); + + return LOS_OK; +} + +VOID ItSmpLosHwi005(VOID) +{ + TEST_ADD_CASE("ItSmpLosHwi005", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_006.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_006.c new file mode 100644 index 00000000..46c9eaca --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_006.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_smp_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#ifdef LOSCFG_KERNEL_SMP + +static VOID HwiF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static VOID TaskF01(void) +{ + UINT32 ret; + + TestDumpCpuid(); + + TEST_HwiDelete(HWI_NUM_TEST); + LOS_AtomicInc(&g_testCount); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, testid, currCpuid; + + g_testCount = 0; + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TestDumpCpuid(); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_hwi_002_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // cross task + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 1); // 100, Set the timeout of runtime; + +#ifdef TEST1980 + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + TestHwiTrigger(HWI_NUM_TEST); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); +EXIT: + TEST_HwiDelete(HWI_NUM_TEST); + return LOS_OK; +} + +VOID ItSmpLosHwi006(VOID) +{ + TEST_ADD_CASE("ItSmpLosHwi006", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_007.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_007.c new file mode 100644 index 00000000..1a901cc3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_007.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_smp_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#ifdef LOSCFG_KERNEL_SMP + +static VOID HwiF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static VOID TaskF01(void) +{ + UINT32 ret; + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + + return; +} + +static VOID TaskF02(void) +{ + UINT32 ret; +#ifdef TEST1980 + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + TestHwiTrigger(HWI_NUM_TEST); + + TestDumpCpuid(); + return; +} + + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(testTask, "it_hwi_007_task01", TaskF01, TASK_PRIO_TEST + 1); + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(1); + + TEST_TASK_PARAM_INIT(testTask, "it_hwi_007_task02", TaskF02, TASK_PRIO_TEST + 1); + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(1); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); +EXIT: + TEST_HwiDelete(HWI_NUM_TEST); + return LOS_OK; +} + +VOID ItSmpLosHwi007(VOID) +{ + TEST_ADD_CASE("ItSmpLosHwi007", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_008.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_008.c new file mode 100644 index 00000000..497d73eb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_008.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_smp_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#ifdef LOSCFG_KERNEL_SMP + +static UINT32 g_ret = 0; +static VOID HwiF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static VOID TaskF01(void) +{ + UINT32 ret; + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + g_ret |= ret; + TestDumpCpuid(); + + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, i, j; + + for (j = 0; j < LOOP; j++) { + g_testCount = 0; + g_ret = 0; + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_hwi_007_task01", TaskF01, TASK_PRIO_TEST + 1, + CPUID_TO_AFFI_MASK(i)); + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + LOS_TaskDelay(1); + +#ifdef TEST1980 + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + TestHwiTrigger(HWI_NUM_TEST); + + LOS_TaskDelay(1); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + ICUNIT_GOTO_NOT_EQUAL(g_ret, 0, g_ret, EXIT); + TEST_HwiDelete(HWI_NUM_TEST); + } + +EXIT: + LOS_TaskDelete(g_testTaskID01); + TEST_HwiDelete(HWI_NUM_TEST); + return LOS_OK; +} + +VOID ItSmpLosHwi008(VOID) +{ + TEST_ADD_CASE("ItSmpLosHwi008", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} + +#endif +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_009.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_009.c new file mode 100644 index 00000000..f1541a4e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_009.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_smp_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#ifdef LOSCFG_KERNEL_SMP + +static UINT32 g_ret = 0; +static VOID HwiF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static VOID TaskF01(void) +{ + UINT32 ret; + ret = LOS_HwiDelete(HWI_NUM_TEST, NULL); + g_ret |= ret; + TestDumpCpuid(); + + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, i, j; + + for (j = 0; j < LOOP; j++) { + g_testCount = 0; + g_ret = 0; + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_hwi_007_task01", TaskF01, TASK_PRIO_TEST + 1, + CPUID_TO_AFFI_MASK(i)); + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + LOS_TaskDelay(2); // 2, set delay time + +#ifdef TEST1980 + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + TestHwiTrigger(HWI_NUM_TEST); + + LOS_TaskDelay(1); + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + } +EXIT: + LOS_HwiDelete(HWI_NUM_TEST, NULL); + return LOS_OK; +} + +VOID ItSmpLosHwi009(VOID) +{ + TEST_ADD_CASE("ItSmpLosHwi009", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_010.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_010.c new file mode 100644 index 00000000..230ae933 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_010.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_smp_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#ifdef LOSCFG_KERNEL_SMP +static UINT32 g_szId[LOSCFG_KERNEL_CORE_NUM] = {0}; +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testCount); +} +static VOID HwiF01(void) +{ + UINT32 ret; + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)SwtmrF01, &g_szId[0], 0); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + TestDumpCpuid(); + return; +} +static VOID HwiF02(void) +{ + UINT32 ret; + + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)SwtmrF01, &g_szId[1], 0); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret, i; + + g_testCount = 0; + g_testPeriod = 10; // 10, Timeout interval of a periodic software timer. + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // curret cpu + + ret = LOS_HwiCreate(HWI_NUM_TEST1, 1, 0, (HWI_PROC_FUNC)HwiF02, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST1, CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % LOSCFG_KERNEL_CORE_NUM)); // other cpu + + for (i = 0; i < LOOP; i++) { +#ifndef TEST1980 + TestHwiTrigger(HWI_NUM_TEST1); + TestHwiTrigger(HWI_NUM_TEST); +#else + HalIrqSendIpi(CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % LOSCFG_KERNEL_CORE_NUM), HWI_NUM_TEST1); + HalIrqSendIpi(CPUID_TO_AFFI_MASK(ArchCurrCpuid()), HWI_NUM_TEST); +#endif + + LOS_TaskDelay(1); + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + ret = LOS_SwtmrDelete(g_szId[0]); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ret = LOS_SwtmrDelete(g_szId[1]); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + + ret = LOS_HwiDelete(HWI_NUM_TEST, NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ret = LOS_HwiDelete(HWI_NUM_TEST1, NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; + +EXIT: + LOS_SwtmrDelete(g_szId[0]); + LOS_SwtmrDelete(g_szId[1]); + LOS_HwiDelete(HWI_NUM_TEST, NULL); + LOS_HwiDelete(HWI_NUM_TEST1, NULL); + return LOS_OK; +} + +VOID ItSmpLosHwi010(VOID) +{ + TEST_ADD_CASE("ItSmpLosHwi010", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_011.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_011.c new file mode 100644 index 00000000..d58221d9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_011.c @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_smp_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#ifdef LOSCFG_KERNEL_SMP +static UINT32 g_szId[LOSCFG_KERNEL_CORE_NUM] = {0}; +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testCount); +} +static VOID HwiF01(void) +{ + UINT32 ret; + TEST_HwiClear(HWI_NUM_TEST); + ret = LOS_SwtmrStart(g_szId[0]); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + TestDumpCpuid(); + return; +EXIT: + LOS_HwiDelete(HWI_NUM_TEST, NULL); + LOS_HwiDelete(HWI_NUM_TEST1, NULL); + LOS_HwiDelete(HWI_NUM_TEST2, NULL); + LOS_HwiDelete(HWI_NUM_TEST3, NULL); + LOS_SwtmrDelete(g_szId[0]); + LOS_SwtmrDelete(g_szId[1]); + return; +} +static VOID HwiF02(void) +{ + UINT32 ret; + TEST_HwiClear(HWI_NUM_TEST1); + ret = LOS_SwtmrStart(g_szId[1]); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + TestDumpCpuid(); + return; +EXIT: + LOS_HwiDelete(HWI_NUM_TEST, NULL); + LOS_HwiDelete(HWI_NUM_TEST1, NULL); + LOS_HwiDelete(HWI_NUM_TEST2, NULL); + LOS_HwiDelete(HWI_NUM_TEST3, NULL); + LOS_SwtmrDelete(g_szId[0]); + LOS_SwtmrDelete(g_szId[1]); + return; +} +static VOID HwiF03(void) +{ + UINT32 ret; + TEST_HwiClear(HWI_NUM_TEST2); + ret = LOS_SwtmrStop(g_szId[1]); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + TestDumpCpuid(); + return; +EXIT: + LOS_HwiDelete(HWI_NUM_TEST, NULL); + LOS_HwiDelete(HWI_NUM_TEST1, NULL); + LOS_HwiDelete(HWI_NUM_TEST2, NULL); + LOS_HwiDelete(HWI_NUM_TEST3, NULL); + LOS_SwtmrDelete(g_szId[0]); + LOS_SwtmrDelete(g_szId[1]); + return; +} +static VOID HwiF04(void) +{ + UINT32 ret; + TEST_HwiClear(HWI_NUM_TEST3); + ret = LOS_SwtmrStop(g_szId[0]); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + TestDumpCpuid(); + return; +EXIT: + LOS_HwiDelete(HWI_NUM_TEST, NULL); + LOS_HwiDelete(HWI_NUM_TEST1, NULL); + LOS_HwiDelete(HWI_NUM_TEST2, NULL); + LOS_HwiDelete(HWI_NUM_TEST3, NULL); + LOS_SwtmrDelete(g_szId[0]); + LOS_SwtmrDelete(g_szId[1]); + return; +} +static UINT32 Testcase(void) +{ + UINT32 ret, i; + + g_testCount = 0; + g_testPeriod = 10; // 10, Timeout interval of a periodic software timer. + + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)SwtmrF01, &g_szId[0], 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)SwtmrF01, &g_szId[1], 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // curret cpu + + ret = LOS_HwiCreate(HWI_NUM_TEST1, 1, 0, (HWI_PROC_FUNC)HwiF02, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + HalIrqSetAffinity(HWI_NUM_TEST1, CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % LOSCFG_KERNEL_CORE_NUM)); // other cpu + + ret = LOS_HwiCreate(HWI_NUM_TEST2, 1, 0, (HWI_PROC_FUNC)HwiF03, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + HalIrqSetAffinity(HWI_NUM_TEST2, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // curret cpu + + ret = LOS_HwiCreate(HWI_NUM_TEST3, 1, 0, (HWI_PROC_FUNC)HwiF04, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + HalIrqSetAffinity(HWI_NUM_TEST3, CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % LOSCFG_KERNEL_CORE_NUM)); // other cpu + + for (i = 0; i < LOOP; i++) { +#ifndef TEST1980 + TestHwiTrigger(HWI_NUM_TEST1); // start swtmrs + TestHwiTrigger(HWI_NUM_TEST); +#else + HalIrqSendIpi(CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % LOSCFG_KERNEL_CORE_NUM), HWI_NUM_TEST1); + HalIrqSendIpi(CPUID_TO_AFFI_MASK(ArchCurrCpuid()), HWI_NUM_TEST); +#endif + LOS_TaskDelay(g_testPeriod + 1); + + ICUNIT_GOTO_EQUAL(g_testCount, 2 * (i + 1), g_testCount, EXIT); // 2 * (i + 1),Compared to the expected value. +#ifndef TEST1980 + TestHwiTrigger(HWI_NUM_TEST3); // stop swtmrs + TestHwiTrigger(HWI_NUM_TEST2); +#else + HalIrqSendIpi(CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % LOSCFG_KERNEL_CORE_NUM), HWI_NUM_TEST3); + HalIrqSendIpi(CPUID_TO_AFFI_MASK(ArchCurrCpuid()), HWI_NUM_TEST2); +#endif + LOS_TaskDelay(g_testPeriod + 1); + ICUNIT_GOTO_EQUAL(g_testCount, 2 * (i + 1), g_testCount, EXIT); // 2 * (i + 1),Compared to the expected value. + } +EXIT: + ret = LOS_HwiDelete(HWI_NUM_TEST, NULL); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ret = LOS_HwiDelete(HWI_NUM_TEST1, NULL); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ret = LOS_HwiDelete(HWI_NUM_TEST2, NULL); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ret = LOS_HwiDelete(HWI_NUM_TEST3, NULL); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrDelete(g_szId[0]); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ret = LOS_SwtmrDelete(g_szId[1]); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return LOS_OK; +} + +VOID ItSmpLosHwi011(VOID) +{ + TEST_ADD_CASE("ItSmpLosHwi011", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_012.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_012.c new file mode 100644 index 00000000..ae21951c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_012.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_smp_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#ifdef LOSCFG_KERNEL_SMP +static UINT32 g_szId[LOSCFG_KERNEL_CORE_NUM] = {0}; +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testCount); +} +static VOID HwiF01(void) +{ + UINT32 ret; + ret = LOS_SwtmrDelete(g_szId[0]); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + TestDumpCpuid(); + return; +} +static VOID HwiF02(void) +{ + UINT32 ret; + + ret = LOS_SwtmrDelete(g_szId[1]); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret, i; + + g_testCount = 0; + g_testPeriod = 10; // 10, Timeout interval of a periodic software timer. + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // curret cpu + + ret = LOS_HwiCreate(HWI_NUM_TEST1, 1, 0, (HWI_PROC_FUNC)HwiF02, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST1, CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % LOSCFG_KERNEL_CORE_NUM)); // other cpu + + for (i = 0; i < LOOP; i++) { + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)SwtmrF01, &g_szId[0], 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)SwtmrF01, &g_szId[1], 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_SwtmrStart(g_szId[0]); + LOS_SwtmrStart(g_szId[1]); + +#ifndef TEST1980 + TestHwiTrigger(HWI_NUM_TEST1); + TestHwiTrigger(HWI_NUM_TEST); +#else + HalIrqSendIpi(CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % LOSCFG_KERNEL_CORE_NUM), HWI_NUM_TEST1); + HalIrqSendIpi(CPUID_TO_AFFI_MASK(ArchCurrCpuid()), HWI_NUM_TEST); +#endif + LOS_TaskDelay(g_testPeriod + 1); + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + } + +EXIT: + ret = LOS_HwiDelete(HWI_NUM_TEST, NULL); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ret = LOS_HwiDelete(HWI_NUM_TEST1, NULL); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrDelete(g_szId[0]); + ICUNIT_GOTO_NOT_EQUAL(ret, LOS_OK, ret, EXIT); + ret = LOS_SwtmrDelete(g_szId[1]); + ICUNIT_GOTO_NOT_EQUAL(ret, LOS_OK, ret, EXIT); + + return LOS_OK; +} + +VOID ItSmpLosHwi012(VOID) +{ + TEST_ADD_CASE("ItSmpLosHwi012", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_013.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_013.c new file mode 100644 index 00000000..9b4604b3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_013.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_smp_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#ifdef LOSCFG_KERNEL_SMP + +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testCount); +} +static VOID HwiF01(void) +{ + UINT32 ret, i; + for (i = 0; i < TRandom() % 100; i++) { // Get a random number between 0 and 100 + } + + ret = LOS_SwtmrDelete(g_swTmrID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret, i, j; + + g_testCount = 0; + g_testPeriod = 10; // 10, Timeout interval of a periodic software timer. + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % LOSCFG_KERNEL_CORE_NUM)); // other cpu + + for (i = 0; i < LOOP; i++) { + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)SwtmrF01, &g_swTmrID, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestHwiTrigger(HWI_NUM_TEST); // delete swtmr in hwi on other cpu + + for (j = 0; j < TRandom() % 500; j++) { // Get a random number between 0 and 500 + LOS_SwtmrStart(g_swTmrID); // start swtmr in task on current cpu + } + + LOS_TaskDelay(g_testPeriod + 1); + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + } + +EXIT: + ret = LOS_HwiDelete(HWI_NUM_TEST, NULL); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrDelete(g_swTmrID); + ICUNIT_GOTO_NOT_EQUAL(ret, LOS_OK, ret, EXIT); + return LOS_OK; +} + +VOID ItSmpLosHwi013(VOID) +{ + TEST_ADD_CASE("ItSmpLosHwi013", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_ipi_001.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_ipi_001.c new file mode 100644 index 00000000..7507779e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_ipi_001.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_smp_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#ifdef LOSCFG_KERNEL_SMP +static UINT32 g_targetCpuid; + +static VOID HwiF01(void) +{ + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + ICUNIT_GOTO_EQUAL(ArchCurrCpuid(), g_targetCpuid, ArchCurrCpuid(), EXIT); + return; +EXIT: + TEST_HwiDelete(HWI_NUM_INT11); + return; +} + +static VOID TaskF01(void) +{ + HalIrqUnmask(HWI_NUM_INT11); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, testid; + UINT32 i; + + g_testCount = 0; + + g_targetCpuid = 0; + + HalIrqUnmask(HWI_NUM_INT11); + + ret = LOS_HwiCreate(HWI_NUM_INT11, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_hwi_001_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK((ArchCurrCpuid() + i + 1) % + LOSCFG_KERNEL_CORE_NUM)); // let current cpu 's task create at the last + ret = LOS_TaskCreate(&testid, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + g_targetCpuid = ArchCurrCpuid(); // currernt cpu + + PRINT_DEBUG("g_targetCpuid = %d\n", g_targetCpuid); + + LOS_TaskDelay(1); + + HalIrqSendIpi(g_targetCpuid + 1, HWI_NUM_INT11); // 01:0kernel,10:1kernel,11:0kernel& 1kernel + + LOS_TaskDelay(1); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); +EXIT: + TEST_HwiDelete(HWI_NUM_INT11); + return LOS_OK; +} + +VOID ItSmpLosHwiIpi001(VOID) +{ + TEST_ADD_CASE("ItSmpLosHwiIpi001", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_ipi_002.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_ipi_002.c new file mode 100644 index 00000000..054771aa --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_ipi_002.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_smp_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#ifdef LOSCFG_KERNEL_SMP +static UINT32 g_targetCpuid; + +static VOID HwiF01(void) +{ + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + ICUNIT_ASSERT_EQUAL_VOID(ArchCurrCpuid(), g_targetCpuid, ArchCurrCpuid()); +} + +static VOID TaskF01(void) +{ + HalIrqUnmask(HWI_NUM_INT11); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, testid; + UINT32 i; + + g_testCount = 0; + + g_targetCpuid = 0; + + ret = LOS_HwiCreate(HWI_NUM_INT11, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqUnmask(HWI_NUM_INT11); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_hwi_001_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK((ArchCurrCpuid() + i + 1) % + LOSCFG_KERNEL_CORE_NUM)); // let current cpu 's task create at the last + ret = LOS_TaskCreate(&testid, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + g_targetCpuid = (ArchCurrCpuid() + 1) % LOSCFG_KERNEL_CORE_NUM; // other cpu + + PRINT_DEBUG("g_targetCpuid = %d\n", g_targetCpuid); + + LOS_TaskDelay(1); + + HalIrqSendIpi(g_targetCpuid + 1, HWI_NUM_INT11); + + LOS_TaskDelay(1); + + TEST_HwiDelete(HWI_NUM_INT11); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + return LOS_OK; +} + +VOID ItSmpLosHwiIpi002(VOID) +{ + TEST_ADD_CASE("ItSmpLosHwiIpi002", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_ipi_003.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_ipi_003.c new file mode 100644 index 00000000..d7c82d16 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_ipi_003.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_smp_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#ifdef LOSCFG_KERNEL_SMP +static UINT32 g_targetCpuid; + +static VOID HwiF01(void) +{ + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + ICUNIT_ASSERT_EQUAL_VOID(ArchCurrCpuid(), g_targetCpuid, ArchCurrCpuid()); +} + +static VOID TaskF01(void) +{ + HalIrqUnmask(HWI_NUM_INT11); + + PRINT_DEBUG("g_targetCpuid = %d\n", g_targetCpuid); + + HalIrqSendIpi(g_targetCpuid + 1, HWI_NUM_INT11); + + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, testid, currCpuid; + UINT32 i; + + g_testCount = 0; + + g_targetCpuid = 0; + + ret = LOS_HwiCreate(HWI_NUM_INT11, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqUnmask(HWI_NUM_INT11); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + g_targetCpuid = currCpuid; // other cpu + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_hwi_001_task", TaskF01, TASK_PRIO_TEST - 1, CPUID_TO_AFFI_MASK(currCpuid)); + ret = LOS_TaskCreate(&testid, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(10); // 10, set delay time + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + TEST_HwiDelete(HWI_NUM_INT11); + return LOS_OK; +} + +VOID ItSmpLosHwiIpi003(VOID) +{ + TEST_ADD_CASE("ItSmpLosHwiIpi003", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_ipi_004.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_ipi_004.c new file mode 100644 index 00000000..b1ef1588 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_ipi_004.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_smp_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#ifdef LOSCFG_KERNEL_SMP +static UINT32 g_targetCpuid; + +static VOID HwiF01(void) +{ + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + ICUNIT_ASSERT_EQUAL_VOID(ArchCurrCpuid(), g_targetCpuid, ArchCurrCpuid()); +} + +static VOID TaskF01(void) +{ + HalIrqUnmask(HWI_NUM_INT11); + + PRINT_DEBUG("g_targetCpuid = %d\n", g_targetCpuid); + + HalIrqSendIpi(g_targetCpuid + 1, HWI_NUM_INT11); + + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, testid, currCpuid; + UINT32 i; + + g_testCount = 0; + + g_targetCpuid = 0; + + ret = LOS_HwiCreate(HWI_NUM_INT11, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqUnmask(HWI_NUM_INT11); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); // other cpu + + g_targetCpuid = ArchCurrCpuid(); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_hwi_001_task", TaskF01, TASK_PRIO_TEST - 1, CPUID_TO_AFFI_MASK(currCpuid)); + ret = LOS_TaskCreate(&testid, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(10); // 10, set delay time + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + TEST_HwiDelete(HWI_NUM_INT11); + return LOS_OK; +} + +VOID ItSmpLosHwiIpi004(VOID) +{ + TEST_ADD_CASE("ItSmpLosHwiIpi004", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_ipi_005.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_ipi_005.c new file mode 100644 index 00000000..03964fc9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_ipi_005.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_smp_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#ifdef LOSCFG_KERNEL_SMP +static UINT32 g_targetCpuid; + +static VOID HwiF01(void) +{ + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +EXIT: + TEST_HwiDelete(HWI_NUM_INT11); + return; +} + +static VOID TaskF01(void) +{ + HalIrqUnmask(HWI_NUM_INT11); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, testid; + UINT32 i; + + g_testCount = 0; + + g_targetCpuid = 0; + + HalIrqUnmask(HWI_NUM_INT11); + + ret = LOS_HwiCreate(HWI_NUM_INT11, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_hwi_001_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK((ArchCurrCpuid() + i + 1) % + LOSCFG_KERNEL_CORE_NUM)); // let current cpu 's task create at the last + ret = LOS_TaskCreate(&testid, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + g_targetCpuid = (1 << LOSCFG_KERNEL_CORE_NUM) - 1; // all cpu + + PRINT_DEBUG("g_targetCpuid = %d\n", g_targetCpuid); + + LOS_TaskDelay(1); + + HalIrqSendIpi(g_targetCpuid, HWI_NUM_INT11); + + LOS_TaskDelay(1); + + ICUNIT_GOTO_EQUAL(g_testCount, LOSCFG_KERNEL_CORE_NUM, g_testCount, EXIT); +EXIT: + TEST_HwiDelete(HWI_NUM_INT11); + return LOS_OK; +} + +VOID ItSmpLosHwiIpi005(VOID) +{ + TEST_ADD_CASE("ItSmpLosHwiIpi005", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_ipi_006.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_ipi_006.c new file mode 100644 index 00000000..4e4cc7b2 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_ipi_006.c @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_smp_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#ifdef LOSCFG_KERNEL_SMP +static UINT32 g_targetCpuid; + +static UINT32 g_szId[LOSCFG_KERNEL_CORE_NUM] = {0}; + +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testCount); +} +static VOID HwiF01(void) +{ + UINT32 ret, index; + index = ArchCurrCpuid(); + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)SwtmrF01, &g_szId[index], 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + + return; +EXIT: + TEST_HwiDelete(HWI_NUM_INT11); + return; +} + +static VOID TaskF01(void) +{ + HalIrqUnmask(HWI_NUM_INT11); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, testid; + UINT32 i, j; + + g_testCount = 0; + g_testPeriod = 10; // 10, Timeout interval of a periodic software timer. + g_targetCpuid = 0; + + HalIrqUnmask(HWI_NUM_INT11); + + g_targetCpuid = (1 << LOSCFG_KERNEL_CORE_NUM) - 1; // all cpu + + ret = LOS_HwiCreate(HWI_NUM_INT11, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_hwi_001_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK((ArchCurrCpuid() + i + 1) % + LOSCFG_KERNEL_CORE_NUM)); // let current cpu 's task create at the last + ret = LOS_TaskCreate(&testid, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + LOS_TaskDelay(1); + + for (j = 0; j < LOOP; j++) { + HalIrqSendIpi(g_targetCpuid, HWI_NUM_INT11); + + LOS_TaskDelay(1); + + ICUNIT_GOTO_EQUAL(g_testCount, LOSCFG_KERNEL_CORE_NUM * (j + 1), g_testCount, EXIT); + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + ret = LOS_SwtmrDelete(g_szId[i]); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + } + TEST_HwiDelete(HWI_NUM_INT11); + return LOS_OK; +EXIT: + TEST_HwiDelete(HWI_NUM_INT11); + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + LOS_SwtmrDelete(g_szId[i]); + } + return LOS_OK; +} + +VOID ItSmpLosHwiIpi006(VOID) +{ + TEST_ADD_CASE("ItSmpLosHwiIpi006", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_ipi_007.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_ipi_007.c new file mode 100644 index 00000000..6918fd91 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_ipi_007.c @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_smp_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#ifdef LOSCFG_KERNEL_SMP +static UINT32 g_targetCpuid; + +/* for debugging */ +STATIC UINT32 g_ipiTriggerTimes = 0; +STATIC UINT32 g_ipiRecieveTimes[LOSCFG_KERNEL_CORE_NUM] = { 0 }; + +static UINT32 g_szId[LOSCFG_KERNEL_CORE_NUM] = {0}; + +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testCount); +} +static VOID HwiF01(void) +{ + UINT32 ret, index; + index = ArchCurrCpuid(); + g_ipiRecieveTimes[index]++; + ret = LOS_SwtmrDelete(g_szId[index]); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + + return; +EXIT: + TEST_HwiDelete(HWI_NUM_INT11); + return; +} + +static VOID TaskF01(void) +{ + HalIrqUnmask(HWI_NUM_INT11); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, testid; + UINT32 i, j; + + g_testCount = 0; + g_testPeriod = 10; // 10, Timeout interval of a periodic software timer. + g_targetCpuid = 0; + + HalIrqUnmask(HWI_NUM_INT11); + + g_targetCpuid = (1 << LOSCFG_KERNEL_CORE_NUM) - 1; // all cpu + + ret = LOS_HwiCreate(HWI_NUM_INT11, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_hwi_001_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK((ArchCurrCpuid() + i + 1) % + LOSCFG_KERNEL_CORE_NUM)); // let current cpu 's task create at the last + ret = LOS_TaskCreate(&testid, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + LOS_TaskDelay(1); + + for (j = 0; j < LOOP; j++) { + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)SwtmrF01, &g_szId[i], 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + g_ipiTriggerTimes++; + HalIrqSendIpi(g_targetCpuid, HWI_NUM_INT11); + + LOS_TaskDelay(1); + PRINTK("sent %u time\n", g_ipiTriggerTimes); + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + PRINTK(" cpu%d received %u times\n", i, g_ipiRecieveTimes[i]); + } + + ICUNIT_GOTO_EQUAL(g_testCount, LOSCFG_KERNEL_CORE_NUM * (j + 1), g_testCount, EXIT); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + ret = LOS_SwtmrDelete(g_szId[i]); + ICUNIT_ASSERT_NOT_EQUAL(ret, LOS_OK, ret); + } + } + TEST_HwiDelete(HWI_NUM_INT11); + return LOS_OK; +EXIT: + TEST_HwiDelete(HWI_NUM_INT11); + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + PRINT_DEBUG("---%d---\n", g_szId[i]); + LOS_SwtmrDelete(g_szId[i]); + } + return LOS_OK; +} + +VOID ItSmpLosHwiIpi007(VOID) +{ + TEST_ADD_CASE("ItSmpLosHwiIpi007", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_ipi_008.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_ipi_008.c new file mode 100644 index 00000000..ccfe146c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_ipi_008.c @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_smp_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#ifdef LOSCFG_KERNEL_SMP +static UINT32 g_targetCpuid; + +static VOID SwtmrF01(void) +{ + LOS_AtomicDec(&g_testCount); +} +static VOID HwiF01(void) +{ + UINT32 ret, id; + + id = ArchCurrCpuid() % 3; // 3, Get the current CPU + switch (id) { + case 0: + LOS_SwtmrStart(g_swTmrID); + break; + case 1: + LOS_SwtmrDelete(g_swTmrID); + break; + case 2: // 2, when id is 2 + LOS_SwtmrStop(g_swTmrID); + break; + default: + break; + } + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static VOID TaskF01(void) +{ + HalIrqUnmask(HWI_NUM_INT11); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, testid; + UINT32 i; + + g_testCount = 0; + g_testPeriod = 10; // 10, Timeout interval of a periodic software timer. + g_targetCpuid = 0; + + HalIrqUnmask(HWI_NUM_INT11); + + ret = LOS_HwiCreate(HWI_NUM_INT11, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_hwi_001_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK((ArchCurrCpuid() + i + 1) % + LOSCFG_KERNEL_CORE_NUM)); // let current cpu 's task create at the last + ret = LOS_TaskCreate(&testid, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + g_targetCpuid = (1 << LOSCFG_KERNEL_CORE_NUM) - 1; // all cpu + + LOS_TaskDelay(1); + for (i = 0; i < LOOP; i++) { + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)SwtmrF01, &g_swTmrID, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSendIpi(g_targetCpuid, HWI_NUM_INT11); + + LOS_TaskDelay(1); + + ICUNIT_GOTO_EQUAL(g_testCount, LOSCFG_KERNEL_CORE_NUM * (i + 1), g_testCount, EXIT); + LOS_SwtmrDelete(g_swTmrID); + } + TEST_HwiDelete(HWI_NUM_INT11); + return LOS_OK; +EXIT: + TEST_HwiDelete(HWI_NUM_INT11); + LOS_SwtmrDelete(g_swTmrID); + return LOS_OK; +} + +VOID ItSmpLosHwiIpi008(VOID) +{ + TEST_ADD_CASE("ItSmpLosHwiIpi008", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_nest_001.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_nest_001.c new file mode 100644 index 00000000..8bd2d2f0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_nest_001.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_smp_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#ifdef LOSCFG_KERNEL_SMP +static UINT32 g_targetCpuid; + +static VOID HwiF02(void) +{ + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} +static VOID HwiF01(void) +{ + TestHwiTrigger(HWI_NUM_TEST); + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static VOID TaskF01(void) +{ + HalIrqUnmask(HWI_NUM_INT12); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, testid; + UINT32 i; + + g_testCount = 0; + g_testPeriod = 10; // 10, Timeout interval of a periodic software timer. + g_targetCpuid = 0; + + HalIrqUnmask(HWI_NUM_INT12); + ret = LOS_HwiCreate(HWI_NUM_INT12, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); // ipi + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF02, 0); // spi + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // curret cpu + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_hwi_001_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK((ArchCurrCpuid() + i + 1) % + LOSCFG_KERNEL_CORE_NUM)); // let current cpu 's task create at the last + ret = LOS_TaskCreate(&testid, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + g_targetCpuid = ArchCurrCpuid(); + HalIrqSendIpi(CPUID_TO_AFFI_MASK(g_targetCpuid), HWI_NUM_INT12); // currernt cpu; + + LOS_TaskDelay(1); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2,The expected value + + TEST_HwiDelete(HWI_NUM_INT12); + TEST_HwiDelete(HWI_NUM_TEST); + return LOS_OK; +EXIT: + TEST_HwiDelete(HWI_NUM_INT12); + TEST_HwiDelete(HWI_NUM_TEST); + return LOS_OK; +} + +VOID ItSmpLosHwiNest001(VOID) +{ + TEST_ADD_CASE("ItSmpLosHwiNest001", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_nest_002.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_nest_002.c new file mode 100644 index 00000000..4d8f9a27 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_nest_002.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_smp_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#ifdef LOSCFG_KERNEL_SMP +static UINT32 g_targetCpuid; +extern EVENT_CB_S g_event; +static VOID HwiF02(void) +{ + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} +static VOID HwiF01(void) +{ + TestHwiTrigger(HWI_NUM_TEST); + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static VOID TaskF01(void) +{ + HalIrqUnmask(HWI_NUM_INT12); + LOS_EventWrite(&g_event, 0x1 << (ArchCurrCpuid())); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, testid; + UINT32 i; + + g_testCount = 0; + g_testPeriod = 10; // 10, Timeout interval of a periodic software timer. + g_targetCpuid = 0; + LOS_EventInit(&g_event); + + HalIrqUnmask(HWI_NUM_INT12); + ret = LOS_HwiCreate(HWI_NUM_INT12, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); // ipi + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF02, 0); // spi + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // curret cpu + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_hwi_001_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK((ArchCurrCpuid() + i + 1) % + LOSCFG_KERNEL_CORE_NUM)); // let current cpu 's task create at the last + ret = LOS_TaskCreate(&testid, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + ret = LOS_EventRead(&g_event, (0x1 << LOSCFG_KERNEL_CORE_NUM) - 1, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, (0x1 << LOSCFG_KERNEL_CORE_NUM) - 1, ret, EXIT); + + g_targetCpuid = (ArchCurrCpuid() + 1) % LOSCFG_KERNEL_CORE_NUM; // other cpu + HalIrqSendIpi(CPUID_TO_AFFI_MASK(g_targetCpuid), HWI_NUM_INT12); + + LOS_TaskDelay(1); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2,The expected value +EXIT: + TEST_HwiDelete(HWI_NUM_INT12); + TEST_HwiDelete(HWI_NUM_TEST); + LOS_EventDestroy(&g_event); + return LOS_OK; +} + +VOID ItSmpLosHwiNest002(VOID) +{ + TEST_ADD_CASE("ItSmpLosHwiNest002", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_nest_003.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_nest_003.c new file mode 100644 index 00000000..9f71aa5d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_nest_003.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_smp_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#ifdef LOSCFG_KERNEL_SMP +static UINT32 g_targetCpuid; + +static VOID HwiF02(void) +{ + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} +static VOID HwiF01(void) +{ + TestHwiTrigger(HWI_NUM_TEST1); + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, testid; + UINT32 i; + + g_testCount = 0; + g_testPeriod = 10; // 10, Timeout interval of a periodic software timer. + g_targetCpuid = 0; + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); // spi + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // curret cpu + + ret = LOS_HwiCreate(HWI_NUM_TEST1, 1, 0, (HWI_PROC_FUNC)HwiF02, 0); // spi + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + HalIrqSetAffinity(HWI_NUM_TEST1, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // curret cpu + + TestHwiTrigger(HWI_NUM_TEST); + LOS_TaskDelay(1); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2,The expected value + + TEST_HwiDelete(HWI_NUM_TEST); + TEST_HwiDelete(HWI_NUM_TEST1); + return LOS_OK; +EXIT: + TEST_HwiDelete(HWI_NUM_TEST); + TEST_HwiDelete(HWI_NUM_TEST1); + return LOS_OK; +} + +VOID ItSmpLosHwiNest003(VOID) +{ + TEST_ADD_CASE("ItSmpLosHwiNest003", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_nest_004.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_nest_004.c new file mode 100644 index 00000000..62a285c0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_nest_004.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_smp_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#ifdef LOSCFG_KERNEL_SMP +static UINT32 g_targetCpuid; + +static VOID HwiF02(void) +{ + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} +static VOID HwiF01(void) +{ +#ifndef TEST1980 + TestHwiTrigger(HWI_NUM_TEST1); +#else + HalIrqSendIpi(CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % LOSCFG_KERNEL_CORE_NUM), HWI_NUM_TEST1); +#endif + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, testid; + UINT32 i; + + g_testCount = 0; + g_testPeriod = 10; // 10, Timeout interval of a periodic software timer. + g_targetCpuid = 0; + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); // spi + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // curret cpu + + ret = LOS_HwiCreate(HWI_NUM_TEST1, 1, 0, (HWI_PROC_FUNC)HwiF02, 0); // spi + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + HalIrqSetAffinity(HWI_NUM_TEST1, CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % LOSCFG_KERNEL_CORE_NUM)); // other cpu + +#ifndef TEST1980 + TestHwiTrigger(HWI_NUM_TEST); +#else + HalIrqSendIpi(CPUID_TO_AFFI_MASK(ArchCurrCpuid()), HWI_NUM_TEST); +#endif + LOS_TaskDelay(1); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2,The expected value + + TEST_HwiDelete(HWI_NUM_TEST); + TEST_HwiDelete(HWI_NUM_TEST1); + return LOS_OK; +EXIT: + TEST_HwiDelete(HWI_NUM_TEST); + TEST_HwiDelete(HWI_NUM_TEST1); + return LOS_OK; +} + +VOID ItSmpLosHwiNest004(VOID) +{ + TEST_ADD_CASE("ItSmpLosHwiNest004", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_nest_005.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_nest_005.c new file mode 100644 index 00000000..87414631 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_nest_005.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_smp_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#ifdef LOSCFG_KERNEL_SMP +static UINT32 g_targetCpuid; + +static VOID HwiF02(void) +{ + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} +static VOID HwiF01(void) +{ + HalIrqSendIpi(g_targetCpuid + 1, HWI_NUM_INT12); + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static VOID TaskF01(void) +{ + HalIrqUnmask(HWI_NUM_INT11); + HalIrqUnmask(HWI_NUM_INT12); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, testid; + UINT32 i; + + g_testCount = 0; + g_testPeriod = 10; // 10, Timeout interval of a periodic software timer. + g_targetCpuid = 0; + + HalIrqUnmask(HWI_NUM_INT11); + HalIrqUnmask(HWI_NUM_INT12); + ret = LOS_HwiCreate(HWI_NUM_INT11, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); // ipi + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_HwiCreate(HWI_NUM_INT12, 1, 0, (HWI_PROC_FUNC)HwiF02, 0); // ipi + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_hwi_001_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK((ArchCurrCpuid() + i + 1) % + LOSCFG_KERNEL_CORE_NUM)); // let current cpu 's task create at the last + ret = LOS_TaskCreate(&testid, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + g_targetCpuid = ArchCurrCpuid(); // current cpu + HalIrqSendIpi(g_targetCpuid + 1, HWI_NUM_INT11); + + LOS_TaskDelay(1); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2,The expected value + + TEST_HwiDelete(HWI_NUM_INT11); + TEST_HwiDelete(HWI_NUM_INT12); + return LOS_OK; +EXIT: + TEST_HwiDelete(HWI_NUM_INT11); + TEST_HwiDelete(HWI_NUM_INT12); + return LOS_OK; +} + +VOID ItSmpLosHwiNest005(VOID) +{ + TEST_ADD_CASE("ItSmpLosHwiNest005", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_nest_006.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_nest_006.c new file mode 100644 index 00000000..fb416702 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_nest_006.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_smp_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#ifdef LOSCFG_KERNEL_SMP +static UINT32 g_targetCpuid; + +static VOID HwiF02(void) +{ + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} +static VOID HwiF01(void) +{ + HalIrqSendIpi(((ArchCurrCpuid() + 1) % LOSCFG_KERNEL_CORE_NUM) + 1, HWI_NUM_INT12); + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static VOID TaskF01(void) +{ + HalIrqUnmask(HWI_NUM_INT11); + HalIrqUnmask(HWI_NUM_INT12); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, testid; + UINT32 i; + + g_testCount = 0; + g_testPeriod = 10; // 10, Timeout interval of a periodic software timer. + g_targetCpuid = 0; + + HalIrqUnmask(HWI_NUM_INT11); + HalIrqUnmask(HWI_NUM_INT12); + ret = LOS_HwiCreate(HWI_NUM_INT11, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); // ipi + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_HwiCreate(HWI_NUM_INT12, 1, 0, (HWI_PROC_FUNC)HwiF02, 0); // ipi + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_hwi_001_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK((ArchCurrCpuid() + i + 1) % + LOSCFG_KERNEL_CORE_NUM)); // let current cpu 's task create at the last + ret = LOS_TaskCreate(&testid, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + g_targetCpuid = ArchCurrCpuid(); // current cpu + HalIrqSendIpi(g_targetCpuid + 1, HWI_NUM_INT11); + + LOS_TaskDelay(1); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2,The expected value + + TEST_HwiDelete(HWI_NUM_INT11); + TEST_HwiDelete(HWI_NUM_INT12); + return LOS_OK; +EXIT: + TEST_HwiDelete(HWI_NUM_INT11); + TEST_HwiDelete(HWI_NUM_INT12); + return LOS_OK; +} + +VOID ItSmpLosHwiNest006(VOID) +{ + TEST_ADD_CASE("ItSmpLosHwiNest006", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_nest_007.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_nest_007.c new file mode 100644 index 00000000..b9050a8b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_nest_007.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_smp_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#ifdef LOSCFG_KERNEL_SMP +static UINT32 g_targetCpuid; + +static VOID HwiF02(void) +{ + HalIrqSendIpi(CPUID_TO_AFFI_MASK(g_targetCpuid), HWI_NUM_INT11); // currernt cpu; + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} +static VOID HwiF01(void) +{ + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static VOID TaskF01(void) +{ + HalIrqUnmask(HWI_NUM_INT11); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, testid; + UINT32 i; + + g_testCount = 0; + g_testPeriod = 10; // 10, Timeout interval of a periodic software timer. + g_targetCpuid = 0; + + HalIrqUnmask(HWI_NUM_INT11); + ret = LOS_HwiCreate(HWI_NUM_INT11, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); // ipi + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_HwiCreate(HWI_NUM_TEST1, 1, 0, (HWI_PROC_FUNC)HwiF02, 0); // spi + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + HalIrqSetAffinity(HWI_NUM_TEST1, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // curret cpu + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_hwi_001_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK((ArchCurrCpuid() + i + 1) % + LOSCFG_KERNEL_CORE_NUM)); // let current cpu 's task create at the last + ret = LOS_TaskCreate(&testid, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + g_targetCpuid = ArchCurrCpuid(); + TestHwiTrigger(HWI_NUM_TEST1); + + LOS_TaskDelay(1); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2,The expected value + + TEST_HwiDelete(HWI_NUM_INT11); + TEST_HwiDelete(HWI_NUM_TEST1); + return LOS_OK; +EXIT: + TEST_HwiDelete(HWI_NUM_INT11); + TEST_HwiDelete(HWI_NUM_TEST1); + return LOS_OK; +} + +VOID ItSmpLosHwiNest007(VOID) +{ + TEST_ADD_CASE("ItSmpLosHwiNest007", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_nest_008.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_nest_008.c new file mode 100644 index 00000000..d1fea484 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_nest_008.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_smp_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#ifdef LOSCFG_KERNEL_SMP +static UINT32 g_targetCpuid; + +static VOID HwiF02(void) +{ + HalIrqSendIpi(CPUID_TO_AFFI_MASK((g_targetCpuid + 1) % LOSCFG_KERNEL_CORE_NUM), HWI_NUM_INT11); // other cpu; + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} +static VOID HwiF01(void) +{ + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static VOID TaskF01(void) +{ + HalIrqUnmask(HWI_NUM_INT11); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, testid; + UINT32 i; + + g_testCount = 0; + g_testPeriod = 10; // 10, Timeout interval of a periodic software timer. + g_targetCpuid = 0; + + HalIrqUnmask(HWI_NUM_INT11); + ret = LOS_HwiCreate(HWI_NUM_INT11, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); // ipi + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_HwiCreate(HWI_NUM_TEST1, 1, 0, (HWI_PROC_FUNC)HwiF02, 0); // spi + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + HalIrqSetAffinity(HWI_NUM_TEST1, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // curret cpu + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_hwi_001_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK((ArchCurrCpuid() + i + 1) % + LOSCFG_KERNEL_CORE_NUM)); // let current cpu 's task create at the last + ret = LOS_TaskCreate(&testid, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + g_targetCpuid = ArchCurrCpuid(); + TestHwiTrigger(HWI_NUM_TEST1); + + LOS_TaskDelay(1); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2,The expected value + + TEST_HwiDelete(HWI_NUM_INT11); + TEST_HwiDelete(HWI_NUM_TEST1); + return LOS_OK; +EXIT: + TEST_HwiDelete(HWI_NUM_INT11); + TEST_HwiDelete(HWI_NUM_TEST1); + return LOS_OK; +} + +VOID ItSmpLosHwiNest008(VOID) +{ + TEST_ADD_CASE("ItSmpLosHwiNest008", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_share_001.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_share_001.c new file mode 100644 index 00000000..9df37ec1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_share_001.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_smp_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#ifndef LOSCFG_NO_SHARED_IRQ + +static HwiIrqParam g_dev1, g_dev2; + +static VOID HwiF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static VOID HwiF02(void) +{ + LOS_AtomicAdd(&g_testCount, 0xff); +} + +static VOID TaskF01(void) +{ + UINT32 ret; + + g_dev2.pDevId = (void *)2; // 2, Set device ID + g_dev2.swIrq = HWI_NUM_TEST; + ret = LOS_HwiCreate(HWI_NUM_TEST, 3, IRQF_SHARED, (HWI_PROC_FUNC)HwiF02, &g_dev2); // 3, Set the interrupt priority + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, testid; + + g_testCount = 0; + + g_dev1.pDevId = (void *)1; + g_dev1.swIrq = HWI_NUM_TEST; + ret = LOS_HwiCreate(HWI_NUM_TEST, 3, IRQF_SHARED, (HWI_PROC_FUNC)HwiF01, &g_dev1); // 3, Set the interrupt priority + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestDumpCpuid(); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_hwi_001_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(1); + + TestHwiTrigger(HWI_NUM_TEST); + + LOS_TaskDelay(1); + ICUNIT_GOTO_EQUAL(g_testCount, 0x100, g_testCount, EXIT); + + ret = LOS_HwiDelete(HWI_NUM_TEST, &g_dev1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_HwiDelete(HWI_NUM_TEST, &g_dev2); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +EXIT: + LOS_HwiDelete(HWI_NUM_TEST, &g_dev1); + LOS_HwiDelete(HWI_NUM_TEST, &g_dev2); + return LOS_OK; +} + +VOID ItSmpLosHwiShare001(VOID) +{ + TEST_ADD_CASE("ItSmpLosHwiShare001", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_share_002.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_share_002.c new file mode 100644 index 00000000..9abdf86a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_share_002.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_smp_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#ifndef LOSCFG_NO_SHARED_IRQ + +static HwiIrqParam g_dev1, g_dev2; + +static VOID HwiF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static VOID HwiF02(void) +{ + LOS_AtomicAdd(&g_testCount, 0xff); +} + +static VOID TaskF01(void) +{ + UINT32 ret; + + g_dev2.pDevId = (void *)2; // 2, Set device ID + g_dev2.swIrq = HWI_NUM_TEST; + ret = LOS_HwiCreate(HWI_NUM_TEST, 3, IRQF_SHARED, (HWI_PROC_FUNC)HwiF02, &g_dev2); // 3, Set the interrupt priority + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, testid, currCpuid; + + g_testCount = 0; + + g_dev1.pDevId = (void *)1; + g_dev1.swIrq = HWI_NUM_TEST; + ret = LOS_HwiCreate(HWI_NUM_TEST, 3, IRQF_SHARED, (HWI_PROC_FUNC)HwiF01, &g_dev1); // 3, Set the interrupt priority + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TestDumpCpuid(); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_hwi_002_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // cross task + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(1); + + TestHwiTrigger(HWI_NUM_TEST); + + LOS_TaskDelay(1); + ICUNIT_GOTO_EQUAL(g_testCount, 0x100, g_testCount, EXIT); + + ret = LOS_HwiDelete(HWI_NUM_TEST, &g_dev1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_HwiDelete(HWI_NUM_TEST, &g_dev2); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +EXIT: + LOS_HwiDelete(HWI_NUM_TEST, &g_dev1); + LOS_HwiDelete(HWI_NUM_TEST, &g_dev2); + return LOS_OK; +} + +VOID ItSmpLosHwiShare002(VOID) +{ + TEST_ADD_CASE("ItSmpLosHwiShare002", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_share_003.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_share_003.c new file mode 100644 index 00000000..08e6e9b9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_share_003.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_smp_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#ifndef LOSCFG_NO_SHARED_IRQ + +static HwiIrqParam g_dev1, g_dev2; + +static VOID HwiF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static VOID HwiF02(void) +{ + LOS_AtomicAdd(&g_testCount, 0xff); +} + +static VOID TaskF01(void) +{ + UINT32 ret; + + TestDumpCpuid(); + + TestHwiTrigger(HWI_NUM_TEST); + + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, testid; + + g_testCount = 0; + + g_dev1.pDevId = (void *)1; + g_dev1.swIrq = HWI_NUM_TEST; + ret = LOS_HwiCreate(HWI_NUM_TEST, 3, IRQF_SHARED, (HWI_PROC_FUNC)HwiF01, &g_dev1); // 3, Set the interrupt priority + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + g_dev2.pDevId = (void *)2; // 2, Set device ID + g_dev2.swIrq = HWI_NUM_TEST; + ret = LOS_HwiCreate(HWI_NUM_TEST, 3, IRQF_SHARED, (HWI_PROC_FUNC)HwiF02, &g_dev2); // 3, Set the interrupt priority + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestDumpCpuid(); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_hwi_001_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(1); + + ICUNIT_GOTO_EQUAL(g_testCount, 0x100, g_testCount, EXIT); + + ret = LOS_HwiDelete(HWI_NUM_TEST, &g_dev1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_HwiDelete(HWI_NUM_TEST, &g_dev2); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +EXIT: + LOS_HwiDelete(HWI_NUM_TEST, &g_dev1); + LOS_HwiDelete(HWI_NUM_TEST, &g_dev2); + return LOS_OK; +} + +VOID ItSmpLosHwiShare003(VOID) +{ + TEST_ADD_CASE("ItSmpLosHwiShare003", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_share_004.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_share_004.c new file mode 100644 index 00000000..933c46ab --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_share_004.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_smp_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#ifndef LOSCFG_NO_SHARED_IRQ + +static HwiIrqParam g_dev1, g_dev2; + +static VOID HwiF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static VOID HwiF02(void) +{ + LOS_AtomicAdd(&g_testCount, 0xff); +} + +static VOID TaskF01(void) +{ + TestDumpCpuid(); + TestHwiTrigger(HWI_NUM_TEST); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, testid, currCpuid; + + g_testCount = 0; + + g_dev1.pDevId = (void *)1; + g_dev1.swIrq = HWI_NUM_TEST; + ret = LOS_HwiCreate(HWI_NUM_TEST, 3, IRQF_SHARED, (HWI_PROC_FUNC)HwiF01, &g_dev1); // 3, Set the interrupt priority + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + g_dev2.pDevId = (void *)2; // 2, Set device ID + g_dev2.swIrq = HWI_NUM_TEST; + ret = LOS_HwiCreate(HWI_NUM_TEST, 3, IRQF_SHARED, (HWI_PROC_FUNC)HwiF02, &g_dev2); // 3, Set the interrupt priority + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TestDumpCpuid(); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_hwi_002_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // cross task + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(1); + + ICUNIT_GOTO_EQUAL(g_testCount, 0x100, g_testCount, EXIT); + + ret = LOS_HwiDelete(HWI_NUM_TEST, &g_dev1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_HwiDelete(HWI_NUM_TEST, &g_dev2); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +EXIT: + LOS_HwiDelete(HWI_NUM_TEST, &g_dev1); + LOS_HwiDelete(HWI_NUM_TEST, &g_dev2); + return LOS_OK; +} + +VOID ItSmpLosHwiShare004(VOID) +{ + TEST_ADD_CASE("ItSmpLosHwiShare004", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_share_005.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_share_005.c new file mode 100644 index 00000000..1be98fbd --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_share_005.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_smp_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#ifndef LOSCFG_NO_SHARED_IRQ + +static HwiIrqParam g_dev1, g_dev2; + +static VOID HwiF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static VOID HwiF02(void) +{ + LOS_AtomicAdd(&g_testCount, 0xff); +} + +static VOID TaskF01(void) +{ + UINT32 ret; + + TestDumpCpuid(); + + ret = LOS_HwiDelete(HWI_NUM_TEST, &g_dev1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, testid; + g_testCount = 0; + g_dev1.pDevId = (void *)1; + g_dev1.swIrq = HWI_NUM_TEST; + ret = LOS_HwiCreate(HWI_NUM_TEST, 3, IRQF_SHARED, (HWI_PROC_FUNC)HwiF01, &g_dev1); // 3, Set the interrupt priority + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + g_dev2.pDevId = (void *)2; // 2, Set device ID + g_dev2.swIrq = HWI_NUM_TEST; + ret = LOS_HwiCreate(HWI_NUM_TEST, 3, IRQF_SHARED, (HWI_PROC_FUNC)HwiF02, &g_dev2); // 3, Set the interrupt priority + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestDumpCpuid(); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_hwi_001_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(1); + + TestHwiTrigger(HWI_NUM_TEST); + + LOS_TaskDelay(1); + ICUNIT_GOTO_EQUAL(g_testCount, 0xff, g_testCount, EXIT); + + ret = LOS_HwiDelete(HWI_NUM_TEST, &g_dev2); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + return LOS_OK; +EXIT: + LOS_HwiDelete(HWI_NUM_TEST, &g_dev1); + LOS_HwiDelete(HWI_NUM_TEST, &g_dev2); + return LOS_OK; +} + +VOID ItSmpLosHwiShare005(VOID) +{ + TEST_ADD_CASE("ItSmpLosHwiShare005", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_share_006.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_share_006.c new file mode 100644 index 00000000..29d38157 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_share_006.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_smp_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#ifndef LOSCFG_NO_SHARED_IRQ + +static HwiIrqParam g_dev1, g_dev2; +extern EVENT_CB_S g_event; +static VOID HwiF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static VOID HwiF02(void) +{ + LOS_AtomicAdd(&g_testCount, 0xff); +} + +static VOID TaskF01(void) +{ + UINT32 ret; + ret = LOS_HwiDelete(HWI_NUM_TEST, &g_dev1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + LOS_EventWrite(&g_event, 0x1); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, testid, currCpuid; + + g_testCount = 0; + LOS_EventInit(&g_event); + + g_dev1.pDevId = (void *)1; + g_dev1.swIrq = HWI_NUM_TEST; + ret = LOS_HwiCreate(HWI_NUM_TEST, 3, IRQF_SHARED, (HWI_PROC_FUNC)HwiF01, &g_dev1); // 3, Set the interrupt priority + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + g_dev2.pDevId = (void *)2; // 2, Set device ID + g_dev2.swIrq = HWI_NUM_TEST; + ret = LOS_HwiCreate(HWI_NUM_TEST, 3, IRQF_SHARED, (HWI_PROC_FUNC)HwiF02, &g_dev2); // 3, Set the interrupt priority + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TestDumpCpuid(); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_hwi_002_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // cross task + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_EventRead(&g_event, 0x1, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, 0x1, ret, EXIT); + + TestHwiTrigger(HWI_NUM_TEST); + + LOS_TaskDelay(1); + ICUNIT_GOTO_EQUAL(g_testCount, 0xff, g_testCount, EXIT); + + ret = LOS_HwiDelete(HWI_NUM_TEST, &g_dev2); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + LOS_EventDestroy(&g_event); + return LOS_OK; +EXIT: + LOS_EventDestroy(&g_event); + LOS_HwiDelete(HWI_NUM_TEST, &g_dev1); + LOS_HwiDelete(HWI_NUM_TEST, &g_dev2); + return LOS_OK; +} + +VOID ItSmpLosHwiShare006(VOID) +{ + TEST_ADD_CASE("ItSmpLosHwiShare006", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_share_007.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_share_007.c new file mode 100644 index 00000000..adfa111c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_share_007.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_smp_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +extern EVENT_CB_S g_event; +#ifndef LOSCFG_NO_SHARED_IRQ + +static HwiIrqParam g_dev[LOSCFG_KERNEL_CORE_NUM]; + +static VOID HwiF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static VOID TaskF02(VOID) +{ + TestHwiTrigger(HWI_NUM_TEST); + LOS_EventWrite(&g_event, 0x1 << LOSCFG_KERNEL_CORE_NUM); + TestDumpCpuid(); + return; +} + +static VOID TaskF01(UINTPTR devIndex) +{ + UINT32 ret; + // 3, Set the interrupt priority + ret = LOS_HwiCreate(HWI_NUM_TEST, 3, IRQF_SHARED, (HWI_PROC_FUNC)HwiF01, &(g_dev[devIndex])); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_EventWrite(&g_event, 0x1 << devIndex); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, testid, currCpuid; + UINT32 i; + + g_testCount = 0; + LOS_EventInit(&g_event); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + g_dev[i].pDevId = (void *)(i + 1); + g_dev[i].swIrq = HWI_NUM_TEST; + } + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + TEST_TASK_PARAM_INIT(testTask, "it_hwi_share_task", TaskF01, + TASK_PRIO_TEST + 1); // not set cpuaffi + testTask.auwArgs[0] = i; + ret = LOS_TaskCreate(&testid, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + ret = LOS_EventRead(&g_event, (0x1 << LOSCFG_KERNEL_CORE_NUM) - 1, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, (0x1 << LOSCFG_KERNEL_CORE_NUM) - 1, ret, EXIT); + + TEST_TASK_PARAM_INIT(testTask, "it_hwi_share_task", TaskF02, + TASK_PRIO_TEST + 1); // not set cpuaffi + ret = LOS_TaskCreate(&testid, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_EventRead(&g_event, (0x1 << (LOSCFG_KERNEL_CORE_NUM + 1)) - 1, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, (0x1 << (LOSCFG_KERNEL_CORE_NUM + 1)) - 1, ret, EXIT); + + LOS_TaskDelay(2); // 2, set delay time + + ICUNIT_GOTO_EQUAL(g_testCount, LOSCFG_KERNEL_CORE_NUM, g_testCount, EXIT); +EXIT: + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + LOS_HwiDelete(HWI_NUM_TEST, &(g_dev[i])); + } + LOS_EventDestroy(&g_event); + return LOS_OK; +} + +VOID ItSmpLosHwiShare007(VOID) +{ + TEST_ADD_CASE("ItSmpLosHwiShare007", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_share_008.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_share_008.c new file mode 100644 index 00000000..1a75078c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_share_008.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_smp_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#ifndef LOSCFG_NO_SHARED_IRQ + +static UINT32 g_ret = 0; +static HwiIrqParam g_dev; + +static VOID HwiF01(void) +{ + TEST_HwiClear(HWI_NUM_TEST); + LOS_AtomicInc(&g_testCount); +} + +static VOID TaskF01() +{ + UINT32 ret; + ret = LOS_HwiCreate(HWI_NUM_TEST, 3, IRQF_SHARED, (HWI_PROC_FUNC)HwiF01, &g_dev); // 3, Set the interrupt priority + g_ret |= ret; + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, testid; + UINT32 i, j; + + g_dev.pDevId = (void *)(1); + g_dev.swIrq = HWI_NUM_TEST; + + for (j = 0; j < LOOP; j++) { + g_testCount = 0; + g_ret = 0; + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_hwi_share_task", TaskF01, TASK_PRIO_TEST + 1, + CPUID_TO_AFFI_MASK(i)); + ret = LOS_TaskCreate(&testid, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + LOS_TaskDelay(1); + TestHwiTrigger(HWI_NUM_TEST); + LOS_TaskDelay(1); + ICUNIT_GOTO_NOT_EQUAL(g_ret, 0, g_ret, EXIT); + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + LOS_HwiDelete(HWI_NUM_TEST, &g_dev); + } + LOS_HwiDelete(HWI_NUM_TEST, &g_dev); + return LOS_OK; +EXIT: + LOS_HwiDelete(HWI_NUM_TEST, &g_dev); + return LOS_OK; +} + +VOID ItSmpLosHwiShare008(VOID) +{ + TEST_ADD_CASE("ItSmpLosHwiShare008", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_share_009.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_share_009.c new file mode 100644 index 00000000..45a72747 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_share_009.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_smp_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#ifndef LOSCFG_NO_SHARED_IRQ + +static HwiIrqParam g_dev; +static UINT32 g_ret = 0; + +static VOID HwiF01(void) +{ + TEST_HwiClear(HWI_NUM_TEST); + LOS_AtomicInc(&g_testCount); +} + + +static VOID TaskF01() +{ + UINT32 ret; + + ret = LOS_HwiDelete(HWI_NUM_TEST, &g_dev); + g_ret |= ret; + TestDumpCpuid(); + + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, testid; + UINT32 i, j; + + g_dev.pDevId = (void *)(1); + g_dev.swIrq = HWI_NUM_TEST; + + for (j = 0; j < LOOP; j++) { + g_testCount = 0; + g_ret = 0; + // 3, Set the interrupt priority + ret = LOS_HwiCreate(HWI_NUM_TEST, 3, IRQF_SHARED, (HWI_PROC_FUNC)HwiF01, &g_dev); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_hwi_share_task", TaskF01, TASK_PRIO_TEST + 1, + CPUID_TO_AFFI_MASK(i)); + ret = LOS_TaskCreate(&testid, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + LOS_TaskDelay(1); + TestHwiTrigger(HWI_NUM_TEST); + LOS_TaskDelay(1); + ICUNIT_GOTO_NOT_EQUAL(g_ret, 0, g_ret, EXIT); + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + LOS_HwiDelete(HWI_NUM_TEST, &g_dev); + } + return LOS_OK; +EXIT: + LOS_HwiDelete(HWI_NUM_TEST, &g_dev); + return LOS_OK; +} + +VOID ItSmpLosHwiShare009(VOID) +{ + TEST_ADD_CASE("ItSmpLosHwiShare009", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_share_010.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_share_010.c new file mode 100644 index 00000000..9b84a33a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi/smp/It_smp_los_hwi_share_010.c @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_smp_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#ifndef LOSCFG_NO_SHARED_IRQ + +static HwiIrqParam g_dev[3]; // 3, Three devices + +static VOID HwiF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static VOID TaskF01() +{ + UINT32 ret, index, i; + index = ArchCurrCpuid(); + switch (index) { + case 0: + for (i = 0; i < LOOP; i++) { + // 3, Set the interrupt priority + ret = LOS_HwiCreate(HWI_NUM_TEST, 3, IRQF_SHARED, (HWI_PROC_FUNC)HwiF01, &(g_dev[0])); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + TestHwiTrigger(HWI_NUM_TEST); + LOS_HwiDelete(HWI_NUM_TEST, &(g_dev[0])); + TestDumpCpuid(); + } + break; + case 1: + for (i = 0; i < LOOP; i++) { + // 3, Set the interrupt priority + ret = LOS_HwiCreate(HWI_NUM_TEST, 3, IRQF_SHARED, (HWI_PROC_FUNC)HwiF01, &(g_dev[1])); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + TestHwiTrigger(HWI_NUM_TEST); + LOS_HwiDelete(HWI_NUM_TEST, &(g_dev[1])); + TestDumpCpuid(); + } + break; + case 2: // 2, when CPU id is + for (i = 0; i < LOOP; i++) { + // 3, Set the interrupt priority; 2, index + ret = LOS_HwiCreate(HWI_NUM_TEST, 3, IRQF_SHARED, (HWI_PROC_FUNC)HwiF01, &(g_dev[2])); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + TestHwiTrigger(HWI_NUM_TEST); + LOS_HwiDelete(HWI_NUM_TEST, &(g_dev[2])); // 2, index + TestDumpCpuid(); + } + break; + default: + TestDumpCpuid(); + break; + } + + return; +EXIT: + LOS_HwiDelete(HWI_NUM_TEST, &(g_dev[0])); + LOS_HwiDelete(HWI_NUM_TEST, &(g_dev[1])); + LOS_HwiDelete(HWI_NUM_TEST, &(g_dev[2])); // 2, index + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, testid, currCpuid; + UINT32 i; + + g_testCount = 0; + + for (i = 0; i < 3; i++) { // 3, max index + g_dev[i].pDevId = (void *)(i + 1); + g_dev[i].swIrq = HWI_NUM_TEST; + } + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_hwi_share_task", TaskF01, TASK_PRIO_TEST + 1, CPUID_TO_AFFI_MASK(i)); + ret = LOS_TaskCreate(&testid, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + LOS_TaskDelay(100); // 100, set delay time + + for (i = 0; i < 3; i++) { // 3, max index + ret = LOS_HwiDelete(HWI_NUM_TEST, &(g_dev[i])); + PRINT_DEBUG("ret = 0x%x\n", ret); + ICUNIT_ASSERT_NOT_EQUAL(ret, LOS_OK, ret); + } + return LOS_OK; +} + +VOID ItSmpLosHwiShare010(VOID) +{ + TEST_ADD_CASE("ItSmpLosHwiShare010", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi_nesting/It_hwi_nesting.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi_nesting/It_hwi_nesting.c new file mode 100644 index 00000000..8c330828 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi_nesting/It_hwi_nesting.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_hwi_nesting.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#define RECORD_SIZE 100 + +UINT32 g_intrTrace[RECORD_SIZE]; +UINT32 g_traceIdx = 0; +UINT32 g_intrHandleEnd = 0; + +VOID RecordIntrTrace(INT32 irq, INT32 direction) +{ + g_intrTrace[g_traceIdx++] = irq | (direction << 31); // 31, Bit shift mark. +} + +VOID ResetIntrTrace(VOID) +{ + g_traceIdx = 0; + (void)memset_s(g_intrTrace, RECORD_SIZE, 0, RECORD_SIZE); +} + +UINT32 CheckIntrTrace(UINT32 *expect, UINT32 num) +{ + UINT32 ret = LOS_OK; + INT32 idx = 0; + + if ((expect == NULL) || (num > RECORD_SIZE)) { + return LOS_NOK; + } + + for (; idx < g_traceIdx; idx++) { + if (expect[idx] != g_intrTrace[idx]) { + ret = LOS_NOK; + break; + } + } + + if (ret == LOS_NOK) { + for (idx = 0; idx < g_traceIdx; idx++) { + dprintf("%u ", g_intrTrace[idx]); + } + } + dprintf("\n"); + + return ret; +} + +VOID ItSuiteHwiNesting(VOID) +{ +#if defined(LOSCFG_TEST_FULL) +#ifdef LOSCFG_ARCH_INTERRUPT_PREEMPTION + ItLosHwiNest001(); + ItLosHwiNest002(); + ItLosHwiNest003(); + ItLosHwiNest004(); + ItLosHwiNest005(); + ItLosHwiNest006(); + ItLosHwiNest007(); +#endif +#endif +} + + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi_nesting/It_hwi_nesting.h b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi_nesting/It_hwi_nesting.h new file mode 100644 index 00000000..5dc1bf18 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi_nesting/It_hwi_nesting.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "osTest.h" +#include "los_hwi.h" +#include "gic_common.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#define HIGHT_PRIO_INTR 100 +#define MIDDLE_PRIO_INTR 101 +#define LOW_PRIO_INTR 102 + +#define SPI_HIGHT_PRIO 0 +#define SPI_MIDDLE_PRIO ((GIC_MAX_INTERRUPT_PREEMPTION_LEVEL - 2) << PRIORITY_SHIFT) +#define SPI_LOW_PRIO MIN_INTERRUPT_PRIORITY + +#define INTR_ENTRY 0 +#define INTR_EXIT 1 + +extern UINT32 g_intrHandleEnd; +VOID RecordIntrTrace(INT32 irq, INT32 direction); +VOID ResetIntrTrace(VOID); +UINT32 CheckIntrTrace(UINT32 *expect, UINT32 num); +VOID ItLosHwiNest001(VOID); +VOID ItLosHwiNest002(VOID); +VOID ItLosHwiNest003(VOID); +VOID ItLosHwiNest004(VOID); +VOID ItLosHwiNest005(VOID); +VOID ItLosHwiNest006(VOID); +VOID ItLosHwiNest007(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi_nesting/full/It_los_hwi_nesting_001.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi_nesting/full/It_los_hwi_nesting_001.c new file mode 100644 index 00000000..2d8d20f9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi_nesting/full/It_los_hwi_nesting_001.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_hwi_nesting.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +#ifdef LOSCFG_ARCH_INTERRUPT_PREEMPTION +static HwiIrqParam g_nestingPara; + +/* low in -> middle in -> hight in -> hight out -> middle out -> low out */ +static UINT32 g_expect[] = { + LOW_PRIO_INTR, MIDDLE_PRIO_INTR, HIGHT_PRIO_INTR, + 0x80000000 | HIGHT_PRIO_INTR, + 0x80000000 | MIDDLE_PRIO_INTR, + 0x80000000 | LOW_PRIO_INTR +}; + +static VOID NestingPrioLow(INT32 irq, VOID *data) +{ + volatile UINT64 nestingDelay = 10000000; // 10000000, The loop frequency. + + RecordIntrTrace(LOW_PRIO_INTR, INTR_ENTRY); + + HalIrqPending(MIDDLE_PRIO_INTR); /* pending middle prio interrupt */ + while (nestingDelay-- > 0) { + } + + RecordIntrTrace(LOW_PRIO_INTR, INTR_EXIT); + + g_intrHandleEnd = 1; +} + +static VOID NestingPrioMiddle(INT32 irq, VOID *data) +{ + volatile UINT64 nestingDelay = 10000000; // 10000000, The loop frequency. + + RecordIntrTrace(MIDDLE_PRIO_INTR, INTR_ENTRY); + + HalIrqPending(HIGHT_PRIO_INTR); /* pending hight prio interrupt */ + while (nestingDelay-- > 0) { + } + + RecordIntrTrace(MIDDLE_PRIO_INTR, INTR_EXIT); +} + +static VOID NestingPrioHigh(INT32 irq, VOID *data) +{ + RecordIntrTrace(HIGHT_PRIO_INTR, INTR_ENTRY); + RecordIntrTrace(HIGHT_PRIO_INTR, INTR_EXIT); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + + LOS_HwiCreate(HIGHT_PRIO_INTR, SPI_HIGHT_PRIO, 0, (HWI_PROC_FUNC)NestingPrioHigh, &g_nestingPara); + LOS_HwiCreate(MIDDLE_PRIO_INTR, SPI_MIDDLE_PRIO, 0, (HWI_PROC_FUNC)NestingPrioMiddle, &g_nestingPara); + LOS_HwiCreate(LOW_PRIO_INTR, SPI_LOW_PRIO, 0, (HWI_PROC_FUNC)NestingPrioLow, &g_nestingPara); + HalIrqUnmask(HIGHT_PRIO_INTR); + HalIrqUnmask(MIDDLE_PRIO_INTR); + HalIrqUnmask(LOW_PRIO_INTR); + + HalIrqPending(LOW_PRIO_INTR); + + while (g_intrHandleEnd == 0) { + LOS_TaskDelay(10); // 10, set delay time. + } + + ret = CheckIntrTrace(g_expect, sizeof(g_expect)); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + +EXIT: + LOS_HwiDelete(HIGHT_PRIO_INTR, &g_nestingPara); + LOS_HwiDelete(MIDDLE_PRIO_INTR, &g_nestingPara); + LOS_HwiDelete(LOW_PRIO_INTR, &g_nestingPara); + HalIrqMask(HIGHT_PRIO_INTR); + HalIrqMask(MIDDLE_PRIO_INTR); + HalIrqMask(LOW_PRIO_INTR); + g_intrHandleEnd = 0; + ResetIntrTrace(); + + return LOS_OK; +} + +VOID ItLosHwiNest001(VOID) +{ + TEST_ADD_CASE("ItLosHwiNest001", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi_nesting/full/It_los_hwi_nesting_002.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi_nesting/full/It_los_hwi_nesting_002.c new file mode 100644 index 00000000..63f30c99 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi_nesting/full/It_los_hwi_nesting_002.c @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_hwi_nesting.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +#ifdef LOSCFG_ARCH_INTERRUPT_PREEMPTION +static HwiIrqParam g_nestingPara; + +/* middle in -> middle out -> low in -> hight in -> hight out -> low out */ +static UINT32 g_expect[] = { + MIDDLE_PRIO_INTR, + 0x80000000 | MIDDLE_PRIO_INTR, + LOW_PRIO_INTR, + HIGHT_PRIO_INTR, + 0x80000000 | HIGHT_PRIO_INTR, + 0x80000000 | LOW_PRIO_INTR +}; + +static VOID NestingPrioLow(INT32 irq, VOID *data) +{ + volatile UINT64 nestingDelay = 10000000; // 10000000, The loop frequency. + + RecordIntrTrace(LOW_PRIO_INTR, INTR_ENTRY); + + HalIrqPending(HIGHT_PRIO_INTR); /* pending hight prio interrupt */ + while (nestingDelay-- > 0); + + RecordIntrTrace(LOW_PRIO_INTR, INTR_EXIT); + + g_intrHandleEnd = 1; +} + +static VOID NestingPrioMiddle(INT32 irq, VOID *data) +{ + volatile UINT64 nestingDelay = 10000000; // 10000000, The loop frequency. + + RecordIntrTrace(MIDDLE_PRIO_INTR, INTR_ENTRY); + + HalIrqPending(LOW_PRIO_INTR); /* pending low prio interrupt */ + while (nestingDelay-- > 0); + + RecordIntrTrace(MIDDLE_PRIO_INTR, INTR_EXIT); +} + +static VOID NestingPrioHigh(INT32 irq, VOID *data) +{ + RecordIntrTrace(HIGHT_PRIO_INTR, INTR_ENTRY); + RecordIntrTrace(HIGHT_PRIO_INTR, INTR_EXIT); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + + LOS_HwiCreate(HIGHT_PRIO_INTR, SPI_HIGHT_PRIO, 0, (HWI_PROC_FUNC)NestingPrioHigh, &g_nestingPara); + LOS_HwiCreate(MIDDLE_PRIO_INTR, SPI_MIDDLE_PRIO, 0, (HWI_PROC_FUNC)NestingPrioMiddle, &g_nestingPara); + LOS_HwiCreate(LOW_PRIO_INTR, SPI_LOW_PRIO, 0, (HWI_PROC_FUNC)NestingPrioLow, &g_nestingPara); + HalIrqUnmask(HIGHT_PRIO_INTR); + HalIrqUnmask(MIDDLE_PRIO_INTR); + HalIrqUnmask(LOW_PRIO_INTR); + + HalIrqPending(MIDDLE_PRIO_INTR); /* pending middle prio interrupt */ + + while (g_intrHandleEnd == 0) { + LOS_TaskDelay(10); // 10, set delay time. + } + + ret = CheckIntrTrace(g_expect, sizeof(g_expect)); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + +EXIT: + LOS_HwiDelete(HIGHT_PRIO_INTR, &g_nestingPara); + LOS_HwiDelete(MIDDLE_PRIO_INTR, &g_nestingPara); + LOS_HwiDelete(LOW_PRIO_INTR, &g_nestingPara); + HalIrqMask(HIGHT_PRIO_INTR); + HalIrqMask(MIDDLE_PRIO_INTR); + HalIrqMask(LOW_PRIO_INTR); + g_intrHandleEnd = 0; + ResetIntrTrace(); + + return LOS_OK; +} + + +VOID ItLosHwiNest002(VOID) +{ + TEST_ADD_CASE("ItLosHwiNest002", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi_nesting/full/It_los_hwi_nesting_003.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi_nesting/full/It_los_hwi_nesting_003.c new file mode 100644 index 00000000..c81b5114 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi_nesting/full/It_los_hwi_nesting_003.c @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_hwi_nesting.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +#ifdef LOSCFG_ARCH_INTERRUPT_PREEMPTION +static HwiIrqParam g_nestingPara; + +/* hight in -> hight out -> middle in -> middle out -> low in -> low out */ +static UINT32 g_expect[] = { + HIGHT_PRIO_INTR, + 0x80000000 | HIGHT_PRIO_INTR, + MIDDLE_PRIO_INTR, + 0x80000000 | MIDDLE_PRIO_INTR, + LOW_PRIO_INTR, + 0x80000000 | LOW_PRIO_INTR +}; + +static VOID NestingPrioLow(INT32 irq, VOID *data) +{ + RecordIntrTrace(LOW_PRIO_INTR, INTR_ENTRY); + RecordIntrTrace(LOW_PRIO_INTR, INTR_EXIT); + + g_intrHandleEnd = 1; +} + +static VOID NestingPrioMiddle(INT32 irq, VOID *data) +{ + volatile UINT64 nestingDelay = 10000000; // 10000000, The loop frequency. + + RecordIntrTrace(MIDDLE_PRIO_INTR, INTR_ENTRY); + + HalIrqPending(LOW_PRIO_INTR); /* pending low prio interrupt */ + while (nestingDelay-- > 0) { + } + + RecordIntrTrace(MIDDLE_PRIO_INTR, INTR_EXIT); +} + +static VOID NestingPrioHigh(INT32 irq, VOID *data) +{ + volatile UINT64 nestingDelay = 10000000; // 10000000, The loop frequency. + + RecordIntrTrace(HIGHT_PRIO_INTR, INTR_ENTRY); + + HalIrqPending(MIDDLE_PRIO_INTR); /* pending middle prio interrupt */ + while (nestingDelay-- > 0) { + } + + RecordIntrTrace(HIGHT_PRIO_INTR, INTR_EXIT); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + + LOS_HwiCreate(HIGHT_PRIO_INTR, SPI_HIGHT_PRIO, 0, (HWI_PROC_FUNC)NestingPrioHigh, &g_nestingPara); + LOS_HwiCreate(MIDDLE_PRIO_INTR, SPI_MIDDLE_PRIO, 0, (HWI_PROC_FUNC)NestingPrioMiddle, &g_nestingPara); + LOS_HwiCreate(LOW_PRIO_INTR, SPI_LOW_PRIO, 0, (HWI_PROC_FUNC)NestingPrioLow, &g_nestingPara); + HalIrqUnmask(HIGHT_PRIO_INTR); + HalIrqUnmask(MIDDLE_PRIO_INTR); + HalIrqUnmask(LOW_PRIO_INTR); + + HalIrqPending(HIGHT_PRIO_INTR); /* pending hight prio interrupt */ + + while (g_intrHandleEnd == 0) { + LOS_TaskDelay(10); // 10, set delay time. + } + + ret = CheckIntrTrace(g_expect, sizeof(g_expect)); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + +EXIT: + LOS_HwiDelete(HIGHT_PRIO_INTR, &g_nestingPara); + LOS_HwiDelete(MIDDLE_PRIO_INTR, &g_nestingPara); + LOS_HwiDelete(LOW_PRIO_INTR, &g_nestingPara); + HalIrqMask(HIGHT_PRIO_INTR); + HalIrqMask(MIDDLE_PRIO_INTR); + HalIrqMask(LOW_PRIO_INTR); + g_intrHandleEnd = 0; + ResetIntrTrace(); + + return LOS_OK; +} + +VOID ItLosHwiNest003(VOID) +{ + TEST_ADD_CASE("ItLosHwiNest003", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi_nesting/full/It_los_hwi_nesting_004.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi_nesting/full/It_los_hwi_nesting_004.c new file mode 100644 index 00000000..d1179084 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi_nesting/full/It_los_hwi_nesting_004.c @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_hwi_nesting.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +#ifdef LOSCFG_ARCH_INTERRUPT_PREEMPTION +static HwiIrqParam g_nestingPara; + +/* middle in -> middle out -> low in -> low out -> hight in -> hight out */ +static UINT32 g_expect[] = { + MIDDLE_PRIO_INTR, + 0x80000000 | MIDDLE_PRIO_INTR, + LOW_PRIO_INTR, + 0x80000000 | LOW_PRIO_INTR, + HIGHT_PRIO_INTR, + 0x80000000 | HIGHT_PRIO_INTR +}; + +static VOID NestingPrioLow(INT32 irq, VOID *data) +{ + volatile UINT64 nestingDelay = 10000000; // 10000000, The loop frequency. + + RecordIntrTrace(LOW_PRIO_INTR, INTR_ENTRY); + + HalIrqPending(HIGHT_PRIO_INTR); /* pending hight prio interrupt */ + while (nestingDelay-- > 0); + + RecordIntrTrace(LOW_PRIO_INTR, INTR_EXIT); + + g_intrHandleEnd = 1; +} + +static VOID NestingPrioMiddle(INT32 irq, VOID *data) +{ + volatile UINT64 nestingDelay = 10000000; // 10000000, The loop frequency. + + RecordIntrTrace(MIDDLE_PRIO_INTR, INTR_ENTRY); + + HalIrqPending(LOW_PRIO_INTR); /* pending low prio interrupt */ + while (nestingDelay-- > 0); + + RecordIntrTrace(MIDDLE_PRIO_INTR, INTR_EXIT); +} + +static VOID NestingPrioHigh(INT32 irq, VOID *data) +{ + RecordIntrTrace(HIGHT_PRIO_INTR, INTR_ENTRY); + RecordIntrTrace(HIGHT_PRIO_INTR, INTR_EXIT); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + + LOS_HwiCreate(HIGHT_PRIO_INTR, SPI_MIDDLE_PRIO, 0, (HWI_PROC_FUNC)NestingPrioHigh, &g_nestingPara); + LOS_HwiCreate(MIDDLE_PRIO_INTR, SPI_MIDDLE_PRIO, 0, (HWI_PROC_FUNC)NestingPrioMiddle, &g_nestingPara); + LOS_HwiCreate(LOW_PRIO_INTR, SPI_MIDDLE_PRIO, 0, (HWI_PROC_FUNC)NestingPrioLow, &g_nestingPara); + HalIrqUnmask(HIGHT_PRIO_INTR); + HalIrqUnmask(MIDDLE_PRIO_INTR); + HalIrqUnmask(LOW_PRIO_INTR); + + HalIrqPending(MIDDLE_PRIO_INTR); /* pending middle prio interrupt */ + + while (g_intrHandleEnd == 0) { + LOS_TaskDelay(10); // 10, set delay time. + } + + ret = CheckIntrTrace(g_expect, sizeof(g_expect)); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + +EXIT: + LOS_HwiDelete(HIGHT_PRIO_INTR, &g_nestingPara); + LOS_HwiDelete(MIDDLE_PRIO_INTR, &g_nestingPara); + LOS_HwiDelete(LOW_PRIO_INTR, &g_nestingPara); + HalIrqMask(HIGHT_PRIO_INTR); + HalIrqMask(MIDDLE_PRIO_INTR); + HalIrqMask(LOW_PRIO_INTR); + g_intrHandleEnd = 0; + ResetIntrTrace(); + + return LOS_OK; +} + + +VOID ItLosHwiNest004(VOID) +{ + TEST_ADD_CASE("ItLosHwiNest004", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi_nesting/full/It_los_hwi_nesting_005.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi_nesting/full/It_los_hwi_nesting_005.c new file mode 100644 index 00000000..83744b40 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi_nesting/full/It_los_hwi_nesting_005.c @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_hwi_nesting.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +#ifdef LOSCFG_ARCH_INTERRUPT_PREEMPTION +static HwiIrqParam g_nestingPara; + +/* low in -> middle in -> hight in -> hight out -> middle out -> low out */ +/* loop trigger */ +static UINT32 g_expect[] = { + LOW_PRIO_INTR, MIDDLE_PRIO_INTR, HIGHT_PRIO_INTR, + 0x80000000 | HIGHT_PRIO_INTR, + 0x80000000 | MIDDLE_PRIO_INTR, + 0x80000000 | LOW_PRIO_INTR, + LOW_PRIO_INTR, MIDDLE_PRIO_INTR, HIGHT_PRIO_INTR, + 0x80000000 | HIGHT_PRIO_INTR, + 0x80000000 | MIDDLE_PRIO_INTR, + 0x80000000 | LOW_PRIO_INTR, + LOW_PRIO_INTR, MIDDLE_PRIO_INTR, HIGHT_PRIO_INTR, + 0x80000000 | HIGHT_PRIO_INTR, + 0x80000000 | MIDDLE_PRIO_INTR, + 0x80000000 | LOW_PRIO_INTR, + LOW_PRIO_INTR, + 0x80000000 | LOW_PRIO_INTR, +}; + +static VOID NestingPrioLow(INT32 irq, VOID *data) +{ + volatile UINT64 nestingDelay = 10000000; // 10000000, The loop frequency. + + RecordIntrTrace(LOW_PRIO_INTR, INTR_ENTRY); + + if (g_intrHandleEnd < 3) { // 3, Interrupt callback function count. + HalIrqPending(MIDDLE_PRIO_INTR); /* pending middle prio interrupt */ + } + while (nestingDelay-- > 0) { + } + + RecordIntrTrace(LOW_PRIO_INTR, INTR_EXIT); + + g_intrHandleEnd++; +} + +static VOID NestingPrioMiddle(INT32 irq, VOID *data) +{ + volatile UINT64 nestingDelay = 10000000; // 10000000, The loop frequency. + + RecordIntrTrace(MIDDLE_PRIO_INTR, INTR_ENTRY); + + HalIrqPending(HIGHT_PRIO_INTR); /* pending hight prio interrupt */ + while (nestingDelay-- > 0) { + } + + RecordIntrTrace(MIDDLE_PRIO_INTR, INTR_EXIT); +} + +static VOID NestingPrioHigh(INT32 irq, VOID *data) +{ + RecordIntrTrace(HIGHT_PRIO_INTR, INTR_ENTRY); + + HalIrqPending(LOW_PRIO_INTR); + + RecordIntrTrace(HIGHT_PRIO_INTR, INTR_EXIT); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + + LOS_HwiCreate(HIGHT_PRIO_INTR, SPI_HIGHT_PRIO, 0, (HWI_PROC_FUNC)NestingPrioHigh, &g_nestingPara); + LOS_HwiCreate(MIDDLE_PRIO_INTR, SPI_MIDDLE_PRIO, 0, (HWI_PROC_FUNC)NestingPrioMiddle, &g_nestingPara); + LOS_HwiCreate(LOW_PRIO_INTR, SPI_LOW_PRIO, 0, (HWI_PROC_FUNC)NestingPrioLow, &g_nestingPara); + HalIrqUnmask(HIGHT_PRIO_INTR); + HalIrqUnmask(MIDDLE_PRIO_INTR); + HalIrqUnmask(LOW_PRIO_INTR); + + HalIrqPending(LOW_PRIO_INTR); + + while (g_intrHandleEnd == 0) { + LOS_TaskDelay(10); // 10, set delay time. + } + + ret = CheckIntrTrace(g_expect, sizeof(g_expect)); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + +EXIT: + LOS_HwiDelete(HIGHT_PRIO_INTR, &g_nestingPara); + LOS_HwiDelete(MIDDLE_PRIO_INTR, &g_nestingPara); + LOS_HwiDelete(LOW_PRIO_INTR, &g_nestingPara); + HalIrqMask(HIGHT_PRIO_INTR); + HalIrqMask(MIDDLE_PRIO_INTR); + HalIrqMask(LOW_PRIO_INTR); + g_intrHandleEnd = 0; + ResetIntrTrace(); + + return LOS_OK; +} + +VOID ItLosHwiNest005(VOID) +{ + TEST_ADD_CASE("ItLosHwiNest005", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi_nesting/full/It_los_hwi_nesting_006.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi_nesting/full/It_los_hwi_nesting_006.c new file mode 100644 index 00000000..2421bfa9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi_nesting/full/It_los_hwi_nesting_006.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_hwi_nesting.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +#ifdef LOSCFG_ARCH_INTERRUPT_PREEMPTION +static HwiIrqParam g_nestingPara; + +static VOID NestingPrioHigh(INT32 irq, VOID *data) +{ + g_intrHandleEnd = 1; + UINT32 temp[0x100][2] = {0}; + (void)memset_s(temp, sizeof(UINT32) * 0x100 * 2, 1, sizeof(UINT32) * 0x100 * 2); // 2, buffer size. +} + +static VOID TaskF01(VOID) +{ + HalIrqUnmask(HIGHT_PRIO_INTR); + HalIrqPending(HIGHT_PRIO_INTR); +} +static UINT32 Testcase(VOID) +{ + UINT32 ret, taskID; + + TSK_INIT_PARAM_S task1 = { 0 }; + + // 4, Task priority calculation. + TEST_TASK_PARAM_INIT(task1, "ItLosHwiNest010", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST - 4); + task1.uwStackSize = 0x2000; + LOS_HwiCreate(HIGHT_PRIO_INTR, SPI_HIGHT_PRIO, 0, (HWI_PROC_FUNC)NestingPrioHigh, &g_nestingPara); + HalIrqUnmask(HIGHT_PRIO_INTR); + + ret = LOS_TaskCreate(&taskID, &task1); + + while (g_intrHandleEnd == 0) { + LOS_TaskDelay(10); // 10, set delay time. + } + + ICUNIT_GOTO_EQUAL(g_intrHandleEnd, 1, g_intrHandleEnd, EXIT); + +EXIT: + LOS_HwiDelete(HIGHT_PRIO_INTR, &g_nestingPara); + HalIrqMask(HIGHT_PRIO_INTR); + g_intrHandleEnd = 0; + + return LOS_OK; +} + + +VOID ItLosHwiNest006(VOID) +{ + TEST_ADD_CASE("ItLosHwiNest006", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi_nesting/full/It_los_hwi_nesting_007.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi_nesting/full/It_los_hwi_nesting_007.c new file mode 100644 index 00000000..6fc6c219 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/hwi_nesting/full/It_los_hwi_nesting_007.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_hwi_nesting.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +#ifdef LOSCFG_ARCH_INTERRUPT_PREEMPTION + +#define MAX_RECORD_SIZE 1000 +static HwiIrqParam g_nestingPara; +static INT32 g_saveIndex = 0; +static UINT64 g_intPendTime; +static UINT64 g_recordTime[MAX_RECORD_SIZE] = {0}; +static VOID NestingPrioHigh(INT32 irq, VOID *data) +{ + UINT64 curTime; + curTime = LOS_CurrNanosec(); + g_recordTime[g_saveIndex] = curTime - g_intPendTime; + dprintf("curTime = %lld, pendTime = %lld \n", curTime, g_intPendTime); + dprintf("%lld\n", curTime - g_intPendTime); + dprintf("[swtmr] hwi response time : ##%lld \n", g_recordTime[g_saveIndex]); + g_saveIndex++; + if (g_saveIndex == MAX_RECORD_SIZE) { + g_saveIndex = 0; + } +} + +static VOID DumpResult() +{ + UINT32 i, count; + UINT64 avg, sum; + sum = 0; + count = 0; + for (i = 0; i < MAX_RECORD_SIZE; i++) { + if (g_recordTime[i] != 0) { + dprintf("%lld "); + sum += g_recordTime[i]; + count++; + } + } + + avg = sum / count; + dprintf("***hwi perf test dump***: \n"); + dprintf("avg = %lld \n"); +} + +static VOID SwtmrF01(VOID) +{ + g_intPendTime = LOS_CurrNanosec(); + HalIrqPending(HIGHT_PRIO_INTR); +} +static UINT32 Testcase(VOID) +{ + UINT32 ret, swtmrId; + + LOS_HwiCreate(HIGHT_PRIO_INTR, SPI_HIGHT_PRIO, 0, (HWI_PROC_FUNC)NestingPrioHigh, &g_nestingPara); + HalIrqUnmask(HIGHT_PRIO_INTR); + + // 10, Timing duration of the software timer to be created. + ret = LOS_SwtmrCreate(10, LOS_SWTMR_MODE_PERIOD, SwtmrF01, &swtmrId, + 0xffff); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_SwtmrStart(swtmrId); + + /* EXIT time control */ + LOS_TaskDelay(100); // 100, set delay time. + + LOS_SwtmrStop(swtmrId); + DumpResult(); + +EXIT: + LOS_SwtmrDelete(swtmrId); + LOS_HwiDelete(HIGHT_PRIO_INTR, &g_nestingPara); + HalIrqMask(HIGHT_PRIO_INTR); + + return LOS_OK; +} + + +VOID ItLosHwiNest007(VOID) +{ + TEST_ADD_CASE("ItLosHwiNest007", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/It_los_swtmr.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/It_los_swtmr.c new file mode 100644 index 00000000..44c53550 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/It_los_swtmr.c @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +EVENT_CB_S g_eventCB1, g_eventCB2, g_eventCB3; + +VOID ItSuiteLosSwtmr(VOID) +{ +#if defined(LOSCFG_TEST_SMOKE) + ItLosSwtmr053(); + ItLosSwtmr058(); +#endif +#ifdef LOSCFG_KERNEL_SMP + ItSmpLosSwtmr001(); /* Concurrent Multi-core */ + ItSmpLosSwtmr002(); /* Stop Across Cores */ + ItSmpLosSwtmr003(); + ItSmpLosSwtmr004(); + ItSmpLosSwtmr005(); + ItSmpLosSwtmr006(); + ItSmpLosSwtmr007(); + ItSmpLosSwtmr008(); + ItSmpLosSwtmr009(); + ItSmpLosSwtmr010(); + ItSmpLosSwtmr011(); + ItSmpLosSwtmr012(); + ItSmpLosSwtmr013(); + ItSmpLosSwtmr014(); + ItSmpLosSwtmr015(); + ItSmpLosSwtmr016(); + ItSmpLosSwtmr017(); + ItSmpLosSwtmr018(); + ItSmpLosSwtmr019(); + ItSmpLosSwtmr020(); + ItSmpLosSwtmr021(); + ItSmpLosSwtmr023(); + ItSmpLosSwtmr024(); + ItSmpLosSwtmr026(); + ItSmpLosSwtmr027(); + ItSmpLosSwtmr028(); + ItSmpLosSwtmr029(); + ItSmpLosSwtmr030(); + ItSmpLosSwtmr031(); + ItSmpLosSwtmr032(); + ItSmpLosSwtmr034(); + ItSmpLosSwtmr035(); +#endif + +#if defined(LOSCFG_TEST_FULL) + ItLosSwtmr001(); + ItLosSwtmr002(); + ItLosSwtmr003(); + ItLosSwtmr005(); + ItLosSwtmr006(); + ItLosSwtmr007(); + ItLosSwtmr008(); + ItLosSwtmr009(); + ItLosSwtmr010(); + ItLosSwtmr011(); + ItLosSwtmr012(); + ItLosSwtmr013(); + ItLosSwtmr014(); + ItLosSwtmr015(); + ItLosSwtmr016(); + ItLosSwtmr017(); + ItLosSwtmr018(); + ItLosSwtmr019(); + ItLosSwtmr020(); + ItLosSwtmr021(); + ItLosSwtmr030(); + ItLosSwtmr036(); + ItLosSwtmr037(); + ItLosSwtmr042(); + ItLosSwtmr044(); + ItLosSwtmr045(); + ItLosSwtmr046(); + ItLosSwtmr047(); + ItLosSwtmr048(); + ItLosSwtmr049(); + ItLosSwtmr050(); + ItLosSwtmr051(); + ItLosSwtmr052(); + ItLosSwtmr054(); + ItLosSwtmr055(); + ItLosSwtmr056(); + ItLosSwtmr057(); + ItLosSwtmr059(); + ItLosSwtmr061(); + ItLosSwtmr062(); + ItLosSwtmr063(); + ItLosSwtmr066(); + ItLosSwtmr067(); + ItLosSwtmr068(); + ItLosSwtmr069(); + ItLosSwtmr070(); + ItLosSwtmr071(); + ItLosSwtmr075(); + ItLosSwtmr076(); + ItLosSwtmr077(); + ItLosSwtmr078(); +#endif + +#if defined(LOSCFG_TEST_PRESSURE) + ItLosSwtmr004(); + ItLosSwtmr024(); + ItLosSwtmr025(); + ItLosSwtmr026(); + ItLosSwtmr027(); + ItLosSwtmr028(); + ItLosSwtmr029(); + ItLosSwtmr031(); + ItLosSwtmr032(); + ItLosSwtmr034(); + ItLosSwtmr035(); + ItLosSwtmr038(); +#endif + +#if defined(LOSCFG_TEST_LLT) + ItLosSwtmr073(); +#if !defined(TESTPBXA9) && !defined(TESTVIRTA53) && !defined(TEST3516DV300) && !defined(TESTHI1980IMU) + ItLosSwtmr072(); // SwtmrTimeGet + ItLosSwtmr074(); // across cores + ItLosSwtmr079(); // sched_clock_swtmr +#endif + ItLosSwtmr080(); + ItLosSwtmr023(); +#endif +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/It_los_swtmr.h b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/It_los_swtmr.h new file mode 100644 index 00000000..580342f1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/It_los_swtmr.h @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IT_LOS_SWTMR_H +#define IT_LOS_SWTMR_H + +#include "los_swtmr.h" +#include "osTest.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#define LOOP 100 + +#define SELF_DELETED 0 +#define SYS_EXIST_SWTMR 1 +#define SWTMR_LOOP_NUM 10 +#define TEST_HWI_RUNTIME 0x100000 + +extern EVENT_CB_S g_eventCB1; +extern EVENT_CB_S g_eventCB2; +extern EVENT_CB_S g_eventCB3; + +extern LITE_OS_SEC_BSS SWTMR_CTRL_S *m_pstSwtmrFreeList; + +static UINT32 g_swTmrMaxNum; + +static UINT16 g_swTmrID1; +static UINT16 g_swTmrID2; +static UINT16 g_swTmrID3; + +static UINT32 g_swtmrCountA; +static UINT32 g_swtmrCountB; +static UINT32 g_swtmrCountC; +static UINT64 g_cpuTickCountA; +static UINT64 g_cpuTickCountB; + +extern UINT32 OsSwTmrGetNextTimeout(VOID); +extern UINT32 OsSwtmrTimeGet(SWTMR_CTRL_S *swtmr); + +extern VOID LOS_GetCpuTick(UINT32 *puwCntHi, UINT32 *puwCntLo); +extern VOID ItSuiteLosSwtmr(VOID); + +#if defined(LOSCFG_KERNEL_SMP) +VOID ItSmpLosSwtmr001(VOID); +VOID ItSmpLosSwtmr002(VOID); +VOID ItSmpLosSwtmr003(VOID); +VOID ItSmpLosSwtmr004(VOID); +VOID ItSmpLosSwtmr005(VOID); +VOID ItSmpLosSwtmr006(VOID); +VOID ItSmpLosSwtmr007(VOID); +VOID ItSmpLosSwtmr008(VOID); +VOID ItSmpLosSwtmr009(VOID); +VOID ItSmpLosSwtmr010(VOID); +VOID ItSmpLosSwtmr011(VOID); +VOID ItSmpLosSwtmr012(VOID); +VOID ItSmpLosSwtmr013(VOID); +VOID ItSmpLosSwtmr014(VOID); +VOID ItSmpLosSwtmr015(VOID); +VOID ItSmpLosSwtmr016(VOID); +VOID ItSmpLosSwtmr017(VOID); +VOID ItSmpLosSwtmr018(VOID); +VOID ItSmpLosSwtmr019(VOID); +VOID ItSmpLosSwtmr020(VOID); +VOID ItSmpLosSwtmr021(VOID); +VOID ItSmpLosSwtmr022(VOID); +VOID ItSmpLosSwtmr023(VOID); +VOID ItSmpLosSwtmr024(VOID); +VOID ItSmpLosSwtmr025(VOID); +VOID ItSmpLosSwtmr026(VOID); +VOID ItSmpLosSwtmr027(VOID); +VOID ItSmpLosSwtmr028(VOID); +VOID ItSmpLosSwtmr029(VOID); +VOID ItSmpLosSwtmr030(VOID); +VOID ItSmpLosSwtmr031(VOID); +VOID ItSmpLosSwtmr032(VOID); +VOID ItSmpLosSwtmr033(VOID); +VOID ItSmpLosSwtmr034(VOID); +VOID ItSmpLosSwtmr035(VOID); +#endif + +#if defined(LOSCFG_TEST_SMOKE) +VOID ItLosSwtmr053(VOID); +VOID ItLosSwtmr058(VOID); +#endif + +#if defined(LOSCFG_TEST_FULL) +VOID ItLosSwtmr001(VOID); +VOID ItLosSwtmr002(VOID); +VOID ItLosSwtmr003(VOID); +VOID ItLosSwtmr005(VOID); +VOID ItLosSwtmr006(VOID); +VOID ItLosSwtmr007(VOID); +VOID ItLosSwtmr008(VOID); +VOID ItLosSwtmr009(VOID); +VOID ItLosSwtmr010(VOID); +VOID ItLosSwtmr011(VOID); +VOID ItLosSwtmr012(VOID); +VOID ItLosSwtmr013(VOID); +VOID ItLosSwtmr014(VOID); +VOID ItLosSwtmr015(VOID); +VOID ItLosSwtmr016(VOID); +VOID ItLosSwtmr017(VOID); +VOID ItLosSwtmr018(VOID); +VOID ItLosSwtmr019(VOID); +VOID ItLosSwtmr020(VOID); +VOID ItLosSwtmr021(VOID); +VOID ItLosSwtmr022(VOID); +VOID ItLosSwtmr030(VOID); +VOID ItLosSwtmr033(VOID); +VOID ItLosSwtmr036(VOID); +VOID ItLosSwtmr037(VOID); +VOID ItLosSwtmr038(VOID); +VOID ItLosSwtmr039(VOID); +VOID ItLosSwtmr040(VOID); +VOID ItLosSwtmr041(VOID); +VOID ItLosSwtmr042(VOID); +VOID ItLosSwtmr043(VOID); +VOID ItLosSwtmr044(VOID); +VOID ItLosSwtmr045(VOID); +VOID ItLosSwtmr046(VOID); +VOID ItLosSwtmr047(VOID); +VOID ItLosSwtmr048(VOID); +VOID ItLosSwtmr049(VOID); +VOID ItLosSwtmr050(VOID); +VOID ItLosSwtmr051(VOID); +VOID ItLosSwtmr052(VOID); +VOID ItLosSwtmr054(VOID); +VOID ItLosSwtmr055(VOID); +VOID ItLosSwtmr056(VOID); +VOID ItLosSwtmr057(VOID); +VOID ItLosSwtmr059(VOID); +VOID ItLosSwtmr060(VOID); +VOID ItLosSwtmr061(VOID); +VOID ItLosSwtmr062(VOID); +VOID ItLosSwtmr063(VOID); +VOID ItLosSwtmr064(VOID); +VOID ItLosSwtmr065(VOID); +VOID ItLosSwtmr066(VOID); +VOID ItLosSwtmr067(VOID); +VOID ItLosSwtmr068(VOID); +VOID ItLosSwtmr069(VOID); +VOID ItLosSwtmr070(VOID); +VOID ItLosSwtmr071(VOID); +VOID ItLosSwtmr075(VOID); +VOID ItLosSwtmr076(VOID); +VOID ItLosSwtmr077(VOID); +VOID ItLosSwtmr078(VOID); +#endif + +#if defined(LOSCFG_TEST_PRESSURE) +VOID ItLosSwtmr004(VOID); +VOID ItLosSwtmr024(VOID); +VOID ItLosSwtmr025(VOID); +VOID ItLosSwtmr026(VOID); +VOID ItLosSwtmr027(VOID); +VOID ItLosSwtmr028(VOID); +VOID ItLosSwtmr029(VOID); +VOID ItLosSwtmr031(VOID); +VOID ItLosSwtmr032(VOID); +VOID ItLosSwtmr034(VOID); +VOID ItLosSwtmr035(VOID); +VOID ItLosSwtmr081(VOID); +VOID ItLosSwtmr082(VOID); +VOID ItLosSwtmr083(VOID); +#endif + +#if defined(LOSCFG_TEST_LLT) +VOID ItLosSwtmr072(VOID); +VOID ItLosSwtmr073(VOID); +VOID ItLosSwtmr074(VOID); +VOID ItLosSwtmr079(VOID); +VOID ItLosSwtmr080(VOID); +VOID ItLosSwtmr023(VOID); +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#endif /* IT_LOS_SWTMR_H */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_001.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_001.c new file mode 100644 index 00000000..2b752781 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_001.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xffff) { + return; + } + + g_testCount++; + return; +} + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID; + g_testCount = 0; + + // 4, Timeout interval of a periodic software timer. + ret = LOS_SwtmrCreate(4, LOS_SWTMR_MODE_ONCE, SwtmrF01, &swTmrID, 0xffff); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrStart(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskDelay(10); // 10, set delay time + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = LOS_TaskDelay(5); // 5, set delay time + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); +#if SELF_DELETED + ret = LOS_SwtmrDelete(swTmrID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); +#endif + return LOS_OK; + +EXIT: + ret = LOS_SwtmrDelete(swTmrID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItLosSwtmr001(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr001", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_002.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_002.c new file mode 100644 index 00000000..4908967c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_002.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xabcdbcda) { + return; + } + + g_testCount++; + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID; + g_testCount = 0; + + // 4, Timeout interval of a periodic software timer. + ret = LOS_SwtmrCreate(4, LOS_SWTMR_MODE_PERIOD, SwtmrF01, &swTmrID, 0xabcdbcda); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrStart(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskDelay(10); // 10, set delay time + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, The expected value + + ret = LOS_SwtmrDelete(swTmrID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskDelay(10); // 10, set delay time + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, The expected value + + return LOS_OK; + +EXIT: + ret = LOS_SwtmrDelete(swTmrID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosSwtmr002(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr002", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_003.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_003.c new file mode 100644 index 00000000..5249655d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_003.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xffff) { + return; + } + + g_testCount++; + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID; + + // 4, Timeout interval of a periodic software timer. + ret = LOS_SwtmrCreate(4, LOS_SWTMR_MODE_ONCE, SwtmrF01, NULL, 0xffff); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_SWTMR_RET_PTR_NULL, ret, EXIT); + + ret = LOS_SwtmrCreate(0, 0, NULL, &swTmrID, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_SWTMR_INTERVAL_NOT_SUITED, ret, EXIT); + + // 4, Timeout interval of a periodic software timer. + ret = LOS_SwtmrCreate(4, LOS_SWTMR_MODE_ONCE, NULL, &swTmrID, 0xffff); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_SWTMR_PTR_NULL, ret, EXIT); + + ret = LOS_SwtmrCreate(0, LOS_SWTMR_MODE_ONCE, SwtmrF01, &swTmrID, 0xffff); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_SWTMR_INTERVAL_NOT_SUITED, ret, EXIT); + + // 4, Timeout interval of a periodic software timer. 3, test mode + ret = LOS_SwtmrCreate(4, 3, SwtmrF01, &swTmrID, 0xffff); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_SWTMR_MODE_INVALID, ret, EXIT); + + return LOS_OK; +EXIT: + ret = LOS_SwtmrDelete(swTmrID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItLosSwtmr003(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr003", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_005.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_005.c new file mode 100644 index 00000000..6095e71a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_005.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xffff) { + return; + } + + g_testCount++; + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID; + + ret = LOS_SwtmrCreate(0x8000, LOS_SWTMR_MODE_PERIOD, SwtmrF01, &swTmrID, 0xffff); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrDelete(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return LOS_OK; +EXIT: + LOS_SwtmrDelete(swTmrID); + return LOS_OK; +} + + +VOID ItLosSwtmr005(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr005", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_006.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_006.c new file mode 100644 index 00000000..9395a09f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_006.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xffff) { + return; + } + + g_testCount++; + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID; + + ret = LOS_SwtmrCreate(0x7fff, LOS_SWTMR_MODE_PERIOD, SwtmrF01, &swTmrID, 0xffff); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrDelete(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return LOS_OK; +EXIT: + LOS_SwtmrDelete(swTmrID); + return LOS_OK; +} + + +VOID ItLosSwtmr006(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr006", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_007.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_007.c new file mode 100644 index 00000000..3d4bc23d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_007.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xffff) { + return; + } + + g_testCount++; + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID; + + // 4, Timeout interval of a periodic software timer. + ret = LOS_SwtmrCreate(4, LOS_SWTMR_MODE_ONCE, SwtmrF01, &swTmrID, 0xffff); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrDelete(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrDelete(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_SWTMR_NOT_CREATED, ret, EXIT); + + return LOS_OK; +EXIT: + LOS_SwtmrDelete(swTmrID); + + return LOS_OK; +} + + +VOID ItLosSwtmr007(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr007", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_008.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_008.c new file mode 100644 index 00000000..fc1ffaae --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_008.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xffff) { + return; + } + + g_testCount++; + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID; + + ret = LOS_SwtmrCreate(1, LOS_SWTMR_MODE_PERIOD, SwtmrF01, &swTmrID, 0xffff); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrDelete(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrDelete(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_SWTMR_NOT_CREATED, ret, EXIT); + + return LOS_OK; +EXIT: + LOS_SwtmrDelete(swTmrID); + + return LOS_OK; +} + + +VOID ItLosSwtmr008(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr008", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_009.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_009.c new file mode 100644 index 00000000..b92c102b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_009.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID = OS_SWTMR_MAX_TIMERID; + + ret = LOS_SwtmrDelete(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_SWTMR_ID_INVALID, ret, EXIT); + + return LOS_OK; +EXIT: + LOS_SwtmrDelete(swTmrID); + return LOS_OK; +} + + +VOID ItLosSwtmr009(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr009", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_010.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_010.c new file mode 100644 index 00000000..6f7e94c0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_010.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xffff) { + return; + } + + g_testCount++; + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID; + g_testCount = 0; + + // 4, Timeout interval of a periodic software timer. + ret = LOS_SwtmrCreate(4, LOS_SWTMR_MODE_ONCE, SwtmrF01, &swTmrID, 0xffff); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrStart(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrDelete(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskDelay(10); // 10, set delay time + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_ASSERT_EQUAL(g_testCount, 0, g_testCount); + + return LOS_OK; + +EXIT: + LOS_SwtmrDelete(swTmrID); + return LOS_OK; +} + + +VOID ItLosSwtmr010(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr010", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_011.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_011.c new file mode 100644 index 00000000..af87ea95 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_011.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xffff) { + return; + } + + g_testCount++; + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID; + g_testCount = 0; + + // 4, Timeout interval of a periodic software timer. + ret = LOS_SwtmrCreate(4, LOS_SWTMR_MODE_PERIOD, SwtmrF01, &swTmrID, 0xffff); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrStart(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrDelete(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskDelay(10); // 10, set delay time + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_ASSERT_EQUAL(g_testCount, 0, g_testCount); + + return LOS_OK; + +EXIT: + ret = LOS_SwtmrDelete(swTmrID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + + +VOID ItLosSwtmr011(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr011", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_012.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_012.c new file mode 100644 index 00000000..3fb5753b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_012.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(UINT32 arg) +{ + UINT32 ret; + + if (arg != 0xffff) { + return; + } +#if SELF_DELETED + ret = LOS_SwtmrDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); +#endif + g_testCount++; + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID; + g_testCount = 0; + + // 4, Timeout interval of a periodic software timer. + ret = LOS_SwtmrCreate(4, LOS_SWTMR_MODE_ONCE, SwtmrF01, &swTmrID, 0xffff); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + g_testTaskID01 = swTmrID; + + ret = LOS_SwtmrStart(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskDelay(10); // 10, set delay time + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + +EXIT: +#if SELF_DELETED + ret = LOS_SwtmrDelete(swTmrID); + ICUNIT_ASSERT_NOT_EQUAL(ret, LOS_OK, ret); +#endif + return LOS_OK; +} + + +VOID ItLosSwtmr012(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr012", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_013.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_013.c new file mode 100644 index 00000000..1af9a1f7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_013.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(UINT32 arg) +{ + UINT32 ret; + + if (arg != 0xffff) { + return; + } + + g_testCount++; + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID; + g_testCount = 0; + + // 4, Timeout interval of a periodic software timer. + ret = LOS_SwtmrCreate(4, LOS_SWTMR_MODE_PERIOD, SwtmrF01, &swTmrID, 0xffff); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrStart(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskDelay(10); // 10, set delay time + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, The expected value + +EXIT: + ret = LOS_SwtmrDelete(swTmrID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosSwtmr013(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr013", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_014.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_014.c new file mode 100644 index 00000000..4b788bd8 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_014.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID = OS_SWTMR_MAX_TIMERID; + + ret = LOS_SwtmrStart(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_SWTMR_ID_INVALID, ret, EXIT); + +EXIT: + LOS_SwtmrDelete(swTmrID); + return LOS_OK; +} + + +VOID ItLosSwtmr014(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr014", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_015.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_015.c new file mode 100644 index 00000000..30dd751e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_015.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xffff) { + return; + } + + g_testCount++; + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID; + g_testCount = 0; + + // 4, Timeout interval of a periodic software timer. + ret = LOS_SwtmrCreate(4, LOS_SWTMR_MODE_ONCE, SwtmrF01, &swTmrID, 0xffff); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrStart(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrStart(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskDelay(10); // 10, set delay time + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + +EXIT: +#if SELF_DELETED + ret = LOS_SwtmrDelete(swTmrID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); +#endif + return LOS_OK; +} + + +VOID ItLosSwtmr015(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr015", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_016.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_016.c new file mode 100644 index 00000000..2edcb6e0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_016.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xabcdbcda) { + return; + } + + g_testCount++; + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID; + g_testCount = 0; + + // 4, Timeout interval of a periodic software timer. + ret = LOS_SwtmrCreate(4, LOS_SWTMR_MODE_PERIOD, SwtmrF01, &swTmrID, 0xabcdbcda); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrStart(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrStart(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskDelay(10); // 10, set delay time + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, The expected value + +EXIT: + ret = LOS_SwtmrDelete(swTmrID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosSwtmr016(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr016", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_017.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_017.c new file mode 100644 index 00000000..81b639bf --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_017.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xffff) { + return; + } + + g_testCount++; + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID; + + ret = LOS_SwtmrCreate(0x8000, LOS_SWTMR_MODE_ONCE, SwtmrF01, &swTmrID, 0xffff); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrDelete(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrStart(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_SWTMR_NOT_CREATED, ret, EXIT); + + return LOS_OK; +EXIT: + LOS_SwtmrDelete(swTmrID); + return LOS_OK; +} + + +VOID ItLosSwtmr017(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr017", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_018.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_018.c new file mode 100644 index 00000000..694f3584 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_018.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xffff) { + return; + } + + g_testCount++; + return; +} + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID; + + ret = LOS_SwtmrCreate(0x8000, LOS_SWTMR_MODE_PERIOD, SwtmrF01, &swTmrID, 0xffff); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrDelete(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrStart(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_SWTMR_NOT_CREATED, ret, EXIT); + + return LOS_OK; +EXIT: + LOS_SwtmrDelete(swTmrID); + return LOS_OK; +} + + +VOID ItLosSwtmr018(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr018", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_019.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_019.c new file mode 100644 index 00000000..05e15827 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_019.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xffff) { + return; + } + + g_testCount++; + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID; + g_testCount = 0; + + // 4, Timeout interval of a periodic software timer. + ret = LOS_SwtmrCreate(4, LOS_SWTMR_MODE_ONCE, SwtmrF01, &swTmrID, 0xffff); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrStart(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskDelay(10); // 10, set delay time + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + return LOS_OK; + +EXIT: + LOS_SwtmrDelete(swTmrID); + + ret = LOS_SwtmrStart(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_SWTMR_NOT_CREATED, ret, EXIT); + return LOS_OK; +} + +VOID ItLosSwtmr019(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr019", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_020.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_020.c new file mode 100644 index 00000000..9bafbfd1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_020.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(UINT32 arg) +{ + UINT32 ret; + + if (arg != 0xffff) { + return; + } +#if SELF_DELETED + ret = LOS_SwtmrStart(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); +#endif + g_testCount++; + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID; + g_testCount = 0; + + // 4, Timeout interval of a periodic software timer. + ret = LOS_SwtmrCreate(4, LOS_SWTMR_MODE_ONCE, SwtmrF01, &swTmrID, 0xffff); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + g_testTaskID01 = swTmrID; + + ret = LOS_SwtmrStart(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskDelay(10); // 10, set delay time + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); +#if SELF_DELETED + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, The expected value +#else + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); +#endif + +EXIT: +#if SELF_DELETED + ret = LOS_SwtmrDelete(swTmrID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); +#endif + return LOS_OK; +} + +VOID ItLosSwtmr020(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr020", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_021.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_021.c new file mode 100644 index 00000000..d337d2ea --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_021.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(UINT32 arg) +{ + UINT32 ret; + + if (arg != 0xffff) { + return; + } +#if SELF_DELETED + ret = LOS_SwtmrStart(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); +#endif + g_testCount++; + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID; + g_testCount = 0; + + // 4, Timeout interval of a periodic software timer. + ret = LOS_SwtmrCreate(4, LOS_SWTMR_MODE_PERIOD, SwtmrF01, &swTmrID, 0xffff); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + g_testTaskID01 = swTmrID; + + ret = LOS_SwtmrStart(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskDelay(10); // 10, set delay time + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, The expected value + +EXIT: + ret = LOS_SwtmrDelete(swTmrID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosSwtmr021(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr021", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_022.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_022.c new file mode 100644 index 00000000..3118d432 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_022.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(UINT32 arg) +{ + if (g_testCount != 2) { // 2, Execute if g_testCount is 2 + return; + } + g_testCount++; + return; +} + +static VOID HwiF01(VOID) +{ + UINT32 ret; + UINT32 hwiNum; +#ifdef TEST3516A + hwiNum = HWI_NUM_INT32; +#elif defined TEST3518E || defined TEST3516CV300 + hwiNum = HWI_NUM_INT31; +#elif defined TEST3559 + hwiNum = HWI_NUM_INT32; +#elif defined TEST3559A + hwiNum = HWI_NUM_INT69; +#elif defined TEST3559A_M7 + hwiNum = HWI_NUM_INT11; +#elif defined TESTPBXA9 || defined TESTVIRTA53 + hwiNum = HWI_NUM_INT60; +#elif defined TEST3516DV300 + hwiNum = HWI_NUM_INT60; +#endif + + TEST_HwiClear(HWI_NUM_TEST3); + g_testCount++; + + // 2, Timeout interval of a periodic software timer. + ret = LOS_SwtmrCreate(2, LOS_SWTMR_MODE_ONCE, SwtmrF01, &g_swTmrID1, 0xffff); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; + + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + g_testCount = 0; + + ret = LOS_HwiCreate(HWI_NUM_TEST3, 1, 0, HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestHwiTrigger(HWI_NUM_TEST3); + + TestExtraTaskDelay(2); // 2, set delay time + + ret = LOS_SwtmrStart(g_swTmrID1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskDelay(5); // 5, set delay time + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, The expected value + +EXIT: + TEST_HwiDelete(HWI_NUM_TEST3); +#if SELF_DELETED + ret = LOS_SwtmrDelete(g_swTmrID1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); +#endif + return LOS_OK; +} + +VOID ItLosSwtmr022(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr022", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_030.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_030.c new file mode 100644 index 00000000..7239f95b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_030.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +static VOID SwtmrF01(UINT32 arg) +{ + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + LOS_AtomicInc(&g_testCount); +} + +static VOID SwtmrF02(UINT32 arg) +{ + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID1; + UINT16 swTmrID2; + int value; + g_testCount = 0; + + // 10, Timeout interval of a periodic software timer. + ret = LOS_SwtmrCreate(10, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)SwtmrF02, &swTmrID1, 0xffff); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + // 10, Timeout interval of a periodic software timer. + ret = LOS_SwtmrCreate(10, LOS_SWTMR_MODE_ONCE, (SWTMR_PROC_FUNC)SwtmrF01, &swTmrID2, 0xffff); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrStart(swTmrID1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrStart(swTmrID2); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + HAL_READ_UINT32(&g_testCount, value); + while (value < 4) { // 4, if value < 4, to do + HAL_READ_UINT32(&g_testCount, value); + } + + ret = LOS_SwtmrDelete(swTmrID1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosSwtmr030(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr030", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_033.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_033.c new file mode 100644 index 00000000..40cf3c17 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_033.c @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID HwiF01(VOID) +{ + UINT32 index; + + TEST_HwiClear(HWI_NUM_TEST); + + for (index = 0; index < TEST_HWI_RUNTIME; index++) { + } + + g_testCount = 10; // 10,Set the number to determine whether the process is as expected. +} + +static VOID SwtmrF01(UINT32 arg) +{ + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 20, g_testCount); // 20, The expected value + g_testCount++; +} + +static VOID SwtmrF02(UINT32 arg) +{ + UINT32 index; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 10, g_testCount); // 10, The expected value + + for (index = 0; index < 0x1000; index++) { + } + + g_testCount = 20; // 20, Set the number to determine whether the process is as expected. +} + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID1; + UINT16 swTmrID2; + int value; + UINT64 tickstart; + + g_testCount = 0; + + ret = LOS_SwtmrCreate(1, LOS_SWTMR_MODE_ONCE, (SWTMR_PROC_FUNC)SwtmrF02, &swTmrID1, 0xffff); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + // 2, Timeout interval of a periodic software timer. + ret = LOS_SwtmrCreate(2, LOS_SWTMR_MODE_ONCE, (SWTMR_PROC_FUNC)SwtmrF01, &swTmrID2, 0xffff); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + ret = LOS_SwtmrStart(swTmrID1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ret = LOS_SwtmrStart(swTmrID2); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestHwiTrigger(HWI_NUM_TEST); + HAL_READ_UINT32(&g_testCount, value); + + tickstart = LOS_TickCountGet(); + + while (value != 21) { // 21, The expected value is not 21, execute + HAL_READ_UINT32(&g_testCount, value); + if (LOS_TickCountGet() - tickstart > 0xff) { + ICUNIT_GOTO_EQUAL(g_testCount, 21, g_testCount, EXIT); // 21, The expected value + } + } + +EXIT: + LOS_SwtmrDelete(swTmrID1); + LOS_SwtmrDelete(swTmrID2); + TEST_HwiDelete(HWI_NUM_TEST); + return LOS_OK; +} + +VOID ItLosSwtmr033(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr033", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_036.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_036.c new file mode 100644 index 00000000..f027814e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_036.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_testSwtmrCount; +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xffff) { + return; + } + + g_testSwtmrCount++; + return; +} +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID; + g_testSwtmrCount = 0; + + ret = LOS_SwtmrCreate(1, LOS_SWTMR_MODE_ONCE, SwtmrF01, &swTmrID, 0xffff); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrStart((swTmrID + 1)); + ICUNIT_ASSERT_NOT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrStart(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskDelay(10); // 10, set delay time + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_testSwtmrCount, 1, g_testSwtmrCount, EXIT); + +#if SELF_DELETED + ret = LOS_SwtmrDelete(swTmrID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); +#endif + return LOS_OK; +EXIT: + LOS_SwtmrDelete(swTmrID); + return LOS_OK; +} + +VOID ItLosSwtmr036(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr036", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_037.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_037.c new file mode 100644 index 00000000..448c1b4d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_037.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xffff) { + return; + } + + g_testCount++; + return; +} +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID1; + + g_testCount = 0; + + ret = LOS_SwtmrCreate(LOS_Tick2MS(1), LOS_SWTMR_MODE_PERIOD, SwtmrF01, &swTmrID1, 0xffff); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrStart((swTmrID1 + 1)); + ICUNIT_ASSERT_NOT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrStart(swTmrID1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrStart(swTmrID1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskDelay(12); // 12, set delay time + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + if (g_testCount < 10) { // 10, if g_testCount < 10 set an erro code, then exit + ICUNIT_GOTO_EQUAL(g_testCount, 10, g_testCount, EXIT); // 10, if g_testCount < 10 set an erro code, then exit + } + +EXIT: + ret = LOS_SwtmrDelete(swTmrID1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosSwtmr037(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr037", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_039.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_039.c new file mode 100644 index 00000000..f349fdf7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_039.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(UINT32 arg) +{ + UINT32 ret; + + TEST_HwiClear(HWI_NUM_TEST); + ret = LOS_SwtmrStart(g_swTmrID1); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testCount1++; + return; + +EXIT: + TEST_HwiDelete(HWI_NUM_TEST); + ret = LOS_SwtmrDelete(g_swTmrID1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_SWTMR_HWI_ACTIVE, ret); +} + +static VOID SwtmrF02(UINT32 arg) +{ + g_testCount1++; + return; +} + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + HWI_PRIOR_T hwiPrio = 3; + HWI_MODE_T hwiMode; + HWI_ARG_T arg = 0; + + g_testCount1 = 0; + ret = LOS_SwtmrCreate(1, LOS_SWTMR_MODE_ONCE, (SWTMR_PROC_FUNC)SwtmrF02, &g_swTmrID1, arg); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT3); + hwiMode = 0; + ret = TEST_HwiCreate(HWI_NUM_TEST, hwiPrio, hwiMode, (HWI_PROC_FUNC)SwtmrF01, (HwiIrqParam *)arg); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT3); +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + TestHwiTrigger(HWI_NUM_TEST); + LOS_TaskDelay(5); // 5, set delay time + ICUNIT_GOTO_EQUAL(g_testCount1, 2, g_testCount1, EXIT5); // 2, The expected value + TEST_HwiDelete(HWI_NUM_TEST); +EXIT5: +#if SELF_DELETED + ret = LOS_SwtmrDelete(g_swTmrID1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); +#endif + TEST_HwiDelete(HWI_NUM_TEST); + return LOS_OK; + +EXIT3: + ret = LOS_SwtmrDelete(g_swTmrID1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + TEST_HwiDelete(HWI_NUM_TEST); + return LOS_OK; +} + +VOID ItLosSwtmr039(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr039", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_040.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_040.c new file mode 100644 index 00000000..c9e0dc7d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_040.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID HwiF01(UINT32 arg) +{ + UINT32 ret; + + TEST_HwiClear(HWI_NUM_TEST); + ret = LOS_SwtmrStart(g_swTmrID1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount1++; + + return; + +EXIT: + ret = LOS_SwtmrDelete(g_swTmrID1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_SWTMR_HWI_ACTIVE, ret); + + TEST_HwiDelete(HWI_NUM_TEST); +} + +static VOID SwtmrF02(UINT32 arg) +{ + g_testCount++; + + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + HWI_PRIOR_T hwiPrio = 1; + HWI_MODE_T hwiMode; + HWI_ARG_T arg = 0; + + g_testCount1 = 0; + g_testCount = 0; + // 5, create swtmr. + ret = LOS_SwtmrCreate(LOS_Tick2MS(5), LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)SwtmrF02, &g_swTmrID1, arg); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT3); + + hwiMode = 0; + ret = TEST_HwiCreate(HWI_NUM_TEST, hwiPrio, hwiMode, (HWI_PROC_FUNC)HwiF01, (HwiIrqParam *)arg); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT3); +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + TestHwiTrigger(HWI_NUM_TEST); + + ret = LOS_TaskDelay(7); // 7, set delay time + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT3); + + ICUNIT_GOTO_EQUAL(g_testCount1, 1, g_testCount1, EXIT3); + ICUNIT_GOTO_NOT_EQUAL(g_testCount, 0, g_testCount, EXIT3); + TEST_HwiDelete(HWI_NUM_TEST); + + ret = LOS_SwtmrDelete(g_swTmrID1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT3); + + TEST_HwiDelete(HWI_NUM_TEST); + + return LOS_OK; +EXIT3: + LOS_SwtmrDelete(g_swTmrID1); + TEST_HwiDelete(HWI_NUM_TEST); + return LOS_OK; +} + +VOID ItLosSwtmr040(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr040", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_041.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_041.c new file mode 100644 index 00000000..05e28865 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_041.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(UINT32 arg) +{ + UINT32 ret; + + TEST_HwiClear(HWI_NUM_TEST); + ret = LOS_SwtmrDelete(g_swTmrID1); + + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = LOS_SwtmrDelete(g_swTmrID2); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + g_testCount1++; + + TEST_HwiDelete(HWI_NUM_TEST); + return; + +EXIT: + LOS_SwtmrDelete(g_swTmrID1); + LOS_SwtmrDelete(g_swTmrID2); + TEST_HwiDelete(HWI_NUM_TEST); + return; +} + +static VOID SwtmrF02(UINT32 arg) +{ + g_testCount1++; + + return; +} + +static VOID SwtmrF03(UINT32 arg) +{ + g_testCount1++; + + return; +} + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + HWI_PRIOR_T hwiPrio = 3; + HWI_MODE_T hwiMode = 0; + HWI_ARG_T arg = 0; + g_testCount1 = 0; + + TEST_HwiClear(HWI_NUM_TEST); + + // 10, Timeout interval of a periodic software timer. + ret = LOS_SwtmrCreate(10, LOS_SWTMR_MODE_ONCE, (SWTMR_PROC_FUNC)SwtmrF03, &g_swTmrID1, arg); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + // 20, Timeout interval of a periodic software timer. + ret = LOS_SwtmrCreate(20, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)SwtmrF02, &g_swTmrID2, arg); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT3); + + ret = TEST_HwiCreate(HWI_NUM_TEST, hwiPrio, hwiMode, (HWI_PROC_FUNC)SwtmrF01, (HwiIrqParam *)arg); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT5); +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + ret = LOS_SwtmrStart(g_swTmrID2); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT5); + + ret = LOS_SwtmrStart(g_swTmrID1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT5); + TestHwiTrigger(HWI_NUM_TEST); + + ret = LOS_TaskDelay(10); // 10, set delay time + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount1, 1, g_testCount1, EXIT5); + TEST_HwiDelete(HWI_NUM_TEST); + return LOS_OK; + +EXIT5: + TEST_HwiDelete(HWI_NUM_TEST); + +EXIT3: + LOS_SwtmrDelete(g_swTmrID2); + +EXIT: + LOS_SwtmrDelete(g_swTmrID1); +} + +VOID ItLosSwtmr041(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr041", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_042.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_042.c new file mode 100644 index 00000000..0f01941d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_042.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xffff) { + return; + } + + g_testCount++; + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID1, swTmrID2; + UINT32 *tick = NULL; + + g_testCount = 0; + + // 10, Timeout interval of a periodic software timer. + ret = LOS_SwtmrCreate(10, LOS_SWTMR_MODE_ONCE, SwtmrF01, &swTmrID1, 0xffff); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrStart(swTmrID1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrStop((OS_SWTMR_MAX_TIMERID + 1)); + ICUNIT_ASSERT_NOT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + ret = LOS_SwtmrDelete(swTmrID1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +EXIT: + LOS_SwtmrDelete(swTmrID1); + return LOS_OK; +} + + +VOID ItLosSwtmr042(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr042", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_043.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_043.c new file mode 100644 index 00000000..b0e37b0f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_043.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(UINT32 arg) +{ + g_testCount1++; + return; +} + +static VOID HwiF01(VOID) +{ + UINT32 ret; + UINT32 tick; + + TEST_HwiClear(HWI_NUM_TEST); + g_testCount1++; + + ret = LOS_SwtmrStart(g_swTmrID1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_SwtmrStop(g_swTmrID1); + ICUNIT_ASSERT_EQUAL_VOID(ret, 0, ret); + + ret = LOS_SwtmrTimeGet(g_swTmrID1, &tick); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_SWTMR_NOT_STARTED, ret); + g_testCount1++; + + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + + g_testCount1 = 0; + + // 2, Timeout interval of a periodic software timer. + ret = LOS_SwtmrCreate(2, LOS_SWTMR_MODE_PERIOD, SwtmrF01, &g_swTmrID1, 0xffff); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + TestHwiTrigger(HWI_NUM_TEST); + + ret = LOS_TaskDelay(1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + +EXIT: + ret = LOS_SwtmrDelete(g_swTmrID1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_HwiDelete(HWI_NUM_TEST); + + return LOS_OK; +} + + +VOID ItLosSwtmr043(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr043", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_044.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_044.c new file mode 100644 index 00000000..34f1055a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_044.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(UINT32 arg) +{ + g_testCount++; + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID; + + // 2, Timeout interval of a periodic software timer. + ret = LOS_SwtmrCreate(2, LOS_SWTMR_MODE_PERIOD, SwtmrF01, &swTmrID, 0xffff); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrStop(swTmrID); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_SWTMR_NOT_STARTED, ret); + + ret = LOS_SwtmrDelete(swTmrID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrStop(swTmrID); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_SWTMR_NOT_CREATED, ret); + return LOS_OK; +} + + +VOID ItLosSwtmr044(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr044", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_045.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_045.c new file mode 100644 index 00000000..645f83e2 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_045.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xffff) { + return; + } + + g_testCount++; + return; +} + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID1, swTmrID2; + g_testCount = 0; + + ret = LOS_SwtmrCreate(1, LOS_SWTMR_MODE_ONCE, SwtmrF01, &swTmrID1, 0xffff); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrCreate(1, LOS_SWTMR_MODE_PERIOD, SwtmrF01, &swTmrID2, 0xffff); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrDelete(swTmrID1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrDelete(swTmrID2); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosSwtmr045(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr045", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_046.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_046.c new file mode 100644 index 00000000..345478bf --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_046.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xffff) { + return; + } + + g_testCount++; + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID1; + g_testCount = 0; + + // 2, set swtmr + ret = LOS_SwtmrCreate(2, LOS_SWTMR_MODE_ONCE | LOS_SWTMR_MODE_PERIOD, SwtmrF01, &swTmrID1, 0xffff); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrStart(swTmrID1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskDelay(21); // 21, set delay time + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_testCount, 10, g_testCount, EXIT); // 10, The expected value + + ret = LOS_SwtmrDelete(swTmrID1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +EXIT: + LOS_SwtmrDelete(swTmrID1); + return LOS_OK; +} + +VOID ItLosSwtmr046(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr046", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_047.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_047.c new file mode 100644 index 00000000..98e3cb76 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_047.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(UINT32 arg) +{ + g_testCount++; + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID1 = 0xffff; + g_testCount = 0; + + ret = LOS_SwtmrCreate(1, 10, SwtmrF01, &swTmrID1, 0xffff); // 10, Timeout interval of a periodic software timer. + ICUNIT_ASSERT_NOT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrDelete(swTmrID1); + ICUNIT_ASSERT_NOT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosSwtmr047(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr047", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_048.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_048.c new file mode 100644 index 00000000..0a1f38c2 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_048.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xffff) { + return; + } + + g_testCount++; + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID1 = (LOSCFG_BASE_CORE_SWTMR_CONFIG - 1); + UINT16 swTmrID2 = (LOSCFG_BASE_CORE_SWTMR_CONFIG - 1); + + g_testCount = 0; + + ret = LOS_SwtmrCreate(1, LOS_SWTMR_MODE_ONCE, SwtmrF01, &swTmrID1, 0xffff); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrDelete(swTmrID1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrCreate(1, LOS_SWTMR_MODE_PERIOD, SwtmrF01, &swTmrID2, 0xffff); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrDelete(swTmrID2); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + + +VOID ItLosSwtmr048(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr048", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_049.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_049.c new file mode 100644 index 00000000..06b8b524 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_049.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xffff) { + return; + } + + g_testCount++; + return; +} +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID1, swTmrID2; + g_testCount = 0; + + ret = LOS_SwtmrCreate(1, LOS_SWTMR_MODE_ONCE, SwtmrF01, &swTmrID1, 0xffff); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrDelete(swTmrID1 + 1); + ICUNIT_ASSERT_NOT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrDelete(swTmrID1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + g_testCount = 0; + ret = LOS_SwtmrCreate(1, LOS_SWTMR_MODE_PERIOD, SwtmrF01, &swTmrID2, 0xffff); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrDelete(swTmrID2 + 1); + ICUNIT_ASSERT_NOT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrDelete(swTmrID2); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + + +VOID ItLosSwtmr049(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr049", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_050.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_050.c new file mode 100644 index 00000000..d5f97694 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_050.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID = OS_SWTMR_MAX_TIMERID; + ret = LOS_SwtmrStart(swTmrID); + ICUNIT_GOTO_NOT_EQUAL(ret, LOS_OK, ret, EXIT); + + return LOS_OK; +EXIT: + LOS_SwtmrDelete(swTmrID); + return LOS_OK; +} + + +VOID ItLosSwtmr050(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr050", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_051.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_051.c new file mode 100644 index 00000000..4721d1cb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_051.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xffff) { + return; + } + + g_testCount++; + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID1, swTmrID2; + g_testCount = 0; + + ret = LOS_SwtmrCreate(1, LOS_SWTMR_MODE_ONCE, SwtmrF01, &swTmrID1, 0xffff); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrDelete(OS_SWTMR_MAX_TIMERID); + ICUNIT_ASSERT_NOT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrDelete(swTmrID1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + g_testCount = 0; + + ret = LOS_SwtmrCreate(1, LOS_SWTMR_MODE_PERIOD, SwtmrF01, &swTmrID2, 0xffff); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrDelete(OS_SWTMR_MAX_TIMERID); + ICUNIT_ASSERT_NOT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrDelete(swTmrID2); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + + +VOID ItLosSwtmr051(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr051", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_052.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_052.c new file mode 100644 index 00000000..70650e0f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_052.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xffff) { + return; + } + + g_testCount++; + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID1, swTmrID2; + g_testCount = 0; + + ret = LOS_SwtmrCreate(1, LOS_SWTMR_MODE_ONCE, SwtmrF01, &swTmrID1, 0xffff); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrDelete(OS_SWTMR_MAX_TIMERID); + ICUNIT_ASSERT_NOT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrDelete(swTmrID1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + g_testCount = 0; + + ret = LOS_SwtmrCreate(1, LOS_SWTMR_MODE_PERIOD, SwtmrF01, &swTmrID2, 0xffff); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrDelete(OS_SWTMR_MAX_TIMERID); + ICUNIT_ASSERT_NOT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrDelete(swTmrID2); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + + +VOID ItLosSwtmr052(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr052", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_054.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_054.c new file mode 100644 index 00000000..e38953cc --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_054.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xffff) { + return; + } + + g_testCount++; + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID1, swTmrID2; + UINT32 tick; + + g_testCount = 0; + + ret = LOS_SwtmrCreate(1, LOS_SWTMR_MODE_PERIOD, SwtmrF01, &swTmrID1, 0xffff); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrTimeGet(swTmrID1 + 1, &tick); + ICUNIT_ASSERT_NOT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrDelete(swTmrID1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + + +VOID ItLosSwtmr054(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr054", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_055.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_055.c new file mode 100644 index 00000000..bf2bf1ac --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_055.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xffff) { + return; + } + + g_testCount++; + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID1, swTmrID2; + UINT32 tick; + + g_testCount = 0; + + ret = LOS_SwtmrCreate(1, LOS_SWTMR_MODE_ONCE, SwtmrF01, &swTmrID1, 0xffff); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrTimeGet(swTmrID1, &tick); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_SWTMR_NOT_STARTED, ret); + + ret = LOS_SwtmrDelete(swTmrID1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + + +VOID ItLosSwtmr055(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr055", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_056.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_056.c new file mode 100644 index 00000000..a5a46bb2 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_056.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xffff) { + return; + } + + g_testCount++; + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID1, swTmrID2; + UINT32 tick; + + g_testCount = 0; + + ret = LOS_SwtmrCreate(1, LOS_SWTMR_MODE_PERIOD, SwtmrF01, &swTmrID1, 0xffff); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrTimeGet(swTmrID1, &tick); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_SWTMR_NOT_STARTED, ret); + + ret = LOS_SwtmrDelete(swTmrID1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + + +VOID ItLosSwtmr056(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr056", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_057.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_057.c new file mode 100644 index 00000000..d9f92ce8 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_057.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xffff) { + return; + } + + g_testCount++; + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID1; + UINT32 *tick = NULL; + + g_testCount = 0; + + ret = LOS_SwtmrCreate(1, LOS_SWTMR_MODE_PERIOD, SwtmrF01, &swTmrID1, 0xffff); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrStart(swTmrID1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrStop(OS_SWTMR_MAX_TIMERID); + ICUNIT_ASSERT_NOT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrDelete(swTmrID1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + + +VOID ItLosSwtmr057(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr057", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_059.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_059.c new file mode 100644 index 00000000..a003cd42 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_059.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xffff) { + return; + } + + g_testCount++; + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID1, swTmrID2; + UINT32 tick; + + g_testCount = 0; + + ret = LOS_SwtmrCreate(1, LOS_SWTMR_MODE_ONCE, SwtmrF01, &swTmrID1, 0xffff); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrTimeGet(OS_SWTMR_MAX_TIMERID, &tick); + ICUNIT_ASSERT_NOT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrDelete(swTmrID1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + + +VOID ItLosSwtmr059(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr059", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_060.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_060.c new file mode 100644 index 00000000..540c2dc9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_060.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xffff) { + return; + } + + g_testCount++; + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID1, swTmrID2; + UINT32 tick; + + g_testCount = 0; + + ret = LOS_SwtmrCreate(1, LOS_SWTMR_MODE_ONCE, SwtmrF01, &swTmrID1, 0xffff); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrTimeGet(OS_SWTMR_MAX_TIMERID, &tick); + ICUNIT_ASSERT_NOT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrDelete(swTmrID1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + + +VOID ItLosSwtmr060(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr060", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_061.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_061.c new file mode 100644 index 00000000..a0f9a47c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_061.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xffff) { + return; + } + + g_testCount++; + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID1, swTmrID2; + UINT32 tick; + + g_testCount = 0; + + ret = LOS_SwtmrCreate(1, LOS_SWTMR_MODE_ONCE, SwtmrF01, &swTmrID1, 0xffff); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrTimeGet((OS_SWTMR_MAX_TIMERID + 1), &tick); + ICUNIT_ASSERT_NOT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrDelete(swTmrID1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 0, g_testCount); + + return LOS_OK; +} + + +VOID ItLosSwtmr061(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr061", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_062.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_062.c new file mode 100644 index 00000000..db2350aa --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_062.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xffff) { + return; + } + + g_testCount++; + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID1, swTmrID2; + UINT32 *tick = NULL; + + g_testCount = 0; + + ret = LOS_SwtmrCreate(1, LOS_SWTMR_MODE_ONCE, SwtmrF01, &swTmrID1, 0xffff); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrTimeGet(swTmrID1, NULL); + ICUNIT_GOTO_NOT_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrDelete(swTmrID1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +EXIT: + LOS_SwtmrDelete(swTmrID1); + return LOS_OK; +} + + +VOID ItLosSwtmr062(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr062", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_063.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_063.c new file mode 100644 index 00000000..e1610458 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_063.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xffff) { + return; + } + + g_testCount++; + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID1, swTmrID2; + UINT32 *tick = NULL; + + g_testCount = 0; + + // 2, Timeout interval of a periodic software timer. + ret = LOS_SwtmrCreate(2, LOS_SWTMR_MODE_ONCE, SwtmrF01, &swTmrID1, 0xffff); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrStart(swTmrID1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrStop((swTmrID1 + 1)); + ICUNIT_ASSERT_NOT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrStop(swTmrID1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrDelete(swTmrID1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + + +VOID ItLosSwtmr063(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr063", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_064.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_064.c new file mode 100644 index 00000000..543eab9c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_064.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(UINT32 arg) +{ + LOS_AtomicInc(&g_testCount); + return; +} +static VOID HwiF01(VOID) +{ + UINT32 ret; + + TEST_HwiClear(HWI_NUM_TEST); + ret = LOS_SwtmrStop(g_swTmrID1); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + LOS_AtomicInc(&g_testCount); + return; + +EXIT: + TEST_HwiDelete(HWI_NUM_TEST); + LOS_SwtmrDelete(g_swTmrID1); +} +static UINT32 Testcase(VOID) +{ + UINT32 ret; + HWI_PRIOR_T hwiPrio = 3; + HWI_MODE_T hwiMode; + HWI_ARG_T arg = 0; + + g_testCount = 0; + // 10, Timeout interval of a periodic software timer. + ret = LOS_SwtmrCreate(10, LOS_SWTMR_MODE_ONCE, (SWTMR_PROC_FUNC)SwtmrF01, &g_swTmrID1, arg); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT3); + + hwiMode = 0; + ret = TEST_HwiCreate(HWI_NUM_TEST, hwiPrio, hwiMode, (HWI_PROC_FUNC)HwiF01, (HwiIrqParam *)arg); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT3); +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + ret = LOS_SwtmrStart(g_swTmrID1); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT3); + + TestHwiTrigger(HWI_NUM_TEST); + + ret = LOS_SwtmrStart(g_swTmrID1); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT3); + + LOS_TaskDelay(15); // 15, set delay time + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT5); // 2, The expected value +#if SELF_DELETED + ret = LOS_SwtmrDelete(g_swTmrID1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); +#endif + TEST_HwiDelete(HWI_NUM_TEST); + return LOS_OK; +EXIT5: +#if SELF_DELETED + ret = LOS_SwtmrDelete(g_swTmrID1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); +#endif + TEST_HwiDelete(HWI_NUM_TEST); + return LOS_OK; +EXIT3: + ret = LOS_SwtmrDelete(g_swTmrID1); + TEST_HwiDelete(HWI_NUM_TEST); + return LOS_OK; +} + +VOID ItLosSwtmr064(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr064", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_065.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_065.c new file mode 100644 index 00000000..ddd739c2 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_065.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID HwiF01(VOID) +{ + UINT32 ret; + + TEST_HwiClear(HWI_NUM_TEST); + ret = LOS_SwtmrStop(g_swTmrID1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + + return; + +EXIT: + LOS_SwtmrDelete(g_swTmrID1); + TEST_HwiDelete(HWI_NUM_TEST); +} +static VOID SwtmrF01(UINT32 arg) +{ + LOS_AtomicInc(&g_testCount); + return; +} +static UINT32 Testcase(VOID) +{ + UINT32 ret; + HWI_PRIOR_T hwiPrio = 1; + HWI_MODE_T hwiMode; + HWI_ARG_T arg = 0; + + g_testCount = 0; + ret = LOS_SwtmrCreate(1, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)SwtmrF01, &g_swTmrID1, arg); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT3); + + hwiMode = 0; + ret = TEST_HwiCreate(HWI_NUM_TEST, hwiPrio, hwiMode, (HWI_PROC_FUNC)HwiF01, (HwiIrqParam *)arg); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT3); +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + ret = LOS_SwtmrStart(g_swTmrID1); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT3); + + TestHwiTrigger(HWI_NUM_TEST); + ret = LOS_TaskDelay(3); // 3, set delay time + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT5); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT5); + TEST_HwiDelete(HWI_NUM_TEST); + ret = LOS_SwtmrDelete(g_swTmrID1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +EXIT5: + ret = LOS_SwtmrDelete(g_swTmrID1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_HwiDelete(HWI_NUM_TEST); + return LOS_OK; + +EXIT3: + ret = LOS_SwtmrDelete(g_swTmrID1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + TEST_HwiDelete(HWI_NUM_TEST); + return LOS_OK; +} + +VOID ItLosSwtmr065(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr065", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_066.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_066.c new file mode 100644 index 00000000..25e91d95 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_066.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xffff) { + return; + } + + g_testCount++; + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID; + UINT32 tick; + g_testCount = 0; + + // 4, Timeout interval of a periodic software timer. + ret = LOS_SwtmrCreate(4, LOS_SWTMR_MODE_ONCE, SwtmrF01, &swTmrID, 0xffff); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrStart(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrTimeGet(swTmrID, &tick); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + if (tick > 4) { // 4, if tick > 4, set an erro code, then exit + ICUNIT_GOTO_EQUAL(1, 0, tick, EXIT); + } + + ret = LOS_TaskDelay(10); // 10, set delay time + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + ret = LOS_TaskDelay(5); // 5, set delay time + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrTimeGet(swTmrID, &tick); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_SWTMR_ID_INVALID, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + +#if SELF_DELETED + ret = LOS_SwtmrDelete(swTmrID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +#endif + return LOS_OK; + +EXIT: + ret = LOS_SwtmrDelete(swTmrID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItLosSwtmr066(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr066", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_067.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_067.c new file mode 100644 index 00000000..5a687653 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_067.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_tick67; +static UINT16 g_swTmrID67; + +static VOID SwtmrF01(UINT32 arg) +{ + UINT32 ret; + if (arg != 0xffff) { + return; + } + + ret = LOS_SwtmrTimeGet(g_swTmrID67, &g_tick67); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_SWTMR_ID_INVALID, ret, EXIT); + + g_testCount++; + return; +EXIT: + LOS_SwtmrDelete(g_swTmrID67); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + + g_testCount = 0; + + // 4, Timeout interval of a periodic software timer. + ret = LOS_SwtmrCreate(4, LOS_SWTMR_MODE_ONCE, SwtmrF01, &g_swTmrID67, 0xffff); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrStart(g_swTmrID67); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskDelay(10); // 10, set delay time + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + ret = LOS_TaskDelay(5); // 5, set delay time + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrTimeGet(g_swTmrID67, &g_tick67); + ICUNIT_GOTO_NOT_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); +#if SELF_DELETED + ret = LOS_SwtmrDelete(g_swTmrID67); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +#endif + return LOS_OK; + +EXIT: + ret = LOS_SwtmrDelete(g_swTmrID67); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItLosSwtmr067(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr067", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_068.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_068.c new file mode 100644 index 00000000..1308c5d1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_068.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xabcdbcda) { + return; + } + + g_testCount++; + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID; + UINT32 tick; + g_testCount = 0; + + // 4, Timeout interval of a periodic software timer. + ret = LOS_SwtmrCreate(4, LOS_SWTMR_MODE_PERIOD, SwtmrF01, &swTmrID, 0xabcdbcda); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrStart(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrTimeGet(swTmrID, &tick); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskDelay(10); // 10, set delay time + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrTimeGet(swTmrID, &tick); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, The expected value + + ret = LOS_SwtmrDelete(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrTimeGet(swTmrID, &tick); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_SWTMR_NOT_CREATED, ret, EXIT); + + ret = LOS_TaskDelay(10); // 10, set delay time + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, The expected value + + return LOS_OK; + +EXIT: + LOS_SwtmrDelete(swTmrID); + return LOS_OK; +} + +VOID ItLosSwtmr068(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr068", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_069.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_069.c new file mode 100644 index 00000000..21ee45a0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_069.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_tick69; +static UINT16 g_swTmrID69; + +static VOID SwtmrF01(UINT32 arg) +{ + UINT32 ret; + if (arg != 0xabcdbcda) { + return; + } + + ret = LOS_SwtmrTimeGet(g_swTmrID69, &g_tick69); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + g_testCount++; + return; +EXIT: + LOS_SwtmrDelete(g_swTmrID69); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + + g_testCount = 0; + + // 4, Timeout interval of a periodic software timer. + ret = LOS_SwtmrCreate(4, LOS_SWTMR_MODE_PERIOD, SwtmrF01, &g_swTmrID69, 0xabcdbcda); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrStart(g_swTmrID69); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskDelay(10); // 10, set delay time + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrTimeGet(g_swTmrID69, &g_tick69); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, The expected value + + ret = LOS_SwtmrDelete(g_swTmrID69); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrTimeGet(g_swTmrID69, &g_tick69); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_SWTMR_NOT_CREATED, ret, EXIT); + + ret = LOS_TaskDelay(10); // 10, set delay time + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, The expected value + + return LOS_OK; +EXIT: + ret = LOS_SwtmrDelete(g_swTmrID69); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItLosSwtmr069(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr069", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_070.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_070.c new file mode 100644 index 00000000..4c713258 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_070.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +UINT32 g_getTickConsume1 = 0; +static UINT32 g_time1, g_time2; +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xffff) { + return; + } + + g_testCount++; + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID; + g_testCount = 0; + g_time1 = g_time2 = 0; + + // 4, Timeout interval of a periodic software timer. + ret = LOS_SwtmrCreate(4, LOS_SWTMR_MODE_ONCE, SwtmrF01, &swTmrID, 0xffff); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrStart(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskDelay(10); // 10, set delay time + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + ret = LOS_TaskDelay(5); // 5, set delay time + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + +#if SELF_DELETED + ret = LOS_SwtmrDelete(swTmrID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); +#endif + return LOS_OK; + +EXIT: + ret = LOS_SwtmrDelete(swTmrID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItLosSwtmr070(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr070", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_071.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_071.c new file mode 100644 index 00000000..2b33ca55 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_071.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +static UINT32 g_tick; +static UINT16 g_swTmrID71; +static VOID SwtmrF01(UINT32 arg) +{ + UINT32 ret; + UINT32 tickTask1; + + if (arg != 0xffff) { + return; + } + + tickTask1 = (UINT32)LOS_TickCountGet(); + g_testCount++; + return; +EXIT: + LOS_SwtmrDelete(g_swTmrID71); + return; +} +static UINT32 Testcase(VOID) +{ + UINT32 ret; + g_testCount = 0; + // 10, Timeout interval of a periodic software timer. + ret = LOS_SwtmrCreate(10, LOS_SWTMR_MODE_ONCE, SwtmrF01, &g_swTmrID71, 0xffff); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrTimeGet(g_swTmrID71, &g_tick); // Gets the number of ticks left in the timer before it starts + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_SWTMR_NOT_STARTED, ret, EXIT); + + ret = 0; + ret = LOS_SwtmrStop(g_swTmrID71); // If the timer is not started, stop + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_SWTMR_NOT_STARTED, ret, EXIT); + + ret = LOS_SwtmrStart(g_swTmrID71); // Start timer + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = 0; + ret = LOS_TaskDelay(5); // 5, set delay time + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrTimeGet(g_swTmrID71, &g_tick); // Gets the number of ticks remaining for the timer being timed + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrStop(g_swTmrID71); // Stops the started timer + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrTimeGet(g_swTmrID71, &g_tick); // Gets the number of ticks left in the stopped timer + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_SWTMR_NOT_STARTED, ret, EXIT); + + ret = LOS_SwtmrStart(g_swTmrID71); // Start the timer again + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskDelay(12); // 12, set delay time + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + ret = LOS_SwtmrDelete(g_swTmrID71); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_SWTMR_ID_INVALID, ret, EXIT); + + // After a single timer executes the callback function, the timer will be deleted, and the timer status will change + // to OS_SWTMR_STATUS_UNUSED + ret = LOS_SwtmrTimeGet(g_swTmrID71, &g_tick); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_SWTMR_ID_INVALID, ret, EXIT); + +#if SELF_DELETED + ret = LOS_SwtmrDelete(g_swTmrID71); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +#endif + + return LOS_OK; +EXIT: + ret = LOS_SwtmrDelete(g_swTmrID71); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItLosSwtmr071(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr071", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_075.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_075.c new file mode 100644 index 00000000..5ca81364 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_075.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xffff) { + return; + } + + g_testCount++; + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID = 0; + + g_testCount = 0; + + // 4, Timeout interval of a periodic software timer. + ret = LOS_SwtmrCreate(4, LOS_SWTMR_MODE_NO_SELFDELETE, (SWTMR_PROC_FUNC)SwtmrF01, &swTmrID, 0xffff); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrStart(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskDelay(10); // 10, set delay time + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + ret = LOS_TaskDelay(10); // 10, set delay time + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + ret = LOS_SwtmrDelete(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return LOS_OK; + +EXIT: + LOS_SwtmrDelete(swTmrID); + return LOS_OK; +} + +VOID ItLosSwtmr075(VOID) +{ + TEST_ADD_CASE("ItLosSwtmr075", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_076.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_076.c new file mode 100644 index 00000000..066c5519 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_076.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xffff) { + return; + } + + g_testCount++; + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID = 0; + g_testCount = 0; + + // 4, Timeout interval of a periodic software timer. + ret = LOS_SwtmrCreate(4, LOS_SWTMR_MODE_ONCE | LOS_SWTMR_MODE_NO_SELFDELETE, (SWTMR_PROC_FUNC)SwtmrF01, &swTmrID, + 0xffff); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrStart(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskDelay(10); // 10, set delay time + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + ret = LOS_TaskDelay(10); // 10, set delay time + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + ret = LOS_SwtmrDelete(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskDelay(10); // 10, set delay time + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + return LOS_OK; + +EXIT: + LOS_SwtmrDelete(swTmrID); + return LOS_OK; +} + +VOID ItLosSwtmr076(VOID) +{ + TEST_ADD_CASE("ItLosSwtmr076", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_077.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_077.c new file mode 100644 index 00000000..f08f8af7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_077.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xffff) { + return; + } + + g_testCount++; + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID; + g_testCount = 0; + + swTmrID = 0xff; + + // 4, Timeout interval of a periodic software timer. + ret = LOS_SwtmrCreate(4, LOS_SWTMR_MODE_PERIOD | LOS_SWTMR_MODE_NO_SELFDELETE, (SWTMR_PROC_FUNC)SwtmrF01, &swTmrID, + 0xffff); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_SWTMR_MODE_INVALID, ret, EXIT); + + ret = LOS_SwtmrStart(swTmrID); + if ((ret != LOS_ERRNO_SWTMR_ID_INVALID) && (ret != LOS_ERRNO_SWTMR_NOT_CREATED)) + ICUNIT_GOTO_EQUAL(1, LOS_OK, ret, EXIT); + + ret = LOS_TaskDelay(10); // 10, set delay time + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrDelete(swTmrID); + if ((ret != LOS_ERRNO_SWTMR_ID_INVALID) && (ret != LOS_ERRNO_SWTMR_NOT_CREATED)) + ICUNIT_GOTO_EQUAL(1, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + return LOS_OK; + +EXIT: + LOS_SwtmrDelete(swTmrID); + return LOS_OK; +} + +VOID ItLosSwtmr077(VOID) +{ + TEST_ADD_CASE("ItLosSwtmr077", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_078.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_078.c new file mode 100644 index 00000000..f2fd5e4e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/full/It_los_swtmr_078.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xffff) { + return; + } + + g_testCount++; + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID = 0xfff; + + g_testCount = 0; + + // 4, Timeout interval of a periodic software timer. + ret = LOS_SwtmrCreate(4, LOS_SWTMR_MODE_OPP, (SWTMR_PROC_FUNC)SwtmrF01, &swTmrID, 0xffff); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_SWTMR_MODE_INVALID, ret, EXIT); + + ret = LOS_SwtmrStart(swTmrID); + if ((ret != LOS_ERRNO_SWTMR_ID_INVALID) && (ret != LOS_ERRNO_SWTMR_NOT_CREATED)) + ICUNIT_GOTO_EQUAL(1, LOS_OK, ret, EXIT); + + ret = LOS_TaskDelay(10); // 10, set delay time + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrDelete(swTmrID); + if ((ret != LOS_ERRNO_SWTMR_ID_INVALID) && (ret != LOS_ERRNO_SWTMR_NOT_CREATED)) + ICUNIT_GOTO_EQUAL(1, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + return LOS_OK; + +EXIT: + LOS_SwtmrDelete(swTmrID); + return LOS_OK; +} + +VOID ItLosSwtmr078(VOID) +{ + TEST_ADD_CASE("ItLosSwtmr078", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smoke/It_los_swtmr_053.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smoke/It_los_swtmr_053.c new file mode 100644 index 00000000..a370cf36 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smoke/It_los_swtmr_053.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xffff) { + return; + } + + g_testCount++; + return; +} +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID1, swTmrID2; + UINT32 tick; + + g_testCount = 0; + + ret = LOS_SwtmrCreate(1, LOS_SWTMR_MODE_ONCE, SwtmrF01, &swTmrID1, 0xffff); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrTimeGet(swTmrID1 + 1, &tick); + ICUNIT_ASSERT_NOT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrDelete(swTmrID1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + + +VOID ItLosSwtmr053(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr053", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smoke/It_los_swtmr_058.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smoke/It_los_swtmr_058.c new file mode 100644 index 00000000..6eb0d091 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smoke/It_los_swtmr_058.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(UINT32 arg) +{ + if (arg != 0xffff) { + return; + } + + g_testCount++; + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID1; + UINT32 *tick = NULL; + + g_testCount = 0; + + ret = LOS_SwtmrCreate(1, LOS_SWTMR_MODE_PERIOD, SwtmrF01, &swTmrID1, 0xffff); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrStart(swTmrID1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrStop((swTmrID1 + 1)); + ICUNIT_ASSERT_NOT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrDelete(swTmrID1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + + +VOID ItLosSwtmr058(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSwtmr058", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_001.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_001.c new file mode 100644 index 00000000..4e02d0b0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_001.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_testTimes; + +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret; + UINT16 testSwtmrHandle; + + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)SwtmrF01, &testSwtmrHandle, 0); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_SwtmrStart(testSwtmrHandle); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_TaskDelay(g_testPeriod * g_testTimes + 5); // g_testPeriod * g_testTimes + 5, set delay time + + ret = LOS_SwtmrStop(testSwtmrHandle); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrDelete(testSwtmrHandle); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + +EXIT: + LOS_SwtmrDelete(testSwtmrHandle); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, testid; + UINT32 coreIdx = 0; + + /* each core run swtmr for 10 times, period is 10 */ + g_testCount = 0; + g_testPeriod = 10; // period is 10 + g_testTimes = 10; // each core run swtmr for 10 times + + while (coreIdx < LOSCFG_KERNEL_CORE_NUM) { + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_swtmr_001_task", TaskF01, TASK_PRIO_TEST_SWTMR - 1, + CPUID_TO_AFFI_MASK(coreIdx)); + ret = LOS_TaskCreate(&testid, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + coreIdx++; + } + + LOS_TaskDelay(g_testPeriod * g_testTimes + 10); // g_testPeriod * g_testTimes + 10, set delay time + + ICUNIT_ASSERT_EQUAL(g_testCount, g_testTimes * LOSCFG_KERNEL_CORE_NUM, g_testCount); + + return LOS_OK; +} + +VOID ItSmpLosSwtmr001(VOID) +{ + TEST_ADD_CASE("ItSmpLosSwtmr001", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_002.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_002.c new file mode 100644 index 00000000..87029a71 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_002.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_testTimes; + +static UINT16 g_swtmrHandle[LOSCFG_KERNEL_CORE_NUM]; + +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(UINTPTR swtmrId) +{ + UINT32 ret; + + ret = LOS_SwtmrStart(swtmrId); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + TestDumpCpuid(); + + return; + +EXIT: + LOS_SwtmrDelete(swtmrId); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, testid; + UINT32 i; + + /* each core run swtmr for 10 times, period is 10 */ + g_testCount = 0; + g_testPeriod = 10; // period is 10 + g_testTimes = 1; + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)SwtmrF01, &g_swtmrHandle[i], 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + TEST_TASK_PARAM_INIT(testTask, "it_swtmr_002_task", TaskF01, + TASK_PRIO_TEST_SWTMR + 1); // not set cpuaffi + testTask.auwArgs[0] = g_swtmrHandle[i]; + testTask.usCpuAffiMask = CPUID_TO_AFFI_MASK(i); + ret = LOS_TaskCreate(&testid, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + UINT64 startTime = LOS_CurrNanosec(); + LOS_TaskDelay(g_testPeriod * g_testTimes + 5); // g_testPeriod * g_testTimes + 5, set delay time + UINT64 usedTime = LOS_CurrNanosec() - startTime; + + ICUNIT_ASSERT_EQUAL(g_testCount, g_testTimes * LOSCFG_KERNEL_CORE_NUM, g_testCount); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + ret = LOS_SwtmrStop(g_swtmrHandle[i]); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrDelete(g_swtmrHandle[i]); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + return LOS_OK; +EXIT: + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + LOS_SwtmrDelete(g_swtmrHandle[i]); + } +} + +VOID ItSmpLosSwtmr002(VOID) +{ + TEST_ADD_CASE("ItSmpLosSwtmr002", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_003.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_003.c new file mode 100644 index 00000000..28d1e937 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_003.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret, currCpuid; + + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_ONCE, (SWTMR_PROC_FUNC)SwtmrF01, &g_swTmrID, 0); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_SwtmrStart(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return; + +EXIT: + LOS_SwtmrDelete(g_swTmrID); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret; + + g_testCount = 0; + g_testPeriod = 10; // period is 10 + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_swtmr_003_task", TaskF01, TASK_PRIO_TEST_SWTMR - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(g_testPeriod + 10); // period is 10 + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + /* do stop and delete */ + ret = LOS_SwtmrStop(g_swTmrID); + ICUNIT_GOTO_NOT_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrDelete(g_swTmrID); + ICUNIT_GOTO_NOT_EQUAL(ret, LOS_OK, ret, EXIT); + return LOS_OK; + +EXIT: + LOS_SwtmrDelete(g_swTmrID); + return LOS_OK; +} + +VOID ItSmpLosSwtmr003(VOID) +{ + TEST_ADD_CASE("ItSmpLosSwtmr003", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_004.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_004.c new file mode 100644 index 00000000..4f396640 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_004.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret; + LOS_AtomicInc(&g_testCount); + ret = LOS_SwtmrStart(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return; + +EXIT: + LOS_SwtmrDelete(g_swTmrID); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret; + UINT32 currCpuid; + + g_testCount = 0; + g_testPeriod = 10; // period is 10 + + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_ONCE, (SWTMR_PROC_FUNC)SwtmrF01, &g_swTmrID, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_swtmr_003_task", TaskF01, TASK_PRIO_TEST_SWTMR - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // cross task + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 1); // 100, Set the timeout of runtime; + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + LOS_TaskDelay(g_testPeriod + 1); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, The expected value + + /* do stop and delete */ + ret = LOS_SwtmrStop(g_swTmrID); + ICUNIT_GOTO_NOT_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrDelete(g_swTmrID); + ICUNIT_GOTO_NOT_EQUAL(ret, LOS_OK, ret, EXIT); + return LOS_OK; + +EXIT: + LOS_SwtmrDelete(g_swTmrID); + return LOS_OK; +} + +VOID ItSmpLosSwtmr004(VOID) +{ + TEST_ADD_CASE("ItSmpLosSwtmr004", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_005.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_005.c new file mode 100644 index 00000000..dd99d9bf --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_005.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret, currCpuid; + + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)SwtmrF01, &g_swTmrID, 0); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_SwtmrStart(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return; + +EXIT: + LOS_SwtmrDelete(g_swTmrID); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret; + + g_testCount = 0; + g_testPeriod = 10; // period is 10 + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_swtmr_005_task", TaskF01, TASK_PRIO_TEST_SWTMR - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(g_testPeriod * 2 + 1); // g_testPeriod*2+1, set delay time + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, The expected value + + /* do stop and delete */ + ret = LOS_SwtmrStop(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrDelete(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + return LOS_OK; + +EXIT: + LOS_SwtmrDelete(g_swTmrID); + return LOS_OK; +} + +VOID ItSmpLosSwtmr005(VOID) +{ + TEST_ADD_CASE("ItSmpLosSwtmr005", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_006.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_006.c new file mode 100644 index 00000000..c2159a88 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_006.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret; + + ret = LOS_SwtmrStart(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return; + +EXIT: + LOS_SwtmrDelete(g_swTmrID); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret; + UINT32 currCpuid; + + g_testCount = 0; + g_testPeriod = 10; // period is 10 + + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)SwtmrF01, &g_swTmrID, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_swtmr_003_task", TaskF01, TASK_PRIO_TEST_SWTMR - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // cross task + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(g_testPeriod * 2 + 1); // g_testPeriod*2+1, set delay time + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, The expected value + + /* do stop and delete */ + ret = LOS_SwtmrStop(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrDelete(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + return LOS_OK; + +EXIT: + LOS_SwtmrDelete(g_swTmrID); + return LOS_OK; +} + +VOID ItSmpLosSwtmr006(VOID) +{ + TEST_ADD_CASE("ItSmpLosSwtmr006", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_007.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_007.c new file mode 100644 index 00000000..5aeae55f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_007.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret, currCpuid; + + ret = LOS_SwtmrStop(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_SWTMR_NOT_STARTED, ret, EXIT); + + return; + +EXIT: + LOS_SwtmrDelete(g_swTmrID); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret; + + g_testCount = 0; + g_testPeriod = 10; // period is 10 + + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_ONCE, (SWTMR_PROC_FUNC)SwtmrF01, &g_swTmrID, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_swtmr_003_task", TaskF01, TASK_PRIO_TEST_SWTMR - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(g_testPeriod + 1); + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + ret = LOS_SwtmrDelete(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + return LOS_OK; + +EXIT: + LOS_SwtmrDelete(g_swTmrID); + return LOS_OK; +} + +VOID ItSmpLosSwtmr007(VOID) +{ + TEST_ADD_CASE("ItSmpLosSwtmr007", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_008.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_008.c new file mode 100644 index 00000000..7e7ebcae --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_008.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret; + + ret = LOS_SwtmrStop(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_SWTMR_NOT_STARTED, ret, EXIT); + + return; + +EXIT: + LOS_SwtmrDelete(g_swTmrID); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret; + UINT32 currCpuid; + + g_testCount = 0; + g_testPeriod = 10; // period is 10 + + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_ONCE, (SWTMR_PROC_FUNC)SwtmrF01, &g_swTmrID, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_swtmr_003_task", TaskF01, TASK_PRIO_TEST_SWTMR - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // cross task + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(g_testPeriod + 1); + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + ret = LOS_SwtmrDelete(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + return LOS_OK; + +EXIT: + LOS_SwtmrDelete(g_swTmrID); + return LOS_OK; +} + +VOID ItSmpLosSwtmr008(VOID) +{ + TEST_ADD_CASE("ItSmpLosSwtmr008", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_009.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_009.c new file mode 100644 index 00000000..db54d29b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_009.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret, currCpuid; + + ret = LOS_SwtmrStop(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_SWTMR_NOT_STARTED, ret, EXIT); + + return; + +EXIT: + LOS_SwtmrDelete(g_swTmrID); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret; + + g_testCount = 0; + g_testPeriod = 10; // period is 10 + + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)SwtmrF01, &g_swTmrID, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_swtmr_009_task", TaskF01, TASK_PRIO_TEST_SWTMR - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(g_testPeriod * 2 + 1); // g_testPeriod*2+1, set delay time + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + ret = LOS_SwtmrDelete(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + return LOS_OK; + +EXIT: + LOS_SwtmrDelete(g_swTmrID); + return LOS_OK; +} + +VOID ItSmpLosSwtmr009(VOID) +{ + TEST_ADD_CASE("ItSmpLosSwtmr009", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_010.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_010.c new file mode 100644 index 00000000..bbc549d5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_010.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret; + + ret = LOS_SwtmrStop(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_SWTMR_NOT_STARTED, ret, EXIT); + + return; + +EXIT: + LOS_SwtmrDelete(g_swTmrID); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret; + UINT32 currCpuid; + + g_testCount = 0; + g_testPeriod = 10; // period is 10 + + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)SwtmrF01, &g_swTmrID, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_swtmr_003_task", TaskF01, TASK_PRIO_TEST_SWTMR - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // cross task + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(g_testPeriod * 2 + 1); // g_testPeriod*2+1, set delay time + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + ret = LOS_SwtmrDelete(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + return LOS_OK; + +EXIT: + LOS_SwtmrDelete(g_swTmrID); + return LOS_OK; +} + +VOID ItSmpLosSwtmr010(VOID) +{ + TEST_ADD_CASE("ItSmpLosSwtmr010", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_011.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_011.c new file mode 100644 index 00000000..f8a60f3e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_011.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret, currCpuid; + + ret = LOS_SwtmrDelete(g_swTmrID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret; + + g_testCount = 0; + g_testPeriod = 10; // period is 10 + + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_ONCE, (SWTMR_PROC_FUNC)SwtmrF01, &g_swTmrID, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_swtmr_003_task", TaskF01, TASK_PRIO_TEST_SWTMR - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(g_testPeriod + 1); + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + return LOS_OK; + +EXIT: + LOS_SwtmrDelete(g_swTmrID); + return LOS_OK; +} + +VOID ItSmpLosSwtmr011(VOID) +{ + TEST_ADD_CASE("ItSmpLosSwtmr011", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_012.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_012.c new file mode 100644 index 00000000..7f6fb59d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_012.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret; + + ret = LOS_SwtmrDelete(g_swTmrID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret; + UINT32 currCpuid; + + g_testCount = 0; + g_testPeriod = 10; // period is 10 + + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_ONCE, (SWTMR_PROC_FUNC)SwtmrF01, &g_swTmrID, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_swtmr_003_task", TaskF01, TASK_PRIO_TEST_SWTMR - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // cross task + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(g_testPeriod + 1); + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + return LOS_OK; + +EXIT: + LOS_SwtmrDelete(g_swTmrID); + return LOS_OK; +} + +VOID ItSmpLosSwtmr012(VOID) +{ + TEST_ADD_CASE("ItSmpLosSwtmr012", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_013.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_013.c new file mode 100644 index 00000000..688783dd --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_013.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret, currCpuid; + + ret = LOS_SwtmrDelete(g_swTmrID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret; + + g_testCount = 0; + g_testPeriod = 10; // period is 10 + + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)SwtmrF01, &g_swTmrID, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_swtmr_013_task", TaskF01, TASK_PRIO_TEST_SWTMR - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(g_testPeriod * 2 + 1); // g_testPeriod*2+1, set delay time + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + return LOS_OK; + +EXIT: + LOS_SwtmrDelete(g_swTmrID); + return LOS_OK; +} + +VOID ItSmpLosSwtmr013(VOID) +{ + TEST_ADD_CASE("ItSmpLosSwtmr013", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_014.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_014.c new file mode 100644 index 00000000..3f76c286 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_014.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret; + + ret = LOS_SwtmrDelete(g_swTmrID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret; + UINT32 currCpuid; + + g_testCount = 0; + g_testPeriod = 10; // period is 10 + + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)SwtmrF01, &g_swTmrID, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_swtmr_014_task", TaskF01, TASK_PRIO_TEST_SWTMR - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // cross task + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(g_testPeriod * 2 + 1); // g_testPeriod*2+1, set delay time + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + return LOS_OK; + +EXIT: + LOS_SwtmrDelete(g_swTmrID); + return LOS_OK; +} + +VOID ItSmpLosSwtmr014(VOID) +{ + TEST_ADD_CASE("ItSmpLosSwtmr014", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_015.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_015.c new file mode 100644 index 00000000..c08564cf --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_015.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret; + + ret = LOS_SwtmrStop(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return; + +EXIT: + LOS_SwtmrDelete(g_swTmrID); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret; + + g_testCount = 0; + g_testPeriod = 10; // period is 10 + + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_ONCE, (SWTMR_PROC_FUNC)SwtmrF01, &g_swTmrID, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrStart(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_swtmr_003_task", TaskF01, TASK_PRIO_TEST_SWTMR - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(g_testPeriod + 1); + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + ret = LOS_SwtmrDelete(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + return LOS_OK; + +EXIT: + LOS_SwtmrDelete(g_swTmrID); + return LOS_OK; +} + +VOID ItSmpLosSwtmr015(VOID) +{ + TEST_ADD_CASE("ItSmpLosSwtmr015", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_016.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_016.c new file mode 100644 index 00000000..1763c9ed --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_016.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret; + + ret = LOS_SwtmrStop(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return; + +EXIT: + LOS_SwtmrDelete(g_swTmrID); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret; + UINT32 currCpuid; + + g_testCount = 0; + g_testPeriod = 10; // period is 10 + + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_ONCE, (SWTMR_PROC_FUNC)SwtmrF01, &g_swTmrID, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrStart(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_swtmr_003_task", TaskF01, TASK_PRIO_TEST_SWTMR - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // cross task + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(g_testPeriod + 1); + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + ret = LOS_SwtmrDelete(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + return LOS_OK; + +EXIT: + LOS_SwtmrDelete(g_swTmrID); + return LOS_OK; +} + +VOID ItSmpLosSwtmr016(VOID) +{ + TEST_ADD_CASE("ItSmpLosSwtmr016", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_017.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_017.c new file mode 100644 index 00000000..1a7d88bd --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_017.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret, currCpuid; + + ret = LOS_SwtmrStop(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return; + +EXIT: + LOS_SwtmrDelete(g_swTmrID); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret; + + g_testCount = 0; + g_testPeriod = 10; // period is 10 + + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)SwtmrF01, &g_swTmrID, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrStart(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_swtmr_009_task", TaskF01, TASK_PRIO_TEST_SWTMR - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(g_testPeriod * 2 + 1); // g_testPeriod*2+1, set delay time + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + ret = LOS_SwtmrDelete(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + return LOS_OK; + +EXIT: + LOS_SwtmrDelete(g_swTmrID); + return LOS_OK; +} + +VOID ItSmpLosSwtmr017(VOID) +{ + TEST_ADD_CASE("ItSmpLosSwtmr017", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_018.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_018.c new file mode 100644 index 00000000..1a25097c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_018.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret; + + ret = LOS_SwtmrStop(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return; + +EXIT: + LOS_SwtmrDelete(g_swTmrID); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret; + UINT32 currCpuid; + + g_testCount = 0; + g_testPeriod = 10; // period is 10 + + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)SwtmrF01, &g_swTmrID, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrStart(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_swtmr_003_task", TaskF01, TASK_PRIO_TEST_SWTMR - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // cross task + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(g_testPeriod * 2 + 1); // g_testPeriod*2+1, set delay time + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + ret = LOS_SwtmrDelete(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + return LOS_OK; + +EXIT: + LOS_SwtmrDelete(g_swTmrID); + return LOS_OK; +} + +VOID ItSmpLosSwtmr018(VOID) +{ + TEST_ADD_CASE("ItSmpLosSwtmr018", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_019.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_019.c new file mode 100644 index 00000000..cba98581 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_019.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret, currCpuid; + + ret = LOS_SwtmrDelete(g_swTmrID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret; + + g_testCount = 0; + g_testPeriod = 10; // period is 10 + + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_ONCE, (SWTMR_PROC_FUNC)SwtmrF01, &g_swTmrID, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrStart(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_swtmr_003_task", TaskF01, TASK_PRIO_TEST_SWTMR - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(g_testPeriod + 1); + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + return LOS_OK; + +EXIT: + LOS_SwtmrDelete(g_swTmrID); + return LOS_OK; +} + +VOID ItSmpLosSwtmr019(VOID) +{ + TEST_ADD_CASE("ItSmpLosSwtmr019", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_020.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_020.c new file mode 100644 index 00000000..146b808d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_020.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret; + + ret = LOS_SwtmrDelete(g_swTmrID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret; + UINT32 currCpuid; + + g_testCount = 0; + g_testPeriod = 10; // period is 10 + + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_ONCE, (SWTMR_PROC_FUNC)SwtmrF01, &g_swTmrID, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrStart(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_swtmr_003_task", TaskF01, TASK_PRIO_TEST_SWTMR - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // cross task + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(g_testPeriod + 1); + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + return LOS_OK; + +EXIT: + LOS_SwtmrDelete(g_swTmrID); + return LOS_OK; +} + +VOID ItSmpLosSwtmr020(VOID) +{ + TEST_ADD_CASE("ItSmpLosSwtmr020", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_021.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_021.c new file mode 100644 index 00000000..d23455db --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_021.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret, currCpuid; + + ret = LOS_SwtmrDelete(g_swTmrID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret; + + g_testCount = 0; + g_testPeriod = 10; // period is 10 + + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)SwtmrF01, &g_swTmrID, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrStart(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_swtmr_009_task", TaskF01, TASK_PRIO_TEST_SWTMR - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(g_testPeriod * 2 + 1); // g_testPeriod*2+1, set delay time + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + return LOS_OK; + +EXIT: + LOS_SwtmrDelete(g_swTmrID); + return LOS_OK; +} + +VOID ItSmpLosSwtmr021(VOID) +{ + TEST_ADD_CASE("ItSmpLosSwtmr021", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_022.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_022.c new file mode 100644 index 00000000..56b752ec --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_022.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret; + + ret = LOS_SwtmrDelete(g_swTmrID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret; + UINT32 currCpuid; + + g_testCount = 0; + g_testPeriod = 10; // period is 10 + + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)SwtmrF01, &g_swTmrID, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrStart(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_swtmr_003_task", TaskF01, TASK_PRIO_TEST_SWTMR - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // cross task + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(g_testPeriod * 2 + 1); // g_testPeriod*2+1, set delay time + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + return LOS_OK; + +EXIT: + LOS_SwtmrDelete(g_swTmrID); + return LOS_OK; +} + +VOID ItSmpLosSwtmr022(VOID) +{ + TEST_ADD_CASE("ItSmpLosSwtmr022", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_023.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_023.c new file mode 100644 index 00000000..60cdd36a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_023.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret; + + ret = LOS_SwtmrStart(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_TaskDelay(g_testPeriod * 2 + 1); // g_testPeriod*2+1, set delay time + + ret = LOS_SwtmrDelete(g_swTmrID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + +EXIT: + LOS_SwtmrDelete(g_swTmrID); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret; + UINT32 currCpuid; + + g_testCount = 0; + g_testPeriod = 10; // period is 10 + + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)SwtmrF01, &g_swTmrID, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_swtmr_003_task", TaskF01, TASK_PRIO_TEST_SWTMR - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // cross task + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(g_testPeriod + 1); + + ret = LOS_SwtmrStop(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + LOS_TaskDelay(g_testPeriod + 1); + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + return LOS_OK; + +EXIT: + LOS_SwtmrDelete(g_swTmrID); + return LOS_OK; +} + +VOID ItSmpLosSwtmr023(VOID) +{ + TEST_ADD_CASE("ItSmpLosSwtmr023", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_024.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_024.c new file mode 100644 index 00000000..496966fe --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_024.c @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret; + + ret = LOS_SwtmrStart(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + TestDumpCpuid(); + return; + +EXIT: + LOS_SwtmrDelete(g_swTmrID); + return; +} + +static void TaskF02(void) +{ + UINT32 ret; + + do { + __asm__ volatile("nop"); + } while (g_testCount != 1); + + LOS_SwtmrStop(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + TestDumpCpuid(); + return; + +EXIT: + LOS_SwtmrDelete(g_swTmrID); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret; + UINT32 currCpuid; + + g_testCount = 0; + g_testPeriod = 10; // period is 10 + + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)SwtmrF01, &g_swTmrID, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_swtmr_024_task1", TaskF01, + TASK_PRIO_TEST_SWTMR + 1, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + testTask.uwResved = LOS_TASK_ATTR_JOINABLE; + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_swtmr_024_task2", TaskF02, + TASK_PRIO_TEST_SWTMR + 1, CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % LOSCFG_KERNEL_CORE_NUM)); + testTask.uwResved = LOS_TASK_ATTR_JOINABLE; + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(g_testPeriod + 1); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + ret = LOS_TaskJoin(g_testTaskID01, NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskJoin(g_testTaskID02, NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_SwtmrDelete(g_swTmrID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + LOS_SwtmrDelete(g_swTmrID); + return LOS_OK; +} + +VOID ItSmpLosSwtmr024(VOID) +{ + TEST_ADD_CASE("ItSmpLosSwtmr024", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_025.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_025.c new file mode 100644 index 00000000..0377b465 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_025.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_szId[LOSCFG_KERNEL_CORE_NUM] = {0}; +static UINT32 g_testSwtmtCount = 0; +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testSwtmtCount); +} + +static void TaskF01(UINT32 index) +{ + UINT32 ret; + + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)SwtmrF01, &g_szId[index], 0); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret; + UINT32 currCpuid; + UINT32 i; + UINT32 taskID[LOSCFG_KERNEL_CORE_NUM]; + g_testSwtmtCount = 0; + g_testPeriod = 10; // period is 10 + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_swtmr_025_task1", TaskF01, TASK_PRIO_TEST_SWTMR + 1, CPUID_TO_AFFI_MASK(i)); + testTask.auwArgs[0] = i; + testTask.uwResved = LOS_TASK_ATTR_JOINABLE; + ret = LOS_TaskCreate(&taskID[i], &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + ret = LOS_TaskJoin(taskID[i], NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + ret = LOS_SwtmrStart(g_szId[i]); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + LOS_TaskDelay(g_testPeriod + 5); /* 5 ticks */ + + ICUNIT_GOTO_EQUAL(g_testSwtmtCount, LOSCFG_KERNEL_CORE_NUM, g_testSwtmtCount, EXIT); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + ret = LOS_SwtmrDelete(g_szId[i]); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + return LOS_OK; + +EXIT: + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + LOS_SwtmrDelete(g_szId[i]); + } + return LOS_OK; +} + +VOID ItSmpLosSwtmr025(VOID) +{ + TEST_ADD_CASE("ItSmpLosSwtmr025", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_026.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_026.c new file mode 100644 index 00000000..fc596eb7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_026.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_sztmrId[LOSCFG_KERNEL_CORE_NUM] = {0}; +static UINT32 g_sztskId[LOSCFG_KERNEL_CORE_NUM] = {0}; + +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(UINT32 index) +{ + UINT32 ret, i, j; + + for (i = 0; i < LOOP; i++) { + for (j = 0; j < TRandom() % 100; j++) { // 100, Gets a random number between 0 and 100 + } + ret = LOS_SwtmrStart(g_sztmrId[index]); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + + TestDumpCpuid(); + return; + +EXIT: + LOS_SwtmrDelete(g_sztmrId[index]); + return; +} + + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret; + UINT32 currCpuid; + UINT32 i, ticks; + + g_testCount = 0; + g_testPeriod = 10; // period is 10 + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)SwtmrF01, &g_sztmrId[i], 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_swtmr_026_task1", TaskF01, TASK_PRIO_TEST_SWTMR - 1, + CPUID_TO_AFFI_MASK((ArchCurrCpuid() + i + 1) % + LOSCFG_KERNEL_CORE_NUM)); // let current cpu 's task create at the last + testTask.auwArgs[0] = i; + ret = LOS_TaskCreate(&g_sztskId[i], &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + TestBusyTaskDelay(g_testPeriod + 1); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + ret = OS_TCB_FROM_TID(g_sztskId[i])->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_UNUSED, 0, ret, EXIT); + ret = LOS_SwtmrTimeGet(g_sztmrId[i], &ticks); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + if (ticks > g_testPeriod) + ICUNIT_GOTO_EQUAL(1, 0, ticks, EXIT); + } + +EXIT: + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + LOS_TaskDelete(g_sztskId[i]); + ret = LOS_SwtmrDelete(g_sztmrId[i]); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + return LOS_OK; +} + +VOID ItSmpLosSwtmr026(VOID) +{ + TEST_ADD_CASE("ItSmpLosSwtmr026", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_027.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_027.c new file mode 100644 index 00000000..8a79c73c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_027.c @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_sztmrId[LOSCFG_KERNEL_CORE_NUM] = {0}; +static UINT32 g_sztskId[LOSCFG_KERNEL_CORE_NUM] = {0}; + +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static VOID TaskF01(UINT32 index) +{ + UINT32 ret, i; + + for (i = 0; i < TRandom() % 500; i++) { // 500, Gets a random number between 0 and 500 + } + + ret = LOS_SwtmrStop(g_sztmrId[index]); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_AtomicInc(&g_testCount1); + TestDumpCpuid(); + return; + +EXIT: + LOS_SwtmrDelete(g_sztmrId[index]); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret; + UINT32 currCpuid; + UINT32 i, j; + + g_testCount = 0; + g_testCount1 = 0; + g_testPeriod = 10; // period is 10 + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)SwtmrF01, &g_sztmrId[i], 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrStart(g_sztmrId[i]); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + + for (j = 0; j < LOOP; j++) { + g_testCount = 0; + g_testCount1 = 0; + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_swtmr_027_task1", TaskF01, TASK_PRIO_TEST_SWTMR - 1, + CPUID_TO_AFFI_MASK((ArchCurrCpuid() + i + 1) % + LOSCFG_KERNEL_CORE_NUM)); // let current cpu 's task create at the last + testTask.auwArgs[0] = i; + ret = LOS_TaskCreate(&g_sztskId[i], &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + LOS_TaskDelay(g_testPeriod * 2); // 2,delay enough time + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + ICUNIT_GOTO_EQUAL(g_testCount1, LOSCFG_KERNEL_CORE_NUM, g_testCount1, EXIT); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + ret = OS_TCB_FROM_TID(g_sztskId[i])->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_UNUSED, 0, ret, EXIT); + + ret = LOS_SwtmrStart(g_sztmrId[i]); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + } + +EXIT: + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + LOS_SwtmrDelete(g_sztmrId[i]); + LOS_TaskDelete(g_sztskId[i]); + } + return LOS_OK; +} + +VOID ItSmpLosSwtmr027(VOID) +{ + TEST_ADD_CASE("ItSmpLosSwtmr027", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_028.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_028.c new file mode 100644 index 00000000..4d7f05f7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_028.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 g_sztmrId[LOSCFG_KERNEL_CORE_NUM] = {0}; +static UINT32 g_sztskId[LOSCFG_KERNEL_CORE_NUM] = {0}; +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(UINT32 index) +{ + UINT32 ret, i; + + for (i = 0; i < TRandom() % 500; i++) { // 500, Gets a random number between 0 and 500 + } + + ret = LOS_SwtmrDelete(g_sztmrId[index]); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_AtomicInc(&g_testCount1); + TestDumpCpuid(); + return; + +EXIT: + LOS_SwtmrDelete(g_sztmrId[index]); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret; + UINT32 currCpuid; + UINT32 i, j; + + g_testPeriod = 10; // period is 10 + + for (j = 0; j < LOOP; j++) { + g_testCount = 0; + g_testCount1 = 0; + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)SwtmrF01, &g_sztmrId[i], 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrStart(g_sztmrId[i]); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_swtmr_028_task1", TaskF01, TASK_PRIO_TEST_SWTMR - 1, + CPUID_TO_AFFI_MASK((ArchCurrCpuid() + i + 1) % + LOSCFG_KERNEL_CORE_NUM)); // let current cpu 's task create at the last + testTask.auwArgs[0] = i; + ret = LOS_TaskCreate(&g_sztskId[i], &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + LOS_TaskDelay(g_testPeriod * 2); // 2, delay enough time + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + ICUNIT_GOTO_EQUAL(g_testCount1, LOSCFG_KERNEL_CORE_NUM, g_testCount1, EXIT); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + ret = OS_TCB_FROM_TID(g_sztskId[i])->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_UNUSED, 0, ret, EXIT); + + LOS_SwtmrDelete(g_sztmrId[i]); // clear the swtmr + LOS_TaskDelete(g_sztskId[i]); + } + } + + return LOS_OK; + +EXIT: + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + LOS_SwtmrDelete(g_sztmrId[i]); + LOS_TaskDelete(g_sztskId[i]); + } + + return LOS_OK; +} + +VOID ItSmpLosSwtmr028(VOID) +{ + TEST_ADD_CASE("ItSmpLosSwtmr028", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_029.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_029.c new file mode 100644 index 00000000..6b548a64 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_029.c @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 g_sztmrId[LOSCFG_KERNEL_CORE_NUM] = {0}; +static UINT32 g_sztskId[LOSCFG_KERNEL_CORE_NUM] = {0}; + +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(VOID) +{ + UINT32 ret, i, j; + + for (i = 0; i < LOOP; i++) { + for (j = 0; j < TRandom() % 100; j++) { // 100, Gets a random number between 0 and 100 + } + + ret = LOS_SwtmrStart(g_sztmrId[0]); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + LOS_AtomicInc(&g_testCount1); + TestDumpCpuid(); + ret = LOS_EventWrite(&g_eventCB, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + return; + +EXIT: + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + LOS_SwtmrDelete(g_sztmrId[i]); + } + return; +} + + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret; + UINT32 currCpuid; + UINT32 i, j; + + g_testCount = 0; + g_testPeriod = 10; // period is 10 + g_testCount1 = 0; + + ret = LOS_EventInit(&g_eventCB); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)SwtmrF01, &g_sztmrId[i], 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_swtmr_029_task1", TaskF01, TASK_PRIO_TEST_SWTMR - 1, + CPUID_TO_AFFI_MASK((ArchCurrCpuid() + i + 1) % + LOSCFG_KERNEL_CORE_NUM)); // let current cpu 's task create at the last + ret = LOS_TaskCreate(&g_sztskId[i], &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + ret = LOS_EventRead(&g_eventCB, LOSCFG_KERNEL_CPU_MASK, LOS_WAITMODE_AND, + LOS_MS2Tick(10000)); // 10000, Converts the number of milliseconds to the number of ticks,and set timeout + LOS_TaskDelay(g_testPeriod + 1); + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + ICUNIT_GOTO_EQUAL(g_testCount1, LOSCFG_KERNEL_CORE_NUM, g_testCount1, EXIT); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + ret = OS_TCB_FROM_TID(g_sztskId[i])->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_UNUSED, 0, ret, EXIT); + } + +EXIT: + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + LOS_TaskDelete(g_sztskId[i]); + ret = LOS_SwtmrDelete(g_sztmrId[i]); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + LOS_EventDestroy(&g_eventCB); + return LOS_OK; +} + +VOID ItSmpLosSwtmr029(VOID) +{ + TEST_ADD_CASE("ItSmpLosSwtmr029", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_030.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_030.c new file mode 100644 index 00000000..333408eb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_030.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_sztskId[LOSCFG_KERNEL_CORE_NUM] = {0}; +static UINT32 g_ret = 0xff; +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret, i; + + for (i = 0; i < TRandom() % 100; i++) { // 100, Gets a random number between 0 and 100 + } + + ret = LOS_SwtmrStop(g_swTmrID); + + LOS_AtomicAdd(&g_ret, ret); + + TestDumpCpuid(); + return; +} + + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret; + UINT32 currCpuid; + UINT32 i, j; + + g_testCount = 0; + g_testPeriod = 10; // period is 10 + + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)SwtmrF01, &g_swTmrID, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrStart(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + for (j = 0; j < LOOP; j++) { + g_testCount = 0; + g_ret = 0xff; + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_swtmr_030_task1", TaskF01, TASK_PRIO_TEST_SWTMR - 1, + CPUID_TO_AFFI_MASK((ArchCurrCpuid() + i + 1) % + LOSCFG_KERNEL_CORE_NUM)); // let current cpu 's task create at the last + ret = LOS_TaskCreate(&g_sztskId[i], &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + LOS_TaskDelay(g_testPeriod * 2); // g_testPeriod*2, delay enough time + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + ICUNIT_GOTO_EQUAL(g_ret, 0xff + LOS_OK + LOS_ERRNO_SWTMR_NOT_STARTED * (LOSCFG_KERNEL_CORE_NUM - 1), g_ret, + EXIT); + + ret = LOS_SwtmrStart(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + +EXIT: + + ret = LOS_SwtmrDelete(g_swTmrID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + LOS_TaskDelete(g_sztskId[i]); + } + return LOS_OK; +} + +VOID ItSmpLosSwtmr030(VOID) +{ + TEST_ADD_CASE("ItSmpLosSwtmr030", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_031.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_031.c new file mode 100644 index 00000000..953b6f96 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_031.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_sztskId[LOSCFG_KERNEL_CORE_NUM] = {0}; +static UINT32 g_ret = 0xff; + +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret, i; + + for (i = 0; i < TRandom() % 100; i++) { // 100, Gets a random number between 0 and 100 + } + + ret = LOS_SwtmrDelete(g_swTmrID); + LOS_AtomicAdd(&g_ret, ret); + + TestDumpCpuid(); + return; + +EXIT: + LOS_SwtmrDelete(g_swTmrID); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret; + UINT32 currCpuid; + UINT32 i, j; + + g_testCount = 0; + g_testPeriod = 10; // period is 10 + + for (j = 0; j < LOOP; j++) { + g_testCount = 0; + g_ret = 0xff; + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)SwtmrF01, &g_swTmrID, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrStart(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_swtmr_031_task1", TaskF01, TASK_PRIO_TEST_SWTMR - 1, + CPUID_TO_AFFI_MASK((ArchCurrCpuid() + i + 1) % + LOSCFG_KERNEL_CORE_NUM)); // let current cpu 's task create at the last + + ret = LOS_TaskCreate(&g_sztskId[i], &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + LOS_TaskDelay(g_testPeriod * 2); // g_testPeriod*2, set delay time + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + ICUNIT_GOTO_EQUAL(g_ret, 0xff + LOS_OK + LOS_ERRNO_SWTMR_NOT_CREATED * (LOSCFG_KERNEL_CORE_NUM - 1), g_ret, + EXIT); + } + +EXIT: + + LOS_SwtmrDelete(g_swTmrID); + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + LOS_TaskDelete(g_sztskId[i]); + } + LOS_TaskDelay(20); // 20, delay + return LOS_OK; +} + +VOID ItSmpLosSwtmr031(VOID) +{ + TEST_ADD_CASE("ItSmpLosSwtmr031", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_032.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_032.c new file mode 100644 index 00000000..8f85fb06 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_032.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_sztmrId[LOSCFG_KERNEL_CORE_NUM] = {0}; +static UINT32 g_sztskId[LOSCFG_KERNEL_CORE_NUM] = {0}; +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static VOID TaskF01(UINT32 index) +{ + UINT32 ret, i, j; + + for (i = 0; i < LOOP; i++) { + for (j = 0; j < TRandom() % 100; j++) { // 100, Gets a random number between 0 and 100 + } + + ret = LOS_SwtmrCreate(LOS_Tick2MS(g_testPeriod), LOS_SWTMR_MODE_PERIOD, + (SWTMR_PROC_FUNC)SwtmrF01, &g_sztmrId[index], 0); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_SwtmrStart(g_sztmrId[index]); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_TaskDelay(g_testPeriod + 3); // +3, have enough time to wait alarm. + + for (j = 0; j < TRandom() % 100; j++) { // 100, Gets a random number between 0 and 100 + } + + ret = LOS_SwtmrStop(g_sztmrId[index]); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrDelete(g_sztmrId[index]); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + TestDumpCpuid(); + return; +EXIT: + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + LOS_SwtmrDelete(g_sztmrId[i]); + } + + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret; + UINT32 currCpuid; + UINT32 i; + + g_testCount = 0; + g_testPeriod = 10; // period is 10 + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_swtmr_032_task1", TaskF01, TASK_PRIO_TEST_SWTMR - 1, + CPUID_TO_AFFI_MASK((ArchCurrCpuid() + i + 1) % + LOSCFG_KERNEL_CORE_NUM)); // let current cpu 's task create at the last + testTask.auwArgs[0] = i; + ret = LOS_TaskCreate(&g_sztskId[i], &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + LOS_TaskDelay(g_testPeriod * LOOP * 10 + 1000); // g_testPeriod*LOOP * 10 +1000, delay enough time + + ICUNIT_GOTO_EQUAL(g_testCount, LOSCFG_KERNEL_CORE_NUM * LOOP, g_testCount, EXIT); + + return LOS_OK; + +EXIT: + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + LOS_SwtmrDelete(g_sztmrId[i]); + LOS_TaskDelete(g_sztskId[i]); + } + return LOS_OK; +} + +VOID ItSmpLosSwtmr032(VOID) +{ + TEST_ADD_CASE("ItSmpLosSwtmr032", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_033.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_033.c new file mode 100644 index 00000000..efc5dca1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_033.c @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_sztskId[LOSCFG_KERNEL_CORE_NUM] = {0}; +static UINT32 g_ret; +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testCount); +} +static VOID TaskF01(void) +{ + UINT32 ret, i; + + for (i = 0; i < TRandom() % 500; i++) { // 500, Gets a random number between 0 and 500 + } + + ret = LOS_SwtmrStart(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + return; +EXIT: + LOS_SwtmrDelete(g_swTmrID); + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + return; +} + +static VOID TaskF02(void) +{ + UINT32 ret, i; + + for (i = 0; i < TRandom() % 500; i++) { // 500, Gets a random number between 0 and 500 + } + + ret = LOS_SwtmrStop(g_swTmrID); + g_ret = ret; + return; +EXIT: + LOS_SwtmrDelete(g_swTmrID); + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret; + UINT32 currCpuid; + UINT32 i; + + g_testPeriod = 10; // period is 10 + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)SwtmrF01, &g_swTmrID, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + for (i = 0; i < LOOP; i++) { + g_testCount = 0; + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_swtmr_033_task1", TaskF01, TASK_PRIO_TEST_SWTMR - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_swtmr_033_task1", TaskF02, TASK_PRIO_TEST_SWTMR - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(1); + + if ((g_ret != LOS_OK) && (g_ret != LOS_ERRNO_SWTMR_NOT_STARTED)) { + ICUNIT_GOTO_EQUAL(1, 0, g_ret, EXIT); + } + + if (g_ret == LOS_ERRNO_SWTMR_NOT_STARTED) { // timer is started and stop failed + LOS_TaskDelay(g_testPeriod + 1); + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + } + + LOS_SwtmrStop(g_swTmrID); + } + + ret = LOS_SwtmrDelete(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + LOS_SwtmrDelete(g_swTmrID); + return LOS_OK; +} + +VOID ItSmpLosSwtmr033(VOID) +{ + TEST_ADD_CASE("ItSmpLosSwtmr033", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_034.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_034.c new file mode 100644 index 00000000..45e9f210 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_034.c @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_sztmrId[LOSCFG_KERNEL_CORE_NUM] = {0}; +static UINT32 g_sztskId[LOSCFG_KERNEL_CORE_NUM] = {0}; +static volatile UINT32 g_flag = 0; +static volatile UINT32 g_mStop = 0; +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testCount); +} +static UINT32 Calsum(UINT32 begin, UINT32 end) +{ + UINT32 result = 0; + UINT32 i; + LOS_ASSERT(begin < end); + for (i = begin; i <= end; i++) + result += i; + return result; +} +static VOID TaskF01(UINT32 index) +{ + UINT32 ret, i, j; + ret = LOS_SwtmrCreate(LOS_Tick2MS(g_testPeriod), LOS_SWTMR_MODE_PERIOD, + (SWTMR_PROC_FUNC)SwtmrF01, &g_sztmrId[index], 0); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + LOS_AtomicAdd(&g_flag, index); + while (g_flag != g_mStop) { // wait for all swtmr create + } + + for (i = 0; i < LOOP; i++) { + for (j = 0; j < TRandom() % 100; j++) { // 100, Gets a random number between 0 and 100 + } + + ret = LOS_SwtmrStart(g_sztmrId[index]); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_TaskDelay(g_testPeriod + 1); + + ret = LOS_SwtmrStop(g_sztmrId[index]); // cross + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + LOS_TaskDelay(1); + } + TestDumpCpuid(); + return; +EXIT: + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + LOS_SwtmrDelete(g_sztmrId[i]); + } + + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret; + UINT32 currCpuid; + UINT32 i; + + g_testCount = 0; + g_flag = 0; + g_testPeriod = 10; // period is 10 + g_mStop = Calsum(0, LOSCFG_KERNEL_CORE_NUM - 1); + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_swtmr_032_task1", TaskF01, TASK_PRIO_TEST_SWTMR - 1, + CPUID_TO_AFFI_MASK((ArchCurrCpuid() + i + 1) % + LOSCFG_KERNEL_CORE_NUM)); // let current cpu 's task create at the last + testTask.auwArgs[0] = i; + ret = LOS_TaskCreate(&g_sztskId[i], &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + LOS_TaskDelay(g_testPeriod * LOOP + 20000); // g_testPeriod*LOOP+20000, delay enough time + + ICUNIT_GOTO_EQUAL(g_testCount, LOSCFG_KERNEL_CORE_NUM * LOOP, g_testCount, EXIT); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + ret = LOS_SwtmrDelete(g_sztmrId[i]); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + LOS_TaskDelete(g_sztskId[i]); + } + return LOS_OK; + +EXIT: + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + LOS_SwtmrDelete(g_sztmrId[i]); + LOS_TaskDelete(g_sztskId[i]); + } + return LOS_OK; +} + +VOID ItSmpLosSwtmr034(VOID) +{ + TEST_ADD_CASE("ItSmpLosSwtmr034", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_035.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_035.c new file mode 100644 index 00000000..cd992ef8 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/swtmr/smp/It_smp_los_swtmr_035.c @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_sztskId[LOSCFG_KERNEL_CORE_NUM] = {0}; +static UINT32 g_ret = 0xff; +static VOID SwtmrF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static VOID TaskF01(void) +{ + UINT32 ret, i; + + for (i = 0; i < TRandom() % 500; i++) { // 500, Gets a random number between 0 and 500 + } + + ret = LOS_SwtmrStart(g_swTmrID); + g_ret = ret; + return; +EXIT: + LOS_SwtmrDelete(g_swTmrID); + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + return; +} + +static VOID TaskF02(void) +{ + UINT32 ret, i; + + for (i = 0; i < TRandom() % 500; i++) { // 500, Gets a random number between 0 and 500 + } + + ret = LOS_SwtmrDelete(g_swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return; +EXIT: + LOS_SwtmrDelete(g_swTmrID); + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret; + UINT32 currCpuid; + UINT32 i; + + g_testPeriod = 10; // period is 10 + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + for (i = 0; i < LOOP; i++) { + g_testCount = 0; + + ret = LOS_SwtmrCreate(g_testPeriod, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)SwtmrF01, &g_swTmrID, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_swtmr_033_task1", TaskF01, TASK_PRIO_TEST_SWTMR - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_swtmr_033_task1", TaskF02, TASK_PRIO_TEST_SWTMR - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(1); + + if ((g_ret != LOS_OK) && (g_ret != LOS_ERRNO_SWTMR_NOT_CREATED)) { + ICUNIT_GOTO_EQUAL(1, 0, g_ret, EXIT); + } + + LOS_TaskDelay(g_testPeriod + 10); // g_testPeriod+10, delay enough time + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + LOS_SwtmrDelete(g_swTmrID); + } + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + LOS_SwtmrDelete(g_swTmrID); + return LOS_OK; +} + +VOID ItSmpLosSwtmr035(VOID) +{ + TEST_ADD_CASE("ItSmpLosSwtmr035", Testcase, TEST_LOS, TEST_SWTMR, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/It_los_task.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/It_los_task.c new file mode 100644 index 00000000..c48f04e3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/It_los_task.c @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#define LOSCFG_TEST_UNSOLVED 1 +volatile UINT64 g_itTimesliceTestCount1 = 0; +volatile INT32 g_timesliceTestCount = 0; + +void ItSuiteLosTask(void) +{ +#if defined(LOSCFG_TEST_SMOKE) + ItLosTask045(); + ItLosTask046(); + ItLosTask089(); + ItLosTask097(); + ItLosTask101(); + ItLosTask099(); + ItLosTaskTimeslice001(); +#ifdef LOSCFG_KERNEL_SMP + ItSmpLosTask001(); /* Task Affinity */ + ItSmpLosTask002(); /* Task Deletion Across Cores */ + ItSmpLosTask003(); /* Task Suspend Across Cores */ + ItSmpLosTask004(); /* Task Created Unbinded */ +#endif +#endif + +#if defined(LOSCFG_TEST_FULL) + // fixed + ItSmpLosTask099(); + ItSmpLosTask049(); + ItSmpLosTask130(); + ItSmpLosTask159(); + ItSmpLosTask161(); + ItSmpLosTask137(); + ItSmpLosTask021(); + ItSmpLosTask022(); + ItSmpLosTask023(); + ItSmpLosTask025(); + ItSmpLosTask026(); + ItSmpLosTask027(); + ItSmpLosTask028(); + ItSmpLosTask029(); + ItSmpLosTask030(); + ItSmpLosTask032(); + ItSmpLosTask033(); + ItSmpLosTask034(); + ItSmpLosTask035(); + ItSmpLosTask036(); + ItSmpLosTask037(); + ItSmpLosTask040(); + ItSmpLosTask042(); + ItSmpLosTask043(); + ItSmpLosTask044(); + ItSmpLosTask046(); + ItSmpLosTask047(); + ItSmpLosTask048(); + ItSmpLosTask050(); + ItSmpLosTask052(); + ItSmpLosTask053(); + ItSmpLosTask054(); + ItSmpLosTask055(); + ItSmpLosTask056(); + ItSmpLosTask057(); + ItSmpLosTask058(); + ItSmpLosTask059(); + ItSmpLosTask060(); + ItSmpLosTask061(); + ItSmpLosTask062(); + ItSmpLosTask063(); + ItSmpLosTask064(); + ItSmpLosTask065(); + ItSmpLosTask066(); + ItSmpLosTask067(); + ItSmpLosTask068(); + ItSmpLosTask069(); + ItSmpLosTask070(); + ItSmpLosTask071(); + ItSmpLosTask073(); + ItSmpLosTask074(); + ItSmpLosTask076(); + ItSmpLosTask077(); + ItSmpLosTask078(); + ItSmpLosTask079(); + ItSmpLosTask081(); + ItSmpLosTask084(); + ItSmpLosTask087(); + ItSmpLosTask088(); + ItSmpLosTask089(); + ItSmpLosTask090(); + ItSmpLosTask091(); + ItSmpLosTask092(); + ItSmpLosTask093(); + ItSmpLosTask094(); + ItSmpLosTask095(); + ItSmpLosTask096(); + ItSmpLosTask098(); + ItSmpLosTask100(); + ItSmpLosTask101(); + ItSmpLosTask102(); + ItSmpLosTask103(); + ItSmpLosTask105(); + ItSmpLosTask106(); + ItSmpLosTask107(); + ItSmpLosTask108(); + ItSmpLosTask109(); + ItSmpLosTask110(); + ItSmpLosTask112(); + ItSmpLosTask114(); + ItSmpLosTask115(); +#ifndef LOSCFG_KERNEL_SMP_TASK_SYNC + ItSmpLosTask117(); +#endif + ItSmpLosTask126(); + ItSmpLosTask127(); + ItSmpLosTask128(); + ItSmpLosTask129(); + ItSmpLosTask131(); + ItSmpLosTask132(); + ItSmpLosTask133(); + ItSmpLosTask134(); + ItSmpLosTask135(); + ItSmpLosTask136(); + ItSmpLosTask138(); + ItSmpLosTask139(); + ItSmpLosTask141(); + ItSmpLosTask142(); + ItSmpLosTask143(); + ItSmpLosTask144(); + ItSmpLosTask145(); + ItSmpLosTask146(); + ItSmpLosTask147(); + ItSmpLosTask148(); + ItSmpLosTask149(); + ItSmpLosTask150(); + ItSmpLosTask151(); + ItSmpLosTask152(); + ItSmpLosTask153(); + ItSmpLosTask154(); + ItSmpLosTask155(); + ItSmpLosTask156(); + ItSmpLosTask157(); +#endif +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/It_los_task.h b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/It_los_task.h new file mode 100644 index 00000000..ab1e54f4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/It_los_task.h @@ -0,0 +1,368 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IT_LOS_TASK_H +#define IT_LOS_TASK_H + +#include "osTest.h" +#include "los_base_pri.h" +#include "los_task_pri.h" +#include "los_tick_pri.h" +#include "los_list.h" +#include "los_process_pri.h" +#include "los_percpu_pri.h" +#include "los_swtmr_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#define SELF_DELETED 0 +#define SYS_EXIST_SWTMR 1 +#define SWTMR_LOOP_NUM 10 +#define TEST_HWI_RUNTIME 0x100000 +#define TASK_LOOP_NUM 0x100000 +#ifdef LOSCFG_BASE_CORE_SWTMR_ENABLE +#define TASK_EXISTED_NUM 4 +#else +#define TASK_EXISTED_NUM 2 +#endif + +#define TASK_EXISTED_D_NUM TASK_EXISTED_NUM +#define TASK_NAME_NUM 10 +#define IT_TASK_LOOP 20 +#define IT_TASK_SMP_LOOP 100 + +extern EVENT_CB_S g_eventCB; +extern EVENT_CB_S g_eventCB1; +extern EVENT_CB_S g_eventCB2; +extern EVENT_CB_S g_eventCB3; + +extern UINT32 g_testTaskID01; +extern UINT32 g_testTaskID02; +extern UINT32 g_testTaskID03; +extern UINT32 g_testTskHandle; +extern UINT32 g_swTmrMaxNum; + +extern UINT8 g_mUsIndex; +extern UINT16 g_swTmrID1; +extern UINT16 g_swTmrID2; +extern UINT16 g_swTmrID3; + +extern UINT32 g_swtmrCountA; +extern UINT32 g_swtmrCountB; +extern UINT32 g_swtmrCountC; +extern UINT64 g_cpuTickCountA; +extern UINT64 g_cpuTickCountB; +extern UINT32 g_leavingTaskNum; + +extern UINT32 g_mAuwTestTaskId[32]; + +extern volatile UINT64 g_itTimesliceTestCount1; +extern volatile INT32 g_timesliceTestCount; + +extern UINT32 OsPriQueueTotalSize(void); +extern void ItSuiteLosTask(void); + + +#if defined(LOSCFG_TEST_SMP) +void ItSmpLosTask001(void); +void ItSmpLosTask002(void); +void ItSmpLosTask003(void); +void ItSmpLosTask004(void); +void ItSmpLosTask021(void); +void ItSmpLosTask022(void); +void ItSmpLosTask023(void); +void ItSmpLosTask025(void); +void ItSmpLosTask026(void); +void ItSmpLosTask027(void); +void ItSmpLosTask028(void); +void ItSmpLosTask029(void); +void ItSmpLosTask030(void); +void ItSmpLosTask031(void); +void ItSmpLosTask032(void); +void ItSmpLosTask033(void); +void ItSmpLosTask034(void); +void ItSmpLosTask035(void); +void ItSmpLosTask036(void); +void ItSmpLosTask037(void); +void ItSmpLosTask038(void); +void ItSmpLosTask039(void); +void ItSmpLosTask040(void); +void ItSmpLosTask041(void); +void ItSmpLosTask042(void); +void ItSmpLosTask043(void); +void ItSmpLosTask044(void); +void ItSmpLosTask045(void); +void ItSmpLosTask046(void); +void ItSmpLosTask047(void); +void ItSmpLosTask048(void); +void ItSmpLosTask049(void); +void ItSmpLosTask050(void); +void ItSmpLosTask051(void); +void ItSmpLosTask052(void); +void ItSmpLosTask053(void); +void ItSmpLosTask054(void); +void ItSmpLosTask055(void); +void ItSmpLosTask056(void); +void ItSmpLosTask057(void); +void ItSmpLosTask058(void); +void ItSmpLosTask059(void); +void ItSmpLosTask060(void); +void ItSmpLosTask061(void); +void ItSmpLosTask062(void); +void ItSmpLosTask063(void); +void ItSmpLosTask064(void); +void ItSmpLosTask065(void); +void ItSmpLosTask066(void); +void ItSmpLosTask067(void); +void ItSmpLosTask068(void); +void ItSmpLosTask069(void); +void ItSmpLosTask070(void); +void ItSmpLosTask071(void); +void ItSmpLosTask073(void); +void ItSmpLosTask074(void); +void ItSmpLosTask076(void); +void ItSmpLosTask077(void); +void ItSmpLosTask078(void); +void ItSmpLosTask079(void); +void ItSmpLosTask081(void); +void ItSmpLosTask082(void); +void ItSmpLosTask084(void); +void ItSmpLosTask087(void); +void ItSmpLosTask088(void); +void ItSmpLosTask089(void); +void ItSmpLosTask090(void); +void ItSmpLosTask091(void); +void ItSmpLosTask092(void); +void ItSmpLosTask093(void); +void ItSmpLosTask094(void); +void ItSmpLosTask095(void); +void ItSmpLosTask096(void); +void ItSmpLosTask097(void); +void ItSmpLosTask098(void); +void ItSmpLosTask099(void); +void ItSmpLosTask100(void); +void ItSmpLosTask101(void); +void ItSmpLosTask102(void); +void ItSmpLosTask103(void); +void ItSmpLosTask104(void); +void ItSmpLosTask105(void); +void ItSmpLosTask106(void); +void ItSmpLosTask107(void); +void ItSmpLosTask108(void); +void ItSmpLosTask109(void); +void ItSmpLosTask110(void); +void ItSmpLosTask111(void); +void ItSmpLosTask112(void); +void ItSmpLosTask114(void); +void ItSmpLosTask115(void); +void ItSmpLosTask117(void); +void ItSmpLosTask126(void); +void ItSmpLosTask127(void); +void ItSmpLosTask128(void); +void ItSmpLosTask129(void); +void ItSmpLosTask130(void); +void ItSmpLosTask131(void); +void ItSmpLosTask132(void); +void ItSmpLosTask133(void); +void ItSmpLosTask134(void); +void ItSmpLosTask135(void); +void ItSmpLosTask136(void); +void ItSmpLosTask137(void); +void ItSmpLosTask138(void); +void ItSmpLosTask139(void); +void ItSmpLosTask141(void); +void ItSmpLosTask142(void); +void ItSmpLosTask143(void); +void ItSmpLosTask144(void); +void ItSmpLosTask145(void); +void ItSmpLosTask146(void); +void ItSmpLosTask147(void); +void ItSmpLosTask148(void); +void ItSmpLosTask149(void); +void ItSmpLosTask150(void); +void ItSmpLosTask151(void); +void ItSmpLosTask152(void); +void ItSmpLosTask153(void); +void ItSmpLosTask154(void); +void ItSmpLosTask155(void); +void ItSmpLosTask156(void); +void ItSmpLosTask157(void); +void ItSmpLosTask158(void); +void ItSmpLosTask159(void); +void ItSmpLosTask161(void); +#endif + +#ifdef LOSCFG_TEST_SMOKE +void ItLosTask081(void); +#endif + +#if defined(LOSCFG_TEST_SMOKE) +void ItLosTask045(void); +void ItLosTask046(void); +void ItLosTask049(void); +void ItLosTask081(void); +void ItLosTask089(void); +void ItLosTask097(void); +void ItLosTask099(void); +void ItLosTask101(void); +void ItLosTask105(void); +#endif + +#if defined(LOSCFG_TEST_FULL) +void ItLosTask001(void); +void ItLosTask002(void); +void ItLosTask004(void); +void ItLosTask007(void); +void ItLosTask008(void); +void ItLosTask009(void); +void ItLosTask010(void); +void ItLosTask011(void); +void ItLosTask012(void); +void ItLosTask013(void); +void ItLosTask014(void); +void ItLosTask015(void); +void ItLosTask016(void); +void ItLosTask017(void); +void ItLosTask018(void); +void ItLosTask019(void); +void ItLosTask020(void); +void ItLosTask021(void); +void ItLosTask022(void); +void ItLosTask023(void); +void ItLosTask024(void); +void ItLosTask025(void); +void ItLosTask026(void); +void ItLosTask027(void); +void ItLosTask028(void); +void ItLosTask029(void); +void ItLosTask031(void); +void ItLosTask032(void); +void ItLosTask033(void); +void ItLosTask034(void); +void ItLosTask035(void); +void ItLosTask036(void); +void ItLosTask037(void); +void ItLosTask038(void); +void ItLosTask039(void); +void ItLosTask040(void); +void ItLosTask041(void); +void ItLosTask042(void); +void ItLosTask043(void); +void ItLosTask047(void); +void ItLosTask048(void); +void ItLosTask050(void); +void ItLosTask051(void); +void ItLosTask052(void); +void ItLosTask053(void); +void ItLosTask054(void); +void ItLosTask055(void); +void ItLosTask056(void); +void ItLosTask057(void); +void ItLosTask058(void); +void ItLosTask060(void); +void ItLosTask061(void); +void ItLosTask063(void); +void ItLosTask064(void); +void ItLosTask065(void); +void ItLosTask066(void); +void ItLosTask067(void); +void ItLosTask068(void); +void ItLosTask069(void); +void ItLosTask071(void); +void ItLosTask072(void); +void ItLosTask073(void); +void ItLosTask074(void); +void ItLosTask075(void); +void ItLosTask076(void); +void ItLosTask077(void); +void ItLosTask078(void); +void ItLosTask079(void); +void ItLosTask080(void); +void ItLosTask082(void); +void ItLosTask090(void); +void ItLosTask092(void); +void ItLosTask093(void); +void ItLosTask094(void); +void ItLosTask095(void); +void ItLosTask096(void); +void ItLosTask098(void); +void ItLosTask100(void); +void ItLosTask102(void); +void ItLosTask103(void); +void ItLosTask104(void); +void ItLosTask106(void); +void ItLosTask107(void); +void ItLosTask108(void); +void ItLosTask109(void); +void ItLosTask110(void); +void ItLosTask111(void); +void ItLosTask112(void); +void ItLosTask113(void); +void ItLosTask114(void); +void ItLosTask115(void); +void ItLosTask116(void); +void ItLosTask118(void); +void ItLosTask119(void); +void ItLosTask120(void); +void ItLosTask121(void); +void ItLosTask122(void); +void ItLosTask123(void); +void ItLosTask124(void); +void ItLosTask125(void); +void ItLosTask126(void); +void ItLosTask127(void); +void ItLosTask128(void); +void ItLosTask129(void); +void ItLosTask130(void); +void ItLosTask131(void); +void ItLosTask132(void); +void ItLosTask133(void); +void ItLosTask134(void); +void ItLosTask135(void); +void ItLosTask136(void); +void ItLosTask138(void); +void ItLosTaskTimeslice001(void); +void ItLosTaskTimeslice002(void); +void ItLosTaskTimeslice003(void); +void ItLosTaskTimeslice004(void); +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#endif diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/float/It_los_float.h b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/float/It_los_float.h new file mode 100644 index 00000000..a8429ef4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/float/It_los_float.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IT_LOS_FLOAT_H +#define IT_LOS_FLOAT_H + +#include "los_base.h" +#include "los_task.h" +#include "los_atomic.h" +#include "osTest.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +extern void ItSuiteLosFloat(void); + +#if defined(LOSCFG_TEST_SMOKE) +#if defined(LOSCFG_TEST_SMP) +void ItSmpLosFloatSwitch001(void); +void ItSmpLosFloatSwitch002(void); +void ItSmpLosFloatSwitch003(void); +void ItSmpLosFloatSwitch004(void); +void ItSmpLosFloatSwitch005(void); +void ItSmpLosFloatSwitch006(void); +void ItSmpLosFloatSwitch007(void); +#endif +#endif +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#endif \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/float/It_smp_los_float_switch_001.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/float/It_smp_los_float_switch_001.c new file mode 100644 index 00000000..78ff1cbb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/float/It_smp_los_float_switch_001.c @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_float.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#ifndef LOSCFG_ARCH_FPU_DISABLE +static UINT32 g_sz[LOSCFG_KERNEL_CORE_NUM] = {0}; +static void TaskF01(UINT32 arg) +{ + UINT32 temp1 = 0xffff; + UINT32 temp2; + FLOAT a = 123.321; + FLOAT b = 1234.4321; + FLOAT c = 999.002345; + FLOAT d, f, e; + LOS_AtomicInc(&g_testCount); + + while (temp1--) { + temp2 = 0xffff; + while (temp2--) { + d = a * b + c + temp2; + f = a * c + b + temp2; + e = a + b * c + temp2; + // 153230.406250, numbers involved in floating-point operations, without special functions. + if (d != 153230.406250 + temp2) { + dprintf("Error:d = %f----temp = 0x%x----\n", d, temp2); + LOS_AtomicInc(&g_testCount); + continue; + // 124432.390625, numbers involved in floating-point operations, without special functions. + } else if (f != 124432.390625 + temp2) { + dprintf("Error:f = %f----temp = 0x%x----\n", f, temp2); + LOS_AtomicInc(&g_testCount); + continue; + // 1233323.875000, numbers involved in floating-point operations, without special functions. + } else if (e != (1233323.875000 + temp2)) { + dprintf("Error:e = %f----temp = 0x%x----\n", e, temp2); + LOS_AtomicInc(&g_testCount); + continue; + } + // 153230.406250, numbers involved in floating-point operations, without special functions. + ICUNIT_GOTO_EQUAL(d, 153230.406250 + temp2, temp2, EXIT); + // 124432.390625, numbers involved in floating-point operations, without special functions. + ICUNIT_GOTO_EQUAL(f, 124432.390625 + temp2, temp2, EXIT); + // 1233323.875000, numbers involved in floating-point operations, without special functions. + ICUNIT_GOTO_EQUAL(e, 1233323.875000 + temp2, temp2, EXIT); + } + } + +EXIT: + LOS_TaskDelete(g_sz[arg]); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret; + UINT32 i; + UINT32 coreIdx = 0; + + g_testCount = 0; + + while (coreIdx < LOSCFG_KERNEL_CORE_NUM) { + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_smp_float_switch_001", TaskF01, TASK_PRIO_TEST_TASK + 1, + CPUID_TO_AFFI_MASK(coreIdx)); + testTask.auwArgs[0] = coreIdx; + ret = LOS_TaskCreate(&g_sz[coreIdx], &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + coreIdx++; + } + + LOS_TaskDelay(100); // 100, set delay time. + + ICUNIT_GOTO_EQUAL(g_testCount, LOSCFG_KERNEL_CORE_NUM, g_testCount, EXIT); + +EXIT: + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + LOS_TaskDelete(g_sz[i]); + } + return LOS_OK; +} +#endif + +void ItSmpLosFloatSwitch001(void) +{ +#ifndef LOSCFG_ARCH_FPU_DISABLE + TEST_ADD_CASE("IT_SMP_LOS_FLOAT_SWITCH_001", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL0, TEST_FUNCTION); +#endif +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/float/It_smp_los_float_switch_002.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/float/It_smp_los_float_switch_002.c new file mode 100644 index 00000000..b7eec4c5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/float/It_smp_los_float_switch_002.c @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_float.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#ifndef LOSCFG_ARCH_FPU_DISABLE + +static UINT32 g_sz[LOSCFG_KERNEL_CORE_NUM] = {0}; +static UINT32 g_cpuidTask1, g_cpuidTask2; +static void TaskF01(UINT32 arg) +{ + UINT32 temp1 = 0xff; + UINT32 temp2; + FLOAT a = 123.321; + FLOAT b = 1234.4321; + FLOAT c = 999.002345; + FLOAT d, f, e; + LOS_AtomicInc(&g_testCount); + + while (temp1--) { + temp2 = 0xff; + while (temp2--) { + d = a * b + c + temp2; + f = a * c + b + temp2; + e = a + b * c + temp2; + + // 153230.406250, numbers involved in floating-point operations, without special functions. + if (d != 153230.406250 + temp2) { + dprintf("Error:d = %f----temp = 0x%x----\n", d, temp2); + LOS_AtomicInc(&g_testCount); + continue; + // 124432.390625, numbers involved in floating-point operations, without special functions. + } else if (f != 124432.390625 + temp2) { + dprintf("Error:f = %f----temp = 0x%x----\n", f, temp2); + LOS_AtomicInc(&g_testCount); + continue; + // 1233323.875000, numbers involved in floating-point operations, without special functions. + } else if (e != (1233323.875000 + temp2)) { + dprintf("Error:e = %f----temp = 0x%x----\n", e, temp2); + LOS_AtomicInc(&g_testCount); + continue; + } + // 153230.406250, numbers involved in floating-point operations, without special functions. + ICUNIT_GOTO_EQUAL(d, 153230.406250 + temp2, temp2, EXIT); + // 124432.390625, numbers involved in floating-point operations, without special functions. + ICUNIT_GOTO_EQUAL(f, 124432.390625 + temp2, temp2, EXIT); + // 1233323.875000, numbers involved in floating-point operations, without special functions. + ICUNIT_GOTO_EQUAL(e, 1233323.875000 + temp2, temp2, EXIT); + // 2, obtains the CPU ID. + LOS_TaskCpuAffiSet(g_testTaskID01, temp2 % 2 ? g_cpuidTask1 : g_cpuidTask2); + } + } + +EXIT: + LOS_TaskDelete(g_testTaskID01); + return; +} + +static void TaskF02(UINT32 arg) +{ + UINT32 temp1 = 0xff; + UINT32 temp2; + FLOAT a = 123.321; + FLOAT b = 1234.4321; + FLOAT c = 999.002345; + FLOAT d, f, e; + LOS_AtomicInc(&g_testCount); + + while (temp1--) { + temp2 = 0xffff; + while (temp2--) { + d = a * b + c + temp2; + f = a * c + b + temp2; + e = a + b * c + temp2; + + // 153230.406250, numbers involved in floating-point operations, without special functions. + if (d != 153230.406250 + temp2) { + dprintf("Error:d = %f----temp = 0x%x----\n", d, temp2); + LOS_AtomicInc(&g_testCount); + continue; + } else if (f != 124432.390625 + temp2) { // 124432.390625, numbers involved in floating-point operations, without special functions. + dprintf("Error:f = %f----temp = 0x%x----\n", f, temp2); + LOS_AtomicInc(&g_testCount); + continue; + } else if (e != (1233323.875000 + temp2)) { // 1233323.875000, numbers involved in floating-point operations, without special functions. + dprintf("Error:e = %f----temp = 0x%x----\n", e, temp2); + LOS_AtomicInc(&g_testCount); + continue; + } + // 153230.406250, numbers involved in floating-point operations, without special functions. + ICUNIT_GOTO_EQUAL(d, 153230.406250 + temp2, temp2, EXIT); + // 124432.390625, numbers involved in floating-point operations, without special functions. + ICUNIT_GOTO_EQUAL(f, 124432.390625 + temp2, temp2, EXIT); + // 1233323.875000, numbers involved in floating-point operations, without special functions. + ICUNIT_GOTO_EQUAL(e, 1233323.875000 + temp2, temp2, EXIT); + // 2, obtains the CPU ID. + LOS_TaskCpuAffiSet(g_testTaskID02, temp2 % 2 ? g_cpuidTask2 : g_cpuidTask1); + } + } + +EXIT: + LOS_TaskDelete(g_testTaskID02); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, currCpuid; + + g_testCount = 0; + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + g_cpuidTask1 = ArchCurrCpuid(); + g_cpuidTask2 = currCpuid; + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_smp_float_switch_002_task1", TaskF01, TASK_PRIO_TEST_TASK + 1, + CPUID_TO_AFFI_MASK(g_cpuidTask1)); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_028_task2", TaskF02, TASK_PRIO_TEST_TASK + 2, + CPUID_TO_AFFI_MASK(g_cpuidTask2)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(100); // 100, set delay time. + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + +EXIT: + + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + return LOS_OK; +} +#endif + +void ItSmpLosFloatSwitch002(void) +{ +#ifndef LOSCFG_ARCH_FPU_DISABLE + TEST_ADD_CASE("IT_SMP_LOS_FLOAT_SWITCH_002", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL0, TEST_FUNCTION); +#endif +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/float/It_smp_los_float_switch_003.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/float/It_smp_los_float_switch_003.c new file mode 100644 index 00000000..f4b3a9be --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/float/It_smp_los_float_switch_003.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_float.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#ifndef LOSCFG_ARCH_FPU_DISABLE + +static UINT32 g_sz[3] = {0}; +static void TaskF01(UINT32 arg) +{ + UINT32 temp1 = 0xff; + UINT32 temp2; + FLOAT a = 123.321; + FLOAT b = 1234.4321; + FLOAT c = 999.002345; + FLOAT d, f, e; + LOS_AtomicInc(&g_testCount); + + while (temp1--) { + temp2 = 0xffff; + while (temp2--) { + d = a * b + c + temp2; + f = a * c + b + temp2; + e = a + b * c + temp2; + + // 153230.406250, numbers involved in floating-point operations, without special functions. + if (d != 153230.406250 + temp2) { + dprintf("Error:d = %f----temp = 0x%x----\n", d, temp2); + LOS_AtomicInc(&g_testCount); + continue; + // 124432.390625, numbers involved in floating-point operations, without special functions. + } else if (f != 124432.390625 + temp2) { + dprintf("Error:f = %f----temp = 0x%x----\n", f, temp2); + LOS_AtomicInc(&g_testCount); + continue; + // 1233323.875000, numbers involved in floating-point operations, without special functions. + } else if (e != (1233323.875000 + temp2)) { + dprintf("Error:e = %f----temp = 0x%x----\n", e, temp2); + LOS_AtomicInc(&g_testCount); + continue; + } + // 153230.406250, numbers involved in floating-point operations, without special functions. + ICUNIT_GOTO_EQUAL(d, 153230.406250 + temp2, temp2, EXIT); + // 124432.390625, numbers involved in floating-point operations, without special functions. + ICUNIT_GOTO_EQUAL(f, 124432.390625 + temp2, temp2, EXIT); + // 1233323.875000, numbers involved in floating-point operations, without special functions. + ICUNIT_GOTO_EQUAL(e, 1233323.875000 + temp2, temp2, EXIT); + } + } + +EXIT: + LOS_TaskDelete(g_sz[arg]); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret; + UINT32 i; + UINT32 coreIdx; + + g_testCount = 0; + + // 3, Number of cycles + for (i = 0; i < 3; i++) { + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_smp_float_switch_003", TaskF01, TASK_PRIO_TEST_TASK + 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + testTask.auwArgs[0] = i; + ret = LOS_TaskCreate(&g_sz[i], &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + LOS_TaskDelay(100); // 100, set delay time. + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, assert that g_testCount is equal to this. + +EXIT: + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + LOS_TaskDelete(g_sz[i]); + } + return LOS_OK; +} +#endif + +void ItSmpLosFloatSwitch003(void) +{ +#ifndef LOSCFG_ARCH_FPU_DISABLE + TEST_ADD_CASE("IT_SMP_LOS_FLOAT_SWITCH_003", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL0, TEST_FUNCTION); +#endif +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/float/It_smp_los_float_switch_004.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/float/It_smp_los_float_switch_004.c new file mode 100644 index 00000000..21e213e0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/float/It_smp_los_float_switch_004.c @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_float.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#ifndef LOSCFG_ARCH_FPU_DISABLE + +static UINT32 g_sz[3] = {0}; +static void TaskF01(void) +{ + UINT32 temp1 = 0xff; + UINT32 temp2; + FLOAT a = 123.321; + FLOAT b = 1234.4321; + FLOAT c = 999.002345; + FLOAT d, f, e; + LOS_AtomicInc(&g_testCount); + + while (temp1--) { + temp2 = 0xffff; + while (temp2--) { + d = a * b + c + temp2; + f = a * c + b + temp2; + e = a + b * c + temp2; + + // 153230.406250, numbers involved in floating-point operations, without special functions. + if (d != 153230.406250 + temp2) { + dprintf("Error:d = %f----temp = 0x%x----\n", d, temp2); + LOS_AtomicInc(&g_testCount); + continue; + // 124432.390625, numbers involved in floating-point operations, without special functions. + } else if (f != 124432.390625 + temp2) { + dprintf("Error:f = %f----temp = 0x%x----\n", f, temp2); + LOS_AtomicInc(&g_testCount); + continue; + // 1233323.875000, numbers involved in floating-point operations, without special functions. + } else if (e != (1233323.875000 + temp2)) { + dprintf("Error:e = %f----temp = 0x%x----\n", e, temp2); + LOS_AtomicInc(&g_testCount); + continue; + } + // 153230.406250, numbers involved in floating-point operations, without special functions. + ICUNIT_GOTO_EQUAL(d, 153230.406250 + temp2, temp2, EXIT); + // 124432.390625, numbers involved in floating-point operations, without special functions. + ICUNIT_GOTO_EQUAL(f, 124432.390625 + temp2, temp2, EXIT); + // 1233323.875000, numbers involved in floating-point operations, without special functions. + ICUNIT_GOTO_EQUAL(e, 1233323.875000 + temp2, temp2, EXIT); + } + } + +EXIT: + LOS_TaskDelete(g_testTaskID01); + return; +} +static void HwiF01() +{ + FLOAT a = 123.321; + FLOAT b = 1234.4321; + DOUBLE c = 999.002345; + FLOAT d, f, e; + + d = a * b + c; + // 2.34, 5.67, 1.25, numbers involved in floating-point operations, without special functions. + f = a * 2.34 + b * 5.67 + c * 1.25; + // 4.321, numbers involved in floating-point operations, without special functions. + e = (a + b + c) * 4.321; + + g_testCount1++; + TestDumpCpuid(); + return; +} +static void TaskF02() +{ + while (1) { + TestHwiTrigger(HWI_NUM_TEST); + LOS_TaskDelay(2); // 2, set delay time. + } + return; +} +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, currCpuid; + UINT32 i; + + g_testCount = 0; + g_testCount1 = 0; + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); // hwi to interrupt task f01 + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // curret cpu + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_smp_float_switch_004", TaskF01, TASK_PRIO_TEST_TASK + 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_smp_float_switch_004", TaskF02, TASK_PRIO_TEST_TASK + 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu to trigger the hwi + + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(100); // 100, set delay time. + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + ICUNIT_GOTO_NOT_EQUAL(g_testCount1, 0, g_testCount1, EXIT); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + ret = LOS_HwiDelete(HWI_NUM_TEST, NULL); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + return LOS_OK; +} +#endif + +void ItSmpLosFloatSwitch004(void) +{ +#ifndef LOSCFG_ARCH_FPU_DISABLE + TEST_ADD_CASE("IT_SMP_LOS_FLOAT_SWITCH_004", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL0, TEST_FUNCTION); +#endif +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/float/It_smp_los_float_switch_005.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/float/It_smp_los_float_switch_005.c new file mode 100644 index 00000000..07dd79a4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/float/It_smp_los_float_switch_005.c @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_float.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#ifndef LOSCFG_ARCH_FPU_DISABLE + +static UINT32 g_sz[3] = {0}; +static void TaskF01(void) +{ + UINT32 temp1 = 0xff; + UINT32 temp2; + FLOAT a = 123.321; + FLOAT b = 1234.4321; + FLOAT c = 999.002345; + FLOAT d, f, e; + LOS_AtomicInc(&g_testCount); + + while (temp1--) { + temp2 = 0xffff; + while (temp2--) { + d = a * b + c + temp2; + f = a * c + b + temp2; + e = a + b * c + temp2; + + // 153230.406250, numbers involved in floating-point operations, without special functions. + if (d != 153230.406250 + temp2) { + dprintf("Error:d = %f----temp = 0x%x----\n", d, temp2); + LOS_AtomicInc(&g_testCount); + continue; + // 124432.390625, numbers involved in floating-point operations, without special functions. + } else if (f != 124432.390625 + temp2) { + dprintf("Error:f = %f----temp = 0x%x----\n", f, temp2); + LOS_AtomicInc(&g_testCount); + continue; + // 1233323.875000, numbers involved in floating-point operations, without special functions. + } else if (e != (1233323.875000 + temp2)) { + dprintf("Error:e = %f----temp = 0x%x----\n", e, temp2); + LOS_AtomicInc(&g_testCount); + continue; + } + // 153230.406250, numbers involved in floating-point operations, without special functions. + ICUNIT_GOTO_EQUAL(d, 153230.406250 + temp2, temp2, EXIT); + // 124432.390625, numbers involved in floating-point operations, without special functions. + ICUNIT_GOTO_EQUAL(f, 124432.390625 + temp2, temp2, EXIT); + // 1233323.875000, numbers involved in floating-point operations, without special functions. + ICUNIT_GOTO_EQUAL(e, 1233323.875000 + temp2, temp2, EXIT); + } + } + +EXIT: + LOS_TaskDelete(g_testTaskID01); + return; +} +static void HwiF01() +{ + FLOAT a = 123.321; + FLOAT b = 1234.4321; + DOUBLE c = 999.002345; + FLOAT d, f, e; + + d = a * b + c; + // 2.34, 5.67, 1.25, numbers involved in floating-point operations, without special functions. + f = a * 2.34 + b * 5.67 + c * 1.25; + // 4.321, numbers involved in floating-point operations, without special functions. + e = (a + b + c) * 4.321; + + g_testCount1++; + TestDumpCpuid(); + return; +} +static void TaskF02() +{ + while (1) { + TestHwiTrigger(HWI_NUM_TEST); + LOS_TaskDelay(2); // 2, set delay time. + } + return; +} +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, currCpuid; + UINT32 i; + + g_testCount = 0; + g_testCount1 = 0; + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); // hwi to interrupt task f01 + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(((ArchCurrCpuid() + 1) % LOSCFG_KERNEL_CORE_NUM))); // other cpu + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_smp_float_switch_004", TaskF01, TASK_PRIO_TEST_TASK + 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_smp_float_switch_004", TaskF02, TASK_PRIO_TEST_TASK + 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu to trigger the hwi + + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(100); // 100, set delay time. + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + ICUNIT_GOTO_NOT_EQUAL(g_testCount1, 0, g_testCount1, EXIT); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + ret = LOS_HwiDelete(HWI_NUM_TEST, NULL); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + return LOS_OK; +} +#endif + +void ItSmpLosFloatSwitch005(void) +{ +#ifndef LOSCFG_ARCH_FPU_DISABLE + TEST_ADD_CASE("IT_SMP_LOS_FLOAT_SWITCH_005", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL0, TEST_FUNCTION); +#endif +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/float/It_smp_los_float_switch_006.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/float/It_smp_los_float_switch_006.c new file mode 100644 index 00000000..94f0a31f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/float/It_smp_los_float_switch_006.c @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_float.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#ifndef LOSCFG_ARCH_FPU_DISABLE + +static void HwiF01(UINT32 arg) +{ + UINT32 temp2 = 0xf; + FLOAT a = 123.321; + FLOAT b = 1234.4321; + FLOAT c = 999.002345; + FLOAT d, f, e; + LOS_AtomicInc(&g_testCount); + + while (temp2--) { + d = a * b + c + temp2; + f = a * c + b + temp2; + e = a + b * c + temp2; + + // 153230.406250, numbers involved in floating-point operations, without special functions. + if (d != 153230.406250 + temp2) { + dprintf("Error:d = %f----temp = 0x%x----\n", d, temp2); + LOS_AtomicInc(&g_testCount); + continue; + // 124432.390625, numbers involved in floating-point operations, without special functions. + } else if (f != 124432.390625 + temp2) { + dprintf("Error:f = %f----temp = 0x%x----\n", f, temp2); + LOS_AtomicInc(&g_testCount); + continue; + // 1233323.875000, numbers involved in floating-point operations, without special functions. + } else if (e != (1233323.875000 + temp2)) { + dprintf("Error:e = %f----temp = 0x%x----\n", e, temp2); + LOS_AtomicInc(&g_testCount); + continue; + } + // 153230.406250, numbers involved in floating-point operations, without special functions. + ICUNIT_GOTO_EQUAL(d, 153230.406250 + temp2, temp2, EXIT); + // 124432.390625, numbers involved in floating-point operations, without special functions. + ICUNIT_GOTO_EQUAL(f, 124432.390625 + temp2, temp2, EXIT); + // 1233323.875000, numbers involved in floating-point operations, without special functions. + ICUNIT_GOTO_EQUAL(e, 1233323.875000 + temp2, temp2, EXIT); + } +EXIT: + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, currCpuid; + UINT32 i; + + g_testCount = 0; + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // curret cpu + + ret = LOS_HwiCreate(HWI_NUM_TEST1, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST1, CPUID_TO_AFFI_MASK(((ArchCurrCpuid() + 1) % LOSCFG_KERNEL_CORE_NUM))); // other cpu + + // 100, Number of cycles + for (i = 0; i < 100; i++) { + TestHwiTrigger(HWI_NUM_TEST1); + TestHwiTrigger(HWI_NUM_TEST); + LOS_TaskDelay(10); // 10, set delay time. + } + + ICUNIT_GOTO_EQUAL(g_testCount, 200, g_testCount, EXIT); // 200, assert that g_testCount is equal to this. + +EXIT: + + ret = LOS_HwiDelete(HWI_NUM_TEST, NULL); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ret = LOS_HwiDelete(HWI_NUM_TEST1, NULL); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + return LOS_OK; +} +#endif + +void ItSmpLosFloatSwitch006(void) +{ +#ifndef LOSCFG_ARCH_FPU_DISABLE + TEST_ADD_CASE("IT_SMP_LOS_FLOAT_SWITCH_006", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL0, TEST_FUNCTION); +#endif +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/float/It_smp_los_float_switch_007.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/float/It_smp_los_float_switch_007.c new file mode 100644 index 00000000..ce199698 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/float/It_smp_los_float_switch_007.c @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_float.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#ifndef LOSCFG_ARCH_FPU_DISABLE +#ifdef LOSCFG_KERNEL_SMP +static UINT32 g_targetCpuid; + +static void HwiF01(UINT32 arg) +{ + UINT32 temp2 = 0xf; + FLOAT a = 123.321; + FLOAT b = 1234.4321; + FLOAT c = 999.002345; + FLOAT d, f, e; + LOS_AtomicInc(&g_testCount); + + while (temp2--) { + d = a * b + c + temp2; + f = a * c + b + temp2; + e = a + b * c + temp2; + + // 153230.406250, numbers involved in floating-point operations, without special functions. + if (d != 153230.406250 + temp2) { + dprintf("Error:d = %f----temp = 0x%x----\n", d, temp2); + LOS_AtomicInc(&g_testCount); + continue; + // 124432.390625, numbers involved in floating-point operations, without special functions. + } else if (f != 124432.390625 + temp2) { + dprintf("Error:f = %f----temp = 0x%x----\n", f, temp2); + LOS_AtomicInc(&g_testCount); + continue; + // 1233323.875000, numbers involved in floating-point operations, without special functions. + } else if (e != (1233323.875000 + temp2)) { + dprintf("Error:e = %f----temp = 0x%x----\n", e, temp2); + LOS_AtomicInc(&g_testCount); + continue; + } + // 153230.406250, numbers involved in floating-point operations, without special functions. + ICUNIT_GOTO_EQUAL(d, 153230.406250 + temp2, temp2, EXIT); + // 124432.390625, numbers involved in floating-point operations, without special functions. + ICUNIT_GOTO_EQUAL(f, 124432.390625 + temp2, temp2, EXIT); + // 1233323.875000, numbers involved in floating-point operations, without special functions. + ICUNIT_GOTO_EQUAL(e, 1233323.875000 + temp2, temp2, EXIT); + } +EXIT: + return; +} + +static void TaskF01(void) +{ + HalIrqUnmask(HWI_NUM_INT11); + + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, testid; + UINT32 i; + + g_testCount = 0; + + g_targetCpuid = 0; + + ret = LOS_HwiCreate(HWI_NUM_INT11, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqUnmask(HWI_NUM_INT11); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_hwi_001_task", TaskF01, TASK_PRIO_TEST_TASK - 1, CPUID_TO_AFFI_MASK(i)); + ret = LOS_TaskCreate(&testid, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + g_targetCpuid = (1 << LOSCFG_KERNEL_CORE_NUM) - 1; // all cpu + + dprintf("g_targetCpuid = %d\n", g_targetCpuid); + + LOS_TaskDelay(1); // 1, set delay time. + + // 100, Number of cycles + for (i = 0; i < 100; i++) { + HalIrqSendIpi(g_targetCpuid, HWI_NUM_INT11); + LOS_TaskDelay(10); // 10, set delay time. + } + + // 100, assert that g_testCount is equal to this. + ICUNIT_ASSERT_EQUAL(g_testCount, 100 * LOSCFG_KERNEL_CORE_NUM, g_testCount); + + TEST_HwiDelete(HWI_NUM_INT11); + return LOS_OK; +} +#endif + +void ItSmpLosFloatSwitch007(void) +{ +#ifndef LOSCFG_ARCH_FPU_DISABLE + TEST_ADD_CASE("IT_SMP_LOS_FLOAT_SWITCH_007", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +#endif +} +#endif +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_001.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_001.c new file mode 100644 index 00000000..4f751b60 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_001.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + g_testCount++; + + return; +} +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk001A"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; + g_testCount = 0; + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestExtraTaskDelay(2); // 2, set delay time.(2); + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + return LOS_OK; +} + +void ItLosTask001(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask001", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_002.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_002.c new file mode 100644 index 00000000..3027d913 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_002.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = NULL; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk002A"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_ENTRY_NULL, ret); + + task1.pcName = ""; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task1.pcName = NULL; + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_NAME_EMPTY, ret); + + return LOS_OK; +} + +void ItLosTask002(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask002", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_004.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_004.c new file mode 100644 index 00000000..5eae0c89 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_004.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = LOS_TASK_MIN_STACK_SIZE - sizeof(UINTPTR) * 2; // 2, Used to calculate stack space + task1.pcName = "Tsk004A"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_TSK_STKSZ_TOO_SMALL, ret, EXIT); + + return LOS_OK; +EXIT: + LOS_TaskDelete(g_testTaskID01); + return LOS_OK; +} + +void ItLosTask004(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask004", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_007.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_007.c new file mode 100644 index 00000000..b4274ab4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_007.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + return; +} +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = OS_SYS_MEM_SIZE + 1; + task1.pcName = "Tsk007A"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_STKSZ_TOO_LARGE, ret); + + return LOS_OK; +} + +void ItLosTask007(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask007", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_008.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_008.c new file mode 100644 index 00000000..7302772f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_008.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + g_testCount++; + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk007A_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +void ItLosTask008(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask008", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_009.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_009.c new file mode 100644 index 00000000..e1044f24 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_009.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + return; +} +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = NULL; + task1.usTaskPrio = 0; + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + return LOS_OK; +} + +void ItLosTask009(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask009", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_010.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_010.c new file mode 100644 index 00000000..a3672b62 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_010.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + g_testCount++; + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = 0xFFFFFFFE; + task1.pcName = "Tsk010A"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_STKSZ_TOO_LARGE, ret); + + task1.uwStackSize = 0xFFFFFFF0; + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_STKSZ_TOO_LARGE, ret); + + task1.uwStackSize = 0xFFFFFFFF; + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_STKSZ_TOO_LARGE, ret); + + return LOS_OK; +} + +void ItLosTask010(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask010", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_011.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_011.c new file mode 100644 index 00000000..3d985709 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_011.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + g_testCount++; + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk011A!@#$%^&*_+~<>"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +#ifdef LOSCFG_KERNEL_SMP + /* Wait TaskF01 to start */ + while (g_testCount == 0) { + } +#endif + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + return LOS_OK; + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +void ItLosTask011(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask011", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_012.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_012.c new file mode 100644 index 00000000..d41c6605 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_012.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + g_testCount++; + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk012A"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestExtraTaskDelay(2); // 2, set delay time.(2); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_NOT_CREATED, ret); + + return LOS_OK; +} + +void ItLosTask012(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask012", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_013.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_013.c new file mode 100644 index 00000000..3ef8cd6c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_013.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + g_testCount++; + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk013A"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = 0; + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestExtraTaskDelay(2); // 2, set delay time.(2); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +void ItLosTask013(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask013", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_014.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_014.c new file mode 100644 index 00000000..ff8cee9f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_014.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + g_testCount++; + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk014A"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestExtraTaskDelay(2); // 2, set delay time. + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_NOT_CREATED, ret); + + return LOS_OK; +} + +void ItLosTask014(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask014", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_015.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_015.c new file mode 100644 index 00000000..c0b6c7e4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_015.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + g_testCount++; + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk015A"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestExtraTaskDelay(2); // 2, set delay time.(2); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_NOT_CREATED, ret); + + return LOS_OK; +} + +void ItLosTask015(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask015", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_016.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_016.c new file mode 100644 index 00000000..94549436 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_016.c @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF04(UINTPTR arg1, UINTPTR arg2, UINTPTR arg3, UINTPTR arg4) +{ + ICUNIT_ASSERT_EQUAL_VOID(arg1, 1, arg1); + ICUNIT_ASSERT_EQUAL_VOID(arg2, 0xffffffff, arg2); + ICUNIT_ASSERT_EQUAL_VOID(arg3, -1, arg3); + ICUNIT_ASSERT_EQUAL_VOID(arg4, 0xffffffff, arg4); + g_testCount++; + + return; +} + +static void TaskF03(UINTPTR arg1, UINTPTR arg2, UINTPTR arg3) +{ + ICUNIT_ASSERT_EQUAL_VOID(arg1, 0, arg1); + ICUNIT_ASSERT_EQUAL_VOID(arg2, 0xffff, arg2); + ICUNIT_ASSERT_EQUAL_VOID(arg3, -1, arg3); + + g_testCount++; + + return; +} + +static void TaskF02(UINTPTR arg1, UINTPTR arg2) +{ + ICUNIT_ASSERT_EQUAL_VOID(arg1, 0, arg1); + ICUNIT_ASSERT_EQUAL_VOID(arg2, 0xffff, arg2); + + g_testCount++; + + return; +} +static void TaskF01(UINTPTR arg1) +{ + ICUNIT_ASSERT_EQUAL_VOID(arg1, 0xffff, arg1); + + g_testCount++; + + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk016A"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; + // 0xffff, initializes the args. this parameter has no special meaning. + task1.auwArgs[0] = 0xffff; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + g_testCount = 0; + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.auwArgs[0] = 0; + // 0xffff, initializes the args. this parameter has no special meaning. + task1.auwArgs[1] = 0xffff; + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF03; + task1.auwArgs[0] = 0; + // 0xffff, initializes the args. this parameter has no special meaning. + task1.auwArgs[1] = 0xffff; + // 2, auwArgs array subscript. + task1.auwArgs[2] = -1; + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF04; + task1.auwArgs[0] = 1; + // 0xffffffff, initializes the args. this parameter has no special meaning. + task1.auwArgs[1] = 0xffffffff; + // 2, auwArgs array subscript. + task1.auwArgs[2] = -1; + // 3, auwArgs array subscript. + task1.auwArgs[3] = 0xffffffff; + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 4, g_testCount); // 4, assert that g_testCount is equal to this. + + return LOS_OK; +} + +void ItLosTask016(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask016", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_017.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_017.c new file mode 100644 index 00000000..8adb7c1d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_017.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + g_testCount++; + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk017A"; + task1.usTaskPrio = 1; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); +} + +void ItLosTask017(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask017", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_018.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_018.c new file mode 100644 index 00000000..7f22abba --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_018.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + g_testCount++; + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk018A"; + task1.usTaskPrio = OS_TASK_PRIORITY_LOWEST; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +void ItLosTask018(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask018", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_019.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_019.c new file mode 100644 index 00000000..dc15e92e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_019.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + g_testCount++; + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk019A"; + task1.usTaskPrio = OS_TASK_PRIORITY_LOWEST + 1; + + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_PRIOR_ERROR, ret); + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +void ItLosTask019(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask019", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_020.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_020.c new file mode 100644 index 00000000..394245d2 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_020.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + + ret = LOS_TaskCreate(&g_testTaskID01, NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_PTR_NULL, ret); + + return LOS_OK; +} + +void ItLosTask020(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask020", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_021.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_021.c new file mode 100644 index 00000000..6951e15a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_021.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk021A"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + ret = LOS_TaskCreate(NULL, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_ID_INVALID, ret); + + return LOS_OK; +} + +void ItLosTask021(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask021", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_022.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_022.c new file mode 100644 index 00000000..c8a27207 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_022.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(void) +{ + UINT32 ret; + ret = LOS_TaskDelete(-1); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_ID_INVALID, ret); + + return LOS_OK; +} + +void ItLosTask022(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask022", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_023.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_023.c new file mode 100644 index 00000000..d847798e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_023.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(void) +{ + UINT32 ret; + + ret = LOS_TaskDelete(OsGetIdleTaskId()); + ICUNIT_ASSERT_NOT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +void ItLosTask023(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask023", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_024.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_024.c new file mode 100644 index 00000000..58de01ec --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_024.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(void) +{ + UINT32 ret; + + ret = LOS_TaskDelete(LOSCFG_BASE_CORE_TSK_LIMIT + 1); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_ID_INVALID, ret); + + return LOS_OK; +} + +void ItLosTask024(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask024", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_025.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_025.c new file mode 100644 index 00000000..37a3619f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_025.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + g_testCount++; + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk025A"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + g_testCount++; + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_NOT_CREATED, ret); + + ret = LOS_TaskDelete(LOSCFG_BASE_CORE_TSK_LIMIT); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_ID_INVALID, ret); + + return LOS_OK; +} + +void ItLosTask025(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask025", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_026.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_026.c new file mode 100644 index 00000000..3fca73f6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_026.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(void) +{ + UINT32 ret; + + ret = LOS_TaskDelay(0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return LOS_OK; +} + +void ItLosTask026(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask026", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_027.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_027.c new file mode 100644 index 00000000..28c55086 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_027.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(void) +{ + UINT32 ret; + ret = LOS_TaskDelay(1); // 1, set delay time. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +void ItLosTask027(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask027", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_028.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_028.c new file mode 100644 index 00000000..a9d694ef --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_028.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(void) +{ + UINT32 ret; + + // 200, set delay time. + ret = LOS_TaskDelay(200); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +void ItLosTask028(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask028", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_029.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_029.c new file mode 100644 index 00000000..87a18286 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_029.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_TSK_NOT_SUSPENDED, ret, EXIT); + + g_testCount++; + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk029A"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +void ItLosTask029(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask029", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_031.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_031.c new file mode 100644 index 00000000..5065607e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_031.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_TSK_NOT_SUSPENDED, ret, EXIT); + + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk031A"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_TSK_ALREADY_SUSPENDED, ret, EXIT); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +void ItLosTask031(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask031", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_032.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_032.c new file mode 100644 index 00000000..e62dd195 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_032.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(void) +{ + UINT32 ret; + + ret = LOS_TaskSuspend(OsGetIdleTaskId()); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK, ret); + + ret = LOS_TaskResume(OsGetIdleTaskId()); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_NOT_SUSPENDED, ret); + + return LOS_OK; +} + +void ItLosTask032(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask032", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_033.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_033.c new file mode 100644 index 00000000..b4ba7424 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_033.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + char *taskName = NULL; + g_testCount++; + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + + g_testCount++; + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + return; +} + +static UINT32 Testcase(void) +{ + char *taskName = NULL; + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + task1.pcName = "Tsk033A"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + g_testCount++; + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, assert that g_testCount is equal to this. + + return LOS_OK; +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +void ItLosTask033(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask033", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_034.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_034.c new file mode 100644 index 00000000..7ee7868f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_034.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(void) +{ + UINT32 ret; + + ret = LOS_TaskSuspend(0xFFFFFFFF); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_ID_INVALID, ret); + + ret = LOS_TaskResume(0xFFFFFFFF); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_ID_INVALID, ret); + + return LOS_OK; +} + +void ItLosTask034(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask034", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_035.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_035.c new file mode 100644 index 00000000..18b941a9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_035.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(void) +{ + UINT32 ret; + + ret = LOS_TaskSuspend(0xFFFFFFFE); + ICUNIT_TRACK_EQUAL(ret, LOS_ERRNO_TSK_ID_INVALID, ret); + + ret = LOS_TaskResume(0xFFFFFFFE); + ICUNIT_TRACK_EQUAL(ret, LOS_ERRNO_TSK_ID_INVALID, ret); + + return LOS_OK; +} + +void ItLosTask035(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask035", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_036.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_036.c new file mode 100644 index 00000000..e7c54821 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_036.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(void) +{ + LOS_TaskLock(); + + LOS_TaskUnlock(); + + return LOS_OK; +} + +void ItLosTask036(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask036", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_037.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_037.c new file mode 100644 index 00000000..2547e490 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_037.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(void) +{ + UINT32 ret; + + LOS_TaskLock(); + + ret = LOS_TaskDelay(2); // 2, set delay time. + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_DELAY_IN_LOCK, ret); + + LOS_TaskUnlock(); + + ret = LOS_TaskDelay(2); // 2, set delay time. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +void ItLosTask037(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask037", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_038.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_038.c new file mode 100644 index 00000000..6df1d299 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_038.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + g_testCount++; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); +} + +static void TaskF02(void) +{ + UINT32 ret; + g_testCount++; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID02); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); +} +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk038A"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; + g_testCount = 0; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + LOS_TaskLock(); + LOS_TaskLock(); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.pcName = "Tsk038B"; + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskUnlock(); + ICUNIT_ASSERT_EQUAL(g_testCount, 0, g_testCount); + + LOS_TaskUnlock(); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + return LOS_OK; +} + +void ItLosTask038(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask038", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_039.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_039.c new file mode 100644 index 00000000..38fbdef6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_039.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + g_testCount++; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + UINT8 index; + CHAR acName[TASK_NAME_NUM] = "Tsk"; + TSK_INIT_PARAM_S task1 = { 0 }; + UINT32 testTaskID[LOSCFG_BASE_CORE_TSK_LIMIT]; + UINT32 taskCnt; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST_TASK + 1; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + taskCnt = OsShellCmdTaskCntGet(); + LOS_TaskLock(); + + for (index = 0; index < LOSCFG_BASE_CORE_TSK_LIMIT - taskCnt; index++) { + task1.usTaskPrio = index % OS_TASK_PRIORITY_LOWEST; + task1.pcName = acName; + task1.uwResved = LOS_TASK_STATUS_DETACHED; + ret = LOS_TaskCreate(&testTaskID[index], &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + + task1.usTaskPrio = index % OS_TASK_PRIORITY_LOWEST; + task1.pcName = "TskA"; + task1.uwResved = LOS_TASK_STATUS_DETACHED; + ret = LOS_TaskCreate(&testTaskID[index], &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_TSK_TCB_UNAVAILABLE, ret, EXIT); +EXIT: + for (index = 0; index < LOSCFG_BASE_CORE_TSK_LIMIT - taskCnt; index++) { + ret = LOS_TaskDelete(testTaskID[index]); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + LOS_TaskUnlock(); + + return LOS_OK; +} + +void ItLosTask039(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask039", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_040.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_040.c new file mode 100644 index 00000000..5b9deb01 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_040.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + UINT32 index; + CHAR acName[TASK_NAME_NUM] = ""; + + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + LOS_TaskLock(); + // 32, number of cycles + for (index = 0; index < 32; index++) { + task1.usTaskPrio = index; + (void)snprintf_s(acName, TASK_NAME_NUM, TASK_NAME_NUM - 1, "Tsk040A%2d", index); + task1.pcName = acName; + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_TRACK_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_TRACK_EQUAL(ret, LOS_OK, ret); + } + + LOS_TaskUnlock(); + + return LOS_OK; +} + +void ItLosTask040(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask040", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_041.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_041.c new file mode 100644 index 00000000..a5268b06 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_041.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; + + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk041A"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_ALREADY_SUSPENDED, ret); + + LOS_TaskLock(); + + ret = LOS_TaskSuspend(g_testTskHandle); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_SUSPEND_LOCKED, ret); + + LOS_TaskUnlock(); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. +EXIT: + LOS_TaskDelete(g_testTaskID01); + return LOS_OK; +} + +void ItLosTask041(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask041", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_042.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_042.c new file mode 100644 index 00000000..9ff64254 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_042.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + g_testCount++; + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + // 4, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 4; + task1.pcName = "Tsk042A"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskLock(); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + g_testCount++; + + LOS_TaskUnlock(); + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + return LOS_OK; +EXIT: + LOS_TaskUnlock(); + LOS_TaskDelete(g_testTaskID01); + return LOS_OK; +} + +void ItLosTask042(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask042", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_043.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_043.c new file mode 100644 index 00000000..3b9a6f16 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_043.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + g_testCount++; + + LOS_TaskDelay(3); // 3, set delay time. + + g_testCount++; + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk043A"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + ret = LOS_TaskResume(g_testTskHandle); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_NOT_SUSPENDED, ret); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + LOS_TaskDelay(30); // 30, set delay time. + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + return LOS_OK; +} + +void ItLosTask043(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask043", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_047.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_047.c new file mode 100644 index 00000000..bb983c34 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_047.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static EVENT_CB_S g_eventCb01; +static void TaskF01(void) +{ + UINT32 ret; + g_testCount++; + ret = LOS_CurTaskPriSet(OS_TASK_PRIORITY_HIGHEST); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(OsCurrTaskGet()->priority, OS_TASK_PRIORITY_HIGHEST, OsCurrTaskGet()->priority); + // 4, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + ret = LOS_CurTaskPriSet(TASK_PRIO_TEST_TASK - 4); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + // 4, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + ICUNIT_ASSERT_EQUAL_VOID(OsCurrTaskGet()->priority, TASK_PRIO_TEST_TASK - 4, OsCurrTaskGet()->priority); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + ret = LOS_CurTaskPriSet(OS_TASK_PRIORITY_LOWEST); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk047A"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + g_testCount = 0; + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +void ItLosTask047(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask047", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_048.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_048.c new file mode 100644 index 00000000..6d2443de --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_048.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID01); +} + +static void TaskF02(void) +{ + UINT32 ret; + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID02); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + UINT32 taskCnt; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk048A"; + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + taskCnt = LOSCFG_BASE_CORE_TSK_CONFIG - OsShellCmdTaskCntGet(); + // 4, Possible range of parameters + if (taskCnt >= 4) + // 2, Set the priority according to the task purpose + task1.usTaskPrio = 2; + // 2, 3, Possible range of parameters + else if ((taskCnt == 3) || (taskCnt == 2)) + // 1, Set the priority according to the task purpose + task1.usTaskPrio = 1; + else + task1.usTaskPrio = 0; + + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + TestBusyTaskDelay(2); // 2, set delay time + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.pcName = "Tsk048B"; + task1.usTaskPrio = OS_TASK_PRIORITY_LOWEST - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskDelay(4); // 4, set delay time. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT1); // 2, assert that g_testCount is equal to this. + +EXIT1: + LOS_TaskDelete(g_testTaskID02); +EXIT: + LOS_TaskDelete(g_testTaskID01); + return LOS_OK; +} + +void ItLosTask048(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask048", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_050.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_050.c new file mode 100644 index 00000000..b02ac19e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_050.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02(void) +{ + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + g_testCount++; + + LOS_TaskDelete(g_testTaskID02); +} + +static void TaskF01(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk050B"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + g_testCount++; + + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + g_testCount++; + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); +} + + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk050A"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + g_testCount = 0; + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +void ItLosTask050(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask050", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_051.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_051.c new file mode 100644 index 00000000..567e698b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_051.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02(void) +{ + UINT32 ret; + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID02); +} + +static void TaskF01(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + task1.pcName = "Tsk051B"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + g_testCount++; + + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskDelay(2); // 2, set delay time. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk051A"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskDelay(3); // 3, set delay time. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + return LOS_OK; +} + +void ItLosTask051(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask051", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_052.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_052.c new file mode 100644 index 00000000..fe98cbf9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_052.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02(void) +{ + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + g_testCount++; + + LOS_TaskDelete(g_testTaskID02); +} + +static void TaskF01(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk052B"; + // 3, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 3; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + g_testCount++; + + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + g_testCount++; + + LOS_TaskDelete(g_testTaskID01); +} + + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk052A"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + return LOS_OK; +} + +void ItLosTask052(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask052", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_053.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_053.c new file mode 100644 index 00000000..a1c80e09 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_053.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void HwiF01(void) +{ + UINT32 ret; + + TEST_HwiClear(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + g_testCount++; + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); +} +static void TaskF01(void) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + TestHwiTrigger(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + g_testCount++; + + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk053A"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + g_testCount++; + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(20); // 20, set delay time. + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, assert that g_testCount is equal to this. +EXIT: + TEST_HwiDelete(HWI_NUM_TEST); + return LOS_OK; +} + +void ItLosTask053(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask053", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_054.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_054.c new file mode 100644 index 00000000..d746a77d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_054.c @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void HwiF01(void) +{ + UINT32 ret; + + TEST_HwiClear(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + g_testCount++; + + ret = LOS_TaskSuspend(g_testTaskID02); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); +} + +static void TaskF02(void) +{ + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 4, g_testCount); // 4, assert that g_testCount is equal to this. + g_testCount++; + + LOS_TaskDelete(g_testTaskID02); +} + +static void TaskF01(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk054B"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount++; + + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + TestHwiTrigger(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + g_testCount++; + + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk054A"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + g_testCount++; + + ret = LOS_TaskResume(g_testTaskID02); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); // 5, assert that g_testCount is equal to this. +EXIT: + TEST_HwiDelete(HWI_NUM_TEST); + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + return LOS_OK; +} + +void ItLosTask054(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask054", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_055.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_055.c new file mode 100644 index 00000000..66b9dd72 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_055.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02(void) +{ + g_testCount++; +} + +static void TaskF01(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk055B"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + g_testCount++; + + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_TaskSuspend(g_testTaskID02); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + g_testCount++; + + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + task1.pcName = "Tsk055A"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + LOS_TaskDelete(g_testTaskID02); + + return LOS_OK; +} + +void ItLosTask055(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask055", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_056.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_056.c new file mode 100644 index 00000000..ac7823f9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_056.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02(void) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + g_testCount++; + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_TaskDelete(g_testTaskID02); +} + +static void TaskF01(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk056B"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + g_testCount++; + + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + g_testCount++; + + ret = LOS_TaskDelay(2); // 2, set delay time. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + g_testCount++; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk056A"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +void ItLosTask056(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask056", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_057.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_057.c new file mode 100644 index 00000000..7f1451e3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_057.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02(void) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + g_testCount++; + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; + LOS_TaskDelete(g_testTaskID02); +} + +static void TaskF01(void) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + g_testCount++; + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 4, g_testCount); // 4, assert that g_testCount is equal to this. + g_testCount++; + + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk057A"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + g_testCount++; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.pcName = "Tsk057B"; + // 3, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 3; + + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 5, g_testCount); // 5, assert that g_testCount is equal to this. + + return LOS_OK; +} + +void ItLosTask057(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask057", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_058.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_058.c new file mode 100644 index 00000000..0137b11a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_058.c @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02(void) +{ + UINT32 ret; + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT1); // 2, assert that g_testCount is equal to this. + g_testCount++; + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT2); // 4, assert that g_testCount is equal to this. + g_testCount++; + + LOS_TaskDelete(g_testTaskID02); + + return; + +EXIT1: + LOS_TaskDelete(g_testTaskID01); +EXIT2: + LOS_TaskDelete(g_testTaskID02); + return; +} + +static void TaskF01(void) +{ + UINT32 ret; + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT2); + g_testCount++; + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT1); // 3, assert that g_testCount is equal to this. + g_testCount++; + + LOS_TaskDelete(g_testTaskID01); + + return; + +EXIT1: + LOS_TaskDelete(g_testTaskID02); +EXIT2: + LOS_TaskDelete(g_testTaskID01); + + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk058A"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + g_testCount++; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.pcName = "Tsk058B"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 5, g_testCount); // 5, assert that g_testCount is equal to this. + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + return LOS_OK; +} + +void ItLosTask058(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask058", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_060.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_060.c new file mode 100644 index 00000000..2e0a188f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_060.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02(void) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + g_testCount++; + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 4, g_testCount); // 4, assert that g_testCount is equal to this. + + g_testCount++; + LOS_TaskDelete(g_testTaskID02); +} + +static void TaskF01(void) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + g_testCount++; + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + g_testCount++; + + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk060A"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + g_testCount++; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.pcName = "Tsk060B"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 5, g_testCount); // 5, assert that g_testCount is equal to this. + + return LOS_OK; +} + +void ItLosTask060(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask060", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_061.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_061.c new file mode 100644 index 00000000..c0ed2a19 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_061.c @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void HwiF01(void) +{ + UINT32 ret; + + TEST_HwiClear(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + g_testCount++; + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); +} + +static void TaskF02(void) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + g_testCount++; + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + TestHwiTrigger(HWI_NUM_TEST); + + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); // 5, assert that g_testCount is equal to this. + + g_testCount++; +EXIT: + LOS_TaskDelete(g_testTaskID02); + + return; +} + +static void TaskF01(void) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, assert that g_testCount is equal to this. + g_testCount++; +EXIT: + LOS_TaskDelete(g_testTaskID01); + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk061A"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + g_testCount++; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.pcName = "Tsk061B"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 6, g_testCount, EXIT2); // 6, assert that g_testCount is equal to this. + + TEST_HwiDelete(HWI_NUM_TEST); + + return LOS_OK; +EXIT2: + TEST_HwiDelete(HWI_NUM_TEST); +EXIT1: + LOS_TaskDelete(g_testTaskID02); +EXIT: + LOS_TaskDelete(g_testTaskID01); + return LOS_OK; +} + +void ItLosTask061(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask061", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_063.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_063.c new file mode 100644 index 00000000..9da5327e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_063.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02(void) +{ + UINT32 index; + int value; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + g_testCount++; + HAL_READ_UINT32(&g_testCount, value); + + while (value != 4) { // 4, assert value . + HAL_READ_UINT32(&g_testCount, value); + } + + HAL_READ_UINT32(&g_testCount, value); + g_testCount = value; + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 4, g_testCount); // 4, assert that g_testCount is equal to this. + g_testCount++; + + LOS_TaskDelete(g_testTaskID02); +} + +static void TaskF01(void) +{ + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + g_testCount++; + + LOS_TaskDelay(5); // 5, set delay time. + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + g_testCount++; + + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk063A"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + g_testCount++; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.pcName = "Tsk063B"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 5, g_testCount); // 5, assert that g_testCount is equal to this. + + return LOS_OK; +} + +void ItLosTask063(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask063", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_064.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_064.c new file mode 100644 index 00000000..b82cceeb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_064.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void HwiF01(void) +{ + UINT32 ret; + + TEST_HwiClear(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + g_testCount++; + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); +} + +static void TaskF02(void) +{ + UINT32 ret; + UINT32 index; + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + g_testCount++; + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + TestHwiTrigger(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + g_testCount++; + + for (index = 0; index < TASK_LOOP_NUM; index++) { + } + + LOS_TaskDelete(g_testTaskID02); +} + +static void TaskF01(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk064B"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount++; + + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_TaskDelay(5); // 5, set delay time. + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 5, g_testCount); // 5, assert that g_testCount is equal to this. + g_testCount++; + + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk064A"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_HwiTriggerDelay; + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT2); // 4, assert that g_testCount is equal to this. + g_testCount++; + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 6, g_testCount, EXIT2); // 6, assert that g_testCount is equal to this. + + TEST_HwiDelete(HWI_NUM_TEST); + + return LOS_OK; +EXIT2: + TEST_HwiDelete(HWI_NUM_TEST); +EXIT1: + LOS_TaskDelete(g_testTaskID02); +EXIT: + LOS_TaskDelete(g_testTaskID01); + return LOS_OK; +} + +void ItLosTask064(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask064", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_065.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_065.c new file mode 100644 index 00000000..92623f6a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_065.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02(void) +{ + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + g_testCount++; + + LOS_TaskDelete(g_testTaskID02); +} + +static void TaskF01(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk065B"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + g_testCount++; + + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + g_testCount++; + + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk065A"; + // 3, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 3; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + return LOS_OK; +} + +void ItLosTask065(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask065", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_066.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_066.c new file mode 100644 index 00000000..b85ecf61 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_066.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF03(void) +{ + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + g_testCount++; + + LOS_TaskDelete(g_testTaskID03); +} + +static void TaskF02(void) +{ + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + g_testCount++; + + LOS_TaskDelete(g_testTaskID02); +} + +static void TaskF01(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk066B"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + g_testCount++; + + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF03; + task1.pcName = "Tsk066C"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID03, &task1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + g_testCount++; + + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk066A"; + // 3, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 3; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 4, g_testCount); // 4, assert that g_testCount is equal to this. + + return LOS_OK; +} + +void ItLosTask066(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask066", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_067.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_067.c new file mode 100644 index 00000000..d7b9cf90 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_067.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02(void) +{ + UINT32 ret; + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + g_testCount++; + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_ASSERT_NOT_EQUAL_VOID(ret, LOS_OK, ret); + LOS_TaskDelete(g_testTaskID02); + + return; +} + +static void TaskF01(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk067B"; + // 3, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 3; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + g_testCount++; + + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + g_testCount++; + + ret = LOS_TaskSuspend(g_testTaskID02); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_TSK_NOT_CREATED, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + g_testCount++; + + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk067A"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 4, g_testCount); // 4, assert that g_testCount is equal to this. + + LOS_TaskDelete(g_testTaskID01); + return LOS_OK; +} + +void ItLosTask067(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask067", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_068.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_068.c new file mode 100644 index 00000000..92f726aa --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_068.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02(void) +{ + UINT32 ret; + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + g_testCount++; + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_NOT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_TaskDelete(g_testTaskID02); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); +} + +static void TaskF01(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk068B"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + g_testCount++; + + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + g_testCount++; + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk068A"; + // 3, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 3; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_ASSERT_NOT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +void ItLosTask068(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask068", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_069.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_069.c new file mode 100644 index 00000000..d3668b0f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_069.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02(void) +{ + UINT32 ret; + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + g_testCount++; + + ret = LOS_TaskSuspend(g_testTaskID02); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); +} + +static void TaskF01(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk069B"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + g_testCount++; + + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + g_testCount++; + + ret = LOS_TaskResume(g_testTaskID02); + ICUNIT_ASSERT_NOT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); +} + + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk069A"; + // 3, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 3; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID02); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +void ItLosTask069(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask069", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_071.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_071.c new file mode 100644 index 00000000..963df73a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_071.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + g_testCount++; + LOS_TaskDelete(g_testTaskID01); + + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk071A"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + LOS_TaskLock(); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT3); + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT1); + + LOS_TaskUnlock(); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT2); + + return LOS_OK; + +EXIT1: + LOS_TaskUnlock(); +EXIT2: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +EXIT3: + LOS_TaskUnlock(); + + return LOS_OK; +} + +void ItLosTask071(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask071", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_072.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_072.c new file mode 100644 index 00000000..3a72268f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_072.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + g_testCount++; + LOS_TaskDelete(g_testTaskID01); + + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk072A"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + LOS_TaskLock(); + + LOS_TaskLock(); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + + LOS_TaskUnlock(); + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT2); + + LOS_TaskUnlock(); + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT3); + + return LOS_OK; + +EXIT1: + LOS_TaskUnlock(); + LOS_TaskUnlock(); + + return LOS_OK; +EXIT2: + LOS_TaskUnlock(); +EXIT3: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +void ItLosTask072(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask072", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_073.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_073.c new file mode 100644 index 00000000..dee78432 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_073.c @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02(void) +{ + UINT32 ret; + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT1); + g_testCount++; + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT2); // 3, assert that g_testCount is equal to this. + g_testCount++; + + LOS_TaskDelete(g_testTaskID02); + return; + +EXIT1: + LOS_TaskDelete(g_testTaskID01); +EXIT2: + LOS_TaskDelete(g_testTaskID02); + + return; +} + +static void TaskF01(void) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + g_testCount++; + + LOS_TaskDelete(g_testTaskID01); + + return; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk073A"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + LOS_TaskLock(); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT2); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.pcName = "Tsk073B"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT1); + + LOS_TaskUnlock(); + + ICUNIT_ASSERT_EQUAL(g_testCount, 4, g_testCount); // 4, assert that g_testCount is equal to this. + + return LOS_OK; + +EXIT1: + LOS_TaskDelete(g_testTaskID01); +EXIT2: + LOS_TaskUnlock(); + + return LOS_OK; +} + +void ItLosTask073(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask073", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_074.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_074.c new file mode 100644 index 00000000..44a86715 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_074.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.pcName = "Tsk074A"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskLock(); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + g_testCount++; + + LOS_TaskUnlock(); + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + return LOS_OK; + +EXIT: + LOS_TaskUnlock(); + + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +void ItLosTask074(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask074", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_075.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_075.c new file mode 100644 index 00000000..2ba3c829 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_075.c @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02(void) +{ + int value; + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT1); + g_testCount++; + + HAL_READ_UINT32(&g_testCount, value); + + while (value <= 2) { // 2, Waiting for the change of value. + HAL_READ_UINT32(&g_testCount, value); + } + + HAL_READ_UINT32(&g_testCount, value); + g_testCount = value; + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT2); // 3, assert that g_testCount is equal to this. + g_testCount++; + + LOS_TaskDelete(g_testTaskID02); + + return; + +EXIT1: + LOS_TaskDelete(g_testTaskID02); +EXIT2: + LOS_TaskDelete(g_testTaskID01); + return; +} + +static void TaskF01(void) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_TaskDelay(1); // 1, set delay time. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + g_testCount++; + + LOS_TaskDelete(g_testTaskID01); + + return; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + return; +} + + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk075A"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + LOS_TaskLock(); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT3); + + ret = LOS_TaskDelay(2); // 2, set delay time. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_TSK_DELAY_IN_LOCK, ret, EXIT2); + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT2); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.pcName = "Tsk075B"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT2); + + ret = LOS_TaskDelay(2); // 2, set delay time. + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_DELAY_IN_LOCK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT1); + + LOS_TaskUnlock(); + + ICUNIT_ASSERT_EQUAL(g_testCount, 4, g_testCount); // 4, assert that g_testCount is equal to this. + + return LOS_OK; + +EXIT1: + LOS_TaskDelete(g_testTaskID02); +EXIT2: + LOS_TaskDelete(g_testTaskID01); +EXIT3: + LOS_TaskLock(); + return LOS_OK; +} + +void ItLosTask075(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask075", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_076.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_076.c new file mode 100644 index 00000000..bc193435 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_076.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02(void) +{ + g_testCount++; + + LOS_TaskDelete(g_testTaskID02); + + return; +} + +static void TaskF01(void) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_TaskDelay(0); + ICUNIT_ASSERT_EQUAL_VOID(ret, 0, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID02); + LOS_TaskDelete(g_testTaskID01); + + return; +} + + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk076A"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + LOS_TaskLock(); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT3); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.pcName = "Tsk076B"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT2); + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT1); + + LOS_TaskUnlock(); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + return LOS_OK; + +EXIT1: + LOS_TaskDelete(g_testTaskID02); +EXIT2: + LOS_TaskDelete(g_testTaskID01); +EXIT3: + LOS_TaskUnlock(); + return LOS_OK; +} + +void ItLosTask076(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask076", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_077.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_077.c new file mode 100644 index 00000000..5189bb24 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_077.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF03(void) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + g_testCount++; + + ret = LOS_TaskSuspend(g_testTaskID03); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); +} + +static void TaskF02(void) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + g_testCount++; + + ret = LOS_TaskSuspend(g_testTaskID02); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); +} + +static void TaskF01(void) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk077A"; + // 3, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 3; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + LOS_TaskLock(); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.pcName = "Tsk077B"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF03; + task1.pcName = "Tsk077C"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + ret = LOS_TaskCreate(&g_testTaskID03, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 0, g_testCount); + + LOS_TaskUnlock(); + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + LOS_TaskDelete(g_testTaskID03); + + return LOS_OK; +} + +void ItLosTask077(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask077", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_078.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_078.c new file mode 100644 index 00000000..22a88563 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_078.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + g_testCount++; + + LOS_TaskLock(); + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_TSK_DELETE_LOCKED, ret, EXIT); + + LOS_TaskUnlock(); + + g_testCount++; + +EXIT: + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk078A"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + g_testCount++; + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + return LOS_OK; +} + +void ItLosTask078(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask078", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_079.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_079.c new file mode 100644 index 00000000..41d12880 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_079.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + g_testCount++; + + ret = LOS_SemPend(g_semID, 0x2); + ICUNIT_TRACK_EQUAL(ret, LOS_ERRNO_SEM_TIMEOUT, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + g_testCount++; + +EXIT: + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk079A"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + g_testCount++; + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(3); // 3, set delay time. + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +void ItLosTask079(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask079", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_080.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_080.c new file mode 100644 index 00000000..43e792c0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_080.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void HwiF01(void) +{ + UINT32 ret; + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + + TEST_HwiClear(HWI_NUM_TEST); + + ret = LOS_TaskYield(); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_TSK_YIELD_IN_INT, ret); + + g_testCount++; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + HWI_PRIOR_T hwiPrio = 3; + HWI_MODE_T mode = 0; + HWI_ARG_T arg = 0; + + g_testCount = 0; + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + g_testCount++; + + ret = LOS_HwiCreate(HWI_NUM_TEST, hwiPrio, mode, (HWI_PROC_FUNC)HwiF01, (HwiIrqParam *)arg); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + TestHwiTrigger(HWI_NUM_TEST); + +EXIT: + TEST_HwiDelete(HWI_NUM_TEST); + + return LOS_OK; +} + +void ItLosTask080(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask080", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_082.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_082.c new file mode 100644 index 00000000..8fc8eb7e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_082.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static EVENT_CB_S g_eventCb01; + +static void TaskF01(void) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_EventRead(&g_eventCb01, 0x11, LOS_WAITMODE_OR | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, 0x1, ret, EXIT); + g_testCount++; + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = {0}; + + LOS_EventInit(&g_eventCb01); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "Tsk082A"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_EventWrite(&g_eventCb01, 0x80000000); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + LOS_EventWrite(&g_eventCb01, 0x1); + +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + return LOS_OK; +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +void ItLosTask082(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask082", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_090.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_090.c new file mode 100644 index 00000000..3a8c9803 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_090.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + g_testCount++; + ret = LOS_TaskYield(); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + g_testCount++; +EXIT: + LOS_TaskDelete(g_testTaskID01); +} + +static void TaskF02(void) +{ + UINT32 ret; + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID02); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk090A"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + LOS_TaskLock(); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.pcName = "Tsk090B"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + LOS_TaskUnlock(); + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + return LOS_OK; +} + +void ItLosTask090(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask090", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_092.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_092.c new file mode 100644 index 00000000..c04bf8d8 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_092.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + g_testCount++; + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = LOS_TASK_MIN_STACK_SIZE + 1; + task1.pcName = "Tsk092A"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +void ItLosTask092(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask092", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_093.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_093.c new file mode 100644 index 00000000..7cd2591a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_093.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + CHAR buff1[8] = "UniDSP"; + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + g_testCount++; + + ret = LOS_QueueRead(g_testQueueID01, &buff1, sizeof(UINTPTR), 0xff); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISEMPTY, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + g_testCount++; + +EXIT: + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + + // 3, queue len. + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk093A"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + g_testCount++; + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(5); // 5, set delay time. + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +void ItLosTask093(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask093", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_094.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_094.c new file mode 100644 index 00000000..f3269e4f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_094.c @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF03(UINTPTR arg1, UINTPTR arg2, UINTPTR arg3, UINTPTR arg4) +{ + g_testCount++; + + ICUNIT_GOTO_EQUAL(arg1, 1, arg1, EXIT); + ICUNIT_GOTO_EQUAL(arg2, 0xffff, arg2, EXIT); + ICUNIT_GOTO_EQUAL(arg3, -1, arg3, EXIT); + ICUNIT_GOTO_EQUAL(arg4, 0xffffffff, arg4, EXIT); +EXIT: + return; +} + +static void TaskF02(UINTPTR arg1, UINTPTR arg2) +{ + ICUNIT_GOTO_EQUAL(arg1, 0, arg1, EXIT); + ICUNIT_GOTO_EQUAL(arg2, 0xffff, arg2, EXIT); + + g_testCount++; + +EXIT: + return; +} + +static void TaskF01(UINTPTR arg1) +{ + ICUNIT_GOTO_EQUAL(arg1, 0xffff, arg1, EXIT); + + g_testCount++; +EXIT: + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk094A"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = 0; + // 0xffff, initializes the args. this parameter has no special meaning. + task1.auwArgs[0] = 0xffff; + task1.processID = LOS_GetCurrProcessID(); +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + task1.processID = LOS_GetCurrProcessID(); + ret = LOS_TaskCreateOnly(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + ret = LOS_SetTaskScheduler(g_testTaskID01, LOS_SCHED_RR, task1.usTaskPrio); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.auwArgs[0] = 0; + // 0xffff, initializes the args. this parameter has no special meaning. + task1.auwArgs[1] = 0xffff; + task1.pcName = "Tsk094B"; + // 3, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 3; + task1.processID = LOS_GetCurrProcessID(); +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + task1.processID = LOS_GetCurrProcessID(); + ret = LOS_TaskCreateOnly(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + ret = LOS_SetTaskScheduler(g_testTaskID02, LOS_SCHED_RR, task1.usTaskPrio); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF03; + task1.auwArgs[0] = 1; + // 0xffff, initializes the args. this parameter has no special meaning. + task1.auwArgs[1] = 0xffff; + // 2, auwArgs array subscript. + task1.auwArgs[2] = -1; + // 3, auwArgs array subscript. + task1.auwArgs[3] = 0xffffffff; + task1.pcName = "Tsk094C"; + // 4, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 4; + task1.processID = LOS_GetCurrProcessID(); +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + task1.processID = LOS_GetCurrProcessID(); + ret = LOS_TaskCreateOnly(&g_testTaskID03, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + + ret = LOS_SetTaskScheduler(g_testTaskID03, LOS_SCHED_RR, task1.usTaskPrio); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, assert that g_testCount is equal to this. + + LOS_TaskDelay(10); // 10, set delay time. + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + LOS_TaskDelete(g_testTaskID03); + return LOS_OK; +} + +void ItLosTask094(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask094", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_095.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_095.c new file mode 100644 index 00000000..41ee35b1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_095.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + g_testCount++; + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk095A"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; + task1.processID = LOS_GetCurrProcessID(); +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + task1.processID = LOS_GetCurrProcessID(); + + g_testCount = 0; + ret = LOS_TaskCreateOnly(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + ret = LOS_SetTaskScheduler(g_testTaskID01, LOS_SCHED_RR, task1.usTaskPrio); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_TaskDelay(10); // 10, set delay time. + + ret = LOS_TaskCreateOnly(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +void ItLosTask095(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask095", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_096.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_096.c new file mode 100644 index 00000000..57b5c8a0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_096.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02(void) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + + g_testCount++; +} + +static void TaskF01(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk059B"; + // 3, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 3; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID02); + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk096A"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = 0; + task1.processID = LOS_GetCurrProcessID(); +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + task1.processID = LOS_GetCurrProcessID(); + g_testCount = 0; + ret = LOS_TaskCreateOnly(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + ret = LOS_SetTaskScheduler(g_testTaskID01, LOS_SCHED_RR, task1.usTaskPrio); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_TaskDelay(10); // 10, set delay time. + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskDelete(g_testTaskID02); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_TSK_NOT_CREATED, ret, EXIT); + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +void ItLosTask096(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask096", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_098.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_098.c new file mode 100644 index 00000000..e8ef4d8f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_098.c @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02(void) +{ + g_testCount++; + return; +} + +static void TaskF01(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk098B"; + // 3, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 3; + task1.uwResved = LOS_TASK_STATUS_DETACHED; + task1.processID = LOS_GetCurrProcessID(); +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + task1.processID = LOS_GetCurrProcessID(); + ret = LOS_TaskCreateOnly(&g_testTaskID02, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + ret = LOS_SetTaskScheduler(g_testTaskID02, LOS_SCHED_RR, task1.usTaskPrio); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT1); + g_testCount++; + return; +EXIT1: + LOS_TaskDelete(g_testTaskID02); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk098A"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; + task1.processID = LOS_GetCurrProcessID(); +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + task1.processID = LOS_GetCurrProcessID(); + g_testCount = 0; + + ret = LOS_TaskCreateOnly(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + ret = LOS_SetTaskScheduler(g_testTaskID01, LOS_SCHED_RR, task1.usTaskPrio); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_TaskDelay(10); // 10, set delay time. + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_NOT_CREATED, ret); + + ret = LOS_TaskDelete(g_testTaskID02); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_NOT_CREATED, ret); + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +void ItLosTask098(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask098", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_100.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_100.c new file mode 100644 index 00000000..da22e5b4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_100.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + g_testCount++; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + + ret = LOS_TaskPriGet(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, TASK_PRIO_TEST_TASK - 1, ret); + + g_testCount++; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk100A"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + g_testTaskID01 = 0xffff; + + ret = LOS_TaskPriGet(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, (UINT16)OS_INVALID, ret); + + ret = LOS_TaskPriGet(g_taskMaxNum + 1); + ICUNIT_GOTO_EQUAL(ret, (UINT16)OS_INVALID, ret, EXIT); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + + LOS_TaskDelay(10); // 10, set delay time. + + ret = LOS_TaskPriGet(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, (UINT16)OS_INVALID, ret); + + return LOS_OK; +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +void ItLosTask100(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask100", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_102.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_102.c new file mode 100644 index 00000000..e395c577 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_102.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void HwiF01(void) +{ + UINT32 ret; + + TEST_HwiClear(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + g_testCount++; + + ret = LOS_TaskPriGet(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, TASK_PRIO_TEST_TASK - 1, ret); +} + +static void TaskF01(void) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + TestHwiTrigger(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + g_testCount++; + + TEST_HwiDelete(HWI_NUM_TEST); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk102A"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, assert that g_testCount is equal to this. + +EXIT: + LOS_TaskDelete(g_testTaskID01); + TEST_HwiDelete(HWI_NUM_TEST); + return LOS_OK; +} + +void ItLosTask102(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask102", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_103.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_103.c new file mode 100644 index 00000000..ef91eb9d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_103.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02(void) +{ + UINT32 ret; + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID02); + return; +} + +static void TaskF01(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk103B"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskPriGet(g_testTaskID02); + ICUNIT_ASSERT_EQUAL_VOID(ret, TASK_PRIO_TEST_TASK - 1, ret); + + ret = LOS_TaskPriGet(g_testTaskID01); + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + ICUNIT_ASSERT_EQUAL_VOID(ret, TASK_PRIO_TEST_TASK - 2, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + g_testCount++; + +EXIT1: + LOS_TaskDelete(g_testTaskID01); + return; +EXIT: + LOS_TaskDelete(g_testTaskID02); + LOS_TaskDelete(g_testTaskID01); + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk103A"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + g_testCount = 0; + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +void ItLosTask103(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask103", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_104.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_104.c new file mode 100644 index 00000000..844f38f6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_104.c @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02(void) +{ + UINT32 ret; + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + g_testCount++; + + ret = LOS_TaskPriGet(g_testTaskID02); + // 3, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + ICUNIT_ASSERT_EQUAL_VOID(ret, TASK_PRIO_TEST_TASK - 3, ret); + + ret = LOS_TaskPriGet(g_testTaskID01); + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + ICUNIT_ASSERT_EQUAL_VOID(ret, TASK_PRIO_TEST_TASK - 2, ret); + +EXIT: + LOS_TaskDelete(g_testTaskID02); + return; +} + +static void TaskF01(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk104B"; + // 3, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 3; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT1); + + ret = LOS_TaskPriGet(g_testTaskID02); + ICUNIT_GOTO_EQUAL(ret, (UINT16)OS_INVALID, ret, EXIT1); + +EXIT1: + LOS_TaskDelete(g_testTaskID01); + return; +EXIT: + LOS_TaskDelete(g_testTaskID02); + LOS_TaskDelete(g_testTaskID01); + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk104A"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(10); // 10, set delay time. + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +void ItLosTask104(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask104", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_106.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_106.c new file mode 100644 index 00000000..e3b067d2 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_106.c @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void HwiF01(void) +{ + UINT32 ret; + + TEST_HwiClear(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + g_testCount++; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + ret = LOS_TaskPriSet(g_testTaskID02, TASK_PRIO_TEST_TASK - 2); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); +} + +static void TaskF02(void) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + g_testCount++; + + ret = LOS_TaskPriGet(g_testTaskID02); + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + ICUNIT_ASSERT_EQUAL_VOID(ret, TASK_PRIO_TEST_TASK - 2, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + g_testCount++; +} + +static void TaskF01(void) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + TestHwiTrigger(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 4, g_testCount); // 4, assert that g_testCount is equal to this. + g_testCount++; + + TEST_HwiDelete(HWI_NUM_TEST); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk106A"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + LOS_TaskLock(); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.pcName = "Tsk106B"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK + 1; + + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + + LOS_TaskUnlock(); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT2); // 5, assert that g_testCount is equal to this. + +EXIT2: + TEST_HwiDelete(HWI_NUM_TEST); +EXIT1: + LOS_TaskDelete(g_testTaskID02); +EXIT: + LOS_TaskDelete(g_testTaskID01); + return LOS_OK; +} + +void ItLosTask106(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask106", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_107.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_107.c new file mode 100644 index 00000000..3b8430bd --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_107.c @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02(void) +{ + UINT32 ret; + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + g_testCount++; + + // 4, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + ret = LOS_TaskPriSet(g_testTaskID02, TASK_PRIO_TEST_TASK - 4); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + g_testCount++; + + return; +EXIT: + LOS_TaskDelete(g_testTaskID02); + return; +} + +static void TaskF01(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk107B"; + // 3, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 3; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskPriGet(g_testTaskID02); + ICUNIT_ASSERT_EQUAL_VOID(ret, (UINT16)OS_INVALID, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + g_testCount++; + +EXIT1: + LOS_TaskDelete(g_testTaskID01); + return; +EXIT: + LOS_TaskDelete(g_testTaskID02); + LOS_TaskDelete(g_testTaskID01); + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk107A"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(10); // 10, set delay time. + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, assert that g_testCount is equal to this. + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +void ItLosTask107(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask107", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_108.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_108.c new file mode 100644 index 00000000..afefcb22 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_108.c @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02(void) +{ + UINT32 ret; + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + g_testCount++; + + ret = LOS_TaskPriSet(g_testTaskID02, TASK_PRIO_TEST_TASK - 1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, assert that g_testCount is equal to this. + g_testCount++; + + return; +EXIT: + LOS_TaskDelete(g_testTaskID02); + return; +} + +static void TaskF01(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk108B"; + // 3, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 3; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + g_testCount++; + + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskPriGet(g_testTaskID02); + ICUNIT_ASSERT_EQUAL_VOID(ret, TASK_PRIO_TEST_TASK - 1, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + g_testCount++; + +EXIT1: + LOS_TaskDelete(g_testTaskID01); + return; +EXIT: + LOS_TaskDelete(g_testTaskID02); + LOS_TaskDelete(g_testTaskID01); + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk108A"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(10); // 10, set delay time. + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, assert that g_testCount is equal to this. + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +void ItLosTask108(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask108", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_109.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_109.c new file mode 100644 index 00000000..981af5ce --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_109.c @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02(void) +{ + UINT32 ret; + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + g_testCount++; + + ret = LOS_TaskPriSet(g_testTaskID01, TASK_PRIO_TEST_TASK - 1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + g_testCount++; + + return; +EXIT: + LOS_TaskDelete(g_testTaskID02); + return; +} + +static void TaskF01(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk109B"; + // 3, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 3; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskPriGet(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, TASK_PRIO_TEST_TASK - 1, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + g_testCount++; + +EXIT1: + LOS_TaskDelete(g_testTaskID01); + return; +EXIT: + LOS_TaskDelete(g_testTaskID02); + LOS_TaskDelete(g_testTaskID01); + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk109A"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(10); // 10, set delay time. + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, assert that g_testCount is equal to this. + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +void ItLosTask109(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask109", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_110.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_110.c new file mode 100644 index 00000000..117485d8 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_110.c @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02(void) +{ + UINT32 ret; + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + g_testCount++; + + // 4, Used to calculate priority + ret = LOS_TaskPriSet(g_testTaskID01, TASK_PRIO_TEST_TASK - 4); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, assert that g_testCount is equal to this. + g_testCount++; + + return; +EXIT: + LOS_TaskDelete(g_testTaskID02); + return; +} + +static void TaskF01(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk110B"; + // 3, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 3; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + g_testCount++; + + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskPriGet(g_testTaskID01); + // 4, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + ICUNIT_ASSERT_EQUAL_VOID(ret, TASK_PRIO_TEST_TASK - 4, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + g_testCount++; + +EXIT1: + LOS_TaskDelete(g_testTaskID01); + return; +EXIT: + LOS_TaskDelete(g_testTaskID02); + LOS_TaskDelete(g_testTaskID01); + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk110A"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(10); // 10, set delay time. + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, assert that g_testCount is equal to this. + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +void ItLosTask110(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask110", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_111.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_111.c new file mode 100644 index 00000000..9036dc02 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_111.c @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02(void) +{ + UINT32 ret; + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + g_testCount++; + + // 3, Used to calculate priority. + ret = LOS_TaskPriSet(g_testTaskID01, TASK_PRIO_TEST_TASK - 3); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + g_testCount++; + + return; +EXIT: + LOS_TaskDelete(g_testTaskID02); + return; +} + +static void TaskF01(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk111B"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 3; // 3, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskPriGet(g_testTaskID01); + // 3, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + ICUNIT_ASSERT_EQUAL_VOID(ret, TASK_PRIO_TEST_TASK - 3, ret); + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + g_testCount++; + +EXIT1: + LOS_TaskDelete(g_testTaskID01); + return; +EXIT: + LOS_TaskDelete(g_testTaskID02); + LOS_TaskDelete(g_testTaskID01); + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk111A"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(10); // 10, set delay time. + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, assert that g_testCount is equal to this. + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +void ItLosTask111(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask111", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_112.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_112.c new file mode 100644 index 00000000..09d6fc9d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_112.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02(void) +{ + UINT32 ret; + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + g_testCount++; + + ret = LOS_TaskPriSet(g_testTaskID02, TASK_PRIO_TEST_TASK - 1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + g_testCount++; + + return; +EXIT: + LOS_TaskDelete(g_testTaskID02); + return; +} + +static void TaskF01(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk112B"; + // 4, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 4; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + g_testCount++; + + ret = LOS_TaskPriGet(g_testTaskID02); + ICUNIT_GOTO_EQUAL(ret, TASK_PRIO_TEST_TASK - 1, ret, EXIT); + + // 4, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + ret = LOS_TaskPriSet(g_testTaskID02, TASK_PRIO_TEST_TASK - 4); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, assert that g_testCount is equal to this. + g_testCount++; + +EXIT1: + LOS_TaskDelete(g_testTaskID01); + return; +EXIT: + LOS_TaskDelete(g_testTaskID02); + LOS_TaskDelete(g_testTaskID01); + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk112A"; + // 3, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 3; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(15); // 15, set delay time. + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, assert that g_testCount is equal to this. + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +void ItLosTask112(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask112", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_113.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_113.c new file mode 100644 index 00000000..70d96b3a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_113.c @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02(void) +{ + UINT32 ret; + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + + g_testCount++; + + ret = LOS_TaskPriGet(g_testTaskID02); + // 3, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + ICUNIT_GOTO_EQUAL(ret, TASK_PRIO_TEST_TASK - 3, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, assert that g_testCount is equal to this. + g_testCount++; + + return; +EXIT: + LOS_TaskDelete(g_testTaskID02); + return; +} + +static void TaskF01(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk113B"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + g_testCount++; + + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + g_testCount++; + + // 3, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + ret = LOS_TaskPriSet(g_testTaskID02, TASK_PRIO_TEST_TASK - 3); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, assert that g_testCount is equal to this. + g_testCount++; + +EXIT1: + LOS_TaskDelete(g_testTaskID01); + return; +EXIT: + LOS_TaskDelete(g_testTaskID02); + LOS_TaskDelete(g_testTaskID01); + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk113A"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(10); // 10, set delay time. + + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); // 5, assert that g_testCount is equal to this. + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +void ItLosTask113(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask113", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_114.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_114.c new file mode 100644 index 00000000..414a279c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_114.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void HwiF01(void) +{ + UINT32 ret; + + TEST_HwiClear(HWI_NUM_TEST); + // 3, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + ret = LOS_CurTaskPriSet(TASK_PRIO_TEST_TASK - 3); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + g_testCount++; +EXIT: + return; +} + +static void TaskF01(void) +{ + UINT32 ret; + HWI_PRIOR_T hwiPrio = 3; + HWI_MODE_T mode = 0; + HWI_ARG_T arg = 0; + + ret = LOS_HwiCreate(HWI_NUM_TEST, hwiPrio, mode, (HWI_PROC_FUNC)HwiF01, (HwiIrqParam *)arg); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + TestHwiTrigger(HWI_NUM_TEST); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT1); + + ret = LOS_TaskPriGet(g_testTaskID01); + // 3, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + ICUNIT_GOTO_EQUAL(ret, TASK_PRIO_TEST_TASK - 3, ret, EXIT1); + +EXIT1: + TEST_HwiDelete(HWI_NUM_TEST); +EXIT: + LOS_TaskDelete(g_testTaskID01); + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk114A"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(10); // 10, set delay time. + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +void ItLosTask114(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask114", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_115.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_115.c new file mode 100644 index 00000000..5cfd8fb8 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_115.c @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02(void) +{ + UINT32 ret; + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + g_testCount++; + + LOS_TaskLock(); + + ret = LOS_CurTaskPriSet(TASK_PRIO_TEST_TASK - 1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + g_testCount++; + + LOS_TaskUnlock(); + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, assert that g_testCount is equal to this. + g_testCount++; + + return; +EXIT: + LOS_TaskDelete(g_testTaskID02); + return; +} + +static void TaskF01(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk078B"; + // 4, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 4; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + g_testCount++; + + ret = LOS_TaskPriGet(g_testTaskID02); + ICUNIT_GOTO_EQUAL(ret, TASK_PRIO_TEST_TASK - 1, ret, EXIT); + + // 4, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + ret = LOS_TaskPriSet(g_testTaskID02, TASK_PRIO_TEST_TASK - 4); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, assert that g_testCount is equal to this. + g_testCount++; + +EXIT1: + LOS_TaskDelete(g_testTaskID01); + return; +EXIT: + LOS_TaskDelete(g_testTaskID02); + LOS_TaskDelete(g_testTaskID01); + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk078A"; + // 3, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 3; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(15); // 15, set delay time. + + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); // 5, assert that g_testCount is equal to this. + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +void ItLosTask115(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask115", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_116.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_116.c new file mode 100644 index 00000000..7b5fdd2d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_116.c @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void SwtmrF01(UINTPTR arg) +{ + UINT32 ret; + if (arg != 0xffff) { + return; + } + // 3, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + ret = LOS_CurTaskPriSet(TASK_PRIO_TEST_TASK - 3); + + g_testCount++; + return; +} + +static void TaskF01(void) +{ + UINT32 ret; + UINT16 swTmrID; + + // 2, Used to set swtmr + ret = LOS_SwtmrCreate(2, LOS_SWTMR_MODE_ONCE, SwtmrF01, &swTmrID, 0xffff); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + + ret = LOS_SwtmrStart(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + + ret = LOS_TaskDelay(5); // 5, set delay time. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT1); + g_testCount++; + + ret = LOS_TaskPriGet(g_testTaskID01); + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + ICUNIT_GOTO_EQUAL(ret, TASK_PRIO_TEST_TASK - 2, ret, EXIT); + +#if SELF_DELETED + ret = LOS_SwtmrDelete(swTmrID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return; +#endif + return; + +EXIT1: + LOS_SwtmrDelete(swTmrID); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk116A"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(10); // 10, set delay time. + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +void ItLosTask116(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask116", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_118.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_118.c new file mode 100644 index 00000000..e3ea1bf7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_118.c @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_sumSize; +static void *g_ptr1 = NULL; +static void *g_ptr2 = NULL; +extern UINT32 OsTaskMemUsage(UINT32 taskID); +static void HwiF01(void) +{ + UINT32 size = 2; + UINT32 ret; + UINT32 sumSize; + g_ptr1 = LOS_MemAlloc((void *)OS_SYS_MEM_ADDR, size); + ICUNIT_GOTO_NOT_EQUAL(g_ptr1, NULL, g_ptr1, EXIT); + sumSize = OsTaskMemUsage(g_testTaskID01); + ICUNIT_GOTO_EQUAL(sumSize, g_sumSize, sumSize, EXIT); + LOS_MemFree((void *)OS_SYS_MEM_ADDR, g_ptr1); + sumSize = OsTaskMemUsage(g_testTaskID01); + ICUNIT_GOTO_EQUAL(sumSize, g_sumSize, sumSize, EXIT); +EXIT: + TEST_HwiClear(HWI_NUM_TEST); +} + +static void TaskF02(void) +{ + UINT32 ret; + UINT32 sumSize; + + LOS_MemFree((void *)OS_SYS_MEM_ADDR, g_ptr2); + sumSize = OsTaskMemUsage(g_testTaskID02); + ICUNIT_GOTO_EQUAL(sumSize, 0, sumSize, EXIT); + sumSize = OsTaskMemUsage(g_testTaskID01); + ICUNIT_GOTO_EQUAL(sumSize, 0, sumSize, EXIT); + + return; +EXIT: + LOS_TaskDelete(g_testTaskID02); + return; +} + +static void TaskF01(void) +{ + UINT32 ret; + UINT32 sumSize1, sumSize2; + UINT32 size = 2; + HWI_PRIOR_T hwiPrio = 3; + HWI_MODE_T mode = 0; + HWI_ARG_T arg = 0; + + ret = LOS_HwiCreate(HWI_NUM_TEST, hwiPrio, mode, (HWI_PROC_FUNC)HwiF01, arg); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + g_sumSize = OsTaskMemUsage(g_testTaskID01); + + TestHwiTrigger(HWI_NUM_TEST); + + TEST_HwiDelete(HWI_NUM_TEST); + + g_ptr2 = LOS_MemAlloc((void *)OS_SYS_MEM_ADDR, size); + ICUNIT_GOTO_NOT_EQUAL(g_ptr2, NULL, g_ptr2, EXIT); + sumSize1 = OsTaskMemUsage(g_testTaskID01); + ICUNIT_GOTO_NOT_EQUAL(sumSize1, 0, sumSize1, EXIT); + LOS_TaskDelay(10); // 10, set delay time. + + size = 0x200; + g_ptr1 = LOS_MemAlloc((void *)OS_SYS_MEM_ADDR, size); + ICUNIT_GOTO_NOT_EQUAL(g_ptr1, NULL, g_ptr1, EXIT); + sumSize1 = OsTaskMemUsage(g_testTaskID01); + ICUNIT_GOTO_NOT_EQUAL(sumSize1, 0, sumSize1, EXIT); + + size = 0x2; + g_ptr2 = LOS_MemAlloc((void *)OS_SYS_MEM_ADDR, size); + ICUNIT_GOTO_NOT_EQUAL(g_ptr2, NULL, g_ptr2, EXIT); + sumSize2 = OsTaskMemUsage(g_testTaskID01); + ICUNIT_GOTO_NOT_EQUAL(sumSize2, sumSize1, sumSize2, EXIT); + + LOS_MemFree((void *)OS_SYS_MEM_ADDR, g_ptr2); + sumSize2 = OsTaskMemUsage(g_testTaskID01); + ICUNIT_GOTO_EQUAL(sumSize2, sumSize1, sumSize2, EXIT); + + LOS_MemFree((void *)OS_SYS_MEM_ADDR, g_ptr1); + sumSize2 = OsTaskMemUsage(g_testTaskID01); + ICUNIT_GOTO_EQUAL(sumSize2, 0, sumSize2, EXIT); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk118A"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = memset_s(&task1, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk118B"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(10); // 10, set delay time. + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + + return LOS_OK; +} + +void ItLosTask118(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask118", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_119.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_119.c new file mode 100644 index 00000000..908e332e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_119.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Task_119"; + // 32, Set the priority according to the task purpose + task1.usTaskPrio = 32; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_PRIOR_ERROR, ret); + + return LOS_OK; +} + +void ItLosTask119(void) +{ + TEST_ADD_CASE("ItLosTask119", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_120.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_120.c new file mode 100644 index 00000000..03b989f1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_120.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + g_testCount++; + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return; +EXIT: + g_testCount = 0; + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = NULL; + task1.uwStackSize = TASK_STACK_SIZE_TEST; // TASK_STACK_SIZE_TEST = 1024 + task1.pcName = "Task_120"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_TSK_ENTRY_NULL, ret, EXIT); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = ""; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + task1.pcName = "Task_120"; + task1.uwStackSize = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ICUNIT_GOTO_EQUAL(task1.uwStackSize, LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE, task1.uwStackSize, EXIT); + + TestExtraTaskDelay(2); // 2, set delay time.(2); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + + return LOS_OK; +EXIT: + LOS_TaskDelete(g_testTaskID01); + return LOS_OK; +} + +void ItLosTask120(void) +{ + TEST_ADD_CASE("ItLosTask120", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_121.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_121.c new file mode 100644 index 00000000..1d569e65 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_121.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = 0x101; + task1.pcName = "Task_121"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_STKSZ_TOO_SMALL, ret); + + return LOS_OK; +} + +void ItLosTask121(void) +{ + TEST_ADD_CASE("ItLosTask121", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_122.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_122.c new file mode 100644 index 00000000..e3ccd8b1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_122.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02(void) +{ + g_testCount++; + + LOS_TaskDelete(g_testTaskID02); + + return; +} + +static void TaskF01(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Task_122_1"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + g_testCount++; + + LOS_TaskDelete(g_testTaskID01); + + return; + +EXIT: + LOS_TaskDelete(g_testTaskID02); + LOS_TaskDelete(g_testTaskID01); + + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Task_122"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + LOS_TaskDelete(g_testTaskID01); + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + return LOS_OK; +} + +void ItLosTask122(void) +{ + TEST_ADD_CASE("ItLosTask122", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_123.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_123.c new file mode 100644 index 00000000..b7346365 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_123.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02(void) +{ + g_testCount++; + + while (1) { + } +} + +static void TaskF01(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Task_123_1"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + ret = LOS_TaskDelay(2); // 2, set delay time. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID02); + LOS_TaskDelete(g_testTaskID01); + + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Task_123"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + return LOS_OK; +} + +void ItLosTask123(void) +{ + TEST_ADD_CASE("ItLosTask123", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_124.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_124.c new file mode 100644 index 00000000..79244497 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_124.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02(void) +{ + INT32 ret; + g_testCount++; + + ret = LOS_TaskDelete(g_testTaskID02); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + return; +} + +static void TaskF01(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Task_124_1"; + // 3, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 3; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + g_testCount++; + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + return; + +EXIT: + LOS_TaskDelete(g_testTaskID02); + LOS_TaskDelete(g_testTaskID01); + + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Task_124"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + return LOS_OK; +} + +void ItLosTask124(void) +{ + TEST_ADD_CASE("ItLosTask124", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_125.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_125.c new file mode 100644 index 00000000..28d09aad --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_125.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void HwiF01(void) +{ + UINT32 ret; + + TEST_HwiClear(HWI_NUM_TEST); + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + g_testCount++; + + return; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + return; +} + +static void TaskF01(void) +{ + UINT32 ret; + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + TestHwiTrigger(HWI_NUM_TEST); + + TEST_HwiDelete(HWI_NUM_TEST); + + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Task_125"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_HwiTriggerDelay; + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + TEST_HwiTriggerDelay; + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + return LOS_OK; +EXIT: + LOS_TaskDelete(g_testTaskID01); + return LOS_OK; +} + +void ItLosTask125(void) +{ + TEST_ADD_CASE("ItLosTask125", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_126.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_126.c new file mode 100644 index 00000000..46d46126 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_126.c @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02(void) +{ + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, assert that g_testCount is equal to this. + + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID02); + + return; +} +static void HwiF01(void) +{ + UINT32 ret; + + TEST_HwiClear(HWI_NUM_TEST); + + ret = LOS_TaskSuspend(g_testTaskID02); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + g_testCount++; + + return; + +EXIT: + LOS_TaskDelete(g_testTaskID02); + LOS_TaskDelete(g_testTaskID01); + return; +} + +static void TaskF01(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Task_126_1"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT2); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + TestHwiTrigger(HWI_NUM_TEST); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT1); + + g_testCount++; + + TEST_HwiDelete(HWI_NUM_TEST); + + LOS_TaskDelete(g_testTaskID01); + + return; + +EXIT1: + LOS_TaskDelete(g_testTaskID02); +EXIT2: + TEST_HwiDelete(HWI_NUM_TEST); + LOS_TaskDelete(g_testTaskID01); + + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Task_126"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + + g_testCount++; + + ret = LOS_TaskResume(g_testTaskID02); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, assert that g_testCount is equal to this. + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID02); + return LOS_OK; +} + +void ItLosTask126(void) +{ + TEST_ADD_CASE("ItLosTask126", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_127.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_127.c new file mode 100644 index 00000000..e3ea0943 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_127.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02(void) +{ + g_testCount++; +} + +static void TaskF01(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Task_127_1"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskSuspend(g_testTaskID02); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Task_127"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + LOS_TaskDelete(g_testTaskID02); + + return LOS_OK; +} + +void ItLosTask127(void) +{ + TEST_ADD_CASE("ItLosTask127", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_128.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_128.c new file mode 100644 index 00000000..ff52a0b3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_128.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02(void) +{ + UINT32 ret; + UINT32 index; + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + for (index = 0; index < 0x1000; index++) { + } + + g_testCount++; + + LOS_TaskDelete(g_testTaskID02); + return; +} + +static void TaskF01(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Task_128_1"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + g_testCount++; + + ret = LOS_TaskDelay(2); // 2, set delay time. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + return; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Task_128"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +void ItLosTask128(void) +{ + TEST_ADD_CASE("ItLosTask128", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_129.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_129.c new file mode 100644 index 00000000..051c06b4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_129.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02(void) +{ + return; +} + +static void HwiF01(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Task_129_1"; + // 3, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 3; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + TEST_HwiClear(HWI_NUM_TEST); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + g_testCount++; + + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_TSK_YIELD_IN_INT, ret, EXIT); + +EXIT: + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + g_testCount = 0; + g_testCount++; + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + g_testCount++; + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + TestHwiTrigger(HWI_NUM_TEST); + + ret = LOS_TaskDelay(1); // 1, set delay time. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_HwiDelete(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + return LOS_OK; + +EXIT: + TEST_HwiDelete(HWI_NUM_TEST); + return LOS_OK; +} + +void ItLosTask129(void) +{ + TEST_ADD_CASE("ItLosTask129", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_130.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_130.c new file mode 100644 index 00000000..ab3e7bd3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_130.c @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02(void) +{ + UINT32 ret; + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT1); // 2, assert that g_testCount is equal to this. + g_testCount++; + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT2); // 4, assert that g_testCount is equal to this. + g_testCount++; + + LOS_TaskDelete(g_testTaskID02); + + return; + +EXIT1: + LOS_TaskDelete(g_testTaskID01); +EXIT2: + LOS_TaskDelete(g_testTaskID02); + + return; +} + +static void TaskF01(void) +{ + UINT32 ret; + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT2); + g_testCount++; + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT1); // 3, assert that g_testCount is equal to this. + g_testCount++; + + LOS_TaskDelete(g_testTaskID01); + return; + +EXIT1: + LOS_TaskDelete(g_testTaskID02); +EXIT2: + LOS_TaskDelete(g_testTaskID01); + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Task_130"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + g_testCount++; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.pcName = "Task_130_1"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_ASSERT_EQUAL(g_testCount, 5, g_testCount); // 5, assert that g_testCount is equal to this. + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +void ItLosTask130(void) +{ + TEST_ADD_CASE("ItLosTask130", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_131.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_131.c new file mode 100644 index 00000000..7bc428d0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_131.c @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void HwiF01(void) +{ + UINT32 ret; + + TEST_HwiClear(HWI_NUM_TEST); + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, assert that g_testCount is equal to this. + g_testCount++; + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return; + +EXIT: + LOS_TaskDelete(g_testTaskID02); + LOS_TaskDelete(g_testTaskID01); + + return; +} + +static void TaskF02(void) +{ + UINT32 ret; + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT1); // 2, assert that g_testCount is equal to this. + g_testCount++; + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + TestHwiTrigger(HWI_NUM_TEST); + + ret = LOS_TaskDelay(1); // 1, set delay time. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT2); // 5, assert that g_testCount is equal to this. + + g_testCount++; + + TEST_HwiDelete(HWI_NUM_TEST); + + LOS_TaskDelete(g_testTaskID02); + + return; + +EXIT1: + LOS_TaskDelete(g_testTaskID02); +EXIT2: + LOS_TaskDelete(g_testTaskID01); + + return; +} + +static void TaskF01(void) +{ + UINT32 ret; + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT2); + + g_testCount++; + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT1); // 4, assert that g_testCount is equal to this. + g_testCount++; + + LOS_TaskDelete(g_testTaskID01); + + return; + +EXIT1: + LOS_TaskDelete(g_testTaskID02); +EXIT2: + LOS_TaskDelete(g_testTaskID01); + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Task_131"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + g_testCount++; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.pcName = "Task_131_1"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskDelay(1); // 1, set delay time. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 6, g_testCount); // 6, assert that g_testCount is equal to this. + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +void ItLosTask131(void) +{ + TEST_ADD_CASE("ItLosTask131", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_132.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_132.c new file mode 100644 index 00000000..a0728a9d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_132.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(void) +{ + UINT32 ret; + + g_swTmrID = OsPercpuGet()->swtmrTaskID; + + ret = LOS_TaskSuspend(g_swTmrID); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK, ret); + + ret = LOS_TaskResume(g_swTmrID); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_NOT_SUSPENDED, ret); + + return LOS_OK; +} + +void ItLosTask132(void) +{ + TEST_ADD_CASE("ItLosTask132", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_133.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_133.c new file mode 100644 index 00000000..9385e15a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_133.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + ret = LOS_TaskDelete(g_testTaskID01); + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + UINT32 taskID02; + + TSK_INIT_PARAM_S task1 = { 0 }; + LOS_TaskLock(); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Task_133"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + ret = LOS_TaskCreate(&taskID02, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskUnlock(); + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_NOT_CREATED, ret); + + ret = LOS_TaskDelete(taskID02); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_NOT_CREATED, ret); + + return LOS_OK; +} + +void ItLosTask133(void) +{ + TEST_ADD_CASE("ItLosTask133", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_134.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_134.c new file mode 100644 index 00000000..ac30ed74 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_134.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Task_134__"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK + 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + // 3, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK + 3; + + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT2); + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT2); + ret = LOS_TaskDelete(g_testTaskID02); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT2); + + return LOS_OK; +EXIT2: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + return LOS_OK; +} + +void ItLosTask134(void) +{ + TEST_ADD_CASE("ItLosTask134", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_135.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_135.c new file mode 100644 index 00000000..f95914f3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_135.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + + g_testCount = 0; + + TSK_INIT_PARAM_S task1 = { 0 }; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk138A"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_TRACK_EQUAL(ret, LOS_ERRNO_TSK_NOT_CREATED, ret); + + ret = LOS_TaskResume(OsGetIdleTaskId()); + ICUNIT_TRACK_EQUAL(ret, LOS_ERRNO_TSK_NOT_SUSPENDED, ret); + + ret = LOS_TaskResume(LOSCFG_BASE_CORE_TSK_LIMIT + 1); + ICUNIT_TRACK_EQUAL(ret, LOS_ERRNO_TSK_ID_INVALID, ret); + + return LOS_OK; +} + +void ItLosTask135(void) +{ + TEST_ADD_CASE("ItLosTask135", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_136.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_136.c new file mode 100644 index 00000000..5a142e34 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_136.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_TRACK_EQUAL(ret, LOS_OK, ret); + + g_testCount++; + + return; +} + +static void TaskF02(void) +{ + UINT32 ret; + + ret = LOS_TaskSuspend(g_testTaskID02); + ICUNIT_TRACK_EQUAL(ret, LOS_OK, ret); + + g_testCount++; + + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret, i; + TSK_INIT_PARAM_S task1 = { 0 }; + TSK_INIT_PARAM_S task2 = { 0 }; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Task_136_1"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + task2.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task2.uwStackSize = TASK_STACK_SIZE_TEST; + task2.pcName = "Task_136_2"; + task2.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task2.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task2.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + for (i = 0; i < IT_TASK_SMP_LOOP; i++) { + g_testCount = 0; + + LOS_TaskLock(); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskCreate(&g_testTaskID02, &task2); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskUnlock(); + + ICUNIT_ASSERT_EQUAL(g_testCount, 0, g_testCount); + + LOS_TaskLock(); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_TRACK_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskResume(g_testTaskID02); + ICUNIT_TRACK_EQUAL(ret, LOS_OK, ret); + + LOS_TaskUnlock(); + } + + LOS_TaskDelay(1); // 1, set delay time. + + return LOS_OK; +} + +void ItLosTask136(void) +{ + TEST_ADD_CASE("ItLosTask136", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_138.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_138.c new file mode 100644 index 00000000..6a4210d0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_138.c @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_sumSize; +static void *g_ptr1 = NULL; +static void *g_ptr2 = NULL; +extern UINT32 OsTaskMemUsage(UINT32 taskID); +static void HwiF01(void) +{ + UINT32 size = 2; + UINT32 ret; + UINT32 sumSize; + g_ptr1 = LOS_MemAlloc((void *)OS_SYS_MEM_ADDR, size); + ICUNIT_GOTO_NOT_EQUAL(g_ptr1, NULL, g_ptr1, EXIT); + sumSize = OsTaskMemUsage(g_testTaskID01); + ICUNIT_GOTO_EQUAL(sumSize, g_sumSize, sumSize, EXIT); + LOS_MemFree((void *)OS_SYS_MEM_ADDR, g_ptr1); + sumSize = OsTaskMemUsage(g_testTaskID01); + ICUNIT_GOTO_EQUAL(sumSize, g_sumSize, sumSize, EXIT); +EXIT: + TEST_HwiClear(HWI_NUM_TEST); +} + +static void TaskF02(void) +{ + UINT32 ret; + UINT32 sumSize; + + LOS_MemFree((void *)OS_SYS_MEM_ADDR, g_ptr2); + sumSize = OsTaskMemUsage(g_testTaskID02); + ICUNIT_GOTO_EQUAL(sumSize, 0, sumSize, EXIT); + sumSize = OsTaskMemUsage(g_testTaskID01); + ICUNIT_GOTO_EQUAL(sumSize, 0, sumSize, EXIT); + + return; +EXIT: + LOS_TaskDelete(g_testTaskID02); + return; +} + +static void TaskF01(void) +{ + UINT32 ret; + UINT32 sumSize1, sumSize2; + UINT32 size = 2; + HWI_PRIOR_T hwiPrio = 3; + HWI_MODE_T mode = 0; + HWI_ARG_T arg = 0; + + ret = LOS_HwiCreate(HWI_NUM_TEST, hwiPrio, mode, (HWI_PROC_FUNC)HwiF01, (HwiIrqParam *)arg); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + g_sumSize = OsTaskMemUsage(g_testTaskID01); + + TestHwiTrigger(HWI_NUM_TEST); + + TEST_HwiDelete(HWI_NUM_TEST); + + g_ptr2 = LOS_MemAlloc((void *)OS_SYS_MEM_ADDR, size); + ICUNIT_GOTO_NOT_EQUAL(g_ptr2, NULL, g_ptr2, EXIT); + sumSize1 = OsTaskMemUsage(g_testTaskID01); + ICUNIT_GOTO_NOT_EQUAL(sumSize1, 0, sumSize1, EXIT); + LOS_TaskDelay(10); // 10, set delay time. + + size = 0x200; + g_ptr1 = LOS_MemAlloc((void *)OS_SYS_MEM_ADDR, size); + ICUNIT_GOTO_NOT_EQUAL(g_ptr1, NULL, g_ptr1, EXIT); + sumSize1 = OsTaskMemUsage(g_testTaskID01); + ICUNIT_GOTO_NOT_EQUAL(sumSize1, 0, sumSize1, EXIT); + + size = 0x2; + g_ptr2 = LOS_MemAlloc((void *)OS_SYS_MEM_ADDR, size); + ICUNIT_GOTO_NOT_EQUAL(g_ptr2, NULL, g_ptr2, EXIT); + sumSize2 = OsTaskMemUsage(g_testTaskID01); + ICUNIT_GOTO_NOT_EQUAL(sumSize2, sumSize1, sumSize2, EXIT); + + LOS_MemFree((void *)OS_SYS_MEM_ADDR, g_ptr2); + sumSize2 = OsTaskMemUsage(g_testTaskID01); + ICUNIT_GOTO_EQUAL(sumSize2, sumSize1, sumSize2, EXIT); + + LOS_MemFree((void *)OS_SYS_MEM_ADDR, g_ptr1); + sumSize2 = OsTaskMemUsage(g_testTaskID01); + ICUNIT_GOTO_EQUAL(sumSize2, 0, sumSize2, EXIT); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk118A"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = memset_s(&task1, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk118B"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(10); // 10, set delay time. + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + + return LOS_OK; +} + +void ItLosTask138(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask138", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_141.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_141.c new file mode 100644 index 00000000..a41d892a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_141.c @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#ifndef TESTHI1980IMU + +static EVENT_CB_S g_eventCb01; +static UINT32 g_fpsrc01; +static UINT32 g_fpsrc02; +static UINT32 g_fpsrc03; + +__attribute__((noinline, used, optimize("-O0"))) static void FloatTestInTask() +{ +#ifndef LOSCFG_ARCH_FPU_DISABLE + float d1 = 100.0f; + UINT32 n1 = 0; + + __asm__("vldr s15, %0" ::"m"(d1)); + __asm__("vcmp.f32 s15, #0"); + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + + g_testCount++; + + __asm__ __volatile__("vmrs %0, fpscr\n" : "=r"(n1)::); // n1 is fpscr + g_fpsrc01 = n1; + dprintf("before schual fpscr = %x\n", n1); + LOS_EventWrite(&g_eventCb01, 0x1); + __asm__ __volatile__("vmrs %0, fpscr\n" : "=r"(n1)::); // need equals to before delay 's fpscr + + g_fpsrc02 = n1; + dprintf("after resume fpscr = %x\n", n1); + + g_testCount++; + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + LOS_EventWrite(&g_eventCb01, 0x1); +#endif +} + +#ifndef LOSCFG_ARCH_FPU_DISABLE +static UINT32 Testcase(void) +{ + UINT32 ret; + LOS_EventInit(&g_eventCb01); + + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)FloatTestInTask; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "TskTstA"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK + 1; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + g_fpsrc01 = 0; + g_fpsrc02 = 0; + g_fpsrc03 = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_EventRead(&g_eventCb01, 0x11, LOS_WAITMODE_OR | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, 0x1, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + float d1 = -100.0f; + UINT32 n1 = 0; + + __asm__("vldr s15, %0" ::"m"(d1)); + __asm__("vcmp.f32 s15, #0"); + + __asm__ __volatile__("vmrs %0, fpscr\n" : "=r"(n1)::); // fpscr need not equals to up value + g_fpsrc03 = n1; + dprintf("after change fpscr = %x\n", n1); + + g_testCount += 1; + + ret = LOS_EventRead(&g_eventCb01, 0x11, LOS_WAITMODE_OR | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, 0x1, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_fpsrc01, g_fpsrc02, g_fpsrc01, EXIT); + ICUNIT_GOTO_NOT_EQUAL(g_fpsrc01, g_fpsrc03, g_fpsrc03, EXIT); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_EventDestroy(&g_eventCb01); + + return LOS_OK; +} +#endif + +void ItLosTask141(void) +{ +#ifndef LOSCFG_ARCH_FPU_DISABLE + TEST_ADD_CASE("ItLosTask141", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +#endif +} + +#endif +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_142.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_142.c new file mode 100644 index 00000000..0f3f260c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_142.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#ifndef TESTHI1980IMU +#ifndef LOSCFG_ARCH_FPU_DISABLE + +static UINT32 g_fpsrc01; +static UINT32 g_fpsrc02; +static UINT32 g_fpsrc03; + +static void ItHwi() +{ + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + float d1 = -100.0f; + UINT32 n1 = 0; + __asm__("vldr s15, %0" ::"m"(d1)); + __asm__("vcmp.f32 s15, #0"); + + __asm__ __volatile__("vmrs %0, fpscr\n" : "=r"(n1)::); // n1 is fpscr + g_fpsrc03 = n1; + dprintf("after change fpscr = %x\n", n1); + + g_testCount += 1; + return; +} +static UINT32 Testcase(void) +{ + UINT32 ret; + HWI_PRIOR_T hwiPrio = 3; + HWI_MODE_T mode = 0; + HWI_ARG_T arg = 0; + + g_testCount = 0; + g_fpsrc01 = 0; + g_fpsrc02 = 0; + g_fpsrc03 = 0; + ret = LOS_HwiCreate(HWI_NUM_TEST3, hwiPrio, mode, (HWI_PROC_FUNC)ItHwi, arg); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST3, ArchCurrCpuid() + 1); // curret cpu +#endif + float d1 = 100.0f; + UINT32 n1 = 0; + __asm__("vldr s15, %0" ::"m"(d1)); + __asm__("vcmp.f32 s15, #0"); + + __asm__ __volatile__("vmrs %0, fpscr\n" : "=r"(n1)::); // n1 is fpscr + g_fpsrc01 = n1; + dprintf("before schual fpscr = %x\n", n1); + + ICUNIT_ASSERT_EQUAL(g_testCount, 0, g_testCount); + g_testCount++; + TestHwiTrigger(HWI_NUM_TEST3); + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + __asm__ __volatile__("vmrs %0, fpscr\n" : "=r"(n1)::); + g_fpsrc02 = n1; + dprintf("after resume fpscr = %x\n", n1); + g_testCount++; + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + TEST_HwiDelete(HWI_NUM_TEST3); + ICUNIT_ASSERT_EQUAL(g_fpsrc01, g_fpsrc02, g_fpsrc01); + ICUNIT_ASSERT_NOT_EQUAL(g_fpsrc01, g_fpsrc03, g_fpsrc03); + return LOS_OK; +} +#endif + +void ItLosTask142(void) +{ +#ifndef LOSCFG_ARCH_FPU_DISABLE + TEST_ADD_CASE("ItLosTask142", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL2, TEST_FUNCTION); +#endif + return; +} +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_timeslice_002.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_timeslice_002.c new file mode 100644 index 00000000..d055f0cd --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_timeslice_002.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02(void const * argument) +{ + g_timesliceTestCount++; +} + +static void TaskF01(void const * argument) +{ + UINT32 ret; + UINT32 intSave; + + intSave = LOS_IntLock(); + + g_itTimesliceTestCount1 = TestTickCountGet(); + + LOS_IntRestore(intSave); + + while (1) { + dprintf(""); + intSave = LOS_IntLock(); + if ((g_itTimesliceTestCount1 + 1) <= TestTickCountGet()) { + LOS_IntRestore(intSave); + break; + } + LOS_IntRestore(intSave); + } + ICUNIT_GOTO_EQUAL(g_timesliceTestCount, 0, g_timesliceTestCount, EXIT); + +EXIT:; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + + g_itTimesliceTestCount1 = 0; + g_timesliceTestCount = 0; + + LOS_TaskLock(); + + TSK_INIT_PARAM_S task; + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task.pcName = "TimesTsk002A"; + // 2, Used to calculate stack space + task.uwStackSize = TASK_STACK_SIZE_TEST * 2; + task.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task.pcName = "TimesTsk002B"; + task.uwStackSize = TASK_STACK_SIZE_TEST; + task.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + ret = LOS_TaskCreate(&g_testTaskID02, &task); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskUnlock(); + + LOS_TaskDelay(5); // 5, set delay time. + LOS_TaskDelete(g_testTaskID02); + LOS_TaskDelete(g_testTaskID01); + return LOS_OK; +} + +void ItLosTaskTimeslice002(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTaskTIMESLICE_002", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_timeslice_003.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_timeslice_003.c new file mode 100644 index 00000000..c62a362f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_timeslice_003.c @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF03(void const * argument) +{ + UINT32 ret; + + // 2, assert that result is equal to this. + ICUNIT_GOTO_EQUAL(g_timesliceTestCount, 2, g_timesliceTestCount, EXIT); + g_timesliceTestCount++; + +EXIT:; +} + +static void TaskF02(void const * argument) +{ + UINT32 ret; + UINT32 intSave; + UINT64 itTimesliceCount11; + + ICUNIT_GOTO_EQUAL(g_timesliceTestCount, 1, g_timesliceTestCount, EXIT); + g_timesliceTestCount++; + + intSave = LOS_IntLock(); + + itTimesliceCount11 = TestTickCountGet(); + + LOS_IntRestore(intSave); + + while (1) { + dprintf(""); + intSave = LOS_IntLock(); + if ((itTimesliceCount11 + LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT) < TestTickCountGet()) { + LOS_IntRestore(intSave); + break; + } + LOS_IntRestore(intSave); + } + // 4, assert that result is equal to this. + ICUNIT_GOTO_EQUAL(g_timesliceTestCount, 4, g_timesliceTestCount, EXIT); + g_timesliceTestCount++; + +EXIT:; +} + +static void TaskF01(void const * argument) +{ + UINT32 ret; + UINT32 intSave; + + intSave = LOS_IntLock(); + + ICUNIT_GOTO_EQUAL(g_timesliceTestCount, 0, g_timesliceTestCount, EXIT); + g_timesliceTestCount++; + + g_itTimesliceTestCount1 = TestTickCountGet(); + + LOS_IntRestore(intSave); + + while (1) { + dprintf(""); + intSave = LOS_IntLock(); + if ((g_itTimesliceTestCount1 + LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT) < TestTickCountGet()) { + LOS_IntRestore(intSave); + break; + } + LOS_IntRestore(intSave); + } + // 3, assert that result is equal to this. + ICUNIT_GOTO_EQUAL(g_timesliceTestCount, 3, g_timesliceTestCount, EXIT); + g_timesliceTestCount++; + +EXIT:; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + + g_itTimesliceTestCount1 = 0; + g_timesliceTestCount = 0; + + LOS_TaskLock(); + + TSK_INIT_PARAM_S task; + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task.pcName = "TimesTsk003A"; + // 2, Used to calculate stack space + task.uwStackSize = TASK_STACK_SIZE_TEST * 2; + task.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task.pcName = "TimesTsk003B"; + // 2, Used to calculate stack space + task.uwStackSize = TASK_STACK_SIZE_TEST * 2; + task.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + ret = LOS_TaskCreate(&g_testTaskID02, &task); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF03; + task.pcName = "TimesTsk003C"; + task.uwStackSize = TASK_STACK_SIZE_TEST; + task.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + ret = LOS_TaskCreate(&g_testTaskID03, &task); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskUnlock(); + + LOS_TaskDelay(20); // 20, set delay time. + // 5, assert that result is equal to this. + ICUNIT_ASSERT_EQUAL(g_timesliceTestCount, 5, g_timesliceTestCount); + LOS_TaskDelete(g_testTaskID03); + LOS_TaskDelete(g_testTaskID02); + LOS_TaskDelete(g_testTaskID01); + return LOS_OK; +} + +void ItLosTaskTimeslice003(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTaskTIMESLICE_003", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_timeslice_004.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_timeslice_004.c new file mode 100644 index 00000000..cbe89f85 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/full/It_los_task_timeslice_004.c @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +UINT32 g_cmsisRobinTestCount2 = 0; +static void TaskF02(void const * argument) +{ + UINT32 ret; + + ICUNIT_GOTO_EQUAL(g_timesliceTestCount, 1, ret, EXIT); + g_timesliceTestCount++; + return; +} + +static void SwtmrF01(UINT32 *arg) +{ + // 100, set g_cmsisRobinTestCount2 num + g_cmsisRobinTestCount2 = 100; + return; +} + +static void TaskF01(void const * argument) +{ + UINT32 ret; + UINT32 arg; + UINT32 intSave; + + ICUNIT_GOTO_EQUAL(g_timesliceTestCount, 0, ret, EXIT); + g_timesliceTestCount++; + + ret = LOS_SwtmrCreate(1, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)SwtmrF01, &g_swTmrID, 0xffff); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_SwtmrStart(g_swTmrID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + intSave = LOS_IntLock(); + g_itTimesliceTestCount1 = TestTickCountGet(); + + LOS_IntRestore(intSave); + + while (1) { + dprintf(""); + intSave = LOS_IntLock(); + + if ((g_itTimesliceTestCount1 + LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT) < TestTickCountGet()) { + LOS_IntRestore(intSave); + break; + } + + LOS_IntRestore(intSave); + } + + // 2, assert that result is equal to this. + ICUNIT_GOTO_EQUAL(g_timesliceTestCount, 2, ret, EXIT); + g_timesliceTestCount++; + + // 100, assert that result is equal to this. + if (g_cmsisRobinTestCount2 == 100) { + // 2, set g_cmsisRobinTestCount2 for future Tests. + g_cmsisRobinTestCount2 = 2; + } else { + dprintf("ERROR It_Timeslice_004_f01 g_cmsis_robinTestCount %d\n", g_cmsisRobinTestCount2); + } + + ret = LOS_SwtmrDelete(g_swTmrID); // Los_SwTmrDelete + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + return; + +EXIT: + ret = LOS_SwtmrDelete(g_swTmrID); // Los_SwTmrDelete + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + // 2, set g_cmsisRobinTestCount2 for future Tests. + g_cmsisRobinTestCount2 = 2; + + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + + g_cmsisRobinTestCount2 = 0; + g_itTimesliceTestCount1 = 0; + g_timesliceTestCount = 0; + + LOS_TaskLock(); + TSK_INIT_PARAM_S task; + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task.pcName = "TimesTsk004A"; + // 3, Used to calculate stack space + task.uwStackSize = TASK_STACK_SIZE_TEST * 3; + task.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task.pcName = "TimesTsk004B"; + task.uwStackSize = TASK_STACK_SIZE_TEST; + task.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + ret = LOS_TaskCreate(&g_testTaskID02, &task); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + LOS_TaskUnlock(); + + return LOS_OK; +} + +void ItLosTaskTimeslice004(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTaskTIMESLICE_004", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smoke/It_los_task_045.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smoke/It_los_task_045.c new file mode 100644 index 00000000..6cc62a2e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smoke/It_los_task_045.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void SwtmrF01(UINT32 arg) +{ + UINT32 uwSwTmrTaskID; + UINT32 ret; + + g_testCount++; + + uwSwTmrTaskID = LOS_CurTaskIDGet(); + ret = LOS_TaskSuspend(uwSwTmrTaskID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK, ret); + + ret = LOS_TaskResume(uwSwTmrTaskID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_TSK_NOT_SUSPENDED, ret); + + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + UINT16 swTmrID; + + g_testCount = 0; + // 4, time interval of swtmr. + ret = LOS_SwtmrCreate(4, LOS_SWTMR_MODE_ONCE, SwtmrF01, &swTmrID, 0xffff); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SwtmrStart(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskDelay(100); // 100, set delay time. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + +EXIT: + LOS_SwtmrDelete(swTmrID); + + return LOS_OK; +} + +void ItLosTask045(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask045", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smoke/It_los_task_046.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smoke/It_los_task_046.c new file mode 100644 index 00000000..29167d4a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smoke/It_los_task_046.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(void) +{ + UINT32 ret; + ret = LOS_CurTaskPriSet(-1); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_PRIOR_ERROR, ret); + + ret = LOS_CurTaskPriSet(OS_TASK_PRIORITY_LOWEST + 1); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_PRIOR_ERROR, ret); + return LOS_OK; +} + +void ItLosTask046(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask046", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smoke/It_los_task_049.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smoke/It_los_task_049.c new file mode 100644 index 00000000..f1cb1b56 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smoke/It_los_task_049.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static TSK_INFO_S g_taskInfo; +static UINT16 g_testPrio; +static void TaskF01(void) +{ + UINT32 ret; + + ret = LOS_TaskInfoGet(-1, &g_taskInfo); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_TSK_ID_INVALID, ret, EXIT1); + + ret = LOS_TaskInfoGet(LOSCFG_BASE_CORE_TSK_CONFIG - 1, &g_taskInfo); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_TSK_NOT_CREATED, ret, EXIT1); + + ret = LOS_TaskInfoGet(g_testTaskID01, NULL); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_TSK_PTR_NULL, ret, EXIT1); + + ret = LOS_TaskInfoGet(g_testTaskID01, &g_taskInfo); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + ICUNIT_GOTO_STRING_EQUAL(g_taskInfo.acName, "Tsk049A", g_taskInfo.acName, EXIT1); + ICUNIT_GOTO_EQUAL(g_taskInfo.uwTaskID, g_testTaskID01, g_taskInfo.uwTaskID, EXIT1); + // 2, assert usTaskPrio change. + ICUNIT_GOTO_EQUAL(g_taskInfo.usTaskPrio, g_testPrio - 2, g_taskInfo.usTaskPrio, EXIT1); + ICUNIT_GOTO_EQUAL(OS_TASK_STATUS_RUNNING & g_taskInfo.usTaskStatus, OS_TASK_STATUS_RUNNING, + OS_TASK_STATUS_RUNNING & g_taskInfo.usTaskStatus, EXIT1); + ICUNIT_GOTO_EQUAL(g_taskInfo.uwBottomOfStack, g_taskInfo.uwSP + g_taskInfo.uwCurrUsed, g_taskInfo.uwBottomOfStack, + EXIT1); + + g_testCount++; + return; + +EXIT1: + LOS_TaskDelete(g_testTaskID01); + + return; +} + + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + + g_testPrio = TASK_PRIO_TEST_TASK; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk049A"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = g_testPrio - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + g_testCount = 0; + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_NOK; +} + +void ItLosTask049(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask049", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smoke/It_los_task_081.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smoke/It_los_task_081.c new file mode 100644 index 00000000..d37870f7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smoke/It_los_task_081.c @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + UINT32 semHandle; + volatile UINT64 tick1, tick2; + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + g_testCount++; + + tick1 = TestTickCountGet(); + LOS_TaskDelay(10); // 10, set delay time. + tick2 = TestTickCountGet(); + + // 10, assert that tick2 - tick1 is equal to this. + ICUNIT_ASSERT_EQUAL_TIME((tick2 - tick1), 10, (tick2 - tick1), EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return; +} + +static void TaskF02(void) +{ + UINT32 ret; + UINT32 semHandle; + UINT32 tick1, tick2; + + ret = LOS_SemCreate(0, &semHandle); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, assert that g_testCount is equal to this. + g_testCount++; + + tick1 = TestTickCountGet(); + // 10, Timeout interval of sem. + ret = LOS_SemPend(semHandle, 10); + tick2 = TestTickCountGet(); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_SEM_TIMEOUT, ret, EXIT); + + // 10, assert that tick2 - tick1 is equal to this. + ICUNIT_ASSERT_EQUAL_TIME((tick2 - tick1), 10, (tick2 - tick1), EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); // 5, assert that g_testCount is equal to this. + g_testCount++; + + ret = LOS_SemDelete(semHandle); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + return; +} + + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk081A"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + g_testCount++; + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(10); // 10, set delay time. + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 4, g_testCount); // 4, assert that g_testCount is equal to this. + g_testCount++; + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + // 11, set delay time. + LOS_TaskDelay(11); + ICUNIT_ASSERT_EQUAL(g_testCount, 6, g_testCount); // 6, assert that g_testCount is equal to this. + return LOS_OK; +} + +void ItLosTask081() // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask081", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smoke/It_los_task_089.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smoke/It_los_task_089.c new file mode 100644 index 00000000..333b92c6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smoke/It_los_task_089.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(void) +{ + UINT32 ret; + ret = LOS_TaskYield(); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return LOS_OK; +} + +void ItLosTask089(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask089", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smoke/It_los_task_097.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smoke/It_los_task_097.c new file mode 100644 index 00000000..f7b83b3a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smoke/It_los_task_097.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02(void) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + + g_testCount++; +} + +static void TaskF01(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk097B"; + // 3, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 3; + task1.uwResved = 0; + task1.processID = LOS_GetCurrProcessID(); +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + task1.processID = LOS_GetCurrProcessID(); + + ret = LOS_TaskCreateOnly(&g_testTaskID02, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + ret = LOS_SetTaskScheduler(g_testTaskID02, LOS_SCHED_RR, task1.usTaskPrio); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk097A"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + task1.processID = -1; + g_testCount = 0; + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(10); // 10, set delay time. + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_TSK_NOT_CREATED, ret, EXIT); + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +void ItLosTask097(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask097", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smoke/It_los_task_099.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smoke/It_los_task_099.c new file mode 100644 index 00000000..79459cf6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smoke/It_los_task_099.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + g_testCount++; + LOS_TaskDelete(g_testTaskID01); + + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "TskB099"; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 2; + task1.processID = LOS_GetCurrProcessID(); +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + task1.processID = LOS_GetCurrProcessID(); + + g_testCount = 0; + + LOS_TaskLock(); + + ret = LOS_TaskCreateOnly(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT3); + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT3); + + ret = LOS_SetTaskScheduler(g_testTaskID01, LOS_SCHED_RR, task1.usTaskPrio); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT1); + + LOS_TaskUnlock(); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT2); + + return LOS_OK; + +EXIT1: + LOS_TaskUnlock(); +EXIT2: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +EXIT3: + LOS_TaskUnlock(); + + return LOS_OK; +} + +void ItLosTask099(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask099", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smoke/It_los_task_101.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smoke/It_los_task_101.c new file mode 100644 index 00000000..223c11cb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smoke/It_los_task_101.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_testPrio; +static void TaskF01(void) +{ + UINT32 ret; + + g_testCount++; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + + ret = LOS_TaskPriGet(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, g_testPrio, ret); + + g_testCount++; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testPrio = TASK_PRIO_TEST_TASK - 1; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk101A"; + task1.usTaskPrio = g_testPrio; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + ret = LOS_TaskPriGet(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, (UINT16)OS_INVALID, ret); + + ret = LOS_TaskPriGet(g_taskMaxNum + 1); + ICUNIT_GOTO_EQUAL(ret, (UINT16)OS_INVALID, ret, EXIT); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + + LOS_TaskDelay(10); // 10, set delay time. + + ret = LOS_TaskPriGet(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, (UINT16)OS_INVALID, ret); + + return LOS_OK; +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +void ItLosTask101(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask101", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smoke/It_los_task_105.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smoke/It_los_task_105.c new file mode 100644 index 00000000..55932c80 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smoke/It_los_task_105.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + g_testCount++; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + + ret = LOS_TaskPriGet(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, TASK_PRIO_TEST_TASK - 1, ret); + + ret = LOS_TaskPriSet(g_testTaskID01, TASK_PRIO_TEST_TASK + 1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "Tsk105A"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + ret = LOS_TaskPriSet(g_testTaskID01, TASK_PRIO_TEST_TASK - 1); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_NOT_CREATED, ret); + + ret = LOS_TaskPriSet(OsGetIdleTaskId(), TASK_PRIO_TEST_TASK - 1); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK, ret); + + ret = LOS_TaskPriSet(g_taskMaxNum + 1, TASK_PRIO_TEST_TASK - 1); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_ID_INVALID, ret); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + ret = LOS_TaskPriSet(g_testTaskID01, OS_TASK_PRIORITY_LOWEST + 1); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_PRIOR_ERROR, ret); + + LOS_TaskDelay(10); // 10, set delay time. + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + + ret = LOS_TaskPriSet(g_testTaskID01, TASK_PRIO_TEST_TASK - 1); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_NOT_CREATED, ret); + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + return LOS_OK; +} + +void ItLosTask105(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTask105", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smoke/It_los_task_timeslice_001.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smoke/It_los_task_timeslice_001.c new file mode 100644 index 00000000..b5100a99 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smoke/It_los_task_timeslice_001.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02(void const * argument) +{ + g_timesliceTestCount++; +} + +static void TaskF01(void const * argument) +{ + UINT32 ret; + UINT32 intSave; + + g_itTimesliceTestCount1 = TestTickCountGet(); + + while (1) { + dprintf(""); + // 15000, It is used to calculate g_itTimesliceTestCount1. + if ((g_itTimesliceTestCount1 + 15000) < TestTickCountGet()) { + break; + } + } + ICUNIT_GOTO_EQUAL(g_timesliceTestCount, 1, ret, EXIT); + +EXIT:; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + g_itTimesliceTestCount1 = 0; + g_timesliceTestCount = 0; + LOS_TaskLock(); + TSK_INIT_PARAM_S task = { 0 }; + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task.pcName = "TimesTsk001A"; + // 2, It is used to calculate uwStackSize. + task.uwStackSize = TASK_STACK_SIZE_TEST * 2; + task.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task.pcName = "TimesTsk001B"; + task.uwStackSize = TASK_STACK_SIZE_TEST; + task.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + ret = LOS_TaskCreate(&g_testTaskID02, &task); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskUnlock(); + + LOS_TaskDelay(5); // 5, set delay time. + LOS_TaskDelete(g_testTaskID02); + LOS_TaskDelete(g_testTaskID01); + return LOS_OK; +} + +void ItLosTaskTimeslice001(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosTaskTIMESLICE_001", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_001.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_001.c new file mode 100644 index 00000000..dae3e1d3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_001.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static SPIN_LOCK_INIT(g_TestSpin); + +static void TaskF01(void) +{ + UINT32 puvIntSave; + + LOS_SpinLockSave(&g_TestSpin, &puvIntSave); + g_testCount |= 1 << ArchCurrCpuid(); + Dmb(); + LOS_SpinUnlockRestore(&g_TestSpin, puvIntSave); +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret; + UINT32 testid; + UINT32 coreIdx = 0; + + g_testCount = 0; + + while (coreIdx < LOSCFG_KERNEL_CORE_NUM) { + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_smp_task_001", TaskF01, TASK_PRIO_TEST_TASK + 1, + CPUID_TO_AFFI_MASK(coreIdx)); + ret = LOS_TaskCreate(&testid, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + coreIdx++; + } + + LOS_TaskDelay(5); // 5, set delay time. + + ICUNIT_ASSERT_EQUAL(g_testCount, LOSCFG_KERNEL_CPU_MASK, g_testCount); + + return LOS_OK; +} + +void ItSmpLosTask001(void) +{ + TEST_ADD_CASE("ItSmpLosTask001", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_002.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_002.c new file mode 100644 index 00000000..b7ae2ae4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_002.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + while (1) { + WFI; + }; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, currCpuid; + UINT32 testid = 0xff; + + /* make sure that created test task is definitely on another core */ + currCpuid = (ArchCurrCpuid() + 1) % LOSCFG_KERNEL_CORE_NUM; + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_smp_task_002", TaskF01, OS_TASK_PRIORITY_LOWEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); + + ret = LOS_TaskCreate(&testid, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(2); // 2, set delay time. + ret = LOS_TaskDelete(testid); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +#ifndef LOSCFG_KERNEL_SMP_TASK_SYNC + /* delay and check */ + LOS_TaskDelay(10); // 10, set delay time. +#endif + ret = LOS_TaskDelete(testid); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_NOT_CREATED, ret); + + return LOS_OK; +} + +void ItSmpLosTask002(void) +{ + TEST_ADD_CASE("ItSmpLosTask002", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_003.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_003.c new file mode 100644 index 00000000..af402953 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_003.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + while (1) { + WFI; + }; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, currCpuid; + UINT32 testid = 0xff; + + /* make sure that created test task is definitely on another core */ + currCpuid = (ArchCurrCpuid() + 1) % LOSCFG_KERNEL_CORE_NUM; + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_smp_task_003", TaskF01, OS_TASK_PRIORITY_LOWEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); + + ret = LOS_TaskCreate(&testid, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(2); // 2, set delay time. + ret = LOS_TaskSuspend(testid); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + /* delay and check */ + LOS_TaskDelay(100); // 10, set delay time. + + ret = OS_TCB_FROM_TID(testid)->taskStatus; + ICUNIT_GOTO_EQUAL(ret & OS_TASK_STATUS_SUSPEND, OS_TASK_STATUS_SUSPEND, ret, EXIT); + + LOS_TaskResume(testid); + +EXIT: + LOS_TaskDelay(2); // 2, set delay time. + LOS_TaskDelete(testid); + + return LOS_OK; +} + +void ItSmpLosTask003(void) +{ + TEST_ADD_CASE("ItSmpLosTask003", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_004.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_004.c new file mode 100644 index 00000000..f1ed6a5b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_004.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + g_testCount++; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + + g_testCount = 0; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + TEST_TASK_PARAM_INIT_AFFI(task1, "it_smp_task_004", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 2, 0); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + while (g_testCount == 0) { + } + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + return LOS_OK; + +EXIT: + + return LOS_OK; +} + +void ItSmpLosTask004(void) +{ + TEST_ADD_CASE("ItSmpLosTask004", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_021.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_021.c new file mode 100644 index 00000000..c3133c34 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_021.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" +#include "los_atomic.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + LOS_AtomicInc(&g_testCount); + while (1) { + } +} + +static void TaskF02Preempt(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + UINT32 testTaskIDSmp[LOSCFG_KERNEL_CORE_NUM]; + + g_testCount = 0; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + TEST_TASK_PARAM_INIT(task1, "it_smp_task_021", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK + 2); + int i; + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + /* take control of every cores */ + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(i); + ret = LOS_TaskCreate(&testTaskIDSmp[i], &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + /* give up this core to task_f01 of this core */ + LOS_TaskDelay(10); // 10, set delay time. + + /* take this core back to control, create an unbinded task */ + ICUNIT_ASSERT_EQUAL(g_testCount, LOSCFG_KERNEL_CORE_NUM, g_testCount); + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02Preempt; + task1.usTaskPrio = TASK_PRIO_TEST_TASK + 1; + task1.usCpuAffiMask = 0; + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + + LOS_TaskDelay(10); // 10, set delay time. + + /* take this core back to control */ + ICUNIT_ASSERT_EQUAL(g_testCount, LOSCFG_KERNEL_CORE_NUM + 1, g_testCount); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + ret = LOS_TaskDelete(testTaskIDSmp[i]); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + return LOS_OK; +} + +void ItSmpLosTask021(void) +{ + TEST_ADD_CASE("ItSmpLosTask021", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_022.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_022.c new file mode 100644 index 00000000..888f0a47 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_022.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" +#include "los_atomic.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + LOS_AtomicInc(&g_testCount); + while (1) { + } +} + +static void TaskF02Preempt(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + UINT32 testTaskIDSmp[LOSCFG_KERNEL_CORE_NUM]; + + g_testCount = 0; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + TEST_TASK_PARAM_INIT(task1, "it_smp_task_022", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK + 2); + int i; + for (i = 1; i < LOSCFG_KERNEL_CORE_NUM; i++) { + /* take control of every cores except this one */ + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(i); + ret = LOS_TaskCreate(&testTaskIDSmp[i], &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + + /* wait task_f01 to run */ + LOS_TaskDelay(10); // 10, set delay time. + + ICUNIT_GOTO_EQUAL(g_testCount, LOSCFG_KERNEL_CORE_NUM - 1, g_testCount, EXIT); + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02Preempt; + task1.usTaskPrio = TASK_PRIO_TEST_TASK + 1; + task1.usCpuAffiMask = 0; + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + /* give up this core to task_f02 */ + LOS_TaskDelay(10); // 10, set delay time. + + /* take this core back to control */ + ICUNIT_GOTO_EQUAL(g_testCount, LOSCFG_KERNEL_CORE_NUM, g_testCount, EXIT); + + for (i = 1; i < LOSCFG_KERNEL_CORE_NUM; i++) { + ret = LOS_TaskDelete(testTaskIDSmp[i]); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + + return LOS_OK; +EXIT: + for (i = 1; i < LOSCFG_KERNEL_CORE_NUM; i++) { + LOS_TaskDelete(testTaskIDSmp[i]); + } + + return LOS_NOK; +} + +void ItSmpLosTask022(void) +{ + TEST_ADD_CASE("ItSmpLosTask022", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_023.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_023.c new file mode 100644 index 00000000..36434693 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_023.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + LOS_AtomicInc(&g_testCount); + + /* delay for a long time */ + LOS_TaskDelay(1000); // 1000, set delay time. +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, currCpuid; + UINT32 testid = 0xff; + g_testCount = 0; + + /* make sure that created test task is definitely on another core */ + currCpuid = (ArchCurrCpuid() + 1) % LOSCFG_KERNEL_CORE_NUM; + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_smp_task_003", TaskF01, OS_TASK_PRIORITY_LOWEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); + + ret = LOS_TaskCreate(&testid, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + /* Wait TaskF01 to start */ + TestAssertBusyTaskDelay(100, 1); // 100, Set the timeout of runtime; 1, test running count + TestBusyTaskDelay(2); // 2, set delay time + + ret = OS_TCB_FROM_TID(testid)->taskStatus; + ICUNIT_GOTO_EQUAL(ret & OS_TASK_STATUS_DELAY, OS_TASK_STATUS_DELAY, ret, EXIT); + + LOS_TaskSuspend(testid); + + /* delay and check */ + LOS_TaskDelay(2); // 2, set delay time. + + ret = OS_TCB_FROM_TID(testid)->taskStatus; + ICUNIT_GOTO_EQUAL(ret & OS_TASK_STATUS_SUSPEND, OS_TASK_STATUS_SUSPEND, ret, EXIT); + + LOS_TaskResume(testid); + +EXIT: + LOS_TaskDelay(2); // 2, set delay time. + LOS_TaskDelete(testid); + + return LOS_OK; +} + +void ItSmpLosTask023(void) +{ + TEST_ADD_CASE("ItSmpLosTask023", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_024.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_024.c new file mode 100644 index 00000000..7ed3dcd4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_024.c @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_itTestTaskID01; +static UINT32 g_itTestTaskID02; +static volatile int g_itTimesliceTestCount = 0; +static volatile UINT32 g_itTestResult = LOS_OK; + +static UINT32 ItTimeslice001F02(void const * argument) +{ + g_itTimesliceTestCount++; + return LOS_OK; +} + +static UINT32 ItTimeslice001F01(void const * argument) +{ + UINT64 timesliceCount; + + // 2, 1000, Used to calculate timesliceCount. + timesliceCount = TestTickCountGet() + (LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT / 1000) * 2; + + while (1) { + if (timesliceCount <= TestTickCountGet()) { // modify + break; + } + } + if (1 != g_itTimesliceTestCount) { + g_itTestResult = LOS_NOK; + } + return LOS_OK; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + UINT32 currCpuid; + TSK_INIT_PARAM_S task; + + g_itTimesliceTestCount = 0; + g_itTestResult = LOS_OK; + + LOS_TaskLock(); +#ifdef LOSCFG_KERNEL_SMP + currCpuid = (ArchCurrCpuid() + 1) % LOSCFG_KERNEL_CORE_NUM; +#endif + + ret = memset_s(&task, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + task.pfnTaskEntry = (TSK_ENTRY_FUNC)ItTimeslice001F01; + task.usTaskPrio = TASK_PRIO_TEST_TASK + 1; + task.pcName = "it_timeslice_001_f01"; + task.uwStackSize = LOS_TASK_MIN_STACK_SIZE; + task.uwResved = LOS_TASK_STATUS_DETACHED; + task.processID = LOS_GetCurrProcessID(); + + ret = LOS_TaskCreateOnly(&g_itTestTaskID01, &task); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + LOS_TaskCpuAffiSet(g_itTestTaskID01, CPUID_TO_AFFI_MASK(currCpuid)); + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)ItTimeslice001F02; + task.usTaskPrio = TASK_PRIO_TEST_TASK + 1; + task.pcName = "it_timeslice_001_f02"; + task.uwStackSize = LOS_TASK_MIN_STACK_SIZE; + task.uwResved = LOS_TASK_STATUS_DETACHED; + task.processID = LOS_GetCurrProcessID(); + + ret = LOS_TaskCreateOnly(&g_itTestTaskID02, &task); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + LOS_TaskCpuAffiSet(g_itTestTaskID02, CPUID_TO_AFFI_MASK(currCpuid)); + + ret = LOS_SetTaskScheduler(g_itTestTaskID01, LOS_SCHED_RR, task.usTaskPrio); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ret = LOS_SetTaskScheduler(g_itTestTaskID02, LOS_SCHED_RR, task.usTaskPrio); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_TaskUnlock(); + // 10, Used to calculate delay time. + LOS_TaskDelay(LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT * 10); + + ICUNIT_ASSERT_EQUAL(g_itTestResult, LOS_OK, g_itTestResult); + return LOS_OK; +EXIT: + LOS_TaskUnlock(); + return LOS_NOK; +} + +void ItSmpLosTask024(void) +{ + TEST_ADD_CASE("ItSmpLosTask024", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_025.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_025.c new file mode 100644 index 00000000..4c6909e2 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_025.c @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_itTestTaskID01; +static UINT32 g_itTestTaskID02; +static volatile UINT32 g_itTestResult = LOS_OK; +static EVENT_CB_S g_eventCb01; + +static UINT32 ItTimeslice002F02(void const * argument) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_TaskYield(); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + return LOS_OK; +} + +static UINT32 ItTimeslice002F01(void const * argument) +{ + UINT64 timesliceCount; + UINT32 ret; + + ret = LOS_SetTaskScheduler(g_itTestTaskID02, LOS_SCHED_RR, LOS_TaskPriGet(g_itTestTaskID02)); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + /* Wait TaskF01 to yield, then testTask timeslice is LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT */ + while (g_testCount != 1) { + } + + timesliceCount = TestTickCountByCurrCpuid() + LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT - 1; + + /* Task will not scheduled in timeslice - 1 */ + while (1) { + if (timesliceCount <= TestTickCountByCurrCpuid) { + break; + } + } + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + +EXIT: + ret = LOS_EventWrite(&g_eventCb01, 0x11); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + UINT32 currCpuid; + TSK_INIT_PARAM_S task; + LOS_EventInit(&g_eventCb01); + + g_testCount = 0; + g_itTestResult = LOS_NOK; + + LOS_TaskLock(); +#ifdef LOSCFG_KERNEL_SMP + currCpuid = (ArchCurrCpuid() + 1) % LOSCFG_KERNEL_CORE_NUM; +#endif + + ret = memset_s(&task, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + task.pfnTaskEntry = (TSK_ENTRY_FUNC)ItTimeslice002F01; + task.usTaskPrio = TASK_PRIO_TEST_TASK + 1; + task.pcName = "it_timeslice_002_f01"; + task.uwStackSize = LOS_TASK_MIN_STACK_SIZE; + task.uwResved = LOS_TASK_STATUS_DETACHED; + task.processID = LOS_GetCurrProcessID(); + + ret = LOS_TaskCreateOnly(&g_itTestTaskID01, &task); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + LOS_TaskCpuAffiSet(g_itTestTaskID01, CPUID_TO_AFFI_MASK(currCpuid)); + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)ItTimeslice002F02; + task.usTaskPrio = TASK_PRIO_TEST_TASK + 1; + task.pcName = "it_timeslice_002_f02"; + task.uwStackSize = LOS_TASK_MIN_STACK_SIZE; + task.uwResved = LOS_TASK_STATUS_DETACHED; + task.processID = LOS_GetCurrProcessID(); + + ret = LOS_TaskCreateOnly(&g_itTestTaskID02, &task); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + LOS_TaskCpuAffiSet(g_itTestTaskID02, CPUID_TO_AFFI_MASK(currCpuid)); + + ret = LOS_SetTaskScheduler(g_itTestTaskID01, LOS_SCHED_RR, task.usTaskPrio); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_TaskUnlock(); + + ret = LOS_EventRead(&g_eventCb01, 0x11, LOS_WAITMODE_OR | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, 0x11, ret, EXIT); + + ret = LOS_EventDestroy(&g_eventCb01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + return LOS_OK; + +EXIT: + LOS_EventDestroy(&g_eventCb01); + LOS_TaskDelete(g_itTestTaskID01); + LOS_TaskDelete(g_itTestTaskID02); + return LOS_NOK; +} + +void ItSmpLosTask025(void) +{ + TEST_ADD_CASE("ItSmpLosTask025", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_026.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_026.c new file mode 100644 index 00000000..6716c6ab --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_026.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_atomic.h" +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + LOS_AtomicInc(&g_testCount); + while (1) { + WFI; + } +} + +static void TaskF02(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, currCpuid; + UINT32 testid[2]; + + g_testCount = 0; + + currCpuid = (ArchCurrCpuid() + 1) % LOSCFG_KERNEL_CORE_NUM; + + // 3, It is used to calculate a priority relative to OS_TASK_PRIORITY_LOWEST. + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_smp_task_026_f01", TaskF01, OS_TASK_PRIORITY_LOWEST - 3, + CPUID_TO_AFFI_MASK(currCpuid)); + ret = LOS_TaskCreate(&testid[0], &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + // 2, It is used to calculate a priority relative to OS_TASK_PRIORITY_LOWEST. + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_smp_task_026_f02", TaskF02, OS_TASK_PRIORITY_LOWEST - 2, + CPUID_TO_AFFI_MASK(currCpuid)); + ret = LOS_TaskCreate(&testid[1], &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + /* Wait TaskF1 to start */ + TestAssertBusyTaskDelay(100, 1); // 100, Set the timeout of runtime; 1, test running count + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + /* lower down the priority of TaskF01 to trigger preeption */ + LOS_TaskPriSet(testid[0], OS_TASK_PRIORITY_LOWEST - 1); + + LOS_TaskDelay(5); // 5, set delay time. + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + +EXIT: + LOS_TaskDelete(testid[0]); + LOS_TaskDelete(testid[1]); + + return LOS_OK; +} + +void ItSmpLosTask026(void) +{ + TEST_ADD_CASE("ItSmpLosTask026", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_027.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_027.c new file mode 100644 index 00000000..f9531987 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_027.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_atomic.h" +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_testid, g_cpuid; + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + /* loop for 15 ticks */ + LOS_TaskDelay(15); // 15, set delay time + + ret = OS_TCB_FROM_TID(g_testid)->currCpu; + ICUNIT_ASSERT_EQUAL_VOID(ret, g_cpuid, ret); + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret, currCpuid; + + g_testCount = 0; + + currCpuid = ArchCurrCpuid(); + /* make sure that created test task is definitely on another core */ + g_cpuid = (currCpuid + 1) % LOSCFG_KERNEL_CORE_NUM; + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_smp_task_027_f01", TaskF01, TASK_PRIO_TEST_TASK - 1, + CPUID_TO_AFFI_MASK(currCpuid)); + ret = LOS_TaskCreate(&g_testid, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + /* loop for 2 ticks */ + TestBusyTaskDelay(2); // 2, set delay time + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + /* set the affinity of test task */ + LOS_TaskCpuAffiSet(g_testid, CPUID_TO_AFFI_MASK(g_cpuid)); + + /* loop for 20 ticks */ + TestBusyTaskDelay(20); // 20, set delay time + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + +EXIT: + LOS_TaskDelete(g_testid); + + return LOS_OK; +} + +void ItSmpLosTask027(void) +{ + TEST_ADD_CASE("ItSmpLosTask027", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_028.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_028.c new file mode 100644 index 00000000..7739a515 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_028.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_testTaskIdsmp[LOSCFG_KERNEL_CORE_NUM]; +static int g_runCpu[LOSCFG_KERNEL_CORE_NUM]; +static void TaskF01(UINT32 i) +{ + g_runCpu[i] = OS_TCB_FROM_TID(g_testTaskIdsmp[i])->currCpu; + while (1) { + } +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + UINT32 gBitmap; + TSK_INIT_PARAM_S task1 = { 0 }; + int i; + + g_testCount = 0; + gBitmap = LOSCFG_KERNEL_CPU_MASK; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_028", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK + 1); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + g_runCpu[i] = 3; // 3, It is used to calculate runcpu id. + /* take control of every cores */ + task1.usTaskPrio = TASK_PRIO_TEST_TASK + i + 1; + task1.usCpuAffiMask = 0; + task1.auwArgs[0] = i; + ret = LOS_TaskCreate(&g_testTaskIdsmp[i], &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + TestBusyTaskDelay(10); // 10, set delay time + + /* Calculate the field on the other core */ + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + ret = g_runCpu[i]; + g_testCount |= (0x1 << ret); + ret = LOS_TaskDelete(g_testTaskIdsmp[i]); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + /* Calculate the field on the current core */ + ret = ArchCurrCpuid(); + g_testCount |= (0x1 << ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, gBitmap, g_testCount); + + return LOS_OK; + +EXIT: + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + LOS_TaskDelete(g_testTaskIdsmp[i]); + } +} + +void ItSmpLosTask028(void) +{ + TEST_ADD_CASE("ItSmpLosTask028", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_029.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_029.c new file mode 100644 index 00000000..cbf2573b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_029.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + while (1) { + } +} + +static void TaskF02(void) +{ + LOS_AtomicInc(&g_testCount2); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + UINT32 bitmap; + TSK_INIT_PARAM_S task1 = { 0 }; + UINT32 testTaskIDSmp[LOSCFG_KERNEL_CORE_NUM + 1]; + + g_testCount = 0; + bitmap = LOSCFG_KERNEL_CPU_MASK; + g_testCount2 = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_029", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK + 1); + int i; + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + /* take control of every cores */ + task1.usTaskPrio = TASK_PRIO_TEST_TASK + i + 1; + task1.usCpuAffiMask = 0; + ret = LOS_TaskCreate(&testTaskIDSmp[i], &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + + TestBusyTaskDelay(2); // 2, set delay time + + for (i = LOSCFG_KERNEL_CORE_NUM - 1; i < LOSCFG_KERNEL_CORE_NUM + 1; i++) { + /* take control of every cores */ + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.usCpuAffiMask = 0; + ret = LOS_TaskCreate(&testTaskIDSmp[i], &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + + TestBusyTaskDelay(2); // 2, set delay time + + /* Calculate the field on the other core */ + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + ret = OS_TCB_FROM_TID(testTaskIDSmp[i])->currCpu; + g_testCount |= (0x1 << ret); + ret = LOS_TaskDelete(testTaskIDSmp[i]); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + + /* Calculate the field on the current core */ + ret = ArchCurrCpuid(); + g_testCount |= (0x1 << ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, bitmap, g_testCount); + ICUNIT_ASSERT_EQUAL(g_testCount2, 2, g_testCount2); // 2, assert that g_testCount2 is equal to this. + + return LOS_OK; + +EXIT: + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM + 1; i++) { + LOS_TaskDelete(testTaskIDSmp[i]); + } +} + +void ItSmpLosTask029(void) +{ + TEST_ADD_CASE("ItSmpLosTask029", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_030.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_030.c new file mode 100644 index 00000000..0cca36c5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_030.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_testTaskIdsmp[LOSCFG_KERNEL_CORE_NUM + 2]; +static int g_runCpu[LOSCFG_KERNEL_CORE_NUM]; +static void TaskF01(UINT32 i) +{ + g_runCpu[i] = OS_TCB_FROM_TID(g_testTaskIdsmp[i])->currCpu; + while (1) { + } +} + +static void TaskF02(void) +{ + LOS_AtomicInc(&g_testCount2); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + UINT32 gBitmap; + TSK_INIT_PARAM_S task1 = { 0 }; + + g_testCount = 0; + gBitmap = 0; + g_testCount2 = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_030", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK + 1); + int i; + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + // 3, It is used to calculate runcpu id. + g_runCpu[i] = 3; + task1.usTaskPrio = TASK_PRIO_TEST_TASK + i + 1; + task1.usCpuAffiMask = 0; + task1.auwArgs[0] = i; + ret = LOS_TaskCreate(&g_testTaskIdsmp[i], &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + TestBusyTaskDelay(2); // 2, set delay time + // 2, It is used to calculate number of cycles + for (i = LOSCFG_KERNEL_CORE_NUM - 1; i < LOSCFG_KERNEL_CORE_NUM + 2; i++) { + /* take control of every cores */ + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.usCpuAffiMask = 0; + ret = LOS_TaskCreate(&g_testTaskIdsmp[i], &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + TestBusyTaskDelay(2); // 2, set delay time + + /* Calculate the field on the other core */ + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + ret = g_runCpu[i]; + g_testCount |= (0x1 << ret); + gBitmap |= (0x1 << i); + + ret = LOS_TaskDelete(g_testTaskIdsmp[i]); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + /* Calculate the field on the current core */ + ret = ArchCurrCpuid(); + g_testCount |= (0x1 << ret); + gBitmap |= (0x1 << (LOSCFG_KERNEL_CORE_NUM - 1)); + + ICUNIT_ASSERT_EQUAL(g_testCount, gBitmap, g_testCount); + ICUNIT_ASSERT_EQUAL(g_testCount2, 3, g_testCount2); // 3, assert that g_testCount2 is equal to this. + + return LOS_OK; + +EXIT: + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM + 1; i++) { + LOS_TaskDelete(g_testTaskIdsmp[i]); + } +} + +void ItSmpLosTask030(void) +{ + TEST_ADD_CASE("ItSmpLosTask030", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_032.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_032.c new file mode 100644 index 00000000..a138c42c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_032.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + LOS_AtomicInc(&g_testCount); + while (1) { + } +} + +static UINT32 Testcase(void) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S task1 = { 0 }; + int i; + + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_032", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK); + + /* make sure that created test task is definitely on another core */ + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(currCpuid); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + /* wait for task_f01 to start */ + TestBusyTaskDelay(10); // 10, set delay time + + /* take this core back to control */ + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_EQUAL(ret, OS_TASK_STATUS_RUNNING | OS_TASK_STATUS_DETACHED, ret, EXIT); + + ret = LOS_TaskDelete(g_testTaskID01); + + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + + LOS_TaskDelete(g_testTaskID01); + return LOS_NOK; +} + +void ItSmpLosTask032(void) +{ + TEST_ADD_CASE("ItSmpLosTask032", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_033.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_033.c new file mode 100644 index 00000000..425b88bc --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_033.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + LOS_AtomicInc(&g_testCount); + while (1) { + } +} + +static void TaskF02Preempt(void) +{ + LOS_AtomicInc(&g_testCount); + while (1) { + } +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + UINT32 testTaskIDSmp[LOSCFG_KERNEL_CORE_NUM]; + + g_testCount = 0; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + TEST_TASK_PARAM_INIT(task1, "it_smp_task_033", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK + 2); + int i; + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + /* take control of every cores */ + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK + 2 + i; + task1.usCpuAffiMask = 0; + ret = LOS_TaskCreate(&testTaskIDSmp[i], &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + + TestBusyTaskDelay(2); // 2, set delay time + task1.usTaskPrio = TASK_PRIO_TEST_TASK + 1; + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + /* wait for task to schedule */ + TestBusyTaskDelay(10); // 10, set delay time + + /* take this core back to control */ + ICUNIT_GOTO_EQUAL(g_testCount, LOSCFG_KERNEL_CORE_NUM - 1 + 1, g_testCount, EXIT); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_EQUAL(ret, OS_TASK_STATUS_RUNNING | OS_TASK_STATUS_DETACHED, ret, EXIT); + + // 2, It is used to calculate number of cycles + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 2; i++) { + ret = OS_TCB_FROM_TID(testTaskIDSmp[i])->taskStatus; + ICUNIT_GOTO_EQUAL(ret, OS_TASK_STATUS_RUNNING | OS_TASK_STATUS_DETACHED, ret, EXIT); + } + // 2, It is used to calculate number of cycles + ret = OS_TCB_FROM_TID(testTaskIDSmp[LOSCFG_KERNEL_CORE_NUM - 2])->taskStatus; + ICUNIT_GOTO_EQUAL(ret, OS_TASK_STATUS_READY | OS_TASK_STATUS_DETACHED, ret, EXIT); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + ret = LOS_TaskDelete(testTaskIDSmp[i]); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, LOSCFG_KERNEL_CORE_NUM, g_testCount); + + return LOS_OK; + +EXIT: + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + LOS_TaskDelete(testTaskIDSmp[i]); + } + LOS_TaskDelete(g_testTaskID01); + + return LOS_NOK; +} + +void ItSmpLosTask033(void) +{ + TEST_ADD_CASE("ItSmpLosTask033", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_034.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_034.c new file mode 100644 index 00000000..5ed73c92 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_034.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + LOS_AtomicInc(&g_testCount); + while (1) { + } +} + +static void TaskF02Preempt(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + UINT32 testTaskIDSmp[LOSCFG_KERNEL_CORE_NUM]; + + g_testCount = 0; + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + TEST_TASK_PARAM_INIT(task1, "it_smp_task_034", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK + 2); + int i; + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + /* take control of every cores */ + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + task1.usTaskPrio = TASK_PRIO_TEST_TASK + 2 + i; + task1.usCpuAffiMask = 0; + ret = LOS_TaskCreate(&testTaskIDSmp[i], &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02Preempt; + task1.usTaskPrio = TASK_PRIO_TEST_TASK + 1; + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret + 1, LOS_OK + 1, ret, EXIT); + + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + /* wait for task to schedule */ + TestBusyTaskDelay(10); // 10, set delay time + + /* take this core back to control */ + ICUNIT_GOTO_EQUAL(g_testCount, LOSCFG_KERNEL_CORE_NUM + 1, g_testCount, EXIT); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + ret = LOS_TaskDelete(testTaskIDSmp[i]); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + + return LOS_OK; + +EXIT: + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + LOS_TaskDelete(testTaskIDSmp[i]); + } + + return LOS_NOK; +} + +void ItSmpLosTask034(void) +{ + TEST_ADD_CASE("ItSmpLosTask034", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_035.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_035.c new file mode 100644 index 00000000..ccbe59ff --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_035.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02Preempt(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + UINT32 testTaskIDSmp[LOSCFG_KERNEL_CORE_NUM]; + + g_testCount = 0; + TEST_TASK_PARAM_INIT(task1, "it_smp_task_035", (TSK_ENTRY_FUNC)TaskF02Preempt, TASK_PRIO_TEST_TASK - 1); + + /* create preempt task */ + task1.usCpuAffiMask = 0; + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + /* wait for task to schedule */ + TestBusyTaskDelay(2); // 2, set delay time + + /* take this core back to control */ + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + return LOS_OK; +} + +void ItSmpLosTask035(void) +{ + TEST_ADD_CASE("ItSmpLosTask035", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_036.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_036.c new file mode 100644 index 00000000..c2f1c956 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_036.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + LOS_AtomicInc(&g_testCount); + while (1) { + } +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + UINT32 testTaskIDSmp[LOSCFG_KERNEL_CORE_NUM + 1]; + int i; + + g_testCount = 0; + TEST_TASK_PARAM_INIT(task1, "it_smp_task_036", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK); + + task1.usCpuAffiMask = 0; + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + /* take control of every cores */ + task1.usTaskPrio = TASK_PRIO_TEST_TASK; + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + i + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&testTaskIDSmp[i], &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + /* wait for task to start */ + TestBusyTaskDelay(10); // 10, set delay time + + /* take this core back to control */ + ICUNIT_GOTO_EQUAL(g_testCount, LOSCFG_KERNEL_CORE_NUM - 1, g_testCount, EXIT); + + /* check task status on other cores */ + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + ret = OS_TCB_FROM_TID(testTaskIDSmp[i])->taskStatus; + ICUNIT_GOTO_EQUAL(ret, OS_TASK_STATUS_RUNNING | OS_TASK_STATUS_DETACHED, ret, EXIT); + } + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + ret = LOS_TaskDelete(testTaskIDSmp[i]); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + + return LOS_OK; + +EXIT: + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + LOS_TaskDelete(testTaskIDSmp[i]); + } + + return LOS_NOK; +} + +void ItSmpLosTask036(void) +{ + TEST_ADD_CASE("ItSmpLosTask036", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_037.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_037.c new file mode 100644 index 00000000..2425e039 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_037.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static volatile UINT32 g_itTestResult = LOS_NOK; +static volatile int g_flag = 0; + +static void TaskF02(void const * argument) +{ + LOS_AtomicInc(&g_testCount); + while (1) { + } +} + +static void TaskF01(void const * argument) +{ + UINT64 timesliceCount; + + LOS_AtomicInc(&g_testCount); + // 5, 1000, Used to calculate timesliceCount. + timesliceCount = TestTickCountGet() + (LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT / 1000) * 5; + + while (1) { + if (timesliceCount <= TestTickCountGet()) { + break; + } + } + if (g_testCount == LOSCFG_KERNEL_CORE_NUM) { + g_itTestResult = LOS_OK; + g_flag = 1; + } +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + UINT32 testTaskIDSmp[LOSCFG_KERNEL_CORE_NUM]; + const CHAR *taskAll = "-a"; + + g_testCount = 0; + TEST_TASK_PARAM_INIT(task1, "it_smp_task_037", (TSK_ENTRY_FUNC)TaskF02, TASK_PRIO_TEST_TASK); + int i; + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + /* take control of every cores */ + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + i + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&testTaskIDSmp[i], &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + TestBusyTaskDelay(2); // 2, set delay time + /* check if every core's task is running */ + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + OsShellCmdDumpTask(1, &taskAll); + do { + ret = OS_TCB_FROM_TID(testTaskIDSmp[i])->taskStatus; + } while (ret & OS_TASK_STATUS_READY); + + ICUNIT_GOTO_EQUAL(ret, OS_TASK_STATUS_RUNNING | OS_TASK_STATUS_DETACHED, ret, EXIT); + } + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.usCpuAffiMask = 0; + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + /* wait for task01 is finished */ + while (g_flag != 1) { + } + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + ret = LOS_TaskDelete(testTaskIDSmp[i]); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + + return g_itTestResult; + +EXIT: + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + LOS_TaskDelete(testTaskIDSmp[i]); + } + + return LOS_NOK; +} + +void ItSmpLosTask037(void) +{ + TEST_ADD_CASE("ItSmpLosTask037", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_040.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_040.c new file mode 100644 index 00000000..1b5ecc8e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_040.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static volatile UINT32 g_itTestResult = LOS_NOK; + +static void TaskF01(void const * argument) +{ + LOS_AtomicInc(&g_testCount); + while (1) { + } +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + UINT32 testTaskIDSmp[LOSCFG_KERNEL_CORE_NUM]; + + g_testCount = 0; + TEST_TASK_PARAM_INIT(task1, "it_smp_task_040", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK + 1); + int i; + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + /* take control of every cores */ + task1.pfnTaskEntry = TaskF01; + ret = LOS_TaskCreate(&testTaskIDSmp[i], &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + /* wait for task to yield */ + TestBusyTaskDelay(LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT * 2); // 2, used to calculate delay time + + ICUNIT_GOTO_EQUAL(g_testCount, LOSCFG_KERNEL_CORE_NUM, g_testCount, EXIT); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + ret = LOS_TaskDelete(testTaskIDSmp[i]); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + return LOS_OK; + +EXIT: + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + ret = LOS_TaskDelete(testTaskIDSmp[i]); + } + return LOS_NOK; +} + +void ItSmpLosTask040(void) +{ + TEST_ADD_CASE("ItSmpLosTask040", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_042.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_042.c new file mode 100644 index 00000000..0933d379 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_042.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static volatile UINT32 g_itTestResult = LOS_NOK; + +static void TaskF01(void const * argument) +{ + LOS_AtomicInc(&g_testCount); + while (1) { + } +} + +static void TaskF02(void const * argument) +{ + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + UINT32 testTaskIDSmp[LOSCFG_KERNEL_CORE_NUM]; + + g_testCount = 0; + TEST_TASK_PARAM_INIT(task1, "it_smp_task_042", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK); + int i; + + /* create high prio task on every cores */ + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + /* take control of every cores */ + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + i + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&testTaskIDSmp[i], &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + TestBusyTaskDelay(2); // 2, set delay time + /* check every cores are running test task */ + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + ret = OS_TCB_FROM_TID(testTaskIDSmp[i])->taskStatus; + ICUNIT_GOTO_EQUAL(ret, OS_TASK_STATUS_RUNNING | OS_TASK_STATUS_DETACHED, ret, EXIT); + } + + /* Create a number of cores + 1 high priority task, this task is rotation */ + task1.usCpuAffiMask = 0; + ret = LOS_TaskCreate(&testTaskIDSmp[LOSCFG_KERNEL_CORE_NUM - 1], &task1); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.usTaskPrio = TASK_PRIO_TEST_TASK + 1; + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + /* Waiting for two time slices */ + TestBusyTaskDelay(LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT * 2); // 2, used to calculate delay time + + /* check task is executed */ + ICUNIT_GOTO_EQUAL(g_testCount, LOSCFG_KERNEL_CORE_NUM, g_testCount, EXIT); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + ret = LOS_TaskDelete(testTaskIDSmp[i]); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; + +EXIT: + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + LOS_TaskDelete(testTaskIDSmp[i]); + } + + LOS_TaskDelete(g_testTaskID01); + + return LOS_NOK; +} + +void ItSmpLosTask042(void) +{ + TEST_ADD_CASE("ItSmpLosTask042", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_043.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_043.c new file mode 100644 index 00000000..d8a18068 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_043.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static volatile UINT32 g_itTestResult = LOS_NOK; + +static void TaskF01(void const * argument) +{ + LOS_AtomicInc(&g_testCount); + while (1) { + } +} + +static void TaskF02(void const * argument) +{ + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + UINT32 testTaskIDSmp[LOSCFG_KERNEL_CORE_NUM]; + const CHAR *taskAll = "-a"; + + g_testCount = 0; + TEST_TASK_PARAM_INIT(task1, "it_smp_task_043", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK); + int i; + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + /* take control of every cores */ + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + i + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&testTaskIDSmp[i], &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + /* wait test task to start */ + TestBusyTaskDelay(10); // 10, set delay time + + /* check every cores is running test task */ + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + do { + OsShellCmdDumpTask(1, &taskAll); + ret = OS_TCB_FROM_TID(testTaskIDSmp[i])->taskStatus; + } while (ret & OS_TASK_STATUS_READY); + ICUNIT_GOTO_EQUAL(ret, OS_TASK_STATUS_RUNNING | OS_TASK_STATUS_DETACHED, ret, EXIT); + } + + task1.usCpuAffiMask = 0; + ret = LOS_TaskCreate(&testTaskIDSmp[LOSCFG_KERNEL_CORE_NUM - 1], &task1); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestBusyTaskDelay(LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT * 2); // 2, used to calculate delay time + + ICUNIT_GOTO_EQUAL(g_testCount, LOSCFG_KERNEL_CORE_NUM + 1, g_testCount, EXIT); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + ret = LOS_TaskDelete(testTaskIDSmp[i]); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + return LOS_OK; + +EXIT: + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + LOS_TaskDelete(testTaskIDSmp[i]); + } + + return LOS_NOK; +} + +void ItSmpLosTask043(void) +{ + TEST_ADD_CASE("ItSmpLosTask043", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_044.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_044.c new file mode 100644 index 00000000..927f3bd2 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_044.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(void) +{ + UINT32 ret; + UINT64 timesliceCount; + UINT64 timesliceCount2; + + // 10, It is used to calculate timesliceCount + timesliceCount = TestTickCountGet() + 10; + + ret = LOS_TaskDelay(10); // 10, set delay time. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + timesliceCount2 = TestTickCountGet(); + + ICUNIT_ASSERT_EQUAL(timesliceCount, timesliceCount2, timesliceCount); + + return LOS_OK; +} + +void ItSmpLosTask044(void) +{ + TEST_ADD_CASE("ItSmpLosTask044", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_046.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_046.c new file mode 100644 index 00000000..6a3ce2f4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_046.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static volatile UINT32 g_itTestResult = LOS_OK; + +static void TaskF01(void const * argument) +{ + UINT32 ret; + UINT64 timesliceCount; + UINT64 timesliceCount2; + LOS_AtomicInc(&g_testCount); + + // 50, It is used to calculate timesliceCount + timesliceCount = TestTickCountGet() + 50; + + ret = LOS_TaskDelay(50); // 50, set delay time. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + timesliceCount2 = TestTickCountGet(); + + dprintf("Time1 = 0x%llX ; Time2 = 0x%llX \n", timesliceCount, timesliceCount2); + if ((timesliceCount > (timesliceCount2 + 1)) || ((timesliceCount < timesliceCount2 - 1))) { + g_itTestResult = LOS_NOK; + } + + while (1) { + } +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + UINT32 testTaskIDSmp[LOSCFG_KERNEL_CORE_NUM]; + + g_testCount = 0; + TEST_TASK_PARAM_INIT(task1, "it_smp_task_046", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK); + int i; + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + /* take control of every cores */ + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + i + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&testTaskIDSmp[i], &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + LOS_TaskDelay(30); // 30, set delay time. + + /* check every cores is running test task */ + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + ret = OS_TCB_FROM_TID(testTaskIDSmp[i])->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_DELAY, 0, ret, EXIT); + } + + ICUNIT_GOTO_EQUAL(g_testCount, LOSCFG_KERNEL_CORE_NUM - 1, g_testCount, EXIT); + + TestBusyTaskDelay(60); // 60, set delay time + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + ret = LOS_TaskDelete(testTaskIDSmp[i]); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + ICUNIT_ASSERT_EQUAL(g_itTestResult, LOS_OK, g_itTestResult); + + return LOS_OK; + +EXIT: + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + ret = LOS_TaskDelete(testTaskIDSmp[i]); + } + + return LOS_NOK; +} + +void ItSmpLosTask046(void) +{ + TEST_ADD_CASE("ItSmpLosTask046", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_047.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_047.c new file mode 100644 index 00000000..b17ea88e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_047.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static volatile UINT32 g_itTestResult = LOS_OK; + +static void TaskF01(void const * argument) +{ + LOS_AtomicInc(&g_testCount); + LOS_TaskDelay(20); // 20, set delay time. + while (1) { + } +} + +static void TaskF02(void const * argument) +{ + LOS_AtomicInc(&g_testCount); +} + + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + UINT32 testTaskIDSmp[LOSCFG_KERNEL_CORE_NUM]; + + g_testCount = 0; + TEST_TASK_PARAM_INIT(task1, "it_smp_task_047", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK); + int i; + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + /* take control of every cores */ + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + i + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&testTaskIDSmp[i], &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.usCpuAffiMask = 0; + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + /* wait test task to start */ + TestBusyTaskDelay(10); // 10, set delay time + + ICUNIT_GOTO_EQUAL(g_testCount, LOSCFG_KERNEL_CORE_NUM, g_testCount, EXIT); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + ret = LOS_TaskDelete(testTaskIDSmp[i]); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + ICUNIT_ASSERT_EQUAL(g_itTestResult, LOS_OK, g_itTestResult); + + return LOS_OK; + +EXIT: + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + ret = LOS_TaskDelete(testTaskIDSmp[i]); + } + + return LOS_NOK; +} + +void ItSmpLosTask047(void) +{ + TEST_ADD_CASE("ItSmpLosTask047", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_048.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_048.c new file mode 100644 index 00000000..5cbcf48e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_048.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_testRet; + +static void HwiF01(void) +{ + TEST_HwiClear(HWI_NUM_TEST); + + g_testRet = LOS_TaskDelay(10); // 10, set delay time. + ICUNIT_ASSERT_EQUAL_VOID(g_testRet, LOS_ERRNO_TSK_DELAY_IN_INT, g_testRet); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + + TestHwiTrigger(HWI_NUM_TEST); + + TEST_HwiDelete(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL(g_testRet, LOS_ERRNO_TSK_DELAY_IN_INT, g_testRet); + + return LOS_OK; +} + +void ItSmpLosTask048(void) +{ + TEST_ADD_CASE("ItSmpLosTask048", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_049.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_049.c new file mode 100644 index 00000000..f0020a2b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_049.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_testTaskResult = LOS_OK; + +static void HwiF01(void) +{ + UINT32 ret; + + TEST_HwiClear(HWI_NUM_TEST); + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_EQUAL_VOID(ret, OS_TASK_STATUS_RUNNING | OS_TASK_STATUS_DETACHED, ret); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_TSK_NOT_SUSPENDED, ret); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_EQUAL_VOID(ret, OS_TASK_STATUS_RUNNING | OS_TASK_STATUS_DETACHED, ret); + + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret; + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + + TestHwiTrigger(HWI_NUM_TEST); + + TEST_HwiDelete(HWI_NUM_TEST); + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_049", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + int i; + + /* take control of every cores */ + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ICUNIT_ASSERT_EQUAL(g_testTaskResult, LOS_OK, g_testTaskResult); + + return LOS_OK; +} + +void ItSmpLosTask049(void) +{ + TEST_ADD_CASE("ItSmpLosTask049", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_050.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_050.c new file mode 100644 index 00000000..c744494d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_050.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + LOS_AtomicInc(&g_testCount); + + while (1) { + } +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + LOS_TaskDelay(10); // 10, set delay time. + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_050", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + int i; + + /* take control of every cores */ + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + TestBusyTaskDelay(10); // 10, set delay time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_RUNNING, 0, ret, EXIT); + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + TestBusyTaskDelay(100); // 100, set delay time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_SUSPEND, 0, ret, EXIT); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + TestBusyTaskDelay(100); // 100, set delay time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_RUNNING, 0, ret, EXIT); + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_NOK; +} + +void ItSmpLosTask050(void) +{ + TEST_ADD_CASE("ItSmpLosTask050", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_051.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_051.c new file mode 100644 index 00000000..99a49c20 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_051.c @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +UINT32 g_testTaskResult = LOS_OK; + +static void HwiF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + TEST_HwiClear(HWI_NUM_TEST); + + ret = LOS_TaskSuspend(g_testTaskID02); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret; + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + + TestHwiTrigger(HWI_NUM_TEST); + + /* wait for Hwi is finished */ + TestBusyTaskDelay(5); // 5, set delay time + + TEST_HwiDelete(HWI_NUM_TEST); + + LOS_AtomicInc(&g_testCount); +} + +static void TaskF02(void) +{ + LOS_AtomicInc(&g_testCount); + + while (1) { + } +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_051", (TSK_ENTRY_FUNC)TaskF02, TASK_PRIO_TEST_TASK - 1); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + TestBusyTaskDelay(5); // 5, set delay time + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + TestBusyTaskDelay(10); // 10, set delay time + + ret = OS_TCB_FROM_TID(g_testTaskID02)->taskStatus; + ICUNIT_GOTO_EQUAL(ret & OS_TASK_STATUS_SUSPEND, OS_TASK_STATUS_SUSPEND, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, assert that g_testCount is equal to this. + + ICUNIT_GOTO_EQUAL(g_testTaskResult, LOS_OK, g_testTaskResult, EXIT); + + ret = LOS_TaskDelete(g_testTaskID02); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + LOS_TaskDelete(g_testTaskID02); +} + +void ItSmpLosTask051(void) +{ + TEST_ADD_CASE("ItSmpLosTask051", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_052.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_052.c new file mode 100644 index 00000000..a34586ec --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_052.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + LOS_AtomicInc(&g_testCount); + + while (1) { + } +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_052", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK + 1); + int i; + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_EQUAL(ret, OS_TASK_STATUS_READY | OS_TASK_STATUS_DETACHED, ret); + + ret = LOS_TaskSuspend(g_testTaskID01); + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_EQUAL(ret, OS_TASK_STATUS_SUSPEND | OS_TASK_STATUS_DETACHED, ret); + + ret = LOS_TaskResume(g_testTaskID01); + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_EQUAL(ret, OS_TASK_STATUS_READY | OS_TASK_STATUS_DETACHED, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 0, g_testCount); + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +void ItSmpLosTask052(void) +{ + TEST_ADD_CASE("ItSmpLosTask052", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_053.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_053.c new file mode 100644 index 00000000..9ee9faa2 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_053.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void HwiF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + TEST_HwiClear(HWI_NUM_TEST); + + LOS_TaskSuspend(g_testTaskID02); + + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret; + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // curret cpu + + TestHwiTrigger(HWI_NUM_TEST); + + /* wait for Hwi is finished */ + TestBusyTaskDelay(10); // 10, set delay time + + TEST_HwiDelete(HWI_NUM_TEST); + + LOS_AtomicInc(&g_testCount); +} + +static void TaskF02(void) +{ + LOS_AtomicInc(&g_testCount); + + while (1) { + } +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_053", (TSK_ENTRY_FUNC)TaskF02, TASK_PRIO_TEST_TASK + 1); + int i; + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = OS_TCB_FROM_TID(g_testTaskID02)->taskStatus; + ICUNIT_ASSERT_EQUAL(ret, OS_TASK_STATUS_READY | OS_TASK_STATUS_DETACHED, ret); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestBusyTaskDelay(10); // 10, set delay time + ret = OS_TCB_FROM_TID(g_testTaskID02)->taskStatus; + ICUNIT_ASSERT_EQUAL(ret, OS_TASK_STATUS_SUSPEND | OS_TASK_STATUS_DETACHED, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID02); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +void ItSmpLosTask053(void) +{ + TEST_ADD_CASE("ItSmpLosTask053", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_054.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_054.c new file mode 100644 index 00000000..3551b3a4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_054.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_TaskDelay(10); // 10, set delay time. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_054", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + + LOS_AtomicInc(&g_testCount); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_EQUAL(ret, OS_TASK_STATUS_SUSPEND | OS_TASK_STATUS_DELAY | OS_TASK_STATUS_DETACHED, ret); + + TestBusyTaskDelay(10); // 10, set delay time + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +void ItSmpLosTask054(void) +{ + TEST_ADD_CASE("ItSmpLosTask054", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_055.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_055.c new file mode 100644 index 00000000..185da274 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_055.c @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void HwiF01(void) +{ + UINT32 ret; + + TEST_HwiClear(HWI_NUM_TEST); + + LOS_AtomicInc(&g_testCount); + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + LOS_TaskDelay(100); // 100, set delay time. + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_055", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + int i; + + LOS_AtomicInc(&g_testCount); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_EQUAL(ret, OS_TASK_STATUS_DELAY | OS_TASK_STATUS_DETACHED, ret, EXIT); + + TestHwiTrigger(HWI_NUM_TEST); + + TestBusyTaskDelay(2); // 2, set delay time + + TEST_HwiDelete(HWI_NUM_TEST); + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, assert that g_testCount is equal to this. + + TestBusyTaskDelay(10); // 10, set delay time + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, assert that g_testCount is equal to this. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_EQUAL(ret, OS_TASK_STATUS_SUSPEND | OS_TASK_STATUS_DELAY | OS_TASK_STATUS_DETACHED, ret, EXIT); + + TestBusyTaskDelay(100); // 100, set delay time + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_NOK; +} + +void ItSmpLosTask055(void) +{ + TEST_ADD_CASE("ItSmpLosTask055", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_056.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_056.c new file mode 100644 index 00000000..6e4338a6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_056.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_TaskDelay(50); // 50, set delay time. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_056", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + + LOS_AtomicInc(&g_testCount); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + /* wait for task running and delay on the other core */ + TestBusyTaskDelay(10); // 10, set delay time + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_EQUAL(ret, OS_TASK_STATUS_DELAY | OS_TASK_STATUS_DETACHED, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + /* suspend task on the other core is asynchronous */ + TestBusyTaskDelay(10); // 10, set delay time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_EQUAL(ret, OS_TASK_STATUS_SUSPEND | OS_TASK_STATUS_DELAY | OS_TASK_STATUS_DETACHED, ret); + + TestBusyTaskDelay(10); // 10, set delay time + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +void ItSmpLosTask056(void) +{ + TEST_ADD_CASE("ItSmpLosTask056", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_057.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_057.c new file mode 100644 index 00000000..0450aa71 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_057.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void HwiF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + TEST_HwiClear(HWI_NUM_TEST); + + LOS_TaskSuspend(g_testTaskID01); + + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + LOS_TaskDelay(50); // 50, set delay time. + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_057", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + + LOS_AtomicInc(&g_testCount); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestBusyTaskDelay(5); // 5, set delay time + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_EQUAL(ret, OS_TASK_STATUS_DELAY | OS_TASK_STATUS_DETACHED, ret); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + + TestHwiTrigger(HWI_NUM_TEST); + + TEST_HwiDelete(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL(g_testCount, 4, g_testCount); // 4, assert that g_testCount is equal to this. + + TestBusyTaskDelay(10); // 10, set delay time + + ICUNIT_ASSERT_EQUAL(g_testCount, 4, g_testCount); // 4, assert that g_testCount is equal to this. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_EQUAL(ret, OS_TASK_STATUS_SUSPEND | OS_TASK_STATUS_DELAY | OS_TASK_STATUS_DETACHED, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 4, g_testCount); // 4, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +void ItSmpLosTask057(void) +{ + TEST_ADD_CASE("ItSmpLosTask057", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_058.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_058.c new file mode 100644 index 00000000..31512ec2 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_058.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static EVENT_CB_S g_eventCb01; + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_EventRead(&g_eventCb01, 0x11, LOS_WAITMODE_OR | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, 0x1, ret, EXIT); + + LOS_AtomicInc(&g_testCount); + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + LOS_EventInit(&g_eventCb01); + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_058", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + int i; + + LOS_AtomicInc(&g_testCount); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_EQUAL(ret, OS_TASK_STATUS_PEND | OS_TASK_STATUS_DETACHED, ret); + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_EQUAL(ret, OS_TASK_STATUS_SUSPEND | OS_TASK_STATUS_PEND | OS_TASK_STATUS_DETACHED, ret); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_EQUAL(ret, OS_TASK_STATUS_PEND | OS_TASK_STATUS_DETACHED, ret); + + LOS_EventWrite(&g_eventCb01, 0x1); + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + return LOS_OK; + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +void ItSmpLosTask058(void) +{ + TEST_ADD_CASE("ItSmpLosTask058", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_059.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_059.c new file mode 100644 index 00000000..5de885a5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_059.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + PRINTK("ItSmpLosTask059 4\n"); + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + PRINTK("ItSmpLosTask059 5 ret:0x%x\n", ret); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + PRINTK("ItSmpLosTask059 6\n"); + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_059", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + + LOS_AtomicInc(&g_testCount); + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_PEND), 0, ret); + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_SUSPEND), 0, ret); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_EQUAL((ret & OS_TASK_STATUS_SUSPEND), 0, ret); + PRINTK("ItSmpLosTask059 1\n"); + ret = LOS_SemPost(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + PRINTK("ItSmpLosTask059 2\n"); + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + PRINTK("ItSmpLosTask059 3\n"); + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +void ItSmpLosTask059(void) +{ + TEST_ADD_CASE("ItSmpLosTask059", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_060.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_060.c new file mode 100644 index 00000000..e38ac745 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_060.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static EVENT_CB_S g_eventCb01; + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_EventRead(&g_eventCb01, 0x11, LOS_WAITMODE_OR | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, 0x1, ret, EXIT); + + LOS_AtomicInc(&g_testCount); + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + LOS_EventInit(&g_eventCb01); + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_060", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + + LOS_AtomicInc(&g_testCount); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestBusyTaskDelay(10); // 10, set delay time + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_EQUAL(ret, OS_TASK_STATUS_PEND | OS_TASK_STATUS_DETACHED, ret); + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestBusyTaskDelay(10); // 10, set delay time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_EQUAL(ret, OS_TASK_STATUS_SUSPEND | OS_TASK_STATUS_PEND | OS_TASK_STATUS_DETACHED, ret); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestBusyTaskDelay(10); // 10, set delay time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_EQUAL(ret, OS_TASK_STATUS_PEND | OS_TASK_STATUS_DETACHED, ret); + + LOS_EventWrite(&g_eventCb01, 0x1); + + TestBusyTaskDelay(10); // 10, set delay time + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + return LOS_OK; + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +void ItSmpLosTask060(void) +{ + TEST_ADD_CASE("ItSmpLosTask060", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_061.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_061.c new file mode 100644 index 00000000..cdf9a878 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_061.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_061", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + + LOS_AtomicInc(&g_testCount); + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + + TestBusyTaskDelay(2); // 2, set delay time + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_PEND), 0, ret); + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestBusyTaskDelay(10); // 10, set delay time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & (OS_TASK_STATUS_PEND | OS_TASK_STATUS_SUSPEND)), 0, ret); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestBusyTaskDelay(2); // 2, set delay time + + ret = LOS_SemPost(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 3); // 100, Set the timeout of runtime; 3, test running count + + TestBusyTaskDelay(2); // 2, set delay time + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + return LOS_OK; + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +void ItSmpLosTask061(void) +{ + TEST_ADD_CASE("ItSmpLosTask061", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_062.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_062.c new file mode 100644 index 00000000..7c055bee --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_062.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_queue; + +static void TaskF01(void) +{ + UINT32 ret; + UINT32 readbuf; + + LOS_AtomicInc(&g_testCount); + + // 50, queue buffer size. + ret = LOS_QueueRead(g_queue, &readbuf, 50, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + // 5, length of the queue; 50, max queue msg size. + ret = LOS_QueueCreate("queue", 5, &g_queue, 0, 50); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_062", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + + LOS_AtomicInc(&g_testCount); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL((ret & OS_TASK_STATUS_PEND), 0, ret, EXIT); + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL((ret & (OS_TASK_STATUS_SUSPEND | OS_TASK_STATUS_PEND)), 0, ret, EXIT); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + TestBusyTaskDelay(10); // 10, set delay time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL((ret & OS_TASK_STATUS_PEND), 0, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(g_queue); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_QueueDelete(g_queue); + + return LOS_NOK; +} + +void ItSmpLosTask062(void) +{ + TEST_ADD_CASE("ItSmpLosTask062", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_063.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_063.c new file mode 100644 index 00000000..16ba91d8 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_063.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_queue; + +static void TaskF01(void) +{ + UINT32 ret; + UINT32 readbuf; + + LOS_AtomicInc(&g_testCount); + // 50, queue buffer size. + ret = LOS_QueueRead(g_queue, &readbuf, 50, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + // 5, length of the queue; 50, max queue msg size. + ret = LOS_QueueCreate("queue", 5, &g_queue, 0, 50); + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_063", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + + LOS_AtomicInc(&g_testCount); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + /* Wait TaskF01 to start */ + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + + TestBusyTaskDelay(2); // 2, set delay time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL((ret & OS_TASK_STATUS_PEND), 0, ret, EXIT); + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + TestBusyTaskDelay(2); // 2, set delay time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL((ret & (OS_TASK_STATUS_SUSPEND | OS_TASK_STATUS_PEND)), 0, ret, EXIT); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + TestBusyTaskDelay(2); // 2, set delay time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL((ret & OS_TASK_STATUS_PEND), 0, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(g_queue); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_QueueDelete(g_queue); + + return LOS_NOK; +} + +void ItSmpLosTask063(void) +{ + TEST_ADD_CASE("ItSmpLosTask063", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_064.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_064.c new file mode 100644 index 00000000..77bffdac --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_064.c @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static EVENT_CB_S g_eventCb01; + +static void HwiF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + TEST_HwiClear(HWI_NUM_TEST); + + LOS_TaskSuspend(g_testTaskID01); + + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_EventRead(&g_eventCb01, 0x11, LOS_WAITMODE_OR | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, 0x1, ret, EXIT); + + LOS_AtomicInc(&g_testCount); + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + LOS_EventInit(&g_eventCb01); + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_064", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + + LOS_AtomicInc(&g_testCount); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestBusyTaskDelay(2); // 2, set delay time + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_PEND), 0, ret); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + + TestHwiTrigger(HWI_NUM_TEST); + + TEST_HwiDelete(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL(g_testCount, 4, g_testCount); // 4, assert that g_testCount is equal to this. + + TestBusyTaskDelay(10); // 10, set delay time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & (OS_TASK_STATUS_SUSPEND | OS_TASK_STATUS_PEND)), 0, ret); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestBusyTaskDelay(2); // 2, set delay time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_PEND), 0, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 4, g_testCount); // 4, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +void ItSmpLosTask064(void) +{ + TEST_ADD_CASE("ItSmpLosTask064", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_065.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_065.c new file mode 100644 index 00000000..5274085d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_065.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static EVENT_CB_S g_eventCb01; + +static void HwiF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + TEST_HwiClear(HWI_NUM_TEST); + + LOS_TaskSuspend(g_testTaskID01); + + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_EventRead(&g_eventCb01, 0x11, LOS_WAITMODE_OR | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, 0x1, ret, EXIT); + + LOS_AtomicInc(&g_testCount); + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + LOS_EventInit(&g_eventCb01); + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_065", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + + LOS_AtomicInc(&g_testCount); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + + TestBusyTaskDelay(2); // 2, set delay time + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_PEND), 0, ret); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + + TestHwiTrigger(HWI_NUM_TEST); + + TEST_HwiDelete(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL(g_testCount, 4, g_testCount); // 4, assert that g_testCount is equal to this. + + TestBusyTaskDelay(2); // 2, set delay time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & (OS_TASK_STATUS_SUSPEND | OS_TASK_STATUS_PEND)), 0, ret); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestBusyTaskDelay(2); // 2, set delay time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_PEND), 0, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 4, g_testCount); // 4, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +void ItSmpLosTask065(void) +{ + TEST_ADD_CASE("ItSmpLosTask065", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_066.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_066.c new file mode 100644 index 00000000..966da4f4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_066.c @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void HwiF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + TEST_HwiClear(HWI_NUM_TEST); + + LOS_TaskSuspend(g_testTaskID01); + + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_AtomicInc(&g_testCount); + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + int i; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_066", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + + LOS_AtomicInc(&g_testCount); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestBusyTaskDelay(2); // 2, set delay time + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_PEND), 0, ret); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + + TestHwiTrigger(HWI_NUM_TEST); + + TEST_HwiDelete(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL(g_testCount, 4, g_testCount); // 4, assert that g_testCount is equal to this. + + TestBusyTaskDelay(10); // 10, set delay time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & (OS_TASK_STATUS_SUSPEND | OS_TASK_STATUS_PEND)), 0, ret); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestBusyTaskDelay(2); // 2, set delay time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_PEND), 0, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 4, g_testCount); // 4, assert that g_testCount is equal to this. + + ret = LOS_SemPost(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 5, g_testCount); // 5, assert that g_testCount is equal to this. + + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +void ItSmpLosTask066(void) +{ + TEST_ADD_CASE("ItSmpLosTask066", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_067.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_067.c new file mode 100644 index 00000000..0b9fe91c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_067.c @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void HwiF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + TEST_HwiClear(HWI_NUM_TEST); + + LOS_TaskSuspend(g_testTaskID01); + + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_AtomicInc(&g_testCount); + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_067", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + + LOS_AtomicInc(&g_testCount); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + /* Wait TaskF01 to start */ + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + + TestBusyTaskDelay(2); // 2, set delay time + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_PEND), 0, ret); + + TestHwiTrigger(HWI_NUM_TEST); + + TEST_HwiDelete(HWI_NUM_TEST); + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, assert that g_testCount is equal to this. + + TestBusyTaskDelay(2); // 2, set delay time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL((ret & (OS_TASK_STATUS_SUSPEND | OS_TASK_STATUS_PEND)), 0, ret, EXIT); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + TestBusyTaskDelay(2); // 2, set delay time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL((ret & OS_TASK_STATUS_PEND), 0, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, assert that g_testCount is equal to this. + + ret = LOS_SemPost(g_semID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + TestBusyTaskDelay(10); // 10, set delay time + + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); // 5, assert that g_testCount is equal to this. + + ret = LOS_SemDelete(g_semID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_SemDelete(g_semID); + + return LOS_NOK; +} + +void ItSmpLosTask067(void) +{ + TEST_ADD_CASE("ItSmpLosTask067", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_068.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_068.c new file mode 100644 index 00000000..ab7fc3fb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_068.c @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_queue; + +static void HwiF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + TEST_HwiClear(HWI_NUM_TEST); + + LOS_TaskSuspend(g_testTaskID01); + + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret; + UINT32 readbuf; + + LOS_AtomicInc(&g_testCount); + + // 50, queue buffer size. + ret = LOS_QueueRead(g_queue, &readbuf, 50, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + // 5, length of the queue; 50, max queue msg size. + ret = LOS_QueueCreate("queue", 5, &g_queue, 0, 50); + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_068", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + + LOS_AtomicInc(&g_testCount); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + TestBusyTaskDelay(2); // 2, set delay time + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL((ret & OS_TASK_STATUS_PEND), 0, ret, EXIT); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + + TestHwiTrigger(HWI_NUM_TEST); + + TEST_HwiDelete(HWI_NUM_TEST); + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, assert that g_testCount is equal to this. + + TestBusyTaskDelay(10); // 10, set delay time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL((ret & (OS_TASK_STATUS_SUSPEND | OS_TASK_STATUS_PEND)), 0, ret, EXIT); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + TestBusyTaskDelay(2); // 2, set delay time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL((ret & OS_TASK_STATUS_PEND), 0, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(g_queue); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return LOS_OK; + +EXIT: + LOS_QueueDelete(g_queue); + + LOS_TaskDelete(g_testTaskID01); + + return LOS_NOK; +} + +void ItSmpLosTask068(void) +{ + TEST_ADD_CASE("ItSmpLosTask068", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_069.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_069.c new file mode 100644 index 00000000..edf0c6ac --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_069.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +UINT32 g_queue; + +static void HwiF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + TEST_HwiClear(HWI_NUM_TEST); + + LOS_TaskSuspend(g_testTaskID01); + + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret; + UINT32 readbuf; + + LOS_AtomicInc(&g_testCount); + + // 50, queue buffer size. + ret = LOS_QueueRead(g_queue, &readbuf, 50, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + // 5, length of the queue; 50, max queue msg size. + ret = LOS_QueueCreate("queue", 5, &g_queue, 0, 50); + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_065", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + + LOS_AtomicInc(&g_testCount); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + + TestBusyTaskDelay(2); // 2, set delay time + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_PEND), 0, ret); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + + TestHwiTrigger(HWI_NUM_TEST); + + TEST_HwiDelete(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL(g_testCount, 4, g_testCount); // 4, assert that g_testCount is equal to this. + + TestBusyTaskDelay(2); // 2, set delay time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & (OS_TASK_STATUS_SUSPEND | OS_TASK_STATUS_PEND)), 0, ret); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestBusyTaskDelay(2); // 2, set delay time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_PEND), 0, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 4, g_testCount); // 4, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_QueueDelete(g_queue); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +void ItSmpLosTask069(void) +{ + TEST_ADD_CASE("ItSmpLosTask069", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_070.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_070.c new file mode 100644 index 00000000..69fc2f79 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_070.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void HwiF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + TEST_HwiClear(HWI_NUM_TEST); + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_TSK_ALREADY_SUSPENDED, ret); + + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + while (1) { + } +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_070", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK + 1); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_SUSPEND), 0, ret); + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_ALREADY_SUSPENDED, ret); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + + TestHwiTrigger(HWI_NUM_TEST); + + TEST_HwiDelete(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +void ItSmpLosTask070(void) +{ + TEST_ADD_CASE("ItSmpLosTask070", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_071.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_071.c new file mode 100644 index 00000000..b18d826a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_071.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void HwiF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + TEST_HwiClear(HWI_NUM_TEST); + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_TSK_ALREADY_SUSPENDED, ret); + + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + while (1) { + } +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_071", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK + 1); + int i; + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestBusyTaskDelay(50); // 50, set delay time + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_SUSPEND), 0, ret); + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_ALREADY_SUSPENDED, ret); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + + TestHwiTrigger(HWI_NUM_TEST); + + TEST_HwiDelete(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +void ItSmpLosTask071(void) +{ + TEST_ADD_CASE("ItSmpLosTask071", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_072.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_072.c new file mode 100644 index 00000000..489812d8 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_072.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 uvIntSave; + + LOS_AtomicInc(&g_testCount); + + LOS_TaskLock(); + + TestBusyTaskDelay(20); // 20, set delay time + + LOS_TaskUnlock(); + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_072", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK + 1); + int i; + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + /* wait for other core's task being schduled */ + TestAssertBusyTaskDelay(100, 1); // 100, Set the timeout of runtime; 1, test running count + + TestBusyTaskDelay(2); // 2, set delay time + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_RUNNING), 0, ret); + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_SUSPEND_LOCKED, + ret); // expect RET=LOS_ERRNO_TSK_SUSPEND_LOCKED, but can't solve asynchronous problems + + TestBusyTaskDelay(10); // 10, set delay time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_RUNNING), 0, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_NOT_SUSPENDED, ret); + + /* wait for other core's task being finished */ + do { + __asm__ volatile("nop"); + } while (g_testCount != 1); + + TestBusyTaskDelay(10); // 10, set delay time + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_NOT_CREATED, ret); + + return LOS_OK; +} + +void ItSmpLosTask072(void) +{ + TEST_ADD_CASE("ItSmpLosTask072", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_073.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_073.c new file mode 100644 index 00000000..f2021478 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_073.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + LOS_TaskLock(); + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_TSK_SUSPEND_LOCKED, ret); + + LOS_TaskUnlock(); + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_073", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + int i; + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + return LOS_OK; +} + +void ItSmpLosTask073(void) +{ + TEST_ADD_CASE("ItSmpLosTask073", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_074.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_074.c new file mode 100644 index 00000000..638190bb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_074.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void HwiF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + TEST_HwiClear(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_TSK_SUSPEND_LOCKED, ret); + + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + LOS_TaskLock(); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + + TestHwiTrigger(HWI_NUM_TEST); + + TEST_HwiDelete(HWI_NUM_TEST); + + LOS_TaskUnlock(); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_074", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + int i; + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 4, g_testCount); // 4, assert that g_testCount is equal to this. + + return LOS_OK; +} + +void ItSmpLosTask074(void) +{ + TEST_ADD_CASE("ItSmpLosTask074", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_075.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_075.c new file mode 100644 index 00000000..8cfcd026 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_075.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void HwiF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + TEST_HwiClear(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + LOS_TaskLock(); + + TestBusyTaskDelay(50); // 50, set delay time + + LOS_TaskUnlock(); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_075", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + int i; + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 1); // 100, Set the timeout of runtime; 1, test running count + + TestBusyTaskDelay(2); // 2, set delay time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_EQUAL(ret, OS_TASK_STATUS_RUNNING, ret); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + + TestHwiTrigger(HWI_NUM_TEST); + + TEST_HwiDelete(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + do { + __asm__ volatile("nop"); + } while (g_testCount != 4); // 4, assert that g_testCount is equal to this. + + TestBusyTaskDelay(10); // 10, set delay time + + ICUNIT_ASSERT_EQUAL(g_testCount, 4, g_testCount); // 4, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_NOT_CREATED, ret); + + return LOS_OK; +} + +void ItSmpLosTask075(void) +{ + TEST_ADD_CASE("ItSmpLosTask075", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_076.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_076.c new file mode 100644 index 00000000..ee9c7b8d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_076.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_076", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + int i; + + ret = LOS_MuxInit(&g_mutexkernelTest, NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_PEND), 0, ret); + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & (OS_TASK_STATUS_SUSPEND | OS_TASK_STATUS_PEND)), 0, ret); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_PEND), 0, ret); + + LOS_AtomicInc(&g_testCount); + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_NOT_CREATED, ret); + + (void)LOS_MuxDestroy(&g_mutexkernelTest); + return LOS_OK; +} + +void ItSmpLosTask076(void) +{ + TEST_ADD_CASE("ItSmpLosTask076", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_077.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_077.c new file mode 100644 index 00000000..1dbe1089 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_077.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + LOS_AtomicInc(&g_testCount); + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_077", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + + ret = LOS_MuxInit(&g_mutexkernelTest, NULL); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + /* wait for other core's task being scheduled */ + TestAssertBusyTaskDelay(100, 1); // 100, Set the timeout of runtime; 1, test running count + + TestBusyTaskDelay(2); // 2, set delay time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL((ret & OS_TASK_STATUS_PEND), 0, ret, EXIT); + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL((ret & (OS_TASK_STATUS_SUSPEND | OS_TASK_STATUS_PEND)), 0, ret, EXIT); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL((ret & OS_TASK_STATUS_PEND), 0, ret, EXIT); + + LOS_AtomicInc(&g_testCount); + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + /* wait for other core's task executed */ + TestAssertBusyTaskDelay(100, 3); // 100, Set the timeout of runtime; 3, test running count + + TestBusyTaskDelay(4); // 4, set delay time + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, assert that g_testCount is equal to this. + + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; + +EXIT: + LOS_MuxDestroy(&g_mutexkernelTest); + + LOS_TaskDelete(g_testTaskID01); + + return LOS_NOK; +} + +void ItSmpLosTask077(void) +{ + TEST_ADD_CASE("ItSmpLosTask077", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_078.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_078.c new file mode 100644 index 00000000..13f519bd --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_078.c @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void HwiF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + TEST_HwiClear(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 5, g_testCount); // 5, assert that g_testCount is equal to this. + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_078", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + int i; + + ret = LOS_MuxInit(&g_mutexkernelTest, NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + do { + __asm__ volatile("nop"); + } while (g_testCount != 1); + + TestBusyTaskDelay(2); // 2, set delay time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_PEND), 0, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + LOS_AtomicInc(&g_testCount); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + + TestHwiTrigger(HWI_NUM_TEST); + + TEST_HwiDelete(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL(g_testCount, 4, g_testCount); // 4, assert that g_testCount is equal to this. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & (OS_TASK_STATUS_SUSPEND | OS_TASK_STATUS_PEND)), 0, ret); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_PEND), 0, ret); + + LOS_AtomicInc(&g_testCount); + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 6, g_testCount); // 6, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_NOT_CREATED, ret); + + (void)LOS_MuxDestroy(&g_mutexkernelTest); + return LOS_OK; +} + +void ItSmpLosTask078(void) +{ + TEST_ADD_CASE("ItSmpLosTask078", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_079.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_079.c new file mode 100644 index 00000000..e2d50b33 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_079.c @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void HwiF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + TEST_HwiClear(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 5, g_testCount); // 5, assert that g_testCount is equal to this. + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_079", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + int i; + + ret = LOS_MuxInit(&g_mutexkernelTest, NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + do { + __asm__ volatile("nop"); + } while (g_testCount != 1); + + TestBusyTaskDelay(2); // 2, set delay time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_PEND), 0, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + LOS_AtomicInc(&g_testCount); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + + TestHwiTrigger(HWI_NUM_TEST); + + TEST_HwiDelete(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL(g_testCount, 4, g_testCount); // 4, assert that g_testCount is equal to this. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & (OS_TASK_STATUS_SUSPEND | OS_TASK_STATUS_PEND)), 0, ret); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_PEND), 0, ret); + + LOS_AtomicInc(&g_testCount); + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + do { + __asm__ volatile("nop"); + } while (g_testCount != 6); // 6, assert that g_testCount is equal to this. + + TestBusyTaskDelay(2); // 2, set delay time + + ICUNIT_ASSERT_EQUAL(g_testCount, 6, g_testCount); // 6, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_NOT_CREATED, ret); + + (void)LOS_MuxDestroy(&g_mutexkernelTest); + return LOS_OK; +} + +void ItSmpLosTask079(void) +{ + TEST_ADD_CASE("ItSmpLosTask079", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_081.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_081.c new file mode 100644 index 00000000..eed2544c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_081.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(void) +{ + UINT32 ret; + UINT32 gTestIdleTaskID; + UINT32 gTestSwtmrTaskID; + UINT32 cpuid = ArchCurrCpuid(); + + gTestIdleTaskID = OsGetIdleTaskId(); + + ret = LOS_TaskSuspend(gTestIdleTaskID); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK, ret); + + gTestSwtmrTaskID = OsSwtmrTaskIDGetByCpuid(cpuid); + + ret = LOS_TaskSuspend(gTestSwtmrTaskID); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK, ret); + + return LOS_OK; +} + +void ItSmpLosTask081(void) +{ + TEST_ADD_CASE("ItSmpLosTask081", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_082.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_082.c new file mode 100644 index 00000000..04398288 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_082.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(void) +{ + UINT32 ret; + UINT32 gTestIdleTaskID; + UINT32 gTestSwtmrTaskID; + UINT32 cpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + gTestIdleTaskID = g_percpu[cpuid].idleTaskID; + + ret = LOS_TaskSuspend(gTestIdleTaskID); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK, ret); + + gTestSwtmrTaskID = g_percpu[cpuid].swtmrTaskID; + + ret = LOS_TaskSuspend(gTestSwtmrTaskID); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK, ret); + + return LOS_OK; +} + +void ItSmpLosTask082(void) +{ + TEST_ADD_CASE("ItSmpLosTask082", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_084.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_084.c new file mode 100644 index 00000000..a0c51001 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_084.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void HwiF01(void) +{ + UINT32 ret; + + TEST_HwiClear(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_TSK_NOT_SUSPENDED, ret); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_EQUAL_VOID(ret, (OS_TASK_STATUS_RUNNING | OS_TASK_STATUS_DETACHED), ret); + + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret; + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + + TestHwiTrigger(HWI_NUM_TEST); + + TestBusyTaskDelay(5); // 5, set delay time + + TEST_HwiDelete(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_084", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + int i; + + /* take control of every cores */ + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + return LOS_OK; +} + +void ItSmpLosTask084(void) +{ + TEST_ADD_CASE("ItSmpLosTask084", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_087.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_087.c new file mode 100644 index 00000000..ff2ff72d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_087.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + LOS_AtomicInc(&g_testCount); + + while (1) { + } +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_087", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK + 1); + int i; + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_EQUAL(ret, (OS_TASK_STATUS_READY | OS_TASK_STATUS_DETACHED), ret, EXIT); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_TSK_NOT_SUSPENDED, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return LOS_OK; + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); +} + +void ItSmpLosTask087(void) +{ + TEST_ADD_CASE("ItSmpLosTask087", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_088.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_088.c new file mode 100644 index 00000000..12c2da62 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_088.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void HwiF01(void) +{ + UINT32 ret; + + TEST_HwiClear(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_TSK_NOT_SUSPENDED, ret); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_EQUAL_VOID(ret, (OS_TASK_STATUS_READY | OS_TASK_STATUS_DETACHED), ret); + + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + LOS_AtomicInc(&g_testCount); + + while (1) { + } +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_088", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK + 1); + int i; + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + TestBusyTaskDelay(2); // 2, set delay time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_EQUAL(ret, (OS_TASK_STATUS_READY | OS_TASK_STATUS_DETACHED), ret, EXIT); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + + TestHwiTrigger(HWI_NUM_TEST); + + TEST_HwiDelete(HWI_NUM_TEST); + + LOS_AtomicInc(&g_testCount); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return LOS_OK; + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); +} + +void ItSmpLosTask088(void) +{ + TEST_ADD_CASE("ItSmpLosTask088", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_089.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_089.c new file mode 100644 index 00000000..ac9ac3d7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_089.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void HwiF01(void) +{ + UINT32 ret; + + TEST_HwiClear(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + + ret = LOS_TaskResume(g_testTaskID02); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_TSK_NOT_SUSPENDED, ret); + + ret = OS_TCB_FROM_TID(g_testTaskID02)->taskStatus; + ICUNIT_ASSERT_EQUAL_VOID(ret, (OS_TASK_STATUS_READY | OS_TASK_STATUS_DETACHED), ret); + + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + LOS_AtomicInc(&g_testCount); + + while (1) { + } +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_087", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + int i; + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + task1.usTaskPrio = TASK_PRIO_TEST_TASK; + + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 1); // 100, Set the timeout of runtime; 1, test running count + + TestBusyTaskDelay(2); // 2, set delay time + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = OS_TCB_FROM_TID(g_testTaskID02)->taskStatus; + ICUNIT_ASSERT_EQUAL(ret, (OS_TASK_STATUS_READY | OS_TASK_STATUS_DETACHED), ret); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + + TestHwiTrigger(HWI_NUM_TEST); + + TEST_HwiDelete(HWI_NUM_TEST); + + LOS_AtomicInc(&g_testCount); + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskDelete(g_testTaskID02); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +void ItSmpLosTask089(void) +{ + TEST_ADD_CASE("ItSmpLosTask089", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_090.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_090.c new file mode 100644 index 00000000..b754fde2 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_090.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_090", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + int i; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL((ret & OS_TASK_STATUS_PEND), 0, ret, EXIT); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_TSK_NOT_SUSPENDED, ret, EXIT); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL((ret & OS_TASK_STATUS_PEND), 0, ret, EXIT); + + ret = LOS_SemPost(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +void ItSmpLosTask090(void) +{ + TEST_ADD_CASE("ItSmpLosTask090", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_091.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_091.c new file mode 100644 index 00000000..acaeacba --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_091.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_091", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + int i; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + + TestBusyTaskDelay(2); // 2, set delay time + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_PEND), 0, ret); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_NOT_SUSPENDED, ret); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_PEND), 0, ret); + + TestBusyTaskDelay(10); // 10, set delay time + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = LOS_SemPost(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 3); // 100, Set the timeout of runtime; 3, test running count + + TestBusyTaskDelay(2); // 2, set delay time + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +void ItSmpLosTask091(void) +{ + TEST_ADD_CASE("ItSmpLosTask091", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_092.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_092.c new file mode 100644 index 00000000..1282a723 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_092.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void HwiF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + TEST_HwiClear(HWI_NUM_TEST); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_TSK_NOT_SUSPENDED, ret); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL_VOID((ret & OS_TASK_STATUS_PEND), 0, ret); + + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_AtomicInc(&g_testCount); + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + int i; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_092", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + + LOS_AtomicInc(&g_testCount); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestBusyTaskDelay(2); // 2, set delay time + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_PEND), 0, ret); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + + TestHwiTrigger(HWI_NUM_TEST); + + TEST_HwiDelete(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL(g_testCount, 4, g_testCount); // 4, assert that g_testCount is equal to this. + + TestBusyTaskDelay(10); // 10, set delay time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_PEND), 0, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 4, g_testCount); // 4, assert that g_testCount is equal to this. + + ret = LOS_SemPost(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 5, g_testCount); // 5, assert that g_testCount is equal to this. + + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +void ItSmpLosTask092(void) +{ + TEST_ADD_CASE("ItSmpLosTask092", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_093.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_093.c new file mode 100644 index 00000000..38524eef --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_093.c @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void HwiF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + TEST_HwiClear(HWI_NUM_TEST); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_TSK_NOT_SUSPENDED, ret); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL_VOID((ret & OS_TASK_STATUS_PEND), 0, ret); + + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_AtomicInc(&g_testCount); + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_093", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + int i; + + LOS_AtomicInc(&g_testCount); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + + TestBusyTaskDelay(2); // 2, set delay time + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_PEND), 0, ret); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + + TestHwiTrigger(HWI_NUM_TEST); + + TEST_HwiDelete(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL(g_testCount, 4, g_testCount); // 4, assert that g_testCount is equal to this. + + TestBusyTaskDelay(2); // 2, set delay time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_PEND), 0, ret); + + ret = LOS_SemPost(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 5); // 100, Set the timeout of runtime; 5, test running count + + ICUNIT_ASSERT_EQUAL(g_testCount, 5, g_testCount); // 5, assert that g_testCount is equal to this. + + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +void ItSmpLosTask093(void) +{ + TEST_ADD_CASE("ItSmpLosTask093", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_094.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_094.c new file mode 100644 index 00000000..0d3b6055 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_094.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_094", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + int i; + + LOS_AtomicInc(&g_testCount); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL((ret & OS_TASK_STATUS_SUSPEND), 0, ret, EXIT); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_NOT_CREATED, ret); + + return LOS_OK; + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +void ItSmpLosTask094(void) +{ + TEST_ADD_CASE("ItSmpLosTask094", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_095.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_095.c new file mode 100644 index 00000000..0e338187 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_095.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void HwiF01(void) +{ + UINT32 ret; + + TEST_HwiClear(HWI_NUM_TEST); + + LOS_AtomicInc(&g_testCount); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + LOS_TaskSuspend(g_testTaskID01); + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // curret cpu + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_095", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + int i; + + LOS_AtomicInc(&g_testCount); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_EQUAL(ret, (OS_TASK_STATUS_SUSPEND | OS_TASK_STATUS_DETACHED), ret, EXIT); + + TestHwiTrigger(HWI_NUM_TEST); + + TestBusyTaskDelay(1); + + TEST_HwiDelete(HWI_NUM_TEST); + + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); // 5, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_TSK_NOT_CREATED, ret, EXIT); + + return LOS_OK; +EXIT: + TEST_HwiDelete(HWI_NUM_TEST); + LOS_TaskDelete(g_testTaskID01); + + return LOS_NOK; +} + +void ItSmpLosTask095(void) +{ + TEST_ADD_CASE("ItSmpLosTask095", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_096.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_096.c new file mode 100644 index 00000000..70f359d7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_096.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void HwiF01(void) +{ + UINT32 ret; + + TEST_HwiClear(HWI_NUM_TEST); + + LOS_AtomicInc(&g_testCount); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_096", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + int i; + + LOS_AtomicInc(&g_testCount); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + + TestBusyTaskDelay(2); // 2, set delay time + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_EQUAL(ret, (OS_TASK_STATUS_SUSPEND | OS_TASK_STATUS_DETACHED), ret); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // curret cpu + + TestHwiTrigger(HWI_NUM_TEST); + + TEST_HwiDelete(HWI_NUM_TEST); + + TestBusyTaskDelay(10); // 10, set delay time + + ICUNIT_ASSERT_EQUAL(g_testCount, 5, g_testCount); // 5, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_NOT_CREATED, ret); + + return LOS_OK; +} + +void ItSmpLosTask096(void) +{ + TEST_ADD_CASE("ItSmpLosTask096", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_097.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_097.c new file mode 100644 index 00000000..9d57864c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_097.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_094", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + int i; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + while (g_testCount == 1) { + } + + TestBusyTaskDelay(2); // 2, set delay time + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL((ret & OS_TASK_STATUS_SUSPEND), 0, ret, EXIT); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + /* Wait other core's TaskF01 to resume */ + TestAssertBusyTaskDelay(100, 3); // 100, Set the timeout of runtime; 3, test running count + + TestBusyTaskDelay(2); // 2, set delay time + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_NOT_CREATED, ret); + + return LOS_OK; + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_NOK; +} + +void ItSmpLosTask097(void) +{ + TEST_ADD_CASE("ItSmpLosTask097", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_098.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_098.c new file mode 100644 index 00000000..39f93646 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_098.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_098", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + int i; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL((ret & OS_TASK_STATUS_SUSPEND), 0, ret, EXIT); + + LOS_TaskLock(); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_EQUAL(ret, (OS_TASK_STATUS_READY | OS_TASK_STATUS_DETACHED), ret, EXIT); + + LOS_TaskUnlock(); + + TestBusyTaskDelay(2); // 2, set delay time + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + return LOS_OK; + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_NOK; +} + +void ItSmpLosTask098(void) +{ + TEST_ADD_CASE("ItSmpLosTask098", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_099.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_099.c new file mode 100644 index 00000000..9fb8a003 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_099.c @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void HwiF01(void) +{ + UINT32 ret; + + TEST_HwiClear(HWI_NUM_TEST); + + // 3, assert that g_testCount is equal to this. + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 3, g_testCount); + + LOS_AtomicInc(&g_testCount); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 5, g_testCount); // 5, assert that g_testCount is equal to this. + + LOS_AtomicInc(&g_testCount); +} + +static void TaskF02(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + LOS_TaskLock(); + + TestBusyTaskDelay(50); // 50, set delay time + + LOS_TaskUnlock(); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 6, g_testCount); // 6, assert that g_testCount is equal to this. + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_099_1", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + int i; + + LOS_AtomicInc(&g_testCount); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + while (g_testCount == 1) { + } + + TestBusyTaskDelay(2); // 2, set delay time + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL((ret & OS_TASK_STATUS_SUSPEND), 0, ret, EXIT); + + task1.pcName = "it_smp_task_099_2"; + task1.usTaskPrio = TASK_PRIO_TEST_TASK + 1; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + while (g_testCount == 2) { // 2, assert that g_testCount is equal to this. + } + + TestBusyTaskDelay(2); // 2, set delay time + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, assert that g_testCount is equal to this. + + ret = OS_TCB_FROM_TID(g_testTaskID02)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL((ret & OS_TASK_STATUS_RUNNING), 0, ret, EXIT); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // curret cpu + + TestHwiTrigger(HWI_NUM_TEST); + + TEST_HwiDelete(HWI_NUM_TEST); + + while (g_testCount == 3) { // 3, assert that g_testCount is equal to this. + } + + TestBusyTaskDelay(2); // 2, set delay time + + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); // 5, assert that g_testCount is equal to this. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL((ret & OS_TASK_STATUS_READY), 0, ret, EXIT); + + TestBusyTaskDelay(60); // 60, set delay time + + ICUNIT_GOTO_EQUAL(g_testCount, 7, g_testCount, EXIT); // 7, assert that g_testCount is equal to this. + + LOS_TaskDelete(g_testTaskID01); + + LOS_TaskDelete(g_testTaskID02); + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + LOS_TaskDelete(g_testTaskID02); + + return LOS_NOK; +} + +void ItSmpLosTask099(void) +{ + TEST_ADD_CASE("ItSmpLosTask099", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_100.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_100.c new file mode 100644 index 00000000..3fe94c2d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_100.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + while (1) { + } +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_100", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK + 1); + int i; + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 0, g_testCount); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL((ret & OS_TASK_STATUS_READY), 0, ret, EXIT); + + LOS_TaskLock(); + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL((ret & OS_TASK_STATUS_SUSPEND), 0, ret, EXIT); + + LOS_TaskUnlock(); + + ICUNIT_ASSERT_EQUAL(g_testCount, 0, g_testCount); + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +void ItSmpLosTask100(void) +{ + TEST_ADD_CASE("ItSmpLosTask100", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_101.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_101.c new file mode 100644 index 00000000..26ef5a45 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_101.c @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static volatile int g_flag = 0; + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_TaskLock(); + + LOS_AtomicInc(&g_testCount); + + while (g_flag == 0) { + } + + LOS_TaskUnlock(); + + LOS_AtomicInc(&g_testCount); +} + +static void TaskF02(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + while (1) { + } +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + UINT32 gTestTaskLock; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_101", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + int i; + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.usTaskPrio = TASK_PRIO_TEST_TASK + 1; + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 1); // 100, Set the timeout of runtime; 1, test running count + + TestBusyTaskDelay(2); // 2, set delay time + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL((ret & OS_TASK_STATUS_RUNNING), 0, ret, EXIT); + + ret = OS_TCB_FROM_TID(g_testTaskID02)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL((ret & OS_TASK_STATUS_READY), 0, ret, EXIT); + + /* check if other core is Task_locked */ + gTestTaskLock = OsSchedRunqueueByID((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM))->taskLockCnt; + ICUNIT_ASSERT_NOT_EQUAL(gTestTaskLock, 0, gTestTaskLock); + + ret = LOS_TaskSuspend(g_testTaskID02); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + TestBusyTaskDelay(2); // 2, set delay time + + ret = OS_TCB_FROM_TID(g_testTaskID02)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL((ret & OS_TASK_STATUS_SUSPEND), 0, ret, EXIT); + + /* unlock other core's tasklock */ + g_flag = 1; + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + + TestBusyTaskDelay(2); // 2, set delay time + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_NOT_CREATED, ret); + + ret = LOS_TaskDelete(g_testTaskID02); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskDelete(g_testTaskID02); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_NOK; +} + +void ItSmpLosTask101(void) +{ + TEST_ADD_CASE("ItSmpLosTask101", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_102.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_102.c new file mode 100644 index 00000000..44febc70 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_102.c @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static volatile int g_flag = 0; +static void TaskF01(void) +{ + UINT32 ret; + + LOS_TaskLock(); + + LOS_AtomicInc(&g_testCount); + + while (g_flag == 0) { + } + + LOS_TaskUnlock(); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + LOS_AtomicInc(&g_testCount); +} + +static void TaskF02(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + LOS_TaskSuspend(g_testTaskID02); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + UINT32 gTestTaskLock; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_102", (TSK_ENTRY_FUNC)TaskF02, TASK_PRIO_TEST_TASK - 1); + int i; + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + /* wait for other core's task to suspend */ + TestAssertBusyTaskDelay(100, 1); // 100, Set the timeout of runtime; 1, test running count + + TestBusyTaskDelay(2); // 2, set delay time + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + ret = OS_TCB_FROM_TID(g_testTaskID02)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL((ret & OS_TASK_STATUS_SUSPEND), 0, ret, EXIT); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.usTaskPrio = TASK_PRIO_TEST_TASK + 1; + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + /* wait for other core's task being running */ + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + TestBusyTaskDelay(10); // 10, set delay time + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL((ret & OS_TASK_STATUS_RUNNING), 0, ret, EXIT); + + /* wait for other core is Task_locked */ + TestBusyTaskDelay(2); // 2, set delay time + + ret = LOS_TaskResume(g_testTaskID02); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + TestBusyTaskDelay(2); // 2, set delay time + + ret = OS_TCB_FROM_TID(g_testTaskID02)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL((ret & OS_TASK_STATUS_READY), 0, ret, EXIT); + + g_flag = 1; + + // 4, assert that g_testCount is equal to this. + while (g_testCount != 4) { + } + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, assert that g_testCount is equal to this. + + LOS_TaskDelete(g_testTaskID01); + + LOS_TaskDelete(g_testTaskID02); + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + LOS_TaskDelete(g_testTaskID02); + + return LOS_NOK; +} + +void ItSmpLosTask102(void) +{ + TEST_ADD_CASE("ItSmpLosTask102", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_103.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_103.c new file mode 100644 index 00000000..fc3a69c3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_103.c @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void HwiF01(void) +{ + UINT32 ret; + + TEST_HwiClear(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + + LOS_AtomicInc(&g_testCount); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_EQUAL_VOID(ret, (OS_TASK_STATUS_SUSPEND | OS_TASK_STATUS_DETACHED), ret); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_EQUAL_VOID(ret, (OS_TASK_STATUS_READY | OS_TASK_STATUS_DETACHED), ret); + + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_103", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + int i; + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL((ret & OS_TASK_STATUS_SUSPEND), 0, ret, EXIT); + + LOS_TaskLock(); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // curret cpu + + TestHwiTrigger(HWI_NUM_TEST); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_EQUAL(ret, (OS_TASK_STATUS_READY | OS_TASK_STATUS_DETACHED), ret, EXIT); + + TEST_HwiDelete(HWI_NUM_TEST); + + LOS_TaskUnlock(); + + ICUNIT_ASSERT_EQUAL(g_testCount, 4, g_testCount); // 4, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_NOT_CREATED, ret); + + return LOS_OK; + +EXIT: + TEST_HwiDelete(HWI_NUM_TEST); + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_NOK; +} + +void ItSmpLosTask103(void) +{ + TEST_ADD_CASE("ItSmpLosTask103", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_105.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_105.c new file mode 100644 index 00000000..ffa4955d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_105.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + // 50, sem timeout. + ret = LOS_SemPend(g_semID, 50); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_105", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + int i; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_PEND), 0, ret); + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_UNUSED), 0, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +void ItSmpLosTask105(void) +{ + TEST_ADD_CASE("ItSmpLosTask105", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_106.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_106.c new file mode 100644 index 00000000..b8151a02 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_106.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + // 50, sem timeout. + ret = LOS_SemPend(g_semID, 50); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_106", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + int i; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + + // 2, set delay time. + TestBusyTaskDelay(2); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_PEND), 0, ret); + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_UNUSED), 0, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +void ItSmpLosTask106(void) +{ + TEST_ADD_CASE("ItSmpLosTask106", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_107.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_107.c new file mode 100644 index 00000000..209b73ee --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_107.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_107", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK + 1); + int i; + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_READY), 0, ret); + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_UNUSED), 0, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 0, g_testCount); + + return LOS_OK; + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +void ItSmpLosTask107(void) +{ + TEST_ADD_CASE("ItSmpLosTask107", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_108.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_108.c new file mode 100644 index 00000000..4e5a3637 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_108.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_108", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + int i; + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_SUSPEND), 0, ret); + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_UNUSED), 0, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + return LOS_OK; + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +void ItSmpLosTask108(void) +{ + TEST_ADD_CASE("ItSmpLosTask108", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_109.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_109.c new file mode 100644 index 00000000..ac2ab829 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_109.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_109", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + while (g_testCount == 0) { + } + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + TestBusyTaskDelay(2); // 2, set delay time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL((ret & OS_TASK_STATUS_SUSPEND), 0, ret, EXIT); + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + TestBusyTaskDelay(2); // 2, set delay time + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL((ret & OS_TASK_STATUS_UNUSED), 0, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +void ItSmpLosTask109(void) +{ + TEST_ADD_CASE("ItSmpLosTask109", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_110.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_110.c new file mode 100644 index 00000000..6827e853 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_110.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_TaskDelay(50); // 50, set delay time. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_110", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + int i; + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_DELAY), 0, ret); + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_UNUSED), 0, ret); + + ret = LOS_TaskDelay(50); // 50, set delay time. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + return LOS_OK; + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +void ItSmpLosTask110(void) +{ + TEST_ADD_CASE("ItSmpLosTask110", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_112.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_112.c new file mode 100644 index 00000000..20a09fe3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_112.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + LOS_TaskLock(); + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_TSK_DELETE_LOCKED, ret); + + LOS_TaskUnlock(); + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_112", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + int i; + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + return LOS_OK; +} + +void ItSmpLosTask112(void) +{ + TEST_ADD_CASE("ItSmpLosTask112", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_113.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_113.c new file mode 100644 index 00000000..eabc693c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_113.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + LOS_TaskLock(); + + TestBusyTaskDelay(30); // 30, set delay time + + LOS_TaskUnlock(); + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_113", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + int i; + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + while (g_testCount == 0) { + } + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_RUNNING), 0, ret); + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_SUSPEND_LOCKED, + ret); // expect RET=LOS_ERRNO_TSK_SUSPEND_LOCKED, but can't solve asynchronous problems + + TestBusyTaskDelay(2); // 2, set delay time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_RUNNING), 0, ret); + + TestBusyTaskDelay(30); // 30, set delay time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_UNUSED), 0, ret); + + return LOS_OK; +} + +void ItSmpLosTask113(void) +{ + TEST_ADD_CASE("ItSmpLosTask113", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_114.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_114.c new file mode 100644 index 00000000..ca48b5da --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_114.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(void) +{ + UINT32 ret; + UINT32 gTestIdleTaskID; + UINT32 gTestSwtmrTaskID; + UINT32 cpuid = ArchCurrCpuid(); + + gTestIdleTaskID = OsGetIdleTaskId(); + + ret = LOS_TaskDelete(gTestIdleTaskID); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK, ret); + + gTestSwtmrTaskID = OsSwtmrTaskIDGetByCpuid(cpuid); + + ret = LOS_TaskDelete(gTestSwtmrTaskID); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK, ret); + + return LOS_OK; +} + +void ItSmpLosTask114(void) +{ + TEST_ADD_CASE("ItSmpLosTask114", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_115.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_115.c new file mode 100644 index 00000000..b5b7d165 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_115.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(void) +{ + UINT32 ret; + UINT32 gTestIdleTaskID; + UINT32 gTestSwtmrTaskID; + UINT32 cpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + gTestSwtmrTaskID = OsSwtmrTaskIDGetByCpuid(cpuid); + + ret = LOS_TaskDelete(gTestSwtmrTaskID); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK, ret); + + return LOS_OK; +} + +void ItSmpLosTask115(void) +{ + TEST_ADD_CASE("ItSmpLosTask115", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_117.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_117.c new file mode 100644 index 00000000..e407ea6c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_117.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void HwiF01(void) +{ + UINT32 ret; + + TEST_HwiClear(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + + LOS_AtomicInc(&g_testCount); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_EQUAL_VOID(ret, OS_TASK_STATUS_RUNNING, ret); + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + LOS_AtomicInc(&g_testCount); + + while (1) { + } +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_117", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + while (g_testCount == 0) { + } // wait task01 to start + + TestBusyTaskDelay(2); // 2, set delay time + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_RUNNING), 0, ret); + + TestHwiTrigger(HWI_NUM_TEST); + + TEST_HwiDelete(HWI_NUM_TEST); + + TestBusyTaskDelay(10); // 10, set delay time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_UNUSED), 0, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_NOT_CREATED, ret); + + return LOS_OK; + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +void ItSmpLosTask117(void) +{ + TEST_ADD_CASE("ItSmpLosTask117", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_126.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_126.c new file mode 100644 index 00000000..9bf825d2 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_126.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" +#include "los_swtmr_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void HwiF01(void) +{ + UINT32 ret; + UINT32 gTestIdleTaskID; + UINT32 gTestSwtmrTaskID; + UINT32 cpuid = ArchCurrCpuid(); + + LOS_AtomicInc(&g_testCount); + + gTestIdleTaskID = OsGetIdleTaskId(); + + ret = LOS_TaskDelete(gTestIdleTaskID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_TSK_YIELD_IN_INT, ret); + + LOS_AtomicInc(&g_testCount); + + gTestSwtmrTaskID = OsSwtmrTaskIDGetByCpuid(cpuid); + + ret = LOS_TaskDelete(gTestSwtmrTaskID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_TSK_YIELD_IN_INT, ret); + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + + g_testCount = 0; + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + + TestHwiTrigger(HWI_NUM_TEST); + + TEST_HwiDelete(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + return LOS_OK; +} + +void ItSmpLosTask126(void) +{ + TEST_ADD_CASE("ItSmpLosTask126", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_127.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_127.c new file mode 100644 index 00000000..26de0819 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_127.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void HwiF01(void) +{ + UINT32 ret; + UINT32 gTestIdleTaskID; + UINT32 gTestSwtmrTaskID; + UINT32 cpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + gTestIdleTaskID = OsSchedRunqueueByID(cpuid)->idleTaskID; + + ret = LOS_TaskDelete(gTestIdleTaskID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_TSK_YIELD_IN_INT, ret); + + gTestSwtmrTaskID = OsSwtmrTaskIDGetByCpuid(cpuid); + + ret = LOS_TaskDelete(gTestSwtmrTaskID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_TSK_YIELD_IN_INT, ret); + + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + + TestHwiTrigger(HWI_NUM_TEST); + + TEST_HwiDelete(HWI_NUM_TEST); + + return LOS_OK; +} + +void ItSmpLosTask127(void) +{ + TEST_ADD_CASE("ItSmpLosTask127", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_128.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_128.c new file mode 100644 index 00000000..df6c3dc5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_128.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + while (1) { + } +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + UINT32 testTaskIDSmp[LOSCFG_KERNEL_CORE_NUM + 1]; + const CHAR *taskAll = "-a"; + g_testCount = 0; + TEST_TASK_PARAM_INIT(task1, "it_smp_task_128", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK); + int i; + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + /* take control of every cores */ + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + i + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&testTaskIDSmp[i], &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + + /* wait for task to start */ + TestBusyTaskDelay(10); // 10, set delay time + + /* take this core back to control */ + ICUNIT_GOTO_EQUAL(g_testCount, LOSCFG_KERNEL_CORE_NUM - 1, g_testCount, EXIT); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + do { + OsShellCmdDumpTask(1, &taskAll); + ret = OS_TCB_FROM_TID(testTaskIDSmp[i])->taskStatus; + } while (ret & OS_TASK_STATUS_READY); + + ICUNIT_GOTO_EQUAL(ret, (OS_TASK_STATUS_RUNNING | OS_TASK_STATUS_DETACHED), ret, EXIT); + } + + ret = LOS_TaskYield(); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + ret = LOS_TaskDelete(testTaskIDSmp[i]); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + + return LOS_OK; + +EXIT: + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + LOS_TaskDelete(testTaskIDSmp[i]); + } + + return LOS_NOK; +} + +void ItSmpLosTask128(void) +{ + TEST_ADD_CASE("ItSmpLosTask128", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_129.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_129.c new file mode 100644 index 00000000..a3bf8d37 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_129.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + LOS_AtomicInc(&g_testCount); + while (1) { + } +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + UINT32 testTaskIDSmp[LOSCFG_KERNEL_CORE_NUM + 1]; + UINT64 timesliceCount1; + UINT64 timesliceCount2; + + g_testCount = 0; + TEST_TASK_PARAM_INIT(task1, "it_smp_task_129", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK); + int i; + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + /* create core_num same priority tasks */ + task1.usCpuAffiMask = 0; + ret = LOS_TaskCreate(&testTaskIDSmp[i], &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + TestBusyTaskDelay(10); // 10, set delay time + + timesliceCount1 = TestTickCountGet(); + + ret = LOS_TaskYield(); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + timesliceCount2 = TestTickCountGet(); + + /* Check if task yield definitely succeeded */ + ICUNIT_GOTO_NOT_EQUAL(timesliceCount2, timesliceCount1, timesliceCount2 - timesliceCount1, EXIT); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + ret = LOS_TaskDelete(testTaskIDSmp[i]); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + + return LOS_OK; + +EXIT: + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + LOS_TaskDelete(testTaskIDSmp[i]); + } + + return LOS_NOK; +} + +void ItSmpLosTask129(void) +{ + TEST_ADD_CASE("ItSmpLosTask129", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_130.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_130.c new file mode 100644 index 00000000..4bd26689 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_130.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + + LOS_AtomicInc(&g_testCount); + + ret = LOS_TaskYield(); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + LOS_AtomicInc(&g_testCount); + + while (1) { + } +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + UINT16 prio = LOS_TaskPriGet(LOS_CurTaskIDGet()); + TEST_TASK_PARAM_INIT(task1, "it_smp_task_130", (TSK_ENTRY_FUNC)TaskF01, prio); + int i; + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + /* Wait TaskF01 to yield, then testTask timeslice is LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT */ + if (g_testCount != 1) { + LOS_TaskYield(); + } + + LOS_TaskLock(); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + LOS_AtomicInc(&g_testCount); + + ret = LOS_TaskYield(); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_TSK_YIELD_IN_LOCK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + + LOS_TaskUnlock(); + + ret = LOS_TaskYield(); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + TestAssertBusyTaskDelay(100, 3); // 100, Set the timeout of runtime; 3, test running count + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_NOK; +} + +void ItSmpLosTask130(void) +{ + TEST_ADD_CASE("ItSmpLosTask130", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_131.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_131.c new file mode 100644 index 00000000..b9407420 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_131.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void HwiF01(void) +{ + UINT32 ret; + + TEST_HwiClear(HWI_NUM_TEST); + + LOS_AtomicInc(&g_testCount); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_EQUAL_VOID(ret, (OS_TASK_STATUS_READY | OS_TASK_STATUS_DETACHED), ret); + + ret = LOS_TaskYield(); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_TSK_YIELD_IN_INT, ret); +} + +static void TaskF01(void) +{ + LOS_AtomicInc(&g_testCount); + + while (1) { + } +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_131", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_READY), 0, ret); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + + TestHwiTrigger(HWI_NUM_TEST); + + TEST_HwiDelete(HWI_NUM_TEST); + + TestBusyTaskDelay(2 * LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT); // 2, set delay time + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + return LOS_OK; +} + +void ItSmpLosTask131(void) +{ + TEST_ADD_CASE("ItSmpLosTask131", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_132.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_132.c new file mode 100644 index 00000000..569c6470 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_132.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + LOS_AtomicInc(&g_testCount); + while (1) { + } +} + +static void TaskF02(void) +{ + UINT32 ret; + LOS_AtomicInc(&g_testCount); + + ret = LOS_TaskYield(); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestBusyTaskDelay(2 * LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT); // 2, set delay time + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + UINT32 testTaskIDSmp[LOSCFG_KERNEL_CORE_NUM + 1]; + UINT64 timesliceCount1; + UINT64 timesliceCount2; + int i; + const CHAR *taskAll = "-a"; + g_testCount = 0; + TEST_TASK_PARAM_INIT(task1, "it_smp_task_132", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + /* take control of every cores */ + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + i + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&testTaskIDSmp[i], &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + TestBusyTaskDelay(10); // 10, set delay time + + /* check all task is running */ + ICUNIT_GOTO_EQUAL(g_testCount, LOSCFG_KERNEL_CORE_NUM - 1, g_testCount, EXIT); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + do { + OsShellCmdDumpTask(1, &taskAll); + ret = OS_TCB_FROM_TID(testTaskIDSmp[i])->taskStatus; + } while (ret & OS_TASK_STATUS_READY); + ICUNIT_GOTO_EQUAL(ret, (OS_TASK_STATUS_RUNNING | OS_TASK_STATUS_DETACHED), ret, EXIT); + } + + task1.usCpuAffiMask = 0; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + ret = LOS_TaskCreate(&testTaskIDSmp[i], &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + while (g_testCount != LOSCFG_KERNEL_CORE_NUM) { + } + + ICUNIT_GOTO_EQUAL(g_testCount, LOSCFG_KERNEL_CORE_NUM, g_testCount, EXIT); + + ret = LOS_TaskYield(); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, LOSCFG_KERNEL_CORE_NUM, g_testCount, EXIT); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + ret = LOS_TaskDelete(testTaskIDSmp[i]); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + + return LOS_OK; + +EXIT: + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + LOS_TaskDelete(testTaskIDSmp[i]); + } + + return LOS_NOK; +} + +void ItSmpLosTask132(void) +{ + TEST_ADD_CASE("ItSmpLosTask132", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_133.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_133.c new file mode 100644 index 00000000..264e5f5f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_133.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void SwtmrF01(UINT32 arg) +{ + UINT32 ret; + if (arg != 0xffff) { + return; + } + + LOS_AtomicInc(&g_testCount); + + ret = LOS_TaskYield(); + ICUNIT_ASSERT_EQUAL_VOID(ret, 0, ret); + return; +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + UINT16 swTmrID; + + // 2, swtmr interval + ret = LOS_SwtmrCreate(2, LOS_SWTMR_MODE_ONCE, SwtmrF01, &swTmrID, 0xffff); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrStart(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + TestBusyTaskDelay(3); // 3, set delay time + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = LOS_SwtmrDelete(swTmrID); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_SWTMR_ID_INVALID, ret); + + return LOS_OK; + +EXIT: + LOS_SwtmrDelete(swTmrID); +} + +void ItSmpLosTask133(void) +{ + TEST_ADD_CASE("ItSmpLosTask133", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_134.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_134.c new file mode 100644 index 00000000..2984cb1f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_134.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + LOS_AtomicInc(&g_testCount); + while (1) { + } +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + UINT32 testTaskIDSmp[LOSCFG_KERNEL_CORE_NUM + 1]; + UINT64 timesliceCount1; + UINT64 timesliceCount2; + + g_testCount = 0; + TEST_TASK_PARAM_INIT(task1, "it_smp_task_134", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + int i; + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&testTaskIDSmp[LOSCFG_KERNEL_CORE_NUM - 1], &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task1.usTaskPrio = TASK_PRIO_TEST_TASK; + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + /* take control of every cores */ + task1.usCpuAffiMask = 0; + ret = LOS_TaskCreate(&testTaskIDSmp[i], &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + timesliceCount1 = TestTickCountGet(); + + ret = LOS_TaskYield(); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + timesliceCount2 = TestTickCountGet(); + + ICUNIT_GOTO_NOT_EQUAL(timesliceCount1, timesliceCount2, timesliceCount1, EXIT); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + ret = LOS_TaskDelete(testTaskIDSmp[i]); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + + TestBusyTaskDelay(20); // 20, set delay time + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_EQUAL(ret, OS_TASK_STATUS_UNUSED, ret, EXIT); + } + + return LOS_OK; + +EXIT: + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + LOS_TaskDelete(testTaskIDSmp[i]); + } + + return LOS_NOK; +} + +void ItSmpLosTask134(void) +{ + TEST_ADD_CASE("ItSmpLosTask134", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_135.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_135.c new file mode 100644 index 00000000..4add0299 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_135.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + LOS_AtomicInc(&g_testCount); + while (1) { + } +} + +static void TaskF02(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_TaskYield(); + ICUNIT_ASSERT_EQUAL_VOID(ret, 0, ret); + + while (1) { + } +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + UINT32 testTaskIDSmp[LOSCFG_KERNEL_CORE_NUM + 1]; + UINT64 timesliceCount1; + UINT64 timesliceCount2; + int i; + + g_testCount = 0; + TEST_TASK_PARAM_INIT(task1, "it_smp_task_135", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + /* take control of every cores */ + task1.usCpuAffiMask = 0; + ret = LOS_TaskCreate(&testTaskIDSmp[i], &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&testTaskIDSmp[LOSCFG_KERNEL_CORE_NUM - 1], &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + /* wait for other task being running */ + TestBusyTaskDelay(10); // 10, set delay time + + timesliceCount1 = TestTickCountGet(); + + ret = LOS_TaskYield(); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + timesliceCount2 = TestTickCountGet(); + + ICUNIT_GOTO_NOT_EQUAL(timesliceCount1, timesliceCount2, timesliceCount1, EXIT); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + ret = LOS_TaskDelete(testTaskIDSmp[i]); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + + return LOS_OK; + +EXIT: + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + LOS_TaskDelete(testTaskIDSmp[i]); + } + + return LOS_NOK; +} + +void ItSmpLosTask135(void) +{ + TEST_ADD_CASE("ItSmpLosTask135", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_136.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_136.c new file mode 100644 index 00000000..098eb888 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_136.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_testTaskIdsmp[LOSCFG_KERNEL_CORE_NUM + 1]; + +static void TaskF01(void) +{ + LOS_AtomicInc(&g_testCount); + while (1) { + } +} + +static void TaskF02(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_TaskSuspend(g_testTaskIdsmp[LOSCFG_KERNEL_CORE_NUM - 1]); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + UINT64 timesliceCount1; + UINT64 timesliceCount2; + int i; + + g_testCount = 0; + TEST_TASK_PARAM_INIT(task1, "it_smp_task_136", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM - 1; i++) { + /* take control of every cores */ + task1.usCpuAffiMask = 0; + ret = LOS_TaskCreate(&g_testTaskIdsmp[i], &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskIdsmp[LOSCFG_KERNEL_CORE_NUM - 1], &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestBusyTaskDelay(20); // 20, set delay time + + ret = LOS_TaskYield(); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, LOSCFG_KERNEL_CORE_NUM, g_testCount, EXIT); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + ret = LOS_TaskDelete(g_testTaskIdsmp[i]); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + + return LOS_OK; + +EXIT: + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + LOS_TaskDelete(g_testTaskIdsmp[i]); + } + + return LOS_NOK; +} + +void ItSmpLosTask136(void) +{ + TEST_ADD_CASE("ItSmpLosTask136", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_137.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_137.c new file mode 100644 index 00000000..af1af9c1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_137.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + LOS_AtomicInc(&g_testCount); + while (1) { + if (ArchCurrCpuid() == 0) { + g_testCount++; + break; + } + } +} + +static void TaskF02(void) +{ + LOS_AtomicInc(&g_testCount); + while (1) { + } +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + + g_testCount = 0; + TEST_TASK_PARAM_INIT(task1, "it_smp_task_137", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = OS_TCB_FROM_TID(g_testTaskID02)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_READY), 0, ret); + + TestAssertBusyTaskDelay(100, 1); // 100, Set the timeout of runtime; 1, test running count + + ICUNIT_ASSERT_NOT_EQUAL(g_testCount, 0, g_testCount); + + ret = LOS_TaskYield(); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ICUNIT_ASSERT_NOT_EQUAL(g_testCount, 0, g_testCount); + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskDelete(g_testTaskID02); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + LOS_TaskDelete(g_testTaskID02); + + return LOS_NOK; +} + +void ItSmpLosTask137(void) +{ + TEST_ADD_CASE("ItSmpLosTask137", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_138.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_138.c new file mode 100644 index 00000000..11f5106a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_138.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + UINT64 timesliceCount1; + UINT64 timesliceCount2; + int i; + + g_testCount = 0; + TEST_TASK_PARAM_INIT(task1, "it_smp_task_138", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + + LOS_TaskLock(); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 0, g_testCount); + + LOS_TaskUnlock(); + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_NOK; +} + +void ItSmpLosTask138(void) +{ + TEST_ADD_CASE("ItSmpLosTask138", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_139.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_139.c new file mode 100644 index 00000000..4222b3f3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_139.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static void HwiF01(void) +{ + UINT32 ret; + + TSK_INIT_PARAM_S task1 = { 0 }; + + TEST_HwiClear(HWI_NUM_TEST); + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_139", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + + LOS_AtomicInc(&g_testCount); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_TSK_YIELD_IN_INT, ret); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + + TSK_INIT_PARAM_S task1 = { 0 }; + + g_testCount = 0; + + LOS_TaskLock(); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + + TestHwiTrigger(HWI_NUM_TEST); + + TEST_HwiDelete(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + LOS_TaskUnlock(); + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + return LOS_OK; +} + +void ItSmpLosTask139(void) +{ + TEST_ADD_CASE("ItSmpLosTask139", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_141.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_141.c new file mode 100644 index 00000000..e2db4ba1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_141.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static void HwiF01(void) +{ + UINT32 ret; + + TSK_INIT_PARAM_S task1 = { 0 }; + + TEST_HwiClear(HWI_NUM_TEST); + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_141", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + + LOS_AtomicInc(&g_testCount); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() - 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_TSK_YIELD_IN_INT, ret); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + + TSK_INIT_PARAM_S task1 = { 0 }; + + g_testCount = 0; + + LOS_TaskLock(); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM))); // other cpu + + TestHwiTrigger(HWI_NUM_TEST); + + TestBusyTaskDelay(5); // 5, set delay time + + TEST_HwiDelete(HWI_NUM_TEST); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + LOS_TaskUnlock(); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + return LOS_OK; + +EXIT: + return LOS_NOK; +} + +void ItSmpLosTask141(void) +{ + TEST_ADD_CASE("ItSmpLosTask141", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_142.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_142.c new file mode 100644 index 00000000..fd008611 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_142.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + UINT64 timesliceCount1; + UINT64 timesliceCount2; + int i; + + g_testCount = 0; + TEST_TASK_PARAM_INIT(task1, "it_smp_task_142", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK); + + LOS_TaskLock(); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + LOS_TaskUnlock(); + + TestBusyTaskDelay(2 * LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT); // 2, used to calculate delay time + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_NOK; +} + +void ItSmpLosTask142(void) +{ + TEST_ADD_CASE("ItSmpLosTask142", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_143.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_143.c new file mode 100644 index 00000000..fc6c26f3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_143.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static void HwiF01(void) +{ + UINT32 ret; + + TSK_INIT_PARAM_S task1 = { 0 }; + + TEST_HwiClear(HWI_NUM_TEST); + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_143", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + + LOS_AtomicInc(&g_testCount); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_TSK_YIELD_IN_INT, ret); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + + TSK_INIT_PARAM_S task1 = { 0 }; + + g_testCount = 0; + + LOS_TaskLock(); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + + TestHwiTrigger(HWI_NUM_TEST); + + TEST_HwiDelete(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + LOS_TaskUnlock(); + + /* wait for TaskF01 is finished */ + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_NOK; +} + +void ItSmpLosTask143(void) +{ + TEST_ADD_CASE("ItSmpLosTask143", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_144.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_144.c new file mode 100644 index 00000000..cc042f7d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_144.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF02(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + TSK_INIT_PARAM_S task1 = { 0 }; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_144", (TSK_ENTRY_FUNC)TaskF02, TASK_PRIO_TEST_TASK); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() - 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + LOS_TaskDelete(g_testTaskID02); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + + TSK_INIT_PARAM_S task1 = { 0 }; + + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_140", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + + LOS_TaskLock(); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + TestBusyTaskDelay(20); // 20, set delay time + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + ret = OS_TCB_FROM_TID(g_testTaskID02)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL((ret & OS_TASK_STATUS_READY), 0, ret, EXIT); + + LOS_TaskUnlock(); + + TestBusyTaskDelay(LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT * 2); // 2, used to calculate delay time + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + LOS_TaskDelete(g_testTaskID02); + + return LOS_NOK; +} + +void ItSmpLosTask144(void) +{ + TEST_ADD_CASE("ItSmpLosTask144", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_145.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_145.c new file mode 100644 index 00000000..02ab477c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_145.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static void HwiF01(void) +{ + UINT32 ret; + + TSK_INIT_PARAM_S task1 = { 0 }; + + TEST_HwiClear(HWI_NUM_TEST); + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_145", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK); + + LOS_AtomicInc(&g_testCount); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() - 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_TSK_YIELD_IN_INT, ret); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + + TSK_INIT_PARAM_S task1 = { 0 }; + + g_testCount = 0; + + LOS_TaskLock(); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM))); // other cpu + + TestHwiTrigger(HWI_NUM_TEST); + + TestBusyTaskDelay(10); // 10, set delay time + + TEST_HwiDelete(HWI_NUM_TEST); + + /* wait for Hwi is finished */ + while (g_testCount == 0) { + } + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + LOS_TaskUnlock(); + + TestBusyTaskDelay(2 * LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT); // 2, Used to calculate delay time. + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_NOK; +} + +void ItSmpLosTask145(void) +{ + TEST_ADD_CASE("ItSmpLosTask145", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_146.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_146.c new file mode 100644 index 00000000..945737a3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_146.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + while (g_testCount == 1) { + } + + ret = LOS_TaskPriGet(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, TASK_PRIO_TEST_TASK - 1, ret); + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + + TSK_INIT_PARAM_S task1 = { 0 }; + + g_testCount = 0; + + // 2, Used to calculate priority. + TEST_TASK_PARAM_INIT(task1, "it_smp_task_146", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 2); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + while (g_testCount == 0) { + } + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = LOS_TaskPriSet(g_testTaskID01, TASK_PRIO_TEST_TASK - 1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskPriGet(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, TASK_PRIO_TEST_TASK - 1, ret); + + LOS_AtomicInc(&g_testCount); + + // 2, assert that g_testCount is equal to this. + while (g_testCount == 2) { + } + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + TestBusyTaskDelay(2); // 2, set delay time + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_NOT_CREATED, ret); + + return LOS_OK; +} + +void ItSmpLosTask146(void) +{ + TEST_ADD_CASE("ItSmpLosTask146", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_147.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_147.c new file mode 100644 index 00000000..025b874b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_147.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + while (g_testCount == 1) { + } + + ret = LOS_TaskPriGet(g_testTaskID01); + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + ICUNIT_ASSERT_EQUAL_VOID(ret, TASK_PRIO_TEST_TASK - 2, ret); + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + + TSK_INIT_PARAM_S task1 = { 0 }; + + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_147", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + while (g_testCount == 0) { + } + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + ret = LOS_TaskPriSet(g_testTaskID01, TASK_PRIO_TEST_TASK - 2); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskPriGet(g_testTaskID01); + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + ICUNIT_ASSERT_EQUAL(ret, TASK_PRIO_TEST_TASK - 2, ret); + + LOS_AtomicInc(&g_testCount); + + // 2, assert that g_testCount is eaual to this. + while (g_testCount == 2) { + } + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + TestBusyTaskDelay(2); // 2, set delay time + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_NOT_CREATED, ret); + return LOS_OK; +} + +void ItSmpLosTask147(void) +{ + TEST_ADD_CASE("ItSmpLosTask147", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_148.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_148.c new file mode 100644 index 00000000..04b07414 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_148.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + + ret = LOS_TaskPriGet(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, TASK_PRIO_TEST_TASK - 1, ret); + + LOS_TaskDelay(10); // 10, set delay time. + + LOS_AtomicInc(&g_testCount); + + ret = LOS_TaskPriGet(g_testTaskID01); + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + ICUNIT_ASSERT_EQUAL_VOID(ret, TASK_PRIO_TEST_TASK - 2, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + + TSK_INIT_PARAM_S task1 = { 0 }; + + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_148", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + LOS_AtomicInc(&g_testCount); + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + ret = LOS_TaskPriSet(g_testTaskID01, TASK_PRIO_TEST_TASK - 2); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskPriGet(g_testTaskID01); + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + ICUNIT_GOTO_EQUAL(ret, TASK_PRIO_TEST_TASK - 2, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + + LOS_TaskDelay(11); // 11, set a delay time + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_TSK_NOT_CREATED, ret, EXIT); + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_NOK; +} + +void ItSmpLosTask148(void) +{ + TEST_ADD_CASE("ItSmpLosTask148", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_149.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_149.c new file mode 100644 index 00000000..e62bd377 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_149.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_TaskPriGet(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, TASK_PRIO_TEST_TASK - 1, ret); + + // 50, sem timeout time. + ret = LOS_SemPend(g_semID, 50); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_TaskPriGet(g_testTaskID01); + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + ICUNIT_ASSERT_EQUAL_VOID(ret, TASK_PRIO_TEST_TASK - 2, ret); + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_149", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + + LOS_AtomicInc(&g_testCount); + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL((ret & OS_TASK_STATUS_PEND), 0, ret, EXIT); + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + ret = LOS_TaskPriSet(g_testTaskID01, TASK_PRIO_TEST_TASK - 2); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskPriGet(g_testTaskID01); + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + ICUNIT_GOTO_EQUAL(ret, TASK_PRIO_TEST_TASK - 2, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + + ret = LOS_SemPost(g_semID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, assert that g_testCount is equal to this. + + ret = LOS_SemDelete(g_semID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_TSK_NOT_CREATED, ret, EXIT); + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + return LOS_NOK; +} + +void ItSmpLosTask149(void) +{ + TEST_ADD_CASE("ItSmpLosTask149", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_150.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_150.c new file mode 100644 index 00000000..060bdc3c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_150.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_TaskPriGet(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, TASK_PRIO_TEST_TASK - 1, ret); + + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_TaskPriGet(g_testTaskID01); + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + ICUNIT_ASSERT_EQUAL_VOID(ret, TASK_PRIO_TEST_TASK - 2, ret); + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_150", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + int i; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + + TestBusyTaskDelay(5); // 5, set delay time + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_PEND), 0, ret); + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + ret = LOS_TaskPriSet(g_testTaskID01, TASK_PRIO_TEST_TASK - 2); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskPriGet(g_testTaskID01); + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + ICUNIT_ASSERT_EQUAL(ret, TASK_PRIO_TEST_TASK - 2, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = LOS_SemPost(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 3); // 100, Set the timeout of runtime; 3, test running count + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestBusyTaskDelay(20); // 20, set delay time + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_NOT_CREATED, ret); + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_NOK; +} + +void ItSmpLosTask150(void) +{ + TEST_ADD_CASE("ItSmpLosTask150", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_151.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_151.c new file mode 100644 index 00000000..42c66ec0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_151.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_TaskPriGet(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, TASK_PRIO_TEST_TASK - 1, ret); + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_TaskPriGet(g_testTaskID01); + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + ICUNIT_ASSERT_EQUAL_VOID(ret, TASK_PRIO_TEST_TASK - 2, ret); + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_151", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + + LOS_AtomicInc(&g_testCount); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL((ret & OS_TASK_STATUS_SUSPEND), 0, ret, EXIT); + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + ret = LOS_TaskPriSet(g_testTaskID01, TASK_PRIO_TEST_TASK - 2); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskPriGet(g_testTaskID01); + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + ICUNIT_GOTO_EQUAL(ret, TASK_PRIO_TEST_TASK - 2, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_NOT_CREATED, ret); + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_NOK; +} + +void ItSmpLosTask151(void) +{ + TEST_ADD_CASE("ItSmpLosTask151", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_152.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_152.c new file mode 100644 index 00000000..94edc0d4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_152.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_TaskPriGet(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, TASK_PRIO_TEST_TASK - 1, ret); + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_TaskPriGet(g_testTaskID01); + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + ICUNIT_ASSERT_EQUAL_VOID(ret, TASK_PRIO_TEST_TASK - 2, ret); + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_152", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + int i; + + LOS_AtomicInc(&g_testCount); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + + TestBusyTaskDelay(2); // 2, set delay time + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL((ret & OS_TASK_STATUS_SUSPEND), 0, ret); + + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + ret = LOS_TaskPriSet(g_testTaskID01, TASK_PRIO_TEST_TASK - 2); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskPriGet(g_testTaskID01); + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + ICUNIT_ASSERT_EQUAL(ret, TASK_PRIO_TEST_TASK - 2, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 3); // 100, Set the timeout of runtime; 3, test running count + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + TestBusyTaskDelay(2); // 2, set delay time + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_NOT_CREATED, ret); + + return LOS_OK; + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +void ItSmpLosTask152(void) +{ + TEST_ADD_CASE("ItSmpLosTask152", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_153.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_153.c new file mode 100644 index 00000000..c2c41ec1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_153.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void HwiF01(void) +{ + UINT32 ret; + + TEST_HwiClear(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + + LOS_AtomicInc(&g_testCount); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_EQUAL_VOID(ret, (OS_TASK_STATUS_RUNNING | OS_TASK_STATUS_DETACHED), ret); + + ret = LOS_TaskPriGet(g_testTaskID01); + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + ICUNIT_ASSERT_EQUAL_VOID(ret, TASK_PRIO_TEST_TASK - 2, ret); + + ret = LOS_TaskPriSet(g_testTaskID01, TASK_PRIO_TEST_TASK - 1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_TaskPriGet(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, TASK_PRIO_TEST_TASK - 1, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + TestHwiTrigger(HWI_NUM_TEST); + + ret = LOS_TaskPriGet(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, TASK_PRIO_TEST_TASK - 1, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + TEST_TASK_PARAM_INIT(task1, "it_smp_task_153", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 2); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_HwiDelete(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL(g_testCount, 4, g_testCount); // 4, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_NOT_CREATED, ret); + + return LOS_OK; + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +void ItSmpLosTask153(void) +{ + TEST_ADD_CASE("ItSmpLosTask153", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_154.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_154.c new file mode 100644 index 00000000..9a67bdf8 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_154.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void HwiF01(void) +{ + UINT32 ret; + + TEST_HwiClear(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + + LOS_AtomicInc(&g_testCount); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_EQUAL_VOID(ret, (OS_TASK_STATUS_RUNNING | OS_TASK_STATUS_DETACHED), ret); + + ret = LOS_TaskPriGet(g_testTaskID01); + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + ICUNIT_ASSERT_EQUAL_VOID(ret, TASK_PRIO_TEST_TASK - 2, ret); + + ret = LOS_TaskPriSet(g_testTaskID01, TASK_PRIO_TEST_TASK - 1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_TaskPriGet(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, TASK_PRIO_TEST_TASK - 1, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + LOS_AtomicInc(&g_testCount); +} + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + TestHwiTrigger(HWI_NUM_TEST); + + TestBusyTaskDelay(10); // 10, set delay time + + ret = LOS_TaskPriGet(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, TASK_PRIO_TEST_TASK - 1, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + TEST_TASK_PARAM_INIT(task1, "it_smp_task_154", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 2); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + // 4, assert that g_testCount is equal to this. + while (g_testCount != 4) { + } + + TestBusyTaskDelay(2); // 2, set delay time + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, assert that g_testCount is equal to this. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL((ret & OS_TASK_STATUS_UNUSED), 0, ret, EXIT); + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_NOT_CREATED, ret); + + TEST_HwiDelete(HWI_NUM_TEST); + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + TEST_HwiDelete(HWI_NUM_TEST); + + return LOS_NOK; +} + +void ItSmpLosTask154(void) +{ + TEST_ADD_CASE("ItSmpLosTask154", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_155.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_155.c new file mode 100644 index 00000000..efb834a7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_155.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + + LOS_TaskLock(); + ret = LOS_TaskPriGet(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, TASK_PRIO_TEST_TASK - 1, ret); + + ret = LOS_TaskPriSet(g_testTaskID01, TASK_PRIO_TEST_TASK + 1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_TaskPriGet(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, TASK_PRIO_TEST_TASK + 1, ret); + + LOS_TaskUnlock(); + + LOS_AtomicInc(&g_testCount); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_155", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_AtomicInc(&g_testCount); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, assert that g_testCount is equal to this. + + ret = LOS_TaskPriGet(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, TASK_PRIO_TEST_TASK + 1, ret, EXIT); + + LOS_TaskDelay(10); // 10, set delay time. + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_TSK_NOT_CREATED, ret, EXIT); + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + return LOS_NOK; +} + +void ItSmpLosTask155(void) +{ + TEST_ADD_CASE("ItSmpLosTask155", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_156.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_156.c new file mode 100644 index 00000000..162f8e84 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_156.c @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + + LOS_AtomicInc(&g_testCount); + + LOS_TaskLock(); + + TestBusyTaskDelay(20); // 20, set delay time + + ret = LOS_TaskPriGet(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, TASK_PRIO_TEST_TASK + 1, ret); + + LOS_TaskUnlock(); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 3, g_testCount); // 3, assert that g_testCount is equal to this. + + LOS_AtomicInc(&g_testCount); +} + +static void TaskF02(void) +{ + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_156", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + task1.usTaskPrio = TASK_PRIO_TEST_TASK; + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 1); // 100, Set the timeout of runtime; 1, test running count + + LOS_AtomicInc(&g_testCount); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = LOS_TaskPriGet(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, TASK_PRIO_TEST_TASK - 1, ret); + + ret = LOS_TaskPriSet(g_testTaskID01, TASK_PRIO_TEST_TASK + 1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskPriGet(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, TASK_PRIO_TEST_TASK + 1, ret); + + while (g_testCount != 4) { // 4, assert that g_testCount is equal to this. + } + ICUNIT_ASSERT_EQUAL(g_testCount, 4, g_testCount); // 4, assert that g_testCount is equal to this. + + LOS_TaskDelete(g_testTaskID01); + + LOS_TaskDelete(g_testTaskID02); + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + LOS_TaskDelete(g_testTaskID02); + + return LOS_NOK; +} + +void ItSmpLosTask156(void) +{ + TEST_ADD_CASE("ItSmpLosTask156", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_157.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_157.c new file mode 100644 index 00000000..2d5953b3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_157.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_ASSERT_NOT_EQUAL_VOID((ret & OS_TASK_STATUS_RUNNING), 0, ret); + + ret = LOS_TaskCpuAffiSet(g_testTaskID01, CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM))); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(ArchCurrCpuid(), ArchCurrCpuid() + 1, ArchCurrCpuid()); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_157", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + LOS_AtomicInc(&g_testCount); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_NOK; +} + +void ItSmpLosTask157(void) +{ + TEST_ADD_CASE("ItSmpLosTask157", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_158.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_158.c new file mode 100644 index 00000000..fa4620b3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_158.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + + ret = LOS_TaskYield(); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + + while (1) { + } +} + +static void TaskF02(void) +{ + LOS_AtomicInc(&g_testCount); +} + + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + UINT32 testid[2]; + int i; + g_testCount = 0; + + TEST_TASK_PARAM_INIT(task1, "it_smp_task_158", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + for (i = 0; i < 100; i++) { // 100, Number of cycles. + TestBusyTaskDelay((LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT / LOS_US_PER_TICK) - 1); + + /* if same priority task is executedbreak loop */ + if (g_testCount != i) { + break; + } + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + /* if same priority task is executedbreak loop */ + if (g_testCount != i + 1) { + break; + } + } + + ICUNIT_GOTO_NOT_EQUAL(g_testCount, 100, g_testCount, EXIT); // 100, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskDelete(g_testTaskID02); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_TSK_NOT_CREATED, ret, EXIT); + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + LOS_TaskDelete(g_testTaskID02); + + return LOS_NOK; +} + +void ItSmpLosTask158(void) +{ + TEST_ADD_CASE("ItSmpLosTask158", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_159.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_159.c new file mode 100644 index 00000000..c0d7e7b3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_159.c @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static EVENT_CB_S g_eventCb01; + +static void TaskF01(void) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + + LOS_AtomicInc(&g_testCount); + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); +} + +static void TaskF02(void) +{ + UINT32 ret; + int i; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + + LOS_AtomicInc(&g_testCount); + + for (i = 0; i < TRandom() % 200; i++) { // 200, Number of cycles. + } + /* It is possible that TaskF01 is finished. */ + LOS_TaskDelete(g_testTaskID01); + + LOS_AtomicInc(&g_testCount); + + LOS_EventWrite(&g_eventCb01, 0x1); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + int i, j; + LOS_EventInit(&g_eventCb01); + + for (i = 0; i < IT_TASK_SMP_LOOP; i++) { + g_testCount = 0; + TEST_TASK_PARAM_INIT_AFFI(task1, "it_smp_task_159_1", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1, 0); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(task1, "it_smp_task_159_2", (TSK_ENTRY_FUNC)TaskF02, TASK_PRIO_TEST_TASK - 1, 0); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + /* wait for task02 start */ + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + + for (j = 0; j < TRandom() % 200; j++) { // 200, Number of cycles. + } + /* It is possible that delete TaskF01 first. */ + ret = LOS_TaskResume(g_testTaskID01); + if (ret != LOS_ERRNO_TSK_NOT_CREATED && ret != LOS_OK) { + goto EXIT; + } + + /* possible value of g_testCount are 2, 3, 4 */ + if (g_testCount != 2 && g_testCount != 3 && g_testCount != 4) { + goto EXIT; + } + + ret = LOS_EventRead(&g_eventCb01, 0x11, LOS_WAITMODE_OR | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, 0x1, ret, EXIT); + + TestBusyTaskDelay(2); // 2, set delay time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_EQUAL(!(ret & OS_TASK_STATUS_UNUSED), 0, ret, EXIT); + + ret = OS_TCB_FROM_TID(g_testTaskID02)->taskStatus; + ICUNIT_GOTO_EQUAL(!(ret & OS_TASK_STATUS_UNUSED), 0, ret, EXIT); + } + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + + return LOS_NOK; +} + +void ItSmpLosTask159(void) +{ + TEST_ADD_CASE("ItSmpLosTask159", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_160.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_160.c new file mode 100644 index 00000000..f399a1d4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_160.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + UINT32 ret; + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + + LOS_AtomicInc(g_testCount); + + while (1) { + } + + LOS_AtomicInc(g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + + g_testCount = 0; + TEST_TASK_PARAM_INIT_AFFI(task1, "it_smp_task_160", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 1, 0); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(LOSCFG_KERNEL_CORE_NUM); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestBusyTaskDelay(10); // 10, set delay time + + ICUNIT_ASSERT_EQUAL(g_testCount, 0, g_testCount); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_EQUAL(ret, OS_TASK_STATUS_UNUSED, ret, EXIT); + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + + return LOS_OK; +} + +void ItSmpLosTask160(void) +{ + TEST_ADD_CASE("ItSmpLosTask160", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_161.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_161.c new file mode 100644 index 00000000..f46c15e1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_161.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void TaskF01(void) +{ + LOS_AtomicInc(&g_testCount); + + while (1) { + } +} + +static void TaskF02(void) +{ + LOS_AtomicInc(&g_testCount); +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + g_testCount = 0; + + // 2, It is used to calculate a priority relative to TASK_PRIO_TEST_TASK. + TEST_TASK_PARAM_INIT(task1, "it_smp_task_161", (TSK_ENTRY_FUNC)TaskF01, TASK_PRIO_TEST_TASK - 2); + + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 1; + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM)); + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 1); // 100, Set the timeout of runtime; 1, test running count + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = LOS_TaskCpuAffiSet(g_testTaskID02, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, assert that g_testCount is equal to this. + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskDelete(g_testTaskID02); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_NOT_CREATED, ret); + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + LOS_TaskDelete(g_testTaskID02); + + return LOS_NOK; +} + +void ItSmpLosTask161(void) +{ + TEST_ADD_CASE("ItSmpLosTask161", Testcase, TEST_LOS, TEST_TASK, TEST_LEVEL1, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/BUILD.gn b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/BUILD.gn new file mode 100644 index 00000000..ce0a7dac --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/BUILD.gn @@ -0,0 +1,111 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +import("//kernel/liteos_a/liteos.gni") + +kernel_module("test_ipc") { + sources = [ "mux/It_los_mux.c" ] + + sources += [ + "mux/full/It_los_mutex_006.c", + "mux/full/It_los_mutex_007.c", + "mux/full/It_los_mutex_008.c", + "mux/full/It_los_mutex_009.c", + "mux/full/It_los_mutex_010.c", + "mux/full/It_los_mutex_011.c", + "mux/full/It_los_mutex_012.c", + "mux/full/It_los_mutex_013.c", + "mux/full/It_los_mutex_015.c", + "mux/full/It_los_mutex_016.c", + "mux/full/It_los_mutex_017.c", + "mux/full/It_los_mutex_018.c", + "mux/full/It_los_mutex_020.c", + "mux/full/It_los_mutex_021.c", + "mux/full/It_los_mutex_025.c", + "mux/full/It_los_mutex_026.c", + "mux/full/It_los_mutex_027.c", + "mux/full/It_los_mutex_028.c", + "mux/full/It_los_mutex_029.c", + "mux/full/It_los_mutex_031.c", + "mux/full/It_los_mutex_035.c", + "mux/full/It_los_mutex_036.c", + "mux/full/It_los_mutex_037.c", + "mux/full/It_los_mutex_038.c", + "mux/full/It_los_mutex_039.c", + "mux/full/It_los_mutex_040.c", + "mux/full/It_los_mutex_041.c", + "mux/full/It_los_mutex_042.c", + "mux/full/It_los_mutex_043.c", + "mux/smoke/It_los_mutex_001.c", + "mux/smoke/It_los_mutex_002.c", + "mux/smoke/It_los_mutex_003.c", + "mux/smoke/It_los_mutex_004.c", + "mux/smp/It_smp_los_mux_001.c", + "mux/smp/It_smp_los_mux_002.c", + "mux/smp/It_smp_los_mux_003.c", + "mux/smp/It_smp_los_mux_004.c", + "mux/smp/It_smp_los_mux_005.c", + "mux/smp/It_smp_los_mux_006.c", + "mux/smp/It_smp_los_mux_007.c", + "mux/smp/It_smp_los_mux_2001.c", + "mux/smp/It_smp_los_mux_2002.c", + "mux/smp/It_smp_los_mux_2003.c", + "mux/smp/It_smp_los_mux_2004.c", + "mux/smp/It_smp_los_mux_2005.c", + "mux/smp/It_smp_los_mux_2006.c", + "mux/smp/It_smp_los_mux_2007.c", + "mux/smp/It_smp_los_mux_2008.c", + "mux/smp/It_smp_los_mux_2009.c", + "mux/smp/It_smp_los_mux_2010.c", + "mux/smp/It_smp_los_mux_2011.c", + "mux/smp/It_smp_los_mux_2012.c", + "mux/smp/It_smp_los_mux_2013.c", + "mux/smp/It_smp_los_mux_2014.c", + "mux/smp/It_smp_los_mux_2015.c", + "mux/smp/It_smp_los_mux_2016.c", + "mux/smp/It_smp_los_mux_2017.c", + "mux/smp/It_smp_los_mux_2018.c", + "mux/smp/It_smp_los_mux_2021.c", + "mux/smp/It_smp_los_mux_2022.c", + "mux/smp/It_smp_los_mux_2024.c", + "mux/smp/It_smp_los_mux_2025.c", + "mux/smp/It_smp_los_mux_2026.c", + "mux/smp/It_smp_los_mux_2027.c", + "mux/smp/It_smp_los_mux_2028.c", + "mux/smp/It_smp_los_mux_2029.c", + ] + include_dirs = [ + "sem", + "event", + "mux", + "queue", + ] + + public_configs = + [ "$LITEOSTOPDIR/testsuites/kernel:liteos_kernel_test_public" ] +} diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/Makefile b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/Makefile new file mode 100644 index 00000000..2db39fc5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/Makefile @@ -0,0 +1,51 @@ + +include $(LITEOSTESTTOPDIR)/config.mk + +MODULE_NAME := ipctest + +LOCAL_INCLUDE := \ + -I $(LITEOSTESTTOPDIR)/kernel/include \ + -I $(LITEOSTESTTOPDIR)/kernel/sample/kernel_base/ipc/mux \ + -I $(LITEOSTESTTOPDIR)/kernel/sample/kernel_base/ipc/sem \ + -I $(LITEOSTESTTOPDIR)/kernel/sample/kernel_base/ipc/event \ + -I $(LITEOSTESTTOPDIR)/kernel/sample/kernel_base/ipc/queue \ + -I $(LITEOSTESTTOPDIR)/kernel/sample/kernel_base/ipc/rwlock + +SRC_MODULES := sem event queue mux rwlock + +ifeq ($(LOSCFG_KERNEL_SMP), y) +SMP_MODULES := sem/smp event/smp queue/smp mux/smp rwlock/smp +endif + +ifeq ($(LOSCFG_TEST_LLT), y) +LLT_MODULES := sem/llt event/llt queue/llt mux/llt +endif + +ifeq ($(LOSCFG_TEST_PRESSURE), y) +PRESSURE_MODULES := sem/pressure event/pressure queue/pressure mux/pressure +endif + +ifeq ($(LOSCFG_TEST_SMOKE), y) +SMOKE_MODULES := sem/smoke event/smoke queue/smoke mux/smoke rwlock/smoke +endif + +ifeq ($(LOSCFG_TEST_FULL), y) +FULL_MODULES := sem/full event/full queue/full mux/full +endif + +ifeq ($(LOSCFG_TEST_MANUAL_SHELL), y) +MANUAL_MODULES := sem/manual event/manual queue/manual +endif + +ifeq ($(LOSCFG_TEST_MANUAL_TEST), y) +MANUAL_MODULES :=sem/manual event/manual queue/manual mux/manual +endif + +LOCAL_MODULES := $(SRC_MODULES) $(LLT_MODULES) $(PRESSURE_MODULES) $(SMOKE_MODULES) $(FULL_MODULES) $(SMP_MODULES) $(MANUAL_MODULES) + +LOCAL_SRCS := $(foreach dir,$(LOCAL_MODULES),$(wildcard $(dir)/*.c)) +LOCAL_CHS := $(foreach dir,$(LOCAL_MODULES),$(wildcard $(dir)/*.h)) + +LOCAL_FLAGS := $(LOCAL_INCLUDE) -Wno-error + +include $(MODULE) diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/It_los_event.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/It_los_event.c new file mode 100644 index 00000000..949e547f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/It_los_event.c @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +VOID ItSuiteLosEvent(VOID) +{ +#ifdef LOSCFG_KERNEL_SMP + ItSmpLosEvent001(); + ItSmpLosEvent002(); + ItSmpLosEvent003(); + ItSmpLosEvent004(); + ItSmpLosEvent005(); + ItSmpLosEvent006(); + ItSmpLosEvent007(); + ItSmpLosEvent008(); + ItSmpLosEvent009(); + ItSmpLosEvent010(); + ItSmpLosEvent011(); + ItSmpLosEvent012(); + ItSmpLosEvent013(); + ItSmpLosEvent014(); + ItSmpLosEvent015(); + ItSmpLosEvent016(); + ItSmpLosEvent017(); + ItSmpLosEvent018(); + ItSmpLosEvent019(); + ItSmpLosEvent020(); + ItSmpLosEvent021(); + ItSmpLosEvent022(); + ItSmpLosEvent023(); + ItSmpLosEvent024(); + ItSmpLosEvent025(); + ItSmpLosEvent027(); + + ItSmpLosEvent029(); + ItSmpLosEvent030(); + ItSmpLosEvent031(); + ItSmpLosEvent032(); + ItSmpLosEvent034(); + ItSmpLosEvent037(); +#endif + +#if defined(LOSCFG_TEST_SMOKE) + ItLosEvent031(); // 0 destroy + ItLosEvent035(); // 0 init + ItLosEvent036(); // 0 clear destroy write read + ItLosEvent041(); // 0 read +#endif + +#if defined(LOSCFG_TEST_FULL) + ItLosEvent001(); + ItLosEvent002(); + ItLosEvent003(); + ItLosEvent004(); + ItLosEvent005(); // write clear destroy + ItLosEvent006(); + ItLosEvent007(); + ItLosEvent008(); + ItLosEvent009(); // read + ItLosEvent010(); + ItLosEvent011(); + ItLosEvent012(); + ItLosEvent013(); + ItLosEvent014(); + ItLosEvent015(); + ItLosEvent016(); + ItLosEvent018(); + ItLosEvent019(); + ItLosEvent020(); + ItLosEvent021(); + ItLosEvent022(); + ItLosEvent023(); + ItLosEvent024(); + ItLosEvent025(); +#ifndef LOSCFG_KERNEL_SMP + ItLosEvent026(); +#endif + ItLosEvent027(); + ItLosEvent029(); + ItLosEvent030(); + ItLosEvent032(); + ItLosEvent033(); // / + ItLosEvent037(); + ItLosEvent038(); +#ifndef LOSCFG_KERNEL_SMP + ItLosEvent039(); +#endif + ItLosEvent040(); + ItLosEvent042(); + ItLosEvent043(); +#endif + +#if defined(LOSCFG_TEST_PRESSURE) + ItLosEvent028(); +#endif + +#if defined(LOSCFG_TEST_LLT) + LltLosEvent001(); + ItLosEvent017(); + ItLosEvent034(); +#endif +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, 1); +#endif +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/It_los_event.h b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/It_los_event.h new file mode 100644 index 00000000..26dad0f9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/It_los_event.h @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IT_LOS_EVENT_H +#define IT_LOS_EVENT_H + +#include "osTest.h" +#include "los_base_pri.h" +#include "los_task_pri.h" +#include "los_tick_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#define LOOP 100 + +#define SELF_DELETED 0 +#define SYS_EXIST_SWTMR 1 +#define SWTMR_LOOP_NUM 10 +#define TEST_HWI_RUNTIME 0x100000 +#define TASK_LOOP_NUM 0x100000 + +#define TASK_NAME_NUM 10 +#define IT_TASK_LOOP 20 + +extern UINT32 g_testTaskID01; +extern UINT32 g_testTaskID02; +extern UINT32 g_testTaskID03; +extern UINT32 g_testQueueID01; +extern UINT32 g_TestTskHandle; +extern UINT32 g_swTmrMaxNum; + +extern UINT16 usSwTmrID1; +extern UINT16 usSwTmrID2; +extern UINT16 usSwTmrID3; + +extern UINT32 SwtmrCountA; +extern UINT32 SwtmrCountB; +extern UINT32 SwtmrCountC; +extern UINT64 CpuTickCountA; +extern UINT64 CpuTickCountB; + +typedef struct tagHwTmrTCR { + UINT16 rsvd1 : 4; // 3:0 Reserved + UINT16 TSS : 1; // 4 Timer Start/Stop + UINT16 TRB : 1; // 5 Timer reload + UINT16 rsvd2 : 4; // 9:6 Reserved + UINT16 SOFT : 1; // 10 Emulation modes + UINT16 FREE : 1; // 11 + UINT16 rsvd3 : 2; // 12:13 Reserved + UINT16 TIE : 1; // 14 Output enable + UINT16 TIF : 1; // 15 Interrupt flag +} HWTMR_TCR; + +typedef struct tagHwTmr { + volatile UINT32 vuwTIM; + volatile UINT32 vuwPRD; + volatile HWTMR_TCR stTCR; + volatile UINT16 vusReserved; + volatile UINT16 vusTPR; + volatile UINT16 vusTPRH; +} OS_HWTMR_S; + +extern OS_HWTMR_S *g_pstHwTmrMap; +extern VOID LOS_GetCpuTick(UINT32 *puwCntHi, UINT32 *puwCntLo); +extern VOID ItSuiteLosEvent(VOID); + +#if defined(LOSCFG_TEST_SMOKE) +extern VOID ItLosEvent031(VOID); +extern VOID ItLosEvent035(VOID); +extern VOID ItLosEvent036(VOID); +extern VOID ItLosEvent041(VOID); +#endif + +#if defined(LOSCFG_TEST_FULL) +extern VOID ItLosEvent001(VOID); +extern VOID ItLosEvent002(VOID); +extern VOID ItLosEvent003(VOID); +extern VOID ItLosEvent004(VOID); +extern VOID ItLosEvent005(VOID); +extern VOID ItLosEvent006(VOID); +extern VOID ItLosEvent007(VOID); +extern VOID ItLosEvent008(VOID); +extern VOID ItLosEvent009(VOID); +extern VOID ItLosEvent010(VOID); +extern VOID ItLosEvent011(VOID); +extern VOID ItLosEvent012(VOID); +extern VOID ItLosEvent013(VOID); +extern VOID ItLosEvent014(VOID); +extern VOID ItLosEvent015(VOID); +extern VOID ItLosEvent016(VOID); +extern VOID ItLosEvent018(VOID); +extern VOID ItLosEvent019(VOID); +extern VOID ItLosEvent020(VOID); +extern VOID ItLosEvent021(VOID); +extern VOID ItLosEvent022(VOID); +extern VOID ItLosEvent023(VOID); +extern VOID ItLosEvent024(VOID); +extern VOID ItLosEvent025(VOID); +extern VOID ItLosEvent026(VOID); +extern VOID ItLosEvent027(VOID); +extern VOID ItLosEvent029(VOID); +extern VOID ItLosEvent030(VOID); +extern VOID ItLosEvent032(VOID); +extern VOID ItLosEvent033(VOID); +extern VOID ItLosEvent037(VOID); +extern VOID ItLosEvent038(VOID); +extern VOID ItLosEvent039(VOID); +extern VOID ItLosEvent040(VOID); +extern VOID ItLosEvent042(VOID); +extern VOID ItLosEvent043(VOID); +#endif + +#if defined(LOSCFG_TEST_PRESSURE) +extern VOID ItLosEvent028(VOID); +#endif +#if defined(LOSCFG_TEST_LLT) +extern VOID LltLosEvent001(VOID); +extern VOID ItLosEvent017(VOID); +extern VOID ItLosEvent034(VOID); +#endif + +#ifdef LOSCFG_KERNEL_SMP +VOID ItSmpLosEvent001(VOID); +VOID ItSmpLosEvent002(VOID); +VOID ItSmpLosEvent003(VOID); +VOID ItSmpLosEvent004(VOID); +VOID ItSmpLosEvent005(VOID); +VOID ItSmpLosEvent006(VOID); +VOID ItSmpLosEvent007(VOID); +VOID ItSmpLosEvent008(VOID); +VOID ItSmpLosEvent009(VOID); +VOID ItSmpLosEvent010(VOID); +VOID ItSmpLosEvent011(VOID); +VOID ItSmpLosEvent012(VOID); +VOID ItSmpLosEvent013(VOID); +VOID ItSmpLosEvent014(VOID); +VOID ItSmpLosEvent015(VOID); +VOID ItSmpLosEvent016(VOID); +VOID ItSmpLosEvent017(VOID); +VOID ItSmpLosEvent018(VOID); +VOID ItSmpLosEvent019(VOID); +VOID ItSmpLosEvent020(VOID); +VOID ItSmpLosEvent021(VOID); +VOID ItSmpLosEvent022(VOID); +VOID ItSmpLosEvent023(VOID); +VOID ItSmpLosEvent024(VOID); +VOID ItSmpLosEvent025(VOID); +VOID ItSmpLosEvent026(VOID); +VOID ItSmpLosEvent027(VOID); +VOID ItSmpLosEvent028(VOID); +VOID ItSmpLosEvent029(VOID); +VOID ItSmpLosEvent030(VOID); +VOID ItSmpLosEvent031(VOID); +VOID ItSmpLosEvent032(VOID); +VOID ItSmpLosEvent033(VOID); +VOID ItSmpLosEvent034(VOID); +VOID ItSmpLosEvent035(VOID); +VOID ItSmpLosEvent036(VOID); +VOID ItSmpLosEvent037(VOID); +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#endif /* IT_LOS_EVENT_H */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_001.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_001.c new file mode 100644 index 00000000..6b46ebb7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_001.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + g_testCount++; + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, g_event.uwEventID, ret); + ICUNIT_ASSERT_EQUAL_VOID(g_event.uwEventID, 0x11, g_event.uwEventID); + + g_testCount++; + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = {0}; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "EventTsk1"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 2; // 2, set new task priority, it is higher than the current task. + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + g_testCount = 0; + g_event.uwEventID = 0; + LOS_EventInit(&g_event); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + TestExtraTaskDelay(1); + + ret = LOS_EventWrite(&g_event, 0x10); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + TestExtraTaskDelay(2); // 2, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + ret = LOS_EventWrite(&g_event, 0x1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + TestExtraTaskDelay(2); // 2, delay enouge time + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, Here, assert that g_testCount is equal to 2. + + return LOS_OK; +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + LOS_EventDestroy(&g_event); + return LOS_OK; +} + +VOID ItLosEvent001(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosEvent001", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_002.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_002.c new file mode 100644 index 00000000..032e53a5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_002.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + g_testCount++; + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, 3); // 3, The timeout period for reading events. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_EVENT_READ_TIMEOUT, ret, EXIT); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, Here, assert that g_testCount is equal to 2. + g_testCount++; + + ret = LOS_EventRead(&g_event, 0x4, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = {0}; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "EventTsk2"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 2; // 2, set new task priority, it is higher than the current task. + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + g_testCount = 0; + g_event.uwEventID = 0; + LOS_EventInit(&g_event); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + TestExtraTaskDelay(1); + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + g_testCount++; + + LOS_EventWrite(&g_event, 0x2); + + LOS_TaskDelay(3); // 3, delay enouge time + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, Here, assert that g_testCount is equal to 3. + g_testCount++; + + LOS_EventWrite(&g_event, 0x11); + + LOS_TaskDelay(4); // 4, delay enouge time + + ICUNIT_ASSERT_EQUAL(g_testCount, 4, g_testCount); // 4, Here, assert that g_testCount is equal to 4. + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosEvent002(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosEvent002", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_003.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_003.c new file mode 100644 index 00000000..bf8a5fb1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_003.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + g_testCount++; + + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, 10); // 10, The timeout period for reading events. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_EVENT_READ_TIMEOUT, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + g_testCount++; +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_EventDestroy(&g_event); +} +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = {0}; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "EventTsk3"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 2; // 2, set new task priority, it is higher than the current task. + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + g_testCount = 0; + g_event.uwEventID = 0; + + LOS_EventInit(&g_event); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + TestExtraTaskDelay(1); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + g_testCount++; + + TestAssertBusyTaskDelay(100, 3); // 100, Set the timeout of runtime; 3, test running count + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, Here, assert that g_testCount is equal to 3. +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_EventDestroy(&g_event); + + return LOS_OK; +} + +VOID ItLosEvent003(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosEvent003", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_004.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_004.c new file mode 100644 index 00000000..566cadca --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_004.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_EventRead(&g_event, 0xFFFFFFFF, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_EVENT_SETBIT_INVALID, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = {0}; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "EventTsk4"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 2; // 2, set new task priority, it is higher than the current task. + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + g_testCount = 0; + + g_event.uwEventID = 0; + LOS_EventInit(&g_event); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + TestExtraTaskDelay(2); // 2, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + + g_testCount++; + + ret = LOS_EventWrite(&g_event, 0xFFFFFFFF); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_EVENT_SETBIT_INVALID, ret, EXIT1); + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT1); // 3, Here, assert that g_testCount is equal to 3. + +EXIT1: + + ret = LOS_EventClear(&g_event, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + return LOS_OK; +} + +VOID ItLosEvent004(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosEvent004", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_005.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_005.c new file mode 100644 index 00000000..bdfecffa --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_005.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + + ret = LOS_EventWrite(NULL, 0x1); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_EVENT_PTR_NULL, ret); + + g_event.uwEventID = 0; + LOS_EventInit(&g_event); + + LOS_EventWrite(&g_event, 0x1); + ICUNIT_GOTO_EQUAL(g_event.uwEventID, 1, g_event.uwEventID, EXIT); + + LOS_EventWrite(&g_event, 0); + ICUNIT_GOTO_EQUAL(g_event.uwEventID, 1, g_event.uwEventID, EXIT); + + LOS_EventWrite(&g_event, 0x10); + ICUNIT_GOTO_EQUAL(g_event.uwEventID, 0x11, g_event.uwEventID, EXIT); + + ret = LOS_EventWrite(&g_event, 0xFFFFFFFF); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_EVENT_SETBIT_INVALID, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_event.uwEventID, 0x11, g_event.uwEventID, EXIT); +EXIT: + + ret = LOS_EventClear(&g_event, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosEvent005(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosEvent005", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_006.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_006.c new file mode 100644 index 00000000..930d1617 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_006.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_EventRead(&g_event, 0x00000110, LOS_WAITMODE_OR, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, g_event.uwEventID, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_event.uwEventID, 0x10, g_event.uwEventID, EXIT); + + g_testCount++; + + ret = LOS_EventRead(&g_event, 0x00000110, LOS_WAITMODE_AND, 4); // 4, The timeout period for reading events. + ICUNIT_GOTO_EQUAL(ret, g_event.uwEventID, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_event.uwEventID, 0x110, g_event.uwEventID, EXIT); + + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = {0}; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "EventTsk6"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 2; // 2, set new task priority, it is higher than the current task. + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + g_testCount = 0; + + g_event.uwEventID = 0; + LOS_EventInit(&g_event); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + TestExtraTaskDelay(2); // 2, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + g_testCount++; + + LOS_EventWrite(&g_event, 0x10); + TestExtraTaskDelay(2); // 2, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT1); // 3, Here, assert that g_testCount is equal to 3. + + g_testCount++; + + LOS_EventWrite(&g_event, 0x110); + TestExtraTaskDelay(2); // 2, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT1); // 5, Here, assert that g_testCount is equal to 5. + +EXIT1: + + ret = LOS_EventClear(&g_event, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +VOID ItLosEvent006(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosEvent006", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_007.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_007.c new file mode 100644 index 00000000..890f8c82 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_007.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + UINT32 event; + + g_testCount++; + + g_event.uwEventID = 0; + LOS_EventInit(&g_event); + + LOS_EventWrite(&g_event, 0x10); + + ret = LOS_EventRead(&g_event, 0x00000110, LOS_WAITMODE_OR, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, g_event.uwEventID, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_event.uwEventID, 0x10, g_event.uwEventID, EXIT); + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + g_testCount++; + + LOS_EventWrite(&g_event, 0x110); + ICUNIT_GOTO_EQUAL(g_event.uwEventID, 0x110, g_event.uwEventID, EXIT); + + ret = LOS_EventRead(&g_event, 0x00000110, LOS_WAITMODE_AND, 0); + ICUNIT_GOTO_EQUAL(ret, g_event.uwEventID, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_event.uwEventID, 0x110, g_event.uwEventID, EXIT); + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + + g_testCount++; + + ret = LOS_EventRead(&g_event, 0x00000011, LOS_WAITMODE_AND, 0); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_event.uwEventID, 0x110, g_event.uwEventID, EXIT); + + g_testCount++; + +EXIT: + + ret = LOS_EventClear(&g_event, 0); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = {0}; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "EventTsk7"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 2; // 2, set new task priority, it is higher than the current task. + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + TestExtraTaskDelay(2); // 2, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, Here, assert that g_testCount is equal to 4. + +EXIT: + LOS_TaskDelete(g_testTaskID01); + return LOS_OK; +} + +VOID ItLosEvent007(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosEvent007", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_008.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_008.c new file mode 100644 index 00000000..27e60a74 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_008.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_EventRead(&g_event, 0, LOS_WAITMODE_OR, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_EVENT_EVENTMASK_INVALID, ret, EXIT); + + g_testCount++; + + ret = LOS_EventRead(&g_event, 0x0FFFFFFF, LOS_WAITMODE_OR, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_EVENT_SETBIT_INVALID, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = {0}; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "EventTsk8"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 2; // 2, set new task priority, it is higher than the current task. + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + g_testCount = 0; + + g_event.uwEventID = 0; + LOS_EventInit(&g_event); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + TestExtraTaskDelay(2); // 2, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, Here, assert that g_testCount is equal to 3. + + g_testCount++; + + LOS_EventWrite(&g_event, 0x10011); + ICUNIT_GOTO_EQUAL(g_event.uwEventID, 0x10011, g_event.uwEventID, EXIT1); + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT1); // 4, Here, assert that g_testCount is equal to 4. + +EXIT1: + + ret = LOS_EventClear(&g_event, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +VOID ItLosEvent008(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosEvent008", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_009.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_009.c new file mode 100644 index 00000000..63f734cf --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_009.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + g_testCount++; + ret = LOS_EventRead(NULL, 0x11, LOS_WAITMODE_OR, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_EVENT_PTR_NULL, ret, EXIT); + + ret = LOS_EventRead(&g_event, 0, LOS_WAITMODE_OR, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_EVENT_EVENTMASK_INVALID, ret, EXIT); + + ret = LOS_EventRead(&g_event, 0xffffffff, LOS_WAITMODE_OR, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_EVENT_SETBIT_INVALID, ret, EXIT); + g_testCount++; + + ret = LOS_EventRead(&g_event, 0x11, 0xffffffff, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_EVENT_FLAGS_INVALID, ret, EXIT); + + ret = LOS_EventRead(&g_event, 0x11, 0, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_EVENT_FLAGS_INVALID, ret, EXIT); + + ret = LOS_EventRead(&g_event, 0x11, (LOS_WAITMODE_AND | LOS_WAITMODE_OR | LOS_WAITMODE_CLR), LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_EVENT_FLAGS_INVALID, ret, EXIT); + + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = {0}; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "EventTsk9"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + // 24, Set the priority according to the task purpose,a smaller number means a higher priority. + task1.usTaskPrio = 24; + + g_testCount = 0; + g_event.uwEventID = 0; + + LOS_EventInit(&g_event); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + TestExtraTaskDelay(2); // 2, delay enouge time + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, Here, assert that g_testCount is equal to 3. + + return LOS_OK; +} + +VOID ItLosEvent009(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosEvent009", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_010.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_010.c new file mode 100644 index 00000000..4ddddb6e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_010.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_EventRead(&g_event, 0x1, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, 0x1, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, Here, assert that g_testCount is equal to 3. + + g_testCount++; + + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, g_event.uwEventID, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_event.uwEventID, 0x11, g_event.uwEventID, EXIT); + + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = {0}; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "EventTsk10"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 2; // 2, set new task priority, it is higher than the current task. + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + g_testCount = 0; + LOS_EventInit(&g_event); + + ret = LOS_EventRead(&g_event, 0x1, LOS_WAITMODE_AND, 1); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_EVENT_READ_TIMEOUT, ret, EXIT); + + ret = LOS_EventRead(&g_event, 0x1, LOS_WAITMODE_AND, 1); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_EVENT_READ_TIMEOUT, ret, EXIT); + + ret = LOS_EventRead(&g_event, 0x1, LOS_WAITMODE_AND, 2); // 2, The timeout period for reading events. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_EVENT_READ_TIMEOUT, ret, EXIT); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + TestExtraTaskDelay(2); // 2, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + g_testCount++; + + ret = LOS_EventWrite(&g_event, 0x10); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT1); // 2, Here, assert that g_testCount is equal to 2. + + g_testCount++; + + ret = LOS_EventWrite(&g_event, 0x1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + TestExtraTaskDelay(2); // 2, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT1); // 5, Here, assert that g_testCount is equal to 5. + +EXIT1: + ret = LOS_EventClear(&g_event, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +VOID ItLosEvent010(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosEvent010", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_011.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_011.c new file mode 100644 index 00000000..83b447e3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_011.c @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, 5); // 5, The timeout period for reading events. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_EVENT_READ_TIMEOUT, ret, EXIT); + + g_testCount++; + + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, 0); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, 0); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testCount++; + + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + ICUNIT_GOTO_NOT_EQUAL(ret, g_event.uwEventID, ret, EXIT); + ICUNIT_GOTO_EQUAL(ret, 0x11, ret, EXIT); + + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = {0}; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "EventTsk11"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 2; // 2, set new task priority, it is higher than the current task. + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + g_testCount = 0; + + LOS_EventInit(&g_event); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + TestExtraTaskDelay(1); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + g_testCount++; + + LOS_EventWrite(&g_event, 0x100); + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT1); // 2, Here, assert that g_testCount is equal to 2. + + g_testCount++; + + LOS_EventWrite(&g_event, 0x1000); + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT1); // 3, Here, assert that g_testCount is equal to 3. + + g_testCount++; + + LOS_EventWrite(&g_event, 0x10000); + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT1); // 4, Here, assert that g_testCount is equal to 4. + + g_testCount++; + + LOS_TaskDelay(10); // 10, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, 7, g_testCount, EXIT1); // 7, Here, assert that g_testCount is equal to 7. + + ret = LOS_EventWrite(&g_event, 0x11); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + TestExtraTaskDelay(2); // 2, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, 8, g_testCount, EXIT1); // 8, Here, assert that g_testCount is equal to 8. + +EXIT1: + ret = LOS_EventClear(&g_event, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +VOID ItLosEvent011(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosEvent011", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_012.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_012.c new file mode 100644 index 00000000..8a68e30d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_012.c @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_EventRead(&g_event, 0x110, LOS_WAITMODE_OR, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, 0x10, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_event.uwEventID, 0x11010, g_event.uwEventID, EXIT); + + g_testCount++; + + ret = LOS_EventRead(&g_event, 0x1001, LOS_WAITMODE_OR, 0); + ICUNIT_GOTO_EQUAL(ret, 0x1000, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_event.uwEventID, 0x11010, g_event.uwEventID, EXIT); + + g_testCount++; + + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, 2); // 2, The timeout period for reading events. + ICUNIT_GOTO_EQUAL(ret, 0x11, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_event.uwEventID, 0x11011, g_event.uwEventID, EXIT); + + g_testCount++; + + ret = LOS_EventRead(&g_event, 0x1100, LOS_WAITMODE_AND, 0); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + + TSK_INIT_PARAM_S task1 = {0}; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "EventTsk12"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 2; // 2, set new task priority, it is higher than the current task. + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + g_testCount = 0; + LOS_EventInit(&g_event); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + TestExtraTaskDelay(1); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + g_testCount++; + + ret = LOS_EventWrite(&g_event, 0x11010); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + TestExtraTaskDelay(1); + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT1); // 4, Here, assert that g_testCount is equal to 4. + + g_testCount++; + + ret = LOS_EventWrite(&g_event, 0x1001); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + + LOS_TaskDelay(3); // 3, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, 7, g_testCount, EXIT1); // 7, Here, assert that g_testCount is equal to 7. + +EXIT1: + ret = LOS_EventClear(&g_event, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +VOID ItLosEvent012(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosEvent012", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_013.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_013.c new file mode 100644 index 00000000..5c88cbe9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_013.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_OR, LOS_WAIT_FOREVER); + ICUNIT_GOTO_NOT_EQUAL(ret, g_event.uwEventID, ret, EXIT); + ICUNIT_GOTO_EQUAL(ret, 0x11, ret, EXIT); + + g_testCount++; + + ret = LOS_EventRead(&g_event, 0x1100, LOS_WAITMODE_AND, 0); + ICUNIT_GOTO_NOT_EQUAL(ret, g_event.uwEventID, ret, EXIT); + ICUNIT_GOTO_EQUAL(ret, 0x1100, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_event.uwEventID, 0x11111111, g_event.uwEventID, EXIT); + + g_testCount++; + + ret = LOS_EventRead(&g_event, 0x110000, LOS_WAITMODE_AND | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, 0x110000, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_event.uwEventID, 0x11001111, g_event.uwEventID, EXIT); + + g_testCount++; + + ret = LOS_EventRead(&g_event, 0x11000000, LOS_WAITMODE_OR | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, 0x11000000, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_event.uwEventID, 0x00001111, g_event.uwEventID, EXIT); + + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = {0}; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "EventTsk13"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 2; // 2, set new task priority, it is higher than the current task. + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + g_testCount = 0; + LOS_EventInit(&g_event); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + TestExtraTaskDelay(2); // 2, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + g_testCount++; + + LOS_EventWrite(&g_event, 0x11111111); + TestExtraTaskDelay(2); // 2, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, 6, g_testCount, EXIT1); // 6, Here, assert that g_testCount is equal to 3. + +EXIT1: + ret = LOS_EventClear(&g_event, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +VOID ItLosEvent013(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosEvent013", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_014.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_014.c new file mode 100644 index 00000000..75051c1c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_014.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + g_testCount++; + + ret = LOS_EventRead(&g_event, 0x01, LOS_WAITMODE_OR, 0); + ICUNIT_GOTO_EQUAL(ret, 0x01, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_event.uwEventID, 0x11, g_event.uwEventID, EXIT); + + g_testCount++; + + ret = LOS_EventRead(&g_event, 0x01, LOS_WAITMODE_OR, 0); + ICUNIT_GOTO_EQUAL(ret, 0x01, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_event.uwEventID, 0x11, g_event.uwEventID, EXIT); + + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = {0}; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "EventTsk14"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 2; // 2, set new task priority, it is higher than the current task. + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + g_testCount = 0; + LOS_EventInit(&g_event); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + TestExtraTaskDelay(2); // 2, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + g_testCount++; + + ret = LOS_EventWrite(&g_event, 0x11); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + + ret = LOS_EventWrite(&g_event, 0x11); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + + ret = LOS_TaskResume(g_testTaskID01); + TestExtraTaskDelay(2); // 2, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT1); // 5, Here, assert that g_testCount is equal to 5. + +EXIT1: + ret = LOS_EventClear(&g_event, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +VOID ItLosEvent014(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosEvent014", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_015.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_015.c new file mode 100644 index 00000000..c25036b2 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_015.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + g_testCount++; + + LOS_TaskDelay(10); // 10, delay enouge time + + g_testCount++; + + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, 0); + ICUNIT_GOTO_EQUAL(ret, 0x11, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_event.uwEventID, 0x1111, g_event.uwEventID, EXIT); + + g_testCount++; + ret = LOS_EventRead(&g_event, 0x1100, LOS_WAITMODE_AND, 2); // 2, The timeout period for reading events. + ICUNIT_GOTO_EQUAL(ret, 0x1100, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_event.uwEventID, 0x1111, g_event.uwEventID, EXIT); + + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = {0}; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "EventTsk15"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 2; // 2, set new task priority, it is higher than the current task. + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + g_testCount = 0; + LOS_EventInit(&g_event); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + do { + __asm__ volatile("nop"); + } while (g_testCount < 1); + + LOS_EventWrite(&g_event, 0x1111); + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + TestAssertBusyTaskDelay(100, 4); // 100, Set the timeout of runtime; 4, test running count + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT1); // 4, Here, assert that g_testCount is equal to 4. + +EXIT1: + ret = LOS_EventClear(&g_event, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_EventDestroy(&g_event); + return LOS_OK; +} + +VOID ItLosEvent015(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosEvent015", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_016.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_016.c new file mode 100644 index 00000000..d8f96bc1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_016.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + g_testCount++; + + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, 0); + ICUNIT_GOTO_EQUAL(ret, g_event.uwEventID, ret, EXIT); + + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = {0}; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "EventTsk16"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 2; // 2, set new task priority, it is higher than the current task. + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + g_testCount = 0; + LOS_EventInit(&g_event); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + TestExtraTaskDelay(2); // 2, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + g_testCount++; + + LOS_EventWrite(&g_event, 0x11); + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT1); // 2, Here, assert that g_testCount is equal to 2. + +EXIT1: + ret = LOS_EventClear(&g_event, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +VOID ItLosEvent016(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosEvent016", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_018.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_018.c new file mode 100644 index 00000000..a7464cb5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_018.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF02(VOID) +{ + UINT32 ret; + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + g_testCount++; + + ret = LOS_EventWrite(&g_event, 0x10); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); +#ifndef LOSCFG_KERNEL_SMP + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, Here, assert that g_testCount is equal to 4. +#endif + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID02); +} + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_EventRead(&g_event, 0x10, LOS_WAITMODE_AND, 10); // 10, The timeout period for reading events. + ICUNIT_GOTO_EQUAL(ret, 0x10, ret, EXIT); + ICUNIT_GOTO_EQUAL(ret, g_event.uwEventID, ret, EXIT); + + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = {0}; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "EvtTsk18A"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 2; // 2, set new task priority, it is higher than the current task. + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + g_testCount = 0; + LOS_EventInit(&g_event); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + TestExtraTaskDelay(1); + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + g_testCount++; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.pcName = "EvtTs18B"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + TestExtraTaskDelay(1); + + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ICUNIT_ASSERT_EQUAL(g_testCount, 5, g_testCount); // 5, Here, assert that g_testCount is equal to 5. + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + + return LOS_OK; +} + +VOID ItLosEvent018(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosEvent018", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} + +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_019.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_019.c new file mode 100644 index 00000000..e7563697 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_019.c @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF02(VOID) +{ + UINT32 ret; + UINT32 index = 10000 - 1; // 10000 - 1, init + UINT32 value; + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + g_testCount++; + + ret = LOS_EventWrite(&g_event, 0x10); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, Here, assert that g_testCount is equal to 3. + g_testCount++; + HAL_READ_UINT32(&index, value); + + while (value < 10000) { // 10000, loop num + HAL_READ_UINT32(&index, value); + index--; + } + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, Here, assert that g_testCount is equal to 4. + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID02); +} + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + ICUNIT_GOTO_NOT_EQUAL(ret, LOS_OK, ret, EXIT); + + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = {0}; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "EvtTsk19A"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + g_testCount = 0; + LOS_EventInit(&g_event); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + TestExtraTaskDelay(2); // 2, delay enouge time + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + g_testCount++; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.pcName = "EvTsk19B"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 2; // 2, set new task priority, it is higher than the current task. + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + + LOS_TaskDelay(10); // 10, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT1); // 5, Here, assert that g_testCount is equal to 5. +EXIT1: + LOS_TaskDelete(g_testTaskID02); +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_EventDestroy(&g_event); + + return LOS_OK; +} + +VOID ItLosEvent019(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosEvent019", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_020.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_020.c new file mode 100644 index 00000000..0d3ecd97 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_020.c @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF02(VOID) +{ + UINT32 ret; + UINT32 index = 10000 - 1; // 10000 - 1, init + UINT32 value; + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + g_testCount++; + + HAL_READ_UINT32(&index, value); + + while (value < 10000) { // 10000, loop num + HAL_READ_UINT32(&index, value); + index--; + } + + ret = LOS_EventWrite(&g_event, 0x11); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, Here, assert that g_testCount is equal to 3. + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID02); +} + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_OR, 20); // 20, The timeout period for reading events. + ICUNIT_GOTO_EQUAL(ret, g_event.uwEventID, ret, EXIT); + ICUNIT_GOTO_EQUAL(ret, 0x11, ret, EXIT); + + g_testCount++; + + LOS_TaskDelay(30); // 30, delay enouge time + +EXIT: + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = {0}; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "EvtTsk20A"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + g_testCount = 0; + LOS_EventInit(&g_event); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + TestExtraTaskDelay(2); // 2, delay enouge time + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + g_testCount++; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.pcName = "EvtTsk20B"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 2; // 2, set new task priority, it is higher than the current task. + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + TestExtraTaskDelay(2); // 2, delay enouge time + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT1); // 5, Here, assert that g_testCount is equal to 5. + +EXIT1: + LOS_TaskDelete(g_testTaskID02); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_EventDestroy(&g_event); + + return LOS_OK; +} + +VOID ItLosEvent020(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosEvent020", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_021.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_021.c new file mode 100644 index 00000000..7b1e1673 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_021.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF02(VOID) +{ + UINT32 ret; + + g_testCount++; + + LOS_EventWrite(&g_event, 0x11); + + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID02); +} + +static VOID TaskF01(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = {0}; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.pcName = "EvtTsk21B"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 2; // 2, set new task priority, it is higher than the current task. + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + g_testCount++; + + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + TestExtraTaskDelay(1); + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, Here, assert that g_testCount is equal to 3. + + g_testCount++; + + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, 0); + ICUNIT_GOTO_EQUAL(ret, g_event.uwEventID, ret, EXIT); + + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = {0}; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "EvtTsk21A"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + g_testCount = 0; + LOS_EventInit(&g_event); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + TestExtraTaskDelay(5); // 5, delay enouge time + + ICUNIT_ASSERT_EQUAL(g_testCount, 5, g_testCount); // 5, Here, assert that g_testCount is equal to 5. + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +VOID ItLosEvent021(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosEvent021", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_022.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_022.c new file mode 100644 index 00000000..bd635ce2 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_022.c @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF02(VOID) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_EventWrite(&g_event, 0x11); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID02); +} + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, g_event.uwEventID, ret, EXIT); + + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = {0}; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "EvtTsk22A"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 2; // 2, set new task priority, it is higher than the current task. + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + g_testCount = 0; + LOS_EventInit(&g_event); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + TestExtraTaskDelay(2); // 2, delay enouge time + + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + g_testCount++; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.pcName = "EvtTsk22B"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + TestExtraTaskDelay(2); // 2, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT1); // 4, Here, assert that g_testCount is equal to 4. + g_testCount++; + + ret = LOS_TaskResume(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + TestExtraTaskDelay(2); // 2, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, 6, g_testCount, EXIT1); // 6, Here, assert that g_testCount is equal to 3. + +EXIT1: + LOS_TaskDelete(g_testTaskID02); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +VOID ItLosEvent022(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosEvent022", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_023.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_023.c new file mode 100644 index 00000000..86865e17 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_023.c @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID HwiF01(VOID) +{ + UINT32 ret; + + TEST_HwiClear(HWI_NUM_TEST); + + g_testCount++; + + ret = LOS_EventWrite(&g_event, 0x11); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; +} + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, g_event.uwEventID, ret, EXIT); + ICUNIT_ASSERT_EQUAL_VOID(ret, 0x11, ret); + +#ifndef LOSCFG_KERNEL_SMP + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); // 5, Here, assert that g_testCount is equal to 5. +#endif + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID01); +} + +static VOID TaskF02(VOID) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, g_event.uwEventID, ret, EXIT); + ICUNIT_ASSERT_EQUAL_VOID(ret, 0x11, ret); + +#ifndef LOSCFG_KERNEL_SMP + ICUNIT_GOTO_EQUAL(g_testCount, 6, g_testCount, EXIT); // 6, Here, assert that g_testCount is equal to 6. +#endif + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID02); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = {0}; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "EvtTsk23A"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 2; // 2, set new task priority, it is higher than the current task. + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + g_testCount = 0; + LOS_EventInit(&g_event); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.pcName = "EvtTsk23B"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 1; + + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + TestExtraTaskDelay(2); // 2, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT1); // 2, Here, assert that g_testCount is equal to 2. + g_testCount++; + + ret = LOS_HwiCreate(HWI_NUM_TEST, 0, 0, HwiF01, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + TestHwiTrigger(HWI_NUM_TEST); + + LOS_TaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 7, g_testCount); // 7, Here, assert that g_testCount is equal to 7. + + TEST_HwiDelete(HWI_NUM_TEST); + +EXIT1: + LOS_TaskDelete(g_testTaskID02); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +VOID ItLosEvent023(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosEvent023", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_024.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_024.c new file mode 100644 index 00000000..32d754be --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_024.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID HwiF01(VOID) +{ + UINT32 ret; + + TEST_HwiClear(HWI_NUM_TEST); + g_testCount++; + + ret = LOS_EventRead(&g_event, 0x1, LOS_WAITMODE_AND, 10); // 10, The timeout period for reading events. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_EVENT_READ_IN_INTERRUPT, ret); + + g_testCount++; +} +static UINT32 Testcase(VOID) +{ + UINT32 ret; + + g_testCount = 0; + LOS_EventInit(&g_event); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + TestHwiTrigger(HWI_NUM_TEST); + TestExtraTaskDelay(2); // 2, delay enouge time + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, Here, assert that g_testCount is equal to 2. + +EXIT: + TEST_HwiDelete(HWI_NUM_TEST); + + return LOS_OK; +} + +VOID ItLosEvent024(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosEvent024", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_025.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_025.c new file mode 100644 index 00000000..51a81143 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_025.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +extern VOID LOS_GetCpuCycle(UINT32 *puwCntHi, UINT32 *puwCntLo); + +static UINT64 TestGetCurCycle(VOID) +{ + UINT32 cntHi; + UINT32 cntLo; + UINT64 curCycle; + + LOS_GetCpuCycle(&cntHi, &cntLo); + curCycle = ((UINT64)cntHi << 32) | cntLo; // 32, High byte + + return curCycle; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT64 osEndTime; + UINT64 osStartTime; + UINT32 tickNum; + LOS_EventInit(&g_event); + + osStartTime = TestGetCurCycle(); + + ret = LOS_EventRead(&g_event, 0x1, LOS_WAITMODE_AND, 10); // 10, The timeout period for reading events. + + osEndTime = TestGetCurCycle(); + + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_EVENT_READ_TIMEOUT, ret); + + tickNum = (osEndTime - osStartTime) * LOSCFG_BASE_CORE_TICK_PER_SECOND / OS_SYS_CLOCK; + + if (tickNum < (10 - 2) || tickNum > (10 + 2)) { // when tick num in 10 - 2 or 10 + 2 interval + ICUNIT_ASSERT_EQUAL(tickNum, 0, tickNum); + } + ret = LOS_EventClear(&g_event, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosEvent025(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosEvent025", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_026.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_026.c new file mode 100644 index 00000000..74064d8d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_026.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + LOS_TaskLock(); + + g_testCount++; + + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, g_event.uwEventID, ret, EXIT); + ICUNIT_GOTO_EQUAL(ret, 0x11, ret, EXIT); + + g_testCount++; + + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, 0); + ICUNIT_GOTO_EQUAL(ret, g_event.uwEventID, ret, EXIT); + ICUNIT_GOTO_EQUAL(ret, 0x11, ret, EXIT); + + g_testCount++; + + LOS_TaskUnlock(); + +EXIT: + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = {0}; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "EventTsk26"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 2; // 2, set new task priority, it is higher than the current task. + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + LOS_EventInit(&g_event); + LOS_TaskLock(); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + LOS_EventWrite(&g_event, 0x11); + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT1); + + LOS_TaskUnlock(); + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT1); // 3, Here, assert that g_testCount is equal to 3. + +EXIT1: + ret = LOS_EventClear(&g_event, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosEvent026(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosEvent026", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_027.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_027.c new file mode 100644 index 00000000..5754cbd9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_027.c @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_testeventCount1; +static UINT32 g_eventMask; + +static VOID SwtmrF01(VOID) +{ + UINT32 ret; + + g_testCount++; + + g_eventMask = g_eventMask | (1 << g_testCount); + + if (g_testCount > 17) { // g_testCount > 17, do noting return + return; + } + + ret = LOS_EventWrite(&g_event, g_eventMask); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); +} + +static VOID TaskF01(VOID) +{ + UINT32 ret; + int value; + HAL_READ_UINT32(&g_testCount, value); + + while (value < 16) { // if value < 16, read + HAL_READ_UINT32(&g_testCount, value); + } + + ret = LOS_EventRead(&g_event, 0x1FFFF, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, g_event.uwEventID, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_event.uwEventID, 0x1FFFF, g_event.uwEventID, EXIT); + + g_testCount1++; + +EXIT: + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + + UINT16 swTmrID; + + TSK_INIT_PARAM_S task1 = {0}; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "EventTsk27"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 2; // 2, set new task priority, it is higher than the current task. + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + g_testCount = 0; + g_testeventCount1 = 0; + g_eventMask = 1; + g_testCount1 = 0; + + LOS_EventInit(&g_event); + + ret = LOS_SwtmrCreate(2, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)SwtmrF01, &swTmrID, 0xffff); // 2, Timeout interval of a periodic software timer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrStart(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + + LOS_TaskDelay(32 + TEST_TASKDELAY_2TICK); // 32 + TEST_TASKDELAY_2TICK, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount1, 1, g_testCount1, EXIT1); + +EXIT1: + LOS_TaskDelete(g_testTaskID01); + +EXIT: + LOS_SwtmrDelete(swTmrID); + return LOS_OK; +} + +VOID ItLosEvent027(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosEvent027", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_029.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_029.c new file mode 100644 index 00000000..3ac2c858 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_029.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + UINT32 index; + + for (index = 0; index < 0xFF00; index++) { + ret = LOS_EventWrite(&g_event, 0xFF); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + +EXIT: + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 event; + TSK_INIT_PARAM_S task1 = {0}; + LOS_EventInit(&g_event); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "EventTsk29"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 2; // 2, set new task priority, it is higher than the current task. + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + TestExtraTaskDelay(2); // 2, delay enouge time + + ret = LOS_EventRead(&g_event, 0xFF, LOS_WAITMODE_AND, 0); + ICUNIT_GOTO_EQUAL(ret, g_event.uwEventID, ret, EXIT1); + ICUNIT_GOTO_EQUAL(g_event.uwEventID, 0xFF, g_event.uwEventID, EXIT1); + +EXIT1: + + ret = LOS_EventClear(&g_event, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +VOID ItLosEvent029(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosEvent029", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_030.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_030.c new file mode 100644 index 00000000..d52f38d3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_030.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, 3); // 3, The timeout period for reading events. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_EVENT_READ_TIMEOUT, ret, EXIT); + +EXIT: + LOS_TaskDelete(g_testTaskID01); +} +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = {0}; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "EventTsk30"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 2; // 2, set new task priority, it is higher than the current task. + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + g_testCount = 0; + g_event.uwEventID = 1; + LOS_EventInit(&g_event); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + TestExtraTaskDelay(2); // 2, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + LOS_TaskDelay(35); // 35, delay enouge time + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +VOID ItLosEvent030(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosEvent030", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_032.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_032.c new file mode 100644 index 00000000..8d844212 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_032.c @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ret = LOS_EventRead(&g_event, 0xF, LOS_WAITMODE_AND, 30); // 30, The timeout period for reading events. + ICUNIT_GOTO_NOT_EQUAL(ret, g_event.uwEventID, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID01); +} + +static VOID TaskF02(VOID) +{ + UINT32 ret; + + ret = LOS_EventRead(&g_event, 0xF, LOS_WAITMODE_AND, 31); // 31, The timeout period for reading events. + ICUNIT_GOTO_NOT_EQUAL(ret, g_event.uwEventID, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + g_testCount++; + +EXIT: + + LOS_TaskDelete(g_testTaskID02); +} + +static VOID TaskF03(VOID) +{ + UINT32 ret; + + ret = LOS_EventRead(&g_event, 0xF, LOS_WAITMODE_AND, 32); // 32, The timeout period for reading events. + ICUNIT_GOTO_NOT_EQUAL(ret, g_event.uwEventID, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID03); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = {0}; + + g_testCount = 0; + LOS_EventInit(&g_event); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "EventTsk32A"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 3; // 3, Set the priority according to the task purpose,a smaller number means a higher priority. + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.pcName = "EventTsk32B"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 2; // 2, set new task priority, it is higher than the current task. + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF03; + task1.pcName = "EventTsk32C"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + ret = LOS_TaskCreate(&g_testTaskID03, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT2); + + LOS_TaskDelay(50); // 50, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT2); // 3, Here, assert that g_testCount is equal to 3. + +EXIT2: + LOS_TaskDelete(g_testTaskID03); + +EXIT1: + LOS_TaskDelete(g_testTaskID02); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +VOID ItLosEvent032(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosEvent032", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_033.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_033.c new file mode 100644 index 00000000..11e39058 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_033.c @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + g_testCount++; + ret = LOS_EventRead(&g_event, 0xF, LOS_WAITMODE_AND | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, 0xF, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_event.uwEventID, 0, g_event.uwEventID, EXIT); + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, Here, assert that g_testCount is equal to 3. + g_testCount++; + + ret = LOS_EventWrite(&g_event, 0xF); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + +EXIT: + LOS_TaskDelete(g_testTaskID01); +} + +static VOID TaskF02(VOID) +{ + UINT32 ret; + + g_testCount++; + TestExtraTaskDelay(2); // 2, delay enouge time + + ret = LOS_EventRead(&g_event, 0xF, LOS_WAITMODE_AND | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, 0xF, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_event.uwEventID, 0, g_event.uwEventID, EXIT); + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, Here, assert that g_testCount is equal to 4. + g_testCount++; + + ret = LOS_EventWrite(&g_event, 0xF); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + +EXIT: + + LOS_TaskDelete(g_testTaskID02); +} + +static VOID TaskF03(VOID) +{ + UINT32 ret; + + g_testCount++; + TestExtraTaskDelay(4); // 4, set delay time + + ret = LOS_EventRead(&g_event, 0xF, LOS_WAITMODE_AND | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, 0xF, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_event.uwEventID, 0, g_event.uwEventID, EXIT); + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); // 5, Here, assert that g_testCount is equal to 5. + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID03); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = {0}; + + g_testCount = 0; + LOS_EventInit(&g_event); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "EventTsk33A"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + // 3, Set the priority according to the task purpose,a smaller number means a higher priority. + task1.usTaskPrio = TASK_PRIO_TEST - 3; + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.pcName = "EventTsk33B"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 2; // 2, set new task priority, it is higher than the current task. + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF03; + task1.pcName = "EventTsk33C"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + ret = LOS_TaskCreate(&g_testTaskID03, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT2); + TestExtraTaskDelay(1); + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT2); // 3, Here, assert that g_testCount is equal to 3. + + ret = LOS_EventWrite(&g_event, 0xF); + + TestBusyTaskDelay(10); // 10, set delay time + LOS_TaskDelay(1); + + ICUNIT_GOTO_EQUAL(g_testCount, 6, g_testCount, EXIT3); // 6, Here, assert that g_testCount is equal to 3. + +EXIT3: + ret = LOS_EventClear(&g_event, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT2: + LOS_TaskDelete(g_testTaskID03); + +EXIT1: + LOS_TaskDelete(g_testTaskID02); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +VOID ItLosEvent033(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosEvent033", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_037.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_037.c new file mode 100644 index 00000000..5cf5c025 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_037.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_TaskSuspend(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + g_testCount++; + + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND | LOS_WAITMODE_CLR, 0); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = {0}; + LOS_EventInit(&g_event); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "EventTsk37"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 2; // 2, set new task priority, it is higher than the current task. + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + TestExtraTaskDelay(2); // 2, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + g_testCount++; + + LOS_EventWrite(&g_event, 0x11); + + LOS_EventClear(&g_event, (~(0x11))); + + ret = LOS_TaskResume(g_testTaskID01); + TestExtraTaskDelay(2); // 2, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT1); // 4, Here, assert that g_testCount is equal to 4. + +EXIT1: + + ret = LOS_EventClear(&g_event, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +VOID ItLosEvent037(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosEvent037", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_038.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_038.c new file mode 100644 index 00000000..19e68eb1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_038.c @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static EVENT_CB_S g_pevent2 = { 0 }; + +static VOID HwiF01(VOID) +{ + UINT32 ret; + + TEST_HwiClear(HWI_NUM_TEST); + + g_testCount++; + + ret = LOS_EventWrite(&g_event, 0x11); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_EventWrite(&g_pevent2, 0x11); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + LOS_EventClear(&g_pevent2, 0); + + g_testCount++; +} + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_EventRead(&g_pevent2, 0x11, LOS_WAITMODE_AND, 10); // 10, The timeout period for reading events. + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + LOS_EventClear(&g_pevent2, 0x11); + + ret = LOS_EventRead(&g_pevent2, 0x11, LOS_WAITMODE_AND, 10); // 10, The timeout period for reading events. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_EVENT_READ_TIMEOUT, ret, EXIT); + + ret = LOS_EventWrite(&g_pevent2, 0x11); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_EventClear(&g_pevent2, 0x11); + ret = LOS_EventRead(&g_pevent2, 0x11, LOS_WAITMODE_AND, 0); + ICUNIT_GOTO_EQUAL(ret, 0x11, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_testCount, 6, g_testCount, EXIT); // 6, Here, assert that g_testCount is equal to 6. + + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID01); +} + +static VOID TaskF02(VOID) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_EventRead(&g_event, 0x1, LOS_WAITMODE_OR, 10); // 10, The timeout period for reading events. + ICUNIT_GOTO_EQUAL(ret, 0x1, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); // 5, Here, assert that g_testCount is equal to 5. + + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID02); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = {0}; + LOS_EventInit(&g_event); + LOS_EventInit(&g_pevent2); + + g_testCount = 0; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "EventTsk38A"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 2; // 2, set new task priority, it is higher than the current task. + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.pcName = "EventTsk38B"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 1; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT1); // 2, Here, assert that g_testCount is equal to 2. + g_testCount++; + + ret = LOS_HwiCreate(HWI_NUM_TEST, 0, 0, HwiF01, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + TestHwiTrigger(HWI_NUM_TEST); + + LOS_TaskDelay(11); // 11, delay enouge time + ICUNIT_GOTO_EQUAL(g_testCount, 7, g_testCount, EXIT1); // 7, Here, assert that g_testCount is equal to 7. + +EXIT1: + LOS_TaskDelete(g_testTaskID02); +EXIT: + LOS_TaskDelete(g_testTaskID01); + TEST_HwiDelete(HWI_NUM_TEST); + + return LOS_OK; +} + +VOID ItLosEvent038(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosEvent038", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_039.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_039.c new file mode 100644 index 00000000..c434a846 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_039.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, 200); // 200, The timeout period for reading events. + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_event.uwEventID, 0, g_event.uwEventID, EXIT); + + g_testCount++; +EXIT: + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + LOS_EventInit(&g_event); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "EventTsk39"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 2; // 2, set new task priority, it is higher than the current task. + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + LOS_TaskLock(); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + ret = LOS_EventWrite(&g_event, 0x11); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + ret = LOS_EventClear(&g_event, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_TaskUnlock(); + + LOS_TaskDelay(1); + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + LOS_TaskLock(); + + ret = LOS_EventWrite(&g_event, 0x11); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_EventClear(&g_event, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_TaskUnlock(); + + LOS_TaskDelay(1); + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +VOID ItLosEvent039(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosEvent039", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_040.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_040.c new file mode 100644 index 00000000..f1ded303 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_040.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + g_testCount++; + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, 10); // 10, The timeout period for reading events. + ICUNIT_ASSERT_EQUAL_VOID(ret, 0x11, ret); + ICUNIT_ASSERT_EQUAL_VOID(g_event.uwEventID, 0x111, g_event.uwEventID); + + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + return; +} +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = {0}; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "EventTsk40"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 2; // 2, set new task priority, it is higher than the current task. + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + g_testCount = 0; + g_event.uwEventID = 0; + LOS_EventInit(&g_event); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_EventWrite(&g_event, 0x100); + + LOS_EventWrite(&g_event, 0x1); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + LOS_EventWrite(&g_event, 0x10); + TestExtraTaskDelay(2); // 2, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + + return LOS_OK; +EXIT: + LOS_TaskDelete(g_testTaskID01); + return LOS_OK; +} + +VOID ItLosEvent040(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosEvent040", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_042.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_042.c new file mode 100644 index 00000000..2cad4637 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_042.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, g_event.uwEventID, ret); + ICUNIT_ASSERT_EQUAL_VOID(g_event.uwEventID, 0x11, g_event.uwEventID); + + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + return; +} +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = {0}; + EVENT_CB_S pevent = { 0 }; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "EventTsk42"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 2; // 2, set new task priority, it is higher than the current task. + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + g_testCount = 0; + + g_event.uwEventID = 0; + LOS_EventInit(&g_event); + LOS_EventInit(&pevent); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_EventWrite(&pevent, 0x11); + TestExtraTaskDelay(2); // 2, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + LOS_EventWrite(&g_event, 0x11); + TestExtraTaskDelay(2); // 2, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + + return LOS_OK; +EXIT: + LOS_TaskDelete(g_testTaskID01); + return LOS_OK; +} + +VOID ItLosEvent042(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosEvent042", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_043.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_043.c new file mode 100644 index 00000000..0777cac5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/full/It_los_event_043.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + g_testCount++; + + g_event.uwEventID = 0; + LOS_EventInit(&g_event); + + LOS_EventWrite(&g_event, 0x1); + + ret = LOS_EventRead(&g_event, 0x1, LOS_WAITMODE_OR, 0); + ICUNIT_GOTO_EQUAL(ret, g_event.uwEventID, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_event.uwEventID, 0x1, g_event.uwEventID, EXIT); + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + g_testCount++; + + LOS_EventWrite(&g_event, 0x10); + ICUNIT_GOTO_EQUAL(g_event.uwEventID, 0x11, g_event.uwEventID, EXIT); + + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, 0); + ICUNIT_GOTO_EQUAL(ret, g_event.uwEventID, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_event.uwEventID, 0x11, g_event.uwEventID, EXIT); + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + + g_testCount++; + + LOS_EventWrite(&g_event, 0x100); + ICUNIT_GOTO_EQUAL(g_event.uwEventID, 0x111, g_event.uwEventID, EXIT); + + ret = LOS_EventRead(&g_event, 0x10, LOS_WAITMODE_OR, 0); + ICUNIT_GOTO_EQUAL(ret, 0x10, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_event.uwEventID, 0x111, g_event.uwEventID, EXIT); + + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = {0}; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "EventTsk43"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 2; // 2, set new task priority, it is higher than the current task. + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + TestExtraTaskDelay(2); // 2, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, Here, assert that g_testCount is equal to 4. + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +VOID ItLosEvent043(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosEvent043", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smoke/It_los_event_031.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smoke/It_los_event_031.c new file mode 100644 index 00000000..5548d1df --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smoke/It_los_event_031.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + + ret = LOS_EventDestroy(NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_EVENT_PTR_NULL, ret); + return LOS_OK; +} + +VOID ItLosEvent031(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosEvent031", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL0, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smoke/It_los_event_035.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smoke/It_los_event_035.c new file mode 100644 index 00000000..60f3b27b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smoke/It_los_event_035.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + int ret; + + g_event.uwEventID = 0; + + ret = LOS_EventInit(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_EventInit(NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_EVENT_PTR_NULL, ret); + return LOS_OK; +} + +VOID ItLosEvent035(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosEvent035", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL0, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smoke/It_los_event_036.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smoke/It_los_event_036.c new file mode 100644 index 00000000..81fdf88b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smoke/It_los_event_036.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND | LOS_WAITMODE_CLR, 0); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_event.uwEventID, 0, g_event.uwEventID, EXIT); + + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = {0}; + + LOS_EventInit(&g_event); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "EventTsk36"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 2; // 2, set new task priority, it is higher than the current task. + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + LOS_TaskLock(); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + ret = LOS_EventWrite(&g_event, 0x11); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT1); + + LOS_EventClear(&g_event, (~(0x11))); + + LOS_TaskUnlock(); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT1); // 2, Here, assert that g_testCount is equal to 2. + +EXIT1: + + ret = LOS_EventClear(&g_event, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +VOID ItLosEvent036(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosEvent036", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL0, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smoke/It_los_event_041.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smoke/It_los_event_041.c new file mode 100644 index 00000000..2f5cf515 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smoke/It_los_event_041.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + g_testCount++; + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, 3); // 3, The timeout period for reading events. + ICUNIT_GOTO_EQUAL(ret, g_event.uwEventID, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_event.uwEventID, 0x11, g_event.uwEventID, EXIT); + + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = {0}; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "EventTsk41"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST - 2; // 2, set new task priority, it is higher than the current task. + task1.uwResved = LOS_TASK_STATUS_DETACHED; + + g_testCount = 0; + g_event.uwEventID = 0; + LOS_EventInit(&g_event); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + while (g_testCount < 1) { + } + + LOS_EventWrite(&g_event, 0x11); + TestExtraTaskDelay(2); // 2, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_EventDestroy(&g_event); + + return LOS_OK; +} + +VOID ItLosEvent041(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosEvent041", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL0, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_001.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_001.c new file mode 100644 index 00000000..c9c35c37 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_001.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + g_event.uwEventID = 0; + + ret = LOS_EventInit(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_001_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_EventDestroy(&g_event); + return LOS_OK; +} + +VOID ItSmpLosEvent001(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosEvent001", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_002.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_002.c new file mode 100644 index 00000000..507f4426 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_002.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + g_event.uwEventID = 0; + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LOS_EventInit(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_001_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_EventDestroy(&g_event); + return LOS_OK; +} + +VOID ItSmpLosEvent002(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosEvent002", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_003.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_003.c new file mode 100644 index 00000000..05a2fb52 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_003.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID HwiF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + g_event.uwEventID = 0; + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LOS_EventInit(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + + TestHwiTrigger(HWI_NUM_TEST); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + +EXIT: + LOS_HwiDelete(HWI_NUM_TEST, NULL); + LOS_EventDestroy(&g_event); + return LOS_OK; +} + +VOID ItSmpLosEvent003(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosEvent003", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_004.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_004.c new file mode 100644 index 00000000..7e520457 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_004.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, g_event.uwEventID, ret); + ICUNIT_ASSERT_EQUAL_VOID(g_event.uwEventID, 0x11, g_event.uwEventID); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + g_event.uwEventID = 0; + + ret = LOS_EventInit(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_001_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_EVENT_SHOULD_NOT_DESTROY, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosEvent004(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosEvent004", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_005.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_005.c new file mode 100644 index 00000000..821b6f7f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_005.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, g_event.uwEventID, ret); + ICUNIT_ASSERT_EQUAL_VOID(g_event.uwEventID, 0x11, g_event.uwEventID); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static VOID TaskF02(VOID) +{ + UINT32 ret; + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_EVENT_SHOULD_NOT_DESTROY, ret); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + g_event.uwEventID = 0; + + ret = LOS_EventInit(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_005_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_005_task2", TaskF02, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(1); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + LOS_TaskDelete(g_testTaskID02); + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosEvent005(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosEvent005", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_006.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_006.c new file mode 100644 index 00000000..60570852 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_006.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, g_event.uwEventID, ret); + ICUNIT_ASSERT_EQUAL_VOID(g_event.uwEventID, 0x11, g_event.uwEventID); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + g_event.uwEventID = 0; + + ret = LOS_EventInit(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_006_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + do { + __asm__ volatile("nop"); + } while (g_testCount != 1); + + TestBusyTaskDelay(2); // 2, delay enouge time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL((ret & OS_TASK_STATUS_PEND), 0, ret, EXIT); + + ret = LOS_EventDestroy(&g_event); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_EVENT_SHOULD_NOT_DESTROY, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosEvent006(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosEvent006", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_007.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_007.c new file mode 100644 index 00000000..868b544b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_007.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, g_event.uwEventID, ret); + ICUNIT_ASSERT_EQUAL_VOID(g_event.uwEventID, 0x11, g_event.uwEventID); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static VOID TaskF02(VOID) +{ + UINT32 ret; + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_EVENT_SHOULD_NOT_DESTROY, ret); + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + g_event.uwEventID = 0; + + ret = LOS_EventInit(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + // 2, Set the priority according to the task purpose,a smaller number means a higher priority. + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_007_task1", TaskF01, TASK_PRIO_TEST - 2, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_007_task2", TaskF02, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(10); // 10, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + + ret = OS_TCB_FROM_TID(g_testTaskID02)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_UNUSED, 0, ret, EXIT); + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + LOS_TaskDelete(g_testTaskID02); + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosEvent007(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosEvent007", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_008.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_008.c new file mode 100644 index 00000000..aa34c8cc --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_008.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID HwiF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_EVENT_READ_IN_INTERRUPT, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + g_event.uwEventID = 0; + + ret = LOS_EventInit(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + + TestHwiTrigger(HWI_NUM_TEST); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + + ret = LOS_EventDestroy(&g_event); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + +EXIT: + LOS_HwiDelete(HWI_NUM_TEST, NULL); + LOS_EventDestroy(&g_event); + return LOS_OK; +} + +VOID ItSmpLosEvent008(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosEvent008", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_009.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_009.c new file mode 100644 index 00000000..e35855e2 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_009.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, g_event.uwEventID, ret); + ICUNIT_ASSERT_EQUAL_VOID(g_event.uwEventID, 0x11, g_event.uwEventID); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static VOID HwiF01(VOID) +{ + UINT32 ret; + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_EVENT_SHOULD_NOT_DESTROY, ret); + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + g_event.uwEventID = 0; + + ret = LOS_EventInit(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_009_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + do { + __asm__ volatile("nop"); + } while (g_testCount != 1); + + TestBusyTaskDelay(2); // 2, delay enouge time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL((ret & OS_TASK_STATUS_PEND), 0, ret, EXIT); + + TestHwiTrigger(HWI_NUM_TEST); + + do { + __asm__ volatile("nop"); + } while (g_testCount != 2); // 2, wait until g_testCount is 2 ,or do noting + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_PEND, 0, ret, EXIT); + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ret = LOS_HwiDelete(HWI_NUM_TEST, NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosEvent009(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosEvent009", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_010.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_010.c new file mode 100644 index 00000000..d9409125 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_010.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, g_event.uwEventID, ret); + ICUNIT_ASSERT_EQUAL_VOID(g_event.uwEventID, 0x11, g_event.uwEventID); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static VOID TaskF02(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + + ret = LOS_EventWrite(&g_event, 0x11); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + g_event.uwEventID = 0; + + ret = LOS_EventInit(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_010_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_010_task2", TaskF02, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, Here, assert that g_testCount is equal to 3. + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosEvent010(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosEvent010", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_011.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_011.c new file mode 100644 index 00000000..98e53d83 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_011.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF02(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + + ret = LOS_EventWrite(&g_event, 0x11); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, g_event.uwEventID, ret); + ICUNIT_ASSERT_EQUAL_VOID(g_event.uwEventID, 0x11, g_event.uwEventID); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + g_event.uwEventID = 0; + + ret = LOS_EventInit(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_011_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_011_task2", TaskF02, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 3); // 100, Set the timeout of runtime; 3, test running count + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, Here, assert that g_testCount is equal to 3. + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosEvent011(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosEvent011", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_012.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_012.c new file mode 100644 index 00000000..f8c7d13e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_012.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, g_event.uwEventID, ret); + ICUNIT_ASSERT_EQUAL_VOID(g_event.uwEventID, 0x11, g_event.uwEventID); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static VOID HwiF01(VOID) +{ + UINT32 ret; + ret = LOS_EventWrite(&g_event, 0x11); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + g_event.uwEventID = 0; + + ret = LOS_EventInit(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_009_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(1); + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + TestHwiTrigger(HWI_NUM_TEST); + + LOS_TaskDelay(1); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + ret = LOS_HwiDelete(HWI_NUM_TEST, NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosEvent012(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosEvent012", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_013.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_013.c new file mode 100644 index 00000000..58e7eb57 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_013.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, g_event.uwEventID, ret); + ICUNIT_ASSERT_EQUAL_VOID(g_event.uwEventID, 0x11, g_event.uwEventID); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static VOID TaskF02(VOID) +{ + UINT32 ret; + + do { + __asm__ volatile("nop"); + } while (g_testCount != 1); + + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + g_event.uwEventID = 0; + + ret = LOS_EventInit(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_013_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_013_task2", TaskF02, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_EventWrite(&g_event, 0x11); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(10); // 10, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosEvent013(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosEvent013", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_014.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_014.c new file mode 100644 index 00000000..62c82d6d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_014.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF02(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + + ret = LOS_EventWrite(&g_event, 0x11); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + do { + __asm__ volatile("nop"); + } while (g_testCount != 1); + + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + + TestDumpCpuid(); + return; +} +static VOID TaskF01(VOID) +{ + UINT32 ret; + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, g_event.uwEventID, ret); + ICUNIT_ASSERT_EQUAL_VOID(g_event.uwEventID, 0x11, g_event.uwEventID); + LOS_AtomicInc(&g_testCount); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + g_event.uwEventID = 0; + + ret = LOS_EventInit(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_014_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_014_task2", TaskF02, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosEvent014(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosEvent014", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_015.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_015.c new file mode 100644 index 00000000..346f9652 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_015.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, g_event.uwEventID, ret); + ICUNIT_ASSERT_EQUAL_VOID(g_event.uwEventID, 0x11, g_event.uwEventID); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static VOID HwiF01(VOID) +{ + UINT32 ret; + ret = LOS_EventWrite(&g_event, 0x11); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + do { + __asm__ volatile("nop"); + } while (g_testCount != 2); // 2, wait until g_testCount is 2 ,or do noting + + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + g_event.uwEventID = 0; + + ret = LOS_EventInit(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_009_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(1); + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + TestHwiTrigger(HWI_NUM_TEST); + + TestAssertBusyTaskDelay(100, 3); // 100, Set the timeout of runtime; 3, test running count + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, Here, assert that g_testCount is equal to 3. + +EXIT: + LOS_TaskDelete(g_testTaskID01); + ret = LOS_HwiDelete(HWI_NUM_TEST, NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosEvent015(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosEvent015", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_016.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_016.c new file mode 100644 index 00000000..e24feed0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_016.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + + ret = LOS_EventWrite(&g_event, 0x11); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + g_event.uwEventID = 0; + + ret = LOS_EventInit(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_016_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + +EXIT: + LOS_TaskDelete(g_testTaskID01); + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosEvent016(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosEvent016", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_017.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_017.c new file mode 100644 index 00000000..1d8e5821 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_017.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + ret = LOS_EventWrite(&g_event, 0x11); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + g_event.uwEventID = 0; + + ret = LOS_EventInit(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_017_task2", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 1); // 100, Set the timeout of runtime; + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosEvent017(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosEvent017", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_018.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_018.c new file mode 100644 index 00000000..9f64a437 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_018.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + ret = LOS_EventWrite(&g_event, 0x11); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + LOS_AtomicInc(&g_testCount); + + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + g_event.uwEventID = 0; + + ret = LOS_EventInit(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_005_task2", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + +EXIT: + LOS_TaskDelete(g_testTaskID01); + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosEvent018(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosEvent018", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_019.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_019.c new file mode 100644 index 00000000..de8efd3b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_019.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID HwiF01(VOID) +{ + UINT32 ret; + ret = LOS_EventWrite(&g_event, 0x11); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + g_event.uwEventID = 0; + + ret = LOS_EventInit(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + + TestHwiTrigger(HWI_NUM_TEST); + + TestAssertBusyTaskDelay(100, 1); // 100, Set the timeout of runtime; + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + ret = LOS_HwiDelete(HWI_NUM_TEST, NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosEvent019(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosEvent019", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_020.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_020.c new file mode 100644 index 00000000..5c71584c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_020.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + + LOS_AtomicInc(&g_testCount); + + ret = LOS_EventWrite(&g_event, 0x11); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + g_event.uwEventID = 0; + + ret = LOS_EventInit(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_020_task2", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(1); + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL(ret, g_event.uwEventID, ret); + + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosEvent020(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosEvent020", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_021.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_021.c new file mode 100644 index 00000000..2144965b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_021.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, g_event.uwEventID, ret); + ICUNIT_ASSERT_EQUAL_VOID(g_event.uwEventID, 0x11, g_event.uwEventID); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + g_event.uwEventID = 0; + + ret = LOS_EventInit(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LOS_EventWrite(&g_event, 0x11); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + LOS_AtomicInc(&g_testCount); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_021_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosEvent021(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosEvent021", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_022.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_022.c new file mode 100644 index 00000000..7de02441 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_022.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + ret = LOS_EventWrite(&g_event, 0x11); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static VOID HwiF01(VOID) +{ + UINT32 ret; + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_EVENT_READ_IN_INTERRUPT, ret); + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + g_event.uwEventID = 0; + + ret = LOS_EventInit(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_009_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + TestHwiTrigger(HWI_NUM_TEST); + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + + ret = LOS_EventDestroy(&g_event); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + ret = LOS_HwiDelete(HWI_NUM_TEST, NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosEvent022(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosEvent022", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_023.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_023.c new file mode 100644 index 00000000..aa552f59 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_023.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, g_event.uwEventID, ret); + ICUNIT_ASSERT_EQUAL_VOID(g_event.uwEventID, 0x11, g_event.uwEventID); + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static VOID TaskF02(VOID) +{ + UINT32 ret; + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + g_event.uwEventID = 0; + + ret = LOS_EventInit(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_EventWrite(&g_event, 0x11); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_023_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_023_task", TaskF02, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // othercpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosEvent023(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosEvent023", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_024.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_024.c new file mode 100644 index 00000000..54c3bbf9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_024.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF02(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, g_event.uwEventID, ret); + ICUNIT_ASSERT_EQUAL_VOID(g_event.uwEventID, 0x11, g_event.uwEventID); + + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + + TestDumpCpuid(); + return; +} + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ret = LOS_EventWrite(&g_event, 0x11); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + LOS_AtomicInc(&g_testCount); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + g_event.uwEventID = 0; + + ret = LOS_EventInit(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_014_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_014_task2", TaskF02, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosEvent024(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosEvent024", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_025.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_025.c new file mode 100644 index 00000000..63c10b79 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_025.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + + ret = LOS_EventWrite(&g_event, 0x11); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static VOID HwiF01(VOID) +{ + UINT32 ret; + + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_EVENT_READ_IN_INTERRUPT, ret); + + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + g_event.uwEventID = 0; + + ret = LOS_EventInit(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_009_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + TestHwiTrigger(HWI_NUM_TEST); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + +EXIT: + LOS_TaskDelete(g_testTaskID01); + ret = LOS_HwiDelete(HWI_NUM_TEST, NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosEvent025(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosEvent025", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_026.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_026.c new file mode 100644 index 00000000..f88e14c1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_026.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_ret1; +static UINT32 g_ret2 = 0; + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER); // read and clear + g_ret1 = ret; + ICUNIT_ASSERT_EQUAL_VOID(g_event.uwEventID, 0, g_event.uwEventID); + LOS_AtomicInc(&g_testCount); + + TestDumpCpuid(); + return; +} + +static VOID TaskF02(VOID) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER); // read and clear + g_ret2 = ret; + ICUNIT_ASSERT_EQUAL_VOID(g_event.uwEventID, 0, g_event.uwEventID); + LOS_AtomicInc(&g_testCount); + + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + g_event.uwEventID = 0; + + ret = LOS_EventInit(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_026_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_026_task2", TaskF02, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + + ret = LOS_EventWrite(&g_event, 0x11); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(10); // 10, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, Here, assert that g_testCount is equal to 4. + + PRINT_DEBUG("g_ret1=0x%x,g_ret2=0x%x\n", g_ret1, g_ret2); + ICUNIT_GOTO_EQUAL(g_ret1, 0x11, g_ret1, EXIT); + ICUNIT_GOTO_EQUAL(g_ret2, 0x11, g_ret2, EXIT); + + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosEvent026(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosEvent026", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_027.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_027.c new file mode 100644 index 00000000..280ca0d7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_027.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); // just read not clear + ICUNIT_ASSERT_EQUAL_VOID(ret, 0x11, ret); + ICUNIT_ASSERT_EQUAL_VOID(g_event.uwEventID, 0x11, g_event.uwEventID); + LOS_AtomicInc(&g_testCount); + + TestDumpCpuid(); + return; +} + +static VOID TaskF02(VOID) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); // just read not clear + ICUNIT_ASSERT_EQUAL_VOID(ret, 0x11, ret); + ICUNIT_ASSERT_EQUAL_VOID(g_event.uwEventID, 0x11, g_event.uwEventID); + LOS_AtomicInc(&g_testCount); + + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + g_event.uwEventID = 0; + + ret = LOS_EventInit(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_026_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_026_task2", TaskF02, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + while (g_testCount != 2) { // 2, wait until g_testCount is 2 ,or do noting + } + + ret = LOS_EventWrite(&g_event, 0x11); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(10); // 10, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, Here, assert that g_testCount is equal to 4. + + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosEvent027(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosEvent027", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_028.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_028.c new file mode 100644 index 00000000..c4c74b57 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_028.c @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_ret = 0; + +static VOID TaskF02(VOID) +{ + UINT32 ret, i; + LOS_AtomicInc(&g_testCount); + + for (i = 0; i < TRandom() % 500; i++) { // Random values of 0 to 500 + } + + ret = LOS_EventWrite(&g_event, 0x10); // write 1 event + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + + TestDumpCpuid(); + return; +} + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_OR, LOS_WAIT_FOREVER); // wait 2 event with OR mode + + g_ret |= ret; + + LOS_AtomicInc(&g_testCount); + + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid, i, j; + TSK_INIT_PARAM_S testTask; + LosTaskCB *cb = NULL; + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + for (i = 0; i < LOOP; i++) { + g_testCount = 0; + g_event.uwEventID = 0; + ret = LOS_EventInit(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_028_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_028_task2", TaskF02, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + do { + __asm__ volatile("nop"); + } while (g_testCount == 1); // wait for task f02 + + for (j = 0; j < TRandom() % 500; j++) { // Random values of 0 to 500 + } + + ret = LOS_EventWrite(&g_event, 0x01); // write another event + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(10); // 10, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, Here, assert that g_testCount is equal to 4. + if ((g_ret != 0x10) && (g_ret != 0x01)) { + ICUNIT_GOTO_EQUAL(1, 0, g_ret, EXIT); + } + + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_UNUSED, 0, ret, EXIT); + ret = OS_TCB_FROM_TID(g_testTaskID02)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_UNUSED, 0, ret, EXIT); + } + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + LOS_EventDestroy(&g_event); + return LOS_OK; +} + +VOID ItSmpLosEvent028(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosEvent028", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_029.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_029.c new file mode 100644 index 00000000..18f28947 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_029.c @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_ret = 0; +static VOID HwiF01(VOID) +{ + UINT32 ret; + ret = LOS_EventWrite(&g_event, 0x01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + LOS_AtomicInc(&g_testCount); + + TestDumpCpuid(); + return; +} + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + g_ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + + LOS_AtomicInc(&g_testCount); + + TestDumpCpuid(); + return; +} + +static VOID TaskF02(VOID) +{ + UINT32 ret, i; + LOS_AtomicInc(&g_testCount); + + for (i = 0; i < TRandom() % 500; i++) { // Random values of 0 to 500 + } + + ret = LOS_EventWrite(&g_event, 0x10); // write another event + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid, i, j; + TSK_INIT_PARAM_S testTask; + LosTaskCB *cb = NULL; + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // curret cpu + + for (i = 0; i < LOOP; i++) { + g_testCount = 0; + g_event.uwEventID = 0; + ret = LOS_EventInit(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_029_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_029_task2", TaskF02, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + do { + __asm__ volatile("nop"); + } while (g_testCount == 1); // wait for task f02 + + for (j = 0; j < TRandom() % 500; j++) { // Random values of 0 to 500 + } + + TestHwiTrigger(HWI_NUM_TEST); + + LOS_TaskDelay(10); // 10, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); // 5, Here, assert that g_testCount is equal to 5. + + ICUNIT_GOTO_EQUAL(g_ret, 0x11, g_ret, EXIT); + + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_UNUSED, 0, ret, EXIT); + ret = OS_TCB_FROM_TID(g_testTaskID02)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_UNUSED, 0, ret, EXIT); + } + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + LOS_HwiDelete(HWI_NUM_TEST, NULL); + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosEvent029(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosEvent029", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_030.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_030.c new file mode 100644 index 00000000..2df01bb6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_030.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret, i; + LOS_AtomicInc(&g_testCount); + + for (i = 0; i < TRandom() % 500; i++) { // Random values of 0 to 500 + } + + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + LOS_AtomicInc(&g_testCount); + + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid, i, j; + TSK_INIT_PARAM_S testTask; + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + for (i = 0; i < LOOP; i++) { + g_testCount = 0; + g_event.uwEventID = 0; + ret = LOS_EventInit(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_030_task2", TaskF01, TASK_PRIO_TEST + 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + do { + __asm__ volatile("nop"); + } while (g_testCount == 0); // wait for task f01 + + for (j = 0; j < TRandom() % 500; j++) { // Random values of 0 to 500 + } + + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(10); // 10, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_UNUSED, 0, ret, EXIT); + } +EXIT: + LOS_TaskDelete(g_testTaskID01); + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosEvent030(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosEvent030", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_031.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_031.c new file mode 100644 index 00000000..e75f81b1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_031.c @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_ret = 0; + +static VOID TaskF01(VOID) +{ + UINT32 ret; + LOS_AtomicInc(&g_testCount); + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + /* + * write event ---> read event ---> destroy event [pass] + * write event ---> destroy event ---> read event [fail] + */ + LOS_AtomicInc(&g_testCount); + + TestDumpCpuid(); + return; +} + +static VOID TaskF02(VOID) +{ + UINT32 ret, i; + LOS_AtomicInc(&g_testCount); + + for (i = 0; i < TRandom() % 500; i++) { // Random values of 0 to 500 + } + + g_ret = LOS_EventDestroy(&g_event); // delete event in other cpu + LOS_AtomicInc(&g_testCount); + + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid, i, j; + TSK_INIT_PARAM_S testTask; + LosTaskCB *cb = NULL; + + g_testCount = 0; + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + for (i = 0; i < LOOP; i++) { + g_event.uwEventID = 0; + ret = LOS_EventInit(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_031_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_031_task2", TaskF02, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + do { + __asm__ volatile("nop"); + } while (g_testCount == 1); // wait for task f02 + + for (j = 0; j < TRandom() % 500; j++) { // Random values of 0 to 500 + } + + ret = LOS_EventWrite(&g_event, 0x11); // write event in other cpu + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_TaskDelay(10); // 10, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, Here, assert that g_testCount is equal to 4. + + if ((g_ret != LOS_OK) && (g_ret != LOS_ERRNO_EVENT_SHOULD_NOT_DESTROY)) { + ICUNIT_GOTO_EQUAL(1, 0, g_ret, EXIT); + } + + /* clear enviorment */ + g_testCount = 0; + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_UNUSED, 0, ret, EXIT); + ret = OS_TCB_FROM_TID(g_testTaskID02)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_UNUSED, 0, ret, EXIT); + LOS_EventDestroy(&g_event); + } +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosEvent031(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosEvent031", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_032.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_032.c new file mode 100644 index 00000000..9e6c9dfa --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_032.c @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#ifdef LOSCFG_KERNEL_SMP + +static UINT32 g_ret1, g_ret2, g_ret3; +static UINT32 g_szId[3] = {0}; + +static VOID TaskF01(UINT32 index) +{ + UINT32 ret, i; + PRINT_DEBUG("index = %d,cpuid=%d\n", index, ArchCurrCpuid()); + switch (index) { + case 0: + PRINT_DEBUG("---000---\n"); + for (i = 0; i < TRandom() % 500; i++) { // Random values of 0 to 500 + } + LOS_AtomicInc(&g_testCount); + g_ret1 = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + break; + case 1: + PRINT_DEBUG("---111---\n"); + for (i = 0; i < TRandom() % 500; i++) { // Random values of 0 to 500 + } + LOS_AtomicInc(&g_testCount); + g_ret2 = LOS_EventWrite(&g_event, 0x11); + break; + case 2: // 2,index + PRINT_DEBUG("---222---\n"); + for (i = 0; i < TRandom() % 500; i++) { // Random values of 0 to 500 + } + LOS_AtomicInc(&g_testCount); + g_ret3 = LOS_EventDestroy(&g_event); + break; + default: + break; + } + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret; + UINT32 i, j; + + for (i = 0; i < LOOP; i++) { + g_testCount = 0; + g_event.uwEventID = 0; + g_ret1 = 0xff; + g_ret2 = 0xff; + g_ret3 = 0xff; + ret = LOS_EventInit(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + for (j = 0; j < 3; j++) { // 3, max index + TEST_TASK_PARAM_INIT(testTask, "it_event_032_task", TaskF01, TASK_PRIO_TEST - 1); + testTask.auwArgs[0] = j; + ret = LOS_TaskCreate(&g_szId[j], &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + while (g_testCount < 3) { // 3, wait if g_testCount < 3 ,or do noting + } + + LOS_TaskDelay(10); // 10, delay enouge time + PRINT_DEBUG("ret1= 0x%x,ret2 = 0x%x,ret3=0x%x\n", g_ret1, g_ret2, g_ret3); + + if ((g_ret1 == 0x11) && (g_ret2 == LOS_OK) && (g_ret3 == LOS_OK)) { // pend-post-del ///post-pend-del + } else if ((g_ret1 == 0x11) && (g_ret2 == LOS_OK) && + (g_ret3 == LOS_ERRNO_EVENT_SHOULD_NOT_DESTROY)) { // pend-delete-post + } else if ((g_ret1 == 0xff) && (g_ret2 == LOS_OK) && (g_ret3 == LOS_OK)) { // post-del-pend + LOS_TaskDelete(g_szId[0]); // delete the pend task + } else if ((g_ret1 == 0x00) && (g_ret2 == LOS_OK) && (g_ret3 == LOS_OK)) { + /* + * (g_ret1 == 0) && (g_ret2 == 0) && (uwRet3 == 0) + * try read -->write event ---resume read---> destroy event ---> read event [fail] + */ + } else { + ICUNIT_GOTO_EQUAL(1, 0, g_ret1, EXIT); + } + + for (j = 0; j < 3; j++) { // 3, max index + ret = OS_TCB_FROM_TID(g_szId[j])->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_UNUSED, 0, ret, EXIT); + } + + LOS_EventDestroy(&g_event); + } + +EXIT: + for (i = 0; i < 3; i++) { // 3, max index + LOS_TaskDelete(g_szId[i]); + } + return LOS_OK; +} + +VOID ItSmpLosEvent032(VOID) +{ + TEST_ADD_CASE("ItSmpLosEvent032", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_033.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_033.c new file mode 100644 index 00000000..32345aca --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_033.c @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_ret = 0xff; + +static VOID TaskF02(VOID) +{ + UINT32 ret, i; + LOS_AtomicInc(&g_testCount); + + for (i = 0; i < TRandom() % 500; i++) { // Random values of 0 to 500 + } + + ret = LOS_EventWrite(&g_event, 0x11); // write event + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + LOS_AtomicInc(&g_testCount); + + TestDumpCpuid(); + return; +} + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); // wait event + + g_ret = ret; + + LOS_AtomicInc(&g_testCount); + + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid, i, j; + TSK_INIT_PARAM_S testTask; + LosTaskCB *cb = NULL; + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + for (i = 0; i < LOOP; i++) { + g_testCount = 0; + g_event.uwEventID = 0; + ret = LOS_EventInit(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_028_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_028_task2", TaskF02, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + do { + __asm__ volatile("nop"); + } while (g_testCount == 1); // wait for task f02 + + for (j = 0; j < TRandom() % 500; j++) { // Random values of 0 to 500 + } + + ret = LOS_EventClear(&g_event, (~(0x11))); // clear event + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(10); // 10, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, Here, assert that g_testCount is equal to 4. + + if ((g_ret != 0xff) && (g_ret != 0x11)) { + PRINT_DEBUG("g_ret = 0x%x\n", g_ret); + ICUNIT_GOTO_EQUAL(1, 0, g_ret, EXIT); + } + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_UNUSED, 0, ret, EXIT); + ret = OS_TCB_FROM_TID(g_testTaskID02)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_UNUSED, 0, ret, EXIT); + ret = LOS_EventDestroy(&g_event); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosEvent033(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosEvent033", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_034.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_034.c new file mode 100644 index 00000000..e8d4d369 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_034.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, 0x11, ret); + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 4, g_testCount); // 4, Here, assert that g_testCount is equal to 4. + + LOS_AtomicInc(&g_testCount); + + TestDumpCpuid(); + return; +} + +static VOID TaskF02(VOID) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, 0x11, ret); + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, Here, assert that g_testCount is equal to 2. // other core get the sem first + + LOS_AtomicInc(&g_testCount); + + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid, i, uvIntSave; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + g_event.uwEventID = 0; + + ret = LOS_EventInit(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_sem_033_task2", TaskF02, TASK_PRIO_TEST - 1, CPUID_TO_AFFI_MASK(currCpuid)); + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + do { + __asm__ volatile("nop"); + } while (g_testCount != 1); // let the task f02 read event first + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_sem_033_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + + LOS_TaskLock(); + + ret = LOS_EventWrite(&g_event, 0x11); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + do { + __asm__ volatile("nop"); + } while (g_testCount != 3); // 3, wait until g_testCount is 3 ,or do noting + + LOS_AtomicInc(&g_testCount); + + LOS_TaskUnlock(); + + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); // 5, Here, assert that g_testCount is equal to 5. +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; + +EXIT1: + LOS_TaskUnlock(); + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosEvent034(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosEvent034", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_035.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_035.c new file mode 100644 index 00000000..e2a45178 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_035.c @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static volatile UINT32 g_runFlag = 1; + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, 0x11, ret); + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 3, g_testCount); // 3, Here, assert that g_testCount is equal to 3. + LOS_AtomicInc(&g_testCount); + + TestDumpCpuid(); + return; +} + +static VOID TaskF02(VOID) +{ + UINT32 ret, uvIntSave; + + LOS_AtomicInc(&g_testCount); + + LOS_TaskLock(); // task lock on other cpu + do { + __asm__ volatile("nop"); + } while (g_runFlag == 1); + + LOS_TaskUnlock(); // schedule occur ---switch to task f01 + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 4, g_testCount); // 4, Here, assert that g_testCount is equal to 4. + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid, i; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + g_runFlag = 1; + g_event.uwEventID = 0; + + ret = LOS_EventInit(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_sem_034_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_sem_034_task2", TaskF02, TASK_PRIO_TEST, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + while (g_testCount < 2) { // g_testCount < 2,do nothing + } + + ret = LOS_EventWrite(&g_event, 0x11); // try to wake task f01 + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + // 100, Set the timeout of runtime; 2, test running count + TestAssertBusyTaskDelay(100, 2); // cause tasklock on other cpu ,so task f01 wake failed + + LOS_AtomicInc(&g_testCount); + + g_runFlag = 0; // unlock the other cpu + // 100, Set the timeout of runtime; 4, test running count + TestAssertBusyTaskDelay(100, 4); // not schedule in current cpu cause tasklock +EXIT: + + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosEvent035(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosEvent035", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_036.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_036.c new file mode 100644 index 00000000..c1e7a6ab --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_036.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret, i; + + LOS_AtomicInc(&g_testCount); + + for (i = 0; i < TRandom() % 500; i++) { // Random values of 0 to 500 + } + + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, 0x11, ret); + + LOS_AtomicInc(&g_testCount); + + do { + __asm__ volatile("nop"); + } while (1); + + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid, i, j; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + g_event.uwEventID = 0; + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + for (i = 0; i < LOOP; i++) { + ret = LOS_EventInit(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_035_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + do { + __asm__ volatile("nop"); + } while (g_testCount == 0); // wait for task f01 run + + for (j = 0; j < TRandom() % 500; j++) { // Random values of 0 to 500 + } + + ret = LOS_TaskDelete(g_testTaskID01); // cross delete always return ok + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(100); // 100, delay enouge time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_EQUAL(ret, OS_TASK_STATUS_UNUSED, ret, EXIT); + + ret = LOS_EventWrite(&g_event, 0x11); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(10); // 10, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_EQUAL(ret, OS_TASK_STATUS_UNUSED, ret, EXIT); + + ret = LOS_EventDestroy(&g_event); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + +EXIT: + + LOS_TaskDelete(g_testTaskID01); + LOS_EventDestroy(&g_event); + return LOS_OK; +} + +VOID ItSmpLosEvent036(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosEvent036", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_037.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_037.c new file mode 100644 index 00000000..09b52278 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/event/smp/It_smp_los_event_037.c @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_ret = 0xff; + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_EventRead(&g_event, 0x11, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); // pend on current cpu + ICUNIT_ASSERT_EQUAL_VOID(ret, 0x11, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static VOID TaskF02(VOID) +{ + UINT32 ret, i; + + LOS_AtomicInc(&g_testCount); + + do { + __asm__ volatile("nop"); + } while (g_testCount == 2); // 2, wait for test task + + for (i = 0; i < TRandom() % 500; i++) { // Random values of 0 to 500 + } + + ret = LOS_EventWrite(&g_event, 0x11); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid, i, j; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + g_event.uwEventID = 0; + + ret = LOS_EventInit(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + for (i = 0; i < LOOP; i++) { + g_testCount = 0; + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_smp_event_037_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_PEND, 0, ret, EXIT); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_smp_event_037_task2", TaskF02, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + do { + __asm__ volatile("nop"); + } while (g_testCount == 1); // wait for task f02 + + LOS_AtomicInc(&g_testCount); + + for (j = 0; j < TRandom() % 500; j++) { // Random values of 0 to 500 + } + + ret = LOS_TaskDelete(g_testTaskID01); + g_ret = ret; + + LOS_TaskDelay(10); // 10, delay enouge time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_UNUSED, 0, ret, EXIT); + + if (g_testCount == 4) { // 4,case + ICUNIT_GOTO_EQUAL(g_ret, LOS_OK, g_ret, EXIT); + } else if (g_testCount == 5) { // 5,case + ICUNIT_GOTO_EQUAL(g_ret, LOS_ERRNO_TSK_NOT_CREATED, g_ret, EXIT); + } else { + ICUNIT_GOTO_EQUAL(1, 0, g_ret, EXIT); + } + LOS_TaskDelete(g_testTaskID02); + ret = OS_TCB_FROM_TID(g_testTaskID02)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_UNUSED, 0, ret, EXIT); + + LOS_EventClear(&g_event, (~(0x11))); + } + +EXIT: + + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + ret = LOS_EventDestroy(&g_event); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosEvent037(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosEvent037", Testcase, TEST_LOS, TEST_EVENT, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/It_los_mux.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/It_los_mux.c new file mode 100644 index 00000000..b0cb2a26 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/It_los_mux.c @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_task_pri.h" +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +LosMux g_mutexTest1; +LosMux g_mutexTest2; +LosMux g_mutexTest3; + + +u_long TRand() +{ + return TRandom(); +} +void ShowMuxId(UINT32 *p, int len) +{ + int i; + for (i = 0; i < len; i++) { + dprintf("%d , ", p[i]); + } + dprintf("\n"); +} +void RandSZ(UINT32 *sz, int len) +{ + int idx; + for (idx = len - 1; idx > 1; idx--) { /* get the random index */ + int randIdx = TRand() % idx; + UINT32 tempMuxID = sz[randIdx]; + sz[randIdx] = sz[idx]; + sz[idx] = tempMuxID; + } + return; +} +VOID ItSuiteLosMux(void) +{ +#if defined(LOSCFG_TEST_SMOKE) + ItLosMux001(); + ItLosMux002(); + ItLosMux003(); + ItLosMux004(); +#endif +#if defined(LOSCFG_TEST_FULL) + ItLosMux006(); + ItLosMux007(); + ItLosMux008(); + ItLosMux009(); + ItLosMux010(); + ItLosMux011(); + ItLosMux012(); + ItLosMux013(); + ItLosMux015(); + ItLosMux016(); + ItLosMux017(); + ItLosMux018(); + ItLosMux020(); + ItLosMux021(); + ItLosMux025(); + ItLosMux026(); + ItLosMux027(); + ItLosMux028(); + ItLosMux029(); + ItLosMux031(); + ItLosMux035(); + ItLosMux036(); + ItLosMux037(); + ItLosMux038(); + ItLosMux039(); + ItLosMux040(); + ItLosMux041(); + ItLosMux042(); + ItLosMux043(); +#endif + +#ifdef LOSCFG_KERNEL_SMP + ItSmpLosMux001(); + ItSmpLosMux002(); + ItSmpLosMux003(); + ItSmpLosMux004(); + ItSmpLosMux005(); + ItSmpLosMux006(); + ItSmpLosMux007(); + ItSmpLosMux2001(); + ItSmpLosMux2002(); + ItSmpLosMux2003(); + ItSmpLosMux2004(); + ItSmpLosMux2005(); + ItSmpLosMux2006(); + ItSmpLosMux2007(); + ItSmpLosMux2008(); + ItSmpLosMux2009(); + ItSmpLosMux2010(); + ItSmpLosMux2011(); + ItSmpLosMux2012(); + ItSmpLosMux2013(); + ItSmpLosMux2014(); + ItSmpLosMux2015(); + ItSmpLosMux2016(); + ItSmpLosMux2017(); + ItSmpLosMux2018(); + ItSmpLosMux2021(); + ItSmpLosMux2022(); + ItSmpLosMux2024(); + ItSmpLosMux2025(); + ItSmpLosMux2026(); + ItSmpLosMux2027(); + ItSmpLosMux2028(); + ItSmpLosMux2029(); +#endif + +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, 1); + HalIrqSetAffinity(HWI_NUM_TEST1, 1); +#endif +} + + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/It_los_mux.h b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/It_los_mux.h new file mode 100644 index 00000000..6172afff --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/It_los_mux.h @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _IT_LOS_MUX_H +#define _IT_LOS_MUX_H + +#include "osTest.h" +#include "los_mux_pri.h" +#include "los_config.h" +#include "los_bitmap.h" +#include "los_sem_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +extern LosMux g_mutexTest1; +extern LosMux g_mutexTest2; +extern LosMux g_mutexTest3; +extern VOID ItSuiteLosMux(void); + +#define LOOP 100 + +#define LOS_ERRNO_MUX_INVALID EINVAL +#define LOS_ERRNO_MUX_PTR_NULL EINVAL +#define LOS_ERRNO_MUX_PENDED EBUSY +#define LOS_ERRNO_MUX_UNAVAILABLE EBUSY +#define LOS_ERRNO_MUX_TIMEOUT ETIMEDOUT +#define LOS_ERRNO_MUX_ALL_BUSY EAGAIN +#define LOS_ERRNO_MUX_PEND_IN_LOCK EDEADLK +#define LOS_ERRNO_MUX_PEND_INTERR EINTR +u_long TRand(void); +void ShowMuxId(UINT32 *p, int len); +void RandSZ(UINT32 *sz, int len); +void WaitAllTasksFinish(UINT32 *szTaskID, int len); +bool CheckAllTasksStatus(UINT32 *szTaskID, int len, const char *supposedStatus); +UINT8 *T_osShellConvertTskStatus(UINT16 taskStatus); +#if defined(LOSCFG_TEST_SMOKE) +VOID ItLosMux001(void); +VOID ItLosMux002(void); +VOID ItLosMux003(void); +VOID ItLosMux004(void); +#endif + +#if defined(LOSCFG_TEST_FULL) +VOID ItLosMux006(void); +VOID ItLosMux007(void); +VOID ItLosMux008(void); +VOID ItLosMux009(void); +VOID ItLosMux010(void); +VOID ItLosMux011(void); +VOID ItLosMux012(void); +VOID ItLosMux013(void); +VOID ItLosMux015(void); +VOID ItLosMux016(void); +VOID ItLosMux017(void); +VOID ItLosMux018(void); +VOID ItLosMux020(void); +VOID ItLosMux021(void); +VOID ItLosMux025(void); +VOID ItLosMux026(void); +VOID ItLosMux027(void); +VOID ItLosMux028(void); +VOID ItLosMux029(void); +VOID ItLosMux031(void); +VOID ItLosMux035(void); +VOID ItLosMux036(void); +VOID ItLosMux037(void); +VOID ItLosMux038(void); +VOID ItLosMux039(void); +VOID ItLosMux040(void); +VOID ItLosMux041(void); +VOID ItLosMux042(void); +VOID ItLosMux043(void); +#endif + +#if defined(LOSCFG_TEST_SMP) +VOID ItSmpLosMux001(void); +VOID ItSmpLosMux002(void); +VOID ItSmpLosMux003(void); +VOID ItSmpLosMux004(void); +VOID ItSmpLosMux005(void); +VOID ItSmpLosMux006(void); +VOID ItSmpLosMux007(void); +VOID ItSmpLosMux2001(void); +VOID ItSmpLosMux2002(void); +VOID ItSmpLosMux2003(void); +VOID ItSmpLosMux2004(void); +VOID ItSmpLosMux2005(void); +VOID ItSmpLosMux2006(void); +VOID ItSmpLosMux2007(void); +VOID ItSmpLosMux2008(void); +VOID ItSmpLosMux2009(void); +VOID ItSmpLosMux2010(void); +VOID ItSmpLosMux2011(void); +VOID ItSmpLosMux2012(void); +VOID ItSmpLosMux2013(void); +VOID ItSmpLosMux2014(void); +VOID ItSmpLosMux2015(void); +VOID ItSmpLosMux2016(void); +VOID ItSmpLosMux2017(void); +VOID ItSmpLosMux2018(void); +VOID ItSmpLosMux2019(void); +VOID ItSmpLosMux2020(void); +VOID ItSmpLosMux2021(void); +VOID ItSmpLosMux2022(void); +VOID ItSmpLosMux2023(void); +VOID ItSmpLosMux2024(void); +VOID ItSmpLosMux2025(void); +VOID ItSmpLosMux2026(void); +VOID ItSmpLosMux2027(void); +VOID ItSmpLosMux2028(void); +VOID ItSmpLosMux2029(void); +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#endif /* _IT_LOS_MUX_H */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_006.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_006.c new file mode 100644 index 00000000..c3618642 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_006.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + LosMux muxHandle, muxHandle2; + + ret = LosMuxCreate(&muxHandle); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LosMuxCreate(&muxHandle2); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxDestroy(&muxHandle); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxDestroy(&muxHandle); + ICUNIT_ASSERT_EQUAL(ret, EBADF, ret); + + ret = LOS_MuxDestroy(&muxHandle2); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxDestroy(&muxHandle2); + ICUNIT_ASSERT_EQUAL(ret, EBADF, ret); + + return LOS_OK; +} + + +VOID ItLosMux006(void) +{ + TEST_ADD_CASE("ItLosMux006", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_007.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_007.c new file mode 100644 index 00000000..4e5c132b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_007.c @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(void) +{ + UINT32 ret; + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + g_testCount++; + + LOS_TaskDelay(100); // 100, set delay time. + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + TestExtraTaskDelay(2); // 2, delay for Timing control. + + g_testCount++; + + LOS_TaskDelay(200); // 200, set delay time. +} + +static VOID TaskF02(void) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + g_testCount++; + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, here assert the result. + g_testCount++; + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 3, g_testCount); // 3, here assert the result. + g_testCount++; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task = { 0 }; + TSK_INIT_PARAM_S task2 = { 0 }; + + g_testCount = 0; + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task.usTaskPrio = (TASK_PRIO_TEST_TASK - 1); + task.pcName = "VMuteB2_1"; + task.uwStackSize = 0x900; + task.uwResved = 0; + + ret = LosMuxCreate(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + TestExtraTaskDelay(2); // 2, delay for Timing control. + + task2.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task2.usTaskPrio = (TASK_PRIO_TEST_TASK - 2); // 2, set reasonable priority. + task2.pcName = "VMuteB2_2"; + task2.uwStackSize = 0x900; + task2.uwResved = 0; + + ret = LOS_TaskCreate(&g_testTaskID02, &task2); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(200); // 200, set delay time. + + ICUNIT_ASSERT_EQUAL(g_testCount, 5, g_testCount); // 5, here assert the result. + + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + LOS_TaskDelete(g_testTaskID02); + return LOS_OK; +} + + +VOID ItLosMux007(void) +{ + TEST_ADD_CASE("ItLosMux007", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_008.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_008.c new file mode 100644 index 00000000..a4ef237c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_008.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + + ret = LosMuxCreate(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, EPERM, ret); + + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + + +VOID ItLosMux008(void) +{ + TEST_ADD_CASE("ItLosMux008", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_009.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_009.c new file mode 100644 index 00000000..23c110f9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_009.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TestHook091(void) +{ + UINT32 ret; + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, EPERM, ret); + + g_testCount++; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task = { 0 }; + + ret = LosMuxCreate(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + g_testCount = 0; + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TestHook091; + task.usTaskPrio = (TASK_PRIO_TEST_TASK - 1); + task.pcName = "VMutexB4"; + task.uwStackSize = TASK_STACK_SIZE_TEST; + task.uwResved = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task); + TestExtraTaskDelay(2); // 2, delay for Timing control. + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + + +VOID ItLosMux009(void) +{ + TEST_ADD_CASE("ItLosMux009", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_010.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_010.c new file mode 100644 index 00000000..d6a305f2 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_010.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + + ret = LosMuxCreate(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_MUX_PENDED, ret); + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + + +VOID ItLosMux010(void) +{ + TEST_ADD_CASE("ItLosMux010", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_011.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_011.c new file mode 100644 index 00000000..fc64f0ab --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_011.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(void) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_TaskDelay(10); // 10, delay for Timing control. + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; + + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task = { 0 }; + + ret = LosMuxCreate(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + g_testCount = 0; + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task.usTaskPrio = (TASK_PRIO_TEST_TASK - 1); + task.pcName = "VMutexB6"; + task.uwStackSize = TASK_STACK_SIZE_TEST; + task.uwResved = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task); + TestExtraTaskDelay(2); // 2, delay for Timing control. + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_MUX_PENDED, ret); + LOS_TaskDelay(15); // 15, delay for Timing control. + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, here assert the result. + + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + LOS_TaskDelete(g_testTaskID01); + return LOS_OK; +} + + +VOID ItLosMux011(void) +{ + TEST_ADD_CASE("ItLosMux011", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_012.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_012.c new file mode 100644 index 00000000..01d6a1c0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_012.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static VOID TaskF01(void) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_MuxLock(&g_mutexkernelTest, 0); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_MuxLock(&g_mutexkernelTest, 0); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_TaskDelay(10); // 10, delay for Timing control. + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; +} +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task = { 0 }; + + ret = LosMuxCreate(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + g_testCount = 0; + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task.usTaskPrio = (TASK_PRIO_TEST_TASK - 1); + task.pcName = "VMutexB7"; + task.uwStackSize = TASK_STACK_SIZE_TEST; + task.uwResved = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + TestExtraTaskDelay(2); // 2, delay for Timing control. + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_MUX_PENDED, ret); + + LOS_TaskDelay(10); // 10, delay for Timing control. + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, here assert the result. + + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + + +VOID ItLosMux012(void) +{ + TEST_ADD_CASE("ItLosMux012", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_013.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_013.c new file mode 100644 index 00000000..d7b003b0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_013.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static VOID HwiF01(void) +{ + UINT32 ret; + TEST_HwiClear(HWI_NUM_TEST); + + ret = LosMuxCreate(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_MuxLock(&g_mutexkernelTest, 0); + + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_MUX_PEND_INTERR, ret); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_MUX_PEND_INTERR, ret); + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_MUX_PEND_INTERR, ret); + + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + + g_testCount = 0; + + ret = LOS_HwiCreate(HWI_NUM_TEST, 0, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + TestHwiTrigger(HWI_NUM_TEST); +#ifdef LOSCFG_KERNEL_SMP + TestBusyTaskDelay(5); // 5, delay for Timing control. +#endif + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + TEST_HwiDelete(HWI_NUM_TEST); + + return LOS_OK; +} + + +VOID ItLosMux013(void) +{ + TEST_ADD_CASE("ItLosMux013", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_015.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_015.c new file mode 100644 index 00000000..ebabcde4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_015.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static VOID TaskF01(void) +{ + UINT32 ret; + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_TaskDelay(10); // 10, delay for Timing control. + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; + + ret = LOS_MuxLock(&g_mutexkernelTest, 0); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_TaskDelay(10); // 10, delay for Timing control. + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task = {0}; + + ret = LosMuxCreate(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + g_testCount = 0; + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task.usTaskPrio = (TASK_PRIO_TEST_TASK - 1); + task.pcName = "VMuteB010"; + task.uwStackSize = TASK_STACK_SIZE_TEST; + task.uwResved = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 0, g_testCount); + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, EPERM, ret); + + LOS_TaskDelay(15); // 15, delay for Timing control. + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, EPERM, ret); + + LOS_TaskDelay(20); // 20, delay for Timing control. + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, EPERM, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, here assert the result. + + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + + +VOID ItLosMux015(void) +{ + TEST_ADD_CASE("ItLosMux015", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_016.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_016.c new file mode 100644 index 00000000..cd2ab6e1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_016.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static VOID HwiF01(void) +{ + UINT32 ret; + + TEST_HwiClear(HWI_NUM_TEST); + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_MUX_PEND_INTERR, ret); + + g_testCount++; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + + g_testCount = 0; + + ret = LosMuxCreate(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 0, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + TestHwiTrigger(HWI_NUM_TEST); + +#ifdef LOSCFG_KERNEL_SMP + TestBusyTaskDelay(10); // 10, delay for Timing control. +#endif + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_HwiDelete(HWI_NUM_TEST); + + return LOS_OK; +} + + +VOID ItLosMux016(void) +{ + TEST_ADD_CASE("ItLosMux016", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_017.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_017.c new file mode 100644 index 00000000..c98ff4e9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_017.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static VOID HwiF01(void) +{ + UINT32 ret; + + TEST_HwiClear(HWI_NUM_TEST); + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_MUX_PEND_INTERR, ret); + + g_testCount++; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + g_testCount = 0; + + ret = LosMuxCreate(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxLock(&g_mutexkernelTest, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 0, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + TestHwiTrigger(HWI_NUM_TEST); + TestExtraTaskDelay(5); // 5, delay for Timing control. + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_HwiDelete(HWI_NUM_TEST); + + return LOS_OK; +} + + +VOID ItLosMux017(void) +{ + TEST_ADD_CASE("ItLosMux017", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_018.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_018.c new file mode 100644 index 00000000..f5bc131d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_018.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 semHandle; + + ret = LosMuxCreate(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SemCreate(1, &semHandle); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL(ret, EBADF, ret); + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, EBADF, ret); + + ret = LOS_SemDelete(semHandle); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + + +VOID ItLosMux018(void) +{ + TEST_ADD_CASE("ItLosMux018", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_020.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_020.c new file mode 100644 index 00000000..4da64155 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_020.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static VOID HwiF02(void) +{ + UINT32 ret; + + TEST_HwiClear(HWI_NUM_TEST0); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, here assert the result. + g_testCount++; + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_MUX_PEND_INTERR, ret); +} + +static VOID HwiF01(void) +{ + UINT32 ret; + TEST_HwiClear(HWI_NUM_TEST); + + g_testCount++; + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_MUX_PEND_INTERR, ret); + + g_testCount++; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + + g_testCount = 0; + + ret = LosMuxCreate(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 0, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ret = LOS_HwiCreate(HWI_NUM_TEST0, 0, 0, (HWI_PROC_FUNC)HwiF02, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + HalIrqSetAffinity(HWI_NUM_TEST0, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + TestHwiTrigger(HWI_NUM_TEST); + TestExtraTaskDelay(5); // 5, delay for Timing control. + TestHwiTrigger(HWI_NUM_TEST0); + TestExtraTaskDelay(5); // 5, delay for Timing control. + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, here assert the result. + + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_HwiDelete(HWI_NUM_TEST); + TEST_HwiDelete(HWI_NUM_TEST0); + + return LOS_OK; +} + + +VOID ItLosMux020(void) +{ + TEST_ADD_CASE("ItLosMux020", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_021.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_021.c new file mode 100644 index 00000000..09869413 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_021.c @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(void) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, here assert the result. + g_testCount++; + + LOS_TaskDelay(200); // 200, set delay time. +} + +VOID TaskF02(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = {0}; + + g_testCount++; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "LosMB2_2"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = TASK_PRIO_TEST_TASK - 3; // 3, set reasonable priority. + task1.uwResved = 0; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_TaskDelay(1); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 3, g_testCount); // 3, here assert the result. + g_testCount++; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task = { 0 }; + + g_testCount = 0; + + ret = LosMuxCreate(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task.usTaskPrio = (TASK_PRIO_TEST_TASK - 1); + task.pcName = "LosMB2_1"; + task.uwStackSize = 0x900; + task.uwResved = 0; +#ifdef LOSCFG_KERNEL_SMP + task.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(1); + TestExtraTaskDelay(10); // 10, delay for Timing control. + ICUNIT_ASSERT_EQUAL(g_testCount, 4, g_testCount); // 4, here assert the result. + + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskDelete(g_testTaskID02); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelete(g_testTaskID01); + return LOS_OK; +} + + +VOID ItLosMux021(void) +{ + TEST_ADD_CASE("ItLosMux021", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_025.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_025.c new file mode 100644 index 00000000..18dafb45 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_025.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 loop = 30; // 30, init. + UINT32 loop2 = 100; // 100, init. + UINT32 loop3 = 100; // 100, init. + + while (loop--) { + ret = LosMuxCreate(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + while (loop2) { + loop2--; + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, loop2); + } + + LOS_TaskDelay(1); + while (loop3) { + loop3--; + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, loop3); + } + + ret = LOS_MuxLock(&g_mutexkernelTest, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(1); + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + return LOS_OK; +} + + +VOID ItLosMux025(void) +{ + TEST_ADD_CASE("ItLosMux025", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_026.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_026.c new file mode 100644 index 00000000..d4d4707c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_026.c @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +static VOID TaskDFunc(VOID) +{ + UINT32 ret; + g_testCount++; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 6, g_testCount); // 6, here assert the result. + + g_testCount++; + ret = LOS_MuxLock(&g_mutexTest3, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_MuxUnlock(&g_mutexTest3); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; + UINT16 priority = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + ICUNIT_ASSERT_EQUAL_VOID(priority, 2, priority); // 2, here assert the result. + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 9, g_testCount); // 9, here assert the result. + + g_testCount++; +} + +static VOID TaskCFunc(VOID) +{ + UINT32 ret; + g_testCount++; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 4, g_testCount); // 4, here assert the result. + + g_testCount++; + ret = LOS_MuxLock(&g_mutexTest2, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_MuxUnlock(&g_mutexTest2); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + g_testCount++; + + UINT16 priority = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + ICUNIT_ASSERT_EQUAL_VOID(priority, 3, priority); // 3, here assert the result. + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 11, g_testCount); // 11, here assert the result. + + g_testCount++; +} + +static VOID TaskBFunc(VOID) +{ + UINT32 ret; + + g_testCount++; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, here assert the result. + + g_testCount++; + ret = LOS_MuxLock(&g_mutexTest1, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_MuxUnlock(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; + + UINT16 priority = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + ICUNIT_ASSERT_EQUAL_VOID(priority, 5, priority); // 5, here assert the result. + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 13, g_testCount); // 13, here assert the result. + g_testCount++; +} + +static VOID TaskAFunc(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + TSK_INIT_PARAM_S task2 = { 0 }; + TSK_INIT_PARAM_S task3 = { 0 }; + + g_testCount++; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + ret = LOS_MuxLock(&g_mutexTest1, 0); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskBFunc; + task1.usTaskPrio = 5; // 5, set reasonable priority. + task1.pcName = "TaskB"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 3, g_testCount); // 3, here assert the result. + + ret = LosMuxCreate(&g_mutexTest2); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + ret = LOS_MuxLock(&g_mutexTest2, 0); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + task2.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskCFunc; + task2.usTaskPrio = 3; // 3, set reasonable priority. + task2.pcName = "TaskC"; + task2.uwStackSize = TASK_STACK_SIZE_TEST; + task2.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task2.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID03, &task2); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LosMuxCreate(&g_mutexTest3); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + ret = LOS_MuxLock(&g_mutexTest3, 0); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 5, g_testCount); // 5, here assert the result. + task3.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskDFunc; + task3.usTaskPrio = 2; // 2, set reasonable priority. + task3.pcName = "TaskD"; + task3.uwStackSize = TASK_STACK_SIZE_TEST; + task3.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task3.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID04, &task3); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + g_testCount++; + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 8, g_testCount); // 8, here assert the result. + + ret = LOS_MuxUnlock(&g_mutexTest3); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 10, g_testCount); // 10, here assert the result. + + UINT16 priority = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + ICUNIT_ASSERT_EQUAL_VOID(priority, 3, priority); // 3, here assert the result. + + ret = LOS_MuxUnlock(&g_mutexTest2); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 12, g_testCount); // 12, here assert the result. + priority = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + ICUNIT_ASSERT_EQUAL_VOID(priority, 5, priority); // 5, here assert the result. + + ret = LOS_MuxUnlock(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 14, g_testCount); // 14, here assert the result. + + ret = LOS_MuxDestroy(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_MuxDestroy(&g_mutexTest2); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_MuxDestroy(&g_mutexTest3); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 14, g_testCount); // 14, here assert the result. + priority = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + ICUNIT_ASSERT_EQUAL_VOID(priority, 10, priority); // 10, here assert the result. +} + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task = { 0 }; + + g_testCount = 0; + + UINT16 priority = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + ICUNIT_ASSERT_EQUAL(priority, 25, priority); // 25, here assert the result. + + ret = LosMuxCreate(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskAFunc; + task.usTaskPrio = 10; // 10, set reasonable priority. + task.pcName = "TaskA"; + task.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + task.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 14, g_testCount); // 14, here assert the result. + priority = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + ICUNIT_ASSERT_EQUAL(priority, 25, priority); // 25, here assert the result. + return LOS_OK; +} + +VOID ItLosMux026(void) +{ + TEST_ADD_CASE("ItLosMux026", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_027.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_027.c new file mode 100644 index 00000000..f825b878 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_027.c @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +static VOID TaskD1Func(VOID) +{ + UINT32 ret; + g_testCount++; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 4, g_testCount); // 4, here assert the result. + + ret = LOS_MuxLock(&g_mutexTest1, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_MuxUnlock(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 5, g_testCount); // 5, here assert the result. + UINT16 priority = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + ICUNIT_ASSERT_EQUAL_VOID(priority, 2, priority); // 2, here assert the result. + g_testCount++; +} + +static VOID TaskC1Func(VOID) +{ + UINT32 ret; + g_testCount++; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 3, g_testCount); // 3, here assert the result. + + ret = LOS_MuxLock(&g_mutexTest1, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_MuxUnlock(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 6, g_testCount); // 6, here assert the result. + + UINT16 priority = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + ICUNIT_ASSERT_EQUAL_VOID(priority, 3, priority); // 3, here assert the result. + g_testCount++; +} + +static VOID TaskB1Func(VOID) +{ + UINT32 ret; + g_testCount++; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, here assert the result. + + ret = LOS_MuxLock(&g_mutexTest1, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_MuxUnlock(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 7, g_testCount); // 7, here assert the result. + + UINT16 priority = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + ICUNIT_ASSERT_EQUAL_VOID(priority, 5, priority); // 5, here assert the result. + g_testCount++; +} + +static VOID TaskA1Func(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = {0}; + TSK_INIT_PARAM_S task2 = {0}; + TSK_INIT_PARAM_S task3 = {0}; + g_testCount++; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + + ret = LOS_MuxLock(&g_mutexTest1, 0); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskB1Func; + task1.usTaskPrio = 5; // 5, set reasonable priority. + task1.pcName = "TaskB"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + task2.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskC1Func; + task2.usTaskPrio = 3; // 3, set reasonable priority. + task2.pcName = "TaskC"; + task2.uwStackSize = TASK_STACK_SIZE_TEST; + task2.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task2.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID03, &task2); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + task3.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskD1Func; + task3.usTaskPrio = 2; // 2, set reasonable priority. + task3.pcName = "TaskD"; + task3.uwStackSize = TASK_STACK_SIZE_TEST; + task3.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task3.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID04, &task3); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 4, g_testCount); // 4, here assert the result. + + ret = LOS_MuxUnlock(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_MuxDestroy(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + UINT16 priority = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + ICUNIT_ASSERT_EQUAL_VOID(priority, 10, priority); // 10, here assert the result. + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 8, g_testCount); // 8, here assert the result. +} + +static UINT32 Testcase(void) +{ + UINT32 ret; + TSK_INIT_PARAM_S task = {0}; + g_testCount = 0; + + ret = LosMuxCreate(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskA1Func; + task.usTaskPrio = 10; // 10, set reasonable priority. + task.pcName = "TaskA"; + task.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + task.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 8, g_testCount); // 8, here assert the result. + UINT16 priority = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + ICUNIT_ASSERT_EQUAL(priority, 25, priority); // 25, here assert the result. + return LOS_OK; +} + +VOID ItLosMux027(void) +{ + TEST_ADD_CASE("ItLosMux027", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_028.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_028.c new file mode 100644 index 00000000..52bbb8cc --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_028.c @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +static VOID TaskD2Func(VOID) +{ + UINT32 ret; + g_testCount++; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 4, g_testCount); // 4, here assert the result. + ret = LOS_MuxLock(&g_mutexTest1, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_MuxUnlock(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 6, g_testCount); // 6, here assert the result. + UINT16 priority = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + ICUNIT_ASSERT_EQUAL_VOID(priority, 10, priority); // 10, here assert the result. + g_testCount++; +} + +static VOID TaskC2Func(VOID) +{ + UINT32 ret; + g_testCount++; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 3, g_testCount); // 3, here assert the result. + ret = LOS_MuxLock(&g_mutexTest1, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_MuxUnlock(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 5, g_testCount); // 5, here assert the result. + UINT16 priority = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + ICUNIT_ASSERT_EQUAL_VOID(priority, 10, priority); // 10, here assert the result. + g_testCount++; +} + +static VOID TaskB2Func(VOID) +{ + UINT32 ret; + g_testCount++; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, here assert the result. + ret = LOS_MuxLock(&g_mutexTest1, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_MuxUnlock(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 4, g_testCount); // 4, here assert the result. + UINT16 priority = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + ICUNIT_ASSERT_EQUAL_VOID(priority, 10, priority); // 10, here assert the result. + g_testCount++; +} + +static VOID TaskA2Func(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = {0}; + TSK_INIT_PARAM_S task2 = {0}; + TSK_INIT_PARAM_S task3 = {0}; + g_testCount++; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + ret = LOS_MuxLock(&g_mutexTest1, 0); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskB2Func; + task1.usTaskPrio = 10; // 10, set reasonable priority. + task1.pcName = "TaskB"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + LOS_TaskYield(); + + task2.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskC2Func; + task2.usTaskPrio = 10; // 10, set reasonable priority. + task2.pcName = "TaskC"; + task2.uwStackSize = TASK_STACK_SIZE_TEST; + task2.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task2.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID03, &task2); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + LOS_TaskYield(); + + task3.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskD2Func; + task3.usTaskPrio = 10; // 10, set reasonable priority. + task3.pcName = "TaskD"; + task3.uwStackSize = TASK_STACK_SIZE_TEST; + task3.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task3.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID04, &task3); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + LOS_TaskYield(); + + ret = LOS_MuxUnlock(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_TaskDelay(10); // 10, delay for Timing control. + + ret = LOS_MuxDestroy(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + UINT16 priority = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + ICUNIT_ASSERT_EQUAL_VOID(priority, 10, priority); // 10, here assert the result. + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 8, g_testCount); // 8, here assert the result. + g_testCount++; +} + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task = {0}; + g_testCount = 0; + + ret = LosMuxCreate(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskA2Func; + task.usTaskPrio = 10; // 10, set reasonable priority. + task.pcName = "TaskA"; + task.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + task.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 7, g_testCount); // 7, here assert the result. + g_testCount++; + LOS_TaskDelay(20); // 20, delay for Timing control. + + ICUNIT_ASSERT_EQUAL(g_testCount, 9, g_testCount); // 9, here assert the result. + return LOS_OK; +} + +VOID ItLosMux028(void) +{ + TEST_ADD_CASE("ItLosMux028", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_029.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_029.c new file mode 100644 index 00000000..7037fb86 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_029.c @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +static VOID TaskD3Func(VOID) +{ + UINT32 ret; + g_testCount++; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 4, g_testCount); // 4, here assert the result. + ret = LOS_MuxLock(&g_mutexTest2, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 5, g_testCount); // 5, here assert the result. + ret = LOS_MuxUnlock(&g_mutexTest2); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 6, g_testCount); // 6, here assert the result. + + UINT16 priority = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + ICUNIT_ASSERT_EQUAL_VOID(priority, 2, priority); // 2, here assert the result. + g_testCount++; +} + +static VOID TaskC3Func(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = {0}; + g_testCount++; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 3, g_testCount); // 3, here assert the result. + ret = LosMuxCreate(&g_mutexTest2); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_MuxLock(&g_mutexTest2, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskD3Func; + task1.usTaskPrio = 2; // 2, set reasonable priority. + task1.pcName = "TaskD"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID04, &task1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_MuxLock(&g_mutexTest1, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_MuxUnlock(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 5, g_testCount); // 5, here assert the result. + + ret = LOS_MuxUnlock(&g_mutexTest2); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 7, g_testCount); // 7, here assert the result. + UINT16 priority = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + ICUNIT_ASSERT_EQUAL_VOID(priority, 3, priority); // 3, here assert the result. + g_testCount++; +} + +static VOID TaskB3Func(VOID) +{ + UINT32 ret; + g_testCount++; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, here assert the result. + ret = LOS_MuxLock(&g_mutexTest1, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_MuxUnlock(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 8, g_testCount); // 8, here assert the result. + UINT16 priority = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + ICUNIT_ASSERT_EQUAL_VOID(priority, 5, priority); // 5, here assert the result. + g_testCount++; +} + +static VOID TaskA3Func(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = {0}; + TSK_INIT_PARAM_S task2 = {0}; + g_testCount++; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + ret = LOS_MuxLock(&g_mutexTest1, 0); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskB3Func; + task1.usTaskPrio = 5; // 5, set reasonable priority. + task1.pcName = "TaskB"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + task2.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskC3Func; + task2.usTaskPrio = 3; // 3, set reasonable priority. + task2.pcName = "TaskC"; + task2.uwStackSize = TASK_STACK_SIZE_TEST; + task2.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task2.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID03, &task2); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 4, g_testCount); // 4, here assert the result. + ret = LOS_MuxUnlock(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_MuxDestroy(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_MuxDestroy(&g_mutexTest2); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 9, g_testCount); // 9, here assert the result. + UINT16 priority = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + ICUNIT_ASSERT_EQUAL_VOID(priority, 10, priority); // 10, here assert the result. + g_testCount++; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task = {0}; + g_testCount = 0; + + ret = LosMuxCreate(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskA3Func; + task.usTaskPrio = 10; // 10, set reasonable priority. + task.pcName = "TaskA"; + task.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + task.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 10, g_testCount); // 10, here assert the result. + UINT16 priority = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + ICUNIT_ASSERT_EQUAL(priority, 25, priority); // 25, here assert the result. + return LOS_OK; +} + +VOID ItLosMux029(void) +{ + TEST_ADD_CASE("ItLosMux029", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_031.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_031.c new file mode 100644 index 00000000..ccd01cb9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_031.c @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +static VOID TaskD5Func(VOID) +{ + UINT32 ret; + g_testCount++; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 4, g_testCount); // 4, here assert the result. + + ret = LOS_MuxLock(&g_mutexTest2, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 5, g_testCount); // 5, here assert the result. + + ret = LOS_MuxUnlock(&g_mutexTest2); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + UINT16 priority = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + ICUNIT_ASSERT_EQUAL_VOID(priority, 2, priority); // 2, here assert the result. + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 5, g_testCount); // 5, here assert the result. + g_testCount++; +} + +static VOID TaskC5Func(VOID) +{ + UINT32 ret; + g_testCount++; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 3, g_testCount); // 3, here assert the result. + + ret = LOS_MuxLock(&g_mutexTest2, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 6, g_testCount); // 6, here assert the result. + + ret = LOS_MuxUnlock(&g_mutexTest2); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + UINT16 priority = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + ICUNIT_ASSERT_EQUAL_VOID(priority, 3, priority); // 3, here assert the result. + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 6, g_testCount); // 6, here assert the result. + g_testCount++; +} + +static VOID TaskB5Func(VOID) +{ + UINT32 ret; + g_testCount++; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, here assert the result. + + ret = LOS_MuxLock(&g_mutexTest1, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 7, g_testCount); // 7, here assert the result. + + ret = LOS_MuxUnlock(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + UINT16 priority = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + ICUNIT_ASSERT_EQUAL_VOID(priority, 5, priority); // 5, here assert the result. + + g_testCount++; +} + +static VOID TaskA5Func(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + TSK_INIT_PARAM_S task2 = { 0 }; + TSK_INIT_PARAM_S task3 = { 0 }; + g_testCount++; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + + ret = LOS_MuxLock(&g_mutexTest1, 0); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_MuxLock(&g_mutexTest2, 0); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskB5Func; + task1.usTaskPrio = 5; // 5, set reasonable priority. + task1.pcName = "TaskB"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + task2.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskC5Func; + task2.usTaskPrio = 3; // 3, set reasonable priority. + task2.pcName = "TaskC"; + task2.uwStackSize = TASK_STACK_SIZE_TEST; + task2.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task2.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID03, &task2); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + task3.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskD5Func; + task3.usTaskPrio = 2; // 2, set reasonable priority. + task3.pcName = "TaskD"; + task3.uwStackSize = TASK_STACK_SIZE_TEST; + task3.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task3.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID04, &task3); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 5, g_testCount); // 5, here assert the result. + + ret = LOS_MuxUnlock(&g_mutexTest2); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 7, g_testCount); // 5, here assert the result. + + ret = LOS_MuxUnlock(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + UINT16 priority = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + ICUNIT_ASSERT_EQUAL_VOID(priority, 10, priority); // 10, here assert the result. + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 8, g_testCount); // 8, here assert the result. + g_testCount++; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task = {0}; + g_testCount = 0; + + ret = LosMuxCreate(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LosMuxCreate(&g_mutexTest2); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskA5Func; + task.usTaskPrio = 10; // 10, set reasonable priority. + task.pcName = "TaskA"; + task.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + task.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxDestroy(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxDestroy(&g_mutexTest2); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 9, g_testCount); // 9, here assert the result. + + UINT16 priority = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + ICUNIT_ASSERT_EQUAL(priority, 25, priority); // 25, here assert the result. + return LOS_OK; +} + +VOID ItLosMux031(void) +{ + TEST_ADD_CASE("ItLosMux031", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_035.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_035.c new file mode 100644 index 00000000..f5290e71 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_035.c @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "osTest.h" +#include "los_config.h" +#include "los_bitmap.h" +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +static VOID TaskFe2Func(VOID) +{ + UINT32 ret; + g_testCount++; + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 4, g_testCount); // 4, here assert the result. + + ret = LOS_MuxLock(&g_mutexTest2, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 7, g_testCount); // 7, here assert the result. + + ret = LOS_MuxUnlock(&g_mutexTest2); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); +} + +static VOID TaskService3Func(VOID) +{ + UINT32 ret; + g_testCount++; + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, here assert the result. + + ret = LOS_MuxLock(&g_mutexTest2, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 3, g_testCount); // 3, here assert the result. + + ret = LOS_MuxLock(&g_mutexTest1, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 5, g_testCount); // 5, here assert the result. + + ret = LOS_MuxUnlock(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 6, g_testCount); // 6, here assert the result. + + ret = LOS_MuxUnlock(&g_mutexTest2); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); +} + +static VOID TaskMisc10Func(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = {0}; + + g_testCount++; + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + + ret = LOS_MuxLock(&g_mutexTest1, 0); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskService3Func; + task1.usTaskPrio = 3; // 3, set reasonable priority. + task1.pcName = "TaskService_3"; + task1.uwStackSize = LOS_TASK_MIN_STACK_SIZE; + task1.uwResved = LOS_TASK_ATTR_JOINABLE; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 3, g_testCount); // 3, here assert the result. + + LOS_TaskDelay(5); // 5, delay for Timing control. + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 4, g_testCount); // 4, here assert the result. + + ret = LOS_MuxUnlock(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task = {0}; + g_testCount = 0; + + ret = LosMuxCreate(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LosMuxCreate(&g_mutexTest2); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskMisc10Func; + task.usTaskPrio = 10; // 10, set reasonable priority. + task.pcName = "TaskMisc_10"; + task.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + task.uwResved = LOS_TASK_ATTR_JOINABLE; +#ifdef LOSCFG_KERNEL_SMP + task.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskFe2Func; + task.usTaskPrio = 2; // 2, set reasonable priority. + task.pcName = "TaskFe_2"; + task.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + task.uwResved = LOS_TASK_ATTR_JOINABLE; +#ifdef LOSCFG_KERNEL_SMP + task.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + ret = LOS_TaskCreate(&g_testTaskID03, &task); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(1000); // 1000, delay for Timing control. + + ICUNIT_ASSERT_EQUAL(g_testCount, 7, g_testCount); // 7, here assert the result. + + ret = LOS_MuxDestroy(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxDestroy(&g_mutexTest2); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + OsShellCmdTskInfoGet(0xffffffff, NULL, 0); + // 10, here assert the result. + ICUNIT_GOTO_EQUAL(LOS_TaskPriGet(g_testTaskID01), 10, LOS_TaskPriGet(g_testTaskID01), EXIT); + // 3, here assert the result. + ICUNIT_GOTO_EQUAL(LOS_TaskPriGet(g_testTaskID02), 3, LOS_TaskPriGet(g_testTaskID02), EXIT); + // 2, here assert the result. + ICUNIT_GOTO_EQUAL(LOS_TaskPriGet(g_testTaskID03), 2, LOS_TaskPriGet(g_testTaskID03), EXIT); +EXIT: + ret = LOS_TaskJoin(g_testTaskID01, NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ret = LOS_TaskJoin(g_testTaskID02, NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ret = LOS_TaskJoin(g_testTaskID03, NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosMux035(void) +{ + TEST_ADD_CASE("ItLosMux035", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_036.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_036.c new file mode 100644 index 00000000..1241fd36 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_036.c @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "osTest.h" +#include "los_config.h" +#include "los_bitmap.h" +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +static VOID TaskFe4Func(VOID) +{ + UINT32 ret; + g_testCount++; + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 3, g_testCount); // 3, here assert the result. + + ret = LOS_MuxLock(&g_mutexTest1, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 4, g_testCount); // 4, here assert the result. + + ret = LOS_MuxUnlock(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); +} + +static VOID TaskService5Func(VOID) +{ + UINT32 ret; + g_testCount++; + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, here assert the result. + + ret = LOS_MuxLock(&g_mutexTest1, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 5, g_testCount); // 5, here assert the result. + + ret = LOS_MuxUnlock(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); +} + +static VOID TaskMisc10Func(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = {0}; + g_testCount++; + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + + ret = LOS_MuxLock(&g_mutexTest1, 0); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskService5Func; + task1.usTaskPrio = 5; // 5, set reasonable priority. + task1.pcName = "TaskService_5"; + task1.uwStackSize = LOS_TASK_MIN_STACK_SIZE; + task1.uwResved = LOS_TASK_ATTR_JOINABLE; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, here assert the result. + + LOS_TaskDelay(5); // 5, delay for Timing control. + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 3, g_testCount); // 3, here assert the result. + ret = LOS_MuxUnlock(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); +} + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task = {0}; + g_testCount = 0; + + ret = LosMuxCreate(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskMisc10Func; + task.usTaskPrio = 10; // 10, set reasonable priority. + task.pcName = "TaskMisc_10"; + task.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + task.uwResved = LOS_TASK_ATTR_JOINABLE; +#ifdef LOSCFG_KERNEL_SMP + task.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, here assert the result. + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskFe4Func; + task.usTaskPrio = 4; // 4, set reasonable priority. + task.pcName = "TaskFe_4"; + task.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + task.uwResved = LOS_TASK_ATTR_JOINABLE; +#ifdef LOSCFG_KERNEL_SMP + task.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + ret = LOS_TaskCreate(&g_testTaskID03, &task); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(200); // 200, set delay time. + + ICUNIT_ASSERT_EQUAL(g_testCount, 5, g_testCount); // 5, here assert the result. + + ret = LOS_MuxDestroy(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + // 10, here assert the result. + ICUNIT_GOTO_EQUAL(LOS_TaskPriGet(g_testTaskID01), 10, LOS_TaskPriGet(g_testTaskID01), EXIT); + // 5, here assert the result. + ICUNIT_GOTO_EQUAL(LOS_TaskPriGet(g_testTaskID02), 5, LOS_TaskPriGet(g_testTaskID02), EXIT); + // 4, here assert the result. + ICUNIT_GOTO_EQUAL(LOS_TaskPriGet(g_testTaskID03), 4, LOS_TaskPriGet(g_testTaskID03), EXIT); + +EXIT: + ret = LOS_TaskJoin(g_testTaskID01, NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ret = LOS_TaskJoin(g_testTaskID02, NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ret = LOS_TaskJoin(g_testTaskID03, NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItLosMux036(void) +{ + TEST_ADD_CASE("ItLosMux036", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_037.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_037.c new file mode 100644 index 00000000..a1db4fce --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_037.c @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "osTest.h" +#include "los_config.h" +#include "los_bitmap.h" +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define OS_MUX_NUM 1000 +LosMux *g_testMux = NULL; + +static VOID TaskFe4Func(VOID) +{ + UINT32 ret; + + g_testCount++; + for (INT32 i = 0; i < OS_MUX_NUM; i++) { + ret = LOS_MuxLock(&g_testMux[i], LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + } + + g_testCount++; + return; +} + +static VOID TaskMisc10Func(VOID) +{ + UINT32 ret; + + g_testCount++; + for (INT32 i = 0; i < OS_MUX_NUM; i++) { + ret = LOS_MuxLock(&g_testMux[i], LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + } + + g_testCount++; + PRINTK("taskMisc_10_func LOCK : 0x%x\n", &g_testMux[0]); + return; +} + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task = {0}; + g_testCount = 0; + + g_testMux = LOS_MemAlloc(m_aucSysMem0, OS_MUX_NUM * sizeof(LosMux)); + ICUNIT_ASSERT_NOT_EQUAL(g_testMux, NULL, g_testMux); + + for (INT32 i = 0; i < OS_MUX_NUM; i++) { + ret = LosMuxCreate(&g_testMux[i]); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + + g_testCount = 0; + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskMisc10Func; + task.usTaskPrio = 10; // 10, set reasonable priority. + task.pcName = "TaskMisc_10"; + task.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + task.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskFe4Func; + task.usTaskPrio = 4; // 4, set reasonable priority. + task.pcName = "TaskFe_4"; + task.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + task.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + ret = LOS_TaskCreate(&g_testTaskID03, &task); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + for (INT32 i = 0; i < OS_MUX_NUM; i++) { + ret = LOS_MuxLock(&g_testMux[i], LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, here assert the result. + +EXIT: + for (UINT32 i = 0; i < OS_MUX_NUM; i++) { + LOS_MuxUnlock(&g_testMux[i]); + LOS_MuxDestroy(&g_testMux[i]); + } + + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID03); + LOS_MemFree(m_aucSysMem0, g_testMux); + + return LOS_OK; +} + +VOID ItLosMux037(void) +{ + TEST_ADD_CASE("ItLosMux037", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_038.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_038.c new file mode 100644 index 00000000..5f079ef1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_038.c @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "osTest.h" +#include "los_config.h" +#include "los_bitmap.h" +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define OS_MUX_NUM 100 +static LosMux g_testMux1; + +static VOID TaskFe4Func(VOID) +{ + UINT32 ret; + + g_testCount++; + for (INT32 i = 0; i < OS_MUX_NUM; i++) { + ret = LOS_MuxLock(&g_testMux1, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + } + + g_testCount++; + return; +} + +static VOID TaskMisc10Func(VOID) +{ + UINT32 ret; + + g_testCount++; + for (INT32 i = 0; i < OS_MUX_NUM; i++) { + ret = LOS_MuxLock(&g_testMux1, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + } + + g_testCount++; + return; +} + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task = {0}; + g_testCount = 0; + + ret = LosMuxCreate(&g_testMux1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + g_testCount = 0; + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskMisc10Func; + task.usTaskPrio = 10; // 10, set reasonable priority. + task.pcName = "TaskMisc_10"; + task.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + task.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskFe4Func; + task.usTaskPrio = 4; // 4, set reasonable priority. + task.pcName = "TaskFe_4"; + task.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + task.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + ret = LOS_TaskCreate(&g_testTaskID03, &task); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_MuxLock(&g_testMux1, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, here assert the result. + +EXIT: + LOS_MuxUnlock(&g_testMux1); + LOS_MuxDestroy(&g_testMux1); + + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID03); + + return LOS_OK; +} + +VOID ItLosMux038(void) +{ + TEST_ADD_CASE("ItLosMux038", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_039.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_039.c new file mode 100644 index 00000000..fc024814 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_039.c @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "osTest.h" +#include "los_config.h" +#include "los_bitmap.h" +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define OS_MUX_NUM 1000 +static LosMux g_testMux1; +static LosMux g_testMux2; +static VOID TaskFe4Func(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 4, g_testCount); // 4, here assert the result. + g_testCount++; + + ret = LOS_MuxLock(&g_testMux2, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 6, g_testCount); // 6, here assert the result. + g_testCount++; + + ret = LOS_MuxLock(&g_testMux1, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; + return; +} + +static VOID TaskMisc10Func(VOID) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_MuxLock(&g_testMux2, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, here assert the result. + g_testCount++; + + ret = LOS_MuxLock(&g_testMux1, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; + return; +} + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task = {0}; + g_testCount = 0; + + ret = LosMuxCreate(&g_testMux1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LosMuxCreate(&g_testMux2); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_MuxLock(&g_testMux1, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + g_testCount++; + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskMisc10Func; + task.usTaskPrio = 10; // 10, set reasonable priority. + task.pcName = "TaskMisc_10"; + task.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + task.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, here assert the result. + g_testCount++; + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskFe4Func; + task.usTaskPrio = 4; // 4, set reasonable priority. + task.pcName = "TaskFe_4"; + task.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + task.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + ret = LOS_TaskCreate(&g_testTaskID03, &task); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); // 5, here assert the result. + g_testCount++; + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 7, g_testCount, EXIT); // 7, here assert the result. + g_testCount++; + + ret = LOS_TaskDelete(g_testTaskID03); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_MuxLock(&g_testMux1, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_MuxLock(&g_testMux2, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 8, g_testCount, EXIT); // 8, here assert the result. + +EXIT: + ret = LOS_MuxUnlock(&g_testMux1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxUnlock(&g_testMux1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxUnlock(&g_testMux2); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + UINT16 priority = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + ICUNIT_ASSERT_EQUAL(priority, TASK_PRIO_TEST_TASK, priority); + + ret = LOS_MuxDestroy(&g_testMux1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxDestroy(&g_testMux2); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosMux039(void) +{ + TEST_ADD_CASE("ItLosMux039", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_040.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_040.c new file mode 100644 index 00000000..16f0a76c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_040.c @@ -0,0 +1,315 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "osTest.h" +#include "los_config.h" +#include "los_bitmap.h" +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define OS_MUX_NUM 1000 +static LosMux g_testMux1; +static LosMux g_testMux2; +static LosMux g_testMux3; +static LosMux g_testMux4; +static LosMux g_testMux5; + +static VOID TaskFe7Func(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 15, g_testCount); // 15, here assert the result. + g_testCount++; + + ret = LOS_MuxLock(&g_testMux4, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 17, g_testCount); // 17, here assert the result. + g_testCount++; + + ret = LOS_MuxLock(&g_testMux1, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 21, g_testCount); // 21, here assert the result. + g_testCount++; + return; +} + + +static VOID TaskFe8Func(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 13, g_testCount); // 13, here assert the result. + g_testCount++; + + ret = LOS_MuxLock(&g_testMux3, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 18, g_testCount); // 18, here assert the result. + g_testCount++; + + ret = LOS_MuxLock(&g_testMux1, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 22, g_testCount); // 22, here assert the result. + g_testCount++; + return; +} + +static VOID TaskFe9Func(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 11, g_testCount); // 11, here assert the result. + g_testCount++; + + ret = LOS_MuxLock(&g_testMux2, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 19, g_testCount); // 19, here assert the result. + g_testCount++; + + ret = LOS_MuxLock(&g_testMux1, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 23, g_testCount); // 23, here assert the result. + g_testCount++; + return; +} + +static VOID TaskMisc10Func(VOID) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_MuxLock(&g_testMux2, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, here assert the result. + g_testCount++; + + ret = LOS_MuxLock(&g_testMux3, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 3, g_testCount); // 3, here assert the result. + g_testCount++; + + ret = LOS_MuxLock(&g_testMux4, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 4, g_testCount); // 4, here assert the result. + g_testCount++; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 5, g_testCount); // 5, here assert the result. + g_testCount++; + + ret = LOS_MuxLock(&g_testMux2, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 6, g_testCount); // 6, here assert the result. + g_testCount++; + + ret = LOS_MuxLock(&g_testMux3, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 7, g_testCount); // 7, here assert the result. + g_testCount++; + + ret = LOS_MuxLock(&g_testMux3, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 8, g_testCount); // 8, here assert the result. + g_testCount++; + + ret = LOS_MuxLock(&g_testMux3, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 9, g_testCount); // 9, here assert the result. + g_testCount++; + + ret = LOS_MuxLock(&g_testMux1, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; + return; +} + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task = {0}; + g_testCount = 0; + + ret = LosMuxCreate(&g_testMux1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LosMuxCreate(&g_testMux2); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LosMuxCreate(&g_testMux3); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LosMuxCreate(&g_testMux4); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_MuxLock(&g_testMux1, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + g_testCount++; + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskMisc10Func; + task.usTaskPrio = 10; // 10, set reasonable priority. + task.pcName = "TaskMisc_10"; + task.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + task.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 10, g_testCount, EXIT); // 10, here assert the result. + g_testCount++; + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskFe9Func; + task.usTaskPrio = 9; // 9, set reasonable priority. + task.pcName = "TaskFe_9"; + task.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + task.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + ret = LOS_TaskCreate(&g_testTaskID02, &task); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 12, g_testCount, EXIT); // 12, here assert the result. + g_testCount++; + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskFe8Func; + task.usTaskPrio = 8; // 8, set reasonable priority. + task.pcName = "TaskFe_8"; + task.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + task.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + ret = LOS_TaskCreate(&g_testTaskID03, &task); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 14, g_testCount, EXIT); // 14, here assert the result. + g_testCount++; + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskFe7Func; + task.usTaskPrio = 7; // 7, set reasonable priority. + task.pcName = "TaskFe_7"; + task.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + task.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + ret = LOS_TaskCreate(&g_testTaskID04, &task); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 16, g_testCount, EXIT); // 16, here assert the result. + g_testCount++; + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 20, g_testCount, EXIT); // 20, here assert the result. + g_testCount++; + + ret = LOS_MuxUnlock(&g_testMux1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_ASSERT_EQUAL(g_testCount, 24, g_testCount); // 24, here assert the result. + + ret = LOS_MuxLock(&g_testMux2, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_MuxLock(&g_testMux3, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_MuxLock(&g_testMux4, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 24, g_testCount, EXIT); // 24, here assert the result. + +EXIT: + ret = LOS_MuxUnlock(&g_testMux2); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxUnlock(&g_testMux3); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxUnlock(&g_testMux4); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + UINT16 priority = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + ICUNIT_ASSERT_EQUAL(priority, TASK_PRIO_TEST_TASK, priority); + + ret = LOS_MuxDestroy(&g_testMux1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxDestroy(&g_testMux2); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxDestroy(&g_testMux3); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxDestroy(&g_testMux4); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosMux040(void) +{ + TEST_ADD_CASE("ItLosMux040", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_041.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_041.c new file mode 100644 index 00000000..f36ffe68 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_041.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "osTest.h" +#include "los_config.h" +#include "los_bitmap.h" +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +static LosMux g_testMux1; +static UINT32 g_mainTaskID; +static VOID TaskMisc10Func(VOID) +{ + UINT32 ret; + g_testCount++; + + ret = LOS_MuxLock(&g_testMux1, 100); // 100, init mutex. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ETIMEDOUT, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 3, g_testCount); // 3, here assert the result. + g_testCount++; + + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S taskParam = {0}; + g_testCount = 0; + LosTaskCB *task = NULL; + UINT16 prio = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + g_mainTaskID = OsCurrTaskGet()->taskID; + + ret = LosMuxCreate(&g_testMux1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_MuxLock(&g_testMux1, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + g_testCount++; + + taskParam.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskMisc10Func; + taskParam.usTaskPrio = 10; // 10, set reasonable priority. + taskParam.pcName = "TaskMisc_10"; + taskParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + taskParam.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + taskParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + ret = LOS_TaskCreate(&g_testTaskID01, &taskParam); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + UINT16 priority = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + ICUNIT_GOTO_EQUAL(priority, 10, priority, EXIT); // 10, here assert the result. + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, here assert the result. + g_testCount++; + + LOS_TaskDelay(110); // 110, set delay time. + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, here assert the result. + g_testCount++; + + ret = LOS_MuxUnlock(&g_testMux1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + priority = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + ICUNIT_GOTO_EQUAL(priority, prio, priority, EXIT); + +EXIT: + LOS_MuxUnlock(&g_testMux1); + ret = LOS_MuxDestroy(&g_testMux1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosMux041(void) +{ + TEST_ADD_CASE("ItLosMux041", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_042.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_042.c new file mode 100644 index 00000000..2126ec0c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_042.c @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "osTest.h" +#include "los_config.h" +#include "los_bitmap.h" +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +static LosMux g_testMux1; +static UINT32 g_mainTaskID; +static VOID TaskFe4Func(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 4, g_testCount); // 4, here assert the result. + g_testCount++; + + ret = LOS_MuxLock(&g_testMux1, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 8, g_testCount); // 8, here assert the result. + g_testCount++; + + return; +} + +static VOID TaskMisc10Func(VOID) +{ + UINT32 ret; + g_testCount++; + + ret = LOS_MuxLock(&g_testMux1, 100); // 100, init mutex. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ETIMEDOUT, ret); + + UINT16 priority = LOS_TaskPriGet(g_mainTaskID); + ICUNIT_ASSERT_EQUAL_VOID(priority, 4, priority); // 4, here assert the result. + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 6, g_testCount); // 6, here assert the result. + g_testCount++; + + return; +} + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S taskParam = {0}; + g_testCount = 0; + LosTaskCB *task = NULL; + UINT16 prio = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + g_mainTaskID = OsCurrTaskGet()->taskID; + + ret = LosMuxCreate(&g_testMux1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_MuxLock(&g_testMux1, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + g_testCount++; + g_testCount++; + + taskParam.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskMisc10Func; + taskParam.usTaskPrio = 10; // 10, set reasonable priority. + taskParam.pcName = "TaskMisc_10"; + taskParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + taskParam.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + taskParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + ret = LOS_TaskCreate(&g_testTaskID01, &taskParam); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + UINT16 priority = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + ICUNIT_GOTO_EQUAL(priority, 10, priority, EXIT); // 10, here assert the result. + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, here assert the result. + g_testCount++; + + taskParam.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskFe4Func; + taskParam.usTaskPrio = 4; // 4, set reasonable priority. + taskParam.pcName = "TaskFe_4"; + taskParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + taskParam.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + taskParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + ret = LOS_TaskCreate(&g_testTaskID03, &taskParam); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + priority = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + ICUNIT_GOTO_EQUAL(priority, 4, priority, EXIT); // 4, here assert the result. + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); // 5, here assert the result. + g_testCount++; + + LOS_TaskDelay(200); // 200, set delay time. + + ICUNIT_GOTO_EQUAL(g_testCount, 7, g_testCount, EXIT); // 7, here assert the result. + g_testCount++; + + ret = LOS_MuxUnlock(&g_testMux1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + priority = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + ICUNIT_GOTO_EQUAL(priority, prio, priority, EXIT); + + ret = LOS_MuxLock(&g_testMux1, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 9, g_testCount, EXIT); // 9, here assert the result. + +EXIT: + ret = LOS_MuxUnlock(&g_testMux1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxDestroy(&g_testMux1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosMux042(void) +{ + TEST_ADD_CASE("ItLosMux042", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_043.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_043.c new file mode 100644 index 00000000..685e5aa3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/full/It_los_mutex_043.c @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "osTest.h" +#include "los_config.h" +#include "los_bitmap.h" +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +static LosMux g_testMux1; +static LosMux g_testMux2; +static UINT32 g_mainTaskID; +static VOID TaskFe4Func(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 4, g_testCount); // 4, here assert the result. + g_testCount++; + + ret = LOS_MuxLock(&g_testMux2, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + UINT16 priority = LOS_TaskPriGet(g_mainTaskID); + ICUNIT_ASSERT_EQUAL_VOID(priority, 10, priority); // 10, here assert the result. + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 6, g_testCount); // 6, here assert the result. + g_testCount++; + + ret = LOS_MuxUnlock(&g_testMux2); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + return; +} + +static VOID TaskMisc10Func(VOID) +{ + UINT32 ret; + g_testCount++; + + ret = LOS_MuxLock(&g_testMux1, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 8, g_testCount); // 8, here assert the result. + g_testCount++; + + ret = LOS_MuxUnlock(&g_testMux1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S taskParam = { 0 }; + g_testCount = 0; + LosTaskCB *task = NULL; + LosMuxAttr attr = { 0 }; + + UINT16 prio = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + g_mainTaskID = OsCurrTaskGet()->taskID; + + ret = LosMuxCreate(&g_testMux1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_MuxAttrInit(&attr); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_MuxAttrSetProtocol(&attr, LOS_MUX_PRIO_NONE); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_MuxInit(&g_testMux2, &attr); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_MuxLock(&g_testMux1, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_MuxLock(&g_testMux2, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + g_testCount++; + g_testCount++; + + taskParam.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskMisc10Func; + taskParam.usTaskPrio = 10; // 10, set reasonable priority. + taskParam.pcName = "TaskMisc_10"; + taskParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + taskParam.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + taskParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + ret = LOS_TaskCreate(&g_testTaskID01, &taskParam); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + UINT16 priority = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + ICUNIT_GOTO_EQUAL(priority, 10, priority, EXIT); // 10, here assert the result. + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, here assert the result. + g_testCount++; + + taskParam.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskFe4Func; + taskParam.usTaskPrio = 4; // 4, set reasonable priority. + taskParam.pcName = "TaskFe_4"; + taskParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + taskParam.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + taskParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + + ret = LOS_TaskCreate(&g_testTaskID03, &taskParam); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + priority = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + ICUNIT_GOTO_EQUAL(priority, 10, priority, EXIT); // 10, here assert the result. + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); // 5, here assert the result. + g_testCount++; + + ret = LOS_MuxUnlock(&g_testMux2); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 7, g_testCount, EXIT); // 7, here assert the result. + g_testCount++; + + ret = LOS_MuxUnlock(&g_testMux1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + priority = LOS_TaskPriGet(OsCurrTaskGet()->taskID); + ICUNIT_GOTO_EQUAL(priority, prio, priority, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 9, g_testCount, EXIT); // 9, here assert the result. + +EXIT: + ret = LOS_MuxDestroy(&g_testMux1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxDestroy(&g_testMux2); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosMux043(void) +{ + TEST_ADD_CASE("ItLosMux043", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smoke/It_los_mutex_001.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smoke/It_los_mutex_001.c new file mode 100644 index 00000000..3d90cafd --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smoke/It_los_mutex_001.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 *mutex = NULL; + LosMux mutex1; + + ret = LosMuxCreate(mutex); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_MUX_PTR_NULL, ret); + + ret = LosMuxCreate(&mutex1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxDestroy(&mutex1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + + +VOID ItLosMux001(void) +{ + TEST_ADD_CASE("ItLosMux001", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smoke/It_los_mutex_002.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smoke/It_los_mutex_002.c new file mode 100644 index 00000000..1fe42276 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smoke/It_los_mutex_002.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + LosMux maxSem; + LosMux semTemp; + UINT32 ret; + + UINT32 *mutex = NULL; + LosMux mutex1; + + ret = LosMuxCreate(&mutex1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxDestroy(&mutex1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxDestroy(&mutex1); + ICUNIT_ASSERT_EQUAL(ret, EBADF, ret); + + ret = LOS_MuxDestroy(&maxSem); + ICUNIT_ASSERT_EQUAL(ret, EBADF, ret); + + ret = LOS_MuxDestroy(&semTemp); + ICUNIT_ASSERT_EQUAL(ret, EBADF, ret); + + return LOS_OK; +} + + +VOID ItLosMux002(void) +{ + TEST_ADD_CASE("ItLosMux002", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smoke/It_los_mutex_003.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smoke/It_los_mutex_003.c new file mode 100644 index 00000000..70a19cbe --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smoke/It_los_mutex_003.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + LosMux muxHandle; + + ret = LosMuxCreate(&muxHandle); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxLock(&muxHandle, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxDestroy(&muxHandle); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_MUX_PENDED, ret); + + ret = LOS_MuxUnlock(&muxHandle); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxDestroy(&muxHandle); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxLock(&muxHandle, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL(ret, EBADF, ret); + + return LOS_OK; +} + + +VOID ItLosMux003(void) +{ + TEST_ADD_CASE("ItLosMux003", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smoke/It_los_mutex_004.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smoke/It_los_mutex_004.c new file mode 100644 index 00000000..cbe0333f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smoke/It_los_mutex_004.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + LosMux muxHandle; + + ret = LosMuxCreate(&muxHandle); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxLock(&muxHandle, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxLock(&muxHandle, 1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxDestroy(&muxHandle); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_MUX_PENDED, ret); + + ret = LOS_MuxUnlock(&muxHandle); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxDestroy(&muxHandle); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_MUX_PENDED, ret); + + ret = LOS_MuxUnlock(&muxHandle); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxDestroy(&muxHandle); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxLock(&muxHandle, 0); + ICUNIT_ASSERT_EQUAL(ret, EBADF, ret); + + return LOS_OK; +} + + +VOID ItLosMux004(void) +{ + TEST_ADD_CASE("ItLosMux004", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_001.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_001.c new file mode 100644 index 00000000..55b27696 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_001.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void Task01(VOID) +{ + UINT32 ret; + + ret = LOS_MuxLock(&g_mutexTest1, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_MuxUnlock(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 currCpuid; + g_testCount = 0; + TSK_INIT_PARAM_S task = { 0 }; + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LosMuxCreate(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxLock(&g_mutexTest1, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)Task01; + task.pcName = "Test Case 1"; + task.uwStackSize = TASK_STACK_SIZE_TEST; + task.usTaskPrio = TASK_PRIO_TEST_TASK; + task.uwResved = LOS_TASK_STATUS_DETACHED; + task.usCpuAffiMask = CPUID_TO_AFFI_MASK(currCpuid); + + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxUnlock(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 1); // 100, delay for Timing control. + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = LOS_MuxDestroy(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItSmpLosMux001(void) +{ + TEST_ADD_CASE("ItSmpLosMux001", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_002.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_002.c new file mode 100644 index 00000000..7f8215d1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_002.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void Task01(VOID) +{ + UINT32 ret; + + ret = LOS_MuxLock(&g_mutexTest1, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_MuxUnlock(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 currCpuid; + g_testCount = 0; + TSK_INIT_PARAM_S task = { 0 }; + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LosMuxCreate(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)Task01; + task.pcName = "Test Case 1"; + task.uwStackSize = TASK_STACK_SIZE_TEST; + task.usTaskPrio = TASK_PRIO_TEST_TASK; + task.uwResved = LOS_TASK_STATUS_DETACHED; + task.usCpuAffiMask = CPUID_TO_AFFI_MASK(currCpuid); + + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 1); // 100, delay for Timing control. + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + ret = LOS_MuxLock(&g_mutexTest1, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_MuxUnlock(&g_mutexTest1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + ret = LOS_MuxDestroy(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItSmpLosMux002(void) +{ + TEST_ADD_CASE("ItSmpLosMux002", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_003.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_003.c new file mode 100644 index 00000000..48dab1f0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_003.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static void Hwi01(VOID) +{ + UINT32 ret; + + ret = LOS_MuxUnlock(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_MUX_PEND_INTERR, ret); + + TEST_HwiClear(HWI_NUM_TEST); + + g_testCount++; +} + +static void Task01(VOID) +{ + UINT32 ret; + + TestHwiTrigger(HWI_NUM_TEST); + + g_testCount++; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 currCpuid; + g_testCount = 0; + TSK_INIT_PARAM_S task = { 0 }; + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LosMuxCreate(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 0, 0, (HWI_PROC_FUNC)Hwi01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(currCpuid)); + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)Task01; + task.pcName = "Test Case 1"; + task.uwStackSize = TASK_STACK_SIZE_TEST; + task.usTaskPrio = TASK_PRIO_TEST_TASK; + task.uwResved = LOS_TASK_STATUS_DETACHED; + task.usCpuAffiMask = CPUID_TO_AFFI_MASK(currCpuid); + + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxLock(&g_mutexTest1, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, 2, delay for Timing control. + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, here assert the result. + + TEST_HwiDelete(HWI_NUM_TEST); + + ret = LOS_MuxUnlock(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxDestroy(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +EXIT: + TEST_HwiDelete(HWI_NUM_TEST); + LOS_TaskDelete(g_testTaskID01); + LOS_MuxUnlock(&g_mutexTest1); + LOS_MuxDestroy(&g_mutexTest1); + return LOS_OK; +} + +VOID ItSmpLosMux003(void) +{ + TEST_ADD_CASE("ItSmpLosMux003", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_004.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_004.c new file mode 100644 index 00000000..a7a0f1ff --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_004.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void Task01(VOID) +{ + UINT32 ret; + + ret = LOS_MuxDestroy(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 currCpuid; + g_testCount = 0; + TSK_INIT_PARAM_S task = { 0 }; + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LosMuxCreate(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)Task01; + task.pcName = "Test Case 1"; + task.uwStackSize = TASK_STACK_SIZE_TEST; + task.usTaskPrio = TASK_PRIO_TEST_TASK; + task.uwResved = LOS_TASK_STATUS_DETACHED; + task.usCpuAffiMask = CPUID_TO_AFFI_MASK(currCpuid); + + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 1); // 100, delay for Timing control. + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + return LOS_OK; +} + +VOID ItSmpLosMux004(void) +{ + TEST_ADD_CASE("ItSmpLosMux004", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_005.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_005.c new file mode 100644 index 00000000..886278e9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_005.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static void Task01(VOID) +{ + UINT32 ret; + + ret = LOS_MuxDestroy(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_MUX_PENDED, ret); + g_testCount++; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 currCpuid; + g_testCount = 0; + TSK_INIT_PARAM_S task = { 0 }; + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LosMuxCreate(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxLock(&g_mutexTest1, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)Task01; + task.pcName = "Test Case 1"; + task.uwStackSize = TASK_STACK_SIZE_TEST; + task.usTaskPrio = TASK_PRIO_TEST_TASK; + task.uwResved = LOS_TASK_STATUS_DETACHED; + task.usCpuAffiMask = CPUID_TO_AFFI_MASK(currCpuid); + + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 1); // 100, delay for Timing control. + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = LOS_MuxUnlock(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxDestroy(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItSmpLosMux005(void) +{ + TEST_ADD_CASE("ItSmpLosMux005", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_006.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_006.c new file mode 100644 index 00000000..fbc514a4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_006.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void Task01(VOID) +{ + UINT32 ret; + + ret = LosMuxCreate(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_MuxLock(&g_mutexTest1, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_MuxUnlock(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_MuxDestroy(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + g_testCount++; +} + +static void Task02(VOID) +{ + UINT32 ret; + + ret = LosMuxCreate(&g_mutexTest2); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_MuxLock(&g_mutexTest2, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_MuxUnlock(&g_mutexTest2); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_MuxDestroy(&g_mutexTest2); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + g_testCount++; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid, currCpuid2; + g_testCount = 0; + TSK_INIT_PARAM_S task = { 0 }; + TSK_INIT_PARAM_S task2 = { 0 }; + currCpuid = ArchCurrCpuid() % (LOSCFG_KERNEL_CORE_NUM - 1) + 1; + currCpuid2 = currCpuid % (LOSCFG_KERNEL_CORE_NUM - 1) + 1; + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)Task01; + task.pcName = "Test Case 1"; + task.uwStackSize = TASK_STACK_SIZE_TEST; + task.uwResved = LOS_TASK_STATUS_DETACHED; + task.usCpuAffiMask = CPUID_TO_AFFI_MASK(currCpuid); + + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task2.pfnTaskEntry = (TSK_ENTRY_FUNC)Task02; + task2.pcName = "Test Case 2"; + task2.uwStackSize = TASK_STACK_SIZE_TEST; + task2.uwResved = LOS_TASK_STATUS_DETACHED; + task2.usCpuAffiMask = CPUID_TO_AFFI_MASK(currCpuid2); + + ret = LOS_TaskCreate(&g_testTaskID02, &task2); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, 2, delay for Timing control. + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, here assert the result. + + return LOS_OK; +} + +VOID ItSmpLosMux006(void) +{ + TEST_ADD_CASE("ItSmpLosMux006", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_007.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_007.c new file mode 100644 index 00000000..13ca805d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_007.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static void Task01(VOID) +{ + UINT32 ret; + + ret = LOS_MuxLock(&g_mutexTest1, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestBusyTaskDelay(5); // 5, delay for Timing control. + + ret = LOS_MuxUnlock(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; +} + +static void Task02(VOID) +{ + UINT32 ret; + + ret = LOS_MuxLock(&g_mutexTest1, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestBusyTaskDelay(5); // 5, delay for Timing control. + + ret = LOS_MuxUnlock(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid, currCpuid2; + g_testCount = 0; + TSK_INIT_PARAM_S task = { 0 }; + TSK_INIT_PARAM_S task2 = { 0 }; + currCpuid = ArchCurrCpuid() % (LOSCFG_KERNEL_CORE_NUM - 1) + 1; + currCpuid2 = currCpuid % (LOSCFG_KERNEL_CORE_NUM - 1) + 1; + + ret = LosMuxCreate(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)Task01; + task.pcName = "Test Case 1"; + task.uwStackSize = TASK_STACK_SIZE_TEST; + task.uwResved = LOS_TASK_STATUS_DETACHED; + task.usCpuAffiMask = CPUID_TO_AFFI_MASK(currCpuid); + + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task2.pfnTaskEntry = (TSK_ENTRY_FUNC)Task02; + task2.pcName = "Test Case 2"; + task2.uwStackSize = TASK_STACK_SIZE_TEST; + task2.uwResved = LOS_TASK_STATUS_DETACHED; + task2.usCpuAffiMask = CPUID_TO_AFFI_MASK(currCpuid2); + + ret = LOS_TaskCreate(&g_testTaskID02, &task2); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, 2, delay for Timing control. + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, here assert the result. + + ret = LOS_MuxDestroy(&g_mutexTest1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItSmpLosMux007(void) +{ + TEST_ADD_CASE("ItSmpLosMux007", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2001.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2001.c new file mode 100644 index 00000000..d9b9860b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2001.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S testTask = {0}; + + g_testCount = 0; + + ret = LosMuxCreate(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_001_task", TaskF01, TASK_PRIO_TEST_TASK - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, here assert the result. + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_MuxDestroy(&g_mutexkernelTest); + return LOS_OK; +} + + +VOID ItSmpLosMux2001(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosMux2001", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2002.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2002.c new file mode 100644 index 00000000..16df543b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2002.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask = {0}; + + g_testCount = 0; + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LosMuxCreate(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_001_task", TaskF01, TASK_PRIO_TEST_TASK - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, 2, delay for Timing control. + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, here assert the result. + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_MuxDestroy(&g_mutexkernelTest); + return LOS_OK; +} + + +VOID ItSmpLosMux2002(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosMux2002", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2003.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2003.c new file mode 100644 index 00000000..94127af4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2003.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static VOID HwiF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask = {0}; + + g_testCount = 0; + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LosMuxCreate(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + + TestHwiTrigger(HWI_NUM_TEST); + + TestAssertBusyTaskDelay(100, 2); // 100, 2, delay for Timing control. + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, here assert the result. + +EXIT: + LOS_HwiDelete(HWI_NUM_TEST, NULL); + LOS_MuxDestroy(&g_mutexkernelTest); + return LOS_OK; +} + + +VOID ItSmpLosMux2003(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosMux2003", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2004.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2004.c new file mode 100644 index 00000000..67286fa6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2004.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S testTask = {0}; + + g_testCount = 0; + + ret = LosMuxCreate(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_001_task", TaskF01, TASK_PRIO_TEST_TASK - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, here assert the result. + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_MuxDestroy(&g_mutexkernelTest); + return LOS_OK; +} + + +VOID ItSmpLosMux2004(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosMux2004", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2005.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2005.c new file mode 100644 index 00000000..2794a3da --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2005.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + + TestAssertBusyTaskDelay(100, 3); // 100, 3, delay for Timing control. + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, here assert the result. + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + + TestDumpCpuid(); + return; +EXIT: + LOS_MuxUnlock(&g_mutexkernelTest); + LOS_TaskDelete(g_testTaskID01); + return; +} + +static VOID TaskF02(VOID) +{ + UINT32 ret; + + TestAssertBusyTaskDelay(100, 2); // 100, 2, delay for Timing control. + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, here assert the result. + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_MUX_PENDED, ret); + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask = {0}; + + g_testCount = 0; + + ret = LosMuxCreate(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_005_task2", TaskF02, TASK_PRIO_TEST_TASK - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_005_task1", TaskF01, TASK_PRIO_TEST_TASK - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 4); // 100, 4, delay for Timing control. + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, here assert the result. + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + + +VOID ItSmpLosMux2005(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosMux2005", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2006.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2006.c new file mode 100644 index 00000000..674998bf --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2006.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 volatile g_runFlag = 0; +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + + do { + __asm__ volatile("nop"); + } while (g_runFlag); + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + + TestDumpCpuid(); + return; +} + + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask = {0}; + + g_testCount = 0; + g_runFlag = 1; + + ret = LosMuxCreate(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_006_task1", TaskF01, TASK_PRIO_TEST_TASK - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, 2, delay for Timing control. + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, here assert the result. + + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_MUX_PENDED, ret); + + g_runFlag = 0; + TestAssertBusyTaskDelay(100, 3); // 100, 3, delay for Timing control. + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, here assert the result. + +EXIT: + LOS_TaskDelete(g_testTaskID01); + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + + +VOID ItSmpLosMux2006(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosMux2006", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2007.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2007.c new file mode 100644 index 00000000..6a5f871b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2007.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + + LOS_TaskDelay(2); // 2, delay for Timing control. + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static VOID TaskF02(VOID) +{ + UINT32 ret; + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, here assert the result. + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_MUX_PENDED, ret); + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask = {0}; + + g_testCount = 0; + + ret = LosMuxCreate(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + // 2, set reasonable priority. + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_007_task1", TaskF01, TASK_PRIO_TEST_TASK - 2, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_007_task2", TaskF02, TASK_PRIO_TEST_TASK - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 4); // 100, 4, delay for Timing control. + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, here assert the result. + + LOS_TaskDelay(10); // 10, delay for Timing control. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_UNUSED, 0, ret, EXIT); + + ret = OS_TCB_FROM_TID(g_testTaskID02)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_UNUSED, 0, ret, EXIT); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + + +VOID ItSmpLosMux2007(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosMux2007", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2008.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2008.c new file mode 100644 index 00000000..1c65cf77 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2008.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID HwiF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_MUX_PEND_INTERR, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask = {0}; + + g_testCount = 0; + + ret = LosMuxCreate(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + + TestHwiTrigger(HWI_NUM_TEST); + + TestAssertBusyTaskDelay(100, 2); // 100, 2, delay for Timing control. + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, here assert the result. + + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + +EXIT: + LOS_HwiDelete(HWI_NUM_TEST, NULL); + LOS_MuxDestroy(&g_mutexkernelTest); + return LOS_OK; +} + +VOID ItSmpLosMux2008(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosMux2008", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2009.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2009.c new file mode 100644 index 00000000..4769261d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2009.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + + TestAssertBusyTaskDelay(100, 3); // 100, 3, delay for Timing control. + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, here assert the result. +EXIT: + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static VOID HwiF01(VOID) +{ + UINT32 ret; + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_MUX_PENDED, ret); + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask = {0}; + + g_testCount = 0; + + ret = LosMuxCreate(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_009_task", TaskF01, TASK_PRIO_TEST_TASK - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, 2, delay for Timing control. + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, here assert the result. + + TestHwiTrigger(HWI_NUM_TEST); + + TestAssertBusyTaskDelay(100, 4); // 100, 4, delay for Timing control. + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, here assert the result. + +EXIT: + LOS_TaskDelay(10); // 10, delay for Timing control. + LOS_TaskDelete(g_testTaskID01); + ret = LOS_HwiDelete(HWI_NUM_TEST, NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + + +VOID ItSmpLosMux2009(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosMux2009", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2010.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2010.c new file mode 100644 index 00000000..7debeca2 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2010.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); +EXIT: + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + LOS_AtomicInc(&g_testCount); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S testTask = {0}; + + g_testCount = 0; + + ret = LosMuxCreate(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_010_task1", TaskF01, TASK_PRIO_TEST_TASK - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, here assert the result. + + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_MuxDestroy(&g_mutexkernelTest); + return LOS_OK; +} + + +VOID ItSmpLosMux2010(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosMux2010", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2011.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2011.c new file mode 100644 index 00000000..c1f5ddc8 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2011.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF02(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + LOS_TaskDelay(2); // 2, delay for Timing control. + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, here assert the result. // task f01 pend + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + LOS_AtomicInc(&g_testCount); + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask = {0}; + + g_testCount = 0; + + ret = LosMuxCreate(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_011_task2", TaskF02, TASK_PRIO_TEST_TASK - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + do { + __asm__ volatile("nop"); + } while (g_testCount != 1); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_011_task1", TaskF01, TASK_PRIO_TEST_TASK + 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(10); // 10, delay for Timing control. // TaskF01 run + + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); // 5, here assert the result. + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + LOS_MuxDestroy(&g_mutexkernelTest); + return LOS_OK; +} + + +VOID ItSmpLosMux2011(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosMux2011", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2012.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2012.c new file mode 100644 index 00000000..9650daa5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2012.c @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, here assert the result. + LOS_AtomicInc(&g_testCount); + + ret = LOS_MuxLock(&g_mutexkernelTest, 5); // 5, init mutex. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_MUX_TIMEOUT, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, here assert the result. + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +EXIT: + LOS_TaskDelete(g_testTaskID01); + return; +} + +static VOID TaskF02(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + + LOS_TaskDelay(100); // 100, set delay time. + + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); // 5, here assert the result. +EXIT: + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + LOS_AtomicInc(&g_testCount); + return; +} + +static VOID HwiF01(VOID) +{ + UINT32 ret; + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, here assert the result. + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_MUX_PEND_INTERR, ret); + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +EXIT: + LOS_HwiDelete(HWI_NUM_TEST, NULL); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask = {0}; + + g_testCount = 0; + + ret = LosMuxCreate(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_MUX_2012_task1", TaskF02, TASK_PRIO_TEST_TASK - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, 2, delay for Timing control. + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, here assert the result. + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_MUX_2012_task2", TaskF01, TASK_PRIO_TEST_TASK + 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(1); // task f01 run + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, here assert the result. + + TestHwiTrigger(HWI_NUM_TEST); + + LOS_TaskDelay(200); // 200, set delay time. + + ICUNIT_GOTO_EQUAL(g_testCount, 6, g_testCount, EXIT); // 6, here assert the result. + + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + ret = LOS_HwiDelete(HWI_NUM_TEST, NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + LOS_MuxDestroy(&g_mutexkernelTest); + return LOS_OK; +} + + +VOID ItSmpLosMux2012(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosMux2012", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2013.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2013.c new file mode 100644 index 00000000..13561559 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2013.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + + LOS_AtomicInc(&g_testCount); + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static VOID TaskF02(VOID) +{ + UINT32 ret; + + do { + __asm__ volatile("nop"); + } while (g_testCount != 3); // 3, wait until g_testCount == 3. + + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask = {0}; + + g_testCount = 0; + + ret = LosMuxCreate(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_013_task1", TaskF01, TASK_PRIO_TEST_TASK - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_013_task2", TaskF02, TASK_PRIO_TEST_TASK - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 4); // 100, 4, delay for Timing control. + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, here assert the result. + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + LOS_MuxDestroy(&g_mutexkernelTest); + return LOS_OK; +} + +VOID ItSmpLosMux2013(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosMux2013", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2014.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2014.c new file mode 100644 index 00000000..4c25064f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2014.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF02(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + + LOS_TaskDelay(5); // 5, delay for Timing control. + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + LOS_AtomicInc(&g_testCount); + + do { + __asm__ volatile("nop"); + } while (g_testCount != 3); // 3, wait until g_testCount == 3. + + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + + TestDumpCpuid(); + return; +} +static VOID TaskF01(VOID) +{ + UINT32 ret; + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + LOS_AtomicInc(&g_testCount); + return; +} +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask = {0}; + + g_testCount = 0; + + ret = LosMuxCreate(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_014_task2", TaskF02, TASK_PRIO_TEST_TASK - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + do { + __asm__ volatile("nop"); + } while (g_testCount != 1); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_014_task1", TaskF01, TASK_PRIO_TEST_TASK + 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(10); // 10, delay for Timing control.// task f01 run + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, here assert the result. + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + LOS_MuxDestroy(&g_mutexkernelTest); + return LOS_OK; +} + + +VOID ItSmpLosMux2014(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosMux2014", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2015.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2015.c new file mode 100644 index 00000000..a1d94ed9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2015.c @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, here assert the result. + LOS_AtomicInc(&g_testCount); + + ret = LOS_MuxLock(&g_mutexkernelTest, 5); // 5, init mutex. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_MUX_TIMEOUT, ret); + PRINT_DEBUG("TaskF01 pend timeout\n"); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static VOID TaskF02(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + PRINT_DEBUG("delay in task f02\n"); + LOS_TaskDelay(10); // 10, delay for Timing control. + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + PRINT_DEBUG("post mux in task f02\n"); + LOS_AtomicInc(&g_testCount); + return; +} +static VOID HwiF01(VOID) +{ + UINT32 ret; + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_MUX_PEND_INTERR, ret); + PRINT_DEBUG("after post in hwi \n"); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} +static VOID HwiF02(VOID) +{ + UINT32 ret; + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask = {0}; + + g_testCount = 0; + + ret = LosMuxCreate(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_HwiCreate(HWI_NUM_TEST1, 1, 0, (HWI_PROC_FUNC)HwiF02, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + HalIrqSetAffinity(HWI_NUM_TEST1, CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_MUX_2015_task2", TaskF02, TASK_PRIO_TEST_TASK - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + do { + __asm__ volatile("nop"); + } while (g_testCount != 2); // 2, wait until g_testCount == 2. + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_MUX_2015_task1", TaskF01, TASK_PRIO_TEST_TASK + 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(1); // task f01 run + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, here assert the result. + + TestHwiTrigger(HWI_NUM_TEST); + + LOS_TaskDelay(1); + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, here assert the result. + + PRINT_DEBUG("delay in testtask begin\n"); + LOS_TaskDelay(20); // 20, delay for Timing control. + PRINT_DEBUG("delay in testtask end\n"); + TestHwiTrigger(HWI_NUM_TEST1); + + LOS_TaskDelay(1); + ICUNIT_GOTO_EQUAL(g_testCount, 7, g_testCount, EXIT); // 7, here assert the result. + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + ret = LOS_HwiDelete(HWI_NUM_TEST, NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ret = LOS_HwiDelete(HWI_NUM_TEST1, NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + LOS_MuxDestroy(&g_mutexkernelTest); + return LOS_OK; +} + + +VOID ItSmpLosMux2015(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosMux2015", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2016.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2016.c new file mode 100644 index 00000000..7b0444e3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2016.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S testTask = {0}; + + g_testCount = 0; + + ret = LosMuxCreate(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_001_task", TaskF01, TASK_PRIO_TEST_TASK - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_PEND, 0, ret, EXIT); + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(10); // 10, delay for Timing control. + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + + +VOID ItSmpLosMux2016(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosMux2016", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2017.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2017.c new file mode 100644 index 00000000..43e52e94 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2017.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask = {0}; + + g_testCount = 0; + + ret = LosMuxCreate(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_001_task", TaskF01, TASK_PRIO_TEST_TASK - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 1); // 100, 1, delay for Timing control. + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + /* wait for task01 to pend sem */ + TestBusyTaskDelay(2); // 2, delay for Timing control. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_PEND, 0, ret, EXIT); + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(10); // 10, taskdelete other cpu's task need time + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(10); // 10, delay for Timing control. + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + +EXIT: + LOS_TaskPriSet(g_testTskHandle, TASK_PRIO_TEST_TASK); // recovery test task's prio + LOS_TaskDelete(g_testTaskID01); + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosMux2017(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosMux2017", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2018.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2018.c new file mode 100644 index 00000000..0ecc5bca --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2018.c @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static volatile UINT32 g_flag1 = 1; +static volatile UINT32 g_flag2 = 1; +static VOID TaskF01(VOID) +{ + UINT32 ret, i; + + LOS_AtomicInc(&g_testCount); + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + dprintf("task f01 get mux\n"); + LOS_AtomicInc(&g_testCount); + + do { + __asm__ volatile("nop"); + } while (g_flag1); + + dprintf("task f01 post mux\n"); + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + TestDumpCpuid(); + return; +} +static VOID TaskF02(VOID) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + dprintf("task f02 get mux\n"); + LOS_AtomicInc(&g_testCount); + + do { + __asm__ volatile("nop"); + } while (g_flag2); + dprintf("task f02 post mux\n"); + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask = {0}; + + g_testCount = 0; + g_flag1 = 1; + g_flag2 = 1; + + ret = LosMuxCreate(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_MUX_2018_task1", TaskF01, TASK_PRIO_TEST_TASK + 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_MUX_2018_task2", TaskF02, TASK_PRIO_TEST_TASK + 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu, low prio + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(2); // let task f02 run + + TestAssertBusyTaskDelay(100, 2); // 100, 2, wait for task f01 run + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, here assert the result. + + /* wait for task01 to pend sem */ + TestBusyTaskDelay(2); // 2, delay for Timing control. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_PEND, 0, ret, EXIT); + + ret = OS_TCB_FROM_TID(g_testTaskID02)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_PEND, 0, ret, EXIT); + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(10); // 10, delay for Timing control. + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, here assert the result. + + do { + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + + __asm__ volatile("nop"); + } while (!(ret & (OS_TASK_STATUS_RUNNING | OS_TASK_STATUS_PEND))); + + if (ret & OS_TASK_STATUS_RUNNING) { // task f01 get the mux + dprintf("running task f01\n"); + ret = LOS_TaskDelete(g_testTaskID02); // so delete the task f02 + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + g_flag1 = 0; // mux post in task f01 + g_flag2 = 1; + } else if (ret & OS_TASK_STATUS_PEND) { // task f02 get the mux + dprintf("pend task f01\n"); + ret = LOS_TaskDelete(g_testTaskID01); // so delete the task f01 + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + LOS_TaskDelay(2); // 2, cross core to delete task + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_UNUSED, 0, ret, EXIT); + g_flag2 = 0; // mux post in task f02 + g_flag1 = 1; + } else { + dprintf("ret = 0x%x\n", ret); + } + LOS_TaskDelay(10); // 10, delay for Timing control. + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, here assert the result. + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + + +VOID ItSmpLosMux2018(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosMux2018", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2021.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2021.c new file mode 100644 index 00000000..919a0570 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2021.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask = {0}; + + g_testCount = 0; + + ret = LosMuxCreate(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_021_task", TaskF01, TASK_PRIO_TEST_TASK - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 1); // 100, 1, delay for Timing control. + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + /* 2, wait for task01 to pend sem */ + TestBusyTaskDelay(2); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_PEND, 0, ret, EXIT); + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, 2, delay for Timing control. + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, here assert the result. + + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_MuxDestroy(&g_mutexkernelTest); + return LOS_OK; +} + +VOID ItSmpLosMux2021(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosMux2021", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2022.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2022.c new file mode 100644 index 00000000..d9d13bff --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2022.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID HwiF01(VOID) +{ + UINT32 ret; + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_MUX_PEND_INTERR, ret); + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask = {0}; + + g_testCount = 0; + + ret = LosMuxCreate(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestHwiTrigger(HWI_NUM_TEST); + + TestAssertBusyTaskDelay(100, 1); // 100, 1, delay for Timing control. + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + ret = LOS_HwiDelete(HWI_NUM_TEST, NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + LOS_MuxDestroy(&g_mutexkernelTest); + return LOS_OK; +} + +VOID ItSmpLosMux2022(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosMux2022", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2024.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2024.c new file mode 100644 index 00000000..6b922233 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2024.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF02(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + + TestDumpCpuid(); + return; +} + + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask = {0}; + + g_testCount = 0; + + ret = LosMuxCreate(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_014_task2", TaskF02, TASK_PRIO_TEST_TASK - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(1); + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + LOS_TaskDelay(1); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + +EXIT: + LOS_TaskDelete(g_testTaskID02); + LOS_MuxDestroy(&g_mutexkernelTest); + return LOS_OK; +} + + +VOID ItSmpLosMux2024(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosMux2024", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2025.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2025.c new file mode 100644 index 00000000..958a97d1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2025.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID HwiF01(VOID) +{ + UINT32 ret; + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_MUX_PEND_INTERR, ret); + + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask = {0}; + + g_testCount = 0; + + ret = LosMuxCreate(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + TestHwiTrigger(HWI_NUM_TEST); + + TestAssertBusyTaskDelay(100, 1); // 100, 1, delay for Timing control. + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + ret = LOS_HwiDelete(HWI_NUM_TEST, NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + LOS_MuxDestroy(&g_mutexkernelTest); + return LOS_OK; +} + + +VOID ItSmpLosMux2025(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosMux2025", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2026.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2026.c new file mode 100644 index 00000000..8b410a54 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2026.c @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 4, g_testCount); // 4, here assert the result. + + LOS_AtomicInc(&g_testCount); + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + return; +} + +static VOID TaskF02(VOID) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, other core get the sem first + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + + TestDumpCpuid(); + return; +} + + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid, i, uvIntSave; + TSK_INIT_PARAM_S testTask = {0}; + + g_testCount = 0; + + ret = LosMuxCreate(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + // 3, set reasonable priority. + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_MUX_2026_task2", TaskF02, TASK_PRIO_TEST_TASK - 3, + CPUID_TO_AFFI_MASK(currCpuid)); // let the task f02 pend mux first + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 1); // 100, delay for Timing control. + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_MUX_2026_task1", TaskF01, TASK_PRIO_TEST_TASK - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(2); // test task's prio be set 22 + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); + + LOS_TaskLock(); + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); // task schedule in other cpu + + TestAssertBusyTaskDelay(100, 3); // 100, 3, delay for Timing control. + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT1); // 3, not schedule in current cpu cause tasklock + + LOS_AtomicInc(&g_testCount); + + LOS_TaskUnlock(); + + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); // 5, here assert the result. + +EXIT: + + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +EXIT1: + LOS_TaskUnlock(); + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosMux2026(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosMux2026", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2027.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2027.c new file mode 100644 index 00000000..cf145ddb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2027.c @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static volatile UINT32 g_runFlag = 1; +static VOID TaskF01(VOID) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 3, g_testCount); // 3, here assert the result. + LOS_AtomicInc(&g_testCount); + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + return; +} + +static VOID TaskF02(VOID) +{ + UINT32 ret, uvIntSave; + + LOS_TaskLock(); // task lock on other cpu + LOS_AtomicInc(&g_testCount); + + do { + __asm__ volatile("nop"); + } while (g_runFlag == 1); + + LOS_TaskUnlock(); // schedule occur ---switch to task f01 + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 4, g_testCount); // 4, here assert the result. + + TestDumpCpuid(); + return; +} + + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid, i; + TSK_INIT_PARAM_S testTask = {0}; + + g_testCount = 0; + g_runFlag = 1; + + ret = LosMuxCreate(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_sem_034_task1", TaskF01, TASK_PRIO_TEST_TASK - 2, // 2, set reasonable priority. + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_sem_034_task2", TaskF02, TASK_PRIO_TEST_TASK - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, 2, delay for Timing control. + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, here assert the result. + + /* 2, wait for task01 to pend mutex */ + TestBusyTaskDelay(2); + + ret = LOS_MuxUnlock(&g_mutexkernelTest); // try to wake task f01 + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(10); // 10, delay enough time for other cpu + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, cause tasklock on other cpu ,so task f01 wake failed + + LOS_AtomicInc(&g_testCount); + + g_runFlag = 0; // unlock the other cpu + LOS_TaskDelay(10); // 10, delay for Timing control. + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, not schedule in current cpu cause tasklock + +EXIT: + + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + ret = LOS_MuxDestroy(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosMux2027(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosMux2027", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2028.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2028.c new file mode 100644 index 00000000..5b0abe3d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2028.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret, i; + + LOS_AtomicInc(&g_testCount); + + for (i = 0; i < TRandom() % 500; i++) { // 500, get rand number in 500. + } + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + do { + __asm__ volatile("nop"); + } while (1); + TestDumpCpuid(); + return; +} + + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid, i, j; + TSK_INIT_PARAM_S testTask = {0}; + + for (i = 0; i < LOOP; i++) { + g_testCount = 0; + + ret = LosMuxCreate(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_mux_028_task", TaskF01, TASK_PRIO_TEST_TASK - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + do { + __asm__ volatile("nop"); + } while (g_testCount == 0); // wait for task f01 run + + for (j = 0; j < TRandom() % 500; j++) { // 500, get rand number in 500. + } + ret = LOS_TaskDelete(g_testTaskID01); + if (ret != LOS_OK && ret != LOS_ERRNO_TSK_MP_SYNC_FAILED) { + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + } + + LOS_TaskDelay(10); // 10, delay for Timing control. + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(10); // 10, delay for Timing control. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_EQUAL(ret, OS_TASK_STATUS_UNUSED, ret, EXIT); + + LOS_MuxDestroy(&g_mutexkernelTest); + } + +EXIT: + LOS_TaskPriSet(g_testTskHandle, TASK_PRIO_TEST_TASK); // recovery test task's prio + LOS_TaskDelete(g_testTaskID01); + LOS_MuxDestroy(&g_mutexkernelTest); + return LOS_OK; +} + + +VOID ItSmpLosMux2028(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosMux2028", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2029.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2029.c new file mode 100644 index 00000000..6e7dae6e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/mux/smp/It_smp_los_mux_2029.c @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_ret = 0xff; +static VOID TaskF01(VOID) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); // pend on current cpu + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + + ret = LOS_MuxUnlock(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + return; +} + +static VOID TaskF02(VOID) +{ + UINT32 ret, i; + + LOS_AtomicInc(&g_testCount); + + for (i = 0; i < TRandom() % 500; i++) { // 500, get rand number in 500. + } + + ret = LOS_TaskDelete(g_testTaskID01); + g_ret = ret; + + LOS_AtomicInc(&g_testCount); + + TestDumpCpuid(); + return; +} +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid, i, j; + TSK_INIT_PARAM_S testTask = {0}; + + g_testCount = 0; + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + for (i = 0; i < LOOP; i++) { + PRINT_DEBUG("i = %d\n", i); + ret = LosMuxCreate(&g_mutexkernelTest); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_MuxLock(&g_mutexkernelTest, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_smp_event_037_task1", TaskF01, TASK_PRIO_TEST_TASK - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_smp_event_037_task2", TaskF02, TASK_PRIO_TEST_TASK - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_PEND, 0, ret, EXIT); + + do { + __asm__ volatile("nop"); + } while (g_testCount == 1); // wait for task f02 + + for (j = 0; j < TRandom() % 500; j++) { // 500, get rand number in 500. + } + + ret = LOS_MuxUnlock(&g_mutexkernelTest); // try to wake task f01 + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(10); // 10, delay for Timing control. + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_UNUSED, 0, ret, EXIT); + + if ((g_ret != LOS_OK) && (g_ret != LOS_ERRNO_TSK_NOT_CREATED)) { + ICUNIT_GOTO_EQUAL(1, 0, g_ret, EXIT); + } + + PRINT_DEBUG("g_testCount = %d ,g_ret = 0x%x\n", g_testCount, g_ret); + + LOS_MuxDestroy(&g_mutexkernelTest); + } +EXIT: + + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + LOS_MuxDestroy(&g_mutexkernelTest); + return LOS_OK; +} + +VOID ItSmpLosMux2029(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosMux2029", Testcase, TEST_LOS, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/It_los_queue.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/It_los_queue.c new file mode 100644 index 00000000..e1828b25 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/It_los_queue.c @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "It_los_queue.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +VOID ItSuiteLosQueue(VOID) +{ +#ifdef LOSCFG_KERNEL_SMP + ItSmpLosQueue001(); + ItSmpLosQueue002(); + ItSmpLosQueue003(); + ItSmpLosQueue004(); + ItSmpLosQueue005(); + ItSmpLosQueue006(); + ItSmpLosQueue007(); + ItSmpLosQueue008(); + ItSmpLosQueue009(); + ItSmpLosQueue010(); + ItSmpLosQueue011(); + ItSmpLosQueue012(); + ItSmpLosQueue013(); + ItSmpLosQueue014(); + ItSmpLosQueue015(); + ItSmpLosQueue016(); + ItSmpLosQueue017(); + ItSmpLosQueue018(); + ItSmpLosQueue019(); + ItSmpLosQueue020(); + ItSmpLosQueue021(); + ItSmpLosQueue022(); + ItSmpLosQueue023(); + ItSmpLosQueue024(); + ItSmpLosQueue025(); + ItSmpLosQueue026(); + ItSmpLosQueue027(); + ItSmpLosQueue029(); + ItSmpLosQueue031(); + ItSmpLosQueue032(); +#endif +#if defined(LOSCFG_TEST_SMOKE) + ItLosQueue001(); + ItLosQueue097(); +#if (LOS_MEM_TLSF == 1) +#else + ItLosQueue100(); + ItLosQueue105(); +#endif + ItLosQueueHead002(); +#endif + +#if defined(LOSCFG_TEST_FULL) + ItLosQueue002(); + ItLosQueue003(); + ItLosQueue005(); + ItLosQueue006(); + ItLosQueue007(); + ItLosQueue008(); + ItLosQueue009(); + ItLosQueue010(); + ItLosQueue011(); + ItLosQueue012(); + ItLosQueue013(); + ItLosQueue014(); + ItLosQueue015(); + ItLosQueue017(); + ItLosQueue018(); + ItLosQueue019(); + ItLosQueue020(); +#ifndef LOSCFG_KERNEL_SMP + ItLosQueue021(); +#endif + ItLosQueue022(); + ItLosQueue023(); + ItLosQueue024(); + ItLosQueue025(); + ItLosQueue026(); + ItLosQueue027(); + ItLosQueue028(); + ItLosQueue029(); + ItLosQueue032(); + ItLosQueue033(); + ItLosQueue037(); + ItLosQueue038(); + ItLosQueue040(); + ItLosQueue041(); + ItLosQueue042(); + ItLosQueue043(); + ItLosQueue044(); + ItLosQueue045(); + ItLosQueue046(); + ItLosQueue047(); + ItLosQueue048(); + ItLosQueue049(); + ItLosQueue050(); + ItLosQueue051(); + ItLosQueue052(); + ItLosQueue053(); + ItLosQueue054(); + ItLosQueue055(); + ItLosQueue056(); + ItLosQueue057(); + ItLosQueue058(); + ItLosQueue059(); + ItLosQueue061(); + ItLosQueue062(); + ItLosQueue064(); + ItLosQueue065(); + ItLosQueue066(); + ItLosQueue067(); + ItLosQueue068(); + ItLosQueue069(); + ItLosQueue070(); + ItLosQueue071(); + ItLosQueue072(); + ItLosQueue073(); + ItLosQueue074(); + ItLosQueue075(); + ItLosQueue076(); + ItLosQueue077(); + ItLosQueue078(); + ItLosQueue079(); + ItLosQueue080(); + ItLosQueue081(); + ItLosQueue082(); + ItLosQueue083(); + ItLosQueue084(); + ItLosQueue085(); + ItLosQueue086(); + ItLosQueue087(); + ItLosQueue088(); + ItLosQueue089(); + ItLosQueue091(); + ItLosQueue092(); + ItLosQueue093(); + ItLosQueue094(); + ItLosQueue095(); + ItLosQueue096(); + ItLosQueue098(); + +#if (LOS_MEM_TLSF == 1) +#else + ItLosQueue099(); + ItLosQueue101(); + ItLosQueue102(); + ItLosQueue103(); + ItLosQueue104(); + ItLosQueue106(); + ItLosQueue107(); + ItLosQueue108(); + ItLosQueue109(); + ItLosQueue110(); + ItLosQueue111(); + ItLosQueue112(); + ItLosQueue113(); + ItLosQueue114(); + ItLosQueue116(); +#endif + + ItLosQueueHead003(); + ItLosQueueHead004(); + ItLosQueueHead005(); + ItLosQueueHead006(); + ItLosQueueHead007(); + ItLosQueueHead008(); + ItLosQueueHead009(); + ItLosQueueHead010(); + ItLosQueueHead011(); + ItLosQueueHead012(); + ItLosQueueHead013(); + ItLosQueueHead014(); + ItLosQueueHead015(); + ItLosQueueHead016(); + ItLosQueueHead017(); + ItLosQueueHead018(); + ItLosQueueHead019(); + ItLosQueueHead020(); + ItLosQueueHead021(); + ItLosQueueHead022(); + ItLosQueueHead023(); + ItLosQueueHead024(); + ItLosQueueHead025(); + ItLosQueueHead026(); + ItLosQueueHead027(); + ItLosQueueHead028(); + ItLosQueueHead029(); + ItLosQueueHead030(); + ItLosQueueHead031(); + ItLosQueueHead032(); + ItLosQueueHead038(); + ItLosQueueHead039(); + ItLosQueueHead040(); + ItLosQueueHead041(); + ItLosQueueHead042(); +#endif + +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, 1); +#endif +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/It_los_queue.h b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/It_los_queue.h new file mode 100644 index 00000000..4b090392 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/It_los_queue.h @@ -0,0 +1,299 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "los_base.h" +#include "los_task.h" +#include "los_membox.h" +#include "osTest.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#define QUEUE_SHORT_BUFFER_LENGTH 12 +#define QUEUE_STANDARD_BUFFER_LENGTH 50 +#define QUEUE_BASE_NUM 3 +#define QUEUE_BASE_MSGSIZE 8 + +#define LOOP 100 + +#ifdef __LP64__ +#define PER_ADDED_VALUE 8 +#else +#define PER_ADDED_VALUE 4 +#endif + +extern UINT32 g_testTaskID01; +extern UINT32 g_testTaskID02; +extern UINT32 g_testQueueID01; +extern UINT32 g_testQueueID02; +extern UINT32 g_TestQueueID03; + +extern VOID ItSuiteLosQueue(VOID); + +#if defined(LOSCFG_TEST_SMOKE) +VOID ItLosQueue001(VOID); +VOID ItLosQueue097(VOID); +#if (LOS_MEM_TLSF == 1) +#else +VOID ItLosQueue100(VOID); +VOID ItLosQueue105(VOID); +#endif +VOID ItLosQueueHead002(VOID); +#endif + +#if defined(LOSCFG_TEST_FULL) +VOID ItLosQueue002(VOID); +VOID ItLosQueue003(VOID); +VOID ItLosQueue004(VOID); +VOID ItLosQueue005(VOID); +VOID ItLosQueue006(VOID); +VOID ItLosQueue007(VOID); +VOID ItLosQueue008(VOID); +VOID ItLosQueue009(VOID); +VOID ItLosQueue010(VOID); +VOID ItLosQueue011(VOID); +VOID ItLosQueue012(VOID); +VOID ItLosQueue013(VOID); +VOID ItLosQueue014(VOID); +VOID ItLosQueue015(VOID); +VOID ItLosQueue017(VOID); +VOID ItLosQueue018(VOID); +VOID ItLosQueue019(VOID); +VOID ItLosQueue020(VOID); +VOID ItLosQueue021(VOID); +VOID ItLosQueue022(VOID); +VOID ItLosQueue023(VOID); +VOID ItLosQueue024(VOID); +VOID ItLosQueue025(VOID); +VOID ItLosQueue026(VOID); +VOID ItLosQueue027(VOID); +VOID ItLosQueue028(VOID); +VOID ItLosQueue029(VOID); +VOID ItLosQueue032(VOID); +VOID ItLosQueue033(VOID); +VOID ItLosQueue037(VOID); +VOID ItLosQueue038(VOID); +VOID ItLosQueue040(VOID); +VOID ItLosQueue041(VOID); +VOID ItLosQueue042(VOID); +VOID ItLosQueue043(VOID); +VOID ItLosQueue044(VOID); +VOID ItLosQueue045(VOID); +VOID ItLosQueue046(VOID); +VOID ItLosQueue047(VOID); +VOID ItLosQueue048(VOID); +VOID ItLosQueue049(VOID); +VOID ItLosQueue050(VOID); +VOID ItLosQueue051(VOID); +VOID ItLosQueue052(VOID); +VOID ItLosQueue053(VOID); +VOID ItLosQueue054(VOID); +VOID ItLosQueue055(VOID); +VOID ItLosQueue056(VOID); +VOID ItLosQueue057(VOID); +VOID ItLosQueue058(VOID); +VOID ItLosQueue059(VOID); +VOID ItLosQueue061(VOID); +VOID ItLosQueue062(VOID); +VOID ItLosQueue064(VOID); +VOID ItLosQueue065(VOID); +VOID ItLosQueue066(VOID); +VOID ItLosQueue067(VOID); +VOID ItLosQueue068(VOID); +VOID ItLosQueue069(VOID); +VOID ItLosQueue070(VOID); +VOID ItLosQueue071(VOID); +VOID ItLosQueue072(VOID); +VOID ItLosQueue073(VOID); +VOID ItLosQueue074(VOID); +VOID ItLosQueue075(VOID); +VOID ItLosQueue076(VOID); +VOID ItLosQueue077(VOID); +VOID ItLosQueue078(VOID); +VOID ItLosQueue079(VOID); +VOID ItLosQueue080(VOID); +VOID ItLosQueue081(VOID); +VOID ItLosQueue082(VOID); +VOID ItLosQueue083(VOID); +VOID ItLosQueue084(VOID); +VOID ItLosQueue085(VOID); +VOID ItLosQueue086(VOID); +VOID ItLosQueue087(VOID); +VOID ItLosQueue088(VOID); +VOID ItLosQueue089(VOID); +VOID ItLosQueue090(VOID); +VOID ItLosQueue091(VOID); +VOID ItLosQueue092(VOID); +VOID ItLosQueue093(VOID); +VOID ItLosQueue094(VOID); +VOID ItLosQueue095(VOID); +VOID ItLosQueue096(VOID); +VOID ItLosQueue098(VOID); +VOID ItLosQueue099(VOID); +VOID ItLosQueue101(VOID); +VOID ItLosQueue102(VOID); +VOID ItLosQueue103(VOID); +VOID ItLosQueue104(VOID); +VOID ItLosQueue106(VOID); +VOID ItLosQueue107(VOID); +VOID ItLosQueue108(VOID); +VOID ItLosQueue109(VOID); +VOID ItLosQueue110(VOID); +VOID ItLosQueue111(VOID); +VOID ItLosQueue112(VOID); +VOID ItLosQueue113(VOID); +VOID ItLosQueue114(VOID); +VOID ItLosQueue116(VOID); + +VOID ItLosQueueHead003(VOID); +VOID ItLosQueueHead004(VOID); +VOID ItLosQueueHead005(VOID); +VOID ItLosQueueHead006(VOID); +VOID ItLosQueueHead007(VOID); +VOID ItLosQueueHead008(VOID); +VOID ItLosQueueHead009(VOID); +VOID ItLosQueueHead010(VOID); +VOID ItLosQueueHead011(VOID); +VOID ItLosQueueHead012(VOID); +VOID ItLosQueueHead013(VOID); +VOID ItLosQueueHead014(VOID); +VOID ItLosQueueHead015(VOID); +VOID ItLosQueueHead016(VOID); +VOID ItLosQueueHead017(VOID); +VOID ItLosQueueHead018(VOID); +VOID ItLosQueueHead019(VOID); +VOID ItLosQueueHead020(VOID); +VOID ItLosQueueHead021(VOID); +VOID ItLosQueueHead022(VOID); +VOID ItLosQueueHead023(VOID); +VOID ItLosQueueHead024(VOID); +VOID ItLosQueueHead025(VOID); +VOID ItLosQueueHead026(VOID); +VOID ItLosQueueHead027(VOID); +VOID ItLosQueueHead028(VOID); +VOID ItLosQueueHead029(VOID); +VOID ItLosQueueHead030(VOID); +VOID ItLosQueueHead031(VOID); +VOID ItLosQueueHead032(VOID); +VOID ItLosQueueHead036(VOID); +VOID ItLosQueueHead038(VOID); +VOID ItLosQueueHead039(VOID); +VOID ItLosQueueHead040(VOID); +VOID ItLosQueueHead041(VOID); +VOID ItLosQueueHead042(VOID); +#endif + +#if defined(LOSCFG_TEST_MANUAL_SHELL) && defined(LOSCFG_DEBUG_QUEUE) +VOID ItLosQueueManual001(VOID); +VOID ItLosQueueManual002(VOID); +VOID ItLosQueueManual003(VOID); +VOID ItLosQueueManual004(VOID); +VOID ItLosQueueManual005(VOID); +VOID ItLosQueueManual006(VOID); +VOID ItLosQueueManual007(VOID); +VOID ItLosQueueManual008(VOID); +VOID ItLosQueueManual009(VOID); +VOID ItLosQueueManual010(VOID); +#endif +#if defined(LOSCFG_TEST_PRESSURE) +VOID ItLosQueue016(VOID); +VOID ItLosQueue030(VOID); +VOID ItLosQueue031(VOID); +VOID ItLosQueue034(VOID); +VOID ItLosQueue035(VOID); +VOID ItLosQueue036(VOID); +VOID ItLosQueue039(VOID); +VOID ItLosQueue060(VOID); +VOID ItLosQueue063(VOID); +VOID ItLosQueue123(VOID); + + +#endif + +#if defined(LOSCFG_TEST_LLT) +VOID ItLosQueueHead001(VOID); +VOID ItLosQueue115(VOID); +VOID ItLosQueue117(VOID); +VOID ItLosQueue118(VOID); +VOID ItLosQueue119(VOID); +VOID ItLosQueue120(VOID); +VOID ItLosQueue121(VOID); +VOID ItLosQueue122(VOID); +#if defined(LOSCFG_SHELL) && defined(LOSCFG_DEBUG_QUEUE) +VOID ItLosQueueDebug001(void); +#endif +#endif + +#ifdef LOSCFG_KERNEL_SMP +VOID ItSmpLosQueue001(VOID); +VOID ItSmpLosQueue002(VOID); +VOID ItSmpLosQueue003(VOID); +VOID ItSmpLosQueue004(VOID); +VOID ItSmpLosQueue005(VOID); +VOID ItSmpLosQueue006(VOID); +VOID ItSmpLosQueue007(VOID); +VOID ItSmpLosQueue008(VOID); +VOID ItSmpLosQueue009(VOID); +VOID ItSmpLosQueue010(VOID); +VOID ItSmpLosQueue011(VOID); +VOID ItSmpLosQueue012(VOID); +VOID ItSmpLosQueue013(VOID); +VOID ItSmpLosQueue014(VOID); +VOID ItSmpLosQueue015(VOID); +VOID ItSmpLosQueue016(VOID); +VOID ItSmpLosQueue017(VOID); +VOID ItSmpLosQueue018(VOID); +VOID ItSmpLosQueue019(VOID); +VOID ItSmpLosQueue020(VOID); +VOID ItSmpLosQueue021(VOID); +VOID ItSmpLosQueue022(VOID); +VOID ItSmpLosQueue023(VOID); +VOID ItSmpLosQueue024(VOID); +VOID ItSmpLosQueue025(VOID); +VOID ItSmpLosQueue026(VOID); +VOID ItSmpLosQueue027(VOID); +VOID ItSmpLosQueue028(VOID); +VOID ItSmpLosQueue029(VOID); +VOID ItSmpLosQueue030(VOID); +VOID ItSmpLosQueue031(VOID); +VOID ItSmpLosQueue032(VOID); +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_002.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_002.c new file mode 100644 index 00000000..6561733c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_002.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + + g_testQueueID01 = 1025; // 1025, ID of successfully created queue control structure. + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, 0); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_PARA_ISZERO, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_INVALID, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_INVALID, ret, EXIT); + + return LOS_OK; + +EXIT: + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItLosQueue002(VOID) +{ + TEST_ADD_CASE("ItLosQueue002", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_003.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_003.c new file mode 100644 index 00000000..43a405a3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_003.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, 1); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 16, 0); // 16, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_WRITE_SIZE_TOO_BIG, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 16, 0); // 16, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISEMPTY, ret, EXIT); + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosQueue003(VOID) +{ + TEST_ADD_CASE("ItLosQueue003", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_005.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_005.c new file mode 100644 index 00000000..787db5b4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_005.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + + g_testQueueID01 = LOSCFG_BASE_IPC_QUEUE_CONFIG - 1; + + ret = LOS_QueueCreate("Q1", 30, &g_testQueueID01, 0, 0xFFFF); // 30, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_SIZE_TOO_BIG, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_NOT_CREATE, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_NOT_CREATE, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_NOT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + + +VOID ItLosQueue005(VOID) +{ + TEST_ADD_CASE("ItLosQueue005", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_006.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_006.c new file mode 100644 index 00000000..5cb0724a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_006.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + + g_testQueueID01 = 1025; // 1025, ID of successfully created queue control structure. + + ret = LOS_QueueCreate("Q1", 3, NULL, 0, 8); // 3, Set the queue length; 8, Set the node size of the queue. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_CREAT_PTR_NULL, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_INVALID, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the settig size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_INVALID, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_NOT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + + +VOID ItLosQueue006(VOID) +{ + TEST_ADD_CASE("ItLosQueue006", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_007.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_007.c new file mode 100644 index 00000000..dec6572b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_007.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + + g_testQueueID01 = 1025; // 1025, ID of successfully created queue control structure. + + ret = LOS_QueueCreate("Q1", 0, &g_testQueueID01, 0, 8); // 8, Set the node size of the queue. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_PARA_ISZERO, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_INVALID, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_INVALID, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_NOT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItLosQueue007(VOID) +{ + TEST_ADD_CASE("ItLosQueue007", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_008.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_008.c new file mode 100644 index 00000000..20f51745 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_008.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, 8); // 8, Set the node size of the queue. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItLosQueue008(VOID) +{ + TEST_ADD_CASE("ItLosQueue008", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_009.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_009.c new file mode 100644 index 00000000..7e0edaf1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_009.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + + g_testQueueID01 = 1025; // 1025, ID of successfully created queue control structure. + + ret = LOS_QueueCreate("Q1", 0xFFFE, &g_testQueueID01, 0, 0xFFF0); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_CREATE_NO_MEMORY, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_INVALID, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_INVALID, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_NOT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItLosQueue009(VOID) +{ + TEST_ADD_CASE("ItLosQueue009", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_010.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_010.c new file mode 100644 index 00000000..840d377a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_010.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSPtest"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + + g_testQueueID01 = LOSCFG_BASE_IPC_QUEUE_CONFIG - 1; + +#if defined(TEST3559A_M7) || defined(TESTHI1980IMU) || defined(TEST1980) + ret = LOS_QueueCreate("Q1", 0xFF, &g_testQueueID01, 0, sizeof(UINTPTR)); +#else + ret = LOS_QueueCreate("Q1", 0xFFFF, &g_testQueueID01, 0, sizeof(UINTPTR)); +#endif + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 12, 0); // 12, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 12, 0); // 12, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItLosQueue010(VOID) +{ + TEST_ADD_CASE("ItLosQueue010", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_011.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_011.c new file mode 100644 index 00000000..7b514ecd --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_011.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSPtest"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, QUEUE_SHORT_BUFFER_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, sizeof(UINTPTR), 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItLosQueue011(VOID) +{ + TEST_ADD_CASE("ItLosQueue011", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_012.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_012.c new file mode 100644 index 00000000..46e1999d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_012.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[] = "UniDSPOS"; + UINTPTR buff2; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, buff1, sizeof(UINTPTR) * 2, 0); // 2, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, (sizeof(UINTPTR) * 2 - 1), 0); // 2, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ICUNIT_GOTO_EQUAL(*((char *)buff2 + 6), buff1[6], *((char *)buff2 + 6), EXIT); // 6, The offset of queue buffer. + ICUNIT_GOTO_EQUAL(*((char *)buff2 + 7), 'S', *((char *)buff2 + 7), EXIT); // 7, The offset of queue buffer. + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosQueue012(VOID) +{ + TEST_ADD_CASE("ItLosQueue012", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_013.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_013.c new file mode 100644 index 00000000..c18beaf0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_013.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[] = "UniDSPOS"; + UINTPTR buff2; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 9, 0); // 9, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ICUNIT_GOTO_EQUAL(*((char *)buff2 + 7), buff1[7], *((char *)buff2 + 7), EXIT); // 7, The offset of queue buffer. + ICUNIT_GOTO_EQUAL(*((char *)buff2 + 8), '\0', *((char *)buff2 + 8), EXIT); // 8, The offset of queue buffer. + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItLosQueue013(VOID) +{ + TEST_ADD_CASE("ItLosQueue013", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_014.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_014.c new file mode 100644 index 00000000..62704fe9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_014.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 index; + CHAR buff1[] = "UniDSPOS"; + CHAR buff2[9] = ""; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, 8); // 3, Set the queue length; 8, Set the node size of the queue. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 0, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_READSIZE_IS_INVALID, ret, EXIT); + for (index = 0; index < 9; index++) { // 9, The offset of queue buffer. + ICUNIT_GOTO_EQUAL(buff2[index], '\0', buff2[index], EXIT); + } + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosQueue014(VOID) +{ + TEST_ADD_CASE("ItLosQueue014", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_015.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_015.c new file mode 100644 index 00000000..b818ccb8 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_015.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[9] = ""; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 9, 0); // 9, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISEMPTY, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 9, 0); // 9, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItLosQueue015(VOID) +{ + TEST_ADD_CASE("ItLosQueue015", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_017.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_017.c new file mode 100644 index 00000000..6aeaab1e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_017.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, 8); // 3, Set the queue length; 8, Set the node size of the queue. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, NULL, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_READ_PTR_NULL, ret, EXIT); + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosQueue017(VOID) +{ + TEST_ADD_CASE("ItLosQueue017", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_018.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_018.c new file mode 100644 index 00000000..0710925b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_018.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, 8); // 3, Set the queue length; 8, Set the node size of the queue. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead((UINT32)-1, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_INVALID, ret, EXIT); + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItLosQueue018(VOID) +{ + TEST_ADD_CASE("ItLosQueue018", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_019.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_019.c new file mode 100644 index 00000000..2bebbc0d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_019.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, QUEUE_SHORT_BUFFER_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, QUEUE_SHORT_BUFFER_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, QUEUE_SHORT_BUFFER_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_NOT_CREATE, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_NOT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItLosQueue019(VOID) +{ + TEST_ADD_CASE("ItLosQueue019", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_020.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_020.c new file mode 100644 index 00000000..a2b05a69 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_020.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueCreate("Q2", 3, &g_testQueueID02, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID02, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID02, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_QueueDelete(g_testQueueID02); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosQueue020(VOID) +{ + TEST_ADD_CASE("ItLosQueue020", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_021.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_021.c new file mode 100644 index 00000000..54214e8f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_021.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 index; + UINT32 queueID[LOSCFG_BASE_IPC_QUEUE_CONFIG + 1]; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + + UINT32 exsitedQueue = QUEUE_EXISTED_NUM; + for (index = 0; index < LOSCFG_BASE_IPC_QUEUE_CONFIG - exsitedQueue; index++) { + ret = LOS_QueueCreate(NULL, 3, &queueID[index], 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + + ret = LOS_QueueWrite(queueID[index - 1], &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(queueID[index - 1], &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); // 3, Set the queue length. + + ret = LOS_QueueCreate("Q1", 3, &queueID[index], 0, 8); // 3, Set the queue length; 8, Set the node size of the queue. + ICUNIT_GOTO_NOT_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueCreate("Q1", 3, &queueID[index], 0, 8); // 3, Set the queue length; 8, Set the node size of the queue. + ICUNIT_GOTO_NOT_EQUAL(ret, LOS_OK, ret, EXIT); + +EXIT: + for (index = 0; index < LOSCFG_BASE_IPC_QUEUE_CONFIG - exsitedQueue; index++) { + ret = LOS_QueueDelete(queueID[index]); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + return LOS_OK; +} + +VOID ItLosQueue021(VOID) +{ + TEST_ADD_CASE("ItLosQueue021", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_022.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_022.c new file mode 100644 index 00000000..3f2bd74e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_022.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 index; + UINT32 queueID[LOSCFG_BASE_IPC_QUEUE_CONFIG + 1]; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + + UINT32 exsitedQueue = QUEUE_EXISTED_NUM; + for (index = 0; index < LOSCFG_BASE_IPC_QUEUE_CONFIG - exsitedQueue; index++) { + ret = LOS_QueueCreate(NULL, 3, &queueID[index], 0, 8); // 3, Set the queue length; 8, Set the node size of the queue. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + + ret = LOS_QueueCreate("Q1", 3, &queueID[LOSCFG_BASE_IPC_QUEUE_CONFIG], 0, 8); // 3, Set the queue length; 8, Set the node size of the queue. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_CB_UNAVAILABLE, ret, EXIT); + + ret = LOS_QueueWrite(LOSCFG_BASE_IPC_QUEUE_CONFIG + 1, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_INVALID, ret, EXIT); + + ret = LOS_QueueRead(LOSCFG_BASE_IPC_QUEUE_CONFIG + 1, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_INVALID, ret, EXIT); + +EXIT: + for (index = 0; index < LOSCFG_BASE_IPC_QUEUE_CONFIG - exsitedQueue; index++) { + ret = LOS_QueueDelete(queueID[index]); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + return LOS_OK; +} + +VOID ItLosQueue022(VOID) +{ + TEST_ADD_CASE("ItLosQueue022", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_023.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_023.c new file mode 100644 index 00000000..46553ee4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_023.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 0, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosQueue023(VOID) +{ + TEST_ADD_CASE("ItLosQueue023", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_024.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_024.c new file mode 100644 index 00000000..ebd5deed --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_024.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 13, 0); // 13, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosQueue024(VOID) +{ + TEST_ADD_CASE("ItLosQueue024", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_025.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_025.c new file mode 100644 index 00000000..e06dc74b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_025.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 index; + CHAR buff1[] = "UniDSP_TEST"; + UINTPTR buff2; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, buff1, 7, 0); // 7, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + for (index = 0; index < 7; index++) { // 7, The offset of queue buffer. + ICUNIT_GOTO_EQUAL(*((char *)buff2 + index), buff1[index], *((char *)buff2 + index), EXIT); + } + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISEMPTY, ret, EXIT); + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosQueue025(VOID) +{ + TEST_ADD_CASE("ItLosQueue025", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_026.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_026.c new file mode 100644 index 00000000..c8597038 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_026.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "gjl"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, NULL, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_WRITE_PTR_NULL, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosQueue026(VOID) +{ + TEST_ADD_CASE("ItLosQueue026", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_027.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_027.c new file mode 100644 index 00000000..e69f559e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_027.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite((UINT32)-1, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_INVALID, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISEMPTY, ret, EXIT); + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosQueue027(VOID) +{ + TEST_ADD_CASE("ItLosQueue027", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_028.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_028.c new file mode 100644 index 00000000..2f7dcf4e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_028.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + + ret = LOS_QueueWrite(QUEUE_EXISTED_NUM + 1, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_QUEUE_NOT_CREATE, ret); + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosQueue028(VOID) +{ + TEST_ADD_CASE("ItLosQueue028", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_029.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_029.c new file mode 100644 index 00000000..451e59df --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_029.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueCreate("Q2", 3, &g_testQueueID02, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_QueueDelete(g_testQueueID02); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosQueue029(VOID) +{ + TEST_ADD_CASE("ItLosQueue029", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_032.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_032.c new file mode 100644 index 00000000..40edd360 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_032.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = "DOPRA"; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, 8); // 3, Set the queue length; 8, Set the node size of the queue. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueCreate("Q2", 3, &g_testQueueID02, 0, 8); // 3, Set the queue length; 8, Set the node size of the queue. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID02, &buff2, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_QueueDelete(g_testQueueID02); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosQueue032(VOID) +{ + TEST_ADD_CASE("ItLosQueue032", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_033.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_033.c new file mode 100644 index 00000000..47b716b7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_033.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH]; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff1, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISEMPTY, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItLosQueue033(VOID) +{ + TEST_ADD_CASE("ItLosQueue033", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_037.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_037.c new file mode 100644 index 00000000..a0144103 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_037.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 index; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = "DOPRA"; + CHAR buff3[8] = "TEST"; + UINTPTR buff4; + UINTPTR buff5; + UINTPTR buff6; + + // 3, Set the queue length + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, buff2, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff3, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff4, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff5, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff6, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + for (index = 0; index < 8; index++) { // 8, The offset of queue buffer. + ICUNIT_GOTO_EQUAL(*((char *)buff4 + index), buff1[index], *((char *)buff4 + index), EXIT); + ICUNIT_GOTO_EQUAL(*((char *)buff5 + index), buff2[index], *((char *)buff5 + index), EXIT); + ICUNIT_GOTO_EQUAL(*((char *)buff6 + index), buff3[index], *((char *)buff6 + index), EXIT); + } + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItLosQueue037(VOID) +{ + TEST_ADD_CASE("ItLosQueue037", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_038.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_038.c new file mode 100644 index 00000000..1b5fec25 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_038.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 index; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISEMPTY, ret, EXIT); + + for (index = 0; index < 3; index++) { // 3, The offset of queue buffer. + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + + for (index = 0; index < 3; index++) { // 3, The offset of queue buffer. + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISEMPTY, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItLosQueue038(VOID) +{ + TEST_ADD_CASE("ItLosQueue038", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_040.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_040.c new file mode 100644 index 00000000..880feb47 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_040.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static VOID TaskF01(VOID) +{ + UINT32 ret; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + + g_testCount++; + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID01); +} + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[8] = "UniDSP"; + + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "TskName40"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = 23; // 23, Set the priority according to the task purpose,a smaller number means a higher priority. + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItLosQueue040(VOID) +{ + TEST_ADD_CASE("ItLosQueue040", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_041.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_041.c new file mode 100644 index 00000000..15e4fbce --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_041.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static VOID TaskF01(VOID) +{ + UINT32 ret; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + + g_testCount++; + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_NOT_CREATE, ret, EXIT); + + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "TskName"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = 23; // 23, Set the priority according to the task purpose,a smaller number means a higher priority. + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, 8); // 3, Set the queue length; 8, Set the node size of the queue. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + + return LOS_OK; +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItLosQueue041(VOID) +{ + TEST_ADD_CASE("ItLosQueue041", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_042.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_042.c new file mode 100644 index 00000000..3b9c4fe9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_042.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static VOID TaskF01(VOID) +{ + UINT32 ret; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_AtomicInc(&g_testCount); + +EXIT: + LOS_TaskDelete(g_testTaskID02); +} + +static VOID TaskF02(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_AtomicInc(&g_testCount); + +EXIT: + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + + TSK_INIT_PARAM_S task1 = { 0 }; + TSK_INIT_PARAM_S task2 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.pcName = "TskName1"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = 22; // 22, Set the priority according to the task purpose,a smaller number means a higher priority. + + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + LOS_AtomicInc(&g_testCount); + + task2.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task2.pcName = "TskName2"; + task2.uwStackSize = TASK_STACK_SIZE_TEST; + task2.usTaskPrio = 23; // 23, Set the priority according to the task purpose,a smaller number means a higher priority. + + ret = LOS_TaskCreate(&g_testTaskID02, &task2); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); // 5, Here, assert that g_testCount is equal to 5. + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return LOS_OK; +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItLosQueue042(VOID) +{ + TEST_ADD_CASE("ItLosQueue042", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_043.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_043.c new file mode 100644 index 00000000..50d14fbc --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_043.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static VOID TaskF01(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 100); // 8, Write the setting size of queue buffer. 100, timeout of queue write event. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_AtomicInc(&g_testCount); + +EXIT: + LOS_TaskDelete(g_testTaskID01); +} + +static VOID TaskF02(VOID) +{ + UINT32 ret; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_AtomicInc(&g_testCount); + +EXIT: + LOS_TaskDelete(g_testTaskID02); +} +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[8] = "UniDSP"; + + TSK_INIT_PARAM_S task1 = { 0 }; + TSK_INIT_PARAM_S task2 = { 0 }; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "TskName1"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = 22; // 22, Set the priority according to the task purpose,a smaller number means a higher priority. + + task2.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task2.pcName = "TskName2"; + task2.uwStackSize = TASK_STACK_SIZE_TEST; + task2.usTaskPrio = 21; // 21, Set the priority according to the task purpose,a smaller number means a higher priority. + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 100); // 8, Write the setting size of queue buffer. 100, timeout of queue write event. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + LOS_AtomicInc(&g_testCount); + + ret = LOS_TaskCreate(&g_testTaskID02, &task2); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); // 5, Here, assert that g_testCount is equal to 5. + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_QueueDelete(g_testQueueID02); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItLosQueue043(VOID) +{ + TEST_ADD_CASE("ItLosQueue043", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_044.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_044.c new file mode 100644 index 00000000..f47b3586 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_044.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static VOID HwiF01(VOID) +{ + UINT32 ret; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + + TEST_HwiClear(HWI_NUM_TEST); + + g_testCount++; + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + g_testCount++; + +EXIT: + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = TEST_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + TestHwiTrigger(HWI_NUM_TEST); + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_HwiDelete(HWI_NUM_TEST); + return LOS_OK; + +EXIT: + TEST_HwiDelete(HWI_NUM_TEST); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItLosQueue044(VOID) +{ + TEST_ADD_CASE("ItLosQueue044", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_045.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_045.c new file mode 100644 index 00000000..e57f3ec8 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_045.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID HwiF01(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + + TEST_HwiClear(HWI_NUM_TEST); + + g_testCount++; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, 8); // 3, Set the queue length; 8, Set the node size of the queue. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + g_testCount++; + +EXIT: + LOS_QueueDelete(g_testQueueID01); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + g_testCount = 0; + + ret = TEST_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + TestHwiTrigger(HWI_NUM_TEST); + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + +EXIT: + TEST_HwiDelete(HWI_NUM_TEST); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItLosQueue045(VOID) +{ + TEST_ADD_CASE("ItLosQueue045", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_046.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_046.c new file mode 100644 index 00000000..19bca4a7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_046.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static VOID HwiF01(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + + TEST_HwiClear(HWI_NUM_TEST); + + LOS_AtomicInc(&g_testCount); + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); +} + +static VOID HwiF02(VOID) +{ + UINT32 ret; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + + TEST_HwiClear(HWI_NUM_TEST3); + + LOS_AtomicInc(&g_testCount); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_AtomicInc(&g_testCount); + +EXIT: + LOS_QueueDelete(g_testQueueID01); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + g_testCount = 0; + + ret = TEST_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = TEST_HwiCreate(HWI_NUM_TEST3, 1, 0, HwiF02, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + TestHwiTrigger(HWI_NUM_TEST); + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + LOS_AtomicInc(&g_testCount); + + TestHwiTrigger(HWI_NUM_TEST3); + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); // 5, Here, assert that g_testCount is equal to 5. + + TEST_HwiDelete(HWI_NUM_TEST3); + TEST_HwiDelete(HWI_NUM_TEST); + LOS_QueueDelete(g_testQueueID01); + + return LOS_OK; +EXIT: + TEST_HwiDelete(HWI_NUM_TEST); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItLosQueue046(VOID) +{ + TEST_ADD_CASE("ItLosQueue046", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_047.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_047.c new file mode 100644 index 00000000..f336392b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_047.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static VOID TaskF01(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_AtomicInc(&g_testCount); + +EXIT: + LOS_TaskDelete(g_testTaskID01); +} + +static VOID HwiF01(VOID) +{ + UINT32 ret; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + + TEST_HwiClear(HWI_NUM_TEST); + + LOS_AtomicInc(&g_testCount); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_AtomicInc(&g_testCount); + +EXIT: + LOS_QueueDelete(g_testQueueID01); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "TskName"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = 23; // 23, Set the priority according to the task purpose,a smaller number means a higher priority. + + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + LOS_AtomicInc(&g_testCount); + + ret = TEST_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + TestHwiTrigger(HWI_NUM_TEST); + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); // 5, Here, assert that g_testCount is equal to 5. + + TEST_HwiDelete(HWI_NUM_TEST); + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + TEST_HwiDelete(HWI_NUM_TEST); + return LOS_OK; +} + +VOID ItLosQueue047(VOID) +{ + TEST_ADD_CASE("ItLosQueue047", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_048.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_048.c new file mode 100644 index 00000000..3847f03f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_048.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static VOID TaskF01(VOID) +{ + UINT32 ret; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_AtomicInc(&g_testCount); + +EXIT: + LOS_QueueDelete(g_testQueueID01); + LOS_TaskDelete(g_testTaskID01); +} + +static VOID HwiF01(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + + TEST_HwiClear(HWI_NUM_TEST); + + LOS_AtomicInc(&g_testCount); + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_AtomicInc(&g_testCount); +EXIT: + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "TskName"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = 23; // 23, Set the priority according to the task purpose,a smaller number means a higher priority. + + g_testCount = 0; + + ret = TEST_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + TestHwiTrigger(HWI_NUM_TEST); + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + + LOS_AtomicInc(&g_testCount); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); // 5, Here, assert that g_testCount is equal to 5. + + TEST_HwiDelete(HWI_NUM_TEST); + + return LOS_OK; + +EXIT: + TEST_HwiDelete(HWI_NUM_TEST); + LOS_TaskDelete(g_testTaskID01); + return LOS_OK; +} + +VOID ItLosQueue048(VOID) +{ + TEST_ADD_CASE("ItLosQueue048", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_049.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_049.c new file mode 100644 index 00000000..3ef21715 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_049.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static VOID SwtmrF01(VOID) +{ + UINT32 ret; + CHAR buffer2[] = "UniDSP"; + + ret = LOS_QueueWrite(g_testQueueID01, &buffer2, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buffer1[] = "MiniOS"; + UINT16 swTmrID; + INT32 value; + UINT64 tickstart; + + g_testCount = 0; + + ret = LOS_SwtmrCreate(20, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)SwtmrF01, &swTmrID, 0xffff); // 20, Timing duration of the software timer to be created. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueCreate("Q1", 10, &g_testQueueID01, 0, 8); // 10, Set the queue length; 8, Set the node size of the queue. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_SwtmrStart(swTmrID); + HAL_READ_UINT32(&g_testCount, value); + tickstart = LOS_TickCountGet(); + while (value < 10) { // 10, Here, assert that g_testCount is equal to 10. + HAL_READ_UINT32(&g_testCount, value); + if (LOS_TickCountGet() - tickstart > 1000) { // 1000, Test execution time tick count upper limit. + ICUNIT_GOTO_EQUAL(1, 0, g_testCount, EXIT); + break; + } + } + + ret = LOS_QueueWrite(g_testQueueID01, &buffer1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISFULL, ret, EXIT); + + LOS_SwtmrDelete(swTmrID); + LOS_QueueDelete(g_testQueueID01); + + return LOS_OK; +EXIT: + LOS_SwtmrDelete(swTmrID); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItLosQueue049(VOID) +{ + TEST_ADD_CASE("ItLosQueue049", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_050.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_050.c new file mode 100644 index 00000000..205ab668 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_050.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static VOID HwiF01(VOID) +{ + UINT32 ret; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + + TEST_HwiClear(HWI_NUM_TEST); + + g_testCount++; + + ret = LOS_QueueRead(g_testQueueID01, buff2, 8, 0xff); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_READ_IN_INTERRUPT, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, buff2, 8, 0xff); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_WRITE_IN_INTERRUPT, ret, EXIT); + g_testCount++; +EXIT: + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, 8); // 8, Set the node size of the queue. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = TEST_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + TestHwiTrigger(HWI_NUM_TEST); + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + TEST_HwiDelete(HWI_NUM_TEST); + + return LOS_OK; + +EXIT: + LOS_QueueDelete(g_testQueueID01); + TEST_HwiDelete(HWI_NUM_TEST); + return LOS_OK; +} + +VOID ItLosQueue050(VOID) +{ + TEST_ADD_CASE("ItLosQueue050", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_051.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_051.c new file mode 100644 index 00000000..7577dc76 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_051.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, sizeof(UINTPTR)); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_TaskLock(); + + ret = LOS_QueueRead(g_testQueueID01, buff1, 8, 0xff); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_PEND_IN_LOCK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, buff1, 8, 0xff); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, buff1, 8, 0xff); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_PEND_IN_LOCK, ret, EXIT); + LOS_TaskUnlock(); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return LOS_OK; + +EXIT: + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItLosQueue051(VOID) +{ + TEST_ADD_CASE("ItLosQueue051", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_052.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_052.c new file mode 100644 index 00000000..3383739a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_052.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, sizeof(UINTPTR)); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, buff1, 8, 0xf); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_TIMEOUT, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, buff1, 8, 0xf); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, buff1, 8, 0xf); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_TIMEOUT, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return LOS_OK; + +EXIT: + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItLosQueue052(VOID) +{ + TEST_ADD_CASE("ItLosQueue052", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_053.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_053.c new file mode 100644 index 00000000..d28ab711 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_053.c @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + + g_testCount++; + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0xf); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + g_testCount++; + + ret = LOS_QueueWrite(g_testQueueID01, buff2, 8, 0xf); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, buff2, 8, 0xf); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID01); +} +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + TSK_INIT_PARAM_S task1 = { 0 }; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "TskName53"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = 23; // 23, Set the priority according to the task purpose,a smaller number means a higher priority. + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, sizeof(UINTPTR)); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(LOSCFG_BASE_IPC_QUEUE_CONFIG + 1); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_NOT_FOUND, ret, EXIT); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT1); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_IN_TSKUSE, ret, EXIT1); + + ret = LOS_QueueWrite(g_testQueueID01, buff1, 8, 0xf); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT1); // 2, Here, assert that g_testCount is equal to 2. + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_IN_TSKUSE, ret, EXIT1); + + ret = LOS_QueueRead(g_testQueueID01, buff1, 8, 0xf); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT1); // 3, Here, assert that g_testCount is equal to 3. + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_NOT_CREATE, ret, EXIT1); + + return LOS_OK; + +EXIT: + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +EXIT1: + LOS_TaskDelete(g_testTaskID01); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItLosQueue053(VOID) +{ + TEST_ADD_CASE("ItLosQueue053", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_054.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_054.c new file mode 100644 index 00000000..7f9e0a16 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_054.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + + g_testQueueID01 = 0; + + ret = LOS_QueueCreate(0, 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + return LOS_OK; + +EXIT: + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItLosQueue054(VOID) +{ + TEST_ADD_CASE("ItLosQueue054", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_055.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_055.c new file mode 100644 index 00000000..91ff5ca5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_055.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + + g_testQueueID01 = 0; + + ret = LOS_QueueCreate("a", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return LOS_OK; + +EXIT: + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItLosQueue055(VOID) +{ + TEST_ADD_CASE("ItLosQueue055", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_056.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_056.c new file mode 100644 index 00000000..32debca3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_056.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + + g_testQueueID01 = 0; + + ret = LOS_QueueCreate("", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return LOS_OK; + +EXIT: + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItLosQueue056(VOID) +{ + TEST_ADD_CASE("ItLosQueue056", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_057.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_057.c new file mode 100644 index 00000000..96f50eb6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_057.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + char bufname[5002] = {0}; + + g_testQueueID01 = 0; + + ret = memset_s(bufname, 5001, 'a', 5001); // 5001, buffer size. + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + bufname[5001] = '\0'; // 5001, buffer size. + ret = LOS_QueueCreate(bufname, 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return LOS_OK; + +EXIT: + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItLosQueue057(VOID) +{ + TEST_ADD_CASE("ItLosQueue057", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_058.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_058.c new file mode 100644 index 00000000..285224e7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_058.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + UINT32 maxMsgSize; + + g_testQueueID01 = LOSCFG_BASE_IPC_QUEUE_CONFIG - 1; + maxMsgSize = 0xFFFF + 1; + + ret = LOS_QueueCreate("Q1", 30, &g_testQueueID01, 0, maxMsgSize); // 30, Set the queue length. + ICUNIT_GOTO_NOT_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_NOT_CREATE, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_NOT_CREATE, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_NOT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItLosQueue058(VOID) +{ + TEST_ADD_CASE("ItLosQueue058", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_059.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_059.c new file mode 100644 index 00000000..afc8514f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_059.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + + g_testQueueID01 = 0; + + ret = LOS_QueueCreate("Q1", 30, &g_testQueueID01, 0, sizeof(UINTPTR)); // 30, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return LOS_OK; + +EXIT: + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItLosQueue059(VOID) +{ + TEST_ADD_CASE("ItLosQueue059", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_061.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_061.c new file mode 100644 index 00000000..584cfb2e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_061.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buffer1[] = "MiniOS"; + CHAR buffer2[] = "UniDSP"; + + UINT16 swTmrID1, swTmrID2; + INT32 value; + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 10, &g_testQueueID01, 0, sizeof(UINTPTR)); // 10, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buffer1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buffer2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_NOT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItLosQueue061(VOID) +{ + TEST_ADD_CASE("ItLosQueue061", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_062.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_062.c new file mode 100644 index 00000000..7b8ae4eb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_062.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buffer1[] = "MiniOS"; + CHAR buffer2[] = "UniDSP"; + + UINT16 swTmrID1, swTmrID2; + INT32 value; + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 10, &g_testQueueID01, 0, 0); // 10, Set the queue length + ICUNIT_GOTO_NOT_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buffer1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_NOT_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buffer2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_NOT_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_NOT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItLosQueue062(VOID) +{ + TEST_ADD_CASE("ItLosQueue062", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_064.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_064.c new file mode 100644 index 00000000..0b457ebe --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_064.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret, len1; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + + g_testQueueID01 = LOSCFG_BASE_IPC_QUEUE_CONFIG - 1; + len1 = 0xFFFF + 1; + + ret = LOS_QueueCreate("Q1", len1, &g_testQueueID01, 0, 30); // 30, Set the node size of the queue. + ICUNIT_GOTO_NOT_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_NOT_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_NOT_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_NOT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItLosQueue064(VOID) +{ + TEST_ADD_CASE("ItLosQueue064", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_065.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_065.c new file mode 100644 index 00000000..8563256c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_065.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[] = "UniDSPOS"; + UINTPTR buff2 = 0; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 0xffffffff, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_READSIZE_IS_INVALID, ret, EXIT); + ICUNIT_GOTO_EQUAL(buff2, 0, buff2, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ICUNIT_GOTO_EQUAL(*((char *)buff2 + 7), buff1[7], *((char *)buff2 + 7), EXIT); // 7, The offset of queue buffer. + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItLosQueue065(VOID) +{ + TEST_ADD_CASE("ItLosQueue065", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_066.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_066.c new file mode 100644 index 00000000..680d4b63 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_066.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[] = "UniDSPOS"; + UINTPTR buff2 = 0; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, (0xffffffff - 1), 0); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_READSIZE_IS_INVALID, ret, EXIT); + ICUNIT_GOTO_EQUAL(buff2, 0, buff2, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ICUNIT_GOTO_EQUAL(*((char *)buff2 + 7), buff1[7], *((char *)buff2 + 7), EXIT); // 7, The offset of queue buffer. + + return LOS_OK; + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItLosQueue066(VOID) +{ + TEST_ADD_CASE("ItLosQueue066", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_067.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_067.c new file mode 100644 index 00000000..911b1627 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_067.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[] = "UniDSPOS"; + UINTPTR buff2; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, 8); // 3, Set the queue length; 8, Set the node size of the queue. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, (0xffffffff + 1), 0); + ICUNIT_GOTO_NOT_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItLosQueue067(VOID) +{ + TEST_ADD_CASE("ItLosQueue067", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_068.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_068.c new file mode 100644 index 00000000..62758c02 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_068.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[7]; + + g_testQueueID01 = LOSCFG_BASE_IPC_QUEUE_CONFIG - 1; + + ret = LOS_QueueCreate("Q1", 30, &g_testQueueID01, 0, sizeof(UINTPTR)); // 30, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItLosQueue068(VOID) +{ + TEST_ADD_CASE("ItLosQueue068", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_069.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_069.c new file mode 100644 index 00000000..90b932ba --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_069.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[10]; + + g_testQueueID01 = LOSCFG_BASE_IPC_QUEUE_CONFIG - 1; + + ret = LOS_QueueCreate("Q1", 30, &g_testQueueID01, 0, sizeof(UINTPTR)); // 30, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItLosQueue069(VOID) +{ + TEST_ADD_CASE("ItLosQueue069", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_070.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_070.c new file mode 100644 index 00000000..9fefcd60 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_070.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[10]; + + g_testQueueID01 = LOSCFG_BASE_IPC_QUEUE_CONFIG - 1; + + ret = LOS_QueueCreate("Q1", 30, &g_testQueueID01, 0, 8); // 30, Set the queue length; 8, Set the node size of the queue. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead((LOSCFG_BASE_IPC_QUEUE_CONFIG + 1), &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_NOT_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItLosQueue070(VOID) +{ + TEST_ADD_CASE("ItLosQueue070", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_071.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_071.c new file mode 100644 index 00000000..19f5881e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_071.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[10]; + + g_testQueueID01 = LOSCFG_BASE_IPC_QUEUE_CONFIG - 1; + + ret = LOS_QueueCreate("Q1", 30, &g_testQueueID01, 0, sizeof(UINTPTR)); // 30, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItLosQueue071(VOID) +{ + TEST_ADD_CASE("ItLosQueue071", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_072.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_072.c new file mode 100644 index 00000000..82ff1e40 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_072.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[10]; + + g_testQueueID01 = LOSCFG_BASE_IPC_QUEUE_CONFIG - 1; + + ret = LOS_QueueCreate("Q1", 30, &g_testQueueID01, 0, sizeof(UINTPTR)); // 30, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, LOS_WAIT_FOREVER); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItLosQueue072(VOID) +{ + TEST_ADD_CASE("ItLosQueue072", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_073.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_073.c new file mode 100644 index 00000000..d10500e9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_073.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(VOID) +{ + UINT32 ret; + CHAR buffer1[] = "MiniOS"; + + ret = LOS_QueueWrite(g_testQueueID01, &buffer1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); +} + +static VOID SwtmrF02(VOID) +{ + UINT32 ret; + CHAR buffer2[] = "UniDSP"; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + + ret = LOS_QueueRead(g_testQueueID01, &buffer2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); +} +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buffer1[] = "MiniOS"; + CHAR buffer2[] = "UniDSP"; + + UINT16 swTmrID1, swTmrID2; + INT32 value; + + g_testCount = 0; + + ret = LOS_SwtmrCreate(4, LOS_SWTMR_MODE_ONCE, (SWTMR_PROC_FUNC)SwtmrF01, &swTmrID1, 0xffff); // 4, Timing duration of the software timer to be created. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT2); + + ret = LOS_SwtmrCreate(8, LOS_SWTMR_MODE_ONCE, (SWTMR_PROC_FUNC)SwtmrF02, &swTmrID2, 0xffff); // 8, Timing duration of the software timer to be created. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT3); + + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, sizeof(UINTPTR)); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + + LOS_SwtmrStart(swTmrID1); + LOS_SwtmrStart(swTmrID2); + + ret = LOS_TaskDelay(5); // 5, set delay time. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + + ret = LOS_TaskDelay(5); // 5, set delay time. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + + ret = LOS_QueueRead(g_testQueueID01, &buffer2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISEMPTY, ret, EXIT1); + + LOS_SwtmrDelete(swTmrID1); + LOS_SwtmrDelete(swTmrID2); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; + +EXIT1: + LOS_SwtmrDelete(swTmrID1); + LOS_SwtmrDelete(swTmrID2); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +EXIT2: + LOS_SwtmrDelete(swTmrID1); + return LOS_OK; +EXIT3: + LOS_SwtmrDelete(swTmrID2); + return LOS_OK; +} + +VOID ItLosQueue073(VOID) +{ + TEST_ADD_CASE("ItLosQueue073", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_074.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_074.c new file mode 100644 index 00000000..93f47114 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_074.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[10]; + + g_testQueueID01 = LOSCFG_BASE_IPC_QUEUE_CONFIG - 1; + + ret = LOS_QueueCreate("Q1", 30, &g_testQueueID01, 0, sizeof(UINTPTR)); // 30, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, (LOS_WAIT_FOREVER - 1)); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItLosQueue074(VOID) +{ + TEST_ADD_CASE("ItLosQueue074", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_075.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_075.c new file mode 100644 index 00000000..bfc9a12b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_075.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 index; + CHAR buff1[] = "UniDSP_TEST"; + UINTPTR buff2; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, 2); // 3, Set the queue length; 2, Set the node size of the queue. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, buff1, 0xFFFFFFFF, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_WRITE_SIZE_TOO_BIG, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISEMPTY, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItLosQueue075(VOID) +{ + TEST_ADD_CASE("ItLosQueue075", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_076.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_076.c new file mode 100644 index 00000000..aa543f03 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_076.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 index; + CHAR buff1[] = "UniDSP_TEST"; + UINTPTR buff2; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, buff1, (0xFFFFFFFF + 1), 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItLosQueue076(VOID) +{ + TEST_ADD_CASE("ItLosQueue076", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_077.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_077.c new file mode 100644 index 00000000..e2c58a6b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_077.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 index; + CHAR buff1[] = "UniDSP_TEST"; + UINTPTR buff2; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, buff1, (0xFFFFFFFF - 1), 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItLosQueue077(VOID) +{ + TEST_ADD_CASE("ItLosQueue077", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_078.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_078.c new file mode 100644 index 00000000..6acb8b25 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_078.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 index; + CHAR buff1[] = "UniDSP_TEST"; + UINTPTR buff2; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, 8); // 3, Set the queue length; 8, Set the node size of the queue. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(LOSCFG_BASE_IPC_QUEUE_CONFIG, buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_NOT_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_NOT_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItLosQueue078(VOID) +{ + TEST_ADD_CASE("ItLosQueue078", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_079.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_079.c new file mode 100644 index 00000000..dee8408a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_079.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 index; + CHAR buff1[] = "UniDSP_TEST"; + UINTPTR buff2; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, 8); // 3, Set the queue length; 8, Set the node size of the queue. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite((LOSCFG_BASE_IPC_QUEUE_CONFIG + 1), buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_NOT_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_NOT_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItLosQueue079(VOID) +{ + TEST_ADD_CASE("ItLosQueue079", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_080.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_080.c new file mode 100644 index 00000000..07ad8e23 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_080.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 index; + CHAR buff1[] = "UniDSP_TEST"; + UINTPTR buff2; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, 8); // 3, Set the queue length; 8, Set the node size of the queue. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_NOT_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItLosQueue080(VOID) +{ + TEST_ADD_CASE("ItLosQueue080", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_081.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_081.c new file mode 100644 index 00000000..ad079a68 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_081.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 index; + CHAR buff1[] = "UniDSP_TEST"; + UINTPTR buff2; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(0xFFFFFFFF); + ICUNIT_GOTO_NOT_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItLosQueue081(VOID) +{ + TEST_ADD_CASE("ItLosQueue081", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_082.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_082.c new file mode 100644 index 00000000..5d8754d7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_082.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 index; + CHAR buff1[] = "UniDSP_TEST"; + UINTPTR buff2; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(LOSCFG_BASE_IPC_QUEUE_CONFIG); + ICUNIT_GOTO_NOT_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItLosQueue082(VOID) +{ + TEST_ADD_CASE("ItLosQueue082", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_083.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_083.c new file mode 100644 index 00000000..3409870c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_083.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 index; + CHAR buff1[] = "UniDSP_TEST"; + UINTPTR buff2; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete((LOSCFG_BASE_IPC_QUEUE_CONFIG + 1)); + ICUNIT_GOTO_NOT_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItLosQueue083(VOID) +{ + TEST_ADD_CASE("ItLosQueue083", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_084.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_084.c new file mode 100644 index 00000000..2603e7ca --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_084.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 index; + CHAR buff1[] = "UniDSP_TEST"; + UINTPTR buff2; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItLosQueue084(VOID) +{ + TEST_ADD_CASE("ItLosQueue084", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_085.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_085.c new file mode 100644 index 00000000..59226ffc --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_085.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 index; + CHAR buff1[] = "UniDSP_TEST"; + UINTPTR buff2; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(100); // 100, Queue ID. + ICUNIT_GOTO_NOT_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return LOS_OK; + +EXIT: + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItLosQueue085(VOID) +{ + TEST_ADD_CASE("ItLosQueue085", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_086.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_086.c new file mode 100644 index 00000000..53081a61 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_086.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 index; + CHAR buff1[] = "UniDSP_TEST"; + UINTPTR buff2; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(100); // 100, Queue ID. + ICUNIT_GOTO_NOT_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItLosQueue086(VOID) +{ + TEST_ADD_CASE("ItLosQueue086", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_087.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_087.c new file mode 100644 index 00000000..5d72c4a9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_087.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret, i; + UINT32 index; + const UINT32 count = 256; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + CHAR filebuf[260] = "abcdeabcde0123456789abcedfghij9876550210abcdeabcde0123456789abcedfghij9876550210abcdeabcde0123" + "456789abcedfghij9876550210abcdeabcde0123456789abcedfghij9876550210abcdeabcde0123456789abcedfgh" + "ij9876550210abcdeabcde0123456789abcedfghij9876550210lalalalalalalala"; + CHAR readbuf[260] = ""; + QUEUE_INFO_S queueInfo; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, count); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + for (i = 0; i < 100; i++) { // 100, The loop frequency. + ret = LOS_QueueWrite(g_testQueueID01, filebuf, count, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = memset_s(readbuf, 260, 0, 260); // 260, Read buf size. + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ret = LOS_QueueRead(g_testQueueID01, readbuf, count, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueInfoGet(g_testQueueID01, &queueInfo); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ICUNIT_GOTO_EQUAL(queueInfo.usQueueLen, 3, queueInfo.usQueueLen, EXIT); // 3, Here, assert that g_testCount is equal to 3. + ICUNIT_GOTO_EQUAL(queueInfo.uwQueueID, g_testQueueID01, queueInfo.uwQueueID, EXIT); + } + ret = LOS_QueueRead(g_testQueueID01, readbuf, count, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISEMPTY, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItLosQueue087(VOID) +{ + TEST_ADD_CASE("ItLosQueue087", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_088.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_088.c new file mode 100644 index 00000000..7e52514f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_088.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret, i; + UINT32 index; + const UINT32 len = 1000; // 1000, Queue buffer length. + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + QUEUE_INFO_S queueInfo; + + // 1000, Set the queue length. + ret = LOS_QueueCreate("Q1", 1000, &g_testQueueID01, 0, QUEUE_SHORT_BUFFER_LENGTH); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueInfoGet(g_testQueueID01, &queueInfo); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ICUNIT_GOTO_EQUAL(queueInfo.usQueueLen, len, queueInfo.usQueueLen, EXIT); + ICUNIT_GOTO_EQUAL(queueInfo.uwQueueID, g_testQueueID01, queueInfo.uwQueueID, EXIT); + + for (i = 0; i < 1000; i++) { // 1000, Set the queue length. + ret = LOS_QueueWrite(g_testQueueID01, buff1, QUEUE_SHORT_BUFFER_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + ret = LOS_QueueWrite(g_testQueueID01, buff1, QUEUE_SHORT_BUFFER_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISFULL, ret, EXIT); + + for (i = 0; i < 1000; i++) { // 1000, Set the queue length. + ret = LOS_QueueRead(g_testQueueID01, buff2, QUEUE_SHORT_BUFFER_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + ret = LOS_QueueRead(g_testQueueID01, buff2, QUEUE_SHORT_BUFFER_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISEMPTY, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, buff1, QUEUE_SHORT_BUFFER_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, buff2, QUEUE_SHORT_BUFFER_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueInfoGet(g_testQueueID01, &queueInfo); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ICUNIT_GOTO_EQUAL(queueInfo.usQueueLen, len, queueInfo.usQueueLen, EXIT); + ICUNIT_GOTO_EQUAL(queueInfo.uwQueueID, g_testQueueID01, queueInfo.uwQueueID, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, buff2, QUEUE_SHORT_BUFFER_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISEMPTY, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItLosQueue088(VOID) +{ + TEST_ADD_CASE("ItLosQueue088", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_089.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_089.c new file mode 100644 index 00000000..d63cf9f3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_089.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret, i, j; + UINT32 index; + const UINT32 len = 1000; + const UINT32 count = sizeof(UINTPTR); + CHAR filebuf[260] = "abcdeabcde0123456789abcedfghij9876550210abcdeabcde0123456789abcedfghij9876550210abcdeabcde0123" + "456789abcedfghij9876550210abcdeabcde0123456789abcedfghij9876550210abcdeabcde0123456789abcedfgh" + "ij9876550210abcdeabcde0123456789abcedfghij9876550210lalalalalalalala"; + CHAR readbuf[260] = ""; + QUEUE_INFO_S queueInfo; + + ret = LOS_QueueCreate("Q1", 1000, &g_testQueueID01, 0, count); // 1000, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueInfoGet(g_testQueueID01, &queueInfo); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ICUNIT_GOTO_EQUAL(queueInfo.usQueueLen, len, queueInfo.usQueueLen, EXIT); + ICUNIT_GOTO_EQUAL(queueInfo.uwQueueID, g_testQueueID01, queueInfo.uwQueueID, EXIT); + + for (j = 0; j < 100; j++) { // 100, The loop frequency. + for (i = 0; i < 1000; i++) { // 1000, The loop frequency. + ret = LOS_QueueWrite(g_testQueueID01, filebuf, QUEUE_SHORT_BUFFER_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + ret = LOS_QueueWrite(g_testQueueID01, filebuf, QUEUE_SHORT_BUFFER_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISFULL, ret, EXIT); + + for (i = 0; i < 1000; i++) { // 1000, The loop frequency. + ret = memset_s(readbuf, 260, 0, 260); // 260, Read buf size. + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ret = LOS_QueueRead(g_testQueueID01, readbuf, QUEUE_SHORT_BUFFER_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + ret = LOS_QueueRead(g_testQueueID01, readbuf, QUEUE_SHORT_BUFFER_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISEMPTY, ret, EXIT); + } + ret = LOS_QueueWrite(g_testQueueID01, filebuf, QUEUE_SHORT_BUFFER_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, readbuf, QUEUE_SHORT_BUFFER_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueInfoGet(g_testQueueID01, &queueInfo); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ICUNIT_GOTO_EQUAL(queueInfo.usQueueLen, len, queueInfo.usQueueLen, EXIT); + ICUNIT_GOTO_EQUAL(queueInfo.uwQueueID, g_testQueueID01, queueInfo.uwQueueID, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, readbuf, QUEUE_SHORT_BUFFER_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISEMPTY, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItLosQueue089(VOID) +{ + TEST_ADD_CASE("ItLosQueue089", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_091.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_091.c new file mode 100644 index 00000000..42f552a0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_091.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(VOID) +{ + UINT32 ret; + CHAR buffer2[] = "UniDSP"; + + ret = LOS_QueueRead(g_testQueueID01, &buffer2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buffer1[] = "MiniOS"; + CHAR buffer2[] = "UniDSP"; + + UINT16 swTmrID; + INT32 value; + + g_testCount = 0; + + ret = LOS_SwtmrCreate(20, LOS_SWTMR_MODE_ONCE, (SWTMR_PROC_FUNC)SwtmrF01, &swTmrID, 0xffff); // 20, Timing duration of the software timer to be created. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + + ret = LOS_QueueCreate("Q1", 10, &g_testQueueID01, 0, 8); // 10, Set the queue length; 8, Set the node size of the queue. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + + ret = LOS_QueueWrite(g_testQueueID01, &buffer1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + + LOS_SwtmrStart(swTmrID); + + ret = LOS_TaskDelay(5); // 5, set delay time. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + + LOS_SwtmrDelete(swTmrID); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; + +EXIT1: + LOS_SwtmrDelete(swTmrID); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItLosQueue091(VOID) +{ + TEST_ADD_CASE("ItLosQueue091", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_092.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_092.c new file mode 100644 index 00000000..c6f6aa59 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_092.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(VOID) +{ + UINT32 ret; + + ret = LOS_QueueCreate("Q1", 2, &g_testQueueID01, 0, sizeof(UINTPTR)); // 2, Set the queue length. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; +} + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buffer1[] = "MiniOS"; + CHAR buffer2[] = "UniDSP"; + + UINT16 swTmrID; + INT32 value; + + g_testCount = 0; + + // 4, Timing duration of the software timer to be created. + ret = LOS_SwtmrCreate(4, LOS_SWTMR_MODE_ONCE, (SWTMR_PROC_FUNC)SwtmrF01, &swTmrID, 0xffff); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + + LOS_SwtmrStart(swTmrID); + + ret = LOS_TaskDelay(5); // 5, set delay time. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + + ret = LOS_QueueWrite(g_testQueueID01, &buffer1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + + ret = LOS_QueueRead(g_testQueueID01, &buffer2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + + LOS_SwtmrDelete(swTmrID); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT1: + LOS_SwtmrDelete(swTmrID); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItLosQueue092(VOID) +{ + TEST_ADD_CASE("ItLosQueue092", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_093.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_093.c new file mode 100644 index 00000000..817d32b6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_093.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(VOID) +{ + UINT32 ret; + CHAR buffer1[] = "MiniOS"; + + ret = LOS_QueueCreate("Q1", 2, &g_testQueueID01, 0, sizeof(UINTPTR)); // 2, Set the queue length. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_QueueWrite(g_testQueueID01, &buffer1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buffer2[] = "UniDSP"; + + UINT16 swTmrID; + INT32 value; + + g_testCount = 0; + + // 4, Timing duration of the software timer to be created. + ret = LOS_SwtmrCreate(4, LOS_SWTMR_MODE_ONCE, (SWTMR_PROC_FUNC)SwtmrF01, &swTmrID, 0xffff); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + + LOS_SwtmrStart(swTmrID); + + ret = LOS_TaskDelay(5); // 5, set delay time. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + + ret = LOS_QueueRead(g_testQueueID01, &buffer2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + + LOS_SwtmrDelete(swTmrID); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT1: + LOS_SwtmrDelete(swTmrID); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItLosQueue093(VOID) +{ + TEST_ADD_CASE("ItLosQueue093", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_094.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_094.c new file mode 100644 index 00000000..c0277ad2 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_094.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID SwtmrF01(VOID) +{ + UINT32 ret; + CHAR buffer1[] = "MiniOS"; + CHAR buffer2[] = "UniDSP"; + + ret = LOS_QueueWrite(g_testQueueID01, &buffer1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_QueueRead(g_testQueueID01, &buffer2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; +} +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buffer1[] = "MiniOS"; + CHAR buffer2[] = "UniDSP"; + + UINT16 swTmrID; + INT32 value; + + g_testCount = 0; + + // 4, Timing duration of the software timer to be created. + ret = LOS_SwtmrCreate(4, LOS_SWTMR_MODE_ONCE, (SWTMR_PROC_FUNC)SwtmrF01, &swTmrID, 0xffff); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueCreate("Q1", 10, &g_testQueueID01, 0, sizeof(UINTPTR)); // 10, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_SwtmrStart(swTmrID); + + ret = LOS_TaskDelay(5); // 5, set delay time. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + + ret = LOS_QueueRead(g_testQueueID01, &buffer2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISEMPTY, ret, EXIT1); + + LOS_SwtmrDelete(swTmrID); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; + +EXIT1: + LOS_SwtmrDelete(swTmrID); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItLosQueue094(VOID) +{ + TEST_ADD_CASE("ItLosQueue094", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_095.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_095.c new file mode 100644 index 00000000..57bea3af --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_095.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static VOID SwtmrF01(VOID) +{ + UINT32 ret; + CHAR buffer1[] = "MiniOS"; + CHAR buffer2[] = "UniDSP"; + + ret = LOS_QueueCreate("Q1", 10, &g_testQueueID01, 0, sizeof(UINTPTR)); // 10, Set the queue length. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_QueueWrite(g_testQueueID01, &buffer1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_QueueRead(g_testQueueID01, &buffer2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buffer1[] = "MiniOS"; + CHAR buffer2[] = "UniDSP"; + UINT16 swTmrID; + + g_testCount = 0; + + // 4, Timing duration of the software timer to be created. + ret = LOS_SwtmrCreate(4, LOS_SWTMR_MODE_ONCE, (SWTMR_PROC_FUNC)SwtmrF01, &swTmrID, 0xffff); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_SwtmrStart(swTmrID); + + ret = LOS_TaskDelay(5); // 5, set delay time. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT1); + + ret = LOS_QueueRead(g_testQueueID01, &buffer2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISEMPTY, ret, EXIT1); + + LOS_SwtmrDelete(swTmrID); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +EXIT1: + LOS_SwtmrDelete(swTmrID); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItLosQueue095(VOID) +{ + TEST_ADD_CASE("ItLosQueue095", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_096.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_096.c new file mode 100644 index 00000000..a5ec9e1a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_096.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 queueID; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + QUEUE_INFO_S queueInfo; + + queueID = LOSCFG_BASE_IPC_QUEUE_CONFIG + 1; + ret = LOS_QueueInfoGet(queueID, &queueInfo); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_INVALID, ret, EXIT); + + queueID = LOSCFG_BASE_IPC_QUEUE_CONFIG; + ret = LOS_QueueInfoGet(queueID, &queueInfo); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_INVALID, ret, EXIT); + + queueID = LOSCFG_BASE_IPC_QUEUE_CONFIG - 1; + ret = LOS_QueueInfoGet(queueID, &queueInfo); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_NOT_CREATE, ret, EXIT); + + return LOS_OK; + +EXIT: + LOS_QueueDelete(queueID); + return LOS_OK; +} + +VOID ItLosQueue096(VOID) +{ + TEST_ADD_CASE("ItLosQueue096", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_098.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_098.c new file mode 100644 index 00000000..1ce9ee41 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_098.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 queueID; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + QUEUE_INFO_S queueInfo; + UINT32 readSize; + + queueID = LOSCFG_BASE_IPC_QUEUE_CONFIG + 1; + ret = memset_s(buff2, QUEUE_SHORT_BUFFER_LENGTH, 0, QUEUE_SHORT_BUFFER_LENGTH); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + readSize = 8; // 8, Read the setting size of queue buffer. + ret = LOS_QueueReadCopy(queueID, &buff2, &readSize, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_INVALID, ret, EXIT); + ICUNIT_GOTO_EQUAL(readSize, 8, readSize, EXIT); // 8, Here, assert that g_testCount is equal to 8. + + queueID = LOSCFG_BASE_IPC_QUEUE_CONFIG; + ret = memset_s(buff2, QUEUE_SHORT_BUFFER_LENGTH, 0, QUEUE_SHORT_BUFFER_LENGTH); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + readSize = 8; // 8, Read the setting size of queue buffer. + ret = LOS_QueueReadCopy(queueID, &buff2, &readSize, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_INVALID, ret, EXIT); + ICUNIT_GOTO_EQUAL(readSize, 8, readSize, EXIT); // 8, Here, assert that g_testCount is equal to 8. + + queueID = LOSCFG_BASE_IPC_QUEUE_CONFIG - 1; + ret = memset_s(buff2, QUEUE_SHORT_BUFFER_LENGTH, 0, QUEUE_SHORT_BUFFER_LENGTH); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + readSize = 8; // 8, Read the setting size of queue buffer. + ret = LOS_QueueReadCopy(queueID, &buff2, &readSize, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_NOT_CREATE, ret, EXIT); + ICUNIT_GOTO_EQUAL(readSize, 8, readSize, EXIT); // 8, Here, assert that g_testCount is equal to 8. + + queueID = 0; + ret = memset_s(buff2, QUEUE_SHORT_BUFFER_LENGTH, 0, QUEUE_SHORT_BUFFER_LENGTH); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + readSize = 8; // 8, Read the setting size of queue buffer. + ret = LOS_QueueReadCopy(queueID - 1, &buff2, &readSize, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_INVALID, ret, EXIT); + ICUNIT_GOTO_EQUAL(readSize, 8, readSize, EXIT); // 8, Here, assert that g_testCount is equal to 8. + + return LOS_OK; + +EXIT: + LOS_QueueDelete(queueID); + return LOS_OK; +} + +VOID ItLosQueue098(VOID) +{ + TEST_ADD_CASE("ItLosQueue098", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_099.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_099.c new file mode 100644 index 00000000..72ac08df --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_099.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 queueID; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + QUEUE_INFO_S queueInfo; + UINT32 readSize; + + ret = LOS_QueueCreate("Q1", 3, &queueID, 0, 8); // 3, Set the queue length; 8, Set the node size of the queue. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueInfoGet(queueID, &queueInfo); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(queueID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = memset_s(buff2, QUEUE_SHORT_BUFFER_LENGTH, 0, QUEUE_SHORT_BUFFER_LENGTH); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + readSize = 8; // 8, Read the setting size of queue buffer. + ret = LOS_QueueReadCopy(queueID, &buff2, &readSize, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_NOT_CREATE, ret, EXIT); + + ret = LOS_QueueInfoGet(queueID, &queueInfo); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_NOT_CREATE, ret, EXIT); + + return LOS_OK; + +EXIT: + LOS_QueueDelete(queueID); + return LOS_OK; +} + +VOID ItLosQueue099(VOID) +{ + TEST_ADD_CASE("ItLosQueue099", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_101.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_101.c new file mode 100644 index 00000000..3384dda6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_101.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 queueID; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + QUEUE_INFO_S queueInfo; + UINT32 readSize; + + ret = LOS_QueueCreate("Q1", 3, &queueID, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(queueID, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = memset_s(buff2, QUEUE_SHORT_BUFFER_LENGTH, 0, QUEUE_SHORT_BUFFER_LENGTH); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + readSize = sizeof(buff1); + ret = LOS_QueueReadCopy(queueID, NULL, &readSize, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_READ_PTR_NULL, ret, EXIT); + + ret = memset_s(buff2, QUEUE_SHORT_BUFFER_LENGTH, 0, QUEUE_SHORT_BUFFER_LENGTH); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + readSize = sizeof(buff1); + ret = LOS_QueueReadCopy(queueID, &buff2, &readSize, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(queueID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return LOS_OK; + +EXIT: + LOS_QueueDelete(queueID); + return LOS_OK; +} + +VOID ItLosQueue101(VOID) +{ + TEST_ADD_CASE("ItLosQueue101", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_102.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_102.c new file mode 100644 index 00000000..7c793f84 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_102.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 queueID; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + QUEUE_INFO_S queueInfo; + UINT32 readSize; + + ret = LOS_QueueCreate("Q1", 3, &queueID, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(queueID, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = memset_s(buff2, QUEUE_SHORT_BUFFER_LENGTH, 0, QUEUE_SHORT_BUFFER_LENGTH); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + readSize = sizeof(buff1); + ret = LOS_QueueReadCopy(queueID, &buff2, &readSize, 0xffffffff); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(queueID, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = memset_s(buff2, QUEUE_SHORT_BUFFER_LENGTH, 0, QUEUE_SHORT_BUFFER_LENGTH); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + readSize = sizeof(buff1); + ret = LOS_QueueReadCopy(queueID, &buff2, &readSize, 0xffffffff + 1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(queueID, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = memset_s(buff2, QUEUE_SHORT_BUFFER_LENGTH, 0, QUEUE_SHORT_BUFFER_LENGTH); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + readSize = sizeof(buff1); + ret = LOS_QueueReadCopy(queueID, &buff2, &readSize, 0xffffffff - 1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(queueID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return LOS_OK; + +EXIT: + LOS_QueueDelete(queueID); + return LOS_OK; +} + +VOID ItLosQueue102(VOID) +{ + TEST_ADD_CASE("ItLosQueue102", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_103.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_103.c new file mode 100644 index 00000000..655953d5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_103.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 queueID; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + QUEUE_INFO_S queueInfo; + + queueID = LOSCFG_BASE_IPC_QUEUE_CONFIG; + ret = LOS_QueueWriteCopy(queueID, &buff1, 8, 0); // 8, Incoming buffer size. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_INVALID, ret, EXIT); + + queueID = LOSCFG_BASE_IPC_QUEUE_CONFIG + 1; + ret = LOS_QueueWriteCopy(queueID, &buff1, 8, 0); // 8, Incoming buffer size. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_INVALID, ret, EXIT); + + queueID = LOSCFG_BASE_IPC_QUEUE_CONFIG - 1; + ret = LOS_QueueWriteCopy(queueID, &buff1, 8, 0); // 8, Incoming buffer size. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_NOT_CREATE, ret, EXIT); + + queueID = 0; + ret = LOS_QueueWriteCopy(queueID - 1, &buff1, 8, 0); // 8, Incoming buffer size. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_INVALID, ret, EXIT); + + return LOS_OK; + +EXIT: + LOS_QueueDelete(queueID); + return LOS_OK; +} + +VOID ItLosQueue103(VOID) +{ + TEST_ADD_CASE("ItLosQueue103", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_104.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_104.c new file mode 100644 index 00000000..75882bb6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_104.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 queueID; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + QUEUE_INFO_S queueInfo; + + ret = LOS_QueueCreate("Q1", 3, &queueID, 0, 8); // 3, Set the queue length; 8, Set the node size of the queue. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWriteCopy(queueID, &buff1, 8, 0); // 8, Incoming buffer size. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueInfoGet(queueID, &queueInfo); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ICUNIT_GOTO_EQUAL(queueInfo.usQueueLen, 3, queueInfo.usQueueLen, EXIT); // 3, Here, assert that g_testCount is equal to 3. + ICUNIT_GOTO_EQUAL(queueInfo.uwQueueID, queueID, queueInfo.uwQueueID, EXIT); + + ret = LOS_QueueDelete(queueID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWriteCopy(queueID, &buff1, 8, 0); // 8, Incoming buffer size. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_NOT_CREATE, ret, EXIT); + + ret = LOS_QueueDelete(queueID); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_NOT_CREATE, ret, EXIT); + + return LOS_OK; + +EXIT: + LOS_QueueDelete(queueID); + return LOS_OK; +} + +VOID ItLosQueue104(VOID) +{ + TEST_ADD_CASE("ItLosQueue104", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_106.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_106.c new file mode 100644 index 00000000..896d059f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_106.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 queueID; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "ABC"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + QUEUE_INFO_S queueInfo; + + ret = LOS_QueueCreate("Q1", 3, &queueID, 0, QUEUE_SHORT_BUFFER_LENGTH); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWriteCopy(queueID, NULL, QUEUE_SHORT_BUFFER_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_WRITE_PTR_NULL, ret, EXIT); + + ret = memset_s(buff2, QUEUE_SHORT_BUFFER_LENGTH, 0, QUEUE_SHORT_BUFFER_LENGTH); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ret = LOS_QueueRead(queueID, &buff2, QUEUE_SHORT_BUFFER_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISEMPTY, ret, EXIT); + + ret = LOS_QueueWriteCopy(queueID, &buff1, QUEUE_SHORT_BUFFER_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = memset_s(buff2, QUEUE_SHORT_BUFFER_LENGTH, 0, QUEUE_SHORT_BUFFER_LENGTH); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ret = LOS_QueueRead(queueID, &buff2, QUEUE_SHORT_BUFFER_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(queueID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return LOS_OK; + +EXIT: + LOS_QueueDelete(queueID); + return LOS_OK; +} + +VOID ItLosQueue106(VOID) +{ + TEST_ADD_CASE("ItLosQueue106", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_107.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_107.c new file mode 100644 index 00000000..a29dbdc5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_107.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 queueID; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "123"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + QUEUE_INFO_S queueInfo; + + ret = LOS_QueueCreate("Q1", 3, &queueID, 0, QUEUE_SHORT_BUFFER_LENGTH); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWriteCopy(queueID, &buff1, QUEUE_SHORT_BUFFER_LENGTH, 0xffffffff); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = memset_s(buff2, QUEUE_SHORT_BUFFER_LENGTH, 0, QUEUE_SHORT_BUFFER_LENGTH); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ret = LOS_QueueRead(queueID, &buff2, QUEUE_SHORT_BUFFER_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWriteCopy(queueID, &buff1, QUEUE_SHORT_BUFFER_LENGTH, 0xffffffff + 1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = memset_s(buff2, QUEUE_SHORT_BUFFER_LENGTH, 0, QUEUE_SHORT_BUFFER_LENGTH); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ret = LOS_QueueRead(queueID, &buff2, QUEUE_SHORT_BUFFER_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWriteCopy(queueID, &buff1, QUEUE_SHORT_BUFFER_LENGTH, 0xffffffff - 1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = memset_s(buff2, QUEUE_SHORT_BUFFER_LENGTH, 0, QUEUE_SHORT_BUFFER_LENGTH); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ret = LOS_QueueRead(queueID, &buff2, QUEUE_SHORT_BUFFER_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(queueID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return LOS_OK; + +EXIT: + LOS_QueueDelete(queueID); + return LOS_OK; +} + +VOID ItLosQueue107(VOID) +{ + TEST_ADD_CASE("ItLosQueue107", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_108.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_108.c new file mode 100644 index 00000000..48e42202 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_108.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static VOID HwiF01(VOID) +{ + UINT32 ret; + QUEUE_INFO_S queueInfo; + + TEST_HwiClear(HWI_NUM_TEST); + + g_testCount++; + + ret = LOS_QueueInfoGet(g_testQueueID01, &queueInfo); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ICUNIT_GOTO_EQUAL(queueInfo.usQueueLen, 3, queueInfo.usQueueLen, EXIT); // 3, Here, assert that g_testCount is equal to 3. + ICUNIT_GOTO_EQUAL(queueInfo.uwQueueID, g_testQueueID01, queueInfo.uwQueueID, EXIT); + + g_testCount++; + + return; +EXIT: + g_testCount = 0; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + QUEUE_INFO_S queueInfo; + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, QUEUE_SHORT_BUFFER_LENGTH); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, QUEUE_SHORT_BUFFER_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = TEST_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + TestHwiTrigger(HWI_NUM_TEST); + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + + g_testCount++; + + ret = LOS_QueueInfoGet(g_testQueueID01, &queueInfo); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ICUNIT_GOTO_EQUAL(queueInfo.usQueueLen, 3, queueInfo.usQueueLen, EXIT); // 3, Here, assert that g_testCount is equal to 3. + ICUNIT_GOTO_EQUAL(queueInfo.uwQueueID, g_testQueueID01, queueInfo.uwQueueID, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, Here, assert that g_testCount is equal to 3. + + TEST_HwiDelete(HWI_NUM_TEST); + + return LOS_OK; + +EXIT: + TEST_HwiDelete(HWI_NUM_TEST); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItLosQueue108(VOID) +{ + TEST_ADD_CASE("ItLosQueue108", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_109.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_109.c new file mode 100644 index 00000000..f5dbf5ae --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_109.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + QUEUE_INFO_S queueInfo; + + g_testCount++; + + ret = LOS_QueueInfoGet(g_testQueueID01, &queueInfo); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ICUNIT_GOTO_EQUAL(queueInfo.usQueueLen, 3, queueInfo.usQueueLen, EXIT); // 3, Here, assert that g_testCount is equal to 3. + ICUNIT_GOTO_EQUAL(queueInfo.uwQueueID, g_testQueueID01, queueInfo.uwQueueID, EXIT); + + g_testCount++; + + LOS_TaskDelete(g_testTaskID01); + + return; +EXIT: + g_testCount = 0; + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + QUEUE_INFO_S queueInfo; + TSK_INIT_PARAM_S task1 = { 0 }; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "queue_109"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = 23; // 23, Set task priority. + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, QUEUE_SHORT_BUFFER_LENGTH); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, QUEUE_SHORT_BUFFER_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + + g_testCount++; + + ret = LOS_QueueInfoGet(g_testQueueID01, &queueInfo); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ICUNIT_GOTO_EQUAL(queueInfo.usQueueLen, 3, queueInfo.usQueueLen, EXIT); // 3, Here, assert that g_testCount is equal to 3. + ICUNIT_GOTO_EQUAL(queueInfo.uwQueueID, g_testQueueID01, queueInfo.uwQueueID, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, Here, assert that g_testCount is equal to 3. + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItLosQueue109(VOID) +{ + TEST_ADD_CASE("ItLosQueue109", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_110.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_110.c new file mode 100644 index 00000000..7e48a783 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_110.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static VOID SwtmrF01(VOID) +{ + UINT32 ret; + QUEUE_INFO_S queueInfo; + + g_testCount++; + + ret = LOS_QueueInfoGet(g_testQueueID01, &queueInfo); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ICUNIT_GOTO_EQUAL(queueInfo.usQueueLen, 3, queueInfo.usQueueLen, EXIT); // 3, Here, assert that g_testCount is equal to 3. + ICUNIT_GOTO_EQUAL(queueInfo.uwQueueID, g_testQueueID01, queueInfo.uwQueueID, EXIT); + + g_testCount++; + + return; +EXIT: + g_testCount = 0; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + QUEUE_INFO_S queueInfo; + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, QUEUE_SHORT_BUFFER_LENGTH); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, QUEUE_SHORT_BUFFER_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrCreate(4, LOS_SWTMR_MODE_ONCE, (SWTMR_PROC_FUNC)SwtmrF01, &swTmrID, 0xffff); // 4, Timing duration of the software timer to be created. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrStart(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskDelay(5); // 5, set delay time. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + + ret = LOS_QueueInfoGet(g_testQueueID01, &queueInfo); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ICUNIT_GOTO_EQUAL(queueInfo.usQueueLen, 3, queueInfo.usQueueLen, EXIT); // 3, Here, assert that g_testCount is equal to 3. + ICUNIT_GOTO_EQUAL(queueInfo.uwQueueID, g_testQueueID01, queueInfo.uwQueueID, EXIT); + + LOS_SwtmrDelete(swTmrID); + + g_testCount++; + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, Here, assert that g_testCount is equal to 3. + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + LOS_SwtmrDelete(swTmrID); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItLosQueue110(VOID) +{ + TEST_ADD_CASE("ItLosQueue110", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_111.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_111.c new file mode 100644 index 00000000..84ed0f2a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_111.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static VOID HwiF01(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + UINT32 readSize; + + TEST_HwiClear(HWI_NUM_TEST); + + g_testCount++; + + ret = LOS_QueueWriteCopy(g_testQueueID01, &buff1, QUEUE_SHORT_BUFFER_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + readSize = QUEUE_SHORT_BUFFER_LENGTH; + ret = LOS_QueueReadCopy(g_testQueueID01, &buff2, &readSize, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + g_testCount++; + + return; +EXIT: + g_testCount = 0; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + QUEUE_INFO_S queueInfo; + UINT32 readSize; + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, QUEUE_SHORT_BUFFER_LENGTH); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = TEST_HwiCreate(HWI_NUM_TEST, 1, 0, HwiF01, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + TestHwiTrigger(HWI_NUM_TEST); + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + + g_testCount++; + + readSize = QUEUE_SHORT_BUFFER_LENGTH; + ret = LOS_QueueReadCopy(g_testQueueID01, &buff2, &readSize, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISEMPTY, ret, EXIT); + + ret = LOS_QueueInfoGet(g_testQueueID01, &queueInfo); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ICUNIT_GOTO_EQUAL(queueInfo.usQueueLen, 3, queueInfo.usQueueLen, EXIT); // 3, Here, assert that g_testCount is equal to 3. + ICUNIT_GOTO_EQUAL(queueInfo.uwQueueID, g_testQueueID01, queueInfo.uwQueueID, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, Here, assert that g_testCount is equal to 3. + + TEST_HwiDelete(HWI_NUM_TEST); + + return LOS_OK; + +EXIT: + TEST_HwiDelete(HWI_NUM_TEST); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItLosQueue111(VOID) +{ + TEST_ADD_CASE("ItLosQueue111", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_112.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_112.c new file mode 100644 index 00000000..85334d30 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_112.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static VOID TaskF01(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + UINT32 readSize; + + TEST_HwiClear(HWI_NUM_TEST); + + g_testCount++; + + ret = LOS_QueueWriteCopy(g_testQueueID01, &buff1, QUEUE_SHORT_BUFFER_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + readSize = QUEUE_SHORT_BUFFER_LENGTH; + ret = LOS_QueueReadCopy(g_testQueueID01, &buff2, &readSize, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + g_testCount++; + + LOS_TaskDelete(g_testTaskID01); + + return; +EXIT: + g_testCount = 0; + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + QUEUE_INFO_S queueInfo; + TSK_INIT_PARAM_S task1 = { 0 }; + UINT32 readSize; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.pcName = "queue_109"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = 23; // 23, Set task priority. + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, QUEUE_SHORT_BUFFER_LENGTH); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + + g_testCount++; + + readSize = QUEUE_SHORT_BUFFER_LENGTH; + ret = LOS_QueueReadCopy(g_testQueueID01, &buff2, &readSize, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISEMPTY, ret, EXIT); + + ret = LOS_QueueInfoGet(g_testQueueID01, &queueInfo); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ICUNIT_GOTO_EQUAL(queueInfo.usQueueLen, 3, queueInfo.usQueueLen, EXIT); // 3, Here, assert that g_testCount is equal to 3. + ICUNIT_GOTO_EQUAL(queueInfo.uwQueueID, g_testQueueID01, queueInfo.uwQueueID, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, Here, assert that g_testCount is equal to 3. + + return LOS_OK; + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItLosQueue112(VOID) +{ + TEST_ADD_CASE("ItLosQueue112", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_113.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_113.c new file mode 100644 index 00000000..4381092e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_113.c @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static VOID SwtmrF01(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + UINT32 readSize; + + g_testCount++; + + ret = LOS_QueueWriteCopy(g_testQueueID01, &buff1, QUEUE_SHORT_BUFFER_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + readSize = QUEUE_SHORT_BUFFER_LENGTH; + ret = LOS_QueueReadCopy(g_testQueueID01, &buff2, &readSize, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + g_testCount++; + + return; +EXIT: + g_testCount = 0; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT16 swTmrID; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + QUEUE_INFO_S queueInfo; + UINT32 readSize; + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, QUEUE_SHORT_BUFFER_LENGTH); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + // 4, Timing duration of the software timer to be created. + ret = LOS_SwtmrCreate(4, LOS_SWTMR_MODE_ONCE, (SWTMR_PROC_FUNC)SwtmrF01, &swTmrID, 0xffff); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SwtmrStart(swTmrID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskDelay(5); // 5, set delay time. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + + readSize = QUEUE_SHORT_BUFFER_LENGTH; + ret = LOS_QueueReadCopy(g_testQueueID01, &buff2, &readSize, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISEMPTY, ret, EXIT); + + ret = LOS_QueueInfoGet(g_testQueueID01, &queueInfo); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ICUNIT_GOTO_EQUAL(queueInfo.usQueueLen, 3, queueInfo.usQueueLen, EXIT); // 3, Here, assert that g_testCount is equal to 3. + ICUNIT_GOTO_EQUAL(queueInfo.uwQueueID, g_testQueueID01, queueInfo.uwQueueID, EXIT); + + LOS_SwtmrDelete(swTmrID); + + g_testCount++; + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, Here, assert that g_testCount is equal to 3. + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + LOS_SwtmrDelete(swTmrID); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +/* +********** +testcase brief in English +********** +*/ + +VOID ItLosQueue113(VOID) +{ + TEST_ADD_CASE("ItLosQueue113", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_114.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_114.c new file mode 100644 index 00000000..95c9e33c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_114.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 i; + UINT32 queueID; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + QUEUE_INFO_S queueInfo; + + ret = LOS_QueueCreate("Q1", 3, &queueID, 0, QUEUE_SHORT_BUFFER_LENGTH); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + for (i = 0; i < 3; i++) { // 3, The loop frequency. + ret = LOS_QueueWriteCopy(queueID, &buff1, QUEUE_SHORT_BUFFER_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + + ret = LOS_QueueWrite(queueID, &buff1, QUEUE_SHORT_BUFFER_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISFULL, ret, EXIT); + + ret = LOS_QueueWriteCopy(queueID, &buff1, QUEUE_SHORT_BUFFER_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISFULL, ret, EXIT); + + ret = LOS_QueueInfoGet(queueID, &queueInfo); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ICUNIT_GOTO_EQUAL(queueInfo.usQueueLen, 3, queueInfo.usQueueLen, EXIT); // 3, Here, assert that g_testCount is equal to 3. + ICUNIT_GOTO_EQUAL(queueInfo.uwQueueID, queueID, queueInfo.uwQueueID, EXIT); + + ret = LOS_QueueDelete(queueID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return LOS_OK; + +EXIT: + LOS_QueueDelete(queueID); + return LOS_OK; +} + +VOID ItLosQueue114(VOID) +{ + TEST_ADD_CASE("ItLosQueue114", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_116.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_116.c new file mode 100644 index 00000000..00fc98e4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_116.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + QUEUE_INFO_S queueInfo; + UINT32 readSize; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, 8); // 3, Set the queue length; 8, Set the node size of the queue. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWriteCopy(g_testQueueID01, &buff1, 8, 0); // 8, Incoming buffer size. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + readSize = 8; // 8, Read the setting size of queue buffer. + ret = LOS_QueueReadCopy(g_testQueueID01, &buff2, &readSize, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueInfoGet(g_testQueueID01, &queueInfo); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + readSize = 8; // 8, Read the setting size of queue buffer. + ret = LOS_QueueReadCopy(g_testQueueID01, &buff2, &readSize, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISEMPTY, ret, EXIT); + + LOS_TaskLock(); + readSize = 8; // 8, Read the setting size of queue buffer. + ret = LOS_QueueReadCopy(g_testQueueID01, &buff2, &readSize, 1); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_PEND_IN_LOCK, ret, EXIT); + LOS_TaskUnlock(); + + readSize = 8; // 8, Read the setting size of queue buffer. + ret = LOS_QueueReadCopy(g_testQueueID01, &buff2, &readSize, 2); // 2, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_TIMEOUT, ret, EXIT); + +EXIT: + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItLosQueue116(VOID) +{ + TEST_ADD_CASE("ItLosQueue116", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_003.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_003.c new file mode 100644 index 00000000..598f570d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_003.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[8] = "A"; + CHAR buff2[8] = "B"; + CHAR buff3[8] = "C"; + CHAR buff4[8] = ""; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWriteHead(g_testQueueID01, &buff2, sizeof(UINTPTR), 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWriteHead(g_testQueueID01, &buff3, sizeof(UINTPTR), 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff4, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosQueueHead003(VOID) +{ + TEST_ADD_CASE("ItLosQueueHead003", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_004.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_004.c new file mode 100644 index 00000000..96f772cb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_004.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[8] = "A"; + CHAR buff2[8] = "B"; + CHAR buff3[8] = "C"; + CHAR buff4[8] = "D"; + CHAR buff5[8] = ""; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWriteHead(g_testQueueID01, &buff2, sizeof(UINTPTR), 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWriteHead(g_testQueueID01, &buff3, sizeof(UINTPTR), 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWriteHead(g_testQueueID01, &buff4, sizeof(UINTPTR), 0); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISFULL, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff5, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosQueueHead004(VOID) +{ + TEST_ADD_CASE("ItLosQueueHead004", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_005.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_005.c new file mode 100644 index 00000000..ad7f6fdb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_005.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[8] = "UniDSP"; + CHAR buff2[8] = ""; + + g_testQueueID01 = 1025; // 1025, ID of successfully created queue control structure. + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, 0); // 3, Set the queue length. + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_QUEUE_PARA_ISZERO, ret); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_QUEUE_INVALID, ret); + + ret = LOS_QueueWriteHead(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_QUEUE_INVALID, ret); + + return LOS_OK; +} + +VOID ItLosQueueHead005(VOID) +{ + TEST_ADD_CASE("ItLosQueueHead005", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_006.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_006.c new file mode 100644 index 00000000..5dd55bec --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_006.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[8] = "UniDSP"; + CHAR buff2[8] = ""; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, 1); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWriteHead(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_WRITE_SIZE_TOO_BIG, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISEMPTY, ret, EXIT); + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosQueueHead006(VOID) +{ + TEST_ADD_CASE("ItLosQueueHead006", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_007.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_007.c new file mode 100644 index 00000000..2ff2037d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_007.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[8] = "UniDSP"; + CHAR buff2[8] = ""; + + g_testQueueID01 = 0x5; + + ret = LOS_QueueCreate("Q1", 30, &g_testQueueID01, 0, 0xFFFF); // 30, Set the queue length. + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_QUEUE_SIZE_TOO_BIG, ret); + + ret = LOS_QueueWriteHead(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_QUEUE_NOT_CREATE, ret); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_QUEUE_NOT_CREATE, ret); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_QUEUE_NOT_CREATE, ret); + + return LOS_OK; +} + +VOID ItLosQueueHead007(VOID) +{ + TEST_ADD_CASE("ItLosQueueHead007", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_008.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_008.c new file mode 100644 index 00000000..5c374238 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_008.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[8] = "UniDSP"; + CHAR buff2[8] = ""; + + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, sizeof(UINTPTR)); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWriteHead(g_testQueueID01, &buff1, sizeof(UINTPTR), 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, sizeof(UINTPTR), 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosQueueHead008(VOID) +{ + TEST_ADD_CASE("ItLosQueueHead008", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_009.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_009.c new file mode 100644 index 00000000..86201cb1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_009.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[8] = "UniDSP"; + CHAR buff2[8] = ""; + + g_testQueueID01 = 1025; // 1025, ID of successfully created queue control structure. + + ret = LOS_QueueCreate("Q1", 0xFFF0, &g_testQueueID01, 0, 0xFFFF); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_QUEUE_SIZE_TOO_BIG, ret); + + ret = LOS_QueueWriteHead(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_QUEUE_INVALID, ret); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_QUEUE_INVALID, ret); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_QUEUE_NOT_FOUND, ret); + + return LOS_OK; +} + +VOID ItLosQueueHead009(VOID) +{ + TEST_ADD_CASE("ItLosQueueHead009", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_010.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_010.c new file mode 100644 index 00000000..680a34b4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_010.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[8] = "UniDSP"; + CHAR buff2[12] = ""; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWriteHead(g_testQueueID01, &buff1, sizeof(UINTPTR), 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, sizeof(UINTPTR) + 2, 0); // 2, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosQueueHead010(VOID) +{ + TEST_ADD_CASE("ItLosQueueHead010", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_011.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_011.c new file mode 100644 index 00000000..cc40bcf3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_011.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[] = "UniDSPOS"; + UINTPTR buff2; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWriteHead(g_testQueueID01, buff1, sizeof(UINTPTR), 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, (sizeof(UINTPTR) * 2 - 1), 0); // 2, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ICUNIT_GOTO_EQUAL(*((char *)buff2 + 6), buff1[6], *((char *)buff2 + 6), EXIT); // 6, The offset of queue buffer. + ICUNIT_GOTO_EQUAL(*((char *)buff2 + 7), 'S', *((char *)buff2 + 7), EXIT); // 7, The offset of queue buffer. + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosQueueHead011(VOID) +{ + TEST_ADD_CASE("ItLosQueueHead011", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_012.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_012.c new file mode 100644 index 00000000..57ccd96e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_012.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[] = "UniDSPOS"; + UINTPTR buff2; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWriteHead(g_testQueueID01, buff1, sizeof(UINTPTR), 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 9, 0); // 9, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ICUNIT_GOTO_EQUAL(*((char *)buff2 + 7), buff1[7], *((char *)buff2 + 7), EXIT); // 7, The offset of queue buffer. + ICUNIT_GOTO_EQUAL(*((char *)buff2 + 8), '\0', *((char *)buff2 + 8), EXIT); // 8, The offset of queue buffer. + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosQueueHead012(VOID) +{ + TEST_ADD_CASE("ItLosQueueHead012", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_013.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_013.c new file mode 100644 index 00000000..168fe46d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_013.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[8] = "UniDSP"; + CHAR buff2[9] = ""; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 9, 0); // 9, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISEMPTY, ret, EXIT); + + ret = LOS_QueueWriteHead(g_testQueueID01, &buff1, sizeof(UINTPTR), 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 9, 0); // 9, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosQueueHead013(VOID) +{ + TEST_ADD_CASE("ItLosQueueHead013", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_014.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_014.c new file mode 100644 index 00000000..c7fbfa32 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_014.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[8] = "UniDSP"; + CHAR buff2[16] = ""; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWriteHead(g_testQueueID01, &buff1, sizeof(UINTPTR), 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, sizeof(UINTPTR) * 2 - 1, 0); // 2, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosQueueHead014(VOID) +{ + TEST_ADD_CASE("ItLosQueueHead014", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_015.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_015.c new file mode 100644 index 00000000..0e437bf8 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_015.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 index; + UINT32 queueID[LOSCFG_BASE_IPC_QUEUE_CONFIG + 1]; + CHAR buff1[8] = "UniDSP"; + CHAR buff2[8] = ""; + + UINT32 exsitedQueue = QUEUE_EXISTED_NUM; + for (index = 0; index < LOSCFG_BASE_IPC_QUEUE_CONFIG - exsitedQueue; index++) { + ret = LOS_QueueCreate(NULL, 3, &queueID[index], 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + + ret = LOS_QueueWriteHead(queueID[index - 1], &buff1, sizeof(UINTPTR), 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(queueID[index - 1], &buff2, sizeof(UINTPTR), 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueCreate("Q1", 3, &queueID[index], 0, 8); // 3, Set the queue length; 8, Set the node size of the queue. + ICUNIT_GOTO_NOT_EQUAL(ret, LOS_OK, ret, EXIT); +EXIT: + for (index = 0; index < LOSCFG_BASE_IPC_QUEUE_CONFIG - exsitedQueue; index++) { + ret = LOS_QueueDelete(queueID[index]); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + return LOS_OK; +} + +VOID ItLosQueueHead015(VOID) +{ + TEST_ADD_CASE("ItLosQueueHead015", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_016.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_016.c new file mode 100644 index 00000000..467abed1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_016.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 index; + UINT32 queueID[LOSCFG_BASE_IPC_QUEUE_CONFIG + 1]; + CHAR buff1[8] = "UniDSP"; + CHAR buff2[8] = ""; + + UINT32 exsitedQueue = QUEUE_EXISTED_NUM; + for (index = 0; index < LOSCFG_BASE_IPC_QUEUE_CONFIG - exsitedQueue; index++) { + ret = LOS_QueueCreate(NULL, 3, &queueID[index], 0, 8); // 3, Set the queue length; 8, Set the node size of the queue. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + + ret = LOS_QueueCreate("Q1", 3, &queueID[LOSCFG_BASE_IPC_QUEUE_CONFIG], 0, 8); // 3, Set the queue length; 8, Set the node size of the queue. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_CB_UNAVAILABLE, ret, EXIT); + + ret = LOS_QueueWriteHead(LOSCFG_BASE_IPC_QUEUE_CONFIG + 1, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_INVALID, ret, EXIT); + + ret = LOS_QueueRead(LOSCFG_BASE_IPC_QUEUE_CONFIG + 1, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_INVALID, ret, EXIT); + +EXIT: + for (index = 0; index < LOSCFG_BASE_IPC_QUEUE_CONFIG - exsitedQueue; index++) { + ret = LOS_QueueDelete(queueID[index]); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + return LOS_OK; +} + +VOID ItLosQueueHead016(VOID) +{ + TEST_ADD_CASE("ItLosQueueHead016", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_017.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_017.c new file mode 100644 index 00000000..c6592e85 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_017.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[8] = "UniDSP"; + CHAR buff2[8] = ""; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISEMPTY, ret, EXIT); + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosQueueHead017(VOID) +{ + TEST_ADD_CASE("ItLosQueueHead017", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_018.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_018.c new file mode 100644 index 00000000..cc145edb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_018.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[8] = "UniDSP"; + CHAR buff2[8] = ""; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISEMPTY, ret, EXIT); + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosQueueHead018(VOID) +{ + TEST_ADD_CASE("ItLosQueueHead018", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_019.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_019.c new file mode 100644 index 00000000..85f8f20d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_019.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 index; + CHAR buff1[] = "UniDSP_TEST"; + UINTPTR buff2; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWriteHead(g_testQueueID01, buff1, sizeof(UINTPTR), 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + for (index = 0; index < 7; index++) { // 7, The loop frequency. Queue buffer size. + ICUNIT_GOTO_EQUAL(*((char *)buff2 + index), buff1[index], *((char *)buff2 + index), EXIT); + } + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISEMPTY, ret, EXIT); + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosQueueHead019(VOID) +{ + TEST_ADD_CASE("ItLosQueueHead019", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_020.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_020.c new file mode 100644 index 00000000..b57bb65c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_020.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff2[8] = ""; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWriteHead(g_testQueueID01, NULL, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_WRITE_PTR_NULL, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISEMPTY, ret, EXIT); + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosQueueHead020(VOID) +{ + TEST_ADD_CASE("ItLosQueueHead020", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_021.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_021.c new file mode 100644 index 00000000..97ce20ef --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_021.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[8] = "UniDSP"; + CHAR buff2[8] = ""; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWriteHead((UINT32)-1, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_INVALID, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISEMPTY, ret, EXIT); + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosQueueHead021(VOID) +{ + TEST_ADD_CASE("ItLosQueueHead021", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_022.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_022.c new file mode 100644 index 00000000..d20fba71 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_022.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 index; + UINT32 queueID[LOSCFG_BASE_IPC_QUEUE_CONFIG + 1]; + CHAR buff1[8] = "UniDSP"; + CHAR buff2[8]; + + UINT32 exsitedQueue = QUEUE_EXISTED_NUM; + for (index = 0; index < LOSCFG_BASE_IPC_QUEUE_CONFIG - exsitedQueue; index++) { + ret = LOS_QueueCreate(NULL, 3, &queueID[index], 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + + ret = LOS_QueueWriteHead(queueID[index - 1], &buff1, sizeof(UINTPTR), 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(queueID[index - 1], &buff2, sizeof(UINTPTR), 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + +EXIT: + for (index = 0; index < LOSCFG_BASE_IPC_QUEUE_CONFIG - exsitedQueue; index++) { + ret = LOS_QueueDelete(queueID[index]); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + return LOS_OK; +} + +VOID ItLosQueueHead022(VOID) +{ + TEST_ADD_CASE("ItLosQueueHead022", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_023.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_023.c new file mode 100644 index 00000000..95b4adc5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_023.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[8] = "UniDSP"; + CHAR buff2[8] = ""; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWriteHead(LOSCFG_BASE_IPC_QUEUE_CONFIG, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_INVALID, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISEMPTY, ret, EXIT); + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosQueueHead023(VOID) +{ + TEST_ADD_CASE("ItLosQueueHead023", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_024.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_024.c new file mode 100644 index 00000000..8e52071b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_024.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[8] = "UniDSP"; + CHAR buff2[8] = "DOPRA"; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, 8); // 3, Set the queue length; 8, Set the node size of the queue. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueCreate("Q2", 3, &g_testQueueID02, 0, 8); // 3, Set the queue length; 8, Set the node size of the queue. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWriteHead(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWriteHead(g_testQueueID02, &buff2, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_QueueDelete(g_testQueueID02); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosQueueHead024(VOID) +{ + TEST_ADD_CASE("ItLosQueueHead024", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_025.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_025.c new file mode 100644 index 00000000..9004ae9d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_025.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 index; + UINT32 queueID[LOSCFG_BASE_IPC_QUEUE_CONFIG + 1]; + CHAR buff1[8] = "UniDSP"; + + UINT32 exsitedQueue = QUEUE_EXISTED_NUM; + for (index = 0; index < LOSCFG_BASE_IPC_QUEUE_CONFIG - exsitedQueue; index++) { + ret = LOS_QueueCreate(NULL, 3, &queueID[index], 0, 8); // 3, Set the queue length; 8, Set the node size of the queue. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + + ret = LOS_QueueCreate("Q1", 3, &queueID[LOSCFG_BASE_IPC_QUEUE_CONFIG], 0, 8); // 3, Set the queue length; 8, Set the node size of the queue. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_CB_UNAVAILABLE, ret, EXIT); + + for (index = 0; index < LOSCFG_BASE_IPC_QUEUE_CONFIG - exsitedQueue; index++) { + ret = LOS_QueueWriteHead(queueID[index], &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + +EXIT: + for (index = 0; index < LOSCFG_BASE_IPC_QUEUE_CONFIG - exsitedQueue; index++) { + ret = LOS_QueueDelete(queueID[index]); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + return LOS_OK; +} + +VOID ItLosQueueHead025(VOID) +{ + TEST_ADD_CASE("ItLosQueueHead025", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_026.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_026.c new file mode 100644 index 00000000..77f53031 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_026.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 index; + CHAR buff1[8] = "UniDSP"; + CHAR buff2[8] = ""; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWriteHead(g_testQueueID01, &buff1, sizeof(UINTPTR), 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + for (index = 0; index < 3; index++) { // 3, The loop frequency. + ret = LOS_QueueWriteHead(g_testQueueID01, &buff1, sizeof(UINTPTR), 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosQueueHead026(VOID) +{ + TEST_ADD_CASE("ItLosQueueHead026", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_027.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_027.c new file mode 100644 index 00000000..363168b5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_027.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 index; + CHAR buff1[8] = "UniDSP"; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, 8); // 3, Set the queue length; 8, Set the node size of the queue. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + for (index = 0; index < 3; index++) { // 3, The loop frequency. + ret = LOS_QueueWriteHead(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + + ret = LOS_QueueWriteHead(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISFULL, ret, EXIT); + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosQueueHead027(VOID) +{ + TEST_ADD_CASE("ItLosQueueHead027", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_028.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_028.c new file mode 100644 index 00000000..a21b8cc9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_028.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 index; + CHAR buff1[8] = "UniDSP"; + CHAR buff2[8] = "DOPRA"; + CHAR buff3[8] = "TEST"; + UINTPTR buff4; + UINTPTR buff5; + UINTPTR buff6; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWriteHead(g_testQueueID01, buff1, sizeof(UINTPTR), 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWriteHead(g_testQueueID01, buff2, sizeof(UINTPTR), 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWriteHead(g_testQueueID01, &buff3, sizeof(UINTPTR), 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff4, sizeof(UINTPTR), 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff5, sizeof(UINTPTR), 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff6, sizeof(UINTPTR), 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + for (index = 0; index < 8; index++) { // 8, The loop frequency. + ICUNIT_GOTO_EQUAL(*((char *)buff4 + index), buff3[index], *((char *)buff4 + index), EXIT); + ICUNIT_GOTO_EQUAL(*((char *)buff5 + index), buff2[index], *((char *)buff5 + index), EXIT); + ICUNIT_GOTO_EQUAL(*((char *)buff6 + index), buff1[index], *((char *)buff6 + index), EXIT); + } + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosQueueHead028(VOID) +{ + TEST_ADD_CASE("ItLosQueueHead028", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_029.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_029.c new file mode 100644 index 00000000..146cd59e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_029.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 index; + CHAR buff1[8] = "UniDSP"; + CHAR buff2[8] = ""; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISEMPTY, ret, EXIT); + + for (index = 0; index < 3; index++) { // 3, The loop frequency. + ret = LOS_QueueWriteHead(g_testQueueID01, &buff1, sizeof(UINTPTR), 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + + for (index = 0; index < 3; index++) { // 3, The loop frequency. + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISEMPTY, ret, EXIT); + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosQueueHead029(VOID) +{ + TEST_ADD_CASE("ItLosQueueHead029", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_030.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_030.c new file mode 100644 index 00000000..b89289dd --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_030.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID ItQueueHead030F01(VOID) +{ + UINT32 ret; + CHAR buff2[8] = ""; + + g_testCount++; + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_NOT_CREATE, ret, EXIT); + + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[8] = "UniDSP"; + + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)ItQueueHead030F01; + task1.pcName = "TskName"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = 23; // 23, Set task priority. + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, 8); // 3, Set the queue length; 8, Set the node size of the queue. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_QueueWriteHead(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, Here, assert that g_testCount is equal to 2. + return LOS_OK; +} + +VOID ItLosQueueHead030(VOID) +{ + TEST_ADD_CASE("ItLosQueueHead030", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_031.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_031.c new file mode 100644 index 00000000..f8ad9446 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_031.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID ItQueueHead031F02(VOID) +{ + UINT32 ret; + CHAR buff2[8] = ""; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_AtomicInc(&g_testCount); + +EXIT: + LOS_TaskDelete(g_testTaskID02); +} +static VOID ItQueueHead031F01(VOID) +{ + UINT32 ret; + CHAR buff1[8] = "UniDSP"; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWriteHead(g_testQueueID01, &buff1, sizeof(UINTPTR), 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_AtomicInc(&g_testCount); + +EXIT: + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + + TSK_INIT_PARAM_S task1 = { 0 }; + TSK_INIT_PARAM_S task2 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)ItQueueHead031F01; + task1.pcName = "TskName1"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = 22; // 22, Set task priority. + + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, Here, assert that g_testCount is equal to 2. + LOS_AtomicInc(&g_testCount); + + task2.pfnTaskEntry = (TSK_ENTRY_FUNC)ItQueueHead031F02; + task2.pcName = "TskName2"; + task2.uwStackSize = TASK_STACK_SIZE_TEST; + task2.usTaskPrio = 23; // 23, Set task priority. + + ret = LOS_TaskCreate(&g_testTaskID02, &task2); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); // 5, Here, assert that g_testCount is equal to 5. + +EXIT: + LOS_QueueDelete(g_testQueueID01); + + return LOS_OK; +} + +VOID ItLosQueueHead031(VOID) +{ + TEST_ADD_CASE("ItLosQueueHead031", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_032.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_032.c new file mode 100644 index 00000000..99e13a69 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_032.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID ItQueueHead032F02(VOID) +{ + UINT32 ret; + CHAR buff2[8] = ""; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_AtomicInc(&g_testCount); + +EXIT: + LOS_TaskDelete(g_testTaskID02); +} +static VOID ItQueueHead032F01(VOID) +{ + UINT32 ret; + CHAR buff1[8] = "UniDSP"; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_QueueWriteHead(g_testQueueID01, &buff1, sizeof(UINTPTR), 100); // 100, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_AtomicInc(&g_testCount); + +EXIT: + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[8] = "UniDSP"; + + TSK_INIT_PARAM_S task1 = { 0 }; + TSK_INIT_PARAM_S task2 = { 0 }; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)ItQueueHead032F01; + task1.pcName = "TskName1"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = 22; // 22, Set task priority. + + task2.pfnTaskEntry = (TSK_ENTRY_FUNC)ItQueueHead032F02; + task2.pcName = "TskName2"; + task2.uwStackSize = TASK_STACK_SIZE_TEST; + task2.usTaskPrio = 21; // 21, Set task priority. + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, sizeof(UINTPTR)); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWriteHead(g_testQueueID01, &buff1, sizeof(UINTPTR), 100); // 100, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + TestExtraTaskDelay(TEST_TASKDELAY_10TICK); + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + g_testCount++; + + ret = LOS_TaskCreate(&g_testTaskID02, &task2); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + TestExtraTaskDelay(TEST_TASKDELAY_10TICK); + + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); // 5, Here, assert that g_testCount is equal to 5. + +EXIT: + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItLosQueueHead032(VOID) +{ + TEST_ADD_CASE("ItLosQueueHead032", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_038.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_038.c new file mode 100644 index 00000000..38692d9d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_038.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[8] = "abc"; + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, sizeof(UINTPTR)); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_TaskLock(); + + ret = LOS_QueueRead(g_testQueueID01, buff1, sizeof(UINTPTR), 0xff); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_PEND_IN_LOCK, ret, EXIT); + + ret = LOS_QueueWriteHead(g_testQueueID01, buff1, sizeof(UINTPTR), 0xff); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWriteHead(g_testQueueID01, buff1, sizeof(UINTPTR), 0xff); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_PEND_IN_LOCK, ret, EXIT); + LOS_TaskUnlock(); + +EXIT: + LOS_QueueDelete(g_testQueueID01); + + return LOS_OK; +} + +VOID ItLosQueueHead038(VOID) +{ + TEST_ADD_CASE("ItLosQueueHead038", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_039.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_039.c new file mode 100644 index 00000000..747f44ec --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_039.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[8] = "UniDSP"; + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, sizeof(UINTPTR)); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, buff1, sizeof(UINTPTR), 0xf); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_TIMEOUT, ret, EXIT); + + ret = LOS_QueueWriteHead(g_testQueueID01, buff1, sizeof(UINTPTR), 0xf); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWriteHead(g_testQueueID01, buff1, sizeof(UINTPTR), 0xf); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_TIMEOUT, ret, EXIT); + +EXIT: + LOS_QueueDelete(g_testQueueID01); + + return LOS_OK; +} + +VOID ItLosQueueHead039(VOID) +{ + TEST_ADD_CASE("ItLosQueueHead039", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_040.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_040.c new file mode 100644 index 00000000..615b765d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_040.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID ItQueueHead040F01(VOID) +{ + UINT32 ret; + CHAR buff2[8] = ""; + + g_testCount++; + + ret = LOS_QueueRead(g_testQueueID01, &buff2, sizeof(UINTPTR), 0xf); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + g_testCount++; + + ret = LOS_QueueWriteHead(g_testQueueID01, buff2, sizeof(UINTPTR), 0xf); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWriteHead(g_testQueueID01, buff2, sizeof(UINTPTR), 0xf); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[8] = "fgh"; + TSK_INIT_PARAM_S task1 = { 0 }; + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)ItQueueHead040F01; + task1.pcName = "TskName53"; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.usTaskPrio = 23; // 23, Set task priority. + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, sizeof(UINTPTR)); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(LOSCFG_BASE_IPC_QUEUE_CONFIG + 1); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_NOT_FOUND, ret, EXIT); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_IN_TSKUSE, ret, EXIT); + + ret = LOS_QueueWriteHead(g_testQueueID01, buff1, sizeof(UINTPTR), 0xf); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_IN_TSKUSE, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, buff1, sizeof(UINTPTR), 0xf); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, Here, assert that g_testCount is equal to 3. + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_NOT_CREATE, ret, EXIT); + +EXIT: + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItLosQueueHead040(VOID) +{ + TEST_ADD_CASE("ItLosQueueHead040", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_041.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_041.c new file mode 100644 index 00000000..511c7c6d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_041.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 index; + CHAR buff1[8] = "UniDSP"; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, 8); // 3, Set the queue length; 8, Set the node size of the queue. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWriteHead(g_testQueueID01, NULL, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_WRITE_PTR_NULL, ret, EXIT); + + for (index = 0; index < 3; index++) { // 3, The loop frequency. + ret = LOS_QueueWriteHead(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + +EXIT: + LOS_QueueDelete(g_testQueueID01); + + return LOS_OK; +} + +VOID ItLosQueueHead041(VOID) +{ + TEST_ADD_CASE("ItLosQueueHead041", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_042.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_042.c new file mode 100644 index 00000000..246ef588 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/full/It_los_queue_head_042.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 index; + + CHAR buff1[8] = "UniDSP"; + CHAR buff2[8] = "DOPRA"; + CHAR buff3[8] = "TEST"; + UINTPTR buff4; + UINTPTR buff5; + UINTPTR buff6; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWriteHead(g_testQueueID01, &buff1, sizeof(UINTPTR), 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWriteHead(g_testQueueID01, &buff2, sizeof(UINTPTR), 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWriteHead(g_testQueueID01, &buff3, sizeof(UINTPTR), 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, NULL, sizeof(UINTPTR), 0); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_READ_PTR_NULL, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff4, sizeof(UINTPTR), 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff5, sizeof(UINTPTR), 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff6, sizeof(UINTPTR), 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + for (index = 0; index < 8; index++) { // 8, The loop frequency. + ICUNIT_GOTO_EQUAL(*((char *)buff4 + index), buff3[index], *((char *)buff4 + index), EXIT); + ICUNIT_GOTO_EQUAL(*((char *)buff5 + index), buff2[index], *((char *)buff5 + index), EXIT); + ICUNIT_GOTO_EQUAL(*((char *)buff6 + index), buff1[index], *((char *)buff6 + index), EXIT); + } + +EXIT: + LOS_QueueDelete(g_testQueueID01); + + return LOS_OK; +} + +VOID ItLosQueueHead042(VOID) +{ + TEST_ADD_CASE("ItLosQueueHead042", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smoke/It_los_queue_001.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smoke/It_los_queue_001.c new file mode 100644 index 00000000..fd068ae0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smoke/It_los_queue_001.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + + ret = LOS_QueueCreate("Q1", 3, &g_testQueueID01, 0, 8); // 3, Set the queue length; 8, Set the node size of the queue. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueRead(g_testQueueID01, &buff2, 8, 0); // 8, Read the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItLosQueue001(VOID) +{ + TEST_ADD_CASE("ItLosQueue001", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smoke/It_los_queue_097.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smoke/It_los_queue_097.c new file mode 100644 index 00000000..609d8ab5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smoke/It_los_queue_097.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 queueID; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + QUEUE_INFO_S queueInfo; + + ret = LOS_QueueCreate("Q1", 3, &queueID, 0, 8); // 3, Set the queue length; 8, Set the node size of the queue. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(queueID, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueInfoGet(queueID, &queueInfo); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ICUNIT_GOTO_EQUAL(queueInfo.usQueueLen, 3, queueInfo.usQueueLen, EXIT); // 3, Here, assert the usQueueLen. + ICUNIT_GOTO_EQUAL(queueInfo.uwQueueID, queueID, queueInfo.uwQueueID, EXIT); + + ret = LOS_QueueDelete(queueID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_QueueInfoGet(queueID, &queueInfo); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_NOT_CREATE, ret, EXIT); + + ret = LOS_QueueDelete(queueID); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_QUEUE_NOT_CREATE, ret); + + return LOS_OK; + +EXIT: + LOS_QueueDelete(queueID); + return LOS_OK; +} + +VOID ItLosQueue097(VOID) +{ + TEST_ADD_CASE("ItLosQueue097", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smoke/It_los_queue_100.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smoke/It_los_queue_100.c new file mode 100644 index 00000000..5820be16 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smoke/It_los_queue_100.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 queueID; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "123"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + UINT32 readSize; + + ret = LOS_QueueCreate("Q1", 3, &queueID, 0, sizeof(UINTPTR)); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(queueID, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = memset_s(buff2, QUEUE_SHORT_BUFFER_LENGTH, 0, QUEUE_SHORT_BUFFER_LENGTH); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + readSize = sizeof(buff1); + ret = LOS_QueueReadCopy(queueID, &buff2, &readSize, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(queueID, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = memset_s(buff2, QUEUE_SHORT_BUFFER_LENGTH, 0, QUEUE_SHORT_BUFFER_LENGTH); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + readSize = sizeof(buff1) + 1; + ret = LOS_QueueReadCopy(queueID, &buff2, &readSize, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(queueID, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = memset_s(buff2, QUEUE_SHORT_BUFFER_LENGTH, 0, QUEUE_SHORT_BUFFER_LENGTH); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + readSize = sizeof(buff1); + ret = LOS_QueueReadCopy(queueID, &buff2, &readSize, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(queueID, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = memset_s(buff2, QUEUE_SHORT_BUFFER_LENGTH, 0, QUEUE_SHORT_BUFFER_LENGTH); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + readSize = 0; + ret = LOS_QueueReadCopy(queueID, &buff2, &readSize, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_READSIZE_IS_INVALID, ret, EXIT); + + ret = LOS_QueueDelete(queueID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return LOS_OK; + +EXIT: + LOS_QueueDelete(queueID); + return LOS_OK; +} + +VOID ItLosQueue100(VOID) +{ + TEST_ADD_CASE("ItLosQueue100", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smoke/It_los_queue_105.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smoke/It_los_queue_105.c new file mode 100644 index 00000000..9f93ff78 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smoke/It_los_queue_105.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 queueID; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "abc"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + QUEUE_INFO_S queueInfo; + UINT32 readSize; + + ret = LOS_QueueCreate("Q1", 3, &queueID, 0, QUEUE_SHORT_BUFFER_LENGTH); // 3, Set the queue length. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWriteCopy(queueID, &buff1, QUEUE_SHORT_BUFFER_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = memset_s(buff2, QUEUE_SHORT_BUFFER_LENGTH, 0, QUEUE_SHORT_BUFFER_LENGTH); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ret = LOS_QueueRead(queueID, &buff2, QUEUE_SHORT_BUFFER_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWriteCopy(queueID, &buff1, QUEUE_SHORT_BUFFER_LENGTH + PER_ADDED_VALUE, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_WRITE_SIZE_TOO_BIG, ret, EXIT); + + ret = memset_s(buff2, QUEUE_SHORT_BUFFER_LENGTH, 0, QUEUE_SHORT_BUFFER_LENGTH); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ret = LOS_QueueRead(queueID, &buff2, QUEUE_SHORT_BUFFER_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISEMPTY, ret, EXIT); + + ret = LOS_QueueWrite(queueID, &buff1, QUEUE_SHORT_BUFFER_LENGTH - 1, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = memset_s(buff2, QUEUE_SHORT_BUFFER_LENGTH, 0, QUEUE_SHORT_BUFFER_LENGTH); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ret = LOS_QueueRead(queueID, &buff2, QUEUE_SHORT_BUFFER_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = memset_s(buff2, QUEUE_SHORT_BUFFER_LENGTH, 0, QUEUE_SHORT_BUFFER_LENGTH); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ret = LOS_QueueRead(queueID, &buff2, QUEUE_SHORT_BUFFER_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISEMPTY, ret, EXIT); + + ret = LOS_QueueWrite(queueID, &buff1, 0, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = memset_s(buff2, QUEUE_SHORT_BUFFER_LENGTH, 0, QUEUE_SHORT_BUFFER_LENGTH); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + readSize = 0; + ret = LOS_QueueReadCopy(queueID, &buff2, &readSize, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_READSIZE_IS_INVALID, ret, EXIT); + + ret = LOS_QueueDelete(queueID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return LOS_OK; + +EXIT: + LOS_QueueDelete(queueID); + return LOS_OK; +} + +VOID ItLosQueue105(VOID) +{ + TEST_ADD_CASE("ItLosQueue105", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smoke/It_los_queue_head_002.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smoke/It_los_queue_head_002.c new file mode 100644 index 00000000..07d331ff --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smoke/It_los_queue_head_002.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + CHAR buff1[8] = "A"; + CHAR buff2[8] = "B"; + CHAR buff3[8] = "C"; + + ret = LOS_QueueCreate("Q1", 2, &g_testQueueID01, 0, 8); // 2, Set the queue length; 8, Set the node size of the queue. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &buff2, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_QueueWriteHead(g_testQueueID01, &buff3, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_ISFULL, ret, EXIT); + +EXIT: + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosQueueHead002(VOID) +{ + TEST_ADD_CASE("ItLosQueueHead002", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_001.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_001.c new file mode 100644 index 00000000..dfa7e9c0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_001.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, 8); // 8, Set the maximum data length of the message queue. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_001_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItSmpLosQueue001(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosQueue001", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_002.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_002.c new file mode 100644 index 00000000..8273d04f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_002.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, 8); // 8, Set the maximum data length of the message queue. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_001_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count. + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItSmpLosQueue002(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosQueue002", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_003.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_003.c new file mode 100644 index 00000000..79006c92 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_003.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static VOID HwiF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + CHAR buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; + CHAR buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, 8); // 8, Set the maximum data length of the message queue. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + + TestHwiTrigger(HWI_NUM_TEST); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count. + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + +EXIT: + LOS_HwiDelete(HWI_NUM_TEST, NULL); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItSmpLosQueue003(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosQueue003", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_004.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_004.c new file mode 100644 index 00000000..80c8f4f1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_004.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static CHAR g_buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; +static CHAR g_buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + + ret = LOS_QueueRead(g_testQueueID01, &g_buff2, 8, LOS_WAIT_FOREVER); // 8, Read the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, 8); // 8, Set the maximum data length of the message queue. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_001_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_QUEUE_IN_TSKUSE, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosQueue004(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosQueue004", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_005.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_005.c new file mode 100644 index 00000000..0b87c5a4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_005.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static CHAR g_buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; +static CHAR g_buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + + ret = LOS_QueueRead(g_testQueueID01, &g_buff2, 8, LOS_WAIT_FOREVER); // 8, Read the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static VOID TaskF02(VOID) +{ + UINT32 ret; + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_QUEUE_IN_TSKUSE, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, 8); // 8, Set the maximum data length of the message queue. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_005_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_005_task2", TaskF02, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count. + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + LOS_TaskDelete(g_testTaskID02); + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosQueue005(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosQueue005", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_006.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_006.c new file mode 100644 index 00000000..f6e01b5a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_006.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static CHAR g_buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; +static CHAR g_buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + + ret = LOS_QueueRead(g_testQueueID01, &g_buff2, 8, LOS_WAIT_FOREVER); // 8, Read the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, 8); // 8, Set the maximum data length of the message queue. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_006_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 1); // 100, Set the timeout of runtime; + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + TestBusyTaskDelay(2); // 2, Set the timeout of runtime; + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_PEND, 0, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_QUEUE_IN_TSKUSE, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + LOS_TaskDelay(10); // 10, set delay time. + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_UNUSED, 0, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosQueue006(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosQueue006", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_007.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_007.c new file mode 100644 index 00000000..9c0a1be4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_007.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static CHAR g_buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; +static CHAR g_buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + + ret = LOS_QueueRead(g_testQueueID01, &g_buff2, 8, LOS_WAIT_FOREVER); // 8, Read the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static VOID TaskF02(VOID) +{ + UINT32 ret; + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_QUEUE_IN_TSKUSE, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, 8); // 8, Set the maximum data length of the message queue. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + // 2, set new task priority, it is higher than the current task. + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_007_task1", TaskF01, TASK_PRIO_TEST - 2, + CPUID_TO_AFFI_MASK(currCpuid)); + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_007_task2", TaskF02, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count. + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + LOS_TaskDelete(g_testTaskID02); + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosQueue007(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosQueue007", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_008.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_008.c new file mode 100644 index 00000000..e896122c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_008.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static CHAR g_buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; +static CHAR g_buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; +static VOID HwiF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + + ret = LOS_QueueRead(g_testQueueID01, &g_buff2, 8, LOS_WAIT_FOREVER); // 8, Read the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_QUEUE_READ_IN_INTERRUPT, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, 8); // 8, Set the maximum data length of the message queue. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + + TestHwiTrigger(HWI_NUM_TEST); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count. + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + +EXIT: + LOS_HwiDelete(HWI_NUM_TEST, NULL); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItSmpLosQueue008(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosQueue008", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_009.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_009.c new file mode 100644 index 00000000..252206a8 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_009.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static CHAR g_buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; +static CHAR g_buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + + ret = LOS_QueueRead(g_testQueueID01, &g_buff2, 8, LOS_WAIT_FOREVER); // 8, Read the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static VOID HwiF01(VOID) +{ + UINT32 ret; + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_QUEUE_IN_TSKUSE, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, 8); // 8, Set the maximum data length of the message queue. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_009_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 1); // 100, Set the timeout of runtime; + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + LOS_TaskDelay(1); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_PEND, 0, ret, EXIT); + + TestHwiTrigger(HWI_NUM_TEST); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count. + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); + +EXIT: + ret = LOS_HwiDelete(HWI_NUM_TEST, NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + LOS_TaskDelay(10); // 10, set delay time. + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_UNUSED, 0, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosQueue009(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosQueue009", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_010.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_010.c new file mode 100644 index 00000000..e83d3048 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_010.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static CHAR g_buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; +static CHAR g_buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + ret = LOS_QueueRead(g_testQueueID01, &g_buff2, 8, LOS_WAIT_FOREVER); // 8, Read the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static VOID TaskF02(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + + ret = LOS_QueueWrite(g_testQueueID01, &g_buff1, 8, 0); // 8, Write the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, 8); // 8, Set the maximum data length of the message queue. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + // 2, set new task priority, it is higher than the current task. + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_010_task1", TaskF01, TASK_PRIO_TEST - 2, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_010_task2", TaskF02, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, Here, assert that g_testCount is equal to 3. + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItSmpLosQueue010(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosQueue010", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_011.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_011.c new file mode 100644 index 00000000..1df85c1e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_011.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static CHAR g_buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; +static CHAR g_buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; +static VOID TaskF02(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + + ret = LOS_QueueWrite(g_testQueueID01, &g_buff1, 8, LOS_WAIT_FOREVER); // 8, Write the setting size of queue buffer.; + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + ret = LOS_QueueRead(g_testQueueID01, &g_buff2, 8, LOS_WAIT_FOREVER); // 8, Read the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, 8); // 8, Set the maximum data length of the message queue. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_011_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_011_task2", TaskF02, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 3); // 100, Set the timeout of runtime; 3, test running count. + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, Here, assert that g_testCount is equal to 3. + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItSmpLosQueue011(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosQueue011", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_012.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_012.c new file mode 100644 index 00000000..1be46ee1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_012.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static CHAR g_buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; +static CHAR g_buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + + ret = LOS_QueueRead(g_testQueueID01, &g_buff2, 8, LOS_WAIT_FOREVER); // 8, Read the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static VOID HwiF01(VOID) +{ + UINT32 ret; + ret = LOS_QueueWrite(g_testQueueID01, &g_buff1, 8, LOS_NO_WAIT); // 8, Write the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, 8); // 8, Set the maximum data length of the message queue. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_009_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + TestHwiTrigger(HWI_NUM_TEST); + + TestAssertBusyTaskDelay(100, 3); // 100, Set the timeout of runtime; 3, test running count. + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, Here, assert that g_testCount is equal to 3. + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + ret = LOS_HwiDelete(HWI_NUM_TEST, NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItSmpLosQueue012(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosQueue012", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_013.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_013.c new file mode 100644 index 00000000..a3d1098a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_013.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static CHAR g_buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; +static CHAR g_buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + ret = LOS_QueueRead(g_testQueueID01, &g_buff2, 8, LOS_WAIT_FOREVER); // 8, Read the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static VOID TaskF02(VOID) +{ + UINT32 ret; + + do { + __asm__ volatile("nop"); + } while (g_testCount != 2); // 2, Here, judgment that g_testCount is not equal to 2. + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, 8); // 8, Set the maximum data length of the message queue. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_013_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_013_task2", TaskF02, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_QueueWrite(g_testQueueID01, &g_buff1, 8, LOS_WAIT_FOREVER); // 8, Write the setting size of queue buffer.; + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 3); // 100, Set the timeout of runtime; 3, test running count. + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, Here, assert that g_testCount is equal to 3. + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItSmpLosQueue013(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosQueue013", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_014.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_014.c new file mode 100644 index 00000000..4a2c4dee --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_014.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static CHAR g_buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; +static CHAR g_buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; +static VOID TaskF02(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + + ret = LOS_QueueWrite(g_testQueueID01, &g_buff1, 8, LOS_WAIT_FOREVER); // 8, Write the setting size of queue buffer.; + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + do { + __asm__ volatile("nop"); + } while (g_testCount != 2); // 2, Here, judgment that g_testCount is not equal to 2. + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} +static VOID TaskF01(VOID) +{ + UINT32 ret; + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + + LOS_AtomicInc(&g_testCount); + ret = LOS_QueueRead(g_testQueueID01, &g_buff2, 8, LOS_WAIT_FOREVER); // 8, Read the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, 8); // 8, Set the maximum data length of the message queue. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_014_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_014_task2", TaskF02, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 3); // 100, Set the timeout of runtime; 3, test running count. + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, Here, assert that g_testCount is equal to 3. + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItSmpLosQueue014(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosQueue014", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_015.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_015.c new file mode 100644 index 00000000..7fbb85b1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_015.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static CHAR g_buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; +static CHAR g_buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + + ret = LOS_QueueRead(g_testQueueID01, &g_buff2, 8, LOS_WAIT_FOREVER); // 8, Read the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static VOID HwiF01(VOID) +{ + UINT32 ret; + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + ret = LOS_QueueWrite(g_testQueueID01, &g_buff1, 8, LOS_NO_WAIT); // 8, Write the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + do { + __asm__ volatile("nop"); + } while (g_testCount != 2); // 2, Here, judgment that g_testCount is not equal to 3. + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, 8); // 8, Set the maximum data length of the message queue. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_009_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + TestHwiTrigger(HWI_NUM_TEST); + + TestAssertBusyTaskDelay(100, 3); // 100, Set the timeout of runtime; 3, test running count. + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, Here, assert that g_testCount is equal to 3. + + +EXIT: + LOS_TaskDelete(g_testTaskID01); + ret = LOS_HwiDelete(HWI_NUM_TEST, NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItSmpLosQueue015(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosQueue015", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_016.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_016.c new file mode 100644 index 00000000..c605bd63 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_016.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static CHAR g_buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; +static CHAR g_buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + + ret = LOS_QueueWrite(g_testQueueID01, &g_buff1, 8, LOS_WAIT_FOREVER); // 8, Write the setting size of queue buffer.; + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, 8); // 8, Set the maximum data length of the message queue. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_016_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItSmpLosQueue016(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosQueue016", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_017.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_017.c new file mode 100644 index 00000000..80afc6f4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_017.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static CHAR g_buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; +static CHAR g_buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + ret = LOS_QueueWrite(g_testQueueID01, &g_buff1, 8, LOS_WAIT_FOREVER); // 8, Write the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, 8); // 8, Set the maximum data length of the message queue. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_017_task2", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 1); // 100, Set the timeout of runtime; + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItSmpLosQueue017(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosQueue017", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_018.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_018.c new file mode 100644 index 00000000..7603416a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_018.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static CHAR g_buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; +static CHAR g_buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + ret = LOS_QueueWrite(g_testQueueID01, &g_buff1, 8, LOS_WAIT_FOREVER); // 8, Write the setting size of queue buffer.; + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + LOS_AtomicInc(&g_testCount); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, 8); // 8, Set the maximum data length of the message queue. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_005_task2", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count. + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItSmpLosQueue018(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosQueue018", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_019.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_019.c new file mode 100644 index 00000000..b3add687 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_019.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static CHAR g_buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; +static CHAR g_buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; +static VOID HwiF01(VOID) +{ + UINT32 ret; + ret = LOS_QueueWrite(g_testQueueID01, &g_buff1, 8, LOS_NO_WAIT); // 8, Write the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, 8); // 8, Set the maximum data length of the message queue. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + + TestHwiTrigger(HWI_NUM_TEST); + + TestAssertBusyTaskDelay(100, 1); // 100, Set the timeout of runtime; + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + ret = LOS_HwiDelete(HWI_NUM_TEST, NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItSmpLosQueue019(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosQueue019", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_020.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_020.c new file mode 100644 index 00000000..9977ec45 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_020.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static CHAR g_buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; +static CHAR g_buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + + LOS_AtomicInc(&g_testCount); + + ret = LOS_QueueWrite(g_testQueueID01, &g_buff1, 8, LOS_WAIT_FOREVER); // 8, Write the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, 8); // 8, Set the maximum data length of the message queue. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_020_task2", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + + ret = LOS_QueueRead(g_testQueueID01, &g_buff2, 8, LOS_WAIT_FOREVER); // 8, Read the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItSmpLosQueue020(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosQueue020", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_021.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_021.c new file mode 100644 index 00000000..16df0c11 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_021.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static CHAR g_buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; +static CHAR g_buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + + ret = LOS_QueueRead(g_testQueueID01, &g_buff2, 8, LOS_WAIT_FOREVER); // 8, Read the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, 8); // 8, Set the maximum data length of the message queue. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LOS_QueueWrite(g_testQueueID01, &g_buff1, 8, LOS_WAIT_FOREVER); // 8, Write the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + LOS_AtomicInc(&g_testCount); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_021_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count. + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItSmpLosQueue021(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosQueue021", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_022.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_022.c new file mode 100644 index 00000000..d956d06e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_022.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static CHAR g_buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; +static CHAR g_buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + ret = LOS_QueueWrite(g_testQueueID01, &g_buff1, 8, LOS_WAIT_FOREVER); // 8, Write the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static VOID HwiF01(VOID) +{ + UINT32 ret; + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + ret = LOS_QueueRead(g_testQueueID01, &g_buff2, 8, LOS_WAIT_FOREVER); // 8, Read the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_QUEUE_READ_IN_INTERRUPT, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, 8); // 8, Set the maximum data length of the message queue. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_009_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + TestHwiTrigger(HWI_NUM_TEST); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count. + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + ret = LOS_HwiDelete(HWI_NUM_TEST, NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItSmpLosQueue022(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosQueue022", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_023.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_023.c new file mode 100644 index 00000000..84fe4693 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_023.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static CHAR g_buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; +static CHAR g_buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + + ret = LOS_QueueRead(g_testQueueID01, &g_buff2, 8, LOS_WAIT_FOREVER); // 8, Read the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static VOID TaskF02(VOID) +{ + UINT32 ret; + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, 8); // 8, Set the maximum data length of the message queue. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_QueueWrite(g_testQueueID01, &g_buff1, 8, LOS_WAIT_FOREVER); // 8, Write the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_023_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_023_task", TaskF02, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // othercpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count. + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItSmpLosQueue023(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosQueue023", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_024.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_024.c new file mode 100644 index 00000000..8c012384 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_024.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static CHAR g_buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; +static CHAR g_buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; +static VOID TaskF02(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + + ret = LOS_QueueRead(g_testQueueID01, &g_buff2, 8, LOS_WAIT_FOREVER); // 8, Read the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ret = LOS_QueueWrite(g_testQueueID01, &g_buff1, 8, LOS_WAIT_FOREVER); // 8, Write the setting size of queue buffer.; + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + LOS_AtomicInc(&g_testCount); + return; +} +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, 8); // 8, Set the maximum data length of the message queue. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_014_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_014_task2", TaskF02, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count. + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItSmpLosQueue024(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosQueue024", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_025.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_025.c new file mode 100644 index 00000000..61b11d7a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_025.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static CHAR g_buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; +static CHAR g_buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + + ret = LOS_QueueWrite(g_testQueueID01, &g_buff1, 8, LOS_WAIT_FOREVER); // 8, Write the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static VOID HwiF01(VOID) +{ + UINT32 ret; + + ret = LOS_QueueRead(g_testQueueID01, &g_buff2, 8, LOS_WAIT_FOREVER); // 8, Read the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_QUEUE_READ_IN_INTERRUPT, ret); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, 8); // 8, Set the maximum data length of the message queue. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_009_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + TestHwiTrigger(HWI_NUM_TEST); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count. + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. +EXIT: + LOS_TaskDelete(g_testTaskID01); + ret = LOS_HwiDelete(HWI_NUM_TEST, NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItSmpLosQueue025(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosQueue025", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_026.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_026.c new file mode 100644 index 00000000..a61301cc --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_026.c @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static CHAR g_buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; +static CHAR g_buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; +static VOID TaskF01(VOID) +{ + UINT32 ret; + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + + LOS_AtomicInc(&g_testCount); + ret = LOS_QueueRead(g_testQueueID01, &g_buff2, 8, LOS_WAIT_FOREVER); // 8, Read the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 4, g_testCount); // 4, Here, assert that g_testCount is equal to 4. + + LOS_AtomicInc(&g_testCount); + + TestDumpCpuid(); + return; +} + +static VOID TaskF02(VOID) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + ret = LOS_QueueRead(g_testQueueID01, &g_buff2, 8, LOS_WAIT_FOREVER); // 8, Read the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, Here, assert that g_testCount is equal to 2. + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid, i, uvIntSave; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, 8); // 8, Set the maximum data length of the message queue. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_sem_033_task2", TaskF02, TASK_PRIO_TEST - 1, CPUID_TO_AFFI_MASK(currCpuid)); + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 1); // 100, Set the timeout of runtime; + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + TestBusyTaskDelay(10); // 10, Set the timeout of runtime; let the task f02 todo pend + + ret = OS_TCB_FROM_TID(g_testTaskID02)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_PEND, 0, ret, EXIT); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_sem_033_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + + LOS_TaskLock(); + + ret = LOS_QueueWrite(g_testQueueID01, &g_buff1, 8, LOS_WAIT_FOREVER); // 8, Write the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 3); // 100, Set the timeout of runtime; 3, test running count. + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT1); // 3, Here, assert that g_testCount is equal to 3. + + ret = LOS_QueueWrite(g_testQueueID01, &g_buff1, 8, LOS_WAIT_FOREVER); // 8, Write the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT1); // 3, Here, assert that g_testCount is equal to 3. + + LOS_AtomicInc(&g_testCount); + + LOS_TaskUnlock(); + + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); // 5, Here, assert that g_testCount is equal to 5. + +EXIT: + + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +EXIT1: + LOS_TaskUnlock(); + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosQueue026(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosQueue026", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_027.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_027.c new file mode 100644 index 00000000..5f5537d5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_027.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static CHAR g_buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; +static CHAR g_buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; +static volatile UINT32 g_runFlag = 1; +static VOID TaskF01(VOID) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + PRINT_DEBUG("task f01 pend begin\n"); + ret = LOS_QueueRead(g_testQueueID01, &g_buff2, 8, LOS_WAIT_FOREVER); // 8, Read the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + PRINT_DEBUG("task f01 pend success\n"); + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 3, g_testCount); // 3, Here, assert that g_testCount is equal to 3. + LOS_AtomicInc(&g_testCount); + + TestDumpCpuid(); + return; +} + +static VOID TaskF02(VOID) +{ + UINT32 ret, uvIntSave; + + PRINT_DEBUG("task f02 lock\n"); + + LOS_TaskLock(); // task lock on other cpu + LOS_AtomicInc(&g_testCount); + + do { + __asm__ volatile("nop"); + } while (g_runFlag == 1); + + PRINT_DEBUG("task f02 unlock\n"); + LOS_TaskUnlock(); // schedule occur ---switch to task f01 + + PRINT_DEBUG("task f02 back\n"); + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 4, g_testCount); // 4, Here, assert that g_testCount is equal to 4. + + TestDumpCpuid(); + return; +} + + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid, i; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + g_runFlag = 1; + + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, 8); // 8, Set the maximum data length of the message queue. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_sem_034_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_sem_034_task2", TaskF02, TASK_PRIO_TEST, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count. + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + + /* wait for task01 to pend sem */ + TestBusyTaskDelay(2); // 2, Set the timeout of runtime; + + ret = OS_TCB_FROM_TID(g_testTaskID02)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_PEND, 0, ret, EXIT); // pend + + PRINT_DEBUG("sem post\n"); + ret = LOS_QueueWrite(g_testQueueID01, &g_buff1, 8, LOS_WAIT_FOREVER); // 8, Write the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(10); // 10, set delay time. + + ret = OS_TCB_FROM_TID(g_testTaskID02)->taskStatus; + ICUNIT_GOTO_EQUAL(ret & OS_TASK_STATUS_PEND, 0, ret, EXIT); // not pend + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + + LOS_AtomicInc(&g_testCount); + + PRINT_DEBUG("try to unlock\n"); + + g_runFlag = 0; // unlock the other cpu + + PRINT_DEBUG("finally\n"); + TestAssertBusyTaskDelay(100, 4); // 100, Set the timeout of runtime; 4, test running count. + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, Here, assert that g_testCount is equal to 4. + +EXIT: + + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosQueue027(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosQueue027", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_029.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_029.c new file mode 100644 index 00000000..a0ffc54f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_029.c @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static CHAR g_buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; +static CHAR g_buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; +static VOID TaskF01(VOID) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_QueueRead(g_testQueueID01, &g_buff2, 8, LOS_WAIT_FOREVER); // 8, Read the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + + TestDumpCpuid(); + return; +} +static VOID TaskF02(VOID) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_QueueRead(g_testQueueID01, &g_buff2, 8, LOS_WAIT_FOREVER); // 8, Read the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, 8); // 8, Set the maximum data length of the message queue. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_queue_029_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_queue_029_task2", TaskF02, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count. + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to 2. + + /* wait for task01 to pend sem */ + TestBusyTaskDelay(2); // 2, Set the timeout of runtime; + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_PEND, 0, ret, EXIT); + + ret = OS_TCB_FROM_TID(g_testTaskID02)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_PEND, 0, ret, EXIT); + + ret = LOS_QueueWrite(g_testQueueID01, &g_buff1, 8, LOS_WAIT_FOREVER); // 8, Write the setting size of queue buffer. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 3); // 100, Set the timeout of runtime; 3, test running count. + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, Here, assert that g_testCount is equal to 3. + +EXIT: + LOS_TaskDelete(g_testTaskID02); + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelay(1); // cross delete task need time + + ret = OS_TCB_FROM_TID(g_testTaskID02)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_UNUSED, 0, ret, EXIT); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_UNUSED, 0, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosQueue029(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosQueue029", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_031.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_031.c new file mode 100644 index 00000000..c0188a5b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_031.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static CHAR g_buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; +static CHAR g_buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; +static UINT32 g_ret = 0xff; +static VOID TaskF01(VOID) +{ + UINT32 ret, i; + LOS_AtomicInc(&g_testCount); + + for (i = 0; i < TRandom() % 500; i++); // 500, Set this loop to not more than 500 cpu cycles. + + ret = LOS_QueueRead(g_testQueueID01, &g_buff2, 8, LOS_WAIT_FOREVER); // 8, Read the setting size of queue buffer. + g_ret = ret; + + LOS_AtomicInc(&g_testCount); + + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid, i, j; + TSK_INIT_PARAM_S testTask; + LosTaskCB *cb = NULL; + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + for (i = 0; i < LOOP; i++) { + g_testCount = 0; + g_ret = 0xff; + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, 8); // 8, Set the maximum data length of the message queue. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_queue_031_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 1); // 100, Set the timeout of runtime; wait for task f01 run + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + for (j = 0; j < TRandom() % 500; j++); // 500, Set this loop to not more than 500 cpu cycles. + + ret = LOS_QueueDelete(g_testQueueID01); // delete queue in current cpu + if ((g_ret == LOS_ERRNO_QUEUE_NOT_CREATE) && (ret == LOS_OK)) { + } else if ((g_ret == 0xff) && (ret == LOS_OK)) { + } else if ((g_ret == 0xff) && (ret == LOS_ERRNO_QUEUE_IN_TSKUSE)) { + } else { + ICUNIT_GOTO_EQUAL(1, 0, g_ret, EXIT); // report error + } + + /* clear enviorment */ + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelay(10); // 10, set delay time. + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_UNUSED, 0, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + PRINT_DEBUG("finally delRet = 0x%x\n", ret); + } +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItSmpLosQueue031(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosQueue031", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_032.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_032.c new file mode 100644 index 00000000..4bc2ae1e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/queue/smp/It_smp_los_queue_032.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_queue.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static CHAR g_buff1[QUEUE_SHORT_BUFFER_LENGTH] = "UniDSP"; +static CHAR g_buff2[QUEUE_SHORT_BUFFER_LENGTH] = ""; +static UINT32 g_ret = 0xff; +static VOID TaskF02(VOID) +{ + UINT32 ret, i; + LOS_AtomicInc(&g_testCount); + + for (i = 0; i < TRandom() % 500; i++); // 500, Set this loop to not more than 500 cpu cycles. + + ret = LOS_QueueWrite(g_testQueueID01, &g_buff1, 8, LOS_WAIT_FOREVER); // 8, Write the setting size of queue buffer. + g_ret = ret; + + LOS_AtomicInc(&g_testCount); + + TestDumpCpuid(); + return; +} +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid, i, j; + TSK_INIT_PARAM_S testTask; + LosTaskCB *cb = NULL; + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + for (i = 0; i < LOOP; i++) { + g_testCount = 0; + g_ret = 0xff; + ret = LOS_QueueCreate("Q1", 1, &g_testQueueID01, 0, 8); // 8, Set the maximum data length of the message queue. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_queue_032_task1", TaskF02, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + do { + __asm__ volatile("nop"); + } while (g_testCount == 0); // wait for task f01 run + for (j = 0; j < TRandom() % 500; j++); // 500, Set this loop to not more than 500 cpu cycles. + + ret = LOS_QueueDelete(g_testQueueID01); // delete queue in current cpu + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + if ((g_ret != LOS_OK) && (g_ret != LOS_ERRNO_QUEUE_NOT_CREATE) && (g_ret != 0xff)) { + ICUNIT_GOTO_EQUAL(1, 0, g_ret, EXIT); + } + + PRINT_DEBUG("writeRet = 0x%x, delRet = 0x%x\n", g_ret, ret); + + /* clear enviorment */ + + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelay(10); // 10, set delay time. + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_UNUSED, 0, ret, EXIT); + + ret = LOS_QueueDelete(g_testQueueID01); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_QUEUE_NOT_CREATE, ret, EXIT); + PRINT_DEBUG("finally delRet = 0x%x\n", ret); + } +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_QueueDelete(g_testQueueID01); + return LOS_OK; +} + +VOID ItSmpLosQueue032(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosQueue032", Testcase, TEST_LOS, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/It_los_sem.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/It_los_sem.c new file mode 100644 index 00000000..1c28e50c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/It_los_sem.c @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +VOID ItSuiteLosSem(void) +{ +#ifdef LOSCFG_KERNEL_SMP + /* fixed */ + ItSmpLosSem008(); + ItSmpLosSem022(); + ItSmpLosSem025(); + + ItSmpLosSem001(); + ItSmpLosSem002(); + ItSmpLosSem003(); + ItSmpLosSem004(); + ItSmpLosSem005(); + ItSmpLosSem006(); + ItSmpLosSem007(); + ItSmpLosSem009(); + ItSmpLosSem010(); + ItSmpLosSem011(); + ItSmpLosSem012(); + ItSmpLosSem013(); + ItSmpLosSem014(); + ItSmpLosSem015(); + ItSmpLosSem016(); + ItSmpLosSem017(); + ItSmpLosSem018(); + ItSmpLosSem019(); + ItSmpLosSem020(); + ItSmpLosSem021(); + ItSmpLosSem023(); + ItSmpLosSem024(); + ItSmpLosSem026(); + ItSmpLosSem027(); + ItSmpLosSem028(); + ItSmpLosSem029(); + ItSmpLosSem030(); + ItSmpLosSem031(); + ItSmpLosSem032(); + ItSmpLosSem033(); + ItSmpLosSem034(); + ItSmpLosSem035(); + ItSmpLosSem036(); +#endif + +#if defined(LOSCFG_TEST_SMOKE) + ItLosSem001(); + ItLosSem003(); + ItLosSem006(); +#endif + +#if defined(LOSCFG_TEST_FULL) + ItLosSem002(); + ItLosSem005(); + ItLosSem009(); + ItLosSem012(); + ItLosSem013(); + ItLosSem014(); + ItLosSem015(); + ItLosSem016(); + ItLosSem017(); + ItLosSem019(); + ItLosSem020(); + ItLosSem022(); + ItLosSem023(); + ItLosSem026(); + ItLosSem027(); + ItLosSem028(); + ItLosSem029(); + ItLosSem034(); +#endif + +#if defined(LOSCFG_TEST_PRESSURE) +#ifndef TESTHI1980IMU + ItLosSem035(); +#endif + ItLosSem036(); + ItLosSem037(); + ItLosSem038(); +#ifndef LOSCFG_KERNEL_SMP_TASK_SYNC + // LOSCFG_KERNEL_SMP_TASK_SYNC is opened ,create task success is depend on created semaphore succeeded; + ItLosSem039(); + ItLosSem040(); + ItLosSem041(); + ItLosSem043(); +#endif + ItLosSem042(); + ItLosSem044(); // ID will not be duplicate +#endif + +#if defined(LOSCFG_TEST_LLT) + ItLosSem004(); + ItLosSem007(); + ItLosSem008(); + ItLosSem010(); + ItLosSem011(); + ItLosSem024(); + ItLosSem030(); + ItLosSem032(); +#ifndef LOSCFG_KERNEL_SMP + ItLosSem033(); +#endif + LltLosSem001(); +#if defined(LOSCFG_SHELL) && defined(LOSCFG_DEBUG_SEMAPHORE) + ItLosSemDebug001(); +#endif +#endif +#if defined(LOSCFG_TEST_MANUAL_SHELL) || defined(LOSCFG_TEST_MANUAL_TEST) +#if defined(LOSCFG_DEBUG_SEMAPHORE) + ItLosSem045(); + ItLosSem046(); + ItLosSem047(); + ItLosSem048(); + ItLosSem049(); + ItLosSem050(); +#endif +#endif + +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, 1); +#endif +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/It_los_sem.h b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/It_los_sem.h new file mode 100644 index 00000000..62368917 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/It_los_sem.h @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _IT_LOS_SEM_H +#define _IT_LOS_SEM_H + +#include "osTest.h" +#include "los_sem_pri.h" +#include "los_task_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +extern volatile UINT64 g_tickCount[]; +extern VOID ItSuiteLosSem(void); +#define LOOP 100 + +#ifndef spin_lock +#define spin_lock(lock) \ + do { \ + LOS_TaskLock(); \ + } while (0) +#endif +#ifndef spin_unlock +#define spin_unlock(lock) \ + do { \ + LOS_TaskUnlock(); \ + } while (0) +#endif + +#if defined(LOSCFG_TEST_SMOKE) +VOID ItLosSem001(void); +VOID ItLosSem002(void); +VOID ItLosSem003(void); +#endif + +#if defined(LOSCFG_TEST_FULL) +VOID ItLosSem005(void); +VOID ItLosSem006(void); +VOID ItLosSem009(void); +VOID ItLosSem012(void); +VOID ItLosSem013(void); +VOID ItLosSem014(void); +VOID ItLosSem015(void); +VOID ItLosSem016(void); +VOID ItLosSem017(void); +VOID ItLosSem018(void); +VOID ItLosSem019(void); +VOID ItLosSem020(void); +VOID ItLosSem021(void); +VOID ItLosSem022(void); +VOID ItLosSem023(void); +VOID ItLosSem025(void); +VOID ItLosSem026(void); +VOID ItLosSem027(void); +VOID ItLosSem028(void); +VOID ItLosSem029(void); +VOID ItLosSem034(void); +#endif + +#if defined(LOSCFG_TEST_PRESSURE) +VOID ItLosSem035(void); +VOID ItLosSem036(void); +VOID ItLosSem037(void); +VOID ItLosSem038(void); +VOID ItLosSem039(void); +VOID ItLosSem040(void); +VOID ItLosSem041(void); +VOID ItLosSem042(void); +VOID ItLosSem043(void); +VOID ItLosSem044(void); +#endif + +#ifdef LOSCFG_KERNEL_SMP +VOID ItSmpLosSem001(VOID); +VOID ItSmpLosSem002(VOID); +VOID ItSmpLosSem003(VOID); +VOID ItSmpLosSem004(VOID); +VOID ItSmpLosSem005(VOID); +VOID ItSmpLosSem006(VOID); +VOID ItSmpLosSem007(VOID); +VOID ItSmpLosSem008(VOID); +VOID ItSmpLosSem009(VOID); +VOID ItSmpLosSem010(VOID); +VOID ItSmpLosSem011(VOID); +VOID ItSmpLosSem012(VOID); +VOID ItSmpLosSem013(VOID); +VOID ItSmpLosSem014(VOID); +VOID ItSmpLosSem015(VOID); +VOID ItSmpLosSem016(VOID); +VOID ItSmpLosSem017(VOID); +VOID ItSmpLosSem018(VOID); +VOID ItSmpLosSem019(VOID); +VOID ItSmpLosSem020(VOID); +VOID ItSmpLosSem021(VOID); +VOID ItSmpLosSem022(VOID); +VOID ItSmpLosSem023(VOID); +VOID ItSmpLosSem024(VOID); +VOID ItSmpLosSem025(VOID); +VOID ItSmpLosSem026(VOID); +VOID ItSmpLosSem027(VOID); +VOID ItSmpLosSem028(VOID); +VOID ItSmpLosSem029(VOID); +VOID ItSmpLosSem030(VOID); +VOID ItSmpLosSem031(VOID); +VOID ItSmpLosSem032(VOID); +VOID ItSmpLosSem033(VOID); +VOID ItSmpLosSem034(VOID); +VOID ItSmpLosSem035(VOID); +VOID ItSmpLosSem036(VOID); +#endif + +VOID ItSuiteLosSem(void); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#endif /* _IT_LOS_SEM_H */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_002.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_002.c new file mode 100644 index 00000000..f20fca85 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_002.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + + ret = LOS_SemCreate(0, NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_SEM_PTR_NULL, ret); + + return LOS_OK; +} + + +VOID ItLosSem002(void) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItLosSem002", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_005.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_005.c new file mode 100644 index 00000000..75c97681 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_005.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + + ret = LOS_SemCreate(2, &g_semID); // 2, Number of semaphore available + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SemPend(g_semID, LOS_NO_WAIT); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SemPend(g_semID, 0xF); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ret = LOS_SemPend(g_semID, LOS_NO_WAIT); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_SEM_UNAVAILABLE, ret, EXIT); + + ret = LOS_SemPend(g_semID, 0xF); + ICUNIT_TRACK_EQUAL(ret, LOS_ERRNO_SEM_TIMEOUT, ret); + +EXIT: + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + + +VOID ItLosSem005(void) +{ + TEST_ADD_CASE("ItLosSem005", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_009.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_009.c new file mode 100644 index 00000000..0546b300 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_009.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(void) +{ + UINT32 ret; + + g_testCount++; + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + + g_testCount++; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task = { 0 }; + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task.pcName = "SemTsk9"; + task.uwStackSize = TASK_STACK_SIZE_TEST; + task.usTaskPrio = TASK_PRIO_TEST - 1; + task.uwResved = LOS_TASK_STATUS_DETACHED; + + g_testCount = 0; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT2); + +EXIT2: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); +EXIT1: + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosSem009(void) +{ + TEST_ADD_CASE("ItLosSem009", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_012.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_012.c new file mode 100644 index 00000000..3bcba226 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_012.c @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_testTsk = 0; + +static VOID TaskF01(void) +{ + UINT32 ret; + + g_testCount++; + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testTsk = 1; + g_testCount++; + + LOS_TaskDelete(g_testTaskID01); +} +static VOID TaskF02(void) +{ + UINT32 ret; + + g_testCount++; + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testTsk = 2; // 2, Set flag number + g_testCount++; + + LOS_TaskDelete(g_testTaskID02); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task = { 0 }; + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task.pcName = "Sem12"; + task.uwStackSize = TASK_STACK_SIZE_TEST; + task.usTaskPrio = TASK_PRIO_TEST - 1; + task.uwResved = LOS_TASK_STATUS_DETACHED; + + g_testCount = 0; + g_testTsk = 0; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT1); + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task.pcName = "Sem12_1"; + task.usTaskPrio = TASK_PRIO_TEST - 3; // 3, Set the priority according to the task purpose,a smaller number means a higher priority. + task.uwResved = LOS_TASK_STATUS_DETACHED; + + ret = LOS_TaskCreate(&g_testTaskID02, &task); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT2); // 2, Here, assert that g_testCount is equal to + + ICUNIT_GOTO_EQUAL(g_testTsk, 0, g_testTsk, EXIT3); + ret = LOS_SemPost(g_semID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT2); + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + + ICUNIT_GOTO_EQUAL(g_testTsk, 1, g_testTsk, EXIT3); + + ret = LOS_SemPost(g_semID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT2); + LOS_TaskDelay(1); + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT2); // 4, Here, assert that g_testCount is equal to + ICUNIT_GOTO_EQUAL(g_testTsk, 2, g_testTsk, EXIT3); // 2, Here, assert that g_testCount is equal to + + LOS_TaskDelete(g_testTaskID02); + + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT2: + LOS_TaskDelete(g_testTaskID02); +EXIT1: + LOS_TaskDelete(g_testTaskID01); +EXIT: + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +EXIT3: + LOS_TaskDelete(g_testTaskID02); + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosSem012() +{ + TEST_ADD_CASE("ItLosSem012", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_013.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_013.c new file mode 100644 index 00000000..0024de16 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_013.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_testTsk = 0; + +static VOID TaskF01(void) +{ + UINT32 ret; + + g_testCount++; + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; + + LOS_TaskDelete(g_testTaskID01); +} + +static VOID TaskF02(void) +{ + UINT32 ret; + + g_testCount++; + ret = LOS_SemPend(g_semID2, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; + LOS_TaskDelete(g_testTaskID02); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task = { 0 }; + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task.pcName = "SemTsk13"; + task.uwStackSize = TASK_STACK_SIZE_TEST; + task.usTaskPrio = TASK_PRIO_TEST - 1; + task.uwResved = LOS_TASK_STATUS_DETACHED; + + g_testCount = 0; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SemCreate(0, &g_semID2); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT2); + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT3); + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task.pcName = "Sem13_1"; + task.usTaskPrio = TASK_PRIO_TEST - 2; // 2, Set the priority according to the task purpose,a smaller number means a higher priority. + task.uwResved = LOS_TASK_STATUS_DETACHED; + + ret = LOS_TaskCreate(&g_testTaskID02, &task); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT3); + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + + ICUNIT_TRACK_EQUAL(g_testCount, 2, g_testCount); // 2, Here, assert that g_testCount is equal to + + LOS_TaskDelete(g_testTaskID02); +EXIT3: + LOS_TaskDelete(g_testTaskID01); +EXIT2: + ret = LOS_SemDelete(g_semID2); + ICUNIT_TRACK_EQUAL(ret, LOS_OK, ret); +EXIT: + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosSem013(void) +{ + TEST_ADD_CASE("ItLosSem013", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_014.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_014.c new file mode 100644 index 00000000..addcecc5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_014.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_testTsk = 0; + +static VOID TaskF01(void) +{ + UINT32 ret; + + g_testCount++; + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testTsk = 1; + g_testCount++; + + LOS_TaskDelete(g_testTaskID01); +} + +static VOID TaskF02(void) +{ + UINT32 ret; + + g_testCount++; + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testTsk = 2; // 2, Set flag number + g_testCount++; + + LOS_TaskDelete(g_testTaskID02); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task = { 0 }; + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task.pcName = "SemTsk14"; + task.uwStackSize = TASK_STACK_SIZE_TEST; + task.usTaskPrio = TASK_PRIO_TEST + 1; + task.uwResved = LOS_TASK_STATUS_DETACHED; + + g_testCount = 0; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task.pcName = "Sem14_1"; + task.usTaskPrio = TASK_PRIO_TEST + 2; // 2, Set the priority according to the task purpose,a smaller number means a higher priority. + task.uwResved = LOS_TASK_STATUS_DETACHED; + + ret = LOS_TaskCreate(&g_testTaskID02, &task); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT2); + + ret = LOS_SemPend(g_semID, 0xF); + ICUNIT_TRACK_EQUAL(ret, LOS_ERRNO_SEM_TIMEOUT, ret); + + ICUNIT_TRACK_EQUAL(g_testCount, 2, g_testCount); // 2, Here, assert that g_testCount is equal to + + LOS_TaskDelete(g_testTaskID02); +EXIT2: + LOS_TaskDelete(g_testTaskID01); +EXIT: + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosSem014(void) +{ + TEST_ADD_CASE("ItLosSem014", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_015.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_015.c new file mode 100644 index 00000000..b53d6519 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_015.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_testTsk = 0; + +static VOID TaskF01(void) +{ + UINT32 ret; + + g_testCount++; + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testTsk = 1; + g_testCount++; + + LOS_TaskDelete(g_testTaskID01); +} + +static VOID TaskF02(void) +{ + UINT32 ret; + + g_testCount++; + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testTsk = 2; // 2, Set flag number + g_testCount++; + + LOS_TaskDelete(g_testTaskID02); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task = { 0 }; + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task.pcName = "SemTsk15"; + task.uwStackSize = TASK_STACK_SIZE_TEST; + task.usTaskPrio = TASK_PRIO_TEST - 1; + task.uwResved = LOS_TASK_STATUS_DETACHED; + + g_testCount = 0; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT2); + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task.pcName = "Sem15_1"; + task.usTaskPrio = TASK_PRIO_TEST + 1; + task.uwResved = LOS_TASK_STATUS_DETACHED; + + ret = LOS_TaskCreate(&g_testTaskID02, &task); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT2); + + ret = LOS_SemPend(g_semID, 0xF); + ICUNIT_TRACK_EQUAL(ret, LOS_ERRNO_SEM_TIMEOUT, ret); + + ICUNIT_TRACK_EQUAL(g_testCount, 2, g_testCount); // 2, Here, assert that g_testCount is equal to + + LOS_TaskDelete(g_testTaskID02); +EXIT2: + LOS_TaskDelete(g_testTaskID01); +EXIT: + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosSem015(void) +{ + TEST_ADD_CASE("ItLosSem015", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_016.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_016.c new file mode 100644 index 00000000..b75cec70 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_016.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_testTsk = 0; + +static VOID TaskF01(void) +{ + UINT32 ret; + + g_testCount++; + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; + + LOS_TaskDelete(g_testTaskID01); +} + +static VOID TaskF02(void) +{ + UINT32 ret; + + g_testCount++; + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testCount++; + + LOS_TaskDelete(g_testTaskID02); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task = { 0 }; + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task.pcName = "SemTsk16"; + task.uwStackSize = TASK_STACK_SIZE_TEST; + task.usTaskPrio = TASK_PRIO_TEST - 1; + task.uwResved = LOS_TASK_STATUS_DETACHED; + + g_testCount = 0; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT2); + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task.pcName = "Sem16_1"; + task.usTaskPrio = TASK_PRIO_TEST - 2; // 2, Set the priority according to the task purpose,a smaller number means a higher priority. + task.uwResved = LOS_TASK_STATUS_DETACHED; + + ret = LOS_TaskCreate(&g_testTaskID02, &task); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT2); + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + + ICUNIT_TRACK_EQUAL(g_testCount, 2, g_testCount); // 2, Here, assert that g_testCount is equal to + + ret = LOS_SemPend(g_semID, 0xF); + ICUNIT_TRACK_EQUAL(ret, LOS_ERRNO_SEM_TIMEOUT, ret); + + LOS_TaskDelete(g_testTaskID02); +EXIT2: + LOS_TaskDelete(g_testTaskID01); +EXIT: + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosSem016(void) +{ + TEST_ADD_CASE("ItLosSem016", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_017.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_017.c new file mode 100644 index 00000000..92b69216 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_017.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(void) +{ + UINT32 ret; + + g_testCount++; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SemPost(g_semID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + g_testCount++; + +EXIT: + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task = { 0 }; + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task.pcName = "SemTsk17"; + task.uwStackSize = TASK_STACK_SIZE_TEST; + task.usTaskPrio = TASK_PRIO_TEST - 1; + task.uwResved = LOS_TASK_STATUS_DETACHED; + + g_testCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosSem017(void) +{ + TEST_ADD_CASE("ItLosSem017", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_019.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_019.c new file mode 100644 index 00000000..f91f89c0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_019.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_testTsk = 0; + +static VOID TaskF01(void) +{ + UINT32 ret; + + g_testCount++; + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testTsk = 1; + g_testCount++; + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task = { 0 }; + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task.pcName = "Sem19"; + task.uwStackSize = TASK_STACK_SIZE_TEST; + task.usTaskPrio = TASK_PRIO_TEST - 1; + task.uwResved = LOS_TASK_STATUS_DETACHED; + + g_testCount = 0; + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT2); + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + + ICUNIT_TRACK_EQUAL(g_testCount, 1, g_testCount); + ret = LOS_SemPost(g_semID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + +EXIT2: + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + + +VOID ItLosSem019(void) +{ + TEST_ADD_CASE("ItLosSem019", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_020.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_020.c new file mode 100644 index 00000000..47bb469c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_020.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(void) +{ + UINT32 ret; + + g_testCount++; + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + g_testCount++; + + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task = { 0 }; + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task.pcName = "SemTsk20"; + task.uwStackSize = TASK_STACK_SIZE_TEST; + task.usTaskPrio = TASK_PRIO_TEST - 1; + task.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + task.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_testCount = 0; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + ICUNIT_TRACK_EQUAL(g_testCount, 1, g_testCount); + + LOS_TaskLock(); + ret = LOS_SemPost(g_semID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT2); + ICUNIT_TRACK_EQUAL(g_testCount, 1, g_testCount); + LOS_TaskUnlock(); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT2); // 2, Here, assert that g_testCount is equal to + +EXIT: + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT2: + LOS_TaskDelete(g_testTaskID01); + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + + +VOID ItLosSem020(void) +{ + TEST_ADD_CASE("ItLosSem020", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_022.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_022.c new file mode 100644 index 00000000..56ffb69d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_022.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_testTsk = 0; + +static VOID TaskF01(void) +{ + UINT32 ret; + + g_testCount++; + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testTsk = 1; + g_testCount++; + LOS_TaskDelete(g_testTaskID01); +} + +static VOID TaskF02(void) +{ + UINT32 ret; + ICUNIT_TRACK_EQUAL(g_testCount, 1, g_testCount); + + LOS_TaskLock(); + ret = LOS_SemPost(g_semID); + ICUNIT_TRACK_EQUAL(ret, LOS_OK, ret); +#ifndef LOSCFG_KERNEL_SMP + ICUNIT_TRACK_EQUAL(g_testCount, 1, g_testCount); +#endif + + LOS_TaskUnlock(); +#ifndef LOSCFG_KERNEL_SMP + ICUNIT_TRACK_EQUAL(g_testCount, 1, g_testCount); +#endif + g_testCount++; + LOS_TaskDelete(g_testTaskID02); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task = { 0 }; + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task.pcName = "SemTsk22"; + task.uwStackSize = TASK_STACK_SIZE_TEST; + task.usTaskPrio = TASK_PRIO_TEST - 1; + task.uwResved = LOS_TASK_STATUS_DETACHED; + g_testCount = 0; + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT2); + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task.pcName = "Sem22_1"; + task.usTaskPrio = TASK_PRIO_TEST - 2; // 2, Set the priority according to the task purpose,a smaller number means a higher priority. + task.uwResved = LOS_TASK_STATUS_DETACHED; + ret = LOS_TaskCreate(&g_testTaskID02, &task); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT2); + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + + ICUNIT_TRACK_EQUAL(g_testCount, 3, g_testCount); // 3, Here, assert that g_testCount is equal to + +EXIT: + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT2: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +VOID ItLosSem022(void) +{ + TEST_ADD_CASE("ItLosSem022", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_023.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_023.c new file mode 100644 index 00000000..263c6c41 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_023.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_testTsk = 0; + +static VOID TaskF01(void) +{ + UINT32 ret; + + g_testCount++; + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_testTsk = 1; + g_testCount++; + + LOS_TaskDelete(g_testTaskID01); +} + +static VOID HwiF01(void) +{ + UINT32 ret; + TEST_HwiClear(HWI_NUM_TEST); + + ICUNIT_TRACK_EQUAL(g_testCount, 1, g_testCount); + + ret = LOS_SemPost(g_semID); + ICUNIT_TRACK_EQUAL(ret, LOS_OK, ret); + + g_testCount++; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task = { 0 }; + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task.pcName = "SemTsk23"; + task.uwStackSize = TASK_STACK_SIZE_TEST; + task.usTaskPrio = TASK_PRIO_TEST - 1; + task.uwResved = LOS_TASK_STATUS_DETACHED; + g_testCount = 0; + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT2); + + TEST_HwiDelete(HWI_NUM_TEST); + ret = TEST_HwiCreate(HWI_NUM_TEST, 0, 0, HwiF01, 0); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT2); +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + TestHwiTrigger(HWI_NUM_TEST); + + LOS_TaskDelay(10); // 10, delay enouge time + + ICUNIT_TRACK_EQUAL(g_testCount, 3, g_testCount); // 3, Here, assert that g_testCount is equal to + TEST_HwiDelete(HWI_NUM_TEST); + +EXIT: + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT2: + LOS_TaskDelete(g_testTaskID01); + + return LOS_OK; +} + +VOID ItLosSem023(void) +{ + TEST_ADD_CASE("ItLosSem023", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_026.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_026.c new file mode 100644 index 00000000..65132b95 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_026.c @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF02(void) +{ + UINT32 ret; + + g_testCount++; + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); +#ifndef LOSCFG_KERNEL_SMP + ICUNIT_TRACK_EQUAL(g_testCount, 2, g_testCount); // 2, Here, assert that g_testCount is equal to +#endif + g_testCount++; + LOS_TaskDelete(g_testTaskID02); +} + +static VOID TaskF01(void) +{ + UINT32 ret; + + g_testCount++; + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); +#ifndef LOSCFG_KERNEL_SMP + ICUNIT_TRACK_EQUAL(g_testCount, 3, g_testCount); // 3, Here, assert that g_testCount is equal to +#endif + g_testCount++; + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task = { 0 }; + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task.pcName = "SemTsk26"; + task.uwStackSize = TASK_STACK_SIZE_TEST; + task.usTaskPrio = TASK_PRIO_TEST - 1; + task.uwResved = LOS_TASK_STATUS_DETACHED; + g_testCount = 0; + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT2); + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task.pcName = "Sem26_1"; + task.usTaskPrio = TASK_PRIO_TEST - 2; // 2, Set the priority according to the task purpose,a smaller number means a higher priority. + task.uwResved = LOS_TASK_STATUS_DETACHED; + ret = LOS_TaskCreate(&g_testTaskID02, &task); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT2); + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT3); // 2, Here, assert that g_testCount is equal to + + ret = LOS_SemPost(g_semID); + ICUNIT_TRACK_EQUAL(ret, LOS_OK, ret); + + LOS_TaskLock(); + + ret = LOS_SemPost(g_semID); + ICUNIT_TRACK_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SemPost(g_semID); + ICUNIT_TRACK_EQUAL(ret, LOS_OK, ret); + + LOS_TaskUnlock(); + + TestExtraTaskDelay(TEST_TASKDELAY_10TICK); + ICUNIT_TRACK_EQUAL(g_testCount, 4, g_testCount); // 4, Here, assert that g_testCount is equal to + +EXIT: + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +EXIT3: + LOS_TaskDelete(g_testTaskID02); + +EXIT2: + LOS_TaskDelete(g_testTaskID01); + + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + + +VOID ItLosSem026(void) +{ + TEST_ADD_CASE("ItLosSem026", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_027.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_027.c new file mode 100644 index 00000000..d52981ed --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_027.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#define IT_SEMLOOP 10 + +static VOID TaskF01(void) +{ + UINT32 ret; + UINT32 i; + + g_testCount++; + + for (i = 0; i < IT_SEMLOOP + 1; i++) { + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + } + + g_testCount++; + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task = { 0 }; + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task.pcName = "SemTsk_27"; + task.uwStackSize = TASK_STACK_SIZE_TEST; + task.usTaskPrio = TASK_PRIO_TEST - 1; + task.uwResved = LOS_TASK_STATUS_DETACHED; + g_testCount = 0; + ret = LOS_SemCreate(IT_SEMLOOP, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_TaskDelay(100); // 100, delay enouge time + + ICUNIT_GOTO_NOT_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to + ICUNIT_TRACK_EQUAL(g_testCount, 1, g_testCount); + + LOS_TaskDelete(g_testTaskID01); + +EXIT: + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosSem027(void) +{ + TEST_ADD_CASE("ItLosSem027", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_028.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_028.c new file mode 100644 index 00000000..2c43ef31 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_028.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#define IT_SEMLOOP 10 + +static VOID TaskF01(void) +{ + UINT32 ret; + UINT32 i; + + g_testCount++; + for (i = 0; i < IT_SEMLOOP; i++) { + ret = LOS_SemPost(g_semID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + } + + for (i = 0; i < IT_SEMLOOP + 1; i++) { + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + } + + g_testCount++; + LOS_TaskDelete(g_testTaskID01); +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task = { 0 }; + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task.pcName = "SemTsk28"; + task.uwStackSize = TASK_STACK_SIZE_TEST; + task.usTaskPrio = TASK_PRIO_TEST - 1; + task.uwResved = LOS_TASK_STATUS_DETACHED; + g_testCount = 0; + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + + ICUNIT_GOTO_NOT_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to + ICUNIT_TRACK_EQUAL(g_testCount, 1, g_testCount); + + LOS_TaskDelete(g_testTaskID01); + +EXIT: + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + + +VOID ItLosSem028(void) +{ + TEST_ADD_CASE("ItLosSem028", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_029.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_029.c new file mode 100644 index 00000000..a9166b94 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_029.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#define IT_SEMLOOP 10 + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 i; + + g_testCount = 0; + ret = LOS_SemCreate(0xFFFF - IT_SEMLOOP, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + for (i = 0; i < IT_SEMLOOP - 1; i++) { + ret = LOS_SemPost(g_semID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + + ret = LOS_SemPost(g_semID); + ICUNIT_TRACK_EQUAL(ret, LOS_ERRNO_SEM_OVERFLOW, ret); + +EXIT: + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + + +VOID ItLosSem029(void) +{ + TEST_ADD_CASE("ItLosSem029", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_034.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_034.c new file mode 100644 index 00000000..aec135db --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/full/It_los_sem_034.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(void) +{ + UINT32 ret; + UINT64 osEndTime; + UINT64 osStartTime; + UINT32 tickNum; + + g_testCount++; + + osStartTime = LOS_TickCountGet(); + ret = LOS_SemPend(g_semID, 1000); // 1000, set timeout + osEndTime = LOS_TickCountGet(); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_SEM_TIMEOUT, ret); + + tickNum = (osEndTime - osStartTime); + + if (tickNum < (1000 - TEST_TASKDELAY_2TICK) || tickNum > (1000 + TEST_TASKDELAY_2TICK)) { // 1000, timeout + ICUNIT_ASSERT_EQUAL_VOID(tickNum, 0, tickNum); + } + + g_testCount++; + + LOS_TaskDelay(100); // 100, delay enouge time +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task = { 0 }; + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task.pcName = "Sem_34"; + task.uwStackSize = TASK_STACK_SIZE_TEST; + task.usTaskPrio = TASK_PRIO_TEST - 1; + task.uwResved = LOS_TASK_STATUS_DETACHED; + g_testCount = 0; + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskCreate(&g_testTaskID01, &task); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + TestExtraTaskDelay(TEST_TASKDELAY_2TICK); + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + LOS_TaskDelay(1000); // 1000, delay enouge time + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, Here, assert that g_testCount is equal to + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosSem034(void) +{ + TEST_ADD_CASE("ItLosSem034", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smoke/It_los_sem_001.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smoke/It_los_sem_001.c new file mode 100644 index 00000000..63d4352a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smoke/It_los_sem_001.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#define IT_SEM_COUNT_MAX 0xFFFE + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SemCreate(1, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SemCreate(IT_SEM_COUNT_MAX, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SemCreate(IT_SEM_COUNT_MAX + 1, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_SEM_OVERFLOW, ret); + + return LOS_OK; +} + +VOID ItLosSem001() +{ + TEST_ADD_CASE("ItLosSem001", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smoke/It_los_sem_003.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smoke/It_los_sem_003.c new file mode 100644 index 00000000..957425bf --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smoke/It_los_sem_003.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#define IT_SEM_COUNT_MAX 0xFFFE + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SemPend(g_semID, 2); // 2, set timeout + ICUNIT_TRACK_EQUAL(ret, LOS_ERRNO_SEM_TIMEOUT, ret); + + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SemCreate(1, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_TRACK_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SemCreate(IT_SEM_COUNT_MAX, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_TRACK_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosSem003(void) +{ + TEST_ADD_CASE("ItLosSem003", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smoke/It_los_sem_006.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smoke/It_los_sem_006.c new file mode 100644 index 00000000..3c821ee7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smoke/It_los_sem_006.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#define IT_SEM_COUNT_MAX 0xFFFE + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SemPost(g_semID); + ICUNIT_TRACK_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SemCreate(IT_SEM_COUNT_MAX, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SemPost(g_semID); + ICUNIT_TRACK_EQUAL(ret, LOS_ERRNO_SEM_OVERFLOW, ret); + + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItLosSem006(void) +{ + TEST_ADD_CASE("ItLosSem006", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_001.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_001.c new file mode 100644 index 00000000..12256ba9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_001.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "It_los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_SemCreate(1, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_sem_001_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_SemDelete(g_semID); + return LOS_OK; +} + +VOID ItSmpLosSem001(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosSem001", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_002.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_002.c new file mode 100644 index 00000000..9b1b4b1e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_002.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LOS_SemCreate(1, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_001_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_SemDelete(g_semID); + return LOS_OK; +} + +VOID ItSmpLosSem002(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosSem002", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_003.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_003.c new file mode 100644 index 00000000..16988f07 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_003.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID HwiF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LOS_SemCreate(1, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + + TestHwiTrigger(HWI_NUM_TEST); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to + +EXIT: + LOS_HwiDelete(HWI_NUM_TEST, NULL); + LOS_SemDelete(g_semID); + return LOS_OK; +} + +VOID ItSmpLosSem003(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosSem003", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_004.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_004.c new file mode 100644 index 00000000..b99d0ee9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_004.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_001_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_SEM_PENDED, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosSem004(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosSem004", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_005.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_005.c new file mode 100644 index 00000000..05d265a4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_005.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static VOID TaskF02(VOID) +{ + UINT32 ret; + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_SEM_PENDED, ret); + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_005_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_005_task2", TaskF02, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to + + TestBusyTaskDelay(1); + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_PEND, 0, ret, EXIT); + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + LOS_TaskDelete(g_testTaskID02); + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosSem005(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosSem005", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_006.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_006.c new file mode 100644 index 00000000..92f1fabd --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_006.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_006_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 1); // 100, Set the timeout of runtime; + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + LOS_TaskDelay(1); + + ret = LOS_SemDelete(g_semID); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_SEM_PENDED, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosSem006(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosSem006", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_007.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_007.c new file mode 100644 index 00000000..0121e8de --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_007.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static VOID TaskF02(VOID) +{ + UINT32 ret; + TestAssertBusyTaskDelay(100, 1); // 100, Set the timeout of runtime; + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + + /* wait for task1 to pend sem */ + TestBusyTaskDelay(1); + + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_SEM_PENDED, ret); + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + // 2, Set the priority according to the task purpose,a smaller number means a higher priority. + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_007_task1", TaskF01, TASK_PRIO_TEST - 2, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_007_task2", TaskF02, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to + + /* wait for task1 to pend sem */ + TestBusyTaskDelay(1); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_PEND, 0, ret, EXIT); + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelete(g_testTaskID02); + + LOS_TaskDelay(10); // 10, delay enouge time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_UNUSED, 0, ret, EXIT); + + ret = OS_TCB_FROM_TID(g_testTaskID02)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_UNUSED, 0, ret, EXIT); + + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosSem007(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosSem007", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_008.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_008.c new file mode 100644 index 00000000..fc02f412 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_008.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_sem.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID HwiF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_SEM_PEND_INTERR, ret, EXIT); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +EXIT: + LOS_HwiDelete(HWI_NUM_TEST, NULL); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + + TestHwiTrigger(HWI_NUM_TEST); + + TestAssertBusyTaskDelay(200, 2); // 200, Set the timeout of runtime; 2, test running count + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert the result + + ret = LOS_SemDelete(g_semID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + +EXIT: + LOS_HwiDelete(HWI_NUM_TEST, NULL); + LOS_SemDelete(g_semID); + return LOS_OK; +} + + +VOID ItSmpLosSem008(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosSem008", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_009.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_009.c new file mode 100644 index 00000000..df74f15d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_009.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static VOID HwiF01(VOID) +{ + UINT32 ret; + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_SEM_PENDED, ret); + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_009_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 1); // 100, Set the timeout of runtime; + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + /* wait for task1 to pend sem */ + TestBusyTaskDelay(1); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_PEND, 0, ret, EXIT); + + TestHwiTrigger(HWI_NUM_TEST); + + TestAssertBusyTaskDelay(200, 2); // 200, Set the timeout of runtime; 2, test running count + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to + +EXIT: + ret = LOS_HwiDelete(HWI_NUM_TEST, NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + LOS_TaskDelay(10); // 10, delay enouge time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_UNUSED, 0, ret, EXIT); + + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosSem009(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosSem009", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_010.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_010.c new file mode 100644 index 00000000..063970c2 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_010.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static VOID TaskF02(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + + ret = LOS_SemPost(g_semID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_010_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_010_task2", TaskF02, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, Here, assert that g_testCount is equal to + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + LOS_SemDelete(g_semID); + return LOS_OK; +} + +VOID ItSmpLosSem010(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosSem010", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_011.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_011.c new file mode 100644 index 00000000..fa11bf47 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_011.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF02(VOID) +{ + UINT32 ret; + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + + ret = LOS_SemPost(g_semID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_011_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_011_task2", TaskF02, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 3); // 100, Set the timeout of runtime; 3, test running count + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, Here, assert that g_testCount is equal to + + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + LOS_SemDelete(g_semID); + return LOS_OK; +} + +VOID ItSmpLosSem011(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosSem011", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_012.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_012.c new file mode 100644 index 00000000..ef6f657e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_012.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static VOID HwiF01(VOID) +{ + UINT32 ret; + ret = LOS_SemPost(g_semID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_009_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + TestHwiTrigger(HWI_NUM_TEST); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to + + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + ret = LOS_HwiDelete(HWI_NUM_TEST, NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + LOS_SemDelete(g_semID); + return LOS_OK; +} + +VOID ItSmpLosSem012(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosSem012", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_013.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_013.c new file mode 100644 index 00000000..07731374 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_013.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static VOID TaskF02(VOID) +{ + UINT32 ret; + + do { + __asm__ volatile("nop"); + } while (g_testCount != 1); + + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_013_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_013_task2", TaskF02, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SemPost(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + LOS_SemDelete(g_semID); + return LOS_OK; +} + +VOID ItSmpLosSem013(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosSem013", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_014.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_014.c new file mode 100644 index 00000000..39906dc5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_014.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF02(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + + ret = LOS_SemPost(g_semID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + do { + __asm__ volatile("nop"); + } while (g_testCount != 1); + + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + + TestDumpCpuid(); + return; +} +static VOID TaskF01(VOID) +{ + UINT32 ret; + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + LOS_AtomicInc(&g_testCount); + return; +} +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_014_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_014_task2", TaskF02, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + LOS_SemDelete(g_semID); + return LOS_OK; +} + +VOID ItSmpLosSem014(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosSem014", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_015.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_015.c new file mode 100644 index 00000000..bafcd493 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_015.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static VOID HwiF01(VOID) +{ + UINT32 ret; + ret = LOS_SemPost(g_semID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + do { + __asm__ volatile("nop"); + } while (g_testCount != 2); // 2, wait flag is, or do nothing + + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_009_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + TestHwiTrigger(HWI_NUM_TEST); + + TestAssertBusyTaskDelay(100, 3); // 100, Set the timeout of runtime; 3, test running count + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, Here, assert that g_testCount is equal to + +EXIT: + LOS_TaskDelete(g_testTaskID01); + ret = LOS_HwiDelete(HWI_NUM_TEST, NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + LOS_SemDelete(g_semID); + return LOS_OK; +} + +VOID ItSmpLosSem015(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosSem015", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_016.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_016.c new file mode 100644 index 00000000..46f9bcd5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_016.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + LOS_AtomicInc(&g_testCount); + + ret = LOS_SemPost(g_semID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_016_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_SemDelete(g_semID); + return LOS_OK; +} + +VOID ItSmpLosSem016(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosSem016", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_017.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_017.c new file mode 100644 index 00000000..4004112c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_017.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + ret = LOS_SemPost(g_semID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_017_task2", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 1); // 100, Set the timeout of runtime; + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_SemDelete(g_semID); + return LOS_OK; +} + +VOID ItSmpLosSem017(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosSem017", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_018.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_018.c new file mode 100644 index 00000000..320386e7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_018.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + ret = LOS_SemPost(g_semID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + LOS_AtomicInc(&g_testCount); + + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_005_task2", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_SemDelete(g_semID); + return LOS_OK; +} + +VOID ItSmpLosSem018(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosSem018", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_019.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_019.c new file mode 100644 index 00000000..3d0acd58 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_019.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID HwiF01(VOID) +{ + UINT32 ret; + ret = LOS_SemPost(g_semID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + + TestHwiTrigger(HWI_NUM_TEST); + + TestAssertBusyTaskDelay(100, 1); // 100, Set the timeout of runtime; + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + ret = LOS_HwiDelete(HWI_NUM_TEST, NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + LOS_SemDelete(g_semID); + return LOS_OK; +} + +VOID ItSmpLosSem019(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosSem019", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_020.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_020.c new file mode 100644 index 00000000..874dc295 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_020.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + + LOS_AtomicInc(&g_testCount); + + ret = LOS_SemPost(g_semID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_020_task2", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to + + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_SemDelete(g_semID); + return LOS_OK; +} + +VOID ItSmpLosSem020(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosSem020", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_021.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_021.c new file mode 100644 index 00000000..c5955132 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_021.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LOS_SemPost(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + LOS_AtomicInc(&g_testCount); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_021_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to + + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_SemDelete(g_semID); + return LOS_OK; +} + +VOID ItSmpLosSem021(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosSem021", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_022.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_022.c new file mode 100644 index 00000000..7109d6d3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_022.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_sem.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + ret = LOS_SemPost(g_semID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static VOID HwiF01(VOID) +{ + UINT32 ret; + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_SEM_PEND_INTERR, ret, EXIT); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +EXIT: + LOS_HwiDelete(HWI_NUM_TEST, NULL); + return; +} + +static UINT32 testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_009_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + TestHwiTrigger(HWI_NUM_TEST); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to + + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + +EXIT: + LOS_TaskDelete(g_testTaskID01); + ret = LOS_HwiDelete(HWI_NUM_TEST, NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + LOS_SemDelete(g_semID); + return LOS_OK; +} + +VOID ItSmpLosSem022(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosSem022", testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_023.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_023.c new file mode 100644 index 00000000..4d093330 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_023.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static VOID TaskF02(VOID) +{ + UINT32 ret; + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SemPost(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_023_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_023_task", TaskF02, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // othercpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + LOS_SemDelete(g_semID); + return LOS_OK; +} + +VOID ItSmpLosSem023(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosSem023", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_024.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_024.c new file mode 100644 index 00000000..f25052c7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_024.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF02(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 1, g_testCount); + + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ret = LOS_SemPost(g_semID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + LOS_AtomicInc(&g_testCount); + return; +} +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_014_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_014_task2", TaskF02, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to + +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + LOS_SemDelete(g_semID); + return LOS_OK; +} + +VOID ItSmpLosSem024(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosSem024", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_025.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_025.c new file mode 100644 index 00000000..27f23248 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_025.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_sem.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 0, g_testCount); + + ret = LOS_SemPost(g_semID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static VOID HwiF01(VOID) +{ + UINT32 ret; + + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_SEM_PEND_INTERR, ret, EXIT); + + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +EXIT: + LOS_SemDelete(g_semID); + LOS_HwiDelete(HWI_NUM_TEST, NULL); + return; +} + +static UINT32 testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_009_task", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + TestHwiTrigger(HWI_NUM_TEST); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to + +EXIT: + LOS_TaskDelete(g_testTaskID01); + ret = LOS_HwiDelete(HWI_NUM_TEST, NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + LOS_SemDelete(g_semID); + return LOS_OK; +} + + +VOID ItSmpLosSem025(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosSem025", testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_026.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_026.c new file mode 100644 index 00000000..5b530340 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_026.c @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_ret1 = 0xff; +static UINT32 g_ret2 = 0xff; + +static UINT32 TestAbs(UINT32 num1, UINT32 num2) +{ + return (num1 > num2) ? num1 - num2 : num2 - num1; +} +static VOID TaskF01(VOID) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + g_ret1 = ret; + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static VOID TaskF02(VOID) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + g_ret2 = ret; + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + g_ret1 = 0xff; + g_ret2 = 0xff; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_026_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_026_task2", TaskF02, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to + + ret = LOS_SemPost(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 3); // 100, Set the timeout of runtime; 3, test running count + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, Here, assert that g_testCount is equal to + if ((g_ret1 + g_ret2 == 0xff) && (TestAbs(g_ret1, g_ret2) == 0xff)) { + ICUNIT_GOTO_EQUAL(1, 1, g_ret1, EXIT); + } else { + ICUNIT_GOTO_EQUAL(1, 0, g_ret1, EXIT); + } + PRINT_DEBUG("ret1=0x%x,ret2=0x%x\n", g_ret1, g_ret2); +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosSem026(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosSem026", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_027.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_027.c new file mode 100644 index 00000000..845b7e12 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_027.c @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID HwiF01(VOID) +{ + UINT32 ret, i; + LOS_AtomicInc(&g_testCount); + for (i = 0; i < TRandom() % 500; i++) { // Gets a random value of 0-500 + } + + ret = LOS_SemPost(g_semID); // sem post in hwi + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static VOID TaskF02(VOID) +{ + UINT32 ret; + + TestHwiTrigger(HWI_NUM_TEST); + + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid, i, j; + TSK_INIT_PARAM_S testTask; + LosTaskCB *cb = NULL; + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + + for (i = 0; i < LOOP; i++) { + g_testCount = 0; + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_sem_027_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_sem_027_task1", TaskF02, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + do { + __asm__ volatile("nop"); + } while (g_testCount == 1); // wait for task f02 + + for (j = 0; j < TRandom() % 500; j++) { // Gets a random value of 0-500 + } + + ret = LOS_SemPost(g_semID); // sem post in task + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 4); // 100, Set the timeout of runtime; 4, test running count + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, Here, assert that g_testCount is equal to + + ret = LOS_SemDelete(g_semID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + LOS_HwiDelete(HWI_NUM_TEST, NULL); + LOS_SemDelete(g_semID); + return LOS_OK; +} + +VOID ItSmpLosSem027(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosSem027", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_028.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_028.c new file mode 100644 index 00000000..43f0d3b6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_028.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_ret1 = 0xff; +static UINT32 g_ret2 = 0xff; + +static VOID TaskF01(VOID) +{ + UINT32 ret, i; + LOS_AtomicInc(&g_testCount); + + for (i = 0; i < TRandom() % 100; i++) { // Gets a random value of 0-100 + } + + ret = LOS_SemDelete(g_semID); + g_ret2 = ret; + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid, i, j; + TSK_INIT_PARAM_S testTask; + LosTaskCB *cb = NULL; + + for (i = 0; i < LOOP; i++) { + g_testCount = 0; + g_ret1 = 0xff; + g_ret2 = 0xff; + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_030_task2", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + do { + __asm__ volatile("nop"); + } while (g_testCount == 0); // wait for task f01 + + for (j = 0; j < TRandom() % 500; j++) { // Gets a random value of 0-500 + } + + ret = LOS_SemDelete(g_semID); + g_ret1 = ret; + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to + + if (((g_ret1 == LOS_OK) && (g_ret2 != LOS_OK)) || ((g_ret2 == LOS_OK) && (g_ret1 != LOS_OK))) + ICUNIT_GOTO_EQUAL(1, 1, g_ret1, EXIT); + else + ICUNIT_GOTO_EQUAL(1, 2, g_ret1, EXIT); // 2, Here, assert that g_testCount is equal to + + TestBusyTaskDelay(10); // 10, delay enouge time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_UNUSED, 0, ret, EXIT); + } +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_SemDelete(g_semID); + return LOS_OK; +} + +VOID ItSmpLosSem028(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosSem028", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_029.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_029.c new file mode 100644 index 00000000..a7d3af39 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_029.c @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_ret = 0; +static VOID TaskF01(VOID) +{ + UINT32 ret; + LOS_AtomicInc(&g_testCount); + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static VOID TaskF02(VOID) +{ + UINT32 ret, i; + LOS_AtomicInc(&g_testCount); + + for (i = 0; i < TRandom() % 500; i++) { // Gets a random value of 0-500 + } + + ret = LOS_SemDelete(g_semID); // delete event in other cpu + g_ret = ret; + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid, i, j; + TSK_INIT_PARAM_S testTask; + LosTaskCB *cb = NULL; + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + for (i = 0; i < LOOP; i++) { + g_testCount = 0; + g_ret = 0; + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_031_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_event_031_task2", TaskF02, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + do { + __asm__ volatile("nop"); + } while (g_testCount == 1); // wait for task f02 + + for (j = 0; j < TRandom() % 500; j++) { // Gets a random value of 0-500 + } + + ret = LOS_SemPost(g_semID); // post sem in other cpu + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + TestAssertBusyTaskDelay(100, 4); // 100, Set the timeout of runtime; 4, test running count + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, Here, assert that g_testCount is equal to + + if ((g_ret != LOS_OK) && (g_ret != LOS_ERRNO_SEM_PENDED)) { + ICUNIT_GOTO_EQUAL(1, 0, g_ret, EXIT); + } + + /* clear enviorment */ + ret = LOS_SemDelete(g_semID); + if (g_ret == LOS_ERRNO_SEM_PENDED) { + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } else { + ICUNIT_GOTO_EQUAL(ret, LOS_ERRNO_SEM_INVALID, ret, EXIT); + } + + TestBusyTaskDelay(2); // 2, delay enouge time + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_UNUSED, 0, ret, EXIT); + ret = OS_TCB_FROM_TID(g_testTaskID02)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_UNUSED, 0, ret, EXIT); + } +EXIT: + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + LOS_SemDelete(g_semID); + return LOS_OK; +} + +VOID ItSmpLosSem029(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosSem029", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_030.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_030.c new file mode 100644 index 00000000..fdc8155b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_030.c @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#ifdef LOSCFG_KERNEL_SMP +static UINT32 g_ret1, g_ret2, g_ret3; +static UINT32 g_szId[3] = {0}; + +static VOID TaskF01(UINT32 index) +{ + UINT32 ret, i; + switch (index) { + case 0: + for (i = 0; i < TRandom() % 500; i++) { // Gets a random value of 0-500 + } + g_ret1 = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + LOS_AtomicInc(&g_testCount); + break; + case 1: + for (i = 0; i < TRandom() % 500; i++) { // Gets a random value of 0-500 + } + g_ret2 = LOS_SemPost(g_semID); + LOS_AtomicInc(&g_testCount); + break; + case 2: // 2, index + for (i = 0; i < TRandom() % 500; i++) { // Gets a random value of 0-500 + } + g_ret3 = LOS_SemDelete(g_semID); + LOS_AtomicInc(&g_testCount); + break; + default: + break; + } + + TestDumpCpuid(); + return; +} +static UINT32 Testcase(void) +{ + TSK_INIT_PARAM_S testTask; + UINT32 ret; + UINT32 i, j; + + g_testCount = 0; + + for (i = 0; i < LOOP; i++) { + g_testCount = 0; + g_ret1 = 0xff; + g_ret2 = 0xff; + g_ret3 = 0xff; + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + for (j = 0; j < 3; j++) { // 3, max index + TEST_TASK_PARAM_INIT(testTask, "it_sem_030_task", TaskF01, TASK_PRIO_TEST + 1); + testTask.auwArgs[0] = j; + ret = LOS_TaskCreate(&g_szId[j], &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + LOS_TaskDelay(10); // 10, delay enouge time + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, Here, assert that g_testCount is equal to + + if ((g_ret1 == LOS_OK) && (g_ret2 == LOS_OK) && (g_ret3 == LOS_OK)) { // pend-post-del ///post-pend-del + } else if ((g_ret1 == LOS_ERRNO_SEM_INVALID) && (g_ret2 == LOS_ERRNO_SEM_INVALID) && + (g_ret3 == LOS_OK)) { // del-pend-post//del-post-pend + } else if ((g_ret1 == LOS_OK) && (g_ret2 == LOS_OK) && (g_ret3 == LOS_ERRNO_SEM_PENDED)) { // pend-delete-post + } else if ((g_ret1 == LOS_ERRNO_SEM_INVALID) && (g_ret2 == LOS_OK) && (g_ret3 == LOS_OK)) { // post-del-pend + } else { + ICUNIT_GOTO_EQUAL(1, 0, g_ret1, EXIT); + } + for (j = 0; j < 3; j++) { // 3, max index + ret = OS_TCB_FROM_TID(g_szId[j])->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_UNUSED, 0, ret, EXIT); + } + LOS_SemDelete(g_semID); + } + +EXIT: + for (i = 0; i < 3; i++) { // 3, max index + LOS_TaskDelete(g_szId[i]); + } + LOS_SemDelete(g_semID); + return LOS_OK; +} + +VOID ItSmpLosSem030(VOID) +{ + TEST_ADD_CASE("ItSmpLosSem030", Testcase, TEST_LOS, TEST_HWI, TEST_LEVEL1, TEST_FUNCTION); +} +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_031.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_031.c new file mode 100644 index 00000000..6dc8e6ee --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_031.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_sz[LOSCFG_KERNEL_CORE_NUM] = {0}; +static UINT32 TestAbs(UINT32 num1, UINT32 num2) +{ + return (num1 > num2) ? num1 - num2 : num2 - num1; +} +static VOID TaskF01(VOID) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + ret = LOS_SemPend(g_semID, 10); // 10 ticks timeout + if ((ret != LOS_OK) && (ret != LOS_ERRNO_SEM_TIMEOUT)) { + ICUNIT_ASSERT_EQUAL_VOID(1, 0, ret); + } + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid, i; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_sem_031_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK((ArchCurrCpuid() + i + 1) % + LOSCFG_KERNEL_CORE_NUM)); // let current cpu 's task create at the last + ret = LOS_TaskCreate(&g_sz[i], &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + LOS_TaskDelay(5); // 5, delay enouge time + ICUNIT_GOTO_EQUAL(g_testCount, LOSCFG_KERNEL_CORE_NUM, g_testCount, EXIT); + + ret = LOS_SemPost(g_semID); // post sem before 10 ticks timeout + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + LOS_TaskDelay(1); + ICUNIT_GOTO_EQUAL(g_testCount, LOSCFG_KERNEL_CORE_NUM + 1, g_testCount, EXIT); + + LOS_TaskDelay(10); // 10, delay enouge time + + ICUNIT_GOTO_EQUAL(g_testCount, LOSCFG_KERNEL_CORE_NUM * 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to + +EXIT: + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + LOS_TaskDelete(g_sz[i]); + } + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosSem031(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosSem031", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_032.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_032.c new file mode 100644 index 00000000..b0e6f8fa --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_032.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_sz[LOSCFG_KERNEL_CORE_NUM] = {0}; + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + ret = LOS_SemPend(g_semID, 100); // 100 ticks timeout + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + + ret = LOS_SemPost(g_semID); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid, i; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_sem_031_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK((ArchCurrCpuid() + i + 1) % + LOSCFG_KERNEL_CORE_NUM)); // let current cpu 's task create at the last + ret = LOS_TaskCreate(&g_sz[i], &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + TestAssertBusyTaskDelay(100, LOSCFG_KERNEL_CORE_NUM); // 100, Set the timeout of runtime + ICUNIT_GOTO_EQUAL(g_testCount, LOSCFG_KERNEL_CORE_NUM, g_testCount, EXIT); + + ret = LOS_SemPost(g_semID); // post sem before 10 ticks timeout + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, LOSCFG_KERNEL_CORE_NUM * 3); // 100, Set the timeout of runtime; LOSCFG_KERNEL_CORE_NUM * 3, test running count + ICUNIT_GOTO_EQUAL(g_testCount, LOSCFG_KERNEL_CORE_NUM * 3, g_testCount, EXIT); // 3, Here, assert that g_testCount is equal to + +EXIT: + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + LOS_TaskDelete(g_sz[i]); + } + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosSem032(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosSem032", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_033.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_033.c new file mode 100644 index 00000000..b0f17877 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_033.c @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 4, g_testCount); // 4, Here, assert that g_testCount is equal to + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static VOID TaskF02(VOID) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + // other core get the sem first; 2, Here, assert that g_testCount is equal to + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid, i, uvIntSave; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_sem_033_task2", TaskF02, TASK_PRIO_TEST - 1, CPUID_TO_AFFI_MASK(currCpuid)); + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 1); // 100, Set the timeout of runtime; + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); // let the task f02 pend sem first + + TestBusyTaskDelay(10); // let the task f02 todo pend 10, delay enouge time + + ret = OS_TCB_FROM_TID(g_testTaskID02)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_PEND, 0, ret, EXIT); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_sem_033_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to + + LOS_TaskLock(); + + ret = LOS_SemPost(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(200, 3); // 200, Set the timeout of runtime; 3, test running count + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT1); // 3, Here, assert that g_testCount is equal to + + ret = LOS_SemPost(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT1); // 3, not schedule in current cpu cause tasklock + + LOS_AtomicInc(&g_testCount); + + LOS_TaskUnlock(); + + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); // 5, Here, assert that g_testCount is equal to + +EXIT: + + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +EXIT1: + LOS_TaskUnlock(); + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosSem033(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosSem033", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_034.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_034.c new file mode 100644 index 00000000..2704d2e6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_034.c @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static volatile UINT32 g_runFlag = 1; + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + PRINT_DEBUG("task f01 pend begin\n"); + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + PRINT_DEBUG("task f01 pend success\n"); + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 3, g_testCount); // 3, Here, assert that g_testCount is equal to + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static VOID TaskF02(VOID) +{ + UINT32 ret, uvIntSave; + + LOS_AtomicInc(&g_testCount); + + PRINT_DEBUG("task f02 lock\n"); + + LOS_TaskLock(); // task lock on other cpu + + do { + __asm__ volatile("nop"); + } while (g_runFlag == 1); + + PRINT_DEBUG("task f02 unlock\n"); + LOS_TaskUnlock(); // schedule occur ---switch to task f01 + PRINT_DEBUG("task f02 back\n"); + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 4, g_testCount); // 4, Here, assert that g_testCount is equal to + + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid, i; + TSK_INIT_PARAM_S testTask; + + g_testCount = 0; + g_runFlag = 1; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_sem_034_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_sem_034_task2", TaskF02, TASK_PRIO_TEST, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestAssertBusyTaskDelay(100, 2); // 100, Set the timeout of runtime; 2, test running count + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to + + PRINT_DEBUG("sem post\n"); + ret = LOS_SemPost(g_semID); // try to wake task f01 + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(10); // 10, delay enough time for other cpu + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert that g_testCount is equal to // cause tasklock on other cpu ,so task f01 wake failed + + LOS_AtomicInc(&g_testCount); + + PRINT_DEBUG("try to unlock\n"); + + g_runFlag = 0; // unlock the other cpu + LOS_TaskDelay(10); // 10, delay enouge time + + PRINT_DEBUG("finally\n"); + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, Here, assert that g_testCount is equal to // not schedule in current cpu cause tasklock + +EXIT: + + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; +} + +VOID ItSmpLosSem034(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosSem034", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_035.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_035.c new file mode 100644 index 00000000..d970352d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_035.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID TaskF01(VOID) +{ + UINT32 ret, i; + + LOS_AtomicInc(&g_testCount); + + for (i = 0; i < TRandom() % 500; i++) { // Gets a random value of 0-500 + } + + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + LOS_AtomicInc(&g_testCount); + + do { + __asm__ volatile("nop"); + } while (1); + + TestDumpCpuid(); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid, i, j; + TSK_INIT_PARAM_S testTask; + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + for (i = 0; i < LOOP; i++) { + g_testCount = 0; + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_sem_035_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + do { + __asm__ volatile("nop"); + } while (g_testCount == 0); // wait for task f01 run + + for (j = 0; j < TRandom() % 500; j++) { // Gets a random value of 0-500 + } + + ret = LOS_TaskDelete(g_testTaskID01); + if (ret != LOS_OK && ret != LOS_ERRNO_TSK_MP_SYNC_FAILED) { + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + + LOS_TaskDelay(10); // 10, delay enouge time + + ret = LOS_SemPost(g_semID); // try to wake task f01 + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(10); // 10, delay enouge time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_EQUAL(ret, OS_TASK_STATUS_UNUSED, ret, EXIT); + + ret = LOS_SemDelete(g_semID); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + } + +EXIT: + + LOS_TaskDelete(g_testTaskID01); + LOS_SemDelete(g_semID); + return LOS_OK; +} + +VOID ItSmpLosSem035(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosSem035", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_036.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_036.c new file mode 100644 index 00000000..9730450e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_base/ipc/sem/smp/It_smp_los_sem_036.c @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "It_los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_ret = 0xff; + +static VOID TaskF01(VOID) +{ + UINT32 ret; + + LOS_AtomicInc(&g_testCount); + + ret = LOS_SemPend(g_semID, LOS_WAIT_FOREVER); // pend on current cpu + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} + +static VOID TaskF02(VOID) +{ + UINT32 ret, i; + + LOS_AtomicInc(&g_testCount); + + do { + __asm__ volatile("nop"); + } while (g_testCount == 2); // 2, wait for test task + + for (i = 0; i < TRandom() % 100; i++) { // Gets a random value of 0-100 + } + + ret = LOS_SemPost(g_semID); // try to wake task f01 + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + TestDumpCpuid(); + LOS_AtomicInc(&g_testCount); + return; +} +static UINT32 Testcase(VOID) +{ + UINT32 ret, currCpuid, i, j; + TSK_INIT_PARAM_S testTask; + + currCpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); + + for (i = 0; i < LOOP; i++) { + g_testCount = 0; + g_ret = 0xff; + + ret = LOS_SemCreate(0, &g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_smp_event_037_task1", TaskF01, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(ArchCurrCpuid())); // current cpu + ret = LOS_TaskCreate(&g_testTaskID01, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_PEND, 0, ret, EXIT); + + TEST_TASK_PARAM_INIT_AFFI(testTask, "it_smp_event_037_task2", TaskF02, TASK_PRIO_TEST - 1, + CPUID_TO_AFFI_MASK(currCpuid)); // other cpu + ret = LOS_TaskCreate(&g_testTaskID02, &testTask); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + do { + __asm__ volatile("nop"); + } while (g_testCount == 1); // wait for task f02 + + LOS_AtomicInc(&g_testCount); + + for (j = 0; j < TRandom() % 500; j++) { // Gets a random value of 0-500 + } + + ret = LOS_TaskDelete(g_testTaskID01); + g_ret = ret; + + LOS_TaskDelay(10); // 10, delay enouge time + + ret = OS_TCB_FROM_TID(g_testTaskID01)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_UNUSED, 0, ret, EXIT); + + PRINT_DEBUG("g_testCount = %d ,g_ret = 0x%x\n", g_testCount, g_ret); + if (g_testCount == 4) { // 4, wait for task flag + ICUNIT_GOTO_EQUAL(g_ret, LOS_OK, g_ret, EXIT); + } else if (g_testCount == 5) { // 5, wait for task flag + ICUNIT_GOTO_EQUAL(g_ret, LOS_ERRNO_TSK_NOT_CREATED, g_ret, EXIT); + } else { + ICUNIT_GOTO_EQUAL(1, 0, g_ret, EXIT); + } + + ret = OS_TCB_FROM_TID(g_testTaskID02)->taskStatus; + ICUNIT_GOTO_NOT_EQUAL(ret & OS_TASK_STATUS_UNUSED, 0, ret, EXIT); + + ret = LOS_SemDelete(g_semID); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + } + +EXIT: + + LOS_TaskDelete(g_testTaskID01); + LOS_TaskDelete(g_testTaskID02); + LOS_SemDelete(g_semID); + return LOS_OK; +} + +VOID ItSmpLosSem036(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItSmpLosSem036", Testcase, TEST_LOS, TEST_SEM, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/BUILD.gn b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/BUILD.gn new file mode 100644 index 00000000..940980df --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/BUILD.gn @@ -0,0 +1,47 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +static_library("test_cpup") { + sources = [ "It_extend_cpup.c" ] + + if (LOSCFG_TEST_SMOKE) { + sources += [ + "smoke/It_extend_cpup_001.c", + "smoke/It_extend_cpup_002.c", + ] + } + + include_dirs = [ + "../../../include/", + "./", + "../../../../kernel/extended/include", + ] + + cflags = [ "-Wno-error" ] +} diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/It_extend_cpup.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/It_extend_cpup.c new file mode 100644 index 00000000..ec095e56 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/It_extend_cpup.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_extend_cpup.h" + +UINT32 GetNopCount(void) +{ + return LOS_CyclePerTickGet(); +} + +#ifdef LOSCFG_CPUP_INCLUDE_IRQ + +CPUP_INFO_S g_testPstHwiCpupAll[OS_HWI_MAX_NUM]; +CPUP_INFO_S g_testPstHwiCpup10s[OS_HWI_MAX_NUM]; +CPUP_INFO_S g_testPstHwiCpup1s[OS_HWI_MAX_NUM]; + +UINT32 TestGetSingleHwiCpup(UINT32 hwi, UINT32 mode) +{ + UINT32 size; + UINT32 tempHwi; + if (hwi > OS_HWI_MAX_NUM) { + return -1; + } + + size = sizeof(CPUP_INFO_S) * LOS_GetSystemHwiMaximum(); + switch (mode) { + case CPUP_LAST_ONE_SECONDS: + (VOID)memset_s((VOID *)g_testPstHwiCpup1s, size, 0, size); + (VOID)LOS_GetAllIrqCpuUsage(CPUP_LAST_ONE_SECONDS, g_testPstHwiCpup1s, size); + tempHwi = g_testPstHwiCpup1s[hwi].usage; + break; + case CPUP_LAST_TEN_SECONDS: + (VOID)memset_s((VOID *)g_testPstHwiCpup10s, size, 0, size); + (VOID)LOS_GetAllIrqCpuUsage(CPUP_LAST_TEN_SECONDS, g_testPstHwiCpup10s, size); + tempHwi = g_testPstHwiCpup10s[hwi].usage; + break; + case CPUP_ALL_TIME: + /* fall-through */ + default: + (VOID)memset_s((VOID *)g_testPstHwiCpupAll, size, 0, size); + (VOID)LOS_GetAllIrqCpuUsage(CPUP_ALL_TIME, g_testPstHwiCpupAll, size); + tempHwi = g_testPstHwiCpupAll[hwi].usage; + break; + } + return tempHwi; +} +#endif + + +VOID ItSuiteExtendCpup(VOID) +{ +#if defined(LOSCFG_TEST_SMOKE) + ItExtendCpup001(); + ItExtendCpup002(); +#endif + +#if defined(LOSCFG_TEST_FULL) + ItExtendCpup003(); + ItExtendCpup004(); + ItExtendCpup005(); + ItExtendCpup006(); + ItExtendCpup007(); + ItExtendCpup008(); + ItExtendCpup011(); + ItExtendCpup012(); +#endif + +#if defined(LOSCFG_TEST_LLT) + LltExtendCpup003(); + ItExtendCpup009(); + ItExtendCpup010(); +#endif + +#ifdef LOSCFG_KERNEL_SMP + ItSmpExtendCpup001(); + ItSmpExtendCpup002(); +#ifdef LOSCFG_CPUP_INCLUDE_IRQ + ItSmpExtendCpup003(); + ItSmpExtendCpup004(); +#endif + ItSmpExtendCpup005(); + ItSmpExtendCpup007(); + ItSmpExtendCpup008(); + ItSmpExtendCpup009(); + ItSmpExtendCpup010(); + ItSmpExtendCpup011(); + ItSmpExtendCpup012(); +#endif +} diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/It_extend_cpup.h b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/It_extend_cpup.h new file mode 100644 index 00000000..7a4d8eea --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/It_extend_cpup.h @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IT_LOS_CPUP_H +#define IT_LOS_CPUP_H + +#include "los_cpup_pri.h" +#include "los_cpup.h" +#include "los_sys.h" +#include "los_task.h" +#include "osTest.h" + +#ifdef __cplusplus +#if __cplusplus + extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#define CPU_USE_MODE1 1 +#define CPU_USE_MODE0 0 +#define CPU_USE_MIN 0 +#define TASK_STATUS_UNDETACHED 0 + +#define CPUP_TEST_TOLERANT 50 +#define CPUP_BACKWARD 2 + +#define ICUNIT_ASSERT_PROCESS_CPUP_USAGE(usage, lable) \ + do { \ + UINT32 ret_ = LOS_NOK; \ + if (((usage) > LOS_CPUP_PRECISION) || ((usage) < CPU_USE_MIN)) { \ + ret_ = LOS_OK; \ + } else { \ + ret_ = usage; \ + } \ + ICUNIT_GOTO_EQUAL(ret_, LOS_OK, ret_, lable); \ + } while (0) + +#define ICUNIT_ASSERT_SINGLE_CPUP_USAGE(usage, lable) \ + do { \ + UINT32 ret_ = LOS_NOK; \ + if (((usage) > LOS_CPUP_SINGLE_CORE_PRECISION) || ((usage) < CPU_USE_MIN)) { \ + ret_ = LOS_OK; \ + } else { \ + ret_ = usage; \ + } \ + ICUNIT_GOTO_EQUAL(ret_, LOS_OK, ret_, lable); \ + } while (0) + +extern UINT32 g_cpuTestTaskID; +extern UINT32 g_testTaskID01; +extern UINT32 g_testTaskID02; +extern UINT32 g_testTaskID03; +extern UINT32 g_cpupTestCount; +extern VOID ItSuiteExtendCpup(VOID); +extern UINT32 TimeClkRead(VOID); +extern LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdCpup(INT32 argc, CHAR **argv); +extern LITE_OS_SEC_TEXT_MINOR VOID OsTaskCycleEnd(VOID); +extern LITE_OS_SEC_TEXT_MINOR UINT64 OsGetCpuCycle(VOID); + +extern UINT32 GetNopCount(void); +#ifdef LOSCFG_CPUP_INCLUDE_IRQ +extern UINT32 TestGetSingleHwiCpup(UINT32 hwi, UINT32 mode); +#endif + +#if defined(LOSCFG_TEST_SMOKE) +VOID ItExtendCpup001(VOID); +VOID ItExtendCpup002(VOID); +#endif + +#if defined(LOSCFG_TEST_FULL) +VOID ItExtendCpup003(VOID); +VOID ItExtendCpup004(VOID); +VOID ItExtendCpup005(VOID); +VOID ItExtendCpup006(VOID); +VOID ItExtendCpup007(VOID); +VOID ItExtendCpup008(VOID); +VOID ItExtendCpup011(VOID); +VOID ItExtendCpup012(VOID); +#endif + +#if defined(LOSCFG_TEST_LLT) +VOID LLT_EXTEND_CPUP_001(VOID); +VOID LLT_EXTEND_CPUP_002(VOID); +VOID LltExtendCpup003(VOID); +VOID LLT_EXTEND_CPUP_006(VOID); +VOID LLT_EXTEND_CPUP_007(VOID); +VOID ItExtendCpup009(VOID); +VOID ItExtendCpup010(VOID); +#endif + +#ifdef LOSCFG_KERNEL_SMP +VOID ItSmpExtendCpup001(VOID); +VOID ItSmpExtendCpup002(VOID); +#ifdef LOSCFG_CPUP_INCLUDE_IRQ +VOID ItSmpExtendCpup003(VOID); +VOID ItSmpExtendCpup004(VOID); +#endif +VOID ItSmpExtendCpup005(VOID); +VOID ItSmpExtendCpup006(VOID); +VOID ItSmpExtendCpup007(VOID); +VOID ItSmpExtendCpup008(VOID); +VOID ItSmpExtendCpup009(VOID); +VOID ItSmpExtendCpup010(VOID); +VOID ItSmpExtendCpup011(VOID); +VOID ItSmpExtendCpup012(VOID); +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#endif diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/Makefile b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/Makefile new file mode 100644 index 00000000..dd4b11d9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/Makefile @@ -0,0 +1,40 @@ + +include $(LITEOSTESTTOPDIR)/config.mk + +MODULE_NAME := cpuptest + +LOCAL_INCLUDE := \ + -I $(LITEOSTESTTOPDIR)/kernel/include \ + -I $(LITEOSTESTTOPDIR)/kernel/sample/kernel_extend/cpup \ + -I $(LITEOSTOPDIR)/kernel/extended/include/ + +SRC_MODULES := . + +ifeq ($(LOSCFG_KERNEL_SMP), y) +SMP_MODULES := smp +endif + +ifeq ($(LOSCFG_TEST_LLT), y) +LLT_MODULES := llt +endif + +ifeq ($(LOSCFG_TEST_PRESSURE), y) +PRESSURE_MODULES := pressure +endif + +ifeq ($(LOSCFG_TEST_SMOKE), y) +SMOKE_MODULES := smoke +endif + +ifeq ($(LOSCFG_TEST_FULL), y) +FULL_MODULES := full +endif + +LOCAL_MODULES := $(SRC_MODULES) $(SMOKE_MODULES) $(FULL_MODULES) $(SMP_MODULES) $(LLT_MODULES) + +LOCAL_SRCS := $(foreach dir,$(LOCAL_MODULES),$(wildcard $(dir)/*.c)) +LOCAL_CHS := $(foreach dir,$(LOCAL_MODULES),$(wildcard $(dir)/*.h)) + +LOCAL_FLAGS := $(LOCAL_INCLUDE) -Wno-error + +include $(MODULE) diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/full/It_extend_cpup_003.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/full/It_extend_cpup_003.c new file mode 100644 index 00000000..cffe4dba --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/full/It_extend_cpup_003.c @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_extend_cpup.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 TaskF02(VOID) +{ + UINT32 cpupUse, ret; + g_testTaskID02 = LOS_GetCurrProcessID(); + + ret = LOS_SetProcessPriority(g_testTaskID02, TASK_PRIO_TEST - 1); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_EQUAL(g_cpupTestCount, 2, g_cpupTestCount); // 2, Here, assert that g_cpupTestCount is equal to the expected value. + g_cpupTestCount++; + cpupUse = LOS_HistoryProcessCpuUsage(g_testTaskID01, CPUP_ALL_TIME); + if (cpupUse > LOS_CPUP_PRECISION || cpupUse < CPU_USE_MIN) { + ret = LOS_NOK; + } else { + ret = LOS_OK; + } + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + cpupUse = LOS_HistoryProcessCpuUsage(g_testTaskID02, CPUP_ALL_TIME); + if (cpupUse > LOS_CPUP_PRECISION || cpupUse < CPU_USE_MIN) { + ret = LOS_NOK; + } else { + ret = LOS_OK; + } + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + LOS_TaskDelay(3); // 3, set delay time. + + ICUNIT_ASSERT_EQUAL(g_cpupTestCount, 4, g_cpupTestCount); // 4, Here, assert that g_cpupTestCount is equal to the expected value. + g_cpupTestCount++; + + return LOS_OK; + +EXIT: + return ret; +} + +static UINT32 TaskF01(VOID) +{ + UINT32 cpupUse, ret; + g_testTaskID01 = LOS_GetCurrProcessID(); + + // 2, used to calculate the task priority. + ret = LOS_SetProcessPriority(g_testTaskID01, TASK_PRIO_TEST - 2); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_EQUAL(g_cpupTestCount, 0, g_cpupTestCount); + g_cpupTestCount++; + + cpupUse = LOS_HistorySysCpuUsage(CPUP_ALL_TIME); + if (cpupUse > LOS_CPUP_PRECISION || cpupUse < CPU_USE_MIN) { + ret = LOS_NOK; + } else { + ret = LOS_OK; + } + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + LOS_TaskDelay(4); // 4, set delay time. + + ICUNIT_ASSERT_EQUAL(g_cpupTestCount, 3, g_cpupTestCount); // 3, Here, assert that g_cpupTestCount is equal to the expected value. + g_cpupTestCount++; + + return LOS_OK; + +EXIT: + return ret; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, cpupUse; + INT32 pid1; + + g_cpupTestCount = 0; + INT32 pid = LOS_Fork(0, "TestCpupTsk1", TaskF01, TASK_STACK_SIZE_TEST); + if (pid < 0) { + ICUNIT_ASSERT_EQUAL(1, LOS_OK, 1); + } + + LOS_TaskDelay(2); // 2, set delay time. + + ICUNIT_ASSERT_EQUAL(g_cpupTestCount, 1, g_cpupTestCount); + g_cpupTestCount++; + + pid1 = LOS_Fork(0, "TestCpupTsk2", TaskF02, TASK_STACK_SIZE_TEST); + if (pid1 < 0) { + ICUNIT_ASSERT_EQUAL(1, LOS_OK, 1); + } + + LOS_TaskDelay(2); // 2, set delay time. + + cpupUse = LOS_HistorySysCpuUsage(CPUP_ALL_TIME); + if (cpupUse > LOS_CPUP_PRECISION || cpupUse < CPU_USE_MIN) { + ret = LOS_NOK; + } else { + ret = LOS_OK; + } + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + cpupUse = LOS_HistorySysCpuUsage(CPU_USE_MODE1); + if (cpupUse > LOS_CPUP_PRECISION || cpupUse < CPU_USE_MIN) { + ret = LOS_NOK; + } else { + ret = LOS_OK; + } + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + LOS_TaskDelay(3); // 3, set delay time. + + ICUNIT_ASSERT_EQUAL(g_cpupTestCount, 5, g_cpupTestCount); // 5, Here, assert that g_cpupTestCount is equal to the expected value. + + (VOID)LOS_Wait(pid, NULL, 0, NULL); + (VOID)LOS_Wait(pid1, NULL, 0, NULL); + + return LOS_OK; +EXIT: + return ret; +} + +VOID ItExtendCpup003(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItExtendCpup003", Testcase, TEST_EXTEND, TEST_CPUP, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/full/It_extend_cpup_004.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/full/It_extend_cpup_004.c new file mode 100644 index 00000000..2643a713 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/full/It_extend_cpup_004.c @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_extend_cpup.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 TaskF02(VOID) +{ + UINT32 cpupUse, ret; + ICUNIT_ASSERT_EQUAL(g_cpupTestCount, 2, g_cpupTestCount); // 2, Here, assert that g_cpupTestCount is equal to the expected value. + g_cpupTestCount++; + + cpupUse = LOS_HistoryProcessCpuUsage(LOS_GetCurrProcessID(), CPUP_ALL_TIME); + if (cpupUse > LOS_CPUP_PRECISION || cpupUse < CPU_USE_MIN) { + ret = LOS_NOK; + } else { + ret = LOS_OK; + } + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskDelete(g_testTaskID02); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; + +EXIT: + ret = LOS_TaskDelete(g_testTaskID02); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return ret; +} + +static UINT32 TaskF01(VOID) +{ + UINT32 ret, cpupUse; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "TestCpupTsk2"; + task1.usTaskPrio = TASK_PRIO_TEST - 1; // 1, used to calculate the task priority. + task1.uwResved = TASK_STATUS_UNDETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ICUNIT_ASSERT_EQUAL(g_cpupTestCount, 0, g_cpupTestCount); + g_cpupTestCount++; + + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_cpupTestCount, 1, g_cpupTestCount); + g_cpupTestCount++; + + cpupUse = LOS_HistoryProcessCpuUsage(LOS_GetCurrProcessID(), CPUP_ALL_TIME); + if (cpupUse > LOS_CPUP_PRECISION || cpupUse < CPU_USE_MIN) { + ret = LOS_NOK; + } else { + ret = LOS_OK; + } + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return LOS_OK; + +EXIT: + return ret; +} +static UINT32 Testcase(VOID) +{ + UINT32 ret, cpupUse; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "TestCpupTsk1"; + task1.usTaskPrio = TASK_PRIO_TEST - 2; // 2, used to calculate the task priority. + task1.uwResved = TASK_STATUS_UNDETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_cpupTestCount = 0; + + cpupUse = LOS_HistorySysCpuUsage(CPUP_ALL_TIME); + if (cpupUse > LOS_CPUP_PRECISION || cpupUse < CPU_USE_MIN) { + ret = LOS_NOK; + } else { + ret = LOS_OK; + } + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_cpupTestCount, 3, g_cpupTestCount); // 3, Here, assert that g_cpupTestCount is equal to the expected value. + g_cpupTestCount++; + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; + +EXIT: + return ret; +} + +VOID ItExtendCpup004(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItExtendCpup004", Testcase, TEST_EXTEND, TEST_CPUP, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/full/It_extend_cpup_005.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/full/It_extend_cpup_005.c new file mode 100644 index 00000000..2e80bad8 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/full/It_extend_cpup_005.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_extend_cpup.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 TaskF01(VOID) +{ + UINT32 cpupUse, ret; + g_cpupTestCount++; + + cpupUse = LOS_HistoryProcessCpuUsage(LOS_GetCurrProcessID(), CPUP_ALL_TIME); + if (cpupUse > LOS_CPUP_PRECISION || cpupUse < CPU_USE_MIN) { + ret = LOS_NOK; + } else { + ret = LOS_OK; + } + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + cpupUse = LOS_HistoryProcessCpuUsage(LOS_GetCurrProcessID(), CPU_USE_MODE1); + if (cpupUse > LOS_CPUP_PRECISION || cpupUse < CPU_USE_MIN) { + ret = LOS_NOK; + } else { + ret = LOS_OK; + } + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; + +EXIT: + ret = LOS_TaskDelete(g_testTaskID01); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return ret; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "TskTst1"; + task1.usTaskPrio = TASK_PRIO_TEST - 1; // 1, used to calculate the task priority. + task1.uwResved = TASK_STATUS_UNDETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_cpupTestCount = 0; + + LOS_TaskLock(); + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL(g_cpupTestCount, 0, g_cpupTestCount); + + LOS_TaskUnlock(); + + ICUNIT_ASSERT_EQUAL(g_cpupTestCount, 1, g_cpupTestCount); // 1, Here, assert that g_cpupTestCount is equal to the expected value. + + return LOS_OK; +} + +VOID ItExtendCpup005(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItExtendCpup005", Testcase, TEST_EXTEND, TEST_CPUP, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/full/It_extend_cpup_006.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/full/It_extend_cpup_006.c new file mode 100644 index 00000000..152f2e29 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/full/It_extend_cpup_006.c @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_extend_cpup.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 TaskF02(VOID) +{ + UINT32 ret, cpupUse; + + ICUNIT_ASSERT_EQUAL(g_cpupTestCount, 2, g_cpupTestCount); // 2, Here, assert that g_cpupTestCount is equal to the expected value. + g_cpupTestCount++; + + cpupUse = LOS_HistoryProcessCpuUsage(g_testTaskID01, CPUP_ALL_TIME); + if (cpupUse > LOS_CPUP_PRECISION || cpupUse < CPU_USE_MIN) { + ret = LOS_NOK; + } else { + ret = LOS_OK; + } + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = LOS_TaskDelete(g_testTaskID02); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return LOS_OK; + +EXIT: + ret = LOS_TaskDelete(g_testTaskID02); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + return ret; +} + +static VOID TaskF01(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "TskTst2"; + task1.usTaskPrio = TASK_PRIO_TEST - 1; // 1, used to calculate the task priority. + task1.uwResved = TASK_STATUS_UNDETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ICUNIT_ASSERT_EQUAL_VOID(g_cpupTestCount, 0, g_cpupTestCount); + g_cpupTestCount++; + + g_testTaskID01 = LOS_GetCurrProcessID(); + + ret = LOS_GetTaskScheduler(LOS_CurTaskIDGet()); + // 2, used to calculate the task priority. + ret = LOS_SetTaskScheduler(LOS_CurTaskIDGet(), ret, TASK_PRIO_TEST - 2); + ICUNIT_ASSERT_EQUAL_VOID(ret, 0, ret); + + ret = LOS_TaskCreate(&g_testTaskID02, &task1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ICUNIT_ASSERT_EQUAL_VOID(g_cpupTestCount, 1, g_cpupTestCount); + g_cpupTestCount++; + + LOS_TaskDelay(30); // 30, set delay time. + + ICUNIT_ASSERT_EQUAL_VOID(g_cpupTestCount, 3, g_cpupTestCount); // 3, Here, assert that g_cpupTestCount is equal to the expected value. + g_cpupTestCount++; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, cpupUse; + TSK_INIT_PARAM_S task1 = { 0 }; + + cpupUse = LOS_HistorySysCpuUsage(CPUP_ALL_TIME); + if (cpupUse > LOS_CPUP_PRECISION || cpupUse < CPU_USE_MIN) { + ret = LOS_NOK; + } else { + ret = LOS_OK; + } + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "TskTst1"; + task1.usTaskPrio = TASK_PRIO_TEST - 2; // 2, used to calculate the task priority. + task1.uwResved = TASK_STATUS_UNDETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_cpupTestCount = 0; + INT32 pid = LOS_Fork(0, "TestCpupTsk1", TaskF01, TASK_STACK_SIZE_TEST); + if (pid < 0) { + ICUNIT_ASSERT_EQUAL(1, LOS_OK, 1); + } + + ret = LOS_Wait(pid, NULL, 0, NULL); + ICUNIT_ASSERT_EQUAL(pid, ret, pid); + + ICUNIT_ASSERT_EQUAL(g_cpupTestCount, 4, g_cpupTestCount); // 4, Here, assert that g_cpupTestCount is equal to the expected value. + + cpupUse = LOS_HistorySysCpuUsage(CPU_USE_MODE1); + if (cpupUse > LOS_CPUP_PRECISION || cpupUse < CPU_USE_MIN) { + ret = LOS_NOK; + } else { + ret = LOS_OK; + } + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return LOS_OK; + +EXIT: + return ret; +} + +VOID ItExtendCpup006(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItExtendCpup006", Testcase, TEST_EXTEND, TEST_CPUP, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/full/It_extend_cpup_007.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/full/It_extend_cpup_007.c new file mode 100644 index 00000000..75e64592 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/full/It_extend_cpup_007.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_extend_cpup.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret, cpupUse; + + cpupUse = LOS_HistorySysCpuUsage(CPU_USE_MODE0); + if (cpupUse > LOS_CPUP_PRECISION || cpupUse < CPU_USE_MIN) { + ret = LOS_NOK; + } else { + ret = LOS_OK; + } + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + cpupUse = LOS_HistorySysCpuUsage(CPU_USE_MODE1); + if (cpupUse > LOS_CPUP_PRECISION || cpupUse < CPU_USE_MIN) { + ret = LOS_NOK; + } else { + ret = LOS_OK; + } + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + // 2, used to test history func. + cpupUse = LOS_HistorySysCpuUsage(-2); + if (cpupUse > LOS_CPUP_PRECISION || cpupUse < CPU_USE_MIN) { + ret = LOS_NOK; + } else { + ret = LOS_OK; + } + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + cpupUse = LOS_HistorySysCpuUsage(0xFFFF); + if (cpupUse > LOS_CPUP_PRECISION || cpupUse < CPU_USE_MIN) { + ret = LOS_NOK; + } else { + ret = LOS_OK; + } + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + return LOS_OK; +} + +VOID ItExtendCpup007(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItExtendCpup007", Testcase, TEST_EXTEND, TEST_CPUP, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/full/It_extend_cpup_008.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/full/It_extend_cpup_008.c new file mode 100644 index 00000000..45188fd0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/full/It_extend_cpup_008.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_extend_cpup.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 TaskF01(VOID) +{ + UINT32 cpupUse, ret; + + ICUNIT_ASSERT_EQUAL(g_cpupTestCount, 0, g_cpupTestCount); + g_cpupTestCount++; + + cpupUse = LOS_HistoryProcessCpuUsage(LOS_GetCurrProcessID(), CPUP_ALL_TIME); + if (cpupUse > LOS_CPUP_PRECISION || cpupUse < CPU_USE_MIN) { + ret = LOS_NOK; + } else { + ret = LOS_OK; + } + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + cpupUse = LOS_HistoryProcessCpuUsage(g_taskMaxNum, CPUP_ALL_TIME); + ICUNIT_GOTO_NOT_EQUAL(cpupUse, LOS_OK, cpupUse, EXIT); + + ICUNIT_ASSERT_EQUAL(g_cpupTestCount, 1, g_cpupTestCount); + g_cpupTestCount++; + + return LOS_OK; +EXIT: + return ret; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret, cpupUse; + TSK_INIT_PARAM_S task1 = { 0 }; + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task1.uwStackSize = TASK_STACK_SIZE_TEST; + task1.pcName = "TestCpupTsk1"; + task1.usTaskPrio = TASK_PRIO_TEST - 2; // 2, used to calculate the task priority. + task1.uwResved = TASK_STATUS_UNDETACHED; +#ifdef LOSCFG_KERNEL_SMP + task1.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + g_cpupTestCount = 0; + + ret = LOS_TaskCreate(&g_testTaskID01, &task1); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ICUNIT_ASSERT_EQUAL(g_cpupTestCount, 2, g_cpupTestCount); // 2, Here, assert that g_cpupTestCount is equal to the expected value. +EXIT: + LOS_TaskDelete(g_testTaskID01); + return LOS_OK; +} + +VOID ItExtendCpup008(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItExtendCpup008", Testcase, TEST_EXTEND, TEST_CPUP, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/full/It_extend_cpup_011.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/full/It_extend_cpup_011.c new file mode 100644 index 00000000..baf3df0a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/full/It_extend_cpup_011.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_extend_cpup.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 loop; + UINT32 ret, cpupUse; + UINT32 systemProcessNumber = LOS_GetSystemProcessMaximum(); + UINT32 cpupInfoLen; + CPUP_INFO_S *cpup = NULL; + +#ifdef LOSCFG_CPUP_INCLUDE_IRQ + UINT32 systemIrqNumber = LOS_GetSystemHwiMaximum(); + cpupInfoLen = systemIrqNumber * sizeof(CPUP_INFO_S); + cpup = (CPUP_INFO_S *)LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, cpupInfoLen); + if (cpup == NULL) { + PRINTK("%s[%d] malloc failure!\n", __FUNCTION__, __LINE__); + return OS_ERROR; + } + + ret = LOS_GetAllIrqCpuUsage(CPUP_LAST_ONE_SECONDS, cpup, cpupInfoLen); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + for (loop = 0; loop < systemIrqNumber; loop++) { + ICUNIT_ASSERT_SINGLE_CPUP_USAGE(cpup[loop].usage, EXIT1); + } + + ret = LOS_GetAllIrqCpuUsage(CPUP_LAST_TEN_SECONDS, cpup, cpupInfoLen); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + for (loop = 0; loop < systemIrqNumber; loop++) { + ICUNIT_ASSERT_SINGLE_CPUP_USAGE(cpup[loop].usage, EXIT1); + } + + ret = LOS_GetAllIrqCpuUsage(CPUP_ALL_TIME, cpup, cpupInfoLen); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + for (loop = 0; loop < systemIrqNumber; loop++) { + ICUNIT_ASSERT_SINGLE_CPUP_USAGE(cpup[loop].usage, EXIT1); + } + + LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, cpup); + cpup = NULL; +#endif + + cpupInfoLen = systemProcessNumber * sizeof(CPUP_INFO_S); + cpup = (CPUP_INFO_S *)LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, cpupInfoLen); + if (cpup == NULL) { + PRINTK("%s[%d] malloc failure!\n", __FUNCTION__, __LINE__); + return OS_ERROR; + } + + ret = LOS_GetAllProcessCpuUsage(CPUP_LAST_ONE_SECONDS, cpup, cpupInfoLen); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + for (loop = 0; loop < systemProcessNumber; loop++) { + ICUNIT_ASSERT_PROCESS_CPUP_USAGE(cpup[loop].usage, EXIT1); + } + + ret = LOS_GetAllProcessCpuUsage(CPUP_LAST_TEN_SECONDS, cpup, cpupInfoLen); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + for (loop = 0; loop < systemProcessNumber; loop++) { + ICUNIT_ASSERT_PROCESS_CPUP_USAGE(cpup[loop].usage, EXIT1); + } + + ret = LOS_GetAllProcessCpuUsage(CPUP_ALL_TIME, cpup, cpupInfoLen); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + for (loop = 0; loop < systemProcessNumber; loop++) { + ICUNIT_ASSERT_PROCESS_CPUP_USAGE(cpup[loop].usage, EXIT1); + } + + LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, cpup); + cpup = NULL; + +EXIT1: + LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, cpup); + cpup = NULL; + return LOS_OK; +} + +VOID ItExtendCpup011(VOID) +{ + TEST_ADD_CASE("ItExtendCpup011", Testcase, TEST_EXTEND, TEST_CPUP, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/full/It_extend_cpup_012.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/full/It_extend_cpup_012.c new file mode 100644 index 00000000..cc44dee3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/full/It_extend_cpup_012.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_extend_cpup.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#define ICUNIT_ASSERT_CPUP_EQUAL(cpupUse, val) \ + do { \ + if ((cpupUse) > LOS_CPUP_SINGLE_CORE_PRECISION || (cpupUse) < CPU_USE_MIN) { \ + ICUNIT_ASSERT_EQUAL(cpupUse, val, cpupUse); \ + } \ + } while (0) + +static INT32 TaskF01(VOID) +{ + INT32 testCount = 1000; // 1000, set to init testcount. + UINT32 cpupUse; + LOS_Mdelay(5000); // 5000, set delay time. + + const CHAR *taskAll = "-a"; + OsShellCmdDumpTask(1, &taskAll); + + while (testCount > 0) { + cpupUse = LOS_HistoryProcessCpuUsage(LOS_GetCurrProcessID(), CPUP_LAST_TEN_SECONDS); + ICUNIT_ASSERT_CPUP_EQUAL(cpupUse, OS_INVALID_VALUE); + cpupUse = LOS_HistoryProcessCpuUsage(LOS_GetCurrProcessID(), CPUP_LAST_ONE_SECONDS); + ICUNIT_ASSERT_CPUP_EQUAL(cpupUse, OS_INVALID_VALUE); + + cpupUse = LOS_HistorySysCpuUsage(CPU_USE_MODE1); + if ((cpupUse > LOS_CPUP_PRECISION) || (cpupUse < CPU_USE_MIN)) { + ICUNIT_ASSERT_EQUAL(cpupUse, OS_INVALID_VALUE, cpupUse); + } + + testCount--; + } + cpupUse = LOS_HistoryProcessCpuUsage(LOS_GetCurrProcessID(), CPUP_ALL_TIME); + ICUNIT_ASSERT_CPUP_EQUAL(cpupUse, OS_INVALID_VALUE); + + LOS_CpupReset(); + LOS_Mdelay(5000); // 5000, set delay time. + + testCount = 1000; // 1000, set to init testcount. + while (testCount > 0) { + cpupUse = LOS_HistoryProcessCpuUsage(LOS_GetCurrProcessID(), CPUP_LAST_TEN_SECONDS); + ICUNIT_ASSERT_CPUP_EQUAL(cpupUse, OS_INVALID_VALUE); + cpupUse = LOS_HistoryProcessCpuUsage(LOS_GetCurrProcessID(), CPUP_LAST_ONE_SECONDS); + ICUNIT_ASSERT_CPUP_EQUAL(cpupUse, OS_INVALID_VALUE); + + cpupUse = LOS_HistorySysCpuUsage(CPU_USE_MODE1); + if ((cpupUse > LOS_CPUP_PRECISION) || (cpupUse < CPU_USE_MIN)) { + ICUNIT_ASSERT_EQUAL(cpupUse, OS_INVALID_VALUE, cpupUse); + } + testCount--; + } + + cpupUse = LOS_HistoryProcessCpuUsage(LOS_GetCurrProcessID(), CPUP_ALL_TIME); + ICUNIT_ASSERT_CPUP_EQUAL(cpupUse, OS_INVALID_VALUE); + + OsShellCmdDumpTask(1, &taskAll); + +EXIT: + return 0; +} + +static UINT32 Testcase(VOID) +{ + INT32 pid = LOS_Fork(0, "TestCpupProcess", TaskF01, TASK_STACK_SIZE_TEST); + if (pid < 0) { + ICUNIT_ASSERT_EQUAL(1, LOS_OK, 1); + } + + LOS_Wait(pid, 0, 0, 0); + + return LOS_OK; +} + +VOID ItExtendCpup012(VOID) +{ + TEST_ADD_CASE("ItExtendCpup012", Testcase, TEST_EXTEND, TEST_CPUP, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smoke/It_extend_cpup_001.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smoke/It_extend_cpup_001.c new file mode 100644 index 00000000..05f58667 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smoke/It_extend_cpup_001.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_extend_cpup.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 TaskF02(VOID) +{ + UINT32 ret = OS_ERROR, cpupUse; + g_cpupTestCount++; + + // 2, Here, assert that g_cpupTestCount is equal to the expected value. + ICUNIT_GOTO_EQUAL(g_cpupTestCount, 2, g_cpupTestCount, EXIT); + cpupUse = LOS_HistoryProcessCpuUsage(g_testTaskID01, CPUP_ALL_TIME); + if (cpupUse > LOS_CPUP_PRECISION || cpupUse < CPU_USE_MIN) { + ret = LOS_NOK; + } else { + ret = LOS_OK; + } + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + g_cpupTestCount++; + return LOS_OK; + +EXIT: + return ret; +} + +static UINT32 TaskF01(VOID) +{ + UINT32 ret; + INT32 pid; + g_cpupTestCount++; + g_testTaskID01 = LOS_GetCurrProcessID(); + + pid = LOS_Fork(0, "TestCpupTsk2", TaskF02, LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE); + if (pid < 0) { + ICUNIT_ASSERT_EQUAL(1, LOS_OK, 1); + } + + LOS_TaskDelay(10); // 10, set delay time. + g_cpupTestCount++; + (VOID)LOS_Wait(pid, NULL, 0, NULL); + return LOS_OK; + +EXIT: + return ret; +} + +static UINT32 Testcase(VOID) +{ + INT32 pid; + UINT32 ret, cpupUse; + g_cpupTestCount = 0; + + cpupUse = LOS_HistorySysCpuUsage(CPUP_ALL_TIME); + + if (cpupUse > LOS_CPUP_PRECISION || cpupUse < CPU_USE_MIN) { + ret = LOS_NOK; + } else { + ret = LOS_OK; + } + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + pid = LOS_Fork(0, "TestCpupTsk", TaskF01, LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE); + if (pid < 0) { + ICUNIT_ASSERT_EQUAL(1, LOS_OK, 1); + } + + LOS_TaskDelay(10); // 10, set delay time. + (VOID)LOS_Wait(pid, NULL, 0, NULL); + return LOS_OK; +} + + +VOID ItExtendCpup001(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItExtendCpup001", Testcase, TEST_EXTEND, TEST_CPUP, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smoke/It_extend_cpup_002.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smoke/It_extend_cpup_002.c new file mode 100644 index 00000000..6e399ce3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smoke/It_extend_cpup_002.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_extend_cpup.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 TaskF01(VOID) +{ + UINT32 ret = OS_ERROR; + UINT32 cpupUse; + g_cpupTestCount++; + + ICUNIT_GOTO_EQUAL(g_cpupTestCount, 1, g_cpupTestCount, EXIT); + + cpupUse = LOS_HistoryProcessCpuUsage(LOS_GetCurrProcessID(), CPU_USE_MODE0); + if (cpupUse > LOS_CPUP_PRECISION || cpupUse < CPU_USE_MIN) { + ret = LOS_NOK; + } else { + ret = LOS_OK; + } + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + cpupUse = LOS_HistoryProcessCpuUsage(LOS_GetCurrProcessID(), CPU_USE_MODE1); + if (cpupUse > LOS_CPUP_PRECISION || cpupUse < CPU_USE_MIN) { + ret = LOS_NOK; + } else { + ret = LOS_OK; + } + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + cpupUse = LOS_HistoryProcessCpuUsage(LOS_GetCurrProcessID(), CPU_USE_MODE1); + if (cpupUse > LOS_CPUP_PRECISION || cpupUse < CPU_USE_MIN) { + ret = LOS_NOK; + } else { + ret = LOS_OK; + } + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + return LOS_OK; + +EXIT: + return ret; +} + +static UINT32 Testcase(VOID) +{ + INT32 pid; + UINT32 ret, cpupUse; + g_cpupTestCount = 0; + + pid = LOS_Fork(0, "TestCpupTsk", TaskF01, LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE); + if (pid < 0) { + ICUNIT_ASSERT_EQUAL(1, LOS_OK, 1); + } + + cpupUse = LOS_HistorySysCpuUsage(CPU_USE_MODE0); + if (cpupUse > LOS_CPUP_PRECISION || cpupUse < CPU_USE_MIN) { + ret = LOS_NOK; + } else { + ret = LOS_OK; + } + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + cpupUse = LOS_HistorySysCpuUsage(CPU_USE_MODE1); + if (cpupUse > LOS_CPUP_PRECISION || cpupUse < CPU_USE_MIN) { + ret = LOS_NOK; + } else { + ret = LOS_OK; + } + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_Wait(pid, NULL, 0, NULL); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + return LOS_OK; +} + +VOID ItExtendCpup002(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItExtendCpup002", Testcase, TEST_EXTEND, TEST_CPUP, TEST_LEVEL0, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_001.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_001.c new file mode 100644 index 00000000..9832354c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_001.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_extend_cpup.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_testSmpCpupTaskID01, g_testSmpCpupTaskID02; +static volatile UINT32 g_testSmpCpupStop = 0; +static void Task01(void) +{ + while (g_testSmpCpupStop < 1) { + __asm__ volatile("nop"); + } + return; +} +static void Task02(void) +{ + UINT32 tempCpup; + + LOS_TaskDelay(LOSCFG_BASE_CORE_TICK_PER_SECOND * CPUP_BACKWARD); + tempCpup = LOS_HistoryTaskCpuUsage(g_testSmpCpupTaskID01, CPUP_LAST_ONE_SECONDS); + ICUNIT_GOTO_WITHIN_EQUAL(tempCpup, LOS_CPUP_SINGLE_CORE_PRECISION - CPUP_TEST_TOLERANT, + LOS_CPUP_SINGLE_CORE_PRECISION, tempCpup, EXIT2); + +EXIT2: + g_testSmpCpupStop = 1; + + LOS_TaskDelay(LOSCFG_BASE_CORE_TICK_PER_SECOND * CPUP_BACKWARD); + tempCpup = LOS_HistoryTaskCpuUsage(g_testSmpCpupTaskID01, CPUP_LAST_ONE_SECONDS); + ICUNIT_ASSERT_EQUAL_VOID(tempCpup, CPU_USE_MIN, tempCpup); + + return; +} + + +static UINT32 Testcase(VOID) +{ + TSK_INIT_PARAM_S taskInitParam; + UINT32 ret; + + ret = memset_s((void *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Task01; + taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + taskInitParam.pcName = "SmpCpup001_task01"; + taskInitParam.usTaskPrio = TASK_PRIO_TEST - 2; // 2, used to calculate the task priority. +#ifdef LOSCFG_KERNEL_SMP + /* make sure that created test task is definitely on another core */ + UINT32 currCpuid = (ArchCurrCpuid() + 1) % LOSCFG_KERNEL_CORE_NUM; + taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(currCpuid); +#endif + ret = LOS_TaskCreate(&g_testSmpCpupTaskID01, &taskInitParam); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = memset_s((void *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Task02; + taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + taskInitParam.pcName = "SmpCpup001_task02"; + taskInitParam.usTaskPrio = TASK_PRIO_TEST - 1; // 1, used to calculate the task priority. +#ifdef LOSCFG_KERNEL_SMP + taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testSmpCpupTaskID02, &taskInitParam); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EIXT1); + + LOS_TaskDelay(LOSCFG_BASE_CORE_TICK_PER_SECOND * (CPUP_BACKWARD * 2 + 1)); // 2, used to calculate the delay time. + +EIXT1: + LOS_TaskDelete(g_testSmpCpupTaskID02); +EXIT: + LOS_TaskDelete(g_testSmpCpupTaskID01); + + return LOS_OK; +} + +VOID ItSmpExtendCpup001(VOID) +{ + TEST_ADD_CASE("ItSmpExtendCpup001", Testcase, TEST_EXTEND, TEST_CPUP, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_002.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_002.c new file mode 100644 index 00000000..51796a90 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_002.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_extend_cpup.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_testSmpCpupTaskID01; + +static void Task01(void) +{ + UINT32 tempCpup; + /* make sure that created test task is definitely on another core */ + UINT32 currCpuid = (ArchCurrCpuid() + 1) % LOSCFG_KERNEL_CORE_NUM; + UINT32 idleID = g_percpu[currCpuid].idleTaskID; + TSK_INFO_S tempTaskInfo; + + do { + LOS_TaskInfoGet(idleID, &tempTaskInfo); + } while (!(tempTaskInfo.usTaskStatus & OS_TASK_STATUS_RUNNING)); + + tempCpup = LOS_HistoryTaskCpuUsage(idleID, CPUP_ALL_TIME); + ICUNIT_ASSERT_WITHIN_EQUAL_VOID(tempCpup, CPU_USE_MIN, LOS_CPUP_SINGLE_CORE_PRECISION, tempCpup); + + return; +} + + +static UINT32 Testcase(VOID) +{ + TSK_INIT_PARAM_S taskInitParam; + UINT32 ret; + + ret = memset_s((void *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Task01; + taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + taskInitParam.pcName = "SmpCpup002_task01"; + taskInitParam.usTaskPrio = TASK_PRIO_TEST - 1; // 1, used to calculate the task priority. +#ifdef LOSCFG_KERNEL_SMP + taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testSmpCpupTaskID01, &taskInitParam); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + LOS_TaskDelay(LOSCFG_BASE_CORE_TICK_PER_SECOND); + +EXIT: + LOS_TaskDelete(g_testSmpCpupTaskID01); + + return LOS_OK; +} + +VOID ItSmpExtendCpup002(VOID) +{ + TEST_ADD_CASE("ItSmpExtendCpup002", Testcase, TEST_EXTEND, TEST_CPUP, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_003.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_003.c new file mode 100644 index 00000000..5f5f4827 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_003.c @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_extend_cpup.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#ifdef LOSCFG_CPUP_INCLUDE_IRQ +static UINT32 g_testSmpCpupTaskID01, g_testSmpCpupTaskID02; +static volatile UINT32 g_testSmpCpupStop = 0; +static void HwiF01(void) +{ + UINT32 i; + UINT32 count = GetNopCount(); + for (i = 0; i < count; i++) { + __asm__ volatile("nop"); + } +} +static void Task01(void) +{ + UINT32 ret; + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + + while (g_testSmpCpupStop < 1) { + TestHwiTrigger(HWI_NUM_TEST); + } + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(0)); + TEST_HwiDelete(HWI_NUM_TEST); + + return; +} +static void Task02(void) +{ + UINT32 tempCpup; + + tempCpup = TestGetSingleHwiCpup(HWI_NUM_TEST, CPUP_LAST_ONE_SECONDS); + ICUNIT_ASSERT_EQUAL_VOID(tempCpup, CPU_USE_MIN, tempCpup); + + LOS_TaskDelay(LOSCFG_BASE_CORE_TICK_PER_SECOND * CPUP_BACKWARD); + tempCpup = TestGetSingleHwiCpup(HWI_NUM_TEST, CPUP_LAST_ONE_SECONDS); + // 2, used to calculate the input of equal func. + ICUNIT_GOTO_WITHIN_EQUAL(tempCpup, LOS_CPUP_SINGLE_CORE_PRECISION / 2, LOS_CPUP_SINGLE_CORE_PRECISION, tempCpup, + EXIT2); + +EXIT2: + g_testSmpCpupStop = 1; + + LOS_TaskDelay(LOSCFG_BASE_CORE_TICK_PER_SECOND * CPUP_BACKWARD); + tempCpup = TestGetSingleHwiCpup(HWI_NUM_TEST, CPUP_LAST_ONE_SECONDS); + ICUNIT_ASSERT_EQUAL_VOID(tempCpup, CPU_USE_MIN, tempCpup); + + return; +} + + +static UINT32 Testcase(VOID) +{ + TSK_INIT_PARAM_S taskInitParam; + UINT32 ret; + + ret = memset_s((void *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Task01; + taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + taskInitParam.pcName = "SmpCpup003_task01"; + taskInitParam.usTaskPrio = TASK_PRIO_TEST - 2; // 2, used to calculate the task priority. +#ifdef LOSCFG_KERNEL_SMP + /* make sure that created test task is definitely on another core */ + UINT32 currCpuid = (ArchCurrCpuid() + 1) % LOSCFG_KERNEL_CORE_NUM; + taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(currCpuid); +#endif + ret = LOS_TaskCreate(&g_testSmpCpupTaskID01, &taskInitParam); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = memset_s((void *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Task02; + taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + taskInitParam.pcName = "SmpCpup003_task02"; + taskInitParam.usTaskPrio = TASK_PRIO_TEST - 1; // 1, used to calculate the task priority. +#ifdef LOSCFG_KERNEL_SMP + taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testSmpCpupTaskID02, &taskInitParam); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EIXT1); + + LOS_TaskDelay(LOSCFG_BASE_CORE_TICK_PER_SECOND * (CPUP_BACKWARD * 2 + 1)); // 2, used to calculate the delay time. + +EIXT1: + LOS_TaskDelete(g_testSmpCpupTaskID02); +EXIT: + LOS_TaskDelete(g_testSmpCpupTaskID01); + + return LOS_OK; +} +#endif + +VOID ItSmpExtendCpup003(VOID) +{ +#ifdef LOSCFG_CPUP_INCLUDE_IRQ + TEST_ADD_CASE("ItSmpExtendCpup003", Testcase, TEST_EXTEND, TEST_CPUP, TEST_LEVEL2, TEST_FUNCTION); +#endif +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_004.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_004.c new file mode 100644 index 00000000..1dddcf6d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_004.c @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_extend_cpup.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#ifdef LOSCFG_CPUP_INCLUDE_IRQ +static UINT32 g_testSmpCpupTaskID01, g_testSmpCpupTaskID02; +static volatile UINT32 g_testSmpCpupStop = 0; +static HwiIrqParam g_dev1, g_dev2; +static void HwiF01(void) +{ + UINT32 i; + // 2, used to calculate the conut num. + UINT32 count = GetNopCount() / 2; + for (i = 0; i < count; i++) { + __asm__ volatile("nop"); + } +} +static void HwiF02(void) +{ + UINT32 i; + // 2, used to calculate the conut num. + UINT32 count = GetNopCount() / 2; + for (i = 0; i < count; i++) { + __asm__ volatile("nop"); + } +} + +static void Task01(void) +{ + UINT32 ret; + g_dev1.pDevId = (void *)1; + g_dev1.swIrq = HWI_NUM_TEST; + // 3, used to set the hwi priority. + ret = LOS_HwiCreate(HWI_NUM_TEST, 3, IRQF_SHARED, (HWI_PROC_FUNC)HwiF01, &g_dev1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + g_dev2.pDevId = (void *)2; // 2, used to set the dev ID. + g_dev2.swIrq = HWI_NUM_TEST; + // 3, used to set the hwi priority. + ret = LOS_HwiCreate(HWI_NUM_TEST, 3, IRQF_SHARED, (HWI_PROC_FUNC)HwiF02, &g_dev2); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); + + while (g_testSmpCpupStop < 1) { + TestHwiTrigger(HWI_NUM_TEST); + } + + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(0)); + ret = LOS_HwiDelete(HWI_NUM_TEST, &g_dev1); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + ret = LOS_HwiDelete(HWI_NUM_TEST, &g_dev2); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + + return; +} +static void Task02(void) +{ + UINT32 tempCpup; + + LOS_TaskDelay(LOSCFG_BASE_CORE_TICK_PER_SECOND * CPUP_BACKWARD); + tempCpup = TestGetSingleHwiCpup(HWI_NUM_TEST, CPUP_LAST_ONE_SECONDS); + // 2, used to calculate the input of equal func. + ICUNIT_GOTO_WITHIN_EQUAL(tempCpup, LOS_CPUP_SINGLE_CORE_PRECISION / 2, LOS_CPUP_PRECISION, tempCpup, EXIT2); + +EXIT2: + g_testSmpCpupStop = 1; + + LOS_TaskDelay(LOSCFG_BASE_CORE_TICK_PER_SECOND * CPUP_BACKWARD); + tempCpup = LOS_HistoryTaskCpuUsage(g_testSmpCpupTaskID01, CPUP_LAST_ONE_SECONDS); + ICUNIT_ASSERT_EQUAL_VOID(tempCpup, CPU_USE_MIN, tempCpup); + + return; +} + +static UINT32 Testcase(VOID) +{ + TSK_INIT_PARAM_S taskInitParam; + UINT32 ret; + + ret = memset_s((void *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Task01; + taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + taskInitParam.pcName = "SmpCpup004_task01"; + taskInitParam.usTaskPrio = TASK_PRIO_TEST - 2; // 2, used to calculate the task priority. +#ifdef LOSCFG_KERNEL_SMP + /* make sure that created test task is definitely on another core */ + UINT32 currCpuid = (ArchCurrCpuid() + 1) % LOSCFG_KERNEL_CORE_NUM; + taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(currCpuid); +#endif + ret = LOS_TaskCreate(&g_testSmpCpupTaskID01, &taskInitParam); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = memset_s((void *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Task02; + taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + taskInitParam.pcName = "SmpCpup004_task02"; + taskInitParam.usTaskPrio = TASK_PRIO_TEST - 1; // 1, used to calculate the task priority. +#ifdef LOSCFG_KERNEL_SMP + taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testSmpCpupTaskID02, &taskInitParam); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EIXT1); + + LOS_TaskDelay(LOSCFG_BASE_CORE_TICK_PER_SECOND * (CPUP_BACKWARD * 2 + 1)); // 2, used to calculate the delay time. + +EIXT1: + LOS_TaskDelete(g_testSmpCpupTaskID02); +EXIT: + LOS_TaskDelete(g_testSmpCpupTaskID01); + + return LOS_OK; +} +#endif + +VOID ItSmpExtendCpup004(VOID) +{ +#ifdef LOSCFG_CPUP_INCLUDE_IRQ + TEST_ADD_CASE("ItSmpExtendCpup004", Testcase, TEST_EXTEND, TEST_CPUP, TEST_LEVEL2, TEST_FUNCTION); +#endif +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_005.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_005.c new file mode 100644 index 00000000..13aad806 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_005.c @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_extend_cpup.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_testSmpCpupTaskID01, g_testSmpCpupTaskID02, g_testSmpCpupTaskID03, g_testSmpCpupTaskID04; +static volatile UINT32 g_testSmpCpupStop = 0; +static volatile UINT32 g_testSmpCpupCount = 0; + +static void Task03(void) +{ + while (g_testSmpCpupStop < 1) { + g_testSmpCpupCount++; + LOS_TaskYield(); + } + return; +} +static void Task04(void) +{ + while (g_testSmpCpupStop < 1) { + g_testSmpCpupCount++; + LOS_TaskYield(); + } + return; +} + +static void Task01(void) +{ + TSK_INIT_PARAM_S taskInitParam; + UINT32 ret; + + ret = memset_s((void *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Task03; + taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + taskInitParam.pcName = "SmpCpup005_task03"; + taskInitParam.usTaskPrio = TASK_PRIO_TEST - 2; // 2, used to calculate the task priority. +#ifdef LOSCFG_KERNEL_SMP + taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testSmpCpupTaskID03, &taskInitParam); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT2); + + ret = memset_s((void *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT2); + taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Task04; + taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + taskInitParam.pcName = "SmpCpup005_task04"; + taskInitParam.usTaskPrio = TASK_PRIO_TEST - 2; // 2, used to calculate the task priority. +#ifdef LOSCFG_KERNEL_SMP + taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testSmpCpupTaskID04, &taskInitParam); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT3); + + while (g_testSmpCpupStop < 1) { + g_testSmpCpupCount++; + LOS_TaskYield(); + } + + // 2, the g_testSmpCpupStop possible values. + while (g_testSmpCpupStop < 2) { + // 4, used to calculate the delay time. + LOS_TaskDelay(LOSCFG_BASE_CORE_TICK_PER_SECOND / 4); + } +EXIT3: + LOS_TaskDelete(g_testSmpCpupTaskID04); +EXIT2: + LOS_TaskDelete(g_testSmpCpupTaskID03); + return; +} +static void Task02(void) +{ + UINT32 tempCpup, tempCpup1, tempCpup2, tempCpup3; + + LOS_TaskDelay(LOSCFG_BASE_CORE_TICK_PER_SECOND * CPUP_BACKWARD); + tempCpup1 = LOS_HistoryTaskCpuUsage(g_testSmpCpupTaskID01, CPUP_LAST_ONE_SECONDS); + tempCpup2 = LOS_HistoryTaskCpuUsage(g_testSmpCpupTaskID03, CPUP_LAST_ONE_SECONDS); + tempCpup3 = LOS_HistoryTaskCpuUsage(g_testSmpCpupTaskID04, CPUP_LAST_ONE_SECONDS); + tempCpup = tempCpup1 + tempCpup2 + tempCpup3; + ICUNIT_GOTO_WITHIN_EQUAL(tempCpup, LOS_CPUP_SINGLE_CORE_PRECISION - CPUP_TEST_TOLERANT, + LOS_CPUP_SINGLE_CORE_PRECISION, tempCpup, EXIT3); + +EXIT3: + g_testSmpCpupStop = 1; + + LOS_TaskDelay(LOSCFG_BASE_CORE_TICK_PER_SECOND * CPUP_BACKWARD); + tempCpup1 = LOS_HistoryTaskCpuUsage(g_testSmpCpupTaskID01, CPUP_LAST_ONE_SECONDS); + tempCpup2 = LOS_HistoryTaskCpuUsage(g_testSmpCpupTaskID03, CPUP_LAST_ONE_SECONDS); + tempCpup3 = LOS_HistoryTaskCpuUsage(g_testSmpCpupTaskID04, CPUP_LAST_ONE_SECONDS); + tempCpup = tempCpup1 + tempCpup2 + tempCpup3; + ICUNIT_GOTO_WITHIN_EQUAL(tempCpup, CPU_USE_MIN, CPU_USE_MIN + CPUP_TEST_TOLERANT, tempCpup, EXIT2); + +EXIT2: + // 2, set the g_testSmpCpupStop possible values. + g_testSmpCpupStop = 2; + + LOS_TaskDelay(LOSCFG_BASE_CORE_TICK_PER_SECOND * CPUP_BACKWARD); + + return; +} + +static UINT32 Testcase(VOID) +{ + TSK_INIT_PARAM_S taskInitParam; + UINT32 ret; + + ret = memset_s((void *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Task01; + taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + taskInitParam.pcName = "SmpCpup005_task01"; + taskInitParam.usTaskPrio = TASK_PRIO_TEST - 2; // 2, used to calculate the task priority. +#ifdef LOSCFG_KERNEL_SMP + /* make sure that created test task is definitely on another core */ + UINT32 currCpuid = (ArchCurrCpuid() + 1) % LOSCFG_KERNEL_CORE_NUM; + taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(currCpuid); +#endif + ret = LOS_TaskCreate(&g_testSmpCpupTaskID01, &taskInitParam); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = memset_s((void *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Task02; + taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + taskInitParam.pcName = "SmpCpup005_task02"; + taskInitParam.usTaskPrio = TASK_PRIO_TEST - 1; // 1, used to calculate the task priority. +#ifdef LOSCFG_KERNEL_SMP + taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testSmpCpupTaskID02, &taskInitParam); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EIXT1); + + LOS_TaskDelay(LOSCFG_BASE_CORE_TICK_PER_SECOND * (CPUP_BACKWARD * 3 + 1)); // 3, used to calculate the delay time. + +EIXT1: + LOS_TaskDelete(g_testSmpCpupTaskID02); +EXIT: + LOS_TaskDelete(g_testSmpCpupTaskID01); + + return LOS_OK; +} + +VOID ItSmpExtendCpup005(VOID) +{ + TEST_ADD_CASE("ItSmpExtendCpup005", Testcase, TEST_EXTEND, TEST_CPUP, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_007.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_007.c new file mode 100644 index 00000000..8780fd7e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_007.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_extend_cpup.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_testSmpCpupTaskID01, g_testSmpCpupTaskID02; +static void Task01(void) +{ + // 2, set delay time. + LOS_TaskDelay(2); + + return; +} +static void Task02(void) +{ + UINT32 tempCpup[2]; + UINT32 index = 0x00000001; + + do { + index ^= 0x00000001; + tempCpup[index] = LOS_HistoryTaskCpuUsage(g_testSmpCpupTaskID01, CPUP_ALL_TIME); + } while (!(LOS_ERRNO_OS_ERROR(LOS_MOD_SYS, 0x00) & tempCpup[index])); + ICUNIT_ASSERT_EQUAL_VOID(tempCpup[index], LOS_ERRNO_CPUP_NO_CREATED, tempCpup[index]); + + index ^= 0x00000001; + ICUNIT_ASSERT_WITHIN_EQUAL_VOID(tempCpup[index], CPU_USE_MIN, LOS_CPUP_SINGLE_CORE_PRECISION, tempCpup[index]); + + return; +} + +static UINT32 Testcase(VOID) +{ + TSK_INIT_PARAM_S taskInitParam; + UINT32 ret; + + ret = memset_s((void *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Task01; + taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + taskInitParam.pcName = "SmpCpup007_task01"; + taskInitParam.usTaskPrio = TASK_PRIO_TEST - 2; // 2, used to calculate the task priority. + taskInitParam.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + /* make sure that created test task is definitely on another core */ + UINT32 currCpuid = (ArchCurrCpuid() + 1) % LOSCFG_KERNEL_CORE_NUM; + taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(currCpuid); +#endif + ret = LOS_TaskCreate(&g_testSmpCpupTaskID01, &taskInitParam); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = memset_s((void *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Task02; + taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + taskInitParam.pcName = "SmpCpup007_task02"; + taskInitParam.usTaskPrio = TASK_PRIO_TEST - 1; +#ifdef LOSCFG_KERNEL_SMP + taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testSmpCpupTaskID02, &taskInitParam); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EIXT1); + + // 10, set delay time. + LOS_TaskDelay(10); + +EIXT1: + LOS_TaskDelete(g_testSmpCpupTaskID02); +EXIT: + LOS_TaskDelete(g_testSmpCpupTaskID01); + + return LOS_OK; +} + +VOID ItSmpExtendCpup007(VOID) +{ + TEST_ADD_CASE("ItSmpExtendCpup007", Testcase, TEST_EXTEND, TEST_CPUP, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_008.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_008.c new file mode 100644 index 00000000..6d0d34fc --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_008.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_extend_cpup.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_testSmpCpupTaskID01, g_testSmpCpupTaskID02; +static void Task01(void) +{ + // 2, set delay time. + LOS_TaskDelay(2); + LOS_TaskDelete(g_testSmpCpupTaskID01); + return; +} +static void Task02(void) +{ + UINT32 tempCpup[2]; + UINT32 index = 0x00000001; + + do { + index ^= 0x00000001; + tempCpup[index] = LOS_HistoryTaskCpuUsage(g_testSmpCpupTaskID01, CPUP_ALL_TIME); + } while (!(LOS_ERRNO_OS_ERROR(LOS_MOD_SYS, 0x00) & tempCpup[index])); + ICUNIT_ASSERT_EQUAL_VOID(tempCpup[index], LOS_ERRNO_CPUP_NO_CREATED, tempCpup[index]); + + index ^= 0x00000001; + ICUNIT_ASSERT_WITHIN_EQUAL_VOID(tempCpup[index], CPU_USE_MIN, LOS_CPUP_SINGLE_CORE_PRECISION, tempCpup[index]); + + return; +} + +static UINT32 Testcase(VOID) +{ + TSK_INIT_PARAM_S taskInitParam; + UINT32 ret; + + ret = memset_s((void *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Task01; + taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + taskInitParam.pcName = "SmpCpup008_task01"; + taskInitParam.usTaskPrio = TASK_PRIO_TEST - 2; // 2, used to calculate the task priority. +#ifdef LOSCFG_KERNEL_SMP + /* make sure that created test task is definitely on another core */ + UINT32 currCpuid = (ArchCurrCpuid() + 1) % LOSCFG_KERNEL_CORE_NUM; + taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(currCpuid); +#endif + ret = LOS_TaskCreate(&g_testSmpCpupTaskID01, &taskInitParam); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = memset_s((void *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Task02; + taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + taskInitParam.pcName = "SmpCpup008_task02"; + taskInitParam.usTaskPrio = TASK_PRIO_TEST - 1; // 1, used to calculate the task priority. +#ifdef LOSCFG_KERNEL_SMP + taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testSmpCpupTaskID02, &taskInitParam); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EIXT1); + // 10, set delay time. + LOS_TaskDelay(10); + +EIXT1: + LOS_TaskDelete(g_testSmpCpupTaskID02); +EXIT: + LOS_TaskDelete(g_testSmpCpupTaskID01); + + return LOS_OK; +} + +VOID ItSmpExtendCpup008(VOID) +{ + TEST_ADD_CASE("ItSmpExtendCpup008", Testcase, TEST_EXTEND, TEST_CPUP, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_009.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_009.c new file mode 100644 index 00000000..811008dd --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_009.c @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_extend_cpup.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_testSmpCpupTaskID01, g_testSmpCpupTaskID02, g_testSmpCpupTaskID03; + +static void Task03(void) +{ + LOS_TaskDelay(LOSCFG_BASE_CORE_TICK_PER_SECOND * CPUP_BACKWARD); + return; +} + +static void Task01(void) +{ + TSK_INIT_PARAM_S taskInitParam; + UINT32 ret; + + ret = memset_s((void *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Task03; + taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + taskInitParam.pcName = "SmpCpup009_task03"; + taskInitParam.usTaskPrio = TASK_PRIO_TEST - 2; // 2, used to calculate the task priority. + taskInitParam.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testSmpCpupTaskID03, &taskInitParam); + ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_OK, ret); + // 2, set delay time. + LOS_TaskDelay(2); + LOS_TaskDelete(g_testSmpCpupTaskID03); + + return; +} + +static void Task02(void) +{ + UINT32 tempCpup[2] = {0}; + UINT32 index = 0x00000001; + + do { + index ^= 0x00000001; + tempCpup[index] = LOS_HistoryTaskCpuUsage(g_testSmpCpupTaskID03, CPUP_ALL_TIME); + } while (!(LOS_ERRNO_OS_ERROR(LOS_MOD_SYS, 0x00) & tempCpup[index])); + ICUNIT_ASSERT_EQUAL_VOID(tempCpup[index], LOS_ERRNO_CPUP_NO_CREATED, tempCpup[index]); + + index ^= 0x00000001; + ICUNIT_ASSERT_WITHIN_EQUAL_VOID(tempCpup[index], CPU_USE_MIN, LOS_CPUP_SINGLE_CORE_PRECISION, tempCpup[index]); + + return; +} + +static UINT32 Testcase(VOID) +{ + TSK_INIT_PARAM_S taskInitParam; + UINT32 ret; + + ret = memset_s((void *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Task01; + taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + taskInitParam.pcName = "SmpCpup009_task01"; + taskInitParam.usTaskPrio = TASK_PRIO_TEST - 2; // 2, used to calculate the task priority. + taskInitParam.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + /* make sure that created test task is definitely on another core */ + UINT32 currCpuid = (ArchCurrCpuid() + 1) % LOSCFG_KERNEL_CORE_NUM; + taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(currCpuid); +#endif + ret = LOS_TaskCreate(&g_testSmpCpupTaskID01, &taskInitParam); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = memset_s((void *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Task02; + taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + taskInitParam.pcName = "SmpCpup009_task02"; + taskInitParam.usTaskPrio = TASK_PRIO_TEST - 1; // 1, used to calculate the task priority. +#ifdef LOSCFG_KERNEL_SMP + taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testSmpCpupTaskID02, &taskInitParam); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EIXT1); + + LOS_TaskDelay(LOSCFG_BASE_CORE_TICK_PER_SECOND * (CPUP_BACKWARD + 1)); + +EIXT1: + LOS_TaskDelete(g_testSmpCpupTaskID02); +EXIT: + LOS_TaskDelete(g_testSmpCpupTaskID01); + + return LOS_OK; +} + +VOID ItSmpExtendCpup009(VOID) +{ + TEST_ADD_CASE("ItSmpExtendCpup009", Testcase, TEST_EXTEND, TEST_CPUP, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_010.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_010.c new file mode 100644 index 00000000..fdace6ba --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_010.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_extend_cpup.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_testSmpCpupTaskID01, g_testSmpCpupTaskID02; +static volatile UINT32 g_testSmpCpupStop = 0; + +static void Task01(void) +{ + UINT32 i; + + // 2, set delay time. + LOS_TaskDelay(2); + LOS_CpupReset(); + g_testSmpCpupStop = 1; + + return; +} + +static void Task02(void) +{ + UINT32 tempCpup; + + do { + tempCpup = LOS_HistoryTaskCpuUsage(g_testSmpCpupTaskID01, CPUP_ALL_TIME); + } while ((!(LOS_ERRNO_OS_ERROR(LOS_MOD_CPUP, 0x00) & tempCpup)) && (g_testSmpCpupStop != 1)); + ICUNIT_ASSERT_EQUAL_VOID(tempCpup, LOS_ERRNO_CPUP_NO_INIT, tempCpup); + + return; +} + +static UINT32 Testcase(VOID) +{ + TSK_INIT_PARAM_S taskInitParam; + UINT32 ret; + + ret = memset_s((void *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Task01; + taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + taskInitParam.pcName = "SmpCpup001_task01"; + taskInitParam.usTaskPrio = TASK_PRIO_TEST - 2; // 2, used to calculate the task priority. + taskInitParam.uwResved = LOS_TASK_STATUS_DETACHED; +#ifdef LOSCFG_KERNEL_SMP + /* make sure that created test task is definitely on another core */ + UINT32 currCpuid = (ArchCurrCpuid() + 1) % LOSCFG_KERNEL_CORE_NUM; + taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(currCpuid); +#endif + ret = LOS_TaskCreate(&g_testSmpCpupTaskID01, &taskInitParam); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = memset_s((void *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Task02; + taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + taskInitParam.pcName = "SmpCpup001_task02"; + taskInitParam.usTaskPrio = TASK_PRIO_TEST - 1; // 1, used to calculate the task priority. +#ifdef LOSCFG_KERNEL_SMP + taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testSmpCpupTaskID02, &taskInitParam); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EIXT1); + + // 10, set delay time. + LOS_TaskDelay(10); + +EIXT1: + LOS_TaskDelete(g_testSmpCpupTaskID02); +EXIT: + LOS_TaskDelete(g_testSmpCpupTaskID01); + + return LOS_OK; +} + +VOID ItSmpExtendCpup010(VOID) +{ + TEST_ADD_CASE("ItSmpExtendCpup010", Testcase, TEST_EXTEND, TEST_CPUP, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_011.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_011.c new file mode 100644 index 00000000..1219733b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_011.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_extend_cpup.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_testSmpCpupTaskID01, g_testSmpCpupTaskID02; +static volatile UINT32 g_testSmpCpupStop = 0; +static CPUP_INFO_S g_psttaskcpup1st[LOSCFG_BASE_CORE_TSK_LIMIT]; +static UINT32 StatisticsTaskCpup(CPUP_INFO_S *taskCpup) +{ + UINT32 i; + UINT32 tmpCpup = 0; + for (i = 0; i < LOSCFG_BASE_CORE_TSK_LIMIT; i++) { + tmpCpup += taskCpup[i].usage; + } + return tmpCpup; +} + +static void Task01(void) +{ + while (g_testSmpCpupStop < 1) { + __asm__ volatile("nop"); + } + + LOS_TaskDelete(g_testSmpCpupTaskID01); + + return; +} + +static void Task02(void) +{ + UINT32 tempCpup; + UINT32 ret; + UINT32 cpupBeforeDel; + TSK_INFO_S tempTaskInfo; + + LOS_TaskDelay(LOSCFG_BASE_CORE_TICK_PER_SECOND * CPUP_BACKWARD); + cpupBeforeDel = LOS_HistoryTaskCpuUsage(g_testSmpCpupTaskID01, CPUP_LAST_ONE_SECONDS); + // 2, used to calculate the input of equal func. + ICUNIT_GOTO_WITHIN_EQUAL(cpupBeforeDel, LOS_CPUP_SINGLE_CORE_PRECISION / 2, LOS_CPUP_SINGLE_CORE_PRECISION, + cpupBeforeDel, EXIT2); + +EXIT2: + g_testSmpCpupStop = 1; + + do { + ret = LOS_TaskInfoGet(g_testSmpCpupTaskID01, &tempTaskInfo); + } while (ret != LOS_ERRNO_TSK_NOT_CREATED); + + return; +} + + +static UINT32 Testcase(VOID) +{ + TSK_INIT_PARAM_S taskInitParam; + UINT32 ret; + + ret = memset_s((void *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Task01; + taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + taskInitParam.pcName = "SmpCpup001_task01"; + taskInitParam.usTaskPrio = TASK_PRIO_TEST - 2; // 2, used to calculate the task priority. +#ifdef LOSCFG_KERNEL_SMP + /* make sure that created test task is definitely on another core */ + UINT32 currCpuid = (ArchCurrCpuid() + 1) % LOSCFG_KERNEL_CORE_NUM; + taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(currCpuid); +#endif + ret = LOS_TaskCreate(&g_testSmpCpupTaskID01, &taskInitParam); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = memset_s((void *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Task02; + taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + taskInitParam.pcName = "SmpCpup001_task02"; + taskInitParam.usTaskPrio = TASK_PRIO_TEST - 1; // 1, used to calculate the task priority. +#ifdef LOSCFG_KERNEL_SMP + taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testSmpCpupTaskID02, &taskInitParam); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EIXT1); + + LOS_TaskDelay(LOSCFG_BASE_CORE_TICK_PER_SECOND * (CPUP_BACKWARD * 2 + 1)); // 2, used to calculate the delay time. + +EIXT1: + LOS_TaskDelete(g_testSmpCpupTaskID02); +EXIT: + LOS_TaskDelete(g_testSmpCpupTaskID01); + + return LOS_OK; +} + +VOID ItSmpExtendCpup011(VOID) +{ + TEST_ADD_CASE("ItSmpExtendCpup011", Testcase, TEST_EXTEND, TEST_CPUP, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_012.c b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_012.c new file mode 100644 index 00000000..1b46c878 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/kernel_extend/cpup/smp/It_smp_extend_cpup_012.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_extend_cpup.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 g_testSmpCpupTaskID01, g_testSmpCpupTaskID02; +static void Task01(void) +{ + UINT32 tempCpup; + UINT32 ret; + LOS_TaskDelay(LOSCFG_BASE_CORE_TICK_PER_SECOND * CPUP_BACKWARD); + ret = LOS_EventRead(&g_eventCB, 0x00000001, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + + tempCpup = LOS_HistoryTaskCpuUsage(g_testSmpCpupTaskID02, CPUP_LAST_ONE_SECONDS); + ICUNIT_ASSERT_WITHIN_EQUAL_VOID(tempCpup, CPU_USE_MIN, CPU_USE_MIN + CPUP_TEST_TOLERANT, tempCpup); + + return; +} +static void Task02(void) +{ + UINT32 tempCpup; + UINT32 ret; + LOS_TaskDelay(LOSCFG_BASE_CORE_TICK_PER_SECOND * CPUP_BACKWARD); + + ret = LOS_EventRead(&g_eventCB, 0x00000001, LOS_WAITMODE_AND, LOS_WAIT_FOREVER); + + tempCpup = LOS_HistoryTaskCpuUsage(g_testSmpCpupTaskID01, CPUP_LAST_ONE_SECONDS); + ICUNIT_ASSERT_WITHIN_EQUAL_VOID(tempCpup, CPU_USE_MIN, CPU_USE_MIN + CPUP_TEST_TOLERANT, tempCpup); + + return; +} + +static UINT32 Testcase(VOID) +{ + TSK_INIT_PARAM_S taskInitParam; + UINT32 ret; + + g_eventCB.uwEventID = 0; + ret = LOS_EventInit(&g_eventCB); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT0); + + ret = memset_s((void *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT0); + taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Task01; + taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + taskInitParam.pcName = "SmpCpup001_task01"; + taskInitParam.usTaskPrio = TASK_PRIO_TEST - 2; // 2, used to calculate the task priority. +#ifdef LOSCFG_KERNEL_SMP + /* make sure that created test task is definitely on another core */ + UINT32 currCpuid = (ArchCurrCpuid() + 1) % LOSCFG_KERNEL_CORE_NUM; + taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(currCpuid); +#endif + ret = LOS_TaskCreate(&g_testSmpCpupTaskID01, &taskInitParam); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT); + + ret = memset_s((void *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT1); + taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Task02; + taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + taskInitParam.pcName = "SmpCpup001_task02"; + taskInitParam.usTaskPrio = TASK_PRIO_TEST - 1; // 1, used to calculate the task priority. +#ifdef LOSCFG_KERNEL_SMP + taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_testSmpCpupTaskID02, &taskInitParam); + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EIXT1); + + ret = LOS_EventWrite(&g_eventCB, 0x00000001); + + LOS_TaskDelay(LOSCFG_BASE_CORE_TICK_PER_SECOND * (CPUP_BACKWARD + 1)); + + LOS_EventClear(&g_eventCB, ~0x00000001); + +EIXT1: + LOS_TaskDelete(g_testSmpCpupTaskID02); +EXIT: + LOS_TaskDelete(g_testSmpCpupTaskID01); +EXIT0: + LOS_EventDestroy(&g_eventCB); + + return LOS_OK; +} + +VOID ItSmpExtendCpup012(VOID) +{ + TEST_ADD_CASE("ItSmpExtendCpup012", Testcase, TEST_EXTEND, TEST_CPUP, TEST_LEVEL2, TEST_FUNCTION); +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/BUILD.gn b/src/kernel_liteos_a/testsuites/kernel/sample/posix/BUILD.gn new file mode 100644 index 00000000..f9fc77b8 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/BUILD.gn @@ -0,0 +1,117 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +static_library("test_posix") { + sources = [ + "mem/It_posix_mem.c", + "mqueue/It_posix_queue.c", + "mutex/It_posix_mutex.c", + "pthread/It_posix_pthread.c", + "sched/It_posix_sched.c", + "sem/It_posix_sem.c", + "smp/It_posix_smp.c", + "smp/It_posix_smp_001.c", + "smp/It_posix_smp_002.c", + "smp/It_posix_smp_003.c", + "smp/It_posix_smp_004.c", + "smp/It_posix_smp_005.c", + "smp/It_posix_smp_006.c", + "smp/It_posix_smp_007.c", + "smp/It_posix_smp_008.c", + "smp/It_posix_smp_009.c", + "smp/It_posix_smp_010.c", + "smp/It_posix_smp_011.c", + "smp/It_posix_smp_012.c", + "smp/It_posix_smp_013.c", + "smp/It_posix_smp_014.c", + "smp/It_posix_smp_015.c", + "smp/It_posix_smp_016.c", + "smp/It_posix_smp_017.c", + "smp/It_posix_smp_018.c", + "swtmr/It_posix_swtmr.c", + ] + + if (LOSCFG_TEST_SMOKE) { + sources += [ + "mem/smoke/It_posix_mem_001.c", + "mem/smoke/It_posix_mem_002.c", + "mem/smoke/It_posix_mem_003.c", + "mqueue/smoke/It_posix_queue_001.c", + "mqueue/smoke/It_posix_queue_003.c", + "mqueue/smoke/It_posix_queue_028.c", + "mqueue/smoke/It_posix_queue_062.c", + "mutex/smoke/It_posix_mutex_001.c", + "mutex/smoke/It_posix_mutex_007.c", + "mutex/smoke/It_posix_mutex_012.c", + "mutex/smoke/It_posix_mutex_015.c", + "mutex/smoke/It_posix_mutex_016.c", + "mutex/smoke/It_posix_mutex_019.c", + "mutex/smoke/It_posix_mutex_020.c", + "pthread/smoke/It_posix_pthread_003.c", + "pthread/smoke/It_posix_pthread_004.c", + "pthread/smoke/It_posix_pthread_005.c", + "pthread/smoke/It_posix_pthread_006.c", + "pthread/smoke/It_posix_pthread_009.c", + "pthread/smoke/It_posix_pthread_018.c", + "pthread/smoke/It_posix_pthread_019.c", + "pthread/smoke/It_posix_pthread_020.c", + "pthread/smoke/It_posix_pthread_021.c", + "pthread/smoke/It_posix_pthread_022.c", + "sem/smoke/It_posix_sem_001.c", + "sem/smoke/It_posix_sem_002.c", + "swtmr/smoke/It_posix_swtmr_001.c", + "swtmr/smoke/It_posix_swtmr_013.c", + "swtmr/smoke/It_posix_swtmr_046.c", + "swtmr/smoke/It_posix_swtmr_047.c", + "swtmr/smoke/It_posix_swtmr_049.c", + "swtmr/smoke/It_posix_swtmr_055.c", + "swtmr/smoke/It_posix_swtmr_065.c", + "swtmr/smoke/It_posix_swtmr_067.c", + "swtmr/smoke/It_posix_swtmr_101.c", + "swtmr/smoke/It_posix_swtmr_103.c", + "swtmr/smoke/It_posix_swtmr_105.c", + "swtmr/smoke/It_posix_swtmr_106.c", + ] + } + + include_dirs = [ + "../../../compat/posix/src", + "../../include", + "mem", + "mqueue", + "mutex", + "pthread", + "sched", + "sem", + "smp", + "swtmr", + ] + + cflags = [ "-Wno-error" ] +} diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/Makefile b/src/kernel_liteos_a/testsuites/kernel/sample/posix/Makefile new file mode 100644 index 00000000..3b9cead1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/Makefile @@ -0,0 +1,37 @@ + +include $(LITEOSTESTTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd))test + +LOCAL_INCLUDE := \ + -I $(LITEOSTOPDIR)/compat/posix/src \ + -I $(LITEOSTESTTOPDIR)/kernel/include \ + -I $(LITEOSTESTTOPDIR)/kernel/sample/posix/mutex \ + -I $(LITEOSTESTTOPDIR)/kernel/sample/posix/pthread + +SRC_MODULES := mqueue mutex sem pthread swtmr sched mem + +ifeq ($(LOSCFG_TEST_LLT), y) +LLT_MODULES := mqueue/llt mutex/llt sem/llt pthread/llt swtmr/llt sched/llt mem/llt +endif + +ifeq ($(LOSCFG_TEST_SMOKE), y) +SMOKE_MODULES := mqueue/smoke mutex/smoke sem/smoke pthread/smoke swtmr/smoke sched/smoke mem/smoke +endif + +ifeq ($(LOSCFG_TEST_FULL), y) +FULL_MODULES := mqueue/full mutex/full sem/full pthread/full swtmr/full sched/full mem/full +endif + +ifeq ($(LOSCFG_TEST_PRESSURE), y) +PRESSURE_MODULES := mqueue/pressure mutex/pressure sem/pressure pthread/pressure swtmr/pressure sched/pressure mem/pressure +endif + +LOCAL_MODULES := $(SRC_MODULES) $(LLT_MODULES) $(PRESSURE_MODULES) $(SMOKE_MODULES) $(FULL_MODULES) + +LOCAL_SRCS := $(foreach dir,$(LOCAL_MODULES),$(wildcard $(dir)/*.c)) +LOCAL_CHS := $(foreach dir,$(LOCAL_MODULES),$(wildcard $(dir)/*.h)) + +LOCAL_FLAGS := $(LOCAL_INCLUDE) -Wno-error + +include $(MODULE) diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/It_posix_mutex.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/It_posix_mutex.c new file mode 100644 index 00000000..c253061e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/It_posix_mutex.c @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +int g_retval; +int g_returned; +int g_canceled; +int g_value; +int g_ctrl; + + +VOID ItSuitePosixMutex(void) +{ +#if defined(LOSCFG_TEST_SMOKE) + ItPosixMux001(); + ItPosixMux007(); + ItPosixMux012(); + ItPosixMux015(); + ItPosixMux016(); + ItPosixMux019(); + ItPosixMux020(); +#endif + +#if defined(LOSCFG_TEST_FULL) + ItPosixMux002(); + ItPosixMux003(); + ItPosixMux004(); + ItPosixMux005(); + ItPosixMux006(); + ItPosixMux008(); + ItPosixMux009(); + ItPosixMux010(); + ItPosixMux011(); + ItPosixMux013(); + ItPosixMux014(); + ItPosixMux017(); + ItPosixMux018(); + ItPosixMux021(); + ItPosixMux022(); + ItPosixMux023(); + ItPosixMux024(); + ItPosixMux025(); + ItPosixMux026(); + ItPosixMux027(); + ItPosixMux028(); + ItPosixMux029(); + ItPosixMux032(); + ItPosixMux033(); + ItPosixMux034(); + ItPosixMux035(); + ItPosixMux036(); + ItPosixMux037(); + ItPosixMux038(); + ItPosixMux039(); + ItPosixMux040(); + ItPosixMux041(); + ItPosixMux042(); + ItPosixMux043(); + ItPosixMux044(); + ItPosixMux045(); + ItPosixMux046(); + ItPosixMux047(); + ItPosixMux048(); + ItPosixMux049(); + ItPosixMux050(); + ItPosixMux054(); + ItPosixMux055(); + ItPosixMux056(); + ItPosixMux057(); + ItPosixMux058(); + ItPosixMux059(); + ItPosixMux060(); + ItPosixMux061(); + ItPosixMux062(); + ItPosixMux063(); + ItPosixMux064(); + ItPosixMux065(); + ItPosixMux066(); + ItPosixMux067(); + ItPosixMux068(); + ItPosixMux069(); + ItPosixMux070(); + ItPosixMux071(); + ItPosixMux072(); + ItPosixMux073(); + ItPosixMux074(); +#ifndef LOSCFG_KERNEL_SMP + ItPosixMux075(); +#endif + ItPosixMux076(); + ItPosixMux077(); + ItPosixMux078(); + ItPosixMux079(); + ItPosixMux080(); + ItPosixMux081(); + ItPosixMux082(); + ItPosixMux084(); + ItPosixMux085(); + ItPosixMux086(); + ItPosixMux087(); + ItPosixMux089(); + ItPosixMux090(); + ItPosixMux091(); + ItPosixMux092(); + ItPosixMux093(); + ItPosixMux094(); + ItPosixMux095(); + ItPosixMux097(); + ItPosixMux098(); + ItPosixMux099(); + ItPosixMux101(); +#endif +} + + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/It_posix_mutex.h b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/It_posix_mutex.h new file mode 100644 index 00000000..0d737ba3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/It_posix_mutex.h @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _IT_POSIX_MUTEX_H +#define _IT_POSIX_MUTEX_H + +#include "osTest.h" +#include "pthread.h" +#include "errno.h" +#include "sched.h" +#include "semaphore.h" +#include "unistd.h" +#include "los_task_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#ifdef LOSCFG_DEBUG_DEADLOCK +#define TEST_MUTEX_INIT \ + { \ + { 0, 0, 0, 0 }, \ + { \ + { 0, 0 }, { 0, 0 }, 0, 0 \ + } \ + } +#else +#define TEST_MUTEX_INIT \ + { \ + { 0, 0, 0, 0 }, \ + { \ + { 0, 0 }, 0, 0 \ + } \ + } +#endif +#define MUTEX_TEST_NUM 100 + +extern int g_retval; +extern int g_value; +extern int g_ctrl; + +long sysconf(int name); + +#if defined(LOSCFG_TEST_SMOKE) +VOID IT_FS_VNODE_001(void); +VOID IT_FS_NAMECACHE_001(void); + +VOID ItPosixMux001(void); +VOID ItPosixMux007(void); +VOID ItPosixMux012(void); +VOID ItPosixMux015(void); +VOID ItPosixMux016(void); +VOID ItPosixMux019(void); +VOID ItPosixMux020(void); +#endif + +#if defined(LOSCFG_TEST_FULL) +VOID ItPosixMux002(void); +VOID ItPosixMux003(void); +VOID ItPosixMux004(void); +VOID ItPosixMux005(void); +VOID ItPosixMux006(void); +VOID ItPosixMux008(void); +VOID ItPosixMux009(void); +VOID ItPosixMux010(void); +VOID ItPosixMux011(void); +VOID ItPosixMux013(void); +VOID ItPosixMux014(void); +VOID ItPosixMux017(void); +VOID ItPosixMux018(void); +VOID ItPosixMux021(void); +VOID ItPosixMux022(void); +VOID ItPosixMux023(void); +VOID ItPosixMux024(void); +VOID ItPosixMux025(void); +VOID ItPosixMux026(void); +VOID ItPosixMux027(void); +VOID ItPosixMux028(void); +VOID ItPosixMux029(void); +VOID ItPosixMux032(void); +VOID ItPosixMux033(void); +VOID ItPosixMux034(void); +VOID ItPosixMux035(void); +VOID ItPosixMux036(void); +VOID ItPosixMux037(void); +VOID ItPosixMux038(void); +VOID ItPosixMux039(void); +VOID ItPosixMux040(void); +VOID ItPosixMux041(void); +VOID ItPosixMux042(void); +VOID ItPosixMux043(void); +VOID ItPosixMux044(void); +VOID ItPosixMux045(void); +VOID ItPosixMux046(void); +VOID ItPosixMux047(void); +VOID ItPosixMux048(void); +VOID ItPosixMux049(void); +VOID ItPosixMux050(void); +VOID ItPosixMux054(void); +VOID ItPosixMux055(void); +VOID ItPosixMux056(void); +VOID ItPosixMux057(void); +VOID ItPosixMux058(void); +VOID ItPosixMux059(void); +VOID ItPosixMux060(void); +VOID ItPosixMux061(void); +VOID ItPosixMux062(void); +VOID ItPosixMux063(void); +VOID ItPosixMux064(void); +VOID ItPosixMux065(void); +VOID ItPosixMux066(void); +VOID ItPosixMux067(void); +VOID ItPosixMux068(void); +VOID ItPosixMux069(void); +VOID ItPosixMux070(void); +VOID ItPosixMux071(void); +VOID ItPosixMux072(void); +VOID ItPosixMux073(void); +VOID ItPosixMux074(void); +VOID ItPosixMux075(void); +VOID ItPosixMux076(void); +VOID ItPosixMux077(void); +VOID ItPosixMux078(void); +VOID ItPosixMux079(void); +VOID ItPosixMux080(void); +VOID ItPosixMux081(void); +VOID ItPosixMux082(void); +VOID ItPosixMux084(void); +VOID ItPosixMux085(void); +VOID ItPosixMux086(void); +VOID ItPosixMux087(void); +VOID ItPosixMux089(void); +VOID ItPosixMux090(void); +VOID ItPosixMux091(void); +VOID ItPosixMux092(void); +VOID ItPosixMux093(void); +VOID ItPosixMux094(void); +VOID ItPosixMux095(void); +VOID ItPosixMux097(void); +VOID ItPosixMux098(void); +VOID ItPosixMux099(void); +VOID ItPosixMux101(void); +#endif + +#if defined(LOSCFG_TEST_LLT) +VOID LltPosixMux001(VOID); +VOID LltPosixMux002(VOID); +VOID LltPosixMux003(VOID); +VOID LltPosixMux004(VOID); +VOID LltPosixMux005(VOID); +VOID ItPosixMux031(void); +VOID ItPosixMux083(void); +VOID ItPosixMux088(void); +VOID ItPosixMux096(void); +VOID ItPosixMux100(void); +VOID LltPosixMux006(void); +VOID LltPosixMux007(void); +#endif + +#if defined(LOSCFG_TEST_PRESSURE) +VOID ItPosixMux051(void); +VOID ItPosixMux052(void); +VOID ItPosixMux053(void); +#endif + +VOID ItSuitePosixMutex(void); + + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _IT_POSIX_MUTEX_H */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/Makefile b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/Makefile new file mode 100644 index 00000000..d4cdb0c7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/Makefile @@ -0,0 +1,35 @@ + +include $(LITEOSTESTTOPDIR)/config.mk + +MODULE_NAME := mutextest + +LOCAL_INCLUDE := \ + -I $(LITEOSTESTTOPDIR)/kernel/include \ + -I $(LITEOSTESTTOPDIR)/kernel/sample/posix/mutex + +SRC_MODULES := . + +ifeq ($(LOSCFG_TEST_LLT), y) +LLT_MODULES := llt +endif + +ifeq ($(LOSCFG_TEST_PRESSURE), y) +PRESSURE_MODULES := pressure +endif + +ifeq ($(LOSCFG_TEST_SMOKE), y) +SMOKE_MODULES := smoke +endif + +ifeq ($(LOSCFG_TEST_FULL), y) +FULL_MODULES := full +endif + +LOCAL_MODULES := $(SRC_MODULES) $(LLT_MODULES) $(PRESSURE_MODULES) $(SMOKE_MODULES) $(FULL_MODULES) + +LOCAL_SRCS := $(foreach dir,$(LOCAL_MODULES),$(wildcard $(dir)/*.c)) +LOCAL_CHS := $(foreach dir,$(LOCAL_MODULES),$(wildcard $(dir)/*.h)) + +LOCAL_FLAGS := $(LOCAL_INCLUDE) -Wno-error + +include $(MODULE) diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_002.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_002.c new file mode 100644 index 00000000..fa2a8d0f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_002.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +/* pthread_mutexattr_init 3-1.c + * Test that pthread_mutexattr_init() + * Upon successful completion, pthread_mutexattr_init() shall return a value of 0. + + * Steps: + * 1. Initialize a pthread_mutexattr_t object with pthread_mutexattr_init() + * 2. ENOMEM is the only uwErr it returns, so if it doesn't return that uwErr, + * the return number should be 0. + */ +static UINT32 Testcase(VOID) +{ + pthread_mutexattr_t *mta = NULL; + int rc; + + /* Initialize a mutex attributes object */ + rc = pthread_mutexattr_init(mta); + ICUNIT_GOTO_EQUAL(rc, EINVAL, rc, EXIT); + + return LOS_OK; + +EXIT: + pthread_mutexattr_destroy(mta); + return LOS_OK; +} + + +VOID ItPosixMux002(void) +{ + TEST_ADD_CASE("ItPosixMux002", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_003.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_003.c new file mode 100644 index 00000000..81e1abde --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_003.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +/* pthread_mutexattr_destroy 1-1.c + * Test that pthread_mutexattr_destroy() + * shall destroy a mutex attributes object. + * + * Steps: + * 1. Initialize a pthread_mutexattr_t object using pthread_mutexattr_init() + * 2. Destroy the attributes object using pthread_mutexattr_destroy() + * + */ +static UINT32 Testcase(VOID) +{ + pthread_mutexattr_t mta; + int rc; + + /* Initialize a mutex attributes object */ + rc = pthread_mutexattr_init(&mta); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + + /* Destroy the mutex attributes object */ + rc = pthread_mutexattr_destroy(&mta); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT); + + return LOS_OK; + +EXIT: + pthread_mutexattr_destroy(&mta); + return LOS_OK; +} + + +VOID ItPosixMux003(void) +{ + TEST_ADD_CASE("ItPosixMux003", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_004.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_004.c new file mode 100644 index 00000000..9201f5c5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_004.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +/* pthread_mutexattr_destroy 2-1.c + * Test pthread_mutexattr_destroy() + * A destroyed 'attr' attributes object can be reinitialized using + * pthread_mutexattr_init(); the results of otherwise referencing the + * object after it has been destroyed are undefined. + * + * Steps: + * 1. Initialize a pthread_mutexattr_t object using pthread_mutexattr_init() + * 2. Destroy that initialized attribute using pthread_mutexattr_destroy() + * 3. Initialize the pthread_mutexattr_t object again. This should not result + * in any uwErr. + * + */ +static UINT32 Testcase(VOID) +{ + pthread_mutexattr_t mta; + int rc; + + /* Initialize a mutex attributes object */ + rc = pthread_mutexattr_init(&mta); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + + /* Destroy the mutex attributes object */ + rc = pthread_mutexattr_destroy(&mta); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT); + + /* Initialize the mutex attributes object again. This shouldn't result in an uwErr. */ + rc = pthread_mutexattr_init(&mta); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + + rc = pthread_mutexattr_destroy(&mta); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT); + + return LOS_OK; + +EXIT: + pthread_mutexattr_destroy(&mta); + return LOS_OK; +} + + +VOID ItPosixMux004(void) +{ + TEST_ADD_CASE("ItPosixMux004", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_005.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_005.c new file mode 100644 index 00000000..3f268b3e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_005.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +/* pthread_mutexattr_destroy 3-1.c + * Test pthread_mutexattr_destroy() + * Upon successful completion, pthread_mutexattr_destroy() shall + * return a value of 0. + * + * Steps: + * 1. Initialize a pthread_mutexattr_t object using pthread_mutexattr_init() + * 2. Destroy that initialized attribute using pthread_mutexattr_destroy(). + * This should return 0; + * + */ +static UINT32 Testcase(VOID) +{ + pthread_mutexattr_t mta; + int rc; + + /* Initialize a mutex attributes object */ + rc = pthread_mutexattr_init(&mta); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + + /* Destroy the mutex attributes object */ + rc = pthread_mutexattr_destroy(&mta); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT); + + return LOS_OK; + +EXIT: + pthread_mutexattr_destroy(&mta); + return LOS_OK; +} + + +VOID ItPosixMux005(void) +{ + TEST_ADD_CASE("ItPosixMux005", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_006.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_006.c new file mode 100644 index 00000000..c27db8bc --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_006.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +/* pthread_mutexattr_destroy 4-1.c + * Test pthread_mutexattr_destroy() + * If it fails, an uwErr number shall be returned to indicate the uwErr: + * [EINVAL] The value specified by 'attr' is invalid + * + * Steps: + * Try to destroy a NULL mutex attributes object using pthread_mutexattr_destroy(). + * If it returns EINVAL, the test passes. + * + */ +static UINT32 Testcase(VOID) +{ + pthread_mutexattr_t *mta = NULL; + int rc; + + /* Try to destroy a NULL mutex attributes object using pthread_mutexattr_destroy() + * It should return EINVAL */ + rc = pthread_mutexattr_destroy(mta); + ICUNIT_ASSERT_EQUAL(rc, EINVAL, rc); + + return LOS_OK; +} + + +VOID ItPosixMux006(void) +{ + TEST_ADD_CASE("ItPosixMux006", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_008.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_008.c new file mode 100644 index 00000000..724b1921 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_008.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +/* pthread_mutexattr_setprotocol 3-1.c + * Test that pthread_mutexattr_setprotocol() + * + * It Shall fail if: + * [ENOTSUP] The value specified by protocol is an unsupported value. + * It may fail if: + * [EINVAL] 'protocol' is invalid + */ +static UINT32 Testcase(VOID) +{ + pthread_mutexattr_t mta; + int protocol; + + int ret; + + /* Initialize a mutex attributes object */ + ret = pthread_mutexattr_init(&mta); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + protocol = mta.protocol; + + while (protocol == PTHREAD_PRIO_NONE || protocol == PTHREAD_PRIO_INHERIT || protocol == PTHREAD_PRIO_PROTECT) { + protocol--; + } + + /* Set the protocol to an invalid value. */ + ret = pthread_mutexattr_setprotocol(&mta, protocol); + ICUNIT_GOTO_EQUAL(ret, EINVAL, ret, EXIT); + + ret = pthread_mutexattr_destroy(&mta); + ICUNIT_GOTO_EQUAL(ret, ENOERR, ret, EXIT); + +EXIT: + pthread_mutexattr_destroy(&mta); + return LOS_OK; +} + + +VOID ItPosixMux008(void) +{ + TEST_ADD_CASE("ItPosixMux008", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_009.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_009.c new file mode 100644 index 00000000..12f4ef52 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_009.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +/* pthread_mutexattr_setprotocol 3-2.c + * Test that pthread_mutexattr_setprotocol() + * + * It may fail if: + * [EINVAL] The value specified by 'attr' is invalid. + * + * Steps: + * 1. Call pthread_mutexattr_setprotocol with an uninitialized pthread_mutexattr_t object. + */ +static UINT32 Testcase(VOID) +{ + pthread_mutexattr_t mta; + int ret; + + /* Set the protocol to an invalid value. */ + ret = pthread_mutexattr_setprotocol(&mta, PTHREAD_PRIO_NONE); + ICUNIT_ASSERT_EQUAL(ret, ENOERR, ret); + + ret = pthread_mutexattr_destroy(&mta); + ICUNIT_GOTO_EQUAL(ret, ENOERR, ret, EXIT); + return LOS_OK; + +EXIT: + pthread_mutexattr_destroy(&mta); + return LOS_OK; +} + + +VOID ItPosixMux009(void) +{ + TEST_ADD_CASE("ItPosixMux009", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_010.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_010.c new file mode 100644 index 00000000..c92efefc --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_010.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +/* pthread_mutexattr_getprotocol 1-1.c + * Test that pthread_mutexattr_getprotocol() + * + * Gets the protocol attribute of a mutexattr object (which was prev. created + * by the function pthread_mutexattr_init()). + * + * Steps: + * 1. Initialize a pthread_mutexattr_t object with pthread_mutexattr_init() + * 2. Call pthread_mutexattr_getprotocol() to obtain the protocol. + * + */ +static UINT32 Testcase(VOID) +{ + pthread_mutexattr_t mta; + int protocol, rc; + + /* Initialize a mutex attributes object */ + rc = pthread_mutexattr_init(&mta); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + + /* Get the protocol mutex attr. */ + rc = pthread_mutexattr_getprotocol(&mta, &protocol); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + + rc = pthread_mutexattr_destroy(&mta); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT); + + return LOS_OK; + +EXIT: + pthread_mutexattr_destroy(&mta); + return LOS_OK; +} + + +VOID ItPosixMux010(void) +{ + TEST_ADD_CASE("ItPosixMux010", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_011.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_011.c new file mode 100644 index 00000000..9755d5e4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_011.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +/* pthread_mutexattr_getprotocol 1-2.c + * Test that pthread_mutexattr_getprotocol() + * + * Gets the protocol attribute of a mutexattr object (which was prev. created + * by the function pthread_mutexattr_init()). + * + */ +static UINT32 Testcase(VOID) +{ + pthread_mutexattr_t mta; + int protocol, protcls[3], i; + int rc; + + /* Initialize a mutex attributes object */ + rc = pthread_mutexattr_init(&mta); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + + protcls[0] = PTHREAD_PRIO_NONE; + protcls[1] = PTHREAD_PRIO_INHERIT; + protcls[2] = PTHREAD_PRIO_PROTECT; // 2, buffer index. + + for (i = 0; i < 3; i++) { // 3, The loop frequency. + /* Set the protocol to one of the 3 valid protocols. */ + rc = pthread_mutexattr_setprotocol(&mta, protcls[i]); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT); + + /* Get the protocol mutex attr. */ + rc = pthread_mutexattr_getprotocol(&mta, &protocol); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT); + + /* Make sure that the protocol set is the protocl we get when calling + * pthread_mutexattr_getprocol() */ + if (protocol != protcls[i]) { + ICUNIT_GOTO_EQUAL(1, 0, LOS_NOK, EXIT); + } + } + + rc = pthread_mutexattr_destroy(&mta); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT); + return LOS_OK; + +EXIT: + pthread_mutexattr_destroy(&mta); + return LOS_OK; +} + + +VOID ItPosixMux011(void) +{ + TEST_ADD_CASE("ItPosixMux011", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_013.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_013.c new file mode 100644 index 00000000..cc18d5b5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_013.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + pthread_mutexattr_t mta; + int prioceiling, ret; + + prioceiling = sched_get_priority_max(SCHED_RR); + prioceiling++; + + /* Set the prioceiling of an uninitialized mutex attr. */ + ret = pthread_mutexattr_setprioceiling(&mta, prioceiling); + ICUNIT_GOTO_EQUAL(ret, EINVAL, ret, EXIT); + + ret = pthread_mutexattr_destroy(&mta); + ICUNIT_GOTO_EQUAL(ret, ENOERR, ret, EXIT); + + return LOS_OK; + +EXIT: + pthread_mutexattr_destroy(&mta); + return LOS_OK; +} + + +VOID ItPosixMux013(void) +{ + TEST_ADD_CASE("ItPosixMux013", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_014.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_014.c new file mode 100644 index 00000000..ef84f312 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_014.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +/* pthread_mutexattr_setprioceiling 3-2.c + * Test that pthread_mutexattr_setprioceiling() + * + * It MAY fail if: + * + * [EINVAL] - 'attr' or 'prioceiling' is invalid. + * [EPERM] - The caller doesn't have the privilege to perform the operation. + * + * Steps: + * 1. Initialize a pthread_mutexattr_t object with pthread_mutexattr_init() + * 2. Call pthread_mutexattr_setprioceiling() with an invalid prioceiling value. + * + */ +static UINT32 Testcase(VOID) +{ + pthread_mutexattr_t mta; + int prioceiling, ret; + + /* Set 'prioceiling' out of SCHED_FIFO boundary. */ + prioceiling = sched_get_priority_min(SCHED_RR); + prioceiling--; + + /* Set the prioceiling to an invalid prioceiling. */ + ret = pthread_mutexattr_setprioceiling(&mta, prioceiling); + ICUNIT_GOTO_EQUAL(ret, EINVAL, ret, EXIT); + + ret = pthread_mutexattr_destroy(&mta); + ICUNIT_GOTO_EQUAL(ret, ENOERR, ret, EXIT); + + return LOS_OK; + +EXIT: + pthread_mutexattr_destroy(&mta); + return LOS_OK; +} + + +VOID ItPosixMux014(void) +{ + TEST_ADD_CASE("ItPosixMux014", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_017.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_017.c new file mode 100644 index 00000000..1dcad74e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_017.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +/* pthread_mutexattr_getprioceiling 3-1.c + * Test that pthread_mutexattr_getprioceiling() + * + * It MAY fail if: + * + * [EINVAL] - 'attr' or 'prioceiling' is invalid. + * [EPERM] - The caller doesn't have the privilege to perform the operation. + * + * This function shall not return an uwErr code of [EINTR] + * + * Steps: + * 1. Call pthread_mutexattr_getprioceiling() to obtain the prioceiling for an + * uninitialized pthread_mutexattr_t object. + * + */ +static UINT32 Testcase(VOID) +{ + int prioceiling, ret; + pthread_mutexattr_t mta; + + /* Get the prioceiling of an uninitialized mutex attr. */ + ret = pthread_mutexattr_getprioceiling(&mta, &prioceiling); + ICUNIT_ASSERT_EQUAL(ret, ENOERR, ret); + + ret = pthread_mutexattr_destroy(&mta); + ICUNIT_GOTO_EQUAL(ret, ENOERR, ret, EXIT); + + return LOS_OK; + +EXIT: + pthread_mutexattr_destroy(&mta); + return LOS_OK; +} + + +VOID ItPosixMux017(void) +{ + TEST_ADD_CASE("ItPosixMux017", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_018.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_018.c new file mode 100644 index 00000000..96b0932a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_018.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static pthread_mutex_t g_mutex1, g_mutex2; + +/* pthread_mutex_init 1-1.c + * Test that pthread_mutex_init() + * initializes a mutex referenced by 'mutex' with attributes specified + * by 'attr'. If 'attr' is NULL, the default mutex attributes are used. + * The effect shall be the same as passing the address of a default + * mutex attributes. + + * NOTE: There is no direct way to judge if two mutexes have the same effect, + * thus this test does not cover the statement in the last sentence. + * + */ +static UINT32 Testcase(VOID) +{ + pthread_mutexattr_t mta; + int rc; + + /* Initialize a mutex attributes object */ + rc = pthread_mutexattr_init(&mta); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + + /* Initialize mutex1 with the default mutex attributes */ + rc = pthread_mutex_init(&g_mutex1, &mta); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT1); + + /* Initialize mutex2 with NULL attributes */ + rc = pthread_mutex_init(&g_mutex2, NULL); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT2); + + rc = pthread_mutexattr_destroy(&mta); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT1); + + rc = pthread_mutex_destroy(&g_mutex1); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT2); + + rc = pthread_mutex_destroy(&g_mutex2); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT3); + + return LOS_OK; + +EXIT1: + pthread_mutexattr_destroy(&mta); + +EXIT2: + pthread_mutex_destroy(&g_mutex1); + +EXIT3: + pthread_mutex_destroy(&g_mutex2); + return LOS_OK; +} + + +VOID ItPosixMux018(void) +{ + TEST_ADD_CASE("ItPosixMux018", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_021.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_021.c new file mode 100644 index 00000000..9c3fb5ff --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_021.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +/* pthread_mutex_init 3-1.c + * Test that the macro PTHREAD_MUTEX_INITIALIZER can be sued to intiailize + * mutexes that are statically allocated. + * + */ +static UINT32 Testcase(VOID) +{ + pthread_mutex_t data = PTHREAD_MUTEX_INITIALIZER; + return LOS_OK; +} + + +VOID ItPosixMux021(void) +{ + TEST_ADD_CASE("ItPosixMux021", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_022.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_022.c new file mode 100644 index 00000000..7d06e933 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_022.c @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static pthread_mutex_t *g_mtx; +static sem_t g_semA, g_semB; +static pthread_mutex_t g_mtxNull; +static pthread_mutex_t g_mtxMacro = PTHREAD_MUTEX_INITIALIZER; + +void *UnlockIssue022(void *arg) +{ + int ret; + TestBusyTaskDelay(20); // 20, Set the timeout of runtime. + g_testCount++; + + if ((ret = pthread_mutex_lock(g_mtx))) { + ICUNIT_GOTO_EQUAL(1, 0, ret, EXIT); + } + + if ((ret = sem_post(&g_semA))) { + ICUNIT_GOTO_EQUAL(1, 0, ret, EXIT); + } + + if ((ret = sem_wait(&g_semB))) { + ICUNIT_GOTO_EQUAL(1, 0, ret, EXIT); + } + + if (g_retval != 0) { /* parent thread failed to unlock the mutex) */ + if ((ret = pthread_mutex_unlock(g_mtx))) { + ICUNIT_GOTO_EQUAL(1, 0, ret, EXIT); + } + } + + g_testCount++; +EXIT: + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t thr; + + pthread_mutex_t *tabMutex[2]; + int tabRes[2][3] = { {0, 0, 0}, {0, 0, 0} }; + + int ret; + void *thRet = NULL; + + int i; + + g_retval = 0; + + g_testCount = 0; + + /* We first initialize the two mutexes. */ + if ((ret = pthread_mutex_init(&g_mtxNull, NULL))) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + + tabMutex[0] = &g_mtxNull; + tabMutex[1] = &g_mtxMacro; + + if ((ret = sem_init(&g_semA, 0, 0))) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + if ((ret = sem_init(&g_semB, 0, 0))) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + /* OK let's go for the first part of the test : abnormals unlocking */ + + /* We first check if unlocking an unlocked mutex returns an uwErr. */ + g_retval = pthread_mutex_unlock(tabMutex[0]); + ICUNIT_ASSERT_NOT_EQUAL(g_retval, ENOERR, g_retval); + + ret = pthread_mutex_unlock(tabMutex[1]); + if (ret != g_retval) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + + /* Now we focus on unlocking a mutex lock by another thread */ + for (i = 0; i < 2; i++) { // 2, The loop frequency. + g_mtx = tabMutex[i]; + tabRes[i][0] = 0; + tabRes[i][1] = 0; + tabRes[i][2] = 0; // 2, buffer index. + + if ((ret = pthread_create(&thr, NULL, UnlockIssue022, NULL))) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + + if (i == 0) { + ICUNIT_ASSERT_EQUAL(g_testCount, 0, g_testCount); + } + if (i == 1) { + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, Assert that g_testCount. + } + + if ((ret = sem_wait(&g_semA))) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + + g_retval = pthread_mutex_unlock(g_mtx); + ICUNIT_ASSERT_EQUAL(g_retval, EPERM, g_retval); + + if ((ret = sem_post(&g_semB))) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + if (ret = pthread_join(thr, &thRet)) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + + if (i == 0) { + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, Assert that g_testCount. + } + if (i == 1) { + ICUNIT_ASSERT_EQUAL(g_testCount, 4, g_testCount); // 4, Assert that g_testCount. + } + + tabRes[i][0] = g_retval; + } + + if (tabRes[0][0] != tabRes[1][0]) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + + (void)pthread_mutex_destroy(&g_mtxNull); + (void)pthread_mutex_destroy(&g_mtxMacro); + (void)pthread_mutex_destroy(tabMutex[0]); + (void)pthread_mutex_destroy(tabMutex[1]); + + ret = sem_destroy(&g_semA); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = sem_destroy(&g_semB); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return LOS_OK; +} + + +VOID ItPosixMux022(void) +{ + TEST_ADD_CASE("ItPosixMux022", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_023.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_023.c new file mode 100644 index 00000000..0f0fd335 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_023.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +/* pthread_mutex_init 4-1.c + * Test that pthread_mutex_init() + * Upon successful completion, it shall return a 0 + * + */ +static UINT32 Testcase(VOID) +{ + pthread_mutexattr_t mta; + pthread_mutex_t mutex = TEST_MUTEX_INIT; + int rc; + + /* Initialize a mutex attributes object */ + rc = pthread_mutexattr_init(&mta); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + + /* Initialize a mutex object with the default mutex attributes */ + rc = pthread_mutex_init(&mutex, &mta); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT1); + + rc = pthread_mutexattr_destroy(&mta); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT2); + + rc = pthread_mutex_destroy(&mutex); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT2); + + return LOS_OK; + +EXIT2: + pthread_mutex_destroy(&mutex); + +EXIT1: + pthread_mutexattr_destroy(&mta); + + return LOS_OK; +} + + +VOID ItPosixMux023(void) +{ + TEST_ADD_CASE("ItPosixMux023", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_024.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_024.c new file mode 100644 index 00000000..e0a331e4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_024.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +/* pthread_mutex_destroy 1-1.c + * Test that pthread_mutex_destroy() + * shall destroy the mutex referenced by 'mutex'; the mutex object in effect + * becomes uninitialized. + * + */ +static UINT32 Testcase(VOID) +{ + pthread_mutexattr_t mta; + pthread_mutex_t mutex1 = TEST_MUTEX_INIT; + pthread_mutex_t mutex2 = TEST_MUTEX_INIT; + pthread_mutex_t mutex3 = PTHREAD_MUTEX_INITIALIZER; + int rc; + + /* Initialize a mutex attributes object */ + rc = pthread_mutexattr_init(&mta); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + + /* Initialize mutex1 with the default mutex attributes */ + rc = pthread_mutex_init(&mutex1, &mta); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT1); + + /* Initialize mutex2 with NULL attributes */ + rc = pthread_mutex_init(&mutex2, NULL); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT3); + + /* Destroy the mutex attributes object */ + rc = pthread_mutexattr_destroy(&mta); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT3); + + /* Destroy mutex1 */ + rc = pthread_mutex_destroy(&mutex1); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT3); + + /* Destroy mutex2 */ + rc = pthread_mutex_destroy(&mutex2); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT2); + + /* Destroy mutex3 */ + rc = pthread_mutex_destroy(&mutex3); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT1); + + return LOS_OK; + +EXIT3: + pthread_mutex_destroy(&mutex1); + +EXIT2: + pthread_mutex_destroy(&mutex2); + +EXIT1: + pthread_mutexattr_destroy(&mta); + pthread_mutex_destroy(&mutex3); + + return LOS_OK; +} + + +VOID ItPosixMux024(void) +{ + TEST_ADD_CASE("ItPosixMux024", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_025.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_025.c new file mode 100644 index 00000000..b7dc3131 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_025.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +/* pthread_mutex_destroy 2-1.c + * Test pthread_mutex_destroy() that + * a destroyed mutex object can be reinitialized using pthread_mutex_init() + * + */ +static UINT32 Testcase(VOID) +{ + pthread_mutex_t mutex = TEST_MUTEX_INIT; + int rc; + + /* Initialize a mutex attributes object */ + rc = pthread_mutex_init(&mutex, NULL); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + + /* Destroy the mutex attributes object */ + rc = pthread_mutex_destroy(&mutex); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT); + + /* Initialize the mutex attributes object again. This shouldn't result in an uwErr. */ + rc = pthread_mutex_init(&mutex, NULL); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + + rc = pthread_mutex_destroy(&mutex); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT); + + return LOS_OK; + +EXIT: + pthread_mutex_destroy(&mutex); + return LOS_OK; +} + + +VOID ItPosixMux025(void) +{ + TEST_ADD_CASE("ItPosixMux025", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_026.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_026.c new file mode 100644 index 00000000..c9c42284 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_026.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +struct _scenar_028 { + int m_type; /* Mutex type to use */ + int m_pshared; /* 0: mutex is process-private (default) ~ !0: mutex is process-shared, if supported */ + char *descr; /* Case description */ +} g_scenarii028[] = { + {PTHREAD_MUTEX_DEFAULT, 0, "Default mutex"}, + {PTHREAD_MUTEX_NORMAL, 0, "Normal mutex"}, + {PTHREAD_MUTEX_ERRORCHECK, 0, "Errorcheck mutex"}, + {PTHREAD_MUTEX_RECURSIVE, 0, "Recursive mutex"}, + {PTHREAD_MUTEX_DEFAULT, 1, "Pshared mutex"}, + {PTHREAD_MUTEX_NORMAL, 1, "Pshared Normal mutex"}, + {PTHREAD_MUTEX_ERRORCHECK, 1, "Pshared Errorcheck mutex"}, + {PTHREAD_MUTEX_RECURSIVE, 1, "Pshared Recursive mutex"} +}; + +#define NSCENAR (sizeof(g_scenarii028) / sizeof(g_scenarii028[0])) + +static UINT32 Testcase(VOID) +{ + int ret; + int i, j; + pthread_mutex_t mtx; + pthread_mutexattr_t ma[NSCENAR + 1]; + pthread_mutexattr_t *pma[NSCENAR + 2]; + long pshared; + + pshared = sysconf(_SC_THREAD_PROCESS_SHARED); + + for (i = 0; i < NSCENAR; i++) { + ret = pthread_mutexattr_init(&ma[i]); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + } + + ret = pthread_mutexattr_init(&ma[i]); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + for (i = 0; i < NSCENAR + 2; i++) // 2, The loop frequency. + /* NULL pointer */ + pma[i] = NULL; + + for (i = 0; i < NSCENAR + 2; i++) { // 2, The loop frequency. + for (j = 0; j < NSCENAR + 2; j++) { // 2, The loop frequency. + ret = pthread_mutex_init(&mtx, pma[i]); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&mtx); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_init(&mtx, pma[j]); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&mtx); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + } + } + for (i = 0; i < NSCENAR + 1; i++) { + ret = pthread_mutexattr_destroy(&ma[i]); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + } + + return LOS_OK; +} + + +VOID ItPosixMux026(void) +{ + TEST_ADD_CASE("ItPosixMux026", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_027.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_027.c new file mode 100644 index 00000000..8074cd65 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_027.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +/* pthread_mutex_destroy 3-1.c + * Test that pthread_mutex_destroy() + * Upon successful completion, it shall return a 0 + * + */ +static UINT32 Testcase(VOID) +{ + pthread_mutex_t mutex = TEST_MUTEX_INIT; + int rc; + + /* Initialize a mutex object */ + rc = pthread_mutex_init(&mutex, NULL); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + + rc = pthread_mutex_destroy(&mutex); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT); + + return LOS_OK; + +EXIT: + pthread_mutex_destroy(&mutex); + return LOS_OK; +} + + +VOID ItPosixMux027(void) +{ + TEST_ADD_CASE("ItPosixMux027", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_028.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_028.c new file mode 100644 index 00000000..fb0a43e4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_028.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +/* pthread_mutex_destroy 4-2.c + * Test that when a pthread_mutex_destroy is called on a + * locked mutex, it fails and returns EBUSY + + * Steps: + * 1. Create a mutex + * 2. Lock the mutex + * 3. Try to destroy the mutex + * 4. Check that this may fail with EBUSY + */ + +static UINT32 Testcase(VOID) +{ + pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + int rc; + + /* Lock the mutex */ + rc = pthread_mutex_lock(&mutex); + if (rc != 0) { + ICUNIT_ASSERT_EQUAL(1, 0, rc); + } + + /* Try to destroy the locked mutex */ + rc = pthread_mutex_destroy(&mutex); + if (rc == EBUSY) { + pthread_mutex_unlock(&mutex); + pthread_mutex_destroy(&mutex); + return LOS_OK; + } + + return LOS_NOK; +} + + +VOID ItPosixMux028(void) +{ + TEST_ADD_CASE("ItPosixMux028", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_029.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_029.c new file mode 100644 index 00000000..ef4473b3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_029.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +/* pthread_mutex_destroy 5-1.c + * Test that pthread_mutex_destroy() + * It shall be safe to destroy an initialized mutex that is unlocked. + */ +static UINT32 Testcase(VOID) +{ + int rc; + pthread_mutex_t mutex = TEST_MUTEX_INIT; + + /* Initialize mutex with the default mutex attributes */ + rc = pthread_mutex_init(&mutex, NULL); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + + /* Lock mutex */ + rc = pthread_mutex_lock(&mutex); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT); + + sleep(1); + /* Unlock */ + rc = pthread_mutex_unlock(&mutex); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT1); + + /* Destroy mutex after it is unlocked */ + rc = pthread_mutex_destroy(&mutex); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT); + + return LOS_OK; + +EXIT1: + pthread_mutex_unlock(&mutex); + +EXIT: + pthread_mutex_destroy(&mutex); + return LOS_OK; +} + + +VOID ItPosixMux029(void) +{ + TEST_ADD_CASE("ItPosixMux029", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_032.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_032.c new file mode 100644 index 00000000..981d8409 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_032.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +/* pthread_mutex_getprioceiling 1-1.c + * + * Test that pthread_mutex_getprioceiling() returns the current prioceiling of + * the mutex with PTHREAD_PRIO_PROTECT. + * + * Steps: + * 1. Initialize a pthread_mutexattr_t object with pthread_mutexattr_init() + * 2. Set the protocol using PTHREAD_PRIO_PROTECT. + * 3. Call pthread_mutex_getprioceiling() to obtain the prioceiling. + * + */ +static UINT32 Testcase(VOID) +{ + pthread_mutexattr_t mutexAttr; + pthread_mutex_t mutex = TEST_MUTEX_INIT; + int err, prioceiling; + + err = pthread_mutexattr_init(&mutexAttr); + ICUNIT_ASSERT_EQUAL(err, ENOERR, err); + + /* + * Has to be something other than PTHREAD_PRIO_NONE, the default as per + * pthread_mutexattr_getprotocol. + */ + err = pthread_mutexattr_setprotocol(&mutexAttr, PTHREAD_PRIO_PROTECT); + ICUNIT_ASSERT_EQUAL(err, ENOERR, err); + + /* Initialize a mutex object */ + err = pthread_mutex_init(&mutex, &mutexAttr); + ICUNIT_ASSERT_EQUAL(err, ENOERR, err); + + /* Get the prioceiling of the mutex. */ + err = pthread_mutex_getprioceiling(&mutex, &prioceiling); + ICUNIT_ASSERT_EQUAL(err, ENOERR, err); + + err = pthread_mutexattr_destroy(&mutexAttr); + ICUNIT_GOTO_EQUAL(err, ENOERR, err, EXIT1); + + err = pthread_mutex_destroy(&mutex); + ICUNIT_GOTO_EQUAL(err, ENOERR, err, EXIT2); + + return LOS_OK; + +EXIT1: + pthread_mutexattr_destroy(&mutexAttr); + +EXIT2: + pthread_mutex_destroy(&mutex); + return LOS_OK; +} + + +VOID ItPosixMux032(void) +{ + TEST_ADD_CASE("ItPosixMux032", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_033.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_033.c new file mode 100644 index 00000000..cd4443ff --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_033.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +/* pthread_mutex_getprioceiling 3-1.c + * Test that pthread_mutex_getprioceiling() fails because: + * + * [EINVAL] + * The protocol attribute of mutex is PTHREAD_PRIO_NONE. + * + * by not specifying PTHREAD_PRIO_NONE and noting that the default (as per + * pthread_mutexattr_getprotocol) is PTHREAD_PRIO_NONE. + * + * Steps: + * 1. Initialize a mutex via pthread_mutex_init. + * 2. Do not modify the mutex. + * 3. Call pthread_mutex_getprioceiling() to obtain the prioceiling. + * + */ +static UINT32 Testcase(VOID) +{ + pthread_mutex_t mutex = TEST_MUTEX_INIT; + int err, prioceiling; + + /* Initialize a mutex object */ + err = pthread_mutex_init(&mutex, NULL); + ICUNIT_ASSERT_EQUAL(err, ENOERR, err); + + /* Get the prioceiling of the mutex. */ + err = pthread_mutex_getprioceiling(&mutex, &prioceiling); + ICUNIT_GOTO_EQUAL(err, ENOERR, err, EXIT); + + err = pthread_mutex_destroy(&mutex); + ICUNIT_GOTO_EQUAL(err, ENOERR, err, EXIT); + + return LOS_OK; + +EXIT: + pthread_mutex_destroy(&mutex); + return LOS_OK; +} + + +VOID ItPosixMux033(void) +{ + TEST_ADD_CASE("ItPosixMux033", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_034.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_034.c new file mode 100644 index 00000000..76360302 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_034.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +/* pthread_mutex_getprioceiling 3-2.c + * Test that pthread_mutex_getprioceiling() fails because: + * + * [EINVAL] + * The protocol attribute of mutex is PTHREAD_PRIO_NONE. + * + * by explicitly specifying the protocol as PTHREAD_PRIO_NONE. + * + * Steps: + * 1. Initialize a pthread_mutexattr_t object with pthread_mutexattr_init() + * 2. Explicitly set the protocol using PTHREAD_PRIO_NONE. + * 3. Call pthread_mutex_getprioceiling() to obtain the prioceiling. + * + */ +static UINT32 Testcase(VOID) +{ + pthread_mutexattr_t mutexAttr; + pthread_mutex_t mutex = TEST_MUTEX_INIT; + int err, prioceiling; + + err = pthread_mutexattr_init(&mutexAttr); + ICUNIT_ASSERT_EQUAL(err, ENOERR, err); + + /* + * The default protocol is PTHREAD_PRIO_NONE according to + * pthread_mutexattr_getprotocol. + */ + err = pthread_mutexattr_setprotocol(&mutexAttr, PTHREAD_PRIO_NONE); + ICUNIT_ASSERT_EQUAL(err, ENOERR, err); + + /* Initialize a mutex object */ + err = pthread_mutex_init(&mutex, &mutexAttr); + ICUNIT_GOTO_EQUAL(err, ENOERR, err, EXIT1); + + /* Get the prioceiling of the mutex. */ + err = pthread_mutex_getprioceiling(&mutex, &prioceiling); + ICUNIT_GOTO_EQUAL(err, ENOERR, err, EXIT2); + + err = pthread_mutexattr_destroy(&mutexAttr); + ICUNIT_GOTO_EQUAL(err, ENOERR, err, EXIT1); + + err = pthread_mutex_destroy(&mutex); + ICUNIT_GOTO_EQUAL(err, ENOERR, err, EXIT2); + + return LOS_OK; + +EXIT2: + pthread_mutex_destroy(&mutex); + +EXIT1: + pthread_mutexattr_destroy(&mutexAttr); + return LOS_OK; +} + + +VOID ItPosixMux034(void) +{ + TEST_ADD_CASE("ItPosixMux034", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_035.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_035.c new file mode 100644 index 00000000..1c26f584 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_035.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +/* pthread_mutex_getprioceiling 3-3.c + * Test that pthread_mutex_getprioceiling() fails because: + * + * [EINVAL] + * The protocol attribute of mutex is PTHREAD_PRIO_NONE. + * + * by explicitly specifying the protocol as PTHREAD_PRIO_NONE. + * + * Steps: + * 1. Initialize a pthread_mutexattr_t object with pthread_mutexattr_init() + * 2. Explicitly set the protocol using PTHREAD_PRIO_NONE. + * 3. Call pthread_mutex_getprioceiling() to obtain the prioceiling. + * + */ +static UINT32 Testcase(VOID) +{ + pthread_mutexattr_t mutexAttr; + pthread_mutex_t mutex = TEST_MUTEX_INIT; + int err, prioceiling; + + err = pthread_mutexattr_init(&mutexAttr); + ICUNIT_ASSERT_EQUAL(err, ENOERR, err); + + /* + * The default protocol is PTHREAD_PRIO_NONE according to + * pthread_mutexattr_getprotocol. + */ + err = pthread_mutexattr_setprotocol(&mutexAttr, PTHREAD_PRIO_INHERIT); + ICUNIT_GOTO_EQUAL(err, ENOERR, err, EXIT1); + + /* Initialize a mutex object */ + err = pthread_mutex_init(&mutex, &mutexAttr); + ICUNIT_GOTO_EQUAL(err, ENOERR, err, EXIT1); + + /* Get the prioceiling of the mutex. */ + err = pthread_mutex_getprioceiling(&mutex, &prioceiling); + ICUNIT_GOTO_EQUAL(err, ENOERR, err, EXIT2); + + err = pthread_mutexattr_destroy(&mutexAttr); + ICUNIT_GOTO_EQUAL(err, ENOERR, err, EXIT1); + + err = pthread_mutex_destroy(&mutex); + ICUNIT_GOTO_EQUAL(err, ENOERR, err, EXIT2); + + return LOS_OK; + +EXIT2: + pthread_mutex_destroy(&mutex); + +EXIT1: + pthread_mutexattr_destroy(&mutexAttr); + return LOS_OK; +} + + +VOID ItPosixMux035(void) +{ + TEST_ADD_CASE("ItPosixMux035", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_036.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_036.c new file mode 100644 index 00000000..64f75083 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_036.c @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +#define THREAD_NUM 5 +#define LOOPS 4 + +static pthread_mutex_t g_mutex036 = PTHREAD_MUTEX_INITIALIZER; + +/* pthread_mutex_lock 1-1.c + * Test that pthread_mutex_lock() + * shall lock the mutex object referenced by 'mutex'. If the mutex is + * already locked, the calling thread shall block until the mutex becomes + * available. This operation shall return with the mutex object referenced + * by 'mutex' in the locked state with the calling thread as its owner. + + * Steps: + * -- Initialize a mutex to protect a global variable 'value' + * -- Create N threads. Each is looped M times to acquire the mutex, + * increase the value, and then release the mutex. + * -- Check if the value has increased properly (M*N); a broken mutex + * implementation may cause lost augments. + * + */ + +static void *TaskF01(void *parm) +{ + int i, tmp; + int rc; + + /* Loopd M times to acquire the mutex, increase the value, + and then release the mutex. */ + for (i = 0; i < LOOPS; ++i) { + rc = pthread_mutex_lock(&g_mutex036); + if (rc != 0) { + return (void *)(LOS_NOK); + } + + tmp = g_value; + tmp = tmp + 1; + sleep(1); + g_value = tmp; + + rc = pthread_mutex_unlock(&g_mutex036); + if (rc != 0) { + return (void *)(LOS_NOK); + } + sleep(1); + } + + return (void *)(LOS_OK); +} + +static UINT32 Testcase(VOID) +{ + int i, rc; + pthread_attr_t pta; + pthread_t threads[THREAD_NUM]; + + g_value = 0; + + pthread_attr_init(&pta); + pthread_attr_setdetachstate(&pta, PTHREAD_CREATE_JOINABLE); + + /* Create threads */ + for (i = 0; i < THREAD_NUM; ++i) { + rc = pthread_create(&threads[i], &pta, TaskF01, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + } + + /* Wait to join all threads */ + for (i = 0; i < THREAD_NUM; ++i) { + rc = pthread_join(threads[i], NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + } + pthread_attr_destroy(&pta); + pthread_mutex_destroy(&g_mutex036); + + /* Check if the final value is as expected */ + if (g_value != (THREAD_NUM)*LOOPS) { + return LOS_NOK; + } + + return LOS_OK; +} + + +VOID ItPosixMux036(void) +{ + TEST_ADD_CASE("ItPosixMux036", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_037.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_037.c new file mode 100644 index 00000000..1b9e12a7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_037.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +/* pthread_mutex_lock 2-1.c + * This file is licensed under the GPL license. For the full content + * of this license, see the COPYING file at the top level of this + * source tree. + + * Test that pthread_mutex_lock() + * Upon successful completion, it shall return a 0 + * + */ +static UINT32 Testcase(VOID) +{ + pthread_mutex_t mutex; + int rc; + + /* Initialize a mutex object with the default mutex attributes */ + rc = pthread_mutex_init(&mutex, NULL); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + + /* Lock the mutex using pthread_mutex_lock() */ + rc = pthread_mutex_lock(&mutex); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT1); + + rc = pthread_mutex_unlock(&mutex); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT2); + + rc = pthread_mutex_destroy(&mutex); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT1); + + return LOS_OK; + +EXIT2: + pthread_mutex_unlock(&mutex); +EXIT1: + pthread_mutex_destroy(&mutex); + return LOS_OK; +} + + +VOID ItPosixMux037(void) +{ + TEST_ADD_CASE("ItPosixMux037", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_038.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_038.c new file mode 100644 index 00000000..9dde4c5a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_038.c @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static pthread_mutex_t g_mutex038; +static sem_t g_sem038; + +static void *TaskF01(void *arg) +{ + int ret; + + ret = pthread_mutex_trylock(&g_mutex038); + if (ret == 0) { + ICUNIT_GOTO_EQUAL(1, 0, ret, EXIT); + } + + if ((ret = sem_post(&g_sem038))) { + ICUNIT_GOTO_EQUAL(1, 0, ret, EXIT); + } + + if ((ret = pthread_mutex_lock(&g_mutex038))) { + ICUNIT_GOTO_EQUAL(1, 0, ret, EXIT); + } + + if ((ret = sem_post(&g_sem038))) { + ICUNIT_GOTO_EQUAL(1, 0, ret, EXIT); + } + + if ((ret = pthread_mutex_unlock(&g_mutex038))) { + ICUNIT_GOTO_EQUAL(1, 0, ret, EXIT); + } +EXIT: + return NULL; +} + +static UINT32 Testcase(VOID) +{ + int ret; + int i; + pthread_mutexattr_t ma; + pthread_t child; + + if ((ret = sem_init(&g_sem038, 0, 0))) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + + if ((ret = pthread_mutexattr_init(&ma))) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + + if ((ret = pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_RECURSIVE))) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + + if ((ret = pthread_mutex_init(&g_mutex038, &ma))) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + + if ((ret = pthread_mutexattr_destroy(&ma))) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + + if ((ret = pthread_mutex_lock(&g_mutex038))) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + + if ((ret = pthread_mutex_lock(&g_mutex038))) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + + if ((ret = pthread_mutex_unlock(&g_mutex038))) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + + if ((ret = pthread_create(&child, NULL, TaskF01, NULL))) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + + if ((ret = sem_wait(&g_sem038))) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + + if ((ret = pthread_mutex_unlock(&g_mutex038))) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + + if ((ret = sem_wait(&g_sem038))) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + + ret = pthread_mutex_unlock(&g_mutex038); + if (ret == ENOERR) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + + if ((ret = pthread_join(child, NULL))) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + + for (i = 0; i < 50; i++) { // 50, The loop frequency. + if ((ret = pthread_mutex_lock(&g_mutex038))) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + } + for (i = 0; i < 50; i++) { // 50, The loop frequency. + if ((ret = pthread_mutex_unlock(&g_mutex038))) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + } + + ret = pthread_mutex_unlock(&g_mutex038); + if (ret == 0) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + if ((ret = pthread_mutex_destroy(&g_mutex038))) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + + ret = sem_destroy(&g_sem038); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return LOS_OK; +} + + +VOID ItPosixMux038(void) +{ + TEST_ADD_CASE("ItPosixMux038", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_039.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_039.c new file mode 100644 index 00000000..b2289552 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_039.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +/* pthread_mutex_unlock 1-1.c + * Test that pthread_mutex_unlock() + * shall release the mutex object 'mutex'. + + * Steps: + * -- initialize a mutex object + * -- Get the mutex using pthread_mutex_lock() + * -- Release the mutex using pthread_mutex_unlock() + * -- Try to get the mutex using pthread_mutex_trylock() + * -- Release the mutex using pthread_mutex_unlock() + * + */ +static UINT32 Testcase(VOID) +{ + int rc; + pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + + /* Get the mutex using pthread_mutex_lock() */ + rc = pthread_mutex_lock(&mutex); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + + /* Release the mutex using pthread_mutex_unlock() */ + rc = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + + /* Get the mutex using pthread_mutex_trylock() */ + rc = pthread_mutex_trylock(&mutex); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + + /* Release the mutex using pthread_mutex_unlock() */ + rc = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + + rc = pthread_mutex_destroy(&mutex); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT); + + return LOS_OK; + +EXIT: + pthread_mutex_destroy(&mutex); + return LOS_OK; +} + + +VOID ItPosixMux039(void) +{ + TEST_ADD_CASE("ItPosixMux039", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_040.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_040.c new file mode 100644 index 00000000..4da38267 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_040.c @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +#define THREAD_NUM 6 +#define LOOPS 3 + +static pthread_mutex_t g_mutex040 = PTHREAD_MUTEX_INITIALIZER; + +/* pthread_mutex_unlock 2-1.c + * Test that pthread_mutex_unlock() + * If there are threads blocked on the mutex object referenced by 'mutex' when + * pthread_mutex_unlock() is called, resulting in the mutex becoming available, + * the scheduling policy shall determine which thread shall acquire the mutex. + + * NOTES: + * The default scheduling policy is implementation dependent, thus this case + * will only demo the scheduling sequence instead of testing it. + + * Steps: + * -- Initialize a mutex to protect a global variable 'value' + * -- Create N threads. Each is looped M times to acquire the mutex, + increase the value, and then release the mutex. + * -- Check if the value has increased properly (M*N); a broken mutex + implementation may cause lost augments. + * + */ +static void *TaskF01(void *parm) +{ + int i, tmp; + int rc; + + /* Loopd M times to acquire the mutex, increase the value, + and then release the mutex. */ + + for (i = 0; i < LOOPS; ++i) { + rc = pthread_mutex_lock(&g_mutex040); + if (rc != 0) { + return (void *)(LOS_NOK); + } + + tmp = g_value; + tmp = tmp + 1; + usleep(1000); // 1000, delay the increasement operation. + g_value = tmp; + + rc = pthread_mutex_unlock(&g_mutex040); + if (rc != 0) { + return (void *)(LOS_NOK); + } + sleep(1); + } + pthread_exit(0); + return (void *)(LOS_OK); +} + +static UINT32 Testcase(VOID) +{ + int i, rc; + pthread_t threads[THREAD_NUM]; + + g_value = 0; + /* Create threads */ + for (i = 0; i < THREAD_NUM; ++i) { + rc = pthread_create(&threads[i], NULL, TaskF01, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + } + + /* Wait to join all threads */ + for (i = 0; i < THREAD_NUM; ++i) { + rc = pthread_join(threads[i], NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + } + pthread_mutex_destroy(&g_mutex040); + + /* Check if the final value is as expected */ + if (g_value != (THREAD_NUM)*LOOPS) { + ICUNIT_ASSERT_EQUAL(1, 0, LOS_NOK); + } + + return LOS_OK; +} + + +VOID ItPosixMux040(void) +{ + TEST_ADD_CASE("ItPosixMux040", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_041.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_041.c new file mode 100644 index 00000000..89318019 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_041.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +/* pthread_mutex_unlock 3-1.c + * Test that pthread_mutex_unlock() + * Upon successful completion, it shall return zero + * + */ +static UINT32 Testcase(VOID) +{ + pthread_mutex_t mutex = TEST_MUTEX_INIT; + int rc; + + /* Initialize a mutex object */ + rc = pthread_mutex_init(&mutex, NULL); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + + rc = pthread_mutex_lock(&mutex); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + + /* Release the mutex using pthread_mutex_unlock() */ + rc = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + + rc = pthread_mutex_destroy(&mutex); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + + return LOS_OK; +} + + +VOID ItPosixMux041(void) +{ + TEST_ADD_CASE("ItPosixMux041", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_042.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_042.c new file mode 100644 index 00000000..6a80c922 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_042.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static pthread_mutex_t g_mutex042; + +static void *TaskF01(void *arg) +{ + int ret; + ret = pthread_mutex_unlock(&g_mutex042); + ICUNIT_GOTO_EQUAL(ret, EPERM, ret, EXIT); + +EXIT: + return NULL; +} + +static UINT32 Testcase(VOID) +{ + int ret; + pthread_mutexattr_t ma; + pthread_t th; + + ret = pthread_mutexattr_init(&ma); + ICUNIT_ASSERT_EQUAL(ret, ENOERR, ret); + + ret = pthread_mutex_init(&g_mutex042, &ma); + ICUNIT_ASSERT_EQUAL(ret, ENOERR, ret); + + ret = pthread_mutex_lock(&g_mutex042); + ICUNIT_ASSERT_EQUAL(ret, ENOERR, ret); + + /* destroy the mutex attribute object */ + ret = pthread_mutexattr_destroy(&ma); + ICUNIT_ASSERT_EQUAL(ret, ENOERR, ret); + + ret = pthread_create(&th, NULL, TaskF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, ENOERR, ret); + + /* Let the thread terminate */ + ret = pthread_join(th, NULL); + ICUNIT_GOTO_EQUAL(ret, ENOERR, ret, EXIT); + + /* We can clean everything and exit */ + ret = pthread_mutex_unlock(&g_mutex042); + ICUNIT_GOTO_EQUAL(ret, ENOERR, ret, EXIT); + + ret = pthread_mutex_destroy(&g_mutex042); + ICUNIT_GOTO_EQUAL(ret, ENOERR, ret, EXIT); + return LOS_OK; + +EXIT: + pthread_join(th, NULL); + pthread_mutex_unlock(&g_mutex042); + pthread_mutex_destroy(&g_mutex042); + return LOS_OK; +} + + +VOID ItPosixMux042(void) +{ + TEST_ADD_CASE("ItPosixMux042", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_043.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_043.c new file mode 100644 index 00000000..ebbc4f66 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_043.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + int ret; + pthread_mutex_t mutex = TEST_MUTEX_INIT; + pthread_mutexattr_t ma; + + ret = pthread_mutexattr_init(&ma); + if (ret != 0) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + + ret = pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_RECURSIVE); + if (ret != 0) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + + ret = pthread_mutex_init(&mutex, &ma); + if (ret != 0) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + + ret = pthread_mutex_unlock(&mutex); + if (ret == 0) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + + ret = pthread_mutex_lock(&mutex); + if (ret != 0) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + ret = pthread_mutex_lock(&mutex); + if (ret != 0) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + ret = pthread_mutex_unlock(&mutex); + if (ret != 0) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + ret = pthread_mutex_unlock(&mutex); + if (ret != 0) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + + /* destroy the mutex attribute object */ + ret = pthread_mutexattr_destroy(&ma); + if (ret != 0) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + + ret = pthread_mutex_unlock(&mutex); + if (ret == 0) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + ret = pthread_mutex_destroy(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&mutex); + if (ret == 0) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + return LOS_OK; +} + + +VOID ItPosixMux043(void) +{ + TEST_ADD_CASE("ItPosixMux043", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_044.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_044.c new file mode 100644 index 00000000..f0af9e21 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_044.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static pthread_mutex_t g_mutex044 = PTHREAD_MUTEX_INITIALIZER; +static int g_t1Start = 0; +static int g_t1Pause = 1; + +static void *TaskF01(void *parm) +{ + int rc; + if ((rc = pthread_mutex_lock(&g_mutex044)) != 0) { + ICUNIT_GOTO_EQUAL(1, 0, rc, EXIT); + } + + g_t1Start = 1; + + g_testCount++; + + while (g_t1Pause) + sleep(1); + + g_testCount++; + + if ((rc = pthread_mutex_unlock(&g_mutex044)) != 0) { + ICUNIT_GOTO_EQUAL(1, 0, rc, EXIT); + } + g_testCount++; + +EXIT: + pthread_exit(0); + return (void *)(LOS_OK); +} + +static UINT32 Testcase(VOID) +{ + int i, rc; + pthread_t t1; + g_testCount = 0; + + /* Create a secondary thread and wait until it has locked the mutex */ + rc = pthread_create(&t1, NULL, TaskF01, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + while (!g_t1Start) { + sleep(1); + } + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + /* Trylock the mutex and expect it returns EBUSY */ + rc = pthread_mutex_trylock(&g_mutex044); + if (rc != EBUSY) { + ICUNIT_ASSERT_EQUAL(1, 0, rc); + } + + /* Allow the secondary thread to go ahead */ + g_t1Pause = 0; + /* Trylock the mutex for N times */ + for (i = 0; i < 5; i++) { // 5, The loop frequency. + rc = pthread_mutex_trylock(&g_mutex044); + if (rc == 0) { + pthread_mutex_unlock(&g_mutex044); + break; + } else if (rc == EBUSY) { + sleep(1); + continue; + } else { + ICUNIT_ASSERT_EQUAL(1, 0, rc); + } + } + + /* Clean up */ + pthread_join(t1, NULL); + pthread_mutex_destroy(&g_mutex044); + + if (i >= 5) { // 5, The loop frequency. + ICUNIT_ASSERT_EQUAL(1, 0, LOS_NOK); + } + + g_t1Pause = 1; + g_t1Start = 0; + return LOS_OK; +} + + +VOID ItPosixMux044(void) +{ + TEST_ADD_CASE("ItPosixMux044", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_045.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_045.c new file mode 100644 index 00000000..9485153b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_045.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static pthread_mutex_t g_mutex045; + +static VOID *TaskF01(void *argument) +{ + int ret; + ret = pthread_mutex_trylock(&g_mutex045); + ICUNIT_GOTO_EQUAL(ret, EBUSY, ret, EXIT); + + return NULL; + +EXIT: + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_mutexattr_t mta; + int ret; + + pthread_attr_t attr; + pthread_t newTh; + + ret = pthread_mutexattr_init(&mta); + ret = pthread_mutex_init(&g_mutex045, &mta); + + ret = pthread_mutex_trylock(&g_mutex045); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_trylock(&g_mutex045); + ICUNIT_ASSERT_EQUAL(ret, EBUSY, ret); + + ret = PosixPthreadInit(&attr, 4); // 4, Set thread priority. + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newTh, &attr, TaskF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&g_mutex045); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + pthread_mutex_destroy(&g_mutex045); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return LOS_OK; +} + + +VOID ItPosixMux045(void) +{ + TEST_ADD_CASE("ItPosixMux045", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_046.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_046.c new file mode 100644 index 00000000..1c44de79 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_046.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static pthread_mutex_t g_mutex046; +static UINT32 g_nID; + +static void *TaskF01(void *arg) +{ + int ret; + ret = pthread_mutex_trylock(&g_mutex046); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_nID = OsCurrTaskGet()->taskID; + LOS_TaskSuspend(OsCurrTaskGet()->taskID); + + ret = pthread_mutex_unlock(&g_mutex046); + + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + +EXIT: + return NULL; +} + +static UINT32 Testcase(VOID) +{ + int ret; + pthread_t newTh; + pthread_attr_t attr; + + ret = pthread_mutex_init(&g_mutex046, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_trylock(&g_mutex046); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_trylock(&g_mutex046); + ICUNIT_ASSERT_EQUAL(ret, EBUSY, ret); + + ret = pthread_mutex_unlock(&g_mutex046); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadInit(&attr, 4); // 4, Set thread priority. + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newTh, &attr, TaskF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&g_mutex046); + ICUNIT_ASSERT_EQUAL(ret, EPERM, ret); + + LOS_TaskResume(g_nID); + + ret = pthread_mutex_unlock(&g_mutex046); + ICUNIT_ASSERT_NOT_EQUAL(ret, ENOERR, ret); + + ret = pthread_mutex_destroy(&g_mutex046); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return LOS_OK; +} + + +VOID ItPosixMux046(void) +{ + TEST_ADD_CASE("ItPosixMux046", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_047.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_047.c new file mode 100644 index 00000000..0b528fe3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_047.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +/* pthread_mutex_trylock 3-1.c + * Test that pthread_mutex_trylock() + * Upon successful completion, it shall return a 0 + * + */ +static UINT32 Testcase(VOID) +{ + int rc; + pthread_mutex_t mutex = TEST_MUTEX_INIT; + /* Initialize a mutex object with the default mutex attributes */ + if ((rc = pthread_mutex_init(&mutex, NULL)) != 0) { + ICUNIT_ASSERT_EQUAL(1, 0, rc); + } + + /* Try to lock the mutex using pthread_mutex_trylock() */ + if ((rc = pthread_mutex_trylock(&mutex)) == 0) { + pthread_mutex_unlock(&mutex); + pthread_mutex_destroy(&mutex); + return LOS_OK; + + /* Check if returned values are tolerable */ + /* PATCH: since we are using the mutex properly, */ + /* errors are NOT tolerable here */ + } else if (rc == EBUSY) { + ICUNIT_ASSERT_EQUAL(1, 0, rc); + } else if (rc == EINVAL) { + ICUNIT_ASSERT_EQUAL(1, 0, rc); + } else if (rc == EAGAIN) { + ICUNIT_ASSERT_EQUAL(1, 0, rc); + } +} + + +VOID ItPosixMux047(void) +{ + TEST_ADD_CASE("ItPosixMux047", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_048.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_048.c new file mode 100644 index 00000000..db32c4be --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_048.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +/* pthread_mutex_trylock 4-1.c + * Test that pthread_mutex_trylock() + * Upon failure, it shall return: + * -[EBUSY] The mutex could not be acquired because it was already locked. + + * Steps: + * -- initialize a mutex object + * -- Lock the mutex using pthread_mutex_lock() + * -- Try to lock the mutex using pthread_mutex_trylock() and expect EBUSY + * + */ +static UINT32 Testcase(VOID) +{ + int rc; + pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + + if ((rc = pthread_mutex_lock(&mutex)) != 0) { + ICUNIT_ASSERT_EQUAL(1, 0, rc); + } + + rc = pthread_mutex_trylock(&mutex); + if (rc != EBUSY) { + ICUNIT_ASSERT_EQUAL(1, 0, rc); + } + + pthread_mutex_unlock(&mutex); + pthread_mutex_destroy(&mutex); + + return LOS_OK; +} + + +VOID ItPosixMux048(void) +{ + TEST_ADD_CASE("ItPosixMux048", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_049.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_049.c new file mode 100644 index 00000000..79f98caf --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_049.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static pthread_mutex_t g_mutex049; + +static VOID *TaskF01(void *argument) +{ + int ret; + ret = pthread_mutex_trylock(&g_mutex049); + ICUNIT_GOTO_EQUAL(ret, 16, ret, EXIT); // 16, Here, assert the g_testCount. + + return NULL; + +EXIT: + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_mutexattr_t mta; + int ret; + + pthread_attr_t attr; + pthread_t newTh; + + ret = pthread_mutexattr_init(&mta); + ret = pthread_mutex_init(&g_mutex049, &mta); + + ret = pthread_mutex_lock(&g_mutex049); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadInit(&attr, 4); // 4, Set thread priority. + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newTh, &attr, TaskF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&g_mutex049); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + pthread_mutex_destroy(&g_mutex049); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return LOS_OK; +} + + +VOID ItPosixMux049(void) +{ + TEST_ADD_CASE("ItPosixMux049", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_050.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_050.c new file mode 100644 index 00000000..7f355e7c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_050.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static pthread_mutex_t g_mutex050; + +static void *TaskF01(void *argument) +{ + int ret; + LOS_TaskLock(); + + ret = pthread_mutex_lock(&g_mutex050); + ICUNIT_GOTO_EQUAL(ret, EDEADLK, ret, EXIT); + + ret = pthread_mutex_lock(&g_mutex050); + ICUNIT_GOTO_EQUAL(ret, EDEADLK, ret, EXIT); + + LOS_TaskUnlock(); +EXIT: + return NULL; +} + +static UINT32 Testcase(VOID) +{ + int ret; + pthread_mutexattr_t mta; + + pthread_attr_t attr; + pthread_t newTh; + + ret = pthread_mutexattr_init(&mta); + + ret = pthread_mutex_init(&g_mutex050, &mta); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_mutex_lock(&g_mutex050); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = PosixPthreadInit(&attr, 4); // 4, Set thread priority. + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newTh, &attr, TaskF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + TestBusyTaskDelay(3); // 3, Set the timeout of runtime. + + ret = pthread_mutex_unlock(&g_mutex050); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + (void)pthread_mutex_destroy(&g_mutex050); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return LOS_OK; +EXIT: + ret = pthread_mutex_destroy(&g_mutex050); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); +} + + +VOID ItPosixMux050(void) +{ + TEST_ADD_CASE("ItPosixMux050", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_054.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_054.c new file mode 100644 index 00000000..e46bea03 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_054.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + int ret; + pthread_mutexattr_t mta; + pthread_mutex_t mutex = TEST_MUTEX_INIT; + + ret = pthread_mutexattr_init(&mta); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_init(&mutex, &mta); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + + ret = pthread_mutexattr_destroy(&mta); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return LOS_OK; +} + + +VOID ItPosixMux054(void) +{ + TEST_ADD_CASE("ItPosixMux054", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_055.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_055.c new file mode 100644 index 00000000..94091441 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_055.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + int ret; + pthread_mutexattr_t mta; + pthread_mutex_t mutex = TEST_MUTEX_INIT; + + ret = pthread_mutexattr_init(&mta); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_init(&mutex, &mta); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&mutex); + ICUNIT_ASSERT_EQUAL(ret, EBUSY, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + (void)pthread_mutexattr_destroy(&mta); + pthread_mutex_destroy(&mutex); + + return LOS_OK; +} + + +VOID ItPosixMux055(void) +{ + TEST_ADD_CASE("ItPosixMux055", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_056.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_056.c new file mode 100644 index 00000000..7cfdf845 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_056.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static pthread_mutex_t g_mutex056; + +static VOID *TaskF01(void *argument) +{ + int ret; + + ret = pthread_mutex_trylock(&g_mutex056); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_mutex_unlock(&g_mutex056); + g_testCount++; + +EXIT: + return NULL; +} + +static UINT32 Testcase(VOID) +{ + int ret; + pthread_mutexattr_t mta; + + pthread_attr_t attr; + pthread_t newTh; + + g_testCount = 0; + + ret = pthread_mutexattr_init(&mta); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_init(&g_mutex056, &mta); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadInit(&attr, 4); // 4, Set thread priority. + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newTh, &attr, TaskF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = pthread_mutex_destroy(&g_mutex056); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + (void)pthread_mutexattr_destroy(&mta); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return LOS_OK; +} + + +VOID ItPosixMux056(void) +{ + TEST_ADD_CASE("ItPosixMux056", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_057.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_057.c new file mode 100644 index 00000000..c1af362f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_057.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + int ret; + pthread_mutexattr_t mta; + pthread_mutex_t mutex = TEST_MUTEX_INIT; + + ret = pthread_mutexattr_init(&mta); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_init(&mutex, &mta); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + (void)pthread_mutexattr_destroy(&mta); + return LOS_OK; +} + + +VOID ItPosixMux057(void) +{ + TEST_ADD_CASE("ItPosixMux057", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_058.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_058.c new file mode 100644 index 00000000..219c82c2 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_058.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static pthread_mutex_t g_mutex058; + +static VOID HwiF01(void) +{ + int ret; + + TEST_HwiClear(HWI_NUM_TEST); + + ret = pthread_mutex_unlock(&g_mutex058); + ICUNIT_ASSERT_EQUAL_VOID(ret, EINTR, ret); + + ret = pthread_mutex_lock(&g_mutex058); + ICUNIT_ASSERT_EQUAL_VOID(ret, EINTR, ret); + + ret = pthread_mutex_unlock(&g_mutex058); + ICUNIT_ASSERT_EQUAL_VOID(ret, EINTR, ret); + + g_testCount++; + + return; +} + +static UINT32 Testcase(VOID) +{ + int ret; + pthread_mutexattr_t mta; + + g_testCount = 0; + + ret = pthread_mutexattr_init(&mta); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_init(&g_mutex058, &mta); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 0, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + TestHwiTrigger(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + ret = pthread_mutex_lock(&g_mutex058); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&g_mutex058); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&g_mutex058); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + (void)pthread_mutexattr_destroy(&mta); + + TEST_HwiDelete(HWI_NUM_TEST); + + return LOS_OK; +} + + +VOID ItPosixMux058(void) +{ + TEST_ADD_CASE("ItPosixMux058", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_059.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_059.c new file mode 100644 index 00000000..a2630d05 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_059.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + int ret; + pthread_mutexattr_t mta; + pthread_mutex_t mutex = TEST_MUTEX_INIT; + + sem_t sem; + int pshared; + + ret = pthread_mutexattr_init(&mta); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_init(&mutex, &mta); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = sem_init(&sem, pshared, 2); // 2, The initial number of available semaphores. + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = sem_wait(&sem); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = sem.sem->semCount; + ICUNIT_ASSERT_EQUAL(ret, 1, ret); + + ret = sem_wait(&sem); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = sem_post(&sem); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = sem_wait(&sem); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = sem_destroy(&sem); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + (void)pthread_mutexattr_destroy(&mta); + return LOS_OK; +} + + +VOID ItPosixMux059(void) +{ + TEST_ADD_CASE("ItPosixMux059", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_060.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_060.c new file mode 100644 index 00000000..7d4bda07 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_060.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static pthread_mutex_t g_mutex060; + +static VOID HwiF01(void) +{ + int ret; + + TEST_HwiClear(HWI_NUM_TEST); + + ret = pthread_mutex_lock(&g_mutex060); + ICUNIT_ASSERT_NOT_EQUAL_VOID(ret, 0, ret); + + g_testCount++; +} + +static UINT32 Testcase(VOID) +{ + int ret; + pthread_mutexattr_t mta; + + g_testCount = 0; + + ret = pthread_mutexattr_init(&mta); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_init(&g_mutex060, &mta); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 0, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + TestHwiTrigger(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = pthread_mutex_lock(&g_mutex060); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&g_mutex060); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&g_mutex060); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + (void)pthread_mutexattr_destroy(&mta); + + TEST_HwiDelete(HWI_NUM_TEST); + return LOS_OK; +} + + +VOID ItPosixMux060(void) +{ + TEST_ADD_CASE("ItPosixMux060", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_061.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_061.c new file mode 100644 index 00000000..a3aec68c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_061.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + pthread_mutex_t mutex = TEST_MUTEX_INIT; + + ret = pthread_mutex_init(NULL, NULL); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_mutex_init(&mutex, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return LOS_OK; +} + + +VOID ItPosixMux061(void) +{ + TEST_ADD_CASE("ItPosixMux061", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_062.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_062.c new file mode 100644 index 00000000..cc1dab6f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_062.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + pthread_mutex_t mutex = TEST_MUTEX_INIT; + + ret = pthread_mutex_destroy(NULL); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_mutex_init(&mutex, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(NULL); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_mutex_destroy(NULL); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + return LOS_OK; +} + + +VOID ItPosixMux062(void) +{ + TEST_ADD_CASE("ItPosixMux062", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_063.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_063.c new file mode 100644 index 00000000..b4ad2728 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_063.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + pthread_mutex_t mutex = TEST_MUTEX_INIT; + + ret = pthread_mutex_lock(NULL); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_mutex_init(&mutex, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&mutex); + ICUNIT_ASSERT_EQUAL(ret, EBUSY, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return LOS_OK; +} + + +VOID ItPosixMux063(void) +{ + TEST_ADD_CASE("ItPosixMux063", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_064.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_064.c new file mode 100644 index 00000000..95e00c2e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_064.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + pthread_mutex_t mutex = TEST_MUTEX_INIT; + + ret = pthread_mutex_trylock(NULL); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_mutex_init(&mutex, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_trylock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&mutex); + ICUNIT_ASSERT_EQUAL(ret, EBUSY, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_trylock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_trylock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, EBUSY, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return LOS_OK; +} + + +VOID ItPosixMux064(void) +{ + TEST_ADD_CASE("ItPosixMux064", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_065.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_065.c new file mode 100644 index 00000000..e473c798 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_065.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + pthread_mutex_t mutex = TEST_MUTEX_INIT; + + ret = pthread_mutex_unlock(NULL); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_mutex_init(&mutex, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_trylock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + + return LOS_OK; +} + + +VOID ItPosixMux065(void) +{ + TEST_ADD_CASE("ItPosixMux065", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_066.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_066.c new file mode 100644 index 00000000..6e81eabe --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_066.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static pthread_mutex_t g_mutex066; + +static void *TaskF01(void *argv) +{ + UINT32 ret; + g_testCount++; + + ret = pthread_mutex_trylock(&g_mutex066); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + ret = pthread_mutex_trylock(&g_mutex066); + ICUNIT_TRACK_EQUAL(ret, EBUSY, ret); + + LOS_TaskDelay(2); // 2, set delay time. + + ret = pthread_mutex_unlock(&g_mutex066); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&g_mutex066); + ICUNIT_TRACK_NOT_EQUAL(ret, 0, ret); + + g_testCount++; + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + pthread_t newTh; + pthread_attr_t attr; + + g_testCount = 0; + + ret = pthread_mutex_init(&g_mutex066, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadInit(&attr, 4); // 4, Set thread priority. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = pthread_create(&newTh, &attr, TaskF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = pthread_mutex_destroy(&g_mutex066); + ICUNIT_ASSERT_EQUAL(ret, EBUSY, ret); + + LOS_TaskDelay(3); // 3, set delay time. + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, Assert that g_testCount. + + ret = pthread_mutex_destroy(&g_mutex066); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadDestroy(&attr, newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return LOS_OK; +} + + +VOID ItPosixMux066(void) +{ + TEST_ADD_CASE("ItPosixMux066", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_067.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_067.c new file mode 100644 index 00000000..bc376650 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_067.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static pthread_mutex_t g_mutex067; + +static int HwiF01(void) +{ + UINT32 ret; + + TEST_HwiClear(HWI_NUM_TEST); + + ret = pthread_mutex_init(&g_mutex067, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_trylock(&g_mutex067); + ICUNIT_ASSERT_EQUAL(ret, EINTR, ret); + + ret = pthread_mutex_lock(&g_mutex067); + ICUNIT_ASSERT_EQUAL(ret, EINTR, ret); + + ret = pthread_mutex_trylock(&g_mutex067); + ICUNIT_ASSERT_EQUAL(ret, EINTR, ret); + + ret = pthread_mutex_unlock(&g_mutex067); + ICUNIT_ASSERT_EQUAL(ret, EINTR, ret); + + ret = pthread_mutex_unlock(&g_mutex067); + ICUNIT_ASSERT_EQUAL(ret, EINTR, ret); + + ret = pthread_mutex_unlock(&g_mutex067); + ICUNIT_ASSERT_EQUAL(ret, EINTR, ret); + + ret = pthread_mutex_destroy(&g_mutex067); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + g_testCount++; + + return LOS_OK; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + + g_testCount = 0; + + ret = LOS_HwiCreate(HWI_NUM_TEST, 0, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + TestHwiTrigger(HWI_NUM_TEST); + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + TEST_HwiDelete(HWI_NUM_TEST); + + return LOS_OK; +} + + +VOID ItPosixMux067(void) +{ + TEST_ADD_CASE("ItPosixMux067", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_068.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_068.c new file mode 100644 index 00000000..a4e35c2e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_068.c @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static pthread_mutex_t g_mutex068; + +static VOID *TaskF01(void *argv) +{ + UINT32 ret; + + g_testCount++; + + ret = pthread_mutex_lock(&g_mutex068); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + g_testCount++; + + LOS_TaskDelay(30); // 30, set delay time. + + ret = pthread_mutex_unlock(&g_mutex068); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + LOS_TaskDelay(100); // 100, set delay time. + + return NULL; +} +static VOID *TaskF02(void *argv) +{ + UINT32 ret; + + g_testCount++; + + ret = pthread_mutex_lock(&g_mutex068); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + g_testCount++; + + LOS_TaskDelay(30); // 30, set delay time. + + ret = pthread_mutex_unlock(&g_mutex068); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + LOS_TaskDelay(100); // 100, set delay time. + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + pthread_t newTh; + pthread_attr_t attr; + pthread_t newTh2; + pthread_attr_t attr2; + + ret = pthread_mutex_init(&g_mutex068, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + g_testCount = 0; + + LOS_TaskLock(); + + ret = PosixPthreadInit(&attr, 10); // 10, Set thread priority. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = pthread_create(&newTh, &attr, TaskF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadInit(&attr2, 4); // 4, Set thread priority. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = pthread_create(&newTh2, &attr2, TaskF02, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LOS_TaskUnlock(); + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, Assert that g_testCount. + + LOS_TaskDelay(40); // 40, set delay time. + ICUNIT_ASSERT_EQUAL(g_testCount, 4, g_testCount); // 4, Assert that g_testCount. + + LOS_TaskDelay(30); // 30, set delay time. + + ret = pthread_mutex_destroy(&g_mutex068); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadDestroy(&attr, newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadDestroy(&attr2, newTh2); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return LOS_OK; +} + + +VOID ItPosixMux068(void) +{ + TEST_ADD_CASE("ItPosixMux068", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_069.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_069.c new file mode 100644 index 00000000..b65071ac --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_069.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static pthread_mutex_t g_mutex069; + +static VOID *TaskF01(void *argv) +{ + UINT32 ret; + + ret = pthread_mutex_lock(&g_mutex069); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + LOS_TaskDelay(10); // 10, set delay time. + + ret = pthread_mutex_unlock(&g_mutex069); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + g_testCount++; + + ret = pthread_mutex_trylock(&g_mutex069); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + LOS_TaskDelay(10); // 10, set delay time. + + ret = pthread_mutex_unlock(&g_mutex069); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + g_testCount++; + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + pthread_t newTh; + pthread_attr_t attr; + + ret = pthread_mutex_init(&g_mutex069, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + g_testCount = 0; + + ret = PosixPthreadInit(&attr, 4); // 4, Set thread priority. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = pthread_create(&newTh, &attr, TaskF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 0, g_testCount); + + ret = pthread_mutex_unlock(&g_mutex069); + ICUNIT_ASSERT_EQUAL(ret, EPERM, ret); + + LOS_TaskDelay(15); // 15, set delay time. + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = pthread_mutex_unlock(&g_mutex069); + ICUNIT_ASSERT_EQUAL(ret, EPERM, ret); + + LOS_TaskDelay(10); // 10, set delay time. + + ret = pthread_mutex_unlock(&g_mutex069); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, Assert that g_testCount. + + ret = pthread_mutex_destroy(&g_mutex069); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadDestroy(&attr, newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return LOS_OK; +} + + +VOID ItPosixMux069(void) +{ + TEST_ADD_CASE("ItPosixMux069", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_070.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_070.c new file mode 100644 index 00000000..9c14d8c7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_070.c @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static pthread_mutex_t g_mutex070; + +static VOID *TaskF01(void *arg) +{ + int i; + UINT32 ret; + + g_testCount = 0; + + ret = pthread_mutex_lock(&g_mutex070); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + for (i = 1; i <= 10; i++) { // 10, The loop frequency. + g_testCount++; + } + + ret = pthread_mutex_unlock(&g_mutex070); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + ICUNIT_TRACK_EQUAL(g_testCount, 10, g_testCount); // 10, Here, assert that g_testCount is equal to 30. + + ret = LOS_EventWrite(&g_eventCB, 0x1); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + return NULL; +} + +static VOID *TaskF02(void *arg) +{ + int i; + UINT32 ret; + + ret = pthread_mutex_lock(&g_mutex070); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + for (i = 1; i <= 10; i++) { // 10, The loop frequency. + g_testCount += 2; // 2, Set g_testCount. + } + + ret = pthread_mutex_unlock(&g_mutex070); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + ICUNIT_TRACK_EQUAL(g_testCount, 30, g_testCount); // 30, Here, assert that g_testCount is equal to 30. + + ret = LOS_EventWrite(&g_eventCB, 0x10); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + pthread_t newTh; + pthread_attr_t attr; + pthread_t newTh2; + pthread_attr_t attr2; + + ret = pthread_mutex_init(&g_mutex070, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = LOS_EventInit(&g_eventCB); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + LOS_TaskLock(); + + ret = PosixPthreadInit(&attr, 4); // 4, Set thread priority. + ICUNIT_GOTO_EQUAL(ret, LOS_OK, ret, EXIT1); + + ret = pthread_create(&newTh, &attr, TaskF01, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT2); + + ret = PosixPthreadInit(&attr2, 4); // 4, Set thread priority. + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT2); + + ret = pthread_create(&newTh2, &attr2, TaskF02, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT3); + + LOS_TaskUnlock(); + + ret = LOS_EventRead(&g_eventCB, 0x11, LOS_WAITMODE_AND | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER); + ICUNIT_GOTO_EQUAL(ret, 0x11, ret, EXIT3); + + ret = PosixPthreadDestroy(&attr2, newTh2); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT3); + + ret = PosixPthreadDestroy(&attr, newTh); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT2); + + ret = LOS_EventDestroy(&g_eventCB); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT1); + + ret = pthread_mutex_destroy(&g_mutex070); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + return 0; + +EXIT3: + PosixPthreadDestroy(&attr, newTh2); + +EXIT2: + PosixPthreadDestroy(&attr, newTh); + +EXIT1: + LOS_EventDestroy(&g_eventCB); + +EXIT: + pthread_mutex_destroy(&g_mutex070); + return 0; +} + + +VOID ItPosixMux070(void) +{ + TEST_ADD_CASE("ItPosixMux070", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_071.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_071.c new file mode 100644 index 00000000..96cc70e7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_071.c @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static pthread_mutex_t g_mutex071; + +static VOID *TaskF01(void *arg) +{ + UINT32 ret; + ret = pthread_mutex_lock(&g_mutex071); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + ICUNIT_TRACK_EQUAL(g_testCount, 0, g_testCount); + g_testCount++; + + LOS_TaskDelay(20); // 20, set delay time. + ret = pthread_mutex_unlock(&g_mutex071); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + ICUNIT_TRACK_EQUAL(g_testCount, 2, g_testCount); // 2, Here, assert that g_testCount is equal to 2. + g_testCount++; + + return LOS_OK; +} + +static VOID *TaskF02(void *arg) +{ + UINT32 ret; + + ICUNIT_TRACK_EQUAL(g_testCount, 1, g_testCount); + g_testCount++; + + ret = pthread_mutex_lock(&g_mutex071); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + TestBusyTaskDelay(1); + ICUNIT_TRACK_EQUAL(g_testCount, 3, g_testCount); // 3, Here, assert that g_testCount is equal to 3. + g_testCount++; + + ret = pthread_mutex_unlock(&g_mutex071); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + ICUNIT_TRACK_EQUAL(g_testCount, 4, g_testCount); // 4, Here, assert that g_testCount is equal to 4. + g_testCount++; + + return LOS_OK; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + pthread_t newTh; + pthread_attr_t attr; + + pthread_t newTh2; + pthread_attr_t attr2; + + ret = pthread_mutex_init(&g_mutex071, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + g_testCount = 0; + + ret = PosixPthreadInit(&attr, 4); // 4, Set thread priority. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = pthread_create(&newTh, &attr, TaskF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadInit(&attr2, 10); // 10, Set thread priority. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = pthread_create(&newTh2, &attr2, TaskF02, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LOS_TaskDelay(50); // 50, set delay time. + ICUNIT_ASSERT_EQUAL(g_testCount, 5, g_testCount); // 5, Assert that g_testCount. + + ret = pthread_mutex_destroy(&g_mutex071); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadDestroy(&attr, newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadDestroy(&attr2, newTh2); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return LOS_OK; +} + + +VOID ItPosixMux071(void) +{ + TEST_ADD_CASE("ItPosixMux071", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_072.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_072.c new file mode 100644 index 00000000..8a810f28 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_072.c @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static pthread_mutex_t g_mutex072; + +static VOID *TaskF01(void *arg) +{ + UINT32 ret; + ret = pthread_mutex_lock(&g_mutex072); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + ICUNIT_TRACK_EQUAL(g_testCount, 0, g_testCount); + g_testCount++; + + ret = pthread_mutex_unlock(&g_mutex072); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + LOS_TaskDelay(6); // 6, set delay time. + ICUNIT_TRACK_EQUAL(g_testCount, 4, g_testCount); // 4, Here, assert that g_testCount is equal to 4. + g_testCount++; + + return LOS_OK; +} + +static VOID *TaskF02(void *arg) +{ + UINT32 ret; + + ICUNIT_TRACK_EQUAL(g_testCount, 1, g_testCount); + g_testCount++; + + ret = pthread_mutex_lock(&g_mutex072); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + ICUNIT_TRACK_EQUAL(g_testCount, 2, g_testCount); // 2, Here, assert that g_testCount is equal to 2. + g_testCount++; + + ret = pthread_mutex_unlock(&g_mutex072); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + ICUNIT_TRACK_EQUAL(g_testCount, 3, g_testCount); // 3, Here, assert that g_testCount is equal to 3. + g_testCount++; + + return LOS_OK; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + pthread_t newTh; + pthread_attr_t attr; + + pthread_t newTh2; + pthread_attr_t attr2; + + ret = pthread_mutex_init(&g_mutex072, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + g_testCount = 0; + + ret = PosixPthreadInit(&attr, 10); // 10, Set thread priority. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = pthread_create(&newTh, &attr, TaskF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadInit(&attr2, 4); // 4, Set thread priority. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = pthread_create(&newTh2, &attr2, TaskF02, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LOS_TaskDelay(8); // 8, set delay time. + ICUNIT_ASSERT_EQUAL(g_testCount, 5, g_testCount); // 5, Assert that g_testCount. + + ret = pthread_mutex_destroy(&g_mutex072); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadDestroy(&attr, newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadDestroy(&attr2, newTh2); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return LOS_OK; +} + + +VOID ItPosixMux072(void) +{ + TEST_ADD_CASE("ItPosixMux072", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_073.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_073.c new file mode 100644 index 00000000..2ccab35b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_073.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + pthread_mutex_t mutex = TEST_MUTEX_INIT; + + ret = pthread_mutex_init(&mutex, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&mutex); + ICUNIT_ASSERT_EQUAL(ret, EBUSY, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return LOS_OK; +} + + +VOID ItPosixMux073(void) +{ + TEST_ADD_CASE("ItPosixMux073", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_074.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_074.c new file mode 100644 index 00000000..b0bbae94 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_074.c @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static pthread_mutex_t g_mutex074; +static sem_t g_sem074; +static int g_pshared074; + +static VOID *TaskF01(void *arg) +{ + UINT32 ret; + ret = pthread_mutex_lock(&g_mutex074); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + g_testCount++; + ICUNIT_TRACK_EQUAL(g_testCount, 1, g_testCount); + + LOS_TaskDelay(5); // 5, set delay time. + + ret = sem_wait(&g_sem074); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + g_testCount++; + ICUNIT_TRACK_EQUAL(g_testCount, 5, g_testCount); // 5, Here, assert that g_testCount is equal to 5. + + ret = sem_post(&g_sem074); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + g_testCount++; + ICUNIT_TRACK_EQUAL(g_testCount, 6, g_testCount); // 6, Here, assert that g_testCount is equal to 6. + + ret = pthread_mutex_unlock(&g_mutex074); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + return NULL; +} +static VOID *TaskF02(void *arg) +{ + UINT32 ret; + LOS_TaskDelay(1); + + g_testCount++; + ICUNIT_TRACK_EQUAL(g_testCount, 2, g_testCount); // 2, Here, assert that g_testCount is equal to 2. + + ret = pthread_mutex_lock(&g_mutex074); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + g_testCount++; + ICUNIT_TRACK_EQUAL(g_testCount, 7, g_testCount); // 7, Here, assert that g_testCount is equal to 7. + + ret = pthread_mutex_unlock(&g_mutex074); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + return NULL; +} +static VOID *TaskF03(void *arg) +{ + UINT32 ret; + + LOS_TaskDelay(2); // 2, set delay time. + g_testCount++; + ICUNIT_TRACK_EQUAL(g_testCount, 3, g_testCount); // 3, Here, assert that g_testCount is equal to 3. + + ret = sem_wait(&g_sem074); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + g_testCount++; + ICUNIT_TRACK_EQUAL(g_testCount, 4, g_testCount); // 4, Here, assert that g_testCount is equal to 4. + + LOS_TaskDelay(4); // 4, set delay time. + ret = sem_post(&g_sem074); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + g_testCount++; + ICUNIT_TRACK_EQUAL(g_testCount, 8, g_testCount); // 8, Here, assert that g_testCount is equal to 8. + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + pthread_t newTh; + pthread_attr_t attr; + pthread_t newTh2; + pthread_attr_t attr2; + pthread_t newTh3; + pthread_attr_t attr3; + g_testCount = 0; + + ret = pthread_mutex_init(&g_mutex074, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = sem_init(&g_sem074, g_pshared074, 2); // 2, The initial number of available semaphores. + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadInit(&attr, 15); // 15, Set thread priority. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = pthread_create(&newTh, &attr, TaskF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadInit(&attr2, 4); // 4, Set thread priority. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = pthread_create(&newTh2, &attr2, TaskF02, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadInit(&attr3, 10); // 10, Set thread priority. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = pthread_create(&newTh3, &attr3, TaskF03, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LOS_TaskDelay(10); // 10, set delay time. + ret = pthread_mutex_destroy(&g_mutex074); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = sem_destroy(&g_sem074); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadDestroy(&attr, newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadDestroy(&attr2, newTh2); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadDestroy(&attr3, newTh3); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return LOS_OK; +} + + +VOID ItPosixMux074(void) +{ + TEST_ADD_CASE("ItPosixMux074", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_075.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_075.c new file mode 100644 index 00000000..20decee8 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_075.c @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static pthread_mutex_t g_mutex075; +static sem_t g_sem075; +static int g_pshared075; + +static VOID *TaskF01(void *arg) +{ + UINT32 ret; + ret = pthread_mutex_lock(&g_mutex075); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + g_testCount++; + ICUNIT_TRACK_EQUAL(g_testCount, 3, g_testCount); // 3, Here, assert that g_testCount is equal to 3. + + ret = sem_wait(&g_sem075); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + g_testCount++; + ICUNIT_TRACK_EQUAL(g_testCount, 6, g_testCount); // 6, Here, assert that g_testCount is equal to 6. + + ret = sem_post(&g_sem075); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + g_testCount++; + ICUNIT_TRACK_EQUAL(g_testCount, 7, g_testCount); // 7, Here, assert that g_testCount is equal to 7. + + ret = pthread_mutex_unlock(&g_mutex075); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + return NULL; +} +static VOID *TaskF02(void *arg) +{ + UINT32 ret; + LOS_TaskDelay(2); // 2, set delay time. + + g_testCount++; + ICUNIT_TRACK_EQUAL(g_testCount, 4, g_testCount); // 4, Here, assert that g_testCount is equal to 4. + + ret = pthread_mutex_lock(&g_mutex075); + ICUNIT_TRACK_EQUAL(ret, 0, ret); // + + g_testCount++; + ICUNIT_TRACK_EQUAL(g_testCount, 8, g_testCount); // 8, Here, assert that g_testCount is equal to 8. + + ret = pthread_mutex_unlock(&g_mutex075); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + return NULL; +} +static VOID *TaskF03(void *arg) +{ + UINT32 ret; + + g_testCount++; + ICUNIT_TRACK_EQUAL(g_testCount, 1, g_testCount); + + g_testCount++; + ICUNIT_TRACK_EQUAL(g_testCount, 2, g_testCount); // 2, Here, assert that g_testCount is equal to 2. + + LOS_TaskDelay(3); // 3, set delay time. + + g_testCount++; + ICUNIT_TRACK_EQUAL(g_testCount, 5, g_testCount); // 5, Here, assert that g_testCount is equal to 5. + + ret = sem_post(&g_sem075); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + LOS_TaskDelay(1); + g_testCount++; + ICUNIT_TRACK_EQUAL(g_testCount, 9, g_testCount); // 9, Here, assert the g_testCount. + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + pthread_t newTh; + pthread_attr_t attr; + pthread_t newTh2; + pthread_attr_t attr2; + pthread_t newTh3; + pthread_attr_t attr3; + g_testCount = 0; + + ret = pthread_mutex_init(&g_mutex075, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = sem_init(&g_sem075, g_pshared075, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadInit(&attr, 10); // 10, Set thread priority. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = pthread_create(&newTh, &attr, TaskF03, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadInit(&attr2, 15); // 15, Set thread priority. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = pthread_create(&newTh2, &attr2, TaskF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadInit(&attr3, 4); // 4, Set thread priority. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = pthread_create(&newTh3, &attr3, TaskF02, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LOS_TaskDelay(5); // 5, set delay time. + ret = pthread_mutex_destroy(&g_mutex075); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = sem_destroy(&g_sem075); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadDestroy(&attr, newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadDestroy(&attr2, newTh2); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadDestroy(&attr3, newTh3); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return LOS_OK; +} + + +VOID ItPosixMux075(void) +{ + TEST_ADD_CASE("ItPosixMux075", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_076.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_076.c new file mode 100644 index 00000000..0e0288c3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_076.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static pthread_mutex_t g_mutex1076; +static pthread_mutex_t g_mutex2076; + +static VOID *TaskF01(void *arg) +{ + UINT32 ret; + ret = pthread_mutex_lock(&g_mutex1076); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&g_mutex1076); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + pthread_t newTh; + pthread_attr_t attr; + pthread_mutexattr_t mutexAttr; + g_testCount = 0; + + pthread_mutexattr_init(&mutexAttr); + + pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_ERRORCHECK); + + ret = pthread_mutex_init(&g_mutex1076, &mutexAttr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_init(&g_mutex2076, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&g_mutex1076); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&g_mutex1076); + ICUNIT_ASSERT_EQUAL(ret, EDEADLK, ret); + + ret = pthread_mutex_destroy(&g_mutex1076); + ICUNIT_ASSERT_EQUAL(ret, EBUSY, ret); + + ret = pthread_mutex_unlock(&g_mutex1076); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadInit(&attr, 4); // 4, Set thread priority. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = pthread_create(&newTh, &attr, TaskF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LOS_TaskDelay(5); // 5, set delay time. + + ret = pthread_mutex_destroy(&g_mutex1076); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(NULL); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_mutex_destroy(&g_mutex2076); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadDestroy(&attr, newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return LOS_OK; +} + + +VOID ItPosixMux076(void) +{ + TEST_ADD_CASE("ItPosixMux076", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_077.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_077.c new file mode 100644 index 00000000..1f0ac098 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_077.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static pthread_mutex_t g_mutex077; + +static VOID *TaskF01(void *arg) +{ + UINT32 ret; + ret = pthread_mutex_trylock(&g_mutex077); + ICUNIT_TRACK_EQUAL(ret, EBUSY, ret); + + g_testCount++; + + ret = pthread_mutex_lock(&g_mutex077); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&g_mutex077); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + g_testCount++; + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + pthread_t newTh; + pthread_attr_t attr; + pthread_mutexattr_t mutexAttr; + + g_testCount = 0; + ret = pthread_mutex_lock(NULL); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_mutex_lock(&g_mutex077); + ICUNIT_ASSERT_EQUAL(ret, EBADF, ret); + + ret = pthread_mutex_unlock(&g_mutex077); + ICUNIT_ASSERT_EQUAL(ret, EBADF, ret); + pthread_mutexattr_init(&mutexAttr); + + pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_ERRORCHECK); + + ret = pthread_mutex_init(&g_mutex077, &mutexAttr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&g_mutex077); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadInit(&attr, 4); // 4, Set thread priority. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = pthread_create(&newTh, &attr, TaskF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LOS_TaskDelay(5); // 5, set delay time. + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = pthread_mutex_unlock(&g_mutex077); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + TestExtraTaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, Assert that g_testCount. + + ret = pthread_mutex_lock(&g_mutex077); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&g_mutex077); + ICUNIT_ASSERT_EQUAL(ret, EDEADLK, ret); + + ret = pthread_mutex_lock(&g_mutex077); + ICUNIT_ASSERT_EQUAL(ret, EDEADLK, ret); + + ret = pthread_mutex_unlock(&g_mutex077); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&g_mutex077); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&g_mutex077); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&g_mutex077); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return LOS_OK; +} + + +VOID ItPosixMux077(void) +{ + TEST_ADD_CASE("ItPosixMux077", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_078.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_078.c new file mode 100644 index 00000000..849091c6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_078.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + pthread_mutexattr_t mutexAttr; + pthread_mutex_t mutex = TEST_MUTEX_INIT; + + pthread_mutexattr_init(&mutexAttr); + + pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_ERRORCHECK); + + ret = pthread_mutex_init(&mutex, &mutexAttr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, EDEADLK, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return LOS_OK; +} + + +VOID ItPosixMux078(void) +{ + TEST_ADD_CASE("ItPosixMux078", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_079.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_079.c new file mode 100644 index 00000000..db8b5b4f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_079.c @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static pthread_mutex_t g_mutex079; +static sem_t g_sem079; +static int g_pshared084; + +static VOID *TaskF01(void *arg) +{ + UINT32 ret; + ret = pthread_mutex_trylock(&g_mutex079); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + ret = sem_wait(&g_sem079); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&g_mutex079); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + return NULL; +} +static VOID *TaskF02(void *arg) +{ + UINT32 ret; + + ret = sem_post(&g_sem079); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + return NULL; +} +static VOID *TaskF03(void *arg) +{ + UINT32 ret; + + ret = pthread_mutex_lock(&g_mutex079); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&g_mutex079); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + pthread_t newTh; + pthread_attr_t attr; + pthread_t newTh2; + pthread_attr_t attr2; + pthread_t newTh3; + pthread_attr_t attr3; + + ret = pthread_mutex_init(&g_mutex079, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = sem_init(&g_sem079, g_pshared084, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadInit(&attr, 4); // 4, Set thread priority. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = pthread_create(&newTh, &attr, TaskF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadInit(&attr2, 3); // 3, Set thread priority. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = pthread_create(&newTh2, &attr2, TaskF02, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadInit(&attr3, 4); // 4, Set thread priority. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = pthread_create(&newTh3, &attr3, TaskF03, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&g_mutex079); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = sem_destroy(&g_sem079); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadDestroy(&attr, newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadDestroy(&attr2, newTh2); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadDestroy(&attr3, newTh3); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return LOS_OK; +} + + +VOID ItPosixMux079(void) +{ + TEST_ADD_CASE("ItPosixMux079", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_080.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_080.c new file mode 100644 index 00000000..909f17bc --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_080.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static pthread_mutex_t g_mutex080; + +static VOID *TaskF01(void *arg) +{ + INT32 ret; + ret = pthread_mutex_unlock(&g_mutex080); + ICUNIT_TRACK_NOT_EQUAL(ret, 0, ret); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + INT32 ret; + pthread_t newTh; + pthread_attr_t attr; + + ret = pthread_mutex_init(&g_mutex080, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadInit(&attr, 4); // 4, Set thread priority. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = pthread_create(&newTh, &attr, TaskF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&g_mutex080); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LOS_TaskDelay(1); + + ret = pthread_mutex_unlock(&g_mutex080); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&g_mutex080); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadDestroy(&attr, newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return LOS_OK; +} + + +VOID ItPosixMux080(void) +{ + TEST_ADD_CASE("ItPosixMux080", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_081.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_081.c new file mode 100644 index 00000000..25ef3325 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_081.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + INT32 ret; + INT32 prioceiling; + pthread_mutexattr_t mattr; + + ret = pthread_mutexattr_setprioceiling(NULL, 1); + if (ret != EINVAL) { + ICUNIT_ASSERT_EQUAL(1, 0, prioceiling); + } + + ret = pthread_mutexattr_init(&mattr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + prioceiling = mattr.prioceiling; + if (prioceiling != OS_TASK_PRIORITY_LOWEST) { + ICUNIT_ASSERT_EQUAL(1, 0, prioceiling); + } + + ret = pthread_mutexattr_setprioceiling(&mattr, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + prioceiling = mattr.prioceiling; + if (prioceiling != 0) { + ICUNIT_ASSERT_EQUAL(1, 0, prioceiling); + } + + ret = pthread_mutexattr_setprioceiling(&mattr, OS_TASK_PRIORITY_LOWEST + 1); + if (ret != EINVAL) { + ICUNIT_ASSERT_EQUAL(1, 0, prioceiling); + } + + ret = pthread_mutexattr_setprioceiling(&mattr, OS_TASK_PRIORITY_HIGHEST - 1); + if (ret != EINVAL) { + ICUNIT_ASSERT_EQUAL(1, 0, prioceiling); + } + + return LOS_OK; +} + + +VOID ItPosixMux081(void) +{ + TEST_ADD_CASE("ItPosixMux081", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_082.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_082.c new file mode 100644 index 00000000..fa3ba9f1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_082.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 prioceiling; + pthread_mutexattr_t mattr; + pthread_mutex_t mutex = TEST_MUTEX_INIT; + + ret = pthread_mutexattr_init(&mattr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_init(&mutex, &mattr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_getprioceiling(&mutex, &prioceiling); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + if (prioceiling != OS_TASK_PRIORITY_LOWEST) { + ICUNIT_ASSERT_EQUAL(1, 0, prioceiling); + } + + prioceiling = 8; // 8, task priority. + ret = pthread_mutex_setprioceiling(&mutex, prioceiling, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_getprioceiling(&mutex, &prioceiling); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + if (prioceiling != 8) { // 8, task priority. + ICUNIT_ASSERT_EQUAL(1, 0, prioceiling); + } + + prioceiling = 6; // 6, task priority. + + ret = pthread_mutex_setprioceiling(&mutex, prioceiling, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_getprioceiling(&mutex, &prioceiling); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + if (prioceiling != 6) { // 6, task priority. + ICUNIT_ASSERT_EQUAL(1, 0, prioceiling); + } + + ret = pthread_mutex_destroy(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return LOS_OK; +} + + +VOID ItPosixMux082(void) +{ + TEST_ADD_CASE("ItPosixMux082", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_084.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_084.c new file mode 100644 index 00000000..6a764e92 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_084.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + int ret; + pthread_mutex_t mutex1084 = TEST_MUTEX_INIT; + pthread_mutex_t mutex2084 = TEST_MUTEX_INIT; + + ret = pthread_mutex_init(&mutex1084, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_trylock(&mutex1084); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_init(&mutex2084, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&mutex2084); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_trylock(&mutex2084); + ICUNIT_ASSERT_EQUAL(ret, EBUSY, ret); + + ret = pthread_mutex_unlock(&mutex1084); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&mutex1084); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&mutex2084); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&mutex2084); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return LOS_OK; +} + + +VOID ItPosixMux084(void) +{ + TEST_ADD_CASE("ItPosixMux084", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_085.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_085.c new file mode 100644 index 00000000..2e906dd5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_085.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + int ret; + pthread_mutexattr_t mattr; + pthread_mutex_t mutex = TEST_MUTEX_INIT; + + ret = pthread_mutexattr_init(NULL); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_mutexattr_setprotocol(NULL, 1); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_mutexattr_getprotocol(NULL, NULL); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_mutexattr_getprioceiling(NULL, NULL); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_mutex_init(NULL, NULL); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_mutex_getprioceiling(NULL, NULL); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_mutex_setprioceiling(NULL, 0, NULL); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_mutexattr_init(&mattr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_init(&mutex, &mattr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return LOS_OK; +} + + +VOID ItPosixMux085(void) +{ + TEST_ADD_CASE("ItPosixMux085", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_086.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_086.c new file mode 100644 index 00000000..106e8df5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_086.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + int ret; + pthread_mutex_t mutex = TEST_MUTEX_INIT; + + ret = pthread_mutex_init(&mutex, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + mutex.attr.type = PTHREAD_MUTEX_RECURSIVE; + + ret = pthread_mutex_lock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_trylock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return LOS_OK; +} + + +VOID ItPosixMux086(void) +{ + TEST_ADD_CASE("ItPosixMux086", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_087.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_087.c new file mode 100644 index 00000000..c1396704 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_087.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + int ret; + pthread_mutex_t mutex = TEST_MUTEX_INIT; + + ret = pthread_mutex_init(&mutex, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + mutex.attr.type = PTHREAD_MUTEX_RECURSIVE; + + ret = pthread_mutex_lock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_trylock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return LOS_OK; +} + + +VOID ItPosixMux087(void) +{ + TEST_ADD_CASE("ItPosixMux087", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_089.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_089.c new file mode 100644 index 00000000..562597d3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_089.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + int ret; + pthread_mutex_t mutex = TEST_MUTEX_INIT; + + ret = pthread_mutex_init(&mutex, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + mutex.attr.type = 1; + ret = pthread_mutex_lock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&mutex); + ICUNIT_ASSERT_EQUAL(ret, EBUSY, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return LOS_OK; +} + + +VOID ItPosixMux089(void) +{ + TEST_ADD_CASE("ItPosixMux089", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_090.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_090.c new file mode 100644 index 00000000..8af7da2f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_090.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + int ret; + pthread_mutex_t mutex = TEST_MUTEX_INIT; + + ret = pthread_mutex_init(&mutex, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + mutex.attr.type = PTHREAD_MUTEX_RECURSIVE; + + ret = pthread_mutex_lock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return LOS_OK; +} + + +VOID ItPosixMux090(void) +{ + TEST_ADD_CASE("ItPosixMux090", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_091.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_091.c new file mode 100644 index 00000000..cfaedb26 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_091.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static pthread_mutex_t g_mutex091; + +static VOID *TaskF01(void *arg) +{ + INT32 ret; + ret = pthread_mutex_unlock(&g_mutex091); + ICUNIT_TRACK_NOT_EQUAL(ret, 0, ret); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + INT32 ret; + pthread_t newTh; + pthread_attr_t attr; + + ret = pthread_mutex_init(&g_mutex091, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + g_mutex091.attr.type = 1; + + ret = pthread_mutex_lock(&g_mutex091); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadInit(&attr, 4); // 4, Set thread priority. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = pthread_create(&newTh, &attr, TaskF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LOS_TaskDelay(5); // 5, set delay time. + + ret = pthread_mutex_unlock(&g_mutex091); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&g_mutex091); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadDestroy(&attr, newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return LOS_OK; +} + + +VOID ItPosixMux091(void) +{ + TEST_ADD_CASE("ItPosixMux091", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_092.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_092.c new file mode 100644 index 00000000..7699b528 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_092.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static pthread_mutex_t g_mutex1092; +static pthread_mutex_t g_mutex2092; + +static VOID *TaskF01(void *arg) +{ + INT32 ret; + + ret = pthread_mutex_init(&g_mutex2092, NULL); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + g_mutex2092.attr.type = 1; + + ret = pthread_mutex_lock(&g_mutex2092); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&g_mutex2092); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + INT32 ret; + pthread_t newTh; + pthread_attr_t attr; + + ret = pthread_mutex_init(&g_mutex1092, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + g_mutex1092.attr.type = 1; + + ret = pthread_mutex_lock(&g_mutex1092); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadInit(&attr, 4); // 4, Set thread priority. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = pthread_create(&newTh, &attr, TaskF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LOS_TaskDelay(5); // 5, set delay time. + + ret = pthread_mutex_unlock(&g_mutex1092); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&g_mutex1092); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&g_mutex2092); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadDestroy(&attr, newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return LOS_OK; +} + + +VOID ItPosixMux092(void) +{ + TEST_ADD_CASE("ItPosixMux092", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_093.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_093.c new file mode 100644 index 00000000..0329721f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_093.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static pthread_mutex_t g_mutex1093; +static pthread_mutex_t g_mutex2093; + +static VOID *TaskF01(void *arg) +{ + UINT32 ret; + + ret = pthread_mutex_init(&g_mutex1093, NULL); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + g_mutex1093.attr.type = 1; + + ret = pthread_mutex_lock(&g_mutex1093); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&g_mutex1093); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&g_mutex1093); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&g_mutex1093); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + return NULL; +} + +static VOID *TaskF02(void *arg) +{ + UINT32 ret; + + ret = pthread_mutex_init(&g_mutex2093, NULL); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + g_mutex2093.attr.type = 1; + + ret = pthread_mutex_lock(&g_mutex2093); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&g_mutex2093); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&g_mutex2093); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&g_mutex2093); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + pthread_t newTh; + pthread_attr_t attr; + + pthread_t newTh2; + pthread_attr_t attr2; + + ret = PosixPthreadInit(&attr, 10); // 10, Set thread priority. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = pthread_create(&newTh, &attr, TaskF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadInit(&attr2, 4); // 4, Set thread priority. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = pthread_create(&newTh2, &attr2, TaskF02, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&g_mutex1093); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&g_mutex2093); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadDestroy(&attr, newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadDestroy(&attr2, newTh2); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return LOS_OK; +} + + +VOID ItPosixMux093(void) +{ + TEST_ADD_CASE("ItPosixMux093", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_094.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_094.c new file mode 100644 index 00000000..dc2d0a12 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_094.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + int ret; + pthread_mutex_t mutex = TEST_MUTEX_INIT; + + ret = pthread_mutex_init(&mutex, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + mutex.attr.type = PTHREAD_MUTEX_ERRORCHECK; + + ret = pthread_mutex_lock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, EDEADLK, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return LOS_OK; +} + + +VOID ItPosixMux094(void) +{ + TEST_ADD_CASE("ItPosixMux094", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_095.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_095.c new file mode 100644 index 00000000..34c31469 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_095.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static UINT32 Testcase(VOID) +{ + int ret; + pthread_mutex_t mutex = TEST_MUTEX_INIT; + ret = pthread_mutex_init(&mutex, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + mutex.attr.type = PTHREAD_MUTEX_ERRORCHECK; + + ret = pthread_mutex_lock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, EDEADLK, ret); + + ret = pthread_mutex_trylock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, EBUSY, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return LOS_OK; +} + + +VOID ItPosixMux095(void) +{ + TEST_ADD_CASE("ItPosixMux095", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_097.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_097.c new file mode 100644 index 00000000..8892449f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_097.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static pthread_mutex_t g_mutex097; + +static VOID *TaskF01(void *arg) +{ + INT32 ret; + ret = pthread_mutex_unlock(&g_mutex097); + ICUNIT_TRACK_NOT_EQUAL(ret, 0, ret); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + INT32 ret; + pthread_t newTh; + pthread_attr_t attr; + + ret = pthread_mutex_init(&g_mutex097, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + g_mutex097.attr.type = PTHREAD_MUTEX_ERRORCHECK; + + ret = pthread_mutex_lock(&g_mutex097); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadInit(&attr, 4); // 4, Set thread priority. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = pthread_create(&newTh, &attr, TaskF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LOS_TaskDelay(5); // 5, set delay time. + + ret = pthread_mutex_unlock(&g_mutex097); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&g_mutex097); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadDestroy(&attr, newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return LOS_OK; +} + + +VOID ItPosixMux097(void) +{ + TEST_ADD_CASE("ItPosixMux097", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_098.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_098.c new file mode 100644 index 00000000..3811a2a9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_098.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static pthread_mutex_t g_mutex1098; +static pthread_mutex_t g_mutex2098; + +static VOID *TaskF01(void *arg) +{ + INT32 ret; + + ret = pthread_mutex_init(&g_mutex2098, NULL); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + g_mutex2098.attr.type = PTHREAD_MUTEX_ERRORCHECK; + + ret = pthread_mutex_lock(&g_mutex2098); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&g_mutex2098); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + return NULL; +} + + +static UINT32 Testcase(VOID) +{ + INT32 ret; + pthread_t newTh; + pthread_attr_t attr; + + ret = pthread_mutex_init(&g_mutex1098, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + g_mutex1098.attr.type = PTHREAD_MUTEX_ERRORCHECK; + ret = pthread_mutex_lock(&g_mutex1098); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadInit(&attr, 4); // 4, Set thread priority. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = pthread_create(&newTh, &attr, TaskF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LOS_TaskDelay(5); // 5, set delay time. + + ret = pthread_mutex_unlock(&g_mutex1098); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&g_mutex1098); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&g_mutex2098); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadDestroy(&attr, newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return LOS_OK; +} + + +VOID ItPosixMux098(void) +{ + TEST_ADD_CASE("ItPosixMux098", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_099.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_099.c new file mode 100644 index 00000000..f6b602b5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_099.c @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +pthread_mutex_t g_mutex1099; +pthread_mutex_t g_mutex2099; + +static VOID *TaskF01(void *arg) +{ + UINT32 ret; + + ret = pthread_mutex_init(&g_mutex1099, NULL); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + g_mutex1099.attr.type = PTHREAD_MUTEX_ERRORCHECK; + + ret = pthread_mutex_lock(&g_mutex1099); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&g_mutex1099); + ICUNIT_TRACK_EQUAL(ret, EDEADLK, ret); + + ret = pthread_mutex_unlock(&g_mutex1099); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + return NULL; +} + +static VOID *TaskF02(void *arg) +{ + UINT32 ret; + + ret = pthread_mutex_init(&g_mutex2099, NULL); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + g_mutex2099.attr.type = PTHREAD_MUTEX_ERRORCHECK; + + ret = pthread_mutex_lock(&g_mutex2099); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&g_mutex2099); + ICUNIT_TRACK_EQUAL(ret, EDEADLK, ret); + + ret = pthread_mutex_unlock(&g_mutex2099); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + pthread_t newTh; + pthread_attr_t attr; + + pthread_t newTh2; + pthread_attr_t attr2; + + ret = PosixPthreadInit(&attr, 10); // 10, Set thread priority. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = pthread_create(&newTh, &attr, TaskF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadInit(&attr2, 4); // 4, Set thread priority. + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = pthread_create(&newTh2, &attr2, TaskF02, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&g_mutex1099); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&g_mutex2099); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadDestroy(&attr, newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = PosixPthreadDestroy(&attr2, newTh2); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return LOS_OK; +} + + +VOID ItPosixMux099(void) +{ + TEST_ADD_CASE("ItPosixMux099", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_101.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_101.c new file mode 100644 index 00000000..68e62519 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/full/It_posix_mutex_101.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static pthread_mutex_t g_mutexTest100 = { 0 }; + +static VOID TestMutexInit101(UINT8 type) +{ + int ret; + pthread_mutexattr_t mta = { 0 }; + + /* Initialize a mutex attributes object */ + ret = pthread_mutexattr_init(&mta); + ICUNIT_ASSERT_EQUAL_VOID(ret, ENOERR, ret); + + mta.type = type; + + ret = pthread_mutex_init(&g_mutexTest100, &mta); + ICUNIT_ASSERT_EQUAL_VOID(ret, 0, ret); + + (void)pthread_mutexattr_destroy(&mta); +} + + +static UINT32 Testcase(VOID) +{ + int ret; + + ICUNIT_ASSERT_EQUAL(OsCurrTaskGet()->priority, TASK_PRIO_TEST, OsCurrTaskGet()->priority); + + TestMutexInit101(PTHREAD_MUTEX_ERRORCHECK); + + ret = pthread_mutex_lock(&g_mutexTest100); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_mutex_setprioceiling(&g_mutexTest100, 21, NULL); // 21, task priority. + ICUNIT_GOTO_EQUAL(ret, EDEADLK, ret, EXIT1); + + ret = pthread_mutex_unlock(&g_mutexTest100); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_mutex_destroy(&g_mutexTest100); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + return LOS_OK; + +EXIT1: + ret = pthread_mutex_unlock(&g_mutexTest100); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + +EXIT: + ret = pthread_mutex_destroy(&g_mutexTest100); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return LOS_OK; +} + +VOID ItPosixMux101(void) +{ + TEST_ADD_CASE("ItPosixMux101", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL2, TEST_FUNCTION); +} + + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/smoke/It_posix_mutex_001.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/smoke/It_posix_mutex_001.c new file mode 100644 index 00000000..814d6215 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/smoke/It_posix_mutex_001.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +/* pthread_mutexattr_init 1-1.c + * Test that pthread_mutexattr_init() + * shall initialize a mutex attributes object 'attr' with the default + * value for all of the attributes defined by the implementation. + + * Steps: + * 1. Initialize a pthread_mutexattr_t object with pthread_mutexattr_init() + * 2. Call pthread_mutexattr_getpshared() to check if the process-shared + * attribute is set as the default value PTHREAD_PROCESS_PRIVATE. + * + */ +static UINT32 Testcase(VOID) +{ + pthread_mutexattr_t mta; + int rc; + + /* Initialize a mutex attributes object */ + rc = pthread_mutexattr_init(&mta); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_mutexattr_destroy(&mta); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + return LOS_OK; +} + + +VOID ItPosixMux001(void) +{ + TEST_ADD_CASE("ItPosixMux001", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/smoke/It_posix_mutex_007.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/smoke/It_posix_mutex_007.c new file mode 100644 index 00000000..d834eb33 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/smoke/It_posix_mutex_007.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +/* pthread_mutexattr_setprotocol 1-1.c + * Test that pthread_mutexattr_setprotocol() + * + * Sets the protocol attribute of a mutexattr object (which was prev. created + * by the function pthread_mutexattr_init()). + * + * Steps: + * 1. In a for loop, call pthread_mutexattr_setprotocol with all the valid 'protocol' values. + * 2. In the for loop, then call pthread_mutexattr_getprotocol and ensure that the same + * value that was set was the same value that was retrieved from this function. + */ +static UINT32 Testcase(VOID) +{ + pthread_mutexattr_t mta; + int protocol, protcls[3], i; + int rc; + + /* Initialize a mutex attributes object */ + rc = pthread_mutexattr_init(&mta); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + + protcls[0] = PTHREAD_PRIO_NONE; + protcls[1] = PTHREAD_PRIO_INHERIT; + protcls[2] = PTHREAD_PRIO_PROTECT; // 2, priority buffer index. + + for (i = 0; i < 3; i++) { // 3, The loop frequency. + /* Set the protocol to one of the 3 valid protocols. */ + rc = pthread_mutexattr_setprotocol(&mta, protcls[i]); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + + /* Get the protocol mutex attr. */ + rc = pthread_mutexattr_getprotocol(&mta, &protocol); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + + /* Make sure that the protocol set is the protocl we get when calling + * pthread_mutexattr_getprocol() */ + if (protocol != protcls[i]) { + ICUNIT_ASSERT_EQUAL(1, 0, LOS_NOK); + } + } + rc = pthread_mutexattr_destroy(&mta); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT); + + return LOS_OK; + +EXIT: + pthread_mutexattr_destroy(&mta); + return LOS_OK; +} + + +VOID ItPosixMux007(void) +{ + TEST_ADD_CASE("ItPosixMux007", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/smoke/It_posix_mutex_012.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/smoke/It_posix_mutex_012.c new file mode 100644 index 00000000..b7e5b48d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/smoke/It_posix_mutex_012.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +/* pthread_mutexattr_setprioceiling 1-1.c + * Test that pthread_mutexattr_setprioceiling() + * + * Sets the priority ceiling attribute of a mutexattr object (which was prev. created + * by the function pthread_mutexattr_init()). + * + * Steps: + * 1. Initialize a pthread_mutexattr_t object with pthread_mutexattr_init() + * 2. Get the min and max boundries for SCHED_FIFO of what prioceiling can be. + * 3. In a for loop, go through each valid SCHED_FIFO value, set the prioceiling. + * + */ +static UINT32 Testcase(VOID) +{ + pthread_mutexattr_t mta; + int maxPrio, minPrio, i; + int rc; + + /* Initialize a mutex attributes object */ + rc = pthread_mutexattr_init(&mta); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + + maxPrio = OS_TASK_PRIORITY_HIGHEST; + minPrio = OS_TASK_PRIORITY_LOWEST; + + for (i = maxPrio; (i < minPrio + 1); i++) { + /* Set the prioceiling to a priority number in the boundries + * of SCHED_FIFO policy */ + rc = pthread_mutexattr_setprioceiling(&mta, i); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT); + } + rc = pthread_mutexattr_destroy(&mta); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT); + + return LOS_OK; + +EXIT: + pthread_mutexattr_destroy(&mta); + return LOS_OK; +} + + +VOID ItPosixMux012(void) +{ + TEST_ADD_CASE("ItPosixMux012", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/smoke/It_posix_mutex_015.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/smoke/It_posix_mutex_015.c new file mode 100644 index 00000000..57a6b63d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/smoke/It_posix_mutex_015.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +/* pthread_mutexattr_getprioceiling 1-1.c + * Test that pthread_mutexattr_getprioceiling() + * + * Gets the priority ceiling attribute of a mutexattr object (which was prev. created + * by the function pthread_mutexattr_init()). + * + * Steps: + * 1. Initialize a pthread_mutexattr_t object with pthread_mutexattr_init() + * 2. Call pthread_mutexattr_getprioceiling() to obtain the prioceiling. + * + */ +static UINT32 Testcase(VOID) +{ + pthread_mutexattr_t ma; + int prioceiling, maxPrio, minPrio, ret; + + /* Initialize a mutex attributes object */ + ret = pthread_mutexattr_init(&ma); + ICUNIT_ASSERT_EQUAL(ret, ENOERR, ret); + + ret = pthread_mutexattr_setprotocol(&ma, PTHREAD_PRIO_PROTECT); + ICUNIT_GOTO_EQUAL(ret, ENOERR, ret, EXIT); + + /* Get the prioceiling mutex attr. */ + ret = pthread_mutexattr_getprioceiling(&ma, &prioceiling); + ICUNIT_GOTO_EQUAL(ret, ENOERR, ret, EXIT); + + /* Get the max and min according to SCHED_FIFO */ + maxPrio = OS_TASK_PRIORITY_HIGHEST; // 0 + minPrio = OS_TASK_PRIORITY_LOWEST; // 31 + + /* Ensure that prioceiling is within legal limits. */ + if ((prioceiling > minPrio) || (prioceiling < maxPrio)) { + ICUNIT_GOTO_EQUAL(1, 0, LOS_NOK, EXIT); + } + + ret = pthread_mutexattr_destroy(&ma); + ICUNIT_GOTO_EQUAL(ret, ENOERR, ret, EXIT); + + return LOS_OK; + +EXIT: + pthread_mutexattr_destroy(&ma); + return LOS_OK; +} + + +VOID ItPosixMux015(void) +{ + TEST_ADD_CASE("ItPosixMux015", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/smoke/It_posix_mutex_016.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/smoke/It_posix_mutex_016.c new file mode 100644 index 00000000..4ffe0bbf --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/smoke/It_posix_mutex_016.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +/* pthread_mutexattr_getprioceiling 1-2.c + * Test that pthread_mutexattr_getprioceiling() + * + * Gets the priority ceiling attribute of a mutexattr object (which was prev. created + * by the function pthread_mutexattr_init()). + * + * Steps: + * 1. Initialize a pthread_mutexattr_t object with pthread_mutexattr_init() + * 2. Get the min and max boundries for SCHED_FIFO of what prioceiling can be. + * 3. In a for loop, go through each valid SCHED_FIFO value, set the prioceiling, then + * get the prio ceiling. These should always be the same. If not, fail the test. + * + */ +static UINT32 Testcase(VOID) +{ + pthread_mutexattr_t mta; + int prioceiling, maxPrio, minPrio, i; + int rc; + + /* Initialize a mutex attributes object */ + rc = pthread_mutexattr_init(&mta); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + + /* Get the max and min prio according to SCHED_FIFO (posix scheduling policy) */ + maxPrio = OS_TASK_PRIORITY_HIGHEST; // 0 + minPrio = OS_TASK_PRIORITY_LOWEST; // 31 + + for (i = maxPrio; (i < minPrio + 1); i++) { + /* Set the prioceiling to a priority number in the boundries + * of SCHED_FIFO policy */ + rc = pthread_mutexattr_setprioceiling(&mta, i); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT); + + /* Get the prioceiling mutex attr. */ + rc = pthread_mutexattr_getprioceiling(&mta, &prioceiling); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT); + + /* Make sure that prioceiling is within the legal SCHED_FIFO boundries. */ + if (prioceiling != i) { + rc = pthread_mutexattr_destroy(&mta); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT); + return LOS_NOK; + } + } + rc = pthread_mutexattr_destroy(&mta); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT); + + return LOS_OK; + +EXIT: + pthread_mutexattr_destroy(&mta); + return LOS_OK; +} + + +VOID ItPosixMux016(void) +{ + TEST_ADD_CASE("ItPosixMux016", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/smoke/It_posix_mutex_019.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/smoke/It_posix_mutex_019.c new file mode 100644 index 00000000..7c5b1170 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/smoke/It_posix_mutex_019.c @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +static pthread_mutex_t *g_mtx; +static sem_t g_semA, g_semB; +static pthread_mutex_t g_mtxNull, g_mtxDef; + +static void *TaskF01(void *arg) +{ + int ret; + + TestBusyTaskDelay(20); // 20, Set the timeout of runtime. + + g_testCount++; + + if ((ret = pthread_mutex_lock(g_mtx))) { + ICUNIT_GOTO_EQUAL(1, 0, ret, EXIT); + } + + if ((ret = sem_post(&g_semA))) { + ICUNIT_GOTO_EQUAL(1, 0, ret, EXIT); + } + + if ((ret = sem_wait(&g_semB))) { + ICUNIT_GOTO_EQUAL(1, 0, ret, EXIT); + } + + if (g_retval != 0) { /* parent thread failed to unlock the mutex) */ + if ((ret = pthread_mutex_unlock(g_mtx))) { + ICUNIT_GOTO_EQUAL(1, 0, ret, EXIT); + } + } + + g_testCount++; + +EXIT: + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_mutexattr_t mattr; + pthread_t thr; + + pthread_mutex_t *tabMutex[2]; + int tabRes[2][3] = { {0, 0, 0}, {0, 0, 0} }; + + int ret; + void *thRet = NULL; + + int i; + + g_retval = 0; + + g_testCount = 0; + + /* We first initialize the two mutexes. */ + if ((ret = pthread_mutex_init(&g_mtxNull, NULL))) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + + if ((ret = pthread_mutexattr_init(&mattr))) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + + if ((ret = pthread_mutex_init(&g_mtxDef, &mattr))) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + + if ((ret = pthread_mutexattr_destroy(&mattr))) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + + tabMutex[0] = &g_mtxNull; + tabMutex[1] = &g_mtxDef; + + if ((ret = sem_init(&g_semA, 0, 0))) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + + if ((ret = sem_init(&g_semB, 0, 0))) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + + /* OK let's go for the first part of the test : abnormals unlocking */ + + /* We first check if unlocking an unlocked mutex returns an uwErr. */ + ret = pthread_mutex_unlock(tabMutex[0]); + ICUNIT_ASSERT_NOT_EQUAL(ret, ENOERR, ret); + + ret = pthread_mutex_unlock(tabMutex[1]); + ICUNIT_ASSERT_NOT_EQUAL(ret, ENOERR, ret); + + /* Now we focus on unlocking a mutex lock by another thread */ + for (i = 0; i < 2; i++) { // 2, Set the timeout of runtime + g_mtx = tabMutex[i]; + tabRes[i][0] = 0; + tabRes[i][1] = 0; + tabRes[i][2] = 0; // 2, buffer index. + + if ((ret = pthread_create(&thr, NULL, TaskF01, NULL))) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + + if (i == 0) { + ICUNIT_ASSERT_EQUAL(g_testCount, 0, g_testCount); + } + if (i == 1) { + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, Here, assert the g_testCount. + } + + if ((ret = sem_wait(&g_semA))) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + + g_retval = pthread_mutex_unlock(g_mtx); + ICUNIT_ASSERT_EQUAL(g_retval, EPERM, g_retval); + + if (i == 0) { + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + } + if (i == 1) { + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, Here, assert the g_testCount. + } + + if ((ret = sem_post(&g_semB))) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + + if ((ret = pthread_join(thr, &thRet))) { + ICUNIT_ASSERT_EQUAL(1, 0, ret); + } + + if (i == 0) { + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, Here, assert the g_testCount. + } + if (i == 1) { + ICUNIT_ASSERT_EQUAL(g_testCount, 4, g_testCount); // 4, Here, assert the g_testCount. + } + + tabRes[i][0] = g_retval; + } + + if (tabRes[0][0] != tabRes[1][0]) { + ICUNIT_ASSERT_EQUAL(1, 0, LOS_NOK); + } + + /* We start with testing the NULL mutex features */ + (void)pthread_mutexattr_destroy(&mattr); + ret = pthread_mutex_destroy(&g_mtxNull); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&g_mtxDef); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = sem_destroy(&g_semA); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = sem_destroy(&g_semB); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return LOS_OK; +} + + +VOID ItPosixMux019(void) +{ + TEST_ADD_CASE("ItPosixMux019", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/smoke/It_posix_mutex_020.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/smoke/It_posix_mutex_020.c new file mode 100644 index 00000000..f1750ae1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/mutex/smoke/It_posix_mutex_020.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_mutex.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +/* pthread_mutex_init 2-1.c + * Test that pthread_mutex_init() + * Upon successful initialization, the state of the mutex becomes + * initialized and unlocked. + * + */ +static UINT32 Testcase(VOID) +{ + pthread_mutex_t mutex; + int rc; + + /* Initialize a mutex object */ + rc = pthread_mutex_init(&mutex, NULL); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + + /* Acquire the mutex object using pthread_mutex_lock */ + rc = pthread_mutex_lock(&mutex); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT1); + + sleep(1); + + /* Release the mutex object using pthread_mutex_unlock */ + rc = pthread_mutex_unlock(&mutex); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT2); + + /* Destroy the mutex object */ + rc = pthread_mutex_destroy(&mutex); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT1); + + return LOS_OK; + +EXIT2: + pthread_mutex_unlock(&mutex); + +EXIT1: + pthread_mutex_destroy(&mutex); + return LOS_OK; +} + + +VOID ItPosixMux020(void) +{ + TEST_ADD_CASE("ItPosixMux020", Testcase, TEST_POSIX, TEST_MUX, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/It_posix_pthread.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/It_posix_pthread.c new file mode 100644 index 00000000..3607d837 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/It_posix_pthread.c @@ -0,0 +1,358 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +pthread_key_t g_key; +pthread_key_t g_pthreadKeyTest[PTHREAD_KEY_NUM]; +pthread_t g_newTh; +pthread_t g_newTh2; +pthread_once_t g_onceControl = PTHREAD_ONCE_INIT; +pthread_cond_t g_pthreadCondTest1 = PTHREAD_COND_INITIALIZER; +pthread_mutex_t g_pthreadMutexTest1 = PTHREAD_MUTEX_INITIALIZER; +INT32 g_startNum = 0; +INT32 g_wakenNum = 0; +INT32 g_t1Start = 0; +INT32 g_signaled = 0; +INT32 g_wokenUp = -1; +INT32 g_lowDone = -1; +INT32 g_pthreadSem = 0; /* Manual semaphore */ +INT32 g_pthreadScopeValue = 0; +INT32 g_pthreadSchedInherit = 0; +INT32 g_pthreadSchedPolicy = 0; + +ScenarIo g_scenarii[] = { + CASE_POS(0, 0, 0, 0, 0, 0, 0, 0, "default"), + CASE_POS(1, 0, 0, 0, 0, 0, 0, 0, "detached"), + CASE_POS(0, 1, 0, 0, 0, 0, 0, 0, "Explicit sched"), + CASE_UNK(0, 0, 1, 0, 0, 0, 0, 0, "FIFO Policy"), + CASE_UNK(0, 0, 2, 0, 0, 0, 0, 0, "RR Policy"), + CASE_UNK(0, 0, 0, 1, 0, 0, 0, 0, "Max sched param"), + CASE_UNK(0, 0, 0, -1, 0, 0, 0, 0, "Min sched param"), + CASE_POS(0, 0, 0, 0, 1, 0, 0, 0, "Alternative contension scope"), + CASE_POS(0, 0, 0, 0, 0, 1, 0, 0, "Alternative stack"), + CASE_POS(0, 0, 0, 0, 0, 0, 1, 0, "No guard size"), + CASE_UNK(0, 0, 0, 0, 0, 0, 2, 0, "1p guard size"), + CASE_POS(0, 0, 0, 0, 0, 0, 0, 1, "Min stack size"), + /* Stack play */ + CASE_POS(0, 0, 0, 0, 0, 0, 1, 1, "Min stack size, no guard"), + CASE_UNK(0, 0, 0, 0, 0, 0, 2, 1, "Min stack size, 1p guard"), + CASE_POS(1, 0, 0, 0, 0, 1, 0, 0, "Detached, Alternative stack"), + CASE_POS(1, 0, 0, 0, 0, 0, 1, 1, "Detached, Min stack size, no guard"), + CASE_UNK(1, 0, 0, 0, 0, 0, 2, 1, "Detached, Min stack size, 1p guard"), +}; + +pthread_t g_pthreadTestTh; + +VOID ScenarInit(VOID) +{ + INT32 ret; + UINT32 i; + INT32 old; + long pagesize, minstacksize; + long tsa, tss, tps; + + pagesize = sysconf(_SC_PAGESIZE); + minstacksize = sysconf(_SC_THREAD_STACK_MIN); + tsa = sysconf(_SC_THREAD_ATTR_STACKADDR); + tss = sysconf(_SC_THREAD_ATTR_STACKSIZE); + tps = sysconf(_SC_THREAD_PRIORITY_SCHEDULING); + + if (pagesize && minstacksize % pagesize) { + ICUNIT_ASSERT_EQUAL_VOID(1, 0, errno); + } + + for (i = 0; i < NSCENAR; i++) { + ret = pthread_attr_init(&g_scenarii[i].ta); + ICUNIT_ASSERT_EQUAL_VOID(ret, PTHREAD_NO_ERROR, ret); + + if (g_scenarii[i].detached == 1) { + ret = pthread_attr_setdetachstate(&g_scenarii[i].ta, PTHREAD_CREATE_DETACHED); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_getdetachstate(&g_scenarii[i].ta, &old); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_TRACK_EQUAL(old, PTHREAD_CREATE_JOINABLE, old); + } + + /* Sched related attributes */ + /* + * This routine is dependent on the Thread Execution + * Scheduling option + */ + if (tps > 0) { + if (g_scenarii[i].explicitsched == 1) + ret = pthread_attr_setinheritsched(&g_scenarii[i].ta, PTHREAD_EXPLICIT_SCHED); + else + ret = pthread_attr_setinheritsched(&g_scenarii[i].ta, PTHREAD_INHERIT_SCHED); + + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + } + + if (tps > 0) { + if (g_scenarii[i].schedpolicy == 1) + ret = pthread_attr_setschedpolicy(&g_scenarii[i].ta, SCHED_FIFO); + if (g_scenarii[i].schedpolicy == 2) // 2, set SCHED_RR as sched mode. + ret = pthread_attr_setschedpolicy(&g_scenarii[i].ta, SCHED_RR); + ICUNIT_ASSERT_EQUAL_VOID(ret, PTHREAD_NO_ERROR, ret); + + if (g_scenarii[i].schedparam != 0) { + struct sched_param sp; + + ret = pthread_attr_getschedpolicy(&g_scenarii[i].ta, &old); + ICUNIT_ASSERT_EQUAL_VOID(ret, PTHREAD_NO_ERROR, ret); + + if (g_scenarii[i].schedparam == 1) + sp.sched_priority = sched_get_priority_max(old); + if (g_scenarii[i].schedparam == -1) + sp.sched_priority = sched_get_priority_min(old); + + ret = pthread_attr_setschedparam(&g_scenarii[i].ta, &sp); + ICUNIT_ASSERT_EQUAL_VOID(ret, PTHREAD_NO_ERROR, ret); + } + + if (tps > 0) { + ret = pthread_attr_getscope(&g_scenarii[i].ta, &old); + ICUNIT_ASSERT_EQUAL_VOID(ret, PTHREAD_NO_ERROR, ret); + + if (g_scenarii[i].altscope != 0) { + if (old == PTHREAD_SCOPE_PROCESS) + old = PTHREAD_SCOPE_SYSTEM; + else + old = PTHREAD_SCOPE_PROCESS; + + ret = pthread_attr_setscope(&g_scenarii[i].ta, old); + } + } + + if ((tss > 0) && (tsa > 0)) { + if (g_scenarii[i].altstack != 0) { + g_scenarii[i].bottom = malloc(minstacksize + pagesize); + ICUNIT_TRACK_NOT_EQUAL(g_scenarii[i].bottom, NULL, g_scenarii[i].bottom); + } + } + + if (tss > 0) { + if (g_scenarii[i].altsize != 0) { + ret = pthread_attr_setstacksize(&g_scenarii[i].ta, minstacksize); + ICUNIT_ASSERT_EQUAL_VOID(ret, PTHREAD_NO_ERROR, ret); + } + } + + ret = sem_init(&g_scenarii[i].sem, 0, 0); + ICUNIT_ASSERT_EQUAL_VOID(ret, PTHREAD_NO_ERROR, ret); + } + } +} +/* + * This function will free all resources consumed + * in the scenar_init() routine + */ +VOID ScenarFini(VOID) +{ + INT32 ret; + UINT32 i; + + for (i = 0; i < NSCENAR; i++) { + if (g_scenarii[i].bottom != NULL) + free(g_scenarii[i].bottom); + + ret = sem_destroy(&g_scenarii[i].sem); + ICUNIT_ASSERT_EQUAL_VOID(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_destroy(&g_scenarii[i].ta); + ICUNIT_ASSERT_EQUAL_VOID(ret, PTHREAD_NO_ERROR, ret); + } +} + +/* + * return value of pthread_self() is 0 when + * pthread create from LOS_TaskCreate() + */ +pthread_t TestPthreadSelf(void) +{ + pthread_t tid = pthread_self(); + if (tid == 0) { + tid = ((LosTaskCB *)(OsCurrTaskGet()))->taskID; + } + return tid; +} + +VOID ItSuitePosixPthread() +{ +#if defined(LOSCFG_TEST_SMOKE) + ItPosixPthread003(); + ItPosixPthread004(); + ItPosixPthread005(); + ItPosixPthread006(); + ItPosixPthread009(); + ItPosixPthread018(); + ItPosixPthread019(); + ItPosixPthread021(); +#endif + +#if defined(LOSCFG_TEST_FULL) + ItPosixPthread001(); + ItPosixPthread002(); + ItPosixPthread007(); + ItPosixPthread008(); + ItPosixPthread010(); + ItPosixPthread011(); + ItPosixPthread013(); + ItPosixPthread023(); + ItPosixPthread028(); + ItPosixPthread029(); + ItPosixPthread030(); + ItPosixPthread031(); + ItPosixPthread032(); + ItPosixPthread033(); + ItPosixPthread034(); + ItPosixPthread035(); + ItPosixPthread039(); + ItPosixPthread040(); + ItPosixPthread041(); + ItPosixPthread042(); + ItPosixPthread044(); + ItPosixPthread045(); + ItPosixPthread046(); +#ifndef LOSCFG_KERNEL_SMP + ItPosixPthread047(); // pthread preemption, may not happen on smp +#endif + ItPosixPthread048(); + ItPosixPthread049(); + ItPosixPthread050(); + ItPosixPthread051(); + ItPosixPthread056(); + ItPosixPthread057(); + ItPosixPthread058(); + ItPosixPthread060(); + ItPosixPthread066(); + ItPosixPthread068(); + ItPosixPthread069(); + ItPosixPthread071(); + ItPosixPthread072(); + ItPosixPthread073(); + ItPosixPthread074(); + ItPosixPthread075(); + ItPosixPthread078(); + ItPosixPthread079(); + ItPosixPthread080(); + ItPosixPthread081(); + ItPosixPthread082(); + ItPosixPthread083(); + ItPosixPthread084(); + ItPosixPthread085(); + ItPosixPthread087(); + ItPosixPthread088(); + ItPosixPthread089(); + ItPosixPthread092(); + ItPosixPthread095(); + ItPosixPthread098(); + ItPosixPthread101(); + ItPosixPthread102(); + ItPosixPthread103(); + ItPosixPthread107(); + ItPosixPthread108(); + ItPosixPthread110(); + ItPosixPthread112(); + ItPosixPthread116(); + ItPosixPthread121(); + ItPosixPthread123(); + ItPosixPthread124(); + ItPosixPthread125(); + ItPosixPthread127(); + ItPosixPthread128(); + ItPosixPthread129(); + ItPosixPthread132(); + ItPosixPthread133(); + ItPosixPthread134(); + ItPosixPthread136(); + ItPosixPthread138(); + ItPosixPthread141(); + ItPosixPthread142(); + ItPosixPthread144(); + ItPosixPthread150(); + ItPosixPthread152(); + ItPosixPthread154(); + ItPosixPthread166(); + ItPosixPthread167(); + ItPosixPthread173(); + ItPosixPthread175(); + ItPosixPthread176(); + ItPosixPthread177(); + ItPosixPthread182(); + ItPosixPthread185(); + ItPosixPthread186(); + ItPosixPthread187(); + ItPosixPthread188(); + ItPosixPthread193(); + ItPosixPthread194(); + ItPosixPthread197(); + ItPosixPthread198(); + ItPosixPthread200(); + ItPosixPthread204(); + ItPosixPthread205(); + ItPosixPthread206(); + ItPosixPthread208(); + ItPosixPthread209(); + ItPosixPthread211(); + ItPosixPthread213(); + ItPosixPthread214(); + ItPosixPthread215(); + ItPosixPthread217(); + ItPosixPthread218(); + ItPosixPthread219(); + ItPosixPthread221(); + ItPosixPthread224(); + ItPosixPthread226(); + ItPosixPthread233(); + ItPosixPthread237(); + ItPosixPthread238(); + ItPosixPthread239(); + ItPosixPthread240(); + ItPosixPthread241(); + ItPosixPthread246(); +#endif +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/It_posix_pthread.h b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/It_posix_pthread.h new file mode 100644 index 00000000..d83b51f5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/It_posix_pthread.h @@ -0,0 +1,358 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IT_POSIX_PTHREAD_H +#define IT_POSIX_PTHREAD_H + +#include "sched.h" +#include "signal.h" +#include "semaphore.h" +#include "sched.h" +#include "osTest.h" +#include "pthread.h" +#include "pprivate.h" +#include "limits.h" +#include "unistd.h" +#include "mqueue.h" +#include "signal.h" + +#ifndef VERBOSE +#define VERBOSE 1 +#endif + +/* Some routines are part of the XSI Extensions */ +#ifndef WITHOUT_XOPEN +#define _XOPEN_SOURCE 600 +#endif + +#define PTHREAD_NO_ERROR 0 +#define PTHREAD_IS_ERROR (-1) +#define PTHREAD_SIGNAL_SUPPORT 0 /* 0 means that not support the signal */ +#define PTHREAD_PRIORITY_TEST 20 +#define PTHREAD_DEFAULT_STACK_SIZE (LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE) +#define PTHREAD_KEY_NUM 10 +#define THREAD_NUM 3 +#define PTHREAD_TIMEOUT (THREAD_NUM * 2) +#define PTHREAD_INTHREAD_TEST 0 /* Control going to or is already for Thread */ +#define PTHREAD_INMAIN_TEST 1 /* Control going to or is already for Main */ +#define INVALID_PSHARED_VALUE (-100) +#define NUM_OF_CONDATTR 10 +#define RUNTIME 5 +#define PTHREAD_THREADS_NUM 3 +#define TCOUNT 5 // Number of single-threaded polling +#define COUNT_LIMIT 7 // The number of times the signal is sent +#define HIGH_PRIORITY 5 +#define LOW_PRIORITY 10 +#define PTHREAD_EXIT_VALUE ((void *)100) /* The return code of the thread when using pthread_exit(). */ + +#define PTHREAD_EXISTED_NUM TASK_EXISTED_NUM +#define PTHREAD_EXISTED_SEM_NUM SEM_EXISTED_NUM + +/* We are testing conformance to IEEE Std 1003.1, 2003 Edition */ +#define _POSIX_C_SOURCE 200112L + +#define PTHREAD_MUTEX_RECURSIVE 0 +#define PTHREAD_MUTEX_ERRORCHECK 0 + +#define uart_printf_func dprintf + +#define PRIORITY_OTHER (-1) +#define PRIORITY_FIFO 20 +#define PRIORITY_RR 20 + +#define PTHREAD_TEST_BUG dprintf + +#define CASE(det, expl, scp, spa, sco, sta, gua, ssi, desc, res) \ + { \ + { 0 }, det, expl, scp, spa, sco, sta, gua, ssi, desc, NULL, res, \ + { \ + 0 \ + } \ + } +#define CASE_POS(det, expl, scp, spa, sco, sta, gua, ssi, desc) CASE(det, expl, scp, spa, sco, sta, gua, ssi, desc, 0) +#define CASE_NEG(det, expl, scp, spa, sco, sta, gua, ssi, desc) CASE(det, expl, scp, spa, sco, sta, gua, ssi, desc, 1) +#define CASE_UNK(det, expl, scp, spa, sco, sta, gua, ssi, desc) CASE(det, expl, scp, spa, sco, sta, gua, ssi, desc, 2) + +struct params { + INT32 policy; + INT32 priority; + char *policy_label; + INT32 status; +}; + +typedef struct { + /* + * Object to hold the given configuration, + * and which will be used to create the threads + */ + pthread_attr_t ta; + + /* General parameters */ + /* 0, joinable; 1, detached */ + INT32 detached; + + /* Scheduling parameters */ + /* + * 0, sched policy is inherited; + * 1, sched policy from the attr param + */ + INT32 explicitsched; + /* 0, default; 1, SCHED_FIFO; 2, SCHED_RR */ + INT32 schedpolicy; + /* + * 0, default sched param; + * 1, max value for sched param; + * -1, min value for sched param + */ + INT32 schedparam; + /* + * 0, default contension scope; + * 1, alternative contension scope + */ + INT32 altscope; + + /* Stack parameters */ + /* 0, system manages the stack; 1, stack is provided */ + INT32 altstack; + /* + * 0, default guardsize; + * 1, guardsize is 0; + * 2, guard is 1 page + * -- this setting only affect system stacks (not user's). + */ + INT32 guard; + /* + * 0, default stack size; + * 1, stack size specified (min value) + * -- ignored when stack is provided + */ + INT32 altsize; + + /* Additionnal information */ + /* object description */ + char *descr; + /* Stores the stack start when an alternate stack is required */ + void *bottom; + /* + * This thread creation is expected to: + * 0, succeed; 1, fail; 2, unknown + */ + INT32 result; + /* + * This semaphore is used to signal the end of + * the detached threads execution + */ + sem_t sem; +} ScenarIo; + +#define NSCENAR 10 // (sizeof(g_scenarii)/sizeof(g_scenarii[0])) + +extern ScenarIo g_scenarii[]; + +extern _pthread_data *pthread_get_self_data(void); +extern _pthread_data *pthread_get_data(pthread_t id); +extern pthread_key_t g_key; +extern pthread_key_t g_pthreadKeyTest[PTHREAD_KEY_NUM]; +extern pthread_t g_newTh; +extern pthread_t g_newTh2; +extern UINT32 g_taskMaxNum; +extern pthread_once_t g_onceControl; +extern pthread_cond_t g_pthreadCondTest1; +extern pthread_mutex_t g_pthreadMutexTest1; +extern INT32 g_startNum; +extern INT32 g_wakenNum; +extern INT32 g_t1Start; +extern INT32 g_signaled; +extern INT32 g_wokenUp; +extern INT32 g_lowDone; +extern INT32 g_pthreadSem; +extern INT32 g_pthreadScopeValue; +extern INT32 g_pthreadSchedInherit; +extern INT32 g_pthreadSchedPolicy; + +extern pthread_t g_pthreadTestTh; + +#ifdef LOSCFG_AARCH64 +#define PTHREAD_STACK_MIN_TEST (PTHREAD_STACK_MIN * 3) +#else +#define PTHREAD_STACK_MIN_TEST PTHREAD_STACK_MIN +#endif + +static pthread_t g_testNewTh; + +static struct testdata { + pthread_mutex_t mutex; + pthread_cond_t cond; +} g_td; + +extern unsigned int sleep(unsigned int seconds); +extern unsigned int alarm(unsigned int seconds); + +extern long sysconf(int name); + +VOID ScenarInit(VOID); +VOID ScenarFini(VOID); +pthread_t TestPthreadSelf(void); + +extern UINT32 PosixPthreadInit(pthread_attr_t *attr, INT32 pri); + +#if defined(LOSCFG_TEST_SMOKE) +VOID ItPosixPthread003(VOID); +VOID ItPosixPthread004(VOID); +VOID ItPosixPthread005(VOID); +VOID ItPosixPthread006(VOID); +VOID ItPosixPthread009(VOID); +VOID ItPosixPthread018(VOID); +VOID ItPosixPthread019(VOID); +VOID ItPosixPthread021(VOID); +#endif + +#if defined(LOSCFG_TEST_FULL) +VOID ItPosixPthread001(VOID); +VOID ItPosixPthread002(VOID); +VOID ItPosixPthread007(VOID); +VOID ItPosixPthread008(VOID); +VOID ItPosixPthread010(VOID); +VOID ItPosixPthread011(VOID); +VOID ItPosixPthread013(VOID); +VOID ItPosixPthread023(VOID); +VOID ItPosixPthread028(VOID); +VOID ItPosixPthread029(VOID); +VOID ItPosixPthread030(VOID); +VOID ItPosixPthread031(VOID); +VOID ItPosixPthread032(VOID); +VOID ItPosixPthread033(VOID); +VOID ItPosixPthread034(VOID); +VOID ItPosixPthread035(VOID); +VOID ItPosixPthread039(VOID); +VOID ItPosixPthread040(VOID); +VOID ItPosixPthread041(VOID); +VOID ItPosixPthread042(VOID); +VOID ItPosixPthread044(VOID); +VOID ItPosixPthread045(VOID); +VOID ItPosixPthread046(VOID); +VOID ItPosixPthread048(VOID); +VOID ItPosixPthread049(VOID); +VOID ItPosixPthread050(VOID); +VOID ItPosixPthread051(VOID); +VOID ItPosixPthread056(VOID); +VOID ItPosixPthread057(VOID); +VOID ItPosixPthread058(VOID); +VOID ItPosixPthread060(VOID); +VOID ItPosixPthread066(VOID); +VOID ItPosixPthread068(VOID); +VOID ItPosixPthread069(VOID); +VOID ItPosixPthread071(VOID); +VOID ItPosixPthread072(VOID); +VOID ItPosixPthread073(VOID); +VOID ItPosixPthread074(VOID); +VOID ItPosixPthread075(VOID); +VOID ItPosixPthread078(VOID); +VOID ItPosixPthread079(VOID); +VOID ItPosixPthread080(VOID); +VOID ItPosixPthread081(VOID); +VOID ItPosixPthread082(VOID); +VOID ItPosixPthread083(VOID); +VOID ItPosixPthread084(VOID); +VOID ItPosixPthread085(VOID); +VOID ItPosixPthread087(VOID); +VOID ItPosixPthread088(VOID); +VOID ItPosixPthread089(VOID); +VOID ItPosixPthread092(VOID); +VOID ItPosixPthread095(VOID); +VOID ItPosixPthread098(VOID); +VOID ItPosixPthread101(VOID); +VOID ItPosixPthread102(VOID); +VOID ItPosixPthread103(VOID); +VOID ItPosixPthread107(VOID); +VOID ItPosixPthread108(VOID); +VOID ItPosixPthread110(VOID); +VOID ItPosixPthread112(VOID); +VOID ItPosixPthread116(VOID); +VOID ItPosixPthread121(VOID); +VOID ItPosixPthread123(VOID); +VOID ItPosixPthread124(VOID); +VOID ItPosixPthread125(VOID); +VOID ItPosixPthread127(VOID); +VOID ItPosixPthread128(VOID); +VOID ItPosixPthread129(VOID); +VOID ItPosixPthread132(VOID); +VOID ItPosixPthread133(VOID); +VOID ItPosixPthread134(VOID); +VOID ItPosixPthread136(VOID); +VOID ItPosixPthread138(VOID); +VOID ItPosixPthread141(VOID); +VOID ItPosixPthread142(VOID); +VOID ItPosixPthread144(VOID); +VOID ItPosixPthread150(VOID); +VOID ItPosixPthread152(VOID); +VOID ItPosixPthread154(VOID); +VOID ItPosixPthread166(VOID); +VOID ItPosixPthread167(VOID); +VOID ItPosixPthread173(VOID); +VOID ItPosixPthread175(VOID); +VOID ItPosixPthread176(VOID); +VOID ItPosixPthread177(VOID); +VOID ItPosixPthread182(VOID); +VOID ItPosixPthread185(VOID); +VOID ItPosixPthread186(VOID); +VOID ItPosixPthread187(VOID); +VOID ItPosixPthread188(VOID); +VOID ItPosixPthread193(VOID); +VOID ItPosixPthread194(VOID); +VOID ItPosixPthread197(VOID); +VOID ItPosixPthread198(VOID); +VOID ItPosixPthread200(VOID); +VOID ItPosixPthread204(VOID); +VOID ItPosixPthread205(VOID); +VOID ItPosixPthread206(VOID); +VOID ItPosixPthread208(VOID); +VOID ItPosixPthread209(VOID); +VOID ItPosixPthread211(VOID); +VOID ItPosixPthread213(VOID); +VOID ItPosixPthread214(VOID); +VOID ItPosixPthread215(VOID); +VOID ItPosixPthread217(VOID); +VOID ItPosixPthread218(VOID); +VOID ItPosixPthread219(VOID); +VOID ItPosixPthread221(VOID); +VOID ItPosixPthread224(VOID); +VOID ItPosixPthread226(VOID); +VOID ItPosixPthread233(VOID); +VOID ItPosixPthread237(VOID); +VOID ItPosixPthread238(VOID); +VOID ItPosixPthread239(VOID); +VOID ItPosixPthread240(VOID); +VOID ItPosixPthread241(VOID); +VOID ItPosixPthread246(VOID); +#endif + +#endif /* IT_POSIX_PTHREAD_H */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/Makefile b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/Makefile new file mode 100644 index 00000000..041c2040 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/Makefile @@ -0,0 +1,36 @@ + +include $(LITEOSTESTTOPDIR)/config.mk + +MODULE_NAME := pthreadtest + +LOCAL_INCLUDE := \ + -I $(LITEOSTESTTOPDIR)/kernel/include \ + -I $(LITEOSTOPDIR)/compat/posix/src \ + -I $(LITEOSTESTTOPDIR)/kernel/sample/posix/pthread + +SRC_MODULES := . + +ifeq ($(LOSCFG_TEST_LLT), y) +LLT_MODULES := llt +endif + +ifeq ($(LOSCFG_TEST_PRESSURE), y) +PRESSURE_MODULES := pressure +endif + +ifeq ($(LOSCFG_TEST_SMOKE), y) +SMOKE_MODULES := smoke +endif + +ifeq ($(LOSCFG_TEST_FULL), y) +FULL_MODULES := full +endif + +LOCAL_MODULES := $(SRC_MODULES) $(LLT_MODULES) $(PRESSURE_MODULES) $(SMOKE_MODULES) $(FULL_MODULES) + +LOCAL_SRCS := $(foreach dir,$(LOCAL_MODULES),$(wildcard $(dir)/*.c)) +LOCAL_CHS := $(foreach dir,$(LOCAL_MODULES),$(wildcard $(dir)/*.h)) + +LOCAL_FLAGS := $(LOCAL_INCLUDE) -Wno-error + +include $(MODULE) diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_001.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_001.c new file mode 100644 index 00000000..c2050a63 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_001.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ +#ifndef PTHREAD_CANCEL_ASYNCHRONOUS +#error PTHREAD_CANCEL_ASYNCHRONOUS not defined +#endif + +#ifndef PTHREAD_CANCEL_ENABLE +#error PTHREAD_CANCEL_ENABLE not defined +#endif + +#ifndef PTHREAD_CANCEL_DEFERRED +#error PTHREAD_CANCEL_DEFERRED not defined +#endif + +#ifndef PTHREAD_CANCEL_DISABLE +#error PTHREAD_CANCEL_DISABLE not defined +#endif + +#ifndef PTHREAD_CANCELED +#error PTHREAD_CANCELED not defined +#endif + +#ifndef PTHREAD_CREATE_DETACHED +#error PTHREAD_CREATE_DETACHED not defined +#endif + +#ifndef PTHREAD_CREATE_JOINABLE +#error PTHREAD_CREATE_JOINABLE not defined +#endif + +#ifndef PTHREAD_EXPLICIT_SCHED +#error PTHREAD_EXPLICIT_SCHED not defined +#endif + +#ifndef PTHREAD_INHERIT_SCHED +#error PTHREAD_INHERIT_SCHED not defined +#endif + +#ifndef PTHREAD_ONCE_INIT +#error PTHREAD_ONCE_INIT not defined +#endif + +#ifndef PTHREAD_PROCESS_SHARED +#error PTHREAD_PROCESS_SHARED not defined +#endif + +#ifndef PTHREAD_PROCESS_PRIVATE +#error PTHREAD_PROCESS_PRIVATE not defined +#endif + +#ifndef PTHREAD_COND_INITIALIZER +#error PTHREAD_COND_INTIALIZER not defined +#endif + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread001(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread001", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_002.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_002.c new file mode 100644 index 00000000..aac44f8d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_002.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + pthread_attr_t dummy1; + pthread_key_t dummy6; + pthread_mutex_t dummy7; + pthread_mutexattr_t dummy8; + pthread_once_t dummy9; + pthread_t dummy13; + pthread_once_t dummy; + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread002(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread002", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_007.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_007.c new file mode 100644 index 00000000..4bbb07c7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_007.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(void *argument) +{ + g_testCount++; + + return argument; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + pthread_attr_t attr; + UINT32 ret; + UINT32 uwint = 8; + char cc = 'a'; + char str[5] = "abcd"; + _pthread_data *joinee = NULL; + UINTPTR temp; + + g_testCount = 0; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + /* Create a new thread. */ + ret = pthread_create(NULL, &attr, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_create(&newTh, NULL, PthreadF01, (void *)&uwint); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + LOS_TaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = pthread_join(newTh, (void *)&temp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(*((UINT32 *)temp), 8, *((UINT32 *)temp)); // 8, here assert the result. + + ret = pthread_create(&newTh, &attr, NULL, (void *)8); // 8, test for invalid param. + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_create(&newTh, &attr, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LOS_TaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, here assert the result. + + ret = pthread_join(newTh, (void *)&temp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL((UINT32)temp, 0, (UINT32)temp); + + ret = pthread_create(&newTh, &attr, PthreadF01, (void *)&cc); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LOS_TaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, here assert the result. + ret = pthread_join(newTh, (void *)&temp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(*((char *)temp), 97, *((char *)temp)); // 97, here assert the result. + + ret = pthread_create(&newTh, &attr, PthreadF01, (void *)str); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LOS_TaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 4, g_testCount); // 4, here assert the result. + + ret = pthread_join(newTh, (void *)&temp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_STRING_EQUAL((char *)temp, "abcd", (char *)temp); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread007(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread007", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_008.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_008.c new file mode 100644 index 00000000..4fc0489f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_008.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + + g_testCount = 0; + + ret = pthread_attr_init(NULL); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_attr_destroy(NULL); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread008(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread008", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_010.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_010.c new file mode 100644 index 00000000..6f3a9f76 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_010.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(void *argument) +{ + g_testCount = pthread_self(); + + pthread_exit((void *)8); // 8, here set value of the exit status. + + return (void *)9; // 9, here set value of the return status. +} +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + UINT32 ret; + UINTPTR temp = 1; + + g_testCount = 0; + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LOS_TaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, newTh, g_testCount); + + ret = pthread_join(newTh, (void *)&temp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(temp, 8, temp); // 8, here assert the result. + + temp = TestPthreadSelf(); + ret = pthread_equal(temp, g_testCount); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_equal(newTh, g_testCount); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + + ret = pthread_equal(0, 0); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + + ret = pthread_equal(0, 1); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread010(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread010", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_011.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_011.c new file mode 100644 index 00000000..fc827820 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_011.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + pthread_attr_t attr; + UINT32 ret; + int detachstate; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_setdetachstate(NULL, PTHREAD_CREATE_DETACHED); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE - 1); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_attr_setdetachstate(&attr, 3); // 3, test the param of function. + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_attr_getdetachstate(NULL, &detachstate); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_attr_getdetachstate(&attr, NULL); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_getdetachstate(&attr, &detachstate); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(detachstate, PTHREAD_CREATE_DETACHED, detachstate); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread011(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread011", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_013.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_013.c new file mode 100644 index 00000000..447d8d23 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_013.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + pthread_attr_t attr; + UINT32 ret; + int inherit; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_setinheritsched(NULL, PTHREAD_INHERIT_SCHED); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED - 1); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED + 1); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_attr_getinheritsched(NULL, &inherit); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_attr_getinheritsched(&attr, NULL); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_getinheritsched(&attr, &inherit); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(inherit, PTHREAD_EXPLICIT_SCHED, inherit); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread013(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread013", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_023.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_023.c new file mode 100644 index 00000000..89caf553 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_023.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void PthreadCleanF01(void *arg) +{ + ICUNIT_ASSERT_EQUAL_VOID((int)(intptr_t)arg, 8, (int)(intptr_t)arg); // 8, here assert the result. + g_testCount++; + + return; +} + +static VOID *PthreadF01(void *argument) +{ + g_testCount++; + + pthread_cleanup_push(PthreadCleanF01, (void *)8); // 8, here set value. + return (void *)8; // 8, here set value about the return status. +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + + UINT32 ret; + UINTPTR temp = 1; + + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + LOS_TaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = pthread_join(newTh, (void *)&temp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(temp, 8, temp); // 8, here assert the result. + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread023(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread023", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_028.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_028.c new file mode 100644 index 00000000..01c5f57e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_028.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(void *argument) +{ + g_testCount++; + + return (void *)9; // 9, here set value about the return status. +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + + UINT32 ret; + UINTPTR temp = 1; + + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + LOS_TaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = pthread_join(newTh, (void *)&temp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(temp, 9, temp); // 9, here assert the result. + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread028(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread028", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_029.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_029.c new file mode 100644 index 00000000..39c2e3e9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_029.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(void *argument) +{ + g_testCount++; + + pthread_exit((void *)8); // 8, here set value about the exit status. + return (void *)9; // 9, here set value about the return status. +} +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + + UINT32 ret; + UINTPTR temp = 1; + + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + LOS_TaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = pthread_join(newTh, (void *)&temp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(temp, 8, temp); // 8, here assert the result. + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread029(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread029", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_030.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_030.c new file mode 100644 index 00000000..d8b2dc7c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_030.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(void *argument) +{ + g_testCount++; + LOS_TaskDelay(2); // 2, delay for Timing control. + TestExtraTaskDelay(2); // 2, delay for Timing control. + + pthread_testcancel(); + g_testCount++; + return (void *)9; // 9, here set value about the return status. +} +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + + UINT32 ret; + UINTPTR temp = 1; + + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + LOS_TaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = pthread_cancel(newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newTh, (void *)&temp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(temp, (UINTPTR)PTHREAD_CANCELED, temp); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread030(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread030", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_031.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_031.c new file mode 100644 index 00000000..7798190c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_031.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(void *argument) +{ + UINT32 ret; + + g_testCount++; + + ret = pthread_join(g_newTh, NULL); + ICUNIT_GOTO_NOT_EQUAL(ret, 0, ret, EXIT); +EXIT: + return (void *)9; // 9, here set value about the return status. +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINTPTR temp = 1; + + g_testCount = 0; + + ret = pthread_create(&g_newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + LOS_TaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = pthread_join(g_newTh, (void *)&temp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(temp, 9, temp); // 9, here assert the result. + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread031(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread031", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_032.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_032.c new file mode 100644 index 00000000..2afbcb30 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_032.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(void *argument) +{ + g_testCount++; + + return (void *)9; // 9, here set value about the return status. +} + +static VOID *PthreadF02(void *argument) +{ + UINT32 ret; + UINTPTR temp = 1; + + TestExtraTaskDelay(2); // 2, delay for Timing control. + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + g_testCount++; + + ret = pthread_join(g_newTh2, (void *)&temp); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ICUNIT_GOTO_EQUAL(temp, 7, temp, EXIT); // 7, here assert the result. + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, here assert the result. + g_testCount++; +EXIT: + return (void *)8; // 8, here set value about the return status. +} + +static VOID *PthreadF03(void *argument) +{ + UINT32 ret; + UINTPTR temp = 1; + + TestExtraTaskDelay(4); // 4, delay for Timing control. + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, here assert the result. + g_testCount++; + + ret = pthread_join(g_newTh, (void *)&temp); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ICUNIT_GOTO_EQUAL(temp, 9, temp, EXIT); // 9, here assert the result. + +EXIT: + return (void *)7; // 7, here set value about the return status. +} +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + pthread_attr_t attr; + UINT32 ret; + UINTPTR temp = 1; + + g_testCount = 0; + + ret = PosixPthreadInit(&attr, 4); // 4, test for param of the function. + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LOS_TaskLock(); + + ret = pthread_create(&g_newTh, &attr, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newTh, &attr, PthreadF02, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&g_newTh2, &attr, PthreadF03, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LOS_TaskUnlock(); + + TestExtraTaskDelay(6); // 6, delay for Timing control. + + ICUNIT_ASSERT_EQUAL(g_testCount, 4, g_testCount); // 4, here assert the result. + + ret = pthread_join(newTh, (void *)&temp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(temp, 8, temp); // 8, here assert the result. + + ret = pthread_join(newTh, (void *)&temp); + ICUNIT_ASSERT_EQUAL(ret, ESRCH, ret); + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread032(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread032", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_033.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_033.c new file mode 100644 index 00000000..391f40cf --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_033.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(void *argument) +{ + g_testCount++; + + return (void *)9; // 9, here set value about the return status. +} + +static VOID *PthreadF02(void *argument) +{ + UINT32 ret; + UINTPTR temp = 1; + + g_testCount++; + + LOS_TaskDelay(5); // 5, delay for Timing control. + TestExtraTaskDelay(1); + ret = pthread_join(g_newTh, (void *)&temp); + ICUNIT_GOTO_NOT_EQUAL(ret, 0, ret, EXIT); +EXIT: + return (void *)8; // 8, here set value about the return status. +} + + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + + UINT32 ret; + UINTPTR temp = 1; + + g_testCount = 0; + + ret = pthread_create(&g_newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newTh, NULL, PthreadF02, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LOS_TaskDelay(2); // 2, delay for Timing control. + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, here assert the result. + + ret = pthread_join(g_newTh, (void *)&temp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(temp, 9, temp); // 9, here assert the result. + + LOS_TaskDelay(2); // 2, delay for Timing control. + ret = pthread_join(g_newTh, (void *)&temp); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + + ret = pthread_join(newTh, (void *)&temp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(temp, 8, temp); // 8, here assert the result. + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread033(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread033", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_034.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_034.c new file mode 100644 index 00000000..88d3f65b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_034.c @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + +#define LOOP_NUM 2000 + +static VOID *PthreadF01(void *argument) +{ + UINT32 i, j; + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + for (i = 0, j = 0; i < LOOP_NUM; i++) { + j++; + } + + g_testCount++; + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); +EXIT: + return (void *)9; // 9, here set value about the return status. +} + +static VOID *PthreadF02(void *argument) +{ + UINT32 i, j; + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + for (i = 0, j = 0; i < LOOP_NUM; i++) { + j++; + } + + g_testCount++; + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, here assert the result. +EXIT: + return (void *)8; // 8, here set value about the return status. +} + +static VOID *PthreadF03(void *argument) +{ + UINT32 i, j; + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, here assert the result. + + for (i = 0, j = 0; i < LOOP_NUM; i++) { + j++; + } + + g_testCount++; + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, here assert the result. + +EXIT: + return (void *)7; // 7, here set value about the return status. +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh, newTh2, newTh3; + + UINT32 ret; + UINTPTR temp = 1; + + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newTh2, NULL, PthreadF02, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newTh3, NULL, PthreadF03, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LOS_TaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, here assert the result. + + ret = pthread_join(newTh, (void *)&temp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newTh2, (void *)&temp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newTh3, (void *)&temp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread034(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread034", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_035.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_035.c new file mode 100644 index 00000000..2af191f0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_035.c @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(void *argument) +{ + UINT32 j = 0; + INT32 value; + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + g_testCount++; + + while (g_testCount != 3) { // 3, wait until g_testCount is equal to 3. + j++; + } + g_testCount++; + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, here assert the result. +EXIT: + return (void *)9; // 9, here set value about the return status. +} + +static VOID *PthreadF02(void *argument) +{ + UINT32 j = 0; + INT32 value; + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + g_testCount++; + + while (g_testCount != 4) { // 4, wait until g_testCount is equal to 4. + j++; + } + + g_testCount++; + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); // 5, here assert the result. +EXIT: + return (void *)8; // 8, here set value about the return status. +} + +static VOID *PthreadF03(void *argument) +{ + UINT32 j = 0; + INT32 value; + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, here assert the result. + g_testCount++; + + while (g_testCount != 5) { // 5, wait until g_testCount is equal to 5. + j++; + } + + g_testCount++; + ICUNIT_GOTO_EQUAL(g_testCount, 6, g_testCount, EXIT); // 6, here assert the result. + +EXIT: + return (void *)7; // 7, here set value about the return status. +} +static UINT32 Testcase(VOID) +{ + pthread_t newTh, newTh2, newTh3; + + UINT32 ret; + UINTPTR temp = 1; + + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newTh2, NULL, PthreadF02, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newTh3, NULL, PthreadF03, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + while (g_testCount < 6) { // 6, wait until g_testCount is equal to 6. + sleep(1); + } + + ICUNIT_ASSERT_EQUAL(g_testCount, 6, g_testCount); // 6, here assert the result. + + ret = pthread_join(newTh, (void *)&temp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newTh2, (void *)&temp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newTh3, (void *)&temp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread035(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread035", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_039.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_039.c new file mode 100644 index 00000000..042fe0bc --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_039.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(void *argument) +{ + g_testCount++; + LOS_TaskDelay(2); // 2, delay for Timing control. + pthread_testcancel(); + g_testCount++; + return (void *)9; // 9, here set value about the return status. +} + +static UINT32 Testcase(VOID) +{ + INT32 count = PTHREAD_EXISTED_NUM; + pthread_t newTh; + UINT32 ret; + UINT32 index; + UINT32 count1 = 0; + + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + LOS_TaskDelay(1); + + ret = pthread_cancel(newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_detach(newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + LOS_TaskDelay(2); // 2, delay for Timing control. + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + for (index = 0; index < LOSCFG_BASE_CORE_TSK_LIMIT; index++) { + if (g_taskCBArray[index].taskStatus == OS_TASK_STATUS_UNUSED) { + count1++; + } + } + + ICUNIT_ASSERT_EQUAL(count1, g_taskMaxNum - count - 1, count1); + + ret = pthread_create(&newTh, NULL, PthreadF01, + NULL); // the detach will release resources the next time when creates one pthread + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + LOS_TaskDelay(2); // 2, delay for Timing control. + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + for (count1 = 0, index = 0; index < LOSCFG_BASE_CORE_TSK_LIMIT; index++) { + if (g_taskCBArray[index].taskStatus == OS_TASK_STATUS_UNUSED) { + count1++; + } + } + + ICUNIT_ASSERT_EQUAL(count1, g_taskMaxNum - count, count1); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread039(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread039", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_040.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_040.c new file mode 100644 index 00000000..5ae39d28 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_040.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(void *argument) +{ + g_testCount++; + LOS_TaskDelay(2); // 2, delay for Timing control. + g_testCount++; + + return (void *)9; // 9, here set value about the return status. +} +static UINT32 Testcase(VOID) +{ + INT32 count = PTHREAD_EXISTED_NUM; + pthread_t newTh; + UINT32 ret; + UINT32 index; + UINT32 count1 = 0; + + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + LOS_TaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = pthread_detach(newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + + LOS_TaskDelay(2); // 2, delay for Timing control. + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, here assert the result. + + for (index = 0; index < LOSCFG_BASE_CORE_TSK_LIMIT; index++) { + if (g_taskCBArray[index].taskStatus & OS_TASK_STATUS_UNUSED) { + count1++; + } + } + + ICUNIT_ASSERT_EQUAL(count1, g_taskMaxNum - count, count1); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread040(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread040", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_041.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_041.c new file mode 100644 index 00000000..c7521150 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_041.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(void *argument) +{ + g_testCount++; + + return (void *)9; // 9, here set value about the return status. +} + +static UINT32 Testcase(VOID) +{ + INT32 count = PTHREAD_EXISTED_NUM; + pthread_t newTh; + UINT32 ret; + UINT32 index; + UINT32 count1 = 0; + + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + LOS_TaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_detach(newTh); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + + LOS_TaskDelay(1); + + for (index = 0; index < LOSCFG_BASE_CORE_TSK_LIMIT; index++) { + if (g_taskCBArray[index].taskStatus == OS_TASK_STATUS_UNUSED) { + count1++; + } + } + + ICUNIT_ASSERT_EQUAL(count1, g_taskMaxNum - count, count1); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread041(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread041", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_042.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_042.c new file mode 100644 index 00000000..907c0680 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_042.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(void *argument) +{ + g_testCount++; + LOS_TaskDelay(2); // 2, delay for Timing control. + g_testCount++; + + return (void *)9; // 9, here set value about the return status. +} +static UINT32 Testcase(VOID) +{ + INT32 count = PTHREAD_EXISTED_NUM; + pthread_t newTh; + UINT32 ret; + UINT32 index; + UINT32 count1 = 0; + pthread_attr_t attr; + int detachstate; + + g_testCount = 0; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_getdetachstate(&attr, &detachstate); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(detachstate, PTHREAD_CREATE_JOINABLE, detachstate); + + ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newTh, &attr, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LOS_TaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + + ret = pthread_detach(newTh); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + + LOS_TaskDelay(3); // 3, delay for Timing control. + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, here assert the result. + for (index = 0; index < LOSCFG_BASE_CORE_TSK_LIMIT; index++) { + if (g_taskCBArray[index].taskStatus & OS_TASK_STATUS_UNUSED) { + count1++; + } + } + + ICUNIT_ASSERT_EQUAL(count1, g_taskMaxNum - count, count1); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + + ret = pthread_detach(newTh); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + + ret = pthread_attr_getdetachstate(&attr, &detachstate); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(detachstate, PTHREAD_CREATE_DETACHED, detachstate); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread042(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread042", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_044.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_044.c new file mode 100644 index 00000000..0591b40c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_044.c @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF02(void *argument) +{ + _pthread_data *info = NULL; + + TestExtraTaskDelay(2); // 2, delay for Timing control. + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + g_testCount++; + + info = pthread_get_self_data(); + + // 3, here assert the result. + ICUNIT_GOTO_EQUAL(info->attr.schedparam.sched_priority, 3, info->attr.schedparam.sched_priority, EXIT); + ICUNIT_GOTO_EQUAL(info->attr.schedpolicy, SCHED_RR, info->attr.schedpolicy, EXIT); + ICUNIT_GOTO_EQUAL(info->attr.scope, PTHREAD_SCOPE_PROCESS, info->attr.scope, EXIT); + ICUNIT_GOTO_EQUAL(info->task->priority, 3, info->task->priority, EXIT); // 3, here assert the result. +EXIT: + return (void *)9; // 9, here set value about the return status. +} + +static VOID *PthreadF01(void *argument) +{ + pthread_t newTh; + UINT32 ret; + pthread_attr_t attr; + struct sched_param param; + _pthread_data *info = NULL; + + g_testCount++; + + info = pthread_get_self_data(); + + // 4, here assert the result. + ICUNIT_GOTO_EQUAL(info->attr.schedparam.sched_priority, 4, info->attr.schedparam.sched_priority, EXIT); + ICUNIT_GOTO_EQUAL(info->attr.schedpolicy, SCHED_RR, info->attr.schedpolicy, EXIT); + ICUNIT_GOTO_EQUAL(info->attr.scope, PTHREAD_SCOPE_PROCESS, info->attr.scope, EXIT); + ICUNIT_GOTO_EQUAL(info->task->priority, 4, info->task->priority, EXIT); // 4, here assert the result. + + ret = pthread_attr_init(&attr); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_create(&newTh, &attr, PthreadF02, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + param.sched_priority = 3; // 3, set priority. + ret = pthread_setschedparam(newTh, SCHED_RR, ¶m); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_detach(newTh); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + TestExtraTaskDelay(4); // 4, delay for Timing control. + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, here assert the result. + g_testCount++; + ret = pthread_attr_destroy(&attr); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); +EXIT: + return (void *)9; // 9, here set value about the return status. +} +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + UINT32 ret; + pthread_attr_t attr; + int inherit; + struct sched_param param; + + g_testCount = 0; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_setschedpolicy(&attr, SCHED_RR); // + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + param.sched_priority = 4; // 4, set priority. + ret = pthread_attr_setschedparam(&attr, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_setscope(&attr, PTHREAD_SCOPE_PROCESS); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newTh, &attr, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + TestExtraTaskDelay(6); // 6, delay for Timing control. + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, here assert the result. + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_getinheritsched(&attr, &inherit); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(inherit, PTHREAD_EXPLICIT_SCHED, inherit); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread044(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread044", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_045.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_045.c new file mode 100644 index 00000000..c8520925 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_045.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(void *argument) +{ + _pthread_data *info = NULL; + + g_testCount++; + dprintf("!!!!!!!!!\n"); + dprintf("%x\n", TASK_STACK_SIZE_TEST); + info = pthread_get_self_data(); + + // 3, here assert the result. + ICUNIT_GOTO_EQUAL(info->attr.stacksize, (TASK_STACK_SIZE_TEST + 3) & ~3, info->attr.stacksize, EXIT); // failed + ICUNIT_GOTO_EQUAL(info->attr.stacksize_set, 1, info->attr.stacksize_set, EXIT); + // 3, here assert the result. + ICUNIT_GOTO_EQUAL(info->task->stackSize, (TASK_STACK_SIZE_TEST + 3) & ~3, info->task->stackSize, EXIT); + + g_testCount++; + +EXIT: + return (void *)9; // 9, here set value about the return status. +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + int ret; + pthread_attr_t attr; + size_t stacksize; + size_t stacksize2; + + g_testCount = 0; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + stacksize = TASK_STACK_SIZE_TEST; + ret = pthread_attr_setstacksize(&attr, stacksize); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newTh, &attr, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + +#ifdef TEST3559A_M7 + ret = LOS_TaskDelay(10); // 10, delay for Timing control. +#else + ret = LOS_TaskDelay(10); // 10, delay for Timing control. +#endif + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, here assert the result. + + ret = pthread_join(newTh, NULL); + + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_getstacksize(&attr, &stacksize2); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(stacksize2, TASK_STACK_SIZE_TEST, stacksize2); + + attr.stacksize_set = 1; + attr.stacksize = LOS_TASK_MIN_STACK_SIZE - 2 * sizeof(UINTPTR); // 2, Set reasonable stack size. + ret = pthread_create(&newTh, &attr, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread045(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread045", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_046.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_046.c new file mode 100644 index 00000000..5bd03270 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_046.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(void *argument) +{ + _pthread_data *info = NULL; + + g_testCount++; + + info = pthread_get_self_data(); + + ICUNIT_GOTO_EQUAL(info->attr.stacksize, + // 2, here assert the result. + ((PTHREAD_STACK_MIN_TEST + 1 + (sizeof(UINTPTR) * 2 - 1)) & ~(sizeof(UINTPTR) * 2 - 1)), info->attr.stacksize, + EXIT); + ICUNIT_GOTO_EQUAL(info->attr.stacksize_set, 1, info->attr.stacksize_set, EXIT); + + ICUNIT_GOTO_EQUAL(info->task->stackSize, + // 2, here assert the result. + ((PTHREAD_STACK_MIN_TEST + 1 + (sizeof(UINTPTR) * 2 - 1)) & ~(sizeof(UINTPTR) * 2 - 1)), info->task->stackSize, + EXIT); + + g_testCount++; + +EXIT: + return (void *)9; // 9, here set value about the return status. +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + UINT32 ret; + pthread_attr_t attr; + size_t stacksize; + size_t stacksize2; + + g_testCount = 0; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + stacksize = PTHREAD_STACK_MIN_TEST + 1; + ret = pthread_attr_setstacksize(&attr, stacksize); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newTh, &attr, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + LOS_TaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, here assert the result. + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_getstacksize(&attr, &stacksize2); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(stacksize2, PTHREAD_STACK_MIN_TEST + 1, stacksize2); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread046(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread046", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_047.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_047.c new file mode 100644 index 00000000..945df038 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_047.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(void *argument) +{ + UINT32 ret; + struct sched_param param; + int policy; + + g_testCount++; + + ret = pthread_getschedparam(g_newTh, &policy, ¶m); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ICUNIT_GOTO_EQUAL(policy, SCHED_RR, policy, EXIT); + ICUNIT_GOTO_EQUAL(param.sched_priority, 4, param.sched_priority, EXIT); // 4, here assert the result. + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + param.sched_priority = 26; // 26, set priority. + ret = pthread_setschedparam(g_newTh, SCHED_RR, ¶m); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, here assert the result. + g_testCount++; + + ret = pthread_getschedparam(g_newTh, &policy, ¶m); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ICUNIT_GOTO_EQUAL(policy, SCHED_RR, policy, EXIT); + ICUNIT_GOTO_EQUAL(param.sched_priority, 26, param.sched_priority, EXIT); // 26, here assert the result. +EXIT: + return (void *)9; // 9, here set value about the return status. +} +static UINT32 Testcase(VOID) +{ + UINT32 ret; + pthread_attr_t attr; + struct sched_param param; + int policy; + + g_testCount = 0; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_setschedpolicy(&attr, SCHED_RR); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + param.sched_priority = 4; // 4, set priority. + ret = pthread_attr_setschedparam(&attr, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&g_newTh, &attr, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_getschedparam(g_newTh, &policy, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(policy, SCHED_RR, policy); + ICUNIT_ASSERT_EQUAL(param.sched_priority, 26, param.sched_priority); // 26, here assert the result. + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + g_testCount++; + LOS_TaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, here assert the result. + + ret = pthread_join(g_newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread047(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread047", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_048.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_048.c new file mode 100644 index 00000000..c2a17716 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_048.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID PthreadOnceF01(VOID) +{ + g_testCount++; +} +static VOID *PthreadF01(void *argument) +{ + g_testCount++; + + pthread_once(&g_onceControl, PthreadOnceF01); + g_testCount++; + + return (void *)9; // 9, here set value about the return status. +} +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + UINT32 ret; + + g_testCount = 0; + g_onceControl = PTHREAD_ONCE_INIT; + + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + LOS_TaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, here assert the result. + + ret = pthread_once(&g_onceControl, PthreadOnceF01); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, here assert the result. + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread048(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread048", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_049.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_049.c new file mode 100644 index 00000000..2273f199 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_049.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void PthreadOnceF01(void) +{ + g_testCount++; +} + +static void PthreadOnceF02(void) +{ + g_testCount++; +} +static VOID *PthreadF01(void *argument) +{ + UINT32 ret; + + g_testCount++; + + ret = pthread_once(&g_onceControl, PthreadOnceF01); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + +EXIT: + return (void *)9; // 9, here set value about the return status. +} +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + UINT32 ret; + + g_testCount = 0; + g_onceControl = PTHREAD_ONCE_INIT; + + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + LOS_TaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, here assert the result. + + ret = pthread_once(&g_onceControl, PthreadOnceF02); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, here assert the result. + + ret = pthread_once(&g_onceControl, PthreadOnceF01); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, here assert the result. + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread049(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread049", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_050.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_050.c new file mode 100644 index 00000000..32983f61 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_050.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void PthreadOnceF01(void) +{ + g_testCount++; + pthread_exit((void *)8); // 8, here set value about the exit status. +} + +static void PthreadOnceF02(void) +{ + g_testCount++; +} +static VOID *PthreadF01(void *argument) +{ + UINT32 ret; + + g_testCount++; + + ret = pthread_once(&g_onceControl, PthreadOnceF01); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + +EXIT: + return (void *)9; // 9, here set value about the return status. +} +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + UINT32 ret; + UINTPTR temp; + + g_testCount = 0; + g_onceControl = PTHREAD_ONCE_INIT; + + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + LOS_TaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, here assert the result. + + ret = pthread_once(&g_onceControl, PthreadOnceF02); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, here assert the result. + + ret = pthread_join(newTh, (void *)&temp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(temp, 8, temp); // 8, here assert the result. + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread050(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread050", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_051.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_051.c new file mode 100644 index 00000000..5ca251ec --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_051.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void PthreadOnceF01(void) +{ + g_testCount++; + pthread_testcancel(); +} + +static VOID *PthreadF01(void *argument) +{ + UINT32 ret; + + g_testCount++; + + TestExtraTaskDelay(2); // 2, delay for Timing control. + + ret = pthread_once(&g_onceControl, PthreadOnceF01); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); // not reachable + +EXIT: + return (void *)9; // 9, here set value about the return status. +} +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + UINT32 ret; + UINTPTR temp; + + g_testCount = 0; + g_onceControl = PTHREAD_ONCE_INIT; + + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_cancel(newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LOS_TaskDelay(3); // 3, delay for Timing control. + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, here assert the result. + + ret = pthread_once(&g_onceControl, PthreadOnceF01); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, here assert the result. + + ret = pthread_join(newTh, (void *)&temp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(temp, (UINTPTR)PTHREAD_CANCELED, temp); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread051(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread051", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_056.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_056.c new file mode 100644 index 00000000..3dc082cc --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_056.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(void *argument) +{ + int oldstate; + UINT32 ret; + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + g_testCount++; + + TestExtraTaskDelay(2); // 2, delay for Timing control. + + ret = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ICUNIT_GOTO_EQUAL(oldstate, PTHREAD_CANCEL_ENABLE, oldstate, EXIT); + + pthread_testcancel(); + + g_testCount++; + ret = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ICUNIT_GOTO_EQUAL(oldstate, PTHREAD_CANCEL_DISABLE, oldstate, EXIT); + + pthread_testcancel(); + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); // not reachable + +EXIT: + return (void *)9; // 9, here set value about the return status. +} +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + UINT32 ret; + UINTPTR temp = 1; + + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_cancel(newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LOS_TaskDelay(4); // 4, delay for Timing control. + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, here assert the result. + + ret = pthread_join(newTh, (void *)&temp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(temp, (UINTPTR)PTHREAD_CANCELED, temp); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread056(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread056", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_057.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_057.c new file mode 100644 index 00000000..66a77cb2 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_057.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(void *argument) +{ + UINT32 ret; + int oldstate; + UINT32 i, j; + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + g_testCount++; + ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ICUNIT_GOTO_EQUAL(oldstate, PTHREAD_CANCEL_DEFERRED, oldstate, EXIT); + while (1) { + }; + g_testCount++; + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, here assert the result. +EXIT: + return (void *)9; // 9, here set value about the return status. +} +static UINT32 Testcase(VOID) +{ + pthread_t newTh, newTh2; + UINT32 ret; + UINTPTR temp = 1; + + g_testCount = 1; + + ret = pthread_create(&newTh2, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LOS_TaskDelay(1); + TestExtraTaskDelay(10); // 10, delay for Timing control. + + ret = pthread_cancel(newTh2); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newTh2, (void *)&temp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(temp, (UINTPTR)PTHREAD_CANCELED, temp); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread057(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread057", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_058.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_058.c new file mode 100644 index 00000000..0becc53d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_058.c @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(void *argument) +{ + int oldstate; + UINT32 ret; + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + g_testCount++; + + ret = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ICUNIT_GOTO_EQUAL(oldstate, PTHREAD_CANCEL_ENABLE, oldstate, EXIT); + + pthread_testcancel(); + + ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ICUNIT_GOTO_EQUAL(oldstate, PTHREAD_CANCEL_DEFERRED, oldstate, EXIT); + + g_testCount++; + ret = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ICUNIT_GOTO_EQUAL(oldstate, PTHREAD_CANCEL_DISABLE, oldstate, EXIT); + + pthread_testcancel(); + + LOS_TaskDelay(2); // 2, delay for Timing control. + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + +EXIT: + return (void *)9; // 9, here set value about the return status. +} + +static VOID *PthreadF02(void *argument) +{ + int oldstate; + UINT32 ret; + + g_testCount++; + + ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + /* asynchronous cancelled, needs more time */ + LOS_TaskDelay(3); // 3, delay for Timing control. + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + g_testCount++; + +EXIT: + return (void *)9; // 9, here set value about the return status. +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + UINT32 ret; + UINTPTR temp = 1; + + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LOS_TaskDelay(1); + + ret = pthread_cancel(newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LOS_TaskDelay(2); // 2, delay for Timing control. + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, here assert the result. + + ret = pthread_join(newTh, (void *)&temp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(temp, (UINTPTR)PTHREAD_CANCELED, temp); + +#if 1 + ret = pthread_create(&newTh, NULL, PthreadF02, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LOS_TaskDelay(2); // 2, delay for Timing control. + ret = pthread_cancel(newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, here assert the result. + + ret = pthread_join(newTh, (void *)&temp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(temp, (UINTPTR)PTHREAD_CANCELED, temp); + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, here assert the result. +#endif + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread058(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread058", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_060.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_060.c new file mode 100644 index 00000000..59cf2725 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_060.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF02(void *argument) +{ + g_testCount++; + return (void *)8; // 8, here set value about the return status. +} +static VOID *PthreadF01(void *argument) +{ + UINT32 ret; + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + g_testCount++; + + TestExtraTaskDelay(1); + + ret = pthread_create(&g_newTh, NULL, PthreadF02, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_join(g_newTh, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testCount++; + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + +EXIT: + return (void *)9; // 9, here set value about the return status. +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + UINT32 ret; + UINTPTR temp = 1; + + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_cancel(newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LOS_TaskDelay(3); // 3, delay for Timing control. + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, here assert the result. + + ret = pthread_join(newTh, (void *)&temp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(temp, (UINTPTR)PTHREAD_CANCELED, temp); + + ret = pthread_join(g_newTh, (void *)&temp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(temp, 8, temp); // 8, here assert the result. + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread060(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread060", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_066.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_066.c new file mode 100644 index 00000000..76132c12 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_066.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF02(void *argument) +{ + int oldstate; + UINT32 ret; + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + ret = pthread_cancel(g_newTh); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testCount++; + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, here assert the result. +EXIT: + return (void *)9; // 9, here set value about the return status. +} + +static VOID *PthreadF01(void *argument) +{ + int oldstate; + UINT32 ret; + pthread_attr_t attr; + pthread_t newTh; + + g_testCount++; + + ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ICUNIT_GOTO_EQUAL(oldstate, PTHREAD_CANCEL_DEFERRED, oldstate, EXIT); + + ret = pthread_attr_init(&attr); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + attr.inheritsched = PTHREAD_EXPLICIT_SCHED; + attr.schedparam.sched_priority = 8; // 8, set priority. + + ret = pthread_create(&g_newTh2, &attr, PthreadF02, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + +#ifdef LOSCFG_KERNEL_SMP + while (g_testCount < 2) { // 2, delay until g_testCount is equal to 2. + TestBusyTaskDelay(1); + } + TestExtraTaskDelay(1); +#else + g_testCount++; + + ret = pthread_join(g_newTh2, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + g_testCount++; + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, here assert the result. +#endif +EXIT: + return (void *)9; // 9, here set value about the return status. +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINTPTR temp = 1; + pthread_attr_t attr; + + g_testCount = 0; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + attr.inheritsched = PTHREAD_EXPLICIT_SCHED; + attr.schedparam.sched_priority = 10; // 10, set priority. + + ret = pthread_create(&g_newTh, &attr, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + TestExtraTaskDelay(10); // 10, delay for Timing control. + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, here assert the result. + + ret = pthread_join(g_newTh, (void *)&temp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(temp, (UINTPTR)PTHREAD_CANCELED, temp); + + ret = pthread_join(g_newTh2, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread066(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread066", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_068.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_068.c new file mode 100644 index 00000000..a71ec33b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_068.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF02(VOID *argument) +{ + UINT32 ret; + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + ret = pthread_cancel(g_newTh); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testCount++; + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, here assert the result. +EXIT: + return NULL; +} + +static VOID *PthreadF01(VOID *argument) +{ + int oldstate; + UINT32 ret; + pthread_attr_t attr; + + g_testCount++; + + ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ICUNIT_GOTO_EQUAL(oldstate, PTHREAD_CANCEL_DEFERRED, oldstate, EXIT); + + ret = pthread_attr_init(&attr); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + attr.inheritsched = PTHREAD_EXPLICIT_SCHED; + attr.schedparam.sched_priority = 8; // 8, set priority. + + ret = pthread_create(&g_newTh2, &attr, PthreadF02, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + +#ifdef LOSCFG_KERNEL_SMP + while (g_testCount < 2) { // 2, delay until g_testCount is equal to 2. + TestBusyTaskDelay(1); + } + TestBusyTaskDelay(1); +#else + g_testCount++; + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, here assert the result. +#endif +EXIT: + return NULL; +} +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINTPTR temp = 1; + g_testCount = 0; + + ret = pthread_create(&g_newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + TestExtraTaskDelay(10); // 10, delay for Timing control. + + ret = pthread_join(g_newTh, (void *)&temp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_EQUAL(temp, (UINTPTR)PTHREAD_CANCELED, temp); + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, here assert the result. + ret = pthread_join(g_newTh2, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread068(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread068", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_069.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_069.c new file mode 100644 index 00000000..457c4600 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_069.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + pthread_condattr_t condattr; + pthread_cond_t cond1; + pthread_cond_t cond2; + int rc; + + rc = pthread_condattr_init(&condattr); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_cond_init(&cond1, &condattr); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_cond_init(&cond2, NULL); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + rc = pthread_cond_destroy(&cond1); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT); + rc = pthread_cond_destroy(&cond2); + ICUNIT_GOTO_EQUAL(rc, ENOERR, rc, EXIT); + + return PTHREAD_NO_ERROR; +EXIT: + (void)pthread_cond_destroy(&cond1); + (void)pthread_cond_destroy(&cond2); +} + +VOID ItPosixPthread069(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread069", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_071.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_071.c new file mode 100644 index 00000000..96577bad --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_071.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + pthread_condattr_t condattr; + int rc; + pthread_cond_t cond1, cond2; + pthread_cond_t cond3 = PTHREAD_COND_INITIALIZER; + + /* Initialize a condition variable attribute object */ + rc = pthread_condattr_init(&condattr); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* Initialize cond1 with the default condition variable attribute */ + rc = pthread_cond_init(&cond1, &condattr); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* Initialize cond2 with NULL attributes */ + rc = pthread_cond_init(&cond2, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* Destroy the condition variable attribute object */ + rc = pthread_condattr_destroy(&condattr); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* Destroy cond1 */ + rc = pthread_cond_destroy(&cond1); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* Destroy cond2 */ + rc = pthread_cond_destroy(&cond2); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* Destroy cond3 */ + rc = pthread_cond_destroy(&cond3); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread071(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread071", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_072.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_072.c new file mode 100644 index 00000000..1de98858 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_072.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void *PthreadF01(void *tmp) +{ + int rc; + g_testCount++; + + /* acquire the mutex */ + rc = pthread_mutex_lock(&g_pthreadMutexTest1); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + g_testCount++; + /* Wait on the cond var. This will not return, as nobody signals */ + rc = pthread_cond_wait(&g_pthreadCondTest1, &g_pthreadMutexTest1); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + g_testCount++; + + rc = pthread_mutex_unlock(&g_pthreadMutexTest1); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + g_testCount++; +EXIT: + return NULL; +} +static UINT32 Testcase(VOID) +{ + pthread_t lowId; + int rc; + + g_pthreadMutexTest1 = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER; + g_pthreadCondTest1 = (pthread_cond_t)PTHREAD_COND_INITIALIZER; + g_testCount = 0; + + /* Create a new thread with default attributes */ + rc = pthread_create(&lowId, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* Let the other thread run */ + LOS_TaskDelay(2); // 2, delay for Timing control. + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, here assert the result. + + /* Try to destroy the cond var. This should return an error */ + rc = pthread_cond_destroy(&g_pthreadCondTest1); + ICUNIT_ASSERT_EQUAL(rc, EBUSY, rc); + + rc = pthread_cond_broadcast(&g_pthreadCondTest1); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + LOS_TaskDelay(2); // 2, delay for Timing control. + ICUNIT_ASSERT_EQUAL(g_testCount, 4, g_testCount); // 4, here assert the result. + + rc = pthread_cond_destroy(&g_pthreadCondTest1); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_join(lowId, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread072(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread072", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_073.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_073.c new file mode 100644 index 00000000..ba0a89ae --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_073.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + pthread_condattr_t condattr; + int rc; + +#ifdef PTHREAD_PROCESS_SHARED + int pshared; +#endif + /* Initialize a cond attributes object */ + rc = pthread_condattr_init(&condattr); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + +#ifdef PTHREAD_PROCESS_SHARED + /* If the symbol {PTHREAD_PROCESS_SHARED} is defined, the attribute + * process-shared should be provided and its default value should be + * PTHREAD_PROCESS_PRIVATE */ + rc = pthread_condattr_getpshared(&condattr, &pshared); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + ICUNIT_ASSERT_EQUAL(pshared, PTHREAD_PROCESS_PRIVATE, pshared); + +#endif + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread073(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread073", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_074.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_074.c new file mode 100644 index 00000000..a239e2d1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_074.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + pthread_condattr_t condattr; + int rc; + + /* Initialize a condition variable attributes object */ + rc = pthread_condattr_init(&condattr); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* Destroy the condition variable attributes object */ + rc = pthread_condattr_destroy(&condattr); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* Initialize the condition variable attributes object again. This shouldn't result in an error. */ + rc = pthread_condattr_init(&condattr); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread074(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread074", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_075.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_075.c new file mode 100644 index 00000000..d0727622 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_075.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + pthread_condattr_t *condattr = NULL; + int rc; + + /* Initialize a condition variable attributes object */ + rc = pthread_condattr_init(condattr); + ICUNIT_ASSERT_EQUAL(rc, EINVAL, rc); + + /* Destroy the condition variable attributes object */ + rc = pthread_condattr_destroy(condattr); + ICUNIT_ASSERT_EQUAL(rc, EINVAL, rc); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread075(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread075", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_078.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_078.c new file mode 100644 index 00000000..7f3b3893 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_078.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + pthread_condattr_t attr; + int ret; + + /* Initialize a cond attributes object */ + ret = pthread_condattr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + /* Set 'pshared' to INVALID_PSHARED_VALUE. */ + ret = pthread_condattr_setpshared(&attr, INVALID_PSHARED_VALUE); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + /* Destroy the cond attributes object */ + ret = pthread_condattr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread078(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread078", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_079.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_079.c new file mode 100644 index 00000000..c6f17f00 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_079.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + pthread_condattr_t attr; + int ret; + int pshared; + + /* Initialize a cond attributes object */ + ret = pthread_condattr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + /* Set 'pshared' to INVALID_PSHARED_VALUE. */ + ret = pthread_condattr_getpshared(&attr, &pshared); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(pshared, PTHREAD_PROCESS_PRIVATE, pshared); + + /* Destroy the cond attributes object */ + ret = pthread_condattr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread079(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread079", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_080.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_080.c new file mode 100644 index 00000000..eb65ad28 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_080.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void *PthreadF01(void *arg) +{ + int rc; + + rc = pthread_mutex_lock(&g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + g_startNum++; + + rc = pthread_cond_wait(&g_td.cond, &g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + g_wakenNum++; + + rc = pthread_mutex_unlock(&g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + +EXIT: + return NULL; +} +static UINT32 Testcase(VOID) +{ + int i, rc; + g_startNum = 0; + g_wakenNum = 0; + pthread_t thread[THREAD_NUM]; + + rc = pthread_mutex_init(&g_td.mutex, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_cond_init(&g_td.cond, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + for (i = 0; i < THREAD_NUM; i++) { + rc = pthread_create(&thread[i], NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + } + + while (g_startNum < THREAD_NUM) { + usleep(100); // 100, delay for Timing control. + } + + /* + * Acquire the mutex to make sure that all waiters are currently + * blocked on pthread_cond_wait + */ + rc = pthread_mutex_lock(&g_td.mutex); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_mutex_unlock(&g_td.mutex); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* broadcast and check if all waiters are wakened */ + + rc = pthread_cond_broadcast(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + sleep(1); + + ICUNIT_ASSERT_EQUAL(g_wakenNum, THREAD_NUM, g_wakenNum); + + /* join all secondary threads */ + for (i = 0; i < THREAD_NUM; i++) { + rc = pthread_join(thread[i], NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + } + + rc = pthread_cond_destroy(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread080(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread080", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_081.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_081.c new file mode 100644 index 00000000..70163aa3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_081.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void *PthreadF01(void *arg) +{ + int rc; + + rc = pthread_mutex_lock(&g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + g_startNum++; + + rc = pthread_cond_wait(&g_td.cond, &g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + rc = pthread_mutex_trylock(&g_td.mutex); + ICUNIT_GOTO_NOT_EQUAL(rc, 0, rc, EXIT); + + g_wakenNum++; + + rc = pthread_mutex_unlock(&g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + +EXIT: + return NULL; +} + +static UINT32 Testcase(VOID) +{ + int i, rc; + pthread_t thread[THREAD_NUM]; + + g_startNum = 0; + g_wakenNum = 0; + + rc = pthread_mutex_init(&g_td.mutex, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_cond_init(&g_td.cond, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + for (i = 0; i < THREAD_NUM; i++) { + rc = pthread_create(&thread[i], NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + } + + while (g_startNum < THREAD_NUM) { + usleep(100); // 100, delay for Timing control. + } + + /* + * Acquire the mutex to make sure that all waiters are currently + * blocked on pthread_cond_wait + */ + rc = pthread_mutex_lock(&g_td.mutex); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_mutex_unlock(&g_td.mutex); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* broadcast and check if all waiters are wakened */ + + rc = pthread_cond_broadcast(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + sleep(1); + + ICUNIT_ASSERT_EQUAL(g_wakenNum, THREAD_NUM, g_wakenNum); + + /* join all secondary threads */ + for (i = 0; i < THREAD_NUM; i++) { + rc = pthread_join(thread[i], NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + } + + rc = pthread_cond_destroy(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread081(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread081", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_082.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_082.c new file mode 100644 index 00000000..65d71060 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_082.c @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void *PthreadF01(void *arg) +{ + int rc; + struct timespec timeout; + struct timeval curtime; + + rc = pthread_mutex_lock(&g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + g_startNum++; + + rc = gettimeofday(&curtime, NULL); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + timeout.tv_sec = curtime.tv_sec + PTHREAD_TIMEOUT; + timeout.tv_nsec = curtime.tv_usec * 1000; // 1000, us transfer to ns. + + rc = pthread_cond_timedwait(&g_td.cond, &g_td.mutex, &timeout); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + rc = pthread_mutex_trylock(&g_td.mutex); + ICUNIT_GOTO_NOT_EQUAL(rc, 0, rc, EXIT); + + g_wakenNum++; + + rc = pthread_mutex_unlock(&g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + +EXIT: + return NULL; +} +static UINT32 Testcase(VOID) +{ + int i, rc; + pthread_t thread[THREAD_NUM]; + + g_startNum = 0; + g_wakenNum = 0; + + rc = pthread_mutex_init(&g_td.mutex, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_cond_init(&g_td.cond, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + for (i = 0; i < THREAD_NUM; i++) { + rc = pthread_create(&thread[i], NULL, PthreadF01, NULL); // + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + } + + while (g_startNum < THREAD_NUM) { + usleep(100); // 100, delay for Timing control. + } + + /* + * Acquire the mutex to make sure that all waiters are currently + * blocked on pthread_cond_wait + */ + rc = pthread_mutex_lock(&g_td.mutex); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_mutex_unlock(&g_td.mutex); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* broadcast and check if all waiters are wakened */ + + ICUNIT_ASSERT_EQUAL(g_wakenNum, 0, g_wakenNum); + + rc = pthread_cond_broadcast(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + sleep(1); + + ICUNIT_ASSERT_EQUAL(g_wakenNum, THREAD_NUM, g_wakenNum); + + /* join all secondary threads */ + for (i = 0; i < THREAD_NUM; i++) { + rc = pthread_join(thread[i], NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + } + + rc = pthread_cond_destroy(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread082(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread082", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_083.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_083.c new file mode 100644 index 00000000..32aacfb7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_083.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void *PthreadF01(void *arg) +{ + int rc; + + rc = pthread_mutex_lock(&g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + g_startNum++; + + rc = pthread_cond_wait(&g_td.cond, &g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + g_wakenNum++; + + rc = pthread_mutex_unlock(&g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + +EXIT: + return NULL; +} +static UINT32 Testcase(VOID) +{ + int i, rc; + pthread_t thread[THREAD_NUM]; + + g_startNum = 0; + g_wakenNum = 0; + + rc = pthread_mutex_init(&g_td.mutex, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_cond_init(&g_td.cond, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + for (i = 0; i < THREAD_NUM; i++) { + rc = pthread_create(&thread[i], NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + } + + while (g_startNum < THREAD_NUM) { + usleep(100); // 100, delay for Timing control. + } + + /* + * Acquire the mutex to make sure that all waiters are currently + * blocked on pthread_cond_wait + */ + rc = pthread_mutex_lock(&g_td.mutex); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_mutex_unlock(&g_td.mutex); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* broadcast and check if all waiters are wakened */ + + ICUNIT_ASSERT_EQUAL(g_wakenNum, 0, g_wakenNum); + + rc = pthread_cond_signal(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + sleep(1); + + ICUNIT_ASSERT_EQUAL(g_wakenNum, 1, g_wakenNum); + + rc = pthread_cond_signal(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_cond_signal(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_cond_signal(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + sleep(1); + + ICUNIT_ASSERT_EQUAL(g_wakenNum, THREAD_NUM, g_wakenNum); + + /* join all secondary threads */ + for (i = 0; i < THREAD_NUM; i++) { + rc = pthread_join(thread[i], NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + } + + rc = pthread_cond_destroy(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread083(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread083", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_084.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_084.c new file mode 100644 index 00000000..b749f8eb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_084.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void *PthreadF01(void *arg) +{ + int rc; + + rc = pthread_mutex_lock(&g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + g_startNum++; + + rc = pthread_cond_wait(&g_td.cond, &g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + rc = pthread_mutex_trylock(&g_td.mutex); + ICUNIT_GOTO_NOT_EQUAL(rc, 0, rc, EXIT); + + g_wakenNum++; + + rc = pthread_mutex_unlock(&g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + +EXIT: + return NULL; +} +static UINT32 Testcase(VOID) +{ + int i, rc; + pthread_t thread[THREAD_NUM]; + + g_startNum = 0; + g_wakenNum = 0; + + rc = pthread_mutex_init(&g_td.mutex, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_cond_init(&g_td.cond, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + for (i = 0; i < THREAD_NUM; i++) { + rc = pthread_create(&thread[i], NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + } + + while (g_startNum < THREAD_NUM) { + usleep(100); // 100, delay for Timing control. + } + + /* + * Acquire the mutex to make sure that all waiters are currently + * blocked on pthread_cond_wait + */ + rc = pthread_mutex_lock(&g_td.mutex); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_mutex_unlock(&g_td.mutex); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* broadcast and check if all waiters are wakened */ + + rc = pthread_cond_signal(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + sleep(1); + + ICUNIT_ASSERT_EQUAL(g_wakenNum, 1, g_wakenNum); + + rc = pthread_cond_signal(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_cond_signal(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_cond_signal(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + sleep(1); + + ICUNIT_ASSERT_EQUAL(g_wakenNum, THREAD_NUM, g_wakenNum); + + /* join all secondary threads */ + for (i = 0; i < THREAD_NUM; i++) { + rc = pthread_join(thread[i], NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + } + + rc = pthread_cond_destroy(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread084(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread084", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_085.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_085.c new file mode 100644 index 00000000..f55e50ff --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_085.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void *PthreadF01(void *arg) +{ + int rc; + + rc = pthread_mutex_lock(&g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + g_t1Start = 1; /* let main thread continue */ + + rc = pthread_cond_wait(&g_td.cond, &g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + ICUNIT_GOTO_NOT_EQUAL(g_signaled, 0, g_signaled, EXIT); + + rc = pthread_mutex_unlock(&g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + g_t1Start = 2; // 2, init. +EXIT: + return NULL; +} +static UINT32 Testcase(VOID) +{ + struct sigaction act; + int rc; + pthread_t thread1; + + g_t1Start = 0; + + rc = pthread_mutex_init(&g_td.mutex, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_cond_init(&g_td.cond, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_create(&thread1, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + while (!g_t1Start) { /* wait for thread1 started */ + usleep(100); // 100, delay for Timing control. + } + + /* acquire the mutex released by pthread_cond_wait() within thread 1 */ + rc = pthread_mutex_lock(&g_td.mutex); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_mutex_unlock(&g_td.mutex); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + sleep(1); + + fprintf(stderr, "Time to wake up thread1 by signaling a condition\n"); + g_signaled = 1; + rc = pthread_cond_signal(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_join(thread1, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + ICUNIT_ASSERT_EQUAL(g_t1Start, 2, g_t1Start); // 2, here assert the result. + g_signaled = 0; + + rc = pthread_cond_destroy(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread085(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread085", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_087.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_087.c new file mode 100644 index 00000000..bda1e4e0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_087.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void *PthreadF01(void *arg) +{ + int rc; + struct timespec timeout; + struct timeval curtime; + + rc = pthread_mutex_lock(&g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + g_t1Start = 1; /* let main thread continue */ + + timeout.tv_sec = PTHREAD_TIMEOUT; + timeout.tv_nsec = 0; + + rc = pthread_cond_timedwait(&g_td.cond, &g_td.mutex, &timeout); + ICUNIT_GOTO_EQUAL(rc, ETIMEDOUT, rc, EXIT); + + rc = pthread_mutex_trylock(&g_td.mutex); + ICUNIT_GOTO_NOT_EQUAL(rc, 0, rc, EXIT); + ICUNIT_GOTO_EQUAL(g_signaled, 1, g_signaled, EXIT); + + rc = pthread_mutex_unlock(&g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); +EXIT: + pthread_exit((void *)5); // 5, here set value of the exit status. +} + +static UINT32 Testcase(VOID) +{ + struct sigaction act; + int rc; + pthread_t thread1; + void *thRet = NULL; + + g_t1Start = 0; + + rc = pthread_mutex_init(&g_td.mutex, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_cond_init(&g_td.cond, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_create(&thread1, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + while (!g_t1Start) { /* wait for thread1 started */ + usleep(100); // 100, delay for Timing control. + } + + /* acquire the mutex released by pthread_cond_wait() within thread 1 */ + rc = pthread_mutex_lock(&g_td.mutex); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_mutex_unlock(&g_td.mutex); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + sleep(1); + g_signaled = 1; + rc = pthread_join(thread1, &thRet); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + ICUNIT_ASSERT_EQUAL((long)(intptr_t)thRet, 5, (long)(intptr_t)thRet); // 5, here assert the result. + g_signaled = 0; + + rc = pthread_cond_destroy(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread087(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread087", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_088.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_088.c new file mode 100644 index 00000000..8e6a9c61 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_088.c @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void PthreadSignalHandlerF01(int sig) +{ + int rc; + + rc = pthread_cond_signal(&g_pthreadCondTest1); + ICUNIT_ASSERT_EQUAL_VOID(rc, 0, rc); +} + +/* Utility function to find difference between two time values */ +static float PthreadTimeF01(struct timespec t2, struct timespec t1) +{ + float diff = t2.tv_sec - t1.tv_sec; + diff += (t2.tv_nsec - t1.tv_nsec) / 1000000000.0; // 1000000000.0, ns to s. + return diff; +} + +static void *PthreadF01(void *tmp) +{ + struct sched_param param; + int policy; + int rc; + + param.sched_priority = HIGH_PRIORITY; + + rc = pthread_setschedparam(pthread_self(), SCHED_RR, ¶m); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + rc = pthread_getschedparam(pthread_self(), &policy, ¶m); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + ICUNIT_GOTO_EQUAL(policy, SCHED_RR, policy, EXIT); + ICUNIT_GOTO_EQUAL(param.sched_priority, HIGH_PRIORITY, param.sched_priority, EXIT); + + /* acquire the mutex */ + rc = pthread_mutex_lock(&g_pthreadMutexTest1); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + /* Block, to be woken up by the signal handler */ + rc = pthread_cond_wait(&g_pthreadCondTest1, &g_pthreadMutexTest1); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + /* This variable is unprotected because the scheduling removes + * the contention + */ + if (g_lowDone != 1) + g_wokenUp = 1; + + rc = pthread_mutex_unlock(&g_pthreadMutexTest1); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); +EXIT: + return NULL; +} + +static void *PthreadF02(void *tmp) +{ + struct timespec startTime, currentTime; + struct sched_param param; + int policy; + int rc; + + param.sched_priority = LOW_PRIORITY; + + rc = pthread_setschedparam(pthread_self(), SCHED_RR, ¶m); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + rc = pthread_getschedparam(pthread_self(), &policy, ¶m); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + ICUNIT_GOTO_EQUAL(policy, SCHED_RR, policy, EXIT); + ICUNIT_GOTO_EQUAL(param.sched_priority, LOW_PRIORITY, param.sched_priority, EXIT); + + PthreadSignalHandlerF01(SIGALRM); + + /* grab the start time and busy loop for 5 seconds */ + clock_gettime(CLOCK_REALTIME, &startTime); + while (1) { + clock_gettime(CLOCK_REALTIME, ¤tTime); + if (PthreadTimeF01(currentTime, startTime) > RUNTIME) { + break; + } + } + g_lowDone = 1; +EXIT: + return NULL; +} +static UINT32 Testcase(VOID) +{ + pthread_t highId, lowId; + pthread_attr_t highAttr, lowAttr; + struct sched_param param; + int rc; + + g_pthreadMutexTest1 = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER; + g_pthreadCondTest1 = (pthread_cond_t)PTHREAD_COND_INITIALIZER; + /* Create the higher priority thread */ + rc = pthread_attr_init(&highAttr); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_attr_setschedpolicy(&highAttr, SCHED_RR); // + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + highAttr.inheritsched = PTHREAD_EXPLICIT_SCHED; + + param.sched_priority = HIGH_PRIORITY; + rc = pthread_attr_setschedparam(&highAttr, ¶m); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_create(&highId, &highAttr, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* Create the low priority thread */ + rc = pthread_attr_init(&lowAttr); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_attr_setschedpolicy(&lowAttr, SCHED_RR); // + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + lowAttr.inheritsched = PTHREAD_EXPLICIT_SCHED; + + param.sched_priority = LOW_PRIORITY; + rc = pthread_attr_setschedparam(&lowAttr, ¶m); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_create(&lowId, &lowAttr, PthreadF02, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* Wait for the threads to exit */ + rc = pthread_join(highId, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_join(lowId, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_cond_destroy(&g_pthreadCondTest1); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* Check the result */ + ICUNIT_ASSERT_EQUAL(g_wokenUp, 1, g_wokenUp); + ICUNIT_ASSERT_EQUAL(g_lowDone, 1, g_lowDone); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread088(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread088", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_089.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_089.c new file mode 100644 index 00000000..3fa8a48c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_089.c @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void PthreadSignalHandlerF01(int sig) +{ + int rc; + rc = pthread_cond_broadcast(&g_pthreadCondTest1); + ICUNIT_ASSERT_EQUAL_VOID(rc, 0, rc); +} + +/* Utility function to find difference between two time values */ +static float PthreadTimeF01(struct timespec t2, struct timespec t1) +{ + float diff = t2.tv_sec - t1.tv_sec; + diff += (t2.tv_nsec - t1.tv_nsec) / 1000000000.0; // 1000000000.0, ns to s. + return diff; +} + +static void *PthreadF01(void *tmp) +{ + struct sched_param param; + int policy; + int rc; + + param.sched_priority = HIGH_PRIORITY; + + rc = pthread_setschedparam(pthread_self(), SCHED_RR, ¶m); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + rc = pthread_getschedparam(pthread_self(), &policy, ¶m); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + ICUNIT_GOTO_EQUAL(policy, SCHED_RR, policy, EXIT); + ICUNIT_GOTO_EQUAL(param.sched_priority, HIGH_PRIORITY, param.sched_priority, EXIT); + + /* acquire the mutex */ + rc = pthread_mutex_lock(&g_pthreadMutexTest1); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + /* Block, to be woken up by the signal handler */ + rc = pthread_cond_wait(&g_pthreadCondTest1, &g_pthreadMutexTest1); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + /* This variable is unprotected because the scheduling removes + * the contention + */ + if (g_lowDone != 1) + g_wokenUp = 1; + + rc = pthread_mutex_unlock(&g_pthreadMutexTest1); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); +EXIT: + return NULL; +} + +static void *PthreadF02(void *tmp) +{ + struct timespec startTime, currentTime; + struct sched_param param; + int policy; + int rc; + + ICUNIT_GOTO_EQUAL(g_wokenUp, -1, g_wokenUp, EXIT); + + param.sched_priority = LOW_PRIORITY; + + rc = pthread_setschedparam(pthread_self(), SCHED_RR, ¶m); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + rc = pthread_getschedparam(pthread_self(), &policy, ¶m); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + ICUNIT_GOTO_EQUAL(policy, SCHED_RR, policy, EXIT); + ICUNIT_GOTO_EQUAL(param.sched_priority, LOW_PRIORITY, param.sched_priority, EXIT); + + PthreadSignalHandlerF01(SIGALRM); + + /* grab the start time and busy loop for 5 seconds */ + clock_gettime(CLOCK_REALTIME, &startTime); + while (1) { + clock_gettime(CLOCK_REALTIME, ¤tTime); + if (PthreadTimeF01(currentTime, startTime) > RUNTIME) { + break; + } + } + g_lowDone = 1; +EXIT: + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t highId, lowId; + pthread_attr_t highAttr, lowAttr; + struct sched_param param; + int rc; + + g_wokenUp = -1; + g_lowDone = -1; + + g_pthreadMutexTest1 = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER; + g_pthreadCondTest1 = (pthread_cond_t)PTHREAD_COND_INITIALIZER; + /* Create the higher priority thread */ + rc = pthread_attr_init(&highAttr); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_attr_setschedpolicy(&highAttr, SCHED_RR); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + highAttr.inheritsched = PTHREAD_EXPLICIT_SCHED; + + param.sched_priority = HIGH_PRIORITY; + rc = pthread_attr_setschedparam(&highAttr, ¶m); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_create(&highId, &highAttr, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* Create the low priority thread */ + rc = pthread_attr_init(&lowAttr); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_attr_setschedpolicy(&lowAttr, SCHED_RR); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + param.sched_priority = LOW_PRIORITY; + rc = pthread_attr_setschedparam(&lowAttr, ¶m); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_create(&lowId, &lowAttr, PthreadF02, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* Wait for the threads to exit */ + rc = pthread_join(highId, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_join(lowId, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_cond_destroy(&g_pthreadCondTest1); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* Check the result */ + ICUNIT_ASSERT_EQUAL(g_wokenUp, 1, g_wokenUp); + ICUNIT_ASSERT_EQUAL(g_lowDone, 1, g_lowDone); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread089(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread089", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_092.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_092.c new file mode 100644 index 00000000..6002f9be --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_092.c @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF02(void *argument) +{ + int oldstate; + UINT32 ret; + int i; + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, here assert the result. + g_testCount++; + + ret = pthread_cancel(g_newTh); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, here assert the result. + g_testCount++; +EXIT: + return (void *)9; // 9, here set value about the return status. +} + +static VOID *PthreadF01(void *argument) +{ + int oldstate; + UINT32 ret; + pthread_attr_t attr; + + TestExtraTaskDelay(1); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + g_testCount++; + ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ICUNIT_GOTO_EQUAL(oldstate, PTHREAD_CANCEL_DEFERRED, oldstate, EXIT); + + ret = pthread_attr_init(&attr); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + attr.inheritsched = PTHREAD_EXPLICIT_SCHED; + attr.schedparam.sched_priority = 8; // 8, set priority. + + ret = pthread_create(&g_newTh2, &attr, PthreadF02, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + /* cannot preempt on smp */ + TestExtraTaskDelay(10); // 10, delay for Timing control. + + ICUNIT_GOTO_EQUAL(g_testCount, -1, g_testCount, EXIT); +EXIT: + return (void *)9; // 9, here set value about the return status. +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINTPTR wtemp = 1; + + int i; + g_testCount = 0; + + ret = pthread_create(&g_newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 0, g_testCount); + g_testCount++; + + ret = pthread_join(g_newTh, (void *)&wtemp); + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, here assert the result. + g_testCount++; + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(wtemp, (UINTPTR)PTHREAD_CANCELED, wtemp); + + ret = pthread_join(g_newTh2, NULL); + + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); // 5, here assert the result. + g_testCount++; + +EXIT: + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread092(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread092", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_095.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_095.c new file mode 100644 index 00000000..b40b2698 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_095.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static int g_testCnt; + +static VOID *PthreadF02(void *argument) +{ + int oldstate; + UINT32 ret; + int i; + + ICUNIT_GOTO_EQUAL(g_testCnt, 2, g_testCnt, EXIT); // 2, here assert the result. + g_testCnt++; + + ret = pthread_cancel(g_newTh); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + LOS_TaskDelay(10); // 10, delay for Timing control. + + ICUNIT_GOTO_EQUAL(g_testCnt, 5, g_testCnt, EXIT); // 5, here assert the result. + g_testCnt++; +EXIT: + return (void *)9; // 9, here set value about the return status. +} + +static VOID *PthreadF01(void *argument) +{ + int oldstate; + UINT32 ret; + pthread_attr_t attr; + + TestExtraTaskDelay(1); + ICUNIT_GOTO_EQUAL(g_testCnt, 1, g_testCnt, EXIT); + g_testCnt++; + ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ICUNIT_GOTO_EQUAL(oldstate, PTHREAD_CANCEL_DEFERRED, oldstate, EXIT); + + ret = pthread_attr_init(&attr); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + attr.inheritsched = PTHREAD_EXPLICIT_SCHED; + attr.schedparam.sched_priority = 26; // 26, set priority. + + ret = pthread_create(&g_newTh2, &attr, PthreadF02, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + LOS_TaskDelay(LOS_MS2Tick(1000)); // 1000, delay for Timing control. + + ICUNIT_GOTO_EQUAL(g_testCnt, -1, g_testCnt, EXIT); + g_testCnt++; + +EXIT: + return (void *)9; // 9, here set value about the return status. +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINTPTR wtemp = 1; + + int i; + g_testCnt = 0; + + ret = pthread_create(&g_newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_EQUAL(g_testCnt, 0, g_testCnt); + g_testCnt++; + + ret = pthread_join(g_newTh, (void *)&wtemp); + + ICUNIT_GOTO_EQUAL(g_testCnt, 3, g_testCnt, EXIT); // 3, here assert the result. + g_testCnt++; + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(wtemp, (UINTPTR)PTHREAD_CANCELED, wtemp); + + ICUNIT_GOTO_EQUAL(g_testCnt, 4, g_testCnt, EXIT); // 4, here assert the result. + g_testCnt++; + + ret = pthread_join(g_newTh2, NULL); + + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_GOTO_EQUAL(g_testCnt, 6, g_testCnt, EXIT); // 6, here assert the result. + g_testCnt++; + +EXIT: + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread095(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread095", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_098.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_098.c new file mode 100644 index 00000000..aa079c07 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_098.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(void *argument) +{ + _pthread_data *self = NULL; + g_testCount++; + LOS_TaskDelay(2); // 2, delay for Timing control. + + pthread_testcancel(); + g_testCount++; + return (void *)9; // 9, here set value about the return status. +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + UINT32 ret; + pthread_attr_t attr; + UINTPTR temp = 1; + _pthread_data *f = NULL; + _pthread_data *f1 = NULL; + + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + LOS_TaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + f = pthread_get_data(newTh); + ICUNIT_ASSERT_NOT_EQUAL(f, NULL, f); + + f->id += 1; + f1 = pthread_get_data(newTh); + ICUNIT_ASSERT_EQUAL(f1, NULL, f1); + + f->id -= 1; + ret = pthread_cancel(newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newTh, (void *)&temp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(temp, (UINTPTR)PTHREAD_CANCELED, temp); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread098(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread098", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_101.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_101.c new file mode 100644 index 00000000..0d04ba17 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_101.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(void *argument) +{ + UINT32 ret; + int oldstate; + UINT32 i, j; + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + g_testCount++; + ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ICUNIT_GOTO_EQUAL(oldstate, PTHREAD_CANCEL_DEFERRED, oldstate, EXIT); + LOS_TaskDelay(4); // 4, delay for Timing control. + +EXIT: + return (void *)9; // 9, here set value about the return status. +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh, newTh2; + UINT32 ret; + pthread_attr_t attr; + + pthread_attr_init(&attr); + attr.detachstate = PTHREAD_CREATE_DETACHED; + + g_testCount = 1; + + ret = pthread_create(&newTh2, &attr, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LOS_TaskDelay(2); // 2, delay for Timing control. + + ret = pthread_cancel(newTh2); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread101(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread101", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_102.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_102.c new file mode 100644 index 00000000..d6e18744 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_102.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void PthreadOnceF01(VOID) +{ + g_testCount++; +} + +static VOID HwiF01(int irq, void *dev) +{ + UINT32 ret; + struct sched_param param; + TEST_HwiClear(HWI_NUM_TEST); + g_testCount += 1; + + ret = pthread_once(&g_onceControl, PthreadOnceF01); + ICUNIT_ASSERT_EQUAL_VOID(ret, EINTR, ret); + ICUNIT_ASSERT_EQUAL_VOID(g_testCount, 2, g_testCount); // 2, here assert the result. + + g_testCount += 1; + + return; +} + +static VOID *PthreadF01(void *argument) +{ + UINT32 ret; + g_testCount++; + +EXIT: + return (void *)9; // 9, here set value about the return status. +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + UINT32 ret; + + g_testCount = 0; + g_onceControl = PTHREAD_ONCE_INIT; + + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + LOS_TaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_GOTO_EQUAL(ret, PTHREAD_NO_ERROR, ret, EXIT); + + TestHwiTrigger(HWI_NUM_TEST); + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, here assert the result. + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + TEST_HwiDelete(HWI_NUM_TEST); + + return PTHREAD_NO_ERROR; +EXIT: + return LOS_NOK; +} + +VOID ItPosixPthread102(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread102", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_103.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_103.c new file mode 100644 index 00000000..88aa0bc8 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_103.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(void *argument) +{ + g_testCount++; + pthread_exit((void *)8); // 8, here set value about the exit status. + + return argument; +} + +static VOID HwiF01(int irq, void *dev) +{ + UINT32 ret; + int policy; + struct sched_param param = { 31 }; + struct sched_param param2 = { 2 }; + TEST_HwiClear(HWI_NUM_TEST); + g_testCount += 1; + + ret = pthread_setschedparam(g_testNewTh, SCHED_RR, ¶m); + ICUNIT_ASSERT_EQUAL_VOID(ret, EINTR, ret); + + g_testCount += 1; + ret = pthread_getschedparam(g_testNewTh, &policy, ¶m2); + ICUNIT_ASSERT_EQUAL_VOID(ret, EINTR, ret); + g_testCount += 1; + + return; +} +static UINT32 Testcase(VOID) +{ + UINT32 ret; + unsigned long flags; + UINTPTR temp; + g_testCount = 0; + + ret = pthread_create(&g_testNewTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + LOS_TaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_GOTO_EQUAL(ret, PTHREAD_NO_ERROR, ret, EXIT); + + TestHwiTrigger(HWI_NUM_TEST); + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, here assert the result. + + ret = pthread_join(g_testNewTh, (void *)&temp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(temp, 8, temp); // 8, here assert the result. + + TEST_HwiDelete(HWI_NUM_TEST); + + return PTHREAD_NO_ERROR; + +EXIT: + return LOS_NOK; +} + +VOID ItPosixPthread103(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread103", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_107.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_107.c new file mode 100644 index 00000000..932984ee --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_107.c @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#define LOOP_NUM 2 + +static VOID *PthreadF01(void *t) +{ + int rc; + + rc = pthread_mutex_lock(&g_pthreadMutexTest1); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + g_testCount++; + LOS_TaskDelay(1); + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, here assert the result. + g_testCount++; + + rc = pthread_cond_wait(&g_pthreadCondTest1, &g_pthreadMutexTest1); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); // 5, here assert the result. + rc = pthread_mutex_unlock(&g_pthreadMutexTest1); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + +EXIT: + return NULL; +} + +static VOID *PthreadF02(void *t) +{ + int i; + int rc; + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + g_testCount++; + rc = pthread_mutex_lock(&g_pthreadMutexTest1); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, here assert the result. + g_testCount++; + rc = pthread_cond_signal(&g_pthreadCondTest1); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, here assert the result. + g_testCount++; + + rc = pthread_mutex_unlock(&g_pthreadMutexTest1); /* Increase latency for thread polling mutex */ + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + LOS_TaskDelay(2); // 2, delay for Timing control. + +EXIT: + pthread_exit(NULL); +} +static UINT32 Testcase(VOID) +{ + int i; + long t1 = 1; + long t2 = 2; // 2, init + int rc; + pthread_t threads[3]; // 3, need 3 pthread for test. + pthread_attr_t attr; /* Initializes mutex and conditional variable objects */ + + g_testCount = 0; + pthread_mutex_init(&g_pthreadMutexTest1, NULL); + /* When creating thread, it is set to connectable state, which is easy to transplant */ + pthread_cond_init(&g_pthreadCondTest1, NULL); + pthread_attr_init(&attr); + + rc = pthread_create(&threads[0], &attr, PthreadF01, (void *)t1); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_create(&threads[1], &attr, PthreadF02, (void *)t2); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* Wait for all threads to complete */ + for (i = 0; i < LOOP_NUM; i++) { + rc = pthread_join(threads[i], NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + } + + /* Clear and exit */ + rc = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_mutex_destroy(&g_pthreadMutexTest1); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + rc = pthread_cond_destroy(&g_pthreadCondTest1); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread107(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread107", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_108.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_108.c new file mode 100644 index 00000000..27205330 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_108.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + pthread_condattr_t condattr; + pthread_cond_t cond1; + pthread_cond_t cond2; + int pshared; + int rc; + + rc = pthread_condattr_getpshared(NULL, &pshared); + ICUNIT_ASSERT_EQUAL(rc, EINVAL, rc); + + rc = pthread_condattr_getpshared(&condattr, NULL); + ICUNIT_ASSERT_EQUAL(rc, EINVAL, rc); + + rc = pthread_condattr_getpshared(NULL, NULL); + ICUNIT_ASSERT_EQUAL(rc, EINVAL, rc); + + rc = pthread_condattr_getpshared(&condattr, &pshared); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + ICUNIT_ASSERT_EQUAL(pshared, PTHREAD_PROCESS_PRIVATE, pshared); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread108(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread108", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_110.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_110.c new file mode 100644 index 00000000..45fa878d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_110.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + int rc; + + rc = pthread_cond_init(NULL, NULL); + ICUNIT_ASSERT_EQUAL(rc, EINVAL, rc); + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread110(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread110", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_112.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_112.c new file mode 100644 index 00000000..0475dd85 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_112.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + int rc; + + rc = pthread_cond_signal(NULL); + ICUNIT_ASSERT_EQUAL(rc, EINVAL, rc); + + rc = pthread_cond_broadcast(NULL); + ICUNIT_ASSERT_EQUAL(rc, EINVAL, rc); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread112(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread112", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_116.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_116.c new file mode 100644 index 00000000..3683c91c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_116.c @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static pthread_t g_th1; +static pthread_mutex_t g_mutx = PTHREAD_MUTEX_INITIALIZER; +static int g_cnt = 0; +#define PRI 9 + +static VOID *PthreadF01(VOID *arg) +{ + struct sched_param schParam; + UINT32 priority; + UINT32 sched = SCHED_RR; + int ret; + + g_cnt++; + ICUNIT_GOTO_EQUAL(g_cnt, 1, g_cnt, EXIT); + pthread_mutex_lock(&g_mutx); + LOS_TaskDelay(10); // 10, delay for Timing control. + + pthread_getschedparam(g_th1, &sched, &schParam); + ICUNIT_GOTO_EQUAL(schParam.sched_priority, PRI, schParam.sched_priority, EXIT); + + priority = schParam.sched_priority - 4; // 4, Set reasonable priority + schParam.sched_priority = priority; + ret = pthread_setschedparam(g_th1, sched, &schParam); + g_cnt++; + ICUNIT_GOTO_EQUAL(g_cnt, 3, g_cnt, EXIT); // 3, here assert the result. + pthread_mutex_unlock(&g_mutx); + pthread_getschedparam(g_th1, &sched, &schParam); + ICUNIT_GOTO_EQUAL(schParam.sched_priority, priority, schParam.sched_priority, EXIT); +EXIT: + return NULL; +} + +static VOID *PthreadF02(VOID *arg) +{ + g_cnt++; + ICUNIT_GOTO_EQUAL(g_cnt, 2, g_cnt, EXIT); // 2, here assert the result. + pthread_mutex_lock(&g_mutx); + + g_cnt++; + ICUNIT_GOTO_EQUAL(g_cnt, 4, g_cnt, EXIT); // 4, here assert the result. + pthread_mutex_unlock(&g_mutx); + + return NULL; +EXIT: + pthread_mutex_unlock(&g_mutx); + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + UINT32 ret; + pthread_attr_t attr; + struct sched_param schParam; + UINT32 priority; + UINT32 sched = SCHED_RR; + g_cnt = 0; + + pthread_attr_init(&attr); + attr.schedparam.sched_priority = PRI; + attr.inheritsched = PTHREAD_EXPLICIT_SCHED; + attr.detachstate = PTHREAD_CREATE_DETACHED; + + ret = pthread_create(&g_th1, &attr, PthreadF01, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + pthread_attr_init(&attr); + attr.schedparam.sched_priority = PRI - 1; + attr.inheritsched = PTHREAD_EXPLICIT_SCHED; + + ret = pthread_create(&newTh, &attr, PthreadF02, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + pthread_getschedparam(g_th1, &sched, &schParam); + + ret = pthread_join(newTh, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_cnt, 4, g_cnt, EXIT); // 4, here assert the result. + + return PTHREAD_NO_ERROR; + +EXIT: + pthread_detach(g_th1); + pthread_detach(newTh); + return LOS_NOK; +} + +VOID ItPosixPthread116(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread116", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_121.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_121.c new file mode 100644 index 00000000..d81b3422 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_121.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(VOID *arg) +{ + pthread_exit(0); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + INT32 ret; + + /* Create a new thread. The default attribute should be that + * it is joinable. */ + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_GOTO_EQUAL(ret, PTHREAD_NO_ERROR, ret, EXIT); + + /* The new thread should be able to be joined. */ + ret = pthread_join(newTh, NULL); + ICUNIT_GOTO_EQUAL(ret, PTHREAD_NO_ERROR, ret, EXIT); + + /* The new thread should be able to be detached. */ + ret = pthread_detach(newTh); + ICUNIT_GOTO_EQUAL(ret, ESRCH, ret, EXIT); + + return PTHREAD_NO_ERROR; +EXIT: + pthread_join(newTh, NULL); + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread121(VOID) +{ + TEST_ADD_CASE("ItPosixPthread121", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_123.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_123.c new file mode 100644 index 00000000..7d6c1e53 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_123.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(VOID *argument) +{ + g_pthreadTestTh = pthread_self(); + pthread_exit(0); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + INT32 ret; + + /* Create a new thread */ + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_GOTO_EQUAL(ret, PTHREAD_NO_ERROR, ret, EXIT); + + /* Wait for the thread function to return to make sure we got + * the thread ID value from pthread_self(). */ + ret = pthread_join(newTh, NULL); + ICUNIT_GOTO_EQUAL(ret, PTHREAD_NO_ERROR, ret, EXIT); + + /* If the value of pthread_self() and the return value from + * pthread_create() is equal, then the test passes. */ + ret = pthread_equal(newTh, g_pthreadTestTh); + ICUNIT_GOTO_NOT_EQUAL(ret, PTHREAD_NO_ERROR, ret, EXIT); + return PTHREAD_NO_ERROR; +EXIT: + pthread_detach(newTh); + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread123(VOID) +{ + TEST_ADD_CASE("ItPosixPthread123", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_124.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_124.c new file mode 100644 index 00000000..f59b562a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_124.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static int g_testCnt; + +static VOID *PthreadF01(VOID *num) +{ + intptr_t i = (intptr_t)num; + PRINTK("Passed argument for thread: %d, g_testCnt = %d\n", (int)i, g_testCnt); + ICUNIT_TRACK_EQUAL(g_testCnt, i, g_testCnt); + g_testCnt++; + + pthread_exit(0); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + long i; + INT32 ret; + + g_testCnt = 1; + + for (i = 1; i < PTHREAD_THREADS_NUM + 1; i++) { + ret = pthread_create(&newTh, NULL, PthreadF01, (void *)i); + ICUNIT_GOTO_EQUAL(ret, PTHREAD_NO_ERROR, ret, EXIT); + + /* Wait for thread to end execution */ + ret = pthread_join(newTh, NULL); + ICUNIT_GOTO_EQUAL(ret, PTHREAD_NO_ERROR, ret, EXIT); + } + + return PTHREAD_NO_ERROR; +EXIT: + pthread_detach(newTh); + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread124(VOID) +{ + TEST_ADD_CASE("ItPosixPthread124", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_125.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_125.c new file mode 100644 index 00000000..a218a403 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_125.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(VOID *num) +{ + int *i, j; + + i = (int *)num; + + for (j = 0; j < PTHREAD_THREADS_NUM; j++) { + dprintf("Passed argument %d for thread\n", i[j]); + ICUNIT_TRACK_EQUAL(i[j], j + 1, i[j]); + } + + pthread_exit(0); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + INT32 i[PTHREAD_THREADS_NUM], j, ret; + + for (j = 0; j < PTHREAD_THREADS_NUM; j++) + i[j] = j + 1; + + ret = pthread_create(&newTh, NULL, PthreadF01, (void *)&i); + ICUNIT_GOTO_EQUAL(ret, PTHREAD_NO_ERROR, ret, EXIT); + + /* Wait for thread to end execution */ + ret = pthread_join(newTh, NULL); + ICUNIT_GOTO_EQUAL(ret, PTHREAD_NO_ERROR, ret, EXIT); + + return PTHREAD_NO_ERROR; +EXIT: + pthread_detach(newTh); + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread125(VOID) +{ + TEST_ADD_CASE("ItPosixPthread125", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_127.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_127.c new file mode 100644 index 00000000..13ab83ae --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_127.c @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +typedef struct { + sigset_t mask; + sigset_t pending; +} testdata_t; + +/* Thread function; which will check the signal mask and pending signals */ +static VOID *PthreadF01(VOID *arg) +{ + INT32 ret; + testdata_t *td = (testdata_t *)arg; + + /* Obtain the signal mask of this thread. */ + ret = pthread_sigmask(SIG_SETMASK, NULL, &(td->mask)); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + /* Obtain the pending signals of this thread. It should be empty. */ + ret = sigpending(&(td->pending)); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + /* Signal we're done (especially in case of a detached thread) */ + do { + ret = sem_post(&g_scenarii[g_testCount].sem); + } while ((ret == -1) && (errno == EINTR)); + ICUNIT_TRACK_NOT_EQUAL(ret, -1, ret); + + return arg; +} + +static UINT32 Testcase(VOID) +{ + INT32 ret; + pthread_t child; + testdata_t tdParent, tdThread; + + g_testCount = 0; + +#if PTHREAD_SIGNAL_SUPPORT == 1 + + /* Initialize thread attribute objects */ + ScenarInit(); + + /* Initialize the signal state */ + ret = sigemptyset(&(tdParent.mask)); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = sigemptyset(&(tdParent.pending)); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + /* Add SIGCONT, SIGUSR1 and SIGUSR2 to the set of blocked signals */ + ret = sigaddset(&(tdParent.mask), SIGUSR1); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = sigaddset(&(tdParent.mask), SIGUSR2); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + /* Block those signals. */ + ret = pthread_sigmask(SIG_SETMASK, &(tdParent.mask), NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + /* Raise those signals so they are now pending. */ + ret = raise(SIGUSR1); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = raise(SIGUSR2); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + /* Do the testing for each thread */ + for (g_testCount = 0; g_testCount < NSCENAR; g_testCount++) { + /* (re)initialize thread signal sets */ + ret = sigemptyset(&(tdThread.mask)); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = sigemptyset(&(tdThread.pending)); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_create(&child, &g_scenarii[g_testCount].ta, PthreadF01, &tdThread); + switch (g_scenarii[g_testCount].result) { + case 0: /* Operation was expected to succeed */ + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + break; + + case 1: /* Operation was expected to fail */ + ICUNIT_ASSERT_NOT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + break; + + case 2: /* 2, We did not know the expected result */ + default: + break; + } + if (ret == 0) { /* The new thread is running */ + if (g_scenarii[g_testCount].detached == 0) { + ret = pthread_join(child, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + } else { + /* Just wait for the thread to terminate */ + do { + ret = sem_wait(&g_scenarii[g_testCount].sem); + } while ((ret == -1) && (errno == EINTR)); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + } + + /* The thread has terminated its work, so we can now control */ + ret = sigismember(&(tdThread.mask), SIGUSR1); + ICUNIT_ASSERT_EQUAL(ret, 1, ret); + + ret = sigismember(&(tdThread.mask), SIGUSR2); + ICUNIT_ASSERT_EQUAL(ret, 1, ret); + + ret = sigismember(&(tdThread.pending), SIGUSR1); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = sigismember(&(tdThread.pending), SIGUSR2); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + } + } + + ScenarFini(); + +#endif + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread127(VOID) +{ + TEST_ADD_CASE("ItPosixPthread127", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_128.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_128.c new file mode 100644 index 00000000..c73a24a4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_128.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(VOID *argument) +{ + clockid_t cpuclock; + INT32 ret; + struct timespec ts = { + .tv_sec = 1, + .tv_nsec = 1 + }; + + cpuclock = CLOCK_MONOTONIC; + + ret = clock_gettime(cpuclock, &ts); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + pthread_exit(0); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + INT32 ret; + + ret = sysconf(_SC_THREAD_CPUTIME); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_IS_ERROR, ret); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno); + + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, errno); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, errno); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread128(VOID) +{ + TEST_ADD_CASE("ItPosixPthread128", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_129.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_129.c new file mode 100644 index 00000000..e9a0befd --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_129.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(VOID *argument) +{ + pthread_exit(0); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + INT32 ret; + + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_GOTO_EQUAL(ret, PTHREAD_NO_ERROR, errno, EXIT); + + ret = pthread_join(newTh, NULL); + ICUNIT_GOTO_EQUAL(ret, PTHREAD_NO_ERROR, errno, EXIT); + + return PTHREAD_NO_ERROR; + +EXIT: + pthread_join(newTh, NULL); + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread129(VOID) +{ + TEST_ADD_CASE("ItPosixPthread129", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_132.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_132.c new file mode 100644 index 00000000..14a76158 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_132.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(VOID *argument) +{ + g_newTh = pthread_self(); + + pthread_exit(0); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh1; + INT32 ret; + + ret = pthread_create(&newTh1, NULL, PthreadF01, NULL); + ICUNIT_GOTO_EQUAL(ret, PTHREAD_NO_ERROR, ret, EXIT); + + ret = pthread_join(newTh1, NULL); + ICUNIT_GOTO_EQUAL(ret, PTHREAD_NO_ERROR, ret, EXIT); + + ret = pthread_equal(newTh1, g_newTh); + ICUNIT_GOTO_EQUAL(ret, 1, errno, EXIT); + + ret = pthread_equal(newTh1, TestPthreadSelf()); + ICUNIT_GOTO_EQUAL(ret, PTHREAD_NO_ERROR, ret, EXIT); + + return PTHREAD_NO_ERROR; +EXIT: + pthread_detach(g_newTh); + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread132(VOID) +{ + TEST_ADD_CASE("ItPosixPthread132", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_133.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_133.c new file mode 100644 index 00000000..5f7aa3ff --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_133.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(VOID *argument) +{ + pthread_exit(0); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + INT32 ret; + + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_equal(newTh, newTh); + ICUNIT_ASSERT_EQUAL(ret, 1, ret); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread133(VOID) +{ + TEST_ADD_CASE("ItPosixPthread133", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_134.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_134.c new file mode 100644 index 00000000..676892e9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_134.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(VOID *argument) +{ + pthread_exit(0); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh1, newTh2; + INT32 ret; + + ret = pthread_create(&newTh1, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_create(&newTh2, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_equal(newTh1, newTh2); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(newTh1, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newTh2, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread134(VOID) +{ + TEST_ADD_CASE("ItPosixPthread134", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_136.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_136.c new file mode 100644 index 00000000..1299ba7d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_136.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#define LOOP_NUM 4 + +static VOID *PthreadF01(VOID *argument) +{ + INT32 i; + + dprintf("Wait for 3 seconds for thread to finish execution:\n"); + for (i = 1; i < LOOP_NUM; i++) { + dprintf("Waited (%d) second\n", i); + sleep(1); + } + + g_testCount = 1; + + pthread_exit(0); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + INT32 ret; + + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread136(VOID) +{ + TEST_ADD_CASE("ItPosixPthread136", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_138.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_138.c new file mode 100644 index 00000000..9ea39142 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_138.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(VOID *argument) +{ + g_pthreadSem = PTHREAD_INMAIN_TEST; + pthread_exit(PTHREAD_EXIT_VALUE); + return NULL; +} + + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + VOID *valuePtr; + INT32 ret; + + valuePtr = 0; + g_pthreadSem = PTHREAD_INTHREAD_TEST; + + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + /* Make sure the thread was created before we join it. */ + while (g_pthreadSem == PTHREAD_INTHREAD_TEST) { + sleep(1); + } + + ret = pthread_join(newTh, &valuePtr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + /* + * Check to make sure that 'value_ptr' that was passed to + * pthread_join() and the pthread_exit() return code that + * was used in the thread function are the same. + */ + ICUNIT_ASSERT_EQUAL(valuePtr, PTHREAD_EXIT_VALUE, errno); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread138(VOID) +{ + TEST_ADD_CASE("ItPosixPthread138", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_141.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_141.c new file mode 100644 index 00000000..698b7482 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_141.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(VOID *argument) +{ + pthread_exit(0); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + INT32 ret; + + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread141(VOID) +{ + TEST_ADD_CASE("ItPosixPthread141", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_142.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_142.c new file mode 100644 index 00000000..c0dc0540 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_142.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(VOID *argument) +{ + pthread_exit(0); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + INT32 ret; + + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, ESRCH, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread142(VOID) +{ + TEST_ADD_CASE("ItPosixPthread142", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_144.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_144.c new file mode 100644 index 00000000..b6bcf63a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_144.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(VOID *argument) +{ + INT32 ret; + + ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + LOS_TaskDelay(3); // 3, delay for Timing control. + + pthread_exit(0); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_attr_t newAttr; + pthread_t newTh; + _pthread_data *pthreadData = NULL; + INT32 ret; + + ret = pthread_attr_init(&newAttr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_setdetachstate(&newAttr, PTHREAD_CREATE_JOINABLE); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_create(&newTh, &newAttr, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_detach(newTh); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + pthreadData = pthread_get_data(newTh); + ICUNIT_ASSERT_EQUAL(pthreadData->state, PTHREAD_STATE_DETACHED, pthreadData->state); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = LOS_TaskDelay(2); // 2, delay for Timing control. + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_cancel(newTh); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread144(VOID) +{ + TEST_ADD_CASE("ItPosixPthread144", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_150.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_150.c new file mode 100644 index 00000000..35347c59 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_150.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(VOID *argument) +{ + pthread_exit(0); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + _pthread_data *pthreadData; + INT32 ret; + + pthreadData = pthread_get_data(newTh); + ICUNIT_ASSERT_EQUAL(pthreadData, NULL, pthreadData); + + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + pthreadData = pthread_get_data(newTh); + ICUNIT_ASSERT_EQUAL(pthreadData->state, PTHREAD_STATE_RUNNING, pthreadData->state); + + /* Wait 'till the thread returns. + * The thread could have ended by the time we try to join, so + * don't worry about it, just so long as other errors don't + * occur. The point is to make sure the thread has ended execution. */ + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + pthreadData = pthread_get_data(newTh); + ICUNIT_ASSERT_EQUAL(pthreadData, NULL, pthreadData); + + /* Detach the non-existent thread. */ + ret = pthread_detach(newTh); + ICUNIT_ASSERT_EQUAL(ret, ESRCH, ret); + + pthreadData = pthread_get_data(newTh); + ICUNIT_ASSERT_EQUAL(pthreadData, NULL, pthreadData); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, ESRCH, ret); + + /* Cleanup and cancel the thread */ + ret = pthread_cancel(newTh); + ICUNIT_ASSERT_EQUAL(ret, ESRCH, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread150(VOID) +{ + TEST_ADD_CASE("ItPosixPthread150", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_152.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_152.c new file mode 100644 index 00000000..f61f3054 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_152.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + pthread_attr_t newAttr; + INT32 detachState, ret; + + /* Initialize attribute */ + ret = pthread_attr_init(&newAttr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + /* The test passes if the attribute object has a detachstate of + * PTHREAD_CREATE_JOINABLE, which is the default value for this + * attribute. */ + ret = pthread_attr_getdetachstate(&newAttr, &detachState); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(detachState, PTHREAD_CREATE_JOINABLE, detachState); + + ret = pthread_attr_destroy(&newAttr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return LOS_OK; +} + +VOID ItPosixPthread152(VOID) +{ + TEST_ADD_CASE("ItPosixPthread152", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_154.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_154.c new file mode 100644 index 00000000..2d113acc --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_154.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(VOID *argument) +{ + pthread_exit(NULL); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newThreads[PTHREAD_THREADS_NUM]; + pthread_attr_t newAttr; + INT32 i, ret; + + ret = pthread_attr_init(&newAttr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + for (i = 0; i < PTHREAD_THREADS_NUM; i++) { + ret = pthread_create(&newThreads[i], &newAttr, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + } + + for (i = 0; i < PTHREAD_THREADS_NUM; i++) { + ret = pthread_join(newThreads[i], NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + } + + for (i = 0; i < PTHREAD_THREADS_NUM; i++) { + } + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread154(VOID) +{ + TEST_ADD_CASE("ItPosixPthread154", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_166.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_166.c new file mode 100644 index 00000000..56d11b03 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_166.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(VOID *argument) +{ + pthread_exit(0); + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + pthread_attr_t newAttr; + _pthread_data *pthreadData = NULL; + INT32 ret; + + /* Initialize attribute */ + ret = pthread_attr_init(&newAttr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + /* Destroy attribute */ + ret = pthread_attr_destroy(&newAttr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + /* Creating a thread, passing to it the destroyed attribute, should + * result in an error value of EINVAL (invalid 'attr' value). */ + ret = pthread_create(&newTh, &newAttr, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + sleep(1); + + /* The new_th is delelted in Here */ + pthreadData = pthread_get_data(newTh); + ICUNIT_ASSERT_EQUAL(pthreadData, NULL, pthreadData); + + /* Cleanup and cancel the thread */ + ret = pthread_cancel(newTh); + ICUNIT_ASSERT_EQUAL(ret, ESRCH, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread166(VOID) +{ + TEST_ADD_CASE("ItPosixPthread166", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_167.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_167.c new file mode 100644 index 00000000..58706dab --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_167.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + pthread_attr_t newAttr; + INT32 ret; + + ret = pthread_attr_init(&newAttr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_destroy(&newAttr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_init(&newAttr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_destroy(&newAttr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread167(VOID) +{ + TEST_ADD_CASE("ItPosixPthread167", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_173.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_173.c new file mode 100644 index 00000000..413004bd --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_173.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + pthread_attr_t newAttr; + INT32 detachState, ret; + + /* Initialize attribute */ + ret = pthread_attr_init(&newAttr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + /* The test passes if pthread_attr_getdetachstate gets the attribute + * of PTHREAD_CREATE_JOINABLE from the attribute object. */ + ret = pthread_attr_getdetachstate(&newAttr, &detachState); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(detachState, PTHREAD_CREATE_JOINABLE, detachState); + + ret = pthread_attr_destroy(&newAttr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread173(VOID) +{ + TEST_ADD_CASE("ItPosixPthread173", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_175.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_175.c new file mode 100644 index 00000000..0e719cf9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_175.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(VOID *argument) +{ + pthread_exit(PTHREAD_EXIT_VALUE); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + pthread_attr_t attr; + INT32 cscope; + INT32 ret; + + g_pthreadScopeValue = PTHREAD_SCOPE_PROCESS; + + /* Initialize attr */ + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, errno); + + ret = pthread_attr_setscope(&attr, g_pthreadScopeValue); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, errno); + + ret = pthread_create(&newTh, &attr, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, errno); + + ret = pthread_attr_getscope(&attr, &cscope); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, errno); + ICUNIT_ASSERT_EQUAL(cscope, g_pthreadScopeValue, cscope); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, errno); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, errno); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread175(VOID) +{ + TEST_ADD_CASE("ItPosixPthread175", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_176.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_176.c new file mode 100644 index 00000000..1ab0316d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_176.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + INT32 ret; + pthread_attr_t attr; + + g_pthreadScopeValue = 999; // 999, init + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_setscope(&attr, g_pthreadScopeValue); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, errno); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread176(VOID) +{ + TEST_ADD_CASE("ItPosixPthread176", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_177.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_177.c new file mode 100644 index 00000000..b004ff73 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_177.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + INT32 ret; + INT32 rc2; + pthread_attr_t attr; + INT32 scope; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_getscope(&attr, &scope); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(scope, PTHREAD_SCOPE_PROCESS, scope); + + g_pthreadScopeValue = PTHREAD_SCOPE_PROCESS; + ret = pthread_attr_setscope(&attr, g_pthreadScopeValue); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_getscope(&attr, &scope); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(scope, PTHREAD_SCOPE_PROCESS, scope); + + g_pthreadScopeValue = PTHREAD_SCOPE_SYSTEM; + ret = pthread_attr_setscope(&attr, g_pthreadScopeValue); + ICUNIT_ASSERT_EQUAL(ret, ENOTSUP, ret); + + ret = pthread_attr_getscope(&attr, &scope); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(scope, PTHREAD_SCOPE_PROCESS, scope); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread177(VOID) +{ + TEST_ADD_CASE("ItPosixPthread177", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_182.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_182.c new file mode 100644 index 00000000..ccf6a8d2 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_182.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(void *tmp) +{ + struct sched_param param; + INT32 policy; + INT32 ret; + + TestExtraTaskDelay(2); // 2, delay for Timing control. + LOS_TaskDelay(1); + + ret = pthread_getschedparam(pthread_self(), &policy, ¶m); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + if (policy == g_pthreadSchedPolicy) { + g_testCount = 1; + } + if (param.sched_priority == PTHREAD_PRIORITY_TEST) { + g_testCount--; + } + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_attr_t attr; + pthread_t threadId; + struct sched_param param; + INT32 ret; + + g_pthreadSchedPolicy = SCHED_RR; + g_pthreadSchedInherit = PTHREAD_INHERIT_SCHED; + g_testCount = 0; + + param.sched_priority = PTHREAD_PRIORITY_TEST; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_setinheritsched(&attr, g_pthreadSchedInherit); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_create(&threadId, &attr, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_setschedparam(threadId, g_pthreadSchedPolicy, ¶m); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(threadId, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 0, g_testCount); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread182(VOID) +{ + TEST_ADD_CASE("ItPosixPthread182", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_185.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_185.c new file mode 100644 index 00000000..f7bc7966 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_185.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + INT32 ret; + INT32 inheritsched; + pthread_attr_t attr; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_pthreadSchedInherit = PTHREAD_INHERIT_SCHED; + ret = pthread_attr_setinheritsched(&attr, g_pthreadSchedInherit); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_getinheritsched(&attr, &inheritsched); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(inheritsched, g_pthreadSchedInherit, inheritsched); + + g_pthreadSchedInherit = PTHREAD_EXPLICIT_SCHED; + ret = pthread_attr_setinheritsched(&attr, g_pthreadSchedInherit); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_getinheritsched(&attr, &inheritsched); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(inheritsched, g_pthreadSchedInherit, inheritsched); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread185(VOID) +{ + TEST_ADD_CASE("ItPosixPthread185", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_186.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_186.c new file mode 100644 index 00000000..3d0bcad5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_186.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(VOID *data) +{ + pthread_t self; + struct sched_param schedparam; + struct params *paramTest = data; + INT32 policy; + INT32 ret; + + self = pthread_self(); + ret = pthread_getschedparam(self, &policy, &schedparam); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_TRACK_EQUAL(policy, paramTest->policy, policy); + ICUNIT_TRACK_EQUAL(paramTest->priority, PRIORITY_OTHER, paramTest->priority); + dprintf("sched_priority=:%d\n", schedparam.sched_priority); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + INT32 ret; + struct params paramTest; + pthread_t thread; + pthread_attr_t attr; + VOID *status = NULL; + _pthread_data *pthreadData = NULL; + struct sched_param schedparam; + + paramTest.policy = SCHED_OTHER; + paramTest.priority = PRIORITY_OTHER; + paramTest.policy_label = "SCHED_OTHER"; + paramTest.status = PTHREAD_NO_ERROR; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_pthreadSchedPolicy = SCHED_OTHER; + ret = pthread_attr_setschedpolicy(&attr, g_pthreadSchedPolicy); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + g_pthreadSchedInherit = PTHREAD_EXPLICIT_SCHED; + ret = pthread_attr_setinheritsched(&attr, g_pthreadSchedInherit); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + schedparam.sched_priority = paramTest.priority; + ret = pthread_attr_setschedparam(&attr, &schedparam); + ICUNIT_ASSERT_EQUAL(ret, ENOTSUP, ret); + + attr.schedparam.sched_priority = paramTest.priority; + ret = pthread_create(&thread, &attr, PthreadF01, ¶mTest); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + pthreadData = pthread_get_data(thread); + ICUNIT_ASSERT_EQUAL(pthreadData, NULL, pthreadData); + + ret = pthread_join(thread, &status); + ICUNIT_ASSERT_EQUAL(ret, ESRCH, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread186(VOID) +{ + TEST_ADD_CASE("ItPosixPthread186", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_187.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_187.c new file mode 100644 index 00000000..e5449e59 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_187.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(VOID *data) +{ + pthread_t self; + struct sched_param schedparam; + struct params *paramTest = data; + INT32 policy; + INT32 ret; + + self = pthread_self(); + ret = pthread_getschedparam(self, &policy, &schedparam); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ICUNIT_TRACK_EQUAL(paramTest->priority, PRIORITY_FIFO, paramTest->priority); + ICUNIT_TRACK_EQUAL(schedparam.sched_priority, paramTest->priority, schedparam.sched_priority); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + INT32 ret; + struct params paramTest; + pthread_t thread; + pthread_attr_t attr; + VOID *status = NULL; + _pthread_data *pthreadData = NULL; + struct sched_param schedparam; + + paramTest.policy = SCHED_FIFO; + paramTest.priority = PRIORITY_FIFO; + paramTest.policy_label = "SCHED_FIFO"; + paramTest.status = LOS_NOK; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_pthreadSchedPolicy = SCHED_FIFO; + ret = pthread_attr_setschedpolicy(&attr, g_pthreadSchedPolicy); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + g_pthreadSchedInherit = PTHREAD_EXPLICIT_SCHED; + ret = pthread_attr_setinheritsched(&attr, g_pthreadSchedInherit); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + schedparam.sched_priority = paramTest.priority; + ret = pthread_attr_setschedparam(&attr, &schedparam); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_create(&thread, &attr, PthreadF01, ¶mTest); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + pthreadData = pthread_get_data(thread); + ICUNIT_ASSERT_EQUAL(pthreadData->state, PTHREAD_STATE_RUNNING, pthreadData->state); + ICUNIT_ASSERT_EQUAL(pthreadData->attr.schedparam.sched_priority, paramTest.priority, + pthreadData->attr.schedparam.sched_priority); + + ret = pthread_join(thread, &status); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread187(VOID) +{ + TEST_ADD_CASE("ItPosixPthread187", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_188.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_188.c new file mode 100644 index 00000000..8b99b257 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_188.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(VOID *data) +{ + pthread_t self; + struct sched_param schedparam; + struct params *paramTest = data; + INT32 policy; + INT32 ret; + + self = pthread_self(); + ret = pthread_getschedparam(self, &policy, &schedparam); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_TRACK_EQUAL(policy, paramTest->policy, policy); + ICUNIT_TRACK_EQUAL(paramTest->priority, PRIORITY_RR, paramTest->priority); + ICUNIT_TRACK_EQUAL(schedparam.sched_priority, paramTest->priority, schedparam.sched_priority); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + INT32 ret; + struct params paramTest; + pthread_t thread; + pthread_attr_t attr; + VOID *status = NULL; + _pthread_data *pthreadData = NULL; + struct sched_param schedparam; + + paramTest.policy = SCHED_RR; + paramTest.priority = PRIORITY_RR; + paramTest.policy_label = "SCHED_RR"; + paramTest.status = PTHREAD_NO_ERROR; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_pthreadSchedPolicy = SCHED_OTHER; + ret = pthread_attr_setschedpolicy(&attr, g_pthreadSchedPolicy); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + g_pthreadSchedPolicy = SCHED_RR; + ret = pthread_attr_setschedpolicy(&attr, g_pthreadSchedPolicy); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_pthreadSchedInherit = PTHREAD_EXPLICIT_SCHED; + ret = pthread_attr_setinheritsched(&attr, g_pthreadSchedInherit); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + schedparam.sched_priority = paramTest.priority; + if (paramTest.priority != PRIORITY_OTHER) { + ret = pthread_attr_setschedparam(&attr, &schedparam); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + } + + ret = pthread_create(&thread, &attr, PthreadF01, ¶mTest); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + pthreadData = pthread_get_data(thread); + ICUNIT_ASSERT_EQUAL(pthreadData->state, PTHREAD_STATE_RUNNING, pthreadData->state); + + ret = pthread_join(thread, &status); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread188(VOID) +{ + TEST_ADD_CASE("ItPosixPthread188", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_193.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_193.c new file mode 100644 index 00000000..a37307e6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_193.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(VOID *argument) +{ + TestExtraTaskDelay(1); + LOS_TaskDelay(1); + + g_testCount = 1; + + pthread_exit(PTHREAD_NO_ERROR); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t thread; + pthread_attr_t attr; + INT32 ret; + struct sched_param param; + INT32 priority; + _pthread_data *pthreadData = NULL; + + g_testCount = 0; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_pthreadSchedPolicy = SCHED_FIFO; + ret = pthread_attr_setschedpolicy(&attr, g_pthreadSchedPolicy); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + priority = sched_get_priority_max(g_pthreadSchedPolicy); + ICUNIT_ASSERT_EQUAL(priority, -1, priority); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno); + + param.sched_priority = priority; + ret = pthread_attr_setschedparam(&attr, ¶m); + ICUNIT_ASSERT_EQUAL(ret, ENOTSUP, ret); + + ret = pthread_create(&thread, &attr, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + pthreadData = pthread_get_data(thread); + ICUNIT_ASSERT_EQUAL(pthreadData->state, PTHREAD_STATE_RUNNING, pthreadData->state); + ICUNIT_ASSERT_EQUAL(pthreadData->attr.schedparam.sched_priority, TASK_PRIO_TEST, + pthreadData->attr.schedparam.sched_priority); + + ret = pthread_join(thread, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread193(VOID) +{ + TEST_ADD_CASE("ItPosixPthread193", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_194.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_194.c new file mode 100644 index 00000000..fce9ab86 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_194.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(VOID *argument) +{ + g_testCount = 1; + + pthread_exit(PTHREAD_NO_ERROR); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t thread; + pthread_attr_t attr; + INT32 ret; + struct sched_param param; + INT32 priority; + _pthread_data *pthreadData = NULL; + + g_testCount = 0; + + /* use delay to reset timelsice to prevent created task get + to run before expected */ + LOS_TaskDelay(1); + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_pthreadSchedPolicy = SCHED_RR; + ret = pthread_attr_setschedpolicy(&attr, g_pthreadSchedPolicy); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + priority = sched_get_priority_max(g_pthreadSchedPolicy); + ICUNIT_ASSERT_NOT_EQUAL(priority, -1, priority); + + param.sched_priority = priority; + ret = pthread_attr_setschedparam(&attr, ¶m); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_create(&thread, &attr, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + pthreadData = pthread_get_data(thread); + ICUNIT_ASSERT_EQUAL(pthreadData->state, PTHREAD_STATE_RUNNING, pthreadData->state); + ICUNIT_ASSERT_EQUAL(pthreadData->attr.schedparam.sched_priority, TASK_PRIO_TEST, + pthreadData->attr.schedparam.sched_priority); + + ret = pthread_join(thread, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread194(VOID) +{ + TEST_ADD_CASE("ItPosixPthread194", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_197.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_197.c new file mode 100644 index 00000000..1fcc4b1d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_197.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + pthread_attr_t attr; + INT32 ret; + struct sched_param param; + INT32 priority; + INT32 offset = 0xff; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_pthreadSchedPolicy = SCHED_FIFO; + ret = pthread_attr_setschedpolicy(&attr, g_pthreadSchedPolicy); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + priority = sched_get_priority_max(g_pthreadSchedPolicy); + ICUNIT_ASSERT_EQUAL(priority, PTHREAD_IS_ERROR, priority); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno); + + param.sched_priority = priority + offset; + ret = pthread_attr_setschedparam(&attr, ¶m); + ICUNIT_ASSERT_EQUAL(ret, ENOTSUP, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread197(VOID) +{ + TEST_ADD_CASE("ItPosixPthread197", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_198.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_198.c new file mode 100644 index 00000000..cf48513a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_198.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + pthread_attr_t attr; + INT32 ret; + struct sched_param param; + INT32 priority; + INT32 offset = 0xff; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_pthreadSchedPolicy = SCHED_RR; + ret = pthread_attr_setschedpolicy(&attr, g_pthreadSchedPolicy); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + priority = sched_get_priority_min(g_pthreadSchedPolicy); + ICUNIT_ASSERT_EQUAL(priority, PTHREAD_NO_ERROR, priority); + + param.sched_priority = priority + offset; + ret = pthread_attr_setschedparam(&attr, ¶m); + ICUNIT_ASSERT_EQUAL(ret, ENOTSUP, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread198(VOID) +{ + TEST_ADD_CASE("ItPosixPthread198", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_200.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_200.c new file mode 100644 index 00000000..3c8c9439 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_200.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(VOID *arg) +{ + pthread_exit(PTHREAD_NO_ERROR); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + pthread_attr_t attr; + size_t stackSize = PTHREAD_STACK_MIN; + size_t ssize; + INT32 ret; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_getstacksize(&attr, &ssize); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(ssize, PTHREAD_DEFAULT_STACK_SIZE, ssize); + + ret = pthread_attr_setstacksize(&attr, stackSize); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_getstacksize(&attr, &ssize); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(ssize, stackSize, ssize); + + ret = pthread_create(&newTh, &attr, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread200(VOID) +{ + TEST_ADD_CASE("ItPosixPthread200", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_204.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_204.c new file mode 100644 index 00000000..a011386e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_204.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(VOID *argument) +{ + struct sched_param sparam; + INT32 priority, policy; + INT32 ret; + + g_pthreadSchedPolicy = SCHED_RR; + +#ifdef LOSCFG_KERNEL_TICKLESS + priority = sched_get_priority_max(g_pthreadSchedPolicy) - 1; +#else + priority = sched_get_priority_max(g_pthreadSchedPolicy); +#endif + + sparam.sched_priority = priority; + + ret = pthread_setschedparam(pthread_self(), g_pthreadSchedPolicy, &sparam); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_getschedparam(pthread_self(), &policy, &sparam); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_TRACK_EQUAL(policy, g_pthreadSchedPolicy, policy); + ICUNIT_TRACK_EQUAL(sparam.sched_priority, priority, sparam.sched_priority); + + pthread_exit(0); + + return NULL; +} + + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + INT32 ret; + + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread204(VOID) +{ + TEST_ADD_CASE("ItPosixPthread204", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_205.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_205.c new file mode 100644 index 00000000..b1b4c431 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_205.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(VOID *arg) +{ + INT32 ret; + INT32 policy; + INT32 priority; + struct sched_param schedparam; + + LOS_TaskDelay(2); // 2, delay for Timing control. + +#ifdef LOSCFG_KERNEL_TICKLESS + priority = sched_get_priority_max(SCHED_RR) - 1; +#else + priority = sched_get_priority_max(SCHED_RR); +#endif + + ret = pthread_getschedparam(pthread_self(), &policy, &schedparam); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_TRACK_EQUAL(policy, SCHED_RR, policy); + ICUNIT_TRACK_EQUAL(schedparam.sched_priority, priority, schedparam.sched_priority); + + return NULL; +} + +static VOID *PthreadF02(VOID *arg) +{ + INT32 ret; + struct sched_param schedparam; +#ifdef LOSCFG_KERNEL_TICKLESS + schedparam.sched_priority = sched_get_priority_max(SCHED_RR) - 1; + ICUNIT_TRACK_EQUAL(schedparam.sched_priority, OS_TASK_PRIORITY_LOWEST - 1, schedparam.sched_priority); +#else + schedparam.sched_priority = sched_get_priority_max(SCHED_RR); + ICUNIT_TRACK_EQUAL(schedparam.sched_priority, OS_TASK_PRIORITY_LOWEST, schedparam.sched_priority); +#endif + + ret = pthread_setschedparam(*(pthread_t *)arg, SCHED_RR, &schedparam); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + INT32 ret; + pthread_t newTh1, newTh2; + pthread_attr_t attr; + INT32 bar; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_pthreadSchedInherit = PTHREAD_EXPLICIT_SCHED; + ret = pthread_attr_setinheritsched(&attr, g_pthreadSchedInherit); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + LOS_TaskLock(); + + ret = pthread_create(&newTh1, &attr, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_create(&newTh2, &attr, PthreadF02, &newTh1); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + LOS_TaskUnlock(); + + ret = pthread_join(newTh2, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(newTh1, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread205(VOID) +{ + TEST_ADD_CASE("ItPosixPthread205", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_206.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_206.c new file mode 100644 index 00000000..2e6b2fe5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_206.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void *PthreadF01(void *arg) +{ + INT32 ret; + INT32 policy; + struct sched_param schedparam; + struct sched_param schedparam1; + + g_pthreadSchedPolicy = SCHED_RR; + + schedparam.sched_priority = sched_get_priority_min(g_pthreadSchedPolicy); + + ret = pthread_setschedparam(pthread_self(), g_pthreadSchedPolicy, &schedparam); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + policy = SCHED_RR; + ret = pthread_getschedparam(pthread_self(), &policy, &schedparam1); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_TRACK_EQUAL(policy, g_pthreadSchedPolicy, policy); + ICUNIT_TRACK_EQUAL(schedparam1.sched_priority, schedparam.sched_priority, schedparam1.sched_priority); + + /* Now set the priority to an invalid value. */ + schedparam.sched_priority++; + + ret = pthread_setschedparam(pthread_self(), SCHED_RR, &schedparam); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + policy = SCHED_RR; + ret = pthread_getschedparam(pthread_self(), &policy, &schedparam1); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_TRACK_EQUAL(policy, g_pthreadSchedPolicy, policy); + ICUNIT_TRACK_EQUAL(schedparam1.sched_priority, schedparam.sched_priority, schedparam1.sched_priority); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + INT32 ret; + pthread_attr_t attr; + pthread_t newTh1; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_pthreadSchedInherit = PTHREAD_EXPLICIT_SCHED; + ret = pthread_attr_setinheritsched(&attr, g_pthreadSchedInherit); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_create(&newTh1, &attr, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(newTh1, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread206(VOID) +{ + TEST_ADD_CASE("ItPosixPthread206", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_208.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_208.c new file mode 100644 index 00000000..1f3ade88 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_208.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(VOID *argument) +{ + struct sched_param sparam; + INT32 policy; + INT32 ret; + + ret = pthread_getschedparam(pthread_self(), &policy, &sparam); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_TRACK_EQUAL(policy, g_pthreadSchedPolicy, policy); + ICUNIT_TRACK_EQUAL(sparam.sched_priority, TASK_PRIO_TEST, sparam.sched_priority); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + INT32 ret; + + g_pthreadSchedPolicy = SCHED_RR; + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread208(VOID) +{ + TEST_ADD_CASE("ItPosixPthread208", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_209.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_209.c new file mode 100644 index 00000000..45ed7642 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_209.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(VOID *argument) +{ + struct sched_param sparam; + INT32 policy, priority; + INT32 ret; + + g_pthreadSchedPolicy = SCHED_RR; + +#ifdef LOSCFG_KERNEL_TICKLESS + priority = sched_get_priority_max(g_pthreadSchedPolicy) - 1; +#else + priority = sched_get_priority_max(g_pthreadSchedPolicy); +#endif + + sparam.sched_priority = priority; + + ret = pthread_setschedparam(pthread_self(), g_pthreadSchedPolicy, &sparam); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_getschedparam(pthread_self(), &policy, &sparam); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_TRACK_EQUAL(policy, g_pthreadSchedPolicy, policy); + +#ifdef LOSCFG_KERNEL_TICKLESS + ICUNIT_TRACK_EQUAL(sparam.sched_priority, OS_TASK_PRIORITY_LOWEST - 1, sparam.sched_priority); +#else + ICUNIT_TRACK_EQUAL(sparam.sched_priority, OS_TASK_PRIORITY_LOWEST, sparam.sched_priority); +#endif + + return NULL; +} + + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + pthread_attr_t attr; + INT32 ret; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_pthreadSchedInherit = PTHREAD_EXPLICIT_SCHED; + ret = pthread_attr_setinheritsched(&attr, g_pthreadSchedInherit); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_create(&newTh, &attr, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread209(VOID) +{ + TEST_ADD_CASE("ItPosixPthread209", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_211.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_211.c new file mode 100644 index 00000000..c15264ed --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_211.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +/* The init function that pthread_once calls */ +static VOID PthreadF01(VOID) +{ + g_testCount++; +} + +static UINT32 Testcase(VOID) +{ + INT32 ret; + + pthread_once_t onceControl = PTHREAD_ONCE_INIT; + + g_testCount = 0; + + ret = pthread_once(&onceControl, PthreadF01); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(onceControl, 1, onceControl); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = pthread_once(&onceControl, PthreadF01); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(onceControl, 1, onceControl); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread211(VOID) +{ + TEST_ADD_CASE("ItPosixPthread211", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_213.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_213.c new file mode 100644 index 00000000..cf1a104f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_213.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID PthreadF02(VOID) +{ + INT32 ret; + ret = pthread_mutex_lock(&g_pthreadMutexTest1); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_testCount++; + + ret = pthread_mutex_unlock(&g_pthreadMutexTest1); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return; +} + +static VOID *PthreadF01(VOID *arg) +{ + INT32 ret; + + ret = pthread_once(arg, PthreadF02); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return NULL; +} + + +static UINT32 Testcase(VOID) +{ + INT32 ret, i; + + pthread_once_t myctl[PTHREAD_THREADS_NUM] = {PTHREAD_ONCE_INIT, }; + + pthread_t th[PTHREAD_THREADS_NUM]; + + g_pthreadMutexTest1 = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER; + + g_testCount = 0; + + for (i = 0; i < PTHREAD_THREADS_NUM; i++) { + ret = pthread_create(&th[i], NULL, PthreadF01, &myctl[i]); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + } + + for (i = 0; i < PTHREAD_THREADS_NUM; i++) { + ret = pthread_join(th[i], NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + } + + ret = pthread_mutex_lock(&g_pthreadMutexTest1); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); // 3, here assert the result. + + ret = pthread_mutex_unlock(&g_pthreadMutexTest1); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread213(VOID) +{ + TEST_ADD_CASE("ItPosixPthread213", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_214.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_214.c new file mode 100644 index 00000000..7ffdae7c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_214.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID PthreadF01(VOID) +{ + sleep(1); + + g_testCount = 1; + + return; +} + +static UINT32 Testcase(VOID) +{ + INT32 ret; + + pthread_once_t onceControl = PTHREAD_ONCE_INIT; + + g_testCount = 0; + + ret = pthread_once(&onceControl, PthreadF01); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(onceControl, 1, onceControl); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread214(VOID) +{ + TEST_ADD_CASE("ItPosixPthread214", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_215.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_215.c new file mode 100644 index 00000000..e50a42ab --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_215.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID PthreadF02(VOID) +{ + g_testCount = 1; + + sleep(10); // 10, delay for Timing control. + + g_testCount = -1; +} + +static VOID *PthreadF01(VOID *arg) +{ + INT32 ret; + + ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_once(&g_onceControl, (VOID *)PthreadF02); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return NULL; +} + +static VOID *PthreadF03(VOID) +{ + g_testCount = 1; + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + g_testCount = 0; + INT32 ret; + + g_onceControl = PTHREAD_ONCE_INIT; + + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + while (g_testCount == 0) { + sleep(1); + } + + ret = pthread_cancel(newTh); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + g_testCount = 0; + + ret = pthread_once(&g_onceControl, (VOID *)PthreadF03); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(g_onceControl, 1, g_onceControl); + ICUNIT_ASSERT_EQUAL(g_testCount, 0, g_testCount); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread215(VOID) +{ + TEST_ADD_CASE("ItPosixPthread215", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_217.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_217.c new file mode 100644 index 00000000..2035e506 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_217.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + INT32 i, ret; + const INT32 keyValue = 0; + VOID *specific = NULL; + + for (i = 0; i < PTHREAD_KEY_NUM; i++) { + ret = pthread_key_create(&g_pthreadKeyTest[i], NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ret = pthread_setspecific(g_pthreadKeyTest[i], (VOID *)(long)(i + keyValue)); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + } + + for (i = 0; i < PTHREAD_KEY_NUM; ++i) { + specific = pthread_getspecific(g_pthreadKeyTest[i]); + ICUNIT_ASSERT_EQUAL(specific, NULL, specific); + } + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread217(VOID) +{ + TEST_ADD_CASE("ItPosixPthread217", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_218.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_218.c new file mode 100644 index 00000000..1bc637b9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_218.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(VOID *argument) +{ + INT32 ret; + const INT32 keyValue = 1000; + + ret = pthread_setspecific(g_pthreadKeyTest[g_testCount], (const void *)(keyValue)); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + pthread_exit(0); + + return NULL; +} + + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + VOID *valuePtr = NULL; + INT32 ret; + + g_testCount = 0; + + for (g_testCount = 0; g_testCount < PTHREAD_KEY_NUM; g_testCount++) { + ret = pthread_key_create(&g_pthreadKeyTest[g_testCount], NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + } + + for (g_testCount = 0; g_testCount < PTHREAD_KEY_NUM; g_testCount++) { + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(newTh, &valuePtr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(valuePtr, 0, valuePtr); + } + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread218(VOID) +{ + TEST_ADD_CASE("ItPosixPthread218", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_219.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_219.c new file mode 100644 index 00000000..963720e4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_219.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + pthread_key_t g_key; + VOID *specific; + INT32 ret; + + specific = pthread_getspecific(g_key); + ICUNIT_ASSERT_EQUAL(specific, NULL, specific); + + ret = pthread_key_create(&g_key, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + specific = pthread_getspecific(g_key); + ICUNIT_ASSERT_EQUAL(specific, NULL, specific); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread219(VOID) +{ + TEST_ADD_CASE("ItPosixPthread219", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_221.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_221.c new file mode 100644 index 00000000..daf1bebb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_221.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + INT32 i, ret; + pthread_key_t keysMax[PTHREAD_KEYS_MAX]; + + for (i = 0; i <= PTHREAD_KEYS_MAX; i++) { + ret = pthread_key_create(&keysMax[i], NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + } + + for (i = 0; i <= PTHREAD_KEYS_MAX; i++) { + } + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread221(VOID) +{ + TEST_ADD_CASE("ItPosixPthread221", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_224.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_224.c new file mode 100644 index 00000000..f0f6dcd3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_224.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID PthreadF02(VOID *p) +{ + INT32 ret; + + g_testCount++; +} + +static VOID *PthreadF01(VOID *argument) +{ + INT32 ret; + const INT32 keyValue = 1000; + + ret = pthread_setspecific(g_key, (void *)(keyValue)); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + pthread_exit(0); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + INT32 ret; + + g_testCount = 0; + + ret = pthread_key_create(&g_key, PthreadF02); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 0, g_testCount); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread224(VOID) +{ + TEST_ADD_CASE("ItPosixPthread224", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_226.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_226.c new file mode 100644 index 00000000..6558d3aa --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_226.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static const INT32 g_keyValue1 = 100; +static const INT32 g_keyValue2 = 200; + +static VOID *g_specific1; +static VOID *g_specific2; + +static VOID *PthreadF01(VOID *argument) +{ + INT32 ret; + + /* Bind a value to g_key for this thread (this will be different from the value + * that we bind for the main thread) */ + ret = pthread_setspecific(g_key, (void *)(g_keyValue2)); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + /* Get the bound value of the g_key that we just set. */ + g_specific2 = pthread_getspecific(g_key); + + pthread_exit(0); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + INT32 ret; + + ret = pthread_key_create(&g_key, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_setspecific(g_key, (void *)(g_keyValue1)); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_specific1 = pthread_getspecific(g_key); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread226(VOID) +{ + TEST_ADD_CASE("ItPosixPthread226", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_233.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_233.c new file mode 100644 index 00000000..273e386b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_233.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID PthreadF02(VOID *tmp) +{ + g_testCount = 1; +} + +static VOID *PthreadF01(VOID *tmp) +{ + pthread_key_t g_key; + INT32 value = 1; + INT32 ret; + + ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_key_create(&g_key, PthreadF02); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_setspecific(g_key, &value); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_pthreadSem = 1; + + while (1) { + sleep(5); // 5, delay for Timing control. + } + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + INT32 ret; + + g_testCount = 0; + g_pthreadSem = 0; + + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + while (g_pthreadSem == 0) { + sleep(1); + } + + ret = pthread_cancel(newTh); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread233(VOID) +{ + TEST_ADD_CASE("ItPosixPthread233", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_237.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_237.c new file mode 100644 index 00000000..450bd825 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_237.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(VOID *argument) +{ + pthread_exit(0); + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + INT32 ret; + + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_cancel(newTh); + ICUNIT_ASSERT_EQUAL(ret, ESRCH, ret); + + return PTHREAD_NO_ERROR; +} +VOID ItPosixPthread237(VOID) +{ + TEST_ADD_CASE("ItPosixPthread237", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_238.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_238.c new file mode 100644 index 00000000..5a8723c1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_238.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(VOID *argument) +{ + INT32 ret; + + ret = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_testCount = 1; + + g_pthreadSem = PTHREAD_INMAIN_TEST; + + while (g_pthreadSem == PTHREAD_INMAIN_TEST) { + sleep(1); + } + + pthread_testcancel(); + + g_testCount = -1; + pthread_exit(0); + return NULL; +} + + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + INT32 ret; + + g_pthreadSem = PTHREAD_INTHREAD_TEST; + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + while (g_pthreadSem == PTHREAD_INTHREAD_TEST) { + sleep(1); + } + + ret = pthread_cancel(newTh); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_pthreadSem = PTHREAD_INTHREAD_TEST; + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread238(VOID) +{ + TEST_ADD_CASE("ItPosixPthread238", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_239.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_239.c new file mode 100644 index 00000000..0d611e8d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_239.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(VOID *argument) +{ + INT32 ret; + + ret = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_testCount = -1; + + g_pthreadSem = PTHREAD_INMAIN_TEST; + + while (g_pthreadSem == PTHREAD_INMAIN_TEST) { + sleep(1); + } + + pthread_testcancel(); + + g_testCount = 1; + pthread_exit(0); + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + INT32 ret; + + g_pthreadSem = PTHREAD_INTHREAD_TEST; + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + while (g_pthreadSem == PTHREAD_INTHREAD_TEST) { + sleep(1); + } + + ret = pthread_cancel(newTh); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_pthreadSem = PTHREAD_INTHREAD_TEST; + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread239(VOID) +{ + TEST_ADD_CASE("ItPosixPthread239", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_240.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_240.c new file mode 100644 index 00000000..8a288069 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_240.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(VOID *argument) +{ + INT32 ret; + + ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_testCount = 1; + + g_pthreadSem = PTHREAD_INMAIN_TEST; + + while (g_pthreadSem == PTHREAD_INMAIN_TEST) { + sleep(1); + } + + pthread_testcancel(); + + g_testCount = -1; + + pthread_exit(0); + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + INT32 ret; + + g_pthreadSem = PTHREAD_INTHREAD_TEST; + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + while (g_pthreadSem == PTHREAD_INTHREAD_TEST) { + sleep(1); + } + + ret = pthread_cancel(newTh); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_pthreadSem = PTHREAD_INTHREAD_TEST; + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread240(VOID) +{ + TEST_ADD_CASE("ItPosixPthread240", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_241.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_241.c new file mode 100644 index 00000000..23c0e0ce --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_241.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(VOID *argument) +{ + INT32 ret; + + g_testCount++; + + ret = pthread_setcancelstate(-100, NULL); // -100, test for invalid param. + ICUNIT_TRACK_EQUAL(ret, EINVAL, ret); + + pthread_exit(0); + + return NULL; +} + + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + INT32 ret; + + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread241(VOID) +{ + TEST_ADD_CASE("ItPosixPthread241", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_246.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_246.c new file mode 100644 index 00000000..5c341c88 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/full/It_posix_pthread_246.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(VOID *argument) +{ + INT32 ret; + + ret = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_testCount = -1; + + g_pthreadSem = PTHREAD_INMAIN_TEST; + + while (g_pthreadSem == PTHREAD_INMAIN_TEST) { + sleep(1); + } + + pthread_testcancel(); + + g_testCount = 1; + + pthread_exit(0); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + INT32 ret; + + g_pthreadSem = PTHREAD_INTHREAD_TEST; + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + while (g_pthreadSem == PTHREAD_INTHREAD_TEST) { + sleep(1); + } + + ret = pthread_cancel(newTh); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_pthreadSem = PTHREAD_INTHREAD_TEST; + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread246(VOID) +{ + TEST_ADD_CASE("ItPosixPthread246", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/smoke/It_posix_pthread_003.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/smoke/It_posix_pthread_003.c new file mode 100644 index 00000000..7a577c68 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/smoke/It_posix_pthread_003.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void *ThreadF01(void *arg) +{ + pthread_exit(NULL); + return NULL; +} +static UINT32 Testcase(VOID) +{ + pthread_t aThread; + pthread_t ptid; + pthread_t a = 0; + pthread_t b = 0; + int tmp; + pthread_attr_t aa = { 0 }; + int detachstate; + pthread_mutex_t c; + UINT32 ret; + + ptid = pthread_self(); + pthread_create(&aThread, NULL, ThreadF01, NULL); + + tmp = pthread_equal(a, b); + + pthread_attr_init(&aa); + + pthread_attr_getdetachstate(&aa, &detachstate); + + pthread_attr_setdetachstate(&aa, PTHREAD_CREATE_DETACHED); + + pthread_attr_destroy(&aa); + + ret = pthread_join(aThread, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread003(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread003", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/smoke/It_posix_pthread_004.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/smoke/It_posix_pthread_004.c new file mode 100644 index 00000000..5963b9bd --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/smoke/It_posix_pthread_004.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void *ThreadF01(void *arg) +{ + pthread_exit((void *)2); // 2, here set value of the exit status. + return NULL; +} +static UINT32 Testcase(VOID) +{ + pthread_t mainTh, newTh; + UINT32 ret; + UINTPTR temp; + + if (pthread_create(&newTh, NULL, ThreadF01, NULL) != 0) { + uart_printf_func("Error creating thread\n"); + ICUNIT_ASSERT_EQUAL(1, 0, errno); + } + + LOS_TaskDelay(1); + /* Obtain the thread ID of this main function */ + mainTh = TestPthreadSelf(); + /* Compare the thread ID of the new thread to the main thread. + * They should be different. If not, the test fails. */ + if (pthread_equal(newTh, mainTh) != 0) { + dprintf("Test FAILED: A new thread wasn't created\n"); + ICUNIT_ASSERT_EQUAL(1, 0, errno); + } + + TestExtraTaskDelay(1); + ret = pthread_join(newTh, (void *)&temp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(temp, 2, temp); // 2, here assert the result. + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread004(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread004", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/smoke/It_posix_pthread_005.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/smoke/It_posix_pthread_005.c new file mode 100644 index 00000000..6b592005 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/smoke/It_posix_pthread_005.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void *ThreadF01(void *arg) +{ + sleep(1); + + /* Shouldn't reach here. If we do, then the pthread_cancel() + * function did not succeed. */ + + pthread_exit((void *)0); + return NULL; +} +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + UINT32 ret; + UINTPTR temp; + + if (pthread_create(&newTh, NULL, ThreadF01, NULL) < 0) { + uart_printf_func("Error creating thread\n"); + ICUNIT_ASSERT_EQUAL(1, 0, errno); + } + + LOS_TaskDelay(1); + /* Try to cancel the newly created thread. If an error is returned, + * then the thread wasn't created successfully. */ + if (pthread_cancel(newTh) != 0) { + dprintf("Test FAILED: A new thread wasn't created\n"); + ICUNIT_ASSERT_EQUAL(1, 0, errno); + } + + ret = pthread_join(newTh, (void *)&temp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread005(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread005", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/smoke/It_posix_pthread_006.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/smoke/It_posix_pthread_006.c new file mode 100644 index 00000000..34cc2c6b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/smoke/It_posix_pthread_006.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static void *ThreadF01(void *arg) +{ + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + + sleep(1); + + pthread_exit((void *)0); + return NULL; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + void *temp = NULL; + pthread_t a; + + /* SIGALRM will be sent in 5 seconds. */ + + /* Create a new thread. */ + if (pthread_create(&a, NULL, ThreadF01, NULL) != 0) { + uart_printf_func("Error creating thread\n"); + ICUNIT_ASSERT_EQUAL(1, 0, errno); + } + + LOS_TaskDelay(1); + pthread_cancel(a); + /* If 'main' has reached here, then the test passed because it means + * that the thread is truly asynchronise, and main isn't waiting for + * it to return in order to move on. */ + + ret = pthread_join(a, &temp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread006(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread006", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/smoke/It_posix_pthread_009.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/smoke/It_posix_pthread_009.c new file mode 100644 index 00000000..ddb49aba --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/smoke/It_posix_pthread_009.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(void *argument) +{ + g_testCount++; + + pthread_exit(NULL); + + return (void *)9; // 9, here set value about the return status. +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + UINT32 ret; + UINTPTR temp = 1; + _pthread_data *joinee = NULL; + + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + LOS_TaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = pthread_join(g_taskMaxNum, (void *)&temp); + ICUNIT_ASSERT_EQUAL(ret, ESRCH, ret); + ICUNIT_ASSERT_EQUAL(temp, 1, temp); + + ret = pthread_join(LOSCFG_BASE_CORE_TSK_CONFIG + 1, (void *)&temp); + ICUNIT_ASSERT_EQUAL(ret, ESRCH, ret); + ICUNIT_ASSERT_EQUAL(temp, 1, temp); + + ret = pthread_detach(g_taskMaxNum); + ICUNIT_ASSERT_EQUAL(ret, ESRCH, ret); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + sleep(1); + ret = pthread_detach(newTh); + ICUNIT_ASSERT_EQUAL(ret, ESRCH, ret); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, ESRCH, ret); + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread009(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread009", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/smoke/It_posix_pthread_018.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/smoke/It_posix_pthread_018.c new file mode 100644 index 00000000..9693fe82 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/smoke/It_posix_pthread_018.c @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID *PthreadF01(void *argument) +{ + g_testCount++; + + return argument; +} +static UINT32 Testcase(VOID) +{ + pthread_attr_t attr; + pthread_t newTh; + UINT32 ret; + UINTPTR temp; + int policy; + struct sched_param param; + struct sched_param param2 = { 2 }; // 2, init + + g_testCount = 0; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newTh, NULL, PthreadF01, (void *)9); // 9, test param of the function. + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + LOS_TaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = pthread_setschedparam(newTh, 0, ¶m); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_setschedparam(newTh, 4, ¶m); // 4, test for invalid param. + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_setschedparam(newTh, SCHED_RR, NULL); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + param.sched_priority = 0; + ret = pthread_setschedparam(newTh, SCHED_RR, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + param.sched_priority = 31; // 31, init + ret = pthread_setschedparam(newTh, SCHED_RR, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + param.sched_priority = 32; // 32, init + ret = pthread_setschedparam(newTh, SCHED_RR, ¶m); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_getschedparam(newTh, NULL, ¶m2); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + ICUNIT_ASSERT_EQUAL(param2.sched_priority, 2, param2.sched_priority); // 2, here assert the result. + + ret = pthread_getschedparam(newTh, &policy, NULL); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_getschedparam(newTh, &policy, ¶m2); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(param2.sched_priority, 31, param2.sched_priority); // 31, here assert the result. + + ret = pthread_join(newTh, (void *)&temp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(temp, 9, temp); // 9, here assert the result. + + param.sched_priority = 4; // 4, init + ret = pthread_setschedparam(newTh, SCHED_RR, ¶m); + ICUNIT_ASSERT_EQUAL(ret, ESRCH, ret); + + ret = pthread_setschedparam(newTh + 9, SCHED_RR, ¶m); // 9, test for invalid param. + ICUNIT_ASSERT_EQUAL(ret, ESRCH, ret); + + ret = pthread_getschedparam(newTh, &policy, ¶m2); + ICUNIT_ASSERT_EQUAL(ret, ESRCH, ret); + + ret = pthread_getschedparam(newTh + 8, &policy, ¶m2); // 8, test for invalid param. + ICUNIT_ASSERT_EQUAL(ret, ESRCH, ret); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread018(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread018", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/smoke/It_posix_pthread_019.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/smoke/It_posix_pthread_019.c new file mode 100644 index 00000000..9d7c6478 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/smoke/It_posix_pthread_019.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static VOID PthreadOnceF01(VOID) +{ + g_testCount++; +} +static UINT32 Testcase(VOID) +{ + UINT32 ret; + pthread_once_t onceBlock; + + g_testCount = 0; + + ret = pthread_once(NULL, PthreadOnceF01); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + onceBlock = 1; + ret = pthread_once(&onceBlock, PthreadOnceF01); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 0, g_testCount); + + onceBlock = PTHREAD_ONCE_INIT; + ret = pthread_once(&onceBlock, NULL); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_once(&onceBlock, PthreadOnceF01); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = pthread_once(&onceBlock, PthreadOnceF01); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread019(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread019", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/smoke/It_posix_pthread_021.c b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/smoke/It_posix_pthread_021.c new file mode 100644 index 00000000..d9d9fffc --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/sample/posix/pthread/smoke/It_posix_pthread_021.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_posix_pthread.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + int oldstate; + int oldstype; + + ret = pthread_setcancelstate(2, &oldstate); // 2, test for invalid param. + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_setcancelstate(3, &oldstate); // 3, test for invalid param. + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(oldstate, PTHREAD_CANCEL_ENABLE, oldstate); + + ret = pthread_setcanceltype(2, &oldstype); // 2, test for invalid param. + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_setcanceltype(3, &oldstype); // 3, test for invalid param. + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldstate); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(oldstate, PTHREAD_CANCEL_ASYNCHRONOUS, oldstate); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread021(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixPthread021", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL0, TEST_FUNCTION); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/kernel/src/iCunit.c b/src/kernel_liteos_a/testsuites/kernel/src/iCunit.c new file mode 100644 index 00000000..ad014b19 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/src/iCunit.c @@ -0,0 +1,663 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "iCunit.h" +#include "iCunit.inc" +#include "iCunit_config.h" +#include "osTest.h" +#if TEST_RESOURCELEAK_CHECK == 1 +#include "los_swtmr_pri.h" +#include "los_sem_pri.h" +#include "los_queue_pri.h" +#include "los_task_pri.h" +#include "los_mux_pri.h" +#endif +#include + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#define ARRAY_SIZE 2 + +#ifdef LOSCFG_KERNEL_SMP +LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_testSuitSpin); +#endif + +extern UINT32 g_failResult; +extern UINT32 g_passResult; + +extern int atoi(const char *str); +extern int strncmp(const char *s1, const char *s2, size_t n); + +char *g_strLayer[] = {"LOS", "POSIX", "LIB", "VFS", "EXTEND", + "PARTITION", "CPP", "SHELL", "LINUX", "USB", +#if defined(LOSCFG_3RDPARTY_TEST) + "TEST_3RDPARTY", +#endif + "DRIVER", "ALL" + }; + +char *g_strModule[] = {"TASK", "MEM", "SEM", "MUX", "EVENT", "QUE", "SWTMR", "HWI", "MP", "ATO", "CPUP", "SCATTER", "RUNSTOP", "TIMER", "MMU", + "ROBIN", "LIBC", "WAIT", "VFAT", "JFFS", "RAMFS", "NFS", "PROC", "FS", "UART", + "PTHREAD", "COMP", "HWI_HALFBOTTOM", "WORKQ", "WAKELOCK", "TIMES", + "LIBM", "SUPPORT", "STL", "MAIL", "MSG", "CP", "SIGNAL", "SCHED", "MTDCHAR", "TIME", "WRITE", "READ", "DYNLOAD", "REGISTER", + "UNAME", "ERR", "CMD", "TICKLESS", "TRACE", "UNALIGNACCESS", "EXC", "REQULATOR", "DEVFREQ", "CPUFREQ", "TEST_MISC", +#if defined(LOSCFG_3RDPARTY_TEST) + "THTTPD", "BIDIREFC", "CJSON", "CURL", "FFMPEG", "FREETYPE", "INIPARSER", "JSONCPP", "LIBICONV", "LIBJPEG", "LIBPNG", "OPENEXIF", "OPENSSL", + "OPUS", "SQLITE", "TINYXML", "XML2", "ZBAR", "HARFBUZZ", +#endif + "TEST_DRIVERBASE", "ALL" + }; +UINT32 g_modelNum = sizeof(g_strModule) / sizeof(g_strModule[0]); + +#if TEST_MODULE_CHECK == 1 + +UINT32 g_failModelResult[sizeof(g_strModule) / sizeof(g_strModule[0])] = {0}; +UINT32 g_passModelResult[sizeof(g_strModule) / sizeof(g_strModule[0])] = {0}; +UINT32 g_executModelNum[sizeof(g_strModule) / sizeof(g_strModule[0])] = {0}; +ICUNIT_CASE_S g_errorCase[50] = {0}; + +#endif + +char *g_strLevel[] = {"LEVEL0", "LEVEL1", "LEVEL2", "LEVEL3", "LEVEL4", "ALL"}; +char *g_strType[] = {"FUNCTION", "PRESSURE", "PERFORMANCE", "ALL"}; +char *g_strSequence[] = {"SEQUENCE", "RANDOM"}; + + +u_long ICunitRand(void) +{ + static u_long randseed; + u_long t; + long x, hi, lo; + UINT32 high = 0; + UINT32 low = 0; + + extern VOID LOS_GetCpuCycle(UINT32 * puwCntHi, UINT32 * puwCntLo); + LOS_GetCpuCycle(&high, &low); + randseed = ((u_long)(high << 30) + low); // 30, generate a seed. + + /* + * Compute x[n + 1] = (7^5 * x[n]) mod (2^31 - 1). + * From "Random number generators: good ones are hard to find", + * Park and Miller, Communications of the ACM, vol. 31, no. 10, + * October 1988, p. 1195. + */ + x = randseed; + hi = x / 127773; // 127773, generate a seed. + lo = x % 127773; // 127773, generate a seed. + t = 16807 * lo - 2836 * hi; // 16807, 2836, generate a seed. + if (t <= 0) + t += 0x7fffffff; + randseed = t; + return (u_long)(t); +} + +void ICunitSaveErr(iiUINT32 line, iiUINT32 retCode) +{ +#ifdef LOSCFG_KERNEL_SMP + UINT32 intSave; + TESTSUIT_LOCK(intSave); +#endif + g_iCunitErrCode = ((g_iCunitErrCode == 0) && (g_iCunitErrLineNo == 0)) ? (iiUINT32)retCode : g_iCunitErrCode; + g_iCunitErrLineNo = (g_iCunitErrLineNo == 0) ? line : g_iCunitErrLineNo; +#ifdef LOSCFG_KERNEL_SMP + TESTSUIT_UNLOCK(intSave); +#endif +} + +#undef LOSCFG_TEST_LEVEL +#define LOSCFG_TEST_LEVEL 0 +iUINT32 ICunitAddCase(const iCHAR *caseName, CASE_FUNCTION caseFunc, iUINT16 testcaseLayer, iUINT16 testcaseModule, + iUINT16 testcaseLevel, iUINT16 testcaseType) +{ + iUINT16 idx; + + if (g_iCunitInitSuccess) { + return (iUINT32)ICUNIT_UNINIT; + } + + /* Don't run Firstly with Python */ + if (g_iCunitCaseRun == 0) { + return (iUINT32)ICUNIT_SUCCESS; + } + +#if defined(LITEOS_TESTSUIT_SHELL) || defined(LOSCFG_TEST_MUTIL) + idx = g_iCunitCaseCnt; +#else + idx = 0; +#endif + if (idx == ICUNIT_CASE_SIZE) { + g_iCunitErrLogAddCase++; + return (iUINT32)ICUNIT_CASE_FULL; + } + + g_iCunitCaseArray[idx].pcCaseID = caseName; + g_iCunitCaseArray[idx].pstCaseFunc = caseFunc; + g_iCunitCaseArray[idx].testcase_layer = testcaseLayer; + g_iCunitCaseArray[idx].testcase_module = testcaseModule; + g_iCunitCaseArray[idx].testcase_level = testcaseLevel; + g_iCunitCaseArray[idx].testcase_type = testcaseType; + +#if defined(LITEOS_TESTSUIT_SHELL) || defined(LOSCFG_TEST_MUTIL) + g_iCunitCaseCnt++; +#else + ICunitRunSingle(&g_iCunitCaseArray[idx]); +#endif + +#if defined(LOSCFG_TEST_MUTIL) + ICunitRunSingle(&g_iCunitCaseArray[idx]); +#endif + + return (iUINT32)ICUNIT_SUCCESS; +} +UINT32 g_cunitInitFlag = 0; +iUINT32 ICunitInit(void) +{ +#ifdef LOSCFG_KERNEL_SMP + if (LOS_AtomicCmpXchg32bits(&g_cunitInitFlag, 1, 0)) { + PRINTK("other core already done iCunitInit\n"); + return (iUINT32)ICUNIT_SUCCESS; + } +#endif + g_iCunitInitSuccess = 0x0000; + g_iCunitCaseCnt = 0x0000; + g_iCunitCaseFailedCnt = 0; + g_iCunitErrLogAddCase = 0; + (void)memset_s(g_iCunitCaseArray, sizeof(g_iCunitCaseArray), 0, sizeof(g_iCunitCaseArray)); + g_iCunitCaseRun = 1; + + return (iUINT32)ICUNIT_SUCCESS; +} + +iUINT32 ICunitRunSingle(ICUNIT_CASE_S *psubCase) +{ + if ((g_isSpinorInit == FALSE) && (psubCase->testcase_module == TEST_JFFS)) { + dprintf("****** Jffs is not support ! ****** \n"); + } else { + ICunitRunF(psubCase); + } + + return (iUINT32)ICUNIT_SUCCESS; +} + +iUINT32 ICunitRunF(ICUNIT_CASE_S *psubCase) +{ + iUINT32 caseRet; + UINT32 curTestTaskID; + g_iCunitErrLineNo = 0; + g_iCunitErrCode = 0; + +#if TEST_RESOURCELEAK_CHECK == 1 + extern UINT32 LOS_MemTotalUsedGet(VOID * pPool); + extern HwiHandleForm g_hwiForm[OS_HWI_MAX_NUM]; + extern SWTMR_CTRL_S *g_swtmrCBArray; + static SWTMR_CTRL_S *swtmr; + iUINT32 i; + static UINT32 gAuwMemuse[ARRAY_SIZE]; + static UINT32 gUwTskNum[ARRAY_SIZE]; + static UINT32 gUwSwtNum[ARRAY_SIZE]; + static UINT32 gUwHwiNum[ARRAY_SIZE]; + static UINT32 gUwQueueNum[ARRAY_SIZE]; + LosQueueCB *queueCB = NULL; + static UINT32 gUwSemNum[ARRAY_SIZE]; + static LosSemCB *semNode; + UINT32 muxCnt[ARRAY_SIZE]; + + (void)memset_s(gUwSwtNum, sizeof(gUwSwtNum), 0, sizeof(gUwSwtNum)); + (void)memset_s(gUwHwiNum, sizeof(gUwHwiNum), 0, sizeof(gUwHwiNum)); + (void)memset_s(gUwTskNum, sizeof(gUwTskNum), 0, sizeof(gUwTskNum)); + (void)memset_s(gAuwMemuse, sizeof(gAuwMemuse), 0, sizeof(gAuwMemuse)); + (void)memset_s(gUwQueueNum, sizeof(gUwQueueNum), 0, sizeof(gUwQueueNum)); + (void)memset_s(gUwSemNum, sizeof(gUwSemNum), 0, sizeof(gUwSemNum)); + + curTestTaskID = LOS_CurTaskIDGet(); + + // task + for (i = 0; i <= LOSCFG_BASE_CORE_TSK_LIMIT; i++) { + if (g_taskCBArray[i].taskStatus == OS_TASK_STATUS_UNUSED) + gUwTskNum[0]++; + } + + // swtmr + swtmr = g_swtmrCBArray; + for (i = 0; i < LOSCFG_BASE_CORE_SWTMR_LIMIT; i++, swtmr++) { + if (swtmr->ucState == OS_SWTMR_STATUS_UNUSED) + gUwSwtNum[0]++; + } + + // hwi + for (i = 0; i < OS_HWI_MAX_NUM; i++) { + if ((g_hwiForm[i].pfnHook == (HWI_PROC_FUNC)NULL) && (g_hwiForm[i].uwParam == 0)) + gUwHwiNum[0]++; + } + + // sem + for (i = 0; i < LOSCFG_BASE_IPC_SEM_LIMIT; i++) { + semNode = GET_SEM(i); + if (semNode->semStat == OS_SEM_UNUSED) { + gUwSemNum[0]++; + } + } + + // queue + queueCB = g_allQueue; + for (i = 0; i < LOSCFG_BASE_IPC_QUEUE_LIMIT; i++, queueCB++) { + if (queueCB->queueState == OS_QUEUE_UNUSED) { + gUwQueueNum[0]++; + } + } + + gAuwMemuse[0] = LOS_MemTotalUsedGet(OS_SYS_MEM_ADDR); + + if (g_performanceStart <= 0) { + dprintf("# Enter:%s \n", psubCase->pcCaseID); + } + caseRet = psubCase->pstCaseFunc(); + + if (g_performanceStart <= 0) { + if ((strcmp(psubCase->pcCaseID, "LLT_PLAT_004") == 0) || + (strcmp(psubCase->pcCaseID, "IT_FS_JFFS_MUTIPTHREAD_001") == 0) || + (strcmp(psubCase->pcCaseID, "IT_FS_JFFS_PRESSURE_013") == 0) || + (strcmp(psubCase->pcCaseID, "IT_FS_JFFS_PRESSURE_052") == 0) || + (strcmp(psubCase->pcCaseID, "IT_FS_JFFS_026") == 0) || + (strcmp(psubCase->pcCaseID, "IT_PARTITION_JFFS_004") == 0) || + (strcmp(psubCase->pcCaseID, "IT_PARTITION_JFFS_009") == 0) || + (strcmp(psubCase->pcCaseID, "IT_PARTITION_JFFS_013") == 0) || + (strcmp(psubCase->pcCaseID, "IT_PARTITION_JFFS_017") == 0) || + (strcmp(psubCase->pcCaseID, "IT_PARTITION_JFFS_018") == 0) || + (strcmp(psubCase->pcCaseID, "IT_PARTITION_JFFS_039") == 0) || + (strcmp(psubCase->pcCaseID, "IT_FS_FAT_VIRPART_PRESSURE_001") == 0) || + (strcmp(psubCase->pcCaseID, "IT_FS_FAT_VIRPART_151") == 0) || + (strcmp(psubCase->pcCaseID, "IT_FS_FAT_VIRPART_040") == 0) || + (strcmp(psubCase->pcCaseID, "IT_FS_FAT_VIRPART_MULTIPTHREAD_000") == 0) || + (strcmp(psubCase->pcCaseID, "IT_FS_FAT_VIRPART_MULTIPTHREAD_033") == 0) || + (strcmp(psubCase->pcCaseID, "IT_FS_FAT_VIRPART_MULTIPTHREAD_034") == 0) || + (strcmp(psubCase->pcCaseID, "IT_FS_FATVP_363") == 0) || + (strcmp(psubCase->pcCaseID, "IT_FS_FAT_VIRPART_012") == 0) || + (strcmp(psubCase->pcCaseID, "IT_PARTITION_DISK_001") == 0) || + (strcmp(psubCase->pcCaseID, "IT_FS_NFS_PRESSURE_013") == 0) || + (strcmp(psubCase->pcCaseID, "IT_PARTITION_Yaffs_019") == 0) || + (strcmp(psubCase->pcCaseID, "IT_PARTITION_Yaffs_017") == 0) || + (strcmp(psubCase->pcCaseID, "IT_PARTITION_Yaffs_013") == 0) || + (strcmp(psubCase->pcCaseID, "IT_PARTITION_Yaffs_009") == 0) || + (strcmp(psubCase->pcCaseID, "LLT_VFS_FAT_002") == 0) || + (strcmp(psubCase->pcCaseID, "IT_FS_FAT_363") == 0) || (strcmp(psubCase->pcCaseID, "LLT_FS_VFS_004") == 0) || + (strcmp(psubCase->pcCaseID, "LLT_FS_RAMFS_003") == 0) || + (strcmp(psubCase->pcCaseID, "LLT_FS_RAMFS_001") == 0)) { + dprintf(" [Case]-%s-%s-%s-%s-%s,unrunning!!!\n", psubCase->pcCaseID, g_strLayer[psubCase->testcase_layer], + g_strModule[psubCase->testcase_module], g_strLevel[psubCase->testcase_level], + g_strType[psubCase->testcase_type]); + goto ENDING; + } + + gAuwMemuse[1] = LOS_MemTotalUsedGet(OS_SYS_MEM_ADDR); + + // task + for (i = 0; i <= LOSCFG_BASE_CORE_TSK_LIMIT; i++) { + if (g_taskCBArray[i].taskStatus == OS_TASK_STATUS_UNUSED) + gUwTskNum[1]++; + } + + // swtmr + swtmr = g_swtmrCBArray; + for (i = 0; i < LOSCFG_BASE_CORE_SWTMR_LIMIT; i++, swtmr++) { + if (swtmr->ucState == OS_SWTMR_STATUS_UNUSED) + gUwSwtNum[1]++; + } + + // hwi + for (i = 0; i < OS_HWI_MAX_NUM; i++) { + if ((g_hwiForm[i].pfnHook == (HWI_PROC_FUNC)NULL) && (g_hwiForm[i].uwParam == 0)) + gUwHwiNum[1]++; + } + + // sem + for (i = 0; i < LOSCFG_BASE_IPC_SEM_LIMIT; i++) { + semNode = GET_SEM(i); + if (semNode->semStat == OS_SEM_UNUSED) { + gUwSemNum[1]++; + } + } + + // queue + queueCB = g_allQueue; + for (i = 0; i < LOSCFG_BASE_IPC_QUEUE_LIMIT; i++, queueCB++) { + if (queueCB->queueState == OS_QUEUE_UNUSED) { + gUwQueueNum[1]++; + } + } + + if (gUwSemNum[1] != gUwSemNum[0]) { + dprintf("\n[Case Resource Leak Failed]------------------Sem used:%d Semleak:%d\n", gUwSemNum[1], + (gUwSemNum[1] - gUwSemNum[0])); + } + + if (gUwQueueNum[1] != gUwQueueNum[0]) { + dprintf("\n[Case Resource Leak Failed]------------------Queue used:%d Queueleak:%d\n", gUwQueueNum[1], + (gUwQueueNum[1] - gUwQueueNum[0])); + } + + if (gUwTskNum[1] != gUwTskNum[0]) { + dprintf("\n[Case Resource Leak Failed]------------------Task used:%d Taskleak:%d\n", gUwTskNum[1], + (gUwTskNum[1] - gUwTskNum[0])); + } + + if (gUwSwtNum[1] != gUwSwtNum[0]) { + dprintf("\n[Case Resource Leak Failed]------------------Swtmr used:%d Swtmrleak:%d\n", gUwSwtNum[1], + (gUwSwtNum[1] - gUwSwtNum[0])); + } + + if (gUwHwiNum[1] != gUwHwiNum[0]) { + dprintf("\n[Case Resource Leak Failed]------------------Hwi used:%d Hwileak:%d\n", gUwHwiNum[1], + (gUwHwiNum[1] - gUwHwiNum[0])); + } + + if (gAuwMemuse[1] != gAuwMemuse[0]) { + dprintf("\n[Case Resource Leak Failed]------------------Mem used:%d Memleak:%d\n", gAuwMemuse[1], + (gAuwMemuse[1] - gAuwMemuse[0])); + } + } + +#else + if (g_performanceStart <= 0) { + curTestTaskID = LOS_CurTaskIDGet(); + dprintf("# T:%d Enter:%s \n", curTestTaskID, psubCase->pcCaseID); + } + caseRet = psubCase->pstCaseFunc(); +#endif + + psubCase->errLine = g_iCunitErrLineNo; + psubCase->retCode = (0 == g_iCunitErrLineNo) ? (caseRet) : (g_iCunitErrCode); + +#if TEST_MODULE_CHECK == 1 + g_executModelNum[psubCase->testcase_module]++; +#endif +ENDING: + if (psubCase->errLine == 0 && caseRet == 0) { + g_passResult++; + +#if TEST_MODULE_CHECK == 1 + g_passModelResult[psubCase->testcase_module]++; +#endif + + if (g_performanceStart <= 0) { + dprintf(" T:%d [Passed]-%s-%s-%s-%s-%s\n", curTestTaskID, psubCase->pcCaseID, + g_strLayer[psubCase->testcase_layer], g_strModule[psubCase->testcase_module], + g_strLevel[psubCase->testcase_level], g_strType[psubCase->testcase_type]); + } + } else { +#if TEST_MODULE_CHECK == 1 + if (g_failResult < 50) { // 50 + g_errorCase[g_failResult] = *psubCase; + } + g_failModelResult[psubCase->testcase_module]++; +#endif + + g_iCunitCaseFailedCnt++; + g_failResult++; + dprintf(" T:%d [Failed]-%s-%s-%s-%s-%s-[Errline: %d RetCode:0x%04X%04X]\n", curTestTaskID, psubCase->pcCaseID, + g_strLayer[psubCase->testcase_layer], g_strModule[psubCase->testcase_module], + g_strLevel[psubCase->testcase_level], g_strType[psubCase->testcase_type], psubCase->errLine, + (iUINT16)((psubCase->retCode) >> 16), (iUINT16)(psubCase->retCode)); // 16 + +#ifdef LOSCFG_SHELL + dprintf("\n\n ********************************************************** \n"); + OsShellCmdSystemInfo(0, NULL); + dprintf("\n ********************************************************** \n"); + const CHAR *taskAll = "-a"; + OsShellCmdDumpTask(1, &taskAll); + dprintf(" ********************************************************** \n\n\n"); +#endif + } + + return (iUINT32)ICUNIT_SUCCESS; +} + +INT32 ICunitRunTestArray(const char *tcSequence, const char *tcNum, const char *tcLayer, const char *tcModule, + const char *tcLevel, const char *tcType) +{ + iUINT32 testcaseNum; + iUINT32 testcaseLayer = 0xFFFF; + iUINT32 testcaseModule = 0xFFFF; + iUINT32 testcaseLevel = 0xFFFF; + iUINT32 testcaseType = 0xFFFF; + iUINT32 ilayer; + iUINT32 imodule; + iUINT32 ilevel; + iUINT32 itype; + + testcaseNum = atoi(tcNum); + if (testcaseNum > 0xFFFF) { + dprintf("[testcase_Num]-%u is too large \n", testcaseNum); + + testcaseNum = 0xFFFF; + } + + for (ilayer = 0; ilayer <= TEST_LAYER_ALL; ilayer++) { + if (strcmp(g_strLayer[ilayer], tcLayer) == 0) { + testcaseLayer = ilayer; + dprintf("[testcase_Layer]-%s \n", g_strLayer[ilayer]); + + break; + } + } + + if (testcaseLayer == 0xFFFF) { + dprintf("[testcase_Layer]-%s is invalid \n", tcLayer); + + return (iUINT32)ICUNIT_SUCCESS; + } + + for (imodule = 0; imodule <= TEST_MODULE_ALL; imodule++) { + if (strcmp(g_strModule[imodule], tcModule) == 0) { + testcaseModule = imodule; + dprintf("[testcase_Module]-%s \n", g_strModule[imodule]); + + break; + } + } + + if (testcaseModule == 0xFFFF) { + dprintf("[testcase_Module]-%s is invalid \n", tcModule); + + return (iUINT32)ICUNIT_SUCCESS; + } + + for (ilevel = 0; ilevel <= TEST_LEVEL_ALL; ilevel++) { + if (strcmp(g_strLevel[ilevel], tcLevel) == 0) { + testcaseLevel = ilevel; + dprintf("[testcase_Level]-%s \n", g_strLevel[ilevel]); + + break; + } + } + + if (testcaseLevel == 0xFFFF) { + dprintf("[testcase_Level]-%s is invalid \n", tcLevel); + + return (iUINT32)ICUNIT_SUCCESS; + } + + for (itype = 0; itype <= TEST_TYPE_ALL; itype++) { + if (strcmp(g_strType[itype], tcType) == 0) { + testcaseType = itype; + dprintf("[testcase_Type]-%s \n", g_strType[itype]); + + break; + } + } + + if (testcaseType == 0xFFFF) { + dprintf("[testcase_Type]-%s is invalid \n", tcType); + + return (iUINT32)ICUNIT_SUCCESS; + } + + if (0 == strncmp(tcSequence, "SEQUENCE", 8)) { // 8, "SEQUENCE" length + dprintf("[testcase_Sequence]-%s \n", tcSequence); + + ICunitRunTestArraySequence(testcaseNum, testcaseLayer, testcaseModule, testcaseLevel, testcaseType); + } else if (0 == strncmp(tcSequence, "RANDOM", 6)) { // 6, "RANDOM" length + dprintf("[testcase_Random]-%s \n", tcSequence); + + ICunitRunTestArrayRandom(testcaseNum, testcaseLayer, testcaseModule, testcaseLevel, testcaseType); + } else { + dprintf("[testcase_Sequence]-%s is invalid \n", tcSequence); + } + + g_failResult = 0; + g_passResult = 0; + + return (iUINT32)ICUNIT_SUCCESS; +} + +iUINT32 ICunitRunTestArraySequence(iUINT32 testcaseNum, iUINT32 testcaseLayer, iUINT32 testcaseModule, + iUINT32 testcaseLevel, iUINT32 testcaseType) +{ + iUINT32 num; + iUINT32 idx; + iUINT32 idx1; + iUINT32 failedCount; + iUINT32 successCount; + + idx1 = g_iCunitCaseCnt; + + for (num = 0; num < testcaseNum; num++) { + failedCount = g_failResult; + successCount = g_passResult; + + for (idx = 0; idx < idx1; idx++) { + ICunitRunTestcaseSatisfied(&(g_iCunitCaseArray[idx]), testcaseLayer, testcaseModule, testcaseLevel, + testcaseType); + } + } + + return (iUINT32)ICUNIT_SUCCESS; +} + + +iUINT32 ICunitRunTestArrayRandom(iUINT32 testcaseNum, iUINT32 testcaseLayer, iUINT32 testcaseModule, + iUINT32 testcaseLevel, iUINT32 testcaseType) +{ + iUINT32 num; + iUINT32 idx; + iUINT32 idx1; + iUINT32 randIdx; + ICUNIT_CASE_S subCaseArrayTemp; + iUINT32 failedCount; + iUINT32 successCount; + + (void)memset_s(&subCaseArrayTemp, sizeof(ICUNIT_CASE_S), 0, sizeof(ICUNIT_CASE_S)); + + idx1 = g_iCunitCaseCnt; + + for (num = 0; num < testcaseNum; num++) { + failedCount = g_failResult; + successCount = g_passResult; + + for (idx = idx1 - 1; idx > 1; idx--) { + (void)memset_s(&subCaseArrayTemp, sizeof(ICUNIT_CASE_S), 0, sizeof(ICUNIT_CASE_S)); + + randIdx = ICunitRand() % idx; + subCaseArrayTemp = g_iCunitCaseArray[randIdx]; + g_iCunitCaseArray[randIdx] = g_iCunitCaseArray[idx]; + g_iCunitCaseArray[idx] = subCaseArrayTemp; + ICunitRunTestcaseSatisfied(&(g_iCunitCaseArray[idx]), testcaseLayer, testcaseModule, testcaseLevel, + testcaseType); + } + + ICunitRunTestcaseSatisfied(&(g_iCunitCaseArray[1]), testcaseLayer, testcaseModule, testcaseLevel, testcaseType); + ICunitRunTestcaseSatisfied(&(g_iCunitCaseArray[0]), testcaseLayer, testcaseModule, testcaseLevel, testcaseType); + } + + return (iUINT32)ICUNIT_SUCCESS; +} + +extern iUINT32 ICunitRunTestcaseOne(ICUNIT_CASE_S *testCase); + +iUINT32 ICunitRunTestOne(const char *tcId) +{ + iUINT32 idx; + iUINT32 idx1; + ICUNIT_CASE_S subCaseArrayTemp; + + (void)memset_s(&subCaseArrayTemp, sizeof(ICUNIT_CASE_S), 0, sizeof(ICUNIT_CASE_S)); + + idx1 = g_iCunitCaseCnt; + + for (idx = 0; idx < idx1; idx++) { + (void)memset_s(&subCaseArrayTemp, sizeof(ICUNIT_CASE_S), 0, sizeof(ICUNIT_CASE_S)); + subCaseArrayTemp = g_iCunitCaseArray[idx]; + + if (strcmp(subCaseArrayTemp.pcCaseID, tcId) == 0) { + ICunitRunTestcaseOne(&g_iCunitCaseArray[idx]); + } + } + + return (iUINT32)ICUNIT_SUCCESS; +} + +iUINT32 ICunitRunTestcaseSatisfied(ICUNIT_CASE_S *testCase, iUINT32 testcaseLayer, iUINT32 testcaseModule, + iUINT32 testcaseLevel, iUINT32 testcaseType) +{ + /* reserve interface to extend */ + if (((testCase->testcase_layer == testcaseLayer) || (testcaseLayer == TEST_LAYER_ALL)) && + ((testCase->testcase_module == testcaseModule) || (testcaseModule == TEST_MODULE_ALL)) && + ((testCase->testcase_level == testcaseLevel) || (testcaseLevel == TEST_LEVEL_ALL)) && + ((testCase->testcase_type == testcaseType) || (testcaseType == TEST_TYPE_ALL))) { + ICunitRunSingle(testCase); + } + + return (iUINT32)ICUNIT_SUCCESS; +} + +iUINT32 ICunitRunTestcaseOne(ICUNIT_CASE_S *testCase) +{ + ICunitRunSingle(testCase); + return (iUINT32)ICUNIT_SUCCESS; +} + + +#ifndef TST_DRVPRINT +iUINT32 PtSaveReport(iCHAR *iCunitReportName, iCHAR *name, iUINT32 value) +{ + return ICUNIT_SUCCESS; +} +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/src/osTest.c b/src/kernel_liteos_a/testsuites/kernel/src/osTest.c new file mode 100644 index 00000000..151a1645 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/src/osTest.c @@ -0,0 +1,509 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "osTest.h" +#include "securec.h" +#ifdef LOSCFG_KERNEL_CPPSUPPORT +#include "los_cppsupport.h" +#endif +#if defined(TEST3518E) || defined(TEST3516A) || defined(TEST3516EV200) +#include "eth_drv.h" +#endif +#if !defined(LOSCFG_AARCH64) && !defined(TESTISP) +#include "console.h" +#else +#include "los_config.h" +#endif +#include "los_sem_pri.h" +#include "los_mux_pri.h" +#include "los_queue_pri.h" +#include "los_swtmr_pri.h" +#include "los_init.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +UINT32 g_shellTestQueueID; + +UINT32 g_testTskHandle; +UINT32 volatile g_testCount; +UINT32 g_flowcheck = 0; +UINT32 g_failResult = 0; +UINT32 g_passResult = 0; + +#ifdef TESTPBXA9 +int snprintf(char *str, unsigned int len, const char *fmt, ...) {} +#endif + +#ifdef TEST1980 +UINT32 g_testhwiFlag; +UINT32 g_testCpuMask; +#endif + +SPIN_LOCK_S g_testSpin; +UINT32 g_testCount1; +UINT32 g_testCount2; +UINT32 g_testCount3; +UINT32 g_testTaskID01; +UINT32 g_testTaskID02; +UINT32 g_testTaskID03; +UINT32 g_testTaskID04; +UINT32 g_hwiNum1; +UINT32 g_hwiNum2; +UINT32 g_semID; +UINT32 g_semID2; +LosMux g_mutexkernelTest; +UINT32 g_cpupTestCount; +UINT32 g_waitTestCount; +UINT32 g_testPeriod; + +UINT16 g_swTmrID; +UINT32 g_testQueueID01; +UINT32 g_testQueueID02; +UINT32 g_testQueueID03; +UINT32 g_leavingTaskNum; +UINT32 g_getTickConsume = 0; +EVENT_CB_S g_eventCB; +EVENT_CB_S g_event; +UINT32 g_testCircleCount = 0; +INT32 g_performanceStart = -1; + +#define MOUNT_PATH NFS_MOUNT_DIR +UINT32 g_fatFilesystem; +UINT8 g_mIndex; +UINT32 g_semID3[LOSCFG_BASE_IPC_SEM_CONFIG + 1]; +LOS_MEM_POOL_STATUS g_sysMemStatus = { 0 }; + +#if TEST_MODULE_CHECK == 1 + +extern UINT32 g_failModelResult[]; +extern UINT32 g_passModelResult[]; +extern UINT32 g_executModelNum[]; +extern ICUNIT_CASE_S g_errorCase[]; +#endif +extern char *g_strLayer[]; +extern char *g_strLevel[]; +extern char *g_strType[]; + +extern char *g_strModule[]; +extern UINT32 g_modelNum; + +#ifdef LOSCFG_TEST_FS_FAT +#define TEST_FAT32 0x02 +#define TEST_EXFAT 0x04 +#endif + +BOOL g_isSpinorInit = FALSE; +BOOL g_isSdInit = FALSE; +BOOL g_isUartDevInit = FALSE; +BOOL g_isTcpipInit = FALSE; +BOOL g_isInitSerial = FALSE; +UINT32 g_vfsCyclesCount = 0; +INT32 g_serialInitFlag = -1; +BOOL g_isAddArray = TRUE; +BOOL g_isUsbInit = FALSE; +BOOL g_isIpcGmacInit = FALSE; + +BOOL g_isDriversRandomInit = FALSE; + +BOOL g_isHisiEthSetPhyModeInit = FALSE; + +BOOL g_isVfsInit = FALSE; + +u_long TRandom(VOID) +{ + u_long t; + long x, hi, lo; + UINT64 cpuCycle; + UINT32 high, low; + extern VOID LOS_GetCpuCycle(UINT32 * puwCntHi, UINT32 * puwCntLo); + LOS_GetCpuCycle(&high, &low); + cpuCycle = (((UINT64)high << 30) + low); // 30, generate a seed. + x = cpuCycle; + hi = x / 127773; // 127773, generate a seed. + lo = x % 127773; // 127773, generate a seed. + t = 16807 * lo - 2836 * hi; // 16807, 2836, generate a seed. + if (t <= 0) + t += 0x7fffffff; + return (u_long)(t); +} + +UINT32 LosMuxCreate(LosMux *mutex) +{ + return LOS_MuxInit(mutex, NULL); +} + +UINT32 TaskCountGetTest(VOID) +{ + UINT32 loop; + UINT32 taskCnt = 0; + UINT32 intSave; + LosTaskCB *taskCB = (LosTaskCB *)NULL; + + intSave = LOS_IntLock(); + for (loop = 0; loop < g_taskMaxNum; loop++) { + taskCB = (((LosTaskCB *)g_taskCBArray) + loop); + if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { + continue; + } + taskCnt++; + } + (VOID)LOS_IntRestore(intSave); + return taskCnt; +} + +UINT32 SemCountGetTest(VOID) +{ + UINT32 loop; + UINT32 semCnt = 0; + UINT32 intSave; + LosSemCB *semNode = (LosSemCB *)NULL; + + intSave = LOS_IntLock(); + for (loop = 0; loop < LOSCFG_BASE_IPC_SEM_CONFIG; loop++) { + semNode = GET_SEM(loop); + if (semNode->semStat == OS_SEM_USED) { + semCnt++; + } + } + (VOID)LOS_IntRestore(intSave); + return semCnt; +} + +UINT32 QueueCountGetTest(VOID) +{ + UINT32 loop; + UINT32 queueCnt = 0; + UINT32 intSave; + LosQueueCB *queueCB = (LosQueueCB *)NULL; + + intSave = LOS_IntLock(); + queueCB = g_allQueue; + for (loop = 0; loop < LOSCFG_BASE_IPC_QUEUE_CONFIG; loop++, queueCB++) { + if (queueCB->queueState == OS_QUEUE_INUSED) { + queueCnt++; + } + } + (VOID)LOS_IntRestore(intSave); + return queueCnt; +} + +UINT32 SwtmrCountGetTest(VOID) +{ + UINT32 loop; + UINT32 swTmrCnt = 0; + UINT32 intSave; + SWTMR_CTRL_S *swTmrCB = (SWTMR_CTRL_S *)NULL; + + intSave = LOS_IntLock(); + swTmrCB = g_swtmrCBArray; + for (loop = 0; loop < LOSCFG_BASE_CORE_SWTMR_CONFIG; loop++, swTmrCB++) { + if (swTmrCB->ucState != OS_SWTMR_STATUS_UNUSED) { + swTmrCnt++; + } + } + (VOID)LOS_IntRestore(intSave); + return swTmrCnt; +} + +#ifdef TEST1980 +VOID TestHwiTrigger(unsigned int irq) +{ + int i; + HalIrqSendIpi(g_testCpuMask, irq); + for (i = 0; i < 0xff; i++) { + } +} +#else +void TestHwiTrigger(unsigned int irq) +{ + extern void Dsb(void); + extern void HalIrqPending(unsigned int vector); + extern VOID HalIrqUnmask(unsigned int vector); + + HalIrqUnmask(irq); + HalIrqPending(irq); + Dsb(); + Dsb(); + Dsb(); +} +#endif + +VOID TestExtraTaskDelay(UINT32 tick) +{ +#ifdef LOSCFG_KERNEL_SMP + // trigger task schedule may occor on another core + // needs adding delay and checking status later + LOS_TaskDelay(tick); +#else + // do nothing +#endif +} + +UINT64 TestTickCountGet(VOID) +{ + /* not use LOS_TickCountGet for now, + cause every timer is not match with others. + use cpu0 timer instead. */ + return LOS_TickCountGet(); +} + +UINT64 TestTickCountByCurrCpuid(VOID) +{ + return LOS_TickCountGet(); +} + +/* + * different from calling LOS_TaskDelay, + * this func will not yield this task to another one. + */ +VOID TestBusyTaskDelay(UINT32 tick) +{ + UINT64 runtime; + + runtime = TestTickCountByCurrCpuid() + tick; + while (1) { + if (runtime <= TestTickCountByCurrCpuid()) { + break; + } + } +} + +VOID TestAssertBusyTaskDelay(UINT32 timeout, UINT32 flag) +{ + UINT64 runtime; + + runtime = TestTickCountGet() + timeout; + while (1) { + if ((runtime <= TestTickCountGet()) || (g_testCount == flag)) { + break; + } + } +} + +VOID TestTestHwiDelete(unsigned int irq, VOID *devId) +{ + HwiIrqParam stuwIrqPara; + + if (OS_INT_ACTIVE) { + return; + } + + stuwIrqPara.swIrq = irq; + stuwIrqPara.pDevId = devId; + + (VOID)LOS_HwiDelete(irq, &stuwIrqPara); + return; +} + +VOID TestDumpCpuid(VOID) +{ +#ifdef LOSCFG_KERNEL_SMP + PRINT_DEBUG("%d,cpuid = %d\n", LOS_CurTaskIDGet(), ArchCurrCpuid()); +#endif + return; +} + +#if defined(LOSCFG_COMPAT_POSIX) +UINT32 PosixPthreadInit(pthread_attr_t *attr, int pri) +{ + UINT32 ret; + struct sched_param sp; + + ret = pthread_attr_init(attr); + ICUNIT_GOTO_EQUAL(ret, 0, ret, NOK); + + attr->inheritsched = PTHREAD_EXPLICIT_SCHED; + + sp.sched_priority = pri; + ret = pthread_attr_setschedparam(attr, &sp); + ICUNIT_GOTO_EQUAL(ret, 0, ret, NOK); + + ret = pthread_attr_setschedpolicy(attr, SCHED_RR); + ICUNIT_GOTO_EQUAL(ret, 0, ret, NOK); + + return LOS_OK; +NOK: + return LOS_NOK; +} + +UINT32 PosixPthreadDestroy(pthread_attr_t *attr, pthread_t thread) +{ + UINT32 ret; + + ret = pthread_join(thread, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, NOK); + + ret = pthread_attr_destroy(attr); + ICUNIT_GOTO_EQUAL(ret, 0, ret, NOK); + + return LOS_OK; +NOK: + return LOS_NOK; +} +#endif + +VOID TestKernelBase(VOID) +{ +#if defined(LOSCFG_TEST_KERNEL_BASE) + ItSuiteLosTask(); + ItSuiteLosSwtmr(); + ItSuiteLosMux(); +#endif +} + +VOID TestPosixMutex(VOID) +{ +#if defined(LOSCFG_TEST_POSIX_MUTEX) + ItSuitePosixMutex(); +#endif +} + +VOID TestPosixPthread(VOID) +{ +#if defined(LOSCFG_TEST_POSIX_PTHREAD) + ItSuitePosixPthread(); +#endif +} + +VOID TestPosix(VOID) +{ +#if defined(LOSCFG_TEST_POSIX) + TestPosixMutex(); + TestPosixPthread(); +#endif +} + +VOID TestKernelExtendCpup(VOID) +{ +#if defined(LOSCFG_TEST_KERNEL_EXTEND_CPUP) + ItSuiteExtendCpup(); +#endif +} + +VOID TestKernelExtend(VOID) +{ +#if defined(LOSCFG_TEST_KERNEL_EXTEND) + TestKernelExtendCpup(); +#endif +} + +VOID TestReset(VOID) +{ +#if defined(TEST3559A) || defined(TEST3559A_M7) || defined(TEST3516EV200) || defined(LOSCFG_LLTREPORT) || \ + defined(LITEOS_3RDPARTY_THTTPD_TEST) || defined(TESTISP) +#else +#ifdef LOSCFG_SHELL + extern VOID cmd_reset(VOID); + cmd_reset(); +#endif +#endif +} + +VOID TestTaskEntry(VOID) +{ + UINT32 i; + + g_testCircleCount = 0; + dprintf("\t\n --- Test start--- \n"); + +#if (TEST_LESSER_MEM == 1) + UINT32 memusedfirst = 0x600000; // 6M for fs or 3M for kernel + LOS_MEM_POOL_STATUS status = { 0 }; + LOS_MemInfoGet(OS_SYS_MEM_ADDR, &status); + LOS_MemAlloc(OS_SYS_MEM_ADDR, status.uwTotalFreeSize - memusedfirst); +#endif + + for (i = 0; i < 1; i++) { + g_testCircleCount++; + ICunitInit(); + + TestKernelExtend(); + TestKernelBase(); + TestPosix(); + +#if (TEST_MODULE_CHECK == 1) + for (int i = 0; i < g_modelNum - 1; i++) { + if (g_executModelNum[i] != 0) { + dprintf("\nExecuted Model: %s, Executed Model_Num: %d ,failed_count: %d , success_count :%d", + g_strModule[i], g_executModelNum[i], g_failModelResult[i], g_passModelResult[i]); + } + for (int j = 0; j < g_failResult && j < 50; j++) { // 50 + if (i == g_errorCase[j].testcase_module) { + LOS_Msleep(200); // 200, delay. + dprintf(" \n [Failed]-%s-%s-%s-%s-%s-[Errline: %d RetCode:0x%04X%04X]", g_errorCase[j].pcCaseID, + g_strLayer[g_errorCase[j].testcase_layer], g_strModule[g_errorCase[j].testcase_module], + g_strLevel[g_errorCase[j].testcase_level], g_strType[g_errorCase[j].testcase_type], + g_errorCase[j].errLine, (iUINT16)((g_errorCase[j].retCode) >> 16), // 16 + (iUINT16)(g_errorCase[j].retCode)); + } + } + } + dprintf("\nNot Executed Model: "); + for (int i = 0; i < g_modelNum - 1; i++) { + if (g_executModelNum[i] == 0) { + LOS_Msleep(40); // 40, delay. + dprintf("%s ", g_strModule[i]); + } + } +#endif + dprintf("\n\ntest_count: %d,failed count: %d, success count: %d\n", g_testCircleCount, g_failResult, + g_passResult); + } + LOS_Msleep(200); // 200, delay. + dprintf("\t\n --- Test End--- \n"); +} + +static void TestSystemInit(void) +{ + TSK_INIT_PARAM_S sysTask; + + (VOID)memset_s(&sysTask, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + sysTask.pfnTaskEntry = (TSK_ENTRY_FUNC)TestTaskEntry; + sysTask.uwStackSize = 0x3000; /* 0x3000: stack size */ + sysTask.pcName = "TestTask"; + sysTask.usTaskPrio = TASK_PRIO_TEST_TASK; + sysTask.uwResved = LOS_TASK_ATTR_JOINABLE; +#ifdef LOSCFG_KERNEL_SMP + sysTask.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + LOS_TaskCreate(&g_testTskHandle, &sysTask); +} + +LOS_MODULE_INIT(TestSystemInit, LOS_INIT_LEVEL_KMOD_TASK); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/kernel_liteos_a/testsuites/kernel/test.mk b/src/kernel_liteos_a/testsuites/kernel/test.mk new file mode 100644 index 00000000..dee9a0a7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/kernel/test.mk @@ -0,0 +1,587 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +TESTLIB_SUBDIRS += kernel +LITEOS_BASELIB += -lktest + +ifeq ($(LOSCFG_TESTSUIT_SHELL), y) +LITEOS_CMACRO += -DLITEOS_TESTSUIT_SHELL +else ifeq ($(LOSCFG_TEST), y) +LITEOS_CMACRO += -DLITEOS_TEST_AUTO +else ifeq ($(LOSCFG_TEST_MANUAL_TEST),y) +LITEOS_CMACRO += -DLOSCFG_TEST_MANUAL_TEST +endif + + +SRC_MODULES := +LLT_MODULES := +SMOKE_MODULES := +PRESSURE_MODULES := +FULL_MODULES := +ifeq ($(LOSCFG_TEST_MUTIL), y) +LITEOS_CMACRO += -DLOSCFG_TEST_MUTIL +LOSCFG_TEST_MUTIL := y +endif + +ifeq ($(LOSCFG_TEST_KERNEL_BASE), y) +LITEOS_CMACRO += -DLOSCFG_TEST_KERNEL_BASE +endif + +ifeq ($(LOSCFG_TEST_KERNEL_BASE_IPC), y) +TESTLIB_SUBDIRS += kernel/sample/kernel_base/ipc +LITEOS_BASELIB += -lipctest +LITEOS_CMACRO += -DLOSCFG_TEST_KERNEL_BASE_IPC +endif + +ifeq ($(LOSCFG_TEST_KERNEL_BASE_CORE), y) +TESTLIB_SUBDIRS += kernel/sample/kernel_base/core +LITEOS_BASELIB += -lcoretest +LITEOS_CMACRO += -DLOSCFG_TEST_KERNEL_BASE_CORE +endif +ifeq ($(LOSCFG_TEST_KERNEL_BASE_MP), y) +TESTLIB_SUBDIRS += kernel/sample/kernel_base/mp +LITEOS_BASELIB += -lmptest +LITEOS_CMACRO += -DLOSCFG_TEST_KERNEL_BASE_MP +endif +ifeq ($(LOSCFG_TEST_KERNEL_BASE_MEM), y) +TESTLIB_SUBDIRS += kernel/sample/kernel_base/mem +LITEOS_BASELIB += -lmemtest +LITEOS_CMACRO += -DLOSCFG_TEST_KERNEL_BASE_MEM +endif +ifeq ($(LOSCFG_TEST_KERNEL_BASE_VM), y) +TESTLIB_SUBDIRS += kernel/sample/kernel_base/vm +LITEOS_BASELIB += -lvmtest +LITEOS_CMACRO += -DLOSCFG_TEST_KERNEL_BASE_VM +endif +ifeq ($(LOSCFG_TEST_KERNEL_BASE_MISC), y) +TESTLIB_SUBDIRS += kernel/sample/kernel_base/misc +LITEOS_BASELIB += -lmisctest +LITEOS_CMACRO += -DLOSCFG_TEST_KERNEL_BASE_MISC +endif +ifeq ($(LOSCFG_TEST_KERNEL_BASE_OM), y) +TESTLIB_SUBDIRS += kernel/sample/kernel_base/om +LITEOS_BASELIB += -lomtest +LITEOS_CMACRO += -DLOSCFG_TEST_KERNEL_BASE_OM +endif +ifeq ($(LOSCFG_TEST_KERNEL_BASE_ATOMIC), y) +TESTLIB_SUBDIRS += kernel/sample/kernel_base/atomic +LITEOS_BASELIB += -latomictest +LITEOS_CMACRO += -DLOSCFG_TEST_KERNEL_BASE_ATOMIC +endif +ifeq ($(LOSCFG_TEST_KERNEL_EXTEND), y) +LITEOS_CMACRO += -DLOSCFG_TEST_KERNEL_EXTEND +endif +ifeq ($(LOSCFG_TEST_KERNEL_EXTEND_CPP), y) +TESTLIB_SUBDIRS += kernel/sample/kernel_extend/cpp +LITEOS_BASELIB += -lcpptest +LITEOS_CMACRO += -DLOSCFG_TEST_KERNEL_EXTEND_CPP +endif +ifeq ($(LOSCFG_TEST_KERNEL_EXTEND_CPUP), y) +TESTLIB_SUBDIRS += kernel/sample/kernel_extend/cpup +LITEOS_BASELIB += -lcpuptest +LITEOS_CMACRO += -DLOSCFG_TEST_KERNEL_EXTEND_CPUP +endif +ifeq ($(LOSCFG_TEST_KERNEL_EXTEND_EXC), y) +TESTLIB_SUBDIRS += kernel/sample/kernel_extend/exc +LITEOS_BASELIB += -lexctest +LITEOS_CMACRO += -DLOSCFG_TEST_KERNEL_EXTEND_EXC +endif +ifeq ($(LOSCFG_TEST_KERNEL_EXTEND_UNALIGNACCESS), y) +TESTLIB_SUBDIRS += kernel/sample/kernel_extend/unalignaccess +LITEOS_BASELIB += -lunalignaccesstest +LITEOS_CMACRO += -DLOSCFG_TEST_KERNEL_EXTEND_UNALIGNACCESS +endif +ifeq ($(LOSCFG_TEST_KERNEL_EXTEND_MMU), y) +TESTLIB_SUBDIRS += kernel/sample/kernel_extend/mmu +LITEOS_BASELIB += -lmmutest +LITEOS_CMACRO += -DLOSCFG_TEST_KERNEL_EXTEND_MMU +endif +ifeq ($(LOSCFG_TEST_KERNEL_EXTEND_DYNLOAD), y) +TESTLIB_SUBDIRS += kernel/sample/kernel_extend/dynload +LITEOS_BASELIB += -ldynloadtest +LITEOS_CMACRO += -DLOSCFG_TEST_KERNEL_EXTEND_DYNLOAD +endif +ifeq ($(LOSCFG_TEST_KERNEL_EXTEND_MPU), y) +TESTLIB_SUBDIRS += kernel/sample/kernel_extend/mpu +LITEOS_BASELIB += -lmputest +LITEOS_CMACRO += -DLOSCFG_TEST_KERNEL_EXTEND_MPU +endif +ifeq ($(LOSCFG_TEST_KERNEL_EXTEND_RUNSTOP), y) +TESTLIB_SUBDIRS += kernel/sample/kernel_extend/runstop +LITEOS_BASELIB += -lrunstoptest +LITEOS_CMACRO += -DLOSCFG_TEST_KERNEL_EXTEND_RUNSTOP +endif +ifeq ($(LOSCFG_TEST_KERNEL_EXTEND_SCATTER), y) +TESTLIB_SUBDIRS += kernel/sample/kernel_extend/scatter +LITEOS_BASELIB += -lscattertest +LITEOS_CMACRO += -DLOSCFG_TEST_KERNEL_EXTEND_SCATTER +endif +ifeq ($(LOSCFG_TEST_KERNEL_EXTEND_TICKLESS), y) +TESTLIB_SUBDIRS += kernel/sample/kernel_extend/tickless +LITEOS_BASELIB += -lticklesstest +LITEOS_CMACRO += -DLOSCFG_TEST_KERNEL_EXTEND_TICKLESS +endif +ifeq ($(LOSCFG_TEST_KERNEL_EXTEND_TRACE), y) +TESTLIB_SUBDIRS += kernel/sample/kernel_extend/trace +LITEOS_BASELIB += -ltracetest +LITEOS_CMACRO += -DLOSCFG_TEST_KERNEL_EXTEND_TRACE +endif + +ifeq ($(LOSCFG_TEST_POSIX), y) +TESTLIB_SUBDIRS += kernel/sample/posix +LITEOS_BASELIB += -lposixtest +LITEOS_CMACRO += -DLOSCFG_TEST_POSIX +endif +ifeq ($(LOSCFG_TEST_POSIX_MEM), y) +TESTLIB_SUBDIRS += kernel/sample/posix/mem +LITEOS_BASELIB += -lmemtest +LITEOS_CMACRO += -DLOSCFG_TEST_POSIX_MEM +endif +ifeq ($(LOSCFG_TEST_POSIX_MQUEUE), y) +TESTLIB_SUBDIRS += kernel/sample/posix/mqueue +LITEOS_BASELIB += -lmqueuetest +LITEOS_CMACRO += -DLOSCFG_TEST_POSIX_MQUEUE +endif +ifeq ($(LOSCFG_TEST_POSIX_MUTEX), y) +TESTLIB_SUBDIRS += kernel/sample/posix/mutex +LITEOS_BASELIB += -lmutextest +LITEOS_CMACRO += -DLOSCFG_TEST_POSIX_MUTEX +endif +ifeq ($(LOSCFG_TEST_POSIX_PTHREAD), y) +TESTLIB_SUBDIRS += kernel/sample/posix/pthread +LITEOS_BASELIB += -lpthreadtest +LITEOS_CMACRO += -DLOSCFG_TEST_POSIX_PTHREAD +endif +ifeq ($(LOSCFG_TEST_POSIX_SCHED), y) +TESTLIB_SUBDIRS += kernel/sample/posix/sched +LITEOS_BASELIB += -lschedtest +LITEOS_CMACRO += -DLOSCFG_TEST_POSIX_SCHED +endif +ifeq ($(LOSCFG_TEST_POSIX_SEM), y) +TESTLIB_SUBDIRS += kernel/sample/posix/sem +LITEOS_BASELIB += -lsemtest +LITEOS_CMACRO += -DLOSCFG_TEST_POSIX_SEM +endif +ifeq ($(LOSCFG_TEST_POSIX_SWTMR), y) +TESTLIB_SUBDIRS += kernel/sample/posix/swtmr +LITEOS_BASELIB += -lswtmrtest +LITEOS_CMACRO += -DLOSCFG_TEST_POSIX_SWTMR +endif +ifeq ($(LOSCFG_TEST_LINUX), y) +TESTLIB_SUBDIRS += kernel/sample/linux +LITEOS_BASELIB += -llinuxtest +LITEOS_CMACRO += -DLOSCFG_TEST_LINUX +endif +ifeq ($(LOSCFG_TEST_LINUX_HRTIMER), y) +TESTLIB_SUBDIRS += kernel/sample/linux/hrtimer +LITEOS_BASELIB += -lhrtimertest +LITEOS_CMACRO += -DLOSCFG_TEST_LINUX +endif + +ifeq ($(LOSCFG_TEST_FS), y) +LITEOS_CMACRO += -DLOSCFG_TEST_FS +endif + +ifeq ($(LOSCFG_TEST_FS_VFS), y) +TESTLIB_SUBDIRS += kernel/sample/fs/vfs +LITEOS_BASELIB += -lvfstest +LITEOS_CMACRO += -DLOSCFG_TEST_FS_VFS +endif + +ifeq ($(LOSCFG_TEST_FS_JFFS), y) +TESTLIB_SUBDIRS += kernel/sample/fs/jffs +LITEOS_BASELIB += -ljffstest +LITEOS_CMACRO += -DLOSCFG_TEST_FS_JFFS +endif + +ifeq ($(LOSCFG_TEST_FS_FAT), y) +TESTLIB_SUBDIRS += kernel/sample/fs/vfat +LITEOS_BASELIB += -lvfattest +LITEOS_CMACRO += -DLOSCFG_TEST_FS_FAT +endif + +ifeq ($(LOSCFG_TEST_FS_FAT_FAT32), y) +LITEOS_CMACRO += -DLOSCFG_TEST_FS_FAT_FAT32 +endif + +ifeq ($(LOSCFG_TEST_FAT32_FSCK), y) +LITEOS_CMACRO += -DLOSCFG_TEST_FAT32_FSCK +endif + +ifeq ($(LOSCFG_TEST_FS_VIRPART), y) +TESTLIB_SUBDIRS += kernel/sample/fs/virpart +LITEOS_BASELIB += -lvirparttest +LITEOS_CMACRO += -DLOSCFG_TEST_FS_VIRPART +endif + +ifeq ($(LOSCFG_TEST_FS_NFS), y) +TESTLIB_SUBDIRS += kernel/sample/fs/nfs +LITEOS_BASELIB += -lnfstest +LITEOS_CMACRO += -DLOSCFG_TEST_FS_NFS +endif + +ifeq ($(LOSCFG_TEST_FS_PROC), y) +TESTLIB_SUBDIRS += kernel/sample/fs/proc +LITEOS_BASELIB += -lproctest +LITEOS_CMACRO += -DLOSCFG_TEST_FS_PROC +endif + +ifeq ($(LOSCFG_TEST_FS_RAMFS), y) +TESTLIB_SUBDIRS += kernel/sample/fs/ramfs +LITEOS_BASELIB += -lramfstest +LITEOS_CMACRO += -DLOSCFG_TEST_FS_RAMFS +endif + +ifeq ($(LOSCFG_TEST_MTD_JFFS), y) +TESTLIB_SUBDIRS += kernel/sample/mtd/spinor/ +LITEOS_BASELIB += -lspinortest +LITEOS_CMACRO += -DLOSCFG_TEST_MTD_JFFS +endif + +ifeq ($(LOSCFG_TEST_MTD_FAT), y) +TESTLIB_SUBDIRS += kernel/sample/mtd/fat +LITEOS_BASELIB += -lfattest +LITEOS_CMACRO += -DLOSCFG_TEST_MTD_FAT +endif + +ifeq ($(LOSCFG_TEST_MTD_DISK), y) +TESTLIB_SUBDIRS += kernel/sample/mtd/disk +LITEOS_BASELIB += -ldisktest +LITEOS_CMACRO += -DLOSCFG_TEST_MTD_DISK +endif + +ifeq ($(LOSCFG_TEST_MTD_FAT_VIRPART), y) +TESTLIB_SUBDIRS += kernel/sample/mtd/dvirpart +LITEOS_BASELIB += -ldvirparttest +LITEOS_CMACRO += -DLOSCFG_TEST_MTD_FAT_VIRPART +endif + +ifeq ($(LOSCFG_TEST_DRIVERBASE), y) +TESTLIB_SUBDIRS += kernel/sample/drivers/base +TESTLIB_SUBDIRS += kernel/sample/drivers/regulator +TESTLIB_SUBDIRS += kernel/sample/drivers/cpufreq +TESTLIB_SUBDIRS += kernel/sample/drivers/devfreq +LITEOS_BASELIB += -lbasetest -lregulatortest -lcpufreqtest -ldevfreqtest +LITEOS_CMACRO += -DLOSCFG_TEST_DRIVER_BASE +endif + +ifeq ($(LOSCFG_TEST_LIBC), y) +TESTLIB_SUBDIRS += kernel/sample/libc +LITEOS_BASELIB += -llibctest +LITEOS_CMACRO += -DLOSCFG_TEST_LIBC +endif + +ifeq ($(LOSCFG_TEST_LIBM), y) +TESTLIB_SUBDIRS += kernel/sample/libm +LITEOS_BASELIB += -llibmtest +LITEOS_CMACRO += -DLOSCFG_TEST_LIBM +endif + +ifeq ($(LOSCFG_TEST_SHELL), y) +TESTLIB_SUBDIRS += kernel/sample/shell +LITEOS_BASELIB += -lshelltest +LITEOS_CMACRO += -DLOSCFG_TEST_SHELL +endif + +ifeq ($(LOSCFG_TEST_HOST_MASS_DEVICE), y) +TESTLIB_SUBDIRS += kernel/sample/performance/usb +LITEOS_BASELIB += -lusbtest +LITEOS_CMACRO += -DLOSCFG_TEST_HOST_MASS_DEVICE +endif + +ifeq ($(LOSCFG_TEST_MMC), y) +TESTLIB_SUBDIRS += kernel/sample/drivers/mmc +LITEOS_BASELIB += -lmmctest +endif + +ifeq ($(LOSCFG_TEST_AUTO_USB), y) +TESTLIB_SUBDIRS += kernel/sample/drivers/usb/auto +LITEOS_BASELIB += -lautotest +endif + +ifeq ($(LOSCFG_TEST_DEVICE_MASS_GADGET), y) +TESTLIB_SUBDIRS += kernel/sample/drivers/usb/storage +LITEOS_BASELIB += -lstoragetest +LITEOS_CMACRO += -DLOSCFG_TEST_DEVICE_MASS_GADGET +endif + +ifeq ($(LOSCFG_TEST_UVC_GADGET), y) +TESTLIB_SUBDIRS += kernel/sample/drivers/usb/uvc +LITEOS_BASELIB += -luvctest +LITEOS_CMACRO += -DLOSCFG_TEST_UVC_GADGET +endif + +ifeq ($(LOSCFG_TEST_SMP_USB), y) +TESTLIB_SUBDIRS += kernel/sample/drivers/usb/usbsmp +LITEOS_BASELIB += -lusbsmptest +LITEOS_CMACRO += -DLOSCFG_TEST_SMP_USB +endif + +ifeq ($(LOSCFG_TEST_UAC_GADGET), y) +TESTLIB_SUBDIRS += kernel/sample/drivers/usb/uac +LITEOS_BASELIB += -luactest +LITEOS_CMACRO += -DLOSCFG_TEST_UAC_GADGET +endif + +ifeq ($(LOSCFG_TEST_CAMERA_GADGET), y) +TESTLIB_SUBDIRS += kernel/sample/drivers/usb/camera +LITEOS_BASELIB += -lcameratest +LITEOS_CMACRO += -DLOSCFG_TEST_CAMERA_GADGET +endif + +ifeq ($(LOSCFG_TEST_HID_GADGET), y) +TESTLIB_SUBDIRS += kernel/sample/drivers/usb/hid +LITEOS_BASELIB += -lhidtest +LITEOS_CMACRO += -DLOSCFG_TEST_HID_GADGET +endif + +ifeq ($(LOSCFG_TEST_HUB_GADGET), y) +TESTLIB_SUBDIRS += kernel/sample/drivers/usb/hub +LITEOS_BASELIB += -lhubtest +LITEOS_CMACRO += -DLOSCFG_TEST_HUB_GADGET +endif + +ifeq ($(LOSCFG_TEST_SERIAL_GADGET), y) +TESTLIB_SUBDIRS += kernel/sample/drivers/usb/serial +LITEOS_BASELIB += -lserialtest +LITEOS_CMACRO += -DLOSCFG_TEST_SERIAL_GADGET +endif + +ifeq ($(LOSCFG_TEST_DFU_GADGET), y) +TESTLIB_SUBDIRS += kernel/sample/drivers/usb/dfu +LITEOS_BASELIB += -ldfutest +LITEOS_CMACRO += -DLOSCFG_TEST_DFU_GADGET +endif + +ifeq ($(LOSCFG_TEST_MUTILDEVICE_GADGET), y) +TESTLIB_SUBDIRS += kernel/sample/drivers/usb/multidevice +LITEOS_BASELIB += -lmultidevicetest +LITEOS_CMACRO += -DLOSCFG_TEST_MUTILDEVICE_GADGET +endif + +ifeq ($(LOSCFG_DRIVERS_USB_ETHERNET_GADGET), y) +TESTLIB_SUBDIRS += kernel/sample/drivers/usb/rndis +LITEOS_BASELIB += -lrndistest +LITEOS_CMACRO += -DLOSCFG_DRIVERS_USB_ETHERNET_GADGET +endif + +ifeq ($(LOSCFG_DRIVERS_USB_HOST_UVC), y) +TESTLIB_SUBDIRS += kernel/sample/drivers/usb/video +LITEOS_BASELIB += -lvideotest +LITEOS_CMACRO += -DLOSCFG_DRIVERS_USB_HOST_UVC +endif + +ifeq ($(LOSCFG_TEST_PERFORMANCE), y) +TESTLIB_SUBDIRS += kernel/sample/performance/kernel +LITEOS_BASELIB += -lperformancetest +LITEOS_CMACRO += -DLOSCFG_TEST_PERFORMANCE +ifeq ($(LOSCFG_TEST_PERFORMANCE_CORE), y) +LITEOS_CMACRO += -DLOSCFG_TEST_PERFORMANCE_CORE +endif +ifeq ($(LOSCFG_TEST_PERFORMANCE_MEM), y) +LITEOS_CMACRO += -DLOSCFG_TEST_PERFORMANCE_MEM +endif +ifeq ($(LOSCFG_TEST_PERFORMANCE_FS), y) +LITEOS_CMACRO += -DLOSCFG_TEST_PERFORMANCE_FS +endif +ifeq ($(LOSCFG_TEST_PERFORMANCE_USB), y) +LITEOS_CMACRO += -DLOSCFG_TEST_PERFORMANCE_USB +endif +ifeq ($(LOSCFG_TEST_PERFORMANCE_NET), y) +LITEOS_CMACRO += -DLOSCFG_TEST_PERFORMANCE_NET +endif +endif + +ifeq ($(LOSCFG_TEST_NET), y) + LITEOS_CMACRO += -DTEST_NET + ifeq ($(LOSCFG_PLATFORM_HI3559)$(LOSCFG_ARCH_CORTEX_A17), yy) + LITEOS_BASELIB += -lipcm -lipcm_net + endif + LITEOS_BASELIB += -lnettest + TESTLIB_SUBDIRS += kernel/sample/net +endif + +ifeq ($(LOSCFG_TEST_LWIP), y) + LITEOS_CMACRO += -DTEST_LWIP + LITEOS_BASELIB += -llwiptest +ifeq ($(LOSCFG_NET_LWIP_SACK_2_0), y) + TESTLIB_SUBDIRS += kernel/sample/lwip-2.0 +else + TESTLIB_SUBDIRS += kernel/sample/lwip +endif +endif + +ifeq ($(LOSCFG_TEST_PLATFORM), y) +TESTLIB_SUBDIRS += kernel/sample/platform +LITEOS_BASELIB += -lplatformtest +LITEOS_CMACRO += -DLOSCFG_TEST_PLATFORM +endif + +ifeq ($(LOSCFG_FUZZ_DT), y) +TESTLIB_SUBDIRS += kernel/sample/fuzz +LITEOS_BASELIB += -lfuzzDTtest +LITEOS_CMACRO += -DLOSCFG_FUZZ_DT +endif + +ifeq ($(LOSCFG_TEST_MANUAL_TEST), y) +TESTLIB_SUBDIRS += kernel/sample/kernel_base/ipc +LITEOS_BASELIB += -lipctest +LITEOS_CMACRO += -DLOSCFG_TEST_MANUAL_TEST +endif + +ifeq ($(LOSCFG_3RDPARTY_TEST), y) + LITEOS_CMACRO += -DLOSCFG_3RDPARTY_TEST + ifeq ($(LOSCFG_3RDPARTY_TINYXML), y) + LITEOS_BASELIB += -ltinyxmltest + LITEOS_CMACRO += -DLOSCFG_3RDPARTY_TINYXML_TEST + TESTLIB_SUBDIRS += kernel/sample/3rdParty/tinyxml + endif + + ifeq ($(LOSCFG_3RDPARTY_INIPARSER), y) + LITEOS_BASELIB += -liniparsertest + LITEOS_CMACRO += -DLOSCFG_3RDPARTY_INIPARSER_TEST + TESTLIB_SUBDIRS += kernel/sample/3rdParty/iniparser + endif + + ifeq ($(LOSCFG_3RDPARTY_CJSON), y) + LITEOS_BASELIB += -lcJSONtest + LITEOS_CMACRO += -DLOSCFG_3RDPARTY_CJSON_TEST + TESTLIB_SUBDIRS += kernel/sample/3rdParty/cJSON + endif + + ifeq ($(LOSCFG_3RDPARTY_ICONV), y) + LITEOS_BASELIB += -liconvtest + LITEOS_CMACRO += -DLITEOS_3RDPARTY_ICONV_TEST + TESTLIB_SUBDIRS += kernel/sample/3rdParty/iconv + endif + + ifeq ($(LOSCFG_3RDPARTY_OPENSSL), y) + LITEOS_BASELIB += -lopenssltest + LITEOS_CMACRO += -DLITEOS_3RDPARTY_OPENSSL_TEST + TESTLIB_SUBDIRS += kernel/sample/3rdParty/openssl + endif + + ifeq ($(LOSCFG_3RDPARTY_OPUS), y) + LITEOS_BASELIB += -lopustest + LITEOS_CMACRO += -DLITEOS_3RDPARTY_OPUS_TEST + TESTLIB_SUBDIRS += kernel/sample/3rdParty/opus + endif + + ifeq ($(LOSCFG_3RDPARTY_BIDIREFC), y) + LITEOS_BASELIB += -lbidirefctest + LITEOS_CMACRO += -DLITEOS_3RDPARTY_BIDIREFC_TEST + TESTLIB_SUBDIRS += kernel/sample/3rdParty/bidirefc + endif + + ifeq ($(LOSCFG_3RDPARTY_FREETYPE), y) + LITEOS_BASELIB += -lfreetypetest + LITEOS_CMACRO += -DLITEOS_3RDPARTY_FREETYPE_TEST + TESTLIB_SUBDIRS += kernel/sample/3rdParty/freetype + endif + + ifeq ($(LOSCFG_3RDPARTY_JSONCPP), y) + LITEOS_BASELIB += -ljsoncpptest + LITEOS_CMACRO += -DLITEOS_3RDPARTY_JSONCPP_TEST + TESTLIB_SUBDIRS += kernel/sample/3rdParty/jsoncpp + endif + + ifeq ($(LOSCFG_3RDPARTY_THTTPD), y) + LITEOS_BASELIB += -lthttpdtest + LITEOS_CMACRO += -DLITEOS_3RDPARTY_THTTPD_TEST + TESTLIB_SUBDIRS += kernel/sample/3rdParty/thttpd + endif + + ifeq ($(LOSCFG_3RDPARTY_SQLITE), y) + LITEOS_BASELIB += -lsqlitetest + LITEOS_CMACRO += -DLITEOS_3RDPARTY_SQLITE_TEST + TESTLIB_SUBDIRS += kernel/sample/3rdParty/sqlite + endif + + ifeq ($(LOSCFG_3RDPARTY_FFMPEG), y) + LITEOS_BASELIB += -lffmpegtest + LITEOS_CMACRO += -DLITEOS_3RDPARTY_FFMPEG_TEST + TESTLIB_SUBDIRS += kernel/sample/3rdParty/ffmpeg + endif + + ifeq ($(LOSCFG_3RDPARTY_LUA), y) + LITEOS_BASELIB += -lluatest + LITEOS_CMACRO += -DLITEOS_3RDPARTY_LUA_TEST + TESTLIB_SUBDIRS += kernel/sample/3rdParty/lua + endif + + ifeq ($(LOSCFG_3RDPARTY_DIRECTFB), y) + LITEOS_BASELIB += -ldirectfbtest + LITEOS_CMACRO += -DLITEOS_3RDPARTY_DIRECTFB_TEST + TESTLIB_SUBDIRS += kernel/sample/3rdParty/directfb + endif + + ifeq ($(LOSCFG_3RDPARTY_JPEG), y) + LITEOS_BASELIB += -ljpegtest + LITEOS_CMACRO += -DLOSCFG_3RDPARTY_JPEG_TEST + TESTLIB_SUBDIRS += kernel/sample/3rdParty/jpeg + endif + + ifeq ($(LOSCFG_3RDPARTY_PNG), y) + LITEOS_BASELIB += -lpngtest + LITEOS_CMACRO += -DLOSCFG_3RDPARTY_PNG_TEST + TESTLIB_SUBDIRS += kernel/sample/3rdParty/png + endif + + ifeq ($(LOSCFG_3RDPARTY_OPENEXIFJPEG), y) + LITEOS_BASELIB += -lOpenExifJpegtest + LITEOS_CMACRO += -DLOSCFG_3RDPARTY_OPENEXIFJPEG_TEST + TESTLIB_SUBDIRS += kernel/sample/3rdParty/OpenExifJpeg + endif + + ifeq ($(LOSCFG_3RDPARTY_XML2), y) + LITEOS_BASELIB += -lxml2test + LITEOS_CMACRO += -DLITEOS_3RDPARTY_XML2_TEST + TESTLIB_SUBDIRS += kernel/sample/3rdParty/xml2 + endif + + ifeq ($(LOSCFG_3RDPARTY_ZBAR), y) + LITEOS_BASELIB += -lzbartest + LITEOS_CMACRO += -DLITEOS_3RDPARTY_ZBAR_TEST + TESTLIB_SUBDIRS += kernel/sample/3rdParty/zbar + endif + + ifeq ($(LOSCFG_3RDPARTY_HARFBUZZ), y) + LITEOS_BASELIB += -lharfbuzztest + LITEOS_CMACRO += -DLOSCFG_3RDPARTY_HARFBUZZ_TEST + TESTLIB_SUBDIRS += kernel/sample/3rdParty/harfbuzz + endif + + ifeq ($(LOSCFG_3RDPARTY_CURL), y) + LITEOS_LD_OPTS += -ucurl_shellcmd + LITEOS_BASELIB += -lcurltest + LITEOS_CMACRO += -DLITEOS_3RDPARTY_CURL_TEST + TESTLIB_SUBDIRS += kernel/sample/3rdParty/curl + endif +endif + diff --git a/src/kernel_liteos_a/testsuites/unittest/BUILD.gn b/src/kernel_liteos_a/testsuites/unittest/BUILD.gn new file mode 100644 index 00000000..b1ebb922 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/BUILD.gn @@ -0,0 +1,204 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("config.gni") + +local_flags = [ + "-fpermissive", + "-O2", + "-fbuiltin", + "-Wno-narrowing", + "-fPIE", + "-Wno-error", +] +if (LOSCFG_USER_TEST_SMP == "enable" || + (LOSCFG_USER_TEST_SMP == "default" && board_name == "hispark_taurus")) { + local_flags += [ "-DLOSCFG_USER_TEST_SMP" ] +} + +config("public_config_for_door") { + cflags = [ "-DLOSCFG_USER_TEST_SMOKE" ] + cflags += local_flags + cflags_cc = cflags +} + +config("public_config_for_all") { + cflags = [ + "-DLOSCFG_USER_TEST_SMOKE", + "-DLOSCFG_USER_TEST_FULL", + ] + cflags += local_flags + cflags_cc = cflags +} + +config("public_config_for_pressure") { + cflags = [ "-DLOSCFG_USER_TEST_PRESSURE" ] + cflags += local_flags + cflags_cc = cflags +} + +# Note: The execution time of a single XXX_door.bin cannot exceed 90 seconds. +group("unittest") { + deps = [] + if (ohos_build_type == "debug") { + deps += [ "tools:liteos_unittest_run" ] + + # basic test + if (LOSCFG_USER_TEST_BASIC == true) { + if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_LOW) { + deps += [ "basic:liteos_a_basic_unittest_door" ] + } + if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_MIDDLE) { + deps += [ "basic:liteos_a_basic_unittest" ] + } + } + + # drivers test + if (LOSCFG_USER_TEST_DRIVERS == true) { + if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_LOW) { + deps += [ "drivers:liteos_a_drivers_unittest_door" ] + } + if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_MIDDLE) { + deps += [ "drivers:liteos_a_drivers_unittest" ] + } + } + + # extended test + if (LOSCFG_USER_TEST_EXTENDED == true) { + if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_LOW) { + deps += [ "extended:liteos_a_extended_unittest_door" ] + } + if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_MIDDLE) { + deps += [ "extended:liteos_a_extended_unittest" ] + } + } + + # fs test + if (LOSCFG_USER_TEST_FS == true) { + if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_LOW) { + deps += [ "fs:liteos_a_fs_unittest_door" ] + } + if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_MIDDLE) { + deps += [ "fs:liteos_a_fs_unittest" ] + } + if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_HIGH) { + deps += [ "fs:liteos_a_fs_unittest_pressure" ] + } + } + + # libc test + if (LOSCFG_USER_TEST_LIBC == true) { + if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_LOW) { + deps += [ + "libc/io:liteos_a_libc_io_unittest_door", + "libc/misc:liteos_a_libc_misc_unittest_door", + "libc/posix:liteos_a_libc_posix_unittest_door", + "libc/sys:liteos_a_libc_sys_unittest_door", + "libc/time:liteos_a_libc_time_unittest_door", + "libc/util:liteos_a_libc_util_unittest_door", + ] + } + if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_MIDDLE) { + deps += [ + "libc/io:liteos_a_libc_io_unittest", + "libc/misc:liteos_a_libc_misc_unittest", + "libc/posix:liteos_a_libc_posix_unittest", + "libc/sys:liteos_a_libc_sys_unittest", + "libc/time:liteos_a_libc_time_unittest", + "libc/util:liteos_a_libc_util_unittest", + ] + } + } + + # net test + if (LOSCFG_USER_TEST_NET == true) { + if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_LOW) { + deps += [ "net:liteos_a_net_unittest_door" ] + } + if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_MIDDLE) { + deps += [ "net:liteos_a_net_unittest" ] + } + } + + # process test + if (LOSCFG_USER_TEST_PROCESS_THREAD == true) { + if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_LOW) { + deps += [ + "process/basic/process:liteos_a_process_basic_process_unittest_door", + "process/basic/pthread:liteos_a_process_basic_pthread_unittest_door", + "process/lock:liteos_a_process_lock_unittest_door", + ] + if (LOSCFG_USER_TEST_PROCESS_FS == true) { + deps += [ "process/fs:liteos_a_process_fs_unittest_door" ] + } + if (LOSCFG_USER_TEST_PROCESS_PLIMITS == true) { + deps += [ "process/plimits:liteos_a_process_plimits_unittest_door" ] + } + } + if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_MIDDLE) { + deps += [ + "process/basic/process:liteos_a_process_basic_process_unittest", + "process/basic/pthread:liteos_a_process_basic_pthread_unittest", + "process/lock:liteos_a_process_lock_unittest", + ] + if (LOSCFG_USER_TEST_PROCESS_FS == true) { + deps += [ "process/fs:liteos_a_process_fs_unittest" ] + } + if (LOSCFG_USER_TEST_PROCESS_PLIMITS == true) { + deps += [ "process/plimits:liteos_a_process_plimits_unittest" ] + } + } + } + + # security test + if (LOSCFG_USER_TEST_SECURITY == true) { + if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_LOW) { + deps += [ "security:liteos_a_security_unittest_door" ] + } + if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_MIDDLE) { + deps += [ "security:liteos_a_security_unittest" ] + } + } + + # container test + if (LOSCFG_USER_TEST_CONTAINER == true) { + if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_LOW) { + deps += [ "container:liteos_a_container_unittest_door" ] + } + if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_MIDDLE) { + deps += [ "container:liteos_a_container_unittest" ] + } + } + + # fuzz test + if (LOSCFG_USER_FUZZ_TEST == true) { + deps += [ "fuzz:liteos_a_fuzztest" ] + } + } +} diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/BUILD.gn b/src/kernel_liteos_a/testsuites/unittest/basic/BUILD.gn new file mode 100644 index 00000000..bf8ff3e5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/BUILD.gn @@ -0,0 +1,56 @@ +# Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("./config.gni") + +if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_LOW) { + unittest("liteos_a_basic_unittest_door") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + include_dirs = common_include_dirs + sources = sources_entry + sources += sources_smoke + sources_full = [] + sources += sources_full + configs = [ "..:public_config_for_door" ] + deps = [ "$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR:libsec_shared" ] + } +} + +if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_MIDDLE) { + unittest("liteos_a_basic_unittest") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + include_dirs = common_include_dirs + sources = sources_entry + sources += sources_smoke + sources += sources_full + configs = [ "..:public_config_for_all" ] + deps = [ "$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR:libsec_shared" ] + } +} diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/config.gni b/src/kernel_liteos_a/testsuites/unittest/basic/config.gni new file mode 100644 index 00000000..8f372411 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/config.gni @@ -0,0 +1,77 @@ +# Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//build/lite/config/test.gni") +import("//kernel/liteos_a/liteos.gni") +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +common_include_dirs = [ + "$THIRDPARTY_GOOGLETEST_DIR/googletest/include", + "../common/include", +] + +sources_entry = [ "../common/osTest.cpp" ] + +sources_smoke = [] + +sources_full = [] + +# dynload module +if (LOSCFG_USER_TEST_DYNLOAD == true) { + import("./dynload/config.gni") + common_include_dirs += dynload_include_dirs + sources_entry += dynload_sources_entry + sources_smoke += dynload_sources_smoke + sources_full += dynload_sources_full +} + +# exc module +if (LOSCFG_USER_TEST_EXC == true) { + import("./exc/config.gni") + common_include_dirs += exc_include_dirs + sources_entry += exc_sources_entry + sources_smoke += exc_sources_smoke + sources_full += exc_sources_full +} + +# mem module +if (LOSCFG_USER_TEST_MEM_SHM == true) { + import("./mem/shm/config.gni") + common_include_dirs += mem_shm_include_dirs + sources_entry += mem_shm_sources_entry + sources_smoke += mem_shm_sources_smoke + sources_full += mem_shm_sources_full +} + +if (LOSCFG_USER_TEST_MEM_VM == true) { + import("./mem/vm/config.gni") + common_include_dirs += mem_vm_include_dirs + sources_entry += mem_vm_sources_entry + sources_smoke += mem_vm_sources_smoke + sources_full += mem_vm_sources_full +} diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/dynload/config.gni b/src/kernel_liteos_a/testsuites/unittest/basic/dynload/config.gni new file mode 100644 index 00000000..58d5b847 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/dynload/config.gni @@ -0,0 +1,40 @@ +# Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +dynload_include_dirs = [ "$TEST_UNITTEST_DIR/basic/dynload" ] + +dynload_sources_entry = [ "$TEST_UNITTEST_DIR/basic/dynload/dynload_test.cpp" ] + +dynload_sources_smoke = [ + "$TEST_UNITTEST_DIR/basic/dynload/smoke/dynload_test_002.cpp", + "$TEST_UNITTEST_DIR/basic/dynload/smoke/dynload_test_004.cpp", +] + +dynload_sources_full = [] diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/dynload/dynload_test.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/dynload/dynload_test.cpp new file mode 100644 index 00000000..68589549 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/dynload/dynload_test.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include + +#include "it_test_dynload.h" + +using namespace testing::ext; +namespace OHOS { +class DynloadTest : public testing::Test { +public: + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} +}; + +#if defined(LOSCFG_USER_TEST_SMOKE) +/* * + * @tc.name: it_test_dynload_002 + * @tc.desc: function for DynloadTest + * @tc.type: FUNC + */ +HWTEST_F(DynloadTest, ItTestDynload002, TestSize.Level0) +{ + ItTestDynload002(); +} + +/* * + * @tc.name: it_test_dynload_004 + * @tc.desc: function for DynloadTest + * @tc.type: FUNC + */ +HWTEST_F(DynloadTest, ItTestDynload004, TestSize.Level0) +{ + ItTestDynload004(); +} +#endif +} // namespace OHOS diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/dynload/it_test_dynload.h b/src/kernel_liteos_a/testsuites/unittest/basic/dynload/it_test_dynload.h new file mode 100644 index 00000000..50f33c37 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/dynload/it_test_dynload.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _IT_TEST_DYNLOAD_H +#define _IT_TEST_DYNLOAD_H + +#include "osTest.h" +#include +#include + +extern void ItTestDynload002(void); +extern void it_test_dynload_003(void); +extern void ItTestDynload004(void); +#endif diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/dynload/smoke/dynload_test_002.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/dynload/smoke/dynload_test_002.cpp new file mode 100644 index 00000000..717ca316 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/dynload/smoke/dynload_test_002.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_dynload.h" +#include + +#define LIBCSO_REAL_PATH "/lib/libc.so" +#define LIBCSO_RELATIVE_PATH "../../lib/libc.so" +#define SYMBOL_TO_FIND "printf" +#define SYMBOL_TO_MATCH (void *)printf + +static int Testcase(void) +{ + int ret; + char *workingPath = "/usr/bin"; + void *handle = nullptr; + int (*func)(int); + char curPath[1024] = { 0 }; /* 1024, buffer size */ + + handle = getcwd(curPath, sizeof(curPath)); + ICUNIT_ASSERT_NOT_EQUAL(handle, NULL, handle); + + ret = chdir(workingPath); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + handle = dlopen(NULL, RTLD_NOW | RTLD_LOCAL); + ICUNIT_GOTO_NOT_EQUAL(handle, NULL, 1, EXIT1); /* 1, return value */ + + ret = dlclose(handle); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + handle = dlopen(LIBCSO_REAL_PATH, RTLD_NOW); + ICUNIT_GOTO_NOT_EQUAL(handle, NULL, 1, EXIT1); /* 1, return value */ + + func = reinterpret_cast(dlsym(handle, SYMBOL_TO_FIND)); + ICUNIT_GOTO_NOT_EQUAL(func, NULL, func, EXIT); + ICUNIT_GOTO_EQUAL(func, SYMBOL_TO_MATCH, func, EXIT); + + ret = dlclose(handle); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + handle = dlopen(LIBCSO_RELATIVE_PATH, RTLD_NOW); + ICUNIT_GOTO_NOT_EQUAL(handle, NULL, 1, EXIT1); /* 1, return value */ + + func = reinterpret_cast(dlsym(handle, SYMBOL_TO_FIND)); + ICUNIT_GOTO_NOT_EQUAL(func, NULL, func, EXIT); + + ret = dlclose(handle); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = chdir(curPath); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT1); + + return 0; + +EXIT: + dlclose(handle); + +EXIT1: + ret = chdir(curPath); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return 1; /* 1, return value */ +} + +void ItTestDynload002(void) +{ + TEST_ADD_CASE("IT_TEST_DYNLOAD_002", Testcase, TEST_EXTEND, TEST_DYNLOAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/dynload/smoke/dynload_test_004.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/dynload/smoke/dynload_test_004.cpp new file mode 100644 index 00000000..9ff3ab7f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/dynload/smoke/dynload_test_004.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_dynload.h" +#include + +#define LIBCSO_REAL_PATH "/lib/libc.so" +#define INVALID_MODE (-1) +#define MODE_WITHOUT_NOW_AND_LAZY (RTLD_NOLOAD | RTLD_GLOBAL | RTLD_LOCAL | RTLD_NODELETE) +#define INVALID_FILENAME (char *)((void *)0) + +static int Testcase(void) +{ + int ret; + void *handle = nullptr; + + handle = dlopen(LIBCSO_REAL_PATH, 0); + ICUNIT_ASSERT_EQUAL(handle, NULL, handle); + + handle = dlopen(LIBCSO_REAL_PATH, INVALID_MODE); + ICUNIT_ASSERT_EQUAL(handle, NULL, handle); + + handle = dlopen(LIBCSO_REAL_PATH, MODE_WITHOUT_NOW_AND_LAZY); + ICUNIT_ASSERT_EQUAL(handle, NULL, handle); + + handle = dlopen(INVALID_FILENAME, 0); + ICUNIT_ASSERT_EQUAL(handle, NULL, handle); + + handle = dlopen(INVALID_FILENAME, INVALID_MODE); + ICUNIT_ASSERT_EQUAL(handle, NULL, handle); + + handle = dlopen(INVALID_FILENAME, MODE_WITHOUT_NOW_AND_LAZY); + ICUNIT_ASSERT_EQUAL(handle, NULL, handle); + + handle = dlopen(INVALID_FILENAME, RTLD_NOW); + ICUNIT_ASSERT_NOT_EQUAL(handle, NULL, handle); + + ret = dlclose(handle); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return 0; +} + +void ItTestDynload004(void) +{ + TEST_ADD_CASE("IT_TEST_DYNLOAD_004", Testcase, TEST_EXTEND, TEST_DYNLOAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/exc/config.gni b/src/kernel_liteos_a/testsuites/unittest/basic/exc/config.gni new file mode 100644 index 00000000..8609fc81 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/exc/config.gni @@ -0,0 +1,44 @@ +# Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +exc_include_dirs = [ "$TEST_UNITTEST_DIR/basic/exc" ] + +exc_sources_entry = [ "$TEST_UNITTEST_DIR/basic/exc/exc_test.cpp" ] + +exc_sources_smoke = [ + "$TEST_UNITTEST_DIR/basic/exc/smoke/it_test_exc_001.cpp", + "$TEST_UNITTEST_DIR/basic/exc/smoke/it_test_exc_002.cpp", + "$TEST_UNITTEST_DIR/basic/exc/smoke/it_test_exc_003.cpp", + "$TEST_UNITTEST_DIR/basic/exc/smoke/it_test_exc_004.cpp", + "$TEST_UNITTEST_DIR/basic/exc/smoke/it_test_exc_005.cpp", +] + +exc_sources_full = + [ "$TEST_UNITTEST_DIR/basic/exc/full/it_test_fexecve_001.cpp" ] diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/exc/exc_test.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/exc/exc_test.cpp new file mode 100644 index 00000000..b0175cb6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/exc/exc_test.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include + +#include "it_test_exc.h" + +using namespace testing::ext; +namespace OHOS { +class ExcTest : public testing::Test { +public: + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} +}; + +#if defined(LOSCFG_USER_TEST_SMOKE) +/* * + * @tc.name: ItTestExc005 + * @tc.desc: function for ExcTest + * @tc.type: FUNC + */ +HWTEST_F(ExcTest, ItTestExc005, TestSize.Level0) +{ + ItTestExc005(); +} + +/* * + * @tc.name: ItTestExc001 + * @tc.desc: function for ExcTest + * @tc.type: FUNC + */ +HWTEST_F(ExcTest, ItTestExc001, TestSize.Level0) +{ + ItTestExc001(); +} + +/* * + * @tc.name: ItTestExc002 + * @tc.desc: function for ExcTest + * @tc.type: FUNC + */ +HWTEST_F(ExcTest, ItTestExc002, TestSize.Level0) +{ + ItTestExc002(); +} + +/* * + * @tc.name: ItTestExc003 + * @tc.desc: function for ExcTest + * @tc.type: FUNC + */ +HWTEST_F(ExcTest, ItTestExc003, TestSize.Level0) +{ + ItTestExc003(); +} + +/* * + * @tc.name: ItTestExc004 + * @tc.desc: function for ExcTest + * @tc.type: FUNC + */ +HWTEST_F(ExcTest, ItTestExc004, TestSize.Level0) +{ + ItTestExc004(); +} +#endif +} // namespace OHOS diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/exc/full/it_test_fexecve_001.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/exc/full/it_test_fexecve_001.cpp new file mode 100644 index 00000000..af175ad8 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/exc/full/it_test_fexecve_001.cpp @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#define __USE_GUN +#include "it_test_exc.h" +#include +#include +#include +#include +#include +#include + +static char *g_args[] = { + "hic et nunc", + "-l", + "/dev/shm", + nullptr +}; + +static int TestCase(void) +{ + struct stat st = {0}; + void *p = nullptr; + int fd = 0; + int shmFd = 0; + int rc = 0; + int ret = 0; + + shmFd = shm_open("wurstverschwendung", O_RDWR | O_CREAT, 0777); + if (shmFd == -1) { + perror("shm_open"); + return -1; + } + + rc = stat("/bin/shell", &st); + if (rc == -1) { + perror("stat"); + close(shmFd); + return -1; + } + + printf("shm_fd=%d,st.st_size=%lld\n", shmFd, st.st_size); + rc = ftruncate(shmFd, st.st_size); + if (rc == -1) { + perror("ftruncate"); + close(shmFd); + return -1; + } + + p = mmap(nullptr, st.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, shmFd, 0); + if (p == MAP_FAILED) { + perror("mmap"); + close(shmFd); + return -1; + } + + fd = open("/bin/shell", O_RDONLY, 0); + printf("fd=%d\n", fd); + if (fd == -1) { + perror("openls"); + munmap(p, st.st_size); + close(shmFd); + return -1; + } + + rc = read(fd, p, st.st_size); + if (rc == -1) { + perror("read"); + munmap(p, st.st_size); + close(shmFd); + return -1; + } + if (rc != st.st_size) { + fputs("Strange situation!\n", stderr); + munmap(p, st.st_size); + close(shmFd); + return -1; + } + + munmap(p, st.st_size); + close(shmFd); + + shmFd = shm_open("wurstverschwendung", O_RDONLY, 0); + ret = fexecve(shmFd, g_args, environ); + perror("fexecve"); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret); + + return LOS_OK; +} + +void ItTestFexecve001(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/exc/it_test_exc.h b/src/kernel_liteos_a/testsuites/unittest/basic/exc/it_test_exc.h new file mode 100644 index 00000000..e204898e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/exc/it_test_exc.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _IT_TEST_EXC_H +#define _IT_TEST_EXC_H + +#include "osTest.h" + +#define INVALID_PROCESS_ID 100000 +extern void ItTestExc001(void); +extern void ItTestExc002(void); +extern void ItTestExc003(void); +extern void ItTestExc004(void); +extern void ItTestExc005(void); +extern void ItTestFexecve001(void); + +#endif diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/exc/smoke/it_test_exc_001.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/exc/smoke/it_test_exc_001.cpp new file mode 100644 index 00000000..1d88aa34 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/exc/smoke/it_test_exc_001.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_exc.h" + +__attribute__((optnone)) static int TestCase(void) +{ + int ret; + int status = 0; + int *test = NULL; // for trggering an exception + pid_t pid = fork(); + ICUNIT_ASSERT_WITHIN_EQUAL(pid, 0, INVALID_PROCESS_ID, pid); + if (pid == 0) { + *test = 0x1; // Deliberately trigger an exceptioin + exit(0); + } + + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ret = WIFEXITED(status); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = WIFSIGNALED(status); + ICUNIT_ASSERT_EQUAL(ret, 1, ret); + ret = WTERMSIG(status); + ICUNIT_ASSERT_EQUAL(ret, SIGUSR2, ret); + + pid = fork(); + ICUNIT_ASSERT_WITHIN_EQUAL(pid, 0, INVALID_PROCESS_ID, pid); + if (pid == 0) { + *test = 0x1; // Deliberately trigger an exceptioin + exit(0); + } + + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ret = WIFEXITED(status); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = WIFSIGNALED(status); + ICUNIT_ASSERT_EQUAL(ret, 1, ret); + ret = WTERMSIG(status); + ICUNIT_ASSERT_EQUAL(ret, SIGUSR2, ret); + + return 0; +} + +void ItTestExc001(void) +{ + TEST_ADD_CASE("IT_TEST_EXC_001", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/exc/smoke/it_test_exc_002.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/exc/smoke/it_test_exc_002.cpp new file mode 100644 index 00000000..80b9fe06 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/exc/smoke/it_test_exc_002.cpp @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_exc.h" +#include "pthread.h" + +__attribute__((optnone)) static void *ThreadFunc2(void *arg) +{ + while (1) { + } + + return nullptr; +} + +__attribute__((optnone)) static void *ThreadFunc1(void *arg) +{ + int *test = nullptr; + *test = 0x1; + + while (1) { + } + return nullptr; +} + +static int TestThread(void) +{ + pthread_t newThread; + int ret; + int currThreadPolicy = 3; + int currThreadPri; + pthread_attr_t a = { 0 }; + struct sched_param param = { 0 }; + int count = 5; + while (count > 0) { + ret = pthread_create(&newThread, nullptr, ThreadFunc2, nullptr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + count--; + } + + ret = pthread_getschedparam(pthread_self(), &currThreadPolicy, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + currThreadPri = param.sched_priority; + + ret = pthread_attr_init(&a); + param.sched_priority = currThreadPri - 1; + pthread_attr_setschedparam(&a, ¶m); + ret = pthread_create(&newThread, &a, ThreadFunc1, nullptr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return 0; +} + + +__attribute__((optnone)) static int TestCase(void) +{ + int *test = nullptr; + int count = 5; + int status = 0; + int ret; + pid_t pid = fork(); + ICUNIT_ASSERT_WITHIN_EQUAL(pid, 0, INVALID_PROCESS_ID, pid); + if (pid == 0) { + (void)TestThread(); + while (1) { + } + } + + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ret = WIFEXITED(status); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = WIFSIGNALED(status); + ICUNIT_ASSERT_EQUAL(ret, 1, ret); + ret = WTERMSIG(status); + ICUNIT_ASSERT_EQUAL(ret, SIGUSR2, ret); + + return 0; +} + +void ItTestExc002(void) +{ + TEST_ADD_CASE("IT_TEST_EXC_002", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/exc/smoke/it_test_exc_003.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/exc/smoke/it_test_exc_003.cpp new file mode 100644 index 00000000..cef01003 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/exc/smoke/it_test_exc_003.cpp @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_exc.h" +#include "pthread.h" + +#define TEST_THREAD_COUNT 5 +static volatile int g_testCondFlag; +static int g_count[TEST_THREAD_COUNT]; + +__attribute__((optnone)) static void *ThreadFunc2(void *arg) +{ + int count = *(int *)arg; + int *test = nullptr; + + g_testCondFlag++; + + while (g_testCondFlag < 2) { /* 2, no special meaning */ + } + + *test = 0x1; + + while (1) { + } + + return nullptr; +} + +static int TestThread(void) +{ + pthread_t newThread; + int ret; + int currThreadPolicy = 3; + int currThreadPri; + pthread_attr_t a = { 0 }; + struct sched_param param = { 0 }; + int count = 0; + + ret = pthread_getschedparam(pthread_self(), &currThreadPolicy, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + currThreadPri = param.sched_priority; + + ret = pthread_attr_init(&a); + param.sched_priority = currThreadPri + 1; + pthread_attr_setschedparam(&a, ¶m); + + while (count < TEST_THREAD_COUNT) { + g_count[count] = count; + ret = pthread_create(&newThread, &a, ThreadFunc2, &g_count[count]); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + count++; + } + + ret = pthread_join(newThread, nullptr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return 0; +} + +__attribute__((optnone)) static int TestCase(void) +{ + int *test = nullptr; + int count = 5; + int status = 0; + int ret; + + g_testCondFlag = 0; + + pid_t pid = fork(); + ICUNIT_ASSERT_WITHIN_EQUAL(pid, 0, INVALID_PROCESS_ID, pid); + if (pid == 0) { + (void)TestThread(); + while (1) { + } + } + + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ret = WIFEXITED(status); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = WIFSIGNALED(status); + ICUNIT_ASSERT_EQUAL(ret, 1, ret); + ret = WTERMSIG(status); + ICUNIT_ASSERT_EQUAL(ret, SIGUSR2, ret); + return 0; +} + +void ItTestExc003(void) +{ + TEST_ADD_CASE("IT_TEST_EXC_003", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/exc/smoke/it_test_exc_004.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/exc/smoke/it_test_exc_004.cpp new file mode 100644 index 00000000..90bd76d0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/exc/smoke/it_test_exc_004.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_exc.h" +#include "pthread.h" + +#define TEST_THREAD_COUNT 5 + +__attribute__((optnone)) static int TestThread(void) +{ + int ret; + int *test = nullptr; // For triggering an exceptioin + + pid_t pid = fork(); + ICUNIT_ASSERT_WITHIN_EQUAL(pid, 0, INVALID_PROCESS_ID, pid); + if (pid == 0) { + *test = 0x1; // Deliberately trigger an exceptioin + while (1) { + } + } + *test = 0x1; // Deliberately trigger an exceptioin + + ret = waitpid(pid, NULL, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + + return 0; +} + +__attribute__((optnone)) static int TestCase(void) +{ + int count = 5; + int status = 0; + int ret; + + pid_t pid = fork(); + ICUNIT_ASSERT_WITHIN_EQUAL(pid, 0, INVALID_PROCESS_ID, pid); + if (pid == 0) { + (void)TestThread(); + while (1) { + } + } + + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ret = WIFEXITED(status); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = WIFSIGNALED(status); + ICUNIT_ASSERT_EQUAL(ret, 1, ret); + ret = WTERMSIG(status); + ICUNIT_ASSERT_EQUAL(ret, SIGUSR2, ret); + return 0; +} + +void ItTestExc004(void) +{ + TEST_ADD_CASE("IT_TEST_EXC_004", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/exc/smoke/it_test_exc_005.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/exc/smoke/it_test_exc_005.cpp new file mode 100644 index 00000000..8e00525c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/exc/smoke/it_test_exc_005.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_exc.h" + +__attribute__((optnone)) static void Child(void) +{ + while (1) { + printf("@@@@@@@@@@@@@ pid : %d getppid : %d @@@@@@@@@@@@@@@@\n", getpid(), getppid()); + } +} +static void TestKill(int sig) +{ + exit(0); +} + +__attribute__((optnone)) static int TestCase(void) +{ + int ret; + void (*retptr)(int) = NULL; + int *test = NULL; + int status = 0; + pid_t pid1; + + retptr = signal(SIGTERM, TestKill); + ICUNIT_ASSERT_NOT_EQUAL(retptr, NULL, retptr); + + pid_t pid = fork(); + ICUNIT_ASSERT_WITHIN_EQUAL(pid, 0, INVALID_PROCESS_ID, pid); + if (pid == 0) { + Child(); + exit(0); + } + + for (int i = 0; i < 2; i++) { + pid1 = fork(); + ICUNIT_ASSERT_WITHIN_EQUAL(pid1, 0, INVALID_PROCESS_ID, pid1); + if (pid1 == 0) { + *test = 0x1; + exit(0); + } else { + ret = waitpid(pid1, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid1, ret); + } + } + + kill(pid, SIGTERM); + + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + + return 0; +} + +void ItTestExc005(void) +{ + TEST_ADD_CASE("IT_TEST_EXC_005", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/config.gni b/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/config.gni new file mode 100644 index 00000000..32c730b3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/config.gni @@ -0,0 +1,52 @@ +# Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +mem_shm_include_dirs = [ "$TEST_UNITTEST_DIR/basic/mem/shm" ] + +mem_shm_sources_entry = [ "$TEST_UNITTEST_DIR/basic/mem/shm/mem_shm_test.cpp" ] + +mem_shm_sources_smoke = + [ "$TEST_UNITTEST_DIR/basic/mem/shm/smoke/shm_test_011.cpp" ] + +mem_shm_sources_full = [ + "$TEST_UNITTEST_DIR/basic/mem/shm/full/shm_test_001.cpp", + "$TEST_UNITTEST_DIR/basic/mem/shm/full/shm_test_002.cpp", + "$TEST_UNITTEST_DIR/basic/mem/shm/full/shm_test_003.cpp", + "$TEST_UNITTEST_DIR/basic/mem/shm/full/shm_test_004.cpp", + "$TEST_UNITTEST_DIR/basic/mem/shm/full/shm_test_005.cpp", + "$TEST_UNITTEST_DIR/basic/mem/shm/full/shm_test_006.cpp", + "$TEST_UNITTEST_DIR/basic/mem/shm/full/shm_test_007.cpp", + "$TEST_UNITTEST_DIR/basic/mem/shm/full/shm_test_008.cpp", + "$TEST_UNITTEST_DIR/basic/mem/shm/full/shm_test_009.cpp", + "$TEST_UNITTEST_DIR/basic/mem/shm/full/shm_test_010.cpp", + "$TEST_UNITTEST_DIR/basic/mem/shm/full/shm_test_012.cpp", + "$TEST_UNITTEST_DIR/basic/mem/shm/full/shm_test_013.cpp", + "$TEST_UNITTEST_DIR/basic/mem/shm/full/shm_test_014.cpp", +] diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/it_test_mem_100.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/it_test_mem_100.cpp new file mode 100644 index 00000000..918a6aeb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/it_test_mem_100.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_shm.h" +#include "wchar.h" + +#define TEST_STR "abcdefghijk" + +static int TestCase(void) +{ + int flag; + wchar_t res[] = L"abcd"; + wchar_t res1[] = L"mngh"; + wchar_t res2[] = L"abcdmngh"; + wchar_t *p, *pnew; + + pnew = static_cast(malloc(sizeof(wchar_t) * (wcslen(res) + wcslen(res1)))); + ICUNIT_ASSERT_NOT_EQUAL(pnew, NULL, pnew); + + p = wmempcpy(pnew, res, wcslen(res)); + wmempcpy(p, res1, wcslen(res1)); + flag = wmemcmp(pnew, res2, wcslen(res)); + + p = nullptr; + pnew = nullptr; + free(pnew); + ICUNIT_ASSERT_EQUAL(flag, 0, flag); + + return 0; +} + +void ItTestMem100(void) +{ + TEST_ADD_CASE("it_test_mem_100", TestCase, TEST_VFS, TEST_JFFS, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_001.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_001.cpp new file mode 100644 index 00000000..7582e132 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_001.cpp @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_shm.h" +#include "pthread.h" + +#define TEXT_SZ 8 +static int g_threadCount = 0; + +struct shared_use_st { + int written; + char text[TEXT_SZ]; +}; + +VOID *ShmReadFunc(VOID *ptr) +{ + void *shm = nullptr; + struct shared_use_st *shared = nullptr; + int shmid; + int ret; + + shmid = shmget((key_t)1234, sizeof(struct shared_use_st), 0666 | IPC_CREAT); + ICUNIT_ASSERT_NOT_EQUAL_NULL_VOID(shmid, -1, shmid); + + shm = shmat(shmid, 0, 0); + ICUNIT_ASSERT_NOT_EQUAL_NULL_VOID(shm, INVALID_PTR, shm); + + printf("Memory attached at %p\n", shm); + + shared = (struct shared_use_st *)shm; + while (1) { + if (shared->written == 1) { + printf("You wrote: %s\n", shared->text); + sleep(1); + + shared->written = 0; + if (strncmp(shared->text, "end", 3) == 0) { + break; + } + } else { + sleep(1); + } + } + + ret = shmdt(shm); + ICUNIT_ASSERT_EQUAL_NULL_VOID(ret, 0, ret); + + ret = shmctl(shmid, IPC_RMID, 0); + ICUNIT_ASSERT_EQUAL_NULL_VOID(ret, 0, ret); + + g_threadCount++; + return nullptr; +} + +VOID *ShmWriteFunc(VOID *ptr) +{ + void *shm = nullptr; + struct shared_use_st *shared = nullptr; + char buffer[BUFSIZ + 1] = {'\0'}; + int shmid; + int ret; + static int count = 0; + + shmid = shmget((key_t)1234, sizeof(struct shared_use_st), 0666 | IPC_CREAT); + ICUNIT_ASSERT_NOT_EQUAL_NULL_VOID(shmid, -1, shmid); + + shm = shmat(shmid, nullptr, 0); + ICUNIT_ASSERT_NOT_EQUAL_NULL_VOID(shm, INVALID_PTR, shm); + + printf("Memory attached at %p\n", shm); + + shared = (struct shared_use_st *)shm; + while (1) { + while (shared->written == 1) { + sleep(1); + printf("%s %d, Waiting...\n", __FUNCTION__, __LINE__); + } + + printf("Enter some text: "); + if (count == 0) { + (void)snprintf_s(buffer, BUFSIZ, BUFSIZ + 1, "test"); + } else { + (void)snprintf_s(buffer, BUFSIZ, BUFSIZ + 1, "end"); + } + count++; + (void)strncpy_s(shared->text, TEXT_SZ, buffer, TEXT_SZ - 1); + + shared->written = 1; + if (strncmp(buffer, "end", 3) == 0) { + break; + } + } + + ret = shmdt(shm); + ICUNIT_ASSERT_EQUAL_NULL_VOID(ret, 0, ret); + + sleep(1); + g_threadCount++; + return nullptr; +} + + +static int Testcase(VOID) +{ + pthread_t newPthread[2]; + int curThreadPri, curThreadPolicy; + pthread_attr_t a = { 0 }; + struct sched_param param = { 0 }; + int ret; + int i, j; + + g_threadCount = 0; + + ret = pthread_getschedparam(pthread_self(), &curThreadPolicy, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + curThreadPri = param.sched_priority; + ret = pthread_attr_init(&a); + param.sched_priority = curThreadPri; + pthread_attr_setschedparam(&a, ¶m); + + ret = pthread_create(&newPthread[0], &a, ShmReadFunc, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newPthread[1], &a, ShmWriteFunc, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newPthread[0], nullptr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newPthread[1], nullptr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_EQUAL(g_threadCount, 2, g_threadCount); + + return 0; +} + +void ItTestShm001(void) +{ + TEST_ADD_CASE("IT_MEM_SHM_001", Testcase, TEST_LOS, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_002.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_002.cpp new file mode 100644 index 00000000..d605e033 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_002.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_shm.h" + +#define SHMID_MAX 192 +#define SHM_FLAG 0777 + +static int Testcase(VOID) +{ + int shmid[SHMID_MAX + 1] = {-1}; + int ret; + int i; + struct shm_info shmInfo; + int leftShmIds; + + ret = shmctl(0, SHM_INFO, reinterpret_cast(&shmInfo)); + ICUNIT_ASSERT_EQUAL(ret, SHMID_MAX, ret); + leftShmIds = SHMID_MAX - shmInfo.used_ids; + + shmid[0] = shmget((key_t)0x1234, PAGE_SIZE, SHM_FLAG | IPC_CREAT); // 0x1234: a key used to create shared memory + ICUNIT_ASSERT_NOT_EQUAL(shmid[0], -1, shmid[0]); + + ret = shmctl(shmid[0], IPC_RMID, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + shmid[0] = shmget(IPC_PRIVATE, PAGE_SIZE, SHM_FLAG | IPC_CREAT); + ICUNIT_ASSERT_NOT_EQUAL(shmid[0], -1, shmid[0]); + + ret = shmctl(shmid[0], IPC_RMID, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + for (i = 0; i < leftShmIds; i++) { + shmid[i] = shmget(IPC_PRIVATE, PAGE_SIZE, SHM_FLAG | IPC_CREAT); + ICUNIT_ASSERT_NOT_EQUAL(shmid[i], -1, shmid[i]); + } + + shmid[leftShmIds] = shmget(IPC_PRIVATE, PAGE_SIZE, SHM_FLAG | IPC_CREAT); + ICUNIT_ASSERT_EQUAL(shmid[leftShmIds], -1, shmid[leftShmIds]); + + for (i = 0; i < leftShmIds; i++) { + ret = shmctl(shmid[i], IPC_RMID, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + } + + for (i = 0; i < leftShmIds; i++) { + ret = shmctl(shmid[i], IPC_RMID, NULL); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + } + + return 0; +} + +void ItTestShm002(void) +{ + TEST_ADD_CASE("IT_MEM_SHM_002", Testcase, TEST_LOS, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_003.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_003.cpp new file mode 100644 index 00000000..c9bfaba3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_003.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_shm.h" + +static int Testcase(VOID) +{ + int shmid; + int ret; + void *shm = NULL; + void *vaddrPageAlign = NULL; + void *vaddr = NULL; + + shmid = shmget(IPC_PRIVATE, PAGE_SIZE, 0777 | IPC_CREAT); + ICUNIT_ASSERT_NOT_EQUAL(shmid, -1, shmid); + + shm = shmat(shmid, NULL, 0); + ICUNIT_ASSERT_NOT_EQUAL(shm, INVALID_PTR, shm); + + (void)memset_s(shm, PAGE_SIZE, 0, PAGE_SIZE); + + ret = shmdt(shm); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret); + + vaddrPageAlign = mmap(NULL, PAGE_SIZE * 2, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); + ICUNIT_ASSERT_NOT_EQUAL(vaddrPageAlign, NULL, vaddrPageAlign); + + ret = munmap(vaddrPageAlign, PAGE_SIZE * 2); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret); + + shm = shmat(shmid, vaddrPageAlign, 0); + ICUNIT_ASSERT_EQUAL(shm, vaddrPageAlign, shm); + + (void)memset_s(shm, PAGE_SIZE, 0, PAGE_SIZE); + + ret = shmdt(shm); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret); + + vaddr = (void *)((uintptr_t)vaddrPageAlign + 0x10); + shm = shmat(shmid, vaddr, SHM_REMAP); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret); + + shm = shmat(shmid, vaddr, 0); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret); + + ret = shmctl(shmid, IPC_RMID, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return 0; +} + +void ItTestShm003(void) +{ + TEST_ADD_CASE("IT_MEM_SHM_003", Testcase, TEST_LOS, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_004.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_004.cpp new file mode 100644 index 00000000..4a2d914c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_004.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_shm.h" + +static int Testcase(VOID) +{ + int shmid; + int ret; + void *shm = NULL; + struct shmid_ds ds = { 0 }; + struct shminfo info = { 0 }; + + shmid = shmget(IPC_PRIVATE, PAGE_SIZE, 0777 | IPC_CREAT); + ICUNIT_ASSERT_NOT_EQUAL(shmid, -1, shmid); + + shm = shmat(shmid, NULL, 0); + ICUNIT_GOTO_NOT_EQUAL(shm, INVALID_PTR, shm, ERROR_OUT); + + (void)memset_s(shm, PAGE_SIZE, 0, PAGE_SIZE); + + ret = shmctl(shmid, IPC_STAT, &ds); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + ICUNIT_GOTO_EQUAL(ds.shm_segsz, PAGE_SIZE, ds.shm_segsz, ERROR_OUT); + ICUNIT_GOTO_EQUAL(ds.shm_nattch, 1, ds.shm_nattch, ERROR_OUT); + ICUNIT_GOTO_EQUAL(ds.shm_cpid, getpid(), ds.shm_cpid, ERROR_OUT); + ICUNIT_GOTO_EQUAL(ds.shm_lpid, getpid(), ds.shm_lpid, ERROR_OUT); + ICUNIT_GOTO_EQUAL(ds.shm_perm.uid, getuid(), ds.shm_perm.uid, ERROR_OUT); + + ret = shmctl(shmid, SHM_STAT, &ds); + ICUNIT_GOTO_NOT_EQUAL(ret, -1, ret, ERROR_OUT); + ICUNIT_GOTO_NOT_EQUAL(ret, 0, ret, ERROR_OUT); + + ds.shm_perm.uid = getuid(); + ds.shm_perm.gid = getgid(); + ds.shm_perm.mode = 0; + ret = shmctl(shmid, IPC_SET, &ds); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + + ret = shmctl(shmid, IPC_INFO, (struct shmid_ds *)&info); + ICUNIT_GOTO_EQUAL(ret, 192, ret, ERROR_OUT); + ICUNIT_GOTO_EQUAL(info.shmmax, 0x1000000, info.shmmax, ERROR_OUT); + ICUNIT_GOTO_EQUAL(info.shmmin, 1, info.shmmin, ERROR_OUT); + ICUNIT_GOTO_EQUAL(info.shmmni, 192, info.shmmni, ERROR_OUT); + ICUNIT_GOTO_EQUAL(info.shmseg, 128, info.shmseg, ERROR_OUT); // 128: expected value of shmseg + ICUNIT_GOTO_EQUAL(info.shmall, 0x1000, info.shmall, ERROR_OUT); + + ret = shmdt(shm); + ICUNIT_GOTO_NOT_EQUAL(ret, -1, ret, ERROR_OUT); + + ret = shmctl(shmid, IPC_RMID, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return 0; + +ERROR_OUT: + ret = shmctl(shmid, IPC_RMID, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return -1; +} + +void ItTestShm004(void) +{ + TEST_ADD_CASE("IT_MEM_SHM_004", Testcase, TEST_LOS, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_005.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_005.cpp new file mode 100644 index 00000000..b4d6ba61 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_005.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_shm.h" + +static int Testcase(VOID) +{ + int shmid; + int ret; + void *shm = NULL; + void *vaddrPageAlign = NULL; + void *vaddr = NULL; + + errno = 0; + shmid = shmget(0x111, PAGE_SIZE, 0777 | IPC_EXCL); + ICUNIT_ASSERT_EQUAL(shmid, -1, shmid); + ICUNIT_ASSERT_EQUAL(errno, ENOENT, errno); + + shmid = shmget(IPC_PRIVATE, PAGE_SIZE, 0777 | IPC_CREAT); + ICUNIT_ASSERT_NOT_EQUAL(shmid, -1, shmid); + + shm = shmat(shmid, NULL, SHM_REMAP); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno); + + shm = shmat(shmid, reinterpret_cast(0x100), 0); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno); + + shm = shmat(shmid, NULL, 0); + ICUNIT_ASSERT_NOT_EQUAL(shm, reinterpret_cast(-1), shm); + + ret = shmdt(reinterpret_cast(0x100)); + ICUNIT_ASSERT_EQUAL(ret, -1, shmid); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno); + + ret = shmdt(shm); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret); + + ret = shmctl(0x111, IPC_RMID, NULL); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno); + + ret = shmctl(shmid, IPC_RMID, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = shmctl(shmid, IPC_RMID, NULL); + ICUNIT_ASSERT_EQUAL(ret, -1, shmid); + ICUNIT_ASSERT_EQUAL(errno, EIDRM, errno); + + return 0; +} + +void ItTestShm005(void) +{ + TEST_ADD_CASE("IT_MEM_SHM_005", Testcase, TEST_LOS, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_006.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_006.cpp new file mode 100644 index 00000000..46f52a4d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_006.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_shm.h" + +static int Testcase(VOID) +{ + const int memSize = PAGE_SIZE; + int ret; + int shmid; + void *shared = NULL; + void *remap = NULL; + + shmid = shmget(IPC_PRIVATE, memSize, 0666 | IPC_CREAT); + ICUNIT_ASSERT_NOT_EQUAL(shmid, -1, shmid); + + shared = shmat(shmid, 0, 0); + ICUNIT_ASSERT_NOT_EQUAL(shared, reinterpret_cast(-1), shared); + + ret = shmdt(shared); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret); + + remap = shared; + shared = shmat(shmid, remap, SHM_REMAP); + ICUNIT_ASSERT_NOT_EQUAL(shared, reinterpret_cast(-1), shared); + + ret = shmdt(shared); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret); + + ret = shmctl(shmid, IPC_RMID, NULL); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret); + + return 0; +} + +void ItTestShm006(void) +{ + TEST_ADD_CASE("IT_MEM_SHM_006", Testcase, TEST_LOS, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_007.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_007.cpp new file mode 100644 index 00000000..1f0e16d4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_007.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_shm.h" +#include "sys/types.h" + +static int Testcase(void) +{ + const int memSize = 1024; + int shmid; + char *shared = NULL; + char testStr[] = "hello shmem"; + pid_t pid; + int ret; + int status; + + shmid = shmget((key_t)1234, memSize, 0666 | IPC_CREAT); + ICUNIT_ASSERT_NOT_EQUAL(shmid, -1, shmid); + + ret = fork(); + if (ret == 0) { + usleep(100000); + if ((shared = static_cast(shmat(shmid, 0, 0))) == reinterpret_cast(-1)) { + printf("child : error: shmat()\n"); + exit(1); + } + + if (strncmp(shared, testStr, sizeof(testStr)) != 0) { + printf("child : error strncmp() shared = %s\n", shared); + exit(1); + } + + if ((shmdt(shared)) < 0) { + printf("child : error : shmdt()\n"); + exit(1); + } + + if (shmctl(shmid, IPC_RMID, NULL) == -1) { + printf("child : error : shmctl()\n"); + exit(1); + } + + exit(0); + } else { + pid = ret; + usleep(50000); + + shared = static_cast(shmat(shmid, 0, 0)); + ICUNIT_ASSERT_NOT_EQUAL(shared, reinterpret_cast(-1), shared); + + ret = strncpy_s(shared, memSize, testStr, sizeof(testStr)); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = shmdt(shared); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret); + + usleep(100000); + + ret = wait(&status); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ICUNIT_ASSERT_EQUAL(status, 0, status); + } + + return 0; +} + +void ItTestShm007(void) +{ + TEST_ADD_CASE("IT_MEM_SHM_007", Testcase, TEST_LOS, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_008.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_008.cpp new file mode 100644 index 00000000..7c8fb5f0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_008.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_shm.h" +#include "sys/types.h" + +static int Testcase(void) +{ + const int memSize = PAGE_SIZE; + int ret; + int shmid; + void *shared = NULL; + + shmid = shmget(IPC_PRIVATE, memSize, SHM_R | IPC_CREAT); + ICUNIT_ASSERT_NOT_EQUAL(shmid, -1, shmid); + + shared = shmat(shmid, 0, 0); + ICUNIT_ASSERT_EQUAL(shared, reinterpret_cast(-1), shared); + ICUNIT_ASSERT_EQUAL(errno, EACCES, errno); + + shared = shmat(shmid, 0, SHM_RDONLY); + ICUNIT_ASSERT_NOT_EQUAL(shared, reinterpret_cast(-1), shared); + + ret = shmdt(shared); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret); + + ret = shmctl(shmid, IPC_RMID, NULL); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret); + + return 0; +} + +void ItTestShm008(void) +{ + TEST_ADD_CASE("IT_MEM_SHM_008", Testcase, TEST_LOS, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_009.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_009.cpp new file mode 100644 index 00000000..2fbb0854 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_009.cpp @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_shm.h" +#include "sys/types.h" +#include +#include +#include +#include +#include +#include +#include +#include + +static int *g_shmptr = NULL; + +static void ChildProcess(void) +{ + struct sched_param param; + + param.sched_priority = sched_get_priority_max(SCHED_RR); + if(sched_setparam(getpid(), ¶m) != 0) { + printf("An error occurs when calling sched_setparam()"); + return; + } + + /* to avoid blocking */ + alarm(2); + while(1); +} + +static void TestProcess(void) +{ + /* to avoid blocking */ + alarm(5); + + while(1) { + (*g_shmptr)++; + sched_yield(); + } +} + +static void ExitChildren(int sig) +{ + exit(0); +} + +static void KillChildren(int childPid) +{ + kill(childPid, SIGTERM); + sleep(1); //wait for kill child finish. +} + +static int Testcase(void) +{ + int childPid, oldcount, newcount, shmid; + struct sched_param param = {0}; + struct sched_param paramCopy = {0}; + int processPolicy = 0; + int threadPrio = 0; + int ret; + int pid; + + void *ptr = reinterpret_cast(signal(SIGTERM, ExitChildren)); + ICUNIT_ASSERT_NOT_EQUAL(ptr, NULL, ptr); + + shmid = shmget(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0600); + ICUNIT_ASSERT_NOT_EQUAL(shmid, -1, shmid); + + g_shmptr = (int *)shmat(shmid, 0, 0); + ICUNIT_ASSERT_NOT_EQUAL(g_shmptr, reinterpret_cast(-1), g_shmptr); + + *g_shmptr = 0; + + processPolicy = sched_getscheduler(getpid()); + ret = sched_getparam(getpid(), ¶mCopy); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + param.sched_priority = (sched_get_priority_min(SCHED_RR) + + sched_get_priority_max(SCHED_RR)) / 2; + ret = sched_setscheduler(getpid(), SCHED_RR, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_getschedparam(pthread_self(), &processPolicy, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + threadPrio = param.sched_priority; + ret = pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + childPid = fork(); + ICUNIT_GOTO_NOT_EQUAL(childPid, -1, childPid, OUT_SCHEDULER); + + if (childPid == 0) { + TestProcess(); + exit(0); + } + sleep(1); + + param.sched_priority = sched_get_priority_min(SCHED_RR); + oldcount = *g_shmptr; + ret = sched_setparam(childPid, ¶m); + ICUNIT_GOTO_EQUAL(ret, 0, ret, OUT_SCHEDULER); + + ret = 1; + newcount = *g_shmptr; + ICUNIT_GOTO_NOT_EQUAL(oldcount, newcount, newcount, OUT); + + ret = 0; +OUT: + KillChildren(childPid); + pid = waitpid(childPid, NULL, 0); + ICUNIT_ASSERT_EQUAL(pid, childPid, pid); + (void)sched_setparam(getpid(), ¶mCopy); +OUT_SCHEDULER: + (void)sched_setscheduler(getpid(), processPolicy, ¶mCopy); + param.sched_priority = threadPrio; + pthread_setschedparam(pthread_self(), SCHED_RR, ¶m); + + ret = shmdt(g_shmptr); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret); + + ret = shmctl(shmid, IPC_RMID, NULL); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret); + + return ret; +} + +void ItTestShm009(void) +{ + TEST_ADD_CASE("IT_MEM_SHM_009", Testcase, TEST_LOS, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_010.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_010.cpp new file mode 100644 index 00000000..73a9b537 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_010.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_shm.h" +#include "sys/types.h" + +static int Testcase(void) +{ + const int memSize = 1024; + int shmid; + int ret; + int status; + + ret = fork(); + if (ret == 0) { + usleep(10000); + shmid = shmget((key_t)1234, memSize, 0666 | IPC_CREAT); + if (shmid < 0) { + if (errno == EACCES) { + exit(1); + } + } + + exit(0); + } else { + shmid = shmget((key_t)1234, memSize, 0000 | IPC_CREAT); + ICUNIT_ASSERT_NOT_EQUAL(shmid, -1, shmid); + usleep(20000); + ret = shmctl(shmid, IPC_RMID, NULL); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret); + + wait(&status); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(status, 1, status); + } + + return 0; +} + +void ItTestShm010(void) +{ + TEST_ADD_CASE("IT_MEM_SHM_010", Testcase, TEST_LOS, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_012.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_012.cpp new file mode 100644 index 00000000..474e4ebb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_012.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_shm.h" +#include "sys/types.h" + +#define SHMNAME "shm_ram" +#define OPEN_FLAG (O_RDWR | O_CREAT | O_EXCL) +#define OPEN_MODE 00777 + +static int Testcase(void) +{ + int fd = shm_open(SHMNAME, OPEN_FLAG, OPEN_MODE); + ICUNIT_ASSERT_NOT_EQUAL(fd, -1, fd); + + errno = 0; + fd = shm_open(SHMNAME, OPEN_FLAG, OPEN_MODE); + ICUNIT_ASSERT_EQUAL(fd, -1, fd); + ICUNIT_ASSERT_EQUAL(errno, EEXIST, errno); + + errno = 0; + fd = shm_open("SHM_RAM", O_RDONLY, OPEN_MODE); + ICUNIT_ASSERT_EQUAL(fd, -1, fd); + ICUNIT_ASSERT_EQUAL(errno, ENOENT, errno); + + errno = 0; + fd = shm_open("..../1.txt/123", OPEN_FLAG, OPEN_MODE); + ICUNIT_ASSERT_EQUAL(fd, -1, fd); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno); + + errno = 0; + fd = shm_open("SHM_RAM", OPEN_FLAG, 0); + ICUNIT_ASSERT_NOT_EQUAL(fd, -1, fd); + int ret = shm_unlink(SHMNAME); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = shm_unlink("SHM_RAM"); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + errno = 0; + ret = shm_unlink("shm_ram_unlink"); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, ENOENT, errno); + + return 0; +} + +void ItTestShm012(void) +{ + TEST_ADD_CASE("IT_MEM_SHM_012", Testcase, TEST_LOS, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} + diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_013.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_013.cpp new file mode 100644 index 00000000..773402aa --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_013.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_shm.h" +#include "sys/types.h" + +static int testcase(void) +{ + int shmfd; + int ret; + int count; + int pageSize = getpagesize(); + char *writebuf = NULL; + char *readbuf = NULL; + + shmfd = shm_open("test_1", O_RDWR | O_CREAT | O_EXCL, 0644); + ICUNIT_ASSERT_NOT_EQUAL(shmfd, -1, shmfd); + + writebuf = static_cast(malloc(pageSize)); + ICUNIT_ASSERT_NOT_EQUAL(writebuf, NULL, writebuf); + readbuf = static_cast(malloc(pageSize)); + ICUNIT_GOTO_NOT_EQUAL(readbuf, NULL, readbuf, EXIT); + + (void)memset_s(writebuf, pageSize, 0xf, pageSize); + + count = write(shmfd, writebuf, pageSize); + ICUNIT_GOTO_EQUAL(count, pageSize, count, EXIT); + + ret = lseek(shmfd, 0, SEEK_SET); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + count = read(shmfd, readbuf, pageSize); + ICUNIT_GOTO_EQUAL(count, pageSize, count, EXIT); + +EXIT: + if (readbuf != NULL) { + free(readbuf); + } + if (writebuf != NULL) { + free(writebuf); + } + close(shmfd); + ret = shm_unlink("test_1"); + return 0; +} + +void it_test_shm_013(void) +{ + TEST_ADD_CASE("IT_MEM_SHM_013", testcase, TEST_LOS, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_014.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_014.cpp new file mode 100644 index 00000000..7acd2b76 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/full/shm_test_014.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_shm.h" +#include "sys/types.h" + +#define SHMNAME "shm_ram" + +static int testcase(void) +{ + int shmfd; + int ret; + int count; + int pageSize = getpagesize(); + char *writebuf = NULL; + char *readbuf = NULL; + + errno = 0; + shmfd = shm_open("test_2", O_RDONLY, 00664); + ICUNIT_ASSERT_EQUAL(shmfd, -1, shmfd); + ICUNIT_ASSERT_EQUAL(errno, 2, errno); + + shmfd = shm_open("test_2", O_RDONLY | O_CREAT, 00664); + ICUNIT_ASSERT_NOT_EQUAL(shmfd, -1, shmfd); + writebuf = static_cast(malloc(pageSize)); + ICUNIT_ASSERT_NOT_EQUAL(writebuf, NULL, writebuf); + readbuf = static_cast(malloc(pageSize)); + ICUNIT_ASSERT_NOT_EQUAL(readbuf, NULL, readbuf); + (void)memset_s(writebuf, pageSize, 0xf, pageSize); + + errno = 0; + + count = write(shmfd, writebuf, pageSize); + ICUNIT_ASSERT_EQUAL(count, -1, count); + ICUNIT_ASSERT_EQUAL(errno, EACCES, errno); + close(shmfd); + ret = shm_unlink("test_2"); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + shmfd = shm_open("test_3", O_WRONLY | O_CREAT, 00664); + ICUNIT_ASSERT_NOT_EQUAL(shmfd, -1, shmfd); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + errno = 0; + count = write(shmfd, writebuf, pageSize); + ICUNIT_ASSERT_EQUAL(count, pageSize, count); + + errno = 0; + count = read(shmfd, readbuf, pageSize); + ICUNIT_ASSERT_EQUAL(count, -1, count); + ICUNIT_ASSERT_EQUAL(errno, EACCES, errno); + free(writebuf); + free(readbuf); + close(shmfd); + + ret = shm_unlink("test_3"); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return 0; +} + +void it_test_shm_014(void) +{ + TEST_ADD_CASE("IT_MEM_SHM_014", testcase, TEST_LOS, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/it_test_shm.h b/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/it_test_shm.h new file mode 100644 index 00000000..96f5ae7c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/it_test_shm.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _IT_TEST_MEM_SHM_H +#define _IT_TEST_MEM_SHM_H + +#include "osTest.h" +#include "sys/shm.h" + +#define INVALID_PTR ((void *)-1) +extern void ItTestShm001(void); +extern void ItTestShm002(void); +extern void ItTestShm003(void); +extern void ItTestShm004(void); +extern void ItTestShm005(void); +extern void ItTestShm006(void); +extern void ItTestShm007(void); +extern void ItTestShm008(void); +extern void ItTestShm009(void); +extern void ItTestShm010(void); +extern void ItTestShm011(void); +extern void ItTestShm012(void); +extern void it_test_shm_013(void); +extern void it_test_shm_014(void); +extern void ItTestMem100(void); + +#endif diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/mem_shm_test.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/mem_shm_test.cpp new file mode 100644 index 00000000..c023f09c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/mem_shm_test.cpp @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include + +#include "it_test_shm.h" + +using namespace testing::ext; +namespace OHOS { +class MemShmTest : public testing::Test { +public: + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} +}; + +#if defined(LOSCFG_USER_TEST_FULL) +/* * + * @tc.name: it_test_shm_001 + * @tc.desc: function for MemShmTest + * @tc.type: FUNC + */ +HWTEST_F(MemShmTest, ItTestShm001, TestSize.Level0) +{ + ItTestShm001(); +} + +/* * + * @tc.name: it_test_shm_002 + * @tc.desc: function for MemShmTest + * @tc.type: FUNC + */ +HWTEST_F(MemShmTest, ItTestShm002, TestSize.Level0) +{ + ItTestShm002(); +} + +/* * + * @tc.name: it_test_shm_003 + * @tc.desc: function for MemShmTest + * @tc.type: FUNC + */ +HWTEST_F(MemShmTest, ItTestShm003, TestSize.Level0) +{ + ItTestShm003(); +} + +/* * + * @tc.name: it_test_shm_004 + * @tc.desc: function for MemShmTest + * @tc.type: FUNC + */ +HWTEST_F(MemShmTest, ItTestShm004, TestSize.Level0) +{ + ItTestShm004(); +} + +/* * + * @tc.name: it_test_shm_005 + * @tc.desc: function for MemShmTest + * @tc.type: FUNC + */ +HWTEST_F(MemShmTest, ItTestShm005, TestSize.Level0) +{ + ItTestShm005(); +} + +/* * + * @tc.name: it_test_shm_006 + * @tc.desc: function for MemShmTest + * @tc.type: FUNC + */ +HWTEST_F(MemShmTest, ItTestShm006, TestSize.Level0) +{ + ItTestShm006(); +} + +/* * + * @tc.name: it_test_shm_007 + * @tc.desc: function for MemShmTest + * @tc.type: FUNC + */ +HWTEST_F(MemShmTest, ItTestShm007, TestSize.Level0) +{ + ItTestShm007(); +} + +/* * + * @tc.name: it_test_shm_008 + * @tc.desc: function for MemShmTest + * @tc.type: FUNC + */ +HWTEST_F(MemShmTest, ItTestShm008, TestSize.Level0) +{ + ItTestShm008(); +} + +/* * + * @tc.name: it_test_shm_009 + * @tc.desc: function for MemShmTest + * @tc.type: FUNC + */ +HWTEST_F(MemShmTest, ItTestShm009, TestSize.Level0) +{ + ItTestShm009(); +} + +/* * + * @tc.name: it_test_shm_010 + * @tc.desc: function for MemShmTest + * @tc.type: FUNC + */ +HWTEST_F(MemShmTest, ItTestShm010, TestSize.Level0) +{ + ItTestShm010(); +} +#endif + +#if defined(LOSCFG_USER_TEST_SMOKE) +/* * + * @tc.name: it_test_shm_011 + * @tc.desc: function for MemShmTest + * @tc.type: FUNC + */ +HWTEST_F(MemShmTest, ItTestShm011, TestSize.Level0) +{ + ItTestShm011(); +} +#endif +} +// namespace OHOS diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/smoke/shm_test_011.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/smoke/shm_test_011.cpp new file mode 100644 index 00000000..3a35156b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/mem/shm/smoke/shm_test_011.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_shm.h" +#include "sys/types.h" + +static int Testcase(void) +{ + const int memSize = 1024; + int *shared = NULL; + int shmid; + int ret; + int status; + + shmid = shmget((key_t)IPC_PRIVATE, memSize, 0666 | IPC_CREAT); + ICUNIT_ASSERT_NOT_EQUAL(shmid, -1, shmid); + + ret = fork(); + if (ret == 0) { + shared = (int *)shmat(shmid, NULL, 0); + if (shared == reinterpret_cast(-1)) { + exit(1); + } + *shared = 2; + ret = shmdt(shared); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret); + exit(0); + } else { + usleep(20000); + shared = (int *)shmat(shmid, NULL, 0); + ICUNIT_ASSERT_NOT_EQUAL(shared, reinterpret_cast(-1), shared); + + ICUNIT_ASSERT_EQUAL(*shared, 2, *shared); + + ret = shmdt(shared); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret); + + wait(&status); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(status, 0, status); + + ret = shmctl(shmid, IPC_RMID, NULL); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret); + } + + return 0; +} + +void ItTestShm011(void) +{ + TEST_ADD_CASE("IT_MEM_SHM_011", Testcase, TEST_LOS, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/config.gni b/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/config.gni new file mode 100644 index 00000000..d30ebbe8 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/config.gni @@ -0,0 +1,53 @@ +# Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +mem_vm_include_dirs = [ "$TEST_UNITTEST_DIR/basic/mem/vm" ] + +mem_vm_sources_entry = [ "$TEST_UNITTEST_DIR/basic/mem/vm/mem_vm_test.cpp" ] + +mem_vm_sources_smoke = [ + "$TEST_UNITTEST_DIR/basic/mem/vm/smoke/mmap_test_001.cpp", + "$TEST_UNITTEST_DIR/basic/mem/vm/smoke/mmap_test_002.cpp", + "$TEST_UNITTEST_DIR/basic/mem/vm/smoke/mmap_test_003.cpp", + "$TEST_UNITTEST_DIR/basic/mem/vm/smoke/mmap_test_004.cpp", + "$TEST_UNITTEST_DIR/basic/mem/vm/smoke/mmap_test_005.cpp", + "$TEST_UNITTEST_DIR/basic/mem/vm/smoke/mmap_test_006.cpp", + "$TEST_UNITTEST_DIR/basic/mem/vm/smoke/mmap_test_007.cpp", + "$TEST_UNITTEST_DIR/basic/mem/vm/smoke/mmap_test_008.cpp", + "$TEST_UNITTEST_DIR/basic/mem/vm/smoke/mmap_test_009.cpp", + "$TEST_UNITTEST_DIR/basic/mem/vm/smoke/mmap_test_010.cpp", + "$TEST_UNITTEST_DIR/basic/mem/vm/smoke/mprotect_test_001.cpp", + "$TEST_UNITTEST_DIR/basic/mem/vm/smoke/mremap_test_001.cpp", + "$TEST_UNITTEST_DIR/basic/mem/vm/smoke/oom_test_001.cpp", + "$TEST_UNITTEST_DIR/basic/mem/vm/smoke/open_wmemstream_test_001.cpp", + "$TEST_UNITTEST_DIR/basic/mem/vm/smoke/user_copy_test_001.cpp", +] + +mem_vm_sources_full = [] diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/it_test_vm.h b/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/it_test_vm.h new file mode 100644 index 00000000..7537401b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/it_test_vm.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _IT_TEST_MEM_VM_H +#define _IT_TEST_MEM_VM_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "osTest.h" + +extern void ItTestMmap001(void); +extern void ItTestMmap002(void); +extern void ItTestMmap003(void); +extern void ItTestMmap004(void); +extern void ItTestMmap005(void); +extern void ItTestMmap006(void); +extern void ItTestMmap007(void); +extern void ItTestMmap008(void); +extern void ItTestMmap009(void); +extern void ItTestMmap010(void); +extern void ItTestMprotect001(void); +extern void ItTestMremap001(void); +extern void ItTestOom001(void); +extern void ItTestUserCopy001(void); +extern void open_wmemstream_test_001(void); +#endif diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/mem_vm_test.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/mem_vm_test.cpp new file mode 100644 index 00000000..982dbff3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/mem_vm_test.cpp @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include + +#include "it_test_vm.h" + +using namespace testing::ext; +namespace OHOS { +class MemVmTest : public testing::Test { +public: + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} +}; + +#if defined(LOSCFG_USER_TEST_SMOKE) +/* * + * @tc.name: it_test_mmap_001 + * @tc.desc: function for MemVmTest + * @tc.type: FUNC + */ +HWTEST_F(MemVmTest, ItTestMmap001, TestSize.Level0) +{ + ItTestMmap001(); +} + +/* * + * @tc.name: it_test_mmap_005 + * @tc.desc: function for MemVmTest + * @tc.type: FUNC + */ +HWTEST_F(MemVmTest, ItTestMmap005, TestSize.Level0) +{ + ItTestMmap005(); +} + +/* * + * @tc.name: it_test_mmap_006 + * @tc.desc: function for MemVmTest + * @tc.type: FUNC + */ +HWTEST_F(MemVmTest, ItTestMmap006, TestSize.Level0) +{ + ItTestMmap006(); +} + +/* * + * @tc.name: it_test_mmap_007 + * @tc.desc: function for MemVmTest + * @tc.type: FUNC + */ +HWTEST_F(MemVmTest, ItTestMmap007, TestSize.Level0) +{ + ItTestMmap007(); +} + +/* * + * @tc.name: it_test_mmap_008 + * @tc.desc: function for MemVmTest + * @tc.type: FUNC + */ +HWTEST_F(MemVmTest, ItTestMmap008, TestSize.Level0) +{ + ItTestMmap008(); +} + +/* * + * @tc.name: it_test_mmap_009 + * @tc.desc: function for MemVmTest + * @tc.type: FUNC + */ +HWTEST_F(MemVmTest, ItTestMmap009, TestSize.Level0) +{ + ItTestMmap009(); +} + +/* * + * @tc.name: it_test_mmap_010 + * @tc.desc: function for MemVmTest + * @tc.type: FUNC + */ +HWTEST_F(MemVmTest, ItTestMmap010, TestSize.Level0) +{ + ItTestMmap010(); +} + +/* * + * @tc.name: it_test_mprotect_001 + * @tc.desc: function for MemVmTest + * @tc.type: FUNC + */ +HWTEST_F(MemVmTest, ItTestMprotect001, TestSize.Level0) +{ + ItTestMprotect001(); +} + +#ifndef LOSCFG_USER_TEST_SMP +/* * + * @tc.name: it_test_oom_001 + * @tc.desc: function for MemVmTest + * @tc.type: FUNC + */ +HWTEST_F(MemVmTest, ItTestOom001, TestSize.Level0) +{ + ItTestOom001(); +} + +#endif +/* * + * @tc.name: it_test_mremap_001 + * @tc.desc: function for MemVmTest + * @tc.type: FUNC + */ +HWTEST_F(MemVmTest, ItTestMremap001, TestSize.Level0) +{ + ItTestMremap001(); +} + +/* * + * @tc.name: it_test_user_copy_001 + * @tc.desc: function for MemVmTest + * @tc.type: FUNC + */ +HWTEST_F(MemVmTest, ItTestUserCopy001, TestSize.Level0) +{ + ItTestUserCopy001(); +} + +/* * + * @tc.name: open_wmemstream_test_001 + * @tc.desc: function for open_wmemstream + * @tc.type: FUNC + */ +HWTEST_F(MemVmTest, open_wmemstream_test_001, TestSize.Level0) +{ + open_wmemstream_test_001(); +} +#endif +} // namespace OHOS diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mmap_test_001.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mmap_test_001.cpp new file mode 100644 index 00000000..1c7f4c4c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mmap_test_001.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_vm.h" + +#define MAP_ARRAY_SIZE 9 +#define MAP_FLAGS (MAP_ANONYMOUS | MAP_PRIVATE) + +static const struct { + void *addr; + int ret; + unsigned int flags; +} g_gMmapTests[MAP_ARRAY_SIZE] = { + {(void *)0, 0, MAP_FLAGS}, + {(void *)1, -1, MAP_FLAGS | MAP_FIXED}, + {(void *)(PAGE_SIZE - 1), -1, MAP_FLAGS | MAP_FIXED}, + {(void *)PAGE_SIZE, -1, MAP_FLAGS | MAP_FIXED}, + {(void *)-1, 0, MAP_FLAGS}, + {(void *)(-PAGE_SIZE), -1, MAP_FLAGS | MAP_FIXED}, + {(void *)(-1 - PAGE_SIZE), -1, MAP_FLAGS | MAP_FIXED}, + {(void *)(-1 - PAGE_SIZE - 1), -1, MAP_FLAGS | MAP_FIXED}, + {(void *)(0x1000 * PAGE_SIZE), 0, MAP_FLAGS | MAP_FIXED}, +}; + +static int Testcase(void) +{ + void *p = NULL; + int i; + int ret; + int count = sizeof(g_gMmapTests) / sizeof(g_gMmapTests[0]); + void *array[MAP_ARRAY_SIZE] = {NULL}; + + for (i = 0; i < count; i++) { + p = mmap((void *)g_gMmapTests[i].addr, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, g_gMmapTests[i].flags, -1, + 0); + ret = (p == MAP_FAILED) ? -1 : 0; + ICUNIT_ASSERT_EQUAL(g_gMmapTests[i].ret, ret, p); + array[i] = p; + } + + for (i = 0; i < count; i++) { + if (array[i] == MAP_FAILED) { + continue; + } + ret = munmap(array[i], PAGE_SIZE); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + } + + return 0; +} + +void ItTestMmap001(void) +{ + TEST_ADD_CASE("IT_MEM_MMAP_001", Testcase, TEST_LOS, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mmap_test_002.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mmap_test_002.cpp new file mode 100644 index 00000000..85f44eed --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mmap_test_002.cpp @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_vm.h" + +#define MAP_RESERVED0080 0x0080 + +static int CheckedMmap(int prot, int flags, int fd) +{ + void *p = NULL; + int pageSize = getpagesize(); + int ret; + + if (pageSize < 0) { + printf("err: mmap size invalid\n"); + return -1; + } + p = mmap(NULL, pageSize, prot, flags, fd, 0); + if (p == MAP_FAILED) { + return errno; + } else { + ret = munmap(p, pageSize); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return 0; + } +} + +static int Testcase(void) +{ + int shmfd; + int ret; + int count; + int pageSize = getpagesize(); + char *buf = NULL; + + shmfd = shm_open("/test", O_RDWR | O_CREAT, 0644); + ICUNIT_ASSERT_NOT_EQUAL(shmfd, -1, shmfd); + + if (pageSize <= 0) { + printf("err: malloc size invalid\n"); + return -1; + } + if (pageSize <= 0) { + printf("err: malloc size invalid\n"); + return -1; + } + buf = static_cast(malloc(pageSize)); + ICUNIT_ASSERT_NOT_EQUAL(buf, NULL, buf); + (void)memset_s(buf, pageSize, 0xf, pageSize); + + count = write(shmfd, buf, pageSize); + if (count != pageSize) { + free(buf); + ICUNIT_ASSERT_EQUAL(count, pageSize, count); + } + free(buf); + + /* Simple MAP_ANONYMOUS */ + ret = CheckedMmap(PROT_READ | PROT_WRITE, MAP_ANONYMOUS, -1); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + /* Simple shm fd shared */ + ret = CheckedMmap(PROT_READ | PROT_WRITE, MAP_SHARED, shmfd); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + /* Simple shm fd private */ + ret = CheckedMmap(PROT_READ | PROT_WRITE, MAP_PRIVATE, shmfd); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + /* MAP_ANONYMOUS with extra PROT flags */ + ret = CheckedMmap(PROT_READ | PROT_WRITE | 0x100000, MAP_ANONYMOUS, -1); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + /* Shm fd with garbage PROT */ + ret = CheckedMmap(0xffff, MAP_SHARED, shmfd); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + /* Undefined flag. */ + ret = CheckedMmap(PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_RESERVED0080, -1); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + /* Both MAP_SHARED and MAP_PRIVATE */ + ret = CheckedMmap(PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_SHARED, -1); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + /* Shm fd with both SHARED and PRIVATE */ + ret = CheckedMmap(PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_SHARED, shmfd); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + /* At least one of MAP_SHARED or MAP_PRIVATE without ANON */ + ret = CheckedMmap(PROT_READ | PROT_WRITE, 0, shmfd); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + /* MAP_ANONYMOUS with either sharing flag (impacts fork). */ + ret = CheckedMmap(PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = CheckedMmap(PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = CheckedMmap(PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = close(shmfd); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return 0; +} + +void ItTestMmap002(void) +{ + TEST_ADD_CASE("IT_MEM_MMAP_002", Testcase, TEST_LOS, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mmap_test_003.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mmap_test_003.cpp new file mode 100644 index 00000000..2508b381 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mmap_test_003.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_vm.h" + +#define MAP_TEST_FILE "/dev/shm/test" + +static int Testcase(void) +{ + char *p1 = NULL; + char *p2 = NULL; + char *p3 = NULL; + int fd, pageSize; + int ret; + + pageSize = getpagesize(); + fd = open(MAP_TEST_FILE, O_RDONLY); + ICUNIT_ASSERT_NOT_EQUAL(fd, -1, fd); + + p1 = (char *)mmap(NULL, pageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); + ICUNIT_ASSERT_NOT_EQUAL(p1, MAP_FAILED, p1); + (void)memset_s(p1, pageSize, 0, pageSize); + + p2 = (char *)mmap(NULL, pageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); + ICUNIT_ASSERT_NOT_EQUAL(p2, MAP_FAILED, p2); + (void)memset_s(p2, pageSize, 0, pageSize); + + ret = memcmp(p1, p2, pageSize); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + p1[0] = 1; + ICUNIT_ASSERT_EQUAL(p2[0], 0, p2[0]); + + p2[0] = 2; + ICUNIT_ASSERT_EQUAL(p1[0], 1, p1[0]); + + p3 = (char *)mmap(NULL, pageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); + ICUNIT_ASSERT_NOT_EQUAL(p3, MAP_FAILED, p3); + ICUNIT_ASSERT_EQUAL(p3[0], 0xf, p3[0]); + + ret = munmap(p1, pageSize); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = munmap(p2, pageSize); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = munmap(p3, pageSize); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = close(fd); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return 0; +} + +void ItTestMmap003(void) +{ + TEST_ADD_CASE("IT_MEM_MMAP_003", Testcase, TEST_LOS, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mmap_test_004.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mmap_test_004.cpp new file mode 100644 index 00000000..7ab16a86 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mmap_test_004.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_vm.h" + +#define MAP_TEST_FILE "/dev/shm/test" + +static int Testcase(void) +{ + char *p1 = NULL; + char *p2 = NULL; + char *p3 = NULL; + int fd, pageSize; + int ret; + + pageSize = getpagesize(); + fd = open(MAP_TEST_FILE, O_RDWR); + ICUNIT_ASSERT_NOT_EQUAL(fd, -1, fd); + + p1 = (char *)mmap(NULL, pageSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + ICUNIT_ASSERT_NOT_EQUAL(p1, MAP_FAILED, p1); + (void)memset_s(p1, pageSize, 0, pageSize); + + p2 = (char *)mmap(NULL, pageSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + ICUNIT_ASSERT_NOT_EQUAL(p2, MAP_FAILED, p2); + (void)memset_s(p2, pageSize, 0, pageSize); + + ret = memcmp(p1, p2, pageSize); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + p1[0] = 1; + ICUNIT_ASSERT_EQUAL(p2[0], 1, p2[0]); + + p2[0] = 2; + ICUNIT_ASSERT_EQUAL(p1[0], 2, p1[0]); + + p3 = (char *)mmap(NULL, pageSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + ICUNIT_ASSERT_NOT_EQUAL(p3, MAP_FAILED, p3); + ICUNIT_ASSERT_EQUAL(p3[0], 2, p3[0]); + + ret = munmap(p1, pageSize); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = munmap(p2, pageSize); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = munmap(p3, pageSize); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = close(fd); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return 0; +} + +void ItTestMmap004(void) +{ + TEST_ADD_CASE("IT_MEM_MMAP_004", Testcase, TEST_LOS, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mmap_test_005.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mmap_test_005.cpp new file mode 100644 index 00000000..3685d3e4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mmap_test_005.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_vm.h" + +#define MAP_TEST_FILE "/lib/libc.so" + +static int Testcase(void) +{ + void *map = NULL; + int fd; + + fd = open(MAP_TEST_FILE, O_RDONLY); + ICUNIT_ASSERT_NOT_EQUAL(fd, -1, fd); + + map = mmap(NULL, 0, PROT_READ, MAP_PRIVATE, fd, 0); + ICUNIT_ASSERT_EQUAL(map, MAP_FAILED, map); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno); + + return 0; +} + +void ItTestMmap005(void) +{ + TEST_ADD_CASE("IT_MEM_MMAP_005", Testcase, TEST_LOS, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mmap_test_006.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mmap_test_006.cpp new file mode 100644 index 00000000..6f45c878 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mmap_test_006.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_vm.h" +#define INVALID_FD 0xFFFFFFFF +#define INVALID_VADDR 0xAFFFFFFF +#define VALIDE_ADDR 0x12000000 +#define ADDR_OFFSET 0X123 +#define OVER_LEN 0x40000000 +#define MAP_LEN 0x1000 +#define FLAG_NUM 3 + +static int Testcase(void) +{ + void *mem = NULL; + void *invalueAddr = NULL; + size_t len = MAP_LEN; + char file[] = "/storage/testMmapEINVAL.txt"; + int flags[FLAG_NUM] = {0, MAP_ANON, MAP_PRIVATE | MAP_SHARED}; + int ret, fd; + + fd = open(file, O_CREAT | O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO); + ICUNIT_ASSERT_NOT_EQUAL(fd, -1, fd); + + invalueAddr = reinterpret_cast(VALIDE_ADDR | ADDR_OFFSET); + mem = mmap(invalueAddr, len, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, fd, 0); + ICUNIT_GOTO_EQUAL(mem, MAP_FAILED, mem, EXIT); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT); + + mem = mmap((void *)INVALID_VADDR, len, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, fd, 0); + ICUNIT_GOTO_EQUAL(mem, MAP_FAILED, mem, EXIT); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT); + + mem = mmap((void *)INVALID_VADDR, len, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0); + ICUNIT_GOTO_NOT_EQUAL(mem, MAP_FAILED, mem, EXIT); + ret = munmap(mem, len); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + len = OVER_LEN; + mem = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + ICUNIT_GOTO_EQUAL(mem, MAP_FAILED, mem, EXIT); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT); + + len = MAP_LEN; + mem = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, INVALID_FD); + ICUNIT_GOTO_EQUAL(mem, MAP_FAILED, mem, EXIT); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT); + + len = 0; + mem = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + ICUNIT_GOTO_EQUAL(mem, MAP_FAILED, mem, EXIT); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT); + + len = MAP_LEN; + for (int i = 0; i < FLAG_NUM; i++) { + mem = mmap(NULL, len, PROT_READ | PROT_WRITE, flags[i], fd, 0); + ICUNIT_GOTO_EQUAL(mem, MAP_FAILED, mem, EXIT); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT); + } + +EXIT: + ret = close(fd); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = remove(file); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return 0; +} + +void ItTestMmap006(void) +{ + TEST_ADD_CASE("IT_MEM_MMAP_006", Testcase, TEST_LOS, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mmap_test_007.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mmap_test_007.cpp new file mode 100644 index 00000000..01dce375 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mmap_test_007.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_vm.h" + +#define MAP_LEN 0x200000 +#define MAP_ADDR 0x1200000 +#define MAP_OFFSET 0x100000 + +static int Testcase(void) +{ + size_t len = MAP_LEN; + unsigned long fixAddr = MAP_ADDR; + unsigned long before, after; + size_t shinkLen; + unsigned int flags = MAP_ANON | MAP_SHARED | MAP_FIXED; + void *mem = NULL; + void *prev = NULL; + void *next = NULL; + void *belong = NULL; + int ret; + + mem = mmap((void *)fixAddr, len, PROT_READ | PROT_WRITE, flags, -1, 0); + ICUNIT_GOTO_NOT_EQUAL(mem, MAP_FAILED, mem, EXIT); + + before = fixAddr - MAP_OFFSET; + prev = mmap((void *)before, len, PROT_READ | PROT_WRITE, flags, -1, 0); + ICUNIT_GOTO_NOT_EQUAL(prev, MAP_FAILED, prev, EXIT1); + + after = fixAddr + MAP_OFFSET; + next = mmap((void *)after, len, PROT_READ | PROT_WRITE, flags, -1, 0); + ICUNIT_GOTO_NOT_EQUAL(next, MAP_FAILED, next, EXIT2); + + shinkLen = len - MAP_OFFSET; + belong = mmap((void *)after, shinkLen, PROT_READ | PROT_WRITE, flags, -1, 0); + ICUNIT_GOTO_NOT_EQUAL(belong, MAP_FAILED, belong, EXIT3); + + ret = munmap(prev, len); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = munmap(next, len); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return LOS_OK; + +EXIT1: + ret = munmap(mem, len); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return LOS_NOK; +EXIT2: + ret = munmap(mem, len); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = munmap(prev, len); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return LOS_NOK; +EXIT3: + ret = munmap(prev, len); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = munmap(next, len); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); +EXIT: + return LOS_NOK; +} + +void ItTestMmap007(void) +{ + TEST_ADD_CASE("IT_MEM_MMAP_007", Testcase, TEST_LOS, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mmap_test_008.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mmap_test_008.cpp new file mode 100644 index 00000000..2d024751 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mmap_test_008.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_vm.h" + +#define MAP_OFFSET 0x1000 +#define MAP_ADDR 0x1200000 +#define MAP_LEN 0x2000 + +static int Testcase(void) +{ + unsigned long fixAddr = MAP_ADDR; + unsigned int len = MAP_LEN; + unsigned int flags = MAP_ANON | MAP_SHARED; + void *mem = NULL; + void *memFix = NULL; + void *memNoFix = NULL; + void *pre = NULL; + void *next = NULL; + void *overlay = NULL; + int ret; + + mem = mmap((void *)fixAddr, len, PROT_READ | PROT_WRITE, flags | MAP_FIXED, -1, 0); + ICUNIT_GOTO_NOT_EQUAL(mem, MAP_FAILED, mem, EXIT); + + memFix = mmap((void *)fixAddr, len, PROT_READ | PROT_WRITE, flags | MAP_FIXED, -1, 0); + ICUNIT_GOTO_NOT_EQUAL(memFix, MAP_FAILED, memFix, EXIT1); + ICUNIT_ASSERT_EQUAL(mem, memFix, mem); + + memNoFix = mmap((void *)fixAddr, len, PROT_READ | PROT_WRITE, flags | MAP_FIXED_NOREPLACE, -1, 0); + ICUNIT_ASSERT_EQUAL(memNoFix, MAP_FAILED, memNoFix); + + memNoFix = mmap((void *)(fixAddr - MAP_OFFSET), len, PROT_READ | PROT_WRITE, flags | MAP_FIXED_NOREPLACE, -1, 0); + ICUNIT_ASSERT_EQUAL(memNoFix, MAP_FAILED, memNoFix); + + memNoFix = mmap((void *)(fixAddr + MAP_OFFSET), len, PROT_READ | PROT_WRITE, flags | MAP_FIXED_NOREPLACE, -1, 0); + ICUNIT_ASSERT_EQUAL(memNoFix, MAP_FAILED, memNoFix); + + memNoFix = mmap((void *)(fixAddr - MAP_OFFSET), len + MAP_OFFSET, PROT_READ | PROT_WRITE, + flags | MAP_FIXED_NOREPLACE, -1, 0); + ICUNIT_ASSERT_EQUAL(memNoFix, MAP_FAILED, memNoFix); + + ret = munmap(mem, len); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return LOS_OK; +EXIT1: + ret = munmap(mem, len); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return LOS_NOK; +EXIT: + return LOS_NOK; +} + +void ItTestMmap008(void) +{ + TEST_ADD_CASE("IT_MEM_MMAP_008", Testcase, TEST_LOS, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mmap_test_009.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mmap_test_009.cpp new file mode 100644 index 00000000..57211386 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mmap_test_009.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "it_test_vm.h" + +#define INVALID_PROCESS_ID 100000 +#define MMAP_SIZE 0x1000 +#define PARAM_INIT 0x123 + +/* Test PROT_NONE flag */ +static int Testcase(void) +{ + int ret, param; + int *ptr = NULL; + int status = 0; + pid_t pid = fork(); + ICUNIT_ASSERT_WITHIN_EQUAL(pid, 0, INVALID_PROCESS_ID, pid); + if (pid == 0) { + ptr = (int *)mmap(0, MMAP_SIZE, PROT_NONE, MAP_ANON | MAP_PRIVATE, -1, 0); + ICUNIT_ASSERT_NOT_EQUAL(ptr, MAP_FAILED, ptr); + printf("%d\n", *ptr); + exit(0); + } + + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ret = WIFEXITED(status); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = WIFSIGNALED(status); + ICUNIT_ASSERT_EQUAL(ret, 1, ret); + ret = WTERMSIG(status); + ICUNIT_ASSERT_EQUAL(ret, SIGUSR2, ret); + + pid = fork(); + ICUNIT_ASSERT_WITHIN_EQUAL(pid, 0, INVALID_PROCESS_ID, pid); + if (pid == 0) { + ptr = (int *)mmap(0, MMAP_SIZE, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); + ICUNIT_ASSERT_NOT_EQUAL(ptr, MAP_FAILED, ptr); + *ptr = PARAM_INIT; + ret = mprotect(ptr, MMAP_SIZE, PROT_READ); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(*ptr, PARAM_INIT, *ptr); + ret = mprotect(ptr, MMAP_SIZE, PROT_NONE); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + printf("%d\n", *ptr); + exit(0); + } + + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ret = WIFEXITED(status); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = WIFSIGNALED(status); + ICUNIT_ASSERT_EQUAL(ret, 1, ret); + ret = WTERMSIG(status); + ICUNIT_ASSERT_EQUAL(ret, SIGUSR2, ret); + + return 0; +} + +void ItTestMmap009(void) +{ + TEST_ADD_CASE("IT_MEM_MMAP_009", Testcase, TEST_LOS, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} + diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mmap_test_010.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mmap_test_010.cpp new file mode 100644 index 00000000..d3689038 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mmap_test_010.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "it_test_vm.h" + +#define MMAP_SIZE 0x1000 +#define PARAM_INIT 0x123 + +/* Test PROT_WRITE and PROT_EXEC flag only */ +static int Testcase(void) +{ + int ret; + int *ptr = NULL; + + ptr = (int *)mmap(0, MMAP_SIZE, PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); + ICUNIT_ASSERT_NOT_EQUAL(ptr, MAP_FAILED, ptr); + *ptr = PARAM_INIT; + ICUNIT_ASSERT_EQUAL(*ptr, PARAM_INIT, *ptr); + ret = munmap(ptr, MMAP_SIZE); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ptr = (int *)mmap(0, MMAP_SIZE, PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0); + ICUNIT_ASSERT_NOT_EQUAL(ptr, MAP_FAILED, ptr); + ICUNIT_ASSERT_EQUAL(*ptr, 0, *ptr); + ret = munmap(ptr, MMAP_SIZE); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return 0; +} + +void ItTestMmap010(void) +{ + TEST_ADD_CASE("IT_MEM_MMAP_010", Testcase, TEST_LOS, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} + diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mprotect_test_001.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mprotect_test_001.cpp new file mode 100644 index 00000000..f700a8f2 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mprotect_test_001.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_vm.h" + +static int Testcase(void) +{ + char *p = NULL; + int pageSize; + int ret; + + pageSize = getpagesize(); + + ret = mprotect(0, pageSize, PROT_NONE); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno); + + ret = mprotect(0, pageSize, 0xffff); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno); + + ret = mprotect((void *)0x1000, pageSize, PROT_READ | PROT_WRITE); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno); + + ret = mprotect((void *)0xffffff, pageSize, PROT_READ | PROT_WRITE); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno); + + p = (char *)mmap(NULL, pageSize * 3, PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + ICUNIT_ASSERT_NOT_EQUAL(p, MAP_FAILED, p); + + ret = mprotect(p, pageSize * 4, PROT_READ | PROT_WRITE); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno); + + ret = mprotect(p, pageSize, PROT_READ | PROT_WRITE); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + (void)memset_s(p, pageSize, 0xf, pageSize); + + ret = mprotect(p + pageSize * 2, pageSize, PROT_READ | PROT_WRITE); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + (void)memset_s(p + pageSize * 2, pageSize, 0xf, pageSize); + + ret = munmap(p, pageSize); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return 0; +} + +void ItTestMprotect001(void) +{ + TEST_ADD_CASE("IT_MEM_MPROTECT_001", Testcase, TEST_LOS, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mremap_test_001.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mremap_test_001.cpp new file mode 100644 index 00000000..e9d86cb3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/mremap_test_001.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_vm.h" + +static int Testcase(void) +{ + char *p = NULL; + void *newAddr = NULL; + int pageSize; + int size; + int ret; + + pageSize = getpagesize(); + size = pageSize << 1; + + p = (char *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + ICUNIT_ASSERT_NOT_EQUAL(p, MAP_FAILED, p); + + /* Parameter check */ + newAddr = mremap(0, 0, 0, 0, 0); + ICUNIT_ASSERT_EQUAL(newAddr, MAP_FAILED, newAddr); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno); + + newAddr = mremap(p, size, size, MREMAP_FIXED, 0); + ICUNIT_ASSERT_EQUAL(newAddr, MAP_FAILED, newAddr); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno); + + /* Shrink a region */ + newAddr = mremap(p, size, pageSize, MREMAP_MAYMOVE, 0); + ICUNIT_ASSERT_EQUAL(newAddr, p, newAddr); + + /* Remap a region by same size */ + newAddr = mremap(p, pageSize, pageSize, MREMAP_MAYMOVE, 0); + ICUNIT_ASSERT_EQUAL(newAddr, p, newAddr); + + /* Expand a region */ + newAddr = mremap(p, pageSize, size, MREMAP_MAYMOVE, 0); + ICUNIT_ASSERT_EQUAL(newAddr, p, newAddr); + + /* New region overlapping with the old one */ + newAddr = mremap(p, size, pageSize, MREMAP_MAYMOVE | MREMAP_FIXED, p + pageSize); + ICUNIT_ASSERT_EQUAL(newAddr, MAP_FAILED, newAddr); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno); + + newAddr = mremap(p, size, size, MREMAP_MAYMOVE | MREMAP_FIXED, p - pageSize); + ICUNIT_ASSERT_EQUAL(newAddr, MAP_FAILED, newAddr); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno); + + newAddr = mremap(p, size, size + pageSize, MREMAP_MAYMOVE | MREMAP_FIXED, p - pageSize); + ICUNIT_ASSERT_EQUAL(newAddr, MAP_FAILED, newAddr); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno); + + /* Remap to new addr */ + newAddr = mremap(p, size, size, MREMAP_MAYMOVE | MREMAP_FIXED, p + size); + ICUNIT_ASSERT_EQUAL(newAddr, p + size, newAddr); + + newAddr = mremap(newAddr, size, size, MREMAP_MAYMOVE | MREMAP_FIXED, (char *)newAddr - size); + ICUNIT_ASSERT_EQUAL(newAddr, p, newAddr); + + ret = munmap(p, size); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return 0; +} + +void ItTestMremap001(void) +{ + TEST_ADD_CASE("IT_MEM_MREMAP_001", Testcase, TEST_LOS, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/oom_test_001.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/oom_test_001.cpp new file mode 100644 index 00000000..adec8b50 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/oom_test_001.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_vm.h" + +#define MAX_MEM_SIZE 0x6000000 +/* test page fault oom */ +static int Testcase(void) +{ + int ret; + int status; + int pid; + unsigned int *ptr = NULL; + + ret = fork(); + if (ret == 0) { + ptr = (unsigned int *)mmap(0, MAX_MEM_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); + ICUNIT_ASSERT_NOT_EQUAL(ptr, MAP_FAILED, ptr); + /* expect oom */ + for (int i = 0; i < MAX_MEM_SIZE / PAGE_SIZE; i++) { + *(ptr + i * PAGE_SIZE / sizeof(unsigned int)) = 0; + } + + /* if we go here, phy mem is enough, should increase the MAX_MEM_SIZE and rerun */ + ICUNIT_ASSERT_EQUAL(1, 0, 1); + } else { + pid = ret; + ret = waitpid(pid, &status, 0); + status = WIFSIGNALED(status); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ICUNIT_ASSERT_EQUAL(status, 1, status); + } + + return 0; +} + +void ItTestOom001(void) +{ + TEST_ADD_CASE("IT_MEM_OOM_001", Testcase, TEST_LOS, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/open_wmemstream_test_001.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/open_wmemstream_test_001.cpp new file mode 100644 index 00000000..cb1e2225 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/open_wmemstream_test_001.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "it_test_vm.h" +#include "wchar.h" + +static int testcase(void) +{ + FILE *stream = nullptr; + wchar_t *buf = nullptr; + size_t len = 0; + + stream = open_wmemstream(&buf, &len); + ICUNIT_ASSERT_NOT_EQUAL(stream, nullptr, stream); + + fwprintf(stream, L"hello my world"); + int ret = fflush(stream); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(len, 14, len); + off_t eob = ftello(stream); + ret = fseeko(stream, 0, SEEK_SET); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + fwprintf(stream, L"good-bye"); + ret = fseeko(stream, eob, SEEK_SET); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = fclose(stream); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(len, 8, len); + free(buf); + return 0; +} + +void open_wmemstream_test_001(void) +{ + TEST_ADD_CASE("OPEN_WMEMSTEAM_TEST_001", testcase, TEST_LOS, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/user_copy_test_001.cpp b/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/user_copy_test_001.cpp new file mode 100644 index 00000000..33c20f4c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/basic/mem/vm/smoke/user_copy_test_001.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_vm.h" +#include "signal.h" + +#define INVALID_USER_VADDR 0x1200000 + +static int Testcase(void) +{ + int ret; + sigset_t oldset; + const char *str = "Hi, OHOS."; + + /* sigprocmask 内核系统调用接口通过arch_copy_from_user拷贝用户参数 */ + ret = sigprocmask(SIG_BLOCK, reinterpret_cast(1), &oldset); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, EFAULT, errno); + + ret = sigprocmask(SIG_BLOCK, reinterpret_cast(INVALID_USER_VADDR), &oldset); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, EFAULT, errno); + + /* sigprocmask 内核系统调用接口通过arch_copy_to_user将内核参数拷贝至用户 */ + ret = sigprocmask(SIG_BLOCK, reinterpret_cast(INVALID_USER_VADDR), reinterpret_cast(1)); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, EFAULT, errno); + + ret = sigprocmask(SIG_BLOCK, reinterpret_cast(INVALID_USER_VADDR), + reinterpret_cast(INVALID_USER_VADDR)); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, EFAULT, errno); + + ret = sigprocmask(SIG_BLOCK, reinterpret_cast(INVALID_USER_VADDR), + reinterpret_cast(const_cast(str))); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, EFAULT, errno); + + return 0; +} + +void ItTestUserCopy001(void) +{ + TEST_ADD_CASE("IT_MEM_USER_COPY_001", Testcase, TEST_LOS, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/common/include/iCunit.h b/src/kernel_liteos_a/testsuites/unittest/common/include/iCunit.h new file mode 100644 index 00000000..a8fa009c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/common/include/iCunit.h @@ -0,0 +1,401 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _UNI_ICUNIT_H +#define _UNI_ICUNIT_H + +#include +#include +#include "los_typedef.h" +#include +#include + +typedef unsigned short iUINT16; +typedef unsigned int iUINT32; +typedef signed short iINT16; +typedef signed long iINT32; +typedef char iCHAR; +typedef void iVOID; + +typedef unsigned long iiUINT32; + + +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE 1 +#endif + +#define ICUNIT_SUCCESS 0x00000000 + +#define FUNCTION_TEST (1 << 0) + +#define PRESSURE_TEST (1 << 1) + +#define PERFORMANCE_TEST (1 << 2) + +#define TEST_MODE (FUNCTION_TEST) + +#define TEST_LESSER_MEM 0 + +#define TEST_ADD_CASE(string, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION) \ + do { \ + UINT32 ret; \ + ret = TestCase(); \ + ASSERT_EQ(ret, LOS_OK); \ + } while (0) + +#if 1 +/* * + * 跟踪param和value不同,不做任何处理 + */ +#define ICUNIT_TRACK_EQUAL(param, value, retcode) \ + do { \ + if ((param) != (value)) { \ + EXPECT_EQ((long)(value), (long)(param)); \ + } \ + } while (0) + +/* * + * 跟踪param和value相同,不做任何处理 + */ +#define ICUNIT_TRACK_NOT_EQUAL(param, value, retcode) \ + do { \ + if ((param) == (value)) { \ + EXPECT_NE((long)(value), (long)(param)); \ + } \ + } while (0) + + +#define ICUNIT_ASSERT_NOT_EQUAL_NULL(param, value, retcode) \ + do { \ + if ((param) == (value)) { \ + EXPECT_NE((long)(value), (long)(param)); \ + return NULL; \ + } \ + } while (0) + + +#define ICUNIT_ASSERT_EQUAL_NULL(param, value, retcode) \ + do { \ + if ((param) != (value)) { \ + EXPECT_EQ((long)(value), (long)(param)); \ + return NULL; \ + } \ + } while (0) + + +/* * + * 断言param和value相同,不同则return + */ +#define ICUNIT_ASSERT_EQUAL_VOID(param, value, retcode) \ + do { \ + if ((param) != (value)) { \ + EXPECT_EQ((long)(value), (long)(param)); \ + return; \ + } \ + } while (0) + + +/* * + * 断言param和value不同,相同则return + */ +#define ICUNIT_ASSERT_NOT_EQUAL_VOID(param, value, retcode) \ + do { \ + if ((param) == (value)) { \ + EXPECT_NE((long)(value), (long)(param)); \ + return; \ + } \ + } while (0) + +#define ICUNIT_ASSERT_EQUAL(param, value, retcode) \ + do { \ + if ((param) != (value)) { \ + EXPECT_EQ((long)(param), (long)(value)); \ + return 1; \ + } \ + } while (0) + + +#define ICUNIT_ASSERT_TWO_EQUAL(param, value1, value2, retcode) \ + do { \ + if (((param) != (value1)) && ((param) != (value2))) { \ + EXPECT_EQ((long)(value1), (long)(param)); \ + EXPECT_EQ((long)(value2), (long)(param)); \ + return 1; \ + } \ + } while (0) + +/* * + * 判断param等于value1或value2,不等则跳转到label处 + */ +#define ICUNIT_GOTO_TWO_EQUAL(param, value1, value2, retcode, label) \ + do { \ + if (((param) != (value1)) && ((param) != (value2))) { \ + EXPECT_NE((long)(retcode), (long)(retcode)); \ + goto label; \ + } \ + } while (0) + +/* * + * 断言param和value不同,相同则return + */ +#define ICUNIT_ASSERT_NOT_EQUAL(param, value, retcode) \ + do { \ + if ((param) == (value)) { \ + EXPECT_NE(retcode, retcode); \ + return 1; \ + } \ + } while (0) +/* * + * 断言param不在value1和value2之间就return + */ +#define ICUNIT_ASSERT_WITHIN_EQUAL(param, value1, value2, retcode) \ + do { \ + if ((param) < (value1) || (param) > (value2)) { \ + EXPECT_GE((long)(param), (long)(value1)); \ + EXPECT_LE((long)(param), (long)(value2)); \ + return 1; \ + } \ + } while (0) + + +/* * + * 断言param是否在一定范围内,不在则return + */ +#define ICUNIT_ASSERT_WITHIN_EQUAL_VOID(param, value1, value2, retcode) \ + do { \ + if ((param) < (value1) || (param) > (value2)) { \ + EXPECT_GE((long)(param), (long)(value1)); \ + EXPECT_LE((long)(param), (long)(value2)); \ + return; \ + } \ + } while (0) + + +/* * + * 断言param是否在一定范围内,不在则return + */ +#define ICUNIT_ASSERT_WITHIN_EQUAL_NULL(param, value1, value2, retcode) \ + do { \ + if ((param) < (value1) || (param) > (value2)) { \ + EXPECT_GE((long)(param), (long)(value1)); \ + EXPECT_LE((long)(param), (long)(value2)); \ + return NULL; \ + } \ + } while (0) + + +/* * + * 断言指定个数str1和str2字符串内容相同,不同则return + */ + +#define ICUNIT_ASSERT_SIZE_STRING_EQUAL(str1, str2, strsize, retcode) \ + do { \ + if (strncmp((str1), (str2), (strsize)) != 0) { \ + EXPECT_NE((long)(retcode), (long)(retcode)); \ + return 1; \ + } \ + } while (0) + + +/* * + * 判断param和value是否相同,不同则跳转到label处 + */ +#define ICUNIT_ASSERT_EQUAL_TIME(param, value, retcode, label) \ + do { \ + if ((param) < (value - 1) || (param) > (value + 1)) { \ + EXPECT_NE((long)(retcode), (long)(retcode)); \ + goto label; \ + } \ + } while (0) + + +#if 1 +/* * + * 断言指定个数str1和str2字符串内容相同,不同则return + */ +#define ICUNIT_ASSERT_SIZE_STRING_EQUAL_VOID(str1, str2, size, retcode) \ + do { \ + if (strncmp(str1, str2, size) != 0) { \ + EXPECT_NE((long)(retcode), (long)(retcode)); \ + return; \ + } \ + } while (0) + +/* * + * 断言指定个数str1和str2字符串内容不同,相同则return + */ +#define ICUNIT_ASSERT_SIZE_STRING_NOT_EQUAL(str1, str2, size, retcode) \ + do { \ + if (strncmp(str1, str2, size) == 0) { \ + EXPECT_NE((long)(retcode), (long)(retcode)); \ + return 1; \ + } \ + } while (0) +#endif + +/* * + * 断言str1和str2字符串内容相同,不同则return + */ +#define ICUNIT_ASSERT_STRING_EQUAL(str1, str2, retcode) \ + do { \ + if (strcmp(str1, str2) != 0) { \ + EXPECT_NE((long)(retcode), (long)(retcode)); \ + return 1; \ + } \ + } while (0) + +/* * + * 断言str1和str2字符串内容相同,不同则return + */ +#define ICUNIT_ASSERT_STRING_EQUAL_VOID(str1, str2, retcode) \ + do { \ + if (strcmp(str1, str2) != 0) { \ + EXPECT_NE((long)(retcode), (long)(retcode)); \ + return; \ + } \ + } while (0) + +#define ICUNIT_ASSERT_STRING_EQUAL_RET(str1, str2, retcode, ret) \ + do { \ + if (strcmp(str1, str2) != 0) { \ + EXPECT_NE((long)(retcode), (long)(retcode)); \ + return (ret); \ + } \ + } while (0) + +/* * + * 断言str1和str2字符串内容不同,相同则return + */ +#define ICUNIT_ASSERT_STRING_NOT_EQUAL(str1, str2, retcode) \ + do { \ + if (strcmp(str1, str2) == 0) { \ + EXPECT_NE((long)(retcode), (long)(retcode)); \ + return 1; \ + } \ + } while (0) + +/* * + * 判断param和value是否相同,不同则跳转到label处 + */ +#define ICUNIT_GOTO_EQUAL(param, value, retcode, label) \ + do { \ + if ((param) != (value)) { \ + EXPECT_EQ((long)(value), (long)(param)); \ + goto label; \ + } \ + } while (0) + + +#define ICUNIT_GOTO_EQUAL_IN(param, value1, value2, retcode, label) \ + do { \ + if (((param) != (value1)) && ((param) != (value2))) { \ + EXPECT_NE((long)(retcode), (long)(retcode)); \ + goto label; \ + } \ + } while (0) + +/* * + * 判断param和value是否不同,相同则跳转到label处 + */ +#define ICUNIT_GOTO_NOT_EQUAL(param, value, retcode, label) \ + do { \ + if ((param) == (value)) { \ + EXPECT_NE((long)(value), (long)(param)); \ + goto label; \ + } \ + } while (0) + + +#define ICUNIT_GOTO_WITHIN_EQUAL(param, value1, value2, retcode, label) \ + do { \ + if ((param) < (value1) || (param) > (value2)) { \ + EXPECT_GE((long)(param), (long)(value1)); \ + EXPECT_LE((long)(param), (long)(value2)); \ + goto label; \ + } \ + } while (0) + + +/* * + * 判断str1和str2是否相同,不同则跳转到label处 + */ +#define ICUNIT_GOTO_STRING_EQUAL(str1, str2, retcode, label) \ + do { \ + if (strcmp(str1, str2) != 0) { \ + EXPECT_NE((long)(retcode), (long)(retcode)); \ + goto label; \ + } \ + } while (0) + + +/* * + * 判断str1和str2是否不同,相同则跳转到label处 + */ +#define ICUNIT_GOTO_STRING_NOT_EQUAL(str1, str2, retcode, label) \ + do { \ + if (strcmp(str1, str2) == 0) { \ + EXPECT_NE((long)(retcode), (long)(retcode)); \ + goto label; \ + } \ + } while (0) + +/* * + * 跟踪param和value不同,不做任何处理 + */ +#define ICUNIT_ASSERT_EQUAL_EXIT(param, value, exitcode) \ + do { \ + if ((param) != (value)) { \ + EXPECT_EQ((long)(value), (long)(param)); \ + exit(exitcode); \ + } \ + } while (0) + +#define ICUNIT_ASSERT_NOT_EQUAL_NULL_VOID(param, value, retcode) \ + do { \ + if ((param) == (value)) { \ + EXPECT_NE((long)(value), (long)(param)); \ + return NULL; \ + } \ + } while (0) + +#define ICUNIT_ASSERT_EQUAL_NULL_VOID(param, value, retcode) \ + do { \ + if ((param) != (value)) { \ + EXPECT_EQ((long)(value), (long)(param)); \ + return NULL; \ + } \ + } while (0) + +#endif + +#endif /* _UNI_ICUNIT_H */ diff --git a/src/kernel_liteos_a/testsuites/unittest/common/include/los_typedef.h b/src/kernel_liteos_a/testsuites/unittest/common/include/los_typedef.h new file mode 100644 index 00000000..44ab2d8e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/common/include/los_typedef.h @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* * + * @defgroup los_typedef Type define + * @ingroup kernel + */ + +#ifndef _LOS_TYPEDEF_H +#define _LOS_TYPEDEF_H + +#include "stddef.h" +#include "stdbool.h" +#include "stdint.h" + + +#define OS_STRING(x) #x +#define X_STRING(x) OS_STRING(x) + +/* type definitions */ +typedef unsigned char UINT8; +typedef unsigned short UINT16; +typedef unsigned int UINT32; +typedef signed char INT8; +typedef signed short INT16; +typedef signed int INT32; +typedef float FLOAT; +typedef double DOUBLE; +typedef char CHAR; +typedef unsigned long u_long; +typedef u_long ULong; +typedef long Long; + +#ifdef __LP64__ +typedef long unsigned int UINT64; +typedef long signed int INT64; +typedef unsigned long UINTPTR; +typedef signed long INTPTR; +#else +typedef unsigned long long UINT64; +typedef signed long long INT64; +typedef unsigned int UINTPTR; +typedef signed int INTPTR; +#endif + +#ifdef __LP64__ +typedef __uint128_t UINT128; +typedef INT64 ssize_t; +typedef UINT64 size_t; +#define LOSCFG_AARCH64 +#else +typedef INT32 ssize_t; +typedef UINT32 size_t; +#endif + +typedef UINTPTR AARCHPTR; +typedef size_t BOOL; + +#define VOID void +#define STATIC static + +#ifndef FALSE +#define FALSE 0U +#endif + +#ifndef TRUE +#define TRUE 1U +#endif + +#ifndef NULL +#define NULL ((VOID *)0) +#endif + +#define OS_NULL_BYTE ((UINT8)0xFF) +#define OS_NULL_SHORT ((UINT16)0xFFFF) +#define OS_NULL_INT ((UINT32)0xFFFFFFFF) + +#ifndef USER +#define USER +#endif + +#ifndef LOS_OK +#define LOS_OK 0 +#endif + +#ifndef LOS_NOK +#define LOS_NOK 1 +#endif + +#ifndef LOS_EPERM +#define LOS_EPERM 1 +#endif + +#ifndef LOS_ESRCH +#define LOS_ESRCH 3 +#endif + +#ifndef LOS_ECHILD +#define LOS_ECHILD 10 +#endif + +#ifndef LOS_EINVAL +#define LOS_EINVAL 22 +#endif + +#ifndef LOS_EOPNOTSUPP +#define LOS_EOPNOTSUPP 95 +#endif + +#define OS_FAIL 1 +#define OS_ERROR (UINT32)(-1) +#define OS_INVALID (UINT32)(-1) +#define OS_INVALID_VALUE ((UINT32)0xFFFFFFFF) + +#define asm __asm +#ifdef typeof +#undef typeof +#endif +#define typeof __typeof__ + +#ifndef LOS_LABEL_DEFN +#define LOS_LABEL_DEFN(label) label +#endif + +#ifndef LOSARC_ALIGNMENT +#define LOSARC_ALIGNMENT 8 +#endif +/* And corresponding power of two alignment */ +#ifndef LOSARC_P2ALIGNMENT +#ifdef LOSCFG_AARCH64 +#define LOSARC_P2ALIGNMENT 3 +#else +#define LOSARC_P2ALIGNMENT 2 +#endif +#endif + +#define PAGE_SIZE_SHIFT (12) + +#ifndef PAGE_SIZE +#define PAGE_SIZE (1UL << PAGE_SIZE_SHIFT) +#endif +#define USER_PAGE_SIZE (1UL << 12) + +#if ARM64_CPU_CORTEX_A53 || ARM64_CPU_CORTEX_A57 || ARM64_CPU_CORTEX_A72 +#define CACHE_LINE 64 +#else +#define CACHE_LINE 32 +#endif + +typedef int status_t; +typedef unsigned long vaddr_t; +typedef unsigned long paddr_t; +typedef unsigned int uint; +typedef unsigned long pte_t; + +/* Give a type or object explicit minimum alignment */ +#if !defined(LOSBLD_ATTRIB_ALIGN) +#define LOSBLD_ATTRIB_ALIGN(__align__) __attribute__((aligned(__align__))) +#endif + +/* Assign a defined variable to a specific section */ +#if !defined(LOSBLD_ATTRIB_SECTION) +#define LOSBLD_ATTRIB_SECTION(__sect__) __attribute__((section(__sect__))) +#endif + +/* + * Tell the compiler not to throw away a variable or function. Only known + * available on 3.3.2 or above. Old version's didn't throw them away, + * but using the unused attribute should stop warnings. + */ +#define LOSBLD_ATTRIB_USED __attribute__((used)) + + +#endif /* _LOS_TYPEDEF_H */ diff --git a/src/kernel_liteos_a/testsuites/unittest/common/include/osTest.h b/src/kernel_liteos_a/testsuites/unittest/common/include/osTest.h new file mode 100644 index 00000000..f9c037e2 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/common/include/osTest.h @@ -0,0 +1,498 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _OSTEST_H +#define _OSTEST_H + +#ifndef SWTMR_TEST +#define SWTMR_TEST +#endif +#include "iCunit.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "los_typedef.h" +#include "sys/wait.h" +#include "glob.h" +#include "mntent.h" +#include "securectype.h" +#include "securec.h" +#include +#include +#include +#include +#include + +#ifndef OK +#define OK 0 +#endif + +#define dprintf printf +#define ENOERR OK +#define LOSCFG_BASE_CORE_TSK_CONFIG 1024 + +#define USER_PROCESS_PRIORITY_HIGHEST 10 +#define USER_PROCESS_PRIORITY_LOWEST 31 +#define TEST_TASK_PARAM_INIT(stTestTask, task_name, entry, prio) \ + do { \ + (void)memset_s(&stTestTask, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); \ + stTestTask.pfnTaskEntry = (TSK_ENTRY_FUNC)entry; \ + stTestTask.uwStackSize = LOS_TASK_MIN_STACK_SIZE; \ + stTestTask.pcName = task_name; \ + stTestTask.usTaskPrio = prio; \ + stTestTask.uwResved = LOS_TASK_STATUS_DETACHED; \ + } while (0) + +#ifdef LOSCFG_KERNEL_SMP +#define TEST_TASK_PARAM_INIT_AFFI(stTestTask, task_name, entry, prio, affi) \ + TEST_TASK_PARAM_INIT(stTestTask, task_name, entry, prio) \ + stTestTask.usCpuAffiMask = affi; +#else +#define TEST_TASK_PARAM_INIT_AFFI(stTestTask, task_name, entry, prio, affi) \ + TEST_TASK_PARAM_INIT(stTestTask, task_name, entry, prio) +#endif +#define JFFS_BASE_MTD_ADDR 0x100000 +#define JFFS_BASE_MTD_LEN 0x600000 + +#define LOS_TASK_MIN_STACK_SIZE 2048 +#define TASK_PRIO_TEST 20 +#ifdef LOSCFG_AARCH64 +#define TASK_STACK_SIZE_TEST (LOS_TASK_MIN_STACK_SIZE * 3) +#else +#define TASK_STACK_SIZE_TEST LOS_TASK_MIN_STACK_SIZE +#endif +#define LOS_MS_PER_TICK (OS_SYS_MS_PER_SECOND / LOSCFG_BASE_CORE_TICK_PER_SECOND) + +#define HWI_NUM_INTVALID OS_HWI_MAX_NUM +#define writel(value, address) WRITE_UINT32(value, address) + +extern UINT32 PrepareFileEnv(CHAR *pathList[], CHAR *streamList[], INT32 streamLen[], INT32 listCnt); +extern UINT32 RecoveryFileEnv(CHAR *pathList[], INT32 listCnt); +extern UINT32 PosixPthreadInit(pthread_attr_t *attr, int pri); +extern UINT32 PosixPthreadDestroy(pthread_attr_t *attr, pthread_t thread); + +extern VOID TaskHold(UINT64 sec); + +extern UINT32 TaskCountGetTest(VOID); +extern UINT32 Sem_Count_Get_Test(VOID); +extern UINT32 QueueCountGetTest(VOID); +extern UINT32 Swtmr_Count_Get_Test(VOID); +extern void hal_interrupt_set_affinity(uint32_t irq, uint32_t cpuMask); + +#define TASK_EXISTED_NUM (TaskCountGetTest()) +#define QUEUE_EXISTED_NUM (QueueCountGetTest()) +#define SWTMR_EXISTED_NUM (Swtmr_Count_Get_Test()) +#define SEM_EXISTED_NUM (Sem_Count_Get_Test()) + +extern void TEST_TEST_HwiDelete(unsigned int irq, void *dev_id); +extern void TEST_HwiTrigger(unsigned int irq); +extern void TestExtraTaskDelay(UINT32 tick); +extern UINT64 TestTickCountGet(void); +extern UINT64 TestTickCountByCurrCpuid(void); +extern void TestBusyTaskDelay(UINT32 tick); +extern void *malloc(size_t size); +extern void TEST_DumpCpuid(void); +extern u_long T_random(void); +extern VOID TestAssertWaitDelay(UINT32 *testCount, UINT32 flag); + +UINT32 LosTaskDelay(UINT32 tick); +#define TEST_HwiDelete(ID) TEST_TEST_HwiDelete(ID, NULL) +#define TEST_HwiClear(ID) HalIrqMask(ID) +#define TEST_HwiTriggerDelay LosTaskDelay(200 * LOSCFG_BASE_CORE_TICK_PER_SECOND / 1000) +#define TEST_HwiCreate(ID, prio, mode, Func, arg) LOS_HwiCreate(ID, prio, mode, Func, arg) + +#if HUAWEI_ENV_NFS +#define NFS_MOUNT_DIR "/nfs" +#define NFS_MAIN_DIR NFS_MOUNT_DIR +#define NFS_PATH_NAME "/nfs/test" +#else +#define NFS_MOUNT_DIR "/nfs" +#define NFS_MAIN_DIR NFS_MOUNT_DIR +#define NFS_PATH_NAME "/nfs/test" +#endif + +#define WIN_MOUNT_PATH "/nfs" +#define WIN_NFS_MOUNT_DIR WIN_MOUNT_PATH +#define WIN_NFS_MAIN_DIR WIN_NFS_MOUNT_DIR +#define WIN_NFS_PATH_NAME "/nfs/test" + +#define HWI_NUM_INT0 0 +#define HWI_NUM_INT1 1 +#define HWI_NUM_INT2 2 +#define HWI_NUM_INT3 3 +#define HWI_NUM_INT4 4 +#define HWI_NUM_INT5 5 +#define HWI_NUM_INT6 6 +#define HWI_NUM_INT7 7 +#define HWI_NUM_INT11 11 +#define HWI_NUM_INT12 12 +#define HWI_NUM_INT13 13 +#define HWI_NUM_INT14 14 +#define HWI_NUM_INT15 15 +#define HWI_NUM_INT16 16 +#define HWI_NUM_INT17 17 +#define HWI_NUM_INT18 18 +#define HWI_NUM_INT19 19 +#define HWI_NUM_INT21 21 +#define HWI_NUM_INT22 22 +#define HWI_NUM_INT23 23 +#define HWI_NUM_INT24 24 +#define HWI_NUM_INT25 25 +#define HWI_NUM_INT26 26 +#define HWI_NUM_INT27 27 +#define HWI_NUM_INT28 28 +#define HWI_NUM_INT30 30 +#define HWI_NUM_INT31 31 +#define HWI_NUM_INT32 32 +#define HWI_NUM_INT33 33 +#define HWI_NUM_INT34 34 +#define HWI_NUM_INT35 35 +#define HWI_NUM_INT42 42 +#define HWI_NUM_INT45 45 +#define HWI_NUM_INT46 46 +#define HWI_NUM_INT50 50 +#define HWI_NUM_INT55 55 +#define HWI_NUM_INT56 56 +#define HWI_NUM_INT57 57 +#define HWI_NUM_INT58 58 +#define HWI_NUM_INT59 59 +#define HWI_NUM_INT60 60 +#define HWI_NUM_INT61 61 +#define HWI_NUM_INT63 63 +#define HWI_NUM_INT62 62 +#define HWI_NUM_INT68 68 +#define HWI_NUM_INT69 69 + +#define HWI_NUM_INT95 95 +#define HWI_NUM_INT114 114 +#define HWI_NUM_INT169 169 + +#if defined TESTPBXA9 +#define HWI_NUM_TEST HWI_NUM_INT56 +#define HWI_NUM_TEST1 HWI_NUM_INT57 +#define HWI_NUM_TEST0 HWI_NUM_INT58 +#define HWI_NUM_TEST2 HWI_NUM_INT59 +#define HWI_NUM_TEST3 HWI_NUM_INT60 +#elif defined TEST3518EV300 +#define HWI_NUM_TEST0 HWI_NUM_INT58 +#define HWI_NUM_TEST HWI_NUM_INT59 +#define HWI_NUM_TEST1 HWI_NUM_INT60 +#define HWI_NUM_TEST2 HWI_NUM_INT61 +#define HWI_NUM_TEST3 HWI_NUM_INT68 +#elif defined TEST3516DV300 +#define HWI_NUM_TEST HWI_NUM_INT56 +#define HWI_NUM_TEST1 HWI_NUM_INT57 +#define HWI_NUM_TEST0 HWI_NUM_INT58 +#define HWI_NUM_TEST2 HWI_NUM_INT59 +#define HWI_NUM_TEST3 HWI_NUM_INT60 +#endif + +#define TEST_TASKDELAY_1TICK 1 +#define TEST_TASKDELAY_2TICK 2 +#define TEST_TASKDELAY_4TICK 4 +#define TEST_TASKDELAY_10TICK 10 +#define TEST_TASKDELAY_20TICK 20 +#define TEST_TASKDELAY_50TICK 50 + +#define uart_printf_func printf + +#ifndef VFS_STAT_PRINTF +#define VFS_STAT_PRINTF 0 +#endif + +#ifndef VFS_STATFS_PRINTF +#define VFS_STATFS_PRINTF 0 +#endif + +#define OPEN_FILE_MAX 20 + +#define HUAWEI_ENV_NFS 0 + +#ifndef TEST_RESOURCELEAK_CHECK +#define TEST_RESOURCELEAK_CHECK 1 +#endif + +#ifndef TEST_MODULE_CHECK +#define TEST_MODULE_CHECK 1 +#endif + +extern UINT32 g_shellTestQueueID; +extern UINT32 g_testCount; +extern UINT32 g_testCount1; +extern UINT32 g_testCount2; +extern UINT32 g_testCount3; +extern UINT32 g_flowcheck; +extern UINT32 g_failResult; +extern UINT32 g_passResult; +extern UINT32 g_testTskHandle; +extern UINT32 g_testTaskID01; +extern UINT32 g_testTaskID02; +extern UINT32 g_testTaskID03; +extern UINT32 g_testTaskID04; +extern UINT32 g_hwiNum1; +extern UINT32 g_hwiNum2; +extern UINT32 g_semID; +extern UINT32 g_semID2; +extern UINT32 g_mutexTest; +extern UINT32 g_cpupTestCount; +extern UINT16 g_swTmrID; +extern UINT32 g_semID; +extern UINT32 g_testQueueID01; +extern UINT32 g_testQueueID02; +extern UINT32 g_testQueueID03; +extern UINT32 g_testTskHandle; +extern UINT32 g_leavingTaskNum; +extern UINT32 g_mAuwTestTaskID[32]; +extern UINT8 g_mUsIndex; +extern UINT32 g_usSemID3[]; +extern UINT32 g_testPeriod; +extern BOOL g_isAddArray; +extern BOOL g_isSpinorInit; +extern BOOL g_isSdInit; +extern UINT32 g_getTickConsume; +extern UINT32 g_waitTestCount; +extern INT32 g_libFilesystem; + +extern UINT32 GetTimer2Value(VOID); +extern int hinand_erase(unsigned long start, unsigned long size); +#define hispinor_erase(start, size) \ + do { \ + struct erase_info opts; \ + struct mtd_info *pstMtd; \ + pstMtd = get_mtd("spinor"); \ + (void)memset_s(&opts, sizeof(opts), 0, sizeof(opts)); \ + opts.addr = start; \ + opts.len = size; \ + pstMtd->erase(pstMtd, &opts); \ + } while (0) +extern void ipc_gmac_init(void); + +extern UINT32 Mem_Consume_Show(void); +extern VOID shell_cmd_register(void); +extern INT32 OsShellCmdSystemInfo(INT32 argc, const CHAR **argv); +extern UINT32 OsShellCmdDumpTask(INT32 argc, const CHAR **argv); +extern UINT32 OsShellCmdTaskCntGet(VOID); +extern UINT32 OsShellCmdSwtmrCntGet(VOID); +extern void msleep(unsigned int msecs); +extern unsigned int sleep(unsigned int seconds); +extern int usleep(unsigned useconds); + +extern VOID ipc_network_init(void); +#ifdef LOSCFG_DRIVERS_MMC +extern INT32 SD_MMC_Host_init(void); +#endif +extern VOID rdk_fs_init(void); +extern VOID jffs2_fs_init(void); +extern VOID ProcFsInit(void); + +extern UINT32 LOS_MemTotalUsedGet(VOID *pool); +extern VOID ptestTickConsume(VOID); +extern UINT32 TEST_TskDelete(UINT32 taskID); +extern UINT32 TEST_SemDelete(UINT32 semHandle); +extern VOID irq_trigger(unsigned int irq); +extern VOID TestPartInit(char *type, UINT32 startAddr, UINT32 length); +extern VOID TestPartDelete(char *type); + +extern VOID TestRunShell(VOID); + +extern VOID It_Usb_AutoTest(VOID); +extern VOID Test_hid_dev_mode(VOID); + +extern UINT32 usbshell_cmd_reg(VOID); +extern void usbshell_queue_control(VOID); +extern UINT32 OsTestInit(VOID); + +extern void TEST_DT_COMMON(void); + +extern void it_process_testcase(void); +extern void it_pthread_testcase(void); +extern void it_mutex_test(void); +extern void it_rwlock_test(void); +extern void it_spinlock_test(void); + +/* Format options (3rd argument of f_mkfs) */ +#define TEST_FM_FAT 0x01 +#define TEST_FM_FAT32 0x02 +#define TEST_FM_EXFAT 0x04 +#define TEST_FM_ANY 0x07 +#define TEST_FM_SFD 0x08 + +#define BIG_FD 512 +typedef struct testrunParam { + CHAR testcase_sequence[16]; + CHAR testcase_num[16]; + CHAR testcase_layer[32]; + CHAR testcase_module[32]; + CHAR testcase_level[16]; + CHAR testcase_type[16]; + CHAR testcase_id[128]; +} TEST_RUN_PARAM; + +typedef enum test_type { + HOST_U, // USB U PERFORMANCE + HOST_MUTIL, // MUTIL + HOST_DISK, // USB DISKPARTION + HOST_HUB, // USB HUB + HOST_ETH, // USB HOST ETH + USB_SMP, + HOST_UVC, // USB HOST UVC + HOST_NULL +} usb_test_type; + + +#define SHELLTEST_QUEUE_BUFSIZE sizeof(TEST_RUN_PARAM) +#ifdef LOSCFG_DRIVERS_USB + +void Test_usb_shellcmd(controller_type ctype, device_type dtype, usb_test_type typetest); +#endif + +extern int Gettid(void); + +/* like the ctime/asctime api, use static buffer, though not thread-safe. */ +static inline const char *Curtime() +{ + struct timespec ts; + struct tm t; + static char buf[32]; + (void)clock_gettime(CLOCK_REALTIME, &ts); + (void)localtime_r(&ts.tv_sec, &t); + (void)sprintf_s(buf, sizeof(buf), "%d-%02d-%02d %02d:%02d:%02d.%06ld", t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, t.tm_hour, + t.tm_min, t.tm_sec, ts.tv_nsec / 1000); + return buf; +} + +#define LogPrintln(fmt, ...) \ + printf("%s [%d] %s:%d " fmt "%c", Curtime(), Gettid(), __FILE__, __LINE__, ##__VA_ARGS__, \ + ('\n' == " " fmt[sizeof(" " fmt) - 2]) ? '\0' : '\n') // trailing newline is auto appended + +#if !_REDIR_TIME64 || defined(__LP64__) +#define TIME_F "ld" +#else +#define TIME_F "lld" +#endif + +static void noprintf (...) +{ + return; +} +#define TEST_PRINT printf + +/* the files with different access privilege used in testcases are define below */ +#define FILEPATH_ENOENT "/storage/test_nosuchfile.txt" +#define FILEPATHLEN_ENOENT (strlen(FILEPATH_ENOENT) +1U) + +#define FILEPATH_NOACCESS "noaccessssssssssssssssssssssssssssssssssssssssssss" +#define FILEPATHLEN_NOACCESS (strlen(FILEPATH_NOACCESS) +1U) + +#define FILEPATH_000 "/storage/test_000.txt" +#define FILEPATHLEN_000 (strlen(FILEPATH_000) +1U) + +#define FILEPATH_775 "/storage/test_775.txt" +#define FILEPATHLEN_775 (strlen(FILEPATH_775) +1U) + +#define FILEPATH_755 "/storage/test_775.txt" +#define FILEPATHLEN_755 (strlen(FILEPATH_755) +1U) + +#define FILEPATH_RELATIVE "./1.txt" +#define FILEPATHLEN_RELATIVE (strlen(FILEPATH_RELATIVE) +1U) + +#define DIRPATH_775 "/storage" + +#define FD_EBADF 513 +#define FD_EFAULT -1000 + +#define PATHNAME_ENAMETOOLONG "ENAMETOOLONG12345678912345678912345678912345678912345678912345678912345678911111\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789\ +12345678912345678912345678913245678912345678912345678913245678913456789123456789" + +#endif /* _OSTEST_H */ diff --git a/src/kernel_liteos_a/testsuites/unittest/common/osTest.cpp b/src/kernel_liteos_a/testsuites/unittest/common/osTest.cpp new file mode 100644 index 00000000..e96863ed --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/common/osTest.cpp @@ -0,0 +1,475 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "osTest.h" +#include +#include + +UINT32 g_shellTestQueueID; +INT32 g_iCunitErrCode = 0; +INT32 g_iCunitErrLineNo = 0; + +UINT32 g_testTskHandle; +UINT32 g_testCount; +UINT32 g_flowcheck = 0; +UINT32 g_failResult = 0; +UINT32 g_passResult = 0; + +#ifdef TEST1980 +UINT32 g_testhwiFlag; +UINT32 g_testCpuMask; +#endif + +UINT32 g_testCount1; +UINT32 g_testCount2; +UINT32 g_testCount3; +UINT32 g_testTaskID01; +UINT32 g_testTaskID02; +UINT32 g_testTaskID03; +UINT32 g_testTaskID04; +UINT32 g_hwiNum1; +UINT32 g_hwiNum2; +UINT32 g_semID; +UINT32 g_semID2; +UINT32 g_mutexTest; +UINT32 g_cpupTestCount; +UINT32 g_waitTestCount; +UINT32 g_testPeriod; + +UINT16 g_swTmrID; +UINT32 g_testQueueID01; +UINT32 g_testQueueID02; +UINT32 g_testQueueID03; +UINT32 g_leavingTaskNum; +UINT32 g_mAuwTestTaskID[32] = {0}; +UINT32 g_getTickConsume = 0; +CHAR g_libcPathname[50] = "/usr/jffs0"; +UINT32 g_testCircleCount = 0; + +UINT32 g_fatFilesystem; +UINT8 g_mUsIndex; + +#if TEST_MODULE_CHECK == 1 + +extern UINT32 g_FailModelResult[]; +extern UINT32 g_PassModelResult[]; +extern UINT32 g_ExecutModelNum[]; +#endif +extern char *StrLayer[]; +extern char *StrLevel[]; +extern char *StrType[]; + +extern char *StrModule[]; +extern UINT32 g_ModelNum; + +#ifdef LOSCFG_USER_TEST_FS_FAT +#define TEST_FAT32 0x02 +#define TEST_EXFAT 0x04 +#endif + +BOOL g_isSpinorInit = FALSE; +BOOL g_isSdInit = FALSE; +BOOL g_isUartDevInit = FALSE; +BOOL g_isTcpipInit = FALSE; +BOOL g_isInitSerial = FALSE; +UINT32 g_vfsCyclesCount = 0; +INT32 g_serialInitFlag = -1; +BOOL g_isAddArray = TRUE; +BOOL g_isUsbInit = FALSE; +BOOL g_isIpcGmacInit = FALSE; + +BOOL g_isDriversRandomInit = FALSE; + +BOOL g_isHisiEthSetPhyModeInit = FALSE; + +BOOL g_isVfsInit = FALSE; +BOOL g_isProcInit = FALSE; + +INT32 g_libFilesystem = -1; +enum { + LIB_USE_FAT = 1, + LIB_USE_JFFS2, +}; +#ifdef LOSCFG_DRIVERS_USB +VOID test_init_usb(controller_type ctype, device_type dtype); +#endif +VOID test_init_ipc_gmac(VOID); +VOID test_init_proc(VOID); +VOID test_init_sd(VOID); +VOID TestInitVfs(VOID); +VOID test_init_spinor(VOID); +VOID test_deinit_jffs(VOID); +VOID test_mtd_jffs(VOID); + +UINT32 PrepareFileEnv(CHAR *pathList[], CHAR *streamList[], INT32 streamLen[], INT32 listCnt) +{ + CHAR nameBuf[256] = {0}; + for (UINT32 i = 0; i < listCnt; i++) { + UINT32 ret = access(pathList[i], 0); + if (ret == 0) { + ret = memcpy_s(nameBuf, sizeof(nameBuf), pathList[i], strlen(pathList[i]) + 1); + if (ret != 0) { + return -1; + } + ret = strcat_s(nameBuf, sizeof(nameBuf), "_bak_for_test"); + if (ret != 0) { + return -1; + } + ret = rename(pathList[i], nameBuf); + if (ret != 0) { + return -1; + } + } + FILE *fp = fopen(pathList[i], "w"); + if (fp == NULL) { + return -1; + } + ret = fwrite(streamList[i], 1, streamLen[i], fp); + if (ret != streamLen[i]) { + (VOID)fclose(fp); + return -1; + } + ret = fclose(fp); + if (ret != 0) { + printf("%d\n", errno); + } + } + return 0; +} + +UINT32 RecoveryFileEnv(CHAR *pathList[], INT32 listCnt) +{ + UINT32 ret; + CHAR nameBuf[256] = {0}; + for (UINT32 i = 0; i < listCnt; i++) { + ret = remove(pathList[i]); + if (ret != 0) { + printf("ret = %d, err = %d\n", ret, errno); + } + ret = memcpy_s(nameBuf, sizeof(nameBuf), pathList[i], strlen(pathList[i]) + 1); + if (ret != 0) { + return -1; + } + ret = strcat_s(nameBuf, sizeof(nameBuf), "_bak_for_test"); + if (ret != 0) { + return -1; + } + ret = access(nameBuf, 0); + if (ret == 0) { + ret = rename(nameBuf, pathList[i]); + if (ret != 0) { + return -1; + } + } + } + return 0; +} + +VOID Wfi(VOID) +{ + __asm__ __volatile__("wfi" : : : "memory"); +} + +VOID Dmb(VOID) +{ + __asm__ __volatile__("dmb" : : : "memory"); +} + +VOID Dsb(VOID) +{ + __asm__ __volatile__("dsb" : : : "memory"); +} + +__attribute__((weak)) int Gettid() +{ + return syscall(SYS_gettid); +} + +UINT32 LosCurTaskIDGet() +{ + return Gettid(); +} + + +UINT32 LosTaskDelay(UINT32 tick) +{ + return usleep(10 * tick * 1000); +} + +VOID TestExtraTaskDelay(UINT32 uwTick) +{ +#ifdef LOSCFG_KERNEL_SMP + // trigger task schedule may occor on another core + // needs adding delay and checking status later + LosTaskDelay(uwTick); +#else + // do nothing +#endif +} + +extern volatile UINT64 g_tickCount[]; +UINT64 TestTickCountGet(VOID) +{ + /* not use LOS_TickCountGet for now, + cause every timer is not match with others. + use cpu0 timer instead. */ + return clock(); +} + +UINT64 TestTickCountByCurrCpuid(VOID) +{ + return clock(); +} + +/* + * different from calling LOS_TaskDelay, + * this func will not yield this task to another one. + */ +VOID TestBusyTaskDelay(UINT32 tick) +{ + UINT64 runtime = 0; + + runtime = TestTickCountByCurrCpuid() + tick; + while (1) { + if (runtime <= TestTickCountByCurrCpuid()) { + break; + } + Wfi(); + } +} + +VOID TestAssertBusyTaskDelay(UINT32 timeout, UINT32 flag) +{ + UINT64 runtime = 0; + + runtime = TestTickCountGet() + timeout; + while (1) { + if ((runtime <= TestTickCountGet()) || (g_testCount == flag)) { + break; + } + Wfi(); + } +} + +VOID TestAssertWaitDelay(UINT32 *testCount, UINT32 flag) +{ + while (*testCount != flag) { + usleep(1); + } +} + +UINT32 PosixPthreadInit(pthread_attr_t *attr, int pri) +{ + UINT32 uwRet = 0; + struct sched_param sp; + + uwRet = pthread_attr_init(attr); + ICUNIT_GOTO_EQUAL(uwRet, 0, uwRet, NOK); + + uwRet = pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED); + ICUNIT_GOTO_EQUAL(uwRet, 0, uwRet, NOK); + + sp.sched_priority = pri; + uwRet = pthread_attr_setschedparam(attr, &sp); + ICUNIT_GOTO_EQUAL(uwRet, 0, uwRet, NOK); + + return LOS_OK; +NOK: + return LOS_NOK; +} + +UINT32 PosixPthreadDestroy(pthread_attr_t *attr, pthread_t thread) +{ + UINT32 uwRet = 0; + + uwRet = pthread_join(thread, NULL); + ICUNIT_GOTO_EQUAL(uwRet, 0, uwRet, NOK); + + uwRet = pthread_attr_destroy(attr); + ICUNIT_GOTO_EQUAL(uwRet, 0, uwRet, NOK); + + return LOS_OK; +NOK: + return LOS_NOK; +} + +VOID TestInitVfs(VOID) +{ +#if defined(LOSCFG_FS_VFS) + if (g_isVfsInit) { + return; + } + + extern VOID los_vfs_init(VOID); + los_vfs_init(); + g_isVfsInit = TRUE; + +#endif +} + +VOID TestInitDriversRandom(VOID) +{ + if (g_isDriversRandomInit) { + return; + } + +#if defined(LOSCFG_DRIVERS_RANDOM) + + printf("random init ...\n"); + extern int ran_dev_register(VOID); + ran_dev_register(); + +#endif + +#if defined(LOSCFG_HW_RANDOM_ENABLE) + + extern int random_hw_dev_register(VOID); + printf("random_hw init ...\n"); + if (random_hw_dev_register() != 0) { + printf("Failed!\n"); + } + +#endif + + g_isDriversRandomInit = TRUE; +} + +VOID TestInitUartDev(VOID) {} + +/* **************************************** +Function:Test_PartInit +Description: create a partition for testing,partition num is 0,mount point is jffs0 +Input: + [1]type: "spinor" + [2]start_addr: the partition start address + [3]length: the partition length +Output: None +Return: None +***************************************** */ +VOID TestPartInit(char *type, UINT32 start_addr, UINT32 length) +{ +#if defined(LOSCFG_FS_JFFS) + int uwRet = 0; + + if ((uwRet = add_mtd_partition(type, start_addr, length, 0)) != 0) + PRINT_ERR("add %s partition failed, return %d\n", type, uwRet); + else { + printf("[OK] add %s partition successful\n", type); + if (strcmp(type, "spinor") == 0) { + if ((uwRet = mount("/dev/spinorblk0", "/jffs0", "jffs", 0, NULL)) != 0) + PRINT_ERR("mount jffs0 failed,err %d\n", uwRet); + else + printf("[OK] mount jffs0 successful\n"); + } + } +#endif + return; +} + +/* **************************************** +Function:Test_PartDelete +Description: delete the partition for test +Input: + [1]type: "spinor" +Output: None +Return: None +***************************************** */ +VOID TestPartDelete(char *type) +{ +#if defined(LOSCFG_FS_JFFS) + + int uwRet = 0; + char *point = ""; + + if (strcmp(type, "spinor") == 0) { + point = "/jffs0"; + } + + if ((uwRet = umount(point)) != 0) { + PRINT_ERR("umount %s failed,err %d.\n", point, uwRet); + } else { + printf("[OK] umount %s OK.\n", point); + if ((uwRet = delete_mtd_partition(0, type)) != 0) + PRINT_ERR("delete %s partition failed, return %d\n", type, uwRet); + else + printf("[OK] delete %s partition OK.\n", type); + } +#endif + return; +} + +/* * + * dir: what you want to delete force + */ +int RemoveDir(const char *dir) +{ + char cur_dir[] = "."; + char up_dir[] = ".."; + char dir_name[128] = { 0 }; + DIR *dirp = NULL; + struct dirent *dp = NULL; + struct stat dir_stat; + int ret; + + if (access(dir, F_OK) != 0) { + return 0; + } + + if (stat(dir, &dir_stat) < 0) { + perror("get directory stat error"); + return -1; + } + + if (S_ISREG(dir_stat.st_mode)) { + remove(dir); + } else if (S_ISDIR(dir_stat.st_mode)) { + dirp = opendir(dir); + while ((dp = readdir(dirp)) != NULL) { + if ((strcmp(cur_dir, dp->d_name) == 0) || (strcmp(up_dir, dp->d_name) == 0)) { + continue; + } + + ret = sprintf_s(dir_name, sizeof(dir_name), "%s/%s", dir, dp->d_name); + if (ret < 0) { + perror("sprintf dir_name error"); + closedir(dirp); + return -1; + } + RemoveDir(dir_name); + } + closedir(dirp); + + rmdir(dir); /* now dir is empty */ + } else { + perror("unknown file type!"); + } + return 0; +} diff --git a/src/kernel_liteos_a/testsuites/unittest/config.gni b/src/kernel_liteos_a/testsuites/unittest/config.gni new file mode 100644 index 00000000..b7e6bf85 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/config.gni @@ -0,0 +1,181 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("$root_out_dir/config.gni") +TEST_UNITTEST_DIR = rebase_path(".") +declare_args() { + liteos_container_test_enable = false + liteos_fuzz_test_enable = false +} + +TEST_LEVEL_LOW = 1 +TEST_LEVEL_MIDDLE = 3 +TEST_LEVEL_HIGH = 5 + +# 0: don`t generate +# TEST_LEVEL_LOW: only generate xxx_unittest_door.bin (smoke) +# TEST_LEVEL_MIDDLE: generate xxx_unittest_door.bin (smoke) & xxx_unittest.bin (smoke + full) +# TEST_LEVEL_HIGH: generate xxx_unittest_door.bin (smoke) & xxx_unittest.bin (smoke + full) & xxx_unittest_pressure.bin (pressure) +LOSCFG_USER_TEST_LEVEL = TEST_LEVEL_HIGH + +# "default": depend on board_name +# "enable": those testsuites testing for SMP is enable +# "disable": those testsuites is disable +LOSCFG_USER_TEST_SMP = "default" + +########## basic test ########## +# Control switch for basic function test +LOSCFG_USER_TEST_BASIC = true + +# Module list +LOSCFG_USER_TEST_DYNLOAD = true +LOSCFG_USER_TEST_EXC = true +LOSCFG_USER_TEST_MEM_SHM = true +LOSCFG_USER_TEST_MEM_VM = true + +########## process test ########## +# Control switch for process&pthread function test +LOSCFG_USER_TEST_PROCESS_THREAD = true + +# Module list +LOSCFG_USER_TEST_PROCESS_BASIC_PROCESS = true +LOSCFG_USER_TEST_PROCESS_BASIC_PTHREAD = true +LOSCFG_USER_TEST_PROCESS_LOCK_MUTEX = true +LOSCFG_USER_TEST_PROCESS_LOCK_RWLOCK = true +LOSCFG_USER_TEST_PROCESS_LOCK_SPINLOCK = true + +########## extended test ########## +# Control switch for extended function test +LOSCFG_USER_TEST_EXTENDED = true + +# Module list +LOSCFG_USER_TEST_IPC = false +LOSCFG_USER_TEST_LITEIPC = false +LOSCFG_USER_TEST_SIGNAL = true +LOSCFG_USER_TEST_TRACE = false + +########## drivers test ########## +# Control switch for drivers function test +LOSCFG_USER_TEST_DRIVERS = true + +# Module list +LOSCFG_USER_TEST_DRIVERS_HID = true +LOSCFG_USER_TEST_DRIVERS_STORAGE = true + +########## fs test ########## +# Control switch for fs function test +LOSCFG_USER_TEST_FS = true + +# Module list +LOSCFG_USER_TEST_FS_JFFS = false +LOSCFG_USER_TEST_FS_PROC = false +LOSCFG_USER_TEST_FS_VFAT = false + +########## libc test ########## +# Control switch for libc & posix function test +LOSCFG_USER_TEST_LIBC = true + +# Module list +LOSCFG_USER_TEST_LIBC_IO = true +LOSCFG_USER_TEST_LIBC_MISC = true +LOSCFG_USER_TEST_LIBC_POSIX_MEM = true +LOSCFG_USER_TEST_LIBC_POSIX_MQUEUE = true +LOSCFG_USER_TEST_LIBC_POSIX_PTHREAD = false +LOSCFG_USER_TEST_LIBC_SYS = true +LOSCFG_USER_TEST_LIBC_TIME_CLOCK = true +LOSCFG_USER_TEST_LIBC_TIME_TIMER = true +LOSCFG_USER_TEST_LIBC_UTIL = true + +########## net test ########## +# Control switch for network function test +LOSCFG_USER_TEST_NET = true + +# Module list +LOSCFG_USER_TEST_NET_NETDB = true +LOSCFG_USER_TEST_NET_RESOLV = true +LOSCFG_USER_TEST_NET_SOCKET = true + +########## security test ########## +# Control switch for security function test +LOSCFG_USER_TEST_SECURITY = true + +# Module list +LOSCFG_USER_TEST_SECURITY_CAPABILITY = true +LOSCFG_USER_TEST_SECURITY_REUGID = true +LOSCFG_USER_TEST_SECURITY_VID = true + +LOSCFG_USER_TEST_PROCESS_FS = false +if (defined(LOSCFG_PROC_PROCESS_DIR) || liteos_container_test_enable == true) { + LOSCFG_USER_TEST_PROCESS_FS = true +} + +########## container test ########## +LOSCFG_USER_TEST_CONTAINER = false +LOSCFG_USER_TEST_PID_CONTAINER = false +LOSCFG_USER_TEST_UTS_CONTAINER = false +LOSCFG_USER_TEST_MNT_CONTAINER = false +LOSCFG_USER_TEST_IPC_CONTAINER = false +LOSCFG_USER_TEST_TIME_CONTAINER = false +LOSCFG_USER_TEST_USER_CONTAINER = false +LOSCFG_USER_TEST_NET_CONTAINER = false +if (defined(LOSCFG_KERNEL_CONTAINER) || liteos_container_test_enable == true) { + LOSCFG_USER_TEST_CONTAINER = true + if (defined(LOSCFG_PID_CONTAINER) || liteos_container_test_enable == true) { + LOSCFG_USER_TEST_PID_CONTAINER = true + } + if (defined(LOSCFG_UTS_CONTAINER) || liteos_container_test_enable == true) { + LOSCFG_USER_TEST_UTS_CONTAINER = true + } + if (defined(LOSCFG_MNT_CONTAINER) || liteos_container_test_enable == true) { + LOSCFG_USER_TEST_MNT_CONTAINER = true + } + if (defined(LOSCFG_IPC_CONTAINER) || liteos_container_test_enable == true) { + LOSCFG_USER_TEST_IPC_CONTAINER = true + } + if (defined(LOSCFG_TIME_CONTAINER) || liteos_container_test_enable == true) { + LOSCFG_USER_TEST_TIME_CONTAINER = true + } + if (defined(LOSCFG_USER_CONTAINER) || liteos_container_test_enable == true) { + LOSCFG_USER_TEST_USER_CONTAINER = true + } + if (defined(LOSCFG_NET_CONTAINER) || liteos_container_test_enable == true) { + LOSCFG_USER_TEST_NET_CONTAINER = true + } +} + +LOSCFG_USER_TEST_PROCESS_PLIMITS = false +if (defined(LOSCFG_KERNEL_PLIMITS) || liteos_container_test_enable == true) { + LOSCFG_USER_TEST_PROCESS_PLIMITS = true +} + +########## fuzz test ########## +LOSCFG_USER_FUZZ_TEST = false +if (liteos_fuzz_test_enable == true) { + LOSCFG_USER_FUZZ_TEST = true +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/BUILD.gn b/src/kernel_liteos_a/testsuites/unittest/container/BUILD.gn new file mode 100644 index 00000000..20273997 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/BUILD.gn @@ -0,0 +1,88 @@ +# Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("./config.gni") + +config("container_config") { + cflags = [] + if (defined(LOSCFG_USER_TEST_PID_CONTAINER)) { + cflags += [ "-DLOSCFG_USER_TEST_PID_CONTAINER" ] + } + if (defined(LOSCFG_USER_TEST_UTS_CONTAINER)) { + cflags += [ "-DLOSCFG_USER_TEST_UTS_CONTAINER" ] + } + if (defined(LOSCFG_USER_TEST_MNT_CONTAINER)) { + cflags += [ "-DLOSCFG_USER_TEST_MNT_CONTAINER" ] + } + if (defined(LOSCFG_USER_TEST_IPC_CONTAINER)) { + cflags += [ "-DLOSCFG_USER_TEST_IPC_CONTAINER" ] + } + if (defined(LOSCFG_USER_TEST_TIME_CONTAINER)) { + cflags += [ "-DLOSCFG_USER_TEST_TIME_CONTAINER" ] + } + if (defined(LOSCFG_USER_TEST_USER_CONTAINER)) { + cflags += [ "-DLOSCFG_USER_TEST_USER_CONTAINER" ] + } + if (defined(LOSCFG_USER_TEST_NET_CONTAINER)) { + cflags += [ "-DLOSCFG_USER_TEST_NET_CONTAINER" ] + } + cflags_cc = cflags +} + +if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_LOW) { + unittest("liteos_a_container_unittest_door") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + include_dirs = common_include_dirs + sources = sources_entry + sources += sources_smoke + sources_full = [] + sources += sources_full + configs = [ + "..:public_config_for_door", + ":container_config", + ] + deps = [ "$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR:libsec_shared" ] + } +} + +if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_MIDDLE) { + unittest("liteos_a_container_unittest") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + include_dirs = common_include_dirs + sources = sources_entry + sources += sources_smoke + sources += sources_full + configs = [ + "..:public_config_for_all", + ":container_config", + ] + deps = [ "$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR:libsec_shared" ] + } +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/It_container_test.cpp b/src/kernel_liteos_a/testsuites/unittest/container/It_container_test.cpp new file mode 100644 index 00000000..f0b37474 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/It_container_test.cpp @@ -0,0 +1,1394 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include "It_container_test.h" + +const char *USERDATA_DIR_NAME = "/userdata"; +const char *ACCESS_FILE_NAME = "/userdata/mntcontainertest"; +const char *MNT_ACCESS_FILE_NAME = "/mntcontainertest"; +const char *USERDATA_DEV_NAME = "/dev/mmcblk0p2"; +const char *FS_TYPE = "vfat"; + +const int BIT_ON_RETURN_VALUE = 8; +const int STACK_SIZE = 1024 * 1024; +const int CHILD_FUNC_ARG = 0x2088; +static const int TRY_COUNT = 5; +static const int OFFSET = 2; + +int ChildFunction(void *args) +{ + (void)args; + const int sleep_time = 2; + sleep(sleep_time); + return 0; +} + +pid_t CloneWrapper(int (*func)(void *), int flag, void *args) +{ + pid_t pid; + char *stack = (char *)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, + -1, 0); + if (stack == MAP_FAILED) { + return -1; + } + char *stackTop = stack + STACK_SIZE; + + pid = clone(func, stackTop, flag, args); + munmap(stack, STACK_SIZE); + return pid; +} + +int WaitChild(pid_t pid, int *status, int errNo1, int errNo2) +{ + int ret = waitpid(pid, status, 0); + if (ret != pid) { + printf("[ERR] WaitChild pid=%d return pid=%d\n", pid, ret); + return errNo1; + } + if (status == nullptr) { + return 0; + } + ret = WIFEXITED(*status); + if (ret == 0) { + printf("[ERR] WaitChild pid=%d WIFEXITED(status)=%d\n", pid, WIFEXITED(*status)); + return errNo2; + } + ret = WEXITSTATUS(*status); + if (ret != 0) { + printf("[ERR] WaitChild pid=%d WEXITSTATUS(status)=%d\n", pid, WEXITSTATUS(*status)); + return errNo2; + } + return 0; +} + +int ReadFile(const char *filepath, char *buf) +{ + FILE *fpid = nullptr; + fpid = fopen(filepath, "r"); + if (fpid == nullptr) { + return -1; + } + size_t trd = fread(buf, 1, 512, fpid); + (void)fclose(fpid); + return trd; +} + +int WriteFile(const char *filepath, const char *buf) +{ + int fd = open(filepath, O_WRONLY); + if (fd == -1) { + return -1; + } + size_t twd = write(fd, buf, strlen(buf)); + if (twd == -1) { + (void)close(fd); + return -1; + } + (void)close(fd); + return twd; +} + +int GetLine(char *buf, int count, int maxLen, char **array) +{ + char *head = buf; + char *tail = buf; + char index = 0; + if ((buf == NULL) || (strlen(buf) == 0)) { + return 0; + } + while (*tail != '\0') { + if (*tail != '\n') { + tail++; + continue; + } + if (index >= count) { + return index + 1; + } + + array[index] = head; + index++; + *tail = '\0'; + if (strlen(head) > maxLen) { + return index + 1; + } + tail++; + head = tail; + tail++; + } + return (index + 1); +} + +static int TryResetNetAddr(const char *ifname, const char *ip, const char *netmask, const char *gw) +{ + int ret; + struct ifreq ifr; + struct rtentry rt; + + int fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); + if (fd < 0) { + return -1; + } + ret = strncpy_s(ifr.ifr_name, sizeof(ifr.ifr_name), ifname, IFNAMSIZ); + if (ret != EOK) { + (void)close(fd); + return -1; + } + ifr.ifr_addr.sa_family = AF_INET; + inet_pton(AF_INET, netmask, ifr.ifr_addr.sa_data + OFFSET); + ret = ioctl(fd, SIOCSIFNETMASK, &ifr); + if (ret != 0) { + printf("[ERR][%s:%d] ioctl SIOCSIFNETMASK failed, %s!\n", __FUNCTION__, __LINE__, strerror(errno)); + (void)close(fd); + return -1; + } + inet_pton(AF_INET, ip, ifr.ifr_addr.sa_data + OFFSET); + ret = ioctl(fd, SIOCSIFADDR, &ifr); + if (ret != 0) { + (void)close(fd); + printf("[ERR][%s:%d] ioctl SIOCGIFADDR failed, %s!\n", __FUNCTION__, __LINE__, strerror(errno)); + return -1; + } + struct sockaddr_in *addr = reinterpret_cast(&rt.rt_gateway); + addr->sin_family = AF_INET; + addr->sin_addr.s_addr = inet_addr(gw); + rt.rt_flags = RTF_GATEWAY; + ret = ioctl(fd, SIOCADDRT, &rt); + if (ret != 0) { + (void)close(fd); + printf("[ERR][%s:%d] ioctl SIOCADDRT failed, %s!\n", __FUNCTION__, __LINE__, strerror(errno)); + return ret; + } + ret = close(fd); + if (ret != 0) { + printf("[ERR][%s:%d] close failed, %s!\n", __FUNCTION__, __LINE__, strerror(errno)); + return ret; + } + return ret; +} + +int NetContainerResetNetAddr(const char *ifname, const char *ip, const char *netmask, const char *gw) +{ + int ret; + int try_count = TRY_COUNT; + + while (try_count--) { + ret = TryResetNetAddr(ifname, ip, netmask, gw); + if (ret == 0) { + break; + } + sleep(1); + } + return ret; +} + +int NetContainerGetLocalIP(const char *ifname, char *ip, int ipLen) +{ + struct ifreq ifr = {0}; + int ret = strcpy_s(ifr.ifr_name, sizeof(ifr.ifr_name), ifname); + if (ret != EOK) { + return -1; /* -1: errno */ + } + int inet_sock = socket(AF_INET, SOCK_DGRAM, 0); + if (inet_sock < 0) { + return -2; /* -2: errno */ + } + ret = ioctl(inet_sock, SIOCGIFADDR, &ifr); + if (ret != 0) { + (void)close(inet_sock); + printf("[ERR][%s:%d] ioctl SIOCGIFADDR failed, %s!\n", __FUNCTION__, __LINE__, strerror(errno)); + return -3; /* -3: errno */ + } + ret = close(inet_sock); + if (ret != 0) { + return -4; /* -4: errno */ + } + ret = strcpy_s(ip, ipLen, inet_ntoa((reinterpret_cast(&ifr.ifr_addr))->sin_addr)); + if (ret != EOK) { + (void)close(inet_sock); + return -5; /* -5: errno */ + } + return 0; +} + +std::string GenContainerLinkPath(int pid, const std::string& containerType) +{ + std::ostringstream buf; + buf << "/proc/" << pid << "/container/" << containerType; + return buf.str(); +} + +std::string ReadlinkContainer(int pid, const std::string& containerType) +{ + char buf[PATH_MAX] = {0}; + auto path = GenContainerLinkPath(pid, containerType); + ssize_t nbytes = readlink(path.c_str(), buf, PATH_MAX); + if (nbytes == -1) { + printf("pid %d, ReadlinkContainer readlink %s failed, errno=%d\n", getpid(), path.c_str(), errno); + return path.c_str(); + } + return buf; +} + +using namespace testing::ext; +namespace OHOS { +class ContainerTest : public testing::Test { +public: + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} + +protected: + virtual void SetUp(); + virtual void TearDown(); +}; + +#if defined(LOSCFG_USER_TEST_SMOKE) +HWTEST_F(ContainerTest, ItContainer001, TestSize.Level0) +{ + ItContainer001(); +} +#if defined(LOSCFG_USER_TEST_NET_CONTAINER) +/** +* @tc.name: Container_NET_Test_001 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6HPH2 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItNetContainer001, TestSize.Level0) +{ + ItNetContainer001(); +} + +/** +* @tc.name: Container_NET_Test_002 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6HPH2 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItNetContainer002, TestSize.Level0) +{ + ItNetContainer002(); +} + +/** +* @tc.name: Container_NET_Test_003 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6HPH2 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItNetContainer003, TestSize.Level0) +{ + ItNetContainer003(); +} + +/** +* @tc.name: Container_NET_Test_004 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6HPH2 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItNetContainer004, TestSize.Level0) +{ + ItNetContainer004(); +} + +/** +* @tc.name: Container_NET_Test_005 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6HPH2 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItNetContainer005, TestSize.Level0) +{ + ItNetContainer005(); +} + +/** +* @tc.name: Container_NET_Test_006 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6HPH2 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItNetContainer006, TestSize.Level0) +{ + ItNetContainer006(); +} + +/** +* @tc.name: Container_NET_Test_007 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6HPH2 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItNetContainer007, TestSize.Level0) +{ + ItNetContainer007(); +} + +/** +* @tc.name: Container_NET_Test_008 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6HPH2 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItNetContainer008, TestSize.Level0) +{ + ItNetContainer008(); +} + +/** +* @tc.name: Container_NET_Test_009 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6HPH2 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItNetContainer009, TestSize.Level0) +{ + ItNetContainer009(); +} + +/** +* @tc.name: Container_NET_Test_011 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6HPH2 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItNetContainer011, TestSize.Level0) +{ + ItNetContainer011(); +} + +/** +* @tc.name: Container_NET_Test_012 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6HPH2 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItNetContainer012, TestSize.Level0) +{ + ItNetContainer012(); +} +#endif +#if defined(LOSCFG_USER_TEST_USER_CONTAINER) +/** +* @tc.name: Container_UTS_Test_001 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6EC0A +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItUserContainer001, TestSize.Level0) +{ + ItUserContainer001(); +} + +/** +* @tc.name: Container_UTS_Test_002 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6EC0A +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItUserContainer002, TestSize.Level0) +{ + ItUserContainer002(); +} + +/** +* @tc.name: Container_UTS_Test_003 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6EC0A +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItUserContainer003, TestSize.Level0) +{ + ItUserContainer003(); +} + +/** +* @tc.name: Container_UTS_Test_004 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6EC0A +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItUserContainer004, TestSize.Level0) +{ + ItUserContainer004(); +} + +/** +* @tc.name: Container_UTS_Test_006 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6HDQK +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItUserContainer006, TestSize.Level0) +{ + ItUserContainer006(); +} + +/** +* @tc.name: Container_UTS_Test_007 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6HDQK +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItUserContainer007, TestSize.Level0) +{ + ItUserContainer007(); +} +#endif +#if defined(LOSCFG_USER_TEST_PID_CONTAINER) +/** +* @tc.name: Container_Pid_Test_032 +* @tc.desc: pid container function test case +* @tc.type: FUNC +* @tc.require: issueI6HDQK +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItPidContainer032, TestSize.Level0) +{ + ItPidContainer032(); +} + +/** +* @tc.name: Container_Pid_Test_033 +* @tc.desc: pid container function test case +* @tc.type: FUNC +* @tc.require: issueI6HDQK +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItPidContainer033, TestSize.Level0) +{ + ItPidContainer033(); +} + +/** +* @tc.name: Container_Pid_Test_023 +* @tc.desc: pid container function test case +* @tc.type: FUNC +* @tc.require: issueI68LVW +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItPidContainer023, TestSize.Level0) +{ + ItPidContainer023(); +} + +/** +* @tc.name: Container_Pid_Test_025 +* @tc.desc: pid container function test case +* @tc.type: FUNC +* @tc.require: issueI68LVW +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItPidContainer025, TestSize.Level0) +{ + ItPidContainer025(); +} + +/** +* @tc.name: Container_Pid_Test_026 +* @tc.desc: pid container function test case +* @tc.type: FUNC +* @tc.require: issueI68LVW +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItPidContainer026, TestSize.Level0) +{ + ItPidContainer026(); +} + +/** +* @tc.name: Container_Pid_Test_027 +* @tc.desc: pid container function test case +* @tc.type: FUNC +* @tc.require: issueI6BE5A +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItPidContainer027, TestSize.Level0) +{ + ItPidContainer027(); +} + +/** +* @tc.name: Container_Pid_Test_028 +* @tc.desc: pid container function test case +* @tc.type: FUNC +* @tc.require: issueI6BE5A +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItPidContainer028, TestSize.Level0) +{ + ItPidContainer028(); +} + +/** +* @tc.name: Container_Pid_Test_029 +* @tc.desc: pid container function test case +* @tc.type: FUNC +* @tc.require: issueI6BE5A +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItPidContainer029, TestSize.Level0) +{ + ItPidContainer029(); +} + +/** +* @tc.name: Container_Pid_Test_030 +* @tc.desc: pid container function test case +* @tc.type: FUNC +* @tc.require: issueI6BE5A +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItPidContainer030, TestSize.Level0) +{ + ItPidContainer030(); +} + +/** +* @tc.name: Container_Pid_Test_031 +* @tc.desc: pid container function test case +* @tc.type: FUNC +* @tc.require: issueI6D9Y0 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItPidContainer031, TestSize.Level0) +{ + ItPidContainer031(); +} +#endif +#if defined(LOSCFG_USER_TEST_UTS_CONTAINER) +/** +* @tc.name: Container_UTS_Test_001 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6A7C8 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItUtsContainer001, TestSize.Level0) +{ + ItUtsContainer001(); +} + +/** +* @tc.name: Container_UTS_Test_002 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6A7C8 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItUtsContainer002, TestSize.Level0) +{ + ItUtsContainer002(); +} + +/** +* @tc.name: Container_UTS_Test_004 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6BE5A +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItUtsContainer004, TestSize.Level0) +{ + ItUtsContainer004(); +} + +/** +* @tc.name: Container_UTS_Test_005 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6D9Y0 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItUtsContainer005, TestSize.Level0) +{ + ItUtsContainer005(); +} + +/** +* @tc.name: Container_UTS_Test_006 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6D9Y0 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItUtsContainer006, TestSize.Level0) +{ + ItUtsContainer006(); +} + +/** +* @tc.name: Container_UTS_Test_007 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6HDQK +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItUtsContainer007, TestSize.Level0) +{ + ItUtsContainer007(); +} + +/** +* @tc.name: Container_UTS_Test_008 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6HDQK +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItUtsContainer008, TestSize.Level0) +{ + ItUtsContainer008(); +} +#endif + +#if defined(LOSCFG_USER_TEST_MNT_CONTAINER) +/** +* @tc.name: Container_MNT_Test_001 +* @tc.desc: mnt container function test case +* @tc.type: FUNC +* @tc.require: issueI6APW2 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItMntContainer001, TestSize.Level0) +{ + ItMntContainer001(); +} + +/** +* @tc.name: Container_MNT_Test_002 +* @tc.desc: mnt container function test case +* @tc.type: FUNC +* @tc.require: issueI6APW2 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItMntContainer002, TestSize.Level0) +{ + ItMntContainer002(); +} + +/** +* @tc.name: Container_MNT_Test_003 +* @tc.desc: mnt container function test case +* @tc.type: FUNC +* @tc.require: issueI6APW2 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItMntContainer003, TestSize.Level0) +{ + ItMntContainer003(); +} + +/** +* @tc.name: Container_MNT_Test_004 +* @tc.desc: mnt container function test case +* @tc.type: FUNC +* @tc.require: issueI6APW2 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItMntContainer004, TestSize.Level0) +{ + ItMntContainer004(); +} + +/** +* @tc.name: Container_MNT_Test_005 +* @tc.desc: mnt container function test case +* @tc.type: FUNC +* @tc.require: issueI6BE5A +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItMntContainer005, TestSize.Level0) +{ + ItMntContainer005(); +} + +/** +* @tc.name: Container_MNT_Test_006 +* @tc.desc: mnt container function test case +* @tc.type: FUNC +* @tc.require: issueI6BE5A +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItMntContainer006, TestSize.Level0) +{ + ItMntContainer006(); +} + +/** +* @tc.name: Container_MNT_Test_007 +* @tc.desc: mnt container function test case +* @tc.type: FUNC +* @tc.require: issueI6BE5A +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItMntContainer007, TestSize.Level0) +{ + ItMntContainer007(); +} + +/** +* @tc.name: Container_MNT_Test_008 +* @tc.desc: mnt container function test case +* @tc.type: FUNC +* @tc.require: issueI6D9Y0 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItMntContainer008, TestSize.Level0) +{ + ItMntContainer008(); +} + +/** +* @tc.name: Container_MNT_Test_009 +* @tc.desc: mnt container function test case +* @tc.type: FUNC +* @tc.require: issueI6HDQK +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItMntContainer009, TestSize.Level0) +{ + ItMntContainer009(); +} + +/** +* @tc.name: Container_MNT_Test_010 +* @tc.desc: mnt container function test case +* @tc.type: FUNC +* @tc.require: issueI6HDQK +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItMntContainer010, TestSize.Level0) +{ + ItMntContainer010(); +} + +/** +* @tc.name: chroot_Test_001 +* @tc.desc: chroot function test case +* @tc.type: FUNC +* @tc.require: issueI6APW2 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItContainerChroot001, TestSize.Level0) +{ + ItContainerChroot001(); +} + +/** +* @tc.name: chroot_Test_002 +* @tc.desc: chroot function test case +* @tc.type: FUNC +* @tc.require: issueI6APW2 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItContainerChroot002, TestSize.Level0) +{ + ItContainerChroot002(); +} +#endif /* LOSCFG_USER_TEST_MNT_CONTAINER */ + +#if defined(LOSCFG_USER_TEST_IPC_CONTAINER) +/** +* @tc.name: Container_IPC_Test_001 +* @tc.desc: ipc container function test case +* @tc.type: FUNC +* @tc.require: issueI6AVMY +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItIpcContainer001, TestSize.Level0) +{ + ItIpcContainer001(); +} + +/** +* @tc.name: Container_IPC_Test_002 +* @tc.desc: ipc container function test case +* @tc.type: FUNC +* @tc.require: issueI6D9Y0 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItIpcContainer002, TestSize.Level0) +{ + ItIpcContainer002(); +} + +/** +* @tc.name: Container_IPC_Test_003 +* @tc.desc: ipc container function test case +* @tc.type: FUNC +* @tc.require: issueI6BE5A +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItIpcContainer003, TestSize.Level0) +{ + ItIpcContainer003(); +} + +/** +* @tc.name: Container_IPC_Test_004 +* @tc.desc: ipc container function test case +* @tc.type: FUNC +* @tc.require: issueI6AVMY +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItIpcContainer004, TestSize.Level0) +{ + ItIpcContainer004(); +} + +/** +* @tc.name: Container_IPC_Test_005 +* @tc.desc: ipc container function test case +* @tc.type: FUNC +* @tc.require: issueI6BE5A +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItIpcContainer005, TestSize.Level0) +{ + ItIpcContainer005(); +} + +/** +* @tc.name: Container_IPC_Test_006 +* @tc.desc: ipc container function test case +* @tc.type: FUNC +* @tc.require: issueI6D9Y0 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItIpcContainer006, TestSize.Level0) +{ + ItIpcContainer006(); +} + +/** +* @tc.name: Container_IPC_Test_007 +* @tc.desc: ipc container function test case +* @tc.type: FUNC +* @tc.require: issueI6HDQK +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItIpcContainer007, TestSize.Level0) +{ + ItIpcContainer007(); +} + +/** +* @tc.name: Container_IPC_Test_008 +* @tc.desc: ipc container function test case +* @tc.type: FUNC +* @tc.require: issueI6HDQK +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItIpcContainer008, TestSize.Level0) +{ + ItIpcContainer008(); +} +#endif + +#if defined(LOSCFG_USER_TEST_TIME_CONTAINER) +/** +* @tc.name: Container_TIME_Test_001 +* @tc.desc: time container function test case +* @tc.type: FUNC +* @tc.require: issueI6B0A3 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItTimeContainer001, TestSize.Level0) +{ + ItTimeContainer001(); +} + +/** +* @tc.name: Container_TIME_Test_002 +* @tc.desc: time container function test case +* @tc.type: FUNC +* @tc.require: issueI6BE5A +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItTimeContainer002, TestSize.Level0) +{ + ItTimeContainer002(); +} + +/** +* @tc.name: Container_TIME_Test_003 +* @tc.desc: time container function test case +* @tc.type: FUNC +* @tc.require: issueI6D9Y0 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItTimeContainer003, TestSize.Level0) +{ + ItTimeContainer003(); +} + +/** +* @tc.name: Container_TIME_Test_004 +* @tc.desc: time container function test case +* @tc.type: FUNC +* @tc.require: issueI6BE5A +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItTimeContainer004, TestSize.Level0) +{ + ItTimeContainer004(); +} + +/** +* @tc.name: Container_TIME_Test_005 +* @tc.desc: time container function test case +* @tc.type: FUNC +* @tc.require: issueI6BE5A +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItTimeContainer005, TestSize.Level0) +{ + ItTimeContainer005(); +} + +/** +* @tc.name: Container_TIME_Test_006 +* @tc.desc: time container function test case +* @tc.type: FUNC +* @tc.require: issueI6HDQK +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItTimeContainer006, TestSize.Level0) +{ + ItTimeContainer006(); +} + +/* +* @tc.name: Container_TIME_Test_007 +* @tc.desc: time container function test case +* @tc.type: FUNC +* @tc.require: issueI6B0A3 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItTimeContainer007, TestSize.Level0) +{ + ItTimeContainer007(); +} + +/** +* @tc.name: Container_TIME_Test_008 +* @tc.desc: time container function test case +* @tc.type: FUNC +* @tc.require: issueI6BE5A +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItTimeContainer008, TestSize.Level0) +{ + ItTimeContainer008(); +} + +/** +* @tc.name: Container_TIME_Test_009 +* @tc.desc: time container function test case +* @tc.type: FUNC +* @tc.require: issueI6B0A3 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItTimeContainer009, TestSize.Level0) +{ + ItTimeContainer009(); +} + +/** +* @tc.name: Container_TIME_Test_010 +* @tc.desc: time container function test case +* @tc.type: FUNC +* @tc.require: issueI6B0A3 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItTimeContainer010, TestSize.Level0) +{ + ItTimeContainer010(); +} +#endif +#endif /* LOSCFG_USER_TEST_SMOKE */ + +#if defined(LOSCFG_USER_TEST_FULL) +#if defined(LOSCFG_USER_TEST_PID_CONTAINER) +/** +* @tc.name: Container_Pid_Test_001 +* @tc.desc: pid container function test case +* @tc.type: FUNC +* @tc.require: issueI68LVW +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItPidContainer001, TestSize.Level0) +{ + ItPidContainer001(); +} + +/** +* @tc.name: Container_Pid_Test_002 +* @tc.desc: pid container function test case +* @tc.type: FUNC +* @tc.require: issueI68LVW +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItPidContainer002, TestSize.Level0) +{ + ItPidContainer002(); +} + +/** +* @tc.name: Container_Pid_Test_003 +* @tc.desc: pid container function test case +* @tc.type: FUNC +* @tc.require: issueI68LVW +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItPidContainer003, TestSize.Level0) +{ + ItPidContainer003(); +} + +/** +* @tc.name: Container_Pid_Test_004 +* @tc.desc: pid container function test case +* @tc.type: FUNC +* @tc.require: issueI68LVW +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItPidContainer004, TestSize.Level0) +{ + ItPidContainer004(); +} + +#if defined(LOSCFG_USER_TEST_UTS_CONTAINER) +/** +* @tc.name: Container_Pid_Test_005 +* @tc.desc: pid container function test case +* @tc.type: FUNC +* @tc.require: issueI68LVW +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItPidContainer005, TestSize.Level0) +{ + ItPidContainer005(); +} +#endif + +/** +* @tc.name: Container_Pid_Test_006 +* @tc.desc: pid container function test case +* @tc.type: FUNC +* @tc.require: issueI68LVW +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItPidContainer006, TestSize.Level0) +{ + ItPidContainer006(); +} + +/** +* @tc.name: Container_Pid_Test_007 +* @tc.desc: pid container function test case +* @tc.type: FUNC +* @tc.require: issueI68LVW +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItPidContainer007, TestSize.Level0) +{ + ItPidContainer007(); +} + +/** +* @tc.name: Container_Pid_Test_008 +* @tc.desc: pid container function test case +* @tc.type: FUNC +* @tc.require: issueI68LVW +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItPidContainer008, TestSize.Level0) +{ + ItPidContainer008(); +} + +/** +* @tc.name: Container_Pid_Test_009 +* @tc.desc: pid container function test case +* @tc.type: FUNC +* @tc.require: issueI68LVW +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItPidContainer009, TestSize.Level0) +{ + ItPidContainer009(); +} + +/** +* @tc.name: Container_Pid_Test_010 +* @tc.desc: pid container function test case +* @tc.type: FUNC +* @tc.require: issueI68LVW +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItPidContainer010, TestSize.Level0) +{ + ItPidContainer010(); +} + +/** +* @tc.name: Container_Pid_Test_011 +* @tc.desc: pid container function test case +* @tc.type: FUNC +* @tc.require: issueI68LVW +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItPidContainer011, TestSize.Level0) +{ + ItPidContainer011(); +} + +/** +* @tc.name: Container_Pid_Test_012 +* @tc.desc: pid container function test case +* @tc.type: FUNC +* @tc.require: issueI68LVW +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItPidContainer012, TestSize.Level0) +{ + ItPidContainer012(); +} + +/** +* @tc.name: Container_Pid_Test_013 +* @tc.desc: pid container function test case +* @tc.type: FUNC +* @tc.require: issueI68LVW +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItPidContainer013, TestSize.Level0) +{ + ItPidContainer013(); +} + +/** +* @tc.name: Container_Pid_Test_014 +* @tc.desc: pid container function test case +* @tc.type: FUNC +* @tc.require: issueI68LVW +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItPidContainer014, TestSize.Level0) +{ + ItPidContainer014(); +} + +/** +* @tc.name: Container_Pid_Test_015 +* @tc.desc: pid container function test case +* @tc.type: FUNC +* @tc.require: issueI68LVW +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItPidContainer015, TestSize.Level0) +{ + ItPidContainer015(); +} + +/** +* @tc.name: Container_Pid_Test_016 +* @tc.desc: pid container function test case +* @tc.type: FUNC +* @tc.require: issueI68LVW +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItPidContainer016, TestSize.Level0) +{ + ItPidContainer016(); +} + +/** +* @tc.name: Container_Pid_Test_017 +* @tc.desc: pid container function test case +* @tc.type: FUNC +* @tc.require: issueI68LVW +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItPidContainer017, TestSize.Level0) +{ + ItPidContainer017(); +} + +/** +* @tc.name: Container_Pid_Test_018 +* @tc.desc: pid container function test case +* @tc.type: FUNC +* @tc.require: issueI68LVW +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItPidContainer018, TestSize.Level0) +{ + ItPidContainer018(); +} + +/** +* @tc.name: Container_Pid_Test_019 +* @tc.desc: pid container function test case +* @tc.type: FUNC +* @tc.require: issueI68LVW +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItPidContainer019, TestSize.Level0) +{ + ItPidContainer019(); +} + +/** +* @tc.name: Container_Pid_Test_020 +* @tc.desc: pid container function test case +* @tc.type: FUNC +* @tc.require: issueI68LVW +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItPidContainer020, TestSize.Level0) +{ + ItPidContainer020(); +} + +/** +* @tc.name: Container_Pid_Test_021 +* @tc.desc: pid container function test case +* @tc.type: FUNC +* @tc.require: issueI68LVW +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItPidContainer021, TestSize.Level0) +{ + ItPidContainer021(); +} + +/** +* @tc.name: Container_Pid_Test_022 +* @tc.desc: pid container function test case +* @tc.type: FUNC +* @tc.require: issueI68LVW +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItPidContainer022, TestSize.Level0) +{ + ItPidContainer022(); +} + +/** +* @tc.name: Container_Pid_Test_024 +* @tc.desc: pid container function test case +* @tc.type: FUNC +* @tc.require: issueI68LVW +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItPidContainer024, TestSize.Level0) +{ + ItPidContainer024(); +} +#endif +#if defined(LOSCFG_USER_TEST_UTS_CONTAINER) +/** +* @tc.name: Container_UTS_Test_003 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6A7C8 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItUtsContainer003, TestSize.Level0) +{ + ItUtsContainer003(); +} +#endif +#if defined(LOSCFG_USER_TEST_USER_CONTAINER) +/** +* @tc.name: Container_UTS_Test_005 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6EC0A +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItUserContainer005, TestSize.Level0) +{ + ItUserContainer005(); +} +#endif +#if defined(LOSCFG_USER_TEST_NET_CONTAINER) +/** +* @tc.name: Container_NET_Test_010 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6HPH2 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItNetContainer010, TestSize.Level0) +{ + ItNetContainer010(); +} +#endif +#endif +} // namespace OHOS + +namespace OHOS { +void ContainerTest::SetUp() +{ + mode_t mode = 0; + (void)mkdir(ACCESS_FILE_NAME, S_IFDIR | mode); +} +void ContainerTest::TearDown() +{ + (void)rmdir(ACCESS_FILE_NAME); +} +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/It_container_test.h b/src/kernel_liteos_a/testsuites/unittest/container/It_container_test.h new file mode 100644 index 00000000..18ecbe5c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/It_container_test.h @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _IT_CONTAINER_TEST_H +#define _IT_CONTAINER_TEST_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "osTest.h" +#include "mqueue.h" +#include "sys/time.h" +#include "sys/shm.h" +#include "sys/types.h" + +const int EXIT_CODE_ERRNO_1 = 1; +const int EXIT_CODE_ERRNO_2 = 2; +const int EXIT_CODE_ERRNO_3 = 3; +const int EXIT_CODE_ERRNO_4 = 4; +const int EXIT_CODE_ERRNO_5 = 5; +const int EXIT_CODE_ERRNO_6 = 6; +const int EXIT_CODE_ERRNO_7 = 7; +const int EXIT_CODE_ERRNO_8 = 8; +const int EXIT_CODE_ERRNO_9 = 9; +const int EXIT_CODE_ERRNO_10 = 10; +const int EXIT_CODE_ERRNO_11 = 11; +const int EXIT_CODE_ERRNO_12 = 12; +const int EXIT_CODE_ERRNO_13 = 13; +const int EXIT_CODE_ERRNO_14 = 14; +const int EXIT_CODE_ERRNO_15 = 15; +const int EXIT_CODE_ERRNO_16 = 16; +const int EXIT_CODE_ERRNO_17 = 17; +const int EXIT_CODE_ERRNO_255 = 255; +const int CONTAINER_FIRST_PID = 1; +const int CONTAINER_SECOND_PID = 2; +const int CONTAINER_THIRD_PID = 3; + +const int MQUEUE_TEST_SIZE = 50; +const int MQUEUE_TEST_MAX_MSG = 255; + +const int SHM_TEST_DATA_SIZE = 1024; +const int SHM_TEST_KEY1 = 1234; +const int SHM_TEST_OPEN_PERM = 0666; +const int CLONE_STACK_MMAP_FLAG = MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK; + +extern const char *USERDATA_DIR_NAME; +extern const char *ACCESS_FILE_NAME; +extern const char *MNT_ACCESS_FILE_NAME; +extern const char *USERDATA_DEV_NAME; +extern const char *FS_TYPE; + +extern const int BIT_ON_RETURN_VALUE; +extern const int STACK_SIZE; +extern const int CHILD_FUNC_ARG; + +const int MQUEUE_STANDARD_NAME_LENGTH = 255; + +extern "C" { +#define CLONE_NEWTIME 0x00000080 +} + +int WriteFile(const char *filepath, const char *buf); +int ReadFile(const char *filepath, char *buf); +int GetLine(char *buf, int count, int maxLen, char **array); + +int ChildFunction(void *args); + +pid_t CloneWrapper(int (*func)(void *), int flag, void *args); + +int WaitChild(pid_t pid, int *status, int errNo1, int errNo2); + +int NetContainerResetNetAddr(const char *ifname, const char *ip, const char *netmask, const char *gw); + +int NetContainerGetLocalIP(const char *ifname, char *ip, int ipLen); + +std::string GenContainerLinkPath(int pid, const std::string& containerType); + +extern std::string ReadlinkContainer(int pid, const std::string& containerType); + +class MQueueFinalizer { +public: + explicit MQueueFinalizer(mqd_t mqueueParent, const std::string& mqname) + { + m_mqueueParent = mqueueParent; + m_mqname = mqname; + } + ~MQueueFinalizer() + { + if (m_mqueueParent >= 0) { + mq_close(m_mqueueParent); + mq_unlink(m_mqname.c_str()); + } + } +private: + mqd_t m_mqueueParent; + std::string m_mqname; +}; + +class ShmFinalizer { +public: + explicit ShmFinalizer(void* shm, int shmid) + { + m_shm = shm; + m_shmid = shmid; + } + ~ShmFinalizer() + { + shmdt(m_shm); + shmctl(m_shmid, IPC_RMID, nullptr); + } +private: + void* m_shm; + int m_shmid; +}; + +void ItUserContainer001(void); +void ItUserContainer002(void); +void ItUserContainer003(void); +void ItUserContainer004(void); +void ItUserContainer005(void); +void ItUserContainer006(void); +void ItUserContainer007(void); +void ItContainer001(void); +void ItContainerChroot001(void); +void ItContainerChroot002(void); +void ItPidContainer023(void); +void ItPidContainer025(void); +void ItPidContainer026(void); +void ItPidContainer027(void); +void ItPidContainer028(void); +void ItPidContainer029(void); +void ItPidContainer030(void); +void ItPidContainer031(void); +void ItPidContainer032(void); +void ItPidContainer033(void); +void ItUtsContainer001(void); +void ItUtsContainer002(void); +void ItUtsContainer004(void); +void ItUtsContainer005(void); +void ItUtsContainer006(void); +void ItUtsContainer007(void); +void ItUtsContainer008(void); +void ItMntContainer001(void); +void ItMntContainer002(void); +void ItMntContainer003(void); +void ItMntContainer004(void); +void ItMntContainer005(void); +void ItMntContainer006(void); +void ItMntContainer007(void); +void ItMntContainer008(void); +void ItMntContainer009(void); +void ItMntContainer010(void); +void ItIpcContainer001(void); +void ItIpcContainer002(void); +void ItIpcContainer003(void); +void ItIpcContainer004(void); +void ItIpcContainer005(void); +void ItIpcContainer006(void); +void ItIpcContainer007(void); +void ItIpcContainer008(void); +void ItTimeContainer001(void); +void ItTimeContainer002(void); +void ItTimeContainer003(void); +void ItTimeContainer004(void); +void ItTimeContainer005(void); +void ItTimeContainer006(void); +void ItTimeContainer007(void); +void ItTimeContainer008(void); +void ItTimeContainer009(void); +void ItTimeContainer010(void); +void ItPidContainer001(void); +void ItPidContainer002(void); +void ItPidContainer003(void); +void ItPidContainer004(void); +void ItPidContainer005(void); +void ItPidContainer006(void); +void ItPidContainer007(void); +void ItPidContainer008(void); +void ItPidContainer009(void); +void ItPidContainer010(void); +void ItPidContainer011(void); +void ItPidContainer012(void); +void ItPidContainer013(void); +void ItPidContainer014(void); +void ItPidContainer015(void); +void ItPidContainer016(void); +void ItPidContainer017(void); +void ItPidContainer018(void); +void ItPidContainer019(void); +void ItPidContainer020(void); +void ItPidContainer021(void); +void ItPidContainer022(void); +void ItPidContainer024(void); +void ItUtsContainer003(void); +void ItNetContainer001(void); +void ItNetContainer002(void); +void ItNetContainer003(void); +void ItNetContainer004(void); +void ItNetContainer005(void); +void ItNetContainer006(void); +void ItNetContainer007(void); +void ItNetContainer008(void); +void ItNetContainer009(void); +void ItNetContainer010(void); +void ItNetContainer011(void); +void ItNetContainer012(void); +#endif /* _IT_CONTAINER_TEST_H */ diff --git a/src/kernel_liteos_a/testsuites/unittest/container/config.gni b/src/kernel_liteos_a/testsuites/unittest/container/config.gni new file mode 100644 index 00000000..9bfa4dd6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/config.gni @@ -0,0 +1,170 @@ +# Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//build/lite/config/test.gni") +import("//kernel/liteos_a/liteos.gni") +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +common_include_dirs = [ + "$THIRDPARTY_GOOGLETEST_DIR/googletest/include", + "../common/include", + "$TEST_UNITTEST_DIR/container", +] + +sources_entry = [ "$TEST_UNITTEST_DIR/container/It_container_test.cpp" ] + +sources_smoke = [ "$TEST_UNITTEST_DIR/container/smoke/It_container_001.cpp" ] + +sources_full = [] + +if (defined(LOSCFG_USER_TEST_PID_CONTAINER)) { + sources_smoke += [ + "$TEST_UNITTEST_DIR/container/smoke/It_pid_container_023.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_pid_container_025.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_pid_container_026.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_pid_container_027.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_pid_container_028.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_pid_container_029.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_pid_container_030.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_pid_container_031.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_pid_container_032.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_pid_container_033.cpp", + ] + sources_full += [ + "$TEST_UNITTEST_DIR/container/full/It_pid_container_001.cpp", + "$TEST_UNITTEST_DIR/container/full/It_pid_container_002.cpp", + "$TEST_UNITTEST_DIR/container/full/It_pid_container_003.cpp", + "$TEST_UNITTEST_DIR/container/full/It_pid_container_004.cpp", + "$TEST_UNITTEST_DIR/container/full/It_pid_container_005.cpp", + "$TEST_UNITTEST_DIR/container/full/It_pid_container_006.cpp", + "$TEST_UNITTEST_DIR/container/full/It_pid_container_007.cpp", + "$TEST_UNITTEST_DIR/container/full/It_pid_container_008.cpp", + "$TEST_UNITTEST_DIR/container/full/It_pid_container_009.cpp", + "$TEST_UNITTEST_DIR/container/full/It_pid_container_010.cpp", + "$TEST_UNITTEST_DIR/container/full/It_pid_container_011.cpp", + "$TEST_UNITTEST_DIR/container/full/It_pid_container_012.cpp", + "$TEST_UNITTEST_DIR/container/full/It_pid_container_013.cpp", + "$TEST_UNITTEST_DIR/container/full/It_pid_container_014.cpp", + "$TEST_UNITTEST_DIR/container/full/It_pid_container_015.cpp", + "$TEST_UNITTEST_DIR/container/full/It_pid_container_016.cpp", + "$TEST_UNITTEST_DIR/container/full/It_pid_container_017.cpp", + "$TEST_UNITTEST_DIR/container/full/It_pid_container_018.cpp", + "$TEST_UNITTEST_DIR/container/full/It_pid_container_019.cpp", + "$TEST_UNITTEST_DIR/container/full/It_pid_container_020.cpp", + "$TEST_UNITTEST_DIR/container/full/It_pid_container_021.cpp", + "$TEST_UNITTEST_DIR/container/full/It_pid_container_022.cpp", + "$TEST_UNITTEST_DIR/container/full/It_pid_container_024.cpp", + ] +} +if (defined(LOSCFG_USER_TEST_UTS_CONTAINER)) { + sources_smoke += [ + "$TEST_UNITTEST_DIR/container/smoke/It_uts_container_001.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_uts_container_002.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_uts_container_004.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_uts_container_005.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_uts_container_006.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_uts_container_007.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_uts_container_008.cpp", + ] + sources_full += + [ "$TEST_UNITTEST_DIR/container/full/It_uts_container_003.cpp" ] +} +if (defined(LOSCFG_USER_TEST_MNT_CONTAINER)) { + sources_smoke += [ + "$TEST_UNITTEST_DIR/container/smoke/It_container_chroot_001.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_container_chroot_002.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_mnt_container_001.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_mnt_container_002.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_mnt_container_003.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_mnt_container_004.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_mnt_container_005.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_mnt_container_006.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_mnt_container_007.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_mnt_container_008.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_mnt_container_009.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_mnt_container_010.cpp", + ] +} + +if (defined(LOSCFG_USER_TEST_IPC_CONTAINER)) { + sources_smoke += [ + "$TEST_UNITTEST_DIR/container/smoke/It_ipc_container_001.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_ipc_container_002.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_ipc_container_003.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_ipc_container_004.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_ipc_container_005.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_ipc_container_006.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_ipc_container_007.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_ipc_container_008.cpp", + ] +} + +if (defined(LOSCFG_USER_TEST_TIME_CONTAINER)) { + sources_smoke += [ + "$TEST_UNITTEST_DIR/container/smoke/It_time_container_001.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_time_container_002.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_time_container_003.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_time_container_004.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_time_container_005.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_time_container_006.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_time_container_007.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_time_container_008.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_time_container_009.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_time_container_010.cpp", + ] +} + +if (defined(LOSCFG_USER_TEST_USER_CONTAINER)) { + sources_smoke += [ + "$TEST_UNITTEST_DIR/container/smoke/It_user_container_001.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_user_container_002.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_user_container_003.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_user_container_004.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_user_container_006.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_user_container_007.cpp", + ] + sources_full += + [ "$TEST_UNITTEST_DIR/container/full/It_user_container_005.cpp" ] +} +if (defined(LOSCFG_USER_TEST_NET_CONTAINER)) { + sources_smoke += [ + "$TEST_UNITTEST_DIR/container/smoke/It_net_container_001.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_net_container_002.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_net_container_003.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_net_container_004.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_net_container_005.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_net_container_006.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_net_container_007.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_net_container_008.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_net_container_009.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_net_container_011.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_net_container_012.cpp", + ] + sources_full += + [ "$TEST_UNITTEST_DIR/container/full/It_net_container_010.cpp" ] +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/full/It_net_container_010.cpp b/src/kernel_liteos_a/testsuites/unittest/container/full/It_net_container_010.cpp new file mode 100644 index 00000000..11993fd6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/full/It_net_container_010.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "sys/resource.h" +#include "sys/wait.h" +#include "pthread.h" +#include "sched.h" +#include "It_container_test.h" + +const int MAX_PID_RANGE = 100000; +const int SLEEP_TIME_US = 1000; +const int LOOP_NUM = 100; + +static int ChildFunc(void *arg) +{ + usleep(SLEEP_TIME_US); + exit(EXIT_CODE_ERRNO_5); +} + +static int GroupProcess(void *arg) +{ + (void)arg; + int ret; + int status = 0; + + for (int i = 0; i < LOOP_NUM; i++) { + int argTmp = CHILD_FUNC_ARG; + auto pid = CloneWrapper(ChildFunc, CLONE_NEWNET, &argTmp); + if (pid == -1) { + return EXIT_CODE_ERRNO_1; + } + ret = waitpid(pid, &status, 0); + status = WEXITSTATUS(status); + if (status != EXIT_CODE_ERRNO_5) { + return EXIT_CODE_ERRNO_2; + } + } + + exit(EXIT_CODE_ERRNO_5); +} + +void ItNetContainer010(void) +{ + int ret; + int status = 0; + int arg = CHILD_FUNC_ARG; + auto pid = CloneWrapper(GroupProcess, CLONE_NEWNET, &arg); + ASSERT_NE(pid, -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + status = WEXITSTATUS(status); + ASSERT_EQ(status, EXIT_CODE_ERRNO_5); + + sleep(5); /* 5: Wait for process resources to be reclaimed */ +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_001.cpp b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_001.cpp new file mode 100644 index 00000000..d363bdf6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_001.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +static int ChildFun(void *p) +{ + (void)p; + return getpid(); +} + +void ItPidContainer001(void) +{ + int status; + int ret; + void *pstk = malloc(STACK_SIZE); + ASSERT_TRUE(pstk != NULL); + int childPid = clone(ChildFun, (char *)pstk + STACK_SIZE, CLONE_NEWPID | SIGCHLD, NULL); + free(pstk); + ASSERT_NE(childPid, -1); + + ret = waitpid(childPid, &status, 0); + ASSERT_EQ(ret, childPid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, CONTAINER_FIRST_PID); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_002.cpp b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_002.cpp new file mode 100644 index 00000000..f9048eb8 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_002.cpp @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +static int ChildFun(void *p) +{ + (void)p; + return getpid(); +} + +static int ChildFunClone3(void *p) +{ + (void)p; + int childPid; + int status; + int ret; + pid_t pid = getpid(); + int childFunRet = (int)pid; + void *pstk = malloc(STACK_SIZE); + if (pstk == NULL) { + return EXIT_CODE_ERRNO_1; + } + pid_t parent_pid = getppid(); + if (parent_pid != CONTAINER_FIRST_PID) { + free(pstk); + return EXIT_CODE_ERRNO_3; + } + + childPid = clone(ChildFun, (char *)pstk + STACK_SIZE, SIGCHLD, NULL); + free(pstk); + if (childPid == -1) { + return EXIT_CODE_ERRNO_4; + } + + ret = waitpid(childPid, &status, 0); + if (ret != childPid) { + return EXIT_CODE_ERRNO_5; + } + ret = WIFEXITED(status); + if (ret == 0) { + return EXIT_CODE_ERRNO_6; + } + ret = WEXITSTATUS(status); + if (ret != CONTAINER_THIRD_PID) { + return EXIT_CODE_ERRNO_7; + } + return childFunRet; +} + +static int ChildFunClone2(void *p) +{ + (void)p; + int status; + int ret; + pid_t pid = getpid(); + int childFunRet = (int)pid; + void *pstk = malloc(STACK_SIZE); + if (pstk == NULL) { + return EXIT_CODE_ERRNO_2; + } + int childPid = clone(ChildFunClone3, (char *)pstk + STACK_SIZE, SIGCHLD, NULL); + if (childPid == -1) { + free(pstk); + return EXIT_CODE_ERRNO_3; + } + + ret = wait(&status); + ret = WIFEXITED(status); + ret = WEXITSTATUS(status); + if (ret != CONTAINER_SECOND_PID) { + free(pstk); + return EXIT_CODE_ERRNO_4; + } + + free(pstk); + return childFunRet; +} + +static int ChildFunClone1(void *p) +{ + (void)p; + int status; + int ret; + pid_t pid = getpid(); + int childFunRet = (int)pid; + char *containerType = "pid"; + int childPid = clone(ChildFunClone2, NULL, CLONE_NEWPID | SIGCHLD, NULL); + if (childPid == -1) { + return EXIT_CODE_ERRNO_3; + } + + auto linkBuffer = ReadlinkContainer(childPid, containerType); + auto linkBuffer1 = ReadlinkContainer(getpid(), containerType); + ret = linkBuffer.compare(linkBuffer1); + if (ret == 0) { + (void)waitpid(childPid, &status, 0); + return EXIT_CODE_ERRNO_5; + } + + ret = waitpid(childPid, &status, 0); + ret = WIFEXITED(status); + ret = WEXITSTATUS(status); + if (ret != CONTAINER_FIRST_PID) { + return EXIT_CODE_ERRNO_4; + } + return childFunRet; +} + +void ItPidContainer002(void) +{ + int status; + int ret; + void *pstk = malloc(STACK_SIZE); + ASSERT_TRUE(pstk != NULL); + int childPid = clone(ChildFunClone1, (char *)pstk + STACK_SIZE, CLONE_NEWPID | SIGCHLD, NULL); + free(pstk); + ASSERT_NE(childPid, -1); + + ret = waitpid(childPid, &status, 0); + ASSERT_EQ(ret, childPid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, CONTAINER_FIRST_PID); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_003.cpp b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_003.cpp new file mode 100644 index 00000000..8bc8ab52 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_003.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +static int ChildFun(void *p) +{ + (void)p; + return getpid(); +} + +static int ChildFunClone2() +{ + void *pstk = malloc(STACK_SIZE); + if (pstk == NULL) { + return -1; + } + int childPid = clone(ChildFun, (char *)pstk + STACK_SIZE, SIGCHLD, NULL); + + free(pstk); + return childPid; +} + +static int ChildFunClone1(void *p) +{ + (void)p; + pid_t pid = getpid(); + const int COUNT = 100; + int childPid; + int childFunRet = (int)pid; + int processCount = 0; + int ret; + int status; + + for (int i = 0; i < COUNT; i++) { + childPid = ChildFunClone2(); + if (childPid != -1) { + processCount++; + } else { + ret = wait(&status); + if (ret > 0) { + processCount--; + } else { + sleep(1); + } + continue; + } + } + + ret = 0; + while (processCount > 0) { + ret = wait(&status); + if (ret > 0) { + processCount--; + } + } + + return childFunRet; +} + +void ItPidContainer003(void) +{ + int status; + int ret; + void *pstk = malloc(STACK_SIZE); + ASSERT_TRUE(pstk != NULL); + int childPid = clone(ChildFunClone1, (char *)pstk + STACK_SIZE, CLONE_NEWPID | SIGCHLD, NULL); + ASSERT_NE(childPid, -1); + + ret = waitpid(childPid, &status, 0); + ASSERT_EQ(ret, childPid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, CONTAINER_FIRST_PID); + + sleep(5); /* 5: Wait for process resources to be reclaimed */ +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_004.cpp b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_004.cpp new file mode 100644 index 00000000..290e3190 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_004.cpp @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +static int ChildFun(void *p) +{ + (void)p; + return getpid(); +} + +static int ChildFunClone2(void *p) +{ + (void)p; + void *pstk = malloc(STACK_SIZE); + if (pstk == NULL) { + return EXIT_CODE_ERRNO_1; + } + int childPid = clone(ChildFun, (char *)pstk + STACK_SIZE, CLONE_NEWPID | SIGCHLD, NULL); + if (childPid != -1) { + free(pstk); + return EXIT_CODE_ERRNO_2; + } + + free(pstk); + return 0; +} + +static int ChildFunClone1(void *p) +{ + (void)p; + int ret = 0; + int status; + pid_t pid = getpid(); + int childFunRet = (int)pid; + void *pstk = malloc(STACK_SIZE); + if (pstk == NULL) { + return EXIT_CODE_ERRNO_2; + } + int childPid = clone(ChildFunClone2, (char *)pstk + STACK_SIZE, CLONE_NEWPID | SIGCHLD, NULL); + if (childPid == -1) { + free(pstk); + return EXIT_CODE_ERRNO_3; + } + + ret = waitpid(childPid, &status, 0); + if (ret != childPid) { + return EXIT_CODE_ERRNO_4; + } + ret = WIFEXITED(status); + if (ret == 0) { + return EXIT_CODE_ERRNO_5; + } + ret = WEXITSTATUS(status); + if (ret != 0) { + free(pstk); + return EXIT_CODE_ERRNO_6; + } + + free(pstk); + return childFunRet; +} + +void ItPidContainer004(void) +{ + int ret = 0; + int status; + void *pstk = malloc(STACK_SIZE); + ASSERT_TRUE(pstk != NULL); + int childPid = clone(ChildFunClone1, (char *)pstk + STACK_SIZE, CLONE_NEWPID | SIGCHLD, NULL); + free(pstk); + ASSERT_NE(childPid, -1); + + ret = waitpid(childPid, &status, 0); + ASSERT_EQ(ret, childPid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, CONTAINER_FIRST_PID); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_005.cpp b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_005.cpp new file mode 100644 index 00000000..7fa3b6f5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_005.cpp @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +static int ChildFunClone3(void *p) +{ + (void)p; + auto pid = getpid(); + if (pid != CONTAINER_SECOND_PID) { + return EXIT_CODE_ERRNO_1; + } + return 0; +} + +static int ChildFunClone2(void *p) +{ + (void)p; + auto pid = getpid(); + if (pid != CONTAINER_FIRST_PID) { + return EXIT_CODE_ERRNO_1; + } + int ret; + int status; + void *pstk = malloc(STACK_SIZE); + if (pstk == NULL) { + return EXIT_CODE_ERRNO_2; + } + int childPid = clone(ChildFunClone3, (char *)pstk + STACK_SIZE, SIGCHLD, NULL); + if (childPid == -1) { + free(pstk); + return EXIT_CODE_ERRNO_3; + } + + ret = waitpid(childPid, &status, 0); + ret = WIFEXITED(status); + ret = WEXITSTATUS(status); + if (ret != 0) { + free(pstk); + return EXIT_CODE_ERRNO_4; + } + + free(pstk); + return 0; +} + +static int ChildFunClone1(void *p) +{ + (void)p; + int ret; + int status; + const char *containerType = "pid"; + const char *containerType1 = "pid_for_children"; + + auto pid = getpid(); + ret = unshare(CLONE_NEWPID); + if (ret == -1) { + return EXIT_CODE_ERRNO_1; + } + auto pid1 = getpid(); + if (pid != pid1) { + return EXIT_CODE_ERRNO_2; + } + + auto linkBuffer = ReadlinkContainer(pid, containerType); + auto linkBuffer1 = ReadlinkContainer(pid, containerType1); + ret = linkBuffer.compare(linkBuffer1); + if (ret == 0) { + return EXIT_CODE_ERRNO_3; + } + + void *pstk = malloc(STACK_SIZE); + if (pstk == NULL) { + return EXIT_CODE_ERRNO_4; + } + int childPid = clone(ChildFunClone2, (char *)pstk + STACK_SIZE, CLONE_NEWUTS | SIGCHLD, NULL); + free(pstk); + if (childPid == -1) { + return EXIT_CODE_ERRNO_5; + } + + ret = waitpid(childPid, &status, 0); + if (ret != childPid) { + return EXIT_CODE_ERRNO_6; + } + ret = WIFEXITED(status); + if (ret == 0) { + return EXIT_CODE_ERRNO_7; + } + ret = WEXITSTATUS(status); + if (ret != 0) { + return EXIT_CODE_ERRNO_8; + } + return 0; +} + +void ItPidContainer005(void) +{ + int status; + int ret; + void *pstk = malloc(STACK_SIZE); + ASSERT_TRUE(pstk != NULL); + + int childPid = clone(ChildFunClone1, (char *)pstk + STACK_SIZE, SIGCHLD, NULL); + free(pstk); + ASSERT_NE(childPid, -1); + + ret = waitpid(childPid, &status, 0); + ASSERT_EQ(ret, childPid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_006.cpp b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_006.cpp new file mode 100644 index 00000000..9c97aeed --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_006.cpp @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +static int ChildFun1(void *p) +{ + (void)p; + return getpid(); +} + +static int ChildFun(void *p) +{ + (void)p; + int status; + int ret; + pid_t pid = getpid(); + int childFunRet = (int)pid; + void *pstk = malloc(STACK_SIZE); + if (pstk == NULL) { + return EXIT_CODE_ERRNO_2; + } + int childPid = clone(ChildFun1, (char *)pstk + STACK_SIZE, SIGCHLD, NULL); + if (childPid == -1) { + free(pstk); + return EXIT_CODE_ERRNO_3; + } + + ret = waitpid(childPid, &status, 0); + ret = WIFEXITED(status); + ret = WEXITSTATUS(status); + if (ret != CONTAINER_SECOND_PID) { + free(pstk); + return EXIT_CODE_ERRNO_4; + } + + childPid = clone(ChildFun1, (char *)pstk + STACK_SIZE, SIGCHLD, NULL); + if (childPid == -1) { + free(pstk); + return EXIT_CODE_ERRNO_5; + } + + ret = waitpid(childPid, &status, 0); + ret = WIFEXITED(status); + ret = WEXITSTATUS(status); + if (ret != CONTAINER_THIRD_PID) { + free(pstk); + return EXIT_CODE_ERRNO_6; + } + + free(pstk); + return childFunRet; +} + +void ItPidContainer006(void) +{ + int status; + int ret; + void *pstk = malloc(STACK_SIZE); + ASSERT_TRUE(pstk != NULL); + pid_t parentPid = getpid(); + int childPid = clone(ChildFun, (char *)pstk + STACK_SIZE, CLONE_NEWPID | SIGCHLD, NULL); + free(pstk); + ASSERT_NE(childPid, -1); + + ret = waitpid(childPid, &status, 0); + ASSERT_EQ(ret, childPid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, CONTAINER_FIRST_PID); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_007.cpp b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_007.cpp new file mode 100644 index 00000000..9b395325 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_007.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +static int ChildFun(void *p) +{ + (void)p; + int ret; + int status; + int pid = getpid(); + if (pid != CONTAINER_FIRST_PID) { + return -1; + } + ret = fork(); + if (ret < 0) { + return -1; + } else if (ret == 0) { + if (getpid() != CONTAINER_SECOND_PID) { + return -1; + } + exit(0); + } else { + wait(&status); + } + + exit(EXIT_CODE_ERRNO_5); +} + +void ItPidContainer007(void) +{ + int ret = 0; + int status; + void *pstk = malloc(STACK_SIZE); + ASSERT_TRUE(pstk != NULL); + int childPid = clone(ChildFun, (char *)pstk + STACK_SIZE, CLONE_NEWPID | SIGCHLD, NULL); + free(pstk); + ASSERT_NE(childPid, -1); + + ret = waitpid(childPid, &status, 0); + ASSERT_EQ(ret, childPid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, EXIT_CODE_ERRNO_5); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_008.cpp b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_008.cpp new file mode 100644 index 00000000..1dac81f1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_008.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +static int ChildFun(void *p) +{ + (void)p; + int ret; + cpu_set_t cpuset; + cpu_set_t initCpuset; + + CPU_ZERO(&initCpuset); + ret = sched_getaffinity(getpid(), sizeof(cpu_set_t), &initCpuset); + if (ret != 0) { + return EXIT_CODE_ERRNO_1; + } + + CPU_ZERO(&cpuset); + CPU_SET(1, &cpuset); + ret = sched_setaffinity(getpid(), sizeof(cpu_set_t), &cpuset); + if (ret != 0) { + return EXIT_CODE_ERRNO_2; + } + + CPU_ZERO(&cpuset); + ret = sched_getaffinity(getpid(), sizeof(cpu_set_t), &cpuset); + if (ret != 0) { + return EXIT_CODE_ERRNO_3; + } + ret = (CPU_ISSET(0, &cpuset) > 0) ? 1 : 0; + if (ret != 0) { + return EXIT_CODE_ERRNO_4; + } + ret = (CPU_ISSET(1, &cpuset) > 0) ? 1 : 0; + if (ret != 1) { + return EXIT_CODE_ERRNO_5; + } + + return 0; +} + +void ItPidContainer008(void) +{ + int status; + int ret; + void *pstk = malloc(STACK_SIZE); + ASSERT_TRUE(pstk != NULL); + int childPid = clone(ChildFun, (char *)pstk + STACK_SIZE, CLONE_NEWPID | SIGCHLD, NULL); + free(pstk); + ASSERT_NE(childPid, -1); + + ret = waitpid(childPid, &status, 0); + ASSERT_EQ(ret, childPid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_009.cpp b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_009.cpp new file mode 100644 index 00000000..47672603 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_009.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +static int ChildFun(void *p) +{ + (void)p; + int ret; + int status = 0; + pid_t pid; + int count = 100; + int processCount = 0; + + pid = getpid(); + if (pid != CONTAINER_FIRST_PID) { + return EXIT_CODE_ERRNO_1; + } + + for (int i = 0; i < count; i++) { + pid = fork(); + if (pid == 0) { + sleep(2); /* delay 2s */ + exit(0); + } else if (pid < 0) { + if (errno != EAGAIN) { + sleep(1); + } + ret = wait(&status); + if (ret > 0) { + processCount--; + } + continue; + } else { + processCount++; + continue; + } + } + + ret = 0; + while (processCount > 0) { + ret = wait(&status); + if (ret > 0) { + processCount--; + } else { + sleep(1); + } + } + exit(EXIT_CODE_ERRNO_255); +} + +void ItPidContainer009(void) +{ + int ret = 0; + int status; + void *pstk = malloc(STACK_SIZE); + ASSERT_TRUE(pstk != NULL); + int childPid = clone(ChildFun, (char *)pstk + STACK_SIZE, CLONE_NEWPID | SIGCHLD, NULL); + free(pstk); + ASSERT_NE(childPid, -1); + + ret = waitpid(childPid, &status, 0); + ASSERT_EQ(ret, childPid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, EXIT_CODE_ERRNO_255); + + sleep(5); /* 5: Wait for process resources to be reclaimed */ +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_010.cpp b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_010.cpp new file mode 100644 index 00000000..f947796f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_010.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +static int ChildFun(void *p) +{ + (void)p; + int ret; + int currGid = getpgrp(); + if (currGid != CONTAINER_FIRST_PID) { + printf("ChildFun pid %d currGid %d\n", getpid(), currGid); + return EXIT_CODE_ERRNO_1; + } + + ret = setpgid(getpid(), 0); + if (ret == 0) { + return EXIT_CODE_ERRNO_2; + } + return 0; +} + +void ItPidContainer010(void) +{ + int status; + int ret; + void *pstk = malloc(STACK_SIZE); + ASSERT_TRUE(pstk != NULL); + int childPid = clone(ChildFun, (char *)pstk + STACK_SIZE, CLONE_NEWPID | SIGCHLD, NULL); + free(pstk); + ASSERT_NE(childPid, -1); + + ret = waitpid(childPid, &status, 0); + ASSERT_EQ(ret, childPid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_011.cpp b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_011.cpp new file mode 100644 index 00000000..f20998af --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_011.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +static int ChildFun(void *p) +{ + (void)p; + return execl("/bin/toybox", "toybox", "ps", (char *)0); +} + +void ItPidContainer011(void) +{ + int status; + int ret; + void *pstk = malloc(STACK_SIZE); + ASSERT_TRUE(pstk != NULL); + int childPid = clone(ChildFun, (char *)pstk + STACK_SIZE, CLONE_NEWPID | SIGCHLD, NULL); + free(pstk); + ASSERT_NE(childPid, -1); + + ret = waitpid(childPid, &status, 0); + ASSERT_EQ(ret, childPid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_012.cpp b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_012.cpp new file mode 100644 index 00000000..1e04c248 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_012.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +static int ChildFun(void *p) +{ + (void)p; + return execl("/bin/shell", "shell", "kill", "-9", "1", (char *)0); +} + +void ItPidContainer012(void) +{ + int status; + int ret; + const int SIGNAL_NUM = 9; + void *pstk = malloc(STACK_SIZE); + ASSERT_TRUE(pstk != NULL); + int childPid = clone(ChildFun, (char *)pstk + STACK_SIZE, CLONE_NEWPID | SIGCHLD, NULL); + free(pstk); + ASSERT_NE(childPid, -1); + + ret = waitpid(childPid, &status, 0); + ASSERT_EQ(ret, childPid); + ret = WIFEXITED(status); + ASSERT_EQ(ret, 0); + ret = WTERMSIG(status); + ASSERT_EQ(ret, SIGNAL_NUM); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_013.cpp b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_013.cpp new file mode 100644 index 00000000..21d9a7ed --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_013.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +static int ChildFun(void *p) +{ + (void)p; + pid_t pid = getpid(); + if (pid != 1) { + return EXIT_CODE_ERRNO_1; + } + struct timespec ts = { 0 }; + const int MIN_NSEC = 5000000; + const int MAX_NSEC = 20000000; + int ret = sched_rr_get_interval(pid, &ts); + if ((ts.tv_nsec < MIN_NSEC) || (ts.tv_nsec > MAX_NSEC)) { + if (ts.tv_nsec != -1) { + return EXIT_CODE_ERRNO_2; + } + } + return ret; +} + +void ItPidContainer013(void) +{ + int status; + int ret; + void *pstk = malloc(STACK_SIZE); + ASSERT_TRUE(pstk != NULL); + int childPid = clone(ChildFun, (char *)pstk + STACK_SIZE, CLONE_NEWPID | SIGCHLD, NULL); + free(pstk); + ASSERT_NE(childPid, -1); + + ret = waitpid(childPid, &status, 0); + ASSERT_EQ(ret, childPid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_014.cpp b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_014.cpp new file mode 100644 index 00000000..98d73cd9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_014.cpp @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +static int ChildFun(void *p) +{ + (void)p; + int ret = 0; + int val, currPolicy; + struct sched_param param = { 0 }; + const int DEFALUTE_PRIORITY = 31; + int testProcessPri = 0; + int currProcessPri = getpriority(PRIO_PROCESS, getpid()); + if ((currProcessPri > DEFALUTE_PRIORITY) || (currProcessPri < 0)) { + return EXIT_CODE_ERRNO_1; + } + + testProcessPri = currProcessPri + 1; + currPolicy = sched_getscheduler(getpid()); + if (currPolicy != SCHED_RR) { + return EXIT_CODE_ERRNO_2; + } + + val = getpriority(PRIO_PROCESS, 0); + if (val != currProcessPri) { + return EXIT_CODE_ERRNO_3; + } + + ret = sched_getparam(0, ¶m); + if ((ret != 0) || (param.sched_priority != currProcessPri)) { + return EXIT_CODE_ERRNO_4; + } + + val = sched_getscheduler(0); + if (val != currPolicy) { + return EXIT_CODE_ERRNO_5; + } + + ret = setpriority(PRIO_PROCESS, 0, testProcessPri); + if (ret != 0) { + return EXIT_CODE_ERRNO_6; + } + + ret = getpriority(PRIO_PROCESS, 0); + if (ret != testProcessPri) { + return EXIT_CODE_ERRNO_7; + } + + param.sched_priority = currProcessPri; + ret = sched_setparam(0, ¶m); + if (ret != 0) { + return EXIT_CODE_ERRNO_8; + } + + ret = getpriority(PRIO_PROCESS, getpid()); + if (ret != currProcessPri) { + return EXIT_CODE_ERRNO_9; + } + + ret = sched_setscheduler(0, SCHED_FIFO, ¶m); + if ((ret != -1) || (errno != EINVAL)) { + return EXIT_CODE_ERRNO_10; + } + + ret = sched_setscheduler(0, SCHED_RR, ¶m); + if (ret != 0) { + return EXIT_CODE_ERRNO_11; + } + + ret = sched_setscheduler(1, SCHED_FIFO, ¶m); + if ((ret != -1) || (errno != EINVAL)) { + return EXIT_CODE_ERRNO_12; + } + + ret = sched_setscheduler(2, SCHED_FIFO, ¶m); // 2, input the pid. + if ((ret != -1) || (errno != ESRCH)) { + return EXIT_CODE_ERRNO_13; + } + + ret = sched_setparam(1, ¶m); + if (ret != 0) { + return EXIT_CODE_ERRNO_14; + } + + ret = sched_setparam(2, ¶m); // 2, set the param. + if ((ret != -1) || (errno != ESRCH)) { + return EXIT_CODE_ERRNO_15; + } + + ret = setpriority(PRIO_PROCESS, 1, testProcessPri); + if (ret != 0) { + return EXIT_CODE_ERRNO_16; + } + + ret = setpriority(PRIO_PROCESS, 2, testProcessPri); // 2, Used to calculate priorities. + if ((ret != -1) || (errno != ESRCH)) { + return EXIT_CODE_ERRNO_255; + } + + return 0; +} + +void ItPidContainer014(void) +{ + int status; + int ret; + void *pstk = malloc(STACK_SIZE); + ASSERT_TRUE(pstk != NULL); + int childPid = clone(ChildFun, (char *)pstk + STACK_SIZE, CLONE_NEWPID | SIGCHLD, NULL); + free(pstk); + ASSERT_NE(childPid, -1); + + ret = waitpid(childPid, &status, 0); + ASSERT_EQ(ret, childPid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_015.cpp b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_015.cpp new file mode 100644 index 00000000..e3964cdd --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_015.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +static int ChildFun(void *p) +{ + (void)p; + int ret = execl("/bin/shell", "shell", "v2p", "1", "0x1000000", (char *)0); + if (ret < 0) { + return errno; + } + return 0; +} + +void ItPidContainer015(void) +{ + int status; + int ret; + void *pstk = malloc(STACK_SIZE); + ASSERT_TRUE(pstk != NULL); + int childPid = clone(ChildFun, (char *)pstk + STACK_SIZE, CLONE_NEWPID | SIGCHLD, NULL); + free(pstk); + ASSERT_NE(childPid, -1); + + ret = waitpid(childPid, &status, 0); + ASSERT_EQ(ret, childPid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_016.cpp b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_016.cpp new file mode 100644 index 00000000..102f5b5b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_016.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +static int ChildFun(void *p) +{ + (void)p; + int ret = execl("/bin/shell", "shell", "vmm", "1", (char *)0); + if (ret < 0) { + return errno; + } + return 0; +} + +void ItPidContainer016(void) +{ + int status; + int ret; + void *pstk = malloc(STACK_SIZE); + ASSERT_TRUE(pstk != NULL); + int childPid = clone(ChildFun, (char *)pstk + STACK_SIZE, CLONE_NEWPID | SIGCHLD, NULL); + free(pstk); + ASSERT_NE(childPid, -1); + + ret = waitpid(childPid, &status, 0); + ASSERT_EQ(ret, childPid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_017.cpp b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_017.cpp new file mode 100644 index 00000000..ab671415 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_017.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +static int ChildFun(void *p) +{ + (void)p; + int ret = execl("/bin/shell", "shell", "cpup", "0", "1", (char *)0); + if (ret < 0) { + return errno; + } + return 0; +} + +void ItPidContainer017(void) +{ + int status; + int ret; + void *pstk = malloc(STACK_SIZE); + ASSERT_TRUE(pstk != NULL); + int childPid = clone(ChildFun, (char *)pstk + STACK_SIZE, CLONE_NEWPID | SIGCHLD, NULL); + free(pstk); + ASSERT_NE(childPid, -1); + + ret = waitpid(childPid, &status, 0); + ASSERT_EQ(ret, childPid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_018.cpp b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_018.cpp new file mode 100644 index 00000000..9cbc95c5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_018.cpp @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +const int TEST_COUNT = 5; +const int TEST_PARENT_SLEEP_TIME = 2; +const int TEST_CHILD_SLEEP_TIME = 5; +static int ChildShell(void *p) +{ + printf("\n###################### %s pid container process info ####################\n", (char *)p); + int ret = execl("/bin/shell", "shell", "task", "-a", (char *)0); + if (ret < 0) { + return errno; + } + return 0; +} + +static void *PthreadFunc(void *arg) +{ + (void)arg; + sleep(TEST_CHILD_SLEEP_TIME); + return NULL; +} + +static int Child2(void *p) +{ + (void)p; + sleep(TEST_CHILD_SLEEP_TIME); + exit(0); +} + +static int Child1(void *p) +{ + (void)p; + int ret; + pid_t pid = fork(); + if (pid == 0) { + sleep(TEST_CHILD_SLEEP_TIME); + exit(0); + } + + sleep(TEST_CHILD_SLEEP_TIME); + + ret = waitpid(pid, NULL, 0); + if (ret != pid) { + exit(EXIT_CODE_ERRNO_5); + } + return 0; +} + +static int ChildFun(void *p) +{ + (void)p; + int ret; + + pid_t pid1 = fork(); + if (pid1 == 0) { + ret = Child1(NULL); + exit(ret); + } + + pid_t pid2 = fork(); + if (pid2 == 0) { + (void)Child2(NULL); + } + + pid_t pid3 = fork(); + if (pid3 == 0) { + ret = ChildShell(static_cast(const_cast("Child"))); + if (ret != 0) { + exit(EXIT_CODE_ERRNO_1); + } + exit(0); + } + + sleep(TEST_CHILD_SLEEP_TIME); + + ret = waitpid(pid1, NULL, 0); + if (ret != pid1) { + exit(EXIT_CODE_ERRNO_2); + } + + ret = waitpid(pid2, NULL, 0); + if (ret != pid2) { + exit(EXIT_CODE_ERRNO_3); + } + + ret = waitpid(pid3, NULL, 0); + if (ret != pid3) { + exit(EXIT_CODE_ERRNO_4); + } + + return 0; +} + +void ItPidContainer018(void) +{ + int status; + int ret; + pid_t pid; + void *pstk = malloc(STACK_SIZE); + ASSERT_TRUE(pstk != NULL); + int childPid = clone(ChildFun, (char *)pstk + STACK_SIZE, CLONE_NEWPID | SIGCHLD, NULL); + free(pstk); + ASSERT_NE(childPid, -1); + + sleep(TEST_PARENT_SLEEP_TIME); + + pid = fork(); + if (pid == 0) { + ret = ChildShell(static_cast(const_cast("Parent"))); + ASSERT_EQ(ret, 0); + } + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); + + ret = waitpid(childPid, &status, 0); + ASSERT_EQ(ret, childPid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_019.cpp b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_019.cpp new file mode 100644 index 00000000..b0178247 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_019.cpp @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +const int TEST_COUNT = 5; +const int TEST_CMD_LEN = 20; +const int TEST_PARENT_SLEEP_TIME = 2; +const int TEST_CHILD_SLEEP_TIME = 5; +static int ChildShell(void *p) +{ + pid_t pid = (pid_t)(uintptr_t)p; + char param[TEST_CMD_LEN] = {0}; + int ret = snprintf_s(param, TEST_CMD_LEN, TEST_CMD_LEN - 1, "-p %d", pid); + if (ret < 0) { + return errno; + } + + printf("\n###################### Pid %d thread info ####################\n", pid); + ret = execl("/bin/shell", "shell", "task", param, (char *)0); + if (ret < 0) { + return errno; + } + return 0; +} + +static void *PthreadFunc(void *arg) +{ + (void)arg; + sleep(TEST_CHILD_SLEEP_TIME); + return NULL; +} + +static int ChildFun(void *p) +{ + (void)p; + int ret; + + pthread_t pthread[TEST_COUNT] = {0}; + for (int count = 0; count < TEST_COUNT; count++) { + pthread_create(&pthread[count], NULL, PthreadFunc, NULL); + } + + pid_t pid1 = fork(); + if (pid1 == 0) { + ret = ChildShell(reinterpret_cast(getppid())); + if (ret != 0) { + exit(EXIT_CODE_ERRNO_1); + } + } + + sleep(TEST_CHILD_SLEEP_TIME); + + ret = waitpid(pid1, NULL, 0); + if (ret != pid1) { + exit(EXIT_CODE_ERRNO_2); + } + + return 0; +} + +void ItPidContainer019(void) +{ + int status; + int ret; + pid_t pid; + void *pstk = malloc(STACK_SIZE); + ASSERT_TRUE(pstk != NULL); + int childPid = clone(ChildFun, (char *)pstk + STACK_SIZE, CLONE_NEWPID | SIGCHLD, NULL); + free(pstk); + ASSERT_NE(childPid, -1); + + sleep(TEST_PARENT_SLEEP_TIME); + + pid = fork(); + if (pid == 0) { + ret = ChildShell((void *)childPid); + ASSERT_EQ(ret, 0); + } + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); + + ret = waitpid(childPid, &status, 0); + ASSERT_EQ(ret, childPid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_020.cpp b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_020.cpp new file mode 100644 index 00000000..f598bb22 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_020.cpp @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +const int TEST_COUNT = 5; +const int TEST_PARENT_SLEEP_TIME = 3; +static int Child(void *p) +{ + (void)p; + pid_t pid1 = fork(); + if (pid1 == 0) { + pid_t pid3 = fork(); + if (pid3 == 0) { + sleep(TEST_PARENT_SLEEP_TIME); + exit(0); + } + + sleep(TEST_PARENT_SLEEP_TIME); + if (getppid() != 1) { + exit(EXIT_CODE_ERRNO_3); + } + exit(0); + } + + pid_t pid2 = fork(); + if (pid2 == 0) { + sleep(TEST_PARENT_SLEEP_TIME); + + if (getppid() != 1) { + exit(EXIT_CODE_ERRNO_4); + } + exit(0); + } + + exit(0); +} + +static int ChildFun(void *p) +{ + (void)p; + int ret; + int count = 2; + int status = 0; + + pid_t pid1 = fork(); + if (pid1 == 0) { + (void)Child(NULL); + } + + ret = waitpid(pid1, &status, 0); + if ((ret != pid1) || (WIFEXITED(status) == 0)) { + exit(EXIT_CODE_ERRNO_2); + } + if (WEXITSTATUS(status) != 0) { + exit(WEXITSTATUS(status)); + } + + while (count > 0) { + ret = wait(&status); + if ((ret < 0) || (WIFEXITED(status) == 0)) { + exit(EXIT_CODE_ERRNO_3); + } + if (WEXITSTATUS(status) != 0) { + exit(WEXITSTATUS(status)); + } + count--; + } + + return 0; +} + +void ItPidContainer020(void) +{ + int status; + int ret; + void *pstk = malloc(STACK_SIZE); + ASSERT_TRUE(pstk != NULL); + int childPid = clone(ChildFun, (char *)pstk + STACK_SIZE, CLONE_NEWPID | SIGCHLD, NULL); + free(pstk); + ASSERT_NE(childPid, -1); + + ret = waitpid(childPid, &status, 0); + ASSERT_EQ(ret, childPid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); + + sleep(5); /* 5: Wait for process resources to be reclaimed */ +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_021.cpp b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_021.cpp new file mode 100644 index 00000000..96115cea --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_021.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +static int ChildFun(void *p) +{ + (void)p; + struct timespec ts; + clockid_t clockid; + int ret; + const int TEST_PID = 2; + ret = clock_getcpuclockid(TEST_PID, &clockid); + if (ret != EINVAL) { + return EXIT_CODE_ERRNO_1; + } + + ret = clock_getcpuclockid(getpid(), &clockid); + if (ret != 0) { + return EXIT_CODE_ERRNO_2; + } + ret = clock_gettime(clockid, &ts); + if (ret != 0) { + return EXIT_CODE_ERRNO_3; + } + return 0; +} + +void ItPidContainer021(void) +{ + void *pstk = malloc(STACK_SIZE); + ASSERT_TRUE(pstk != NULL); + int ret; + int status; + + int childPid = clone(ChildFun, (char *)pstk + STACK_SIZE, CLONE_NEWPID | SIGCHLD, NULL); + free(pstk); + ASSERT_NE(childPid, -1); + + ret = waitpid(childPid, &status, 0); + ASSERT_EQ(ret, childPid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_022.cpp b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_022.cpp new file mode 100644 index 00000000..83f895fb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_022.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +static int ChildFun(void *p) +{ + (void)p; + int ret; + unsigned int cap; + pid_t pid = getpid(); + + ret = ohos_capget(pid, &cap); + if (ret != 0) { + return EXIT_CODE_ERRNO_1; + } + + ret = kill(pid, SIGKILL); + if (ret != 0) { + return EXIT_CODE_ERRNO_2; + } + return ret; +} + +void ItPidContainer022(void) +{ + void *pstk = malloc(STACK_SIZE); + ASSERT_TRUE(pstk != NULL); + int ret; + siginfo_t info = { 0 }; + + int childPid = clone(ChildFun, (char *)pstk + STACK_SIZE, CLONE_NEWPID | SIGCHLD, NULL); + free(pstk); + ASSERT_NE(childPid, -1); + + ret = waitid(P_PID, childPid, &info, WEXITED); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_024.cpp b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_024.cpp new file mode 100644 index 00000000..d103af47 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/full/It_pid_container_024.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" +#include "sys/resource.h" +#include "sys/wait.h" +#include "pthread.h" +#include "sched.h" + +const int LOOP_NUM = 100; + +static int ChildFunc(void *arg) +{ + (void)arg; + exit(EXIT_CODE_ERRNO_5); +} + +static int GroupProcess(void *arg) +{ + (void)arg; + int ret; + int status = 0; + + for (int i = 0; i < LOOP_NUM; i++) { + int argTmp = CHILD_FUNC_ARG; + auto pid = CloneWrapper(ChildFunc, CLONE_NEWPID, &argTmp); + if (pid == -1) { + return EXIT_CODE_ERRNO_1; + } + + ret = waitpid(pid, &status, 0); + status = WEXITSTATUS(status); + if (status != EXIT_CODE_ERRNO_5) { + return EXIT_CODE_ERRNO_2; + } + usleep(10000); + } + + exit(EXIT_CODE_ERRNO_5); +} + +void ItPidContainer024(void) +{ + int ret; + int status = 0; + int arg = CHILD_FUNC_ARG; + auto pid = CloneWrapper(GroupProcess, CLONE_NEWPID, &arg); + ASSERT_NE(pid, -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + status = WEXITSTATUS(status); + ASSERT_EQ(status, EXIT_CODE_ERRNO_5); + + sleep(5); /* 5: Wait for process resources to be reclaimed */ +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/full/It_user_container_005.cpp b/src/kernel_liteos_a/testsuites/unittest/container/full/It_user_container_005.cpp new file mode 100644 index 00000000..297fa9fe --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/full/It_user_container_005.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" +#include "sys/resource.h" +#include "sys/wait.h" +#include "pthread.h" +#include "sched.h" + +const int EXIT_TRUE_CODE = 255; +const int MAX_PID_RANGE = 100000; +const int SLEEP_TIME_US = 1000; +const int LOOP_NUM = 1000; + +static int childFunc(void *arg) +{ + (void)arg; + usleep(SLEEP_TIME_US); + exit(EXIT_TRUE_CODE); +} + +static int GroupProcess(void *arg) +{ + (void)arg; + int ret; + int status = 0; + + for (int i = 0; i < LOOP_NUM; i++) { + int arg_child = CHILD_FUNC_ARG; + auto pid = CloneWrapper(childFunc, CLONE_NEWUSER, &arg_child); + if (pid == -1) { + return EXIT_CODE_ERRNO_1; + } + + ret = waitpid(pid, &status, 0); + if (ret != pid) { + return EXIT_CODE_ERRNO_2; + } + + status = WEXITSTATUS(status); + if (status != EXIT_TRUE_CODE) { + return EXIT_CODE_ERRNO_3; + } + } + + exit(EXIT_TRUE_CODE); +} + +void ItUserContainer005(void) +{ + int ret; + int status = 0; + int arg = CHILD_FUNC_ARG; + auto pid = CloneWrapper(GroupProcess, CLONE_NEWUSER, &arg); + ASSERT_NE(pid, -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + status = WEXITSTATUS(status); + ASSERT_EQ(status, EXIT_TRUE_CODE); + + sleep(5); /* 5: Wait for process resources to be reclaimed */ +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/full/It_uts_container_003.cpp b/src/kernel_liteos_a/testsuites/unittest/container/full/It_uts_container_003.cpp new file mode 100644 index 00000000..1338441c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/full/It_uts_container_003.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" +#include "sys/resource.h" +#include "sys/wait.h" +#include "pthread.h" +#include "sched.h" + +const int SLEEP_TIME_US = 1000; +const int LOOP_NUM = 100; + +static int ChildFunc(void *arg) +{ + (void)arg; + usleep(SLEEP_TIME_US); + exit(EXIT_CODE_ERRNO_5); +} + +static int GroupProcess(void *arg) +{ + (void)arg; + int ret; + int status = 0; + + for (int i = 0; i < LOOP_NUM; i++) { + int argTmp = CHILD_FUNC_ARG; + auto pid = CloneWrapper(ChildFunc, CLONE_NEWUTS, &argTmp); + if (pid == -1) { + return EXIT_CODE_ERRNO_1; + } + + ret = waitpid(pid, &status, 0); + status = WEXITSTATUS(status); + if (status != EXIT_CODE_ERRNO_5) { + return EXIT_CODE_ERRNO_2; + } + } + + exit(EXIT_CODE_ERRNO_5); +} + +void ItUtsContainer003(void) +{ + int ret; + int status = 0; + int arg = CHILD_FUNC_ARG; + auto pid = CloneWrapper(GroupProcess, CLONE_NEWUTS, &arg); + ASSERT_NE(pid, -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + status = WEXITSTATUS(status); + ASSERT_EQ(status, EXIT_CODE_ERRNO_5); + + sleep(5); /* 5: Wait for process resources to be reclaimed */ +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_container_001.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_container_001.cpp new file mode 100644 index 00000000..2a739061 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_container_001.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" +using namespace std; + +const int TIMER_INTERVAL_3S = 3; + +static int ChildFunc(void *arg) +{ + int value = *((int *)arg); + if (value != CHILD_FUNC_ARG) { + return EXIT_CODE_ERRNO_1; + } + sleep(TIMER_INTERVAL_3S); + return 0; +} + +void ItContainer001(void) +{ + int ret; + int status = 0; + int childReturn = 0; + int arg = CHILD_FUNC_ARG; + char *stack = nullptr; + char *stackTop = nullptr; + stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); + ASSERT_NE(stack, MAP_FAILED); + stackTop = stack + STACK_SIZE; + + auto pid = clone(ChildFunc, stackTop, SIGCHLD, &arg); + (void)munmap(stack, STACK_SIZE); + ASSERT_NE(pid, -1); + + ret = waitpid(pid, &status, 0); + childReturn = (status >> BIT_ON_RETURN_VALUE) & 0xff; + ASSERT_EQ(childReturn, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_container_chroot_001.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_container_chroot_001.cpp new file mode 100644 index 00000000..870cf65f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_container_chroot_001.cpp @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" +using namespace std; + +static int ChildFunc(void *arg) +{ + int ret; + int value = *((int *)arg); + + if (value != CHILD_FUNC_ARG) { + return EXIT_CODE_ERRNO_1; + } + + ret = mount(USERDATA_DEV_NAME, USERDATA_DIR_NAME, FS_TYPE, 0, nullptr); + if (ret != 0) { + return EXIT_CODE_ERRNO_2; + } + + ret = access(ACCESS_FILE_NAME, F_OK); + if (ret != 0) { + return EXIT_CODE_ERRNO_3; + } + + ret = chroot(USERDATA_DIR_NAME); + if (ret != 0) { + return EXIT_CODE_ERRNO_4; + } + + ret = access(ACCESS_FILE_NAME, F_OK); + if (ret == 0) { + return EXIT_CODE_ERRNO_5; + } + + ret = access(MNT_ACCESS_FILE_NAME, F_OK); + if (ret != 0) { + return EXIT_CODE_ERRNO_6; + } + + return 0; +} + +void ItContainerChroot001(void) +{ + int ret; + int status = 0; + int childReturn = 0; + int arg = CHILD_FUNC_ARG; + char *stack = nullptr; + char *stackTop = nullptr; + + stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); + ASSERT_NE(stack, MAP_FAILED); + + ret = umount(USERDATA_DIR_NAME); + ASSERT_EQ(ret, 0); + + stackTop = stack + STACK_SIZE; + auto pid = clone(ChildFunc, stackTop, CLONE_NEWNS, &arg); + ASSERT_NE(pid, -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); + + ret = access(ACCESS_FILE_NAME, F_OK); + ASSERT_NE(ret, 0); + + ret = umount(USERDATA_DIR_NAME); + ASSERT_NE(ret, 0); + + ret = mount(USERDATA_DEV_NAME, USERDATA_DIR_NAME, FS_TYPE, 0, nullptr); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_container_chroot_002.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_container_chroot_002.cpp new file mode 100644 index 00000000..0bbfcf6e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_container_chroot_002.cpp @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" +using namespace std; + +static int OpendirCheck(void) +{ + DIR *dir = opendir("/proc"); + if (dir == nullptr) { + return EXIT_CODE_ERRNO_1; + } + closedir(dir); + return 0; +} + +static int ChildFunc(void *arg) +{ + int ret = 0; + ret = OpendirCheck(); + if (ret == 0) { + return EXIT_CODE_ERRNO_1; + } + + return 0; +} + +static int TestFunc(void *arg) +{ + int ret = 0; + int fd; + char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); + if (stack == nullptr) { + return EXIT_CODE_ERRNO_1; + } + char *stackTop = stack + STACK_SIZE; + + ret = OpendirCheck(); + if (ret != 0) { + return EXIT_CODE_ERRNO_2; + } + + ret = chroot("/system/etc"); + if (ret != 0) { + return EXIT_CODE_ERRNO_3; + } + + ret = OpendirCheck(); + if (ret == 0) { + return EXIT_CODE_ERRNO_4; + } + fd = open("/PCID.sc", O_RDONLY); + if (fd == -1) { + return EXIT_CODE_ERRNO_5; + } + close(fd); + sleep(1); + + auto pid = clone(ChildFunc, stackTop, SIGCHLD, arg); + if (pid == -1) { + return EXIT_CODE_ERRNO_6; + } + int status; + ret = waitpid(pid, &status, 0); + ret = WIFEXITED(status); + int exitCode = WEXITSTATUS(status); + if (exitCode != 0) { + return EXIT_CODE_ERRNO_7; + } + + return 0; +} + +void ItContainerChroot002(void) +{ + int ret = 0; + char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); + ASSERT_TRUE(stack != nullptr); + char *stackTop = stack + STACK_SIZE; + + int arg = CHILD_FUNC_ARG; + auto pid = clone(TestFunc, stackTop, SIGCHLD, &arg); + ASSERT_NE(pid, -1); + + int status; + ret = waitpid(pid, &status, 0); + ret = WIFEXITED(status); + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_ipc_container_001.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_ipc_container_001.cpp new file mode 100644 index 00000000..792398e9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_ipc_container_001.cpp @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include "It_container_test.h" +using namespace std; + +static int childFunc(void *arg) +{ + int ret; + (void)arg; + mqd_t mqueueChild; + char msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + char mqname[MQUEUE_STANDARD_NAME_LENGTH] = "/testMQueue001"; + const char msgptr[] = "childMsgs"; + struct mq_attr attr = { 0 }; + attr.mq_msgsize = MQUEUE_TEST_SIZE; + attr.mq_maxmsg = MQUEUE_TEST_MAX_MSG; + mqueueChild = mq_open(mqname, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR, &attr); + if (mqueueChild == (mqd_t)-1) { + goto EXIT1; + } + ret = mq_send(mqueueChild, msgptr, strlen(msgptr), 0); + if (ret != 0) { + goto EXIT1; + } + ret = mq_receive(mqueueChild, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + if (ret == -1) { + goto EXIT1; + } + if (strncmp(msgrcd, msgptr, strlen(msgptr)) != 0) { + goto EXIT1; + } + +EXIT1: + if (mqueueChild >= 0) { + ret = mq_close(mqueueChild); + if (ret != 0) { + return EXIT_CODE_ERRNO_1; + } + ret = mq_unlink(mqname); + if (ret != 0) { + return EXIT_CODE_ERRNO_2; + } + } + return EXIT_CODE_ERRNO_7; +} + +void ItIpcContainer001(void) +{ + uint32_t ret; + int status; + int exitCode; + pid_t pid; + mqd_t mqueueParent; + int arg = CHILD_FUNC_ARG; + char *stack = (char *)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, + -1, 0); + ASSERT_NE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + char msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + char mqname[MQUEUE_STANDARD_NAME_LENGTH] = "/testMQueue001"; + const char msgptr[] = "parentMsg"; + struct mq_attr attr = { 0 }; + attr.mq_msgsize = MQUEUE_TEST_SIZE; + attr.mq_maxmsg = MQUEUE_TEST_MAX_MSG; + + mqueueParent = mq_open(mqname, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR, NULL); + MQueueFinalizer mQueueFinalizer(mqueueParent, mqname); + + ASSERT_NE(mqueueParent, (mqd_t)-1); + + (void)memset_s(&attr, sizeof(attr), 0, sizeof(attr)); + ret = mq_getattr(mqueueParent, &attr); + ASSERT_EQ(ret, 0); + + attr.mq_flags |= O_NONBLOCK; + ret = mq_setattr(mqueueParent, &attr, NULL); + ASSERT_EQ(ret, 0); + + ret = mq_getattr(mqueueParent, &attr); + ASSERT_EQ(ret, 0); + + ret = mq_send(mqueueParent, msgptr, strlen(msgptr), 0); + ASSERT_EQ(ret, 0); + + pid = clone(childFunc, stackTop, CLONE_NEWIPC | SIGCHLD, &arg); + ASSERT_NE(pid, -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + + exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, EXIT_CODE_ERRNO_7); + + ret = mq_receive(mqueueParent, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ASSERT_NE(ret, -1); + ASSERT_STREQ(msgrcd, msgptr); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_ipc_container_002.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_ipc_container_002.cpp new file mode 100644 index 00000000..7ccc878f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_ipc_container_002.cpp @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include "It_container_test.h" +using namespace std; + +static int childFunc(void *arg) +{ + int ret; + (void)arg; + char msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + char mqname[] = "/testMQueue003"; + const char msgptr[] = "childMsgs"; + struct mq_attr attr = { 0 }; + mqd_t mqueue; + attr.mq_msgsize = MQUEUE_TEST_SIZE; + attr.mq_maxmsg = MQUEUE_TEST_MAX_MSG; + + mqueue = mq_open(mqname, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR, &attr); + if (mqueue == (mqd_t)-1) { + goto EXIT1; + } + ret = mq_send(mqueue, msgptr, strlen(msgptr), 0); + if (ret != 0) { + goto EXIT1; + } + ret = mq_receive(mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + if (ret != strlen(msgptr)) { + goto EXIT1; + } + if (strncmp(msgrcd, msgptr, strlen(msgptr)) != 0) { + goto EXIT1; + } + +EXIT1: + if (mqueue >= 0) { + ret = mq_close(mqueue); + if (ret != 0) { + return EXIT_CODE_ERRNO_1; + } + ret = mq_unlink(mqname); + if (ret != 0) { + return EXIT_CODE_ERRNO_2; + } + } + return EXIT_CODE_ERRNO_7; +} + +void ItIpcContainer002(void) +{ + uint32_t ret; + int status; + int exitCode; + mqd_t mqueue; + pid_t childPid; + int arg = CHILD_FUNC_ARG; + char *stack = (char *)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, + -1, 0); + ASSERT_NE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + struct mq_attr attr = { 0 }; + attr.mq_msgsize = MQUEUE_TEST_SIZE; + attr.mq_maxmsg = MQUEUE_TEST_MAX_MSG; + char msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + char mqname[] = "/testMQueue004"; + const char msgptr[] = "parentMsg"; + std::string containerType = "ipc"; + std::string filePath; + int fd; + int parentPid; + std::string parentlink; + std::string childlink; + + mqueue = mq_open(mqname, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR, NULL); + MQueueFinalizer mQueueFinalizer(mqueue, mqname); + + ASSERT_NE(mqueue, (mqd_t)-1); + + (void)memset_s(&attr, sizeof(attr), 0, sizeof(attr)); + ret = mq_getattr(mqueue, &attr); + ASSERT_EQ(ret, 0); + + attr.mq_flags |= O_NONBLOCK; + ret = mq_setattr(mqueue, &attr, NULL); + ASSERT_EQ(ret, 0); + + ret = mq_getattr(mqueue, &attr); + ASSERT_EQ(ret, 0); + + ret = mq_send(mqueue, msgptr, strlen(msgptr), 0); + ASSERT_EQ(ret, 0); + + ret = mq_close(mqueue); + ASSERT_EQ(ret, 0); + + ret = mq_unlink(mqname); + ASSERT_EQ(ret, 0); + + childPid = clone(childFunc, stackTop, CLONE_NEWIPC | SIGCHLD, &arg); + ASSERT_NE(childPid, -1); + + parentPid = getpid(); + parentlink = ReadlinkContainer(parentPid, containerType); + childlink = ReadlinkContainer(childPid, containerType); + filePath = GenContainerLinkPath(childPid, containerType); + fd = open(filePath.c_str(), O_RDONLY); + ASSERT_NE(fd, -1); + + ret = setns(fd, CLONE_NEWIPC); + ASSERT_NE(ret, -1); + + ret = close(fd); + ASSERT_NE(ret, -1); + + ret = waitpid(childPid, &status, 0); + ASSERT_EQ(ret, childPid); + + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + + exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, EXIT_CODE_ERRNO_7); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_ipc_container_003.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_ipc_container_003.cpp new file mode 100644 index 00000000..c824af35 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_ipc_container_003.cpp @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include "It_container_test.h" +using namespace std; + +static int childFunc(void *arg) +{ + int ret; + (void)arg; + char msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + char mqname[] = "/testMQueue005"; + const char msgptr[] = "childMsg"; + struct mq_attr attr = { 0 }; + mqd_t mqueue; + attr.mq_msgsize = MQUEUE_TEST_SIZE; + attr.mq_maxmsg = MQUEUE_TEST_MAX_MSG; + + mqueue = mq_open(mqname, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR, &attr); + if (mqueue == (mqd_t)-1) { + goto EXIT1; + } + ret = mq_send(mqueue, msgptr, strlen(msgptr), 0); + if (ret != 0) { + goto EXIT1; + } + ret = mq_receive(mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + if (ret != strlen(msgptr)) { + goto EXIT1; + } + if (strncmp(msgrcd, msgptr, strlen(msgptr)) != 0) { + goto EXIT1; + } + +EXIT1: + if (mqueue >= 0) { + ret = mq_close(mqueue); + if (ret != 0) { + return EXIT_CODE_ERRNO_1; + } + ret = mq_unlink(mqname); + if (ret != 0) { + return EXIT_CODE_ERRNO_2; + } + } + return EXIT_CODE_ERRNO_7; +} + +static void IpcContainerUnshare(void) +{ + int status, exitCode, ret; + int arg = CHILD_FUNC_ARG; + char *stack = (char *)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0); + ASSERT_NE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + struct mq_attr attr = { 0 }; + attr.mq_msgsize = MQUEUE_TEST_SIZE; + attr.mq_maxmsg = MQUEUE_TEST_MAX_MSG; + struct sigevent notification; + notification.sigev_notify = 5; /* 5: test data */ + char msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + char mqname[] = "/testMQueue006"; + const char msgptr[] = "parentMsg"; + + ret = unshare(CLONE_NEWIPC); + ASSERT_EQ(ret, 0); + + mqd_t mqueue = mq_open(mqname, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR, &attr); + MQueueFinalizer mQueueFinalizer(mqueue, mqname); + + ASSERT_NE(mqueue, (mqd_t)-1); + + ret = mq_notify(mqueue, ¬ification); + ASSERT_EQ(ret, -1); + ASSERT_EQ(errno, EINVAL); + + notification.sigev_notify = SIGEV_THREAD; + ret = mq_notify(mqueue, ¬ification); + ASSERT_EQ(ret, -1); + ASSERT_EQ(errno, ENOTSUP); + + notification.sigev_notify = SIGEV_NONE; + + ret = mq_notify(-1, ¬ification); + ASSERT_EQ(ret, -1); + ASSERT_EQ(errno, EBADF); + + ret = mq_notify(mqueue, ¬ification); + ASSERT_EQ(ret, 0); + + (void)memset_s(&attr, sizeof(attr), 0, sizeof(attr)); + ret = mq_getattr(mqueue, &attr); + ASSERT_EQ(ret, 0); + + attr.mq_flags |= O_NONBLOCK; + ret = mq_setattr(mqueue, &attr, NULL); + ASSERT_EQ(ret, 0); + + ret = mq_getattr(mqueue, &attr); + ASSERT_EQ(ret, 0); + + ret = mq_send(mqueue, msgptr, strlen(msgptr), 0); + ASSERT_EQ(ret, 0); + + pid_t pid = clone(childFunc, stackTop, CLONE_NEWIPC | SIGCHLD, &arg); + ASSERT_NE(pid, -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_NE(pid, 0); + + exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, EXIT_CODE_ERRNO_7); + + ret = mq_notify(mqueue, nullptr); + ASSERT_EQ(ret, 0); + + ret = mq_receive(mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ASSERT_EQ(ret, strlen(msgptr)); + ASSERT_STREQ(msgrcd, msgptr); +} + +void ItIpcContainer003(void) +{ + auto pid = fork(); + ASSERT_TRUE(pid != -1); + if (pid == 0) { + IpcContainerUnshare(); + exit(0); + } + auto ret = waitpid(pid, NULL, 0); + ASSERT_EQ(ret, pid); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_ipc_container_004.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_ipc_container_004.cpp new file mode 100644 index 00000000..7a938d94 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_ipc_container_004.cpp @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" +using namespace std; + +static const char *containerType = "ipc"; + +struct shared_use_st { + char test[SHM_TEST_DATA_SIZE]; +}; + +static int childFunc1(void *arg) +{ + struct shared_use_st *shared = NULL; + const char testBuf[] = "child test shm"; + int ret; + (void)arg; + + int shmid = shmget((key_t)SHM_TEST_KEY1, sizeof(struct shared_use_st), SHM_TEST_OPEN_PERM | IPC_CREAT); + if (shmid == -1) { + return EXIT_CODE_ERRNO_1; + } + + void *shm = shmat(shmid, 0, 0); + if (shm == reinterpret_cast(-1)) { + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_2; + } + shared = (struct shared_use_st *)shm; + ret = strncmp(shared->test, testBuf, strlen(testBuf)); + if (ret != 0) { + shmdt(shm); + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_3; + } + ret = shmdt(shm); + if (ret == -1) { + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_4; + } + return 0; +} + +static int childFunc(void *arg) +{ + const char testBuf[] = "parent test shm"; + const char testBuf1[] = "child test shm"; + int ret, status, pid, exitCode; + (void)arg; + char *stack = (char *)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0); + if (stack == nullptr) { + return EXIT_CODE_ERRNO_17; + } + char *stackTop = stack + STACK_SIZE; + auto linkBuffer = ReadlinkContainer(getpid(), containerType); + + int shmid = shmget((key_t)SHM_TEST_KEY1, sizeof(struct shared_use_st), SHM_TEST_OPEN_PERM | IPC_CREAT); + if (shmid == -1) { + return EXIT_CODE_ERRNO_1; + } + + void *shm = shmat(shmid, 0, 0); + if (shm == reinterpret_cast(-1)) { + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_2; + } + + struct shared_use_st *shared = (struct shared_use_st *)shm; + ret = strncmp(shared->test, testBuf, strlen(testBuf)); + if (ret == 0) { + ret = EXIT_CODE_ERRNO_3; + goto EXIT; + } + + ret = memcpy_s(shared->test, sizeof(struct shared_use_st), testBuf1, sizeof(testBuf1)); + if (ret != 0) { + ret = EXIT_CODE_ERRNO_4; + goto EXIT; + } + + pid = clone(childFunc1, stackTop, SIGCHLD, &arg); + if (pid == -1) { + ret = EXIT_CODE_ERRNO_5; + goto EXIT; + } + + ret = waitpid(pid, &status, 0); + if (ret != pid) { + ret = EXIT_CODE_ERRNO_6; + goto EXIT; + } + + ret = WIFEXITED(status); + if (ret == 0) { + ret = EXIT_CODE_ERRNO_7; + goto EXIT; + } + + exitCode = WEXITSTATUS(status); + if (exitCode != 0) { + ret = EXIT_CODE_ERRNO_8; + goto EXIT; + } + + ret = shmdt(shm); + if (ret == -1) { + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_9; + } + + ret = shmctl(shmid, IPC_RMID, 0); + if (ret == -1) { + return EXIT_CODE_ERRNO_10; + } + + return 0; +EXIT: + shmdt(shm); + shmctl(shmid, IPC_RMID, 0); + return ret; +} + +void ItIpcContainer004(void) +{ + const char testBuf[] = "parent test shm"; + int pid, exitCode, status, ret; + void *shm = NULL; + struct shmid_ds ds = {}; + struct shminfo info = {}; + + int arg = CHILD_FUNC_ARG; + char *stack = (char *)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0); + ASSERT_NE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + + int shmid = shmget((key_t)SHM_TEST_KEY1, sizeof(struct shared_use_st), SHM_TEST_OPEN_PERM | IPC_CREAT); + ShmFinalizer ShmFinalizer(shm, shmid); + ASSERT_NE(shmid, -1); + + shm = shmat(shmid, 0, 0); + ASSERT_NE((int)shm, -1); + + struct shared_use_st *shared = (struct shared_use_st *)shm; + ret = memcpy_s(shared->test, sizeof(struct shared_use_st), testBuf, sizeof(testBuf)); + ASSERT_EQ(ret, 0); + + pid = clone(childFunc, stackTop, CLONE_NEWIPC | SIGCHLD, &arg); + ASSERT_NE(pid, -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + + exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); + + ret = shmctl(shmid, IPC_STAT, &ds); + ASSERT_EQ(ret, 0); + ASSERT_EQ(ds.shm_segsz, PAGE_SIZE); + ASSERT_EQ(ds.shm_nattch, 1); + ASSERT_EQ(ds.shm_cpid, getpid()); + ASSERT_EQ(ds.shm_lpid, getpid()); + ASSERT_EQ(ds.shm_perm.uid, getuid()); + + ret = shmctl(shmid, SHM_STAT, &ds); + ASSERT_NE(ret, -1); + ASSERT_NE(ret, 0); + + ds.shm_perm.uid = getuid(); + ds.shm_perm.gid = getgid(); + ds.shm_perm.mode = 0; + ret = shmctl(shmid, IPC_SET, &ds); + ASSERT_EQ(ret, 0); + + ret = shmctl(shmid, IPC_INFO, (struct shmid_ds *)&info); + ASSERT_EQ(ret, 192); /* 192: test value */ + ASSERT_EQ(info.shmmax, 0x1000000); /* 0x1000000: Shared memory information */ + ASSERT_EQ(info.shmmin, 1); /* 1: Shared memory information */ + ASSERT_EQ(info.shmmni, 192); /* 192: Shared memory information */ + ASSERT_EQ(info.shmseg, 128); /* 128: Shared memory information */ + ASSERT_EQ(info.shmall, 0x1000); /* 0x1000: Shared memory information */ + + ret = shmdt(shm); + ASSERT_NE(ret, -1); + + ret = shmctl(shmid, IPC_RMID, NULL); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_ipc_container_005.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_ipc_container_005.cpp new file mode 100644 index 00000000..8f65f4c7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_ipc_container_005.cpp @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" +using namespace std; + +static const char testBuf[] = "test shm"; +struct shared_use_st { + char test[SHM_TEST_DATA_SIZE]; +}; + +static int childFunc(void *arg) +{ + struct shared_use_st *shared = NULL; + int ret; + (void)arg; + char *containerType = "ipc"; + auto linkBuffer = ReadlinkContainer(getpid(), containerType); + + ret = unshare(CLONE_NEWIPC); + if (ret != 0) { + return EXIT_CODE_ERRNO_1; + } + + auto linkBuffer1 = ReadlinkContainer(getpid(), containerType); + ret = linkBuffer.compare(linkBuffer1); + if (ret == 0) { + return EXIT_CODE_ERRNO_2; + } + + int shmid = shmget((key_t)SHM_TEST_KEY1, sizeof(struct shared_use_st), SHM_TEST_OPEN_PERM | IPC_CREAT); + if (shmid == -1) { + return EXIT_CODE_ERRNO_3; + } + + void *shm = shmat(shmid, 0, 0); + if (shm == reinterpret_cast(-1)) { + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_4; + } + + shared = (struct shared_use_st *)shm; + ret = strncmp(shared->test, testBuf, strlen(testBuf)); + if (ret == 0) { + shmdt(shm); + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_5; + } + + ret = shmdt(shm); + if (ret == -1) { + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_6; + } + + ret = shmctl(shmid, IPC_RMID, 0); + if (ret == -1) { + return EXIT_CODE_ERRNO_7; + } + return 0; +} + +static int testChild(void *arg) +{ + (void)arg; + int ret; + struct shared_use_st *shared = NULL; + int status; + int exitCode; + int pid; + + char *stack = (char *)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, + -1, 0); + if (stack == nullptr) { + return EXIT_CODE_ERRNO_17; + } + char *stackTop = stack + STACK_SIZE; + + int shmid = shmget((key_t)SHM_TEST_KEY1, sizeof(struct shared_use_st), SHM_TEST_OPEN_PERM | IPC_CREAT); + if (shmid == -1) { + return EXIT_CODE_ERRNO_8; + } + + void *shm = shmat(shmid, 0, 0); + if (shm == reinterpret_cast(-1)) { + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_9; + } + + shared = (struct shared_use_st *)shm; + ret = memcpy_s(shared->test, sizeof(struct shared_use_st), testBuf, sizeof(testBuf)); + if (ret != 0) { + shmdt(shm); + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_10; + } + + pid = clone(childFunc, stackTop, SIGCHLD, &arg); + if (pid == -1) { + shmdt(shm); + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_11; + } + + ret = waitpid(pid, &status, 0); + if (ret != pid) { + shmdt(shm); + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_12; + } + + ret = WIFEXITED(status); + if (ret == 0) { + shmdt(shm); + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_13; + } + + exitCode = WEXITSTATUS(status); + if (exitCode != 0) { + shmdt(shm); + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_14; + } + + ret = shmdt(shm); + if (ret == -1) { + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_15; + } + + ret = shmctl(shmid, IPC_RMID, 0); + if (ret == -1) { + return EXIT_CODE_ERRNO_16; + } + return 0; +} + +void ItIpcContainer005(void) +{ + int ret; + int status; + char *stack = (char *)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, + -1, 0); + ASSERT_NE(stack, nullptr); + + char *stackTop = stack + STACK_SIZE; + + int arg = CHILD_FUNC_ARG; + auto pid = clone(testChild, stackTop, CLONE_NEWIPC | SIGCHLD, &arg); + ASSERT_NE(pid, -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_ipc_container_006.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_ipc_container_006.cpp new file mode 100644 index 00000000..d8524513 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_ipc_container_006.cpp @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" +using namespace std; + +static const char testBuf[] = "test shm"; +static const char *containerType = "ipc"; +struct shared_use_st { + char test[SHM_TEST_DATA_SIZE]; +}; + +static int childFunc1(void *arg) +{ + struct shared_use_st *shared = NULL; + int ret; + (void)arg; + const int sleep_num = 3; /* 3: delay */ + + int shmid = shmget((key_t)SHM_TEST_KEY1, sizeof(struct shared_use_st), SHM_TEST_OPEN_PERM | IPC_CREAT); + if (shmid == -1) { + return EXIT_CODE_ERRNO_1; + } + + void *shm = shmat(shmid, 0, 0); + if (shm == reinterpret_cast(-1)) { + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_2; + } + shared = (struct shared_use_st *)shm; + sleep(sleep_num); + ret = strncmp(shared->test, testBuf, strlen(testBuf)); + if (ret != 0) { + shmdt(shm); + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_3; + } + + ret = shmdt(shm); + if (ret == -1) { + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_4; + } + return 0; +} + +static int childFunc(void *arg) +{ + struct shared_use_st *shared = NULL; + int ret; + (void)arg; + int status; + int exitCode; + const int sleep_num = 1; + auto linkBuffer = ReadlinkContainer(getpid(), containerType); + char *stack = (char *)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, + -1, 0); + if (stack == nullptr) { + return EXIT_CODE_ERRNO_17; + } + char *stackTop = stack + STACK_SIZE; + + auto pid = clone(childFunc1, stackTop, CLONE_NEWIPC | SIGCHLD, &arg); + if (pid == -1) { + return EXIT_CODE_ERRNO_6; + } + + std::string filePath = GenContainerLinkPath(pid, containerType); + int fd = open(filePath.c_str(), O_RDONLY); + if (fd == -1) { + return EXIT_CODE_ERRNO_7; + } + sleep(sleep_num); + ret = setns(fd, CLONE_NEWIPC); + if (ret == -1) { + close(fd); + return EXIT_CODE_ERRNO_8; + } + close(fd); + auto linkBuffer1 = ReadlinkContainer(getpid(), containerType); + auto linkBuffer2 = ReadlinkContainer(pid, containerType); + ret = linkBuffer.compare(linkBuffer1); + if (ret == 0) { + return EXIT_CODE_ERRNO_9; + } + ret = linkBuffer1.compare(linkBuffer2); + if (ret != 0) { + return EXIT_CODE_ERRNO_10; + } + + int shmid = shmget((key_t)SHM_TEST_KEY1, sizeof(struct shared_use_st), SHM_TEST_OPEN_PERM | IPC_CREAT); + if (shmid == -1) { + return EXIT_CODE_ERRNO_11; + } + + void *shm = shmat(shmid, 0, 0); + if (shm == reinterpret_cast(-1)) { + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_12; + } + + shared = (struct shared_use_st *)shm; + + ret = memcpy_s(shared->test, sizeof(struct shared_use_st), testBuf, sizeof(testBuf)); + if (ret != 0) { + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_13; + } + + ret = waitpid(pid, &status, 0); + if (ret != pid) { + shmdt(shm); + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_14; + } + + exitCode = WEXITSTATUS(status); + if (exitCode != 0) { + shmdt(shm); + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_15; + } + + ret = shmdt(shm); + if (ret == -1) { + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_16; + } + + ret = shmctl(shmid, IPC_RMID, 0); + if (ret == -1) { + return EXIT_CODE_ERRNO_255; + } + return 0; +} + +void ItIpcContainer006(void) +{ + int ret; + int status; + char *stack = (char *)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, + -1, 0); + ASSERT_NE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + + int arg = CHILD_FUNC_ARG; + auto pid = clone(childFunc, stackTop, CLONE_NEWIPC | SIGCHLD, &arg); + ASSERT_NE(pid, -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_ipc_container_007.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_ipc_container_007.cpp new file mode 100644 index 00000000..76e3f114 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_ipc_container_007.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "It_container_test.h" + +static int const configLen = 16; +static const int MAX_CONTAINER = 10; +static const int g_buffSize = 512; +static const int g_arryLen = 4; +static const int g_readLen = 254; + +static int childFunc(void *arg) +{ + (void)arg; + sleep(2); /* 2: delay 2s */ + + return 0; +} + +void ItIpcContainer007(void) +{ + std::string path = "/proc/sys/user/max_ipc_container"; + char *array[g_arryLen] = { nullptr }; + char buf[g_buffSize] = { 0 }; + + int ret = ReadFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + GetLine(buf, g_arryLen, g_readLen, array); + + int value = atoi(array[1] + strlen("limit: ")); + ASSERT_EQ(value, MAX_CONTAINER); + + int usedCount = atoi(array[2] + strlen("count: ")); + + (void)memset_s(buf, configLen, 0, configLen); + ret = sprintf_s(buf, configLen, "%d", usedCount + 1); + ASSERT_GT(ret, 0); + + ret = WriteFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, + -1, 0); + ASSERT_NE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + + auto pid1 = clone(childFunc, stackTop, CLONE_NEWIPC, NULL); + ASSERT_NE(pid1, -1); + + auto pid2 = clone(childFunc, stackTop, CLONE_NEWIPC, NULL); + ASSERT_EQ(pid2, -1); + + ret = waitpid(pid1, NULL, 0); + ASSERT_EQ(ret, pid1); + + (void)memset_s(buf, configLen, 0, configLen); + ret = sprintf_s(buf, configLen, "%d", value); + ASSERT_GT(ret, 0); + + ret = WriteFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + (void)memset_s(buf, configLen, 0, configLen); + ret = ReadFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + GetLine(buf, g_arryLen, g_readLen, array); + + value = atoi(array[1] + strlen("limit: ")); + ASSERT_EQ(value, MAX_CONTAINER); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_ipc_container_008.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_ipc_container_008.cpp new file mode 100644 index 00000000..27b08583 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_ipc_container_008.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "It_container_test.h" + +static int const configLen = 16; +static const int MAX_CONTAINER = 10; +static const int g_buffSize = 512; +static const int g_arryLen = 4; +static const int g_readLen = 254; + +static int childFunc(void *arg) +{ + (void)arg; + + int ret = unshare(CLONE_NEWIPC); + if (ret != 0) { + return EXIT_CODE_ERRNO_1; + } + return 0; +} + +void ItIpcContainer008(void) +{ + std::string path = "/proc/sys/user/max_ipc_container"; + char *array[g_arryLen] = { nullptr }; + char buf[g_buffSize] = { 0 }; + int status = 0; + + int ret = ReadFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + GetLine(buf, g_arryLen, g_readLen, array); + + int value = atoi(array[1] + strlen("limit: ")); + ASSERT_EQ(value, MAX_CONTAINER); + + int usedCount = atoi(array[2] + strlen("count: ")); + + (void)memset_s(buf, configLen, 0, configLen); + ret = sprintf_s(buf, configLen, "%d", usedCount + 1); + ASSERT_GT(ret, 0); + + ret = WriteFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, + -1, 0); + ASSERT_NE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + + auto pid1 = clone(childFunc, stackTop, CLONE_NEWIPC, NULL); + ASSERT_NE(pid1, -1); + + ret = waitpid(pid1, &status, 0); + ASSERT_EQ(ret, pid1); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, EXIT_CODE_ERRNO_1); + + (void)memset_s(buf, configLen, 0, configLen); + ret = sprintf_s(buf, configLen, "%d", value); + ASSERT_GT(ret, 0); + + ret = WriteFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + (void)memset_s(buf, configLen, 0, configLen); + ret = ReadFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + GetLine(buf, g_arryLen, g_readLen, array); + + value = atoi(array[1] + strlen("limit: ")); + ASSERT_EQ(value, MAX_CONTAINER); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_mnt_container_001.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_mnt_container_001.cpp new file mode 100644 index 00000000..2cc9d390 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_mnt_container_001.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" +#include "sys/mount.h" + +static int ChildFunc(void *arg) +{ + int ret; + int value = *((int *)arg); + + if (value != CHILD_FUNC_ARG) { + return EXIT_CODE_ERRNO_1; + } + + ret = access(ACCESS_FILE_NAME, F_OK); + if (ret != 0) { + return EXIT_CODE_ERRNO_2; + } + + ret = umount(USERDATA_DIR_NAME); + if (ret != 0) { + return EXIT_CODE_ERRNO_3; + } + + ret = access(ACCESS_FILE_NAME, F_OK); + if (ret == 0) { + return EXIT_CODE_ERRNO_4; + } + + return 0; +} + +/* mount container clone test: mount in parent, clone without NEW_NS, umount in child */ +void ItMntContainer001(void) +{ + int ret; + int status = 0; + int childReturn = 0; + int arg = CHILD_FUNC_ARG; + char *stack = nullptr; + char *stackTop = nullptr; + + stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); + ASSERT_NE(stack, MAP_FAILED); + + ret = access(ACCESS_FILE_NAME, F_OK); + ASSERT_EQ(ret, 0); + + stackTop = stack + STACK_SIZE; + auto pid = clone(ChildFunc, stackTop, 0, &arg); + ASSERT_NE(pid, -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); + + ret = access(ACCESS_FILE_NAME, F_OK); + ASSERT_NE(ret, 0); + + ret = mount(USERDATA_DEV_NAME, USERDATA_DIR_NAME, FS_TYPE, 0, nullptr); + ASSERT_EQ(ret, 0); + + ret = access(ACCESS_FILE_NAME, F_OK); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_mnt_container_002.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_mnt_container_002.cpp new file mode 100644 index 00000000..fc6c30bd --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_mnt_container_002.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" +#include "sys/mount.h" + +static int ChildFunc(void *arg) +{ + int ret; + int value = *((int *)arg); + + if (value != CHILD_FUNC_ARG) { + return EXIT_CODE_ERRNO_1; + } + + ret = access(ACCESS_FILE_NAME, F_OK); + if (ret != 0) { + return EXIT_CODE_ERRNO_2; + } + + ret = umount(USERDATA_DIR_NAME); + if (ret != 0) { + return EXIT_CODE_ERRNO_3; + } + + ret = access(ACCESS_FILE_NAME, F_OK); + if (ret == 0) { + return EXIT_CODE_ERRNO_4; + } + + ret = mount(USERDATA_DEV_NAME, USERDATA_DIR_NAME, FS_TYPE, 0, nullptr); + if (ret != 0) { + return EXIT_CODE_ERRNO_5; + } + + ret = umount(USERDATA_DIR_NAME); + if (ret != 0) { + return EXIT_CODE_ERRNO_6; + } + + return 0; +} + +/* mount container clone test: mount in parent, clone with NEW_NS, umount in child */ +void ItMntContainer002(void) +{ + int ret; + int status = 0; + int childReturn = 0; + int arg = CHILD_FUNC_ARG; + char *stack = nullptr; + char *stackTop = nullptr; + + stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); + ASSERT_NE(stack, MAP_FAILED); + + ret = access(ACCESS_FILE_NAME, F_OK); + ASSERT_EQ(ret, 0); + + stackTop = stack + STACK_SIZE; + auto pid = clone(ChildFunc, stackTop, CLONE_NEWNS, &arg); + ASSERT_NE(pid, -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); + + ret = access(ACCESS_FILE_NAME, F_OK); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_mnt_container_003.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_mnt_container_003.cpp new file mode 100644 index 00000000..bc3a9f0b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_mnt_container_003.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" +#include "sys/mount.h" + +static int ChildFunc(void *arg) +{ + int ret; + int value = *((int *)arg); + + if (value != CHILD_FUNC_ARG) { + return EXIT_CODE_ERRNO_1; + } + + ret = mount(USERDATA_DEV_NAME, USERDATA_DIR_NAME, FS_TYPE, 0, nullptr); + if (ret != 0) { + return EXIT_CODE_ERRNO_2; + } + + ret = access(ACCESS_FILE_NAME, F_OK); + if (ret != 0) { + return EXIT_CODE_ERRNO_3; + } + + return 0; +} + +/* mount container clone test: clone without NEW_NS, mount in child */ +void ItMntContainer003(void) +{ + int ret; + int status = 0; + int childReturn = 0; + int arg = CHILD_FUNC_ARG; + char *stack = nullptr; + char *stackTop = nullptr; + + stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); + ASSERT_NE(stack, MAP_FAILED); + + ret = umount(USERDATA_DIR_NAME); + ASSERT_EQ(ret, 0); + + stackTop = stack + STACK_SIZE; + auto pid = clone(ChildFunc, stackTop, 0, &arg); + ASSERT_NE(pid, -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); + + ret = access(ACCESS_FILE_NAME, F_OK); + ASSERT_EQ(ret, 0); + + ret = mount(USERDATA_DEV_NAME, USERDATA_DIR_NAME, FS_TYPE, 0, nullptr); + ASSERT_NE(ret, 0); + + ret = umount(USERDATA_DIR_NAME); + ASSERT_EQ(ret, 0); + + ret = mount(USERDATA_DEV_NAME, USERDATA_DIR_NAME, FS_TYPE, 0, nullptr); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_mnt_container_004.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_mnt_container_004.cpp new file mode 100644 index 00000000..98c02220 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_mnt_container_004.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" +#include "sys/mount.h" + +static int ChildFunc(void *arg) +{ + int ret; + int value = *((int *)arg); + if (value != CHILD_FUNC_ARG) { + return EXIT_CODE_ERRNO_1; + } + + ret = mount(USERDATA_DEV_NAME, USERDATA_DIR_NAME, FS_TYPE, 0, nullptr); + if (ret != 0) { + return EXIT_CODE_ERRNO_2; + } + + ret = access(ACCESS_FILE_NAME, F_OK); + if (ret != 0) { + return EXIT_CODE_ERRNO_3; + } + + return 0; +} + +/* mount container clone test: clone with NEW_NS, mount in child */ +void ItMntContainer004(void) +{ + int ret; + int status = 0; + int childReturn = 0; + int arg = CHILD_FUNC_ARG; + char *stack = nullptr; + char *stackTop = nullptr; + + stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); + ASSERT_NE(stack, MAP_FAILED); + + ret = umount(USERDATA_DIR_NAME); + ASSERT_EQ(ret, 0); + + stackTop = stack + STACK_SIZE; + auto pid = clone(ChildFunc, stackTop, CLONE_NEWNS, &arg); + ASSERT_NE(pid, -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); + + ret = access(ACCESS_FILE_NAME, F_OK); + ASSERT_NE(ret, 0); + + ret = umount(USERDATA_DIR_NAME); + ASSERT_NE(ret, 0); + + ret = mount(USERDATA_DEV_NAME, USERDATA_DIR_NAME, FS_TYPE, 0, nullptr); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_mnt_container_005.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_mnt_container_005.cpp new file mode 100644 index 00000000..524617fe --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_mnt_container_005.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +/* + * mount container unshare test: unshare in current pcb with NEW_NS + */ +static void MntContainerUnshare(void) +{ + int ret; + + ret = access(ACCESS_FILE_NAME, F_OK); + ASSERT_EQ(ret, 0); + + ret = unshare(CLONE_NEWNS); + ASSERT_EQ(ret, 0); + + ret = access(ACCESS_FILE_NAME, F_OK); + ASSERT_EQ(ret, 0); + + ret = umount(USERDATA_DIR_NAME); + ASSERT_EQ(ret, 0); + + ret = access(ACCESS_FILE_NAME, F_OK); + ASSERT_NE(ret, 0); + + ret = mount(USERDATA_DEV_NAME, USERDATA_DIR_NAME, FS_TYPE, 0, nullptr); + ASSERT_EQ(ret, 0); + + ret = access(ACCESS_FILE_NAME, F_OK); + ASSERT_EQ(ret, 0); + exit(0); +} + +void ItMntContainer005(void) +{ + int status = 0; + auto pid = fork(); + ASSERT_TRUE(pid != -1); + if (pid == 0) { + MntContainerUnshare(); + exit(EXIT_CODE_ERRNO_1); + } + auto ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_mnt_container_006.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_mnt_container_006.cpp new file mode 100644 index 00000000..6de07377 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_mnt_container_006.cpp @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" +#include "sys/mount.h" + +static int ChildFunc(void *arg) +{ + int ret; + int value = *((int *)arg); + if (value != CHILD_FUNC_ARG) { + return EXIT_CODE_ERRNO_1; + } + + ret = access(ACCESS_FILE_NAME, F_OK); + if (ret != 0) { + return EXIT_CODE_ERRNO_2; + } + + ret = unshare(CLONE_NEWNS); + if (ret != 0) { + return EXIT_CODE_ERRNO_3; + } + + ret = access(ACCESS_FILE_NAME, F_OK); + if (ret != 0) { + return EXIT_CODE_ERRNO_4; + } + + ret = umount(USERDATA_DIR_NAME); + if (ret != 0) { + return EXIT_CODE_ERRNO_5; + } + + ret = access(ACCESS_FILE_NAME, F_OK); + if (ret == 0) { + return EXIT_CODE_ERRNO_6; + } + + return 0; +} + +/* + * mount container unshare test: mount in parent, child clone without NEW_NS, + * unshare in child with NEW_NS, umount in child. + */ +void ItMntContainer006(void) +{ + int ret; + int status = 0; + int childReturn = 0; + int arg = CHILD_FUNC_ARG; + char *stack = nullptr; + char *stackTop = nullptr; + + stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); + ASSERT_NE(stack, MAP_FAILED); + + stackTop = stack + STACK_SIZE; + ret = access(ACCESS_FILE_NAME, F_OK); + ASSERT_EQ(ret, 0); + + auto pid = clone(ChildFunc, stackTop, 0, &arg); + ASSERT_NE(pid, -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); + + ret = access(ACCESS_FILE_NAME, F_OK); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_mnt_container_007.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_mnt_container_007.cpp new file mode 100644 index 00000000..1b5cf5cb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_mnt_container_007.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" +#include "sys/mount.h" + +static int ChildFunc(void *arg) +{ + int ret; + int value = *((int *)arg); + + if (value != CHILD_FUNC_ARG) { + return EXIT_CODE_ERRNO_1; + } + + ret = unshare(CLONE_NEWNS); + if (ret != 0) { + return EXIT_CODE_ERRNO_2; + } + + ret = mount(USERDATA_DEV_NAME, USERDATA_DIR_NAME, FS_TYPE, 0, nullptr); + if (ret != 0) { + return EXIT_CODE_ERRNO_2; + } + + ret = access(ACCESS_FILE_NAME, F_OK); + if (ret != 0) { + return EXIT_CODE_ERRNO_2; + } + + return 0; +} + +/* + * mount container unshare test: child clone without NEW_NS, + * unshare in child with NEW_NS, umount in child + */ +void ItMntContainer007(void) +{ + int ret; + int status = 0; + int childReturn = 0; + int arg = CHILD_FUNC_ARG; + char *stack = nullptr; + char *stackTop = nullptr; + + stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); + ASSERT_NE(stack, MAP_FAILED); + + ret = umount(USERDATA_DIR_NAME); + ASSERT_EQ(ret, 0); + + stackTop = stack + STACK_SIZE; + auto pid = clone(ChildFunc, stackTop, 0, &arg); + ASSERT_NE(pid, -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); + + ret = access(ACCESS_FILE_NAME, F_OK); + ASSERT_NE(ret, 0); + + ret = umount(USERDATA_DIR_NAME); + ASSERT_NE(ret, 0); + + ret = mount(USERDATA_DEV_NAME, USERDATA_DIR_NAME, FS_TYPE, 0, nullptr); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_mnt_container_008.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_mnt_container_008.cpp new file mode 100644 index 00000000..c4d9855b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_mnt_container_008.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +const int CHILD_FUNC_EXITCODE = 3; +const int PATH_LENGTH = 100; + +static int ChildFun(void *p) +{ + (void)p; + const int sleepSecond = 2; + (void)getpid(); + (void)sleep(sleepSecond); + return CHILD_FUNC_EXITCODE; +} + +void ItMntContainer008(void) +{ + pid_t parentPid; + int childPid; + void *pstk = nullptr; + int fd; + int ret; + int status; + char targetpath[PATH_LENGTH]; + char old_mnt_link[PATH_LENGTH]; + char new_mnt_link[PATH_LENGTH]; + std::string containerType = "mnt"; + int setFlag = CLONE_NEWNS; + + parentPid = getpid(); + pstk = malloc(STACK_SIZE); + ASSERT_NE(pstk, nullptr); + + childPid = clone(ChildFun, (char *)pstk + STACK_SIZE, CLONE_NEWNS, nullptr); + ASSERT_NE(childPid, -1); + + auto linkBuffer = ReadlinkContainer(parentPid, containerType.c_str()); + ret = sprintf_s(old_mnt_link, PATH_LENGTH, "%s", linkBuffer.c_str()); + ASSERT_GT(ret, 0); + ret = sprintf_s(targetpath, PATH_LENGTH, "/proc/%d/container/mnt", childPid); + ASSERT_GT(ret, 0); + fd = open(targetpath, O_RDONLY | O_CLOEXEC); + ASSERT_NE(fd, -1); + + ret = setns(fd, setFlag); + ASSERT_EQ(ret, 0); + + ret = close(fd); + ASSERT_EQ(ret, 0); + + linkBuffer = ReadlinkContainer(parentPid, containerType.c_str()); + + ret = sprintf_s(new_mnt_link, PATH_LENGTH, "%s", linkBuffer.c_str()); + ASSERT_GT(ret, 0); + ASSERT_STRNE(old_mnt_link, new_mnt_link); + + ret = waitpid(childPid, &status, 0); + ASSERT_EQ(ret, childPid); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, CHILD_FUNC_EXITCODE); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_mnt_container_009.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_mnt_container_009.cpp new file mode 100644 index 00000000..3df5c82d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_mnt_container_009.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "It_container_test.h" + +static int const configLen = 16; +static const int MAX_CONTAINER = 10; +static const int g_buffSize = 512; +static const int g_arryLen = 4; +static const int g_readLen = 254; + +static int childFunc(void *arg) +{ + (void)arg; + sleep(2); /* 2: delay 2s */ + + return 0; +} + +void ItMntContainer009(void) +{ + std::string path = "/proc/sys/user/max_mnt_container"; + char *array[g_arryLen] = { nullptr }; + char buf[g_buffSize] = { 0 }; + + int ret = ReadFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + GetLine(buf, g_arryLen, g_readLen, array); + + int value = atoi(array[1] + strlen("limit: ")); + ASSERT_EQ(value, MAX_CONTAINER); + + int usedCount = atoi(array[2] + strlen("count: ")); + + (void)memset_s(buf, configLen, 0, configLen); + ret = sprintf_s(buf, configLen, "%d", usedCount + 1); + ASSERT_GT(ret, 0); + + ret = WriteFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, + -1, 0); + ASSERT_NE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + + auto pid1 = clone(childFunc, stackTop, CLONE_NEWNS, NULL); + ASSERT_NE(pid1, -1); + + auto pid2 = clone(childFunc, stackTop, CLONE_NEWNS, NULL); + ASSERT_EQ(pid2, -1); + + ret = waitpid(pid1, NULL, 0); + ASSERT_EQ(ret, pid1); + + (void)memset_s(buf, configLen, 0, configLen); + ret = sprintf_s(buf, configLen, "%d", value); + ASSERT_GT(ret, 0); + + ret = WriteFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + (void)memset_s(buf, configLen, 0, configLen); + ret = ReadFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + GetLine(buf, g_arryLen, g_readLen, array); + + value = atoi(array[1] + strlen("limit: ")); + ASSERT_EQ(value, MAX_CONTAINER); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_mnt_container_010.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_mnt_container_010.cpp new file mode 100644 index 00000000..ebcf3a90 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_mnt_container_010.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "It_container_test.h" + +static int const configLen = 16; +static const int MAX_CONTAINER = 10; +static const int g_buffSize = 512; +static const int g_arryLen = 4; +static const int g_readLen = 254; + +static int childFunc(void *arg) +{ + (void)arg; + + int ret = unshare(CLONE_NEWNS); + if (ret != 0) { + return EXIT_CODE_ERRNO_1; + } + return 0; +} + +void ItMntContainer010(void) +{ + std::string path = "/proc/sys/user/max_mnt_container"; + char *array[g_arryLen] = { nullptr }; + char buf[g_buffSize] = { 0 }; + int status = 0; + + int ret = ReadFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + GetLine(buf, g_arryLen, g_readLen, array); + + int value = atoi(array[1] + strlen("limit: ")); + ASSERT_EQ(value, MAX_CONTAINER); + + int usedCount = atoi(array[2] + strlen("count: ")); + + (void)memset_s(buf, configLen, 0, configLen); + ret = sprintf_s(buf, configLen, "%d", usedCount + 1); + ASSERT_GT(ret, 0); + + ret = WriteFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, + -1, 0); + ASSERT_NE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + + auto pid1 = clone(childFunc, stackTop, CLONE_NEWNS, NULL); + ASSERT_NE(pid1, -1); + + ret = waitpid(pid1, &status, 0); + ASSERT_EQ(ret, pid1); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, EXIT_CODE_ERRNO_1); + + (void)memset_s(buf, configLen, 0, configLen); + ret = sprintf_s(buf, configLen, "%d", value); + ASSERT_GT(ret, 0); + + ret = WriteFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + (void)memset_s(buf, configLen, 0, configLen); + ret = ReadFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + GetLine(buf, g_arryLen, g_readLen, array); + + value = atoi(array[1] + strlen("limit: ")); + ASSERT_EQ(value, MAX_CONTAINER); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_001.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_001.cpp new file mode 100644 index 00000000..e6d79516 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_001.cpp @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include "It_container_test.h" + +using namespace std; +static const int IpLen = 16; +static const char *NETMASK = "255.255.255.0"; +static const char *GW = "192.168.100.1"; +static const char *IFNAME = "veth0"; +static const char *PEER_IP = "192.168.100.5"; + +static int SetIP(char *ip) +{ + struct ifreq ifr; + int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); + if (fd < 0) { + return -1; + } + int ret = strncpy_s(ifr.ifr_name, sizeof(ifr.ifr_name), "eth0", IFNAMSIZ); + if (ret != EOK) { + (void)close(fd); + return -1; + } + ifr.ifr_addr.sa_family = AF_INET; + inet_pton(AF_INET, ip, ifr.ifr_addr.sa_data + 2); /* 2: offset */ + ret = ioctl(fd, SIOCSIFADDR, &ifr); + if (ret != 0) { + (void)close(fd); + printf("[ERR][%s:%d] ioctl SIOCSIFADDR failed, %s!\n", __FUNCTION__, __LINE__, strerror(errno)); + return -1; + } + + ret = close(fd); + if (ret != 0) { + return -1; + } + return 0; +} + +static int ChildFunc(void *arg) +{ + (void)arg; + int ret; + char oldIp[IpLen] = {NULL}; + char newIp[IpLen] = {NULL}; + + ret = NetContainerGetLocalIP("eth0", oldIp, IpLen); + if (ret == 0) { + return EXIT_CODE_ERRNO_1; + } + + ret = SetIP("192.168.1.233"); + if (ret == 0) { + return EXIT_CODE_ERRNO_2; + } + + ret = NetContainerResetNetAddr(IFNAME, PEER_IP, NETMASK, GW); + if (ret != 0) { + return EXIT_CODE_ERRNO_3; + } + + (void)memset_s(newIp, IpLen, 0, IpLen); + ret = NetContainerGetLocalIP(IFNAME, newIp, IpLen); + if (ret != 0) { + return EXIT_CODE_ERRNO_4; + } + + if (strcmp(PEER_IP, newIp) != 0) { + return EXIT_CODE_ERRNO_5; + } + printf("######## [%s:%d] %s: %s ########\n", __FUNCTION__, __LINE__, IFNAME, newIp); + return 0; +} + +void ItNetContainer001(void) +{ + int ret; + char oldIp[IpLen] = {NULL}; + char newIp[IpLen] = {NULL}; + + char *stack = (char *)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0); + EXPECT_STRNE(stack, NULL); + char *stackTop = stack + STACK_SIZE; + + ret = NetContainerGetLocalIP("eth0", oldIp, IpLen); + ASSERT_EQ(ret, 0); + + auto pid = clone(ChildFunc, stackTop, SIGCHLD | CLONE_NEWNET, NULL); + ASSERT_NE(pid, -1); + + int status; + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); + + ret = NetContainerGetLocalIP("eth0", newIp, IpLen); + ASSERT_EQ(ret, 0); + + ret = strcmp(oldIp, newIp); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_002.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_002.cpp new file mode 100644 index 00000000..1771d8f8 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_002.cpp @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include "It_container_test.h" + +using namespace std; +static const int IpLen = 16; +static const char *NETMASK = "255.255.255.0"; +static const char *GW = "192.168.100.1"; +static const char *IFNAME = "veth0"; +static const char *PEER_IP = "192.168.100.5"; + +static int SetIP(char *ip) +{ + struct ifreq ifr; + int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); + if (fd < 0) { + return -1; + } + int ret = strncpy_s(ifr.ifr_name, sizeof(ifr.ifr_name), "eth0", IFNAMSIZ); + if (ret != EOK) { + (void)close(fd); + return -1; + } + ifr.ifr_addr.sa_family = AF_INET; + inet_pton(AF_INET, ip, ifr.ifr_addr.sa_data + 2); /* 2: offset */ + ret = ioctl(fd, SIOCSIFADDR, &ifr); + if (ret != 0) { + printf("[ERR][%s:%d] ioctl SIOCSIFADDR failed, %s!\n", __FUNCTION__, __LINE__, strerror(errno)); + (void)close(fd); + return -1; + } + ret = close(fd); + if (ret != 0) { + return -1; + } + return 0; +} + +static int ChildFunc(void *arg) +{ + (void)arg; + int ret; + char oldIp[IpLen] = {NULL}; + char newIp[IpLen] = {NULL}; + + ret = NetContainerGetLocalIP("eth0", oldIp, IpLen); + if (ret != 0) { + return EXIT_CODE_ERRNO_1; + } + + ret = unshare(CLONE_NEWNET); + if (ret < 0) { + return EXIT_CODE_ERRNO_2; + } + + ret = NetContainerGetLocalIP("eth0", newIp, IpLen); + if (ret == 0) { + return EXIT_CODE_ERRNO_3; + } + + ret = SetIP("192.168.1.234"); + if (ret == 0) { + return EXIT_CODE_ERRNO_4; + } + + ret = NetContainerResetNetAddr(IFNAME, PEER_IP, NETMASK, GW); + if (ret != 0) { + return EXIT_CODE_ERRNO_5; + } + + (void)memset_s(newIp, IpLen, 0, IpLen); + ret = NetContainerGetLocalIP(IFNAME, newIp, IpLen); + if (ret != 0) { + return EXIT_CODE_ERRNO_6; + } + + if (strcmp(PEER_IP, newIp) != 0) { + return EXIT_CODE_ERRNO_7; + } + printf("######## [%s:%d] %s: %s ########\n", __FUNCTION__, __LINE__, IFNAME, newIp); + return 0; +} + +void ItNetContainer002(void) +{ + int ret; + char oldIp[IpLen] = {NULL}; + char newIp[IpLen] = {NULL}; + + char *stack = (char *)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0); + EXPECT_STRNE(stack, NULL); + char *stackTop = stack + STACK_SIZE; + + ret = NetContainerGetLocalIP("eth0", oldIp, IpLen); + ASSERT_EQ(ret, 0); + + auto pid = clone(ChildFunc, stackTop, SIGCHLD, NULL); + ASSERT_NE(pid, -1); + + int status; + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); + + ret = NetContainerGetLocalIP("eth0", newIp, IpLen); + ASSERT_EQ(ret, 0); + + ret = strcmp(oldIp, newIp); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_003.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_003.cpp new file mode 100644 index 00000000..422a4d34 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_003.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include "It_container_test.h" + +static std::string GenNetLinkPath(int pid) +{ + std::ostringstream buf; + buf << "/proc/" << pid << "/container/net"; + return buf.str(); +} + +static std::string ReadlinkNet(int pid) +{ + auto path = GenNetLinkPath(pid); + struct stat sb; + + int ret = lstat(path.data(), &sb); + if (ret == -1) { + perror("lstat"); + return std::string(); + } + + auto bufsiz = sb.st_size + 1; + if (sb.st_size == 0) { + bufsiz = PATH_MAX; + } + + std::vector buf(bufsiz); + auto nbytes = readlink(path.c_str(), buf.data(), bufsiz); + if (nbytes == -1) { + perror("readlink"); + return std::string(); + } + + return buf.data(); +} + +void ItNetContainer003(void) +{ + std::string zerolink("'net:[0]'"); + auto netlink = ReadlinkNet(getpid()); + int ret = zerolink.compare(netlink); + ASSERT_NE(ret, 0); + + std::regex reg("'net:\\[[0-9]+\\]'"); + ret = std::regex_match(netlink, reg); + ASSERT_EQ(ret, 1); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_004.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_004.cpp new file mode 100644 index 00000000..63b083ac --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_004.cpp @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include "It_container_test.h" + +static const char *CONTAINER_TYPE = "net"; +static const int SLEEP_SECONDS = 2; +static const int TEST_PATH_MAX = 100; + +static int NewnetChildFun(void *) +{ + sleep(SLEEP_SECONDS); + return 0; +} + +static int ChildFun(void *p) +{ + (void)p; + int ret; + int status; + char path[TEST_PATH_MAX]; + + char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0); + EXPECT_STRNE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + int arg = CHILD_FUNC_ARG; + auto childPid = clone(NewnetChildFun, stackTop, SIGCHLD | CLONE_NEWNET, &arg); + if (childPid == -1) { + return EXIT_CODE_ERRNO_1; + } + auto oldReadLink = ReadlinkContainer(getpid(), CONTAINER_TYPE); + + if (sprintf_s(path, TEST_PATH_MAX, "/proc/%d/container/net", childPid) < 0) { + (void)waitpid(childPid, &status, 0); + return EXIT_CODE_ERRNO_8; + } + int fd = open(path, O_RDONLY | O_CLOEXEC); + if (fd < 0) { + return EXIT_CODE_ERRNO_2; + } + + ret = setns(fd, CLONE_NEWNET); + if (ret != 0) { + (void)close(fd); + return EXIT_CODE_ERRNO_3; + } + + ret = close(fd); + if (ret != 0) { + return EXIT_CODE_ERRNO_4; + } + + auto newReadLink = ReadlinkContainer(getpid(), CONTAINER_TYPE); + + ret = strcmp(oldReadLink.c_str(), newReadLink.c_str()); + if (ret == 0) { + return EXIT_CODE_ERRNO_5; + } + + ret = waitpid(childPid, &status, 0); + if (ret != childPid) { + return EXIT_CODE_ERRNO_6; + } + + int exitCode = WEXITSTATUS(status); + if (exitCode != 0) { + return EXIT_CODE_ERRNO_7; + } + + return 0; +} + +void ItNetContainer004(void) +{ + int status; + + char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0); + EXPECT_STRNE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + int arg = CHILD_FUNC_ARG; + auto childPid = clone(ChildFun, stackTop, SIGCHLD | CLONE_NEWNET, &arg); + ASSERT_NE(childPid, -1); + + int ret = waitpid(childPid, &status, 0); + ASSERT_EQ(ret, childPid); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_005.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_005.cpp new file mode 100644 index 00000000..c35c4389 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_005.cpp @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include "It_container_test.h" + +static const char *NETMASK = "255.255.255.0"; +static const char *GW = "192.168.100.1"; +static const char *IFNAME = "veth0"; +static const char *SERVER_IP = "192.168.100.6"; +static const int SERVER_PORT = 8000; +static const char *PEER_IP = "192.168.100.5"; +static const int PEER_PORT = 8001; +static const int DATA_LEN = 128; +static const char *SERVER_MSG = "===Hi, I'm Server.==="; +static const char *PEER_MSG = "===Hi, I'm Peer.==="; +static const int TRY_COUNT = 5; + +static int UdpClient(void) +{ + int ret = 0; + int peer; + int try_count = TRY_COUNT; + char recv_data[DATA_LEN]; + struct sockaddr_in server_addr; + struct sockaddr_in peer_addr; + + peer = socket(AF_INET, SOCK_DGRAM, 0); + if (peer < 0) { + return EXIT_CODE_ERRNO_1; + } + + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = inet_addr(SERVER_IP); + server_addr.sin_port = htons(SERVER_PORT); + (void)memset_s(&(server_addr.sin_zero), sizeof(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero)); + + peer_addr.sin_family = AF_INET; + peer_addr.sin_addr.s_addr = inet_addr(PEER_IP); + peer_addr.sin_port = htons(PEER_PORT); + (void)memset_s(&(peer_addr.sin_zero), sizeof(peer_addr.sin_zero), 0, sizeof(peer_addr.sin_zero)); + + ret = bind(peer, const_cast(reinterpret_cast(&peer_addr)), + sizeof(struct sockaddr)); + if (ret != 0) { + return EXIT_CODE_ERRNO_2; + } + + timeval tv = {1, 0}; + ret = setsockopt(peer, SOL_SOCKET, SO_RCVTIMEO, const_cast(reinterpret_cast(&tv)), sizeof(timeval)); + + /* loop try util server is ready */ + while (try_count--) { + ret = sendto(peer, PEER_MSG, strlen(PEER_MSG) + 1, 0, + const_cast(reinterpret_cast(&server_addr)), + (socklen_t)sizeof(server_addr)); + if (ret == -1) { + continue; + } + ret = recvfrom(peer, recv_data, DATA_LEN, 0, nullptr, nullptr); + if (ret != -1) { + break; + } + } + if (ret < 0) { + return EXIT_CODE_ERRNO_3; + } + + (void)close(peer); + + ret = strcmp(recv_data, SERVER_MSG); + if (ret != 0) { + return EXIT_CODE_ERRNO_4; + } + + return 0; +} + +static int ChildFunc(void *arg) +{ + int ret = NetContainerResetNetAddr(IFNAME, PEER_IP, NETMASK, GW); + if (ret != 0) { + return EXIT_CODE_ERRNO_1; + } + + return UdpClient(); +} + +static int UdpServer(void) +{ + int ret = 0; + int server; + int try_count = TRY_COUNT; + char recv_data[DATA_LEN]; + struct sockaddr_in server_addr; + struct sockaddr_in peer_addr; + socklen_t peer_addr_len = sizeof(struct sockaddr); + + server = socket(AF_INET, SOCK_DGRAM, 0); + if (server < 0) { + return EXIT_CODE_ERRNO_1; + } + + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = inet_addr(SERVER_IP); + server_addr.sin_port = htons(SERVER_PORT); + (void)memset_s(&(server_addr.sin_zero), sizeof(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero)); + + ret = bind(server, const_cast(reinterpret_cast(&server_addr)), + sizeof(struct sockaddr)); + if (ret != 0) { + return EXIT_CODE_ERRNO_2; + } + + ret = recvfrom(server, recv_data, DATA_LEN, 0, reinterpret_cast(&peer_addr), &peer_addr_len); + if (ret < 0) { + return EXIT_CODE_ERRNO_3; + } + + ret = sendto(server, SERVER_MSG, strlen(SERVER_MSG) + 1, 0, + const_cast(reinterpret_cast(&peer_addr)), peer_addr_len); + if (ret < 0) { + return EXIT_CODE_ERRNO_4; + } + + (void)close(server); + + ret = strcmp(recv_data, PEER_MSG); + if (ret != 0) { + return EXIT_CODE_ERRNO_5; + } + + return ret; +} + +static void *UdpServerThread(void *arg) +{ + int ret = NetContainerResetNetAddr(IFNAME, SERVER_IP, NETMASK, GW); + if (ret != 0) { + return (void *)(intptr_t)ret; + } + + ret = UdpServer(); + + return (void *)(intptr_t)ret; +} + +void ItNetContainer005(void) +{ + int ret = 0; + int status; + void *tret = nullptr; + pthread_t srv; + pthread_attr_t attr; + + ret = pthread_attr_init(&attr); + ASSERT_EQ(ret, 0); + + ret = pthread_create(&srv, &attr, UdpServerThread, nullptr); + ASSERT_EQ(ret, 0); + + char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0); + EXPECT_STRNE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + + int arg = CHILD_FUNC_ARG; + auto pid = clone(ChildFunc, stackTop, SIGCHLD | CLONE_NEWNET, &arg); + ASSERT_NE(pid, -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); + + ret = pthread_join(srv, &tret); + ASSERT_EQ(ret, 0); + + ret = pthread_attr_destroy(&attr); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_006.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_006.cpp new file mode 100644 index 00000000..f195e505 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_006.cpp @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include "It_container_test.h" + +static const char *SERVER_IP = "127.0.0.1"; +static const int SERV_PORT = 8002; +static const char *SERVER_MSG = "Hi, I'm Tcp Server!"; +static const char *PEER_MSG = "Hi, I'm Tcp Client!"; +static const int DATA_LEN = 128; + +static int TcpClient(void *arg) +{ + int ret; + int client; + char buffer[DATA_LEN]; + struct sockaddr_in server_addr; + + client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (client < 0) { + return EXIT_CODE_ERRNO_1; + } + + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + server_addr.sin_port = htons(SERV_PORT); + (void)memset_s(&(server_addr.sin_zero), sizeof(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero)); + + ret = connect(client, const_cast(reinterpret_cast(&server_addr)), + sizeof(server_addr)); + if (ret < 0) { + return EXIT_CODE_ERRNO_2; + } + + ret = send(client, PEER_MSG, strlen(PEER_MSG) + 1, 0); + if (ret < 0) { + return EXIT_CODE_ERRNO_3; + } + + ret = recv(client, buffer, sizeof(buffer), 0); + if (ret < 0) { + return EXIT_CODE_ERRNO_4; + } + + ret = strcmp(buffer, SERVER_MSG); + if (ret != 0) { + return EXIT_CODE_ERRNO_5; + } + + (void)close(client); + + return 0; +} + +static int ChildFunc(void *) +{ + int ret; + int server; + int status; + char *stack = nullptr; + char *stackTop = nullptr; + char buffer[DATA_LEN]; + struct sockaddr_in server_addr; + + server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (server < 0) { + return EXIT_CODE_ERRNO_1; + } + + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + server_addr.sin_port = htons(SERV_PORT); + (void)memset_s(&(server_addr.sin_zero), sizeof(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero)); + + ret = bind(server, const_cast(reinterpret_cast(&server_addr)), + sizeof(server_addr)); + if (ret < 0) { + return EXIT_CODE_ERRNO_2; + } + + ret = listen(server, 1); + if (ret < 0) { + return EXIT_CODE_ERRNO_3; + } + + stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0); + EXPECT_STRNE(stack, nullptr); + stackTop = stack + STACK_SIZE; + + int arg = CHILD_FUNC_ARG; + int pid = clone(TcpClient, stackTop, SIGCHLD, &arg); + if (pid == -1) { + return EXIT_CODE_ERRNO_4; + } + + int client = accept(server, nullptr, nullptr); + if (ret < 0) { + return EXIT_CODE_ERRNO_5; + } + + ret = recv(client, buffer, sizeof(buffer), 0); + if (ret < 0) { + return EXIT_CODE_ERRNO_6; + } + + ret = strcmp(buffer, PEER_MSG); + if (ret != 0) { + return EXIT_CODE_ERRNO_7; + } + + ret = send(client, SERVER_MSG, strlen(SERVER_MSG) + 1, 0); + if (ret < 0) { + return EXIT_CODE_ERRNO_8; + } + + (void)close(client); + (void)close(server); + + ret = waitpid(pid, &status, 0); + if (ret != pid) { + return EXIT_CODE_ERRNO_9; + } + + int exitCode = WEXITSTATUS(status); + if (exitCode != 0) { + return EXIT_CODE_ERRNO_10; + } + + return 0; +} + +void ItNetContainer006(void) +{ + int ret = 0; + int status; + + char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0); + EXPECT_STRNE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + + int arg = CHILD_FUNC_ARG; + int pid = clone(ChildFunc, stackTop, SIGCHLD | CLONE_NEWNET, &arg); + ASSERT_NE(pid, -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_007.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_007.cpp new file mode 100644 index 00000000..69531868 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_007.cpp @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include "It_container_test.h" + +static const char *LOCALHOST = "127.0.0.1"; +static const int LOCALPORT = 8003; +static const char *MSG = "Tis is UDP Test!"; +static const int DATA_LEN = 128; + +static int ChildFunc(void *arg) +{ + int ret; + int sock; + int recv_data_len; + char recv_data[DATA_LEN]; + struct sockaddr_in addr; + + sock = socket(AF_INET, SOCK_DGRAM, 0); + if (sock < 0) { + return EXIT_CODE_ERRNO_1; + } + + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr(LOCALHOST); + addr.sin_port = htons(LOCALPORT); + (void)memset_s(&(addr.sin_zero), sizeof(addr.sin_zero), 0, sizeof(addr.sin_zero)); + + ret = bind(sock, const_cast(reinterpret_cast(&addr)), + sizeof(struct sockaddr)); + if (ret < 0) { + return EXIT_CODE_ERRNO_2; + } + + ret = sendto(sock, MSG, DATA_LEN, 0, const_cast(reinterpret_cast(&addr)), + (socklen_t)sizeof(addr)); + if (ret < 0) { + return EXIT_CODE_ERRNO_3; + } + + ret = recvfrom(sock, recv_data, DATA_LEN, 0, nullptr, nullptr); + if (ret < 0) { + return EXIT_CODE_ERRNO_4; + } + + ret = strcmp(recv_data, MSG); + if (ret != 0) { + return EXIT_CODE_ERRNO_5; + } + + (void)close(sock); + + return 0; +} + +void ItNetContainer007(void) +{ + int ret = 0; + int status; + + char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0); + EXPECT_STRNE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + + int arg = CHILD_FUNC_ARG; + auto pid = clone(ChildFunc, stackTop, SIGCHLD | CLONE_NEWNET, &arg); + ASSERT_NE(pid, -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_008.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_008.cpp new file mode 100644 index 00000000..c4e8ad6d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_008.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include "It_container_test.h" + +static const int PORT = 8004; +static const char *LOCALHOST = "127.0.0.1"; + +static int UdpTcpBind(int *sock1, int *sock2) +{ + int ret; + int udp_sock; + int tcp_sock; + + udp_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (udp_sock < 0) { + return EXIT_CODE_ERRNO_1; + } + + struct sockaddr_in sa; + sa.sin_family = AF_INET; + sa.sin_addr.s_addr = inet_addr(LOCALHOST); + sa.sin_port = htons(PORT); + + ret = bind(udp_sock, const_cast(reinterpret_cast(&sa)), sizeof(sa)); + if (ret != 0) { + return EXIT_CODE_ERRNO_2; + } + + tcp_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (tcp_sock < 0) { + return EXIT_CODE_ERRNO_3; + } + + ret = bind(tcp_sock, const_cast(reinterpret_cast(&sa)), sizeof(sa)); + if (ret != 0) { + return EXIT_CODE_ERRNO_4; + } + + (*sock1) = udp_sock; + (*sock2) = tcp_sock; + + return 0; +} + +static int ClientFunc(void *param) +{ + (void)param; + int ret; + int udp_sock; + int tcp_sock; + + ret = UdpTcpBind(&udp_sock, &tcp_sock); + if (ret != 0) { + return EXIT_CODE_ERRNO_1; + } + + (void)close(udp_sock); + (void)close(tcp_sock); + + return ret; +} + +void ItNetContainer008(void) +{ + int ret; + int status; + int udp_sock; + int tcp_sock; + + ret = UdpTcpBind(&udp_sock, &tcp_sock); + ASSERT_EQ(ret, 0); + + char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0); + EXPECT_STRNE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + int arg = CHILD_FUNC_ARG; + int pid = clone(ClientFunc, stackTop, SIGCHLD | CLONE_NEWNET, &arg); + ASSERT_NE(pid, -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); + + (void)close(udp_sock); + (void)close(tcp_sock); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_009.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_009.cpp new file mode 100644 index 00000000..fcb398ed --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_009.cpp @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include "It_container_test.h" + +static const char *NETMASK = "255.255.255.0"; +static const char *GW = "192.168.100.1"; +static const char *IFNAME = "veth0"; +static const char *SERVER_IP = "192.168.100.6"; +static const int SERVER_PORT = 8005; +static const char *PEER_IP = "192.168.100.5"; +static const char *SERVER_MSG = "===Hi, I'm Server.==="; +static const char *PEER_MSG = "===Hi, I'm Peer.==="; +static const int TRY_COUNT = 5; +static const int DATA_LEN = 128; +static const int IpLen = 16; + +static int TcpClient(void) +{ + int ret = 0; + int peer; + int try_count = TRY_COUNT; + char recv_data[DATA_LEN]; + struct sockaddr_in server_addr; + + peer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (peer < 0) { + return EXIT_CODE_ERRNO_1; + } + + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = inet_addr(SERVER_IP); + server_addr.sin_port = htons(SERVER_PORT); + (void)memset_s(&(server_addr.sin_zero), sizeof(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero)); + + do { + sleep(1); + ret = connect(peer, const_cast(reinterpret_cast(&server_addr)), + sizeof(struct sockaddr)); + } while (ret !=0 && (try_count--)); + + if (ret < 0) { + (void)close(peer); + printf("[ERR][%s:%d] connect failed, %s!\n", __FUNCTION__, __LINE__, strerror(errno)); + return EXIT_CODE_ERRNO_2; + } + + ret = send(peer, PEER_MSG, strlen(PEER_MSG) + 1, 0); + if (ret < 0) { + (void)close(peer); + printf("[ERR][%s:%d] send failed, %s!\n", __FUNCTION__, __LINE__, strerror(errno)); + return EXIT_CODE_ERRNO_3; + } + + ret = recv(peer, recv_data, sizeof(recv_data), 0); + if (ret < 0) { + (void)close(peer); + printf("[ERR][%s:%d] recv failed, %s!\n", __FUNCTION__, __LINE__, strerror(errno)); + return EXIT_CODE_ERRNO_4; + } + (void)close(peer); + + ret = strcmp(recv_data, SERVER_MSG); + if (ret != 0) { + return EXIT_CODE_ERRNO_5; + } + return 0; +} + +static int TcpServer(void) +{ + int ret = 0; + int server; + int peer; + char recv_data[DATA_LEN]; + struct sockaddr_in server_addr; + + server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (server < 0) { + return EXIT_CODE_ERRNO_1; + } + + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = inet_addr(SERVER_IP); + server_addr.sin_port = htons(SERVER_PORT); + (void)memset_s(&(server_addr.sin_zero), sizeof(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero)); + + ret = bind(server, const_cast(reinterpret_cast(&server_addr)), + sizeof(struct sockaddr)); + if (ret != 0) { + printf("[ERR][%s:%d] bind failed, %s!\n", __FUNCTION__, __LINE__, strerror(errno)); + return EXIT_CODE_ERRNO_2; + } + + ret = listen(server, 1); + if (ret < 0) { + printf("[ERR][%s:%d] listen failed, %s!\n", __FUNCTION__, __LINE__, strerror(errno)); + return EXIT_CODE_ERRNO_3; + } + + peer = accept(server, nullptr, nullptr); + if (peer < 0) { + printf("[ERR][%s:%d] accept failed, %s!\n", __FUNCTION__, __LINE__, strerror(errno)); + return EXIT_CODE_ERRNO_4; + } + + (void)close(server); + + ret = recv(peer, recv_data, sizeof(recv_data), 0); + if (ret < 0) { + printf("[ERR][%s:%d] recv failed, %s!\n", __FUNCTION__, __LINE__, strerror(errno)); + return EXIT_CODE_ERRNO_5; + } + + ret = strcmp(recv_data, PEER_MSG); + if (ret != 0) { + return EXIT_CODE_ERRNO_6; + } + + ret = send(peer, SERVER_MSG, strlen(SERVER_MSG) + 1, 0); + if (ret < 0) { + printf("[ERR][%s:%d] send failed, %s!\n", __FUNCTION__, __LINE__, strerror(errno)); + return EXIT_CODE_ERRNO_7; + } + + (void)close(peer); + return 0; +} + +static void *TcpClientThread(void *arg) +{ + char newIp[IpLen] = {NULL}; + int ret = NetContainerResetNetAddr(IFNAME, PEER_IP, NETMASK, GW); + if (ret != 0) { + return (void *)(intptr_t)EXIT_CODE_ERRNO_1; + } + + ret = NetContainerGetLocalIP(IFNAME, newIp, IpLen); + if (ret != 0) { + return (void *)(intptr_t)EXIT_CODE_ERRNO_2; + } + + if (strncmp(PEER_IP, newIp, strlen(PEER_IP)) != 0) { + return (void *)(intptr_t)EXIT_CODE_ERRNO_3; + } + printf("######## [%s:%d] %s: %s ########\n", __FUNCTION__, __LINE__, IFNAME, newIp); + + ret = TcpClient(); + return (void *)(intptr_t)ret; +} + +static int ChildFunc(void *arg) +{ + char newIp[IpLen] = {NULL}; + int ret = NetContainerResetNetAddr(IFNAME, SERVER_IP, NETMASK, GW); + if (ret != 0) { + return EXIT_CODE_ERRNO_8; + } + + ret = NetContainerGetLocalIP(IFNAME, newIp, IpLen); + if (ret != 0) { + return EXIT_CODE_ERRNO_9; + } + + if (strncmp(SERVER_IP, newIp, strlen(SERVER_IP)) != 0) { + return EXIT_CODE_ERRNO_10; + } + + printf("######## [%s:%d] %s: %s ########\n", __FUNCTION__, __LINE__, IFNAME, newIp); + return TcpServer(); +} + +VOID ItNetContainer009(void) +{ + int ret = 0; + int status; + void *tret = nullptr; + pthread_t srv; + pthread_attr_t attr; + + char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0); + EXPECT_STRNE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + + int arg = CHILD_FUNC_ARG; + int pid = clone(ChildFunc, stackTop, SIGCHLD | CLONE_NEWNET, &arg); + ASSERT_NE(pid, -1); + + ret = pthread_attr_init(&attr); + ASSERT_EQ(ret, 0); + + ret = pthread_create(&srv, &attr, TcpClientThread, nullptr); + ASSERT_EQ(ret, 0); + + ret = pthread_join(srv, &tret); + ASSERT_EQ(ret, 0); + + ret = (uintptr_t)tret; + ASSERT_EQ(ret, 0); + + ret = pthread_attr_destroy(&attr); + ASSERT_EQ(ret, 0); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_011.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_011.cpp new file mode 100644 index 00000000..8b327787 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_011.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "It_container_test.h" + +static int const configLen = 16; +static const int MAX_CONTAINER = 10; +static const int g_buffSize = 512; +static const int g_arryLen = 4; +static const int g_readLen = 254; + +static int childFunc(void *arg) +{ + (void)arg; + sleep(2); /* 2: delay 2s */ + + return 0; +} + +void ItNetContainer011(void) +{ + std::string path = "/proc/sys/user/max_net_container"; + char *array[g_arryLen] = { nullptr }; + char buf[g_buffSize] = { 0 }; + + int ret = ReadFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + GetLine(buf, g_arryLen, g_readLen, array); + + int value = atoi(array[1] + strlen("limit: ")); + ASSERT_EQ(value, MAX_CONTAINER); + + int usedCount = atoi(array[2] + strlen("count: ")); + + (void)memset_s(buf, configLen, 0, configLen); + ret = sprintf_s(buf, configLen, "%d", usedCount + 1); + ASSERT_GT(ret, 0); + + ret = WriteFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, + -1, 0); + ASSERT_NE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + + auto pid1 = clone(childFunc, stackTop, CLONE_NEWNET, NULL); + ASSERT_NE(pid1, -1); + + auto pid2 = clone(childFunc, stackTop, CLONE_NEWNET, NULL); + ASSERT_EQ(pid2, -1); + + ret = waitpid(pid1, NULL, 0); + ASSERT_EQ(ret, pid1); + + (void)memset_s(buf, configLen, 0, configLen); + ret = sprintf_s(buf, configLen, "%d", value); + ASSERT_GT(ret, 0); + + ret = WriteFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + (void)memset_s(buf, configLen, 0, configLen); + ret = ReadFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + GetLine(buf, g_arryLen, g_readLen, array); + + value = atoi(array[1] + strlen("limit: ")); + ASSERT_EQ(value, MAX_CONTAINER); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_012.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_012.cpp new file mode 100644 index 00000000..a6f24c18 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_net_container_012.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "It_container_test.h" + +static int const configLen = 16; +static const int MAX_CONTAINER = 10; +static const int g_buffSize = 512; +static const int g_arryLen = 4; +static const int g_readLen = 254; + +static int childFunc(void *arg) +{ + (void)arg; + + int ret = unshare(CLONE_NEWNET); + if (ret != 0) { + return EXIT_CODE_ERRNO_1; + } + return 0; +} + +void ItNetContainer012(void) +{ + std::string path = "/proc/sys/user/max_net_container"; + char *array[g_arryLen] = { nullptr }; + char buf[g_buffSize] = { 0 }; + int status = 0; + + int ret = ReadFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + GetLine(buf, g_arryLen, g_readLen, array); + + int value = atoi(array[1] + strlen("limit: ")); + ASSERT_EQ(value, MAX_CONTAINER); + + int usedCount = atoi(array[2] + strlen("count: ")); + + (void)memset_s(buf, configLen, 0, configLen); + ret = sprintf_s(buf, configLen, "%d", usedCount + 1); + ASSERT_GT(ret, 0); + + ret = WriteFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, + -1, 0); + ASSERT_NE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + + auto pid1 = clone(childFunc, stackTop, CLONE_NEWNET, NULL); + ASSERT_NE(pid1, -1); + + ret = waitpid(pid1, &status, 0); + ASSERT_EQ(ret, pid1); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, EXIT_CODE_ERRNO_1); + + (void)memset_s(buf, configLen, 0, configLen); + ret = sprintf_s(buf, configLen, "%d", value); + ASSERT_GT(ret, 0); + + ret = WriteFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + (void)memset_s(buf, configLen, 0, configLen); + ret = ReadFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + GetLine(buf, g_arryLen, g_readLen, array); + + value = atoi(array[1] + strlen("limit: ")); + ASSERT_EQ(value, MAX_CONTAINER); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_pid_container_023.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_pid_container_023.cpp new file mode 100644 index 00000000..61682578 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_pid_container_023.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +static int ChildFunc(void *arg) +{ + int value = *((int*)arg); + if (value != CHILD_FUNC_ARG) { + return EXIT_CODE_ERRNO_5; + } + + if (getpid() != CONTAINER_FIRST_PID) { + return EXIT_CODE_ERRNO_1; + } + + if (getppid() != 0) { + return EXIT_CODE_ERRNO_2; + } + + sleep(1); + return 0; +} + +void ItPidContainer023(void) +{ + int ret; + void *stack = malloc(STACK_SIZE); + ASSERT_TRUE(stack != NULL); + + int arg = CHILD_FUNC_ARG; + auto pid = clone(ChildFunc, (char *)stack + STACK_SIZE, CLONE_NEWPID, &arg); + free(stack); + ASSERT_NE(pid, -1); + + int status; + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_pid_container_025.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_pid_container_025.cpp new file mode 100644 index 00000000..8a9e7041 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_pid_container_025.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +static int childFunc(void *arg) +{ + (void)arg; + return 0; +} + +void ItPidContainer025(void) +{ + int ret; + int status; + char *containerType = "pid"; + char *containerType1 = "pid_for_children"; + + char *stack = (char *)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0); + ASSERT_NE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + std::cout << getpid() << std::endl; + auto linkBuffer = ReadlinkContainer(getpid(), containerType); + auto linkBuffer1 = ReadlinkContainer(getpid(), containerType1); + ret = linkBuffer.compare(linkBuffer1); + ASSERT_EQ(ret, 0); + + auto pid = clone(childFunc, stackTop, CLONE_NEWPID | SIGCHLD, NULL); + ASSERT_TRUE(pid != -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); + + auto linkBuffer2 = ReadlinkContainer(getpid(), containerType); + ret = linkBuffer.compare(linkBuffer2); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_pid_container_026.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_pid_container_026.cpp new file mode 100644 index 00000000..be5a0657 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_pid_container_026.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +static int childFunc(void *arg) +{ + (void)arg; + sleep(1); + return 0; +} + +void ItPidContainer026(void) +{ + int ret; + int status; + char *containerType = "pid"; + char *containerType1 = "pid_for_children"; + + char *stack = (char *)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0); + ASSERT_NE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + std::cout << getpid() << std::endl; + auto linkBuffer = ReadlinkContainer(getpid(), containerType); + auto linkBuffer1 = ReadlinkContainer(getpid(), containerType1); + ret = linkBuffer.compare(linkBuffer1); + ASSERT_EQ(ret, 0); + + auto pid = clone(childFunc, stackTop, CLONE_NEWPID | SIGCHLD, NULL); + ASSERT_TRUE(pid != -1); + + auto linkBuffer2 = ReadlinkContainer(pid, containerType); + ret = linkBuffer.compare(linkBuffer2); + ASSERT_NE(ret, 0); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_pid_container_027.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_pid_container_027.cpp new file mode 100644 index 00000000..85e654e3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_pid_container_027.cpp @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +static int ChildFunClone3(void *p) +{ + (void)p; + auto pid = getpid(); + if (pid != CONTAINER_SECOND_PID) { + return EXIT_CODE_ERRNO_1; + } + return 0; +} + +static int ChildFunClone2(void *p) +{ + (void)p; + auto pid = getpid(); + if (pid != CONTAINER_FIRST_PID) { + return EXIT_CODE_ERRNO_1; + } + int ret; + int status; + void *pstk = malloc(STACK_SIZE); + if (pstk == NULL) { + return EXIT_CODE_ERRNO_2; + } + int childPid = clone(ChildFunClone3, (char *)pstk + STACK_SIZE, SIGCHLD, NULL); + if (childPid == -1) { + free(pstk); + return EXIT_CODE_ERRNO_3; + } + + ret = waitpid(childPid, &status, 0); + ret = WIFEXITED(status); + ret = WEXITSTATUS(status); + if (ret != 0) { + free(pstk); + return EXIT_CODE_ERRNO_4; + } + + free(pstk); + return 0; +} + + +static int ChildFunClone1(void *p) +{ + (void)p; + int ret; + int status; + const char *containerType = "pid"; + const char *containerType1 = "pid_for_children"; + + auto pid = getpid(); + ret = unshare(CLONE_NEWPID); + if (ret == -1) { + return EXIT_CODE_ERRNO_1; + } + + auto pid1 = getpid(); + if (pid != pid1) { + return EXIT_CODE_ERRNO_2; + } + + auto linkBuffer = ReadlinkContainer(pid, containerType); + auto linkBuffer1 = ReadlinkContainer(pid, containerType1); + ret = linkBuffer.compare(linkBuffer1); + if (ret == 0) { + printf("linkBuffer: %s linkBuffer1: %s\n", linkBuffer.c_str(), linkBuffer1.c_str()); + return EXIT_CODE_ERRNO_3; + } + + void *pstk = malloc(STACK_SIZE); + if (pstk == NULL) { + return EXIT_CODE_ERRNO_4; + } + int childPid = clone(ChildFunClone2, (char *)pstk + STACK_SIZE, SIGCHLD, NULL); + free(pstk); + if (childPid == -1) { + return EXIT_CODE_ERRNO_5; + } + + ret = unshare(CLONE_NEWPID); + if (ret != -1) { + return EXIT_CODE_ERRNO_6; + } + + ret = waitpid(childPid, &status, 0); + if (ret != childPid) { + return EXIT_CODE_ERRNO_7; + } + ret = WIFEXITED(status); + if (ret == 0) { + return EXIT_CODE_ERRNO_8; + } + ret = WEXITSTATUS(status); + if (ret != 0) { + return EXIT_CODE_ERRNO_9; + } + return 0; +} + +void ItPidContainer027(void) +{ + void *pstk = malloc(STACK_SIZE); + ASSERT_TRUE(pstk != NULL); + + int childPid = clone(ChildFunClone1, (char *)pstk + STACK_SIZE, SIGCHLD, NULL); + free(pstk); + ASSERT_NE(childPid, -1); + + int status; + int ret = waitpid(childPid, &status, 0); + ASSERT_EQ(ret, childPid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_pid_container_028.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_pid_container_028.cpp new file mode 100644 index 00000000..846996c2 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_pid_container_028.cpp @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +static int ChildFunClone3(void *p) +{ + (void)p; + auto pid = getpid(); + if (pid != CONTAINER_SECOND_PID) { + return EXIT_CODE_ERRNO_1; + } + return 0; +} + +static int ChildFunClone2(void *p) +{ + (void)p; + auto pid = getpid(); + if (pid != CONTAINER_FIRST_PID) { + return EXIT_CODE_ERRNO_1; + } + int ret; + int status; + void *pstk = malloc(STACK_SIZE); + if (pstk == NULL) { + return EXIT_CODE_ERRNO_2; + } + int childPid = clone(ChildFunClone3, (char *)pstk + STACK_SIZE, SIGCHLD, NULL); + if (childPid == -1) { + free(pstk); + return EXIT_CODE_ERRNO_3; + } + + ret = waitpid(childPid, &status, 0); + ret = WIFEXITED(status); + ret = WEXITSTATUS(status); + if (ret != 0) { + free(pstk); + return EXIT_CODE_ERRNO_4; + } + + free(pstk); + return 0; +} + + +static int ChildFunClone1(void *p) +{ + (void)p; + int ret; + int status; + const char *containerType = "pid"; + const char *containerType1 = "pid_for_children"; + + auto pid = getpid(); + ret = unshare(CLONE_NEWPID); + if (ret == -1) { + return EXIT_CODE_ERRNO_1; + } + auto pid1 = getpid(); + if (pid != pid1) { + return EXIT_CODE_ERRNO_2; + } + + auto linkBuffer = ReadlinkContainer(pid, containerType); + auto linkBuffer1 = ReadlinkContainer(pid, containerType1); + ret = linkBuffer.compare(linkBuffer1); + if (ret == 0) { + return EXIT_CODE_ERRNO_3; + } + + void *pstk = malloc(STACK_SIZE); + if (pstk == NULL) { + return EXIT_CODE_ERRNO_4; + } + int childPid = clone(ChildFunClone2, (char *)pstk + STACK_SIZE, SIGCHLD, NULL); + free(pstk); + if (childPid == -1) { + return EXIT_CODE_ERRNO_5; + } + + ret = unshare(CLONE_NEWPID); + if (ret != -1) { + return EXIT_CODE_ERRNO_6; + } + + ret = waitpid(childPid, &status, 0); + if (ret != childPid) { + return EXIT_CODE_ERRNO_7; + } + ret = WIFEXITED(status); + if (ret == 0) { + return EXIT_CODE_ERRNO_8; + } + ret = WEXITSTATUS(status); + if (ret != 0) { + return EXIT_CODE_ERRNO_9; + } + return 0; +} + +void ItPidContainer028(void) +{ + void *pstk = malloc(STACK_SIZE); + ASSERT_TRUE(pstk != NULL); + + int childPid = clone(ChildFunClone1, (char *)pstk + STACK_SIZE, SIGCHLD, NULL); + free(pstk); + ASSERT_NE(childPid, -1); + + int status; + int ret = waitpid(childPid, &status, 0); + ASSERT_EQ(ret, childPid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_pid_container_029.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_pid_container_029.cpp new file mode 100644 index 00000000..e1ff97ac --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_pid_container_029.cpp @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +static int ChildFunClone3(void *p) +{ + (void)p; + auto pid = getpid(); + if (pid != CONTAINER_FIRST_PID) { + return EXIT_CODE_ERRNO_1; + } + return 0; +} + +static int ChildFunClone2(void *p) +{ + (void)p; + auto pid = getpid(); + if (pid != CONTAINER_FIRST_PID) { + return EXIT_CODE_ERRNO_1; + } + return 0; +} + +static int ChildFunClone1(void *p) +{ + (void)p; + int ret; + int status; + const char *containerType = "pid"; + const char *containerType1 = "pid_for_children"; + + auto pid = getpid(); + ret = unshare(CLONE_NEWPID); + if (ret == -1) { + return EXIT_CODE_ERRNO_1; + } + auto pid1 = getpid(); + if (pid != pid1) { + return EXIT_CODE_ERRNO_2; + } + + auto linkBuffer = ReadlinkContainer(pid, containerType); + auto linkBuffer1 = ReadlinkContainer(pid, containerType1); + ret = linkBuffer.compare(linkBuffer1); + if (ret == 0) { + return EXIT_CODE_ERRNO_3; + } + + void *pstk = malloc(STACK_SIZE); + if (pstk == NULL) { + return EXIT_CODE_ERRNO_4; + } + int childPid = clone(ChildFunClone2, (char *)pstk + STACK_SIZE, CLONE_NEWPID | SIGCHLD, NULL); + if (childPid != -1) { + free(pstk); + return EXIT_CODE_ERRNO_5; + } + + int childPid1 = clone(ChildFunClone3, (char *)pstk + STACK_SIZE, SIGCHLD, NULL); + free(pstk); + if (childPid1 == -1) { + return EXIT_CODE_ERRNO_6; + } + + ret = unshare(CLONE_NEWPID); + if (ret != -1) { + return EXIT_CODE_ERRNO_7; + } + + ret = waitpid(childPid1, &status, 0); + if (ret != childPid1) { + return EXIT_CODE_ERRNO_11; + } + ret = WIFEXITED(status); + if (ret == 0) { + return EXIT_CODE_ERRNO_12; + } + ret = WEXITSTATUS(status); + if (ret != 0) { + return EXIT_CODE_ERRNO_13; + } + return 0; +} + +void ItPidContainer029(void) +{ + void *pstk = malloc(STACK_SIZE); + ASSERT_TRUE(pstk != NULL); + + int childPid = clone(ChildFunClone1, (char *)pstk + STACK_SIZE, SIGCHLD, NULL); + free(pstk); + ASSERT_NE(childPid, -1); + + int status; + int ret = waitpid(childPid, &status, 0); + ASSERT_EQ(ret, childPid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_pid_container_030.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_pid_container_030.cpp new file mode 100644 index 00000000..04fb9738 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_pid_container_030.cpp @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +static int ChildFunClone3(void *p) +{ + (void)p; + auto pid = getpid(); + if (pid != CONTAINER_SECOND_PID) { + return EXIT_CODE_ERRNO_1; + } + sleep(2); /* dealy 2s */ + return 0; +} + +static int ChildFunClone2(void *p) +{ + (void)p; + auto pid = getpid(); + if (pid != CONTAINER_FIRST_PID) { + return EXIT_CODE_ERRNO_1; + } + sleep(2); /* dealy 2s */ + return 0; +} + +static int ChildFunClone1(void *p) +{ + (void)p; + int ret, status; + const char *containerType = "pid"; + const char *containerType1 = "pid_for_children"; + + auto pid = getpid(); + ret = unshare(CLONE_NEWPID); + if (ret == -1) { + return EXIT_CODE_ERRNO_1; + } + auto pid1 = getpid(); + if (pid != pid1) { + return EXIT_CODE_ERRNO_2; + } + + auto linkBuffer = ReadlinkContainer(pid, containerType); + auto linkBuffer1 = ReadlinkContainer(pid, containerType1); + ret = linkBuffer.compare(linkBuffer1); + if (ret == 0) { + return EXIT_CODE_ERRNO_3; + } + + void *pstk = malloc(STACK_SIZE); + if (pstk == NULL) { + return EXIT_CODE_ERRNO_4; + } + int childPid = clone(ChildFunClone2, (char *)pstk + STACK_SIZE, SIGCHLD, NULL); + if (childPid == -1) { + free(pstk); + return EXIT_CODE_ERRNO_5; + } + + auto linkBuffer2 = ReadlinkContainer(childPid, containerType); + + int childPid1 = clone(ChildFunClone3, (char *)pstk + STACK_SIZE, SIGCHLD, NULL); + free(pstk); + if (childPid1 == -1) { + return EXIT_CODE_ERRNO_6; + } + + auto linkBuffer3 = ReadlinkContainer(childPid1, containerType); + ret = linkBuffer3.compare(linkBuffer2); + if (ret != 0) { + return EXIT_CODE_ERRNO_7; + } + + ret = unshare(CLONE_NEWPID); + if (ret != -1) { + return EXIT_CODE_ERRNO_8; + } + + ret = WaitChild(childPid1, &status, EXIT_CODE_ERRNO_9, EXIT_CODE_ERRNO_10); + if (ret != 0) { + return ret; + } + + ret = WaitChild(childPid, &status, EXIT_CODE_ERRNO_11, EXIT_CODE_ERRNO_12); + if (ret != 0) { + return ret; + } + return 0; +} + +void ItPidContainer030(void) +{ + void *pstk = malloc(STACK_SIZE); + ASSERT_TRUE(pstk != NULL); + + int childPid = clone(ChildFunClone1, (char *)pstk + STACK_SIZE, SIGCHLD, NULL); + free(pstk); + ASSERT_NE(childPid, -1); + + int status; + int ret = waitpid(childPid, &status, 0); + ASSERT_EQ(ret, childPid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_pid_container_031.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_pid_container_031.cpp new file mode 100644 index 00000000..4bbbbc61 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_pid_container_031.cpp @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +static const int BUF_SIZE = 100; + +static int ChildFun2(void *p) +{ + (void)p; + sleep(3); /* 3: delay 3s */ + return 0; +} + +static int ChildFun1(void *p) +{ + (void)p; + sleep(6); /* 6: delay 6s */ + return 0; +} + +static int ChildFun(void *p) +{ + (void)p; + int status, ret; + const char *containerType = "pid"; + const char *containerType1 = "pid_for_children"; + char targetpath[BUF_SIZE] = {0}; + auto linkBuffer1 = ReadlinkContainer(getpid(), containerType); + + int childPid = clone(ChildFun1, NULL, CLONE_NEWPID | SIGCHLD, NULL); + if (childPid == -1) { + return EXIT_CODE_ERRNO_1; + } + auto linkBuffer2 = ReadlinkContainer(childPid, containerType); + ret = linkBuffer2.compare(linkBuffer1); + if (ret == 0) { + return EXIT_CODE_ERRNO_2; + } + + ret = sprintf_s(targetpath, BUF_SIZE, "/proc/%d/container/pid", childPid); + if (ret < 0) { + return EXIT_CODE_ERRNO_16; + } + int fd = open(targetpath, O_RDONLY | O_CLOEXEC); + if (fd == -1) { + return EXIT_CODE_ERRNO_3; + } + + ret = setns(fd, CLONE_NEWPID); + if (ret != 0) { + close(fd); + return EXIT_CODE_ERRNO_4; + } + + close(fd); + + auto linkBuffer6 = ReadlinkContainer(getpid(), containerType); + ret = linkBuffer6.compare(linkBuffer1); + if (ret != 0) { + return EXIT_CODE_ERRNO_17; + } + + auto linkBuffer3 = ReadlinkContainer(getpid(), containerType1); + ret = linkBuffer3.compare(linkBuffer2); + if (ret != 0) { + return EXIT_CODE_ERRNO_5; + } + + int childPid1 = clone(ChildFun2, NULL, SIGCHLD, NULL); + if (childPid1 == -1) { + return EXIT_CODE_ERRNO_6; + } + + auto linkBuffer4 = ReadlinkContainer(childPid1, containerType); + ret = linkBuffer4.compare(linkBuffer3); + if (ret != 0) { + return EXIT_CODE_ERRNO_7; + } + + int childPid2 = clone(ChildFun2, NULL, CLONE_NEWUTS | SIGCHLD, NULL); + if (childPid2 == -1) { + return EXIT_CODE_ERRNO_8; + } + + auto linkBuffer5 = ReadlinkContainer(childPid2, containerType); + ret = linkBuffer5.compare(linkBuffer4); + if (ret != 0) { + return EXIT_CODE_ERRNO_9; + } + + ret = WaitChild(childPid2, &status, EXIT_CODE_ERRNO_10, EXIT_CODE_ERRNO_11); + if (ret != 0) { + return ret; + } + + ret = WaitChild(childPid1, &status, EXIT_CODE_ERRNO_12, EXIT_CODE_ERRNO_13); + if (ret != 0) { + return ret; + } + ret = WaitChild(childPid, &status, EXIT_CODE_ERRNO_14, EXIT_CODE_ERRNO_15); + if (ret != 0) { + return ret; + } + return 0; +} + +void ItPidContainer031(void) +{ + int status; + int childPid = clone(ChildFun, NULL, CLONE_NEWPID | SIGCHLD, NULL); + ASSERT_NE(childPid, -1); + + int ret = waitpid(childPid, &status, 0); + ASSERT_EQ(ret, childPid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_pid_container_032.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_pid_container_032.cpp new file mode 100644 index 00000000..f78f0e7d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_pid_container_032.cpp @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "It_container_test.h" + +static int const configLen = 16; +static const int MAX_CONTAINER = 10; +static const int g_buffSize = 512; +static const int g_arryLen = 4; +static const int g_readLen = 254; + +static int childFunc(void *arg) +{ + (void)arg; + sleep(2); /* 2: delay 2s */ + + return 0; +} + +void ItPidContainer032(void) +{ + std::string path = "/proc/sys/user/max_pid_container"; + char *array[g_arryLen] = { nullptr }; + char buf[g_buffSize] = { 0 }; + + sleep(2); /* 2: Wait for cache resource reclamation */ + + int ret = ReadFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + GetLine(buf, g_arryLen, g_readLen, array); + + int value = atoi(array[1] + strlen("limit: ")); + ASSERT_EQ(value, MAX_CONTAINER); + + int usedCount = atoi(array[2] + strlen("count: ")); + + (void)memset_s(buf, configLen, 0, configLen); + ret = sprintf_s(buf, configLen, "%d", usedCount + 1); + ASSERT_GT(ret, 0); + + ret = WriteFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, + -1, 0); + ASSERT_NE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + + auto pid1 = clone(childFunc, stackTop, CLONE_NEWPID, NULL); + ASSERT_NE(pid1, -1); + + auto pid2 = clone(childFunc, stackTop, CLONE_NEWPID, NULL); + ASSERT_EQ(pid2, -1); + + ret = waitpid(pid1, NULL, 0); + ASSERT_EQ(ret, pid1); + + (void)memset_s(buf, configLen, 0, configLen); + ret = sprintf_s(buf, configLen, "%d", value); + ASSERT_GT(ret, 0); + + ret = WriteFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + (void)memset_s(buf, configLen, 0, configLen); + ret = ReadFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + GetLine(buf, g_arryLen, g_readLen, array); + + value = atoi(array[1] + strlen("limit: ")); + ASSERT_EQ(value, MAX_CONTAINER); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_pid_container_033.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_pid_container_033.cpp new file mode 100644 index 00000000..04ee6ed7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_pid_container_033.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "It_container_test.h" + +static int const configLen = 16; +static const int MAX_CONTAINER = 10; +static const int g_buffSize = 512; +static const int g_arryLen = 4; +static const int g_readLen = 254; + +static int childFunc(void *arg) +{ + (void)arg; + + int ret = unshare(CLONE_NEWPID); + if (ret != 0) { + return EXIT_CODE_ERRNO_1; + } + return 0; +} + +void ItPidContainer033(void) +{ + std::string path = "/proc/sys/user/max_pid_container"; + char *array[g_arryLen] = { nullptr }; + char buf[g_buffSize] = { 0 }; + int status = 0; + + sleep(2); /* 2: Wait for cache resource reclamation */ + + int ret = ReadFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + GetLine(buf, g_arryLen, g_readLen, array); + + int value = atoi(array[1] + strlen("limit: ")); + ASSERT_EQ(value, MAX_CONTAINER); + + int usedCount = atoi(array[2] + strlen("count: ")); + + (void)memset_s(buf, configLen, 0, configLen); + ret = sprintf_s(buf, configLen, "%d", usedCount + 1); + ASSERT_GT(ret, 0); + + ret = WriteFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, + -1, 0); + ASSERT_NE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + + auto pid1 = clone(childFunc, stackTop, CLONE_NEWPID, NULL); + ASSERT_NE(pid1, -1); + + ret = waitpid(pid1, &status, 0); + ASSERT_EQ(ret, pid1); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, EXIT_CODE_ERRNO_1); + + (void)memset_s(buf, configLen, 0, configLen); + ret = sprintf_s(buf, configLen, "%d", value); + ASSERT_GT(ret, 0); + + ret = WriteFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + (void)memset_s(buf, configLen, 0, configLen); + ret = ReadFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + GetLine(buf, g_arryLen, g_readLen, array); + + value = atoi(array[1] + strlen("limit: ")); + ASSERT_EQ(value, MAX_CONTAINER); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_time_container_001.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_time_container_001.cpp new file mode 100644 index 00000000..0fa88dc9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_time_container_001.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +static int childFunc(void *arg) +{ + int value = *((int*)arg); + if (value != CHILD_FUNC_ARG) { + return EXIT_CODE_ERRNO_1; + } + sleep(1); + return 0; +} + +void ItTimeContainer001(void) +{ + int ret; + int status; + char *containerType = "time"; + char *containerType1 = "time_for_children"; + + char *stack = (char *)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0); + ASSERT_NE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + std::cout << getpid() << std::endl; + auto linkBuffer = ReadlinkContainer(getpid(), containerType); + auto linkBuffer1 = ReadlinkContainer(getpid(), containerType1); + ret = linkBuffer.compare(linkBuffer1); + ASSERT_EQ(ret, 0); + + int arg = CHILD_FUNC_ARG; + auto pid = clone(childFunc, stackTop, CLONE_NEWTIME | SIGCHLD, &arg); + ASSERT_TRUE(pid != -1); + + auto linkBuffer2 = ReadlinkContainer(pid, containerType); + ret = linkBuffer.compare(linkBuffer2); + ASSERT_EQ(ret, 0); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_time_container_002.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_time_container_002.cpp new file mode 100644 index 00000000..7f37efa7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_time_container_002.cpp @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +const int STR_LEN = 50; +const int SEC = 600; +const int NSEC = 800000000; + +static int childFunc(void *arg) +{ + char path[STR_LEN]; + char timeOff[STR_LEN]; + char readBuf[STR_LEN]; + int ret; + + ret = sprintf_s(timeOff, STR_LEN, "monotonic %d %d", SEC, NSEC); + if (ret <= 0) { + return EXIT_CODE_ERRNO_4; + } + ret = sprintf_s(path, STR_LEN, "/proc/%d/time_offsets", getpid()); + if (ret <= 0) { + return EXIT_CODE_ERRNO_5; + } + + int fd = open(path, O_RDWR); + if (fd == -1) { + return EXIT_CODE_ERRNO_1; + } + + ret = read(fd, readBuf, STR_LEN); + if (ret == -1) { + close(fd); + return EXIT_CODE_ERRNO_2; + } + close(fd); + ret = strncmp(timeOff, readBuf, strlen(timeOff)); + if (ret != 0) { + return EXIT_CODE_ERRNO_3; + } + + return 0; +} + +static int WriteProcTime(int pid) +{ + int ret = 0; + char path[STR_LEN]; + char timeOff[STR_LEN]; + + ret = sprintf_s(timeOff, STR_LEN, "monotonic %d %d", SEC, NSEC); + if (ret <= 0) { + return EXIT_CODE_ERRNO_6; + } + ret = sprintf_s(path, STR_LEN, "/proc/%d/time_offsets", pid); + if (ret <= 0) { + return EXIT_CODE_ERRNO_7; + } + + int strLen = strlen(timeOff); + int fd = open(path, O_WRONLY); + if (ret == -1) { + return EXIT_CODE_ERRNO_8; + } + + ret = write(fd, timeOff, strLen); + if (ret != strLen) { + close(fd); + return EXIT_CODE_ERRNO_9; + } + + close(fd); + return 0; +} + +static void TimeContainerUnshare(void) +{ + int ret; + int status; + char *containerType = "time"; + char *containerType1 = "time_for_children"; + + char *stack = (char *)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0); + ASSERT_NE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + + ret = unshare(CLONE_NEWTIME); + ASSERT_EQ(ret, 0); + + ret = unshare(CLONE_NEWTIME); + ASSERT_EQ(ret, -1); + + ret = WriteProcTime(getpid()); + ASSERT_EQ(ret, 0); + + auto linkBuffer = ReadlinkContainer(getpid(), containerType); + auto linkBuffer1 = ReadlinkContainer(getpid(), containerType1); + ret = linkBuffer.compare(linkBuffer1); + ASSERT_TRUE(ret != 0); + + int arg = CHILD_FUNC_ARG; + auto pid = clone(childFunc, stackTop, CLONE_NEWTIME | SIGCHLD, &arg); + ASSERT_TRUE(pid != -1); + + auto linkBuffer2 = ReadlinkContainer(pid, containerType); + ret = linkBuffer1.compare(linkBuffer2); + ASSERT_EQ(ret, 0); + + ret = unshare(CLONE_NEWTIME); + ASSERT_EQ(ret, -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_TRUE(ret != 0); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); + + exit(0); +} + +void ItTimeContainer002(void) +{ + int status = 0; + auto pid = fork(); + ASSERT_TRUE(pid != -1); + if (pid == 0) { + TimeContainerUnshare(); + exit(EXIT_CODE_ERRNO_1); + } + auto ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_time_container_003.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_time_container_003.cpp new file mode 100644 index 00000000..edd80dea --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_time_container_003.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +static int childFunc(void *arg) +{ + int ret; + char *containerType = "time"; + char *containerType1 = "time_for_children"; + char pid_link[100]; /* 100: test len */ + char targetpath[100]; /* 100: test len */ + auto linkBuffer = ReadlinkContainer(getppid(), containerType); + int fd; + + ret = sprintf_s(pid_link, 100, "%s", linkBuffer.c_str()); /* 100: test len */ + if (ret <= 0) { + return EXIT_CODE_ERRNO_4; + } + ret = sprintf_s(targetpath, 100, "/proc/%d/container/time", getppid()); /* 100: test len */ + if (ret <= 0) { + return EXIT_CODE_ERRNO_5; + } + fd = open(targetpath, O_RDONLY | O_CLOEXEC); + if (fd == -1) { + return EXIT_CODE_ERRNO_1; + } + + ret = setns(fd, CLONE_NEWTIME); + if (ret != 0) { + close(fd); + return EXIT_CODE_ERRNO_2; + } + close(fd); + auto linkBuffer1 = ReadlinkContainer(getpid(), containerType); + auto linkBuffer2 = ReadlinkContainer(getpid(), containerType1); + ret = linkBuffer1.compare(linkBuffer2); + EXPECT_EQ(ret, 0); + if (ret != 0) { + return EXIT_CODE_ERRNO_3; + } + + return 0; +} + +static void TimeContainerUnshare(void) +{ + int ret; + int status; + char *containerType = "time"; + char *containerType1 = "time_for_children"; + + char *stack = (char *)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0); + ASSERT_NE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + + ret = unshare(CLONE_NEWTIME); + ASSERT_EQ(ret, 0); + + auto linkBuffer = ReadlinkContainer(getpid(), containerType1); + + int arg = CHILD_FUNC_ARG; + auto pid = clone(childFunc, stackTop, CLONE_NEWTIME | SIGCHLD, &arg); + ASSERT_TRUE(pid != -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_TRUE(ret != 0); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); + exit(0); +} + +void ItTimeContainer003(void) +{ + int status = 0; + auto pid = fork(); + ASSERT_TRUE(pid != -1); + if (pid == 0) { + TimeContainerUnshare(); + exit(EXIT_CODE_ERRNO_1); + } + auto ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); +} + diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_time_container_004.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_time_container_004.cpp new file mode 100644 index 00000000..e8c760f0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_time_container_004.cpp @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +const int STR_LEN = 50; +const int SEC = 172800; +const int NSEC = 800000000; + +static int childFunc(void *arg) +{ + int ret; + struct timespec tp = *((struct timespec *)arg); + struct timespec tp1; + + ret = clock_gettime(CLOCK_MONOTONIC_RAW, &tp1); + if (ret != 0) { + return EXIT_CODE_ERRNO_1; + } + + ret = ((tp1.tv_sec >= tp.tv_sec + SEC)); + if (ret != 1) { + return EXIT_CODE_ERRNO_2; + } + + return 0; +} +static int WriteProcTime(int pid) +{ + int ret; + char path[STR_LEN]; + char timeOff[STR_LEN]; + + ret = sprintf_s(timeOff, STR_LEN, "monotonic %d %d", SEC, NSEC); + if (ret <= 0) { + return EXIT_CODE_ERRNO_5; + } + ret = sprintf_s(path, STR_LEN, "/proc/%d/time_offsets", pid); + if (ret <= 0) { + return EXIT_CODE_ERRNO_6; + } + int strLen = strlen(timeOff); + int fd = open(path, O_WRONLY); + if (fd == -1) { + return EXIT_CODE_ERRNO_3; + } + + ret = write(fd, timeOff, strLen); + if (ret != strLen) { + close(fd); + return EXIT_CODE_ERRNO_4; + } + + close(fd); + return 0; +} + +static void TimeContainerUnshare(void) +{ + int ret; + int status; + struct timespec tp; + + char *stack = (char *)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0); + ASSERT_NE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + + ret = unshare(CLONE_NEWTIME); + ASSERT_EQ(ret, 0); + + ret = WriteProcTime(getpid()); + ASSERT_EQ(ret, 0); + + ret = clock_gettime(CLOCK_MONOTONIC_RAW, &tp); + ASSERT_EQ(ret, 0); + + auto pid = clone(childFunc, stackTop, CLONE_NEWTIME | SIGCHLD, &tp); + ASSERT_TRUE(pid != -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); + + exit(0); +} + +void ItTimeContainer004(void) +{ + int status = 0; + auto pid = fork(); + ASSERT_TRUE(pid != -1); + if (pid == 0) { + TimeContainerUnshare(); + exit(EXIT_CODE_ERRNO_1); + } + auto ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_time_container_005.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_time_container_005.cpp new file mode 100644 index 00000000..b08832d4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_time_container_005.cpp @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +const int STR_LEN = 50; +const int SEC = 172800; +const int NSEC = 800000000; + +static int childFunc(void *arg) +{ + int ret; + struct timespec tp = *((struct timespec *)arg); + struct timespec tp1 = {0}; + + ret = clock_gettime(CLOCK_MONOTONIC, &tp1); + if (ret != 0) { + return EXIT_CODE_ERRNO_1; + } + + ret = ((tp1.tv_sec >= tp.tv_sec + SEC)); + if (ret != 1) { + return EXIT_CODE_ERRNO_2; + } + + return 0; +} +static int WriteProcTime(int pid) +{ + int ret; + char path[STR_LEN]; + char timeOff[STR_LEN]; + + ret = sprintf_s(timeOff, STR_LEN, "monotonic %d %d", SEC, NSEC); + if (ret <= 0) { + return EXIT_CODE_ERRNO_5; + } + ret = sprintf_s(path, STR_LEN, "/proc/%d/time_offsets", pid); + if (ret <= 0) { + return EXIT_CODE_ERRNO_5; + } + int strLen = strlen(timeOff); + int fd = open(path, O_WRONLY); + if (fd == -1) { + return EXIT_CODE_ERRNO_3; + } + + ret = write(fd, timeOff, strLen); + if (ret != strLen) { + close(fd); + return EXIT_CODE_ERRNO_4; + } + + close(fd); + return 0; +} + +static void TimeContainerUnshare(void) +{ + int ret; + int status; + struct timespec tp = {0}; + + char *stack = (char *)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0); + ASSERT_NE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + + ret = unshare(CLONE_NEWTIME); + ASSERT_EQ(ret, 0); + + ret = WriteProcTime(getpid()); + ASSERT_EQ(ret, 0); + + ret = clock_gettime(CLOCK_MONOTONIC, &tp); + ASSERT_EQ(ret, 0); + + auto pid = clone(childFunc, stackTop, CLONE_NEWTIME | SIGCHLD, &tp); + ASSERT_TRUE(pid != -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_TRUE(ret != 0); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); + + exit(0); +} + +void ItTimeContainer005(void) +{ + int status = 0; + auto pid = fork(); + ASSERT_TRUE(pid != -1); + if (pid == 0) { + TimeContainerUnshare(); + exit(EXIT_CODE_ERRNO_1); + } + auto ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_time_container_006.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_time_container_006.cpp new file mode 100644 index 00000000..2d2d6e1b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_time_container_006.cpp @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "It_container_test.h" + +static int const configLen = 16; +static const int MAX_CONTAINER = 10; +static const int g_buffSize = 512; +static const int g_arryLen = 4; +static const int g_readLen = 254; + +static int childFunc(void *arg) +{ + (void)arg; + + int ret = unshare(CLONE_NEWTIME); + if (ret != 0) { + return EXIT_CODE_ERRNO_1; + } + + ret = unshare(CLONE_NEWTIME); + if (ret != 0) { + return EXIT_CODE_ERRNO_2; + } + + return 0; +} + +void ItTimeContainer006(void) +{ + std::string path = "/proc/sys/user/max_time_container"; + char *array[g_arryLen] = { nullptr }; + char buf[g_buffSize] = { 0 }; + int status = 0; + + int ret = ReadFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + GetLine(buf, g_arryLen, g_readLen, array); + + int value = atoi(array[1] + strlen("limit: ")); + ASSERT_EQ(value, MAX_CONTAINER); + + int usedCount = atoi(array[2] + strlen("count: ")); + + (void)memset_s(buf, configLen, 0, configLen); + ret = sprintf_s(buf, configLen, "%d", usedCount + 1); + ASSERT_GT(ret, 0); + + ret = WriteFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, + -1, 0); + ASSERT_NE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + + auto pid1 = clone(childFunc, stackTop, CLONE_NEWTIME, NULL); + ASSERT_NE(pid1, -1); + + ret = waitpid(pid1, &status, 0); + ASSERT_EQ(ret, pid1); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, EXIT_CODE_ERRNO_2); + + (void)memset_s(buf, configLen, 0, configLen); + ret = sprintf_s(buf, configLen, "%d", value); + ASSERT_GT(ret, 0); + + ret = WriteFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + (void)memset_s(buf, configLen, 0, configLen); + ret = ReadFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + GetLine(buf, g_arryLen, g_readLen, array); + + value = atoi(array[1] + strlen("limit: ")); + ASSERT_EQ(value, MAX_CONTAINER); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_time_container_007.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_time_container_007.cpp new file mode 100644 index 00000000..2bb6d9d5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_time_container_007.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +const int STR_LEN = 50; +const int SEC = 172800; +const int NSEC = 80000000; + +static int WriteProcTime(int pid) +{ + int ret; + char path[STR_LEN] = {0}; + char timeOff[STR_LEN] = {0}; + + ret = sprintf_s(timeOff, STR_LEN, "monotonic %d %d", SEC, NSEC); + if (ret < 0) { + return EXIT_CODE_ERRNO_3; + } + ret = sprintf_s(path, STR_LEN, "/proc/%d/time_offsets", pid); + if (ret < 0) { + return EXIT_CODE_ERRNO_4; + } + + int strLen = strlen(timeOff); + int fd = open(path, O_WRONLY); + if (fd == -1) { + return EXIT_CODE_ERRNO_1; + } + + ret = write(fd, timeOff, strLen); + if (ret != -1) { + close(fd); + return EXIT_CODE_ERRNO_2; + } + + close(fd); + return 0; +} + +void ItTimeContainer007(void) +{ + int ret; + + ret = WriteProcTime(getpid()); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_time_container_008.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_time_container_008.cpp new file mode 100644 index 00000000..8c748041 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_time_container_008.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +const int STR_LEN = 50; +const int SEC = 172800; +const long long NSEC = 800000000000; + +static int WriteProcTime(int pid) +{ + int ret; + char path[STR_LEN] = {0}; + char timeOff[STR_LEN] = {0}; + + ret = sprintf_s(timeOff, STR_LEN, "monotonic %d %lld", SEC, NSEC); + if (ret < 0) { + return EXIT_CODE_ERRNO_3; + } + ret = sprintf_s(path, STR_LEN, "/proc/%d/time_offsets", pid); + if (ret < 0) { + return EXIT_CODE_ERRNO_3; + } + int strLen = strlen(timeOff); + int fd = open(path, O_WRONLY); + if (fd == -1) { + return EXIT_CODE_ERRNO_1; + } + + ret = write(fd, timeOff, strLen); + if (ret != -1) { + close(fd); + return EXIT_CODE_ERRNO_2; + } + + close(fd); + return 0; +} + +static void TimeContainerUnshare(void) +{ + int ret = unshare(CLONE_NEWTIME); + ASSERT_EQ(ret, 0); + + ret = WriteProcTime(getpid()); + ASSERT_EQ(ret, 0); + + exit(0); +} + +void ItTimeContainer008(void) +{ + int status = 0; + auto pid = fork(); + ASSERT_TRUE(pid != -1); + if (pid == 0) { + TimeContainerUnshare(); + exit(EXIT_CODE_ERRNO_1); + } + auto ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_time_container_009.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_time_container_009.cpp new file mode 100644 index 00000000..8dc70bf3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_time_container_009.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "It_container_test.h" + +static std::string GenTimeLinkPath(int pid) +{ + std::ostringstream buf; + buf << "/proc/" << pid << "/container/time"; + return buf.str(); +} + +static std::string ReadlinkTime(int pid) +{ + auto path = GenTimeLinkPath(pid); + struct stat sb; + + int ret = lstat(path.data(), &sb); + if (ret == -1) { + perror("lstat"); + return std::string(); + } + + auto bufsiz = sb.st_size + 1; + if (sb.st_size == 0) { + bufsiz = PATH_MAX; + } + + std::vector buf(bufsiz); + auto nbytes = readlink(path.c_str(), buf.data(), bufsiz); + if (nbytes == -1) { + perror("readlink"); + return std::string(); + } + + return buf.data(); +} + +void ItTimeContainer009(void) +{ + auto timelink = ReadlinkTime(getpid()); + std::cout << "Contents of the time link is: " << timelink << std::endl; + + std::regex reg("'time:\\[[0-9]+\\]'"); + bool ret = std::regex_match(timelink, reg); + ASSERT_TRUE(ret); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_time_container_010.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_time_container_010.cpp new file mode 100644 index 00000000..8807a033 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_time_container_010.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +static int childFunc(void *arg) +{ + int value = *((int*)arg); + if (value != CHILD_FUNC_ARG) { + return EXIT_CODE_ERRNO_1; + } + return 0; +} + +void ItTimeContainer010(void) +{ + int ret; + int status; + char *containerType = "time"; + char *containerType1 = "time_for_children"; + + char *stack = (char *)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0); + ASSERT_NE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + std::cout << getpid() << std::endl; + auto linkBuffer = ReadlinkContainer(getpid(), containerType); + auto linkBuffer1 = ReadlinkContainer(getpid(), containerType1); + ret = linkBuffer.compare(linkBuffer1); + ASSERT_EQ(ret, 0); + + int arg = CHILD_FUNC_ARG; + auto pid = clone(childFunc, stackTop, CLONE_NEWTIME | SIGCHLD, &arg); + ASSERT_TRUE(pid != -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); + + auto linkBuffer2 = ReadlinkContainer(getpid(), containerType); + ret = linkBuffer.compare(linkBuffer2); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_user_container_001.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_user_container_001.cpp new file mode 100644 index 00000000..78d3d900 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_user_container_001.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" +using namespace std; + +const int RETURN_CODE = 2; + +static int childFunc(void *arg) +{ + int value = *((int*)arg); + if (value != CHILD_FUNC_ARG) { + return EXIT_CODE_ERRNO_1; + } + + sleep(1); + return RETURN_CODE; +} + +void ItUserContainer001(void) +{ + int ret; + int arg = CHILD_FUNC_ARG; + auto pid = CloneWrapper(childFunc, CLONE_NEWUSER, &arg); + ASSERT_NE(pid, -1); + + int status; + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, RETURN_CODE); +} + diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_user_container_002.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_user_container_002.cpp new file mode 100644 index 00000000..add03c26 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_user_container_002.cpp @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" +#include "sys/utsname.h" + +const int EXIT_TRUE_CODE = 255; +const int TEST_SET_OLD_ID = 1001; +const int TEST_SET_NEW_ID = 4; +static const int SLEEP_TIME = 3; + +std::string GetIdMapPath(int pid, const std::string& mapType) +{ + std::ostringstream buf; + buf << "/proc/" << pid << "/" << mapType; + return buf.str(); +} + +int WriteIdMap(int pid) +{ + std::string uidMapPath = GetIdMapPath(pid, "uid_map"); + std::string gidMapPath = GetIdMapPath(pid, "gid_map"); + + const char* idMapStr = "0 1000 1\n1 1001 1\n2 1002 1\n3 1003 1\n4 1004 1\n"; + int strLen = strlen(idMapStr); + int uidMap = open(uidMapPath.c_str(), O_WRONLY); + if (uidMap == -1) { + return EXIT_CODE_ERRNO_1; + } + + int ret = write(uidMap, idMapStr, strLen); + if (ret != strLen) { + close(uidMap); + return EXIT_CODE_ERRNO_2; + } + close(uidMap); + + int gidMap = open(gidMapPath.c_str(), O_WRONLY); + if (gidMap == -1) { + close(gidMap); + return EXIT_CODE_ERRNO_3; + } + + ret = write(gidMap, idMapStr, strLen); + if (ret != strLen) { + close(gidMap); + return EXIT_CODE_ERRNO_4; + } + + close(gidMap); + return 0; +} + +static int childFunc(void *arg) +{ + (void)arg; + sleep(SLEEP_TIME); + + int newUid = getuid(); + if (newUid != 1) { + return EXIT_CODE_ERRNO_1; + } + + int newGid = getgid(); + if (newGid != 1) { + return EXIT_CODE_ERRNO_2; + } + + int ret = setuid(TEST_SET_NEW_ID); + if (ret != 0) { + return EXIT_CODE_ERRNO_3; + } + + ret = setgid(TEST_SET_NEW_ID); + if (ret != 0) { + return EXIT_CODE_ERRNO_4; + } + + newUid = getuid(); + if (newUid != TEST_SET_NEW_ID) { + return EXIT_CODE_ERRNO_5; + } + + newGid = getgid(); + if (newGid != TEST_SET_NEW_ID) { + return EXIT_CODE_ERRNO_6; + } + + exit(EXIT_TRUE_CODE); +} + +void ItUserContainer002(void) +{ + int ret = setuid(TEST_SET_OLD_ID); + ASSERT_EQ(ret, 0); + + int oldUid = getuid(); + ASSERT_EQ(oldUid, TEST_SET_OLD_ID); + + ret = setgid(TEST_SET_OLD_ID); + ASSERT_EQ(ret, 0); + + int oldGid = getgid(); + ASSERT_EQ(oldGid, TEST_SET_OLD_ID); + + int arg = CHILD_FUNC_ARG; + auto pid = CloneWrapper(childFunc, CLONE_NEWUSER, &arg); + ASSERT_NE(pid, -1); + + ret = WriteIdMap(pid); + ASSERT_EQ(ret, 0); + + int status; + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + status = WEXITSTATUS(status); + ASSERT_EQ(status, EXIT_TRUE_CODE); + + int oldUid1 = getuid(); + ASSERT_EQ(oldUid1, TEST_SET_OLD_ID); + + int oldGid1 = getgid(); + ASSERT_EQ(oldGid1, TEST_SET_OLD_ID); + + ASSERT_EQ(oldUid, oldUid1); + ASSERT_EQ(oldGid, oldGid1); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_user_container_003.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_user_container_003.cpp new file mode 100644 index 00000000..e46a15bb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_user_container_003.cpp @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" +#include "sys/utsname.h" + +const int EXIT_TRUE_CODE = 255; +const int MAX_PID_RANGE = 100000; +const int TEST_SET_OLD_ID = 1001; +const int TEST_SET_NEW_ID = 4; + +std::string GetIdMapPath(int pid, const std::string& mapType); +int WriteIdMap(int pid); + +static int TestMap(int oldUid, int oldGid) +{ + pid_t pid = getpid(); + int ret = WriteIdMap(pid); + if (ret != 0) { + return EXIT_CODE_ERRNO_6; + } + + int newUid = getuid(); + if (newUid != 1) { + return EXIT_CODE_ERRNO_7; + } + + int newGid = getgid(); + if (newGid != 1) { + return EXIT_CODE_ERRNO_8; + } + + ret = setuid(TEST_SET_NEW_ID); + if (ret != 0) { + return EXIT_CODE_ERRNO_9; + } + + ret = setgid(TEST_SET_NEW_ID); + if (ret != 0) { + return EXIT_CODE_ERRNO_10; + } + + newUid = getuid(); + if (newUid != TEST_SET_NEW_ID) { + return EXIT_CODE_ERRNO_11; + } + + newGid = getgid(); + if (newGid != TEST_SET_NEW_ID) { + exit(1); + } + + if (oldUid == newUid) { + return EXIT_CODE_ERRNO_12; + } + + if (oldGid == newGid) { + return EXIT_CODE_ERRNO_13; + } + return 0; +} + +static int childFunc(void *arg) +{ + (void)arg; + int ret; + int oldUid; + int oldGid; + + ret = setuid(TEST_SET_OLD_ID); + if (ret != 0) { + return EXIT_CODE_ERRNO_1; + } + + oldUid = getuid(); + if (oldUid != TEST_SET_OLD_ID) { + return EXIT_CODE_ERRNO_2; + } + + ret = setgid(TEST_SET_OLD_ID); + if (ret != 0) { + return EXIT_CODE_ERRNO_3; + } + + oldGid = getgid(); + if (oldGid != TEST_SET_OLD_ID) { + return EXIT_CODE_ERRNO_4; + } + + ret = unshare(CLONE_NEWUSER); + if (ret == -1) { + return EXIT_CODE_ERRNO_5; + } + + ret = TestMap(oldUid, oldGid); + if (ret != 0) { + return ret; + } + + exit(EXIT_TRUE_CODE); +} + +void ItUserContainer003(void) +{ + int ret; + int status = 0; + int arg = CHILD_FUNC_ARG; + auto pid = CloneWrapper(childFunc, SIGCHLD, &arg); + ASSERT_NE(pid, -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + status = WEXITSTATUS(status); + ASSERT_EQ(status, EXIT_TRUE_CODE); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_user_container_004.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_user_container_004.cpp new file mode 100644 index 00000000..846667ce --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_user_container_004.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include "It_container_test.h" + +const int EXIT_TRUE_CODE = 255; +const int MAX_PID_RANGE = 100000; + +static int childFunc(void *arg) +{ + (void)arg; + std::string containerType = "user"; + std::string childlink; + std::string filePath; + std::string parentlink1; + int fd; + int ret; + int status; + int parentPid = getpid(); + + auto parentlink = ReadlinkContainer(parentPid, containerType); + int childsPid = CloneWrapper(ChildFunction, CLONE_NEWUSER, NULL); + if (childsPid == -1) { + return EXIT_CODE_ERRNO_1; + } + + childlink = ReadlinkContainer(childsPid, containerType); + filePath = GenContainerLinkPath(childsPid, containerType); + fd = open(filePath.c_str(), O_RDONLY); + if (fd == -1) { + return EXIT_CODE_ERRNO_2; + } + + ret = setns(fd, CLONE_NEWUSER); + if (ret == -1) { + close(fd); + return EXIT_CODE_ERRNO_3; + } + + parentlink1 = ReadlinkContainer(parentPid, containerType); + + close(fd); + + ret = waitpid(childsPid, &status, 0); + if (ret != childsPid) { + return EXIT_CODE_ERRNO_4; + } + + ret = parentlink.compare(parentlink1); + if (ret == 0) { + return EXIT_CODE_ERRNO_5; + } + + ret = parentlink1.compare(childlink); + if (ret != 0) { + return EXIT_CODE_ERRNO_6; + } + + exit(EXIT_TRUE_CODE); +} + +void ItUserContainer004(void) +{ + + int ret; + int status = 0; + int arg = CHILD_FUNC_ARG; + auto pid = CloneWrapper(childFunc, SIGCHLD, &arg); + ASSERT_NE(pid, -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + status = WEXITSTATUS(status); + ASSERT_EQ(status, EXIT_TRUE_CODE); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_user_container_006.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_user_container_006.cpp new file mode 100644 index 00000000..4aeb45dd --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_user_container_006.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "It_container_test.h" + +static int const configLen = 16; +static const int MAX_CONTAINER = 10; +static const int g_buffSize = 512; +static const int g_arryLen = 4; +static const int g_readLen = 254; + +static int childFunc(void *arg) +{ + (void)arg; + sleep(2); /* 2: delay 2s */ + + return 0; +} + +void ItUserContainer006(void) +{ + std::string path = "/proc/sys/user/max_user_container"; + char *array[g_arryLen] = { nullptr }; + char buf[g_buffSize] = { 0 }; + + int ret = ReadFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + GetLine(buf, g_arryLen, g_readLen, array); + + int value = atoi(array[1] + strlen("limit: ")); + ASSERT_EQ(value, MAX_CONTAINER); + + int usedCount = atoi(array[2] + strlen("count: ")); + + (void)memset_s(buf, configLen, 0, configLen); + ret = sprintf_s(buf, configLen, "%d", usedCount + 1); + ASSERT_GT(ret, 0); + + ret = WriteFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, + -1, 0); + ASSERT_NE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + + auto pid1 = clone(childFunc, stackTop, CLONE_NEWUSER, NULL); + ASSERT_NE(pid1, -1); + + auto pid2 = clone(childFunc, stackTop, CLONE_NEWUSER, NULL); + ASSERT_EQ(pid2, -1); + + ret = waitpid(pid1, NULL, 0); + ASSERT_EQ(ret, pid1); + + (void)memset_s(buf, configLen, 0, configLen); + ret = sprintf_s(buf, configLen, "%d", value); + ASSERT_GT(ret, 0); + + ret = WriteFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + (void)memset_s(buf, configLen, 0, configLen); + ret = ReadFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + GetLine(buf, g_arryLen, g_readLen, array); + + value = atoi(array[1] + strlen("limit: ")); + ASSERT_EQ(value, MAX_CONTAINER); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_user_container_007.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_user_container_007.cpp new file mode 100644 index 00000000..f66c16d7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_user_container_007.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "It_container_test.h" + +static int const configLen = 16; +static const int MAX_CONTAINER = 10; +static const int g_buffSize = 512; +static const int g_arryLen = 4; +static const int g_readLen = 254; + +static int childFunc(void *arg) +{ + (void)arg; + + int ret = unshare(CLONE_NEWUSER); + if (ret != 0) { + return EXIT_CODE_ERRNO_1; + } + return 0; +} + +void ItUserContainer007(void) +{ + std::string path = "/proc/sys/user/max_user_container"; + char *array[g_arryLen] = { nullptr }; + char buf[g_buffSize] = { 0 }; + int status = 0; + + int ret = ReadFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + GetLine(buf, g_arryLen, g_readLen, array); + + int value = atoi(array[1] + strlen("limit: ")); + ASSERT_EQ(value, MAX_CONTAINER); + + int usedCount = atoi(array[2] + strlen("count: ")); + + (void)memset_s(buf, configLen, 0, configLen); + ret = sprintf_s(buf, configLen, "%d", usedCount + 1); + ASSERT_GT(ret, 0); + + ret = WriteFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, + -1, 0); + ASSERT_NE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + + auto pid1 = clone(childFunc, stackTop, CLONE_NEWUSER, NULL); + ASSERT_NE(pid1, -1); + + ret = waitpid(pid1, &status, 0); + ASSERT_EQ(ret, pid1); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, EXIT_CODE_ERRNO_1); + + (void)memset_s(buf, configLen, 0, configLen); + ret = sprintf_s(buf, configLen, "%d", value); + ASSERT_GT(ret, 0); + + ret = WriteFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + (void)memset_s(buf, configLen, 0, configLen); + ret = ReadFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + GetLine(buf, g_arryLen, g_readLen, array); + + value = atoi(array[1] + strlen("limit: ")); + ASSERT_EQ(value, MAX_CONTAINER); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_uts_container_001.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_uts_container_001.cpp new file mode 100644 index 00000000..7129f6fb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_uts_container_001.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +static int ChildFunc(void *arg) +{ + int value = *((int*)arg); + if (value != CHILD_FUNC_ARG) { + return EXIT_CODE_ERRNO_1; + } + return EXIT_CODE_ERRNO_2; +} + +void ItUtsContainer001(void) +{ + int ret; + + int arg = CHILD_FUNC_ARG; + auto pid = CloneWrapper(ChildFunc, CLONE_NEWUTS, &arg); + ASSERT_NE(pid, -1); + + int status; + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, EXIT_CODE_ERRNO_2); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_uts_container_002.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_uts_container_002.cpp new file mode 100644 index 00000000..1509334c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_uts_container_002.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" +#include "sys/utsname.h" + +static int ChildFunc(void *arg) +{ + int ret; + int value = *((int*)arg); + if (value != CHILD_FUNC_ARG) { + return EXIT_CODE_ERRNO_1; + } + sleep(1); + + struct utsname newName; + ret = uname(&newName); + if (ret != 0) { + return EXIT_CODE_ERRNO_2; + } + + const char *name = "TestHostName"; + ret = sethostname(name, strlen(name)); + if (ret != 0) { + return EXIT_CODE_ERRNO_3; + } + + struct utsname newName1; + ret = uname(&newName1); + if (ret != 0) { + return EXIT_CODE_ERRNO_4; + } + + ret = strcmp(newName.nodename, newName1.nodename); + if (ret == 0) { + return EXIT_CODE_ERRNO_5; + } + + return 0; +} + +void ItUtsContainer002(void) +{ + int ret; + char *stack = (char*)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); + ASSERT_TRUE(stack != NULL); + char *stackTop = stack + STACK_SIZE; + + struct utsname oldName; + ret = uname(&oldName); + ASSERT_EQ(ret, 0); + + int arg = CHILD_FUNC_ARG; + auto pid = clone(ChildFunc, stackTop, CLONE_NEWUTS, &arg); + (void)munmap(stack, STACK_SIZE); + ASSERT_NE(pid, -1); + + int status; + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); + + struct utsname oldName1; + ret = uname(&oldName1); + ASSERT_EQ(ret, 0); + + ret = strcmp(oldName.nodename, oldName1.nodename); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_uts_container_004.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_uts_container_004.cpp new file mode 100644 index 00000000..8171a0a6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_uts_container_004.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" +#include "sys/utsname.h" + +static int ChildFunc(void *arg) +{ + (void)arg; + int ret; + + ret = unshare(CLONE_NEWUTS); + if (ret != 0) { + return EXIT_CODE_ERRNO_1; + } + + struct utsname newName; + ret = uname(&newName); + if (ret != 0) { + return EXIT_CODE_ERRNO_2; + } + + const char *name = "TestHostName"; + ret = sethostname(name, strlen(name)); + if (ret != 0) { + return EXIT_CODE_ERRNO_3; + } + + struct utsname newName1; + ret = uname(&newName1); + if (ret != 0) { + return EXIT_CODE_ERRNO_4; + } + + ret = strcmp(newName.nodename, newName1.nodename); + if (ret == 0) { + return EXIT_CODE_ERRNO_5; + } + + return 0; +} + +void ItUtsContainer004(void) +{ + int ret; + char *stack = (char *)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0); + ASSERT_TRUE(stack != NULL); + char *stackTop = stack + STACK_SIZE; + struct utsname oldName; + + ret = uname(&oldName); + ASSERT_EQ(ret, 0); + + auto pid = clone(ChildFunc, stackTop, SIGCHLD, NULL); + (void)munmap(stack, STACK_SIZE); + ASSERT_NE(pid, -1); + + int status; + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); + + struct utsname oldName1; + ret = uname(&oldName1); + ASSERT_EQ(ret, 0); + + ret = strcmp(oldName.nodename, oldName1.nodename); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_uts_container_005.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_uts_container_005.cpp new file mode 100644 index 00000000..e9f4a7b8 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_uts_container_005.cpp @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +const int TIMER_INTERVAL_3S = 2; + +static int ChildFun(void *p) +{ + (void)p; + sleep(TIMER_INTERVAL_3S); + return EXIT_CODE_ERRNO_3; +} + +static int UtsContainerTest(void *arg) +{ + (void)arg; + pid_t callerPid; + int childPid; + int fd = -1; + int ret, status, setFlag; + char targetpath[100]; + const char *containerType = "uts"; + + callerPid = getpid(); + childPid = clone(ChildFun, NULL, CLONE_NEWUTS | SIGCHLD, NULL); + if (childPid == -1) { + return EXIT_CODE_ERRNO_1; + } + + auto linkBuffer1 = ReadlinkContainer(callerPid, containerType); + if (linkBuffer1.c_str() == NULL) { + return EXIT_CODE_ERRNO_2; + } + + ret = sprintf_s(targetpath, sizeof(targetpath), "/proc/%d/container/uts", childPid); + if (ret == -1) { + return EXIT_CODE_ERRNO_4; + } + + fd = open(targetpath, O_RDONLY | O_CLOEXEC); + if (fd == -1) { + return EXIT_CODE_ERRNO_5; + } + + setFlag = CLONE_NEWUTS; + ret = setns(fd, setFlag); + (void)close(fd); + if (ret == -1) { + return EXIT_CODE_ERRNO_6; + } + + auto linkBuffer2 = ReadlinkContainer(callerPid, containerType); + + ret = linkBuffer2.compare(linkBuffer1); + if (ret == 0) { + return EXIT_CODE_ERRNO_7; + } + + ret = waitpid(childPid, &status, 0); + if (ret != childPid) { + return EXIT_CODE_ERRNO_8; + } + + int exitCode = WEXITSTATUS(status); + if (exitCode != EXIT_CODE_ERRNO_3) { + return EXIT_CODE_ERRNO_9; + } + + ret = setns(fd, setFlag); + if (ret != -1) { + return EXIT_CODE_ERRNO_10; + } + return 0; +} + +void ItUtsContainer005(void) +{ + int ret; + + int arg = CHILD_FUNC_ARG; + auto pid = CloneWrapper(UtsContainerTest, CLONE_NEWUTS, &arg); + ASSERT_NE(pid, -1); + + int status; + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_uts_container_006.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_uts_container_006.cpp new file mode 100644 index 00000000..d7bf8d0f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_uts_container_006.cpp @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +static int UtsContainerTest(void *arg) +{ + (void)arg; + std::string containerType = "uts"; + + int parentPid = getpid(); + auto parentlink = ReadlinkContainer(parentPid, containerType); + + int childsPid = CloneWrapper(ChildFunction, CLONE_NEWUTS, NULL); + if (childsPid == -1) { + return EXIT_CODE_ERRNO_1; + } + auto childlink = ReadlinkContainer(childsPid, containerType); + + std::string filePath = GenContainerLinkPath(childsPid, containerType); + int fd = open(filePath.c_str(), O_RDONLY); + if (fd == -1) { + return EXIT_CODE_ERRNO_2; + } + + int ret = setns(fd, CLONE_NEWUTS); + (void)close(fd); + if (ret == -1) { + return EXIT_CODE_ERRNO_3; + } + + auto parentlink1 = ReadlinkContainer(parentPid, containerType); + + ret = parentlink.compare(parentlink1); + if (ret == 0) { + return EXIT_CODE_ERRNO_4; + } + ret = parentlink1.compare(childlink); + if (ret != 0) { + return EXIT_CODE_ERRNO_5; + } + + int status; + ret = waitpid(childsPid, &status, 0); + if (ret != childsPid) { + return EXIT_CODE_ERRNO_6; + } + + int exitCode = WEXITSTATUS(status); + if (exitCode != 0) { + return EXIT_CODE_ERRNO_7; + } + return 0; +} + +void ItUtsContainer006(void) +{ + int ret; + + int arg = CHILD_FUNC_ARG; + auto pid = CloneWrapper(UtsContainerTest, CLONE_NEWUTS, &arg); + ASSERT_NE(pid, -1); + + int status; + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_uts_container_007.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_uts_container_007.cpp new file mode 100644 index 00000000..2e7bb30f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_uts_container_007.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "It_container_test.h" + +static int const configLen = 16; +static const int MAX_CONTAINER = 10; +static const int g_buffSize = 512; +static const int g_arryLen = 4; +static const int g_readLen = 254; + +static int childFunc(void *arg) +{ + (void)arg; + sleep(2); /* 2: delay 2s */ + + return 0; +} + +void ItUtsContainer007(void) +{ + std::string path = "/proc/sys/user/max_uts_container"; + char *array[g_arryLen] = { nullptr }; + char buf[g_buffSize] = { 0 }; + + int ret = ReadFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + GetLine(buf, g_arryLen, g_readLen, array); + + int value = atoi(array[1] + strlen("limit: ")); + ASSERT_EQ(value, MAX_CONTAINER); + + int usedCount = atoi(array[2] + strlen("count: ")); + + (void)memset_s(buf, configLen, 0, configLen); + ret = sprintf_s(buf, configLen, "%d", usedCount + 1); + ASSERT_GT(ret, 0); + + ret = WriteFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, + -1, 0); + ASSERT_NE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + + auto pid1 = clone(childFunc, stackTop, CLONE_NEWUTS, NULL); + ASSERT_NE(pid1, -1); + + auto pid2 = clone(childFunc, stackTop, CLONE_NEWUTS, NULL); + ASSERT_EQ(pid2, -1); + + ret = waitpid(pid1, NULL, 0); + ASSERT_EQ(ret, pid1); + + (void)memset_s(buf, configLen, 0, configLen); + ret = sprintf_s(buf, configLen, "%d", value); + ASSERT_GT(ret, 0); + + ret = WriteFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + (void)memset_s(buf, configLen, 0, configLen); + ret = ReadFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + GetLine(buf, g_arryLen, g_readLen, array); + + value = atoi(array[1] + strlen("limit: ")); + ASSERT_EQ(value, MAX_CONTAINER); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_uts_container_008.cpp b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_uts_container_008.cpp new file mode 100644 index 00000000..d5cc7c34 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/container/smoke/It_uts_container_008.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "It_container_test.h" + +static int const configLen = 16; +static const int MAX_CONTAINER = 10; +static const int g_buffSize = 512; +static const int g_arryLen = 4; +static const int g_readLen = 254; + +static int childFunc(void *arg) +{ + (void)arg; + + int ret = unshare(CLONE_NEWUTS); + if (ret != 0) { + return EXIT_CODE_ERRNO_1; + } + return 0; +} + +void ItUtsContainer008(void) +{ + std::string path = "/proc/sys/user/max_uts_container"; + char *array[g_arryLen] = { nullptr }; + char buf[g_buffSize] = { 0 }; + int status = 0; + + int ret = ReadFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + GetLine(buf, g_arryLen, g_readLen, array); + + int value = atoi(array[1] + strlen("limit: ")); + ASSERT_EQ(value, MAX_CONTAINER); + + int usedCount = atoi(array[2] + strlen("count: ")); + + (void)memset_s(buf, configLen, 0, configLen); + ret = sprintf_s(buf, configLen, "%d", usedCount + 1); + ASSERT_GT(ret, 0); + + ret = WriteFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, + -1, 0); + ASSERT_NE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + + auto pid1 = clone(childFunc, stackTop, CLONE_NEWUTS, NULL); + ASSERT_NE(pid1, -1); + + ret = waitpid(pid1, &status, 0); + ASSERT_EQ(ret, pid1); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, EXIT_CODE_ERRNO_1); + + (void)memset_s(buf, configLen, 0, configLen); + ret = sprintf_s(buf, configLen, "%d", value); + ASSERT_GT(ret, 0); + + ret = WriteFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + (void)memset_s(buf, configLen, 0, configLen); + ret = ReadFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + GetLine(buf, g_arryLen, g_readLen, array); + + value = atoi(array[1] + strlen("limit: ")); + ASSERT_EQ(value, MAX_CONTAINER); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/drivers/BUILD.gn b/src/kernel_liteos_a/testsuites/unittest/drivers/BUILD.gn new file mode 100644 index 00000000..eb3d7c4f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/drivers/BUILD.gn @@ -0,0 +1,56 @@ +# Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("./config.gni") + +if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_LOW) { + unittest("liteos_a_drivers_unittest_door") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + include_dirs = common_include_dirs + sources = sources_entry + sources += sources_smoke + sources_full = [] + sources += sources_full + configs = [ "..:public_config_for_door" ] + deps = [ "$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR:libsec_shared" ] + } +} + +if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_MIDDLE) { + unittest("liteos_a_drivers_unittest") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + include_dirs = common_include_dirs + sources = sources_entry + sources += sources_smoke + sources += sources_full + configs = [ "..:public_config_for_all" ] + deps = [ "$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR:libsec_shared" ] + } +} diff --git a/src/kernel_liteos_a/testsuites/unittest/drivers/config.gni b/src/kernel_liteos_a/testsuites/unittest/drivers/config.gni new file mode 100644 index 00000000..161d42fe --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/drivers/config.gni @@ -0,0 +1,60 @@ +# Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//build/lite/config/test.gni") +import("//kernel/liteos_a/liteos.gni") +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +common_include_dirs = [ + "$THIRDPARTY_GOOGLETEST_DIR/googletest/include", + "../common/include", +] + +sources_entry = [ "../common/osTest.cpp" ] + +sources_smoke = [] + +sources_full = [] + +# hid module +if (LOSCFG_USER_TEST_DRIVERS_HID == true) { + import("./hid/config.gni") + common_include_dirs += hid_include_dirs + sources_entry += hid_sources_entry + sources_smoke += hid_sources_smoke + sources_full += hid_sources_full +} + +# storage module +if (LOSCFG_USER_TEST_DRIVERS_STORAGE == true) { + import("./storage/config.gni") + common_include_dirs += storage_include_dirs + sources_entry += storage_sources_entry + sources_smoke += storage_sources_smoke + sources_full += storage_sources_full +} diff --git a/src/kernel_liteos_a/testsuites/unittest/drivers/hid/config.gni b/src/kernel_liteos_a/testsuites/unittest/drivers/hid/config.gni new file mode 100644 index 00000000..90042d36 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/drivers/hid/config.gni @@ -0,0 +1,37 @@ +# Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +hid_include_dirs = [ "$TEST_UNITTEST_DIR/drivers/hid" ] + +hid_sources_entry = [ "$TEST_UNITTEST_DIR/drivers/hid/drivers_hid_test.cpp" ] + +hid_sources_smoke = [ "$TEST_UNITTEST_DIR/drivers/hid/smoke/hid_test_001.cpp" ] + +hid_sources_full = [] diff --git a/src/kernel_liteos_a/testsuites/unittest/drivers/hid/drivers_hid_test.cpp b/src/kernel_liteos_a/testsuites/unittest/drivers/hid/drivers_hid_test.cpp new file mode 100644 index 00000000..d2513386 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/drivers/hid/drivers_hid_test.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include "it_test_hid.h" + +using namespace testing::ext; +namespace OHOS { +class DriversHidTest : public testing::Test { +public: + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} +}; + +#if defined(LOSCFG_USER_TEST_SMOKE) +/* * + * @tc.name: it_test_hid_001 + * @tc.desc: function for drivers hid + * @tc.type: FUNC + */ +HWTEST_F(DriversHidTest, ItTestHid001, TestSize.Level0) +{ + ItTestHid001(); +} +#endif +} // namespace OHOS diff --git a/src/kernel_liteos_a/testsuites/unittest/drivers/hid/it_test_hid.h b/src/kernel_liteos_a/testsuites/unittest/drivers/hid/it_test_hid.h new file mode 100644 index 00000000..e948b349 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/drivers/hid/it_test_hid.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _IT_TEST_DRIVERS_HID_H +#define _IT_TEST_DRIVERS_HID_H + +#include "osTest.h" +#include "poll.h" + +extern void ItTestHid001(void); + +#endif diff --git a/src/kernel_liteos_a/testsuites/unittest/drivers/hid/smoke/hid_test_001.cpp b/src/kernel_liteos_a/testsuites/unittest/drivers/hid/smoke/hid_test_001.cpp new file mode 100644 index 00000000..8ddeb4f7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/drivers/hid/smoke/hid_test_001.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_hid.h" +#include "fcntl.h" +#include "sys/ioctl.h" + +#define MOUSE_DEV_PATH "/dev/usb/uhid0" +#define MOUSE_DATA_LEN 5 +#define MOUSE_TEST_COUNT 20 +#define MOUSE_WAIT_TIME 1000 + +#define USB_GET_REPORT_ID _IOR('U', 25, int) + +static int Testcase(VOID) +{ + int ret; + int fd = -1; + int i; + struct pollfd pfds[1]; + char *buf = NULL; + int id = -1; + + ret = access(MOUSE_DEV_PATH, 0); + if (!ret) { + fd = open(MOUSE_DEV_PATH, O_RDWR, 0666); + ICUNIT_ASSERT_NOT_EQUAL(fd, -1, fd); + + buf = static_cast(malloc(MOUSE_DATA_LEN)); + ICUNIT_ASSERT_NOT_EQUAL(buf, NULL, buf); + ret = memset_s(buf, MOUSE_DATA_LEN, 0, MOUSE_DATA_LEN); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = ioctl(fd, USB_GET_REPORT_ID, &id); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(id, 0, id); + + printf("Reading mouse data ... \n"); + for (i = 0; i < MOUSE_TEST_COUNT; i++) { + pfds[0].fd = fd; + pfds[0].events = POLLIN; + + ret = poll(pfds, 1, MOUSE_WAIT_TIME); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret); + + if (ret == 0) { + continue; + } else { + printf("read ...\n"); + read(fd, buf, MOUSE_DATA_LEN); + printf("mouse data [%#x %#x %#x %#x]\n", buf[0], buf[1], buf[2], buf[3]); + } + } + ret = close(fd); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + free(buf); + } + + return 0; +} + +void ItTestHid001(void) +{ + TEST_ADD_CASE("IT_DRIVERS_HID_001", Testcase, TEST_LOS, TEST_DRIVERBASE, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/drivers/storage/config.gni b/src/kernel_liteos_a/testsuites/unittest/drivers/storage/config.gni new file mode 100644 index 00000000..08eaf8eb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/drivers/storage/config.gni @@ -0,0 +1,39 @@ +# Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +storage_include_dirs = [ "$TEST_UNITTEST_DIR/drivers/storage" ] + +storage_sources_entry = + [ "$TEST_UNITTEST_DIR/drivers/storage/drivers_storage_test.cpp" ] + +storage_sources_smoke = + [ "$TEST_UNITTEST_DIR/drivers/storage/smoke/storage_test_001.cpp" ] + +storage_sources_full = [] diff --git a/src/kernel_liteos_a/testsuites/unittest/drivers/storage/drivers_storage_test.cpp b/src/kernel_liteos_a/testsuites/unittest/drivers/storage/drivers_storage_test.cpp new file mode 100644 index 00000000..908bc61a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/drivers/storage/drivers_storage_test.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include "it_test_storage.h" + +using namespace testing::ext; +namespace OHOS { +class DriversStorageTest : public testing::Test { +public: + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} +}; + +#if defined(LOSCFG_USER_TEST_SMOKE) +/* * + * @tc.name: it_test_storage_001 + * @tc.desc: function for drivers storage + * @tc.type: FUNC + */ +HWTEST_F(DriversStorageTest, ItTestStorage001, TestSize.Level0) +{ + ItTestStorage001(); +} +#endif +} // namespace OHOS diff --git a/src/kernel_liteos_a/testsuites/unittest/drivers/storage/it_test_storage.h b/src/kernel_liteos_a/testsuites/unittest/drivers/storage/it_test_storage.h new file mode 100644 index 00000000..5c1ab777 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/drivers/storage/it_test_storage.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _IT_TEST_DRIVERS_STORAGE_H +#define _IT_TEST_DRIVERS_STORAGE_H + +#include "osTest.h" +#include "poll.h" + +extern void ItTestStorage001(void); + +#endif diff --git a/src/kernel_liteos_a/testsuites/unittest/drivers/storage/smoke/storage_test_001.cpp b/src/kernel_liteos_a/testsuites/unittest/drivers/storage/smoke/storage_test_001.cpp new file mode 100644 index 00000000..62e48e1e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/drivers/storage/smoke/storage_test_001.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_storage.h" +#include "fcntl.h" +#include "sys/ioctl.h" + +#define STORAGE_DEV_PATH "/dev/sdap0" +#define STORAGE_DATA_LEN 32 +#define DIOC_GETPRIV 0x1000 +#define INVALID_PTR 0x11111111 + +static int Testcase(VOID) +{ + int ret; + int fd = -1; + int i; + ssize_t n; + char *buf = NULL; + void *bch = NULL; + + ret = access(STORAGE_DEV_PATH, 0); + if (!ret) { + fd = open(STORAGE_DEV_PATH, O_RDWR, 0666); + ICUNIT_ASSERT_NOT_EQUAL(fd, -1, fd); + + buf = static_cast(malloc(STORAGE_DATA_LEN)); + ICUNIT_ASSERT_NOT_EQUAL(buf, NULL, buf); + ret = memset_s(buf, STORAGE_DATA_LEN, 0, STORAGE_DATA_LEN); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = ioctl(fd, DIOC_GETPRIV, &bch); + printf("bch = %#x, &bch = %#x, errno = %d\n", bch, &bch, errno); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret); + + + printf("Reading storage data ... \n"); + n = read(fd, buf, STORAGE_DATA_LEN); + ICUNIT_ASSERT_EQUAL(n, STORAGE_DATA_LEN, n); + printf("storage data [%#x %#x %#x %#x]\n", buf[0], buf[1], buf[2], buf[3]); + + n = read(fd, (void *)INVALID_PTR, STORAGE_DATA_LEN); + ICUNIT_ASSERT_NOT_EQUAL(n, STORAGE_DATA_LEN, n); + + ret = close(fd); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + free(buf); + } + + return 0; +} + +void ItTestStorage001(void) +{ + TEST_ADD_CASE("IT_DRIVERS_STORAGE_001", Testcase, TEST_LOS, TEST_DRIVERBASE, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/BUILD.gn b/src/kernel_liteos_a/testsuites/unittest/extended/BUILD.gn new file mode 100644 index 00000000..f57067ae --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/BUILD.gn @@ -0,0 +1,56 @@ +# Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("./config.gni") + +if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_LOW) { + unittest("liteos_a_extended_unittest_door") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + include_dirs = common_include_dirs + sources = sources_entry + sources += sources_smoke + sources_full = [] + sources += sources_full + configs = [ "..:public_config_for_door" ] + deps = [ "$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR:libsec_shared" ] + } +} + +if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_MIDDLE) { + unittest("liteos_a_extended_unittest") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + include_dirs = common_include_dirs + sources = sources_entry + sources += sources_smoke + sources += sources_full + configs = [ "..:public_config_for_all" ] + deps = [ "$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR:libsec_shared" ] + } +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/config.gni b/src/kernel_liteos_a/testsuites/unittest/extended/config.gni new file mode 100644 index 00000000..3a341b62 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/config.gni @@ -0,0 +1,78 @@ +# Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//build/lite/config/test.gni") +import("//kernel/liteos_a/liteos.gni") +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +common_include_dirs = [ + "$THIRDPARTY_GOOGLETEST_DIR/googletest/include", + "../common/include", +] + +sources_entry = [ "../common/osTest.cpp" ] + +sources_smoke = [] + +sources_full = [] + +# ipc module +if (LOSCFG_USER_TEST_IPC == true) { + import("./ipc/config.gni") + common_include_dirs += ipc_include_dirs + sources_entry += ipc_sources_entry + sources_smoke += ipc_sources_smoke + sources_full += ipc_sources_full +} + +# liteipc module +if (LOSCFG_USER_TEST_LITEIPC == true) { + import("./liteipc/config.gni") + common_include_dirs += liteipc_include_dirs + sources_entry += liteipc_sources_entry + sources_smoke += liteipc_sources_smoke + sources_full += liteipc_sources_full +} + +# signal module +if (LOSCFG_USER_TEST_SIGNAL == true) { + import("./signal/config.gni") + common_include_dirs += signal_include_dirs + sources_entry += signal_sources_entry + sources_smoke += signal_sources_smoke + sources_full += signal_sources_full +} + +# trace module +if (LOSCFG_USER_TEST_TRACE == true) { + import("./trace/config.gni") + common_include_dirs += trace_include_dirs + sources_entry += trace_sources_entry + sources_smoke += trace_sources_smoke + sources_full += trace_sources_full +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/ipc/It_test_IPC.h b/src/kernel_liteos_a/testsuites/unittest/extended/ipc/It_test_IPC.h new file mode 100644 index 00000000..c9fd393f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/ipc/It_test_IPC.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _IT_TEST_IPC_H +#define _IT_TEST_IPC_H + +#include "osTest.h" +#include "stdio.h" +#include "stdlib.h" +#include "unistd.h" +#include "string.h" +#include "termios.h" +#include "sys/types.h" +#include "sys/stat.h" +#include "fcntl.h" +#include "locale.h" +#include "wctype.h" +#include "wchar.h" +#include "stdarg.h" +#include "semaphore.h" +#include "ftw.h" +#include "aio.h" +#include "shadow.h" +#include "pty.h" +#include "dirent.h" +#include "poll.h" +#include "grp.h" +#include "pwd.h" +#include "sys/uio.h" +#include "syslog.h" + +extern int CloseRmAllFile(int fd[], char filePathName[][50], int cnt); +extern char *g_IoTestPath; + +extern VOID IPC_TEST_MKFIFOAT_001(VOID); +extern VOID IPC_TEST_MKFIFOAT_002(VOID); + +#endif diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/ipc/config.gni b/src/kernel_liteos_a/testsuites/unittest/extended/ipc/config.gni new file mode 100644 index 00000000..970d7016 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/ipc/config.gni @@ -0,0 +1,40 @@ +# Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +ipc_include_dirs = [ "$TEST_UNITTEST_DIR/extended/ipc" ] + +ipc_sources_entry = [ "$TEST_UNITTEST_DIR/extended/ipc/ipc_test.cpp" ] + +ipc_sources_smoke = [] + +ipc_sources_full = [ + "$TEST_UNITTEST_DIR/extended/ipc/full/ipc_test_mkfifoat_001.cpp", + "$TEST_UNITTEST_DIR/extended/ipc/full/ipc_test_mkfifoat_002.cpp", +] diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/ipc/full/ipc_test_mkfifoat_001.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/ipc/full/ipc_test_mkfifoat_001.cpp new file mode 100644 index 00000000..ae69b882 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/ipc/full/ipc_test_mkfifoat_001.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_IPC.h" +#include +#include + +#define PATHNAME_FIFO "./fifo.test" +#define PATHNAME_FIFO_FULL "/dev/fifo.test" + +static UINT32 testcase1(VOID) +{ + int ret = 0; + char *dirname = "/dev"; + DIR *dir = NULL; + int fdDir = 0; + + errno = 0; + dir = opendir(dirname); + fdDir = dirfd(dir); + TEST_PRINT("[INFO]%s:%d,%s,fdDir=%d,errno=%d,errstr=%s\n", __FILE__, __LINE__, __func__, fdDir, errno, strerror(errno)); + ICUNIT_GOTO_NOT_EQUAL(fdDir, -1, fdDir, OUT); + + errno = 0; + ret = mkfifoat(fdDir, PATHNAME_FIFO, 0777); + TEST_PRINT("[INFO]%s:%d,%s,ret=%d,errno=%d,errstr=%s\n", __FILE__, __LINE__, __func__, ret, errno, strerror(errno)); + ICUNIT_GOTO_EQUAL(ret, 0, ret, OUT); + ICUNIT_GOTO_EQUAL(errno, 0, errno, OUT); + + /* remove the pipe file created in order to ensure to run the testcase again. */ + errno = 0; + ret = remove(PATHNAME_FIFO_FULL); + TEST_PRINT("[INFO]%s:%d,%s,ret=%d,errno=%d,errstr=%s\n", __FILE__, __LINE__, __func__, ret, errno, strerror(errno)); + ICUNIT_GOTO_EQUAL(ret, 0, ret, OUT); + ICUNIT_GOTO_EQUAL(errno, 0, errno, OUT); + + close(fdDir); + return LOS_OK; +OUT: + close(fdDir); + return LOS_NOK; +} + +static UINT32 testcase(VOID) +{ + testcase1(); + + return LOS_OK; +} + +VOID IPC_TEST_MKFIFOAT_001(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/ipc/full/ipc_test_mkfifoat_002.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/ipc/full/ipc_test_mkfifoat_002.cpp new file mode 100644 index 00000000..8432e140 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/ipc/full/ipc_test_mkfifoat_002.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_IPC.h" +#include +#include + +#define PATHNAME_FIFO "./fifo.test" +#define PATHNAME_FIFO_FULL "/dev/fifo.test" +#define PATHNAME_ENOTDIR FILEPATH_775 + +static UINT32 testcase1(VOID) +{ + int ret = 0; + int fdDir = 0; + + errno = 0; + fdDir = open(PATHNAME_ENOTDIR, O_RDWR, 0666); + TEST_PRINT("[INFO]%s:%d,%s,fdDir=%d,errno=%d,errstr=%s\n", __FILE__, __LINE__, __func__, fdDir, errno, strerror(errno)); + ICUNIT_GOTO_NOT_EQUAL(fdDir, -1, fdDir, OUT); + ICUNIT_GOTO_EQUAL(errno, 0, errno, OUT); + + errno = 0; + ret = mkfifoat(fdDir, PATHNAME_FIFO, 0777); + TEST_PRINT("[INFO]%s:%d,%s,ret=%d,errno=%d,errstr=%s\n", __FILE__, __LINE__, __func__, ret, errno, strerror(errno)); + ICUNIT_GOTO_EQUAL(ret, -1, ret, OUT); + ICUNIT_GOTO_EQUAL(errno, ENOTDIR, errno, OUT); + + close(fdDir); + return LOS_OK; +OUT: + close(fdDir); + return LOS_NOK; +} + +static UINT32 testcase(VOID) +{ + testcase1(); + + return LOS_OK; +} + +VOID IPC_TEST_MKFIFOAT_002(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/ipc/ipc_test.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/ipc/ipc_test.cpp new file mode 100644 index 00000000..4fb45462 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/ipc/ipc_test.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include + +#include "It_test_IPC.h" + +using namespace testing::ext; +namespace OHOS { +class IoTest : public testing::Test { +public: + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} +}; +} // namespace OHOS diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/liteipc/config.gni b/src/kernel_liteos_a/testsuites/unittest/extended/liteipc/config.gni new file mode 100644 index 00000000..1bb6432a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/liteipc/config.gni @@ -0,0 +1,43 @@ +# Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +liteipc_include_dirs = [ "$TEST_UNITTEST_DIR/extended/liteipc" ] + +liteipc_sources_entry = [ + "$TEST_UNITTEST_DIR/extended/liteipc/smgr_demo.cpp", + "$TEST_UNITTEST_DIR/extended/liteipc/it_test_liteipc.cpp", +] + +liteipc_sources_smoke = [ + "$TEST_UNITTEST_DIR/extended/liteipc/smoke/liteipc_test_001.cpp", + "$TEST_UNITTEST_DIR/extended/liteipc/smoke/liteipc_test_002.cpp", +] + +liteipc_sources_full = [] diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/liteipc/it_test_liteipc.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/liteipc/it_test_liteipc.cpp new file mode 100644 index 00000000..43697074 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/liteipc/it_test_liteipc.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "it_test_liteipc.h" + +using namespace testing::ext; +namespace OHOS { +class LiteIpcTest : public testing::Test { +public: + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} +}; + +/* * + * @tc.name: ItPosixLiteIpc001 + * @tc.desc: function test for liteipc + * @tc.type: FUNC + */ +HWTEST_F(LiteIpcTest, ItPosixLiteIpc001, TestSize.Level0) +{ + ItPosixLiteIpc001(); +} + +/* * + * @tc.name: ItPosixLiteIpc002 + * @tc.desc: function test for liteipc + * @tc.type: FUNC + */ +HWTEST_F(LiteIpcTest, ItPosixLiteIpc002, TestSize.Level0) +{ + ItPosixLiteIpc002(); +} +} \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/liteipc/it_test_liteipc.h b/src/kernel_liteos_a/testsuites/unittest/extended/liteipc/it_test_liteipc.h new file mode 100644 index 00000000..586f0dc3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/liteipc/it_test_liteipc.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _IT_TEST_LITEIPC_H +#define _IT_TEST_LITEIPC_H + +#include "osTest.h" +#include "sys/resource.h" + +#define USE_TIMESTAMP 1 + +extern void ItPosixLiteIpc001(void); +extern void ItPosixLiteIpc002(void); + +#endif diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/liteipc/liteipc.h b/src/kernel_liteos_a/testsuites/unittest/extended/liteipc/liteipc.h new file mode 100644 index 00000000..528a09e3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/liteipc/liteipc.h @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LITEIPC_H +#define _LITEIPC_H + +#include + +#define LITEIPC_DRIVER "/dev/lite_ipc" + +typedef enum { OBJ_FD, OBJ_PTR, OBJ_SVC } ObjType; + +typedef struct { + uint32_t buffSz; + void *buff; +} BuffPtr; + +typedef struct { + uint32_t handle; + uint32_t token; + uint32_t cookie; +} SvcIdentity; + +typedef union { + uint32_t fd; + BuffPtr ptr; + SvcIdentity svc; +} ObjContent; + +typedef struct { + ObjType type; + ObjContent content; +} SpecialObj; + +typedef enum { MT_REQUEST, MT_REPLY, MT_FAILED_REPLY, MT_DEATH_NOTIFY } MsgType; +typedef enum { CMS_GEN_HANDLE, CMS_REMOVE_HANDLE, CMS_ADD_ACCESS } CmsCmd; + +/* lite ipc ioctl */ +#define IPC_IOC_MAGIC 'i' +#define IPC_SET_CMS _IO(IPC_IOC_MAGIC, 1) +#define IPC_CMS_CMD _IOWR(IPC_IOC_MAGIC, 2, CmsCmdContent) +#define IPC_SET_IPC_THREAD _IO(IPC_IOC_MAGIC, 3) +#define IPC_SEND_RECV_MSG _IOWR(IPC_IOC_MAGIC, 4, IpcContent) + +typedef struct { + CmsCmd cmd; + uint32_t taskID; + uint32_t serviceHandle; +} CmsCmdContent; + +typedef struct { + MsgType type; /**< cmd type, decide the data structure below */ + SvcIdentity target; /**< serviceHandle or targetTaskId, depending on type */ + uint32_t code; + uint32_t flag; +#if (USE_TIMESTAMP == 1) + uint64_t timestamp; +#endif + uint32_t dataSz; /**< size of data */ + void* data; + uint32_t spObjNum; + void* offsets; + uint32_t processID; /**< filled by kernel, processId of sender/receiver */ + uint32_t taskID; /**< filled by kernel, taskId of sender/receiver */ +#ifdef LOSCFG_SECURITY_CAPABILITY + uint32_t userID; + uint32_t gid; +#endif +} IpcMsg; + +#define SEND (1 << 0) +#define RECV (1 << 1) +#define BUFF_FREE (1 << 2) + +typedef struct { + uint32_t flag; + IpcMsg *outMsg; /**< data to send to target */ + IpcMsg *inMsg; /**< data reply by target */ + void *buffToFree; +} IpcContent; + +#endif //_LITEIPC_H \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/liteipc/smgr_demo.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/liteipc/smgr_demo.cpp new file mode 100644 index 00000000..9c49d25c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/liteipc/smgr_demo.cpp @@ -0,0 +1,297 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "it_test_liteipc.h" +#include "signal.h" +#include "sys/wait.h" + +#include "unistd.h" +#include "liteipc.h" +#include "stdlib.h" +#include "stdio.h" +#include "string.h" +#include "sys/ioctl.h" +#include "sys/time.h" + +#include "smgr_demo.h" + +ServiceName g_serviceNameMap[MAX_SREVICE_NUM]; +BOOL g_cmsRunningFlag = FALSE; + +static void InitCms() +{ + (void)memset_s(g_serviceNameMap, sizeof(g_serviceNameMap), 0, sizeof(g_serviceNameMap)); +} + +uint32_t SetCms(int fd) +{ + return ioctl(fd, IPC_SET_CMS, 200); +} + +void SendReply(int fd, IpcMsg *dataIn, uint32_t result, uint32_t serviceHandle) +{ + IpcContent data1; + IpcMsg dataOut; + unsigned int ret; + uint32_t ptr[2]; + + data1.flag = SEND | BUFF_FREE; + data1.buffToFree = dataIn; + data1.outMsg = &dataOut; + (void)memset_s(data1.outMsg, sizeof(IpcMsg), 0, sizeof(IpcMsg)); + data1.outMsg->type = MT_REPLY; + data1.outMsg->target.handle = dataIn->taskID; + data1.outMsg->target.token = dataIn->target.token; + data1.outMsg->code = dataIn->code; +#if (USE_TIMESTAMP == 1) + data1.outMsg->timestamp = dataIn->timestamp; +#endif + ptr[0] = result; + ptr[1] = serviceHandle; + data1.outMsg->dataSz = 8; + data1.outMsg->data = ptr; + ret = ioctl(fd, IPC_SEND_RECV_MSG, &data1); + if (ret) { + printf("SendReply failed\n"); + } +} + +void FreeBuffer(int fd, IpcMsg *dataIn) +{ + IpcContent data1; + unsigned int ret; + data1.flag = BUFF_FREE; + data1.buffToFree = dataIn; + ret = ioctl(fd, IPC_SEND_RECV_MSG, &data1); + if (ret) { + printf("FreeBuffer failed\n"); + } +} + +static uint32_t SendCmsCmd(int fd, CmsCmdContent *content) +{ + unsigned int ret; + ret = ioctl(fd, IPC_CMS_CMD, content); + if (ret) { + printf("SendCmsCmd failed\n"); + } + return ret; +} + +uint32_t RegService(int fd, char *serviceName, uint32_t nameLen, uint32_t *serviceHandle) +{ + IpcContent data1; + IpcMsg dataIn; + IpcMsg dataOut; + uint32_t ret; + uint32_t *ptr = nullptr; + ServiceName name; + + if (nameLen > NAME_LEN_MAX) { + return -1; + } + (void)memcpy_s(name.serviceName, nameLen, serviceName, nameLen); + name.nameLen = nameLen; + + data1.flag = SEND | RECV; + data1.outMsg = &dataOut; + (void)memset_s(data1.outMsg, sizeof(IpcMsg), 0, sizeof(IpcMsg)); + data1.outMsg->type = MT_REQUEST; + data1.outMsg->target.handle = 0; + data1.outMsg->code = REG_CODE; + data1.outMsg->dataSz = sizeof(ServiceName); + data1.outMsg->data = &name; + + ret = ioctl(fd, IPC_SEND_RECV_MSG, &data1); + if (ret != 0) { + printf("RegService failed\n"); + return ret; + } + ptr = (uint32_t*)(data1.inMsg->data); + *serviceHandle = ptr[1]; + FreeBuffer(fd, data1.inMsg); + return ptr[0]; +} + +uint32_t GetService(int fd, char *serviceName, uint32_t nameLen, uint32_t *serviceHandle) +{ + IpcContent data1; + IpcMsg dataIn; + IpcMsg dataOut; + uint32_t ret; + uint32_t *ptr = nullptr; + ServiceName name; + + if (nameLen > NAME_LEN_MAX) { + return -1; + } + (void)memcpy_s(name.serviceName, nameLen, serviceName, nameLen); + name.nameLen = nameLen; + + data1.flag = SEND | RECV; + data1.outMsg = &dataOut; + (void)memset_s(data1.outMsg, sizeof(IpcMsg), 0, sizeof(IpcMsg)); + data1.outMsg->type = MT_REQUEST; + data1.outMsg->target.handle = 0; + data1.outMsg->code = GET_CODE; + data1.outMsg->dataSz = sizeof(ServiceName); + data1.outMsg->data = &name; + + ret = ioctl(fd, IPC_SEND_RECV_MSG, &data1); + if (ret != 0) { + return ret; + } + ptr = (uint32_t*)(data1.inMsg->data); + *serviceHandle = ptr[1]; + FreeBuffer(fd, data1.inMsg); + return ptr[0]; +} + +static void HandleServiceRegAndGet(int fd, IpcMsg *data) +{ + uint32_t ret, i; + + if (data->code == STOP_CODE) { + g_cmsRunningFlag = FALSE; + return; + } + + ServiceName *info = (ServiceName*)(data->data); + CmsCmdContent content; + if ((info->nameLen == 0) || (info->serviceName == NULL)) { + goto ERROR_EXIT; + } + for (i = 0; i < MAX_SREVICE_NUM; i++) { + if (g_serviceNameMap[i].serviceName != NULL && g_serviceNameMap[i].nameLen == info->nameLen) { + if(memcmp(g_serviceNameMap[i].serviceName, info->serviceName, info->nameLen) == 0) { + break; + } + } + } + printf("receive service request, code:%d, service name:%s\n", data->code, info->serviceName); + switch (data->code) { + case REG_CODE: + if (i == MAX_SREVICE_NUM) { + content.cmd = CMS_GEN_HANDLE; + content.taskID = data->taskID; + ret = SendCmsCmd(fd, &content); + if (ret) { + goto ERROR_EXIT; + } + if (g_serviceNameMap[content.serviceHandle].serviceName != NULL && g_serviceNameMap[content.serviceHandle].nameLen == info->nameLen) { + printf("the task has already a service named:%s\n", g_serviceNameMap[content.serviceHandle].serviceName); + goto ERROR_REG; + } else { + (void)memcpy_s(g_serviceNameMap[content.serviceHandle].serviceName, info->nameLen, + info->serviceName, info->nameLen); + g_serviceNameMap[content.serviceHandle].nameLen = info->nameLen; + SendReply(fd, data, 0, content.serviceHandle); + } + }else { + printf("this service already registered\n"); + goto ERROR_EXIT; + } + break; + case GET_CODE: + if (i == MAX_SREVICE_NUM) { + goto ERROR_EXIT; + }else { + content.cmd = CMS_ADD_ACCESS; + content.taskID = data->taskID; + content.serviceHandle = i; + SendCmsCmd(fd, &content); + SendReply(fd, data, 0, i); + } + break; + default: + break; + } + return; +ERROR_REG: + content.cmd = CMS_REMOVE_HANDLE; + SendCmsCmd(fd, &content); +ERROR_EXIT: + SendReply(fd, data, -1, 0); +} + +static uint32_t CmsLoop(int fd) +{ + IpcContent data1; + IpcMsg dataIn; + IpcMsg dataOut; + uint32_t ret; + g_cmsRunningFlag = TRUE; + while (g_cmsRunningFlag == TRUE) { + data1.flag = RECV; + ret = ioctl(fd, IPC_SEND_RECV_MSG, &data1); + if (ret != 0) { + printf("bad request!\n"); + continue; + } + switch (data1.inMsg->type) { + case MT_REQUEST: + HandleServiceRegAndGet(fd, data1.inMsg); + break; + default: + printf("request not support:%d!\n", data1.inMsg->type); + FreeBuffer(fd, data1.inMsg); + break; + } + } +} + +void StartCms(int fd) +{ + InitCms(); + CmsLoop(fd); +} + +void StopCms(int fd) +{ + IpcContent data1; + IpcMsg dataOut; + int ret; + + data1.flag = SEND; + data1.outMsg = &dataOut; + (void)memset_s(data1.outMsg, sizeof(IpcMsg), 0, sizeof(IpcMsg)); + data1.outMsg->type = MT_REQUEST; + data1.outMsg->target.handle = 0; + data1.outMsg->code = STOP_CODE; + data1.outMsg->dataSz = 0; + data1.outMsg->data = 0; + + ret = ioctl(fd, IPC_SEND_RECV_MSG, &data1); + if (ret != 0) { + printf("StopCms failed ioctl ret:%d!\n", ret); + } +} + diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/liteipc/smgr_demo.h b/src/kernel_liteos_a/testsuites/unittest/extended/liteipc/smgr_demo.h new file mode 100644 index 00000000..06526fa3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/liteipc/smgr_demo.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "liteipc.h" + +#define MAX_SREVICE_NUM 100 +#define NAME_LEN_MAX 30 +typedef struct { + char serviceName[NAME_LEN_MAX + 1]; + uint32_t nameLen; +} ServiceName; + +typedef enum { + REG_CODE, + GET_CODE, + STOP_CODE +} SmgrCode; + +void StartCms(int fd); +void StopCms(int fd); +uint32_t RegService(int fd, char *serviceName, uint32_t nameLen, uint32_t *serviceHandle); +uint32_t GetService(int fd, char *serviceName, uint32_t nameLen, uint32_t *serviceHandle); +void SendReply(int fd, IpcMsg *dataIn, uint32_t result, uint32_t serviceHandle); +void FreeBuffer(int fd, IpcMsg *dataIn); + diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/liteipc/smoke/liteipc_test_001.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/liteipc/smoke/liteipc_test_001.cpp new file mode 100644 index 00000000..62cb49a0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/liteipc/smoke/liteipc_test_001.cpp @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "it_test_liteipc.h" +#include "sys/wait.h" + +#include "unistd.h" +#include "stdlib.h" +#include "stdio.h" +#include "string.h" +#include "sys/time.h" +#include "sys/ioctl.h" +#include "fcntl.h" + +#include "liteipc.h" +#include "smgr_demo.h" + +static int LiteIpcTest(void) +{ + unsigned int ret; + IpcContent tmp; + void *retptr = nullptr; + /* testing open liteipc driver with different flag, expecting result is that flag matters nothing */ + int fd = open(LITEIPC_DRIVER, O_WRONLY | O_CLOEXEC); + ICUNIT_ASSERT_NOT_EQUAL(fd, -1, fd); + ret = close(fd); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + fd = open(LITEIPC_DRIVER, O_RDONLY | O_CREAT); + ICUNIT_ASSERT_NOT_EQUAL(fd, -1, fd); + ret = close(fd); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + fd = open(LITEIPC_DRIVER, O_RDWR | O_SYNC); + ICUNIT_ASSERT_NOT_EQUAL(fd, -1, fd); + + /* testing mmap liteipc mem pool with different size and flag */ + retptr = mmap(nullptr, 1024 * 4096, PROT_READ, MAP_PRIVATE, fd, 0); + ICUNIT_ASSERT_EQUAL(static_cast(static_cast(retptr)), -1, retptr); + retptr = mmap(nullptr, -1, PROT_READ, MAP_PRIVATE, fd, 0); + ICUNIT_ASSERT_EQUAL(static_cast(static_cast(retptr)), -1, retptr); + retptr = mmap(nullptr, 4096, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); + ICUNIT_ASSERT_EQUAL(static_cast(static_cast(retptr)), -1, retptr); + retptr = mmap(nullptr, 4096, PROT_READ, MAP_SHARED, fd, 0); // 4096: length of mapped memory + ICUNIT_ASSERT_EQUAL(static_cast(static_cast(retptr)), -1, retptr); + + retptr = mmap(nullptr, 1, PROT_READ, MAP_PRIVATE, fd, 0); + ICUNIT_ASSERT_NOT_EQUAL(static_cast(static_cast(retptr)), -1, retptr); + retptr = mmap(nullptr, 4095, PROT_READ, MAP_PRIVATE, fd, 0); + ICUNIT_ASSERT_EQUAL(static_cast(static_cast(retptr)), -1, retptr); + + /* testing read/write api */ + char buf[10] = {0}; + ret = read(fd, buf, 10); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ret = write(fd, buf, 10); // 10: size of buf + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + + /* before set cms, testing ioctl cmd */ + ret = ioctl(fd, IPC_CMS_CMD, 0); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + ret = ioctl(fd, IPC_SET_IPC_THREAD, 0); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + ret = ioctl(fd, IPC_SEND_RECV_MSG, 0); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + ret = ioctl(fd, IPC_SEND_RECV_MSG, &tmp); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + + sleep(2); + /* after set cms, testing set cms cmd */ + ret = ioctl(fd, IPC_SET_CMS, 200); // 200: use 200 for set cms cmd testing + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + + exit(0); + return 0; +} + +static int TestCase(void) +{ + unsigned int ret; + int fd = -1; + void *retptr = nullptr; + int status = 0; + pid_t pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); + if (pid == 0) { + LiteIpcTest(); + exit(-1); + } + + sleep(1); + fd = open(LITEIPC_DRIVER, O_RDONLY); + ICUNIT_ASSERT_NOT_EQUAL(fd, -1, fd); + + retptr = mmap(nullptr, 16 * 4096, PROT_READ, MAP_PRIVATE, fd, 0); + ICUNIT_ASSERT_NOT_EQUAL(static_cast(static_cast(retptr)), -1, retptr); + ret = ioctl(fd, IPC_SET_CMS, 0); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + ret = ioctl(fd, IPC_SET_CMS, 200); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = ioctl(fd, IPC_SET_CMS, 200); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + + ret = waitpid(pid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 0, status, EXIT); + + return 0; +EXIT: + return 1; +} + +void ItPosixLiteIpc001(void) +{ + TEST_ADD_CASE("ItPosixLiteIpc001", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} + diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/liteipc/smoke/liteipc_test_002.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/liteipc/smoke/liteipc_test_002.cpp new file mode 100644 index 00000000..0adbbe06 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/liteipc/smoke/liteipc_test_002.cpp @@ -0,0 +1,274 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "it_test_liteipc.h" +#include "sys/wait.h" + +#include "unistd.h" +#include "liteipc.h" +#include "stdlib.h" +#include "stdio.h" +#include "string.h" +#include "sys/time.h" +#include "sys/ioctl.h" +#include "fcntl.h" + +#include "smgr_demo.h" + +#define NEED_BREAK 1 + +static int g_ipcFd; +char g_serviceName[] = "ohos.testservice"; + +static int CallTestServiceLoop(uint32_t id) +{ + IpcContent data1; + IpcMsg dataIn; + IpcMsg dataOut; + uint32_t ret; + void *retptr = nullptr; + uint32_t num = 0; + uint32_t *ptr = nullptr; + struct timeval test_time; + struct timeval test_time2; + unsigned int serviceHandle; + + printf("i am the client%d process, my process id is %d\n", id, getpid()); + ret = GetService(g_ipcFd, g_serviceName, sizeof(g_serviceName), &serviceHandle); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + retptr = mmap(NULL, 4096, PROT_READ, MAP_PRIVATE, g_ipcFd, 0); + ICUNIT_ASSERT_NOT_EQUAL(static_cast(static_cast(retptr)), -1, retptr); + ret = GetService(g_ipcFd, g_serviceName, sizeof(g_serviceName), &serviceHandle); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + while (1) { + num++; +#if (NEED_BREAK == 1) + if (num > 50000) { + break; + } +#endif + data1.flag = SEND | RECV; + data1.outMsg = &dataOut; + (void)memset_s(data1.outMsg, sizeof(IpcMsg), 0, sizeof(IpcMsg)); + data1.outMsg->type = MT_REQUEST; + data1.outMsg->target.handle = serviceHandle; + data1.outMsg->dataSz = 4; + data1.outMsg->data = # + ret = ioctl(g_ipcFd, IPC_SEND_RECV_MSG, &data1); + if (ret != 0) { + printf("client%d CallTestServiceLoop ioctl ret:%d, errno:%d, num:%d\n", id, ret, errno, num); + ICUNIT_ASSERT_EQUAL(errno, ETIME, errno); + goto EXIT; + } else { + ptr = (uint32_t*)(data1.inMsg->data); + ICUNIT_ASSERT_EQUAL(ptr[0], 0, ptr[0]); + ICUNIT_ASSERT_EQUAL(ptr[1], 2 * num, ptr[1]); + FreeBuffer(g_ipcFd, data1.inMsg); + } + } + char tmpBuff[2048]; + data1.flag = SEND | RECV; + data1.outMsg = &dataOut; + (void)memset_s(data1.outMsg, sizeof(IpcMsg), 0, sizeof(IpcMsg)); + data1.outMsg->type = MT_REQUEST; + data1.outMsg->target.handle = serviceHandle; + data1.outMsg->dataSz = 1024; + data1.outMsg->data = tmpBuff; + ret = ioctl(g_ipcFd, IPC_SEND_RECV_MSG, &data1); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + FreeBuffer(g_ipcFd, data1.inMsg); + data1.outMsg->dataSz = 2048; + data1.outMsg->data = tmpBuff; + ret = ioctl(g_ipcFd, IPC_SEND_RECV_MSG, &data1); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + data1.outMsg->spObjNum = 300; + data1.outMsg->offsets = tmpBuff; + ret = ioctl(g_ipcFd, IPC_SEND_RECV_MSG, &data1); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); +EXIT: + exit(0); + return 0; +} + +static void HandleRequest(IpcMsg *data) +{ + uint32_t *ptr = (uint32_t*)data->data; + SendReply(g_ipcFd, data, 0, 2 * ptr[0]); +} + +static int TestServiceLoop(void) +{ + IpcContent data1; + IpcMsg dataIn; + IpcMsg dataOut; + int ret; + void *retptr = nullptr; + struct timeval last_time; + struct timeval test_time; + int cnt = 0; + unsigned int serviceHandle; + + printf("i am the test service process, my process id is %d\n", getpid()); + ret = RegService(g_ipcFd, g_serviceName, sizeof(g_serviceName), &serviceHandle); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + retptr = mmap(NULL, 4096, PROT_READ, MAP_PRIVATE, g_ipcFd, 0); + ICUNIT_ASSERT_NOT_EQUAL(static_cast(static_cast(retptr)), -1, retptr); + ret = RegService(g_ipcFd, g_serviceName, sizeof(g_serviceName), &serviceHandle); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + gettimeofday(&last_time, 0); + while (1) { + cnt++; +#if (NEED_BREAK == 1) + if (cnt > 100000 - 10) { + printf("TestServiceLoop break!\n"); + break; + } +#endif + data1.flag = RECV; + ret = ioctl(g_ipcFd, IPC_SEND_RECV_MSG, &data1); + if ((cnt % 1000000) == 0) { + gettimeofday(&test_time, 0); + printf("LiteIPC cnt:%d, time used:%d sec\n", cnt, test_time.tv_sec - last_time.tv_sec); + } + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + switch (data1.inMsg->type) { + case MT_REQUEST: + HandleRequest(data1.inMsg); + break; + default: + printf("request not support:%d!\n", data1.inMsg->type); + FreeBuffer(g_ipcFd, data1.inMsg); + break; + } + } + sleep(6); + exit(0); + return 0; +} + +static int LiteIpcTest(void) +{ + + int count = 0; + unsigned int ret; + void *retptr = nullptr; + pid_t farPid, sonPid, pid; + int status; + + retptr = mmap(NULL, 16 * 4096, PROT_READ, MAP_PRIVATE, g_ipcFd, 0); + ICUNIT_GOTO_NOT_EQUAL((int)(intptr_t)retptr, -1, retptr, EXIT1); + + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT1); + if (pid == 0) { + TestServiceLoop(); + exit(-1); + } + sleep(1);//wait server start + + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT1); + if (pid == 0) { + CallTestServiceLoop(1); + exit(-1); + } + + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT1); + if (pid == 0) { + CallTestServiceLoop(2); + exit(-1); + } + + ret = waitpid(-1, &status, 0); + printf("waitpid1 ret:%d\n", ret); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 0, status, EXIT2); + + ret = waitpid(-1, &status, 0); + printf("waitpid2 ret:%d\n", ret); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 0, status, EXIT2); + + ret = waitpid(-1, &status, 0); + printf("waitpid3 ret:%d\n", ret); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 0, status, EXIT2); + + return 0; +EXIT1: + return 1; +EXIT2: + printf("EXIT2 status:%d\n", status); + return status; +} + +static int TestCase(void) +{ + int ret; + int status; + g_ipcFd = open(LITEIPC_DRIVER, O_RDWR); + ICUNIT_ASSERT_NOT_EQUAL(g_ipcFd, -1, g_ipcFd); + + pid_t pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); + if (pid == 0) { + sleep(1);//wait cms start + ret = LiteIpcTest(); + StopCms(g_ipcFd); + if (ret == 0) { + exit(0); + } + if (ret == 1) { + exit(-1); + } + exit(ret); + } + + StartCms(g_ipcFd); + + ret = waitpid(pid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 0, status, EXIT); + + return 0; +EXIT: + return 1; +} + +void ItPosixLiteIpc002(void) +{ + TEST_ADD_CASE("ItPosixLiteIpc002", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} + diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/config.gni b/src/kernel_liteos_a/testsuites/unittest/extended/signal/config.gni new file mode 100644 index 00000000..6d0a0286 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/config.gni @@ -0,0 +1,102 @@ +# Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +signal_include_dirs = [ "$TEST_UNITTEST_DIR/extended/signal" ] + +signal_sources_entry = [ "$TEST_UNITTEST_DIR/extended/signal/signal_test.cpp" ] + +signal_sources_smoke = [ + "$TEST_UNITTEST_DIR/extended/signal/smoke/It_ipc_fdisset_001.cpp", + "$TEST_UNITTEST_DIR/extended/signal/smoke/It_ipc_mkfifo_002.cpp", + "$TEST_UNITTEST_DIR/extended/signal/smoke/It_ipc_mkfifo_003.cpp", + "$TEST_UNITTEST_DIR/extended/signal/smoke/It_ipc_pipe_004.cpp", + "$TEST_UNITTEST_DIR/extended/signal/smoke/It_ipc_pipe_005.cpp", + "$TEST_UNITTEST_DIR/extended/signal/smoke/mkfifo_test_001.cpp", + "$TEST_UNITTEST_DIR/extended/signal/smoke/mkfifo_test_002.cpp", + "$TEST_UNITTEST_DIR/extended/signal/smoke/pipe_test_002.cpp", + "$TEST_UNITTEST_DIR/extended/signal/smoke/pipe_test_004.cpp", + "$TEST_UNITTEST_DIR/extended/signal/smoke/signal_test_002.cpp", + "$TEST_UNITTEST_DIR/extended/signal/smoke/signal_test_009.cpp", + "$TEST_UNITTEST_DIR/extended/signal/smoke/signal_test_013.cpp", + "$TEST_UNITTEST_DIR/extended/signal/smoke/signal_test_014.cpp", + "$TEST_UNITTEST_DIR/extended/signal/smoke/signal_test_021.cpp", + "$TEST_UNITTEST_DIR/extended/signal/smoke/signal_test_022.cpp", + "$TEST_UNITTEST_DIR/extended/signal/smoke/signal_test_023.cpp", + "$TEST_UNITTEST_DIR/extended/signal/smoke/signal_test_024.cpp", + "$TEST_UNITTEST_DIR/extended/signal/smoke/signal_test_031.cpp", + "$TEST_UNITTEST_DIR/extended/signal/smoke/signal_test_032.cpp", + "$TEST_UNITTEST_DIR/extended/signal/smoke/signal_test_035.cpp", + "$TEST_UNITTEST_DIR/extended/signal/smoke/signal_test_036.cpp", + "$TEST_UNITTEST_DIR/extended/signal/smoke/signal_test_037.cpp", + "$TEST_UNITTEST_DIR/extended/signal/smoke/signal_test_039.cpp", + "$TEST_UNITTEST_DIR/extended/signal/smoke/signal_test_042.cpp", + "$TEST_UNITTEST_DIR/extended/signal/smoke/sigset_test_001.cpp", + "$TEST_UNITTEST_DIR/extended/signal/smoke/sigset_test_002.cpp", +] + +signal_sources_full = [ + "$TEST_UNITTEST_DIR/extended/signal/full/It_ipc_fdclr_001.cpp", + "$TEST_UNITTEST_DIR/extended/signal/full/It_ipc_fdset_001.cpp", + "$TEST_UNITTEST_DIR/extended/signal/full/It_ipc_fdzero_001.cpp", + "$TEST_UNITTEST_DIR/extended/signal/full/It_ipc_sigaction_001.cpp", + "$TEST_UNITTEST_DIR/extended/signal/full/It_ipc_sigpause_001.cpp", + "$TEST_UNITTEST_DIR/extended/signal/full/It_ipc_sigprocmask_001.cpp", + "$TEST_UNITTEST_DIR/extended/signal/full/signal_test_001.cpp", + "$TEST_UNITTEST_DIR/extended/signal/full/signal_test_003.cpp", + "$TEST_UNITTEST_DIR/extended/signal/full/signal_test_004.cpp", + "$TEST_UNITTEST_DIR/extended/signal/full/signal_test_005.cpp", + "$TEST_UNITTEST_DIR/extended/signal/full/signal_test_006.cpp", + "$TEST_UNITTEST_DIR/extended/signal/full/signal_test_007.cpp", + "$TEST_UNITTEST_DIR/extended/signal/full/signal_test_008.cpp", + "$TEST_UNITTEST_DIR/extended/signal/full/signal_test_010.cpp", + "$TEST_UNITTEST_DIR/extended/signal/full/signal_test_011.cpp", + "$TEST_UNITTEST_DIR/extended/signal/full/signal_test_012.cpp", + "$TEST_UNITTEST_DIR/extended/signal/full/signal_test_015.cpp", + "$TEST_UNITTEST_DIR/extended/signal/full/signal_test_016.cpp", + "$TEST_UNITTEST_DIR/extended/signal/full/signal_test_017.cpp", + "$TEST_UNITTEST_DIR/extended/signal/full/signal_test_018.cpp", + "$TEST_UNITTEST_DIR/extended/signal/full/signal_test_019.cpp", + "$TEST_UNITTEST_DIR/extended/signal/full/signal_test_020.cpp", + "$TEST_UNITTEST_DIR/extended/signal/full/signal_test_025.cpp", + "$TEST_UNITTEST_DIR/extended/signal/full/signal_test_026.cpp", + "$TEST_UNITTEST_DIR/extended/signal/full/signal_test_028.cpp", + "$TEST_UNITTEST_DIR/extended/signal/full/signal_test_029.cpp", + "$TEST_UNITTEST_DIR/extended/signal/full/signal_test_030.cpp", + "$TEST_UNITTEST_DIR/extended/signal/full/signal_test_033.cpp", + "$TEST_UNITTEST_DIR/extended/signal/full/signal_test_038.cpp", + "$TEST_UNITTEST_DIR/extended/signal/full/signal_test_040.cpp", + "$TEST_UNITTEST_DIR/extended/signal/full/signal_test_041.cpp", + "$TEST_UNITTEST_DIR/extended/signal/full/It_ipc_pipe_002.cpp", + "$TEST_UNITTEST_DIR/extended/signal/full/It_ipc_pipe_003.cpp", + "$TEST_UNITTEST_DIR/extended/signal/full/pipe_test_001.cpp", + "$TEST_UNITTEST_DIR/extended/signal/full/pipe_test_003.cpp", + "$TEST_UNITTEST_DIR/extended/signal/full/pipe_test_005.cpp", + "$TEST_UNITTEST_DIR/extended/signal/full/pipe_test_006.cpp", +] diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/It_ipc_fdclr_001.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/It_ipc_fdclr_001.cpp new file mode 100644 index 00000000..13fd61a4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/It_ipc_fdclr_001.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" + +static const int TEST_LOOP_NUM = 4; +static const int TAR_STR_LEN = 12; + +static UINT32 Testcase(VOID) +{ + int pipeFd[TEST_LOOP_NUM][2], ret, i; // 2, pipe return 2 file descirpter + int fdmax = 0; + struct timeval tv; + fd_set reads; + FD_ZERO(&reads); + tv.tv_sec = 1; + tv.tv_usec = 50; // 50, overtime setting + for (i = 0; i < TEST_LOOP_NUM; i++) { + ret = pipe(pipeFd[i]); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + fdmax = pipeFd[i][1] > fdmax ? pipeFd[i][1] : fdmax; + ret = write(pipeFd[i][1], "aloha world", TAR_STR_LEN); + printf("write first status: %d\n", ret); + ICUNIT_GOTO_EQUAL(ret, TAR_STR_LEN, ret, EXIT); + } + printf("next is select ...\n"); + ret = select(fdmax + 1, &reads, NULL, NULL, &tv); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT1); + printf("select passed &&&&&&&&&&&&&&&&\n"); + FD_SET(pipeFd[0][0], &reads); + ret = select(fdmax + 1, &reads, NULL, NULL, &tv); + ICUNIT_GOTO_EQUAL(ret, 1, ret, EXIT1); + ret = FD_ISSET(pipeFd[0][0], &reads); + ICUNIT_GOTO_NOT_EQUAL(ret, 0, ret, EXIT1); + FD_SET(pipeFd[1][0], &reads); + FD_SET(pipeFd[2][0], &reads); // 2, pipe return on the 2nd loop + FD_SET(pipeFd[3][0], &reads); // 3, pipe return on the 3rd loop + FD_CLR(pipeFd[3][0], &reads); // 3, pipe return on the 3rd loop + FD_CLR(pipeFd[2][0], &reads); // 2, pipe return on the 2nd loop + ret = select(fdmax + 1, &reads, NULL, NULL, &tv); + ICUNIT_GOTO_EQUAL(ret, 2, ret, EXIT1); // 2, expect selcet return value + ret = FD_ISSET(pipeFd[1][0], &reads); + ICUNIT_GOTO_NOT_EQUAL(ret, 0, ret, EXIT1); + ret = FD_ISSET(pipeFd[0][0], &reads); + ICUNIT_GOTO_NOT_EQUAL(ret, 0, ret, EXIT1); + ret = FD_ISSET(pipeFd[2][0], &reads); // 2, pipe return on the 2nd loop + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT1); + ret = FD_ISSET(pipeFd[3][0], &reads); // 3, pipe return on the 3rd loop + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT1); + for (i = 0; i < TEST_LOOP_NUM; i++) { + close(pipeFd[i][0]); + close(pipeFd[i][1]); + } + + return LOS_OK; +EXIT1: + i = TEST_LOOP_NUM - 1; +EXIT: + for (i; i >= 0; i--) { + close(pipeFd[i][0]); + close(pipeFd[i][1]); + } + return LOS_NOK; +} + +VOID ItIpcFdClr001(void) +{ + TEST_ADD_CASE(__FUNCTION__, Testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/It_ipc_fdset_001.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/It_ipc_fdset_001.cpp new file mode 100644 index 00000000..dda0395b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/It_ipc_fdset_001.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" + + +static const int TEST_LOOP_NUM = 4; +static const int TAR_STR_LEN = 12; + +static UINT32 Testcase(VOID) +{ + int pipeFd[TEST_LOOP_NUM][2], ret, i; // 2, pipe return 2 file descirpter + int fdmax = 0; + struct timeval tv; + fd_set reads; + FD_ZERO(&reads); + + tv.tv_sec = 1; + tv.tv_usec = 50; // 50, overtime setting + for (i = 0; i < TEST_LOOP_NUM; i++) { + ret = pipe(pipeFd[i]); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + fdmax = pipeFd[i][1] > fdmax ? pipeFd[i][1] : fdmax; + fdmax = pipeFd[i][0] > fdmax ? pipeFd[i][0] : fdmax; + ret = write(pipeFd[i][1], "Aloha World", TAR_STR_LEN); + printf("write first status: %d\n", ret); + ICUNIT_GOTO_EQUAL(ret, TAR_STR_LEN, ret, EXIT); + } + + ret = select(fdmax + 1, &reads, NULL, NULL, &tv); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT1); + + FD_SET(pipeFd[0][0], &reads); + ret = select(fdmax + 1, &reads, NULL, NULL, &tv); + ICUNIT_GOTO_EQUAL(ret, 1, ret, EXIT1); + ret = FD_ISSET(pipeFd[0][0], &reads); + ICUNIT_GOTO_NOT_EQUAL(ret, 0, ret, EXIT1); + + FD_SET(pipeFd[1][0], &reads); + FD_SET(pipeFd[2][0], &reads); // 2, pipe return on the 2nd loop + FD_SET(pipeFd[3][0], &reads); // 3, pipe return on the 3rd loop + ret = select(fdmax + 1, &reads, NULL, NULL, &tv); + ICUNIT_GOTO_EQUAL(ret, TEST_LOOP_NUM, ret, EXIT1); + + for (i = 0; i < TEST_LOOP_NUM; i++) { + ret = FD_ISSET(pipeFd[i][0], &reads); + ICUNIT_GOTO_NOT_EQUAL(ret, 0, ret, EXIT1); + } + + for (i = 0; i < TEST_LOOP_NUM; i++) { + close(pipeFd[i][0]); + close(pipeFd[i][1]); + } + printf("-----------FD_SET ok------------\n"); + return LOS_OK; +EXIT1: + i = TEST_LOOP_NUM - 1; +EXIT: + for (i; i >= 0; i--) { + close(pipeFd[i][0]); + close(pipeFd[i][1]); + } + return LOS_NOK; +} + +VOID ItIpcFdSet001(void) +{ + TEST_ADD_CASE(__FUNCTION__, Testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/It_ipc_fdzero_001.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/It_ipc_fdzero_001.cpp new file mode 100644 index 00000000..33a45823 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/It_ipc_fdzero_001.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" + + +static const int TEST_LOOP_NUM = 4; +static const int TAR_STR_LEN = 12; + +static UINT32 Testcase(VOID) +{ + int pipeFd[TEST_LOOP_NUM][2], ret, i; // 2, pipe return 2 file descirpter + int fdmax = 0; + struct timeval tv; + fd_set reads; + FD_ZERO(&reads); + + tv.tv_sec = 1; + tv.tv_usec = 50; // 50, overtime setting + for (i = 0; i < TEST_LOOP_NUM; i++) { + ret = pipe(pipeFd[i]); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + fdmax = pipeFd[i][1] > fdmax ? pipeFd[i][1] : fdmax; + ret = write(pipeFd[i][1], "Aloha world", TAR_STR_LEN); + printf("write first status: %d\n", ret); + ICUNIT_GOTO_EQUAL(ret, TAR_STR_LEN, ret, EXIT); + } + + ret = select(fdmax + 1, &reads, NULL, NULL, &tv); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT1); + + FD_SET(pipeFd[0][0], &reads); + ret = select(fdmax + 1, &reads, NULL, NULL, &tv); + ICUNIT_GOTO_EQUAL(ret, 1, ret, EXIT1); + ret = FD_ISSET(pipeFd[0][0], &reads); + ICUNIT_GOTO_NOT_EQUAL(ret, 0, ret, EXIT1); + + FD_SET(pipeFd[1][0], &reads); + FD_SET(pipeFd[2][0], &reads); // 2, pipe return on the 2nd loop + FD_SET(pipeFd[3][0], &reads); // 3, pipe return on the 3rd loop + FD_ZERO(&reads); + ret = select(fdmax + 1, &reads, NULL, NULL, &tv); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT1); + + for (i = 0; i < TEST_LOOP_NUM; i++) { + ret = FD_ISSET(pipeFd[i][0], &reads); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT1); + } + + for (i = 0; i < TEST_LOOP_NUM; i++) { + close(pipeFd[i][0]); + close(pipeFd[i][1]); + } + + return LOS_OK; +EXIT1: + i = TEST_LOOP_NUM - 1; +EXIT: + for (i; i >= 0; i--) { + close(pipeFd[i][0]); + close(pipeFd[i][1]); + } + return LOS_NOK; +} + +VOID ItIpcFdZero001(void) +{ + TEST_ADD_CASE(__FUNCTION__, Testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/It_ipc_pipe_002.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/It_ipc_pipe_002.cpp new file mode 100644 index 00000000..bb91fb3e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/It_ipc_pipe_002.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "sys/shm.h" + +static UINT32 Testcase(VOID) +{ + int pipeFd[2], ret, spid; // 2, pipe return 2 file descripter + char buffer[20]; // 20, target buffer size + int *sharedflag = NULL; + int shmid; + + ret = pipe(pipeFd); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT1); + shmid = shmget(static_cast(IPC_PRIVATE), sizeof(int), 0666 | IPC_CREAT); // 0666 the authority of the shm + ICUNIT_ASSERT_NOT_EQUAL(shmid, -1, shmid); + sharedflag = (int *)shmat(shmid, NULL, 0); + *sharedflag = 0; + + spid = fork(); + ICUNIT_GOTO_NOT_EQUAL(spid, -1, spid, EXIT1); + if (spid == 0) { + sharedflag = (int *)shmat(shmid, NULL, 0); + close(pipeFd[0]); + ret = write(pipeFd[1], "hello world", 12); // 12, "hello world" length and '\0' + printf("write first status: %d\n", ret); + if (ret != 12) { // 12, "hello world" length and '\0' + exit(11); // 11, the value of son process unexpected exit, convenient to debug + } + *sharedflag = 1; + close(pipeFd[1]); + exit(RED_FLAG); + } + close(pipeFd[1]); + // waitting for the sub process has written the sentence + while (*sharedflag != 1) { + usleep(1); + } + ret = read(pipeFd[0], buffer, 12); // 12, "hello world" length and '\0' + ICUNIT_GOTO_EQUAL(ret, 12, ret, EXIT); // 12, "hello world" length and '\0' + ret = strcmp(buffer, "hello world"); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + printf("read pipe success: %s\n", buffer); + wait(&ret); + printf("son return status: %d\n", WEXITSTATUS(ret)); + ICUNIT_GOTO_EQUAL(WEXITSTATUS(ret), RED_FLAG, WEXITSTATUS(ret), EXIT); + printf("pipe ok\n"); + close(pipeFd[0]); + return LOS_OK; +EXIT: + close(pipeFd[0]); +EXIT1: + return LOS_NOK; +} + +VOID ItIpcPipe002(void) +{ + TEST_ADD_CASE(__FUNCTION__, Testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/It_ipc_pipe_003.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/It_ipc_pipe_003.cpp new file mode 100644 index 00000000..f3b3b8f3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/It_ipc_pipe_003.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "sys/shm.h" + +static const int TAR_STR_LEN = 12; + +static UINT32 Testcase(VOID) +{ + int pipeFd[2], ret, spid; // 2, pipe return 2 file descripter + char buffer[20]; // 20, target buffer size + int *sharedflag = NULL; + int shmid; + + ret = pipe(pipeFd); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT1); + shmid = shmget(static_cast(IPC_PRIVATE), sizeof(int), 0666 | IPC_CREAT); // 0666 the authority of the shm + ICUNIT_ASSERT_NOT_EQUAL(shmid, -1, shmid); + sharedflag = (int *)shmat(shmid, NULL, 0); + *sharedflag = 0; + + spid = fork(); + ICUNIT_GOTO_NOT_EQUAL(spid, -1, spid, EXIT1); + if (spid == 0) { + sharedflag = (int *)shmat(shmid, NULL, 0); + close(pipeFd[0]); + ret = write(pipeFd[1], "Hello world", TAR_STR_LEN); + printf("write first status: %d\n", ret); + if (ret != TAR_STR_LEN) { + exit(11); // 11, the value of son process unexpected exit, convenient to debug + } + *sharedflag = 1; + close(pipeFd[1]); + exit(RED_FLAG); + } + close(pipeFd[1]); + // waitting for the sub process has written the sentence + while (*sharedflag != 1) { + usleep(1); + } + ret = read(pipeFd[0], buffer, TAR_STR_LEN); + ICUNIT_GOTO_EQUAL(ret, TAR_STR_LEN, ret, EXIT); + ret = strcmp(buffer, "Hello world"); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + printf("read pipe success: %s\n", buffer); + wait(&ret); + printf("son return status: %d\n", WEXITSTATUS(ret)); + ICUNIT_GOTO_EQUAL(WEXITSTATUS(ret), RED_FLAG, WEXITSTATUS(ret), EXIT); + printf("pipe ok\n"); + close(pipeFd[0]); + return LOS_OK; +EXIT: + close(pipeFd[0]); +EXIT1: + return LOS_NOK; +} + +VOID ItIpcPipe003(void) +{ + TEST_ADD_CASE(__FUNCTION__, Testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/It_ipc_sigaction_001.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/It_ipc_sigaction_001.cpp new file mode 100644 index 00000000..06870d8a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/It_ipc_sigaction_001.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" + + +static int g_actionCnt1; +static void CatchAction1(int param) +{ + g_actionCnt1++; + printf("---------%d---signum-%d-----\n", g_actionCnt1, param); +} + +static UINT32 Testcase(VOID) +{ + int spid, ret; + struct sigaction act, oldact; + act.sa_handler = CatchAction1; + sigemptyset(&act.sa_mask); + act.sa_flags = 0; + spid = fork(); + ICUNIT_ASSERT_NOT_EQUAL(spid, -1, spid); + if (spid == 0) { + ret = sigaction(SIGCHLD, &act, &oldact); + if (ret == -1) { + exit(-1); + } + spid = fork(); + if (spid == 0) { + spid = getppid(); + kill(spid, SIGCHLD); + usleep(1000 * 10 * 10); // 1000, 10, 10, Used to calculate the delay time. + exit(0); + } + if (spid == -1) { + exit(-1); + } + ret = 0; + while (ret == 0) { + ret = waitpid(spid, NULL, WNOHANG); + } + + ret = sigaction(SIGCHLD, &oldact, NULL); + if (ret == -1) { + exit(6); // 6, the value of son process unexpected exit, convenient to debug + } + sleep(1); + printf("---son--cnt check----%d--------\n", g_actionCnt1); + exit(g_actionCnt1); + } + wait(&ret); + ICUNIT_ASSERT_EQUAL(WEXITSTATUS(ret), 2, WEXITSTATUS(ret)); // 2, assert that function Result is equal to this. + return LOS_OK; +} + +VOID ItIpcSigaction001(void) +{ + TEST_ADD_CASE(__FUNCTION__, Testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/It_ipc_sigpause_001.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/It_ipc_sigpause_001.cpp new file mode 100644 index 00000000..69532df7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/It_ipc_sigpause_001.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" + + +static void CatchAction3(int param) +{ + printf("son recv signal: SIGUSR1\n"); +} + +static UINT32 Testcase(VOID) +{ + int spid = 0; + int retval = 0; + + struct sigaction act; + act.sa_handler = CatchAction3; + act.sa_flags = 0; + spid = fork(); + ICUNIT_ASSERT_NOT_EQUAL(spid, -1, spid); + if (spid == 0) { + retval = sigemptyset(&act.sa_mask); + if (retval == -1) { + exit(-1); + } + retval = sigaction(SIGUSR1, &act, NULL); + if (retval == -1) { + exit(-1); + } + printf("enter sigpause...\n"); + retval = sigpause(SIGUSR1); + retval = RED_FLAG; + printf("son retval check %d\n", retval); + exit(retval); + } + sleep(2); // 2, sleep 2 second + ICUNIT_ASSERT_EQUAL(retval, 0, retval); + printf("send signal to %d: SIGUSR1...\n", spid); + kill(spid, SIGUSR1); + wait(&retval); + printf("father retval check %d\n", WEXITSTATUS(retval)); + ICUNIT_ASSERT_EQUAL(WEXITSTATUS(retval), RED_FLAG, WEXITSTATUS(retval)); + return LOS_OK; +} + +VOID ItIpcSigpause001(void) +{ + TEST_ADD_CASE(__FUNCTION__, Testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/It_ipc_sigprocmask_001.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/It_ipc_sigprocmask_001.cpp new file mode 100644 index 00000000..4ce04ff1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/It_ipc_sigprocmask_001.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" + + +static UINT32 Testcase(VOID) +{ + int spid = 0; + int retval = 0; + + sigset_t set, oldset; + spid = fork(); + ICUNIT_ASSERT_NOT_EQUAL(spid, -1, spid); + if (spid == 0) { + retval = sigemptyset(&set); + if (retval == -1) { + exit(-1); + } + retval = sigemptyset(&oldset); + if (retval == -1) { + exit(-1); + } + retval = sigaddset(&set, SIGTERM); + if (retval == -1) { + exit(-1); + } + retval = sigprocmask(SIG_BLOCK, &set, &oldset); + if (retval == -1) { + exit(-1); + } + sleep(2); // 2, sleep 2 second + retval = RED_FLAG; + printf("son retval check %d\n", retval); + exit(retval); + } + sleep(1); + kill(spid, SIGTERM); + wait(&retval); + printf("father retval check %d\n", WEXITSTATUS(retval)); + ICUNIT_ASSERT_EQUAL(WEXITSTATUS(retval), RED_FLAG, WEXITSTATUS(retval)); + return LOS_OK; +} + +VOID ItIpcSigpromask001(void) +{ + TEST_ADD_CASE(__FUNCTION__, Testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/pipe_test_001.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/pipe_test_001.cpp new file mode 100644 index 00000000..8e24b370 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/pipe_test_001.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" +#include "fcntl.h" + +int TestPipeSingleProcess() +{ + int pipefd[2]; // 2, array subscript + int retValue = -1; + pid_t pid; + retValue = pipe(pipefd); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + + int *readFd = &pipefd[0]; + int *writeFd = &pipefd[1]; + + char readbuffer[100]; // 100, array subscript + int status, ret; + + int flag = fcntl(*readFd, F_GETFL); + fcntl(*readFd, F_SETFL, flag | O_NONBLOCK); + + pid = fork(); + if (pid == -1) { + printf("Fork Error!\n"); + return -1; + } else if (pid == 0) { + for (int i = 0; i < 3; i++) { // 3, Number of cycles + errno = 0; + char sentence1[15] = "Hello World"; + char a[4] = {0}; + (void)sprintf_s(a, sizeof(a), "%d", i); + (void)strcat_s(sentence1, 15, a); // 15, sizeof sentence1 + int ret = write(*writeFd, sentence1, strlen(sentence1) + 1); + usleep(100000); // 100000, Used to calculate the delay time. + + printf("read\n"); + (void)memset_s(readbuffer, sizeof(readbuffer), 0, sizeof(readbuffer)); + retValue = read(*readFd, readbuffer, sizeof(readbuffer)); + printf("Receive %d bytes data : %s,%d\n", retValue, readbuffer, errno); + if (strncmp((readbuffer), (readbuffer), (strlen(sentence1))) != 0) { + exit(errno); + } + usleep(100000); // 100000, Used to calculate the delay time. + } + exit(0); + } + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ICUNIT_ASSERT_EQUAL(WEXITSTATUS(status), 0, WEXITSTATUS(status)); + ret = unlink("/dev/pipe0"); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + ret = close(pipefd[0]); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = unlink("/dev/pipe0"); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + ret = close(pipefd[1]); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = unlink("/dev/pipe0"); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return 0; +} + + +void ItPosixPipe001(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestPipeSingleProcess, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/pipe_test_003.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/pipe_test_003.cpp new file mode 100644 index 00000000..03d5eafd --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/pipe_test_003.cpp @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" +#include "fcntl.h" + +int TestPipeSingleProcessFcntl() +{ + int pipefd[2]; // 2, array subscript + pid_t pid; + int retValue = -1; + retValue = pipe(pipefd); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + + int *readFd = &pipefd[0]; + int *writeFd = &pipefd[1]; + + char readbuffer[100]; + int status, ret; + + int flag = fcntl(*readFd, F_GETFL); + fcntl(*readFd, F_SETFL, flag | O_NONBLOCK); + + pid = fork(); + if (pid == -1) { + printf("Fork Error!\n"); + return -1; + } else if (pid == 0) { + for (int i = 0; i < 3; i++) { // 3, Number of cycles + errno = 0; + char sentence1[15] = "Hello World"; + char a[4] = {0}; + (void)sprintf_s(a, sizeof(a), "%d", i); + (void)strcat_s(sentence1, 15, a); // 15, sizeof sentence1 + int ret = write(*writeFd, sentence1, strlen(sentence1) + 1); + usleep(100000); // 100000, Used to calculate the delay time. + } + char sentence1[15] = "Hello World"; + char a[4] = {0}; + usleep(10000); // 10000, Used to calculate the delay time. + printf("read\n"); + (void)memset_s(readbuffer, sizeof(readbuffer), 0, sizeof(readbuffer)); + retValue = read(*readFd, readbuffer, sizeof(readbuffer)); + printf("Receive %d bytes data : %s,%d\n", retValue, readbuffer, errno); + printf("Receive %d bytes data : %s,%d\n", retValue, readbuffer + 13, errno); // 13, readbuffer offset. + printf("Receive %d bytes data : %s,%d\n", retValue, readbuffer + 26, errno); // 26, readbuffer offset. + ICUNIT_ASSERT_SIZE_STRING_EQUAL(readbuffer, "Hello World0", strlen(sentence1), errno); + ICUNIT_ASSERT_SIZE_STRING_EQUAL(readbuffer + 13, "Hello World1", strlen(sentence1), errno); // 13, readbuffer offset. + ICUNIT_ASSERT_SIZE_STRING_EQUAL(readbuffer + 26, "Hello World2", strlen(sentence1), errno); // 26, readbuffer offset. + usleep(100000); // 100000, Used to calculate the delay time. + + printf("read\n"); + (void)memset_s(readbuffer, sizeof(readbuffer), 0, sizeof(readbuffer)); + fcntl(*readFd, F_SETFL, O_NONBLOCK); + ret = fcntl(*readFd, F_GETFL, O_NONBLOCK); + printf("fctrl ret=%d,O_NONBLOCK=%d\n", ret, O_NONBLOCK); + retValue = read(*readFd, readbuffer, sizeof(readbuffer)); + printf("Receive %d bytes data : %s,%d\n", retValue, readbuffer, errno); + + ICUNIT_ASSERT_EQUAL(retValue, -1, retValue); + ICUNIT_ASSERT_EQUAL(errno, EAGAIN, errno); + ICUNIT_ASSERT_SIZE_STRING_EQUAL(readbuffer, readbuffer, strlen(sentence1), errno); + usleep(100000); // 100000, Used to calculate the delay time. + exit(0); + } + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ret = close(pipefd[0]); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = close(pipefd[1]); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return 0; +} + +void ItPosixPipe003(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestPipeSingleProcessFcntl, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/pipe_test_005.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/pipe_test_005.cpp new file mode 100644 index 00000000..720f9b6f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/pipe_test_005.cpp @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "sys/shm.h" +#include "it_test_signal.h" +#include "signal.h" + +static void SigPrint(int signum) +{ + printf("Pipe break\n"); +} + +static int PipecommonWrite() +{ + int pipefd[2]; // 2, array subscript + pid_t pid; + int retValue = -1; + int *sharedflag = NULL; + int shmid; + int *readFd = &pipefd[0]; + int *writeFd = &pipefd[1]; + char sentence[] = "Hello World"; + char readbuffer[100]; + int status, ret; + + retValue = pipe(pipefd); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + if (signal(SIGPIPE, SigPrint) == SIG_ERR) { + printf("signal error\n"); + } + + shmid = shmget(static_cast(IPC_PRIVATE), sizeof(int), 0666 | IPC_CREAT); // 0666 the authority of the shm + ICUNIT_ASSERT_NOT_EQUAL(shmid, -1, shmid); + sharedflag = (int *)shmat(shmid, NULL, 0); + *sharedflag = 0; + + pid = fork(); + if (pid == -1) { + printf("Fork Error!\n"); + return -1; + } else if (pid == 0) { + sharedflag = (int *)shmat(shmid, NULL, 0); + close(*readFd); + retValue = write(*writeFd, sentence, strlen(sentence) + 1); + ICUNIT_ASSERT_EQUAL(retValue, strlen(sentence) + 1, retValue); + *sharedflag = 1; + // 2 waitting for the father process close the pipe's read port + while (*sharedflag != 2) { + usleep(1); + } + retValue = write(*writeFd, sentence, strlen(sentence) + 1); + ICUNIT_ASSERT_EQUAL(retValue, -1, retValue); + ICUNIT_ASSERT_EQUAL(errno, EPIPE, errno); + exit(0); + } else { + close(*writeFd); + // 1 waitting for the sub process has written the sentence first + while (*sharedflag != 1) { + usleep(1); + } + close(*readFd); + // 2 father process close the pipe's read port + *sharedflag = 2; + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ICUNIT_ASSERT_EQUAL(WEXITSTATUS(status), 0, WEXITSTATUS(status)); + } + return 0; +} + +void ItPosixPipe005(void) +{ + TEST_ADD_CASE(__FUNCTION__, PipecommonWrite, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/pipe_test_006.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/pipe_test_006.cpp new file mode 100644 index 00000000..3bd8e54a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/pipe_test_006.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" + +static const int NAME_LEN = 60; + +static const int MAX_PIPES = 32; + +static int PipeUnlinkTest() +{ + int pipefd[MAX_PIPES][2]; // 2, array subscript + int tmpFd[2]; + pid_t pid; + int retValue = -1; + + int status, ret; + char devName[NAME_LEN]; // 60, array subscript + pid = fork(); + if (pid == -1) { + printf("Fork Error!\n"); + return -1; + } else if (pid == 0) { + for (int i = 0; i < MAX_PIPES; i++) { + retValue = pipe(pipefd[i]); + ICUNIT_ASSERT_EQUAL_EXIT(retValue, 0, __LINE__); + } + retValue = pipe(tmpFd); + ICUNIT_ASSERT_EQUAL_EXIT(retValue, -1, __LINE__); + for (int i = 0; i < MAX_PIPES; i++) { + (void)snprintf_s(devName, NAME_LEN, NAME_LEN - 1, "/dev/pipe%d", i); // 60, len of max size + retValue = unlink(devName); + ICUNIT_ASSERT_EQUAL_EXIT(retValue, -1, __LINE__); + retValue = close(pipefd[i][0]); + ICUNIT_ASSERT_EQUAL_EXIT(retValue, 0, __LINE__); + retValue = unlink(devName); + ICUNIT_ASSERT_EQUAL_EXIT(retValue, -1, __LINE__); + retValue = close(pipefd[i][1]); + ICUNIT_ASSERT_EQUAL_EXIT(retValue, 0, __LINE__); + retValue = unlink(devName); + ICUNIT_ASSERT_EQUAL_EXIT(retValue, 0, __LINE__); + } + exit(0); + } + usleep(15000); // 15000, Used to calculate the delay time. + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ICUNIT_ASSERT_EQUAL(WEXITSTATUS(status), 0, WEXITSTATUS(status)); + return 0; +} + + +void ItPosixPipe006(void) +{ + TEST_ADD_CASE(__FUNCTION__, PipeUnlinkTest, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_001.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_001.cpp new file mode 100644 index 00000000..05914887 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_001.cpp @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" +#include "sys/wait.h" + +static const int SIG_TEST_COUNT = 3; +static int g_sigCount = 0; +static void SigPrint(int sig) +{ + g_sigCount++; +} + +static int TestRaiseMuliti() +{ + int sig = SIGTERM; + int count = 0; + void (*ret)(int); + int retValue; + + g_sigCount = 0; + ret = signal(sig, SigPrint); + ICUNIT_ASSERT_NOT_EQUAL(ret, NULL, ret); + + while (1) { + retValue = raise(sig); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + usleep(10000); // 10000, Used to calculate the delay time. + count++; + if (count >= SIG_TEST_COUNT) { + break; + } + } + + return g_sigCount; +} + +static int TestCase(void) +{ + int count = TestRaiseMuliti(); + ICUNIT_ASSERT_EQUAL(count, SIG_TEST_COUNT, count); + + int pid = fork(); + if (pid == 0) { + int retValue; + printf("sigprocmask(1, NULL, NULL);\n"); + retValue = sigprocmask(1, NULL, NULL); + if (retValue != 0) { + printf("errline = %d\n", __LINE__); + exit(-1); + } + printf("raise(SIGSTOP);\n"); + raise(SIGSTOP); + + int ret = kill(10, 0); // 10, kill process pid. + if (retValue != -1 || errno != ESRCH) { + exit(-1); + } + + ret = kill(99999, 0); // 99999, kill process pid. + if (retValue != -1 || errno != ESRCH) { + printf("errline = %d\n", __LINE__); + exit(-1); + } + ret = kill(10, 31); // 10, kill process pid; 31, signal. + if (retValue != -1 || errno != EINVAL) { + printf("errline = %d\n", __LINE__); + exit(-1); + } + ret = kill(10, 32); // 10, kill process pid; 32, signal. + if (retValue != -1 || errno != EINVAL) { + printf("errline = %d\n", __LINE__); + exit(-1); + } + + ret = kill(2, 32); // 2, kill process pid; 32, signal. + if (retValue != -1 || errno != EINVAL) { + printf("errline = %d\n", __LINE__); + exit(-1); + } + + printf("test EPERM begin\n"); + ret = kill(2, 5); // 2, kill process pid; 5, signal. + if (retValue != -1 || errno != EPERM) { + printf("errline = %d\n", __LINE__); + exit(-1); + } + + ret = kill(3, 5); // 3, kill process pid; 5, signal. + if (retValue != -1 || errno != EPERM) { + printf("errline = %d\n", __LINE__); + exit(-1); + } + + ret = kill(0, 5); // 5, kill sigal num. + if (retValue != -1 || errno != EPERM) { + printf("errline = %d\n", __LINE__); + exit(-1); + } + + ret = kill(1, 5); // 5, kill signal num . + if (retValue != -1 || errno != EPERM) { + printf("errline = %d\n", __LINE__); + exit(-1); + } + + printf("test kill ok\n"); + retValue = raise(SIGSTOP); + if (retValue != 0) { + printf("errline = %d\n", __LINE__); + exit(-1); + } + int status, rt; + signal(SIGALRM, SigPrint); + sigset_t sigmask, oldmask, pending; + sigemptyset(&sigmask); + sigemptyset(&oldmask); + sigemptyset(&pending); + sigpending(&pending); + if (sigisemptyset(&pending) != 1) { + printf("errline = %d\n", __LINE__); + exit(-1); + } + sigaddset(&sigmask, SIGALRM); + sigaddset(&sigmask, SIGUSR1); + sigprocmask(SIG_BLOCK, &sigmask, &oldmask); + sigpending(&pending); + if (sigisemptyset(&pending) != 1) { + printf("errline = %d\n", __LINE__); + exit(-1); + } + if (sigisemptyset(&oldmask) != 1) { + printf("errline = %d\n", __LINE__); + exit(-1); + } + + printf("1 pending=%lu\n", pending.__bits[0]); + printf("1 oldmask=%lu\n", oldmask.__bits[0]); + printf("before raise\n"); + raise(SIGALRM); + printf("after raise\n"); + sigpending(&pending); + if (sigismember(&pending, SIGALRM) != 1) { + printf("errline = %d\n", __LINE__); + exit(-1); + } + printf("pending=%d,sigismem = %lu\n", pending.__bits[0], sigismember(&pending, SIGALRM)); + exit(0); + } + sleep(1); + int status; + signal(SIGALRM, SIG_DFL); + int retValue = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(retValue, pid, retValue); + return 0; +} + +void ItPosixSignal001(void) +{ + TEST_ADD_CASE("IT_POSIX_SIGNAL_001", TestCase, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_003.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_003.cpp new file mode 100644 index 00000000..ce0c1727 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_003.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" +#include "sys/wait.h" + +static const int SIG_TEST_COUNT = 3; +static int g_sigCount = 0; +static void SigPrint(int sig) +{ + g_sigCount++; +} + +static int TestRaise() +{ + int count = 0; + int status = 0; + int fpid; + int fatherPid; + int sonPid; + void (*ret)(int) = NULL; + int retValue; + + g_sigCount = 0; + ret = signal(SIGTERM, SigPrint); + ICUNIT_ASSERT_NOT_EQUAL(ret, NULL, ret); + retValue = raise(SIGTERM); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + fatherPid = getpid(); + fpid = fork(); + // fpid check err + ICUNIT_ASSERT_WITHIN_EQUAL(fpid, 0, UINT_MAX, fpid); + if (fpid == 0) { + while (1) { + usleep(500000); // 500000, Used to calculate the delay time. + count++; + if (g_sigCount == SIG_TEST_COUNT) { + break; + } + // check child process num + // 0 means count should be positive and 2 controls the upper bound of count + if ((count) < (0) || (count) > (SIG_TEST_COUNT * 2)) { + exit(count); + } + } + exit(0); + } else { // parent threa + sonPid = fpid; + usleep(10); // 10, Used to calculate the delay time. + while (1) { + retValue = kill(sonPid, SIGTERM); + + sleep(1); + count++; + if (count == SIG_TEST_COUNT) { + break; + } + } + retValue = waitpid(sonPid, &status, 0); + ICUNIT_ASSERT_EQUAL(retValue, sonPid, retValue); + ICUNIT_ASSERT_EQUAL(WEXITSTATUS(status), 0, WEXITSTATUS(status)); + } + return g_sigCount; +} + +static int TestCase(void) +{ + int count = TestRaise(); + // count should be 1, for global variables are not shared between different processors + ICUNIT_ASSERT_EQUAL(count, 1, count); + return 0; +} + +void ItPosixSignal003(void) +{ + TEST_ADD_CASE("IT_POSIX_SIGNAL_003", TestCase, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_004.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_004.cpp new file mode 100644 index 00000000..2e65400b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_004.cpp @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" +#include "sys/wait.h" + +static const int SIG_TEST_COUNT = 3; +static int g_sigCount = 0; +static void SigPrint(int sig) +{ + g_sigCount++; +} + +/* child process kill msg to father , father receive msg and do func , wake up the pend thread */ +static int TestRaiseWake() +{ + int count = 0; + int fpid; + int fatherPid; + int status, retValue; + void (*retSig)(int); + + g_sigCount = 0; + retSig = signal(SIGTERM, SigPrint); + ICUNIT_ASSERT_NOT_EQUAL(retSig, NULL, retSig); + fatherPid = getpid(); + fpid = fork(); + // fpid check err + ICUNIT_ASSERT_WITHIN_EQUAL(fpid, 0, UINT_MAX, fpid); + if (fpid == 0) { + while (1) { + retValue = kill(fatherPid, SIGTERM); + if (retValue != 0) { + exit(retValue); + } + usleep(100000); // 100000, Used to calculate the delay time. + count++; + if (count == SIG_TEST_COUNT) { + break; + } + } + exit(0); + } else { // parent threa + usleep(10); // 10, Used to calculate the delay time. + while (1) { + count++; + usleep(3000); // 3000, Used to calculate the delay time. + if (g_sigCount == SIG_TEST_COUNT) { + break; + } + // check child process num + ICUNIT_ASSERT_WITHIN_EQUAL(count, 0, SIG_TEST_COUNT * 30, count); // 30, assert that function Result is equal to this. + } + retValue = waitpid(fpid, &status, 0); + ICUNIT_ASSERT_EQUAL(retValue, fpid, retValue); + ICUNIT_ASSERT_EQUAL(WEXITSTATUS(status), 0, WEXITSTATUS(status)); + } + return g_sigCount; +} + +static int TestCase(void) +{ + int retValue, status; + + int fpid = fork(); + if (fpid == 0) { + retValue = TestRaiseWake(); + if (retValue != SIG_TEST_COUNT) { + exit(retValue); + } + exit(0); + } + retValue = waitpid(fpid, &status, 0); + ICUNIT_ASSERT_EQUAL(retValue, fpid, retValue); + ICUNIT_ASSERT_EQUAL(WEXITSTATUS(status), 0, WEXITSTATUS(status)); + return 0; +} + +void ItPosixSignal004(void) +{ + TEST_ADD_CASE("IT_POSIX_SIGNAL_004", TestCase, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_005.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_005.cpp new file mode 100644 index 00000000..b70c58ab --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_005.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" +#include "sys/wait.h" + +static void SigPrint(int sig) +{ + printf("rase\n"); +} +static int TestSigDefAction() +{ + void (*ret)(int); + int retValue; + + ret = signal(SIGALRM, SigPrint); + ICUNIT_ASSERT_NOT_EQUAL(ret, NULL, ret); + retValue = raise(SIGALRM); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + sleep(1); + retValue = raise(SIGALRM); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + return 0; +} + +void ItPosixSignal005(void) +{ + TEST_ADD_CASE("IT_POSIX_SIGNAL_005", TestSigDefAction, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_006.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_006.cpp new file mode 100644 index 00000000..b1644707 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_006.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" +#include "sys/wait.h" + +static void SigAlarm(int) +{ + printf("alert rings\n"); +} + +static int TestSigDefActionChild() +{ + int retValue, fpid, status; + void (*ret)(int) = NULL; + + ret = signal(SIGALRM, SigAlarm); + ICUNIT_ASSERT_NOT_EQUAL(ret, NULL, ret); + retValue = raise(SIGALRM); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + sleep(1); + fpid = fork(); + ICUNIT_ASSERT_WITHIN_EQUAL(fpid, 0, UINT_MAX, fpid); + if (fpid == 0) { + retValue = raise(SIGALRM); + if (retValue != 0) { + exit(retValue); + } + exit(0); + } + retValue = waitpid(fpid, &status, 0); + ICUNIT_ASSERT_EQUAL(retValue, fpid, retValue); + ICUNIT_ASSERT_EQUAL(WEXITSTATUS(status), 0, WEXITSTATUS(status)); + return 0; +} + +void ItPosixSignal006(void) +{ + TEST_ADD_CASE("IT_POSIX_SIGNAL_006", TestSigDefActionChild, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_007.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_007.cpp new file mode 100644 index 00000000..906582bf --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_007.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" +#include "sys/wait.h" + +static int g_break = 0; +/* Sample : Father process want to free zombine child process */ +static void SigChildResponse(int signo) +{ + printf("Child Response\n"); + wait(nullptr); +} + +/* Register SIGCHLD, through signal to restore the child memory */ +static int TestSigKillResp() +{ + void (*ret)(int) = nullptr; + int fpid, fpids, status, retValue; + + signal(SIGCHLD, SigChildResponse); + fpid = fork(); + ICUNIT_ASSERT_WITHIN_EQUAL(fpid, 0, UINT_MAX, fpid); + if (fpid == 0) { + fpids = fork(); + if (fpids == 0) { + while (1) { + sleep(2); // 2, sleep 10 second. + } + } + usleep(10000); // 10000, Used to calculate the delay time. + retValue = kill(fpids, SIGKILL); + if (retValue != 0) { + exit(retValue); + } + retValue = waitpid(fpids, NULL, 0); + if (retValue != fpids) { + exit(retValue); + } + exit(0); + } + retValue = waitpid(fpid, &status, 0); + ICUNIT_ASSERT_EQUAL(retValue, fpid, retValue); + ICUNIT_ASSERT_EQUAL(WEXITSTATUS(status), 0, WEXITSTATUS(status)); + ret = signal(SIGCHLD, SIG_DFL); + + return 0; +} + +void ItPosixSignal007(void) +{ + TEST_ADD_CASE("IT_POSIX_SIGNAL_007", TestSigKillResp, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_008.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_008.cpp new file mode 100644 index 00000000..acbc6d3f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_008.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" +#include "sys/wait.h" + +/* Sample : Father process want to free zombine child process */ +void SigChildResponse(int signo) +{ + wait(nullptr); +} + +/* Register SIGCHLD, through signal to restore the child memory */ +static int TestSigKillWaitFromSigChild() +{ + void (*ret)(int); + int sig = SIGINT; + int fpid, fpids, status, retValue; + ret = signal(sig, SIG_IGN); + ICUNIT_ASSERT_NOT_EQUAL(ret, NULL, ret); + + ret = signal(sig, SigChildResponse); + ICUNIT_ASSERT_NOT_EQUAL(ret, NULL, ret); + fpid = fork(); + ICUNIT_ASSERT_WITHIN_EQUAL(fpid, 0, UINT_MAX, fpid); + if (fpid == 0) { + fpids = fork(); + if (fpids == 0) { + while (1) { + sleep(2); // 2, sleep 10 second. + } + } + usleep(10000); // 10000, Used to calculate the delay time. + retValue = kill(fpids, SIGKILL); + if (retValue != 0) { + exit(retValue); + } + retValue = waitpid(fpids, &status, 0); + if (retValue != fpids) { + exit(retValue); + } + exit(0); + } + retValue = waitpid(fpid, &status, 0); + ICUNIT_ASSERT_EQUAL(retValue, fpid, retValue); + ICUNIT_ASSERT_EQUAL(WEXITSTATUS(status), 0, WEXITSTATUS(status)); + + ret = signal(sig, SIG_DFL); + ICUNIT_ASSERT_NOT_EQUAL(ret, NULL, ret); + + return 0; +} + +void ItPosixSignal008(void) +{ + TEST_ADD_CASE("IT_POSIX_SIGNAL_008", TestSigKillWaitFromSigChild, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, + TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_010.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_010.cpp new file mode 100644 index 00000000..a8fa2800 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_010.cpp @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" + +static int g_sigCount = 0; +static void SigPrint(int sig) +{ + g_sigCount++; +} + +static void SigPrint1(int sig) +{ + g_sigCount += 100; // 100, Used to calculate the progress of the program. +} + +static int TestSigWait() +{ + sigset_t set; + int sig, fpid, retValue, status; + void (*retSig)(int); + signal(SIGCHLD, SIG_DFL); + retSig = signal(SIGALRM, SigPrint1); + ICUNIT_ASSERT_NOT_EQUAL(retSig, NULL, retSig); + + retSig = signal(SIGUSR1, SigPrint1); + ICUNIT_ASSERT_NOT_EQUAL(retSig, NULL, retSig); + retValue = sigemptyset(&set); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + retValue = sigaddset(&set, SIGALRM); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + retValue = sigaddset(&set, SIGUSR1); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + int count = 0; + fpid = fork(); + ICUNIT_ASSERT_WITHIN_EQUAL(fpid, 0, UINT_MAX, fpid); + if (fpid == 0) { + printf("sig wait begin\n"); + while (1) { + retValue = sigwait(&set, &sig); + if (retValue != 0) { + exit(retValue); + } + printf("sig wait end\n"); + count++; + if (count == 3) { // 3, Possible values for the current parameter + break; + } + } + exit(0); + } + sleep(1); + retValue = kill(fpid, SIGUSR1); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + sleep(1); + retValue = kill(fpid, SIGALRM); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + sleep(1); + retValue = kill(fpid, SIGALRM); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + + retValue = waitpid(fpid, &status, 0); + ICUNIT_ASSERT_EQUAL(retValue, fpid, retValue); + ICUNIT_ASSERT_EQUAL(WEXITSTATUS(status), 0, WEXITSTATUS(status)); + + signal(SIGALRM, SIG_DFL); + signal(SIGUSR1, SIG_DFL); + return 0; +} + +void ItPosixSignal010(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestSigWait, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_011.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_011.cpp new file mode 100644 index 00000000..1e84c4da --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_011.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" + +static void SigPrint(int sig) +{ + return; +} + +static int TestSigTimeWait() +{ + sigset_t set; + int sig, fpid, retValue, status; + siginfo_t si; + struct timespec ts; + void (*retSig)(int); + ts.tv_sec = 2; // 2, set the sec of timeout. + ts.tv_nsec = 0; + retSig = signal(SIGALRM, SigPrint); + ICUNIT_ASSERT_NOT_EQUAL(retSig, NULL, retSig); + + retSig = signal(SIGUSR1, SigPrint); + ICUNIT_ASSERT_NOT_EQUAL(retSig, NULL, retSig); + retValue = sigemptyset(&set); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + retValue = sigaddset(&set, SIGALRM); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + retValue = sigaddset(&set, SIGUSR1); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + int count = 0; + fpid = fork(); + ICUNIT_ASSERT_WITHIN_EQUAL(fpid, 0, UINT_MAX, fpid); + if (fpid == 0) { + printf("sig wait begin\n"); + while (1) { + retValue = sigtimedwait(&set, &si, &ts); + if (retValue == -1 && errno != EAGAIN) { + exit(errno); + } + printf("sig wait end\n"); + count++; + if (count == 3) { // 3, Possible values for the current parameter + break; + } + } + exit(0); + } + sleep(1); + retValue = kill(fpid, SIGUSR1); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + sleep(1); + retValue = kill(fpid, SIGALRM); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + + retValue = waitpid(fpid, &status, 0); + ICUNIT_ASSERT_EQUAL(retValue, fpid, retValue); + ICUNIT_ASSERT_EQUAL(WEXITSTATUS(status), 0, WEXITSTATUS(status)); + signal(SIGALRM, SIG_DFL); + signal(SIGUSR1, SIG_DFL); + return 0; +} + +void ItPosixSignal011(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestSigTimeWait, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_012.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_012.cpp new file mode 100644 index 00000000..1e14d2c2 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_012.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" + +void SigAlarm(int signum) +{ + printf("Alert Rings\n"); +} + +static int TestSigTimeWaitMultiPthread() +{ + int retValue; + int fpid, status; + + signal(SIGALRM, SigAlarm); + + fpid = fork(); + ICUNIT_ASSERT_WITHIN_EQUAL(fpid, 0, UINT_MAX, fpid); + if (fpid == 0) { + sigset_t waitSet; + retValue = sigemptyset(&waitSet); + if (retValue != 0) { + exit(retValue); + } + retValue = sigaddset(&waitSet, SIGALRM); + if (retValue != 0) { + exit(retValue); + } + + alarm(1); + int receivedSignal; + retValue = sigwait(&waitSet, &receivedSignal); + if (retValue != 0) { + exit(retValue); + } + if (receivedSignal != SIGALRM) { + exit(receivedSignal); + } + exit(0); + } + + retValue = waitpid(fpid, &status, 0); + ICUNIT_ASSERT_EQUAL(retValue, fpid, retValue); + ICUNIT_ASSERT_EQUAL(WEXITSTATUS(status), 0, WEXITSTATUS(status)); + return 0; +} + +void ItPosixSignal012(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestSigTimeWaitMultiPthread, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_015.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_015.cpp new file mode 100644 index 00000000..7e05440d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_015.cpp @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" + +static int g_sigCount = 0; +static void SigPrint(int sig) +{ + g_sigCount = 1; +} + +static int TestPauseNormal() +{ + void (*retSig)(int); + int retValue; + + int status; + errno = 0; + retSig = signal(SIGPWR, SigPrint); + ICUNIT_ASSERT_NOT_EQUAL(retSig, NULL, retSig); + ICUNIT_ASSERT_EQUAL(errno, 0, errno); + + int fpid = fork(); + ICUNIT_ASSERT_WITHIN_EQUAL(fpid, 0, UINT_MAX, fpid); + if (fpid == 0) { + printf("child pause 1\n"); + sigset_t newset; + sigemptyset(&newset); + sigprocmask(SIG_SETMASK, &newset, nullptr); + sigaddset(&newset, SIGUSR1); + sigprocmask(SIG_BLOCK, &newset, nullptr); + int ret1 = pause(); + printf("child pause end 1 retSig = %d, errno=%d\n", ret1, errno); + exit(errno); + } + + sleep(1); + printf("father kill SIGUSR1 child not exec\n"); + retValue = kill(fpid, SIGUSR1); + sleep(1); + printf("father sleep then send signal to wake child\n"); + + retValue = kill(fpid, SIGPWR); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + retValue = waitpid(fpid, &status, 0); + ICUNIT_ASSERT_EQUAL(retValue, fpid, retValue); + ICUNIT_ASSERT_EQUAL(WEXITSTATUS(status), EINTR, WEXITSTATUS(status)); + + /* Child pause, then father kill child */ + fpid = fork(); + ICUNIT_ASSERT_WITHIN_EQUAL(fpid, 0, UINT_MAX, fpid); + if (fpid == 0) { + printf("child pause 2\n"); + pause(); + if (g_sigCount != 1) { + exit(g_sigCount); + } + printf("child pause end 2\n"); + exit(0); + } + printf("father sleep 2 then send signal to wake child\n"); + sleep(1); + printf("father kill fpid = %d\n", fpid); + retValue = kill(fpid, SIGKILL); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + retValue = waitpid(fpid, &status, 0); + ICUNIT_ASSERT_EQUAL(retValue, fpid, retValue); + ICUNIT_ASSERT_EQUAL(WIFEXITED(status), 0, WIFEXITED(status)); + ICUNIT_ASSERT_EQUAL(WIFSIGNALED(status), 1, WIFSIGNALED(status)); + ICUNIT_ASSERT_EQUAL(WTERMSIG(status), SIGKILL, WTERMSIG(status)); + + return 0; +} + +void ItPosixSignal015(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestPauseNormal, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_016.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_016.cpp new file mode 100644 index 00000000..01e276fc --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_016.cpp @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" + +static void SigPrint(int sig) +{ + (void)sig; + printf("%s%d\n", __FUNCTION__, __LINE__); +} + +static void *ThreadSetFunc2(void *arg) +{ + int retValue; + + sigset_t set; + int sig; + retValue = sigemptyset(&set); + ICUNIT_ASSERT_EQUAL_NULL(retValue, 0, retValue); + retValue = sigaddset(&set, SIGALRM); + ICUNIT_ASSERT_EQUAL_NULL(retValue, 0, retValue); + retValue = sigaddset(&set, SIGUSR1); + ICUNIT_ASSERT_EQUAL_NULL(retValue, 0, retValue); + + retValue = sigwait(&set, &sig); + ICUNIT_ASSERT_EQUAL_NULL(retValue, 0, retValue); + return NULL; +} + +static void *ThreadSetDfl(void *arg) +{ + int retValue; + + sigset_t set; + int sig; + retValue = sigemptyset(&set); + ICUNIT_ASSERT_EQUAL_NULL(retValue, 0, retValue); + retValue = sigaddset(&set, SIGALRM); + ICUNIT_ASSERT_EQUAL_NULL(retValue, 0, retValue); + retValue = sigaddset(&set, SIGUSR1); + ICUNIT_ASSERT_EQUAL_NULL(retValue, 0, retValue); + + retValue = sigwait(&set, &sig); + ICUNIT_ASSERT_EQUAL_NULL(retValue, 0, retValue); + return NULL; +} + +static void *ThreadKill(void *arg) +{ + (void)arg; + while (1) { + sleep(1); + } +} + +static int TestMultiPthreadKillPendNormal() +{ + int status, retValue, fpid; + pthread_t thread, thread1, thread2; + + fpid = fork(); + if (fpid == 0) { + retValue = pthread_create(&thread1, NULL, ThreadSetDfl, 0); + if (retValue != 0) { + exit(retValue); + } + retValue = pthread_create(&thread2, NULL, ThreadSetFunc2, 0); + if (retValue != 0) { + exit(retValue); + } + retValue = pthread_create(&thread, NULL, ThreadKill, 0); + if (retValue != 0) { + exit(retValue); + } + + pthread_join(thread, NULL); + pthread_join(thread1, NULL); + pthread_join(thread2, NULL); + + sigset_t set; + int sig; + retValue = sigemptyset(&set); + if (retValue != 0) { + exit(retValue); + } + retValue = sigaddset(&set, SIGALRM); + if (retValue != 0) { + exit(retValue); + } + retValue = sigaddset(&set, SIGUSR1); + if (retValue != 0) { + exit(retValue); + } + + retValue = sigwait(&set, &sig); + if (retValue != 0) { + exit(retValue); + } + printf("here exit\n"); + exit(0); + } + sleep(1); + /* Father kill child, then it will wake child */ + retValue = kill(fpid, SIGKILL); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + printf("father wait child dead\n"); + retValue = waitpid(fpid, &status, 0); + ICUNIT_ASSERT_EQUAL(retValue, fpid, retValue); + printf("status = %d\n", WEXITSTATUS(status)); + ICUNIT_ASSERT_EQUAL(WIFEXITED(status), 0, WIFEXITED(status)); + ICUNIT_ASSERT_EQUAL(WIFSIGNALED(status), 1, WIFSIGNALED(status)); + ICUNIT_ASSERT_EQUAL(WTERMSIG(status), SIGKILL, WTERMSIG(status)); + return 0; +} + +void ItPosixSignal016(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestMultiPthreadKillPendNormal, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_017.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_017.cpp new file mode 100644 index 00000000..675e8569 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_017.cpp @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" + +static void SigPrint(int sig) +{ + (void)sig; + printf("%s%d\n", __FUNCTION__, __LINE__); +} + +static void *ThreadSetFunc2(void *arg) +{ + int retValue; + + sigset_t set; + int sig; + retValue = sigemptyset(&set); + ICUNIT_ASSERT_EQUAL_NULL(retValue, 0, retValue); + retValue = sigaddset(&set, SIGALRM); + ICUNIT_ASSERT_EQUAL_NULL(retValue, 0, retValue); + retValue = sigaddset(&set, SIGUSR1); + ICUNIT_ASSERT_EQUAL_NULL(retValue, 0, retValue); + + retValue = sigwait(&set, &sig); + ICUNIT_ASSERT_EQUAL_NULL(retValue, 0, retValue); + + return NULL; +} + +static void *ThreadSetDfl(void *arg) +{ + int retValue; + + sigset_t set; + int sig; + retValue = sigemptyset(&set); + ICUNIT_ASSERT_EQUAL_NULL(retValue, 0, retValue); + retValue = sigaddset(&set, SIGALRM); + ICUNIT_ASSERT_EQUAL_NULL(retValue, 0, retValue); + retValue = sigaddset(&set, SIGUSR1); + ICUNIT_ASSERT_EQUAL_NULL(retValue, 0, retValue); + + retValue = sigwait(&set, &sig); + ICUNIT_ASSERT_EQUAL_NULL(retValue, 0, retValue); + + return NULL; +} + +static void *ThreadKill(void *arg) +{ + int retValue; + + sigset_t set; + int sig; + retValue = sigemptyset(&set); + ICUNIT_ASSERT_EQUAL_NULL(retValue, 0, retValue); + retValue = sigaddset(&set, SIGALRM); + ICUNIT_ASSERT_EQUAL_NULL(retValue, 0, retValue); + retValue = sigaddset(&set, SIGUSR1); + ICUNIT_ASSERT_EQUAL_NULL(retValue, 0, retValue); + + retValue = sigwait(&set, &sig); + ICUNIT_ASSERT_EQUAL_NULL(retValue, 0, retValue); + + return NULL; +} + +static int TestMultiPthreadFatherProcessExit() +{ + int status = 0; + int retValue; + int fpid, fpids; + + pthread_t thread, thread1, thread2; + int father; + + fpid = fork(); + ICUNIT_ASSERT_WITHIN_EQUAL(fpid, 0, UINT_MAX, fpid); + if (fpid == 0) { + fpids = fork(); + ICUNIT_ASSERT_WITHIN_EQUAL(fpids, 0, UINT_MAX, fpids); + if (fpids == 0) { + retValue = pthread_create(&thread, NULL, ThreadKill, 0); + if (retValue != 0) { + exit(retValue); + } + retValue = pthread_create(&thread2, NULL, ThreadSetFunc2, 0); + if (retValue != 0) { + exit(retValue); + } + retValue = pthread_create(&thread1, NULL, ThreadSetDfl, 0); + if (retValue != 0) { + exit(retValue); + } + + father = getppid(); + printf("fatherPid = %d\n", father); + sleep(1); + printf("child kill father = %d\n", father); + retValue = kill(father, SIGKILL); + if (retValue != 0) { + exit(retValue); + } + } + sleep(1); + retValue = waitpid(fpids, &status, 0); + // grandchild process kill father process, so child process is recovered by init process + // child process doesn't receive termination signal from grandchild process + // so waitpid() returns -1 + ICUNIT_ASSERT_EQUAL(retValue, -1, retValue); + exit(1); + } + sleep(1); + retValue = waitpid(fpid, &status, 0); + ICUNIT_ASSERT_EQUAL(retValue, fpid, retValue); + ICUNIT_ASSERT_EQUAL(WIFEXITED(status), 0, WIFEXITED(status)); + ICUNIT_ASSERT_EQUAL(WIFSIGNALED(status), 1, WIFSIGNALED(status)); + ICUNIT_ASSERT_EQUAL(WTERMSIG(status), SIGKILL, WTERMSIG(status)); + return 0; +} + +void ItPosixSignal017(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestMultiPthreadFatherProcessExit, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_018.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_018.cpp new file mode 100644 index 00000000..cf7d275a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_018.cpp @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" + +static void SigPrint(int sig) +{ + (void)sig; + printf("%s%d\n", __FUNCTION__, __LINE__); +} + +static int TestSigTimeWaitKillProcess(void) +{ + sigset_t set; + int sig, fpid, retValue, status; + siginfo_t si; + struct timespec ts; + + ts.tv_sec = 2; // 2, set the sec of timeout. + ts.tv_nsec = 0; + void (*retSig)(int); + retSig = signal(SIGALRM, SigPrint); + ICUNIT_ASSERT_NOT_EQUAL(retSig, NULL, retSig); + + retSig = signal(SIGUSR1, SigPrint); + ICUNIT_ASSERT_NOT_EQUAL(retSig, NULL, retSig); + retValue = sigemptyset(&set); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + retValue = sigaddset(&set, SIGALRM); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + retValue = sigaddset(&set, SIGUSR1); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + int count = 0; + fpid = fork(); + ICUNIT_ASSERT_WITHIN_EQUAL(fpid, 0, UINT_MAX, fpid); + if (fpid == 0) { + printf("sig wait begin\n"); + while (1) { + retValue = sigtimedwait(&set, &si, &ts); + if (retValue != SIGUSR1) { + exit(retValue); + } + printf("sig wait end\n"); + count++; + if (count == 3) { // 3, Possible values for the current parameter + break; + } + } + exit(0); + } + sleep(1); + retValue = kill(fpid, SIGUSR1); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + sleep(1); + retValue = kill(fpid, SIGKILL); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + + retValue = waitpid(fpid, &status, 0); + ICUNIT_ASSERT_EQUAL(retValue, fpid, retValue); + ICUNIT_ASSERT_EQUAL(WIFEXITED(status), 0, WIFEXITED(status)); + ICUNIT_ASSERT_EQUAL(WIFSIGNALED(status), 1, WIFSIGNALED(status)); + ICUNIT_ASSERT_EQUAL(WTERMSIG(status), SIGKILL, WTERMSIG(status)); + + signal(SIGALRM, SIG_DFL); + signal(SIGUSR1, SIG_DFL); + return 0; +} + + +void ItPosixSignal018(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestSigTimeWaitKillProcess, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_019.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_019.cpp new file mode 100644 index 00000000..0235fc91 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_019.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" + +static void SigPrint(int sig) +{ + (void)sig; + printf("%s%d\n", __FUNCTION__, __LINE__); +} + +static int TestSigTimeWaitDirectKillChild(void) +{ + sigset_t set; + int sig, fpid, retValue, status; + siginfo_t si; + struct timespec ts; + + ts.tv_sec = 2; // 2, set the sec of timeout. + ts.tv_nsec = 0; + printf("1 sig wait begin\n"); + void (*retSig)(int); + retSig = signal(SIGALRM, SigPrint); + ICUNIT_ASSERT_NOT_EQUAL(retSig, NULL, retSig); + retSig = signal(SIGUSR1, SigPrint); + ICUNIT_ASSERT_NOT_EQUAL(retSig, NULL, retSig); + retValue = sigemptyset(&set); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + retValue = sigaddset(&set, SIGALRM); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + retValue = sigaddset(&set, SIGUSR1); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + int count = 0; + fpid = fork(); + ICUNIT_ASSERT_WITHIN_EQUAL(fpid, 0, UINT_MAX, fpid); + if (fpid == 0) { + printf("sig wait begin\n"); + while (1) { + retValue = sigtimedwait(&set, &si, &ts); + if (retValue != 0) { + exit(retValue); + } + printf("sig wait end\n"); + count++; + if (count == 3) { // 3, Possible values for the current parameter + break; + } + } + exit(0); + } + sleep(1); + /* direct kill the child */ + retValue = kill(fpid, SIGKILL); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + + retValue = waitpid(fpid, &status, 0); + ICUNIT_ASSERT_EQUAL(retValue, fpid, retValue); + ICUNIT_ASSERT_EQUAL(WIFEXITED(status), 0, WIFEXITED(status)); + ICUNIT_ASSERT_EQUAL(WIFSIGNALED(status), 1, WIFSIGNALED(status)); + ICUNIT_ASSERT_EQUAL(WTERMSIG(status), SIGKILL, WTERMSIG(status)); + signal(SIGALRM, SIG_DFL); + signal(SIGUSR1, SIG_DFL); + return 0; +} + +void ItPosixSignal019(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestSigTimeWaitDirectKillChild, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_020.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_020.cpp new file mode 100644 index 00000000..1821b792 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_020.cpp @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" + +static void SigHandler(int sig) // źŴ +{ + if (sig == SIGINT) { + printf("SIGINT sig\n"); + } else if (sig == SIGQUIT) { + printf("SIGQUIT sig\n"); + } else { + printf("SIGUSR1 sig\n"); + } +} + +static int TestSigSuspend() +{ + int status, retValue; + int fpid = fork(); + ICUNIT_ASSERT_WITHIN_EQUAL(fpid, 0, UINT_MAX, fpid); + if (fpid == 0) { + sigset_t newset, old, wait; + struct sigaction act; + printf("SIGUSR1 sig\n"); + act.sa_handler = SigHandler; + retValue = sigemptyset(&act.sa_mask); + if (retValue != 0) { + exit(retValue); + } + act.sa_flags = 0; + sigaction(SIGINT, &act, nullptr); + sigaction(SIGQUIT, &act, nullptr); + sigaction(SIGUSR1, &act, nullptr); + sigaction(SIGALRM, &act, nullptr); + + retValue = sigemptyset(&newset); + if (retValue != 0) { + exit(retValue); + } + retValue = sigaddset(&newset, SIGALRM); + if (retValue != 0) { + exit(retValue); + } + retValue = sigprocmask(SIG_BLOCK, &newset, &old); + if (retValue != 0) { + exit(retValue); + } + printf("newset 1 = %lx\n", newset.__bits[0]); + printf("old 1 = %lx\n", old.__bits[0]); + + retValue = sigemptyset(&newset); + if (retValue != 0) { + exit(retValue); + } + retValue = sigaddset(&newset, SIGQUIT); + if (retValue != 0) { + exit(retValue); + } + retValue = sigprocmask(SIG_BLOCK, &newset, &old); + if (retValue != 0) { + exit(retValue); + } + printf("newset 2 = %lx\n", newset.__bits[0]); + printf("old 2 = %lx\n", old.__bits[0]); + + retValue = sigemptyset(&newset); + if (retValue != 0) { + exit(retValue); + } + retValue = sigaddset(&newset, SIGINT); + if (retValue != 0) { + exit(retValue); + } + + retValue = sigprocmask(SIG_BLOCK, &newset, &old); + if (retValue != 0) { + exit(retValue); + } + printf("newset 1 = %lx\n", newset.__bits[0]); + printf("old 1 = %lx\n", old.__bits[0]); + + retValue = sigemptyset(&wait); + if (retValue != 0) { + exit(retValue); + } + retValue = sigaddset(&wait, SIGUSR1); + if (retValue != 0) { + exit(retValue); + } + printf("wait = %lx\n", wait.__bits[0]); + + if (sigsuspend(&wait) != -1) { + printf("sigsuspend error\n"); + return -1; + } + printf("After sigsuspend\n"); + if (retValue != 0) { + exit(retValue); + } + printf("old 2= %lx\n", old.__bits[0]); + + sigset_t pending; + retValue = sigemptyset(&pending); + if (retValue != 0) { + exit(retValue); + } + printf("pending 1= %lx\n", pending.__bits[0]); + retValue = raise(SIGINT); + if (retValue != 0) { + exit(retValue); + } + retValue = sigpending(&pending); + if (retValue != 0) { + exit(retValue); + } + printf("pending 2= %lx\n", pending.__bits[0]); + + retValue = raise(SIGALRM); + if (retValue != 0) { + exit(retValue); + } + retValue = sigpending(&pending); + if (retValue != 0) { + exit(retValue); + } + printf("pending 3= %lx\n", pending.__bits[0]); + exit(0); + } + + sleep(1); + printf("kill SIGUSR1\n"); + retValue = kill(fpid, SIGUSR1); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + sleep(1); + printf("kill SIGINT\n"); + retValue = kill(fpid, SIGINT); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + retValue = waitpid(fpid, &status, 0); + ICUNIT_ASSERT_EQUAL(retValue, fpid, retValue); + ICUNIT_ASSERT_EQUAL(WEXITSTATUS(status), 0, WEXITSTATUS(status)); + + sigset_t new1, old1; + struct sigaction act; + + fpid = fork(); + if (fpid == 0) { + act.sa_handler = SigHandler; + retValue = sigemptyset(&act.sa_mask); + act.sa_flags = 0; + sigaction(SIGINT, &act, nullptr); + sigaction(SIGQUIT, &act, nullptr); + sigaction(SIGUSR1, &act, nullptr); + + retValue = sigemptyset(&new1); + if (retValue != 0) { + exit(retValue); + } + retValue = sigaddset(&new1, SIGINT); + if (retValue != 0) { + exit(retValue); + } + retValue = sigprocmask(SIG_BLOCK, &new1, &old1); + if (retValue != 0) { + exit(retValue); + } + printf("new 1 = %lx\n", new1.__bits[0]); + printf("old 1 = %lx\n", old1.__bits[0]); + + retValue = kill(getpid(), SIGINT); + if (retValue != 0) { + exit(retValue); + } + retValue = raise(SIGUSR1); + if (retValue != 0) { + exit(retValue); + } + printf("raise 1 = %lx\n", new1.__bits[0]); + + exit(0); + } + + retValue = waitpid(fpid, &status, 0); + ICUNIT_ASSERT_EQUAL(retValue, fpid, retValue); + ICUNIT_ASSERT_EQUAL(WEXITSTATUS(status), 0, WEXITSTATUS(status)); + + return 0; +} + +void ItPosixSignal020(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestSigSuspend, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_025.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_025.cpp new file mode 100644 index 00000000..52e71e59 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_025.cpp @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" + +static void SigAlrm(int signum) +{ + printf("Alert rings.\n"); +} + +static int TestBlock() +{ + int sig = SIGALRM; + void *ret; + int retValue, status; + + int fpid = fork(); + if (fpid == 0) { + sigset(SIGALRM, SigAlrm); + int clock = 2; + printf("Alarm after %d seconds\n", clock); + alarm(clock); + for (int i = 0; i < 4; i++) { // 4, Number of cycles + printf("time = %d s\n", i); + sleep(1); + } + printf("\n\n"); + + printf("Hold the signal\n"); + retValue = sighold(sig); + if (retValue != 0) { + exit(retValue); + } + alarm(clock); + for (int i = 0; i < 4; i++) { // 4, Number of cycles + printf("time = %d s\n", i); + sleep(1); + } + printf("\n\n"); + + printf("Release the signal\n"); + retValue = sigrelse(sig); + if (retValue != 0) { + exit(retValue); + } + alarm(clock); + for (int i = 0; i < 4; i++) { // 4, Number of cycles + printf("time = %d s\n", i); + sleep(1); + } + printf("\n\n"); + + printf("Signal Pause(1)\n"); + printf("The process sleeps until alter rings (after 2 seconds)\n"); + alarm(clock); + retValue = sigpause(sig); + if (retValue != -1) { + exit(retValue); + } + printf("\n\n"); + + printf("Signal Pause(2)\n"); + printf("To test whether pause can release the signal\n"); + alarm(clock); + retValue = sighold(sig); + if (retValue != 0) { + exit(retValue); + } + retValue = sigpause(sig); + if (retValue != -1) { + exit(retValue); + } + printf("\n\n"); + + printf("Ignore the signal\n"); + retValue = sigignore(sig); + if (retValue != 0) { + exit(retValue); + } + alarm(clock); + for (int i = 0; i < 4; i++) { // 4, Number of cycles + printf("time = %d s\n", i); + sleep(1); + } + printf("\n\n"); + printf("Test Ends\n"); + + exit(0); + } + retValue = waitpid(fpid, &status, 0); + ICUNIT_ASSERT_EQUAL(retValue, fpid, retValue); + ICUNIT_ASSERT_EQUAL(WEXITSTATUS(status), 0, WEXITSTATUS(status)); + return 0; +} + +void ItPosixSignal025(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestBlock, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_026.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_026.cpp new file mode 100644 index 00000000..63293c6a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_026.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" +#define INVALID_SIG 1000 + +static void SigPrint(int signum) +{ + printf("Signal Triggered\n"); +} + +static UINT32 TestCase(VOID) +{ + int ret, sig; + struct itimerval newValue, oldValue; + siginfo_t info; + sigset_t newset; + struct timespec timeout; + + timeout.tv_nsec = 0; + timeout.tv_sec = 1; + + int fpid, status; + fpid = fork(); + if (fpid == 0) { + (void)signal(SIGCHLD, SigPrint); + sigemptyset(&newset); + sigaddset(&newset, SIGCHLD); + ret = sigtimedwait(&newset, &info, &timeout); + if (ret != -1) { + exit(ret); + } + if (errno != EAGAIN) { + exit(errno); + } + printf("---------------\n"); + + sigemptyset(&newset); + sigaddset(&newset, SIGCHLD); + timeout.tv_nsec = 1; + timeout.tv_sec = -1; + ret = sigtimedwait(&newset, &info, &timeout); + printf("ret = %d errno = %d EINVAL = %d\n", ret, errno, EINVAL); + if (ret != -1) { + exit(ret); + } + if (errno != EINVAL) { + exit(errno); + } + + sigemptyset(&newset); + sigaddset(&newset, SIGCHLD); + timeout.tv_nsec = 1; + timeout.tv_sec = 3; // 3, set the sec of timeout. + ret = sigtimedwait(&newset, reinterpret_cast(2), &timeout); // 2, wait for signal num + printf("ret = %d errno = %d EFAULT = %d\n", ret, errno, EFAULT); + if (ret != -1) { + exit(ret); + } + if (errno != EFAULT) { + exit(errno); + } + exit(0); + } + + sleep(2); // 2, sleep 10 second. + kill(fpid, SIGCHLD); + ret = waitpid(fpid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, fpid, ret); + ICUNIT_ASSERT_EQUAL(WEXITSTATUS(status), 0, WEXITSTATUS(status)); + return LOS_OK; +} + +void ItPosixSignal026(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_028.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_028.cpp new file mode 100644 index 00000000..ba48ed17 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_028.cpp @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" + +// print the sigset bit by biy +static void PrintSigset(sigset_t *set) +{ + for (int i = 0; i < 32; ++i) { // 32, Number of cycles + if (sigismember(set, i)) { + putchar('1'); + } else { + putchar('0'); + } + } + puts(""); +} + +static int TestSigset() +{ + // record mask words + sigset_t sigset; + + void *ret; + int retValue, status; + + int fpid = fork(); + if (fpid == 0) { + // clean the signal set + printf("EmptySet\n"); + retValue = sigemptyset(&sigset); + if (retValue != 0) { + exit(retValue); + } + printf("Current set is: \n"); + PrintSigset(&sigset); + printf("EmptySet End\n\n"); + + printf("IsEmptySet\n"); + retValue = sigisemptyset(&sigset); + if (retValue != 1) { + exit(retValue); + } + if (retValue == 1) { + printf("The set is empty\n"); + } else { + printf("The set is not empty\n"); + } + printf("IsEmptySet End\n\n"); + + printf("AddSet\n"); + retValue = sigaddset(&sigset, SIGINT); + if (retValue != 0) { + exit(retValue); + } + printf("Add SIGINT\n"); + printf("Current set is: \n"); + PrintSigset(&sigset); + printf("AddSet End\n\n"); + + printf("IsMember\n"); + retValue = sigismember(&sigset, SIGINT); + if (retValue != 1) { + exit(retValue); + } + if (retValue == 1) { + printf("The SIGINT is a member of set\n"); + } else { + printf("The SIGINT is not a member of set\n"); + } + printf("IsMember End\n\n"); + + printf("DelSet\n"); + retValue = sigdelset(&sigset, SIGINT); + if (retValue != 0) { + exit(retValue); + } + printf("Delete signal SIGINT\n"); + printf("Current set is: \n"); + PrintSigset(&sigset); + printf("DelSet End\n\n"); + + printf("FillSet\n"); + retValue = sigfillset(&sigset); + if (retValue != 0) { + exit(retValue); + } + printf("Current set is: \n"); + PrintSigset(&sigset); + printf("FillSet End\n\n"); + + sigset_t sigsetTmp; + sigemptyset(&sigsetTmp); + sigset_t sigsetTarget; + sigfillset(&sigset); + printf("AndSet\n"); + retValue = sigandset(&sigsetTarget, &sigset, &sigsetTmp); + if (retValue != 0) { + exit(retValue); + } + printf("And fullset with emptyset\n"); + printf("Current set is: \n"); + PrintSigset(&sigset); + if (sigisemptyset(&sigsetTarget)) { + printf("AndSet Succeed\n"); + } else { + printf("AndSet Fail\n"); + } + printf("AndSet End\n\n"); + + sigemptyset(&sigsetTarget); + printf("OrSet\n"); + retValue = sigorset(&sigsetTarget, &sigset, &sigsetTmp); + if (retValue != 0) { + exit(retValue); + } + printf("Or fullset with emptyset\n"); + printf("Current set is: \n"); + PrintSigset(&sigset); + if (!sigisemptyset(&sigsetTarget)) { + printf("OrSet Succeed\n"); + } else { + printf("OrSet Fail\n"); + } + printf("OrSet End\n\n"); + + exit(0); + } + + retValue = waitpid(fpid, &status, 0); + ICUNIT_ASSERT_EQUAL(retValue, fpid, retValue); + ICUNIT_ASSERT_EQUAL(WEXITSTATUS(status), 0, WEXITSTATUS(status)); + + return 0; +} + +void ItPosixSignal028(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestSigset, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_029.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_029.cpp new file mode 100644 index 00000000..c06e84bf --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_029.cpp @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" + +static int g_sigCount = 0; +static void SigPrint(int signum) +{ + g_sigCount++; + printf("signal receive success\n"); +} + +static UINT32 TestCase(VOID) +{ + int pid; + int ret, status; + sigset_t newset; + struct sigaction act; + + act.sa_handler = SigPrint; + sigemptyset(&act.sa_mask); + act.sa_flags = 0; + pid = fork(); + if (pid < 0) { + printf("Fork error\n"); + return LOS_NOK; + } else if (pid == 0) { + ret = sigaction(SIGUSR1, &act, nullptr); + if (ret != 0) { + exit(LOS_NOK); + } + sigemptyset(&newset); + sigaddset(&newset, SIGCHLD); + ret = sigsuspend(&newset); + printf("ret = %d errno = %d EINTR = %d\n", ret, errno, EINTR); + if (ret != -1 || errno != EINTR) { + exit(LOS_NOK); + } + + ret = sigsuspend(NULL); + if (ret != -1) { + exit(ret); + } + if (errno != EFAULT) { + exit(errno); + } + + ret = sigsuspend(reinterpret_cast(2)); // 2, suspend signal num. + if (ret != -1) { + exit(ret); + } + if (errno != EFAULT) { + exit(errno); + } + + ret = sigpending(NULL); + if (ret != -1) { + exit(ret); + } + if (errno != EFAULT) { + exit(errno); + } + + ret = sigpending(reinterpret_cast(2)); // 2, pending signal num. + if (ret != -1) { + exit(ret); + } + if (errno != EFAULT) { + exit(errno); + } + exit(LOS_OK); + } + sleep(1); + ret = kill(pid, SIGUSR1); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + printf("kill success\n"); + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ICUNIT_ASSERT_EQUAL(WEXITSTATUS(status), LOS_OK, WEXITSTATUS(status)); + + return LOS_OK; +} + +void ItPosixSignal029(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_030.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_030.cpp new file mode 100644 index 00000000..563f1273 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_030.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" + +static int g_sigCount = 0; +static void SigPrint(int sig) +{ + g_sigCount++; + printf("signal receive success\n"); +} + +static UINT32 TestCase(VOID) +{ + int pid; + int ret = 0; + struct sigaction act; + + act.sa_handler = SigPrint; + sigemptyset(&act.sa_mask); + act.sa_flags = 0; + pid = fork(); + if (pid < 0) { + printf("Fork error\n"); + return LOS_NOK; + } else if (pid == 0) { + ret = sigaction(SIGUSR1, &act, nullptr); + if (ret != 0) { + printf("ret = %d\n", ret); + exit(LOS_NOK); + } + ret = sigpause(SIGUSR1); + printf("ret = %d errno = %d EINTR = %d\n", ret, errno, EINTR); + if (ret == -1 && errno == EINTR) { + exit(LOS_OK); + } + sleep(10); // 10, sleep 10 second. + exit(LOS_NOK); + } + sleep(1); + ret = kill(pid, SIGUSR1); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + printf("kill success\n"); + wait(&ret); + ICUNIT_ASSERT_EQUAL(WEXITSTATUS(ret), LOS_OK, WEXITSTATUS(ret)); + return LOS_OK; +} + +void ItPosixSignal030(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_033.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_033.cpp new file mode 100644 index 00000000..11d725d4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_033.cpp @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" + +static int g_sigCount = 0; +static int g_sigCount1 = 0; +static void SigPrint(int sig) +{ + g_sigCount++; + printf("signal receive success\n"); +} + +static void SigPrint1(int sig) +{ + g_sigCount1++; + printf("signal receive success\n"); +} + +static UINT32 TestCase(VOID) +{ + int pid = 0; + int ret = 0; + void (*retptr)(int); + sigset_t newset, oldset; + + pid = fork(); + if (pid < 0) { + printf("Fork error\n"); + return LOS_NOK; + } else if (pid == 0) { + printf("test032 raise before\n"); + sigemptyset(&newset); + sigaddset(&newset, SIGUSR1); + sigaddset(&newset, SIGUSR2); + ret = sigprocmask(SIG_BLOCK, &newset, &oldset); + if (ret != 0) { + printf("error:sigprocmask\n"); + exit(LOS_NOK); + } + retptr = signal(SIGUSR1, SigPrint); + if (retptr == SIG_ERR) { + printf("error:signal\n"); + exit(LOS_NOK); + } + retptr = signal(SIGUSR2, SigPrint1); + if (retptr == SIG_ERR) { + printf("error:signal\n"); + exit(LOS_NOK); + } + raise(SIGUSR1); + raise(SIGUSR2); + sigdelset(&newset, SIGUSR2); + ret = sigprocmask(SIG_UNBLOCK, &newset, &oldset); + if (ret != 0) { + printf("error:sigprocmask\n"); + exit(LOS_NOK); + } + sleep(1); + if (!(g_sigCount == 1 && g_sigCount1 == 0)) { + printf("Assert failed in line %d\n", __LINE__); + printf("g_sigCount = %d, g_sigCount1 = %d\n", g_sigCount, g_sigCount1); + exit(LOS_NOK); + } + sigdelset(&newset, SIGUSR1); + sigaddset(&newset, SIGUSR2); + ret = sigprocmask(SIG_UNBLOCK, &newset, &oldset); + if (ret != 0) { + printf("error:sigprocmask\n"); + exit(LOS_NOK); + } + sleep(1); + if (!(g_sigCount == 1 && g_sigCount1 == 1)) { + printf("Assert failed in line %d\n", __LINE__); + printf("g_sigCount = %d, g_sigCount1 = %d\n", g_sigCount, g_sigCount1); + exit(LOS_NOK); + } + printf("test032 raise after\n"); + exit(LOS_OK); + } + + wait(&ret); + ICUNIT_ASSERT_EQUAL(WEXITSTATUS(ret), LOS_OK, WEXITSTATUS(ret)); + return LOS_OK; +} + +void ItPosixSignal033(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_038.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_038.cpp new file mode 100644 index 00000000..3e924deb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_038.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" + +static const int INVAILD_SIG = 1000; +static void *ThreadKillTest(void *arg) +{ + printf("Enter ThreadKillTest...\n"); + sleep(2); // 2, sleep 10 second. + printf("ThreadKillTest finished...\n"); + return NULL; +} +static UINT32 TestCase(VOID) +{ + int ret, status; + + int fpid = fork(); + if (fpid == 0) { + pthread_t thread1; + ret = pthread_create(&thread1, NULL, ThreadKillTest, 0); + if (ret != 0) { + exit(ret); + } + sleep(1); + ret = pthread_kill(thread1, INVAILD_SIG); + printf("ret = %d errno = %d EINVAL = %d\n", ret, errno, EINVAL); + if (ret != EINVAL) { + exit(ret); + } + // sleep 2 seconds + sleep(2); // 2, sleep 10 second. + pthread_join(thread1, NULL); + + exit(0); + } + + ret = waitpid(fpid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, fpid, ret); + ICUNIT_ASSERT_EQUAL(WEXITSTATUS(status), 0, WEXITSTATUS(status)); + return LOS_OK; +} + +void ItPosixSignal038(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_040.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_040.cpp new file mode 100644 index 00000000..76654c6a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_040.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" + +static int g_sigCount = 0; +static int g_sigCount1 = 0; +static void SigPrint(int sig) +{ + (void)sig; + g_sigCount++; + printf("signal receive success\cn"); +} + +static UINT32 TestCase(VOID) +{ + int pid = 0; + int ret = 0; + void *retptr = NULL; + sigset_t newset, oldset; + + sigemptyset(&newset); + sigprocmask(SIG_SETMASK, &newset, NULL); + + signal(SIGURG, SIG_IGN); + raise(SIGURG); + signal(SIGURG, SigPrint); + raise(SIGURG); + printf("g_sigCount=%d\n", g_sigCount); + sleep(1); + ICUNIT_ASSERT_EQUAL(g_sigCount, 1, g_sigCount); + + signal(SIGHUP, SigPrint); + signal(SIGUSR1, SigPrint); + pid = fork(); + if (pid == 0) { + signal(SIGHUP, SigPrint); + signal(SIGUSR1, SigPrint); + sigset_t set, set1; + sigemptyset(&set); + sigemptyset(&set1); + sigaddset(&set, SIGHUP); + sigaddset(&set1, SIGUSR1); + sigaddset(&set1, SIGHUP); + sigprocmask(SIG_BLOCK, &set1, NULL); + raise(SIGHUP); + raise(SIGUSR1); + printf("child\n"); + int rt = sigsuspend(&set); + printf("sigsuspend rt = %d, errno=%d\n", rt, errno); + exit(2); // 2, exit args + } else { + sleep(1); + kill(pid, SIGHUP); + printf("sighug\n"); + kill(pid, SIGUSR1); + wait(&ret); + printf("ret1 = %d,%d\n", ret, WEXITSTATUS(ret)); + ICUNIT_ASSERT_EQUAL(WEXITSTATUS(ret), 2, WEXITSTATUS(ret)); // 2, assert that function Result is equal to this. + } + return LOS_OK; +} + +void ItPosixSignal040(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_041.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_041.cpp new file mode 100644 index 00000000..c8c818a4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/full/signal_test_041.cpp @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" + +#include "pthread.h" + +static void Sigprint(int sig) +{ + (void)sig; + printf("enter sighandle : -------------------------\n"); +} +static void Sigprint111(int sig) +{ + (void)sig; + printf("enter sighandle : ---111----------------------\n"); +} + +static void *ThreadFunc7(void *arg) +{ + (void)arg; + int retval; + sigset_t set, oldset; + sighandler_t sigret; + printf("-----------------------------\n"); + sleep(1); + raise(SIGUSR2); + sleep(1); + sigret = signal(SIGUSR2, Sigprint); + + sleep(1); + raise(SIGUSR2); + retval = sigemptyset(&set); + if (retval == -1) { + exit(-1); + } + printf("line = %d\n", __LINE__); + retval = sigemptyset(&oldset); + if (retval == -1) { + exit(-1); + } + printf("line = %d\n", __LINE__); + retval = sigprocmask(SIG_SETMASK, &set, &oldset); + if (retval == -1) { + exit(-1); + } + retval = sigismember(&oldset, SIGTERM); + printf("th SIGTERM is in oldset:%d\n", retval); + if (retval != 1) { + exit(-1); + } + retval = sigismember(&oldset, SIGUSR1); + printf("th SIGUSR1 is in oldset:%d\n", retval); + if (retval != 1) { + exit(-1); + } + retval = sigismember(&oldset, SIGUSR2); + printf("th SIGUSR2 is in oldset:%d\n", retval); + if (retval != 0) { + exit(-1); + } + retval = sigprocmask(SIG_SETMASK, &oldset, &set); + if (retval == -1) { + exit(-1); + } + sleep(1); + printf("-----------------------------\n"); + retval = sigemptyset(&set); + if (retval == -1) { + exit(-1); + } + retval = sigemptyset(&oldset); + if (retval == -1) { + exit(-1); + } + retval = sigprocmask(SIG_SETMASK, &set, &oldset); + if (retval == -1) { + exit(-1); + } + retval = sigismember(&oldset, SIGTERM); + printf("SIGTERM is in oldset:%d\n", retval); + if (retval != 1) { + exit(-1); + } + retval = sigismember(&oldset, SIGUSR1); + printf("SIGUSR1 is in oldset:%d\n", retval); + if (retval != 1) { + exit(-1); + } + retval = sigismember(&oldset, SIGUSR2); + printf("SIGUSR2 is in oldset:%d\n", retval); + if (retval != 0) { + exit(-1); + } + + printf("-----------------newthread7 is finished------------\n"); + return nullptr; +} + +static UINT32 TestCase(VOID) +{ + int ret, retval; + void *res = nullptr; + pthread_t newPthread, newPthread1; + sigset_t set, oldset; + sighandler_t sigret; + sigret = signal(SIGUSR2, Sigprint111); + retval = sigemptyset(&set); + if (retval == -1) { + printf("error: sigemptyset \n"); + return -1; + } + retval = sigemptyset(&oldset); + if (retval == -1) { + printf("error: sigemptyset \n"); + return -1; + } + retval = sigaddset(&set, SIGTERM); + if (retval == -1) { + printf("error: sigemptyset \n"); + return -1; + } + retval = sigismember(&set, SIGTERM); + printf("SIGTERM is in set:%d\n", retval); + ICUNIT_ASSERT_EQUAL(retval, 1, retval); + retval = sigaddset(&set, SIGUSR1); + if (retval == -1) { + printf("error: sigemptyset \n"); + return -1; + } + retval = sigismember(&set, SIGUSR1); + printf("SIGUSR1 is in set:%d\n", retval); + ICUNIT_ASSERT_EQUAL(retval, 1, retval); + retval = sigismember(&set, SIGUSR2); + ICUNIT_ASSERT_EQUAL(retval, 0, retval); + printf("SIGUSR2 is in set:%d\n", retval); + retval = sigprocmask(SIG_SETMASK, &set, &oldset); + printf("line = %d\n", __LINE__); + if (retval == -1) { + printf("error: sigemptyset \n"); + return -1; + } + printf("line = %d\n", __LINE__); + raise(SIGUSR2); + printf("line = %d\n", __LINE__); + sleep(1); + ret = pthread_create(&newPthread1, nullptr, ThreadFunc7, nullptr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + printf("line = %d\n", __LINE__); + sleep(1); + raise(SIGUSR2); + retval = sigaddset(&set, SIGUSR2); + if (retval == -1) { + printf("error: sigemptyset \n"); + return -1; + } + printf("line = %d\n", __LINE__); + retval = sigdelset(&set, SIGUSR1); + if (retval == -1) { + printf("error: sigemptyset \n"); + return -1; + } + printf("line = %d\n", __LINE__); + retval = sigismember(&set, SIGTERM); + printf("f SIGTERM is in set:%d\n", retval); + ICUNIT_ASSERT_EQUAL(retval, 1, retval); + retval = sigismember(&set, SIGUSR1); + printf("f SIGUSR1 is in set:%d\n", retval); + ICUNIT_ASSERT_EQUAL(retval, 0, retval); + retval = sigismember(&set, SIGUSR2); + printf("f SIGUSR2 is in set:%d\n", retval); + ICUNIT_ASSERT_EQUAL(retval, 1, retval); + retval = sigprocmask(SIG_SETMASK, &set, nullptr); + if (retval == -1) { + printf("error: sigemptyset \n"); + return -1; + } + ret = pthread_join(newPthread1, &res); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + retval = sigprocmask(SIG_SETMASK, &oldset, &set); + if (retval == -1) { + printf("error: sigemptyset \n"); + return -1; + } + + printf("-----------------main is finished------------\n"); + + return 0; +} + +void ItPosixSignal041(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/it_test_signal.h b/src/kernel_liteos_a/testsuites/unittest/extended/signal/it_test_signal.h new file mode 100644 index 00000000..a6913d12 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/it_test_signal.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef IT_TEST_SIGNAL_H +#define IT_TEST_SIGNAL_H + +#include "osTest.h" +#include "sys/resource.h" +#include + +#define RED_FLAG 6 + +extern void ItPosixSignal001(void); +extern void ItPosixSignal002(void); +extern void ItPosixSignal003(void); +extern void ItPosixSignal004(void); +extern void ItPosixSignal005(void); +extern void ItPosixSignal006(void); +extern void ItPosixSignal007(void); +extern void ItPosixSignal008(void); +extern void ItPosixSignal009(void); +extern void ItPosixSignal010(void); +extern void ItPosixSignal011(void); +extern void ItPosixSignal012(void); +extern void ItPosixSignal013(void); +extern void ItPosixSignal014(void); +extern void ItPosixSignal015(void); +extern void ItPosixSignal016(void); +extern void ItPosixSignal017(void); +extern void ItPosixSignal018(void); +extern void ItPosixSignal019(void); +extern void ItPosixSignal020(void); +extern void ItPosixSignal021(void); +extern void ItPosixSignal022(void); +extern void ItPosixSignal023(void); +extern void ItPosixSignal024(void); +extern void ItPosixSignal025(void); + +extern void ItPosixSignal026(void); +extern void ItPosixSignal027(void); +extern void ItPosixSignal028(void); +extern void ItPosixSignal029(void); +extern void ItPosixSignal030(void); +extern void ItPosixSignal031(void); +extern void ItPosixSignal032(void); +extern void ItPosixSignal033(void); +extern void ItPosixSignal034(void); +extern void ItPosixSignal035(void); +extern void ItPosixSignal036(void); +extern void ItPosixSignal037(void); +extern void ItPosixSignal038(void); +extern void ItPosixSignal039(void); +extern void ItPosixSignal040(void); +extern void ItPosixSignal041(void); +extern void ItPosixSignal042(void); + +extern void ItPosixSigset001(void); +extern void ItPosixSigset002(void); +extern void ItPosixPipe001(void); +extern void ItPosixPipe002(void); +extern void ItPosixPipe003(void); +extern void ItPosixPipe004(void); +extern void ItPosixPipe005(void); +extern void ItPosixPipe006(void); +extern void ItPosixMkfifo001(void); +extern void ItPosixMkfifo002(void); +extern void ItIpcFdClr001(void); +extern void ItIpcFdIsset001(void); +extern void ItIpcFdSet001(void); +extern void ItIpcFdZero001(void); +extern void ItIpcMkfifo002(void); +extern void ItIpcMkfifo003(void); +extern void ItIpcPipe002(void); +extern void ItIpcPipe003(void); +extern void ItIpcPipe004(void); +extern void ItIpcPipe005(void); +extern void ItIpcSigaction001(void); +extern void ItIpcSigpause001(void); +extern void ItIpcSigpromask001(void); +extern int kill(pid_t pid, int sig); + +#endif diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/signal_test.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/signal_test.cpp new file mode 100644 index 00000000..ec4173e4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/signal_test.cpp @@ -0,0 +1,608 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include "it_test_signal.h" + +using namespace testing::ext; +namespace OHOS { +class SignalTest : public testing::Test { +public: + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} +}; + +#if defined(LOSCFG_USER_TEST_SMOKE) +/* * + * @tc.name: IT_POSIX_SIGNAL_002 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixSignal002, TestSize.Level0) +{ + ItPosixSignal002(); +} + +/* * + * @tc.name: IT_POSIX_SIGNAL_009 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixSignal009, TestSize.Level0) +{ + ItPosixSignal009(); +} + +/* * + * @tc.name: IT_POSIX_SIGNAL_013 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixSignal013, TestSize.Level0) +{ + ItPosixSignal013(); +} + +/* * + * @tc.name: IT_POSIX_SIGNAL_014 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixSignal014, TestSize.Level0) +{ + ItPosixSignal014(); +} + + +/* * + * @tc.name: IT_POSIX_SIGNAL_021 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixSignal021, TestSize.Level0) +{ + ItPosixSignal021(); +} + +/* * + * @tc.name: IT_POSIX_SIGNAL_022 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixSignal022, TestSize.Level0) +{ + ItPosixSignal022(); +} + +/* * + * @tc.name: IT_POSIX_SIGNAL_023 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixSignal023, TestSize.Level0) +{ + ItPosixSignal023(); +} + +/* * + * @tc.name: IT_POSIX_SIGNAL_024 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixSignal024, TestSize.Level0) +{ + ItPosixSignal024(); +} + +/* * + * @tc.name: IT_POSIX_SIGNAL_031 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixSignal031, TestSize.Level0) +{ + ItPosixSignal031(); +} + +/* * + * @tc.name: IT_POSIX_SIGNAL_032 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixSignal032, TestSize.Level0) +{ + ItPosixSignal032(); +} + +/* * + * @tc.name: IT_POSIX_SIGNAL_035 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixSignal035, TestSize.Level0) +{ + ItPosixSignal035(); +} + +/* * + * @tc.name: IT_POSIX_SIGNAL_036 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixSignal036, TestSize.Level0) +{ + ItPosixSignal036(); +} + +/* * + * @tc.name: IT_POSIX_SIGNAL_037 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixSignal037, TestSize.Level0) +{ + ItPosixSignal037(); +} + +/* * + * @tc.name: IT_POSIX_SIGNAL_039 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixSignal039, TestSize.Level0) +{ + ItPosixSignal039(); +} + +/* * + * @tc.name: IT_POSIX_SIGNAL_042 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixSignal042, TestSize.Level0) +{ + ItPosixSignal042(); +} + +/* * + * @tc.name: ItPosixPipe002 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixPipe002, TestSize.Level0) +{ + ItPosixPipe002(); +} + +/* * + * @tc.name: ItPosixMkfifo002 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixMkfifo002, TestSize.Level0) +{ + ItPosixMkfifo002(); +} + +/* * + * @tc.name: IT_IPC_FD_ISSET_001 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItIpcFdIsset001, TestSize.Level0) +{ + ItIpcFdIsset001(); +} +#endif + +#if defined(LOSCFG_USER_TEST_FULL) +/* * + * @tc.name: IT_IPC_FD_CLR_001 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItIpcFdClr001, TestSize.Level0) +{ + ItIpcFdClr001(); +} + +/* * + * @tc.name: IT_IPC_FD_SET_001 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItIpcFdSet001, TestSize.Level0) +{ + ItIpcFdSet001(); +} + +/* * + * @tc.name: IT_IPC_FD_ZERO_001 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItIpcFdZero001, TestSize.Level0) +{ + ItIpcFdZero001(); +} + +/* + * @tc.name: IT_IPC_SIGACTION_001^M + * @tc.desc: function for SignalTest^M + * @tc.type: FUNC^M + */ +HWTEST_F(SignalTest, ItIpcSigaction001, TestSize.Level0) +{ + ItIpcSigaction001(); +} + +/* * + * @tc.name: IT_IPC_SIGPAUSE_001 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItIpcSigpause001, TestSize.Level0) +{ + ItIpcSigpause001(); +} + +/* * + * @tc.name: IT_IPC_SIGPROMASK_001 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItIpcSigpromask001, TestSize.Level0) +{ + ItIpcSigpromask001(); +} + +/* * + * @tc.name: IT_POSIX_SIGNAL_001 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixSignal001, TestSize.Level0) +{ + ItPosixSignal001(); +} + +/* * + * @tc.name: IT_POSIX_SIGNAL_003 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixSignal003, TestSize.Level0) +{ + ItPosixSignal003(); +} + +/* * + * @tc.name: IT_POSIX_SIGNAL_004 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixSignal004, TestSize.Level0) +{ + ItPosixSignal004(); +} + +/* * + * @tc.name: IT_POSIX_SIGNAL_005 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixSignal005, TestSize.Level0) +{ + ItPosixSignal005(); +} + +/* * + * @tc.name: IT_POSIX_SIGNAL_006 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixSignal006, TestSize.Level0) +{ + ItPosixSignal006(); +} + +/* * + * @tc.name: IT_POSIX_SIGNAL_007 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixSignal007, TestSize.Level0) +{ + ItPosixSignal007(); +} + +/* * + * @tc.name: IT_POSIX_SIGNAL_008 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixSignal008, TestSize.Level0) +{ + ItPosixSignal008(); +} + +/* * + * @tc.name: IT_POSIX_SIGNAL_010 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixSignal010, TestSize.Level0) +{ + ItPosixSignal010(); +} + +/* * + * @tc.name: IT_POSIX_SIGNAL_011 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixSignal011, TestSize.Level0) +{ + ItPosixSignal011(); +} + +/* * + * @tc.name: IT_POSIX_SIGNAL_012 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixSignal012, TestSize.Level0) +{ + ItPosixSignal012(); +} + +/* * + * @tc.name: IT_POSIX_SIGNAL_015 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixSignal015, TestSize.Level0) +{ + ItPosixSignal015(); +} + +/* * + * @tc.name: IT_POSIX_SIGNAL_016 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixSignal016, TestSize.Level0) +{ + ItPosixSignal016(); +} + +/* * + * @tc.name: IT_POSIX_SIGNAL_017 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixSignal017, TestSize.Level0) +{ + ItPosixSignal017(); +} + +/* * + * @tc.name: IT_POSIX_SIGNAL_018 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixSignal018, TestSize.Level0) +{ + ItPosixSignal018(); +} + +/* * + * @tc.name: IT_POSIX_SIGNAL_019 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixSignal019, TestSize.Level0) +{ + ItPosixSignal019(); +} + +/* * + * @tc.name: IT_POSIX_SIGNAL_020 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixSignal020, TestSize.Level0) +{ + ItPosixSignal020(); +} + +/* * + * @tc.name: IT_POSIX_SIGNAL_025 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixSignal025, TestSize.Level0) +{ + ItPosixSignal025(); +} + +/* * + * @tc.name: IT_POSIX_SIGNAL_026 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixSignal026, TestSize.Level0) +{ + ItPosixSignal026(); +} + +/* * + * @tc.name: IT_POSIX_SIGNAL_028 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixSignal028, TestSize.Level0) +{ + ItPosixSignal028(); +} + +/* * + * @tc.name: IT_POSIX_SIGNAL_029 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixSignal029, TestSize.Level0) +{ + ItPosixSignal029(); +} + +/* * + * @tc.name: IT_POSIX_SIGNAL_030 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixSignal030, TestSize.Level0) +{ + ItPosixSignal030(); +} + +/* * + * @tc.name: IT_POSIX_SIGNAL_033 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixSignal033, TestSize.Level0) +{ + ItPosixSignal033(); +} + +/* * + * @tc.name: IT_POSIX_SIGNAL_038 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixSignal038, TestSize.Level0) +{ + ItPosixSignal038(); +} + +/* * + * @tc.name: IT_POSIX_SIGNAL_040 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixSignal040, TestSize.Level0) +{ + ItPosixSignal040(); +} + +/* * + * @tc.name: IT_POSIX_SIGNAL_041 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixSignal041, TestSize.Level0) +{ + ItPosixSignal041(); +} + +/* * + * @tc.name: IT_IPC_PIPE_002 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItIpcPipe002, TestSize.Level0) +{ + ItIpcPipe002(); +} + +/* * + * @tc.name: IT_IPC_PIPE_003 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItIpcPipe003, TestSize.Level0) +{ + ItIpcPipe003(); +} + +/* * + * @tc.name: ItPosixPipe001 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixPipe001, TestSize.Level0) +{ + ItPosixPipe001(); +} + +/* * + * @tc.name: ItPosixPipe003 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixPipe003, TestSize.Level0) +{ + ItPosixPipe003(); +} + +/* * + * @tc.name: ItPosixPipe004 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixPipe004, TestSize.Level0) +{ + ItPosixPipe004(); +} + +/* * + * @tc.name: ItPosixPipe005 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixPipe005, TestSize.Level0) +{ + ItPosixPipe005(); +} + +/* * + * @tc.name: ItPosixPipe006 + * @tc.desc: function for SignalTest + * @tc.type: FUNC + */ +HWTEST_F(SignalTest, ItPosixPipe006, TestSize.Level0) +{ + ItPosixPipe006(); +} + +#endif +} // namespace OHOS diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/It_ipc_fdisset_001.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/It_ipc_fdisset_001.cpp new file mode 100644 index 00000000..806f38d0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/It_ipc_fdisset_001.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" + + +static const int TAR_STR_LEN = 12; + +static UINT32 Testcase(VOID) +{ + int pipeFd[2], ret; // 2, pipe return 2 file descirpter + fd_set reads; + ret = pipe(pipeFd); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ret = write(pipeFd[1], "Hello World", TAR_STR_LEN); + printf("write first status: %d\n", ret); + ICUNIT_GOTO_EQUAL(ret, TAR_STR_LEN, ret, EXIT); + FD_ZERO(&reads); + FD_SET(pipeFd[0], &reads); + ret = select(pipeFd[0] + 1, &reads, NULL, NULL, NULL); + ICUNIT_GOTO_EQUAL(ret, 1, ret, EXIT); + ret = FD_ISSET(pipeFd[0], &reads); + ICUNIT_GOTO_NOT_EQUAL(ret, 0, ret, EXIT); + close(pipeFd[0]); + close(pipeFd[1]); + printf("-------------------FD_ISSET ok------------\n"); + return LOS_OK; +EXIT: + close(pipeFd[0]); + close(pipeFd[1]); + return LOS_NOK; +} + +VOID ItIpcFdIsset001(void) +{ + TEST_ADD_CASE(__FUNCTION__, Testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/It_ipc_mkfifo_002.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/It_ipc_mkfifo_002.cpp new file mode 100644 index 00000000..3e48ae2e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/It_ipc_mkfifo_002.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" + + +static const int NAME_BUF_SIZE = 50; +static const int TAR_STR_LEN = 12; + +static UINT32 Testcase(VOID) +{ + int tarFd, ret, spid; + char buffer[20]; // 20, target buffer size + char pathname[NAME_BUF_SIZE]; + char *filename = "/mkfifotest2"; + char *dir = "/dev"; + errno_t ret1 = strncpy_s(pathname, NAME_BUF_SIZE, dir, strlen(dir)); + ICUNIT_ASSERT_EQUAL(ret1, EOK, ret1); + + ret1 = strcat_s(pathname, NAME_BUF_SIZE, filename); + ICUNIT_ASSERT_EQUAL(ret1, EOK, ret1); + + ret = mkfifo(pathname, 0777); // 0777, file athurioty + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT1); + spid = fork(); + ICUNIT_GOTO_NOT_EQUAL(ret, -1, ret, EXIT1); + if (spid == 0) { + sleep(1); + tarFd = open(pathname, O_WRONLY, 0777); // 0777, file athurioty + if (tarFd == -1) { + exit(12); // 12, the value of son process unexpect exit, convenient to debug + } + printf("son tarfd = %d\n", tarFd); + ret = write(tarFd, "hello world", TAR_STR_LEN); + if (ret != TAR_STR_LEN) { + exit(11); // 11, the value of son process unexpect exit, convenient to debug + } + printf("write first status: %d\n", ret); + close(tarFd); + exit(RED_FLAG); + } + + tarFd = open(pathname, O_RDONLY, 0777); // 0777, file athurioty + printf("son tarfd = %d\n", tarFd); + ICUNIT_GOTO_NOT_EQUAL(tarFd, -1, tarFd, EXIT); + ret = read(tarFd, buffer, TAR_STR_LEN); + ICUNIT_GOTO_EQUAL(ret, TAR_STR_LEN, ret, EXIT); + ret = strcmp(buffer, "hello world"); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + printf("read fifo success: %s\n", buffer); + wait(&ret); + ICUNIT_GOTO_EQUAL(WEXITSTATUS(ret), RED_FLAG, WEXITSTATUS(ret), EXIT); + + close(tarFd); + remove(pathname); + printf("mkfifo ok\n"); + return LOS_OK; +EXIT: + close(tarFd); +EXIT1: + remove(pathname); + return LOS_NOK; +} + +VOID ItIpcMkfifo002(void) +{ + TEST_ADD_CASE(__FUNCTION__, Testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/It_ipc_mkfifo_003.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/It_ipc_mkfifo_003.cpp new file mode 100644 index 00000000..52a54958 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/It_ipc_mkfifo_003.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" + + +static const int NAME_BUF_SIZE = 50; +static const int TAR_STR_LEN = 12; + +static UINT32 Testcase(VOID) +{ + int tarFd, ret, spid; + char buffer[20]; // 20, target buffer size + char pathname[NAME_BUF_SIZE]; + char *filename = "/mkfifotest3"; + char *dir = "/dev"; + errno_t ret1 = strncpy_s(pathname, NAME_BUF_SIZE, dir, strlen(dir)); + ICUNIT_ASSERT_EQUAL(ret1, EOK, ret1); + + ret1 = strcat_s(pathname, NAME_BUF_SIZE, filename); + ICUNIT_ASSERT_EQUAL(ret1, EOK, ret1); + + ret = mkfifo(pathname, 0777); // 0777, file athurioty + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT1); + spid = fork(); + ICUNIT_GOTO_NOT_EQUAL(ret, -1, ret, EXIT1); + if (spid == 0) { + tarFd = open(pathname, O_WRONLY, 0777); // 0777, file athurioty + if (tarFd == -1) { + exit(12); // 12, the value of son process unexpect exit, convenient to debug + } + printf("son tarfd = %d\n", tarFd); + ret = write(tarFd, "hello world", TAR_STR_LEN); + if (ret != TAR_STR_LEN) { + exit(11); // 11, the value of son process unexpect exit, convenient to debug + } + printf("write first status: %d\n", ret); + close(tarFd); + exit(RED_FLAG); + } + + tarFd = open(pathname, O_RDONLY, 0777); // 0777, file athurioty + printf("son tarfd = %d\n", tarFd); + ICUNIT_GOTO_NOT_EQUAL(tarFd, -1, tarFd, EXIT); + sleep(1); + ret = read(tarFd, buffer, TAR_STR_LEN); + ICUNIT_GOTO_EQUAL(ret, TAR_STR_LEN, ret, EXIT); + ret = strcmp(buffer, "hello world"); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + printf("read fifo success: %s\n", buffer); + wait(&ret); + ICUNIT_GOTO_EQUAL(WEXITSTATUS(ret), RED_FLAG, WEXITSTATUS(ret), EXIT); + + close(tarFd); + remove(pathname); + printf("mkfifo ok\n"); + return LOS_OK; +EXIT: + close(tarFd); +EXIT1: + remove(pathname); + return LOS_NOK; +} + +VOID ItIpcMkfifo003(void) +{ + TEST_ADD_CASE(__FUNCTION__, Testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/It_ipc_pipe_004.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/It_ipc_pipe_004.cpp new file mode 100644 index 00000000..32305026 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/It_ipc_pipe_004.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2021-2021, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "it_test_signal.h" + +#define TAR_STR_LEN 12 + +static UINT32 TestCase(VOID) +{ + int pipefd[2]; // 2, array subscript + int retValue = pipe2(pipefd, O_CLOEXEC); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + + int *readFd = &pipefd[0]; + int *writeFd = &pipefd[1]; + char readbuffer[100]; + int status, ret; + + pid_t pid = fork(); + if (pid == -1) { + printf("Fork Error!\n"); + return -1; + } else if (pid == 0) { + for (int i = 0; i < 3; i++) { // 3, Number of cycles + errno = 0; + char sentence1[15] = "Hello World"; + char a[4] = {0}; + retValue = sprintf_s(a, sizeof(a), "%d", i); + ICUNIT_ASSERT_NOT_EQUAL(retValue, 0, retValue); + retValue = strcat_s(sentence1, sizeof(sentence1), a); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + ret = write(*writeFd, sentence1, strlen(sentence1) + 1); + ICUNIT_ASSERT_EQUAL(ret, 13, ret); // 13, assert that function Result is equal to this. + usleep(100000); // 100000, Used to calculate the delay time. + + retValue = memset_s(readbuffer, sizeof(readbuffer), 0, sizeof(readbuffer)); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + retValue = read(*readFd, readbuffer, sizeof(readbuffer)); + ICUNIT_ASSERT_EQUAL(retValue, 13, retValue); // 13, assert that function Result is equal to this. + ret = strncmp((readbuffer), (sentence1), (strlen(sentence1))); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + usleep(100000); // 100000, Used to calculate the delay time. + } + exit(0); + } + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ICUNIT_ASSERT_EQUAL(WEXITSTATUS(status), 0, WEXITSTATUS(status)); + ret = unlink("/dev/pipe0"); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + ret = close(pipefd[0]); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = unlink("/dev/pipe0"); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + ret = close(pipefd[1]); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = unlink("/dev/pipe0"); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return 0; +} + +void ItIpcPipe004(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/It_ipc_pipe_005.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/It_ipc_pipe_005.cpp new file mode 100644 index 00000000..03e9e655 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/It_ipc_pipe_005.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2021-2021, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "it_test_signal.h" + +static UINT32 TestCase(VOID) +{ + int pipefd[2]; // 2, array subscript + errno = 0; + int ret = pipe2(pipefd, -1); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno); + pipefd[0] = 2; // 2, set pipe fd + pipefd[1] = 3; // 3, set pipe fd + + errno = 0; + ret = pipe2((int *)-1, O_CLOEXEC); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, EFAULT, errno); + return 0; +} + +void ItIpcPipe005(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} + diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/mkfifo_test_001.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/mkfifo_test_001.cpp new file mode 100644 index 00000000..017bb106 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/mkfifo_test_001.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include +#include +#include +#include +#include +#include + +static int TestMkfifo() +{ + char buffer[80]; + int fd; + int retValue; + pid_t pid; + + unlink("/dev/fifo"); + + retValue = mkfifo("/dev/fifo", 0777); // 0777, mkfifo config. + printf("mkfifo begin,retValue=%d\n", retValue); + + char sentence[] = "Hello World"; + + pid = fork(); + if (pid < 0) { + printf("Fork error\n"); + return -1; + } else if (pid == 0) { + fd = open("/dev/fifo", O_WRONLY); + if (fd < 0) { + return -1; + } + write(fd, sentence, sizeof(sentence)); + close(fd); + exit(0); + } else { + fd = open("/dev/fifo", O_RDONLY); + if (fd < 0) { + return -1; + } + read(fd, buffer, sizeof(buffer)); + printf("Receive data: %s\n", buffer); + close(fd); + } + return 0; +} + + +void ItPosixMkfifo001(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestMkfifo, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/mkfifo_test_002.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/mkfifo_test_002.cpp new file mode 100644 index 00000000..495a7330 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/mkfifo_test_002.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include +#include +#include +#include +#include +#include + +static const int NAME_BUF_SIZE = 500; +static const int FAULT1 = 6; +static const int FAULT2 = 7; + +static int TestMkfifoReturn() +{ + int retValue, i; + int status = 0; + pid_t pid; + + retValue = mkfifo("/dev/fifo0", 0777); // 0777, mkfifo config. + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + retValue = mkfifo("/dev/fifo0", 0777); // 0777, mkfifo config. + ICUNIT_GOTO_EQUAL(retValue, -1, retValue, EXIT); + ICUNIT_GOTO_EQUAL(errno, EEXIST, errno, EXIT); + + unlink("/usr/fifo0"); + unlink("/dev/fifo0/fifo1"); + unlink("/dev/usr/fifo0"); + rmdir("/dev/usr"); + unlink("/dev/fifo0"); + return LOS_OK; + +EXIT: + unlink("/usr/fifo0"); + unlink("/dev/fifo0/fifo1"); + unlink("/dev/usr/fifo0"); + rmdir("/dev/usr"); + unlink("/dev/fifo0"); + return LOS_NOK; +} + +void ItPosixMkfifo002(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestMkfifoReturn, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/pipe_test_002.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/pipe_test_002.cpp new file mode 100644 index 00000000..4a705182 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/pipe_test_002.cpp @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" +#include "fcntl.h" +#include "sys/shm.h" + +static int TestPipeMultiProcess() +{ + int pipefd[2]; // 2, array subscript + pid_t pid; + int retValue = -1; + retValue = pipe(pipefd); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + + int *readFd = &pipefd[0]; + int *writeFd = &pipefd[1]; + char readbuffer[100] = {0}; + int status, ret; + int totalNum = 3; + int *sharedflag = NULL; + int shmid; + + int flag = fcntl(*readFd, F_GETFL); + fcntl(*readFd, F_SETFL, flag | O_NONBLOCK); + shmid = shmget(static_cast(IPC_PRIVATE), sizeof(int), 0666 | IPC_CREAT); // 0666 the authority of the shm + ICUNIT_ASSERT_NOT_EQUAL(shmid, -1, shmid); + sharedflag = (int *)shmat(shmid, NULL, 0); + *sharedflag = 0; + + pid = fork(); + if (pid == -1) { + printf("Fork Error!\n"); + return -1; + } else if (pid == 0) { + sharedflag = (int *)shmat(shmid, NULL, 0); + close(pipefd[0]); + for (int i = 0; i < totalNum; i++) { + errno = 0; + char sentence1[15] = "Hello World"; + char a[2] = {0}; + (void)sprintf_s(a, sizeof(a), "%d", i); + (void)strcat_s(sentence1, 15, a); // 15, sizeof sentence1 + int ret = write(*writeFd, sentence1, strlen(sentence1) + 1); + ICUNIT_ASSERT_EQUAL(ret, strlen(sentence1) + 1, ret); + usleep(10000); // 10000, Used to calculate the delay time. + } + *sharedflag = 1; + ret = close(pipefd[1]); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + exit(0); + } else { + close(pipefd[1]); + // waitting for the sub process has written the sentence first + while (*sharedflag != 1) { + usleep(1); + } + for (int i = 0; i < totalNum; i++) { + printf("read\n"); + char sentence1[15] = "Hello World"; + char a[2] = {0}; + (void)sprintf_s(a, sizeof(a), "%d", i); + (void)strcat_s(sentence1, 15, a); // 15, sizeof sentence1 + (void)memset_s(readbuffer, sizeof(readbuffer), 0, sizeof(readbuffer)); + retValue = read(*readFd, readbuffer, strlen(sentence1) + 1); + printf("Receive %d bytes data : %s, errno : %d\n", retValue, readbuffer, errno); + ICUNIT_ASSERT_SIZE_STRING_EQUAL(readbuffer, sentence1, strlen(sentence1), errno); + } + } + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ret = close(pipefd[0]); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return 0; +} + + +void ItPosixPipe002(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestPipeMultiProcess, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/pipe_test_004.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/pipe_test_004.cpp new file mode 100644 index 00000000..87e8243f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/pipe_test_004.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" +#include "fcntl.h" + +#define FAULT1 11 +#define FAULT2 22 +int TestPipeReturn() +{ + int pipefd[2]; // 2, array subscript + int retValue, i, status; + retValue = pipe(NULL); + ICUNIT_ASSERT_EQUAL(retValue, -1, retValue); + ICUNIT_ASSERT_EQUAL(errno, EFAULT, errno); + printf("***************1\n"); + + return LOS_OK; +} + +void ItPosixPipe004(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestPipeReturn, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_002.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_002.cpp new file mode 100644 index 00000000..540b02a6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_002.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" +#include "sys/wait.h" + +static int g_sigCount = 0; +static void SigPrint(int sig) +{ + (void)sig; + g_sigCount++; +} + +static int TestRaiseIgnore(void) +{ + int sig = SIGPWR; + void *ret; + int retValue; + + g_sigCount = 0; + // trigger one + ret = reinterpret_cast(signal(sig, SigPrint)); + ICUNIT_ASSERT_NOT_EQUAL(ret, NULL, ret); + + retValue = raise(sig); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + + usleep(1000); // 1000, Used to calculate the delay time. + // trigger ignore + ret = reinterpret_cast(signal(sig, SIG_IGN)); + ICUNIT_ASSERT_NOT_EQUAL(ret, NULL, ret); + + retValue = raise(sig); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + // trigger one + ret = reinterpret_cast(signal(sig, SigPrint)); + ICUNIT_ASSERT_NOT_EQUAL(ret, NULL, ret); + retValue = raise(sig); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + return g_sigCount; +} + +static int TestCase(void) +{ + int count; + + count = TestRaiseIgnore(); + // the signal should be triggered twice + ICUNIT_ASSERT_EQUAL(count, 2, count); // 2, assert that function Result is equal to this. + return 0; +} + +void ItPosixSignal002(void) +{ + TEST_ADD_CASE("IT_POSIX_SIGNAL_002", TestCase, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_009.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_009.cpp new file mode 100644 index 00000000..dc36dde7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_009.cpp @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" + +static int g_sigCount = 0; +static void SigPrint(int sig) +{ + (void)sig; + g_sigCount++; +} + +static void SigPrint1(int sig) +{ + (void)sig; + g_sigCount += 100; // 100, Used to calculate the progress of the program. +} + +static int TestSigSet(void) +{ + sigset_t set = { 0 }; + sigset_t set1 = { 0 }; + sigset_t left = { 0 }; + sigset_t right = { 0 }; + + void (*ret)(int); + int retValue; + + left.__bits[0] = 0x1; + right.__bits[0] = 0x2; + + retValue = sigandset(&set, &left, &right); + ICUNIT_ASSERT_EQUAL(set.__bits[0], 0, set.__bits[0]); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + + left.__bits[0] = 0x11; + right.__bits[0] = 0x1; + + retValue = sigandset(&set, &left, &right); + ICUNIT_ASSERT_EQUAL(set.__bits[0], 1, set.__bits[0]); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + + left.__bits[0] = 0x11; + right.__bits[0] = 0x11; + + retValue = sigandset(&set, &left, &right); + ICUNIT_ASSERT_EQUAL(set.__bits[0], 0x11, set.__bits[0]); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + + retValue = sigorset(&set, &left, &right); + ICUNIT_ASSERT_EQUAL(set.__bits[0], 0x11, set.__bits[0]); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + + retValue = sigdelset(&set, 1); + ICUNIT_ASSERT_EQUAL(set.__bits[0], 0x10, set.__bits[0]); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + + int sigs; + sigset(1, SigPrint1); + + retValue = raise(1); + ICUNIT_ASSERT_EQUAL(g_sigCount, 100, g_sigCount); // 100, assert that function Result is equal to this. + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + + retValue = sigfillset(&set); + ICUNIT_ASSERT_EQUAL(set.__bits[0], 0x7fffffff, set.__bits[0]); + ICUNIT_ASSERT_EQUAL(set.__bits[1], 0xfffffffc, set.__bits[1]); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + + retValue = sigaddset(&set1, 1); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + + ret = signal(1, SigPrint); + ICUNIT_ASSERT_NOT_EQUAL(ret, NULL, ret); + retValue = sighold(1); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + + retValue = raise(1); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + retValue = sigrelse(1); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + + retValue = raise(1); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + ICUNIT_ASSERT_EQUAL(g_sigCount, 102, g_sigCount); // 102, assert that function Result is equal to this. + + retValue = sigisemptyset(&set1); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + + retValue = siginterrupt(1, 0); + ICUNIT_ASSERT_EQUAL(retValue, 0, retValue); + return 0; +} + + +void ItPosixSignal009(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestSigSet, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_013.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_013.cpp new file mode 100644 index 00000000..040fcfff --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_013.cpp @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" + +static void SigPrint(int sig) +{ + (void)sig; + printf("%s%d\n", __FUNCTION__, __LINE__); + return; +} + +static void SigPrint1(int sig) +{ + (void)sig; + printf("%s%d\n", __FUNCTION__, __LINE__); + return; +} + +static int g_sigCount = 0; +static void SigPrint2(int sig) +{ + (void)sig; + g_sigCount = 1; + printf("%s, count = %d\n", __FUNCTION__, g_sigCount); + return; +} + +static void *ThreadSetFunc2(void *arg) +{ + (void)arg; + void (*retSig)(int); + retSig = signal(SIGALRM, SigPrint2); + ICUNIT_GOTO_NOT_EQUAL(retSig, SIG_ERR, retSig, EXIT); + pthread_exit((void *)NULL); + return NULL; +EXIT: + pthread_exit(reinterpret_cast(-1)); + return reinterpret_cast(-1); +} + +static void *ThreadSetDfl(void *arg) +{ + (void)arg; + void (*retSig)(int); + retSig = signal(SIGALRM, SIG_DFL); + ICUNIT_GOTO_NOT_EQUAL(retSig, SIG_ERR, retSig, EXIT); + pthread_exit((void *)NULL); + return NULL; +EXIT: + pthread_exit(reinterpret_cast(-1)); + return reinterpret_cast(-1); +} + +static void *ThreadKill(void *arg) +{ + (void)arg; + int retValue; + + retValue = raise(SIGALRM); + ICUNIT_GOTO_EQUAL(retValue, 0, retValue, EXIT); + pthread_exit((void *)NULL); + return NULL; +EXIT: + pthread_exit(reinterpret_cast(-1)); + return reinterpret_cast(-1); +} + +static int TestSigMultiPthread(void) +{ + int fpid; + int status; + int *status1 = nullptr; + int ret; + int count; + pthread_t thread, thread1, thread2; + + fpid = fork(); + ICUNIT_ASSERT_WITHIN_EQUAL(fpid, 0, UINT_MAX, fpid); + if (fpid == 0) { + ret = pthread_create(&thread1, NULL, ThreadSetDfl, 0); + if (ret != 0) { + exit(ret); + } + ret = pthread_create(&thread2, NULL, ThreadSetFunc2, 0); + if (ret != 0) { + exit(ret); + } + ret = pthread_create(&thread, NULL, ThreadKill, 0); + if (ret != 0) { + exit(ret); + } + + pthread_join(thread, reinterpret_cast(&status1)); + if ((int)(intptr_t)status1 != 0) { + exit(-1); + } + pthread_join(thread1, reinterpret_cast(&status1)); + if ((int)(intptr_t)status1 != 0) { + exit(-1); + } + pthread_join(thread2, reinterpret_cast(&status1)); + if ((int)(intptr_t)status1 != 0) { + exit(-1); + } + if (g_sigCount != 1) { + exit(g_sigCount); + } + exit(0); + } + + ret = waitpid(fpid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, fpid, ret); + ICUNIT_ASSERT_EQUAL(WEXITSTATUS(status), 0, WEXITSTATUS(status)); + return 0; +} + +void ItPosixSignal013(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestSigMultiPthread, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_014.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_014.cpp new file mode 100644 index 00000000..36180e20 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_014.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" + +static void SigPrint(int sig) +{ + printf("%s,%d\n", __FUNCTION__, __LINE__); +} + +static int TestSigErrno() +{ + void (*ret)(int); + ret = signal(100, SigPrint); // 100, signal num. + ICUNIT_ASSERT_EQUAL((int)ret, -1, (int)ret); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno); + + ret = signal(0, SigPrint); + ICUNIT_ASSERT_EQUAL((int)ret, -1, (int)ret); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno); + + errno = 0; + ret = signal(30, SigPrint); // 30, signal num. + ICUNIT_ASSERT_EQUAL(errno, 0, errno); + + ret = signal(-1, SigPrint); + ICUNIT_ASSERT_EQUAL((int)ret, -1, (int)ret); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno); + + ret = signal(32, SigPrint); // 32, signal num. + ICUNIT_ASSERT_EQUAL((int)ret, -1, (int)ret); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno); + + ret = signal(31, SigPrint); // 31, signal num. + ICUNIT_ASSERT_EQUAL((int)ret, -1, (int)ret); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno); + + return 0; +} + +void ItPosixSignal014(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestSigErrno, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_021.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_021.cpp new file mode 100644 index 00000000..753975ef --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_021.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "stdio.h" +#include "unistd.h" +#include "signal.h" + +static void SigPrint(int signum) +{ + (void)signum; + printf("Catch signal %d\n", signum); +} + +static void SigQuit(int signum) +{ + (void)signum; + printf("QUIT\n"); +} + +static int TestSignal(void) +{ + int sigI = SIGINT; + int sigQ = SIGQUIT; + void (*ret)(int); + int retValue, status; + + int fpid = fork(); + if (fpid == 0) { + ret = signal(sigI, SigPrint); + if (ret == nullptr) { + exit((int)ret); + } + printf("SIGINT to trigger the signal\n"); + printf("SIGQUIT to quit\n\n"); + + retValue = raise(sigI); + if (retValue != 0) { + exit(retValue); + } + + ret = signal(sigQ, SigQuit); + if (ret == nullptr) { + exit((int)ret); + } + + retValue = raise(sigQ); + if (retValue != 0) { + exit(retValue); + } + exit(0); + } + + retValue = waitpid(fpid, &status, 0); + ICUNIT_ASSERT_EQUAL(retValue, fpid, retValue); + ICUNIT_ASSERT_EQUAL(WEXITSTATUS(status), 0, WEXITSTATUS(status)); + + return 0; +} + +void ItPosixSignal021(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestSignal, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_022.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_022.cpp new file mode 100644 index 00000000..f3ed53b5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_022.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" + +static void SigPrint(int) +{ + printf("Receive signal. Raise successes\n\n"); +} + +static int TestRaise() +{ + int sig = SIGINT; + void (*ret)(int) = nullptr; + int retValue, status; + + int fpid = fork(); + if (fpid == 0) { + printf("Set signal\n"); + ret = signal(sig, SigPrint); + if (ret == nullptr) { + exit((int)ret); + } + retValue = raise(sig); + if (retValue != 0) { + exit(retValue); + } + + usleep(1000); // 1000, Used to calculate the delay time. + printf("Set ignore\n"); + ret = signal(sig, SIG_IGN); + if (ret == NULL) { + exit((int)ret); + } + retValue = raise(sig); + if (retValue != 0) { + exit(retValue); + } + + printf("\nReset signal\n"); + ret = signal(sig, SigPrint); + if (ret == NULL) { + exit((int)ret); + } + retValue = raise(sig); + if (retValue != 0) { + exit(retValue); + } + exit(0); + } + + retValue = waitpid(fpid, &status, 0); + ICUNIT_ASSERT_EQUAL(retValue, fpid, retValue); + ICUNIT_ASSERT_EQUAL(WEXITSTATUS(status), 0, WEXITSTATUS(status)); + + return 0; +} + +void ItPosixSignal022(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestRaise, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_023.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_023.cpp new file mode 100644 index 00000000..9b96715b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_023.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" + +static void SigPrint(int signum) +{ + printf("Receive signal. Kill succeeds\n\n"); +} + +static int TestKill() +{ + int sig = SIGALRM; + + void (*retSig)(int); + int retValue, status; + + printf("new code \n"); + + int fpid = fork(); + if (fpid == 0) { + printf("Set Signal\n\n"); + retSig = signal(sig, SigPrint); + if (retSig == NULL) { + printf("retSig = null\n"); + exit((int)retSig); + } + + printf("Test Kill\n"); + usleep(1000); // 1000, Used to calculate the delay time. + retValue = kill(getpid(), sig); + if (retValue != 0) { + printf("value != 0 \n"); + exit(retValue); + } + exit(0); + } + + retValue = waitpid(fpid, &status, 0); + ICUNIT_ASSERT_EQUAL(retValue, fpid, retValue); + ICUNIT_ASSERT_EQUAL(WEXITSTATUS(status), 0, WEXITSTATUS(status)); + + return 0; +} + +void ItPosixSignal023(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestKill, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_024.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_024.cpp new file mode 100644 index 00000000..e4a67455 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_024.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" + +static void OldAction(int signum) +{ + (void)signum; + printf("Here is the old action\n"); +} + +static void NewAction(int signum) +{ + (void)signum; + printf("Here is the new action\n"); +} + +static int TestSigaction(void) +{ + int retValue, status; + int fpid = fork(); + if (fpid == 0) { + struct sigaction curAction, oldAction; + curAction.sa_handler = OldAction; + retValue = sigemptyset(&curAction.sa_mask); + if (retValue != 0) { + exit(retValue); + } + curAction.sa_flags = 0; + + printf("Execute Signal\n"); + retValue = sigaction(SIGINT, &curAction, NULL); + if (retValue != 0) { + exit(retValue); + } + retValue = raise(SIGINT); + if (retValue != 0) { + exit(retValue); + } + printf("\n\n"); + + printf("Test backup\n"); + retValue = sigaction(SIGINT, &curAction, &oldAction); + if (retValue != 0) { + exit(retValue); + } + curAction.sa_handler = NewAction; + retValue = sigaction(SIGINT, &curAction, NULL); + if (retValue != 0) { + exit(retValue); + } + retValue = sigaction(SIGALRM, &oldAction, NULL); + if (retValue != 0) { + exit(retValue); + } + retValue = raise(SIGINT); + if (retValue != 0) { + exit(retValue); + } + retValue = raise(SIGALRM); + if (retValue != 0) { + exit(retValue); + } + printf("\n\n"); + + exit(0); + } + + retValue = waitpid(fpid, &status, 0); + ICUNIT_ASSERT_EQUAL(retValue, fpid, retValue); + ICUNIT_ASSERT_EQUAL(WEXITSTATUS(status), 0, WEXITSTATUS(status)); + + return 0; +} + +void ItPosixSignal024(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestSigaction, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_031.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_031.cpp new file mode 100644 index 00000000..849e9b0f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_031.cpp @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" + +static const int INVALID_SIG = 1000; + +static UINT32 TestCase(VOID) +{ + int ret = 0; + sigset_t set; + + int status; + int fpid = fork(); + if (fpid == 0) { + sigemptyset(&set); + ret = sigaddset(&set, INVALID_SIG); + if (ret != -1) { + exit(ret); + } + if (errno != EINVAL) { + exit(errno); + } + printf("----------------------------------\n"); + + ret = sigdelset(&set, INVALID_SIG); + if (ret != -1) { + exit(ret); + } + if (errno != EINVAL) { + exit(errno); + } + printf("----------------------------------\n"); + + ret = sigignore(INVALID_SIG); + if (ret != -1) { + exit(ret); + } + if (errno != EINVAL) { + exit(errno); + } + printf("----------------------------------\n"); + + ret = sigignore(SIGKILL); + if (ret != -1) { + exit(ret); + } + if (errno != EINVAL) { + exit(errno); + } + printf("----------------------------------\n"); + + ret = sigrelse(INVALID_SIG); + if (ret != -1) { + exit(ret); + } + if (errno != EINVAL) { + exit(errno); + } + printf("----------------------------------\n"); + + ret = sighold(INVALID_SIG); + if (ret != -1) { + exit(ret); + } + if (errno != EINVAL) { + exit(errno); + } + printf("----------------------------------\n"); + + exit(0); + } + + ret = waitpid(fpid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, fpid, ret); + ICUNIT_ASSERT_EQUAL(WEXITSTATUS(status), 0, WEXITSTATUS(status)); + + return LOS_OK; +} + +void ItPosixSignal031(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_032.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_032.cpp new file mode 100644 index 00000000..9c0416a8 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_032.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" + +static int g_sigCount = 0; +static void SigPrint(int sig) +{ + (void)sig; + g_sigCount++; + printf("signal receive success\n"); +} + +static UINT32 TestCase(VOID) +{ + int pid = 0; + int ret = 0; + void (*retptr)(int) = NULL; + sigset_t newset, oldset; + pid = fork(); + if (pid < 0) { + printf("Fork error\n"); + return LOS_NOK; + } else if (pid == 0) { + printf("test032 raise before\n"); + sigemptyset(&newset); + sigaddset(&newset, SIGUSR1); + ret = sigprocmask(SIG_BLOCK, &newset, &oldset); + if (ret != 0) { + printf("error:sigprocmask\n"); + exit(LOS_NOK); + } + retptr = signal(SIGUSR1, SigPrint); + if (retptr == SIG_ERR) { + printf("error:signal\n"); + exit(LOS_NOK); + } + raise(SIGUSR1); + printf("test032 raise after\n"); + exit(g_sigCount); + } + + wait(&ret); + ICUNIT_ASSERT_EQUAL(WEXITSTATUS(ret), 0, WEXITSTATUS(ret)); + return LOS_OK; +} + +void ItPosixSignal032(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_035.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_035.cpp new file mode 100644 index 00000000..f07e329b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_035.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" + +static int g_sigCount = 0; +static void SigPrint(int sig) +{ + (void)sig; + g_sigCount++; +} + +static int TestCase() +{ + int sig = 100; + int count = 0; + int retValue, status; + void (*ret)(int); + + printf("new 2\n"); + + int fpid = fork(); + if (fpid == 0) { + ret = signal(sig, SigPrint); + if (ret != SIG_ERR) { + exit((int)ret); + } + if (errno != EINVAL) { + exit(errno); + } + + sig = SIGTERM; + ret = signal(sig, SigPrint); + ret = signal(sig, SIG_DFL); + if (ret != SigPrint) { + exit((int)ret); + } + exit(0); + } + + retValue = waitpid(fpid, &status, 0); + ICUNIT_ASSERT_EQUAL(retValue, fpid, retValue); + ICUNIT_ASSERT_EQUAL(WEXITSTATUS(status), 0, WEXITSTATUS(status)); + + return LOS_OK; +} + +void ItPosixSignal035(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_036.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_036.cpp new file mode 100644 index 00000000..35aaed0b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_036.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" + +static int g_sigCount = 0; +static void SigPrint(int sig) +{ + g_sigCount++; +} + +static int TestCase() +{ + int sig = SIGKILL; + int ret, status; + + int fpid = fork(); + if (fpid == 0) { + struct sigaction sigAct, oldAct; + sigAct.sa_handler = SigPrint; + sigemptyset(&sigAct.sa_mask); + sigAct.sa_flags = 0; + + ret = sigaction(sig, &sigAct, &oldAct); + printf("ret = %d\n", ret); + if (ret != -1) { + exit(ret); + } + if (errno != EINVAL) { + exit(errno); + } + exit(0); + } + + ret = waitpid(fpid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, fpid, ret); + ICUNIT_ASSERT_EQUAL(WEXITSTATUS(status), 0, WEXITSTATUS(status)); + + return LOS_OK; +} + +void ItPosixSignal036(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_037.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_037.cpp new file mode 100644 index 00000000..75f8c4bd --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_037.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" + +static UINT32 TestCase(VOID) +{ + int retval, status; + sigset_t set, oldset; + + int fpid = fork(); + if (fpid == 0) { + retval = sigemptyset(&set); + ICUNIT_ASSERT_NOT_EQUAL(retval, -1, retval); + retval = sigemptyset(&oldset); + ICUNIT_ASSERT_NOT_EQUAL(retval, -1, retval); + retval = sigaddset(&set, SIGTERM); + ICUNIT_ASSERT_NOT_EQUAL(retval, -1, retval); + printf("----------------------------------\n"); + retval = sigprocmask(666, &set, &oldset); // 666, invalid param + ICUNIT_ASSERT_EQUAL(retval, -1, retval); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno); + printf("----------------------------------\n"); + retval = sigprocmask(SIG_BLOCK, reinterpret_cast(1), &oldset); + ICUNIT_ASSERT_EQUAL(retval, -1, retval); + ICUNIT_ASSERT_EQUAL(errno, EFAULT, errno); + printf("----------------------------------\n"); + retval = sigprocmask(SIG_BLOCK, &set, &oldset); + ICUNIT_ASSERT_EQUAL(retval, 0, retval); + + exit(0); + } + + retval = waitpid(fpid, &status, 0); + ICUNIT_ASSERT_EQUAL(retval, fpid, retval); + ICUNIT_ASSERT_EQUAL(WEXITSTATUS(status), 0, WEXITSTATUS(status)); + + return LOS_OK; +} + +void ItPosixSignal037(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_039.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_039.cpp new file mode 100644 index 00000000..fa35c14c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_039.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" +#include "time.h" +static const int INVALID_WHICH = 666; +#define IS32BIT(x) !((x) + 0x80000000ULL >> 32) + +static UINT32 TestCase(VOID) +{ + int ret, status; + struct itimerval newValue = { 0 }; + struct itimerval oldValue = { 0 }; + struct itimerval test; + + int fpid = fork(); + if (fpid == 0) { + bool flag = IS32BIT(test.it_interval.tv_sec); + ret = setitimer(INVALID_WHICH, &newValue, &oldValue); + printf("ret=%x--flag=%d-----\n", ret, flag); + if (ret != -1) { + exit(ret); + } + if (errno != EINVAL) { + exit(errno); + } + printf("---------------\n"); + + exit(0); + } + + ret = waitpid(fpid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, fpid, ret); + ICUNIT_ASSERT_EQUAL(WEXITSTATUS(status), 0, WEXITSTATUS(status)); + return LOS_OK; +} + +void ItPosixSignal039(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_042.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_042.cpp new file mode 100644 index 00000000..b8d7c21a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/signal_test_042.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_signal.h" +#include "signal.h" + +#include "pthread.h" + +static int SigtimedwaitFailTest(const sigset_t *set, siginfo_t *info, const struct timespec *timeout, + unsigned int expectErrno) +{ + int ret; + errno = 0; + if (expectErrno == 0) { + ret = sigtimedwait(set, info, timeout); + if (ret != 0) { + printf("err: line %d, errno %d\n", __LINE__, errno); + return errno; + } + return 0; + } + ret = sigtimedwait(set, info, timeout); + if (ret == 0) { + printf("err: line %d\n", __LINE__); + return -1; + } + if (errno != expectErrno) { + printf("err: line %d\n", __LINE__); + return errno; + } + return 0; +} + +static UINT32 TestCase() +{ + int ret; + struct timespec time1 = { 0, 50 }; + sigset_t set; + + sigemptyset(&set); + sigprocmask(SIG_SETMASK, &set, NULL); + + printf("check invalid sigset ...\n"); + int rt = sigaddset(&set, 0); + ICUNIT_ASSERT_EQUAL(rt, -1, rt); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno); + rt = sigaddset(&set, 100); // 100, set signal num + ICUNIT_ASSERT_EQUAL(rt, -1, rt); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno); + rt = sigaddset(&set, SIGALRM); + ICUNIT_ASSERT_EQUAL(rt, 0, rt); + + siginfo_t si; + time1.tv_sec = -1; + printf("check invalid timespec: tv_sec=-1 ...\n"); + ret = SigtimedwaitFailTest(&set, &si, &time1, EINVAL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + time1.tv_sec = 1; + time1.tv_nsec = -1; + printf("check invalid timespec: tv_nsec=-1 ...\n"); + ret = SigtimedwaitFailTest(&set, &si, &time1, EINVAL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + time1.tv_sec = 1; + time1.tv_nsec = 1000 * 1000 * 1000 + 1; // 1000, set the nsec of time. + printf("check invalid timespec: tv_nsec overflow ...\n"); + ret = SigtimedwaitFailTest(&set, &si, &time1, EINVAL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return 0; +} + +void ItPosixSignal042(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/sigset_test_001.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/sigset_test_001.cpp new file mode 100644 index 00000000..257e552f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/sigset_test_001.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "it_test_signal.h" +#include "signal.h" +#include "pthread.h" +#include "errno.h" +static int g_signum; + +static void SigUsr(int sigNum) +{ + g_signum = sigNum; + ICUNIT_ASSERT_EQUAL_VOID(g_signum, SIGUSR2, g_signum); +} + +static void *PthreadSigsetSigHold(void *arg) +{ + void (*ret)(int); + ret = sigset(SIGUSR1, SIG_HOLD); + ICUNIT_ASSERT_NOT_EQUAL_NULL(ret, NULL, ret); + ICUNIT_ASSERT_EQUAL_NULL(errno, EINVAL, errno); + return nullptr; +} + +static void *PthreadSigsetSigUsr(void *arg) +{ + void (*ret)(int); + ret = sigset(SIGUSR2, SigUsr); + ICUNIT_ASSERT_NOT_EQUAL_NULL(ret, NULL, ret); + return nullptr; +} + +static UINT32 TestCase() +{ + pthread_t tid = -1; + + int ret = pthread_create(&tid, nullptr, PthreadSigsetSigHold, nullptr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_kill(tid, SIGUSR1); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = pthread_join(tid, nullptr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&tid, nullptr, PthreadSigsetSigUsr, nullptr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_kill(tid, SIGUSR2); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = pthread_join(tid, nullptr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return 0; +} + +void ItPosixSigset001(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/sigset_test_002.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/sigset_test_002.cpp new file mode 100644 index 00000000..d9be9437 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/signal/smoke/sigset_test_002.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "it_test_signal.h" +#include "signal.h" +#include "pthread.h" +#include "errno.h" +static int g_signum; + +static void SigUsr(int sigNum) +{ + g_signum = sigNum; +} + +static void *PthreadSigsetSigSetError(void *arg) +{ + void (*ret)(int); + ret = sigset(0, SigUsr); + ICUNIT_ASSERT_NOT_EQUAL_NULL(ret, NULL, ret); + ICUNIT_ASSERT_EQUAL_NULL(errno, EINVAL, errno); + errno = 0; + + ret = sigset(_NSIG, SigUsr); + ICUNIT_ASSERT_NOT_EQUAL_NULL(ret, NULL, ret); + ICUNIT_ASSERT_EQUAL_NULL(errno, EINVAL, errno); + errno = 0; + + return nullptr; +} + +static UINT32 TestCase() +{ + pthread_t tid; + + int ret = pthread_create(&tid, nullptr, PthreadSigsetSigSetError, nullptr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = pthread_kill(tid, SIGUSR1); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = pthread_join(tid, nullptr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return 0; +} + +void ItPosixSigset002(void) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/trace/It_test_trace.h b/src/kernel_liteos_a/testsuites/unittest/extended/trace/It_test_trace.h new file mode 100644 index 00000000..aa183311 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/trace/It_test_trace.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _IT_TEST_SYS_H +#define _IT_TEST_SYS_H + +#include "osTest.h" +#include +#include +#include +#include +#include + +#define TRACE_IOC_MAGIC 'T' +#define TRACE_START _IO(TRACE_IOC_MAGIC, 1) +#define TRACE_STOP _IO(TRACE_IOC_MAGIC, 2) +#define TRACE_RESET _IO(TRACE_IOC_MAGIC, 3) +#define TRACE_DUMP _IO(TRACE_IOC_MAGIC, 4) +#define TRACE_SET_MASK _IO(TRACE_IOC_MAGIC, 5) +#define TRACE_USR_MAX_PARAMS 3 + +typedef struct { + unsigned int eventType; + uintptr_t identity; + uintptr_t params[TRACE_USR_MAX_PARAMS]; +} UsrEventInfo; + +VOID ItTestTrace001(VOID); +VOID ItTestTrace002(VOID); +VOID ItTestTrace003(VOID); +VOID ItTestTrace004(VOID); +#endif diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/trace/config.gni b/src/kernel_liteos_a/testsuites/unittest/extended/trace/config.gni new file mode 100644 index 00000000..78b55197 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/trace/config.gni @@ -0,0 +1,43 @@ +# Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +trace_include_dirs = [ "$TEST_UNITTEST_DIR/extended/trace" ] + +trace_sources_entry = + [ "$TEST_UNITTEST_DIR/extended/trace/trace_unit_test.cpp" ] + +trace_sources_smoke = [ + "$TEST_UNITTEST_DIR/extended/trace/smoke/trace_test_001.cpp", + "$TEST_UNITTEST_DIR/extended/trace/smoke/trace_test_002.cpp", + "$TEST_UNITTEST_DIR/extended/trace/smoke/trace_test_003.cpp", + "$TEST_UNITTEST_DIR/extended/trace/smoke/trace_test_004.cpp", +] + +trace_sources_full = [] diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/trace/smoke/trace_test_001.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/trace/smoke/trace_test_001.cpp new file mode 100644 index 00000000..65694ec2 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/trace/smoke/trace_test_001.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_test_trace.h" + +static UINT32 TestCase(VOID) +{ + int fd = open("/dev/trace", O_RDWR); + ICUNIT_GOTO_NOT_EQUAL(fd, -1, errno, EXIT); + + ioctl(fd, TRACE_START, NULL); + sleep(1); + ioctl(fd, TRACE_STOP, NULL); + ioctl(fd, TRACE_DUMP, false); +EXIT: + close(fd); + return 0; +} + +VOID ItTestTrace001(VOID) +{ + TEST_ADD_CASE("IT_TEST_TRACE_001", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/trace/smoke/trace_test_002.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/trace/smoke/trace_test_002.cpp new file mode 100644 index 00000000..71ec72cf --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/trace/smoke/trace_test_002.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_test_trace.h" + +static UINT32 TestCase(VOID) +{ + size_t mask; + int fd = open("/dev/trace", O_RDWR); + ICUNIT_GOTO_NOT_EQUAL(fd, -1, errno, EXIT); + + ioctl(fd, TRACE_STOP, NULL); + ioctl(fd, TRACE_RESET, NULL); /* clear all events */ + + mask = 0x10000; /* filter kernel events */ + ioctl(fd, TRACE_SET_MASK, mask); + + ioctl(fd, TRACE_START, NULL); /* start trace */ + sleep(1); + ioctl(fd, TRACE_STOP, NULL); + ioctl(fd, TRACE_DUMP, false); +EXIT: + close(fd); + return 0; +} + +VOID ItTestTrace002(VOID) +{ + TEST_ADD_CASE("IT_TEST_TRACE_002", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/trace/smoke/trace_test_003.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/trace/smoke/trace_test_003.cpp new file mode 100644 index 00000000..3feeb3b9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/trace/smoke/trace_test_003.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_test_trace.h" + +static UINT32 TestCase(VOID) +{ + UsrEventInfo info = { + .eventType = 0x1, + .identity = 0x0001, + .params = {1, 2, 3}, + }; + + int fd = open("/dev/trace", O_RDWR); + ICUNIT_GOTO_NOT_EQUAL(fd, -1, errno, EXIT); + + ioctl(fd, TRACE_START, NULL); /* start trace */ + (void)write(fd, &info, sizeof(UsrEventInfo)); + info.eventType = 0x2; + info.identity = 0x0002; + (void)write(fd, &info, sizeof(UsrEventInfo)); + + ioctl(fd, TRACE_STOP, NULL); + ioctl(fd, TRACE_DUMP, false); +EXIT: + close(fd); + return 0; +} + +VOID ItTestTrace003(VOID) +{ + TEST_ADD_CASE("IT_TEST_TRACE_003", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/trace/smoke/trace_test_004.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/trace/smoke/trace_test_004.cpp new file mode 100644 index 00000000..8429ed36 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/trace/smoke/trace_test_004.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_test_trace.h" + +static UINT32 TestCase(VOID) +{ + int i; + int size = 0x100; + int len; + char *buffer = NULL; + + int fd = open("/dev/trace", O_RDWR); + ICUNIT_GOTO_NOT_EQUAL(fd, -1, errno, EXIT); + + ioctl(fd, TRACE_STOP, NULL); + + buffer = static_cast(malloc(size)); + if (buffer == NULL) { + printf("Read buffer malloc failed!\n"); + goto EXIT; + } + + len = read(fd, buffer, size); + for (i = 0; i < len; i++) { + printf("%02x ", buffer[i] & 0xFF); + } + printf("\n"); + free(buffer); +EXIT: + close(fd); + return 0; +} + +VOID ItTestTrace004(VOID) +{ + TEST_ADD_CASE("IT_TEST_TRACE_004", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/extended/trace/trace_unit_test.cpp b/src/kernel_liteos_a/testsuites/unittest/extended/trace/trace_unit_test.cpp new file mode 100644 index 00000000..2ccf372b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/extended/trace/trace_unit_test.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "stdio.h" +#include +#include + +#include "It_test_trace.h" + +using namespace testing::ext; +namespace OHOS { +class TraceTest : public testing::Test { +public: + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} +}; + +#if defined(LOSCFG_USER_TEST_SMOKE) +/* * + * @tc.name: IT_TEST_TRACE_001 + * @tc.desc: function for TraceTest + * @tc.type: FUNC + */ +HWTEST_F(TraceTest, ItTestTrace001, TestSize.Level0) +{ + ItTestTrace001(); +} + +/* * + * @tc.name: IT_TEST_TRACE_002 + * @tc.desc: function for TraceTest + * @tc.type: FUNC + */ +HWTEST_F(TraceTest, ItTestTrace002, TestSize.Level0) +{ + ItTestTrace002(); +} + +/* * + * @tc.name: IT_TEST_TRACE_003 + * @tc.desc: function for TraceTest + * @tc.type: FUNC + */ +HWTEST_F(TraceTest, ItTestTrace003, TestSize.Level0) +{ + ItTestTrace003(); +} + +/* * + * @tc.name: IT_TEST_TRACE_004 + * @tc.desc: function for TraceTest + * @tc.type: FUNC + */ +HWTEST_F(TraceTest, ItTestTrace004, TestSize.Level0) +{ + ItTestTrace004(); +} +#endif +} // namespace OHOS diff --git a/src/kernel_liteos_a/testsuites/unittest/fs/BUILD.gn b/src/kernel_liteos_a/testsuites/unittest/fs/BUILD.gn new file mode 100644 index 00000000..1b108871 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fs/BUILD.gn @@ -0,0 +1,77 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("./config.gni") + +if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_LOW) { + unittest("liteos_a_fs_unittest_door") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + include_dirs = common_include_dirs + sources = sources_entry + sources += sources_smoke + sources_full = [] + sources += sources_full + sources_pressure = [] + sources += sources_pressure + configs = [ "..:public_config_for_door" ] + deps = [ "$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR:libsec_shared" ] + } +} + +if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_MIDDLE) { + unittest("liteos_a_fs_unittest") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + include_dirs = common_include_dirs + sources = sources_entry + sources += sources_smoke + sources += sources_full + sources_pressure = [] + sources += sources_pressure + configs = [ "..:public_config_for_all" ] + deps = [ "$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR:libsec_shared" ] + } +} + +if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_HIGH) { + unittest("liteos_a_fs_unittest_pressure") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + include_dirs = common_include_dirs + sources = sources_entry + sources_smoke = [] + sources += sources_smoke + sources_full = [] + sources += sources_full + sources += sources_pressure + configs = [ "..:public_config_for_pressure" ] + deps = [ "$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR:libsec_shared" ] + } +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fs/config.gni b/src/kernel_liteos_a/testsuites/unittest/fs/config.gni new file mode 100644 index 00000000..f2f1e802 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fs/config.gni @@ -0,0 +1,44 @@ +# Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//build/lite/config/test.gni") +import("//kernel/liteos_a/liteos.gni") +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +common_include_dirs = [ + "$THIRDPARTY_GOOGLETEST_DIR/googletest/include", + "../common/include", +] + +sources_entry = [ "../common/osTest.cpp" ] + +sources_smoke = [] + +sources_pressure = [] + +sources_full = [] diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/BUILD.gn b/src/kernel_liteos_a/testsuites/unittest/fuzz/BUILD.gn new file mode 100644 index 00000000..21b6295c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/BUILD.gn @@ -0,0 +1,88 @@ +# Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//build/lite/config/test.gni") + +fuzztest("liteos_a_user_fuzz_test") { + output_extension = "bin" + sources = [ + "adjtime_fuzzer.cpp", + "chroot_fuzzer.cpp", + "clone_fuzzer.cpp", + "epoll_create_fuzzer.cpp", + "epoll_ctl_fuzzer.cpp", + "epoll_wait_fuzzer.cpp", + "fesetenv_fuzzer.cpp", + "getrlimit_fuzzer.cpp", + "main.cpp", + "mlock_fuzzer.cpp", + "mlockall_fuzzer.cpp", + "posix_spawn_file_actions_addchdir_np_fuzzer.cpp", + "posix_spawn_file_actions_adddup2_fuzzer.cpp", + "posix_spawn_file_actions_addfchdir_np_fuzzer.cpp", + "posix_spawn_file_actions_addopen_fuzzer.cpp", + "posix_spawn_file_actions_destroy_fuzzer.cpp", + "posix_spawn_file_actions_init_fuzzer.cpp", + "posix_spawn_fuzzer.cpp", + "posix_spawnattr_destroy_fuzzer.cpp", + "posix_spawnattr_getflags_fuzzer.cpp", + "posix_spawnattr_getpgroup_fuzzer.cpp", + "posix_spawnattr_getschedparam_fuzzer.cpp", + "posix_spawnattr_getschedpolicy_fuzzer.cpp", + "posix_spawnattr_getsigdefault_fuzzer.cpp", + "posix_spawnattr_getsigmask_fuzzer.cpp", + "posix_spawnattr_init_fuzzer.cpp", + "posix_spawnattr_setflags_fuzzer.cpp", + "posix_spawnattr_setpgroup_fuzzer.cpp", + "posix_spawnattr_setschedparam_fuzzer.cpp", + "posix_spawnattr_setschedpolicy_fuzzer.cpp", + "posix_spawnattr_setsigdefault_fuzzer.cpp", + "posix_spawnattr_setsigmask_fuzzer.cpp", + "posix_spawnp_fuzzer.cpp", + "pthread_mutex_consistent_fuzzer.cpp", + "pthread_mutex_getprioceiling_fuzzer.cpp", + "pthread_mutexattr_setprotocol_fuzzer.cpp", + "pthread_mutexattr_setrobust_fuzzer.cpp", + "pthread_mutexattr_settype_fuzzer.cpp", + "pthread_setconcurrency_fuzzer.cpp", + "readlink_fuzzer.cpp", + "readlinkat_fuzzer.cpp", + "sem_open_fuzzer.cpp", + "sethostname_fuzzer.cpp", + "setns_fuzzer.cpp", + "syslog_fuzzer.cpp", + "system_fuzzer.cpp", + "times_fuzzer.cpp", + "unshare_fuzzer.cpp", + ] + include_dirs = [] + deps = [] +} +group("liteos_a_fuzztest") { + deps = [ ":liteos_a_user_fuzz_test" ] +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/adjtime_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/adjtime_fuzzer.cpp new file mode 100644 index 00000000..294a91d7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/adjtime_fuzzer.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "fuzzertest.h" + +void TestAdjtime(void) +{ + struct timeval fa; + printf("start----TestAdjtime\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestAdjtime"), 0) { + char *delta = DT_SetGetFixBlob(&g_Element[0], sizeof(struct timeval), sizeof(struct timeval), (char *)&fa); + char *olddelta = DT_SetGetFixBlob(&g_Element[1], sizeof(struct timeval), sizeof(struct timeval), (char *)&fa); + adjtime((struct timeval *)delta, (struct timeval *)olddelta); + } + DT_FUZZ_END() + printf("end----TestAdjtime\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/chroot_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/chroot_fuzzer.cpp new file mode 100644 index 00000000..4db53e36 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/chroot_fuzzer.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "fuzzertest.h" + +void TestChroot(void) +{ + printf("start----TestChroot\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestChroot"), 0) { + char *buf = DT_SetGetString(&g_Element[0], LENGTH_STRING, MAXLENGTH_STRING, INITVALUE_STRING); + chroot(buf); + } + DT_FUZZ_END() + printf("end----TestChroot\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/clone_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/clone_fuzzer.cpp new file mode 100644 index 00000000..2ac95f6b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/clone_fuzzer.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "fuzzertest.h" + +static int childFunc(void *) +{ + return 0; +} + +void TestClone(void) +{ + printf("start----TestClone\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestClone"), 0) { + s32 number = *(s32 *)DT_SetGetS32(&g_Element[0], INITVALUE_S32); + pid_t pid = clone(childFunc, NULL, number, NULL); + waitpid(pid, NULL, 0); + } + DT_FUZZ_END() + printf("end----TestClone\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/epoll_create_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/epoll_create_fuzzer.cpp new file mode 100644 index 00000000..9a143a90 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/epoll_create_fuzzer.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "fuzzertest.h" + +void TestEpollCreate(void) +{ + printf("start----TestEpollCreate\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestEpollCreate"), 0) { + s32 number = *(s32 *)DT_SetGetS32(&g_Element[0], INITVALUE_S32); + epoll_create(number); + } + DT_FUZZ_END() + printf("end----TestEpollCreate\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/epoll_ctl_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/epoll_ctl_fuzzer.cpp new file mode 100644 index 00000000..1312df5d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/epoll_ctl_fuzzer.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "fuzzertest.h" + +void TestEpollCtl(void) +{ + struct epoll_event fa; + printf("start----TestEpollCtl\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestEpollCtl"), 0) { + s32 number0 = *(s32 *)DT_SetGetS32(&g_Element[0], INITVALUE_S32); + s32 number1 = *(s32 *)DT_SetGetS32(&g_Element[1], INITVALUE_S32); + s32 number2 = *(s32 *)DT_SetGetS32(&g_Element[2], INITVALUE_S32); + char *datainput = DT_SetGetFixBlob(&g_Element[3], sizeof(struct epoll_event), sizeof(struct epoll_event), + (char *)&fa); + epoll_ctl(number0, number1, number2, (struct epoll_event *)datainput); + } + DT_FUZZ_END() + printf("end----TestEpollCtl\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/epoll_wait_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/epoll_wait_fuzzer.cpp new file mode 100644 index 00000000..1bdb16f7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/epoll_wait_fuzzer.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "fuzzertest.h" + +void TestEpollWait(void) +{ + struct epoll_event fa; + printf("start----TestEpollWait\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestEpollWait"), 0) { + s32 number0 = *(s32 *)DT_SetGetS32(&g_Element[0], INITVALUE_S32); + s32 number1 = *(s32 *)DT_SetGetS32(&g_Element[1], INITVALUE_S32); + s32 number2 = *(s32 *)DT_SetGetS32(&g_Element[2], INITVALUE_S32); + char *datainput = DT_SetGetFixBlob(&g_Element[3], sizeof(struct epoll_event), sizeof(struct epoll_event), + (char *)&fa); + epoll_wait(number0, (struct epoll_event *)datainput, number1, number2); + } + DT_FUZZ_END() + printf("end----TestEpollWait\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/fesetenv_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/fesetenv_fuzzer.cpp new file mode 100644 index 00000000..7df96707 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/fesetenv_fuzzer.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "fuzzertest.h" + +void TestFesetenv(void) +{ + fenv_t fa; + printf("start----TestFesetenv\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestFesetenv"), 0) { + char *envp = DT_SetGetFixBlob(&g_Element[0], sizeof(fenv_t), sizeof(fenv_t), (char *)&fa); + fesetenv((fenv_t *)envp); + } + DT_FUZZ_END() + printf("end----TestFesetenv\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/fuzzertest.h b/src/kernel_liteos_a/testsuites/unittest/fuzz/fuzzertest.h new file mode 100644 index 00000000..d6d5e01c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/fuzzertest.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _FUZZERTEST_H +#define _FUZZERTEST_H + +#define FREQUENCY 100000 +#define INITVALUE_S32 0x123456 +#define INITVALUE_STRING "123456" +#define LENGTH_STRING 6 +#define MAXLENGTH_STRING 10000 + +#endif \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/getrlimit_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/getrlimit_fuzzer.cpp new file mode 100644 index 00000000..20af5126 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/getrlimit_fuzzer.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "fuzzertest.h" + +void TestGetrlimit(void) +{ + struct rlimit fa; + printf("start----TestGetrlimit\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestGetrlimit"), 0) { + s32 resource = *(s32 *)DT_SetGetS32(&g_Element[0], INITVALUE_S32); + char *datainput = DT_SetGetFixBlob(&g_Element[1], sizeof(struct rlimit), sizeof(struct rlimit), (char *)&fa); + getrlimit(resource, (struct rlimit *)datainput); + } + DT_FUZZ_END() + printf("end----TestGetrlimit\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/main.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/main.cpp new file mode 100644 index 00000000..3a231efe --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/main.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +extern void TestPosixSpawnFileActionsAddchdirNp(void); +extern void TestPosixSpawnFileActionsAdddup2(void); +extern void TestPosixSpawnFileActionsAddfchdirNp(void); +extern void TestPosixSpawnFileActionsAddopen(void); +extern void TestPosixSpawnFileActionsDestroy(void); +extern void TestPosixSpawnFileActionsInit(void); +extern void TestPosixSpawn(void); +extern void TestPosixSpawnattrDestroy(void); +extern void TestPosixSpawnattrGetflags(void); +extern void TestPosixSpawnattrGetpgroup(void); +extern void TestPosixSpawnattrGetschedparam(void); +extern void TestPosixSpawnattrGetschedpolicy(void); +extern void TestPosixSpawnattrGetsigdefault(void); +extern void TestPosixSpawnattrGetsigmask(void); +extern void TestPosixSpawnattrInit(void); +extern void TestPosixSpawnattrSetflags(void); +extern void TestPosixSpawnattrSetpgroup(void); +extern void TestPosixSpawnattrSetschedparam(void); +extern void TestPosixSpawnattrSetschedpolicy(void); +extern void TestPosixSpawnattrSetsigdefault(void); +extern void TestPosixSpawnattrSetsigmask(void); +extern void TestPosixSpawnp(void); +extern void TestAdjtime(void); +extern void TestFesetenv(void); +extern void TestGetrlimit(void); +extern void TestReadlink(void); +extern void TestReadlinkat(void); +extern void TestSyslog(void); +extern void TestSystem(void); +extern void TestTimes(void); +extern void TestClone(void); +extern void TestEpollCreate(void); +extern void TestEpollCtl(void); +extern void TestEpollWait(void); +extern void TestMlock(void); +extern void TestMlockall(void); +extern void TestPthreadMutexConsistent(void); +extern void TestPthreadMutexGetprioceiling(void); +extern void TestPthreadMutexattrSetprotocol(void); +extern void TestPthreadMutexattrSetrobust(void); +extern void TestPthreadMutexattrSettype(void); +extern void TestPthreadSetconcurrency(void); +extern void TestSetns(void); +extern void TestUnshare(void); +extern void TestSemOpen(void); +extern void TestChroot(void); +extern void TestSethostname(void); + +int main() +{ + DT_Set_Report_Path("/storage/"); + TestReadlink(); + TestReadlinkat(); + TestSethostname(); + TestClone(); + TestUnshare(); + TestChroot(); + TestSetns(); + return 0; +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/mlock_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/mlock_fuzzer.cpp new file mode 100644 index 00000000..06169988 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/mlock_fuzzer.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "fuzzertest.h" + +void TestMlock(void) +{ + int lockSize = 4096 + 1; + printf("start----TestMlock\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestMlock"), 0) { + char *p = DT_SetGetString(&g_Element[0], LENGTH_STRING, MAXLENGTH_STRING, INITVALUE_STRING); + mlock(p, lockSize); + munlock(p, lockSize); + } + DT_FUZZ_END() + printf("end----TestMlock\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/mlockall_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/mlockall_fuzzer.cpp new file mode 100644 index 00000000..c9c35f45 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/mlockall_fuzzer.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "fuzzertest.h" + +void TestMlockall(void) +{ + printf("start----TestMlockall\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestMlockall"), 0) { + s32 number = *(s32 *)DT_SetGetS32(&g_Element[0], INITVALUE_S32); + mlockall(number); + } + DT_FUZZ_END() + printf("end----TestMlockall\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawn_file_actions_addchdir_np_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawn_file_actions_addchdir_np_fuzzer.cpp new file mode 100644 index 00000000..bef1a865 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawn_file_actions_addchdir_np_fuzzer.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "fuzzertest.h" + +void TestPosixSpawnFileActionsAddchdirNp(void) +{ + posix_spawn_file_actions_t fa; + printf("start ---- TestPosixSpawnFileActionsAddchdirNp\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestPosixSpawnFileActionsAddchdirNp"), 0) { + fa.__pad0[0] = *(s32 *)DT_SetGetS32(&g_Element[0], INITVALUE_S32); + fa.__pad0[1] = *(s32 *)DT_SetGetS32(&g_Element[1], INITVALUE_S32); + fa.__pad0[2] = *(s32 *)DT_SetGetS32(&g_Element[2], INITVALUE_S32); + for (int i = 0; i < 16; i++) { + fa.__pad[i] = *(s32 *)DT_SetGetS32(&g_Element[i+3], INITVALUE_S32); + } + char *action = DT_SetGetBlob(&g_Element[18], LENGTH_STRING, MAXLENGTH_STRING, INITVALUE_STRING); + fa.__actions=(void *)action; + char *path = DT_SetGetString(&g_Element[19], LENGTH_STRING, MAXLENGTH_STRING, INITVALUE_STRING); + posix_spawn_file_actions_addchdir_np(&fa, path); + } + DT_FUZZ_END(); + printf("end --- TestPosixSpawnFileActionsAddchdirNp\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawn_file_actions_adddup2_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawn_file_actions_adddup2_fuzzer.cpp new file mode 100644 index 00000000..d7b877eb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawn_file_actions_adddup2_fuzzer.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "gtest/gtest.h" +#include "fuzzertest.h" + +void TestPosixSpawnFileActionsAdddup2(void) +{ + posix_spawn_file_actions_t fa; + printf("start ---- TestPosixSpawnFileActionsAdddup2\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestPosixSpawnFileActionsAdddup2"), 0) { + fa.__pad0[0] = *(s32 *)DT_SetGetS32(&g_Element[0], INITVALUE_S32); + fa.__pad0[1] = *(s32 *)DT_SetGetS32(&g_Element[1], INITVALUE_S32); + fa.__pad0[2] = *(s32 *)DT_SetGetS32(&g_Element[2], INITVALUE_S32); + for (int i = 0; i < 16; i++) { + fa.__pad[i] = *(s32 *)DT_SetGetS32(&g_Element[i+3], INITVALUE_S32); + } + char *action = DT_SetGetBlob(&g_Element[18], LENGTH_STRING, MAXLENGTH_STRING, INITVALUE_STRING); + fa.__actions=(void *)action; + s32 tmpfd = *(s32 *)DT_SetGetS32(&g_Element[19], INITVALUE_S32); + posix_spawn_file_actions_adddup2(&fa, STDOUT_FILENO, tmpfd); + } + DT_FUZZ_END(); + printf("end --- TestPosixSpawnFileActionsAdddup2\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawn_file_actions_addfchdir_np_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawn_file_actions_addfchdir_np_fuzzer.cpp new file mode 100644 index 00000000..894e6283 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawn_file_actions_addfchdir_np_fuzzer.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "fuzzertest.h" + +void TestPosixSpawnFileActionsAddfchdirNp(void) +{ + posix_spawn_file_actions_t fa; + printf("start ---- TestPosixSpawnFileActionsAddfchdirNp\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestPosixSpawnFileActionsAddfchdirNp"), 0) { + fa.__pad0[0] = *(s32 *)DT_SetGetS32(&g_Element[0], INITVALUE_S32); + fa.__pad0[1] = *(s32 *)DT_SetGetS32(&g_Element[1], INITVALUE_S32); + fa.__pad0[2] = *(s32 *)DT_SetGetS32(&g_Element[2], INITVALUE_S32); + for (int i = 0; i < 16; i++) { + fa.__pad[i] = *(s32 *)DT_SetGetS32(&g_Element[i+3], INITVALUE_S32); + } + char *action = DT_SetGetBlob(&g_Element[18], LENGTH_STRING, MAXLENGTH_STRING, INITVALUE_STRING); + fa.__actions=(void *)action; + s32 tmpfd = *(s32 *)DT_SetGetS32(&g_Element[19], INITVALUE_S32); + posix_spawn_file_actions_addfchdir_np(&fa, tmpfd); + } + DT_FUZZ_END(); + printf("end --- TestPosixSpawnFileActionsAddfchdirNp\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawn_file_actions_addopen_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawn_file_actions_addopen_fuzzer.cpp new file mode 100644 index 00000000..5310b781 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawn_file_actions_addopen_fuzzer.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "fuzzertest.h" + +void TestPosixSpawnFileActionsAddopen(void) +{ + posix_spawn_file_actions_t fa; + printf("start ---- TestPosixSpawnFileActionsAddopen\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestPosixSpawnFileActionsAddopen"), 0) { + fa.__pad0[0] = *(s32 *)DT_SetGetS32(&g_Element[0], INITVALUE_S32); + fa.__pad0[1] = *(s32 *)DT_SetGetS32(&g_Element[1], INITVALUE_S32); + fa.__pad0[2] = *(s32 *)DT_SetGetS32(&g_Element[2], INITVALUE_S32); + for (int i = 0; i < 16; i++) { + fa.__pad[i] = *(s32 *)DT_SetGetS32(&g_Element[i+3], INITVALUE_S32); + } + char *action = DT_SetGetBlob(&g_Element[18], LENGTH_STRING, MAXLENGTH_STRING, INITVALUE_STRING); + fa.__actions=(void *)action; + s32 tmpfd = *(s32 *)DT_SetGetS32(&g_Element[19], INITVALUE_S32); + char *path = DT_SetGetBlob(&g_Element[20], LENGTH_STRING, MAXLENGTH_STRING, INITVALUE_STRING); + s32 flag = *(s32 *)DT_SetGetS32(&g_Element[21], INITVALUE_S32); + posix_spawn_file_actions_addopen(&fa, tmpfd, path, flag, 0); + posix_spawn_file_actions_addclose(&fa, tmpfd); + } + DT_FUZZ_END(); + printf("end --- TestPosixSpawnFileActionsAddopen\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawn_file_actions_destroy_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawn_file_actions_destroy_fuzzer.cpp new file mode 100644 index 00000000..1acd5089 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawn_file_actions_destroy_fuzzer.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "fuzzertest.h" + +void TestPosixSpawnFileActionsDestroy(void) +{ + posix_spawn_file_actions_t fa; + printf("start ---- TestPosixSpawnFileActionsDestroy\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestPosixSpawnFileActionsDestroy"), 0) { + fa.__pad0[0] = *(s32 *)DT_SetGetS32(&g_Element[0], INITVALUE_S32); + fa.__pad0[1] = *(s32 *)DT_SetGetS32(&g_Element[1], INITVALUE_S32); + fa.__pad0[2] = *(s32 *)DT_SetGetS32(&g_Element[2], INITVALUE_S32); + for (int i = 0; i < 16; i++) { + fa.__pad[i] = *(s32 *)DT_SetGetS32(&g_Element[i+3], INITVALUE_S32); + } + char *action = DT_SetGetBlob(&g_Element[18], LENGTH_STRING, MAXLENGTH_STRING, INITVALUE_STRING); + fa.__actions=(void *)action; + posix_spawn_file_actions_init(&fa); + posix_spawn_file_actions_destroy(&fa); + } + DT_FUZZ_END(); + printf("end --- TestPosixSpawnFileActionsDestroy\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawn_file_actions_init_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawn_file_actions_init_fuzzer.cpp new file mode 100644 index 00000000..d62edb05 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawn_file_actions_init_fuzzer.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "fuzzertest.h" + +void TestPosixSpawnFileActionsInit(void) +{ + posix_spawn_file_actions_t fa; + printf("start ---- TestPosixSpawnFileActionsInit\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestPosixSpawnFileActionsInit"), 0) { + fa.__pad0[0] = *(s32 *)DT_SetGetS32(&g_Element[0], INITVALUE_S32); + fa.__pad0[1] = *(s32 *)DT_SetGetS32(&g_Element[1], INITVALUE_S32); + fa.__pad0[2] = *(s32 *)DT_SetGetS32(&g_Element[2], INITVALUE_S32); + for (int i = 0; i < 16; i++) { + fa.__pad[i] = *(s32 *)DT_SetGetS32(&g_Element[i+3], INITVALUE_S32); + } + char *action = DT_SetGetBlob(&g_Element[18], LENGTH_STRING, MAXLENGTH_STRING, INITVALUE_STRING); + fa.__actions=(void *)action; + posix_spawn_file_actions_init(&fa); + } + DT_FUZZ_END(); + printf("end --- TestPosixSpawnFileActionsInit\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawn_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawn_fuzzer.cpp new file mode 100644 index 00000000..20285647 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawn_fuzzer.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include "fuzzertest.h" + +void TestPosixSpawn(void) +{ + printf("start ---- TestPosixSpawn\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestPosixSpawn"), 0) { + s32 pid = *(s32 *)DT_SetGetS32(&g_Element[0], INITVALUE_S32); + char *argv[] = {"tftp", nullptr}; + posix_spawn(&pid, "/bin/tftp", nullptr, nullptr, argv, nullptr); + } + DT_FUZZ_END(); + printf("end --- TestPosixSpawn\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_destroy_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_destroy_fuzzer.cpp new file mode 100644 index 00000000..c9da6ad1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_destroy_fuzzer.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "fuzzertest.h" + +void TestPosixSpawnattrDestroy(void) +{ + posix_spawnattr_t attr; + printf("start ---- TestPosixSpawnattrDestroy\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestPosixSpawnattrDestroy"), 0) { + char *datainput = DT_SetGetFixBlob(&g_Element[0], sizeof(posix_spawnattr_t), sizeof(posix_spawnattr_t), + (char *)&attr); + posix_spawnattr_destroy((posix_spawnattr_t *)datainput); + } + DT_FUZZ_END(); + printf("end --- TestPosixSpawnattrDestroy\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_getflags_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_getflags_fuzzer.cpp new file mode 100644 index 00000000..ed299f63 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_getflags_fuzzer.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "fuzzertest.h" + +void TestPosixSpawnattrGetflags(void) +{ + posix_spawnattr_t attr; + printf("start ---- TestPosixSpawnattrGetflags\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestPosixSpawnattrGetflags"), 0) { + char *datainput = DT_SetGetFixBlob(&g_Element[0], sizeof(posix_spawnattr_t), sizeof(posix_spawnattr_t), + (char *)&attr); + s16 flag = *(s16 *)DT_SetGetS16(&g_Element[1], INITVALUE_S32); + posix_spawnattr_getflags((posix_spawnattr_t *)datainput, &flag); + } + DT_FUZZ_END(); + printf("end --- TestPosixSpawnattrGetflags\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_getpgroup_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_getpgroup_fuzzer.cpp new file mode 100644 index 00000000..12e92060 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_getpgroup_fuzzer.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "fuzzertest.h" + +void TestPosixSpawnattrGetpgroup(void) +{ + posix_spawnattr_t attr; + printf("start ---- TestPosixSpawnattrGetpgroup\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestPosixSpawnattrGetpgroup"), 0) { + char *datainput = DT_SetGetFixBlob(&g_Element[0], sizeof(posix_spawnattr_t), sizeof(posix_spawnattr_t), + (char *)&attr); + s32 pgrp = *(s32 *)DT_SetGetS32(&g_Element[1], INITVALUE_S32); + posix_spawnattr_getpgroup((posix_spawnattr_t *)datainput, &pgrp); + } + DT_FUZZ_END(); + printf("end --- TestPosixSpawnattrGetpgroup\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_getschedparam_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_getschedparam_fuzzer.cpp new file mode 100644 index 00000000..90b0b06b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_getschedparam_fuzzer.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include "fuzzertest.h" + +void TestPosixSpawnattrGetschedparam(void) +{ + posix_spawnattr_t attr; + struct sched_param schedparam; + printf("start ---- TestPosixSpawnattrGetschedparam\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestPosixSpawnattrGetschedparam"), 0) { + char *datainput = DT_SetGetFixBlob(&g_Element[0], sizeof(posix_spawnattr_t), sizeof(posix_spawnattr_t), + (char *)&attr); + char *datainput1 = DT_SetGetFixBlob(&g_Element[1], sizeof(struct sched_param), sizeof(struct sched_param), + (char *)&schedparam); + posix_spawnattr_getschedparam((posix_spawnattr_t *)datainput, (struct sched_param *)datainput); + } + DT_FUZZ_END(); + printf("end --- TestPosixSpawnattrGetschedparam\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_getschedpolicy_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_getschedpolicy_fuzzer.cpp new file mode 100644 index 00000000..c71e195f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_getschedpolicy_fuzzer.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "fuzzertest.h" + +void TestPosixSpawnattrGetschedpolicy(void) +{ + posix_spawnattr_t attr; + printf("start ---- TestPosixSpawnattrGetschedpolicy\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestPosixSpawnattrGetschedpolicy"), 0) { + char *datainput = DT_SetGetFixBlob(&g_Element[0], sizeof(posix_spawnattr_t), sizeof(posix_spawnattr_t), + (char *)&attr); + s32 policy = *(s32 *)DT_SetGetS32(&g_Element[1], INITVALUE_S32); + posix_spawnattr_getschedpolicy((posix_spawnattr_t *)datainput, &policy); + } + DT_FUZZ_END(); + printf("end --- TestPosixSpawnattrGetschedpolicy\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_getsigdefault_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_getsigdefault_fuzzer.cpp new file mode 100644 index 00000000..866527f4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_getsigdefault_fuzzer.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "fuzzertest.h" + +void TestPosixSpawnattrGetsigdefault(void) +{ + posix_spawnattr_t attr; + sigset_t signalset; + printf("start ---- TestPosixSpawnattrGetsigdefault\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestPosixSpawnattrGetsigdefault"), 0) { + char *datainput = DT_SetGetFixBlob(&g_Element[0], sizeof(posix_spawnattr_t), sizeof(posix_spawnattr_t), + (char *)&attr); + char *datainput1 = DT_SetGetFixBlob(&g_Element[1], sizeof(signalset), sizeof(signalset), (char *)&signalset); + posix_spawnattr_getsigdefault((posix_spawnattr_t *)datainput, (sigset_t *)datainput1); + } + DT_FUZZ_END(); + printf("end --- TestPosixSpawnattrGetsigdefault\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_getsigmask_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_getsigmask_fuzzer.cpp new file mode 100644 index 00000000..4410762a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_getsigmask_fuzzer.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "fuzzertest.h" + +void TestPosixSpawnattrGetsigmask(void) +{ + posix_spawnattr_t attr; + sigset_t signalset; + printf("start ---- TestPosixSpawnattrGetsigmask\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestPosixSpawnattrGetsigmask"), 0) { + char *datainput = DT_SetGetFixBlob(&g_Element[0], sizeof(posix_spawnattr_t), sizeof(posix_spawnattr_t), + (char *)&attr); + char *datainput1 = DT_SetGetFixBlob(&g_Element[1], sizeof(sigset_t), sizeof(sigset_t), (char *)&signalset); + posix_spawnattr_getsigmask((posix_spawnattr_t *)datainput, (sigset_t *)datainput1); + } + DT_FUZZ_END(); + printf("end --- TestPosixSpawnattrGetsigmask\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_init_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_init_fuzzer.cpp new file mode 100644 index 00000000..1bde6065 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_init_fuzzer.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "fuzzertest.h" + +void TestPosixSpawnattrInit(void) +{ + posix_spawnattr_t attr; + printf("start ---- TestPosixSpawnattrInit\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestPosixSpawnattrInit"), 0) { + char *datainput = DT_SetGetFixBlob(&g_Element[0], sizeof(posix_spawnattr_t), sizeof(posix_spawnattr_t), + (char *)&attr); + posix_spawnattr_init((posix_spawnattr_t *)datainput); + } + DT_FUZZ_END(); + printf("end --- TestPosixSpawnattrInit\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_setflags_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_setflags_fuzzer.cpp new file mode 100644 index 00000000..92718e75 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_setflags_fuzzer.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "fuzzertest.h" + +void TestPosixSpawnattrSetflags(void) +{ + posix_spawnattr_t attr; + printf("start ---- TestPosixSpawnattrSetflags\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestPosixSpawnattrSetflags"), 0) { + char *datainput = DT_SetGetFixBlob(&g_Element[0], sizeof(posix_spawnattr_t), sizeof(posix_spawnattr_t), + (char *)&attr); + s16 flags = *(s16 *)DT_SetGetS16(&g_Element[1], INITVALUE_S32); + posix_spawnattr_setflags((posix_spawnattr_t *)datainput, flags); + } + DT_FUZZ_END(); + printf("end --- TestPosixSpawnattrSetflags\n"); +} \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_setpgroup_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_setpgroup_fuzzer.cpp new file mode 100644 index 00000000..6c11e0d7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_setpgroup_fuzzer.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include "fuzzertest.h" + +void TestPosixSpawnattrSetpgroup(void) +{ + posix_spawnattr_t attr; + printf("start ---- TestPosixSpawnattrSetpgroup\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestPosixSpawnattrSetpgroup"), 0) { + char *datainput = DT_SetGetFixBlob(&g_Element[0], sizeof(posix_spawnattr_t), sizeof(posix_spawnattr_t), + (char *)&attr); + s32 pgrp = *(s32 *)DT_SetGetS32(&g_Element[1], INITVALUE_S32); + posix_spawnattr_setpgroup((posix_spawnattr_t *)datainput, pgrp); + } + DT_FUZZ_END(); + printf("end --- TestPosixSpawnattrSetpgroup\n"); +} \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_setschedparam_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_setschedparam_fuzzer.cpp new file mode 100644 index 00000000..5ddefaf6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_setschedparam_fuzzer.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include "fuzzertest.h" + +void TestPosixSpawnattrSetschedparam(void) +{ + posix_spawnattr_t attr; + struct sched_param schedparam; + printf("start ---- TestPosixSpawnattrSetschedparam\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestPosixSpawnattrSetschedparam"), 0) { + char *datainput = DT_SetGetFixBlob(&g_Element[0], sizeof(posix_spawnattr_t), sizeof(posix_spawnattr_t), + (char *)&attr); + char *datainput1 = DT_SetGetFixBlob(&g_Element[1], sizeof(struct sched_param), sizeof(struct sched_param), + (char *)&schedparam); + posix_spawnattr_setschedparam((posix_spawnattr_t *)datainput, (struct sched_param *)datainput1); + } + DT_FUZZ_END(); + printf("end --- TestPosixSpawnattrSetschedparam\n"); +} \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_setschedpolicy_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_setschedpolicy_fuzzer.cpp new file mode 100644 index 00000000..85df5784 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_setschedpolicy_fuzzer.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include "fuzzertest.h" + +void TestPosixSpawnattrSetschedpolicy(void) +{ + posix_spawnattr_t attr; + printf("start ---- TestPosixSpawnattrSetschedpolicy\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestPosixSpawnattrSetschedpolicy"), 0) { + char *datainput = DT_SetGetFixBlob(&g_Element[0], sizeof(posix_spawnattr_t), sizeof(posix_spawnattr_t), + (char *)&attr); + s32 policy = *(s32 *)DT_SetGetS32(&g_Element[1], INITVALUE_S32); + posix_spawnattr_setschedpolicy((posix_spawnattr_t *)datainput, policy); + } + DT_FUZZ_END(); + printf("end --- TestPosixSpawnattrSetschedpolicy\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_setsigdefault_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_setsigdefault_fuzzer.cpp new file mode 100644 index 00000000..e9dd3e5f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_setsigdefault_fuzzer.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "fuzzertest.h" + +void TestPosixSpawnattrSetsigdefault(void) +{ + posix_spawnattr_t attr; + sigset_t sigdefault; + printf("start ---- TestPosixSpawnattrSetsigdefault\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestPosixSpawnattrSetsigdefault"), 0) { + char *datainput = DT_SetGetFixBlob(&g_Element[0], sizeof(posix_spawnattr_t), sizeof(posix_spawnattr_t), + (char *)&attr); + char *datainput1 = DT_SetGetFixBlob(&g_Element[1], sizeof(sigset_t), sizeof(sigset_t), (char *)&sigdefault); + posix_spawnattr_setsigdefault((posix_spawnattr_t *)datainput, (sigset_t *)datainput1); + } + DT_FUZZ_END(); + printf("end --- TestPosixSpawnattrSetsigdefault\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_setsigmask_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_setsigmask_fuzzer.cpp new file mode 100644 index 00000000..b26412e2 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnattr_setsigmask_fuzzer.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "fuzzertest.h" + +void TestPosixSpawnattrSetsigmask(void) +{ + posix_spawnattr_t attr; + sigset_t signalset; + printf("start ---- TestPosixSpawnattrSetsigmask\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestPosixSpawnattrSetsigmask"), 0) { + char *datainput = DT_SetGetFixBlob(&g_Element[0], sizeof(posix_spawnattr_t), sizeof(posix_spawnattr_t), + (char *)&attr); + char *datainput1 = DT_SetGetFixBlob(&g_Element[1], sizeof(sigset_t), sizeof(sigset_t), (char *)&signalset); + posix_spawnattr_setsigmask((posix_spawnattr_t *)datainput, (sigset_t *)datainput1); + } + DT_FUZZ_END(); + printf("end --- TestPosixSpawnattrSetsigmask\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnp_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnp_fuzzer.cpp new file mode 100644 index 00000000..f2de4464 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/posix_spawnp_fuzzer.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include "fuzzertest.h" + +void TestPosixSpawnp(void) +{ + printf("start ---- TestPosixSpawnp\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestPosixSpawnp"), 0) { + s32 pid = *(s32 *)DT_SetGetS32(&g_Element[0], INITVALUE_S32); + char *argv[] = {"tftp", nullptr}; + posix_spawnp(&pid, "/bin/tftp", nullptr, nullptr, argv, nullptr); + } + DT_FUZZ_END(); + printf("end --- TestPosixSpawnp\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/pthread_mutex_consistent_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/pthread_mutex_consistent_fuzzer.cpp new file mode 100644 index 00000000..30854ae1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/pthread_mutex_consistent_fuzzer.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "fuzzertest.h" + +void TestPthreadMutexConsistent(void) +{ + pthread_mutex_t fa; + printf("start----TestPthreadMutexConsistent\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestPthreadMutexConsistent"), 0) { + char *datainput = DT_SetGetFixBlob(&g_Element[0], sizeof(pthread_mutex_t), sizeof(pthread_mutex_t), + (char *)&fa); + pthread_mutex_consistent((pthread_mutex_t *)datainput); + } + DT_FUZZ_END() + printf("end----TestPthreadMutexConsistent\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/pthread_mutex_getprioceiling_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/pthread_mutex_getprioceiling_fuzzer.cpp new file mode 100644 index 00000000..d659eb0b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/pthread_mutex_getprioceiling_fuzzer.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "fuzzertest.h" + +void TestPthreadMutexGetprioceiling(void) +{ + pthread_mutex_t g_muxLock; + printf("start----TestPthreadMutexGetprioceiling\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestPthreadMutexGetprioceiling"), 0) { + char *datainput = DT_SetGetFixBlob(&g_Element[0], sizeof(pthread_mutex_t), sizeof(pthread_mutex_t), + (char *)&g_muxLock); + s32 number0 = *(s32 *)DT_SetGetS32(&g_Element[1], INITVALUE_S32); + pthread_mutex_init((pthread_mutex_t *)datainput, NULL); + pthread_mutex_setprioceiling((pthread_mutex_t *)datainput, number0, NULL); + pthread_mutex_getprioceiling((pthread_mutex_t *)datainput, &number0); + pthread_mutex_destroy((pthread_mutex_t *)datainput); + } + DT_FUZZ_END(); + printf("end----TestPthreadMutexGetprioceiling\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/pthread_mutexattr_setprotocol_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/pthread_mutexattr_setprotocol_fuzzer.cpp new file mode 100644 index 00000000..1ce21c5f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/pthread_mutexattr_setprotocol_fuzzer.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "fuzzertest.h" + +void TestPthreadMutexattrSetprotocol(void) +{ + pthread_mutexattr_t fa; + printf("start----TestPthreadMutexattrSetprotocol\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestPthreadMutexattrSetprotocol"), 0) { + char *datainput = DT_SetGetFixBlob(&g_Element[0], sizeof(pthread_mutexattr_t), sizeof(pthread_mutexattr_t), + (char *)&fa); + s32 number = *(s32 *)DT_SetGetS32(&g_Element[1], INITVALUE_S32); + pthread_mutexattr_setprotocol((pthread_mutexattr_t *)datainput, number); + } + DT_FUZZ_END() + printf("end----TestPthreadMutexattrSetprotocol\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/pthread_mutexattr_setrobust_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/pthread_mutexattr_setrobust_fuzzer.cpp new file mode 100644 index 00000000..f1a7a155 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/pthread_mutexattr_setrobust_fuzzer.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "fuzzertest.h" + +void TestPthreadMutexattrSetrobust(void) +{ + pthread_mutexattr_t fa; + printf("start----TestPthreadMutexattrSetrobust\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestPthreadMutexattrSetrobust"), 0) { + char *datainput = DT_SetGetFixBlob(&g_Element[0], sizeof(pthread_mutexattr_t), sizeof(pthread_mutexattr_t), + (char *)&fa); + s32 number = *(s32 *)DT_SetGetS32(&g_Element[1], INITVALUE_S32); + pthread_mutexattr_setrobust((pthread_mutexattr_t *)datainput, number); + } + DT_FUZZ_END() + printf("end----TestPthreadMutexattrSetrobust\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/pthread_mutexattr_settype_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/pthread_mutexattr_settype_fuzzer.cpp new file mode 100644 index 00000000..7acbcbf0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/pthread_mutexattr_settype_fuzzer.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "fuzzertest.h" + +void TestPthreadMutexattrSettype(void) +{ + pthread_mutexattr_t fa; + printf("start----TestPthreadMutexattrSettype\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestPthreadMutexattrSettype"), 0) { + char *datainput = DT_SetGetFixBlob(&g_Element[0], sizeof(pthread_mutexattr_t), sizeof(pthread_mutexattr_t), + (char *)&fa); + s32 number = *(s32 *)DT_SetGetS32(&g_Element[1], INITVALUE_S32); + pthread_mutexattr_settype((pthread_mutexattr_t *)datainput, number); + } + DT_FUZZ_END() + printf("end----TestPthreadMutexattrSettype\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/pthread_setconcurrency_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/pthread_setconcurrency_fuzzer.cpp new file mode 100644 index 00000000..7cb46f09 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/pthread_setconcurrency_fuzzer.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "fuzzertest.h" + +void TestPthreadSetconcurrency(void) +{ + printf("start----TestPthreadSetconcurrency\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestPthreadSetconcurrency"), 0) { + s32 number = *(s32 *)DT_SetGetS32(&g_Element[0], INITVALUE_S32); + pthread_setconcurrency(number); + } + DT_FUZZ_END() + printf("end----TestPthreadSetconcurrency\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/readlink_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/readlink_fuzzer.cpp new file mode 100644 index 00000000..9280345a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/readlink_fuzzer.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "fuzzertest.h" + +void TestReadlink(void) +{ + printf("start----TestReadlink\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestReadlink"), 0) { + char *pathname = DT_SetGetBlob(&g_Element[0], LENGTH_STRING, MAXLENGTH_STRING, INITVALUE_STRING); + char *buf = DT_SetGetBlob(&g_Element[1], LENGTH_STRING, MAXLENGTH_STRING, INITVALUE_STRING); + int bufsize = DT_GET_MutatedValueLen(&g_Element[1]); + readlink(pathname, buf, bufsize); + } + DT_FUZZ_END() + printf("end----TestReadlink\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/readlinkat_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/readlinkat_fuzzer.cpp new file mode 100644 index 00000000..1f63f150 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/readlinkat_fuzzer.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include "fuzzertest.h" + +void TestReadlinkat(void) +{ + printf("start----TestReadlinkat\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestReadlinkat"), 0) { + s32 dirfd = *(s32*)DT_SetGetS32(&g_Element[0], INITVALUE_S32); + char *pathname = DT_SetGetBlob(&g_Element[1], LENGTH_STRING, MAXLENGTH_STRING, INITVALUE_STRING); + char *buf = DT_SetGetBlob(&g_Element[2], LENGTH_STRING, MAXLENGTH_STRING, INITVALUE_STRING); + int bufsize = DT_GET_MutatedValueLen(&g_Element[2]); + readlinkat(dirfd, pathname, buf, bufsize); + } + DT_FUZZ_END() + printf("end----TestReadlinkat\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/sem_open_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/sem_open_fuzzer.cpp new file mode 100644 index 00000000..475f4a79 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/sem_open_fuzzer.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "sys/types.h" +#include "gtest/gtest.h" +#include "fuzzertest.h" + +void TestSemOpen(void) +{ + printf("start ---- TestSemOpen\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestSemOpen"), 0) { + char *buf = DT_SetGetString(&g_Element[0], LENGTH_STRING, MAXLENGTH_STRING, INITVALUE_STRING); + sem_open(buf, O_CREAT | O_EXCL, 0700, 1); + } + DT_FUZZ_END(); + printf("end --- TestSemOpen\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/sethostname_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/sethostname_fuzzer.cpp new file mode 100644 index 00000000..13cd4beb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/sethostname_fuzzer.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "fuzzertest.h" + +void TestSethostname(void) +{ + printf("start----TestSethostname\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestSethostname"), 0) { + char *buf = DT_SetGetString(&g_Element[0], LENGTH_STRING, MAXLENGTH_STRING, INITVALUE_STRING); + s32 number = *(s32 *)DT_SetGetS32(&g_Element[1], INITVALUE_S32); + sethostname(buf, number); + } + DT_FUZZ_END() + printf("end----TestSethostname\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/setns_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/setns_fuzzer.cpp new file mode 100644 index 00000000..469122a5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/setns_fuzzer.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "fuzzertest.h" + +void TestSetns(void) +{ + printf("start----TestSetns\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestSetns"), 0) { + s32 number0 = *(s32 *)DT_SetGetS32(&g_Element[0], INITVALUE_S32); + s32 number1 = *(s32 *)DT_SetGetS32(&g_Element[1], INITVALUE_S32); + setns(number0, number1); + } + DT_FUZZ_END() + printf("end----TestSetns\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/syslog_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/syslog_fuzzer.cpp new file mode 100644 index 00000000..adf5166b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/syslog_fuzzer.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "fuzzertest.h" + +void TestSyslog(void) +{ + printf("start----TestSyslog\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestSyslog"), 0) { + s32 number = *(s32 *)DT_SetGetS32(&g_Element[0], INITVALUE_S32); + char *buf = DT_SetGetString(&g_Element[1], LENGTH_STRING, MAXLENGTH_STRING, INITVALUE_STRING); + syslog(number, "%s\n", buf); + } + DT_FUZZ_END() + printf("end----TestSyslog\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/system_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/system_fuzzer.cpp new file mode 100644 index 00000000..1151fdfa --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/system_fuzzer.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "fuzzertest.h" + +void TestSystem(void) +{ + printf("start----TestSystem\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestSystem"), 0) { + char *buf = DT_SetGetString(&g_Element[0], LENGTH_STRING, MAXLENGTH_STRING, INITVALUE_STRING); + system(buf); + } + DT_FUZZ_END() + printf("end----TestSystem\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/times_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/times_fuzzer.cpp new file mode 100644 index 00000000..449179b6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/times_fuzzer.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include "fuzzertest.h" + +void TestTimes(void) +{ + struct tms buf; + printf("start----TestTimes\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestTimes"), 0) { + char *datainput = DT_SetGetFixBlob(&g_Element[0], sizeof(struct tms), sizeof(struct tms), (char *)&buf); + times((struct tms *)datainput); + } + DT_FUZZ_END() + printf("end----TestTimes\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/fuzz/unshare_fuzzer.cpp b/src/kernel_liteos_a/testsuites/unittest/fuzz/unshare_fuzzer.cpp new file mode 100644 index 00000000..8d451e4c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/fuzz/unshare_fuzzer.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "fuzzertest.h" + +void TestUnshare(void) +{ + printf("start----TestUnshare\n"); + DT_Enable_Support_Loop(1); + + DT_FUZZ_START(0, FREQUENCY, const_cast("TestUnshare"), 0) { + s32 number = *(s32 *)DT_SetGetS32(&g_Element[0], INITVALUE_S32); + unshare(number); + } + DT_FUZZ_END() + printf("end----TestUnshare\n"); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/BUILD.gn b/src/kernel_liteos_a/testsuites/unittest/libc/io/BUILD.gn new file mode 100644 index 00000000..797aae93 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/BUILD.gn @@ -0,0 +1,66 @@ +# Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("./config.gni") + +config("libc_config") { + if (LOSCFG_USER_TEST_LIBC_POSIX_MQUEUE == true || + LOSCFG_USER_TEST_LIBC_POSIX_PTHREAD == true) { + cflags = [ "-O1" ] + cflags_cc = cflags + } +} + +if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_LOW) { + unittest("liteos_a_libc_io_unittest_door") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + include_dirs = common_include_dirs + sources = sources_entry + sources += sources_smoke + sources_full = [] + sources += sources_full + configs = [ "../..:public_config_for_door" ] + configs += [ ":libc_config" ] + deps = [ "$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR:libsec_shared" ] + } +} + +if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_MIDDLE) { + unittest("liteos_a_libc_io_unittest") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + include_dirs = common_include_dirs + sources = sources_entry + sources += sources_smoke + sources += sources_full + configs = [ "../..:public_config_for_all" ] + configs += [ ":libc_config" ] + deps = [ "$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR:libsec_shared" ] + } +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/It_test_IO.h b/src/kernel_liteos_a/testsuites/unittest/libc/io/It_test_IO.h new file mode 100644 index 00000000..422531de --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/It_test_IO.h @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _IT_TEST_IO_H +#define _IT_TEST_IO_H + +#include "osTest.h" +#include "stdio.h" +#include "stdlib.h" +#include "unistd.h" +#include "string.h" +#include "termios.h" +#include "sys/types.h" +#include "sys/stat.h" +#include "fcntl.h" +#include "locale.h" +#include "wctype.h" +#include "wchar.h" +#include "stdarg.h" +#include "semaphore.h" +#include "ftw.h" +#include "aio.h" +#include "shadow.h" +#include "pty.h" +#include "dirent.h" +#include "poll.h" +#include "grp.h" +#include "pwd.h" +#include "sys/uio.h" +#include "syslog.h" +#include "sys/epoll.h" + +extern int CloseRmAllFile(int fd[], char filePathName[][50], int cnt); +extern char *g_ioTestPath; + +extern VOID ItTestIo001(VOID); +extern VOID ItTestIo002(VOID); +extern VOID ItTestIo003(VOID); +extern VOID ItTestIo004(VOID); +extern VOID ItTestIo005(VOID); +extern VOID ItTestIo006(VOID); +extern VOID ItTestIo007(VOID); +extern VOID ItTestIo008(VOID); +extern VOID ItTestIo009(VOID); +extern VOID ItTestIo010(VOID); +extern VOID ItTestIo011(VOID); +extern VOID ItTestIo012(VOID); +extern VOID ItTestIo013(VOID); + +extern VOID ItLocaleFreelocale001(void); +extern VOID ItLocaleLocaleconv001(void); +extern VOID ItStdioFputws001(void); +extern VOID ItStdioFwprintf001(void); +extern VOID ItStdioFtruncate001(void); +extern VOID ItStdioFtw001(void); +extern VOID ItStdlibOpenpty001(void); +extern VOID ItStdlibPtsname001(void); +extern VOID ItStdioGetcUnlocked001(void); +extern VOID ItStdioGetcharUnlocked001(void); +extern VOID ItStdioGetw001(void); +extern VOID ItStdioGetwchar001(void); +extern VOID ItStdioLioListio001(void); // linux erro +extern VOID ItStdioMblen001(void); +extern VOID ItStdioMbrlen001(void); +extern VOID ItStdioMbstowcs001(void); +extern VOID ItStdioMbsnrtowcs001(void); +extern VOID ItStdioPutcUnlocked001(void); +extern VOID ItStdioPutcharUnlocked001(void); +extern VOID ItStdioPutgrent001(void); +extern VOID ItStdioPutpwent001(void); +extern VOID ItStdioPutspent001(void); +extern VOID ItStdioPutwc001(void); +extern VOID ItStdioPutwchar001(void); +extern VOID ItStdioReadv001(void); +extern VOID ItStdioRindex001(void); +extern VOID ItStdioSelect002(void); +extern VOID ItStdioSetgrent001(void); +extern VOID ItStdioSetlogmask001(void); +extern VOID ItStdioSetmntent001(void); +extern VOID ItStdlibGcvt001(void); +extern VOID ItStdlibOpenpty001(void); +extern VOID ItStdlibPoll001(void); +extern VOID ItStdlibPoll002(void); +extern VOID ItStdlibPoll003(void); +extern VOID ItStdlibPtsname001(void); +extern VOID IT_STDIO_HASMNTOPT_001(void); +extern VOID IO_TEST_NGETTEXT_001(void); +extern VOID IO_TEST_EPOLL_001(void); +extern VOID IO_TEST_LOCALE_001(void); +extern VOID IO_TEST_LOCALE_002(void); +extern VOID IO_TEST_CONFSTR_001(void); +extern VOID IO_TEST_NL_LANGINFO_001(VOID); +extern VOID IO_TEST_STRCASECMP_L_001(VOID); +extern VOID IO_TEST_STRCASECMP_L_002(VOID); +extern VOID IO_TEST_STRNCASECMP_L_001(VOID); +extern VOID IO_TEST_STRNCASECMP_L_002(VOID); +extern VOID IO_TEST_DUPLOCALE_001(void); +extern VOID IO_TEST_NL_LANGINFO_l_001(VOID); +extern VOID IO_TEST_DNGETTEXT_001(VOID); +extern VOID IO_TEST_DNGETTEXT_002(VOID); +extern VOID IO_TEST_DCNGETTEXT_001(VOID); +extern VOID IO_TEST_DCNGETTEXT_002(VOID); +extern VOID IO_TEST_DCGETTEXT_001(VOID); +extern VOID IO_TEST_DCGETTEXT_002(VOID); +extern VOID IO_TEST_GETTEXT_001(VOID); +extern VOID IO_TEST_PSELECT_001(void); +extern VOID IO_TEST_PSELECT_002(void); +extern VOID IO_TEST_STRFMON_L_001(VOID); +extern VOID IO_TEST_STRFMON_L_002(VOID); +extern VOID IO_TEST_PPOLL_001(VOID); +extern VOID IO_TEST_PPOLL_002(VOID); +extern VOID IO_TEST_PPOLL_003(VOID); +extern VOID IO_TEST_EPOLL_001(VOID); +extern VOID IO_TEST_EPOLL_002(VOID); + +#endif diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/config.gni b/src/kernel_liteos_a/testsuites/unittest/libc/io/config.gni new file mode 100644 index 00000000..9d072a92 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/config.gni @@ -0,0 +1,105 @@ +# Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//build/lite/config/test.gni") +import("//kernel/liteos_a/liteos.gni") +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +common_include_dirs = [ + "$THIRDPARTY_GOOGLETEST_DIR/googletest/include", + "../../common/include", +] + +sources_entry = [ "../../common/osTest.cpp" ] + +sources_smoke = [] + +sources_full = [] + +libc_io_include_dirs = [ "$TEST_UNITTEST_DIR/libc/io" ] + +libc_io_sources_entry = [ "$TEST_UNITTEST_DIR/libc/io/io_test.cpp" ] + +libc_io_sources_smoke = [ + "$TEST_UNITTEST_DIR/libc/io/smoke/IO_test_005.cpp", + "$TEST_UNITTEST_DIR/libc/io/smoke/IO_test_008.cpp", + "$TEST_UNITTEST_DIR/libc/io/smoke/IO_test_010.cpp", + "$TEST_UNITTEST_DIR/libc/io/smoke/IO_test_013.cpp", +] + +libc_io_sources_full = [ + "$TEST_UNITTEST_DIR/libc/io/full/IO_test_confstr_001.cpp", + "$TEST_UNITTEST_DIR/libc/io/full/IO_test_dcgettext_001.cpp", + "$TEST_UNITTEST_DIR/libc/io/full/IO_test_dcgettext_002.cpp", + "$TEST_UNITTEST_DIR/libc/io/full/IO_test_dcngettext_001.cpp", + "$TEST_UNITTEST_DIR/libc/io/full/IO_test_dcngettext_002.cpp", + "$TEST_UNITTEST_DIR/libc/io/full/IO_test_dngettext_001.cpp", + "$TEST_UNITTEST_DIR/libc/io/full/IO_test_dngettext_002.cpp", + "$TEST_UNITTEST_DIR/libc/io/full/IO_test_duplocale_001.cpp", + "$TEST_UNITTEST_DIR/libc/io/full/IO_test_locale_001.cpp", + "$TEST_UNITTEST_DIR/libc/io/full/IO_test_locale_002.cpp", + "$TEST_UNITTEST_DIR/libc/io/full/IO_test_ngettext_001.cpp", + "$TEST_UNITTEST_DIR/libc/io/full/IO_test_nl_langinfo_001.cpp", + "$TEST_UNITTEST_DIR/libc/io/full/IO_test_nl_langinfo_l_001.cpp", + "$TEST_UNITTEST_DIR/libc/io/full/IO_test_strcasecmp_l_001.cpp", + "$TEST_UNITTEST_DIR/libc/io/full/IO_test_strcasecmp_l_002.cpp", + "$TEST_UNITTEST_DIR/libc/io/full/IO_test_strfmon_l_001.cpp", + "$TEST_UNITTEST_DIR/libc/io/full/IO_test_strfmon_l_002.cpp", + "$TEST_UNITTEST_DIR/libc/io/full/It_locale_localeconv_001.cpp", + "$TEST_UNITTEST_DIR/libc/io/full/It_stdio_fputws_001.cpp", + "$TEST_UNITTEST_DIR/libc/io/full/It_stdio_fwprintf_001.cpp", + "$TEST_UNITTEST_DIR/libc/io/full/It_stdio_getc_unlocked_001.cpp", + "$TEST_UNITTEST_DIR/libc/io/full/It_stdio_hasmntopt_001.cpp", + "$TEST_UNITTEST_DIR/libc/io/full/It_stdio_mblen_001.cpp", + "$TEST_UNITTEST_DIR/libc/io/full/It_stdio_mbrlen_001.cpp", + "$TEST_UNITTEST_DIR/libc/io/full/It_stdio_putwc_001.cpp", + "$TEST_UNITTEST_DIR/libc/io/full/It_stdio_readv_001.cpp", + "$TEST_UNITTEST_DIR/libc/io/full/It_stdio_rindex_001.cpp", + "$TEST_UNITTEST_DIR/libc/io/full/It_stdio_setlogmask_001.cpp", + "$TEST_UNITTEST_DIR/libc/io/full/It_stdlib_gcvt_001.cpp", + "$TEST_UNITTEST_DIR/libc/io/full/It_stdlib_poll_002.cpp", + "$TEST_UNITTEST_DIR/libc/io/full/It_stdlib_poll_003.cpp", + "$TEST_UNITTEST_DIR/libc/io/full/IO_test_gettext_001.cpp", + "$TEST_UNITTEST_DIR/libc/io/full/IO_test_strncasecmp_l_001.cpp", + "$TEST_UNITTEST_DIR/libc/io/full/IO_test_strncasecmp_l_002.cpp", + "$TEST_UNITTEST_DIR/libc/io/full/IO_test_ppoll_001.cpp", + "$TEST_UNITTEST_DIR/libc/io/full/IO_test_ppoll_002.cpp", + "$TEST_UNITTEST_DIR/libc/io/full/IO_test_ppoll_003.cpp", + "$TEST_UNITTEST_DIR/libc/io/full/IO_test_pselect_001.cpp", + "$TEST_UNITTEST_DIR/libc/io/full/IO_test_pselect_002.cpp", + "$TEST_UNITTEST_DIR/libc/io/full/IO_test_epoll_001.cpp", + "$TEST_UNITTEST_DIR/libc/io/full/IO_test_epoll_002.cpp", +] + +# libc io module +if (LOSCFG_USER_TEST_LIBC_IO == true) { + common_include_dirs += libc_io_include_dirs + sources_entry += libc_io_sources_entry + sources_smoke += libc_io_sources_smoke + sources_full += libc_io_sources_full +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_confstr_001.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_confstr_001.cpp new file mode 100644 index 00000000..b63c3ba3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_confstr_001.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_IO.h" + +static UINT32 testcase(VOID) +{ + char *pathbuf = nullptr; + char *gun_libpthread_version_buf = nullptr; + char *gun_libc_version_buf = nullptr; + size_t n = 0; + + n = confstr(_CS_PATH, NULL, (size_t) 0); + ICUNIT_ASSERT_WITHIN_EQUAL(n, 0, UINT_MAX, n); + pathbuf = (char *)malloc(n); + if (pathbuf == NULL) { + return LOS_NOK; + } + confstr(_CS_PATH, pathbuf, n); + ICUNIT_ASSERT_NOT_EQUAL(pathbuf, NULL, -1); + free(pathbuf); + pathbuf = NULL; + + n = confstr(_CS_GNU_LIBPTHREAD_VERSION, NULL, (size_t) 0); + ICUNIT_ASSERT_WITHIN_EQUAL(n, 0, UINT_MAX, n); + if (n > 0) { + gun_libpthread_version_buf = (char *)malloc(n); + } + if (gun_libpthread_version_buf == NULL) { + return LOS_NOK; + } + confstr(_CS_GNU_LIBPTHREAD_VERSION, gun_libpthread_version_buf, n); + ICUNIT_ASSERT_NOT_EQUAL(gun_libpthread_version_buf, NULL, -1); + free(gun_libpthread_version_buf); + gun_libpthread_version_buf = NULL; + + n = confstr(_CS_GNU_LIBC_VERSION, NULL, (size_t) 0); + ICUNIT_ASSERT_WITHIN_EQUAL(n, 0, UINT_MAX, n); + if (n > 0) { + gun_libc_version_buf = (char *)malloc(n); + } + if (gun_libc_version_buf == NULL) { + return LOS_NOK; + } + confstr(_CS_GNU_LIBC_VERSION, gun_libc_version_buf, n); + ICUNIT_ASSERT_NOT_EQUAL(gun_libc_version_buf, NULL, -1); + free(gun_libc_version_buf); + gun_libc_version_buf = NULL; + + return LOS_OK; +} + +VOID IO_TEST_CONFSTR_001(void) +{ + TEST_ADD_CASE(__FUNCTION__, testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_dcgettext_001.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_dcgettext_001.cpp new file mode 100644 index 00000000..c5ea39da --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_dcgettext_001.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_IO.h" +#include +#include + +const int domain_name_length = 10; +const int buffer_size = 50; + +static UINT32 testcase(VOID) +{ + char *s = ""; + char domain[buffer_size], tmp[domain_name_length]; + srand(time(NULL)); + for (int i = 0, r = 0; i < domain_name_length; i++) { + r = rand() % 36; // 36: 0-9 and a-z + if (r < 10) { // 10: 0-9 + tmp[i] = '0' + r; + } else { + tmp[i] = 'a' + r; + } + } + int ret = sprintf_s(domain, sizeof(domain), "www.%s.com", tmp); + if (ret == 0) { + printf("sprinf_s failed\n"); + return LOS_NOK; + } + + setlocale(LC_ALL, ""); + textdomain("gettext_demo"); + bindtextdomain("gettext_demo", "."); + bind_textdomain_codeset("gettext_demo", "UTF-8"); + + printf(dcgettext(domain, "TestString1\n", LC_MESSAGES)); + + s = dcgettext(domain, "TestString1\n", LC_MESSAGES); + printf("[INFO]%s:%d,%s,s=%s\n", __FILE__, __LINE__, __func__, s); + ICUNIT_ASSERT_STRING_EQUAL(s, "TestString1\n", s); + setlocale(LC_ALL, "C"); + + return LOS_OK; +} + +VOID IO_TEST_DCGETTEXT_001(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_dcgettext_002.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_dcgettext_002.cpp new file mode 100644 index 00000000..0c1174d3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_dcgettext_002.cpp @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_IO.h" +#include +#include + +static UINT32 testcase1(VOID) +{ + char *s = ""; + + setlocale(LC_ALL, ""); + textdomain("gettext_demo"); + bindtextdomain("gettext_demo", "."); + bind_textdomain_codeset("gettext_demo", "UTF-8"); + + errno = 0; + s = dcgettext("www.huawei.com", "TestString1\n", LC_MESSAGES); + TEST_PRINT("[INFO]%s:%d,%s,s=%s\n", __FILE__, __LINE__, __func__, s); + TEST_PRINT("[INFO]%s:%d,%s,errno=%d,errstr=%s\n", __FILE__, __LINE__, __func__, errno, strerror(errno)); + ICUNIT_GOTO_STRING_EQUAL(s, "TestString1\n", -1, OUT); + + return LOS_OK; +OUT: + return LOS_NOK; +} + +static UINT32 testcase2(VOID) +{ + char *s = ""; + + setlocale(LC_ALL, ""); + textdomain("gettext_demo"); + bindtextdomain("gettext_demo", "."); + bind_textdomain_codeset("gettext_demo", "UTF-8"); + + errno = 0; + s = dcgettext(nullptr, "Hello World!\n", LC_MESSAGES); + TEST_PRINT("[INFO]%s:%d,%s,s=%s\n", __FILE__, __LINE__, __func__, s); + TEST_PRINT("[INFO]%s:%d,%s,errno=%d,errstr=%s\n", __FILE__, __LINE__, __func__, errno, strerror(errno)); + ICUNIT_GOTO_STRING_EQUAL(s, "Hello World!\n", -1, OUT); + + return LOS_OK; +OUT: + return LOS_NOK; +} + +static UINT32 testcase3(VOID) +{ + char *s = ""; + char *domain = "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ +12345678901234567890123456789012345678901234567890123456"; + char *string = "Domain is NAME_MAX+1 256 characters long!\n"; + + setlocale(LC_ALL, ""); + textdomain("gettext_demo"); + bindtextdomain("gettext_demo", "."); + bind_textdomain_codeset("gettext_demo", "UTF-8"); + + errno = 0; + s = dcgettext(domain, string, LC_MESSAGES); + TEST_PRINT("[INFO]%s:%d,%s,s=%s\n", __FILE__, __LINE__, __func__, s); + TEST_PRINT("[INFO]%s:%d,%s,errno=%d,errstr=%s\n", __FILE__, __LINE__, __func__, errno, strerror(errno)); + ICUNIT_GOTO_STRING_EQUAL(s, string, -1, OUT); + + return LOS_OK; +OUT: + return LOS_NOK; +} + +static UINT32 testcase4(VOID) +{ + char *s = ""; + char *domain = "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ +123456789012345678901234567890123456789012345678901234567"; + char *string = "Domain is more than NAME_MAX+1(256) 257 characters long!\n"; + + setlocale(LC_ALL, ""); + textdomain("gettext_demo"); + bindtextdomain("gettext_demo", "."); + bind_textdomain_codeset("gettext_demo", "UTF-8"); + + errno = 0; + s = dcgettext(domain, string, LC_MESSAGES); + TEST_PRINT("[INFO]%s:%d,%s,s=%s\n", __FILE__, __LINE__, __func__, s); + TEST_PRINT("[INFO]%s:%d,%s,errno=%d,errstr=%s\n", __FILE__, __LINE__, __func__, errno, strerror(errno)); + ICUNIT_GOTO_STRING_EQUAL(s, string, -1, OUT); + + return LOS_OK; +OUT: + return LOS_NOK; +} +static UINT32 testcase(VOID) +{ + errno = 0; + + testcase1(); + testcase2(); + testcase3(); + testcase4(); + setlocale(LC_ALL, "C"); + + return LOS_OK; +} + +VOID IO_TEST_DCGETTEXT_002(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_dcngettext_001.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_dcngettext_001.cpp new file mode 100644 index 00000000..5d9ee5ef --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_dcngettext_001.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_IO.h" +#include +#include + +static UINT32 testcase(VOID) +{ + char *s = ""; + + setlocale(LC_ALL, ""); + textdomain("gettext_demo"); + bindtextdomain("gettext_demo", "."); + bind_textdomain_codeset("gettext_demo", "UTF-8"); + + printf(dcngettext("www.huawei.com", "TestString1\n", "TestString2\n", 1, LC_MESSAGES)); + printf(dcngettext("www.huawei.com", "TestString1\n", "TestString2\n", 2, LC_MESSAGES)); + + s = dcngettext("www.huawei.com", "TestString1\n", "TestString2\n", 1, LC_MESSAGES); + printf("[INFO]%s:%d,%s,s=%s\n", __FILE__, __LINE__, __func__, s); + ICUNIT_ASSERT_STRING_EQUAL(s, "TestString1\n", s); + + s = dcngettext("www.huawei.com", "TestString1\n", "TestString2\n", 2, LC_MESSAGES); + printf("[INFO]%s:%d,%s,s=%s\n", __FILE__, __LINE__, __func__, s); + ICUNIT_ASSERT_STRING_EQUAL(s, "TestString2\n", s); + + return LOS_OK; +} + +VOID IO_TEST_DCNGETTEXT_001(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_dcngettext_002.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_dcngettext_002.cpp new file mode 100644 index 00000000..75732114 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_dcngettext_002.cpp @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_IO.h" +#include +#include + +static UINT32 testcase1(VOID) +{ + char *s = ""; + + setlocale(LC_ALL, "zh_CN.UTF-8"); + textdomain("gettext_demo"); + bindtextdomain("gettext_demo", "."); + bind_textdomain_codeset("gettext_demo", "UTF-8"); + + errno = 0; + s = dcngettext("", "TestString1:Hello world!\n", "TestString2\n", 1, LC_MESSAGES); + TEST_PRINT("[INFO]%s:%d,%s,s=%s\n", __FILE__, __LINE__, __func__, s); + TEST_PRINT("[INFO]%s:%d,%s,errno=%d,errstr=%s\n", __FILE__, __LINE__, __func__, errno, strerror(errno)); + ICUNIT_ASSERT_STRING_EQUAL(s, "TestString1:Hello world!\n", s); + ICUNIT_GOTO_EQUAL(errno, 0, errno, OUT); + + errno = 0; + s = dcngettext("", "TestString1\n", "TestString2:Hello world!\n", 2, LC_MESSAGES); + TEST_PRINT("[INFO]%s:%d,%s,s=%s\n", __FILE__, __LINE__, __func__, s); + TEST_PRINT("[INFO]%s:%d,%s,errno=%d,errstr=%s\n", __FILE__, __LINE__, __func__, errno, strerror(errno)); + ICUNIT_ASSERT_STRING_EQUAL(s, "TestString2:Hello world!\n", s); + ICUNIT_GOTO_EQUAL(errno, 0, errno, OUT); + + return LOS_OK; +OUT: + return LOS_NOK; +} + +static UINT32 testcase2(VOID) +{ + char *s = ""; + + setlocale(LC_ALL, "zh_CN.UTF-8"); + textdomain("gettext_demo"); + bindtextdomain("gettext_demo", "."); + bind_textdomain_codeset("gettext_demo", "UTF-8"); + + errno = 0; + s = dcngettext("en_US.UTF-8", "TestString1:Hello world!\n", "TestString2:Hello world!\n", 1, LC_MESSAGES); + TEST_PRINT("[INFO]%s:%d,%s,s=%s\n", __FILE__, __LINE__, __func__, s); + TEST_PRINT("[INFO]%s:%d,%s,errno=%d,errstr=%s\n", __FILE__, __LINE__, __func__, errno, strerror(errno)); + ICUNIT_ASSERT_STRING_EQUAL(s, "TestString1:Hello world!\n", s); + ICUNIT_GOTO_EQUAL(errno, 0, errno, OUT); + + errno = 0; + s = dcngettext("en_US.UTF-8", "TestString1\n", "TestString2:Hello world!\n", 2, LC_MESSAGES); + TEST_PRINT("[INFO]%s:%d,%s,s=%s\n", __FILE__, __LINE__, __func__, s); + TEST_PRINT("[INFO]%s:%d,%s,errno=%d,errstr=%s\n", __FILE__, __LINE__, __func__, errno, strerror(errno)); + ICUNIT_ASSERT_STRING_EQUAL(s, "TestString2:Hello world!\n", s); + ICUNIT_GOTO_EQUAL(errno, 0, errno, OUT); + + return LOS_OK; +OUT: + return LOS_NOK; +} + +static UINT32 testcase(VOID) +{ + testcase1(); + testcase2(); + setlocale(LC_ALL, "C"); + + return LOS_OK; +} + +VOID IO_TEST_DCNGETTEXT_002(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_dngettext_001.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_dngettext_001.cpp new file mode 100644 index 00000000..5b890485 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_dngettext_001.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_IO.h" +#include +#include + +static UINT32 testcase(VOID) +{ + char *s = ""; + + setlocale(LC_ALL, ""); + textdomain("gettext_demo"); + bindtextdomain("gettext_demo", "."); + bind_textdomain_codeset("gettext_demo", "UTF-8"); + + printf(dngettext("www.huawei.com", "TestString1\n", "TestString2\n", 1)); + printf(dngettext("www.huawei.com", "TestString1\n", "TestString2\n", 2)); + + s = dngettext("www.huawei.com", "TestString1\n", "TestString2\n", 1); + printf("[INFO]%s:%d,%s,s=%s\n", __FILE__, __LINE__, __func__, s); + ICUNIT_ASSERT_STRING_EQUAL(s, "TestString1\n", s); + + s = dngettext("www.huawei.com", "TestString1\n", "TestString2\n", 2); + printf("[INFO]%s:%d,%s,s=%s\n", __FILE__, __LINE__, __func__, s); + ICUNIT_ASSERT_STRING_EQUAL(s, "TestString2\n", s); + setlocale(LC_ALL, "C"); + + return LOS_OK; +} + +VOID IO_TEST_DNGETTEXT_001(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_dngettext_002.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_dngettext_002.cpp new file mode 100644 index 00000000..bcb9bf0d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_dngettext_002.cpp @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_IO.h" +#include +#include + +static UINT32 testcase1(VOID) +{ + char *s = ""; + + setlocale(LC_ALL, "zh_CN.UTF-8"); + textdomain("gettext_demo"); + bindtextdomain("gettext_demo", "."); + bind_textdomain_codeset("gettext_demo", "UTF-8"); + + errno = 0; + s = dngettext("", "TestString1:Hello world!\n", "TestString2\n", 1); + TEST_PRINT("[INFO]%s:%d,%s,s=%s\n", __FILE__, __LINE__, __func__, s); + TEST_PRINT("[INFO]%s:%d,%s,errno=%d,errstr=%s\n", __FILE__, __LINE__, __func__, errno, strerror(errno)); + ICUNIT_ASSERT_STRING_EQUAL(s, "TestString1:Hello world!\n", s); + ICUNIT_GOTO_EQUAL(errno, 0, errno, OUT); + + errno = 0; + s = dngettext("", "TestString1\n", "TestString2:Hello world!\n", 2); + TEST_PRINT("[INFO]%s:%d,%s,s=%s\n", __FILE__, __LINE__, __func__, s); + TEST_PRINT("[INFO]%s:%d,%s,errno=%d,errstr=%s\n", __FILE__, __LINE__, __func__, errno, strerror(errno)); + ICUNIT_ASSERT_STRING_EQUAL(s, "TestString2:Hello world!\n", s); + ICUNIT_GOTO_EQUAL(errno, 0, errno, OUT); + + return LOS_OK; +OUT: + return LOS_NOK; +} + +static UINT32 testcase2(VOID) +{ + char *s = ""; + + setlocale(LC_ALL, "zh_CN.UTF-8"); + textdomain("gettext_demo"); + bindtextdomain("gettext_demo", "."); + bind_textdomain_codeset("gettext_demo", "UTF-8"); + + errno = 0; + s = dngettext("en_US.UTF-8", "TestString1:Hello world!\n", "TestString2\n", 1); + TEST_PRINT("[INFO]%s:%d,%s,s=%s\n", __FILE__, __LINE__, __func__, s); + TEST_PRINT("[INFO]%s:%d,%s,errno=%d,errstr=%s\n", __FILE__, __LINE__, __func__, errno, strerror(errno)); + ICUNIT_ASSERT_STRING_EQUAL(s, "TestString1:Hello world!\n", s); + ICUNIT_GOTO_EQUAL(errno, 0, errno, OUT); + + errno = 0; + s = dngettext("en_US.UTF-8", "TestString1\n", "TestString2:Hello world!\n", 2); + TEST_PRINT("[INFO]%s:%d,%s,s=%s\n", __FILE__, __LINE__, __func__, s); + TEST_PRINT("[INFO]%s:%d,%s,errno=%d,errstr=%s\n", __FILE__, __LINE__, __func__, errno, strerror(errno)); + ICUNIT_ASSERT_STRING_EQUAL(s, "TestString2:Hello world!\n", s); + ICUNIT_GOTO_EQUAL(errno, 0, errno, OUT); + + return LOS_OK; +OUT: + return LOS_NOK; +} + +static UINT32 testcase3(VOID) +{ + char *s = ""; + + setlocale(LC_ALL, "zh_CN.UTF-8"); + textdomain("gettext_demo"); + bindtextdomain("gettext_demo", "."); + bind_textdomain_codeset("gettext_demo", "UTF-8"); + + errno = 0; + s = dngettext("en_US.UTF-8", "TestString1:Hello world!\n", "TestString2!\n", 5); + TEST_PRINT("[INFO]%s:%d,%s,s=%s\n", __FILE__, __LINE__, __func__, s); + TEST_PRINT("[INFO]%s:%d,%s,errno=%d,errstr=%s\n", __FILE__, __LINE__, __func__, errno, strerror(errno)); + ICUNIT_GOTO_STRING_EQUAL(s, "TestString2!\n", -1, OUT); + ICUNIT_GOTO_EQUAL(errno, 0, errno, OUT); + + errno = 0; + s = dngettext("en_US.UTF-8", "TestString1\n", "TestString2:Hello world!\n", 3); + TEST_PRINT("[INFO]%s:%d,%s,s=%s\n", __FILE__, __LINE__, __func__, s); + TEST_PRINT("[INFO]%s:%d,%s,errno=%d,errstr=%s\n", __FILE__, __LINE__, __func__, errno, strerror(errno)); + ICUNIT_GOTO_STRING_EQUAL(s, "TestString2:Hello world!\n", -1, OUT); + ICUNIT_GOTO_EQUAL(errno, 0, errno, OUT); + + return LOS_OK; +OUT: + return LOS_NOK; +} + +static UINT32 testcase(VOID) +{ + testcase1(); /* test the domain is NULL */ + testcase2(); /* test the domain is different with the setlocale */ + testcase3(); /* if n != 1,then dngettext will choose msgid2's string */ + setlocale(LC_ALL, "C"); + + return LOS_OK; +} + +VOID IO_TEST_DNGETTEXT_002(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_duplocale_001.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_duplocale_001.cpp new file mode 100644 index 00000000..442cf09c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_duplocale_001.cpp @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include "It_test_IO.h" + +/* Zh_cn.utf-8 File content */ +int fileWords[] = { + 0x950412de, 0x0, 0x3, 0x1c, 0x34, 0x5, + 0x4c, 0x0, 0x60, 0x3, 0x61, 0x3, + 0x65, 0x14f, 0x69, 0x9, 0x1b9, 0x6, + 0x1c3, 0x1, 0x3, 0x0, 0x0, 0x2, + 0x69724600, 0x6e614a00, 0x6f725000, 0x7463656a, 0x2d64492d, 0x73726556, + 0x3a6e6f69, 0x6d695620, 0x6d695328, 0x66696c70, 0x20646569, 0x6e696843, + 0x29657365, 0x7065520a, 0x2d74726f, 0x6967734d, 0x75422d64, 0x542d7367, + 0xa203a6f, 0x522d4f50, 0x73697665, 0x2d6e6f69, 0x65746144, 0x3032203a, + 0x302d3630, 0x31322d34, 0x3a343120, 0x302b3030, 0xa303038, 0x7473614c, + 0x6172542d, 0x616c736e, 0x3a726f74, 0x68755920, 0x20676e65, 0xa656958, + 0x676e614c, 0x65676175, 0x6165542d, 0x53203a6d, 0x6c706d69, 0x65696669, + 0x68432064, 0x73656e69, 0x494d0a65, 0x562d454d, 0x69737265, 0x203a6e6f, + 0xa302e31, 0x746e6f43, 0x2d746e65, 0x65707954, 0x6574203a, 0x702f7478, + 0x6e69616c, 0x6863203b, 0x65737261, 0x54553d74, 0xa382d46, 0x746e6f43, + 0x2d746e65, 0x6e617254, 0x72656673, 0x636e452d, 0x6e69646f, 0x38203a67, + 0xa746962, 0x72756c50, 0x462d6c61, 0x736d726f, 0x706e203a, 0x6172756c, + 0x313d736c, 0x6c70203b, 0x6c617275, 0xa3b303d, 0x676e614c, 0x65676175, + 0x687a203a, 0xa4e435f, 0x65472d58, 0x6172656e, 0x3a726f74, 0x656f5020, + 0x20746964, 0xa302e33, 0x9f98e600, 0xe49f9ce6, 0xe40094ba, 0x9ce680b8, + 0x88 +}; + +UINT32 SonFunc(VOID) +{ + int ret; + struct tm timer_; + struct tm *timer = &timer_; + char buffer[80]; /* 80, The number of characters returned by strftime */ + char *retptr = nullptr; + + /* set timer as 'Thu Jan 1 23:48:56 1970'" */ + timer->tm_sec = 32; /* 32, example */ + timer->tm_min = 3; /* 3, example */ + timer->tm_hour = 1; + timer->tm_mday = 2; + timer->tm_mon = 0; + timer->tm_year = 70; /* 70, example */ + timer->tm_wday = 5; /* 5, example */ + timer->tm_yday = 1; + timer->tm_isdst = 0; + timer->__tm_gmtoff = 0; + timer->__tm_zone = nullptr; + + ret = setenv("MUSL_LOCPATH", "/storage", 1); + ICUNIT_ASSERT_EQUAL(ret, 0, -1); + retptr = getenv("MUSL_LOCPATH"); + ICUNIT_ASSERT_NOT_EQUAL(retptr, NULL, -1); + ICUNIT_ASSERT_STRING_EQUAL(retptr, "/storage", -1); + + retptr = setlocale(LC_TIME, "en_US.UTF-8"); + ICUNIT_ASSERT_NOT_EQUAL(retptr, NULL, -1); + ICUNIT_ASSERT_STRING_EQUAL(retptr, "en_US.UTF-8", -1); + + ret = strftime(buffer, 80, "%c", timer); /* 80, The maximum number of characters in the string str */ + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, -1); + ICUNIT_ASSERT_STRING_EQUAL(buffer, "Fri Jan 2 01:03:32 1970", -1); + + retptr = setlocale(LC_TIME, "zh_CN.UTF-8"); + ICUNIT_ASSERT_NOT_EQUAL(retptr, NULL, -1); + ICUNIT_ASSERT_STRING_EQUAL(retptr, "zh_CN.UTF-8", -1); + + ret = strftime(buffer, 80, "%c", timer); /* 80, The maximum number of characters in the string str */ + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, -1); + ICUNIT_ASSERT_STRING_EQUAL(buffer, "星期五 一月 2 01:03:32 1970", -1); + + retptr = setlocale(LC_TIME, ""); + ICUNIT_ASSERT_NOT_EQUAL(retptr, NULL, -1); + ICUNIT_ASSERT_STRING_EQUAL(retptr, "C", -1); + + ret = strftime(buffer, 80, "%c", timer); /* 80, The maximum number of characters in the string str */ + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, -1); + ICUNIT_ASSERT_STRING_EQUAL(buffer, "Fri Jan 2 01:03:32 1970", -1); + + return 0; +} + +static UINT32 testcase(VOID) +{ + int ret, status; + locale_t oldloc = LC_GLOBAL_LOCALE; + locale_t newloc = nullptr; + + char *pathList[] = {"/storage/zh_CN.UTF-8"}; + char *streamList[] = {reinterpret_cast(fileWords)}; + int streamLen[] = {sizeof(fileWords) - 2}; + + newloc = duplocale(oldloc); + ICUNIT_ASSERT_NOT_EQUAL(newloc, nullptr, -1); + free(newloc); + + ret = PrepareFileEnv(pathList, streamList, streamLen, 1); + if (ret != 0) { + printf("error: need some env file, but prepare is not ok"); + (VOID)RecoveryFileEnv(pathList, 1); + return -1; + } + + pid_t pid = fork(); + if (pid == 0) { + ret = SonFunc(); + exit(ret); + } + + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + (VOID)RecoveryFileEnv(pathList, 1); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(status, 0, status); + setlocale(LC_ALL, "C"); + + return LOS_OK; +} + +VOID IO_TEST_DUPLOCALE_001(void) +{ + TEST_ADD_CASE(__FUNCTION__, testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_epoll_001.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_epoll_001.cpp new file mode 100644 index 00000000..9e5f45a5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_epoll_001.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_test_IO.h" +#include +#include "signal.h" +#include "pthread.h" +#include +#include +#include + +static UINT32 testcase(VOID) +{ + fd_set rfds; + int retval; + pid_t pid; + int pipeFd[2]; /* 2, pipe id num */ + char buffer[40]; /* 40, buffer size */ + int i = 0; + int status; + + int epFd; + sigset_t mask; + struct epoll_event ev; + struct epoll_event evWait[2]; /* 2, evs num */ + UINT32 ret; + + retval = pipe(pipeFd); + ICUNIT_GOTO_EQUAL(retval, 0, retval, OUT4); + + /* Watch fd to see when it has input. */ + FD_ZERO(&rfds); + FD_SET(pipeFd[0], &rfds); + + /* Wait up to three seconds. */ + epFd = epoll_create1(100); /* 100, cretae input, */ + ICUNIT_GOTO_NOT_EQUAL(epFd, -1, epFd, OUT2); + + ev.events = EPOLLIN | EPOLLOUT | EPOLLRDNORM | EPOLLWRNORM; + retval = epoll_ctl(epFd, EPOLL_CTL_ADD, pipeFd[0], &ev); + ICUNIT_GOTO_NOT_EQUAL(retval, -1, retval, OUT1); + + pid = fork(); + if (pid == 0) { + close(pipeFd[1]); + + ret = memset_s(evWait, sizeof(struct epoll_event) * 2, 0, sizeof(struct epoll_event) * 2); /* 2, evs num */ + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + retval = epoll_wait(epFd, evWait, 2, 3000); /* 2, num of wait fd. 3000, wait time */ + close(pipeFd[0]); + + if (retval) { + exit(LOS_OK); + } else { + exit(LOS_NOK); + } + } else { + sleep(1); + close(pipeFd[0]); + retval = write(pipeFd[1], "0123456789012345678901234567890123456789", 40); /* write 40 bytes to stdin(fd 0) */ + ICUNIT_GOTO_EQUAL(retval, 40, retval, OUT3); + close(pipeFd[1]); + + wait(&status); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(status, LOS_OK, status); + } + + return LOS_OK; +OUT1: + close(epFd); + close(pipeFd[0]); + close(pipeFd[1]); + return LOS_NOK; +OUT2: + close(pipeFd[0]); + close(pipeFd[1]); + return LOS_NOK; +OUT3: + close(epFd); + close(pipeFd[1]); + return LOS_NOK; +OUT4: + return LOS_NOK; +} + + +VOID IO_TEST_EPOLL_001(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_epoll_002.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_epoll_002.cpp new file mode 100644 index 00000000..1d46e936 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_epoll_002.cpp @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_test_IO.h" +#include +#include "signal.h" +#include "pthread.h" +#include +#include +#include + +static void SigPrint(int sig) +{ + return; +} + +static UINT32 testcase(VOID) +{ + fd_set rfds; + struct timespec tv; + int retval; + pid_t pid; + int pipeFd[2]; /* 2, pipe id num */ + char buffer[40]; /* 40, buffer size */ + int i = 0; + int status; + + int epFd = 0; + sigset_t mask; + void (*retSig)(int); + struct epoll_event ev; + struct epoll_event evWait[2]; + + retSig = signal(SIGALRM, SigPrint); + ICUNIT_ASSERT_NOT_EQUAL(retSig, NULL, retSig); + + retSig = signal(SIGUSR1, SigPrint); + ICUNIT_ASSERT_NOT_EQUAL(retSig, NULL, retSig); + + retval = sigemptyset(&mask); + ICUNIT_ASSERT_EQUAL(retval, 0, retval); + + retval = sigaddset(&mask, SIGALRM); + ICUNIT_ASSERT_EQUAL(retval, 0, retval); + + retval = sigaddset(&mask, SIGUSR1); + ICUNIT_ASSERT_EQUAL(retval, 0, retval); + + retval = pipe(pipeFd); + ICUNIT_GOTO_EQUAL(retval, 0, retval, OUT3); + + /* Watch fd to see when it has input. */ + FD_ZERO(&rfds); + FD_SET(pipeFd[0], &rfds); + + /* Wait up to three seconds. */ + tv.tv_sec = 3; /* 3, wait timer, second */ + tv.tv_nsec = 5; /* 5, wait timer, nano second */ + + epFd = epoll_create1(100); /* 100, cretae input, */ + ICUNIT_GOTO_NOT_EQUAL(epFd, -1, epFd, OUT2); + + ev.events = EPOLLRDNORM; + retval = epoll_ctl(epFd, EPOLL_CTL_ADD, pipeFd[0], &ev); + + ICUNIT_GOTO_NOT_EQUAL(retval, -1, retval, OUT1); + + pid = fork(); + if (pid == 0) { + close(pipeFd[1]); + + (void)memset_s(evWait, sizeof(struct epoll_event) * 2, 0, sizeof(struct epoll_event) * 2); /* 2, evs num */ + evWait[0].data.fd = pipeFd[0]; + + retval = epoll_pwait(epFd, evWait, 2, 3000, &mask); /* 2, num of wait fd. 3000, wait time */ + close(pipeFd[0]); + + if (retval) { + exit(LOS_OK); + } else { + exit(LOS_NOK); + } + } else { + sleep(1); + close(pipeFd[0]); + + retval = kill(pid, SIGALRM); + ICUNIT_ASSERT_EQUAL(retval, 0, retval); + + retval = kill(pid, SIGUSR1); + ICUNIT_ASSERT_EQUAL(retval, 0, retval); + close(pipeFd[1]); + + wait(&status); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(status, LOS_OK, status); + } + + return LOS_OK; +OUT1: + close(epFd); +OUT2: + close(pipeFd[0]); + close(pipeFd[1]); +OUT3: + return LOS_NOK; +} + + +VOID IO_TEST_EPOLL_002(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_gettext_001.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_gettext_001.cpp new file mode 100644 index 00000000..23d6960e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_gettext_001.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_IO.h" +#include +#include + +static UINT32 testcase1(VOID) +{ + char *s = nullptr; + char *tmp = nullptr; + + /* set the locale. */ + setlocale(LC_ALL, "zh_CN.UTF-8"); + setenv("MUSL_LOCPATH", "/storage", 1); + TEST_PRINT("[INFO]%s:%d,%s,getenv MUSL_LOCPATH=%s\n", __FILE__, __LINE__, __func__, getenv("MUSL_LOCPATH")); + tmp = setlocale(LC_TIME, "zh_CN.UTF-8"); + TEST_PRINT("[INFO]%s:%d,%s,Locale is: %s\n", __FILE__, __LINE__, __func__, tmp); + ICUNIT_GOTO_STRING_EQUAL(tmp, "zh_CN.UTF-8", -1, OUT); + + /* choose a domain for your program. */ + tmp = textdomain("messages"); + /* bind a directory,use PWD here. */ + bindtextdomain("messages", "."); + /* set the output codeset.It is not needed usually */ + bind_textdomain_codeset("messages", "UTF-8"); + + /* test gettext. */ + s = gettext("Monday/n\n"); + + ICUNIT_ASSERT_STRING_EQUAL(s, "Monday/n\n", s); + setlocale(LC_ALL, "C"); + + return LOS_OK; +OUT: + return LOS_NOK; +} + +static UINT32 testcase(VOID) +{ + testcase1(); + + return LOS_OK; +} + +VOID IO_TEST_GETTEXT_001(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_locale_001.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_locale_001.cpp new file mode 100644 index 00000000..a6d5b825 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_locale_001.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_IO.h" +#include +#include + +static UINT32 testcase(VOID) +{ + time_t currtime; + struct tm *timer = {nullptr}; + char buffer[80]; + + time(&currtime); + timer = localtime(&currtime); + + setenv("MUSL_LOCPATH", "/storage", 1); + printf("getenv MUSL_LOCPATH=%s\n", getenv("MUSL_LOCPATH")); + + printf("Locale is: %s\n", setlocale(LC_TIME, "en_US.UTF-8")); + strftime(buffer, 80, "%c", timer); + printf("Date is: %s\n", buffer); + ICUNIT_ASSERT_NOT_EQUAL(buffer, NULL, -1); + + printf("Locale is: %s\n", setlocale(LC_TIME, "zh_CN.UTF-8")); + strftime(buffer, 80, "%c", timer); + printf("Date is: %s\n", buffer); + ICUNIT_ASSERT_NOT_EQUAL(buffer, NULL, -1); + + printf("Locale is: %s\n", setlocale(LC_TIME, "")); + strftime(buffer, 80, "%c", timer); + printf("Date is: %s\n", buffer); + ICUNIT_ASSERT_NOT_EQUAL(buffer, NULL, -1); + setlocale(LC_ALL, "C"); + + return LOS_OK; +} + +VOID IO_TEST_LOCALE_001(void) +{ + TEST_ADD_CASE(__FUNCTION__, testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_locale_002.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_locale_002.cpp new file mode 100644 index 00000000..a7e1fd6b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_locale_002.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_IO.h" +#include +#include + +static UINT32 testcase(VOID) +{ + time_t currtime; + struct tm *timer = {nullptr}; + char buffer[80]; + + time(&currtime); + timer = localtime(&currtime); + + setenv("MUSL_LOCPATH", "/storage", 1); + printf("getenv MUSL_LOCPATH=%s\n", getenv("MUSL_LOCPATH")); + + printf("Locale is: %s\n", setlocale(LC_TIME, "en_US.UTF-8")); + (void)strftime(buffer, sizeof(buffer), "%c", timer); + printf("Date is: %s\n", buffer); + ICUNIT_ASSERT_NOT_EQUAL(buffer, NULL, -1); + + printf("Locale is: %s\n", setlocale(LC_TIME, "zh_CN.UTF-8")); + (void)strftime(buffer, sizeof(buffer), "%c", timer); + printf("Date is: %s\n", buffer); + ICUNIT_ASSERT_NOT_EQUAL(buffer, NULL, -1); + + printf("Locale is: %s\n", setlocale(LC_TIME, "")); + (void)strftime(buffer, sizeof(buffer), "%c", timer); + printf("Date is: %s\n", buffer); + ICUNIT_ASSERT_NOT_EQUAL(buffer, NULL, -1); + setlocale(LC_ALL, "C"); + + return LOS_OK; +} + +VOID IO_TEST_LOCALE_002(void) +{ + TEST_ADD_CASE(__FUNCTION__, testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_ngettext_001.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_ngettext_001.cpp new file mode 100644 index 00000000..446a7cf7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_ngettext_001.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_IO.h" +#include +#include + +static UINT32 testcase(VOID) +{ + char *s = ""; + + setlocale(LC_ALL, ""); + textdomain("gettext_demo"); + bindtextdomain("gettext_demo", "."); + bind_textdomain_codeset("gettext_demo", "UTF-8"); + + printf(ngettext("Delete the selected file?\n", "Delete the selected files?\n", 1)); + printf(ngettext("Delete the selected file?\n", "Delete the selected files?\n", 2)); + + s = ngettext("0123456789", "0123456789", 2); + ICUNIT_ASSERT_STRING_EQUAL(s, "0123456789", s); + setlocale(LC_ALL, "C"); + + return LOS_OK; +} + +VOID IO_TEST_NGETTEXT_001(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_nl_langinfo_001.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_nl_langinfo_001.cpp new file mode 100644 index 00000000..f843a728 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_nl_langinfo_001.cpp @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_IO.h" +#include +#include + +static UINT32 testcase(VOID) +{ + /* set the locale info */ + setenv("MUSL_LOCPATH", "/storage", 1); + printf("getenv MUSL_LOCPATH=%s\n", getenv("MUSL_LOCPATH")); + printf("Locale is: %s\n", setlocale(LC_TIME, "zh_CN.UTF-8")); + + setlocale(LC_CTYPE, ""); + setlocale(LC_NUMERIC, ""); + + /* echo the nl_langinfo */ + printf("%s\n", nl_langinfo(CODESET)); + printf("%s\n", nl_langinfo(RADIXCHAR)); + printf("%s\n", nl_langinfo(D_T_FMT)); + printf("%s\n", nl_langinfo(D_FMT)); + printf("%s\n", nl_langinfo(T_FMT)); + printf("%s\n", nl_langinfo(DAY_1)); + printf("%s\n", nl_langinfo(DAY_7)); + printf("%s\n", nl_langinfo(ABDAY_1)); + printf("%s\n", nl_langinfo(ABDAY_7)); + printf("%s\n", nl_langinfo(MON_1)); + printf("%s\n", nl_langinfo(MON_12)); + printf("%s\n", nl_langinfo(ABMON_1)); + printf("%s\n", nl_langinfo(ABMON_12)); + printf("%s\n", nl_langinfo(THOUSEP)); + printf("%s\n", nl_langinfo(YESEXPR)); + printf("%s\n", nl_langinfo(NOEXPR)); + printf("%s\n", nl_langinfo(CRNCYSTR)); + + /* set the locale info */ + setenv("MUSL_LOCPATH", "/storage", 1); + printf("getenv MUSL_LOCPATH=%s\n", getenv("MUSL_LOCPATH")); + printf("Locale is: %s\n", setlocale(LC_TIME, "en_US.UTF-8")); + + setlocale(LC_CTYPE, ""); + setlocale(LC_NUMERIC, ""); + + /* echo the nl_langinfo */ + printf("%s\n", nl_langinfo(CODESET)); + printf("%s\n", nl_langinfo(RADIXCHAR)); + printf("%s\n", nl_langinfo(D_T_FMT)); + printf("%s\n", nl_langinfo(D_FMT)); + printf("%s\n", nl_langinfo(T_FMT)); + printf("%s\n", nl_langinfo(DAY_1)); + printf("%s\n", nl_langinfo(DAY_7)); + printf("%s\n", nl_langinfo(ABDAY_1)); + printf("%s\n", nl_langinfo(ABDAY_7)); + printf("%s\n", nl_langinfo(MON_1)); + printf("%s\n", nl_langinfo(MON_12)); + printf("%s\n", nl_langinfo(ABMON_1)); + printf("%s\n", nl_langinfo(ABMON_12)); + printf("%s\n", nl_langinfo(THOUSEP)); + printf("%s\n", nl_langinfo(YESEXPR)); + printf("%s\n", nl_langinfo(NOEXPR)); + printf("%s\n", nl_langinfo(CRNCYSTR)); + + char *string = nl_langinfo(CRNCYSTR); + ICUNIT_ASSERT_NOT_EQUAL(string, NULL, string); + setlocale(LC_ALL, "C"); + + return LOS_OK; +} + +VOID IO_TEST_NL_LANGINFO_001(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_nl_langinfo_l_001.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_nl_langinfo_l_001.cpp new file mode 100644 index 00000000..f954de3c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_nl_langinfo_l_001.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_IO.h" +#include +#include +static UINT32 testcase(VOID) { + /* set the locale info */ + setenv("MUSL_LOCPATH", "/storage", 1); + printf("getenv MUSL_LOCPATH=%s\n", getenv("MUSL_LOCPATH")); + printf("Locale is: %s\n", setlocale(LC_TIME, "en_US.UTF-8")); + + setlocale(LC_CTYPE, ""); + setlocale(LC_NUMERIC, ""); + + /* echo the nl_langinfo_l */ + printf("%s\n", nl_langinfo_l(CODESET, reinterpret_cast(const_cast("en_US.UTF-8")))); + printf("%s\n", nl_langinfo_l(RADIXCHAR, reinterpret_cast(const_cast("en_US.UTF-8")))); + + /* set the locale info */ + setenv("MUSL_LOCPATH", "/storage", 1); + printf("getenv MUSL_LOCPATH=%s\n", getenv("MUSL_LOCPATH")); + printf("Locale is: %s\n", setlocale(LC_TIME, "zh_CN.UTF-8")); + + setlocale(LC_CTYPE, ""); + setlocale(LC_NUMERIC, ""); + + /* echo the nl_langinfo */ + printf("%s\n", nl_langinfo_l(CODESET, reinterpret_cast(const_cast("zh_CN.UTF-8")))); + printf("%s\n", nl_langinfo_l(RADIXCHAR, reinterpret_cast(const_cast("zh_CN.UTF-8")))); + + char *string = nl_langinfo_l(CRNCYSTR, reinterpret_cast(const_cast("zh_CN.UTF-8"))); + ICUNIT_ASSERT_NOT_EQUAL(string, NULL, string); + setlocale(LC_ALL, "C"); + + return LOS_OK; +} + +VOID IO_TEST_NL_LANGINFO_l_001(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_ppoll_001.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_ppoll_001.cpp new file mode 100644 index 00000000..ff32fc1f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_ppoll_001.cpp @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_test_IO.h" +#include "pthread.h" + +const int BUF_SIZE = 128; +const int DELAY_TIME = 200; + +static INT32 pipeFdPpoll[2]; +static INT32 g_step = 1; +static CHAR strBuf[] = "hello world."; +static struct pollfd pfd; + +static void *pthread_01(void *arg) +{ + INT32 retVal; + CHAR buf[BUF_SIZE]; + + /* 执行ppoll监视文件描述符 */ + while (g_step < 3) { /* 3, 3rd step */ + usleep(DELAY_TIME); + } + g_step++; + retVal = ppoll(&pfd, 1, NULL, NULL); + ICUNIT_ASSERT_NOT_EQUAL_NULL(retVal, -1, retVal); + + while (g_step < 5) { /* 5, 5th step */ + usleep(DELAY_TIME); + } + g_step++; + + /* 判断revents */ + if (pfd.revents & POLLIN) { + (void)memset_s(buf, sizeof(buf), 0, sizeof(buf)); + retVal = read(pfd.fd, buf, BUF_SIZE); + ICUNIT_ASSERT_NOT_EQUAL_NULL(retVal, -1, retVal); + + retVal = strcmp(strBuf, buf); + ICUNIT_ASSERT_EQUAL_NULL(retVal, 0, retVal); + } + + while (g_step < 6) { /* 6, 6th step */ + usleep(DELAY_TIME); + } + pthread_exit(NULL); +} + +STATIC UINT32 testcase(VOID) +{ + INT32 retVal; + pthread_t tid; + + /* 建立管道 */ + while (g_step < 1) { /* 1, 1st step */ + usleep(DELAY_TIME); + } + retVal = pipe(pipeFdPpoll); + ICUNIT_ASSERT_NOT_EQUAL(retVal, -1, retVal); + g_step++; + + /* 设置pfd */ + pfd.fd = pipeFdPpoll[0]; + pfd.events = POLLIN; + + /* 开辟线程执行 ppoll */ + while (g_step < 2) { /* 2, 2nd step */ + usleep(DELAY_TIME); + } + retVal = pthread_create(&tid, NULL, pthread_01, NULL); + ICUNIT_ASSERT_EQUAL(retVal, 0, retVal); + g_step++; + + /* 向管道写入数据 */ + while (g_step < 4) { /* 4, 4th step */ + usleep(DELAY_TIME); + } + sleep(1); + + retVal = write(pipeFdPpoll[1], "hello world.", sizeof(strBuf)); + ICUNIT_ASSERT_NOT_EQUAL(retVal, -1, retVal); + g_step++; + + pthread_join(tid, NULL); + + return LOS_OK; +} + +VOID IO_TEST_PPOLL_001(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_ppoll_002.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_ppoll_002.cpp new file mode 100644 index 00000000..a465d1fb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_ppoll_002.cpp @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_test_IO.h" +#include "signal.h" +#include "pthread.h" + +const int BUF_SIZE = 128; +const int DELAY_TIME = 200; + +static int pipeFdPpoll[2]; +static int g_step = 1; +static char strBuf[] = "hello world."; +static struct pollfd pfd; + +static void *pthread_01(void *arg) +{ + int retVal; + char buf[BUF_SIZE]; + const struct timespec timeout = {10000, 0}; + + /* 执行ppoll监视文件描述符 */ + while (g_step < 4) { /* 4, 4th step */ + usleep(DELAY_TIME); + } + g_step++; + retVal = ppoll(&pfd, 1, &timeout, NULL); + ICUNIT_ASSERT_NOT_EQUAL_NULL(retVal, -1, retVal); + + /* 判断revents */ + if (pfd.revents & POLLIN) { + (void)memset_s(buf, sizeof(buf), 0, sizeof(buf)); + retVal = read(pfd.fd, buf, BUF_SIZE); + ICUNIT_ASSERT_NOT_EQUAL_NULL(retVal, -1, retVal); + retVal = strcmp(strBuf, buf); + ICUNIT_ASSERT_EQUAL_NULL(retVal, 0, retVal); + } + + while (g_step < 5) { /* 5, 5th step */ + usleep(DELAY_TIME); + } + pthread_exit(NULL); +} + +static UINT32 testcase(VOID) +{ + int retVal; + pthread_t tid; + + /* 建立管道 */ + while (g_step < 1) { + usleep(DELAY_TIME); + } + retVal = pipe(pipeFdPpoll); + ICUNIT_ASSERT_NOT_EQUAL(retVal, -1, retVal); + g_step++; + + /* 设置pfd */ + pfd.fd = pipeFdPpoll[0]; + pfd.events = POLLIN; + + /* 向管道写入数据 */ + while (g_step < 2) { /* 2, 2nd step */ + usleep(DELAY_TIME); + } + sleep(1); + + retVal = write(pipeFdPpoll[1], "hello world.", sizeof(strBuf)); + ICUNIT_ASSERT_NOT_EQUAL(retVal, -1, retVal); + g_step++; + + /* 开辟线程执行 ppoll */ + while (g_step < 3) { /* 3, 3rd step */ + usleep(DELAY_TIME); + } + retVal = pthread_create(&tid, NULL, pthread_01, NULL); + ICUNIT_ASSERT_EQUAL(retVal, 0, retVal); + g_step++; + + pthread_join(tid, NULL); + + return LOS_OK; +} + +VOID IO_TEST_PPOLL_002(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_ppoll_003.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_ppoll_003.cpp new file mode 100644 index 00000000..f6eae1d8 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_ppoll_003.cpp @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_test_IO.h" +#include "pthread.h" +#include "signal.h" + +const int BUF_SIZE = 128; +const int DELAY_TIME = 200; + +static INT32 pipeFdPpoll[2]; +static INT32 g_step = 1; +static CHAR strBuf[] = "hello world."; +static struct pollfd pfd; +static sigset_t sigMask; +static UINT32 count = 0; + +static void signalHandle(INT32 sigNum) +{ + g_step++; + return; +} + +static void *pthread_01(void *arg) +{ + INT32 retVal; + CHAR buf[BUF_SIZE]; + + (void)signal(SIGUSR1, signalHandle); + + while (1) { + /* 执行ppoll监视文件描述符 */ + while (g_step < 2) { /* 2, 2nd step */ + usleep(DELAY_TIME); + } + g_step++; + retVal = ppoll(&pfd, 1, NULL, &sigMask); + + ICUNIT_ASSERT_NOT_EQUAL_NULL(retVal, -1, retVal); + + /* 判断revents */ + if (pfd.revents & POLLIN) { + (void)memset_s(buf, sizeof(buf), 0, sizeof(buf)); + retVal = read(pfd.fd, buf, BUF_SIZE); + ICUNIT_ASSERT_NOT_EQUAL_NULL(retVal, -1, retVal); + + retVal = strcmp(strBuf, buf); + ICUNIT_ASSERT_EQUAL_NULL(retVal, 0, retVal); + + count++; + } else { + ICUNIT_ASSERT_NOT_EQUAL_NULL(pfd.revents & POLLIN, 0, pfd.revents & POLLIN); + } + g_step++; + + if (g_step >= 7) { /* 7, 7th step */ + ICUNIT_ASSERT_EQUAL_NULL(count, 2, count); /* 2, 2nd step */ + pthread_exit(NULL); + } + } + + return LOS_OK; +} + +static UINT32 testcase(VOID) +{ + INT32 retVal; + pthread_t tid; + + /* 建立管道 */ + while (g_step < 1) { + usleep(DELAY_TIME); + } + retVal = pipe(pipeFdPpoll); + ICUNIT_ASSERT_NOT_EQUAL(retVal, -1, retVal); + + /* 设置pfd sigmask */ + pfd.fd = pipeFdPpoll[0]; + pfd.events = POLLIN; + pfd.revents = 0x0; + + sigemptyset(&sigMask); + sigaddset(&sigMask, SIGUSR1); + + /* 开辟线程执行 ppoll */ + retVal = pthread_create(&tid, NULL, pthread_01, NULL); + ICUNIT_ASSERT_EQUAL(retVal, 0, retVal); + g_step++; + + /* 向管道写入数据 */ + while (g_step < 3) { /* 3, 3ed step */ + usleep(DELAY_TIME); + } + sleep(1); /* 保证先挂起再写入数据 */ + retVal = write(pipeFdPpoll[1], "hello world.", sizeof(strBuf)); + ICUNIT_ASSERT_NOT_EQUAL(retVal, -1, retVal); + + /* 向线程发送信号 */ + while (g_step < 5) { /* 5, 5th step */ + usleep(DELAY_TIME); + } + sleep(1); /* 保证先挂起再发送信号 */ + retVal = pthread_kill(tid, SIGUSR1); + ICUNIT_ASSERT_EQUAL(retVal, 0, retVal); + + /* 继续向管道写入数据 */ + ICUNIT_ASSERT_EQUAL(g_step, 5, g_step); /* 5, sth。判断挂起解除之前信号没有被处理 */ + retVal = write(pipeFdPpoll[1], "hello world.", sizeof(strBuf)); + ICUNIT_ASSERT_NOT_EQUAL(retVal, -1, retVal); + + while (g_step < 7) { /* 7, 7th step */ + usleep(DELAY_TIME); + } + ICUNIT_ASSERT_EQUAL(count, 2, count); /* 2, 2nd step */ + /* 等待退出 */ + pthread_join(tid, NULL); + + return LOS_OK; +} + +VOID IO_TEST_PPOLL_003(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_pselect_001.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_pselect_001.cpp new file mode 100644 index 00000000..d6cfa95d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_pselect_001.cpp @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_test_IO.h" +#include +#include +#include +#include +#include "sys/select.h" + +static UINT32 Testcase1(VOID) +{ + static const int TAR_STR_LEN = 12; /* 12, str len */ + int pipeFd[2], ret; /* 2, pipe return 2 file descirpter */ + fd_set reads; + ret = pipe(pipeFd); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ret = write(pipeFd[1], "Hello World", TAR_STR_LEN); + ICUNIT_GOTO_EQUAL(ret, TAR_STR_LEN, ret, EXIT); + FD_ZERO(&reads); + FD_SET(pipeFd[0], &reads); + ret = select(pipeFd[0] + 1, &reads, nullptr, nullptr, nullptr); + ICUNIT_GOTO_EQUAL(ret, 1, ret, EXIT); + ret = FD_ISSET(pipeFd[0], &reads); + ICUNIT_GOTO_NOT_EQUAL(ret, 0, ret, EXIT); + close(pipeFd[0]); + close(pipeFd[1]); + return LOS_OK; +EXIT: + close(pipeFd[0]); + close(pipeFd[1]); + return LOS_NOK; +} + +#define V_SIGMASK 0x5555 +static UINT32 testcase(VOID) +{ + fd_set rfds; + struct timespec tv; + int retval; + pid_t pid; + int pipeFd[2]; /* 2, pipe id num */ + char buffer[40]; /* 40, buffer size */ + int i = 0; + int status; + + sigset_t mask; + + retval = Testcase1(); /* first check select works */ + ICUNIT_GOTO_EQUAL(retval, 0, retval, OUT); + + retval = pipe(pipeFd); + ICUNIT_GOTO_EQUAL(retval, 0, retval, OUT); + + /* Watch fd to see when it has input. */ + FD_ZERO(&rfds); + FD_SET(pipeFd[0], &rfds); + + /* Wait up to three seconds. */ + tv.tv_sec = 3; /* 3, wait timer, second */ + tv.tv_nsec = 5; /* 5, wait timer, nano second */ + + pid = fork(); + if (pid == 0) { + close(pipeFd[1]); + + retval = pselect(pipeFd[0] + 1, &rfds, nullptr, nullptr, &tv, &mask); + close(pipeFd[0]); + + if (retval) { + exit(LOS_OK); + } else { + exit(LOS_NOK); + } + } else { + sleep(1); + close(pipeFd[0]); + retval = write(pipeFd[1], "0123456789012345678901234567890123456789", 40); /* write 40 bytes to stdin(fd 0) */ + ICUNIT_GOTO_EQUAL(retval, 40, retval, OUT); + close(pipeFd[1]); + + wait(&status); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(status, LOS_OK, status); + } + + return LOS_OK; +OUT: + return LOS_NOK; +} + +VOID IO_TEST_PSELECT_001(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_pselect_002.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_pselect_002.cpp new file mode 100644 index 00000000..a57c316d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_pselect_002.cpp @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_test_IO.h" +#include +#include +#include +#include +#include "sys/select.h" + +static void SigPrint(int sig) +{ + (void)sig; + return; +} + +static UINT32 testcase(VOID) +{ + fd_set rfds; + struct timespec tv; + int retval; + pid_t pid; + int pipeFd[2]; /* 2, pipe id num */ + char buffer[40]; /* 40, buffer size */ + + int i = 0; + int status; + + void (*retSig)(int); + sigset_t mask; + + retSig = signal(SIGALRM, SigPrint); + ICUNIT_ASSERT_NOT_EQUAL(retSig, NULL, retSig); + + retSig = signal(SIGUSR1, SigPrint); + ICUNIT_ASSERT_NOT_EQUAL(retSig, NULL, retSig); + + retval = sigemptyset(&mask); + ICUNIT_ASSERT_EQUAL(retval, 0, retval); + + retval = sigaddset(&mask, SIGALRM); + ICUNIT_ASSERT_EQUAL(retval, 0, retval); + + retval = sigaddset(&mask, SIGUSR1); + ICUNIT_ASSERT_EQUAL(retval, 0, retval); + + retval = pipe(pipeFd); + ICUNIT_GOTO_EQUAL(retval, 0, retval, OUT); + + /* Watch fd to see when it has input. */ + FD_ZERO(&rfds); + FD_SET(pipeFd[0], &rfds); + + /* Wait up to three seconds. */ + tv.tv_sec = 3; /* 3, wait timer, second */ + tv.tv_nsec = 5; /* 5, wait timer, nano second */ + + pid = fork(); + if (pid == 0) { + close(pipeFd[1]); + + retval = pselect(pipeFd[0] + 1, &rfds, nullptr, nullptr, &tv, &mask); + + close(pipeFd[0]); + + if (retval != 0) { + exit(LOS_OK); + } else { + exit(LOS_NOK); + } + } else { + sleep(1); + close(pipeFd[0]); + + retval = kill(pid, SIGALRM); + ICUNIT_ASSERT_EQUAL(retval, 0, retval); + + retval = kill(pid, SIGUSR1); + ICUNIT_ASSERT_EQUAL(retval, 0, retval); + close(pipeFd[1]); + + wait(&status); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(status, LOS_OK, status); + } + + return LOS_OK; +OUT: + return LOS_NOK; +} + +VOID IO_TEST_PSELECT_002(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} + diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_strcasecmp_l_001.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_strcasecmp_l_001.cpp new file mode 100644 index 00000000..7c9acb69 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_strcasecmp_l_001.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_IO.h" +#include +#include "locale.h" + +static UINT32 testcase(VOID) +{ + char *a = "aBcDeF"; + char *b = "AbCdEf"; + locale_t loc; + + printf("Strings:a=%s,b=%s,doing if(!strcasecmp(a, b))printf(\"\%s=\%s\\n\", a, b);", a, b, a, b); + if (!strcasecmp_l(a, b, loc)) { + printf("%s=%s\n", a, b); + } + ICUNIT_ASSERT_EQUAL(strcasecmp_l(a, b, loc), 0, strcasecmp_l(a, b, loc)); + + return LOS_OK; +} + +VOID IO_TEST_STRCASECMP_L_001(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_strcasecmp_l_002.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_strcasecmp_l_002.cpp new file mode 100644 index 00000000..4312816e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_strcasecmp_l_002.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_IO.h" +#include + +static UINT32 testcase1(VOID) +{ + char *a = "aBcDeF"; + char *b = "AbCEf"; + int ret = 0; + locale_t loc; + errno = 0; + + ret = strcasecmp_l(a, b, loc); + TEST_PRINT("[INFO]%s:%d,%s,ret=%d,errno=%d,errstr=%s\n", __FILE__, __LINE__, __func__, ret, errno, strerror(errno)); + ICUNIT_GOTO_NOT_EQUAL(ret, 0, ret, OUT); + ICUNIT_GOTO_EQUAL(errno, 0, errno, OUT); + + return LOS_OK; +OUT: + return LOS_NOK; +} + +static UINT32 testcase2(VOID) +{ + char *a = "aBcDfF"; + char *b = "AbCEe"; + int ret = 0; + locale_t loc; + errno = 0; + + ret = strcasecmp_l(a, b, loc); + TEST_PRINT("[INFO]%s:%d,%s,ret=%d,errno=%d,errstr=%s\n", __FILE__, __LINE__, __func__, ret, errno, strerror(errno)); + ICUNIT_GOTO_NOT_EQUAL(ret, 0, ret, OUT); + ICUNIT_GOTO_EQUAL(errno, 0, errno, OUT); + + return LOS_OK; +OUT: + return LOS_NOK; +} + +static UINT32 testcase(VOID) +{ + testcase1(); + testcase2(); + + return LOS_OK; +} + +VOID IO_TEST_STRCASECMP_L_002(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_strfmon_l_001.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_strfmon_l_001.cpp new file mode 100644 index 00000000..2d4ab5fa --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_strfmon_l_001.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_IO.h" +#include +#include "locale.h" + +static UINT32 testcase(VOID) +{ + char buf[100] = {0}; + int ret = 0; + locale_t loc; + + ret = strfmon_l(buf, sizeof(buf), loc, "[%^=*#6n] [%=*#6i]", 1234.567, 1234.567); + ICUNIT_ASSERT_EQUAL(ret, 23, ret); + + ret = strfmon_l(buf, sizeof(buf), loc, "[%^=*#6n] [%=*#6i]", 134.567, 1234.567); + ICUNIT_ASSERT_EQUAL(ret, 23, ret); + + ret = strfmon_l(buf, sizeof(buf), loc, "[%^=*#6n] [%=*#6i]", 1234.567, 134.567); + ICUNIT_ASSERT_EQUAL(ret, 23, ret); + + return LOS_OK; +} + +VOID IO_TEST_STRFMON_L_001(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_strfmon_l_002.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_strfmon_l_002.cpp new file mode 100644 index 00000000..b266fff4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_strfmon_l_002.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_IO.h" +#include +#include "locale.h" + +static UINT32 testcase1(VOID) +{ + char buf[100] = {0}; + int ret = 0; + locale_t loc; + errno = 0; + + setenv("MUSL_LOCPATH", "/storage", 1); + TEST_PRINT("[INFO]%s:%d,%s,Locale is: %s\n", __FILE__, __LINE__, __func__,setlocale(LC_TIME, "zh_CN.UTF-8")); + + errno = 0; + ret = strfmon_l(buf, 2, loc, "[%^=*#6n] [%=*#6i]", 1234.567, 1234.567); + TEST_PRINT("[INFO]%s:%d,%s,ret=%d,errno=%d,errstr=%s\n", __FILE__, __LINE__, __func__, ret, errno, strerror(errno)); + TEST_PRINT("[INFO]%s:%d,%s,ret=%d,buf=%s\n", __FILE__, __LINE__, __func__, ret, buf); + ICUNIT_GOTO_EQUAL(ret, -1, ret, OUT); + ICUNIT_GOTO_EQUAL(errno, E2BIG, errno, OUT); + + errno = 0; + ret = strfmon_l(buf, 3, loc, "[%^=*#6n] [%=*#6i]", 134.567, 1234.567); + TEST_PRINT("[INFO]%s:%d,%s,ret=%d,errno=%d,errstr=%s\n", __FILE__, __LINE__, __func__, ret, errno, strerror(errno)); + TEST_PRINT("[INFO]%s:%d,%s,ret=%d,buf=%s\n", __FILE__, __LINE__, __func__, ret, buf); + ICUNIT_GOTO_EQUAL(ret, -1, ret, OUT); + ICUNIT_GOTO_EQUAL(errno, E2BIG, errno, OUT); + + errno = 0; + ret = strfmon_l(buf, 22, loc, "[%^=*#6n] [%=*#6i]", 1234.567, 134.567); + TEST_PRINT("[INFO]%s:%d,%s,ret=%d,errno=%d,errstr=%s\n", __FILE__, __LINE__, __func__, ret, errno, strerror(errno)); + TEST_PRINT("[INFO]%s:%d,%s,ret=%d,buf=%s\n", __FILE__, __LINE__, __func__, ret, buf); + ICUNIT_GOTO_EQUAL(ret, -1, ret, OUT); + ICUNIT_GOTO_EQUAL(errno, E2BIG, errno, OUT); + + errno = 0; + ret = strfmon_l(buf, 23, loc, "[%^=*#6n] [%=*#6i]", 1234.567, 134.567); + TEST_PRINT("[INFO]%s:%d,%s,ret=%d,errno=%d,errstr=%s\n", __FILE__, __LINE__, __func__, ret, errno, strerror(errno)); + TEST_PRINT("[INFO]%s:%d,%s,ret=%d,buf=%s\n", __FILE__, __LINE__, __func__, ret, buf); + ICUNIT_GOTO_EQUAL(ret, 23, ret, OUT); + ICUNIT_GOTO_EQUAL(errno, 0, errno, OUT); + setlocale(LC_ALL, "C"); + + return LOS_OK; +OUT: + return LOS_NOK; +} + +static UINT32 testcase(VOID) +{ + testcase1(); + + return LOS_OK; +} + +VOID IO_TEST_STRFMON_L_002(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_strncasecmp_l_001.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_strncasecmp_l_001.cpp new file mode 100644 index 00000000..57ada71c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_strncasecmp_l_001.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_IO.h" +#include +#include "locale.h" + +static UINT32 testcase(VOID) +{ + char *a = "aBcDeF"; + char *b = "AbCdEf"; + int n = 5; + locale_t loc; + + printf("Strings:a=%s,b=%s,doing if(!strncasecmp(a, b, %d))printf(\"\%s=\%s\\n\", a, b);", a, b, n, a, b); + if (!strncasecmp_l(a, b, n, loc)) { + printf("%s=%s in first %d characters.\n", a, b, n); + } + ICUNIT_ASSERT_EQUAL(strncasecmp_l(a, b, n, loc), 0, strncasecmp_l(a, b, n, loc)); + + return LOS_OK; +} + +VOID IO_TEST_STRNCASECMP_L_001(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_strncasecmp_l_002.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_strncasecmp_l_002.cpp new file mode 100644 index 00000000..0f68f80c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/IO_test_strncasecmp_l_002.cpp @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_IO.h" +#include + +static UINT32 testcase1(VOID) +{ + char *a = "aBcDeF"; + char *b = "AbCdEf"; + int n = 600; + int ret = 0; + locale_t loc; + errno = 0; + + setenv("MUSL_LOCPATH", "/storage", 1); + TEST_PRINT("[INFO]%s:%d,%s,Locale is: %s\n", __FILE__, __LINE__, __func__,setlocale(LC_TIME, "zh_CN.UTF-8")); + + errno = 0; + ret = strncasecmp_l(a, b, n, loc); + TEST_PRINT("[INFO]%s:%d,%s,ret=%d,errno=%d,errstr=%s\n", __FILE__, __LINE__, __func__, ret, errno, strerror(errno)); + ICUNIT_GOTO_EQUAL(ret, 0, ret, OUT); + ICUNIT_GOTO_EQUAL(errno, 0, errno, OUT); + + return LOS_OK; +OUT: + return LOS_NOK; +} + +static UINT32 testcase2(VOID) +{ + char *a = "aBcDeF"; + char *b = "AbCdEi"; + int n = -6; + int ret = 0; + locale_t loc; + errno = 0; + + setenv("MUSL_LOCPATH", "/storage", 1); + TEST_PRINT("[INFO]%s:%d,%s,Locale is: %s\n", __FILE__, __LINE__, __func__,setlocale(LC_TIME, "zh_CN.UTF-8")); + + errno = 0; + ret = strncasecmp_l(a, b, n, loc); + TEST_PRINT("[INFO]%s:%d,%s,ret=%d,errno=%d,errstr=%s\n", __FILE__, __LINE__, __func__, ret, errno, strerror(errno)); + ICUNIT_GOTO_EQUAL(ret, -3, ret, OUT); + ICUNIT_GOTO_EQUAL(errno, 0, errno, OUT); + + return LOS_OK; +OUT: + return LOS_NOK; +} + +static UINT32 testcase3(VOID) +{ + char *a = "aBcDeF"; + char *b = "AbCdAx"; + int n = 0; + int ret = 0; + locale_t loc; + errno = 0; + + setenv("MUSL_LOCPATH", "/storage", 1); + TEST_PRINT("[INFO]%s:%d,%s,Locale is: %s\n", __FILE__, __LINE__, __func__,setlocale(LC_TIME, "zh_CN.UTF-8")); + + errno = 0; + ret = strncasecmp_l(a, b, n, loc); + TEST_PRINT("[INFO]%s:%d,%s,ret=%d,errno=%d,errstr=%s\n", __FILE__, __LINE__, __func__, ret, errno, strerror(errno)); + ICUNIT_GOTO_EQUAL(ret, 0, ret, OUT); + ICUNIT_GOTO_EQUAL(errno, 0, errno, OUT); + + return LOS_OK; +OUT: + return LOS_NOK; +} + +static UINT32 testcase4(VOID) +{ + char *a = "34342aBcDeF"; + char *b = "AbCdAx"; + int n = 4; + int ret = 0; + locale_t loc; + errno = 0; + + setenv("MUSL_LOCPATH", "/storage", 1); + TEST_PRINT("[INFO]%s:%d,%s,Locale is: %s\n", __FILE__, __LINE__, __func__,setlocale(LC_TIME, "zh_CN.UTF-8")); + + errno = 0; + ret = strncasecmp_l(a, b, n, loc); + TEST_PRINT("[INFO]%s:%d,%s,ret=%d,errno=%d,errstr=%s\n", __FILE__, __LINE__, __func__, ret, errno, strerror(errno)); + ICUNIT_GOTO_EQUAL(ret, -46, ret, OUT); + ICUNIT_GOTO_EQUAL(errno, 0, errno, OUT); + + return LOS_OK; +OUT: + return LOS_NOK; +} + +static UINT32 testcase(VOID) +{ + testcase1(); + testcase2(); + testcase3(); + testcase4(); + setlocale(LC_ALL, "C"); + + return LOS_OK; +} + +VOID IO_TEST_STRNCASECMP_L_002(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_locale_localeconv_001.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_locale_localeconv_001.cpp new file mode 100644 index 00000000..e9e5ab65 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_locale_localeconv_001.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_IO.h" + + +static UINT32 Testcase(VOID) +{ + struct lconv *newloc = localeconv(); + ICUNIT_ASSERT_NOT_EQUAL(newloc, NULL, newloc); + + return LOS_OK; +} + +VOID ItLocaleLocaleconv001(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, Testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdio_fputws_001.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdio_fputws_001.cpp new file mode 100644 index 00000000..1ada98da --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdio_fputws_001.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_IO.h" + + +static UINT32 Testcase(VOID) +{ + wchar_t *srcStr = L"hello"; + wchar_t tarStr[20] = {0}; // 20, target buffer size + int nRet; + unsigned int nPos; + int nType; + char pathname[50]; // 50, path name buffer size + FILE *testFile; + int ret; + + ret = strncpy_s(pathname, 50, g_ioTestPath, 50); // 50, path name buffer size + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + char *filename = "/crtfputwstest1"; + ret = strcat_s(pathname, 50, filename); // 50, path name buffer size + ICUNIT_ASSERT_EQUAL(ret, EOK, ret); + for (nType = 0; nType < 6; nType++) { // 6, test loop num + testFile = fopen(pathname, "a"); + + ICUNIT_GOTO_NOT_EQUAL(testFile, NULL, testFile, EXIT); + fseek(testFile, 0, SEEK_END); + nPos = (unsigned int)ftell(testFile); + + nRet = fputws(srcStr, testFile); + + ICUNIT_GOTO_NOT_EQUAL(nRet, -1, nRet, EXIT); + if ((nPos + 5) != (unsigned int)ftell(testFile)) { // 5, expect position offset + ICUNIT_GOTO_EQUAL(1, 0, 1, EXIT); + } + fclose(testFile); + + testFile = fopen(pathname, "r"); + ICUNIT_GOTO_NOT_EQUAL(testFile, NULL, testFile, EXIT); + wchar_t *p = fgetws(tarStr, 6, testFile); // 6, "hello" length and '\0' + ICUNIT_GOTO_EQUAL(p, tarStr, p, EXIT); + nRet = wcscmp(srcStr, tarStr); + ICUNIT_GOTO_EQUAL(nRet, 0, nRet, EXIT); + fclose(testFile); + } + + remove(pathname); + return LOS_OK; +EXIT: + if (testFile != NULL) { + fclose(testFile); + remove(pathname); + } + return LOS_NOK; +} + +VOID ItStdioFputws001(void) +{ + TEST_ADD_CASE(__FUNCTION__, Testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdio_fwprintf_001.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdio_fwprintf_001.cpp new file mode 100644 index 00000000..fbafa1bd --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdio_fwprintf_001.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_IO.h" + + +static UINT32 Testcase(VOID) +{ + wchar_t tarStr[20] = {0}; // 20, buffer size + wchar_t *p; + int nRet; + unsigned int nPos; + int nType; + char pathname[50]; // 50, path name buffer size + (void)strncpy_s(pathname, 50, g_ioTestPath, 50); // 50, path name buffer size + char *filename = "/crtfwprintftest1"; + FILE *testFile = NULL; + int ret; + + ret = strcat_s(pathname, 50, filename); // 50, path name buffer size + ICUNIT_ASSERT_EQUAL(ret, EOK, ret); + + for (nType = 0; nType < 6; nType++) { // 6, loop test num + testFile = fopen(pathname, "w+"); + ICUNIT_GOTO_NOT_EQUAL(testFile, NULL, testFile, EXIT); + + nPos = (unsigned int)ftell(testFile); + + nRet = fwprintf(testFile, L"hello world %d", 666); // 666, for test, print to testFile + ICUNIT_GOTO_EQUAL(nRet, 15, nRet, EXIT); // 15, total write size + + if ((nPos + 15) != (unsigned int)ftell(testFile)) { // 15, total write size + ICUNIT_GOTO_EQUAL(1, 0, 1, EXIT); + } + fclose(testFile); + + testFile = fopen(pathname, "r"); + ICUNIT_GOTO_NOT_EQUAL(testFile, NULL, testFile, EXIT); + + p = fgetws(tarStr, 16, testFile); // 16, read size,total write and '\0' + nRet = wcscmp(L"hello world 666", tarStr); + ICUNIT_GOTO_EQUAL(nRet, 0, nRet, EXIT); + + fclose(testFile); + } + + remove(pathname); + return LOS_OK; +EXIT: + if (testFile != NULL) { + fclose(testFile); + remove(pathname); + } + return LOS_NOK; +} + +VOID ItStdioFwprintf001(void) +{ + TEST_ADD_CASE(__FUNCTION__, Testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdio_getc_unlocked_001.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdio_getc_unlocked_001.cpp new file mode 100644 index 00000000..86b87578 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdio_getc_unlocked_001.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_IO.h" + + +static UINT32 Testcase(VOID) +{ + char ch; + unsigned int nPos; + int ret; + char pathname[50]; // 50, enough space. + char *filename = "/crt_getc_unlocked_test1"; + FILE *testFile = NULL; + + ret = strncpy_s(pathname, sizeof(pathname), g_ioTestPath, sizeof(pathname)); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = strcat_s(pathname, 50, filename); // 50, path name buffer size + ICUNIT_ASSERT_EQUAL(ret, EOK, ret); + + testFile = fopen(pathname, "w+"); + ICUNIT_ASSERT_NOT_EQUAL(testFile, NULL, LOS_NOK); + ret = fputs("0123456789abcdefghijklmnopqrstuvwxyz", testFile); + ICUNIT_GOTO_NOT_EQUAL(ret, EOF, ret, EXIT); + fclose(testFile); + + testFile = fopen(pathname, "r"); + ICUNIT_GOTO_NOT_EQUAL(testFile, NULL, testFile, EXIT); + + nPos = ftell(testFile); + + ch = getc_unlocked(testFile); + ICUNIT_GOTO_EQUAL(ch, '0', ch, EXIT); + + if ((nPos + sizeof(char)) != (unsigned int)ftell(testFile)) { + ICUNIT_GOTO_EQUAL(1, 0, 1, EXIT); + } + + fclose(testFile); + remove(pathname); + return LOS_OK; +EXIT: + if (testFile != NULL) { + fclose(testFile); + remove(pathname); + } + return LOS_NOK; +} + +VOID ItStdioGetcUnlocked001(void) +{ + TEST_ADD_CASE(__FUNCTION__, Testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdio_hasmntopt_001.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdio_hasmntopt_001.cpp new file mode 100644 index 00000000..a0d605b6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdio_hasmntopt_001.cpp @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_IO.h" + +static UINT32 testcase(VOID) +{ + struct mntent* mnt = nullptr; + struct mntent* mnt_new = nullptr; + FILE *fp = nullptr; + FILE *fp2 = nullptr; + char *argv[2] = {nullptr}; + argv[0] = "/etc/fstab"; + argv[1] = "errors"; + char *opt = argv[1]; + char *ret = nullptr; + + char fileWords[] = "/dev/disk/by-uuid/c4992556-a86e-45e8-ba5f-190b16a9073x /usr1 ext3 errors=remount-ro,nofail 0 1"; + char *pathList[] = {"/etc/fstab"}; + char *streamList[] = {static_cast(fileWords)}; + int streamLen[] = {sizeof(fileWords)}; + + int flag = PrepareFileEnv(pathList, streamList, streamLen, 1); + if (flag != 0) { + printf("error: need some env file, but prepare is not ok"); + (VOID)RecoveryFileEnv(pathList, 1); + return -1; + } + + mnt_new = (struct mntent *)malloc(sizeof(struct mntent)); + if (mnt_new == NULL) { + (VOID)RecoveryFileEnv(pathList, 1); + return LOS_NOK; + } + mnt_new->mnt_fsname = "UUID=c4992556-a86e-45e8-ba5f-190b16a9073x"; + mnt_new->mnt_dir = "/usr1"; + mnt_new->mnt_type = "ext3"; + mnt_new->mnt_opts = "errors=remount-ro,nofail"; + mnt_new->mnt_freq = 0; + mnt_new->mnt_passno = 1; + + fp = setmntent("/etc/fstab", "r"); + if (!fp) { + printf("fp=0x%x\n", fp); + free(mnt_new); + return LOS_NOK; + } + + mnt = getmntent(fp); + if (mnt && !(feof(fp) || ferror(fp))) { + ret = hasmntopt(mnt, opt); + printf("hasmntopt=%s\n", ret); + ICUNIT_ASSERT_NOT_EQUAL(ret, NULL, -1); + mnt = getmntent(fp); + } + + if (fp != NULL) { + endmntent(fp); + } + + /* test the addmntent below */ + fp = setmntent(argv[0], "a"); + fp2 = fopen("/lib/libc.so", "r"); + if (fp2 != NULL) { + printf("aha I found you are OHOS!!!\n"); + if (addmntent(fp, mnt_new)) { + printf("a new mnt is added to %s\n", argv[0]); + } + } + + if (fp != NULL) { + endmntent(fp); + } + if (fp2 != NULL) { + fclose(fp2); + } + (VOID)RecoveryFileEnv(pathList, 1); + return LOS_OK; +} + +VOID IT_STDIO_HASMNTOPT_001(void) +{ + TEST_ADD_CASE(__FUNCTION__, testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdio_mblen_001.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdio_mblen_001.cpp new file mode 100644 index 00000000..f35fd4b3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdio_mblen_001.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_IO.h" + + +static UINT32 Testcase(VOID) +{ + setlocale(LC_ALL, "en_US.utf8"); + size_t result = 0; + const char *str = "z\u00df\u6c34\U0001f34c"; + const char *end = str + strlen(str); + + mblen(NULL, 0); + while (str < end) { + int next = mblen(str, end - str); + if (next == -1) { + perror("strlen_mb"); + break; + } + str += next; + ++result; + } + ICUNIT_GOTO_EQUAL(result, 4, result, EXIT); // 4, except value + setlocale(LC_ALL, "C"); + + return LOS_OK; +EXIT: + return LOS_NOK; +} + +VOID ItStdioMblen001(void) +{ + TEST_ADD_CASE(__FUNCTION__, Testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdio_mbrlen_001.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdio_mbrlen_001.cpp new file mode 100644 index 00000000..ed59e2ce --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdio_mbrlen_001.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_IO.h" + + +static UINT32 Testcase(VOID) +{ + // allow mbrlen() to work with UTF-8 multibyte encoding + setlocale(LC_ALL, "en_US.utf8"); + const char *str = "水"; + size_t sz = strlen(str); + int len1, len2, len3; + UINT32 ret; + + mbstate_t mb; + ret = memset_s(&mb, sizeof(mb), 0, sizeof(mb)); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + len1 = mbrlen(str, 1, &mb); + ICUNIT_GOTO_EQUAL(len1, -2, len1, EXIT); // -2, except return value + + len2 = mbrlen(str + 1, sz - 1, &mb); + ICUNIT_GOTO_EQUAL(len2, 2, len2, EXIT); // 2, except return value + + len3 = mbrlen(str + 1, sz - 1, &mb); + ICUNIT_GOTO_EQUAL(len3, -1, len3, EXIT); + setlocale(LC_ALL, "C"); + + return LOS_OK; +EXIT: + return LOS_NOK; +} + +VOID ItStdioMbrlen001(void) +{ + TEST_ADD_CASE(__FUNCTION__, Testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdio_putwc_001.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdio_putwc_001.cpp new file mode 100644 index 00000000..7767447b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdio_putwc_001.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_IO.h" + + +static UINT32 Testcase(VOID) +{ + wchar_t srcWc = L'H'; + int tarWc, nRet; + long nPos; + int nType, i; + FILE *putwcFile = NULL; + char pathname[50]; // 50, pathname size + char *filename = "/crtputwctest1"; + int ret; + + ret = strncpy_s(pathname, 50, g_ioTestPath, 50); // 50, pathname size + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = strcat_s(pathname, 50, filename); // 50, path name buffer size + ICUNIT_ASSERT_EQUAL(ret, EOK, ret); + + for (nType = 0; nType < 6; nType++) { // 6, loop test num + putwcFile = fopen(pathname, "w+"); + ICUNIT_GOTO_NOT_EQUAL(putwcFile, NULL, putwcFile, EXIT); + + nPos = ftell(putwcFile); + + nRet = putwc(srcWc, putwcFile); + ICUNIT_GOTO_EQUAL(nRet, L'H', nRet, EXIT); + fclose(putwcFile); + + putwcFile = fopen(pathname, "r"); + ICUNIT_GOTO_NOT_EQUAL(putwcFile, NULL, putwcFile, EXIT); + + tarWc = getwc(putwcFile); + ICUNIT_GOTO_EQUAL(tarWc, L'H', tarWc, EXIT); + + if ((nPos + 1) != ftell(putwcFile)) { + ICUNIT_GOTO_EQUAL(1, 0, 1, EXIT); + } + + fclose(putwcFile); + } + + remove(pathname); + return LOS_OK; +EXIT: + if (putwcFile != NULL) { + fclose(putwcFile); + remove(pathname); + } + return LOS_NOK; +} + +VOID ItStdioPutwc001(void) +{ + TEST_ADD_CASE(__FUNCTION__, Testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdio_readv_001.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdio_readv_001.cpp new file mode 100644 index 00000000..6af0103b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdio_readv_001.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_IO.h" + +static UINT32 Testcase(VOID) +{ + char *srcStr = "helloworld"; + int nRet, fd; + char pathname[50]; // 50, path name size + char *filename = "/crtreadvtest1"; + char buf1[6] = { 0 }; + char buf2[6] = { 0 }; + struct iovec iov[2]; // 2, read 2 block + ssize_t nread; + const int testStrLen = 10; + UINT32 ret; + + iov[0].iov_base = buf1; + iov[0].iov_len = sizeof(buf1) - 1; + iov[1].iov_base = buf2; + iov[1].iov_len = sizeof(buf2) - 1; + + (void)strncpy_s(pathname, 50, g_ioTestPath, 50); // 50, path name size + ret = strcat_s(pathname, 50, filename); // 50, path name buffer size + ICUNIT_ASSERT_EQUAL(ret, EOK, ret); + fd = open(pathname, O_CREAT | O_RDWR | O_TRUNC, 0666); // 0666, file authority + if (fd < 0) { + printf("error: can`t open file\n"); + } + nRet = write(fd, srcStr, testStrLen); + ICUNIT_GOTO_EQUAL(nRet, testStrLen, nRet, EXIT); + close(fd); + + fd = open(pathname, O_RDWR); + if (fd < 0) { + printf("error: can`t open file\n"); + } + nread = readv(fd, iov, 2); // 2, read 2 block + ICUNIT_GOTO_EQUAL(nread, testStrLen, nread, EXIT); + nRet = strcmp(buf2, "world"); + ICUNIT_GOTO_EQUAL(nRet, 0, nRet, EXIT); + nRet = strcmp(buf1, "hello"); + ICUNIT_GOTO_EQUAL(nRet, 0, nRet, EXIT); + + close(fd); + remove(pathname); + return LOS_OK; +EXIT: + close(fd); + remove(pathname); + return LOS_NOK; +} + +VOID ItStdioReadv001(void) +{ + TEST_ADD_CASE(__FUNCTION__, Testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdio_rindex_001.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdio_rindex_001.cpp new file mode 100644 index 00000000..b69df021 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdio_rindex_001.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_IO.h" + + +static UINT32 Testcase(VOID) +{ + int ret; + char *s = "abcdef123456abcdef"; + char *p = NULL; + p = rindex(s, 'b'); + ret = strcmp(p, "bcdef"); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + return LOS_OK; +EXIT: + return LOS_NOK; +} + +VOID ItStdioRindex001(void) +{ + TEST_ADD_CASE(__FUNCTION__, Testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdio_setlogmask_001.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdio_setlogmask_001.cpp new file mode 100644 index 00000000..9fa4f469 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdio_setlogmask_001.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_IO.h" + + +static UINT32 Testcase(VOID) +{ + int oldmask; + int newmask = 0xff; + oldmask = setlogmask(newmask); + newmask = setlogmask(oldmask); + ICUNIT_ASSERT_EQUAL(newmask, 0xff, newmask); + + return LOS_OK; +} + +VOID ItStdioSetlogmask001(void) +{ + TEST_ADD_CASE(__FUNCTION__, Testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdlib_gcvt_001.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdlib_gcvt_001.cpp new file mode 100644 index 00000000..9894425e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdlib_gcvt_001.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_IO.h" + + +static UINT32 Testcase(VOID) +{ + double a = 12345678.12549; + double b = 0.1234567; + char ptr[128] = {0}; // 128, target buffer size + int ret; + gcvt(a, 10, ptr); // 10, convert significant value setting + ret = strcmp(ptr, "12345678.13"); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + gcvt(b, 6, ptr); // 6, convert significant value setting + ret = strcmp(ptr, "0.123457"); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return 0; +} + +VOID ItStdlibGcvt001(void) +{ + TEST_ADD_CASE(__FUNCTION__, Testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdlib_poll_002.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdlib_poll_002.cpp new file mode 100644 index 00000000..58eb521c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdlib_poll_002.cpp @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_IO.h" + +int g_pipeFd[10][2]; // 2, read and write; 10, listen fd number. +static pthread_t g_tid = -1; +static const int LISTEN_FD_NUM = 10; + +static void *Pthread01(void *arg) +{ + int totalNum = 0; + int times = 3; // 3, loop number for test. + int i, ret; + struct pollfd fds[LISTEN_FD_NUM] = {0}; + char buffer[20]; // 20, enough space for test. + const int pollEvents = 1; + + for (i = 0; i < LISTEN_FD_NUM; i++) { + fds[i].fd = g_pipeFd[i][0]; + fds[i].events = pollEvents; + } + + while (times--) { + ret = poll(fds, LISTEN_FD_NUM, 1000); // 1000, wait time. + totalNum += ((ret > 0) ? ret : 0); + + if (ret <= 0) { + continue; + } + + for (i = 0; i < LISTEN_FD_NUM; i++) { + if (fds[i].revents & pollEvents) { + ret = read(fds[i].fd, buffer, 12); // 12, "hello world" length and '\0' + ICUNIT_GOTO_EQUAL(ret, 12, ret, EXIT); // 12, "hello world" length and '\0' + ret = strcmp(buffer, "hello world"); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + } + } + + if (totalNum == LISTEN_FD_NUM) { + break; + } + } + + ICUNIT_GOTO_EQUAL(totalNum, LISTEN_FD_NUM, -1, EXIT); + +EXIT: + return NULL; +} + +static UINT32 Testcase(VOID) +{ + int i; + int ret; + + for (i = 0; i < LISTEN_FD_NUM; i++) { + ret = pipe(g_pipeFd[i]); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + } + + ret = pthread_create(&g_tid, NULL, Pthread01, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + for (i = 0; i < LISTEN_FD_NUM; i++) { + ret = write(g_pipeFd[i][1], "hello world", 12); // 12, "hello world" length and '\0' + ICUNIT_GOTO_EQUAL(ret, 12, ret, EXIT); // 12, "hello world" length and '\0' + } + + pthread_join(g_tid, NULL); + + for (i = 0; i < LISTEN_FD_NUM; i++) { + close(g_pipeFd[i][0]); + close(g_pipeFd[i][1]); + } + + return LOS_OK; + +EXIT: + for (i = 0; i < LISTEN_FD_NUM; i++) { + close(g_pipeFd[i][0]); + close(g_pipeFd[i][1]); + } + return LOS_NOK; +} + +VOID ItStdlibPoll002(void) +{ + TEST_ADD_CASE(__FUNCTION__, Testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdlib_poll_003.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdlib_poll_003.cpp new file mode 100644 index 00000000..d1a99db8 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/full/It_stdlib_poll_003.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_IO.h" + +struct PollParam { + int nfds; + int timeout; + int ret; + int err; +}; + +static UINT32 Testcase(VOID) +{ + const int TEST_STR_LEN = 12; + int pipeFd[2], ret, err; // 2, pipe return 2 file descirpter + struct pollfd pollFd; + struct PollParam pollParam[4] = { /* nfds timeout ret err */ + { 0, 100, -1, EINVAL}, + { 4096, 10, -1, EINVAL}, + { 4095, 10, -1, EFAULT}, + { 1, -1, 1, 0} + }; + + ret = pipe(pipeFd); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = write(pipeFd[1], "hello world", TEST_STR_LEN); + printf("write first status: %d\n", ret); + ICUNIT_GOTO_EQUAL(ret, TEST_STR_LEN, ret, EXIT); + + pollFd.fd = pipeFd[0]; + pollFd.events = POLLIN; + + for (int i = 0; i < sizeof(pollParam) / sizeof(pollParam[0]); i++) { + ret = poll(&pollFd, pollParam[i].nfds, pollParam[i].timeout); + ICUNIT_GOTO_EQUAL(ret, pollParam[i].ret, ret, EXIT); + if (ret == -1) { + printf("i = %d\n", i); + if (i == 2) { // 2, pollParam[2]. + ICUNIT_GOTO_TWO_EQUAL(errno, EFAULT, EBADF, errno, EXIT); + } else { + ICUNIT_GOTO_EQUAL(errno, pollParam[i].err, errno, EXIT); + } + } + } + + close(pipeFd[0]); + close(pipeFd[1]); + return LOS_OK; +EXIT: + close(pipeFd[0]); + close(pipeFd[1]); + return LOS_NOK; +} + +VOID ItStdlibPoll003(void) +{ + TEST_ADD_CASE(__FUNCTION__, Testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/io_test.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/io_test.cpp new file mode 100644 index 00000000..0d47f165 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/io_test.cpp @@ -0,0 +1,493 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include + +#include "It_test_IO.h" + +char *g_ioTestPath = "/storage"; + +using namespace testing::ext; +namespace OHOS { +class IoTest : public testing::Test { +public: + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} +}; + +#if defined(LOSCFG_USER_TEST_SMOKE) +/* * + * @tc.name: IT_TEST_IO_005 + * @tc.desc: function for IoTest + * @tc.type: FUNC + */ +HWTEST_F(IoTest, ItTestIo005, TestSize.Level0) +{ + ItTestIo005(); +} + +#ifdef LOSCFG_USER_TEST_FS_JFFS +/* * + * @tc.name: IT_TEST_IO_008 + * @tc.desc: function for IoTest + * @tc.type: FUNC + */ +HWTEST_F(IoTest, ItTestIo008, TestSize.Level0) +{ + ItTestIo008(); +} +#endif + + +/* * + * @tc.name: IT_TEST_IO_010 + * @tc.desc: function for IoTest + * @tc.type: FUNC + */ +HWTEST_F(IoTest, ItTestIo010, TestSize.Level0) +{ + ItTestIo010(); +} + +/* * + * @tc.name: IT_TEST_IO_013 + * @tc.desc: function for IoTest + * @tc.type: FUNC + */ +HWTEST_F(IoTest, ItTestIo013, TestSize.Level0) +{ + ItTestIo013(); +} +#endif + +#if defined(LOSCFG_USER_TEST_FULL) +/* * + * @tc.name: IO_TEST_PSELECT_001 + * @tc.desc: function for IoTest + * @tc.type: FUNC + */ +HWTEST_F(IoTest, IO_TEST_PSELECT_001, TestSize.Level0) +{ + IO_TEST_PSELECT_001(); +} + +/* * + * @tc.name: IO_TEST_PSELECT_002 + * @tc.desc: function for IoTest + * @tc.type: FUNC + */ +HWTEST_F(IoTest, IO_TEST_PSELECT_002, TestSize.Level0) +{ + IO_TEST_PSELECT_002(); +} + +/* * + * @tc.name: IO_TEST_PPOLL_001 + * @tc.desc: function for IoTest + * @tc.type: FUNC + */ +HWTEST_F(IoTest, IO_TEST_PPOLL_001, TestSize.Level0) +{ + IO_TEST_PPOLL_001(); +} + +/* * + * @tc.name: IO_TEST_PPOLL_002 + * @tc.desc: function for IoTest + * @tc.type: FUNC + */ +HWTEST_F(IoTest, IO_TEST_PPOLL_002, TestSize.Level0) +{ + IO_TEST_PPOLL_002(); +} + +/* * + * @tc.name: IO_TEST_PPOLL_003 + * @tc.desc: function for IoTest + * @tc.type: FUNC + */ +HWTEST_F(IoTest, IO_TEST_PPOLL_003, TestSize.Level0) +{ + IO_TEST_PPOLL_003(); +} + +/* * + * @tc.name: IO_TEST_EPOLL_001 + * @tc.desc: function for IoTest + * @tc.type: FUNC + */ + +HWTEST_F(IoTest, IO_TEST_EPOLL_001, TestSize.Level0) +{ + IO_TEST_EPOLL_001(); +} + +/* * + * @tc.name: IO_TEST_EPOLL_002 + * @tc.desc: function for IoTest + * @tc.type: FUNC + */ +HWTEST_F(IoTest, IO_TEST_EPOLL_002, TestSize.Level0) +{ + IO_TEST_EPOLL_002(); +} + +/* * + * @tc.name: IT_STDLIB_POLL_002 + * @tc.desc: function for IoTest + * @tc.type: FUNC + */ +HWTEST_F(IoTest, ItStdlibPoll002, TestSize.Level0) +{ + ItStdlibPoll002(); +} + +/* * + * @tc.name: IT_STDLIB_POLL_003 + * @tc.desc: function for IoTest + * @tc.type: FUNC + */ +HWTEST_F(IoTest, ItStdlibPoll003, TestSize.Level0) +{ + ItStdlibPoll003(); +} + +/* * + * @tc.name: IT_STDIO_PUTWC_001 + * @tc.desc: function for IoTest + * @tc.type: FUNC + */ +HWTEST_F(IoTest, ItStdioPutwc001, TestSize.Level0) +{ + ItStdioPutwc001(); +} + +/* * + * @tc.name: IT_STDIO_READV_001 + * @tc.desc: function for IoTest + * @tc.type: FUNC + */ +HWTEST_F(IoTest, ItStdioReadv001, TestSize.Level0) +{ + ItStdioReadv001(); +} + +/* * + * @tc.name: IT_STDIO_RINDEX_001 + * @tc.desc: function for IoTest + * @tc.type: FUNC + */ +HWTEST_F(IoTest, ItStdioRindex001, TestSize.Level0) +{ + ItStdioRindex001(); +} + +/* * + * @tc.name: IT_STDIO_SETLOGMASK_001 + * @tc.desc: function for IoTest + * @tc.type: FUNC + */ +HWTEST_F(IoTest, ItStdioSetlogmask001, TestSize.Level0) +{ + ItStdioSetlogmask001(); +} + +/* * + * @tc.name: IT_STDLIB_GCVT_001 + * @tc.desc: function for IoTest + * @tc.type: FUNC + */ +HWTEST_F(IoTest, ItStdlibGcvt001, TestSize.Level0) +{ + ItStdlibGcvt001(); +} + +/* * + * @tc.name: IT_LOCALE_LOCALECONV_001 + * @tc.desc: function for IoTest + * @tc.type: FUNC + */ +HWTEST_F(IoTest, ItLocaleLocaleconv001, TestSize.Level0) +{ + ItLocaleLocaleconv001(); +} + +/* * + * @tc.name: IT_STDIO_FPUTWS_001 + * @tc.desc: function for IoTest + * @tc.type: FUNC + */ +HWTEST_F(IoTest, ItStdioFputws001, TestSize.Level0) +{ + ItStdioFputws001(); +} + +/* * + * @tc.name: IT_STDIO_FWPRINTF_001 + * @tc.desc: function for IoTest + * @tc.type: FUNC + */ +HWTEST_F(IoTest, ItStdioFwprintf001, TestSize.Level0) +{ + ItStdioFwprintf001(); +} + +/* * + * @tc.name: IT_STDIO_GETC_UNLOCKED_001 + * @tc.desc: function for IoTest + * @tc.type: FUNC + */ +HWTEST_F(IoTest, ItStdioGetcUnlocked001, TestSize.Level0) +{ + ItStdioGetcUnlocked001(); +} + +/* * + * @tc.name: IT_STDIO_MBLEN_001 + * @tc.desc: function for IoTest + * @tc.type: FUNC + */ +HWTEST_F(IoTest, ItStdioMblen001, TestSize.Level0) +{ + ItStdioMblen001(); +} + +/* * + * @tc.name: IT_STDIO_MBRLEN_001 + * @tc.desc: function for IoTest + * @tc.type: FUNC + */ +HWTEST_F(IoTest, ItStdioMbrlen001, TestSize.Level0) +{ + ItStdioMbrlen001(); +} + +/* * + * @tc.name: IT_STDIO_HASMNTOPT_001 + * @tc.desc: function for IoTest-normal testcase + * @tc.type: FUNC + */ +HWTEST_F(IoTest, IT_STDIO_HASMNTOPT_001, TestSize.Level0) +{ + IT_STDIO_HASMNTOPT_001(); +} + +/* * + * @tc.name: IO_TEST_DUPLOCALE_001 + * @tc.desc: function for IoTest-dup the locale global pointer + * @tc.type: FUNC + */ +HWTEST_F(IoTest, IO_TEST_DUPLOCALE_001, TestSize.Level0) +{ + IO_TEST_DUPLOCALE_001(); +} + +/* * + * @tc.name: IO_TEST_NL_LANGINFO_001 + * @tc.desc: function for IoTest-normal testcase + * @tc.type: FUNC + */ +HWTEST_F(IoTest, IO_TEST_NL_LANGINFO_001, TestSize.Level0) +{ + IO_TEST_NL_LANGINFO_001(); +} + +/* * + * @tc.name: IO_TEST_STRCASECMP_L_001 + * @tc.desc: function for IoTest-normal testcase + * @tc.type: FUNC + */ +HWTEST_F(IoTest, IO_TEST_STRCASECMP_L_001, TestSize.Level0) +{ + IO_TEST_STRCASECMP_L_001(); +} + +/* * + * @tc.name: IO_TEST_STRCASECMP_L_002 + * @tc.desc: function for IoTest-normal testcase + * @tc.type: FUNC + */ +HWTEST_F(IoTest, IO_TEST_STRCASECMP_L_002, TestSize.Level0) +{ + IO_TEST_STRCASECMP_L_002(); +} + +/* * + * @tc.name: IO_TEST_STRNCASECMP_L_001 + * @tc.desc: function for IoTest-normal testcase + * @tc.type: FUNC + */ +HWTEST_F(IoTest, IO_TEST_STRNCASECMP_L_001, TestSize.Level0) +{ + IO_TEST_STRNCASECMP_L_001(); +} + +/* * + * @tc.name: IO_TEST_STRNCASECMP_L_002 + * @tc.desc: function for IoTest-normal testcase + * @tc.type: FUNC + */ +HWTEST_F(IoTest, IO_TEST_STRNCASECMP_L_002, TestSize.Level0) +{ + IO_TEST_STRNCASECMP_L_002(); +} + +/* * + * @tc.name: IO_TEST_NL_LANGINFO_l_001 + * @tc.desc: function for IoTest-query language and locale information + * @tc.type: FUNC + */ +HWTEST_F(IoTest, IO_TEST_NL_LANGINFO_l_001, TestSize.Level0) +{ + IO_TEST_NL_LANGINFO_l_001(); +} + +/* * + * @tc.name: IO_TEST_DNGETTEXT_001 + * @tc.desc: function for IoTest-print the translated string1 or string2 + * @tc.type: FUNC + */ +HWTEST_F(IoTest, IO_TEST_DNGETTEXT_001, TestSize.Level0) +{ + IO_TEST_DNGETTEXT_001(); +} + +/* * + * @tc.name: IO_TEST_DNGETTEXT_002 + * @tc.desc: function for IoTest-innormal testcases + * @tc.type: FUNC + */ +HWTEST_F(IoTest, IO_TEST_DNGETTEXT_002, TestSize.Level0) +{ + IO_TEST_DNGETTEXT_002(); +} + +/* * + * @tc.name: IO_TEST_DCNGETTEXT_001 + * @tc.desc: function for IoTest-print the translated string1 or string2 with locale parameter + * @tc.type: FUNC + */ +HWTEST_F(IoTest, IO_TEST_DCNGETTEXT_001, TestSize.Level0) +{ + IO_TEST_DCNGETTEXT_001(); +} + +/* * + * @tc.name: IO_TEST_DCNGETTEXT_002 + * @tc.desc: function for IoTest-innormal testcases + * @tc.type: FUNC + */ +HWTEST_F(IoTest, IO_TEST_DCNGETTEXT_002, TestSize.Level0) +{ + IO_TEST_DCNGETTEXT_002(); +} +/* * + * @tc.name: IO_TEST_DCGETTEXT_001 + * @tc.desc: function for IoTest-print the translated string with locale parameter + * @tc.type: FUNC + */ +HWTEST_F(IoTest, IO_TEST_DCGETTEXT_001, TestSize.Level0) +{ + IO_TEST_DCGETTEXT_001(); +} + +/* * + * @tc.name: IO_TEST_DCGETTEXT_002 + * @tc.desc: function for IoTest-innormal testcases + * @tc.type: FUNC + */ +HWTEST_F(IoTest, IO_TEST_DCGETTEXT_002, TestSize.Level0) +{ + IO_TEST_DCGETTEXT_002(); +} + +/* * + * @tc.name: IO_TEST_GETTEXT_001 + * @tc.desc: function for IoTest-normal testcases + * @tc.type: FUNC + */ +HWTEST_F(IoTest, IO_TEST_GETTEXT_001, TestSize.Level0) +{ + IO_TEST_GETTEXT_001(); +} + +/* * + * @tc.name: IO_TEST_LOCALE_001 + * @tc.desc: function for IoTest-normal testcases + * @tc.type: FUNC + */ +HWTEST_F(IoTest, IO_TEST_LOCALE_001, TestSize.Level0) +{ + IO_TEST_LOCALE_001(); +} + +/* * + * @tc.name: IO_TEST_LOCALE_002 + * @tc.desc: function for IoTest-innormal testcases + * @tc.type: FUNC + */ +HWTEST_F(IoTest, IO_TEST_LOCALE_002, TestSize.Level0) +{ + IO_TEST_LOCALE_002(); +} + +/* * + * @tc.name: IO_TEST_STRFMON_L_001 + * @tc.desc: function for IoTest-normal testcases + * @tc.type: FUNC + */ +HWTEST_F(IoTest, IO_TEST_STRFMON_L_001, TestSize.Level0) +{ + IO_TEST_STRFMON_L_001(); +} + +/* * + * @tc.name: IO_TEST_STRFMON_L_002 + * @tc.desc: function for IoTest-innormal testcases + * @tc.type: FUNC + */ +HWTEST_F(IoTest, IO_TEST_STRFMON_L_002, TestSize.Level0) +{ + IO_TEST_STRFMON_L_002(); +} + +/* * + * @tc.name: IO_TEST_NGETTEXT_001 + * @tc.desc: function for IoTest-normal testcases + * @tc.type: FUNC + */ +HWTEST_F(IoTest, IO_TEST_NGETTEXT_001, TestSize.Level0) +{ + IO_TEST_NGETTEXT_001(); +} + +#endif +} // namespace OHOS diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/smoke/IO_test_005.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/smoke/IO_test_005.cpp new file mode 100644 index 00000000..9ba58578 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/smoke/IO_test_005.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_IO.h" + +static UINT32 Testcase(VOID) +{ + INT32 i = 0; + wchar_t str[] = L"ABCDEFG"; + wchar_t str2[] = L"abcdefg"; + wchar_t c[20]; + + wctype_t check = wctype("upper"); + wctrans_t trans = wctrans("tolower"); + + while (str[i]) { + c[i] = str[i]; + if (iswctype(c[i], check)) { + c[i] = towctrans(c[i], trans); + } + if (c[i] != str2[i]) { + goto EXIT; + } + i++; + } + + return 0; +EXIT: + return -1; +} + + +VOID ItTestIo005(void) +{ + TEST_ADD_CASE(__FUNCTION__, Testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/smoke/IO_test_008.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/smoke/IO_test_008.cpp new file mode 100644 index 00000000..ed785892 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/smoke/IO_test_008.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_IO.h" + +static INT32 Vdpfunc(int fd, char *format, ...) +{ + va_list aptr; + INT32 ret; + + va_start(aptr, format); + ret = vdprintf(fd, format, aptr); + va_end(aptr); + + return ret; +} + +static UINT32 Testcase(VOID) +{ + CHAR file[30] = "/jffs0/vdprintf"; + CHAR *str1 = "123456789"; + CHAR buffer[20]; + INT32 ret, fd; + CHAR str[20] = "789"; + const int testBufLen = 20; + + fd = open(file, O_CREAT | O_RDWR | O_TRUNC); + ICUNIT_GOTO_NOT_EQUAL(fd, -1, fd, EXIT); + + ret = Vdpfunc(fd, "%s%s", "123456", str); + if (ret < 0) { + goto EXIT1; + } + + ret = close(fd); + + fd = open(file, O_RDWR); + ICUNIT_GOTO_NOT_EQUAL(fd, -1, fd, EXIT1); + + read(fd, buffer, testBufLen); + close(fd); + + ICUNIT_GOTO_STRING_EQUAL(buffer, str1, buffer, EXIT2); + + unlink(file); + return (0); +EXIT1: + close(fd); +EXIT2: + unlink(file); +EXIT: + return -1; +} + +VOID ItTestIo008(void) +{ + TEST_ADD_CASE(__FUNCTION__, Testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/smoke/IO_test_010.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/smoke/IO_test_010.cpp new file mode 100644 index 00000000..b9189faf --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/smoke/IO_test_010.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_IO.h" + + +static VOID GetWideMatches(const wchar_t *str, const wchar_t *format, ...) +{ + va_list args; + + va_start(args, format); + vswscanf(str, format, args); + va_end(args); +} + +static UINT32 Testcase(VOID) +{ + INT32 val, ret; + wchar_t buf[100]; // 100, buffer size + wchar_t *str = L"bottles"; + + GetWideMatches(L"99 bottles of beer on the wall", L" %d %ls ", &val, buf); + ret = wcscmp(buf, str); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + return 0; +EXIT: + return -1; +} + +VOID ItTestIo010(void) +{ + TEST_ADD_CASE(__FUNCTION__, Testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/io/smoke/IO_test_013.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/io/smoke/IO_test_013.cpp new file mode 100644 index 00000000..9b2763c4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/io/smoke/IO_test_013.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_IO.h" + +static UINT32 Testcase(VOID) +{ + INT32 val, ret, result; + wchar_t buf[200]; + wchar_t *str = L"helloworld"; + + swscanf(str, L"%ls", buf); + + ret = wcscmp(buf, str); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + return 0; +EXIT: + return -1; +} + +VOID ItTestIo013(void) +{ + TEST_ADD_CASE(__FUNCTION__, Testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/misc/BUILD.gn b/src/kernel_liteos_a/testsuites/unittest/libc/misc/BUILD.gn new file mode 100644 index 00000000..77f0f298 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/misc/BUILD.gn @@ -0,0 +1,66 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("./config.gni") + +config("libc_config") { + if (LOSCFG_USER_TEST_LIBC_POSIX_MQUEUE == true || + LOSCFG_USER_TEST_LIBC_POSIX_PTHREAD == true) { + cflags = [ "-O1" ] + cflags_cc = cflags + } +} + +if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_LOW) { + unittest("liteos_a_libc_misc_unittest_door") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + include_dirs = common_include_dirs + sources = sources_entry + sources += sources_smoke + sources_full = [] + sources += sources_full + configs = [ "../..:public_config_for_door" ] + configs += [ ":libc_config" ] + deps = [ "$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR:libsec_shared" ] + } +} + +if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_MIDDLE) { + unittest("liteos_a_libc_misc_unittest") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + include_dirs = common_include_dirs + sources = sources_entry + sources += sources_smoke + sources += sources_full + configs = [ "../..:public_config_for_all" ] + configs += [ ":libc_config" ] + deps = [ "$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR:libsec_shared" ] + } +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/misc/It_test_misc.h b/src/kernel_liteos_a/testsuites/unittest/libc/misc/It_test_misc.h new file mode 100644 index 00000000..a89fbc81 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/misc/It_test_misc.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _IT_TEST_MISC_H +#define _IT_TEST_MISC_H + +#include "osTest.h" +#include "getopt.h" +#include "stdlib.h" +#include "err.h" +#include "unistd.h" +#include "search.h" +#define MISC_OK 0 +#define MISC_NOK (-1) + +extern VOID ItTestMisc001(VOID); +extern VOID ItTestMisc002(VOID); +extern VOID ItTestMisc003(VOID); +extern VOID ItTestMisc004(VOID); +extern VOID ItTestMisc005(VOID); +extern VOID ItTestMisc006(VOID); +extern VOID ItTestMisc007(VOID); +extern VOID ItTestMisc008(VOID); +extern VOID ItTestMisc009(VOID); +extern VOID ItTestMisc010(VOID); +extern VOID ItTestMisc011(VOID); +extern VOID ItTestMisc012(VOID); +extern VOID ItTestMisc013(VOID); +extern VOID IT_TEST_MISC_014(VOID); + +#endif diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/misc/config.gni b/src/kernel_liteos_a/testsuites/unittest/libc/misc/config.gni new file mode 100644 index 00000000..0d34c95f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/misc/config.gni @@ -0,0 +1,74 @@ +# Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//build/lite/config/test.gni") +import("//kernel/liteos_a/liteos.gni") +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +common_include_dirs = [ + "$THIRDPARTY_GOOGLETEST_DIR/googletest/include", + "../../common/include", +] + +sources_entry = [ "../../common/osTest.cpp" ] + +sources_smoke = [] + +sources_full = [] + +libc_misc_include_dirs = [ "$TEST_UNITTEST_DIR/libc/misc" ] + +libc_misc_sources_entry = [ "$TEST_UNITTEST_DIR/libc/misc/misc_test.cpp" ] + +libc_misc_sources_smoke = [ + "$TEST_UNITTEST_DIR/libc/misc/smoke/misc_test_001.cpp", + "$TEST_UNITTEST_DIR/libc/misc/smoke/misc_test_002.cpp", + "$TEST_UNITTEST_DIR/libc/misc/smoke/misc_test_003.cpp", + "$TEST_UNITTEST_DIR/libc/misc/smoke/misc_test_004.cpp", + "$TEST_UNITTEST_DIR/libc/misc/smoke/misc_test_005.cpp", + "$TEST_UNITTEST_DIR/libc/misc/smoke/misc_test_014.cpp", +] + +libc_misc_sources_full = [ + "$TEST_UNITTEST_DIR/libc/misc/full/misc_test_006.cpp", + "$TEST_UNITTEST_DIR/libc/misc/full/misc_test_007.cpp", + "$TEST_UNITTEST_DIR/libc/misc/full/misc_test_008.cpp", + "$TEST_UNITTEST_DIR/libc/misc/full/misc_test_009.cpp", + "$TEST_UNITTEST_DIR/libc/misc/full/misc_test_010.cpp", + "$TEST_UNITTEST_DIR/libc/misc/full/misc_test_011.cpp", + "$TEST_UNITTEST_DIR/libc/misc/full/misc_test_012.cpp", + "$TEST_UNITTEST_DIR/libc/misc/full/misc_test_013.cpp", +] + +# libc misc module +if (LOSCFG_USER_TEST_LIBC_MISC == true) { + common_include_dirs += libc_misc_include_dirs + sources_entry += libc_misc_sources_entry + sources_smoke += libc_misc_sources_smoke + sources_full += libc_misc_sources_full +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/misc/full/misc_test_006.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/misc/full/misc_test_006.cpp new file mode 100644 index 00000000..12241e4f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/misc/full/misc_test_006.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_misc.h" +#include "sys/utsname.h" + +#define INVALID_ADDR_FIRST_PAGE (reinterpret_cast(0x1200000)) +#define INVALID_ADDR_USER_ADDR (reinterpret_cast(0x1000000)) +#define INVALID_ADDR_KERNEL_READONLY_ADDR (reinterpret_cast(0x4016c75c)) + +static UINT32 TestCase(VOID) +{ + int ret; + struct utsname name; + + ret = uname((struct utsname *)NULL); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, EFAULT, errno); + + ret = uname(INVALID_ADDR_FIRST_PAGE); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, EFAULT, errno); + + ret = uname(INVALID_ADDR_USER_ADDR); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, EFAULT, errno); + + ret = uname(INVALID_ADDR_KERNEL_READONLY_ADDR); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, EFAULT, errno); + + ret = uname(&name); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return 0; +} + +VOID ItTestMisc006(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/misc/full/misc_test_007.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/misc/full/misc_test_007.cpp new file mode 100644 index 00000000..c479cfcb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/misc/full/misc_test_007.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_misc.h" + +static UINT32 TestCase(VOID) +{ + int ret; + + ret = sysconf(_SC_AIO_LISTIO_MAX); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + + ret = sysconf(_SC_ARG_MAX); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret); + ret = sysconf(_SC_ATEXIT_MAX); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, -1); + + return 0; +} + +VOID ItTestMisc007(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/misc/full/misc_test_008.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/misc/full/misc_test_008.cpp new file mode 100644 index 00000000..a2ec7a8b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/misc/full/misc_test_008.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_misc.h" + +static UINT32 TestCase(VOID) +{ + char host[100] = {0}; + int ret = 0; + + ret = gethostname(host, sizeof(host)); + + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret); + printf("host = %s\n", host); + + return 0; +} + +VOID ItTestMisc008(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/misc/full/misc_test_009.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/misc/full/misc_test_009.cpp new file mode 100644 index 00000000..cc4c6518 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/misc/full/misc_test_009.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_misc.h" + +STATIC UINT32 TestCase(VOID) +{ + INT32 ret; + CHAR *hostsFileStream = "127.0.0.1 localhost\n192.168.1.3 hisilicon\n::1 localhost\n"; + CHAR *pathList[] = {"/etc/hosts"}; + CHAR *streamList[] = {hostsFileStream}; + INT32 streamLen[] = {strlen(hostsFileStream)}; + + ret = PrepareFileEnv(pathList, streamList, streamLen, 1); + if (ret != 0) { + printf("error: need some env files, but prepare is not ok"); + (VOID)RecoveryFileEnv(pathList, 1); + return -1; + } + + ret = gethostid(); + ICUNIT_GOTO_NOT_EQUAL(ret, -1, ret, ERROUT); + (VOID)RecoveryFileEnv(pathList, 1); + return 0; + +ERROUT: + (VOID)RecoveryFileEnv(pathList, 1); + return -1; +} + +VOID ItTestMisc009(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/misc/full/misc_test_010.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/misc/full/misc_test_010.cpp new file mode 100644 index 00000000..ec0feb9d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/misc/full/misc_test_010.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_misc.h" + +static UINT32 TestCase(VOID) +{ + int ret; + int rlimit = 512; + + ret = getdtablesize(); + ICUNIT_ASSERT_EQUAL(ret, rlimit, ret); + + return 0; +} + +VOID ItTestMisc010(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/misc/full/misc_test_011.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/misc/full/misc_test_011.cpp new file mode 100644 index 00000000..1b849ab5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/misc/full/misc_test_011.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_misc.h" + +static UINT32 TestCase(VOID) +{ + int ret; + struct rlimit rlim; + int limit = 512; + + errno = 0; + ret = getrlimit(RLIMIT_NOFILE, &rlim); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(rlim.rlim_cur, limit, -1); + ret = getrlimit(RLIMIT_RSS, &rlim); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, -1); + + return 0; +} + +VOID ItTestMisc011(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/misc/full/misc_test_012.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/misc/full/misc_test_012.cpp new file mode 100644 index 00000000..32d5ac87 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/misc/full/misc_test_012.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_misc.h" + +static UINT32 TestCase(VOID) +{ + int ret; + struct rlimit rlim1; + struct rlimit rlim2 = {10, 10}; + + errno = 0; + ret = setrlimit(RLIMIT_NOFILE, &rlim2); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret); + ret = getrlimit(RLIMIT_NOFILE, &rlim1); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(rlim1.rlim_cur, rlim2.rlim_cur, ret); + ICUNIT_ASSERT_EQUAL(rlim1.rlim_max, rlim2.rlim_max, ret); + + ret = setrlimit(RLIMIT_FSIZE, &rlim2); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret); + ret = getrlimit(RLIMIT_FSIZE, &rlim1); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(rlim1.rlim_cur, rlim2.rlim_cur, ret); + ICUNIT_ASSERT_EQUAL(rlim1.rlim_max, rlim2.rlim_max, ret); + + ret = setrlimit(RLIMIT_AS, &rlim2); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, -1); + + ret = setrlimit(RLIMIT_DATA, &rlim2); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, -1); + + ret = setrlimit(-100, &rlim2); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, -1); + + return 0; +} + +VOID ItTestMisc012(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/misc/full/misc_test_013.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/misc/full/misc_test_013.cpp new file mode 100644 index 00000000..07fd2f49 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/misc/full/misc_test_013.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_misc.h" +#include "ulimit.h" + +static UINT32 TestCase(VOID) +{ + long ret; + long size = 200; + long max = 0x7fffffff; + + ret = ulimit(UL_SETFSIZE, size); + ICUNIT_ASSERT_EQUAL(ret, size, -1); + + ret = ulimit(UL_GETFSIZE, size); + ICUNIT_ASSERT_EQUAL(ret, size, ret); + + ret = ulimit(size, size); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, ret); + + ret = ulimit(UL_SETFSIZE, max); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, EPERM, ret); + return 0; +} + +VOID ItTestMisc013(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/misc/misc_test.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/misc/misc_test.cpp new file mode 100644 index 00000000..0f34b621 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/misc/misc_test.cpp @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "stdio.h" +#include +#include + +#include "It_test_misc.h" + +using namespace testing::ext; +namespace OHOS { +class MiscTest : public testing::Test { +public: + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} +}; + +#if defined(LOSCFG_USER_TEST_SMOKE) +/* * + * @tc.name: IT_TEST_MISC_001 + * @tc.desc: function for MiscTest + * @tc.type: FUNC + */ +HWTEST_F(MiscTest, ItTestMisc001, TestSize.Level0) +{ + ItTestMisc001(); +} + +/* * + * @tc.name: IT_TEST_MISC_002 + * @tc.desc: function for MiscTest + * @tc.type: FUNC + */ +HWTEST_F(MiscTest, ItTestMisc002, TestSize.Level0) +{ + ItTestMisc002(); +} + +/* * + * @tc.name: IT_TEST_MISC_003 + * @tc.desc: function for MiscTest + * @tc.type: FUNC + */ +HWTEST_F(MiscTest, ItTestMisc003, TestSize.Level0) +{ + ItTestMisc003(); +} + +/* * + * @tc.name: IT_TEST_MISC_004 + * @tc.desc: function for MiscTest + * @tc.type: FUNC + */ +HWTEST_F(MiscTest, ItTestMisc004, TestSize.Level0) +{ + ItTestMisc004(); +} + +/* * + * @tc.name: IT_TEST_MISC_005 + * @tc.desc: function for MiscTest + * @tc.type: FUNC + */ +HWTEST_F(MiscTest, ItTestMisc005, TestSize.Level0) +{ + ItTestMisc005(); +} + +/* * + * @tc.name: IT_TEST_MISC_014 + * @tc.desc: function for tmpnam test + * @tc.type: FUNC + */ +HWTEST_F(MiscTest, IT_TEST_MISC_014, TestSize.Level0) +{ + IT_TEST_MISC_014(); +} +#endif + +#if defined(LOSCFG_USER_TEST_FULL) +/* * + * @tc.name: IT_TEST_MISC_006 + * @tc.desc: function for MiscTest + * @tc.type: FUNC + */ +HWTEST_F(MiscTest, ItTestMisc006, TestSize.Level0) +{ + ItTestMisc006(); +} + +/* * + * @tc.name: IT_TEST_MISC_007 + * @tc.desc: function for MiscTest + * @tc.type: FUNC + */ +HWTEST_F(MiscTest, ItTestMisc007, TestSize.Level0) +{ + ItTestMisc007(); +} + +/* * + * @tc.name: IT_TEST_MISC_008 + * @tc.desc: function for MiscTest + * @tc.type: FUNC + */ +HWTEST_F(MiscTest, ItTestMisc008, TestSize.Level0) +{ + ItTestMisc008(); +} + +/* * + * @tc.name: IT_TEST_MISC_009 + * @tc.desc: function for MiscTest + * @tc.type: FUNC + */ +HWTEST_F(MiscTest, ItTestMisc009, TestSize.Level0) +{ + ItTestMisc009(); +} + +/* * + * @tc.name: IT_TEST_MISC_012 + * @tc.desc: function for MiscTest + * @tc.type: FUNC + */ +HWTEST_F(MiscTest, ItTestMisc012, TestSize.Level0) +{ + ItTestMisc012(); +} +#endif + +} // namespace OHOS diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/misc/smoke/misc_test_001.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/misc/smoke/misc_test_001.cpp new file mode 100644 index 00000000..a2d2a75e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/misc/smoke/misc_test_001.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_misc.h" + +#define TEST_MEMSIZE 8 +static UINT32 TestCase(VOID) +{ + VOID *ptr = NULL; + + ptr = valloc(TEST_MEMSIZE); + ICUNIT_GOTO_NOT_EQUAL(ptr, NULL, ptr, EXIT); + + free(ptr); + + return MISC_OK; +EXIT: + free(ptr); + return MISC_NOK; +} + +VOID ItTestMisc001(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/misc/smoke/misc_test_002.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/misc/smoke/misc_test_002.cpp new file mode 100644 index 00000000..44680381 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/misc/smoke/misc_test_002.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_misc.h" + +#define TEST_OK "success" +#define STR_LEN 20 + +static VOID Vwarnfuc(const char *format, ...) +{ + va_list arglist; + + va_start(arglist, format); + vwarn(format, arglist); + va_end(arglist); +} + +static UINT32 TestCase(VOID) +{ + CHAR ptr[STR_LEN] = TEST_OK; + Vwarnfuc("%s", ptr); + return 0; +} + +VOID ItTestMisc002(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/misc/smoke/misc_test_003.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/misc/smoke/misc_test_003.cpp new file mode 100644 index 00000000..1269a61c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/misc/smoke/misc_test_003.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_misc.h" + +#define TEST_OK "success" +#define STR_LEN 20 + +static VOID Vwarnxfuc(const char *format, ...) +{ + va_list arglist; + + va_start(arglist, format); + vwarnx(format, arglist); + va_end(arglist); +} + +static UINT32 TestCase(VOID) +{ + CHAR ptr[STR_LEN] = TEST_OK; + Vwarnxfuc("%s", ptr); + return 0; +} + +VOID ItTestMisc003(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/misc/smoke/misc_test_004.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/misc/smoke/misc_test_004.cpp new file mode 100644 index 00000000..f692d95f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/misc/smoke/misc_test_004.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_misc.h" + +#define TEST_OK "success" +#define STR_LEN 20 + +static VOID Verrfuc(INT32 fpid, const char *format, ...) +{ + va_list arglist; + + va_start(arglist, format); + verr(fpid, format, arglist); + va_end(arglist); +} + +static UINT32 TestCase(VOID) +{ + CHAR ptr[STR_LEN] = TEST_OK; + INT32 fpid; + + fpid = fork(); + if (fpid == 0) { + Verrfuc(fpid, "%s", ptr); + } + usleep(20); + return 0; +} + +VOID ItTestMisc004(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/misc/smoke/misc_test_005.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/misc/smoke/misc_test_005.cpp new file mode 100644 index 00000000..e377ae48 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/misc/smoke/misc_test_005.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_misc.h" + +#define TEST_OK "success" +#define STR_LEN 20 + +static VOID Verrxfuc(INT32 fpid, const char *format, ...) +{ + va_list arglist; + + va_start(arglist, format); + verrx(fpid, format, arglist); + va_end(arglist); +} + +static UINT32 TestCase(VOID) +{ + CHAR ptr[STR_LEN] = TEST_OK; + INT32 fpid; + + fpid = fork(); + if (fpid == 0) { + Verrxfuc(fpid, "%s", ptr); + } + usleep(20); + return 0; +} + +VOID ItTestMisc005(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/misc/smoke/misc_test_014.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/misc/smoke/misc_test_014.cpp new file mode 100644 index 00000000..1dffbe51 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/misc/smoke/misc_test_014.cpp @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_misc.h" + +static UINT32 TestCase(VOID) +{ + char *name1 = nullptr; + char name2[100] = { 0 }; + char name3[100] = "hello"; + int ret; + + name1 = tmpnam(NULL); + ICUNIT_ASSERT_NOT_EQUAL(name1, nullptr, -1); + ret = strncmp(name1, "/tmp/tmpnam_", 12); + ICUNIT_ASSERT_EQUAL(ret, 0, -1); + + tmpnam(name2); + ICUNIT_ASSERT_NOT_EQUAL(name2[0], 0, -1); + ret = strncmp(name2, "/tmp/tmpnam_", 12); + ICUNIT_ASSERT_EQUAL(ret, 0, -1); + + tmpnam(name2); + ret = strncmp(name2, "/tmp/tmpnam_", 12); + ICUNIT_ASSERT_EQUAL(ret, 0, -1); + + return LOS_OK; +} + +VOID IT_TEST_MISC_014(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/BUILD.gn b/src/kernel_liteos_a/testsuites/unittest/libc/posix/BUILD.gn new file mode 100644 index 00000000..571fce36 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/BUILD.gn @@ -0,0 +1,66 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("./config.gni") + +config("libc_config") { + if (LOSCFG_USER_TEST_LIBC_POSIX_MQUEUE == true || + LOSCFG_USER_TEST_LIBC_POSIX_PTHREAD == true) { + cflags = [ "-O1" ] + cflags_cc = cflags + } +} + +if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_LOW) { + unittest("liteos_a_libc_posix_unittest_door") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + include_dirs = common_include_dirs + sources = sources_entry + sources += sources_smoke + sources_full = [] + sources += sources_full + configs = [ "../..:public_config_for_door" ] + configs += [ ":libc_config" ] + deps = [ "$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR:libsec_shared" ] + } +} + +if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_MIDDLE) { + unittest("liteos_a_libc_posix_unittest") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + include_dirs = common_include_dirs + sources = sources_entry + sources += sources_smoke + sources += sources_full + configs = [ "../..:public_config_for_all" ] + configs += [ ":libc_config" ] + deps = [ "$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR:libsec_shared" ] + } +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/config.gni b/src/kernel_liteos_a/testsuites/unittest/libc/posix/config.gni new file mode 100644 index 00000000..1d1a8adb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/config.gni @@ -0,0 +1,69 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//build/lite/config/test.gni") +import("//kernel/liteos_a/liteos.gni") +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +common_include_dirs = [ + "$THIRDPARTY_GOOGLETEST_DIR/googletest/include", + "../../common/include", +] + +sources_entry = [ "../../common/osTest.cpp" ] + +sources_smoke = [] + +sources_full = [] + +# libc posix mem module +if (LOSCFG_USER_TEST_LIBC_POSIX_MEM == true) { + import("./mem/config.gni") + common_include_dirs += libc_posix_mem_include_dirs + sources_entry += libc_posix_mem_sources_entry + sources_smoke += libc_posix_mem_sources_smoke + sources_full += libc_posix_mem_sources_full +} + +# libc posix mqueue module +if (LOSCFG_USER_TEST_LIBC_POSIX_MQUEUE == true) { + import("./mqueue/config.gni") + common_include_dirs += libc_posix_mqueue_include_dirs + sources_entry += libc_posix_mqueue_sources_entry + sources_smoke += libc_posix_mqueue_sources_smoke + sources_full += libc_posix_mqueue_sources_full +} + +# libc posix pthread module +if (LOSCFG_USER_TEST_LIBC_POSIX_PTHREAD == true) { + import("./pthread/config.gni") + common_include_dirs += libc_posix_pthread_include_dirs + sources_entry += libc_posix_pthread_sources_entry + sources_smoke += libc_posix_pthread_sources_smoke + sources_full += libc_posix_pthread_sources_full +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mem/It_posix_mem.h b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mem/It_posix_mem.h new file mode 100644 index 00000000..fcc832d5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mem/It_posix_mem.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _IT_POSIX_MEM_H +#define _IT_POSIX_MEM_H + +#include "osTest.h" + +#if defined(LOSCFG_USER_TEST_SMOKE) +VOID ItPosixMem001(VOID); +VOID IT_POSIX_MEM_002(VOID); +VOID ItPosixMem003(VOID); +#endif + +#endif /* _IT_POSIX_MEM_H */ diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mem/config.gni b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mem/config.gni new file mode 100644 index 00000000..04322d7e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mem/config.gni @@ -0,0 +1,42 @@ +# Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//build/lite/config/test.gni") +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +libc_posix_mem_include_dirs = [ "$TEST_UNITTEST_DIR/libc/posix/mem" ] + +libc_posix_mem_sources_entry = + [ "$TEST_UNITTEST_DIR/libc/posix/mem/posix_mem_test.cpp" ] + +libc_posix_mem_sources_smoke = [ + "$TEST_UNITTEST_DIR/libc/posix/mem/smoke/It_posix_mem_001.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mem/smoke/It_posix_mem_003.cpp", +] + +libc_posix_mem_sources_full = [] diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mem/posix_mem_test.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mem/posix_mem_test.cpp new file mode 100644 index 00000000..c2f6c5ed --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mem/posix_mem_test.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "stdio.h" +#include +#include + +#include "It_posix_mem.h" + + +using namespace testing::ext; +namespace OHOS { +class PosixMemTest : public testing::Test { +public: + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} +}; + +#if defined(LOSCFG_USER_TEST_SMOKE) +/* * + * @tc.name: IT_POSIX_MEM_001 + * @tc.desc: function for PosixMemTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMemTest, ItPosixMem001, TestSize.Level0) +{ + ItPosixMem001(); +} + +/* * + * @tc.name: IT_POSIX_MEM_003 + * @tc.desc: function for PosixMemTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMemTest, ItPosixMem003, TestSize.Level0) +{ + ItPosixMem003(); +} + +#endif +} // namespace OHOS diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mem/smoke/It_posix_mem_001.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mem/smoke/It_posix_mem_001.cpp new file mode 100644 index 00000000..8dcc876f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mem/smoke/It_posix_mem_001.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_mem.h" + +/* * + * @test IT_POSIX_MEMALIGN_001 + * -@tspec posix_memalign API test + * -@ttitle The alignment argument was not a power of two, or was not a multiple of sizeof(void *) + * -@tprecon dynamic memory function open + * -@tbrief + * -#alignment == 0,2,3,7,15,31,63 + * -@texpect + * -#return EINVAL + * -#return EINVAL + * -@tprior 1 + * -@tauto TRUE + * -@tremark + */ +static UINT32 Testcase(VOID) +{ + int ret; + size_t size = 0x100; + void *p = nullptr; + + ret = posix_memalign(&p, 0, size); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + ICUNIT_ASSERT_EQUAL(p, nullptr, p); + + ret = posix_memalign(&p, 2, size); // 2, alignment + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + ICUNIT_ASSERT_EQUAL(p, nullptr, p); + + for (UINT32 n = 2; n < 7; n++) { // 2, 7, alignment + ret = posix_memalign(&p, ((1 << n) - 1), size); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + ICUNIT_ASSERT_EQUAL(p, nullptr, p); + } + + return 0; +} + + +VOID ItPosixMem001(void) +{ + TEST_ADD_CASE("IT_POSIX_MEM_001", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mem/smoke/It_posix_mem_003.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mem/smoke/It_posix_mem_003.cpp new file mode 100644 index 00000000..8bf8404b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mem/smoke/It_posix_mem_003.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_mem.h" + +/* * + * @test IT_POSIX_MEMALIGN_003 + * -@tspec posix_memalign Function test + * -@ttitle The alignment argument was a power of two + * -@tprecon dynamic memory function open + * -@tbrief + * -#alignment == 4,8,16,32,64 + * -@texpect + * -#return EINVAL + * -#return EINVAL + * -@tprior 1 + * -@tauto TRUE + * -@tremark + */ +static UINT32 Testcase(VOID) +{ + int ret; + size_t align = sizeof(UINTPTR); + size_t size = 0x100; + void *p = nullptr; + + for (align = sizeof(UINTPTR); align <= 64; align <<= 1) { // 64, alignment + ret = posix_memalign(&p, align, size); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_NOT_EQUAL(p, nullptr, p); + + free(p); + } + + return 0; +} + +VOID ItPosixMem003(void) +{ + TEST_ADD_CASE("IT_POSIX_MEM_003", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/It_posix_queue.h b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/It_posix_queue.h new file mode 100644 index 00000000..06471361 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/It_posix_queue.h @@ -0,0 +1,278 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef IT_POSIX_QUEUE_H +#define IT_POSIX_QUEUE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAXMSG5 5 +#define MSGLEN 10 +#define MAXMSG 10 + +const int MQUEUE_SHORT_ARRAY_LENGTH = 10; // = strlen(MQUEUE_SEND_STRING_TEST) +const int MQUEUE_STANDARD_NAME_LENGTH = 50; + +#define MQUEUE_NO_ERROR 0 +#define MQUEUE_IS_ERROR (-1) +#define MQUEUE_PTHREAD_PRIORITY_TEST1 3 +#define MQUEUE_PTHREAD_PRIORITY_TEST2 4 +#define MQUEUE_PATH_MAX_TEST PATH_MAX +#define MQUEUE_NAME_MAX_TEST NAME_MAX +#define MQUEUE_SEND_STRING_TEST "0123456789" +#define MQUEUE_PTHREAD_NUM_TEST 5 +#define MQUEUE_PRIORITY_TEST 0 +#define MQUEUE_TIMEOUT_TEST 7 +#define MQUEUE_PRIORITY_NUM_TEST 3 +#define MQUEUE_MAX_NUM_TEST (LOSCFG_BASE_IPC_QUEUE_CONFIG - QUEUE_EXISTED_NUM) +#define MQ_MAX_MSG_NUM 16 +#define MQ_MAX_MSG_LEN 64 +#define HWI_NUM_TEST 1 +#define HWI_NUM_TEST1 2 +#define LOS_WAIT_FOREVER 0XFFFFFFFF + +typedef VOID (*HWI_PROC_FUNC)(VOID *pParm); + +#define MQ_VALID_MAGIC 0x6db256c1 +const int LOSCFG_BASE_IPC_QUEUE_CONFIG = 1024; + +#ifdef __LP64__ +#define PER_ADDED_VALUE 8 +#else +#define PER_ADDED_VALUE 4 +#endif + +typedef UINT32 TSK_HANDLE_T; +using SEM_HANDLE_T = UINT32; +extern SEM_HANDLE_T g_mqueueSem; + +static TSK_HANDLE_T g_mqueueTaskPID; +extern CHAR g_gqname[MQUEUE_STANDARD_NAME_LENGTH]; +extern CHAR g_mqueueName[LOSCFG_BASE_IPC_QUEUE_CONFIG + 1][MQUEUE_STANDARD_NAME_LENGTH]; +extern mqd_t g_mqueueId[LOSCFG_BASE_IPC_QUEUE_CONFIG + 1]; + +extern CHAR *g_mqueueMsessage[MQUEUE_SHORT_ARRAY_LENGTH]; +extern mqd_t g_messageQId; +extern mqd_t g_gqueue; + +extern unsigned long MsecsToJiffies(const unsigned int m); + +extern VOID ItSuite_Posix_Mqueue(VOID); +extern UINT32 LosCurTaskIDGet(); +extern int LOS_AtomicInc(const volatile unsigned int *num); +extern int LosSemDelete(SEM_HANDLE_T num); +extern int LosSemCreate(int num, const SEM_HANDLE_T *hdl); +extern UINT32 PosixPthreadInit(pthread_attr_t *attr, int pri); +extern void LOS_TaskUnlock(); +extern void LOS_TaskLock(); +extern int LosSemPost(SEM_HANDLE_T); +extern int LosSemPend(SEM_HANDLE_T hdl, int num); +extern int SemPost(SEM_HANDLE_T); +extern int SemPend(SEM_HANDLE_T hdl, int num); +extern int LOS_HwiCreate(int hwiNum, int hwiPrio, int hwiMode, HWI_PROC_FUNC hwiHandler, int *irqParam); +extern UINT64 JiffiesToTick(unsigned long j); +extern int HalIrqMask(int num); +extern UINT32 PosixPthreadDestroy(pthread_attr_t *attr, pthread_t thread); + +#define LOS_TaskLock() +#define LOS_TaskUnlock() +#define LOS_AtomicInc(a) (++*(a)) +#define TEST_TEST_HwiDelete(ID, NULL) + +#if defined(LOSCFG_USER_TEST_SMOKE) +VOID ItPosixQueue001(VOID); +VOID ItPosixQueue003(VOID); +VOID ItPosixQueue028(VOID); +VOID ItPosixQueue062(VOID); +VOID ItPosixQueue053(VOID); +VOID ItPosixQueue144(VOID); +#endif + +#if defined(LOSCFG_USER_TEST_FULL) +VOID ItPosixQueue002(VOID); +VOID ItPosixQueue004(VOID); +VOID ItPosixQueue005(VOID); +VOID ItPosixQueue007(VOID); +VOID ItPosixQueue008(VOID); +VOID ItPosixQueue010(VOID); +VOID ItPosixQueue011(VOID); +VOID ItPosixQueue012(VOID); +VOID ItPosixQueue013(VOID); +VOID ItPosixQueue014(VOID); +VOID ItPosixQueue015(VOID); +VOID ItPosixQueue016(VOID); +VOID ItPosixQueue017(VOID); +VOID ItPosixQueue018(VOID); +VOID ItPosixQueue019(VOID); +VOID ItPosixQueue020(VOID); +VOID ItPosixQueue021(VOID); +VOID ItPosixQueue025(VOID); +VOID ItPosixQueue026(VOID); +VOID ItPosixQueue027(VOID); +VOID ItPosixQueue030(VOID); +VOID ItPosixQueue031(VOID); +VOID ItPosixQueue032(VOID); +VOID ItPosixQueue033(VOID); +VOID ItPosixQueue036(VOID); +VOID ItPosixQueue037(VOID); +VOID ItPosixQueue038(VOID); +VOID ItPosixQueue039(VOID); +VOID ItPosixQueue040(VOID); +VOID ItPosixQueue041(VOID); +VOID ItPosixQueue042(VOID); +VOID ItPosixQueue044(VOID); +VOID ItPosixQueue046(VOID); +VOID ItPosixQueue047(VOID); +VOID ItPosixQueue048(VOID); +VOID ItPosixQueue049(VOID); +VOID ItPosixQueue050(VOID); +VOID ItPosixQueue052(VOID); +VOID ItPosixQueue054(VOID); +VOID ItPosixQueue055(VOID); +VOID ItPosixQueue056(VOID); +VOID ItPosixQueue057(VOID); +VOID ItPosixQueue058(VOID); +VOID ItPosixQueue060(VOID); +VOID ItPosixQueue061(VOID); +VOID ItPosixQueue063(VOID); +VOID ItPosixQueue064(VOID); +VOID ItPosixQueue065(VOID); +VOID ItPosixQueue066(VOID); +VOID ItPosixQueue067(VOID); +VOID ItPosixQueue069(VOID); +VOID ItPosixQueue070(VOID); +VOID ItPosixQueue071(VOID); +VOID ItPosixQueue072(VOID); +VOID ItPosixQueue073(VOID); +VOID ItPosixQueue074(VOID); +VOID ItPosixQueue075(VOID); +VOID ItPosixQueue076(VOID); +VOID ItPosixQueue077(VOID); +VOID ItPosixQueue078(VOID); +VOID ItPosixQueue079(VOID); +VOID ItPosixQueue080(VOID); +VOID ItPosixQueue081(VOID); +VOID ItPosixQueue082(VOID); +VOID ItPosixQueue083(VOID); +VOID ItPosixQueue084(VOID); +VOID ItPosixQueue085(VOID); +VOID ItPosixQueue086(VOID); +VOID ItPosixQueue087(VOID); +VOID ItPosixQueue088(VOID); +VOID ItPosixQueue089(VOID); +VOID ItPosixQueue090(VOID); +VOID ItPosixQueue091(VOID); +VOID ItPosixQueue093(VOID); +VOID ItPosixQueue094(VOID); +VOID ItPosixQueue095(VOID); +VOID ItPosixQueue096(VOID); +VOID ItPosixQueue097(VOID); +VOID ItPosixQueue098(VOID); +VOID ItPosixQueue100(VOID); +VOID ItPosixQueue101(VOID); +VOID ItPosixQueue102(VOID); +VOID ItPosixQueue103(VOID); +VOID ItPosixQueue104(VOID); +VOID ItPosixQueue106(VOID); +VOID ItPosixQueue108(VOID); +VOID ItPosixQueue109(VOID); +VOID ItPosixQueue110(VOID); +VOID ItPosixQueue111(VOID); +VOID ItPosixQueue112(VOID); +VOID ItPosixQueue113(VOID); +VOID ItPosixQueue114(VOID); +VOID ItPosixQueue115(VOID); +VOID ItPosixQueue116(VOID); +VOID ItPosixQueue117(VOID); +VOID ItPosixQueue118(VOID); +VOID ItPosixQueue119(VOID); +VOID ItPosixQueue120(VOID); +VOID ItPosixQueue121(VOID); +VOID ItPosixQueue122(VOID); +VOID ItPosixQueue123(VOID); +VOID ItPosixQueue124(VOID); +VOID ItPosixQueue125(VOID); +VOID ItPosixQueue126(VOID); +VOID ItPosixQueue127(VOID); +VOID ItPosixQueue128(VOID); +VOID ItPosixQueue129(VOID); +VOID ItPosixQueue130(VOID); +VOID ItPosixQueue133(VOID); +VOID ItPosixQueue134(VOID); +VOID ItPosixQueue136(VOID); +VOID ItPosixQueue143(VOID); +VOID ItPosixQueue145(VOID); +VOID ItPosixQueue146(VOID); +VOID ItPosixQueue147(VOID); +VOID ItPosixQueue148(VOID); +VOID ItPosixQueue149(VOID); +VOID ItPosixQueue150(VOID); +VOID ItPosixQueue151(VOID); +VOID ItPosixQueue152(VOID); +VOID ItPosixQueue153(VOID); +VOID ItPosixQueue154(VOID); +VOID ItPosixQueue155(VOID); +VOID ItPosixQueue156(VOID); +VOID ItPosixQueue160(VOID); +VOID ItPosixQueue161(VOID); +VOID ItPosixQueue162(VOID); +VOID ItPosixQueue163(VOID); +VOID ItPosixQueue164(VOID); +VOID ItPosixQueue165(VOID); +VOID ItPosixQueue166(VOID); +VOID ItPosixQueue168(VOID); +VOID ItPosixQueue169(VOID); +VOID ItPosixQueue173(VOID); +VOID ItPosixQueue175(VOID); +VOID ItPosixQueue176(VOID); +VOID ItPosixQueue187(VOID); + +VOID ItPosixQueue200(VOID); +VOID ItPosixQueue201(VOID); +VOID ItPosixQueue202(VOID); +VOID ItPosixQueue203(VOID); +VOID ItPosixQueue204(VOID); + +VOID ItPosixQueue205(VOID); +VOID ItPosixQueue206(VOID); +VOID ItPosixQueue207(VOID); +VOID ItPosixQueue208(VOID); +VOID ItPosixQueue209(VOID); +#endif +#endif diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/config.gni b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/config.gni new file mode 100644 index 00000000..b272dd43 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/config.gni @@ -0,0 +1,191 @@ +# Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//build/lite/config/test.gni") +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +libc_posix_mqueue_include_dirs = [ "$TEST_UNITTEST_DIR/libc/posix/mqueue" ] + +libc_posix_mqueue_sources_entry = + [ "$TEST_UNITTEST_DIR/libc/posix/mqueue/posix_mqueue_test.cpp" ] + +libc_posix_mqueue_sources_smoke = [ + "$TEST_UNITTEST_DIR/libc/posix/mqueue/smoke/It_posix_queue_001.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/smoke/It_posix_queue_003.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/smoke/It_posix_queue_028.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/smoke/It_posix_queue_053.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/smoke/It_posix_queue_062.cpp", +] + +libc_posix_mqueue_sources_full = [ + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_002.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_005.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_008.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_011.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_013.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_014.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_015.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_016.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_018.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_019.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_020.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_021.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_025.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_026.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_027.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_030.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_031.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_032.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_033.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_036.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_038.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_040.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_041.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_042.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_043.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_044.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_046.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_047.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_048.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_049.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_050.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_052.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_054.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_055.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_056.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_057.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_058.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_060.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_061.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_063.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_064.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_065.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_066.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_067.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_069.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_070.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_071.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_072.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_073.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_074.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_075.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_076.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_077.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_078.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_079.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_080.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_081.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_082.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_083.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_084.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_085.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_086.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_087.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_088.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_089.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_090.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_091.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_093.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_094.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_095.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_096.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_097.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_098.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_100.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_101.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_102.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_103.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_104.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_106.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_108.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_109.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_110.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_111.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_112.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_113.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_114.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_115.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_116.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_117.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_118.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_119.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_120.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_121.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_122.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_123.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_124.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_125.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_126.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_127.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_128.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_129.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_130.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_133.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_134.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_136.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_143.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_144.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_145.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_146.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_147.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_148.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_149.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_150.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_151.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_152.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_153.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_154.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_155.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_156.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_157.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_159.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_160.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_161.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_162.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_163.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_164.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_165.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_166.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_168.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_169.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_173.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_175.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_176.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_177.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_187.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_200.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_201.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_202.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_203.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_204.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_205.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_206.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_207.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_208.cpp", + "$TEST_UNITTEST_DIR/libc/posix/mqueue/full/It_posix_queue_209.cpp", +] diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_002.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_002.cpp new file mode 100644 index 00000000..55109fe7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_002.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + struct mq_attr attr = {0}; + mqd_t mqueue; + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = 1; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, + "/mq002_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT2); + + ret = mq_send(mqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_receive(mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT1); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, MQUEUE_SEND_STRING_TEST, msgrcd, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + return MQUEUE_NO_ERROR; + +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_IS_ERROR; +} + +VOID ItPosixQueue002(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_002", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_005.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_005.cpp new file mode 100644 index 00000000..93c2dfb3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_005.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + mqd_t mqueue; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, + "/mq005_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + mqueue = mq_open(mqname, O_RDWR, S_IRUSR | S_IWUSR, NULL); + ICUNIT_GOTO_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT); + ICUNIT_ASSERT_EQUAL(errno, ENOENT, errno); + + return MQUEUE_NO_ERROR; + +EXIT: + mq_close(mqueue); + mq_unlink(mqname); +EXIT1: + return MQUEUE_IS_ERROR; +} + +VOID ItPosixQueue005(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_005", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_008.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_008.cpp new file mode 100644 index 00000000..6e7ca3cb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_008.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + mqd_t roqueue, roqueue2; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, + "/mq008_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + roqueue = mq_open(mqname, O_CREAT | O_RDONLY, S_IRUSR | S_IWUSR, NULL); + ICUNIT_GOTO_NOT_EQUAL(roqueue, (mqd_t)-1, roqueue, EXIT2); + + roqueue2 = mq_open(mqname, O_RDONLY, S_IRUSR | S_IWUSR, NULL); + ICUNIT_GOTO_NOT_EQUAL(roqueue2, (mqd_t)-1, roqueue2, EXIT); + + ret = mq_close(roqueue2); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_close(roqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT3); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(roqueue2); +EXIT: + mq_close(roqueue); +EXIT3: + mq_unlink(mqname); +EXIT2: + return MQUEUE_IS_ERROR; +} + +VOID ItPosixQueue008(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_008", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_011.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_011.cpp new file mode 100644 index 00000000..b6c6c7bf --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_011.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + CHAR msgrcd2[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + mqd_t rdwrqueue, rdwrqueue2; + struct mq_attr attr = {0}; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, + "/mq011_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + rdwrqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(rdwrqueue, (mqd_t)-1, rdwrqueue, EXIT2); + + ret = mq_send(rdwrqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_receive(rdwrqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, strlen(msgptr), ret, EXIT); + + rdwrqueue2 = mq_open(mqname, O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(rdwrqueue2, (mqd_t)-1, rdwrqueue2, EXIT); + + ret = mq_send(rdwrqueue2, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_receive(rdwrqueue2, msgrcd2, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, strlen(msgptr), ret, EXIT1); + + ret = mq_close(rdwrqueue2); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = mq_close(rdwrqueue); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT3); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT2); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(rdwrqueue2); +EXIT: + mq_close(rdwrqueue); +EXIT3: + mq_unlink(mqname); +EXIT2: + return MQUEUE_IS_ERROR; +} + +VOID ItPosixQueue011(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_011", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_013.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_013.cpp new file mode 100644 index 00000000..8c856b0c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_013.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret = 0; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + mqd_t mqueue1, mqueue2; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, + "/mq013_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT3); + + mqueue1 = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, NULL); + ICUNIT_GOTO_NOT_EQUAL(mqueue1, (mqd_t)-1, mqueue1, EXIT3); + + ret = mq_send(mqueue1, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + mqueue2 = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, NULL); + ICUNIT_GOTO_NOT_EQUAL(mqueue2, (mqd_t)-1, mqueue2, EXIT1); + + ret = mq_send(mqueue2, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = mq_close(mqueue2); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_close(mqueue1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT3); + + return MQUEUE_NO_ERROR; +EXIT2: + mq_close(mqueue2); +EXIT1: + mq_close(mqueue1); +EXIT: + mq_unlink(mqname); +EXIT3: + return MQUEUE_IS_ERROR; +} + +VOID ItPosixQueue013(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_013", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_014.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_014.cpp new file mode 100644 index 00000000..204f6e83 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_014.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + mqd_t mqueue; + struct mq_attr attr = {0}; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, + "/mq014_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, NULL); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT2); + + ret = mq_getattr(mqueue, &attr); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(attr.mq_curmsgs, 0, attr.mq_curmsgs, EXIT1); + ICUNIT_GOTO_EQUAL(attr.mq_flags, O_CREAT | O_RDWR, attr.mq_flags, EXIT1); + ICUNIT_GOTO_EQUAL(attr.mq_maxmsg, MQ_MAX_MSG_NUM, attr.mq_maxmsg, EXIT1); + ICUNIT_GOTO_EQUAL(attr.mq_msgsize, MQ_MAX_MSG_LEN, attr.mq_msgsize, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_IS_ERROR; +} + +VOID ItPosixQueue014(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_014", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_015.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_015.cpp new file mode 100644 index 00000000..6a1bec47 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_015.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + mqd_t mqueue; + struct mq_attr attr = {0}; + struct mq_attr attrget; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, + "/mq015_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + attr.mq_maxmsg = MQUEUE_SHORT_ARRAY_LENGTH; + attr.mq_msgsize = 5; // 5, queue message size. + mqueue = mq_open(mqname, O_CREAT | O_RDWR | O_NONBLOCK, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT2); + + ret = mq_getattr(mqueue, &attrget); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(attrget.mq_curmsgs, 0, attrget.mq_curmsgs, EXIT1); + ICUNIT_GOTO_EQUAL(attrget.mq_flags, O_CREAT | O_RDWR | O_NONBLOCK, attrget.mq_flags, EXIT1); + ICUNIT_GOTO_EQUAL(attrget.mq_maxmsg, attr.mq_maxmsg, attrget.mq_maxmsg, EXIT1); + ICUNIT_GOTO_EQUAL(attrget.mq_msgsize, attr.mq_msgsize, attrget.mq_msgsize, EXIT1); + + ICUNIT_GOTO_NOT_EQUAL(attrget.mq_flags & O_NONBLOCK, 0, MQUEUE_IS_ERROR, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_IS_ERROR; +} + +VOID ItPosixQueue015(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_015", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_016.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_016.cpp new file mode 100644 index 00000000..51704024 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_016.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + mqd_t mqueue1, mqueue2; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, + "/mq016_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT3); + + mqueue1 = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, NULL); + ICUNIT_GOTO_NOT_EQUAL(mqueue1, (mqd_t)-1, mqueue1, EXIT3); + + mqueue2 = mq_open(mqname, O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR, NULL); + ICUNIT_GOTO_EQUAL(mqueue2, (mqd_t)-1, mqueue2, EXIT1); + + ret = mq_close(mqueue1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT3); + + return MQUEUE_NO_ERROR; +EXIT2: + mq_close(mqueue2); +EXIT1: + mq_close(mqueue1); +EXIT: + mq_unlink(mqname); +EXIT3: + return MQUEUE_IS_ERROR; +} + +VOID ItPosixQueue016(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_016", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_018.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_018.cpp new file mode 100644 index 00000000..0b852457 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_018.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + mqd_t mqueue; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, + "/mq018_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + mqueue = mq_open(mqname, O_CREAT | O_RDWR | O_NONBLOCK, S_IRUSR | S_IWUSR, NULL); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT2); + + ret = mq_send(mqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_IS_ERROR; +} + +VOID ItPosixQueue018(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_018", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_019.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_019.cpp new file mode 100644 index 00000000..85f36f04 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_019.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + mqd_t mqueue1, mqueue2; + struct mq_attr attr = {0}; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, + "/mq019_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT3); + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + mqueue1 = mq_open(mqname, O_CREAT | O_RDWR | O_NONBLOCK, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue1, (mqd_t)-1, mqueue1, EXIT3); + + ret = mq_receive(mqueue1, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + + ret = mq_send(mqueue1, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + mqueue2 = mq_open(mqname, O_RDWR | O_NONBLOCK, S_IRUSR | S_IWUSR, NULL); + ICUNIT_GOTO_NOT_EQUAL(mqueue1, (mqd_t)-1, mqueue1, EXIT1); + + ret = mq_receive(mqueue1, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, strlen(msgptr), ret, EXIT2); + + ret = mq_close(mqueue1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = mq_close(mqueue2); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; + +EXIT2: + mq_close(mqueue2); +EXIT1: + mq_close(mqueue1); +EXIT: + mq_unlink(mqname); +EXIT3: + return MQUEUE_IS_ERROR; +} + +VOID ItPosixQueue019(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_019", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_020.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_020.cpp new file mode 100644 index 00000000..7b2d9aa6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_020.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + mqd_t mqueue; + struct sigevent ev; + struct sigaction act; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, + "/mq020_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, NULL); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT2); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_IS_ERROR; +} + +VOID ItPosixQueue020(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_020", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_021.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_021.cpp new file mode 100644 index 00000000..2a48378a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_021.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + mqd_t mqueue; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, + "/mq021_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + + mqueue = mq_open(mqname, O_RDWR, S_IRUSR | S_IWUSR, NULL); + ICUNIT_GOTO_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT); + + return MQUEUE_NO_ERROR; + +EXIT: + mq_close(mqueue); + mq_unlink(mqname); +EXIT1: + return MQUEUE_IS_ERROR; +} + +VOID ItPosixQueue021(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_021", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_025.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_025.cpp new file mode 100644 index 00000000..40f6dfea --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_025.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +#define QUEUE_NAME_MAX_LEN (MQUEUE_NAME_MAX_TEST * 2) + +static UINT32 Testcase(VOID) +{ + CHAR mqname[QUEUE_NAME_MAX_LEN]; + mqd_t mqueue; + UINT32 ret; + INT32 i; + + ret = snprintf_s(mqname, QUEUE_NAME_MAX_LEN, QUEUE_NAME_MAX_LEN - 1, \ + "/mq025_%d", LosCurTaskIDGet()); // 2, mqname length. + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + + for (i = 0; i < MQUEUE_NAME_MAX_TEST; i++) { + ret = strcat_s(mqname, QUEUE_NAME_MAX_LEN, "0"); + ICUNIT_ASSERT_EQUAL(ret, EOK, ret); + } + + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, NULL); + ICUNIT_GOTO_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT); + ICUNIT_ASSERT_EQUAL(errno, ENAMETOOLONG, errno); + + return MQUEUE_NO_ERROR; +EXIT: + mq_close(mqueue); + mq_unlink(mqname); +EXIT1: + return MQUEUE_IS_ERROR; +} + +VOID ItPosixQueue025(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_025", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_026.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_026.cpp new file mode 100644 index 00000000..7f268459 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_026.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + CHAR qname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + mqd_t queue; + + ret = snprintf_s(qname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq026-1_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + + queue = mq_open(qname, O_RDWR, S_IRUSR | S_IWUSR, NULL); + ICUNIT_GOTO_EQUAL(queue, (mqd_t)-1, queue, EXIT); + ICUNIT_ASSERT_EQUAL(errno, ENOENT, errno); + + return MQUEUE_NO_ERROR; +EXIT: + mq_close(queue); + mq_unlink(qname); +EXIT1: + return MQUEUE_IS_ERROR; +} + +VOID ItPosixQueue026(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_026", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_027.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_027.cpp new file mode 100644 index 00000000..ecaa52a2 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_027.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + CHAR qname[MQUEUE_STANDARD_NAME_LENGTH]; + INT32 ret; + mqd_t queue; + + ret = snprintf_s(qname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq027-1_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + + queue = mq_open(qname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, NULL); + ICUNIT_ASSERT_NOT_EQUAL(queue, (mqd_t)-1, queue); + + ret = mq_close(queue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = mq_unlink(qname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + return MQUEUE_NO_ERROR; +EXIT: + mq_close(queue); +EXIT2: + mq_unlink(qname); +EXIT1: + return MQUEUE_IS_ERROR; +} + +VOID ItPosixQueue027(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_027", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_030.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_030.cpp new file mode 100644 index 00000000..f867ddfa --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_030.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + ret = mq_close((mqd_t)-1); // -1: an invalid argument + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ICUNIT_ASSERT_EQUAL(errno, EBADF, errno); + + return MQUEUE_NO_ERROR; +EXIT: + return MQUEUE_IS_ERROR; +} + +VOID ItPosixQueue030(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_030", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_031.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_031.cpp new file mode 100644 index 00000000..532481b5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_031.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + struct timespec ts; + mqd_t mqueue; + struct mq_attr attr = {0}; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq031_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_SHORT_ARRAY_LENGTH; + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT2); + + ts.tv_sec = 1; + ts.tv_nsec = 0; + ret = mq_timedsend(mqueue, msgptr, strlen(msgptr), 0, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_receive(mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT1); + + ret = strncmp(msgptr, msgrcd, strlen(msgptr)); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_IS_ERROR; +} + +VOID ItPosixQueue031(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_031", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_032.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_032.cpp new file mode 100644 index 00000000..c6fc107e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_032.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + mqd_t mqueue; + struct sigevent se; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, + "/mq032_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, NULL); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT2); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_IS_ERROR; +} + +VOID ItPosixQueue032(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_032", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_033.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_033.cpp new file mode 100644 index 00000000..71d7327e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_033.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + mqd_t mqueue; + struct mq_attr attr = {0}; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq033_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_SHORT_ARRAY_LENGTH; + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT2); + + ret = mq_send(mqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_receive(mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT1); + + ret = strncmp(msgptr, msgrcd, strlen(msgptr)); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_IS_ERROR; +} + +VOID ItPosixQueue033(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_033", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_036.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_036.cpp new file mode 100644 index 00000000..789e29a0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_036.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + struct timespec ts; + mqd_t mqueue; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq036_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, NULL); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT2); + + ts.tv_sec = 1; + ts.tv_nsec = 0; + ret = mq_timedsend(mqueue, msgptr, strlen(msgptr), MQ_PRIO_MAX + 1, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_IS_ERROR; +} + +VOID ItPosixQueue036(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_036", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_038.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_038.cpp new file mode 100644 index 00000000..cb56bbb0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_038.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + mqd_t mqueue; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq038_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, NULL); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT2); + + ret = mq_send(mqueue, msgptr, strlen(msgptr), MQ_PRIO_MAX); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_IS_ERROR; +} + +VOID ItPosixQueue038(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_038", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_040.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_040.cpp new file mode 100644 index 00000000..b857eb0c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_040.cpp @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +__attribute__((optnone)) static VOID *PthreadF01(VOID *argument) +{ + INT32 i; + INT32 ret; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + + g_testCount = 1; + + g_mqueueTaskPID = LosCurTaskIDGet(); + + for (i = 0; i < 5 + 1; i++) { // 5, The loop frequency. + ret = mq_send(g_gqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + } + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, Here, assert the g_testCount. + + g_testCount = 2; // 2, Init test count value. + + return NULL; +EXIT: + g_testCount = 0; + return NULL; +} + +__attribute__((optnone)) static VOID *PthreadF02(VOID *argument) +{ + INT32 j, ret; + + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = ""; + + g_testCount = 3; // 3, Init test count value. + + ret = mq_receive(g_gqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, strlen(MQUEUE_SEND_STRING_TEST), ret, EXIT); + + ret = mq_close(g_gqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(g_gqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + g_testCount = 4; // 4, Init test count value. + + return NULL; +EXIT: + g_testCount = 0; + return NULL; +} + +__attribute__((optnone)) static UINT32 Testcase(VOID) +{ + pthread_t newTh1, newTh2; + UINT32 ret; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = ""; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + struct mq_attr attr = {0}; + pthread_attr_t attr1; + + ret = snprintf_s(g_gqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq040_%d", getpid()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT3); + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = 5; // 5, queue max message size. + + g_testCount = 0; + + g_gqueue = mq_open(g_gqname, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(g_gqueue, (mqd_t)-1, g_gqueue, EXIT3); + + ret = PosixPthreadInit(&attr1, MQUEUE_PTHREAD_PRIORITY_TEST1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = pthread_create(&newTh1, &attr1, PthreadF01, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + LosTaskDelay(5); // 5, Set delay time. + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT1); + + ret = PosixPthreadInit(&attr1, MQUEUE_PTHREAD_PRIORITY_TEST2); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = pthread_create(&newTh2, &attr1, PthreadF02, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = LosTaskDelay(5); // 5, Set delay time. + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT2); // 4, Here, assert the g_testCount. + + ret = PosixPthreadDestroy(&attr1, newTh2); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = PosixPthreadDestroy(&attr1, newTh1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; + +EXIT2: + PosixPthreadDestroy(&attr1, newTh2); +EXIT1: + PosixPthreadDestroy(&attr1, newTh1); +EXIT: + mq_close(g_gqueue); + mq_unlink(g_gqname); +EXIT3: + return MQUEUE_IS_ERROR; +} + +VOID ItPosixQueue040(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_040", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_041.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_041.cpp new file mode 100644 index 00000000..388c461b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_041.cpp @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static VOID *PthreadF01(VOID *argument) +{ + INT32 i; + struct timespec ts; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + UINT32 ret; + + ts.tv_sec = 0xffff; + ts.tv_nsec = 0; + + g_testCount = 1; + + for (i = 0; i < 5 + 1; i++) { // 5, The loop frequency. + ret = mq_timedsend(g_gqueue, msgptr, strlen(msgptr), 0, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + } + ICUNIT_ASSERT_EQUAL_NULL(g_testCount, 3, g_testCount); // 3, Here, assert the g_testCount. + + g_testCount = 2; // 2, Init test count value. + + return NULL; +EXIT: + g_testCount = 0; + return NULL; +} + +static VOID *PthreadF02(VOID *argument) +{ + INT32 ret; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = ""; + + g_testCount = 3; // 3, Init test count value. + + ret = mq_receive(g_gqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, strlen(MQUEUE_SEND_STRING_TEST), ret, EXIT1); + + TestExtraTaskDelay(2); // 2, Set delay time. + ret = mq_close(g_gqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(g_gqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + g_testCount = 4; // 4, Init test count value. + + return NULL; +EXIT1: + mq_close(g_gqueue); +EXIT: + mq_unlink(g_gqname); +EXIT2: + g_testCount = 0; + return NULL; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + struct mq_attr attr = {0}; + pthread_attr_t attr1; + pthread_t newTh1, newTh2; + + ret = snprintf_s(g_gqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq041_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT3); + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = 5; // 5, queue max message size. + g_gqueue = mq_open(g_gqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(g_gqueue, (mqd_t)-1, g_gqueue, EXIT3); + + g_testCount = 0; + + ret = PosixPthreadInit(&attr1, MQUEUE_PTHREAD_PRIORITY_TEST1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = pthread_create(&newTh1, &attr1, PthreadF01, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + LosTaskDelay(5); // 5, Set delay time. + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT1); + + ret = PosixPthreadInit(&attr1, MQUEUE_PTHREAD_PRIORITY_TEST2); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = pthread_create(&newTh2, &attr1, PthreadF02, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = LosTaskDelay(5); // 5, Set delay time. + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT2); // 4, Here, assert the g_testCount. + + ret = PosixPthreadDestroy(&attr1, newTh2); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = PosixPthreadDestroy(&attr1, newTh1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; + +EXIT2: + PosixPthreadDestroy(&attr1, newTh2); +EXIT1: + PosixPthreadDestroy(&attr1, newTh1); +EXIT: + mq_close(g_gqueue); + mq_unlink(g_gqname); +EXIT3: + return MQUEUE_IS_ERROR; +} + +VOID ItPosixQueue041(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_041", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_042.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_042.cpp new file mode 100644 index 00000000..240dc7f3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_042.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + INT32 i = 0; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + CHAR msgptr[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + mqd_t mqueue; + struct mq_attr attr = {0}; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, + "/mq042_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_SHORT_ARRAY_LENGTH; + + mqueue = mq_open(mqname, O_CREAT | O_RDWR | O_NONBLOCK, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT2); + + while (1) { + ret = snprintf_s(msgptr, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, "message %d", i); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ret = mq_send(mqueue, msgptr, strlen(msgptr), 0); + if (ret == -1) { + ICUNIT_GOTO_EQUAL(errno, EAGAIN, errno, EXIT1); + break; + } + i++; + } + ICUNIT_GOTO_EQUAL(i, MQUEUE_SHORT_ARRAY_LENGTH, i, EXIT1); + + i = 0; + ret = snprintf_s(msgptr, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, "message %d", i); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ret = mq_receive(mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, strlen(msgptr), ret, EXIT1); + + ret = strcmp(msgptr, msgrcd); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_IS_ERROR; +} + +VOID ItPosixQueue042(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_042", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_043.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_043.cpp new file mode 100644 index 00000000..d4fdd79b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_043.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + mqd_t mqueue; + struct mq_attr attr = {0}; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, + "/mq043_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_SHORT_ARRAY_LENGTH; + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_ASSERT_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue); + + ret = mq_send(mqueue, msgptr, strlen(msgptr), MQ_PRIO_MAX - 1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_receive(mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, strlen(msgptr), ret, EXIT1); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, msgptr, msgrcd, EXIT1); + + ret = strncmp(msgptr, msgrcd, strlen(msgptr)); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_IS_ERROR; +} + +/* * +*-@test IT_POSIX_MQUEUE_043 +*-@tspec The API test for mq_send +*-@ttitle Mq_send writes the mqueue while the priority is MQ_PRIO_MAX - 1 +*-@tprecon The mqueue module is open +*-@tbrief +1. use the mq_open to create a legal mqueue; +2. use the mq_send to write the mqueue while the priority is MQ_PRIO_MAX - 1; +3. use the mq_receive to read the mqueue; +4. use the mq_close to close the mqueue; +5. use the mq_unlink to delete the mqueue. +*-@texpect +1. Return succeeded +2. Return succeeded +3. Return succeeded +4. Return succeeded +5. Successful operation +*-@tprior 1 +*-@tauto TRUE +*-@tremark +*/ +VOID ItPosixQueue043(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_043", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_044.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_044.cpp new file mode 100644 index 00000000..93cb5d07 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_044.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + mqd_t mqueue; + struct mq_attr attr = {0}; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, + "/mq044_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_SHORT_ARRAY_LENGTH; + mqueue = mq_open(mqname, O_CREAT | O_RDWR | O_NONBLOCK, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT2); + + ret = mq_send((mqd_t)(&mqueue + 1), msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EBADF, errno, EXIT1); + + ret = mq_receive(mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EAGAIN, errno, EXIT1); + + ret = strcmp(msgptr, msgrcd); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_IS_ERROR; +} + +VOID ItPosixQueue044(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_044", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_046.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_046.cpp new file mode 100644 index 00000000..4800f597 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_046.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + CHAR qname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + mqd_t queue; + INT32 ret; + + ret = snprintf_s(qname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq046-1_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT); + + queue = mq_open(qname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, NULL); + ICUNIT_GOTO_NOT_EQUAL(queue, (mqd_t)-1, queue, EXIT); + + ret = mq_send((mqd_t)(&queue + 1), msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, -1, ret, EXIT2); + ICUNIT_GOTO_EQUAL(errno, EBADF, errno, EXIT2); + + ret = mq_close(queue); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT1); + + ret = mq_unlink(qname); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT2: + mq_close(queue); +EXIT1: + mq_unlink(qname); +EXIT: + return MQUEUE_IS_ERROR; +} + +VOID ItPosixQueue046(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_046", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_047.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_047.cpp new file mode 100644 index 00000000..02909fac --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_047.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH * 2]; // 2: mqueue message length + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + mqd_t mqueue; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, + "/mq047_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + mqueue = mq_open(mqname, O_CREAT | O_RDONLY | O_NONBLOCK, S_IRUSR | S_IWUSR, NULL); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT2); + + ret = mq_send(mqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EBADF, errno, EXIT1); + + ret = mq_receive(mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EMSGSIZE, errno, EXIT1); + + ret = mq_receive(mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH * 2, NULL); // 2, mqueue message length. + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EAGAIN, errno, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_IS_ERROR; +} + +VOID ItPosixQueue047(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_047", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_048.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_048.cpp new file mode 100644 index 00000000..fdc6e5aa --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_048.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + CHAR msgrv[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + const CHAR *msgptr = "test message"; + mqd_t mqueue; + struct timespec ts; + struct mq_attr attr = {0}; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq048_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT2); + + ret = mq_send(mqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ts.tv_sec = 1; + ts.tv_nsec = -1; + ret = mq_timedreceive(mqueue, msgrv, MQUEUE_STANDARD_NAME_LENGTH, NULL, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_IS_ERROR; +} + +VOID ItPosixQueue048(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_048", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_049.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_049.cpp new file mode 100644 index 00000000..4f113bf4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_049.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 i, ret = 0; + INT32 mqueuePri[MQUEUE_PRIORITY_NUM_TEST] = {MQ_PRIO_MAX, MQ_PRIO_MAX + 1, MQ_PRIO_MAX + 5}; // 5, Mqueue priority. + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + mqd_t mqueue; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq049_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, NULL); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + for (i = 0; i < MQUEUE_PRIORITY_NUM_TEST; i++) { + ret = mq_send(mqueue, msgptr, strlen(msgptr), mqueuePri[i]); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT1); + } + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue049(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_049", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_050.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_050.cpp new file mode 100644 index 00000000..3563fa53 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_050.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 i, ret = 0; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + const CHAR *msgptr = "01234567890123456789"; + mqd_t mqueue; + INT32 messagesize[MQUEUE_PRIORITY_NUM_TEST] = {19, 2, 1}; + + struct mq_attr attr = { 0 }; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, + "/mq050_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + for (i = 0; i < MQUEUE_PRIORITY_NUM_TEST; i++) { + attr.mq_msgsize = messagesize[i]; + attr.mq_maxmsg = messagesize[i]; + + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + ret = mq_send(mqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EMSGSIZE, errno, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + } + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue050(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_050", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_052.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_052.cpp new file mode 100644 index 00000000..cbcc4c40 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_052.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret = 0; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + CHAR msgrv[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + const CHAR *msgptr = "test message"; + mqd_t mqueue; + struct mq_attr attr; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, + "/mq052_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH + 1; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH + 1; + + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + ret = mq_send(mqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_receive(mqueue, msgrv, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EMSGSIZE, errno, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue052(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_052", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_054.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_054.cpp new file mode 100644 index 00000000..e81bd409 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_054.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret = 0; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + CHAR msgrv[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + mqd_t mqueue; + struct mq_attr attr = { 0 }; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq054_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + mqueue = mq_open(mqname, O_CREAT | O_NONBLOCK | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + ret = mq_receive(mqueue, msgrv, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EAGAIN, errno, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue054(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_054", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_055.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_055.cpp new file mode 100644 index 00000000..e963e8bb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_055.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret = 0; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + CHAR msgrv1[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + CHAR msgrv2[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + const CHAR *msgptr1 = "test message1"; + const CHAR *msgptr2 = "test message2 with differnet length"; + mqd_t mqueue; + struct mq_attr attr = { 0 }; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq055_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + ret = mq_send(mqueue, msgptr1, strlen(msgptr1), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_send(mqueue, msgptr2, strlen(msgptr2), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_receive(mqueue, msgrv1, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, strlen(msgptr1), ret, EXIT1); + + ret = mq_receive(mqueue, msgrv2, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, strlen(msgptr2), ret, EXIT1); + + ret = strcmp(msgptr1, msgrv1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = strcmp(msgptr2, msgrv2); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = strcmp(msgrv1, msgrv2); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue055(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_055", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_056.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_056.cpp new file mode 100644 index 00000000..b1f0d423 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_056.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH], msgrv[MQUEUE_STANDARD_NAME_LENGTH]; + mqd_t mqdes; + struct mq_attr attr = { 0 }; + INT32 unresolved = 0, failure = 0, ret = 0; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq056-1-%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + mqdes = mq_open(mqname, O_CREAT | O_NONBLOCK | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqdes, (mqd_t)-1, mqdes, EXIT); + + if (mq_receive(mqdes, msgrv, MQUEUE_STANDARD_NAME_LENGTH, NULL) == -1) { + if (EAGAIN != errno) { + failure = 1; + ICUNIT_GOTO_EQUAL(failure, 0, failure, EXIT); + } + } else { + failure = 1; + ICUNIT_GOTO_EQUAL(failure, 0, failure, EXIT); + } + ret = mq_close(mqdes); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT: + mq_close(mqdes); + mq_unlink(mqname); +EXIT1: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue056(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_056", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_057.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_057.cpp new file mode 100644 index 00000000..d266c857 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_057.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret = 0; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + mqd_t mqueue; + CHAR msgrv[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + struct mq_attr attr = { 0 }; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq057_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + mqueue = (mqd_t)((UINTPTR)mqueue + PER_ADDED_VALUE); + ret = mq_receive(mqueue, msgrv, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EBADF, errno, EXIT1); + + ret = mq_close((mqd_t)((UINTPTR)mqueue - PER_ADDED_VALUE)); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue057(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_057", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_058.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_058.cpp new file mode 100644 index 00000000..2af7b114 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_058.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + mqd_t mqdes; + CHAR msgrv[MQUEUE_STANDARD_NAME_LENGTH]; + struct mq_attr attr = { 0 }; + INT32 unresolved = 0, failure = 0, ret = 0; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq058-2-%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + mqdes = mq_open(mqname, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqdes, (mqd_t)-1, mqdes, EXIT); + + ret = mq_receive(mqdes, msgrv, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, -1, ret, EXIT); + ICUNIT_GOTO_EQUAL(errno, EBADF, errno, EXIT); + + ret = mq_close(mqdes); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT: + mq_close(mqdes); + mq_unlink(mqname); +EXIT1: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue058(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_058", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_060.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_060.cpp new file mode 100644 index 00000000..02ed05a6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_060.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq060_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, ENOENT, errno, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_unlink(mqname); +EXIT: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue060(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_060", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_061.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_061.cpp new file mode 100644 index 00000000..e41a4150 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_061.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + mqd_t mqdes; + struct mq_attr mqstat; + INT32 unresolved = 0; + INT32 failure = 0, ret = 0; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq061-1_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + + mqdes = mq_open(mqname, O_CREAT | O_RDWR | O_NONBLOCK, S_IRUSR | S_IWUSR, NULL); + ICUNIT_GOTO_NOT_EQUAL(mqdes, (mqd_t)-1, mqdes, EXIT); + + ret = memset_s(&mqstat, sizeof(mqstat), 0, sizeof(mqstat)); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = mq_getattr(mqdes, &mqstat); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = mq_close(mqdes); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + if (!(mqstat.mq_flags & O_NONBLOCK)) { + failure = 1; + ICUNIT_ASSERT_EQUAL(failure, 0, failure); + } + + return MQUEUE_NO_ERROR; +EXIT: + mq_close(mqdes); + mq_unlink(mqname); +EXIT1: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue061(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_061", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_063.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_063.cpp new file mode 100644 index 00000000..c734057b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_063.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + mqd_t mqdes; + struct mq_attr mqstat, nmqstat; + INT32 unresolved = 0; + INT32 failure = 0, ret = 0; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq063-1_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + + ret = memset_s(&mqstat, sizeof(mqstat), 0, sizeof(mqstat)); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + mqstat.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + mqstat.mq_maxmsg = 40; // 40, queue max message size. + mqdes = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &mqstat); + ICUNIT_GOTO_NOT_EQUAL(mqdes, (mqd_t)-1, mqdes, EXIT); + + ret = memset_s(&nmqstat, sizeof(nmqstat), 0, sizeof(nmqstat)); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = mq_getattr(mqdes, &nmqstat); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + if ((mqstat.mq_maxmsg != nmqstat.mq_maxmsg) || (mqstat.mq_msgsize != nmqstat.mq_msgsize)) { + failure = 1; + ICUNIT_GOTO_EQUAL(failure, 0, failure, EXIT); + } + + ret = mq_close(mqdes); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT: + mq_close(mqdes); + mq_unlink(mqname); +EXIT1: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue063(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_063", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_064.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_064.cpp new file mode 100644 index 00000000..b602f424 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_064.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret = 0, i; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + const CHAR *msgptr = "test message"; + mqd_t mqueue; + struct mq_attr mqstat; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq064_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + ret = memset_s(&mqstat, sizeof(mqstat), 0, sizeof(mqstat)); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + mqstat.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + mqstat.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &mqstat); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + for (i = 0; i < 5; i++) { // 5, the loop frequency. + ret = mq_send(mqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + } + ret = memset_s(&mqstat, sizeof(mqstat), 0, sizeof(mqstat)); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT1); + ret = mq_getattr(mqueue, &mqstat); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(mqstat.mq_curmsgs, 5, mqstat.mq_curmsgs, EXIT1); // 5, assert the curmsgs. + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue064(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_064", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_065.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_065.cpp new file mode 100644 index 00000000..041a008a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_065.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + mqd_t mqueue, mqdesInvalid; + struct mq_attr mqstat; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq065_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, 0); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + mqdesInvalid = (mqd_t)((UINTPTR)mqueue + PER_ADDED_VALUE); + ret = memset_s(&mqstat, sizeof(mqstat), 0, sizeof(mqstat)); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT1); + + ret = mq_getattr(mqdesInvalid, &mqstat); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EBADF, errno, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue065(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_065", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_066.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_066.cpp new file mode 100644 index 00000000..b3e63e77 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_066.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + mqd_t mqdes; + struct mq_attr mqstat = { 0 }; + struct mq_attr nmqstat = { 0 }; + INT32 unresolved = 0; + INT32 failure = 0, ret = 0; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq066-1_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + + mqdes = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, 0); + ICUNIT_GOTO_NOT_EQUAL(mqdes, (mqd_t)-1, mqdes, EXIT); + + ret = memset_s(&mqstat, sizeof(mqstat), 0, sizeof(mqstat)); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ret = memset_s(&nmqstat, sizeof(nmqstat), 0, sizeof(nmqstat)); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = mq_getattr(mqdes, &mqstat); + ICUNIT_GOTO_NOT_EQUAL(ret, -1, ret, EXIT); + + mqstat.mq_flags |= O_NONBLOCK; + + ret = mq_setattr(mqdes, &mqstat, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = mq_getattr(mqdes, &nmqstat); + ICUNIT_GOTO_NOT_EQUAL(ret, -1, ret, EXIT); + + ret = mq_close(mqdes); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + if (nmqstat.mq_flags != mqstat.mq_flags) { + failure = 1; + ICUNIT_GOTO_EQUAL(failure, 0, failure, EXIT); + } + + return MQUEUE_NO_ERROR; +EXIT: + mq_close(mqdes); + mq_unlink(mqname); +EXIT1: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue066(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_066", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_067.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_067.cpp new file mode 100644 index 00000000..3742e40f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_067.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret = 0; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + mqd_t mqueue; + struct mq_attr mqstat1 = { 0 }; + struct mq_attr mqstat2 = { 0 }; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq067_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, 0); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + ret = memset_s(&mqstat1, sizeof(mqstat1), 0, sizeof(mqstat1)); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ret = memset_s(&mqstat2, sizeof(mqstat2), 0, sizeof(mqstat1)); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = mq_getattr(mqueue, &mqstat1); + ICUNIT_GOTO_NOT_EQUAL(ret, -1, ret, EXIT1); + + mqstat1.mq_maxmsg = mqstat1.mq_maxmsg + 1; + mqstat1.mq_msgsize = mqstat1.mq_msgsize + 1; + mqstat1.mq_curmsgs = mqstat1.mq_curmsgs + 1; + + ret = mq_setattr(mqueue, &mqstat1, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_getattr(mqueue, &mqstat2); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + ICUNIT_GOTO_NOT_EQUAL(mqstat2.mq_maxmsg, mqstat1.mq_maxmsg, mqstat2.mq_maxmsg, EXIT1); + ICUNIT_GOTO_NOT_EQUAL(mqstat2.mq_msgsize, mqstat1.mq_msgsize, mqstat2.mq_msgsize, EXIT1); + ICUNIT_GOTO_NOT_EQUAL(mqstat2.mq_curmsgs, mqstat1.mq_curmsgs, mqstat2.mq_curmsgs, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue067(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_067", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_069.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_069.cpp new file mode 100644 index 00000000..d10ec589 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_069.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + mqd_t mqueue1, mqueue2; + struct mq_attr mqstat1; + struct mq_attr mqstat2; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq069_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT3); + + mqueue1 = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, 0); + ICUNIT_GOTO_NOT_EQUAL(mqueue1, (mqd_t)-1, mqueue1, EXIT1); + + mqueue2 = mqueue1; + mqueue1 = (mqd_t)((UINTPTR)mqueue1 + PER_ADDED_VALUE); + + ret = memset_s(&mqstat1, sizeof(mqstat1), 0, sizeof(mqstat1)); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ret = memset_s(&mqstat2, sizeof(mqstat2), 0, sizeof(mqstat2)); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + mqstat2.mq_flags = 1; + + ret = mq_setattr(mqueue1, &mqstat1, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + ICUNIT_GOTO_EQUAL(errno, EBADF, errno, EXIT2); + + ret = mq_close(mqueue1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + ret = mq_close(mqueue2); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = mq_close(mqueue2); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT2: + mq_close(mqueue2); +EXIT1: + mq_close(mqueue1); +EXIT: + mq_unlink(mqname); +EXIT3: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue069(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_069", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_070.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_070.cpp new file mode 100644 index 00000000..b1421a7e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_070.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + mqd_t mqueue; + struct mq_attr attr = { 0 }; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + CHAR *msgptr1 = "1234567890"; + CHAR *msgptr2 = "2345678901"; + CHAR *msgptr3 = "3456789012"; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq070_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + ret = mq_send(mqueue, msgptr1, strlen(msgptr1), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_send(mqueue, msgptr2, strlen(msgptr2), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_send(mqueue, msgptr3, strlen(msgptr3), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_receive(mqueue, msgrcd, 0, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT1); + + ret = mq_receive(mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT1); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, msgptr1, msgrcd, EXIT1); + + ret = mq_receive(mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT1); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, msgptr2, msgrcd, EXIT1); + + ret = mq_receive(mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT1); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, msgptr3, msgrcd, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue070(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_070", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_071.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_071.cpp new file mode 100644 index 00000000..5a195c7a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_071.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + INT32 i; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + mqd_t mqueue; + struct mq_attr attr = { 0 }; + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq071_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + ret = mq_send(mqueue, NULL, 0, 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + + for (i = 0; i < 3; i++) { // 3, the loop frequency. + ret = mq_send(mqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + } + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue071(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_071", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_072.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_072.cpp new file mode 100644 index 00000000..161ad55e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_072.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + + CHAR qName[MQUEUE_STANDARD_NAME_LENGTH] = ""; + const CHAR *msgPtr = MQUEUE_SEND_STRING_TEST; + struct mq_attr msgAttr = { 0 }; + CHAR msgRcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + mqd_t msgQId; + + msgAttr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + msgAttr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + ret = snprintf_s(qName, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq072_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT); + + msgQId = mq_open(qName, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &msgAttr); + ICUNIT_GOTO_NOT_EQUAL(msgQId, (mqd_t)-1, msgQId, EXIT); + + ret = mq_send(msgQId, msgPtr, strlen(msgPtr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = mq_receive(msgQId, msgRcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MSGLEN, ret, EXIT2); + ICUNIT_GOTO_STRING_EQUAL(msgRcd, MQUEUE_SEND_STRING_TEST, msgRcd, EXIT2); + + ret = mq_close(msgQId); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = mq_unlink(qName); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + return MQUEUE_NO_ERROR; +EXIT2: + mq_close(msgQId); +EXIT1: + mq_unlink(qName); +EXIT: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue072(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_072", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_073.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_073.cpp new file mode 100644 index 00000000..0c90161b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_073.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + CHAR mqname1[MQUEUE_STANDARD_NAME_LENGTH] = ""; + CHAR mqname2[MQUEUE_STANDARD_NAME_LENGTH] = ""; + mqd_t mqueue1; + mqd_t mqueue2; + struct mq_attr attr = { 0 }; + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + ret = snprintf_s(mqname1, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq073_1_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + ret = snprintf_s(mqname2, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq073_2_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + mqueue1 = mq_open(mqname1, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue1, (mqd_t)-1, mqueue1, EXIT); + + mqueue2 = mq_open(mqname2, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue2, (mqd_t)-1, mqueue2, EXIT1); + + ret = mq_send(mqueue1, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_send(mqueue2, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_close(mqueue2); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname2); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_close(mqueue1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(mqname1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue2); + mq_unlink(mqname2); +EXIT: + mq_close(mqueue1); + mq_unlink(mqname1); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue073(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_073", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_074.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_074.cpp new file mode 100644 index 00000000..c852b8ef --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_074.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + + CHAR msgRcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + + CHAR qName[MQUEUE_STANDARD_NAME_LENGTH] = "/mq074"; + mqd_t msgQId; + struct mq_attr msgAttr = { 0 }; + msgAttr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + msgAttr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + msgQId = mq_open(qName, O_CREAT | O_RDWR | O_NONBLOCK, S_IRUSR | S_IWUSR, &msgAttr); + ICUNIT_ASSERT_NOT_EQUAL(msgQId, (mqd_t)-1, msgQId); + + ret = mq_receive(msgQId, msgRcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, (UINT32)-1, ret, EXIT1); + + ret = mq_close(msgQId); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(qName); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(msgQId); +EXIT: + mq_unlink(qName); + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue074(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_074", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_075.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_075.cpp new file mode 100644 index 00000000..94985091 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_075.cpp @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" +static int g_testFlag = 0; + +static VOID *PthreadF01(VOID *arg) +{ + INT32 ret; + INT32 i; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + struct timespec ts = { 0 }; + ts.tv_sec = 0xffff; + for (i = 0; i < MQUEUE_STANDARD_NAME_LENGTH * 2; i++) { // 2, The loop frequency name length. + ret = mq_timedreceive(g_gqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, MQUEUE_SEND_STRING_TEST, msgrcd, EXIT); + } + g_testFlag = 0; // 0 means the sub thread has executed + return NULL; +EXIT: + return NULL; +} + +static UINT32 Testcase(VOID) +{ + INT32 ret; + INT32 i; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + pthread_t pthread1; + pthread_attr_t attr1; + struct sched_param schedparam; + struct mq_attr attr = { 0 }; + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + g_testFlag = 1; // 1 initialize the flag + LOS_TaskLock(); + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq075_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + g_gqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(g_gqueue, (mqd_t)-1, g_gqueue, EXIT1); + ret = pthread_attr_init(&attr1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + pthread_attr_setinheritsched(&attr1, PTHREAD_EXPLICIT_SCHED); + schedparam.sched_priority = MQUEUE_PTHREAD_PRIORITY_TEST2; + + ret = pthread_attr_setschedparam(&attr1, &schedparam); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = pthread_create(&pthread1, &attr1, PthreadF01, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + LOS_TaskUnlock(); + for (i = 0; i < MQUEUE_STANDARD_NAME_LENGTH * 2; i++) { // 2, The loop frequency name length. + ret = mq_send(g_gqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + } + + // waitting for the flag is 0, means the sub thread has executed + while (g_testFlag) { + usleep(1); + } + + ret = mq_close(g_gqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = pthread_join(pthread1, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = pthread_attr_destroy(&attr1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(g_gqueue); + mq_unlink(mqname); +EXIT: + PosixPthreadDestroy(&attr1, pthread1); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue075(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_075", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_076.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_076.cpp new file mode 100644 index 00000000..aab026ac --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_076.cpp @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static VOID *PthreadF01(VOID *arg) +{ + INT32 ret; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + + LOS_AtomicInc(&g_testCount); + + ret = mq_receive(g_gqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, MQUEUE_SEND_STRING_TEST, msgrcd, EXIT); + + return NULL; + +EXIT: + g_testCount = 0; + return NULL; +} + +static VOID *PthreadF02(VOID *arg) +{ + INT32 ret, i; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + pthread_t thread1; + pthread_attr_t attr1; + struct sched_param schedparam; + struct mq_attr attr = { 0 }; + struct timespec ts = { 0 }; + + ts.tv_sec = 0xFFFF; + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = 2; // 2, queue max message size. + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq076_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + g_gqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(g_gqueue, (mqd_t)-1, g_gqueue, EXIT1); + ret = pthread_attr_init(&attr1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + schedparam.sched_priority = MQUEUE_PTHREAD_PRIORITY_TEST2; + ret = pthread_attr_setschedparam(&attr1, &schedparam); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = pthread_create(&thread1, &attr1, PthreadF01, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + for (i = 0; i < 3; i++) { // 3, the loop frequency. + ret = mq_timedsend(g_gqueue, msgptr, MQUEUE_SHORT_ARRAY_LENGTH, 0, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + LOS_AtomicInc(&g_testCount); + } + + ret = pthread_join(thread1, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = pthread_attr_destroy(&attr1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_close(g_gqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + return NULL; +EXIT1: + mq_close(g_gqueue); + mq_unlink(mqname); +EXIT: + PosixPthreadDestroy(&attr1, thread1); + g_testCount = 0; +EXIT2: + return NULL; +} + +static UINT32 Testcase(VOID) +{ + INT32 ret; + pthread_t pthread1; + pthread_attr_t attr1; + struct sched_param schedparam; + + g_testCount = 0; + + ret = pthread_attr_init(&attr1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + schedparam.sched_priority = MQUEUE_PTHREAD_PRIORITY_TEST2; + ret = pthread_attr_setschedparam(&attr1, &schedparam); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = pthread_create(&pthread1, &attr1, PthreadF02, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = pthread_join(pthread1, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = pthread_attr_destroy(&attr1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ICUNIT_ASSERT_EQUAL(g_testCount, 4, g_testCount); // 4, Here, assert the g_testCount. + + return MQUEUE_NO_ERROR; + +EXIT: + PosixPthreadDestroy(&attr1, pthread1); + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue076(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_076", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_077.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_077.cpp new file mode 100644 index 00000000..8721c8c7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_077.cpp @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static VOID *PthreadF01(VOID *arg) +{ + INT32 ret; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + + g_testCount++; + + ret = mq_receive(g_gqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, MQUEUE_SEND_STRING_TEST, msgrcd, EXIT); + + g_testCount++; + + return NULL; +EXIT: + g_testCount = 0; + return NULL; +} + +static UINT32 Testcase(VOID) +{ + INT32 ret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + pthread_t pthread1; + pthread_attr_t attr1; + struct sched_param schedparam; + struct mq_attr attr = { 0 }; + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + g_testCount = 0; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq077_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + g_gqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(g_gqueue, (mqd_t)-1, g_gqueue, EXIT1); + + ret = mq_send(g_gqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = pthread_attr_init(&attr1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + pthread_attr_setinheritsched(&attr1, PTHREAD_EXPLICIT_SCHED); + + schedparam.sched_priority = MQUEUE_PTHREAD_PRIORITY_TEST2; + ret = pthread_attr_setschedparam(&attr1, &schedparam); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = pthread_create(&pthread1, &attr1, PthreadF01, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = pthread_join(pthread1, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = pthread_attr_destroy(&attr1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert the g_testCount. + + ret = mq_close(g_gqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + PosixPthreadDestroy(&attr1, pthread1); +EXIT: + mq_close(g_gqueue); + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue077(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_077", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_078.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_078.cpp new file mode 100644 index 00000000..1c9860d4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_078.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static VOID *PthreadF01(VOID *arg) +{ + INT32 ret; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + + LOS_AtomicInc(&g_testCount); + + ret = mq_receive(g_gqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT); + + LOS_AtomicInc(&g_testCount); + + return NULL; + +EXIT: + g_testCount = 0; + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t thread1; + pthread_attr_t attr1; + INT32 ret; + struct sched_param schedparam; + + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + struct mq_attr attr = { 0 }; + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + g_testCount = 0; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq078_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + g_gqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_ASSERT_NOT_EQUAL(g_gqueue, (mqd_t)-1, g_gqueue); + + ret = mq_send(g_gqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_receive(g_gqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT); + ICUNIT_ASSERT_STRING_EQUAL(msgrcd, MQUEUE_SEND_STRING_TEST, msgrcd); + + ret = mq_close(g_gqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = pthread_attr_init(&attr1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + schedparam.sched_priority = MQUEUE_PTHREAD_PRIORITY_TEST2; + ret = pthread_attr_setschedparam(&attr1, &schedparam); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = pthread_create(&thread1, &attr1, PthreadF01, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = pthread_join(thread1, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = pthread_attr_destroy(&attr1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2, Here, assert the g_testCount. + + return MQUEUE_NO_ERROR; +EXIT1: + pthread_attr_destroy(&attr1); +EXIT: + mq_close(g_gqueue); + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue078(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_078", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_079.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_079.cpp new file mode 100644 index 00000000..b657845e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_079.cpp @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static VOID *PthreadF01(VOID *arg) +{ + INT32 ret; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + + LOS_AtomicInc(&g_testCount); + + ret = mq_receive(g_gqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, MQUEUE_SEND_STRING_TEST, msgrcd, EXIT); + + ret = mq_close(g_gqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(g_gqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + LOS_AtomicInc(&g_testCount); + + return NULL; +EXIT: + mq_close(g_gqueue); + mq_unlink(g_gqname); + g_testCount = 0; + return NULL; +} + +static VOID *PthreadF02(VOID *arg) +{ + INT32 ret; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + struct mq_attr attr = { 0 }; + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + LOS_AtomicInc(&g_testCount); + + g_gqueue = mq_open(g_gqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(g_gqueue, (mqd_t)-1, g_gqueue, EXIT); + + ret = mq_send(g_gqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + LOS_AtomicInc(&g_testCount); + return NULL; +EXIT: + mq_close(g_gqueue); + mq_unlink(g_gqname); + g_testCount = 0; + return NULL; +} + +static UINT32 Testcase(VOID) +{ + INT32 ret; + pthread_t thread1; + pthread_t thread2; + pthread_attr_t attr1; + struct sched_param schedparam; + + ret = memset_s(g_gqname, MQUEUE_STANDARD_NAME_LENGTH, 0, MQUEUE_STANDARD_NAME_LENGTH); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + (void)snprintf_s(g_gqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq079_%d", LosCurTaskIDGet()); + + g_testCount = 0; + + ret = pthread_create(&thread1, NULL, PthreadF02, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = LosTaskDelay(10); // 10, Set delay time. + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT1); // 2, Here, assert the g_testCount. + + ret = pthread_attr_init(&attr1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + schedparam.sched_priority = MQUEUE_PTHREAD_PRIORITY_TEST2; + ret = pthread_attr_setschedparam(&attr1, &schedparam); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = pthread_create(&thread2, &attr1, PthreadF01, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT2); // 4, Here, assert the g_testCount. + + ret = pthread_join(thread1, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = pthread_join(thread2, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = pthread_attr_destroy(&attr1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT2: + pthread_join(thread2, NULL); +EXIT1: + pthread_join(thread1, NULL); +EXIT: + pthread_attr_destroy(&attr1); + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue079(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_079", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_080.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_080.cpp new file mode 100644 index 00000000..c68b06e3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_080.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + CHAR qname[MQUEUE_STANDARD_NAME_LENGTH], msgrcd[MQUEUE_STANDARD_NAME_LENGTH]; + CHAR msgptr[MQUEUE_STANDARD_NAME_LENGTH]; + struct timespec ts; + struct mq_attr attr = { 0 }; + mqd_t queue; + INT32 unresolved = 0, failure = 0, i, maxreached = 0, ret = 0; + unsigned pri; + + ret = snprintf_s(qname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq080-1_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MAXMSG5; + queue = mq_open(qname, O_CREAT | O_RDWR | O_NONBLOCK, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(queue, (mqd_t)-1, queue, EXIT); + + ts.tv_sec = 0; + ts.tv_nsec = 0; + for (i = 0; i < MAXMSG5 + 1; i++) { + ret = snprintf_s(msgptr, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, "message %d", i); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT); + ts.tv_sec++; + if (mq_timedsend(queue, msgptr, strlen(msgptr), 0, &ts) == -1) { + maxreached = 1; + ICUNIT_GOTO_EQUAL(errno, EAGAIN, errno, EXIT); + break; + } + } + + if (mq_receive(queue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL) == -1) { + unresolved = 1; + } else { + if ((strcmp(msgptr, msgrcd) == 0) && (maxreached != 0)) { + ICUNIT_GOTO_EQUAL(maxreached, 0, maxreached, EXIT); + } + } + + ret = mq_close(queue); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = mq_unlink(qname); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT: + mq_close(queue); + mq_unlink(qname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue080(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_080", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_081.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_081.cpp new file mode 100644 index 00000000..9af005ad --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_081.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + CHAR qname[MQUEUE_STANDARD_NAME_LENGTH], msgrcd[MQUEUE_STANDARD_NAME_LENGTH]; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + struct timespec ts; + mqd_t queue; + struct mq_attr attr = { 0 }; + INT32 unresolved = 0, ret; + unsigned pri; + + ret = snprintf_s(qname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq081-1_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MAXMSG5; + queue = mq_open(qname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(queue, (mqd_t)-1, queue, EXIT); + + ts.tv_sec = 1; + ts.tv_nsec = 0; + ret = mq_timedsend(queue, msgptr, strlen(msgptr), 0, &ts); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = mq_receive(queue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_NOT_EQUAL(ret, -1, ret, EXIT); + + ret = strncmp(msgptr, msgrcd, strlen(msgptr)); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = mq_close(queue); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = mq_unlink(qname); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT: + mq_close(queue); + mq_unlink(qname); +EXIT1: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue081(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_081", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_082.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_082.cpp new file mode 100644 index 00000000..d39bd4b9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_082.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret = 0; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + struct timespec ts; + mqd_t mqueue; + struct mq_attr attr = { 0 }; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq082_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + mqueue = mq_open(mqname, O_CREAT | O_RDWR | O_NONBLOCK, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + ts.tv_sec = 1; + ts.tv_nsec = 0; + ret = mq_timedsend((mqd_t)((UINTPTR)mqueue + PER_ADDED_VALUE), msgptr, strlen(msgptr), 0, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EBADF, errno, EXIT1); + + ret = mq_receive(mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue082(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_082", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_083.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_083.cpp new file mode 100644 index 00000000..bdb9305e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_083.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + CHAR qname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + CHAR msgptr[MQUEUE_STANDARD_NAME_LENGTH]; + struct timespec ts; + struct mq_attr attr = { 0 }; + mqd_t queue; + INT32 unresolved = 0, failure = 0, i, maxreached = 0, ret = 0; + + ret = snprintf_s(qname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq083-1_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + attr.mq_msgsize = 100; // 100, queue message size. + attr.mq_maxmsg = MAXMSG5; + queue = mq_open(qname, O_CREAT | O_RDWR | O_NONBLOCK, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(queue, (mqd_t)-1, queue, EXIT); + + ts.tv_sec = 1; + ts.tv_nsec = 0; + for (i = 0; i < MAXMSG5; i++) { + ret = snprintf_s(msgptr, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, "message %d", i); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT); + ret = mq_timedsend(queue, msgptr, strlen(msgptr), 0, &ts); + ICUNIT_GOTO_NOT_EQUAL(ret, -1, ret, EXIT); + } + + ret = snprintf_s(msgptr, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, "message %d", i); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ret = mq_timedsend(queue, msgptr, strlen(msgptr), 0, &ts); + ICUNIT_GOTO_EQUAL(ret, -1, ret, EXIT); + ICUNIT_GOTO_EQUAL(errno, EAGAIN, errno, EXIT); + + ret = mq_close(queue); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = mq_unlink(qname); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT: + mq_close(queue); + mq_unlink(qname); +EXIT1: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue083(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_083", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_084.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_084.cpp new file mode 100644 index 00000000..07410d79 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_084.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + CHAR qname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + struct timespec ts; + mqd_t queue; + INT32 unresolved = 0, failure = 0, ret = 0; + + ret = snprintf_s(qname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq084-1_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + queue = mq_open(qname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, NULL); + ICUNIT_GOTO_NOT_EQUAL(queue, (mqd_t)-1, queue, EXIT); + + ts.tv_sec = 1; + ts.tv_nsec = 0; + ret = mq_timedsend((mqd_t)(queue + PER_ADDED_VALUE), msgptr, strlen(msgptr), 0, &ts); + ICUNIT_GOTO_EQUAL(ret, -1, ret, EXIT); + ICUNIT_GOTO_EQUAL(errno, EBADF, errno, EXIT); + + ret = mq_close(queue); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = mq_unlink(qname); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT: + mq_close(queue); + mq_unlink(qname); +EXIT1: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue084(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_084", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_085.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_085.cpp new file mode 100644 index 00000000..9017ad4c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_085.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret = 0; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + struct timespec ts; + mqd_t mqueue; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq085_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + mqueue = mq_open(mqname, O_CREAT | O_RDONLY, S_IRUSR | S_IWUSR, NULL); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + ts.tv_sec = 1; + ts.tv_nsec = 0; + ret = mq_timedsend(mqueue, msgptr, strlen(msgptr), 0, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EBADF, errno, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue085(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_085", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_086.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_086.cpp new file mode 100644 index 00000000..61c5cc1d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_086.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret = 0; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + struct timespec ts; + mqd_t mqueue; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "mq086_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, NULL); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + ts.tv_sec = 1; + ts.tv_nsec = 0; + ret = mq_timedsend(mqueue, msgptr, strlen(msgptr), 0, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue086(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_086", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_087.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_087.cpp new file mode 100644 index 00000000..09b44a7f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_087.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 i, ret = 0; + INT32 mqueuePri[MQUEUE_PRIORITY_NUM_TEST] = {_SC_MQ_PRIO_MAX, _SC_MQ_PRIO_MAX + 1, _SC_MQ_PRIO_MAX + 5}; // 5, Mqueue priority. + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + struct timespec ts; + mqd_t mqueue; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq087_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, NULL); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + ts.tv_sec = 1; + ts.tv_nsec = 0; + for (i = 0; i < MQUEUE_PRIORITY_NUM_TEST; i++) { + ret = mq_timedsend(mqueue, msgptr, strlen(msgptr), mqueuePri[i], &ts); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT1); + } + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue087(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_087", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_088.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_088.cpp new file mode 100644 index 00000000..4f83427b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_088.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 i, ret = 0; + INT32 messagesize[MQUEUE_PRIORITY_NUM_TEST] = {19, 2, 1}; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + const CHAR *msgptr = "01234567890123456789"; + struct timespec ts; + mqd_t mqueue; + struct mq_attr attr = { 0 }; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq088_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + ts.tv_sec = 0; + ts.tv_nsec = 0; + for (i = 0; i < MQUEUE_PRIORITY_NUM_TEST; i++) { + attr.mq_msgsize = messagesize[i]; + attr.mq_maxmsg = messagesize[i]; + + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT); + + ts.tv_sec++; + ret = mq_timedsend(mqueue, msgptr, strlen(msgptr), 0, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT); + ICUNIT_GOTO_EQUAL(errno, EMSGSIZE, errno, EXIT); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + } + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue088(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_088", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_089.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_089.cpp new file mode 100644 index 00000000..e2ddaa92 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_089.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret = 0; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + struct timespec ts; + mqd_t mqueue; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/tm/mq089_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, NULL); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + ts.tv_sec = 1; + ts.tv_nsec = 0; + ret = mq_timedsend(mqueue, msgptr, strlen(msgptr), 0, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue089(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_089", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_090.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_090.cpp new file mode 100644 index 00000000..6cdb9b2e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_090.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + CHAR qname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + mqd_t queue[_POSIX_OPEN_MAX + _POSIX_MQ_OPEN_MAX + 1]; + INT32 i, unresolved = 0, failure = 0, numqueues = 0, ret; + + for (i = 0; (i < _POSIX_OPEN_MAX) && (i < _POSIX_MQ_OPEN_MAX); i++, numqueues++) { + (void)snprintf_s(qname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq090%d_%d", i, LosCurTaskIDGet()); + + queue[i] = mq_open(qname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, NULL); + if (queue[i] == (mqd_t)-1) { + unresolved = 1; + break; + } + } + + queue[numqueues] = mq_open(qname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, NULL); + if (queue[numqueues] != (mqd_t)-1) { + } else { + if (errno != EMFILE) { + failure = 1; + } + } + + for (i = 0; i <= numqueues; i++) { + ret = mq_close(queue[i]); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + } + for (i = 0; i < numqueues; i++) { + (void)snprintf_s(qname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq090%d_%d", i, LosCurTaskIDGet()); + ret = mq_unlink(qname); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + } + + (void)snprintf_s(qname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq090%d_%d", numqueues, LosCurTaskIDGet()); + ret = mq_unlink(qname); + ICUNIT_GOTO_EQUAL(ret, -1, ret, EXIT); + + if (failure == 1) { + ICUNIT_ASSERT_NOT_EQUAL(failure, 1, failure); + } + + if (unresolved == 1) { + ICUNIT_ASSERT_NOT_EQUAL(unresolved, 1, unresolved); + } + return MQUEUE_NO_ERROR; +EXIT: + for (i = 0; i <= numqueues; i++) { + mq_close(queue[i]); + mq_unlink(qname); + } + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue090(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_090", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_091.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_091.cpp new file mode 100644 index 00000000..a1303c79 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_091.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + INT32 ret = 0; + struct timespec ts; + mqd_t mqueue; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq091_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, NULL); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + ts.tv_sec = -1; + ts.tv_nsec = 0; + ret = mq_timedsend(mqueue, msgptr, strlen(msgptr), 0, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue091(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_091", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_093.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_093.cpp new file mode 100644 index 00000000..a94324c8 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_093.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 i, ret = 0; + CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + struct timespec ts; + struct mq_attr attr = { 0 }; + mqd_t mqueue; + struct sigaction act; + time_t currsec; + + ret = snprintf_s(g_gqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq093_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + attr.mq_maxmsg = MQUEUE_SHORT_ARRAY_LENGTH; + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + + g_gqueue = mq_open(g_gqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(g_gqueue, (mqd_t)-1, g_gqueue, EXIT1); + + ts.tv_sec = 0; + ts.tv_nsec = 0; + + for (i = 0; i < MQUEUE_SHORT_ARRAY_LENGTH; i++) { + ret = mq_timedsend(g_gqueue, msgptr, strlen(msgptr), 0, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + } + + ret = mq_timedsend(g_gqueue, msgptr, strlen(msgptr), 0, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EAGAIN, errno, EXIT1); + + ret = mq_close(g_gqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(g_gqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(g_gqueue); +EXIT: + mq_unlink(g_gqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue093(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_093", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_094.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_094.cpp new file mode 100644 index 00000000..817cebf4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_094.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret = 0; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + struct timespec ts; + mqd_t mqueue; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq094_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, NULL); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT); + + ts.tv_sec = -1; + ts.tv_nsec = -1; + + ret = mq_timedsend(mqueue, msgptr, strlen(msgptr), 0, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue094(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_094", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_095.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_095.cpp new file mode 100644 index 00000000..992e376f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_095.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret = 0; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + CHAR msgrv1[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + CHAR msgrv2[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + const CHAR *msgptr1 = "test message 1"; + const CHAR *msgptr2 = "test message 2"; + mqd_t mqueue; + struct timespec ts; + struct mq_attr attr = { 0 }; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq095_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + ret = mq_send(mqueue, msgptr1, strlen(msgptr1), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_send(mqueue, msgptr2, strlen(msgptr2), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ts.tv_sec = 1; + ts.tv_nsec = 0; + ret = mq_timedreceive(mqueue, msgrv1, MQUEUE_STANDARD_NAME_LENGTH, NULL, &ts); + ICUNIT_GOTO_EQUAL(ret, strlen(msgptr1), ret, EXIT1); + + ret = strncmp(msgptr1, msgrv1, strlen(msgptr2)); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ts.tv_sec = 1; + ts.tv_nsec = 0; + ret = mq_timedreceive(mqueue, msgrv2, MQUEUE_STANDARD_NAME_LENGTH, NULL, &ts); + ICUNIT_GOTO_EQUAL(ret, strlen(msgptr2), ret, EXIT1); + + ret = strncmp(msgptr2, msgrv2, strlen(msgptr1)); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue095(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_095", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_096.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_096.cpp new file mode 100644 index 00000000..1a75d554 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_096.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret = 0; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + CHAR msgrv[20]; + const CHAR *msgptr = "test message"; + mqd_t mqueue; + struct mq_attr attr; + struct timespec ts; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq096_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + ret = memset_s(&attr, sizeof(attr), 0, sizeof(attr)); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + attr.mq_msgsize = 20 + 1; // 20, queue message size. + attr.mq_maxmsg = 20 + 1; // 20, queue max message size. + + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + ret = mq_send(mqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ts.tv_sec = 1; + ts.tv_nsec = 0; + + ret = mq_timedreceive(mqueue, msgrv, MQUEUE_STANDARD_NAME_LENGTH, NULL, &ts); + ICUNIT_GOTO_EQUAL(ret, strlen(msgptr), ret, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue096(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_096", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_097.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_097.cpp new file mode 100644 index 00000000..09e7effd --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_097.cpp @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static VOID *PthreadF01(VOID *argument) +{ + INT32 ret = 0; + const CHAR *msgptr = "test message "; + + g_testCount = 1; + + ret = LosTaskDelay(2); // 2, Set delay time. + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_send(g_gqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + g_testCount = 2; // 2, Init test count value. + + return NULL; +EXIT: + g_testCount = 0; + return NULL; +} + +static VOID *PthreadF02(VOID *argument) +{ + INT32 ret = 0, len; + CHAR msgrv[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + const CHAR *msgptr = "test message "; + struct timespec ts; + + g_testCount = 3; // 3, Init test count value. + + ts.tv_sec = INT32_MAX; + ts.tv_nsec = 0; + + len = mq_timedreceive(g_gqueue, msgrv, MQUEUE_STANDARD_NAME_LENGTH, NULL, &ts); + + ret = LosTaskDelay(3); // 3, Set delay time. + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + ICUNIT_GOTO_EQUAL(len, strlen(msgptr), len, EXIT); + + ret = mq_close(g_gqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(g_gqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + g_testCount = 4; // 4, Init test count value. + + return NULL; +EXIT: + mq_close(g_gqueue); + mq_unlink(g_gqname); + g_testCount = 0; + return NULL; +} + +static UINT32 Testcase(VOID) +{ + INT32 ret; + struct mq_attr attr = { 0 }; + pthread_attr_t attr1; + pthread_t newTh, newTh2; + + ret = snprintf_s(g_gqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq097_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT3); + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + g_gqueue = mq_open(g_gqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(g_gqueue, (mqd_t)-1, g_gqueue, EXIT); + + g_testCount = 0; + + ret = PosixPthreadInit(&attr1, MQUEUE_PTHREAD_PRIORITY_TEST1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = pthread_create(&newTh, &attr1, PthreadF01, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = PosixPthreadInit(&attr1, MQUEUE_PTHREAD_PRIORITY_TEST2); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = pthread_create(&newTh2, &attr1, PthreadF02, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = LosTaskDelay(10); // 10, Set delay time. + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + TestAssertWaitDelay(&g_testCount, 4); // 4, Here, assert the g_testCount. + + ret = PosixPthreadDestroy(&attr1, newTh2); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = PosixPthreadDestroy(&attr1, newTh); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + return MQUEUE_NO_ERROR; + +EXIT2: + PosixPthreadDestroy(&attr1, newTh2); +EXIT1: + PosixPthreadDestroy(&attr1, newTh); +EXIT: + mq_close(g_gqueue); + mq_unlink(g_gqname); +EXIT3: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue097(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_097", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_098.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_098.cpp new file mode 100644 index 00000000..3a3fe30d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_098.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + CHAR qname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + INT32 ret = 0; + mqd_t queue; + + ret = snprintf_s(qname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq098_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + + queue = mq_open(qname, O_CREAT | O_RDWR | O_WRONLY, S_IRUSR | S_IWUSR, NULL); + ICUNIT_GOTO_NOT_EQUAL(queue, (mqd_t)-1, queue, EXIT); + + ret = mq_close(queue); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = mq_unlink(qname); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT: + mq_close(queue); + mq_unlink(qname); +EXIT1: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue098(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_098", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_100.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_100.cpp new file mode 100644 index 00000000..02637c82 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_100.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret = 0; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + CHAR msgrv[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + mqd_t mqueue; + struct timespec ts; + struct mq_attr attr = { 0 }; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq100_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + mqueue = mq_open(mqname, O_CREAT | O_NONBLOCK | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + ts.tv_sec = 1; + ts.tv_nsec = 0; + ret = mq_timedreceive(mqueue, msgrv, MQUEUE_STANDARD_NAME_LENGTH, NULL, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EAGAIN, errno, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue100(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_100", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_101.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_101.cpp new file mode 100644 index 00000000..ef149c08 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_101.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret, i; + mqd_t mqueue; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + struct mq_attr attr = { 0 }; + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq101_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + mqueue = mq_open(mqname, O_CREAT | O_RDWR | O_NONBLOCK, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + for (i = 0; i < 3; i++) { // 3, the loop frequency. + ret = mq_send(mqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + } + + for (i = 0; i < 3; i++) { // 3, the loop frequency. + ret = mq_receive(mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT1); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, MQUEUE_SEND_STRING_TEST, msgrcd, EXIT1); + } + + ret = mq_receive(mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EAGAIN, errno, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue101(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_101", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_102.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_102.cpp new file mode 100644 index 00000000..6fe9769e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_102.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret = 0; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + CHAR msgrv[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + const CHAR *msgptr = "test message"; + mqd_t mqueue; + struct timespec ts; + struct mq_attr attr = { 0 }; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq102_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + ret = mq_send(mqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ts.tv_sec = -1; + ts.tv_nsec = 0; + ret = mq_timedreceive(mqueue, msgrv, MQUEUE_STANDARD_NAME_LENGTH, NULL, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue102(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_102", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_103.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_103.cpp new file mode 100644 index 00000000..20891887 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_103.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret = 0; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + CHAR msgrv[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + const CHAR *msgptr = "test message"; + mqd_t mqueue; + struct timespec ts; + struct mq_attr attr = { 0 }; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq103_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + ret = mq_send(mqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + sleep(1); + ts.tv_sec = -1; + ts.tv_nsec = 0; + ret = mq_timedreceive(mqueue, msgrv, MQUEUE_STANDARD_NAME_LENGTH, NULL, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue103(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_103", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_104.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_104.cpp new file mode 100644 index 00000000..109b9257 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_104.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret = 0; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + CHAR msgrv1[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + CHAR msgrv2[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + const CHAR *msgptr1 = "test message1"; + const CHAR *msgptr2 = "test message2 with differnet length"; + mqd_t mqueue; + struct timespec ts; + struct mq_attr attr = { 0 }; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq104_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + ret = mq_send(mqueue, msgptr1, strlen(msgptr1), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_send(mqueue, msgptr2, strlen(msgptr2), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ts.tv_sec = 1; + ts.tv_nsec = 0; + ret = mq_timedreceive(mqueue, msgrv1, MQUEUE_STANDARD_NAME_LENGTH, NULL, &ts); + ICUNIT_GOTO_EQUAL(ret, strlen(msgptr1), ret, EXIT1); + + ret = mq_timedreceive(mqueue, msgrv2, MQUEUE_STANDARD_NAME_LENGTH, NULL, &ts); + ICUNIT_GOTO_EQUAL(ret, strlen(msgptr2), ret, EXIT1); + + ret = strcmp(msgrv1, msgptr1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = strcmp(msgrv2, msgptr2); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = strcmp(msgrv1, msgrv2); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue104(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_104", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_106.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_106.cpp new file mode 100644 index 00000000..fa6b9de8 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_106.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret = 0; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + CHAR msgrv[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + mqd_t mqueue; + struct timespec ts; + struct mq_attr attr = { 0 }; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq106_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + mqueue = (mqd_t)((UINTPTR)mqueue + PER_ADDED_VALUE); + ts.tv_sec = 1; + ts.tv_nsec = 0; + ret = mq_timedreceive(mqueue, msgrv, MQUEUE_STANDARD_NAME_LENGTH, NULL, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EBADF, errno, EXIT1); + + ret = mq_close((mqd_t)((UINTPTR)mqueue - PER_ADDED_VALUE)); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue106(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_106", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_108.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_108.cpp new file mode 100644 index 00000000..5c0afa2c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_108.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH], msgrv[MQUEUE_STANDARD_NAME_LENGTH]; + mqd_t mqdes; + struct timespec ts; + struct mq_attr attr = { 0 }; + INT32 unresolved = 0, failure = 0, ret = 0; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq108-1_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + mqdes = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqdes, (mqd_t)-1, mqdes, EXIT); + + ts.tv_sec = 1; + ts.tv_nsec = -1; + ret = mq_timedreceive(mqdes, msgrv, MQUEUE_STANDARD_NAME_LENGTH, NULL, &ts); + ICUNIT_GOTO_EQUAL(ret, -1, ret, EXIT); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT); + + ret = mq_close(mqdes); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT: + mq_close(mqdes); + mq_unlink(mqname); +EXIT1: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue108(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_108", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_109.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_109.cpp new file mode 100644 index 00000000..91c160f0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_109.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret = 0; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + CHAR msgrv[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + mqd_t mqueue; + struct timespec ts; + struct mq_attr attr = { 0 }; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq109_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + ts.tv_sec = 1; + ts.tv_nsec = 1000000000; // 1000000000, one seconds. + ret = mq_timedreceive(mqueue, msgrv, MQUEUE_STANDARD_NAME_LENGTH, NULL, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue109(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_109", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_110.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_110.cpp new file mode 100644 index 00000000..f107efe9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_110.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret = 0; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + CHAR msgrv[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + mqd_t mqueue; + struct timespec ts; + struct mq_attr attr = { 0 }; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq110_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + ts.tv_sec = 1; + ts.tv_nsec = 1000000000 + 1; // 1000000000, one second. + ret = mq_timedreceive(mqueue, msgrv, MQUEUE_STANDARD_NAME_LENGTH, NULL, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue110(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_110", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_111.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_111.cpp new file mode 100644 index 00000000..2e13de2b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_111.cpp @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static void *PthreadF01(void *arg) +{ + INT32 ret; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + + LOS_AtomicInc(&g_testCount); + + ret = mq_receive(g_gqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, MQUEUE_SEND_STRING_TEST, msgrcd, EXIT); + + return NULL; + +EXIT: + g_testCount = 0; + return NULL; +} + +static VOID *PthreadF02(VOID *arg) +{ + INT32 ret; + UINT32 ret1; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + struct mq_attr attr = { 0 }; + pthread_t pthread1; + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq111_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT3); + + g_gqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(g_gqueue, (mqd_t)-1, g_gqueue, EXIT2); + + LOS_AtomicInc(&g_testCount); + + ret = pthread_create(&pthread1, NULL, PthreadF01, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_send(g_gqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret1 = LosTaskDelay(1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT2); // 2, Here, assert the g_testCount. + + ret = pthread_join(pthread1, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = mq_close(g_gqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + LOS_AtomicInc(&g_testCount); + + return NULL; +EXIT2: + mq_close(g_gqueue); +EXIT1: + mq_unlink(mqname); +EXIT: + pthread_join(pthread1, NULL); +EXIT3: + return NULL; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + pthread_t pthread1; + pthread_attr_t attr1; + struct sched_param schedparam; + + g_testCount = 0; + + ret = pthread_attr_init(&attr1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + schedparam.sched_priority = MQUEUE_PTHREAD_PRIORITY_TEST2; + ret = pthread_attr_setschedparam(&attr1, &schedparam); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = pthread_create(&pthread1, &attr1, PthreadF02, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = LosTaskDelay(2); // 2, Set delay time. + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT1); // 3, Here, assert the g_testCount. + + ret = pthread_join(pthread1, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = pthread_attr_destroy(&attr1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + pthread_join(pthread1, NULL); +EXIT: + pthread_attr_destroy(&attr1); + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue111(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_111", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_112.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_112.cpp new file mode 100644 index 00000000..0c2af96a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_112.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static VOID *PthreadF01(VOID *arg) +{ + INT32 ret; + CHAR msgRcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + + LOS_AtomicInc(&g_testCount); + + ret = mq_receive(g_messageQId, msgRcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MSGLEN, ret, EXIT); + ICUNIT_GOTO_STRING_EQUAL(msgRcd, MQUEUE_SEND_STRING_TEST, msgRcd, EXIT); + + return NULL; +EXIT: + g_testCount = 0; + return NULL; +} +static UINT32 Testcase(VOID) +{ + pthread_t threadA; + pthread_attr_t attrA; + UINT32 ret; + struct sched_param sp; + + CHAR qName[MQUEUE_STANDARD_NAME_LENGTH] = ""; + const CHAR *msgPtr = MQUEUE_SEND_STRING_TEST; + struct mq_attr msgAttr = { 0 }; + msgAttr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + msgAttr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + g_testCount = 0; + + ret = snprintf_s(qName, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq112_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT); + + g_messageQId = mq_open(qName, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &msgAttr); + ICUNIT_GOTO_NOT_EQUAL(g_messageQId, (mqd_t)-1, g_messageQId, EXIT); + + ret = mq_send(g_messageQId, msgPtr, strlen(msgPtr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = pthread_attr_init(&attrA); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + pthread_attr_setinheritsched(&attrA, PTHREAD_EXPLICIT_SCHED); + + sp.sched_priority = MQUEUE_PTHREAD_PRIORITY_TEST2; + ret = pthread_attr_setschedparam(&attrA, &sp); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = pthread_create(&threadA, &attrA, PthreadF01, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + LosTaskDelay(2); // 2, Set delay time. + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT2); + + ret = pthread_join(threadA, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = pthread_attr_destroy(&attrA); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = mq_close(g_messageQId); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(qName); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + return MQUEUE_NO_ERROR; +EXIT2: + PosixPthreadDestroy(&attrA, threadA); +EXIT1: + mq_close(g_messageQId); + mq_unlink(qName); +EXIT: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue112(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_112", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_113.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_113.cpp new file mode 100644 index 00000000..106d6fba --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_113.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static VOID *PthreadF01(VOID *arg) +{ + INT32 ret; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + struct timespec ts = { 0 }; + + ts.tv_sec = 0xffff; + + g_testCount++; + + ret = mq_timedreceive(g_gqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, 0, &ts); + + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, MQUEUE_SEND_STRING_TEST, msgrcd, EXIT); + + return NULL; +EXIT: + g_testCount = 0; + return NULL; +} +static UINT32 Testcase(VOID) +{ + INT32 ret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + pthread_t pthread1; + pthread_attr_t attr1; + struct sched_param schedparam; + struct mq_attr attr = { 0 }; + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + g_testCount = 0; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq113_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT3); + + g_gqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(g_gqueue, (mqd_t)-1, g_gqueue, EXIT2); + + TestExtraTaskDelay(1); + + ret = pthread_attr_init(&attr1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + schedparam.sched_priority = MQUEUE_PTHREAD_PRIORITY_TEST2; + ret = pthread_attr_setschedparam(&attr1, &schedparam); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = pthread_create(&pthread1, &attr1, PthreadF01, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + usleep(0); + ICUNIT_GOTO_NOT_EQUAL(g_gqueue, (mqd_t)-1, g_gqueue, EXIT2); + + ret = mq_send(g_gqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + usleep(0); + + ret = pthread_join(pthread1, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT2); + + ret = mq_close(g_gqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = pthread_attr_destroy(&attr1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + return MQUEUE_NO_ERROR; + +EXIT2: + mq_close(g_gqueue); + mq_unlink(mqname); +EXIT1: + pthread_join(pthread1, NULL); +EXIT: + pthread_attr_destroy(&attr1); +EXIT3: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue113(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_113", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_114.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_114.cpp new file mode 100644 index 00000000..cf3c050b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_114.cpp @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static VOID *PthreadF01(VOID *arg) +{ + INT32 ret, count = 0; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + + while (count < MQUEUE_SHORT_ARRAY_LENGTH) { + LOS_AtomicInc(&g_testCount); + + ret = mq_receive(g_gqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, g_mqueueMsessage[count], msgrcd, EXIT); + + count++; + } + return NULL; +EXIT: + g_testCount = 0; + return NULL; +} + +static UINT32 Testcase(VOID) +{ + INT32 ret, count = 0; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + pthread_t pthread1; + pthread_attr_t attr1; + struct sched_param schedparam; + struct mq_attr attr = { 0 }; + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + g_testCount = 0; + + LOS_TaskLock(); + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq114_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT3); + + g_gqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(g_gqueue, (mqd_t)-1, g_gqueue, EXIT2); + + ret = pthread_attr_init(&attr1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + schedparam.sched_priority = MQUEUE_PTHREAD_PRIORITY_TEST2; + ret = pthread_attr_setschedparam(&attr1, &schedparam); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = pthread_create(&pthread1, &attr1, PthreadF01, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + LOS_TaskUnlock(); + + while (count < MQUEUE_SHORT_ARRAY_LENGTH) { + LOS_AtomicInc(&g_testCount); + + ret = mq_send(g_gqueue, g_mqueueMsessage[count], MQUEUE_SHORT_ARRAY_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + count++; + } + + ret = pthread_join(pthread1, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + TestExtraTaskDelay(2); // 2, Set delay time. + ICUNIT_GOTO_EQUAL(g_testCount, MQUEUE_SHORT_ARRAY_LENGTH * 2, g_testCount, EXIT2); + + ret = mq_close(g_gqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = pthread_attr_destroy(&attr1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + return MQUEUE_NO_ERROR; +EXIT2: + mq_close(g_gqueue); + mq_unlink(mqname); +EXIT1: + pthread_join(pthread1, NULL); +EXIT: + pthread_attr_destroy(&attr1); +EXIT3: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue114(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_114", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_115.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_115.cpp new file mode 100644 index 00000000..eedbc942 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_115.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static VOID *PthreadF01(VOID *arg) +{ + INT32 ret, count = 0; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + + while (count < MQUEUE_SHORT_ARRAY_LENGTH) { + LOS_AtomicInc(&g_testCount); + + ret = mq_receive(g_gqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, g_mqueueMsessage[count], msgrcd, EXIT); + + count++; + } + return NULL; +EXIT: + g_testCount = 0; + return NULL; +} + + +static UINT32 Testcase(VOID) +{ + INT32 ret, count = 0; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + pthread_t pthread1; + pthread_attr_t attr1; + struct sched_param schedparam; + struct mq_attr attr = { 0 }; + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_SHORT_ARRAY_LENGTH; + + g_testCount = 0; + + LOS_TaskLock(); + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq115_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT3); + + g_gqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(g_gqueue, (mqd_t)-1, g_gqueue, EXIT2); + + ret = pthread_attr_init(&attr1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + schedparam.sched_priority = MQUEUE_PTHREAD_PRIORITY_TEST2; + ret = pthread_attr_setschedparam(&attr1, &schedparam); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = pthread_create(&pthread1, &attr1, PthreadF01, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + while (count < MQUEUE_SHORT_ARRAY_LENGTH) { + LOS_AtomicInc(&g_testCount); + ret = mq_send(g_gqueue, g_mqueueMsessage[count], MQUEUE_SHORT_ARRAY_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + count++; + } + + LOS_TaskUnlock(); + + ret = pthread_join(pthread1, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ICUNIT_GOTO_EQUAL(g_testCount, MQUEUE_SHORT_ARRAY_LENGTH * 2, g_testCount, EXIT2); // 2, Here, assert g_testCount. + + ret = mq_close(g_gqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = pthread_attr_destroy(&attr1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT2: + mq_close(g_gqueue); + mq_unlink(mqname); +EXIT1: + pthread_join(pthread1, NULL); +EXIT: + pthread_attr_destroy(&attr1); +EXIT3: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue115(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_115", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_116.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_116.cpp new file mode 100644 index 00000000..9e0fa7e2 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_116.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static VOID *PthreadF01(VOID *arg) +{ + INT32 ret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + struct mq_attr attr = { 0 }; + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + LOS_AtomicInc(&g_testCount); + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq116_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + g_gqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(g_gqueue, (mqd_t)-1, g_gqueue, EXIT1); + + ret = mq_send(g_gqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_receive(g_gqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT1); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, MQUEUE_SEND_STRING_TEST, msgrcd, EXIT1); + + ret = mq_close(g_gqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return NULL; +EXIT1: + mq_close(g_gqueue); +EXIT: + mq_unlink(mqname); + g_testCount = 0; +EXIT2: + return NULL; +} + +static UINT32 Testcase(VOID) +{ + INT32 ret; + pthread_t pthread1; + pthread_attr_t attr1; + struct sched_param schedparam; + + g_testCount = 0; + + LOS_TaskLock(); + + ret = pthread_attr_init(&attr1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + schedparam.sched_priority = MQUEUE_PTHREAD_PRIORITY_TEST2; + ret = pthread_attr_setschedparam(&attr1, &schedparam); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = pthread_create(&pthread1, &attr1, PthreadF01, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + LOS_TaskUnlock(); + + ret = pthread_join(pthread1, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = pthread_attr_destroy(&attr1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + return MQUEUE_NO_ERROR; + +EXIT1: + pthread_join(pthread1, NULL); +EXIT: + pthread_attr_destroy(&attr1); + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue116(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_116", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_117.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_117.cpp new file mode 100644 index 00000000..c1dbcfdb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_117.cpp @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static VOID *PthreadF01(VOID *arg) +{ + INT32 ret; + CHAR msgRcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + struct timespec rcdTimeout = { 0 }; + rcdTimeout.tv_sec = 0xffff; + + LOS_AtomicInc(&g_testCount); + + ret = mq_timedreceive(g_messageQId, msgRcd, MQUEUE_STANDARD_NAME_LENGTH, NULL, &rcdTimeout); + ICUNIT_GOTO_EQUAL(ret, MSGLEN, ret, NOK); + ICUNIT_GOTO_STRING_EQUAL(msgRcd, MQUEUE_SEND_STRING_TEST, msgRcd, NOK); + +NOK: + return NULL; +} +static UINT32 Testcase(VOID) +{ + pthread_t threadA; + pthread_attr_t attrA; + UINT32 ret; + struct sched_param sp; + + CHAR qName[MQUEUE_STANDARD_NAME_LENGTH] = ""; + const CHAR *msgPtr = MQUEUE_SEND_STRING_TEST; + struct mq_attr msgAttr = { 0 }; + + msgAttr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + msgAttr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + g_testCount = 0; + + LOS_TaskLock(); + ret = snprintf_s(qName, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq117_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT); + + g_messageQId = mq_open(qName, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &msgAttr); + ICUNIT_GOTO_NOT_EQUAL(g_messageQId, (mqd_t)-1, g_messageQId, EXIT2); + + ret = pthread_attr_init(&attrA); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + sp.sched_priority = MQUEUE_PTHREAD_PRIORITY_TEST2; + ret = pthread_attr_setschedparam(&attrA, &sp); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = pthread_create(&threadA, &attrA, PthreadF01, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + LOS_TaskUnlock(); + + ret = mq_send(g_messageQId, msgPtr, strlen(msgPtr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + LosTaskDelay(1); + + ret = pthread_join(threadA, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = pthread_attr_destroy(&attrA); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT3); + + ret = mq_close(g_messageQId); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT3); + + ret = mq_unlink(qName); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT3); + + return MQUEUE_NO_ERROR; +EXIT3: + mq_close(g_messageQId); + mq_unlink(qName); + return MQUEUE_NO_ERROR; +EXIT2: + mq_close(g_messageQId); + mq_unlink(qName); +EXIT1: + PosixPthreadDestroy(&attrA, threadA); +EXIT: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue117(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_117", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_118.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_118.cpp new file mode 100644 index 00000000..91af0c1a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_118.cpp @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static VOID *PthreadF01(VOID *arg) +{ + INT32 ret, count = 0; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + + TestExtraTaskDelay(1); + + ICUNIT_GOTO_EQUAL(g_testCount, MQUEUE_SHORT_ARRAY_LENGTH, g_testCount, EXIT); + + while (count < MQUEUE_SHORT_ARRAY_LENGTH) { + LOS_AtomicInc(&g_testCount); + + ret = mq_receive(g_gqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, g_mqueueMsessage[count], msgrcd, EXIT); + + count++; + } + return NULL; + +EXIT: + g_testCount = 0; + return NULL; +} + +static VOID *PthreadF02(VOID *arg) +{ + INT32 ret, count = 0; + + LOS_TaskLock(); + + while (count < MQUEUE_SHORT_ARRAY_LENGTH) { + LOS_AtomicInc(&g_testCount); + ret = mq_send(g_gqueue, g_mqueueMsessage[count], MQUEUE_SHORT_ARRAY_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + count++; + } + + ret = mq_send(g_gqueue, g_mqueueMsessage[count], MQUEUE_SHORT_ARRAY_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT); + + LOS_TaskUnlock(); + + return NULL; + +EXIT: + g_testCount = 0; + return NULL; +} + +static UINT32 Testcase(VOID) +{ + INT32 ret; + UINT32 uret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + pthread_t pthread1; + pthread_attr_t attr1; + pthread_t pthread2; + pthread_attr_t attr2; + struct sched_param schedparam; + struct mq_attr attr = { 0 }; + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_SHORT_ARRAY_LENGTH; + + g_testCount = 0; + + LOS_TaskLock(); + + (void)snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, + "/mq118_%d", LosCurTaskIDGet()); + + g_gqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(g_gqueue, (mqd_t)-1, g_gqueue, EXIT); + + ret = pthread_attr_init(&attr1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + schedparam.sched_priority = MQUEUE_PTHREAD_PRIORITY_TEST2; + ret = pthread_attr_setschedparam(&attr1, &schedparam); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = pthread_create(&pthread1, &attr1, PthreadF02, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = pthread_attr_init(&attr2); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + schedparam.sched_priority = MQUEUE_PTHREAD_PRIORITY_TEST2; + ret = pthread_attr_setschedparam(&attr2, &schedparam); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = pthread_create(&pthread2, &attr2, PthreadF01, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + LOS_TaskUnlock(); + + uret = LosTaskDelay(5); // 5, Set delay time. + ICUNIT_GOTO_EQUAL(uret, MQUEUE_NO_ERROR, uret, EXIT2); + + ret = pthread_join(pthread2, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = pthread_attr_destroy(&attr2); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = pthread_join(pthread1, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = pthread_attr_destroy(&attr1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ICUNIT_GOTO_EQUAL(g_testCount, MQUEUE_SHORT_ARRAY_LENGTH * 2, g_testCount, EXIT); // 2, mqueue message length. + ret = mq_close(g_gqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT2: + PosixPthreadDestroy(&attr2, pthread2); +EXIT1: + PosixPthreadDestroy(&attr1, pthread1); +EXIT: + mq_close(g_gqueue); + mq_unlink(mqname); + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue118(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_118", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_119.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_119.cpp new file mode 100644 index 00000000..9e23add7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_119.cpp @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static VOID *PthreadF01(VOID *arg) +{ + TEST_HwiTrigger(HWI_NUM_TEST); + + LOS_AtomicInc(&g_testCount); + + return NULL; +} + +static VOID HwiF01(VOID *arg) +{ + INT32 ret; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + struct timespec ts = { 0 }; + + ts.tv_sec = 0; + + TEST_HwiClear(HWI_NUM_TEST); + + LOS_AtomicInc(&g_testCount); + + ret = mq_timedsend(g_gqueue, msgptr, strlen(msgptr), 0, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return; +EXIT: + g_testCount = 0; + return; +} + +static VOID *PthreadF02(VOID *arg) +{ + INT32 ret; + UINT32 uret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + pthread_t pthread1; + struct mq_attr attr = { 0 }; + struct timespec ts = { 0 }; + + ts.tv_sec = 10; // 10, secend. + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + LOS_AtomicInc(&g_testCount); + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq119_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT3); + + g_gqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(g_gqueue, (mqd_t)-1, g_gqueue, EXIT); + + ret = LOS_HwiCreate(HWI_NUM_TEST, 0, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = pthread_create(&pthread1, NULL, PthreadF01, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + usleep(10000); // 10000, Microseconds. + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT2); // 3, Here, assert the g_testCount. + + ret = mq_timedreceive(g_gqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT2); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, MQUEUE_SEND_STRING_TEST, msgrcd, EXIT2); + + ret = pthread_join(pthread1, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = mq_close(g_gqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + TEST_HwiDelete(HWI_NUM_TEST); + + LOS_AtomicInc(&g_testCount); + + return MQUEUE_NO_ERROR; +EXIT2: + TEST_HwiDelete(HWI_NUM_TEST); +EXIT1: + pthread_join(pthread1, NULL); +EXIT: + mq_close(g_gqueue); + mq_unlink(mqname); +EXIT3: + return MQUEUE_NO_ERROR; +} + +static UINT32 Testcase(VOID) +{ + INT32 ret; + pthread_t pthread1; + pthread_attr_t attr1; + struct sched_param schedparam; + + g_testCount = 0; + + ret = pthread_attr_init(&attr1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + schedparam.sched_priority = MQUEUE_PTHREAD_PRIORITY_TEST2; + ret = pthread_attr_setschedparam(&attr1, &schedparam); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = pthread_create(&pthread1, &attr1, PthreadF02, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = pthread_join(pthread1, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = pthread_attr_destroy(&attr1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, Here, assert the g_testCount. + + return MQUEUE_NO_ERROR; + +EXIT1: + pthread_join(pthread1, NULL); +EXIT: + pthread_attr_destroy(&attr1); + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue119(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_119", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_120.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_120.cpp new file mode 100644 index 00000000..1def3053 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_120.cpp @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static VOID *PthreadF01(VOID *arg) +{ + INT32 ret; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + struct timespec ts = { 0 }; + + ts.tv_sec = 0xffff; + + LOS_AtomicInc(&g_testCount); + + ret = mq_timedreceive(g_gqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, g_mqueueMsessage[2], msgrcd, EXIT); // 2, g_mqueueMsessage buffer index. + + LOS_AtomicInc(&g_testCount); + return NULL; +EXIT: + g_testCount = 0; + return NULL; +} + +static VOID *PthreadF02(VOID *arg) +{ + INT32 ret; + UINT32 pri; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + struct timespec ts = { 0 }; + ts.tv_sec = 0xffff; + + LOS_AtomicInc(&g_testCount); + + ret = mq_timedreceive(g_gqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, &pri, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, g_mqueueMsessage[1], msgrcd, EXIT); + + LOS_AtomicInc(&g_testCount); + return NULL; +EXIT: + g_testCount = 0; + return NULL; +} + +static UINT32 Testcase(VOID) +{ + INT32 ret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + pthread_t pthread1; + pthread_attr_t attr1; + pthread_t pthread2; + pthread_attr_t attr2; + struct sched_param schedparam1; + struct sched_param schedparam2; + struct mq_attr attr = { 0 }; + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + g_testCount = 0; + + (void)snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, + "/mq120_%d", LosCurTaskIDGet()); + + g_gqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(g_gqueue, (mqd_t)-1, g_gqueue, EXIT1); + + ret = pthread_attr_init(&attr1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + schedparam1.sched_priority = MQUEUE_PTHREAD_PRIORITY_TEST2; + ret = pthread_attr_setschedparam(&attr1, &schedparam1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = pthread_create(&pthread1, &attr1, PthreadF02, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = pthread_attr_init(&attr2); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + schedparam2.sched_priority = MQUEUE_PTHREAD_PRIORITY_TEST2 - 2; // 2, Pthread schedul priority. + ret = pthread_attr_setschedparam(&attr2, &schedparam2); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT3); + + ret = pthread_create(&pthread2, &attr2, PthreadF01, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT3); + + ret = mq_send(g_gqueue, g_mqueueMsessage[1], MQUEUE_SHORT_ARRAY_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT3); + + ret = mq_send(g_gqueue, g_mqueueMsessage[2], MQUEUE_SHORT_ARRAY_LENGTH, 0); // 2, mqueue message buffer index. + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT3); + + TestExtraTaskDelay(3); // 3, Set delay time. + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT3); // 4, Here, assert the g_testCount. + + ret = pthread_join(pthread1, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT3); + + ret = pthread_attr_destroy(&attr1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT3); + + ret = pthread_join(pthread2, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = pthread_attr_destroy(&attr2); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = mq_close(g_gqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT3: + pthread_attr_destroy(&attr1); +EXIT2: + pthread_attr_destroy(&attr2); +EXIT1: + mq_close(g_gqueue); +EXIT: + mq_unlink(mqname); + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue120(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_120", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_121.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_121.cpp new file mode 100644 index 00000000..0f40cff8 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_121.cpp @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static VOID *PthreadF01(VOID *arg) +{ + INT32 ret; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + struct timespec ts = { 0 }; + + ts.tv_sec = 0xffff; + + LOS_AtomicInc(&g_testCount); + + ret = mq_timedreceive(g_gqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, g_mqueueMsessage[4], msgrcd, EXIT); // 4, g_mqueueMsessage buffer index. + + LOS_AtomicInc(&g_testCount); + return NULL; +EXIT: + g_testCount = 0; + return NULL; +} + +static VOID *PthreadF02(VOID *arg) +{ + INT32 ret; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + struct timespec ts = { 0 }; + + ts.tv_sec = 0xffff; + + LOS_AtomicInc(&g_testCount); + + ret = mq_timedreceive(g_gqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, g_mqueueMsessage[3], msgrcd, EXIT); // 3, g_mqueueMsessage buffer index. + + LOS_AtomicInc(&g_testCount); + return NULL; +EXIT: + g_testCount = 0; + return NULL; +} + +static VOID *PthreadF03(VOID *arg) +{ + INT32 ret; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + + struct timespec ts = { 0 }; + ts.tv_sec = 0xffff; + + LOS_AtomicInc(&g_testCount); + + ret = mq_timedreceive(g_gqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, g_mqueueMsessage[2], msgrcd, EXIT); // 2, g_mqueueMsessage buffer index. + + LOS_AtomicInc(&g_testCount); + return NULL; +EXIT: + g_testCount = 0; + return NULL; +} + +static VOID *PthreadF04(VOID *arg) +{ + INT32 ret; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + struct timespec ts = { 0 }; + + ts.tv_sec = 0xffff; + + LOS_AtomicInc(&g_testCount); + + ret = mq_timedreceive(g_gqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, g_mqueueMsessage[1], msgrcd, EXIT); + + LOS_AtomicInc(&g_testCount); + +EXIT: + return NULL; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + + pthread_t threadA; + pthread_attr_t attrA; + struct sched_param spA; + + pthread_t threadB; + pthread_attr_t attrB; + struct sched_param spB; + + pthread_t threadC; + pthread_attr_t attrC; + struct sched_param spC; + + pthread_t threadD; + pthread_attr_t attrD; + struct sched_param spD; + + struct mq_attr msgAttr = { 0 }; + CHAR qName[MQUEUE_STANDARD_NAME_LENGTH] = ""; + + msgAttr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + msgAttr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + g_testCount = 0; + + (void)snprintf_s(qName, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq121_%d", LosCurTaskIDGet()); + + g_messageQId = mq_open(qName, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &msgAttr); + ICUNIT_GOTO_NOT_EQUAL(g_messageQId, (mqd_t)-1, g_messageQId, EXIT); + + ret = pthread_attr_init(&attrA); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + pthread_attr_setinheritsched(&attrA, PTHREAD_EXPLICIT_SCHED); + + spA.sched_priority = MQUEUE_PTHREAD_PRIORITY_TEST2; + ret = pthread_attr_setschedparam(&attrA, &spA); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_create(&threadA, &attrA, PthreadF04, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT1); + + ret = pthread_attr_init(&attrB); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT1); + pthread_attr_setinheritsched(&attrB, PTHREAD_EXPLICIT_SCHED); + spB.sched_priority = 2; // 2, Queue pthread priority. + ret = pthread_attr_setschedparam(&attrB, &spB); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT2); + + ret = pthread_create(&threadB, &attrB, PthreadF03, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT2); + + ret = pthread_attr_init(&attrC); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT2); + + pthread_attr_setinheritsched(&attrC, PTHREAD_EXPLICIT_SCHED); + + spC.sched_priority = 2; // 2, Queue pthread priority. + ret = pthread_attr_setschedparam(&attrC, &spC); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT3); + + ret = pthread_create(&threadC, &attrC, PthreadF02, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT3); + + ret = pthread_attr_init(&attrD); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT3); + + pthread_attr_setinheritsched(&attrD, PTHREAD_EXPLICIT_SCHED); + + spD.sched_priority = 1; + ret = pthread_attr_setschedparam(&attrD, &spD); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT4); + + ret = pthread_create(&threadD, &attrD, PthreadF01, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT4); + + ret = mq_send(g_messageQId, g_mqueueMsessage[1], MSGLEN, 0); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT4); + + ret = mq_send(g_messageQId, g_mqueueMsessage[2], MSGLEN, 0); // 2, g_mqueueMsessage buffer index. + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT4); + + ret = mq_send(g_messageQId, g_mqueueMsessage[3], MSGLEN, 0); // 3, g_mqueueMsessage buffer index. + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT4); + + ret = mq_send(g_messageQId, g_mqueueMsessage[4], MSGLEN, 0); // 4, g_mqueueMsessage buffer index. + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT4); + + TestExtraTaskDelay(3); // 3, Set delay time. + ICUNIT_GOTO_EQUAL(g_testCount, 8, g_testCount, EXIT4); // 8, Here, assert the g_testCount. + + ret = pthread_join(threadD, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT4); + ret = pthread_attr_destroy(&attrD); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT4); + + ret = pthread_join(threadC, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT3); + ret = pthread_attr_destroy(&attrC); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT3); + + ret = pthread_join(threadB, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT2); + ret = pthread_attr_destroy(&attrB); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT2); + + ret = pthread_join(threadA, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT4); + ret = pthread_attr_destroy(&attrA); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT4); + + ret = mq_close(g_messageQId); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = mq_unlink(qName); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + return MQUEUE_NO_ERROR; + +EXIT4: + pthread_join(threadD, NULL); + pthread_attr_destroy(&attrD); +EXIT3: + pthread_join(threadC, NULL); + pthread_attr_destroy(&attrC); +EXIT2: + pthread_join(threadB, NULL); + pthread_attr_destroy(&attrA); +EXIT1: + pthread_join(threadB, NULL); + pthread_attr_destroy(&attrA); +EXIT: + mq_close(g_messageQId); + mq_unlink(qName); + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue121(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_121", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_122.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_122.cpp new file mode 100644 index 00000000..de3753fc --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_122.cpp @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static VOID HwiF01(VOID *arg) +{ + INT32 ret; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + struct timespec ts = { 0 }; + + ts.tv_sec = 0; + + TEST_HwiClear(HWI_NUM_TEST); + + LOS_AtomicInc(&g_testCount); + + ret = mq_timedreceive(g_gqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, MQUEUE_SEND_STRING_TEST, msgrcd, EXIT); + + LOS_AtomicInc(&g_testCount); + + return; + +EXIT: + g_testCount = 0; + return; +} + +static UINT32 Testcase(VOID) +{ + INT32 ret; + UINT32 uret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + struct mq_attr attr = { 0 }; + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + g_testCount = 0; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq122_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT3); + + g_gqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(g_gqueue, (mqd_t)-1, g_gqueue, EXIT1); + + ret = mq_send(g_gqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + uret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_GOTO_EQUAL(uret, MQUEUE_NO_ERROR, uret, EXIT2); + + TEST_HwiTrigger(HWI_NUM_TEST); + + uret = LosTaskDelay(2); // 2, Set delay time. + ICUNIT_GOTO_EQUAL(uret, MQUEUE_NO_ERROR, uret, EXIT2); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT2); // 2, Here, assert the g_testCount. + + TEST_HwiDelete(HWI_NUM_TEST); + + ret = mq_close(g_gqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT2: + TEST_HwiDelete(HWI_NUM_TEST); +EXIT1: + mq_close(g_gqueue); +EXIT: + mq_unlink(mqname); +EXIT3: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue122(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_122", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_123.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_123.cpp new file mode 100644 index 00000000..7d34a05f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_123.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static VOID HwiF01(VOID *arg) +{ + INT32 ret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + struct timespec ts = { 0 }; + struct mq_attr attr = { 0 }; + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + ts.tv_sec = 0; + + TEST_HwiClear(HWI_NUM_TEST); + + LOS_AtomicInc(&g_testCount); + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq123_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + + g_gqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(g_gqueue, (mqd_t)-1, g_gqueue, EXIT); + + ret = mq_timedsend(g_gqueue, msgptr, strlen(msgptr), 0, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + LOS_AtomicInc(&g_testCount); + + ret = mq_close(g_gqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return; + +EXIT: + mq_close(g_gqueue); + mq_unlink(mqname); + g_testCount = 0; +EXIT1: + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 uret; + + g_testCount = 0; + + uret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_GOTO_EQUAL(uret, MQUEUE_NO_ERROR, uret, EXIT); + + TEST_HwiTrigger(HWI_NUM_TEST); + + uret = LosTaskDelay(2); // 2, Set delay time. + ICUNIT_GOTO_EQUAL(uret, MQUEUE_NO_ERROR, uret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert the g_testCount. + + TEST_HwiDelete(HWI_NUM_TEST); + + return MQUEUE_NO_ERROR; +EXIT: + TEST_HwiDelete(HWI_NUM_TEST); + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue123(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_123", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_124.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_124.cpp new file mode 100644 index 00000000..3cf6adaf --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_124.cpp @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static VOID HwiF01(VOID *arg) +{ + INT32 ret; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + struct timespec ts = { 0 }; + + ts.tv_sec = 0; + + TEST_HwiClear(HWI_NUM_TEST); + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, Here, assert the g_testCount. + + LOS_AtomicInc(&g_testCount); + + ret = mq_timedreceive(g_gqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, MQUEUE_SEND_STRING_TEST, msgrcd, EXIT); + + LOS_AtomicInc(&g_testCount); + + ret = mq_close(g_gqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(g_gqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + return; + +EXIT: + mq_close(g_gqueue); + mq_unlink(g_gqname); + return; +} + +static VOID HwiF02(VOID *arg) +{ + INT32 ret; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + struct timespec ts = { 0 }; + struct mq_attr attr = { 0 }; + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + ts.tv_sec = 0; + + TEST_HwiClear(HWI_NUM_TEST1); + + LOS_AtomicInc(&g_testCount); + + g_gqueue = mq_open(g_gqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(g_gqueue, (mqd_t)-1, g_gqueue, EXIT); + + ret = mq_timedsend(g_gqueue, msgptr, strlen(msgptr), 0, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + LOS_AtomicInc(&g_testCount); + + return; + +EXIT: + mq_close(g_gqueue); + mq_unlink(g_gqname); + return; +} + +static UINT32 Testcase(VOID) +{ + UINT32 uret; + INT32 ret; + + g_testCount = 0; + + ret = snprintf_s(g_gqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq124_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT); + + uret = LOS_HwiCreate(HWI_NUM_TEST1, 1, 0, (HWI_PROC_FUNC)HwiF02, 0); + ICUNIT_GOTO_EQUAL(uret, MQUEUE_NO_ERROR, uret, EXIT); + +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST1, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + TEST_HwiTrigger(HWI_NUM_TEST1); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert the g_testCount. + + uret = LOS_HwiCreate(HWI_NUM_TEST, 1, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_GOTO_EQUAL(uret, MQUEUE_NO_ERROR, uret, EXIT1); + +#ifdef LOSCFG_KERNEL_SMP + HalIrqSetAffinity(HWI_NUM_TEST, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); +#endif + + LOS_AtomicInc(&g_testCount); + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT1); // 3, Here, assert the g_testCount. + + TEST_HwiTrigger(HWI_NUM_TEST); + + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT1); // 5, Here, assert the g_testCount. + + TEST_HwiDelete(HWI_NUM_TEST); + + TEST_HwiDelete(HWI_NUM_TEST1); + + return MQUEUE_NO_ERROR; + +EXIT1: + TEST_HwiDelete(HWI_NUM_TEST); +EXIT: + TEST_HwiDelete(HWI_NUM_TEST1); + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue124(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_124", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_125.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_125.cpp new file mode 100644 index 00000000..60f323a3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_125.cpp @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static VOID HwiF01(VOID *arg) +{ + INT32 ret; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + struct timespec ts = { 0 }; + + ts.tv_sec = 0; + + TEST_HwiClear(HWI_NUM_TEST); + + LOS_AtomicInc(&g_testCount); + + ret = mq_timedreceive(g_gqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, MQUEUE_SEND_STRING_TEST, msgrcd, EXIT); + + ret = mq_close(g_gqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(g_gqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + LOS_AtomicInc(&g_testCount); + + return; + +EXIT: + g_testCount = 0; + TEST_HwiDelete(HWI_NUM_TEST); + mq_close(g_gqueue); + mq_unlink(g_gqname); + return; +} + +static VOID *PthreadF01(VOID *arg) +{ + INT32 ret; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + struct mq_attr attr = { 0 }; + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + LOS_AtomicInc(&g_testCount); + + g_gqueue = mq_open(g_gqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(g_gqueue, (mqd_t)-1, g_gqueue, EXIT); + + ret = mq_send(g_gqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + LOS_AtomicInc(&g_testCount); + + return NULL; + +EXIT: + g_testCount = 0; + mq_close(g_gqueue); + mq_unlink(g_gqname); + return NULL; +} + + +static UINT32 Testcase(VOID) +{ + INT32 ret; + UINT32 uret; + pthread_t pthread1; + pthread_attr_t attr1; + struct sched_param schedparam; + + g_testCount = 0; + + ret = snprintf_s(g_gqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq125_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT3); + + ret = pthread_attr_init(&attr1); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + schedparam.sched_priority = MQUEUE_PTHREAD_PRIORITY_TEST2; + ret = pthread_attr_setschedparam(&attr1, &schedparam); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_create(&pthread1, &attr1, PthreadF01, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT1); + TestExtraTaskDelay(2); // 2, Set delay time. + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert the g_testCount. + + LOS_AtomicInc(&g_testCount); + + uret = LOS_HwiCreate(HWI_NUM_TEST, 0, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_GOTO_EQUAL(uret, MQUEUE_NO_ERROR, uret, EXIT2); + + TEST_HwiTrigger(HWI_NUM_TEST); + + uret = LosTaskDelay(2); // 2, Set delay time. + ICUNIT_GOTO_EQUAL(uret, MQUEUE_NO_ERROR, uret, EXIT2); + + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT2); // 5, Here, assert the g_testCount. + + ret = pthread_join(pthread1, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT1); + + ret = pthread_attr_destroy(&attr1); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + TEST_HwiDelete(HWI_NUM_TEST); + + return MQUEUE_NO_ERROR; + +EXIT2: + TEST_HwiDelete(HWI_NUM_TEST); +EXIT1: + pthread_join(pthread1, NULL); +EXIT: + pthread_attr_destroy(&attr1); +EXIT3: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue125(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_125", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_126.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_126.cpp new file mode 100644 index 00000000..ac45f4a9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_126.cpp @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static VOID *PthreadF01(VOID *arg) +{ + INT32 ret; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + + LOS_AtomicInc(&g_testCount); + + ret = mq_receive(g_gqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, MQUEUE_SEND_STRING_TEST, msgrcd, EXIT); + + LOS_AtomicInc(&g_testCount); + + ret = mq_close(g_gqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(g_gqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return NULL; + +EXIT: + g_testCount = 0; + mq_close(g_gqueue); + mq_unlink(g_gqname); + return NULL; +} + +static VOID HwiF01(VOID *arg) +{ + INT32 ret; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + struct timespec ts = { 0 }; + struct mq_attr attr = { 0 }; + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + ts.tv_sec = 0; + + TEST_HwiClear(HWI_NUM_TEST); + + LOS_AtomicInc(&g_testCount); + + g_gqueue = mq_open(g_gqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(g_gqueue, (mqd_t)-1, g_gqueue, EXIT); + + ret = mq_timedsend(g_gqueue, msgptr, strlen(msgptr), 0, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + LOS_AtomicInc(&g_testCount); + + return; +EXIT: + g_testCount = 0; + mq_close(g_gqueue); + mq_unlink(g_gqname); + return; +} + +static UINT32 Testcase(VOID) +{ + INT32 ret; + UINT32 uret; + pthread_t pthread1; + pthread_attr_t attr1; + struct sched_param schedparam; + + g_testCount = 0; + + ret = snprintf_s(g_gqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq126_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT3); + + uret = LOS_HwiCreate(HWI_NUM_TEST, 0, 0, (HWI_PROC_FUNC)HwiF01, 0); + ICUNIT_GOTO_EQUAL(uret, MQUEUE_NO_ERROR, uret, EXIT); + + TEST_HwiTrigger(HWI_NUM_TEST); + + uret = LosTaskDelay(2); // 2, Set delay time. + ICUNIT_GOTO_EQUAL(uret, MQUEUE_NO_ERROR, uret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, Here, assert the g_testCount. + + LOS_AtomicInc(&g_testCount); + + ret = pthread_attr_init(&attr1); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT1); + + schedparam.sched_priority = MQUEUE_PTHREAD_PRIORITY_TEST2; + ret = pthread_attr_setschedparam(&attr1, &schedparam); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT1); + + ret = pthread_create(&pthread1, &attr1, PthreadF01, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT2); + + TestExtraTaskDelay(2); // 2, Set delay time. + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT2); // 5, Here, assert the g_testCount. + + ret = pthread_join(pthread1, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT2); + + ret = pthread_attr_destroy(&attr1); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT1); + + TEST_HwiDelete(HWI_NUM_TEST); + + return MQUEUE_NO_ERROR; +EXIT2: + pthread_join(pthread1, NULL); +EXIT1: + pthread_attr_destroy(&attr1); +EXIT: + TEST_HwiDelete(HWI_NUM_TEST); +EXIT3: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue126(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_126", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_127.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_127.cpp new file mode 100644 index 00000000..8e39a2d5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_127.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + + CHAR qName[MQUEUE_STANDARD_NAME_LENGTH] = "/mq127"; + mqd_t msgQId1; + mqd_t msgQId2; + + struct mq_attr msgAttr = { 0 }; + msgAttr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + msgAttr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + msgQId1 = mq_open(qName, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &msgAttr); + ICUNIT_GOTO_NOT_EQUAL(msgQId1, (mqd_t)-1, msgQId1, EXIT1); + + msgQId2 = mq_open(qName, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &msgAttr); + ICUNIT_GOTO_NOT_EQUAL(msgQId2, (mqd_t)-1, msgQId2, EXIT2); + + ret = mq_close(msgQId2); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = mq_close(msgQId1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(qName); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT2: + mq_close(msgQId2); +EXIT1: + mq_close(msgQId1); +EXIT: + mq_unlink(qName); + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue127(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_127", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_128.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_128.cpp new file mode 100644 index 00000000..b05e6aa5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_128.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + mqd_t mqueue; + struct mq_attr attr = { 0 }; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq128_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT); + ICUNIT_GOTO_EQUAL(errno, ENOENT, errno, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue128(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_128", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_129.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_129.cpp new file mode 100644 index 00000000..ff8dd622 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_129.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret, i; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + mqd_t mqueue; + struct mq_attr attr = { 0 }; + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_SHORT_ARRAY_LENGTH; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq129_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + for (i = 0; i < 0xffff; i++) { + ret = mq_send(mqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_receive(mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT1); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, MQUEUE_SEND_STRING_TEST, msgrcd, EXIT1); + } + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; + +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue129(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_129", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_130.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_130.cpp new file mode 100644 index 00000000..d4cfa92b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_130.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + struct mq_attr attr = { 0 }; + + attr.mq_msgsize = 0; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq130_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + + g_gqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_EQUAL(g_gqueue, (mqd_t)-1, g_gqueue, EXIT); + + ret = mq_send(g_gqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT); + ICUNIT_GOTO_EQUAL(errno, EBADF, errno, EXIT); + + ret = mq_receive(g_gqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT); + ICUNIT_GOTO_EQUAL(errno, EBADF, errno, EXIT); + + return MQUEUE_NO_ERROR; +EXIT: + mq_close(g_gqueue); + mq_unlink(mqname); +EXIT1: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue130(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_130", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_133.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_133.cpp new file mode 100644 index 00000000..a47adcbc --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_133.cpp @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static VOID *PthreadF01(VOID *arg) +{ + INT32 ret; + CHAR msgRcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + struct timespec rcdTimeout = { 0 }; + rcdTimeout.tv_sec = 0xffff; + + LOS_AtomicInc(&g_testCount); + + ret = mq_timedreceive(g_messageQId, msgRcd, MQUEUE_STANDARD_NAME_LENGTH, NULL, &rcdTimeout); + ICUNIT_GOTO_EQUAL(ret, MSGLEN, ret, NOK); + ICUNIT_GOTO_STRING_EQUAL(msgRcd, g_mqueueMsessage[2], msgRcd, NOK); // 2, g_mqueueMsessage buffer index. + + LOS_AtomicInc(&g_testCount); + +NOK: + return NULL; +} + +static VOID *PthreadF02(VOID *arg) +{ + INT32 ret; + CHAR msgRcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + struct timespec rcdTimeout = { 0 }; + rcdTimeout.tv_sec = 0xffff; + + LOS_AtomicInc(&g_testCount); + + ret = mq_timedreceive(g_messageQId, msgRcd, MQUEUE_STANDARD_NAME_LENGTH, NULL, &rcdTimeout); + ICUNIT_GOTO_EQUAL(ret, MSGLEN, ret, NOK); + ICUNIT_GOTO_STRING_EQUAL(msgRcd, g_mqueueMsessage[1], msgRcd, NOK); + + LOS_AtomicInc(&g_testCount); + +NOK: + return NULL; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + + pthread_t threadA; + pthread_attr_t attrA; + struct sched_param spA; + + pthread_t threadB; + pthread_attr_t attrB; + struct sched_param spB; + + struct mq_attr msgAttr = { 0 }; + CHAR qName[MQUEUE_STANDARD_NAME_LENGTH] = ""; + + msgAttr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + msgAttr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + g_testCount = 0; + + (void)snprintf_s(qName, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq170_%d", LosCurTaskIDGet()); + + g_messageQId = mq_open(qName, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &msgAttr); + ICUNIT_GOTO_NOT_EQUAL(g_messageQId, (mqd_t)-1, g_messageQId, EXIT1); + + ret = pthread_attr_init(&attrA); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + spA.sched_priority = MQUEUE_PTHREAD_PRIORITY_TEST2; + ret = pthread_attr_setschedparam(&attrA, &spA); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = pthread_create(&threadA, &attrA, PthreadF02, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = pthread_attr_init(&attrB); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT3); + + spB.sched_priority = 8; // 8, Queue pthread priority. + ret = pthread_attr_setschedparam(&attrB, &spB); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT3); + + ret = pthread_create(&threadB, &attrB, PthreadF01, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT3); + + ret = mq_send(g_messageQId, g_mqueueMsessage[1], MSGLEN, 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT3); + + ret = mq_send(g_messageQId, g_mqueueMsessage[2], MSGLEN, 0); // 2, g_mqueueMsessage buffer index. + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT3); + + TestExtraTaskDelay(2); // 2, Set delay time. + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT3); // 4, Here, assert the g_testCount. + + ret = pthread_join(threadB, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT3); + + ret = pthread_attr_destroy(&attrB); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT3); + + ret = pthread_join(threadA, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = pthread_attr_destroy(&attrA); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = mq_close(g_messageQId); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(qName); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + return MQUEUE_NO_ERROR; +EXIT3: + PosixPthreadDestroy(&attrB, threadB); +EXIT2: + PosixPthreadDestroy(&attrA, threadA); +EXIT1: + mq_close(g_messageQId); + mq_unlink(qName); + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue133(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_133", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_134.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_134.cpp new file mode 100644 index 00000000..27f5a041 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_134.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + UINTPTR temp; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + mqd_t mqueue; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq134_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, 0); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue134(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_134", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_136.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_136.cpp new file mode 100644 index 00000000..71df4fcd --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_136.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + INT32 index; + + mqd_t queueID[LOSCFG_BASE_IPC_QUEUE_CONFIG + 1]; + CHAR qName[LOSCFG_BASE_IPC_QUEUE_CONFIG + 1][MQUEUE_STANDARD_NAME_LENGTH]; + + const CHAR *msgPtr = MQUEUE_SEND_STRING_TEST; + CHAR msgRcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + + struct mq_attr msgAttr = { 0 }; + msgAttr.mq_msgsize = 20; // 20, mqueue message size. + msgAttr.mq_maxmsg = 20; // 20, mqueue message size. + + for (index = 0; index < (LOSCFG_BASE_IPC_QUEUE_CONFIG - QUEUE_EXISTED_NUM); index++) { + (void)snprintf_s(qName[index], MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq136_%d", index); + queueID[index] = mq_open(qName[index], O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &msgAttr); + ICUNIT_GOTO_NOT_EQUAL(queueID[index], (mqd_t)-1, queueID[index], EXIT); + } + +EXIT: + for (; index >= 1;) { + ret = mq_close(queueID[--index]); + ICUNIT_ASSERT_EQUAL(ret, 0, index); + + ret = mq_unlink(qName[index]); + ICUNIT_ASSERT_EQUAL(ret, MQUEUE_NO_ERROR, ret); + } + + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue136(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_136", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_143.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_143.cpp new file mode 100644 index 00000000..c4301752 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_143.cpp @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static VOID *PthreadF01(VOID *argument) +{ + INT32 ret; + struct timespec ts = { 0 }; + + TestBusyTaskDelay(3); // 3, Set the timeout of runtime + + LOS_AtomicInc(&g_testCount); + ret = mq_timedsend(g_gqueue, "1234567890123456789", 20, 0, &ts); // 20, mqueue max message size. + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return NULL; + +EXIT: + g_testCount = 0; + return NULL; +} + +static UINT32 Testcase(VOID) +{ + INT32 ret; + const INT32 size = 20; // 20, queue max message size. + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + pthread_t newTh; + struct mq_attr attr = { 0 }; + + attr.mq_msgsize = size; + attr.mq_maxmsg = size; + attr.mq_flags = O_NONBLOCK; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq143_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + g_gqueue = mq_open(mqname, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR, &attr); + ICUNIT_ASSERT_NOT_EQUAL(g_gqueue, (mqd_t)-1, g_gqueue); + + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_receive(g_gqueue, msgrcd, size, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EAGAIN, errno, EXIT1); + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT1); + + ret = mq_close(g_gqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + g_gqueue = mq_open(mqname, O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(g_gqueue, (mqd_t)-1, g_gqueue, EXIT1); + + ret = mq_receive(g_gqueue, msgrcd, size, NULL); + ICUNIT_GOTO_EQUAL(ret, size, ret, EXIT1); + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT1); + + ret = pthread_join(newTh, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_close(g_gqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + pthread_join(newTh, NULL); +EXIT: + mq_close(g_gqueue); + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue143(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_143", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_144.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_144.cpp new file mode 100644 index 00000000..ebed1beb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_144.cpp @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static VOID *PthreadF01(VOID *argument) +{ + INT32 i, ret; + const CHAR *msgptr[] = { "msg test 1", "msg test 2", "msg test 3" }; + struct mq_attr attr = { 0 }; + + g_testCount = 1; + + mq_getattr(g_gqueue, &attr); + for (i = 0; i < 3; i++) { // 3, the loop frequency. + LosTaskDelay(2); // 2, delay + ret = mq_send(g_gqueue, msgptr[i], attr.mq_msgsize, 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + } + + g_testCount = 2; // 2, Init test count value. + + return NULL; +EXIT: + g_testCount = 0; + return NULL; +} + +static VOID *PthreadF02(VOID *argument) +{ + INT32 i, ret; + UINT32 uret; + const CHAR *msgptr[] = { "msg test 1", "msg test 2", "msg test 3" }; + CHAR msgrcd[3][MQUEUE_STANDARD_NAME_LENGTH] = {0}; + struct mq_attr attr = { 0 }; + UINT32 msgPrio = 1; + + g_testCount = 3; // 3, Init test count value. + + mq_getattr(g_gqueue, &attr); + for (i = 0; i < 3; i++) { // 3, the loop frequency. + uret = LosTaskDelay(2); // 2, delay + ICUNIT_GOTO_EQUAL(uret, MQUEUE_NO_ERROR, uret, EXIT); + + ret = mq_receive(g_gqueue, msgrcd[i], attr.mq_msgsize, &msgPrio); + ICUNIT_GOTO_EQUAL(ret, attr.mq_msgsize, ret, EXIT); + ICUNIT_GOTO_NOT_EQUAL(ret, strlen(msgptr[i]), ret, EXIT); + ICUNIT_GOTO_STRING_EQUAL(msgrcd[i], msgptr[i], msgrcd[i], EXIT); + } + + g_testCount = 4; // 4, Init test count value. + + return NULL; +EXIT: + g_testCount = 0; + return NULL; +} + +static UINT32 Testcase(VOID) +{ + INT32 ret; + UINT32 uret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + struct mq_attr mqstat, attr; + pthread_attr_t attr1; + pthread_t newTh, newTh2; + + ret = memset_s(&mqstat, sizeof(mqstat), 0, sizeof(mqstat)); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + mqstat.mq_maxmsg = MQUEUE_SHORT_ARRAY_LENGTH; + mqstat.mq_msgsize = MQUEUE_SHORT_ARRAY_LENGTH * 2; // 2, mqueue message size. + mqstat.mq_flags = 0; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq144_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT3); + + g_gqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO, &mqstat); + ICUNIT_GOTO_NOT_EQUAL(g_gqueue, (mqd_t)-1, g_gqueue, EXIT); + + g_testCount = 0; + + ret = PosixPthreadInit(&attr1, MQUEUE_PTHREAD_PRIORITY_TEST1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = pthread_create(&newTh, &attr1, PthreadF01, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + LosTaskDelay(1); + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT1); + + ret = PosixPthreadInit(&attr1, MQUEUE_PTHREAD_PRIORITY_TEST2); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = pthread_create(&newTh2, &attr1, PthreadF02, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + uret = LosTaskDelay(12); // 12, Set delay time. + ICUNIT_GOTO_EQUAL(uret, MQUEUE_NO_ERROR, uret, EXIT2); + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT2); // 4, Here, assert the g_testCount. + + ret = PosixPthreadDestroy(&attr1, newTh2); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = PosixPthreadDestroy(&attr1, newTh); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_close(g_gqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT2: + PosixPthreadDestroy(&attr1, newTh2); +EXIT1: + PosixPthreadDestroy(&attr1, newTh); +EXIT: + mq_close(g_gqueue); + mq_unlink(mqname); +EXIT3: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue144(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("ItPosixQueue144", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_145.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_145.cpp new file mode 100644 index 00000000..704fd347 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_145.cpp @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static VOID *PthreadF01(VOID *mq) +{ + INT32 i, ret; + mqd_t mqueue1 = *(mqd_t *)mq; + const CHAR *msgptr[] = { "msg test 1", "msg test 2", "msg test 3" }; + + for (i = 0; i < 3; i++) { // 3, the loop frequency. + ret = mq_send(mqueue1, msgptr[i], MQUEUE_STANDARD_NAME_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + } + + LOS_AtomicInc(&g_testCount); + + pthread_exit(nullptr); + + return NULL; +EXIT: + pthread_exit(nullptr); + g_testCount = 0; + return NULL; +} + +static VOID *PthreadF02(VOID *mq) +{ + INT32 i, ret; + mqd_t mqueue2 = *(mqd_t *)mq; + const CHAR *msgptr[] = { "msg test 1", "msg test 2", "msg test 3" }; + + for (i = 0; i < 3; i++) { // 3, the loop frequency. + ret = mq_send(mqueue2, msgptr[i], MQUEUE_STANDARD_NAME_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + } + LOS_AtomicInc(&g_testCount); + + pthread_exit(nullptr); + + return NULL; +EXIT: + pthread_exit(nullptr); + g_testCount = 0; + return NULL; +} + +static VOID *PthreadF03(VOID *mq) +{ + INT32 i, ret; + mqd_t mqueue1 = *(mqd_t *)mq; + CHAR msgrcd[3][MQUEUE_STANDARD_NAME_LENGTH] = {{0, 0}}; + + for (i = 0; i < 3; i++) { // 3, the loop frequency. + ret = mq_receive(mqueue1, msgrcd[i], MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_STANDARD_NAME_LENGTH, ret, EXIT); + } + LOS_AtomicInc(&g_testCount); + + pthread_exit(nullptr); + + return NULL; +EXIT: + pthread_exit(nullptr); + g_testCount = 0; + return NULL; +} + +static VOID *PthreadF04(VOID *mq) +{ + INT32 i, ret; + mqd_t mqueue2 = *(mqd_t *)mq; + CHAR msgrcd[3][MQUEUE_STANDARD_NAME_LENGTH]; + + for (i = 0; i < 3; i++) { // 3, the loop frequency. + ret = mq_receive(mqueue2, msgrcd[i], MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_STANDARD_NAME_LENGTH, ret, EXIT); + } + + LOS_AtomicInc(&g_testCount); + + pthread_exit(nullptr); + + return NULL; +EXIT: + pthread_exit(nullptr); + g_testCount = 0; + return NULL; +} + +static UINT32 Testcase(VOID) +{ + INT32 ret, oflag; + CHAR mqname1[MQUEUE_STANDARD_NAME_LENGTH] = ""; + CHAR mqname2[MQUEUE_STANDARD_NAME_LENGTH] = ""; + mqd_t mqueue1 = 0, mqueue2 = 0; + struct mq_attr mqstat; + pthread_t pthreadSend1, pthreadSend2, pthreadRecev1, pthreadRecev2; + + (void)snprintf_s(mqname1, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mqueue145_1_%d", LosCurTaskIDGet()); + (void)snprintf_s(mqname2, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mqueue145_2_%d", LosCurTaskIDGet()); + + g_testCount = 0; + + (void)memset_s(&mqstat, sizeof(mqstat), 0, sizeof(mqstat)); + mqstat.mq_maxmsg = MQUEUE_SHORT_ARRAY_LENGTH; + mqstat.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + mqstat.mq_flags = 0; + + oflag = O_CREAT | O_NONBLOCK | O_RDWR; + + mqueue1 = mq_open(mqname1, oflag, S_IRWXU | S_IRWXG | S_IRWXO, &mqstat); + ICUNIT_GOTO_NOT_EQUAL(mqueue1, (mqd_t)-1, mqueue1, EXIT); + + mqueue2 = mq_open(mqname2, oflag, S_IRWXU | S_IRWXG | S_IRWXO, &mqstat); + ICUNIT_GOTO_NOT_EQUAL(mqueue2, (mqd_t)-1, mqueue2, EXIT1); + + ret = pthread_create(&pthreadSend1, NULL, PthreadF01, (void *)&mqueue1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = pthread_create(&pthreadSend2, NULL, PthreadF02, (void *)&mqueue2); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT3); + + ret = pthread_create(&pthreadRecev1, NULL, PthreadF03, (void *)&mqueue1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT4); + + ret = pthread_create(&pthreadRecev2, NULL, PthreadF04, (void *)&mqueue2); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT5); + + ret = pthread_join(pthreadSend1, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT5); + + ret = pthread_join(pthreadSend2, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT5); + + ret = pthread_join(pthreadRecev1, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT5); + + ret = pthread_join(pthreadRecev2, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT5); + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT1); // 4, Here, assert the g_testCount. + + ret = mq_close(mqueue2); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname2); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_close(mqueue1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(mqname1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT5: + pthread_join(pthreadRecev2, NULL); +EXIT4: + pthread_join(pthreadRecev1, NULL); +EXIT3: + pthread_join(pthreadSend2, NULL); +EXIT2: + pthread_join(pthreadSend1, NULL); +EXIT1: + mq_close(mqueue2); + mq_unlink(mqname2); +EXIT: + mq_close(mqueue1); + mq_unlink(mqname1); + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue145(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_145", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_146.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_146.cpp new file mode 100644 index 00000000..e075f335 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_146.cpp @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +typedef struct { + INT32 pthread_ID; + mqd_t mqueue_ID; +} mq_info; + +static VOID *PthreadF01(VOID *info) +{ + INT32 i, ret; + const CHAR *msgptr[] = { "msg test 1", "msg test 2", "msg test 3" }; + mq_info sendInfo; + + sendInfo.pthread_ID = ((mq_info *)info)->pthread_ID; + sendInfo.mqueue_ID = ((mq_info *)info)->mqueue_ID; + for (i = 0; i < 3; i++) { // 3, the loop frequency. + ret = mq_send(sendInfo.mqueue_ID, msgptr[i], MQUEUE_STANDARD_NAME_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + } + + LOS_AtomicInc(&g_testCount); + + pthread_exit(nullptr); + + return NULL; +EXIT: + pthread_exit(nullptr); + g_testCount = 0; + return NULL; +} + +static VOID *PthreadF02(VOID *info) +{ + INT32 i, ret; + CHAR msgrcd[3][MQUEUE_STANDARD_NAME_LENGTH * 2]; + mq_info recvInfo; + + recvInfo.pthread_ID = ((mq_info *)info)->pthread_ID; + recvInfo.mqueue_ID = ((mq_info *)info)->mqueue_ID; + for (i = 0; i < 3; i++) { // 3, the loop frequency. + ret = mq_receive(recvInfo.mqueue_ID, msgrcd[i], MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_STANDARD_NAME_LENGTH, ret, EXIT); + } + + LOS_AtomicInc(&g_testCount); + + pthread_exit(nullptr); + + return NULL; +EXIT: + pthread_exit(nullptr); + g_testCount = 0; + return NULL; +} + +static UINT32 Testcase(VOID) +{ + INT32 i, ret, oflag; + UINT32 uret; + const CHAR *mqname[MQUEUE_PTHREAD_NUM_TEST] = {"/msg1", "/msg2", "/msg3", "/msg4", "/msg5"}; + mqd_t mqueue[MQUEUE_PTHREAD_NUM_TEST]; + struct mq_attr mqstat; + pthread_t pthreadSend[MQUEUE_PTHREAD_NUM_TEST]; + pthread_t pthreadRecev[MQUEUE_PTHREAD_NUM_TEST]; + mq_info info[MQUEUE_PTHREAD_NUM_TEST]; + + g_testCount = 0; + + oflag = O_CREAT | O_NONBLOCK | O_RDWR; + + ret = memset_s(&mqstat, sizeof(mqstat), 0, sizeof(mqstat)); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + mqstat.mq_maxmsg = MQUEUE_SHORT_ARRAY_LENGTH; + mqstat.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + mqstat.mq_flags = 0; + + for (i = 0; i < MQUEUE_PTHREAD_NUM_TEST; i++) { + mqueue[i] = mq_open(mqname[i], oflag, S_IRWXU | S_IRWXG | S_IRWXO, &mqstat); + ICUNIT_GOTO_NOT_EQUAL(mqueue[i], (mqd_t)-1, mqueue[i], EXIT); + } + for (i = 0; i < MQUEUE_PTHREAD_NUM_TEST; i++) { + info[i].pthread_ID = i; + info[i].mqueue_ID = mqueue[i]; + ret = pthread_create(&pthreadSend[i], NULL, PthreadF01, (void *)&info[i]); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = pthread_create(&pthreadRecev[i], NULL, PthreadF02, (void *)&info[i]); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + } + + uret = sleep(5); // 5, seconds. + ICUNIT_GOTO_EQUAL(uret, 0, uret, EXIT1); + + ICUNIT_GOTO_EQUAL(g_testCount, MQUEUE_PTHREAD_NUM_TEST * 2, g_testCount, EXIT1); // 2, assert the g_testCount. + + for (i = 0; i < MQUEUE_PTHREAD_NUM_TEST; i++) { + ret = pthread_join(pthreadSend[i], NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = pthread_join(pthreadRecev[i], NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + } + + for (i = 0; i < MQUEUE_PTHREAD_NUM_TEST; i++) { + ret = mq_close(mqueue[i]); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(mqname[i]); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + } + + return MQUEUE_NO_ERROR; +EXIT1: + for (i = 0; i < MQUEUE_PTHREAD_NUM_TEST; i++) { + pthread_join(pthreadSend[i], NULL); + pthread_join(pthreadRecev[i], NULL); + } +EXIT: + for (i = 0; i < MQUEUE_PTHREAD_NUM_TEST; i++) { + mq_close(mqueue[i]); + mq_unlink(mqname[i]); + } + + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue146(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_146", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_147.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_147.cpp new file mode 100644 index 00000000..1955c0ee --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_147.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + const CHAR *msgptr = "A"; + mqd_t mqueue = 0; + struct mq_attr attr = { 0 }; + + attr.mq_msgsize = 1; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq147_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + ret = mq_send(mqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_receive(mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, strlen(msgptr), ret, EXIT1); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, msgptr, msgrcd, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue147(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_147", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_148.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_148.cpp new file mode 100644 index 00000000..afe8bbc2 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_148.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + + CHAR qName[MQUEUE_STANDARD_NAME_LENGTH] = ""; + const CHAR *msgPtr = MQUEUE_SEND_STRING_TEST; + struct mq_attr msgAttr = { 0 }; + CHAR msgRcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + + msgAttr.mq_msgsize = 0xFFF0; + msgAttr.mq_maxmsg = 0xFFF0; + + ret = snprintf_s(qName, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq148_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + + g_messageQId = mq_open(qName, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &msgAttr); + ICUNIT_GOTO_EQUAL(g_messageQId, (mqd_t)-1, g_messageQId, EXIT); + + ret = mq_send(g_messageQId, msgPtr, strlen(msgPtr), 0); + ICUNIT_GOTO_EQUAL(ret, (UINT32)-1, ret, EXIT); + + ret = mq_receive(g_messageQId, msgRcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, (UINT32)-1, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT: + mq_close(g_messageQId); + mq_unlink(qName); +EXIT1: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue148(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_148", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_149.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_149.cpp new file mode 100644 index 00000000..82a01595 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_149.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + mqd_t mqueue; + struct mq_attr attr = { 0 }; + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq149_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + mqueue = mq_open(mqname, O_CREAT | O_RDWR | O_NONBLOCK, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + ret = mq_send(mqueue, NULL, 0, 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT); + + ret = mq_receive(mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EAGAIN, errno, EXIT); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue149(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_149", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_150.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_150.cpp new file mode 100644 index 00000000..130ed558 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_150.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + mqd_t mqueue; + struct mq_attr attr = { 0 }; + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq150_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + mqueue = mq_open(mqname, O_CREAT | O_RDWR | O_NONBLOCK, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + ret = mq_send((mqd_t)(-1), msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EBADF, errno, EXIT1); + + ret = mq_receive(mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EAGAIN, errno, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue150(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_150", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_151.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_151.cpp new file mode 100644 index 00000000..d3ccfeee --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_151.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + mqd_t mqueue; + struct mq_attr attr = { 0 }; + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq151_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + mqueue = mq_open(mqname, O_CREAT | O_RDWR | O_NONBLOCK, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + ret = mq_receive(mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EAGAIN, errno, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue151(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_151", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_152.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_152.cpp new file mode 100644 index 00000000..773bc1ee --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_152.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + struct mq_attr attr = { 0 }; + mqd_t mqueue; + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq152_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT); + + ret = mq_send(mqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_receive(mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT1); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, MQUEUE_SEND_STRING_TEST, msgrcd, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue152(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_152", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_153.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_153.cpp new file mode 100644 index 00000000..1e0e72bb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_153.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + struct mq_attr attr = { 0 }; + mqd_t mqueue; + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq153_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + ret = mq_send(mqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_receive(mqueue, msgrcd, (MQUEUE_STANDARD_NAME_LENGTH - 1), NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EMSGSIZE, errno, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue153(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_153", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_154.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_154.cpp new file mode 100644 index 00000000..628595e1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_154.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH * 2] = {0}; + struct mq_attr attr = { 0 }; + mqd_t mqueue; + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq154_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + ret = mq_send(mqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_receive(mqueue, msgrcd, (MQUEUE_STANDARD_NAME_LENGTH + 1), NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT1); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, MQUEUE_SEND_STRING_TEST, msgrcd, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue154(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_154", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_155.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_155.cpp new file mode 100644 index 00000000..53be9f33 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_155.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + struct mq_attr attr = { 0 }; + mqd_t mqueue; + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq155_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + ret = mq_send(mqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_receive(mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, MQUEUE_SEND_STRING_TEST, msgrcd, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + errno = 0; + ret = mq_receive(mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT); + ICUNIT_GOTO_EQUAL(errno, EBADF, errno, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue155(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_155", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_156.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_156.cpp new file mode 100644 index 00000000..26dac7bf --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_156.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + + mqd_t msgQIdA; // Define queue ID for queue A + mqd_t msgQIdB; // Define queue ID for queue B + + CHAR qNameA[MQUEUE_STANDARD_NAME_LENGTH] = "/mq156_A"; + CHAR qNameB[MQUEUE_STANDARD_NAME_LENGTH] = "/mq156_B"; + + const CHAR *msgPtr = MQUEUE_SEND_STRING_TEST; + CHAR msgRcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + + struct mq_attr msgAttr = { 0 }; + msgAttr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + msgAttr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + msgQIdA = mq_open(qNameA, O_CREAT | O_RDWR | O_NONBLOCK, S_IRUSR | S_IWUSR, &msgAttr); + ICUNIT_ASSERT_NOT_EQUAL(msgQIdA, (mqd_t)-1, msgQIdA); + + ret = mq_receive(msgQIdA, msgRcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, (UINT32)-1, ret, EXIT); + + msgQIdB = mq_open(qNameB, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &msgAttr); + ICUNIT_ASSERT_NOT_EQUAL(msgQIdB, (mqd_t)-1, msgQIdB); + + ret = mq_send(msgQIdB, msgPtr, strlen(msgPtr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_receive(msgQIdB, msgRcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MSGLEN, ret, EXIT1); + ICUNIT_GOTO_STRING_EQUAL(msgRcd, MQUEUE_SEND_STRING_TEST, msgRcd, EXIT1); + + ret = mq_close(msgQIdB); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(qNameB); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_close(msgQIdA); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(qNameA); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; + +EXIT1: + mq_close(msgQIdB); + mq_unlink(qNameB); +EXIT: + mq_close(msgQIdA); + mq_unlink(qNameA); + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue156(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_156", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_157.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_157.cpp new file mode 100644 index 00000000..672603e6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_157.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret, i; + INT32 count = MQUEUE_MAX_NUM_TEST; + CHAR mqname[LOSCFG_BASE_IPC_QUEUE_CONFIG + 2][MQUEUE_STANDARD_NAME_LENGTH]; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + mqd_t mqueue[LOSCFG_BASE_IPC_QUEUE_CONFIG + 2]; + + struct mq_attr attr = { 0 }; + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_SHORT_ARRAY_LENGTH; + + for (i = 0; i < count; i++) { + (void)snprintf_s(mqname[i], MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "mq157_%d_%d", LosCurTaskIDGet(), i); + + mqueue[i] = mq_open(mqname[i], O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue[i], (mqd_t)-1, mqueue[i], EXIT); + } + +#ifndef LOSCFG_DEBUG_QUEUE + (void)snprintf_s(mqname[i], MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "mq157_%d_%d", LosCurTaskIDGet(), i); + mqueue[i] = mq_open(mqname[i], O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_EQUAL(mqueue[i], (mqd_t)-1, mqueue[i], EXIT); +#endif + + ret = mq_send(mqueue[(count - 1)], msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_receive(mqueue[(count - 1)], msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, MQUEUE_SEND_STRING_TEST, msgrcd, EXIT); + + for (i = 0; i < count; i++) { + ret = mq_close(mqueue[i]); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(mqname[i]); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + } + + return MQUEUE_NO_ERROR; +EXIT: + for (i = 0; i < count; i++) { + mq_close(mqueue[i]); + mq_unlink(mqname[i]); + } + return MQUEUE_NO_ERROR; +} + + +VOID ItPosixQueue157(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_157", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_159.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_159.cpp new file mode 100644 index 00000000..ddb5c292 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_159.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret, i; + INT32 count = MQUEUE_MAX_NUM_TEST; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + CHAR mqname[LOSCFG_BASE_IPC_QUEUE_CONFIG + 1][MQUEUE_STANDARD_NAME_LENGTH]; + mqd_t mqueue[LOSCFG_BASE_IPC_QUEUE_CONFIG + 1]; + struct mq_attr attr = { 0 }; + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = 20; + + for (i = 0; i < count; i++) { + (void)snprintf_s(mqname[i], MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "mq158_%d_%d", LosCurTaskIDGet(), i); + + mqueue[i] = mq_open(mqname[i], O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue[i], (mqd_t)-1, mqueue[i], EXIT); + } + +#ifndef LOSCFG_DEBUG_QUEUE + (void)snprintf_s(mqname[i], MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq158_%d", i); + mqueue[i] = mq_open(mqname[i], O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_EQUAL(mqueue[i], (mqd_t)(-1), mqueue[i], EXIT); +#else + mqueue[i] = (mqd_t)(-1); +#endif + + ret = mq_send(mqueue[i], msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT); + ICUNIT_GOTO_EQUAL(errno, EBADF, errno, EXIT); + + ret = mq_receive(mqueue[i], msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT); + ICUNIT_GOTO_EQUAL(errno, EBADF, errno, EXIT); + + for (i = 0; i < count; i++) { + ret = mq_close(mqueue[i]); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(mqname[i]); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + } + + return MQUEUE_NO_ERROR; + +EXIT: + for (i = 0; i < count; i++) { + mq_close(mqueue[i]); + mq_unlink(mqname[i]); + } + return MQUEUE_NO_ERROR; +} + + + +VOID ItPosixQueue159(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_159", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_160.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_160.cpp new file mode 100644 index 00000000..74418345 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_160.cpp @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static VOID *PthreadF01(VOID *arg) +{ + INT32 i, ret; + INT32 count = MQUEUE_MAX_NUM_TEST; + struct mq_attr attr = { 0 }; + + g_testCount = 0; + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = 5; // 5, queue max message size. + + for (i = 0; i < count; i++, g_testCount++) { + (void)snprintf_s(g_mqueueName[i], MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq160_%d_%d", LosCurTaskIDGet(), i); + g_mqueueId[i] = mq_open(g_mqueueName[i], O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(g_mqueueId[i], (mqd_t)-1, g_mqueueId[i], EXIT); + } + +#ifndef LOSCFG_DEBUG_QUEUE + (void)snprintf_s(g_mqueueName[i], MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq160_%d_%d", LosCurTaskIDGet(), i); + g_mqueueId[i] = mq_open(g_mqueueName[i], O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_EQUAL(g_mqueueId[i], (mqd_t)-1, g_mqueueId[i], EXIT); +#endif + + return NULL; +EXIT: + for (i = 0; i < g_testCount; i++) { + mq_close(g_mqueueId[i]); + mq_unlink(g_mqueueName[i]); + } + return NULL; +} + +static VOID *PthreadF02(VOID *arg) +{ + INT32 ret; + UINT32 i; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + struct timespec ts = { 0 }; + + ts.tv_sec = 0xffff; + + for (i = 0; i < g_testCount; i++) { + ret = mq_timedsend(g_mqueueId[i % g_testCount], msgptr, strlen(msgptr), 0, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_timedreceive(g_mqueueId[i % g_testCount], msgrcd, MQUEUE_STANDARD_NAME_LENGTH, 0, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, MQUEUE_SEND_STRING_TEST, msgrcd, EXIT); + } + return NULL; +EXIT: + for (i = 0; i < g_testCount; i++) { + mq_close(g_mqueueId[i]); + mq_unlink(g_mqueueName[i]); + } + return NULL; +} + +static VOID *PthreadF03(VOID *arg) +{ + INT32 ret, i; + + for (i = 0; i < g_testCount; i++) { + ret = mq_close(g_mqueueId[i]); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(g_mqueueName[i]); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + } + + return NULL; +EXIT: + for (i = 0; i < g_testCount; i++) { + mq_close(g_mqueueId[i]); + mq_unlink(g_mqueueName[i]); + } + return NULL; +} + + +static UINT32 Testcase(VOID) +{ + INT32 ret, i; + pthread_t pthread1, pthread2, pthread3; + pthread_attr_t attr1; + struct sched_param schedparam; + + g_testCount = 0; + + ret = pthread_attr_init(&attr1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + schedparam.sched_priority = MQUEUE_PTHREAD_PRIORITY_TEST2; + ret = pthread_attr_setschedparam(&attr1, &schedparam); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = pthread_attr_init(&attr1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + for (i = 0; i < MQUEUE_STANDARD_NAME_LENGTH; i++) { + ret = pthread_create(&pthread1, &attr1, PthreadF01, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = pthread_join(pthread1, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = pthread_create(&pthread2, &attr1, PthreadF02, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = pthread_join(pthread2, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = pthread_create(&pthread3, &attr1, PthreadF03, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT3); + + ret = pthread_join(pthread3, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT3); + } + + ret = pthread_attr_destroy(&attr1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT3: + pthread_join(pthread3, NULL); +EXIT2: + pthread_join(pthread2, NULL); +EXIT1: + pthread_join(pthread1, NULL); +EXIT: + pthread_attr_destroy(&attr1); + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue160(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_160", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_161.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_161.cpp new file mode 100644 index 00000000..abaa5b9f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_161.cpp @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 g_index = 0; + +static VOID *PthreadF01(VOID *arg) +{ + INT32 i, ret; + UINT32 uret = 0; + INT32 count = (INT32)arg; + struct mq_attr attr = { 0 }; + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = 5; // 5, queue max message size. + + uret = g_index % count; + + (void)snprintf_s(g_mqueueName[uret], MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mqueue_161_%d_%d", LosCurTaskIDGet(), (uret)); + g_mqueueId[uret] = mq_open(g_mqueueName[uret], O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(g_mqueueId[uret], (mqd_t)-1, g_mqueueId[uret], EXIT); + + return NULL; + +EXIT: + for (i = 0; i < count; i++) { + mq_close(g_mqueueId[i]); + mq_unlink(g_mqueueName[i]); + } + return NULL; +} + +static VOID *PthreadF02(VOID *arg) +{ + INT32 ret; + INT32 queueCount = MQUEUE_MAX_NUM_TEST; + UINT32 i, j, count; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + struct timespec ts = { 0 }; + + ts.tv_sec = 0xffff; + + for (i = 0; i < 10; i++) { // 10, The loop frequency. + count = g_index % queueCount; + + for (j = 0; j <= count; j++) { + ret = mq_timedsend(g_mqueueId[j], msgptr, strlen(msgptr), 0, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_timedreceive(g_mqueueId[j], msgrcd, MQUEUE_STANDARD_NAME_LENGTH, 0, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, MQUEUE_SEND_STRING_TEST, msgrcd, EXIT); + } + } + return NULL; +EXIT: + for (i = 0; i < queueCount; i++) { + mq_close(g_mqueueId[i]); + mq_unlink(g_mqueueName[i]); + } + return NULL; +} + +static VOID *PthreadF03(VOID *arg) +{ + INT32 ret, i; + INT32 count = (INT32)arg; + + for (i = 0; i < count; i++) { + ret = mq_close(g_mqueueId[i]); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(g_mqueueName[i]); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + } + + return NULL; +EXIT: + for (i = 0; i < count; i++) { + mq_close(g_mqueueId[i]); + mq_unlink(g_mqueueName[i]); + } + return NULL; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + INT32 count = MQUEUE_MAX_NUM_TEST; + pthread_t threadA; + pthread_attr_t attrA; + pthread_t threadB; + pthread_attr_t attrB; + pthread_t threadC; + pthread_attr_t attrC; + struct sched_param sp; + + ret = pthread_attr_init(&attrA); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + sp.sched_priority = MQUEUE_PTHREAD_PRIORITY_TEST2; + ret = pthread_attr_setschedparam(&attrA, &sp); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = pthread_attr_init(&attrB); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + sp.sched_priority = MQUEUE_PTHREAD_PRIORITY_TEST2; + ret = pthread_attr_setschedparam(&attrB, &sp); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = pthread_attr_init(&attrC); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + sp.sched_priority = MQUEUE_PTHREAD_PRIORITY_TEST2; + ret = pthread_attr_setschedparam(&attrC, &sp); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + for (g_index = 0; g_index < count; g_index++) { + ret = pthread_create(&threadA, &attrA, PthreadF01, (void *)count); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = pthread_join(threadA, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = pthread_create(&threadB, &attrB, PthreadF02, (void *)count); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = pthread_join(threadB, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + if (g_index % count == (count - 1)) { + ret = pthread_create(&threadC, &attrC, PthreadF03, (void *)count); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = pthread_join(threadC, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + } + } + + ret = pthread_attr_destroy(&attrC); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = pthread_attr_destroy(&attrB); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = pthread_attr_destroy(&attrA); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; + +EXIT2: + pthread_attr_destroy(&attrC); +EXIT1: + pthread_attr_destroy(&attrB); +EXIT: + pthread_attr_destroy(&attrA); + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue161(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_161", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_162.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_162.cpp new file mode 100644 index 00000000..74a5128d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_162.cpp @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static VOID *PthreadF01(VOID *arg) +{ + INT32 i, ret; + const CHAR *msgptr[] = { "send_111 1", "send_111 2", "send_111 3", "send_111 4", "send_111 5" }; + + for (i = 0; i < MQUEUE_PTHREAD_NUM_TEST; i++) { + ret = mq_send(g_gqueue, msgptr[i], strlen(msgptr[i]), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + } + LOS_AtomicInc(&g_testCount); + + pthread_exit(nullptr); + + return NULL; +EXIT: + pthread_exit(nullptr); + g_testCount = 0; + return NULL; +} + +static VOID *PthreadF02(VOID *arg) +{ + INT32 i, ret; + INT32 pthreadCount = *(INT32 *)arg; + CHAR msgrcd[MQUEUE_PTHREAD_NUM_TEST][MQUEUE_PTHREAD_NUM_TEST][MQUEUE_STANDARD_NAME_LENGTH]; + + for (i = 0; i < MQUEUE_PTHREAD_NUM_TEST; i++) { + ret = mq_receive(g_gqueue, msgrcd[pthreadCount][i], MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT); + } + + LOS_AtomicInc(&g_testCount); + + pthread_exit(nullptr); + + return NULL; +EXIT: + g_testCount = 0; + pthread_exit(nullptr); + return NULL; +} + +static UINT32 Testcase(VOID) +{ + INT32 oflag, i, ret = 0; + INT32 pthreadCount[MQUEUE_PTHREAD_NUM_TEST]; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + pthread_t pthreadSend[MQUEUE_PTHREAD_NUM_TEST]; + pthread_t pthreadRecev[MQUEUE_PTHREAD_NUM_TEST]; + pthread_attr_t attr1; + struct mq_attr mqstat; + + ret = pthread_attr_init(&attr1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + g_testCount = 0; + + (void)snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, + "/mq162_%d", LosCurTaskIDGet()); + (void)memset_s(&mqstat, sizeof(mqstat), 0, sizeof(mqstat)); + mqstat.mq_maxmsg = MQUEUE_PTHREAD_NUM_TEST; + mqstat.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + mqstat.mq_flags = 0; + + oflag = O_CREAT | O_NONBLOCK | O_RDWR; + g_gqueue = mq_open(mqname, oflag, S_IRWXU | S_IRWXG | S_IRWXO, &mqstat); + ICUNIT_GOTO_NOT_EQUAL(g_gqueue, (mqd_t)-1, g_gqueue, EXIT1); + for (i = 0; i < MQUEUE_PTHREAD_NUM_TEST; i++) { + pthreadCount[i] = i; + ret = pthread_create(&pthreadSend[i], &attr1, PthreadF01, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = pthread_create(&pthreadRecev[i], &attr1, PthreadF02, (void *)&pthreadCount[i]); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + } + + for (i = 0; i < MQUEUE_PTHREAD_NUM_TEST; i++) { + ret = pthread_join(pthreadSend[i], NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = pthread_join(pthreadRecev[i], NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + } + ICUNIT_GOTO_EQUAL(g_testCount, MQUEUE_PTHREAD_NUM_TEST * 2, g_testCount, EXIT1); // 2, assert the g_testCount. + + ret = mq_close(g_gqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = pthread_attr_destroy(&attr1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT2: + for (i = 0; i < MQUEUE_PTHREAD_NUM_TEST; i++) { + pthread_join(pthreadSend[i], NULL); + pthread_join(pthreadRecev[i], NULL); + } +EXIT1: + mq_close(g_gqueue); + mq_unlink(mqname); +EXIT: + pthread_attr_destroy(&attr1); + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue162(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_162", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_163.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_163.cpp new file mode 100644 index 00000000..0a28b4a9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_163.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret, i; + INT32 count = MQUEUE_MAX_NUM_TEST; + CHAR mqname[LOSCFG_BASE_IPC_QUEUE_CONFIG + 1][MQUEUE_STANDARD_NAME_LENGTH]; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + mqd_t mqueue[LOSCFG_BASE_IPC_QUEUE_CONFIG + 1]; + struct mq_attr attr = { 0 }; + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + for (i = 0; i < (count); i++) { + (void)snprintf_s(mqname[i], MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq163_%d_%d", LosCurTaskIDGet(), i); + mqueue[i] = mq_open(mqname[i], O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue[i], (mqd_t)-1, mqueue[i], EXIT); + } + +#ifndef LOSCFG_DEBUG_QUEUE + (void)snprintf_s(mqname[i], MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq163_%d_%d", LosCurTaskIDGet(), i); + mqueue[i] = mq_open(mqname[i], O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_EQUAL(mqueue[i], (mqd_t)-1, mqueue[i], EXIT1); + ICUNIT_GOTO_EQUAL(errno, ENFILE, errno, EXIT1); +#endif + + for (i = 0; i < (count); i++) { + ret = mq_send(mqueue[i], msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + } + + for (i = 0; i < (count); i++) { + ret = mq_close(mqueue[i]); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(mqname[i]); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + } + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue[i]); + mq_unlink(mqname[i]); +EXIT: + for (i = 0; i < (count); i++) { + mq_close(mqueue[i]); + mq_unlink(mqname[i]); + } + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue163(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_163", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_164.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_164.cpp new file mode 100644 index 00000000..dd04ab0d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_164.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret, i; + + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + struct mq_attr attr = { 0 }; + mqd_t mqueue; + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = 3; // 3, queue max message size. + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq164_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + ret = mq_send(mqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_receive(mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT1); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, MQUEUE_SEND_STRING_TEST, msgrcd, EXIT1); + + for (i = 0; i < 3; i++) { // 3, the loop frequency. + ret = mq_send(mqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + } + + ret = mq_receive(mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT1); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, MQUEUE_SEND_STRING_TEST, msgrcd, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue164(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_164", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_165.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_165.cpp new file mode 100644 index 00000000..3897ffed --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_165.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret, i; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + mqd_t mqueue; + struct mq_attr attr = { 0 }; + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = 3; // 3, queue max message size. + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, + "/mq165_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + mqueue = mq_open(mqname, O_CREAT | O_RDWR | O_NONBLOCK, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + for (i = 0; i < 3; i++) { // 3, the loop frequency. + ret = mq_send(mqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + } + + ret = mq_send(mqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EAGAIN, errno, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue165(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_165", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_166.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_166.cpp new file mode 100644 index 00000000..52c8c22b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_166.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + + mqd_t msgQId; + struct mq_attr msgAttr = { 0 }; + CHAR qName[MQUEUE_STANDARD_NAME_LENGTH] = ""; + + CHAR *msgPtr1 = "1234567890"; + CHAR *msgPtr2 = "2345678901"; + CHAR *msgPtr3 = "3456789012"; + CHAR msgRcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + + msgAttr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + msgAttr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + ret = snprintf_s(qName, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq166_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + + msgQId = mq_open(qName, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &msgAttr); + ICUNIT_GOTO_NOT_EQUAL(msgQId, (mqd_t)-1, msgQId, EXIT); + + ret = mq_send(msgQId, msgPtr1, strlen(msgPtr1), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_send(msgQId, msgPtr2, strlen(msgPtr2), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_send(msgQId, msgPtr3, strlen(msgPtr3), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_receive(msgQId, msgRcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MSGLEN, ret, EXIT); + ICUNIT_GOTO_STRING_EQUAL(msgRcd, msgPtr1, msgRcd, EXIT); + + ret = mq_receive(msgQId, msgRcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MSGLEN, ret, EXIT); + ICUNIT_GOTO_STRING_EQUAL(msgRcd, msgPtr2, msgRcd, EXIT); + + ret = mq_receive(msgQId, msgRcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MSGLEN, ret, EXIT); + ICUNIT_GOTO_STRING_EQUAL(msgRcd, msgPtr3, msgRcd, EXIT); + + ret = mq_close(msgQId); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(qName); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT: + mq_close(msgQId); + mq_unlink(qName); +EXIT1: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue166(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_166", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_168.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_168.cpp new file mode 100644 index 00000000..8c6dfc19 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_168.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" +#define FNONBLOCK O_NONBLOCK + +static UINT32 Testcase(VOID) +{ + UINT32 pri; + INT32 ret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + mqd_t mqueue; + struct mq_attr attr = { 0 }; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq168_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_SHORT_ARRAY_LENGTH; + + mqueue = mq_open(mqname, FNONBLOCK | O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_ASSERT_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue); + + ret = mq_send(mqueue, msgptr, strlen(msgptr), MQUEUE_PRIORITY_TEST + 6); // 6, Mqueue priority. + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT1); + + ret = mq_send(mqueue, msgptr, strlen(msgptr), MQUEUE_PRIORITY_TEST + 10); // 10, Mqueue priority. + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT1); + + ret = mq_send(mqueue, msgptr, strlen(msgptr), MQUEUE_PRIORITY_TEST + 2); // 2, Mqueue priority. + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT1); + + ret = mq_send(mqueue, msgptr, strlen(msgptr), MQUEUE_PRIORITY_TEST + 8); // 8, Mqueue priority. + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT1); + + ret = mq_send(mqueue, msgptr, strlen(msgptr), MQUEUE_PRIORITY_TEST + 1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT1); + + ret = mq_receive(mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EAGAIN, errno, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue168(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_168", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_169.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_169.cpp new file mode 100644 index 00000000..3ca47efb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_169.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + UINT32 pri; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + mqd_t mqueue; + struct mq_attr attr = { 0 }; + struct timespec ts; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq169_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_SHORT_ARRAY_LENGTH; + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_ASSERT_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue); + + ret = mq_send(mqueue, msgptr, strlen(msgptr), MQUEUE_PRIORITY_TEST + 1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT1); + + ret = mq_send(mqueue, msgptr, strlen(msgptr), MQUEUE_PRIORITY_TEST + 1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT1); + + ret = mq_send(mqueue, msgptr, strlen(msgptr), MQUEUE_PRIORITY_TEST + 2); // 2, Mqueue priority. + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT1); + + ts.tv_sec = 1; + ts.tv_nsec = 0; + ret = mq_timedreceive(mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, ETIMEDOUT, errno, EXIT1); + + ret = strncmp(msgptr, msgrcd, strlen(msgptr)); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue169(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_169", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_173.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_173.cpp new file mode 100644 index 00000000..0db1dfce --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_173.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + UINT32 rvprio; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + CHAR msgrcd1[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + CHAR msgrcd2[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + const CHAR *msgptr1 = "test message 1"; + const CHAR *msgptr2 = "test message 2"; + mqd_t mqueue; + struct mq_attr attr = { 0 }; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq173_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_ASSERT_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue); + + ret = mq_send(mqueue, msgptr1, strlen(msgptr1), MQUEUE_PRIORITY_TEST + 1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT1); + + ret = mq_send(mqueue, msgptr2, strlen(msgptr2), MQUEUE_PRIORITY_TEST + 2); // 2, Mqueue priority. + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; + +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue173(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_173", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_175.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_175.cpp new file mode 100644 index 00000000..a3c7512c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_175.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + struct timespec ts; + struct mq_attr attr = { 0 }; + mqd_t mqueue; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq175_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_SHORT_ARRAY_LENGTH; + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_ASSERT_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue); + + ts.tv_sec = 1; + ts.tv_nsec = 0; + + ret = mq_timedsend(mqueue, msgptr, strlen(msgptr), MQUEUE_PRIORITY_TEST + 6, &ts); // 6, Mqueue priority. + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT1); + + ts.tv_sec++; + ret = mq_timedsend(mqueue, msgptr, strlen(msgptr), MQUEUE_PRIORITY_TEST + 10, &ts); // 10, Mqueue priority. + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT1); + + ts.tv_sec++; + ret = mq_timedsend(mqueue, msgptr, strlen(msgptr), MQUEUE_PRIORITY_TEST + 2, &ts); // 2, Mqueue priority. + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT1); + + ts.tv_sec++; + ret = mq_timedsend(mqueue, msgptr, strlen(msgptr), MQUEUE_PRIORITY_TEST + 8, &ts); // 8, Mqueue priority. + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT1); + + ts.tv_sec++; + ret = mq_timedsend(mqueue, msgptr, strlen(msgptr), MQUEUE_PRIORITY_TEST + 1, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue175(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_175", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_176.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_176.cpp new file mode 100644 index 00000000..cd7ea7da --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_176.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + UINT32 pri; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + struct timespec ts; + mqd_t mqueue; + struct mq_attr attr = { 0 }; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq176_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_ASSERT_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue); + + ts.tv_sec = 1; + ts.tv_nsec = 0; + ret = mq_timedsend(mqueue, msgptr, strlen(msgptr), MQUEUE_PRIORITY_TEST + 1, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT1); + + ts.tv_sec++; + ret = mq_timedsend(mqueue, msgptr, strlen(msgptr), MQUEUE_PRIORITY_TEST + 1, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT1); + + ts.tv_sec++; + ret = mq_timedsend(mqueue, msgptr, strlen(msgptr), MQUEUE_PRIORITY_TEST + 2, &ts); // 2, Mqueue priority. + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue176(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_176", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_177.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_177.cpp new file mode 100644 index 00000000..839c2099 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_177.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + UINT32 pri; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + struct timespec ts; + mqd_t mqueue; + struct mq_attr attr = { 0 }; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq177_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_SHORT_ARRAY_LENGTH; + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + ts.tv_sec = 1; + ts.tv_nsec = 0; + + ret = mq_timedsend(mqueue, msgptr, strlen(msgptr), MQ_PRIO_MAX - 1, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_receive(mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT1); + + ret = strncmp(msgptr, msgrcd, strlen(msgptr)); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + + +VOID ItPosixQueue177(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_177", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_187.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_187.cpp new file mode 100644 index 00000000..1cd1ad3e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_187.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + mqd_t mqueue; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq187_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + mqueue = mq_open(mqname, O_CREAT | O_NONBLOCK, S_IRUSR | S_IWUSR, 0); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + mqueue = mq_open(mqname, O_CREAT | 0, S_IRUSR | S_IWUSR, 0); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue187(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_187", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_200.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_200.cpp new file mode 100644 index 00000000..cf4bd076 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_200.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret = 0; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + mqd_t mqueue; + struct timespec ts; + struct mq_attr attr = { 0 }; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq200_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + ret = mq_send(mqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ts.tv_sec = 1; + ts.tv_nsec = 0; + errno = 0; + ret = mq_timedreceive(mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(errno, EBADF, errno, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue200(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_200", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_201.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_201.cpp new file mode 100644 index 00000000..e37726b4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_201.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH + 1] = {0}; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + pthread_t newTh; + struct mq_attr attr = { 0 }; + struct timespec ts = { 0 }; + mqd_t mqueue; + + attr.mq_msgsize = 20; // 20, queue message size. + attr.mq_maxmsg = 20; // 20, queue max message size. + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq201_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + mqueue = mq_open(mqname, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR, &attr); + ICUNIT_ASSERT_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue); + + ret = mq_timedsend(mqueue, msgptr, strlen(msgptr), 0, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_receive(mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + errno = 0; + ret = mq_timedsend(mqueue, msgptr, strlen(msgptr), 0, &ts); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT); + ICUNIT_GOTO_EQUAL(errno, EBADF, errno, EXIT); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue201(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_201", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_202.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_202.cpp new file mode 100644 index 00000000..bd5561ee --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_202.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret = MQUEUE_NO_ERROR, i; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + mqd_t mqueue; + struct timespec ts; + struct mq_attr attr = { 0 }; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq202_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + ret = mq_send(mqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + for (i = 0; i < MQUEUE_SHORT_ARRAY_LENGTH; i++) { + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT); + ICUNIT_GOTO_EQUAL(errno, ENOENT, errno, EXIT); + } + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue202(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_202", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_203.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_203.cpp new file mode 100644 index 00000000..49fdf3c4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_203.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + CHAR msgrv1[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + struct mq_attr attr = { 0 }; + INT32 ret = MQUEUE_NO_ERROR, i; + pthread_t pthread1, pthread2; + mqd_t mqueue1, mqueue2; + struct timespec ts; + + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \ + "/mq203_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + mqueue1 = mq_open(mqname, O_CREAT | O_RDWR | O_NONBLOCK, S_IRUSR | S_IWUSR, &attr); + ICUNIT_ASSERT_NOT_EQUAL(mqueue1, (mqd_t)-1, mqueue1); + + mqueue2 = mq_open(mqname, O_RDWR | O_EXCL, S_IRUSR | S_IWUSR, &attr); + ICUNIT_ASSERT_NOT_EQUAL(mqueue2, (mqd_t)-1, mqueue2); + + ts.tv_sec = 1; + ts.tv_nsec = 1; + ret = mq_timedreceive(mqueue1, msgrv1, MQUEUE_STANDARD_NAME_LENGTH, NULL, &ts); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + +EXIT: + mq_close(mqueue1); + mq_close(mqueue2); + mq_unlink(mqname); +EXIT1: + return LOS_OK; +} + +VOID ItPosixQueue203(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_203", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_204.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_204.cpp new file mode 100644 index 00000000..eac0f683 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_204.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +CHAR g_mqname[MQUEUE_STANDARD_NAME_LENGTH] = {0}; +struct mq_attr g_attr = { 0 }; +STATIC volatile UINT32 g_itSync = 0; +mqd_t g_mqueue1, g_mqueue2; + +static void *PthreadF01(void *arg) +{ + while (g_itSync != 1) { + } + + struct mqarray *ptrMqcb = (struct mqarray *)NULL; + g_mqueue1 = mq_open(g_mqname, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR, &g_attr); + LosTaskDelay(2); // 2, Set delay time. + if (g_mqueue1 != -1) { + mq_close(g_mqueue1); + mq_unlink(g_mqname); + } + return nullptr; +} + +static void *PthreadF02(void *arg) +{ + g_itSync = 1; + + struct mqarray *ptrMqcb = (struct mqarray *)NULL; + g_mqueue2 = mq_open(g_mqname, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR, &g_attr); + LosTaskDelay(2); // 2, Set delay time. + if (g_mqueue2 != -1) { + mq_close(g_mqueue2); + mq_unlink(g_mqname); + } + + ICUNIT_GOTO_EQUAL(((g_mqueue1 == -1) && (g_mqueue2 != -1)) || ((g_mqueue1 != -1) && (g_mqueue2 == -1)), TRUE, + g_mqueue1, EXIT); +EXIT: + return NULL; +} + +STATIC UINT32 Testcase(VOID) +{ + INT32 ret = MQUEUE_NO_ERROR, i; + pthread_t pthread1, pthread2; + pthread_attr_t attr1, attr2; + + ret = snprintf_s(g_mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH, + "/mq204_%d", LosCurTaskIDGet()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + g_attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + g_attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + + ret = pthread_attr_init(&attr1); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ret = pthread_create(&pthread1, &attr1, PthreadF01, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_attr_init(&attr2); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ret = pthread_create(&pthread2, &attr2, PthreadF02, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + LosTaskDelay(10); // 10, Set delay time. + +EXIT: + (VOID)pthread_join(pthread1, NULL); + (VOID)pthread_join(pthread2, NULL); +EXIT1: + return LOS_OK; +} + +VOID ItPosixQueue204(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_204", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_205.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_205.cpp new file mode 100644 index 00000000..1d9cd9df --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_205.cpp @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static mqd_t g_mqueue; +static CHAR g_mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; +static int g_signo; + +static void SigUsr1(int signo) +{ + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + int ret; + g_signo = signo; + + ret = mq_receive(g_mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, nullptr); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, MQUEUE_SEND_STRING_TEST, msgrcd, EXIT); + + return; +EXIT: + exit(255); // 255, Set a exit status. +} +static void Child(void) +{ + int ret; + struct sigevent sigev; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + struct mq_attr attr; + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = 1; + + ret = snprintf_s(g_mqname, MQUEUE_STANDARD_NAME_LENGTH - 1, MQUEUE_STANDARD_NAME_LENGTH, "/mq205_%d", getpid()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + + g_mqueue = mq_open(g_mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(g_mqueue, (mqd_t)-1, g_mqueue, EXIT); + + signal(SIGUSR1, SigUsr1); + + sigev.sigev_notify = SIGEV_SIGNAL; + sigev.sigev_signo = SIGUSR1; + + g_signo = 0; + + ret = mq_notify(g_mqueue, &sigev); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_send(g_mqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + while (g_signo == 0) { + } + ICUNIT_GOTO_EQUAL(g_signo, SIGUSR1, g_signo, EXIT); + + mq_close(g_mqueue); + mq_unlink(g_mqname); + + exit(10); // 10, Set a exit status. + +EXIT: + mq_close(g_mqueue); + mq_unlink(g_mqname); +EXIT1: + return; +} + +static UINT32 TestCase(VOID) +{ + int ret; + int status; + + pid_t pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, Valid range value of pid. + + if (pid == 0) { + Child(); + exit(255); // 255, Set a exit status. + } + + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(status, 10, status); // 10, Here, assert the ret. + + return 0; +EXIT: + return 1; +} + +VOID ItPosixQueue205(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_205", TestCase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_206.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_206.cpp new file mode 100644 index 00000000..160d1437 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_206.cpp @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static int Child(VOID) +{ + int ret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + int pid; + int status; + mqd_t mqueue; + struct sigevent notification; + + (void)snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH - 1, MQUEUE_STANDARD_NAME_LENGTH, "/mq206_%d", getpid()); + + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, nullptr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT); + + notification.sigev_notify = 5; // 5, User-defined signal. + + ret = mq_notify(mqueue, ¬ification); + ICUNIT_GOTO_EQUAL(ret, -1, ret, EXIT); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT); + + notification.sigev_notify = SIGEV_THREAD; + + ret = mq_notify(mqueue, ¬ification); + ICUNIT_GOTO_EQUAL(ret, -1, ret, EXIT); + ICUNIT_GOTO_EQUAL(errno, ENOTSUP, errno, EXIT); + + notification.sigev_notify = SIGEV_NONE; + + ret = mq_notify(-1, ¬ification); + ICUNIT_GOTO_EQUAL(ret, -1, ret, EXIT); + ICUNIT_GOTO_EQUAL(errno, EBADF, errno, EXIT); + + ret = mq_notify(mqueue, ¬ification); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, Valid range value of pid. + + if (pid == 0) { + ret = mq_notify(mqueue, ¬ification); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, EBUSY, errno); + + exit(8); // 8, Set a exit status. + } else { + ret = waitpid(pid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT); + + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 8, status, EXIT); // 8, Here, assert the ret. + + ret = mq_notify(mqueue, nullptr); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, Valid range value of pid. + if (pid == 0) { + notification.sigev_notify = SIGEV_SIGNAL; + notification.sigev_signo = SIGUSR1; + + ret = mq_notify(mqueue, ¬ification); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + exit(11); // 11, Set a exit status. + } + + ret = waitpid(pid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT); + + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 11, status, EXIT); // 11, Here, assert the ret. + + mq_close(mqueue); + mq_unlink(mqname); + } + exit(10); // 10, Set a exit status. + +EXIT: + mq_close(mqueue); + mq_unlink(mqname); + return MQUEUE_IS_ERROR; +} +static UINT32 Testcase(VOID) +{ + int ret; + int status; + + pid_t pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, Valid range value of pid. + + if (pid == 0) { + Child(); + exit(255); // 255, Set a exit status. + } + + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(status, 10, status); // 10, Here, assert the ret. + + return 0; +EXIT: + return 1; +} + +VOID ItPosixQueue206(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_206", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_207.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_207.cpp new file mode 100644 index 00000000..8823d793 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_207.cpp @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static mqd_t g_mqueue; +static CHAR g_mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; +static int g_signo; + +static void SigUsr1(int signo) +{ + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + int ret; + + g_signo = 1; + + ret = mq_receive(g_mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, nullptr); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, MQUEUE_SEND_STRING_TEST, msgrcd, EXIT); + + return; +EXIT: + exit(255); // 255, Set a exit status. +} +static void Child(void) +{ + int ret; + struct sigevent sigev = {0}; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + struct mq_attr attr; + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = 1; + + ret = snprintf_s(g_mqname, MQUEUE_STANDARD_NAME_LENGTH - 1, MQUEUE_STANDARD_NAME_LENGTH, "/mq207_%d", getpid()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + + g_mqueue = mq_open(g_mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(g_mqueue, (mqd_t)-1, g_mqueue, EXIT); + + signal(SIGUSR1, SigUsr1); + + sigev.sigev_notify = SIGEV_NONE; + g_signo = 0; + + ret = mq_notify(g_mqueue, &sigev); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + ret = mq_send(g_mqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + for (int i = 0; i < 5; i++) { // 5, The loop frequency. + sleep(1); + } + ICUNIT_GOTO_EQUAL(g_signo, 0, g_signo, EXIT); + + mq_close(g_mqueue); + mq_unlink(g_mqname); + + exit(10); // 10, Set a exit status. +EXIT: + mq_close(g_mqueue); + mq_unlink(g_mqname); +EXIT1: + return; +} + +static UINT32 Testcase(VOID) +{ + int ret; + int status; + + pid_t pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, Valid range value of pid. + + if (pid == 0) { + Child(); + exit(255); // 255, Set a exit status. + } + + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(status, 10, status); // 10, Here, assert the ret. + + return 0; +EXIT: + return 1; +} + +VOID ItPosixQueue207(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_207", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_208.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_208.cpp new file mode 100644 index 00000000..fd3ff84d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_208.cpp @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static mqd_t g_mqueue; +static CHAR g_mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; +static int g_signo; + +static void SigUsr1(int signo) +{ + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + int ret; + g_signo = signo; + + ret = mq_receive(g_mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, nullptr); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, MQUEUE_SEND_STRING_TEST, msgrcd, EXIT); + + return; +EXIT: + exit(255); // 255, Set a exit status. +} +static void Child(void) +{ + int ret; + struct sigevent sigev; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + struct mq_attr attr; + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = 3; // 3, queue max message size. + + ret = snprintf_s(g_mqname, MQUEUE_STANDARD_NAME_LENGTH - 1, MQUEUE_STANDARD_NAME_LENGTH, "/mq208_%d", getpid()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + + g_mqueue = mq_open(g_mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(g_mqueue, (mqd_t)-1, g_mqueue, EXIT); + + signal(SIGUSR1, SigUsr1); + + sigev.sigev_notify = SIGEV_SIGNAL; + sigev.sigev_signo = SIGUSR1; + + g_signo = 0; + + ret = mq_send(g_mqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + for (int i = 0; i < 5; i++) { // 5, The loop frequency. + sleep(1); + } + ICUNIT_GOTO_EQUAL(g_signo, 0, g_signo, EXIT); + + ret = mq_notify(g_mqueue, &sigev); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_send(g_mqueue, g_mqueueMsessage[1], MQUEUE_SHORT_ARRAY_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + for (int i = 0; i < 5; i++) { // 5, The loop frequency. + sleep(1); + } + ICUNIT_GOTO_EQUAL(g_signo, 0, g_signo, EXIT); + + ret = mq_receive(g_mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, nullptr); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, MQUEUE_SEND_STRING_TEST, msgrcd, EXIT); + + ret = mq_receive(g_mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, nullptr); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, g_mqueueMsessage[1], msgrcd, EXIT); + + ret = mq_send(g_mqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + while (g_signo == 0) { + } + ICUNIT_GOTO_EQUAL(g_signo, SIGUSR1, g_signo, EXIT); + + ret = mq_notify(g_mqueue, &sigev); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + mq_close(g_mqueue); + mq_unlink(g_mqname); + exit(10); // 10, Set a exit status. + +EXIT: + mq_close(g_mqueue); + mq_unlink(g_mqname); +EXIT1: + return; +} +static UINT32 Testcase(VOID) +{ + int ret; + int status; + + pid_t pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, Valid range value of pid. + + if (pid == 0) { + Child(); + exit(255); // 255, Set a exit status. + } + + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(status, 10, status); // 10, Here, assert the ret. + + return 0; +EXIT: + return 1; +} + +VOID ItPosixQueue208(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_208", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_209.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_209.cpp new file mode 100644 index 00000000..4a8e53fc --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/full/It_posix_queue_209.cpp @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static mqd_t g_mqueue; +static CHAR g_mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; +static int g_signo; +static int g_cnt; + +static VOID *Pthread(VOID *temp) +{ + INT32 ret; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + g_cnt = 1; + + (void)(temp); + ret = mq_receive(g_mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, nullptr); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, MQUEUE_SEND_STRING_TEST, msgrcd, EXIT); + + return nullptr; +EXIT: + g_cnt = 0; + return nullptr; +} + +static void SigUsr1(int signo) +{ + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + int ret; + g_signo = signo; + + ret = mq_receive(g_mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, nullptr); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, g_mqueueMsessage[1], msgrcd, EXIT); + + return; +EXIT: + exit(255); // 255, Set a exit status. +} +static void Child(void) +{ + int ret; + struct sigevent sigev = {0}; + pthread_t pthread1; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + struct mq_attr attr = {0}; + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = 3; // 3, queue max message size. + + ret = snprintf_s(g_mqname, MQUEUE_STANDARD_NAME_LENGTH - 1, MQUEUE_STANDARD_NAME_LENGTH, "/mq209_%d", getpid()); + ICUNIT_GOTO_NOT_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + + g_mqueue = mq_open(g_mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(g_mqueue, (mqd_t)-1, g_mqueue, EXIT); + + signal(SIGUSR1, SigUsr1); + + sigev.sigev_notify = SIGEV_SIGNAL; + sigev.sigev_signo = SIGUSR1; + + g_signo = 0; + g_cnt = 0; + + ret = pthread_create(&pthread1, nullptr, Pthread, nullptr); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + for (int i = 0; i < 3; i++) { // 3, The loop frequency. + sleep(1); + } + ICUNIT_GOTO_EQUAL(g_cnt, 1, g_cnt, EXIT); + ret = mq_notify(g_mqueue, &sigev); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_send(g_mqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = pthread_join(pthread1, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_cnt, 1, g_cnt, EXIT); + ICUNIT_GOTO_EQUAL(g_signo, 0, g_signo, EXIT); + + ret = mq_send(g_mqueue, g_mqueueMsessage[1], MQUEUE_SHORT_ARRAY_LENGTH, 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + while (g_signo == 0) { + } + ICUNIT_GOTO_EQUAL(g_signo, SIGUSR1, g_signo, EXIT); + + mq_close(g_mqueue); + mq_unlink(g_mqname); + exit(10); // 10, Set a exit status. + +EXIT: + mq_close(g_mqueue); + mq_unlink(g_mqname); +EXIT1: + return; +} +static UINT32 Testcase(VOID) +{ + int ret; + int status; + + pid_t pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, Valid range value of pid. + + if (pid == 0) { + Child(); + exit(255); // 255, Set a exit status. + } + + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(status, 10, status); // 10, Here, assert the ret. + + return 0; +EXIT: + return 1; +} + +VOID ItPosixQueue209(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_209", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/posix_mqueue_test.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/posix_mqueue_test.cpp new file mode 100644 index 00000000..5835f7a5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/posix_mqueue_test.cpp @@ -0,0 +1,1299 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "stdio.h" +#include +#include + + +#include "It_posix_queue.h" +CHAR *g_mqueueMsessage[MQUEUE_SHORT_ARRAY_LENGTH] = {"0123456789", "1234567890", "2345678901", "3456789012", "4567890123", "5678901234", "6789012345", "7890123456", "lalalalala", "hahahahaha"}; +CHAR g_gqname[MQUEUE_STANDARD_NAME_LENGTH]; +CHAR g_mqueueName[LOSCFG_BASE_IPC_QUEUE_CONFIG + 1][MQUEUE_STANDARD_NAME_LENGTH]; +mqd_t g_mqueueId[LOSCFG_BASE_IPC_QUEUE_CONFIG + 1]; +SEM_HANDLE_T g_mqueueSem; +mqd_t g_messageQId; +mqd_t g_gqueue; + +int LOS_HwiCreate(int hwiNum, int hwiPrio, int hwiMode, HWI_PROC_FUNC hwiHandler, int *irqParam) +{ + return 0; +} + +int LosSemCreate(int num, const SEM_HANDLE_T *hdl) +{ + return 0; +} + +int LosSemDelete(SEM_HANDLE_T num) +{ + return 0; +} + +int SemPost(SEM_HANDLE_T num) +{ + return 0; +} + +int LosSemPost(SEM_HANDLE_T num) +{ + return 0; +} + +int HalIrqMask(int num) +{ + return 0; +} + +int SemPend(SEM_HANDLE_T hdl, int num) +{ + return 0; +} + +int LosSemPend(SEM_HANDLE_T hdl, int num) +{ + return 0; +} + +UINT32 QueueCountGetTest(VOID) +{ + return 0; +} + +void TEST_HwiTrigger(unsigned int irq) +{ + return; +} + +UINT64 JiffiesToTick(unsigned long j) +{ + return 0; +} + +unsigned long MsecsToJiffies(const unsigned int m) +{ + return 0; +} + +using namespace testing::ext; +namespace OHOS { +class PosixMqueueTest : public testing::Test { +public: + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} +}; + +#if defined(LOSCFG_USER_TEST_SMOKE) +/* * + * @tc.name: IT_POSIX_QUEUE_001 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue001, TestSize.Level0) +{ + ItPosixQueue001(); +} + +/* * + * @tc.name: IT_POSIX_QUEUE_003 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue003, TestSize.Level0) +{ + ItPosixQueue003(); +} + +/* * + * @tc.name: IT_POSIX_QUEUE_053 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue053, TestSize.Level0) +{ + ItPosixQueue053(); +} + +/* * + * @tc.name: IT_POSIX_QUEUE_028 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue028, TestSize.Level0) +{ + ItPosixQueue028(); +} + +/* * + * @tc.name: IT_POSIX_QUEUE_062 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue062, TestSize.Level0) +{ + ItPosixQueue062(); +} + +#endif + +#if defined(LOSCFG_USER_TEST_FULL) +/** + * @tc.name: IT_POSIX_QUEUE_002 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue002, TestSize.Level0) +{ + ItPosixQueue002(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_005 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue005, TestSize.Level0) +{ + ItPosixQueue005(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_008 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue008, TestSize.Level0) +{ + ItPosixQueue008(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_011 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue011, TestSize.Level0) +{ + ItPosixQueue011(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_013 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue013, TestSize.Level0) +{ + ItPosixQueue013(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_014 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue014, TestSize.Level0) +{ + ItPosixQueue014(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_015 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue015, TestSize.Level0) +{ + ItPosixQueue015(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_016 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue016, TestSize.Level0) +{ + ItPosixQueue016(); +} + +#ifndef LOSCFG_KERNEL_SMP +/** + * @tc.name: IT_POSIX_QUEUE_113 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue113, TestSize.Level0) +{ + ItPosixQueue113(); +} +#endif +/** + * @tc.name: IT_POSIX_QUEUE_018 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue018, TestSize.Level0) +{ + ItPosixQueue018(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_019 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue019, TestSize.Level0) +{ + ItPosixQueue019(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_020 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue020, TestSize.Level0) +{ + ItPosixQueue020(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_021 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue021, TestSize.Level0) +{ + ItPosixQueue021(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_025 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue025, TestSize.Level0) +{ + ItPosixQueue025(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_026 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue026, TestSize.Level0) +{ + ItPosixQueue026(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_027 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue027, TestSize.Level0) +{ + ItPosixQueue027(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_030 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue030, TestSize.Level0) +{ + ItPosixQueue030(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_031 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue031, TestSize.Level0) +{ + ItPosixQueue031(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_032 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue032, TestSize.Level0) +{ + ItPosixQueue032(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_033 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue033, TestSize.Level0) +{ + ItPosixQueue033(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_036 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue036, TestSize.Level0) +{ + ItPosixQueue036(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_038 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue038, TestSize.Level0) +{ + ItPosixQueue038(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_040 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue040, TestSize.Level0) +{ + ItPosixQueue040(); +} + +#ifndef LOSCFG_USER_TEST_SMP +/** + * @tc.name: IT_POSIX_QUEUE_041 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue041, TestSize.Level0) +{ + ItPosixQueue041(); +} +#endif + +/** + * @tc.name: IT_POSIX_QUEUE_042 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue042, TestSize.Level0) +{ + ItPosixQueue042(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_044 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue044, TestSize.Level0) +{ + ItPosixQueue044(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_046 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue046, TestSize.Level0) +{ + ItPosixQueue046(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_047 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue047, TestSize.Level0) +{ + ItPosixQueue047(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_048 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue048, TestSize.Level0) +{ + ItPosixQueue048(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_049 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue049, TestSize.Level0) +{ + ItPosixQueue049(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_050 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue050, TestSize.Level0) +{ + ItPosixQueue050(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_052 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue052, TestSize.Level0) +{ + ItPosixQueue052(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_054 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue054, TestSize.Level0) +{ + ItPosixQueue054(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_055 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue055, TestSize.Level0) +{ + ItPosixQueue055(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_056 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue056, TestSize.Level0) +{ + ItPosixQueue056(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_057 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue057, TestSize.Level0) +{ + ItPosixQueue057(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_058 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue058, TestSize.Level0) +{ + ItPosixQueue058(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_060 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue060, TestSize.Level0) +{ + ItPosixQueue060(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_061 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue061, TestSize.Level0) +{ + ItPosixQueue061(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_063 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue063, TestSize.Level0) +{ + ItPosixQueue063(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_064 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue064, TestSize.Level0) +{ + ItPosixQueue064(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_065 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue065, TestSize.Level0) +{ + ItPosixQueue065(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_066 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue066, TestSize.Level0) +{ + ItPosixQueue066(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_067 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue067, TestSize.Level0) +{ + ItPosixQueue067(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_069 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue069, TestSize.Level0) +{ + ItPosixQueue069(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_070 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue070, TestSize.Level0) +{ + ItPosixQueue070(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_071 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue071, TestSize.Level0) +{ + ItPosixQueue071(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_072 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue072, TestSize.Level0) +{ + ItPosixQueue072(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_073 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue073, TestSize.Level0) +{ + ItPosixQueue073(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_074 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue074, TestSize.Level0) +{ + ItPosixQueue074(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_075 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue075, TestSize.Level0) +{ + ItPosixQueue075(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_080 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue080, TestSize.Level0) +{ + ItPosixQueue080(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_081 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue081, TestSize.Level0) +{ + ItPosixQueue081(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_082 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue082, TestSize.Level0) +{ + ItPosixQueue082(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_083 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue083, TestSize.Level0) +{ + ItPosixQueue083(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_084 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue084, TestSize.Level0) +{ + ItPosixQueue084(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_085 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue085, TestSize.Level0) +{ + ItPosixQueue085(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_086 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue086, TestSize.Level0) +{ + ItPosixQueue086(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_087 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue087, TestSize.Level0) +{ + ItPosixQueue087(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_088 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue088, TestSize.Level0) +{ + ItPosixQueue088(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_089 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue089, TestSize.Level0) +{ + ItPosixQueue089(); +} + + +#ifndef TEST3559A_M7 +/** + * @tc.name: IT_POSIX_QUEUE_090 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue090, TestSize.Level0) +{ + ItPosixQueue090(); +} + +#endif +/** + * @tc.name: IT_POSIX_QUEUE_091 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue091, TestSize.Level0) +{ + ItPosixQueue091(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_093 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue093, TestSize.Level0) +{ + ItPosixQueue093(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_094 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue094, TestSize.Level0) +{ + ItPosixQueue094(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_095 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue095, TestSize.Level0) +{ + ItPosixQueue095(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_096 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue096, TestSize.Level0) +{ + ItPosixQueue096(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_097 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue097, TestSize.Level0) +{ + ItPosixQueue097(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_098 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue098, TestSize.Level0) +{ + ItPosixQueue098(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_100 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue100, TestSize.Level0) +{ + ItPosixQueue100(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_101 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue101, TestSize.Level0) +{ + ItPosixQueue101(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_102 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue102, TestSize.Level0) +{ + ItPosixQueue102(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_103 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue103, TestSize.Level0) +{ + ItPosixQueue103(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_104 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue104, TestSize.Level0) +{ + ItPosixQueue104(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_106 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue106, TestSize.Level0) +{ + ItPosixQueue106(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_108 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue108, TestSize.Level0) +{ + ItPosixQueue108(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_109 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue109, TestSize.Level0) +{ + ItPosixQueue109(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_110 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue110, TestSize.Level0) +{ + ItPosixQueue110(); +} + + +/** + * @tc.name: IT_POSIX_QUEUE_127 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue127, TestSize.Level0) +{ + ItPosixQueue127(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_128 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue128, TestSize.Level0) +{ + ItPosixQueue128(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_129 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue129, TestSize.Level0) +{ + ItPosixQueue129(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_130 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue130, TestSize.Level0) +{ + ItPosixQueue130(); +} + +/* * + * @tc.name: IT_POSIX_QUEUE_144 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue144, TestSize.Level0) +{ + ItPosixQueue144(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_147 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue147, TestSize.Level0) +{ + ItPosixQueue147(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_148 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue148, TestSize.Level0) +{ + ItPosixQueue148(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_149 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue149, TestSize.Level0) +{ + ItPosixQueue149(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_150 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue150, TestSize.Level0) +{ + ItPosixQueue150(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_151 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue151, TestSize.Level0) +{ + ItPosixQueue151(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_152 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue152, TestSize.Level0) +{ + ItPosixQueue152(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_153 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue153, TestSize.Level0) +{ + ItPosixQueue153(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_154 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue154, TestSize.Level0) +{ + ItPosixQueue154(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_155 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue155, TestSize.Level0) +{ + ItPosixQueue155(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_156 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue156, TestSize.Level0) +{ + ItPosixQueue156(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_164 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue164, TestSize.Level0) +{ + ItPosixQueue164(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_165 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue165, TestSize.Level0) +{ + ItPosixQueue165(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_166 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue166, TestSize.Level0) +{ + ItPosixQueue166(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_168 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue168, TestSize.Level0) +{ + ItPosixQueue168(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_169 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue169, TestSize.Level0) +{ + ItPosixQueue169(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_173 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue173, TestSize.Level0) +{ + ItPosixQueue173(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_175 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue175, TestSize.Level0) +{ + ItPosixQueue175(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_176 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue176, TestSize.Level0) +{ + ItPosixQueue176(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_187 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue187, TestSize.Level0) +{ + ItPosixQueue187(); +} + + +/** + * @tc.name: IT_POSIX_QUEUE_200 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue200, TestSize.Level0) +{ + ItPosixQueue200(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_201 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue201, TestSize.Level0) +{ + ItPosixQueue201(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_202 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue202, TestSize.Level0) +{ + ItPosixQueue202(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_203 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue203, TestSize.Level0) +{ + ItPosixQueue203(); +} + +#if (LOSCFG_USER_TEST_SMP == 1) +/** + * @tc.name: IT_POSIX_QUEUE_204 + * @tc.desc: function for PosixMqueueTest + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue204, TestSize.Level0) +{ + ItPosixQueue204(); +} + +#endif + +/** + * @tc.name: IT_POSIX_QUEUE_205 + * @tc.desc: function for mq_notify:Set sigev_notify to SIGEV_NONE + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue205, TestSize.Level0) +{ + ItPosixQueue205(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_206 + * @tc.desc: function for mq_notify:The function returns a failure and the error code is verified. + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue206, TestSize.Level0) +{ + ItPosixQueue206(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_207 + * @tc.desc: function for mq_notify:Set sigev_notify to SIGEV_NONE + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue207, TestSize.Level0) +{ + ItPosixQueue207(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_208 + * @tc.desc: function for mq_notify:The message queue is not empty. + * @tc.type: FUNC + */ +HWTEST_F(PosixMqueueTest, ItPosixQueue208, TestSize.Level0) +{ + ItPosixQueue208(); +} + +/** + * @tc.name: IT_POSIX_QUEUE_209 + * @tc.desc: function for mq_notify:The message queue has waiters. + * @tc.type: FUNC + **/ +HWTEST_F(PosixMqueueTest, ItPosixQueue209, TestSize.Level0) +{ + ItPosixQueue209(); +} + +#endif +} // namespace OHOS diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/smoke/It_posix_queue_001.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/smoke/It_posix_queue_001.cpp new file mode 100644 index 00000000..73d7e9ff --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/smoke/It_posix_queue_001.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + struct mq_attr attr = {0}; + mqd_t mqueue; + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = 0; + + (void)snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH - 1, MQUEUE_STANDARD_NAME_LENGTH, "/mq001_%d", + LosCurTaskIDGet()); + + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + ret = mq_send(mqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + + ret = mq_receive(mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); + return MQUEUE_IS_ERROR; +} + +VOID ItPosixQueue001(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_001", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/smoke/It_posix_queue_003.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/smoke/It_posix_queue_003.cpp new file mode 100644 index 00000000..36ea7b5f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/smoke/It_posix_queue_003.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + mqd_t mqueue; + struct mq_attr attr = {0}; + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = 1; + + (void)snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH - 1, MQUEUE_STANDARD_NAME_LENGTH, "/mq003_%d", + LosCurTaskIDGet()); + + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT2); + + ret = mq_send(mqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_receive(mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT); + ICUNIT_GOTO_STRING_EQUAL(msgrcd, MQUEUE_SEND_STRING_TEST, msgrcd, EXIT); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT2); + + return MQUEUE_NO_ERROR; +EXIT: + mq_close(mqueue); +EXIT1: + mq_unlink(mqname); +EXIT2: + return MQUEUE_IS_ERROR; +} + +VOID ItPosixQueue003(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_003", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/smoke/It_posix_queue_028.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/smoke/It_posix_queue_028.cpp new file mode 100644 index 00000000..2fe36711 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/smoke/It_posix_queue_028.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +const int queue_msg_size = 20; +const int queue_max_msg_size = 20; + +static UINT32 Testcase(VOID) +{ + INT32 ret; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + CHAR msgrcd[queue_max_msg_size] = {0}; + struct mq_attr attr = {0}; + struct timespec absTimeout = {0}; + mqd_t mqueue; + + (void)snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH - 1, MQUEUE_STANDARD_NAME_LENGTH, "/mq028_%d", + LosCurTaskIDGet()); + + attr.mq_msgsize = queue_msg_size; + attr.mq_maxmsg = queue_max_msg_size; + + mqueue = mq_open(mqname, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR, &attr); + ICUNIT_ASSERT_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue); + + ret = mq_timedsend(mqueue, "1234567890123456789", queue_msg_size, 0, &absTimeout); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_receive(mqueue, msgrcd, queue_msg_size, NULL); + ICUNIT_GOTO_EQUAL(ret, queue_msg_size, ret, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + mqueue = mq_open(mqname, O_RDWR | O_NONBLOCK, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT2); + + ret = mq_receive(mqueue, msgrcd, queue_msg_size, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_IS_ERROR, ret, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); +EXIT2: + return MQUEUE_IS_ERROR; +} + +VOID ItPosixQueue028(VOID) +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_028", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/smoke/It_posix_queue_053.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/smoke/It_posix_queue_053.cpp new file mode 100644 index 00000000..7197681e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/smoke/It_posix_queue_053.cpp @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static VOID *PthreadF01(VOID *argument) +{ + INT32 ret; + const CHAR *msgptr = MQUEUE_SEND_STRING_TEST; + + g_testCount = 1; + + TestAssertWaitDelay(&g_testCount, 3); // 3, Here, assert the g_testCount. + + ret = mq_send(g_gqueue, msgptr, strlen(msgptr), 0); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + g_testCount = 2; // 2, Init test count value. + + return NULL; +EXIT: + mq_close(g_gqueue); + mq_unlink(g_gqname); + g_testCount = 0; + return NULL; +} + +static VOID *PthreadF02(VOID *argument) +{ + INT32 ret = 0; + CHAR msgrv[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + + g_testCount = 3; // 3, Init test count value. + + ret = mq_receive(g_gqueue, msgrv, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT); + + ret = LosTaskDelay(1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_close(g_gqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + ret = mq_unlink(g_gqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + g_testCount = 4; // 4, Init test count value. + return NULL; +EXIT: + mq_close(g_gqueue); + mq_unlink(g_gqname); + g_testCount = 0; + return NULL; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + struct mq_attr attr = { 0 }; + pthread_attr_t attr1; + pthread_t newTh1, newTh2; + + (void)snprintf_s(g_gqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, + "/mq053_%d", LosCurTaskIDGet()); + + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH; + g_gqueue = mq_open(g_gqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ICUNIT_GOTO_NOT_EQUAL(g_gqueue, (mqd_t)-1, g_gqueue, EXIT); + + g_testCount = 0; + + ret = PosixPthreadInit(&attr1, MQUEUE_PTHREAD_PRIORITY_TEST1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = pthread_create(&newTh1, &attr1, PthreadF01, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + TestAssertWaitDelay(&g_testCount, 1); + + ret = PosixPthreadInit(&attr1, MQUEUE_PTHREAD_PRIORITY_TEST2); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = pthread_create(&newTh2, &attr1, PthreadF02, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + +#ifdef TEST3559A_M7 + ret = LosTaskDelay(50); // 50, Set delay time. +#else + ret = LosTaskDelay(10); // 10, Set delay time. +#endif + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + TestAssertWaitDelay(&g_testCount, 4); // 4, Here, assert the g_testCount. + + ret = PosixPthreadDestroy(&attr1, newTh2); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT2); + + ret = PosixPthreadDestroy(&attr1, newTh1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + return MQUEUE_NO_ERROR; +EXIT2: + PosixPthreadDestroy(&attr1, newTh2); +EXIT1: + PosixPthreadDestroy(&attr1, newTh1); +EXIT: + mq_close(g_gqueue); + mq_unlink(g_gqname); + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue053(VOID) +{ + TEST_ADD_CASE("ItPosixQueue053", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/smoke/It_posix_queue_062.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/smoke/It_posix_queue_062.cpp new file mode 100644 index 00000000..1b9cbd65 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/mqueue/smoke/It_posix_queue_062.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_queue.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret = 0; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + mqd_t mqueue; + struct mq_attr mqstat1 = { 0 }; + struct mq_attr mqstat2 = { 0 }; + + (void)snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH - 1, MQUEUE_STANDARD_NAME_LENGTH, "/mq062_%d", + LosCurTaskIDGet()); + + mqueue = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, NULL); + ICUNIT_GOTO_NOT_EQUAL(mqueue, (mqd_t)-1, mqueue, EXIT1); + + ret = memset_s(&mqstat1, sizeof(mqstat1), 0, sizeof(mqstat1)); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ret = memset_s(&mqstat2, sizeof(mqstat2), 0, sizeof(mqstat2)); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = mq_getattr(mqueue, &mqstat1); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + mqstat1.mq_flags |= O_NONBLOCK; + ret = mq_setattr(mqueue, &mqstat1, NULL); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_getattr(mqueue, &mqstat2); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + ICUNIT_GOTO_EQUAL(mqstat2.mq_flags, mqstat1.mq_flags, mqstat2.mq_flags, EXIT1); + ICUNIT_GOTO_EQUAL(mqstat2.mq_curmsgs, 0, mqstat2.mq_curmsgs, EXIT1); + ICUNIT_GOTO_EQUAL(mqstat2.mq_flags, O_CREAT | O_RDWR | O_NONBLOCK, mqstat2.mq_flags, EXIT1); + ICUNIT_GOTO_EQUAL(mqstat2.mq_maxmsg, mqstat1.mq_maxmsg, mqstat2.mq_maxmsg, EXIT1); + ICUNIT_GOTO_EQUAL(mqstat2.mq_msgsize, mqstat1.mq_msgsize, mqstat2.mq_msgsize, EXIT1); + + ret = mq_close(mqueue); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT1); + + ret = mq_unlink(mqname); + ICUNIT_GOTO_EQUAL(ret, MQUEUE_NO_ERROR, ret, EXIT); + + return MQUEUE_NO_ERROR; +EXIT1: + mq_close(mqueue); +EXIT: + mq_unlink(mqname); + return MQUEUE_NO_ERROR; +} + +VOID ItPosixQueue062(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_QUEUE_062", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/It_posix_pthread.h b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/It_posix_pthread.h new file mode 100644 index 00000000..5639b799 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/It_posix_pthread.h @@ -0,0 +1,441 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _IT_POSIX_PTHREAD_H +#define _IT_POSIX_PTHREAD_H + +#include "sched.h" +#include "signal.h" +#include "semaphore.h" +#include "sched.h" +#include "osTest.h" +#include "pthread.h" +#include "limits.h" +#include "unistd.h" +#include "mqueue.h" +#include "signal.h" +#include "sys/time.h" + +#ifndef VERBOSE +#define VERBOSE 1 +#endif + +/* Some routines are part of the XSI Extensions */ + +#define LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE (0x6000) +#define LOS_HwiCreate(ID, prio, mode, Func, arg) (-1) +#define HalIrqMask(ID) +#define TEST_TEST_HwiDelete(ID, NULL) +#define TEST_HwiTrigger(HWI_NUM_TEST) +#define LOS_TaskLock() +#define LOS_TaskUnlock() +#define LOS_MS2Tick(ms) ((ms) / 10) +#define OS_TASK_PRIORITY_HIGHEST 0 +#define OS_TASK_PRIORITY_LOWEST 31 + +#define PTHREAD_NO_ERROR 0 +#define PTHREAD_IS_ERROR (-1) +#define PTHREAD_SIGNAL_SUPPORT 0 /* 0 means that not support the signal */ +#define PTHREAD_PRIORITY_TEST 20 +#define PTHREAD_DEFAULT_STACK_SIZE (LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE) +#define PTHREAD_KEY_NUM 10 +#define THREAD_NUM 3 +#define PTHREAD_TIMEOUT (THREAD_NUM * 2) +#define PTHREAD_INTHREAD_TEST 0 /* Control going to or is already for Thread */ +#define PTHREAD_INMAIN_TEST 1 /* Control going to or is already for Main */ +#define INVALID_PSHARED_VALUE (-100) +#define NUM_OF_CONDATTR 10 +#define RUNTIME 5 +#define PTHREAD_THREADS_NUM 3 +#define TCOUNT 5 // Number of single-threaded polling +#define COUNT_LIMIT 7 // The number of times the signal is sent +#define HIGH_PRIORITY 5 +#define LOW_PRIORITY 10 +#define PTHREAD_EXIT_VALUE ((void *)100) /* The return code of the thread when using pthread_exit(). */ + +#define PTHREAD_EXISTED_NUM TASK_EXISTED_NUM +#define PTHREAD_EXISTED_SEM_NUM SEM_EXISTED_NUM + +/* We are testing conformance to IEEE Std 1003.1, 2003 Edition */ +#define _POSIX_C_SOURCE 200112L + +#define uart_printf_func printf + +/* The value below shall be >= to the # of CPU on the test architecture */ +#define NCPU (4) + +#define PRIORITY_OTHER (-1) +#define PRIORITY_FIFO 20 +#define PRIORITY_RR 20 + +#define PTHREAD_TEST_BUG printf + +#define CASE(det, expl, scp, spa, sco, sta, gua, ssi, desc, res) \ + { \ + { 0 }, det, expl, scp, spa, sco, sta, gua, ssi, desc, NULL, res, \ + { \ + 0 \ + } \ + } +#define CASE_POS(det, expl, scp, spa, sco, sta, gua, ssi, desc) CASE(det, expl, scp, spa, sco, sta, gua, ssi, desc, 0) +#define CASE_NEG(det, expl, scp, spa, sco, sta, gua, ssi, desc) CASE(det, expl, scp, spa, sco, sta, gua, ssi, desc, 1) +#define CASE_UNK(det, expl, scp, spa, sco, sta, gua, ssi, desc) CASE(det, expl, scp, spa, sco, sta, gua, ssi, desc, 2) + +struct params { + INT32 policy; + INT32 priority; + char *policy_label; + INT32 status; +}; + +typedef struct { + /* + * Object to hold the given configuration, + * and which will be used to create the threads + */ + pthread_attr_t ta; + + /* General parameters */ + /* 0 => joinable; 1 => detached */ + INT32 detached; + + /* Scheduling parameters */ + /* + * 0 => sched policy is inherited; + * 1 => sched policy from the attr param + */ + INT32 explicitsched; + /* 0 => default; 1=> SCHED_FIFO; 2=> SCHED_RR */ + INT32 schedpolicy; + /* + * 0 => default sched param; + * 1 => max value for sched param; + * -1 => min value for sched param + */ + INT32 schedparam; + /* + * 0 => default contension scope; + * 1 => alternative contension scope + */ + INT32 altscope; + + /* Stack parameters */ + /* 0 => system manages the stack; 1 => stack is provided */ + INT32 altstack; + /* + * 0 => default guardsize; + * 1=> guardsize is 0; + * 2=> guard is 1 page + * -- this setting only affect system stacks (not user's). + */ + INT32 guard; + /* + * 0 => default stack size; + * 1 => stack size specified (min value) + * -- ignored when stack is provided + */ + INT32 altsize; + + /* Additionnal information */ + /* object description */ + char *descr; + /* Stores the stack start when an alternate stack is required */ + void *bottom; + /* + * This thread creation is expected to: + * 0 => succeed; 1 => fail; 2 => unknown + */ + INT32 result; + /* + * This semaphore is used to signal the end of + * the detached threads execution + */ + sem_t sem; +} __scenario; + +#define NSCENAR 10 // (sizeof(scenarii)/sizeof(scenarii[0])) + +extern __scenario g_scenarii[]; + +extern pthread_key_t g_key; +extern pthread_key_t g_key1; +extern pthread_key_t g_key2; +extern pthread_key_t g_pthreadKeyTest[PTHREAD_KEY_NUM]; +extern pthread_t g_newTh; +extern pthread_t g_newTh2; +extern UINT32 g_taskMaxNum; +extern pthread_once_t g_onceControl; +extern pthread_cond_t g_pthreadCondTest1; +extern pthread_mutex_t g_pthreadMutexTest1; +extern pthread_mutex_t g_pthreadMutexTest2; +extern INT32 g_startNum; +extern INT32 g_wakenNum; +extern INT32 g_t1Start; +extern INT32 g_signaled; +extern INT32 g_wokenUp; +extern INT32 g_lowDone; +extern INT32 g_pthreadSem; +extern INT32 g_pthreadScopeValue; +extern INT32 g_pthreadSchedInherit; +extern INT32 g_pthreadSchedPolicy; + +extern sem_t g_pthreadSem1; +extern sem_t g_pthreadSem2; + +extern pthread_t g_pthreadTestTh; + +extern INT32 g_iCunitErrCode; +extern INT32 g_iCunitErrLineNo; + +#ifdef LOSCFG_AARCH64 +#define PTHREAD_STACK_MIN_TEST (PTHREAD_STACK_MIN * 3) +#else +#define PTHREAD_STACK_MIN_TEST PTHREAD_STACK_MIN +#endif + +extern pthread_t g_Test_new_th; + +struct testdata { + pthread_mutex_t mutex; + pthread_cond_t cond; +}; +extern struct testdata g_td; + +extern int map_errno(UINT32 err); +extern void posix_signal_start(void); + +VOID ScenarInit(VOID); +VOID ScenarFini(VOID); +pthread_t TestPthreadSelf(void); + +extern UINT32 PosixPthreadInit(pthread_attr_t *attr, INT32 pri); + +#if defined(LOSCFG_USER_TEST_SMOKE) +VOID ItPosixPthread003(VOID); +VOID ItPosixPthread004(VOID); +VOID ItPosixPthread005(VOID); +VOID ItPosixPthread006(VOID); +VOID IT_POSIX_PTHREAD_009(VOID); +VOID ItPosixPthread018(VOID); +VOID ItPosixPthread019(VOID); +VOID ItPosixPthread020(VOID); +VOID ItPosixPthread021(VOID); +VOID ItPosixPthread022(VOID); +#endif + +#if defined(LOSCFG_USER_TEST_FULL) +VOID ItPosixPthread001(VOID); +VOID ItPosixPthread002(VOID); +VOID ItPosixPthread007(VOID); +VOID IT_POSIX_PTHREAD_008(VOID); +VOID ItPosixPthread010(VOID); +VOID ItPosixPthread011(VOID); +VOID ItPosixPthread013(VOID); +VOID ItPosixPthread023(VOID); +VOID ItPosixPthread025(VOID); +VOID ItPosixPthread026(VOID); +VOID ItPosixPthread027(VOID); +VOID ItPosixPthread028(VOID); +VOID ItPosixPthread029(VOID); +VOID ItPosixPthread030(VOID); +VOID ItPosixPthread031(VOID); +VOID IT_POSIX_PTHREAD_032(VOID); +VOID IT_POSIX_PTHREAD_033(VOID); +VOID ItPosixPthread034(VOID); +VOID ItPosixPthread035(VOID); +VOID ItPosixPthread039(VOID); +VOID ItPosixPthread040(VOID); +VOID IT_POSIX_PTHREAD_041(VOID); +VOID ItPosixPthread042(VOID); +VOID ItPosixPthread044(VOID); +VOID ItPosixPthread045(VOID); +VOID ItPosixPthread046(VOID); +VOID IT_POSIX_PTHREAD_047(VOID); +VOID IT_POSIX_PTHREAD_048(VOID); +VOID IT_POSIX_PTHREAD_049(VOID); +VOID IT_POSIX_PTHREAD_050(VOID); +VOID ItPosixPthread051(VOID); +VOID ItPosixPthread052(VOID); +VOID ItPosixPthread053(VOID); +VOID ItPosixPthread054(VOID); +VOID ItPosixPthread055(VOID); +VOID IT_POSIX_PTHREAD_056(VOID); +VOID ItPosixPthread057(VOID); +VOID IT_POSIX_PTHREAD_058(VOID); +VOID ItPosixPthread059(VOID); +VOID ItPosixPthread060(VOID); +VOID ItPosixPthread061(VOID); +VOID ItPosixPthread062(VOID); +VOID ItPosixPthread063(VOID); +VOID ItPosixPthread064(VOID); +VOID ItPosixPthread066(VOID); +VOID IT_POSIX_PTHREAD_068(VOID); +VOID ItPosixPthread069(VOID); +VOID ItPosixPthread070(VOID); +VOID ItPosixPthread071(VOID); +VOID ItPosixPthread072(VOID); +VOID ItPosixPthread073(VOID); +VOID ItPosixPthread074(VOID); +VOID IT_POSIX_PTHREAD_075(VOID); +VOID ItPosixPthread078(VOID); +VOID ItPosixPthread079(VOID); +VOID ItPosixPthread080(VOID); +VOID ItPosixPthread081(VOID); +VOID ItPosixPthread082(VOID); +VOID ItPosixPthread083(VOID); +VOID ItPosixPthread084(VOID); +VOID ItPosixPthread085(VOID); +VOID ItPosixPthread087(VOID); +VOID ItPosixPthread088(VOID); +VOID ItPosixPthread089(VOID); +VOID ItPosixPthread090(VOID); +VOID ItPosixPthread091(VOID); +VOID ItPosixPthread092(VOID); +VOID ItPosixPthread094(VOID); +VOID ItPosixPthread095(VOID); +VOID IT_POSIX_PTHREAD_098(VOID); +VOID IT_POSIX_PTHREAD_101(VOID); +VOID IT_POSIX_PTHREAD_102(VOID); +VOID IT_POSIX_PTHREAD_103(VOID); +VOID IT_POSIX_PTHREAD_105(VOID); +VOID ItPosixPthread106(VOID); +VOID ItPosixPthread107(VOID); +VOID IT_POSIX_PTHREAD_108(VOID); +VOID IT_POSIX_PTHREAD_110(VOID); +VOID IT_POSIX_PTHREAD_112(VOID); +VOID ItPosixPthread116(VOID); +VOID ItPosixPthread121(VOID); +VOID ItPosixPthread123(VOID); +VOID ItPosixPthread124(VOID); +VOID ItPosixPthread125(VOID); +VOID ItPosixPthread127(VOID); +VOID IT_POSIX_PTHREAD_128(VOID); +VOID ItPosixPthread129(VOID); +VOID ItPosixPthread132(VOID); +VOID ItPosixPthread133(VOID); +VOID ItPosixPthread134(VOID); +VOID ItPosixPthread136(VOID); +VOID ItPosixPthread138(VOID); +VOID ItPosixPthread141(VOID); +VOID ItPosixPthread142(VOID); +VOID ItPosixPthread144(VOID); +VOID IT_POSIX_PTHREAD_150(VOID); +VOID ItPosixPthread152(VOID); +VOID ItPosixPthread154(VOID); +VOID ItPosixPthread166(VOID); +VOID ItPosixPthread167(VOID); +VOID ItPosixPthread173(VOID); +VOID ItPosixPthread175(VOID); +VOID ItPosixPthread176(VOID); +VOID ItPosixPthread177(VOID); +VOID ItPosixPthread182(VOID); +VOID ItPosixPthread185(VOID); +VOID ItPosixPthread186(VOID); +VOID ItPosixPthread187(VOID); +VOID ItPosixPthread188(VOID); +VOID ItPosixPthread193(VOID); +VOID ItPosixPthread194(VOID); +VOID IT_POSIX_PTHREAD_197(VOID); +VOID IT_POSIX_PTHREAD_198(VOID); +VOID ItPosixPthread200(VOID); +VOID ItPosixPthread203(VOID); +VOID ItPosixPthread204(VOID); +VOID ItPosixPthread205(VOID); +VOID ItPosixPthread206(VOID); +VOID IT_POSIX_PTHREAD_208(VOID); +VOID ItPosixPthread209(VOID); +VOID IT_POSIX_PTHREAD_211(VOID); +VOID ItPosixPthread213(VOID); +VOID IT_POSIX_PTHREAD_214(VOID); +VOID IT_POSIX_PTHREAD_215(VOID); +VOID ItPosixPthread217(VOID); +VOID ItPosixPthread218(VOID); +VOID ItPosixPthread219(VOID); +VOID ItPosixPthread221(VOID); +VOID ItPosixPthread224(VOID); +VOID ItPosixPthread226(VOID); +VOID ItPosixPthread233(VOID); +VOID IT_POSIX_PTHREAD_237(VOID); +VOID ItPosixPthread238(VOID); +VOID ItPosixPthread239(VOID); +VOID ItPosixPthread240(VOID); +VOID ItPosixPthread241(VOID); +VOID IT_POSIX_PTHREAD_246(VOID); +#endif + +#if defined(LOSCFG_USER_TEST_PRESSURE) +VOID ItPosixPthread065(VOID); +#endif +#if defined(LOSCFG_USER_TEST_LLT) +VOID LltPosixPthread001(VOID); +VOID LltPosixPthread002(VOID); +VOID LltPosixPthread003(VOID); +VOID LltPosixPthread004(VOID); +VOID ItPosixPthread012(VOID); +VOID ItPosixPthread014(VOID); +VOID ItPosixPthread015(VOID); +VOID ItPosixPthread016(VOID); +VOID ItPosixPthread017(VOID); +VOID ItPosixPthread024(VOID); +VOID ItPosixPthread036(VOID); +VOID ItPosixPthread037(VOID); +VOID ItPosixPthread038(VOID); +VOID ItPosixPthread043(VOID); +VOID ItPosixPthread067(VOID); +VOID ItPosixPthread076(VOID); +VOID ItPosixPthread077(VOID); +VOID ItPosixPthread086(VOID); +VOID ItPosixPthread090(VOID); +VOID ItPosixPthread093(VOID); +VOID ItPosixPthread096(VOID); +VOID ItPosixPthread097(VOID); +VOID ItPosixPthread099(VOID); +VOID ItPosixPthread100(VOID); +VOID ItPosixPthread104(VOID); +VOID ItPosixPthread109(VOID); +VOID ItPosixPthread111(VOID); +VOID ItPosixPthread113(VOID); +VOID ItPosixPthread114(VOID); +VOID ItPosixPthread115(VOID); +VOID ItPosixPthread169(VOID); +VOID ItPosixPthread170(VOID); +VOID ItPosixPthread172(VOID); +VOID ItPosixPthread179(VOID); +VOID ItPosixPthread180(VOID); +VOID ItPosixPthread181(VOID); +VOID ItPosixPthread184(VOID); +VOID ItPosixPthread190(VOID); +VOID ItPosixPthread191(VOID); +VOID ItPosixPthread199(VOID); +VOID ItPosixPthread201(VOID); +VOID ItPosixPthread202(VOID); +#endif + +#endif /* _IT_POSIX_PTHREAD_H */ diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/config.gni b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/config.gni new file mode 100644 index 00000000..d09b57ad --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/config.gni @@ -0,0 +1,156 @@ +# Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//build/lite/config/test.gni") +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +libc_posix_pthread_include_dirs = [ "$TEST_UNITTEST_DIR/libc/posix/pthread" ] + +libc_posix_pthread_sources_entry = + [ "$TEST_UNITTEST_DIR/libc/posix/pthread/posix_pthread_test.cpp" ] + +libc_posix_pthread_sources_smoke = [ + "$TEST_UNITTEST_DIR/libc/posix/pthread/smoke/It_posix_pthread_003.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/smoke/It_posix_pthread_004.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/smoke/It_posix_pthread_005.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/smoke/It_posix_pthread_006.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/smoke/It_posix_pthread_018.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/smoke/It_posix_pthread_019.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/smoke/It_posix_pthread_020.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/smoke/It_posix_pthread_021.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/smoke/It_posix_pthread_022.cpp", +] + +libc_posix_pthread_sources_full = [ + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_001.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_002.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_007.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_010.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_011.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_013.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_023.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_025.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_026.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_027.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_028.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_029.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_030.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_031.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_034.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_035.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_039.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_040.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_042.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_044.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_045.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_046.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_051.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_052.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_053.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_054.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_055.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_057.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_059.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_060.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_061.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_062.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_063.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_064.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_066.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_069.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_070.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_071.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_072.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_073.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_074.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_078.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_079.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_080.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_081.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_082.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_083.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_084.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_085.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_087.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_088.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_089.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_090.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_091.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_092.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_094.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_095.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_106.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_107.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_116.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_123.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_124.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_125.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_127.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_129.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_132.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_133.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_134.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_136.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_138.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_141.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_142.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_144.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_152.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_154.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_166.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_167.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_173.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_175.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_176.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_177.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_182.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_185.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_186.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_187.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_188.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_193.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_194.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_200.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_203.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_204.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_205.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_206.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_209.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_213.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_217.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_218.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_219.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_221.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_224.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_226.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_233.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_238.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_239.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_240.cpp", + "$TEST_UNITTEST_DIR/libc/posix/pthread/full/It_posix_pthread_241.cpp", +] diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_001.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_001.cpp new file mode 100644 index 00000000..09ede149 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_001.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static UINT32 Testcase(VOID) +{ +#ifndef PTHREAD_CANCEL_ASYNCHRONOUS +#error PTHREAD_CANCEL_ASYNCHRONOUS not defined +#endif + +#ifndef PTHREAD_CANCEL_ENABLE +#error PTHREAD_CANCEL_ENABLE not defined +#endif + +#ifndef PTHREAD_CANCEL_DEFERRED +#error PTHREAD_CANCEL_DEFERRED not defined +#endif + +#ifndef PTHREAD_CANCEL_DISABLE +#error PTHREAD_CANCEL_DISABLE not defined +#endif + +#ifndef PTHREAD_CANCELED +#error PTHREAD_CANCELED not defined +#endif + +#ifndef PTHREAD_CREATE_DETACHED +#error PTHREAD_CREATE_DETACHED not defined +#endif + +#ifndef PTHREAD_CREATE_JOINABLE +#error PTHREAD_CREATE_JOINABLE not defined +#endif + +#ifndef PTHREAD_EXPLICIT_SCHED +#error PTHREAD_EXPLICIT_SCHED not defined +#endif + +#ifndef PTHREAD_INHERIT_SCHED +#error PTHREAD_INHERIT_SCHED not defined +#endif + +#ifndef PTHREAD_ONCE_INIT +#error PTHREAD_ONCE_INIT not defined +#endif + + +#ifndef PTHREAD_PROCESS_SHARED +#error PTHREAD_PROCESS_SHARED not defined +#endif + +#ifndef PTHREAD_PROCESS_PRIVATE +#error PTHREAD_PROCESS_PRIVATE not defined +#endif + +#ifndef PTHREAD_COND_INITIALIZER +#error PTHREAD_COND_INTIALIZER not defined +#endif + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread001(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_001", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_002.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_002.cpp new file mode 100644 index 00000000..0d487291 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_002.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static UINT32 Testcase(VOID) +{ + pthread_attr_t dummy1; + pthread_key_t dummy6; + pthread_mutex_t dummy7; + pthread_mutexattr_t dummy8; + pthread_once_t dummy9; + pthread_t dummy13; + pthread_once_t dummy = PTHREAD_ONCE_INIT; + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread002(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_002", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_007.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_007.cpp new file mode 100644 index 00000000..2ebc59ed --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_007.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(void *argument) +{ + g_testCount++; + + return argument; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + pthread_attr_t attr; + UINT32 ret; + UINT32 uwint = 8; + char cc = 'a'; + char str[5] = "abcd"; + + UINTPTR uwtemp; + + g_testCount = 0; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newTh, NULL, pthread_f01, (void *)&uwint); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + LosTaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = pthread_join(newTh, (void **)&uwtemp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(*((UINT32 *)uwtemp), 8, *((UINT32 *)uwtemp)); + + ret = pthread_create(&newTh, &attr, NULL, (void *)8); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_create(&newTh, &attr, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LosTaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); + + ret = pthread_join(newTh, (void **)&uwtemp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL((UINT32)uwtemp, 0, (UINT32)uwtemp); + + ret = pthread_create(&newTh, &attr, pthread_f01, (void *)&cc); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LosTaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); + + ret = pthread_join(newTh, (void **)&uwtemp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(*((char *)uwtemp), 97, *((char *)uwtemp)); + + ret = pthread_create(&newTh, &attr, pthread_f01, (void *)str); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LosTaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 4, g_testCount); + + ret = pthread_join(newTh, (void **)&uwtemp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_STRING_EQUAL((char *)uwtemp, "abcd", (char *)uwtemp); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread007(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_007", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_010.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_010.cpp new file mode 100644 index 00000000..bad03247 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_010.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(void *argument) +{ + g_testCount = pthread_self(); + + pthread_exit(static_cast(8)); // 8: exit value for testing + + return static_cast(9); // 9: return value for testing +} +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + UINT32 ret; + UINTPTR uwtemp = 1; + + g_testCount = 0; + ret = pthread_create(&newTh, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LosTaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, newTh, g_testCount); + + ret = pthread_join(newTh, (void **)&uwtemp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(uwtemp, 8, uwtemp); + + uwtemp = TestPthreadSelf(); + ret = pthread_equal(uwtemp, g_testCount); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_equal(newTh, g_testCount); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + + ret = pthread_equal(0, 0); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + + ret = pthread_equal(0, 1); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread010(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_010", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_011.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_011.cpp new file mode 100644 index 00000000..68f50c75 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_011.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static UINT32 Testcase(VOID) +{ + pthread_attr_t attr; + UINT32 ret; + int detachstate; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_setdetachstate(&attr, 3); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_getdetachstate(&attr, &detachstate); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(detachstate, PTHREAD_CREATE_DETACHED, detachstate); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread011(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_011", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_013.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_013.cpp new file mode 100644 index 00000000..afb15daf --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_013.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static UINT32 Testcase(VOID) +{ + pthread_attr_t attr; + UINT32 ret; + int inherit; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED + 1); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_getinheritsched(&attr, &inherit); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(inherit, PTHREAD_EXPLICIT_SCHED, inherit); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread013(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_013", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_023.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_023.cpp new file mode 100644 index 00000000..b511ab00 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_023.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static void PthreadCleanF01(void *arg) +{ + ICUNIT_ASSERT_EQUAL_VOID((int)arg, 8, (int)arg); + g_testCount++; + + return; +} + +static VOID *pthread_f01(void *argument) +{ + g_testCount++; + + pthread_cleanup_push(PthreadCleanF01, static_cast(8)); // 8:arg that routine is called with + if (argument) { + return static_cast(8); // 8: return value for testing if argument is not NULL + } + pthread_cleanup_pop(0); + + return static_cast(9); // 9: return value for testing +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + + UINT32 ret; + UINTPTR uwtemp = 1; + + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + LosTaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = pthread_join(newTh, (void **)&uwtemp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(uwtemp, 9, uwtemp); + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread023(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_023", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_025.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_025.cpp new file mode 100644 index 00000000..d95411ec --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_025.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static void PthreadCleanF01(void *arg) +{ + ICUNIT_ASSERT_EQUAL_VOID((int)arg, 8, (int)arg); + g_testCount++; + + return; +} + +static VOID *pthread_f01(void *argument) +{ + g_testCount++; + + pthread_cleanup_push(PthreadCleanF01, static_cast(8)); // 8: arg that routine is called with + pthread_exit(static_cast(8)); // 8: exit value for testing + pthread_cleanup_pop(1); + + return static_cast(9); // 9: return value for testing +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + + UINT32 ret; + UINTPTR uwtemp = 1; + + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + LosTaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); + + ret = pthread_join(newTh, (void **)&uwtemp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(uwtemp, 8, uwtemp); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread025(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_025", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_026.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_026.cpp new file mode 100644 index 00000000..d697f00e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_026.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static void PthreadCleanF01(void *arg) +{ + ICUNIT_ASSERT_EQUAL_VOID((int)arg, 8, (int)arg); + g_testCount++; + + return; +} + +static VOID *pthread_f01(void *argument) +{ + g_testCount++; + LosTaskDelay(5); + + pthread_cleanup_push(PthreadCleanF01, static_cast(8)); // 8: arg that routine is called with + pthread_testcancel(); + pthread_cleanup_pop(1); + + return static_cast(9); // 9: return value for testing +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + + UINT32 ret; + UINTPTR uwtemp = 1; + + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + LosTaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = pthread_cancel(newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newTh, (void **)&uwtemp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(uwtemp, (UINTPTR)PTHREAD_CANCELED, uwtemp); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread026(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_026", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_027.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_027.cpp new file mode 100644 index 00000000..672af915 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_027.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static void PthreadCleanF01(void *arg) +{ + if (g_testCount == 1) + ICUNIT_ASSERT_EQUAL_VOID((int)arg, 8, (int)arg); + if (g_testCount == 2) + ICUNIT_ASSERT_EQUAL_VOID((int)arg, 9, (int)arg); + + g_testCount++; + + return; +} + +static VOID *pthread_f01(void *argument) +{ + g_testCount++; + + pthread_cleanup_push(PthreadCleanF01, static_cast(9)); // 9: arg that routine is called with + pthread_cleanup_push(PthreadCleanF01, static_cast(8)); // 8: arg that routine is called with + pthread_exit(static_cast(8)); // 8: exit value for testing + pthread_cleanup_pop(1); + pthread_cleanup_pop(1); + + return static_cast(9); // 9: return value for testing +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + + UINT32 ret; + UINTPTR uwtemp = 1; + + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + LosTaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); + + ret = pthread_join(newTh, (void **)&uwtemp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(uwtemp, 8, uwtemp); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread027(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_027", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_028.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_028.cpp new file mode 100644 index 00000000..ec9d9b20 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_028.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(void *argument) +{ + g_testCount++; + + return static_cast(9); // 9: return value for testing +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + + UINT32 ret; + UINTPTR uwtemp = 1; + + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + LosTaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = pthread_join(newTh, (void **)&uwtemp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(uwtemp, 9, uwtemp); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread028(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_028", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_029.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_029.cpp new file mode 100644 index 00000000..fa868f16 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_029.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(void *argument) +{ + g_testCount++; + + pthread_exit(static_cast(8)); // 8: exit value for testing + return static_cast(9); // 9: return value for testing +} +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + + UINT32 ret; + UINTPTR uwtemp = 1; + + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + LosTaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = pthread_join(newTh, (void **)&uwtemp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(uwtemp, 8, uwtemp); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread029(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_029", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_030.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_030.cpp new file mode 100644 index 00000000..e068b11a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_030.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(void *argument) +{ + g_testCount++; + LosTaskDelay(2); + + pthread_testcancel(); + g_testCount++; + return static_cast(9); // 9: return value for testing +} +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + + UINT32 ret; + UINTPTR uwtemp = 1; + + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + LosTaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = pthread_cancel(newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newTh, (void **)&uwtemp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(uwtemp, (UINTPTR)PTHREAD_CANCELED, uwtemp); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread030(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_030", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_031.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_031.cpp new file mode 100644 index 00000000..bed89e0c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_031.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(void *argument) +{ + UINT32 ret; + + g_testCount++; + + ret = pthread_join(g_newTh, NULL); + ICUNIT_GOTO_NOT_EQUAL(ret, 0, ret, EXIT); +EXIT: + return static_cast(9); // 9: return value for testing +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINTPTR uwtemp = 1; + + g_testCount = 0; + + ret = pthread_create(&g_newTh, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + LosTaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = pthread_join(g_newTh, (void **)&uwtemp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(uwtemp, 9, uwtemp); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread031(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_031", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_034.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_034.cpp new file mode 100644 index 00000000..4715817d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_034.cpp @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(void *argument) +{ + UINT32 i, j; + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + + + for (i = 0, j = 0; i < 2000; i++) { + j++; + } + + g_testCount++; + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); +EXIT: + return static_cast(9); // 9: return value for testing +} + +static VOID *pthread_f02(void *argument) +{ + UINT32 i, j; + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + + for (i = 0, j = 0; i < 2000; i++) { + j++; + } + + g_testCount++; + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); +EXIT: + return static_cast(8); // 8: return value for testing +} + +static VOID *PthreadF03(void *argument) +{ + UINT32 i, j; + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); + + + for (i = 0, j = 0; i < 2000; i++) { + j++; + } + + g_testCount++; + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); + +EXIT: + return static_cast(7); // 7: return value for testing +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh, newTh2, newTh3; + + UINT32 ret; + UINTPTR uwtemp = 1; + + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newTh2, NULL, pthread_f02, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newTh3, NULL, PthreadF03, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LosTaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); + + ret = pthread_join(newTh, (void **)&uwtemp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newTh2, (void **)&uwtemp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newTh3, (void **)&uwtemp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread034(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_034", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_035.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_035.cpp new file mode 100644 index 00000000..0269a7a6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_035.cpp @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" +static volatile int g_testCnt1; + +static VOID *pthread_f01(void *argument) +{ + UINT32 j = 0; + INT32 value; + ICUNIT_GOTO_EQUAL(g_testCnt1, 0, g_testCnt1, EXIT); + g_testCnt1++; + + while (g_testCnt1 != 3) { + j++; + j = j * 2 - 4; + j = 2001 + 4001 * 1 - 2001; + usleep(100); + } + g_testCnt1++; + ICUNIT_GOTO_EQUAL(g_testCnt1, 4, g_testCnt1, EXIT); +EXIT: + return reinterpret_cast(9); // 9: return value for testing +} + +static VOID *pthread_f02(void *argument) +{ + UINT32 j = 0; + INT32 value; + ICUNIT_GOTO_EQUAL(g_testCnt1, 1, g_testCnt1, EXIT); + g_testCnt1++; + + while (g_testCnt1 != 4) { + j++; + j = j * 2 - 4; + j = 2001 + 4001 * 1 - 2001; + usleep(100); + } + + g_testCnt1++; + ICUNIT_GOTO_EQUAL(g_testCnt1, 5, g_testCnt1, EXIT); +EXIT: + return reinterpret_cast(8); // 8:return value for testing +} + +static VOID *PthreadF03(void *argument) +{ + UINT32 j = 0; + INT32 value; + ICUNIT_GOTO_EQUAL(g_testCnt1, 2, g_testCnt1, EXIT); + g_testCnt1++; + + while (g_testCnt1 != 5) { + j++; + j = j * 2 - 4; + j = 2001 + 4001 * 1 - 2001; + usleep(10); + } + + g_testCnt1++; + ICUNIT_GOTO_EQUAL(g_testCnt1, 6, g_testCnt1, EXIT); + +EXIT: + return reinterpret_cast(7); // 7: return value for testing +} +static UINT32 Testcase(VOID) +{ + pthread_t newTh, newTh2, newTh3; + + UINT32 ret; + UINTPTR uwtemp = 1; + + g_testCnt1 = 0; + + ret = pthread_create(&newTh, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newTh2, NULL, pthread_f02, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newTh3, NULL, PthreadF03, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + while (g_testCnt1 < 6) { // 6: threshold for calling sleep + sleep(1); + } + + ICUNIT_ASSERT_EQUAL(g_testCnt1, 6, g_testCnt1); + + ret = pthread_join(newTh, (void **)&uwtemp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newTh2, (void **)&uwtemp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newTh3, (void **)&uwtemp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread035(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_035", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_039.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_039.cpp new file mode 100644 index 00000000..82b9d593 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_039.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *PthreadF01(void *argument) +{ + g_testCount++; + LosTaskDelay(2); + pthread_testcancel(); + g_testCount++; + return static_cast(9); // 9: return value for testing +} + +static UINT32 Testcase(VOID) +{ + INT32 count = PTHREAD_EXISTED_NUM; + pthread_t newTh; + UINT32 ret; + UINT32 index; + + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, PthreadF01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + LosTaskDelay(1); + + ret = pthread_cancel(newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_detach(newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + LosTaskDelay(2); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + + ret = pthread_create(&newTh, NULL, PthreadF01, + NULL); // the detach will release resources the next time when creates one pthread + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + LosTaskDelay(2); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread039(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_039", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_040.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_040.cpp new file mode 100644 index 00000000..55ee8bc0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_040.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(void *argument) +{ + g_testCount++; + LosTaskDelay(2); + g_testCount++; + + return static_cast(9); // 9: return value for testing +} +static UINT32 Testcase(VOID) +{ + INT32 count = PTHREAD_EXISTED_NUM; + pthread_t newTh; + UINT32 ret; + UINT32 index; + + g_testCount = 0; + + + ret = pthread_create(&newTh, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + LosTaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = pthread_detach(newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + + LosTaskDelay(2); + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); + + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread040(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_040", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_042.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_042.cpp new file mode 100644 index 00000000..08aa7c36 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_042.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(void *argument) +{ + g_testCount++; + LosTaskDelay(2); + g_testCount++; + + return static_cast(9); // 9: return value for testing +} +static UINT32 Testcase(VOID) +{ + INT32 count = PTHREAD_EXISTED_NUM; + pthread_t newTh; + UINT32 ret; + UINT32 index; + pthread_attr_t attr; + int detachstate; + + g_testCount = 0; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_getdetachstate(&attr, &detachstate); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(detachstate, PTHREAD_CREATE_JOINABLE, detachstate); + + ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newTh, &attr, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LosTaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + + ret = pthread_detach(newTh); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + + LosTaskDelay(3); + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); + + ret = pthread_attr_getdetachstate(&attr, &detachstate); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(detachstate, PTHREAD_CREATE_DETACHED, detachstate); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread042(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_042", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_044.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_044.cpp new file mode 100644 index 00000000..420b723d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_044.cpp @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f02(void *argument) +{ + UINT32 ret; + INT32 policy; + struct sched_param param; + + LosTaskDelay(2); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + g_testCount++; + + ret = pthread_getschedparam(pthread_self(), &policy, ¶m); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ICUNIT_GOTO_EQUAL(policy, SCHED_RR, policy, EXIT); // + ICUNIT_GOTO_EQUAL(param.sched_priority, 3, param.sched_priority, EXIT); + +EXIT: + return static_cast(9); // 9: return value for testing +} + +static VOID *pthread_f01(void *argument) +{ + pthread_t newTh; + UINT32 ret; + INT32 policy; + pthread_attr_t attr; + struct sched_param param; + + g_testCount++; + + ret = pthread_getschedparam(pthread_self(), &policy, ¶m); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ICUNIT_GOTO_EQUAL(policy, SCHED_RR, policy, EXIT); // + ICUNIT_GOTO_EQUAL(param.sched_priority, 4, param.sched_priority, EXIT); + + ret = pthread_attr_init(&attr); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_create(&newTh, &attr, pthread_f02, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + param.sched_priority = 3; + ret = pthread_setschedparam(newTh, SCHED_RR, ¶m); // + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_detach(newTh); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + LosTaskDelay(4); + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); + g_testCount++; + ret = pthread_attr_destroy(&attr); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); +EXIT: + return static_cast(9); // 9: return value for testing +} +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + UINT32 ret; + pthread_attr_t attr; + int inherit; + int policy; + struct sched_param param; + + g_testCount = 0; + + ret = pthread_getschedparam(pthread_self(), &policy, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(policy, SCHED_RR, policy); // + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_setschedpolicy(&attr, SCHED_RR); // + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + param.sched_priority = 4; + ret = pthread_attr_setschedparam(&attr, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_setscope(&attr, PTHREAD_SCOPE_PROCESS); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newTh, &attr, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LosTaskDelay(6); + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_getinheritsched(&attr, &inherit); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(inherit, PTHREAD_EXPLICIT_SCHED, inherit); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread044(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_044", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_045.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_045.cpp new file mode 100644 index 00000000..f6a32df4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_045.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(void *argument) +{ + g_testCount++; + printf("!!!!!!!!!\n"); + printf("%x\n", TASK_STACK_SIZE_TEST); + + g_testCount++; + +EXIT: + return static_cast(9); // 9: return value for testing +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + int ret; + pthread_attr_t attr; + size_t stacksize; + size_t stacksize2; + + g_testCount = 0; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + stacksize = TASK_STACK_SIZE_TEST; + ret = pthread_attr_setstacksize(&attr, stacksize); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newTh, &attr, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = LosTaskDelay(10); + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); + + ret = pthread_join(newTh, NULL); + + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_getstacksize(&attr, &stacksize2); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(stacksize2, TASK_STACK_SIZE_TEST, stacksize2); + + pthread_attr_setstacksize(&attr, LOS_TASK_MIN_STACK_SIZE - 2 * sizeof(UINTPTR)); + ret = pthread_create(&newTh, &attr, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread045(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_045", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_046.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_046.cpp new file mode 100644 index 00000000..06998e72 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_046.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(void *argument) +{ + g_testCount++; + + g_testCount++; + +EXIT: + return static_cast(9); // 9: return value for testing +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + UINT32 ret; + pthread_attr_t attr; + size_t stacksize; + size_t stacksize2; + + g_testCount = 0; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + stacksize = PTHREAD_STACK_MIN_TEST + 1; + ret = pthread_attr_setstacksize(&attr, stacksize); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newTh, &attr, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + LosTaskDelay(10); + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_getstacksize(&attr, &stacksize2); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(stacksize2, PTHREAD_STACK_MIN_TEST + 1, stacksize2); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread046(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_046", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_051.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_051.cpp new file mode 100644 index 00000000..97a9c0c3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_051.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static void PthreadOnceF01(void) +{ + printf("enter pthread_once_01\n"); + g_testCount++; +} + +static VOID *pthread_f01(void *argument) +{ + UINT32 ret; + + g_testCount++; + + LosTaskDelay(2); + ret = pthread_once(&g_onceControl, PthreadOnceF01); + pthread_testcancel(); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // not reachable + +EXIT: + return static_cast(9); // 9: return value for testing +} +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + UINT32 ret; + UINTPTR temp; + + g_testCount = 0; + g_onceControl = PTHREAD_ONCE_INIT; + + ret = pthread_create(&newTh, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LosTaskDelay(1); + + ret = pthread_cancel(newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + LosTaskDelay(10); + + ICUNIT_ASSERT_EQUAL(g_onceControl, 2, g_onceControl); + ret = pthread_once(&g_onceControl, PthreadOnceF01); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); + + ret = pthread_join(newTh, (void **)&temp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(temp, (UINTPTR)PTHREAD_CANCELED, temp); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread051(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_051", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_052.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_052.cpp new file mode 100644 index 00000000..580564f7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_052.cpp @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(void *argument) +{ + UINT32 temp = 2; + UINT32 ret; + VOID *result; + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + g_testCount++; + + result = pthread_getspecific(g_key); + ICUNIT_GOTO_EQUAL(result, NULL, result, EXIT); + + ret = pthread_setspecific(g_key, (void *)&temp); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + LosTaskDelay(5); + + ret = *((UINT32 *)pthread_getspecific(g_key)); + ICUNIT_GOTO_EQUAL(ret, 2, ret, EXIT); + + g_testCount++; + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); +EXIT: + return static_cast(9); // 9: return value for testing +} + +static VOID *pthread_f02(void *argument) +{ + UINT32 temp = 9; + UINT32 ret; + VOID *result; + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + g_testCount++; + + result = pthread_getspecific(g_key); + ICUNIT_GOTO_EQUAL(result, NULL, result, EXIT); + + ret = pthread_setspecific(g_key, (void *)&temp); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + LosTaskDelay(10); + + ret = *((UINT32 *)pthread_getspecific(g_key)); + ICUNIT_GOTO_EQUAL(ret, 9, ret, EXIT); + + g_testCount++; + ICUNIT_GOTO_EQUAL(g_testCount, 6, g_testCount, EXIT); +EXIT: + return static_cast(8); // 8: return value for testing +} + +static VOID *PthreadF03(void *argument) +{ + char temp[10] = "abcde"; + char *temp1; + UINT32 ret; + VOID *result; + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); + g_testCount++; + + result = pthread_getspecific(g_key); + ICUNIT_GOTO_EQUAL(result, NULL, result, EXIT); + + ret = pthread_setspecific(g_key, (void *)temp); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + LosTaskDelay(20); + + temp1 = (char *)pthread_getspecific(g_key); + ICUNIT_GOTO_STRING_EQUAL(temp1, "abcde", temp1, EXIT); + + g_testCount++; + ICUNIT_GOTO_EQUAL(g_testCount, 8, g_testCount, EXIT); + +EXIT: + return static_cast(7); // 7: return value for testing +} + +static void PthreadKeyF01(void *threadLog) +{ + g_testCount++; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh, newTh2, newTh3; + UINT32 ret; + UINTPTR uwtemp = 1; + + g_testCount = 0; + + ret = pthread_key_create(&g_key, PthreadKeyF01); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newTh, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newTh2, NULL, pthread_f02, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newTh3, NULL, PthreadF03, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LosTaskDelay(30); + ICUNIT_ASSERT_EQUAL(g_testCount, 9, g_testCount); + + ret = pthread_join(newTh, (void **)&uwtemp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newTh2, (void **)&uwtemp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newTh3, (void **)&uwtemp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_key_delete(g_key); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread052(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_052", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_053.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_053.cpp new file mode 100644 index 00000000..deef9174 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_053.cpp @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(void *argument) +{ + UINT32 temp = 200; + UINT32 temp1 = 20000; + char str[11] = "1234567890"; + UINT32 ret; + VOID *result; + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + g_testCount++; + + result = pthread_getspecific(g_key); + ICUNIT_GOTO_EQUAL(result, NULL, result, EXIT); + + result = pthread_getspecific(g_key1); + ICUNIT_GOTO_EQUAL(result, NULL, result, EXIT); + + result = pthread_getspecific(g_key2); + ICUNIT_GOTO_EQUAL(result, NULL, result, EXIT); + + ret = pthread_setspecific(g_key, (void *)&temp); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_setspecific(g_key1, (void *)&temp1); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_setspecific(g_key2, (void *)str); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = *((UINT32 *)pthread_getspecific(g_key)); + ICUNIT_GOTO_EQUAL(ret, 200, ret, EXIT); + + ret = *((UINT32 *)pthread_getspecific(g_key1)); + ICUNIT_GOTO_EQUAL(ret, 20000, ret, EXIT); + + result = pthread_getspecific(g_key2); + ICUNIT_GOTO_STRING_EQUAL((char *)result, "1234567890", (char *)result, EXIT); + + g_testCount++; + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); +EXIT: + return static_cast(9); // 9: return value for testing +} + +static VOID *pthread_f02(void *argument) +{ + UINT32 temp = 100; + UINT32 temp1 = 10000; + char str[11] = "abcdefghjk"; + UINT32 ret; + VOID *result; + + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); + g_testCount++; + + result = pthread_getspecific(g_key); + ICUNIT_GOTO_EQUAL(result, NULL, result, EXIT); + + result = pthread_getspecific(g_key1); + ICUNIT_GOTO_EQUAL(result, NULL, result, EXIT); + + result = pthread_getspecific(g_key2); + ICUNIT_GOTO_EQUAL(result, NULL, result, EXIT); + + ret = pthread_setspecific(g_key, (void *)&temp); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_setspecific(g_key1, (void *)&temp1); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_setspecific(g_key2, (void *)str); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = *((UINT32 *)pthread_getspecific(g_key)); + ICUNIT_GOTO_EQUAL(ret, 100, ret, EXIT); + + ret = *((UINT32 *)pthread_getspecific(g_key1)); + ICUNIT_GOTO_EQUAL(ret, 10000, ret, EXIT); + + result = pthread_getspecific(g_key2); + ICUNIT_GOTO_STRING_EQUAL((char *)result, "abcdefghjk", (char *)result, EXIT); + + g_testCount++; + ICUNIT_GOTO_EQUAL(g_testCount, 7, g_testCount, EXIT); +EXIT: + return static_cast(8); // 8: return value for testing +} +static void PthreadKeyF01(void *threadLog) +{ + g_testCount++; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh, newTh2; + UINT32 ret; + UINTPTR uwtemp = 1; + VOID *result; + + g_testCount = 0; + + ret = pthread_key_create(&g_key, PthreadKeyF01); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_key_create(&g_key1, PthreadKeyF01); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_key_create(&g_key2, PthreadKeyF01); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newTh, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LosTaskDelay(20); + + ret = pthread_create(&newTh2, NULL, pthread_f02, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LosTaskDelay(20); + ICUNIT_ASSERT_EQUAL(g_testCount, 10, g_testCount); + + result = pthread_getspecific(g_key); + ICUNIT_ASSERT_EQUAL(result, NULL, result); + + result = pthread_getspecific(g_key1); + ICUNIT_ASSERT_EQUAL(result, NULL, result); + + result = pthread_getspecific(g_key2); + ICUNIT_ASSERT_EQUAL(result, NULL, result); + + ret = pthread_join(newTh, (void **)&uwtemp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newTh2, (void **)&uwtemp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_key_delete(g_key); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_key_delete(g_key1); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_key_delete(g_key2); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread053(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_053", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_054.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_054.cpp new file mode 100644 index 00000000..0c202abe --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_054.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(void *argument) +{ + UINT32 temp = 2; + UINT32 ret; + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + g_testCount++; + + ret = pthread_setspecific(g_key, (void *)&temp); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + LosTaskDelay(1); + + ret = *((UINT32 *)pthread_getspecific(g_key)); + ICUNIT_GOTO_EQUAL(ret, 2, ret, EXIT); + + g_testCount++; + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); + + pthread_exit(static_cast(7)); // 7: exit value for testing +EXIT: + return static_cast(9); // 9: return value for testing +} + +static void PthreadKeyF01(void *threadLog) +{ + g_testCount++; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + UINT32 ret; + UINTPTR uwtemp = 1; + + g_testCount = 0; + + ret = pthread_key_create(&g_key, PthreadKeyF01); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newTh, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LosTaskDelay(2); + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); + + ret = pthread_join(newTh, (void **)&uwtemp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_key_delete(g_key); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread054(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_054", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_055.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_055.cpp new file mode 100644 index 00000000..a0c9e68b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_055.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(void *argument) +{ + UINT32 temp = 2; + UINT32 ret; + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + g_testCount++; + + ret = pthread_setspecific(g_key, (void *)&temp); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + LosTaskDelay(1); + + ret = *((UINT32 *)pthread_getspecific(g_key)); + ICUNIT_GOTO_EQUAL(ret, 2, ret, EXIT); + + g_testCount++; + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); + + pthread_testcancel(); +EXIT: + return static_cast(9); // 9: return value for testing +} + +static void PthreadKeyF01(void *threadLog) +{ + g_testCount++; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + UINT32 ret; + UINTPTR uwtemp = 1; + + g_testCount = 0; + + ret = pthread_key_create(&g_key, PthreadKeyF01); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newTh, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LosTaskDelay(2); + ret = pthread_cancel(newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LosTaskDelay(10); + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); + + ret = pthread_join(newTh, (void **)&uwtemp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_key_delete(g_key); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread055(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_055", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_057.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_057.cpp new file mode 100644 index 00000000..83010095 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_057.cpp @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(void *argument) +{ + UINT32 ret; + int oldstate; + int i = 0; + + ICUNIT_ASSERT_EQUAL_NULL(g_testCount, 1, (void *)g_testCount); + g_testCount++; // 2 + printf("enter pthread_01\n"); + printf("count: %d\n", g_testCount); + ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate); + ICUNIT_ASSERT_EQUAL_NULL(ret, 0, (void *)ret); + ICUNIT_ASSERT_EQUAL_NULL(oldstate, PTHREAD_CANCEL_DEFERRED, (void *)oldstate); + pthread_testcancel(); + while (1) { + if (++i == 5) { + sleep(20); + } + } +} +static VOID *pthread_f02(void *argument) +{ + UINT32 ret; + int oldstate; + + ICUNIT_ASSERT_EQUAL_NULL(g_testCount, 3, (void *)g_testCount); + g_testCount++; // 4 + ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate); + ICUNIT_ASSERT_EQUAL_NULL(ret, 0, (void *)ret); + ICUNIT_ASSERT_EQUAL_NULL(oldstate, PTHREAD_CANCEL_DEFERRED, (void *)oldstate); + pthread_testcancel(); + LosTaskDelay(20); + g_testCount++; // 7 + ICUNIT_ASSERT_EQUAL_NULL(g_testCount, 7, (void *)g_testCount); +} +static VOID *PthreadF03(void *argument) +{ + UINT32 ret; + UINTPTR uwtemp = 1; + int oldstate; + + ICUNIT_ASSERT_EQUAL_NULL(g_testCount, 5, (void *)g_testCount); + g_testCount++; // 6 + printf("thread01: %#x", (UINT32)g_newTh); + pthread_cancel(g_newTh); + LosTaskDelay(12); + + ret = pthread_join(g_newTh, (void **)&uwtemp); + ICUNIT_ASSERT_EQUAL_NULL(ret, 0, (void *)ret); + ICUNIT_ASSERT_EQUAL_NULL(uwtemp, (UINTPTR)PTHREAD_CANCELED, (void *)uwtemp); + + ret = pthread_join(g_newTh2, (void **)&uwtemp); + ICUNIT_ASSERT_EQUAL_NULL(ret, 0, (void *)ret); + ICUNIT_ASSERT_EQUAL_NULL(g_testCount, 7, (void *)g_testCount); + ICUNIT_ASSERT_NOT_EQUAL_NULL(uwtemp, (UINTPTR)PTHREAD_CANCELED, (void *)uwtemp); +} +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + g_testCount = 0; + struct sched_param param = { 0 }; + int ret; + void *res = NULL; + pthread_attr_t a = { 0 }; + int curThreadPri, curThreadPolicy; + + g_testCount++; // 1 + + curThreadPri = param.sched_priority; + ret = pthread_attr_init(&a); + param.sched_priority = curThreadPri - 1; + + ret = pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + pthread_attr_setschedparam(&a, ¶m); + ret = pthread_create(&g_newTh, &a, pthread_f01, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + LosTaskDelay(10); + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); + g_testCount++; // 3 + + ret = pthread_create(&g_newTh2, &a, pthread_f02, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + LosTaskDelay(10); + ICUNIT_ASSERT_EQUAL(g_testCount, 4, g_testCount); + g_testCount++; // 5 + + ret = pthread_create(&newTh, &a, PthreadF03, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + LosTaskDelay(20); + ICUNIT_ASSERT_EQUAL(g_testCount, 7, g_testCount); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return 0; +} + +VOID ItPosixPthread057(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_057", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_059.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_059.cpp new file mode 100644 index 00000000..354be5ad --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_059.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(void *argument) +{ + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + g_testCount++; + + sleep(1); + + g_testCount++; + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); // failed, =2 + +EXIT: + return static_cast(9); // 9: return value for testing +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + UINT32 ret; + UINTPTR uwtemp = 1; + + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_cancel(newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + sleep(2); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = pthread_join(newTh, (void **)&uwtemp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(uwtemp, (UINTPTR)PTHREAD_CANCELED, uwtemp); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread059(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_059", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_060.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_060.cpp new file mode 100644 index 00000000..d55ad834 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_060.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f02(void *argument) +{ + g_testCount++; + return static_cast(8); // 8: return value for testing +} +static VOID *pthread_f01(void *argument) +{ + UINT32 ret; + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + g_testCount++; + + TestExtraTaskDelay(2); + + ret = pthread_create(&g_newTh, NULL, pthread_f02, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_join(g_newTh, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testCount++; + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + +EXIT: + return static_cast(9); // 9: return value for testing +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + UINT32 ret; + UINTPTR uwtemp = 1; + + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_cancel(newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LosTaskDelay(10); + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); + + ret = pthread_join(newTh, (void **)&uwtemp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(uwtemp, (UINTPTR)PTHREAD_CANCELED, uwtemp); + + ret = pthread_join(g_newTh, (void **)&uwtemp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(uwtemp, 8, uwtemp); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread060(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_060", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_061.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_061.cpp new file mode 100644 index 00000000..9d4d3626 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_061.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(void *argument) +{ + UINT32 ret; + sigset_t set; + int sig; + + sigemptyset(&set); + sigaddset(&set, SIGUSR1); + + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + g_testCount++; + + ret = sigwait(&set, &sig); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testCount++; + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + +EXIT: + return static_cast(9); // 9: return value for testing +} +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + UINT32 ret; + UINTPTR uwtemp = 1; + + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_cancel(newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LosTaskDelay(2); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = pthread_join(newTh, (void **)&uwtemp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(uwtemp, (UINTPTR)PTHREAD_CANCELED, uwtemp); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread061(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_061", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_062.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_062.cpp new file mode 100644 index 00000000..db359dff --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_062.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(void *argument) +{ + UINT32 ret; + sem_t *sem = (sem_t *)argument; + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + g_testCount++; + + ret = sem_wait(sem); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testCount++; + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + +EXIT: + return static_cast(9); // 9: return value for testing +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + UINT32 ret; + UINTPTR uwtemp = 1; + sem_t sem; + + g_testCount = 0; + + ret = sem_init(&sem, 0, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newTh, NULL, pthread_f01, (void *)&sem); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_cancel(newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LosTaskDelay(2); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = pthread_join(newTh, (void **)&uwtemp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(uwtemp, (UINTPTR)PTHREAD_CANCELED, uwtemp); + + ret = sem_destroy(&sem); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread062(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_062", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_063.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_063.cpp new file mode 100644 index 00000000..25126319 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_063.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(void *argument) +{ + UINT32 ret; + char msgrcd[10]; + siginfo_t newSiginfoT; + sigset_t newSigsetT2; + sigset_t newSigsetT; + struct timespec time = { (time_t)0, 2000000 }; + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + g_testCount++; + + sigemptyset(&newSigsetT2); + sigaddset(&newSigsetT2, 17); + ret = sigtimedwait(&newSigsetT2, &newSiginfoT, &time); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testCount++; + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + +EXIT: + return static_cast(9); // 9: return value for testing +} +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + UINT32 ret; + UINTPTR uwtemp = 1; + + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_cancel(newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LosTaskDelay(2); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = pthread_join(newTh, (void **)&uwtemp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(uwtemp, (UINTPTR)PTHREAD_CANCELED, uwtemp); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread063(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_063", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_064.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_064.cpp new file mode 100644 index 00000000..b9a7154c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_064.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(void *argument) +{ + UINT32 ret; + char msgrcd[10]; + siginfo_t newSiginfoT; + sigset_t newSigsetT2; + sigset_t newSigsetT; + struct timespec time = { (time_t)0, 3000000 }; + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + g_testCount++; + + + sigemptyset(&newSigsetT2); + sigaddset(&newSigsetT2, 17); + ret = sigtimedwait(&newSigsetT2, &newSiginfoT, &time); + ICUNIT_GOTO_EQUAL(ret, 17, ret, EXIT); + + g_testCount++; + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); + +EXIT: + return reinterpret_cast(9); // 9: return value for testing +} +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + UINT32 ret; + UINTPTR uwtemp = 1; + sigset_t set; + pthread_attr_t attr; + + sigemptyset(&set); + sigaddset(&set, 17); + sigprocmask(SIG_BLOCK, &set, NULL); + + g_testCount = 0; + + ret = PosixPthreadInit(&attr, 4); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_create(&newTh, &attr, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + g_testCount++; + + ret = kill(0, 17); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); + + ret = pthread_join(newTh, (void **)&uwtemp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread064(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_064", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_066.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_066.cpp new file mode 100644 index 00000000..3682f508 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_066.cpp @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f02(void *argument) +{ + int oldstate; + UINT32 ret; + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + + ret = pthread_cancel(g_newTh); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testCount++; + + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); +EXIT: + return static_cast(9); // 9: return value for testing +} + +static VOID *pthread_f01(void *argument) +{ + int oldstate; + UINT32 ret; + pthread_attr_t attr; + pthread_t newTh; + struct sched_param schedparam; + + g_testCount++; + + ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ICUNIT_GOTO_EQUAL(oldstate, PTHREAD_CANCEL_DEFERRED, oldstate, EXIT); + + ret = pthread_attr_init(&attr); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + schedparam.sched_priority = 8; + pthread_attr_setschedparam(&attr, &schedparam); + + ret = pthread_create(&g_newTh2, &attr, pthread_f02, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + +#ifdef LOSCFG_KERNEL_SMP + while (g_testCount < 2) { + TestBusyTaskDelay(1); + } + TestExtraTaskDelay(1); +#else + g_testCount++; + + ret = pthread_join(g_newTh2, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + g_testCount++; + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); +#endif +EXIT: + return static_cast(9); // 9: return value for testing +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINTPTR uwtemp = 1; + pthread_attr_t attr; + struct sched_param schedparam; + + g_testCount = 0; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + schedparam.sched_priority = 9; + pthread_attr_setschedparam(&attr, &schedparam); + + ret = pthread_create(&g_newTh, &attr, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LosTaskDelay(10); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); + + ret = pthread_join(g_newTh, (void **)&uwtemp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(uwtemp, (UINTPTR)PTHREAD_CANCELED, uwtemp); + + ret = pthread_join(g_newTh2, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread066(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_066", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_069.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_069.cpp new file mode 100644 index 00000000..2a6fdc0c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_069.cpp @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static UINT32 Testcase(VOID) +{ + pthread_condattr_t condattr; + pthread_cond_t cond1; + pthread_cond_t cond2; + int rc; + + rc = pthread_condattr_init(&condattr); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_cond_init(&cond1, &condattr); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_cond_init(&cond2, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + + rc = pthread_cond_destroy(&cond1); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + rc = pthread_cond_destroy(&cond2); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread069(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_069", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_070.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_070.cpp new file mode 100644 index 00000000..6dfb5af2 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_070.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static UINT32 Testcase(VOID) +{ + pthread_cond_t cond; + int rc; + + rc = pthread_cond_init(&cond, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_cond_init(&cond, NULL); + if (rc && rc != EBUSY) { + ICUNIT_ASSERT_EQUAL(rc, EBUSY, rc); + } + + rc = pthread_cond_destroy(&cond); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread070(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_070", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_071.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_071.cpp new file mode 100644 index 00000000..c6a104b7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_071.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static UINT32 Testcase(VOID) +{ + pthread_condattr_t condattr; + int rc; + pthread_cond_t cond1, cond2; + pthread_cond_t cond3 = PTHREAD_COND_INITIALIZER; + + /* Initialize a condition variable attribute object */ + rc = pthread_condattr_init(&condattr); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* Initialize cond1 with the default condition variable attribute */ + rc = pthread_cond_init(&cond1, &condattr); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* Initialize cond2 with NULL attributes */ + rc = pthread_cond_init(&cond2, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* Destroy the condition variable attribute object */ + rc = pthread_condattr_destroy(&condattr); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* Destroy cond1 */ + rc = pthread_cond_destroy(&cond1); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* Destroy cond2 */ + rc = pthread_cond_destroy(&cond2); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* Destroy cond3 */ + rc = pthread_cond_destroy(&cond3); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread071(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_071", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_072.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_072.cpp new file mode 100644 index 00000000..9d8141be --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_072.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static void *pthread_f01(void *tmp) +{ + int rc = 0; + g_testCount++; + + /* acquire the mutex */ + rc = pthread_mutex_lock(&g_pthreadMutexTest1); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + g_testCount++; + /* Wait on the cond var. This will not return, as nobody signals */ + rc = pthread_cond_wait(&g_pthreadCondTest1, &g_pthreadMutexTest1); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + g_testCount++; + + rc = pthread_mutex_unlock(&g_pthreadMutexTest1); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + g_testCount++; +EXIT: + return NULL; +} +static UINT32 Testcase(VOID) +{ + pthread_t lowId; + int rc = 0; + + g_pthreadMutexTest1 = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER; + g_pthreadCondTest1 = (pthread_cond_t)PTHREAD_COND_INITIALIZER; + g_testCount = 0; + + /* Create a new thread with default attributes */ + rc = pthread_create(&lowId, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* Let the other thread run */ + LosTaskDelay(2); + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2: expected value of g_testCount + + /* Try to destroy the cond var. This should return an error */ + rc = pthread_cond_destroy(&g_pthreadCondTest1); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_cond_broadcast(&g_pthreadCondTest1); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + LosTaskDelay(2); + ICUNIT_ASSERT_EQUAL(g_testCount, 4, g_testCount); // 4: expected value of g_testCount + + rc = pthread_cond_destroy(&g_pthreadCondTest1); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_join(lowId, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread072(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_072", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_073.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_073.cpp new file mode 100644 index 00000000..a029b58b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_073.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "pthread.h" +#include "It_posix_pthread.h" + + +static UINT32 Testcase(VOID) +{ + pthread_condattr_t condattr; + int rc; + +#ifdef PTHREAD_PROCESS_SHARED + int pshared; +#endif + /* Initialize a cond attributes object */ + rc = pthread_condattr_init(&condattr); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + +#ifdef PTHREAD_PROCESS_SHARED + /* If the symbol {PTHREAD_PROCESS_SHARED} is defined, the attribute + * process-shared should be provided and its default value should be + * PTHREAD_PROCESS_PRIVATE */ + rc = pthread_condattr_getpshared(&condattr, &pshared); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + ICUNIT_ASSERT_EQUAL(pshared, PTHREAD_PROCESS_PRIVATE, pshared); + +#endif + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread073(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_073", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_074.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_074.cpp new file mode 100644 index 00000000..37b44d24 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_074.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static UINT32 Testcase(VOID) +{ + pthread_condattr_t condattr; + int rc; + + /* Initialize a condition variable attributes object */ + rc = pthread_condattr_init(&condattr); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* Destroy the condition variable attributes object */ + rc = pthread_condattr_destroy(&condattr); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* Initialize the condition variable attributes object again. This shouldn't result in an error. */ + rc = pthread_condattr_init(&condattr); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread074(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_074", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_078.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_078.cpp new file mode 100644 index 00000000..d442e5ab --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_078.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static UINT32 Testcase(VOID) +{ + pthread_condattr_t attr; + int ret; + + /* Initialize a cond attributes object */ + ret = pthread_condattr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + /* Set 'pshared' to INVALID_PSHARED_VALUE. */ + ret = pthread_condattr_setpshared(&attr, INVALID_PSHARED_VALUE); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + /* Destroy the cond attributes object */ + ret = pthread_condattr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread078(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_078", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_079.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_079.cpp new file mode 100644 index 00000000..afe5a8a9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_079.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static UINT32 Testcase(VOID) +{ + pthread_condattr_t attr; + int ret; + int pshared; + + /* Initialize a cond attributes object */ + ret = pthread_condattr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + /* Set 'pshared' to INVALID_PSHARED_VALUE. */ + ret = pthread_condattr_getpshared(&attr, &pshared); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(pshared, PTHREAD_PROCESS_PRIVATE, pshared); + + /* Destroy the cond attributes object */ + ret = pthread_condattr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread079(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_079", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_080.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_080.cpp new file mode 100644 index 00000000..89e876c3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_080.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static void *pthread_f01(void *arg) +{ + int rc; + pthread_t self = pthread_self(); + + rc = pthread_mutex_lock(&g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + g_startNum++; + printf("pthread start_num: %d \n", g_startNum); + rc = pthread_cond_wait(&g_td.cond, &g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + g_wakenNum++; + + rc = pthread_mutex_unlock(&g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + +EXIT: + return NULL; +} +static UINT32 Testcase(VOID) +{ + int i, rc; + g_startNum = 0; + g_wakenNum = 0; + pthread_t thread[THREAD_NUM]; + + rc = pthread_mutex_init(&g_td.mutex, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_cond_init(&g_td.cond, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + for (i = 0; i < THREAD_NUM; i++) { + rc = pthread_create(&thread[i], NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + } + + while (g_startNum < THREAD_NUM) { + usleep(1000 * 10 * 2); + } + + /* + * Acquire the mutex to make sure that all waiters are currently + * blocked on pthread_cond_wait + */ + rc = pthread_mutex_lock(&g_td.mutex); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_mutex_unlock(&g_td.mutex); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* broadcast and check if all waiters are wakened */ + rc = pthread_cond_broadcast(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + sleep(1); + + /* join all secondary threads */ + for (i = 0; i < THREAD_NUM; i++) { + rc = pthread_join(thread[i], NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + } + + printf("start_num: %d", g_startNum); + ICUNIT_ASSERT_EQUAL(g_wakenNum, THREAD_NUM, g_wakenNum); + rc = pthread_cond_destroy(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread080(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_080", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_081.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_081.cpp new file mode 100644 index 00000000..e25b699f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_081.cpp @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static void *pthread_f01(void *arg) +{ + int rc; + pthread_t self = pthread_self(); + + rc = pthread_mutex_lock(&g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + g_startNum++; + + rc = pthread_cond_wait(&g_td.cond, &g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + rc = pthread_mutex_trylock(&g_td.mutex); + ICUNIT_GOTO_NOT_EQUAL(rc, 0, rc, EXIT); + + g_wakenNum++; + + rc = pthread_mutex_unlock(&g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + +EXIT: + return NULL; +} + +static UINT32 Testcase(VOID) +{ + int i, rc; + pthread_t thread[THREAD_NUM]; + + g_startNum = 0; + g_wakenNum = 0; + + rc = pthread_mutex_init(&g_td.mutex, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_cond_init(&g_td.cond, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + for (i = 0; i < THREAD_NUM; i++) { + rc = pthread_create(&thread[i], NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + } + + while (g_startNum < THREAD_NUM) { + usleep(1000 * 10 * 2); + } + /* + * Acquire the mutex to make sure that all waiters are currently + * blocked on pthread_cond_wait + */ + rc = pthread_mutex_lock(&g_td.mutex); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_mutex_unlock(&g_td.mutex); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* broadcast and check if all waiters are wakened */ + rc = pthread_cond_broadcast(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + sleep(1); + + ICUNIT_ASSERT_EQUAL(g_wakenNum, THREAD_NUM, g_wakenNum); + + /* join all secondary threads */ + for (i = 0; i < THREAD_NUM; i++) { + rc = pthread_join(thread[i], NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + } + + rc = pthread_cond_destroy(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread081(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_081", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_082.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_082.cpp new file mode 100644 index 00000000..80d08c51 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_082.cpp @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static void *pthread_f01(void *arg) +{ + int rc; + struct timespec timeout; + struct timeval curtime; + pthread_t self = pthread_self(); + + rc = pthread_mutex_lock(&g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + g_startNum++; + + rc = gettimeofday(&curtime, NULL); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + timeout.tv_sec = curtime.tv_sec + PTHREAD_TIMEOUT; + timeout.tv_nsec = curtime.tv_usec * 1000; + + rc = pthread_cond_timedwait(&g_td.cond, &g_td.mutex, &timeout); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + rc = pthread_mutex_trylock(&g_td.mutex); + ICUNIT_GOTO_NOT_EQUAL(rc, 0, rc, EXIT); + + g_wakenNum++; + + rc = pthread_mutex_unlock(&g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + +EXIT: + return NULL; +} +static UINT32 Testcase(VOID) +{ + int i, rc; + pthread_t thread[THREAD_NUM]; + + g_startNum = 0; + g_wakenNum = 0; + + rc = pthread_mutex_init(&g_td.mutex, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_cond_init(&g_td.cond, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + for (i = 0; i < THREAD_NUM; i++) { + rc = pthread_create(&thread[i], NULL, pthread_f01, NULL); // + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + } + + while (g_startNum < THREAD_NUM) { + usleep(1000 * 10 * 2); + } + + /* + * Acquire the mutex to make sure that all waiters are currently + * blocked on pthread_cond_wait + */ + rc = pthread_mutex_lock(&g_td.mutex); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_mutex_unlock(&g_td.mutex); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* broadcast and check if all waiters are wakened */ + ICUNIT_ASSERT_EQUAL(g_wakenNum, 0, g_wakenNum); + + rc = pthread_cond_broadcast(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + sleep(1); + + ICUNIT_ASSERT_EQUAL(g_wakenNum, THREAD_NUM, g_wakenNum); + + /* join all secondary threads */ + for (i = 0; i < THREAD_NUM; i++) { + rc = pthread_join(thread[i], NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + } + + rc = pthread_cond_destroy(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread082(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_082", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_083.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_083.cpp new file mode 100644 index 00000000..f1fba762 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_083.cpp @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static void *pthread_f01(void *arg) +{ + int rc; + pthread_t self = pthread_self(); + + rc = pthread_mutex_lock(&g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + g_startNum++; + + rc = pthread_cond_wait(&g_td.cond, &g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + g_wakenNum++; + + rc = pthread_mutex_unlock(&g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + +EXIT: + return NULL; +} +static UINT32 Testcase(VOID) +{ + int i, rc; + pthread_t thread[THREAD_NUM]; + + g_startNum = 0; + g_wakenNum = 0; + + rc = pthread_mutex_init(&g_td.mutex, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_cond_init(&g_td.cond, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + for (i = 0; i < THREAD_NUM; i++) { + rc = pthread_create(&thread[i], NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + } + + while (g_startNum < THREAD_NUM) { + usleep(1000 * 10 * 2); + } + + /* + * Acquire the mutex to make sure that all waiters are currently + * blocked on pthread_cond_wait + */ + rc = pthread_mutex_lock(&g_td.mutex); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_mutex_unlock(&g_td.mutex); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* broadcast and check if all waiters are wakened */ + ICUNIT_ASSERT_EQUAL(g_wakenNum, 0, g_wakenNum); + + rc = pthread_cond_signal(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + sleep(1); + + ICUNIT_ASSERT_EQUAL(g_wakenNum, 1, g_wakenNum); + + rc = pthread_cond_signal(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_cond_signal(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_cond_signal(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + sleep(1); + + ICUNIT_ASSERT_EQUAL(g_wakenNum, THREAD_NUM, g_wakenNum); + + /* join all secondary threads */ + for (i = 0; i < THREAD_NUM; i++) { + rc = pthread_join(thread[i], NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + } + + rc = pthread_cond_destroy(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread083(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_083", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_084.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_084.cpp new file mode 100644 index 00000000..2fdb5a98 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_084.cpp @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static void *pthread_f01(void *arg) +{ + int rc; + pthread_t self = pthread_self(); + + rc = pthread_mutex_lock(&g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + g_startNum++; + + rc = pthread_cond_wait(&g_td.cond, &g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + rc = pthread_mutex_trylock(&g_td.mutex); + ICUNIT_GOTO_NOT_EQUAL(rc, 0, rc, EXIT); + + g_wakenNum++; + + rc = pthread_mutex_unlock(&g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + +EXIT: + return NULL; +} +static UINT32 Testcase(VOID) +{ + int i, rc; + pthread_t thread[THREAD_NUM]; + + g_startNum = 0; + g_wakenNum = 0; + + rc = pthread_mutex_init(&g_td.mutex, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_cond_init(&g_td.cond, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + for (i = 0; i < THREAD_NUM; i++) { + rc = pthread_create(&thread[i], NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + } + + while (g_startNum < THREAD_NUM) { + usleep(1000 * 10 * 2); + } + + /* + * Acquire the mutex to make sure that all waiters are currently + * blocked on pthread_cond_wait + */ + rc = pthread_mutex_lock(&g_td.mutex); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_mutex_unlock(&g_td.mutex); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* broadcast and check if all waiters are wakened */ + rc = pthread_cond_signal(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + sleep(1); + + ICUNIT_ASSERT_EQUAL(g_wakenNum, 1, g_wakenNum); + + rc = pthread_cond_signal(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_cond_signal(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_cond_signal(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + sleep(1); + + ICUNIT_ASSERT_EQUAL(g_wakenNum, THREAD_NUM, g_wakenNum); + + /* join all secondary threads */ + for (i = 0; i < THREAD_NUM; i++) { + rc = pthread_join(thread[i], NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + } + + rc = pthread_cond_destroy(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread084(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_084", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_085.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_085.cpp new file mode 100644 index 00000000..9ea91457 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_085.cpp @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static void *pthread_f01(void *arg) +{ + int rc; + + rc = pthread_mutex_lock(&g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + g_t1Start = 1; /* let main thread continue */ + + rc = pthread_cond_wait(&g_td.cond, &g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + ICUNIT_GOTO_NOT_EQUAL(g_signaled, 0, g_signaled, EXIT); + + rc = pthread_mutex_unlock(&g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + g_t1Start = 2; +EXIT: + return NULL; +} +static UINT32 Testcase(VOID) +{ + struct sigaction act; + int rc; + pthread_t thread1; + + g_t1Start = 0; + + rc = pthread_mutex_init(&g_td.mutex, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_cond_init(&g_td.cond, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_create(&thread1, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + while (!g_t1Start) { /* wait for thread1 started */ + usleep(1000 * 10 * 2); + } + + /* acquire the mutex released by pthread_cond_wait() within thread 1 */ + rc = pthread_mutex_lock(&g_td.mutex); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_mutex_unlock(&g_td.mutex); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + sleep(1); + + fprintf(stderr, "Time to wake up thread1 by signaling a condition\n"); + g_signaled = 1; + rc = pthread_cond_signal(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_join(thread1, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + ICUNIT_ASSERT_EQUAL(g_t1Start, 2, g_t1Start); + g_signaled = 0; + + rc = pthread_cond_destroy(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread085(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_085", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_087.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_087.cpp new file mode 100644 index 00000000..40c0e390 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_087.cpp @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static void *pthread_f01(void *arg) +{ + int rc; + struct timespec timeout; + struct timeval curtime; + + rc = pthread_mutex_lock(&g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + g_t1Start = 1; /* let main thread continue */ + + rc = gettimeofday(&curtime, NULL); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + timeout.tv_sec = curtime.tv_sec + PTHREAD_TIMEOUT; + timeout.tv_nsec = curtime.tv_usec * 1000; + + rc = pthread_cond_timedwait(&g_td.cond, &g_td.mutex, &timeout); + ICUNIT_GOTO_EQUAL(rc, ETIMEDOUT, rc, EXIT); + + rc = pthread_mutex_trylock(&g_td.mutex); + ICUNIT_GOTO_NOT_EQUAL(rc, 0, rc, EXIT); + ICUNIT_GOTO_EQUAL(g_signaled, 1, g_signaled, EXIT); + + rc = pthread_mutex_unlock(&g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); +EXIT: + pthread_exit(static_cast(5)); // 5: return value for testing +} + +static UINT32 Testcase(VOID) +{ + struct sigaction act; + int rc; + pthread_t thread1; + void *thRet; + + g_t1Start = 0; + + rc = pthread_mutex_init(&g_td.mutex, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_cond_init(&g_td.cond, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_create(&thread1, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + while (!g_t1Start) { /* wait for thread1 started */ + usleep(1000 * 10 * 2); + } + + /* acquire the mutex released by pthread_cond_wait() within thread 1 */ + rc = pthread_mutex_lock(&g_td.mutex); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_mutex_unlock(&g_td.mutex); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + sleep(1); + g_signaled = 1; + rc = pthread_join(thread1, &thRet); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + ICUNIT_ASSERT_EQUAL(static_cast(thRet), 5, static_cast(thRet)); // 5: return value for testing + g_signaled = 0; + + rc = pthread_cond_destroy(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread087(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_087", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_088.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_088.cpp new file mode 100644 index 00000000..875f7a64 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_088.cpp @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" +static pthread_mutex_t g_pthreadMutexTest100; +static pthread_cond_t g_pthreadCondTest100; + +static void PthreadSignalHandlerF01(int sig) +{ + int rc; + + rc = pthread_cond_signal(&g_pthreadCondTest100); + ICUNIT_ASSERT_EQUAL_VOID(rc, 0, rc); +} + +/* Utility function to find difference between two time values */ +static float PthreadTimeF01(struct timespec t2, struct timespec t1) +{ + float diff = t2.tv_sec - t1.tv_sec; + diff += (t2.tv_nsec - t1.tv_nsec) / 1000000000.0; + return diff; +} + +static void *pthread_f01(void *tmp) +{ + struct sched_param param; + int policy; + int rc = 0; + + param.sched_priority = HIGH_PRIORITY; + + rc = pthread_setschedparam(pthread_self(), SCHED_RR, ¶m); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + rc = pthread_getschedparam(pthread_self(), &policy, ¶m); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + ICUNIT_GOTO_EQUAL(policy, SCHED_RR, policy, EXIT); + ICUNIT_GOTO_EQUAL(param.sched_priority, HIGH_PRIORITY, param.sched_priority, EXIT); + + rc = pthread_mutex_lock(&g_pthreadMutexTest100); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + /* Block, to be woken up by the signal handler */ + rc = pthread_cond_wait(&g_pthreadCondTest100, &g_pthreadMutexTest100); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + /* This variable is unprotected because the scheduling removes + * the contention + */ + if (g_lowDone != 1) + g_wokenUp = 1; + + rc = pthread_mutex_unlock(&g_pthreadMutexTest100); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); +EXIT: + return NULL; +} + +static void *pthread_f02(void *tmp) +{ + struct timespec startTime, currentTime; + struct sched_param param; + int policy; + int rc = 0; + + param.sched_priority = LOW_PRIORITY; + + rc = pthread_setschedparam(pthread_self(), SCHED_RR, ¶m); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + rc = pthread_getschedparam(pthread_self(), &policy, ¶m); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + ICUNIT_GOTO_EQUAL(policy, SCHED_RR, policy, EXIT); + ICUNIT_GOTO_EQUAL(param.sched_priority, LOW_PRIORITY, param.sched_priority, EXIT); + + PthreadSignalHandlerF01(SIGALRM); + + /* grab the start time and busy loop for 5 seconds */ + clock_gettime(CLOCK_REALTIME, &startTime); + while (1) { + clock_gettime(CLOCK_REALTIME, ¤tTime); + if (PthreadTimeF01(currentTime, startTime) > RUNTIME) { + break; + } + } + g_lowDone = 1; +EXIT: + return NULL; +} +static UINT32 Testcase(VOID) +{ + pthread_t highId, lowId; + pthread_attr_t highAttr, lowAttr; + struct sched_param param; + int rc = 0; + g_pthreadMutexTest100 = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER; + g_pthreadCondTest100 = (pthread_cond_t)PTHREAD_COND_INITIALIZER; + /* Create the higher priority thread */ + rc = pthread_attr_init(&highAttr); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_attr_setschedpolicy(&highAttr, SCHED_RR); // + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + pthread_attr_setinheritsched(&highAttr, PTHREAD_EXPLICIT_SCHED); + + param.sched_priority = HIGH_PRIORITY; + rc = pthread_attr_setschedparam(&highAttr, ¶m); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_create(&highId, &highAttr, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* Create the low priority thread */ + rc = pthread_attr_init(&lowAttr); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_attr_setschedpolicy(&lowAttr, SCHED_RR); // + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + pthread_attr_setinheritsched(&lowAttr, PTHREAD_EXPLICIT_SCHED); + + param.sched_priority = LOW_PRIORITY; + rc = pthread_attr_setschedparam(&lowAttr, ¶m); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_create(&lowId, &lowAttr, pthread_f02, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + + /* Wait for the threads to exit */ + rc = pthread_join(highId, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_join(lowId, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_cond_destroy(&g_pthreadCondTest100); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* Check the result */ + ICUNIT_ASSERT_EQUAL(g_wokenUp, 1, g_wokenUp); + ICUNIT_ASSERT_EQUAL(g_lowDone, 1, g_lowDone); + + g_iCunitErrLineNo = 0; + g_iCunitErrCode = 0; + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread088(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_088", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_089.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_089.cpp new file mode 100644 index 00000000..f0714dc9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_089.cpp @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" +static pthread_mutex_t g_pthreadMutexTest100; +; +static pthread_cond_t g_pthreadCondTest100; + +static void PthreadSignalHandlerF01(int sig) +{ + int rc; + rc = pthread_cond_broadcast(&g_pthreadCondTest100); + ICUNIT_ASSERT_EQUAL_VOID(rc, 0, rc); +} + +/* Utility function to find difference between two time values */ +static float PthreadTimeF01(struct timespec t2, struct timespec t1) +{ + float diff = t2.tv_sec - t1.tv_sec; + diff += (t2.tv_nsec - t1.tv_nsec) / 1000000000.0; + return diff; +} + +static void *pthread_f01(void *tmp) +{ + struct sched_param param; + int policy; + int rc = 0; + + param.sched_priority = HIGH_PRIORITY; + + rc = pthread_setschedparam(pthread_self(), SCHED_RR, ¶m); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + rc = pthread_getschedparam(pthread_self(), &policy, ¶m); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + ICUNIT_GOTO_EQUAL(policy, SCHED_RR, policy, EXIT); + ICUNIT_GOTO_EQUAL(param.sched_priority, HIGH_PRIORITY, param.sched_priority, EXIT); + + /* acquire the mutex */ + rc = pthread_mutex_lock(&g_pthreadMutexTest100); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + /* Block, to be woken up by the signal handler */ + rc = pthread_cond_wait(&g_pthreadCondTest100, &g_pthreadMutexTest100); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + /* This variable is unprotected because the scheduling removes + * the contention + */ + if (g_lowDone != 1) + g_wokenUp = 1; + + rc = pthread_mutex_unlock(&g_pthreadMutexTest100); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); +EXIT: + return NULL; +} + +static void *pthread_f02(void *tmp) +{ + struct timespec startTime, currentTime; + struct sched_param param; + int policy; + int rc = 0; + + ICUNIT_GOTO_EQUAL(g_wokenUp, -1, g_wokenUp, EXIT); + + param.sched_priority = LOW_PRIORITY; + + rc = pthread_setschedparam(pthread_self(), SCHED_RR, ¶m); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + rc = pthread_getschedparam(pthread_self(), &policy, ¶m); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + ICUNIT_GOTO_EQUAL(policy, SCHED_RR, policy, EXIT); + ICUNIT_GOTO_EQUAL(param.sched_priority, LOW_PRIORITY, param.sched_priority, EXIT); + + PthreadSignalHandlerF01(SIGALRM); + + /* grab the start time and busy loop for 5 seconds */ + clock_gettime(CLOCK_REALTIME, &startTime); + while (1) { + clock_gettime(CLOCK_REALTIME, ¤tTime); + if (PthreadTimeF01(currentTime, startTime) > RUNTIME) { + break; + } + } + g_lowDone = 1; +EXIT: + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t highId, lowId; + pthread_attr_t highAttr, lowAttr; + struct sched_param param; + int rc = 0; + + sleep(1); + + g_wokenUp = -1; + g_lowDone = -1; + + g_pthreadMutexTest100 = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER; + g_pthreadCondTest100 = (pthread_cond_t)PTHREAD_COND_INITIALIZER; + /* Create the higher priority thread */ + rc = pthread_attr_init(&highAttr); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_attr_setschedpolicy(&highAttr, SCHED_RR); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + pthread_attr_setinheritsched(&highAttr, PTHREAD_EXPLICIT_SCHED); + + param.sched_priority = HIGH_PRIORITY; + rc = pthread_attr_setschedparam(&highAttr, ¶m); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_create(&highId, &highAttr, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* Create the low priority thread */ + rc = pthread_attr_init(&lowAttr); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_attr_setschedpolicy(&lowAttr, SCHED_RR); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + param.sched_priority = LOW_PRIORITY; + rc = pthread_attr_setschedparam(&lowAttr, ¶m); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_create(&lowId, &lowAttr, pthread_f02, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* Wait for the threads to exit */ + rc = pthread_join(highId, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_join(lowId, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_cond_destroy(&g_pthreadCondTest100); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* Check the result */ + ICUNIT_ASSERT_EQUAL(g_wokenUp, 1, g_wokenUp); + ICUNIT_ASSERT_EQUAL(g_lowDone, 1, g_lowDone); + + g_iCunitErrLineNo = 0; + g_iCunitErrCode = 0; + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread089(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_089", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_090.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_090.cpp new file mode 100644 index 00000000..645d4e32 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_090.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +#define THREAD_COUNT 15 +static void *pthread_f01(void *arg) +{ + int rc; + pthread_t self = pthread_self(); + + rc = pthread_mutex_lock(&g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + g_startNum++; + if (g_startNum > 5) { // 5: threshold for calling usleep + usleep(1000 * 10 * 2); + } + + printf("pthread start_num: %d \n", g_startNum); + rc = pthread_cond_wait(&g_td.cond, &g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + g_wakenNum++; + + printf("pthread waken_num: %d \n", g_wakenNum); + rc = pthread_mutex_unlock(&g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + +EXIT: + return NULL; +} +static UINT32 Testcase(VOID) +{ + int i, rc; + g_startNum = 0; + g_wakenNum = 0; + pthread_t thread[THREAD_COUNT]; + + rc = pthread_mutex_init(&g_td.mutex, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_cond_init(&g_td.cond, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_mutex_lock(&g_td.mutex); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + for (i = 0; i < THREAD_COUNT; i++) { + rc = pthread_create(&thread[i], NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + usleep(1000 * 10 * 2); + } + + rc = pthread_mutex_unlock(&g_td.mutex); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + usleep(1000 * 10 * 1); + + printf("%s %d pthread_cond_broadcast \n", __FUNCTION__, __LINE__); + + /* broadcast and check if all waiters are wakened */ + rc = pthread_cond_broadcast(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + sleep(1); + + printf("%s %d pthread_cond_broadcast two\n", __FUNCTION__, __LINE__); + rc = pthread_cond_broadcast(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + /* join all secondary threads */ + for (i = 0; i < THREAD_COUNT; i++) { + rc = pthread_join(thread[i], NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + } + + printf("start_num: %d", g_startNum); + rc = pthread_cond_destroy(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + + g_iCunitErrCode = 0; + g_iCunitErrLineNo = 0; + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread090(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_090", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_091.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_091.cpp new file mode 100644 index 00000000..477509bc --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_091.cpp @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(void *argument) +{ + int oldstate; + UINT32 ret; + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + g_testCount++; + + usleep(1000 * 10 * 5); + ret = pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldstate); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ICUNIT_GOTO_EQUAL(oldstate, PTHREAD_CANCEL_DEFERRED, oldstate, EXIT); + + pthread_testcancel(); + g_testCount++; + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); +EXIT: + return reinterpret_cast(9); // 9: return value for testing +} + +static VOID *pthread_f02(void *argument) +{ + UINT32 ret; + int oldstate; + UINT32 i, j; + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + g_testCount++; + + usleep(1000 * 10 * 5); + ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ICUNIT_GOTO_EQUAL(oldstate, PTHREAD_CANCEL_DEFERRED, oldstate, EXIT); + printf("10\n"); + + for (i = 0, j = 0; i < 0xffffffff; i++) + j++; + g_testCount++; + printf("11\n"); + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // failed , =3 +EXIT: + return static_cast(9); // 9: return value for testing +} +static UINT32 Testcase(VOID) +{ + pthread_t newTh, newTh2; + UINT32 ret; + UINTPTR uwtemp = 1; + + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newTh2, NULL, pthread_f02, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_cancel(newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_cancel(newTh2); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LosTaskDelay(10); + + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); + ret = pthread_join(newTh, (void **)&uwtemp); + + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(uwtemp, (UINTPTR)PTHREAD_CANCELED, uwtemp); + + ret = pthread_join(newTh2, (void **)&uwtemp); + + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(uwtemp, (UINTPTR)PTHREAD_CANCELED, uwtemp); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread091(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_091", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_092.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_092.cpp new file mode 100644 index 00000000..5f22c11d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_092.cpp @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +#define THREAD_COUNT 15 +static int g_testCnt; + +static void *pthread_f01(void *arg) +{ + int rc; + pthread_t self = pthread_self(); + + rc = pthread_mutex_lock(&g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + g_startNum++; + if (g_startNum > 5) { // 5: threshold for calling usleep + usleep(1000 * 10 * 2); + } + + printf("pthread start_num: %d \n", g_startNum); + rc = pthread_cond_wait(&g_td.cond, &g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + g_wakenNum++; + + printf("pthread waken_num: %d \n", g_wakenNum); + rc = pthread_mutex_unlock(&g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + +EXIT: + return NULL; +} + +static void *pthread_f02(void *arg) +{ + int rc; + pthread_t self = pthread_self(); + + g_testCnt++; + rc = pthread_mutex_lock(&g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + rc = pthread_mutex_unlock(&g_td.mutex); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + +EXIT: + return NULL; +} + +static UINT32 Testcase(VOID) +{ + int i, rc; + g_startNum = 0; + g_wakenNum = 0; + pthread_t thread[THREAD_COUNT]; + pthread_t thread2[THREAD_COUNT]; + + rc = pthread_mutex_init(&g_td.mutex, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_cond_init(&g_td.cond, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_mutex_lock(&g_td.mutex); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + g_testCnt = 0; + for (i = 0; i < THREAD_COUNT; i++) { + rc = pthread_create(&thread[i], NULL, pthread_f02, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + usleep(1000 * 10 * 2); + } + + ICUNIT_ASSERT_EQUAL(g_testCnt, THREAD_COUNT, g_testCnt); + + for (i = 0; i < THREAD_COUNT; i++) { + rc = pthread_create(&thread2[i], NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + usleep(1000 * 10 * 2); + } + + rc = pthread_mutex_unlock(&g_td.mutex); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + usleep(1000 * 10 * 1); + + printf("%s %d pthread_cond_broadcast \n", __FUNCTION__, __LINE__); + + /* broadcast and check if all waiters are wakened */ + rc = pthread_cond_broadcast(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + sleep(1); + + printf("%s %d pthread_cond_broadcast two\n", __FUNCTION__, __LINE__); + rc = pthread_cond_broadcast(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + for (i = 0; i < THREAD_COUNT; i++) { + rc = pthread_join(thread[i], NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + } + + /* join all secondary threads */ + for (i = 0; i < THREAD_COUNT; i++) { + rc = pthread_join(thread2[i], NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + } + + printf("start_num: %d", g_startNum); + rc = pthread_cond_destroy(&g_td.cond); + ICUNIT_ASSERT_EQUAL(rc, ENOERR, rc); + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread092(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_092", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_094.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_094.cpp new file mode 100644 index 00000000..a6a18431 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_094.cpp @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f02(void *argument) +{ + int oldstate; + UINT32 ret; + int i = 0; + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); + g_testCount++; + + ret = pthread_cancel(g_newTh); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); + g_testCount++; +EXIT: + return static_cast(9); // 9: return value for testing +} + +static VOID *pthread_f01(void *argument) +{ + int oldstate; + UINT32 ret; + pthread_attr_t attr; + struct sched_param schedparam; + + ICUNIT_GOTO_EQUAL(g_testCount, 0, g_testCount, EXIT); + g_testCount++; + ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ICUNIT_GOTO_EQUAL(oldstate, PTHREAD_CANCEL_DEFERRED, oldstate, EXIT); + + ret = pthread_attr_init(&attr); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + schedparam.sched_priority = 15; + pthread_attr_setschedparam(&attr, &schedparam); + + ret = pthread_create(&g_newTh2, &attr, pthread_f02, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + g_testCount++; + +EXIT: + return static_cast(9); // 9: return value for testing +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINTPTR wtemp = 1; + pthread_attr_t attr; + struct sched_param schedparam; + + int i = 0; + g_testCount = 0; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + schedparam.sched_priority = 10; + pthread_attr_setschedparam(&attr, &schedparam); + + ret = pthread_create(&g_newTh, &attr, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 4, g_testCount); + g_testCount++; + + ret = pthread_join(g_newTh, (void **)&wtemp); + + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); + g_testCount++; + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_NOT_EQUAL(wtemp, (UINTPTR)PTHREAD_CANCELED, wtemp); + + ICUNIT_GOTO_EQUAL(g_testCount, 6, g_testCount, EXIT); + g_testCount++; + + ret = pthread_join(g_newTh2, NULL); + + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_GOTO_EQUAL(g_testCount, 7, g_testCount, EXIT); + g_testCount++; + +EXIT: + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread094(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_094", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_095.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_095.cpp new file mode 100644 index 00000000..b1bcff37 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_095.cpp @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static volatile int g_testCnt1; + +static VOID *pthread_f02(void *argument) +{ + int oldstate; + UINT32 ret; + int i = 0; + + ICUNIT_GOTO_EQUAL(g_testCnt1, 2, g_testCnt1, EXIT); + g_testCnt1++; + + ret = pthread_cancel(g_newTh); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + while (g_testCnt1 != 5) { + LosTaskDelay(1); + } + + g_testCnt1++; +EXIT: + return reinterpret_cast(9); // 9: return value for testing +} + +static VOID *pthread_f01(void *argument) +{ + int oldstate; + UINT32 ret; + pthread_attr_t attr; + struct sched_param schedparam; + + TestExtraTaskDelay(1); + ICUNIT_GOTO_EQUAL(g_testCnt1, 1, g_testCnt1, EXIT); + g_testCnt1++; + ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ICUNIT_GOTO_EQUAL(oldstate, PTHREAD_CANCEL_DEFERRED, oldstate, EXIT); + + ret = pthread_attr_init(&attr); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + schedparam.sched_priority = 26; + pthread_attr_setschedparam(&attr, &schedparam); + + ret = pthread_create(&g_newTh2, &attr, pthread_f02, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + LosTaskDelay(5); + + ICUNIT_GOTO_EQUAL(g_testCnt1, 3, g_testCnt1, EXIT); + g_testCnt1++; + +EXIT: + return static_cast(9); // 9: return value for testing +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINTPTR wtemp = 1; + + int i = 0; + g_testCnt1 = 0; + + ret = pthread_create(&g_newTh, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + g_testCnt1++; + + ret = pthread_join(g_newTh, (void **)&wtemp); + + ICUNIT_GOTO_EQUAL(g_testCnt1, 3, g_testCnt1, EXIT); + g_testCnt1++; + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(wtemp, (UINTPTR)PTHREAD_CANCELED, wtemp); + + ICUNIT_GOTO_EQUAL(g_testCnt1, 4, g_testCnt1, EXIT); + g_testCnt1++; + + ret = pthread_join(g_newTh2, NULL); + + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_GOTO_EQUAL(g_testCnt1, 6, g_testCnt1, EXIT); + g_testCnt1++; + +EXIT: + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread095(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_095", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_106.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_106.cpp new file mode 100644 index 00000000..ce0fecf9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_106.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(VOID *argument) +{ + g_testCount++; + LosTaskDelay(10); + pthread_exit(NULL); + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh2; + UINT32 ret; + pthread_attr_t attr; + + int i = 0; + + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + g_testCount = 0; + + ret = pthread_create(&newTh2, &attr, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LosTaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = pthread_detach(newTh2); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + return PTHREAD_NO_ERROR; +} + +/* +********** +testcase brief in English +Posix_Pthread_add_079 +********** +*/ + +VOID ItPosixPthread106(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_106", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_107.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_107.cpp new file mode 100644 index 00000000..0f57cf6a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_107.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(void *t) +{ + long myId = static_cast(t); + int rc; + + rc = pthread_mutex_lock(&g_pthreadMutexTest1); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + g_testCount++; + LosTaskDelay(1); + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); + g_testCount++; + + rc = pthread_cond_wait(&g_pthreadCondTest1, &g_pthreadMutexTest1); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); + rc = pthread_mutex_unlock(&g_pthreadMutexTest1); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + +EXIT: + return NULL; +} + +static VOID *pthread_f02(void *t) +{ + int i; + long myId = static_cast(t); + int rc; + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + g_testCount++; + rc = pthread_mutex_lock(&g_pthreadMutexTest1); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); + g_testCount++; + rc = pthread_cond_signal(&g_pthreadCondTest1); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); + g_testCount++; + + rc = pthread_mutex_unlock(&g_pthreadMutexTest1); /* Ϊ�߳���ѯ������������ʱ */ + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + LosTaskDelay(2); + +EXIT: + pthread_exit(NULL); +} +static UINT32 Testcase(VOID) +{ + int i; + long t1 = 1, t2 = 2, t3 = 3; + int rc; + pthread_t threads[3]; + pthread_attr_t attr; /* ��ʼ���������������������� */ + + g_testCount = 0; + pthread_mutex_init(&g_pthreadMutexTest1, NULL); + pthread_cond_init(&g_pthreadCondTest1, NULL); /* �����߳�ʱ��Ϊ������״̬��������ֲ */ + pthread_attr_init(&attr); + + rc = pthread_create(&threads[0], &attr, pthread_f01, (void *)t1); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_create(&threads[1], &attr, pthread_f02, (void *)t2); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + + /* �ȴ������߳���� */ + for (i = 0; i < 2; i++) { + rc = pthread_join(threads[i], NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + } + + /* ������˳� */ + rc = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_mutex_destroy(&g_pthreadMutexTest1); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + rc = pthread_cond_destroy(&g_pthreadCondTest1); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread107(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_107", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_116.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_116.cpp new file mode 100644 index 00000000..44ebd7d6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_116.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static pthread_t g_th1; +static pthread_mutex_t g_mutx = PTHREAD_MUTEX_INITIALIZER; +static int g_cnt = 0; +#define PRI 9 + +static VOID *pthread_f01(VOID *arg) +{ + struct sched_param schParam; + UINT32 priority = 0; + INT32 sched = SCHED_RR; + int ret; + + g_cnt++; + ICUNIT_GOTO_EQUAL(g_cnt, 1, g_cnt, EXIT); + pthread_mutex_lock(&g_mutx); + LosTaskDelay(10); + + pthread_getschedparam(g_th1, &sched, &schParam); + ICUNIT_GOTO_EQUAL(schParam.sched_priority, PRI, schParam.sched_priority, EXIT); + + priority = schParam.sched_priority - 4; + schParam.sched_priority = priority; + ret = pthread_setschedparam(g_th1, sched, &schParam); + g_cnt++; + ICUNIT_GOTO_EQUAL(g_cnt, 3, g_cnt, EXIT); + pthread_mutex_unlock(&g_mutx); + pthread_getschedparam(g_th1, &sched, &schParam); + ICUNIT_GOTO_EQUAL(schParam.sched_priority, priority, schParam.sched_priority, EXIT); +EXIT: + return NULL; +} + +static VOID *pthread_f02(VOID *arg) +{ + g_cnt++; + ICUNIT_GOTO_EQUAL(g_cnt, 2, g_cnt, EXIT); + pthread_mutex_lock(&g_mutx); + + g_cnt++; + ICUNIT_GOTO_EQUAL(g_cnt, 4, g_cnt, EXIT); + pthread_mutex_unlock(&g_mutx); + + return NULL; +EXIT: + pthread_mutex_unlock(&g_mutx); + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + UINT32 ret; + pthread_attr_t attr; + struct sched_param schParam; + UINT32 priority = 0; + INT32 sched = SCHED_RR; + g_cnt = 0; + struct sched_param schedparam; + + pthread_attr_init(&attr); + pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + schedparam.sched_priority = PRI; + pthread_attr_setschedparam(&attr, &schedparam); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + + ret = pthread_create(&g_th1, &attr, pthread_f01, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + pthread_attr_init(&attr); + schedparam.sched_priority = PRI - 1; + pthread_attr_setschedparam(&attr, &schedparam); + pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + + ret = pthread_create(&newTh, &attr, pthread_f02, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + pthread_getschedparam(g_th1, &sched, &schParam); + + ret = pthread_join(newTh, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_cnt, 4, g_cnt, EXIT); + + return PTHREAD_NO_ERROR; + +EXIT: + pthread_detach(g_th1); + pthread_detach(newTh); + return LOS_NOK; +} + +VOID ItPosixPthread116(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_116", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_123.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_123.cpp new file mode 100644 index 00000000..4152b6b6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_123.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(VOID *argument) +{ + g_pthreadTestTh = pthread_self(); + pthread_exit(0); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + INT32 ret = 0; + + /* Create a new thread */ + ret = pthread_create(&newTh, NULL, pthread_f01, NULL); + ICUNIT_GOTO_EQUAL(ret, PTHREAD_NO_ERROR, ret, EXIT); + + /* Wait for the thread function to return to make sure we got + * the thread ID value from pthread_self(). */ + ret = pthread_join(newTh, NULL); + ICUNIT_GOTO_EQUAL(ret, PTHREAD_NO_ERROR, ret, EXIT); + + /* If the value of pthread_self() and the return value from + * pthread_create() is equal, then the test passes. */ + ret = pthread_equal(newTh, g_pthreadTestTh); + ICUNIT_GOTO_NOT_EQUAL(ret, PTHREAD_NO_ERROR, ret, EXIT); + return PTHREAD_NO_ERROR; +EXIT: + pthread_detach(newTh); + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread123(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_123", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_124.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_124.cpp new file mode 100644 index 00000000..c27c263c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_124.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(VOID *num) +{ + intptr_t i = (intptr_t)num; + printf("Passed argument for thread: %d\n", (int)i); + ICUNIT_TRACK_EQUAL(g_testCount++, i, g_testCount++); + + pthread_exit(0); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + long i; + INT32 ret = 0; + + g_testCount = 1; + + for (i = 1; i < PTHREAD_THREADS_NUM + 1; i++) { + ret = pthread_create(&newTh, NULL, pthread_f01, (void *)i); + ICUNIT_GOTO_EQUAL(ret, PTHREAD_NO_ERROR, ret, EXIT); + + /* Wait for thread to end execution */ + ret = pthread_join(newTh, NULL); + ICUNIT_GOTO_EQUAL(ret, PTHREAD_NO_ERROR, ret, EXIT); + } + + return PTHREAD_NO_ERROR; +EXIT: + pthread_detach(newTh); + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread124(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_124", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_125.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_125.cpp new file mode 100644 index 00000000..9a480f45 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_125.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(VOID *num) +{ + int *i, j; + + i = (int *)num; + + for (j = 0; j < PTHREAD_THREADS_NUM; j++) { + printf("Passed argument %d for thread\n", i[j]); + ICUNIT_TRACK_EQUAL(i[j], j + 1, i[j]); + } + + pthread_exit(0); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + INT32 i[PTHREAD_THREADS_NUM], j, ret; + + for (j = 0; j < PTHREAD_THREADS_NUM; j++) + i[j] = j + 1; + + ret = pthread_create(&newTh, NULL, pthread_f01, (void *)&i); + ICUNIT_GOTO_EQUAL(ret, PTHREAD_NO_ERROR, ret, EXIT); + + /* Wait for thread to end execution */ + ret = pthread_join(newTh, NULL); + ICUNIT_GOTO_EQUAL(ret, PTHREAD_NO_ERROR, ret, EXIT); + + return PTHREAD_NO_ERROR; +EXIT: + pthread_detach(newTh); + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread125(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_125", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_127.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_127.cpp new file mode 100644 index 00000000..5e1fe9e7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_127.cpp @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +typedef struct { + sigset_t mask; + sigset_t pending; +} testdata_t; + +/* Thread function; which will check the signal mask and pending signals */ +static VOID *pthread_f01(VOID *arg) +{ + INT32 ret; + testdata_t *td = (testdata_t *)arg; + + /* Obtain the signal mask of this thread. */ + ret = pthread_sigmask(SIG_SETMASK, NULL, &(td->mask)); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + /* Obtain the pending signals of this thread. It should be empty. */ + ret = sigpending(&(td->pending)); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + /* Signal we're done (especially in case of a detached thread) */ + do { + ret = sem_post(&g_scenarii[g_testCount].sem); + } while ((ret == -1) && (errno == EINTR)); + ICUNIT_TRACK_NOT_EQUAL(ret, -1, ret); + + return arg; +} + +static UINT32 Testcase(VOID) +{ + INT32 ret = 0; + pthread_t child; + testdata_t tdParent, tdThread; + + g_testCount = 0; + +#if PTHREAD_SIGNAL_SUPPORT == 1 + + /* Initialize thread attribute objects */ + ScenarInit(); + + /* Initialize the signal state */ + ret = sigemptyset(&(tdParent.mask)); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = sigemptyset(&(tdParent.pending)); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + /* Add SIGCONT, SIGUSR1 and SIGUSR2 to the set of blocked signals */ + ret = sigaddset(&(tdParent.mask), SIGUSR1); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = sigaddset(&(tdParent.mask), SIGUSR2); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + /* Block those signals. */ + ret = pthread_sigmask(SIG_SETMASK, &(tdParent.mask), NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + /* Raise those signals so they are now pending. */ + ret = raise(SIGUSR1); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = raise(SIGUSR2); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + /* Do the testing for each thread */ + for (g_testCount = 0; g_testCount < NSCENAR; g_testCount++) { + /* (re)initialize thread signal sets */ + ret = sigemptyset(&(tdThread.mask)); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = sigemptyset(&(tdThread.pending)); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_create(&child, &g_scenarii[g_testCount].ta, pthread_f01, &tdThread); + switch (g_scenarii[g_testCount].result) { + case 0: /* Operation was expected to succeed */ + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + break; + + case 1: /* Operation was expected to fail */ + ICUNIT_ASSERT_NOT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + break; + + case 2: /* We did not know the expected result */ + default: + break; + } + if (ret == 0) { /* The new thread is running */ + if (g_scenarii[g_testCount].detached == 0) { + ret = pthread_join(child, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + } else { + /* Just wait for the thread to terminate */ + do { + ret = sem_wait(&g_scenarii[g_testCount].sem); + } while ((ret == -1) && (errno == EINTR)); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + } + + /* The thread has terminated its work, so we can now control */ + ret = sigismember(&(tdThread.mask), SIGUSR1); + ICUNIT_ASSERT_EQUAL(ret, 1, ret); + + ret = sigismember(&(tdThread.mask), SIGUSR2); + ICUNIT_ASSERT_EQUAL(ret, 1, ret); + + ret = sigismember(&(tdThread.pending), SIGUSR1); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = sigismember(&(tdThread.pending), SIGUSR2); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + } + } + + ScenarFini(); + +#endif + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread127(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_127", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_129.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_129.cpp new file mode 100644 index 00000000..6b69c1bc --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_129.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(VOID *argument) +{ + pthread_exit(0); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + INT32 ret; + + ret = pthread_create(&newTh, NULL, pthread_f01, NULL); + ICUNIT_GOTO_EQUAL(ret, PTHREAD_NO_ERROR, errno, EXIT); + + ret = pthread_join(newTh, NULL); + ICUNIT_GOTO_EQUAL(ret, PTHREAD_NO_ERROR, errno, EXIT); + + return PTHREAD_NO_ERROR; + +EXIT: + pthread_join(newTh, NULL); + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread129(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_129", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_132.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_132.cpp new file mode 100644 index 00000000..f8cdc66c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_132.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(VOID *argument) +{ + g_newTh = pthread_self(); + + pthread_exit(0); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh1; + INT32 ret = 0; + + ret = pthread_create(&newTh1, NULL, pthread_f01, NULL); + ICUNIT_GOTO_EQUAL(ret, PTHREAD_NO_ERROR, ret, EXIT); + + ret = pthread_join(newTh1, NULL); + ICUNIT_GOTO_EQUAL(ret, PTHREAD_NO_ERROR, ret, EXIT); + + ret = pthread_equal(newTh1, g_newTh); + ICUNIT_GOTO_EQUAL(ret, 1, errno, EXIT); + + ret = pthread_equal(newTh1, TestPthreadSelf()); + ICUNIT_GOTO_EQUAL(ret, PTHREAD_NO_ERROR, ret, EXIT); + + return PTHREAD_NO_ERROR; +EXIT: + pthread_detach(g_newTh); + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread132(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_132", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_133.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_133.cpp new file mode 100644 index 00000000..06cc1295 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_133.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(VOID *argument) +{ + pthread_exit(0); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + INT32 ret = 0; + + ret = pthread_create(&newTh, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_equal(newTh, newTh); + ICUNIT_ASSERT_EQUAL(ret, 1, ret); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return PTHREAD_NO_ERROR; +} + + + +VOID ItPosixPthread133(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_133", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_134.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_134.cpp new file mode 100644 index 00000000..2054481c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_134.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(VOID *argument) +{ + pthread_exit(0); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh1, newTh2; + INT32 ret = 0; + + ret = pthread_create(&newTh1, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_create(&newTh2, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_equal(newTh1, newTh2); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(newTh1, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newTh2, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread134(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_134", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_136.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_136.cpp new file mode 100644 index 00000000..284c4250 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_136.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(VOID *argument) +{ + INT32 i; + + printf("Wait for 3 seconds for thread to finish execution:\n"); + for (i = 1; i < 4; i++) { + printf("Waited (%d) second\n", i); + sleep(1); + } + + g_testCount = 1; + + pthread_exit(0); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + INT32 ret = 0; + + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + return PTHREAD_NO_ERROR; +} + + + +VOID ItPosixPthread136(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_136", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_138.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_138.cpp new file mode 100644 index 00000000..322c6ae4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_138.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(VOID *argument) +{ + g_pthreadSem = PTHREAD_INMAIN_TEST; + pthread_exit(PTHREAD_EXIT_VALUE); + return NULL; +} + + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + VOID *valuePtr; + INT32 ret = 0; + + valuePtr = 0; + g_pthreadSem = PTHREAD_INTHREAD_TEST; + + ret = pthread_create(&newTh, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + /* Make sure the thread was created before we join it. */ + while (g_pthreadSem == PTHREAD_INTHREAD_TEST) { + sleep(1); + } + + ret = pthread_join(newTh, &valuePtr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + /* + * Check to make sure that 'value_ptr' that was passed to + * pthread_join() and the pthread_exit() return code that + * was used in the thread function are the same. + */ + ICUNIT_ASSERT_EQUAL(valuePtr, PTHREAD_EXIT_VALUE, errno); + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread138(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_138", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_141.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_141.cpp new file mode 100644 index 00000000..3157ff5d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_141.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(VOID *argument) +{ + pthread_exit(0); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + INT32 ret; + + ret = pthread_create(&newTh, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return PTHREAD_NO_ERROR; +} + + + +VOID ItPosixPthread141(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_141", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_142.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_142.cpp new file mode 100644 index 00000000..cc46f118 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_142.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(VOID *argument) +{ + pthread_exit(0); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + INT32 ret; + + ret = pthread_create(&newTh, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread142(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_142", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_144.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_144.cpp new file mode 100644 index 00000000..e3439635 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_144.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(VOID *argument) +{ + INT32 ret = 0; + + ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + /* If the thread wasn't canceled in 10 seconds, time out */ + LosTaskDelay(3); + + pthread_exit(0); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_attr_t newAttr; + pthread_t newTh; + INT32 ret; + + ret = pthread_attr_init(&newAttr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_setdetachstate(&newAttr, PTHREAD_CREATE_JOINABLE); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_create(&newTh, &newAttr, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_detach(newTh); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = LosTaskDelay(2); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_cancel(newTh); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread144(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_144", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_152.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_152.cpp new file mode 100644 index 00000000..d45a0bb6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_152.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static UINT32 Testcase(VOID) +{ + pthread_attr_t newAttr; + INT32 detachState, ret = 0; + ; + + /* Initialize attribute */ + ret = pthread_attr_init(&newAttr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + /* The test passes if the attribute object has a detachstate of + * PTHREAD_CREATE_JOINABLE, which is the default value for this + * attribute. */ + ret = pthread_attr_getdetachstate(&newAttr, &detachState); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(detachState, PTHREAD_CREATE_JOINABLE, detachState); + + ret = pthread_attr_destroy(&newAttr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + return 0; +} + + +VOID ItPosixPthread152(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_152", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_154.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_154.cpp new file mode 100644 index 00000000..f30be159 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_154.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(VOID *argument) +{ + pthread_exit(NULL); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newThreads[PTHREAD_THREADS_NUM]; + pthread_attr_t newAttr; + INT32 i, ret; + + ret = pthread_attr_init(&newAttr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + for (i = 0; i < PTHREAD_THREADS_NUM; i++) { + ret = pthread_create(&newThreads[i], &newAttr, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + } + + for (i = 0; i < PTHREAD_THREADS_NUM; i++) { + ret = pthread_join(newThreads[i], NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + } + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread154(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_154", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_166.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_166.cpp new file mode 100644 index 00000000..c64f4734 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_166.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(VOID *argument) +{ + pthread_exit(0); + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + pthread_attr_t newAttr; + INT32 ret; + + /* Initialize attribute */ + ret = pthread_attr_init(&newAttr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + /* Destroy attribute */ + ret = pthread_attr_destroy(&newAttr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + /* Creating a thread, passing to it the destroyed attribute, should + * result in an error value of EINVAL (invalid 'attr' value). */ + ret = pthread_create(&newTh, &newAttr, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread166(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_166", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_167.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_167.cpp new file mode 100644 index 00000000..1dbcca34 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_167.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static UINT32 Testcase(VOID) +{ + pthread_attr_t newAttr; + INT32 ret = PTHREAD_NO_ERROR; + + ret = pthread_attr_init(&newAttr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_destroy(&newAttr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_init(&newAttr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_destroy(&newAttr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread167(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_167", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_173.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_173.cpp new file mode 100644 index 00000000..852313bd --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_173.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static UINT32 Testcase(VOID) +{ + pthread_attr_t newAttr; + INT32 detachState, ret = PTHREAD_NO_ERROR; + + /* Initialize attribute */ + ret = pthread_attr_init(&newAttr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + /* The test passes if pthread_attr_getdetachstate gets the attribute + * of PTHREAD_CREATE_JOINABLE from the attribute object. */ + ret = pthread_attr_getdetachstate(&newAttr, &detachState); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(detachState, PTHREAD_CREATE_JOINABLE, detachState); + + ret = pthread_attr_destroy(&newAttr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread173(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_173", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_175.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_175.cpp new file mode 100644 index 00000000..c0dd0fe9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_175.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(VOID *argument) +{ + pthread_exit(PTHREAD_EXIT_VALUE); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + pthread_attr_t attr; + INT32 cscope; + INT32 ret; + + g_pthreadScopeValue = PTHREAD_SCOPE_PROCESS; + + /* Initialize attr */ + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, errno); + + ret = pthread_attr_setscope(&attr, g_pthreadScopeValue); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, errno); + + ret = pthread_create(&newTh, &attr, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, errno); + + ret = pthread_attr_getscope(&attr, &cscope); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, errno); + ICUNIT_ASSERT_EQUAL(cscope, g_pthreadScopeValue, cscope); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, errno); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, errno); + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread175(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_175", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_176.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_176.cpp new file mode 100644 index 00000000..f35df3cb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_176.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret = 0; + pthread_attr_t attr; + + g_pthreadScopeValue = 999; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_setscope(&attr, g_pthreadScopeValue); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, errno); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread176(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_176", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_177.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_177.cpp new file mode 100644 index 00000000..1b162b14 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_177.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret = PTHREAD_NO_ERROR; + INT32 rc2; + pthread_attr_t attr; + INT32 scope; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_getscope(&attr, &scope); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(scope, PTHREAD_SCOPE_PROCESS, scope); + + g_pthreadScopeValue = PTHREAD_SCOPE_SYSTEM; + ret = pthread_attr_setscope(&attr, g_pthreadScopeValue); + ICUNIT_ASSERT_EQUAL(ret, ENOTSUP, ret); + + ret = pthread_attr_getscope(&attr, &scope); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(scope, PTHREAD_SCOPE_PROCESS, scope); + + g_pthreadScopeValue = PTHREAD_SCOPE_PROCESS; + ret = pthread_attr_setscope(&attr, g_pthreadScopeValue); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_getscope(&attr, &scope); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(scope, PTHREAD_SCOPE_PROCESS, scope); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread177(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_177", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_182.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_182.cpp new file mode 100644 index 00000000..af4b67cf --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_182.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + + +static VOID *pthread_f01(void *tmp) +{ + struct sched_param param; + INT32 policy; + INT32 ret = PTHREAD_NO_ERROR; + + TestExtraTaskDelay(2); + LosTaskDelay(1); + + ret = pthread_getschedparam(pthread_self(), &policy, ¶m); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + if (policy == g_pthreadSchedPolicy) { + g_testCount = 1; + } + if (param.sched_priority == PTHREAD_PRIORITY_TEST) { + g_testCount--; + } + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_attr_t attr; + pthread_t threadId; + struct sched_param param; + INT32 ret = PTHREAD_NO_ERROR; + + g_pthreadSchedPolicy = SCHED_RR; + g_pthreadSchedInherit = PTHREAD_INHERIT_SCHED; + g_testCount = 0; + + param.sched_priority = PTHREAD_PRIORITY_TEST; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_setinheritsched(&attr, g_pthreadSchedInherit); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_create(&threadId, &attr, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_setschedparam(threadId, g_pthreadSchedPolicy, ¶m); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(threadId, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 0, g_testCount); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread182(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_182", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_185.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_185.cpp new file mode 100644 index 00000000..8f50e8f7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_185.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static UINT32 Testcase(VOID) +{ + INT32 ret = PTHREAD_NO_ERROR; + INT32 inheritsched; + pthread_attr_t attr; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_pthreadSchedInherit = PTHREAD_INHERIT_SCHED; + ret = pthread_attr_setinheritsched(&attr, g_pthreadSchedInherit); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_getinheritsched(&attr, &inheritsched); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(inheritsched, g_pthreadSchedInherit, inheritsched); + + g_pthreadSchedInherit = PTHREAD_EXPLICIT_SCHED; + ret = pthread_attr_setinheritsched(&attr, g_pthreadSchedInherit); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_getinheritsched(&attr, &inheritsched); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(inheritsched, g_pthreadSchedInherit, inheritsched); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread185(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_185", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_186.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_186.cpp new file mode 100644 index 00000000..c20fef28 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_186.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(VOID *data) +{ + pthread_t self; + struct sched_param schedparam; + struct params *paramTest = (struct params *)data; + INT32 policy; + INT32 ret; + + self = pthread_self(); + ret = pthread_getschedparam(self, &policy, &schedparam); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_TRACK_EQUAL(policy, paramTest->policy, policy); + ICUNIT_TRACK_EQUAL(schedparam.sched_priority, 10, schedparam.sched_priority); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + INT32 ret; + struct params paramTest; + pthread_t thread; + pthread_attr_t attr; + VOID *status; + struct sched_param schedparam; + + paramTest.policy = SCHED_OTHER; + paramTest.priority = PRIORITY_OTHER; + paramTest.policy_label = "SCHED_OTHER"; + paramTest.status = PTHREAD_NO_ERROR; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_pthreadSchedPolicy = SCHED_OTHER; + ret = pthread_attr_setschedpolicy(&attr, g_pthreadSchedPolicy); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + g_pthreadSchedInherit = PTHREAD_EXPLICIT_SCHED; + ret = pthread_attr_setinheritsched(&attr, g_pthreadSchedInherit); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + schedparam.sched_priority = paramTest.priority; + ret = pthread_attr_setschedparam(&attr, &schedparam); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + schedparam.sched_priority = 10; + ret = pthread_attr_setschedparam(&attr, &schedparam); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + paramTest.policy = SCHED_RR; + ret = pthread_create(&thread, &attr, pthread_f01, ¶mTest); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(thread, &status); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread186(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_186", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_187.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_187.cpp new file mode 100644 index 00000000..bacfa73c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_187.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(VOID *data) +{ + pthread_t self; + struct sched_param schedparam; + struct params *paramTest = (struct params *)data; + INT32 policy; + INT32 ret; + + self = pthread_self(); + ret = pthread_getschedparam(self, &policy, &schedparam); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_TRACK_EQUAL(policy, SCHED_FIFO, policy); + ICUNIT_TRACK_EQUAL(paramTest->priority, PRIORITY_FIFO, paramTest->priority); + ICUNIT_TRACK_EQUAL(schedparam.sched_priority, paramTest->priority, schedparam.sched_priority); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + INT32 ret; + struct params paramTest; + pthread_t thread; + pthread_attr_t attr; + VOID *status; + struct sched_param schedparam; + + paramTest.policy = SCHED_FIFO; + paramTest.priority = PRIORITY_FIFO; + paramTest.policy_label = "SCHED_FIFO"; + paramTest.status = LOS_NOK; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_pthreadSchedPolicy = SCHED_FIFO; + ret = pthread_attr_setschedpolicy(&attr, g_pthreadSchedPolicy); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + g_pthreadSchedInherit = PTHREAD_EXPLICIT_SCHED; + ret = pthread_attr_setinheritsched(&attr, g_pthreadSchedInherit); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + schedparam.sched_priority = paramTest.priority; + ret = pthread_attr_setschedparam(&attr, &schedparam); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_create(&thread, &attr, pthread_f01, ¶mTest); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(thread, &status); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread187(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_187", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_188.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_188.cpp new file mode 100644 index 00000000..bc0c49eb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_188.cpp @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(VOID *data) +{ + pthread_t self; + struct sched_param schedparam; + struct params *paramTest = (struct params *)data; + INT32 policy; + INT32 ret; + + self = pthread_self(); + ret = pthread_getschedparam(self, &policy, &schedparam); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_TRACK_EQUAL(policy, paramTest->policy, policy); + ICUNIT_TRACK_EQUAL(paramTest->priority, PRIORITY_RR, paramTest->priority); + ICUNIT_TRACK_EQUAL(schedparam.sched_priority, paramTest->priority, schedparam.sched_priority); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + INT32 ret; + struct params paramTest; + pthread_t thread; + pthread_attr_t attr; + VOID *status; + struct sched_param schedparam; + + paramTest.policy = SCHED_RR; + paramTest.priority = PRIORITY_RR; + paramTest.policy_label = "SCHED_RR"; + paramTest.status = PTHREAD_NO_ERROR; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_pthreadSchedPolicy = SCHED_OTHER; + ret = pthread_attr_setschedpolicy(&attr, g_pthreadSchedPolicy); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + g_pthreadSchedPolicy = SCHED_RR; + ret = pthread_attr_setschedpolicy(&attr, g_pthreadSchedPolicy); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_pthreadSchedInherit = PTHREAD_EXPLICIT_SCHED; + ret = pthread_attr_setinheritsched(&attr, g_pthreadSchedInherit); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + schedparam.sched_priority = paramTest.priority; + if (paramTest.priority != PRIORITY_OTHER) { + ret = pthread_attr_setschedparam(&attr, &schedparam); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + } + + ret = pthread_create(&thread, &attr, pthread_f01, ¶mTest); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(thread, &status); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread188(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_188", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_193.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_193.cpp new file mode 100644 index 00000000..1bc2b059 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_193.cpp @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(VOID *argument) +{ + LosTaskDelay(1); + + g_testCount = 1; + + pthread_exit(PTHREAD_NO_ERROR); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t thread; + pthread_attr_t attr; + INT32 ret = PTHREAD_NO_ERROR; + struct sched_param param; + INT32 priority = 31; + + g_testCount = 0; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_pthreadSchedPolicy = SCHED_OTHER; + ret = pthread_attr_setschedpolicy(&attr, g_pthreadSchedPolicy); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + g_pthreadSchedPolicy = -1; + priority = sched_get_priority_max(g_pthreadSchedPolicy); + ICUNIT_ASSERT_EQUAL(priority, -1, priority); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno); + + g_pthreadSchedPolicy = 4; + priority = sched_get_priority_max(g_pthreadSchedPolicy); + ICUNIT_ASSERT_EQUAL(priority, -1, priority); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno); + + g_pthreadSchedPolicy = SCHED_OTHER; + priority = sched_get_priority_max(g_pthreadSchedPolicy); + ICUNIT_ASSERT_EQUAL(priority, -1, priority); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno); + + priority = 31; + param.sched_priority = priority + 1; + ret = pthread_attr_setschedparam(&attr, ¶m); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_create(&thread, &attr, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(thread, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread193(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_193", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_194.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_194.cpp new file mode 100644 index 00000000..e8b012ac --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_194.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(VOID *argument) +{ + g_testCount = 1; + + pthread_exit(PTHREAD_NO_ERROR); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t thread; + pthread_attr_t attr; + INT32 ret = PTHREAD_NO_ERROR; + struct sched_param param; + INT32 priority; + + g_testCount = 0; + + /* use delay to reset timelsice to prevent created task get + to run before expected */ + LosTaskDelay(1); + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_pthreadSchedPolicy = SCHED_RR; + ret = pthread_attr_setschedpolicy(&attr, g_pthreadSchedPolicy); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + priority = sched_get_priority_max(g_pthreadSchedPolicy); + ICUNIT_ASSERT_NOT_EQUAL(priority, -1, priority); + + param.sched_priority = priority; + ret = pthread_attr_setschedparam(&attr, ¶m); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_create(&thread, &attr, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(thread, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread194(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_194", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_200.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_200.cpp new file mode 100644 index 00000000..71afbaa6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_200.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(VOID *arg) +{ + pthread_exit(PTHREAD_NO_ERROR); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + pthread_attr_t attr; + size_t stackSize = PTHREAD_STACK_MIN; + size_t ssize; + INT32 ret; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_getstacksize(&attr, &ssize); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(ssize, 0x20000, ssize); + + ret = pthread_attr_setstacksize(&attr, stackSize); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_getstacksize(&attr, &ssize); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(ssize, stackSize, ssize); + + ret = pthread_create(&newTh, &attr, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread200(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_200", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_203.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_203.cpp new file mode 100644 index 00000000..ba8e7f39 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_203.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static int Testcase(void) +{ + int ret; + + ret = pthread_setconcurrency(0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_getconcurrency(); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_setconcurrency(-1); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_setconcurrency(1); + ICUNIT_ASSERT_EQUAL(ret, EAGAIN, ret); + + return 0; +} + +VOID ItPosixPthread203(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_203", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL0, TEST_FUNCTION); +} \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_204.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_204.cpp new file mode 100644 index 00000000..91962e00 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_204.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(VOID *argument) +{ + struct sched_param sparam; + INT32 priority, policy; + INT32 ret; + + g_pthreadSchedPolicy = SCHED_RR; + +#ifdef LOSCFG_KERNEL_TICKLESS + priority = sched_get_priority_max(g_pthreadSchedPolicy) - 1; +#else + priority = sched_get_priority_max(g_pthreadSchedPolicy); +#endif + + sparam.sched_priority = priority; + + ret = pthread_setschedparam(pthread_self(), g_pthreadSchedPolicy, &sparam); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_getschedparam(pthread_self(), &policy, &sparam); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_TRACK_EQUAL(policy, g_pthreadSchedPolicy, policy); + ICUNIT_TRACK_EQUAL(sparam.sched_priority, priority, sparam.sched_priority); + + pthread_exit(0); + + return NULL; +} + + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + INT32 ret = PTHREAD_NO_ERROR; + + ret = pthread_create(&newTh, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return PTHREAD_NO_ERROR; +} + + + +VOID ItPosixPthread204(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_204", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_205.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_205.cpp new file mode 100644 index 00000000..fbb96e56 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_205.cpp @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(VOID *arg) +{ + INT32 ret = 0; + INT32 policy; + INT32 priority; + struct sched_param schedparam; + + LosTaskDelay(2); + +#ifdef LOSCFG_KERNEL_TICKLESS + priority = sched_get_priority_max(SCHED_RR) - 1; +#else + priority = sched_get_priority_max(SCHED_RR); // priority = 31 +#endif + + ret = pthread_getschedparam(pthread_self(), &policy, &schedparam); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_TRACK_EQUAL(policy, SCHED_RR, policy); + ICUNIT_TRACK_EQUAL(schedparam.sched_priority, priority, schedparam.sched_priority); + + return NULL; +} + +static VOID *pthread_f02(VOID *arg) +{ + INT32 ret = 0; + struct sched_param schedparam; +#ifdef LOSCFG_KERNEL_TICKLESS + schedparam.sched_priority = sched_get_priority_max(SCHED_RR) - 1; + ICUNIT_TRACK_EQUAL(schedparam.sched_priority, OS_TASK_PRIORITY_LOWEST - 1, schedparam.sched_priority); +#else + schedparam.sched_priority = sched_get_priority_max(SCHED_RR); // priority = 31 + ICUNIT_TRACK_EQUAL(schedparam.sched_priority, OS_TASK_PRIORITY_LOWEST, schedparam.sched_priority); +#endif + + ret = pthread_setschedparam(*(pthread_t *)arg, SCHED_RR, &schedparam); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + INT32 ret = 0; + pthread_t newTh1, newTh2; + pthread_attr_t attr; + INT32 bar; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_pthreadSchedInherit = PTHREAD_EXPLICIT_SCHED; + ret = pthread_attr_setinheritsched(&attr, g_pthreadSchedInherit); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + LOS_TaskLock(); + ret = pthread_create(&newTh1, &attr, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_create(&newTh2, &attr, pthread_f02, &newTh1); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + LOS_TaskUnlock(); + + ret = pthread_join(newTh2, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(newTh1, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread205(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_205", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_206.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_206.cpp new file mode 100644 index 00000000..9718f8a8 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_206.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static void *pthread_f01(void *arg) +{ + INT32 ret = 0; + INT32 policy; + struct sched_param schedparam; + struct sched_param schedparam1; + + g_pthreadSchedPolicy = SCHED_RR; + + schedparam.sched_priority = sched_get_priority_min(g_pthreadSchedPolicy); + + ret = pthread_setschedparam(pthread_self(), g_pthreadSchedPolicy, &schedparam); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + policy = SCHED_RR; + ret = pthread_getschedparam(pthread_self(), &policy, &schedparam1); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_TRACK_EQUAL(policy, g_pthreadSchedPolicy, policy); + ICUNIT_TRACK_EQUAL(schedparam1.sched_priority, schedparam.sched_priority, schedparam1.sched_priority); + + /* Now set the priority to an invalid value. */ + schedparam.sched_priority++; + + ret = pthread_setschedparam(pthread_self(), SCHED_RR, &schedparam); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + policy = SCHED_RR; + ret = pthread_getschedparam(pthread_self(), &policy, &schedparam1); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_TRACK_EQUAL(policy, g_pthreadSchedPolicy, policy); + ICUNIT_TRACK_EQUAL(schedparam1.sched_priority, schedparam.sched_priority, schedparam1.sched_priority); + + return NULL; +} + +static UINT32 Testcase(VOID) +{ + INT32 ret = 0; + pthread_attr_t attr; + pthread_t newTh1; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_pthreadSchedInherit = PTHREAD_EXPLICIT_SCHED; + ret = pthread_attr_setinheritsched(&attr, g_pthreadSchedInherit); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_create(&newTh1, &attr, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(newTh1, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread206(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_206", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_209.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_209.cpp new file mode 100644 index 00000000..4286ca9a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_209.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(VOID *argument) +{ + struct sched_param sparam; + INT32 policy, priority; + INT32 ret; + + g_pthreadSchedPolicy = SCHED_RR; + +#ifdef LOSCFG_KERNEL_TICKLESS + priority = sched_get_priority_max(g_pthreadSchedPolicy) - 1; +#else + priority = sched_get_priority_max(g_pthreadSchedPolicy); +#endif + + sparam.sched_priority = priority; + + ret = pthread_setschedparam(pthread_self(), g_pthreadSchedPolicy, &sparam); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_getschedparam(pthread_self(), &policy, &sparam); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_TRACK_EQUAL(policy, g_pthreadSchedPolicy, policy); + +#ifdef LOSCFG_KERNEL_TICKLESS + ICUNIT_TRACK_EQUAL(sparam.sched_priority, USER_PROCESS_PRIORITY_LOWEST - 1, sparam.sched_priority); +#else + ICUNIT_TRACK_EQUAL(sparam.sched_priority, USER_PROCESS_PRIORITY_LOWEST, sparam.sched_priority); +#endif + + return NULL; +} + + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + pthread_attr_t attr; + INT32 ret; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_pthreadSchedInherit = PTHREAD_EXPLICIT_SCHED; + ret = pthread_attr_setinheritsched(&attr, g_pthreadSchedInherit); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_create(&newTh, &attr, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread209(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_209", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_213.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_213.cpp new file mode 100644 index 00000000..b45d167a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_213.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID pthread_f02(VOID) +{ + INT32 ret = 0; + ret = pthread_mutex_lock(&g_pthreadMutexTest1); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_testCount++; + + ret = pthread_mutex_unlock(&g_pthreadMutexTest1); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return; +} + +static VOID *pthread_f01(VOID *arg) +{ + INT32 ret; + + ret = pthread_once((pthread_once_t *)arg, pthread_f02); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return NULL; +} + + +static UINT32 Testcase(VOID) +{ + INT32 ret, i; + + pthread_once_t myctl[PTHREAD_THREADS_NUM] = {PTHREAD_ONCE_INIT, }; + + pthread_t th[PTHREAD_THREADS_NUM]; + + g_pthreadMutexTest1 = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER; + + g_testCount = 0; + + for (i = 0; i < PTHREAD_THREADS_NUM; i++) { + ret = pthread_create(&th[i], NULL, pthread_f01, &myctl[i]); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + } + + for (i = 0; i < PTHREAD_THREADS_NUM; i++) { + ret = pthread_join(th[i], NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + } + + ret = pthread_mutex_lock(&g_pthreadMutexTest1); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ICUNIT_ASSERT_EQUAL(g_testCount, 3, g_testCount); + + ret = pthread_mutex_unlock(&g_pthreadMutexTest1); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread213(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_213", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_217.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_217.cpp new file mode 100644 index 00000000..e88bc1fa --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_217.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static UINT32 Testcase(VOID) +{ + INT32 i, ret = 0; + const INT32 keyValue = 0; + VOID *specific; + + for (i = 0; i < PTHREAD_KEY_NUM; i++) { + ret = pthread_key_create(&g_pthreadKeyTest[i], NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_setspecific(g_pthreadKeyTest[i], (VOID *)(long)(i + keyValue)); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + } + + for (i = 0; i < PTHREAD_KEY_NUM; ++i) { + specific = pthread_getspecific(g_pthreadKeyTest[i]); + ICUNIT_ASSERT_EQUAL(specific, (VOID *)(long)(i + keyValue), specific); + + ret = pthread_key_delete(g_pthreadKeyTest[i]); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + } + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread217(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_217", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_218.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_218.cpp new file mode 100644 index 00000000..0858a627 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_218.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(VOID *argument) +{ + INT32 ret = 0; + const INT32 keyValue = 1000; + + ret = pthread_setspecific(g_pthreadKeyTest[g_testCount], (const void *)(keyValue)); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + pthread_exit(0); + + return NULL; +} + + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + VOID *valuePtr; + INT32 ret = 0; + + g_testCount = 0; + + for (g_testCount = 0; g_testCount < PTHREAD_KEY_NUM; g_testCount++) { + ret = pthread_key_create(&g_pthreadKeyTest[g_testCount], NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + } + + for (g_testCount = 0; g_testCount < PTHREAD_KEY_NUM; g_testCount++) { + ret = pthread_create(&newTh, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(newTh, &valuePtr); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(valuePtr, 0, valuePtr); + } + + for (g_testCount = 0; g_testCount < PTHREAD_KEY_NUM; g_testCount++) { + ret = pthread_key_delete(g_pthreadKeyTest[g_testCount]); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + } + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread218(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_218", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_219.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_219.cpp new file mode 100644 index 00000000..3a036f6d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_219.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static UINT32 Testcase(VOID) +{ + pthread_key_t key; + VOID *specific; + INT32 ret = 0; + + specific = pthread_getspecific(key); + ICUNIT_ASSERT_EQUAL(specific, NULL, specific); + + ret = pthread_key_create(&key, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + specific = pthread_getspecific(key); + ICUNIT_ASSERT_EQUAL(specific, NULL, specific); + + ret = pthread_key_delete(key); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread219(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_219", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_221.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_221.cpp new file mode 100644 index 00000000..cb7a065b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_221.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static UINT32 Testcase(VOID) +{ + INT32 i, ret; + pthread_key_t keysMax[PTHREAD_KEYS_MAX]; + + for (i = 0; i < PTHREAD_KEYS_MAX; i++) { + ret = pthread_key_create(&keysMax[i], NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + } + + for (i = 0; i < PTHREAD_KEYS_MAX; i++) { + ret = pthread_key_delete(keysMax[i]); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + } + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread221(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_221", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_224.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_224.cpp new file mode 100644 index 00000000..aa63d7cf --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_224.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID pthread_f02(VOID *p) +{ + INT32 ret = 0; + + g_testCount++; + + ret = pthread_key_delete(g_key); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); +} + +static VOID *pthread_f01(VOID *argument) +{ + INT32 ret = 0; + const INT32 keyValue = 1000; + + ret = pthread_setspecific(g_key, (void *)(keyValue)); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + pthread_exit(0); + + return NULL; +} + + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + INT32 ret = 0; + + g_testCount = 0; + + + ret = pthread_key_create(&g_key, pthread_f02); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_create(&newTh, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread224(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_224", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_226.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_226.cpp new file mode 100644 index 00000000..1393d6b8 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_226.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static const INT32 key_value1 = 100; +static const INT32 key_value2 = 200; + +static VOID *g_specific1; +static VOID *g_specific2; + +static VOID *pthread_f01(VOID *argument) +{ + INT32 ret = 0; + + /* Bind a value to key for this thread (this will be different from the value + * that we bind for the main thread) */ + ret = pthread_setspecific(g_key, (void *)(key_value2)); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + /* Get the bound value of the key that we just set. */ + g_specific2 = pthread_getspecific(g_key); + + pthread_exit(0); + + return NULL; +} + + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + INT32 ret = 0; + + ret = pthread_key_create(&g_key, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_setspecific(g_key, (void *)(key_value1)); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_create(&newTh, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_specific1 = pthread_getspecific(g_key); + + ICUNIT_ASSERT_EQUAL(g_specific1, (void *)(key_value1), g_specific1); + ICUNIT_ASSERT_EQUAL(g_specific2, (void *)(key_value2), g_specific2); + + ret = pthread_key_delete(g_key); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread226(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_226", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_233.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_233.cpp new file mode 100644 index 00000000..09619dfc --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_233.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID pthread_f02(VOID *tmp) +{ + g_testCount = 1; +} + +static VOID *pthread_f01(VOID *tmp) +{ + pthread_key_t key; + INT32 value = 1; + INT32 ret = 0; + + ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_key_create(&key, pthread_f02); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_setspecific(key, &value); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_pthreadSem = 1; + + while (1) { + sleep(5); + } + return NULL; +} + + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + INT32 ret = 0; + + g_testCount = 0; + g_pthreadSem = 0; + + ret = pthread_create(&newTh, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + while (g_pthreadSem == 0) { + sleep(1); + } + + ret = pthread_cancel(newTh); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = pthread_key_delete(g_key); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread233(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_233", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_238.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_238.cpp new file mode 100644 index 00000000..d07bb99e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_238.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(VOID *argument) +{ + INT32 ret = 0; + + ret = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_testCount = 1; + + g_pthreadSem = PTHREAD_INMAIN_TEST; + + while (g_pthreadSem == PTHREAD_INMAIN_TEST) { + sleep(1); + } + + pthread_testcancel(); + + g_testCount = -1; + pthread_exit(0); + return NULL; +} + + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + INT32 ret = 0; + + g_pthreadSem = PTHREAD_INTHREAD_TEST; + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + while (g_pthreadSem == PTHREAD_INTHREAD_TEST) { + sleep(1); + } + + ret = pthread_cancel(newTh); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_pthreadSem = PTHREAD_INTHREAD_TEST; + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread238(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_238", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_239.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_239.cpp new file mode 100644 index 00000000..a40642ca --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_239.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(VOID *argument) +{ + INT32 ret = 0; + + ret = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_testCount = -1; + + g_pthreadSem = PTHREAD_INMAIN_TEST; + + while (g_pthreadSem == PTHREAD_INMAIN_TEST) { + sleep(1); + } + + pthread_testcancel(); + + g_testCount = 1; + pthread_exit(0); + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + INT32 ret = 0; + + g_pthreadSem = PTHREAD_INTHREAD_TEST; + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + while (g_pthreadSem == PTHREAD_INTHREAD_TEST) { + sleep(1); + } + + ret = pthread_cancel(newTh); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_pthreadSem = PTHREAD_INTHREAD_TEST; + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread239(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_239", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_240.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_240.cpp new file mode 100644 index 00000000..77ea3fdc --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_240.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(VOID *argument) +{ + INT32 ret = 0; + + ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_testCount = 1; + + g_pthreadSem = PTHREAD_INMAIN_TEST; + + while (g_pthreadSem == PTHREAD_INMAIN_TEST) { + sleep(1); + } + + pthread_testcancel(); + + g_testCount = -1; + + pthread_exit(0); + return NULL; +} + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + INT32 ret = 0; + + g_pthreadSem = PTHREAD_INTHREAD_TEST; + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + while (g_pthreadSem == PTHREAD_INTHREAD_TEST) { + sleep(1); + } + + ret = pthread_cancel(newTh); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + g_pthreadSem = PTHREAD_INTHREAD_TEST; + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread240(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_240", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_241.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_241.cpp new file mode 100644 index 00000000..62395de1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/full/It_posix_pthread_241.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(VOID *argument) +{ + INT32 ret = 0; + + g_testCount++; + + ret = pthread_setcancelstate(-100, NULL); + ICUNIT_TRACK_EQUAL(ret, EINVAL, ret); + + pthread_exit(0); + + return NULL; +} + + +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + INT32 ret = 0; + + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, pthread_f01, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + return PTHREAD_NO_ERROR; +} + + +VOID ItPosixPthread241(VOID) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_241", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/posix_pthread_test.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/posix_pthread_test.cpp new file mode 100644 index 00000000..b9bc707b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/posix_pthread_test.cpp @@ -0,0 +1,1317 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "stdio.h" +#include +#include + + +#include "It_posix_pthread.h" + +pthread_key_t g_key; +pthread_key_t g_key1; +pthread_key_t g_key2; +pthread_key_t g_pthreadKeyTest[PTHREAD_KEY_NUM]; +pthread_t g_newTh; +pthread_t g_newTh2; +UINT32 g_taskMaxNum = LOSCFG_BASE_CORE_TSK_CONFIG; +pthread_once_t g_onceControl = PTHREAD_ONCE_INIT; +pthread_cond_t g_pthreadCondTest1 = PTHREAD_COND_INITIALIZER; +pthread_mutex_t g_pthreadMutexTest1 = PTHREAD_MUTEX_INITIALIZER; +pthread_mutex_t g_pthreadMutexTest2 = PTHREAD_MUTEX_INITIALIZER; +INT32 g_startNum = 0; +INT32 g_wakenNum = 0; +INT32 g_t1Start = 0; +INT32 g_signaled = 0; +INT32 g_wokenUp = -1; +INT32 g_lowDone = -1; +INT32 g_pthreadSem = 0; /* Manual semaphore */ +INT32 g_pthreadScopeValue = 0; +INT32 g_pthreadSchedInherit = 0; +INT32 g_pthreadSchedPolicy = 0; +struct testdata g_td; + +sem_t g_pthreadSem1; +sem_t g_pthreadSem2; + +__scenario g_scenarii[] = { + CASE_POS(0, 0, 0, 0, 0, 0, 0, 0, const_cast("default")), + CASE_POS(1, 0, 0, 0, 0, 0, 0, 0, const_cast("detached")), + CASE_POS(0, 1, 0, 0, 0, 0, 0, 0, const_cast("Explicit sched")), + CASE_UNK(0, 0, 1, 0, 0, 0, 0, 0, const_cast("FIFO Policy")), + CASE_UNK(0, 0, 2, 0, 0, 0, 0, 0, const_cast("RR Policy")), + CASE_UNK(0, 0, 0, 1, 0, 0, 0, 0, const_cast("Max sched param")), + CASE_UNK(0, 0, 0, -1, 0, 0, 0, 0, const_cast("Min sched param")), + CASE_POS(0, 0, 0, 0, 1, 0, 0, 0, const_cast("Alternative contension scope")), + CASE_POS(0, 0, 0, 0, 0, 1, 0, 0, const_cast("Alternative stack")), + CASE_POS(0, 0, 0, 0, 0, 0, 1, 0, const_cast("No guard size")), + CASE_UNK(0, 0, 0, 0, 0, 0, 2, 0, const_cast("1p guard size")), + CASE_POS(0, 0, 0, 0, 0, 0, 0, 1, const_cast("Min stack size")), + /* Stack play */ + CASE_POS(0, 0, 0, 0, 0, 0, 1, 1, const_cast("Min stack size, no guard")), + CASE_UNK(0, 0, 0, 0, 0, 0, 2, 1, const_cast("Min stack size, 1p guard")), + CASE_POS(1, 0, 0, 0, 0, 1, 0, 0, const_cast("Detached, Alternative stack")), + CASE_POS(1, 0, 0, 0, 0, 0, 1, 1, const_cast("Detached, Min stack size, no guard")), + CASE_UNK(1, 0, 0, 0, 0, 0, 2, 1, const_cast("Detached, Min stack size, 1p guard")), +}; + +pthread_t g_pthreadTestTh; + +VOID ScenarInit(VOID) +{ + INT32 ret = 0; + UINT32 i; + INT32 old; + long pagesize, minstacksize; + long tsa, tss, tps; + + pagesize = sysconf(_SC_PAGESIZE); + minstacksize = sysconf(_SC_THREAD_STACK_MIN); + tsa = sysconf(_SC_THREAD_ATTR_STACKADDR); + tss = sysconf(_SC_THREAD_ATTR_STACKSIZE); + tps = sysconf(_SC_THREAD_PRIORITY_SCHEDULING); + + if (minstacksize % pagesize) + ICUNIT_ASSERT_EQUAL_VOID(1, 0, errno); + + for (i = 0; i < NSCENAR; i++) { + ret = pthread_attr_init(&g_scenarii[i].ta); + ICUNIT_ASSERT_EQUAL_VOID(ret, PTHREAD_NO_ERROR, ret); + + if (g_scenarii[i].detached == 1) { + ret = pthread_attr_setdetachstate(&g_scenarii[i].ta, PTHREAD_CREATE_DETACHED); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_getdetachstate(&g_scenarii[i].ta, &old); + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + ICUNIT_TRACK_EQUAL(old, PTHREAD_CREATE_JOINABLE, old); + } + + /* Sched related attributes */ + /* + * This routine is dependent on the Thread Execution + * Scheduling option + */ + if (tps > 0) { + if (g_scenarii[i].explicitsched == 1) + ret = pthread_attr_setinheritsched(&g_scenarii[i].ta, PTHREAD_EXPLICIT_SCHED); + else + ret = pthread_attr_setinheritsched(&g_scenarii[i].ta, PTHREAD_INHERIT_SCHED); + + ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret); + } + + if (tps > 0) { + if (g_scenarii[i].schedpolicy == 1) + ret = pthread_attr_setschedpolicy(&g_scenarii[i].ta, SCHED_FIFO); + if (g_scenarii[i].schedpolicy == 2) + ret = pthread_attr_setschedpolicy(&g_scenarii[i].ta, SCHED_RR); + ICUNIT_ASSERT_EQUAL_VOID(ret, PTHREAD_NO_ERROR, ret); + + if (g_scenarii[i].schedparam != 0) { + struct sched_param sp; + + ret = pthread_attr_getschedpolicy(&g_scenarii[i].ta, &old); + ICUNIT_ASSERT_EQUAL_VOID(ret, PTHREAD_NO_ERROR, ret); + + if (g_scenarii[i].schedparam == 1) + sp.sched_priority = sched_get_priority_min(old); + if (g_scenarii[i].schedparam == -1) + sp.sched_priority = sched_get_priority_max(old); + + ret = pthread_attr_setschedparam(&g_scenarii[i].ta, &sp); + ICUNIT_ASSERT_EQUAL_VOID(ret, PTHREAD_NO_ERROR, ret); + } + + if (tps > 0) { + ret = pthread_attr_getscope(&g_scenarii[i].ta, &old); + ICUNIT_ASSERT_EQUAL_VOID(ret, PTHREAD_NO_ERROR, ret); + + if (g_scenarii[i].altscope != 0) { + if (old == PTHREAD_SCOPE_PROCESS) + old = PTHREAD_SCOPE_SYSTEM; + else + old = PTHREAD_SCOPE_PROCESS; + + ret = pthread_attr_setscope(&g_scenarii[i].ta, old); + } + } + + if ((tss > 0) && (tsa > 0)) { + if (g_scenarii[i].altstack != 0) { + g_scenarii[i].bottom = malloc(minstacksize + pagesize); + ICUNIT_TRACK_NOT_EQUAL(g_scenarii[i].bottom, NULL, g_scenarii[i].bottom); + } + } + + + if (tss > 0) { + if (g_scenarii[i].altsize != 0) { + ret = pthread_attr_setstacksize(&g_scenarii[i].ta, minstacksize); + ICUNIT_ASSERT_EQUAL_VOID(ret, PTHREAD_NO_ERROR, ret); + } + } + + ret = sem_init(&g_scenarii[i].sem, 0, 0); + ICUNIT_ASSERT_EQUAL_VOID(ret, PTHREAD_NO_ERROR, ret); + } + } +} +/* + * This function will free all resources consumed + * in the scenar_init() routine + */ +VOID ScenarFini(VOID) +{ + INT32 ret = 0; + UINT32 i; + + for (i = 0; i < NSCENAR; i++) { + if (g_scenarii[i].bottom != NULL) + free(g_scenarii[i].bottom); + + ret = sem_destroy(&g_scenarii[i].sem); + ICUNIT_ASSERT_EQUAL_VOID(ret, PTHREAD_NO_ERROR, ret); + + ret = pthread_attr_destroy(&g_scenarii[i].ta); + ICUNIT_ASSERT_EQUAL_VOID(ret, PTHREAD_NO_ERROR, ret); + } +} + +/* + * return value of pthread_self() is 0 when + * pthread create from LOS_TaskCreate() + */ +pthread_t TestPthreadSelf(void) +{ + pthread_t tid = pthread_self(); + return tid; +} +UINT32 TaskCountGetTest(VOID) +{ + // not implemented + return 0; +} +using namespace testing::ext; +namespace OHOS { +class PosixPthreadTest : public testing::Test { +public: + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} +}; + +#if defined(LOSCFG_USER_TEST_SMOKE) +/** + * @tc.name: IT_POSIX_PTHREAD_003 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread003, TestSize.Level0) +{ + ItPosixPthread003(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_004 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread004, TestSize.Level0) +{ + ItPosixPthread004(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_005 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread005, TestSize.Level0) +{ + ItPosixPthread005(); // pthread_cancel +} + +/** + * @tc.name: IT_POSIX_PTHREAD_006 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread006, TestSize.Level0) +{ + ItPosixPthread006(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_018 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread018, TestSize.Level0) +{ + ItPosixPthread018(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_019 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread019, TestSize.Level0) +{ + ItPosixPthread019(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_020 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread020, TestSize.Level0) +{ + ItPosixPthread020(); // pthread_key_delete +} + +/** + * @tc.name: IT_POSIX_PTHREAD_021 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread021, TestSize.Level0) +{ + ItPosixPthread021(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_022 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread022, TestSize.Level0) +{ + ItPosixPthread022(); // pthread_cancel +} + +#endif + +#if defined(LOSCFG_USER_TEST_FULL) +/** + * @tc.name: IT_POSIX_PTHREAD_001 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread001, TestSize.Level0) +{ + ItPosixPthread001(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_002 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread002, TestSize.Level0) +{ + ItPosixPthread002(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_007 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread007, TestSize.Level0) +{ + ItPosixPthread007(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_010 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread010, TestSize.Level0) +{ + ItPosixPthread010(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_011 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread011, TestSize.Level0) +{ + ItPosixPthread011(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_013 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread013, TestSize.Level0) +{ + ItPosixPthread013(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_023 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread023, TestSize.Level0) +{ + ItPosixPthread023(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_025 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread025, TestSize.Level0) +{ + ItPosixPthread025(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_026 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread026, TestSize.Level0) +{ + ItPosixPthread026(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_027 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread027, TestSize.Level0) +{ + ItPosixPthread027(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_028 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread028, TestSize.Level0) +{ + ItPosixPthread028(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_029 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread029, TestSize.Level0) +{ + ItPosixPthread029(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_030 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread030, TestSize.Level0) +{ + ItPosixPthread030(); // pthread_cancel +} + +/** + * @tc.name: IT_POSIX_PTHREAD_031 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread031, TestSize.Level0) +{ + ItPosixPthread031(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_034 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread034, TestSize.Level0) +{ + ItPosixPthread034(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_035 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread035, TestSize.Level0) +{ + ItPosixPthread035(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_039 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread039, TestSize.Level0) +{ + ItPosixPthread039(); // pthread_cancel +} + +/** + * @tc.name: IT_POSIX_PTHREAD_040 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread040, TestSize.Level0) +{ + ItPosixPthread040(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_042 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread042, TestSize.Level0) +{ + ItPosixPthread042(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_044 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread044, TestSize.Level0) +{ + ItPosixPthread044(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_045 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread045, TestSize.Level0) +{ + ItPosixPthread045(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_046 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread046, TestSize.Level0) +{ + ItPosixPthread046(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_051 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread051, TestSize.Level0) +{ + ItPosixPthread051(); // pthread_cancel +} + +/** + * @tc.name: IT_POSIX_PTHREAD_052 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread052, TestSize.Level0) +{ + ItPosixPthread052(); // pthread_key_delete +} + +/** + * @tc.name: IT_POSIX_PTHREAD_053 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread053, TestSize.Level0) +{ + ItPosixPthread053(); // pthread_key_delete +} + +/** + * @tc.name: IT_POSIX_PTHREAD_054 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread054, TestSize.Level0) +{ + ItPosixPthread054(); // pthread_key_delete +} + +/** + * @tc.name: IT_POSIX_PTHREAD_055 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread055, TestSize.Level0) +{ + ItPosixPthread055(); // pthread_key_delete and pthread_cancel +} + +/** + * @tc.name: IT_POSIX_PTHREAD_057 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread057, TestSize.Level0) +{ + ItPosixPthread057(); // pthread_cancel +} + +/** + * @tc.name: IT_POSIX_PTHREAD_059 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread059, TestSize.Level0) +{ + ItPosixPthread059(); // pthread_cancel +} + +/** + * @tc.name: IT_POSIX_PTHREAD_060 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread060, TestSize.Level0) +{ + ItPosixPthread060(); // pthread_cancel +} + +/** + * @tc.name: IT_POSIX_PTHREAD_069 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread069, TestSize.Level0) +{ + ItPosixPthread069(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_070 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread070, TestSize.Level0) +{ + ItPosixPthread070(); // bug:pthread_cond_init +} + +/** + * @tc.name: IT_POSIX_PTHREAD_071 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread071, TestSize.Level0) +{ + ItPosixPthread071(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_072 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread072, TestSize.Level0) +{ + ItPosixPthread072(); // pthread_cond_destroy doesn't fully support +} + +/** + * @tc.name: IT_POSIX_PTHREAD_073 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread073, TestSize.Level0) +{ + ItPosixPthread073(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_074 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread074, TestSize.Level0) +{ + ItPosixPthread074(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_078 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread078, TestSize.Level0) +{ + ItPosixPthread078(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_079 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread079, TestSize.Level0) +{ + ItPosixPthread079(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_080 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread080, TestSize.Level0) +{ + ItPosixPthread080(); // pthread_cond +} + +/** + * @tc.name: IT_POSIX_PTHREAD_081 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread081, TestSize.Level0) +{ + ItPosixPthread081(); // pthread_cond +} + +/** + * @tc.name: IT_POSIX_PTHREAD_082 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread082, TestSize.Level0) +{ + ItPosixPthread082(); // pthread_cond +} + +/** + * @tc.name: IT_POSIX_PTHREAD_083 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread083, TestSize.Level0) +{ + ItPosixPthread083(); // pthread_cond +} + +/** + * @tc.name: IT_POSIX_PTHREAD_084 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread084, TestSize.Level0) +{ + ItPosixPthread084(); // pthread_cond +} + +/** + * @tc.name: IT_POSIX_PTHREAD_085 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread085, TestSize.Level0) +{ + ItPosixPthread085(); // pthread_cond +} + +/** + * @tc.name: IT_POSIX_PTHREAD_087 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread087, TestSize.Level0) +{ + ItPosixPthread087(); // pthread_cond +} + +/** + * @tc.name: IT_POSIX_PTHREAD_088 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread088, TestSize.Level0) +{ + ItPosixPthread088(); // pthread_cond +} + +/** + * @tc.name: IT_POSIX_PTHREAD_089 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread089, TestSize.Level0) +{ + ItPosixPthread089(); // pthread_cond +} + +/** + * @tc.name: IT_POSIX_PTHREAD_090 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread090, TestSize.Level0) +{ + ItPosixPthread090(); // pthread_cond +} + +/** + * @tc.name: IT_POSIX_PTHREAD_092 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread092, TestSize.Level0) +{ + ItPosixPthread092(); // pthread_cond +} + +/** + * @tc.name: IT_POSIX_PTHREAD_091 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread091, TestSize.Level0) +{ + ItPosixPthread091(); // pthread_cancel +} + +#ifndef LOSCFG_USER_TEST_SMP +/** + * @tc.name: IT_POSIX_PTHREAD_094 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread094, TestSize.Level0) +{ + ItPosixPthread094(); // pthread_cancel +} +#endif + +/** + * @tc.name: IT_POSIX_PTHREAD_095 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread095, TestSize.Level0) +{ + ItPosixPthread095(); // pthread_cancel +} + +/** + * @tc.name: IT_POSIX_PTHREAD_106 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread106, TestSize.Level0) +{ + ItPosixPthread106(); // pthread_cancel +} + +/** + * @tc.name: IT_POSIX_PTHREAD_107 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread107, TestSize.Level0) +{ + ItPosixPthread107(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_116 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread116, TestSize.Level0) +{ + ItPosixPthread116(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_123 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread123, TestSize.Level0) +{ + ItPosixPthread123(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_124 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread124, TestSize.Level0) +{ + ItPosixPthread124(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_125 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread125, TestSize.Level0) +{ + ItPosixPthread125(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_127 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread127, TestSize.Level0) +{ + ItPosixPthread127(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_129 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread129, TestSize.Level0) +{ + ItPosixPthread129(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_132 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread132, TestSize.Level0) +{ + ItPosixPthread132(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_133 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread133, TestSize.Level0) +{ + ItPosixPthread133(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_134 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread134, TestSize.Level0) +{ + ItPosixPthread134(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_136 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread136, TestSize.Level0) +{ + ItPosixPthread136(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_138 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread138, TestSize.Level0) +{ + ItPosixPthread138(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_141 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread141, TestSize.Level0) +{ + ItPosixPthread141(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_142 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread142, TestSize.Level0) +{ + ItPosixPthread142(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_144 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread144, TestSize.Level0) +{ + ItPosixPthread144(); // pthread_cancel +} + +/** + * @tc.name: IT_POSIX_PTHREAD_152 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread152, TestSize.Level0) +{ + ItPosixPthread152(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_154 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread154, TestSize.Level0) +{ + ItPosixPthread154(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_166 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread166, TestSize.Level0) +{ + ItPosixPthread166(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_167 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread167, TestSize.Level0) +{ + ItPosixPthread167(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_173 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread173, TestSize.Level0) +{ + ItPosixPthread173(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_175 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread175, TestSize.Level0) +{ + ItPosixPthread175(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_176 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread176, TestSize.Level0) +{ + ItPosixPthread176(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_177 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread177, TestSize.Level0) +{ + ItPosixPthread177(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_182 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread182, TestSize.Level0) +{ + ItPosixPthread182(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_185 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread185, TestSize.Level0) +{ + ItPosixPthread185(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_186 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread186, TestSize.Level0) +{ + ItPosixPthread186(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_187 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread187, TestSize.Level0) +{ + ItPosixPthread187(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_188 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread188, TestSize.Level0) +{ + ItPosixPthread188(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_193 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread193, TestSize.Level0) +{ + ItPosixPthread193(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_194 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread194, TestSize.Level0) +{ + ItPosixPthread194(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_200 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread200, TestSize.Level0) +{ + ItPosixPthread200(); +} + +/* * + * @tc.name: IT_POSIX_PTHREAD_203 + * @tc.desc: function for pthread concurrency + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread203, TestSize.Level0) +{ + ItPosixPthread203(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_204 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread204, TestSize.Level0) +{ + ItPosixPthread204(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_205 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread205, TestSize.Level0) +{ + ItPosixPthread205(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_206 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread206, TestSize.Level0) +{ + ItPosixPthread206(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_209 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread209, TestSize.Level0) +{ + ItPosixPthread209(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_213 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread213, TestSize.Level0) +{ + ItPosixPthread213(); +} + +/** + * @tc.name: IT_POSIX_PTHREAD_217 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread217, TestSize.Level0) +{ + ItPosixPthread217(); // phthread_key_create +} + +/** + * @tc.name: IT_POSIX_PTHREAD_218 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread218, TestSize.Level0) +{ + ItPosixPthread218(); // phthread_key_create +} + +/** + * @tc.name: IT_POSIX_PTHREAD_224 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread224, TestSize.Level0) +{ + ItPosixPthread224(); // pthread_key_create +} + +/** + * @tc.name: IT_POSIX_PTHREAD_226 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread226, TestSize.Level0) +{ + ItPosixPthread226(); // pthread_key +} + +/** + * @tc.name: IT_POSIX_PTHREAD_233 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread233, TestSize.Level0) +{ + ItPosixPthread233(); // pthread_key and pthread_cancel +} + +/** + * @tc.name: IT_POSIX_PTHREAD_238 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread238, TestSize.Level0) +{ + ItPosixPthread238(); // pthread_cancel +} + +/** + * @tc.name: IT_POSIX_PTHREAD_239 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread239, TestSize.Level0) +{ + ItPosixPthread239(); // pthread_cancel +} + +/** + * @tc.name: IT_POSIX_PTHREAD_240 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread240, TestSize.Level0) +{ + ItPosixPthread240(); // pthread_cancel +} + +/** + * @tc.name: IT_POSIX_PTHREAD_241 + * @tc.desc: function for PosixPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(PosixPthreadTest, ItPosixPthread241, TestSize.Level0) +{ + ItPosixPthread241(); // pthread_cancel +} +#endif + +} // namespace OHOS diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/smoke/It_posix_pthread_003.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/smoke/It_posix_pthread_003.cpp new file mode 100644 index 00000000..9cd44b50 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/smoke/It_posix_pthread_003.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static void *ThreadF01(void *arg) +{ + pthread_exit(NULL); + return NULL; +} +static UINT32 Testcase(VOID) +{ + pthread_t aThread; + pthread_t ptid = pthread_self(); + pthread_t a = 0; + pthread_t b = 0; + int tmp; + pthread_attr_t aa = { 0 }; + int detachstate; + pthread_mutex_t c; + UINT32 ret; + + pthread_create(&aThread, NULL, ThreadF01, NULL); + + tmp = pthread_equal(a, b); + + pthread_attr_init(&aa); + + pthread_attr_getdetachstate(&aa, &detachstate); + + pthread_attr_setdetachstate(&aa, PTHREAD_CREATE_DETACHED); + + pthread_attr_destroy(&aa); + + ret = pthread_join(aThread, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread003(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_003", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/smoke/It_posix_pthread_004.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/smoke/It_posix_pthread_004.cpp new file mode 100644 index 00000000..24e5b84a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/smoke/It_posix_pthread_004.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static void *ThreadF01(void *arg) +{ + pthread_exit(static_cast(2)); // 2: return value for testing + return NULL; +} +static UINT32 Testcase(VOID) +{ + pthread_t mainTh, newTh; + INT32 ret; + INTPTR *temp; + + if (pthread_create(&newTh, NULL, ThreadF01, NULL) != 0) { + uart_printf_func("Error creating thread\n"); + ICUNIT_ASSERT_EQUAL(1, 0, errno); + } + + LosTaskDelay(1); + /* Obtain the thread ID of this main function */ + mainTh = TestPthreadSelf(); + + /* Compare the thread ID of the new thread to the main thread. + * They should be different. If not, the test fails. */ + if (pthread_equal(newTh, mainTh) != 0) { + printf("Test FAILED: A new thread wasn't created\n"); + ICUNIT_ASSERT_EQUAL(1, 0, errno); + } + + TestExtraTaskDelay(1); + ret = pthread_join(newTh, (void **)&temp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL((int)temp, 2, temp); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread004(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_004", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/smoke/It_posix_pthread_005.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/smoke/It_posix_pthread_005.cpp new file mode 100644 index 00000000..5beb285c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/smoke/It_posix_pthread_005.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static void *ThreadF01(void *arg) +{ + sleep(1); + + /* Shouldn't reach here. If we do, then the pthread_cancel() + * function did not succeed. */ + pthread_exit(nullptr); + return NULL; +} +static UINT32 Testcase(VOID) +{ + pthread_t newTh; + UINT32 ret; + UINTPTR *temp; + + if (pthread_create(&newTh, NULL, ThreadF01, NULL) < 0) { + uart_printf_func("Error creating thread\n"); + ICUNIT_ASSERT_EQUAL(1, 0, errno); + } + + LosTaskDelay(1); + /* Try to cancel the newly created thread. If an error is returned, + * then the thread wasn't created successfully. */ + if (pthread_cancel(newTh) != 0) { + printf("Test FAILED: A new thread wasn't created\n"); + ICUNIT_ASSERT_EQUAL(1, 0, errno); + } + + ret = pthread_join(newTh, (void **)&temp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread005(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_005", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/smoke/It_posix_pthread_006.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/smoke/It_posix_pthread_006.cpp new file mode 100644 index 00000000..80d397a3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/smoke/It_posix_pthread_006.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static void *ThreadF01(void *arg) +{ + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + + sleep(1); + + pthread_exit(nullptr); + return NULL; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + void *temp; + pthread_t a; + + /* SIGALRM will be sent in 5 seconds. */ + + /* Create a new thread. */ + if (pthread_create(&a, NULL, ThreadF01, NULL) != 0) { + uart_printf_func("Error creating thread\n"); + ICUNIT_ASSERT_EQUAL(1, 0, errno); + } + + LosTaskDelay(1); + pthread_cancel(a); + /* If 'main' has reached here, then the test passed because it means + * that the thread is truly asynchronise, and main isn't waiting for + * it to return in order to move on. */ + + ret = pthread_join(a, &temp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread006(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_006", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/smoke/It_posix_pthread_018.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/smoke/It_posix_pthread_018.cpp new file mode 100644 index 00000000..9c22a77c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/smoke/It_posix_pthread_018.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *pthread_f01(void *argument) +{ + g_testCount++; + + return argument; +} +static UINT32 Testcase(VOID) +{ + pthread_attr_t attr; + pthread_t newTh; + UINT32 ret; + UINTPTR uwtemp; + int policy; + struct sched_param param; + struct sched_param param2 = { 2 }; + + g_testCount = 0; + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newTh, NULL, pthread_f01, (void *)9); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + LosTaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = pthread_setschedparam(newTh, 0, ¶m); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_setschedparam(newTh, 4, ¶m); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + + param.sched_priority = 0; + ret = pthread_setschedparam(newTh, SCHED_RR, ¶m); // + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + param.sched_priority = 31; + ret = pthread_setschedparam(newTh, SCHED_RR, ¶m); // + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + param.sched_priority = 32; + ret = pthread_setschedparam(newTh, SCHED_RR, ¶m); // + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_getschedparam(newTh, &policy, ¶m2); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(param2.sched_priority, 31, param2.sched_priority); + + ret = pthread_join(newTh, (void **)&uwtemp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(uwtemp, 9, uwtemp); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread018(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_018", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/smoke/It_posix_pthread_019.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/smoke/It_posix_pthread_019.cpp new file mode 100644 index 00000000..20ac176c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/smoke/It_posix_pthread_019.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID PthreadOnceF01(VOID) +{ + g_testCount++; +} +static UINT32 Testcase(VOID) +{ + UINT32 ret; + pthread_once_t onceBlock = PTHREAD_ONCE_INIT; + + g_testCount = 0; + + // pthread_once_init: (0) NEVER (1) IN_PROGRESS (2) DONE + // If 1:all pthread_once() will wait until one of them transfer his state to (2) DONE,so all of them will stuck + // infinitely. We can't make it happen that all pthreads stuck infinitely in testsuit which is unreasonable. + onceBlock = 2; + ret = pthread_once(&onceBlock, PthreadOnceF01); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 0, g_testCount); + + onceBlock = PTHREAD_ONCE_INIT; + + ret = pthread_once(&onceBlock, PthreadOnceF01); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = pthread_once(&onceBlock, PthreadOnceF01); + ICUNIT_ASSERT_EQUAL(onceBlock, 2, onceBlock); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread019(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_019", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/smoke/It_posix_pthread_020.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/smoke/It_posix_pthread_020.cpp new file mode 100644 index 00000000..cf008c80 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/smoke/It_posix_pthread_020.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static void PthreadKeyF01(void *arg) +{ + g_testCount++; +} + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + UINT32 temp = 9; + VOID *buf; + + g_testCount = 0; + + ret = pthread_key_create(&g_key, PthreadKeyF01); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_setspecific(g_key, &temp); // ɹkey + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = *((UINT32 *)pthread_getspecific(g_key)); + ICUNIT_ASSERT_EQUAL(ret, 9, ret); + + ret = pthread_key_delete(g_key); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(g_testCount, 0, g_testCount); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread020(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_020", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/smoke/It_posix_pthread_021.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/smoke/It_posix_pthread_021.cpp new file mode 100644 index 00000000..c5646d89 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/smoke/It_posix_pthread_021.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static UINT32 Testcase(VOID) +{ + UINT32 ret; + int oldstate; + int oldstype; + + // pthread_setcancelstate(int new, int *old): if new > 2U, return EINVAL, else return 0. + ret = pthread_setcancelstate(0, &oldstate); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_setcancelstate(3, &oldstate); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(oldstate, PTHREAD_CANCEL_ENABLE, oldstate); + + // pthread_setcanceltype(int new, int *old): if new > 1U, return EINVAL,else return 0. + ret = pthread_setcanceltype(0, &oldstype); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_setcanceltype(3, &oldstype); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldstate); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(oldstate, PTHREAD_CANCEL_ASYNCHRONOUS, oldstate); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread021(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_021", Testcase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/smoke/It_posix_pthread_022.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/smoke/It_posix_pthread_022.cpp new file mode 100644 index 00000000..0945ae20 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/posix/pthread/smoke/It_posix_pthread_022.cpp @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_pthread.h" + +static VOID *PthreadF01(void *argument) +{ + g_testCount++; + printf("%d,g_TestCount:%d\n", __LINE__, g_testCount); + while (1) { + LosTaskDelay(1); + } + printf("%d,g_TestCount:%d\n", __LINE__, g_testCount); + g_testCount++; + return argument; +} + +static VOID *PthreadF02(void *argument) +{ + printf("%d,g_TestCount:%d\n", __LINE__, g_testCount); + g_testCount++; + pthread_testcancel(); + return argument; +} + +static UINT32 TestCase(VOID) +{ + pthread_t newTh; + + UINT32 ret; + UINTPTR *uwtemp = NULL; + UINT32 uwint = 8; + + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, PthreadF01, (void **)&uwint); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + LosTaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = pthread_cancel(newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LosTaskDelay(2); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = pthread_join(newTh, (void **)&uwtemp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL((UINTPTR)uwtemp, (UINTPTR)PTHREAD_CANCELED, uwtemp); + + g_testCount = 0; + + ret = pthread_create(&newTh, NULL, PthreadF02, (void **)uwint); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + LosTaskDelay(1); + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = pthread_cancel(newTh); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newTh, (void **)&uwtemp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL((UINTPTR)uwtemp, 8, uwtemp); + + return PTHREAD_NO_ERROR; +} + +VOID ItPosixPthread022(VOID) // IT_Layer_ModuleORFeature_No +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_022", TestCase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/sys/BUILD.gn b/src/kernel_liteos_a/testsuites/unittest/libc/sys/BUILD.gn new file mode 100644 index 00000000..74a55c90 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/sys/BUILD.gn @@ -0,0 +1,66 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("./config.gni") + +config("libc_config") { + if (LOSCFG_USER_TEST_LIBC_POSIX_MQUEUE == true || + LOSCFG_USER_TEST_LIBC_POSIX_PTHREAD == true) { + cflags = [ "-O1" ] + cflags_cc = cflags + } +} + +if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_LOW) { + unittest("liteos_a_libc_sys_unittest_door") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + include_dirs = common_include_dirs + sources = sources_entry + sources += sources_smoke + sources_full = [] + sources += sources_full + configs = [ "../..:public_config_for_door" ] + configs += [ ":libc_config" ] + deps = [ "$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR:libsec_shared" ] + } +} + +if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_MIDDLE) { + unittest("liteos_a_libc_sys_unittest") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + include_dirs = common_include_dirs + sources = sources_entry + sources += sources_smoke + sources += sources_full + configs = [ "../..:public_config_for_all" ] + configs += [ ":libc_config" ] + deps = [ "$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR:libsec_shared" ] + } +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/sys/It_test_sys.h b/src/kernel_liteos_a/testsuites/unittest/libc/sys/It_test_sys.h new file mode 100644 index 00000000..4bc6ad5d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/sys/It_test_sys.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _IT_TEST_SYS_H +#define _IT_TEST_SYS_H + +#include "libgen.h" +#include "setjmp.h" +#include "fenv.h" +#include "float.h" +#include "math.h" +#include "regex.h" +#include "locale.h" +#include "pwd.h" +#include "osTest.h" +#define FE_INVALID 1 +#define FE_DIVBYZERO 4 +#define FE_OVERFLOW 8 +#define FE_UNDERFLOW 16 +#define FE_INEXACT 32 +#define FE_ALL_EXCEPT 0 +#define FE_TONEAREST 0 +#define FE_DOWNWARD 0x400 +#define FE_UPWARD 0x800 +#define FE_TOWARDZERO 0xc00 + +extern CHAR *g_groupFileStream; +extern CHAR *g_passwdFileStream; +extern VOID ItTestSys001(VOID); +extern VOID IT_TEST_SYS_002(VOID); +extern VOID IT_TEST_SYS_003(VOID); +extern VOID ItTestSys004(VOID); +extern VOID ItTestSys005(VOID); +extern VOID ItTestSys006(VOID); +extern VOID ItTestSys007(VOID); +extern VOID ItTestSys008(VOID); +extern VOID ItTestSys009(VOID); +extern VOID ItTestSys010(VOID); +extern VOID IT_TEST_SYS_011(VOID); +extern VOID ItTestSys012(VOID); +extern VOID ItTestSys013(VOID); +extern VOID ItTestSys014(VOID); +extern VOID ItTestSys015(VOID); +extern VOID ItTestSys016(VOID); +extern VOID ItTestSys017(VOID); +extern VOID ItTestSys018(VOID); +extern VOID ItTestSys019(VOID); +extern VOID ItTestSys020(VOID); +extern VOID ItTestSys021(VOID); +extern VOID ItTestSys022(VOID); +extern VOID ItTestSys023(VOID); +extern VOID ItTestSys024(VOID); +extern VOID ItTestSys025(VOID); +extern VOID ItTestSys026(VOID); +extern VOID ItTestSys027(VOID); +extern VOID ItTestSys028(VOID); +extern VOID ItTestSys029(VOID); +extern VOID IT_TEST_SYS_030(VOID); +extern VOID IT_TEST_SYS_031(VOID); +#endif diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/sys/config.gni b/src/kernel_liteos_a/testsuites/unittest/libc/sys/config.gni new file mode 100644 index 00000000..7dd898cc --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/sys/config.gni @@ -0,0 +1,88 @@ +# Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//build/lite/config/test.gni") +import("//kernel/liteos_a/liteos.gni") +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +common_include_dirs = [ + "$THIRDPARTY_GOOGLETEST_DIR/googletest/include", + "../../common/include", +] + +sources_entry = [ "../../common/osTest.cpp" ] + +sources_smoke = [] + +sources_full = [] + +libc_sys_include_dirs = [ "$TEST_UNITTEST_DIR/libc/sys" ] + +libc_sys_sources_entry = [ "$TEST_UNITTEST_DIR/libc/sys/sys_unit_test.cpp" ] + +libc_sys_sources_smoke = [ + "$TEST_UNITTEST_DIR/libc/sys/smoke/sys_test_004.cpp", + "$TEST_UNITTEST_DIR/libc/sys/smoke/sys_test_005.cpp", + "$TEST_UNITTEST_DIR/libc/sys/smoke/sys_test_006.cpp", + "$TEST_UNITTEST_DIR/libc/sys/smoke/sys_test_007.cpp", + "$TEST_UNITTEST_DIR/libc/sys/smoke/sys_test_008.cpp", + "$TEST_UNITTEST_DIR/libc/sys/smoke/sys_test_009.cpp", + "$TEST_UNITTEST_DIR/libc/sys/smoke/sys_test_010.cpp", + "$TEST_UNITTEST_DIR/libc/sys/smoke/sys_test_012.cpp", + "$TEST_UNITTEST_DIR/libc/sys/smoke/sys_test_013.cpp", + "$TEST_UNITTEST_DIR/libc/sys/smoke/sys_test_014.cpp", + "$TEST_UNITTEST_DIR/libc/sys/smoke/sys_test_015.cpp", + "$TEST_UNITTEST_DIR/libc/sys/smoke/sys_test_016.cpp", + "$TEST_UNITTEST_DIR/libc/sys/smoke/sys_test_017.cpp", + "$TEST_UNITTEST_DIR/libc/sys/smoke/sys_test_029.cpp", + "$TEST_UNITTEST_DIR/libc/sys/smoke/sys_test_030.cpp", + "$TEST_UNITTEST_DIR/libc/sys/smoke/sys_test_031.cpp", +] + +libc_sys_sources_full = [ + "$TEST_UNITTEST_DIR/libc/sys/full/sys_test_001.cpp", + "$TEST_UNITTEST_DIR/libc/sys/full/sys_test_018.cpp", + "$TEST_UNITTEST_DIR/libc/sys/full/sys_test_019.cpp", + "$TEST_UNITTEST_DIR/libc/sys/full/sys_test_020.cpp", + "$TEST_UNITTEST_DIR/libc/sys/full/sys_test_021.cpp", + "$TEST_UNITTEST_DIR/libc/sys/full/sys_test_022.cpp", + "$TEST_UNITTEST_DIR/libc/sys/full/sys_test_023.cpp", + "$TEST_UNITTEST_DIR/libc/sys/full/sys_test_024.cpp", + "$TEST_UNITTEST_DIR/libc/sys/full/sys_test_025.cpp", + "$TEST_UNITTEST_DIR/libc/sys/full/sys_test_026.cpp", + "$TEST_UNITTEST_DIR/libc/sys/full/sys_test_027.cpp", + "$TEST_UNITTEST_DIR/libc/sys/full/sys_test_028.cpp", +] + +# libc sys module +if (LOSCFG_USER_TEST_LIBC_SYS == true) { + common_include_dirs += libc_sys_include_dirs + sources_entry += libc_sys_sources_entry + sources_smoke += libc_sys_sources_smoke + sources_full += libc_sys_sources_full +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_001.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_001.cpp new file mode 100644 index 00000000..1ff8db62 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_001.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_test_sys.h" + +static jmp_buf g_buf; +static UINT32 First(VOID) +{ + int val = 2; + int ret = setjmp(g_buf); + if (ret) { + ICUNIT_ASSERT_EQUAL(ret, val, ret); + goto OUT1; + } + + longjmp(g_buf, val); +OUT1: + return 0; +} + +static UINT32 Sencond(VOID) +{ + int ret = setjmp(g_buf); + if (ret) { + ICUNIT_ASSERT_EQUAL(ret, 1, ret); + goto OUT2; + } + + longjmp(g_buf, 0); + +OUT2: + return 0; +} + +static UINT32 TestCase(VOID) +{ + int ret = First(); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = Sencond(); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return 0; +} + +VOID ItTestSys001(VOID) +{ + TEST_ADD_CASE("IT_TEST_SYS_024", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_018.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_018.cpp new file mode 100644 index 00000000..f6490a59 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_018.cpp @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_sys.h" + +STATIC UINT32 TestCase(VOID) +{ + struct passwd *user1 = nullptr; + struct passwd *user2 = nullptr; + struct passwd *user3 = nullptr; + struct passwd *user4 = nullptr; + INT32 ret; + CHAR *pathList[] = {"/etc/group", "/etc/passwd"}; + CHAR *streamList[] = {g_groupFileStream, g_passwdFileStream}; + INT32 streamLen[] = {strlen(g_groupFileStream), strlen(g_passwdFileStream)}; + + ret = PrepareFileEnv(pathList, streamList, streamLen, 2); /* 2, group & passwd */ + if (ret != 0) { + printf("error: need some env file, but prepare is not ok"); + (VOID)RecoveryFileEnv(pathList, 2); /* 2, group & passwd */ + return -1; + } + + user1 = getpwnam("root"); + ICUNIT_GOTO_NOT_EQUAL(user1, nullptr, -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user1->pw_name, "root", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user1->pw_passwd, "x", -1, ERROUT); + ICUNIT_GOTO_EQUAL(user1->pw_uid, 0, -1, ERROUT); + ICUNIT_GOTO_EQUAL(user1->pw_gid, 0, -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user1->pw_gecos, "root", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user1->pw_dir, "/root", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user1->pw_shell, "/bin/bash", -1, ERROUT); + + user2 = getpwnam("daemon"); + ICUNIT_GOTO_NOT_EQUAL(user2, nullptr, -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user2->pw_name, "daemon", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user2->pw_passwd, "x", -1, ERROUT); + ICUNIT_GOTO_EQUAL(user2->pw_uid, 1, -1, ERROUT); + ICUNIT_GOTO_EQUAL(user2->pw_gid, 1, -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user2->pw_gecos, "daemon", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user2->pw_dir, "/usr/sbin", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user2->pw_shell, "/usr/sbin/nologin", -1, ERROUT); + + + user3 = getpwnam("bin"); + ICUNIT_GOTO_NOT_EQUAL(user3, nullptr, -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user3->pw_name, "bin", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user3->pw_passwd, "x", -1, ERROUT); + ICUNIT_GOTO_EQUAL(user3->pw_uid, 2, -1, ERROUT); /* 2, from etc/group */ + ICUNIT_GOTO_EQUAL(user3->pw_gid, 2, -1, ERROUT); /* 2, from etc/group */ + ICUNIT_GOTO_STRING_EQUAL(user3->pw_gecos, "bin", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user3->pw_dir, "/bin", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user3->pw_shell, "/usr/sbin/nologin", -1, ERROUT); + + user4 = getpwnam("lyw"); + ICUNIT_GOTO_EQUAL(user4, nullptr, -1, ERROUT); + + user4 = getpwnam(""); + ICUNIT_GOTO_EQUAL(user4, nullptr, -1, ERROUT); + + (VOID)RecoveryFileEnv(pathList, 2); /* 2, group & passwd */ + return 0; +ERROUT: + (VOID)RecoveryFileEnv(pathList, 2); /* 2, group & passwd */ + return -1; +} + +VOID ItTestSys018(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_019.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_019.cpp new file mode 100644 index 00000000..2460ccda --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_019.cpp @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_sys.h" + +STATIC UINT32 TestCase(VOID) +{ + struct passwd pwd; + struct passwd *user1 = nullptr; + struct passwd *user2 = nullptr; + struct passwd *user3 = nullptr; + struct passwd *user4 = nullptr; + struct passwd *user5 = nullptr; + CHAR buf1[1024] = { 0 }; /* 1024, buffer for test */ + CHAR buf2[2] = { 0 }; /* 2, for test,this buffer is not enough large to save data */ + INT32 ret; + CHAR *pathList[] = {"/etc/group", "/etc/passwd"}; + CHAR *streamList[] = {g_groupFileStream, g_passwdFileStream}; + INT32 streamLen[] = {strlen(g_groupFileStream), strlen(g_passwdFileStream)}; + + ret = PrepareFileEnv(pathList, streamList, streamLen, 2); /* 2, group & passwd */ + if (ret != 0) { + printf("error: need some env file, but prepare is not ok"); + (VOID)RecoveryFileEnv(pathList, 2); /* 2, group & passwd */ + return -1; + } + + ret = getpwnam_r("root", &pwd, buf1, sizeof(buf1), &user1); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROUT); + ICUNIT_GOTO_NOT_EQUAL(user1, nullptr, -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user1->pw_name, "root", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user1->pw_passwd, "x", -1, ERROUT); + ICUNIT_GOTO_EQUAL(user1->pw_uid, 0, -1, ERROUT); + ICUNIT_GOTO_EQUAL(user1->pw_gid, 0, -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user1->pw_gecos, "root", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user1->pw_dir, "/root", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user1->pw_shell, "/bin/bash", -1, ERROUT); + + ICUNIT_GOTO_STRING_EQUAL(pwd.pw_name, "root", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(pwd.pw_passwd, "x", -1, ERROUT); + ICUNIT_GOTO_EQUAL(pwd.pw_uid, 0, -1, ERROUT); + ICUNIT_GOTO_EQUAL(pwd.pw_gid, 0, -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(pwd.pw_gecos, "root", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(pwd.pw_dir, "/root", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(pwd.pw_shell, "/bin/bash", -1, ERROUT); + + ret = getpwnam_r("daemon", &pwd, buf1, sizeof(buf1), &user2); + ICUNIT_GOTO_NOT_EQUAL(user2, nullptr, -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user2->pw_name, "daemon", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user2->pw_passwd, "x", -1, ERROUT); + ICUNIT_GOTO_EQUAL(user2->pw_uid, 1, -1, ERROUT); + ICUNIT_GOTO_EQUAL(user2->pw_gid, 1, -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user2->pw_gecos, "daemon", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user2->pw_dir, "/usr/sbin", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user2->pw_shell, "/usr/sbin/nologin", -1, ERROUT); + + ret = getpwnam_r("bin", &pwd, buf1, sizeof(buf1), &user3); + ICUNIT_GOTO_NOT_EQUAL(user3, nullptr, -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user3->pw_name, "bin", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user3->pw_passwd, "x", -1, ERROUT); + ICUNIT_GOTO_EQUAL(user3->pw_uid, 2, -1, ERROUT); /* 2, from etc/group */ + ICUNIT_GOTO_EQUAL(user3->pw_gid, 2, -1, ERROUT); /* 2, from etc/group */ + ICUNIT_GOTO_STRING_EQUAL(user3->pw_gecos, "bin", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user3->pw_dir, "/bin", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user3->pw_shell, "/usr/sbin/nologin", -1, ERROUT); + + ret = getpwnam_r("root", &pwd, buf2, sizeof(buf2), &user4); + ICUNIT_GOTO_EQUAL(ret, ERANGE, ret, ERROUT); + ICUNIT_GOTO_EQUAL(user4, nullptr, -1, ERROUT); + + ret = getpwnam_r(nullptr, &pwd, buf1, sizeof(buf1), &user5); + ICUNIT_GOTO_EQUAL(ret, 0, -1, ERROUT); + ret = getpwnam_r("", &pwd, buf1, sizeof(buf1), &user5); + ICUNIT_GOTO_NOT_EQUAL(ret, 0, -1, ERROUT); + ret = getpwnam_r("sssssss", &pwd, buf1, sizeof(buf1), &user5); + ICUNIT_GOTO_NOT_EQUAL(ret, 0, -1, ERROUT); + + (VOID)RecoveryFileEnv(pathList, 2); /* 2, group & passwd */ + return 0; +ERROUT: + (VOID)RecoveryFileEnv(pathList, 2); /* 2, group & passwd */ + return -1; +} + +VOID ItTestSys019(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_020.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_020.cpp new file mode 100644 index 00000000..89438972 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_020.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_sys.h" + +STATIC UINT32 TestCase(VOID) +{ + struct passwd *user1 = nullptr; + struct passwd *user2 = nullptr; + struct passwd *user3 = nullptr; + struct passwd *user4 = nullptr; + INT32 ret; + CHAR *pathList[] = {"/etc/group", "/etc/passwd"}; + CHAR *streamList[] = {g_groupFileStream, g_passwdFileStream}; + INT32 streamLen[] = {strlen(g_groupFileStream), strlen(g_passwdFileStream)}; + + ret = PrepareFileEnv(pathList, streamList, streamLen, 2); /* 2, group & passwd */ + if (ret != 0) { + printf("error: need some env file, but prepare is not ok"); + (VOID)RecoveryFileEnv(pathList, 2); /* 2, group & passwd */ + return -1; + } + + user1 = getpwuid(0); + ICUNIT_GOTO_NOT_EQUAL(user1, nullptr, -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user1->pw_name, "root", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user1->pw_passwd, "x", -1, ERROUT); + ICUNIT_GOTO_EQUAL(user1->pw_uid, 0, -1, ERROUT); + ICUNIT_GOTO_EQUAL(user1->pw_gid, 0, -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user1->pw_gecos, "root", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user1->pw_dir, "/root", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user1->pw_shell, "/bin/bash", -1, ERROUT); + + user2 = getpwuid(1); + ICUNIT_GOTO_NOT_EQUAL(user2, nullptr, -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user2->pw_name, "daemon", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user2->pw_passwd, "x", -1, ERROUT); + ICUNIT_GOTO_EQUAL(user2->pw_uid, 1, -1, ERROUT); + ICUNIT_GOTO_EQUAL(user2->pw_gid, 1, -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user2->pw_gecos, "daemon", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user2->pw_dir, "/usr/sbin", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user2->pw_shell, "/usr/sbin/nologin", -1, ERROUT); + + user3 = getpwuid(2); /* 2, from etc/group */ + ICUNIT_GOTO_NOT_EQUAL(user3, nullptr, -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user3->pw_name, "bin", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user3->pw_passwd, "x", -1, ERROUT); + ICUNIT_GOTO_EQUAL(user3->pw_uid, 2, -1, ERROUT); /* 2, from etc/group */ + ICUNIT_GOTO_EQUAL(user3->pw_gid, 2, -1, ERROUT); /* 2, from etc/group */ + ICUNIT_GOTO_STRING_EQUAL(user3->pw_gecos, "bin", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user3->pw_dir, "/bin", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user3->pw_shell, "/usr/sbin/nologin", -1, ERROUT); + + user4 = getpwuid(200); + ICUNIT_GOTO_EQUAL(user4, nullptr, -1, ERROUT); + + user4 = getpwuid(-100); + ICUNIT_GOTO_EQUAL(user4, nullptr, -1, ERROUT); + + user4 = getpwuid(100000); + ICUNIT_GOTO_EQUAL(user4, nullptr, -1, ERROUT); + + (VOID)RecoveryFileEnv(pathList, 2); /* 2, group & passwd */ + return 0; +ERROUT: + (VOID)RecoveryFileEnv(pathList, 2); /* 2, group & passwd */ + return -1; +} + +VOID ItTestSys020(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_021.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_021.cpp new file mode 100644 index 00000000..03e07091 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_021.cpp @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_sys.h" + +STATIC UINT32 TestCase(VOID) +{ + struct passwd pwd; + struct passwd *user1 = nullptr; + struct passwd *user2 = nullptr; + struct passwd *user3 = nullptr; + struct passwd *user4 = nullptr; + struct passwd *user5 = nullptr; + CHAR buf1[1024] = { 0 }; /* 1024, buffer for test */ + CHAR buf2[2] = { 0 }; /* 2, for test,this buffer is not enough large to save data */ + INT32 ret; + CHAR *pathList[] = {"/etc/group", "/etc/passwd"}; + CHAR *streamList[] = {g_groupFileStream, g_passwdFileStream}; + INT32 streamLen[] = {strlen(g_groupFileStream), strlen(g_passwdFileStream)}; + + ret = PrepareFileEnv(pathList, streamList, streamLen, 2); /* 2, group & passwd */ + if (ret != 0) { + printf("error: need some env file, but prepare is not ok"); + (VOID)RecoveryFileEnv(pathList, 2); /* 2, group & passwd */ + return -1; + } + + ret = getpwuid_r(0, &pwd, buf1, sizeof(buf1), &user1); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROUT); + ICUNIT_GOTO_NOT_EQUAL(user1, NULL, -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user1->pw_name, "root", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user1->pw_passwd, "x", -1, ERROUT); + ICUNIT_GOTO_EQUAL(user1->pw_uid, 0, -1, ERROUT); + ICUNIT_GOTO_EQUAL(user1->pw_gid, 0, -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user1->pw_gecos, "root", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user1->pw_dir, "/root", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user1->pw_shell, "/bin/bash", -1, ERROUT); + + ICUNIT_GOTO_STRING_EQUAL(pwd.pw_name, "root", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(pwd.pw_passwd, "x", -1, ERROUT); + ICUNIT_GOTO_EQUAL(pwd.pw_uid, 0, -1, ERROUT); + ICUNIT_GOTO_EQUAL(pwd.pw_gid, 0, -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(pwd.pw_gecos, "root", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(pwd.pw_dir, "/root", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(pwd.pw_shell, "/bin/bash", -1, ERROUT); + + ret = getpwuid_r(1, &pwd, buf1, sizeof(buf1), &user2); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROUT); + ICUNIT_GOTO_NOT_EQUAL(user2, nullptr, -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user2->pw_name, "daemon", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user2->pw_passwd, "x", -1, ERROUT); + ICUNIT_GOTO_EQUAL(user2->pw_uid, 1, -1, ERROUT); + ICUNIT_GOTO_EQUAL(user2->pw_gid, 1, -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user2->pw_gecos, "daemon", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user2->pw_dir, "/usr/sbin", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user2->pw_shell, "/usr/sbin/nologin", -1, ERROUT); + + ret = getpwuid_r(2, &pwd, buf1, sizeof(buf1), &user3); /* 2, from etc/group */ + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROUT); + ICUNIT_GOTO_NOT_EQUAL(user3, nullptr, -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user3->pw_name, "bin", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user3->pw_passwd, "x", -1, ERROUT); + ICUNIT_GOTO_EQUAL(user3->pw_uid, 2, -1, ERROUT); /* 2, from etc/group */ + ICUNIT_GOTO_EQUAL(user3->pw_gid, 2, -1, ERROUT); /* 2, from etc/group */ + ICUNIT_GOTO_STRING_EQUAL(user3->pw_gecos, "bin", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user3->pw_dir, "/bin", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user3->pw_shell, "/usr/sbin/nologin", -1, ERROUT); + + ret = getpwuid_r(0, &pwd, buf2, sizeof(buf2), &user4); + ICUNIT_GOTO_EQUAL(ret, ERANGE, ret, ERROUT); + ICUNIT_GOTO_EQUAL(user4, nullptr, -1, ERROUT); + + + ret = getpwuid_r(200, &pwd, buf1, sizeof(buf1), &user5); /* 200, invalid param for test */ + ICUNIT_GOTO_EQUAL(user5, nullptr, -1, ERROUT); + ICUNIT_GOTO_NOT_EQUAL(ret, 0, -1, ERROUT); + + ret = getpwuid_r(100000, &pwd, buf1, sizeof(buf1), &user5); /* 100000, invalid param for test */ + ICUNIT_GOTO_EQUAL(user5, nullptr, -1, ERROUT); + ICUNIT_GOTO_NOT_EQUAL(ret, 0, -1, ERROUT); + + ret = getpwuid_r(-100, &pwd, buf1, sizeof(buf1), &user5); /* -100, invalid param for test */ + ICUNIT_GOTO_EQUAL(user5, nullptr, -1, ERROUT); + ICUNIT_GOTO_NOT_EQUAL(ret, 0, -1, ERROUT); + + (VOID)RecoveryFileEnv(pathList, 2); /* 2, group & passwd */ + return 0; +ERROUT: + (VOID)RecoveryFileEnv(pathList, 2); /* 2, group & passwd */ + return -1; +} + +VOID ItTestSys021(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_022.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_022.cpp new file mode 100644 index 00000000..fc9814ce --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_022.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_sys.h" + +STATIC UINT32 TestCase(VOID) +{ + struct passwd *user1 = nullptr; + struct passwd *user2 = nullptr; + INT32 ret; + CHAR *pathList[] = {"/etc/group", "/etc/passwd"}; + CHAR *streamList[] = {g_groupFileStream, g_passwdFileStream}; + INT32 streamLen[] = {strlen(g_groupFileStream), strlen(g_passwdFileStream)}; + + ret = PrepareFileEnv(pathList, streamList, streamLen, 2); /* 2, group & passwd */ + if (ret != 0) { + printf("error: need some env file, but prepare is not ok"); + (VOID)RecoveryFileEnv(pathList, 2); /* 2, group & passwd */ + return -1; + } + + user1 = getpwent(); + ICUNIT_GOTO_NOT_EQUAL(user1, NULL, -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user1->pw_name, "root", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user1->pw_passwd, "x", -1, ERROUT); + ICUNIT_GOTO_EQUAL(user1->pw_uid, 0, -1, ERROUT); + ICUNIT_GOTO_EQUAL(user1->pw_gid, 0, -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user1->pw_gecos, "root", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user1->pw_dir, "/root", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user1->pw_shell, "/bin/bash", -1, ERROUT); + + user1 = getpwent(); + ICUNIT_GOTO_NOT_EQUAL(user1, NULL, -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user1->pw_name, "daemon", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user1->pw_passwd, "x", -1, ERROUT); + ICUNIT_GOTO_EQUAL(user1->pw_uid, 1, -1, ERROUT); + ICUNIT_GOTO_EQUAL(user1->pw_gid, 1, -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user1->pw_gecos, "daemon", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user1->pw_dir, "/usr/sbin", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user1->pw_shell, "/usr/sbin/nologin", -1, ERROUT); + + user1 = getpwent(); + ICUNIT_GOTO_NOT_EQUAL(user1, NULL, -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user1->pw_name, "bin", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user1->pw_passwd, "x", -1, ERROUT); + ICUNIT_GOTO_EQUAL(user1->pw_uid, 2, -1, ERROUT); /* 2, from etc/group */ + ICUNIT_GOTO_EQUAL(user1->pw_gid, 2, -1, ERROUT); /* 2, from etc/group */ + ICUNIT_GOTO_STRING_EQUAL(user1->pw_gecos, "bin", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user1->pw_dir, "/bin", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user1->pw_shell, "/usr/sbin/nologin", -1, ERROUT); + + setpwent(); + user2 = getpwent(); + ICUNIT_GOTO_NOT_EQUAL(user2, NULL, -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(user2->pw_name, user1->pw_name, -1, ERROUT); + + setpwent(); + (VOID)RecoveryFileEnv(pathList, 2); /* 2, group & passwd */ + return 0; +ERROUT: + setpwent(); + (VOID)RecoveryFileEnv(pathList, 2); /* 2, group & passwd */ + return -1; +} + +VOID ItTestSys022(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_023.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_023.cpp new file mode 100644 index 00000000..4972e261 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_023.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_sys.h" +#include "grp.h" + +STATIC UINT32 TestCase(VOID) +{ + struct group *grp1 = nullptr; + struct group *grp2 = nullptr; + struct group *grp3 = nullptr; + struct group *grp4 = nullptr; + INT32 ret; + CHAR *pathList[] = {"/etc/group"}; + CHAR *streamList[] = {g_groupFileStream}; + INT32 streamLen[] = {strlen(g_groupFileStream)}; + + ret = PrepareFileEnv(pathList, streamList, streamLen, 1); + if (ret != 0) { + printf("error: need some env file, but prepare is not ok"); + (VOID)RecoveryFileEnv(pathList, 1); + return -1; + } + + grp1 = getgrent(); + ICUNIT_GOTO_NOT_EQUAL(grp1, nullptr, -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(grp1->gr_name, "root", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(grp1->gr_passwd, "x", -1, ERROUT); + ICUNIT_GOTO_EQUAL(grp1->gr_gid, 0, -1, ERROUT); + + grp2 = getgrent(); + ICUNIT_GOTO_NOT_EQUAL(grp2, nullptr, -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(grp2->gr_name, "daemon", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(grp2->gr_passwd, "x", -1, ERROUT); + ICUNIT_GOTO_EQUAL(grp2->gr_gid, 1, -1, ERROUT); + + grp3 = getgrent(); + ICUNIT_GOTO_NOT_EQUAL(grp3, nullptr, -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(grp3->gr_name, "bin", -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(grp3->gr_passwd, "x", -1, ERROUT); + ICUNIT_GOTO_EQUAL(grp3->gr_gid, 2, -1, ERROUT); /* 2, from etc/group */ + + setgrent(); + + grp4 = getgrent(); + ICUNIT_GOTO_NOT_EQUAL(grp4, nullptr, -1, ERROUT); + ICUNIT_GOTO_STRING_EQUAL(grp1->gr_name, grp4->gr_name, -1, ERROUT); + + setgrent(); + (VOID)RecoveryFileEnv(pathList, 1); + return 0; +ERROUT: + setgrent(); + (VOID)RecoveryFileEnv(pathList, 1); + return -1; +} + +VOID ItTestSys023(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_024.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_024.cpp new file mode 100644 index 00000000..442b648c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_024.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_sys.h" + +static jmp_buf g_buf; + +static UINT32 First(VOID) +{ + int ret = _setjmp(g_buf); + if (ret) { + ICUNIT_ASSERT_EQUAL(ret, 2, ret); + goto OUT1; + } + _longjmp(g_buf, 2); +OUT1: + return 0; +} + +static UINT32 Sencond(VOID) +{ + int ret = _setjmp(g_buf); + if (ret) { + ICUNIT_ASSERT_EQUAL(ret, 1, ret); + goto OUT2; + } + _longjmp(g_buf, 0); + +OUT2: + return 0; +} + +static UINT32 TestCase(VOID) +{ + int ret = First(); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = Sencond(); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return 0; +} + +VOID ItTestSys024(VOID) +{ + TEST_ADD_CASE("IT_TEST_SYS_024", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_025.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_025.cpp new file mode 100644 index 00000000..db6d678b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_025.cpp @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_test_sys.h" +#include + +#define GROUPFILE "/etc/group" + +STATIC INT32 TestCase0(void) +{ + struct group getNam1 = { nullptr }; + struct group *getNam2 = nullptr; + struct group getData1 = { nullptr }; + struct group *getData2 = nullptr; + struct group *groupRet = nullptr; + CHAR buf[1000]; /* 1000, buffer for test */ + size_t len = sizeof(buf); + + INT32 ret = getgrgid_r(0, &getNam1, buf, len, &getNam2); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_NOT_EQUAL(getNam2, nullptr, getNam2); + ICUNIT_ASSERT_STRING_EQUAL(getNam2->gr_name, "root", getNam2->gr_name); + ICUNIT_ASSERT_STRING_EQUAL(getNam2->gr_passwd, "x", getNam2->gr_passwd); + ICUNIT_ASSERT_EQUAL(getNam2->gr_gid, 0, getNam2->gr_gid); + + groupRet = getgrgid(0); + ICUNIT_ASSERT_NOT_EQUAL(groupRet, nullptr, groupRet); + ICUNIT_ASSERT_STRING_EQUAL(groupRet->gr_name, "root", groupRet->gr_name); + ICUNIT_ASSERT_STRING_EQUAL(groupRet->gr_passwd, "x", groupRet->gr_passwd); + ICUNIT_ASSERT_EQUAL(groupRet->gr_gid, 0, groupRet->gr_gid); + + groupRet = getgrnam("root"); + ICUNIT_ASSERT_NOT_EQUAL(groupRet, nullptr, groupRet); + ICUNIT_ASSERT_STRING_EQUAL(groupRet->gr_name, "root", groupRet->gr_name); + ICUNIT_ASSERT_STRING_EQUAL(groupRet->gr_passwd, "x", groupRet->gr_passwd); + ICUNIT_ASSERT_EQUAL(groupRet->gr_gid, 0, groupRet->gr_gid); + + ret = getgrnam_r("root", &getData1, buf, len, &getData2); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_NOT_EQUAL(getData2, nullptr, getData2); + ICUNIT_ASSERT_STRING_EQUAL(getData2->gr_name, "root", getData2->gr_name); + ICUNIT_ASSERT_STRING_EQUAL(getData2->gr_passwd, "x", getData2->gr_passwd); + ICUNIT_ASSERT_EQUAL(getData2->gr_gid, 0, getData2->gr_gid); + return 0; +} + +STATIC INT32 TestCase1(void) +{ + INT32 len = 1000; + CHAR buf[1000]; + struct group getNam1 = { nullptr }; + struct group *getNam2 = nullptr; + struct group getData1 = { nullptr }; + struct group *getData2 = nullptr; + struct group *groupRet = nullptr; + + INT32 ret = getgrgid_r(-1, &getNam1, buf, len, &getNam2); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(errno, ENOENT, errno); + errno = 0; + + groupRet = getgrgid(-1); + ICUNIT_ASSERT_EQUAL(groupRet, 0, groupRet); + ICUNIT_ASSERT_EQUAL(errno, ENOENT, errno); + errno = 0; + + groupRet = getgrnam("null"); + ICUNIT_ASSERT_EQUAL(groupRet, nullptr, groupRet); + ICUNIT_ASSERT_EQUAL(errno, ENOENT, errno); + errno = 0; + + ret = getgrnam_r("null", &getData1, buf, len, &getData2); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(errno, ENOENT, errno); + errno = 0; + + return 0; +} + +STATIC INT32 TestCase(void) +{ + CHAR *pathList[] = {"/etc/group"}; + CHAR *streamList[] = {g_groupFileStream}; + INT32 streamLen[] = {strlen(g_groupFileStream)}; + + INT32 ret = PrepareFileEnv(pathList, streamList, streamLen, 1); + if (ret != 0) { + printf("error: need some env file, but prepare is not ok"); + (VOID)RecoveryFileEnv(pathList, 1); + return -1; + } + + ret = TestCase0(); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROUT); + + ret = TestCase1(); + ICUNIT_GOTO_EQUAL(ret, 0, re, ERROUT); + + (VOID)RecoveryFileEnv(pathList, 1); + return 0; +ERROUT: + (VOID)RecoveryFileEnv(pathList, 1); + return -1; +} + +VOID ItTestSys025(VOID) +{ + TEST_ADD_CASE("IT_TEST_SYS_025", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} + diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_026.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_026.cpp new file mode 100644 index 00000000..a730251b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_026.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_test_sys.h" +static int TestCase(void) +{ + char *name = getlogin(); + int ret = getlogin_r(name, sizeof(name)); // Abnormal Scenario Testing + ICUNIT_ASSERT_EQUAL(ret, 6, ret); + ret = setenv("LOGNAME", "USER1", 1); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + name = getlogin(); + ICUNIT_ASSERT_STRING_EQUAL(name, "USER1", name); + ret = getlogin_r(name, strlen(name) + 1); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = getlogin_r(name, 1); + ICUNIT_ASSERT_EQUAL(ret, 34, ret); + + ret = unsetenv("LOGNAME"); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + name = getlogin(); + ICUNIT_ASSERT_EQUAL(name, nullptr, name); + return 0; +} + +VOID ItTestSys026(VOID) +{ + TEST_ADD_CASE("IT_TEST_SYS_026", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_027.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_027.cpp new file mode 100644 index 00000000..6ebe8f73 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_027.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_test_sys.h" +#include "fcntl.h" +#include + +static UINT32 TestCase(VOID) +{ + int fd; + int ret1; + int ret2; + int id1 = 1; + int id2 = 2; + char *str1 = "/storage/1.txt"; + char *str2 = "/etc/2.txt"; + + fd = open(str1, O_CREAT); + if (fd < 0) { + return -1; + } + fd = open(str2, O_CREAT); + if (fd < 0) { + return -1; + } + ret1 = ftok(str1, id1); + ICUNIT_ASSERT_NOT_EQUAL(ret1, -1, ret1); + ret2 = ftok(str1, id2); + ICUNIT_ASSERT_NOT_EQUAL(ret1, -1, ret2); + ICUNIT_ASSERT_NOT_EQUAL(ret1, ret2, -1); + ret2 = ftok(str1, id1); + ICUNIT_ASSERT_EQUAL(ret1, ret2, -1); + ret2 = ftok(str2, id1); + ICUNIT_ASSERT_NOT_EQUAL(ret2, -1, ret2); + ICUNIT_ASSERT_NOT_EQUAL(ret1, ret2, -1); + return 0; +} + +VOID ItTestSys027(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_028.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_028.cpp new file mode 100644 index 00000000..9a3a243d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/sys/full/sys_test_028.cpp @@ -0,0 +1,60 @@ +/* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_sys.h" + +static UINT32 TestCase(VOID) +{ + int ret, status; + + pid_t pid = fork(); + if (pid == 0) { + ret = setpriority(PRIO_PROCESS, 0, 15); /* 15, set priority for test */ + if (ret != 0) { + exit(0); + } + ret = nice(0); + exit(ret); + } else { + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(status, 15, status); /* 15, set priority for test */ + + ret = nice(-40); /* -40, set invalid priority for test */ + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno); + } + return 0; +} + +VOID ItTestSys028(VOID) +{ + TEST_ADD_CASE(ItTestSys028, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_004.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_004.cpp new file mode 100644 index 00000000..cd13455d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_004.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_sys.h" + +#define MAX_NRAND48 0x80000000 + +static UINT32 TestCase(VOID) +{ + long x; + short unsigned int seed[3] = {1, 2, 3}; + + x = nrand48(seed); + if ((x < 0) || (x > MAX_NRAND48)) { + printf("[IN %s][line %d] x = %ld\n", __FUNCTION__, __LINE__, x); + goto EXIT; + } + + return 0; +EXIT: + return -1; +} + +VOID ItTestSys004(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_005.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_005.cpp new file mode 100644 index 00000000..0db849af --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_005.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_sys.h" + +#define MAX_RANDOM 0x80000000 + +static UINT32 TestCase(VOID) +{ + long x; + + x = random(); + if (x > static_cast(MAX_RANDOM - 1)) { + printf("[IN %s][line %d] x = %ld\n", __FUNCTION__, __LINE__, x); + goto EXIT; + } + + return 0; +EXIT: + return -1; +} + +VOID ItTestSys005(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_006.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_006.cpp new file mode 100644 index 00000000..c923415f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_006.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_sys.h" + +#define MAX_RANDOM 0x80000000 +static unsigned int g_seed = 123; + +static UINT32 TestCase(VOID) +{ + int x; + unsigned *pseed = &g_seed; + + x = rand_r(pseed); + printf("x= %d\n", x); + + if (x > abs(int(MAX_RANDOM - 1))) { + printf("[IN %s][line %d] x = %d\n", __FUNCTION__, __LINE__, x); + goto EXIT; + } + + return 0; +EXIT: + return -1; +} + +VOID ItTestSys006(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_007.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_007.cpp new file mode 100644 index 00000000..cc14a156 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_007.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_sys.h" + +#define MAX_RANDOM 0x80000000 +static unsigned short g_seed = 123; + +static UINT32 TestCase(VOID) +{ + double x; + unsigned short *pseed = &g_seed; + unsigned short *p = NULL; + + p = seed48(pseed); + ICUNIT_GOTO_NOT_EQUAL(p, NULL, p, EXIT); + + x = drand48(); + printf("x= %lf\n", x); + + return 0; +EXIT: + return -1; +} + +VOID ItTestSys007(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_008.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_008.cpp new file mode 100644 index 00000000..a3265976 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_008.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_sys.h" + +#define BUF_SIZE 256 + +static UINT32 TestCase(VOID) +{ + char ebuff[BUF_SIZE]; + int ret; + int cflags; + regex_t reg; + char *a = NULL; + char *b = const_cast("No error"); + char *testStr = const_cast("Hello World"); + char *regStr = const_cast("H.*"); + + cflags = REG_EXTENDED | REG_ICASE | REG_NOSUB; + + ret = regcomp(®, regStr, cflags); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = regexec(®, testStr, 0, NULL, 0); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + regerror(ret, ®, ebuff, BUF_SIZE); + a = ebuff; + ret = strcmp(a, b); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + regfree(®); + + return 0; +EXIT: + regerror(ret, ®, ebuff, BUF_SIZE); + fprintf(stderr, "%s\n", ebuff); + regfree(®); + + return -1; +} + + +VOID ItTestSys008(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_009.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_009.cpp new file mode 100644 index 00000000..d851f558 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_009.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_sys.h" + +static UINT32 TestCase(VOID) +{ + char *val = NULL; + const char *name = "ABC"; + char *env = const_cast("test-test"); + int ret; + + val = getenv(name); + ICUNIT_GOTO_EQUAL(val, NULL, val, EXIT); + + setenv(name, env, 1); + + val = getenv(name); + ret = strcmp(val, env); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = unsetenv("ABC"); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + val = getenv(name); + ICUNIT_GOTO_EQUAL(val, NULL, val, EXIT); + + return 0; +EXIT: + return -1; +} + +VOID ItTestSys009(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_010.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_010.cpp new file mode 100644 index 00000000..903bb979 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_010.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_sys.h" + +static UINT32 TestCase(VOID) +{ + char *plocale = NULL; + char *buffer = const_cast("C"); + int ret; + + plocale = setlocale(LC_ALL, NULL); + ret = strcmp(plocale, buffer); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + return 0; +EXIT: + return -1; +} + +VOID ItTestSys010(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_012.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_012.cpp new file mode 100644 index 00000000..130013e2 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_012.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_sys.h" + +static UINT32 TestCase(VOID) +{ + char *val = NULL; + char *val2 = NULL; + const char *name = "ABC"; + char *env = "test-test"; + int ret; + + val = getenv(name); + ICUNIT_GOTO_EQUAL(val, NULL, val, EXIT); + + setenv(name, env, 1); + + val = getenv(name); + val2 = secure_getenv(name); + ret = strcmp(val2, env); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ret = strcmp(val, env); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = unsetenv("ABC"); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + val = getenv(name); + ICUNIT_GOTO_EQUAL(val, NULL, val, EXIT); + + return 0; +EXIT: + return -1; +} + +VOID ItTestSys012(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_013.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_013.cpp new file mode 100644 index 00000000..08c63743 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_013.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_sys.h" + +struct q { + struct q *n; + struct q *p; + int i; +}; + +static struct q *New(int i) +{ + struct q *q = static_cast(malloc(sizeof *q)); + if (q != NULL) { + q->i = i; + } + + return q; +} + +static UINT32 TestCase(VOID) +{ + struct q *q = New(0); + struct q *p = NULL; + int i; + + insque(q, 0); + for (i = 1; i < 10; i++) { + insque(New(i), q); + q = q->n; + } + p = q; + while (q) { + if (q->i != --i) { + printf("[IN %s][line %d]walking queue: got %d, wanted %d\n", __FUNCTION__, __LINE__, q->i, i); + goto EXIT; + } + q = q->p; + } + remque(p->p); + if (p->p->i != p->i - 2) { + printf("[IN %s][line %d]remque: got %d, wanted %d\n", __FUNCTION__, __LINE__, p->p->i, p->i - 2); + goto EXIT; + } + if (p->p->n->i != p->i) { + printf("[IN %s][line %d]remque: got %d, wanted %d\n", __FUNCTION__, __LINE__, p->p->n->i, p->i); + goto EXIT; + } + + return 0; +EXIT: + return -1; +} + +VOID ItTestSys013(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_014.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_014.cpp new file mode 100644 index 00000000..9c224ae9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_014.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_sys.h" + +static void ShowFeExceptions(void) +{ + printf("current exceptions raised: "); + if (fetestexcept(FE_DIVBYZERO)) { + printf(" FE_DIVBYZERO"); + } + if (fetestexcept(FE_INEXACT)) { + printf(" FE_INEXACT"); + } + if (fetestexcept(FE_INVALID)) { + printf(" FE_INVALID"); + } + if (fetestexcept(FE_OVERFLOW)) { + printf(" FE_OVERFLOW"); + } + if (fetestexcept(FE_UNDERFLOW)) { + printf(" FE_UNDERFLOW"); + } + if (fetestexcept(FE_ALL_EXCEPT) == 0) { + printf(" none"); + } + printf("\n"); +} + +static double X2(double x) /* times two */ +{ + fenv_t currExcepts; + + /* Save and clear current f-p environment. */ + feholdexcept(&currExcepts); + + /* Raise inexact and overflow exceptions. */ + printf("In x2(): x = %f\n", x = x * 2.0); + ShowFeExceptions(); + feclearexcept(FE_INEXACT); /* hide inexact exception from caller */ + + /* Merge caller's exceptions (FE_INVALID) */ + /* with remaining x2's exceptions (FE_OVERFLOW). */ + feupdateenv(&currExcepts); + return x; +} + +static UINT32 TestCase(VOID) +{ + feclearexcept(FE_ALL_EXCEPT); + feraiseexcept(FE_INVALID); /* some computation with invalid argument */ + ShowFeExceptions(); + printf("x2(DBL_MAX) = %f\n", X2(DBL_MAX)); + ShowFeExceptions(); + + return 0; +EXIT: + return -1; +} + + +VOID ItTestSys014(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_015.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_015.cpp new file mode 100644 index 00000000..d31254cc --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_015.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_sys.h" + +#define TEST_NUM 123 + +static UINT32 TestCase(VOID) +{ + long a = TEST_NUM; + long b = 0; + char *pstr = NULL; + + pstr = l64a(a); + ICUNIT_GOTO_NOT_EQUAL(pstr, NULL, pstr, EXIT); + + b = a64l(pstr); + ICUNIT_GOTO_EQUAL(b, a, b, EXIT); + + return 0; +EXIT: + return -1; +} + +VOID ItTestSys015(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_016.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_016.cpp new file mode 100644 index 00000000..ce5df778 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_016.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_sys.h" + +static UINT32 TestCase(VOID) +{ + char *ptr = NULL; + int ret; + + ptr = basename(const_cast(".")); + ret = strcmp(ptr, "."); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ptr = basename(".."); + ret = strcmp(ptr, ".."); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ptr = basename("/"); + ret = strcmp(ptr, "/"); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ptr = basename("test1"); + ret = strcmp(ptr, "test1"); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ptr = basename("/test1/test2"); + ret = strcmp(ptr, "test2"); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + return 0; +EXIT: + return -1; +} + +VOID ItTestSys016(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_017.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_017.cpp new file mode 100644 index 00000000..224c4531 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_017.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_sys.h" + +const int password_length = 10; + +static UINT32 TestCase(VOID) +{ + char *passwd1 = NULL; + char *passwd2 = NULL; + char *key = NULL; + char slat[2]; + int ret; + char test_password[password_length]; + srand(time(NULL)); + for (int i = 0, r = 0; i < password_length; i++) { + r = rand() % 36; // 36: 0-9 and a-z + if (r < 10) { // 10: 0-9 + test_password[i] = '0' + r; + } else { + test_password[i] = 'a' + r; + } + } + + key = test_password; + slat[0] = key[0]; + slat[1] = key[1]; + passwd1 = crypt(key, slat); + ICUNIT_GOTO_NOT_EQUAL(passwd1, NULL, passwd1, EXIT); + + key = test_password; + slat[0] = passwd1[0]; + slat[1] = passwd1[1]; + passwd2 = crypt(key, slat); + ICUNIT_GOTO_NOT_EQUAL(passwd2, NULL, passwd2, EXIT); + + ret = strcmp(passwd1, passwd2); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + return 0; +EXIT: + return -1; +} + +VOID ItTestSys017(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_029.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_029.cpp new file mode 100644 index 00000000..d270433e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_029.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_test_sys.h" +#include + +static UINT32 TestCase(VOID) +{ + int ret1; + int id = 1; + char *str1 = "/storage/1"; + char str2[] = { 0 }; + + errno = 0; + ret1 = ftok(str1, id); + ICUNIT_ASSERT_EQUAL(ret1, -1, ret1); + ICUNIT_ASSERT_EQUAL(errno, ENOENT, errno); + + errno = 0; + ret1 = ftok(str2, id); + ICUNIT_ASSERT_EQUAL(ret1, -1, ret1); + ICUNIT_ASSERT_EQUAL(errno, ENOENT, errno); + + return 0; +} + +VOID ItTestSys029(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_030.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_030.cpp new file mode 100644 index 00000000..8e3bc49e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_030.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_test_sys.h" + + +sigjmp_buf jmp_env; +int val = 2; + +static void sig_alarm(int signum) +{ + siglongjmp(jmp_env, val); +} + +static UINT32 TestCase(VOID) +{ + return 0; +} + +VOID IT_TEST_SYS_030(VOID) +{ + TEST_ADD_CASE("IT_TEST_SYS_030", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_031.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_031.cpp new file mode 100644 index 00000000..a68858c0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/sys/smoke/sys_test_031.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_test_sys.h" + +static UINT32 TestCase(VOID) +{ + char buf1[100] = { 0 }; + char *str = nullptr; + + ctermid(buf1); + ICUNIT_ASSERT_STRING_EQUAL(buf1, "/dev/tty", -1); + str = ctermid(nullptr); + ICUNIT_ASSERT_STRING_EQUAL(str, "/dev/tty", -1); + + return 0; +} + +VOID IT_TEST_SYS_031(VOID) +{ + TEST_ADD_CASE("IT_TEST_SYS_031", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/sys/sys_unit_test.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/sys/sys_unit_test.cpp new file mode 100644 index 00000000..6514ae4a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/sys/sys_unit_test.cpp @@ -0,0 +1,332 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "stdio.h" +#include +#include + +#include "It_test_sys.h" + +CHAR *g_groupFileStream = "root:x:0:\ndaemon:x:1:\nbin:x:2:\n"; +CHAR *g_passwdFileStream = "root:x:0:0:root:/root:/bin/bash\n" \ + "daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin\nbin:x:2:2:bin:/bin:/usr/sbin/nologin\n"; + +using namespace testing::ext; +namespace OHOS { +class SysTest : public testing::Test { +public: + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} +}; + +#if defined(LOSCFG_USER_TEST_SMOKE) +/* * + * @tc.name: IT_TEST_SYS_004 + * @tc.desc: function for SysTest + * @tc.type: FUNC + */ +HWTEST_F(SysTest, ItTestSys004, TestSize.Level0) +{ + ItTestSys004(); +} + +/* * + * @tc.name: IT_TEST_SYS_005 + * @tc.desc: function for SysTest + * @tc.type: FUNC + */ +HWTEST_F(SysTest, ItTestSys005, TestSize.Level0) +{ + ItTestSys005(); +} + +/* * + * @tc.name: IT_TEST_SYS_006 + * @tc.desc: function for SysTest + * @tc.type: FUNC + */ +HWTEST_F(SysTest, ItTestSys006, TestSize.Level0) +{ + ItTestSys006(); +} + +/* * + * @tc.name: IT_TEST_SYS_007 + * @tc.desc: function for SysTest + * @tc.type: FUNC + */ +HWTEST_F(SysTest, ItTestSys007, TestSize.Level0) +{ + ItTestSys007(); +} + +/* * + * @tc.name: IT_TEST_SYS_008 + * @tc.desc: function for SysTest + * @tc.type: FUNC + */ +HWTEST_F(SysTest, ItTestSys008, TestSize.Level0) +{ + ItTestSys008(); +} + +/* * + * @tc.name: IT_TEST_SYS_009 + * @tc.desc: function for SysTest + * @tc.type: FUNC + */ +HWTEST_F(SysTest, ItTestSys009, TestSize.Level0) +{ + ItTestSys009(); +} + +/* * + * @tc.name: IT_TEST_SYS_010 + * @tc.desc: function for SysTest + * @tc.type: FUNC + */ +HWTEST_F(SysTest, ItTestSys010, TestSize.Level0) +{ + ItTestSys010(); +} + +/* * + * @tc.name: IT_TEST_SYS_012 + * @tc.desc: function for SysTest + * @tc.type: FUNC + */ +HWTEST_F(SysTest, ItTestSys012, TestSize.Level0) +{ + ItTestSys012(); +} + +/* * + * @tc.name: IT_TEST_SYS_013 + * @tc.desc: function for SysTest + * @tc.type: FUNC + */ +HWTEST_F(SysTest, ItTestSys013, TestSize.Level0) +{ + ItTestSys013(); +} + +/* * + * @tc.name: IT_TEST_SYS_014 + * @tc.desc: function for SysTest + * @tc.type: FUNC + */ +HWTEST_F(SysTest, ItTestSys014, TestSize.Level0) +{ + ItTestSys014(); +} + +/* * + * @tc.name: IT_TEST_SYS_015 + * @tc.desc: function for SysTest + * @tc.type: FUNC + */ +HWTEST_F(SysTest, ItTestSys015, TestSize.Level0) +{ + ItTestSys015(); +} + +/* * + * @tc.name: IT_TEST_SYS_016 + * @tc.desc: function for SysTest + * @tc.type: FUNC + */ +HWTEST_F(SysTest, ItTestSys016, TestSize.Level0) +{ + ItTestSys016(); +} + +/* * + * @tc.name: IT_TEST_SYS_017 + * @tc.desc: function for SysTest + * @tc.type: FUNC + */ +HWTEST_F(SysTest, ItTestSys017, TestSize.Level0) +{ + ItTestSys017(); +} + +/* * + * @tc.name: IT_TEST_SYS_029 + * @tc.desc: function for ftok exception test + * @tc.type: FUNC + */ +HWTEST_F(SysTest, ItTestSys029, TestSize.Level0) +{ + ItTestSys029(); +} + +/* * + * @tc.name: IT_TEST_SYS_030 + * @tc.desc: function for sigsetjmp siglongjmp test + * @tc.type: FUNC + */ +HWTEST_F(SysTest, IT_TEST_SYS_030, TestSize.Level0) +{ + IT_TEST_SYS_030(); +} + +/* * + * @tc.name: IT_TEST_SYS_031 + * @tc.desc: function for ctermid test + * @tc.type: FUNC + */ +HWTEST_F(SysTest, IT_TEST_SYS_031, TestSize.Level0) +{ + IT_TEST_SYS_031(); +} +#endif + +#if defined(LOSCFG_USER_TEST_FULL) +/* * + * @tc.name: IT_TEST_SYS_001 + * @tc.desc: function for SysTest + * @tc.type: FUNC + */ +HWTEST_F(SysTest, ItTestSys001, TestSize.Level0) +{ + ItTestSys001(); +} + +/* * + * @tc.name: IT_TEST_SYS_018 + * @tc.desc: function for SysTest + * @tc.type: FUNC + */ +HWTEST_F(SysTest, ItTestSys018, TestSize.Level0) +{ + ItTestSys018(); +} + +/* * + * @tc.name: IT_TEST_SYS_019 + * @tc.desc: function for SysTest + * @tc.type: FUNC + */ +HWTEST_F(SysTest, ItTestSys019, TestSize.Level0) +{ + ItTestSys019(); +} + +/* * + * @tc.name: IT_TEST_SYS_020 + * @tc.desc: function for SysTest + * @tc.type: FUNC + */ +HWTEST_F(SysTest, ItTestSys020, TestSize.Level0) +{ + ItTestSys020(); +} + +/* * + * @tc.name: IT_TEST_SYS_021 + * @tc.desc: function for SysTest + * @tc.type: FUNC + */ +HWTEST_F(SysTest, ItTestSys021, TestSize.Level0) +{ + ItTestSys021(); +} + +/* * + * @tc.name: IT_TEST_SYS_022 + * @tc.desc: function for SysTest + * @tc.type: FUNC + */ +HWTEST_F(SysTest, ItTestSys022, TestSize.Level0) +{ + ItTestSys022(); +} + +/* * + * @tc.name: IT_TEST_SYS_023 + * @tc.desc: function for SysTest + * @tc.type: FUNC + */ +HWTEST_F(SysTest, ItTestSys023, TestSize.Level0) +{ + ItTestSys023(); +} + +/* * + * @tc.name: IT_TEST_SYS_024 + * @tc.desc: function for SysTest + * @tc.type: FUNC + */ +HWTEST_F(SysTest, ItTestSys024, TestSize.Level0) +{ + ItTestSys024(); +} + +/* * + * @tc.name: IT_TEST_SYS_025 + * @tc.desc: function for SysTest + * @tc.type: FUNC + */ +HWTEST_F(SysTest, ItTestSys025, TestSize.Level0) +{ + ItTestSys025(); +} + +/* * + * @tc.name: IT_TEST_SYS_025 + * @tc.desc: function for SysTest + * @tc.type: FUNC + */ +HWTEST_F(SysTest, ItTestSys026, TestSize.Level0) +{ + ItTestSys026(); +} + +/* * + * @tc.name: IT_TEST_SYS_027 + * @tc.desc: function for ftok normal test + * @tc.type: FUNC + */ +HWTEST_F(SysTest, ItTestSys027, TestSize.Level0) +{ + ItTestSys027(); +} + +/* * + * @tc.name: ItTestSys028 + * @tc.desc: function for nice:set pthread priority + * @tc.type: FUNC + */ +HWTEST_F(SysTest, ItTestSys028, TestSize.Level0) +{ + ItTestSys028(); +} +#endif +} // namespace OHOS diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/time/BUILD.gn b/src/kernel_liteos_a/testsuites/unittest/libc/time/BUILD.gn new file mode 100644 index 00000000..6441afa8 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/time/BUILD.gn @@ -0,0 +1,66 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("./config.gni") + +config("libc_config") { + if (LOSCFG_USER_TEST_LIBC_POSIX_MQUEUE == true || + LOSCFG_USER_TEST_LIBC_POSIX_PTHREAD == true) { + cflags = [ "-O1" ] + cflags_cc = cflags + } +} + +if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_LOW) { + unittest("liteos_a_libc_time_unittest_door") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + include_dirs = common_include_dirs + sources = sources_entry + sources += sources_smoke + sources_full = [] + sources += sources_full + configs = [ "../..:public_config_for_door" ] + configs += [ ":libc_config" ] + deps = [ "$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR:libsec_shared" ] + } +} + +if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_MIDDLE) { + unittest("liteos_a_libc_time_unittest") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + include_dirs = common_include_dirs + sources = sources_entry + sources += sources_smoke + sources += sources_full + configs = [ "../..:public_config_for_all" ] + configs += [ ":libc_config" ] + deps = [ "$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR:libsec_shared" ] + } +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/config.gni b/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/config.gni new file mode 100644 index 00000000..bfca2c94 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/config.gni @@ -0,0 +1,51 @@ +# Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//build/lite/config/test.gni") +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +libc_time_clock_include_dirs = [ "$TEST_UNITTEST_DIR/libc/time/clock" ] + +libc_time_clock_sources_entry = + [ "$TEST_UNITTEST_DIR/libc/time/clock/time_clock_test.cpp" ] + +libc_time_clock_sources_smoke = + [ "$TEST_UNITTEST_DIR/libc/time/clock/smoke/clock_test_smoke.cpp" ] + +libc_time_clock_sources_full = [ + "$TEST_UNITTEST_DIR/libc/time/clock/full/clock_test_001.cpp", + "$TEST_UNITTEST_DIR/libc/time/clock/full/clock_test_002.cpp", + "$TEST_UNITTEST_DIR/libc/time/clock/full/clock_test_003.cpp", + "$TEST_UNITTEST_DIR/libc/time/clock/full/clock_test_004.cpp", + "$TEST_UNITTEST_DIR/libc/time/clock/full/clock_test_005.cpp", + "$TEST_UNITTEST_DIR/libc/time/clock/full/clock_test_006.cpp", + "$TEST_UNITTEST_DIR/libc/time/clock/full/clock_test_007.cpp", + "$TEST_UNITTEST_DIR/libc/time/clock/full/clock_test_008.cpp", + "$TEST_UNITTEST_DIR/libc/time/clock/full/clock_test_009.cpp", + "$TEST_UNITTEST_DIR/libc/time/clock/full/clock_test_010.cpp", +] diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/full/clock_test_001.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/full/clock_test_001.cpp new file mode 100644 index 00000000..de8e2a4a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/full/clock_test_001.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include "lt_clock_test.h" +#include + +/* When clock time is changed, timers for a relative interval are unaffected, + * but timers for an absolute point in time are affected. + */ +static int ClockTest(void) +{ + clockid_t clk = CLOCK_REALTIME; + struct timespec res, tp, oldtp; + int ret; + int passflag = 0; + + /* get clock resolution */ + ret = clock_getres(clk, &res); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(res.tv_sec, CLOCK_RES_SEC, res.tv_sec); + ICUNIT_ASSERT_EQUAL(res.tv_nsec, CLOCK_RES_NSEC, res.tv_nsec); + + /* get current real time */ + ret = clock_gettime(clk, &oldtp); + printf("The current real time: sec is %lld, nsec is %ld\n", oldtp.tv_sec, oldtp.tv_nsec); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + printf("sleep 2 seconds\n"); + sleep(2); // 2, seconds. + + tp.tv_sec = oldtp.tv_sec + 2; // 2, use for testing clock setting + tp.tv_nsec = oldtp.tv_nsec; + + /* set real time */ + ret = clock_settime(clk, &tp); + printf("Setting time: sec is %lld, nsec is %ld\n", tp.tv_sec, tp.tv_nsec); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + printf("get real time clock again\n"); + + /* get current real time again */ + ret = clock_gettime(clk, &tp); + printf("Obtaining the current time after setting: sec = %lld, nsec = %ld\n", tp.tv_sec, tp.tv_nsec); + passflag = (tp.tv_sec >= 2 + oldtp.tv_sec) && (tp.tv_sec <= 2 + oldtp.tv_sec + 1); // 2, use for testing clock setting + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(passflag, true, passflag); + + return 0; +} + +void ClockTest001(void) +{ + TEST_ADD_CASE(__FUNCTION__, ClockTest, TEST_POSIX, TEST_TIMES, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/full/clock_test_002.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/full/clock_test_002.cpp new file mode 100644 index 00000000..f951d878 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/full/clock_test_002.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "lt_clock_test.h" + +static void *ThreadFuncTest(void *arg) +{ + printf("Subthread starting infinite loop\n"); + while (1) { + pthread_testcancel(); + } +} + +static int ThreadClock(const char *msg, clockid_t cid) +{ + struct timespec ts; + int ret; + + printf("%s", msg); + ret = clock_gettime(cid, &ts); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + printf("%lld.%03ld s\n", ts.tv_sec, ts.tv_nsec / 1000000); // 1000000, 1ms. + return 0; +} + +static int ClockTest(void) +{ + pthread_t thread; + clockid_t clockid; + int ret; + struct timespec ts; + + ret = pthread_create(&thread, NULL, ThreadFuncTest, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + printf("Main thread sleeping\n"); + sleep(1); + + printf("Main thread consuming some CPU time...\n"); + usleep(400000); // 400000 delay for test + + /* get current pthread clockid */ + ret = pthread_getcpuclockid(pthread_self(), &clockid); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = ThreadClock("Main thread CPU time: ", clockid); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + /* get create pthread clockid */ + ret = pthread_getcpuclockid(thread, &clockid); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = ThreadClock("Subthread CPU time: ", clockid); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_cancel(thread); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return 0; +} + +void ClockTest002(void) +{ + TEST_ADD_CASE(__FUNCTION__, ClockTest, TEST_POSIX, TEST_TIMES, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/full/clock_test_003.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/full/clock_test_003.cpp new file mode 100644 index 00000000..d37ae98b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/full/clock_test_003.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "lt_clock_test.h" + +static int ClockTest(void) +{ + clockid_t clockid; + struct timespec ts; + int ret; + pid_t pid = 0; + int passflag = 0; + + /* get kernel process 1 clockid */ + pid = 1; + ret = clock_getcpuclockid(1, &clockid); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(clockid, CLOCK_GET_CPU_CLOCKID(pid), clockid); + + /* get clockid time */ + ret = clock_gettime(clockid, &ts); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + printf("Obtaining the process running time: %lld second, %ld nanosecond\n", ts.tv_sec, ts.tv_nsec); + + /* get user process 2 clockid */ + pid = 2; // 2, test the process 2 (An existent pid) + ret = clock_getcpuclockid(2, &clockid); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(clockid, CLOCK_GET_CPU_CLOCKID(pid), clockid); + + /* get clockid time */ + ret = clock_gettime(clockid, &ts); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + printf("Obtaining the process running time: %lld second, %ld nanosecond\n", ts.tv_sec, ts.tv_nsec); + + /* get current process clockid */ + pid = getpid(); + ret = clock_getcpuclockid(getpid(), &clockid); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(clockid, CLOCK_GET_CPU_CLOCKID(pid), clockid); + + /* get clockid time */ + ret = clock_gettime(clockid, &ts); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + printf("Obtaining the process running time: %lld second, %ld nanosecond\n", ts.tv_sec, ts.tv_nsec); + + return 0; +} + +void ClockTest003(void) +{ + TEST_ADD_CASE(__FUNCTION__, ClockTest, TEST_POSIX, TEST_TIMES, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/full/clock_test_004.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/full/clock_test_004.cpp new file mode 100644 index 00000000..5add0e14 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/full/clock_test_004.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "lt_clock_test.h" + +static int ClockTest(void) +{ + pthread_t thread; + clockid_t clockid; + int ret; + struct timespec ts; + + /* check param invalid */ + ret = clock_gettime(-2050, &ts); // 2050, clock id. + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno); + + return 0; +} + +void ClockTest004(void) +{ + TEST_ADD_CASE(__FUNCTION__, ClockTest, TEST_POSIX, TEST_TIMES, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/full/clock_test_005.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/full/clock_test_005.cpp new file mode 100644 index 00000000..8db361ac --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/full/clock_test_005.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "lt_clock_test.h" + +static int ClockTest(void) +{ + clockid_t clockid; + struct timespec ts; + int ret; + pid_t pid = 0; + + /* check param invalid */ + ret = clock_getcpuclockid(pid, &clockid); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + pid = 65; // 65, non existent process id. + ret = clock_getcpuclockid(pid, &clockid); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + return 0; +} + +void ClockTest005(void) +{ + TEST_ADD_CASE(__FUNCTION__, ClockTest, TEST_POSIX, TEST_TIMES, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/full/clock_test_006.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/full/clock_test_006.cpp new file mode 100644 index 00000000..1585f406 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/full/clock_test_006.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include "lt_clock_test.h" +#include + +/* When clock time is changed, timers for a relative interval are unaffected, + * but timers for an absolute point in time are affected. + */ +static int ClockTest(void) +{ + clockid_t clk = CLOCK_REALTIME_COARSE; + struct timespec res, tp, oldtp; + int ret; + int passflag = 0; + + /* get clock resolution */ + ret = clock_getres(clk, &res); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(res.tv_sec, CLOCK_COARSE_RES_SEC, res.tv_sec); + ICUNIT_ASSERT_EQUAL(res.tv_nsec, CLOCK_COARSE_RES_NSEC, res.tv_nsec); + + /* get current real coarse time */ + ret = clock_gettime(clk, &oldtp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + printf("The current coarse real time: sec is %lld, nsec is %ld\n", oldtp.tv_sec, oldtp.tv_nsec); + + tp.tv_sec = 5 * oldtp.tv_sec; // 5, times the number of seconds. + tp.tv_nsec = oldtp.tv_nsec; // 5, times the number of nseconds. + + /* set real coarse time */ + ret = clock_settime(clk, &tp); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, EOPNOTSUPP, errno); + + printf("get coarse real time clock again\n"); + + /* get current real coarse time again */ + ret = clock_gettime(clk, &tp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + printf("The current coarse real time again: sec is %lld, nsec is %ld\n", tp.tv_sec, tp.tv_nsec); + passflag = (tp.tv_sec >= oldtp.tv_sec) && (tp.tv_sec <= oldtp.tv_sec + 1); + ICUNIT_ASSERT_EQUAL(passflag, 1, passflag); + + return 0; +} + +void ClockTest006(void) +{ + TEST_ADD_CASE(__FUNCTION__, ClockTest, TEST_POSIX, TEST_TIMES, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/full/clock_test_007.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/full/clock_test_007.cpp new file mode 100644 index 00000000..ae574345 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/full/clock_test_007.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include "lt_clock_test.h" +#include + +/* When clock time is changed, timers for a relative interval are unaffected, + * but timers for an absolute point in time are affected. + */ +static int ClockTest(void) +{ + clockid_t clk = CLOCK_MONOTONIC_COARSE; + struct timespec res, tp, oldtp; + int ret; + int passflag = 0; + /* get clock resolution */ + ret = clock_getres(clk, &res); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(res.tv_sec, CLOCK_COARSE_RES_SEC, res.tv_sec); + ICUNIT_ASSERT_EQUAL(res.tv_nsec, CLOCK_COARSE_RES_NSEC, res.tv_nsec); + + /* get current monotonic coarse time */ + ret = clock_gettime(clk, &oldtp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + printf("The current monotonic coarse time: sec is %lld, nsec is %ld\n", oldtp.tv_sec, oldtp.tv_nsec); + + tp.tv_sec = 5 * res.tv_sec; // 5, times the number of seconds. + tp.tv_nsec = res.tv_nsec; + + /* set monotonic coarse time */ + ret = clock_settime(clk, &tp); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, EOPNOTSUPP, errno); + + printf("get coarse monotonic time clock again\n"); + + /* get current monotonic coarse time again */ + ret = clock_gettime(clk, &tp); + passflag = (tp.tv_sec >= oldtp.tv_sec) && (tp.tv_sec <= oldtp.tv_sec + 1); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(passflag, 1, passflag); + printf("The current monotonic coarse time again: sec is %lld, nsec is %ld\n", tp.tv_sec, tp.tv_nsec); + + return 0; +} + +void ClockTest007(void) +{ + TEST_ADD_CASE(__FUNCTION__, ClockTest, TEST_POSIX, TEST_TIMES, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/full/clock_test_008.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/full/clock_test_008.cpp new file mode 100644 index 00000000..436123af --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/full/clock_test_008.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include "lt_clock_test.h" + +/* When clock time is changed, timers for a relative interval are unaffected, + * but timers for an absolute point in time are affected. + */ +static int ClockTest(void) +{ + clockid_t clk = CLOCK_MONOTONIC; + struct timespec res, tp, oldtp; + int ret; + int passflag = 0; + + /* get clock resolution */ + ret = clock_getres(clk, &res); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(res.tv_sec, CLOCK_RES_SEC, res.tv_sec); + ICUNIT_ASSERT_EQUAL(res.tv_nsec, CLOCK_RES_NSEC, res.tv_nsec); + + /* get current monotonic time */ + ret = clock_gettime(clk, &oldtp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + printf("The current monotonic time: sec is %lld, nsec is %ld\n", oldtp.tv_sec, oldtp.tv_nsec); + + tp.tv_sec = 5 * oldtp.tv_sec; // 5, times the number of seconds. + tp.tv_nsec = oldtp.tv_nsec; + + /* set real time */ + ret = clock_settime(clk, &tp); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno); + + LogPrintln("get monotonic time clock again\n"); + + /* get current monotonic time again */ + ret = clock_gettime(clk, &tp); + passflag = (tp.tv_sec >= oldtp.tv_sec) && (tp.tv_sec <= oldtp.tv_sec + 1); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(passflag, 1, passflag); + printf("The current monotonic time: sec is %lld, nsec is %ld\n", tp.tv_sec, tp.tv_nsec); + + return 0; +} + +void ClockTest008(void) +{ + TEST_ADD_CASE(__FUNCTION__, ClockTest, TEST_POSIX, TEST_TIMES, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/full/clock_test_009.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/full/clock_test_009.cpp new file mode 100644 index 00000000..c6296625 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/full/clock_test_009.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include "lt_clock_test.h" +#include + +/* When clock time is changed, timers for a relative interval are unaffected, + * but timers for an absolute point in time are affected. + */ +static int ClockTest(void) +{ + clockid_t clk = CLOCK_MONOTONIC_RAW; + struct timespec res, tp, oldtp; + int ret; + int passflag = 0; + + /* get clock resolution */ + ret = clock_getres(clk, &res); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(res.tv_sec, CLOCK_RES_SEC, res.tv_sec); + ICUNIT_ASSERT_EQUAL(res.tv_nsec, CLOCK_RES_NSEC, res.tv_nsec); + + /* get current monotonic raw time */ + ret = clock_gettime(clk, &oldtp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + printf("The current monotonic raw time: sec is %lld, nsec is %ld\n", oldtp.tv_sec, oldtp.tv_nsec); + + tp.tv_sec = 5 * res.tv_sec; // 5, times the number of seconds. + tp.tv_nsec = res.tv_nsec; + + /* set monotonic raw time */ + ret = clock_settime(clk, &tp); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, EOPNOTSUPP, errno); + + printf("get monotonic raw time clock again\n"); + + /* get current monotonic raw time again */ + ret = clock_gettime(clk, &tp); + passflag = (tp.tv_sec >= oldtp.tv_sec) && (tp.tv_sec <= oldtp.tv_sec + 1); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(passflag, 1, passflag); + printf("The current monotonic raw time again: sec is %lld, nsec is %ld\n", tp.tv_sec, tp.tv_nsec); + + return 0; +} + +void ClockTest009(void) +{ + TEST_ADD_CASE(__FUNCTION__, ClockTest, TEST_POSIX, TEST_TIMES, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/full/clock_test_010.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/full/clock_test_010.cpp new file mode 100644 index 00000000..e57dc25a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/full/clock_test_010.cpp @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include "lt_clock_test.h" +#include + +static int g_failCnt = 0; + +static int SleepTest(int64_t expectTime) +{ + clockid_t clk = CLOCK_REALTIME; + struct timespec tp, oldtp; + int ret; + int64_t escapeTime; + + /* get current real time */ + ret = clock_gettime(clk, &oldtp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + tp.tv_sec = expectTime / static_cast(1e9); + tp.tv_nsec = expectTime % static_cast(1e9); + ret = clock_nanosleep(clk, 0, &tp, nullptr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + /* get current real time again */ + ret = clock_gettime(clk, &tp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + escapeTime = (tp.tv_sec - oldtp.tv_sec) * static_cast(1e9) + (tp.tv_nsec - oldtp.tv_nsec); + LogPrintln("slept time (expected --> actual): %" PRId64 "ns --> %" PRId64 "ns, delta: %" PRId64 "ns\n", expectTime, + escapeTime, escapeTime - expectTime); + + g_failCnt += (escapeTime < expectTime); + + return 0; +} + +static void *ClockTestThread(void *arg) +{ + (void)SleepTest(0); + (void)SleepTest(2); // 2, ns. + (void)SleepTest(3); // 3, ns. + (void)SleepTest(40e3); // 40us + (void)SleepTest(50e3); // 50us + (void)SleepTest(50e3 + 1); // 50us+1ns + (void)SleepTest(60e3); // 60us + (void)SleepTest(65e3); // 65us + (void)SleepTest(5e6); // 5ms + (void)SleepTest(10e6); // 10ms + (void)SleepTest(10e6 + 1); // 10ms+1ns + (void)SleepTest(25e6); // 25ms + (void)SleepTest(1e9); // 1s + + return NULL; +} + +static int ClockTest(void) +{ + int ret; + pthread_t thread; + struct sched_param param = { 0 }; + pthread_attr_t attr; + pthread_attr_init(&attr); + + pthread_attr_setschedpolicy(&attr, SCHED_FIFO); + pthread_attr_setschedparam(&attr, ¶m); + + ret = pthread_create(&thread, &attr, ClockTestThread, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(thread, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_EQUAL(g_failCnt, 0, g_failCnt); + return 0; +} + +void ClockTest010(void) +{ + TEST_ADD_CASE(__FUNCTION__, ClockTest, TEST_POSIX, TEST_TIMES, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/lt_clock_test.h b/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/lt_clock_test.h new file mode 100644 index 00000000..9819361c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/lt_clock_test.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef TIME_CLOCK_LT_CLOCK_TEST_H_ +#define TIME_CLOCK_LT_CLOCK_TEST_H_ +#include +#include +#include +#include +#include +#include "osTest.h" + +#define CLOCK_RES_SEC 0 +#define CLOCK_RES_NSEC 1000 +#define CLOCK_COARSE_RES_SEC 0 +#define CLOCK_COARSE_RES_NSEC 1000000 +#define CLOCK_GET_CPU_CLOCKID(pid) ((-(pid) - 1) * 8U + 2) + +void ClockTestSmoke(void); +void ClockTest001(void); +void ClockTest002(void); +void ClockTest003(void); +void ClockTest004(void); +void ClockTest005(void); +void ClockTest006(void); +void ClockTest007(void); +void ClockTest008(void); +void ClockTest009(void); +void ClockTest010(void); + +#endif /* TIME_CLOCK_LT_CLOCK_TEST_H_ */ diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/smoke/clock_test_smoke.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/smoke/clock_test_smoke.cpp new file mode 100644 index 00000000..bde8e6ef --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/smoke/clock_test_smoke.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "lt_clock_test.h" + +static int ClockSmokeTest(void) +{ + clockid_t clk = CLOCK_REALTIME; + struct timespec res = {0,0}, setts = {0,0}, oldtp = {0,0}, ts = {0,0}; + int ret; + int passflag = 0; + + /* get clock resolution */ + ret = clock_getres(clk, &res); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(res.tv_sec, CLOCK_RES_SEC, res.tv_sec); + ICUNIT_ASSERT_EQUAL(res.tv_nsec, CLOCK_RES_NSEC, res.tv_nsec); + + /* get clock realtime */ + ret = clock_gettime(clk, &oldtp); + printf("the clock current time: %lld second, %ld nanosecond\n", oldtp.tv_sec, oldtp.tv_nsec); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + /* set clock realtime */ + setts.tv_sec = oldtp.tv_sec + 1; + setts.tv_nsec = oldtp.tv_nsec; + printf("the clock setting time: %lld second, %ld nanosecond\n", setts.tv_sec, setts.tv_nsec); + ret = clock_settime(CLOCK_REALTIME, &setts); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = clock_gettime(clk, &ts); + printf("obtaining the current time after setting: %lld second, %ld nanosecond\n", ts.tv_sec, ts.tv_nsec); + passflag = (ts.tv_sec >= setts.tv_sec) && (ts.tv_sec <= setts.tv_sec + 1); // 1, means obtaining time's errno is 1 second. + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(passflag, true, passflag); + return 0; +} + +void ClockTestSmoke(void) +{ + TEST_ADD_CASE(__FUNCTION__, ClockSmokeTest, TEST_POSIX, TEST_TIMES, TEST_LEVEL0, TEST_FUNCTION); +} + diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/time_clock_test.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/time_clock_test.cpp new file mode 100644 index 00000000..dee01cf1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/time/clock/time_clock_test.cpp @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "stdio.h" +#include +#include + +#include "lt_clock_test.h" + +using namespace testing::ext; +namespace OHOS { +class TimeClockTest : public testing::Test { +public: + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} +}; + +#if defined(LOSCFG_USER_TEST_SMOKE) +/* * + * @tc.name: ClockTestSmoke + * @tc.desc: function for TimeClockTest + * @tc.type: FUNC + */ +HWTEST_F(TimeClockTest, ClockTestSmoke, TestSize.Level0) +{ + ClockTestSmoke(); +} +#endif + +#if defined(LOSCFG_USER_TEST_FULL) +/* * + * @tc.name: ClockTest001 + * @tc.desc: function for TimeClockTest + * @tc.type: FUNC + */ +HWTEST_F(TimeClockTest, ClockTest001, TestSize.Level0) +{ + ClockTest001(); +} + +/* * + * @tc.name: ClockTest002 + * @tc.desc: function for TimeClockTest + * @tc.type: FUNC + */ +HWTEST_F(TimeClockTest, ClockTest002, TestSize.Level0) +{ + ClockTest002(); +} + +/* * + * @tc.name: ClockTest003 + * @tc.desc: function for TimeClockTest + * @tc.type: FUNC + */ +HWTEST_F(TimeClockTest, ClockTest003, TestSize.Level0) +{ + ClockTest003(); +} + +/* * + * @tc.name: ClockTest004 + * @tc.desc: function for TimeClockTest + * @tc.type: FUNC + */ +HWTEST_F(TimeClockTest, ClockTest004, TestSize.Level0) +{ + ClockTest004(); // clock_getcpuclockid not supported on HMOS currently +} + +/* * + * @tc.name: ClockTest005 + * @tc.desc: function for TimeClockTest + * @tc.type: FUNC + */ +HWTEST_F(TimeClockTest, ClockTest005, TestSize.Level0) +{ + ClockTest005(); +} + +/* * + * @tc.name: ClockTest006 + * @tc.desc: function for TimeClockTest + * @tc.type: FUNC + */ +HWTEST_F(TimeClockTest, ClockTest006, TestSize.Level0) +{ + ClockTest006(); +} + +/* * + * @tc.name: ClockTest007 + * @tc.desc: function for TimeClockTest + * @tc.type: FUNC + */ +HWTEST_F(TimeClockTest, ClockTest007, TestSize.Level0) +{ + ClockTest007(); +} + +/* * + * @tc.name: ClockTest008 + * @tc.desc: function for TimeClockTest + * @tc.type: FUNC + */ +HWTEST_F(TimeClockTest, ClockTest008, TestSize.Level0) +{ + ClockTest008(); +} + +/* * + * @tc.name: ClockTest009 + * @tc.desc: function for TimeClockTest + * @tc.type: FUNC + */ +HWTEST_F(TimeClockTest, ClockTest009, TestSize.Level0) +{ + ClockTest009(); +} + +/* * + * @tc.name: ClockTest010 + * @tc.desc: function for TimeClockTest + * @tc.type: FUNC + */ +HWTEST_F(TimeClockTest, ClockTest010, TestSize.Level0) +{ + ClockTest010(); +} + +#endif +} // namespace OHOS diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/time/config.gni b/src/kernel_liteos_a/testsuites/unittest/libc/time/config.gni new file mode 100644 index 00000000..b413e23a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/time/config.gni @@ -0,0 +1,60 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//build/lite/config/test.gni") +import("//kernel/liteos_a/liteos.gni") +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +common_include_dirs = [ + "$THIRDPARTY_GOOGLETEST_DIR/googletest/include", + "../../common/include", +] + +sources_entry = [ "../../common/osTest.cpp" ] + +sources_smoke = [] + +sources_full = [] + +# libc time clock module +if (LOSCFG_USER_TEST_LIBC_TIME_CLOCK == true) { + import("./clock/config.gni") + common_include_dirs += libc_time_clock_include_dirs + sources_entry += libc_time_clock_sources_entry + sources_smoke += libc_time_clock_sources_smoke + sources_full += libc_time_clock_sources_full +} + +# libc time timer module +if (LOSCFG_USER_TEST_LIBC_TIME_TIMER == true) { + import("./timer/config.gni") + common_include_dirs += libc_time_timer_include_dirs + sources_entry += libc_time_timer_sources_entry + sources_smoke += libc_time_timer_sources_smoke + sources_full += libc_time_timer_sources_full +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/time/timer/config.gni b/src/kernel_liteos_a/testsuites/unittest/libc/time/timer/config.gni new file mode 100644 index 00000000..319427fa --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/time/timer/config.gni @@ -0,0 +1,47 @@ +# Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//build/lite/config/test.gni") +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +libc_time_timer_include_dirs = [ "$TEST_UNITTEST_DIR/libc/time/timer" ] + +libc_time_timer_sources_entry = + [ "$TEST_UNITTEST_DIR/libc/time/timer/time_timer_test.cpp" ] + +libc_time_timer_sources_smoke = [ + "$TEST_UNITTEST_DIR/libc/time/timer/smoke/timer_test_001.cpp", + "$TEST_UNITTEST_DIR/libc/time/timer/smoke/timer_test_002.cpp", + "$TEST_UNITTEST_DIR/libc/time/timer/smoke/timer_test_003.cpp", + "$TEST_UNITTEST_DIR/libc/time/timer/smoke/timer_test_004.cpp", + "$TEST_UNITTEST_DIR/libc/time/timer/smoke/timer_test_005.cpp", + "$TEST_UNITTEST_DIR/libc/time/timer/smoke/timer_test_tzset_001.cpp", + "$TEST_UNITTEST_DIR/libc/time/timer/smoke/timer_test_tzset_002.cpp", +] + +libc_time_timer_sources_full = [] diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/time/timer/lt_timer_test.h b/src/kernel_liteos_a/testsuites/unittest/libc/time/timer/lt_timer_test.h new file mode 100644 index 00000000..1c5ab9a0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/time/timer/lt_timer_test.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef TIME_TIMER_LT_TIMER_TEST_H +#define TIME_TIMER_LT_TIMER_TEST_H + +#include +#include +#include +#include +#include "osTest.h" + +void TimerTest001(void); +void TimerTest002(void); +void TimerTest003(void); +void TimerTest004(void); +void TimerTest005(void); +void TIME_TEST_TZSET_001(void); +void TIME_TEST_TZSET_002(void); + +#endif /* TIME_TIMER_LT_TIMER_TEST_H */ diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/time/timer/smoke/timer_test_001.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/time/timer/smoke/timer_test_001.cpp new file mode 100644 index 00000000..f888c497 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/time/timer/smoke/timer_test_001.cpp @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include "lt_timer_test.h" + +#define SIG SIGALRM +#define CLOCKID CLOCK_REALTIME + +static int g_sigHdlCnt; +static int g_overRunCnt; +static timer_t g_timerID; + +static void SigHandler01(int sig) +{ + g_sigHdlCnt++; + g_overRunCnt += timer_getoverrun(g_timerID); + LogPrintln("signo %d g_sigHdlCnt %d, overrun %d,%d\n", sig, g_sigHdlCnt, g_overRunCnt, timer_getoverrun(g_timerID)); +} + +static int TimerTest(void) +{ + int interval = 3; // 3, seconds + timer_t timerid01, timerid02; + struct sigevent sev; + struct itimerspec its; + sigset_t mask; + struct sigaction sa; + int ret; + + sa.sa_flags = 0; + sa.sa_handler = SigHandler01; + sigemptyset(&sa.sa_mask); + ret = sigaction(SIG, &sa, nullptr); + LogPrintln("sigaction %d: %d", SIG, ret); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + /* Block timer signal */ + sigemptyset(&mask); + sigaddset(&mask, SIG); + ret = sigprocmask(SIG_BLOCK, &mask, nullptr); + LogPrintln("sigprocmask setmask %d: %d", SIG, ret); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + /* Create the timer */ + sev.sigev_notify = SIGEV_SIGNAL; + sev.sigev_signo = SIG; + sev.sigev_value.sival_ptr = &timerid01; + ret = timer_create(CLOCKID, &sev, &timerid01); + LogPrintln("timer_create %p: %d", timerid01, ret); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + g_timerID = timerid01; + + /* Start the timer */ + its.it_value.tv_sec = 0; + its.it_value.tv_nsec = 900000000; // 900000000, 0.9s + its.it_interval.tv_sec = its.it_value.tv_sec; + its.it_interval.tv_nsec = its.it_value.tv_nsec; + + ret = timer_settime(timerid01, 0, &its, nullptr); + LogPrintln("timer_settime %p: %d", timerid01, ret); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + + /* Test of evp is NULL */ + ret = timer_create(CLOCKID, NULL, &timerid02); + LogPrintln("timer_settime %p: %d", timerid02, ret); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + its.it_value.tv_sec = 1; + its.it_value.tv_nsec = 0; + its.it_interval.tv_sec = its.it_value.tv_sec; + its.it_interval.tv_nsec = its.it_value.tv_nsec; + + ret = timer_settime(timerid02, 0, &its, nullptr); + LogPrintln("timer_settime %p: %d", timerid02, ret); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + sleep(6); + /* Sleep for a while */ + LogPrintln("sleep %ds", interval); + sleep(interval); // timer signal is blocked, this sleep should not be interrupted + ICUNIT_ASSERT_EQUAL(g_sigHdlCnt, 0, g_sigHdlCnt); + + /* Get the timer's time */ + ret = timer_gettime(timerid01, &its); + LogPrintln("timer_gettime %p: %d", timerid01, ret); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + /* Get the timer's overruns */ + ret = timer_getoverrun(timerid01); + LogPrintln("timer_getoverrun %p: %d", timerid01, ret); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret); // before timer deliver, return value of timer_getoverrun is unspecified + + LogPrintln("unblock signal %d", SIG); + + /* Unlock the timer signal */ + ret = sigprocmask(SIG_UNBLOCK, &mask, nullptr); + LogPrintln("sigprocmask unblock %d: %d", SIG, ret); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + interval = 1; + LogPrintln("sleep another %ds", interval); + sleep(interval); // this sleep may be interrupted by the timer + LogPrintln("sleep time over, g_sigHdlCnt = %d", g_sigHdlCnt); + + LogPrintln("sleep another %ds", interval); + sleep(interval); // this sleep may be interrupted by the timer + LogPrintln("sleep time over, g_sigHdlCnt = %d", g_sigHdlCnt); + + ret = timer_delete(timerid01); + LogPrintln("timer_delete %p %d", timerid01, ret); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = timer_delete(timerid02); + LogPrintln("timer_delete %p %d", timerid02, ret); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_NOT_EQUAL(g_sigHdlCnt, 0, g_sigHdlCnt); + ICUNIT_ASSERT_NOT_EQUAL(g_overRunCnt, 0, g_overRunCnt); + + return 0; +} + +void TimerTest001(void) +{ + TEST_ADD_CASE(__FUNCTION__, TimerTest, TEST_POSIX, TEST_SWTMR, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/time/timer/smoke/timer_test_002.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/time/timer/smoke/timer_test_002.cpp new file mode 100644 index 00000000..f758eaa2 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/time/timer/smoke/timer_test_002.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "lt_timer_test.h" + +static int g_almHandlerFlag; +static void SigAlmHandler(int sig) +{ + g_almHandlerFlag++; +} + +static int TimerTest(void) +{ + struct itimerval itv; + int ret; + + ret = getitimer(ITIMER_REAL, &itv); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + itv.it_value.tv_sec = 2; // 2, seconds. + itv.it_value.tv_usec = 500000; // 500000, 500ms. + itv.it_interval.tv_sec = 1; + itv.it_interval.tv_usec = 500000; // 500000, 500ms. + (void)signal(SIGALRM, SigAlmHandler); + + ret = setitimer(ITIMER_REAL, &itv, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LogPrintln("sleep %ds", 3); // 3, this sleep may be interrupted by the timer + sleep(3); // 3, this sleep may be interrupted by the timer + LogPrintln("sleep end, almHandlerFlag %d\n", g_almHandlerFlag); + ICUNIT_ASSERT_EQUAL(g_almHandlerFlag, 1, g_almHandlerFlag); + + LogPrintln("sleep %ds", 2); // 2, this sleep may be interrupted by the timer + sleep(2); // 2, this sleep may be interrupted by the timer + LogPrintln("sleep end, almHandlerFlag %d\n", g_almHandlerFlag); + ICUNIT_ASSERT_EQUAL(g_almHandlerFlag, 2, g_almHandlerFlag); // 2, assert the g_almHandlerFlag. + + LogPrintln("sleep %ds", 2); // 2, this sleep may be interrupted by the timer + sleep(2); // 2, this sleep may be interrupted by the timer + LogPrintln("sleep end, almHandlerFlag %d\n", g_almHandlerFlag); + ICUNIT_ASSERT_EQUAL(g_almHandlerFlag, 3, g_almHandlerFlag); // 3, assert the g_almHandlerFlag. + + ret = getitimer(ITIMER_REAL, &itv); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_EQUAL(itv.it_interval.tv_sec, 1, itv.it_interval.tv_sec); + ICUNIT_ASSERT_EQUAL(itv.it_interval.tv_usec, 500000, itv.it_interval.tv_usec); // 500000, assert the tv_usec. + + /* stop this timer */ + itv.it_value.tv_sec = 0; + itv.it_value.tv_usec = 0; + itv.it_interval.tv_sec = 0; + itv.it_interval.tv_usec = 0; + ret = setitimer(ITIMER_REAL, &itv, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return 0; +} + +void TimerTest002(void) +{ + TEST_ADD_CASE(__FUNCTION__, TimerTest, TEST_POSIX, TEST_SWTMR, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/time/timer/smoke/timer_test_003.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/time/timer/smoke/timer_test_003.cpp new file mode 100644 index 00000000..ae454def --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/time/timer/smoke/timer_test_003.cpp @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include "lt_timer_test.h" + +#define SIG SIGALRM +#define CLOCKID CLOCK_REALTIME + +static int SetTimerTest(void) +{ + int ret = 0; + int sig = 0; + int failed = 0; + timer_t timerid; + sigset_t set, oldSet; + struct sigevent sev; + + ret = sigemptyset(&set); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = sigaddset(&set, SIG); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = sigprocmask(SIG_BLOCK, &set, &oldSet); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + /* Create the timer */ + sev.sigev_notify = SIGEV_SIGNAL; + sev.sigev_signo = SIG; + sev.sigev_value.sival_ptr = &timerid; + ret = timer_create(CLOCKID, &sev, &timerid); + LogPrintln("timer_create %p: %d", timerid, ret); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + struct timespec testcases[] = { + {0, 30000000}, + {1, 0}, + {1, 5}, + {1, 5000}, + {1, 30000000}, + {2, 0}, + }, zero = {0, 0}; + + for (int i = 0; i < sizeof(testcases) / sizeof(testcases[0]); ++i) { + struct timespec start, end; + struct itimerspec its; + int64_t expected, escaped; + + its.it_interval = zero; + its.it_value = testcases[i]; + + ret = clock_gettime(CLOCKID, &start); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = timer_settime(timerid, 0, &its, nullptr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = sigwait(&set, &sig); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = clock_gettime(CLOCKID, &end); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + expected = its.it_value.tv_sec * static_cast(1e9) + its.it_value.tv_nsec; + escaped = end.tv_sec * static_cast(1e9) + end.tv_nsec - start.tv_sec * static_cast(1e9) - + start.tv_nsec; + + failed += (escaped < expected || (escaped - expected) >= 20000000); // 20000000, 2 ticks. + } + + ret = timer_delete(timerid); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = sigprocmask(SIG_SETMASK, &oldSet, nullptr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_EQUAL(failed, 0, failed); + + return 0; +} + +void TimerTest003(void) +{ + TEST_ADD_CASE(__FUNCTION__, SetTimerTest, TEST_POSIX, TEST_SWTMR, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/time/timer/smoke/timer_test_004.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/time/timer/smoke/timer_test_004.cpp new file mode 100644 index 00000000..059f7b85 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/time/timer/smoke/timer_test_004.cpp @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include "lt_timer_test.h" + +/* signo should be in the range SIGRTMIN to SIGRTMAX when SA_SIGINFO flag is set. */ +#define SIG SIGRTMIN +#define CLOCKID CLOCK_REALTIME + +static int g_handlerFlag; +static int g_tmrOverrun; + +static void SigHandler(int sig, siginfo_t *si, void *uc) +{ + if (si == nullptr) { + LogPrintln("[ERROR]sig %d, si %p, uc %p\n", sig, si, uc); + return; + } + +#ifdef TEST_ON_LINUX + timer_t timerid = *(timer_t *)si->si_value.sival_ptr; +#else // SA_SIGINFO not compatible with POSIX on HMOS + timer_t timerid = *reinterpret_cast(si); +#endif + + g_tmrOverrun += timer_getoverrun(timerid); + LogPrintln("signo %d handlerFlag %d timer %p overrun %d\n", sig, ++g_handlerFlag, timerid, g_tmrOverrun); +} + +static int SigInfoTimerTest(void) +{ + int interval = 3; // 3 seconds + timer_t timerid; + struct sigevent sev; + struct itimerspec its; + sigset_t mask; + struct sigaction sa; + int ret; + + /* Install handler for timer signal. */ + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = SigHandler; + sigemptyset(&sa.sa_mask); + ret = sigaction(SIG, &sa, nullptr); + LogPrintln("sigaction %d: %d", SIG, ret); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + /* Block timer signal */ + sigemptyset(&mask); + sigaddset(&mask, SIG); + ret = sigprocmask(SIG_BLOCK, &mask, nullptr); + LogPrintln("sigprocmask setmask %d: %d", SIG, ret); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + /* Create the timer */ + sev.sigev_notify = SIGEV_SIGNAL; + sev.sigev_signo = SIG; + sev.sigev_value.sival_ptr = &timerid; + ret = timer_create(CLOCKID, &sev, &timerid); + LogPrintln("timer_create %p: %d", timerid, ret); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + /* Start the timer */ + its.it_value.tv_sec = 0; + its.it_value.tv_nsec = 990000000; // 990000000, 0.99s + its.it_interval.tv_sec = its.it_value.tv_sec; + its.it_interval.tv_nsec = its.it_value.tv_nsec; + + ret = timer_settime(timerid, 0, &its, nullptr); + LogPrintln("timer_settime %p: %d", timerid, ret); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + /* Sleep for a while */ + LogPrintln("sleep %ds", interval); + sleep(interval); // should not be interrupted + + /* Get the timer's time */ + ret = timer_gettime(timerid, &its); + LogPrintln("timer_gettime %p: %d", timerid, ret); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + /* Get the timer's overruns */ + ret = timer_getoverrun(timerid); + LogPrintln("timer_getoverrun %p: %d", timerid, ret); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret); + + /* Unlock the timer signal */ + ret = sigprocmask(SIG_UNBLOCK, &mask, nullptr); + LogPrintln("sigprocmask unblock %d: %d", SIG, ret); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LogPrintln("sleep another %ds", interval); + sleep(interval); // should be interrupted + LogPrintln("sleep time over, g_handlerFlag = %d", g_handlerFlag); + + ret = timer_delete(timerid); + LogPrintln("timer_delete %p %d", timerid, ret); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_NOT_EQUAL(g_handlerFlag, 0, g_handlerFlag); + ICUNIT_ASSERT_NOT_EQUAL(g_tmrOverrun, 0, g_tmrOverrun); + + return 0; +} + +void TimerTest004(void) +{ + TEST_ADD_CASE(__FUNCTION__, SigInfoTimerTest, TEST_POSIX, TEST_SWTMR, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/time/timer/smoke/timer_test_005.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/time/timer/smoke/timer_test_005.cpp new file mode 100644 index 00000000..9ef06c12 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/time/timer/smoke/timer_test_005.cpp @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include "osTest.h" +#include +#include +#include "lt_timer_test.h" + +static int g_sigHdlCnt01; +static int g_sigHdlCnt02; +static int g_sigHdlCnt03; + +static void TempSigHandler(union sigval v) +{ + LogPrintln("This is TempSigHandler ...\r\n"); + (*(void(*)(void))(v.sival_ptr))(); +} + +static void TempSigHandler01(void) +{ + g_sigHdlCnt01++; +} + +static void TempSigHandler02(void) +{ + g_sigHdlCnt02++; +} + +static int TimerTest(void) +{ + timer_t timerid01, timerid02, timerid03; + struct sigevent sev; + struct itimerspec its; + int ret; + int i; + + ret = memset_s(&sev, sizeof(struct sigevent), 0, sizeof(struct sigevent)); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + sev.sigev_notify = SIGEV_THREAD; + sev.sigev_notify_function = TempSigHandler; + sev.sigev_value.sival_ptr = reinterpret_cast(TempSigHandler01); + + /* Start the timer */ + its.it_value.tv_sec = 3; // 3, timer time 3 seconds. + its.it_value.tv_nsec = 0; + its.it_interval.tv_sec = its.it_value.tv_sec; + its.it_interval.tv_nsec = its.it_value.tv_nsec; + ret = timer_create(CLOCK_REALTIME, &sev, &timerid01); + LogPrintln("timer_settime %p: %d", timerid01, ret); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = timer_settime(timerid01, 0, &its, nullptr); + LogPrintln("timer_create %p: %d", timerid01, ret); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + its.it_value.tv_sec = 4; // 4, timer time 4 seconds. + its.it_value.tv_nsec = 0; + its.it_interval.tv_sec = its.it_value.tv_sec; + its.it_interval.tv_nsec = its.it_value.tv_nsec; + + sev.sigev_value.sival_ptr = reinterpret_cast(TempSigHandler02); + ret = timer_create(CLOCK_REALTIME, &sev, &timerid02); + LogPrintln("timer_settime %p: %d", timerid02, ret); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = timer_settime(timerid02, 0, &its, nullptr); + LogPrintln("timer_settime %p: %d", timerid02, ret); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + its.it_value.tv_sec = 5; // 5, timer time 5 seconds. + its.it_value.tv_nsec = 0; + its.it_interval.tv_sec = its.it_value.tv_sec; + its.it_interval.tv_nsec = its.it_value.tv_nsec; + + sleep(20); // 20, sleep seconds for timer. + ret = timer_delete(timerid01); + LogPrintln("timer_delete %p %d", timerid01, ret); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = timer_delete(timerid02); + LogPrintln("timer_delete %p %d", timerid02, ret); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_NOT_EQUAL(g_sigHdlCnt01, 0, g_sigHdlCnt01); + ICUNIT_ASSERT_NOT_EQUAL(g_sigHdlCnt02, 0, g_sigHdlCnt02); + return 0; + +} + +void TimerTest005(void) +{ + TEST_ADD_CASE(__FUNCTION__, TimerTest, TEST_POSIX, TEST_SWTMR, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/time/timer/smoke/timer_test_tzset_001.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/time/timer/smoke/timer_test_tzset_001.cpp new file mode 100644 index 00000000..8cc51b4b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/time/timer/smoke/timer_test_tzset_001.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include "lt_timer_test.h" +#include + +static UINT32 testcase(VOID) +{ + time_t td; + int ret = 0; + + errno = 0; + ret = putenv("TZ=GMT-3"); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + tzset(); + + errno = 0; + ret = time(&td); + TEST_PRINT("[INFO]%s:%d,%s,Current time = %s\n", __FILE__, __LINE__, __func__, asctime(localtime(&td))); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret); + TEST_PRINT("[INFO]%s:%d,%s,ret=%d,errno=%d,errstr=%s\n", __FILE__, __LINE__, __func__, ret, errno, strerror(errno)); + ICUNIT_GOTO_EQUAL(errno, 0, errno, OUT); + + return LOS_OK; +OUT: + return LOS_NOK; +} + +void TIME_TEST_TZSET_001(void) +{ + TEST_ADD_CASE(__FUNCTION__, testcase, TEST_POSIX, TEST_SWTMR, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/time/timer/smoke/timer_test_tzset_002.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/time/timer/smoke/timer_test_tzset_002.cpp new file mode 100644 index 00000000..9834c6b5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/time/timer/smoke/timer_test_tzset_002.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include "lt_timer_test.h" +#include + +static UINT32 testcase(VOID) +{ + time_t td; + int ret = 0; + + errno = 0; + ret = putenv(const_cast("TZ=GMT-100")); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + tzset(); + + errno = 0; + ret = time(&td); + TEST_PRINT("[INFO]%s:%d,%s,Current time = %s\n", __FILE__, __LINE__, __func__, asctime(localtime(&td))); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret); + TEST_PRINT("[INFO]%s:%d,%s,ret=%d,errno=%d,errstr=%s\n", __FILE__, __LINE__, __func__, ret, errno, strerror(errno)); + ICUNIT_GOTO_EQUAL(errno, 0, errno, OUT); + + return LOS_OK; +OUT: + return LOS_NOK; +} + +void TIME_TEST_TZSET_002(void) +{ + TEST_ADD_CASE(__FUNCTION__, testcase, TEST_POSIX, TEST_SWTMR, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/time/timer/time_timer_test.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/time/timer/time_timer_test.cpp new file mode 100644 index 00000000..d859b046 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/time/timer/time_timer_test.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "stdio.h" +#include +#include + +#include "lt_timer_test.h" + +using namespace testing::ext; +namespace OHOS { +class TimeTimerTest : public testing::Test { +public: + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} +}; + +#if defined(LOSCFG_USER_TEST_SMOKE) +/* * + * @tc.name: TimerTest001 + * @tc.desc: function for TimeTimerTest + * @tc.type: FUNC + */ +HWTEST_F(TimeTimerTest, TimerTest001, TestSize.Level0) +{ + TimerTest001(); +} + +/* * + * @tc.name: TimerTest005 + * @tc.desc: function for timer_create SIGEV_THREAD. + * @tc.type: FUNC + */ +HWTEST_F(TimeTimerTest, TimerTest005, TestSize.Level0) +{ + TimerTest005(); +} + +/* * + * @tc.name: TIME_TEST_TZSET_001 + * @tc.desc: function for TIME_TEST_TZSET_001 + * @tc.type: FUNC + */ +HWTEST_F(TimeTimerTest, TIME_TEST_TZSET_001, TestSize.Level0) +{ + TIME_TEST_TZSET_001(); +} + +/* * + * @tc.name: TIME_TEST_TZSET_002 + * @tc.desc: function for TimeTimerTest + * @tc.type: FUNC + */ +HWTEST_F(TimeTimerTest, TIME_TEST_TZSET_002, TestSize.Level0) +{ + TIME_TEST_TZSET_002(); +} +#endif +} // namespace OHOS diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/util/BUILD.gn b/src/kernel_liteos_a/testsuites/unittest/libc/util/BUILD.gn new file mode 100644 index 00000000..37ae169b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/util/BUILD.gn @@ -0,0 +1,66 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("./config.gni") + +config("libc_config") { + if (LOSCFG_USER_TEST_LIBC_POSIX_MQUEUE == true || + LOSCFG_USER_TEST_LIBC_POSIX_PTHREAD == true) { + cflags = [ "-O1" ] + cflags_cc = cflags + } +} + +if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_LOW) { + unittest("liteos_a_libc_util_unittest_door") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + include_dirs = common_include_dirs + sources = sources_entry + sources += sources_smoke + sources_full = [] + sources += sources_full + configs = [ "../..:public_config_for_door" ] + configs += [ ":libc_config" ] + deps = [ "$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR:libsec_shared" ] + } +} + +if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_MIDDLE) { + unittest("liteos_a_libc_util_unittest") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + include_dirs = common_include_dirs + sources = sources_entry + sources += sources_smoke + sources += sources_full + configs = [ "../..:public_config_for_all" ] + configs += [ ":libc_config" ] + deps = [ "$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR:libsec_shared" ] + } +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/util/It_test_util.h b/src/kernel_liteos_a/testsuites/unittest/libc/util/It_test_util.h new file mode 100644 index 00000000..d7adfcc9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/util/It_test_util.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _IT_TEST_UTIL_H +#define _IT_TEST_UTIL_H + +#include "osTest.h" +#include "getopt.h" +#include "stdio.h" +#include "stdlib.h" +#include "unistd.h" +#include "crypt.h" +#include "time.h" +#include "search.h" + +extern VOID ItTestUtil001(VOID); +extern VOID ItTestUtil002(VOID); +extern VOID ItTestUtil003(VOID); +extern VOID ItTestUtil004(VOID); +extern VOID ItTestUtil005(VOID); +extern VOID ItTestUtil006(VOID); +extern VOID ItTestUtil007(VOID); +extern VOID ItTestUtil100(VOID); +extern VOID ItTestUtil101(VOID); + +#endif diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/util/config.gni b/src/kernel_liteos_a/testsuites/unittest/libc/util/config.gni new file mode 100644 index 00000000..488c8079 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/util/config.gni @@ -0,0 +1,71 @@ +# Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//build/lite/config/test.gni") +import("//kernel/liteos_a/liteos.gni") +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +common_include_dirs = [ + "$THIRDPARTY_GOOGLETEST_DIR/googletest/include", + "../../common/include", +] + +sources_entry = [ "../../common/osTest.cpp" ] + +sources_smoke = [] + +sources_full = [] + +libc_util_include_dirs = [ + "$TEST_UNITTEST_DIR/libc/util", + "$TEST_UNITTEST_DIR/libc/misc", +] + +libc_util_sources_entry = [ "$TEST_UNITTEST_DIR/libc/util/util_test.cpp" ] + +libc_util_sources_smoke = [ + "$TEST_UNITTEST_DIR/libc/util/smoke/it_test_util_100.cpp", + "$TEST_UNITTEST_DIR/libc/util/smoke/it_test_util_101.cpp", + "$TEST_UNITTEST_DIR/libc/util/smoke/util_test_001.cpp", + "$TEST_UNITTEST_DIR/libc/util/smoke/util_test_002.cpp", + "$TEST_UNITTEST_DIR/libc/util/smoke/util_test_003.cpp", + "$TEST_UNITTEST_DIR/libc/util/smoke/util_test_004.cpp", + "$TEST_UNITTEST_DIR/libc/util/smoke/util_test_005.cpp", + "$TEST_UNITTEST_DIR/libc/util/smoke/util_test_006.cpp", + "$TEST_UNITTEST_DIR/libc/util/smoke/util_test_007.cpp", +] + +libc_util_sources_full = [] + +# libc util module +if (LOSCFG_USER_TEST_LIBC_UTIL == true) { + common_include_dirs += libc_util_include_dirs + sources_entry += libc_util_sources_entry + sources_smoke += libc_util_sources_smoke + sources_full += libc_util_sources_full +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/util/smoke/it_test_util_100.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/util/smoke/it_test_util_100.cpp new file mode 100644 index 00000000..7e984ef0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/util/smoke/it_test_util_100.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_util.h" + +static int TestCase(void) +{ + wchar_t value[] = L"12"; + wchar_t value1[] = L"abcdefg"; + int len; + + len = wcswidth(value, 2); + ICUNIT_ASSERT_EQUAL(len, 2, len); + + len = wcswidth(value1, 7); + ICUNIT_ASSERT_EQUAL(len, 7, len); + + return 0; +} +void ItTestUtil100(void) + +{ + TEST_ADD_CASE("It_Test_Util_100", TestCase, TEST_VFS, TEST_JFFS, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/util/smoke/it_test_util_101.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/util/smoke/it_test_util_101.cpp new file mode 100644 index 00000000..9c879a9f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/util/smoke/it_test_util_101.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_util.h" + +static int TestCase(void) +{ + wchar_t value[] = L"2"; + wchar_t value1[] = L"a"; + int len; + + len = wcwidth(*value); + ICUNIT_ASSERT_EQUAL(len, 1, len); + + len = wcwidth(*value1); + ICUNIT_ASSERT_EQUAL(len, 1, len); + + return 0; +} + +void ItTestUtil101(void) +{ + TEST_ADD_CASE("It_Test_Util_101", TestCase, TEST_VFS, TEST_JFFS, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/util/smoke/util_test_001.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/util/smoke/util_test_001.cpp new file mode 100644 index 00000000..06a54451 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/util/smoke/util_test_001.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_util.h" + +static struct option g_longOptions[] = { + {"test1", 0, NULL, 'a'}, + {"test2", 0, NULL, 'b'}, + {"test3", 0, NULL, 'c'}, + {0, 0, 0, 0}, +}; + +#define ARGC_NUM 5 + +static UINT32 TestCase(VOID) +{ + INT32 ret, i; + INT32 argc = ARGC_NUM; + CHAR *argv[] = {"test", "-b", "-a", "-c", NULL}; + CHAR *ptr = NULL; + CHAR * const shortOptions = "abc"; + + for (i = 0; (ret = getopt_long(argc, argv, shortOptions, g_longOptions, NULL)) != -1; i++) { + switch (ret) { + case 'a': + ICUNIT_GOTO_EQUAL(i, 1, i, EXIT); + break; + case 'b': + ICUNIT_GOTO_EQUAL(i, 0, i, EXIT); + break; + case 'c': + ICUNIT_GOTO_EQUAL(i, 2, i, EXIT); + break; + default: + break; + } + } + + return 0; +EXIT: + return -1; +} + +VOID ItTestUtil001(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/util/smoke/util_test_002.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/util/smoke/util_test_002.cpp new file mode 100644 index 00000000..fee8059b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/util/smoke/util_test_002.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_util.h" + +static struct option g_longOptions[] = { + {"test1", 0, NULL, 'a'}, + {"test2", 0, NULL, 'b'}, + {"test3", 0, NULL, 'c'}, + {0, 0, 0, 0}, +}; + +#define ARGC_NUM 5 + +static UINT32 TestCase(VOID) +{ + INT32 ret, i; + INT32 argc = ARGC_NUM; + CHAR *argv[] = {"test", "-b", "-a", "-c", NULL}; + CHAR *ptr = NULL; + CHAR * const shortOptions = "abc"; + + for (i = 0; (ret = getopt_long_only(argc, argv, shortOptions, g_longOptions, NULL)) != -1; i++) { + switch (ret) { + case 'a': + ICUNIT_GOTO_EQUAL(i, 1, i, EXIT); + break; + case 'b': + ICUNIT_GOTO_EQUAL(i, 0, i, EXIT); + break; + case 'c': + ICUNIT_GOTO_EQUAL(i, 2, i, EXIT); + break; + default: + break; + } + } + + return 0; +EXIT: + return -1; +} + +VOID ItTestUtil002(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/util/smoke/util_test_003.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/util/smoke/util_test_003.cpp new file mode 100644 index 00000000..867aa173 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/util/smoke/util_test_003.cpp @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_misc.h" + +#define TEST_BUF_SIZE 20 +#define TEST_STR "rw,ro=test" + +static UINT32 TestCase(VOID) +{ + enum { + RO_OPT = 0, + RW_OPT, + NAME_OPT + }; + + CHAR *const token[] = { + [RO_OPT] = "ro", + [RW_OPT] = "rw", + [NAME_OPT] = "name", + NULL + }; + CHAR *buf = (char *)malloc(TEST_BUF_SIZE); + if (buf == NULL) { + return -1; + } + CHAR *a = TEST_STR; + CHAR *value = NULL; + CHAR *subopts = NULL; + INT32 err = 0; + INT32 countRight = 0; + INT32 countErr = 0; + + (void)strcpy_s(buf, TEST_BUF_SIZE, a); + subopts = buf; + + while (*subopts != '\0' && !err) { + switch (getsubopt(&subopts, token, &value)) { + case RO_OPT: + if (value) { + countRight++; + } else { + countErr++; + } + break; + case RW_OPT: + if (value) { + countErr++; + } else { + countRight++; + } + break; + case NAME_OPT: + if (value) { + countErr++; + } else { + countRight++; + } + break; + default: + err = 1; + break; + } + } + + ICUNIT_GOTO_EQUAL(countRight, 2, countRight, EXIT); + ICUNIT_GOTO_EQUAL(countErr, 0, countErr, EXIT); + + free(buf); + return 0; +EXIT: + free(buf); + return -1; +} + +VOID ItTestUtil003(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/util/smoke/util_test_004.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/util/smoke/util_test_004.cpp new file mode 100644 index 00000000..9bb0b38c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/util/smoke/util_test_004.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_misc.h" + +#define JRAND48_NUM 0x100000000 + +static UINT32 TestCase(VOID) +{ + long int x; + unsigned short seed[3] = {1, 2, 3}; + + x = jrand48(seed); + if ((x < -JRAND48_NUM) || (x > JRAND48_NUM)) { + printf("[IN %s][line %d] x = %ld\n", __FUNCTION__, __LINE__, x); + goto EXIT; + } + + return 0; +EXIT: + return -1; +} + +VOID ItTestUtil004(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/util/smoke/util_test_005.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/util/smoke/util_test_005.cpp new file mode 100644 index 00000000..5b2ee32b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/util/smoke/util_test_005.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_misc.h" + +#define MRAND48_NUM 0x100000000 + +static UINT32 TestCase(VOID) +{ + long int x; + unsigned short seed[7] = {1, 2, 3, 4, 5, 6, 7}; + + lcong48(seed); + x = mrand48(); + if ((x < -MRAND48_NUM) || (x > MRAND48_NUM)) { + printf("[IN %s][line %d] x = %ld\n", __FUNCTION__, __LINE__, x); + goto EXIT; + } + + return 0; +EXIT: + return -1; +} + +VOID ItTestUtil005(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/util/smoke/util_test_006.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/util/smoke/util_test_006.cpp new file mode 100644 index 00000000..a5b7be34 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/util/smoke/util_test_006.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_misc.h" + +static UINT32 TestCase(VOID) +{ + char key[64]; + char orig[9] = "eggplant"; + char buf[64]; + char txt[9]; + int i, j; + + for (i = 0; i < 64; i++) { + key[i] = rand() & 1; + } + + for (i = 0; i < 8; i++) { + for (j = 0; j < 8; j++) { + buf[i * 8 + j] = orig[i] >> j & 1; + } + setkey(key); + } + printf("Before encrypting: %s\n", orig); + + encrypt(buf, 0); + for (i = 0; i < 8; i++) { + for (j = 0, txt[i] = '\0'; j < 8; j++) { + txt[i] |= buf[i * 8 + j] << j; + } + txt[8] = '\0'; + } + ICUNIT_GOTO_STRING_NOT_EQUAL(txt, orig, txt, EXIT); + + encrypt(buf, 1); + for (i = 0; i < 8; i++) { + for (j = 0, txt[i] = '\0'; j < 8; j++) { + txt[i] |= buf[i * 8 + j] << j; + } + txt[8] = '\0'; + } + ICUNIT_GOTO_STRING_EQUAL(txt, orig, txt, EXIT); + + return 0; +EXIT: + return -1; +} + + +VOID ItTestUtil006(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/util/smoke/util_test_007.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/util/smoke/util_test_007.cpp new file mode 100644 index 00000000..ecc3dd3f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/util/smoke/util_test_007.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_test_misc.h" + +static void *g_root = NULL; + +static void *Xmalloc(unsigned n) +{ + void *p = NULL; + if (n <= 0) { + printf("err: malloc size invalid\n"); + exit(EXIT_FAILURE); + } + p = malloc(n); + if (p) { + return p; + } + fprintf(stderr, "insufficient memory\n"); + exit(EXIT_FAILURE); +} + +static int Compare(const void *pa, const void *pb) +{ + if (*static_cast(const_cast(pa)) < *static_cast(const_cast(pb))) { + return -1; + } + if (*static_cast(const_cast(pa)) > *static_cast(const_cast(pb))) { + return 1; + } + return 0; +} + +static void Action(const void *nodep, VISIT which, int depth) +{ + int *datap = NULL; + + switch (which) { + case preorder: + break; + case postorder: + datap = *static_cast(const_cast(nodep)); + break; + case endorder: + break; + case leaf: + datap = *static_cast(const_cast(nodep)); + break; + default: + break; + } +} + +static UINT32 TestCase(VOID) +{ + int i; + int *ptr = NULL; + void *val = NULL; + + srand(time(NULL)); + for (i = 0; i < 12; i++) { + ptr = (int *)Xmalloc(sizeof(int)); + *ptr = rand() & 0xff; + val = tsearch(static_cast(ptr), &g_root, Compare); + if (val == NULL) { + exit(EXIT_FAILURE); + } else if ((*(int **)val) != ptr) { + free(ptr); + } + } + + twalk(g_root, Action); + tdestroy(g_root, free); + + return 0; +} + +VOID ItTestUtil007(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/libc/util/util_test.cpp b/src/kernel_liteos_a/testsuites/unittest/libc/util/util_test.cpp new file mode 100644 index 00000000..c299fe0f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/libc/util/util_test.cpp @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "stdio.h" +#include +#include +#include "It_test_util.h" + +using namespace testing::ext; +namespace OHOS { +class UtilTest : public testing::Test { +public: + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} +}; + +#if defined(LOSCFG_USER_TEST_SMOKE) +/* * + * @tc.name: IT_TEST_UTIL_001 + * @tc.desc: function for UtilTest + * @tc.type: FUNC + */ +HWTEST_F(UtilTest, ItTestUtil001, TestSize.Level0) +{ + ItTestUtil001(); +} + +/* * + * @tc.name: IT_TEST_UTIL_002 + * @tc.desc: function for UtilTest + * @tc.type: FUNC + */ +HWTEST_F(UtilTest, ItTestUtil002, TestSize.Level0) +{ + ItTestUtil002(); +} + +/* * + * @tc.name: IT_TEST_UTIL_003 + * @tc.desc: function for UtilTest + * @tc.type: FUNC + */ +HWTEST_F(UtilTest, ItTestUtil003, TestSize.Level0) +{ + ItTestUtil003(); +} + +/* * + * @tc.name: IT_TEST_UTIL_004 + * @tc.desc: function for UtilTest + * @tc.type: FUNC + */ +HWTEST_F(UtilTest, ItTestUtil004, TestSize.Level0) +{ + ItTestUtil004(); +} + +/* * + * @tc.name: IT_TEST_UTIL_005 + * @tc.desc: function for UtilTest + * @tc.type: FUNC + */ +HWTEST_F(UtilTest, ItTestUtil005, TestSize.Level0) +{ + ItTestUtil005(); +} + +/* * + * @tc.name: IT_TEST_UTIL_006 + * @tc.desc: function for UtilTest + * @tc.type: FUNC + */ +HWTEST_F(UtilTest, ItTestUtil006, TestSize.Level0) +{ + ItTestUtil006(); +} + +/* * + * @tc.name: IT_TEST_UTIL_007 + * @tc.desc: function for UtilTest + * @tc.type: FUNC + */ +HWTEST_F(UtilTest, ItTestUtil007, TestSize.Level0) +{ + ItTestUtil007(); +} + +/* * + * @tc.name: IT_TEST_UTIL_101 + * @tc.desc: function for UtilTest + * @tc.type: FUNC + */ +HWTEST_F(UtilTest, ItTestUtil101, TestSize.Level0) +{ + ItTestUtil101(); +} + +#endif +} // namespace OHOS diff --git a/src/kernel_liteos_a/testsuites/unittest/net/BUILD.gn b/src/kernel_liteos_a/testsuites/unittest/net/BUILD.gn new file mode 100644 index 00000000..b10c06f5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/BUILD.gn @@ -0,0 +1,72 @@ +# Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("./config.gni") + +config("net_config") { + cflags = [] + if (LOSCFG_USER_TEST_NET_NETDB == true) { + cflags += [ "-DLOSCFG_USER_TEST_NET_NETDB" ] + } + if (LOSCFG_USER_TEST_NET_RESOLV == true) { + cflags += [ "-DLOSCFG_USER_TEST_NET_RESOLV" ] + } + if (LOSCFG_USER_TEST_NET_SOCKET == true) { + cflags += [ "-DLOSCFG_USER_TEST_NET_SOCKET" ] + } + cflags_cc = cflags +} + +if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_LOW) { + unittest("liteos_a_net_unittest_door") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + include_dirs = common_include_dirs + sources = sources_entry + sources += sources_smoke + sources_full = [] + sources += sources_full + configs = [ "..:public_config_for_door" ] + configs += [ ":net_config" ] + deps = [ "$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR:libsec_shared" ] + } +} + +if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_MIDDLE) { + unittest("liteos_a_net_unittest") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + include_dirs = common_include_dirs + sources = sources_entry + sources += sources_smoke + sources += sources_full + configs = [ "..:public_config_for_all" ] + configs += [ ":net_config" ] + deps = [ "$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR:libsec_shared" ] + } +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/config.gni b/src/kernel_liteos_a/testsuites/unittest/net/config.gni new file mode 100644 index 00000000..aaeafe7e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/config.gni @@ -0,0 +1,69 @@ +# Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//build/lite/config/test.gni") +import("//kernel/liteos_a/liteos.gni") +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +common_include_dirs = [ + "$THIRDPARTY_GOOGLETEST_DIR/googletest/include", + "../common/include", +] + +sources_entry = [ "../common/osTest.cpp" ] + +sources_smoke = [] + +sources_full = [] + +# netdb module +if (LOSCFG_USER_TEST_NET_NETDB == true) { + import("./netdb/config.gni") + common_include_dirs += netdb_include_dirs + sources_entry += netdb_sources_entry + sources_smoke += netdb_sources_smoke + sources_full += netdb_sources_full +} + +# resolv module +if (LOSCFG_USER_TEST_NET_RESOLV == true) { + import("./resolv/config.gni") + common_include_dirs += resolv_include_dirs + sources_entry += resolv_sources_entry + sources_smoke += resolv_sources_smoke + sources_full += resolv_sources_full +} + +# socket module +if (LOSCFG_USER_TEST_NET_SOCKET == true) { + import("./socket/config.gni") + common_include_dirs += socket_include_dirs + sources_entry += socket_sources_entry + sources_smoke += socket_sources_smoke + sources_full += socket_sources_full +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/netdb/config.gni b/src/kernel_liteos_a/testsuites/unittest/net/netdb/config.gni new file mode 100644 index 00000000..2c1702ad --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/netdb/config.gni @@ -0,0 +1,60 @@ +# Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +netdb_include_dirs = [ "$TEST_UNITTEST_DIR/net/netdb" ] + +netdb_sources_entry = [ "$TEST_UNITTEST_DIR/net/netdb/net_netdb_test.cpp" ] + +netdb_sources_smoke = [ + "$TEST_UNITTEST_DIR/net/netdb/smoke/net_netdb_test_001.cpp", + "$TEST_UNITTEST_DIR/net/netdb/smoke/net_netdb_test_013.cpp", +] + +netdb_sources_full = [ + "$TEST_UNITTEST_DIR/net/netdb/full/net_netdb_test_002.cpp", + "$TEST_UNITTEST_DIR/net/netdb/full/net_netdb_test_003.cpp", + "$TEST_UNITTEST_DIR/net/netdb/full/net_netdb_test_004.cpp", + "$TEST_UNITTEST_DIR/net/netdb/full/net_netdb_test_005.cpp", + "$TEST_UNITTEST_DIR/net/netdb/full/net_netdb_test_006.cpp", + "$TEST_UNITTEST_DIR/net/netdb/full/net_netdb_test_007.cpp", + "$TEST_UNITTEST_DIR/net/netdb/full/net_netdb_test_008.cpp", + "$TEST_UNITTEST_DIR/net/netdb/full/net_netdb_test_009.cpp", + "$TEST_UNITTEST_DIR/net/netdb/full/net_netdb_test_010.cpp", + "$TEST_UNITTEST_DIR/net/netdb/full/net_netdb_test_011.cpp", + "$TEST_UNITTEST_DIR/net/netdb/full/net_netdb_test_012.cpp", + "$TEST_UNITTEST_DIR/net/netdb/full/net_netdb_test_015.cpp", + "$TEST_UNITTEST_DIR/net/netdb/full/net_netdb_test_016.cpp", + "$TEST_UNITTEST_DIR/net/netdb/full/net_netdb_test_017.cpp", + "$TEST_UNITTEST_DIR/net/netdb/full/net_netdb_test_018.cpp", + "$TEST_UNITTEST_DIR/net/netdb/full/net_netdb_test_019.cpp", + "$TEST_UNITTEST_DIR/net/netdb/full/net_netdb_test_020.cpp", + "$TEST_UNITTEST_DIR/net/netdb/full/net_netdb_test_021.cpp", + "$TEST_UNITTEST_DIR/net/netdb/full/net_netdb_test_022.cpp", +] diff --git a/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_002.cpp b/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_002.cpp new file mode 100644 index 00000000..2e295946 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_002.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "lt_net_netdb.h" + +static int AddrInfoTest(void) +{ + // Prerequisite: correct DNS servers must be configured. + char host_file[] = "127.0.0.2 example.com\n", serv_file[] = "ftp 21/tcp\n"; + char *pathList[] = {"/etc/hosts", "/etc/services"}; + char *streamList[] = {host_file, serv_file}; + int streamLen[] = {sizeof(host_file), sizeof(serv_file)}; + const int file_number = 2; + int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number); + if (flag != 0) { + RecoveryFileEnv(pathList, file_number); + return -1; + } + + struct addrinfo *addr = NULL; + int ret = getaddrinfo("example.com", "ftp", NULL, &addr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + freeaddrinfo(addr); + + ret = getaddrinfo("local", "ftp", NULL, &addr); + ICUNIT_ASSERT_EQUAL(ret, EAI_AGAIN, ret); + + ret = getaddrinfo("localhost", "fp", NULL, &addr); + ICUNIT_ASSERT_EQUAL(ret, EAI_SERVICE, ret); + + const char *p = gai_strerror(EAI_AGAIN); + ICUNIT_ASSERT_NOT_EQUAL(p, NULL, -1); + + RecoveryFileEnv(pathList, file_number); + return ICUNIT_SUCCESS; +} + +void NetNetDbTest002(void) +{ + TEST_ADD_CASE(__FUNCTION__, AddrInfoTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_003.cpp b/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_003.cpp new file mode 100644 index 00000000..229c3ad5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_003.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "lt_net_netdb.h" + +static int IfAddrsTest(void) +{ + // Prerequisite: correct DNS servers must be configured. + struct ifaddrs *addr = NULL; + int ret = getifaddrs(&addr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_NOT_EQUAL(addr, NULL, -1); + + freeifaddrs(addr); + + return ICUNIT_SUCCESS; +} + +void NetNetDbTest003(void) +{ + TEST_ADD_CASE(__FUNCTION__, IfAddrsTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_004.cpp b/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_004.cpp new file mode 100644 index 00000000..c05a6fb7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_004.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "lt_net_netdb.h" + +static int GetHostByAddrTest(void) +{ + char host_file[] = "127.0.0.1 localhost\n100.0.0.0 example.com example\n"; + char *pathList[] = {"/etc/hosts"}; + char *streamList[] = {host_file}; + int streamLen[] = {sizeof(host_file)}; + const int file_number = 1; + int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number); + if (flag != 0) { + RecoveryFileEnv(pathList, file_number); + return -1; + } + + struct in_addr ia; + int length = 4; // the address length is 4; + ia.s_addr = inet_addr("127.0.0.1"); + struct hostent *addr = gethostbyaddr(&ia, sizeof ia, AF_INET); + ICUNIT_ASSERT_NOT_EQUAL(addr, NULL, -1); + ICUNIT_ASSERT_EQUAL(addr->h_addrtype, AF_INET, addr->h_addrtype); + ICUNIT_ASSERT_STRING_EQUAL(addr->h_name, "localhost", -1); + ICUNIT_ASSERT_EQUAL(addr->h_length, length, -1); + + ia.s_addr = inet_addr("100.0.0.0"); + addr = gethostbyaddr(&ia, sizeof ia, AF_INET); + ICUNIT_ASSERT_NOT_EQUAL(addr, NULL, -1); + ICUNIT_ASSERT_EQUAL(addr->h_addrtype, AF_INET, addr->h_addrtype); + ICUNIT_ASSERT_STRING_EQUAL(addr->h_name, "example.com", -1); + + errno = 0; + ia.s_addr = inet_addr("127.0.0.0"); + addr = gethostbyaddr(&ia, sizeof ia, AF_INET); + ICUNIT_ASSERT_EQUAL(errno, ENOENT, errno); + + RecoveryFileEnv(pathList, file_number); + return ICUNIT_SUCCESS; +} + +void NetNetDbTest004(void) +{ + TEST_ADD_CASE(__FUNCTION__, GetHostByAddrTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_005.cpp b/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_005.cpp new file mode 100644 index 00000000..7fe49c76 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_005.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "lt_net_netdb.h" + +static int GetHostByAddrRTest(void) +{ + struct in_addr ia; + struct hostent addr, *result = NULL; + char buf[1024]; + char buf1[1]; + int err, ret; + int length = 4; + + ia.s_addr = inet_addr("127.0.0.1"); + ret = gethostbyaddr_r(&ia, sizeof ia, AF_INET, &addr, buf, sizeof buf, &result, &err); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_NOT_EQUAL(result, NULL, -1); + ICUNIT_ASSERT_EQUAL(result->h_addrtype, AF_INET, result->h_addrtype); + ICUNIT_ASSERT_STRING_EQUAL(result->h_name, "localhost", -1); + ICUNIT_ASSERT_EQUAL(result->h_length, length, -1); + + errno = 0; + ia.s_addr = inet_addr("127.0.0.0"); + ret = gethostbyaddr_r(&ia, sizeof ia, AF_INET, &addr, buf, sizeof buf, &result, &err); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno); + + ret = gethostbyaddr_r(&ia, sizeof ia, AF_INET, &addr, buf, sizeof buf, &result, &err); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno); + + ret = gethostbyaddr_r(&ia, sizeof ia, AF_INET, &addr, buf1, sizeof buf1, &result, &err); + ICUNIT_ASSERT_EQUAL(ret, ERANGE, ret); + + return ICUNIT_SUCCESS; +} + +void NetNetDbTest005(void) +{ + TEST_ADD_CASE(__FUNCTION__, GetHostByAddrRTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_006.cpp b/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_006.cpp new file mode 100644 index 00000000..9cc7c829 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_006.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "lt_net_netdb.h" + +static int GetHostByNameTest(void) +{ + char host_file[] = "127.0.0.1 localhost\n"; + char *pathList[] = {"/etc/hosts"}; + char *streamList[] = {host_file}; + int streamLen[] = {sizeof(host_file)}; + int flag = PrepareFileEnv(pathList, streamList, streamLen, 1); + if (flag != 0) { + RecoveryFileEnv(pathList, 1); + return -1; + } + + struct hostent *addr = gethostbyname("localhost"); + ICUNIT_ASSERT_NOT_EQUAL(addr, NULL, -1); + ICUNIT_ASSERT_EQUAL(strcmp(addr->h_name, "localhost"), 0, -1); + ICUNIT_ASSERT_EQUAL(addr->h_addrtype, AF_INET, addr->h_addrtype); + ICUNIT_ASSERT_NOT_EQUAL(addr->h_length, 0, addr->h_length); + + addr = gethostbyname("127.0.0.1"); + ICUNIT_ASSERT_NOT_EQUAL(addr, NULL, -1); + ICUNIT_ASSERT_EQUAL(strcmp(addr->h_name, "127.0.0.1"), 0, -1); + ICUNIT_ASSERT_EQUAL(addr->h_addrtype, AF_INET, addr->h_addrtype); + ICUNIT_ASSERT_NOT_EQUAL(addr->h_length, 0, addr->h_length); + + addr = gethostbyname("lo"); + ICUNIT_ASSERT_EQUAL(addr, NULL, -1); + + RecoveryFileEnv(pathList, 1); + return ICUNIT_SUCCESS; +} + +void NetNetDbTest006(void) +{ + TEST_ADD_CASE(__FUNCTION__, GetHostByNameTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_007.cpp b/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_007.cpp new file mode 100644 index 00000000..42ef5c50 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_007.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "lt_net_netdb.h" + +static int GetHostByNameRTest(void) +{ + char host_file[] = "127.0.0.1 localhost\n"; + char *pathList[] = {"/etc/hosts"}; + char *streamList[] = {static_cast(host_file)}; + int streamLen[] = {sizeof(host_file)}; + const int file_number = 1; + int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number); + if (flag != 0) { + RecoveryFileEnv(pathList, file_number); + return -1; + } + + struct hostent addr, *result = NULL; + char buf[1024]; + char buf1[1]; + int err, ret; + + ret = gethostbyname_r("localhost", &addr, buf, sizeof buf, &result, &err); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_NOT_EQUAL(result, NULL, -1); + ICUNIT_ASSERT_EQUAL(strcmp(result->h_name, "localhost"), 0, -1); + ICUNIT_ASSERT_EQUAL(result->h_addrtype, AF_INET, result->h_addrtype); + ICUNIT_ASSERT_NOT_EQUAL(result->h_length, 0, result->h_length); + + ret = gethostbyname_r("127.0.0.1", &addr, buf, sizeof buf, &result, &err); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_NOT_EQUAL(result, NULL, -1); + ICUNIT_ASSERT_EQUAL(strcmp(result->h_name, "127.0.0.1"), 0, -1); + ICUNIT_ASSERT_EQUAL(result->h_addrtype, AF_INET, result->h_addrtype); + ICUNIT_ASSERT_NOT_EQUAL(result->h_length, 0, result->h_length); + + ret = gethostbyname_r("127.0.0.1", &addr, buf1, sizeof buf1, &result, &err); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + ret = gethostbyname_r("127.0.0.0.0", &addr, buf, sizeof buf, &result, &err); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + ret = gethostbyname_r("lo", &addr, buf, sizeof buf, &result, &err); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + + RecoveryFileEnv(pathList, file_number); + return ICUNIT_SUCCESS; +} + +void NetNetDbTest007(void) +{ + TEST_ADD_CASE(__FUNCTION__, GetHostByNameRTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_008.cpp b/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_008.cpp new file mode 100644 index 00000000..7819b3b6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_008.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "lt_net_netdb.h" + +static int GetHostByName2Test(void) +{ + char host_file[] = "127.0.0.1 localhost\n"; + char *pathList[] = {"/etc/hosts"}; + char *streamList[] = {static_cast(host_file)}; + int streamLen[] = {sizeof(host_file)}; + const int file_number = 1; + int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number); + if (flag != 0) { + RecoveryFileEnv(pathList, file_number); + return -1; + } + + struct hostent *addr = gethostbyname2("localhost", AF_INET); + ICUNIT_ASSERT_NOT_EQUAL(addr, NULL, -1); + ICUNIT_ASSERT_EQUAL(strcmp(addr->h_name, "localhost"), 0, -1); + ICUNIT_ASSERT_EQUAL(addr->h_addrtype, AF_INET, addr->h_addrtype); + ICUNIT_ASSERT_NOT_EQUAL(addr->h_length, 0, addr->h_length); + + addr = gethostbyname2("127.0.0.1", AF_INET); + ICUNIT_ASSERT_NOT_EQUAL(addr, NULL, -1); + ICUNIT_ASSERT_EQUAL(strcmp(addr->h_name, "127.0.0.1"), 0, -1); + ICUNIT_ASSERT_EQUAL(addr->h_addrtype, AF_INET, addr->h_addrtype); + ICUNIT_ASSERT_NOT_EQUAL(addr->h_length, 0, addr->h_length); + + addr = gethostbyname2("127.0.0.1", AF_INET6); + ICUNIT_ASSERT_EQUAL(addr, NULL, -1); + addr = gethostbyname2("localh", AF_INET); + ICUNIT_ASSERT_EQUAL(addr, NULL, -1); + + RecoveryFileEnv(pathList, file_number); + return ICUNIT_SUCCESS; +} + +void NetNetDbTest008(void) +{ + TEST_ADD_CASE(__FUNCTION__, GetHostByName2Test, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_009.cpp b/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_009.cpp new file mode 100644 index 00000000..7a9ab531 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_009.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "lt_net_netdb.h" + +static int GetHostByName2RTest(void) +{ + char host_file[] = "127.0.0.1 localhost\n"; + char *pathList[] = {"/etc/hosts"}; + char *streamList[] = {host_file}; + int streamLen[] = {sizeof(host_file)}; + const int file_number = 1; + int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number); + if (flag != 0) { + RecoveryFileEnv(pathList, file_number); + return -1; + } + + struct hostent addr, *result = NULL; + char buf[1024]; + char buf1[1]; + int err, ret; + + ret = gethostbyname2_r("localhost", AF_INET, &addr, buf, sizeof buf, &result, &err); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_NOT_EQUAL(result, NULL, -1); + ICUNIT_ASSERT_EQUAL(strcmp(result->h_name, "localhost"), 0, -1); + ICUNIT_ASSERT_EQUAL(result->h_addrtype, AF_INET, result->h_addrtype); + ICUNIT_ASSERT_NOT_EQUAL(result->h_length, 0, result->h_length); + + ret = gethostbyname2_r("127.0.0.1", AF_INET, &addr, buf, sizeof buf, &result, &err); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_NOT_EQUAL(result, NULL, -1); + ICUNIT_ASSERT_EQUAL(strcmp(result->h_name, "127.0.0.1"), 0, -1); + ICUNIT_ASSERT_EQUAL(result->h_addrtype, AF_INET, result->h_addrtype); + ICUNIT_ASSERT_NOT_EQUAL(result->h_length, 0, result->h_length); + + ret = gethostbyname2_r("127.0.0.1", AF_INET, &addr, buf1, sizeof buf1, &result, &err); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + ret = gethostbyname2_r("127.0.0.1.1", AF_INET, &addr, buf, sizeof buf, &result, &err); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + ret = gethostbyname2_r("lo", AF_INET, &addr, buf, sizeof buf, &result, &err); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + + RecoveryFileEnv(pathList, file_number); + return ICUNIT_SUCCESS; +} + +void NetNetDbTest009(void) +{ + TEST_ADD_CASE(__FUNCTION__, GetHostByName2RTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_010.cpp b/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_010.cpp new file mode 100644 index 00000000..efd6b88b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_010.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "lt_net_netdb.h" + +static int NameInfoTest(void) +{ + char host[256], serv[256]; + struct sockaddr_in addr; + addr.sin_family = AF_INET; + addr.sin_port = htons(22); + addr.sin_addr.s_addr = inet_addr("127.0.0.1"); + int ret = getnameinfo((struct sockaddr*)&addr, sizeof addr, host, sizeof host, serv, sizeof serv, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return ICUNIT_SUCCESS; +} + +void NetNetDbTest010(void) +{ + TEST_ADD_CASE(__FUNCTION__, NameInfoTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_011.cpp b/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_011.cpp new file mode 100644 index 00000000..32f7d434 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_011.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "lt_net_netdb.h" + +static int GetServByPortTest(void) +{ + // refer to the `/etc/services' file. + char serv_file[] = "ssh 22/tcp\n"; + char *pathList[] = {"/etc/services"}; + char *streamList[] = {static_cast(serv_file)}; + int streamLen[] = {sizeof(serv_file)}; + const int file_number = 1; + int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number); + if (flag != 0) { + RecoveryFileEnv(pathList, file_number); + return -1; + } + + const int test_port_no = 22; // ssh port number is 22 + struct servent *se1 = nullptr; + struct servent *se = getservbyport(htons(test_port_no), "tcp"); + ICUNIT_ASSERT_NOT_EQUAL(se, NULL, -1); + ICUNIT_ASSERT_STRING_EQUAL(se->s_name, "ssh", -1); + ICUNIT_ASSERT_STRING_EQUAL(se->s_proto, "tcp", -1); + ICUNIT_ASSERT_STRING_EQUAL(se->s_aliases[0], "ssh", -1); + + se1 = getservbyport(htons(test_port_no), "tp"); + ICUNIT_ASSERT_EQUAL(se1, nullptr, -1); + + RecoveryFileEnv(pathList, file_number); + return ICUNIT_SUCCESS; +} + +void NetNetDbTest011(void) +{ + TEST_ADD_CASE(__FUNCTION__, GetServByPortTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_012.cpp b/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_012.cpp new file mode 100644 index 00000000..503948f9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_012.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "lt_net_netdb.h" + +static int GetServByPortRTest(void) +{ + // refer to the `/etc/services' file. + char serv_file[] = "ssh 22/tcp\n"; + char *pathList[] = {"/etc/services"}; + char *streamList[] = {static_cast(serv_file)}; + int streamLen[] = {sizeof(serv_file)}; + const int file_number = 1; + int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number); + if (flag != 0) { + RecoveryFileEnv(pathList, file_number); + return -1; + } + + struct servent se, *result = NULL; + char buf[1024]; + char buf1[2]; + + const int test_port_no = 22; // ssh port number is 22 + int ret = getservbyport_r(htons(test_port_no), "tcp", &se, buf, sizeof buf, &result); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_NOT_EQUAL(result, NULL, -1); + ICUNIT_ASSERT_STRING_EQUAL(se.s_name, "ssh", -1); + ICUNIT_ASSERT_STRING_EQUAL(se.s_proto, "tcp", -1); + ICUNIT_ASSERT_STRING_EQUAL(se.s_aliases[0], "ssh", -1); + ICUNIT_ASSERT_STRING_EQUAL(result->s_name, "ssh", -1); + ICUNIT_ASSERT_STRING_EQUAL(result->s_proto, "tcp", -1); + ICUNIT_ASSERT_STRING_EQUAL(result->s_aliases[0], "ssh", -1); + + ret = getservbyport_r(htons(test_port_no), "udp", &se, buf, sizeof buf, &result); + ICUNIT_ASSERT_EQUAL(ret, ENOENT, -1); + + ret = getservbyport_r(htons(test_port_no), "udp", &se, buf1, sizeof buf1, &result); + ICUNIT_ASSERT_EQUAL(ret, ERANGE, ret); + + ret = getservbyport_r(htons(test_port_no), "ud", &se, buf, sizeof buf, &result); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + RecoveryFileEnv(pathList, file_number); + return ICUNIT_SUCCESS; +} + +void NetNetDbTest012(void) +{ + TEST_ADD_CASE(__FUNCTION__, GetServByPortRTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_015.cpp b/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_015.cpp new file mode 100644 index 00000000..612b1575 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_015.cpp @@ -0,0 +1,57 @@ +/* + * opyright (c) 2021-2021, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "lt_net_netdb.h" +#include + +static int IfNameToIndexTest(void) +{ + int ret; + char if_name[20]; + char *str = nullptr; + + ret = if_nametoindex("lo"); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, -1); + + str = if_indextoname(ret, if_name); + ICUNIT_ASSERT_NOT_EQUAL(str, nullptr, -1); + ICUNIT_ASSERT_STRING_EQUAL(if_name, "lo", -1); + + ret = if_nametoindex("eth1"); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(errno, ENODEV, errno); + + return ICUNIT_SUCCESS; +} + +void NetNetDbTest015(void) +{ + TEST_ADD_CASE(__FUNCTION__, IfNameToIndexTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_016.cpp b/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_016.cpp new file mode 100644 index 00000000..c9d2d67b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_016.cpp @@ -0,0 +1,80 @@ +/* + * opyright (c) 2021-2021, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "lt_net_netdb.h" + +static int GetServByNameTest(void) +{ + char serv_file[] = "echo 7/tcp\n" + "echo 7/udp\n" + "discard 9/tcp sink null\n" + "discard 9/udp sink null\n" + "systat 11/tcp users\n" + "ssh 22/tcp\n"; + + char *pathList[] = {"/etc/services"}; + char *streamList[] = {static_cast(serv_file)}; + int streamLen[] = {sizeof(serv_file)}; + const int file_number = 1; + int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number); + if (flag != 0) { + RecoveryFileEnv(pathList, file_number); + return -1; + } + + struct servent *se1 = nullptr; + struct servent *se2 = nullptr; + + se1 = getservbyname("discard", "tcp"); + ICUNIT_ASSERT_NOT_EQUAL(se1, NULL, -1); + ICUNIT_ASSERT_STRING_EQUAL(se1->s_name, "discard", -1); + ICUNIT_ASSERT_STRING_EQUAL(se1->s_proto, "tcp", -1); + ICUNIT_ASSERT_STRING_EQUAL(se1->s_aliases[0], "discard", -1); + + se1 = getservbyname("ssh", "tcp"); + ICUNIT_ASSERT_NOT_EQUAL(se1, nullptr, -1); + ICUNIT_ASSERT_STRING_EQUAL(se1->s_name, "ssh", -1); + ICUNIT_ASSERT_STRING_EQUAL(se1->s_proto, "tcp", -1); + ICUNIT_ASSERT_STRING_EQUAL(se1->s_aliases[0], "ssh", -1); + + se2 = getservbyname("cho", "udp"); + ICUNIT_ASSERT_EQUAL(se2, nullptr, -1); + + se2 = getservbyname("systat", "udp"); + ICUNIT_ASSERT_EQUAL(se2, nullptr, -1); + + RecoveryFileEnv(pathList, file_number); + return ICUNIT_SUCCESS; +} + +void NetNetDbTest016(void) +{ + TEST_ADD_CASE(__FUNCTION__, GetServByNameTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_017.cpp b/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_017.cpp new file mode 100644 index 00000000..a3469ff6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_017.cpp @@ -0,0 +1,79 @@ +/* + * opyright (c) 2021-2021, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "lt_net_netdb.h" + +static int GetServByNameRTest(void) +{ + char serv_file[] = "ssh 22/tcp\n"; + char *pathList[] = {"/etc/services"}; + char *streamList[] = {static_cast(serv_file)}; + int streamLen[] = {sizeof(serv_file)}; + const int file_number = 1; + int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number); + if (flag != 0) { + RecoveryFileEnv(pathList, file_number); + return -1; + } + + struct servent se; + struct servent *result = NULL; + char buf1[1024] = { 0 }; + char buf2[2] = { 0 }; + int ret; + + errno = 0; + ret = getservbyname_r("ssh", "tcp", &se, buf1, sizeof buf1, &result); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_NOT_EQUAL(result, NULL, -1); + ICUNIT_ASSERT_STRING_EQUAL(se.s_name, "ssh", -1); + ICUNIT_ASSERT_STRING_EQUAL(se.s_proto, "tcp", -1); + ICUNIT_ASSERT_STRING_EQUAL(se.s_aliases[0], "ssh", -1); + ICUNIT_ASSERT_STRING_EQUAL(result->s_name, "ssh", -1); + ICUNIT_ASSERT_STRING_EQUAL(result->s_proto, "tcp", -1); + ICUNIT_ASSERT_STRING_EQUAL(result->s_aliases[0], "ssh", -1); + + ret = getservbyname_r("ssh", "tcp", &se, buf2, sizeof buf2, &result); + ICUNIT_ASSERT_EQUAL(ret, ERANGE, ret); + + ret = getservbyname_r("ssh", "tp", &se, buf1, sizeof buf1, &result); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = getservbyname_r("sh", "tcp", &se, buf1, sizeof buf1, &result); + ICUNIT_ASSERT_EQUAL(ret, ENOENT, ret); + + RecoveryFileEnv(pathList, file_number); + return ICUNIT_SUCCESS; +} + +void NetNetDbTest017(void) +{ + TEST_ADD_CASE(__FUNCTION__, GetServByNameRTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_018.cpp b/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_018.cpp new file mode 100644 index 00000000..415fd086 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_018.cpp @@ -0,0 +1,113 @@ +/* + * opyright (c) 2021-2021, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "lt_net_netdb.h" + +static int GetServEntTest(void) +{ + char serv_file[] = "tcpmux 1/tcp # TCP port service multiplexer\n" + "echo 7/tcp\n" + "echo 7/udp\n" + "discard 9/tcp sink null\n" + "ssh 100000/tcp\n" + "ssh /tcp\n" + "ssh 22/"; + char *pathList[] = {"/etc/services"}; + char *streamList[] = {static_cast(serv_file)}; + int streamLen[] = {sizeof(serv_file)}; + const int file_number = 1; + int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number); + if (flag != 0) { + RecoveryFileEnv(pathList, file_number); + return -1; + } + + /* tcpmux,echo,discard port number is 1,7,9 */ + const int tcpmux_port_no = 1; + const int echo_port_no = 7; + const int discard_port_no = 9; + + struct servent *se1 = nullptr; + struct servent *se2 = nullptr; + struct servent *se3 = nullptr; + + se1 = getservent(); + ICUNIT_ASSERT_NOT_EQUAL(se1, nullptr, -1); + ICUNIT_ASSERT_STRING_EQUAL(se1->s_name, "tcpmux", -1); + ICUNIT_ASSERT_STRING_EQUAL(se1->s_proto, "tcp", -1); + ICUNIT_ASSERT_EQUAL(se1->s_port, ntohs(tcpmux_port_no), -1); + + endservent(); + se2 = getservent(); + ICUNIT_ASSERT_NOT_EQUAL(se2, nullptr, -1); + ICUNIT_ASSERT_STRING_EQUAL(se1->s_name, se2->s_name, -1); + ICUNIT_ASSERT_STRING_EQUAL(se1->s_proto, se2->s_proto, -1); + ICUNIT_ASSERT_EQUAL(se1->s_port, se2->s_port, -1); + + setservent(0); + se3 = getservent(); + ICUNIT_ASSERT_NOT_EQUAL(se3, nullptr, -1); + ICUNIT_ASSERT_STRING_EQUAL(se1->s_name, se3->s_name, -1); + ICUNIT_ASSERT_STRING_EQUAL(se1->s_proto, se3->s_proto, -1); + ICUNIT_ASSERT_EQUAL(se1->s_port, se3->s_port, -1); + + se3 = getservent(); + ICUNIT_ASSERT_NOT_EQUAL(se3, nullptr, -1); + ICUNIT_ASSERT_STRING_EQUAL(se3->s_name, "echo", -1); + ICUNIT_ASSERT_STRING_EQUAL(se3->s_proto, "tcp", -1); + ICUNIT_ASSERT_EQUAL(se3->s_port, ntohs(echo_port_no), -1); + + se3 = getservent(); + ICUNIT_ASSERT_NOT_EQUAL(se3, nullptr, -1); + ICUNIT_ASSERT_STRING_EQUAL(se3->s_name, "echo", -1); + ICUNIT_ASSERT_STRING_EQUAL(se3->s_proto, "udp", -1); + ICUNIT_ASSERT_EQUAL(se3->s_port, ntohs(echo_port_no), -1); + + se3 = getservent(); + ICUNIT_ASSERT_NOT_EQUAL(se3, nullptr, -1); + ICUNIT_ASSERT_STRING_EQUAL(se3->s_name, "discard", -1); + ICUNIT_ASSERT_STRING_EQUAL(se3->s_proto, "tcp", -1); + ICUNIT_ASSERT_EQUAL(se3->s_port, ntohs(discard_port_no), -1); + ICUNIT_ASSERT_STRING_EQUAL(se3->s_aliases[0], "sink", -1); + ICUNIT_ASSERT_STRING_EQUAL(se3->s_aliases[1], "null", -1); + ICUNIT_ASSERT_EQUAL(se3->s_aliases[2], nullptr, -1); + + se3 = getservent(); + ICUNIT_ASSERT_EQUAL(se3, nullptr, -1); + endservent(); + + RecoveryFileEnv(pathList, file_number); + return ICUNIT_SUCCESS; +} + +void NetNetDbTest018(void) +{ + TEST_ADD_CASE(__FUNCTION__, GetServEntTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_019.cpp b/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_019.cpp new file mode 100644 index 00000000..70ad889a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_019.cpp @@ -0,0 +1,105 @@ +/* + * opyright (c) 2021-2021, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "lt_net_netdb.h" +#include + +static int GetHostEntTest(void) +{ + char host_file[] = "127.0.0.1 localhost #localhost\n" + "::1 ip6-localhost\n" + "10.0.0.0 example example.com example.cn\n" + "10.0.0.0\n" + "10.0.0 example.com"; + char *pathList[] = {"/etc/hosts"}; + char *streamList[] = {static_cast(host_file)}; + int streamLen[] = {sizeof(host_file)}; + const int file_number = 1; + int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number); + if (flag != 0) { + RecoveryFileEnv(pathList, file_number); + return -1; + } + + struct hostent *se1 = nullptr; + struct hostent *se2 = nullptr; + struct hostent *se3 = nullptr; + char addr[INET6_ADDRSTRLEN]; + + se1 = gethostent(); + ICUNIT_ASSERT_NOT_EQUAL(se1, nullptr, -1); + ICUNIT_ASSERT_STRING_EQUAL(se1->h_name, "localhost", -1); + ICUNIT_ASSERT_EQUAL(se1->h_addrtype, AF_INET, -1); + ICUNIT_ASSERT_EQUAL(se1->h_length, INADDRSZ, -1); + ICUNIT_ASSERT_STRING_EQUAL("127.0.0.1", inet_ntop(AF_INET, se1->h_addr_list[0], addr, INET_ADDRSTRLEN), -1); + ICUNIT_ASSERT_EQUAL(se1->h_aliases[0], nullptr, -1); + + endhostent(); + se2 = gethostent(); + ICUNIT_ASSERT_NOT_EQUAL(se2, nullptr, -1); + ICUNIT_ASSERT_STRING_EQUAL(se1->h_name, se2->h_name, -1); + ICUNIT_ASSERT_EQUAL(se1->h_addrtype, se2->h_addrtype, -1); + ICUNIT_ASSERT_EQUAL(se1->h_length, se2->h_length, -1); + + sethostent(0); + se3 = gethostent(); + ICUNIT_ASSERT_NOT_EQUAL(se3, nullptr, -1); + ICUNIT_ASSERT_STRING_EQUAL(se1->h_name, se3->h_name, -1); + ICUNIT_ASSERT_EQUAL(se1->h_addrtype, se3->h_addrtype, -1); + ICUNIT_ASSERT_EQUAL(se1->h_length, se3->h_length, -1); + + se3 = gethostent(); + ICUNIT_ASSERT_NOT_EQUAL(se3, nullptr, -1); + ICUNIT_ASSERT_EQUAL(se3->h_addrtype, AF_INET6, -1); + ICUNIT_ASSERT_STRING_EQUAL(se3->h_name, "ip6-localhost", -1); + ICUNIT_ASSERT_EQUAL(se3->h_length, IN6ADDRSZ, -1); + ICUNIT_ASSERT_STRING_EQUAL("::1", inet_ntop(AF_INET6, se3->h_addr_list[0], addr, INET6_ADDRSTRLEN), -1); + + se3 = gethostent(); + ICUNIT_ASSERT_NOT_EQUAL(se3, nullptr, -1); + ICUNIT_ASSERT_EQUAL(se3->h_addrtype, AF_INET, -1); + ICUNIT_ASSERT_STRING_EQUAL(se3->h_name, "example", -1); + ICUNIT_ASSERT_STRING_EQUAL("10.0.0.0", inet_ntop(AF_INET, se3->h_addr_list[0], addr, INET_ADDRSTRLEN), -1); + ICUNIT_ASSERT_STRING_EQUAL(se3->h_aliases[0], "example.com", -1); + ICUNIT_ASSERT_STRING_EQUAL(se3->h_aliases[1], "example.cn", -1); + ICUNIT_ASSERT_EQUAL(se3->h_aliases[2], nullptr, -1); + + se3 = gethostent(); + ICUNIT_ASSERT_EQUAL(se3, nullptr, -1); + endhostent(); + + RecoveryFileEnv(pathList, file_number); + return ICUNIT_SUCCESS; +} + +void NetNetDbTest019(void) +{ + TEST_ADD_CASE(__FUNCTION__, GetHostEntTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_020.cpp b/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_020.cpp new file mode 100644 index 00000000..5cad29c6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_020.cpp @@ -0,0 +1,94 @@ +/* + * opyright (c) 2021-2021, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "lt_net_netdb.h" + +static int GetNetEntTest(void) +{ + char network_file[] = "# symbolic names for networks, see networks(5) for more information\n" + "link-local 169.254.0.0\n" + "example 192.168.1.0 network example-network\n" + "test1"; + char *pathList[] = {"/etc/networks"}; + char *streamList[] = {static_cast(network_file)}; + int streamLen[] = {sizeof(network_file)}; + const int file_number = 1; + int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number); + if (flag != 0) { + RecoveryFileEnv(pathList, file_number); + return -1; + } + + struct netent *se1 = nullptr; + struct netent *se2 = nullptr; + struct netent *se3 = nullptr; + + se1 = getnetent(); + ICUNIT_ASSERT_NOT_EQUAL(se1, nullptr, -1); + ICUNIT_ASSERT_STRING_EQUAL(se1->n_name, "link-local", -1); + ICUNIT_ASSERT_EQUAL(se1->n_addrtype, AF_INET, -1); + ICUNIT_ASSERT_EQUAL(se1->n_net, inet_network("169.254.0.0"), -1); + ICUNIT_ASSERT_EQUAL(se1->n_aliases[0], nullptr, -1); + + endnetent(); + se2 = getnetent(); + ICUNIT_ASSERT_NOT_EQUAL(se2, nullptr, -1); + ICUNIT_ASSERT_STRING_EQUAL(se1->n_name, se2->n_name, -1); + ICUNIT_ASSERT_EQUAL(se1->n_addrtype, se2->n_addrtype, -1); + ICUNIT_ASSERT_EQUAL(se1->n_net, se2->n_net, -1); + + setnetent(0); + se3 = getnetent(); + ICUNIT_ASSERT_NOT_EQUAL(se3, nullptr, -1); + ICUNIT_ASSERT_STRING_EQUAL(se1->n_name, se3->n_name, -1); + ICUNIT_ASSERT_EQUAL(se1->n_addrtype, se3->n_addrtype, -1); + ICUNIT_ASSERT_EQUAL(se1->n_net, se3->n_net, -1); + + se1 = getnetent(); + ICUNIT_ASSERT_NOT_EQUAL(se1, nullptr, -1); + ICUNIT_ASSERT_STRING_EQUAL(se1->n_name, "example", -1); + ICUNIT_ASSERT_EQUAL(se1->n_addrtype, AF_INET, -1); + ICUNIT_ASSERT_EQUAL(se1->n_net, inet_network("192.168.1.0"), -1); + ICUNIT_ASSERT_STRING_EQUAL(se1->n_aliases[0], "network", -1); + ICUNIT_ASSERT_STRING_EQUAL(se1->n_aliases[1], "example-network", -1); + ICUNIT_ASSERT_EQUAL(se1->n_aliases[2], nullptr, -1); + + se1 = getnetent(); + ICUNIT_ASSERT_EQUAL(se1, nullptr, -1); + endnetent(); + + RecoveryFileEnv(pathList, file_number); + return ICUNIT_SUCCESS; +} + +void NetNetDbTest020(void) +{ + TEST_ADD_CASE(__FUNCTION__, GetNetEntTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_021.cpp b/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_021.cpp new file mode 100644 index 00000000..9b784d51 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_021.cpp @@ -0,0 +1,70 @@ +/* + * opyright (c) 2021-2021, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "lt_net_netdb.h" + +static int GetNetBynametTest(void) +{ + char network_file[] = "# symbolic names for networks, see networks(5) for more information\n" + "link-local 169.254.0.0\n"; + char *pathList[] = {"/etc/networks"}; + char *streamList[] = {static_cast(network_file)}; + int streamLen[] = {sizeof(network_file)}; + const int file_number = 1; + int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number); + if (flag != 0) { + RecoveryFileEnv(pathList, file_number); + return -1; + } + + struct netent *se1 = nullptr; + struct netent *se2 = nullptr; + struct netent *se3 = nullptr; + + se1 = getnetbyname("link-local"); + ICUNIT_ASSERT_NOT_EQUAL(se1, nullptr, -1); + ICUNIT_ASSERT_STRING_EQUAL(se1->n_name, "link-local", -1); + ICUNIT_ASSERT_EQUAL(se1->n_addrtype, AF_INET, -1); + ICUNIT_ASSERT_EQUAL(se1->n_net, inet_network("169.254.0.0"), -1); + + se2 = getnetbyname("link"); + ICUNIT_ASSERT_EQUAL(se2, nullptr, -1); + + se3 = getnetbyname("hs"); + ICUNIT_ASSERT_EQUAL(se3, nullptr, -1); + + RecoveryFileEnv(pathList, file_number); + return ICUNIT_SUCCESS; +} + +void NetNetDbTest021(void) +{ + TEST_ADD_CASE(__FUNCTION__, GetNetBynametTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_022.cpp b/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_022.cpp new file mode 100644 index 00000000..b551318e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/netdb/full/net_netdb_test_022.cpp @@ -0,0 +1,70 @@ +/* + * opyright (c) 2021-2021, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "lt_net_netdb.h" + +static int GetNetByAddrtTest(void) +{ + char network_file[] = "# symbolic names for networks, see networks(5) for more information\n" + "link-local 169.254.0.0\n"; + char *pathList[] = {"/etc/networks"}; + char *streamList[] = {static_cast(network_file)}; + int streamLen[] = {sizeof(network_file)}; + const int file_number = 1; + int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number); + if (flag != 0) { + RecoveryFileEnv(pathList, file_number); + return -1; + } + + struct netent *se1 = nullptr; + struct netent *se2 = nullptr; + struct netent *se3 = nullptr; + + se1 = getnetbyaddr(inet_network("169.254.0.0"), AF_INET); + ICUNIT_ASSERT_NOT_EQUAL(se1, nullptr, -1); + ICUNIT_ASSERT_STRING_EQUAL(se1->n_name, "link-local", -1); + ICUNIT_ASSERT_EQUAL(se1->n_addrtype, AF_INET, -1); + ICUNIT_ASSERT_EQUAL(se1->n_net, inet_network("169.254.0.0"), -1); + + se2 = getnetbyaddr(inet_network("169.254.0.1"), AF_INET); + ICUNIT_ASSERT_EQUAL(se2, nullptr, -1); + + se3 = getnetbyaddr(inet_network("169.254.0.1"), AF_INET6); + ICUNIT_ASSERT_EQUAL(se3, nullptr, -1); + + RecoveryFileEnv(pathList, file_number); + return ICUNIT_SUCCESS; +} + +void NetNetDbTest022(void) +{ + TEST_ADD_CASE(__FUNCTION__, GetNetByAddrtTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/netdb/lt_net_netdb.h b/src/kernel_liteos_a/testsuites/unittest/net/netdb/lt_net_netdb.h new file mode 100644 index 00000000..1ef994ee --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/netdb/lt_net_netdb.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef NET_RESOLV_LT_NET_NETDB_H_ +#define NET_RESOLV_LT_NET_NETDB_H_ + +#include +#include +#include +#include +#include +#include + +void NetNetDbTest001(void); +void NetNetDbTest002(void); +void NetNetDbTest003(void); +void NetNetDbTest004(void); +void NetNetDbTest005(void); +void NetNetDbTest006(void); +void NetNetDbTest007(void); +void NetNetDbTest008(void); +void NetNetDbTest009(void); +void NetNetDbTest010(void); +void NetNetDbTest011(void); +void NetNetDbTest012(void); +void NetNetDbTest013(void); +void NetNetDbTest015(void); +void NetNetDbTest016(void); +void NetNetDbTest017(void); +void NetNetDbTest018(void); +void NetNetDbTest019(void); +void NetNetDbTest020(void); +void NetNetDbTest021(void); +void NetNetDbTest022(void); + +#endif /* NET_RESOLV_LT_NET_NETDB_H_ */ diff --git a/src/kernel_liteos_a/testsuites/unittest/net/netdb/net_netdb_test.cpp b/src/kernel_liteos_a/testsuites/unittest/net/netdb/net_netdb_test.cpp new file mode 100644 index 00000000..51e734f8 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/netdb/net_netdb_test.cpp @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "stdio.h" +#include +#include + +#include "lt_net_netdb.h" + +using namespace testing::ext; +namespace OHOS { +class NetDbTest : public testing::Test { +public: + static void SetUpTestCase(void) + { + struct sched_param param = { 0 }; + int currThreadPolicy, ret; + ret = pthread_getschedparam(pthread_self(), &currThreadPolicy, ¶m); + param.sched_priority = TASK_PRIO_TEST; + ret = pthread_setschedparam(pthread_self(), SCHED_RR, ¶m); + } + static void TearDownTestCase(void) {} +}; + +#if defined(LOSCFG_USER_TEST_SMOKE) && defined(LOSCFG_USER_TEST_NET_NETDB) +/* * + * @tc.name: NetNetDbTest001 + * @tc.desc: function for NetDbTest + * @tc.type: FUNC + */ +HWTEST_F(NetDbTest, NetNetDbTest001, TestSize.Level0) +{ + NetNetDbTest001(); +} + +/* * + * @tc.name: NetNetDbTest013 + * @tc.desc: function for NetDbTest + * @tc.type: FUNC + */ +HWTEST_F(NetDbTest, NetNetDbTest013, TestSize.Level0) +{ + NetNetDbTest013(); +} + +#endif + +#if defined(LOSCFG_USER_TEST_FULL) +/* * + * @tc.name: NetNetDbTest018 + * @tc.desc: function for NetDbTest + * @tc.type: FUNC + */ +HWTEST_F(NetDbTest, NetNetDbTest018, TestSize.Level0) +{ + NetNetDbTest018(); +} + +/* * + * @tc.name: NetNetDbTest002 + * @tc.desc: function for NetDbTest + * @tc.type: FUNC + */ +HWTEST_F(NetDbTest, NetNetDbTest002, TestSize.Level0) +{ + NetNetDbTest002(); +} + +/* * + * @tc.name: NetNetDbTest003 + * @tc.desc: function for NetDbTest + * @tc.type: FUNC + */ +HWTEST_F(NetDbTest, NetNetDbTest003, TestSize.Level0) +{ + NetNetDbTest003(); +} + +/* * + * @tc.name: NetNetDbTest004 + * @tc.desc: function for NetDbTest + * @tc.type: FUNC + */ +HWTEST_F(NetDbTest, NetNetDbTest004, TestSize.Level0) +{ + NetNetDbTest004(); +} + +/* * + * @tc.name: NetNetDbTest006 + * @tc.desc: function for NetDbTest + * @tc.type: FUNC + */ +HWTEST_F(NetDbTest, NetNetDbTest006, TestSize.Level0) +{ + NetNetDbTest006(); +} + +/* * + * @tc.name: NetNetDbTest007 + * @tc.desc: function for NetDbTest + * @tc.type: FUNC + */ +HWTEST_F(NetDbTest, NetNetDbTest007, TestSize.Level0) +{ + NetNetDbTest007(); +} + +/* * + * @tc.name: NetNetDbTest008 + * @tc.desc: function for NetDbTest + * @tc.type: FUNC + */ +HWTEST_F(NetDbTest, NetNetDbTest008, TestSize.Level0) +{ + NetNetDbTest008(); +} + +/* * + * @tc.name: NetNetDbTest009 + * @tc.desc: function for NetDbTest + * @tc.type: FUNC + */ +HWTEST_F(NetDbTest, NetNetDbTest009, TestSize.Level0) +{ + NetNetDbTest009(); +} + +/* * + * @tc.name: NetNetDbTest010 + * @tc.desc: function for NetDbTest + * @tc.type: FUNC + */ +HWTEST_F(NetDbTest, NetNetDbTest010, TestSize.Level0) +{ + NetNetDbTest010(); +} + +/* * + * @tc.name: NetNetDbTest011 + * @tc.desc: function for NetDbTest + * @tc.type: FUNC + */ +HWTEST_F(NetDbTest, NetNetDbTest011, TestSize.Level0) +{ + NetNetDbTest011(); +} + +/* * + * @tc.name: NetNetDbTest012 + * @tc.desc: function for NetDbTest + * @tc.type: FUNC + */ +HWTEST_F(NetDbTest, NetNetDbTest012, TestSize.Level0) +{ + NetNetDbTest012(); +} + +/* * + * @tc.name: NetNetDbTest015 + * @tc.desc: function for NetDbTest + * @tc.type: FUNC + */ +HWTEST_F(NetDbTest, NetNetDbTest015, TestSize.Level0) +{ + NetNetDbTest015(); +} + +/* * + * @tc.name: NetNetDbTest016 + * @tc.desc: function for NetDbTest + * @tc.type: FUNC + */ +HWTEST_F(NetDbTest, NetNetDbTest016, TestSize.Level0) +{ + NetNetDbTest016(); +} + +/* * + * @tc.name: NetNetDbTest017 + * @tc.desc: function for NetDbTest + * @tc.type: FUNC + */ +HWTEST_F(NetDbTest, NetNetDbTest017, TestSize.Level0) +{ + NetNetDbTest017(); +} + +/* * + * @tc.name: NetNetDbTest019 + * @tc.desc: function for NetDbTest + * @tc.type: FUNC + */ +HWTEST_F(NetDbTest, NetNetDbTest019, TestSize.Level0) +{ + NetNetDbTest019(); +} + +/* * + * @tc.name: NetNetDbTest020 + * @tc.desc: function for NetDbTest + * @tc.type: FUNC + */ +HWTEST_F(NetDbTest, NetNetDbTest020, TestSize.Level0) +{ + NetNetDbTest020(); +} + +/* * + * @tc.name: NetNetDbTest021 + * @tc.desc: function for NetDbTest + * @tc.type: FUNC + */ +HWTEST_F(NetDbTest, NetNetDbTest021, TestSize.Level0) +{ + NetNetDbTest021(); +} + +/* * + * @tc.name: NetNetDbTest022 + * @tc.desc: function for NetDbTest + * @tc.type: FUNC + */ +HWTEST_F(NetDbTest, NetNetDbTest022, TestSize.Level0) +{ + NetNetDbTest022(); +} + +#endif +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/netdb/smoke/net_netdb_test_001.cpp b/src/kernel_liteos_a/testsuites/unittest/net/netdb/smoke/net_netdb_test_001.cpp new file mode 100644 index 00000000..1e0b53af --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/netdb/smoke/net_netdb_test_001.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "lt_net_netdb.h" + +static int ProtoentTest(void) +{ + setprotoent(1); + + // refer to the `/etc/protocols' file. + struct protoent *prot = getprotobyname("icmp"); + ICUNIT_ASSERT_NOT_EQUAL(prot, NULL, -1); + ICUNIT_ASSERT_EQUAL(prot->p_proto, 1, prot->p_proto); + + prot = getprotobynumber(1); + ICUNIT_ASSERT_NOT_EQUAL(prot, NULL, -1); + ICUNIT_ASSERT_EQUAL(strcmp(prot->p_name, "icmp"), 0, -1); + + prot = getprotoent(); + ICUNIT_ASSERT_NOT_EQUAL(prot, NULL, -1); + + endprotoent(); + return ICUNIT_SUCCESS; +} + +void NetNetDbTest001(void) +{ + TEST_ADD_CASE(__FUNCTION__, ProtoentTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/netdb/smoke/net_netdb_test_013.cpp b/src/kernel_liteos_a/testsuites/unittest/net/netdb/smoke/net_netdb_test_013.cpp new file mode 100644 index 00000000..b713849d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/netdb/smoke/net_netdb_test_013.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "lt_net_netdb.h" + +static int HerrorTest(void) +{ + const char *err = hstrerror(TRY_AGAIN); + ICUNIT_ASSERT_NOT_EQUAL(err, NULL, -1); + + herror(err); + + return ICUNIT_SUCCESS; +} + +void NetNetDbTest013(void) +{ + TEST_ADD_CASE(__FUNCTION__, HerrorTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/resolv/config.gni b/src/kernel_liteos_a/testsuites/unittest/net/resolv/config.gni new file mode 100644 index 00000000..0b8cb730 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/resolv/config.gni @@ -0,0 +1,47 @@ +# Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +resolv_include_dirs = [ "$TEST_UNITTEST_DIR/net/resolv" ] + +resolv_sources_entry = [ "$TEST_UNITTEST_DIR/net/resolv/net_resolv_test.cpp" ] + +resolv_sources_smoke = [ + "$TEST_UNITTEST_DIR/net/resolv/smoke/net_resolv_test_001.cpp", + "$TEST_UNITTEST_DIR/net/resolv/smoke/net_resolv_test_002.cpp", + "$TEST_UNITTEST_DIR/net/resolv/smoke/net_resolv_test_003.cpp", + "$TEST_UNITTEST_DIR/net/resolv/smoke/net_resolv_test_006.cpp", + "$TEST_UNITTEST_DIR/net/resolv/smoke/net_resolv_test_007.cpp", +] + +resolv_sources_full = [ + "$TEST_UNITTEST_DIR/net/resolv/full/net_resolv_test_004.cpp", + "$TEST_UNITTEST_DIR/net/resolv/full/net_resolv_test_005.cpp", + "$TEST_UNITTEST_DIR/net/resolv/full/net_resolv_test_008.cpp", +] diff --git a/src/kernel_liteos_a/testsuites/unittest/net/resolv/full/net_resolv_test_004.cpp b/src/kernel_liteos_a/testsuites/unittest/net/resolv/full/net_resolv_test_004.cpp new file mode 100644 index 00000000..ea7b2ed7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/resolv/full/net_resolv_test_004.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +static int EtherHosttonTest(void) +{ + // suppose "0:0:0:0:0:0 localhost" in `/etc/ethers' file. + char ether_file[] = "0:0:0:0:0:0 localhost"; + char *pathList[] = {"/etc/ethers"}; + char *streamList[] = {static_cast(ether_file)}; + int streamLen[] = {sizeof(ether_file)}; + const int file_number = 1; + int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number); + if (flag != 0) { + RecoveryFileEnv(pathList, file_number); + return -1; + } + + struct ether_addr addr, *eaddr = &addr; + int ret = ether_hostton("localhost", eaddr); + + ICUNIT_ASSERT_EQUAL(ret, 0, -1); + ICUNIT_ASSERT_EQUAL(eaddr->ether_addr_octet[0], 0x00, eaddr->ether_addr_octet[0]); + ICUNIT_ASSERT_EQUAL(eaddr->ether_addr_octet[1], 0x00, eaddr->ether_addr_octet[1]); + ICUNIT_ASSERT_EQUAL(eaddr->ether_addr_octet[2], 0x00, eaddr->ether_addr_octet[2]); + ICUNIT_ASSERT_EQUAL(eaddr->ether_addr_octet[3], 0x00, eaddr->ether_addr_octet[3]); + ICUNIT_ASSERT_EQUAL(eaddr->ether_addr_octet[4], 0x00, eaddr->ether_addr_octet[4]); + ICUNIT_ASSERT_EQUAL(eaddr->ether_addr_octet[5], 0x00, eaddr->ether_addr_octet[5]); + + RecoveryFileEnv(pathList, file_number); + return ICUNIT_SUCCESS; +} + +void NetResolvTest004(void) +{ + TEST_ADD_CASE(__FUNCTION__, EtherHosttonTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/resolv/full/net_resolv_test_005.cpp b/src/kernel_liteos_a/testsuites/unittest/net/resolv/full/net_resolv_test_005.cpp new file mode 100644 index 00000000..abb18b64 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/resolv/full/net_resolv_test_005.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include + +static int EtherLineTest(void) +{ + struct ether_addr addr, *eaddr = &addr; + char buf[100]; + int ret; + + ret = ether_line("localhost 01:02:03:04:05:06", eaddr, buf); + ICUNIT_ASSERT_EQUAL(ret, -1, -1); + + ret = ether_line("01:02:03:04:05:06 localhost", eaddr, buf); + ICUNIT_ASSERT_EQUAL(ret, 0, -1); + + ICUNIT_ASSERT_EQUAL(strcmp("localhost", buf), 0, -1); + ICUNIT_ASSERT_EQUAL(eaddr->ether_addr_octet[0], 0x01, eaddr->ether_addr_octet[0]); + ICUNIT_ASSERT_EQUAL(eaddr->ether_addr_octet[1], 0x02, eaddr->ether_addr_octet[1]); + ICUNIT_ASSERT_EQUAL(eaddr->ether_addr_octet[2], 0x03, eaddr->ether_addr_octet[2]); + ICUNIT_ASSERT_EQUAL(eaddr->ether_addr_octet[3], 0x04, eaddr->ether_addr_octet[3]); + ICUNIT_ASSERT_EQUAL(eaddr->ether_addr_octet[4], 0x05, eaddr->ether_addr_octet[4]); + ICUNIT_ASSERT_EQUAL(eaddr->ether_addr_octet[5], 0x06, eaddr->ether_addr_octet[5]); + + return ICUNIT_SUCCESS; +} + +void NetResolvTest005(void) +{ + TEST_ADD_CASE(__FUNCTION__, EtherLineTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/resolv/full/net_resolv_test_008.cpp b/src/kernel_liteos_a/testsuites/unittest/net/resolv/full/net_resolv_test_008.cpp new file mode 100644 index 00000000..2fe4a303 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/resolv/full/net_resolv_test_008.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include + +static int EtherNtohostTest(void) +{ + // suppose "0:0:0:0:0:0 localhost" in `/etc/ethers' file. + char ether_file[] = "0:0:0:0:0:0 localhost"; + char *pathList[] = {"/etc/ethers"}; + char *streamList[] = {static_cast(ether_file)}; + int streamLen[] = {sizeof(ether_file)}; + const int file_number = 1; + int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number); + if (flag != 0) { + RecoveryFileEnv(pathList, file_number); + return -1; + } + + struct ether_addr addr = {{0,0,0,0,0,0}}, *eaddr = &addr; + char buf[100]; + int ret = ether_ntohost(buf, eaddr); + + ICUNIT_ASSERT_EQUAL(ret, 0, -1); + ICUNIT_ASSERT_EQUAL(strcmp("localhost", buf), 0, -1); + + RecoveryFileEnv(pathList, file_number); + return ICUNIT_SUCCESS; +} + +void NetResolvTest008(void) +{ + TEST_ADD_CASE(__FUNCTION__, EtherNtohostTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/resolv/lt_net_resolv.h b/src/kernel_liteos_a/testsuites/unittest/net/resolv/lt_net_resolv.h new file mode 100644 index 00000000..26b25985 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/resolv/lt_net_resolv.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef NET_RESOLV_LT_NET_RESOLV_H_ +#define NET_RESOLV_LT_NET_RESOLV_H_ + +#include +#include +#include +#include + +int stricmp(const char *s1, const char *s2); + +void NetResolvTest001(void); +void NetResolvTest002(void); +void NetResolvTest003(void); +void NetResolvTest004(void); +void NetResolvTest005(void); +void NetResolvTest006(void); +void NetResolvTest007(void); +void NetResolvTest008(void); + +#endif /* NET_RESOLV_LT_NET_RESOLV_H_ */ diff --git a/src/kernel_liteos_a/testsuites/unittest/net/resolv/net_resolv_test.cpp b/src/kernel_liteos_a/testsuites/unittest/net/resolv/net_resolv_test.cpp new file mode 100644 index 00000000..515d71cb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/resolv/net_resolv_test.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "stdio.h" +#include +#include + +#include "lt_net_resolv.h" + +int stricmp(const char *s1, const char *s2) +{ + for (; *s1 && *s2; s1++, s2++) { + if (*s1 == *s2) continue; + if ((*s1 ^ *s2) == 0x20 && (*s2 | 0x20) >= 'a' && (*s2 | 0x20) <= 'z') continue; + break; + } + return *s1 - *s2; +} + +using namespace testing::ext; +namespace OHOS { +class NetResolvTest : public testing::Test { +public: + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} +}; + +#if defined(LOSCFG_USER_TEST_SMOKE) && defined(LOSCFG_USER_TEST_NET_RESOLV) +/* * + * @tc.name: NetResolvTest001 + * @tc.desc: function for NetResolvTest + * @tc.type: FUNC + */ +HWTEST_F(NetResolvTest, NetResolvTest001, TestSize.Level0) +{ + NetResolvTest001(); +} + +/* * + * @tc.name: NetResolvTest002 + * @tc.desc: function for NetResolvTest + * @tc.type: FUNC + */ +HWTEST_F(NetResolvTest, NetResolvTest002, TestSize.Level0) +{ + NetResolvTest002(); +} + +/* * + * @tc.name: NetResolvTest003 + * @tc.desc: function for NetResolvTest + * @tc.type: FUNC + */ +HWTEST_F(NetResolvTest, NetResolvTest003, TestSize.Level0) +{ + NetResolvTest003(); +} + +/* * + * @tc.name: NetResolvTest006 + * @tc.desc: function for NetResolvTest + * @tc.type: FUNC + */ +HWTEST_F(NetResolvTest, NetResolvTest006, TestSize.Level0) +{ + NetResolvTest006(); +} + +/* * + * @tc.name: NetResolvTest007 + * @tc.desc: function for NetResolvTest + * @tc.type: FUNC + */ +HWTEST_F(NetResolvTest, NetResolvTest007, TestSize.Level0) +{ + NetResolvTest007(); +} + +#endif +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/resolv/smoke/net_resolv_test_001.cpp b/src/kernel_liteos_a/testsuites/unittest/net/resolv/smoke/net_resolv_test_001.cpp new file mode 100644 index 00000000..821c82eb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/resolv/smoke/net_resolv_test_001.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include +#include +static void dump(unsigned char *s, int len) { + if (!s) return; + for (int i = 0; i < len; ++i) { + printf("%02x ", s[i]); + } + printf("\n"); +} + +static int DnCompTest(void) +{ + unsigned char comp_dn[100] = "example"; + unsigned char *dnptrs[6] = {comp_dn, 0}; + unsigned char **lastdnptr = &dnptrs[6]; + int offset, ret; + + offset = strlen(reinterpret_cast(dnptrs[0])) + 1; + ret = dn_comp("x.y.z.example.com", comp_dn + offset, sizeof(comp_dn) - offset, dnptrs, lastdnptr); + dump(comp_dn + offset, ret); + ICUNIT_ASSERT_EQUAL(ret, 19, ret); + ICUNIT_ASSERT_EQUAL(dnptrs[1], comp_dn + offset, dnptrs[1]); + + offset += ret+1; + ret = dn_comp("zz.example.com", comp_dn + offset, sizeof(comp_dn) - offset, dnptrs, lastdnptr); + dump(comp_dn+offset, ret); + ICUNIT_ASSERT_EQUAL(ret, 5, ret); + ICUNIT_ASSERT_EQUAL(dnptrs[2], comp_dn + offset, dnptrs[2]); + + offset += ret+1; + ret = dn_comp("a.example.com", comp_dn + offset, sizeof(comp_dn) - offset, dnptrs, lastdnptr); + dump(comp_dn+offset, ret); + ICUNIT_ASSERT_EQUAL(ret, 4, ret); + ICUNIT_ASSERT_EQUAL(dnptrs[3], comp_dn + offset, dnptrs[3]); + + offset += ret+1; + ret = dn_comp("example.com.cn", comp_dn + offset, sizeof(comp_dn) - offset, dnptrs, lastdnptr); + dump(comp_dn+offset, ret); + ICUNIT_ASSERT_EQUAL(ret, 16, ret); + ICUNIT_ASSERT_EQUAL(dnptrs[4], comp_dn + offset, dnptrs[4]); + + offset += ret+1; + ret = dn_comp("2example.com", comp_dn + offset, sizeof(comp_dn) - offset, dnptrs, lastdnptr); + dump(comp_dn+offset, ret); + ICUNIT_ASSERT_EQUAL(ret, 11, ret); + ICUNIT_ASSERT_EQUAL(dnptrs[5], /*comp_dn+offset*/ NULL, dnptrs[5]); //last one is always NULL + + for (int i = 0; i < 6; ++i) { + printf("%p: %s\n", dnptrs[i], dnptrs[i]); + } + ICUNIT_ASSERT_EQUAL(offset + ret < 100, 1, ret); + return ICUNIT_SUCCESS; +} + +void NetResolvTest001(void) +{ + TEST_ADD_CASE(__FUNCTION__, DnCompTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/resolv/smoke/net_resolv_test_002.cpp b/src/kernel_liteos_a/testsuites/unittest/net/resolv/smoke/net_resolv_test_002.cpp new file mode 100644 index 00000000..4e570199 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/resolv/smoke/net_resolv_test_002.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include + +const int buffer_size = 20; + +static int EtherAtonTest(void) +{ + struct ether_addr *eaddr = ether_aton("01::EF"); + + ICUNIT_ASSERT_EQUAL(eaddr, NULL, -1); + + char mac_addr[buffer_size], *tmp = mac_addr; + int r[ETH_ALEN]; + srand(time(NULL)); + for (int i = 0; i < ETH_ALEN; i++) { + r[i] = rand() % 0xff; + } + // 0, 1, 2, 3, 4, 5: 6 elements of mac address. + (void)sprintf_s(mac_addr, sizeof(mac_addr), "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", r[0], r[1], r[2], r[3], r[4], r[5]); + eaddr = ether_aton(mac_addr); + ICUNIT_ASSERT_NOT_EQUAL(eaddr, NULL, -1); + + ICUNIT_ASSERT_EQUAL(eaddr->ether_addr_octet[0], r[0], eaddr->ether_addr_octet[0]); + ICUNIT_ASSERT_EQUAL(eaddr->ether_addr_octet[1], r[1], eaddr->ether_addr_octet[1]); + ICUNIT_ASSERT_EQUAL(eaddr->ether_addr_octet[2], r[2], eaddr->ether_addr_octet[2]); // 2: compare r[2] with eaddr + ICUNIT_ASSERT_EQUAL(eaddr->ether_addr_octet[3], r[3], eaddr->ether_addr_octet[3]); // 3: compare r[3] with eaddr + ICUNIT_ASSERT_EQUAL(eaddr->ether_addr_octet[4], r[4], eaddr->ether_addr_octet[4]); // 4: compare r[4] with eaddr + ICUNIT_ASSERT_EQUAL(eaddr->ether_addr_octet[5], r[5], eaddr->ether_addr_octet[5]); // 5: compare r[5] with eaddr + + return ICUNIT_SUCCESS; +} + +void NetResolvTest002(void) +{ + TEST_ADD_CASE(__FUNCTION__, EtherAtonTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/resolv/smoke/net_resolv_test_003.cpp b/src/kernel_liteos_a/testsuites/unittest/net/resolv/smoke/net_resolv_test_003.cpp new file mode 100644 index 00000000..85929a8b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/resolv/smoke/net_resolv_test_003.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include + +const int buffer_size = 20; + +static int EtherAtonrTest(void) +{ + struct ether_addr addr; + struct ether_addr *eaddr = ether_aton_r("::01:EF", &addr); + + ICUNIT_ASSERT_EQUAL(eaddr, NULL, -1); + + char mac_addr[buffer_size], *tmp = mac_addr; + int r[ETH_ALEN]; + srand(time(NULL)); + for (int i = 0; i < ETH_ALEN; i++) { + r[i] = rand() % 0xff; + } + // 0, 1, 2, 3, 4, 5: 6 elements of mac address. + (void)sprintf_s(mac_addr, sizeof(mac_addr), "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", r[0], r[1], r[2], r[3], r[4], r[5]); + eaddr = ether_aton_r(mac_addr, &addr); + + ICUNIT_ASSERT_EQUAL(eaddr, &addr, -1); + ICUNIT_ASSERT_EQUAL(eaddr->ether_addr_octet[0], r[0], eaddr->ether_addr_octet[0]); + ICUNIT_ASSERT_EQUAL(eaddr->ether_addr_octet[1], r[1], eaddr->ether_addr_octet[1]); + ICUNIT_ASSERT_EQUAL(eaddr->ether_addr_octet[2], r[2], eaddr->ether_addr_octet[2]); // 2: compare r[2] with eaddr + ICUNIT_ASSERT_EQUAL(eaddr->ether_addr_octet[3], r[3], eaddr->ether_addr_octet[3]); // 3: compare r[3] with eaddr + ICUNIT_ASSERT_EQUAL(eaddr->ether_addr_octet[4], r[4], eaddr->ether_addr_octet[4]); // 4: compare r[4] with eaddr + ICUNIT_ASSERT_EQUAL(eaddr->ether_addr_octet[5], r[5], eaddr->ether_addr_octet[5]); // 5: compare r[5] with eaddr + + return ICUNIT_SUCCESS; +} + +void NetResolvTest003(void) +{ + TEST_ADD_CASE(__FUNCTION__, EtherAtonrTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/resolv/smoke/net_resolv_test_006.cpp b/src/kernel_liteos_a/testsuites/unittest/net/resolv/smoke/net_resolv_test_006.cpp new file mode 100644 index 00000000..7625ada9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/resolv/smoke/net_resolv_test_006.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include + +const int buffer_size = 20; + +static int EtherNtoaTest(void) +{ + struct ether_addr addr, *eaddr = &addr; + srand(time(NULL)); + int r[ETH_ALEN]; + for (int i = 0; i < ETH_ALEN; i++) { + r[i] = rand() % 16; // 16: 0x0-0xf + eaddr->ether_addr_octet[i] = r[i]; + } + char *buf = ether_ntoa(eaddr); + char str1[buffer_size], str2[buffer_size]; + // 0, 1, 2, 3, 4, 5: 6 elements of mac address. + (void)sprintf_s(str1, sizeof(str1), "%x:%x:%x:%x:%x:%x", r[0], r[1], r[2], r[3], r[4], r[5]); + // 0, 1, 2, 3, 4, 5: 6 elements of mac address. + (void)sprintf_s(str2, sizeof(str2), "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", r[0], r[1], r[2], r[3], r[4], r[5]); + + ICUNIT_ASSERT_NOT_EQUAL(buf, 0, -1); + ICUNIT_ASSERT_EQUAL((stricmp(str1, buf) == 0 || stricmp(str2, buf) == 0), 1, printf("%s\n", buf)); + + return ICUNIT_SUCCESS; +} + +void NetResolvTest006(void) +{ + TEST_ADD_CASE(__FUNCTION__, EtherNtoaTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/resolv/smoke/net_resolv_test_007.cpp b/src/kernel_liteos_a/testsuites/unittest/net/resolv/smoke/net_resolv_test_007.cpp new file mode 100644 index 00000000..d6508c21 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/resolv/smoke/net_resolv_test_007.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +const int buffer_size = 20; + +static int EtherNtoarTest(void) +{ + struct ether_addr addr, *eaddr = &addr; + srand(time(NULL)); + int r[ETH_ALEN]; + for (int i = 0; i < ETH_ALEN; i++) { + r[i] = rand() % 16; // 16: 0x0-0xf + eaddr->ether_addr_octet[i] = r[i]; + } + char buf[100], *p = ether_ntoa_r(eaddr, buf); + + char str1[buffer_size], str2[buffer_size]; + // 0, 1, 2, 3, 4, 5: 6 elements of mac address. + (void)sprintf_s(str1, sizeof(str1), "%x:%x:%x:%x:%x:%x", r[0], r[1], r[2], r[3], r[4], r[5]); + // 0, 1, 2, 3, 4, 5: 6 elements of mac address. + (void)sprintf_s(str2, sizeof(str2), "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", r[0], r[1], r[2], r[3], r[4], r[5]); + + ICUNIT_ASSERT_EQUAL(p, buf, (intptr_t)p); + ICUNIT_ASSERT_EQUAL((stricmp(str1, buf) == 0 || stricmp(str2, buf) == 0), 1, printf("%s\n", p)); + + return ICUNIT_SUCCESS; +} + +void NetResolvTest007(void) +{ + TEST_ADD_CASE(__FUNCTION__, EtherNtoarTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/socket/config.gni b/src/kernel_liteos_a/testsuites/unittest/net/socket/config.gni new file mode 100644 index 00000000..93c4942d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/socket/config.gni @@ -0,0 +1,51 @@ +# Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +socket_include_dirs = [ "$TEST_UNITTEST_DIR/net/socket" ] + +socket_sources_entry = [ "$TEST_UNITTEST_DIR/net/socket/net_socket_test.cpp" ] + +socket_sources_smoke = [ + "$TEST_UNITTEST_DIR/net/socket/smoke/net_socket_test_001.cpp", + "$TEST_UNITTEST_DIR/net/socket/smoke/net_socket_test_002.cpp", + "$TEST_UNITTEST_DIR/net/socket/smoke/net_socket_test_003.cpp", + "$TEST_UNITTEST_DIR/net/socket/smoke/net_socket_test_004.cpp", + "$TEST_UNITTEST_DIR/net/socket/smoke/net_socket_test_005.cpp", + "$TEST_UNITTEST_DIR/net/socket/smoke/net_socket_test_006.cpp", + "$TEST_UNITTEST_DIR/net/socket/smoke/net_socket_test_007.cpp", + "$TEST_UNITTEST_DIR/net/socket/smoke/net_socket_test_008.cpp", + "$TEST_UNITTEST_DIR/net/socket/smoke/net_socket_test_009.cpp", + "$TEST_UNITTEST_DIR/net/socket/smoke/net_socket_test_010.cpp", + "$TEST_UNITTEST_DIR/net/socket/smoke/net_socket_test_011.cpp", + "$TEST_UNITTEST_DIR/net/socket/smoke/net_socket_test_012.cpp", + "$TEST_UNITTEST_DIR/net/socket/smoke/net_socket_test_013.cpp", +] + +socket_sources_full = [] diff --git a/src/kernel_liteos_a/testsuites/unittest/net/socket/lt_net_socket.h b/src/kernel_liteos_a/testsuites/unittest/net/socket/lt_net_socket.h new file mode 100644 index 00000000..04d027c6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/socket/lt_net_socket.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef NET_SOCKET_LT_NET_SOCKET_H_ +#define NET_SOCKET_LT_NET_SOCKET_H_ + +#include +#include + +void NetSocketTest001(void); +void NetSocketTest002(void); +void NetSocketTest003(void); +void NetSocketTest004(void); +void NetSocketTest005(void); +void NetSocketTest006(void); +void NetSocketTest007(void); +void NetSocketTest008(void); +void NetSocketTest009(void); +void NetSocketTest010(void); +void NetSocketTest011(void); +void NetSocketTest012(void); +void NetSocketTest013(void); + +#endif /* NET_SOCKET_LT_NET_SOCKET_H_ */ diff --git a/src/kernel_liteos_a/testsuites/unittest/net/socket/net_socket_test.cpp b/src/kernel_liteos_a/testsuites/unittest/net/socket/net_socket_test.cpp new file mode 100644 index 00000000..bf71bf33 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/socket/net_socket_test.cpp @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "stdio.h" +#include +#include + +#include "lt_net_socket.h" + +using namespace testing::ext; +namespace OHOS { +class NetSocketTest : public testing::Test { +public: + static void SetUpTestCase(void) + { + struct sched_param param = { 0 }; + int currThreadPolicy, ret; + ret = pthread_getschedparam(pthread_self(), &currThreadPolicy, ¶m); + ICUNIT_ASSERT_EQUAL_VOID(ret, 0, -ret); + param.sched_priority = TASK_PRIO_TEST; + ret = pthread_setschedparam(pthread_self(), SCHED_RR, ¶m); + ICUNIT_ASSERT_EQUAL_VOID(ret, 0, -ret); + } + static void TearDownTestCase(void) {} +}; + +#if defined(LOSCFG_USER_TEST_SMOKE) && defined(LOSCFG_USER_TEST_NET_SOCKET) +/* * + * @tc.name: NetSocketTest001 + * @tc.desc: function for NetSocketTest + * @tc.type: FUNC + */ +HWTEST_F(NetSocketTest, NetSocketTest001, TestSize.Level0) +{ + NetSocketTest001(); +} + +/* * + * @tc.name: NetSocketTest002 + * @tc.desc: function for NetSocketTest + * @tc.type: FUNC + */ +HWTEST_F(NetSocketTest, NetSocketTest002, TestSize.Level0) +{ + NetSocketTest002(); +} + +#if TEST_ON_LINUX +/* * + * @tc.name: NetSocketTest003 + * @tc.desc: function for NetSocketTest + * @tc.type: FUNC + */ +HWTEST_F(NetSocketTest, NetSocketTest003, TestSize.Level0) +{ + NetSocketTest003(); // getifaddrs need PF_NETLINK which was not supported by lwip currently +} +#endif + +/* * + * @tc.name: NetSocketTest004 + * @tc.desc: function for NetSocketTest + * @tc.type: FUNC + */ +HWTEST_F(NetSocketTest, NetSocketTest004, TestSize.Level0) +{ + NetSocketTest004(); +} + +/* * + * @tc.name: NetSocketTest005 + * @tc.desc: function for NetSocketTest + * @tc.type: FUNC + */ +HWTEST_F(NetSocketTest, NetSocketTest005, TestSize.Level0) +{ + NetSocketTest005(); +} + +/* * + * @tc.name: NetSocketTest006 + * @tc.desc: function for NetSocketTest + * @tc.type: FUNC + */ +HWTEST_F(NetSocketTest, NetSocketTest006, TestSize.Level0) +{ + NetSocketTest006(); +} + +#if TEST_ON_LINUX +/* * + * @tc.name: NetSocketTest007 + * @tc.desc: function for NetSocketTest + * @tc.type: FUNC + */ +HWTEST_F(NetSocketTest, NetSocketTest007, TestSize.Level0) +{ + NetSocketTest007(); +} +#endif + +/* * + * @tc.name: NetSocketTest008 + * @tc.desc: function for NetSocketTest + * @tc.type: FUNC + */ +HWTEST_F(NetSocketTest, NetSocketTest008, TestSize.Level0) +{ + NetSocketTest008(); +} + +/* * + * @tc.name: NetSocketTest009 + * @tc.desc: function for NetSocketTest + * @tc.type: FUNC + */ +HWTEST_F(NetSocketTest, NetSocketTest009, TestSize.Level0) +{ + NetSocketTest009(); +} + +/* * + * @tc.name: NetSocketTest010 + * @tc.desc: function for NetSocketTest + * @tc.type: FUNC + */ +HWTEST_F(NetSocketTest, NetSocketTest010, TestSize.Level0) +{ + NetSocketTest010(); +} + +/* * + * @tc.name: NetSocketTest011 + * @tc.desc: function for NetSocketTest + * @tc.type: FUNC + */ +HWTEST_F(NetSocketTest, NetSocketTest011, TestSize.Level0) +{ + NetSocketTest011(); +} + +/* * + * @tc.name: NetSocketTest012 + * @tc.desc: function for NetSocketTest + * @tc.type: FUNC + */ +HWTEST_F(NetSocketTest, NetSocketTest012, TestSize.Level0) +{ + NetSocketTest012(); +} + +#endif +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_001.cpp b/src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_001.cpp new file mode 100644 index 00000000..1fc95838 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_001.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +static int SocketTest(void) +{ + int fd = socket(0, 0, 0); + ICUNIT_ASSERT_EQUAL(fd, -1, fd); + return ICUNIT_SUCCESS; +} + +void NetSocketTest001(void) +{ + TEST_ADD_CASE(__FUNCTION__, SocketTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_002.cpp b/src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_002.cpp new file mode 100644 index 00000000..d0a4ce68 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_002.cpp @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define localhost "127.0.0.1" +#define STACK_IP localhost +#define STACK_PORT 2277 +#define PEER_PORT STACK_PORT +#define PEER_IP localhost +#define MSG "Hi, I am UDP" +#define BUF_SIZE (1024 * 8) + +static char g_buf[BUF_SIZE + 1] = { 0 }; + +static int UdpTest(void) +{ + int sfd; + struct sockaddr_in srvAddr = { 0 }; + struct sockaddr_in clnAddr = { 0 }; + socklen_t clnAddrLen = sizeof(clnAddr); + int ret = 0, i = 0; + struct msghdr msg = { 0 }; + struct iovec iov[2] = { }; + + /* socket creation */ + sfd = socket(AF_INET, SOCK_DGRAM, 0); + ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, sfd); + + srvAddr.sin_family = AF_INET; + srvAddr.sin_addr.s_addr = inet_addr(STACK_IP); + srvAddr.sin_port = htons(STACK_PORT); + ret = bind(sfd, reinterpret_cast(&srvAddr), sizeof(srvAddr)); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + /* send */ + clnAddr.sin_family = AF_INET; + clnAddr.sin_addr.s_addr = inet_addr(PEER_IP); + clnAddr.sin_port = htons(PEER_PORT); + ret = memset_s(g_buf, BUF_SIZE, 0, BUF_SIZE); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = strcpy_s(g_buf, BUF_SIZE, MSG); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = sendto(sfd, g_buf, strlen(MSG), 0, reinterpret_cast(&clnAddr), + static_cast(sizeof(clnAddr))); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret); + + /* recv */ + ret = memset_s(g_buf, BUF_SIZE, 0, BUF_SIZE); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = recvfrom(sfd, g_buf, sizeof(g_buf), 0, reinterpret_cast(&clnAddr), + &clnAddrLen); + ICUNIT_ASSERT_EQUAL(ret, strlen(MSG), ret); + + /* sendmsg */ + clnAddr.sin_family = AF_INET; + clnAddr.sin_addr.s_addr = inet_addr(PEER_IP); + clnAddr.sin_port = htons(PEER_PORT); + ret = memset_s(g_buf, BUF_SIZE, 0, BUF_SIZE); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = strcpy_s(g_buf, BUF_SIZE, MSG); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + msg.msg_name = &clnAddr; + msg.msg_namelen = sizeof(clnAddr); + msg.msg_iov = iov; + msg.msg_iovlen = 2; + iov[0].iov_base = g_buf; + iov[0].iov_len = strlen(MSG); + iov[1].iov_base = g_buf; + iov[1].iov_len = strlen(MSG); + ret = sendmsg(sfd, &msg, 0); + ICUNIT_ASSERT_EQUAL(ret, 2 * strlen(MSG), ret); + + /* recvmsg */ + ret = memset_s(g_buf, BUF_SIZE, 0, BUF_SIZE); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = memset_s(&msg, sizeof(msg), 0, sizeof(msg)); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + msg.msg_name = &clnAddr; + msg.msg_namelen = sizeof(clnAddr); + msg.msg_iov = iov; + msg.msg_iovlen = 1; + iov[0].iov_base = g_buf; + iov[0].iov_len = sizeof(g_buf); + ret = recvmsg(sfd, &msg, 0); + ICUNIT_ASSERT_EQUAL(ret, 2 * strlen(MSG), ret); + + /* close socket */ + ret = close(sfd); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret); + return 0; +} + +void NetSocketTest002(void) +{ + TEST_ADD_CASE(__FUNCTION__, UdpTest, TEST_POSIX, TEST_UDP, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_003.cpp b/src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_003.cpp new file mode 100644 index 00000000..d180968f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_003.cpp @@ -0,0 +1,323 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define localhost "127.0.0.1" +#define STACK_IP localhost +#define STACK_PORT 2277 +#define PEER_PORT STACK_PORT +#define PEER_IP localhost +#define BUF_SIZE (1024 * 8) +#define SRV_MSG "Hi, I am TCP server" +#define CLI_MSG "Hi, I am TCP client" + +static pthread_barrier_t gBarrier; +#define Wait() pthread_barrier_wait(&gBarrier) + +static int SampleTcpServer() +{ + static char gBuf[BUF_SIZE + 1] = { 0 }; + int sfd = -1, lsfd = -1; + struct sockaddr_in srvAddr = { 0 }; + struct sockaddr_in clnAddr = { 0 }; + socklen_t clnAddrLen = sizeof(clnAddr); + struct msghdr msg = { 0 }; + struct iovec iov[2] = { }; + int ret = 0, i = 0; + + /* tcp server */ + lsfd = socket(AF_INET, SOCK_STREAM, 0); + LogPrintln("create listen socket inet stream: %d", lsfd); + ICUNIT_ASSERT_NOT_EQUAL(lsfd, -1, lsfd); + + srvAddr.sin_family = AF_INET; + srvAddr.sin_addr.s_addr = inet_addr(STACK_IP); + srvAddr.sin_port = htons(STACK_PORT); + ret = bind(lsfd, reinterpret_cast(&srvAddr), sizeof(srvAddr)); + LogPrintln("bind socket %d to %s:%d: %d", lsfd, inet_ntoa(srvAddr.sin_addr), ntohs(srvAddr.sin_port), ret); + ICUNIT_ASSERT_EQUAL(ret, 0, Wait() + ret); + + ret = listen(lsfd, 0); + LogPrintln("listen socket %d: %d", lsfd, ret); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + Wait(); + + sfd = accept(lsfd, reinterpret_cast(&clnAddr), &clnAddrLen); + LogPrintln("accept socket %d: %d <%s:%d>", lsfd, sfd, inet_ntoa(clnAddr.sin_addr), ntohs(clnAddr.sin_port)); + ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, sfd); + + /* send */ + ret = memset_s(gBuf, BUF_SIZE + 1, 0, BUF_SIZE + 1); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + gBuf[BUF_SIZE - 1] = '\0'; + ret = strcpy_s(gBuf, BUF_SIZE - 1, SRV_MSG); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + gBuf[BUF_SIZE - 1] = '\0'; + ret = send(sfd, gBuf, strlen(SRV_MSG), 0); + LogPrintln("send on socket %d: %d", sfd, ret); + ICUNIT_ASSERT_EQUAL(ret, strlen(SRV_MSG), ret); + + /* recv */ + ret = memset_s(gBuf, BUF_SIZE + 1, 0, BUF_SIZE + 1); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + gBuf[BUF_SIZE - 1] = '\0'; + ret = recv(sfd, gBuf, sizeof(gBuf), 0); + LogPrintln("recv on socket %d: %d", sfd, ret); + ICUNIT_ASSERT_EQUAL(ret, strlen(CLI_MSG), ret); + + Wait(); + + /* sendmsg */ + clnAddr.sin_family = AF_INET; + clnAddr.sin_addr.s_addr = inet_addr(PEER_IP); + clnAddr.sin_port = htons(PEER_PORT); + ret = memset_s(gBuf, BUF_SIZE + 1, 0, BUF_SIZE + 1); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + gBuf[BUF_SIZE - 1] = '\0'; + ret = strcpy_s(gBuf, BUF_SIZE - 1, SRV_MSG); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + gBuf[BUF_SIZE - 1] = '\0'; + msg.msg_name = &clnAddr; + msg.msg_namelen = sizeof(clnAddr); + msg.msg_iov = iov; + msg.msg_iovlen = 2; + iov[0].iov_base = gBuf; + iov[0].iov_len = strlen(SRV_MSG); + iov[1].iov_base = gBuf; + iov[1].iov_len = strlen(SRV_MSG); + ret = sendmsg(sfd, &msg, 0); + LogPrintln("sendmsg on socket %d: %d", sfd, ret); + ICUNIT_ASSERT_EQUAL(ret, 2 * strlen(SRV_MSG), ret); + + Wait(); + + /* recvmsg */ + ret = memset_s(gBuf, BUF_SIZE + 1, 0, BUF_SIZE + 1); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + gBuf[BUF_SIZE - 1] = '\0'; + ret = memset_s(&msg, sizeof(msg), 0, sizeof(msg)); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + msg.msg_name = &clnAddr; + msg.msg_namelen = sizeof(clnAddr); + msg.msg_iov = iov; + msg.msg_iovlen = 1; + iov[0].iov_base = gBuf; + iov[0].iov_len = sizeof(gBuf); + ret = recvmsg(sfd, &msg, 0); + LogPrintln("recvmsg on socket %d: %d", sfd, ret); + ICUNIT_ASSERT_EQUAL(ret, 2 * strlen(CLI_MSG), ret); + + ret = shutdown(sfd, SHUT_RDWR); + LogPrintln("shutdown socket %d: %d", sfd, ret); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + close(sfd); + close(lsfd); + return 0; +} + +static int SampleTcpClient() +{ + static char gBuf[BUF_SIZE + 1] = { 0 }; + int sfd = -1; + struct sockaddr_in srvAddr = { 0 }; + struct sockaddr_in clnAddr = { 0 }; + socklen_t clnAddrLen = sizeof(clnAddr); + int ret = 0, i = 0; + struct msghdr msg = { 0 }; + struct iovec iov[2] = { }; + struct sockaddr addr; + socklen_t addrLen = sizeof(addr); + + /* tcp client connection */ + sfd = socket(AF_INET, SOCK_STREAM, 0); + LogPrintln("create client socket inet stream: %d", sfd); + ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, sfd); + + Wait(); + + srvAddr.sin_family = AF_INET; + srvAddr.sin_addr.s_addr = inet_addr(PEER_IP); + srvAddr.sin_port = htons(PEER_PORT); + ret = connect(sfd, reinterpret_cast(&srvAddr), sizeof(srvAddr)); + LogPrintln("connect socket %d to %s:%d: %d", sfd, inet_ntoa(srvAddr.sin_addr), ntohs(srvAddr.sin_port), ret); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + /* test getpeername */ + ret = getpeername(sfd, &addr, &addrLen); + LogPrintln("getpeername %d %s:%d: %d", sfd, inet_ntoa((reinterpret_cast(&addr))->sin_addr), + ntohs((reinterpret_cast(&addr))->sin_port), ret); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(addrLen, sizeof(struct sockaddr_in), addrLen); + ICUNIT_ASSERT_EQUAL((reinterpret_cast(&addr))->sin_addr.s_addr, + inet_addr(PEER_IP), (static_cast(&addr))->sin_addr.s_addr); + + /* test getsockname */ + ret = getsockname(sfd, &addr, &addrLen); + LogPrintln("getsockname %d %s:%d: %d", sfd, inet_ntoa((reinterpret_cast(&addr))->sin_addr), + ntohs((reinterpret_cast(&addr))->sin_port), ret); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(addrLen, sizeof(struct sockaddr_in), addrLen); + ICUNIT_ASSERT_EQUAL((reinterpret_cast(&addr))->sin_addr.s_addr, + inet_addr(STACK_IP), (static_cast(&addr))->sin_addr.s_addr); + + /* send */ + ret = memset_s(gBuf, BUF_SIZE + 1, 0, BUF_SIZE + 1); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + gBuf[BUF_SIZE - 1] = '\0'; + ret = strcpy_s(gBuf, BUF_SIZE - 1, CLI_MSG); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + gBuf[BUF_SIZE - 1] = '\0'; + ret = send(sfd, gBuf, strlen(CLI_MSG), 0); + LogPrintln("send on socket %d: %d", sfd, ret); + ICUNIT_ASSERT_EQUAL(ret, strlen(CLI_MSG), ret); + + /* recv */ + ret = memset_s(gBuf, BUF_SIZE + 1, 0, BUF_SIZE + 1); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + gBuf[BUF_SIZE - 1] = '\0'; + ret = recv(sfd, gBuf, sizeof(gBuf), 0); + LogPrintln("recv on socket %d: %d", sfd, ret); + ICUNIT_ASSERT_EQUAL(ret, strlen(SRV_MSG), ret); + + Wait(); + + /* sendmsg */ + clnAddr.sin_family = AF_INET; + clnAddr.sin_addr.s_addr = inet_addr(PEER_IP); + clnAddr.sin_port = htons(PEER_PORT); + ret = memset_s(gBuf, BUF_SIZE + 1, 0, BUF_SIZE + 1); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + gBuf[BUF_SIZE - 1] = '\0'; + ret = strcpy_s(gBuf, BUF_SIZE - 1, CLI_MSG); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + gBuf[BUF_SIZE - 1] = '\0'; + msg.msg_name = &clnAddr; + msg.msg_namelen = sizeof(clnAddr); + msg.msg_iov = iov; + msg.msg_iovlen = 2; + iov[0].iov_base = gBuf; + iov[0].iov_len = strlen(CLI_MSG); + iov[1].iov_base = gBuf; + iov[1].iov_len = strlen(CLI_MSG); + ret = sendmsg(sfd, &msg, 0); + LogPrintln("sendmsg on socket %d: %d", sfd, ret); + ICUNIT_ASSERT_EQUAL(ret, 2 * strlen(CLI_MSG), ret); + + Wait(); + + /* recvmsg */ + ret = memset_s(gBuf, BUF_SIZE + 1, 0, BUF_SIZE + 1); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + gBuf[BUF_SIZE - 1] = '\0'; + ret = memset_s(&msg, sizeof(msg), 0, sizeof(msg)); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + msg.msg_name = &clnAddr; + msg.msg_namelen = sizeof(clnAddr); + msg.msg_iov = iov; + msg.msg_iovlen = 1; + iov[0].iov_base = gBuf; + iov[0].iov_len = sizeof(gBuf); + ret = recvmsg(sfd, &msg, 0); + LogPrintln("recvmsg on socket %d: %d", sfd, ret); + ICUNIT_ASSERT_EQUAL(ret, 2 * strlen(SRV_MSG), ret); + + ret = shutdown(sfd, SHUT_RDWR); + LogPrintln("shutdown socket %d: %d", sfd, ret); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + close(sfd); + return 0; +} + +static void* TcpServerRoutine(void *p) +{ + int ret = SampleTcpServer(); + return reinterpret_cast(ret); +} + +static void* TcpClientRoutine(void *p) +{ + int ret = SampleTcpClient(); + return reinterpret_cast(ret); +} + +static int TcpTest() +{ + int ret; + void *sret = NULL; + void *cret = NULL; + pthread_t srv, cli; + pthread_attr_t attr; + + ret = pthread_barrier_init(&gBarrier, 0, 2); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&srv, &attr, TcpServerRoutine, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&cli, &attr, TcpClientRoutine, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(cli, &cret); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LogPrintln("client finish"); + + ret = pthread_join(srv, &sret); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LogPrintln("server finish"); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_barrier_destroy(&gBarrier); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return static_cast(reinterpret_cast(sret)) + static_cast(reinterpret_cast(cret)); +} + +void NetSocketTest003(void) +{ + TEST_ADD_CASE(__FUNCTION__, TcpTest, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_004.cpp b/src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_004.cpp new file mode 100644 index 00000000..81e2ac37 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_004.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +static int SockOptTest(void) +{ + int ret, error, flag; + struct timeval timeout; + socklen_t len; + + int fd = socket(AF_INET, SOCK_STREAM, 0); + ICUNIT_ASSERT_NOT_EQUAL(fd, -1, fd); + + error = -1; + len = sizeof(error); + ret = getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len); + LogPrintln("getsockopt(%d, SOL_SOCKET, SO_ERROR, &error, &len)=%d, error=%d, len=%d, errno=%d", fd, ret, error, len, errno); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(error, 0, error); + + len = sizeof(timeout); + ret = getsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, &len); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + timeout.tv_sec = 1000; + len = sizeof(timeout); + ret = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, len); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = memset_s(&timeout, len, 0, len); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = getsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, &len); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(timeout.tv_sec, 1000, ret); + + error = -1; + len = sizeof(error); + ret = getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len); + LogPrintln("getsockopt(%d, SOL_SOCKET, SO_ERROR, &error, &len)=%d, error=%d, len=%d, errno=%d", fd, ret, error, len, errno); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(error, 0, error); + + flag=1; + ret = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag)); + LogPrintln("setsockopt(TCP_NODELAY) ret=%d", ret); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = close(fd); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return ICUNIT_SUCCESS; +} + +void NetSocketTest004(void) +{ + TEST_ADD_CASE(__FUNCTION__, SockOptTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_005.cpp b/src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_005.cpp new file mode 100644 index 00000000..3cf7f895 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_005.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +static int ByteOrderTest(void) +{ +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + uint32_t hl = ntohl(0x12345678); + ICUNIT_ASSERT_EQUAL(hl, 0x78563412, hl); + + uint32_t nl = htonl(0x12345678); + ICUNIT_ASSERT_EQUAL(nl, 0x78563412, nl); + + uint16_t hs = ntohs(0x1234); + ICUNIT_ASSERT_EQUAL(hs, 0x3412, hs); + + uint16_t ns = htons(0x1234); + ICUNIT_ASSERT_EQUAL(ns, 0x3412, ns); +#else + uint32_t hl = ntohl(0x12345678); + ICUNIT_ASSERT_EQUAL(hl, 0x12345678, hl); + + uint32_t nl = htonl(0x12345678); + ICUNIT_ASSERT_EQUAL(nl, 0x12345678, nl); + + uint16_t hs = ntohs(0x1234); + ICUNIT_ASSERT_EQUAL(hs, 0x1234, hs); + + uint16_t ns = htons(0x1234); + ICUNIT_ASSERT_EQUAL(ns, 0x1234, ns); +#endif + return ICUNIT_SUCCESS; +} + +void NetSocketTest005(void) +{ + TEST_ADD_CASE(__FUNCTION__, ByteOrderTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_006.cpp b/src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_006.cpp new file mode 100644 index 00000000..4c348502 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_006.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +static int InetTest(void) +{ + struct in_addr in; + int ret = inet_pton(AF_INET, "300.10.10.10", &in); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = inet_pton(AF_INET, "10.11.12.13", &in); + ICUNIT_ASSERT_EQUAL(ret, 1, ret); +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + ICUNIT_ASSERT_EQUAL(in.s_addr, 0x0d0c0b0a, in.s_addr); +#else + ICUNIT_ASSERT_EQUAL(in.s_addr, 0x0a0b0c0d, in.s_addr); +#endif + + // host order + in_addr_t lna = inet_lnaof(in); + ICUNIT_ASSERT_EQUAL(lna, 0x000b0c0d, lna); + + // host order + in_addr_t net = inet_netof(in); + ICUNIT_ASSERT_EQUAL(net, 0x0000000a, net); + + in = inet_makeaddr(net, lna); +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + ICUNIT_ASSERT_EQUAL(in.s_addr, 0x0d0c0b0a, in.s_addr); +#else + ICUNIT_ASSERT_EQUAL(in.s_addr, 0x0a0b0c0d, in.s_addr); +#endif + + net = inet_network("300.10.10.10"); + ICUNIT_ASSERT_EQUAL(net, -1, net); + + // host order + net = inet_network("10.11.12.13"); + ICUNIT_ASSERT_EQUAL(net, 0x0a0b0c0d, net); + + const char *p = inet_ntoa(in); + ICUNIT_ASSERT_EQUAL(strcmp(p, "10.11.12.13"), 0, -1); + + char buf[32]; + p = inet_ntop(AF_INET, &in, buf, sizeof(buf)); + ICUNIT_ASSERT_EQUAL(p, buf, -1); + ICUNIT_ASSERT_EQUAL(strcmp(p, "10.11.12.13"), 0, -1); + + return ICUNIT_SUCCESS; +} + +void NetSocketTest006(void) +{ + TEST_ADD_CASE(__FUNCTION__, InetTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_007.cpp b/src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_007.cpp new file mode 100644 index 00000000..1ceece68 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_007.cpp @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +#define SRV_MSG "Hi, I am TCP server" +#define INVALID_USER_ADDR 0X1200000 +#define INVALID_KERNEL_ADDR 0x48000000 + +static int TcpTest() +{ + int ret; + int lsfd = -1; + struct msghdr msg = { 0 }; + + lsfd = socket(AF_INET, SOCK_STREAM, 0); + ICUNIT_ASSERT_NOT_EQUAL(lsfd, -1, lsfd); + + ret = bind(lsfd, reinterpret_cast(INVALID_USER_ADDR), sizeof(struct sockaddr_in)); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + + ret = bind(lsfd, reinterpret_cast(INVALID_KERNEL_ADDR), sizeof(struct sockaddr_in)); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + + ret = connect(lsfd, reinterpret_cast(INVALID_USER_ADDR), sizeof(struct sockaddr_in)); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + + ret = connect(lsfd, reinterpret_cast(INVALID_KERNEL_ADDR), sizeof(struct sockaddr_in)); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + + ret = accept(lsfd, reinterpret_cast(INVALID_USER_ADDR), + reinterpret_cast(INVALID_USER_ADDR)); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + + ret = accept(lsfd, reinterpret_cast(INVALID_KERNEL_ADDR), + reinterpret_cast(INVALID_KERNEL_ADDR)); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + + ret = getsockname(lsfd, reinterpret_cast(INVALID_USER_ADDR), + reinterpret_cast(INVALID_USER_ADDR)); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + + ret = getsockname(lsfd, reinterpret_cast(INVALID_KERNEL_ADDR), + reinterpret_cast(INVALID_KERNEL_ADDR)); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + + ret = getpeername(lsfd, reinterpret_cast(INVALID_USER_ADDR), + reinterpret_cast(INVALID_USER_ADDR)); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + + ret = getpeername(lsfd, reinterpret_cast(INVALID_KERNEL_ADDR), + reinterpret_cast(INVALID_KERNEL_ADDR)); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + + ret = send(lsfd, reinterpret_cast(INVALID_USER_ADDR), strlen(SRV_MSG), 0); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + + ret = send(lsfd, reinterpret_cast(INVALID_KERNEL_ADDR), strlen(SRV_MSG), 0); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + + ret = sendto(lsfd, reinterpret_cast(INVALID_USER_ADDR), strlen(SRV_MSG), 0, + reinterpret_cast(INVALID_USER_ADDR), static_cast(sizeof(struct sockaddr_in))); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + + ret = sendto(lsfd, reinterpret_cast(INVALID_KERNEL_ADDR), strlen(SRV_MSG), 0, + reinterpret_cast(INVALID_KERNEL_ADDR), static_cast(sizeof(struct sockaddr_in))); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + + ret = recv(lsfd, reinterpret_cast(INVALID_USER_ADDR), sizeof(SRV_MSG), 0); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + + ret = recv(lsfd, reinterpret_cast(INVALID_KERNEL_ADDR), sizeof(SRV_MSG), 0); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + + ret = recvfrom(lsfd, reinterpret_cast(INVALID_USER_ADDR), sizeof(SRV_MSG), 0, + reinterpret_cast(INVALID_USER_ADDR), reinterpret_cast(INVALID_USER_ADDR)); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + + ret = recvfrom(lsfd, reinterpret_cast(INVALID_KERNEL_ADDR), sizeof(SRV_MSG), 0, + reinterpret_cast(INVALID_KERNEL_ADDR), reinterpret_cast(INVALID_KERNEL_ADDR)); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + + ret = setsockopt(lsfd, SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast(INVALID_USER_ADDR), + static_cast(sizeof(struct timeval))); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + + ret = setsockopt(lsfd, SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast(INVALID_KERNEL_ADDR), + static_cast(sizeof(struct timeval))); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + + ret = getsockopt(lsfd, SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast(INVALID_USER_ADDR), + reinterpret_cast(sizeof(struct timeval))); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + + ret = getsockopt(lsfd, SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast(INVALID_KERNEL_ADDR), + reinterpret_cast(sizeof(struct timeval))); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + + ret = sendmsg(lsfd, reinterpret_cast(INVALID_USER_ADDR), 0); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + + ret = sendmsg(lsfd, reinterpret_cast(INVALID_KERNEL_ADDR), 0); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + + msg.msg_name = reinterpret_cast(INVALID_USER_ADDR); + msg.msg_namelen = sizeof(struct sockaddr_in); + msg.msg_iov = reinterpret_cast(INVALID_KERNEL_ADDR); + msg.msg_iovlen = 2; + ret = recvmsg(lsfd, static_cast(&msg), 0); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + + ret = recvmsg(lsfd, static_cast(&msg), 0); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + +#ifdef TEST_BIG_MEM + const int bufSiz = 0x1400000; // 20M + void *buf = malloc(bufSiz); + if (!buf) { + printf("malloc 20M fail\n"); + } else { + printf("malloc 20M success\n"); + ret = memset_s(buf, bufSiz, 0, bufSiz); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ret = send(lsfd, buf, bufSiz, 0); + printf("send ret = %d, errno :%d\n", ret, errno); + ICUNIT_GOTO_EQUAL(ret, -1, ret, EXIT); + } + +EXIT: + if (buf != NULL) { + free(buf); + } +#endif + close(lsfd); + return 0; +} + +void NetSocketTest007(void) +{ + TEST_ADD_CASE(__FUNCTION__, TcpTest, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_008.cpp b/src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_008.cpp new file mode 100644 index 00000000..49e642b5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_008.cpp @@ -0,0 +1,282 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include +#include +#include +#include +#include + +#define SERVER_PORT 6666 +#define INVALID_SOCKET -1 +#define CLIENT_NUM 25 +#define BACKLOG CLIENT_NUM + +static int gFds[FD_SETSIZE]; +static int gBye; + +static void InitFds() +{ + for (int i = 0; i < FD_SETSIZE; ++i) { + gFds[i] = INVALID_SOCKET; + } +} + +static void GetReadfds(fd_set *fds, int *nfd) +{ + for (int i = 0; i < FD_SETSIZE; i++) { + if (gFds[i] == INVALID_SOCKET) { + continue; + } + FD_SET(gFds[i], fds); + if (*nfd < gFds[i]) { + *nfd = gFds[i]; + } + } +} + +static int AddFd(int fd) +{ + for (int i = 0; i < FD_SETSIZE; ++i) { + if (gFds[i] == INVALID_SOCKET) { + gFds[i] = fd; + return 0; + } + } + return -1; +} + +static void DelFd(int fd) +{ + for (int i = 0; i < FD_SETSIZE; ++i) { + if (gFds[i] == fd) { + gFds[i] = INVALID_SOCKET; + } + } + (void)close(fd); +} + +static int CloseAllFd(void) +{ + for (int i = 0; i < FD_SETSIZE; ++i) { + if (gFds[i] != INVALID_SOCKET) { + (void)close(gFds[i]); + gFds[i] = INVALID_SOCKET; + } + } + return 0; +} + +static int HandleRecv(int fd) +{ + char buf[256]; + int ret = recv(fd, buf, sizeof(buf)-1, 0); + if (ret < 0) { + LogPrintln("[%d]Error: %s", fd, strerror(errno)); + DelFd(fd); + } else if (ret == 0) { + LogPrintln("[%d]Closed", fd); + DelFd(fd); + } else { + buf[ret] = 0; + LogPrintln("[%d]Received: %s", fd, buf); + if (strstr(buf, "Bye") != NULL) { + DelFd(fd); + gBye++; + } + } + return -(ret < 0); +} + +static int HandleAccept(int lsfd) +{ + struct sockaddr_in sa; + int saLen = sizeof(sa); + int fd = accept(lsfd, reinterpret_cast(&sa), reinterpret_cast(&saLen)); + if (fd == INVALID_SOCKET) { + perror("accept"); + return -1; + } + + if (AddFd(fd) == -1) { + LogPrintln("Too many clients, refuse %s:%d", inet_ntoa(sa.sin_addr), ntohs(sa.sin_port)); + close(fd); + return -1; + } + LogPrintln("New client %d: %s:%d", fd, inet_ntoa(sa.sin_addr), ntohs(sa.sin_port)); + return 0; +} + +static int HandleReadfds(fd_set *fds, int lsfd) +{ + int ret = 0; + for (int i = 0; i < FD_SETSIZE; ++i) { + if (gFds[i] == INVALID_SOCKET || !FD_ISSET(gFds[i], fds)) { + continue; + } + if (gFds[i] == lsfd) { + ret += HandleAccept(lsfd); + } else { + ret += HandleRecv(gFds[i]); + } + } + return ret; +} + +static void *ClientsThread(void *param) +{ + int fd; + int thrNo = (int)(intptr_t)param; + + LogPrintln("<%d>socket client thread started", thrNo); + fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (fd == INVALID_SOCKET) { + perror("socket"); + return NULL; + } + + struct sockaddr_in sa; + sa.sin_family = AF_INET; + sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + sa.sin_port = htons(SERVER_PORT); + if (connect(fd, reinterpret_cast(&sa), sizeof(sa)) == -1) { + perror("connect"); + return NULL; + } + + LogPrintln("[%d]<%d>connected to %s:%d successful", fd, thrNo, inet_ntoa(sa.sin_addr), SERVER_PORT); + + const char *msg[] = { + "hello, ", + "ohos, ", + "my name is net_socket_test_008, ", + "see u next time, ", + "Bye!" + }; + + for (int i = 0; i < sizeof(msg) / sizeof(msg[0]); ++i) { + if (send(fd, msg[i], strlen(msg[i]), 0) < 0) { + LogPrintln("[%d]<%d>send msg [%s] fail", fd, thrNo, msg[i]); + } + } + + (void)shutdown(fd, SHUT_RDWR); + (void)close(fd); + return param; +} + +static int StartClients(pthread_t *cli, int cliNum) +{ + int ret; + pthread_attr_t attr; + + for (int i = 0; i < cliNum; ++i) { + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&cli[i], &attr, ClientsThread, (void *)(intptr_t)i); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + } + return 0; +} + +static int SelectTest(void) +{ + struct sockaddr_in sa = {0}; + int lsfd; + int ret; + + lsfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + ICUNIT_ASSERT_NOT_EQUAL(lsfd, -1, errno); + + sa.sin_family = AF_INET; + sa.sin_addr.s_addr = htonl(INADDR_ANY); + sa.sin_port = htons(SERVER_PORT); + ret = bind(lsfd, reinterpret_cast(&sa), sizeof(sa)); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, errno + CloseAllFd()); + + ret = listen(lsfd, BACKLOG); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, errno + CloseAllFd()); + + InitFds(); + AddFd(lsfd); + LogPrintln("[%d]Waiting for client to connect on port %d", lsfd, SERVER_PORT); + + pthread_t clients[CLIENT_NUM]; + + ret = StartClients(clients, CLIENT_NUM); + ICUNIT_ASSERT_EQUAL(ret, 0, ret + CloseAllFd()); + + for ( ; ; ) { + int nfd; + fd_set readfds; + struct timeval timeout; + + timeout.tv_sec = 3; + timeout.tv_usec = 0; + + nfd = 0; + FD_ZERO(&readfds); + + GetReadfds(&readfds, &nfd); + + ret = select(nfd + 1, &readfds, NULL, NULL, &timeout); + LogPrintln("select %d", ret); + if (ret == -1) { + perror("select"); + break; // error occurred + } else if (ret == 0) { + break; // timed out + } + + if (HandleReadfds(&readfds, lsfd) < 0) { + break; + } + } + + for (int i = 0; i < CLIENT_NUM; ++i) { + ret = pthread_join(clients[i], NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret + CloseAllFd()); + } + + ICUNIT_ASSERT_EQUAL(gBye, CLIENT_NUM, gBye + CloseAllFd()); + (void)CloseAllFd(); + return ICUNIT_SUCCESS; +} + +void NetSocketTest008(void) +{ + TEST_ADD_CASE(__FUNCTION__, SelectTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_009.cpp b/src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_009.cpp new file mode 100644 index 00000000..9d76513c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_009.cpp @@ -0,0 +1,278 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include +#include +#include +#include +#include + +#define SERVER_PORT 8888 +#define INVALID_SOCKET -1 +#define CLIENT_NUM 25 +#define BACKLOG CLIENT_NUM + +static int gFds[FD_SETSIZE]; +static int gBye; + +static void InitFds() +{ + for (int i = 0; i < FD_SETSIZE; ++i) { + gFds[i] = INVALID_SOCKET; + } +} + +static void GetReadfds(struct pollfd *fds, int *nfd) +{ + for (int i = 0; i < FD_SETSIZE; i++) { + if (gFds[i] == INVALID_SOCKET) { + continue; + } + fds[*nfd].fd = gFds[i]; + fds[*nfd].events = POLLIN; + (*nfd)++; + } +} + +static int AddFd(int fd) +{ + for (int i = 0; i < FD_SETSIZE; ++i) { + if (gFds[i] == INVALID_SOCKET) { + gFds[i] = fd; + return 0; + } + } + return -1; +} + +static void DelFd(int fd) +{ + for (int i = 0; i < FD_SETSIZE; ++i) { + if (gFds[i] == fd) { + gFds[i] = INVALID_SOCKET; + } + } + (void)close(fd); +} + +static int CloseAllFd(void) +{ + for (int i = 0; i < FD_SETSIZE; ++i) { + if (gFds[i] != INVALID_SOCKET) { + (void)close(gFds[i]); + gFds[i] = INVALID_SOCKET; + } + } + return 0; +} + +static int HandleRecv(int fd) +{ + char buf[256]; + int ret = recv(fd, buf, sizeof(buf)-1, 0); + if (ret < 0) { + LogPrintln("[%d]Error: %s", fd, strerror(errno)); + DelFd(fd); + } else if (ret == 0) { + LogPrintln("[%d]Closed", fd); + DelFd(fd); + } else { + buf[ret] = 0; + LogPrintln("[%d]Received: %s", fd, buf); + if (strstr(buf, "Bye") != NULL) { + DelFd(fd); + gBye++; + } + } + return -(ret < 0); +} + +static int HandleAccept(int lsfd) +{ + struct sockaddr_in sa; + int saLen = sizeof(sa); + int fd = accept(lsfd, reinterpret_cast(&sa), reinterpret_cast(&saLen)); + if (fd == INVALID_SOCKET) { + perror("accept"); + return -1; + } + + if (AddFd(fd) == -1) { + LogPrintln("Too many clients, refuse %s:%d", inet_ntoa(sa.sin_addr), ntohs(sa.sin_port)); + close(fd); + return -1; + } + LogPrintln("New client %d: %s:%d", fd, inet_ntoa(sa.sin_addr), ntohs(sa.sin_port)); + return 0; +} + +static int HandleReadfds(struct pollfd *fds, int nfds, int lsfd) +{ + int ret = 0; + for (int i = 0; i < nfds; ++i) { + if (fds[i].revents == 0) { + continue; + } + LogPrintln("[%d]revents: %04hx", fds[i].fd, fds[i].revents); + if (fds[i].fd == lsfd) { + ret += HandleAccept(lsfd); + } else { + ret += HandleRecv(fds[i].fd); + } + } + return ret; +} + +static void *ClientsThread(void *param) +{ + int fd; + int thrNo = (int)(intptr_t)param; + + LogPrintln("<%d>socket client thread started", thrNo); + fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (fd == INVALID_SOCKET) { + perror("socket"); + return NULL; + } + + struct sockaddr_in sa; + sa.sin_family = AF_INET; + sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + sa.sin_port = htons(SERVER_PORT); + if (connect(fd, reinterpret_cast(&sa), sizeof(sa)) == -1) { + perror("connect"); + return NULL; + } + + LogPrintln("[%d]<%d>connected to %s:%d successful", fd, thrNo, inet_ntoa(sa.sin_addr), SERVER_PORT); + + const char *msg[] = { + "hello, ", + "ohos, ", + "my name is net_socket_test_009, ", + "see u next time, ", + "Bye!" + }; + + for (int i = 0; i < sizeof(msg) / sizeof(msg[0]); ++i) { + if (send(fd, msg[i], strlen(msg[i]), 0) < 0) { + LogPrintln("[%d]<%d>send msg [%s] fail", fd, thrNo, msg[i]); + } + } + + (void)shutdown(fd, SHUT_RDWR); + (void)close(fd); + return param; +} + +static int StartClients(pthread_t *cli, int cliNum) +{ + int ret; + pthread_attr_t attr; + + for (int i = 0; i < cliNum; ++i) { + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&cli[i], &attr, ClientsThread, (void *)(intptr_t)i); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + } + return 0; +} + +static int PollTest(void) +{ + struct sockaddr_in sa = {0}; + int lsfd; + int ret; + + lsfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + ICUNIT_ASSERT_NOT_EQUAL(lsfd, -1, errno); + + sa.sin_family = AF_INET; + sa.sin_addr.s_addr = htonl(INADDR_ANY); + sa.sin_port = htons(SERVER_PORT); + ret = bind(lsfd, reinterpret_cast(&sa), sizeof(sa)); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, errno + CloseAllFd()); + + ret = listen(lsfd, BACKLOG); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, errno + CloseAllFd()); + + InitFds(); + AddFd(lsfd); + LogPrintln("[%d]Waiting for client to connect on port %d", lsfd, SERVER_PORT); + + pthread_t clients[CLIENT_NUM]; + + ret = StartClients(clients, CLIENT_NUM); + ICUNIT_ASSERT_EQUAL(ret, 0, ret + CloseAllFd()); + + for ( ; ; ) { + int nfd; + struct pollfd readfds[FD_SETSIZE]; + int timeoutMs; + + timeoutMs = 3000; + nfd = 0; + GetReadfds(readfds, &nfd); + + ret = poll(readfds, nfd, timeoutMs); + LogPrintln("poll %d", ret); + if (ret == -1) { + perror("poll"); + break; // error occurred + } else if (ret == 0) { + break; // timed out + } + + if (HandleReadfds(readfds, nfd, lsfd) < 0) { + break; + } + } + + for (int i = 0; i < CLIENT_NUM; ++i) { + ret = pthread_join(clients[i], NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret + CloseAllFd()); + } + + ICUNIT_ASSERT_EQUAL(gBye, CLIENT_NUM, gBye + CloseAllFd()); + (void)CloseAllFd(); + return ICUNIT_SUCCESS; +} + +void NetSocketTest009(void) +{ + TEST_ADD_CASE(__FUNCTION__, PollTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_010.cpp b/src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_010.cpp new file mode 100644 index 00000000..f4478be1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_010.cpp @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include +#include +#include +#include +#include +#include +#include + +static char gDefaultNetif[IFNAMSIZ] = "eth0"; + +static void InitIfreq(struct ifreq *ifr) +{ + *ifr = (struct ifreq){{0}}; + (void)strncpy_s(ifr->ifr_name, sizeof(ifr->ifr_name) - 1, gDefaultNetif, sizeof(ifr->ifr_name) - 1); + ifr->ifr_name[sizeof(ifr->ifr_name) - 1] = '\0'; +} + +static char *IfIndex2Name(int fd, unsigned index, char *name) +{ +#if SUPPORT_IF_INDEX_TO_NAME + return if_indextoname(index, name); +#else + struct ifreq ifr; + int ret; + + ifr.ifr_ifindex = index; + ret = ioctl(fd, SIOCGIFNAME, &ifr); + if (ret < 0) { + return NULL; + } + ret = strncpy_s(name, IF_NAMESIZE - 1, ifr.ifr_name, IF_NAMESIZE - 1); + if (ret < 0) { + return NULL; + } + name[IF_NAMESIZE - 1] = '\0'; + return name; +#endif +} + +static unsigned IfName2Index(int fd, const char *name) +{ +#if SUPPORT_IF_NAME_TO_INDEX + return if_nametoindex(name); +#else + struct ifreq ifr; + int ret; + + ret = strncpy_s(ifr.ifr_name, sizeof(ifr.ifr_name) - 1, name, sizeof(ifr.ifr_name) - 1); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0'; + ret = ioctl(fd, SIOCGIFINDEX, &ifr); + return ret < 0 ? 0 : ifr.ifr_ifindex; +#endif +} + +static int IoctlTestInternal(int sfd) +{ + struct ifreq ifr = {{0}}; + char ifName[IFNAMSIZ] = {0}, *p = NULL; + unsigned int loIndex = 0; + unsigned int lanIndex = 0; + int maxIndex = 256; + int ret; + + for (int i = 0; i < maxIndex; ++i) { + p = IfIndex2Name(sfd, i, ifName); + if (p) { + if (strcmp(p, "lo") == 0) { + loIndex = i; + } else { + lanIndex = i; + } + } + } + + LogPrintln("ifindex of lo: %u, ifindex of lan: %u", loIndex, lanIndex); + ICUNIT_ASSERT_NOT_EQUAL(loIndex, 0, errno); + ICUNIT_ASSERT_NOT_EQUAL(lanIndex, 0, errno); + + p = IfIndex2Name(sfd, loIndex, ifName); + LogPrintln("ifindex %u: %s", loIndex, p); + ICUNIT_ASSERT_NOT_EQUAL(p, NULL, errno); + + p = IfIndex2Name(sfd, lanIndex, ifName); + LogPrintln("ifindex %u: %s", lanIndex, p); + ICUNIT_ASSERT_NOT_EQUAL(p, NULL, errno); + + ret = strncpy_s(gDefaultNetif, sizeof(gDefaultNetif) - 1, p, sizeof(gDefaultNetif) - 1); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + gDefaultNetif[sizeof(gDefaultNetif) - 1] = '\0'; + + ret = static_cast(IfName2Index(sfd, p)); + LogPrintln("index of %s: %d", p, ret); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, errno); + + ifr.ifr_ifindex = lanIndex; + ret = ioctl(sfd, SIOCGIFNAME, &ifr); + ICUNIT_ASSERT_EQUAL(ret, 0, errno); + LogPrintln("name of ifindex %u: %s", lanIndex, ifr.ifr_name); + + InitIfreq(&ifr); + ret = ioctl(sfd, SIOCGIFINDEX, &ifr); + ICUNIT_ASSERT_EQUAL(ret, 0, errno); + LogPrintln("index of ifname %s: %d", ifr.ifr_name, ifr.ifr_ifindex); + + InitIfreq(&ifr); + ret = ioctl(sfd, SIOCGIFHWADDR, &ifr); + ICUNIT_ASSERT_EQUAL(ret, 0, errno); + LogPrintln("hwaddr: %02hhX:%02hhX:%02hhX:XX:XX:XX", ifr.ifr_hwaddr.sa_data[0], ifr.ifr_hwaddr.sa_data[1], ifr.ifr_hwaddr.sa_data[2]); + + InitIfreq(&ifr); + ret = ioctl(sfd, SIOCGIFFLAGS, &ifr); + ICUNIT_ASSERT_EQUAL(ret, 0, errno); + LogPrintln("FLAGS of ifname %s: %#x, IFF_PROMISC: %d", ifr.ifr_name, ifr.ifr_flags, !!(ifr.ifr_flags & IFF_PROMISC)); + + if (ifr.ifr_flags & IFF_PROMISC) { + ifr.ifr_flags &= ~(IFF_PROMISC); + } else { + ifr.ifr_flags |= IFF_PROMISC; + } + LogPrintln("SIOCSIFFLAGS FLAGS: %#x", ifr.ifr_flags); + ret = ioctl(sfd, SIOCSIFFLAGS, &ifr); + if (ret == -1) { + ICUNIT_ASSERT_EQUAL(errno, EPERM, errno); + } else { + ICUNIT_ASSERT_EQUAL(ret, 0, errno); + } + + InitIfreq(&ifr); + ret = ioctl(sfd, SIOCGIFFLAGS, &ifr); + ICUNIT_ASSERT_EQUAL(ret, 0, errno); + LogPrintln("FLAGS of ifname %s: %#x, IFF_PROMISC: %d", ifr.ifr_name, ifr.ifr_flags, !!(ifr.ifr_flags & IFF_PROMISC)); + + ret = fcntl(sfd, F_GETFL, 0); + ICUNIT_ASSERT_EQUAL(ret < 0, 0, errno); + + ret = fcntl(sfd, F_SETFL, ret | O_NONBLOCK); + ICUNIT_ASSERT_EQUAL(ret < 0, 0, errno); + + return ICUNIT_SUCCESS; +} + +static int IoctlTest(void) +{ + int sfd; + + sfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + LogPrintln("socket(PF_INET, SOCK_STREAM, IPPROTO_TCP): %d", sfd); + ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, errno); + + (void)IoctlTestInternal(sfd); + + (void)close(sfd); + return ICUNIT_SUCCESS; +} + +void NetSocketTest010(void) +{ + TEST_ADD_CASE(__FUNCTION__, IoctlTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_011.cpp b/src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_011.cpp new file mode 100644 index 00000000..0cceb863 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_011.cpp @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include +#include +#include +#include +#include + +#define SERVER_PORT 7777 +#define INVALID_SOCKET -1 +#define CLIENT_NUM 25 + +static int gFds[FD_SETSIZE]; +static int gBye; + +static void InitFds() +{ + for (int i = 0; i < FD_SETSIZE; ++i) { + gFds[i] = INVALID_SOCKET; + } +} + +static void GetReadfds(fd_set *fds, int *nfd) +{ + for (int i = 0; i < FD_SETSIZE; i++) { + if (gFds[i] == INVALID_SOCKET) { + continue; + } + FD_SET(gFds[i], fds); + if (*nfd < gFds[i]) { + *nfd = gFds[i]; + } + } +} + +static int AddFd(int fd) +{ + for (int i = 0; i < FD_SETSIZE; ++i) { + if (gFds[i] == INVALID_SOCKET) { + gFds[i] = fd; + return 0; + } + } + return -1; +} + +static void DelFd(int fd) +{ + for (int i = 0; i < FD_SETSIZE; ++i) { + if (gFds[i] == fd) { + gFds[i] = INVALID_SOCKET; + } + } + (void)close(fd); +} + +static int CloseAllFd(void) +{ + for (int i = 0; i < FD_SETSIZE; ++i) { + if (gFds[i] != INVALID_SOCKET) { + (void)close(gFds[i]); + gFds[i] = INVALID_SOCKET; + } + } + return 0; +} + +static int HandleRecv(int fd) +{ + char buf[128]; + int ret = recv(fd, buf, sizeof(buf)-1, 0); + if (ret < 0) { + LogPrintln("[%d]Error: %s", fd, strerror(errno)); + DelFd(fd); + } else if (ret == 0) { + LogPrintln("[%d]Closed", fd); + DelFd(fd); + } else { + buf[ret] = 0; + LogPrintln("[%d]Received: %s", fd, buf); + if (strstr(buf, "Bye") != NULL) { + gBye++; + } + } + return -(ret < 0); +} + +static int HandleReadfds(fd_set *fds, int lsfd) +{ + int ret = 0; + for (int i = 0; i < FD_SETSIZE; ++i) { + if (gFds[i] == INVALID_SOCKET || !FD_ISSET(gFds[i], fds)) { + continue; + } + ret += HandleRecv(gFds[i]); + } + return ret; +} + +static void *ClientsThread(void *param) +{ + int fd; + int thrNo = (int)(intptr_t)param; + + LogPrintln("<%d>socket client thread started", thrNo); + fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (fd == INVALID_SOCKET) { + perror("socket"); + return NULL; + } + + struct sockaddr_in sa; + sa.sin_family = AF_INET; + sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + sa.sin_port = htons(SERVER_PORT); + if (connect(fd, reinterpret_cast(&sa), sizeof(sa)) == -1) { + perror("connect"); + return NULL; + } + + LogPrintln("[%d]<%d>connected to udp://%s:%d successful", fd, thrNo, inet_ntoa(sa.sin_addr), SERVER_PORT); + + const char *msg[] = { + "ohos, ", + "hello, ", + "my name is net_socket_test_011, ", + "see u next time, ", + "Bye!", + }; + + for (int i = 0; i < sizeof(msg) / sizeof(msg[0]); ++i) { + if (send(fd, msg[i], strlen(msg[i]), 0) < 0) { + LogPrintln("[%d]<%d>send msg [%s] fail", fd, thrNo, msg[i]); + } + } + + (void)shutdown(fd, SHUT_RDWR); + (void)close(fd); + return param; +} + +static int StartClients(pthread_t *cli, int cliNum) +{ + int ret; + pthread_attr_t attr = {0}; + struct sched_param param = { 0 }; + int policy; + ret = pthread_getschedparam(pthread_self(), &policy, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, -ret); + + for (int i = 0; i < cliNum; ++i) { + ret = pthread_attr_init(&attr); + param.sched_priority = param.sched_priority + 1; + if (param.sched_priority > 31) { /* 31: prio */ + param.sched_priority = 31; /* 31: prio */ + } + pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + pthread_attr_setschedparam(&attr, ¶m); + + ret = pthread_create(&cli[i], &attr, ClientsThread, (void *)(intptr_t)i); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + } + return 0; +} + +static int UdpSelectTest(void) +{ + struct sockaddr_in sa = {0}; + int lsfd; + int ret; + + lsfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + ICUNIT_ASSERT_NOT_EQUAL(lsfd, -1, errno); + + sa.sin_family = AF_INET; + sa.sin_addr.s_addr = htonl(INADDR_ANY); + sa.sin_port = htons(SERVER_PORT); + ret = bind(lsfd, reinterpret_cast(&sa), sizeof(sa)); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, errno + CloseAllFd()); + + InitFds(); + AddFd(lsfd); + LogPrintln("[%d]Waiting for client to connect on UDP port %d", lsfd, SERVER_PORT); + + pthread_t clients[CLIENT_NUM]; + + ret = StartClients(clients, CLIENT_NUM); + ICUNIT_ASSERT_EQUAL(ret, 0, ret + CloseAllFd()); + + for ( ; ; ) { + int nfd; + fd_set readfds; + struct timeval timeout; + + timeout.tv_sec = 3; + timeout.tv_usec = 0; + + nfd = 0; + FD_ZERO(&readfds); + + GetReadfds(&readfds, &nfd); + + ret = select(nfd + 1, &readfds, NULL, NULL, &timeout); + LogPrintln("select %d", ret); + if (ret == -1) { + perror("select"); + break; // error occurred + } else if (ret == 0) { + break; // timed out + } + + if (HandleReadfds(&readfds, lsfd) < 0) { + break; + } + } + + for (int i = 0; i < CLIENT_NUM; ++i) { + ret = pthread_join(clients[i], NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret + CloseAllFd()); + } + + ICUNIT_ASSERT_EQUAL(gBye, CLIENT_NUM, gBye + CloseAllFd()); + (void)CloseAllFd(); + return ICUNIT_SUCCESS; +} + +void NetSocketTest011(void) +{ + TEST_ADD_CASE(__FUNCTION__, UdpSelectTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_012.cpp b/src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_012.cpp new file mode 100644 index 00000000..f2f0a034 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_012.cpp @@ -0,0 +1,451 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include +#include +#include +#include +#include +#include + +static struct iovec gIov[IOV_MAX + 1]; + +static int SocketNullTestInternal(int sfd) +{ + int ret; + struct sockaddr addr = {0}; + struct sockaddr *bad = reinterpret_cast(0xbad); + socklen_t addrlen = sizeof(addr); + socklen_t zero = 0; + struct msghdr message = {0}; + void *badUserAddr = reinterpret_cast(0x3effffff); + + /** + * accept + */ + ret = accept(sfd, NULL, NULL); + LogPrintln("accept: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + ret = accept(sfd, NULL, &addrlen); + LogPrintln("accept: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + ret = accept(sfd, bad, &zero); + LogPrintln("accept: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + ret = accept(sfd, &addr, NULL); + LogPrintln("accept: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + /** + * bind + */ + ret = bind(sfd, NULL, addrlen); + LogPrintln("bind: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + ret = bind(sfd, bad, 0); + LogPrintln("bind: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + /** + * getpeername + */ + ret = getpeername(sfd, NULL, NULL); + LogPrintln("getpeername: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + ret = getpeername(sfd, NULL, &addrlen); + LogPrintln("getpeername: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + ret = getpeername(sfd, &addr, NULL); + LogPrintln("getpeername: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + zero = 0; + ret = getpeername(sfd, bad, &zero); + LogPrintln("getpeername: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + ICUNIT_ASSERT_EQUAL(errno, ENOTCONN, errno); + + /** + * getsockname + */ + ret = getsockname(sfd, NULL, NULL); + LogPrintln("getsockname: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + ret = getsockname(sfd, NULL, &addrlen); + LogPrintln("getsockname: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + ret = getsockname(sfd, &addr, NULL); + LogPrintln("getsockname: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + zero = 0; + ret = getsockname(sfd, bad, &zero); + LogPrintln("getsockname: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL((ret == 0 || ret == -1), 1, errno); + + /** + * getsockopt + */ + ret = getsockopt(sfd, SOL_SOCKET, SO_RCVTIMEO, NULL, NULL); + LogPrintln("getsockopt: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + ret = getsockopt(sfd, SOL_SOCKET, SO_RCVTIMEO, NULL, &addrlen); + LogPrintln("getsockopt: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + ret = getsockopt(sfd, SOL_SOCKET, SO_RCVTIMEO, &addr, NULL); + LogPrintln("getsockopt: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + zero = 0; + ret = getsockopt(sfd, SOL_SOCKET, SO_RCVTIMEO, bad, &zero); + LogPrintln("getsockopt: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL((ret == 0 || ret == -1), 1, errno); + + /** + * setsockopt + */ + ret = setsockopt(sfd, SOL_SOCKET, SO_RCVTIMEO, NULL, addrlen); + LogPrintln("setsockopt: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + ret = setsockopt(sfd, SOL_SOCKET, SO_RCVTIMEO, bad, 0); + LogPrintln("setsockopt: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + ret = setsockopt(sfd, SOL_SOCKET, SO_RCVTIMEO, bad, addrlen); + LogPrintln("setsockopt: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + /** + * connect + */ + ret = connect(sfd, NULL, addrlen); + LogPrintln("connect: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + ret = connect(sfd, bad, 0); + LogPrintln("connect: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + ret = connect(sfd, bad, addrlen); + LogPrintln("connect: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + /** + * recv + */ + ret = recv(sfd, NULL, 1, MSG_DONTWAIT); + LogPrintln("recv: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + /** + * recvfrom + */ + ret = recvfrom(sfd, NULL, 1, MSG_DONTWAIT, NULL, NULL); + LogPrintln("recvfrom: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + ret = recvfrom(sfd, NULL, 1, MSG_DONTWAIT, NULL, &addrlen); + LogPrintln("recvfrom: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + ret = recvfrom(sfd, NULL, 1, MSG_DONTWAIT, &addr, NULL); + LogPrintln("recvfrom: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + zero = 0; + ret = recvfrom(sfd, NULL, 1, MSG_DONTWAIT, bad, &zero); + LogPrintln("recvfrom: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + /** + * recvmsg + */ + ret = recvmsg(sfd, NULL, MSG_DONTWAIT); + LogPrintln("recvmsg: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + message.msg_iov = NULL; + message.msg_iovlen = 1; + ret = recvmsg(sfd, &message, MSG_DONTWAIT); + LogPrintln("recvmsg: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + message.msg_iov = gIov; + message.msg_iovlen = 1 + IOV_MAX; + ret = recvmsg(sfd, &message, MSG_DONTWAIT); + LogPrintln("recvmsg: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + message.msg_iov = reinterpret_cast(0xbad); + message.msg_iovlen = 1; + ret = recvmsg(sfd, &message, MSG_DONTWAIT); + LogPrintln("recvmsg: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + message.msg_iov = reinterpret_cast(0xbad); + message.msg_iovlen = 0; + ret = recvmsg(sfd, &message, MSG_DONTWAIT); + LogPrintln("recvmsg: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + /** + * send + */ + ret = send(sfd, NULL, 1, MSG_NOSIGNAL); + LogPrintln("send: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + ret = send(sfd, bad, 0, MSG_NOSIGNAL); + LogPrintln("send: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL((ret == 0 || ret == -1), 1, errno); + + /** + * sendmsg + */ + ret = sendmsg(sfd, NULL, MSG_NOSIGNAL); + LogPrintln("sendmsg: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + message.msg_iov = NULL; + message.msg_iovlen = 1; + ret = sendmsg(sfd, &message, MSG_NOSIGNAL); + LogPrintln("sendmsg: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + message.msg_iov = gIov; + message.msg_iovlen = IOV_MAX + 1; + ret = sendmsg(sfd, &message, MSG_NOSIGNAL); + LogPrintln("sendmsg: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + message.msg_iov = gIov; + message.msg_iovlen = (~0UL / sizeof(struct iovec)) + 2; // Test overflow + ret = sendmsg(sfd, &message, MSG_NOSIGNAL); + LogPrintln("sendmsg: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + message.msg_iov = reinterpret_cast(0xbad); + message.msg_iovlen = 1; + ret = sendmsg(sfd, &message, MSG_NOSIGNAL); + LogPrintln("sendmsg: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + message.msg_iov = reinterpret_cast(0xbad); + message.msg_iovlen = 0; + ret = sendmsg(sfd, &message, MSG_NOSIGNAL); + LogPrintln("sendmsg: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + /** + * sendto + */ + ret = sendto(sfd, NULL, 1, MSG_NOSIGNAL, NULL, addrlen); + LogPrintln("sendto: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + ret = sendto(sfd, NULL, 1, MSG_NOSIGNAL, &addr, addrlen); + LogPrintln("sendto: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + ret = sendto(sfd, bad, 0, MSG_NOSIGNAL, &addr, addrlen); + LogPrintln("sendto: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL((ret == 0 || ret == -1), 1, errno); + + ret = sendto(sfd, "NULL", 4, MSG_NOSIGNAL, NULL, addrlen); + LogPrintln("sendto: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + ret = sendto(sfd, "NULL", 4, MSG_NOSIGNAL, bad, 0); + LogPrintln("sendto: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + ret = sendto(sfd, "NULL", 4, MSG_NOSIGNAL, bad, addrlen); + LogPrintln("sendto: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + /** + * read/readv + */ + ret = read(sfd, NULL, 1); + LogPrintln("read: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + ret = read(sfd, NULL, 0); + LogPrintln("read: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, 0, errno); + + ret = read(sfd, bad, 1); + LogPrintln("read: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + ret = read(sfd, badUserAddr, 1); + LogPrintln("read: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + ret = read(sfd, bad, 0); + LogPrintln("read: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL((ret == 0 || ret == -1), 1, errno); + + ret = readv(sfd, reinterpret_cast(bad), 0); + LogPrintln("readv: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL((ret == 0 || ret == -1), 1, errno); + + ret = readv(sfd, reinterpret_cast(bad), 1); + LogPrintln("readv: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + ret = readv(sfd, gIov, 0); + LogPrintln("readv: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL((ret == 0 || ret == -1), 1, errno); + + ret = readv(sfd, gIov, IOV_MAX + 1); + LogPrintln("readv: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + gIov[0].iov_base = bad; + gIov[0].iov_len = 1; + ret = readv(sfd, gIov, 1); + LogPrintln("readv: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + gIov[0].iov_base = bad; + gIov[0].iov_len = 0; + ret = readv(sfd, gIov, 1); + LogPrintln("readv: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL((ret == 0 || ret == -1), 1, errno); + + /** + * write/writev + */ + ret = write(sfd, NULL, 1); + LogPrintln("write: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + ret = write(sfd, NULL, 0); + LogPrintln("write: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL((ret == 0 || ret == -1), 1, errno); + + ret = write(sfd, bad, 1); + LogPrintln("write: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + ret = write(sfd, badUserAddr, 1); + LogPrintln("write: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + ret = write(sfd, bad, 0); + LogPrintln("write: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL((ret == 0 || ret == -1), 1, errno); + + ret = writev(sfd, reinterpret_cast(bad), 0); + LogPrintln("writev: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL((ret == 0 || ret == -1), 1, errno); + + ret = writev(sfd, reinterpret_cast(bad), 1); + LogPrintln("writev: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + ret = writev(sfd, gIov, 0); + LogPrintln("writev: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL((ret == 0 || ret == -1), 1, errno); + + ret = writev(sfd, gIov, IOV_MAX + 1); + LogPrintln("writev: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + gIov[0].iov_base = bad; + gIov[0].iov_len = 1; + ret = writev(sfd, gIov, 1); + LogPrintln("writev: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL(ret, -1, errno); + + gIov[0].iov_base = bad; + gIov[0].iov_len = 0; + ret = writev(sfd, gIov, 1); + LogPrintln("writev: %d, errno=%d", ret, errno); + ICUNIT_ASSERT_EQUAL((ret == 0 || ret == -1), 1, errno); + + return ICUNIT_SUCCESS; +} + +static int SocketSetNonBlock(int sfd) +{ + int ret = fcntl(sfd, F_GETFL, 0); + ICUNIT_ASSERT_EQUAL(ret < 0, 0, errno); + + ret = fcntl(sfd, F_SETFL, ret | O_NONBLOCK); + ICUNIT_ASSERT_EQUAL(ret < 0, 0, errno); + + return ICUNIT_SUCCESS; +} + +static int SocketNullTest(void) +{ + int sfd; + + sighandler_t oldHdl = signal(SIGPIPE, SIG_IGN); + + sfd = socket(PF_INET, SOCK_DGRAM, 0); + ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, errno); + LogPrintln("UDP socket: %d", sfd); + (void)SocketSetNonBlock(sfd); + (void)SocketNullTestInternal(sfd); + (void)close(sfd); + + sfd = socket(PF_INET, SOCK_STREAM, 0); + ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, errno); + LogPrintln("TCP socket: %d", sfd); + (void)SocketSetNonBlock(sfd); + (void)SocketNullTestInternal(sfd); + (void)close(sfd); + + (void)signal(SIGPIPE, oldHdl); + + return ICUNIT_SUCCESS; +} + +void NetSocketTest012(void) +{ + TEST_ADD_CASE(__FUNCTION__, SocketNullTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION); +} + diff --git a/src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_013.cpp b/src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_013.cpp new file mode 100644 index 00000000..6c129f18 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/net/socket/smoke/net_socket_test_013.cpp @@ -0,0 +1,336 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include +#include +#include +#include +#include +#include +#include + +#define SERVER_PORT 9999 +#define INVALID_SOCKET -1 +#define CLIENT_NUM 1 + +static int gFds[FD_SETSIZE]; +static int gBye; + +static void InitFds() +{ + for (int i = 0; i < FD_SETSIZE; ++i) { + gFds[i] = INVALID_SOCKET; + } +} + +static void GetReadfds(fd_set *fds, int *nfd) +{ + for (int i = 0; i < FD_SETSIZE; i++) { + if (gFds[i] == INVALID_SOCKET) { + continue; + } + FD_SET(gFds[i], fds); + if (*nfd < gFds[i]) { + *nfd = gFds[i]; + } + } +} + +static int AddFd(int fd) +{ + for (int i = 0; i < FD_SETSIZE; ++i) { + if (gFds[i] == INVALID_SOCKET) { + gFds[i] = fd; + return 0; + } + } + return -1; +} + +static void DelFd(int fd) +{ + for (int i = 0; i < FD_SETSIZE; ++i) { + if (gFds[i] == fd) { + gFds[i] = INVALID_SOCKET; + } + } + (void)close(fd); +} + +static int CloseAllFd(void) +{ + for (int i = 0; i < FD_SETSIZE; ++i) { + if (gFds[i] != INVALID_SOCKET) { + (void)close(gFds[i]); + gFds[i] = INVALID_SOCKET; + } + } + return 0; +} + +static int HandleRecv(int fd) +{ + char buf[256]; + int ret = recv(fd, buf, sizeof(buf)-1, 0); + if (ret < 0) { + LogPrintln("[%d]Error: %s", fd, strerror(errno)); + DelFd(fd); + } else if (ret == 0) { + LogPrintln("[%d]Closed", fd); + DelFd(fd); + } else { + buf[ret] = 0; + LogPrintln("[%d]Received: %s", fd, buf); + if (strstr(buf, "Bye") != NULL) { + gBye++; + } + } + return -(ret < 0); +} + +static int HandleReadfds(fd_set *fds, int lsfd) +{ + int ret = 0; + for (int i = 0; i < FD_SETSIZE; ++i) { + if (gFds[i] == INVALID_SOCKET || !FD_ISSET(gFds[i], fds)) { + continue; + } + ret += HandleRecv(gFds[i]); + } + return ret; +} + +static unsigned int GetIp(int sfd, const char *ifname) +{ + struct ifreq ifr; + unsigned int ip = 0; + int ret = strncpy_s(ifr.ifr_name, sizeof(ifr.ifr_name) - 1, ifname, sizeof(ifr.ifr_name) - 1); + if (ret < 0) { + return 0; + } + ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0'; + ret = ioctl(sfd, SIOCGIFADDR, &ifr); + if (ret == 0) { + ip = (reinterpret_cast(&(ifr.ifr_addr)))->sin_addr.s_addr; + } + return ip; +} + +static unsigned int GetNetmask(int sfd, const char *ifname) +{ + struct ifreq ifr; + unsigned int msk = 0; + int ret = strncpy_s(ifr.ifr_name, sizeof(ifr.ifr_name) - 1, ifname, sizeof(ifr.ifr_name) - 1); + if (ret < 0) { + return 0; + } + ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0'; + ret = ioctl(sfd, SIOCGIFNETMASK, &ifr); + if (ret == 0) { + msk = (reinterpret_cast(&(ifr.ifr_addr)))->sin_addr.s_addr; + } + return msk; +} + +static char *MyInetNtoa(unsigned int ip) +{ + struct in_addr in = {ip}; + return inet_ntoa(in); +} + +static void *ClientsThread(void *param) +{ + int fd; + int thrNo = (int)(intptr_t)param; + int ret; + const char *ifname[] = {"eth0", "wlan0", "et1", "wl1", "enp4s0f0"}; + unsigned int ip, msk, brdcast; + + LogPrintln("<%d>socket client thread started", thrNo); + fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (fd == INVALID_SOCKET) { + perror("socket"); + return NULL; + } + + int broadcast = 1; + ret = setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast)); + if (ret != 0) { + LogPrintln("[%d]<%d> set broadcast option fail", fd, thrNo); + close(fd); + return NULL; + } + + for (int j = 0; j < sizeof(ifname) / sizeof(ifname[0]); ++j) { + ip = GetIp(fd, ifname[j]); + msk = GetNetmask(fd, ifname[j]); + if (ip != 0) { + LogPrintln("[%d]<%d>%s: ip %s", fd, thrNo, ifname[j], MyInetNtoa(ip)); + LogPrintln("[%d]<%d>%s: netmask %s", fd, thrNo, ifname[j], MyInetNtoa(msk)); + break; + } + } + + brdcast = ip | ~msk; + LogPrintln("[%d]<%d>broadcast address %s", fd, thrNo, MyInetNtoa(brdcast)); + + struct sockaddr_in sa; + sa.sin_family = AF_INET; + sa.sin_addr.s_addr = brdcast; + sa.sin_port = htons(SERVER_PORT); + if (connect(fd, reinterpret_cast(&sa), sizeof(sa)) == -1) { + perror("connect"); + return NULL; + } + + LogPrintln("[%d]<%d>connected to udp://%s:%d successful", fd, thrNo, inet_ntoa(sa.sin_addr), SERVER_PORT); + + const char *msg[] = { + "hello, ", + "ohos, ", + "my name is net_socket_test_013, ", + "see u next time, ", + "Bye!" + }; + + for (int i = 0; i < sizeof(msg) / sizeof(msg[0]); ++i) { + if (send(fd, msg[i], strlen(msg[i]), 0) < 0) { + LogPrintln("[%d]<%d>send msg [%s] fail: errno %d", fd, thrNo, msg[i], errno); + } + } + + (void)shutdown(fd, SHUT_RDWR); + (void)close(fd); + return param; +} + +static int StartClients(pthread_t *cli, int cliNum) +{ + int ret; + pthread_attr_t attr; + + for (int i = 0; i < cliNum; ++i) { + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&cli[i], &attr, ClientsThread, (void *)(intptr_t)i); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + } + return 0; +} + +static int UdpBrdcastSelectTest(void) +{ + struct sockaddr_in sa = {0}; + int lsfd; + int ret; + + lsfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + ICUNIT_ASSERT_NOT_EQUAL(lsfd, -1, errno); + + sa.sin_family = AF_INET; + sa.sin_addr.s_addr = htonl(INADDR_ANY); + sa.sin_port = htons(SERVER_PORT); + ret = bind(lsfd, reinterpret_cast(&sa), sizeof(sa)); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, errno + CloseAllFd()); + + int broadcast = 1; + ret = setsockopt(lsfd, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast)); + ICUNIT_ASSERT_EQUAL(ret, 0, errno + CloseAllFd()); + + int loop = 0; + socklen_t len = sizeof(loop); + ret = getsockopt(lsfd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, &len); + ICUNIT_ASSERT_EQUAL(ret, 0, errno + CloseAllFd()); + LogPrintln("IP_MULTICAST_LOOP default: %d", loop); + + loop = 0; + ret = setsockopt(lsfd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop)); + ICUNIT_ASSERT_EQUAL(ret, 0, errno + CloseAllFd()); + + ret = getsockopt(lsfd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, &len); + ICUNIT_ASSERT_EQUAL(ret, 0, errno + CloseAllFd()); + LogPrintln("IP_MULTICAST_LOOP changed to: %d", loop); + + InitFds(); + AddFd(lsfd); + LogPrintln("[%d]Waiting for client to connect on UDP port %d", lsfd, SERVER_PORT); + + pthread_t clients[CLIENT_NUM]; + + ret = StartClients(clients, CLIENT_NUM); + ICUNIT_ASSERT_EQUAL(ret, 0, ret + CloseAllFd()); + + for ( ; ; ) { + int nfd; + fd_set readfds; + struct timeval timeout; + + timeout.tv_sec = 3; + timeout.tv_usec = 0; + + nfd = 0; + FD_ZERO(&readfds); + + GetReadfds(&readfds, &nfd); + + ret = select(nfd + 1, &readfds, NULL, NULL, &timeout); + LogPrintln("select %d", ret); + if (ret == -1) { + perror("select"); + break; // error occurred + } else if (ret == 0) { + break; // timed out + } + + if (HandleReadfds(&readfds, lsfd) < 0) { + break; + } + } + + for (int i = 0; i < CLIENT_NUM; ++i) { + ret = pthread_join(clients[i], NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret + CloseAllFd()); + } + + ICUNIT_ASSERT_EQUAL(gBye, CLIENT_NUM, gBye + CloseAllFd()); + (void)CloseAllFd(); + return ICUNIT_SUCCESS; +} + +void NetSocketTest013(void) +{ + TEST_ADD_CASE(__FUNCTION__, UdpBrdcastSelectTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/BUILD.gn b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/BUILD.gn new file mode 100644 index 00000000..8519158c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/BUILD.gn @@ -0,0 +1,56 @@ +# Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("./config.gni") + +if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_LOW) { + unittest("liteos_a_process_basic_process_unittest_door") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + include_dirs = common_include_dirs + sources = sources_entry + sources += sources_smoke + sources_full = [] + sources += sources_full + configs = [ "../../..:public_config_for_door" ] + deps = [ "$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR:libsec_shared" ] + } +} + +if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_MIDDLE) { + unittest("liteos_a_process_basic_process_unittest") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + include_dirs = common_include_dirs + sources = sources_entry + sources += sources_smoke + sources += sources_full + configs = [ "../../..:public_config_for_all" ] + deps = [ "$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR:libsec_shared" ] + } +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/config.gni b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/config.gni new file mode 100644 index 00000000..f33462b0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/config.gni @@ -0,0 +1,136 @@ +# Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//build/lite/config/test.gni") +import("//kernel/liteos_a/liteos.gni") +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +common_include_dirs = [ + "$THIRDPARTY_GOOGLETEST_DIR/googletest/include", + "../../../common/include", +] + +sources_entry = [ "../../../common/osTest.cpp" ] + +sources_smoke = [] + +sources_full = [] + +process_basic_process_include_dirs = + [ "$TEST_UNITTEST_DIR/process/basic/process" ] + +process_basic_process_sources_entry = + [ "$TEST_UNITTEST_DIR/process/basic/process/process_process_test.cpp" ] + +process_basic_process_sources_smoke = [ + "$TEST_UNITTEST_DIR/process/basic/process/smoke/process_test_001.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smoke/process_test_002.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smoke/process_test_004.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smoke/process_test_005.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smoke/process_test_006.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smoke/process_test_008.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smoke/process_test_009.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smoke/process_test_010.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smoke/process_test_011.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smoke/process_test_012.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smoke/process_test_013.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smoke/process_test_014.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smoke/process_test_015.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smoke/process_test_016.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smoke/process_test_017.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smoke/process_test_018.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smoke/process_test_019.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smoke/process_test_020.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smoke/process_test_021.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smoke/process_test_022.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smoke/process_test_023.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smoke/process_test_024.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smoke/process_test_025.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smoke/process_test_026.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smoke/process_test_027.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smoke/process_test_029.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smoke/process_test_030.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smoke/process_test_038.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smoke/process_test_039.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smoke/process_test_043.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smoke/process_test_044.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smoke/process_test_045.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smoke/process_test_046.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smoke/process_test_047.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smoke/process_test_048.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smoke/process_test_054.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smoke/process_test_061.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smp/process_test_smp_001.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smp/process_test_smp_002.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smp/process_test_smp_003.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smp/process_test_smp_004.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smp/process_test_smp_005.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smp/process_test_smp_006.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smp/process_test_smp_007.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/smp/process_test_smp_008.cpp", +] + +process_basic_process_sources_full = [ + "$TEST_UNITTEST_DIR/process/basic/process/full/process_test_007.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/full/process_test_031.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/full/process_test_032.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/full/process_test_033.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/full/process_test_034.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/full/process_test_035.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/full/process_test_036.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/full/process_test_037.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/full/process_test_040.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/full/process_test_041.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/full/process_test_042.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/full/process_test_049.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/full/process_test_050.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/full/process_test_051.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/full/process_test_055.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/full/process_test_056.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/full/process_test_057.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/full/process_test_058.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/full/process_test_059.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/full/process_test_060.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/full/process_test_063.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/full/process_test_064.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/full/process_test_065.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/full/process_test_066.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/full/process_test_067.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/full/process_test_068.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/full/process_test_069.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/full/process_test_053.cpp", + "$TEST_UNITTEST_DIR/process/basic/process/full/process_test_062.cpp", +] + +# process basic process module +if (LOSCFG_USER_TEST_PROCESS_BASIC_PROCESS == true) { + common_include_dirs += process_basic_process_include_dirs + sources_entry += process_basic_process_sources_entry + sources_smoke += process_basic_process_sources_smoke + sources_full += process_basic_process_sources_full +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_007.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_007.cpp new file mode 100644 index 00000000..58587ca9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_007.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static const int TEST_COUNT = 10; + +static void *ThreadFunc2(void *arg) +{ + exit(254); // 254, exit args +} + +static int ProcessTest001(void) +{ + int ret; + int status; + int pid; + int data; + int pri; + pthread_t newPthread, newPthread1; + int count = 4; + int currProcessPri = getpriority(PRIO_PROCESS, getpid()); + ICUNIT_ASSERT_WITHIN_EQUAL(currProcessPri, 0, 31, currProcessPri); // 31, assert that function Result is equal to this. + + ret = setpriority(PRIO_PROCESS, getpid(), currProcessPri - 2); // 2, Used to calculate priorities. + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + data = ret; + ret = pthread_create(&newPthread, NULL, ThreadFunc2, &data); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + exit(255); // 255, exit args + return 0; +} + +static int Testcase(void) +{ + int ret; + int status; + int pid; + int count = TEST_COUNT; + int temp = GetCpuCount(); + if (temp <= 1) { + return 0; + } + + while (count > 0) { + ret = fork(); + if (ret == 0) { + ret = ProcessTest001(); + exit(10); // 10, exit args + } else if (ret > 0) { + pid = ret; + ret = wait(&status); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ICUNIT_ASSERT_TWO_EQUAL(status, 255, 254, status); // 255, 254, assert that function Result is equal to this. + } + + ICUNIT_ASSERT_WITHIN_EQUAL(ret, 0, 100000, ret); // 100000, assert that function Result is equal to this. + count--; + } + return 0; +} + +void ItTestProcess007(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_007", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_031.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_031.cpp new file mode 100644 index 00000000..ab00f279 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_031.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static int Child1(int currGid) +{ + ICUNIT_ASSERT_EQUAL(currGid, getpgrp(), getpgrp()); + + usleep(1000 * 10 * 5); // 1000, 10, 5, Used to calculate the delay time. + + ICUNIT_ASSERT_EQUAL(getpgrp(), getpid(), getpgrp()); + + exit(255); // 255, exit args +} + +static int Child2(int currGid, int gid) +{ + ICUNIT_ASSERT_EQUAL(currGid, getpgrp(), getpgrp()); + usleep(1000 * 10 * 5); // 1000, 10, 5, Used to calculate the delay time. + + ICUNIT_ASSERT_EQUAL(getpgrp(), gid, getpgrp()); + exit(255); // 255, exit args +} + +static int TestCase(void) +{ + int ret; + int status = 0; + pid_t pid, pid1; + int currGid = getpgrp(); + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + + if (pid == 0) { + Child1(currGid); + exit(0); + } + + usleep(1000 * 10 * 2); // 1000, 10, 2, Used to calculate the delay time. + + ret = setpgid(pid, pid); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + usleep(1000 * 10 * 5); // 1000, 10, 5, Used to calculate the delay time. + + pid1 = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid1, 0, 100000, pid1, EXIT); // 100000, assert pid1 equal to this. + if (pid1 == 0) { + Child2(currGid, pid); + exit(0); + } + + usleep(1000 * 10 * 2); // 1000, 10, 2, Used to calculate the delay time. + + ret = setpgid(pid1, pid); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + usleep(1000 * 10 * 5); // 1000, 10, 5, Used to calculate the delay time. + + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert status equal to this. + + status = 0; + ret = waitpid(pid1, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid1, ret); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert status equal to this. + + return 0; +EXIT: + return 1; +} + +void ItTestProcess031(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_031", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_032.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_032.cpp new file mode 100644 index 00000000..0b75072b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_032.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static int Child1(int currGid) +{ + ICUNIT_ASSERT_EQUAL(currGid, getpgrp(), getpgrp()); + + usleep(1000 * 10 * 5); // 1000, 10, 5, Used to calculate the delay time. + + ICUNIT_ASSERT_EQUAL(getpgrp(), getpid(), getpgrp()); + + exit(255); // 255, exit args +} + +static int Child2(int currGid, int gid) +{ + int ret; + ICUNIT_ASSERT_EQUAL(currGid, getpgrp(), getpgrp()); + + ret = setpgid(getpid(), gid); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_EQUAL(getpgrp(), gid, getpgrp()); + exit(255); // 255, exit args +} + +static int TestCase(void) +{ + int ret; + int status = 0; + pid_t pid, pid1; + int currGid = getpgrp(); + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + + if (pid == 0) { + Child1(currGid); + exit(0); + } + + usleep(1000 * 10 * 2); // 1000, 10, 2, Used to calculate the delay time. + + ret = setpgid(pid, pid); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + usleep(1000 * 10 * 5); // 1000, 10, 5, Used to calculate the delay time. + + pid1 = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid1, 0, 100000, pid1, EXIT); // 100000, assert pid1 equal to this. + if (pid1 == 0) { + Child2(currGid, pid); + exit(0); + } + + usleep(1000 * 10 * 5); // 1000, 10, 5, Used to calculate the delay time. + + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert status equal to this. + + status = 0; + ret = waitpid(pid1, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid1, ret); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert status equal to this. + + return 0; +EXIT: + return 1; +} + +void ItTestProcess032(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_032", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_033.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_033.cpp new file mode 100644 index 00000000..16db771f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_033.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static int Child1(int currGid) +{ + ICUNIT_ASSERT_EQUAL(currGid, getpgrp(), getpgrp()); + + usleep(1000 * 10 * 5); // 1000, 10, 5, Used to calculate the delay time. + + ICUNIT_ASSERT_EQUAL(getpgrp(), getpid(), getpgrp()); + + exit(255); // 255, exit args +} + +static int Child2(int currGid, int gid) +{ + ICUNIT_ASSERT_EQUAL(currGid, getpgrp(), getpgrp()); + usleep(1000 * 10 * 5); // 1000, 10, 5, Used to calculate the delay time. + + ICUNIT_ASSERT_EQUAL(currGid, getpgrp(), getpgrp()); + exit(255); // 255, exit args +} + +static int TestCase(void) +{ + int ret; + int status = 0; + pid_t pid, pid1; + int currGid = getpgrp(); + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + + if (pid == 0) { + Child1(currGid); + exit(0); + } + + usleep(1000 * 10 * 1); // 1000, 10, Used to calculate the delay time. + ret = setpgid(pid, pid); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert status equal to this. + + pid1 = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid1, 0, 100000, pid1, EXIT); // 100000, assert pid1 equal to this. + ICUNIT_GOTO_NOT_EQUAL(pid1, pid, pid1, EXIT); + + if (pid1 == 0) { + Child2(currGid, pid); + exit(0); + } + + usleep(1000 * 10 * 2); // 1000, 10, 2, Used to calculate the delay time. + + ret = setpgid(pid1, pid); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, EPERM, errno); + + usleep(1000 * 10 * 5); // 1000, 10, 5, Used to calculate the delay time. + + status = 0; + ret = waitpid(pid1, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid1, ret); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert status equal to this. + + return 0; +EXIT: + return 1; +} + +void ItTestProcess033(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_033", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_034.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_034.cpp new file mode 100644 index 00000000..7c6cb926 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_034.cpp @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static int Child1(int currGid) +{ + ICUNIT_ASSERT_EQUAL(currGid, getpgrp(), getpgrp()); + + sleep(1); + + ICUNIT_ASSERT_EQUAL(currGid, getpgrp(), getpgrp()); + + exit(255); // 255, exit args +} + +static int Child2(int currGid, int gid) +{ + ICUNIT_ASSERT_EQUAL(currGid, getpgrp(), getpgrp()); + + sleep(1); + + ICUNIT_ASSERT_EQUAL(currGid, getpgrp(), getpgrp()); + exit(255); // 255, exit args +} + +static int TestCase(void) +{ + int ret; + int status = 0; + pid_t pid, pid1; + int currGid = getpgrp(); + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + + if (pid == 0) { + Child1(currGid); + exit(0); + } + + pid1 = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid1, 0, 100000, pid1, EXIT); // 100000, assert pid1 equal to this. + ICUNIT_GOTO_NOT_EQUAL(pid1, pid, pid1, EXIT); + + if (pid1 == 0) { + Child2(currGid, pid); + exit(0); + } + + usleep(1000 * 10 * 2); // 1000, 10, 2, Used to calculate the delay time. + + ret = setpgid(pid1, pid); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, EPERM, errno); + + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert status equal to this. + + status = 0; + ret = waitpid(pid1, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid1, ret); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert status equal to this. + + return 0; +EXIT: + return 1; +} + +void ItTestProcess034(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_034", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_035.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_035.cpp new file mode 100644 index 00000000..eb21368c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_035.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static int Child1(int currGid) +{ + ICUNIT_ASSERT_EQUAL(currGid, getpgrp(), getpgrp()); + + sleep(1); + + exit(255); // 255, exit args +} + +static int Child2(int currGid, int gid) +{ + int ret; + + ICUNIT_ASSERT_EQUAL(currGid, getpgrp(), getpgrp()); + + ret = setpgid(getpid(), gid); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, EPERM, errno); + + ICUNIT_ASSERT_EQUAL(currGid, getpgrp(), getpgrp()); + exit(255); // 255, exit args +} + +static int TestCase(void) +{ + int ret; + int status = 0; + pid_t pid, pid1; + int currGid = getpgrp(); + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + + if (pid == 0) { + Child1(currGid); + exit(0); + } + + pid1 = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid1, 0, 100000, pid1, EXIT); // 100000, assert pid1 equal to this. + ICUNIT_GOTO_NOT_EQUAL(pid1, pid, pid1, EXIT); + + if (pid1 == 0) { + Child2(currGid, pid); + exit(0); + } + + usleep(1000 * 10 * 2); // 1000, 10, 2, Used to calculate the delay time. + + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert status equal to this. + + status = 0; + ret = waitpid(pid1, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid1, ret); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert status equal to this. + + return 0; +EXIT: + return 1; +} + +void ItTestProcess035(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_035", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_036.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_036.cpp new file mode 100644 index 00000000..1d8efc76 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_036.cpp @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static int Child1(int currGid) +{ + int ret; + + ICUNIT_ASSERT_EQUAL(currGid, getpgrp(), getpgrp()); + + ret = setpgrp(); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(getpid(), getpgrp(), getpgrp()); + + usleep(1000 * 10 * 10); // 1000, 10, 10, Used to calculate the delay time. + + ret = setpgid(getpid(), currGid); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(getpgrp(), currGid, getpgrp()); + + usleep(1000 * 10 * 5); // 1000, 10, 5, Used to calculate the delay time. + exit(255); // 255, exit args +} + +static int Child2(int currGid, int gid) +{ + int ret; + + ICUNIT_ASSERT_EQUAL(currGid, getpgrp(), getpgrp()); + + ret = setpgid(getpid(), gid); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(getpgrp(), gid, getpgrp()); + + usleep(1000 * 10 * 12); // 1000, 10, 12, Used to calculate the delay time. + + ret = setpgrp(); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(getpgrp(), getpid(), getpgrp()); + + exit(255); // 255, exit args +} + +static int ProcessGroup(void) +{ + int ret; + int status = 0; + pid_t pid, pid1; + int currGid = getpgrp(); + ret = setpgrp(); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + currGid = getpgrp(); + + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + + if (pid == 0) { + Child1(currGid); + exit(g_iCunitErrLineNo); + } + + usleep(1000 * 10 * 2); // 1000, 10, 2, Used to calculate the delay time. + + pid1 = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid1, 0, 100000, pid1, EXIT); // 100000, assert pid1 equal to this. + ICUNIT_GOTO_NOT_EQUAL(pid1, pid, pid1, EXIT); + + if (pid1 == 0) { + Child2(currGid, pid); + exit(g_iCunitErrLineNo); + } + + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert status equal to this. + + status = 0; + ret = waitpid(pid1, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid1, ret); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert status equal to this. + + exit(255); // 255, exit args +EXIT: + return 0; +} + +static int TestCase(void) +{ + int ret; + int status = 0; + pid_t pid, pid1; + int currGid = getpgrp(); + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + + if (pid == 0) { + ProcessGroup(); + exit(g_iCunitErrLineNo); + } + + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert status equal to this. + + return 0; +EXIT: + return 1; +} + +void ItTestProcess036(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_036", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_037.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_037.cpp new file mode 100644 index 00000000..29f8c6a4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_037.cpp @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static int Child1(int currGid) +{ + int ret; + + ICUNIT_ASSERT_EQUAL(currGid, getpgrp(), getpgrp()); + + ret = setpgrp(); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(getpid(), getpgrp(), getpgrp()); + + usleep(1000 * 10 * 12); // 1000, 10, 12, Used to calculate the delay time. + + exit(255); // 255, exit args +} + +static int Child2(int currGid, int gid) +{ + int ret; + + ICUNIT_ASSERT_EQUAL(currGid, getpgrp(), getpgrp()); + + ret = setpgid(getpid(), getpid()); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(getpgrp(), getpid(), getpgrp()); + + usleep(1000 * 10 * 12); // 1000, 10, 12, Used to calculate the delay time. + + ICUNIT_ASSERT_EQUAL(getpgrp(), gid, getpgrp()); + + exit(255); // 255, exit args +} + +static int ProcessGroup(void) +{ + int ret; + int status = 0; + pid_t pid, pid1; + int currGid = getpgrp(); + ret = setpgrp(); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + currGid = getpgrp(); + + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + + if (pid == 0) { + Child1(currGid); + exit(g_iCunitErrLineNo); + } + + usleep(1000 * 10 * 2); // 1000, 10, 2, Used to calculate the delay time. + + pid1 = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid1, 0, 100000, pid1, EXIT); // 100000, assert pid1 equal to this. + ICUNIT_GOTO_NOT_EQUAL(pid1, pid, pid1, EXIT); + + if (pid1 == 0) { + Child2(currGid, pid); + exit(g_iCunitErrLineNo); + } + + usleep(1000 * 10 * 2); // 1000, 10, 2, Used to calculate the delay time. + + ret = setpgid(pid1, pid); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert status equal to this. + + status = 0; + ret = waitpid(pid1, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid1, ret); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert status equal to this. + + exit(255); // 255, exit args +EXIT: + return 0; +} + +static int TestCase(void) +{ + int ret; + int status = 0; + pid_t pid, pid1; + int currGid = getpgrp(); + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + + if (pid == 0) { + ProcessGroup(); + exit(g_iCunitErrLineNo); + } + + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert status equal to this. + + return 0; +EXIT: + return 1; +} + +void ItTestProcess037(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_037", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_040.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_040.cpp new file mode 100644 index 00000000..cadf457c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_040.cpp @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static int GroupProcess(void) +{ + int ret; + int status = 0; + pid_t pid, pid1; + int count = 1000; + int waitProcess = 0; + int testPid; + bool thread = false; + int processCount = 0; + + for (int i = 0; i < count; i++) { + pid = fork(); + if (pid == 0) { + usleep(1000 * 10 * 50); // 1000, 10, 50, Used to calculate the delay time. + exit(0); + } else if (pid < 0) { + if (errno != EAGAIN) { + sleep(1); + } + ret = wait(&status); + if (ret > 0) { + processCount--; + } + continue; + } else { + testPid = pid; + processCount++; + continue; + } + } + + ret = 0; + while (processCount > 0) { + ret = wait(&status); + if (ret > 0) { + processCount--; + } else { + sleep(1); + } + } + + exit(255); // 255, exit args +EXIT: + return 0; +} + +static int TestCase(void) +{ + int ret; + int status = 0; + pid_t pid, pid1; + int currGid = getpgrp(); + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + + if (pid == 0) { + prctl(PR_SET_NAME, "mainFork", 0UL, 0UL, 0UL); + GroupProcess(); + printf("[Failed] - [Errline : %d RetCode : 0x%x\n", g_iCunitErrLineNo, g_iCunitErrCode); + exit(g_iCunitErrLineNo); + } + + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert status equal to this. + + return 0; +EXIT: + return 1; +} + +void ItTestProcess040(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_040", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_041.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_041.cpp new file mode 100644 index 00000000..d2356961 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_041.cpp @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static void *Thread(void *arg) +{ + sleep(1); + return NULL; +} + +static int GroupProcess(void) +{ + int testPid; + int ret; + int status = 0; + pid_t pid, pid1; + int count = 500; + int waitProcess = 0; + pthread_attr_t a = { 0 }; + pthread_t pthread[1000] = { 0 }; + struct sched_param param = { 0 }; + bool thread = false; + + int processCount = 0; + + pthread_attr_init(&a); + param.sched_priority = 31; // 31, set pthread priority. + pthread_attr_setschedparam(&a, ¶m); + for (int i = 0; i < 40; i++) { // 40, number of cycles + ret = pthread_create(&pthread[i], &a, Thread, NULL); + if (ret != 0) { + exit(10); // 10, exit args + break; + } + } + + for (int i = 0; i < count; i++) { + pid = fork(); + if (pid == 0) { + pthread_create(&pthread[100], &a, Thread, NULL); // 100, pthread array subscript + pthread_create(&pthread[100], &a, Thread, NULL); // 100, pthread array subscript + pthread_create(&pthread[100], &a, Thread, NULL); // 100, pthread array subscript + usleep(1000 * 10 * 50); // 1000, 10, 50, Used to calculate the delay time. + exit(0); + } else if (pid < 0) { + if (errno != EAGAIN) { + sleep(1); + } + ret = wait(&status); + if (ret > 0) { + processCount--; + } + continue; + } else { + processCount++; + testPid = pid; + continue; + } + } + + ret = 0; + while (processCount > 0) { + ret = wait(&status); + if (ret > 0) { + processCount--; + } else { + sleep(1); + } + } + + exit(255); // 255, exit args +EXIT: + return 0; +} + +static int TestCase(void) +{ + int ret; + int status = 0; + pid_t pid, pid1; + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + + if (pid == 0) { + prctl(PR_SET_NAME, "mainFork", 0UL, 0UL, 0UL); + GroupProcess(); + printf("[Failed] - [Errline : %d RetCode : 0x%x\n", g_iCunitErrLineNo, g_iCunitErrCode); + exit(g_iCunitErrLineNo); + } + + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert status equal to this. + + return 0; +EXIT: + return 1; +} + +void ItTestProcess041(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_041", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_042.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_042.cpp new file mode 100644 index 00000000..bade0abe --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_042.cpp @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" +#include "sys/shm.h" + +static const int TEST_THREAD = 40; +static const int TEST_LOOP = 3000; + +static void Child2(int shmid) +{ + int count = 2; // 2, Set the calculation number to determine the cycle status. + int *shared = (int *)shmat(shmid, nullptr, 0); + ICUNIT_ASSERT_NOT_EQUAL_VOID(shared, reinterpret_cast(-1), shared); + + while ((*shared) < (TEST_LOOP + 2)) { // 2, Set the cycle number. + ICUNIT_ASSERT_EQUAL_VOID(*shared, count, *shared); + (*shared)++; + count += 3; // 3, Set the calculation number to determine the cycle status. + sched_yield(); + } + + exit(255); // 255, exit args + return; +} + +static void Child1(int shmid) +{ + int count = 1; + int *shared = (int *)shmat(shmid, nullptr, 0); + ICUNIT_ASSERT_NOT_EQUAL_VOID(shared, reinterpret_cast(-1), shared); + + while ((*shared) < (TEST_LOOP + 1)) { + ICUNIT_ASSERT_EQUAL_VOID(*shared, count, *shared); + (*shared)++; + count += 3; // 3, Set the calculation number to determine the cycle status. + sched_yield(); + } + + (*shared) = 100000; // 100000, shared num. + + exit(255); // 255, exit args + return; +} + +static int GroupProcess(void) +{ + int testPid; + int ret; + int policy = 0; + struct sched_param param = { 0 }; + int status = 0; + pid_t pid, pid1; + const int memSize = 1024; + int shmid; + int *shared = NULL; + + ret = sched_getparam(getpid(), ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + int processPrio = param.sched_priority; + + ret = pthread_getschedparam(pthread_self(), &policy, ¶m); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + /* 1234, Sets the shmget key; 0666 config of shmget */ + shmid = shmget(static_cast(1234), memSize, 0666 | IPC_CREAT); + ICUNIT_ASSERT_NOT_EQUAL(shmid, -1, shmid); + + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + if (pid == 0) { + Child1(shmid); + printf("[Failed] - [Errline : %d RetCode : 0x%x\n", g_iCunitErrLineNo, g_iCunitErrCode); + exit(0); + } + + pid1 = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid1, 0, 100000, pid1, EXIT); // 100000, assert pid equal to this. + if (pid1 == 0) { + Child2(shmid); + printf("[Failed] - [Errline : %d RetCode : 0x%x\n", g_iCunitErrLineNo, g_iCunitErrCode); + exit(0); + } + + shared = (int *)shmat(shmid, nullptr, 0); + ICUNIT_ASSERT_NOT_EQUAL(shared, reinterpret_cast(-1), shared); + + (*shared) = 0; + + while ((*shared) < TEST_LOOP) { + (*shared)++; + sched_yield(); + } + + (*shared) = TEST_LOOP + 10; // 10, Set the cycle number. + + param.sched_priority = processPrio - 2; // 2, set pthread priority. + ret = sched_setscheduler(pid, SCHED_RR, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_EQUAL(*shared, 100000, *shared); // 100000, assert that function Result is equal to this. + + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(status, 255, status); // 255, assert that function Result is equal to this. + + ret = waitpid(pid1, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid1, ret); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(status, 255, status); // 255, assert that function Result is equal to this. + + exit(255); // 255, exit args +EXIT: + return 0; +} + +static int TestCase(void) +{ + int ret; + int status = 0; + pid_t pid, pid1; + + int temp = GetCpuCount(); + if (temp != 1) { + return 0; + } + + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + + if (pid == 0) { + prctl(PR_SET_NAME, "mainFork", 0UL, 0UL, 0UL); + GroupProcess(); + printf("[Failed] - [Errline : %d RetCode : 0x%x\n", g_iCunitErrLineNo, g_iCunitErrCode); + exit(g_iCunitErrLineNo); + } + + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert status equal to this. + + return 0; +EXIT: + return 1; +} + +void ItTestProcess042(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_042", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_049.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_049.cpp new file mode 100644 index 00000000..70d38ea3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_049.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" +#include "sys/shm.h" + +static int *g_shmptr = NULL; +static int g_usetTestCount = 0; +static VOID *PthreadTest115(VOID *arg) +{ + g_usetTestCount++; + return NULL; +} + +static int TestThread(void *arg) +{ + int data = *((int *)arg); + int ret = 0; + pthread_t gTh; + ret = pthread_create(&gTh, NULL, PthreadTest115, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(gTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(g_usetTestCount, 1, g_usetTestCount); + + *g_shmptr = 100; // 100, set shared num. + + pid_t pid = fork(); + + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + if (pid == 0) { + sleep(1); + exit(0); + } + + *g_shmptr = 200; // 200, set shared num. + + ret = waitpid(pid, NULL, 0); + printf("waitpid ret : %d errno : %d pid : %d getpid : %d\n", ret, errno, pid, getpid()); + + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + + *g_shmptr = data; +EXIT: + return 0; +} + +// This testcase us used for undefination of LOSCFG_USER_TEST_SMP +static int Testcase(void) +{ + int arg = 0x2000; + int status; + int ret; + char *stackTop; + char *stack; + pid_t pid; + + g_usetTestCount = 0; + int shmid = shmget(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0600); // // 0600, set shmget config. + ICUNIT_ASSERT_NOT_EQUAL(shmid, -1, shmid); + + g_shmptr = (int *)shmat(shmid, nullptr, 0); + ICUNIT_ASSERT_NOT_EQUAL(g_shmptr, reinterpret_cast(-1), g_shmptr); + + *g_shmptr = 0; + + stack = static_cast(malloc(arg)); + ICUNIT_GOTO_NOT_EQUAL(stack, NULL, stack, EXIT1); + + stackTop = reinterpret_cast(reinterpret_cast(stack) + arg); + pid = clone(TestThread, (void *)stackTop, CLONE_VFORK, &arg); + + ICUNIT_GOTO_EQUAL(*g_shmptr, arg, *g_shmptr, EXIT2); + + ret = waitpid(pid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT2); + +EXIT2: + free(stack); + +EXIT1: + shmdt(g_shmptr); + shmctl(shmid, IPC_RMID, NULL); + + return 0; +} + +void ItTestProcess049(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_049", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_050.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_050.cpp new file mode 100644 index 00000000..51da4d6e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_050.cpp @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" +#include "sys/shm.h" + +static int *g_shmptr = NULL; +static int g_ppid; +static int TestThread(void *arg) +{ + pid_t ppid = getppid(); + + printf("TestThread ppid : %d g_ppid : %d\n", ppid, g_ppid); + + ICUNIT_ASSERT_EQUAL(ppid, g_ppid, g_ppid); + + *g_shmptr = 100; // 100, set shared num. + return 0; +} + +// This testcase us used for undefination of LOSCFG_USER_TEST_SMP +static int Testcase(void) +{ + int arg = 0x2000; + int status; + void *stack; + char *stackTop; + int ret; + int count; + pid_t pid; + + int shmid = shmget(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0600); // 0600 config of shmget + ICUNIT_ASSERT_NOT_EQUAL(shmid, -1, shmid); + + g_shmptr = (int *)shmat(shmid, nullptr, 0); + ICUNIT_ASSERT_NOT_EQUAL(g_shmptr, reinterpret_cast(-1), g_shmptr); + + *g_shmptr = 0; + + g_ppid = getppid(); + printf("testcase ppid : %d\n", g_ppid); + + stack = malloc(arg); + ICUNIT_GOTO_NOT_EQUAL(stack, NULL, stack, EXIT1); + + stackTop = reinterpret_cast(reinterpret_cast(stack) + arg); + pid = clone(TestThread, (void *)stackTop, CLONE_PARENT, &arg); + + ret = waitpid(pid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, -1, ret, EXIT2); + + count = 0; + while ((count < 100) || (*g_shmptr == 0)) { // 100, Number of cycles. + usleep(1000 * 100); // 1000, 100, set usleep time. + count++; + } + + ICUNIT_GOTO_EQUAL(*g_shmptr, 100, *g_shmptr, EXIT2); // 100, assert g_shmptr equal to this. +EXIT2: + free(stack); + +EXIT1: + shmdt(g_shmptr); + shmctl(shmid, IPC_RMID, NULL); + + return 0; +} + +void ItTestProcess050(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_050", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_051.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_051.cpp new file mode 100644 index 00000000..e46eacf6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_051.cpp @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" +#include "sys/shm.h" + +static int *g_shmptr = NULL; +static int g_ppid; +static int TestThread(void *arg) +{ + int ret = 0; + pid_t pid; + pid_t ppid = getppid(); + + printf("TestThread ppid : %d g_ppid : %d\n", ppid, g_ppid); + + ICUNIT_ASSERT_EQUAL(ppid, g_ppid, g_ppid); + + *g_shmptr = 1000; // 1000, set shared num. + + pid = fork(); + + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + if (pid == 0) { + sleep(1); + exit(0); + } + + ret = waitpid(pid, NULL, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + + *g_shmptr = 100; // 100, set shared num. +EXIT: + return 0; +} + +// This testcase us used for undefination of LOSCFG_USER_TEST_SMP +static int Testcase(void) +{ + int arg = 0x2000; + int status; + pid_t pid; + void *stack; + char *stackTop; + int ret; + + int shmid = shmget(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0600); // 0600 config of shmget + ICUNIT_ASSERT_NOT_EQUAL(shmid, -1, shmid); + + g_shmptr = (int *)shmat(shmid, nullptr, 0); + ICUNIT_ASSERT_NOT_EQUAL(g_shmptr, reinterpret_cast(-1), g_shmptr); + + *g_shmptr = 0; + + g_ppid = getppid(); + printf("testcase ppid : %d\n", g_ppid); + + stack = malloc(arg); + ICUNIT_GOTO_NOT_EQUAL(stack, NULL, stack, EXIT1); + + stackTop = reinterpret_cast(reinterpret_cast(stack) + arg); + pid = clone(TestThread, (void *)stackTop, CLONE_PARENT | CLONE_VFORK, &arg); + + ICUNIT_GOTO_EQUAL(*g_shmptr, 100, *g_shmptr, EXIT2); // 100, assert g_shmptr equal to this. + + ret = waitpid(pid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, -1, ret, EXIT2); + +EXIT2: + free(stack); + +EXIT1: + shmdt(g_shmptr); + shmctl(shmid, IPC_RMID, NULL); + + return 0; +} + +void ItTestProcess051(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_051", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_052.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_052.cpp new file mode 100644 index 00000000..f4f13a43 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_052.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" +#include "sys/shm.h" + +static int *g_shmptr = NULL; +static int g_ppid; +static void *TestThread(void *arg) +{ + int data = *((int *)arg); + int ret = 0; + + pid_t ppid = getppid(); + + printf("TestThread ppid : %d g_ppid : %d\n", ppid, g_ppid); + + ICUNIT_ASSERT_EQUAL(ppid, g_ppid, g_ppid); + + *g_shmptr = 100; // 100, set shared num. + return NULL; +} + +// This testcase us used for undefination of LOSCFG_USER_TEST_SMP +static int Testcase(void) +{ + int arg = 0x2000; + int status; + + int shmid = shmget(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0600); // 0600 config of shmget + ICUNIT_ASSERT_NOT_EQUAL(shmid, -1, shmid); + + g_shmptr = (int *)shmat(shmid, nullptr, 0); + ICUNIT_ASSERT_NOT_EQUAL(g_shmptr, static_cast(-1), g_shmptr); + + *g_shmptr = 0; + + g_ppid = getppid(); + printf("testcase ppid : %d\n", g_ppid); + + void *stack = malloc(arg); + ICUNIT_GOTO_NOT_EQUAL(stack, NULL, stack, EXIT1); + + char *stackTop = static_cast(static_cast(stack) + arg); + pid_t pid = clone(TestThread, (char *)stackTop, CLONE_PARENT | CLONE_VFORK | CLONE_FILES, &arg); + + ICUNIT_GOTO_EQUAL(*g_shmptr, 100, *g_shmptr, EXIT2); // 100, assert g_shmptr equal to this. + + int ret = waitpid(pid, &status, NULL); + ICUNIT_GOTO_EQUAL(ret, -1, ret, EXIT2); + +EXIT2: + free(stack); + +EXIT1: + shmdt(g_shmptr); + shmctl(shmid, IPC_RMID, NULL); + + return 0; +} + +void ItTestProcess052(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_052", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_053.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_053.cpp new file mode 100644 index 00000000..d0a15c46 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_053.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static int g_signal = 0; + +static void Handler(int sig) +{ + g_signal = sig; +} + +static int TestCase(void) +{ + void (*retSig)(int); + int status; + int ret; + retSig = signal(SIGUSR1, Handler); + ICUNIT_ASSERT_NOT_EQUAL(retSig, SIG_ERR, retSig); + + pid_t pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + + if (pid == 0) { + ret = killpg(getpgrp(), SIGUSR1); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + exit(10); // 10, exit args + } + + while (g_signal == 0) { + sleep(1); + } + ICUNIT_ASSERT_EQUAL(g_signal, SIGUSR1, g_signal); + + ret = wait(&status); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(status, 10, status); // 10, assert that function Result is equal to this. + + return 0; +EXIT: + return 1; +} + +void ItTestProcess053(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_053", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_055.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_055.cpp new file mode 100644 index 00000000..30ce7ed1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_055.cpp @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static int Child1(void) +{ + int ret; + siginfo_t info = { 0 }; + + pid_t pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + if (pid == 0) { + ret = kill(getpid(), SIGKILL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + } + + ret = waitid(P_PID, pid, &info, WEXITED); + + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(info.si_status, SIGKILL, info.si_status); + ICUNIT_ASSERT_EQUAL(info.si_code, 2, info.si_code); // 2, assert that function Result is equal to this. + ICUNIT_ASSERT_EQUAL(info.si_pid, pid, info.si_pid); + exit(8); // 8, exit args +EXIT: + return 0; +} + +static int TestCase(void) +{ + pid_t pid; + int status; + int ret; + pid = fork(); + + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + if (pid == 0) { + Child1(); + printf("[Failed] - [Errline : %d RetCode : 0x%x\n", g_iCunitErrLineNo, g_iCunitErrCode); + exit(g_iCunitErrLineNo); + } else { + siginfo_t info = { 0 }; + + ret = waitid(P_ALL, getpgrp(), &info, WEXITED); + + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(info.si_status, 8, info.si_status); // 8, assert that function Result is equal to this. + ICUNIT_ASSERT_EQUAL(info.si_code, 1, info.si_code); + ICUNIT_ASSERT_EQUAL(info.si_pid, pid, info.si_pid); + + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + + if (pid == 0) { + exit(11); // 11, exit args + } + + sleep(1); + + ret = waitid(P_PGID, getpgrp(), &info, WNOHANG); + + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(info.si_status, 11, info.si_status); // 11, assert that function Result is equal to this. + ICUNIT_ASSERT_EQUAL(info.si_code, 1, info.si_code); + ICUNIT_ASSERT_EQUAL(info.si_pid, pid, info.si_pid); + } + return 0; +EXIT: + return 1; +} + +void ItTestProcess055(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_055", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_056.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_056.cpp new file mode 100644 index 00000000..d2ca28cd --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_056.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" +#include + +static int TestCase(void) +{ + pid_t pid; + int ret; + int status = 0; + char *argv1[] = {"tftp", NULL}; + + ret = posix_spawn(&pid, "/bin/tftp", NULL, NULL, argv1, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + + return 0; +} + +void ItTestProcess056(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_056", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_057.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_057.cpp new file mode 100644 index 00000000..e24af5c4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_057.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" +#include + +static int TestCase(void) +{ + pid_t pid; + int ret; + int status = 0; + char *argv1[] = {"tftp", NULL}; + + ret = posix_spawnp(&pid, "tftp", NULL, NULL, argv1, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + + return 0; +} + +void ItTestProcess057(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_057", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_058.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_058.cpp new file mode 100644 index 00000000..be042a22 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_058.cpp @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" +#include + +static const int HIGH_PRIORITY = 10; // 10, set high prio. + +static int TestSpawnAttrDef(posix_spawnattr_t *attr) +{ + sigset_t signalset; + sigset_t signalset1; + int ret; + + ret = sigemptyset(&signalset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = sigaddset(&signalset, SIGPIPE); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = posix_spawnattr_setsigdefault(attr, &signalset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + posix_spawnattr_getsigdefault(attr, &signalset1); + ret = memcmp(&signalset, &signalset1, sizeof(sigset_t)); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = sigismember(&signalset, SIGPIPE); + ICUNIT_GOTO_EQUAL(ret, 1, ret, EXIT); + return 0; +EXIT: + return 1; +} + +static int TestSpawnAttrMask(posix_spawnattr_t *attr) +{ + sigset_t signalset; + sigset_t signalset1; + int ret; + + ret = sigemptyset(&signalset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = sigaddset(&signalset, SIGPIPE); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = posix_spawnattr_setsigmask(attr, &signalset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + posix_spawnattr_getsigmask(attr, &signalset1); + ret = memcmp(&signalset, &signalset1, sizeof(sigset_t)); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = sigismember(&signalset, SIGPIPE); + ICUNIT_GOTO_EQUAL(ret, 1, ret, EXIT); + return 0; +EXIT: + return 1; +} + +static int TestSpawnAttrGroup(posix_spawnattr_t *attr) +{ + pid_t val = -1; + pid_t pid = getpgrp(); + int ret; + posix_spawnattr_getpgroup(attr, &val); + ICUNIT_GOTO_EQUAL(val, 0, val, EXIT); + + val = getpgid(getpid()); + ret = posix_spawnattr_setpgroup(attr, val); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + val = -1; + + posix_spawnattr_getpgroup(attr, &val); + ICUNIT_GOTO_EQUAL(val, pid, val, EXIT); + return 0; +EXIT: + return 1; +} + +static int TestSpawnAttrPrio(posix_spawnattr_t *attr) +{ + struct sched_param val = { -1 }; + struct sched_param val1 = { -1 }; + int ret; + posix_spawnattr_getschedparam(attr, &val); + ICUNIT_GOTO_EQUAL(val.sched_priority, 0, ret, EXIT); + + val.sched_priority = HIGH_PRIORITY; + ret = posix_spawnattr_setschedparam(attr, &val); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + posix_spawnattr_getschedparam(attr, &val1); + ICUNIT_GOTO_EQUAL(val1.sched_priority, HIGH_PRIORITY, ret, EXIT); + + return 0; +EXIT: + return 1; +} + +static int TestSpawnAttrPol(posix_spawnattr_t *attr) +{ + int val = -1; + int ret; + + posix_spawnattr_getschedpolicy(attr, &val); + ICUNIT_GOTO_EQUAL(val, 0, val, EXIT); + + val = SCHED_RR; + ret = posix_spawnattr_setschedpolicy(attr, val); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + val = -1; + + posix_spawnattr_getschedpolicy(attr, &val); + ICUNIT_GOTO_EQUAL(val, SCHED_RR, val, EXIT); + + ret = TestSpawnAttrPrio(attr); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + return 0; +EXIT: + return 1; +} + +static int TestSpawnAttr(short flag) +{ + pid_t pid; + posix_spawnattr_t attr; + int status = 1; + char *argv1[] = {"tftp", NULL}; + short iflag = -1; + int ret; + + ret = posix_spawnattr_init(&attr); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + posix_spawnattr_getflags(&attr, &iflag); + ICUNIT_GOTO_EQUAL(iflag, 0, iflag, EXIT); + + ret = posix_spawnattr_setflags(&attr, flag); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + iflag = -1; + + posix_spawnattr_getflags(&attr, &iflag); + ICUNIT_GOTO_EQUAL(iflag, flag, iflag, EXIT); + + if (POSIX_SPAWN_SETSIGDEF == flag) { + ret = TestSpawnAttrDef(&attr); + } else if (POSIX_SPAWN_SETSIGMASK == flag) { + ret = TestSpawnAttrMask(&attr); + } else if (POSIX_SPAWN_SETPGROUP == flag) { + ret = TestSpawnAttrGroup(&attr); + } else if (POSIX_SPAWN_SETSCHEDPARAM == flag) { + ret = TestSpawnAttrPrio(&attr); + } else if (POSIX_SPAWN_SETSCHEDULER == flag) { + ret = TestSpawnAttrPol(&attr); + } + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = posix_spawn(&pid, "/bin/tftp", NULL, &attr, argv1, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = posix_spawnattr_destroy(&attr); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = waitpid(pid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT); + + return 0; +EXIT: + return 1; +} + +static int TestCase(void) +{ + int ret; + + ret = TestSpawnAttr(POSIX_SPAWN_RESETIDS); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = TestSpawnAttr(POSIX_SPAWN_SETPGROUP); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = TestSpawnAttr(POSIX_SPAWN_SETSIGDEF); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = TestSpawnAttr(POSIX_SPAWN_SETSIGMASK); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = TestSpawnAttr(POSIX_SPAWN_SETSCHEDPARAM); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = TestSpawnAttr(POSIX_SPAWN_SETSCHEDULER); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + return 0; +EXIT: + return 1; +} + +void ItTestProcess058(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_058", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_059.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_059.cpp new file mode 100644 index 00000000..0eff40c7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_059.cpp @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" +#include + +static const int HIGH_PRIORITY = 31; + +static int TestSpawnAttrDef(posix_spawnattr_t *attr) +{ + sigset_t signalset; + sigset_t signalset1; + int ret; + + ret = sigemptyset(&signalset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = sigaddset(&signalset, SIGPIPE); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = posix_spawnattr_setsigdefault(attr, &signalset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + posix_spawnattr_getsigdefault(attr, &signalset1); + ret = memcmp(&signalset, &signalset1, sizeof(sigset_t)); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = sigismember(&signalset, SIGPIPE); + ICUNIT_GOTO_EQUAL(ret, 1, ret, EXIT); + return 0; +EXIT: + return 1; +} + +static int TestSpawnAttrMask(posix_spawnattr_t *attr) +{ + sigset_t signalset; + sigset_t signalset1; + int ret; + + ret = sigemptyset(&signalset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = sigaddset(&signalset, SIGPIPE); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = posix_spawnattr_setsigmask(attr, &signalset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + posix_spawnattr_getsigmask(attr, &signalset1); + ret = memcmp(&signalset, &signalset1, sizeof(sigset_t)); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = sigismember(&signalset, SIGPIPE); + ICUNIT_GOTO_EQUAL(ret, 1, ret, EXIT); + return 0; +EXIT: + return 1; +} + +static int TestSpawnAttrGroup(posix_spawnattr_t *attr) +{ + pid_t val = -1; + pid_t pid = getpgrp(); + int ret; + posix_spawnattr_getpgroup(attr, &val); + ICUNIT_GOTO_EQUAL(val, 0, val, EXIT); + + val = getpgid(getpid()); + ret = posix_spawnattr_setpgroup(attr, val); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + val = -1; + + posix_spawnattr_getpgroup(attr, &val); + ICUNIT_GOTO_EQUAL(val, pid, val, EXIT); + return 0; +EXIT: + return 1; +} + +static int TestSpawnAttrPrio(posix_spawnattr_t *attr) +{ + struct sched_param val = { -1 }; + struct sched_param val1 = { -1 }; + int ret; + posix_spawnattr_getschedparam(attr, &val); + ICUNIT_GOTO_EQUAL(val.sched_priority, 0, ret, EXIT); + + val.sched_priority = HIGH_PRIORITY; + ret = posix_spawnattr_setschedparam(attr, &val); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + posix_spawnattr_getschedparam(attr, &val1); + ICUNIT_GOTO_EQUAL(val1.sched_priority, HIGH_PRIORITY, ret, EXIT); + + return 0; +EXIT: + return 1; +} + +static int TestSpawnAttrPol(posix_spawnattr_t *attr) +{ + int val = -1; + int ret; + + posix_spawnattr_getschedpolicy(attr, &val); + ICUNIT_GOTO_EQUAL(val, 0, val, EXIT); + + val = SCHED_RR; + ret = posix_spawnattr_setschedpolicy(attr, val); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + val = -1; + + posix_spawnattr_getschedpolicy(attr, &val); + ICUNIT_GOTO_EQUAL(val, SCHED_RR, val, EXIT); + + ret = TestSpawnAttrPrio(attr); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + return 0; +EXIT: + return 1; +} + +static int TestSpawnpAttr(short flag) +{ + pid_t pid; + posix_spawnattr_t attr; + int status = 1; + char *argv1[] = {"tftp", NULL}; + short iflag = -1; + int ret; + + ret = posix_spawnattr_init(&attr); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + posix_spawnattr_getflags(&attr, &iflag); + ICUNIT_GOTO_EQUAL(iflag, 0, iflag, EXIT); + + ret = posix_spawnattr_setflags(&attr, flag); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + iflag = -1; + + posix_spawnattr_getflags(&attr, &iflag); + ICUNIT_GOTO_EQUAL(iflag, flag, iflag, EXIT); + + if (POSIX_SPAWN_SETSIGDEF == flag) { + ret = TestSpawnAttrDef(&attr); + } else if (POSIX_SPAWN_SETSIGMASK == flag) { + ret = TestSpawnAttrMask(&attr); + } else if (POSIX_SPAWN_SETPGROUP == flag) { + ret = TestSpawnAttrGroup(&attr); + } else if (POSIX_SPAWN_SETSCHEDPARAM == flag) { + ret = TestSpawnAttrPrio(&attr); + } else if (POSIX_SPAWN_SETSCHEDULER == flag) { + ret = TestSpawnAttrPol(&attr); + } + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = posix_spawnp(&pid, "/bin/tftp", NULL, &attr, argv1, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = posix_spawnattr_destroy(&attr); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = waitpid(pid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT); + + return 0; +EXIT: + return 1; +} + +static int TestCase(void) +{ + int ret; + + ret = TestSpawnpAttr(POSIX_SPAWN_RESETIDS); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = TestSpawnpAttr(POSIX_SPAWN_SETSIGDEF); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = TestSpawnpAttr(POSIX_SPAWN_SETSIGMASK); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = TestSpawnpAttr(POSIX_SPAWN_SETSCHEDPARAM); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = TestSpawnpAttr(POSIX_SPAWN_SETSCHEDULER); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = TestSpawnpAttr(POSIX_SPAWN_SETPGROUP); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + return 0; +EXIT: + return 1; +} + +void ItTestProcess059(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_059", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_060.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_060.cpp new file mode 100644 index 00000000..6f96f65c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_060.cpp @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" +#include + +static int TestGroupError(void) +{ + int ret; + posix_spawnattr_t attr; + + posix_spawnattr_init(&attr); + posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETPGROUP); + posix_spawnattr_setpgroup(&attr, 1); + ret = posix_spawnp(NULL, "/bin/tftp", NULL, &attr, NULL, NULL); + ICUNIT_ASSERT_EQUAL(ret, EPERM, ret); + + posix_spawnattr_setpgroup(&attr, 65); // 65, set group num. + ret = posix_spawnp(NULL, "/bin/tftp", NULL, &attr, NULL, NULL); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + return 0; +} +static int TestPolError(void) +{ + int ret; + posix_spawnattr_t attr; + struct sched_param val = { -1 }; + + posix_spawnattr_init(&attr); + posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSCHEDULER); + val.sched_priority = 15; // 15, set pthread priority. + posix_spawnattr_setschedparam(&attr, &val); + posix_spawnattr_setschedpolicy(&attr, SCHED_FIFO); + ret = posix_spawnp(NULL, "/bin/tftp", NULL, &attr, NULL, NULL); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + return 0; +} +static int TestPrioError(void) +{ + int ret; + posix_spawnattr_t attr; + struct sched_param val = { -1 }; + + posix_spawnattr_init(&attr); + posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSCHEDPARAM); + posix_spawnattr_getschedparam(&attr, &val); + + val.sched_priority = 0; + ret = posix_spawnattr_setschedparam(&attr, &val); + ret = posix_spawnp(NULL, "/bin/tftp", NULL, &attr, NULL, NULL); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + val.sched_priority = 32; // 32, set pthread priority. + ret = posix_spawnattr_setschedparam(&attr, &val); + ret = posix_spawnp(NULL, "/bin/tftp", NULL, &attr, NULL, NULL); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + return 0; +} +static int TestCase(void) +{ + pid_t pid; + posix_spawnattr_t attr; + int status = 1; + int ret; + + posix_spawnattr_init(&attr); + + ret = posix_spawnattr_setflags(&attr, -1); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = posix_spawnattr_setflags(&attr, 128); // 128, set flags num. + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = posix_spawnattr_setflags(&attr, 0xff); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = posix_spawnattr_setschedpolicy(&attr, 0); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = posix_spawnattr_setschedpolicy(&attr, 3); // 3, set policy num. + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + posix_spawnattr_destroy(&attr); + + ret = TestGroupError(); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = TestPolError(); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = TestPrioError(); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return 0; +} + +void ItTestProcess060(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_060", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_062.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_062.cpp new file mode 100644 index 00000000..ad4128b1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_062.cpp @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" +#include "sys/shm.h" + +static volatile int *g_shmptr = NULL; + +static void Handler(int sig) +{ + (*g_shmptr)++; +} + +static int TestCase(void) +{ + int status; + (void)signal(SIGUSR2, Handler); + int ret; + pid_t pid; + + int shmid = shmget(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0600); // 0600 config of shmget + ICUNIT_ASSERT_NOT_EQUAL(shmid, -1, shmid); + + g_shmptr = (int *)shmat(shmid, nullptr, 0); + ICUNIT_GOTO_NOT_EQUAL(g_shmptr, (int *)-1, g_shmptr, EXIT); + + *g_shmptr = 0; + + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + + if (pid == 0) { + pid_t pid1 = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid1, 0, 100000, pid1, EXIT); // 100000, assert pid1 equal to this. + + if (pid1 == 0) { + ret = killpg(getpgrp(), SIGUSR2); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + while (*g_shmptr < 3) { // 3, Number of cycles. + sleep(1); + } + + exit(11); // 11, exit args + } + + while (*g_shmptr < 3) { // 3, Number of cycles. + sleep(1); + } + + ret = waitpid(pid1, &status, 0); + ICUNIT_GOTO_EQUAL(ret, pid1, ret, EXIT); + + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 11, status, EXIT); // 11, assert status equal to this. + + exit(10); // 10, exit args + } + + while (*g_shmptr < 3) { // 3, wait function running. + sleep(1); + } + ICUNIT_ASSERT_EQUAL(*g_shmptr, 3, *g_shmptr); // 3, assert that function Result is equal to this. + + ret = waitpid(pid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT); + + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 10, status, EXIT); // 10, assert that function Result is equal to this. + + shmdt(static_cast(const_cast(g_shmptr))); + shmctl(shmid, IPC_RMID, NULL); + + return 0; +EXIT: + shmdt(static_cast(const_cast(g_shmptr))); + shmctl(shmid, IPC_RMID, NULL); + return 1; +} + +void ItTestProcess062(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_062", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_063.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_063.cpp new file mode 100644 index 00000000..86353e0a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_063.cpp @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" +#include + +static const int FILE_NAME_BYTES = 200; // 200, set test name len. +static const int LONG_FILE_NAME_BYTES = 500; // 500, set test name len. +static const int RANDOM_MAX = 127; // 127, set random max. +static const unsigned int INVALID_USER_VADDR = 0x1200000; + +static int GetRandomNumber(int max) +{ + int n = 0; + + if (max > 0) { + n = rand() % max; + } + + return n + 1; +} + +static void GetRandomData(char **buf, int bufSize) +{ + char *p = *buf; + int i; + + srand(static_cast(time(0))); + for (i = 0; i < bufSize - 1; ++i) { + int r = GetRandomNumber(RANDOM_MAX); + *(p + i) = static_cast(r); + } + *(p + i) = static_cast(0); +} + +static int TestCase(VOID) +{ + int ret; + int err; + pid_t pid; + char *fileName = NULL; + char *childFileName = NULL; + char **childArgv = NULL; + char **childEnvp = NULL; + + ret = posix_spawn(&pid, NULL, NULL, NULL, NULL, NULL); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + childFileName = reinterpret_cast(1); + ret = posix_spawn(&pid, childFileName, NULL, NULL, NULL, NULL); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + childArgv = reinterpret_cast(1); + ret = posix_spawn(&pid, "/usr/bin/testsuits_app", NULL, NULL, childArgv, NULL); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + childEnvp = reinterpret_cast(1); + ret = posix_spawn(&pid, "/usr/bin/testsuits_app", NULL, NULL, NULL, childEnvp); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = posix_spawn(&pid, "/bin", NULL, NULL, NULL, NULL); + ICUNIT_ASSERT_EQUAL(ret, ENOENT, ret); + + fileName = static_cast(malloc(FILE_NAME_BYTES)); + ICUNIT_ASSERT_NOT_EQUAL(fileName, NULL, fileName); + GetRandomData(&fileName, FILE_NAME_BYTES); + ret = posix_spawn(&pid, fileName, NULL, NULL, NULL, NULL); + free(fileName); + ICUNIT_ASSERT_EQUAL(ret, ENOENT, ret); + + fileName = static_cast(malloc(LONG_FILE_NAME_BYTES)); + ICUNIT_ASSERT_NOT_EQUAL(fileName, NULL, fileName); + GetRandomData(&fileName, LONG_FILE_NAME_BYTES); + ret = posix_spawn(&pid, fileName, NULL, NULL, NULL, NULL); + free(fileName); + ICUNIT_ASSERT_EQUAL(ret, ENAMETOOLONG, ret); + + ret = posix_spawn(&pid, reinterpret_cast(INVALID_USER_VADDR), nullptr, nullptr, nullptr, nullptr); + ICUNIT_ASSERT_EQUAL(ret, EFAULT, ret); + + return 0; +} +void ItTestProcess063(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_063", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_064.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_064.cpp new file mode 100644 index 00000000..ace31384 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_064.cpp @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" +#include + +static const int FILE_NAME_BYTES = 200; // 200, set test name len. +static const int LONG_FILE_NAME_BYTES = 500; // 500, set test name len. +static const int RANDOM_MAX = 127; // 127, set random max. +static const unsigned int INVALID_USER_VADDR = 0x1200000; + +static int GetRandomNumber(int max) +{ + int n = 0; + + if (max > 0) { + n = rand() % max; + } + + return n + 1; +} + +static void GetRandomData(char **buf, int bufSize) +{ + char *p = *buf; + int i; + + srand(static_cast(time(0))); + for (i = 0; i < bufSize - 1; ++i) { + int r = GetRandomNumber(RANDOM_MAX); + *(p + i) = static_cast(r); + } + *(p + i) = static_cast(0); +} + +static int TestCase(VOID) +{ + int ret; + int err; + pid_t pid; + char *fileName = NULL; + char *childFileName = NULL; + char **childArgv = NULL; + char **childEnvp = NULL; + + childArgv = reinterpret_cast(1); + ret = posix_spawnp(&pid, "/usr/bin/testsuits_app", NULL, NULL, childArgv, NULL); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + childEnvp = reinterpret_cast(1); + ret = posix_spawnp(&pid, "/usr/bin/testsuits_app", NULL, NULL, NULL, childEnvp); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = posix_spawnp(&pid, "/bin", NULL, NULL, NULL, NULL); + ICUNIT_ASSERT_EQUAL(ret, ENOENT, ret); + + fileName = static_cast(malloc(FILE_NAME_BYTES)); + ICUNIT_ASSERT_NOT_EQUAL(fileName, NULL, fileName); + GetRandomData(&fileName, FILE_NAME_BYTES); + ret = posix_spawnp(&pid, fileName, NULL, NULL, NULL, NULL); + free(fileName); + ICUNIT_ASSERT_EQUAL(ret, ENOENT, ret); + + fileName = static_cast(malloc(LONG_FILE_NAME_BYTES)); + ICUNIT_ASSERT_NOT_EQUAL(fileName, NULL, fileName); + GetRandomData(&fileName, LONG_FILE_NAME_BYTES); + ret = posix_spawnp(&pid, fileName, NULL, NULL, NULL, NULL); + free(fileName); + ICUNIT_ASSERT_EQUAL(ret, ENAMETOOLONG, ret); + + ret = posix_spawnp(&pid, "test_spawnp", NULL, NULL, NULL, NULL); + ICUNIT_ASSERT_EQUAL(ret, ENOENT, ret); + + return 0; +} +void ItTestProcess064(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_064", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_065.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_065.cpp new file mode 100644 index 00000000..15f3fd82 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_065.cpp @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" +#include + +static int TestGroupError(void) +{ + int ret; + posix_spawnattr_t attr; + + posix_spawnattr_init(&attr); + posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETPGROUP); + posix_spawnattr_setpgroup(&attr, 1); + ret = posix_spawn(NULL, "/bin/tftp", NULL, &attr, NULL, NULL); + ICUNIT_ASSERT_EQUAL(ret, EPERM, ret); + + posix_spawnattr_setpgroup(&attr, 65); // 65, set group num. + ret = posix_spawn(NULL, "/bin/tftp", NULL, &attr, NULL, NULL); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + return 0; +} +static int TestPolError(void) +{ + int ret; + posix_spawnattr_t attr; + struct sched_param val = { -1 }; + + posix_spawnattr_init(&attr); + posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSCHEDULER); + val.sched_priority = 15; // 15, set pthread priority. + posix_spawnattr_setschedparam(&attr, &val); + posix_spawnattr_setschedpolicy(&attr, SCHED_FIFO); + ret = posix_spawn(NULL, "/bin/tftp", NULL, &attr, NULL, NULL); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + return 0; +} +static int TestPrioError(void) +{ + int ret; + posix_spawnattr_t attr; + struct sched_param val = { -1 }; + + posix_spawnattr_init(&attr); + posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSCHEDPARAM); + posix_spawnattr_getschedparam(&attr, &val); + + val.sched_priority = 0; + ret = posix_spawnattr_setschedparam(&attr, &val); + ret = posix_spawn(NULL, "/bin/tftp", NULL, &attr, NULL, NULL); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + val.sched_priority = 32; // 32, set pthread priority. + ret = posix_spawnattr_setschedparam(&attr, &val); + ret = posix_spawn(NULL, "/bin/tftp", NULL, &attr, NULL, NULL); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + return 0; +} +static int TestCase(void) +{ + pid_t pid; + posix_spawnattr_t attr; + int status = 1; + int ret; + + posix_spawnattr_init(&attr); + + ret = posix_spawnattr_setflags(&attr, -1); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = posix_spawnattr_setflags(&attr, 128); // 128, set group num. + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = posix_spawnattr_setflags(&attr, 0xff); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = posix_spawnattr_setschedpolicy(&attr, 0); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = posix_spawnattr_setschedpolicy(&attr, 3); // 3, set policy num. + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + posix_spawnattr_destroy(&attr); + + ret = TestGroupError(); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = TestPolError(); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = TestPrioError(); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return 0; +} + +void ItTestProcess065(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_065", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_066.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_066.cpp new file mode 100644 index 00000000..f12bd0d3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_066.cpp @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" +#include + +static const int HIGH_PRIORITY = 10; +static const int NUMMAX = 16; + +static int TestSpawnAttrGroup(posix_spawnattr_t *attr) +{ + pid_t val = -1; + pid_t pid = getpgrp(); + int ret; + posix_spawnattr_getpgroup(attr, &val); + ICUNIT_GOTO_EQUAL(val, 0, val, EXIT); + + val = getpgid(getpid()); + ret = posix_spawnattr_setpgroup(attr, val); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + val = -1; + + posix_spawnattr_getpgroup(attr, &val); + ICUNIT_GOTO_EQUAL(val, pid, val, EXIT); + return 0; +EXIT: + return 1; +} + +static int TestSpawnAttrPrio(posix_spawnattr_t *attr) +{ + struct sched_param val = { -1 }; + struct sched_param val1 = { -1 }; + int ret; + posix_spawnattr_getschedparam(attr, &val); + ICUNIT_GOTO_EQUAL(val.sched_priority, 0, ret, EXIT); + + val.sched_priority = HIGH_PRIORITY; + ret = posix_spawnattr_setschedparam(attr, &val); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + posix_spawnattr_getschedparam(attr, &val1); + ICUNIT_GOTO_EQUAL(val1.sched_priority, HIGH_PRIORITY, ret, EXIT); + + return 0; +EXIT: + return 1; +} + +static int TestSpawnAttrPol(posix_spawnattr_t *attr) +{ + int val = -1; + int ret; + + posix_spawnattr_getschedpolicy(attr, &val); + ICUNIT_GOTO_EQUAL(val, 0, val, EXIT); + + val = SCHED_RR; + ret = posix_spawnattr_setschedpolicy(attr, val); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + val = -1; + + posix_spawnattr_getschedpolicy(attr, &val); + ICUNIT_GOTO_EQUAL(val, SCHED_RR, val, EXIT); + + ret = TestSpawnAttrPrio(attr); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + return 0; +EXIT: + return 1; +} + +static int TestSpawnAttr(short flag) +{ + pid_t pid; + posix_spawnattr_t attr; + int status = 1; + char *argv1[] = {"xxx", NULL}; + char temp[NUMMAX] = {0}; + char temp1[NUMMAX] = {0}; + short iflag = -1; + int ret; + int fd; + ret = posix_spawnattr_init(&attr); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + posix_spawnattr_getflags(&attr, &iflag); + ICUNIT_GOTO_EQUAL(iflag, 0, iflag, EXIT); + + ret = posix_spawnattr_setflags(&attr, flag); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + iflag = -1; + + posix_spawnattr_getflags(&attr, &iflag); + ICUNIT_GOTO_EQUAL(iflag, flag, iflag, EXIT); + + if (POSIX_SPAWN_SETPGROUP == flag) { + ret = TestSpawnAttrGroup(&attr); + argv1[0] = "group"; + } else if (POSIX_SPAWN_SETSCHEDPARAM == flag) { + ret = TestSpawnAttrPrio(&attr); + argv1[0] = "prio"; + } else if (POSIX_SPAWN_SETSCHEDULER == flag) { + ret = TestSpawnAttrPol(&attr); + argv1[0] = "pol"; + } else if (POSIX_SPAWN_RESETIDS == flag) { + argv1[0] = "ids"; + } + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = posix_spawn(&pid, "/storage/test_spawn", NULL, &attr, argv1, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = waitpid(pid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT); + + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 0, status, EXIT); + + fd = open("/storage/testspawnattr.txt", O_RDWR | O_CREAT, 0644); // 0644, open config + if (fd < 0) { + goto EXIT; + } + ret = read(fd, temp, NUMMAX); + ICUNIT_GOTO_EQUAL(ret, NUMMAX, ret, EXIT1); + + if (POSIX_SPAWN_SETPGROUP == flag) { + (void)sprintf_s(temp1, NUMMAX, "pgid = %d", attr.__pgrp); + } else if (POSIX_SPAWN_SETSCHEDPARAM == flag) { + (void)sprintf_s(temp1, NUMMAX, "prio = %d", attr.__prio); + } else if (POSIX_SPAWN_SETSCHEDULER == flag) { + (void)sprintf_s(temp1, NUMMAX, "pol = %d", attr.__pol); + } else if (POSIX_SPAWN_RESETIDS == flag) { + (void)sprintf_s(temp1, NUMMAX, "uid = %d", getuid()); + } + ret = strncmp(temp, temp1, strlen(temp)); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT1); + + close(fd); + unlink("/storage/testspawnattr.txt"); + return 0; +EXIT1: + unlink("/storage/testspawnattr.txt"); + close(fd); +EXIT: + return 1; +} + +static int TestCase(void) +{ + int ret; + + ret = TestSpawnAttr(POSIX_SPAWN_RESETIDS); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = TestSpawnAttr(POSIX_SPAWN_SETSCHEDPARAM); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = TestSpawnAttr(POSIX_SPAWN_SETSCHEDULER); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = TestSpawnAttr(POSIX_SPAWN_SETPGROUP); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + return 0; +EXIT: + return 1; +} + +void ItTestProcess066(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_066", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_067.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_067.cpp new file mode 100644 index 00000000..e561bece --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_067.cpp @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" +#include + +static const int HIGH_PRIORITY = 10; +static const int NUMMAX = 16; + +static int TestSpawnAttrGroup(posix_spawnattr_t *attr) +{ + pid_t val = -1; + pid_t pid = getpgrp(); + int ret; + posix_spawnattr_getpgroup(attr, &val); + ICUNIT_GOTO_EQUAL(val, 0, val, EXIT); + + val = getpgid(getpid()); + ret = posix_spawnattr_setpgroup(attr, val); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + val = -1; + + posix_spawnattr_getpgroup(attr, &val); + ICUNIT_GOTO_EQUAL(val, pid, val, EXIT); + return 0; +EXIT: + return 1; +} + +static int TestSpawnAttrPrio(posix_spawnattr_t *attr) +{ + struct sched_param val = { -1 }; + struct sched_param val1 = { -1 }; + int ret; + posix_spawnattr_getschedparam(attr, &val); + ICUNIT_GOTO_EQUAL(val.sched_priority, 0, ret, EXIT); + + val.sched_priority = HIGH_PRIORITY; + ret = posix_spawnattr_setschedparam(attr, &val); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + posix_spawnattr_getschedparam(attr, &val1); + ICUNIT_GOTO_EQUAL(val1.sched_priority, HIGH_PRIORITY, ret, EXIT); + + return 0; +EXIT: + return 1; +} + +static int TestSpawnAttrPol(posix_spawnattr_t *attr) +{ + int val = -1; + int ret; + + posix_spawnattr_getschedpolicy(attr, &val); + ICUNIT_GOTO_EQUAL(val, 0, val, EXIT); + + val = SCHED_RR; + ret = posix_spawnattr_setschedpolicy(attr, val); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + val = -1; + + posix_spawnattr_getschedpolicy(attr, &val); + ICUNIT_GOTO_EQUAL(val, SCHED_RR, val, EXIT); + + ret = TestSpawnAttrPrio(attr); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + return 0; +EXIT: + return 1; +} + +static int TestSpawnAttr(short flag) +{ + pid_t pid; + posix_spawnattr_t attr; + int status = 1; + char *argv1[] = {"xxx", NULL}; + char temp[NUMMAX] = {0}; + char temp1[NUMMAX] = {0}; + short iflag = -1; + int ret; + int fd; + + ret = posix_spawnattr_init(&attr); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + posix_spawnattr_getflags(&attr, &iflag); + ICUNIT_GOTO_EQUAL(iflag, 0, iflag, EXIT); + + ret = posix_spawnattr_setflags(&attr, flag); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + iflag = -1; + + posix_spawnattr_getflags(&attr, &iflag); + ICUNIT_GOTO_EQUAL(iflag, flag, iflag, EXIT); + + if (POSIX_SPAWN_SETPGROUP == flag) { + ret = TestSpawnAttrGroup(&attr); + argv1[0] = "group"; + } else if (POSIX_SPAWN_SETSCHEDPARAM == flag) { + ret = TestSpawnAttrPrio(&attr); + argv1[0] = "prio"; + } else if (POSIX_SPAWN_SETSCHEDULER == flag) { + ret = TestSpawnAttrPol(&attr); + argv1[0] = "pol"; + } else if (POSIX_SPAWN_RESETIDS == flag) { + argv1[0] = "ids"; + } + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = posix_spawnp(&pid, "/storage/test_spawn", NULL, &attr, argv1, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = waitpid(pid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT); + + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 0, status, EXIT); + + fd = open("/storage/testspawnattr.txt", O_RDWR | O_CREAT, 0644); // 0644, open config + ret = read(fd, temp, NUMMAX); + ICUNIT_GOTO_EQUAL(ret, NUMMAX, ret, EXIT1); + + if (POSIX_SPAWN_SETPGROUP == flag) { + (void)sprintf_s(temp1, NUMMAX, "pgid = %d", attr.__pgrp); + } else if (POSIX_SPAWN_SETSCHEDPARAM == flag) { + (void)sprintf_s(temp1, NUMMAX, "prio = %d", attr.__prio); + } else if (POSIX_SPAWN_SETSCHEDULER == flag) { + (void)sprintf_s(temp1, NUMMAX, "pol = %d", attr.__pol); + } else if (POSIX_SPAWN_RESETIDS == flag) { + (void)sprintf_s(temp1, NUMMAX, "uid = %d", getuid()); + } + ret = strncmp(temp, temp1, strlen(temp)); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT1); + + close(fd); + unlink("/storage/testspawnattr.txt"); + return 0; +EXIT1: + close(fd); + unlink("/storage/testspawnattr.txt"); +EXIT: + return 1; +} + +static int TestCase(void) +{ + int ret; + + ret = TestSpawnAttr(POSIX_SPAWN_RESETIDS); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = TestSpawnAttr(POSIX_SPAWN_SETSCHEDPARAM); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = TestSpawnAttr(POSIX_SPAWN_SETSCHEDULER); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = TestSpawnAttr(POSIX_SPAWN_SETPGROUP); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + return 0; +EXIT: + return 1; +} + +void ItTestProcess067(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_067", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_068.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_068.cpp new file mode 100644 index 00000000..f31338a7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_068.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" +#include + +static const int NUMMAX = 16; + +static int TestCase(void) +{ + char *envp[] = {"ABC=asddfg", NULL}; + char *argv1[] = {"envp", NULL}; + pid_t pid; + int status = 1; + char temp[NUMMAX] = {0}; + int fd; + + int ret = posix_spawn(&pid, "/storage/test_spawn", NULL, NULL, argv1, envp); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = waitpid(pid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT); + + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 0, status, EXIT); + + fd = open("/storage/testspawnattr.txt", O_RDWR | O_CREAT, 0644); // 0644, open config + ret = read(fd, temp, NUMMAX); + ICUNIT_GOTO_EQUAL(ret, NUMMAX, ret, EXIT1); + + ret = strncmp(temp, "ABC=asddfg", strlen(temp)); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT1); + + close(fd); + unlink("/storage/testspawnattr.txt"); + return 0; +EXIT1: + close(fd); + unlink("/storage/testspawnattr.txt"); +EXIT: + return 1; +} + +void ItTestProcess068(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_068", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_069.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_069.cpp new file mode 100644 index 00000000..df8ae063 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/full/process_test_069.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" +#include + +static const int NUMMAX = 16; + +static int TestCase(void) +{ + char *envp[] = {"ABC=asddfg", NULL}; + char *argv1[] = {"envp", NULL}; + pid_t pid; + int status = 1; + char temp[NUMMAX] = {0}; + int ret; + int fd; + + ret = posix_spawnp(&pid, "/storage/test_spawn", NULL, NULL, argv1, envp); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = waitpid(pid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT); + + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 0, status, EXIT); + + fd = open("/storage/testspawnattr.txt", O_RDWR | O_CREAT, 0644); // 0644, open config + ret = read(fd, temp, NUMMAX); + ICUNIT_GOTO_EQUAL(ret, NUMMAX, ret, EXIT1); + + ret = strncmp(temp, "ABC=asddfg", strlen(temp)); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT1); + + close(fd); + unlink("/storage/testspawnattr.txt"); + return 0; +EXIT1: + close(fd); + unlink("/storage/testspawnattr.txt"); +EXIT: + return 1; +} + +void ItTestProcess069(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_069", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/it_test_process.h b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/it_test_process.h new file mode 100644 index 00000000..ac487958 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/it_test_process.h @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef IT_TEST_PROCESS_H +#define IT_TEST_PROCESS_H + +#include "osTest.h" +#include "sys/resource.h" +#include "sys/wait.h" + +#define WAIT_PARENT_FIRST_TO_RUN(tick) usleep((tick)*10 * 1000) // 10, 1000, wait time. +#include "sys/syscall.h" + +static inline int Syscall(int nbr, int parm1, int parm2, int parm3, int parm4) +{ + register int reg7 __asm__("r7") = nbr; + register int reg3 __asm__("r3") = parm4; + register int reg2 __asm__("r2") = parm3; + register int reg1 __asm__("r1") = parm2; + register int reg0 __asm__("r0") = parm1; + + __asm__ __volatile__("svc 0" : "=r"(reg0) : "r"(reg7), "r"(reg0), "r"(reg1), "r"(reg2), "r"(reg3) : "memory"); + + return reg0; +} +extern INT32 g_iCunitErrCode; +extern INT32 g_iCunitErrLineNo; +extern int GetCpuCount(void); + +extern void Wait(const char *ptr, int scount); +extern void ItTestProcess001(void); +extern void ItTestProcess002(void); +extern void ItTestProcess004(void); +extern void ItTestProcess005(void); +extern void ItTestProcess006(void); +extern void ItTestProcess007(void); +extern void ItTestProcess008(void); +extern void ItTestProcess009(void); +extern void ItTestProcess010(void); +extern void ItTestProcess011(void); +extern void ItTestProcess012(void); +extern void ItTestProcess013(void); +extern void ItTestProcess014(void); +extern void ItTestProcess015(void); +extern void ItTestProcess016(void); +extern void ItTestProcess017(void); +extern void ItTestProcess018(void); +extern void ItTestProcess019(void); +extern void ItTestProcess020(void); +extern void ItTestProcess021(void); +extern void ItTestProcess022(void); +extern void ItTestProcess023(void); +extern void ItTestProcess024(void); +extern void ItTestProcess025(void); +extern void ItTestProcess026(void); +extern void ItTestProcess027(void); +extern void ItTestProcess029(void); +extern void ItTestProcess030(void); +extern void ItTestProcess031(void); +extern void ItTestProcess032(void); +extern void ItTestProcess033(void); +extern void ItTestProcess034(void); +extern void ItTestProcess035(void); +extern void ItTestProcess036(void); +extern void ItTestProcess037(void); +extern void ItTestProcess038(void); +extern void ItTestProcess039(void); +extern void ItTestProcess040(void); +extern void ItTestProcess041(void); +extern void ItTestProcess042(void); +extern void ItTestProcess043(void); +extern void ItTestProcess044(void); +extern void ItTestProcess045(void); +extern void ItTestProcess046(void); +extern void ItTestProcess047(void); +extern void ItTestProcess048(void); +extern void ItTestProcess049(void); +extern void ItTestProcess050(void); +extern void ItTestProcess051(void); +extern void ItTestProcess052(void); +extern void ItTestProcess053(void); +extern void ItTestProcess054(void); +extern void ItTestProcess055(void); +extern void ItTestProcess056(void); +extern void ItTestProcess057(void); +extern void ItTestProcess058(void); +extern void ItTestProcess059(void); +extern void ItTestProcess060(void); +extern void ItTestProcess061(void); +extern void ItTestProcess062(void); +extern void ItTestProcess063(void); +extern void ItTestProcess064(void); +extern void ItTestProcess065(void); +extern void ItTestProcess066(void); +extern void ItTestProcess067(void); +extern void ItTestProcess068(void); +extern void ItTestProcess069(void); +extern void ItTestProcessSmp001(void); +extern void ItTestProcessSmp002(void); +extern void ItTestProcessSmp003(void); +extern void ItTestProcessSmp004(void); +extern void ItTestProcessSmp005(void); +extern void ItTestProcessSmp006(void); +extern void ItTestProcessSmp007(void); +extern void ItTestProcessSmp008(void); +#endif diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/process_process_test.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/process_process_test.cpp new file mode 100644 index 00000000..67c398f5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/process_process_test.cpp @@ -0,0 +1,670 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "stdio.h" +#include +#include +#include "it_test_process.h" + +void Wait(const char *ptr, int scount) +{ + int count = 0xffffffff; + while (scount > 0) { + while (count > 0) { + printf("\r"); + count--; + } + count = 0xffffffff; + scount--; + if (ptr) { + printf("%s\n", ptr); + } + } +} + +int GetCpuCount(void) +{ + cpu_set_t cpuset; + + CPU_ZERO(&cpuset); + int temp = sched_getaffinity(getpid(), sizeof(cpu_set_t), &cpuset); + if (temp != 0) { + printf("%s %d Error : %d\n", __FUNCTION__, __LINE__, temp); + } + + return CPU_COUNT(&cpuset); +} + +using namespace testing::ext; +namespace OHOS { +class ProcessProcessTest : public testing::Test { +public: + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} +}; + +#if defined(LOSCFG_USER_TEST_SMOKE) +/* * + * @tc.name: it_test_process_001 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess001, TestSize.Level0) +{ + ItTestProcess001(); +} + +/* * + * @tc.name: it_test_process_002 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess002, TestSize.Level0) +{ + ItTestProcess002(); +} + +/* * + * @tc.name: it_test_process_004 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess004, TestSize.Level0) +{ + ItTestProcess004(); +} + +/* * + * @tc.name: it_test_process_005 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess005, TestSize.Level0) +{ + ItTestProcess005(); +} + +/* * + * @tc.name: it_test_process_006 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess006, TestSize.Level0) +{ + ItTestProcess006(); +} + +/* * + * @tc.name: it_test_process_008 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess008, TestSize.Level0) +{ + ItTestProcess008(); +} + +/* * + * @tc.name: it_test_process_010 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess010, TestSize.Level0) +{ + ItTestProcess010(); +} + +/* * + * @tc.name: it_test_process_009 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess009, TestSize.Level0) +{ + ItTestProcess009(); +} + +/* * + * @tc.name: it_test_process_011 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess011, TestSize.Level0) +{ + ItTestProcess011(); +} + +/* * + * @tc.name: it_test_process_012 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess012, TestSize.Level0) +{ + ItTestProcess012(); +} + +/* * + * @tc.name: it_test_process_013 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess013, TestSize.Level0) +{ + ItTestProcess013(); +} + +/* * + * @tc.name: it_test_process_014 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess014, TestSize.Level0) +{ + ItTestProcess014(); +} + +/* * + * @tc.name: it_test_process_015 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess015, TestSize.Level0) +{ + ItTestProcess015(); +} + +/* * + * @tc.name: it_test_process_016 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess016, TestSize.Level0) +{ + ItTestProcess016(); +} + +/* * + * @tc.name: it_test_process_017 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess017, TestSize.Level0) +{ + ItTestProcess017(); +} + +/* * + * @tc.name: it_test_process_018 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess018, TestSize.Level0) +{ + ItTestProcess018(); +} + +/* * + * @tc.name: it_test_process_019 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess019, TestSize.Level0) +{ + ItTestProcess019(); +} + +/* * + * @tc.name: it_test_process_020 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess020, TestSize.Level0) +{ + ItTestProcess020(); +} + +/* * + * @tc.name: it_test_process_021 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess021, TestSize.Level0) +{ + ItTestProcess021(); +} + +/* * + * @tc.name: it_test_process_022 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess022, TestSize.Level0) +{ + ItTestProcess022(); +} + +/* * + * @tc.name: it_test_process_023 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess023, TestSize.Level0) +{ + ItTestProcess023(); +} + +/* * + * @tc.name: it_test_process_024 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess024, TestSize.Level0) +{ + ItTestProcess024(); +} + +/* * + * @tc.name: it_test_process_025 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess025, TestSize.Level0) +{ + ItTestProcess025(); +} + +/* * + * @tc.name: it_test_process_026 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess026, TestSize.Level0) +{ + ItTestProcess026(); +} + +/* * + * @tc.name: it_test_process_027 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess027, TestSize.Level0) +{ + ItTestProcess027(); +} + +/* * + * @tc.name: it_test_process_029 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess029, TestSize.Level0) +{ + ItTestProcess029(); +} + +/* * + * @tc.name: it_test_process_030 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess030, TestSize.Level0) +{ + ItTestProcess030(); +} + +/* * + * @tc.name: it_test_process_038 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess038, TestSize.Level0) +{ + ItTestProcess038(); +} + +/* * + * @tc.name: it_test_process_039 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess039, TestSize.Level0) +{ + ItTestProcess039(); +} + +/* * + * @tc.name: it_test_process_043 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess043, TestSize.Level0) +{ + ItTestProcess043(); +} + +/* * + * @tc.name: it_test_process_044 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess044, TestSize.Level0) +{ + ItTestProcess044(); +} + +/* * + * @tc.name: it_test_process_045 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess045, TestSize.Level0) +{ + ItTestProcess045(); +} + +/* * + * @tc.name: it_test_process_046 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess046, TestSize.Level0) +{ + ItTestProcess046(); +} + +/* * + * @tc.name: it_test_process_047 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess047, TestSize.Level0) +{ + ItTestProcess047(); +} + +/* * + * @tc.name: it_test_process_048 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess048, TestSize.Level0) +{ + ItTestProcess048(); +} + +/* * + * @tc.name: it_test_process_054 + * @tc.desc: function for waitid: The waitid parameter is incorrect and the error code is verified. + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess054, TestSize.Level0) +{ + ItTestProcess054(); +} + +/* * + * @tc.name: it_test_process_061 + * @tc.desc: function for killpg: The killpg parameter is incorrect and the error code is verified. + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess061, TestSize.Level0) +{ + ItTestProcess061(); +} + +#ifdef LOSCFG_USER_TEST_SMP +/* * + * @tc.name: it_test_process_smp_001 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcessSmp001, TestSize.Level0) +{ + ItTestProcessSmp001(); +} + +/* * + * @tc.name: it_test_process_smp_002 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcessSmp002, TestSize.Level0) +{ + ItTestProcessSmp002(); +} + +/* * + * @tc.name: it_test_process_smp_003 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcessSmp003, TestSize.Level0) +{ + ItTestProcessSmp003(); +} + +/* * + * @tc.name: it_test_process_smp_004 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcessSmp004, TestSize.Level0) +{ + ItTestProcessSmp004(); +} + +/* * + * @tc.name: it_test_process_smp_005 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcessSmp005, TestSize.Level0) +{ + ItTestProcessSmp005(); +} + +/* * + * @tc.name: it_test_process_smp_006 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcessSmp006, TestSize.Level0) +{ + ItTestProcessSmp006(); +} + +/* * + * @tc.name: it_test_process_smp_007 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcessSmp007, TestSize.Level0) +{ + ItTestProcessSmp007(); +} + +/* * + * @tc.name: it_test_process_smp_008 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcessSmp008, TestSize.Level0) +{ + ItTestProcessSmp008(); +} +#endif +#endif + +#if defined(LOSCFG_USER_TEST_FULL) +/* * + * @tc.name: it_test_process_007 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess007, TestSize.Level0) +{ + ItTestProcess007(); +} + +/* * + * @tc.name: it_test_process_031 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess031, TestSize.Level0) +{ + ItTestProcess031(); +} + +/* * + * @tc.name: it_test_process_032 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess032, TestSize.Level0) +{ + ItTestProcess032(); +} + +/* * + * @tc.name: it_test_process_033 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess033, TestSize.Level0) +{ + ItTestProcess033(); +} + +/* * + * @tc.name: it_test_process_034 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess034, TestSize.Level0) +{ + ItTestProcess034(); +} + +/* * + * @tc.name: it_test_process_035 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess035, TestSize.Level0) +{ + ItTestProcess035(); +} + +/* * + * @tc.name: it_test_process_036 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess036, TestSize.Level0) +{ + ItTestProcess036(); +} + +/* * + * @tc.name: it_test_process_037 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess037, TestSize.Level0) +{ + ItTestProcess037(); +} + +/* * + * @tc.name: it_test_process_040 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess040, TestSize.Level0) +{ + ItTestProcess040(); +} + +/* * + * @tc.name: it_test_process_041 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess041, TestSize.Level0) +{ + ItTestProcess041(); +} + +/* * + * @tc.name: it_test_process_042 + * @tc.desc: function for ProcessProcessTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess042, TestSize.Level0) +{ + ItTestProcess042(); +} + +/* * + * @tc.name: it_test_process_053 + * @tc.desc: function for killpg:Sends a signal to the process group, + * Other processes in the process group can receive the signal. + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess053, TestSize.Level0) +{ + ItTestProcess053(); +} + +/* * + * @tc.name: it_test_process_055 + * @tc.desc: function for waitid:To test the function of transferring different parameters of the waitid. + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess055, TestSize.Level0) +{ + ItTestProcess055(); +} + +/* * + * @tc.name: it_test_process_062 + * @tc.desc: function for killpg:Fork two processes. The killpg sends a signal to the current process group. + * The other two processes can receive the signal. + * @tc.type: FUNC + */ +HWTEST_F(ProcessProcessTest, ItTestProcess062, TestSize.Level0) +{ + ItTestProcess062(); +} +#endif +} // namespace OHOS diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_001.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_001.cpp new file mode 100644 index 00000000..10425707 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_001.cpp @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "it_test_process.h" + +static const int PROCESS_PRIORITY_MAX = 10; +static const int PROCESS_PRIORITY_MIN = 31; +static const int PROCESS_SCHED_RR_INTERVAL = 20000000; + +static int Testcase(VOID) +{ + int ret; + struct sched_param param = { 0 }; + struct timespec ts = { 0 }; + int err; + ret = sched_getparam(getpid(), NULL); + err = errno; + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(err, EINVAL, err); + + ret = sched_getparam(-1, ¶m); + err = errno; + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(err, EINVAL, err); + + ret = sched_setparam(getpid(), NULL); + err = errno; + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(err, EINVAL, err); + + ret = sched_setparam(-1, ¶m); + err = errno; + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + + param.sched_priority = PROCESS_PRIORITY_MIN + 1; + ret = sched_setparam(getpid(), ¶m); + err = errno; + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(err, EINVAL, err); + + param.sched_priority = 15; // 15, set pthread priority. + ret = sched_setparam(60, ¶m); // 60, set the param. + err = errno; + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(err, ESRCH, err); + + ret = getpriority(PRIO_USER, getpid()); + err = errno; + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(err, EINVAL, err); + + ret = sched_get_priority_min(SCHED_RR); + ICUNIT_ASSERT_EQUAL(ret, PROCESS_PRIORITY_MAX, ret); + + ret = sched_get_priority_max(SCHED_FIFO); + err = errno; + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(err, EINVAL, err); + + ret = sched_get_priority_max(SCHED_OTHER); + err = errno; + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(err, EINVAL, err); + + ret = sched_get_priority_max(SCHED_RR); + ICUNIT_ASSERT_EQUAL(ret, PROCESS_PRIORITY_MIN, ret); + + ret = sched_get_priority_min(SCHED_OTHER); + err = errno; + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(err, EINVAL, err); + + ret = sched_get_priority_min(SCHED_FIFO); + err = errno; + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(err, EINVAL, err); + + param.sched_priority = PROCESS_PRIORITY_MAX - 1; + ret = sched_setparam(getpid(), ¶m); + err = errno; + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(err, EINVAL, err); + + param.sched_priority = PROCESS_PRIORITY_MAX - 1; + ret = sched_setscheduler(getpid(), SCHED_RR, ¶m); + err = errno; + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(err, EINVAL, err); + + param.sched_priority = 11; // 11, set pthread priority. + ret = sched_setscheduler(1000, SCHED_RR, ¶m); // 1000, input the pid. + err = errno; + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(err, EINVAL, err); + + param.sched_priority = PROCESS_PRIORITY_MAX - 1; + ret = setpriority(PRIO_PROCESS, getpid(), param.sched_priority); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + err = errno; + ICUNIT_ASSERT_EQUAL(err, EINVAL, err); + + ret = sched_getscheduler(getpid()); + ICUNIT_ASSERT_EQUAL(ret, SCHED_RR, ret); + + ret = sched_getscheduler(10000); // 10000, input the pid. + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + err = errno; + ICUNIT_ASSERT_EQUAL(err, EINVAL, err); + + ret = sched_getscheduler(-1); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + err = errno; + ICUNIT_ASSERT_EQUAL(err, EINVAL, err); + + param.sched_priority = PROCESS_PRIORITY_MAX - 1; + ret = sched_setscheduler(getpid(), SCHED_FIFO, ¶m); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + err = errno; + ICUNIT_ASSERT_EQUAL(err, EINVAL, err); + + return 0; + +ERROR_OUT: + return -1; +} + +void ItTestProcess001(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_001", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_002.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_002.cpp new file mode 100644 index 00000000..5badaa3a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_002.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" +#include "sched.h" + +static int Testcase() +{ +#define CURRENT_PROCESS_POLICY SCHED_RR + + struct sched_param param = { 0 }; + int ret = OS_ERROR; + + int currProcessPri = getpriority(PRIO_PROCESS, getpid()); + ICUNIT_GOTO_WITHIN_EQUAL(currProcessPri, 0, 31, currProcessPri, ERROR_OUT); // 31, assert function Result equal to this. + +#define PROCESS_TEST_PRI1 (currProcessPri + 1) +#define PROCESS_TEST_PRI2 (currProcessPri - 1) + + ret = sched_getparam(getpid(), ¶m); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + ICUNIT_GOTO_EQUAL(param.sched_priority, currProcessPri, param.sched_priority, ERROR_OUT); + + ret = sched_getscheduler(getpid()); + ICUNIT_GOTO_EQUAL(ret, CURRENT_PROCESS_POLICY, ret, ERROR_OUT); + + param.sched_priority = PROCESS_TEST_PRI1; + ret = sched_setscheduler(getpid(), SCHED_RR, ¶m); + ICUNIT_GOTO_WITHIN_EQUAL(ret, 0, 100000, ret, ERROR_OUT); // 100000, assert ret equal to this. + + ret = sched_getparam(getpid(), ¶m); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + ICUNIT_GOTO_EQUAL(param.sched_priority, PROCESS_TEST_PRI1, param.sched_priority, ERROR_OUT); + + param.sched_priority = PROCESS_TEST_PRI2; + ret = sched_setparam(getpid(), ¶m); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + + ret = getpriority(PRIO_PROCESS, getpid()); + ICUNIT_GOTO_EQUAL(ret, PROCESS_TEST_PRI2, ret, ERROR_OUT); + + ret = setpriority(PRIO_PROCESS, getpid(), currProcessPri); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + + ret = getpriority(PRIO_PROCESS, getpid()); + ICUNIT_GOTO_EQUAL(ret, currProcessPri, ret, ERROR_OUT); + + param.sched_priority = currProcessPri; + ret = sched_setscheduler(getpid(), CURRENT_PROCESS_POLICY, ¶m); + ICUNIT_GOTO_WITHIN_EQUAL(ret, 0, 100000, ret, ERROR_OUT); // 100000, assert ret equal to this. + + ret = setpgid(getpid(), 1); + ICUNIT_GOTO_EQUAL(ret, -1, ret, ERROR_OUT); + ICUNIT_GOTO_EQUAL(errno, EPERM, errno, ERROR_OUT); + + ret = setpgid(getpid(), 2); // 2, set pid num. + ICUNIT_GOTO_EQUAL(ret, -1, ret, ERROR_OUT); + ICUNIT_GOTO_EQUAL(errno, EPERM, errno, ERROR_OUT); + + return 0; +ERROR_OUT: + return ret; +} + +void ItTestProcess002(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_002", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_004.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_004.cpp new file mode 100644 index 00000000..fae512ff --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_004.cpp @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static int Testcase(void) +{ + int ret; + int status; + int pid; + + ret = fork(); + if (ret == 0) { + exit(5); // 5, exit args + } else if (ret > 0) { + pid = ret; + ret = waitpid(0, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ICUNIT_ASSERT_EQUAL(WEXITSTATUS(status), 5, status); // 5, assert that function Result is equal to this. + ICUNIT_ASSERT_EQUAL(WIFEXITED(status), 1, status); + } + ICUNIT_ASSERT_WITHIN_EQUAL(ret, 0, 100000, ret); // 100000, assert that function Result is equal to this. + + ret = fork(); + if (ret == 0) { + WAIT_PARENT_FIRST_TO_RUN(1); + exit(6); // 6, exit args + } else if (ret > 0) { + pid = ret; + ret = waitpid(0, &status, 0); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ICUNIT_ASSERT_EQUAL(status, 6, status); // 6, assert that function Result is equal to this. + } + + ICUNIT_ASSERT_WITHIN_EQUAL(ret, 0, 100000, ret); // 100000, assert that function Result is equal to this. + + ret = fork(); + if (ret == 0) { + exit(1); + } else if (ret > 0) { + pid = ret; + ret = wait(&status); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ICUNIT_ASSERT_EQUAL(status, 1, status); + } + + ICUNIT_ASSERT_WITHIN_EQUAL(ret, 0, 100000, ret); // 100000, assert that function Result is equal to this. + + ret = fork(); + if (ret == 0) { + WAIT_PARENT_FIRST_TO_RUN(1); + exit(2); // 2, exit args + } else if (ret > 0) { + pid = ret; + ret = wait(&status); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ICUNIT_ASSERT_EQUAL(status, 2, status); // 2, assert that function Result is equal to this. + } + ICUNIT_ASSERT_WITHIN_EQUAL(ret, 0, 100000, ret); // 100000, assert that function Result is equal to this. + + ret = fork(); + if (ret == 0) { + exit(3); // 3, exit args + } else if (ret > 0) { + pid = ret; + ret = waitpid(pid, &status, 0); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ICUNIT_ASSERT_EQUAL(status, 3, status); // 3, assert that function Result is equal to this. + } + ICUNIT_ASSERT_WITHIN_EQUAL(ret, 0, 100000, ret); // 100000, assert that function Result is equal to this. + + ret = fork(); + if (ret == 0) { + WAIT_PARENT_FIRST_TO_RUN(1); + exit(4); // 4, exit args + } else if (ret > 0) { + pid = ret; + ret = waitpid(ret, &status, 0); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ICUNIT_ASSERT_EQUAL(status, 4, status); // 4, assert that function Result is equal to this. + } + ICUNIT_ASSERT_WITHIN_EQUAL(ret, 0, 100000, ret); // 100000, assert that function Result is equal to this. + + return 0; +} + +void ItTestProcess004(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_004", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_005.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_005.cpp new file mode 100644 index 00000000..8a94237b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_005.cpp @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static int ProcessTest002(void) +{ + int pid; + + pid = fork(); + if (pid == 0) { + WAIT_PARENT_FIRST_TO_RUN(1); + exit(12); // 12, exit args + } + + ICUNIT_ASSERT_WITHIN_EQUAL(pid, 0, 100000, pid); // 100000, assert that function Result is equal to this. + + pid = fork(); + if (pid == 0) { + WAIT_PARENT_FIRST_TO_RUN(1); + exit(12); // 12, exit args + } + + ICUNIT_ASSERT_WITHIN_EQUAL(pid, 0, 100000, pid); // 100000, assert that function Result is equal to this. + + pid = fork(); + if (pid == 0) { + WAIT_PARENT_FIRST_TO_RUN(1); + exit(12); // 12, exit args + } + + ICUNIT_ASSERT_WITHIN_EQUAL(pid, 0, 100000, pid); // 100000, assert that function Result is equal to this. + + pid = fork(); + if (pid == 0) { + WAIT_PARENT_FIRST_TO_RUN(1); + exit(12); // 12, exit args + } + + ICUNIT_ASSERT_WITHIN_EQUAL(pid, 0, 100000, pid); // 100000, assert that function Result is equal to this. + + pid = fork(); + if (pid == 0) { + WAIT_PARENT_FIRST_TO_RUN(1); + exit(12); // 12, exit args + } + + ICUNIT_ASSERT_WITHIN_EQUAL(pid, 0, 100000, pid); // 100000, assert that function Result is equal to this. + + pid = fork(); + if (pid == 0) { + WAIT_PARENT_FIRST_TO_RUN(1); + exit(12); // 12, exit args + } + + ICUNIT_ASSERT_WITHIN_EQUAL(pid, 0, 100000, pid); // 100000, assert that function Result is equal to this. + + pid = fork(); + if (pid == 0) { + WAIT_PARENT_FIRST_TO_RUN(1); + exit(12); // 12, exit args + } + + ICUNIT_ASSERT_WITHIN_EQUAL(pid, 0, 100000, pid); // 100000, assert that function Result is equal to this. + + pid = fork(); + if (pid == 0) { + WAIT_PARENT_FIRST_TO_RUN(1); + exit(12); // 12, exit args + } + + ICUNIT_ASSERT_WITHIN_EQUAL(pid, 0, 100000, pid); // 100000, assert that function Result is equal to this. + + pid = fork(); + if (pid == 0) { + WAIT_PARENT_FIRST_TO_RUN(1); + exit(12); // 12, exit args + } + + ICUNIT_ASSERT_WITHIN_EQUAL(pid, 0, 100000, pid); // 100000, assert that function Result is equal to this. + + pid = fork(); + if (pid == 0) { + WAIT_PARENT_FIRST_TO_RUN(1); + exit(8); // 8, exit args + } + + ICUNIT_ASSERT_WITHIN_EQUAL(pid, 0, 100000, pid); // 100000, assert that function Result is equal to this. + + return 0; +} + +static int ProcessTest001(int *id) +{ + int ret; + int status; + int pid; + + pid = fork(); + if (pid == 0) { + ret = ProcessTest002(); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + WAIT_PARENT_FIRST_TO_RUN(200); // 200, wait time. + exit(7); // 7, exit args + } + + ICUNIT_ASSERT_WITHIN_EQUAL(pid, 0, 100000, pid); // 100000, assert that function Result is equal to this. + *id = pid; + return 0; +} + +static int Testcase(void) +{ + int ret; + int status; + int pid; + + ret = fork(); + if (ret == 0) { + ret = ProcessTest001(&pid); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = waitpid(pid, &status, 0); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ICUNIT_ASSERT_EQUAL(status, 7, status); // 7, assert that function Result is equal to this. + exit(8); // 8, exit args + } else if (ret > 0) { + pid = ret; + ret = wait(&status); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ICUNIT_ASSERT_EQUAL(status, 8, status); // 8, assert that function Result is equal to this. + } + + return 0; +} + +void ItTestProcess005(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_005", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_006.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_006.cpp new file mode 100644 index 00000000..909c4e74 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_006.cpp @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static const int TEST_COUNT = 10; + +static void *ThreadFunc2(void *arg) +{ + pid_t pid = *((pid_t *)arg); + int ret; + int status = 0; + ret = waitpid(pid, &status, 0); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL_NULL(ret, pid, ret); + ICUNIT_ASSERT_EQUAL_NULL(status, 12, status); // 12, assert that function Result is equal to this. +} + +static int ProcessTest001(void) +{ + int ret; + int status = 0; + int pid, pid1; + int data; + int pri; + pthread_t newPthread, newPthread1; + int count = 4; + pthread_attr_t a = { 0 }; + struct sched_param param = { 0 }; + int currProcessPri = getpriority(PRIO_PROCESS, getpid()); + ICUNIT_ASSERT_WITHIN_EQUAL(currProcessPri, 0, 31, currProcessPri); // 31, assert that function Result is equal to this. + + ret = setpriority(PRIO_PROCESS, getpid(), currProcessPri - 2); // 2, Used to calculate priorities. + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + pid = fork(); + if (pid == 0) { + WAIT_PARENT_FIRST_TO_RUN(50); // 50, wait time. + exit(12); // 12, exit args + } + + ICUNIT_ASSERT_WITHIN_EQUAL(pid, 0, 100000, pid); // 100000, assert that function Result is equal to this. + pid1 = fork(); + if (pid1 == 0) { + WAIT_PARENT_FIRST_TO_RUN(40); // 40, wait time. + exit(10); // 10, exit args + } + + ICUNIT_ASSERT_WITHIN_EQUAL(pid1, 0, 100000, pid1); // 100000, assert that function Result is equal to this. + data = pid; + ret = pthread_create(&newPthread, NULL, ThreadFunc2, &data); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = waitpid(pid1, &status, 0); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(ret, pid1, ret); + ICUNIT_ASSERT_EQUAL(status, 10, status); // 10, assert that function Result is equal to this. + + ret = pthread_detach(newPthread); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return 0; +} + +static int TestCase(void) +{ + int ret; + int status; + int pid; + int count = TEST_COUNT; + + int temp = GetCpuCount(); + if (temp <= 1) { + return 0; + } + + while (count > 0) { + ret = fork(); + if (ret == 0) { + ret = ProcessTest001(); + exit(11); // 11, exit args + } else if (ret > 0) { + pid = ret; + ret = wait(&status); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ICUNIT_ASSERT_EQUAL(status, 11, status); // 11, assert that function Result is equal to this. + } + count--; + } + return 0; +} + +void ItTestProcess006(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_006", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_008.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_008.cpp new file mode 100644 index 00000000..aba4a9aa --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_008.cpp @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static const int TEST_COUNT = 10; + +__attribute__((optnone)) static void *ThreadFunc2(void *arg) +{ + printf("111111111111111: exit\n"); + exit(254); // 254, exit args +} + +__attribute__((optnone)) static void *ThreadFunc3(void *arg) +{ + while (1) { + } +} + +__attribute__((optnone)) static int ProcessTest001(void) +{ + int ret; + int status; + int pid; + int policy = 0; + int data; + int pri; + pthread_t newPthread, newPthread1; + int count = 4; + pthread_attr_t a = { 0 }; + struct sched_param param = { 0 }; + int currProcessPri = getpriority(PRIO_PROCESS, getpid()); + ICUNIT_ASSERT_WITHIN_EQUAL(currProcessPri, 0, 31, currProcessPri); // 31, assert that function Result is equal to this. + + ret = setpriority(PRIO_PROCESS, getpid(), currProcessPri - 2); // 2, Used to calculate priorities. + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_getschedparam(pthread_self(), &policy, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_init(&a); + param.sched_priority = 26; /* 26: prio */ + pthread_attr_setschedparam(&a, ¶m); + pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED); + ret = pthread_create(&newPthread, &a, ThreadFunc3, &data); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + data = ret; + ret = pthread_create(&newPthread, NULL, ThreadFunc2, &data); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + printf("222222222222222: exit\n"); + exit(255); // 255, exit args + return 0; +} + +__attribute__((optnone)) static int Testcase(void) +{ + int ret; + int status; + int pid; + int count = TEST_COUNT; + int temp = GetCpuCount(); + if (temp <= 1) { + return 0; + } + + while (count > 0) { + ret = fork(); + if (ret == 0) { + ret = ProcessTest001(); + exit(10); // 10, exit args + } else if (ret > 0) { + pid = ret; + ret = wait(&status); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ICUNIT_ASSERT_TWO_EQUAL(status, 255, 254, status); // 255, 254, assert that function Result is equal to this. + } + + ICUNIT_ASSERT_WITHIN_EQUAL(ret, 0, 100000, ret); // 100000, assert that function Result is equal to this. + count--; + } + + return 0; +} + +void ItTestProcess008(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_008", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_009.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_009.cpp new file mode 100644 index 00000000..e31d590a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_009.cpp @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static void *ThreadFunc2(void *arg) +{ + while (1) { + } +} + +static int ProcessTest001(void) +{ + int ret; + int status = 0; + int pid; + int data; + int pri; + pthread_t newPthread, newPthread1; + int count = 4; + pthread_attr_t a = { 0 }; + struct sched_param param = { 0 }; + int currProcessPri = getpriority(PRIO_PROCESS, getpid()); + ICUNIT_ASSERT_WITHIN_EQUAL(currProcessPri, 0, 31, currProcessPri); // 31, assert that function Result is equal to this. + + ret = setpriority(PRIO_PROCESS, getpid(), currProcessPri - 2); // 2, Used to calculate priorities. + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + pid = fork(); + if (pid == 0) { + sleep(1); + exit(12); // 12, exit args + } + + ICUNIT_ASSERT_WITHIN_EQUAL(pid, 0, 100000, pid); // 100000, assert that function Result is equal to this. + + ret = pthread_create(&newPthread, NULL, ThreadFunc2, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newPthread, NULL, ThreadFunc2, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = waitpid(pid, &status, 0); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ICUNIT_ASSERT_EQUAL(status, 12, status); // 12, assert that function Result is equal to this. + + exit(255); // 255, exit args + return 0; +} + +static int Testcase(void) +{ + int ret; + int status; + int pid; + int temp = GetCpuCount(); + if (temp <= 1) { + return 0; + } + + ret = fork(); + if (ret == 0) { + ret = ProcessTest001(); + exit(11); // 11, exit args + } else if (ret > 0) { + pid = ret; + ret = wait(&status); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + // ICUNIT_ASSERT_EQUAL(status, 255, status); // 255, assert that function Result is equal to this. + } + + ICUNIT_ASSERT_WITHIN_EQUAL(pid, 0, 100000, pid); // 100000, assert that function Result is equal to this. + + return 0; +} + +void ItTestProcess009(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_009", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_010.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_010.cpp new file mode 100644 index 00000000..7c5c4843 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_010.cpp @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static const int TEST_COUNT = 10; + +static void *ThreadFunc2(void *arg) {} + +static int ProcessTest001(void) +{ + int ret; + int status; + int pid; + int data; + pthread_t newPthread, newPthread1; + int currProcessPri = getpriority(PRIO_PROCESS, getpid()); + ICUNIT_ASSERT_WITHIN_EQUAL(currProcessPri, 0, 31, currProcessPri); // 31, assert currProcessPri equal to this. + + ret = setpriority(PRIO_PROCESS, getpid(), currProcessPri - 2); // 2, Used to calculate priorities. + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + data = ret; + ret = pthread_create(&newPthread, NULL, ThreadFunc2, &data); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + exit(255); // 255, exit args + return 0; +} + +static int Child(void) +{ + int count = TEST_COUNT; + int status = 0; + + while (count > 0) { + int ret = fork(); + if (ret == 0) { + ret = ProcessTest001(); + exit(ret); + } else if (ret > 0) { + int pid = ret; + ret = wait(&status); + status = WEXITSTATUS(status); + if (ret != pid) { + printf("wait child %d failed, is %d!\n", pid, ret); + exit(__LINE__); + } + if (status != 255) { // 255, assert that function Result is equal to this. + printf("child is error line :%d \n", status); + exit(__LINE__); + } + } else { + printf("fork failed!\n"); + exit(__LINE__); + } + + count--; + } + + return 0; +} + +static int Testcase(void) +{ + int ret; + int status; + int pid; + + int temp = GetCpuCount(); + if (temp <= 1) { + return 0; + } + + ret = fork(); + ICUNIT_ASSERT_WITHIN_EQUAL(ret, 0, 100000, ret); // 100000, assert that function Result is equal to this. + if (ret == 0) { + exit(Child()); + } else if (ret > 0) { + pid = ret; + ret = waitpid(pid, &status, 0); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ICUNIT_ASSERT_EQUAL(status, 0, status); + } + + return 0; +} + +void ItTestProcess010(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_010", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_011.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_011.cpp new file mode 100644 index 00000000..2e86789e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_011.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static int g_testThreadExit = 0; +static int g_testExit = 0; + +static void *ThreadFunc2(void *arg) +{ + sleep(10); // 10, sleep 10 second. + g_testThreadExit++; + return NULL; +} + +static void *ThreadFunc(void *arg) +{ + int ret; + int status = 100; + pthread_t newPthread; + pid_t pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + + if (pid == 0) { + ret = pthread_create(&newPthread, NULL, ThreadFunc2, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + } else { + ret = waitpid(pid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 0, status, EXIT); + + ICUNIT_GOTO_EQUAL(g_testThreadExit, 0, g_testThreadExit, EXIT); + + g_testExit++; + } + + return NULL; +EXIT: + if (pid == 0) { + while (1) { + } + } + return NULL; +} + +static int TestCase(void) +{ + int ret; + int status = 100; + pthread_t newPthread; + + g_testThreadExit = 0; + g_testExit = 0; + + ret = pthread_create(&newPthread, NULL, ThreadFunc, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newPthread, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_EQUAL(g_testExit, 1, g_testExit); + return 0; +} + +void ItTestProcess011(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_011", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_012.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_012.cpp new file mode 100644 index 00000000..ea204195 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_012.cpp @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static int g_testThreadExit = 0; +static int g_testExit = 0; + +static void *ThreadFunc2(void *arg) +{ + sleep(10); // 10, sleep 10 second. + g_testThreadExit++; + return NULL; +} + +static void *ThreadFunc001(void *arg) +{ + int ret; + int status = 100; + pthread_t newPthread; + + pid_t pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + + if (pid == 0) { + ret = pthread_create(&newPthread, NULL, ThreadFunc2, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + } else { + ret = waitpid(pid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 0, status, EXIT); + + ICUNIT_GOTO_EQUAL(g_testThreadExit, 0, g_testThreadExit, EXIT); + + g_testExit++; + } + + return NULL; + +EXIT: + if (pid == 0) { + while (1) { + } + } + return NULL; +} + +static void *ThreadFunc(void *arg) +{ + struct sched_param param = { 0 }; + pthread_t newPthread; + int curThreadPri, curThreadPolicy; + pthread_attr_t a = { 0 }; + + int ret = pthread_getschedparam(pthread_self(), &curThreadPolicy, ¶m); + ICUNIT_GOTO_EQUAL(ret, 0, -ret, EXIT); + + curThreadPri = param.sched_priority; + + ret = pthread_attr_init(&a); + param.sched_priority = curThreadPri - 2; // 2, set pthread priority. + pthread_attr_setschedparam(&a, ¶m); + pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED); + ret = pthread_create(&newPthread, &a, ThreadFunc001, 0); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_join(newPthread, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + return NULL; + +EXIT: + g_testExit = 0; + return NULL; +} + +static int TestCase(void) +{ + int ret; + int status = 100; + pthread_t newPthread; + + g_testThreadExit = 0; + g_testExit = 0; + + ret = pthread_create(&newPthread, NULL, ThreadFunc, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newPthread, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_EQUAL(g_testExit, 1, g_testExit); + return 0; +} + +void ItTestProcess012(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_012", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_013.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_013.cpp new file mode 100644 index 00000000..613d0912 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_013.cpp @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" +#include "sched.h" + +static int TestCase() +{ +#define PROCESS_TEST_PRI1 (currProcessPri + 1) + struct sched_param param = { 0 }; + int ret = OS_ERROR; + int val, currPolicy; + int currProcessPri = getpriority(PRIO_PROCESS, getpid()); + ICUNIT_GOTO_WITHIN_EQUAL(currProcessPri, 0, 31, currProcessPri, ERROR_OUT); // 31, assert currProcessPri equal to this. + + currPolicy = sched_getscheduler(getpid()); + ICUNIT_GOTO_EQUAL(currPolicy, SCHED_RR, currPolicy, ERROR_OUT); + + val = getpriority(PRIO_PROCESS, 0); + ICUNIT_GOTO_EQUAL(val, currProcessPri, val, ERROR_OUT); + + ret = sched_getparam(0, ¶m); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + ICUNIT_GOTO_EQUAL(param.sched_priority, currProcessPri, param.sched_priority, ERROR_OUT); + + val = sched_getscheduler(0); + ICUNIT_GOTO_EQUAL(val, currPolicy, val, ERROR_OUT); + + ret = setpriority(PRIO_PROCESS, 0, PROCESS_TEST_PRI1); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + + ret = getpriority(PRIO_PROCESS, 0); + ICUNIT_GOTO_EQUAL(ret, PROCESS_TEST_PRI1, ret, ERROR_OUT); + + param.sched_priority = currProcessPri; + ret = sched_setparam(0, ¶m); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + + ret = getpriority(PRIO_PROCESS, getpid()); + ICUNIT_GOTO_EQUAL(ret, currProcessPri, ret, ERROR_OUT); + + ret = sched_setscheduler(0, SCHED_FIFO, ¶m); + ICUNIT_GOTO_EQUAL(ret, -1, ret, ERROR_OUT); + ret = errno; + ICUNIT_GOTO_EQUAL(ret, EINVAL, ret, ERROR_OUT); + + ret = sched_setscheduler(0, SCHED_RR, ¶m); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + + ret = sched_setscheduler(1, SCHED_FIFO, ¶m); + ICUNIT_GOTO_EQUAL(ret, -1, ret, ERROR_OUT); + ret = errno; + ICUNIT_GOTO_EQUAL(ret, EPERM, ret, ERROR_OUT); + + ret = sched_setscheduler(2, SCHED_FIFO, ¶m); // 2, input the pid. + ICUNIT_GOTO_EQUAL(ret, -1, ret, ERROR_OUT); + ret = errno; + ICUNIT_GOTO_EQUAL(ret, EPERM, ret, ERROR_OUT); + + ret = sched_setparam(1, ¶m); + ICUNIT_GOTO_EQUAL(ret, -1, ret, ERROR_OUT); + ret = errno; + ICUNIT_GOTO_EQUAL(ret, EPERM, ret, ERROR_OUT); + + ret = sched_setparam(2, ¶m); // 2, set the param. + ICUNIT_GOTO_EQUAL(ret, -1, ret, ERROR_OUT); + ret = errno; + ICUNIT_GOTO_EQUAL(ret, EPERM, ret, ERROR_OUT); + + ret = setpriority(PRIO_PROCESS, 1, PROCESS_TEST_PRI1); + ICUNIT_GOTO_EQUAL(ret, -1, ret, ERROR_OUT); + ret = errno; + ICUNIT_GOTO_EQUAL(ret, EPERM, ret, ERROR_OUT); + + ret = setpriority(PRIO_PROCESS, 2, PROCESS_TEST_PRI1); // 2, Used to calculate priorities. + ICUNIT_GOTO_EQUAL(ret, -1, ret, ERROR_OUT); + ret = errno; + ICUNIT_GOTO_EQUAL(ret, EPERM, ret, ERROR_OUT); + + return 0; + +ERROR_OUT: + return ret; +} + +void ItTestProcess013(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_013", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_014.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_014.cpp new file mode 100644 index 00000000..f69c245a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_014.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static int g_testThreadExit = 0; +static int g_testExit = 0; + +static void *ThreadFunc(void *arg) +{ + int count = 0; + + while (count < 5) { // 5, Number of cycles. + g_testExit++; + count++; + usleep(1000 * 10 * 1); // 1000, 10, Used to calculate the delay time. + } + + return NULL; +} + +static int TestCase(void) +{ + int ret; + int status = 100; + pthread_t newPthread; + pid_t pid; + int count = 0; + g_testThreadExit = 0; + g_testExit = 0; + + ret = pthread_create(&newPthread, NULL, ThreadFunc, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + + if (pid == 0) { + while (count < 10) { // 10, Number of cycles. + count++; + usleep(1000 * 10 * 2); // 1000, 10, 2, Used to calculate the delay time. + } + exit(0); + } else { + ret = waitpid(pid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 0, status, EXIT); + ICUNIT_GOTO_EQUAL(g_testExit, 5, g_testExit, EXIT); // 5, assert status equal to this. + } + + ret = pthread_join(newPthread, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + +EXIT: + return 0; +} + +void ItTestProcess014(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_014", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_015.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_015.cpp new file mode 100644 index 00000000..967a68ff --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_015.cpp @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static int g_testThreadExit = 0; +static int g_testExit = 0; +static int g_waitPid; +static int g_backPid; + +static void *ThreadFunc(void *arg) +{ + int status = 0; + + int ret = waitpid(g_waitPid, NULL, 0); + ICUNIT_GOTO_EQUAL(ret, -1, ret, EXIT); + status = errno; + ICUNIT_GOTO_EQUAL(status, ECHILD, status, EXIT); + +EXIT: + return NULL; +} + +static int ProcessTest(void) +{ + int ret; + int status = 100; + pthread_t newPthread; + pid_t pid; + int count = 0; + g_testThreadExit = 0; + g_testExit = 0; + g_waitPid = 0; + + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + g_waitPid = -1; + + if (pid == 0) { + usleep(1000 * 10 * 20); // 1000, 10, 20, Used to calculate the delay time. + exit(3); // 3, exit args + } + + ret = pthread_create(&newPthread, NULL, ThreadFunc, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + usleep(1000 * 10 * 2); // 1000, 10, 2, Used to calculate the delay time. + + ret = waitpid(pid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 3, status, EXIT); // 3, assert status equal to this. + + ret = pthread_join(newPthread, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + exit(255); // 255, exit args +EXIT: + return 0; +} + +static int TestCase(void) +{ + int ret; + int status = 0; + pid_t pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + if (pid == 0) { + ProcessTest(); + exit(g_iCunitErrLineNo); + } + + ret = waitpid(pid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert status equal to this. + return 0; +EXIT: + return 1; +} + +void ItTestProcess015(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_015", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_016.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_016.cpp new file mode 100644 index 00000000..32394bdf --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_016.cpp @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static int g_testThreadExit = 0; +static int g_testExit = 0; +static int g_waitPid; +static int g_backPid; + +static void *ThreadFunc(void *arg) +{ + int status = 0; + + int ret = waitpid(g_waitPid, NULL, 0); + ICUNIT_GOTO_EQUAL(ret, -1, ret, EXIT); + status = errno; + ICUNIT_GOTO_EQUAL(status, ECHILD, status, EXIT); + +EXIT: + return NULL; +} + +static int ProcessTest(void) +{ + int ret; + int status = 100; + pthread_t newPthread; + pid_t pid; + int count = 0; + g_testThreadExit = 0; + g_testExit = 0; + + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + g_waitPid = 0; + + if (pid == 0) { + while (count < 10) { // 10, Number of cycles. + count++; + usleep(1000 * 10 * 2); // 1000, 10, 2, Used to calculate the delay time. + } + exit(3); // 3, exit args + } + + ret = pthread_create(&newPthread, NULL, ThreadFunc, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + usleep(1000 * 10 * 2); // 1000, 10, 2, Used to calculate the delay time. + + ret = waitpid(pid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 3, status, EXIT); // 3, assert status equal to this. + + ret = pthread_join(newPthread, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + exit(255); // 255, exit args +EXIT: + return 0; +} + +static int TestCase(void) +{ + int ret; + int status = 0; + pid_t pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + if (pid == 0) { + ProcessTest(); + exit(g_iCunitErrLineNo); + } + + ret = waitpid(pid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert status equal to this. + + return 0; + +EXIT: + return 1; +} + + +void ItTestProcess016(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_016", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_017.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_017.cpp new file mode 100644 index 00000000..7519aecc --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_017.cpp @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static int g_testThreadExit = 0; +static int g_testExit = 0; +static int g_waitPid; +static int g_backPid; + +static void *ThreadFunc(void *arg) +{ + int status = 0; + + int ret = waitpid(g_waitPid, NULL, 0); + printf("%s 22222 pid : %d\n", __FUNCTION__, ret); + + ICUNIT_GOTO_EQUAL(ret, -1, ret, EXIT); + status = errno; + ICUNIT_GOTO_EQUAL(status, ECHILD, status, EXIT); + +EXIT: + return NULL; +} + +static int ProcessTest(void) +{ + int ret; + int status = 100; + pthread_t newPthread; + pid_t pid; + int count = 0; + g_testThreadExit = 0; + g_testExit = 0; + + g_waitPid = 0; + + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + if (pid == 0) { + usleep(1000 * 10 * 10); // 1000, 10, 10, Used to calculate the delay time. + exit(3); // 3, exit args + } + + g_waitPid = pid; + ret = pthread_create(&newPthread, NULL, ThreadFunc, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + usleep(1000 * 10 * 5); // 1000, 10, 5, Used to calculate the delay time. + + ret = waitpid(pid, &status, 0); + printf("%s 11111 pid : %d\n", __FUNCTION__, ret); + ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 3, status, EXIT); // 3, assert status equal to this. + + ret = pthread_join(newPthread, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + exit(255); // 255, exit args +EXIT: + return 0; +} + +static int TestCase(void) +{ + int ret; + int status = 0; + pid_t pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + if (pid == 0) { + ProcessTest(); + exit(0); + } + + ret = waitpid(pid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert status equal to this. + return 0; +EXIT: + return 1; +} + +void ItTestProcess017(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_017", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_018.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_018.cpp new file mode 100644 index 00000000..8e92d185 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_018.cpp @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static int g_testThreadExit = 0; +static int g_testExit = 0; +static int g_waitPid; +static int g_backPid; + +static void *ThreadFunc(void *arg) +{ + int status = 0; + + int ret = waitpid(g_waitPid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, g_waitPid, ret, EXIT); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 3, status, EXIT); // 3, assert status equal to this. + +EXIT: + return NULL; +} + +static int ProcessTest(void) +{ + int ret; + int status = 100; + pthread_t newPthread; + pid_t pid, pid1, pid2; + int count = 0; + g_testThreadExit = 0; + g_testExit = 0; + + g_waitPid = 0; + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + g_waitPid = pid; + + if (pid == 0) { + while (count < 10) { // 10, Number of cycles. + count++; + usleep(1000 * 10 * 2); // 1000, 10, 2, Used to calculate the delay time. + } + exit(3); // 3, exit args + } + + ret = pthread_create(&newPthread, NULL, ThreadFunc, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + usleep(1000 * 10 * 2); // 1000, 10, 2, Used to calculate the delay time. + + pid1 = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid1, 0, 100000, pid, EXIT); // 100000, assert pid1 equal to this. + if (pid1 == 0) { + while (count < 10) { // 10, Number of cycles. + count++; + usleep(1000 * 10 * 2); // 1000, 10, 2, Used to calculate the delay time. + } + exit(4); // 4, exit args + } + + ret = waitpid(pid1, &status, 0); + ICUNIT_GOTO_EQUAL(ret, pid1, ret, EXIT); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 4, status, EXIT); // 4, assert status equal to this. + + ret = pthread_join(newPthread, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + exit(255); // 255, exit args +EXIT: + return 0; +} + +static int TestCase(void) +{ + int ret; + int status = 0; + pid_t pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + if (pid == 0) { + ProcessTest(); + exit(g_iCunitErrLineNo); + } + + ret = waitpid(pid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert that function Result is equal to this. + return 0; +EXIT: + return 1; +} + +void ItTestProcess018(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_018", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_019.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_019.cpp new file mode 100644 index 00000000..c51b59d8 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_019.cpp @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static int g_testThreadExit = 0; +static int g_testExit = 0; +static int g_waitPid; +static int g_backPid; + +static void *ThreadFunc(void *arg) +{ + int status = 0; + + int ret = waitpid(g_waitPid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, g_waitPid, ret, EXIT); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 3, status, EXIT); // 3, assert that function Result is equal to this. + +EXIT: + return NULL; +} + +static int ProcessTest(void) +{ + int ret; + int status = 100; + pthread_t newPthread; + pid_t pid, pid1, pid2; + int count = 0; + + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + if (pid == 0) { + while (count < 20) { // 20, number of cycles + count++; + usleep(1000 * 10 * 2); // 1000, 10, 2, Used to calculate the delay time. + } + exit(3); // 3, exit args + } + + g_waitPid = pid; + pid1 = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid1, 0, 100000, pid, EXIT); // 100000, assert pid1 equal to this. + if (pid1 == 0) { + while (count < 15) { // 15, number of cycles + count++; + usleep(1000 * 10 * 2); // 1000, 10, 2, Used to calculate the delay time. + } + exit(4); // 4, exit args + } + + ret = pthread_create(&newPthread, NULL, ThreadFunc, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + usleep(1000 * 10 * 2); // 1000, 10, 2, Used to calculate the delay time. + + ret = waitpid(-1, &status, 0); + ICUNIT_GOTO_EQUAL(ret, pid1, ret, EXIT); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 4, status, EXIT); // 4, assert status equal to this. + + ret = pthread_join(newPthread, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + exit(255); // 255, exit args +EXIT: + return 0; +} + +static int TestCase(void) +{ + int ret; + int status = 0; + pid_t pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + if (pid == 0) { + ProcessTest(); + exit(g_iCunitErrLineNo); + } + + ret = waitpid(pid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert status equal to this. + return 0; +EXIT: + return 1; +} + +void ItTestProcess019(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_019", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_020.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_020.cpp new file mode 100644 index 00000000..16701c6e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_020.cpp @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static int g_waitPid; +static int g_backPid; +static int g_backPid1; + +static void *ThreadFunc(void *arg) +{ + int status = 0; + + int ret = waitpid(g_waitPid, &status, 0); + if (ret == g_backPid) { + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 3, status, EXIT); // 3, assert status equal to this. + } else if (ret == g_backPid1) { + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 4, status, EXIT); // 4, assert status equal to this. + } else { + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + } + + ICUNIT_GOTO_EQUAL(status, 3, status, EXIT); // 3, assert status equal to this. + +EXIT: + return NULL; +} + +static int ProcessTest(void) +{ + int ret; + int status = 100; + pthread_t newPthread; + pid_t pid, pid1, pid2; + int count = 0; + + g_waitPid = 0; + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + g_waitPid = -1; + g_backPid = pid; + + if (pid == 0) { + while (count < 20) { // 20, Number of cycles. + count++; + usleep(1000 * 10 * 2); // 1000, 10, 2, Used to calculate the delay time. + } + exit(3); // 3, exit args + } + + pid1 = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid1, 0, 100000, pid, EXIT); // 100000, assert pid1 equal to this. + g_backPid1 = pid1; + if (pid1 == 0) { + while (count < 15) { // 15, Number of cycles. + count++; + usleep(1000 * 10 * 2); // 1000, 10, 2, Used to calculate the delay time. + } + exit(4); // 4, exit args + } + + ret = pthread_create(&newPthread, NULL, ThreadFunc, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + usleep(1000 * 10 * 2); // 1000, 10, 2, Used to calculate the delay time. + + ret = waitpid(-1, &status, 0); + if (ret == pid) { + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 3, status, EXIT); // 3, assert status equal to this. + } else if (ret == pid1) { + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 4, status, EXIT); // 4, assert status equal to this. + } else { + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + } + + ret = pthread_join(newPthread, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + exit(255); // 255, exit args +EXIT: + return 0; +} + +static int TestCase(void) +{ + int ret; + int status = 0; + pid_t pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + if (pid == 0) { + ProcessTest(); + exit(g_iCunitErrLineNo); + } + + ret = waitpid(pid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert status equal to this. + + return 0; +EXIT: + return 1; +} + +void ItTestProcess020(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_020", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_021.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_021.cpp new file mode 100644 index 00000000..792996c7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_021.cpp @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static int g_waitPid; +static int g_backPid; +static int g_backPid1; +static int g_backPidFlag = 0; +static int g_backPid1Flag = 0; +static int g_errorFalg = 0; + +static void *ThreadFunc(void *arg) +{ + int status = 0; + + int ret = waitpid(g_waitPid, &status, 0); + if ((ret == g_backPid) && (g_backPidFlag == 0)) { + g_backPidFlag = 1; + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 3, status, EXIT); // 3, assert status equal to this. + } else if ((ret == g_backPid1) && (g_backPid1Flag == 0)) { + g_backPid1Flag = 1; + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 4, status, EXIT); // 4, assert status equal to this. + } else if (g_errorFalg == 0) { + g_errorFalg = 1; + ICUNIT_GOTO_EQUAL(ret, -1, ret, EXIT); + } else { + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + } + +EXIT: + return NULL; +} + +static void *ThreadFunc1(void *arg) +{ + int status = 0; + int ret = waitpid(g_waitPid, &status, 0); + if ((ret == g_backPid) && (g_backPidFlag == 0)) { + g_backPidFlag = 1; + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 3, status, EXIT); // 3, assert status equal to this. + } else if ((ret == g_backPid1) && (g_backPid1Flag == 0)) { + g_backPid1Flag = 1; + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 4, status, EXIT); // 4, assert status equal to this. + } else if (g_errorFalg == 0) { + g_errorFalg = 1; + ICUNIT_GOTO_EQUAL(ret, -1, ret, EXIT); + } else { + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + } + +EXIT: + return NULL; +} + +static int ProcessTest(void) +{ + int ret; + int status = 100; + pthread_t newPthread, newPthread1; + pid_t pid, pid1, pid2; + int count = 0; + + g_errorFalg = 0; + g_backPid1Flag = 0; + g_errorFalg = 0; + + g_waitPid = 0; + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + g_waitPid = -1; + g_backPid = pid; + + if (pid == 0) { + while (count < 20) { // 20, Number of cycles. + count++; + usleep(1000 * 10 * 2); // 1000, 10, 2, Used to calculate the delay time. + } + exit(3); // 3, exit args + } + + pid1 = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid1, 0, 100000, pid, EXIT); // 100000, assert pid1 equal to this. + g_backPid1 = pid1; + if (pid1 == 0) { + while (count < 15) { // 15, Number of cycles. + count++; + usleep(1000 * 10 * 2); // 1000, 10, 2, Used to calculate the delay time. + } + exit(4); // 4, exit args + } + + ret = pthread_create(&newPthread, NULL, ThreadFunc, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + usleep(1000 * 10 * 2); // 1000, 10, 2, Used to calculate the delay time. + + ret = pthread_create(&newPthread1, NULL, ThreadFunc1, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + usleep(1000 * 10 * 2); // 1000, 10, 2, Used to calculate the delay time. + + ret = waitpid(-1, &status, 0); + if ((ret == pid) && (g_backPidFlag == 0)) { + g_backPidFlag = 1; + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 3, status, EXIT); // 3, assert status equal to this. + } else if ((ret == pid1) && (g_backPid1Flag == 0)) { + g_backPid1Flag = 1; + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 4, status, EXIT); // 4, assert status equal to this. + } else if (g_errorFalg == 0) { + g_errorFalg = 1; + ICUNIT_GOTO_EQUAL(ret, -1, ret, EXIT); + } else { + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + } + + ret = pthread_join(newPthread, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newPthread1, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + exit(255); // 255, exit args +EXIT: + return 0; +} + +static int TestCase(void) +{ + int ret; + int status = 0; + pid_t pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + if (pid == 0) { + ProcessTest(); + exit(g_iCunitErrLineNo); + } + + ret = waitpid(pid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert status equal to this. + return 0; +EXIT: + return 1; +} + +void ItTestProcess021(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_021", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_022.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_022.cpp new file mode 100644 index 00000000..10d9c112 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_022.cpp @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static int g_waitPid; +static int g_backPid; +static int g_backPid1; + +static int g_thread001; +static int g_thread002; +static void *ThreadFunc(void *arg) +{ + int status = 0; + + int ret = waitpid(0, &status, 0); + printf("3333333333333 pid : %u\n", ret); + ICUNIT_ASSERT_NOT_EQUAL_NULL(ret, -1, ret); + ICUNIT_ASSERT_NOT_EQUAL_NULL(g_thread002, 0, g_thread002); + g_thread001++; + +EXIT: + return NULL; +} + +static void *ThreadFunc2(void *arg) +{ + int status = 0; + + int ret = waitpid(0, &status, 0); + printf("222222222222222222 pid : %u\n", ret); + ICUNIT_ASSERT_NOT_EQUAL_NULL(ret, -1, ret); + ICUNIT_ASSERT_NOT_EQUAL_NULL(g_thread001, 0, g_thread001); + g_thread002++; + +EXIT: + return NULL; +} + +static int ProcessTest(void) +{ + int ret; + int status = 100; + pthread_t newPthread, newPthread1; + pid_t pid, pid1, pid2; + int count = 0; + + ret = setpgrp(); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + g_thread001 = 0; + g_thread002 = 0; + + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + g_backPid = pid; + + if (pid == 0) { + usleep(1000 * 10 * 30); // 1000, 10, 30, Used to calculate the delay time. + exit(3); // 3, exit args + } + + pid1 = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid1, 0, 100000, pid, EXIT); // 100000, assert pid1 equal to this. + g_backPid1 = pid1; + if (pid1 == 0) { + usleep(1000 * 10 * 20); // 1000, 10, 20, Used to calculate the delay time. + exit(4); // 4, exit args + } + + pid2 = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid2, 0, 100000, pid, EXIT); // 100000, assert pid2 equal to this. + if (pid2 == 0) { + usleep(1000 * 10 * 15); // 1000, 10, 15, Used to calculate the delay time. + exit(4); // 4, exit args + } + + ret = pthread_create(&newPthread, NULL, ThreadFunc, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + usleep(1000 * 10 * 5); // 1000, 10, 5, Used to calculate the delay time. + ret = pthread_create(&newPthread1, NULL, ThreadFunc2, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + usleep(1000 * 10 * 5); // 1000, 10, 5, Used to calculate the delay time. + + ret = waitpid(0, &status, 0); + printf("111111111111111 pid : %u\n", ret); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret); + g_thread001++; + ICUNIT_ASSERT_NOT_EQUAL(g_thread002, 1, g_thread001); + + ret = pthread_join(newPthread, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newPthread1, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_EQUAL(g_thread001, 2, g_thread001); // 2, assert that function Result is equal to this. + + exit(255); // 255, exit args +EXIT: + return 0; +} + +static int TestCase(void) +{ + int ret; + int status = 0; + pid_t pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + if (pid == 0) { + ProcessTest(); + exit(g_iCunitErrLineNo); + } + + ret = waitpid(pid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert status equal to this. + return 0; +EXIT: + return 1; +} + +void ItTestProcess022(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_022", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_023.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_023.cpp new file mode 100644 index 00000000..7e05574a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_023.cpp @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static int g_waitPid; +static int g_backPid; +static int g_backPid1; + +static int g_thread001; +static int g_thread002; +static void *ThreadFunc(void *arg) +{ + int status = 0; + + int ret = waitpid(-1, &status, 0); + printf("%s 33333 pid : %d\n", __FUNCTION__, ret); + ICUNIT_ASSERT_NOT_EQUAL_NULL(ret, -1, ret); + ICUNIT_ASSERT_NOT_EQUAL_NULL(g_thread002, 0, g_thread002); + g_thread001++; + + return reinterpret_cast(9); // 9, set thread return value. +EXIT: + return NULL; +} + +static void *ThreadFunc2(void *arg) +{ + int status = 0; + + int ret = waitpid(-1, &status, 0); + g_thread002++; + printf("%s 222222 pid : %d\n", __FUNCTION__, ret); + ICUNIT_ASSERT_NOT_EQUAL_NULL(ret, -1, ret); + ICUNIT_ASSERT_NOT_EQUAL_NULL(g_thread001, 0, g_thread001); + + return reinterpret_cast(9); // 9, set thread return value. +EXIT: + return NULL; +} + +static int ProcessTest(void) +{ + int ret; + int *error = nullptr; + int status = 100; + pthread_t newPthread, newPthread1; + pid_t pid, pid1, pid2; + int count = 0; + + g_thread001 = 0; + g_thread002 = 0; + + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + g_backPid = pid; + + if (pid == 0) { + usleep(1000 * 10 * 20); // 1000, 10, 20, Used to calculate the delay time. + exit(3); // 3, exit args + } + + pid1 = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid1, 0, 100000, pid, EXIT); // 100000, assert pid1 equal to this. + g_backPid1 = pid1; + if (pid1 == 0) { + usleep(1000 * 10 * 15); // 1000, 10, 15, Used to calculate the delay time. + exit(4); // 4, exit args + } + + pid2 = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid2, 0, 100000, pid, EXIT); // 100000, assert pid2 equal to this. + if (pid2 == 0) { + usleep(1000 * 10 * 10); // 1000, 10, 10, Used to calculate the delay time. + exit(4); // 4, exit args + } + + ret = pthread_create(&newPthread, NULL, ThreadFunc, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + usleep(1000 * 10 * 2); // 1000, 10, 2, Used to calculate the delay time. + ret = pthread_create(&newPthread1, NULL, ThreadFunc2, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + usleep(1000 * 10 * 2); // 1000, 10, 2, Used to calculate the delay time. + + ret = waitpid(-1, &status, 0); + g_thread001++; + printf("%s 11111 pid : %d\n", __FUNCTION__, ret); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_NOT_EQUAL(g_thread002, 1, g_thread001); + + ret = pthread_join(newPthread1, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newPthread, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_EQUAL(g_thread001, 2, g_thread001); // 2, assert that function Result is equal to this. + + exit(255); // 255, exit args +EXIT: + return 0; +} + +static int TestCase(void) +{ + int ret; + int status = 0; + pid_t pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + if (pid == 0) { + ProcessTest(); + exit(g_iCunitErrLineNo); + } + + ret = waitpid(pid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert status equal to this. + + return 0; +EXIT: + return 1; +} + +void ItTestProcess023(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_023", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_024.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_024.cpp new file mode 100644 index 00000000..ed927868 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_024.cpp @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static int g_waitPid; +static int g_backPid; +static int g_backPid1; + +static int g_thread001; +static int g_thread002; +static void *ThreadFunc(void *arg) +{ + int status = 0; + + int ret = waitpid(-1, &status, 0); + printf("%s 3333333 pid : %d\n", __FUNCTION__, ret); + ICUNIT_ASSERT_NOT_EQUAL_NULL(ret, -1, ret); + g_thread001++; + +EXIT: + return NULL; +} + +static void *ThreadFunc2(void *arg) +{ + int status = 0; + + int ret = waitpid(0, &status, 0); + g_thread002++; + printf("%s 11111111 pid %d\n", __FUNCTION__, ret); + ICUNIT_ASSERT_NOT_EQUAL_NULL(ret, -1, ret); + +EXIT: + return NULL; +} + +static int ProcessTest(void) +{ + int ret; + int status = 100; + pthread_t newPthread, newPthread1; + pid_t pid, pid1, pid2; + int count = 0; + + g_thread001 = 0; + g_thread002 = 0; + + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + g_backPid = pid; + if (pid == 0) { + usleep(1000 * 10 * 20); // 1000, 10, 20, Used to calculate the delay time. + exit(3); // 3, exit args + } + + pid1 = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid1, 0, 100000, pid, EXIT); // 100000, assert pid1 equal to this. + g_backPid1 = pid1; + if (pid1 == 0) { + usleep(1000 * 10 * 15); // 1000, 10, 15, Used to calculate the delay time. + exit(4); // 4, exit args + } + + pid2 = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid2, 0, 100000, pid, EXIT); // 100000, assert pid2 equal to this. + if (pid2 == 0) { + usleep(1000 * 10 * 10); // 1000, 10, 10, Used to calculate the delay time. + exit(4); // 4, exit args + } + + ret = pthread_create(&newPthread, NULL, ThreadFunc, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + usleep(1000 * 10 * 2); // 1000, 10, 2, Used to calculate the delay time. + + ret = pthread_create(&newPthread1, NULL, ThreadFunc2, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + usleep(1000 * 10 * 2); // 1000, 10, 2, Used to calculate the delay time. + + ret = waitpid(-1, &status, 0); + g_thread001++; + printf("%s 222222 pid : %d\n", __FUNCTION__, ret); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_NOT_EQUAL(g_thread002, 0, g_thread002); + + ret = pthread_join(newPthread1, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newPthread, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_EQUAL(g_thread001, 2, g_thread001); // 2, assert that function Result is equal to this. + + exit(255); // 255, exit args +EXIT: + return 0; +} + +static int TestCase(void) +{ + int ret; + int status = 0; + pid_t pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + if (pid == 0) { + ProcessTest(); + exit(g_iCunitErrLineNo); + } + + ret = waitpid(pid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert status equal to this. + + return 0; +EXIT: + return 1; +} + +void ItTestProcess024(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_024", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_025.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_025.cpp new file mode 100644 index 00000000..631ac97d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_025.cpp @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static int g_waitPid; +static int g_backPid; +static int g_backPid1; + +static int g_thread001; +static int g_thread002; +static void *ThreadFunc(void *arg) +{ + int status = 0; + + int ret = waitpid(-1, &status, 0); + printf("%s 3333333 pid : %d\n", __FUNCTION__, ret); + ICUNIT_ASSERT_NOT_EQUAL_NULL(ret, -1, ret); + g_thread001++; + +EXIT: + return NULL; +} + +static void *ThreadFunc2(void *arg) +{ + int status = 0; + + int ret = waitpid(g_backPid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, g_backPid, ret, EXIT); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 3, status, EXIT); // 3, assert status equal to this. + + g_thread002++; + + printf("%s 11111111 pid %d\n", __FUNCTION__, ret); + ICUNIT_ASSERT_NOT_EQUAL_NULL(ret, -1, ret); + +EXIT: + return NULL; +} + +static int ProcessTest(void) +{ + int ret; + int status = 100; + pthread_t newPthread, newPthread1; + pid_t pid, pid1, pid2; + int count = 0; + + g_thread001 = 0; + g_thread002 = 0; + + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + g_backPid = pid; + if (pid == 0) { + usleep(1000 * 10 * 40); // 1000, 10, 40, Used to calculate the delay time. + printf("child exit 1\n"); + exit(3); // 3, exit args + } + + pid1 = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid1, 0, 100000, pid, EXIT); // 100000, assert pid1 equal to this. + g_backPid1 = pid1; + if (pid1 == 0) { + usleep(1000 * 10 * 45); // 1000, 10, 45, Used to calculate the delay time. + printf("child exit 2\n"); + exit(4); // 4, exit args + } + + pid2 = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid2, 0, 100000, pid, EXIT); // 100000, assert pid2 equal to this. + if (pid2 == 0) { + usleep(1000 * 10 * 50); // 1000, 10, 50, Used to calculate the delay time. + printf("child exit 3\n"); + exit(4); // 4, exit args + } + + ret = pthread_create(&newPthread, NULL, ThreadFunc2, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + usleep(1000 * 10 * 2); // 1000, 10, 2, Used to calculate the delay time. + + ret = pthread_create(&newPthread1, NULL, ThreadFunc, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + usleep(1000 * 10 * 2); // 1000, 10, 2, Used to calculate the delay time. + + ret = waitpid(-1, &status, 0); + g_thread001++; + printf("%s 222222 pid : %d\n", __FUNCTION__, ret); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_NOT_EQUAL(g_thread002, 0, g_thread002); + + ret = pthread_join(newPthread, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newPthread1, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_EQUAL(g_thread001, 2, g_thread001); // 2, assert that function Result is equal to this. + + exit(255); // 255, exit args +EXIT: + return 0; +} + +static int TestCase(void) +{ + int ret; + int status = 0; + pid_t pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + if (pid == 0) { + ProcessTest(); + exit(g_iCunitErrLineNo); + } + + ret = waitpid(pid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert status equal to this. + + return 0; +EXIT: + return 1; +} + +void ItTestProcess025(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_025", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_026.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_026.cpp new file mode 100644 index 00000000..f7e49306 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_026.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static int TestCase(void) +{ + int ret; + int pid = 3; + int status = 0; + + ret = waitpid(pid, &status, -1); + ret = errno; + ICUNIT_GOTO_EQUAL(ret, EINVAL, ret, EXIT); + + ret = waitpid(pid, &status, 4); // 4, waitpid options. + ret = errno; + ICUNIT_GOTO_EQUAL(ret, EINVAL, ret, EXIT); + + ret = waitpid(pid, &status, WUNTRACED); + ret = errno; + ICUNIT_GOTO_EQUAL(ret, EOPNOTSUPP, ret, EXIT); + + ret = waitpid(pid, &status, WCONTINUED); + ret = errno; + ICUNIT_GOTO_EQUAL(ret, EOPNOTSUPP, ret, EXIT); + + ret = waitpid(pid, &status, 10); // 10, waitpid options. + ret = errno; + ICUNIT_GOTO_EQUAL(ret, EOPNOTSUPP, ret, EXIT); + + ret = waitpid(pid, &status, 21); // 21, waitpid options. + ret = errno; + ICUNIT_GOTO_EQUAL(ret, EINVAL, ret, EXIT); + + return 0; +EXIT: + return 1; +} + +void ItTestProcess026(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_026", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_027.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_027.cpp new file mode 100644 index 00000000..a1d77e38 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_027.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static int ProcessTest(void) +{ + int ret; + int status = 100; + pthread_t newPthread; + pid_t pid; + int count = 0; + + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + + if (pid == 0) { + usleep(1000 * 10 * 20); // 1000, 10, 20, Used to calculate the delay time. + exit(3); // 3, exit args + } + + ret = waitpid(pid, &status, WNOHANG); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = waitpid(pid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 3, status, EXIT); // 3, assert status equal to this. + + exit(255); // 255, exit args +EXIT: + return 0; +} + +static int TestCase(void) +{ + int ret; + int status = 0; + pid_t pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + if (pid == 0) { + ProcessTest(); + exit(g_iCunitErrLineNo); + } + + ret = waitpid(pid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert status equal to this. + return 0; +EXIT: + return 1; +} + +void ItTestProcess027(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_027", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_029.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_029.cpp new file mode 100644 index 00000000..71424851 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_029.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static int Child1(int currGid) +{ + ICUNIT_ASSERT_EQUAL(currGid, getpgrp(), getpgrp()); + + usleep(1000 * 10 * 5); // 1000, 10, 5, Used to calculate the delay time. + + ICUNIT_ASSERT_EQUAL(getpgrp(), getpid(), getpgrp()); + + exit(255); // 255, exit args +} + +static int TestCase(void) +{ + int ret; + int status = 0; + pid_t pid, pid1; + int currGid = getpgrp(); + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + + if (pid == 0) { + Child1(currGid); + exit(0); + } + + usleep(1000 * 10 * 2); // 1000, 10, 2, Used to calculate the delay time. + + ret = setpgid(pid, pid); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert status equal to this. + + return 0; +EXIT: + return 1; +} + +void ItTestProcess029(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_029", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_030.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_030.cpp new file mode 100644 index 00000000..e37b26f8 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_030.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static int Child1(int currGid) +{ + int ret; + + ICUNIT_ASSERT_EQUAL(currGid, getpgrp(), getpgrp()); + + ret = setpgrp(); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_EQUAL(getpgrp(), getpid(), getpgrp()); + + exit(255); // 255, exit args +} + +static int TestCase(void) +{ + int ret; + int status = 0; + pid_t pid, pid1; + int currGid = getpgrp(); + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + + if (pid == 0) { + Child1(currGid); + exit(0); + } + + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert status equal to this. + + return 0; +EXIT: + return 1; +} + +void ItTestProcess030(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_030", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_038.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_038.cpp new file mode 100644 index 00000000..c8cbeba2 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_038.cpp @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static int Child1(int currGid) +{ + sleep(1); + + exit(255); // 255, exit args +} + +static int Child2(int currGid, int gid) +{ + sleep(1); + + exit(255); // 255, exit args +} + +static int ProcessGroup(void) +{ + int ret; + int status = 0; + pid_t pid, pid1; + int currGid = getpgrp(); + + ret = setpgrp(); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + currGid = getpgrp(); + + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + + if (pid == 0) { + Child1(currGid); + printf("[Failed] - [Errline : %d RetCode : 0x%x\n", g_iCunitErrLineNo, g_iCunitErrCode); + exit(g_iCunitErrLineNo); + } + + pid1 = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid1, 0, 100000, pid1, EXIT); // 100000, assert pid equal to this. + ICUNIT_GOTO_NOT_EQUAL(pid1, pid, pid1, EXIT); + + if (pid1 == 0) { + Child2(currGid, pid); + printf("[Failed] - [Errline : %d RetCode : 0x%x\n", g_iCunitErrLineNo, g_iCunitErrCode); + exit(g_iCunitErrLineNo); + } + + exit(255); // 255, exit args +EXIT: + return 0; +} + +static int GroupProcess(void) +{ + int ret; + int status = 0; + pid_t pid, pid1; + int currGid = getpgrp(); + int count = 30; + + while (count > 0) { + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + + if (pid == 0) { + ProcessGroup(); + printf("[Failed] - [Errline : %d RetCode : 0x%x\n", g_iCunitErrLineNo, g_iCunitErrCode); + exit(g_iCunitErrLineNo); + } + + ret = waitpid(pid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert status equal to this. + + sleep(1); + count--; + } + + exit(255); // 255, exit args +EXIT: + return 0; +} + +static int TestCase(void) +{ + int ret; + int status = 0; + pid_t pid, pid1; + int currGid = getpgrp(); + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + + if (pid == 0) { + GroupProcess(); + printf("[Failed] - [Errline : %d RetCode : 0x%x\n", g_iCunitErrLineNo, g_iCunitErrCode); + exit(g_iCunitErrLineNo); + } + + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert status equal to this. + + return 0; +EXIT: + return 1; +} + +void ItTestProcess038(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_038", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_039.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_039.cpp new file mode 100644 index 00000000..2abc9e68 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_039.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static int GroupProcess(void) +{ + int ret; + int status = 0; + pid_t pid, pid1; + int count = 1000; + + for (int i = 0; i < count; i++) { + pid = fork(); + if (pid == 0) { + exit(0); + } else if (pid > 0) { + ret = waitpid(pid, &status, 0); + continue; + } else { + exit(5); // 5, exit args + } + } + + exit(255); // 255, exit args +EXIT: + return 0; +} + +static int TestCase(void) +{ + int ret; + int status = 0; + pid_t pid, pid1; + int currGid = getpgrp(); + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + + if (pid == 0) { + prctl(PR_SET_NAME, "mainFork", 0UL, 0UL, 0UL); + GroupProcess(); + printf("[Failed] - [Errline : %d RetCode : 0x%x\n", g_iCunitErrLineNo, g_iCunitErrCode); + exit(g_iCunitErrLineNo); + } + + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert status equal to this. + + return 0; +EXIT: + return 1; +} + +void ItTestProcess039(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_039", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_043.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_043.cpp new file mode 100644 index 00000000..c1bd271f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_043.cpp @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static int Testcase(VOID) +{ + int priority; + int err; + int ret; + int currProcessPri = getpriority(PRIO_PROCESS, getpid()); + int count = 0; + priority = getpriority(PRIO_PGRP, 0); + struct sched_param param = { 0 }; + err = errno; + + priority = getpriority(PRIO_PGRP, 0); + err = errno; + ICUNIT_ASSERT_EQUAL(priority, -1, priority); + ICUNIT_ASSERT_EQUAL(err, EINVAL, err); + + priority = getpriority(PRIO_USER, 0); + err = errno; + ICUNIT_ASSERT_EQUAL(priority, -1, priority); + ICUNIT_ASSERT_EQUAL(err, EINVAL, err); + + for (count = 1; count < 1000; ++count) { // 1000, Number of cycles. + priority = getpriority(PRIO_USER + count, 0); + err = errno; + ICUNIT_ASSERT_EQUAL(priority, -1, priority); + ICUNIT_ASSERT_EQUAL(err, EINVAL, err); + + priority = setpriority(PRIO_USER + count, getpid(), currProcessPri); + err = errno; + ICUNIT_ASSERT_EQUAL(priority, -1, priority); + ICUNIT_ASSERT_EQUAL(err, EINVAL, err); + + priority = getpriority(-count, 0); + err = errno; + ICUNIT_ASSERT_EQUAL(priority, -1, priority); + ICUNIT_ASSERT_EQUAL(err, EINVAL, err); + + priority = setpriority(-count, getpid(), currProcessPri); + err = errno; + ICUNIT_ASSERT_EQUAL(priority, -1, priority); + ICUNIT_ASSERT_EQUAL(err, EINVAL, err); + + priority = sched_get_priority_max(SCHED_RR - count); + err = errno; + ICUNIT_ASSERT_EQUAL(priority, -1, priority); + ICUNIT_ASSERT_EQUAL(err, EINVAL, err); + + priority = sched_get_priority_max(SCHED_RR + count); + err = errno; + ICUNIT_ASSERT_EQUAL(priority, -1, priority); + ICUNIT_ASSERT_EQUAL(err, EINVAL, err); + + priority = sched_get_priority_min(SCHED_RR - count); + err = errno; + ICUNIT_ASSERT_EQUAL(priority, -1, priority); + ICUNIT_ASSERT_EQUAL(err, EINVAL, err); + + priority = sched_get_priority_min(SCHED_RR + count); + err = errno; + ICUNIT_ASSERT_EQUAL(priority, -1, priority); + ICUNIT_ASSERT_EQUAL(err, EINVAL, err); + + ret = sched_setscheduler(getpid(), SCHED_RR - count, ¶m); + err = errno; + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(err, EINVAL, err); + + ret = sched_setscheduler(getpid(), SCHED_RR + count, ¶m); + err = errno; + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(err, EINVAL, err); + } + + priority = setpriority(PRIO_PGRP, getpid(), currProcessPri); + err = errno; + ICUNIT_ASSERT_EQUAL(priority, -1, priority); + ICUNIT_ASSERT_EQUAL(err, EINVAL, err); + + priority = setpriority(PRIO_USER, getpid(), currProcessPri); + err = errno; + ICUNIT_ASSERT_EQUAL(priority, -1, priority); + ICUNIT_ASSERT_EQUAL(err, EINVAL, err); + + return 0; +} + +void ItTestProcess043(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_043", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_044.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_044.cpp new file mode 100644 index 00000000..08995680 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_044.cpp @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "it_test_process.h" + +static void *ThreadFuncTest3(void *arg) +{ + while (1) { + sleep(1); + }; + + return NULL; +} + +static int GroupProcess(void) +{ + int ret; + int status = 0; + pid_t pid, pid1; + pthread_t newPthread; + struct timespec ts = { 0 }; + + ret = sched_rr_get_interval(getpid(), &ts); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(ts.tv_sec, 0, ts.tv_sec); + if (ts.tv_nsec < 5000000 || ts.tv_nsec > 20000000) { // 5000000, 20000000, expected range of tv_nsec. + ICUNIT_ASSERT_EQUAL(ts.tv_nsec, -1, ts.tv_nsec); + } + + ret = pthread_create(&newPthread, NULL, ThreadFuncTest3, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = sched_rr_get_interval(getpid(), &ts); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(ts.tv_sec, 0, ts.tv_sec); + if (ts.tv_nsec < 10000000 || ts.tv_nsec > 40000000) { // 10000000, 40000000, expected range of tv_nsec. + ICUNIT_ASSERT_EQUAL(ts.tv_nsec, -1, ts.tv_nsec); + } + + exit(255); // 255, exit args +EXIT: + return 0; +} + +static int TestCase(void) +{ + int ret; + int status = 0; + pid_t pid, pid1; + int currGid = getpgrp(); + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, assert pid equal to this. + + if (pid == 0) { + prctl(PR_SET_NAME, "mainFork", 0UL, 0UL, 0UL); + GroupProcess(); + printf("[Failed] - [Errline : %d RetCode : 0x%x\n", g_iCunitErrLineNo, g_iCunitErrCode); + exit(g_iCunitErrLineNo); + } + + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert status equal to this. + + return 0; +EXIT: + return 1; +} + +void ItTestProcess044(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_044", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_045.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_045.cpp new file mode 100644 index 00000000..a094cb7e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_045.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "it_test_process.h" + +static UINT32 Testcase(VOID) +{ + int ret; + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + + ret = pthread_getaffinity_np(pthread_self(), 0, &cpuset); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_setaffinity_np(pthread_self(), 0, &cpuset); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = sched_setaffinity(getpid(), 0, &cpuset); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno); + + ret = sched_getaffinity(getpid(), 0, &cpuset); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno); + + ret = sched_setaffinity(-15, sizeof(cpu_set_t), &cpuset); // -15, pid num + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, ESRCH, errno); + + ret = sched_setaffinity(1, sizeof(cpu_set_t), &cpuset); // init process, no permission + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, EPERM, errno); + + ret = sched_setaffinity(128, sizeof(cpu_set_t), &cpuset); // 128, pid num + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, ESRCH, errno); + + ret = sched_getaffinity(128, sizeof(cpu_set_t), &cpuset); // 128, pid num + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, ESRCH, errno); + + ret = sched_getaffinity(-15, sizeof(cpu_set_t), &cpuset); // -15, pid num + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(errno, ESRCH, errno); + + return 0; +} + +void ItTestProcess045(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_045", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_046.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_046.cpp new file mode 100644 index 00000000..a6f849a1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_046.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +// This testcase us used for undefination of LOSCFG_USER_TEST_SMP +static int Testcase(void) +{ + int ret; + int status; + int pid; + + int temp = GetCpuCount(); + if (temp != 1) { + return 0; + } + + ret = fork(); + if (ret == 0) { + int ret; + cpu_set_t cpuset; + + CPU_ZERO(&cpuset); + CPU_SET(1, &cpuset); /* cpu1 unsupported operation */ + ret = sched_setaffinity(getpid(), sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, -1, ret, ERROR_OUT); + + CPU_ZERO(&cpuset); + CPU_SET(0, &cpuset); /* cpu0 */ + ret = sched_setaffinity(getpid(), sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + CPU_ZERO(&cpuset); + + ret = sched_getaffinity(getpid(), sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + ret = (CPU_ISSET(0, &cpuset) > 0) ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 1, ret, ERROR_OUT); + ret = (CPU_ISSET(1, &cpuset) > 0) ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + +ERROR_OUT: + exit(11); // 11, exit args + } else if (ret > 0) { + pid = ret; + ret = waitpid(ret, &status, 0); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ICUNIT_ASSERT_EQUAL(status, 11, status); // 11, assert that function Result is equal to this. + } + + return 0; +} + +void ItTestProcess046(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_046", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_047.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_047.cpp new file mode 100644 index 00000000..cd769a3a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_047.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +// This testcase us used for undefination of LOSCFG_USER_TEST_SMP +static int Testcase(void) +{ + int ret; + int pid; + int status; + + int temp = GetCpuCount(); + if (temp != 1) { + return 0; + } + + ret = fork(); + if (ret == 0) { + int temp; + cpu_set_t cpuset; + + CPU_ZERO(&cpuset); + temp = sched_getaffinity(getpid(), sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(temp, 0, temp, ERROR_OUT); + + temp = CPU_COUNT(&cpuset); + ICUNIT_GOTO_EQUAL(temp, 1, temp, ERROR_OUT); /* one cpu with the undefination of LOSCFG_USER_TEST_SMP */ + +ERROR_OUT: + exit(11); // 11, exit args + } else if (ret > 0) { + pid = ret; + ret = waitpid(ret, &status, 0); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ICUNIT_ASSERT_EQUAL(status, 11, status); // 11, assert that function Result is equal to this. + } + + return 0; +} + +void ItTestProcess047(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_047", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_048.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_048.cpp new file mode 100644 index 00000000..be6e0a2a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_048.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +// This testcase us used for undefination of LOSCFG_USER_TEST_SMP +static int Testcase(void) +{ + int ret; + int status; + int pid; + + int temp = GetCpuCount(); + if (temp != 1) { + return 0; + } + + ret = fork(); + if (ret == 0) { + int ret; + cpu_set_t cpuset; + + CPU_ZERO(&cpuset); + CPU_SET(1, &cpuset); /* cpu1 unsupported operation */ + ret = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, EINVAL, ret, ERROR_OUT); + CPU_ZERO(&cpuset); + + CPU_ZERO(&cpuset); + CPU_SET(0, &cpuset); /* cpu0 */ + ret = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + CPU_ZERO(&cpuset); + + ret = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + ret = (CPU_ISSET(0, &cpuset) > 0) ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 1, ret, ERROR_OUT); + ret = (CPU_ISSET(1, &cpuset) > 0) ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + +ERROR_OUT: + exit(11); // 11, exit args + } else if (ret > 0) { + pid = ret; + ret = waitpid(ret, &status, 0); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ICUNIT_ASSERT_EQUAL(status, 11, status); // 11, assert that function Result is equal to this. + } + + return 0; +} + +void ItTestProcess048(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_048", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_054.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_054.cpp new file mode 100644 index 00000000..6de1aec0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_054.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static int TestCase(void) +{ + int ret; + int pid = 3; + siginfo_t info = { 0 }; + + ret = waitid((idtype_t)3, getpgrp(), &info, WEXITED); // 3, set tid. + ret = errno; + ICUNIT_GOTO_EQUAL(ret, EINVAL, ret, EXIT); + + ret = waitid(P_PID, 0, &info, WEXITED); + ret = errno; + ICUNIT_GOTO_EQUAL(ret, EINVAL, ret, EXIT); + + ret = waitid(P_PID, 999, &info, WEXITED); // 999, set group. + ret = errno; + ICUNIT_GOTO_EQUAL(ret, ECHILD, ret, EXIT); + + ret = waitid(P_PGID, 0, &info, WEXITED); + ret = errno; + ICUNIT_GOTO_EQUAL(ret, EINVAL, ret, EXIT); + + ret = waitid(P_ALL, getpgrp(), &info, -1); + ret = errno; + ICUNIT_GOTO_EQUAL(ret, EINVAL, ret, EXIT); + + ret = waitid(P_ALL, getpgrp(), &info, 0); + ret = errno; + ICUNIT_GOTO_EQUAL(ret, EINVAL, ret, EXIT); + + ret = waitid(P_ALL, getpgrp(), &info, 32); // 32, set exit num. + ret = errno; + ICUNIT_GOTO_EQUAL(ret, EINVAL, ret, EXIT); + + ret = waitid(P_ALL, getpgrp(), &info, WSTOPPED); + ret = errno; + ICUNIT_GOTO_EQUAL(ret, EOPNOTSUPP, ret, EXIT); + + ret = waitid(P_ALL, getpgrp(), &info, WCONTINUED); + ret = errno; + ICUNIT_GOTO_EQUAL(ret, EOPNOTSUPP, ret, EXIT); + + ret = waitid(P_ALL, getpgrp(), &info, WNOWAIT); + ret = errno; + ICUNIT_GOTO_EQUAL(ret, EOPNOTSUPP, ret, EXIT); + + ret = waitid(P_ALL, getpgrp(), &info, 21); // 21, set exit num. + ret = errno; + ICUNIT_GOTO_EQUAL(ret, EINVAL, ret, EXIT); + return 0; +EXIT: + return 1; +} + +void ItTestProcess054(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_054", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_061.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_061.cpp new file mode 100644 index 00000000..69f82594 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smoke/process_test_061.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static int TestCase(void) +{ + int ret = killpg(-1, 0); + ICUNIT_GOTO_EQUAL(ret, -1, ret, EXIT); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT); + + ret = killpg(99999, 0); // 99999, set group + ICUNIT_GOTO_EQUAL(ret, -1, ret, EXIT); + ICUNIT_GOTO_EQUAL(errno, ESRCH, errno, EXIT); + + ret = killpg(2, 0); // 2, set group + ICUNIT_GOTO_EQUAL(ret, -1, ret, EXIT); + ICUNIT_GOTO_EQUAL(errno, EPERM, errno, EXIT); + + ret = killpg(0, 65); // 65, set signal + ICUNIT_GOTO_EQUAL(ret, -1, ret, EXIT); + ICUNIT_GOTO_EQUAL(errno, EINVAL, errno, EXIT); + + return 0; +EXIT: + return 1; +} + +void ItTestProcess061(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_061", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} \ No newline at end of file diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smp/process_test_smp_001.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smp/process_test_smp_001.cpp new file mode 100644 index 00000000..bdaa3a94 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smp/process_test_smp_001.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static int Testcase(void) +{ + int ret; + int status; + int pid; + + ret = fork(); + if (ret == 0) { + int ret; + cpu_set_t cpuset; + + CPU_ZERO(&cpuset); + CPU_SET(1, &cpuset); /* cpu1 */ + ret = sched_setaffinity(getpid(), sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + CPU_ZERO(&cpuset); + ret = sched_getaffinity(getpid(), sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + ret = (CPU_ISSET(0, &cpuset) > 0) ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + ret = (CPU_ISSET(1, &cpuset) > 0) ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 1, ret, ERROR_OUT); + exit(11); // 11, exit args + ERROR_OUT: + exit(11); // 11, exit args + } else if (ret > 0) { + pid = ret; + ret = waitpid(ret, &status, 0); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ICUNIT_ASSERT_EQUAL(status, 11, status); // 11, assert that function Result is equal to this. + } + + return 0; +} + +void ItTestProcessSmp001(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_SMP_001", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smp/process_test_smp_002.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smp/process_test_smp_002.cpp new file mode 100644 index 00000000..ddbb3e8a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smp/process_test_smp_002.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static void *PthreadTest01(VOID *arg) +{ + int ret; + cpu_set_t cpuset; + + CPU_ZERO(&cpuset); + CPU_SET(0, &cpuset); /* cpu0 */ + ret = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT1); + + CPU_ZERO(&cpuset); + ret = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT1); + ret = (CPU_ISSET(0, &cpuset) > 0) ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 1, ret, ERROR_OUT1); + ret = (CPU_ISSET(1, &cpuset) > 0) ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT1); + + CPU_ZERO(&cpuset); + ret = sched_getaffinity(getpid(), sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT1); + ret = (CPU_ISSET(0, &cpuset) > 0) ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT1); + ret = (CPU_ISSET(1, &cpuset) > 0) ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 1, ret, ERROR_OUT1); + return NULL; +ERROR_OUT1: + return NULL; +} + +static int Testcase(void) +{ + int ret; + int pid; + int status; + + ret = fork(); + if (ret == 0) { + int ret; + cpu_set_t cpuset; + pthread_t threadA; + cpu_set_t initCpuset; + + CPU_ZERO(&initCpuset); + ret = sched_getaffinity(getpid(), sizeof(cpu_set_t), &initCpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + + CPU_ZERO(&cpuset); + CPU_SET(1, &cpuset); /* cpu1 */ + ret = sched_setaffinity(getpid(), sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + + CPU_ZERO(&cpuset); + ret = sched_getaffinity(getpid(), sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + ret = (CPU_ISSET(0, &cpuset) > 0) ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + ret = (CPU_ISSET(1, &cpuset) > 0) ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 1, ret, ERROR_OUT); + + ret = pthread_create(&threadA, NULL, PthreadTest01, 0); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + ret = pthread_join(threadA, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + + CPU_ZERO(&cpuset); + ret = sched_getaffinity(getpid(), sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + ret = (CPU_ISSET(0, &cpuset) > 0) ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + ret = (CPU_ISSET(1, &cpuset) > 0) ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 1, ret, ERROR_OUT); + + ret = sched_setaffinity(getpid(), sizeof(cpu_set_t), &initCpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + exit(11); // 11, exit args + ERROR_OUT: + exit(11); // 11, exit args + } else if (ret > 0) { + pid = ret; + ret = waitpid(ret, &status, 0); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ICUNIT_ASSERT_EQUAL(status, 11, status); // 11, assert that function Result is equal to this. + } + + return 0; +} + +void ItTestProcessSmp002(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_SMP_002", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smp/process_test_smp_003.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smp/process_test_smp_003.cpp new file mode 100644 index 00000000..5e81a329 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smp/process_test_smp_003.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static UINT32 Testcase(VOID) +{ + int ret; + int status; + int pid; + + ret = fork(); + if (ret == 0) { + int ret; + cpu_set_t cpuset; + + CPU_ZERO(&cpuset); + CPU_SET(0, &cpuset); + ret = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + ret = sched_getaffinity(0, sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + ret = (CPU_ISSET(0, &cpuset) > 0) ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 1, ret, ERROR_OUT); + ret = (CPU_ISSET(1, &cpuset) > 0) ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + + CPU_ZERO(&cpuset); + CPU_SET(1, &cpuset); + ret = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + ret = sched_getaffinity(0, sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + ret = (CPU_ISSET(0, &cpuset) > 0) ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + ret = (CPU_ISSET(1, &cpuset) > 0) ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 1, ret, ERROR_OUT); + + CPU_ZERO(&cpuset); + CPU_SET(0, &cpuset); + CPU_SET(1, &cpuset); + ret = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + ret = sched_getaffinity(0, sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + ret = (CPU_ISSET(0, &cpuset) > 0) ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 1, ret, ERROR_OUT); + ret = (CPU_ISSET(1, &cpuset) > 0) ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 1, ret, ERROR_OUT); + exit(11); // 11, exit args + ERROR_OUT: + exit(11); // 11, exit args + } else if (ret > 0) { + pid = ret; + ret = waitpid(ret, &status, 0); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ICUNIT_ASSERT_EQUAL(status, 11, status); // 11, assert that function Result is equal to this. + } + + return 0; +} + +void ItTestProcessSmp003(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_SMP_003", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smp/process_test_smp_004.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smp/process_test_smp_004.cpp new file mode 100644 index 00000000..e5d44755 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smp/process_test_smp_004.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static UINT32 Testcase(VOID) +{ + int ret; + cpu_set_t cpuset; + ret = pthread_getaffinity_np(pthread_self(), 0, &cpuset); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + ret = pthread_setaffinity_np(pthread_self(), 0, &cpuset); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + ret = sched_setaffinity(getpid(), 0, &cpuset); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ret = sched_getaffinity(getpid(), 0, &cpuset); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + return 0; +} + +void ItTestProcessSmp004(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_SMP_004", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smp/process_test_smp_005.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smp/process_test_smp_005.cpp new file mode 100644 index 00000000..e656461c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smp/process_test_smp_005.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static void *PthreadTest01(VOID *arg) +{ + int ret; + cpu_set_t cpuset; + + CPU_ZERO(&cpuset); + CPU_SET(1, &cpuset); /* cpu1 */ + ret = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT1); + + CPU_ZERO(&cpuset); + ret = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT1); + ret = (CPU_ISSET(0, &cpuset)) > 0 ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT1); + ret = (CPU_ISSET(1, &cpuset)) > 0 ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 1, ret, ERROR_OUT1); + return NULL; +ERROR_OUT1: + return NULL; +} +static UINT32 Testcase(VOID) +{ + int ret; + int status; + int pid; + + ret = fork(); + if (ret == 0) { + int ret; + cpu_set_t cpuset; + pthread_t threadA; + + CPU_ZERO(&cpuset); + CPU_SET(0, &cpuset); /* cpu0 */ + ret = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + + CPU_ZERO(&cpuset); + ret = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + ret = (CPU_ISSET(0, &cpuset) > 0) ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 1, ret, ERROR_OUT); + ret = (CPU_ISSET(1, &cpuset) > 0) ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + + ret = pthread_create(&threadA, NULL, PthreadTest01, 0); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + ret = pthread_join(threadA, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + + CPU_ZERO(&cpuset); + ret = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + ret = (CPU_ISSET(0, &cpuset) > 0) ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 1, ret, ERROR_OUT); + ret = (CPU_ISSET(1, &cpuset) > 0) ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + exit(11); // 11, exit args + ERROR_OUT: + exit(11); // 11, exit args + } else if (ret > 0) { + pid = ret; + ret = waitpid(ret, &status, 0); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ICUNIT_ASSERT_EQUAL(status, 11, status); // 11, assert that function Result is equal to this. + } + + return 0; +} + +void ItTestProcessSmp005(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_SMP_005", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smp/process_test_smp_006.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smp/process_test_smp_006.cpp new file mode 100644 index 00000000..ecec61a2 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smp/process_test_smp_006.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static void *PthreadTest01(VOID *arg) +{ + int ret; + cpu_set_t cpuset; + + CPU_ZERO(&cpuset); + CPU_SET(1, &cpuset); /* cpu1 */ + ret = sched_setaffinity(0, sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT1); + + CPU_ZERO(&cpuset); + ret = sched_getaffinity(0, sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT1); + ret = (CPU_ISSET(0, &cpuset)) > 0 ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT1); + ret = (CPU_ISSET(1, &cpuset)) > 0 ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 1, ret, ERROR_OUT1); + return NULL; +ERROR_OUT1: + return NULL; +} +static UINT32 Testcase(VOID) +{ + int ret; + int status; + int pid; + + ret = fork(); + if (ret == 0) { + int ret; + cpu_set_t cpuset; + pthread_t threadA; + + CPU_ZERO(&cpuset); + CPU_SET(0, &cpuset); /* cpu0 */ + ret = sched_setaffinity(0, sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + + CPU_ZERO(&cpuset); + ret = sched_getaffinity(0, sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + ret = (CPU_ISSET(0, &cpuset) > 0) ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 1, ret, ERROR_OUT); + ret = (CPU_ISSET(1, &cpuset) > 0) ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + + ret = pthread_create(&threadA, NULL, PthreadTest01, 0); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + ret = pthread_join(threadA, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + + CPU_ZERO(&cpuset); + ret = sched_getaffinity(0, sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + ret = (CPU_ISSET(0, &cpuset) > 0) ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 1, ret, ERROR_OUT); + ret = (CPU_ISSET(1, &cpuset) > 0) ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + exit(11); // 11, exit args + ERROR_OUT: + exit(11); // 11, exit args + } else if (ret > 0) { + pid = ret; + ret = waitpid(ret, &status, 0); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ICUNIT_ASSERT_EQUAL(status, 11, status); // 11, assert that function Result is equal to this. + } + + return 0; +} + +void ItTestProcessSmp006(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_SMP_006", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smp/process_test_smp_007.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smp/process_test_smp_007.cpp new file mode 100644 index 00000000..76edfae4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smp/process_test_smp_007.cpp @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static void *PthreadTest01(VOID *arg) +{ + int ret; + cpu_set_t cpuset; + + sleep(2); // 2, sleep 10 second. + + CPU_ZERO(&cpuset); + ret = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT1); + ret = (CPU_ISSET(0, &cpuset)) > 0 ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT1); + ret = (CPU_ISSET(1, &cpuset)) > 0 ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 1, ret, ERROR_OUT1); + return NULL; +ERROR_OUT1: + return NULL; +} +static UINT32 Testcase(VOID) +{ + int ret; + int status; + int pid; + + ret = fork(); + if (ret == 0) { + int ret; + cpu_set_t cpuset; + pthread_t threadA; + + CPU_ZERO(&cpuset); + CPU_SET(0, &cpuset); /* cpu0 */ + ret = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + + CPU_ZERO(&cpuset); + ret = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + ret = (CPU_ISSET(0, &cpuset) > 0) ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 1, ret, ERROR_OUT); + ret = (CPU_ISSET(1, &cpuset) > 0) ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + + ret = pthread_create(&threadA, NULL, PthreadTest01, 0); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + + CPU_ZERO(&cpuset); + CPU_SET(1, &cpuset); /* cpu1 */ + ret = pthread_setaffinity_np(threadA, sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + + ret = pthread_join(threadA, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + + CPU_ZERO(&cpuset); + ret = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + ret = (CPU_ISSET(0, &cpuset) > 0) ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 1, ret, ERROR_OUT); + ret = (CPU_ISSET(1, &cpuset) > 0) ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + exit(11); // 11, exit args + ERROR_OUT: + exit(11); // 11, exit args + } else if (ret > 0) { + pid = ret; + ret = waitpid(ret, &status, 0); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ICUNIT_ASSERT_EQUAL(status, 11, status); // 11, assert that function Result is equal to this. + } + + return 0; +} + +void ItTestProcessSmp007(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_SMP_007", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smp/process_test_smp_008.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smp/process_test_smp_008.cpp new file mode 100644 index 00000000..bf590220 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/process/smp/process_test_smp_008.cpp @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_process.h" + +static void *PthreadTest01(VOID *arg) +{ + int ret; + cpu_set_t cpuset; + + CPU_ZERO(&cpuset); + CPU_SET(0, &cpuset); /* cpu0 */ + ret = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT1); + + CPU_ZERO(&cpuset); + ret = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT1); + ret = (CPU_ISSET(0, &cpuset)) > 0 ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 1, ret, ERROR_OUT1); + ret = (CPU_ISSET(1, &cpuset)) > 0 ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT1); + + CPU_ZERO(&cpuset); + CPU_SET(0, &cpuset); /* cpu0 */ + CPU_SET(1, &cpuset); /* cpu1 */ + ret = sched_setaffinity(getpid(), sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT1); + + CPU_ZERO(&cpuset); + ret = sched_getaffinity(getpid(), sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT1); + ret = (CPU_ISSET(0, &cpuset)) > 0 ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 1, ret, ERROR_OUT1); + ret = (CPU_ISSET(1, &cpuset)) > 0 ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 1, ret, ERROR_OUT1); + + CPU_ZERO(&cpuset); + ret = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT1); + ret = (CPU_ISSET(0, &cpuset)) > 0 ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 1, ret, ERROR_OUT1); + ret = (CPU_ISSET(1, &cpuset)) > 0 ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT1); + return NULL; +ERROR_OUT1: + return NULL; +} + +static int Testcase(void) +{ + int ret; + int status; + int pid; + + ret = fork(); + if (ret == 0) { + int ret; + cpu_set_t cpuset; + pthread_t threadA; + CPU_ZERO(&cpuset); + CPU_SET(1, &cpuset); /* cpu1 */ + ret = sched_setaffinity(getpid(), sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + + CPU_ZERO(&cpuset); + ret = sched_getaffinity(getpid(), sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + ret = (CPU_ISSET(0, &cpuset) > 0) ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + ret = (CPU_ISSET(1, &cpuset) > 0) ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 1, ret, ERROR_OUT); + + ret = pthread_create(&threadA, NULL, PthreadTest01, 0); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + ret = pthread_join(threadA, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + + CPU_ZERO(&cpuset); + ret = sched_getaffinity(getpid(), sizeof(cpu_set_t), &cpuset); + ICUNIT_GOTO_EQUAL(ret, 0, ret, ERROR_OUT); + ret = (CPU_ISSET(0, &cpuset) > 0) ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 1, ret, ERROR_OUT); + ret = (CPU_ISSET(1, &cpuset) > 0) ? 1 : 0; + ICUNIT_GOTO_EQUAL(ret, 1, ret, ERROR_OUT); + exit(11); // 11, exit args + ERROR_OUT: + exit(11); // 11, exit args + } else if (ret > 0) { + pid = ret; + ret = waitpid(ret, &status, 0); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ICUNIT_ASSERT_EQUAL(status, 11, status); // 11, assert that function Result is equal to this. + } + + return 0; +} + +void ItTestProcessSmp008(void) +{ + TEST_ADD_CASE("IT_POSIX_PROCESS_SMP_008", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/BUILD.gn b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/BUILD.gn new file mode 100644 index 00000000..9db974c0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/BUILD.gn @@ -0,0 +1,56 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("./config.gni") + +if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_LOW) { + unittest("liteos_a_process_basic_pthread_unittest_door") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + include_dirs = common_include_dirs + sources = sources_entry + sources += sources_smoke + sources_full = [] + sources += sources_full + configs = [ "../../..:public_config_for_door" ] + deps = [ "$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR:libsec_shared" ] + } +} + +if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_MIDDLE) { + unittest("liteos_a_process_basic_pthread_unittest") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + include_dirs = common_include_dirs + sources = sources_entry + sources += sources_smoke + sources += sources_full + configs = [ "../../..:public_config_for_all" ] + deps = [ "$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR:libsec_shared" ] + } +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/config.gni b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/config.gni new file mode 100644 index 00000000..fb15d289 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/config.gni @@ -0,0 +1,96 @@ +# Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//build/lite/config/test.gni") +import("//kernel/liteos_a/liteos.gni") +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +common_include_dirs = [ + "$THIRDPARTY_GOOGLETEST_DIR/googletest/include", + "../../../common/include", +] + +sources_entry = [ "../../../common/osTest.cpp" ] + +sources_smoke = [] + +sources_full = [] + +process_basic_pthread_include_dirs = + [ "$TEST_UNITTEST_DIR/process/basic/pthread" ] + +process_basic_pthread_sources_entry = + [ "$TEST_UNITTEST_DIR/process/basic/pthread/process_pthread_test.cpp" ] + +process_basic_pthread_sources_smoke = [ + "$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_atfork_test_001.cpp", + "$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_atfork_test_002.cpp", + "$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_cond_test_001.cpp", + "$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_cond_test_002.cpp", + "$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_cond_test_003.cpp", + "$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_cond_test_004.cpp", + "$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_once_test_001.cpp", + "$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_test_003.cpp", + "$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_test_006.cpp", + "$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_test_007.cpp", + "$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_test_008.cpp", + "$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_test_009.cpp", + "$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_test_010.cpp", + "$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_test_011.cpp", + "$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_test_012.cpp", + "$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_test_013.cpp", + "$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_test_015.cpp", + "$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_test_016.cpp", + "$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_test_017.cpp", + "$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_test_018.cpp", + "$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_test_019.cpp", + "$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_test_020.cpp", + "$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_test_021.cpp", + "$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_test_022.cpp", + "$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_test_023.cpp", + "$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_test_024.cpp", + "$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_test_025.cpp", + "$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_test_026.cpp", + "$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_test_027.cpp", +] + +process_basic_pthread_sources_full = [ + "$TEST_UNITTEST_DIR/process/basic/pthread/full/pthread_test_001.cpp", + "$TEST_UNITTEST_DIR/process/basic/pthread/full/pthread_test_002.cpp", + "$TEST_UNITTEST_DIR/process/basic/pthread/full/pthread_test_004.cpp", + "$TEST_UNITTEST_DIR/process/basic/pthread/full/pthread_test_005.cpp", + "$TEST_UNITTEST_DIR/process/basic/pthread/full/pthread_test_014.cpp", +] + +# process basic pthread module +if (LOSCFG_USER_TEST_PROCESS_BASIC_PTHREAD == true) { + common_include_dirs += process_basic_pthread_include_dirs + sources_entry += process_basic_pthread_sources_entry + sources_smoke += process_basic_pthread_sources_smoke + sources_full += process_basic_pthread_sources_full +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/full/pthread_test_001.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/full/pthread_test_001.cpp new file mode 100644 index 00000000..b43e9ab3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/full/pthread_test_001.cpp @@ -0,0 +1,279 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_pthread_test.h" + +static int g_currThreadPri, g_currThreadPolicy; +static volatile int g_pthreadTestCount = 0; +static int g_threadTestCount1 = 0; + +static void *ThreadFunc5(void *ptr) +{ + pid_t pid = getpid(); + int ret; + + ICUNIT_GOTO_EQUAL(g_threadTestCount1, 2, g_threadTestCount1, EXIT); // 2, here assert the result. + g_threadTestCount1++; + + ret = pthread_detach(pthread_self()); + ICUNIT_GOTO_EQUAL(ret, EINVAL, ret, EXIT); + +EXIT: + return NULL; +} + +static void *ThreadFunc4(void *arg) +{ + pthread_t pthread = pthread_self(); + int i = 0; + unsigned int ret; + pid_t pid = getpid(); + + ICUNIT_GOTO_EQUAL(g_pthreadTestCount, 9, g_pthreadTestCount, EXIT); // 9, here assert the result. + g_pthreadTestCount++; // 10 + + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + + while (1) { + pthread_testcancel(); + if (++i == 5) { // 5, in loop 5, set cancel state. + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + } + + if (i == 10) { // 10, in loop 10, cancel pthread. + ret = pthread_cancel(pthread); + } + } + return reinterpret_cast(i); + +EXIT: + return NULL; +} + +static void *ThreadFunc3(void *arg) +{ + pthread_t pthread = pthread_self(); + int i = 0; + unsigned int ret; + pid_t pid = getpid(); + + g_pthreadTestCount++; // 7 + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); + + while (1) { + pthread_testcancel(); + if (++i == 5) { // 5, in loop 5, set cancel state. + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + } + + if (i == 10) { // 10, in loop 10, cancel pthread. + ret = pthread_cancel(pthread); + } + } + + ICUNIT_GOTO_EQUAL(i, 10, i, EXIT); // 10, here assert the result. + return reinterpret_cast(i); +EXIT: + return NULL; +} + +static void *ThreadFunc2(void *arg) +{ + pthread_t pthread = pthread_self(); + pid_t pid = getpid(); + unsigned int ret; + + ICUNIT_GOTO_EQUAL(g_pthreadTestCount, 3, g_pthreadTestCount, EXIT); // 3, here assert the result. + + g_pthreadTestCount++; // 4 + + ret = pthread_join(pthread_self(), 0); + ICUNIT_GOTO_EQUAL(ret, EINVAL, ret, EXIT); + + ret = pthread_detach(pthread_self()); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + +EXIT: + return NULL; +} + +static void *ThreadFunc6(void *arg) +{ + pid_t pid = getpid(); + + ICUNIT_GOTO_EQUAL(g_pthreadTestCount, 12, g_pthreadTestCount, EXIT); // 12, here assert the result. + g_pthreadTestCount++; // 13 + + return reinterpret_cast(pthread_self()); + +EXIT: + return NULL; +} + +static void *ThreadFunc(void *arg) +{ + unsigned int ret; + void *res = NULL; + pthread_attr_t a = { 0 }; + pthread_t newPthread; + struct sched_param param = { 0 }; + pid_t pid = getpid(); + int curThreadPri, curThreadPolicy; + + ICUNIT_GOTO_EQUAL(g_pthreadTestCount, 2, g_pthreadTestCount, EXIT); // 2, here assert the result. + + g_pthreadTestCount++; // 3 + + ret = pthread_getschedparam(pthread_self(), &curThreadPolicy, ¶m); + ICUNIT_GOTO_EQUAL(ret, 0, -ret, EXIT); + + curThreadPri = param.sched_priority; + + ret = pthread_attr_init(&a); + pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED); + param.sched_priority = curThreadPri - 1; + pthread_attr_setschedparam(&a, ¶m); + ret = pthread_create(&newPthread, &a, ThreadFunc2, 0); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + +#ifdef LOSCFG_USER_TEST_SMP + usleep(1000 * 10 * 2); // 1000 * 10 * 2, for timing control. +#endif + ICUNIT_GOTO_EQUAL(g_pthreadTestCount, 4, g_pthreadTestCount, EXIT); // 4, here assert the result. + + g_pthreadTestCount++; // 5 + + ret = pthread_attr_init(&a); + pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED); + param.sched_priority = curThreadPri + 1; + pthread_attr_setschedparam(&a, ¶m); + ret = pthread_create(&newPthread, &a, ThreadFunc3, 0); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_pthreadTestCount++; // 6 + + ret = pthread_join(newPthread, &res); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_pthreadTestCount, 7, g_pthreadTestCount, EXIT); // 7, here assert the result. + g_pthreadTestCount++; // 8 + + ret = pthread_attr_init(&a); + pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED); + param.sched_priority = curThreadPri + 2; // 2, adjust the priority. + pthread_attr_setschedparam(&a, ¶m); + ret = pthread_create(&newPthread, &a, ThreadFunc4, 0); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_pthreadTestCount, 8, g_pthreadTestCount, EXIT); // 8, here assert the result. + g_pthreadTestCount++; // 9 + + ret = pthread_join(newPthread, &res); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_pthreadTestCount, 10, g_pthreadTestCount, EXIT); // 10, here assert the result. + g_pthreadTestCount++; // 11 + +EXIT: + return NULL; +} + +int PthreadTest001() +{ + struct sched_param param = { 0 }; + int ret; + void *res = NULL; + pthread_attr_t a = { 0 }; + pthread_t newPthread, newPthread1; + int count = 0xf0000; + g_threadTestCount1 = 0; + g_pthreadTestCount = 0; + + ret = pthread_getschedparam(pthread_self(), &g_currThreadPolicy, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, -ret); + + g_currThreadPri = param.sched_priority; + + g_pthreadTestCount++; + + ret = pthread_attr_init(&a); + pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED); + param.sched_priority = g_currThreadPri + 1; + pthread_attr_setschedparam(&a, ¶m); + pthread_attr_setschedpolicy(&a, g_currThreadPolicy); + ret = pthread_create(&newPthread, &a, ThreadFunc, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_EQUAL(g_pthreadTestCount, 1, g_pthreadTestCount); + g_pthreadTestCount++; // 2 + + ret = pthread_create(&newPthread1, &a, ThreadFunc5, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + g_threadTestCount1++; + ICUNIT_ASSERT_EQUAL(g_threadTestCount1, 1, g_threadTestCount1); + + ret = pthread_detach(newPthread1); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + g_threadTestCount1++; + ICUNIT_ASSERT_EQUAL(g_threadTestCount1, 2, g_threadTestCount1); // 2, here assert the result. + ret = pthread_join(newPthread, &res); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_EQUAL(g_threadTestCount1, 3, g_threadTestCount1); // 3, here assert the result. + ICUNIT_ASSERT_EQUAL(g_pthreadTestCount, 11, g_pthreadTestCount); // 11, here assert the result. + g_pthreadTestCount++; // 12 + + param.sched_priority = g_currThreadPri - 1; + pthread_attr_setschedparam(&a, ¶m); + ret = pthread_create(&newPthread1, &a, ThreadFunc6, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + +#ifdef LOSCFG_USER_TEST_SMP + usleep(1000 * 10 * 10); // 1000 * 10 * 10, for timing control. +#endif + + ICUNIT_ASSERT_EQUAL(g_pthreadTestCount, 13, g_pthreadTestCount); // 13, here assert the result. + g_pthreadTestCount++; // 14 + + ret = pthread_detach(newPthread1); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_EQUAL(g_pthreadTestCount, 14, g_pthreadTestCount); // 14, here assert the result. + + return 0; +} + +void ItTestPthread001(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_001", PthreadTest001, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/full/pthread_test_002.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/full/pthread_test_002.cpp new file mode 100644 index 00000000..9df31cc1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/full/pthread_test_002.cpp @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_pthread_test.h" + +static int g_currThreadPri, g_currThreadPolicy; +static volatile int g_testCnt1 = 0; +static volatile int g_testCnt2 = 0; +static volatile int g_testPthredCount = 0; + +static void ThreadWaitCount(int scount, volatile int *ent) +{ + int count = 0xf0000; + while (*ent < scount) { + while (count > 0) { + count--; + } + count = 0xf0000; + (*ent)++; + } +} + +static void *ThreadFuncTest2(void *arg) +{ + (void)arg; + int ret; + struct sched_param param = { 0 }; + int threadPolicy, threadPri; + int old; + const int waitCount1 = 20; + const int waitCount2 = 50; + g_testCnt2 = 0; + + ThreadWaitCount(waitCount1 + g_testCnt2, &g_testCnt2); + + while (g_testCnt1 < 10) { // 10, wait until g_testCnt1 >= 10. + printf("\r"); + } + + g_testPthredCount++; + + param.sched_priority = g_currThreadPri + 1; + ret = pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶m); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + old = g_testCnt1; + param.sched_priority = 0; + ret = pthread_getschedparam(pthread_self(), &threadPolicy, ¶m); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ICUNIT_GOTO_EQUAL(threadPolicy, SCHED_FIFO, threadPolicy, EXIT); + ICUNIT_GOTO_EQUAL(param.sched_priority, (g_currThreadPri + 1), param.sched_priority, EXIT); + + ThreadWaitCount(waitCount2 + g_testCnt2, &g_testCnt2); + + ICUNIT_GOTO_EQUAL(g_testCnt1, old, g_testCnt1, EXIT); + + param.sched_priority = g_currThreadPri; + ret = pthread_setschedparam(pthread_self(), SCHED_RR, ¶m); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + old = g_testCnt1; + param.sched_priority = 0; + ret = pthread_getschedparam(pthread_self(), &threadPolicy, ¶m); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ICUNIT_GOTO_EQUAL(threadPolicy, SCHED_RR, threadPolicy, EXIT); + ICUNIT_GOTO_EQUAL(param.sched_priority, g_currThreadPri, param.sched_priority, EXIT); + + ThreadWaitCount(waitCount2 + g_testCnt2, &g_testCnt2); + + ICUNIT_GOTO_EQUAL(g_testCnt1, old, g_testCnt1, EXIT); + + ret = pthread_setschedprio(pthread_self(), g_currThreadPri + 1); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ThreadWaitCount(waitCount2 + g_testCnt2, &g_testCnt2); + ICUNIT_GOTO_EQUAL(g_testCnt2, 170, g_testCnt2, EXIT); // 170, here assert the result. + g_testPthredCount++; + +EXIT: + return NULL; +} + +static void *ThreadFuncTest3(void *arg) +{ + (void)arg; + struct sched_param param = { 0 }; + int threadPolicy, threadPri; + int ret; + int old = 0; + const int waitCount1 = 20; + const int waitCount2 = 50; + + g_testCnt1 = 0; + + ThreadWaitCount(waitCount1 + g_testCnt1, &g_testCnt1); + + while (g_testCnt2 < 10) { // 10, wait until g_testCnt2 >= 10. + printf("\r"); + } + + g_testPthredCount++; + param.sched_priority = g_currThreadPri + 1; + ret = pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶m); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + old = g_testCnt2; + param.sched_priority = 0; + ret = pthread_getschedparam(pthread_self(), &threadPolicy, ¶m); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ICUNIT_GOTO_EQUAL(threadPolicy, SCHED_FIFO, threadPolicy, EXIT); + ICUNIT_GOTO_EQUAL(param.sched_priority, (g_currThreadPri + 1), param.sched_priority, EXIT); + + ThreadWaitCount(waitCount2 + g_testCnt1, &g_testCnt1); + + ICUNIT_GOTO_EQUAL(g_testCnt2, old, g_testCnt2, EXIT); + + param.sched_priority = g_currThreadPri; + ret = pthread_setschedparam(pthread_self(), SCHED_RR, ¶m); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + old = g_testCnt2; + param.sched_priority = 0; + ret = pthread_getschedparam(pthread_self(), &threadPolicy, ¶m); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ICUNIT_GOTO_EQUAL(threadPolicy, SCHED_RR, threadPolicy, EXIT); + ICUNIT_GOTO_EQUAL(param.sched_priority, g_currThreadPri, param.sched_priority, EXIT); + + ThreadWaitCount(waitCount2 + g_testCnt1, &g_testCnt1); + + ICUNIT_GOTO_EQUAL(g_testCnt2, old, g_testCnt2, EXIT); + ICUNIT_GOTO_EQUAL(g_testCnt1, 120, g_testCnt1, EXIT); // 120, here assert the result. + g_testPthredCount++; + +EXIT: + return NULL; +} + +static int Testcase() +{ + struct sched_param param = { 0 }; + int ret; + void *res = NULL; + pthread_attr_t a = { 0 }; + pthread_t newPthread, newPthread1; + + g_testPthredCount = 0; + + ret = pthread_getschedparam(pthread_self(), &g_currThreadPolicy, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, -ret); + + g_currThreadPri = param.sched_priority; + + g_testPthredCount++; + + ret = pthread_attr_init(&a); + param.sched_priority = g_currThreadPri + 1; + pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED); + pthread_attr_setschedparam(&a, ¶m); + ret = pthread_create(&newPthread, &a, ThreadFuncTest2, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_EQUAL(g_testPthredCount, 1, g_testPthredCount); + g_testPthredCount++; // 2 + + ret = pthread_create(&newPthread1, &a, ThreadFuncTest3, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_EQUAL(g_testPthredCount, 2, g_testPthredCount); // 2, here assert the result. + g_testPthredCount++; // 3 + + ret = pthread_join(newPthread, &res); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newPthread1, &res); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_EQUAL(g_testPthredCount, 7, g_testPthredCount); // 7, here assert the result. + + return 0; +} + +void ItTestPthread002(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_002", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/full/pthread_test_004.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/full/pthread_test_004.cpp new file mode 100644 index 00000000..21613f9b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/full/pthread_test_004.cpp @@ -0,0 +1,391 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_pthread_test.h" + +static int g_currThreadPri, g_currThreadPolicy; +static volatile int g_pthreadTestCount = 0; +static volatile int g_threadTestCount1 = 0; +static pthread_spinlock_t g_spinTestLock; + +static void *ThreadFunc8(void *arg) +{ + pthread_t pthread = pthread_self(); + int ret; + + ret = pthread_detach(pthread); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_spin_lock(&g_spinTestLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + g_threadTestCount1++; + ret = pthread_spin_unlock(&g_spinTestLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + +EXIT: + return NULL; +} + +static void *ThreadFunc7(void *arg) +{ + pthread_t pthread = pthread_self(); + int ret; + pthread_attr_t a = { 0 }; + struct sched_param param = { 0 }; + pthread_t newPthread; + int curThreadPri, curThreadPolicy; + + ret = pthread_detach(pthread); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_getschedparam(pthread_self(), &curThreadPolicy, ¶m); + ICUNIT_GOTO_EQUAL(ret, 0, -ret, EXIT); + + curThreadPri = param.sched_priority; + + ret = pthread_attr_init(&a); + pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED); + param.sched_priority = curThreadPri; + pthread_attr_setschedparam(&a, ¶m); + ret = pthread_create(&newPthread, &a, ThreadFunc8, 0); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_spin_lock(&g_spinTestLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + g_threadTestCount1++; + ret = pthread_spin_unlock(&g_spinTestLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + sleep(2); // 2, delay +EXIT: + return NULL; +} + +static void *ThreadFunc5(void *arg) +{ + pthread_attr_t a = { 0 }; + struct sched_param param = { 0 }; + int ret; + void *res = NULL; + pthread_t newPthread; + int curThreadPri, curThreadPolicy; + + ret = pthread_detach(pthread_self()); + ICUNIT_GOTO_EQUAL(ret, EINVAL, ret, EXIT); + + ret = pthread_getschedparam(pthread_self(), &curThreadPolicy, ¶m); + ICUNIT_GOTO_EQUAL(ret, 0, -ret, EXIT); + + curThreadPri = param.sched_priority; + + ret = pthread_attr_init(&a); + pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED); + param.sched_priority = curThreadPri + 1; + pthread_attr_setschedparam(&a, ¶m); + ret = pthread_create(&newPthread, &a, ThreadFunc7, 0); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_join(newPthread, &res); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_spin_lock(&g_spinTestLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + g_threadTestCount1++; + ret = pthread_spin_unlock(&g_spinTestLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + +EXIT: + return NULL; +} + +static void *ThreadFunc6(void *arg) +{ + pthread_t pthread = pthread_self(); + + ICUNIT_GOTO_EQUAL(g_pthreadTestCount, 12, g_pthreadTestCount, EXIT); // 12, here assert the result. + g_pthreadTestCount++; // 13 + + return (void *)(uintptr_t)pthread; + +EXIT: + return NULL; +} + +static void *ThreadFunc4(void *arg) +{ + pthread_t pthread = pthread_self(); + int i = 0; + unsigned int ret; + + ret = pthread_spin_lock(&g_spinTestLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_pthreadTestCount, 9, g_pthreadTestCount, EXIT); // 9, here assert the result. + g_pthreadTestCount++; // 10 + ret = pthread_spin_unlock(&g_spinTestLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + + while (1) { + pthread_testcancel(); + if (++i == 5) { // 5, in loop 5, set cancel state. + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + } + + if (i == 10) { // 10, in loop 10, cancel pthread. + ret = pthread_cancel(pthread); + } + } + return reinterpret_cast(i); + +EXIT: + return NULL; +} + +static void *ThreadFunc3(void *arg) +{ + pthread_t pthread = pthread_self(); + int i = 0; + unsigned int ret; + + ret = pthread_spin_lock(&g_spinTestLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_pthreadTestCount, 6, g_pthreadTestCount, EXIT); // 6, here assert the result. + g_pthreadTestCount++; // 7 + ret = pthread_spin_unlock(&g_spinTestLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); + + while (1) { + pthread_testcancel(); + if (++i == 5) { // 5, in loop 5, set cancel state. + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + } + + if (i == 10) { // 10, in loop 10, cancel pthread. + ret = pthread_cancel(pthread); + } + } + + ICUNIT_GOTO_EQUAL(i, 10, i, EXIT); // 10, here assert the result. + return reinterpret_cast(i); + +EXIT: + return NULL; +} + +static void *threadFunc2(void *arg) +{ + unsigned int ret; + + ret = pthread_spin_lock(&g_spinTestLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_pthreadTestCount, 3, g_pthreadTestCount, EXIT); // 3, here assert the result. + g_pthreadTestCount++; + ret = pthread_spin_unlock(&g_spinTestLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_join(pthread_self(), 0); + ICUNIT_GOTO_EQUAL(ret, EINVAL, ret, EXIT); + + ret = pthread_detach(pthread_self()); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + +EXIT: + return NULL; +} + +static void *threadFunc(void *arg) +{ + unsigned int ret; + void *res = NULL; + pthread_attr_t a = { 0 }; + pthread_t newPthread; + struct sched_param param = { 0 }; + + ret = pthread_spin_lock(&g_spinTestLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_pthreadTestCount, 2, g_pthreadTestCount, EXIT); // 2, here assert the result. + g_pthreadTestCount++; + ret = pthread_spin_unlock(&g_spinTestLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_attr_init(&a); + pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED); + param.sched_priority = g_currThreadPri; + pthread_attr_setschedparam(&a, ¶m); + ret = pthread_create(&newPthread, &a, threadFunc2, 0); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + +#ifdef LOSCFG_USER_TEST_SMP + sleep(1); +#endif + + ret = pthread_spin_lock(&g_spinTestLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_pthreadTestCount, 4, g_pthreadTestCount, EXIT); // 4, here assert the result. + g_pthreadTestCount++; // 5 + ret = pthread_spin_unlock(&g_spinTestLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_attr_init(&a); + pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED); + param.sched_priority = g_currThreadPri + 2; // 2, adjust priority. + pthread_attr_setschedparam(&a, ¶m); + ret = pthread_create(&newPthread, &a, ThreadFunc3, 0); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_spin_lock(&g_spinTestLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_pthreadTestCount, 5, g_pthreadTestCount, EXIT); // 5, here assert the result. + g_pthreadTestCount++; // 6 + ret = pthread_spin_unlock(&g_spinTestLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_join(newPthread, &res); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_spin_lock(&g_spinTestLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_pthreadTestCount, 7, g_pthreadTestCount, EXIT); // 7, here assert the result. + g_pthreadTestCount++; // 8 + ret = pthread_spin_unlock(&g_spinTestLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_attr_init(&a); + pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED); + param.sched_priority = g_currThreadPri + 3; // 3, adjust priority. + pthread_attr_setschedparam(&a, ¶m); + ret = pthread_create(&newPthread, &a, ThreadFunc4, 0); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_spin_lock(&g_spinTestLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_pthreadTestCount, 8, g_pthreadTestCount, EXIT); // 8, here assert the result. + g_pthreadTestCount++; // 9 + ret = pthread_spin_unlock(&g_spinTestLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_join(newPthread, &res); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_spin_lock(&g_spinTestLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ICUNIT_GOTO_EQUAL(g_pthreadTestCount, 10, g_pthreadTestCount, EXIT); // 10, here assert the result. + g_pthreadTestCount++; // 11 + ret = pthread_spin_unlock(&g_spinTestLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + +EXIT: + return NULL; +} + +int PthreadTest004() +{ + int exitCount = 0; + struct sched_param param = { 0 }; + int ret; + void *res = NULL; + pthread_attr_t a = { 0 }; + pthread_t newPthread, newPthread1; + const int testCount = 5; + int count = 5; + pthread_spin_init(&g_spinTestLock, 0); + + g_threadTestCount1 = 0; + g_pthreadTestCount = 0; + + ret = pthread_getschedparam(pthread_self(), &g_currThreadPolicy, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, -ret); + + g_currThreadPri = param.sched_priority; + + g_pthreadTestCount++; + + ret = pthread_attr_init(&a); + pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED); + param.sched_priority = g_currThreadPri + 1; + pthread_attr_setschedparam(&a, ¶m); + ret = pthread_create(&newPthread, &a, threadFunc, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_EQUAL(g_pthreadTestCount, 1, g_pthreadTestCount); + g_pthreadTestCount++; + + while (count > 0) { + ret = pthread_create(&newPthread1, &a, ThreadFunc5, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_detach(newPthread1); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + count--; + } + + g_threadTestCount1++; + ICUNIT_ASSERT_EQUAL(g_threadTestCount1, 1, g_threadTestCount1); + + ret = pthread_join(newPthread, &res); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + while (g_threadTestCount1 != (1 + (testCount * 3))) { // 3 + sleep(2); // 2, delay + printf("Wait for the concurrent thread to end \n"); + exitCount++; + if (exitCount > 10) { // wait time > 10 * 2s, cancel wait. + break; + } + } + + ICUNIT_ASSERT_EQUAL(g_pthreadTestCount, 11, g_pthreadTestCount); // 11, here assert the result. + g_pthreadTestCount++; // 12 + + param.sched_priority = g_currThreadPri - 1; + pthread_attr_setschedparam(&a, ¶m); + ret = pthread_create(&newPthread1, &a, ThreadFunc6, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newPthread1, &res); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_EQUAL(g_pthreadTestCount, 13, g_pthreadTestCount); // 13, here assert the result. + g_pthreadTestCount++; // 14 + + ICUNIT_ASSERT_EQUAL(g_pthreadTestCount, 14, g_pthreadTestCount); // 14, here assert the result. + + pthread_spin_destroy(&g_spinTestLock); + + return 0; +} + +void ItTestPthread004(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_004", PthreadTest004, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/full/pthread_test_005.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/full/pthread_test_005.cpp new file mode 100644 index 00000000..9ce521f6 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/full/pthread_test_005.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_pthread_test.h" + +extern int PthreadTest001(void); +extern int PthreadTest004(void); + +static void *threadFunc(void *a) +{ + int ret; + int status; + int pid; + + pid = fork(); + if (pid == 0) { + (void)PthreadTest004(); + (void)PthreadTest001(); + exit(12); // 12, set a special exit code. + } + + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, The pid will never exceed 100000. + sleep(10); // 10, delay for timimg control. + + ret = PthreadTest001(); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + +EXIT: + (void)waitpid(pid, &status, 0); + return NULL; +} + +static int Testcase(void) +{ + int ret; + int status; + int pid; + pthread_t tid; + + ret = fork(); + if (ret == 0) { + ret = pthread_create(&tid, NULL, threadFunc, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(tid, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + exit(10); // 10, set a special exit code. + } else if (ret > 0) { + pid = ret; + sleep(10); // 10, delay for timimg control. + (void)PthreadTest004(); + ret = wait(&status); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ICUNIT_ASSERT_EQUAL(status, 10, status); // 10, assert the exit code. + } + + ICUNIT_ASSERT_WITHIN_EQUAL(pid, 0, 100000, pid); // 100000, The pid will never exceed 100000. + + return 0; +} + +void ItTestPthread005(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_005", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/full/pthread_test_014.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/full/pthread_test_014.cpp new file mode 100644 index 00000000..bdabbaf7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/full/pthread_test_014.cpp @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_pthread_test.h" +#include "threads.h" +static const int TEST_LOOP = 5000; + +static int g_testCnt = 0; +static void *ThreadFunc(void *arg) +{ + int count = 1; + while (g_testCnt < TEST_LOOP) { + if (g_testCnt != count) { + printf("%s %d g_testCnt should : %d but is : %d\n", __FUNCTION__, __LINE__, count, g_testCnt); + return NULL; + } + g_testCnt++; + count += 5; // total 5 pthreads. + thrd_yield(); + } + + g_testCnt = TEST_LOOP + 1000; // 1000, here set a special num. + return NULL; +} + +static void *ThreadFunc1(void *arg) +{ + int count = 2; + while (g_testCnt < TEST_LOOP) { + if (g_testCnt != count) { + printf("%s %d g_testCnt should : %d but is : %d\n", __FUNCTION__, __LINE__, count, g_testCnt); + return NULL; + } + g_testCnt++; + count += 5; // total 5 pthreads. + thrd_yield(); + } + + return NULL; +} + +static void *ThreadFunc2(void *arg) +{ + int count = 3; + while (g_testCnt < TEST_LOOP) { + if (g_testCnt != count) { + printf("%s %d g_testCnt should : %d but is : %d\n", __FUNCTION__, __LINE__, count, g_testCnt); + return NULL; + } + g_testCnt++; + count += 5; // total 5 pthreads. + thrd_yield(); + } + + return NULL; +} + +static void *ThreadFunc3(void *arg) +{ + int count = 4; + while (g_testCnt < TEST_LOOP) { + if (g_testCnt != count) { + printf("%s %d g_testCnt should : %d but is : %d\n", __FUNCTION__, __LINE__, count, g_testCnt); + return NULL; + } + g_testCnt++; + count += 5; // total 5 pthreads. + thrd_yield(); + } + + return NULL; +} + +static int TestCase(void) +{ + int ret; + pthread_t tid, tid1, tid2, tid3; + pthread_attr_t attr = { 0 }; + int scope = 0; + int threadPolicy = 0; + struct sched_param param = { 0 }; + + g_testCnt = 0; + + ret = pthread_getschedparam(pthread_self(), &threadPolicy, ¶m); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶m); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_create(&tid, NULL, ThreadFunc, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&tid1, NULL, ThreadFunc1, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&tid2, NULL, ThreadFunc2, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&tid3, NULL, ThreadFunc3, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + while (g_testCnt < TEST_LOOP) { + g_testCnt++; + thrd_yield(); + } + + param.sched_priority -= 2; // 2, adjust the priority. + ret = pthread_setschedparam(tid, SCHED_FIFO, ¶m); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCnt, TEST_LOOP + 1000, g_testCnt, EXIT); // 1000, here assert the special num. + + ret = pthread_join(tid, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = pthread_join(tid1, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = pthread_join(tid2, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = pthread_join(tid3, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + param.sched_priority += 2; // 2, adjust the priority. + ret = pthread_setschedparam(pthread_self(), SCHED_RR, ¶m); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + +EXIT: + return 0; +} + +void ItTestPthread014(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_014", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/it_pthread_test.h b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/it_pthread_test.h new file mode 100644 index 00000000..afcef819 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/it_pthread_test.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _IT_PTHREAD_TEST_H +#define _IT_PTHREAD_TEST_H + +#include "osTest.h" +#include +#include +#include + +#define SLEEP_AND_YIELD(tick) usleep((tick)*10 * 1000) + +#include "sys/syscall.h" + +static inline int Syscall(int nbr, int parm1, int parm2, int parm3, int parm4) +{ + register int reg7 __asm__("r7") = nbr; + register int reg3 __asm__("r3") = parm4; + register int reg2 __asm__("r2") = parm3; + register int reg1 __asm__("r1") = parm2; + register int reg0 __asm__("r0") = parm1; + + __asm__ __volatile__("svc 0" : "=r"(reg0) : "r"(reg7), "r"(reg0), "r"(reg1), "r"(reg2), "r"(reg3) : "memory"); + + return reg0; +} +extern INT32 g_iCunitErrCode; +extern INT32 g_iCunitErrLineNo; + +extern void ItTestPthread001(void); +extern void ItTestPthread002(void); +extern void ItTestPthread003(void); +extern void ItTestPthread004(void); +extern void ItTestPthread005(void); +extern void ItTestPthread006(void); +extern void ItTestPthread007(void); +extern void ItTestPthread008(void); +extern void ItTestPthread009(void); +extern void ItTestPthread010(void); +extern void ItTestPthread012(void); +extern void ItTestPthread011(void); +extern void ItTestPthread013(void); +extern void ItTestPthread014(void); +extern void ItTestPthread015(void); +extern void ItTestPthread016(void); +extern void ItTestPthread017(void); +extern void ItTestPthread018(void); +extern void ItTestPthread019(void); +extern void ItTestPthread020(void); +extern void ItTestPthread021(void); +extern void ItTestPthread022(void); +extern void ItTestPthread023(void); +extern void ItTestPthread024(void); +extern void ItTestPthread025(void); +extern void ItTestPthread026(void); +extern void ItTestPthread027(void); +extern void ItTestPthreadAtfork001(void); +extern void ItTestPthreadAtfork002(void); +extern void ItTestPthreadOnce001(void); +extern void ItTestPthreadCond001(void); +extern void ItTestPthreadCond002(void); +extern void ItTestPthreadCond003(void); +extern void ItTestPthreadCond004(void); +#endif diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/process_pthread_test.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/process_pthread_test.cpp new file mode 100644 index 00000000..3c2187c3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/process_pthread_test.cpp @@ -0,0 +1,425 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "stdio.h" +#include +#include +#include "it_pthread_test.h" +#include + +using namespace testing::ext; +namespace OHOS { +class ProcessPthreadTest : public testing::Test { +public: + static void SetUpTestCase(void) + { + struct sched_param param = { 0 }; + int currThreadPolicy, ret; + ret = pthread_getschedparam(pthread_self(), &currThreadPolicy, ¶m); + ICUNIT_ASSERT_EQUAL_VOID(ret, 0, -ret); + param.sched_priority = TASK_PRIO_TEST; + ret = pthread_setschedparam(pthread_self(), SCHED_RR, ¶m); + ICUNIT_ASSERT_EQUAL_VOID(ret, 0, -ret); + } + static void TearDownTestCase(void) {} +}; + +#if defined(LOSCFG_USER_TEST_SMOKE) +/* * + * @tc.name: it_test_pthread_003 + * @tc.desc: function for ProcessPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessPthreadTest, ItTestPthread003, TestSize.Level0) +{ + ItTestPthread003(); +} + +#ifndef LOSCFG_USER_TEST_SMP +/* * + * @tc.name: it_test_pthread_006 + * @tc.desc: function for ProcessPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessPthreadTest, ItTestPthread006, TestSize.Level0) +{ + ItTestPthread006(); +} +#endif + +/* * + * @tc.name: it_test_pthread_007 + * @tc.desc: function for ProcessPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessPthreadTest, ItTestPthread007, TestSize.Level0) +{ + ItTestPthread007(); +} + +/* * + * @tc.name: it_test_pthread_008 + * @tc.desc: function for ProcessPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessPthreadTest, ItTestPthread008, TestSize.Level0) +{ + ItTestPthread008(); +} + +/* * + * @tc.name: it_test_pthread_009 + * @tc.desc: function for ProcessPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessPthreadTest, ItTestPthread009, TestSize.Level0) +{ + ItTestPthread009(); +} + +#ifndef LOSCFG_USER_TEST_SMP +/* * + * @tc.name: it_test_pthread_010 + * @tc.desc: function for ProcessPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessPthreadTest, ItTestPthread010, TestSize.Level0) +{ + ItTestPthread010(); +} +#endif + +/* * + * @tc.name: it_test_pthread_011 + * @tc.desc: function for ProcessPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessPthreadTest, ItTestPthread011, TestSize.Level0) +{ + ItTestPthread011(); +} + +/* * + * @tc.name: it_test_pthread_012 + * @tc.desc: function for ProcessPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessPthreadTest, ItTestPthread012, TestSize.Level0) +{ + ItTestPthread012(); +} + +/* * + * @tc.name: it_test_pthread_013 + * @tc.desc: function for ProcessPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessPthreadTest, ItTestPthread013, TestSize.Level0) +{ + ItTestPthread013(); +} + +/* * + * @tc.name: it_test_pthread_015 + * @tc.desc: function for ProcessPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessPthreadTest, ItTestPthread015, TestSize.Level0) +{ + ItTestPthread015(); +} + +/* * + * @tc.name: it_test_pthread_016 + * @tc.desc: function for ProcessPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessPthreadTest, ItTestPthread016, TestSize.Level0) +{ + ItTestPthread016(); +} + +/* * + * @tc.name: it_test_pthread_018 + * @tc.desc: function for ProcessPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessPthreadTest, ItTestPthread018, TestSize.Level0) +{ + ItTestPthread018(); +} + +/* * + * @tc.name: it_test_pthread_019 + * @tc.desc: function for ProcessPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessPthreadTest, ItTestPthread019, TestSize.Level0) +{ + ItTestPthread019(); +} + +/* * + * @tc.name: it_test_pthread_020 + * @tc.desc: function for ProcessPthreadTest + * @tc.type: FUNC + * @tc.require: issueI6T3P3 + * @tc.author: + */ +HWTEST_F(ProcessPthreadTest, ItTestPthread020, TestSize.Level0) +{ + ItTestPthread020(); +} + +/* * + * @tc.name: it_test_pthread_021 + * @tc.desc: function for ProcessPthreadTest + * @tc.type: FUNC + * @tc.require: issueI6T3P3 + * @tc.author: + */ +HWTEST_F(ProcessPthreadTest, ItTestPthread021, TestSize.Level0) +{ + ItTestPthread021(); +} + +/* * + * @tc.name: it_test_pthread_022 + * @tc.desc: function for ProcessPthreadTest + * @tc.type: FUNC + * @tc.require: issueI6T3P3 + * @tc.author: + */ +HWTEST_F(ProcessPthreadTest, ItTestPthread022, TestSize.Level0) +{ + ItTestPthread022(); +} + +/* * + * @tc.name: it_test_pthread_024 + * @tc.desc: function for ProcessPthreadTest + * @tc.type: FUNC + * @tc.require: issueI6T3P3 + * @tc.author: + */ +HWTEST_F(ProcessPthreadTest, ItTestPthread024, TestSize.Level0) +{ + ItTestPthread024(); +} + +/* * + * @tc.name: it_test_pthread_026 + * @tc.desc: function for ProcessPthreadTest + * @tc.type: FUNC + * @tc.require: issueI6T3P3 + * @tc.author: + */ +HWTEST_F(ProcessPthreadTest, ItTestPthread026, TestSize.Level0) +{ + ItTestPthread026(); +} + +/* * + * @tc.name: it_test_pthread_027 + * @tc.desc: function for ProcessPthreadTest + * @tc.type: FUNC + * @tc.require: issueI6T3P3 + * @tc.author: + */ +HWTEST_F(ProcessPthreadTest, ItTestPthread027, TestSize.Level0) +{ + ItTestPthread027(); +} + + +/* * + * @tc.name: it_test_pthread_023 + * @tc.desc: function for ProcessPthreadTest + * @tc.type: FUNC + * @tc.require: issueI6T3P3 + * @tc.author: + */ +HWTEST_F(ProcessPthreadTest, ItTestPthread023, TestSize.Level0) +{ + ItTestPthread023(); +} + + +/* * + * @tc.name: it_test_pthread_025 + * @tc.desc: function for ProcessPthreadTest + * @tc.type: FUNC + * @tc.require: issueI6T3P3 + * @tc.author: + */ +HWTEST_F(ProcessPthreadTest, ItTestPthread025, TestSize.Level0) +{ + ItTestPthread025(); +} + +/* * + * @tc.name: it_test_pthread_017 + * @tc.desc: function for ProcessPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessPthreadTest, ItTestPthread017, TestSize.Level0) +{ + ItTestPthread017(); +} + + +/* * + * @tc.name: it_test_pthread_once_001 + * @tc.desc: function for ProcessPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessPthreadTest, ItTestPthreadOnce001, TestSize.Level0) +{ + ItTestPthreadOnce001(); +} + +/* * + * @tc.name: it_test_pthread_atfork_001 + * @tc.desc: function for ProcessPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessPthreadTest, ItTestPthreadAtfork001, TestSize.Level0) +{ + ItTestPthreadAtfork001(); +} + +/* * + * @tc.name: it_test_pthread_atfork_002 + * @tc.desc: function for ProcessPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessPthreadTest, ItTestPthreadAtfork002, TestSize.Level0) +{ + ItTestPthreadAtfork002(); +} + +/* * + * @tc.name: it_test_pthread_cond_001 + * @tc.desc: function for ProcessPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessPthreadTest, ItTestPthreadCond001, TestSize.Level0) +{ + ItTestPthreadCond001(); +} + +/* * + * @tc.name: it_test_pthread_cond_002 + * @tc.desc: function for ProcessPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessPthreadTest, ItTestPthreadCond002, TestSize.Level0) +{ + ItTestPthreadCond002(); +} + +/* * + * @tc.name: it_test_pthread_cond_003 + * @tc.desc: function for ProcessPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessPthreadTest, ItTestPthreadCond003, TestSize.Level0) +{ + ItTestPthreadCond003(); +} + +/* * + * @tc.name: it_test_pthread_cond_004 + * @tc.desc: function for ProcessPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessPthreadTest, ItTestPthreadCond004, TestSize.Level0) +{ + ItTestPthreadCond004(); +} + +#endif + +#if defined(LOSCFG_USER_TEST_FULL) +/* * + * @tc.name: it_test_pthread_001 + * @tc.desc: function for ProcessPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessPthreadTest, ItTestPthread001, TestSize.Level0) +{ + ItTestPthread001(); +} + +#ifndef LOSCFG_USER_TEST_SMP +/* * + * @tc.name: it_test_pthread_002 + * @tc.desc: function for ProcessPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessPthreadTest, ItTestPthread002, TestSize.Level0) +{ + ItTestPthread002(); +} +#endif +/* * + * @tc.name: it_test_pthread_004 + * @tc.desc: function for ProcessPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessPthreadTest, ItTestPthread004, TestSize.Level0) +{ + ItTestPthread004(); +} + +/* * + * @tc.name: it_test_pthread_005 + * @tc.desc: function for ProcessPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessPthreadTest, ItTestPthread005, TestSize.Level0) +{ + ItTestPthread005(); +} + +#ifndef LOSCFG_USER_TEST_SMP +/* * + * @tc.name: it_test_pthread_014 + * @tc.desc: function for ProcessPthreadTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessPthreadTest, ItTestPthread014, TestSize.Level0) +{ + ItTestPthread014(); +} +#endif + +#endif +} // namespace OHOS diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_atfork_test_001.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_atfork_test_001.cpp new file mode 100644 index 00000000..9c3a3a3c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_atfork_test_001.cpp @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_pthread_test.h" + +static volatile int g_count = 0; +static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER; +static int g_testAtforkCount = 0; +static int g_testAtforkPrepare = 0; +static int g_testAtforkParent = 0; +static int g_testAtforkChild = 0; +static const int SLEEP_TIME = 2; + +static void Prepare() +{ + int err; + ICUNIT_ASSERT_EQUAL_VOID(g_testAtforkCount, 1, g_testAtforkCount); + err = pthread_mutex_lock(&g_lock); + ICUNIT_ASSERT_EQUAL_VOID(err, 0, err); + g_testAtforkPrepare++; +} + +static void Parent() +{ + int err; + ICUNIT_ASSERT_EQUAL_VOID(g_testAtforkCount, 1, g_testAtforkCount); + + err = pthread_mutex_unlock(&g_lock); + ICUNIT_ASSERT_EQUAL_VOID(err, 0, err); + g_testAtforkParent++; +} + +static void child() +{ + int err; + ICUNIT_ASSERT_EQUAL_VOID(g_testAtforkCount, 1, g_testAtforkCount); + + err = pthread_mutex_unlock(&g_lock); + ICUNIT_ASSERT_EQUAL_VOID(err, 0, err); + g_testAtforkChild++; +} + +static void *ThreadProc(void *arg) +{ + int err; + + while (g_count < 5) { // 5, wait until g_count == 5. + err = pthread_mutex_lock(&g_lock); + ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); + g_count++; + SLEEP_AND_YIELD(SLEEP_TIME); + err = pthread_mutex_unlock(&g_lock); + ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); + SLEEP_AND_YIELD(SLEEP_TIME); + } + +EXIT: + return NULL; +} + +static void *PthreadAtforkTest(void *arg) +{ + int err; + pid_t pid; + pthread_t tid; + int status = 0; + + g_count = 0; + g_testAtforkCount = 0; + g_testAtforkPrepare = 0; + g_testAtforkParent = 0; + g_testAtforkChild = 0; + + err = pthread_create(&tid, NULL, ThreadProc, NULL); + ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); + err = pthread_atfork(Prepare, Parent, child); + ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); + + g_testAtforkCount++; + + SLEEP_AND_YIELD(SLEEP_TIME); + + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, The pid will never exceed 100000. + ICUNIT_GOTO_EQUAL(g_testAtforkPrepare, 1, g_testAtforkPrepare, EXIT); + + if (pid == 0) { + ICUNIT_GOTO_EQUAL(g_testAtforkChild, 1, g_testAtforkChild, EXIT); + int status; + while (g_count < 5) { // 5, wait until g_count == 5. + err = pthread_mutex_lock(&g_lock); + ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); + g_count++; + SLEEP_AND_YIELD(SLEEP_TIME); + err = pthread_mutex_unlock(&g_lock); + ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); + SLEEP_AND_YIELD(SLEEP_TIME); + } + exit(15); // 15, set exit status + } + + ICUNIT_GOTO_EQUAL(g_testAtforkParent, 1, g_testAtforkParent, EXIT_WAIT); + err = pthread_join(tid, NULL); + ICUNIT_GOTO_EQUAL(err, 0, err, EXIT_WAIT); + + err = waitpid(pid, &status, 0); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(err, pid, err, EXIT); + ICUNIT_GOTO_EQUAL(status, 15, status, EXIT); // 15, get exit status. + +EXIT: + return NULL; + +EXIT_WAIT: + (void)waitpid(pid, &status, 0); + return NULL; +} + +static int Testcase() +{ + int ret; + pthread_t newPthread; + int curThreadPri, curThreadPolicy; + pthread_attr_t a = { 0 }; + struct sched_param param = { 0 }; + + ret = pthread_getschedparam(pthread_self(), &curThreadPolicy, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, -ret); + + curThreadPri = param.sched_priority; + + ret = pthread_attr_init(&a); + pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED); + param.sched_priority = curThreadPri + 2; // 2, adjust the priority. + pthread_attr_setschedparam(&a, ¶m); + ret = pthread_create(&newPthread, &a, PthreadAtforkTest, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newPthread, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return 0; +} + +void ItTestPthreadAtfork001(void) +{ + TEST_ADD_CASE("IT_PTHREAD_ATFORK_001", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_atfork_test_002.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_atfork_test_002.cpp new file mode 100644 index 00000000..018d6139 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_atfork_test_002.cpp @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_pthread_test.h" +#include + +extern int nanosleep(const struct timespec *req, struct timespec *rem); + +static pthread_mutex_t g_mux = PTHREAD_MUTEX_INITIALIZER; +static volatile int g_testAtforkCount = 0; +static int g_testAtforkPrepare = 0; +static int g_testAtforkParent = 0; + +static void *Doit(void *arg) +{ + int err; + struct timespec ts = { 2, 0 }; // 2, set time 2s. + + ICUNIT_GOTO_EQUAL(g_testAtforkCount, 1, g_testAtforkCount, EXIT); + + err = pthread_mutex_lock(&g_mux); + ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); + + (void)nanosleep(&ts, NULL); + err = pthread_mutex_unlock(&g_mux); + ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); + +EXIT: + return NULL; +} + +static void *Doit1(void *arg) +{ + int err; + struct timespec ts = { 2, 0 }; // 2, set time 2s. + + ICUNIT_GOTO_EQUAL(g_testAtforkCount, 1, g_testAtforkCount, EXIT); + + err = pthread_mutex_lock(&g_mux); + ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); + + (void)nanosleep(&ts, NULL); + err = pthread_mutex_unlock(&g_mux); + ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); + +EXIT: + return NULL; +} + +static void Prepare(void) +{ + int err; + + err = pthread_mutex_unlock(&g_mux); + ICUNIT_ASSERT_EQUAL_VOID(err, 0, err); + g_testAtforkPrepare++; +} + +static void Parent(void) +{ + int err = pthread_mutex_lock(&g_mux); + ICUNIT_ASSERT_EQUAL_VOID(err, 0, err); + g_testAtforkParent++; +} + +static void *PthreadAtforkTest(void *arg) +{ + int err, ret; + int pid; + int status = 0; + struct timespec ts = { 1, 0 }; + pthread_t tid; + + g_testAtforkCount = 0; + g_testAtforkPrepare = 0; + g_testAtforkParent = 0; + + err = pthread_atfork(Prepare, Parent, NULL); + ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); + g_testAtforkCount++; + err = pthread_create(&tid, NULL, Doit, NULL); + ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); + + nanosleep(&ts, NULL); + pid = fork(); + ICUNIT_GOTO_EQUAL(g_testAtforkPrepare, 1, g_testAtforkPrepare, EXIT); + if (pid == 0) { + Doit1(NULL); + exit(10); // 10, set exit status. + } + + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT_WAIT); // 100000, The pid will never exceed 100000. + ICUNIT_GOTO_EQUAL(g_testAtforkParent, 1, g_testAtforkParent, EXIT_WAIT); + + err = pthread_join(tid, NULL); + ICUNIT_GOTO_EQUAL(err, 0, err, EXIT_WAIT); + + + err = waitpid(pid, &status, 0); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(err, pid, err, EXIT); + ICUNIT_GOTO_EQUAL(status, 10, status, EXIT); // 10, get exit status. + +EXIT: + return NULL; + +EXIT_WAIT: + (void)waitpid(pid, 0, 0); + return NULL; +} + +static int Testcase(void) +{ + int ret; + pthread_t newPthread; + int curThreadPri, curThreadPolicy; + pthread_attr_t a = { 0 }; + struct sched_param param = { 0 }; + + ret = pthread_getschedparam(pthread_self(), &curThreadPolicy, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, -ret); + + curThreadPri = param.sched_priority; + + ret = pthread_attr_init(&a); + pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED); + param.sched_priority = curThreadPri + 2; // 2, adjust the priority. + pthread_attr_setschedparam(&a, ¶m); + ret = pthread_create(&newPthread, &a, PthreadAtforkTest, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newPthread, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return 0; +} + +void ItTestPthreadAtfork002(void) +{ + TEST_ADD_CASE("IT_PTHREAD_ATFORK_002", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_cond_test_001.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_cond_test_001.cpp new file mode 100644 index 00000000..ed5debca --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_cond_test_001.cpp @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_pthread_test.h" + +static pthread_mutex_t g_pthreadMuxTest1; +static pthread_cond_t g_pthdCondTest1; + +static void *PthreadF01(void *t) +{ + int rc; + + rc = pthread_mutex_lock(&g_pthreadMuxTest1); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + g_testCount++; + LosTaskDelay(100); + ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, here assert the result. + g_testCount++; + + rc = pthread_cond_wait(&g_pthdCondTest1, &g_pthreadMuxTest1); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); // 5, here assert the result. + rc = pthread_mutex_unlock(&g_pthreadMuxTest1); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + +EXIT: + return NULL; +} + +static void *PthreadF02(void *t) +{ + int i; + int rc; + + ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); + g_testCount++; + rc = pthread_mutex_lock(&g_pthreadMuxTest1); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, here assert the result. + g_testCount++; + rc = pthread_cond_signal(&g_pthdCondTest1); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, here assert the result. + g_testCount++; + + rc = pthread_mutex_unlock(&g_pthreadMuxTest1); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + LosTaskDelay(2); // 2, delay for Timing control. + +EXIT: + pthread_exit(NULL); +} + +static unsigned int TestCase(void) +{ + int i; + long t1 = 1; + long t2 = 2; + int rc; + pthread_t threads[3]; // 3, need 3 pthread for test. + pthread_attr_t attr; + const int loopNum = 2; + + g_testCount = 0; + pthread_mutex_init(&g_pthreadMuxTest1, NULL); + pthread_cond_init(&g_pthdCondTest1, NULL); + + rc = pthread_create(&threads[0], NULL, PthreadF01, (void *)t1); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_create(&threads[1], NULL, PthreadF02, (void *)t2); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + for (i = 0; i < loopNum; i++) { + rc = pthread_join(threads[i], NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + } + + rc = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_mutex_destroy(&g_pthreadMuxTest1); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + rc = pthread_cond_destroy(&g_pthdCondTest1); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + return 0; +} + +void ItTestPthreadCond001(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_COND_001", TestCase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_cond_test_002.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_cond_test_002.cpp new file mode 100644 index 00000000..70a2f02c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_cond_test_002.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_pthread_test.h" + +static pthread_mutex_t g_pthreadMuxTest1; +static pthread_cond_t g_pthrdCondTest1; +static unsigned int g_pthreadExit = 0; + +static void *PthreadF01(void *t) +{ + int rc; + unsigned int count = 0; + const int testLoop = 2000; + while (count < testLoop) { + rc = pthread_mutex_lock(&g_pthreadMuxTest1); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + rc = pthread_cond_wait(&g_pthrdCondTest1, &g_pthreadMuxTest1); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + rc = pthread_mutex_unlock(&g_pthreadMuxTest1); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + count++; + } + + g_pthreadExit = 1; +EXIT: + return NULL; +} + +static void *PthreadF02(void *t) +{ + int i; + int rc; + + while (g_pthreadExit != 1) { + rc = pthread_mutex_lock(&g_pthreadMuxTest1); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + rc = pthread_cond_signal(&g_pthrdCondTest1); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + + rc = pthread_mutex_unlock(&g_pthreadMuxTest1); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + } + +EXIT: + pthread_exit(NULL); +} + +static unsigned int TestCase(void) +{ + int i; + long t1 = 1; + long t2 = 2; + int rc; + pthread_t threads[3]; + pthread_attr_t attr; + const int loopNum = 2; + + g_pthreadExit = 0; + g_testCount = 0; + pthread_mutex_init(&g_pthreadMuxTest1, NULL); + pthread_cond_init(&g_pthrdCondTest1, NULL); + + rc = pthread_create(&threads[0], NULL, PthreadF01, (void *)t1); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_create(&threads[1], NULL, PthreadF02, (void *)t2); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + for (i = 0; i < loopNum; i++) { + rc = pthread_join(threads[i], NULL); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + } + + rc = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + rc = pthread_mutex_destroy(&g_pthreadMuxTest1); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + rc = pthread_cond_destroy(&g_pthrdCondTest1); + ICUNIT_ASSERT_EQUAL(rc, 0, rc); + + return 0; +} + +void ItTestPthreadCond002(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_COND_002", TestCase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_cond_test_003.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_cond_test_003.cpp new file mode 100644 index 00000000..736d7d5a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_cond_test_003.cpp @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_pthread_test.h" + +static pthread_cond_t g_pthread_cond; +static pthread_mutex_t g_pthread_mutex; +#define TEST_THREAD_COUNT 5 +static void *pthread_cond_func001(void *arg) +{ + int ret; + struct timespec ts; + + g_testCount++; + + ret = pthread_mutex_lock(&g_pthread_mutex); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + clock_gettime(CLOCK_REALTIME, &ts); + ts.tv_sec += 60; /* 60: wait 1 minute */ + + ret = pthread_cond_timedwait(&g_pthread_cond, &g_pthread_mutex, &ts); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_mutex_unlock(&g_pthread_mutex); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testCount++; +EXIT: + return NULL; +} + +static VOID *pthread_f06(void *argument) +{ + int policy; + int ret; + int i; + pthread_attr_t attr; + struct sched_param schedParam = { 0 }; + pthread_t thread[TEST_THREAD_COUNT]; + + g_testCount = 0; + + ret = pthread_attr_init(&attr); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_getschedparam(pthread_self(), &policy, &schedParam); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + schedParam.sched_priority -= 1; + ret = pthread_attr_setschedparam(&attr, &schedParam); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + for (i = 0; i < TEST_THREAD_COUNT; i++) { + ret = pthread_create(&thread[i], &attr, pthread_cond_func001, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + } + + sleep(1); + + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); /* 5: Five threads */ + + ret = pthread_mutex_lock(&g_pthread_mutex); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_cond_broadcast(&g_pthread_cond); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_mutex_unlock(&g_pthread_mutex); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + for (i = 0; i < TEST_THREAD_COUNT; i++) { + ret = pthread_join(thread[i], NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + } + + ICUNIT_GOTO_EQUAL(g_testCount, 10, g_testCount, EXIT); /* 10: Twice per thread */ +EXIT: + return NULL; +} + +static int TestCase(void) +{ + int policy; + pthread_attr_t attr; + pthread_t newTh; + struct sched_param schedParam = { 0 }; + int ret; + + ret = pthread_mutex_init(&g_pthread_mutex, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_cond_init(&g_pthread_cond, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_getschedparam(pthread_self(), &policy, &schedParam); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + schedParam.sched_priority -= 1; + ret = pthread_attr_setschedparam(&attr, &schedParam); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newTh, &attr, pthread_f06, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return 0; +} + +void ItTestPthreadCond003(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_COND_003", TestCase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_cond_test_004.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_cond_test_004.cpp new file mode 100644 index 00000000..65480312 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_cond_test_004.cpp @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_pthread_test.h" +static pthread_cond_t g_pthread_cond; +static pthread_mutex_t g_pthread_mutex; +#define TEST_THREAD_COUNT 5 + +static void *pthread_cond_func002(void *arg) +{ + int ret; + struct timespec ts; + + g_testCount++; + + ret = pthread_mutex_lock(&g_pthread_mutex); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + clock_gettime(CLOCK_REALTIME, &ts); + ts.tv_sec += 2; /* 2: wait 2 seconds */ + + ret = pthread_cond_timedwait(&g_pthread_cond, &g_pthread_mutex, &ts); + ICUNIT_GOTO_EQUAL(ret, ETIMEDOUT, ret, EXIT); + + ret = pthread_mutex_unlock(&g_pthread_mutex); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testCount++; +EXIT: + return NULL; +} + +static VOID *pthread_f07(void *argument) +{ + int policy; + int ret; + int i; + pthread_attr_t attr; + struct sched_param schedParam = { 0 }; + pthread_t thread[TEST_THREAD_COUNT]; + + g_testCount = 0; + + ret = pthread_attr_init(&attr); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_getschedparam(pthread_self(), &policy, &schedParam); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + schedParam.sched_priority -= 1; + ret = pthread_attr_setschedparam(&attr, &schedParam); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + for (i = 0; i < TEST_THREAD_COUNT; i++) { + ret = pthread_create(&thread[i], &attr, pthread_cond_func002, NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + } + + sleep(1); + + ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); /* 5: Five threads */ + + for (i = 0; i < TEST_THREAD_COUNT; i++) { + ret = pthread_join(thread[i], NULL); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + } + + ICUNIT_GOTO_EQUAL(g_testCount, 10, g_testCount, EXIT); /* 10: Twice per thread */ + +EXIT: + return NULL; +} + +static int TestCase(void) +{ + int policy; + pthread_attr_t attr; + pthread_t newTh; + struct sched_param schedParam = { 0 }; + int ret; + + ret = pthread_mutex_init(&g_pthread_mutex, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_cond_init(&g_pthread_cond, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_getschedparam(pthread_self(), &policy, &schedParam); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + schedParam.sched_priority -= 1; + ret = pthread_attr_setschedparam(&attr, &schedParam); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newTh, &attr, pthread_f07, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newTh, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return 0; +} + +void ItTestPthreadCond004(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_COND_004", TestCase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_once_test_001.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_once_test_001.cpp new file mode 100644 index 00000000..a779ba33 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_once_test_001.cpp @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_pthread_test.h" + +static int g_number = 0; +static int g_okStatus = 777; // 777, a special number indicate the status is ok. +static pthread_once_t g_onceCtrl = PTHREAD_ONCE_INIT; + +static void InitRoutine(void) +{ + g_number++; +} + +static void *Threadfunc(void *parm) +{ + int err; + err = pthread_once(&g_onceCtrl, InitRoutine); + ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); + return reinterpret_cast(g_okStatus); +EXIT: + return NULL; +} + +static void *ThreadFuncTest(void *arg) +{ + pthread_t thread[3]; + int rc = 0; + int i = 3; + void *status; + const int threadsNum = 3; + + g_number = 0; + + for (i = 0; i < threadsNum; ++i) { + rc = pthread_create(&thread[i], NULL, Threadfunc, NULL); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + } + + for (i = 0; i < threadsNum; ++i) { + rc = pthread_join(thread[i], &status); + ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); + ICUNIT_GOTO_EQUAL((unsigned int)status, (unsigned int)g_okStatus, status, EXIT); + } + + ICUNIT_GOTO_EQUAL(g_number, 1, g_number, EXIT); + +EXIT: + return NULL; +} + +static int Testcase(void) +{ + int ret; + pthread_t newPthread; + int curThreadPri, curThreadPolicy; + pthread_attr_t a = { 0 }; + struct sched_param param = { 0 }; + + g_onceCtrl = PTHREAD_ONCE_INIT; + + ret = pthread_getschedparam(pthread_self(), &curThreadPolicy, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, -ret); + + curThreadPri = param.sched_priority; + + ret = pthread_attr_init(&a); + pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED); + param.sched_priority = curThreadPri + 2; // 2, adjust the priority. + pthread_attr_setschedparam(&a, ¶m); + ret = pthread_create(&newPthread, &a, ThreadFuncTest, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newPthread, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return 0; +} + +void ItTestPthreadOnce001(void) +{ + TEST_ADD_CASE("IT_PTHREAD_ONCE_001", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_003.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_003.cpp new file mode 100644 index 00000000..5698c5bb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_003.cpp @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_pthread_test.h" + +/* *************************************************************************** + * Public Functions + * ************************************************************************** */ + +static int g_currThreadPri, g_currThreadPolicy; +static int g_testPthredCount; +static void *ThreadFuncTest2(void *arg) +{ + (void)arg; + int ret; + int policy; + struct sched_param param = { 0 }; + pthread_t pthread = pthread_self(); + + g_testPthredCount++; + + ret = pthread_getschedparam(pthread, &policy, ¶m); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_currThreadPri, param.sched_priority, param.sched_priority, EXIT); + ICUNIT_GOTO_EQUAL(g_currThreadPolicy, policy, policy, EXIT); + ICUNIT_GOTO_EQUAL(g_testPthredCount, 2, g_testPthredCount, EXIT); // 2, here assert the result. +EXIT: + return NULL; +} + +static void *ThreadFuncTest3(void *arg) +{ + (void)arg; + int ret; + int policy; + struct sched_param param = { 0 }; + pthread_t pthread = pthread_self(); + + g_testPthredCount++; + + ret = pthread_getschedparam(pthread, &policy, ¶m); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_currThreadPri, param.sched_priority, param.sched_priority, EXIT); + ICUNIT_GOTO_EQUAL(policy, SCHED_FIFO, policy, EXIT); + ICUNIT_GOTO_EQUAL(g_testPthredCount, 4, g_testPthredCount, EXIT); // 4, here assert the result. + +EXIT: + return NULL; +} + +static int Testcase() +{ + struct sched_param param = { 0 }; + int ret; + void *res = NULL; + pthread_attr_t a = { 0 }; + pthread_t newPthread, newPthread1; + + g_testPthredCount = 0; + + ret = pthread_getschedparam(pthread_self(), &g_currThreadPolicy, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, -ret); + + g_currThreadPri = param.sched_priority; + + g_testPthredCount++; + ret = pthread_create(&newPthread, NULL, ThreadFuncTest2, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newPthread, &res); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_EQUAL(g_testPthredCount, 2, g_testPthredCount); // 2, here assert the result. + g_testPthredCount++; + + param.sched_priority = g_currThreadPri; + ret = pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newPthread, NULL, ThreadFuncTest3, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newPthread, &res); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_EQUAL(g_testPthredCount, 4, g_testPthredCount); // 4, here assert the result. + + param.sched_priority = g_currThreadPri; + ret = pthread_setschedparam(pthread_self(), SCHED_RR, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return 0; +} + +void ItTestPthread003(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_003", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_006.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_006.cpp new file mode 100644 index 00000000..3846c74f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_006.cpp @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_pthread_test.h" + +static pthread_barrier_t g_barrier; +static int g_testToCount001 = 0; +static int g_threadTest[10]; + +static void *ThreadFuncTest0(void *a) +{ + int ret; + int count = *((int *)a); + g_testToCount001++; + + ret = pthread_barrier_wait(&g_barrier); + ICUNIT_GOTO_EQUAL(ret, PTHREAD_BARRIER_SERIAL_THREAD, ret, EXIT); + + g_threadTest[count] = count; + +EXIT: + return NULL; +} + +static void *ThreadFuncTest2(void *a) +{ + int ret; + int count = *((int *)a); + g_testToCount001++; + + ret = pthread_barrier_wait(&g_barrier); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_threadTest[count] = count; + +EXIT: + return NULL; +} + +static void *ThreadFuncTest1(void *a) +{ + int ret; + int count = *((int *)a); + g_testToCount001++; + + ret = pthread_barrier_wait(&g_barrier); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_threadTest[count] = count; +EXIT: + return NULL; +} + +static int Testcase(void) +{ + struct sched_param param = { 0 }; + int ret; + void *res = NULL; + pthread_attr_t a = { 0 }; + pthread_t thread; + pthread_t newPthread[10], newPthread1; + pthread_mutexattr_t mutex; + int index = 0; + int currThreadPri, currThreadPolicy; + int threadParam[10]; + ret = pthread_getschedparam(pthread_self(), &currThreadPolicy, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, -ret); + currThreadPri = param.sched_priority; + const int testCount = 10; + + g_testToCount001 = 0; + + ret = pthread_attr_init(&a); + pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED); + param.sched_priority = currThreadPri - 1; + pthread_attr_setschedparam(&a, ¶m); + + ret = pthread_barrier_init(&g_barrier, NULL, testCount); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + threadParam[0] = 0; + ret = pthread_create(&newPthread[index], &a, ThreadFuncTest0, &threadParam[0]); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + g_threadTest[0] = 0; + + index = 1; + while (index < (testCount - 1)) { + threadParam[index] = index; + ret = pthread_create(&newPthread[index], &a, ThreadFuncTest1, &threadParam[index]); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + g_threadTest[index] = 0; + index++; + } + + ICUNIT_ASSERT_EQUAL(g_testToCount001, testCount - 1, g_testToCount001); + + threadParam[index] = index; + ret = pthread_create(&newPthread[index], &a, ThreadFuncTest2, &threadParam[index]); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + sleep(1); + + ICUNIT_ASSERT_EQUAL(g_testToCount001, testCount, g_testToCount001); + + index = 0; + while (index < testCount) { + threadParam[index] = index; + ret = pthread_join(newPthread[index], NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(g_threadTest[index], index, g_threadTest[index]); + index++; + } + + ret = pthread_barrier_destroy(&g_barrier); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return 0; +} + +void ItTestPthread006(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_006", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_007.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_007.cpp new file mode 100644 index 00000000..119de51d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_007.cpp @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_pthread_test.h" + + +static pthread_t g_th; +VOID *PthreadTest115(VOID *arg) +{ + g_testCount++; + sleep(1); + g_testCount++; + + return NULL; +} + +VOID *PthreadFunc1115(VOID *arg) +{ + int ret = 0; + g_testCount++; + usleep(1000 * 10 * 10); // 1000 * 10 * 10, delay for timimg control. + + ret = pthread_join(g_th, NULL); + ICUNIT_GOTO_EQUAL(ret, EINVAL, ret, EXIT); + g_testCount++; +EXIT: + return NULL; +} + +VOID *PthreadFunc2115(VOID *arg) +{ + int ret = 0; + g_testCount++; + usleep(1000 * 10 * 15); // 1000 * 10 * 15, delay for timimg control. + + ret = pthread_join(g_th, NULL); + ICUNIT_GOTO_EQUAL(ret, EINVAL, ret, EXIT); + g_testCount++; +EXIT: + return NULL; +} + +VOID *PthreadFunc3115(VOID *arg) +{ + int ret = 0; + g_testCount++; + usleep(1000 * 10 * 6); // 1000 * 10 * 6, delay for timimg control. + + ret = pthread_join(g_th, NULL); + ICUNIT_GOTO_EQUAL(ret, EINVAL, ret, EXIT); + g_testCount++; + ; + +EXIT: + return NULL; +} + +static UINT32 Testcase(VOID) +{ + int rc; + + int ret = 0; + pthread_t th1; + pthread_t th2; + pthread_t th3; + pthread_attr_t attr; + g_testCount = 0; + pthread_attr_init(&attr); + pthread_create(&g_th, &attr, PthreadTest115, NULL); + + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_create(&th1, &attr, PthreadFunc1115, NULL); + pthread_create(&th2, &attr, PthreadFunc2115, NULL); + pthread_create(&th3, &attr, PthreadFunc3115, NULL); + ret = pthread_join(g_th, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + usleep(1000 * 10 * 50); // 1000 * 10 * 50, delay for timimg control. + ICUNIT_ASSERT_EQUAL(g_testCount, 8, g_testCount); // 8, assert the exit code. + return 0; +} + +void ItTestPthread007(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_007", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_008.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_008.cpp new file mode 100644 index 00000000..1dd20f38 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_008.cpp @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_pthread_test.h" + + +static pthread_t g_th; +static VOID *PthreadTest115(VOID *arg) +{ + g_testCount++; + sleep(1); + g_testCount++; + + return NULL; +} + +static VOID *PthreadFunc1115(VOID *arg) +{ + int ret = 0; + g_testCount++; + usleep(1000 * 10 * 10); // 1000 * 10 * 10, delay for timimg control. + + ret = pthread_join(g_th, NULL); + ICUNIT_GOTO_EQUAL(ret, EINVAL, ret, EXIT); + g_testCount++; +EXIT: + return NULL; +} + +static VOID *PthreadFunc2115(VOID *arg) +{ + int ret = 0; + g_testCount++; + usleep(1000 * 10 * 15); // 1000 * 10 * 15, delay for timimg control. + + ret = pthread_join(g_th, NULL); + ICUNIT_GOTO_EQUAL(ret, EINVAL, ret, EXIT); + g_testCount++; +EXIT: + return NULL; +} + +static VOID *PthreadFunc3115(VOID *arg) +{ + int ret = 0; + g_testCount++; + usleep(1000 * 10 * 6); // 1000 * 10 * 6, delay for timimg control. + + ret = pthread_detach(g_th); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + g_testCount++; + ; + +EXIT: + return NULL; +} + +static UINT32 Testcase(VOID) +{ + int rc; + + int ret = 0; + pthread_t th1; + pthread_t th2; + pthread_t th3; + pthread_attr_t attr; + g_testCount = 0; + pthread_attr_init(&attr); + pthread_create(&g_th, &attr, PthreadTest115, NULL); + + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_create(&th1, &attr, PthreadFunc1115, NULL); + pthread_create(&th2, &attr, PthreadFunc2115, NULL); + pthread_create(&th3, &attr, PthreadFunc3115, NULL); + ret = pthread_join(g_th, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + usleep(1000 * 10 * 50); // 1000 * 10 * 50, delay for timimg control. + ICUNIT_ASSERT_EQUAL(g_testCount, 8, g_testCount); // 8, assert the exit code. + return 0; +} + +void ItTestPthread008(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_008", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_009.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_009.cpp new file mode 100644 index 00000000..bd1968b4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_009.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_pthread_test.h" + +static pthread_t g_th; +static VOID *PthreadTest115(VOID *arg) +{ + g_testCount++; + int ret = pthread_detach(g_th); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + g_testCount++; + +EXIT: + return NULL; +} + +static UINT32 Testcase(VOID) +{ + int ret; + pthread_attr_t attr; + g_testCount = 0; + pthread_attr_init(&attr); + pthread_create(&g_th, &attr, PthreadTest115, NULL); + +#ifdef LOSCFG_USER_TEST_SMP + sleep(1); +#endif + return 0; +} + +void ItTestPthread009(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_009", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_010.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_010.cpp new file mode 100644 index 00000000..45b3fc45 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_010.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_pthread_test.h" + +static pthread_barrier_t g_barrier; +static int g_testToCount001 = 0; +static int g_threadTest[30]; + +static void *ThreadFuncTest0(void *a) +{ + struct sched_param param = { 0 }; + int ret; + int currThreadPolicy; + ret = pthread_getschedparam(pthread_self(), &currThreadPolicy, ¶m); + ICUNIT_ASSERT_EQUAL_NULL(ret, 0, (void *)(uintptr_t)ret); + int currThreadPri = param.sched_priority; + + g_testToCount001++; + +EXIT: + return NULL; +} + +static int Testcase(void) +{ + struct sched_param param = { 0 }; + int ret; + pthread_attr_t a = { 0 }; + pthread_t newPthread[30]; + int index = 0; + int currThreadPri, currThreadPolicy; + const int testCount = 30; + + ret = pthread_getschedparam(pthread_self(), &currThreadPolicy, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + currThreadPri = param.sched_priority; + g_testToCount001 = 0; + ret = pthread_attr_init(&a); + pthread_attr_setdetachstate(&a, PTHREAD_CREATE_DETACHED); + pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED); + param.sched_priority = currThreadPri - 2; // 2, adjust the priority. + pthread_attr_setschedparam(&a, ¶m); + + while (index < testCount) { + ret = pthread_create(&newPthread[index], &a, ThreadFuncTest0, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + index++; + } + + ICUNIT_ASSERT_EQUAL(g_testToCount001, testCount, g_testToCount001); + + return 0; +} + +void ItTestPthread010(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_010", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_011.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_011.cpp new file mode 100644 index 00000000..932398c0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_011.cpp @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_pthread_test.h" +#include "sys/syscall.h" + +void child1(void) +{ + int count = 0; + int policy, pri, newPolicy; + struct sched_param param = { 0 }; + pthread_t pthread = pthread_self(); + int tid = Syscall(SYS_gettid, 0, 0, 0, 0); + + int ret = pthread_getschedparam(pthread, &policy, ¶m); + + pri = param.sched_priority; + + while (1) { + ret = pthread_getschedparam(pthread, &newPolicy, ¶m); + if (ret != 0) { + printf("pthread_getschedparam failed ! %d error: %d\n", __LINE__, errno); + exit(255); // 255, set a special exit code. + } + + if (newPolicy != policy || pri != param.sched_priority) { + printf("pthread_getschedparam failed ! %d policy %d newPolicy %d pri %d param.sched_priority :%d\n", + __LINE__, policy, newPolicy, pri, param.sched_priority); + exit(255); // 255, set a special exit code. + } + + count++; + }; + + exit(0); +} + +void child(void) +{ + int ret; + int loop = 0; + int status = 0; + const int loopNum = 50; + const int countNum = 128; + pid_t pid = fork(); + if (pid == 0) { + child1(); + } + + int tid = Syscall(SYS_gettid, 0, 0, 0, 0); + + for (int count = 0; count < countNum; count++) { + if (count == tid) { + continue; + } + + ret = Syscall(SYS_pthread_join, count, 0, 0, 0); + if (ret == 0) { + exit(1); + } + + ret = Syscall(SYS_pthread_set_detach, count, 0, 0, 0); + if (ret == 0) { + exit(1); + } + + ret = Syscall(SYS_pthread_deatch, count, 0, 0, 0); + if (ret == 0) { + exit(1); + } + + ret = Syscall(SYS_sched_setparam, count, 20, -1, 0); // 20, param test + if (ret == 0) { + exit(1); + } + + ret = Syscall(SYS_sched_getparam, count, -1, 0, 0); + if (ret == 0) { + exit(1); + } + + ret = Syscall(SYS_sched_setscheduler, count, SCHED_RR, 20, -1); // 20, param test + if (ret == 0) { + exit(1); + } + + ret = Syscall(SYS_sched_getscheduler, count, -1, 0, 0); + if (ret == 0) { + exit(1); + } + + ret = Syscall(SYS_tkill, count, SIGPWR, 0, 0); + if (ret == 0) { + exit(1); + } + + if (count == countNum - 1) { + loop++; + if (loop == loopNum) { + break; + } else { + count = 0; + } + } + } + + kill(pid, SIGKILL); + + ret = waitpid(pid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT); + + exit(255); // 255, set a special exit code. +EXIT: + exit(0); +} + +static int Testcase(void) +{ + int ret; + int status = 0; + pid_t pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, The pid will never exceed 100000. + if (pid == 0) { + child(); + printf("[Failed] - [Errline : %d RetCode : 0x%x\n", g_iCunitErrLineNo, g_iCunitErrCode); + exit(0); + } + ret = waitpid(pid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert exit code. + return 0; +EXIT: + return 1; +} + +void ItTestPthread011(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_011", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_012.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_012.cpp new file mode 100644 index 00000000..f33e7672 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_012.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_pthread_test.h" + +static int Testcase(void) +{ + int ret; + ret = Syscall(SYS_set_thread_area, 0x0, 0, 0, 0); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = Syscall(SYS_set_thread_area, 0x100, 0, 0, 0); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = Syscall(SYS_set_thread_area, 0x5000, 0, 0, 0); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = Syscall(SYS_set_thread_area, 0x5000, 0, 0, 0); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + +#ifndef LOSCFG_USER_TEST_SMP + ret = Syscall(SYS_set_thread_area, 0x40000000, 0, 0, 0); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = Syscall(SYS_set_thread_area, 0x40001000, 0, 0, 0); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); +#else + ret = Syscall(SYS_set_thread_area, 0x80000000, 0, 0, 0); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = Syscall(SYS_set_thread_area, 0x80001000, 0, 0, 0); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); +#endif + return 0; +} + +void ItTestPthread012(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_012", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_013.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_013.cpp new file mode 100644 index 00000000..bf78c1aa --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_013.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_pthread_test.h" + +static int Testcase(void) +{ + int ret; + pthread_attr_t attr = { 0 }; + int scope = 0; + + ret = pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); + ICUNIT_ASSERT_EQUAL(ret, ENOTSUP, ret); + + ret = pthread_attr_setscope(&attr, PTHREAD_SCOPE_PROCESS); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_getscope(&attr, &scope); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(scope, PTHREAD_SCOPE_PROCESS, scope); + + return 0; +} + +void ItTestPthread013(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_013", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_015.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_015.cpp new file mode 100644 index 00000000..4eb42af5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_015.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_pthread_test.h" + +static VOID *PthreadTest115(VOID *arg) +{ + return NULL; +} + +static int GroupProcess(void) +{ + int ret; + pthread_t th1; + pthread_attr_t attr; + pthread_attr_init(&attr); + int policy = 0; + struct sched_param param = { 0 }; + const int testThreadCount = 2000; + + ret = pthread_getschedparam(pthread_self(), &policy, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + param.sched_priority += 2; // 2, adjust the priority. + ret = pthread_attr_setschedparam(&attr, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_setschedpolicy(&attr, SCHED_FIFO); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + for (int i = 0; i < testThreadCount; i++) { + ret = pthread_create(&th1, &attr, PthreadTest115, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(th1, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + } + + exit(255); // 255, set a special exit code. +} + +static int TestCase(void) +{ + int ret; + int status = 0; + pid_t pid, pid1; + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, The pid will never exceed 100000. + + if (pid == 0) { + prctl(PR_SET_NAME, "mainFork", 0UL, 0UL, 0UL); + GroupProcess(); + printf("[Failed] - [Errline : %d RetCode : 0x%x\n", g_iCunitErrLineNo, g_iCunitErrCode); + exit(g_iCunitErrLineNo); + } + + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert the special exit code. + + return 0; +EXIT: + return 1; +} + +void ItTestPthread015(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_015", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_016.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_016.cpp new file mode 100644 index 00000000..23f7962c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_016.cpp @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_pthread_test.h" + +static VOID *PthreadTest115(VOID *arg) +{ + int ret = pthread_detach(pthread_self()); + ICUNIT_ASSERT_EQUAL_NULL(ret, 0, (void *)(intptr_t)ret); + return NULL; +} + +static int GroupProcess(void) +{ + int ret; + pthread_t th1; + pthread_attr_t attr; + pthread_attr_init(&attr); + int policy = 0; + struct sched_param param = { 0 }; + const int testThreadCount = 2000; + + ret = pthread_getschedparam(pthread_self(), &policy, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + param.sched_priority -= 2; // 2, adjust the priority. + ret = pthread_attr_setschedparam(&attr, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_setschedpolicy(&attr, SCHED_FIFO); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + for (int i = 0; i < testThreadCount; i++) { + ret = pthread_create(&th1, &attr, PthreadTest115, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + } + + exit(255); // 255, set a special exit code. +} + +static int TestCase(void) +{ + int ret; + int status = 0; + pid_t pid; + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, The pid will never exceed 100000. + + if (pid == 0) { + prctl(PR_SET_NAME, "mainFork", 0UL, 0UL, 0UL); + GroupProcess(); + printf("[Failed] - [Errline : %d RetCode : 0x%x\n", g_iCunitErrLineNo, g_iCunitErrCode); + exit(g_iCunitErrLineNo); + } + + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert the special exit code. + + return 0; +EXIT: + return 1; +} + +void ItTestPthread016(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_016", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_017.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_017.cpp new file mode 100644 index 00000000..edd54539 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_017.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_pthread_test.h" + +static VOID *PthreadTest115(VOID *arg) {} + +static int GroupProcess(void) +{ + int ret; + pthread_t th1; + pthread_attr_t attr; + pthread_attr_init(&attr); + int policy = 0; + struct sched_param param = { 0 }; + const int testThreadCount = 2000; + + ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_getschedparam(pthread_self(), &policy, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + param.sched_priority -= 2; // 2, adjust the priority. + ret = pthread_attr_setschedparam(&attr, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_setschedpolicy(&attr, SCHED_FIFO); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + for (int i = 0; i < testThreadCount; i++) { + ret = pthread_create(&th1, &attr, PthreadTest115, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + } + + exit(255); // 255, set a special exit code. +} + +static int TestCase(void) +{ + int ret; + int status = 0; + pid_t pid, pid1; + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, The pid will never exceed 100000. + + if (pid == 0) { + prctl(PR_SET_NAME, "mainFork", 0UL, 0UL, 0UL); + GroupProcess(); + printf("[Failed] - [Errline : %d RetCode : 0x%x\n", g_iCunitErrLineNo, g_iCunitErrCode); + exit(g_iCunitErrLineNo); + } + + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert the special exit code. + + return 0; +EXIT: + return 1; +} + +void ItTestPthread017(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_017", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_018.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_018.cpp new file mode 100644 index 00000000..26aed44c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_018.cpp @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_pthread_test.h" +#define TEST_THREAD_COUNT 2000 + +static int g_testCnt = 0; + +static void *PthreadTest116(VOID *arg) +{ + return NULL; +} + +static void *PthreadTest115(VOID *arg) +{ + pthread_t th1; + + int ret = pthread_create(&th1, NULL, PthreadTest116, 0); + ICUNIT_ASSERT_EQUAL_NULL(ret, 0, (void *)(intptr_t)ret); + + ret = pthread_join(th1, NULL); + ICUNIT_ASSERT_EQUAL_NULL(ret, 0, (void *)(intptr_t)ret); + + g_testCnt++; + + return NULL; +} + +static int GroupProcess(void) +{ + int ret; + pthread_t th1; + pthread_attr_t attr; + pthread_attr_init(&attr); + int policy = 0; + unsigned int *getStack = NULL; + size_t getSize; + struct sched_param param = { 0 }; + int stackSize = 0x3000; + + g_testCnt = 0; + + void *stack = malloc(stackSize); + ICUNIT_ASSERT_NOT_EQUAL((int)stack, 0, stack); + + ret = pthread_attr_setstack(&attr, stack, stackSize); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_getstack(&attr, (void **)&getStack, &getSize); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(getStack, stack, getStack); + ICUNIT_ASSERT_EQUAL(getSize, stackSize, getSize); + + ret = pthread_create(&th1, &attr, PthreadTest115, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(th1, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_EQUAL(g_testCnt, 1, g_testCnt); + + free(stack); + + stackSize = 3000; + + pthread_attr_init(&attr); + stack = malloc(stackSize); + ICUNIT_ASSERT_NOT_EQUAL((int)stack, 0, stack); + + ret = pthread_attr_setstack(&attr, stack, stackSize); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_getstack(&attr, (void **)&getStack, &getSize); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(getStack, stack, getStack); + ICUNIT_ASSERT_EQUAL(getSize, stackSize, getSize); + + ret = pthread_create(&th1, &attr, PthreadTest115, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(th1, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_EQUAL(g_testCnt, 2, g_testCnt); // 2, here, assert the result. + + free(stack); + + exit(255); // 255, set a special exit code. + return 0; +} + +static int TestCase(void) +{ + int ret; + int status = 0; + pid_t pid; + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, The pid will never exceed 100000. + + if (pid == 0) { + prctl(PR_SET_NAME, "mainFork", 0UL, 0UL, 0UL); + GroupProcess(); + printf("[Failed] - [Errline : %d RetCode : 0x%x\n", g_iCunitErrLineNo, g_iCunitErrCode); + exit(g_iCunitErrLineNo); + } + + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); // 255, assert the special exit code. + + return 0; +EXIT: + return 1; +} + +void ItTestPthread018(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_018", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_019.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_019.cpp new file mode 100644 index 00000000..8746c78e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_019.cpp @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_pthread_test.h" +#define TEST_THREAD_COUNT 2000 + +static int g_testCnt = 0; + +static void *PthreadTest116(VOID *arg) +{ + return NULL; +} + +static void *PthreadTest115(VOID *arg) +{ + pthread_t th1; + + int ret = pthread_create(&th1, NULL, PthreadTest116, 0); + ICUNIT_ASSERT_EQUAL_NULL(ret, 0, (void *)(intptr_t)ret); + + ret = pthread_join(th1, NULL); + ICUNIT_ASSERT_EQUAL_NULL(ret, 0, (void *)(intptr_t)ret); + + g_testCnt++; + + return NULL; +} + +static int GroupProcess(void) +{ + int ret; + pthread_t th1; + pthread_attr_t attr; + pthread_attr_init(&attr); + int policy = 0; + unsigned int *getStack = NULL; + size_t getSize; + struct sched_param param = { 0 }; + int stackSize = 2047; + void *stack = (void *)&getSize; + + g_testCnt = 0; + + ret = pthread_attr_setstack(&attr, stack, stackSize); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_attr_getstack(&attr, (void **)&getStack, &getSize); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + stackSize = 3000; // 3000, change stackSize, test again. + + pthread_attr_init(&attr); + stack = reinterpret_cast(0x1000); + + ret = pthread_attr_setstack(&attr, stack, stackSize); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_getstack(&attr, (void **)&getStack, &getSize); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(getStack, stack, getStack); + ICUNIT_ASSERT_EQUAL(getSize, stackSize, getSize); + + ret = pthread_create(&th1, &attr, PthreadTest115, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + exit(255); // 255, set a special exit code. + return 0; +} + +static int TestCase(void) +{ + int ret; + int status = 0; + pid_t pid; + pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, The pid will never exceed 100000. + + if (pid == 0) { + prctl(PR_SET_NAME, "mainFork", 0UL, 0UL, 0UL); + GroupProcess(); + printf("[Failed] - [Errline : %d RetCode : 0x%x\n", g_iCunitErrLineNo, g_iCunitErrCode); + exit(g_iCunitErrLineNo); + } + + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ICUNIT_ASSERT_EQUAL(WIFEXITED(status), 0, WIFEXITED(status)); + ICUNIT_ASSERT_EQUAL(WTERMSIG(status), SIGUSR2, WTERMSIG(status)); + +EXIT: + return 0; +} + +void ItTestPthread019(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_019", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_020.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_020.cpp new file mode 100644 index 00000000..1c63816c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_020.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_pthread_test.h" + +static int ChildProcess(void) +{ + int ret, currPolicy = 0; + volatile unsigned int count = 0; + struct sched_param currSchedParam = { 0 }; + struct sched_param param = { + .sched_deadline = 1000000, /* 1000000, 1s */ + .sched_runtime = 20000, /* 20000, 20ms */ + .sched_period = 1000000, /* 1000000, 1s */ + }; + + ret = sched_getparam(getpid(), &currSchedParam); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + currPolicy = sched_getscheduler(getpid()); + ICUNIT_ASSERT_EQUAL(currPolicy, SCHED_RR, LOS_NOK); + currSchedParam.sched_runtime = 0; + ICUNIT_ASSERT_EQUAL(currSchedParam.sched_deadline, 0, LOS_NOK); + ICUNIT_ASSERT_EQUAL(currSchedParam.sched_runtime, 0, LOS_NOK); + ICUNIT_ASSERT_EQUAL(currSchedParam.sched_period, 0, LOS_NOK); + + ret = sched_setscheduler(getpid(), SCHED_DEADLINE, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + currPolicy = sched_getscheduler(getpid()); + ICUNIT_ASSERT_EQUAL(currPolicy, SCHED_DEADLINE, LOS_NOK); + + ret = sched_getparam(getpid(), &currSchedParam); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(currSchedParam.sched_deadline, 1000000, LOS_NOK); /* 1000000, 1s */ + ICUNIT_ASSERT_EQUAL(currSchedParam.sched_runtime, 20000, LOS_NOK); /* 20000, 20ms */ + ICUNIT_ASSERT_EQUAL(currSchedParam.sched_period, 1000000, LOS_NOK); /* 1000000, 1s */ + + printf("--- 1 edf thread start --\n\r"); + do { + for (volatile int i = 0; i < 10000; i++) { /* 10000, no special meaning */ + for (volatile int j = 0; j < 5; j++) { /* 5, no special meaning */ + int tmp = i - j; + } + } + if (count % 3 == 0) { /* 3, no special meaning */ + printf("--- 2 edf thread running --\n\r"); + } + count++; + } while (count <= 6); /* 6, no special meaning */ + printf("--- 3 edf thread end --\n\r"); + + return 0; +} + +static int TestCase(void) +{ + int ret, pid, status; + + pid = fork(); + if (pid == 0) { + ret = ChildProcess(); + if (ret != 0) { + exit(-1); + } + exit(0); + } else if (pid > 0) { + waitpid(pid, &status, 0); + } else { + exit(__LINE__); + } + + return WEXITSTATUS(status) == 0 ? 0 : -1; +} + +void ItTestPthread020(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_020", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_021.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_021.cpp new file mode 100644 index 00000000..e9a6354b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_021.cpp @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_pthread_test.h" + +static void *ThreadFuncTest(void *args) +{ + int pt = (int)args; + int ret, currPolicy; + struct sched_param currSchedParam; + volatile unsigned int count = 0; + int currTID = Syscall(SYS_gettid, 0, 0, 0, 0); + + ret = pthread_getschedparam(pthread_self(), & currPolicy, &currSchedParam); + ICUNIT_GOTO_EQUAL(ret, 0, LOS_NOK, EXIT); + ICUNIT_GOTO_EQUAL( currPolicy, SCHED_DEADLINE, LOS_NOK, EXIT); + ICUNIT_GOTO_EQUAL(currSchedParam.sched_deadline, 1000000, LOS_NOK, EXIT); /* 1000000, 1s */ + ICUNIT_GOTO_EQUAL(currSchedParam.sched_runtime, 20000, LOS_NOK, EXIT); /* 20000, 20ms */ + ICUNIT_GOTO_EQUAL(currSchedParam.sched_period, 1000000, LOS_NOK, EXIT); /* 1000000, 1s */ + + printf("--- 1 edf Tid[%d] PTid[%d] thread start ---\n\r", currTID, pt); + do { + for (volatile int i = 0; i < 100000; i++) { /* 100000, no special meaning */ + for (volatile int j = 0; j < 5; j++) { /* 5, no special meaning */ + volatile int tmp = i - j; + } + } + if (count % 3 == 0) { /* 3, no special meaning */ + printf("--- 2 edf Tid[%d] PTid[%d] thread running ---\n\r", currTID, pt); + } + count++; + } while (count <= 6); /* 6, no special meaning */ + printf("--- 3 edf Tid[%d] PTid[%d] thread end ---\n\r", currTID, pt); + + ret = LOS_OK; + return (void *)(&ret); +EXIT: + ret = LOS_NOK; + return (void *)(&ret); +} + +static int ChildProcess(void) +{ + int *childThreadRetval = nullptr; + pthread_t newUserThread; + int ret, currPolicy = 0; + volatile unsigned int count = 0; + struct sched_param currSchedParam = { 0 }; + int currTID = Syscall(SYS_gettid, 0, 0, 0, 0); + struct sched_param param = { + .sched_deadline = 1000000, /* 1000000, 1s */ + .sched_runtime = 20000, /* 20000, 20ms */ + .sched_period = 1000000, /* 1000000, 1s */ + }; + + ret = sched_setscheduler(getpid(), SCHED_DEADLINE, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_getschedparam(pthread_self(), & currPolicy, &currSchedParam); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(currPolicy, SCHED_DEADLINE, LOS_NOK); + ICUNIT_ASSERT_EQUAL(currSchedParam.sched_deadline, 1000000, LOS_NOK); /* 1000000, 1s */ + ICUNIT_ASSERT_EQUAL(currSchedParam.sched_runtime, 20000, LOS_NOK); /* 20000, 20ms */ + ICUNIT_ASSERT_EQUAL(currSchedParam.sched_period, 1000000, LOS_NOK); /* 1000000, 1s */ + + ret = pthread_create(&newUserThread, NULL, ThreadFuncTest, (void *)currTID); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + printf("--- 1 edf Tid[%d] thread start ---\n\r", currTID); + do { + for (volatile int i = 0; i < 10000; i++) { /* 10000, no special meaning */ + for (volatile int j = 0; j < 5; j++) { /* 5, no special meaning */ + int tmp = i - j; + } + } + if (count % 3 == 0) { /* 3, no special meaning */ + printf("--- 2 edf Tid[%d] thread running ---\n\r", currTID); + } + count++; + } while (count <= 6); /* 6, no special meaning */ + printf("--- 3 edf Tid[%d] thread end ---\n\r", currTID); + + ret = pthread_join(newUserThread, (void **)&childThreadRetval); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(*childThreadRetval, 0, *childThreadRetval); + + return 0; +} + +static int TestCase(void) +{ + int ret, pid, status; + + pid = fork(); + if (pid == 0) { + ret = ChildProcess(); + if (ret != 0) { + exit(-1); + } + exit(0); + } else if (pid > 0) { + waitpid(pid, &status, 0); + } else { + exit(__LINE__); + } + + return WEXITSTATUS(status) == 0 ? 0 : -1; +} + +void ItTestPthread021(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_021", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_022.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_022.cpp new file mode 100644 index 00000000..db55fa5f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_022.cpp @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_pthread_test.h" + +static int EdfProcess(void) +{ + int ret; + int currPolicy = 0; + struct sched_param currSchedParam = { 0 }; + volatile unsigned int count = 0; + int currTID = Syscall(SYS_gettid, 0, 0, 0, 0); + + ret = pthread_getschedparam(pthread_self(), &currPolicy, &currSchedParam); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(currPolicy, SCHED_DEADLINE, LOS_NOK); + ICUNIT_ASSERT_EQUAL(currSchedParam.sched_deadline, 1000000, LOS_NOK); /* 1000000, 1s */ + ICUNIT_ASSERT_EQUAL(currSchedParam.sched_runtime, 20000, LOS_NOK); /* 20000, 20ms */ + ICUNIT_ASSERT_EQUAL(currSchedParam.sched_period, 1000000, LOS_NOK); /* 1000000, 1s */ + + printf("--- edf2 -- 1 -- Tid[%d] thread start ---\n\r", currTID); + do { + for (volatile int i = 0; i < 10000; i++) { /* 10000, no special meaning */ + for (volatile int j = 0; j < 5; j++) { /* 5, no special meaning */ + int tmp = i - j; + } + } + if (count % 3 == 0) { /* 3, no special meaning */ + printf("--- edf2 -- 2 -- Tid[%d] thread running ---\n\r", currTID); + } + count++; + } while (count <= 6); /* 6, no special meaning */ + printf("--- edf2 -- 3 -- Tid[%d] thread end ---\n\r", currTID); + + return 0; +} + +static int ChildProcess(void) +{ + int *childThreadRetval = nullptr; + pthread_t newUserThread; + int pid, status, ret; + int currPolicy = 0; + volatile unsigned int count = 0; + struct sched_param currSchedParam = { 0 }; + int currTID = Syscall(SYS_gettid, 0, 0, 0, 0); + struct sched_param param = { + .sched_deadline = 1000000, /* 1000000, 1s */ + .sched_runtime = 20000, /* 20000, 20ms */ + .sched_period = 1000000, /* 1000000, 1s */ + }; + + ret = sched_setscheduler(getpid(), SCHED_DEADLINE, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_getschedparam(pthread_self(), &currPolicy, &currSchedParam); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(currPolicy, SCHED_DEADLINE, LOS_NOK); + ICUNIT_ASSERT_EQUAL(currSchedParam.sched_deadline, 1000000, LOS_NOK); /* 1000000, 1s */ + ICUNIT_ASSERT_EQUAL(currSchedParam.sched_runtime, 20000, LOS_NOK); /* 20000, 20ms */ + ICUNIT_ASSERT_EQUAL(currSchedParam.sched_period, 1000000, LOS_NOK); /* 1000000, 1s */ + + pid = fork(); + if (pid == 0) { + ret = EdfProcess(); + if (ret != 0) { + exit(-1); + } + exit(0); + } else if (pid > 0) { + printf("--- edf1 -- 1 -- Tid[%d] thread start ---\n\r", currTID); + do { + for (volatile int i = 0; i < 50000; i++) { /* 50000, no special meaning */ + int tmp = i + 1; + } + if (count % 5 == 0) { /* 5, no special meaning */ + printf("--- edf1 -- 2 -- Tid[%d] thread running ---\n\r", currTID); + } + count++; + } while (count <= 10); /* 10, no special meaning */ + printf("--- edf1 -- 3 -- Tid[%d] thread end ---\n\r", currTID); + waitpid(pid, &status, 0); + } else { + exit(__LINE__); + } + + return WEXITSTATUS(status) == 0 ? 0 : -1; +} + +static int TestCase(void) +{ + int ret, pid, status; + + pid = fork(); + if (pid == 0) { + ret = ChildProcess(); + if (ret != 0) { + exit(-1); + } + exit(0); + } else if (pid > 0) { + waitpid(pid, &status, 0); + } else { + exit(__LINE__); + } + + return WEXITSTATUS(status) == 0 ? 0 : -1; +} + +void ItTestPthread022(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_022", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_023.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_023.cpp new file mode 100644 index 00000000..05ab3b99 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_023.cpp @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_pthread_test.h" + +static void *ThreadFuncTest(void *args) +{ + return (void *)NULL; +} + +static int ChildProcess(void) +{ + int ret; + int currPolicy = 0; + int oldPolicy; + pthread_t newUserThread; + pthread_attr_t a = { 0 }; + struct sched_param hpfparam = { 0 }; + volatile unsigned int count = 0; + struct sched_param currSchedParam = { 0 }; + int currTID = Syscall(SYS_gettid, 0, 0, 0, 0); + struct sched_param param = { + .sched_deadline = 1000000, /* 1000000, 1s */ + .sched_runtime = 20000, /* 20000, 20ms */ + .sched_period = 1000000, /* 1000000, 1s */ + }; + + ret = pthread_getschedparam(pthread_self(), &oldPolicy, &hpfparam); + ICUNIT_ASSERT_EQUAL(ret, 0, -ret); + + ret = sched_setscheduler(getpid(), SCHED_DEADLINE, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_getschedparam(pthread_self(), &currPolicy, &currSchedParam); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(currPolicy, SCHED_DEADLINE, LOS_NOK); + ICUNIT_ASSERT_EQUAL(currSchedParam.sched_deadline, 1000000, LOS_NOK); /* 1000000, 1s */ + ICUNIT_ASSERT_EQUAL(currSchedParam.sched_runtime, 20000, LOS_NOK); /* 20000, 20ms */ + ICUNIT_ASSERT_EQUAL(currSchedParam.sched_period, 1000000, LOS_NOK); /* 1000000, 1s */ + + ret = pthread_attr_init(&a); + pthread_attr_setschedpolicy(&a, SCHED_RR); + pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED); + ret = pthread_create(&newUserThread, &a, ThreadFuncTest, NULL); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + + printf("--- edf2 -- 1 -- Tid[%d] thread end ---\n\r", currTID); + + return 0; +} + +static int TestCase(void) +{ + int ret, pid, status; + + pid = fork(); + if (pid == 0) { + ret = ChildProcess(); + if (ret != 0) { + exit(-1); + } + exit(0); + } else if (pid > 0) { + waitpid(pid, &status, 0); + } else { + exit(__LINE__); + } + + return WEXITSTATUS(status) == 0 ? 0 : -1; +} + +void ItTestPthread023(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_023", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_024.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_024.cpp new file mode 100644 index 00000000..c3ca7f52 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_024.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_pthread_test.h" + +static void *ThreadFuncTest(void *args) +{ + (void)args; + printf("hpf thread run...\r\n"); + return NULL; +} + +static int ChildProcess(void) +{ + int ret, currThreadPolicy; + pthread_attr_t a = { 0 }; + struct sched_param hpfparam = { 0 }; + pthread_t newUserThread; + volatile unsigned int count = 0; + int currTID = Syscall(SYS_gettid, 0, 0, 0, 0); + struct sched_param param = { + .sched_deadline = 1000000, /* 1000000, 1s */ + .sched_runtime = 20000, /* 20000, 20ms */ + .sched_period = 1000000, /* 1000000, 1s */ + }; + + ret = pthread_getschedparam(pthread_self(), &currThreadPolicy, &hpfparam); + ICUNIT_ASSERT_EQUAL(ret, 0, -ret); + ret = pthread_attr_init(&a); + hpfparam.sched_priority = hpfparam.sched_priority - 1; + pthread_attr_setschedparam(&a, &hpfparam); + ret = pthread_create(&newUserThread, &a, ThreadFuncTest, (void *)currTID); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = sched_setscheduler(getpid(), SCHED_DEADLINE, ¶m); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + + return 0; +} + +static int TestCase(void) +{ + int ret, pid, status; + + pid = fork(); + if (pid == 0) { + ret = ChildProcess(); + if (ret != 0) { + exit(-1); + } + exit(0); + } else if (pid > 0) { + waitpid(pid, &status, 0); + } else { + exit(__LINE__); + } + + return WEXITSTATUS(status) == 0 ? 0 : -1; +} + +void ItTestPthread024(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_024", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_025.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_025.cpp new file mode 100644 index 00000000..3366012e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_025.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_pthread_test.h" + +static void *ThreadFuncTest(void *args) +{ + (void)args; + printf("hpf thread run...\r\n"); + return NULL; +} + +static int ChildProcess(void) +{ + int currThreadPolicy; + pthread_attr_t a = { 0 }; + struct sched_param hpfparam = { 0 }; + int *childThreadRetval = nullptr; + pthread_t newUserThread; + int ret; + int currPolicy = 0; + volatile unsigned int count = 0; + struct sched_param currSchedParam = { 0 }; + int currTID = Syscall(SYS_gettid, 0, 0, 0, 0); + struct sched_param param = { + .sched_deadline = 1000000, /* 1000000, 1s */ + .sched_runtime = 20000, /* 20000, 20ms */ + .sched_period = 1000000, /* 1000000, 1s */ + }; + + ret = pthread_getschedparam(pthread_self(), &currThreadPolicy, &hpfparam); + ICUNIT_ASSERT_EQUAL(ret, 0, -ret); + ret = pthread_attr_init(&a); + hpfparam.sched_priority = hpfparam.sched_priority - 1; + pthread_attr_setschedparam(&a, &hpfparam); + ret = pthread_create(&newUserThread, &a, ThreadFuncTest, (void *)currTID); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newUserThread, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = sched_setscheduler(getpid(), SCHED_DEADLINE, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return 0; +} + +static int TestCase(void) +{ + int ret, pid, status; + + pid = fork(); + if (pid == 0) { + ret = ChildProcess(); + if (ret != 0) { + exit(-1); + } + exit(0); + } else if (pid > 0) { + waitpid(pid, &status, 0); + } else { + exit(__LINE__); + } + + return WEXITSTATUS(status) == 0 ? 0 : -1; +} + +void ItTestPthread025(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_025", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_026.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_026.cpp new file mode 100644 index 00000000..a9b6b9db --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_026.cpp @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_pthread_test.h" + +static int ChildProcess(void) +{ + int ret; + int currPolicy = 0; + volatile unsigned int count = 0; + struct sched_param currSchedParam = { 0 }; + struct sched_param param = { + .sched_deadline = 1000000, /* 1000000, 1s */ + .sched_runtime = 20000, /* 20000, 20ms */ + .sched_period = 1000000, /* 1000000, 1s */ + }; + + ret = sched_getparam(getpid(), &currSchedParam); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + currPolicy = sched_getscheduler(getpid()); + ICUNIT_ASSERT_EQUAL(currPolicy, SCHED_RR, LOS_NOK); + currSchedParam.sched_runtime = 0; + ICUNIT_ASSERT_EQUAL(currSchedParam.sched_deadline, 0, LOS_NOK); + ICUNIT_ASSERT_EQUAL(currSchedParam.sched_runtime, 0, LOS_NOK); + ICUNIT_ASSERT_EQUAL(currSchedParam.sched_period, 0, LOS_NOK); + + ret = sched_setscheduler(getpid(), SCHED_DEADLINE, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + currPolicy = sched_getscheduler(getpid()); + ICUNIT_ASSERT_EQUAL(currPolicy, SCHED_DEADLINE, LOS_NOK); + + ret = sched_getparam(getpid(), &currSchedParam); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(currSchedParam.sched_deadline, 1000000, LOS_NOK); /* 1000000, 1s */ + ICUNIT_ASSERT_EQUAL(currSchedParam.sched_runtime, 20000, LOS_NOK); /* 20000, 20ms */ + ICUNIT_ASSERT_EQUAL(currSchedParam.sched_period, 1000000, LOS_NOK); /* 1000000, 1s */ + + printf("--- 1 edf thread start ---\n\r"); + do { + for (volatile int i = 0; i < 10000; i++) { /* 10000, no special meaning */ + for (volatile int j = 0; j < 5; j++) { /* 5, no special meaning */ + int tmp = i - j; + } + } + if (count % 3 == 0) { /* 3, no special meaning */ + printf("--- 2 edf thread running ---\n\r"); + } + count++; + } while (count <= 6); /* 6, no special meaning */ + printf("--- 3 edf thread end ---\n\r"); + + return 0; +} + +static int TestCase(void) +{ + int ret, pid, status; + + pid = fork(); + if (pid == 0) { + ret = ChildProcess(); + if (ret != 0) { + exit(-1); + } + exit(0); + } else if (pid > 0) { + waitpid(pid, &status, 0); + } else { + exit(__LINE__); + } + + return WEXITSTATUS(status) == 0 ? 0 : -1; +} + +void ItTestPthread026(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_026", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_027.cpp b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_027.cpp new file mode 100644 index 00000000..a442c090 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/basic/pthread/smoke/pthread_test_027.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_pthread_test.h" + +static int ChildProcess(void) +{ + int ret; + int currPolicy = 0; + volatile unsigned int count = 0; + struct sched_param currSchedParam = { 0 }; + struct sched_param param = { + .sched_deadline = 1000000, /* 1000000, 1s */ + .sched_runtime = 20000, /* 20000, 20ms */ + .sched_period = 1000000, /* 1000000, 1s */ + }; + + ret = sched_getparam(getpid(), &currSchedParam); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + currPolicy = sched_getscheduler(getpid()); + ICUNIT_ASSERT_EQUAL(currPolicy, SCHED_RR, LOS_NOK); + currSchedParam.sched_runtime = 0; + ICUNIT_ASSERT_EQUAL(currSchedParam.sched_deadline, 0, LOS_NOK); + ICUNIT_ASSERT_EQUAL(currSchedParam.sched_runtime, 0, LOS_NOK); + ICUNIT_ASSERT_EQUAL(currSchedParam.sched_period, 0, LOS_NOK); + + ret = sched_setscheduler(getpid(), SCHED_DEADLINE, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + currPolicy = sched_getscheduler(getpid()); + ICUNIT_ASSERT_EQUAL(currPolicy, SCHED_DEADLINE, LOS_NOK); + + ret = sched_getparam(getpid(), &currSchedParam); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(currSchedParam.sched_deadline, 1000000, LOS_NOK); /* 1000000, 1s */ + ICUNIT_ASSERT_EQUAL(currSchedParam.sched_runtime, 20000, LOS_NOK); /* 20000, 20ms */ + ICUNIT_ASSERT_EQUAL(currSchedParam.sched_period, 1000000, LOS_NOK); /* 1000000, 1s */ + return 0; +} + +static int TestCase(void) +{ + int ret, pid, status; + + pid = fork(); + if (pid == 0) { + ret = ChildProcess(); + if (ret != 0) { + exit(-1); + } + exit(0); + } else if (pid > 0) { + waitpid(pid, &status, 0); + } else { + exit(__LINE__); + } + + return WEXITSTATUS(status) == 0 ? 0 : -1; +} + +void ItTestPthread027(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_027", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/fs/BUILD.gn b/src/kernel_liteos_a/testsuites/unittest/process/fs/BUILD.gn new file mode 100644 index 00000000..2308401a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/fs/BUILD.gn @@ -0,0 +1,56 @@ +# Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("./config.gni") + +if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_LOW) { + unittest("liteos_a_process_fs_unittest_door") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + include_dirs = common_include_dirs + sources = sources_entry + sources += sources_smoke + sources_full = [] + sources += sources_full + configs = [ "../..:public_config_for_door" ] + deps = [ "$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR:libsec_shared" ] + } +} + +if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_MIDDLE) { + unittest("liteos_a_process_fs_unittest") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + include_dirs = common_include_dirs + sources = sources_entry + sources += sources_smoke + sources += sources_full + configs = [ "../..:public_config_for_all" ] + deps = [ "$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR:libsec_shared" ] + } +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/fs/It_process_fs_test.h b/src/kernel_liteos_a/testsuites/unittest/process/fs/It_process_fs_test.h new file mode 100644 index 00000000..42cc14cb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/fs/It_process_fs_test.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _IT_PROCESS_FS_TEST_H +#define _IT_PROCESS_FS_TEST_H + +#include +#include +#include "osTest.h" + +extern VOID PrintTest(const CHAR *fmt, ...); + +extern std::string GenProcPidPath(int pid); +extern std::string GenProcPidContainerPath(int pid, char *name); + +extern void ItProcessFs001(void); +extern void ItProcessFs002(void); +extern void ItProcessFs003(void); +extern void ItProcessFs004(void); +extern void ItProcessFs005(void); +extern void ItProcessFs006(void); +extern void ItProcessFs007(void); +extern void ItProcessFs008(void); +extern void ItProcessFs009(void); +extern void ItProcessFs010(void); +extern void ItProcessFs011(void); +extern void ItProcessFs012(void); +extern void ItProcessFs013(void); +extern void ItProcessFs014(void); +extern void ItProcessFs015(void); +extern void ItProcessFs015(void); +extern void ItProcessFs016(void); +extern void ItProcessFs017(void); +extern void ItProcessFs018(void); +extern void ItProcessFs019(void); +extern void ItProcessFs020(void); +extern void ItProcessFs021(void); +extern void ItProcessFs022(void); +#endif diff --git a/src/kernel_liteos_a/testsuites/unittest/process/fs/config.gni b/src/kernel_liteos_a/testsuites/unittest/process/fs/config.gni new file mode 100644 index 00000000..a12552a1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/fs/config.gni @@ -0,0 +1,76 @@ +# Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//build/lite/config/test.gni") +import("//kernel/liteos_a/liteos.gni") +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +common_include_dirs = [ + "$THIRDPARTY_GOOGLETEST_DIR/googletest/include", + "../../common/include", +] + +sources_entry = [ "../../common/osTest.cpp" ] + +sources_smoke = [] + +sources_full = [] + +process_fs_include_dirs = [ "$TEST_UNITTEST_DIR/process/fs" ] + +process_fs_sources_entry = + [ "$TEST_UNITTEST_DIR/process/fs/process_fs_test.cpp" ] + +process_fs_sources_smoke = [ + "$TEST_UNITTEST_DIR/process/fs/smoke/It_process_fs_001.cpp", + "$TEST_UNITTEST_DIR/process/fs/smoke/It_process_fs_002.cpp", + "$TEST_UNITTEST_DIR/process/fs/smoke/It_process_fs_003.cpp", + "$TEST_UNITTEST_DIR/process/fs/smoke/It_process_fs_004.cpp", + "$TEST_UNITTEST_DIR/process/fs/smoke/It_process_fs_005.cpp", + "$TEST_UNITTEST_DIR/process/fs/smoke/It_process_fs_007.cpp", + "$TEST_UNITTEST_DIR/process/fs/smoke/It_process_fs_008.cpp", + "$TEST_UNITTEST_DIR/process/fs/smoke/It_process_fs_009.cpp", + "$TEST_UNITTEST_DIR/process/fs/smoke/It_process_fs_010.cpp", + "$TEST_UNITTEST_DIR/process/fs/smoke/It_process_fs_011.cpp", + "$TEST_UNITTEST_DIR/process/fs/smoke/It_process_fs_012.cpp", + "$TEST_UNITTEST_DIR/process/fs/smoke/It_process_fs_013.cpp", + "$TEST_UNITTEST_DIR/process/fs/smoke/It_process_fs_014.cpp", + "$TEST_UNITTEST_DIR/process/fs/smoke/It_process_fs_015.cpp", + "$TEST_UNITTEST_DIR/process/fs/smoke/It_process_fs_021.cpp", + "$TEST_UNITTEST_DIR/process/fs/smoke/It_process_fs_022.cpp", +] + +process_fs_sources_full = [] + +# fs module +if (LOSCFG_USER_TEST_PROCESS_FS == true) { + common_include_dirs += process_fs_include_dirs + sources_entry += process_fs_sources_entry + sources_smoke += process_fs_sources_smoke + sources_full += process_fs_sources_full +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/fs/process_fs_test.cpp b/src/kernel_liteos_a/testsuites/unittest/process/fs/process_fs_test.cpp new file mode 100644 index 00000000..fc12de19 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/fs/process_fs_test.cpp @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include "It_process_fs_test.h" + +VOID PrintTest(const CHAR *fmt, ...) +{ +#ifdef PRINT_TEST + va_list ap; + if (g_osLkHook != nullptr) { + va_start(ap, fmt); + printf(fmt, ap); + va_end(ap); + } +#endif +} + +std::string GenProcPidPath(int pid) +{ + std::ostringstream buf; + buf << "/proc/" << pid; + return buf.str(); +} + +std::string GenProcPidContainerPath(int pid, char *name) +{ + std::ostringstream buf; + buf << "/proc/" << pid << "/container/" << name; + return buf.str(); +} + + +using namespace testing::ext; +namespace OHOS { +class ProcessFsTest : public testing::Test { +public: + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} +}; + +#if defined(LOSCFG_USER_TEST_SMOKE) +/** +* @tc.name: Process_fs_Test_001 +* @tc.desc: Process mount directory test +* @tc.type: FUNC +* @tc.require: issueI6AEVV +* @tc.author: +*/ +HWTEST_F(ProcessFsTest, ItProcessFs001, TestSize.Level0) +{ + ItProcessFs001(); +} + +/** +* @tc.name: Process_fs_Test_002 +* @tc.desc: System memory information acquisition test +* @tc.type: FUNC +* @tc.require: issueI6AMVG +* @tc.author: +*/ +HWTEST_F(ProcessFsTest, ItProcessFs002, TestSize.Level0) +{ + ItProcessFs002(); +} + +/** +* @tc.name: Process_fs_Test_003 +* @tc.desc: Get the file system type information supported by the system test +* @tc.type: FUNC +* @tc.require: issueI6AMVG +* @tc.author: +*/ +HWTEST_F(ProcessFsTest, ItProcessFs003, TestSize.Level0) +{ + ItProcessFs003(); +} + +/** +* @tc.name: Process_fs_Test_004 +* @tc.desc: Process memory information acquisition test +* @tc.type: FUNC +* @tc.require: issueI6AMVG +* @tc.author: +*/ +HWTEST_F(ProcessFsTest, ItProcessFs004, TestSize.Level0) +{ + ItProcessFs004(); +} + +/** +* @tc.name: Process_fs_Test_005 +* @tc.desc: Process cpup information acquisition test +* @tc.type: FUNC +* @tc.require: issueI6AMVG +* @tc.author: +*/ + +HWTEST_F(ProcessFsTest, ItProcessFs005, TestSize.Level0) +{ + ItProcessFs005(); +} + +/** +* @tc.name: Process_fs_Test_007 +* @tc.desc: Process mount directory test +* @tc.type: FUNC +* @tc.require: issueI6AEVV +* @tc.author: +*/ +HWTEST_F(ProcessFsTest, ItProcessFs007, TestSize.Level0) +{ + ItProcessFs007(); +} + +/** +* @tc.name: Process_fs_Test_008 +* @tc.desc: Process mount directory test +* @tc.type: FUNC +* @tc.require: issueI6APW2 +* @tc.author: +*/ +HWTEST_F(ProcessFsTest, ItProcessFs008, TestSize.Level0) +{ + ItProcessFs008(); +} + +/** +* @tc.name: Process_fs_Test_010 +* @tc.desc: Process mount directory test +* @tc.type: FUNC +* @tc.require: issueI6AEVV +* @tc.author: +*/ +HWTEST_F(ProcessFsTest, ItProcessFs010, TestSize.Level0) +{ + ItProcessFs010(); +} + +/** +* @tc.name: Process_fs_Test_011 +* @tc.desc: Process mount directory test +* @tc.type: FUNC +* @tc.require: issueI6E2LG +* @tc.author: +*/ +HWTEST_F(ProcessFsTest, ItProcessFs011, TestSize.Level0) +{ + ItProcessFs011(); +} + +/** +* @tc.name: Process_fs_Test_012 +* @tc.desc: Process mount directory test +* @tc.type: FUNC +* @tc.require: issueI6AEVV +* @tc.author: +*/ +HWTEST_F(ProcessFsTest, ItProcessFs012, TestSize.Level0) +{ + ItProcessFs012(); +} + +/** +* @tc.name: Process_fs_Test_013 +* @tc.desc: Process mount directory test +* @tc.type: FUNC +* @tc.require: issueI6AEVV +* @tc.author: +*/ +HWTEST_F(ProcessFsTest, ItProcessFs013, TestSize.Level0) +{ + ItProcessFs013(); +} + +/** +* @tc.name: Process_fs_Test_014 +* @tc.desc: Process mount directory test +* @tc.type: FUNC +* @tc.require: issueI6AEVV +* @tc.author: +*/ +HWTEST_F(ProcessFsTest, ItProcessFs014, TestSize.Level0) +{ + ItProcessFs014(); +} + +/** +* @tc.name: Process_fs_Test_015 +* @tc.desc: Process mount directory test +* @tc.type: FUNC +* @tc.require: issueI6AEVV +* @tc.author: +*/ +HWTEST_F(ProcessFsTest, ItProcessFs015, TestSize.Level0) +{ + ItProcessFs015(); +} + +/** +* @tc.name: Process_fs_Test_021 +* @tc.desc: Process mount directory test +* @tc.type: FUNC +* @tc.require: issueI6AVMY +* @tc.author: +*/ +HWTEST_F(ProcessFsTest, ItProcessFs021, TestSize.Level0) +{ + ItProcessFs021(); +} + +/** +* @tc.name: Process_fs_Test_022 +* @tc.desc: Process mount directory test +* @tc.type: FUNC +* @tc.require: issueI6B0A3 +* @tc.author: +*/ +HWTEST_F(ProcessFsTest, ItProcessFs022, TestSize.Level0) +{ + ItProcessFs022(); +} +#endif +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_001.cpp b/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_001.cpp new file mode 100644 index 00000000..5bd1256e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_001.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include "It_process_fs_test.h" + +void ItProcessFs001(void) +{ + auto path = GenProcPidPath(getpid()); + DIR *dirp = opendir(path.data()); + ASSERT_NE(dirp, nullptr); + + (void)closedir(dirp); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_002.cpp b/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_002.cpp new file mode 100644 index 00000000..d558aff9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_002.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "It_process_fs_test.h" + +using namespace std; + +void ItProcessFs002(void) +{ + const int LEN_BUFF = 512; + char szStatBuf[LEN_BUFF]; + FILE *fp = fopen("/proc/meminfo", "rb"); + ASSERT_NE(fp, nullptr); + + int ret = fread(szStatBuf, 1, LEN_BUFF, fp); + (void)fclose(fp); + ASSERT_NE(ret, -1); + + char *res = strstr(szStatBuf, "UsedSize"); + ASSERT_NE(res, nullptr); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_003.cpp b/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_003.cpp new file mode 100644 index 00000000..90f6b89b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_003.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "It_process_fs_test.h" + +using namespace std; + +void ItProcessFs003(void) +{ + const int LEN_STAT = 512; + char szStatBuf[LEN_STAT]; + FILE *fp = fopen("/proc/filesystems", "r"); + ASSERT_NE(fp, nullptr); + + (void)memset_s(szStatBuf, LEN_STAT, 0, LEN_STAT); + int readLen = fread(szStatBuf, 1, LEN_STAT, fp); + + PrintTest("cat /proc/filesystems\n"); + PrintTest("%s\n", szStatBuf); + ASSERT_EQ(readLen, strlen(szStatBuf)); + + char *res = strstr(szStatBuf, "procfs"); + ASSERT_NE(res, nullptr); + + (void)fclose(fp); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_004.cpp b/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_004.cpp new file mode 100644 index 00000000..55e6c748 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_004.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "It_process_fs_test.h" + +static std::string gen_proc_pid_meminfo_path(int pid) +{ + std::ostringstream buf; + buf << "/proc/" << pid << "/meminfo"; + return buf.str(); +} + +static void operPidMemInfo(std::string strFile) +{ + const int FILE_LEN = 1024; + char szStatBuf[FILE_LEN]; + FILE *fp = fopen(strFile.c_str(), "rb"); + ASSERT_NE(fp, nullptr); + + (void)memset_s(szStatBuf, FILE_LEN, 0, FILE_LEN); + int ret = fread(szStatBuf, 1, FILE_LEN, fp); + PrintTest("cat %s\n", strFile.c_str()); + PrintTest("%s\n", szStatBuf); + ASSERT_EQ(ret, strlen(szStatBuf)); + + char *res = strstr(szStatBuf, "VMSpaceSize"); + ASSERT_NE(res, nullptr); + + (void)fclose(fp); +} + +void ItProcessFs004(void) +{ + auto path = gen_proc_pid_meminfo_path(getpid()); + operPidMemInfo(path); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_005.cpp b/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_005.cpp new file mode 100644 index 00000000..1952a168 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_005.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "It_process_fs_test.h" + +static std::string gen_proc_pid_cpup_path(int pid) +{ + std::ostringstream buf; + buf << "/proc/" << pid << "/cpup"; + return buf.str(); +} + +static void operPidCpup(std::string strFile) +{ + const int PUP_LEN = 1024; + char szStatBuf[PUP_LEN]; + FILE *fp = fopen(strFile.c_str(), "rb"); + ASSERT_NE(fp, nullptr); + + (void)memset_s(szStatBuf, PUP_LEN, 0, PUP_LEN); + int ret = fread(szStatBuf, 1, PUP_LEN, fp); + PrintTest("cat %s\n", strFile.c_str()); + + PrintTest("%s\n", szStatBuf); + ASSERT_EQ(ret, strlen(szStatBuf)); + + char *res = strstr(szStatBuf, "TotalRunningTime"); + ASSERT_NE(res, nullptr); + + (void)fclose(fp); +} + +void ItProcessFs005(void) +{ + auto path = gen_proc_pid_cpup_path(getpid()); + operPidCpup(path); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_007.cpp b/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_007.cpp new file mode 100644 index 00000000..88ada66e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_007.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include "It_process_fs_test.h" + +void ItProcessFs007(void) +{ + auto path = GenProcPidContainerPath(getpid(), "uts"); + std::vector buf(PATH_MAX); + auto nbytes = readlink(path.c_str(), buf.data(), PATH_MAX); + ASSERT_NE(nbytes, -1); + + std::regex reg("'uts:\\[[0-9]+\\]'"); + bool ret = std::regex_match(buf.data(), reg); + ASSERT_EQ(ret, true); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_008.cpp b/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_008.cpp new file mode 100644 index 00000000..176de0db --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_008.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include "It_process_fs_test.h" + +void ItProcessFs008(void) +{ + auto path = GenProcPidContainerPath(getpid(), "mnt"); + std::vector buf(PATH_MAX); + auto nbytes = readlink(path.c_str(), buf.data(), PATH_MAX); + ASSERT_NE(nbytes, -1); + + std::regex reg("'mnt:\\[[0-9]+\\]'"); + bool ret = std::regex_match(buf.data(), reg); + ASSERT_EQ(ret, true); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_009.cpp b/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_009.cpp new file mode 100644 index 00000000..9516e5bd --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_009.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include "It_process_fs_test.h" + +void ItProcessFs009(void) +{ + auto path = GenProcPidContainerPath(getpid(), "user"); + std::vector buf(PATH_MAX); + auto nbytes = readlink(path.c_str(), buf.data(), PATH_MAX); + ASSERT_NE(nbytes, -1); + + std::regex reg("'user:\\[[0-9]+\\]'"); + bool ret = std::regex_match(buf.data(), reg); + ASSERT_EQ(ret, true); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_010.cpp b/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_010.cpp new file mode 100644 index 00000000..eef710df --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_010.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include "It_process_fs_test.h" + +void ItProcessFs010(void) +{ + auto path = GenProcPidContainerPath(getpid(), "pid"); + std::vector buf(PATH_MAX); + auto nbytes = readlink(path.c_str(), buf.data(), PATH_MAX); + ASSERT_NE(nbytes, -1); + + std::regex reg("'pid:\\[[0-9]+\\]'"); + bool ret = std::regex_match(buf.data(), reg); + ASSERT_EQ(ret, true); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_011.cpp b/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_011.cpp new file mode 100644 index 00000000..49f26e62 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_011.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include "It_process_fs_test.h" + +void ItProcessFs011(void) +{ + auto path = GenProcPidContainerPath(getpid(), "net"); + std::vector buf(PATH_MAX); + auto nbytes = readlink(path.c_str(), buf.data(), PATH_MAX); + ASSERT_NE(nbytes, -1); + + std::regex reg("'net:\\[[0-9]+\\]'"); + bool ret = std::regex_match(buf.data(), reg); + ASSERT_EQ(ret, true); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_012.cpp b/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_012.cpp new file mode 100644 index 00000000..858a5edb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_012.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include "It_process_fs_test.h" + +static const int STACK_SIZE = 1024 * 1024; +static const int CHILD_FUNC_ARG = 0x2088; + +static int child_process(void *arg) +{ + (void)arg; + pid_t pid = getpid(); + std::ostringstream buf; + buf << "/proc/" << pid; + DIR *dirp = opendir(buf.str().data()); + if (dirp == nullptr) { + return 1; + } + + (void)closedir(dirp); + return 0; +} + +void ItProcessFs012(void) +{ + int ret = 0; + int status; + char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, + -1, 0); + ASSERT_NE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + int arg = CHILD_FUNC_ARG; + pid_t pid = clone(child_process, stackTop, SIGCHLD, &arg); + ASSERT_NE(pid, -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); + + std::ostringstream buf; + buf << "/proc/" << pid; + DIR *dirp = opendir(buf.str().data()); + ASSERT_EQ(dirp, nullptr); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_013.cpp b/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_013.cpp new file mode 100644 index 00000000..d34d49d5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_013.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include "It_process_fs_test.h" + +void ItProcessFs013(void) +{ + std::string path; + DIR *dirp = nullptr; + path = GenProcPidPath(1); + printf("path: %s\n", path.c_str()); + dirp = opendir(path.data()); + ASSERT_NE(dirp, nullptr); + (void)closedir(dirp); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_014.cpp b/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_014.cpp new file mode 100644 index 00000000..4f34c907 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_014.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include "It_process_fs_test.h" + +void ItProcessFs014(void) +{ + std::string path = "/proc/100000"; + DIR *dirp = nullptr; + dirp = opendir(path.c_str()); + ASSERT_EQ(dirp, nullptr); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_015.cpp b/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_015.cpp new file mode 100644 index 00000000..ac5f155b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_015.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include "It_process_fs_test.h" + +void ItProcessFs015(void) +{ + std::string path = "/proc/power"; + DIR *dirp = nullptr; + dirp = opendir(path.c_str()); + ASSERT_NE(dirp, nullptr); + + (void)closedir(dirp); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_021.cpp b/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_021.cpp new file mode 100644 index 00000000..ed36886b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_021.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include "It_process_fs_test.h" + +void ItProcessFs021(void) +{ + auto path = GenProcPidContainerPath(getpid(), "ipc"); + std::vector buf(PATH_MAX); + auto nbytes = readlink(path.c_str(), buf.data(), PATH_MAX); + ASSERT_NE(nbytes, -1); + + std::regex reg("'ipc:\\[[0-9]+\\]'"); + bool ret = std::regex_match(buf.data(), reg); + ASSERT_EQ(ret, true); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_022.cpp b/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_022.cpp new file mode 100644 index 00000000..e09cded3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/fs/smoke/It_process_fs_022.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include "It_process_fs_test.h" + +void ItProcessFs022(void) +{ + auto path = GenProcPidContainerPath(getpid(), "time"); + std::vector buf(PATH_MAX); + auto nbytes = readlink(path.c_str(), buf.data(), PATH_MAX); + ASSERT_NE(nbytes, -1); + + std::regex reg("'time:\\[[0-9]+\\]'"); + bool ret = std::regex_match(buf.data(), reg); + ASSERT_EQ(ret, true); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/lock/BUILD.gn b/src/kernel_liteos_a/testsuites/unittest/process/lock/BUILD.gn new file mode 100644 index 00000000..e1d1fd24 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/lock/BUILD.gn @@ -0,0 +1,56 @@ +# Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("./config.gni") + +if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_LOW) { + unittest("liteos_a_process_lock_unittest_door") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + include_dirs = common_include_dirs + sources = sources_entry + sources += sources_smoke + sources_full = [] + sources += sources_full + configs = [ "../..:public_config_for_door" ] + deps = [ "$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR:libsec_shared" ] + } +} + +if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_MIDDLE) { + unittest("liteos_a_process_lock_unittest") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + include_dirs = common_include_dirs + sources = sources_entry + sources += sources_smoke + sources += sources_full + configs = [ "../..:public_config_for_all" ] + deps = [ "$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR:libsec_shared" ] + } +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/lock/config.gni b/src/kernel_liteos_a/testsuites/unittest/process/lock/config.gni new file mode 100644 index 00000000..550902fe --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/lock/config.gni @@ -0,0 +1,69 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//build/lite/config/test.gni") +import("//kernel/liteos_a/liteos.gni") +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +common_include_dirs = [ + "$THIRDPARTY_GOOGLETEST_DIR/googletest/include", + "../../common/include", +] + +sources_entry = [ "../../common/osTest.cpp" ] + +sources_smoke = [] + +sources_full = [] + +# process lock mutex module +if (LOSCFG_USER_TEST_PROCESS_LOCK_MUTEX == true) { + import("./mutex/config.gni") + common_include_dirs += process_lock_mutex_include_dirs + sources_entry += process_lock_mutex_sources_entry + sources_smoke += process_lock_mutex_sources_smoke + sources_full += process_lock_mutex_sources_full +} + +# process lock rwlock module +if (LOSCFG_USER_TEST_PROCESS_LOCK_RWLOCK == true) { + import("./rwlock/config.gni") + common_include_dirs += process_lock_rwlock_include_dirs + sources_entry += process_lock_rwlock_sources_entry + sources_smoke += process_lock_rwlock_sources_smoke + sources_full += process_lock_rwlock_sources_full +} + +# process lock spinlock module +if (LOSCFG_USER_TEST_PROCESS_LOCK_SPINLOCK == true) { + import("./spinlock/config.gni") + common_include_dirs += process_lock_spinlock_include_dirs + sources_entry += process_lock_spinlock_sources_entry + sources_smoke += process_lock_spinlock_sources_smoke + sources_full += process_lock_spinlock_sources_full +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/config.gni b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/config.gni new file mode 100644 index 00000000..6ff147dd --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/config.gni @@ -0,0 +1,66 @@ +# Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//build/lite/config/test.gni") +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +process_lock_mutex_include_dirs = [ "$TEST_UNITTEST_DIR/process/lock/mutex" ] + +process_lock_mutex_sources_entry = + [ "$TEST_UNITTEST_DIR/process/lock/mutex/process_mutex_test.cpp" ] + +process_lock_mutex_sources_smoke = [ + "$TEST_UNITTEST_DIR/process/lock/mutex/smoke/pthread_mutex_test_001.cpp", + "$TEST_UNITTEST_DIR/process/lock/mutex/smoke/pthread_mutex_test_002.cpp", + "$TEST_UNITTEST_DIR/process/lock/mutex/smoke/pthread_mutex_test_003.cpp", + "$TEST_UNITTEST_DIR/process/lock/mutex/smoke/pthread_mutex_test_004.cpp", + "$TEST_UNITTEST_DIR/process/lock/mutex/smoke/pthread_mutex_test_005.cpp", + "$TEST_UNITTEST_DIR/process/lock/mutex/smoke/pthread_mutex_test_006.cpp", + "$TEST_UNITTEST_DIR/process/lock/mutex/smoke/pthread_mutex_test_007.cpp", + "$TEST_UNITTEST_DIR/process/lock/mutex/smoke/pthread_mutex_test_008.cpp", + "$TEST_UNITTEST_DIR/process/lock/mutex/smoke/pthread_mutex_test_009.cpp", + "$TEST_UNITTEST_DIR/process/lock/mutex/smoke/pthread_mutex_test_010.cpp", + "$TEST_UNITTEST_DIR/process/lock/mutex/smoke/pthread_mutex_test_011.cpp", + "$TEST_UNITTEST_DIR/process/lock/mutex/smoke/pthread_mutex_test_012.cpp", + "$TEST_UNITTEST_DIR/process/lock/mutex/smoke/pthread_mutex_test_013.cpp", + "$TEST_UNITTEST_DIR/process/lock/mutex/smoke/pthread_mutex_test_014.cpp", + "$TEST_UNITTEST_DIR/process/lock/mutex/smoke/pthread_mutex_test_015.cpp", + "$TEST_UNITTEST_DIR/process/lock/mutex/smoke/pthread_mutex_test_016.cpp", + "$TEST_UNITTEST_DIR/process/lock/mutex/smoke/pthread_mutex_test_017.cpp", + "$TEST_UNITTEST_DIR/process/lock/mutex/smoke/pthread_mutex_test_019.cpp", + "$TEST_UNITTEST_DIR/process/lock/mutex/smoke/pthread_mutex_test_020.cpp", + "$TEST_UNITTEST_DIR/process/lock/mutex/smoke/pthread_mutex_test_021.cpp", + "$TEST_UNITTEST_DIR/process/lock/mutex/smoke/pthread_mutex_test_022.cpp", +] + +process_lock_mutex_sources_full = [ + "$TEST_UNITTEST_DIR/process/lock/mutex/full/pthread_mutex_test_018.cpp", + "$TEST_UNITTEST_DIR/process/lock/mutex/full/pthread_mutex_test_023.cpp", + "$TEST_UNITTEST_DIR/process/lock/mutex/full/pthread_mutex_test_024.cpp", + "$TEST_UNITTEST_DIR/process/lock/mutex/full/pthread_mutex_test_025.cpp", +] diff --git a/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/full/pthread_mutex_test_018.cpp b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/full/pthread_mutex_test_018.cpp new file mode 100644 index 00000000..7980e275 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/full/pthread_mutex_test_018.cpp @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_mutex_test.h" + +static pthread_mutex_t g_muxLock001; +static pthread_mutex_t g_muxLock002; +static pthread_mutex_t g_muxLock003; + +static const unsigned int TEST_COUNT = 10; +static volatile int g_testToCount001 = 0; +static volatile int g_testToCount002 = 0; +static volatile int g_testToCount003 = 0; + +static void *ThreadFuncTest2(void *a) +{ + int ret; + pthread_t thread = pthread_self(); + struct timespec time; + struct timeval timeVal = { 0 }; + + ret = pthread_detach(thread); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_mutex_lock(&g_muxLock001); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_mutex_unlock(&g_muxLock001); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testToCount002 = 1; + + return nullptr; + +EXIT: + g_testToCount002 = -1; + return nullptr; +} + +static void *ThreadFuncTest1(void *a) +{ + int ret; + pthread_t thread = pthread_self(); + struct timespec time; + struct timeval timeVal = { 0 }; + + gettimeofday(&timeVal, nullptr); + + if(timeVal.tv_usec + 100000 >= 1000000) { // 100000us, delay time; 1000000us, compare + time.tv_sec = timeVal.tv_sec + 1; + time.tv_nsec = (timeVal.tv_usec + 100000 - 1000000) * 1000; // 100000, delaytime; 1000, us to ns; 1000000us=1s; + } else { + time.tv_sec = timeVal.tv_sec + 0; + time.tv_nsec = (timeVal.tv_usec + 100000) * 1000; // 1000, 100000us to ns + } + + ret = pthread_mutex_timedlock(&g_muxLock001, &time); + ICUNIT_GOTO_EQUAL(ret, ETIMEDOUT, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testToCount002, 1, g_testToCount002, EXIT); + + g_testToCount001 = 1; + return nullptr; + +EXIT: + g_testToCount001 = -1; + return nullptr; +} + +static int Testcase(void) +{ + struct sched_param param = { 0 }; + int ret; + void *res = nullptr; + pthread_attr_t a = { 0 }; + pthread_t thread = pthread_self(); + pthread_t newPthread, newPthread1; + pthread_mutexattr_t mutex; + int index = TEST_COUNT; + int gCurrThreadPri, gCurrThreadPolicy; + struct timeval time = { 0 }; + struct timeval timeVal = { 0 }; + + ret = pthread_getschedparam(pthread_self(), &gCurrThreadPolicy, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, -ret); + + gCurrThreadPri = param.sched_priority; + + ret = pthread_attr_init(&a); + + // 2, Set the priority according to the task purpose,a smaller number means a higher priority. + param.sched_priority = gCurrThreadPri + 2; + pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED); + pthread_attr_setschedparam(&a, ¶m); + + while (index) { + pthread_mutexattr_settype(&mutex, PTHREAD_MUTEX_NORMAL); + pthread_mutex_init(&g_muxLock001, &mutex); + + g_testToCount001 = 0; + g_testToCount002 = 0; + + ret = pthread_mutex_lock(&g_muxLock001); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newPthread, &a, ThreadFuncTest1, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + usleep(1000 * 10 * 2); // 1000, 10, 2 + + ret = pthread_create(&newPthread1, nullptr, ThreadFuncTest2, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + gettimeofday(&timeVal, nullptr); + while (1) { + gettimeofday(&time, nullptr); + if ((time.tv_sec - timeVal.tv_sec) >= 1) { + break; + } + } + + ret = pthread_mutex_unlock(&g_muxLock001); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newPthread, nullptr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_NOT_EQUAL(g_testToCount001, -1, g_testToCount001); + ICUNIT_ASSERT_NOT_EQUAL(g_testToCount002, -1, g_testToCount002); + pthread_mutex_destroy(&g_muxLock003); + index--; + } + return 0; +} + +void ItTestPthreadMutex018(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_MUTEX_018", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/full/pthread_mutex_test_023.cpp b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/full/pthread_mutex_test_023.cpp new file mode 100644 index 00000000..b782afbe --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/full/pthread_mutex_test_023.cpp @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_mutex_test.h" + +static pthread_mutex_t g_mutexLock; +static volatile int g_testToCount001 = 0; +static volatile int g_testToCount002 = 0; + +static void *ThreadFuncTest1(void *arg) +{ + int ret = pthread_mutex_lock(&g_mutexLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testToCount001++; + return nullptr; + +EXIT: + g_testToCount001 = -1; + return nullptr; +} + +static void *ThreadFuncTest2(void *arg) +{ + int ret = pthread_mutex_lock(&g_mutexLock); + ICUNIT_GOTO_EQUAL(ret, EOWNERDEAD, ret, EXIT); + + ret = pthread_mutex_consistent(&g_mutexLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testToCount002++; + ret = pthread_mutex_unlock(&g_mutexLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + return nullptr; + +EXIT: + g_testToCount002 = -1; + return nullptr; +} + +static int Testcase(void) +{ + int ret; + pthread_t tid1, tid2; + pthread_mutexattr_t attr; + int robust; + + pthread_mutexattr_init(&attr); + + pthread_mutexattr_getrobust(&attr, &robust); + ICUNIT_ASSERT_EQUAL(robust, 0, robust); + + ret = pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + pthread_mutexattr_getrobust(&attr, &robust); + ICUNIT_ASSERT_EQUAL(robust, PTHREAD_MUTEX_ROBUST, robust); + + pthread_mutex_init(&g_mutexLock, &attr); + + pthread_mutexattr_destroy(&attr); + + g_testToCount001 = 0; + g_testToCount002 = 0; + + ret = pthread_create(&tid1, nullptr, ThreadFuncTest1, nullptr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&tid2, nullptr, ThreadFuncTest2, nullptr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + pthread_join(tid1, nullptr); + pthread_join(tid2, nullptr); + + while (g_testToCount001 == 0 || g_testToCount002 == 0) { + } + ICUNIT_ASSERT_NOT_EQUAL(g_testToCount001, -1, g_testToCount001); + ICUNIT_ASSERT_NOT_EQUAL(g_testToCount002, -1, g_testToCount002); + + pthread_mutex_destroy(&g_mutexLock); + + return 0; +} + +void ItTestPthreadMutex023(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_MUTEX_023", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/full/pthread_mutex_test_024.cpp b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/full/pthread_mutex_test_024.cpp new file mode 100644 index 00000000..acf5b183 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/full/pthread_mutex_test_024.cpp @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "it_mutex_test.h" + +static pthread_mutex_t g_muxLock001; +static pthread_mutex_t g_muxLock002; +static pthread_mutex_t g_muxLock003; +static volatile int g_testToCount001 = 0; +static volatile int g_testToCount002 = 0; +static volatile int g_testToCount003 = 0; + +static void *ThreadFuncTest1(void *arg) +{ + int ret = pthread_mutex_lock(&g_muxLock001); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + ret = pthread_mutex_consistent(&g_muxLock001); + ICUNIT_GOTO_EQUAL(ret, EINVAL, ret, EXIT); + + g_testToCount001++; + return nullptr; + +EXIT: + g_testToCount001 = -1; + return nullptr; +} + +static void *ThreadFuncTest2(void *arg) +{ + int ret = pthread_mutex_lock(&g_muxLock001); + ICUNIT_GOTO_EQUAL(ret, EOWNERDEAD, ret, EXIT); + + g_testToCount002 = 1; + + while (g_testToCount003 == 0) { + sleep(1); + } + + g_testToCount002++; + return nullptr; + +EXIT: + g_testToCount002 = -1; + return nullptr; +} +static void *ThreadFuncTest3(void *arg) +{ + int ret = pthread_mutex_consistent(&g_muxLock001); + ICUNIT_GOTO_EQUAL(ret, EPERM, ret, EXIT); + g_testToCount003 = 1; + + for (int i = 0; i < 5; i++) { // 5 + sleep(1); + } + + g_testToCount003++; + return nullptr; + +EXIT: + g_testToCount003 = -1; + return nullptr; +} + +static int Testcase(void) +{ + int ret; + pthread_t tid1, tid2, tid3; + pthread_mutexattr_t attr; + int robust; + + pthread_mutexattr_init(&attr); + + pthread_mutexattr_getrobust(&attr, &robust); + ICUNIT_ASSERT_EQUAL(robust, 0, robust); + + ret = pthread_mutexattr_setrobust(&attr, 2); // 2 + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + pthread_mutex_init(&g_muxLock002, &attr); + ret = pthread_mutex_consistent(&g_muxLock002); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + pthread_mutexattr_getrobust(&attr, &robust); + ICUNIT_ASSERT_EQUAL(robust, PTHREAD_MUTEX_ROBUST, robust); + + pthread_mutex_init(&g_muxLock001, &attr); + pthread_mutex_init(&g_muxLock003, &attr); + + ret = pthread_mutex_consistent(&g_muxLock003); + ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + + ret = pthread_mutex_unlock(&g_muxLock003); + ICUNIT_ASSERT_EQUAL(ret, EPERM, ret); + + pthread_mutexattr_destroy(&attr); + + g_testToCount001 = 0; + g_testToCount002 = 0; + g_testToCount003 = 0; + + ret = pthread_create(&tid1, nullptr, ThreadFuncTest1, nullptr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&tid2, nullptr, ThreadFuncTest2, nullptr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + while (g_testToCount002 == 0) { + sleep(1); + } + + ret = pthread_create(&tid3, nullptr, ThreadFuncTest3, nullptr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + pthread_join(tid1, nullptr); + pthread_join(tid2, nullptr); + pthread_join(tid3, nullptr); + + ICUNIT_ASSERT_NOT_EQUAL(g_testToCount001, -1, g_testToCount001); + ICUNIT_ASSERT_NOT_EQUAL(g_testToCount002, -1, g_testToCount002); + ICUNIT_ASSERT_NOT_EQUAL(g_testToCount003, -1, g_testToCount003); + + pthread_mutex_destroy(&g_muxLock001); + pthread_mutex_destroy(&g_muxLock002); + pthread_mutex_destroy(&g_muxLock003); + + return 0; +} + +void ItTestPthreadMutex024(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_MUTEX_024", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/full/pthread_mutex_test_025.cpp b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/full/pthread_mutex_test_025.cpp new file mode 100644 index 00000000..77ec8240 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/full/pthread_mutex_test_025.cpp @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_mutex_test.h" + +static pthread_mutex_t g_mutexLock; +static volatile int g_testToCount001 = 0; +static volatile int g_testToCount002 = 0; + +static void *ThreadFuncTest1(void *arg) +{ + int ret = pthread_mutex_lock(&g_mutexLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testToCount001++; + return nullptr; + +EXIT: + g_testToCount001 = -1; + return nullptr; +} + +static void *ThreadFuncTest2(void *arg) +{ + int ret = pthread_mutex_lock(&g_mutexLock); + ICUNIT_GOTO_EQUAL(ret, EOWNERDEAD, ret, EXIT); + + ret = pthread_mutex_consistent(&g_mutexLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testToCount002++; + ret = pthread_mutex_unlock(&g_mutexLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + return nullptr; + +EXIT: + g_testToCount002 = -1; + return nullptr; +} + +static int Child() +{ + int ret; + pthread_t tid1, tid2; + pthread_mutexattr_t attr; + int robust; + + pthread_mutexattr_init(&attr); + + pthread_mutexattr_getrobust(&attr, &robust); + ICUNIT_ASSERT_EQUAL(robust, 0, robust); + + ret = pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + pthread_mutexattr_getrobust(&attr, &robust); + ICUNIT_ASSERT_EQUAL(robust, PTHREAD_MUTEX_ROBUST, robust); + + ret = pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_STALLED); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + pthread_mutexattr_getrobust(&attr, &robust); + ICUNIT_ASSERT_EQUAL(robust, PTHREAD_MUTEX_STALLED, robust); + + pthread_mutex_init(&g_mutexLock, &attr); + + pthread_mutexattr_destroy(&attr); + + g_testToCount001 = 0; + g_testToCount002 = 0; + + ret = pthread_create(&tid1, nullptr, ThreadFuncTest1, nullptr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&tid2, nullptr, ThreadFuncTest2, nullptr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + for (int i = 0; i < 5; i++) { // 5 + if (g_testToCount002 == 0) { + sleep(1); + } + } + + pthread_join(tid1, nullptr); + + ICUNIT_ASSERT_NOT_EQUAL(g_testToCount001, -1, g_testToCount001); + ICUNIT_ASSERT_EQUAL(g_testToCount002, 0, g_testToCount002); + + pthread_mutex_destroy(&g_mutexLock); + + exit(255); // 255, set exitcode +} + +static int Testcase(void) +{ + int ret; + int status; + + pid_t pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, The expected value + + if (pid == 0) { + Child(); + exit(0); + } + + ret = waitpid(pid, &status, 0); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(status, 255, status); // 255, exitcode is 255 + + return 0; +EXIT: + return 1; +} + +void ItTestPthreadMutex025(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_MUTEX_025", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/it_mutex_test.h b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/it_mutex_test.h new file mode 100644 index 00000000..8e1678f7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/it_mutex_test.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _IT_TEST_MUTEX_H +#define _IT_TEST_MUTEX_H +#include "osTest.h" +#include "sys/time.h" +#include + +#define SLEEP_AND_YIELD(tick) usleep((tick)*10 * 1000) + +extern int Gettid(void); +extern void ItTestPthreadMutex001(void); +extern void ItTestPthreadMutex002(void); +extern void ItTestPthreadMutex003(void); +extern void ItTestPthreadMutex004(void); +extern void ItTestPthreadMutex005(void); +extern void ItTestPthreadMutex006(void); +extern void ItTestPthreadMutex007(void); +extern void ItTestPthreadMutex008(void); +extern void ItTestPthreadMutex009(void); +extern void ItTestPthreadMutex010(void); +extern void ItTestPthreadMutex011(void); +extern void ItTestPthreadMutex012(void); +extern void ItTestPthreadMutex013(void); +extern void ItTestPthreadMutex014(void); +extern void ItTestPthreadMutex015(void); +extern void ItTestPthreadMutex016(void); +extern void ItTestPthreadMutex017(void); +extern void ItTestPthreadMutex018(void); +extern void ItTestPthreadMutex019(void); +extern void ItTestPthreadMutex020(void); +extern void ItTestPthreadMutex021(void); +extern void ItTestPthreadMutex022(void); +extern void ItTestPthreadMutex023(void); +extern void ItTestPthreadMutex024(void); +extern void ItTestPthreadMutex025(void); + +#endif diff --git a/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/process_mutex_test.cpp b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/process_mutex_test.cpp new file mode 100644 index 00000000..b30f43b4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/process_mutex_test.cpp @@ -0,0 +1,309 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "stdio.h" +#include +#include +#include +#include + +__attribute__((weak)) int Gettid() +{ + return syscall(SYS_gettid); +} + +#include "it_mutex_test.h" + +using namespace testing::ext; +namespace OHOS { +class ProcessMutexTest : public testing::Test { +public: + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} +}; + +#if defined(LOSCFG_USER_TEST_SMOKE) +/* * + * @tc.name: it_test_pthread_mutex_001 + * @tc.desc: function for ProcessMutexTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessMutexTest, ItTestPthreadMutex001, TestSize.Level0) +{ + ItTestPthreadMutex001(); +} + +/* * + * @tc.name: it_test_pthread_mutex_002 + * @tc.desc: function for ProcessMutexTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessMutexTest, ItTestPthreadMutex002, TestSize.Level0) +{ + ItTestPthreadMutex002(); +} + +/* * + * @tc.name: it_test_pthread_mutex_003 + * @tc.desc: function for ProcessMutexTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessMutexTest, ItTestPthreadMutex003, TestSize.Level0) +{ + ItTestPthreadMutex003(); +} + +/* * + * @tc.name: it_test_pthread_mutex_004 + * @tc.desc: function for ProcessMutexTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessMutexTest, ItTestPthreadMutex004, TestSize.Level0) +{ + ItTestPthreadMutex004(); +} + +/* * + * @tc.name: it_test_pthread_mutex_005 + * @tc.desc: function for ProcessMutexTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessMutexTest, ItTestPthreadMutex005, TestSize.Level0) +{ + ItTestPthreadMutex005(); +} + +/* * + * @tc.name: it_test_pthread_mutex_006 + * @tc.desc: function for ProcessMutexTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessMutexTest, ItTestPthreadMutex006, TestSize.Level0) +{ + ItTestPthreadMutex006(); +} + +/* * + * @tc.name: it_test_pthread_mutex_007 + * @tc.desc: function for ProcessMutexTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessMutexTest, ItTestPthreadMutex007, TestSize.Level0) +{ + ItTestPthreadMutex007(); +} + +/* * + * @tc.name: it_test_pthread_mutex_008 + * @tc.desc: function for ProcessMutexTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessMutexTest, ItTestPthreadMutex008, TestSize.Level0) +{ + ItTestPthreadMutex008(); +} + +/* * + * @tc.name: it_test_pthread_mutex_009 + * @tc.desc: function for ProcessMutexTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessMutexTest, ItTestPthreadMutex009, TestSize.Level0) +{ + ItTestPthreadMutex009(); +} + +/* * + * @tc.name: it_test_pthread_mutex_010 + * @tc.desc: function for ProcessMutexTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessMutexTest, ItTestPthreadMutex010, TestSize.Level0) +{ + ItTestPthreadMutex010(); +} + +/* * + * @tc.name: it_test_pthread_mutex_011 + * @tc.desc: function for ProcessMutexTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessMutexTest, ItTestPthreadMutex011, TestSize.Level0) +{ + ItTestPthreadMutex011(); +} + +/* * + * @tc.name: it_test_pthread_mutex_012 + * @tc.desc: function for ProcessMutexTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessMutexTest, ItTestPthreadMutex012, TestSize.Level0) +{ + ItTestPthreadMutex012(); +} + +/* * + * @tc.name: it_test_pthread_mutex_013 + * @tc.desc: function for ProcessMutexTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessMutexTest, ItTestPthreadMutex013, TestSize.Level0) +{ + ItTestPthreadMutex013(); +} + +/* * + * @tc.name: it_test_pthread_mutex_014 + * @tc.desc: function for ProcessMutexTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessMutexTest, ItTestPthreadMutex014, TestSize.Level0) +{ + ItTestPthreadMutex014(); +} + +/* * + * @tc.name: it_test_pthread_mutex_015 + * @tc.desc: function for ProcessMutexTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessMutexTest, ItTestPthreadMutex015, TestSize.Level0) +{ + ItTestPthreadMutex015(); +} + +/* * + * @tc.name: it_test_pthread_mutex_016 + * @tc.desc: function for ProcessMutexTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessMutexTest, ItTestPthreadMutex016, TestSize.Level0) +{ + ItTestPthreadMutex016(); +} + +/* * + * @tc.name: it_test_pthread_mutex_017 + * @tc.desc: function for ProcessMutexTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessMutexTest, ItTestPthreadMutex017, TestSize.Level0) +{ + ItTestPthreadMutex017(); +} + +#ifndef LOSCFG_USER_TEST_SMP +/* * + * @tc.name: it_test_pthread_mutex_019 + * @tc.desc: function for ProcessMutexTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessMutexTest, ItTestPthreadMutex019, TestSize.Level0) +{ + ItTestPthreadMutex019(); +} + +#endif +/* * + * @tc.name: it_test_pthread_mutex_020 + * @tc.desc: function for ProcessMutexTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessMutexTest, ItTestPthreadMutex020, TestSize.Level0) +{ + ItTestPthreadMutex020(); +} + +/* * + * @tc.name: it_test_pthread_mutex_021 + * @tc.desc: function for ProcessMutexTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessMutexTest, ItTestPthreadMutex021, TestSize.Level0) +{ + ItTestPthreadMutex021(); +} + +/* * + * @tc.name: it_test_pthread_mutex_022 + * @tc.desc: function for ProcessMutexTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessMutexTest, ItTestPthreadMutex022, TestSize.Level0) +{ + ItTestPthreadMutex022(); +} +#endif + +#if defined(LOSCFG_USER_TEST_FULL) +#ifndef LOSCFG_USER_TEST_SMP +/* * + * @tc.name: it_test_pthread_mutex_018 + * @tc.desc: function for ProcessMutexTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessMutexTest, ItTestPthreadMutex018, TestSize.Level0) +{ + ItTestPthreadMutex018(); +} +#endif + +/* * + * @tc.name: it_test_pthread_mutex_023 + * @tc.desc: function for test mutexattr robust + * @tc.type: FUNC + */ +HWTEST_F(ProcessMutexTest, ItTestPthreadMutex023, TestSize.Level0) +{ + ItTestPthreadMutex023(); +} + +/* * + * @tc.name: it_test_pthread_mutex_024 + * @tc.desc: function for test mutexattr robust:error return value + * @tc.type: FUNC + */ +HWTEST_F(ProcessMutexTest, ItTestPthreadMutex024, TestSize.Level0) +{ + ItTestPthreadMutex024(); +} + +/* * + * @tc.name: it_test_pthread_mutex_025 + * @tc.desc: test mutexattr robust:robustness product deadlock is not set + * @tc.type: FUNC + */ +HWTEST_F(ProcessMutexTest, ItTestPthreadMutex025, TestSize.Level0) +{ + ItTestPthreadMutex025(); +} +#endif +} // namespace OHOS diff --git a/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_001.cpp b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_001.cpp new file mode 100644 index 00000000..e0e6ff7b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_001.cpp @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_mutex_test.h" + +static pthread_mutex_t g_mutexLock; + +static const unsigned int TEST_COUNT = 5; +static int g_testInfo[5] = { 0 }; +static int g_testToCount = 0; +static int g_testBackCount = 0; + +static void *ThreadFuncTest3(void *a) +{ + int ret; + int tid = Gettid(); + pthread_t thread = pthread_self(); + + ret = pthread_detach(thread); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testInfo[g_testToCount] = tid; + g_testToCount++; + + ret = pthread_mutex_lock(&g_mutexLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testInfo[g_testBackCount], tid, tid, EXIT); + g_testBackCount++; + + ret = pthread_mutex_unlock(&g_mutexLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + +EXIT: + return nullptr; +} + +static int Testcase(void) +{ + int ret; + pthread_t newPthread; + pthread_mutexattr_t mutex; + int index = 0; + pthread_mutexattr_settype(&mutex, PTHREAD_MUTEX_NORMAL); + pthread_mutex_init(&g_mutexLock, &mutex); + + while (index < 1) { + g_testToCount = 0; + g_testBackCount = 0; + + ret = pthread_mutex_lock(&g_mutexLock); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + for (int count = 0; count < TEST_COUNT; count++) { + ret = pthread_create(&newPthread, nullptr, ThreadFuncTest3, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + SLEEP_AND_YIELD(1); + } + + ret = pthread_mutex_unlock(&g_mutexLock); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + SLEEP_AND_YIELD(1); + + ICUNIT_ASSERT_EQUAL(g_testBackCount, TEST_COUNT, g_testBackCount); + ICUNIT_ASSERT_EQUAL(g_testToCount, TEST_COUNT, g_testToCount); + + index++; + } + + pthread_mutex_destroy(&g_mutexLock); + return 0; +} + +void ItTestPthreadMutex001(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_MUTEX_001", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_002.cpp b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_002.cpp new file mode 100644 index 00000000..14eb9611 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_002.cpp @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_mutex_test.h" + +static pthread_mutex_t g_muxLock; + +static const unsigned int TEST_COUNT = 5; +static int g_testInfo[5] = { 0 }; +static int g_testToCount = 0; +static int g_testBackCount = 0; + +static void *ThreadFuncTest3(void *a) +{ + int ret; + int tid = Gettid(); + pthread_t thread = pthread_self(); + + ret = pthread_detach(thread); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testInfo[g_testToCount] = tid; + g_testToCount++; + + ret = pthread_mutex_lock(&g_muxLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testBackCount--; + + ret = pthread_mutex_unlock(&g_muxLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + +EXIT: + return nullptr; +} + +static int Testcase(void) +{ + struct sched_param param = { 0 }; + int ret; + pthread_attr_t a = { 0 }; + pthread_t newPthread; + pthread_mutexattr_t mutex; + int index = 0; + int currThreadPri, currThreadPolicy; + + pthread_mutexattr_settype(&mutex, PTHREAD_MUTEX_NORMAL); + pthread_mutex_init(&g_muxLock, &mutex); + + param.sched_priority = 20; // 20, Set Priorities + ret = pthread_setschedparam(pthread_self(), SCHED_RR, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_getschedparam(pthread_self(), &currThreadPolicy, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + currThreadPri = param.sched_priority; + + while (index < 2) { // 2 + g_testToCount = 0; + g_testBackCount = TEST_COUNT - 1; + ret = pthread_mutex_lock(&g_muxLock); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + for (int count = 0; count < TEST_COUNT; count++) { + ret = pthread_attr_init(&a); + param.sched_priority = currThreadPri - count - 1; + if (param.sched_priority < 0) { + param.sched_priority = 0; + printf("sched_priority is zero !!!\n"); + } + pthread_attr_setschedparam(&a, ¶m); + pthread_attr_setschedpolicy(&a, currThreadPolicy); + pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED); + ret = pthread_create(&newPthread, &a, ThreadFuncTest3, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + } + + ret = pthread_mutex_unlock(&g_muxLock); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + SLEEP_AND_YIELD(1); + + ICUNIT_ASSERT_EQUAL(g_testBackCount, -1, g_testBackCount); + ICUNIT_ASSERT_EQUAL(g_testToCount, TEST_COUNT, g_testToCount); + + index++; + } + + pthread_mutex_destroy(&g_muxLock); + return 0; +} + +void ItTestPthreadMutex002(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_MUTEX_002", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_003.cpp b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_003.cpp new file mode 100644 index 00000000..092ea25c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_003.cpp @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_mutex_test.h" + +static const unsigned int THREAD_COUNT = 5; +static pthread_mutex_t g_muxLock; +static int g_preTaskPri = 0; +static int g_testCnt = 0; + +static void *ThreadFuncTest3(void *a) +{ + int ret; + struct sched_param param = { 0 }; + pthread_t thread = pthread_self(); + int currThreadPri, currThreadPolicy; + + ret = pthread_detach(thread); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testCnt++; + + ret = pthread_mutex_lock(&g_muxLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_getschedparam(pthread_self(), &currThreadPolicy, ¶m); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + currThreadPri = param.sched_priority; + + if (g_preTaskPri == 0xffffffff) { + ICUNIT_GOTO_EQUAL(currThreadPri, 0, currThreadPri, EXIT); + } else { + ICUNIT_GOTO_WITHIN_EQUAL(currThreadPri, g_preTaskPri, 31, currThreadPri, EXIT); // 31, Lowest priority + } + + g_preTaskPri = currThreadPri; + g_testCnt--; + + ret = pthread_mutex_unlock(&g_muxLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + +EXIT: + return nullptr; +} + +static int Testcase(void) +{ + struct sched_param param = { 0 }; + int ret; + pthread_attr_t a = { 0 }; + pthread_t newPthread; + pthread_mutexattr_t mutex; + int currThreadPri, currThreadPolicy; + + g_preTaskPri = 0xffffffff; + g_testCnt = 0; + + pthread_mutexattr_settype(&mutex, PTHREAD_MUTEX_NORMAL); + pthread_mutex_init(&g_muxLock, &mutex); + + ret = pthread_getschedparam(pthread_self(), &currThreadPolicy, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + currThreadPri = param.sched_priority; + + ret = pthread_mutex_lock(&g_muxLock); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + pthread_attr_init(&a); + pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED); + for (int count = 0; count < THREAD_COUNT; count++) { + // 2, Set the priority according to the task purpose,a smaller number means a higher priority. + param.sched_priority = currThreadPri - 2 * count; + pthread_attr_setschedparam(&a, ¶m); + pthread_attr_setschedpolicy(&a, currThreadPolicy); + ret = pthread_create(&newPthread, &a, ThreadFuncTest3, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + } + + param.sched_priority = currThreadPri - 1; + pthread_attr_setschedparam(&a, ¶m); + pthread_attr_setschedpolicy(&a, currThreadPolicy); + ret = pthread_create(&newPthread, &a, ThreadFuncTest3, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + // 6, Set the priority according to the task purpose,a smaller number means a higher priority. + param.sched_priority = currThreadPri - 6; + pthread_attr_setschedparam(&a, ¶m); + pthread_attr_setschedpolicy(&a, currThreadPolicy); + ret = pthread_create(&newPthread, &a, ThreadFuncTest3, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + param.sched_priority = 0; + pthread_attr_setschedparam(&a, ¶m); + pthread_attr_setschedpolicy(&a, currThreadPolicy); + ret = pthread_create(&newPthread, &a, ThreadFuncTest3, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + param.sched_priority = currThreadPri - 1; + pthread_attr_setschedparam(&a, ¶m); + pthread_attr_setschedpolicy(&a, currThreadPolicy); + ret = pthread_create(&newPthread, &a, ThreadFuncTest3, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + param.sched_priority = currThreadPri; + pthread_attr_setschedparam(&a, ¶m); + pthread_attr_setschedpolicy(&a, currThreadPolicy); + ret = pthread_create(&newPthread, &a, ThreadFuncTest3, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + sleep(1); + + ret = pthread_mutex_unlock(&g_muxLock); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + SLEEP_AND_YIELD(1); + + ICUNIT_ASSERT_EQUAL(g_testCnt, 0, g_testCnt); + + pthread_mutex_destroy(&g_muxLock); + return 0; +} + +void ItTestPthreadMutex003(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_MUTEX_003", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_004.cpp b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_004.cpp new file mode 100644 index 00000000..a22b7020 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_004.cpp @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_mutex_test.h" + +static pthread_mutex_t g_muxLock001; +static pthread_mutex_t g_muxLock002; +static pthread_mutex_t g_muxLock003; + +static const unsigned int THREAD_COUNT = 10; + +static int g_testInfo[3][10] = { 0 }; +static int g_testToCount001 = 0; +static int g_testBackCount001 = 0; +static int g_testToCount002 = 0; +static int g_testBackCount002 = 0; +static int g_testToCount003 = 0; +static int g_testBackCount003 = 0; + +static void *ThreadFuncTest3(void *a) +{ + int ret; + int tid = Gettid(); + pthread_t thread = pthread_self(); + + ret = pthread_detach(thread); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testInfo[2][g_testToCount003] = tid; // 2, max indx + g_testToCount003++; + + ret = pthread_mutex_lock(&g_muxLock003); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testInfo[2][g_testBackCount003], tid, tid, EXIT); // 2, max indx + g_testBackCount003++; + + ret = pthread_mutex_unlock(&g_muxLock003); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + +EXIT: + return nullptr; +} + +static void *ThreadFuncTest2(void *a) +{ + int ret; + int tid = Gettid(); + pthread_t thread = pthread_self(); + + ret = pthread_detach(thread); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testInfo[1][g_testToCount002] = tid; + g_testToCount002++; + + ret = pthread_mutex_lock(&g_muxLock002); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testInfo[1][g_testBackCount002], tid, tid, EXIT); + g_testBackCount002++; + + ret = pthread_mutex_unlock(&g_muxLock002); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + +EXIT: + return nullptr; +} + +static void *ThreadFuncTest1(void *a) +{ + int ret; + int tid = Gettid(); + ; + pthread_t thread = pthread_self(); + + ret = pthread_detach(thread); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testInfo[0][g_testToCount001] = tid; + g_testToCount001++; + + ret = pthread_mutex_lock(&g_muxLock001); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testInfo[0][g_testBackCount001], tid, tid, EXIT); + g_testBackCount001++; + + ret = pthread_mutex_unlock(&g_muxLock001); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + +EXIT: + return nullptr; +} + +static int Testcase(void) +{ + int ret; + pthread_t newPthread; + pthread_mutexattr_t mutex; + + pthread_mutexattr_settype(&mutex, PTHREAD_MUTEX_NORMAL); + pthread_mutex_init(&g_muxLock001, &mutex); + pthread_mutex_init(&g_muxLock002, &mutex); + pthread_mutex_init(&g_muxLock003, &mutex); + + g_testToCount001 = 0; + g_testBackCount001 = 0; + g_testToCount002 = 0; + g_testBackCount002 = 0; + g_testToCount003 = 0; + g_testBackCount003 = 0; + + ret = pthread_mutex_lock(&g_muxLock001); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&g_muxLock002); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&g_muxLock003); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + for (int count = 0; count < THREAD_COUNT; count++) { + ret = pthread_create(&newPthread, nullptr, ThreadFuncTest1, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + SLEEP_AND_YIELD(1); + } + + for (int count = 0; count < THREAD_COUNT; count++) { + ret = pthread_create(&newPthread, nullptr, ThreadFuncTest2, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + SLEEP_AND_YIELD(1); + } + + for (int count = 0; count < THREAD_COUNT; count++) { + ret = pthread_create(&newPthread, nullptr, ThreadFuncTest3, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + SLEEP_AND_YIELD(1); + } + + ret = pthread_mutex_unlock(&g_muxLock001); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + SLEEP_AND_YIELD(1); + + ret = pthread_mutex_unlock(&g_muxLock002); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + SLEEP_AND_YIELD(1); + + ret = pthread_mutex_unlock(&g_muxLock003); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + SLEEP_AND_YIELD(1); + + pthread_mutex_destroy(&g_muxLock001); + pthread_mutex_destroy(&g_muxLock002); + pthread_mutex_destroy(&g_muxLock003); + return 0; +} + +void ItTestPthreadMutex004(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_MUTEX_004", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_005.cpp b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_005.cpp new file mode 100644 index 00000000..b7f06350 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_005.cpp @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_mutex_test.h" + +static pthread_mutex_t g_muxLock001; +static pthread_mutex_t g_muxLock002; +static pthread_mutex_t g_muxLock003; + +static const unsigned int THREAD_COUNT = 10; + +static int g_testInfo[3][10] = { 0 }; +static int g_testToCount001 = 0; +static int g_testBackCount001 = 0; +static int g_testToCount002 = 0; +static int g_testBackCount002 = 0; +static int g_testToCount003 = 0; +static int g_testBackCount003 = 0; + +static void *ThreadFuncTest3(void *a) +{ + int ret; + int tid; + pthread_t thread = pthread_self(); + + ret = pthread_detach(thread); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testInfo[2][g_testToCount003] = Gettid(); // 2, max indx + g_testToCount003++; + + ret = pthread_mutex_lock(&g_muxLock003); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + tid = Gettid(); + ICUNIT_GOTO_EQUAL(g_testInfo[2][g_testBackCount003], tid, tid, EXIT); // 2, max indx + g_testBackCount003++; + + ret = pthread_mutex_unlock(&g_muxLock003); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + +EXIT: + return nullptr; +} + +static void *ThreadFuncTest2(void *a) +{ + int ret; + int tid; + pthread_t thread = pthread_self(); + + ret = pthread_detach(thread); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testInfo[1][g_testToCount002] = Gettid(); + g_testToCount002++; + + ret = pthread_mutex_lock(&g_muxLock002); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + tid = Gettid(); + ICUNIT_GOTO_EQUAL(g_testInfo[1][g_testBackCount002], tid, tid, EXIT); + g_testBackCount002++; + + ret = pthread_mutex_unlock(&g_muxLock002); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + +EXIT: + return nullptr; +} + +static void *ThreadFuncTest1(void *a) +{ + int ret; + int tid; + pthread_t thread = pthread_self(); + + ret = pthread_detach(thread); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testInfo[0][g_testToCount001] = Gettid(); + g_testToCount001++; + + ret = pthread_mutex_lock(&g_muxLock001); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + tid = Gettid(); + ICUNIT_GOTO_EQUAL(g_testInfo[0][g_testBackCount001], tid, tid, EXIT); + g_testBackCount001++; + + ret = pthread_mutex_unlock(&g_muxLock001); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + +EXIT: + return nullptr; +} + +static int Testcase(void) +{ + int ret; + pthread_t newPthread; + pthread_mutexattr_t mutex; + + pthread_mutexattr_settype(&mutex, PTHREAD_MUTEX_NORMAL); + pthread_mutex_init(&g_muxLock001, &mutex); + pthread_mutex_init(&g_muxLock002, &mutex); + pthread_mutex_init(&g_muxLock003, &mutex); + + g_testToCount001 = 0; + g_testBackCount001 = 0; + g_testToCount002 = 0; + g_testBackCount002 = 0; + g_testToCount003 = 0; + g_testBackCount003 = 0; + + ret = pthread_mutex_lock(&g_muxLock001); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&g_muxLock002); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&g_muxLock003); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + for (int count = 0; count < THREAD_COUNT; count++) { + ret = pthread_create(&newPthread, nullptr, ThreadFuncTest3, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + SLEEP_AND_YIELD(1); + } + + for (int count = 0; count < THREAD_COUNT; count++) { + ret = pthread_create(&newPthread, nullptr, ThreadFuncTest2, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + SLEEP_AND_YIELD(1); + } + + for (int count = 0; count < THREAD_COUNT; count++) { + ret = pthread_create(&newPthread, nullptr, ThreadFuncTest1, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + SLEEP_AND_YIELD(1); + } + + ret = pthread_mutex_unlock(&g_muxLock001); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + SLEEP_AND_YIELD(1); + ret = pthread_mutex_unlock(&g_muxLock002); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + SLEEP_AND_YIELD(1); + ret = pthread_mutex_unlock(&g_muxLock003); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + SLEEP_AND_YIELD(1); + + pthread_mutex_destroy(&g_muxLock001); + pthread_mutex_destroy(&g_muxLock002); + pthread_mutex_destroy(&g_muxLock003); + return 0; +} + +void ItTestPthreadMutex005(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_MUTEX_005", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_006.cpp b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_006.cpp new file mode 100644 index 00000000..79c47faa --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_006.cpp @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_mutex_test.h" + +static pthread_mutex_t g_mutexLock001; +static pthread_mutex_t g_mutexLock002; +static pthread_mutex_t g_mutexLock003; + +static const unsigned int THREAD_COUNT = 10; + +static int g_testInfo[3][10] = { 0 }; +static int g_testToCount001 = 0; +static int g_testBackCount001 = 0; +static int g_testToCount002 = 0; +static int g_testBackCount002 = 0; +static int g_testToCount003 = 0; +static int g_testBackCount003 = 0; + +static void *ThreadFuncTest3(void *a) +{ + int ret; + int tid = Gettid(); + pthread_t thread = pthread_self(); + + ret = pthread_detach(thread); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testInfo[2][g_testToCount003] = tid; // 2, max indx + g_testToCount003++; + + ret = pthread_mutex_lock(&g_mutexLock003); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testInfo[2][g_testBackCount003], tid, tid, EXIT); // 2, max indx + g_testBackCount003++; + + ret = pthread_mutex_unlock(&g_mutexLock003); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + +EXIT: + return nullptr; +} + +static void *ThreadFuncTest2(void *a) +{ + int ret; + int tid = Gettid(); + pthread_t thread = pthread_self(); + + ret = pthread_detach(thread); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testInfo[1][g_testToCount002] = tid; + g_testToCount002++; + + ret = pthread_mutex_lock(&g_mutexLock002); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testInfo[1][g_testBackCount002], tid, tid, EXIT); + g_testBackCount002++; + + ret = pthread_mutex_unlock(&g_mutexLock002); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + +EXIT: + return nullptr; +} + +static void *ThreadFuncTest1(void *a) +{ + int ret; + int tid = Gettid(); + pthread_t thread = pthread_self(); + + ret = pthread_detach(thread); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testInfo[0][g_testToCount001] = tid; + g_testToCount001++; + + ret = pthread_mutex_lock(&g_mutexLock001); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testInfo[0][g_testBackCount001], tid, tid, EXIT); + g_testBackCount001++; + + ret = pthread_mutex_unlock(&g_mutexLock001); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + +EXIT: +return nullptr; +} + +static int Testcase(void) +{ + int ret; + pthread_t newPthread; + pthread_mutexattr_t mutex; + pthread_mutexattr_settype(&mutex, PTHREAD_MUTEX_NORMAL); + pthread_mutex_init(&g_mutexLock001, &mutex); + pthread_mutex_init(&g_mutexLock002, &mutex); + pthread_mutex_init(&g_mutexLock003, &mutex); + + g_testToCount001 = 0; + g_testBackCount001 = 0; + g_testToCount002 = 0; + g_testBackCount002 = 0; + g_testToCount003 = 0; + g_testBackCount003 = 0; + + ret = pthread_mutex_lock(&g_mutexLock001); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&g_mutexLock002); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&g_mutexLock003); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + for (int count = 0; count < THREAD_COUNT; count++) { + ret = pthread_create(&newPthread, nullptr, ThreadFuncTest1, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + SLEEP_AND_YIELD(1); + } + + for (int count = 0; count < THREAD_COUNT; count++) { + ret = pthread_create(&newPthread, nullptr, ThreadFuncTest3, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + SLEEP_AND_YIELD(1); + } + + for (int count = 0; count < THREAD_COUNT; count++) { + ret = pthread_create(&newPthread, nullptr, ThreadFuncTest2, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + SLEEP_AND_YIELD(1); + } + + ret = pthread_mutex_unlock(&g_mutexLock001); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + SLEEP_AND_YIELD(1); + ret = pthread_mutex_unlock(&g_mutexLock002); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + SLEEP_AND_YIELD(1); + ret = pthread_mutex_unlock(&g_mutexLock003); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + SLEEP_AND_YIELD(1); + + pthread_mutex_destroy(&g_mutexLock001); + pthread_mutex_destroy(&g_mutexLock002); + pthread_mutex_destroy(&g_mutexLock003); + return 0; +} + +void ItTestPthreadMutex006(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_MUTEX_006", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_007.cpp b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_007.cpp new file mode 100644 index 00000000..b3129b80 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_007.cpp @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_mutex_test.h" + +static pthread_mutex_t g_muxLock001; +static pthread_mutex_t g_muxLock002; +static pthread_mutex_t g_muxLock003; + +static const unsigned int TEST_COUNT = 1; +static volatile int g_testToCount001 = 0; +static volatile int g_testToCount002 = 0; +static volatile int g_testToCount003 = 0; + +static void *ThreadFuncTest3(void *a) +{ + int ret; + pthread_t thread = pthread_self(); + struct sched_param param = { 0 }; + struct timespec time; + struct timeval timeVal = { 0 }; + + ret = pthread_detach(thread); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + gettimeofday(&timeVal, nullptr); + + time.tv_sec = timeVal.tv_sec + 10; // 10, for test + time.tv_nsec = timeVal.tv_usec + 0; + + ret = pthread_mutex_timedlock(&g_muxLock003, &time); + ICUNIT_GOTO_EQUAL(ret, ETIMEDOUT, ret, EXIT); + + g_testToCount003++; + + while (g_testToCount002 == 0) { + SLEEP_AND_YIELD(2); // 2, delay enough time + } + + ret = pthread_mutex_unlock(&g_muxLock003); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + return nullptr; + +EXIT: + g_testToCount003 = -1; + return nullptr; +} + +static void *ThreadFuncTest2(void *a) +{ + int ret; + pthread_t thread = pthread_self(); + struct timespec time; + struct timeval timeVal = { 0 }; + + ret = pthread_detach(thread); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + gettimeofday(&timeVal, nullptr); + + time.tv_sec = timeVal.tv_sec + 5; // 5, for test + time.tv_nsec = timeVal.tv_usec + 0; + + ret = pthread_mutex_timedlock(&g_muxLock002, &time); + ICUNIT_GOTO_EQUAL(ret, ETIMEDOUT, ret, EXIT); + + g_testToCount002++; + + while (g_testToCount001 == 0) { + SLEEP_AND_YIELD(2); // 2, delay enough time + } + + ret = pthread_mutex_unlock(&g_muxLock002); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + return nullptr; + +EXIT: + g_testToCount002 = -1; + return nullptr; +} + +static void *ThreadFuncTest1(void *a) +{ + int ret; + pthread_t thread = pthread_self(); + struct timespec time; + struct timeval timeVal = { 0 }; + + ret = pthread_detach(thread); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + gettimeofday(&timeVal, nullptr); + + time.tv_sec = timeVal.tv_sec + 2; // 2, for test + time.tv_nsec = timeVal.tv_usec + 0; + + ret = pthread_mutex_timedlock(&g_muxLock001, &time); + ICUNIT_GOTO_EQUAL(ret, ETIMEDOUT, ret, EXIT); + + g_testToCount001++; + + ret = pthread_mutex_unlock(&g_muxLock001); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + return nullptr; + +EXIT: + g_testToCount001 = -1; + return nullptr; +} + +static int Testcase(void) +{ + int ret; + pthread_t newPthread; + pthread_mutexattr_t mutex = { 0 }; + int index = TEST_COUNT; + + while (index) { + pthread_mutexattr_settype(&mutex, PTHREAD_MUTEX_NORMAL); + pthread_mutex_init(&g_muxLock001, &mutex); + pthread_mutex_init(&g_muxLock002, &mutex); + pthread_mutex_init(&g_muxLock003, &mutex); + + g_testToCount001 = 0; + g_testToCount002 = 0; + g_testToCount003 = 0; + + ret = pthread_mutex_lock(&g_muxLock001); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&g_muxLock002); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&g_muxLock003); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newPthread, nullptr, ThreadFuncTest1, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newPthread, nullptr, ThreadFuncTest2, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newPthread, nullptr, ThreadFuncTest3, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + while (g_testToCount001 == 0 || g_testToCount002 == 0 || g_testToCount003 == 0) { + } + + ICUNIT_ASSERT_NOT_EQUAL(g_testToCount001, -1, g_testToCount001); + ICUNIT_ASSERT_NOT_EQUAL(g_testToCount002, -1, g_testToCount002); + ICUNIT_ASSERT_NOT_EQUAL(g_testToCount003, -1, g_testToCount003); + + ret = pthread_mutex_unlock(&g_muxLock001); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&g_muxLock002); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&g_muxLock003); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + index--; + + SLEEP_AND_YIELD(2); // 2, delay enouge time + } + + pthread_mutex_destroy(&g_muxLock001); + pthread_mutex_destroy(&g_muxLock002); + pthread_mutex_destroy(&g_muxLock003); + return 0; +} + +void ItTestPthreadMutex007(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_MUTEX_007", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_008.cpp b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_008.cpp new file mode 100644 index 00000000..c827e21f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_008.cpp @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_mutex_test.h" + +static pthread_mutex_t g_muxLock001; + +static const unsigned int TEST_COUNT = 1; +static volatile int g_testToCount001 = 0; +static volatile int g_testToCount002 = 0; +static volatile int g_testToCount003 = 0; + +static void *ThreadFuncTest3(void *a) +{ + int ret; + pthread_t thread = pthread_self(); + struct timespec time; + struct timeval timeVal = { 0 }; + + ret = pthread_detach(thread); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + gettimeofday(&timeVal, nullptr); + + time.tv_sec = timeVal.tv_sec + 15; // 15 + time.tv_nsec = timeVal.tv_usec + 0; + + ret = pthread_mutex_timedlock(&g_muxLock001, &time); + ICUNIT_GOTO_EQUAL(ret, ETIMEDOUT, ret, EXIT); + + g_testToCount003++; + + return nullptr; +EXIT: + g_testToCount003 = -1; + return nullptr; +} + +static void *ThreadFuncTest2(void *a) +{ + int ret; + pthread_t thread = pthread_self(); + struct timespec time; + struct timeval timeVal = { 0 }; + + ret = pthread_detach(thread); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + gettimeofday(&timeVal, nullptr); + + time.tv_sec = timeVal.tv_sec + 10; // 10 + time.tv_nsec = timeVal.tv_usec + 0; + + ret = pthread_mutex_timedlock(&g_muxLock001, &time); + ICUNIT_GOTO_EQUAL(ret, ETIMEDOUT, ret, EXIT); + + g_testToCount002++; + + return nullptr; + +EXIT: + g_testToCount002 = -1; + return nullptr; +} + +static void *ThreadFuncTest1(void *a) +{ + int ret; + pthread_t thread = pthread_self(); + struct timespec time; + struct timeval timeVal = { 0 }; + + ret = pthread_detach(thread); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + gettimeofday(&timeVal, nullptr); + + time.tv_sec = timeVal.tv_sec + 5; // 5 + time.tv_nsec = timeVal.tv_usec + 0; + + ret = pthread_mutex_timedlock(&g_muxLock001, &time); + ICUNIT_GOTO_EQUAL(ret, ETIMEDOUT, ret, EXIT); + + g_testToCount001++; + + return nullptr; +EXIT: + g_testToCount001 = -1; + return nullptr; +} + +static int Testcase(void) +{ + int ret; + pthread_t newPthread; + pthread_mutexattr_t mutex; + int index = TEST_COUNT; + + while (index) { + pthread_mutexattr_settype(&mutex, PTHREAD_MUTEX_NORMAL); + pthread_mutex_init(&g_muxLock001, &mutex); + + g_testToCount001 = 0; + g_testToCount002 = 0; + g_testToCount003 = 0; + + ret = pthread_mutex_lock(&g_muxLock001); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newPthread, nullptr, ThreadFuncTest1, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newPthread, nullptr, ThreadFuncTest2, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newPthread, nullptr, ThreadFuncTest3, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + while (g_testToCount001 == 0 || g_testToCount002 == 0 || g_testToCount003 == 0) { + } + + ret = pthread_mutex_unlock(&g_muxLock001); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + index--; + + SLEEP_AND_YIELD(2); // 2, delay enouge time + + ICUNIT_ASSERT_NOT_EQUAL(g_testToCount001, -1, g_testToCount001); + ICUNIT_ASSERT_NOT_EQUAL(g_testToCount002, -1, g_testToCount002); + ICUNIT_ASSERT_NOT_EQUAL(g_testToCount003, -1, g_testToCount003); + } + + pthread_mutex_destroy(&g_muxLock001); + return 0; +} + +void ItTestPthreadMutex008(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_MUTEX_008", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_009.cpp b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_009.cpp new file mode 100644 index 00000000..f63ad01d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_009.cpp @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_mutex_test.h" + + +static pthread_mutex_t g_muxLock; + +static void *TaskF01(void *arg) +{ + unsigned int ret; + ret = pthread_mutex_trylock(&g_muxLock); + ICUNIT_TRACK_EQUAL(ret, EBUSY, ret); + + g_testCount++; + + ret = pthread_mutex_lock(&g_muxLock); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&g_muxLock); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + g_testCount++; + + return nullptr; +} + +static unsigned int TestCase(void) +{ + unsigned int ret; + pthread_t newThread; + pthread_attr_t attr; + pthread_mutexattr_t mutexAttr; + struct sched_param sp; + + g_testCount = 0; + + pthread_mutexattr_init(&mutexAttr); + pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_ERRORCHECK); + + ret = pthread_mutex_init(&g_muxLock, &mutexAttr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&g_muxLock); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + sp.sched_priority = 4; // 4, Set the priority according to the task purpose,a smaller number means a higher priority. + ret = pthread_attr_setschedparam(&attr, &sp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + ret = pthread_create(&newThread, &attr, TaskF01, nullptr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LosTaskDelay(5); // 5, delay enouge time + ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount); + + ret = pthread_mutex_unlock(&g_muxLock); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + +#ifdef LOSCFG_USER_TEST_SMP + LosTaskDelay(5); // 5, delay enouge time +#endif + ICUNIT_ASSERT_EQUAL(g_testCount, 2, g_testCount); // 2,The expected value + + ret = pthread_mutex_lock(&g_muxLock); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&g_muxLock); + ICUNIT_ASSERT_EQUAL(ret, EDEADLK, ret); + + ret = pthread_mutex_lock(&g_muxLock); + ICUNIT_ASSERT_EQUAL(ret, EDEADLK, ret); + + ret = pthread_mutex_unlock(&g_muxLock); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&g_muxLock); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&g_muxLock); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&g_muxLock); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newThread, nullptr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return 0; +} + +void ItTestPthreadMutex009(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_MUTEX_009", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_010.cpp b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_010.cpp new file mode 100644 index 00000000..040bc0fb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_010.cpp @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_mutex_test.h" + + +static pthread_mutex_t g_mutexLock001; +static pthread_mutex_t g_mutexLock002; + +static void *TaskF01(void *arg) +{ + unsigned int ret; + ret = pthread_mutex_lock(&g_mutexLock001); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&g_mutexLock001); + ICUNIT_TRACK_EQUAL(ret, 0, ret); + + return nullptr; +} + +static unsigned int TestCase(void) +{ + unsigned int ret; + pthread_t newThread; + pthread_attr_t attr; + pthread_mutexattr_t mutexAttr; + struct sched_param sp; + + g_testCount = 0; + + pthread_mutexattr_init(&mutexAttr); + + pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_ERRORCHECK); + + ret = pthread_mutex_init(&g_mutexLock001, &mutexAttr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_init(&g_mutexLock002, nullptr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&g_mutexLock001); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&g_mutexLock001); + ICUNIT_ASSERT_EQUAL(ret, EDEADLK, ret); + + ret = pthread_mutex_unlock(&g_mutexLock001); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_init(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + sp.sched_priority = 4; // 4, Set the priority according to the task purpose,a smaller number means a higher priority. + ret = pthread_attr_setschedparam(&attr, &sp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + ret = pthread_create(&newThread, &attr, TaskF01, nullptr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + LosTaskDelay(5); // 5, delay enouge time + + ret = pthread_mutex_destroy(&g_mutexLock001); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&g_mutexLock001); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&g_mutexLock001); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&g_mutexLock001); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&g_mutexLock002); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newThread, nullptr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_attr_destroy(&attr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return 0; +} + +void ItTestPthreadMutex010(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_MUTEX_010", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_011.cpp b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_011.cpp new file mode 100644 index 00000000..a79521f3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_011.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_mutex_test.h" + + +static unsigned int TestCase(void) +{ + unsigned int ret; + pthread_mutexattr_t mutexAttr; + pthread_mutex_t mutex; + + pthread_mutexattr_init(&mutexAttr); + + pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_ERRORCHECK); + + ret = pthread_mutex_init(&mutex, &mutexAttr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, EDEADLK, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return 0; +} + +void ItTestPthreadMutex011(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_MUTEX_011", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_012.cpp b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_012.cpp new file mode 100644 index 00000000..a3ffda5a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_012.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_mutex_test.h" + + +static unsigned int TestCase(void) +{ + int ret; + pthread_mutex_t mutex; + pthread_mutexattr_t mutexAttr; + + pthread_mutexattr_init(&mutexAttr); + pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_ERRORCHECK); + + ret = pthread_mutex_init(&mutex, &mutexAttr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, EDEADLK, ret); + + ret = pthread_mutex_trylock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, EBUSY, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return 0; +} + +void ItTestPthreadMutex012(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_MUTEX_012", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_013.cpp b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_013.cpp new file mode 100644 index 00000000..68a9a050 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_013.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_mutex_test.h" + + +static unsigned int TestCase(void) +{ + int ret; + pthread_mutex_t mutex; + pthread_mutexattr_t mutexAttr; + + pthread_mutexattr_init(&mutexAttr); + pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_RECURSIVE); + + ret = pthread_mutex_init(&mutex, &mutexAttr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_trylock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return 0; +} + +void ItTestPthreadMutex013(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_MUTEX_013", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_014.cpp b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_014.cpp new file mode 100644 index 00000000..47ef4fe3 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_014.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_mutex_test.h" + + +static UINT32 TestCase(VOID) +{ + int ret; + pthread_mutex_t mutex; + pthread_mutexattr_t ma; + + ret = pthread_mutexattr_init(&ma); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_RECURSIVE); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_init(&mutex, &ma); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutexattr_destroy(&ma); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + + return 0; +} + +void ItTestPthreadMutex014(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_MUTEX_014", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_015.cpp b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_015.cpp new file mode 100644 index 00000000..bfe38e7d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_015.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_mutex_test.h" + + +static unsigned int TestCase(void) +{ + int ret; + pthread_mutex_t mutex; + pthread_mutexattr_t mutexAttr; + + pthread_mutexattr_init(&mutexAttr); + pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_RECURSIVE); + + ret = pthread_mutex_init(&mutex, &mutexAttr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_trylock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return 0; +} + +void ItTestPthreadMutex015(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_MUTEX_015", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_016.cpp b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_016.cpp new file mode 100644 index 00000000..84117e85 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_016.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_mutex_test.h" + + +static unsigned int TestCase(void) +{ + int ret; + pthread_mutex_t mutex; + pthread_mutexattr_t mutexAttr; + + pthread_mutexattr_init(&mutexAttr); + pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_RECURSIVE); + ret = pthread_mutex_init(&mutex, &mutexAttr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_lock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_unlock(&mutex); + ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + + ret = pthread_mutex_destroy(&mutex); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + return 0; +} + +void ItTestPthreadMutex016(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_MUTEX_016", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_017.cpp b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_017.cpp new file mode 100644 index 00000000..def2bfa2 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_017.cpp @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_mutex_test.h" + +static pthread_mutex_t g_mutexLock; + +static int g_testToCount = 0; +static int g_testBackCount = 0; + +static void *ThreadFuncTest3(void *a) +{ + int ret; + pthread_t thread = pthread_self(); + + ret = pthread_detach(thread); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testToCount++; + ret = pthread_mutex_lock(&g_mutexLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testToCount++; + ret = pthread_mutex_unlock(&g_mutexLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + +EXIT: + return nullptr; +} + +static void *ThreadFuncTest2(void *a) +{ + int ret; + + g_testBackCount++; + ret = pthread_mutex_lock(&g_mutexLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testBackCount++; + ret = pthread_mutex_unlock(&g_mutexLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + +EXIT: + return nullptr; +} + +static int TestCase(void) +{ + struct sched_param param = { 0 }; + int ret; + int currThreadPri, currThreadPolicy; + pthread_attr_t a = { 0 }; + pthread_t newPthread; + pthread_mutexattr_t mutex; + pthread_mutexattr_settype(&mutex, PTHREAD_MUTEX_NORMAL); + pthread_mutex_init(&g_mutexLock, &mutex); + + g_testToCount = 0; + g_testBackCount = 0; + + SLEEP_AND_YIELD(1); + + ret = pthread_mutex_lock(&g_mutexLock); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_getschedparam(pthread_self(), &currThreadPolicy, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + currThreadPri = param.sched_priority; + + // 2, Set the priority according to the task purpose,a smaller number means a higher priority. + param.sched_priority = currThreadPri - 2; + pthread_attr_init(&a); + pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED); + pthread_attr_setschedparam(&a, ¶m); + pthread_attr_setschedpolicy(&a, currThreadPolicy); + ret = pthread_create(&newPthread, &a, ThreadFuncTest3, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + SLEEP_AND_YIELD(5); // 5, delay enouge time + + ICUNIT_ASSERT_EQUAL(g_testToCount, 1, g_testToCount); + + ret = pthread_create(&newPthread, nullptr, ThreadFuncTest2, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + SLEEP_AND_YIELD(5); // 5, delay enouge time + + ICUNIT_ASSERT_EQUAL(g_testBackCount, 1, g_testBackCount); + + ret = pthread_mutex_unlock(&g_mutexLock); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_join(newPthread, nullptr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ICUNIT_ASSERT_EQUAL(g_testBackCount, 2, g_testBackCount); // 2,The expected value + ICUNIT_ASSERT_EQUAL(g_testToCount, 2, g_testToCount); // 2,The expected value + + pthread_mutex_destroy(&g_mutexLock); + return 0; +} + +void ItTestPthreadMutex017(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_MUTEX_017", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_019.cpp b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_019.cpp new file mode 100644 index 00000000..05fdb6fa --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_019.cpp @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_mutex_test.h" + +static pthread_mutex_t g_muxLock001; +static pthread_mutex_t g_muxLock002; +static pthread_mutex_t g_muxLock003; + +static const unsigned int TEST_COUNT = 10; +static const unsigned int NEW_THREAD_COUNT = 10; + +static volatile int g_testToCount001 = 0; +static volatile int g_testToCount002 = 0; +static volatile int g_testToCount003 = 0; + +static void *ThreadFuncTest2(void *a) +{ + int ret; + pthread_t thread = pthread_self(); + + ret = pthread_detach(thread); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_mutex_lock(&g_muxLock001); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_mutex_unlock(&g_muxLock001); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testToCount002 = 1; + + return nullptr; + +EXIT: + g_testToCount002 = -1; + return nullptr; +} + +static void *ThreadFuncTest1(void *a) +{ + int ret; + struct timespec time; + struct timeval timeVal = { 0 }; + + gettimeofday(&timeVal, nullptr); + + if(timeVal.tv_usec + 100000 >= 1000000) { // 100000us, delay time; 1000000us, compare + time.tv_sec = timeVal.tv_sec + 1; + time.tv_nsec = (timeVal.tv_usec + 100000 - 1000000) * 1000; // 100000, delaytime; 1000, us to ns; 1000000us=1s; + } else { + time.tv_sec = timeVal.tv_sec + 0; + time.tv_nsec = (timeVal.tv_usec + 100000) * 1000; // 1000, 100000us to ns + } + + ret = pthread_mutex_timedlock(&g_muxLock001, &time); + ICUNIT_GOTO_EQUAL(ret, ETIMEDOUT, ret, EXIT); + + ICUNIT_GOTO_EQUAL(g_testToCount002, 1, g_testToCount002, EXIT); + + g_testToCount001++; + return nullptr; + +EXIT: + g_testToCount001 = -1; + return nullptr; +} + +/* futexList : + * 30(20) -> -1(-1) -> -1(-1) -> -1(-1) -> -1(-1) -> -1(-1) -> -1(-1) -> + * -1(-1) -> -1(-1) -> -1(-1) -> -1(-1) -> -1(-1) -> -1(-1) -> + * + */ +static int Testcase(void) +{ + struct sched_param param = { 0 }; + int ret; + int threadCount; + pthread_attr_t a = { 0 }; + pthread_t newPthread[10], newPthread1; + pthread_mutexattr_t mutex; + int index = TEST_COUNT; + int gCurrThreadPri, gCurrThreadPolicy; + struct timeval time = { 0 }; + struct timeval timeVal = { 0 }; + + ret = pthread_getschedparam(pthread_self(), &gCurrThreadPolicy, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, -ret); + + gCurrThreadPri = param.sched_priority; + + ret = pthread_attr_init(&a); + // 2, Set the priority according to the task purpose,a smaller number means a higher priority. + param.sched_priority = gCurrThreadPri + 2; + pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED); + pthread_attr_setschedparam(&a, ¶m); + + while (index) { + pthread_mutexattr_settype(&mutex, PTHREAD_MUTEX_NORMAL); + pthread_mutex_init(&g_muxLock001, &mutex); + + g_testToCount001 = 0; + g_testToCount002 = 0; + threadCount = 0; + + ret = pthread_mutex_lock(&g_muxLock001); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + while (threadCount < NEW_THREAD_COUNT) { + ret = pthread_create(&newPthread[threadCount], &a, ThreadFuncTest1, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + threadCount++; + } + + usleep(1000 * 10 * 7); // 1000, 10, 7 + + ret = pthread_create(&newPthread1, nullptr, ThreadFuncTest2, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + gettimeofday(&timeVal, nullptr); + while (1) { + gettimeofday(&time, nullptr); + if ((time.tv_sec - timeVal.tv_sec) >= 1) { + break; + } + } + + ret = pthread_mutex_unlock(&g_muxLock001); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + threadCount = 0; + while (threadCount < NEW_THREAD_COUNT) { + ret = pthread_join(newPthread[threadCount], nullptr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + threadCount++; + } + + ICUNIT_ASSERT_NOT_EQUAL(g_testToCount001, -1, g_testToCount001); + ICUNIT_ASSERT_NOT_EQUAL(g_testToCount002, -1, g_testToCount002); + ICUNIT_ASSERT_EQUAL(g_testToCount001, NEW_THREAD_COUNT, g_testToCount001); + + pthread_mutex_destroy(&g_muxLock003); + index--; + } + return 0; +} + +void ItTestPthreadMutex019(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_MUTEX_019", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_020.cpp b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_020.cpp new file mode 100644 index 00000000..0c1f334e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_020.cpp @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_mutex_test.h" + +static pthread_mutex_t g_muxLock001; +static pthread_mutex_t g_muxLock002; +static pthread_mutex_t g_muxLock003; + +static const unsigned int TEST_COUNT = 10; +static const unsigned int NEW_THREAD_COUNT = 10; + +static volatile int g_testToCount001 = 0; +static volatile int g_testToCount002 = 0; +static volatile int g_testToCount000 = 0; + +static void *ThreadFuncTest2(void *a) +{ + int ret; + pthread_t thread = pthread_self(); + + ret = pthread_detach(thread); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_mutex_lock(&g_muxLock001); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_mutex_unlock(&g_muxLock001); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testToCount002 = 1; + + return nullptr; + +EXIT: + g_testToCount002 = -1; + return nullptr; +} + +static void *ThreadFuncTest1(void *a) +{ + int ret; + + ret = pthread_mutex_lock(&g_muxLock001); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + while (g_testToCount002 != 1) { + if (g_testToCount002 == -1) { + return nullptr; + } + } + + ret = pthread_mutex_unlock(&g_muxLock001); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testToCount001++; + return nullptr; + +EXIT: + g_testToCount001 = -1; + return nullptr; +} + +static void *ThreadFuncTest0(void *a) +{ + int ret; + struct timespec time; + struct timeval timeVal = { 0 }; + + gettimeofday(&timeVal, nullptr); + + time.tv_sec = timeVal.tv_sec + 0; + time.tv_nsec = (timeVal.tv_usec + 1000 * 10 * 10) * 1000; // 1000, 10 ms to ns + + ret = pthread_mutex_timedlock(&g_muxLock001, &time); + + while (g_testToCount002 != 1) { + if (g_testToCount002 == -1) { + return nullptr; + } + } + + if (ret == 0) { + ret = pthread_mutex_unlock(&g_muxLock001); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + } + + g_testToCount000++; + return nullptr; + +EXIT: + g_testToCount000 = -1; + return nullptr; +} + +/* futexlist: + * 21(20) -> -1(-1) -> 28(22) -> 27(22) -> 26(22) -> 25(22) -> 24(22) -> 23(22) -> + * -1(-1) -> 28(22) -> 27(22) -> 26(22) -> 25(22) -> 24(22) -> 23(22) -> + * 27(22) -> 26(22) -> 25(22) -> 24(22) -> 23(22) -> + */ +static int Testcase(void) +{ + struct sched_param param = { 0 }; + int ret; + int threadCount; + pthread_attr_t a = { 0 }; + pthread_t newPthread[10], newPthread1; + pthread_mutexattr_t mutex; + int index = TEST_COUNT; + int gCurrThreadPri, gCurrThreadPolicy; + struct timeval time = { 0 }; + struct timeval timeVal = { 0 }; + + ret = pthread_getschedparam(pthread_self(), &gCurrThreadPolicy, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, -ret); + + gCurrThreadPri = param.sched_priority; + + ret = pthread_attr_init(&a); + // 2, Set the priority according to the task purpose,a smaller number means a higher priority. + param.sched_priority = gCurrThreadPri + 2; + pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED); + pthread_attr_setschedparam(&a, ¶m); + + while (index) { + pthread_mutexattr_settype(&mutex, PTHREAD_MUTEX_NORMAL); + pthread_mutex_init(&g_muxLock001, &mutex); + + g_testToCount001 = 0; + g_testToCount002 = 0; + g_testToCount000 = 0; + threadCount = 0; + + ret = pthread_mutex_lock(&g_muxLock001); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = pthread_create(&newPthread[threadCount], &a, ThreadFuncTest0, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + threadCount = 1; + ret = pthread_create(&newPthread[threadCount], &a, ThreadFuncTest0, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + threadCount = 2; // 2 + while (threadCount < NEW_THREAD_COUNT) { + ret = pthread_create(&newPthread[threadCount], &a, ThreadFuncTest1, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + threadCount++; + } + + usleep(1000 * 10 * 8); // 1000, 10, 8 + + ret = pthread_create(&newPthread1, nullptr, ThreadFuncTest2, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + gettimeofday(&timeVal, nullptr); + while (1) { + gettimeofday(&time, nullptr); + if ((time.tv_sec - timeVal.tv_sec) >= 1) { + break; + } + } + + ret = pthread_mutex_unlock(&g_muxLock001); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + threadCount = 0; + while (threadCount < NEW_THREAD_COUNT) { + ret = pthread_join(newPthread[threadCount], nullptr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + threadCount++; + } + + ICUNIT_ASSERT_NOT_EQUAL(g_testToCount001, -1, g_testToCount001); + ICUNIT_ASSERT_NOT_EQUAL(g_testToCount002, -1, g_testToCount002); + ICUNIT_ASSERT_EQUAL(g_testToCount001, NEW_THREAD_COUNT - 2, g_testToCount001); // 2, test value + + pthread_mutex_destroy(&g_muxLock003); + index--; + } + return 0; +} + +void ItTestPthreadMutex020(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_MUTEX_020", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_021.cpp b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_021.cpp new file mode 100644 index 00000000..4a515861 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_021.cpp @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_mutex_test.h" + +static pthread_mutex_t g_muxLock001; +static pthread_mutex_t g_muxLock002; +static pthread_mutex_t g_muxLock003; + +static const unsigned int TEST_COUNT = 10; +static const unsigned int NEW_THREAD_COUNT = 10; + +static volatile int g_testToCount001 = 0; +static volatile int g_testToCount002 = 0; +static volatile int g_testToCount000 = 0; + +static void *ThreadFuncTest2(void *a) +{ + int ret; + pthread_t thread = pthread_self(); + + ret = pthread_detach(thread); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_mutex_lock(&g_muxLock001); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_mutex_unlock(&g_muxLock001); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testToCount002 = 1; + + return nullptr; + +EXIT: + g_testToCount002 = -1; + return nullptr; +} + +static void *ThreadFuncTest1(void *a) +{ + int ret; + + ret = pthread_mutex_lock(&g_muxLock001); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + while (g_testToCount002 != 1) { + if (g_testToCount002 == -1) { + return nullptr; + } + } + + ret = pthread_mutex_unlock(&g_muxLock001); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testToCount001++; + return nullptr; + +EXIT: + g_testToCount001 = -1; + return nullptr; +} + +static void *ThreadFuncTest0(void *a) +{ + int ret; + struct timespec time; + struct timeval timeVal = { 0 }; + + gettimeofday(&timeVal, nullptr); + + time.tv_sec = timeVal.tv_sec + 0; + time.tv_nsec = (timeVal.tv_usec + 1000 * 10 * 10) * 1000; // 1000, 10 ms to ns + + ret = pthread_mutex_timedlock(&g_muxLock001, &time); + + while (g_testToCount002 != 1) { + if (g_testToCount002 == -1) { + return nullptr; + } + } + + if (ret == 0) { + ret = pthread_mutex_unlock(&g_muxLock001); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + } + + g_testToCount000++; + return nullptr; + +EXIT: + g_testToCount000 = -1; + return nullptr; +} + +/* futexlist: + * 21(20) -> -1(-1) -> 28(22) -> 27(22) -> 26(22) -> 25(22) -> 24(22) -> 23(22) -> + * -1(-1) -> 28(22) -> 27(22) -> 26(22) -> 25(22) -> 24(22) -> 23(22) -> + * 27(22) -> 26(22) -> 25(22) -> 24(22) -> 23(22) -> + */ +static int Testcase(void) +{ + struct sched_param param = { 0 }; + int ret; + int threadCount; + pthread_attr_t a = { 0 }; + pthread_t newPthread[10], newPthread1; + pthread_mutexattr_t mutex; + int index = TEST_COUNT; + int gCurrThreadPri, gCurrThreadPolicy; + struct timeval time = { 0 }; + struct timeval timeVal = { 0 }; + + ret = pthread_getschedparam(pthread_self(), &gCurrThreadPolicy, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, -ret); + + gCurrThreadPri = param.sched_priority; + + ret = pthread_attr_init(&a); + // 2, Set the priority according to the task purpose,a smaller number means a higher priority. + param.sched_priority = gCurrThreadPri + 2; + pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED); + pthread_attr_setschedparam(&a, ¶m); + + while (index) { + pthread_mutexattr_settype(&mutex, PTHREAD_MUTEX_NORMAL); + pthread_mutex_init(&g_muxLock001, &mutex); + + g_testToCount001 = 0; + g_testToCount002 = 0; + g_testToCount000 = 0; + threadCount = 0; + + ret = pthread_mutex_lock(&g_muxLock001); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + while (threadCount < NEW_THREAD_COUNT) { + if ((threadCount % 2) == 0) { // 2, for index + ret = pthread_create(&newPthread[threadCount], &a, ThreadFuncTest0, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + } else { + ret = pthread_create(&newPthread[threadCount], &a, ThreadFuncTest1, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + } + threadCount++; + } + + usleep(1000 * 10 * 8); // 1000, 10, 8 + + ret = pthread_create(&newPthread1, nullptr, ThreadFuncTest2, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + gettimeofday(&timeVal, nullptr); + while (1) { + gettimeofday(&time, nullptr); + if ((time.tv_sec - timeVal.tv_sec) >= 1) { + break; + } + } + + ret = pthread_mutex_unlock(&g_muxLock001); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + threadCount = 0; + while (threadCount < NEW_THREAD_COUNT) { + ret = pthread_join(newPthread[threadCount], nullptr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + threadCount++; + } + + ICUNIT_ASSERT_NOT_EQUAL(g_testToCount001, -1, g_testToCount001); + ICUNIT_ASSERT_NOT_EQUAL(g_testToCount002, -1, g_testToCount002); + ICUNIT_ASSERT_NOT_EQUAL(g_testToCount000, -1, g_testToCount000); + + pthread_mutex_destroy(&g_muxLock003); + index--; + } + return 0; +} + +void ItTestPthreadMutex021(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_MUTEX_021", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_022.cpp b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_022.cpp new file mode 100644 index 00000000..0ed49774 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/lock/mutex/smoke/pthread_mutex_test_022.cpp @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_mutex_test.h" + +static pthread_mutex_t g_muxLock001; +static pthread_mutex_t g_muxLock002; +static pthread_mutex_t g_muxLock003; + +static const unsigned int TEST_COUNT = 10; +static const unsigned int NEW_THREAD_COUNT = 10; + +static volatile int g_testToCount001 = 0; +static volatile int g_testToCount002 = 0; +static volatile int g_testToCount000 = 0; + +static void *ThreadFuncTest2(void *a) +{ + int ret; + pthread_t thread = pthread_self(); + + ret = pthread_detach(thread); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_mutex_lock(&g_muxLock001); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + ret = pthread_mutex_unlock(&g_muxLock001); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testToCount002 = 1; + + return nullptr; + +EXIT: + g_testToCount002 = -1; + return nullptr; +} + +static void *ThreadFuncTest1(void *a) +{ + int ret; + + ret = pthread_mutex_lock(&g_muxLock001); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + while (g_testToCount002 != 1) { + if (g_testToCount002 == -1) { + return nullptr; + } + } + + ret = pthread_mutex_unlock(&g_muxLock001); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_testToCount001++; + return nullptr; + +EXIT: + g_testToCount001 = -1; + return nullptr; +} + +static void *ThreadFuncTest0(void *a) +{ + int ret; + struct timespec time; + struct timeval timeVal = { 0 }; + + gettimeofday(&timeVal, nullptr); + + time.tv_sec = timeVal.tv_sec + 0; + time.tv_nsec = (timeVal.tv_usec + 1000 * 10 * 10) * 1000; // 1000, 10 ms to ns + + ret = pthread_mutex_timedlock(&g_muxLock001, &time); + + while (g_testToCount002 != 1) { + if (g_testToCount002 == -1) { + return nullptr; + } + } + + if (ret == 0) { + ret = pthread_mutex_unlock(&g_muxLock001); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + } + + g_testToCount000++; + return nullptr; + +EXIT: + g_testToCount000 = -1; + return nullptr; +} + +/* futexlist: + * 21(20) -> -1(-1) -> 28(22) -> 27(22) -> 26(22) -> 25(22) -> 24(22) -> 23(22) -> + * -1(-1) -> 28(22) -> 27(22) -> 26(22) -> 25(22) -> 24(22) -> 23(22) -> + * 27(22) -> 26(22) -> 25(22) -> 24(22) -> 23(22) -> + */ +static int Testcase(void) +{ + struct sched_param param = { 0 }; + int ret; + int threadCount; + pthread_attr_t a = { 0 }; + pthread_t newPthread[10], newPthread1; + pthread_mutexattr_t mutex; + int index = TEST_COUNT; + int gCurrThreadPri, gCurrThreadPolicy; + struct timeval time = { 0 }; + struct timeval timeVal = { 0 }; + + ret = pthread_getschedparam(pthread_self(), &gCurrThreadPolicy, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, -ret); + + gCurrThreadPri = param.sched_priority; + + ret = pthread_attr_init(&a); + // 2, Set the priority according to the task purpose,a smaller number means a higher priority. + param.sched_priority = gCurrThreadPri + 2; + pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED); + pthread_attr_setschedparam(&a, ¶m); + + while (index) { + pthread_mutexattr_settype(&mutex, PTHREAD_MUTEX_NORMAL); + pthread_mutex_init(&g_muxLock001, &mutex); + + g_testToCount001 = 0; + g_testToCount002 = 0; + g_testToCount000 = 0; + threadCount = 0; + + ret = pthread_mutex_lock(&g_muxLock001); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + while (threadCount < NEW_THREAD_COUNT) { + if ((threadCount % 2) == 0) { // 2, for index + ret = pthread_create(&newPthread[threadCount], &a, ThreadFuncTest1, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + } else { + ret = pthread_create(&newPthread[threadCount], &a, ThreadFuncTest0, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + } + threadCount++; + } + + usleep(1000 * 10 * 8); // 1000, 10, 8 + + ret = pthread_create(&newPthread1, nullptr, ThreadFuncTest2, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + gettimeofday(&timeVal, nullptr); + while (1) { + gettimeofday(&time, nullptr); + if ((time.tv_sec - timeVal.tv_sec) >= 1) { + break; + } + } + + ret = pthread_mutex_unlock(&g_muxLock001); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + threadCount = 0; + while (threadCount < NEW_THREAD_COUNT) { + ret = pthread_join(newPthread[threadCount], nullptr); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + threadCount++; + } + + ICUNIT_ASSERT_NOT_EQUAL(g_testToCount001, -1, g_testToCount001); + ICUNIT_ASSERT_NOT_EQUAL(g_testToCount002, -1, g_testToCount002); + ICUNIT_ASSERT_NOT_EQUAL(g_testToCount000, -1, g_testToCount000); + + pthread_mutex_destroy(&g_muxLock003); + index--; + } + return 0; +} + +void ItTestPthreadMutex022(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_MUTEX_022", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/lock/rwlock/config.gni b/src/kernel_liteos_a/testsuites/unittest/process/lock/rwlock/config.gni new file mode 100644 index 00000000..33b1e506 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/lock/rwlock/config.gni @@ -0,0 +1,43 @@ +# Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//build/lite/config/test.gni") +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +process_lock_rwlock_include_dirs = [ "$TEST_UNITTEST_DIR/process/lock/rwlock" ] + +process_lock_rwlock_sources_entry = + [ "$TEST_UNITTEST_DIR/process/lock/rwlock/process_rwlock_test.cpp" ] + +process_lock_rwlock_sources_smoke = [ + "$TEST_UNITTEST_DIR/process/lock/rwlock/smoke/pthread_rwlock_test_001.cpp", +] + +process_lock_rwlock_sources_full = [ + "$TEST_UNITTEST_DIR/process/lock/rwlock/full/pthread_rwlock_test_002.cpp", +] diff --git a/src/kernel_liteos_a/testsuites/unittest/process/lock/rwlock/full/pthread_rwlock_test_002.cpp b/src/kernel_liteos_a/testsuites/unittest/process/lock/rwlock/full/pthread_rwlock_test_002.cpp new file mode 100644 index 00000000..efff5610 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/lock/rwlock/full/pthread_rwlock_test_002.cpp @@ -0,0 +1,309 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_rwlock_test.h" +#include "string.h" + +static const int WRITE_THREAD_COUNT = 5; // 5, set w thread count. +static const int READ_THREAD_COUNT = 5; // 5, set read thread count. + +static const int READ_LOOP_COUNT = 10; // 10, set read loop count. +static pthread_rwlock_t g_rwlockLock; +static const int TEST_DATA_SIZE = 100000; // 100000, set test data size. +static int g_rwlockData[TEST_DATA_SIZE]; +static int g_rwlockMask; +static volatile int g_isWriting[WRITE_THREAD_COUNT]; +static volatile int g_isReading[READ_THREAD_COUNT]; +static volatile int g_isReadExit[READ_THREAD_COUNT]; +static volatile int g_isWriteExit[WRITE_THREAD_COUNT]; +static int g_writePar[WRITE_THREAD_COUNT]; +static int g_readPar[READ_THREAD_COUNT]; + +static void RwlockWait() +{ + int count; + int count1; + for (count = 0xFFFFFFF; count != 0; count--) { + } +} + +static int CheckReadThreadExit(void) +{ + int count = 0; + + for (int i = 0; i < READ_THREAD_COUNT; i++) { + if (g_isReadExit[i] == 5) { // 5, set read exit data. + count++; + } + } + + if (count == READ_THREAD_COUNT) { + return 0; + } + + return 1; +} + +static int CheckWriteThreadExit(void) +{ + int count = 0; + + for (int i = 1; i < WRITE_THREAD_COUNT; i++) { + if (g_isWriteExit[i] == 6) { // 6, The current possible value of the variable. + count++; + } + } + + if (count == (WRITE_THREAD_COUNT - 1)) { + return 0; + } + + return 1; +} + +static void *ThreadReadFunc(void *a) +{ + int ret; + int count = 0; + pthread_t thread = pthread_self(); + int loop = READ_LOOP_COUNT; + int threadCount = *((int *)a); + + ret = pthread_detach(thread); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + while (loop > 0) { + SLEEP_AND_YIELD(1); + ret = pthread_rwlock_rdlock(&g_rwlockLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + g_isReading[threadCount] = 1; + + for (count = 0; count < TEST_DATA_SIZE; count++) { + ICUNIT_GOTO_EQUAL(g_rwlockData[count], g_rwlockMask, g_rwlockData[count], EXIT); + for (int index = 0; index < WRITE_THREAD_COUNT; index++) { + ICUNIT_GOTO_EQUAL(g_isWriting[index], 0, g_isWriting[index], EXIT); + } + } + + SLEEP_AND_YIELD(1); + g_isReading[threadCount] = 0; + + ret = pthread_rwlock_unlock(&g_rwlockLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + RwlockWait(); + loop--; + } + + g_isReadExit[threadCount] = 5; // 5, set read exit data. + +EXIT: + return nullptr; +} + +static void *ThreadWriteFunc1(void *a) +{ + int ret; + int count = 0; + int oldRwlockMask; + pthread_t thread = pthread_self(); + int threadCount = *((int *)a); + + ret = pthread_detach(thread); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + while (CheckReadThreadExit()) { + SLEEP_AND_YIELD(1); + ret = pthread_rwlock_wrlock(&g_rwlockLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_isWriting[threadCount] = 1; + + oldRwlockMask = g_rwlockMask; + + g_rwlockMask++; + + for (count = 0; count < TEST_DATA_SIZE; count++) { + ICUNIT_GOTO_EQUAL(g_rwlockData[count], oldRwlockMask, g_rwlockData[count], EXIT); + for (int i = 0; i < READ_THREAD_COUNT; i++) { + ICUNIT_GOTO_EQUAL(g_isReading[i], 0, g_isReading[i], EXIT); + } + g_rwlockData[count] = g_rwlockMask; + } + + SLEEP_AND_YIELD(1); + + g_isWriting[threadCount] = 0; + + ret = pthread_rwlock_unlock(&g_rwlockLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + SLEEP_AND_YIELD(1); + } + + g_isWriteExit[threadCount] = 6; // 6, The current possible value of the variable. + +EXIT: + return nullptr; +} + +static void *ThreadWriteFunc(void *a) +{ + int ret; + int count = 0; + int oldRwlockMask; + pthread_t thread = pthread_self(); + int threadCount = *((int *)a); + + while (CheckReadThreadExit() || CheckWriteThreadExit()) { + SLEEP_AND_YIELD(1); + ret = pthread_rwlock_wrlock(&g_rwlockLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_isWriting[threadCount] = 1; + + oldRwlockMask = g_rwlockMask; + + g_rwlockMask++; + + for (count = 0; count < TEST_DATA_SIZE; count++) { + ICUNIT_GOTO_EQUAL(g_rwlockData[count], oldRwlockMask, g_rwlockData[count], EXIT); + for (int i = 0; i < READ_THREAD_COUNT; i++) { + ICUNIT_GOTO_EQUAL(g_isReading[i], 0, g_isReading[i], EXIT); + } + g_rwlockData[count] = g_rwlockMask; + } + + SLEEP_AND_YIELD(1); + + g_isWriting[threadCount] = 0; + + ret = pthread_rwlock_unlock(&g_rwlockLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + SLEEP_AND_YIELD(1); + } + +EXIT: + return nullptr; +} + +static int PthreadRwlockTest(void) +{ + struct sched_param param = { 0 }; + int ret; + void *res = nullptr; + int count = 0; + pthread_attr_t a = { 0 }; + pthread_t thread = pthread_self(); + pthread_t newPthread, newPthread1; + pthread_rwlockattr_t rwlock; + int index = 0; + int curThreadPri, curThreadPolicy; + + ret = memset_s(static_cast(g_rwlockData), sizeof(int) * TEST_DATA_SIZE, 0, sizeof(int) * TEST_DATA_SIZE); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + g_rwlockMask = 0; + + pthread_rwlock_init(&g_rwlockLock, NULL); + + ret = pthread_getschedparam(pthread_self(), &curThreadPolicy, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, -ret); + + curThreadPri = param.sched_priority; + + while (index < 2) { // 2, Number of cycles. + ret = pthread_attr_init(&a); + pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED); + param.sched_priority = curThreadPri + 1; + pthread_attr_setschedparam(&a, ¶m); + + g_writePar[0] = 0; + ret = pthread_create(&newPthread1, &a, ThreadWriteFunc, &g_writePar[0]); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + count = 1; + while (count < WRITE_THREAD_COUNT) { + g_writePar[count] = count; + g_isWriting[count] = 0; + g_isWriteExit[count] = 0; + ret = pthread_create(&newPthread, &a, ThreadWriteFunc1, &g_writePar[count]); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + count++; + } + + count = 0; + while (count < READ_THREAD_COUNT) { + g_readPar[count] = count; + g_isReading[count] = 0; + g_isReadExit[count] = 0; + ret = pthread_create(&newPthread, &a, ThreadReadFunc, &g_readPar[count]); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + count++; + } + + ret = pthread_join(newPthread1, &res); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + index++; + } + + pthread_rwlock_destroy(&g_rwlockLock); + return 0; +} + +static int PthreadRwlockTest1(void) +{ + PthreadRwlockTest(); + exit(255); // 255, exit args. +} + +static int Testcase(void) +{ + int ret; + int status = 0; + pid_t pid = fork(); + ICUNIT_ASSERT_WITHIN_EQUAL(pid, 0, 100000, pid); // 100000, assert that function Result is equal to this. + if (pid == 0) { + PthreadRwlockTest1(); + exit(__LINE__); + } + + PthreadRwlockTest(); + + ret = wait(&status); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ICUNIT_ASSERT_EQUAL(status, 255, status); // 255, assert that function Result is equal to this. + return 0; +} + +void ItTestPthreadRwlock002(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_RWLOCK_002", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/lock/rwlock/it_rwlock_test.h b/src/kernel_liteos_a/testsuites/unittest/process/lock/rwlock/it_rwlock_test.h new file mode 100644 index 00000000..a1c90151 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/lock/rwlock/it_rwlock_test.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef IT_RWLOCK_TEST_H +#define IT_RWLOCK_TEST_H +#include "osTest.h" + +#define SLEEP_AND_YIELD(tick) usleep((tick)*10 * 1000) + +extern void ItTestPthreadRwlock001(void); +extern void ItTestPthreadRwlock002(void); +#endif diff --git a/src/kernel_liteos_a/testsuites/unittest/process/lock/rwlock/process_rwlock_test.cpp b/src/kernel_liteos_a/testsuites/unittest/process/lock/rwlock/process_rwlock_test.cpp new file mode 100644 index 00000000..f492d027 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/lock/rwlock/process_rwlock_test.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "stdio.h" +#include +#include +#include "it_rwlock_test.h" + +using namespace testing::ext; +namespace OHOS { +class ProcessRwlockTest : public testing::Test { +public: + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} +}; + +#if defined(LOSCFG_USER_TEST_SMOKE) +/* * + * @tc.name: it_test_pthread_rwlock_001 + * @tc.desc: function for ProcessRwlockTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessRwlockTest, ItTestPthreadRwlock001, TestSize.Level0) +{ + ItTestPthreadRwlock001(); +} +#endif + +#if defined(LOSCFG_USER_TEST_FULL) +/* * + * @tc.name: it_test_pthread_rwlock_002 + * @tc.desc: function for ProcessRwlockTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessRwlockTest, ItTestPthreadRwlock002, TestSize.Level0) +{ + ItTestPthreadRwlock002(); +} +#endif +} // namespace OHOS diff --git a/src/kernel_liteos_a/testsuites/unittest/process/lock/rwlock/smoke/pthread_rwlock_test_001.cpp b/src/kernel_liteos_a/testsuites/unittest/process/lock/rwlock/smoke/pthread_rwlock_test_001.cpp new file mode 100644 index 00000000..a4a19d75 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/lock/rwlock/smoke/pthread_rwlock_test_001.cpp @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_rwlock_test.h" +#include "string.h" + +static const int WRITE_THREAD_COUNT = 7; // 7, set w thread count. +static const int READ_THREAD_COUNT = 10; // 10, set read thread count. +static const int READ_LOOP_COUNT = 10; // 10, set read loop count. +static const int TEST_DATA_SIZE = 100000; // 100000, set test data size. + +static pthread_rwlock_t g_rwlockLock; + +static int g_rwlockData[TEST_DATA_SIZE]; +static int g_rwlockMask; +static volatile int g_isWriting[WRITE_THREAD_COUNT]; +static volatile int g_isReading[READ_THREAD_COUNT]; +static volatile int g_isReadExit[READ_THREAD_COUNT]; +static volatile int g_isWriteExit[WRITE_THREAD_COUNT]; +static int g_writePar[WRITE_THREAD_COUNT]; +static int g_readPar[READ_THREAD_COUNT]; + +static void RwlockWait() +{ + int count; + int count1; + for (count = 0xFFFFFFF; count != 0; count--) { + } +} + +static int CheckReadThreadExit(void) +{ + int count = 0; + + for (int i = 0; i < READ_THREAD_COUNT; i++) { + if (g_isReadExit[i] == 5) { // 5, set read exit data. + count++; + } + } + + if (count == READ_THREAD_COUNT) { + return 0; + } + + return 1; +} + +static int CheckWriteThreadExit(void) +{ + int count = 0; + + for (int i = 1; i < WRITE_THREAD_COUNT; i++) { + if (g_isWriteExit[i] == 6) { // 6, The current possible value of the variable. + count++; + } + } + + if (count == (WRITE_THREAD_COUNT - 1)) { + return 0; + } + + return 1; +} + +static void *ThreadReadFunc(void *a) +{ + int ret; + int count = 0; + pthread_t thread = pthread_self(); + int loop = READ_LOOP_COUNT; + int threadCount = *((int *)a); + + ret = pthread_detach(thread); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + while (loop > 0) { + ret = pthread_rwlock_rdlock(&g_rwlockLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + g_isReading[threadCount] = 1; + + for (count = 0; count < TEST_DATA_SIZE; count++) { + ICUNIT_GOTO_EQUAL(g_rwlockData[count], g_rwlockMask, g_rwlockData[count], EXIT); + for (int index = 0; index < WRITE_THREAD_COUNT; index++) { + ICUNIT_GOTO_EQUAL(g_isWriting[index], 0, g_isWriting[index], EXIT); + } + } + + SLEEP_AND_YIELD(1); + + g_isReading[threadCount] = 0; + + ret = pthread_rwlock_unlock(&g_rwlockLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + RwlockWait(); + loop--; + } + + g_isReadExit[threadCount] = 5; // 5, set read exit data. + +EXIT: + return nullptr; +} + +static void *ThreadWriteFunc1(void *a) +{ + int ret; + int count = 0; + int oldRwlockMask; + pthread_t thread = pthread_self(); + int threadCount = *((int *)a); + + ret = pthread_detach(thread); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + while (CheckReadThreadExit()) { + ret = pthread_rwlock_wrlock(&g_rwlockLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_isWriting[threadCount] = 1; + + oldRwlockMask = g_rwlockMask; + + g_rwlockMask++; + + for (count = 0; count < TEST_DATA_SIZE; count++) { + ICUNIT_GOTO_EQUAL(g_rwlockData[count], oldRwlockMask, g_rwlockData[count], EXIT); + for (int i = 0; i < READ_THREAD_COUNT; i++) { + ICUNIT_GOTO_EQUAL(g_isReading[i], 0, g_isReading[i], EXIT); + } + g_rwlockData[count] = g_rwlockMask; + } + + SLEEP_AND_YIELD(1); + + g_isWriting[threadCount] = 0; + + ret = pthread_rwlock_unlock(&g_rwlockLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + SLEEP_AND_YIELD(1); + } + + g_isWriteExit[threadCount] = 6; // 6, The current possible value of the variable. + +EXIT: + return nullptr; +} + +static void *ThreadWriteFunc(void *a) +{ + int ret; + int count = 0; + int oldRwlockMask; + pthread_t thread = pthread_self(); + int threadCount = *((int *)a); + + while (CheckReadThreadExit() || CheckWriteThreadExit()) { + ret = pthread_rwlock_wrlock(&g_rwlockLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_isWriting[threadCount] = 1; + + oldRwlockMask = g_rwlockMask; + + g_rwlockMask++; + + for (count = 0; count < TEST_DATA_SIZE; count++) { + ICUNIT_GOTO_EQUAL(g_rwlockData[count], oldRwlockMask, g_rwlockData[count], EXIT); + for (int i = 0; i < READ_THREAD_COUNT; i++) { + ICUNIT_GOTO_EQUAL(g_isReading[i], 0, g_isReading[i], EXIT); + } + g_rwlockData[count] = g_rwlockMask; + } + + SLEEP_AND_YIELD(1); + + g_isWriting[threadCount] = 0; + + ret = pthread_rwlock_unlock(&g_rwlockLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + SLEEP_AND_YIELD(1); + } + +EXIT: + return nullptr; +} + +static int Testcase(void) +{ + struct sched_param param = { 0 }; + int ret; + void *res = nullptr; + int count = 0; + pthread_attr_t a = { 0 }; + pthread_t thread = pthread_self(); + pthread_t newPthread, newPthread1; + pthread_rwlockattr_t rwlock; + int index = 0; + int curThreadPri, curThreadPolicy; + + ret = memset_s(static_cast(g_rwlockData), sizeof(int) * TEST_DATA_SIZE, 0, sizeof(int) * TEST_DATA_SIZE); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + g_rwlockMask = 0; + + pthread_rwlock_init(&g_rwlockLock, NULL); + + ret = pthread_getschedparam(pthread_self(), &curThreadPolicy, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, -ret); + + curThreadPri = param.sched_priority; + + while (index < 2) { // 2, Set the cycle number. + ret = pthread_attr_init(&a); + pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED); + param.sched_priority = curThreadPri + 1; + pthread_attr_setschedparam(&a, ¶m); + + g_writePar[0] = 0; + ret = pthread_create(&newPthread1, &a, ThreadWriteFunc, &g_writePar[0]); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + count = 1; + while (count < WRITE_THREAD_COUNT) { + g_writePar[count] = count; + ret = pthread_create(&newPthread, &a, ThreadWriteFunc1, &g_writePar[count]); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + g_isWriting[count] = 0; + g_isWriteExit[count] = 0; + count++; + } + + count = 0; + while (count < READ_THREAD_COUNT) { + g_readPar[count] = count; + ret = pthread_create(&newPthread, &a, ThreadReadFunc, &g_readPar[count]); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + g_isReading[count] = 0; + g_isReadExit[count] = 0; + count++; + } + + ret = pthread_join(newPthread1, &res); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + index++; + } + + pthread_rwlock_destroy(&g_rwlockLock); + return 0; +} + +void ItTestPthreadRwlock001(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_RWLOCK_001", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/lock/spinlock/config.gni b/src/kernel_liteos_a/testsuites/unittest/process/lock/spinlock/config.gni new file mode 100644 index 00000000..8798d873 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/lock/spinlock/config.gni @@ -0,0 +1,40 @@ +# Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//build/lite/config/test.gni") +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +process_lock_spinlock_include_dirs = + [ "$TEST_UNITTEST_DIR/process/lock/spinlock" ] + +process_lock_spinlock_sources_entry = + [ "$TEST_UNITTEST_DIR/process/lock/spinlock/process_spinlock_test.cpp" ] + +process_lock_spinlock_sources_smoke = [ "$TEST_UNITTEST_DIR/process/lock/spinlock/smoke/pthread_spinlock_test_001.cpp" ] + +process_lock_spinlock_sources_full = [] diff --git a/src/kernel_liteos_a/testsuites/unittest/process/lock/spinlock/it_spinlock_test.h b/src/kernel_liteos_a/testsuites/unittest/process/lock/spinlock/it_spinlock_test.h new file mode 100644 index 00000000..12e78126 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/lock/spinlock/it_spinlock_test.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef IT_SPINLOCK_TEST_H +#define IT_SPINLOCK_TEST_H +#include "osTest.h" + +#define SLEEP_AND_YIELD(tick) usleep((tick)*10 * 1000) + +extern void ItTestPthreadSpinlock001(void); + +#endif diff --git a/src/kernel_liteos_a/testsuites/unittest/process/lock/spinlock/process_spinlock_test.cpp b/src/kernel_liteos_a/testsuites/unittest/process/lock/spinlock/process_spinlock_test.cpp new file mode 100644 index 00000000..1d4005fe --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/lock/spinlock/process_spinlock_test.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "stdio.h" +#include +#include +#include "it_spinlock_test.h" + +using namespace testing::ext; +namespace OHOS { +class ProcessSpinlockTest : public testing::Test { +public: + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} +}; + +#if defined(LOSCFG_USER_TEST_SMOKE) +/* * + * @tc.name: it_test_pthread_spinlock_001 + * @tc.desc: function for ProcessSpinlockTest + * @tc.type: FUNC + */ +HWTEST_F(ProcessSpinlockTest, ItTestPthreadSpinlock001, TestSize.Level0) +{ + ItTestPthreadSpinlock001(); +} +#endif +} // namespace OHOS diff --git a/src/kernel_liteos_a/testsuites/unittest/process/lock/spinlock/smoke/pthread_spinlock_test_001.cpp b/src/kernel_liteos_a/testsuites/unittest/process/lock/spinlock/smoke/pthread_spinlock_test_001.cpp new file mode 100644 index 00000000..8e73e83d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/lock/spinlock/smoke/pthread_spinlock_test_001.cpp @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_spinlock_test.h" +#include "string.h" + +static const int WRITE_THREAD_COUNT = 2; // 2, set test count. +static const int TEST_LOOP_COUNT = 1; +static const int TEST_COUNT = 2; // 2, set write thread count. +static pthread_spinlock_t g_spinlockLock; + +static const int TEST_DATA_SIZE = 100000; // 100000, set test data size. +static int g_spinlockData[TEST_DATA_SIZE]; +static int g_spinlockMask; +static volatile int g_isWriting[WRITE_THREAD_COUNT]; +static volatile int g_isWriteExit[WRITE_THREAD_COUNT]; +static int g_writePar[WRITE_THREAD_COUNT]; + +static void *ThreadWriteFunc1(void *a) +{ + int ret; + int testCount = TEST_LOOP_COUNT; + int oldRwlockMask; + pthread_t thread = pthread_self(); + int threadCount = *((int *)a); + int count; + + ret = pthread_detach(thread); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + while (testCount > 0) { + ret = pthread_spin_lock(&g_spinlockLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_isWriting[threadCount] = 1; + + oldRwlockMask = g_spinlockMask; + + g_spinlockMask++; + + for (count = 0; count < TEST_DATA_SIZE; count++) { + ICUNIT_GOTO_EQUAL(g_spinlockData[count], oldRwlockMask, g_spinlockData[count], EXIT); + g_spinlockData[count] = g_spinlockMask; + } + + g_isWriting[threadCount] = 0; + + ret = pthread_spin_unlock(&g_spinlockLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + SLEEP_AND_YIELD(1); + testCount--; + } + + g_isWriteExit[threadCount] = 6; // 6, The current possible value of the variable. + +EXIT: + return nullptr; +} + +static void *ThreadWriteFunc(void *a) +{ + int ret; + int testCount = TEST_LOOP_COUNT; + int oldRwlockMask; + pthread_t thread = pthread_self(); + int threadCount = *((int *)a); + int count; + + while (testCount > 0) { + ret = pthread_spin_lock(&g_spinlockLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + g_isWriting[threadCount] = 1; + + oldRwlockMask = g_spinlockMask; + + g_spinlockMask++; + + for (count = 0; count < TEST_DATA_SIZE; count++) { + ICUNIT_GOTO_EQUAL(g_spinlockData[count], oldRwlockMask, g_spinlockData[count], EXIT); + g_spinlockData[count] = g_spinlockMask; + } + + g_isWriting[threadCount] = 0; + + ret = pthread_spin_unlock(&g_spinlockLock); + ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); + + SLEEP_AND_YIELD(1); + testCount--; + } + +EXIT: + return nullptr; +} + +static int Testcase(void) +{ + struct sched_param param = { 0 }; + int ret; + void *res = nullptr; + pthread_attr_t a = { 0 }; + pthread_t thread = pthread_self(); + pthread_t newPthread, newPthread1; + pthread_rwlockattr_t rwlock; + int index = 0; + int curThreadPri, curThreadPolicy; + + ret = memset_s(static_cast(g_spinlockData), sizeof(int) * TEST_DATA_SIZE, 0, sizeof(int) * TEST_DATA_SIZE); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + g_spinlockMask = 0; + + pthread_spin_init(&g_spinlockLock, 0); + + ret = pthread_getschedparam(pthread_self(), &curThreadPolicy, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, -ret); + + curThreadPri = param.sched_priority; + + while (index < TEST_COUNT) { + ret = pthread_attr_init(&a); + pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED); + param.sched_priority = curThreadPri + 1; + pthread_attr_setschedparam(&a, ¶m); + + g_writePar[0] = 0; + ret = pthread_create(&newPthread1, &a, ThreadWriteFunc, &g_writePar[0]); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + g_writePar[1] = 1; + ret = pthread_create(&newPthread, &a, ThreadWriteFunc1, &g_writePar[1]); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + g_isWriting[1] = 0; + g_isWriteExit[1] = 0; + + ret = pthread_join(newPthread1, &res); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + index++; + } + + pthread_spin_destroy(&g_spinlockLock); + + return 0; +} + +void ItTestPthreadSpinlock001(void) +{ + TEST_ADD_CASE("IT_POSIX_PTHREAD_SPINLOCK_001", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/BUILD.gn b/src/kernel_liteos_a/testsuites/unittest/process/plimits/BUILD.gn new file mode 100644 index 00000000..cdcf7a29 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/BUILD.gn @@ -0,0 +1,56 @@ +# Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("./config.gni") + +if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_LOW) { + unittest("liteos_a_process_plimits_unittest_door") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + include_dirs = common_include_dirs + sources = sources_entry + sources += sources_smoke + sources_full = [] + sources += sources_full + configs = [ "../..:public_config_for_door" ] + deps = [ "$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR:libsec_shared" ] + } +} + +if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_MIDDLE) { + unittest("liteos_a_process_plimits_unittest") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + include_dirs = common_include_dirs + sources = sources_entry + sources += sources_smoke + sources += sources_full + configs = [ "../..:public_config_for_all" ] + deps = [ "$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR:libsec_shared" ] + } +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/It_process_plimits.h b/src/kernel_liteos_a/testsuites/unittest/process/plimits/It_process_plimits.h new file mode 100644 index 00000000..7596c83a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/It_process_plimits.h @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _IT_PROCESS_PLIMITS_H +#define _IT_PROCESS_PLIMITS_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "osTest.h" + +#define MEM_PAGE_SIZE 4096 +#define MEM_SLEEP_TIME 5 +#define MEM_RESERVED_PAGE 2 +#define CHILD_FUNC_ARG (0x2088) +#define STACK_SIZE (1024 * 1024) +#define PROCESS_LIMIT_AMOUNT (64) +#define TEST_BUFFER_SIZE (512) +#define CPUP10S_INDEX (11) +#define CPUP1S_INDEX (12) +#define WAIT_CPUP_STABLE (7) +#define WAIT_CPUP_STABLE_FOR_100 (17) +#define STATISTIC_TIMES (11) +#define PERIOD_10_SEC_IN_US (10 * 1000 * 1000) +#define QUOTA_2_SEC_IN_US (2 * 1000 * 1000) +#define QUOTA_5_SEC_IN_US (5 * 1000 * 1000) +#define QUOTA_6_SEC_IN_US (6 * 1000 * 1000) +#define QUOTA_7_SEC_IN_US (7 * 1000 * 1000) +#define QUOTA_10_SEC_IN_US (10 * 1000 * 1000) +#define QUOTA_PERCENT_20 (20) +#define QUOTA_PERCENT_50 (50) +#define QUOTA_PERCENT_60 (60) +#define QUOTA_PERCENT_70 (70) +#define QUOTA_PERCENT_100 (100) +#define HARDWARE_CORE_AMOUNT (2) +#define TOLERANCE_ERROR (5) + +int WriteFile(const char *filepath, const char *buf); +int RmdirLimiterFile(std::string path); +int RmdirControlFile(std::string path); +int ReadFile(const char *filepath, char *buf); +int GetLine(char *buf, int count, int maxLen, char **array); +int RmdirTest (std::string path); +extern UINT32 LosCurTaskIDGet(); + +int ForkChilds(int num, int *pidArray); +int CreatePlimitGroup(const char* groupName, char *childPidFiles, + unsigned long long periodUs, unsigned long long quotaUs); +int AddPidIntoSchedLimiters(int num, int *pidArray, const char *procspath); +int WaitForCpupStable(int expectedCpupPercent); +double CalcCpupUsage(int childAmount, int *childPidArray, int expectedCpupPercent); +double CheckCpupUsage(double sumAllChildsCpup, int expectedCpupPercent); +int TerminateChildProcess(int *childPidArray, int childAmount, int sig); +double TestCpupInPlimit(int childAmount, const char* groupName, + unsigned long long periodUs, unsigned long long quotaUs, int expectedCpupPercent); +double TestCpupWithoutLimit(int childAmount, const char* groupName, int expectedCpupPercent); + +#if defined(LOSCFG_USER_TEST_SMOKE) +void ItProcessPlimits001(void); +void ItProcessPlimits002(void); +void ItProcessPlimits003(void); +void ItProcessPlimits004(void); +void ItProcessPlimits005(void); +void ItProcessPlimits006(void); +void ItProcessPlimits007(void); +void ItProcessPlimits008(void); +void ItProcessPlimitsMemory001(void); +void ItProcessPlimitsMemory002(void); +void ItProcessPlimitsPid001(void); +void ItProcessPlimitsPid002(void); +void ItProcessPlimitsPid003(void); +void ItProcessPlimitsPid004(void); +void ItProcessPlimitsPid005(void); +void ItProcessPlimitsPid006(void); +void ItProcessPlimitsSched001(VOID); +void ItProcessPlimitsSched002(VOID); +void ItProcessPlimitsSched003(VOID); +void ItProcessPlimitsSched004(VOID); +void ItProcessPlimitsDevices001(void); +void ItProcessPlimitsDevices002(void); +void ItProcessPlimitsDevices003(void); +void ItProcessPlimitsDevices004(void); +void ItProcessPlimitsDevices005(void); +void ItProcessPlimitsDevices006(void); +void ItProcessPlimitsDevices007(void); +void ItProcessPlimitsDevices008(void); +void ItProcessPlimitsDevices009(void); +void ItProcessPlimitsIpc002(void); +void ItProcessPlimitsIpc003(void); +void ItProcessPlimitsIpc004(void); +void ItProcessPlimitsIpc005(void); +void ItProcessPlimitsIpc006(void); +void ItProcessPlimitsIpc007(void); +void ItProcessPlimitsIpc008(void); +void ItProcessPlimitsIpc009(void); +void ItProcessPlimitsIpc010(void); +void ItProcessPlimitsIpc011(void); +void ItProcessPlimitsIpc012(void); +void ItProcessPlimitsIpc013(void); +#endif +#endif /* _IT_PROCESS_PLIMITS_H */ diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/config.gni b/src/kernel_liteos_a/testsuites/unittest/process/plimits/config.gni new file mode 100644 index 00000000..bba4b0aa --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/config.gni @@ -0,0 +1,101 @@ +# Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//build/lite/config/test.gni") +import("//kernel/liteos_a/liteos.gni") +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +common_include_dirs = [ + "$THIRDPARTY_GOOGLETEST_DIR/googletest/include", + "../../common/include", +] + +sources_entry = [ "../../common/osTest.cpp" ] + +sources_smoke = [] + +sources_full = [] + +process_plimits_include_dirs = [ "$TEST_UNITTEST_DIR/process/plimits" ] + +process_plimits_sources_entry = + [ "$TEST_UNITTEST_DIR/process/plimits/process_plimits_test.cpp" ] + +process_plimits_sources_smoke = [ + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_001.cpp", + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_002.cpp", + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_003.cpp", + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_004.cpp", + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_005.cpp", + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_006.cpp", + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_007.cpp", + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_008.cpp", + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_pid_001.cpp", + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_pid_002.cpp", + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_pid_003.cpp", + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_pid_004.cpp", + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_pid_005.cpp", + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_pid_006.cpp", + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_memory_001.cpp", + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_memory_002.cpp", + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_sched_001.cpp", + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_sched_002.cpp", + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_sched_003.cpp", + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_sched_004.cpp", + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_devices_001.cpp", + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_devices_002.cpp", + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_devices_003.cpp", + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_devices_004.cpp", + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_devices_005.cpp", + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_devices_006.cpp", + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_devices_007.cpp", + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_devices_008.cpp", + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_devices_009.cpp", + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_ipc_002.cpp", + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_ipc_003.cpp", + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_ipc_004.cpp", + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_ipc_005.cpp", + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_ipc_006.cpp", + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_ipc_007.cpp", + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_ipc_008.cpp", + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_ipc_009.cpp", + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_ipc_010.cpp", + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_ipc_011.cpp", + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_ipc_012.cpp", + "$TEST_UNITTEST_DIR/process/plimits/smoke/It_process_plimits_ipc_013.cpp", +] + +process_plimits_sources_full = [] + +# plimits module +if (LOSCFG_USER_TEST_PROCESS_PLIMITS == true) { + common_include_dirs += process_plimits_include_dirs + sources_entry += process_plimits_sources_entry + sources_smoke += process_plimits_sources_smoke + sources_full += process_plimits_sources_full +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/process_plimits_test.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/process_plimits_test.cpp new file mode 100644 index 00000000..a4ca09b9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/process_plimits_test.cpp @@ -0,0 +1,901 @@ +/* + + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "It_process_plimits.h" + +using namespace std; +using namespace testing::ext; +namespace OHOS { +class ProcessPlimitsTest : public testing::Test { +public: + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} + +protected: + virtual void SetUp(); + virtual void TearDown(); + +private: + inline bool IsFile(const std::string &file); + inline bool IsDir(const std::string &path); + inline bool IsSpecialDir(const std::string &path); +}; + +#if defined(LOSCFG_USER_TEST_SMOKE) +/** +* @tc.name: plimits_Test_001 +* @tc.desc: plimits function test case +* @tc.type: FUNC +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, ItProcessPlimits001, TestSize.Level0) +{ + ItProcessPlimits001(); +} + +/** +* @tc.name: plimits_Test_002 +* @tc.desc: plimits function test case +* @tc.type: FUNC +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, ItProcessPlimits002, TestSize.Level0) +{ + ItProcessPlimits002(); +} + +/** +* @tc.name: plimits_Test_003 +* @tc.desc: plimits function test case +* @tc.type: FUNC +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, ItProcessPlimits003, TestSize.Level0) +{ + ItProcessPlimits003(); +} + +/** +* @tc.name: plimits_Test_004 +* @tc.desc: plimits function test case +* @tc.type: FUNC +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, ItProcessPlimits004, TestSize.Level0) +{ + ItProcessPlimits004(); +} + +/** +* @tc.name: plimits_Test_005 +* @tc.desc: plimits function test case +* @tc.type: FUNC +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, ItProcessPlimits005, TestSize.Level0) +{ + ItProcessPlimits005(); +} + +/** +* @tc.name: plimits_Test_006 +* @tc.desc: plimits function test case +* @tc.type: FUNC +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, ItProcessPlimits006, TestSize.Level0) +{ + ItProcessPlimits006(); +} + +/** +* @tc.name: plimits_Test_007 +* @tc.desc: plimits function test case +* @tc.type: FUNC +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, ItProcessPlimits007, TestSize.Level0) +{ + ItProcessPlimits007(); +} + +/** +* @tc.name: plimits_Test_008 +* @tc.desc: plimits function test case +* @tc.type: FUNC +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, ItProcessPlimits008, TestSize.Level0) +{ + ItProcessPlimits008(); +} + +/** +* @tc.name: plimits_pid_Test_001 +* @tc.desc: pid plimit function test case +* @tc.type: FUNC +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, ItProcessPlimitsPid001, TestSize.Level0) +{ + ItProcessPlimitsPid001(); +} + +/** +* @tc.name: plimits_pid_Test_002 +* @tc.desc: pid plimit function test case +* @tc.type: FUNC +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, ItProcessPlimitsPid002, TestSize.Level0) +{ + ItProcessPlimitsPid002(); +} + +/** +* @tc.name: plimits_pid_Test_003 +* @tc.desc: pid plimit function test case +* @tc.type: FUNC +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, ItProcessPlimitsPid003, TestSize.Level0) +{ + ItProcessPlimitsPid003(); +} + +/** +* @tc.name: plimits_pid_Test_004 +* @tc.desc: pid plimit function test case +* @tc.type: FUNC +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, ItProcessPlimitsPid004, TestSize.Level0) +{ + ItProcessPlimitsPid004(); +} + +/** +* @tc.name: plimits_pid_Test_005 +* @tc.desc: pid plimit function test case +* @tc.type: FUNC +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, ItProcessPlimitsPid005, TestSize.Level0) +{ + ItProcessPlimitsPid005(); +} + +/** +* @tc.name: plimits_pid_Test_006 +* @tc.desc: pid plimit function test case +* @tc.type: FUNC +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, ItProcessPlimitsPid006, TestSize.Level0) +{ + ItProcessPlimitsPid006(); +} + +/** +* @tc.name: plimits_Mem_Test_001 +* @tc.desc: mem plimit function test case +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, ItProcessPlimitsMemory001, TestSize.Level0) +{ + ItProcessPlimitsMemory001(); +} + +/** +* @tc.name: plimits_Mem_Test_002 +* @tc.desc: mem plimit function test case +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, ItProcessPlimitsMemory002, TestSize.Level0) +{ + ItProcessPlimitsMemory002(); +} + +/** +* @tc.name: plimits_Dev_Test_001 +* @tc.desc: devices plimit function test case +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, ItProcessPlimitsDevices001, TestSize.Level0) +{ + ItProcessPlimitsDevices001(); +} + +/** +* @tc.name: plimits_Dev_Test_002 +* @tc.desc: devices plimit function test case +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, ItProcessPlimitsDevices002, TestSize.Level0) +{ + ItProcessPlimitsDevices002(); +} + +/** +* @tc.name: plimits_Dev_Test_003 +* @tc.desc: devices plimit function test case +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, ItProcessPlimitsDevices003, TestSize.Level0) +{ + ItProcessPlimitsDevices003(); +} + +/** +* @tc.name: plimits_Dev_Test_004 +* @tc.desc: devices plimit function test case +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, ItProcessPlimitsDevices004, TestSize.Level0) +{ + ItProcessPlimitsDevices004(); +} + +/** +* @tc.name: plimits_Dev_Test_005 +* @tc.desc: devices plimit function test case +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, ItProcessPlimitsDevices005, TestSize.Level0) +{ + ItProcessPlimitsDevices005(); +} + +/** +* @tc.name: plimits_Dev_Test_006 +* @tc.desc: devices plimit function test case +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, ItProcessPlimitsDevices006, TestSize.Level0) +{ + ItProcessPlimitsDevices006(); +} + +/** +* @tc.name: plimits_Dev_Test_007 +* @tc.desc: devices plimit function test case +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, ItProcessPlimitsDevices007, TestSize.Level0) +{ + ItProcessPlimitsDevices007(); +} + +/** +* @tc.name: plimits_Dev_Test_008 +* @tc.desc: devices plimit function test case +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, ItProcessPlimitsDevices008, TestSize.Level0) +{ + ItProcessPlimitsDevices008(); +} + +/** +* @tc.name: plimits_Dev_Test_009 +* @tc.desc: devices plimit function test case +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, ItProcessPlimitsDevices009, TestSize.Level0) +{ + ItProcessPlimitsDevices009(); +} + +/** +* @tc.name: plimits_Ipc_Test_002 +* @tc.desc: ipc plimit function test case +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, ItProcessPlimitsIpc002, TestSize.Level0) +{ + ItProcessPlimitsIpc002(); +} + +/** +* @tc.name: plimits_Ipc_Test_003 +* @tc.desc: ipc plimit function test case +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, ItProcessPlimitsIpc003, TestSize.Level0) +{ + ItProcessPlimitsIpc003(); +} + +/** +* @tc.name: plimits_Ipc_Test_004 +* @tc.desc: ipc plimit function test case +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, ItProcessPlimitsIpc004, TestSize.Level0) +{ + ItProcessPlimitsIpc004(); +} + +/** +* @tc.name: plimits_Ipc_Test_005 +* @tc.desc: ipc plimit function test case +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, ItProcessPlimitsIpc005, TestSize.Level0) +{ + ItProcessPlimitsIpc005(); +} + +/** +* @tc.name: plimits_Ipc_Test_006 +* @tc.desc: ipc plimit function test case +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, ItProcessPlimitsIpc006, TestSize.Level0) +{ + ItProcessPlimitsIpc006(); +} + +/** +* @tc.name: plimits_Ipc_Test_007 +* @tc.desc: ipc plimit function test case +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, ItProcessPlimitsIpc007, TestSize.Level0) +{ + ItProcessPlimitsIpc007(); +} + +/** +* @tc.name: plimits_Ipc_Test_008 +* @tc.desc: ipc plimit function test case +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, ItProcessPlimitsIpc008, TestSize.Level0) +{ + ItProcessPlimitsIpc008(); +} + +/** +* @tc.name: plimits_Ipc_Test_009 +* @tc.desc: ipc plimit function test case +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, ItProcessPlimitsIpc009, TestSize.Level0) +{ + ItProcessPlimitsIpc009(); +} + +/** +* @tc.name: plimits_Ipc_Test_010 +* @tc.desc: ipc plimit function test case +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, ItProcessPlimitsIpc010, TestSize.Level0) +{ + ItProcessPlimitsIpc010(); +} + +/** +* @tc.name: plimits_Ipc_Test_011 +* @tc.desc: ipc plimit function test case +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, ItProcessPlimitsIpc011, TestSize.Level0) +{ + ItProcessPlimitsIpc011(); +} + +/** +* @tc.name: plimits_Ipc_Test_012 +* @tc.desc: ipc plimit function test case +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, ItProcessPlimitsIpc012, TestSize.Level0) +{ + ItProcessPlimitsIpc012(); +} + +/** +* @tc.name: plimits_Ipc_Test_013 +* @tc.desc: ipc plimit function test case +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, ItProcessPlimitsIpc013, TestSize.Level0) +{ + ItProcessPlimitsIpc013(); +} + +/** +* @tc.name: plimits_Sched_Test_001 +* @tc.desc: sched plimit function test case +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, IItProcessPlimitsSched001, TestSize.Level0) +{ + ItProcessPlimitsSched001(); +} + +/** +* @tc.name: plimits_Sched_Test_002 +* @tc.desc: sched plimit function test case +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, IItProcessPlimitsSched002, TestSize.Level0) +{ + ItProcessPlimitsSched002(); +} + +/** +* @tc.name: plimits_Sched_Test_003 +* @tc.desc: sched plimit function test case +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, IItProcessPlimitsSched003, TestSize.Level0) +{ + ItProcessPlimitsSched003(); +} + +/** +* @tc.name: plimits_Sched_Test_004 +* @tc.desc: sched plimit function test case +* @tc.require: issueI6GVPL +* @tc.author: +*/ +HWTEST_F(ProcessPlimitsTest, IItProcessPlimitsSched004, TestSize.Level0) +{ + ItProcessPlimitsSched004(); +} +#endif +} // namespace OHOS + + +namespace OHOS { +void ProcessPlimitsTest::SetUp() +{ + (void)rmdir("/proc/plimits/test"); +} + +void ProcessPlimitsTest::TearDown() +{ + (void)rmdir("/proc/plimits/test"); +} + +bool ProcessPlimitsTest::IsFile(const std::string &file) +{ + struct stat statbuf; + return (lstat(file.c_str(), &statbuf) == 0) && S_ISREG(statbuf.st_mode); +} + +bool ProcessPlimitsTest::IsDir(const std::string &path) +{ + struct stat statbuf; + return (lstat(path.c_str(), &statbuf) == 0) && S_ISDIR(statbuf.st_mode); +} + +bool ProcessPlimitsTest::IsSpecialDir(const std::string &path) +{ + return strcmp(path.c_str(), ".") == 0 || strcmp(path.c_str(), "..") == 0; +} +} // namespace OHOS + +int ReadFile(const char *filepath, char *buf) +{ + FILE *fpid = nullptr; + fpid = fopen(filepath, "r"); + if (fpid == nullptr) { + return -1; + } + size_t trd = fread(buf, 1, 512, fpid); + (void)fclose(fpid); + return trd; +} + +int WriteFile(const char *filepath, const char *buf) +{ + int fd = open(filepath, O_WRONLY); + if (fd == -1) { + return -1; + } + size_t twd = write(fd, buf, strlen(buf)); + if (twd == -1) { + (void)close(fd); + return -1; + } + (void)close(fd); + return twd; +} + +int GetLine(char *buf, int count, int maxLen, char **array) +{ + char *head = buf; + char *tail = buf; + char index = 0; + if ((buf == NULL) || (strlen(buf) == 0)) { + return 0; + } + while (*tail != '\0') { + if (*tail != '\n') { + tail++; + continue; + } + if (index >= count) { + return index + 1; + } + + array[index] = head; + index++; + *tail = '\0'; + if (strlen(head) > maxLen) { + return index + 1; + } + tail++; + head = tail; + tail++; + } + return (index + 1); +} + +int RmdirTest(std::string path) +{ + int ret; + RmdirControlFile(path); + ret = rmdir(path.c_str()); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + return 0; +} + +int WaitForCpupStable(int expectedCpupPercent) +{ + int sleepTime; + if (expectedCpupPercent >= QUOTA_PERCENT_100) { + sleepTime = WAIT_CPUP_STABLE_FOR_100; + } else { + sleepTime = WAIT_CPUP_STABLE; + } + return sleep(sleepTime); +} + +static int SampleRound(void) +{ + return STATISTIC_TIMES; +} + +static vector GetProcessInfo(pid_t pid) +{ + vector contentArr; + char buf[TEST_BUFFER_SIZE + 1] = {0}; + string strpid = to_string(pid); + + ifstream infile; + infile.open("/proc/process"); + while (!infile.eof()) { + infile.getline(buf, TEST_BUFFER_SIZE); + regex e("^\\s+"+strpid); + int matchResult = regex_search(buf, e); + if (matchResult == 1) { + istringstream str(buf); + string out; + while (str >> out) { + contentArr.push_back(out); + } + break; + } + (void)memset_s(buf, TEST_BUFFER_SIZE, 0, TEST_BUFFER_SIZE); + } + infile.close(); + (void)memset_s(buf, TEST_BUFFER_SIZE, 0, TEST_BUFFER_SIZE); + return contentArr; +} + + +static void SigQuit(int s) +{ + exit(0); +} + +static int ChildRunCpup() +{ + struct sigaction act; + act.sa_handler = SigQuit; + (void)sigaction(SIGUSR1, &act, NULL); + + unsigned long x = 1; + unsigned long y = 1; + while (1) { + y++; + x *= y; + } + + return 0; +} + +int ForkChilds(int num, int *pidArray) +{ + pid_t childPid; + pid_t pidArrayLocal[PROCESS_LIMIT_AMOUNT]; + + for (int idx = 0; idx < num; idx++) { + childPid = fork(); + if (childPid == 0) { + (void)ChildRunCpup(); + } else if (childPid > 0) { + pidArrayLocal[idx] = childPid; + *pidArray = childPid; + pidArray++; + } else { + return -errno; + } + } + return 0; +} + +static double GetCpup(pid_t pid) +{ + auto content = GetProcessInfo(pid); + double cpup10s = atof(content[CPUP10S_INDEX].c_str()); + return cpup10s; +} + +static int CollectCpupData(int childAmount, int sampleSeconds, int *pidArray, vector> &cpupValuesArray) +{ + double cpup10s; + for (int i = 0; i < sampleSeconds; i++) { + for (int j = 0; j < childAmount;j++) { + cpup10s = GetCpup(pidArray[j]); + cpupValuesArray[j].push_back(cpup10s); + } + sleep(1); + } + return 0; +} + +static int CalcAverageCpup(int num, vector> &cpupValuesArray, double *cpupAverageArray) +{ + double cpup10sAverage; + for (int idx = 0; idx < num; idx++) { + auto size = cpupValuesArray[idx].size(); + cpup10sAverage = std::accumulate(cpupValuesArray[idx].begin(), cpupValuesArray[idx].end(), 0.0) / size; + cpupAverageArray[idx] = cpup10sAverage; + } + return 0; +} + +int CreatePlimitGroup(const char* groupName, char *childPidFiles, + unsigned long long periodUs, unsigned long long quotaUs) +{ + int ret; + mode_t mode = 0777; + char dirpath[TEST_BUFFER_SIZE]; + char procspath[TEST_BUFFER_SIZE]; + char periodpath[TEST_BUFFER_SIZE]; + char quotapath[TEST_BUFFER_SIZE]; + char periodValue[TEST_BUFFER_SIZE]; + char quotaValue[TEST_BUFFER_SIZE]; + + if (sprintf_s(dirpath, TEST_BUFFER_SIZE, "/proc/plimits/%s", groupName) < 0) { + return -1; + } + if (sprintf_s(procspath, TEST_BUFFER_SIZE, "%s/plimits.procs", dirpath) < 0) { + return -1; + } + if (sprintf_s(periodpath, TEST_BUFFER_SIZE, "%s/sched.period", dirpath) < 0) { + return -1; + } + if (sprintf_s(quotapath, TEST_BUFFER_SIZE, "%s/sched.quota", dirpath) < 0) { + return -1; + } + + ret = access(dirpath, 0); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + + ret = mkdir(dirpath, mode); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + if (sprintf_s(periodValue, TEST_BUFFER_SIZE, "%llu", periodUs) < 0) { + return -1; + } + if (sprintf_s(quotaValue, TEST_BUFFER_SIZE, "%llu", quotaUs) < 0) { + return -1; + } + ret = WriteFile(periodpath, periodValue); + if (ret < 0) { + printf("%s %d\n", __FUNCTION__, __LINE__); + return ret; + } + ret = WriteFile(quotapath, quotaValue); + if (ret < 0) { + printf("%s %d\n", __FUNCTION__, __LINE__); + return ret; + } + if (sprintf_s(childPidFiles, TEST_BUFFER_SIZE, "%s", procspath) < 0) { + return -1; + } + return 0; +} + +int CreatePlimitGroupWithoutLimit(const char* groupName, char *childPidFiles) +{ + int ret; + mode_t mode = 0777; + char dirpath[TEST_BUFFER_SIZE]; + char procspath[TEST_BUFFER_SIZE]; + + if (sprintf_s(dirpath, TEST_BUFFER_SIZE, "/proc/plimits/%s", groupName) < 0) { + return -1; + } + if (sprintf_s(procspath, TEST_BUFFER_SIZE, "%s/plimits.procs", dirpath) < 0) { + return -1; + } + + ret = access(dirpath, 0); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ret = mkdir(dirpath, mode); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + if (sprintf_s(childPidFiles, TEST_BUFFER_SIZE, "%s", procspath) < 0) { + return -1; + } + return 0; +} + +int TerminateChildProcess(int *childPidArray, int childAmount, int sig) +{ + int idx; + for (idx = 0; idx < childAmount; idx++) { + (void)kill(childPidArray[idx], SIGUSR1); + + int status; + (void)waitpid(childPidArray[idx], &status, 0); + } + + (void)signal(SIGUSR1, SIG_DFL); + return 0; +} + +double CalcCpupUsage(int childAmount, int *childPidArray, int expectedCpupPercent) +{ + int idx; + int sampleSeconds = SampleRound(); + vector> cpupValuesArray(PROCESS_LIMIT_AMOUNT); + (void)CollectCpupData(childAmount, sampleSeconds, &childPidArray[0], cpupValuesArray); + + double actualCpup10sArray[PROCESS_LIMIT_AMOUNT]; + (void)CalcAverageCpup(childAmount, cpupValuesArray, &actualCpup10sArray[0]); + + double sumAllChildsCpup = 0; + for (idx = 0; idx < childAmount; idx++) { + sumAllChildsCpup += actualCpup10sArray[idx]; + } + return sumAllChildsCpup; +} + +double CheckCpupUsage(double sumAllChildsCpup, int expectedCpupPercent) +{ + if (expectedCpupPercent <= 0.0) { + return 500.0; /* 500.0: errno */ + } + double errorRate = fabs(sumAllChildsCpup / expectedCpupPercent - 1.0); + return errorRate; +} + +int checkCpupUsageGreaterThan(double sumAllChildsCpup, int expectedCpupPercent) +{ + if (sumAllChildsCpup > expectedCpupPercent) { + return 0; + } else { + return -1; + } +} + +double TestCpupInPlimit(int childAmount, const char* groupName, + unsigned long long periodUs, unsigned long long quotaUs, int expectedCpupPercent) +{ + char dirpath[TEST_BUFFER_SIZE]; + pid_t childPidArray[PROCESS_LIMIT_AMOUNT]; + char procspath[TEST_BUFFER_SIZE]; + double sumAllChildsCpup = 0; + + int ret = CreatePlimitGroup(groupName, procspath, periodUs, quotaUs); + if (ret < 0) { + printf("%s %d, ret=%d\n", __FUNCTION__, __LINE__, ret); + return 100.0; /* 100.0: errno */ + } + ret = ForkChilds(childAmount, &childPidArray[0]); + if (ret != 0) { + printf("%s %d, ret=%d\n", __FUNCTION__, __LINE__, ret); + return 200.0; /* 200.0: errno */ + } + (void)WaitForCpupStable(expectedCpupPercent); + sumAllChildsCpup = CalcCpupUsage(childAmount, &childPidArray[0], 0); + double errorRate = CheckCpupUsage(sumAllChildsCpup, expectedCpupPercent); + + (void)TerminateChildProcess(&childPidArray[0], childAmount, SIGUSR1); + + if (sprintf_s(dirpath, TEST_BUFFER_SIZE, "/proc/plimits/%s", groupName) < 0) { + return 300.0; /* 300.0: errno */ + } + ret = rmdir(dirpath); + if (ret != 0) { + printf("%s %d, ret=%d\n", __FUNCTION__, __LINE__, errno); + return 400.0; /* 400.0: errno */ + } + return errorRate; +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_001.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_001.cpp new file mode 100644 index 00000000..f3665a56 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_001.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "It_process_plimits.h" + +void ItProcessPlimits001(void) +{ + DIR *dirp = opendir("/proc/plimits"); + ASSERT_NE(dirp, nullptr); + (void)closedir(dirp); + + int ret; + std::string path = "/proc/plimits/test1"; + ret = mkdir(path.c_str(), S_IRWXU); // create directory + ASSERT_EQ(ret, 0); + + ret = rmdir(path.c_str()); + ASSERT_EQ(ret, 0); + return; +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_002.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_002.cpp new file mode 100644 index 00000000..e2bf4ef1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_002.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include "It_process_plimits.h" + +void ItProcessPlimits002(void) +{ + (void)rmdir("/proc/plimits"); + DIR *dirp = opendir("/proc/plimits/"); + ASSERT_NE(dirp, nullptr); + (void)closedir(dirp); + return; +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_003.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_003.cpp new file mode 100644 index 00000000..0d5771e8 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_003.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include "It_process_plimits.h" + +void ItProcessPlimits003(void) +{ + int ret; + const char *path = "/proc/text.txt"; + ret = open(path, O_CREAT); + ASSERT_EQ(ret, -1); + return; +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_004.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_004.cpp new file mode 100644 index 00000000..6b54fc00 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_004.cpp @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "It_process_plimits.h" + +void ItProcessPlimits004(void) +{ + int ret, matchResult; + const size_t BUFFER_SIZE = 512; + char buf[BUFFER_SIZE + 1] = {0}; + std::string path = "/proc/plimits/test"; + mode_t mode; + + ret = mkdir(path.c_str(), S_IFDIR | mode); + ASSERT_EQ(ret, 0); + + (void)ReadFile("/proc/plimits/test/plimits.limiters", buf); + printf("/proc/plimits/test/plimits.limiters: %s\n", buf); + matchResult = strncmp(buf, "pids memory ipc devices sched", 29); /* 29: buf len */ + ASSERT_EQ(matchResult, 0); + + ret = rmdir("/proc/plimits/test"); + ASSERT_EQ(ret, 0); + return; +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_005.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_005.cpp new file mode 100644 index 00000000..b103931e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_005.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include "It_process_plimits.h" + +void ItProcessPlimits005(void) +{ + int ret; + const char *path = "/proc/plimits/text.txt"; + ret = open(path, O_CREAT); + ASSERT_EQ(ret, -1); + return; +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_006.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_006.cpp new file mode 100644 index 00000000..971fa18a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_006.cpp @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include "It_process_plimits.h" + +void ItProcessPlimits006(void) +{ + int ret; + const char *path3 = "/proc/plimits/plimits.procs"; + ret = remove(path3); + ASSERT_EQ(ret, -1); + + const char *path4 = "/proc/plimits/pids.max"; + ret = remove(path4); + ASSERT_EQ(ret, -1); + + const char *path5 = "/proc/plimits/pids.priority"; + ret = remove(path5); + ASSERT_EQ(ret, -1); + + const char *path6 = "/proc/plimits/sched.period"; + ret = remove(path6); + ASSERT_EQ(ret, -1); + + const char *path7 = "/proc/plimits/sched.quota"; + ret = remove(path7); + ASSERT_EQ(ret, -1); + + const char *path8 = "/proc/plimits/sched.stat"; + ret = remove(path8); + ASSERT_EQ(ret, -1); + + const char *path9 = "/proc/plimits/memory.limit"; + ret = remove(path9); + ASSERT_EQ(ret, -1); + + const char *path10 = "/proc/plimits/memory.stat"; + ret = remove(path10); + ASSERT_EQ(ret, -1); + + const char *path11 = "/proc/plimits/ipc.mq_limit"; + ret = remove(path11); + ASSERT_EQ(ret, -1); + + const char *path12 = "/proc/plimits/ipc.shm_limit"; + ret = remove(path12); + ASSERT_EQ(ret, -1); + + const char *path13 = "/proc/plimits/ipc.stat"; + ret = remove(path13); + ASSERT_EQ(ret, -1); + + const char *path14 = "/proc/plimits/devices.list"; + ret = remove(path14); + ASSERT_EQ(ret, -1); + + const char *path15 = "/proc/plimits/devices.deny"; + ret = remove(path15); + ASSERT_EQ(ret, -1); + + const char *path16 = "/proc/plimits/devices.allow"; + ret = remove(path16); + ASSERT_EQ(ret, -1); + + const char *path17 = "/proc/plimits/limiters"; + ret = remove(path17); + ASSERT_EQ(ret, -1); + return; +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_007.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_007.cpp new file mode 100644 index 00000000..f7edc0ed --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_007.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "It_process_plimits.h" + +void ItProcessPlimits007(void) +{ + mode_t mode = S_IRWXU; + std::string path0 = "/proc/plimits/test"; + std::string path1 = "/proc/plimits/test/subtest"; + std::string path2 = "/proc/plimits/test/subtest/subtest"; + std::string path3 = "/proc/plimits/test/subtest/subtest/subtest"; + std::string path4 = "/proc/plimits/test/subtest/subtest/subtest/subtest"; + int ret = mkdir(path0.c_str(), mode); + ASSERT_EQ(ret, 0); + + ret = mkdir(path1.c_str(), mode); + ASSERT_EQ(ret, -1); + + ret = mkdir(path2.c_str(), mode); + ASSERT_EQ(ret, -1); + + ret = mkdir(path3.c_str(), mode); + ASSERT_EQ(ret, -1); + + ret = mkdir(path4.c_str(), mode); + ASSERT_EQ(ret, -1); + + ret = rmdir(path0.c_str()); + ASSERT_EQ(ret, 0); + return; +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_008.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_008.cpp new file mode 100644 index 00000000..3c4fcf62 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_008.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "It_process_plimits.h" + +static std::string GetFileMode(const char* filePath) +{ + const int MODE_COUNT = 11; + char fileProperty[MODE_COUNT] = "----------"; + char fileMode[MODE_COUNT] = "-rwxrwxrwx"; + struct stat buf; + stat(filePath, &buf); + unsigned int off = 256; + const int LOOP_VARY = 10; + for (int i = 1; i < LOOP_VARY; i++) { + if (buf.st_mode & (off >> (i - 1))) { + fileProperty[i] = fileMode[i]; + } + } + return fileProperty; +} + +static int IsFilePropertyR1(const char* filePath) +{ + std::string fileOrg = "-r--r--r--"; + std::string fileProperty = GetFileMode(filePath); + return strcmp(fileProperty.c_str(), fileOrg.c_str()); +} + +void ItProcessPlimits008(void) +{ + std::string filePath = "/proc/plimits/"; + std::vector fileName; + fileName.push_back("plimits.procs"); + fileName.push_back("plimits.limiters"); + fileName.push_back("pids.max"); + fileName.push_back("sched.period"); + fileName.push_back("sched.quota"); + fileName.push_back("sched.stat"); + fileName.push_back("memory.failcnt"); + fileName.push_back("memory.limit"); + fileName.push_back("memory.peak"); + fileName.push_back("memory.usage"); + fileName.push_back("memory.stat"); + + for (auto iter = fileName.begin(); iter != fileName.end(); ++iter) { + std::string fileFullPath = filePath + *iter; + int ret = IsFilePropertyR1(fileFullPath.c_str()); + ASSERT_EQ(ret, 0); + } + + return; +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_devices_001.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_devices_001.cpp new file mode 100644 index 00000000..f4b9d078 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_devices_001.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include "It_process_plimits.h" + +void ItProcessPlimitsDevices001(void) +{ + int fd; + int ret; + mode_t mode; + char writeBuf[8]; + std::string test_dev = "/dev/hi_mipi"; + std::string path = "/proc/plimits/test"; + std::string procsTestPath = "/proc/plimits/test/plimits.procs"; + + ret = mkdir(path.c_str(), S_IFDIR | mode); + ASSERT_EQ(ret, 0); + + (void)memset_s(writeBuf, sizeof(writeBuf), 0, sizeof(writeBuf)); + ret = sprintf_s(writeBuf, sizeof(writeBuf), "%d", getpid()); + ASSERT_NE(ret, -1); + + ret = WriteFile(procsTestPath.c_str(), writeBuf); + ASSERT_NE(ret, 0); + + fd = open(test_dev.c_str(), O_RDWR|O_CREAT); + ASSERT_NE(fd, -1); + (void)close(fd); + + ret = rmdir(path.c_str()); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_devices_002.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_devices_002.cpp new file mode 100644 index 00000000..b6743b51 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_devices_002.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include "It_process_plimits.h" + +void ItProcessPlimitsDevices002(void) +{ + int fd; + int ret; + mode_t mode; + std::string test_dev = "/dev/hi_mipi"; + std::string device_a = "a * rwm"; + std::string device_a_r = "a * r"; + std::string path = "/proc/plimits/test"; + std::string devicesDenyPath = "/proc/plimits/test/devices.deny"; + std::string devicesAllowPath = "/proc/plimits/test/devices.allow"; + + ret = mkdir(path.c_str(), S_IFDIR | mode); + ASSERT_EQ(ret, 0); + + ret = WriteFile(devicesDenyPath.c_str(), device_a.c_str()); + ASSERT_NE(ret, -1); + + ret = WriteFile(devicesAllowPath.c_str(), device_a_r.c_str()); + ASSERT_NE(ret, -1); + + fd = open(test_dev.c_str(), O_RDWR|O_CREAT); + ASSERT_NE(fd, -1); + (void)close(fd); + + ret = rmdir(path.c_str()); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_devices_003.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_devices_003.cpp new file mode 100644 index 00000000..4c4f315c --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_devices_003.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include "It_process_plimits.h" + +void ItProcessPlimitsDevices003(void) +{ + int fd; + int ret; + mode_t mode; + std::string test_dev = "/dev/hi_mipi"; + std::string device_a = "a * rwm"; + std::string device_a_w = "a * w"; + std::string path = "/proc/plimits/test"; + std::string devicesDenyPath = "/proc/plimits/test/devices.deny"; + std::string devicesAllowPath = "/proc/plimits/test/devices.allow"; + + ret = mkdir(path.c_str(), S_IFDIR | mode); + ASSERT_EQ(ret, 0); + + ret = WriteFile(devicesDenyPath.c_str(), device_a.c_str()); + ASSERT_NE(ret, -1); + ret = WriteFile(devicesAllowPath.c_str(), device_a_w.c_str()); + ASSERT_NE(ret, -1); + + fd = open(test_dev.c_str(), O_RDWR|O_CREAT); + ASSERT_NE(fd, -1); + (void)close(fd); + + ret = rmdir(path.c_str()); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_devices_004.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_devices_004.cpp new file mode 100644 index 00000000..94a92241 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_devices_004.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include "It_process_plimits.h" + +void ItProcessPlimitsDevices004(void) +{ + int fd; + int ret; + mode_t mode; + std::string test_dev = "/dev/hi_mipi"; + std::string device_a = "a * rwm"; + std::string device_a_m = "a * m"; + std::string path = "/proc/plimits/test"; + std::string devicesDenyPath = "/proc/plimits/test/devices.deny"; + std::string devicesAllowPath = "/proc/plimits/test/devices.allow"; + + ret = mkdir(path.c_str(), S_IFDIR | mode); + ASSERT_EQ(ret, 0); + + ret = WriteFile(devicesDenyPath.c_str(), device_a.c_str()); + ASSERT_NE(ret, -1); + ret = WriteFile(devicesAllowPath.c_str(), device_a_m.c_str()); + ASSERT_NE(ret, -1); + + fd = open(test_dev.c_str(), O_CREAT); + ASSERT_NE(fd, -1); + (void)close(fd); + + ret = rmdir(path.c_str()); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_devices_005.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_devices_005.cpp new file mode 100644 index 00000000..0464ef5b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_devices_005.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include "It_process_plimits.h" + +void ItProcessPlimitsDevices005(void) +{ + int fd; + int ret; + mode_t mode; + std::string test_dev = "/dev/mem"; + std::string device_a = "a * rwm"; + std::string device_c = "c * rwm"; + std::string path = "/proc/plimits/test"; + std::string devicesDenyPath = "/proc/plimits/test/devices.deny"; + std::string devicesAllowPath = "/proc/plimits/test/devices.allow"; + + ret = mkdir(path.c_str(), S_IFDIR | mode); + ASSERT_EQ(ret, 0); + + ret = WriteFile(devicesDenyPath.c_str(), device_a.c_str()); + ASSERT_NE(ret, -1); + ret = WriteFile(devicesAllowPath.c_str(), device_c.c_str()); + ASSERT_NE(ret, -1); + + fd = open(test_dev.c_str(), O_RDWR|O_CREAT); + ASSERT_NE(fd, -1); + (void)close(fd); + + ret = rmdir(path.c_str()); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_devices_006.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_devices_006.cpp new file mode 100644 index 00000000..1b76142e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_devices_006.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include "It_process_plimits.h" + +void ItProcessPlimitsDevices006(void) +{ + int fd; + int ret; + mode_t mode; + std::string test_dev = "/dev/mem"; + std::string device_a = "a * rwm"; + std::string device_c_r = "c * r"; + std::string path = "/proc/plimits/test"; + std::string devicesDenyPath = "/proc/plimits/test/devices.deny"; + std::string devicesAllowPath = "/proc/plimits/test/devices.allow"; + + ret = mkdir(path.c_str(), S_IFDIR | mode); + ASSERT_EQ(ret, 0); + + ret = WriteFile(devicesDenyPath.c_str(), device_a.c_str()); + ASSERT_NE(ret, -1); + ret = WriteFile(devicesAllowPath.c_str(), device_c_r.c_str()); + ASSERT_NE(ret, -1); + + fd = open(test_dev.c_str(), O_RDONLY); + ASSERT_NE(fd, -1); + (void)close(fd); + + ret = rmdir(path.c_str()); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_devices_007.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_devices_007.cpp new file mode 100644 index 00000000..cd75c6d9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_devices_007.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include "It_process_plimits.h" + +void ItProcessPlimitsDevices007(void) +{ + int fd; + int ret; + mode_t mode; + std::string test_dev = "/dev/mem"; + std::string device_a = "a * rwm"; + std::string device_c_w = "c * w"; + std::string path = "/proc/plimits/test"; + std::string devicesDenyPath = "/proc/plimits/test/devices.deny"; + std::string devicesAllowPath = "/proc/plimits/test/devices.allow"; + + ret = mkdir(path.c_str(), S_IFDIR | mode); + ASSERT_EQ(ret, 0); + + ret = WriteFile(devicesDenyPath.c_str(), device_a.c_str()); + ASSERT_NE(ret, -1); + ret = WriteFile(devicesAllowPath.c_str(), device_c_w.c_str()); + ASSERT_NE(ret, -1); + + fd = open(test_dev.c_str(), O_WRONLY); + ASSERT_NE(fd, -1); + (void)close(fd); + + ret = rmdir(path.c_str()); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_devices_008.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_devices_008.cpp new file mode 100644 index 00000000..4e3b19fb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_devices_008.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include "It_process_plimits.h" + +void ItProcessPlimitsDevices008(void) +{ + int fd; + int ret; + mode_t mode; + std::string test_dev = "/dev/mem"; + std::string device_a = "a * rwm"; + std::string device_c_m = "c * rm"; + std::string path = "/proc/plimits/test"; + std::string devicesDenyPath = "/proc/plimits/test/devices.deny"; + std::string devicesAllowPath = "/proc/plimits/test/devices.allow"; + + ret = mkdir(path.c_str(), S_IFDIR | mode); + ASSERT_EQ(ret, 0); + + ret = WriteFile(devicesDenyPath.c_str(), device_a.c_str()); + ASSERT_NE(ret, -1); + ret = WriteFile(devicesAllowPath.c_str(), device_c_m.c_str()); + ASSERT_NE(ret, -1); + + fd = open(test_dev.c_str(), O_CREAT, O_RDONLY); + ASSERT_NE(fd, -1); + (void)close(fd); + + ret = rmdir(path.c_str()); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_devices_009.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_devices_009.cpp new file mode 100644 index 00000000..c1fa4a58 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_devices_009.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include "It_process_plimits.h" + +void ItProcessPlimitsDevices009(void) +{ + int fd; + int ret; + mode_t mode; + std::string test_dev = "/dev/hi_mipi"; + std::string device_a = "a"; + std::string path = "/proc/plimits/test"; + std::string devicesDenyPath = "/proc/plimits/test/devices.deny"; + + ret = mkdir(path.c_str(), S_IFDIR | mode); + ASSERT_EQ(ret, 0); + + ret = WriteFile(devicesDenyPath.c_str(), device_a.c_str()); + ASSERT_NE(ret, -1); + + fd = open(test_dev.c_str(), O_RDONLY|O_CREAT); + ASSERT_EQ(fd, -1); + (void)close(fd); + + fd = open(test_dev.c_str(), O_WRONLY|O_CREAT); + ASSERT_EQ(fd, -1); + (void)close(fd); + + ret = rmdir(path.c_str()); + ASSERT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_002.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_002.cpp new file mode 100644 index 00000000..93a7de37 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_002.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "It_process_plimits.h" + +void ItProcessPlimitsIpc002(void) +{ + mode_t mode; + int ret; + int fd; + std::string plimitsRootPath = "/proc/plimits/"; + std::vector ipcConfFileName; + ipcConfFileName.push_back("ipc.mq_limit"); + ipcConfFileName.push_back("ipc.shm_limit"); + ipcConfFileName.push_back("ipc.stat"); + + for (auto iter = ipcConfFileName.begin(); iter != ipcConfFileName.end(); ++iter) { + std::string fullPath = plimitsRootPath + *iter; + fd = access(fullPath.c_str(), W_OK | X_OK); + ASSERT_EQ(fd, -1); + fd = access(fullPath.c_str(), F_OK | R_OK); + ASSERT_EQ(fd, 0); + } + return; +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_003.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_003.cpp new file mode 100644 index 00000000..ffd36030 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_003.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "It_process_plimits.h" + +void ItProcessPlimitsIpc003(void) +{ + mode_t mode; + int ret; + std::string plimitsPath = "/proc/plimits/test"; + std::string configFileMqCount = "/proc/plimits/test/ipc.mq_limit"; + std::string configFileShmSize = "/proc/plimits/test/ipc.shm_limit"; + std::string configFileStat = "/proc/plimits/test/ipc.stat"; + + ret = mkdir(plimitsPath.c_str(), S_IFDIR | mode); + ASSERT_EQ(ret, 0); + + int fd = access(configFileMqCount.c_str(), F_OK | W_OK | R_OK); + ASSERT_EQ(fd, 0); + + fd = access(configFileShmSize.c_str(), F_OK | W_OK | R_OK); + ASSERT_EQ(fd, 0); + + fd = access(configFileStat.c_str(), F_OK | R_OK); + ASSERT_EQ(fd, 0); + + fd = access(configFileStat.c_str(), W_OK | X_OK); + ASSERT_EQ(fd, -1); + + ret = rmdir(plimitsPath.c_str()); + ASSERT_EQ(ret, 0); + return; +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_004.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_004.cpp new file mode 100644 index 00000000..b70dfa57 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_004.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "It_process_plimits.h" + +void ItProcessPlimitsIpc004(void) +{ + mode_t mode; + mode_t chmodMode = 0777; + int ret; + int fd; + std::string rootplimitsPath = "/proc/plimits"; + std::string subPlimitsPath = "/proc/plimits/test"; + + std::vector ipcConfFileName; + ipcConfFileName.push_back("ipc.mq_limit"); + ipcConfFileName.push_back("ipc.shm_limit"); + ipcConfFileName.push_back("ipc.stat"); + + ret = mkdir(subPlimitsPath.c_str(), S_IFDIR | mode); + ASSERT_EQ(ret, 0); + + for (auto iter = ipcConfFileName.begin(); iter != ipcConfFileName.end(); ++iter) { + std::string fullPath = rootplimitsPath + "/" + *iter; + ret = chmod(fullPath.c_str(), mode); + ASSERT_EQ(ret, -1); + } + + for (auto iter = ipcConfFileName.begin(); iter != ipcConfFileName.end(); ++iter) { + std::string fullPath = subPlimitsPath + "/" + *iter; + ret = chmod(fullPath.c_str(), mode); + ASSERT_EQ(ret, -1); + } + + ret = rmdir(subPlimitsPath.c_str()); + ASSERT_EQ(ret, 0); + return; +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_005.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_005.cpp new file mode 100644 index 00000000..d4d984fb --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_005.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "It_process_plimits.h" + +static const int g_buffSize = 512; +static const int g_arryLen = 4; +static const int MQ_MAX_PER_PROCESS_COUNT = 255; +static const int MQUEUE_STANDARD_NAME_LENGTH = 50; + +void ItProcessPlimitsIpc005(void) +{ + INT32 ret; + mode_t mode; + char buf[g_buffSize] = { 0 }; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + mqd_t mqueue[MQ_MAX_PER_PROCESS_COUNT]; + struct mq_attr attr = { 0 }; + int index = 0; + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = 1; + + std::string plimitsPath = "/proc/plimits/test"; + + ret = mkdir(plimitsPath.c_str(), S_IFDIR | mode); + ASSERT_EQ(ret, 0); + + ret = ReadFile("/proc/plimits/test/ipc.mq_limit", buf); + ASSERT_STREQ(buf, "1024\n"); + + for (index = 0; index < MQ_MAX_PER_PROCESS_COUNT; ++index) { + ret = snprintf_s(mqname, sizeof(mqname), MQUEUE_STANDARD_NAME_LENGTH, "/mq_005_%d_%d", + index, LosCurTaskIDGet()); + ASSERT_NE(ret, -1); + mqueue[index] = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ASSERT_NE(mqueue[index], (mqd_t)-1); + } + for (int k = 0; k < MQ_MAX_PER_PROCESS_COUNT; ++k) { + ret = mq_close(mqueue[k]); + ASSERT_NE(ret, -1); + ret = snprintf_s(mqname, sizeof(mqname), MQUEUE_STANDARD_NAME_LENGTH, "/mq_005_%d_%d", k, LosCurTaskIDGet()); + ASSERT_NE(ret, -1); + ret = mq_unlink(mqname); + ASSERT_EQ(ret, 0); + } + + ret = rmdir(plimitsPath.c_str()); + ASSERT_EQ(ret, 0); + return; +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_006.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_006.cpp new file mode 100644 index 00000000..1e5b25f4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_006.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "It_process_plimits.h" + +static const int MQUEUE_STANDARD_NAME_LENGTH = 50; +static const int g_buffSize = 512; +static const int g_arryLen = 4; +static const int g_readLen = 254; +static const int MQ_MAX_LIMIT_COUNT = 10; + +static int FreeResource(mqd_t *mqueue, int index, char *mqname) +{ + int ret = -1; + for (int k = 0; k < index; ++k) { + if (snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH, "/mq_006_%d_%d", + k, LosCurTaskIDGet()) < 0) { + return -1; + } + ret = mq_close(mqueue[k]); + if (ret != 0) { + return -2; /* 2: errno */ + } + ret = mq_unlink(mqname); + if (ret != 0) { + return -3; /* 3: errno */ + } + (void)memset_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, 0, MQUEUE_STANDARD_NAME_LENGTH); + } + return ret; +} + +// plimits_ipc_07, plimits_ipc_14, plimits_ipc_17 +void ItProcessPlimitsIpc006(void) +{ + INT32 ret; + mode_t mode; + char buf[g_buffSize] = { 0 }; + char *array[g_arryLen] = { nullptr }; + int mqSuccessCount = -1, mqFailedCount = -1; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + mqd_t mqueue[g_readLen]; + std::string subPlimitsPath = "/proc/plimits/test"; + std::string configFileMqCount = "/proc/plimits/test/ipc.mq_limit"; + std::string limitMqCount = "10"; + struct mq_attr attr = { 0 }; + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = 1; + int index = 0; + + ret = mkdir(subPlimitsPath.c_str(), S_IFDIR | mode); + ASSERT_EQ(ret, 0); + + ret = WriteFile(configFileMqCount.c_str(), limitMqCount.c_str()); + ASSERT_NE(ret, -1); + + for (index = 0; index < MQ_MAX_LIMIT_COUNT; ++index) { + ret = snprintf_s(mqname, sizeof(mqname), MQUEUE_STANDARD_NAME_LENGTH, "/mq_006_%d_%d", + index, LosCurTaskIDGet()); + ASSERT_NE(ret, -1); + mqueue[index] = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ASSERT_NE(mqueue[index], (mqd_t)-1); + (void)memset_s(mqname, sizeof(mqname), 0, sizeof(mqname)); + } + ret = snprintf_s(mqname, sizeof(mqname), MQUEUE_STANDARD_NAME_LENGTH, "/mq_006_%d_%d", index, LosCurTaskIDGet()); + ASSERT_NE(ret, -1); + mqueue[index] = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ASSERT_EQ(mqueue[index], (mqd_t)-1); + (void)memset_s(mqname, sizeof(mqname), 0, sizeof(mqname)); + + ret = ReadFile("/proc/plimits/test/ipc.stat", buf); + printf("/proc/plimits/test/ipc.stat: %s\n", buf); + GetLine(buf, g_arryLen, g_readLen, array); + mqSuccessCount = atoi(array[0] + strlen("mq count: ")); + mqFailedCount = atoi((array[1] + strlen("mq failed count: "))); + ASSERT_EQ(mqSuccessCount, MQ_MAX_LIMIT_COUNT); + ASSERT_EQ(mqFailedCount, 1); + ret = FreeResource(mqueue, index, mqname); + ASSERT_EQ(ret, 0); + + ret = rmdir(subPlimitsPath.c_str()); + ASSERT_EQ(ret, 0); + return; +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_007.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_007.cpp new file mode 100644 index 00000000..e2ed8842 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_007.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "It_process_plimits.h" + +void ItProcessPlimitsIpc007(void) +{ + mode_t mode; + int ret; + std::string plimitsPath = "/proc/plimits/test"; + std::string configFileMqCount = "/proc/plimits/test/ipc.mq_limit"; + std::string mqLimitCount = "0123"; + + ret = mkdir(plimitsPath.c_str(), S_IFDIR | mode); + ASSERT_EQ(ret, 0); + + ret = WriteFile(configFileMqCount.c_str(), mqLimitCount.c_str()); + ASSERT_NE(ret, -1); + + ret = rmdir(plimitsPath.c_str()); + ASSERT_EQ(ret, 0); + return; +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_008.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_008.cpp new file mode 100644 index 00000000..f259beb9 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_008.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "It_process_plimits.h" + +void ItProcessPlimitsIpc008(void) +{ + mode_t mode; + int ret; + std::string plimitsPath = "/proc/plimits/test"; + std::string configFileMqCount = "/proc/plimits/test/ipc.mq_limit"; + std::string mqLimitCount_0 = "111*"; + std::string mqLimitCount_1 = "123abc"; + std::string mqLimitCount_2 = "\"123 456\""; + std::string mqLimitCount_3 = "\123"; + std::string mqLimitCount_4 = "10000000000000000000000000000000001"; + std::string mqLimitCount_5 = "\1\2\3"; + + ret = mkdir(plimitsPath.c_str(), S_IFDIR | mode); + ASSERT_EQ(ret, 0); + + ret = WriteFile(configFileMqCount.c_str(), mqLimitCount_0.c_str()); + ASSERT_EQ(ret, -1); + + ret = WriteFile(configFileMqCount.c_str(), mqLimitCount_1.c_str()); + ASSERT_EQ(ret, -1); + + ret = WriteFile(configFileMqCount.c_str(), mqLimitCount_2.c_str()); + ASSERT_EQ(ret, -1); + + ret = WriteFile(configFileMqCount.c_str(), mqLimitCount_3.c_str()); + ASSERT_EQ(ret, -1); + + ret = WriteFile(configFileMqCount.c_str(), mqLimitCount_4.c_str()); + ASSERT_EQ(ret, -1); + + ret = WriteFile(configFileMqCount.c_str(), mqLimitCount_5.c_str()); + ASSERT_EQ(ret, -1); + + ret = rmdir(plimitsPath.c_str()); + ASSERT_EQ(ret, 0); + return; +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_009.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_009.cpp new file mode 100644 index 00000000..0f2ada8b --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_009.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "It_process_plimits.h" + +static const int g_buffSize = 512; +static const int g_arryLen = 4; +static const int g_readLen = 254; + +void ItProcessPlimitsIpc009(void) +{ + mode_t mode; + char buf[g_buffSize] = { 0 }; + int ret; + int shmid; + void *shared = nullptr; + mode_t acessMode = 0666; + std::string subPlimitsPath = "/proc/plimits/test"; + + ret = mkdir(subPlimitsPath.c_str(), S_IFDIR | mode); + ASSERT_EQ(ret, 0); + + ret = ReadFile("/proc/plimits/test/ipc.shm_limit", buf); + ASSERT_STREQ(buf, "4294967295\n"); + + shmid = shmget(IPC_PRIVATE, PAGE_SIZE, acessMode | IPC_CREAT); + ASSERT_NE(shmid, -1); + shared = shmat(shmid, nullptr, 0); + ASSERT_NE(shared, (void *)-1); + ret = shmdt(shared); + ASSERT_NE(ret, -1); + ret = shmctl(shmid, IPC_RMID, nullptr); + ASSERT_NE(ret, -1); + + ret = rmdir(subPlimitsPath.c_str()); + ASSERT_EQ(ret, 0); + return; +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_010.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_010.cpp new file mode 100644 index 00000000..fefc8d2e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_010.cpp @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "It_process_plimits.h" + +static const int g_buffSize = 512; +static const int g_arryLen = 4; +static const int g_readLen = 254; + +void ItProcessPlimitsIpc010(void) +{ + mode_t mode; + mode_t shmAcess = 0666; + char buf[g_buffSize] = { 0 }; + char *array[g_arryLen] = { nullptr }; + int mqSuccessCount; + int mqFailedCount; + int shmSuccessSize; + int shmFailedCount; + int shmid = -1; + int shmid_1 = -1; + int index = 0; + int shmCkeckSize = PAGE_SIZE * 9; + void *shared = nullptr; + size_t shmSize = PAGE_SIZE * 9; + std::string subPlimitsPath = "/proc/plimits/test"; + std::string configFileShmSize = "/proc/plimits/test/ipc.shm_limit"; + char shmemLimit[6] = "40960"; + + int ret = mkdir(subPlimitsPath.c_str(), S_IFDIR | mode); + ASSERT_EQ(ret, 0); + + ret = WriteFile(configFileShmSize.c_str(), shmemLimit); + ASSERT_NE(ret, -1); + + shmid = shmget(IPC_PRIVATE, shmSize, shmAcess | IPC_CREAT); + ASSERT_NE(shmid, -1); + shmid_1 = shmget(IPC_PRIVATE, 2 * PAGE_SIZE, shmAcess | IPC_CREAT); /* 2: PAGE num */ + ASSERT_EQ(shmid_1, -1); + + ret = ReadFile("/proc/plimits/test/ipc.stat", buf); + GetLine(buf, g_arryLen, g_readLen, array); + mqSuccessCount = atoi(array[index++] + strlen("mq count: ")); + mqFailedCount = atoi(array[index++] + strlen("mq failed count: ")); + shmSuccessSize = atoi(array[index++] + strlen("shm size: ")); + shmFailedCount = atoi(array[index++] + strlen("shm failed count: ")); + + ASSERT_EQ(shmSuccessSize, shmCkeckSize); + ASSERT_EQ(shmFailedCount, 1); + + shared = shmat(shmid, nullptr, 0); + ASSERT_NE(shared, (void *)-1); + + ret = shmdt(shared); + ASSERT_NE(ret, -1); + + ret = shmctl(shmid, IPC_RMID, nullptr); + ASSERT_NE(ret, -1); + shmctl(shmid_1, IPC_RMID, nullptr); + + ret = rmdir(subPlimitsPath.c_str()); + ASSERT_EQ(ret, 0); + return; +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_011.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_011.cpp new file mode 100644 index 00000000..d2a2c4a8 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_011.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "It_process_plimits.h" + +void ItProcessPlimitsIpc011(void) +{ + mode_t mode; + int ret; + char buf[512] = { 0 }; + std::string plimitsPath = "/proc/plimits/test"; + std::string configFileShmSize = "/proc/plimits/test/ipc.shm_limit"; + std::string shmLimitSize = "0123"; + + ret = mkdir(plimitsPath.c_str(), S_IFDIR | mode); + ASSERT_EQ(ret, 0); + + ret = WriteFile(configFileShmSize.c_str(), shmLimitSize.c_str()); + ASSERT_NE(ret, -1); + + ret = rmdir(plimitsPath.c_str()); + ASSERT_EQ(ret, 0); + return; +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_012.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_012.cpp new file mode 100644 index 00000000..5b3ead3f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_012.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "It_process_plimits.h" + +void ItProcessPlimitsIpc012(void) +{ + mode_t mode; + int ret; + std::string plimitsPath = "/proc/plimits/test"; + std::string configFileShmSize = "/proc/plimits/test/ipc.shm_limit"; + std::string shmLimitSize_0 = "111*"; + std::string shmLimitSize_1 = "123abc"; + std::string shmLimitSize_2 = "\"123 456\""; + std::string shmLimitSize_3 = "\123"; + std::string shmLimitSize_4 = "10000000000000000000000000000000001"; + std::string shmLimitSize_5 = "\1\2\3"; + + ret = mkdir(plimitsPath.c_str(), S_IFDIR | mode); + ASSERT_EQ(ret, 0); + + ret = WriteFile(configFileShmSize.c_str(), shmLimitSize_0.c_str()); + ASSERT_EQ(ret, -1); + + ret = WriteFile(configFileShmSize.c_str(), shmLimitSize_1.c_str()); + ASSERT_EQ(ret, -1); + + ret = WriteFile(configFileShmSize.c_str(), shmLimitSize_2.c_str()); + ASSERT_EQ(ret, -1); + + ret = WriteFile(configFileShmSize.c_str(), shmLimitSize_3.c_str()); + ASSERT_EQ(ret, -1); + + ret = WriteFile(configFileShmSize.c_str(), shmLimitSize_4.c_str()); + ASSERT_EQ(ret, -1); + + ret = WriteFile(configFileShmSize.c_str(), shmLimitSize_5.c_str()); + ASSERT_EQ(ret, -1); + + ret = rmdir(plimitsPath.c_str()); + ASSERT_EQ(ret, 0); + return; +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_013.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_013.cpp new file mode 100644 index 00000000..0dc5d5a5 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_013.cpp @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "It_process_plimits.h" + +static const int MQUEUE_STANDARD_NAME_LENGTH = 50; +static const int MQUEUE_STANDARD_NAME_LENGTH_MAX = 102500; +static const int g_buff = 512; +static const int MQ_MAX_LIMIT_COUNT = 10; + +static int FreeResource(mqd_t *mqueue, int index, char *mqname) +{ + int ret = -1; + for (int k = 0; k < index; ++k) { + ret = snprintf_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH, "/mq_006_%d_%d", + k, LosCurTaskIDGet()); + if (ret < 0) { + return -1; /* 1: errno */ + } + ret = mq_close(mqueue[k]); + if (ret < 0) { + return -2; /* 2: errno */ + } + ret = mq_unlink(mqname); + if (ret < 0) { + return -3; /* 3: errno */ + } + (void)memset_s(mqname, MQUEUE_STANDARD_NAME_LENGTH, 0, MQUEUE_STANDARD_NAME_LENGTH); + } + return ret ; +} + +void ItProcessPlimitsIpc013(void) +{ + INT32 ret; + mode_t mode; + CHAR mqname[MQUEUE_STANDARD_NAME_LENGTH] = ""; + mqd_t mqueue[g_buff]; + std::string subPlimitsPath = "/proc/plimits/test"; + std::string configFileMqCount = "/proc/plimits/test/ipc.mq_limit"; + std::string limitMqCount = "11"; + struct mq_attr attr = { 0 }; + attr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH; + attr.mq_maxmsg = 1; + struct mq_attr attr_err = { 0 }; + attr_err.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH_MAX; + attr_err.mq_maxmsg = 1; + int index = 0; + + ret = mkdir(subPlimitsPath.c_str(), S_IFDIR | mode); + ASSERT_EQ(ret, 0); + + ret = WriteFile(configFileMqCount.c_str(), limitMqCount.c_str()); + ASSERT_NE(ret, -1); + + for (index = 0; index < MQ_MAX_LIMIT_COUNT; ++index) { + ret = snprintf_s(mqname, sizeof(mqname), MQUEUE_STANDARD_NAME_LENGTH, "/mq_006_%d_%d", + index, LosCurTaskIDGet()); + ASSERT_NE(ret, -1); + mqueue[index] = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + ASSERT_NE(mqueue[index], (mqd_t)-1); + (void)memset_s(mqname, sizeof(mqname), 0, sizeof(mqname)); + } + + ret = snprintf_s(mqname, sizeof(mqname), MQUEUE_STANDARD_NAME_LENGTH, "/mq_006_%d_%d", index, LosCurTaskIDGet()); + ASSERT_NE(ret, -1); + mqueue[index] = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr_err); + ASSERT_EQ(mqueue[index], (mqd_t)-1); + (void)memset_s(mqname, sizeof(mqname), 0, sizeof(mqname)); + ret = FreeResource(mqueue, index, mqname); + ASSERT_EQ(ret, 0); + + ret = rmdir(subPlimitsPath.c_str()); + ASSERT_EQ(ret, 0); + return; +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_memory_001.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_memory_001.cpp new file mode 100644 index 00000000..9bdfe06a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_memory_001.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_process_plimits.h" + +static char *testStr1 = nullptr; + +static int limitWrite(const char *filepath, const char *buf) +{ + int fd = open(filepath, O_WRONLY); + size_t ret = write(fd, buf, strlen(buf)); + close(fd); + return ret; +} + +static int CloneOne(void *arg) +{ + const unsigned int testSize = 11534336; + + testStr1 = (char *)malloc(testSize); + EXPECT_STRNE(testStr1, NULL); + + (void)memset_s(testStr1, testSize, 1, testSize); + return 0; +} + +void ItProcessPlimitsMemory001(void) +{ + mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; + int ret, pid, status; + std::string path = "/proc/plimits/test"; + std::string limitTestPath = "/proc/plimits/test/memory.limit"; + std::string usageTestPath = "/proc/plimits/test/memory.stat"; + const char *buffer = "10485760"; + char buf[512]; + int twoM = 2 * 1024 * 1024; + + char *stack = (char *)mmap(NULL, twoM, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); + EXPECT_STRNE(stack, NULL); + ret = access(path.c_str(), 0); + EXPECT_EQ(ret, -1); + ret = mkdir(path.c_str(), S_IFDIR | mode); + EXPECT_EQ(ret, 0); + ret = limitWrite(limitTestPath.c_str(), buffer); + EXPECT_NE(ret, -1); + pid = clone(CloneOne, stack, 0, NULL); + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + ret = WIFEXITED(status); + ASSERT_EQ(ret, 0); + + (void)memset_s(buf, sizeof(buf), 0, sizeof(buf)); + ret = ReadFile(usageTestPath.c_str(), buf); + EXPECT_NE(ret, -1); + printf("%s: %s\n", usageTestPath.c_str(), buf); + + ret = rmdir(path.c_str()); + EXPECT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_memory_002.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_memory_002.cpp new file mode 100644 index 00000000..b9b2478d --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_memory_002.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_process_plimits.h" + +static char *testStr1 = nullptr; + +static int limitWrite(const char *filepath, const char *buf) +{ + int fd = open(filepath, O_WRONLY); + size_t ret = write(fd, buf, strlen(buf)); + close(fd); + return ret; +} + +static int CloneOne(void *arg) +{ + const unsigned int testSize = 1153; + + testStr1 = (char *)malloc(testSize); + EXPECT_STRNE(testStr1, NULL); + + (void)memset_s(testStr1, testSize, 1, testSize); + free(testStr1); + testStr1 = nullptr; + return 0; +} +void ItProcessPlimitsMemory002(void) +{ + mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; + int ret, pid, status; + std::string path = "/proc/plimits/test"; + std::string limitTestPath = "/proc/plimits/test/memory.limit"; + std::string usageTestPath = "/proc/plimits/test/memory.stat"; + char buf[512]; + const char *buffer = "10485760"; + int twoM = 2 * 1024 * 1024; + + char *stack = (char *)mmap(NULL, twoM, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); + EXPECT_STRNE(stack, NULL); + ret = access(path.c_str(), 0); + EXPECT_EQ(ret, -1); + ret = mkdir(path.c_str(), S_IFDIR | mode); + EXPECT_EQ(ret, 0); + ret = limitWrite(limitTestPath.c_str(), buffer); + EXPECT_NE(ret, -1); + pid = clone(CloneOne, stack, 0, NULL); + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); + + (void)memset_s(buf, sizeof(buf), 0, sizeof(buf)); + ret = ReadFile(usageTestPath.c_str(), buf); + EXPECT_NE(ret, -1); + printf("%s: %s\n", usageTestPath.c_str(), buf); + + ret = rmdir(path.c_str()); + EXPECT_EQ(ret, 0); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_pid_001.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_pid_001.cpp new file mode 100644 index 00000000..592aa6f2 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_pid_001.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include "It_process_plimits.h" + +static int g_pidGroup[10] = {0}; +static int g_index = 0; +static int g_sleepTime = 5; + +static int PidWrite(const char *filepath, char *buf) +{ + int fd = open(filepath, O_WRONLY); + if (fd <= 0) { + return 2; /* 2: errno */ + } + size_t ret = write(fd, buf, strlen(buf)); + if (ret < 0) { + printf("filepath: %s buf: %s, errno=%d\n", filepath, buf, errno); + } + close(fd); + return ret; +} + +static int PidFork(const char *filepath, int index) +{ + pid_t fpid = fork(); + if (fpid == 0) { // children proc + sleep(g_sleepTime); + exit(0); + } else if (fpid > 0) { + g_pidGroup[index] = fpid; + return 0; + } + return -1; +} + +void ItProcessPlimitsPid001(void) +{ + mode_t mode = 0; + int status; + const char *pidMaxPath = "/proc/plimits/test/pids.max"; + const char *procsPath = "/proc/plimits/test/plimits.procs"; + std::string path = "/proc/plimits/test"; + char writeBuf[3]; + int i = 0; + int pidnum = 5; + int mainpid = getpid(); + int ret = mkdir(path.c_str(), S_IFDIR | mode); + ASSERT_EQ(ret, 0); + + (void)memset_s(writeBuf, sizeof(writeBuf), 0, sizeof(writeBuf)); + ret = sprintf_s(writeBuf, sizeof(writeBuf), "%d", pidnum); + ASSERT_NE(ret, -1); + ret = PidWrite(pidMaxPath, writeBuf); + ASSERT_NE(ret, -1); + + for (i = g_index; i < pidnum; i++) { + ret = PidFork(procsPath, i); + if (i != (pidnum - 1)) { + ASSERT_EQ(ret, 0); + } else { + ASSERT_EQ(ret, -1); + } + } + + for (i = 0; i < pidnum - 1; ++i) { + pid_t pid = waitpid(g_pidGroup[i], &status, 0); + ASSERT_EQ(pid, g_pidGroup[i]); + ASSERT_EQ(WEXITSTATUS(status), 0); + } + + ret = rmdir(path.c_str()); + ASSERT_EQ(ret, 0); + return; +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_pid_002.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_pid_002.cpp new file mode 100644 index 00000000..65ac2eb0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_pid_002.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include "It_process_plimits.h" + +static int g_pidGroup[10] = {0}; +static int g_index = 0; +static int g_sleepTime = 5; + +static int PidWrite(const char *filepath, char *buf) +{ + int fd = open(filepath, O_WRONLY); + size_t ret = write(fd, buf, strlen(buf)); + close(fd); + return ret; +} + +static void PidFork(int index) +{ + pid_t fpid = fork(); + if (fpid == 0) { // children proc + sleep(g_sleepTime); + exit(0); + } else if (fpid > 0) { + g_pidGroup[index] = fpid; + return; + } +} + +void ItProcessPlimitsPid002(void) +{ + mode_t mode = 0; + int status; + const char *pidMaxPath = "/proc/plimits/test/pids.max"; + const char *procsPath = "/proc/plimits/test/plimits.procs"; + std::string path = "/proc/plimits/test"; + char writeBuf[3]; + int num = 4; + int i = 0; + pid_t fpid; + int pidnum = 5; + int ret = mkdir(path.c_str(), S_IFDIR | mode); + ASSERT_EQ(ret, 0); + + (void)memset_s(writeBuf, sizeof(writeBuf), 0, sizeof(writeBuf)); + ret = sprintf_s(writeBuf, sizeof(writeBuf), "%d", pidnum); + ASSERT_NE(ret, -1); + ret = PidWrite(pidMaxPath, writeBuf); + ASSERT_NE(ret, -1); + + (void)memset_s(writeBuf, sizeof(writeBuf), 0, sizeof(writeBuf)); + ret = sprintf_s(writeBuf, sizeof(writeBuf), "%d", getpid()); + ASSERT_NE(ret, -1); + ret = PidWrite(procsPath, writeBuf); + ASSERT_NE(ret, -1); + + for (i = g_index; i < num; ++i) { + PidFork(i); + } + g_index = i; + fpid = fork(); + if (fpid == 0) { + exit(0); + } else if (fpid > 0) { + waitpid(fpid, &status, 0); + } + + for (i = 0; i < g_index; ++i) { + waitpid(g_pidGroup[i], &status, 0); + ASSERT_EQ(WEXITSTATUS(status), 0); + } + ret = rmdir(path.c_str()); + ASSERT_EQ(ret, 0); + return; +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_pid_003.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_pid_003.cpp new file mode 100644 index 00000000..f29181f8 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_pid_003.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include "It_process_plimits.h" + +static int PidWrite(const char *filepath, char *buf) +{ + int fd = open(filepath, O_WRONLY); + size_t ret = write(fd, buf, strlen(buf)); + close(fd); + return ret; +} + +void ItProcessPlimitsPid003(void) +{ + mode_t mode = 0; + int status; + struct sched_param param = { 0 }; + const char *pidMaxPath = "/proc/plimits/test/pids.priority"; + std::string path = "/proc/plimits/test"; + char writeBuf[3]; + int pidnum = 15; /* 15: priority limit */ + int ret = mkdir(path.c_str(), S_IFDIR | mode); + ASSERT_EQ(ret, 0); + + (void)memset_s(writeBuf, sizeof(writeBuf), 0, sizeof(writeBuf)); + ret = sprintf_s(writeBuf, sizeof(writeBuf), "%d", pidnum); + ASSERT_NE(ret, -1); + + ret = PidWrite(pidMaxPath, writeBuf); + ASSERT_NE(ret, -1); + + int currProcessPri = getpriority(PRIO_PROCESS, getpid()); + + param.sched_priority = pidnum - 1; + ret = sched_setscheduler(getpid(), SCHED_RR, ¶m); + ASSERT_NE(ret, 0); + + ret = setpriority(PRIO_PROCESS, getpid(), param.sched_priority); + ASSERT_NE(ret, 0); + + ret = sched_setparam(getpid(), ¶m); + ASSERT_NE(ret, 0); + + param.sched_priority = currProcessPri + 1; + ret = sched_setscheduler(getpid(), SCHED_RR, ¶m); + ASSERT_EQ(ret, 0); + + param.sched_priority++; + ret = setpriority(PRIO_PROCESS, getpid(), param.sched_priority); + ASSERT_EQ(ret, 0); + + param.sched_priority++; + ret = sched_setparam(getpid(), ¶m); + ASSERT_EQ(ret, 0); + + ret = rmdir(path.c_str()); + ASSERT_EQ(ret, 0); + return; +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_pid_004.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_pid_004.cpp new file mode 100644 index 00000000..246921b4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_pid_004.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include "It_process_plimits.h" + +void ItProcessPlimitsPid004(void) +{ + mode_t mode = 0; + int ret; + const char *res = nullptr; + const size_t BUFFER_SIZE = 512; + std::string path = "/proc/plimits/test"; + DIR *dirp = opendir("/proc/plimits"); + ASSERT_NE(dirp, nullptr); + closedir(dirp); + + ret = mkdir(path.c_str(), S_IFDIR | mode); + ASSERT_EQ(ret, 0); + + char buff[BUFFER_SIZE] = {0}; + ret = ReadFile("/proc/plimits/pids.max", buff); + res = strstr(buff, "64"); + ASSERT_STRNE(res, nullptr); + (void)memset_s(buff, BUFFER_SIZE, 0, BUFFER_SIZE); + + ret = ReadFile("/proc/plimits/test/pids.max", buff); + res = strstr(buff, "64"); + ASSERT_STRNE(res, nullptr); + ret = rmdir(path.c_str()); + ASSERT_EQ(ret, 0); + return; +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_pid_005.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_pid_005.cpp new file mode 100644 index 00000000..a5a1cf5a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_pid_005.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "It_process_plimits.h" + +static int g_processOs = 8; + +void ItProcessPlimitsPid005(void) +{ + mode_t mode = 0; + std::string path = "/proc/plimits/test"; + std::string filepath = "/proc/plimits/test/plimits.procs"; + int pid = getpid(); + int vprocessId = 90; + std::string missPid = std::to_string(vprocessId); + std::string runPid = std::to_string(pid); + + int ret = mkdir(path.c_str(), S_IFDIR | mode); + ASSERT_EQ(ret, 0); + + int fd = open(filepath.c_str(), O_WRONLY); + ASSERT_NE(fd, -1); + + for (int i = 1; i <= g_processOs; i++) { + std::string fWrite = std::to_string(i); + ret = write(fd, fWrite.c_str(), (fWrite.length())); + ASSERT_EQ(ret, -1); + } + + ret = write(fd, missPid.c_str(), (missPid.length())); + ASSERT_EQ(ret, -1); + + ret = write(fd, path.c_str(), (path.length())); + ASSERT_EQ(ret, -1); + + ret = write(fd, runPid.c_str(), (runPid.length())); + ASSERT_NE(ret, -1); + close(fd); + ret = rmdir(path.c_str()); + ASSERT_EQ(ret, 0); + return; +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_pid_006.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_pid_006.cpp new file mode 100644 index 00000000..4e612a32 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_pid_006.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include "It_process_plimits.h" + +void ItProcessPlimitsPid006(void) +{ + mode_t mode = 0; + int ret; + const char *res = nullptr; + const size_t BUFFER_SIZE = 512; + std::string path = "/proc/plimits/test"; + DIR *dirp = opendir("/proc/plimits"); + ASSERT_NE(dirp, nullptr); + closedir(dirp); + + ret = mkdir(path.c_str(), S_IFDIR | mode); + ASSERT_EQ(ret, 0); + + char buff[BUFFER_SIZE] = {0}; + ret = ReadFile("/proc/plimits/pids.max", buff); + res = strstr(buff, "64"); + ASSERT_STRNE(res, nullptr); + (void)memset_s(buff, BUFFER_SIZE, 0, BUFFER_SIZE); + + ret = ReadFile("/proc/plimits/test/pids.max", buff); + res = strstr(buff, "64"); + ASSERT_STRNE(res, nullptr); + ret = rmdir(path.c_str()); + ASSERT_EQ(ret, 0); + return; +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_sched_001.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_sched_001.cpp new file mode 100644 index 00000000..85ea5489 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_sched_001.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_process_plimits.h" + +using namespace std; + +VOID ItProcessPlimitsSched001(void) +{ + const int childAmount = 1; + double errorRate = TestCpupInPlimit(childAmount, "testcpup101", PERIOD_10_SEC_IN_US, + QUOTA_2_SEC_IN_US, QUOTA_PERCENT_20); + ASSERT_GE(errorRate, 0); + ASSERT_LE(errorRate, TOLERANCE_ERROR); +} + diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_sched_002.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_sched_002.cpp new file mode 100644 index 00000000..a46fb3ca --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_sched_002.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_process_plimits.h" + +using namespace std; + +VOID ItProcessPlimitsSched002(void) +{ + const int childAmount = 1; + double errorRate = TestCpupInPlimit(childAmount, "testcpup102", PERIOD_10_SEC_IN_US, + QUOTA_6_SEC_IN_US, QUOTA_PERCENT_60); + ASSERT_GE(errorRate, 0); + ASSERT_LE(errorRate, TOLERANCE_ERROR); +} + diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_sched_003.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_sched_003.cpp new file mode 100644 index 00000000..e3d87374 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_sched_003.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_process_plimits.h" + +using namespace std; + +VOID ItProcessPlimitsSched003(void) +{ + const int childAmount = 1; + double errorRate = TestCpupInPlimit(childAmount, "testcpup104", PERIOD_10_SEC_IN_US, + QUOTA_10_SEC_IN_US, QUOTA_PERCENT_100); + ASSERT_GE(errorRate, 0); + ASSERT_LE(errorRate, TOLERANCE_ERROR); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_sched_004.cpp b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_sched_004.cpp new file mode 100644 index 00000000..7e6d0d71 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/process/plimits/smoke/It_process_plimits_sched_004.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_process_plimits.h" + +using namespace std; + +VOID ItProcessPlimitsSched004(void) +{ + const int childAmount = 2; + double errorRate = TestCpupInPlimit(childAmount, "testcpup105", PERIOD_10_SEC_IN_US, + QUOTA_10_SEC_IN_US, QUOTA_PERCENT_100); + ASSERT_GE(errorRate, 0); + ASSERT_LE(errorRate, TOLERANCE_ERROR); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/security/BUILD.gn b/src/kernel_liteos_a/testsuites/unittest/security/BUILD.gn new file mode 100644 index 00000000..348066ee --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/security/BUILD.gn @@ -0,0 +1,56 @@ +# Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("./config.gni") + +if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_LOW) { + unittest("liteos_a_security_unittest_door") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + include_dirs = common_include_dirs + sources = sources_entry + sources += sources_smoke + sources_full = [] + sources += sources_full + configs = [ "..:public_config_for_door" ] + deps = [ "$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR:libsec_shared" ] + } +} + +if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_MIDDLE) { + unittest("liteos_a_security_unittest") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + include_dirs = common_include_dirs + sources = sources_entry + sources += sources_smoke + sources += sources_full + configs = [ "..:public_config_for_all" ] + deps = [ "$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR:libsec_shared" ] + } +} diff --git a/src/kernel_liteos_a/testsuites/unittest/security/capability/config.gni b/src/kernel_liteos_a/testsuites/unittest/security/capability/config.gni new file mode 100644 index 00000000..85386ee7 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/security/capability/config.gni @@ -0,0 +1,39 @@ +# Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +capability_include_dirs = [ "$TEST_UNITTEST_DIR/security/capability" ] + +capability_sources_entry = + [ "$TEST_UNITTEST_DIR/security/capability/security_capability_test.cpp" ] + +capability_sources_smoke = + [ "$TEST_UNITTEST_DIR/security/capability/smoke/cap_test_001.cpp" ] + +capability_sources_full = [] diff --git a/src/kernel_liteos_a/testsuites/unittest/security/capability/it_test_capability.h b/src/kernel_liteos_a/testsuites/unittest/security/capability/it_test_capability.h new file mode 100644 index 00000000..bd09554a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/security/capability/it_test_capability.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _IT_TEST_SECURITY_CAPABILITY_H +#define _IT_TEST_SECURITY_CAPABILITY_H + +#include "osTest.h" + +VOID ItSuite_Security_Capbility(VOID); +extern void ItTestCap001(void); + +#endif diff --git a/src/kernel_liteos_a/testsuites/unittest/security/capability/security_capability_test.cpp b/src/kernel_liteos_a/testsuites/unittest/security/capability/security_capability_test.cpp new file mode 100644 index 00000000..4ed9c5f1 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/security/capability/security_capability_test.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "stdio.h" +#include +#include + +#include "it_test_capability.h" + +using namespace testing::ext; +namespace OHOS { +class SecurityCapabilityTest : public testing::Test { +public: + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} +}; + +#if defined(LOSCFG_USER_TEST_SMOKE) +/** + * @tc.name: It_Test_Cap_001 + * @tc.desc: function for SecurityCapbilityTest + * @tc.type: FUNC + */ +HWTEST_F(SecurityCapabilityTest, ItTestCap001, TestSize.Level0) +{ + ItTestCap001(); +} +#endif +} // namespace OHOS diff --git a/src/kernel_liteos_a/testsuites/unittest/security/capability/smoke/cap_test_001.cpp b/src/kernel_liteos_a/testsuites/unittest/security/capability/smoke/cap_test_001.cpp new file mode 100644 index 00000000..f8887989 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/security/capability/smoke/cap_test_001.cpp @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "pthread.h" +#include "linux/capability.h" +#include +#include "it_test_capability.h" +#include +#include +#include + +#define CAP_NUM 2 +#define INVAILD_PID 65535 +#define CHANGE_CHILD_UID 1000 + +static void Sigac(int param) +{ + return; +} + +static void Child() +{ + int i = 10; + signal(25, Sigac); + + while (i--) { + sleep(1); + } + exit(0); +} + +static int TestChild(VOID) +{ + struct __user_cap_header_struct capheader; + struct __user_cap_data_struct capdata[CAP_NUM]; + struct __user_cap_data_struct capdatac[CAP_NUM]; + struct timespec tp; + int ret; + + (void)memset_s(&capheader, sizeof(struct __user_cap_header_struct), 0, sizeof(struct __user_cap_header_struct)); + (void)memset_s(capdata, CAP_NUM * sizeof(struct __user_cap_data_struct), 0, + CAP_NUM * sizeof(struct __user_cap_data_struct)); + capdata[0].permitted = 0xffffffff; + capdata[1].permitted = 0xffffffff; + capheader.version = _LINUX_CAPABILITY_VERSION_3; + capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective |= CAP_TO_MASK(CAP_SETPCAP); + capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective |= CAP_TO_MASK(CAP_SETUID); + capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective |= CAP_TO_MASK(CAP_KILL); + capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective |= CAP_TO_MASK(CAP_SYS_TIME); + capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective |= CAP_TO_MASK(CAP_SYS_NICE); + ret = capset(&capheader, &capdata[0]); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = capget(&capheader, &capdatac[0]); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + capheader.pid = INVAILD_PID; + ret = capget(&capheader, &capdatac[0]); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + errno = 0; + capheader.pid = 3; + kill(capheader.pid, 0); + if (errno != ESRCH) { + ret = capget(&capheader, &capdatac[0]); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + printf("e %d,p %d\n", capdatac[0].effective, capdatac[0].permitted); + } + errno = 0; + capheader.pid = 4; + kill(capheader.pid, 0); + if (errno != ESRCH) { + ret = capget(&capheader, &capdatac[0]); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + printf("e %d,p %d\n", capdatac[0].effective, capdatac[0].permitted); + } + errno = 0; + capheader.pid = 5; + kill(capheader.pid, 0); + if (errno != ESRCH) { + ret = capget(&capheader, &capdatac[0]); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + printf("e %d,p %d\n", capdatac[0].effective, capdatac[0].permitted); + } + errno = 0; + capheader.pid = 6; + kill(capheader.pid, 0); + if (errno != ESRCH) { + ret = capget(&capheader, &capdatac[0]); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + printf("e %d,p %d\n", capdatac[0].effective, capdatac[0].permitted); + } + capheader.pid = 0; + + int pid = fork(); + if (pid == 0) { + ret = setuid(CHANGE_CHILD_UID); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + Child(); + } + sleep(1); + ret = kill(pid, SIGXFSZ); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective &= ~CAP_TO_MASK(CAP_KILL); + ret = capset(&capheader, &capdata[0]); + ret = kill(pid, SIGXFSZ); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + + tp.tv_sec = 0; + tp.tv_nsec = 0; + ret = clock_settime(CLOCK_REALTIME, &tp); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective &= ~CAP_TO_MASK(CAP_SYS_TIME); + ret = capset(&capheader, &capdata[0]); + ret = clock_settime(CLOCK_REALTIME, &tp); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + + struct sched_param param = { 0 }; + ret = sched_getparam(pid, ¶m); + param.sched_priority--; + ret = sched_setparam(pid, ¶m); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective &= ~CAP_TO_MASK(CAP_SYS_NICE); + ret = capset(&capheader, &capdata[0]); + ret = sched_setparam(pid, ¶m); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + wait(nullptr); + exit(92); + + return 0; +} + +static int TestCase(VOID) +{ + int ret; + int status = 0; + pid_t pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); + if (pid == 0) { + ret = TestChild(); + exit(__LINE__); + } + + ret = waitpid(pid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 92, status, EXIT); + + return 0; + +EXIT: + return 1; +} + +void ItTestCap001(void) +{ + TEST_ADD_CASE("IT_SEC_CAP_001", TestCase, TEST_POSIX, TEST_SEC, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/security/config.gni b/src/kernel_liteos_a/testsuites/unittest/security/config.gni new file mode 100644 index 00000000..2f82731e --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/security/config.gni @@ -0,0 +1,69 @@ +# Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//build/lite/config/test.gni") +import("//kernel/liteos_a/liteos.gni") +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +common_include_dirs = [ + "$THIRDPARTY_GOOGLETEST_DIR/googletest/include", + "../common/include", +] + +sources_entry = [ "../common/osTest.cpp" ] + +sources_smoke = [] + +sources_full = [] + +# capability module +if (LOSCFG_USER_TEST_SECURITY_CAPABILITY == true) { + import("./capability/config.gni") + common_include_dirs += capability_include_dirs + sources_entry += capability_sources_entry + sources_smoke += capability_sources_smoke + sources_full += capability_sources_full +} + +# reugid module +if (LOSCFG_USER_TEST_SECURITY_REUGID == true) { + import("./reugid/config.gni") + common_include_dirs += reugid_include_dirs + sources_entry += reugid_sources_entry + sources_smoke += reugid_sources_smoke + sources_full += reugid_sources_full +} + +# vid module +if (LOSCFG_USER_TEST_SECURITY_VID == true) { + import("./vid/config.gni") + common_include_dirs += vid_include_dirs + sources_entry += vid_sources_entry + sources_smoke += vid_sources_smoke + sources_full += vid_sources_full +} diff --git a/src/kernel_liteos_a/testsuites/unittest/security/reugid/config.gni b/src/kernel_liteos_a/testsuites/unittest/security/reugid/config.gni new file mode 100644 index 00000000..41ac9536 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/security/reugid/config.gni @@ -0,0 +1,39 @@ +# Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +reugid_include_dirs = [ "$TEST_UNITTEST_DIR/security/reugid" ] + +reugid_sources_entry = + [ "$TEST_UNITTEST_DIR/security/reugid/security_reugid_test.cpp" ] + +reugid_sources_smoke = + [ "$TEST_UNITTEST_DIR/security/reugid/smoke/reugid_test_001.cpp" ] + +reugid_sources_full = [] diff --git a/src/kernel_liteos_a/testsuites/unittest/security/reugid/it_test_reugid.h b/src/kernel_liteos_a/testsuites/unittest/security/reugid/it_test_reugid.h new file mode 100644 index 00000000..0acadc8f --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/security/reugid/it_test_reugid.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _IT_TEST_SECURITY_CAPABILITY_H +#define _IT_TEST_SECURITY_CAPABILITY_H + +#include "osTest.h" + +VOID ItSuiteSecurityReugid(VOID); +extern void ItTestReugid001(void); + +#endif diff --git a/src/kernel_liteos_a/testsuites/unittest/security/reugid/security_reugid_test.cpp b/src/kernel_liteos_a/testsuites/unittest/security/reugid/security_reugid_test.cpp new file mode 100644 index 00000000..63b42115 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/security/reugid/security_reugid_test.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "stdio.h" +#include +#include + +#include "it_test_reugid.h" + +using namespace testing::ext; +namespace OHOS { +class SecurityReugidTest : public testing::Test { +public: + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} +}; + +#if defined(LOSCFG_USER_TEST_SMOKE) +/** + * @tc.name: ItTestReugid001 + * @tc.desc: function for SecurityReugidTest + * @tc.type: FUNC + */ +HWTEST_F(SecurityReugidTest, ItTestReugid001, TestSize.Level0) +{ + ItTestReugid001(); +} +#endif +} // namespace OHOS diff --git a/src/kernel_liteos_a/testsuites/unittest/security/reugid/smoke/reugid_test_001.cpp b/src/kernel_liteos_a/testsuites/unittest/security/reugid/smoke/reugid_test_001.cpp new file mode 100644 index 00000000..bc558a95 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/security/reugid/smoke/reugid_test_001.cpp @@ -0,0 +1,442 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "pthread.h" +#include "linux/capability.h" +#include "it_test_reugid.h" +#include +#include +#include + +static int Child1(int *list, int listSize) +{ + int getList[500]; + int ruid = 0; + int euid = 0; + int suid = 100; + int rgid = 0; + int egid = 0; + int sgid = 100; + int ret; + + rgid = getgid(); + ICUNIT_ASSERT_EQUAL(rgid, 300, rgid); + egid = getegid(); + ICUNIT_ASSERT_EQUAL(egid, 300, egid); + + ret = getresgid(reinterpret_cast(&ruid), reinterpret_cast(&euid), + reinterpret_cast(&suid)); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(ruid, 300, ruid); // 300: expected ruid + ICUNIT_ASSERT_EQUAL(euid, 300, euid); // 300: expected euid + ICUNIT_ASSERT_EQUAL(suid, 300, suid); + + ruid = getuid(); + ICUNIT_ASSERT_EQUAL(ruid, 300, ruid); + euid = geteuid(); + ICUNIT_ASSERT_EQUAL(euid, 300, euid); + + ret = getresuid(reinterpret_cast(&ruid), reinterpret_cast(&euid), + reinterpret_cast(&suid)); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(ruid, 300, ruid); // 300: expected ruid + ICUNIT_ASSERT_EQUAL(euid, 300, euid); + ICUNIT_ASSERT_EQUAL(suid, 300, suid); + + int size = getgroups(0, reinterpret_cast(getList)); + ICUNIT_ASSERT_EQUAL(size, listSize, size); + + size = getgroups(size, reinterpret_cast(getList)); + ICUNIT_ASSERT_EQUAL(size, listSize, size); + for (int i = 0; i < size - 1; i++) { + ICUNIT_ASSERT_EQUAL(getList[i], list[i], getList[i]); + } + + getList[size - 1] = 500; + ret = setgroups(0, reinterpret_cast(getList)); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = getgroups(0, NULL); + ICUNIT_ASSERT_EQUAL(ret, 1, ret); + + ret = getgroups(ret, reinterpret_cast(getList)); + ICUNIT_ASSERT_EQUAL(ret, 1, ret); + ICUNIT_ASSERT_EQUAL(getList[0], getgid(), getList[0]); + + exit(255); +} + +static int Child(void) +{ + int size; + int ret; + int list[500]; + int getList[500]; + int ruid = 0; + int euid = 0; + int suid = 100; + int rgid = 0; + int egid = 0; + int sgid = 100; + + ret = setgid(3000); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = getgid(); + ICUNIT_ASSERT_EQUAL(ret, 3000, ret); + ret = getegid(); + ICUNIT_ASSERT_EQUAL(ret, 3000, ret); // 3000: expected egid + + ret = setegid(3000); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = getgid(); + ICUNIT_ASSERT_EQUAL(ret, 3000, ret); + ret = getegid(); + ICUNIT_ASSERT_EQUAL(ret, 3000, ret); + + ret = setgid(-1); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno); + ret = setegid(-2); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno); + + list[0] = 1000; // 1000: preset value of list[0] + list[1] = 2000; // 2000: preset value of list[1] + list[2] = 3000; // 3000: preset value of list[2] + list[3] = 4000; // 4000: preset value of list[3] + list[4] = 5000; // 5000: preset value of list[4] + ret = setgroups(5, reinterpret_cast(list)); // 5: set groupid for testing + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + size = getgroups(0, reinterpret_cast(getList)); + ICUNIT_ASSERT_EQUAL(size, 5, size); + + size = getgroups(size, reinterpret_cast(getList)); + ICUNIT_ASSERT_EQUAL(size, 5, size); + + for (int i = 0; i < size; i++) { + ICUNIT_ASSERT_EQUAL(getList[i], list[i], getList[i]); + } + + list[0] = 1000; // 1000: preset value of list[0] + list[1] = 2000; // 2000: preset value of list[1] + list[2] = 6000; // 6000: preset value of list[2] + list[3] = 4000; // 4000: preset value of list[3] + list[4] = 5000; // 5000: preset value of list[4] + list[5] = -1; + ret = setgroups(6, reinterpret_cast(list)); // 6: set groupid for testing + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno); + + list[0] = 1000; // 1000: preset value of list[0] + list[1] = 2000; // 2000: preset value of list[1] + list[2] = 6000; // 6000: preset value of list[2] + list[3] = 4000; // 4000: preset value of list[3] + list[4] = 5000; // 5000: preset value of list[4] + list[5] = 7000; + ret = setgroups(6, reinterpret_cast(list)); // 6: set groupid for testing + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + size = getgroups(0, reinterpret_cast(getList)); + ICUNIT_ASSERT_EQUAL(size, 7, size); + + size = getgroups(0, NULL); + ICUNIT_ASSERT_EQUAL(size, 7, size); + + size = getgroups(size, reinterpret_cast(getList)); + ICUNIT_ASSERT_EQUAL(size, 7, size); + for (int i = 0; i < size - 1; i++) { + ICUNIT_ASSERT_EQUAL(getList[i], list[i], getList[i]); + } + + ICUNIT_ASSERT_EQUAL(getList[size - 1], getgid(), getList[size - 1]); + + ret = seteuid(8000); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = geteuid(); + ICUNIT_ASSERT_EQUAL(ret, 8000, ret); // 8000: expected value of euid + + ret = setuid(2000); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = geteuid(); + ICUNIT_ASSERT_EQUAL(ret, 2000, ret); + ret = getuid(); + ICUNIT_ASSERT_EQUAL(ret, 2000, ret); + + ret = setuid(-1); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno); + ret = seteuid(-2); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno); + + ret = setregid(5000, 300); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(EPERM, errno, errno); + + ret = setregid(5000, 5000); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = getgid(); + ICUNIT_ASSERT_EQUAL(ret, 5000, ret); // 5000: expected value of gid + egid = getegid(); + ICUNIT_ASSERT_EQUAL(egid, 5000, egid); // 5000: expected value of egid + + ret = setregid(5000, -1); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = getgid(); + ICUNIT_ASSERT_EQUAL(ret, 5000, ret); // 5000: expected value of gid + egid = getegid(); + ICUNIT_ASSERT_EQUAL(egid, 5000, egid); // 5000: expected value of egid + + ret = setregid(3000, -2); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno); + + ret = setregid(-5, -2); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno); + + ret = setregid(3000, -1); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = getgid(); + ICUNIT_ASSERT_EQUAL(ret, 3000, ret); // 3000: expected value of gid + egid = getegid(); + ICUNIT_ASSERT_EQUAL(egid, 3000, egid); // 3000: expected value of egid + + ret = setreuid(1000, 3000); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(EPERM, errno, errno); + + ret = setreuid(1000, -2); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno); + + ret = setreuid(-2, -2); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno); + + ret = setreuid(-1, 3000); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ruid = getuid(); + ICUNIT_ASSERT_EQUAL(ruid, 3000, ruid); // 3000: expected value of ruid + euid = geteuid(); + ICUNIT_ASSERT_EQUAL(euid, 3000, euid); // 3000: expected value of euid + + ret = setreuid(1000, -1); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ruid = getuid(); + ICUNIT_ASSERT_EQUAL(ruid, 1000, ruid); // 1000: expected value of ruid + euid = geteuid(); + ICUNIT_ASSERT_EQUAL(euid, 1000, euid); // 1000: expected value of euid + + ret = setresuid(100, 100, 100); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = getresuid(reinterpret_cast(&ruid), reinterpret_cast(&euid), + reinterpret_cast(&suid)); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(ruid, 100, ruid); + ICUNIT_ASSERT_EQUAL(euid, 100, euid); // 100: expected value of euid + ICUNIT_ASSERT_EQUAL(suid, 100, suid); + + ret = setresuid(200, 100, 100); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(EPERM, errno, errno); + + ret = setresuid(100, 100, 200); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(EPERM, errno, errno); + + ret = setresuid(100, 200, 200); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(EPERM, errno, errno); + + ret = setresuid(-1, 200, 200); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = getresuid(reinterpret_cast(&ruid), reinterpret_cast(&euid), + reinterpret_cast(&suid)); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(ruid, 200, ruid); // 200: expected value of ruid + ICUNIT_ASSERT_EQUAL(euid, 200, euid); + ICUNIT_ASSERT_EQUAL(suid, 200, suid); + + ret = setresuid(-1, -1, 300); // set saved-set user id to 300 + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = getresuid(reinterpret_cast(&ruid), reinterpret_cast(&euid), + reinterpret_cast(&suid)); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(ruid, 300, ruid); + ICUNIT_ASSERT_EQUAL(euid, 300, euid); // 300: expected value of euid + ICUNIT_ASSERT_EQUAL(suid, 300, suid); + + ret = setresuid(-1, 200, 300); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ret = setresuid(-1, -2, 200); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno); + + ret = setresuid(-2, 200, 200); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno); + + ret = setresuid(200, -2, 200); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno); + + ret = setresuid(200, 200, -3); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno); + + ret = setresgid(100, 100, 100); // 100: value of rgid, egid and sgid + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = getresgid(reinterpret_cast(&rgid), reinterpret_cast(&egid), + reinterpret_cast(&sgid)); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(rgid, 100, rgid); + ICUNIT_ASSERT_EQUAL(egid, 100, egid); + ICUNIT_ASSERT_EQUAL(sgid, 100, sgid); // 100: expected value of sgid + + ret = setresgid(200, 100, 100); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(EPERM, errno, errno); + + ret = setresgid(100, 100, 200); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(EPERM, errno, errno); + + ret = setresgid(100, 200, 200); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(EPERM, errno, errno); + + ret = setresgid(-2, 100, 200); // set rgid to -2, egid to 100, sgid to 200 + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno); + ret = setresgid(100, -2, 200); // set rgid to 100, egid to -2, sgid to 200 + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno); + ret = setresgid(100, 100, -2); // set rgid and egid to 100, rgid to -2 + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno); + ret = setresgid(100, -1, -2); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno); + ret = setresgid(-1, 200, 200); // 200: value of egid and sgid + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = getresgid(reinterpret_cast(&rgid), reinterpret_cast(&egid), + reinterpret_cast(&sgid)); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(rgid, 200, rgid); // 200: expected value of rgid + ICUNIT_ASSERT_EQUAL(egid, 200, egid); // 200: expected value of egid + ICUNIT_ASSERT_EQUAL(sgid, 200, sgid); // 200: expected value of sgid + + ret = setresgid(-1, -1, 300); // set sgid to 300 + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = getresgid(reinterpret_cast(&rgid), reinterpret_cast(&egid), + reinterpret_cast(&sgid)); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ICUNIT_ASSERT_EQUAL(rgid, 300, rgid); + ICUNIT_ASSERT_EQUAL(egid, 300, egid); + ICUNIT_ASSERT_EQUAL(sgid, 300, sgid); + + ret = setresgid(-1, 200, 300); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(EPERM, errno, errno); + + size = getgroups(0, reinterpret_cast(getList)); + size = getgroups(size, reinterpret_cast(getList)); + pid_t pid = fork(); + if (pid == 0) { + Child1(getList, size); + exit(__LINE__); + } + + int status = 0; + ret = waitpid(pid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); + + ret = setgroups(0, NULL); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = getgroups(0, reinterpret_cast(getList)); + ICUNIT_ASSERT_EQUAL(ret, 1, ret); + + ret = getgroups(1, reinterpret_cast(getList)); + ICUNIT_ASSERT_EQUAL(ret, 1, ret); + ICUNIT_ASSERT_EQUAL(getList[0], getgid(), getList[0]); + + ret = setreuid(-1, -1); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = setregid(-1, -1); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = setresuid(-1, -1, -1); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = setresuid(-1, -1, -1); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + ret = setegid(-1); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno); + ret = seteuid(-1); + ICUNIT_ASSERT_EQUAL(ret, -1, ret); + ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno); + + exit(255); + +EXIT: + return 1; +} + +static int TestCase(VOID) +{ + int ret; + int status = 0; + pid_t pid = fork(); + ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // assume pid is between 0 and 100000 + if (pid == 0) { + ret = Child(); + exit(__LINE__); + } + + ret = waitpid(pid, &status, 0); + ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT); + status = WEXITSTATUS(status); + ICUNIT_GOTO_EQUAL(status, 255, status, EXIT); + + return 0; + +EXIT: + return 1; +} + +void ItTestReugid001(void) +{ + TEST_ADD_CASE("IT_SEC_UGID_001", TestCase, TEST_POSIX, TEST_SEC, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/security/vid/config.gni b/src/kernel_liteos_a/testsuites/unittest/security/vid/config.gni new file mode 100644 index 00000000..6eaef47a --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/security/vid/config.gni @@ -0,0 +1,37 @@ +# Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +vid_include_dirs = [ "$TEST_UNITTEST_DIR/security/vid" ] + +vid_sources_entry = [ "$TEST_UNITTEST_DIR/security/vid/security_vid_test.cpp" ] + +vid_sources_smoke = [ "$TEST_UNITTEST_DIR/security/vid/smoke/vid_test_001.cpp" ] + +vid_sources_full = [] diff --git a/src/kernel_liteos_a/testsuites/unittest/security/vid/it_test_vid.h b/src/kernel_liteos_a/testsuites/unittest/security/vid/it_test_vid.h new file mode 100644 index 00000000..200fa201 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/security/vid/it_test_vid.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _IT_TEST_SECURITY_VID_H +#define _IT_TEST_SECURITY_VID_H + +#define _GNU_SOURCE +#include "osTest.h" +#include +#include "stdio.h" +#include +#include +#include "los_typedef.h" +#include "sched.h" +#include "signal.h" + +extern VOID ItSuite_Security_Vid(VOID); +extern VOID ItSecVid001(VOID); + +#endif diff --git a/src/kernel_liteos_a/testsuites/unittest/security/vid/security_vid_test.cpp b/src/kernel_liteos_a/testsuites/unittest/security/vid/security_vid_test.cpp new file mode 100644 index 00000000..a9fdb4bd --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/security/vid/security_vid_test.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "stdio.h" +#include +#include + +#include "it_test_vid.h" + +using namespace testing::ext; +namespace OHOS { +class SecurityVidTest : public testing::Test { +public: + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} +}; + +#if defined(LOSCFG_USER_TEST_SMOKE) +/** + * @tc.name: It_Sec_Vid_001 + * @tc.desc: function for SecurityVidTest + * @tc.type: FUNC + */ +HWTEST_F(SecurityVidTest, ItSecVid001, TestSize.Level0) +{ + ItSecVid001(); +} +#endif +} // namespace OHOS diff --git a/src/kernel_liteos_a/testsuites/unittest/security/vid/smoke/vid_test_001.cpp b/src/kernel_liteos_a/testsuites/unittest/security/vid/smoke/vid_test_001.cpp new file mode 100644 index 00000000..8c099414 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/security/vid/smoke/vid_test_001.cpp @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "it_test_vid.h" +#include "stdio.h" +#include "unistd.h" +#include "sys/stat.h" +#include "time.h" +#include "stdlib.h" + +static VOID TimerFunc(int sig) +{ + return; +} + +static void ChildFunc() +{ + timer_t tid; + struct sigevent ent; + INT32 *ret1 = NULL; + int ret; + struct itimerspec its; + struct itimerspec its2; + timer_t *tid2 = nullptr; + int i = 0; + signal(SIGUSR1, TimerFunc); + ent.sigev_notify = SIGEV_SIGNAL; + ent.sigev_signo = SIGUSR1; + + tid2 = (timer_t *)malloc(sizeof(UINTPTR) * 1024); + if (tid2 == NULL) { + return; + } + ret1 = (int *)malloc(sizeof(int) * 1024); + if (ret1 == NULL) { + free(tid2); + return; + } + (void)memset_s(tid2, sizeof(char *) * 1024, 0, sizeof(char *) * 1024); + (void)memset_s(ret1, sizeof(int) * 1024, 0xff, sizeof(int) * 1024); + while (i < 1024) { + *(ret1 + i) = timer_create(CLOCK_REALTIME, &ent, tid2 + i); + if (*(ret1 + i) == 0) { + ICUNIT_ASSERT_EQUAL_VOID(*(ret1 + i), 0, *(ret1 + i)); + ICUNIT_ASSERT_EQUAL_VOID(i, (int)(*(tid2 + i)), i); + } else { + ICUNIT_ASSERT_EQUAL_VOID(*(ret1 + i), -1, *(ret1 + i)); + } + i++; + } + + i = 0; + while (*(ret1 + i) == 0) { + ret = timer_delete(*(tid2 + i)); + ICUNIT_ASSERT_EQUAL_VOID(ret, 0, ret); + i++; + } + + i = 0; + while (i < 1024) { + *(ret1 + i) = timer_create(CLOCK_REALTIME, &ent, tid2 + i); + if (*(ret1 + i) == 0) { + ICUNIT_ASSERT_EQUAL_VOID(*(ret1 + i), 0, *(ret1 + i)); + ICUNIT_ASSERT_EQUAL_VOID(i, (int)(*(tid2 + i)), i); + } else { + ICUNIT_ASSERT_EQUAL_VOID(*(ret1 + i), -1, *(ret1 + i)); + } + i++; + } + + i = 0; + while (*(ret1 + i) == 0) { + ret = timer_delete(*(tid2 + i)); + ICUNIT_ASSERT_EQUAL_VOID(ret, 0, ret); + i++; + } + + free(tid2); + ret1 = (INT32 *)timer_create(CLOCK_REALTIME, &ent, &tid); + ICUNIT_ASSERT_EQUAL_VOID(ret1, 0, ret1); + + its.it_interval.tv_sec = 1; + its.it_interval.tv_nsec = 0; + its.it_value.tv_sec = 1; + its.it_value.tv_nsec = 0; + ret1 = (INT32 *)timer_settime(tid, 0, &its, NULL); + ICUNIT_ASSERT_EQUAL_VOID(ret1, 0, ret1); + sleep(1); + ret1 = (INT32 *)timer_gettime(tid, &its2); + ICUNIT_ASSERT_EQUAL_VOID(ret1, 0, ret1); + ret1 = (INT32 *)timer_getoverrun(tid); + ret1 = (INT32 *)(((int)(intptr_t)ret1 >= 0) ? 0 : -1); + ICUNIT_ASSERT_EQUAL_VOID(ret1, 0, ret1); + + ret1 = (INT32 *)timer_delete(tid); + ICUNIT_ASSERT_EQUAL_VOID(ret1, 0, ret1); + + exit(static_cast(reinterpret_cast(tid))); +} + +static UINT32 TestCase(VOID) +{ + int pid; + int status = 0; + pid = fork(); + if (pid == 0) { + ChildFunc(); + } + + waitpid(pid, &status, 0); + return 0; +} + +VOID ItSecVid001(VOID) +{ + TEST_ADD_CASE("IT_SEC_VID_001", TestCase, TEST_POSIX, TEST_SEC, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/src/kernel_liteos_a/testsuites/unittest/tools/BUILD.gn b/src/kernel_liteos_a/testsuites/unittest/tools/BUILD.gn new file mode 100644 index 00000000..842065d4 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/tools/BUILD.gn @@ -0,0 +1,38 @@ +# Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//build/lite/config/test.gni") +import("//kernel/liteos_a/liteos.gni") +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +unittest("liteos_unittest_run") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + sources = [ "unittest_tools.cpp" ] + deps = [ "$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR:libsec_shared" ] +} diff --git a/src/kernel_liteos_a/testsuites/unittest/tools/README.md b/src/kernel_liteos_a/testsuites/unittest/tools/README.md new file mode 100644 index 00000000..a3cd21ae --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/tools/README.md @@ -0,0 +1,63 @@ +# LiteOS Unittest tools + +## 介绍 + +可执行程序 ***liteos_unittest_run.bin*** 是为了提升liteos unittest 测试效率的工具。 + +## 使用介绍 + +### 1.使用帮助 + +``` +OHOS # ./liteos_unittest_run.bin --help +Usage: +liteos_unittest_run.bin [testsuites_dir] [options] +options: + -r [1-1000] --- The number of repeated runs of the test program. + -m [smoke/full] --- Run the smoke or full test case in this directory. + -t [case] [args] -t ... --- Runs the specified executable program name. +``` +- testsuites_dir: unittest 用例所在的绝对路径 + +### 2.常见测试场景举例 + +假设单板上单元测试用例位于路径 ***/usr/bin/unittest*** 下。 + +#### 2.1 运行全量用例或smoke用例 + +- smoke命令 +``` +./liteos_unittest_run.bin /usr/bin/unittest -r 10 -m smoke +``` +注: -r 10 表示: smoke用例运行10次, 一般用于压测 + +- 全量命令 +``` +./liteos_unittest_run.bin /usr/bin/unittest -r 10 -m full +``` + +注: -r 10 表示: 全量用例运行10次, 一般用于压测 + +#### 2.2 单或多用例组合运行 + +- 单用例执行命令 +``` +./liteos_unittest_run.bin /usr/bin/unittest -r 10 -t liteos_a_basic_unittest.bin +``` +注: 只运行liteos_a_basic_unittest.bin 用例, 重复10次 + +``` +./liteos_unittest_run.bin /usr/bin/unittest -r 10 -t liteos_a_basic_unittest.bin --gtest_filter=ExcTest.ItTestExc002 +``` +注: 只运行liteos_a_basic_unittest.bin 用例中的ItTestExc002,重复10次 + +- 多用例组合命令 +``` +./liteos_unittest_run.bin /usr/bin/unittest -r 10 -t liteos_a_basic_unittest.bin -t liteos_a_process_basic_pthread_unittest_door.bin +``` +注: 先运行liteos_a_basic_unittest.bin再运行liteos_a_process_basic_pthread_unittest_door.bin, 重复10次。-t 最多5个。 + +``` +./liteos_unittest_run.bin /usr/bin/unittest -r 10 -t liteos_a_basic_unittest.bin --gtest_filter=ExcTest.ItTestExc002 -t liteos_a_process_basic_pthread_unittest_door.bin --gtest_filter=ProcessPthreadTest.ItTestPthread003 +``` +注:先运行liteos_a_basic_unittest.bin的ItTestExc002,再运行liteos_a_process_basic_pthread_unittest_door.bin的ItTestPthread003,重复10次。-t最多5个。 diff --git a/src/kernel_liteos_a/testsuites/unittest/tools/unittest_tools.cpp b/src/kernel_liteos_a/testsuites/unittest/tools/unittest_tools.cpp new file mode 100644 index 00000000..79ba1fe0 --- /dev/null +++ b/src/kernel_liteos_a/testsuites/unittest/tools/unittest_tools.cpp @@ -0,0 +1,468 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +const static int TEST_PATH_MAX = 255; +const static int TEST_PARAM_NUM = 5; +const static int TEST_CASE_MODE_FULL = 0; +const static int TEST_CASE_MODE_SMOKE = 1; +const static int TEST_DEFAULT_CASE_MAX = 5; +const static int TEST_T_PARAM_LEN = 2; +const static unsigned int TEST_CASE_FLAGS_ALL = 1; +const static unsigned int TEST_CASE_FLAGS_SPECIFY = 2; +const static unsigned int TEST_CASE_FAILED_COUNT_MAX = 500; +static unsigned int g_testsuitesCount = 0; +static unsigned int g_testsuitesFailedCount = 0; + +struct TestCase { + char bin[TEST_PATH_MAX]; + char *param[TEST_PARAM_NUM]; + int caseLen; +}; + +struct TestsuitesParam { + char testsuitesBin[TEST_PATH_MAX]; + char testsuitesDir[TEST_PATH_MAX]; + int testsuitesDirLen; + struct TestCase *testCase[TEST_DEFAULT_CASE_MAX]; + int testCaseNum; + int testMode; + int repeat; +}; + +static struct TestsuitesParam g_param; +static char *g_testsuitesFailedCase[TEST_CASE_FAILED_COUNT_MAX]; + +static vector GetAllTestsuites(string testsuitesDir) +{ + vector vFiles; + int suffixLen = strlen(".bin"); + DIR *dir = opendir(testsuitesDir.c_str()); + if (dir == nullptr) { + cout << "opendir " << testsuitesDir << " failed" << endl; + return vFiles; + } + + do { + struct dirent *pDir = readdir(dir); + if (pDir == nullptr) { + break; + } + + if ((strcmp(pDir->d_name, ".") == 0) || (strcmp(pDir->d_name, "..") == 0)) { + continue; + } + + if (pDir->d_type == DT_REG) { + int pathLen = strlen(pDir->d_name); + if (pathLen <= suffixLen) { + continue; + } + if (strcmp(".bin", (char *)(pDir->d_name + (pathLen - suffixLen))) != 0) { + continue; + } + + vFiles.push_back(testsuitesDir + "/" + pDir->d_name); + } + } while (1); + closedir(dir); + return vFiles; +} + +static bool TestsuitesIsSmoke(string testsuite, int fileLen, string smokeTest, int smokeTestLen) +{ + if (fileLen <= smokeTestLen) { + return false; + } + + if (strcmp(smokeTest.c_str(), (char *)(testsuite.c_str() + (fileLen - smokeTestLen))) == 0) { + return true; + } + return false; +} + +static void RunCase(const char *testCase, char *param[]) +{ + int ret; + int size; + int status = 0; + pid_t pid = fork(); + if (pid < 0) { + cout << "fork failed, " << strerror(errno) << endl; + return; + } + + g_testsuitesCount++; + if (pid == 0) { + cout << testCase << ":" << endl; + ret = execve(param[0], param, nullptr); + if (ret != 0) { + cout << "execl: " << testCase << " failed, " << strerror(errno) << endl; + exit(0); + } + } + + ret = waitpid(pid, &status, 0); + if (ret != pid) { + cout << "waitpid failed, " << strerror(errno) << endl; + return; + } + + if (WEXITSTATUS(status) == 0) { + return; + } + + if (g_testsuitesFailedCount >= TEST_CASE_FAILED_COUNT_MAX) { + cout << "[UNITTEST_RUN] Failure cases more than upper limit!\n"; + return; + } + + size = strlen(testCase) + 1; + g_testsuitesFailedCase[g_testsuitesFailedCount] = static_cast(malloc(size)); + if (g_testsuitesFailedCase[g_testsuitesFailedCount] == nullptr) { + cout << "[UNITTEST_RUN] malloc failed!\n"; + return; + } + + if (memcpy_s(g_testsuitesFailedCase[g_testsuitesFailedCount], size, testCase, size) != EOK) { + cout << "[UNITTEST_RUN] memcpy failed!\n"; + return; + } + g_testsuitesFailedCount++; +} + +static void RunAllTestCase(vector files, struct TestsuitesParam *param) +{ + const char *testMode = nullptr; + const char *smokeTest = "door.bin"; + const char *unittestRun = g_param.testsuitesBin; + int unittestRunLen = strlen(unittestRun); + int smokeTestLen = strlen(smokeTest); + char *execParam[TEST_PARAM_NUM]; + + if (param->testMode == TEST_CASE_MODE_SMOKE) { + testMode = "door.bin"; + } else { + testMode = ".bin"; + } + + for (size_t i = 0; i < files.size(); i++) { + int fileLen = strlen(files[i].c_str()); + if (fileLen >= unittestRunLen) { + if (strcmp((char *)(files[i].c_str() + (fileLen - unittestRunLen)), unittestRun) == 0) { + continue; + } + } + + if (strcmp(testMode, smokeTest) == 0) { + if (!TestsuitesIsSmoke(files[i], fileLen, smokeTest, smokeTestLen)) { + continue; + } + } else { + if (TestsuitesIsSmoke(files[i], fileLen, smokeTest, smokeTestLen)) { + continue; + } + } + + (void)memset_s(execParam, sizeof(char *) * TEST_PARAM_NUM, 0, sizeof(char *) * TEST_PARAM_NUM); + execParam[0] = (char *)files[i].c_str(); + RunCase(files[i].c_str(), execParam); + } +} + +static void TestsuitesToolsUsage(void) +{ + cout << "Usage: " << endl; + cout << "liteos_unittest_run.bin [testsuites_dir] [options]" << endl; + cout << "options:" << endl; + cout << " -r [1-1000] --- The number of repeated runs of the test program." << endl; + cout << " -m [smoke/full] --- Run the smoke or full test case in this directory." << endl; + cout << " -t [case] [args] -t ... --- Runs the specified executable program name." << endl; +} + +static int TestsuitesDirFormat(char *testDir, int len) +{ + if (memcpy_s(g_param.testsuitesDir, TEST_PATH_MAX, testDir, len + 1) != EOK) { + cout << "testsuites dir: " << strerror(ENAMETOOLONG) << endl; + return -1; + } + + char *end = g_param.testsuitesDir + len; + while ((testDir != end) && (*end == '/')) { + *end = '\0'; + end--; + len--; + } + + g_param.testsuitesDirLen = len; + if (len <= 0) { + return -1; + } + return 0; +} + +static int GetTestsuitesToolsName(const char *argv[]) +{ + const char *testBin = static_cast(argv[0]); + const char *end = testBin + strlen(testBin); + while (*end != '/') { + end--; + } + end++; + + if (memcpy_s(g_param.testsuitesBin, TEST_PATH_MAX, end, strlen(end)) != EOK) { + cout << "testsuites dir: " << strerror(ENAMETOOLONG) << endl; + return -1; + } + return 0; +} + +static int ParseTestCaseAndParam(int argc, const char *argv[], int *index) +{ + int j; + + (*index)++; + if (*index >= argc) { + return -1; + } + + if (g_param.testCaseNum >= TEST_DEFAULT_CASE_MAX) { + return -1; + } + + g_param.testCase[g_param.testCaseNum] = (struct TestCase *)malloc(sizeof(struct TestCase)); + if (g_param.testCase[g_param.testCaseNum] == nullptr) { + cout << "test case " << strerror(ENOMEM) << endl; + return -1; + } + (void)memset_s(g_param.testCase[g_param.testCaseNum], sizeof(struct TestCase), 0, sizeof(struct TestCase)); + struct TestCase *testCase = g_param.testCase[g_param.testCaseNum]; + testCase->caseLen = strlen(argv[*index]); + if (memcpy_s(testCase->bin, TEST_PATH_MAX, argv[*index], testCase->caseLen + 1) != EOK) { + testCase->caseLen = 0; + cout << "test case " << strerror(ENAMETOOLONG) << endl; + return -1; + } + testCase->param[0] = testCase->bin; + (*index)++; + for (j = 1; (j < TEST_PARAM_NUM) && (*index < argc) && (strncmp("-t", argv[*index], TEST_T_PARAM_LEN) != 0); j++) { + testCase->param[j] = (char *)argv[*index]; + (*index)++; + } + g_param.testCaseNum++; + if (((*index) < argc) && (strncmp("-t", argv[*index], TEST_T_PARAM_LEN) == 0)) { + (*index)--; + } + return 0; +} + +static int TestsuitesParamCheck(int argc, const char *argv[]) +{ + int ret; + unsigned int mask = 0; + g_param.testMode = TEST_CASE_MODE_FULL; + g_param.repeat = 1; + ret = TestsuitesDirFormat((char *)argv[1], strlen(argv[1])); + if (ret < 0) { + return -1; + } + + for (int i = 2; i < argc; i++) { /* 2: param index */ + if (strcmp("-m", argv[i]) == 0) { + i++; + if (i >= argc) { + return -1; + } + mask |= TEST_CASE_FLAGS_ALL; + if (strcmp("smoke", argv[i]) == 0) { + g_param.testMode = TEST_CASE_MODE_SMOKE; + } else if (strcmp("full", argv[i]) == 0) { + g_param.testMode = TEST_CASE_MODE_FULL; + } else { + return -1; + } + } else if (strcmp("-t", argv[i]) == 0) { + mask |= TEST_CASE_FLAGS_SPECIFY; + ret = ParseTestCaseAndParam(argc, argv, &i); + if (ret < 0) { + return ret; + } + } else if (strcmp("-r", argv[i]) == 0) { + i++; + if (i >= argc) { + return -1; + } + g_param.repeat = atoi(argv[i]); + if ((g_param.repeat <= 0) || (g_param.repeat > 1000)) { /* 1000: repeat limit */ + return -1; + } + } + } + + if (((mask & TEST_CASE_FLAGS_ALL) != 0) && ((mask & TEST_CASE_FLAGS_SPECIFY) != 0)) { + cout << "Invalid parameter combination" << endl; + return -1; + } + return 0; +} + +static void IsCase(vector files, struct TestCase *testCase) +{ + for (size_t i = 0; i < files.size(); i++) { + string file = files[i]; + int fileLen = strlen(file.c_str()); + if (fileLen <= testCase->caseLen) { + continue; + } + + const string &suffix = file.c_str() + (fileLen - testCase->caseLen); + if (strcmp(suffix.c_str(), testCase->bin) != 0) { + continue; + } + + if (memcpy_s(testCase->bin, TEST_PATH_MAX, file.c_str(), fileLen + 1) != EOK) { + testCase->caseLen = 0; + return; + } + testCase->caseLen = fileLen; + g_param.testCaseNum++; + return; + } + cout << "liteos_unittest_run.bin: not find test case: " << testCase->bin << endl; + return; +} + +static int FindTestCase(vector files) +{ + int count = g_param.testCaseNum; + g_param.testCaseNum = 0; + + for (int i = 0; i < count; i++) { + IsCase(files, g_param.testCase[i]); + } + + if (g_param.testCaseNum == 0) { + cout << "Not find test case !" << endl; + return -1; + } + return 0; +} + +static void FreeTestCaseMem(void) +{ + for (int index = 0; index < g_param.testCaseNum; index++) { + free(g_param.testCase[index]); + g_param.testCase[index] = nullptr; + } +} + +static void ShowTestLog(int count) +{ + cout << "[UNITTEST_RUN] Repeats: " << count << " Succeed count: " + << g_testsuitesCount - g_testsuitesFailedCount + << " Failed count: " << g_testsuitesFailedCount << endl; + + if (g_testsuitesFailedCount == 0) { + return; + } + cout << "[UNITTEST_RUN] Failed testcase: " << endl; + for (int i = 0; i < g_testsuitesFailedCount; i++) { + cout << "[" << i << "] -> " << g_testsuitesFailedCase[i] << endl; + free(g_testsuitesFailedCase[i]); + g_testsuitesFailedCase[i] = nullptr; + } +} + +int main(int argc, const char *argv[]) +{ + int ret; + int count = 0; + + if ((argc < 2) || (argv == nullptr)) { /* 2: param index */ + cout << argv[0] << ": " << strerror(EINVAL) << endl; + return -1; + } + + if ((strcmp("--h", argv[1]) == 0) || (strcmp("--help", argv[1]) == 0)) { + TestsuitesToolsUsage(); + return 0; + } + + (void)memset_s(&g_param, sizeof(struct TestsuitesParam), 0, sizeof(struct TestsuitesParam)); + + ret = GetTestsuitesToolsName(argv); + if (ret < 0) { + return -1; + } + + ret = TestsuitesParamCheck(argc, argv); + if (ret < 0) { + cout << strerror(EINVAL) << endl; + FreeTestCaseMem(); + return -1; + } + + vector files = GetAllTestsuites(g_param.testsuitesDir); + + if (g_param.testCaseNum != 0) { + ret = FindTestCase(files); + if (ret < 0) { + files.clear(); + FreeTestCaseMem(); + return -1; + } + } + + while (count < g_param.repeat) { + if (g_param.testCaseNum == 0) { + RunAllTestCase(files, &g_param); + } else { + for (int index = 0; index < g_param.testCaseNum; index++) { + RunCase(g_param.testCase[index]->bin, g_param.testCase[index]->param); + } + } + count++; + } + files.clear(); + FreeTestCaseMem(); + ShowTestLog(count); + return 0; +} diff --git a/src/kernel_liteos_a/tools/.gitignore b/src/kernel_liteos_a/tools/.gitignore new file mode 100644 index 00000000..b9bb3934 --- /dev/null +++ b/src/kernel_liteos_a/tools/.gitignore @@ -0,0 +1,2 @@ +menuconfig/.config.cmd +menuconfig/extra/config/*.o diff --git a/src/kernel_liteos_a/tools/build/liteos.ld b/src/kernel_liteos_a/tools/build/liteos.ld new file mode 100644 index 00000000..40d55102 --- /dev/null +++ b/src/kernel_liteos_a/tools/build/liteos.ld @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +ENTRY(reset_vector) +INCLUDE board.ld +SECTIONS +{ + _start = .; + .set_sysinit_set : { + __start_set_sysinit_set = ABSOLUTE(.); + KEEP (*(.set_sysinit_set)) + __stop_set_sysinit_set = ABSOLUTE(.); + } > ram + + .got ALIGN(0x4) : { *(.got.plt) *(.got) } > ram + + .gcc_except_table ALIGN (0x8) : { . = .; } > ram .gcc_except_table : { KEEP(*(.gcc_except_table*)) } + .exception_ranges ALIGN (0x8) : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) } > ram + + .ARM.extab ALIGN(0x4) : { *(.ARM.extab* .gnu.linkonce.armextab.*) } > ram + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + .ARM.exidx ALIGN(0x8) : { __exidx_start = .; *(.ARM.exidx* .gnu.linkonce.armexidx.*) ;__exidx_end = .;} > ram + + /* text/read-only data */ + .text ALIGN(0x1000) : { + __text_start = .; + *(.text* .sram.text.glue_7* .gnu.linkonce.t.*) + } > ram + + .rel.text : { *(.rel.text) *(.rel.text.*) *(.rel.gnu.linkonce.t*) } > ram + .rela.text : { *(.rela.text) *(.rela.text.*) *(.rela.gnu.linkonce.t*) } > ram + .rel.data : { *(.rel.data) *(.rel.data.*) *(.rel.gnu.linkonce.d*) } > ram + .rela.data : { *(.rela.data) *(.rela.data.*) *(.rela.gnu.linkonce.d*) } > ram + .rel.rodata : { *(.rel.rodata) *(.rel.rodata.*) *(.rel.gnu.linkonce.r*) } > ram + .rela.rodata : { *(.rela.rodata) *(.rela.rodata.*) *(.rela.gnu.linkonce.r*) } > ram + .rel.got : { *(.rel.got) } > ram + .rela.got : { *(.rela.got) } > ram + .rel.ctors : { *(.rel.ctors) } > ram + .rela.ctors : { *(.rela.ctors) } > ram + .rel.dtors : { *(.rel.dtors) } > ram + .rela.dtors : { *(.rela.dtors) } > ram + .rel.init : { *(.rel.init) } > ram + .rela.init : { *(.rela.init) } > ram + .rel.fini : { *(.rel.fini) } > ram + .rela.fini : { *(.rela.fini) } > ram + .rel.bss : { *(.rel.bss) } > ram + .rela.bss : { *(.rela.bss) } > ram + .rel.plt : { *(.rel.plt) } > ram + .rela.plt : { *(.rela.plt) } > ram + .rel.dyn : { *(.rel.dyn) } > ram + + .dummy_post_text : { + __text_end = .; + } > ram + + .rodata ALIGN(0x1000) : { + __rodata_start = .; + __kernel_init_level_0 = ABSOLUTE(.); + KEEP(*( SORT (.rodata.init.kernel.0.*))); + __kernel_init_level_1 = ABSOLUTE(.); + KEEP(*( SORT (.rodata.init.kernel.1.*))); + __kernel_init_level_2 = ABSOLUTE(.); + KEEP(*( SORT (.rodata.init.kernel.2.*))); + __kernel_init_level_3 = ABSOLUTE(.); + KEEP(*( SORT (.rodata.init.kernel.3.*))); + __kernel_init_level_4 = ABSOLUTE(.); + KEEP(*( SORT (.rodata.init.kernel.4.*))); + __kernel_init_level_5 = ABSOLUTE(.); + KEEP(*( SORT (.rodata.init.kernel.5.*))); + __kernel_init_level_6 = ABSOLUTE(.); + KEEP(*( SORT (.rodata.init.kernel.6.*))); + __kernel_init_level_7 = ABSOLUTE(.); + KEEP(*( SORT (.rodata.init.kernel.7.*))); + __kernel_init_level_8 = ABSOLUTE(.); + KEEP(*( SORT (.rodata.init.kernel.8.*))); + __kernel_init_level_9 = ABSOLUTE(.); + KEEP(*( SORT (.rodata.init.kernel.9.*))); + __kernel_init_level_10 = ABSOLUTE(.); + *(.rodata .rodata.* .gnu.linkonce.r.*) + __exc_table_start = .; + KEEP(*(__exc_table)) + __exc_table_end = .; + } > ram + + /* + * extra linker scripts tend to insert sections just after .rodata, + * so we want to make sure this symbol comes after anything inserted above, + * but not aligned to the next section necessarily. + */ + .dummy_post_rodata : { + _hdf_drivers_start = .; + KEEP(*(.hdf.driver)) + _hdf_drivers_end = .; + __rodata_end = .; + } > ram + + .data ALIGN(0x1000) : { + /* writable data */ + __ram_data_start = .; + __vdso_data_start = LOADADDR(.data); + KEEP(*(.data.vdso.datapage)) + . = ALIGN(0x1000); + KEEP(*(.data.vdso.text)) + . = ALIGN(0x1000); + __vdso_text_end = .; + *(.data .data.* .gnu.linkonce.d.*) + . = ALIGN(0x4); + KEEP(*( SORT (.liteos.table.*))); + } > ram + + .ctors : ALIGN(0x4) { + __ctor_list__ = .; + KEEP (*(.ctors .init_array.* .init_array)) + __ctor_end__ = .; + } > ram + .dtors : ALIGN(0x4) { + __dtor_list__ = .; + KEEP (*(.dtors .fini_array)) + __dtor_end__ = .; + } > ram + /* + * extra linker scripts tend to insert sections just after .data, + * so we want to make sure this symbol comes after anything inserted above, + * but not aligned to the next section necessarily. + */ + .dummy_post_data : { + __ram_data_end = .; + } > ram + + .user_init USER_INIT_VM_START : ALIGN(0x1000) { + . = ALIGN(0x4); + __user_init_load_addr = LOADADDR(.user_init); + __user_init_entry = .; + KEEP(libuserinit.O (.user.entry)) + KEEP(libuserinit.O (.user.text)) + KEEP(libuserinit.O (.user.rodata)) + . = ALIGN(0X4); + __user_init_data = .; + KEEP(libuserinit.O (.user.data)) + . = ALIGN(0X4); + __user_init_bss = .; + KEEP(libuserinit.O (.user.bss)) + . = ALIGN(0x1000); + __user_init_end = .; + } > user_ram AT > ram + + __user_init_size = __user_init_end - __user_init_entry; + + /* uninitialized data (in same segment as writable data) */ + .bss : { + . = ALIGN(0x800); + __int_stack_start = .; + *(.int_stack); + . = ALIGN(0x4); + KEEP(*(.bss.prebss.*)) + . = ALIGN(0x8); + __bss_start = .; + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(0x8); + __bss_end = .; + } > ram + + . = ALIGN(0x1000); + _end = .; + /* mmu temp page table(sys aviliable mem is start with __bss_end) */ + . = ALIGN(0x4000); + __mmu_ttlb_begin = .; + + /* Strip unnecessary stuff */ + /DISCARD/ 0 : { *(.comment .note) } > ram +} diff --git a/src/kernel_liteos_a/tools/build/liteos_llvm.ld b/src/kernel_liteos_a/tools/build/liteos_llvm.ld new file mode 100644 index 00000000..a158d778 --- /dev/null +++ b/src/kernel_liteos_a/tools/build/liteos_llvm.ld @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +ENTRY(reset_vector) +INCLUDE board.ld +INPUT(libuserinit.O) +SECTIONS +{ + _start = .; + .set_sysinit_set : { + __start_set_sysinit_set = ABSOLUTE(.); + KEEP (*(.set_sysinit_set)) + __stop_set_sysinit_set = ABSOLUTE(.); + } > ram + + .got ALIGN(0x4) : { *(.got.plt) *(.got) } > ram + + .ctors : ALIGN(0x4) { + __ctor_list__ = .; + KEEP (*(.ctors .init_array.* .init_array)) + __ctor_end__ = .; + } > ram + .dtors : ALIGN(0x4) { + __dtor_list__ = .; + KEEP (*(.dtors .fini_array)) + __dtor_end__ = .; + } > ram + + .gcc_except_table ALIGN (0x8) : { . = .; } > ram .gcc_except_table : { KEEP(*(.gcc_except_table*)) } + .exception_ranges ALIGN (0x8) : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) } > ram + + .ARM.extab ALIGN(0x4) : { *(.ARM.extab* .gnu.linkonce.armextab.*) } > ram + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + /*.ARM.exidx ALIGN(0x8) : { __exidx_start = .; *(.ARM.exidx* .gnu.linkonce.armexidx.*) ;__exidx_end = .;} > ram*/ + .ARM.exidx ALIGN(0x8) : { __exidx_start = .; __exidx_end = .;} > ram + + .eh_frame ALIGN (0x8) : { KEEP (*(.eh_frame)) *(.eh_frame.*); } > ram + + /* text/read-only data */ + .text : ALIGN(0x1000) { + __text_start = .; + *(.text* .sram.text.glue_7* .gnu.linkonce.t.*) + } > ram + + .rel.text : { *(.rel.text) *(.rel.text.*) *(.rel.gnu.linkonce.t*) } > ram + .rela.text : { *(.rela.text) *(.rela.text.*) *(.rela.gnu.linkonce.t*) } > ram + .rel.data : { *(.rel.data) *(.rel.data.*) *(.rel.gnu.linkonce.d*) } > ram + .rela.data : { *(.rela.data) *(.rela.data.*) *(.rela.gnu.linkonce.d*) } > ram + .rel.rodata : { *(.rel.rodata) *(.rel.rodata.*) *(.rel.gnu.linkonce.r*) } > ram + .rela.rodata : { *(.rela.rodata) *(.rela.rodata.*) *(.rela.gnu.linkonce.r*) } > ram + .rel.got : { *(.rel.got) } > ram + .rela.got : { *(.rela.got) } > ram + .rel.ctors : { *(.rel.ctors) } > ram + .rela.ctors : { *(.rela.ctors) } > ram + .rel.dtors : { *(.rel.dtors) } > ram + .rela.dtors : { *(.rela.dtors) } > ram + .rel.init : { *(.rel.init) } > ram + .rela.init : { *(.rela.init) } > ram + .rel.fini : { *(.rel.fini) } > ram + .rela.fini : { *(.rela.fini) } > ram + .rel.bss : { *(.rel.bss) } > ram + .rela.bss : { *(.rela.bss) } > ram + .rel.plt : { *(.rel.plt) } > ram + .rela.plt : { *(.rela.plt) } > ram + .rel.dyn : { *(.rel.dyn) } > ram + + .dummy_post_text : { + __text_end = .; + } > ram + + .rodata : ALIGN(0x1000) { + __rodata_start = .; + __kernel_init_level_0 = ABSOLUTE(.); + KEEP(*( SORT (.rodata.init.kernel.0.*))); + __kernel_init_level_1 = ABSOLUTE(.); + KEEP(*( SORT (.rodata.init.kernel.1.*))); + __kernel_init_level_2 = ABSOLUTE(.); + KEEP(*( SORT (.rodata.init.kernel.2.*))); + __kernel_init_level_3 = ABSOLUTE(.); + KEEP(*( SORT (.rodata.init.kernel.3.*))); + __kernel_init_level_4 = ABSOLUTE(.); + KEEP(*( SORT (.rodata.init.kernel.4.*))); + __kernel_init_level_5 = ABSOLUTE(.); + KEEP(*( SORT (.rodata.init.kernel.5.*))); + __kernel_init_level_6 = ABSOLUTE(.); + KEEP(*( SORT (.rodata.init.kernel.6.*))); + __kernel_init_level_7 = ABSOLUTE(.); + KEEP(*( SORT (.rodata.init.kernel.7.*))); + __kernel_init_level_8 = ABSOLUTE(.); + KEEP(*( SORT (.rodata.init.kernel.8.*))); + __kernel_init_level_9 = ABSOLUTE(.); + KEEP(*( SORT (.rodata.init.kernel.9.*))); + __kernel_init_level_10 = ABSOLUTE(.); + *(.rodata .rodata.* .gnu.linkonce.r.*) + __exc_table_start = .; + KEEP(*(__exc_table)) + __exc_table_end = .; + } > ram + + /* + * extra linker scripts tend to insert sections just after .rodata, + * so we want to make sure this symbol comes after anything inserted above, + * but not aligned to the next section necessarily. + */ + .dummy_post_rodata : { + _hdf_drivers_start = .; + KEEP(*(.hdf.driver)) + _hdf_drivers_end = .; + __rodata_end = .; + } > ram + + .data : ALIGN(0x1000) { + /* writable data */ + __ram_data_start = .; + __vdso_data_start = LOADADDR(.data); + KEEP(*(.data.vdso.datapage)) + . = ALIGN(0x1000); + KEEP(*(.data.vdso.text)) + . = ALIGN(0x1000); + __vdso_text_end = .; + *(.data .data.* .gnu.linkonce.d.*) + . = ALIGN(0x4); + KEEP(*( SORT (.liteos.table.*))); + } > ram + + /* + * extra linker scripts tend to insert sections just after .data, + * so we want to make sure this symbol comes after anything inserted above, + * but not aligned to the next section necessarily. + */ + .dummy_post_data : { + __ram_data_end = .; + } > ram + + .user_init : ALIGN(0x1000) { + . = ALIGN(0x4); + __user_init_load_addr = LOADADDR(.user_init); + __user_init_entry = .; + KEEP(*(.user.entry)) + KEEP(*(.user.text)) + KEEP(*(.user.rodata)) + . = ALIGN(0X4); + __user_init_data = .; + KEEP(*(.user.data)) + . = ALIGN(0X4); + __user_init_bss = .; + KEEP(*(.user.bss)) + . = ALIGN(0x1000); + __user_init_end = .; + } > user_ram AT > ram + + __user_init_size = __user_init_end - __user_init_entry; + + /* uninitialized data (in same segment as writable data) */ + .bss : { + . = ALIGN(0x800); + __int_stack_start = .; + *(.int_stack); + . = ALIGN(0x4); + KEEP(*(.bss.prebss.*)) + . = ALIGN(0x8); + __bss_start = .; + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(0x8); + __bss_end = .; + } > ram + + . = ALIGN(0x1000); + _end = .; + /* mmu temp page table(sys aviliable mem is start with __bss_end) */ + . = ALIGN(0x4000); + __mmu_ttlb_begin = .; + + /* Strip unnecessary stuff */ + /DISCARD/ 0 : { *(.comment .note .ARM.exidx* .gnu.linkonce.armexidx.*) } > ram +} diff --git a/src/kernel_liteos_a/tools/build/mk/liteos_tables_ldflags.mk b/src/kernel_liteos_a/tools/build/mk/liteos_tables_ldflags.mk new file mode 100644 index 00000000..eed3a4b9 --- /dev/null +++ b/src/kernel_liteos_a/tools/build/mk/liteos_tables_ldflags.mk @@ -0,0 +1,192 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +####Kernel command#### +#task_shellcmd.c -utask_shellcmd +#cpup_shellcmd.c -ucpup_shellcmd +#shell_shellcmd.c -uhelp_shellcmd +#mempt_shellcmd.c -ufree_shellcmd -umemcheck_shellcmd -uuname_shellcmd -uwritereg_shellcmd +#sem_shellcmd.c -usem_shellcmd +#sysinfo_shellcmd.c -usysteminfo_shellcmd +#swtmr_shellcmd.c -uswtmr_shellcmd +#hwi_shell.c -uhwi_shellcmd +#dynload_shellcmd.c -uldinit_shellcmd -ucall_shellcmd -ufindsym_shellcmd -ulddrop_shellcmd -umclose_shellcmd -umopen_shellcmd +LITEOS_TABLES_KERNEL_LDFLAGS := \ + -utask_shellcmd \ + -uvm_shellcmd \ + -ucpup_shellcmd \ + -uhelp_shellcmd \ + -ufree_shellcmd \ + -usem_shellcmd \ + -umutex_shellcmd \ + -uqueue_shellcmd \ + -usysteminfo_shellcmd \ + -uswtmr_shellcmd \ + -uhwi_shellcmd \ + -ufindsym_shellcmd \ + -uzbar_scan_shellcmd \ + -udmesg_shellcmd \ + -udate_shellcmd \ + -ureadExcInfo_shellcmd \ + -uwatch_shellcmd \ + -udeadlock_shellcmd \ + -ukill_shellcmd \ + -upmm_shellcmd \ + -upanic_reset_shellcmd \ + -ushm_shellcmd + +####Net command#### +#api_shell.c -uarp_shellcmd -uifconfig_shellcmd -uping_shellcmd -utftp_shellcmd -unetstat_shellcmd -udns_shellcmd -untpdate_shellcmd +#telnet_loop.c -utelnet_shellcmd +LITEOS_TABLES_NET_LDFLAGS := \ + -uarp_shellcmd \ + -utelnet_shellcmd \ + -uping_shellcmd \ + -unetstat_shellcmd \ + -uifconfig_shellcmd + +####FS command#### +#vfs_shellcmd.c -ucd_shellcmd -ucat_shellcmd -uls_shellcmd -upwd_shellcmd -urm_shellcmd -urmdir_shellcmd -umkdir_shellcmd -utouch_shellcmd -uumount_shellcmd -umount_shellcmd -usync_shellcmd -ustatfs_shellcmd -ucp_shellcmd +#fat_shellcmd.c -uformat_shellcmd +#mtd_shellcmd.c -upartition_shellcmd +#proc_shellcmd.c -uwriteproc_shellcmd +#disk_shellcmd.c -upartinfo_shellcmd +LITEOS_TABLES_FS_LDFLAGS := \ + -ucd_shellcmd \ + -uformat_shellcmd \ + -upartition_shellcmd \ + -uwriteproc_shellcmd \ + -upartinfo_shellcmd \ + -uumount_shellcmd -umount_shellcmd \ + -uvirstatfs_shellcmd \ + -ulsfd_shellcmd \ + -usu_shellcmd \ + -uchmod_shellcmd \ + -uchown_shellcmd \ + -uchgrp_shellcmd + +####Tools command#### +#iperf_shell.c -uiperf_shellcmd +LITEOS_TABLES_TOOLS_LDFLAGS := \ + -uiperf_shellcmd \ + -ulwip_dump_shellcmd + +####Extend command#### +#reset_shell.c -ureset_shellcmd +#bcm_wifi.c -ustartap_shellcmd -ustopap_shellcmd -ubcmwifi_shellcmd +#ddrs_shell.c -uhiddrs_shellcmd +#nand_shell.c -unand_bad_shellcmd +#i2c_shell.c -ui2c_read_shellcmd -ui2c_write_shellcmd +#spi_shell.c -ussp_read_shellcmd -ussp_write_shellcmd +#uart_shell.c -uuart_config_shellcmd -uuart_write_shellcmd -uuart_read_shellcmd -uuart_close_shellcmd +LITEOS_TABLES_EXTEND_LDFLAGS := \ + -ureset_shellcmd \ + -ustartap_shellcmd \ + -uhiddrs_shellcmd \ + -unand_bad_shellcmd \ + -ui2c_read_shellcmd \ + -ussp_read_shellcmd \ + -uuart_config_shellcmd\ + -uusb_debug_shellcmd \ + -uOsPmInit + +LITEOS_TABLES_KERNEL_INIT_LDFLAGS := \ + -uOsTraceInit \ + -ulos_vfs_init \ + -uProcFsInit \ + -uOsDriverRandomInit \ + -uHieventInit \ + -uOsBsdInit \ + -uShmInit \ + -uOsDmesgInit \ + -uOsLkLoggerInit \ + -uOsCpupInit \ + -uOsFutexInit \ + -uOsSysWorkQueueInit \ + -uOsSyscallHandleInit \ + -upipe_init \ + -uOomTaskInit \ + -uOsCpupGuardCreator \ + -uOsMpInit \ + -uOsResourceFreeTaskCreate \ + -uOsSystemInit \ + -uOsBBoxDriverInit \ + -uOsBBoxSystemAdapterInit \ + -uOsHiDumperDriverInit + +LITEOS_TABLES_DRIVER_LDFLAGS := \ + -ui2c_init \ + -ugpio_init \ + -uregulator_init \ + -uhispi_init \ + -uhifmc100_init \ + -uhisfc350_init \ + -unand_hifmc100_init \ + -uhifmc100_parallel_init \ + -usd_mci_init \ + -uhi_mci_init \ + -upl011_init \ + -uhinfc620_init \ + -uhisnfc100_init \ + -uregulator_machine_init \ + -uhisimeidia_regulator_init \ + -ucpufreq_init \ + -uhisilicon_cpufreq_init \ + -ucpufreq_machine_init \ + -udevfreq_init \ + -umedia_devfreq_init \ + -udevfreq_machine_init\ + -uhieth_machine_init\ + -uhigmac_machine_init \ + -umachine_init + +####FS MAP#### +LITEOS_TABLES_FSMAP_LDFLAGS := \ + -uramfs_fsmap \ + -uromfs_fsmap \ + -unfs_fsmap \ + -ufat_fsmap \ + -ujffs_fsmap \ + -uprocfs_fsmap \ + -ug_fsmap + +#ifdef LOSCFG_FS_ZPFS +LITEOS_TABLES_FSMAP_LDFLAGS += -uzpfs_fsmap +#endif + +LITEOS_TABLES_LDFLAGS := \ + $(LITEOS_TABLES_KERNEL_LDFLAGS)\ + $(LITEOS_TABLES_NET_LDFLAGS) \ + $(LITEOS_TABLES_FS_LDFLAGS) \ + $(LITEOS_TABLES_TOOLS_LDFLAGS) \ + $(LITEOS_TABLES_EXTEND_LDFLAGS) \ + $(LITEOS_TABLES_FSMAP_LDFLAGS) \ + $(LITEOS_TABLES_DRIVER_LDFLAGS) \ + $(LITEOS_TABLES_KERNEL_INIT_LDFLAGS) + diff --git a/src/kernel_liteos_a/tools/build/mk/los_config.mk b/src/kernel_liteos_a/tools/build/mk/los_config.mk new file mode 100644 index 00000000..2627bcc9 --- /dev/null +++ b/src/kernel_liteos_a/tools/build/mk/los_config.mk @@ -0,0 +1,601 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +LITEOS_MENUCONFIG_H ?= $(LITEOSTOPDIR)/config.h +LITEOS_CONFIG_FILE ?= $(LITEOSTOPDIR)/.config + +-include $(LITEOS_CONFIG_FILE) + +ifeq ($(ARCH),) +ARCH = $(error ARCH not set!) +endif + +## variable define ## +HIDE = @ +RM = -rm -rf +OUT = $(or $(OUTDIR),$(LITEOSTOPDIR)/out/$(LOSCFG_PRODUCT_NAME:"%"=%)) +MODULE = $(LITEOSTOPDIR)/tools/build/mk/module.mk +LITEOS_SCRIPTPATH = $(LITEOSTOPDIR)/tools/scripts +LITEOSTHIRDPARTY = $(LITEOSTOPDIR)/../../third_party + +## compiler relative ## +get_compiler_path = $(or $(wildcard $(1)),$(dir $(shell which $(CROSS_COMPILE)as))) +ifeq ($(LOSCFG_COMPILER_CLANG_LLVM), y) +CROSS_COMPILE ?= llvm- +LITEOS_COMPILER_PATH ?= $(call get_compiler_path,$(LITEOSTOPDIR)/../../prebuilts/clang/ohos/linux-x86_64/llvm/bin/) +LLVM_TARGET = $(if $(LOSCFG_LLVM_TARGET:"%"=%),--target=$(LOSCFG_LLVM_TARGET:"%"=%),) +LLVM_SYSROOT = $(if $(SYSROOT_PATH),--sysroot=$(SYSROOT_PATH),) +CC = $(LITEOS_COMPILER_PATH)clang $(LLVM_TARGET) $(LLVM_SYSROOT) +AS = $(LITEOS_COMPILER_PATH)$(CROSS_COMPILE)as +AR = $(LITEOS_COMPILER_PATH)$(CROSS_COMPILE)ar +LD = $(LITEOS_COMPILER_PATH)ld.lld +GPP = $(LITEOS_COMPILER_PATH)clang++ $(LLVM_TARGET) $(LLVM_SYSROOT) +OBJCOPY = $(LITEOS_COMPILER_PATH)$(CROSS_COMPILE)objcopy -R .bss +OBJDUMP = $(LITEOS_COMPILER_PATH)$(CROSS_COMPILE)objdump +SIZE = $(LITEOS_COMPILER_PATH)$(CROSS_COMPILE)size +NM = $(LITEOS_COMPILER_PATH)$(CROSS_COMPILE)nm +STRIP = $(LITEOS_COMPILER_PATH)$(CROSS_COMPILE)strip +else ifeq ($(LOSCFG_COMPILER_GCC), y) +CROSS_COMPILE ?= $(LOSCFG_CROSS_COMPILE:"%"=%) +LITEOS_COMPILER_PATH ?= $(call get_compiler_path,$(LITEOSTOPDIR)/../../prebuilts/gcc/linux-x86/arm/arm-linux-ohoseabi-gcc/bin/) +CC = $(LITEOS_COMPILER_PATH)$(CROSS_COMPILE)gcc +AS = $(LITEOS_COMPILER_PATH)$(CROSS_COMPILE)as +AR = $(LITEOS_COMPILER_PATH)$(CROSS_COMPILE)ar +LD = $(LITEOS_COMPILER_PATH)$(CROSS_COMPILE)ld +GPP = $(LITEOS_COMPILER_PATH)$(CROSS_COMPILE)g++ +OBJCOPY = $(LITEOS_COMPILER_PATH)$(CROSS_COMPILE)objcopy +OBJDUMP = $(LITEOS_COMPILER_PATH)$(CROSS_COMPILE)objdump +SIZE = $(LITEOS_COMPILER_PATH)$(CROSS_COMPILE)size +NM = $(LITEOS_COMPILER_PATH)$(CROSS_COMPILE)nm +STRIP = $(LITEOS_COMPILER_PATH)$(CROSS_COMPILE)strip +else +CC = echo $(info compiler type not set!) +endif + +## c as cxx ld options ## +LITEOS_ASOPTS := +LITEOS_COPTS_BASE := +LITEOS_COPTS_EXTRA := +LITEOS_COPTS_DEBUG := +LITEOS_CXXOPTS := +LITEOS_CXXOPTS_BASE := +LITEOS_LD_OPTS := +LITEOS_GCOV_OPTS := +## macro define ## +LITEOS_CMACRO := -D__LITEOS__ +LITEOS_CXXMACRO := +## head file path and ld path ## +LITEOS_PLATFORM_INCLUDE := +LITEOS_CXXINCLUDE := +LITEOS_LD_PATH := +LITEOS_LD_SCRIPT := +## c as cxx ld flags ## +LITEOS_ASFLAGS := +LITEOS_CFLAGS := +LITEOS_LDFLAGS := +LITEOS_CXXFLAGS := +## depended lib ## +LITEOS_BASELIB := +LITEOS_LIBDEP := +## directory ## +LIB_SUBDIRS := + +####################################### CPU Option Begin ######################################### +include $(LITEOSTOPDIR)/arch/cpu.mk +####################################### CPU Option End ######################################### + +############################# Platform Option Begin################################# +include $(LITEOSTOPDIR)/platform/bsp.mk +############################# Platform Option End ################################# + +####################################### Kernel Option Begin ########################################### +LITEOS_BASELIB += -lbase +LIB_SUBDIRS += kernel/base +LITEOS_KERNEL_INCLUDE := -I $(LITEOSTOPDIR)/kernel/include \ + -I $(LITEOSTOPDIR)/kernel/base/include + +LITEOS_BASELIB += -lcommon +LIB_SUBDIRS += kernel/common +LITEOS_KERNEL_INCLUDE += -I $(LITEOSTOPDIR)/kernel/common + +ifeq ($(LOSCFG_KERNEL_CPPSUPPORT), y) + LITEOS_BASELIB += -lcppsupport + LIB_SUBDIRS += kernel/extended/cppsupport + LITEOS_CPPSUPPORT_INCLUDE += -I $(LITEOSTOPDIR)/kernel/extended/cppsupport +endif + +ifeq ($(LOSCFG_KERNEL_CPUP), y) + LITEOS_BASELIB += -lcpup + LIB_SUBDIRS += kernel/extended/cpup + LITEOS_CPUP_INCLUDE := -I $(LITEOSTOPDIR)/kernel/extended/cpup +endif + +ifeq ($(LOSCFG_KERNEL_DYNLOAD), y) + LITEOS_BASELIB += -ldynload + LIB_SUBDIRS += kernel/extended/dynload + LITEOS_DYNLOAD_INCLUDE += -I $(LITEOSTOPDIR)/kernel/extended/dynload/include +endif + +ifeq ($(LOSCFG_KERNEL_VDSO), y) + LITEOS_BASELIB += -lvdso + LIB_SUBDIRS += kernel/extended/vdso/usr + LIB_SUBDIRS += kernel/extended/vdso/src + LITEOS_VDSO_INCLUDE += -I $(LITEOSTOPDIR)/kernel/extended/vdso/include +endif + +ifeq ($(LOSCFG_KERNEL_TRACE), y) + LITEOS_BASELIB += -ltrace + LIB_SUBDIRS += kernel/extended/trace +endif + +ifeq ($(LOSCFG_KERNEL_HOOK), y) + LITEOS_BASELIB += -lhook + LIB_SUBDIRS += kernel/extended/hook + LITEOS_HOOK_INCLUDE += -I $(LITEOSTOPDIR)/kernel/extended/hook/include +endif + +ifeq ($(LOSCFG_KERNEL_PERF), y) + LITEOS_BASELIB += -lperf + LIB_SUBDIRS += kernel/extended/perf + LITEOS_PERF_INCLUDE += -I $(LITEOSTOPDIR)/kernel/extended/perf +endif + +ifeq ($(LOSCFG_KERNEL_LMS), y) + LITEOS_BASELIB += -llms + LIB_SUBDIRS += kernel/extended/lms + LITEOS_LMS_INCLUDE += -I $(LITEOSTOPDIR)/kernel/extended/lms +endif + +ifeq ($(LOSCFG_KERNEL_LITEIPC), y) + LITEOS_BASELIB += -lliteipc + LIB_SUBDIRS += kernel/extended/liteipc + LITEOS_LITEIPC_INCLUDE += -I $(LITEOSTOPDIR)/kernel/extended/liteipc +endif + +ifeq ($(LOSCFG_KERNEL_PIPE), y) + LITEOS_BASELIB += -lpipes + LIB_SUBDIRS += kernel/extended/pipes + LITEOS_PIPE_INCLUDE += -I $(LITEOSTOPDIR)/../../third_party/NuttX/drivers/pipes +endif + +ifeq ($(LOSCFG_KERNEL_PM), y) + LITEOS_BASELIB += -lpower + LIB_SUBDIRS += kernel/extended/power + LITEOS_PM_INCLUDE = -I $(LITEOSTOPDIR)/kernel/extended/power +endif + +ifeq ($(LOSCFG_KERNEL_SYSCALL), y) + LITEOS_BASELIB += -lsyscall + LIB_SUBDIRS += syscall +endif + +ifeq ($(LOSCFG_KERNEL_PLIMITS), y) + LITEOS_BASELIB += -lplimit + LIB_SUBDIRS += kernel/extended/plimit + LITEOS_PLIMITS_INCLUDE = -I $(LITEOSTOPDIR)/kernel/extended/plimit +endif + +LIB_SUBDIRS += kernel/user + +################################### Kernel Option End ################################ + +#################################### Lib Option Begin ############################### +LITEOS_BASELIB += -lscrew +LIB_SUBDIRS += lib/libscrew +LITEOS_LIBSCREW_INCLUDE += -I $(LITEOSTOPDIR)/lib/libscrew/include + +ifeq ($(LOSCFG_LIB_LIBC), y) + LIB_SUBDIRS += lib/libc/musl + LITEOS_BASELIB += -lc + LITEOS_LIBC_INCLUDE += \ + -isystem $(LITEOSTHIRDPARTY)/musl/porting/liteos_a/kernel/include + + LIB_SUBDIRS += lib/libsec + LITEOS_BASELIB += -lsec + LITEOS_LIBC_INCLUDE += \ + -I $(LITEOSTHIRDPARTY)/bounds_checking_function/include + LITEOS_CMACRO += -DSECUREC_IN_KERNEL=0 +endif + +ifeq ($(LOSCFG_LIB_ZLIB), y) + LITEOS_BASELIB += -lz + LIB_SUBDIRS += lib/zlib + LITEOS_ZLIB_INCLUDE += -I $(LITEOSTHIRDPARTY)/zlib +endif +################################### Lib Option End ###################################### + +####################################### Compat Option Begin ######################################### +ifeq ($(LOSCFG_COMPAT_POSIX), y) + LITEOS_BASELIB += -lposix + LIB_SUBDIRS += compat/posix + LITEOS_POSIX_INCLUDE += \ + -I $(LITEOSTOPDIR)/compat/posix/include +endif + +ifeq ($(LOSCFG_COMPAT_BSD), y) + LITEOS_BASELIB += -lbsd + LIB_SUBDIRS += bsd + LITEOS_BSD_INCLUDE += -I $(LITEOSTOPDIR)/bsd + LITEOS_BASELIB += -llinuxkpi + LIB_SUBDIRS += bsd/compat/linuxkpi + LITEOS_LINUX_INCLUDE += -I $(LITEOSTOPDIR)/bsd/compat/linuxkpi/include \ + -I $(LITEOSTOPDIR)/bsd \ + -I $(LITEOSTOPDIR)/bsd/kern +endif +######################################## Compat Option End ############################################ + + +#################################### FS Option Begin ################################## +ifeq ($(LOSCFG_FS_VFS), y) + LITEOS_BASELIB += -lvfs -lmulti_partition +ifeq ($(LOSCFG_FS_VFS_BLOCK_DEVICE), y) + LITEOS_BASELIB += -lbch + LIB_SUBDIRS += $(LITEOSTOPDIR)/drivers/char/bch +endif + LIB_SUBDIRS += fs/vfs drivers/mtd/multi_partition + LITEOS_VFS_INCLUDE += -I $(LITEOSTOPDIR)/fs/include \ + -I $(LITEOSTOPDIR)/fs/vfs/include + LITEOS_VFS_INCLUDE += -I $(LITEOSTOPDIR)/fs/vfs/include/operation + LITEOS_VFS_MTD_INCLUDE := -I $(LITEOSTOPDIR)/drivers/mtd/multi_partition/include +endif + +ifeq ($(LOSCFG_FS_FAT), y) + LITEOS_BASELIB += -lfat + LIB_SUBDIRS += fs/fat + LITEOS_FAT_INCLUDE += -I $(LITEOSTHIRDPARTY)/FatFs/source +endif + +ifeq ($(LOSCFG_FS_FAT_VIRTUAL_PARTITION), y) + LITEOS_BASELIB += -lvirpart + LIB_SUBDIRS += fs/fat/virpart + LITEOS_FAT_VIRPART_INCLUDE += -I $(LITEOSTOPDIR)/fs/fat/virpart/include +endif + +ifeq ($(LOSCFG_FS_FAT_DISK), y) + LITEOS_BASELIB += -ldisk + LIB_SUBDIRS += $(LITEOSTOPDIR)/drivers/block/disk + LITEOS_VFS_DISK_INCLUDE := -I $(LITEOSTOPDIR)/drivers/block/disk/include +endif + +ifeq ($(LOSCFG_FS_FAT_CACHE), y) + LITEOS_BASELIB += -lbcache + LIB_SUBDIRS += fs/vfs/bcache + LITEOS_FAT_CACHE_INCLUDE += -I $(LITEOSTOPDIR)/fs/vfs/include/bcache +endif + + +ifeq ($(LOSCFG_FS_RAMFS), y) + LITEOS_BASELIB += -lramfs + LIB_SUBDIRS += fs/ramfs +endif + +ifeq ($(LOSCFG_FS_ROMFS), y) + LITEOS_BASELIB += -lromfs + LIB_SUBDIRS += fs/romfs +endif + +ifeq ($(LOSCFG_FS_NFS), y) + LITEOS_BASELIB += -lnfs + LIB_SUBDIRS += fs/nfs +endif + +ifeq ($(LOSCFG_FS_PROC), y) + LITEOS_BASELIB += -lproc + LIB_SUBDIRS += fs/proc + LITEOS_PROC_INCLUDE += -I $(LITEOSTOPDIR)/fs/proc/include +endif + + +ifeq ($(LOSCFG_FS_JFFS), y) +# LITEOS_BASELIB += -ljffs2 +# LIB_SUBDIRS += fs/jffs2 +endif + +ifeq ($(LOSCFG_PLATFORM_ROOTFS), y) + LITEOS_BASELIB += -lrootfs + LIB_SUBDIRS += fs/rootfs + LITEOS_PLATFORM_INCLUDE += -I $(LITEOSTOPDIR)/fs/rootfs +endif + +ifeq ($(LOSCFG_PLATFORM_PATCHFS), y) + LITEOS_BASELIB += -lpatchfs + LIB_SUBDIRS += fs/patchfs +endif + +ifeq ($(LOSCFG_FS_ZPFS), y) + LITEOS_BASELIB += -lzpfs + LIB_SUBDIRS += fs/zpfs +endif +#################################### FS Option End ################################## + + +################################### Net Option Begin ################################### +ifeq ($(LOSCFG_NET_LWIP_SACK), y) +ifeq ($(LOSCFG_NET_LWIP_SACK_2_1), y) + LWIPDIR := $(LITEOSTHIRDPARTY)/lwip/src + LITEOS_BASELIB += -llwip + LIB_SUBDIRS += net/lwip-2.1 + LITEOS_LWIP_SACK_INCLUDE += \ + -I $(LITEOSTOPDIR)/net/lwip-2.1/porting/include \ + -I $(LWIPDIR)/include \ + -I $(LITEOSTOPDIR)/net/mac +else ifeq ($(LOSCFG_NET_LWIP_SACK_2_0), y) + LWIPDIR := $(LITEOSTHIRDPARTY)/lwip_enhanced/src + LITEOS_BASELIB += -llwip + LIB_SUBDIRS += $(LWIPDIR) + LITEOS_LWIP_SACK_INCLUDE += \ + -I $(LWIPDIR)/include \ + -I $(LITEOSTOPDIR)/net/mac + LITEOS_CMACRO += -DLWIP_CONFIG_FILE=\"lwip/lwipopts.h\" -DLWIP_LITEOS_A_COMPAT +else + $(error "unknown lwip version") +endif +endif + +#################################### Net Option End#################################### +LITEOS_DRIVERS_BASE_PATH := $(LITEOSTOPDIR)/../../drivers/liteos +################################## Driver Option Begin ################################# +ifeq ($(LOSCFG_DRIVERS_HDF), y) +include $(LITEOSTOPDIR)/../../drivers/hdf_core/adapter/khdf/liteos/hdf_lite.mk +endif + +ifeq ($(LOSCFG_DRIVERS_HIEVENT), y) + LITEOS_BASELIB += -lhievent + LIB_SUBDIRS += $(LITEOS_DRIVERS_BASE_PATH)/hievent + LITEOS_HIEVENT_INCLUDE += -I $(LITEOS_DRIVERS_BASE_PATH)/hievent/include +endif + +ifeq ($(LOSCFG_DRIVERS_TZDRIVER), y) + LITEOS_BASELIB += -ltzdriver -lmbedtls + LIB_SUBDIRS += $(LITEOS_DRIVERS_BASE_PATH)/tzdriver $(LITEOSTOPDIR)/lib/libmbedtls + LITEOS_TZDRIVER_INCLUDE += -I $(LITEOS_DRIVERS_BASE_PATH)/tzdriver/include +endif + +ifeq ($(LOSCFG_DRIVERS_MEM), y) + LITEOS_BASELIB += -lmem + LIB_SUBDIRS += $(LITEOSTOPDIR)/drivers/char/mem + LITEOS_DEV_MEM_INCLUDE = -I $(LITEOSTOPDIR)/drivers/char/mem/include +endif + +ifeq ($(LOSCFG_DRIVERS_TRACE), y) + LITEOS_BASELIB += -ltrace_dev + LIB_SUBDIRS += $(LITEOSTOPDIR)/drivers/char/trace +endif + +ifeq ($(LOSCFG_DRIVERS_PERF), y) + LITEOS_BASELIB += -lperf_dev + LIB_SUBDIRS += $(LITEOSTOPDIR)/drivers/char/perf + LITEOS_DEV_PERF_INCLUDE += -I $(LITEOSTOPDIR)/drivers/char/perf/include +endif + +ifeq ($(LOSCFG_DRIVERS_QUICKSTART), y) + LITEOS_BASELIB += -lquickstart + LIB_SUBDIRS += $(LITEOSTOPDIR)/drivers/char/quickstart + LITEOS_DEV_QUICKSTART_INCLUDE = -I $(LITEOSTOPDIR)/drivers/char/quickstart/include +endif + +ifeq ($(LOSCFG_DRIVERS_RANDOM), y) + LITEOS_BASELIB += -lrandom + LIB_SUBDIRS += $(LITEOSTOPDIR)/drivers/char/random + LITEOS_RANDOM_INCLUDE += -I $(LITEOSTOPDIR)/drivers/char/random/include +endif + +ifeq ($(LOSCFG_DRIVERS_USB), y) + LITEOS_BASELIB += -lusb_base + LIB_SUBDIRS += $(LITEOSTOPDIR)/bsd/dev/usb + LITEOS_USB_INCLUDE += -I $(LITEOSTOPDIR)/bsd/dev/usb + LITEOS_CMACRO += -DUSB_DEBUG_VAR=5 +endif + +ifeq ($(LOSCFG_DRIVERS_VIDEO), y) + LITEOS_BASELIB += -lvideo + LIB_SUBDIRS += $(LITEOSTOPDIR)/drivers/char/video + LITEOS_VIDEO_INCLUDE += -I $(LITEOSTHIRDPARTY)/NuttX/include/nuttx/video +endif + +############################## Driver Option End ####################################### + +############################## Dfx Option Begin####################################### +ifeq ($(LOSCFG_BASE_CORE_HILOG), y) + LITEOS_BASELIB += -lhilog + LIB_SUBDIRS += $(LITEOSTOPDIR)/../../base/hiviewdfx/hilog_lite/frameworks/featured + LIB_SUBDIRS += $(LITEOSTOPDIR)/kernel/extended/hilog + LITEOS_HILOG_INCLUDE += -I $(LITEOSTOPDIR)/../../base/hiviewdfx/hilog_lite/interfaces/native/kits + LITEOS_HILOG_INCLUDE += -I $(LITEOSTOPDIR)/../../base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog + LITEOS_HILOG_INCLUDE += -I $(LITEOSTOPDIR)/kernel/extended/hilog +endif +ifeq ($(LOSCFG_BLACKBOX), y) + LITEOS_BASELIB += -lblackbox + LIB_SUBDIRS += $(LITEOSTOPDIR)/kernel/extended/blackbox + LITEOS_BLACKBOX_INCLUDE += -I $(LITEOSTOPDIR)/kernel/extended/blackbox +endif +ifeq ($(LOSCFG_HIDUMPER), y) + LITEOS_BASELIB += -lhidumper + LIB_SUBDIRS += $(LITEOSTOPDIR)/kernel/extended/hidumper + LITEOS_HIDUMPER_INCLUDE += -I $(LITEOSTOPDIR)/kernel/extended/hidumper +endif +############################## Dfx Option End ####################################### + +############################# Tools && Debug Option Begin ############################## +ifeq ($(LOSCFG_COMPRESS), y) + LITEOS_BASELIB += -lcompress + LIB_SUBDIRS += tools/compress +endif + +ifneq ($(LOSCFG_DEBUG_VERSION), y) + LITEOS_COPTS_DEBUG += -DNDEBUG +endif + +ifeq ($(LOSCFG_COMPILE_DEBUG), y) + LITEOS_COPTS_OPTIMIZE = -O0 + LITEOS_COPTS_OPTION = -g -gdwarf-2 +endif +ifeq ($(LOSCFG_COMPILE_OPTIMIZE), y) + LITEOS_COPTS_OPTIMIZE = -O2 +endif +ifeq ($(LOSCFG_COMPILE_OPTIMIZE_SIZE), y) + ifeq ($(LOSCFG_COMPILER_CLANG_LLVM), y) + LITEOS_COPTS_OPTIMIZE = -Oz + else + LITEOS_COPTS_OPTIMIZE = -Os + endif +endif +ifeq ($(LOSCFG_COMPILE_LTO), y) + ifeq ($(LOSCFG_COMPILER_CLANG_LLVM), y) + LITEOS_COPTS_OPTIMIZE += -flto=thin + else + LITEOS_COPTS_OPTIMIZE += -flto + endif +endif + LITEOS_COPTS_DEBUG += $(LITEOS_COPTS_OPTION) $(LITEOS_COPTS_OPTIMIZE) + LITEOS_CXXOPTS_BASE += $(LITEOS_COPTS_OPTION) $(LITEOS_COPTS_OPTIMIZE) + LITEOS_ASOPTS += $(LITEOS_COPTS_OPTION) + +ifeq ($(LOSCFG_SHELL), y) + LITEOS_BASELIB += -lshell + LIB_SUBDIRS += shell + LITEOS_SHELL_INCLUDE += -I $(LITEOSTOPDIR)/shell/full/include +endif + + +ifeq ($(LOSCFG_NET_TELNET), y) + LITEOS_BASELIB += -ltelnet + LIB_SUBDIRS += net/telnet + LITEOS_TELNET_INCLUDE += \ + -I $(LITEOSTOPDIR)/net/telnet/include +endif +############################# Tools && Debug Option End ################################# + +############################# Security Option Begin ############################## +LITEOS_SSP = -fno-stack-protector +ifeq ($(LOSCFG_CC_STACKPROTECTOR), y) + LITEOS_SSP = -fstack-protector --param ssp-buffer-size=4 +endif + +ifeq ($(LOSCFG_CC_STACKPROTECTOR_STRONG), y) + LITEOS_SSP = -fstack-protector-strong +endif + +ifeq ($(LOSCFG_CC_STACKPROTECTOR_ALL), y) + LITEOS_SSP = -fstack-protector-all +endif + +ifeq ($(LOSCFG_SECURITY), y) + LIB_SUBDIRS += security + LITEOS_BASELIB += -lsecurity +ifeq ($(LOSCFG_SECURITY_CAPABILITY), y) + LITEOS_SECURITY_CAP_INC := -I $(LITEOSTOPDIR)/security/cap +endif +ifeq ($(LOSCFG_SECURITY_VID), y) + LITEOS_SECURITY_VID_INC := -I $(LITEOSTOPDIR)/security/vid +endif +endif + +############################# Security Option End ############################## + +LITEOS_EXTKERNEL_INCLUDE := $(LITEOS_CPPSUPPORT_INCLUDE) $(LITEOS_DYNLOAD_INCLUDE) \ + $(LITEOS_TICKLESS_INCLUDE) $(LITEOS_HOOK_INCLUDE)\ + $(LITEOS_VDSO_INCLUDE) $(LITEOS_LITEIPC_INCLUDE) \ + $(LITEOS_PIPE_INCLUDE) $(LITEOS_CPUP_INCLUDE) \ + $(LITEOS_PERF_INCLUDE) $(LITEOS_LMS_INCLUDE) \ + $(LITEOS_PM_INCLUDE) $(LITEOS_PLIMITS_INCLUDE) +LITEOS_COMPAT_INCLUDE := $(LITEOS_POSIX_INCLUDE) $(LITEOS_LINUX_INCLUDE) \ + $(LITEOS_BSD_INCLUDE) +LITEOS_FS_INCLUDE := $(LITEOS_VFS_INCLUDE) $(LITEOS_FAT_CACHE_INCLUDE) \ + $(LITEOS_VFS_MTD_INCLUDE) $(LITEOS_VFS_DISK_INCLUDE) \ + $(LITEOS_PROC_INCLUDE) $(LITEOS_FAT_VIRPART_INCLUDE) \ + $(LITEOS_FAT_INCLUDE) +LITEOS_NET_INCLUDE := $(LITEOS_LWIP_SACK_INCLUDE) +LITEOS_LIB_INCLUDE := $(LITEOS_LIBC_INCLUDE) $(LITEOS_LIBM_INCLUDE) \ + $(LITEOS_ZLIB_INCLUDE) $(LITEOS_LIBSCREW_INCLUDE) +LITEOS_DRIVERS_INCLUDE := $(LITEOS_CELLWISE_INCLUDE) $(LITEOS_GPIO_INCLUDE) \ + $(LITEOS_HIDMAC_INCLUDE) $(LITEOS_HIETH_SF_INCLUDE) \ + $(LITEOS_HIGMAC_INCLUDE) $(LITEOS_I2C_INCLUDE) \ + $(LITEOS_LCD_INCLUDE) $(LITEOS_MMC_INCLUDE) \ + $(LITEOS_MTD_SPI_NOR_INCLUDE) $(LITEOS_MTD_NAND_INCLUDE) \ + $(LITEOS_RANDOM_INCLUDE) $(LITEOS_RTC_INCLUDE) \ + $(LITEOS_SPI_INCLUDE) $(LITEOS_USB_INCLUDE) \ + $(LITEOS_WTDG_INCLUDE) $(LITEOS_DBASE_INCLUDE) \ + $(LITEOS_CPUFREQ_INCLUDE) $(LITEOS_DEVFREQ_INCLUDE) \ + $(LITEOS_REGULATOR_INCLUDE) $(LITEOS_VIDEO_INCLUDE) \ + $(LITEOS_DRIVERS_HDF_INCLUDE) $(LITEOS_TZDRIVER_INCLUDE) \ + $(LITEOS_HIEVENT_INCLUDE) $(LITEOS_DEV_MEM_INCLUDE) \ + $(LITEOS_DEV_QUICKSTART_INCLUDE) $(LITEOS_DEV_PERF_INCLUDE) +LITEOS_DFX_INCLUDE := $(LITEOS_HILOG_INCLUDE) \ + $(LITEOS_BLACKBOX_INCLUDE) \ + $(LITEOS_HIDUMPER_INCLUDE) + +LITEOS_SECURITY_INCLUDE := $(LITEOS_SECURITY_CAP_INC) $(LITEOS_SECURITY_VID_INC) +LITEOS_TOOLS_DEBUG_INCLUDE := $(LITEOS_SHELL_INCLUDE) $(LITEOS_UART_INCLUDE) \ + $(LITEOS_TELNET_INCLUDE) + +LITEOS_COMMON_OPTS := -fno-pic -fno-builtin -nostdinc -nostdlib -Wall -Werror -fms-extensions -fno-omit-frame-pointer -Wno-address-of-packed-member -Winvalid-pch + +LITEOS_CXXOPTS_BASE += $(LITEOS_COMMON_OPTS) -std=c++11 -nostdinc++ -fexceptions -fpermissive -fno-use-cxa-atexit -frtti + +LITEOS_COPTS_BASE += $(LITEOS_COMMON_OPTS) $(LITEOS_SSP) -fno-strict-aliasing -fno-common -fsigned-char -mno-unaligned-access +ifneq ($(LOSCFG_COMPILER_CLANG_LLVM), y) +LITEOS_COPTS_BASE += -fno-aggressive-loop-optimizations +endif + +LITEOS_COPTS_EXTRA += -std=c99 -Wpointer-arith -Wstrict-prototypes -ffunction-sections -fdata-sections -fno-exceptions -fno-short-enums +LITEOS_COPTS_EXTRA += -Wno-strict-prototypes -Wno-deprecated-non-prototype -Wno-unused-but-set-variable + +ifeq ($(LOSCFG_ARCH_ARM_AARCH32), y) +ifneq ($(LOSCFG_COMPILER_CLANG_LLVM), y) +LITEOS_COPTS_EXTRA += -mthumb-interwork +endif +endif + +ifeq ($(LOSCFG_THUMB), y) +ifeq ($(LOSCFG_COMPILER_CLANG_LLVM), y) +LITEOS_CFLAGS_INTERWORK := -mthumb -mimplicit-it=thumb +else +LITEOS_CFLAGS_INTERWORK := -mthumb -Wa,-mimplicit-it=thumb +endif +endif + +# kernel configuration macros +LITEOS_CMACRO += -imacros "$(LITEOS_MENUCONFIG_H)" + +ifneq ($(LOSCFG_COMPILER_CLANG_LLVM), y) +LITEOS_LD_OPTS += -nostartfiles +endif +LITEOS_LD_OPTS += -static --gc-sections +LITEOS_LD_PATH += -L$(OUT)/lib + +ifeq ($(LOSCFG_COMPILER_CLANG_LLVM), y) +LITEOS_LD_SCRIPT := -T$(LITEOSTOPDIR)/tools/build/liteos_llvm.ld +else +LITEOS_LD_SCRIPT := -T$(LITEOSTOPDIR)/tools/build/liteos.ld +endif + +##compiler## +LITEOS_BASELIB += $(shell $(CC) $(LITEOS_CORE_COPTS) "-print-libgcc-file-name") +LITEOS_LIB_INCLUDE += -isystem $(shell $(CC) $(LITEOS_CORE_COPTS) "-print-file-name=include") diff --git a/src/kernel_liteos_a/tools/build/mk/module.mk b/src/kernel_liteos_a/tools/build/mk/module.mk new file mode 100644 index 00000000..7fc3d907 --- /dev/null +++ b/src/kernel_liteos_a/tools/build/mk/module.mk @@ -0,0 +1,76 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +OBJOUT = $(OUT)/obj +TOPDIR = $(abspath $(LITEOSTOPDIR)/../..) + +TARGET = $(OUT)/lib/lib$(MODULE_NAME).a + +LOCAL_OBJS = $(addprefix $(OBJOUT)/,$(addsuffix .o,$(basename $(subst $(TOPDIR)/,,$(abspath $(LOCAL_SRCS)))))) + +all : $(TARGET) + +ifeq ($(HIDE),@) +ECHO = $1 = echo " $1" $$(patsubst $$(OUT)/%,%,$$@) && $1(){ if ! $($1) "$$$$@"; then echo command details: $($1) "$$$$@"; false; fi;};$1 +$(foreach cmd,CC GPP AS AR LD,$(eval $(call ECHO,$(cmd)))) +endif + +LOCAL_FLAGS += -MD -MP +-include $(LOCAL_OBJS:%.o=%.d) + +$(OBJOUT)/%.o: $(TOPDIR)/%.c + $(HIDE)$(CC) $(CFLAGS) $(LOCAL_FLAGS) $(LOCAL_CFLAGS) -c $< -o $@ + +$(OBJOUT)/%.o: $(TOPDIR)/%.cpp + $(HIDE)$(GPP) $(CXXFLAGS) $(LOCAL_FLAGS) $(LOCAL_CPPFLAGS) -c $< -o $@ + +$(OBJOUT)/%.o: $(TOPDIR)/%.S + $(HIDE)$(CC) $(CFLAGS) $(LOCAL_FLAGS) $(LOCAL_ASFLAGS) -c $< -o $@ + +$(OBJOUT)/%.o: $(TOPDIR)/%.s + $(HIDE)$(AS) $(ASFLAGS) $(LOCAL_FLAGS) $(LOCAL_ASFLAGS) -c $< -o $@ + +$(OBJOUT)/%.o: $(TOPDIR)/%.cc + $(HIDE)$(GPP) $(CXXFLAGS) $(LOCAL_FLAGS) $(LOCAL_CPPFLAGS) -c $< -o $@ + +$(OUT)/lib/lib%.a: $(LOCAL_OBJS) + $(HIDE)$(AR) $(ARFLAGS) $@ $^ + +$(OUT)/bin/%: $(LOCAL_OBJS) + $(HIDE)$(GPP) $(LDFLAGS) -o $@ $^ + +$(OUT)/%/:;$(HIDE)mkdir -p $@ + +$(LOCAL_OBJS): | $(dir $(LOCAL_OBJS)) +$(TARGET): | $(dir $(TARGET)) + +clean: + $(HIDE)$(RM) $(TARGET) $(LOCAL_OBJS) + +.PHONY: all clean diff --git a/src/kernel_liteos_a/tools/scripts/make_rootfs/releaseinfo.sh b/src/kernel_liteos_a/tools/scripts/make_rootfs/releaseinfo.sh new file mode 100644 index 00000000..6c247303 --- /dev/null +++ b/src/kernel_liteos_a/tools/scripts/make_rootfs/releaseinfo.sh @@ -0,0 +1,37 @@ +#!/bin/bash +# +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +VERSION=$1 +ROOTFS_DIR=$2 +RELEASE_TIME=$(date "+%Y-%m-%d %H:%M:%S") + +echo VERSION=\"${VERSION}\" > ${ROOTFS_DIR}/etc/os-release +echo RELEASE_TIME=\"${RELEASE_TIME}\" >> ${ROOTFS_DIR}/etc/os-release diff --git a/src/kernel_liteos_a/tools/scripts/make_rootfs/rootfsdir.sh b/src/kernel_liteos_a/tools/scripts/make_rootfs/rootfsdir.sh new file mode 100644 index 00000000..e00cffdf --- /dev/null +++ b/src/kernel_liteos_a/tools/scripts/make_rootfs/rootfsdir.sh @@ -0,0 +1,49 @@ +#!/bin/bash +# +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +set -e + +OUT=$1 +ROOTFS_DIR=$2 +BIN_DIR=${OUT}/bin +LIB_DIR=${OUT}/musl +ETC_DIR=${OUT}/etc + +mkdir -p ${ROOTFS_DIR}/bin ${ROOTFS_DIR}/lib ${ROOTFS_DIR}/usr/bin ${ROOTFS_DIR}/usr/lib ${ROOTFS_DIR}/etc \ +${ROOTFS_DIR}/app ${ROOTFS_DIR}/data ${ROOTFS_DIR}/proc ${ROOTFS_DIR}/dev ${ROOTFS_DIR}/data/system ${ROOTFS_DIR}/data/system/param \ +${ROOTFS_DIR}/system ${ROOTFS_DIR}/system/internal ${ROOTFS_DIR}/system/external +if [ -d "${BIN_DIR}" ] && [ "$(ls -A "${BIN_DIR}")" != "" ]; then + cp -f ${BIN_DIR}/* ${ROOTFS_DIR}/bin +fi +cp -f ${LIB_DIR}/* ${ROOTFS_DIR}/lib + +if [ -e "${ETC_DIR}"/.mkshrc ]; then +cp -f ${ETC_DIR}/.mkshrc ${ROOTFS_DIR}/etc +fi diff --git a/src/kernel_liteos_a/tools/scripts/make_rootfs/rootfsimg.sh b/src/kernel_liteos_a/tools/scripts/make_rootfs/rootfsimg.sh new file mode 100644 index 00000000..816bbb99 --- /dev/null +++ b/src/kernel_liteos_a/tools/scripts/make_rootfs/rootfsimg.sh @@ -0,0 +1,107 @@ +#!/bin/bash +# +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +set -e + +system=$(uname -s) +ROOTFS_DIR=$1 +FSTYPE=$2 +ROOTFS_IMG=${ROOTFS_DIR}"_"${FSTYPE}".img" +JFFS2_TOOL=mkfs.jffs2 +WIN_JFFS2_TOOL=mkfs.jffs2.exe +YAFFS2_TOOL=mkyaffs2image100 +VFAT_TOOL=mkfs.vfat +ROMFS_TOOL=genromfs +MCOPY_TOOL=mcopy + +tool_check() { +local ret='0' +command -v "$1" >/dev/null 2>&1 || { local ret='1'; } +if [ "$ret" -ne 0 ]; then + echo "$1 tool is not exit, please install it" >&2 +fi +return 0 +} + +chmod -R 755 ${ROOTFS_DIR} +if [ -f "${ROOTFS_DIR}/bin/init" ]; then + chmod 700 ${ROOTFS_DIR}/bin/init 2> /dev/null +fi +if [ -f "${ROOTFS_DIR}/bin/shell" ]; then + chmod 700 ${ROOTFS_DIR}/bin/shell 2> /dev/null +fi + +if [ "${FSTYPE}" = "jffs2" ]; then + if [ "${system}" != "Linux" ] ; then + tool_check ${WIN_JFFS2_TOOL} + ${WIN_JFFS2_TOOL} -q -o ${ROOTFS_IMG} -d ${ROOTFS_DIR} --pagesize=4096 + else + tool_check ${JFFS2_TOOL} + ${JFFS2_TOOL} -q -o ${ROOTFS_IMG} -d ${ROOTFS_DIR} --pagesize=4096 + fi +elif [ "${FSTYPE}" = "yaffs2" ]; then + tool_check ${YAFFS2_TOOL} + ${YAFFS2_TOOL} ${ROOTFS_DIR} ${ROOTFS_IMG} 2k 24bit +elif [ "${FSTYPE}" = "romfs" ]; then + tool_check ${ROMFS_TOOL} + ${ROMFS_TOOL} -d ${ROOTFS_DIR} -f ${ROOTFS_IMG} +elif [ "${FSTYPE}" = "vfat" ]; then + if [ "${system}" != "Linux" ] ; then + echo "Unsupported fs type!" >&2 + else + tool_check ${VFAT_TOOL} + tool_check ${MCOPY_TOOL} + BLK_SIZE=512 + CLT_SIZE=2048 + FAT_TAB_NUM=2 + CLT_CNT=$(( ${CLT_SIZE} / ${BLK_SIZE} )) + if [ $# -eq 3 ]; then + IMG_SIZE=$3 + else + FAT32_ITEM_SIZE=4 + RESV_CNT=38 + IMG_MIN_SIZE=1048576 + DU_DIR_SIZE=$(( $(echo $(du -s ${ROOTFS_DIR} | awk '{print $1}')) * 1024 )) + DIR_NUM=$(( $(echo $(ls -lR ${ROOTFS_DIR} | grep "^d" | wc -l | awk '{print $1}')) + 1 )) + DIR_SIZE=$(( ${DU_DIR_SIZE} + ${DIR_NUM} * 4096 )) + IMG_SIZE=$(( ${DIR_SIZE} / (1 - ${FAT_TAB_NUM} * ${FAT32_ITEM_SIZE} / ${CLT_SIZE}) + ${RESV_CNT} * ${BLK_SIZE})) + if [ ${IMG_SIZE} -le ${IMG_MIN_SIZE} ]; then + IMG_SIZE=${IMG_MIN_SIZE} + fi + fi + IMG_CNT=$(( (${IMG_SIZE} + ${BLK_SIZE} - 1) / ${BLK_SIZE} )) + echo mtools_skip_check=1 >> ~/.mtoolsrc + dd if=/dev/zero of=${ROOTFS_IMG} count=${IMG_CNT} bs=${BLK_SIZE} + ${VFAT_TOOL} ${ROOTFS_IMG} -s ${CLT_CNT} -f ${FAT_TAB_NUM} -S ${BLK_SIZE} > /dev/null + ${MCOPY_TOOL} -i ${ROOTFS_IMG} ${ROOTFS_DIR}/* -/ ::/ + fi +else + echo "Unsupported fs type!" >&2 +fi diff --git a/src/kernel_liteos_a/tools/scripts/parse_exc/parse_excinfo.py b/src/kernel_liteos_a/tools/scripts/parse_exc/parse_excinfo.py new file mode 100644 index 00000000..a1ba92d4 --- /dev/null +++ b/src/kernel_liteos_a/tools/scripts/parse_exc/parse_excinfo.py @@ -0,0 +1,265 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import sys +import os +import argparse +import io +import commands + +def find_string(excinfo_file, string): + res = '' + with open(excinfo_file, 'r+') as f: + for lines in f: + if string in lines: + res = lines + break + return res + +def is_kernel_exc(excinfo_file): + res = find_string(excinfo_file, 'excFrom: kernel') + print(res) + return res != '' + +def is_user_exc(excinfo_file): + res = find_string(excinfo_file, 'excFrom: User') + print(res) + return res != '' + +def parse_string_line(excinfo_file, string): + line = find_string(excinfo_file, string) + if line == '': + print("%s is not in %s\n" %(string, excinfo_file)) + return '' + line = line.replace('\n', '') + strlist = line.split(' ') + return strlist + +def parse_kernel_pc_klr(excinfo_file, ohos_image_file, string, addr2line_cmd, objdump_cmd): + #parse pc + with open(excinfo_file, 'r+') as f: + start = 0 + for lines in f.readlines(): + if 'excFrom: kernel' in lines: + if start == 1: + break + start = 1 + if start and string in lines: + lines = lines[lines.find(string):] + strlist = lines.split() + cmd = "%s%s | grep %s: -B 10 -A 5 -w" % (objdump_cmd, ohos_image_file, strlist[2][2:]) + ret = commands.getoutput(cmd) + print(ret) + cmd = "%s%s %s" % (addr2line_cmd, ohos_image_file, strlist[2]) + ret = commands.getoutput(cmd) + ret = ret.split('\n') + print("<%s>%s<%s>\n") % (string, ret[0], strlist[2]) + return 0 + return -1 + +def parse_kernel_lr(excinfo_file, ohos_image_file, addr2line_cmd): + with open(excinfo_file, 'r+') as f: + start = 0 + index = 1 + for lines in f.readlines(): + if 'excFrom: kernel' in lines: + if start == 1: + break + start = 1 + if start and 'lr =' in lines: + lines = lines[lines.find('lr ='):] + strlist = lines.split() + cmd = "%s%s %s" % (addr2line_cmd, ohos_image_file, strlist[2]) + ret = commands.getoutput(cmd) + ret = ret.split('\n') + print("<%.2d>%s<%s>" % (index, ret[0], strlist[2])) + index = index + 1 + +def parse_kernel_exc(excinfo_file, ohos_image_file, addr2line_cmd, objdump_cmd): + #parse pc, klr + ret1 = parse_kernel_pc_klr(excinfo_file, ohos_image_file, 'pc', addr2line_cmd, objdump_cmd) + ret2 = parse_kernel_pc_klr(excinfo_file, ohos_image_file, 'klr', addr2line_cmd, objdump_cmd) + #parse lr + parse_kernel_lr(excinfo_file, ohos_image_file, addr2line_cmd) + return ret1 and ret2 + +def parse_user_pc_ulr(excinfo_file, rootfs_dir, string, addr2line_cmd, objdump_cmd): + #parse pc + with open(excinfo_file, 'r+') as f: + start = 0 + for lines in f.readlines(): + if 'excFrom: User' in lines: + if start == 1: + break + start = 1 + if start and string in lines: + lines = lines[lines.find(string):] + strlist = lines.split() + if len(strlist) < 7: + print('%s is error'%string) + return 0 + cmd = "%s%s%s | grep %s: -B 10 -A 5 -w" % (objdump_cmd, rootfs_dir, strlist[4], strlist[6][2:]) + ret = commands.getoutput(cmd) + print(ret) + cmd = "%s%s%s %s" % (addr2line_cmd, rootfs_dir, strlist[4], strlist[6]) + ret = commands.getoutput(cmd) + ret = ret.split('\n') + print("<%s>%s<%s><%s>\n" % (string, ret[0], strlist[6], strlist[4])) + return 0 + return -1 + +def parse_user_lr(excinfo_file, rootfs_dir, addr2line_cmd): + with open(excinfo_file, 'r+') as f: + start = 0 + index = 1 + for lines in f.readlines(): + if 'excFrom: User' in lines: + if start == 1: + break + start = 1 + if start and 'lr =' in lines: + lines = lines[lines.find('lr ='):] + strlist = lines.split() + if len(strlist) < 11: + print('%s is error' % strlist) + return + cmd = "%s%s%s %s" % (addr2line_cmd, rootfs_dir, strlist[8], strlist[10]) + res = commands.getoutput(cmd) + res = res.split('\n') + print("<%.2d>%s<%s><%s>" % (index, res[0], strlist[10], strlist[8])) + index = index + 1 + +def parse_user_exc(excinfo_file, rootfs_dir, addr2line_cmd, objdump_cmd): + #parse pc ulr + ret1 = parse_user_pc_ulr(excinfo_file, rootfs_dir, 'pc', addr2line_cmd, objdump_cmd) + ret2 = parse_user_pc_ulr(excinfo_file, rootfs_dir, 'ulr', addr2line_cmd, objdump_cmd) + #parse lr + parse_user_lr(excinfo_file, rootfs_dir, addr2line_cmd) + return ret1 and ret2 + +def parse_backtrace(backtrace_file, ohos_image_file, addr2line_cmd): + with open(backtrace_file, 'r+') as f: + find = -1 + start = 0 + index = 1 + for lines in f.readlines(): + if 'backtrace begin' in lines: + if start == 1: + break + start = 1 + if start and 'lr =' in lines: + lines = lines[lines.find('lr ='):] + strlist = lines.split() + cmd = "%s%s %s" % (addr2line_cmd, ohos_image_file, strlist[2]) + ret = commands.getoutput(cmd) + ret = ret.split('\n') + print("\n<%.2d>%s<%s>" % (index, ret[0], strlist[2])) + index = index + 1 + find = 0 + + return find + +def parse_excinfo(excinfo_file, ohos_image_file, rootfs_dir, addr2line_cmd, objdump_cmd): + cmd = "dos2unix %s" % (excinfo_file) + commands.getoutput(cmd) + kernel_exc = is_kernel_exc(excinfo_file) + user_exc = is_user_exc(excinfo_file) + + if kernel_exc == False and user_exc == False: + if parse_backtrace(excinfo_file, ohos_image_file, addr2line_cmd) != 0: + print("%s is not a excinfo or backtrace file\n"%excinfo_file) + return -1 + else: + return 0 + if user_exc: + if rootfs_dir != None: + return parse_user_exc(excinfo_file, rootfs_dir, addr2line_cmd, objdump_cmd) + else: + print('error: rootfs_dir is none') + return -1 + return parse_kernel_exc(excinfo_file, ohos_image_file, addr2line_cmd, objdump_cmd) + +def parse_compiler(compiler): + addr2line = '' + addr2line_cmd = '' + objdump = '' + objdump_cmd = '' + cmd = "which %s" % (compiler) + ret = commands.getoutput(cmd) + if ret == '': + print('%s is not exist'%compiler) + return None + index1 = ret.rfind('gcc') + index2 = ret.rfind('clang') + if index1 != -1: + addr2line = ret[0:index1] + 'addr2line' + objdump = ret[0:index1] + 'objdump' + elif index2 != -1: + index3 = ret.rfind('/') + addr2line = ret[0:index3 + 1] + 'llvm-addr2line' + objdump = ret[0:index3 + 1] + 'llvm-objdump' + else: + print('%s is not arm-xxx-xxx-gcc or clang'%compiler) + return None + addr2line_cmd = addr2line + ' -C -f -e ' + objdump_cmd = objdump + ' -d ' + return [addr2line_cmd, objdump_cmd] + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('--f', help = 'excinfo file or backtrace file') + parser.add_argument('--e', help = 'elf system image file') + parser.add_argument('--r', help = 'the path of rootfs') + parser.add_argument('--c', help = 'compiler [arm-xxx-xxx-gcc/clang]') + args = parser.parse_args() + + if args.f == None or args.e == None: + print("input error\n") + parser.print_help() + return -1 + + excinfo_file = args.f + ohos_image_file = args.e + rootfs_dir = args.r + + addr2line_cmd = 'llvm-addr2line -C -f -e ' + objdump_cmd = 'llvm-objdump -d ' + if args.c != None: + cmd = parse_compiler(args.c) + if cmd == None: + return -1 + addr2line_cmd = cmd[0] + objdump_cmd = cmd[1] + return parse_excinfo(excinfo_file, ohos_image_file, rootfs_dir, addr2line_cmd, objdump_cmd) + +if __name__ == "__main__": + sys.exit(main()) diff --git a/src/kernel_liteos_a/tools/scripts/parse_memory/parse_mem_info.sh b/src/kernel_liteos_a/tools/scripts/parse_memory/parse_mem_info.sh new file mode 100644 index 00000000..746ae614 --- /dev/null +++ b/src/kernel_liteos_a/tools/scripts/parse_memory/parse_mem_info.sh @@ -0,0 +1,127 @@ +#!/bin/bash + +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +set -e + +LOAD_BASE="0x2000000" +LLVM_ADDR2LINE=llvm-addr2line +GCC_ADDR2LINE=addr2line + +get_line() +{ + SYM_ADDR=$(echo $1 | awk '{print $2}') + ELF_OFFSET=$(echo ${SYM_ADDR} | cut -d '[' -f2 | cut -d ']' -f1) + FILE_LINE=$(${ADDR2LINE} -f -e $2 ${ELF_OFFSET} | awk 'NR==2') + if [[ "${FILE_LINE}" == *"?"* ]]; then + typeset ELF_OFFSET=$((ELF_OFFSET+LOAD_BASE)) + ELF_OFFSET=$(echo "obase=16;${ELF_OFFSET}" | bc) + FILE_LINE=$(${ADDR2LINE} -f -e $2 ${ELF_OFFSET} | awk 'NR==2') + fi + echo ${FILE_LINE} +} + +parse_line() +{ + FILE_PATH=$(echo $1 | awk '{print $4}') + ELF_FILE=${FILE_PATH##*/} + ELF_FILE=${ELF_FILE//[$'\t\r\n']} + FLAG=false + for i in $2; do + if [ "${ELF_FILE}" = "$i" ]; then + if [ ! -f "$i" ]; then + echo "Error: no such file: $i" + exit 1 + fi + ELF_FILE_LINE=$(get_line "$1" $i) + if [[ "${ELF_FILE_LINE}" == *"?"* ]] || [ -z "${ELF_FILE_LINE}" ]; then + echo " * Error: you need ensure whether file: "$i" was compiled with -g or not! *" + exit 1 + fi + LINE=$(echo $1 | tr -d '\r') + LINE=$(echo ${LINE} | awk '{print $1,$2}') + echo " "${LINE}" at "${ELF_FILE_LINE} + FLAG=true + break + fi + done + if [[ "${FLAG}" == "false" ]]; then + echo " "$1 + fi +} + +if [ $# -le 1 ]; then + echo "Usage: ./out2line.sh text.txt elf1 elf2 ..." + exit 1 +fi + +read -n5 -p "Compiler is [gcc/llvm]: " ANSWER +case "${ANSWER}" in +(gcc | GCC) + which ${GCC_ADDR2LINE} >/dev/null 2>&1 + if [ $? -eq 0 ]; then + ADDR2LINE=${GCC_ADDR2LINE} + else + echo "${GCC_ADDR2LINE} command not found!" + exit 1 + fi;; +(llvm | LLVM) + which ${LLVM_ADDR2LINE} >/dev/null 2>&1 + if [ $? -eq 0 ]; then + ADDR2LINE=${LLVM_ADDR2LINE} + else + echo "${LLVM_ADDR2LINE} command not found! Trying to use ${GCC_ADDR2LINE}!" + which ${GCC_ADDR2LINE} >/dev/null 2>&1 + if [ $? -eq 0 ]; then + ADDR2LINE=${GCC_ADDR2LINE} + else + echo "${GCC_ADDR2LINE} command not found!" + exit 1 + fi + fi;; +(*) + echo "Error choise!" + exit 1 +esac +echo -e "Now using ${ADDR2LINE} ...\n" + +PARAM_LIST="${*:2}" +cat $1 | while read line; do + HEAD_STRING=$(echo ${line} | awk '{print $1}') + if [[ "${HEAD_STRING}" == *"#"* ]]; then + parse_line "${line}" "${PARAM_LIST}" + else + if [[ "${HEAD_STRING}" == *"["* ]]; then + echo " "${line} + else + echo ${line} + fi + fi +done + From 0faf6677a96c9094a8d859d6e885575f47ba55bb Mon Sep 17 00:00:00 2001 From: Dio Date: Fri, 19 Jan 2024 08:45:25 +0800 Subject: [PATCH 11/33] mem --- doc/泛读报告.docx | Bin 154013 -> 154941 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/doc/泛读报告.docx b/doc/泛读报告.docx index 108df28f038ef932882ad9d3ee76246665c6061f..205293df5de776e773a686cd3b27d9ad08c78928 100644 GIT binary patch delta 13616 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 EFH)Q9Q2+n{ delta 12660 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 F{tp8I>h%Bs From d61d0f23fe99a7166430f8c8dd19ed384c9d3095 Mon Sep 17 00:00:00 2001 From: eee <719747958@qq.com> Date: Fri, 19 Jan 2024 08:52:19 +0800 Subject: [PATCH 12/33] silightly change --- src/kernel_liteos_a/kernel/base/core/los_process.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kernel_liteos_a/kernel/base/core/los_process.c b/src/kernel_liteos_a/kernel/base/core/los_process.c index 1aac6412..2ab53116 100644 --- a/src/kernel_liteos_a/kernel/base/core/los_process.c +++ b/src/kernel_liteos_a/kernel/base/core/los_process.c @@ -2390,7 +2390,7 @@ LITE_OS_SEC_TEXT INT32 LOS_GetUsedPIDList(UINT32 *pidList, INT32 pidMaxNum) INT32 num = 0; UINT32 intSave; UINT32 pid = 1; - // TSK_ENTRY_FUNC + // TSK_ENTRY_FUNC s if (pidList == NULL) { return 0; } From acbcdbb3ad5cd54a93bca770b28178351762371f Mon Sep 17 00:00:00 2001 From: eee <719747958@qq.com> Date: Fri, 19 Jan 2024 08:53:42 +0800 Subject: [PATCH 13/33] lmfao --- .gitignore | 24 ++++++++++++++++++ doc/{绘图1.vsdx => cache/UML用例图.vsdx} | Bin 42479 -> 43805 bytes doc/{ => cache}/image-1.png | Bin doc/{ => cache}/image-2.png | Bin doc/{ => cache}/image-3.png | Bin doc/{ => cache}/image-4.png | Bin doc/{ => cache}/image-5.png | Bin doc/{ => cache}/image-6.png | Bin doc/{ => cache}/image.png | Bin doc/{ => cache}/学习报告.md | 0 doc/{ => cache}/泛读报告.md | 0 11 files changed, 24 insertions(+) create mode 100644 .gitignore rename doc/{绘图1.vsdx => cache/UML用例图.vsdx} (66%) rename doc/{ => cache}/image-1.png (100%) rename doc/{ => cache}/image-2.png (100%) rename doc/{ => cache}/image-3.png (100%) rename doc/{ => cache}/image-4.png (100%) rename doc/{ => cache}/image-5.png (100%) rename doc/{ => cache}/image-6.png (100%) rename doc/{ => cache}/image.png (100%) rename doc/{ => cache}/学习报告.md (100%) rename doc/{ => cache}/泛读报告.md (100%) diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..c796d20f --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +# General ignored file types +*.o +*.a +*.so +*.swp + +# IDE settings +.vscode +.idea +.settings +.cproject +.project + +# VIM files +cscope* +tags + +# Menuconfig temp files +/config.h +/.config +/.config.old + +# Build temp files +/out diff --git a/doc/绘图1.vsdx b/doc/cache/UML用例图.vsdx similarity index 66% rename from doc/绘图1.vsdx rename to doc/cache/UML用例图.vsdx index 39af97a67d6f6e57eb9877dd000928b45df99cc6..d1c233bd6650a2bf324f2c1bf7c1d76e2bf7644f 100644 GIT binary patch delta 12714 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 delta 11447 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 Date: Fri, 19 Jan 2024 09:18:39 +0800 Subject: [PATCH 14/33] =?UTF-8?q?Mem=E6=96=87=E4=BB=B6=E5=86=85=E6=BA=90?= =?UTF-8?q?=E7=A0=81=E6=B3=A8=E9=87=8A=E5=B7=B2=E5=B0=B1=E4=BD=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kernel/base/mem/common/los_memstat.c | 18 +- .../kernel/base/mem/membox/los_membox.c | 223 ++++++++ .../kernel/base/mem/tlsf/los_memory.c | 482 ++++++++++-------- 3 files changed, 490 insertions(+), 233 deletions(-) diff --git a/src/kernel_liteos_a/kernel/base/mem/common/los_memstat.c b/src/kernel_liteos_a/kernel/base/mem/common/los_memstat.c index 91164b4c..03815a3f 100644 --- a/src/kernel_liteos_a/kernel/base/mem/common/los_memstat.c +++ b/src/kernel_liteos_a/kernel/base/mem/common/los_memstat.c @@ -32,9 +32,9 @@ #include "los_memstat_pri.h" #include "los_task_pri.h" - +/// 记录每个任务对内存的使用情况 LITE_OS_SEC_BSS_MINOR STATIC TskMemUsedInfo g_tskMemUsedInfo[LOSCFG_BASE_CORE_TSK_LIMIT]; - +/// 计算指定任务对内存使用增加量 LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemUsedInc(UINT32 usedSize, UINT32 taskID) { if (taskID >= LOSCFG_BASE_CORE_TSK_LIMIT) { @@ -43,9 +43,9 @@ LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemUsedInc(UINT32 usedSize, UINT32 taskID) if (OS_INT_ACTIVE) { return; } - g_tskMemUsedInfo[taskID].memUsed += usedSize; + g_tskMemUsedInfo[taskID].memUsed += usedSize; ///< 叠加 } - +/// 计算指定任务对内存使用减少量 LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemUsedDec(UINT32 usedSize, UINT32 taskID) { if (taskID >= LOSCFG_BASE_CORE_TSK_LIMIT) { @@ -59,9 +59,9 @@ LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemUsedDec(UINT32 usedSize, UINT32 taskID) OsCurrTaskGet()->taskName, g_tskMemUsedInfo[taskID].memUsed, usedSize); return; } - g_tskMemUsedInfo[taskID].memUsed -= usedSize; + g_tskMemUsedInfo[taskID].memUsed -= usedSize; ///< 递减 } - +/// 获取指定任务对内存的使用情况 LITE_OS_SEC_TEXT_MINOR UINT32 OsTaskMemUsage(UINT32 taskID) { if (taskID >= LOSCFG_BASE_CORE_TSK_LIMIT) { @@ -70,7 +70,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsTaskMemUsage(UINT32 taskID) return g_tskMemUsedInfo[taskID].memUsed; } - +/// 清空任务内存使用记录 LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemClear(UINT32 taskID) { if (taskID >= LOSCFG_BASE_CORE_TSK_LIMIT) { @@ -82,8 +82,8 @@ LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemClear(UINT32 taskID) } g_tskMemUsedInfo[taskID].memUsed = 0; } - -#ifdef LOS_MEM_SLAB +// Slab是一种内存分配器,通过将内存划分不同大小的空间分配给对象使用来进行缓存管理,应用于内核对象的缓存。 +#ifdef LOS_MEM_SLAB // LITE_OS_SEC_BSS_MINOR STATIC TskSlabUsedInfo g_tskSlabUsedInfo[LOSCFG_BASE_CORE_TSK_LIMIT]; LITE_OS_SEC_TEXT_MINOR VOID OsTaskSlabUsedInc(UINT32 usedSize, UINT32 taskID) diff --git a/src/kernel_liteos_a/kernel/base/mem/membox/los_membox.c b/src/kernel_liteos_a/kernel/base/mem/membox/los_membox.c index 7a4b66de..4180d3bd 100644 --- a/src/kernel_liteos_a/kernel/base/mem/membox/los_membox.c +++ b/src/kernel_liteos_a/kernel/base/mem/membox/los_membox.c @@ -1,4 +1,22 @@ /* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CON/* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. * @@ -33,6 +51,211 @@ #include "los_hwi.h" #include "los_spinlock.h" +#ifdef LOSCFG_AARCH64 +#define OS_MEMBOX_MAGIC 0xa55a5aa5a55a5aa5 +#else +#define OS_MEMBOX_MAGIC 0xa55a5aa5 +#endif +#define OS_MEMBOX_SET_MAGIC(addr) \ + ((LOS_MEMBOX_NODE *)(addr))->pstNext = (LOS_MEMBOX_NODE *)OS_MEMBOX_MAGIC //设置魔法数字 +#define OS_MEMBOX_CHECK_MAGIC(addr) \ + ((((LOS_MEMBOX_NODE *)(addr))->pstNext == (LOS_MEMBOX_NODE *)OS_MEMBOX_MAGIC) ? LOS_OK : LOS_NOK) + +#define OS_MEMBOX_USER_ADDR(addr) \ + ((VOID *)((UINT8 *)(addr) + OS_MEMBOX_NODE_HEAD_SIZE)) +#define OS_MEMBOX_NODE_ADDR(addr) \ + ((LOS_MEMBOX_NODE *)(VOID *)((UINT8 *)(addr) - OS_MEMBOX_NODE_HEAD_SIZE)) //节块 = (节头 + 节体) addr = 节体 +/* spinlock for mem module, only available on SMP mode */ +LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_memboxSpin); +#define MEMBOX_LOCK(state) LOS_SpinLockSave(&g_memboxSpin, &(state)) ///< 获取静态内存池自旋锁 +#define MEMBOX_UNLOCK(state) LOS_SpinUnlockRestore(&g_memboxSpin, (state))///< 释放静态内存池自旋锁 +/// 检查静态内存块 +STATIC INLINE UINT32 OsCheckBoxMem(const LOS_MEMBOX_INFO *boxInfo, const VOID *node) +{ + UINT32 offset; + + if (boxInfo->uwBlkSize == 0) { + return LOS_NOK; + } + + offset = (UINT32)((UINTPTR)node - (UINTPTR)(boxInfo + 1)); + if ((offset % boxInfo->uwBlkSize) != 0) { + return LOS_NOK; + } + + if ((offset / boxInfo->uwBlkSize) >= boxInfo->uwBlkNum) { + return LOS_NOK; + } + + return OS_MEMBOX_CHECK_MAGIC(node);//检查魔法数字是否被修改过了 +} +/// 初始化一个静态内存池,根据入参设定其起始地址、总大小及每个内存块大小 +LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemboxInit(VOID *pool, UINT32 poolSize, UINT32 blkSize) +{ + LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool;//在内存起始处安置池头 + LOS_MEMBOX_NODE *node = NULL; + UINT32 index; + UINT32 intSave; + + if (pool == NULL) { + return LOS_NOK; + } + + if (blkSize == 0) { + return LOS_NOK; + } + + if (poolSize < sizeof(LOS_MEMBOX_INFO)) { + return LOS_NOK; + } + + MEMBOX_LOCK(intSave); + boxInfo->uwBlkSize = LOS_MEMBOX_ALIGNED(blkSize + OS_MEMBOX_NODE_HEAD_SIZE); //节块总大小(节头+节体) + boxInfo->uwBlkNum = (poolSize - sizeof(LOS_MEMBOX_INFO)) / boxInfo->uwBlkSize;//总节块数量 + boxInfo->uwBlkCnt = 0; //已分配的数量 + if (boxInfo->uwBlkNum == 0) {//只有0块的情况 + MEMBOX_UNLOCK(intSave); + return LOS_NOK; + } + + node = (LOS_MEMBOX_NODE *)(boxInfo + 1);//去除池头,找到第一个节块位置 + + boxInfo->stFreeList.pstNext = node;//池头空闲链表指向第一个节块 + + for (index = 0; index < boxInfo->uwBlkNum - 1; ++index) {//切割节块,挂入空闲链表 + node->pstNext = OS_MEMBOX_NEXT(node, boxInfo->uwBlkSize);//按块大小切割好,统一由pstNext指向 + node = node->pstNext;//node存储了下一个节点的地址信息 + } + + node->pstNext = NULL;//最后一个为null + + MEMBOX_UNLOCK(intSave); + + return LOS_OK; +} +/// 从指定的静态内存池中申请一块静态内存块,整个内核源码只有 OsSwtmrScan中用到了静态内存. +LITE_OS_SEC_TEXT VOID *LOS_MemboxAlloc(VOID *pool) +{ + LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool; + LOS_MEMBOX_NODE *node = NULL; + LOS_MEMBOX_NODE *nodeTmp = NULL; + UINT32 intSave; + + if (pool == NULL) { + return NULL; + } + + MEMBOX_LOCK(intSave); + node = &(boxInfo->stFreeList);//拿到空闲单链表 + if (node->pstNext != NULL) {//不需要遍历链表,因为这是空闲链表 + nodeTmp = node->pstNext;//先记录要使用的节点 + node->pstNext = nodeTmp->pstNext;//不再空闲了,把节点摘出去了. + OS_MEMBOX_SET_MAGIC(nodeTmp);//为已使用的节块设置魔法数字 + boxInfo->uwBlkCnt++;//已使用块数增加 + } + MEMBOX_UNLOCK(intSave); + + return (nodeTmp == NULL) ? NULL : OS_MEMBOX_USER_ADDR(nodeTmp);//返回可用的虚拟地址 +} +/// 释放指定的一块静态内存块 +LITE_OS_SEC_TEXT UINT32 LOS_MemboxFree(VOID *pool, VOID *box) +{ + LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool; + UINT32 ret = LOS_NOK; + UINT32 intSave; + + if ((pool == NULL) || (box == NULL)) { + return LOS_NOK; + } + + MEMBOX_LOCK(intSave); + do { + LOS_MEMBOX_NODE *node = OS_MEMBOX_NODE_ADDR(box);//通过节体获取节块首地址 + if (OsCheckBoxMem(boxInfo, node) != LOS_OK) { + break; + } + + node->pstNext = boxInfo->stFreeList.pstNext;//节块指向空闲链表表头 + boxInfo->stFreeList.pstNext = node;//空闲链表表头反指向它,意味节块排到第一,下次申请将首个分配它 + boxInfo->uwBlkCnt--;//已经使用的内存块减一 + ret = LOS_OK; + } while (0);//将被编译时优化 + MEMBOX_UNLOCK(intSave); + + return ret; +} +/// 清零指定静态内存块的内容 +LITE_OS_SEC_TEXT_MINOR VOID LOS_MemboxClr(VOID *pool, VOID *box) +{ + LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool; + + if ((pool == NULL) || (box == NULL)) { + return; + } + //将魔法数字一并清除了. + (VOID)memset_s(box, (boxInfo->uwBlkSize - OS_MEMBOX_NODE_HEAD_SIZE), 0, + (boxInfo->uwBlkSize - OS_MEMBOX_NODE_HEAD_SIZE)); +} +/// 打印指定静态内存池所有节点信息(打印等级是LOS_INFO_LEVEL),包括内存池起始地址、 +/// 内存块大小、总内存块数量、每个空闲内存块的起始地址、所有内存块的起始地址 +LITE_OS_SEC_TEXT_MINOR VOID LOS_ShowBox(VOID *pool) +{ + UINT32 index; + UINT32 intSave; + LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool; + LOS_MEMBOX_NODE *node = NULL; + + if (pool == NULL) { + return; + } + MEMBOX_LOCK(intSave); + PRINT_INFO("membox(%p,0x%x,0x%x):\r\n", pool, boxInfo->uwBlkSize, boxInfo->uwBlkNum); + PRINT_INFO("free node list:\r\n"); + + for (node = boxInfo->stFreeList.pstNext, index = 0; node != NULL; + node = node->pstNext, ++index) { + PRINT_INFO("(%u,%p)\r\n", index, node); + } + + PRINT_INFO("all node list:\r\n"); + node = (LOS_MEMBOX_NODE *)(boxInfo + 1); + for (index = 0; index < boxInfo->uwBlkNum; ++index, node = OS_MEMBOX_NEXT(node, boxInfo->uwBlkSize)) { + PRINT_INFO("(%u,%p,%p)\r\n", index, node, node->pstNext); + } + MEMBOX_UNLOCK(intSave); +} +/// 获取指定静态内存池的信息,包括内存池中总内存块数量、已经分配出去的内存块数量、每个内存块的大小 +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemboxStatisticsGet(const VOID *boxMem, UINT32 *maxBlk, + UINT32 *blkCnt, UINT32 *blkSize) +{ + if ((boxMem == NULL) || (maxBlk == NULL) || (blkCnt == NULL) || (blkSize == NULL)) { + return LOS_NOK; + } + + *maxBlk = ((OS_MEMBOX_S *)boxMem)->uwBlkNum; + *blkCnt = ((OS_MEMBOX_S *)boxMem)->uwBlkCnt; + *blkSize = ((OS_MEMBOX_S *)boxMem)->uwBlkSize; + + return LOS_OK; +} + +TRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_membox.h" +#include "los_hwi.h" +#include "los_spinlock.h" + #ifdef LOSCFG_AARCH64 #define OS_MEMBOX_MAGIC 0xa55a5aa5a55a5aa5 diff --git a/src/kernel_liteos_a/kernel/base/mem/tlsf/los_memory.c b/src/kernel_liteos_a/kernel/base/mem/tlsf/los_memory.c index 3441b613..5086ca7b 100644 --- a/src/kernel_liteos_a/kernel/base/mem/tlsf/los_memory.c +++ b/src/kernel_liteos_a/kernel/base/mem/tlsf/los_memory.c @@ -43,7 +43,7 @@ #include "los_lms_pri.h" #endif -/* Used to cut non-essential functions. */ +/* Used to cut non-essential functions. | 用于削减非必要功能 */ #define OS_MEM_FREE_BY_TASKID 0 #ifdef LOSCFG_KERNEL_VM #define OS_MEM_EXPAND_ENABLE 1 @@ -56,32 +56,32 @@ /* column num of the output info of mem node */ #define OS_MEM_COLUMN_NUM 8 -UINT8 *m_aucSysMem0 = NULL; -UINT8 *m_aucSysMem1 = NULL; +UINT8 *m_aucSysMem0 = NULL; ///< 异常交互动态内存池地址的起始地址,当不支持异常交互特性时,m_aucSysMem0等于m_aucSysMem1。 +UINT8 *m_aucSysMem1 = NULL; ///< (内核态)系统动态内存池地址的起始地址 #ifdef LOSCFG_MEM_MUL_POOL -VOID *g_poolHead = NULL; +VOID *g_poolHead = NULL; ///内存池头,由它牵引多个内存池 #endif /* The following is the macro definition and interface implementation related to the TLSF. */ /* Supposing a Second Level Index: SLI = 3. */ -#define OS_MEM_SLI 3 +#define OS_MEM_SLI 3 ///< 二级小区间级数, /* Giving 1 free list for each small bucket: 4, 8, 12, up to 124. */ -#define OS_MEM_SMALL_BUCKET_COUNT 31 -#define OS_MEM_SMALL_BUCKET_MAX_SIZE 128 -/* Giving OS_MEM_FREE_LIST_NUM free lists for each large bucket. */ -#define OS_MEM_LARGE_BUCKET_COUNT 24 -#define OS_MEM_FREE_LIST_NUM (1 << OS_MEM_SLI) +#define OS_MEM_SMALL_BUCKET_COUNT 31 ///< 小桶的偏移单位 从 4 ~ 124 ,共32级 +#define OS_MEM_SMALL_BUCKET_MAX_SIZE 128 ///< 小桶的最大数量 +/* Giving OS_MEM_FREE_LIST_NUM free lists for each large bucket. */ +#define OS_MEM_LARGE_BUCKET_COUNT 24 /// 为每个大存储桶空闲列表数量 大桶范围: [2^7, 2^31] ,每个小区间有分为 2^3个小区间 +#define OS_MEM_FREE_LIST_NUM (1 << OS_MEM_SLI) ///< 2^3 = 8 个,即大桶的每个区间又分为8个小区间 /* OS_MEM_SMALL_BUCKET_MAX_SIZE to the power of 2 is 7. */ -#define OS_MEM_LARGE_START_BUCKET 7 +#define OS_MEM_LARGE_START_BUCKET 7 /// 大桶的开始下标 /* The count of free list. */ -#define OS_MEM_FREE_LIST_COUNT (OS_MEM_SMALL_BUCKET_COUNT + (OS_MEM_LARGE_BUCKET_COUNT << OS_MEM_SLI)) +#define OS_MEM_FREE_LIST_COUNT (OS_MEM_SMALL_BUCKET_COUNT + (OS_MEM_LARGE_BUCKET_COUNT << OS_MEM_SLI)) ///< 总链表的数量 32 + 24 * 8 = 224 /* The bitmap is used to indicate whether the free list is empty, 1: not empty, 0: empty. */ -#define OS_MEM_BITMAP_WORDS ((OS_MEM_FREE_LIST_COUNT >> 5) + 1) - -#define OS_MEM_BITMAP_MASK 0x1FU +#define OS_MEM_BITMAP_WORDS ((OS_MEM_FREE_LIST_COUNT >> 5) + 1) ///< 224 >> 5 + 1 = 7 ,为什么要右移 5 因为 2^5 = 32 是一个32位整型的大小 + ///< 而 32 * 7 = 224 ,也就是说用 int[7]当位图就能表示完 224个链表 ,此处,一定要理解好,因为这是理解 TLSF 算法的关键. +#define OS_MEM_BITMAP_MASK 0x1FU ///< 因为一个int型为 32位, 2^5 = 32,所以此处 0x1FU = 5个1 足以. /* Used to find the first bit of 1 in bitmap. */ STATIC INLINE UINT16 OsMemFFS(UINT32 bitmap) @@ -101,7 +101,7 @@ STATIC INLINE UINT32 OsMemLog2(UINT32 size) return OsMemFLS(size); } -/* Get the first level: f = log2(size). */ +/* Get the first level: f = log2(size). | 获取第一级*/ STATIC INLINE UINT32 OsMemFlGet(UINT32 size) { if (size < OS_MEM_SMALL_BUCKET_MAX_SIZE) { @@ -110,56 +110,56 @@ STATIC INLINE UINT32 OsMemFlGet(UINT32 size) return OsMemLog2(size); } -/* Get the second level: s = (size - 2^f) * 2^SLI / 2^f. */ +/* Get the second level: s = (size - 2^f) * 2^SLI / 2^f. | 获取第二级 */ STATIC INLINE UINT32 OsMemSlGet(UINT32 size, UINT32 fl) { return (((size << OS_MEM_SLI) >> fl) - OS_MEM_FREE_LIST_NUM); } /* The following is the memory algorithm related macro definition and interface implementation. */ - +/// 内存池节点 struct OsMemNodeHead { - UINT32 magic; - union { - struct OsMemNodeHead *prev; /* The prev is used for current node points to the previous node */ - struct OsMemNodeHead *next; /* The next is used for last node points to the expand node */ + UINT32 magic; ///< 魔法数字 0xABCDDCBA + union {//注意这里的前后指向的是连续的地址节点,用于分割和合并 + struct OsMemNodeHead *prev; /* The prev is used for current node points to the previous node | prev 用于当前节点指向前一个节点*/ + struct OsMemNodeHead *next; /* The next is used for last node points to the expand node | next 用于最后一个节点指向展开节点*/ } ptr; -#ifdef LOSCFG_MEM_LEAKCHECK - UINTPTR linkReg[LOS_RECORD_LR_CNT]; +#ifdef LOSCFG_MEM_LEAKCHECK //内存泄漏检测 + UINTPTR linkReg[LOS_RECORD_LR_CNT];///< 存放左右节点地址,用于检测 #endif - UINT32 sizeAndFlag; + UINT32 sizeAndFlag; ///< 节点总大小+标签 }; - +/// 已使用内存池节点 struct OsMemUsedNodeHead { - struct OsMemNodeHead header; + struct OsMemNodeHead header;///< 已被使用节点 #if OS_MEM_FREE_BY_TASKID - UINT32 taskID; + UINT32 taskID; ///< 使用节点的任务ID #endif }; - +/// 内存池空闲节点 struct OsMemFreeNodeHead { - struct OsMemNodeHead header; - struct OsMemFreeNodeHead *prev; - struct OsMemFreeNodeHead *next; + struct OsMemNodeHead header; ///< 内存池节点 + struct OsMemFreeNodeHead *prev; ///< 前一个空闲前驱节点 + struct OsMemFreeNodeHead *next; ///< 后一个空闲后继节点 }; - +/// 内存池信息 struct OsMemPoolInfo { - VOID *pool; - UINT32 totalSize; - UINT32 attr; + VOID *pool; ///< 指向内存块基地址,仅做记录而已,真正的分配内存跟它没啥关系 + UINT32 totalSize; ///< 总大小,确定了内存池的边界 + UINT32 attr; ///< 属性 default attr: lock, not expand. #ifdef LOSCFG_MEM_WATERLINE - UINT32 waterLine; /* Maximum usage size in a memory pool */ - UINT32 curUsedSize; /* Current usage size in a memory pool */ + UINT32 waterLine; /* Maximum usage size in a memory pool | 内存吃水线*/ + UINT32 curUsedSize; /* Current usage size in a memory pool | 当前已使用大小*/ #endif }; - +/// 内存池头信息 struct OsMemPoolHead { - struct OsMemPoolInfo info; - UINT32 freeListBitmap[OS_MEM_BITMAP_WORDS]; - struct OsMemFreeNodeHead *freeList[OS_MEM_FREE_LIST_COUNT]; - SPIN_LOCK_S spinlock; + struct OsMemPoolInfo info; ///< 记录内存池的信息 + UINT32 freeListBitmap[OS_MEM_BITMAP_WORDS]; ///< 空闲位图 int[7] = 32 * 7 = 224 > 223 + struct OsMemFreeNodeHead *freeList[OS_MEM_FREE_LIST_COUNT];///< 空闲节点链表 32 + 24 * 8 = 224 + SPIN_LOCK_S spinlock; ///< 操作本池的自旋锁,涉及CPU多核竞争,所以必须得是自旋锁 #ifdef LOSCFG_MEM_MUL_POOL - VOID *nextPool; + VOID *nextPool; ///< 指向下一个内存池 OsMemPoolHead 类型 #endif }; @@ -168,16 +168,16 @@ struct OsMemPoolHead { #define MEM_UNLOCK(pool, state) LOS_SpinUnlockRestore(&(pool)->spinlock, (state)) /* The memory pool support expand. */ -#define OS_MEM_POOL_EXPAND_ENABLE 0x01 +#define OS_MEM_POOL_EXPAND_ENABLE 0x01 ///< 支持扩展 /* The memory pool support no lock. */ -#define OS_MEM_POOL_LOCK_ENABLE 0x02 - -#define OS_MEM_NODE_MAGIC 0xABCDDCBA -#define OS_MEM_MIN_ALLOC_SIZE (sizeof(struct OsMemFreeNodeHead) - sizeof(struct OsMemUsedNodeHead)) - -#define OS_MEM_NODE_USED_FLAG 0x80000000U -#define OS_MEM_NODE_ALIGNED_FLAG 0x40000000U -#define OS_MEM_NODE_LAST_FLAG 0x20000000U /* Sentinel Node */ +#define OS_MEM_POOL_LOCK_ENABLE 0x02 ///< 加锁 + +#define OS_MEM_NODE_MAGIC 0xABCDDCBA ///< 内存节点的魔法数字 +#define OS_MEM_MIN_ALLOC_SIZE (sizeof(struct OsMemFreeNodeHead) - sizeof(struct OsMemUsedNodeHead)) //最小分配空间 +// 必须给指向空闲块的指针留位置 +#define OS_MEM_NODE_USED_FLAG 0x80000000U ///< 已使用标签 +#define OS_MEM_NODE_ALIGNED_FLAG 0x40000000U ///< 对齐标签 +#define OS_MEM_NODE_LAST_FLAG 0x20000000U /* Sentinel Node | 哨兵节点标签*/ #define OS_MEM_NODE_ALIGNED_AND_USED_FLAG (OS_MEM_NODE_USED_FLAG | OS_MEM_NODE_ALIGNED_FLAG | OS_MEM_NODE_LAST_FLAG) #define OS_MEM_NODE_GET_ALIGNED_FLAG(sizeAndFlag) \ @@ -226,32 +226,33 @@ STATIC INLINE UINT32 OsMemAllocCheck(struct OsMemPoolHead *pool, UINT32 intSave) #if OS_MEM_FREE_BY_TASKID STATIC INLINE VOID OsMemNodeSetTaskID(struct OsMemUsedNodeHead *node) { - node->taskID = LOS_CurTaskIDGet(); + node->taskID = LOS_CurTaskIDGet();//将当前任务ID绑定到内存池节点上 } #endif #ifdef LOSCFG_MEM_WATERLINE STATIC INLINE VOID OsMemWaterUsedRecord(struct OsMemPoolHead *pool, UINT32 size) { - pool->info.curUsedSize += size; + pool->info.curUsedSize += size; //延长可使用空间 if (pool->info.curUsedSize > pool->info.waterLine) { - pool->info.waterLine = pool->info.curUsedSize; + pool->info.waterLine = pool->info.curUsedSize; //警戒线加高 } } #else STATIC INLINE VOID OsMemWaterUsedRecord(struct OsMemPoolHead *pool, UINT32 size) { - (VOID)pool; - (VOID)size; + (VOID)pool; + (VOID)size; } #endif #if OS_MEM_EXPAND_ENABLE +/// 更新哨兵节点内容 STATIC INLINE struct OsMemNodeHead *OsMemLastSentinelNodeGet(const struct OsMemNodeHead *sentinelNode) { struct OsMemNodeHead *node = NULL; - VOID *ptr = sentinelNode->ptr.next; - UINT32 size = OS_MEM_NODE_GET_SIZE(sentinelNode->sizeAndFlag); + VOID *ptr = sentinelNode->ptr.next;//返回不连续的内存块 + UINT32 size = OS_MEM_NODE_GET_SIZE(sentinelNode->sizeAndFlag); // 获取大小 while ((ptr != NULL) && (size != 0)) { node = OS_MEM_END_NODE(ptr, size); @@ -261,7 +262,7 @@ STATIC INLINE struct OsMemNodeHead *OsMemLastSentinelNodeGet(const struct OsMemN return node; } - +/// 检查哨兵节点 STATIC INLINE BOOL OsMemSentinelNodeCheck(struct OsMemNodeHead *sentinelNode) { if (!OS_MEM_NODE_GET_USED_FLAG(sentinelNode->sizeAndFlag)) { @@ -274,7 +275,7 @@ STATIC INLINE BOOL OsMemSentinelNodeCheck(struct OsMemNodeHead *sentinelNode) return TRUE; } - +/// 是否为最后一个哨兵节点 STATIC INLINE BOOL OsMemIsLastSentinelNode(struct OsMemNodeHead *sentinelNode) { if (OsMemSentinelNodeCheck(sentinelNode) == FALSE) { @@ -289,11 +290,11 @@ STATIC INLINE BOOL OsMemIsLastSentinelNode(struct OsMemNodeHead *sentinelNode) return FALSE; } - +/// 设置哨兵节点内容 STATIC INLINE VOID OsMemSentinelNodeSet(struct OsMemNodeHead *sentinelNode, VOID *newNode, UINT32 size) { - if (sentinelNode->ptr.next != NULL) { - sentinelNode = OsMemLastSentinelNodeGet(sentinelNode); + if (sentinelNode->ptr.next != NULL) { //哨兵节点有 逻辑地址不连续的衔接内存块 + sentinelNode = OsMemLastSentinelNodeGet(sentinelNode);//更新哨兵节点内容 } sentinelNode->sizeAndFlag = size; @@ -329,14 +330,14 @@ STATIC INLINE struct OsMemNodeHead *PreSentinelNodeGet(const VOID *pool, const s return NULL; } - +/// 大内存释放 UINT32 OsMemLargeNodeFree(const VOID *ptr) { - LosVmPage *page = OsVmVaddrToPage((VOID *)ptr); + LosVmPage *page = OsVmVaddrToPage((VOID *)ptr);//获取物理页 if ((page == NULL) || (page->nPages == 0)) { return LOS_NOK; } - LOS_PhysPagesFreeContiguous((VOID *)ptr, page->nPages); + LOS_PhysPagesFreeContiguous((VOID *)ptr, page->nPages);//释放连续的几个物理页 return LOS_OK; } @@ -375,7 +376,7 @@ STATIC INLINE BOOL TryShrinkPool(const VOID *pool, const struct OsMemNodeHead *n #endif return TRUE; } - +/// 内存池扩展实现 STATIC INLINE INT32 OsMemPoolExpandSub(VOID *pool, UINT32 size, UINT32 intSave) { UINT32 tryCount = MAX_SHRINK_PAGECACHE_TRY; @@ -383,11 +384,11 @@ STATIC INLINE INT32 OsMemPoolExpandSub(VOID *pool, UINT32 size, UINT32 intSave) struct OsMemNodeHead *newNode = NULL; struct OsMemNodeHead *endNode = NULL; - size = ROUNDUP(size + OS_MEM_NODE_HEAD_SIZE, PAGE_SIZE); - endNode = OS_MEM_END_NODE(pool, poolInfo->info.totalSize); + size = ROUNDUP(size + OS_MEM_NODE_HEAD_SIZE, PAGE_SIZE);//圆整 + endNode = OS_MEM_END_NODE(pool, poolInfo->info.totalSize);//获取哨兵节点 RETRY: - newNode = (struct OsMemNodeHead *)LOS_PhysPagesAllocContiguous(size >> PAGE_SHIFT); + newNode = (struct OsMemNodeHead *)LOS_PhysPagesAllocContiguous(size >> PAGE_SHIFT);//申请新的内存池 | 物理内存 if (newNode == NULL) { if (tryCount > 0) { tryCount--; @@ -411,26 +412,26 @@ RETRY: size = (resize == 0) ? size : resize; } #endif - newNode->sizeAndFlag = (size - OS_MEM_NODE_HEAD_SIZE); - newNode->ptr.prev = OS_MEM_END_NODE(newNode, size); - OsMemSentinelNodeSet(endNode, newNode, size); - OsMemFreeNodeAdd(pool, (struct OsMemFreeNodeHead *)newNode); + newNode->sizeAndFlag = (size - OS_MEM_NODE_HEAD_SIZE);//设置新节点大小 + newNode->ptr.prev = OS_MEM_END_NODE(newNode, size);//新节点的前节点指向新节点的哨兵节点 + OsMemSentinelNodeSet(endNode, newNode, size);//设置老内存池的哨兵节点信息,其实就是指向新内存块 + OsMemFreeNodeAdd(pool, (struct OsMemFreeNodeHead *)newNode);//将新节点加入空闲链表 - endNode = OS_MEM_END_NODE(newNode, size); - (VOID)memset(endNode, 0, sizeof(*endNode)); - endNode->ptr.next = NULL; - endNode->magic = OS_MEM_NODE_MAGIC; - OsMemSentinelNodeSet(endNode, NULL, 0); - OsMemWaterUsedRecord(poolInfo, OS_MEM_NODE_HEAD_SIZE); + endNode = OS_MEM_END_NODE(newNode, size);//获取新节点的哨兵节点 + (VOID)memset(endNode, 0, sizeof(*endNode));//清空内存 + endNode->ptr.next = NULL;//新哨兵节点没有后续指向,因为它已成为最后 + endNode->magic = OS_MEM_NODE_MAGIC;//设置新哨兵节的魔法数字 + OsMemSentinelNodeSet(endNode, NULL, 0); //设置新哨兵节点内容 + OsMemWaterUsedRecord(poolInfo, OS_MEM_NODE_HEAD_SIZE);//更新内存池警戒线 return 0; } - +/// 扩展内存池 STATIC INLINE INT32 OsMemPoolExpand(VOID *pool, UINT32 allocSize, UINT32 intSave) { - UINT32 expandDefault = MEM_EXPAND_SIZE(LOS_MemPoolSizeGet(pool)); + UINT32 expandDefault = MEM_EXPAND_SIZE(LOS_MemPoolSizeGet(pool));//至少要扩展现有内存池的 1/8 大小 UINT32 expandSize = MAX(expandDefault, allocSize); - UINT32 tryCount = 1; + UINT32 tryCount = 1;//尝试次数 UINT32 ret; do { @@ -447,7 +448,7 @@ STATIC INLINE INT32 OsMemPoolExpand(VOID *pool, UINT32 allocSize, UINT32 intSave return -1; } - +///< 允许指定内存池扩展 VOID LOS_MemExpandEnable(VOID *pool) { if (pool == NULL) { @@ -486,7 +487,7 @@ STATIC INLINE VOID OsLmsAllocAlignMark(VOID *ptr, VOID *alignedPtr, UINT32 size) g_lms->simpleMark((UINTPTR)ptr + sizeof(UINT32), (UINTPTR)alignedPtr, LMS_SHADOW_REDZONE_U8); } - /* mark remaining as redzone */ + /* mark remining as redzone */ g_lms->simpleMark(LMS_ADDR_ALIGN((UINTPTR)alignedPtr + size), (UINTPTR)OS_MEM_NEXT_NODE(allocNode), LMS_SHADOW_REDZONE_U8); } @@ -522,8 +523,7 @@ STATIC INLINE VOID OsLmsReallocResizeMark(struct OsMemNodeHead *node, UINT32 res g_lms->simpleMark((UINTPTR)node + resize, (UINTPTR)OS_MEM_NEXT_NODE(node), LMS_SHADOW_REDZONE_U8); } #endif - -#ifdef LOSCFG_MEM_LEAKCHECK +#ifdef LOSCFG_MEM_LEAKCHECK //内存泄漏检查 STATIC INLINE VOID OsMemLinkRegisterRecord(struct OsMemNodeHead *node) { LOS_RecordLR(node->linkReg, LOS_RECORD_LR_CNT, LOS_RECORD_LR_CNT, LOS_OMIT_LR_CNT); @@ -549,7 +549,7 @@ STATIC INLINE VOID OsMemUsedNodePrint(struct OsMemNodeHead *node) PRINTK("\n"); } } - +/// 打印已使用的节点 VOID OsMemUsedNodeShow(VOID *pool) { if (pool == NULL) { @@ -626,17 +626,17 @@ STATIC VOID OsMemNodeBacktraceInfo(const struct OsMemNodeHead *tmpNode, STATIC INLINE UINT32 OsMemFreeListIndexGet(UINT32 size) { - UINT32 fl = OsMemFlGet(size); + UINT32 fl = OsMemFlGet(size);//获取一级位图 if (size < OS_MEM_SMALL_BUCKET_MAX_SIZE) { return fl; } - UINT32 sl = OsMemSlGet(size, fl); + UINT32 sl = OsMemSlGet(size, fl);//获取二级位图 return (OS_MEM_SMALL_BUCKET_COUNT + ((fl - OS_MEM_LARGE_START_BUCKET) << OS_MEM_SLI) + sl); } STATIC INLINE struct OsMemFreeNodeHead *OsMemFindCurSuitableBlock(struct OsMemPoolHead *poolHead, - UINT32 index, UINT32 size) + UINT32 index, UINT32 size) { struct OsMemFreeNodeHead *node = NULL; @@ -663,7 +663,7 @@ STATIC INLINE UINT32 OsMemNotEmptyIndexGet(struct OsMemPoolHead *poolHead, UINT3 return OS_MEM_FREE_LIST_COUNT; } - +/// 找到下一个合适的块 STATIC INLINE struct OsMemFreeNodeHead *OsMemFindNextSuitableBlock(VOID *pool, UINT32 size, UINT32 *outIndex) { struct OsMemPoolHead *poolHead = (struct OsMemPoolHead *)pool; @@ -730,13 +730,13 @@ STATIC INLINE VOID OsMemListAdd(struct OsMemPoolHead *pool, UINT32 listIndex, st OsMemSetFreeListBit(pool, listIndex); node->header.magic = OS_MEM_NODE_MAGIC; } - +/// 从空闲链表中删除 STATIC INLINE VOID OsMemListDelete(struct OsMemPoolHead *pool, UINT32 listIndex, struct OsMemFreeNodeHead *node) { if (node == pool->freeList[listIndex]) { pool->freeList[listIndex] = node->next; - if (node->next == NULL) { - OsMemClearFreeListBit(pool, listIndex); + if (node->next == NULL) {//如果链表空了 + OsMemClearFreeListBit(pool, listIndex);//将位图位 置为 0 } else { node->next->prev = NULL; } @@ -748,27 +748,27 @@ STATIC INLINE VOID OsMemListDelete(struct OsMemPoolHead *pool, UINT32 listIndex, } node->header.magic = OS_MEM_NODE_MAGIC; } - +/// 添加一个空闲节点 STATIC INLINE VOID OsMemFreeNodeAdd(VOID *pool, struct OsMemFreeNodeHead *node) { - UINT32 index = OsMemFreeListIndexGet(node->header.sizeAndFlag); + UINT32 index = OsMemFreeListIndexGet(node->header.sizeAndFlag);//根据大小定位索引位 if (index >= OS_MEM_FREE_LIST_COUNT) { LOS_Panic("The index of free lists is error, index = %u\n", index); return; } - OsMemListAdd(pool, index, node); + OsMemListAdd(pool, index, node);//挂入链表 } - +/// 从空闲链表上摘除节点 STATIC INLINE VOID OsMemFreeNodeDelete(VOID *pool, struct OsMemFreeNodeHead *node) { - UINT32 index = OsMemFreeListIndexGet(node->header.sizeAndFlag); + UINT32 index = OsMemFreeListIndexGet(node->header.sizeAndFlag);//根据大小定位索引位 if (index >= OS_MEM_FREE_LIST_COUNT) { LOS_Panic("The index of free lists is error, index = %u\n", index); return; } OsMemListDelete(pool, index, node); } - +//获取一个空闲的节点 STATIC INLINE struct OsMemNodeHead *OsMemFreeNodeGet(VOID *pool, UINT32 size) { struct OsMemPoolHead *poolHead = (struct OsMemPoolHead *)pool; @@ -782,56 +782,67 @@ STATIC INLINE struct OsMemNodeHead *OsMemFreeNodeGet(VOID *pool, UINT32 size) return &firstNode->header; } - +/// 合并节点,和前面的节点合并 node 消失 STATIC INLINE VOID OsMemMergeNode(struct OsMemNodeHead *node) { struct OsMemNodeHead *nextNode = NULL; - node->ptr.prev->sizeAndFlag += node->sizeAndFlag; - nextNode = (struct OsMemNodeHead *)((UINTPTR)node + node->sizeAndFlag); - if (!OS_MEM_NODE_GET_LAST_FLAG(nextNode->sizeAndFlag)) { - nextNode->ptr.prev = node->ptr.prev; + node->ptr.prev->sizeAndFlag += node->sizeAndFlag; //前节点长度变长 + nextNode = (struct OsMemNodeHead *)((UINTPTR)node + node->sizeAndFlag); // 下一个节点位置 + if (!OS_MEM_NODE_GET_LAST_FLAG(nextNode->sizeAndFlag)) {//不是哨兵节点 + nextNode->ptr.prev = node->ptr.prev;//后一个节点的前节点变成前前节点 } } - +/// 切割节点 STATIC INLINE VOID OsMemSplitNode(VOID *pool, struct OsMemNodeHead *allocNode, UINT32 allocSize) { struct OsMemFreeNodeHead *newFreeNode = NULL; struct OsMemNodeHead *nextNode = NULL; - newFreeNode = (struct OsMemFreeNodeHead *)(VOID *)((UINT8 *)allocNode + allocSize); - newFreeNode->header.ptr.prev = allocNode; - newFreeNode->header.sizeAndFlag = allocNode->sizeAndFlag - allocSize; - allocNode->sizeAndFlag = allocSize; - nextNode = OS_MEM_NEXT_NODE(&newFreeNode->header); - if (!OS_MEM_NODE_GET_LAST_FLAG(nextNode->sizeAndFlag)) { - nextNode->ptr.prev = &newFreeNode->header; - if (!OS_MEM_NODE_GET_USED_FLAG(nextNode->sizeAndFlag)) { - OsMemFreeNodeDelete(pool, (struct OsMemFreeNodeHead *)nextNode); - OsMemMergeNode(nextNode); + newFreeNode = (struct OsMemFreeNodeHead *)(VOID *)((UINT8 *)allocNode + allocSize);//切割后出现的新空闲节点,在分配节点的右侧 + newFreeNode->header.ptr.prev = allocNode;//新节点指向前节点,说明是从左到右切割 + newFreeNode->header.sizeAndFlag = allocNode->sizeAndFlag - allocSize;//新空闲节点大小 + allocNode->sizeAndFlag = allocSize;//分配节点大小 + nextNode = OS_MEM_NEXT_NODE(&newFreeNode->header);//获取新节点的下一个节点 + if (!OS_MEM_NODE_GET_LAST_FLAG(nextNode->sizeAndFlag)) {//如果下一个节点不是哨兵节点(末尾节点) + nextNode->ptr.prev = &newFreeNode->header;//下一个节点的前节点为新空闲节点 + if (!OS_MEM_NODE_GET_USED_FLAG(nextNode->sizeAndFlag)) {//如果下一个节点也是空闲的 + OsMemFreeNodeDelete(pool, (struct OsMemFreeNodeHead *)nextNode);//删除下一个节点信息 + OsMemMergeNode(nextNode);//下一个节点和新空闲节点 合并成一个新节点 } } - OsMemFreeNodeAdd(pool, newFreeNode); + OsMemFreeNodeAdd(pool, newFreeNode);//挂入空闲链表 } - +// STATIC INLINE VOID *OsMemCreateUsedNode(VOID *addr) { - struct OsMemUsedNodeHead *node = (struct OsMemUsedNodeHead *)addr; - + struct OsMemUsedNodeHead *node = (struct OsMemUsedNodeHead *)addr;//直接将地址转成使用节点,说明节点信息也存在内存池中 + //这种用法是非常巧妙的 #if OS_MEM_FREE_BY_TASKID - OsMemNodeSetTaskID(node); + OsMemNodeSetTaskID(node);//设置使用内存节点的任务 #endif -#ifdef LOSCFG_KERNEL_LMS +#ifdef LOSCFG_KERNEL_LMS //检测内存泄漏 struct OsMemNodeHead *newNode = (struct OsMemNodeHead *)node; if (g_lms != NULL) { g_lms->mallocMark(newNode, OS_MEM_NEXT_NODE(newNode), OS_MEM_NODE_HEAD_SIZE); } #endif - return node + 1; + return node + 1; //@note_good 这个地方挺有意思的,只是将结构体扩展下,留一个 int 位 ,变成了已使用节点,返回的地址正是要分配给应用的地址 } +/*! + * @brief OsMemPoolInit 内存池初始化 + * 内存池节点部分包含3种类型节点:未使用空闲内存节点(OsMemFreeNodeHead),已使用内存节点(OsMemUsedNodeHead) 和 尾节点(OsMemNodeHead)。 + * \n 每个内存节点维护一个前序指针,指向内存池中上一个内存节点,还维护内存节点的大小和使用标记。 + * \n 空闲内存节点和已使用内存节点后面的内存区域是数据域 + * @param pool + * @param size + * @return + * + * @see + */ STATIC UINT32 OsMemPoolInit(VOID *pool, UINT32 size) { struct OsMemPoolHead *poolHead = (struct OsMemPoolHead *)pool; @@ -853,30 +864,32 @@ STATIC UINT32 OsMemPoolInit(VOID *pool, UINT32 size) #endif LOS_SpinInit(&poolHead->spinlock); - poolHead->info.pool = pool; - poolHead->info.totalSize = size; - poolHead->info.attr = OS_MEM_POOL_LOCK_ENABLE; /* default attr: lock, not expand. */ + poolHead->info.pool = pool; //内存池的起始地址,但注意真正的内存并不是从此处分配,它只是用来记录这个内存块的开始位置而已. + poolHead->info.totalSize = size;//内存池总大小 + poolHead->info.attr = OS_MEM_POOL_LOCK_ENABLE; /* default attr: lock, not expand. | 默认是上锁,不支持扩展,需扩展得另外设置*/ - newNode = OS_MEM_FIRST_NODE(pool); - newNode->sizeAndFlag = (size - sizeof(struct OsMemPoolHead) - OS_MEM_NODE_HEAD_SIZE); - newNode->ptr.prev = NULL; - newNode->magic = OS_MEM_NODE_MAGIC; - OsMemFreeNodeAdd(pool, (struct OsMemFreeNodeHead *)newNode); + newNode = OS_MEM_FIRST_NODE(pool);//跳到第一个节点位置,即跳过结构体本身位置,真正的分配内存是从newNode开始的. + newNode->sizeAndFlag = (size - sizeof(struct OsMemPoolHead) - OS_MEM_NODE_HEAD_SIZE);//这才是可供分配给外界使用的总内存块大小,即数据域 + //OS_MEM_NODE_HEAD_SIZE 叫当前使用节点,即指 newNode占用的空间 + newNode->ptr.prev = NULL;//开始是空指向 + newNode->magic = OS_MEM_NODE_MAGIC;//魔法数字 用于标识这是一个 OsMemNodeHead 节点, 魔法数字不能被覆盖, + OsMemFreeNodeAdd(pool, (struct OsMemFreeNodeHead *)newNode);//添加一个空闲节点,由此有了首个可供分配的空闲节点 /* The last mem node */ - endNode = OS_MEM_END_NODE(pool, size); - endNode->magic = OS_MEM_NODE_MAGIC; -#if OS_MEM_EXPAND_ENABLE - endNode->ptr.next = NULL; - OsMemSentinelNodeSet(endNode, NULL, 0); + endNode = OS_MEM_END_NODE(pool, size);//确定尾节点位置,尾节点没有数据域 + endNode->magic = OS_MEM_NODE_MAGIC; //填入尾节点的魔法数字 +#if OS_MEM_EXPAND_ENABLE //支持扩展 + endNode->ptr.next = NULL;//尾节点没有后继节点 + OsMemSentinelNodeSet(endNode, NULL, 0);//将尾节点设置为哨兵节点 #else - endNode->sizeAndFlag = 0; - endNode->ptr.prev = newNode; + endNode->sizeAndFlag = 0;//0代表没有数据域 + endNode->ptr.prev = newNode;//前驱指针指向第一个节点 OS_MEM_NODE_SET_USED_FLAG(endNode->sizeAndFlag); #endif -#ifdef LOSCFG_MEM_WATERLINE - poolHead->info.curUsedSize = sizeof(struct OsMemPoolHead) + OS_MEM_NODE_HEAD_SIZE; - poolHead->info.waterLine = poolHead->info.curUsedSize; +#ifdef LOSCFG_MEM_WATERLINE //吃水线开关 + poolHead->info.curUsedSize = sizeof(struct OsMemPoolHead) + OS_MEM_NODE_HEAD_SIZE;//内存池已使用了这么多空间,这些都是存内存池自身数据的空间, + //但此处是否还要算是 endNode ? @note_thinking + poolHead->info.waterLine = poolHead->info.curUsedSize; //设置吃水线 #endif #ifdef LOSCFG_KERNEL_LMS if (resize != 0) { @@ -896,13 +909,13 @@ STATIC VOID OsMemPoolDeinit(const VOID *pool, UINT32 size) #endif (VOID)memset_s(pool, size, 0, sizeof(struct OsMemPoolHead)); } - +/// 新增内存池 STATIC UINT32 OsMemPoolAdd(VOID *pool, UINT32 size) { VOID *nextPool = g_poolHead; VOID *curPool = g_poolHead; UINTPTR poolEnd; - while (nextPool != NULL) { + while (nextPool != NULL) {//单链表遍历方式 poolEnd = (UINTPTR)nextPool + LOS_MemPoolSizeGet(nextPool); if (((pool <= nextPool) && (((UINTPTR)pool + size) > (UINTPTR)nextPool)) || (((UINTPTR)pool < poolEnd) && (((UINTPTR)pool + size) >= poolEnd))) { @@ -916,15 +929,15 @@ STATIC UINT32 OsMemPoolAdd(VOID *pool, UINT32 size) } if (g_poolHead == NULL) { - g_poolHead = pool; + g_poolHead = pool; //首个内存池 } else { - ((struct OsMemPoolHead *)curPool)->nextPool = pool; + ((struct OsMemPoolHead *)curPool)->nextPool = pool; //两池扯上关系 } - ((struct OsMemPoolHead *)pool)->nextPool = NULL; + ((struct OsMemPoolHead *)pool)->nextPool = NULL; //新池下一个无所指 return LOS_OK; } - +/// 删除内存池 STATIC UINT32 OsMemPoolDelete(const VOID *pool) { UINT32 ret = LOS_NOK; @@ -955,29 +968,39 @@ STATIC UINT32 OsMemPoolDelete(const VOID *pool) } #endif +/*! + * @brief LOS_MemInit 初始化一块指定的动态内存池,大小为size + * 初始一个内存池后生成一个内存池控制头、尾节点EndNode,剩余的内存被标记为FreeNode内存节点。 + * @param pool + * @param size + * @return + * @attention EndNode作为内存池末尾的节点,size为0。 + * @see + */ UINT32 LOS_MemInit(VOID *pool, UINT32 size) { if ((pool == NULL) || (size <= OS_MEM_MIN_POOL_SIZE)) { return OS_ERROR; } - size = OS_MEM_ALIGN(size, OS_MEM_ALIGN_SIZE); + size = OS_MEM_ALIGN(size, OS_MEM_ALIGN_SIZE);//4个字节对齐 if (OsMemPoolInit(pool, size)) { return OS_ERROR; } -#ifdef LOSCFG_MEM_MUL_POOL +#ifdef LOSCFG_MEM_MUL_POOL //多内存池开关 if (OsMemPoolAdd(pool, size)) { (VOID)OsMemPoolDeInit(pool, size); return OS_ERROR; } #endif - OsHookCall(LOS_HOOK_TYPE_MEM_INIT, pool, size); + OsHookCall(LOS_HOOK_TYPE_MEM_INIT, pool, size);//打印日志 return LOS_OK; } #ifdef LOSCFG_MEM_MUL_POOL +/// 删除指定内存池 UINT32 LOS_MemDeInit(VOID *pool) { struct OsMemPoolHead *tmpPool = (struct OsMemPoolHead *)pool; @@ -997,7 +1020,7 @@ UINT32 LOS_MemDeInit(VOID *pool) OsHookCall(LOS_HOOK_TYPE_MEM_DEINIT, tmpPool); return LOS_OK; } - +/// 打印系统中已初始化的所有内存池,包括内存池的起始地址、内存池大小、空闲内存总大小、已使用内存总大小、最大的空闲内存块大小、空闲内存块数量、已使用的内存块数量。 UINT32 LOS_MemPoolList(VOID) { VOID *nextPool = g_poolHead; @@ -1011,7 +1034,7 @@ UINT32 LOS_MemPoolList(VOID) return index; } #endif - +/// 从指定动态内存池中申请size长度的内存 STATIC INLINE VOID *OsMemAlloc(struct OsMemPoolHead *pool, UINT32 size, UINT32 intSave) { struct OsMemNodeHead *allocNode = NULL; @@ -1024,15 +1047,15 @@ STATIC INLINE VOID *OsMemAlloc(struct OsMemPoolHead *pool, UINT32 size, UINT32 i UINT32 allocSize = OS_MEM_ALIGN(size + OS_MEM_NODE_HEAD_SIZE, OS_MEM_ALIGN_SIZE); #if OS_MEM_EXPAND_ENABLE -retry: +retry: //这种写法也挺赞的 @note_good #endif - allocNode = OsMemFreeNodeGet(pool, allocSize); - if (allocNode == NULL) { + allocNode = OsMemFreeNodeGet(pool, allocSize);//获取空闲节点 + if (allocNode == NULL) {//没有内存了,怎搞? #if OS_MEM_EXPAND_ENABLE if (pool->info.attr & OS_MEM_POOL_EXPAND_ENABLE) { - INT32 ret = OsMemPoolExpand(pool, allocSize, intSave); + INT32 ret = OsMemPoolExpand(pool, allocSize, intSave);//扩展内存池 if (ret == 0) { - goto retry; + goto retry;//再来一遍 } } #endif @@ -1047,22 +1070,22 @@ retry: return NULL; } - if ((allocSize + OS_MEM_NODE_HEAD_SIZE + OS_MEM_MIN_ALLOC_SIZE) <= allocNode->sizeAndFlag) { - OsMemSplitNode(pool, allocNode, allocSize); + if ((allocSize + OS_MEM_NODE_HEAD_SIZE + OS_MEM_MIN_ALLOC_SIZE) <= allocNode->sizeAndFlag) {//所需小于内存池可供分配量 + OsMemSplitNode(pool, allocNode, allocSize);//劈开内存池 } - OS_MEM_NODE_SET_USED_FLAG(allocNode->sizeAndFlag); - OsMemWaterUsedRecord(pool, OS_MEM_NODE_GET_SIZE(allocNode->sizeAndFlag)); + OS_MEM_NODE_SET_USED_FLAG(allocNode->sizeAndFlag);//给节点贴上已使用的标签 + OsMemWaterUsedRecord(pool, OS_MEM_NODE_GET_SIZE(allocNode->sizeAndFlag));//更新吃水线 -#ifdef LOSCFG_MEM_LEAKCHECK +#ifdef LOSCFG_MEM_LEAKCHECK //检测内存泄漏开关 OsMemLinkRegisterRecord(allocNode); #endif - return OsMemCreateUsedNode((VOID *)allocNode); + return OsMemCreateUsedNode((VOID *)allocNode);//创建已使用节点 } - +/// 从指定内存池中申请size长度的内存,注意这可不是从内核堆空间中申请内存 VOID *LOS_MemAlloc(VOID *pool, UINT32 size) { - if ((pool == NULL) || (size == 0)) { + if ((pool == NULL) || (size == 0)) {//没提供内存池时 return (size > 0) ? OsVmBootMemAlloc(size) : NULL; } @@ -1079,14 +1102,14 @@ VOID *LOS_MemAlloc(VOID *pool, UINT32 size) break; } MEM_LOCK(poolHead, intSave); - ptr = OsMemAlloc(poolHead, size, intSave); + ptr = OsMemAlloc(poolHead, size, intSave);//真正的分配内存函数,详细查看 鸿蒙内核源码分析(内存池篇) MEM_UNLOCK(poolHead, intSave); } while (0); - OsHookCall(LOS_HOOK_TYPE_MEM_ALLOC, pool, ptr, size); + OsHookCall(LOS_HOOK_TYPE_MEM_ALLOC, pool, ptr, size);//打印日志,到此一游 return ptr; } - +/// 从指定内存池中申请size长度的内存且地址按boundary字节对齐的内存 VOID *LOS_MemAllocAlign(VOID *pool, UINT32 size, UINT32 boundary) { UINT32 gapSize; @@ -1143,10 +1166,10 @@ VOID *LOS_MemAllocAlign(VOID *pool, UINT32 size, UINT32 boundary) ptr = alignedPtr; } while (0); - OsHookCall(LOS_HOOK_TYPE_MEM_ALLOCALIGN, pool, ptr, size, boundary); + OsHookCall(LOS_HOOK_TYPE_MEM_ALLOCALIGN, pool, ptr, size, boundary);//打印对齐日志,表示程序曾临幸过此处 return ptr; } - +/// 内存池有效性检查 STATIC INLINE BOOL OsMemAddrValidCheck(const struct OsMemPoolHead *pool, const VOID *addr) { UINT32 size; @@ -1160,7 +1183,7 @@ STATIC INLINE BOOL OsMemAddrValidCheck(const struct OsMemPoolHead *pool, const V if (OS_MEM_MIDDLE_ADDR_OPEN_END(pool + 1, addr, (UINTPTR)pool + size)) { return TRUE; } -#if OS_MEM_EXPAND_ENABLE +#if OS_MEM_EXPAND_ENABLE //如果支持可扩展 struct OsMemNodeHead *node = NULL; struct OsMemNodeHead *sentinel = OS_MEM_END_NODE(pool, size); while (OsMemIsLastSentinelNode(sentinel) == FALSE) { @@ -1250,7 +1273,7 @@ STATIC UINT32 OsMemCheckUsedNode(const struct OsMemPoolHead *pool, const struct return LOS_OK; } - +/// 释放内存 STATIC INLINE UINT32 OsMemFree(struct OsMemPoolHead *pool, struct OsMemNodeHead *node) { UINT32 ret = OsMemCheckUsedNode(pool, node); @@ -1260,10 +1283,10 @@ STATIC INLINE UINT32 OsMemFree(struct OsMemPoolHead *pool, struct OsMemNodeHead } #ifdef LOSCFG_MEM_WATERLINE - pool->info.curUsedSize -= OS_MEM_NODE_GET_SIZE(node->sizeAndFlag); + pool->info.curUsedSize -= OS_MEM_NODE_GET_SIZE(node->sizeAndFlag);//降低水位线 #endif - node->sizeAndFlag = OS_MEM_NODE_GET_SIZE(node->sizeAndFlag); + node->sizeAndFlag = OS_MEM_NODE_GET_SIZE(node->sizeAndFlag);//获取大小和标记 #ifdef LOSCFG_MEM_LEAKCHECK OsMemLinkRegisterRecord(node); #endif @@ -1274,17 +1297,17 @@ STATIC INLINE UINT32 OsMemFree(struct OsMemPoolHead *pool, struct OsMemNodeHead g_lms->check((UINTPTR)node + OS_MEM_NODE_HEAD_SIZE, TRUE); } #endif - struct OsMemNodeHead *preNode = node->ptr.prev; /* merage preNode */ + struct OsMemNodeHead *preNode = node->ptr.prev; /* merage preNode | 合并前一个节点*/ if ((preNode != NULL) && !OS_MEM_NODE_GET_USED_FLAG(preNode->sizeAndFlag)) { - OsMemFreeNodeDelete(pool, (struct OsMemFreeNodeHead *)preNode); - OsMemMergeNode(node); + OsMemFreeNodeDelete(pool, (struct OsMemFreeNodeHead *)preNode);//删除前节点的信息 + OsMemMergeNode(node);//向前合并 node = preNode; } - struct OsMemNodeHead *nextNode = OS_MEM_NEXT_NODE(node); /* merage nextNode */ + struct OsMemNodeHead *nextNode = OS_MEM_NEXT_NODE(node); /* merage nextNode | 计算后一个节点位置*/ if ((nextNode != NULL) && !OS_MEM_NODE_GET_USED_FLAG(nextNode->sizeAndFlag)) { - OsMemFreeNodeDelete(pool, (struct OsMemFreeNodeHead *)nextNode); - OsMemMergeNode(nextNode); + OsMemFreeNodeDelete(pool, (struct OsMemFreeNodeHead *)nextNode);//删除后节点信息 + OsMemMergeNode(nextNode);//合并节点 } #if OS_MEM_EXPAND_ENABLE @@ -1305,7 +1328,7 @@ STATIC INLINE UINT32 OsMemFree(struct OsMemPoolHead *pool, struct OsMemNodeHead #endif return ret; } - +/// 释放从指定动态内存中申请的内存 UINT32 LOS_MemFree(VOID *pool, VOID *ptr) { UINT32 intSave; @@ -1321,13 +1344,13 @@ UINT32 LOS_MemFree(VOID *pool, VOID *ptr) struct OsMemNodeHead *node = NULL; do { - UINT32 gapSize = *(UINT32 *)((UINTPTR)ptr - sizeof(UINT32)); + UINT32 gapSize = *(UINT32 *)((UINTPTR)ptr - sizeof(UINT32));//获取节点大小和标签 即: sizeAndFlag if (OS_MEM_NODE_GET_ALIGNED_FLAG(gapSize) && OS_MEM_NODE_GET_USED_FLAG(gapSize)) { PRINT_ERR("[%s:%d]gapSize:0x%x error\n", __FUNCTION__, __LINE__, gapSize); break; } - node = (struct OsMemNodeHead *)((UINTPTR)ptr - OS_MEM_NODE_HEAD_SIZE); + node = (struct OsMemNodeHead *)((UINTPTR)ptr - OS_MEM_NODE_HEAD_SIZE);//定位到节点开始位置 if (OS_MEM_NODE_GET_ALIGNED_FLAG(gapSize)) { gapSize = OS_MEM_NODE_GET_ALIGNED_GAPSIZE(gapSize); @@ -1415,7 +1438,7 @@ STATIC INLINE VOID *OsGetRealPtr(const VOID *pool, VOID *ptr) } STATIC INLINE VOID *OsMemRealloc(struct OsMemPoolHead *pool, const VOID *ptr, - struct OsMemNodeHead *node, UINT32 size, UINT32 intSave) + struct OsMemNodeHead *node, UINT32 size, UINT32 intSave) { struct OsMemNodeHead *nextNode = NULL; UINT32 allocSize = OS_MEM_ALIGN(size + OS_MEM_NODE_HEAD_SIZE, OS_MEM_ALIGN_SIZE); @@ -1446,7 +1469,7 @@ STATIC INLINE VOID *OsMemRealloc(struct OsMemPoolHead *pool, const VOID *ptr, } return tmpPtr; } - +/// 按size大小重新分配内存块,并将原内存块内容拷贝到新内存块。如果新内存块申请成功,则释放原内存块 VOID *LOS_MemRealloc(VOID *pool, VOID *ptr, UINT32 size) { if ((pool == NULL) || OS_MEM_NODE_GET_USED_FLAG(size) || OS_MEM_NODE_GET_ALIGNED_FLAG(size)) { @@ -1539,7 +1562,7 @@ UINT32 LOS_MemFreeByTaskID(VOID *pool, UINT32 taskID) return LOS_OK; } #endif - +/// 获取指定动态内存池的总大小 UINT32 LOS_MemPoolSizeGet(const VOID *pool) { UINT32 count = 0; @@ -1548,23 +1571,23 @@ UINT32 LOS_MemPoolSizeGet(const VOID *pool) return LOS_NOK; } - count += ((struct OsMemPoolHead *)pool)->info.totalSize; + count += ((struct OsMemPoolHead *)pool)->info.totalSize; // 这里的 += 好像没必要吧?, = 就可以了, @note_thinking -#if OS_MEM_EXPAND_ENABLE +#if OS_MEM_EXPAND_ENABLE //支持扩展 UINT32 size; struct OsMemNodeHead *node = NULL; - struct OsMemNodeHead *sentinel = OS_MEM_END_NODE(pool, count); + struct OsMemNodeHead *sentinel = OS_MEM_END_NODE(pool, count);//获取哨兵节点 - while (OsMemIsLastSentinelNode(sentinel) == FALSE) { - size = OS_MEM_NODE_GET_SIZE(sentinel->sizeAndFlag); - node = OsMemSentinelNodeGet(sentinel); - sentinel = OS_MEM_END_NODE(node, size); - count += size; + while (OsMemIsLastSentinelNode(sentinel) == FALSE) {//不是最后一个节点 + size = OS_MEM_NODE_GET_SIZE(sentinel->sizeAndFlag);//数据域大小 + node = OsMemSentinelNodeGet(sentinel);//再获取哨兵节点 + sentinel = OS_MEM_END_NODE(node, size);//获取尾节点 + count += size; //内存池大小变大 } #endif return count; } - +/// 获取指定动态内存池的总使用量大小 UINT32 LOS_MemTotalUsedGet(VOID *pool) { struct OsMemNodeHead *tmpNode = NULL; @@ -1637,7 +1660,7 @@ STATIC UINT32 OsMemAddrValidCheckPrint(const VOID *pool, struct OsMemFreeNodeHea } STATIC UINT32 OsMemIntegrityCheckSub(struct OsMemNodeHead **tmpNode, const VOID *pool, - const struct OsMemNodeHead *endNode) + const struct OsMemNodeHead *endNode) { if (!OS_MEM_MAGIC_VALID(*tmpNode)) { OsMemMagicCheckPrint(tmpNode); @@ -1653,7 +1676,7 @@ STATIC UINT32 OsMemIntegrityCheckSub(struct OsMemNodeHead **tmpNode, const VOID } STATIC UINT32 OsMemFreeListNodeCheck(const struct OsMemPoolHead *pool, - const struct OsMemFreeNodeHead *node) + const struct OsMemFreeNodeHead *node) { if (!OsMemAddrValidCheck(pool, node) || !OsMemAddrValidCheck(pool, node->prev) || @@ -1714,9 +1737,9 @@ OUT: #endif } } - +//对指定内存池做完整性检查, STATIC UINT32 OsMemIntegrityCheck(const struct OsMemPoolHead *pool, struct OsMemNodeHead **tmpNode, - struct OsMemNodeHead **preNode) + struct OsMemNodeHead **preNode) { struct OsMemNodeHead *endNode = OS_MEM_END_NODE(pool, pool->info.totalSize); @@ -1839,7 +1862,7 @@ STATIC INLINE UINT32 OsMemAllocCheck(struct OsMemPoolHead *pool, UINT32 intSave) return LOS_OK; } #endif - +/// 对指定内存池做完整性检查 UINT32 LOS_MemIntegrityCheck(const VOID *pool) { if (pool == NULL) { @@ -1864,7 +1887,7 @@ ERROR_OUT: } STATIC INLINE VOID OsMemInfoGet(struct OsMemPoolHead *poolInfo, struct OsMemNodeHead *node, - LOS_MEM_POOL_STATUS *poolStatus) + LOS_MEM_POOL_STATUS *poolStatus) { UINT32 totalUsedSize = 0; UINT32 totalFreeSize = 0; @@ -1893,8 +1916,17 @@ STATIC INLINE VOID OsMemInfoGet(struct OsMemPoolHead *poolInfo, struct OsMemNode poolStatus->freeNodeNum += freeNodeNum; } +/*! + * @brief LOS_MemInfoGet + * 获取指定内存池的内存结构信息,包括空闲内存大小、已使用内存大小、空闲内存块数量、已使用的内存块数量、最大的空闲内存块大小 + * @param pool + * @param poolStatus + * @return + * + * @see + */ UINT32 LOS_MemInfoGet(VOID *pool, LOS_MEM_POOL_STATUS *poolStatus) -{ +{//内存碎片率计算:同样调用LOS_MemInfoGet接口,可以获取内存池的剩余内存大小和最大空闲内存块大小,然后根据公式(fragment=100-最大空闲内存块大小/剩余内存大小)得出此时的动态内存池碎片率。 struct OsMemPoolHead *poolInfo = pool; if (poolStatus == NULL) { @@ -1975,7 +2007,7 @@ STATIC VOID OsMemInfoPrint(VOID *pool) status.freeNodeNum); #endif } - +/// 打印指定内存池的空闲内存块的大小及数量 UINT32 LOS_MemFreeNodeShow(VOID *pool) { struct OsMemPoolHead *poolInfo = (struct OsMemPoolHead *)pool; @@ -2022,7 +2054,7 @@ UINT32 LOS_MemFreeNodeShow(VOID *pool) return LOS_OK; } - +///内核空间动态内存(堆内存)初始化 , 争取系统动态内存池 STATUS_T OsKHeapInit(size_t size) { STATUS_T ret; @@ -2041,38 +2073,38 @@ STATUS_T OsKHeapInit(size_t size) return -1; } - m_aucSysMem0 = m_aucSysMem1 = ptr; - ret = LOS_MemInit(m_aucSysMem0, size); + m_aucSysMem0 = m_aucSysMem1 = ptr;// 指定内核内存池的位置 + ret = LOS_MemInit(m_aucSysMem0, size); //初始化内存池,供内核分配动态内存 if (ret != LOS_OK) { PRINT_ERR("vmm_kheap_init LOS_MemInit failed!\n"); g_vmBootMemBase -= size; return ret; } #if OS_MEM_EXPAND_ENABLE - LOS_MemExpandEnable(OS_SYS_MEM_ADDR); + LOS_MemExpandEnable(OS_SYS_MEM_ADDR);//支持扩展系统动态内存 #endif return LOS_OK; } - +///< 判断地址是否在堆区 BOOL OsMemIsHeapNode(const VOID *ptr) { - struct OsMemPoolHead *pool = (struct OsMemPoolHead *)m_aucSysMem1; - struct OsMemNodeHead *firstNode = OS_MEM_FIRST_NODE(pool); - struct OsMemNodeHead *endNode = OS_MEM_END_NODE(pool, pool->info.totalSize); + struct OsMemPoolHead *pool = (struct OsMemPoolHead *)m_aucSysMem1;//内核堆区开始地址 + struct OsMemNodeHead *firstNode = OS_MEM_FIRST_NODE(pool);//获取内存池首个节点 + struct OsMemNodeHead *endNode = OS_MEM_END_NODE(pool, pool->info.totalSize);//获取内存池的尾节点 - if (OS_MEM_MIDDLE_ADDR(firstNode, ptr, endNode)) { + if (OS_MEM_MIDDLE_ADDR(firstNode, ptr, endNode)) {//如果在首尾范围内 return TRUE; } -#if OS_MEM_EXPAND_ENABLE - UINT32 intSave; - UINT32 size; - MEM_LOCK(pool, intSave); - while (OsMemIsLastSentinelNode(endNode) == FALSE) { - size = OS_MEM_NODE_GET_SIZE(endNode->sizeAndFlag); - firstNode = OsMemSentinelNodeGet(endNode); - endNode = OS_MEM_END_NODE(firstNode, size); - if (OS_MEM_MIDDLE_ADDR(firstNode, ptr, endNode)) { +#if OS_MEM_EXPAND_ENABLE//内存池经过扩展后,新旧块的虚拟地址是不连续的,所以需要跳块判断 + UINT32 intSave; + UINT32 size;//详细查看百篇博客系列篇之 鸿蒙内核源码分析(内存池篇) + MEM_LOCK(pool, intSave); //获取自旋锁 + while (OsMemIsLastSentinelNode(endNode) == FALSE) { //哨兵节点是内存池结束的标记 + size = OS_MEM_NODE_GET_SIZE(endNode->sizeAndFlag);//获取节点大小 + firstNode = OsMemSentinelNodeGet(endNode);//获取下一块的开始地址 + endNode = OS_MEM_END_NODE(firstNode, size);//获取下一块的尾节点 + if (OS_MEM_MIDDLE_ADDR(firstNode, ptr, endNode)) {//判断地址是否在该块中 MEM_UNLOCK(pool, intSave); return TRUE; } @@ -2081,3 +2113,5 @@ BOOL OsMemIsHeapNode(const VOID *ptr) #endif return FALSE; } + + From 9d1dd5e706e4de7d9f88318c1af6c3db1462faf7 Mon Sep 17 00:00:00 2001 From: dancer <2905764690@qq.com> Date: Fri, 19 Jan 2024 09:25:05 +0800 Subject: [PATCH 15/33] =?UTF-8?q?=E5=95=A6=E5=95=A6=E5=95=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/泛读报告.docx | Bin 154941 -> 145761 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/doc/泛读报告.docx b/doc/泛读报告.docx index 205293df5de776e773a686cd3b27d9ad08c78928..c47306b3f016d12a21464a13ce181140ab32fc1d 100644 GIT binary patch delta 24691 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 S+WVIs3<&5#_5Fql^uGXHGY$O! From e9e8c11bc6dfdc82fc84ef9bd38949e8160c64c9 Mon Sep 17 00:00:00 2001 From: Dio Date: Fri, 19 Jan 2024 09:32:07 +0800 Subject: [PATCH 16/33] =?UTF-8?q?misc=E6=96=87=E4=BB=B6=E5=A4=B9=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E5=B7=B2=E5=B0=B1=E4=BD=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kernel/base/misc/los_stackinfo.c | 37 ++++++++------- .../kernel/base/misc/mempt_shellcmd.c | 2 +- .../kernel/base/misc/swtmr_shellcmd.c | 18 +++---- .../kernel/base/misc/sysinfo_shellcmd.c | 30 ++++++------ .../kernel/base/misc/vm_shellcmd.c | 47 ++++++++++--------- 5 files changed, 69 insertions(+), 65 deletions(-) diff --git a/src/kernel_liteos_a/kernel/base/misc/los_stackinfo.c b/src/kernel_liteos_a/kernel/base/misc/los_stackinfo.c index 6f96a8a5..9eb7a9c0 100644 --- a/src/kernel_liteos_a/kernel/base/misc/los_stackinfo.c +++ b/src/kernel_liteos_a/kernel/base/misc/los_stackinfo.c @@ -38,27 +38,28 @@ #include "shell.h" #endif -const StackInfo *g_stackInfo = NULL; -UINT32 g_stackNum; +const StackInfo *g_stackInfo = NULL; ///< CPU所有工作模式的栈信息 +UINT32 g_stackNum; ///< CPU所有工作模式的栈数量 +///获取栈的吃水线 UINT32 OsStackWaterLineGet(const UINTPTR *stackBottom, const UINTPTR *stackTop, UINT32 *peakUsed) { UINT32 size; const UINTPTR *tmp = NULL; - if (*stackTop == OS_STACK_MAGIC_WORD) { + if (*stackTop == OS_STACK_MAGIC_WORD) {//栈顶值是否等于 magic 0xCCCCCCCC tmp = stackTop + 1; - while ((tmp < stackBottom) && (*tmp == OS_STACK_INIT)) { + while ((tmp < stackBottom) && (*tmp == OS_STACK_INIT)) {//记录从栈顶到栈低有多少个连续的 0xCACACACA tmp++; } - size = (UINT32)((UINTPTR)stackBottom - (UINTPTR)tmp); - *peakUsed = (size == 0) ? size : (size + sizeof(CHAR *)); + size = (UINT32)((UINTPTR)stackBottom - (UINTPTR)tmp);//剩余多少非0xCACACACA的栈空间 + *peakUsed = (size == 0) ? size : (size + sizeof(CHAR *));//得出高峰用值,还剩多少可用 return LOS_OK; } else { - *peakUsed = OS_INVALID_WATERLINE; + *peakUsed = OS_INVALID_WATERLINE;//栈溢出了 return LOS_NOK; } } - +///异常情况下的栈检查,主要就是检查栈顶值有没有被改写 VOID OsExcStackCheck(VOID) { UINT32 index; @@ -71,7 +72,7 @@ VOID OsExcStackCheck(VOID) for (index = 0; index < g_stackNum; index++) { for (cpuid = 0; cpuid < LOSCFG_KERNEL_CORE_NUM; cpuid++) { stackTop = (UINTPTR *)((UINTPTR)g_stackInfo[index].stackTop + cpuid * g_stackInfo[index].stackSize); - if (*stackTop != OS_STACK_MAGIC_WORD) { + if (*stackTop != OS_STACK_MAGIC_WORD) {// 只要栈顶内容不是 0xCCCCCCCCC 就是溢出了. PRINT_ERR("cpu:%u %s overflow , magic word changed to 0x%x\n", LOSCFG_KERNEL_CORE_NUM - 1 - cpuid, g_stackInfo[index].stackName, *stackTop); } @@ -79,6 +80,7 @@ VOID OsExcStackCheck(VOID) } } +///打印栈的信息 把每个CPU的栈信息打印出来 VOID OsExcStackInfo(VOID) { UINT32 index; @@ -93,36 +95,37 @@ VOID OsExcStackInfo(VOID) PrintExcInfo("\n stack name cpu id stack addr total size used size\n" " ---------- ------ --------- -------- --------\n"); - for (index = 0; index < g_stackNum; index++) { - for (cpuid = 0; cpuid < LOSCFG_KERNEL_CORE_NUM; cpuid++) { + for (cpuid = 0; cpuid < LOSCFG_KERNEL_CORE_NUM; cpuid++) {//可以看出 各个CPU的栈是紧挨的的 stackTop = (UINTPTR *)((UINTPTR)g_stackInfo[index].stackTop + cpuid * g_stackInfo[index].stackSize); stack = (UINTPTR *)((UINTPTR)stackTop + g_stackInfo[index].stackSize); - (VOID)OsStackWaterLineGet(stack, stackTop, &size); + (VOID)OsStackWaterLineGet(stack, stackTop, &size);//获取吃水线, 鸿蒙用WaterLine 这个词用的很妙 PrintExcInfo("%11s %-5d %-10p 0x%-8x 0x%-4x\n", g_stackInfo[index].stackName, LOSCFG_KERNEL_CORE_NUM - 1 - cpuid, stackTop, g_stackInfo[index].stackSize, size); } } - OsExcStackCheck(); + OsExcStackCheck();//发生异常时栈检查 } +///注册栈信息 VOID OsExcStackInfoReg(const StackInfo *stackInfo, UINT32 stackNum) { - g_stackInfo = stackInfo; + g_stackInfo = stackInfo; //全局变量指向g_excStack g_stackNum = stackNum; } +///task栈的初始化,设置固定的值. 0xcccccccc 和 0xcacacaca VOID OsStackInit(VOID *stacktop, UINT32 stacksize) { /* initialize the task stack, write magic num to stack top */ - errno_t ret = memset_s(stacktop, stacksize, (INT32)OS_STACK_INIT, stacksize); + errno_t ret = memset_s(stacktop, stacksize, (INT32)OS_STACK_INIT, stacksize);//清一色填 0xCACACACA if (ret == EOK) { - *((UINTPTR *)stacktop) = OS_STACK_MAGIC_WORD; + *((UINTPTR *)stacktop) = OS_STACK_MAGIC_WORD;//0xCCCCCCCCC 中文就是"烫烫烫烫" 这几个字懂点计算机的人都不会陌生了. } } #ifdef LOSCFG_SHELL_CMD_DEBUG -SHELLCMD_ENTRY(stack_shellcmd, CMD_TYPE_EX, "stack", 1, (CmdCallBackFunc)OsExcStackInfo); +SHELLCMD_ENTRY(stack_shellcmd, CMD_TYPE_EX, "stack", 1, (CmdCallBackFunc)OsExcStackInfo);//采用shell命令静态注册方式 #endif diff --git a/src/kernel_liteos_a/kernel/base/misc/mempt_shellcmd.c b/src/kernel_liteos_a/kernel/base/misc/mempt_shellcmd.c index 0e8ec47b..7177ace6 100644 --- a/src/kernel_liteos_a/kernel/base/misc/mempt_shellcmd.c +++ b/src/kernel_liteos_a/kernel/base/misc/mempt_shellcmd.c @@ -193,7 +193,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdUname(INT32 argc, const CHAR *argv[]) if (argc == 1) { if (strcmp(argv[0], "-a") == 0) { - PRINTK("%s %d.%d.%d.%d %s %s\n", KERNEL_NAME, KERNEL_MAJOR, KERNEL_MINOR, KERNEL_PATCH, KERNEL_ITRE, \ + PRINTK("%s %d.%d.%d.%d %s %s\n", KERNEL_NAME, KERNEL_MAJOR, KERNEL_MINOR, KERNEL_PATCH, KERNEL_ITRE,\ __DATE__, __TIME__); return 0; } else if (strcmp(argv[0], "-s") == 0) { diff --git a/src/kernel_liteos_a/kernel/base/misc/swtmr_shellcmd.c b/src/kernel_liteos_a/kernel/base/misc/swtmr_shellcmd.c index 81573ef4..49c8349c 100644 --- a/src/kernel_liteos_a/kernel/base/misc/swtmr_shellcmd.c +++ b/src/kernel_liteos_a/kernel/base/misc/swtmr_shellcmd.c @@ -58,20 +58,21 @@ STATIC VOID OsPrintSwtmrMsg(const SWTMR_CTRL_S *swtmr) (VOID)LOS_SwtmrTimeGet(swtmr->usTimerID, &ticks); PRINTK("%7u%10s%8s%12u%7u%#12x%#12x\n", - swtmr->usTimerID % LOSCFG_BASE_CORE_SWTMR_LIMIT, - g_shellSwtmrStatus[swtmr->ucState], - g_shellSwtmrMode[swtmr->ucMode], - swtmr->uwInterval, + swtmr->usTimerID % LOSCFG_BASE_CORE_SWTMR_LIMIT, //软件定时器ID。 + g_shellSwtmrStatus[swtmr->ucState], //软件定时器状态,状态可能为:"UnUsed", "Created", "Ticking"。 + g_shellSwtmrMode[swtmr->ucMode], //软件定时器模式。模式可能为:"Once", "Period", "NSD(单次定时器,定时结束后不会自动删除)" + swtmr->uwInterval, //软件定时器使用的Tick数。 ticks, - swtmr->uwArg, - swtmr->pfnHandler); + swtmr->uwArg, //传入的参数。 + swtmr->pfnHandler); //回调函数的地址。 } STATIC INLINE VOID OsPrintSwtmrMsgHead(VOID) { PRINTK("\r\nSwTmrID State Mode Interval Count Arg handlerAddr\n"); } - +///shell命令之swtmr 命令用于查询系统软件定时器相关信息。 +//参数缺省时,默认显示所有软件定时器的相关信息。 STATIC UINT32 SwtmrBaseInfoGet(UINT32 timerID) { SWTMR_CTRL_S *swtmr = g_swtmrCBArray; @@ -173,7 +174,6 @@ SWTMR_HELP: PRINTK(" swtmr ID --- Specifies information about a software timer.\n"); return LOS_OK; } - -SHELLCMD_ENTRY(swtmr_shellcmd, CMD_TYPE_EX, "swtmr", 1, (CmdCallBackFunc)OsShellCmdSwtmrInfoGet); +SHELLCMD_ENTRY(swtmr_shellcmd, CMD_TYPE_EX, "swtmr", 1, (CmdCallBackFunc)OsShellCmdSwtmrInfoGet);//采用shell命令静态注册方式 #endif /* LOSCFG_SHELL */ diff --git a/src/kernel_liteos_a/kernel/base/misc/sysinfo_shellcmd.c b/src/kernel_liteos_a/kernel/base/misc/sysinfo_shellcmd.c index b7c56f84..1d3849b2 100644 --- a/src/kernel_liteos_a/kernel/base/misc/sysinfo_shellcmd.c +++ b/src/kernel_liteos_a/kernel/base/misc/sysinfo_shellcmd.c @@ -118,7 +118,7 @@ UINT32 OsShellCmdSwtmrCntGet(VOID) LOS_IntRestore(intSave); return swtmrCnt; } - +///查看系统资源使用情况 LITE_OS_SEC_TEXT_MINOR VOID OsShellCmdSystemInfoGet(VOID) { UINT8 isTaskEnable = TRUE; @@ -137,27 +137,27 @@ LITE_OS_SEC_TEXT_MINOR VOID OsShellCmdSystemInfoGet(VOID) #else UINT8 isSwtmrEnable = FALSE; #endif - +//模块名称 当前使用量 最大可用量 模块是否开启 PRINTK("\n Module Used Total Enabled\n"); PRINTK("--------------------------------------------\n"); PRINTK(" Task %-10u%-10d%s\n", - OsShellCmdTaskCntGet(), - LOSCFG_BASE_CORE_TSK_LIMIT, - SYSINFO_ENABLED(isTaskEnable)); + OsShellCmdTaskCntGet(), //有效任务数 + LOSCFG_BASE_CORE_TSK_LIMIT, //任务最大数 128 + SYSINFO_ENABLED(isTaskEnable));//任务是否失效 YES or NO PRINTK(" Sem %-10u%-10d%s\n", - OsShellCmdSemCntGet(), - LOSCFG_BASE_IPC_SEM_LIMIT, - SYSINFO_ENABLED(isSemEnable)); + OsShellCmdSemCntGet(), //信号量的数量 + LOSCFG_BASE_IPC_SEM_LIMIT, //信号量最大数 1024 + SYSINFO_ENABLED(isSemEnable));//信号量是否失效 YES or NO PRINTK(" Queue %-10u%-10d%s\n", - OsShellCmdQueueCntGet(), - LOSCFG_BASE_IPC_QUEUE_LIMIT, - SYSINFO_ENABLED(isQueueEnable)); + OsShellCmdQueueCntGet(), //队列的数量 + LOSCFG_BASE_IPC_QUEUE_LIMIT, //队列的最大数 1024 + SYSINFO_ENABLED(isQueueEnable));//队列是否失效 YES or NO PRINTK(" SwTmr %-10u%-10d%s\n", - OsShellCmdSwtmrCntGet(), - LOSCFG_BASE_CORE_SWTMR_LIMIT, - SYSINFO_ENABLED(isSwtmrEnable)); + OsShellCmdSwtmrCntGet(), //定时器的数量 + LOSCFG_BASE_CORE_SWTMR_LIMIT, //定时器的总数 1024 + SYSINFO_ENABLED(isSwtmrEnable)); //定时器是否失效 YES or NO } - +///systeminfo命令用于显示当前操作系统内资源使用情况,包括任务、信号量、互斥量、队列、定时器等。 INT32 OsShellCmdSystemInfo(INT32 argc, const CHAR **argv) { if (argc == 0) { diff --git a/src/kernel_liteos_a/kernel/base/misc/vm_shellcmd.c b/src/kernel_liteos_a/kernel/base/misc/vm_shellcmd.c index 445014b3..b8455e8a 100644 --- a/src/kernel_liteos_a/kernel/base/misc/vm_shellcmd.c +++ b/src/kernel_liteos_a/kernel/base/misc/vm_shellcmd.c @@ -54,7 +54,7 @@ #define VMM_CMD "vmm" #define OOM_CMD "oom" #define VMM_PMM_CMD "v2p" - +//dump内核空间 LITE_OS_SEC_TEXT_MINOR VOID OsDumpKernelAspace(VOID) { LosVmSpace *kAspace = LOS_GetKVmSpace(); @@ -104,26 +104,26 @@ LITE_OS_SEC_TEXT_MINOR VOID OsDoDumpVm(pid_t pid) PRINTK("\tThe process [%d] not active\n", pid); } } - +///查看进程的虚拟内存使用情况。vmm [-a / -h / --help], vmm [pid] LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdDumpVm(INT32 argc, const CHAR *argv[]) { - if (argc == 0) { + if (argc == 0) { //没有参数 使用 # vmm 查看所有进程使用虚拟内存的情况 OsDumpAllAspace(); } else if (argc == 1) { pid_t pid = OsPid(argv[0]); - if (strcmp(argv[0], "-a") == 0) { + if (strcmp(argv[0], "-a") == 0) { //# vmm -a 查看所有进程使用虚拟内存的情况 OsDumpAllAspace(); - } else if (strcmp(argv[0], "-k") == 0) { + } else if (strcmp(argv[0], "-k") == 0) {//# vmm -k 查看内核进程使用虚拟内存的情况 OsDumpKernelAspace(); - } else if (pid >= 0) { + } else if (pid >= 0) { //# vmm 3 查看3号进程使用虚拟内存的情况 OsDoDumpVm(pid); - } else if (strcmp(argv[0], "-h") == 0 || strcmp(argv[0], "--help") == 0) { + } else if (strcmp(argv[0], "-h") == 0 || strcmp(argv[0], "--help") == 0) { //# vmm -h 或者 vmm --help OsPrintUsage(); } else { - PRINTK("%s: invalid option: %s\n", VMM_CMD, argv[0]); + PRINTK("%s: invalid option: %s\n", VMM_CMD, argv[0]); //格式错误,输出规范格式 OsPrintUsage(); } - } else { + } else { //多于一个参数 例如 # vmm 3 9 OsPrintUsage(); } @@ -135,7 +135,7 @@ LITE_OS_SEC_TEXT_MINOR VOID V2PPrintUsage(VOID) PRINTK("pid vaddr(0x1000000~0x3e000000), print physical address of virtual address\n" "-h | --help, print v2p command usage\n"); } - +///v2p 虚拟内存对应的物理内存 LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdV2P(INT32 argc, const CHAR *argv[]) { UINT32 vaddr; @@ -180,7 +180,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdV2P(INT32 argc, const CHAR *argv[]) return LOS_OK; } - +///查看系统内存物理页及pagecache物理页使用情况 , Debug版本才具备的命令 # pmm LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdDumpPmm(VOID) { OsVmPhysDump(); @@ -192,12 +192,13 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdDumpPmm(VOID) LITE_OS_SEC_TEXT_MINOR VOID OomPrintUsage(VOID) { - PRINTK("\t-i [interval], set oom check interval (ms)\n" - "\t-m [mem byte], set oom low memory threshold (Byte)\n" - "\t-r [mem byte], set page cache reclaim memory threshold (Byte)\n" - "\t-h | --help, print vmm command usage\n"); + PRINTK("\t-i [interval], set oom check interval (ms)\n" //设置oom线程任务检查的时间间隔。 + "\t-m [mem byte], set oom low memory threshold (Byte)\n" //设置低内存阈值。 + "\t-r [mem byte], set page cache reclaim memory threshold (Byte)\n" //设置pagecache内存回收阈值。 + "\t-h | --help, print vmm command usage\n"); //使用帮助。 } - +///查看和设置低内存阈值以及pagecache内存回收阈值。参数缺省时,显示oom功能当前配置信息。 +//当系统内存不足时,会打印出内存不足的提示信息。 LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdOom(INT32 argc, const CHAR *argv[]) { UINT32 lowMemThreshold; @@ -219,7 +220,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdOom(INT32 argc, const CHAR *argv[]) PRINTK("[oom] low mem threshold %s(byte) invalid.\n", argv[1]); return OS_ERROR; } else { - OomSetLowMemThreashold(lowMemThreshold); + OomSetLowMemThreashold(lowMemThreshold);//设置低内存阈值 } } else if (strcmp(argv[0], "-i") == 0) { checkInterval = strtoul((CHAR *)argv[1], &endPtr, 0); @@ -227,7 +228,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdOom(INT32 argc, const CHAR *argv[]) PRINTK("[oom] check interval %s(us) invalid.\n", argv[1]); return OS_ERROR; } else { - OomSetCheckInterval(checkInterval); + OomSetCheckInterval(checkInterval);//设置oom线程任务检查的时间间隔 } } else if (strcmp(argv[0], "-r") == 0) { reclaimMemThreshold = strtoul((CHAR *)argv[1], &endPtr, 0); @@ -235,7 +236,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdOom(INT32 argc, const CHAR *argv[]) PRINTK("[oom] reclaim mem threshold %s(byte) invalid.\n", argv[1]); return OS_ERROR; } else { - OomSetReclaimMemThreashold(reclaimMemThreshold); + OomSetReclaimMemThreashold(reclaimMemThreshold);//设置pagecache内存回收阈值 } } else { PRINTK("%s: invalid option: %s %s\n", OOM_CMD, argv[0], argv[1]); @@ -250,13 +251,13 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdOom(INT32 argc, const CHAR *argv[]) } #ifdef LOSCFG_SHELL_CMD_DEBUG -SHELLCMD_ENTRY(oom_shellcmd, CMD_TYPE_SHOW, OOM_CMD, 2, (CmdCallBackFunc)OsShellCmdOom); -SHELLCMD_ENTRY(vm_shellcmd, CMD_TYPE_SHOW, VMM_CMD, 1, (CmdCallBackFunc)OsShellCmdDumpVm); -SHELLCMD_ENTRY(v2p_shellcmd, CMD_TYPE_SHOW, VMM_PMM_CMD, 1, (CmdCallBackFunc)OsShellCmdV2P); +SHELLCMD_ENTRY(oom_shellcmd, CMD_TYPE_SHOW, OOM_CMD, 2, (CmdCallBackFunc)OsShellCmdOom);//采用shell命令静态注册方式 +SHELLCMD_ENTRY(vm_shellcmd, CMD_TYPE_SHOW, VMM_CMD, 1, (CmdCallBackFunc)OsShellCmdDumpVm);//采用shell命令静态注册方式 vmm +SHELLCMD_ENTRY(v2p_shellcmd, CMD_TYPE_SHOW, VMM_PMM_CMD, 1, (CmdCallBackFunc)OsShellCmdV2P);//采用shell命令静态注册方式 v2p #endif #ifdef LOSCFG_SHELL -SHELLCMD_ENTRY(pmm_shellcmd, CMD_TYPE_SHOW, "pmm", 0, (CmdCallBackFunc)OsShellCmdDumpPmm); +SHELLCMD_ENTRY(pmm_shellcmd, CMD_TYPE_SHOW, "pmm", 0, (CmdCallBackFunc)OsShellCmdDumpPmm);//采用shell命令静态注册方式 #endif #endif From 2409606bd2cfbf6fbfbc5fca38eccd01e3db92f0 Mon Sep 17 00:00:00 2001 From: eee <719747958@qq.com> Date: Fri, 19 Jan 2024 09:32:36 +0800 Subject: [PATCH 17/33] some changes happens --- doc/cache/~$$进程控制顺序图.~vsdx | Bin 0 -> 4096 bytes doc/cache/进程控制顺序图.vsdx | Bin 0 -> 31931 bytes doc/~$泛读报告.docx | Bin 0 -> 162 bytes doc/泛读报告.docx | Bin 145761 -> 156143 bytes .../kernel/base/mem/common/los_memstat.c | 18 +- .../kernel/base/mem/membox/los_membox.c | 223 -------- .../kernel/base/mem/tlsf/los_memory.c | 482 ++++++++---------- 7 files changed, 233 insertions(+), 490 deletions(-) create mode 100644 doc/cache/~$$进程控制顺序图.~vsdx create mode 100644 doc/cache/进程控制顺序图.vsdx create mode 100644 doc/~$泛读报告.docx diff --git a/doc/cache/~$$进程控制顺序图.~vsdx b/doc/cache/~$$进程控制顺序图.~vsdx new file mode 100644 index 0000000000000000000000000000000000000000..f3ad3b1e37f91454d0e3400f09144749627f80d1 GIT binary patch literal 4096 zcmeHJF;2rk5F95!0Hp{G1)|6YC?X+QX%LMID0u-0kVruyK>+a_p1@0>rhgm=w)gh-W-fcXUcbI|(WXkwCXV9m2f)EjQx0amHYHc8V|<|Z$y zwNxkqpWLg?ua^HAffJ1Q8>5Q^Lq2cts8Tk|Hs1n%@WSzQ-kV?iK@P;jnD+jJXaPk@}AMlFng<+mv~QBVCda9>}Xb z?BR~u0Ozz_&|;Ha@{3n^R(|cbox%U`+xYTc?TlZ&*vhY1xxTJ767Aph0@Y{T6TZW; z^tWrAG2^e8_o{;M8tAg}{2=A?vuLc+U(Y6{`HQ^EZLI%bej&R0FGsh{hW>vWs@-c5 yepl=M)5ojz<&Hp-B=$rr@J#sKxClbr>&N>AxK>k)9{PweFUD`*EY^Kg)$a?@s!^2y literal 0 HcmV?d00001 diff --git a/doc/cache/进程控制顺序图.vsdx b/doc/cache/进程控制顺序图.vsdx new file mode 100644 index 0000000000000000000000000000000000000000..9d0a1f31d626d1d4fe390f2b7c1a9a4a9e86b801 GIT binary patch literal 31931 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 BL4W`N literal 0 HcmV?d00001 diff --git a/doc/~$泛读报告.docx b/doc/~$泛读报告.docx new file mode 100644 index 0000000000000000000000000000000000000000..4ad6b906510457f5e1251738e0b3478879968b88 GIT binary patch literal 162 zcmZRpP;gGn%wZr6urX9HC@?rPBr;?&fb>>8J0rq(oPj|)i3!CZ7!M|HC2{wEnb$4G c8IK_9k01YKUk>C;L3J&w*Aw_xk75J^0DVLjmjD0& literal 0 HcmV?d00001 diff --git a/doc/泛读报告.docx b/doc/泛读报告.docx index c47306b3f016d12a21464a13ce181140ab32fc1d..56a3ce5f5a8f79cdd32c1a7cb67d7058ff546cd1 100644 GIT binary patch delta 35113 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 BKe+$^ delta 24701 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 V{y@$MVgvyML?BRy5N28n`afcd9yI^} diff --git a/src/kernel_liteos_a/kernel/base/mem/common/los_memstat.c b/src/kernel_liteos_a/kernel/base/mem/common/los_memstat.c index 03815a3f..91164b4c 100644 --- a/src/kernel_liteos_a/kernel/base/mem/common/los_memstat.c +++ b/src/kernel_liteos_a/kernel/base/mem/common/los_memstat.c @@ -32,9 +32,9 @@ #include "los_memstat_pri.h" #include "los_task_pri.h" -/// 记录每个任务对内存的使用情况 + LITE_OS_SEC_BSS_MINOR STATIC TskMemUsedInfo g_tskMemUsedInfo[LOSCFG_BASE_CORE_TSK_LIMIT]; -/// 计算指定任务对内存使用增加量 + LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemUsedInc(UINT32 usedSize, UINT32 taskID) { if (taskID >= LOSCFG_BASE_CORE_TSK_LIMIT) { @@ -43,9 +43,9 @@ LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemUsedInc(UINT32 usedSize, UINT32 taskID) if (OS_INT_ACTIVE) { return; } - g_tskMemUsedInfo[taskID].memUsed += usedSize; ///< 叠加 + g_tskMemUsedInfo[taskID].memUsed += usedSize; } -/// 计算指定任务对内存使用减少量 + LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemUsedDec(UINT32 usedSize, UINT32 taskID) { if (taskID >= LOSCFG_BASE_CORE_TSK_LIMIT) { @@ -59,9 +59,9 @@ LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemUsedDec(UINT32 usedSize, UINT32 taskID) OsCurrTaskGet()->taskName, g_tskMemUsedInfo[taskID].memUsed, usedSize); return; } - g_tskMemUsedInfo[taskID].memUsed -= usedSize; ///< 递减 + g_tskMemUsedInfo[taskID].memUsed -= usedSize; } -/// 获取指定任务对内存的使用情况 + LITE_OS_SEC_TEXT_MINOR UINT32 OsTaskMemUsage(UINT32 taskID) { if (taskID >= LOSCFG_BASE_CORE_TSK_LIMIT) { @@ -70,7 +70,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsTaskMemUsage(UINT32 taskID) return g_tskMemUsedInfo[taskID].memUsed; } -/// 清空任务内存使用记录 + LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemClear(UINT32 taskID) { if (taskID >= LOSCFG_BASE_CORE_TSK_LIMIT) { @@ -82,8 +82,8 @@ LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemClear(UINT32 taskID) } g_tskMemUsedInfo[taskID].memUsed = 0; } -// Slab是一种内存分配器,通过将内存划分不同大小的空间分配给对象使用来进行缓存管理,应用于内核对象的缓存。 -#ifdef LOS_MEM_SLAB // + +#ifdef LOS_MEM_SLAB LITE_OS_SEC_BSS_MINOR STATIC TskSlabUsedInfo g_tskSlabUsedInfo[LOSCFG_BASE_CORE_TSK_LIMIT]; LITE_OS_SEC_TEXT_MINOR VOID OsTaskSlabUsedInc(UINT32 usedSize, UINT32 taskID) diff --git a/src/kernel_liteos_a/kernel/base/mem/membox/los_membox.c b/src/kernel_liteos_a/kernel/base/mem/membox/los_membox.c index 4180d3bd..7a4b66de 100644 --- a/src/kernel_liteos_a/kernel/base/mem/membox/los_membox.c +++ b/src/kernel_liteos_a/kernel/base/mem/membox/los_membox.c @@ -1,22 +1,4 @@ /* - * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used - * to endorse or promote products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CON/* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. * @@ -51,211 +33,6 @@ #include "los_hwi.h" #include "los_spinlock.h" -#ifdef LOSCFG_AARCH64 -#define OS_MEMBOX_MAGIC 0xa55a5aa5a55a5aa5 -#else -#define OS_MEMBOX_MAGIC 0xa55a5aa5 -#endif -#define OS_MEMBOX_SET_MAGIC(addr) \ - ((LOS_MEMBOX_NODE *)(addr))->pstNext = (LOS_MEMBOX_NODE *)OS_MEMBOX_MAGIC //设置魔法数字 -#define OS_MEMBOX_CHECK_MAGIC(addr) \ - ((((LOS_MEMBOX_NODE *)(addr))->pstNext == (LOS_MEMBOX_NODE *)OS_MEMBOX_MAGIC) ? LOS_OK : LOS_NOK) - -#define OS_MEMBOX_USER_ADDR(addr) \ - ((VOID *)((UINT8 *)(addr) + OS_MEMBOX_NODE_HEAD_SIZE)) -#define OS_MEMBOX_NODE_ADDR(addr) \ - ((LOS_MEMBOX_NODE *)(VOID *)((UINT8 *)(addr) - OS_MEMBOX_NODE_HEAD_SIZE)) //节块 = (节头 + 节体) addr = 节体 -/* spinlock for mem module, only available on SMP mode */ -LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_memboxSpin); -#define MEMBOX_LOCK(state) LOS_SpinLockSave(&g_memboxSpin, &(state)) ///< 获取静态内存池自旋锁 -#define MEMBOX_UNLOCK(state) LOS_SpinUnlockRestore(&g_memboxSpin, (state))///< 释放静态内存池自旋锁 -/// 检查静态内存块 -STATIC INLINE UINT32 OsCheckBoxMem(const LOS_MEMBOX_INFO *boxInfo, const VOID *node) -{ - UINT32 offset; - - if (boxInfo->uwBlkSize == 0) { - return LOS_NOK; - } - - offset = (UINT32)((UINTPTR)node - (UINTPTR)(boxInfo + 1)); - if ((offset % boxInfo->uwBlkSize) != 0) { - return LOS_NOK; - } - - if ((offset / boxInfo->uwBlkSize) >= boxInfo->uwBlkNum) { - return LOS_NOK; - } - - return OS_MEMBOX_CHECK_MAGIC(node);//检查魔法数字是否被修改过了 -} -/// 初始化一个静态内存池,根据入参设定其起始地址、总大小及每个内存块大小 -LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemboxInit(VOID *pool, UINT32 poolSize, UINT32 blkSize) -{ - LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool;//在内存起始处安置池头 - LOS_MEMBOX_NODE *node = NULL; - UINT32 index; - UINT32 intSave; - - if (pool == NULL) { - return LOS_NOK; - } - - if (blkSize == 0) { - return LOS_NOK; - } - - if (poolSize < sizeof(LOS_MEMBOX_INFO)) { - return LOS_NOK; - } - - MEMBOX_LOCK(intSave); - boxInfo->uwBlkSize = LOS_MEMBOX_ALIGNED(blkSize + OS_MEMBOX_NODE_HEAD_SIZE); //节块总大小(节头+节体) - boxInfo->uwBlkNum = (poolSize - sizeof(LOS_MEMBOX_INFO)) / boxInfo->uwBlkSize;//总节块数量 - boxInfo->uwBlkCnt = 0; //已分配的数量 - if (boxInfo->uwBlkNum == 0) {//只有0块的情况 - MEMBOX_UNLOCK(intSave); - return LOS_NOK; - } - - node = (LOS_MEMBOX_NODE *)(boxInfo + 1);//去除池头,找到第一个节块位置 - - boxInfo->stFreeList.pstNext = node;//池头空闲链表指向第一个节块 - - for (index = 0; index < boxInfo->uwBlkNum - 1; ++index) {//切割节块,挂入空闲链表 - node->pstNext = OS_MEMBOX_NEXT(node, boxInfo->uwBlkSize);//按块大小切割好,统一由pstNext指向 - node = node->pstNext;//node存储了下一个节点的地址信息 - } - - node->pstNext = NULL;//最后一个为null - - MEMBOX_UNLOCK(intSave); - - return LOS_OK; -} -/// 从指定的静态内存池中申请一块静态内存块,整个内核源码只有 OsSwtmrScan中用到了静态内存. -LITE_OS_SEC_TEXT VOID *LOS_MemboxAlloc(VOID *pool) -{ - LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool; - LOS_MEMBOX_NODE *node = NULL; - LOS_MEMBOX_NODE *nodeTmp = NULL; - UINT32 intSave; - - if (pool == NULL) { - return NULL; - } - - MEMBOX_LOCK(intSave); - node = &(boxInfo->stFreeList);//拿到空闲单链表 - if (node->pstNext != NULL) {//不需要遍历链表,因为这是空闲链表 - nodeTmp = node->pstNext;//先记录要使用的节点 - node->pstNext = nodeTmp->pstNext;//不再空闲了,把节点摘出去了. - OS_MEMBOX_SET_MAGIC(nodeTmp);//为已使用的节块设置魔法数字 - boxInfo->uwBlkCnt++;//已使用块数增加 - } - MEMBOX_UNLOCK(intSave); - - return (nodeTmp == NULL) ? NULL : OS_MEMBOX_USER_ADDR(nodeTmp);//返回可用的虚拟地址 -} -/// 释放指定的一块静态内存块 -LITE_OS_SEC_TEXT UINT32 LOS_MemboxFree(VOID *pool, VOID *box) -{ - LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool; - UINT32 ret = LOS_NOK; - UINT32 intSave; - - if ((pool == NULL) || (box == NULL)) { - return LOS_NOK; - } - - MEMBOX_LOCK(intSave); - do { - LOS_MEMBOX_NODE *node = OS_MEMBOX_NODE_ADDR(box);//通过节体获取节块首地址 - if (OsCheckBoxMem(boxInfo, node) != LOS_OK) { - break; - } - - node->pstNext = boxInfo->stFreeList.pstNext;//节块指向空闲链表表头 - boxInfo->stFreeList.pstNext = node;//空闲链表表头反指向它,意味节块排到第一,下次申请将首个分配它 - boxInfo->uwBlkCnt--;//已经使用的内存块减一 - ret = LOS_OK; - } while (0);//将被编译时优化 - MEMBOX_UNLOCK(intSave); - - return ret; -} -/// 清零指定静态内存块的内容 -LITE_OS_SEC_TEXT_MINOR VOID LOS_MemboxClr(VOID *pool, VOID *box) -{ - LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool; - - if ((pool == NULL) || (box == NULL)) { - return; - } - //将魔法数字一并清除了. - (VOID)memset_s(box, (boxInfo->uwBlkSize - OS_MEMBOX_NODE_HEAD_SIZE), 0, - (boxInfo->uwBlkSize - OS_MEMBOX_NODE_HEAD_SIZE)); -} -/// 打印指定静态内存池所有节点信息(打印等级是LOS_INFO_LEVEL),包括内存池起始地址、 -/// 内存块大小、总内存块数量、每个空闲内存块的起始地址、所有内存块的起始地址 -LITE_OS_SEC_TEXT_MINOR VOID LOS_ShowBox(VOID *pool) -{ - UINT32 index; - UINT32 intSave; - LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool; - LOS_MEMBOX_NODE *node = NULL; - - if (pool == NULL) { - return; - } - MEMBOX_LOCK(intSave); - PRINT_INFO("membox(%p,0x%x,0x%x):\r\n", pool, boxInfo->uwBlkSize, boxInfo->uwBlkNum); - PRINT_INFO("free node list:\r\n"); - - for (node = boxInfo->stFreeList.pstNext, index = 0; node != NULL; - node = node->pstNext, ++index) { - PRINT_INFO("(%u,%p)\r\n", index, node); - } - - PRINT_INFO("all node list:\r\n"); - node = (LOS_MEMBOX_NODE *)(boxInfo + 1); - for (index = 0; index < boxInfo->uwBlkNum; ++index, node = OS_MEMBOX_NEXT(node, boxInfo->uwBlkSize)) { - PRINT_INFO("(%u,%p,%p)\r\n", index, node, node->pstNext); - } - MEMBOX_UNLOCK(intSave); -} -/// 获取指定静态内存池的信息,包括内存池中总内存块数量、已经分配出去的内存块数量、每个内存块的大小 -LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemboxStatisticsGet(const VOID *boxMem, UINT32 *maxBlk, - UINT32 *blkCnt, UINT32 *blkSize) -{ - if ((boxMem == NULL) || (maxBlk == NULL) || (blkCnt == NULL) || (blkSize == NULL)) { - return LOS_NOK; - } - - *maxBlk = ((OS_MEMBOX_S *)boxMem)->uwBlkNum; - *blkCnt = ((OS_MEMBOX_S *)boxMem)->uwBlkCnt; - *blkSize = ((OS_MEMBOX_S *)boxMem)->uwBlkSize; - - return LOS_OK; -} - -TRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "los_membox.h" -#include "los_hwi.h" -#include "los_spinlock.h" - #ifdef LOSCFG_AARCH64 #define OS_MEMBOX_MAGIC 0xa55a5aa5a55a5aa5 diff --git a/src/kernel_liteos_a/kernel/base/mem/tlsf/los_memory.c b/src/kernel_liteos_a/kernel/base/mem/tlsf/los_memory.c index 5086ca7b..3441b613 100644 --- a/src/kernel_liteos_a/kernel/base/mem/tlsf/los_memory.c +++ b/src/kernel_liteos_a/kernel/base/mem/tlsf/los_memory.c @@ -43,7 +43,7 @@ #include "los_lms_pri.h" #endif -/* Used to cut non-essential functions. | 用于削减非必要功能 */ +/* Used to cut non-essential functions. */ #define OS_MEM_FREE_BY_TASKID 0 #ifdef LOSCFG_KERNEL_VM #define OS_MEM_EXPAND_ENABLE 1 @@ -56,32 +56,32 @@ /* column num of the output info of mem node */ #define OS_MEM_COLUMN_NUM 8 -UINT8 *m_aucSysMem0 = NULL; ///< 异常交互动态内存池地址的起始地址,当不支持异常交互特性时,m_aucSysMem0等于m_aucSysMem1。 -UINT8 *m_aucSysMem1 = NULL; ///< (内核态)系统动态内存池地址的起始地址 +UINT8 *m_aucSysMem0 = NULL; +UINT8 *m_aucSysMem1 = NULL; #ifdef LOSCFG_MEM_MUL_POOL -VOID *g_poolHead = NULL; ///内存池头,由它牵引多个内存池 +VOID *g_poolHead = NULL; #endif /* The following is the macro definition and interface implementation related to the TLSF. */ /* Supposing a Second Level Index: SLI = 3. */ -#define OS_MEM_SLI 3 ///< 二级小区间级数, +#define OS_MEM_SLI 3 /* Giving 1 free list for each small bucket: 4, 8, 12, up to 124. */ -#define OS_MEM_SMALL_BUCKET_COUNT 31 ///< 小桶的偏移单位 从 4 ~ 124 ,共32级 -#define OS_MEM_SMALL_BUCKET_MAX_SIZE 128 ///< 小桶的最大数量 -/* Giving OS_MEM_FREE_LIST_NUM free lists for each large bucket. */ -#define OS_MEM_LARGE_BUCKET_COUNT 24 /// 为每个大存储桶空闲列表数量 大桶范围: [2^7, 2^31] ,每个小区间有分为 2^3个小区间 -#define OS_MEM_FREE_LIST_NUM (1 << OS_MEM_SLI) ///< 2^3 = 8 个,即大桶的每个区间又分为8个小区间 +#define OS_MEM_SMALL_BUCKET_COUNT 31 +#define OS_MEM_SMALL_BUCKET_MAX_SIZE 128 +/* Giving OS_MEM_FREE_LIST_NUM free lists for each large bucket. */ +#define OS_MEM_LARGE_BUCKET_COUNT 24 +#define OS_MEM_FREE_LIST_NUM (1 << OS_MEM_SLI) /* OS_MEM_SMALL_BUCKET_MAX_SIZE to the power of 2 is 7. */ -#define OS_MEM_LARGE_START_BUCKET 7 /// 大桶的开始下标 +#define OS_MEM_LARGE_START_BUCKET 7 /* The count of free list. */ -#define OS_MEM_FREE_LIST_COUNT (OS_MEM_SMALL_BUCKET_COUNT + (OS_MEM_LARGE_BUCKET_COUNT << OS_MEM_SLI)) ///< 总链表的数量 32 + 24 * 8 = 224 +#define OS_MEM_FREE_LIST_COUNT (OS_MEM_SMALL_BUCKET_COUNT + (OS_MEM_LARGE_BUCKET_COUNT << OS_MEM_SLI)) /* The bitmap is used to indicate whether the free list is empty, 1: not empty, 0: empty. */ -#define OS_MEM_BITMAP_WORDS ((OS_MEM_FREE_LIST_COUNT >> 5) + 1) ///< 224 >> 5 + 1 = 7 ,为什么要右移 5 因为 2^5 = 32 是一个32位整型的大小 - ///< 而 32 * 7 = 224 ,也就是说用 int[7]当位图就能表示完 224个链表 ,此处,一定要理解好,因为这是理解 TLSF 算法的关键. -#define OS_MEM_BITMAP_MASK 0x1FU ///< 因为一个int型为 32位, 2^5 = 32,所以此处 0x1FU = 5个1 足以. +#define OS_MEM_BITMAP_WORDS ((OS_MEM_FREE_LIST_COUNT >> 5) + 1) + +#define OS_MEM_BITMAP_MASK 0x1FU /* Used to find the first bit of 1 in bitmap. */ STATIC INLINE UINT16 OsMemFFS(UINT32 bitmap) @@ -101,7 +101,7 @@ STATIC INLINE UINT32 OsMemLog2(UINT32 size) return OsMemFLS(size); } -/* Get the first level: f = log2(size). | 获取第一级*/ +/* Get the first level: f = log2(size). */ STATIC INLINE UINT32 OsMemFlGet(UINT32 size) { if (size < OS_MEM_SMALL_BUCKET_MAX_SIZE) { @@ -110,56 +110,56 @@ STATIC INLINE UINT32 OsMemFlGet(UINT32 size) return OsMemLog2(size); } -/* Get the second level: s = (size - 2^f) * 2^SLI / 2^f. | 获取第二级 */ +/* Get the second level: s = (size - 2^f) * 2^SLI / 2^f. */ STATIC INLINE UINT32 OsMemSlGet(UINT32 size, UINT32 fl) { return (((size << OS_MEM_SLI) >> fl) - OS_MEM_FREE_LIST_NUM); } /* The following is the memory algorithm related macro definition and interface implementation. */ -/// 内存池节点 + struct OsMemNodeHead { - UINT32 magic; ///< 魔法数字 0xABCDDCBA - union {//注意这里的前后指向的是连续的地址节点,用于分割和合并 - struct OsMemNodeHead *prev; /* The prev is used for current node points to the previous node | prev 用于当前节点指向前一个节点*/ - struct OsMemNodeHead *next; /* The next is used for last node points to the expand node | next 用于最后一个节点指向展开节点*/ + UINT32 magic; + union { + struct OsMemNodeHead *prev; /* The prev is used for current node points to the previous node */ + struct OsMemNodeHead *next; /* The next is used for last node points to the expand node */ } ptr; -#ifdef LOSCFG_MEM_LEAKCHECK //内存泄漏检测 - UINTPTR linkReg[LOS_RECORD_LR_CNT];///< 存放左右节点地址,用于检测 +#ifdef LOSCFG_MEM_LEAKCHECK + UINTPTR linkReg[LOS_RECORD_LR_CNT]; #endif - UINT32 sizeAndFlag; ///< 节点总大小+标签 + UINT32 sizeAndFlag; }; -/// 已使用内存池节点 + struct OsMemUsedNodeHead { - struct OsMemNodeHead header;///< 已被使用节点 + struct OsMemNodeHead header; #if OS_MEM_FREE_BY_TASKID - UINT32 taskID; ///< 使用节点的任务ID + UINT32 taskID; #endif }; -/// 内存池空闲节点 + struct OsMemFreeNodeHead { - struct OsMemNodeHead header; ///< 内存池节点 - struct OsMemFreeNodeHead *prev; ///< 前一个空闲前驱节点 - struct OsMemFreeNodeHead *next; ///< 后一个空闲后继节点 + struct OsMemNodeHead header; + struct OsMemFreeNodeHead *prev; + struct OsMemFreeNodeHead *next; }; -/// 内存池信息 + struct OsMemPoolInfo { - VOID *pool; ///< 指向内存块基地址,仅做记录而已,真正的分配内存跟它没啥关系 - UINT32 totalSize; ///< 总大小,确定了内存池的边界 - UINT32 attr; ///< 属性 default attr: lock, not expand. + VOID *pool; + UINT32 totalSize; + UINT32 attr; #ifdef LOSCFG_MEM_WATERLINE - UINT32 waterLine; /* Maximum usage size in a memory pool | 内存吃水线*/ - UINT32 curUsedSize; /* Current usage size in a memory pool | 当前已使用大小*/ + UINT32 waterLine; /* Maximum usage size in a memory pool */ + UINT32 curUsedSize; /* Current usage size in a memory pool */ #endif }; -/// 内存池头信息 + struct OsMemPoolHead { - struct OsMemPoolInfo info; ///< 记录内存池的信息 - UINT32 freeListBitmap[OS_MEM_BITMAP_WORDS]; ///< 空闲位图 int[7] = 32 * 7 = 224 > 223 - struct OsMemFreeNodeHead *freeList[OS_MEM_FREE_LIST_COUNT];///< 空闲节点链表 32 + 24 * 8 = 224 - SPIN_LOCK_S spinlock; ///< 操作本池的自旋锁,涉及CPU多核竞争,所以必须得是自旋锁 + struct OsMemPoolInfo info; + UINT32 freeListBitmap[OS_MEM_BITMAP_WORDS]; + struct OsMemFreeNodeHead *freeList[OS_MEM_FREE_LIST_COUNT]; + SPIN_LOCK_S spinlock; #ifdef LOSCFG_MEM_MUL_POOL - VOID *nextPool; ///< 指向下一个内存池 OsMemPoolHead 类型 + VOID *nextPool; #endif }; @@ -168,16 +168,16 @@ struct OsMemPoolHead { #define MEM_UNLOCK(pool, state) LOS_SpinUnlockRestore(&(pool)->spinlock, (state)) /* The memory pool support expand. */ -#define OS_MEM_POOL_EXPAND_ENABLE 0x01 ///< 支持扩展 +#define OS_MEM_POOL_EXPAND_ENABLE 0x01 /* The memory pool support no lock. */ -#define OS_MEM_POOL_LOCK_ENABLE 0x02 ///< 加锁 - -#define OS_MEM_NODE_MAGIC 0xABCDDCBA ///< 内存节点的魔法数字 -#define OS_MEM_MIN_ALLOC_SIZE (sizeof(struct OsMemFreeNodeHead) - sizeof(struct OsMemUsedNodeHead)) //最小分配空间 -// 必须给指向空闲块的指针留位置 -#define OS_MEM_NODE_USED_FLAG 0x80000000U ///< 已使用标签 -#define OS_MEM_NODE_ALIGNED_FLAG 0x40000000U ///< 对齐标签 -#define OS_MEM_NODE_LAST_FLAG 0x20000000U /* Sentinel Node | 哨兵节点标签*/ +#define OS_MEM_POOL_LOCK_ENABLE 0x02 + +#define OS_MEM_NODE_MAGIC 0xABCDDCBA +#define OS_MEM_MIN_ALLOC_SIZE (sizeof(struct OsMemFreeNodeHead) - sizeof(struct OsMemUsedNodeHead)) + +#define OS_MEM_NODE_USED_FLAG 0x80000000U +#define OS_MEM_NODE_ALIGNED_FLAG 0x40000000U +#define OS_MEM_NODE_LAST_FLAG 0x20000000U /* Sentinel Node */ #define OS_MEM_NODE_ALIGNED_AND_USED_FLAG (OS_MEM_NODE_USED_FLAG | OS_MEM_NODE_ALIGNED_FLAG | OS_MEM_NODE_LAST_FLAG) #define OS_MEM_NODE_GET_ALIGNED_FLAG(sizeAndFlag) \ @@ -226,33 +226,32 @@ STATIC INLINE UINT32 OsMemAllocCheck(struct OsMemPoolHead *pool, UINT32 intSave) #if OS_MEM_FREE_BY_TASKID STATIC INLINE VOID OsMemNodeSetTaskID(struct OsMemUsedNodeHead *node) { - node->taskID = LOS_CurTaskIDGet();//将当前任务ID绑定到内存池节点上 + node->taskID = LOS_CurTaskIDGet(); } #endif #ifdef LOSCFG_MEM_WATERLINE STATIC INLINE VOID OsMemWaterUsedRecord(struct OsMemPoolHead *pool, UINT32 size) { - pool->info.curUsedSize += size; //延长可使用空间 + pool->info.curUsedSize += size; if (pool->info.curUsedSize > pool->info.waterLine) { - pool->info.waterLine = pool->info.curUsedSize; //警戒线加高 + pool->info.waterLine = pool->info.curUsedSize; } } #else STATIC INLINE VOID OsMemWaterUsedRecord(struct OsMemPoolHead *pool, UINT32 size) { - (VOID)pool; - (VOID)size; + (VOID)pool; + (VOID)size; } #endif #if OS_MEM_EXPAND_ENABLE -/// 更新哨兵节点内容 STATIC INLINE struct OsMemNodeHead *OsMemLastSentinelNodeGet(const struct OsMemNodeHead *sentinelNode) { struct OsMemNodeHead *node = NULL; - VOID *ptr = sentinelNode->ptr.next;//返回不连续的内存块 - UINT32 size = OS_MEM_NODE_GET_SIZE(sentinelNode->sizeAndFlag); // 获取大小 + VOID *ptr = sentinelNode->ptr.next; + UINT32 size = OS_MEM_NODE_GET_SIZE(sentinelNode->sizeAndFlag); while ((ptr != NULL) && (size != 0)) { node = OS_MEM_END_NODE(ptr, size); @@ -262,7 +261,7 @@ STATIC INLINE struct OsMemNodeHead *OsMemLastSentinelNodeGet(const struct OsMemN return node; } -/// 检查哨兵节点 + STATIC INLINE BOOL OsMemSentinelNodeCheck(struct OsMemNodeHead *sentinelNode) { if (!OS_MEM_NODE_GET_USED_FLAG(sentinelNode->sizeAndFlag)) { @@ -275,7 +274,7 @@ STATIC INLINE BOOL OsMemSentinelNodeCheck(struct OsMemNodeHead *sentinelNode) return TRUE; } -/// 是否为最后一个哨兵节点 + STATIC INLINE BOOL OsMemIsLastSentinelNode(struct OsMemNodeHead *sentinelNode) { if (OsMemSentinelNodeCheck(sentinelNode) == FALSE) { @@ -290,11 +289,11 @@ STATIC INLINE BOOL OsMemIsLastSentinelNode(struct OsMemNodeHead *sentinelNode) return FALSE; } -/// 设置哨兵节点内容 + STATIC INLINE VOID OsMemSentinelNodeSet(struct OsMemNodeHead *sentinelNode, VOID *newNode, UINT32 size) { - if (sentinelNode->ptr.next != NULL) { //哨兵节点有 逻辑地址不连续的衔接内存块 - sentinelNode = OsMemLastSentinelNodeGet(sentinelNode);//更新哨兵节点内容 + if (sentinelNode->ptr.next != NULL) { + sentinelNode = OsMemLastSentinelNodeGet(sentinelNode); } sentinelNode->sizeAndFlag = size; @@ -330,14 +329,14 @@ STATIC INLINE struct OsMemNodeHead *PreSentinelNodeGet(const VOID *pool, const s return NULL; } -/// 大内存释放 + UINT32 OsMemLargeNodeFree(const VOID *ptr) { - LosVmPage *page = OsVmVaddrToPage((VOID *)ptr);//获取物理页 + LosVmPage *page = OsVmVaddrToPage((VOID *)ptr); if ((page == NULL) || (page->nPages == 0)) { return LOS_NOK; } - LOS_PhysPagesFreeContiguous((VOID *)ptr, page->nPages);//释放连续的几个物理页 + LOS_PhysPagesFreeContiguous((VOID *)ptr, page->nPages); return LOS_OK; } @@ -376,7 +375,7 @@ STATIC INLINE BOOL TryShrinkPool(const VOID *pool, const struct OsMemNodeHead *n #endif return TRUE; } -/// 内存池扩展实现 + STATIC INLINE INT32 OsMemPoolExpandSub(VOID *pool, UINT32 size, UINT32 intSave) { UINT32 tryCount = MAX_SHRINK_PAGECACHE_TRY; @@ -384,11 +383,11 @@ STATIC INLINE INT32 OsMemPoolExpandSub(VOID *pool, UINT32 size, UINT32 intSave) struct OsMemNodeHead *newNode = NULL; struct OsMemNodeHead *endNode = NULL; - size = ROUNDUP(size + OS_MEM_NODE_HEAD_SIZE, PAGE_SIZE);//圆整 - endNode = OS_MEM_END_NODE(pool, poolInfo->info.totalSize);//获取哨兵节点 + size = ROUNDUP(size + OS_MEM_NODE_HEAD_SIZE, PAGE_SIZE); + endNode = OS_MEM_END_NODE(pool, poolInfo->info.totalSize); RETRY: - newNode = (struct OsMemNodeHead *)LOS_PhysPagesAllocContiguous(size >> PAGE_SHIFT);//申请新的内存池 | 物理内存 + newNode = (struct OsMemNodeHead *)LOS_PhysPagesAllocContiguous(size >> PAGE_SHIFT); if (newNode == NULL) { if (tryCount > 0) { tryCount--; @@ -412,26 +411,26 @@ RETRY: size = (resize == 0) ? size : resize; } #endif - newNode->sizeAndFlag = (size - OS_MEM_NODE_HEAD_SIZE);//设置新节点大小 - newNode->ptr.prev = OS_MEM_END_NODE(newNode, size);//新节点的前节点指向新节点的哨兵节点 - OsMemSentinelNodeSet(endNode, newNode, size);//设置老内存池的哨兵节点信息,其实就是指向新内存块 - OsMemFreeNodeAdd(pool, (struct OsMemFreeNodeHead *)newNode);//将新节点加入空闲链表 + newNode->sizeAndFlag = (size - OS_MEM_NODE_HEAD_SIZE); + newNode->ptr.prev = OS_MEM_END_NODE(newNode, size); + OsMemSentinelNodeSet(endNode, newNode, size); + OsMemFreeNodeAdd(pool, (struct OsMemFreeNodeHead *)newNode); - endNode = OS_MEM_END_NODE(newNode, size);//获取新节点的哨兵节点 - (VOID)memset(endNode, 0, sizeof(*endNode));//清空内存 - endNode->ptr.next = NULL;//新哨兵节点没有后续指向,因为它已成为最后 - endNode->magic = OS_MEM_NODE_MAGIC;//设置新哨兵节的魔法数字 - OsMemSentinelNodeSet(endNode, NULL, 0); //设置新哨兵节点内容 - OsMemWaterUsedRecord(poolInfo, OS_MEM_NODE_HEAD_SIZE);//更新内存池警戒线 + endNode = OS_MEM_END_NODE(newNode, size); + (VOID)memset(endNode, 0, sizeof(*endNode)); + endNode->ptr.next = NULL; + endNode->magic = OS_MEM_NODE_MAGIC; + OsMemSentinelNodeSet(endNode, NULL, 0); + OsMemWaterUsedRecord(poolInfo, OS_MEM_NODE_HEAD_SIZE); return 0; } -/// 扩展内存池 + STATIC INLINE INT32 OsMemPoolExpand(VOID *pool, UINT32 allocSize, UINT32 intSave) { - UINT32 expandDefault = MEM_EXPAND_SIZE(LOS_MemPoolSizeGet(pool));//至少要扩展现有内存池的 1/8 大小 + UINT32 expandDefault = MEM_EXPAND_SIZE(LOS_MemPoolSizeGet(pool)); UINT32 expandSize = MAX(expandDefault, allocSize); - UINT32 tryCount = 1;//尝试次数 + UINT32 tryCount = 1; UINT32 ret; do { @@ -448,7 +447,7 @@ STATIC INLINE INT32 OsMemPoolExpand(VOID *pool, UINT32 allocSize, UINT32 intSave return -1; } -///< 允许指定内存池扩展 + VOID LOS_MemExpandEnable(VOID *pool) { if (pool == NULL) { @@ -487,7 +486,7 @@ STATIC INLINE VOID OsLmsAllocAlignMark(VOID *ptr, VOID *alignedPtr, UINT32 size) g_lms->simpleMark((UINTPTR)ptr + sizeof(UINT32), (UINTPTR)alignedPtr, LMS_SHADOW_REDZONE_U8); } - /* mark remining as redzone */ + /* mark remaining as redzone */ g_lms->simpleMark(LMS_ADDR_ALIGN((UINTPTR)alignedPtr + size), (UINTPTR)OS_MEM_NEXT_NODE(allocNode), LMS_SHADOW_REDZONE_U8); } @@ -523,7 +522,8 @@ STATIC INLINE VOID OsLmsReallocResizeMark(struct OsMemNodeHead *node, UINT32 res g_lms->simpleMark((UINTPTR)node + resize, (UINTPTR)OS_MEM_NEXT_NODE(node), LMS_SHADOW_REDZONE_U8); } #endif -#ifdef LOSCFG_MEM_LEAKCHECK //内存泄漏检查 + +#ifdef LOSCFG_MEM_LEAKCHECK STATIC INLINE VOID OsMemLinkRegisterRecord(struct OsMemNodeHead *node) { LOS_RecordLR(node->linkReg, LOS_RECORD_LR_CNT, LOS_RECORD_LR_CNT, LOS_OMIT_LR_CNT); @@ -549,7 +549,7 @@ STATIC INLINE VOID OsMemUsedNodePrint(struct OsMemNodeHead *node) PRINTK("\n"); } } -/// 打印已使用的节点 + VOID OsMemUsedNodeShow(VOID *pool) { if (pool == NULL) { @@ -626,17 +626,17 @@ STATIC VOID OsMemNodeBacktraceInfo(const struct OsMemNodeHead *tmpNode, STATIC INLINE UINT32 OsMemFreeListIndexGet(UINT32 size) { - UINT32 fl = OsMemFlGet(size);//获取一级位图 + UINT32 fl = OsMemFlGet(size); if (size < OS_MEM_SMALL_BUCKET_MAX_SIZE) { return fl; } - UINT32 sl = OsMemSlGet(size, fl);//获取二级位图 + UINT32 sl = OsMemSlGet(size, fl); return (OS_MEM_SMALL_BUCKET_COUNT + ((fl - OS_MEM_LARGE_START_BUCKET) << OS_MEM_SLI) + sl); } STATIC INLINE struct OsMemFreeNodeHead *OsMemFindCurSuitableBlock(struct OsMemPoolHead *poolHead, - UINT32 index, UINT32 size) + UINT32 index, UINT32 size) { struct OsMemFreeNodeHead *node = NULL; @@ -663,7 +663,7 @@ STATIC INLINE UINT32 OsMemNotEmptyIndexGet(struct OsMemPoolHead *poolHead, UINT3 return OS_MEM_FREE_LIST_COUNT; } -/// 找到下一个合适的块 + STATIC INLINE struct OsMemFreeNodeHead *OsMemFindNextSuitableBlock(VOID *pool, UINT32 size, UINT32 *outIndex) { struct OsMemPoolHead *poolHead = (struct OsMemPoolHead *)pool; @@ -730,13 +730,13 @@ STATIC INLINE VOID OsMemListAdd(struct OsMemPoolHead *pool, UINT32 listIndex, st OsMemSetFreeListBit(pool, listIndex); node->header.magic = OS_MEM_NODE_MAGIC; } -/// 从空闲链表中删除 + STATIC INLINE VOID OsMemListDelete(struct OsMemPoolHead *pool, UINT32 listIndex, struct OsMemFreeNodeHead *node) { if (node == pool->freeList[listIndex]) { pool->freeList[listIndex] = node->next; - if (node->next == NULL) {//如果链表空了 - OsMemClearFreeListBit(pool, listIndex);//将位图位 置为 0 + if (node->next == NULL) { + OsMemClearFreeListBit(pool, listIndex); } else { node->next->prev = NULL; } @@ -748,27 +748,27 @@ STATIC INLINE VOID OsMemListDelete(struct OsMemPoolHead *pool, UINT32 listIndex, } node->header.magic = OS_MEM_NODE_MAGIC; } -/// 添加一个空闲节点 + STATIC INLINE VOID OsMemFreeNodeAdd(VOID *pool, struct OsMemFreeNodeHead *node) { - UINT32 index = OsMemFreeListIndexGet(node->header.sizeAndFlag);//根据大小定位索引位 + UINT32 index = OsMemFreeListIndexGet(node->header.sizeAndFlag); if (index >= OS_MEM_FREE_LIST_COUNT) { LOS_Panic("The index of free lists is error, index = %u\n", index); return; } - OsMemListAdd(pool, index, node);//挂入链表 + OsMemListAdd(pool, index, node); } -/// 从空闲链表上摘除节点 + STATIC INLINE VOID OsMemFreeNodeDelete(VOID *pool, struct OsMemFreeNodeHead *node) { - UINT32 index = OsMemFreeListIndexGet(node->header.sizeAndFlag);//根据大小定位索引位 + UINT32 index = OsMemFreeListIndexGet(node->header.sizeAndFlag); if (index >= OS_MEM_FREE_LIST_COUNT) { LOS_Panic("The index of free lists is error, index = %u\n", index); return; } OsMemListDelete(pool, index, node); } -//获取一个空闲的节点 + STATIC INLINE struct OsMemNodeHead *OsMemFreeNodeGet(VOID *pool, UINT32 size) { struct OsMemPoolHead *poolHead = (struct OsMemPoolHead *)pool; @@ -782,67 +782,56 @@ STATIC INLINE struct OsMemNodeHead *OsMemFreeNodeGet(VOID *pool, UINT32 size) return &firstNode->header; } -/// 合并节点,和前面的节点合并 node 消失 + STATIC INLINE VOID OsMemMergeNode(struct OsMemNodeHead *node) { struct OsMemNodeHead *nextNode = NULL; - node->ptr.prev->sizeAndFlag += node->sizeAndFlag; //前节点长度变长 - nextNode = (struct OsMemNodeHead *)((UINTPTR)node + node->sizeAndFlag); // 下一个节点位置 - if (!OS_MEM_NODE_GET_LAST_FLAG(nextNode->sizeAndFlag)) {//不是哨兵节点 - nextNode->ptr.prev = node->ptr.prev;//后一个节点的前节点变成前前节点 + node->ptr.prev->sizeAndFlag += node->sizeAndFlag; + nextNode = (struct OsMemNodeHead *)((UINTPTR)node + node->sizeAndFlag); + if (!OS_MEM_NODE_GET_LAST_FLAG(nextNode->sizeAndFlag)) { + nextNode->ptr.prev = node->ptr.prev; } } -/// 切割节点 + STATIC INLINE VOID OsMemSplitNode(VOID *pool, struct OsMemNodeHead *allocNode, UINT32 allocSize) { struct OsMemFreeNodeHead *newFreeNode = NULL; struct OsMemNodeHead *nextNode = NULL; - newFreeNode = (struct OsMemFreeNodeHead *)(VOID *)((UINT8 *)allocNode + allocSize);//切割后出现的新空闲节点,在分配节点的右侧 - newFreeNode->header.ptr.prev = allocNode;//新节点指向前节点,说明是从左到右切割 - newFreeNode->header.sizeAndFlag = allocNode->sizeAndFlag - allocSize;//新空闲节点大小 - allocNode->sizeAndFlag = allocSize;//分配节点大小 - nextNode = OS_MEM_NEXT_NODE(&newFreeNode->header);//获取新节点的下一个节点 - if (!OS_MEM_NODE_GET_LAST_FLAG(nextNode->sizeAndFlag)) {//如果下一个节点不是哨兵节点(末尾节点) - nextNode->ptr.prev = &newFreeNode->header;//下一个节点的前节点为新空闲节点 - if (!OS_MEM_NODE_GET_USED_FLAG(nextNode->sizeAndFlag)) {//如果下一个节点也是空闲的 - OsMemFreeNodeDelete(pool, (struct OsMemFreeNodeHead *)nextNode);//删除下一个节点信息 - OsMemMergeNode(nextNode);//下一个节点和新空闲节点 合并成一个新节点 + newFreeNode = (struct OsMemFreeNodeHead *)(VOID *)((UINT8 *)allocNode + allocSize); + newFreeNode->header.ptr.prev = allocNode; + newFreeNode->header.sizeAndFlag = allocNode->sizeAndFlag - allocSize; + allocNode->sizeAndFlag = allocSize; + nextNode = OS_MEM_NEXT_NODE(&newFreeNode->header); + if (!OS_MEM_NODE_GET_LAST_FLAG(nextNode->sizeAndFlag)) { + nextNode->ptr.prev = &newFreeNode->header; + if (!OS_MEM_NODE_GET_USED_FLAG(nextNode->sizeAndFlag)) { + OsMemFreeNodeDelete(pool, (struct OsMemFreeNodeHead *)nextNode); + OsMemMergeNode(nextNode); } } - OsMemFreeNodeAdd(pool, newFreeNode);//挂入空闲链表 + OsMemFreeNodeAdd(pool, newFreeNode); } -// + STATIC INLINE VOID *OsMemCreateUsedNode(VOID *addr) { - struct OsMemUsedNodeHead *node = (struct OsMemUsedNodeHead *)addr;//直接将地址转成使用节点,说明节点信息也存在内存池中 - //这种用法是非常巧妙的 + struct OsMemUsedNodeHead *node = (struct OsMemUsedNodeHead *)addr; + #if OS_MEM_FREE_BY_TASKID - OsMemNodeSetTaskID(node);//设置使用内存节点的任务 + OsMemNodeSetTaskID(node); #endif -#ifdef LOSCFG_KERNEL_LMS //检测内存泄漏 +#ifdef LOSCFG_KERNEL_LMS struct OsMemNodeHead *newNode = (struct OsMemNodeHead *)node; if (g_lms != NULL) { g_lms->mallocMark(newNode, OS_MEM_NEXT_NODE(newNode), OS_MEM_NODE_HEAD_SIZE); } #endif - return node + 1; //@note_good 这个地方挺有意思的,只是将结构体扩展下,留一个 int 位 ,变成了已使用节点,返回的地址正是要分配给应用的地址 + return node + 1; } -/*! - * @brief OsMemPoolInit 内存池初始化 - * 内存池节点部分包含3种类型节点:未使用空闲内存节点(OsMemFreeNodeHead),已使用内存节点(OsMemUsedNodeHead) 和 尾节点(OsMemNodeHead)。 - * \n 每个内存节点维护一个前序指针,指向内存池中上一个内存节点,还维护内存节点的大小和使用标记。 - * \n 空闲内存节点和已使用内存节点后面的内存区域是数据域 - * @param pool - * @param size - * @return - * - * @see - */ STATIC UINT32 OsMemPoolInit(VOID *pool, UINT32 size) { struct OsMemPoolHead *poolHead = (struct OsMemPoolHead *)pool; @@ -864,32 +853,30 @@ STATIC UINT32 OsMemPoolInit(VOID *pool, UINT32 size) #endif LOS_SpinInit(&poolHead->spinlock); - poolHead->info.pool = pool; //内存池的起始地址,但注意真正的内存并不是从此处分配,它只是用来记录这个内存块的开始位置而已. - poolHead->info.totalSize = size;//内存池总大小 - poolHead->info.attr = OS_MEM_POOL_LOCK_ENABLE; /* default attr: lock, not expand. | 默认是上锁,不支持扩展,需扩展得另外设置*/ + poolHead->info.pool = pool; + poolHead->info.totalSize = size; + poolHead->info.attr = OS_MEM_POOL_LOCK_ENABLE; /* default attr: lock, not expand. */ - newNode = OS_MEM_FIRST_NODE(pool);//跳到第一个节点位置,即跳过结构体本身位置,真正的分配内存是从newNode开始的. - newNode->sizeAndFlag = (size - sizeof(struct OsMemPoolHead) - OS_MEM_NODE_HEAD_SIZE);//这才是可供分配给外界使用的总内存块大小,即数据域 - //OS_MEM_NODE_HEAD_SIZE 叫当前使用节点,即指 newNode占用的空间 - newNode->ptr.prev = NULL;//开始是空指向 - newNode->magic = OS_MEM_NODE_MAGIC;//魔法数字 用于标识这是一个 OsMemNodeHead 节点, 魔法数字不能被覆盖, - OsMemFreeNodeAdd(pool, (struct OsMemFreeNodeHead *)newNode);//添加一个空闲节点,由此有了首个可供分配的空闲节点 + newNode = OS_MEM_FIRST_NODE(pool); + newNode->sizeAndFlag = (size - sizeof(struct OsMemPoolHead) - OS_MEM_NODE_HEAD_SIZE); + newNode->ptr.prev = NULL; + newNode->magic = OS_MEM_NODE_MAGIC; + OsMemFreeNodeAdd(pool, (struct OsMemFreeNodeHead *)newNode); /* The last mem node */ - endNode = OS_MEM_END_NODE(pool, size);//确定尾节点位置,尾节点没有数据域 - endNode->magic = OS_MEM_NODE_MAGIC; //填入尾节点的魔法数字 -#if OS_MEM_EXPAND_ENABLE //支持扩展 - endNode->ptr.next = NULL;//尾节点没有后继节点 - OsMemSentinelNodeSet(endNode, NULL, 0);//将尾节点设置为哨兵节点 + endNode = OS_MEM_END_NODE(pool, size); + endNode->magic = OS_MEM_NODE_MAGIC; +#if OS_MEM_EXPAND_ENABLE + endNode->ptr.next = NULL; + OsMemSentinelNodeSet(endNode, NULL, 0); #else - endNode->sizeAndFlag = 0;//0代表没有数据域 - endNode->ptr.prev = newNode;//前驱指针指向第一个节点 + endNode->sizeAndFlag = 0; + endNode->ptr.prev = newNode; OS_MEM_NODE_SET_USED_FLAG(endNode->sizeAndFlag); #endif -#ifdef LOSCFG_MEM_WATERLINE //吃水线开关 - poolHead->info.curUsedSize = sizeof(struct OsMemPoolHead) + OS_MEM_NODE_HEAD_SIZE;//内存池已使用了这么多空间,这些都是存内存池自身数据的空间, - //但此处是否还要算是 endNode ? @note_thinking - poolHead->info.waterLine = poolHead->info.curUsedSize; //设置吃水线 +#ifdef LOSCFG_MEM_WATERLINE + poolHead->info.curUsedSize = sizeof(struct OsMemPoolHead) + OS_MEM_NODE_HEAD_SIZE; + poolHead->info.waterLine = poolHead->info.curUsedSize; #endif #ifdef LOSCFG_KERNEL_LMS if (resize != 0) { @@ -909,13 +896,13 @@ STATIC VOID OsMemPoolDeinit(const VOID *pool, UINT32 size) #endif (VOID)memset_s(pool, size, 0, sizeof(struct OsMemPoolHead)); } -/// 新增内存池 + STATIC UINT32 OsMemPoolAdd(VOID *pool, UINT32 size) { VOID *nextPool = g_poolHead; VOID *curPool = g_poolHead; UINTPTR poolEnd; - while (nextPool != NULL) {//单链表遍历方式 + while (nextPool != NULL) { poolEnd = (UINTPTR)nextPool + LOS_MemPoolSizeGet(nextPool); if (((pool <= nextPool) && (((UINTPTR)pool + size) > (UINTPTR)nextPool)) || (((UINTPTR)pool < poolEnd) && (((UINTPTR)pool + size) >= poolEnd))) { @@ -929,15 +916,15 @@ STATIC UINT32 OsMemPoolAdd(VOID *pool, UINT32 size) } if (g_poolHead == NULL) { - g_poolHead = pool; //首个内存池 + g_poolHead = pool; } else { - ((struct OsMemPoolHead *)curPool)->nextPool = pool; //两池扯上关系 + ((struct OsMemPoolHead *)curPool)->nextPool = pool; } - ((struct OsMemPoolHead *)pool)->nextPool = NULL; //新池下一个无所指 + ((struct OsMemPoolHead *)pool)->nextPool = NULL; return LOS_OK; } -/// 删除内存池 + STATIC UINT32 OsMemPoolDelete(const VOID *pool) { UINT32 ret = LOS_NOK; @@ -968,39 +955,29 @@ STATIC UINT32 OsMemPoolDelete(const VOID *pool) } #endif -/*! - * @brief LOS_MemInit 初始化一块指定的动态内存池,大小为size - * 初始一个内存池后生成一个内存池控制头、尾节点EndNode,剩余的内存被标记为FreeNode内存节点。 - * @param pool - * @param size - * @return - * @attention EndNode作为内存池末尾的节点,size为0。 - * @see - */ UINT32 LOS_MemInit(VOID *pool, UINT32 size) { if ((pool == NULL) || (size <= OS_MEM_MIN_POOL_SIZE)) { return OS_ERROR; } - size = OS_MEM_ALIGN(size, OS_MEM_ALIGN_SIZE);//4个字节对齐 + size = OS_MEM_ALIGN(size, OS_MEM_ALIGN_SIZE); if (OsMemPoolInit(pool, size)) { return OS_ERROR; } -#ifdef LOSCFG_MEM_MUL_POOL //多内存池开关 +#ifdef LOSCFG_MEM_MUL_POOL if (OsMemPoolAdd(pool, size)) { (VOID)OsMemPoolDeInit(pool, size); return OS_ERROR; } #endif - OsHookCall(LOS_HOOK_TYPE_MEM_INIT, pool, size);//打印日志 + OsHookCall(LOS_HOOK_TYPE_MEM_INIT, pool, size); return LOS_OK; } #ifdef LOSCFG_MEM_MUL_POOL -/// 删除指定内存池 UINT32 LOS_MemDeInit(VOID *pool) { struct OsMemPoolHead *tmpPool = (struct OsMemPoolHead *)pool; @@ -1020,7 +997,7 @@ UINT32 LOS_MemDeInit(VOID *pool) OsHookCall(LOS_HOOK_TYPE_MEM_DEINIT, tmpPool); return LOS_OK; } -/// 打印系统中已初始化的所有内存池,包括内存池的起始地址、内存池大小、空闲内存总大小、已使用内存总大小、最大的空闲内存块大小、空闲内存块数量、已使用的内存块数量。 + UINT32 LOS_MemPoolList(VOID) { VOID *nextPool = g_poolHead; @@ -1034,7 +1011,7 @@ UINT32 LOS_MemPoolList(VOID) return index; } #endif -/// 从指定动态内存池中申请size长度的内存 + STATIC INLINE VOID *OsMemAlloc(struct OsMemPoolHead *pool, UINT32 size, UINT32 intSave) { struct OsMemNodeHead *allocNode = NULL; @@ -1047,15 +1024,15 @@ STATIC INLINE VOID *OsMemAlloc(struct OsMemPoolHead *pool, UINT32 size, UINT32 i UINT32 allocSize = OS_MEM_ALIGN(size + OS_MEM_NODE_HEAD_SIZE, OS_MEM_ALIGN_SIZE); #if OS_MEM_EXPAND_ENABLE -retry: //这种写法也挺赞的 @note_good +retry: #endif - allocNode = OsMemFreeNodeGet(pool, allocSize);//获取空闲节点 - if (allocNode == NULL) {//没有内存了,怎搞? + allocNode = OsMemFreeNodeGet(pool, allocSize); + if (allocNode == NULL) { #if OS_MEM_EXPAND_ENABLE if (pool->info.attr & OS_MEM_POOL_EXPAND_ENABLE) { - INT32 ret = OsMemPoolExpand(pool, allocSize, intSave);//扩展内存池 + INT32 ret = OsMemPoolExpand(pool, allocSize, intSave); if (ret == 0) { - goto retry;//再来一遍 + goto retry; } } #endif @@ -1070,22 +1047,22 @@ retry: //这种写法也挺赞的 @note_good return NULL; } - if ((allocSize + OS_MEM_NODE_HEAD_SIZE + OS_MEM_MIN_ALLOC_SIZE) <= allocNode->sizeAndFlag) {//所需小于内存池可供分配量 - OsMemSplitNode(pool, allocNode, allocSize);//劈开内存池 + if ((allocSize + OS_MEM_NODE_HEAD_SIZE + OS_MEM_MIN_ALLOC_SIZE) <= allocNode->sizeAndFlag) { + OsMemSplitNode(pool, allocNode, allocSize); } - OS_MEM_NODE_SET_USED_FLAG(allocNode->sizeAndFlag);//给节点贴上已使用的标签 - OsMemWaterUsedRecord(pool, OS_MEM_NODE_GET_SIZE(allocNode->sizeAndFlag));//更新吃水线 + OS_MEM_NODE_SET_USED_FLAG(allocNode->sizeAndFlag); + OsMemWaterUsedRecord(pool, OS_MEM_NODE_GET_SIZE(allocNode->sizeAndFlag)); -#ifdef LOSCFG_MEM_LEAKCHECK //检测内存泄漏开关 +#ifdef LOSCFG_MEM_LEAKCHECK OsMemLinkRegisterRecord(allocNode); #endif - return OsMemCreateUsedNode((VOID *)allocNode);//创建已使用节点 + return OsMemCreateUsedNode((VOID *)allocNode); } -/// 从指定内存池中申请size长度的内存,注意这可不是从内核堆空间中申请内存 + VOID *LOS_MemAlloc(VOID *pool, UINT32 size) { - if ((pool == NULL) || (size == 0)) {//没提供内存池时 + if ((pool == NULL) || (size == 0)) { return (size > 0) ? OsVmBootMemAlloc(size) : NULL; } @@ -1102,14 +1079,14 @@ VOID *LOS_MemAlloc(VOID *pool, UINT32 size) break; } MEM_LOCK(poolHead, intSave); - ptr = OsMemAlloc(poolHead, size, intSave);//真正的分配内存函数,详细查看 鸿蒙内核源码分析(内存池篇) + ptr = OsMemAlloc(poolHead, size, intSave); MEM_UNLOCK(poolHead, intSave); } while (0); - OsHookCall(LOS_HOOK_TYPE_MEM_ALLOC, pool, ptr, size);//打印日志,到此一游 + OsHookCall(LOS_HOOK_TYPE_MEM_ALLOC, pool, ptr, size); return ptr; } -/// 从指定内存池中申请size长度的内存且地址按boundary字节对齐的内存 + VOID *LOS_MemAllocAlign(VOID *pool, UINT32 size, UINT32 boundary) { UINT32 gapSize; @@ -1166,10 +1143,10 @@ VOID *LOS_MemAllocAlign(VOID *pool, UINT32 size, UINT32 boundary) ptr = alignedPtr; } while (0); - OsHookCall(LOS_HOOK_TYPE_MEM_ALLOCALIGN, pool, ptr, size, boundary);//打印对齐日志,表示程序曾临幸过此处 + OsHookCall(LOS_HOOK_TYPE_MEM_ALLOCALIGN, pool, ptr, size, boundary); return ptr; } -/// 内存池有效性检查 + STATIC INLINE BOOL OsMemAddrValidCheck(const struct OsMemPoolHead *pool, const VOID *addr) { UINT32 size; @@ -1183,7 +1160,7 @@ STATIC INLINE BOOL OsMemAddrValidCheck(const struct OsMemPoolHead *pool, const V if (OS_MEM_MIDDLE_ADDR_OPEN_END(pool + 1, addr, (UINTPTR)pool + size)) { return TRUE; } -#if OS_MEM_EXPAND_ENABLE //如果支持可扩展 +#if OS_MEM_EXPAND_ENABLE struct OsMemNodeHead *node = NULL; struct OsMemNodeHead *sentinel = OS_MEM_END_NODE(pool, size); while (OsMemIsLastSentinelNode(sentinel) == FALSE) { @@ -1273,7 +1250,7 @@ STATIC UINT32 OsMemCheckUsedNode(const struct OsMemPoolHead *pool, const struct return LOS_OK; } -/// 释放内存 + STATIC INLINE UINT32 OsMemFree(struct OsMemPoolHead *pool, struct OsMemNodeHead *node) { UINT32 ret = OsMemCheckUsedNode(pool, node); @@ -1283,10 +1260,10 @@ STATIC INLINE UINT32 OsMemFree(struct OsMemPoolHead *pool, struct OsMemNodeHead } #ifdef LOSCFG_MEM_WATERLINE - pool->info.curUsedSize -= OS_MEM_NODE_GET_SIZE(node->sizeAndFlag);//降低水位线 + pool->info.curUsedSize -= OS_MEM_NODE_GET_SIZE(node->sizeAndFlag); #endif - node->sizeAndFlag = OS_MEM_NODE_GET_SIZE(node->sizeAndFlag);//获取大小和标记 + node->sizeAndFlag = OS_MEM_NODE_GET_SIZE(node->sizeAndFlag); #ifdef LOSCFG_MEM_LEAKCHECK OsMemLinkRegisterRecord(node); #endif @@ -1297,17 +1274,17 @@ STATIC INLINE UINT32 OsMemFree(struct OsMemPoolHead *pool, struct OsMemNodeHead g_lms->check((UINTPTR)node + OS_MEM_NODE_HEAD_SIZE, TRUE); } #endif - struct OsMemNodeHead *preNode = node->ptr.prev; /* merage preNode | 合并前一个节点*/ + struct OsMemNodeHead *preNode = node->ptr.prev; /* merage preNode */ if ((preNode != NULL) && !OS_MEM_NODE_GET_USED_FLAG(preNode->sizeAndFlag)) { - OsMemFreeNodeDelete(pool, (struct OsMemFreeNodeHead *)preNode);//删除前节点的信息 - OsMemMergeNode(node);//向前合并 + OsMemFreeNodeDelete(pool, (struct OsMemFreeNodeHead *)preNode); + OsMemMergeNode(node); node = preNode; } - struct OsMemNodeHead *nextNode = OS_MEM_NEXT_NODE(node); /* merage nextNode | 计算后一个节点位置*/ + struct OsMemNodeHead *nextNode = OS_MEM_NEXT_NODE(node); /* merage nextNode */ if ((nextNode != NULL) && !OS_MEM_NODE_GET_USED_FLAG(nextNode->sizeAndFlag)) { - OsMemFreeNodeDelete(pool, (struct OsMemFreeNodeHead *)nextNode);//删除后节点信息 - OsMemMergeNode(nextNode);//合并节点 + OsMemFreeNodeDelete(pool, (struct OsMemFreeNodeHead *)nextNode); + OsMemMergeNode(nextNode); } #if OS_MEM_EXPAND_ENABLE @@ -1328,7 +1305,7 @@ STATIC INLINE UINT32 OsMemFree(struct OsMemPoolHead *pool, struct OsMemNodeHead #endif return ret; } -/// 释放从指定动态内存中申请的内存 + UINT32 LOS_MemFree(VOID *pool, VOID *ptr) { UINT32 intSave; @@ -1344,13 +1321,13 @@ UINT32 LOS_MemFree(VOID *pool, VOID *ptr) struct OsMemNodeHead *node = NULL; do { - UINT32 gapSize = *(UINT32 *)((UINTPTR)ptr - sizeof(UINT32));//获取节点大小和标签 即: sizeAndFlag + UINT32 gapSize = *(UINT32 *)((UINTPTR)ptr - sizeof(UINT32)); if (OS_MEM_NODE_GET_ALIGNED_FLAG(gapSize) && OS_MEM_NODE_GET_USED_FLAG(gapSize)) { PRINT_ERR("[%s:%d]gapSize:0x%x error\n", __FUNCTION__, __LINE__, gapSize); break; } - node = (struct OsMemNodeHead *)((UINTPTR)ptr - OS_MEM_NODE_HEAD_SIZE);//定位到节点开始位置 + node = (struct OsMemNodeHead *)((UINTPTR)ptr - OS_MEM_NODE_HEAD_SIZE); if (OS_MEM_NODE_GET_ALIGNED_FLAG(gapSize)) { gapSize = OS_MEM_NODE_GET_ALIGNED_GAPSIZE(gapSize); @@ -1438,7 +1415,7 @@ STATIC INLINE VOID *OsGetRealPtr(const VOID *pool, VOID *ptr) } STATIC INLINE VOID *OsMemRealloc(struct OsMemPoolHead *pool, const VOID *ptr, - struct OsMemNodeHead *node, UINT32 size, UINT32 intSave) + struct OsMemNodeHead *node, UINT32 size, UINT32 intSave) { struct OsMemNodeHead *nextNode = NULL; UINT32 allocSize = OS_MEM_ALIGN(size + OS_MEM_NODE_HEAD_SIZE, OS_MEM_ALIGN_SIZE); @@ -1469,7 +1446,7 @@ STATIC INLINE VOID *OsMemRealloc(struct OsMemPoolHead *pool, const VOID *ptr, } return tmpPtr; } -/// 按size大小重新分配内存块,并将原内存块内容拷贝到新内存块。如果新内存块申请成功,则释放原内存块 + VOID *LOS_MemRealloc(VOID *pool, VOID *ptr, UINT32 size) { if ((pool == NULL) || OS_MEM_NODE_GET_USED_FLAG(size) || OS_MEM_NODE_GET_ALIGNED_FLAG(size)) { @@ -1562,7 +1539,7 @@ UINT32 LOS_MemFreeByTaskID(VOID *pool, UINT32 taskID) return LOS_OK; } #endif -/// 获取指定动态内存池的总大小 + UINT32 LOS_MemPoolSizeGet(const VOID *pool) { UINT32 count = 0; @@ -1571,23 +1548,23 @@ UINT32 LOS_MemPoolSizeGet(const VOID *pool) return LOS_NOK; } - count += ((struct OsMemPoolHead *)pool)->info.totalSize; // 这里的 += 好像没必要吧?, = 就可以了, @note_thinking + count += ((struct OsMemPoolHead *)pool)->info.totalSize; -#if OS_MEM_EXPAND_ENABLE //支持扩展 +#if OS_MEM_EXPAND_ENABLE UINT32 size; struct OsMemNodeHead *node = NULL; - struct OsMemNodeHead *sentinel = OS_MEM_END_NODE(pool, count);//获取哨兵节点 + struct OsMemNodeHead *sentinel = OS_MEM_END_NODE(pool, count); - while (OsMemIsLastSentinelNode(sentinel) == FALSE) {//不是最后一个节点 - size = OS_MEM_NODE_GET_SIZE(sentinel->sizeAndFlag);//数据域大小 - node = OsMemSentinelNodeGet(sentinel);//再获取哨兵节点 - sentinel = OS_MEM_END_NODE(node, size);//获取尾节点 - count += size; //内存池大小变大 + while (OsMemIsLastSentinelNode(sentinel) == FALSE) { + size = OS_MEM_NODE_GET_SIZE(sentinel->sizeAndFlag); + node = OsMemSentinelNodeGet(sentinel); + sentinel = OS_MEM_END_NODE(node, size); + count += size; } #endif return count; } -/// 获取指定动态内存池的总使用量大小 + UINT32 LOS_MemTotalUsedGet(VOID *pool) { struct OsMemNodeHead *tmpNode = NULL; @@ -1660,7 +1637,7 @@ STATIC UINT32 OsMemAddrValidCheckPrint(const VOID *pool, struct OsMemFreeNodeHea } STATIC UINT32 OsMemIntegrityCheckSub(struct OsMemNodeHead **tmpNode, const VOID *pool, - const struct OsMemNodeHead *endNode) + const struct OsMemNodeHead *endNode) { if (!OS_MEM_MAGIC_VALID(*tmpNode)) { OsMemMagicCheckPrint(tmpNode); @@ -1676,7 +1653,7 @@ STATIC UINT32 OsMemIntegrityCheckSub(struct OsMemNodeHead **tmpNode, const VOID } STATIC UINT32 OsMemFreeListNodeCheck(const struct OsMemPoolHead *pool, - const struct OsMemFreeNodeHead *node) + const struct OsMemFreeNodeHead *node) { if (!OsMemAddrValidCheck(pool, node) || !OsMemAddrValidCheck(pool, node->prev) || @@ -1737,9 +1714,9 @@ OUT: #endif } } -//对指定内存池做完整性检查, + STATIC UINT32 OsMemIntegrityCheck(const struct OsMemPoolHead *pool, struct OsMemNodeHead **tmpNode, - struct OsMemNodeHead **preNode) + struct OsMemNodeHead **preNode) { struct OsMemNodeHead *endNode = OS_MEM_END_NODE(pool, pool->info.totalSize); @@ -1862,7 +1839,7 @@ STATIC INLINE UINT32 OsMemAllocCheck(struct OsMemPoolHead *pool, UINT32 intSave) return LOS_OK; } #endif -/// 对指定内存池做完整性检查 + UINT32 LOS_MemIntegrityCheck(const VOID *pool) { if (pool == NULL) { @@ -1887,7 +1864,7 @@ ERROR_OUT: } STATIC INLINE VOID OsMemInfoGet(struct OsMemPoolHead *poolInfo, struct OsMemNodeHead *node, - LOS_MEM_POOL_STATUS *poolStatus) + LOS_MEM_POOL_STATUS *poolStatus) { UINT32 totalUsedSize = 0; UINT32 totalFreeSize = 0; @@ -1916,17 +1893,8 @@ STATIC INLINE VOID OsMemInfoGet(struct OsMemPoolHead *poolInfo, struct OsMemNode poolStatus->freeNodeNum += freeNodeNum; } -/*! - * @brief LOS_MemInfoGet - * 获取指定内存池的内存结构信息,包括空闲内存大小、已使用内存大小、空闲内存块数量、已使用的内存块数量、最大的空闲内存块大小 - * @param pool - * @param poolStatus - * @return - * - * @see - */ UINT32 LOS_MemInfoGet(VOID *pool, LOS_MEM_POOL_STATUS *poolStatus) -{//内存碎片率计算:同样调用LOS_MemInfoGet接口,可以获取内存池的剩余内存大小和最大空闲内存块大小,然后根据公式(fragment=100-最大空闲内存块大小/剩余内存大小)得出此时的动态内存池碎片率。 +{ struct OsMemPoolHead *poolInfo = pool; if (poolStatus == NULL) { @@ -2007,7 +1975,7 @@ STATIC VOID OsMemInfoPrint(VOID *pool) status.freeNodeNum); #endif } -/// 打印指定内存池的空闲内存块的大小及数量 + UINT32 LOS_MemFreeNodeShow(VOID *pool) { struct OsMemPoolHead *poolInfo = (struct OsMemPoolHead *)pool; @@ -2054,7 +2022,7 @@ UINT32 LOS_MemFreeNodeShow(VOID *pool) return LOS_OK; } -///内核空间动态内存(堆内存)初始化 , 争取系统动态内存池 + STATUS_T OsKHeapInit(size_t size) { STATUS_T ret; @@ -2073,38 +2041,38 @@ STATUS_T OsKHeapInit(size_t size) return -1; } - m_aucSysMem0 = m_aucSysMem1 = ptr;// 指定内核内存池的位置 - ret = LOS_MemInit(m_aucSysMem0, size); //初始化内存池,供内核分配动态内存 + m_aucSysMem0 = m_aucSysMem1 = ptr; + ret = LOS_MemInit(m_aucSysMem0, size); if (ret != LOS_OK) { PRINT_ERR("vmm_kheap_init LOS_MemInit failed!\n"); g_vmBootMemBase -= size; return ret; } #if OS_MEM_EXPAND_ENABLE - LOS_MemExpandEnable(OS_SYS_MEM_ADDR);//支持扩展系统动态内存 + LOS_MemExpandEnable(OS_SYS_MEM_ADDR); #endif return LOS_OK; } -///< 判断地址是否在堆区 + BOOL OsMemIsHeapNode(const VOID *ptr) { - struct OsMemPoolHead *pool = (struct OsMemPoolHead *)m_aucSysMem1;//内核堆区开始地址 - struct OsMemNodeHead *firstNode = OS_MEM_FIRST_NODE(pool);//获取内存池首个节点 - struct OsMemNodeHead *endNode = OS_MEM_END_NODE(pool, pool->info.totalSize);//获取内存池的尾节点 + struct OsMemPoolHead *pool = (struct OsMemPoolHead *)m_aucSysMem1; + struct OsMemNodeHead *firstNode = OS_MEM_FIRST_NODE(pool); + struct OsMemNodeHead *endNode = OS_MEM_END_NODE(pool, pool->info.totalSize); - if (OS_MEM_MIDDLE_ADDR(firstNode, ptr, endNode)) {//如果在首尾范围内 + if (OS_MEM_MIDDLE_ADDR(firstNode, ptr, endNode)) { return TRUE; } -#if OS_MEM_EXPAND_ENABLE//内存池经过扩展后,新旧块的虚拟地址是不连续的,所以需要跳块判断 - UINT32 intSave; - UINT32 size;//详细查看百篇博客系列篇之 鸿蒙内核源码分析(内存池篇) - MEM_LOCK(pool, intSave); //获取自旋锁 - while (OsMemIsLastSentinelNode(endNode) == FALSE) { //哨兵节点是内存池结束的标记 - size = OS_MEM_NODE_GET_SIZE(endNode->sizeAndFlag);//获取节点大小 - firstNode = OsMemSentinelNodeGet(endNode);//获取下一块的开始地址 - endNode = OS_MEM_END_NODE(firstNode, size);//获取下一块的尾节点 - if (OS_MEM_MIDDLE_ADDR(firstNode, ptr, endNode)) {//判断地址是否在该块中 +#if OS_MEM_EXPAND_ENABLE + UINT32 intSave; + UINT32 size; + MEM_LOCK(pool, intSave); + while (OsMemIsLastSentinelNode(endNode) == FALSE) { + size = OS_MEM_NODE_GET_SIZE(endNode->sizeAndFlag); + firstNode = OsMemSentinelNodeGet(endNode); + endNode = OS_MEM_END_NODE(firstNode, size); + if (OS_MEM_MIDDLE_ADDR(firstNode, ptr, endNode)) { MEM_UNLOCK(pool, intSave); return TRUE; } @@ -2113,5 +2081,3 @@ BOOL OsMemIsHeapNode(const VOID *ptr) #endif return FALSE; } - - From 07bcc09777dc4354c6103375ed70e6ff80adce22 Mon Sep 17 00:00:00 2001 From: Dio Date: Fri, 19 Jan 2024 09:43:07 +0800 Subject: [PATCH 18/33] =?UTF-8?q?mem=E6=8B=AF=E6=95=91=E8=AE=A1=E5=88=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kernel/base/mem/common/los_memstat.c | 18 +- .../kernel/base/mem/membox/los_membox.c | 223 ++++++++ .../kernel/base/mem/tlsf/los_memory.c | 482 ++++++++++-------- 3 files changed, 490 insertions(+), 233 deletions(-) diff --git a/src/kernel_liteos_a/kernel/base/mem/common/los_memstat.c b/src/kernel_liteos_a/kernel/base/mem/common/los_memstat.c index 91164b4c..03815a3f 100644 --- a/src/kernel_liteos_a/kernel/base/mem/common/los_memstat.c +++ b/src/kernel_liteos_a/kernel/base/mem/common/los_memstat.c @@ -32,9 +32,9 @@ #include "los_memstat_pri.h" #include "los_task_pri.h" - +/// 记录每个任务对内存的使用情况 LITE_OS_SEC_BSS_MINOR STATIC TskMemUsedInfo g_tskMemUsedInfo[LOSCFG_BASE_CORE_TSK_LIMIT]; - +/// 计算指定任务对内存使用增加量 LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemUsedInc(UINT32 usedSize, UINT32 taskID) { if (taskID >= LOSCFG_BASE_CORE_TSK_LIMIT) { @@ -43,9 +43,9 @@ LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemUsedInc(UINT32 usedSize, UINT32 taskID) if (OS_INT_ACTIVE) { return; } - g_tskMemUsedInfo[taskID].memUsed += usedSize; + g_tskMemUsedInfo[taskID].memUsed += usedSize; ///< 叠加 } - +/// 计算指定任务对内存使用减少量 LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemUsedDec(UINT32 usedSize, UINT32 taskID) { if (taskID >= LOSCFG_BASE_CORE_TSK_LIMIT) { @@ -59,9 +59,9 @@ LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemUsedDec(UINT32 usedSize, UINT32 taskID) OsCurrTaskGet()->taskName, g_tskMemUsedInfo[taskID].memUsed, usedSize); return; } - g_tskMemUsedInfo[taskID].memUsed -= usedSize; + g_tskMemUsedInfo[taskID].memUsed -= usedSize; ///< 递减 } - +/// 获取指定任务对内存的使用情况 LITE_OS_SEC_TEXT_MINOR UINT32 OsTaskMemUsage(UINT32 taskID) { if (taskID >= LOSCFG_BASE_CORE_TSK_LIMIT) { @@ -70,7 +70,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsTaskMemUsage(UINT32 taskID) return g_tskMemUsedInfo[taskID].memUsed; } - +/// 清空任务内存使用记录 LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemClear(UINT32 taskID) { if (taskID >= LOSCFG_BASE_CORE_TSK_LIMIT) { @@ -82,8 +82,8 @@ LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemClear(UINT32 taskID) } g_tskMemUsedInfo[taskID].memUsed = 0; } - -#ifdef LOS_MEM_SLAB +// Slab是一种内存分配器,通过将内存划分不同大小的空间分配给对象使用来进行缓存管理,应用于内核对象的缓存。 +#ifdef LOS_MEM_SLAB // LITE_OS_SEC_BSS_MINOR STATIC TskSlabUsedInfo g_tskSlabUsedInfo[LOSCFG_BASE_CORE_TSK_LIMIT]; LITE_OS_SEC_TEXT_MINOR VOID OsTaskSlabUsedInc(UINT32 usedSize, UINT32 taskID) diff --git a/src/kernel_liteos_a/kernel/base/mem/membox/los_membox.c b/src/kernel_liteos_a/kernel/base/mem/membox/los_membox.c index 7a4b66de..4180d3bd 100644 --- a/src/kernel_liteos_a/kernel/base/mem/membox/los_membox.c +++ b/src/kernel_liteos_a/kernel/base/mem/membox/los_membox.c @@ -1,4 +1,22 @@ /* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CON/* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. * @@ -33,6 +51,211 @@ #include "los_hwi.h" #include "los_spinlock.h" +#ifdef LOSCFG_AARCH64 +#define OS_MEMBOX_MAGIC 0xa55a5aa5a55a5aa5 +#else +#define OS_MEMBOX_MAGIC 0xa55a5aa5 +#endif +#define OS_MEMBOX_SET_MAGIC(addr) \ + ((LOS_MEMBOX_NODE *)(addr))->pstNext = (LOS_MEMBOX_NODE *)OS_MEMBOX_MAGIC //设置魔法数字 +#define OS_MEMBOX_CHECK_MAGIC(addr) \ + ((((LOS_MEMBOX_NODE *)(addr))->pstNext == (LOS_MEMBOX_NODE *)OS_MEMBOX_MAGIC) ? LOS_OK : LOS_NOK) + +#define OS_MEMBOX_USER_ADDR(addr) \ + ((VOID *)((UINT8 *)(addr) + OS_MEMBOX_NODE_HEAD_SIZE)) +#define OS_MEMBOX_NODE_ADDR(addr) \ + ((LOS_MEMBOX_NODE *)(VOID *)((UINT8 *)(addr) - OS_MEMBOX_NODE_HEAD_SIZE)) //节块 = (节头 + 节体) addr = 节体 +/* spinlock for mem module, only available on SMP mode */ +LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_memboxSpin); +#define MEMBOX_LOCK(state) LOS_SpinLockSave(&g_memboxSpin, &(state)) ///< 获取静态内存池自旋锁 +#define MEMBOX_UNLOCK(state) LOS_SpinUnlockRestore(&g_memboxSpin, (state))///< 释放静态内存池自旋锁 +/// 检查静态内存块 +STATIC INLINE UINT32 OsCheckBoxMem(const LOS_MEMBOX_INFO *boxInfo, const VOID *node) +{ + UINT32 offset; + + if (boxInfo->uwBlkSize == 0) { + return LOS_NOK; + } + + offset = (UINT32)((UINTPTR)node - (UINTPTR)(boxInfo + 1)); + if ((offset % boxInfo->uwBlkSize) != 0) { + return LOS_NOK; + } + + if ((offset / boxInfo->uwBlkSize) >= boxInfo->uwBlkNum) { + return LOS_NOK; + } + + return OS_MEMBOX_CHECK_MAGIC(node);//检查魔法数字是否被修改过了 +} +/// 初始化一个静态内存池,根据入参设定其起始地址、总大小及每个内存块大小 +LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemboxInit(VOID *pool, UINT32 poolSize, UINT32 blkSize) +{ + LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool;//在内存起始处安置池头 + LOS_MEMBOX_NODE *node = NULL; + UINT32 index; + UINT32 intSave; + + if (pool == NULL) { + return LOS_NOK; + } + + if (blkSize == 0) { + return LOS_NOK; + } + + if (poolSize < sizeof(LOS_MEMBOX_INFO)) { + return LOS_NOK; + } + + MEMBOX_LOCK(intSave); + boxInfo->uwBlkSize = LOS_MEMBOX_ALIGNED(blkSize + OS_MEMBOX_NODE_HEAD_SIZE); //节块总大小(节头+节体) + boxInfo->uwBlkNum = (poolSize - sizeof(LOS_MEMBOX_INFO)) / boxInfo->uwBlkSize;//总节块数量 + boxInfo->uwBlkCnt = 0; //已分配的数量 + if (boxInfo->uwBlkNum == 0) {//只有0块的情况 + MEMBOX_UNLOCK(intSave); + return LOS_NOK; + } + + node = (LOS_MEMBOX_NODE *)(boxInfo + 1);//去除池头,找到第一个节块位置 + + boxInfo->stFreeList.pstNext = node;//池头空闲链表指向第一个节块 + + for (index = 0; index < boxInfo->uwBlkNum - 1; ++index) {//切割节块,挂入空闲链表 + node->pstNext = OS_MEMBOX_NEXT(node, boxInfo->uwBlkSize);//按块大小切割好,统一由pstNext指向 + node = node->pstNext;//node存储了下一个节点的地址信息 + } + + node->pstNext = NULL;//最后一个为null + + MEMBOX_UNLOCK(intSave); + + return LOS_OK; +} +/// 从指定的静态内存池中申请一块静态内存块,整个内核源码只有 OsSwtmrScan中用到了静态内存. +LITE_OS_SEC_TEXT VOID *LOS_MemboxAlloc(VOID *pool) +{ + LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool; + LOS_MEMBOX_NODE *node = NULL; + LOS_MEMBOX_NODE *nodeTmp = NULL; + UINT32 intSave; + + if (pool == NULL) { + return NULL; + } + + MEMBOX_LOCK(intSave); + node = &(boxInfo->stFreeList);//拿到空闲单链表 + if (node->pstNext != NULL) {//不需要遍历链表,因为这是空闲链表 + nodeTmp = node->pstNext;//先记录要使用的节点 + node->pstNext = nodeTmp->pstNext;//不再空闲了,把节点摘出去了. + OS_MEMBOX_SET_MAGIC(nodeTmp);//为已使用的节块设置魔法数字 + boxInfo->uwBlkCnt++;//已使用块数增加 + } + MEMBOX_UNLOCK(intSave); + + return (nodeTmp == NULL) ? NULL : OS_MEMBOX_USER_ADDR(nodeTmp);//返回可用的虚拟地址 +} +/// 释放指定的一块静态内存块 +LITE_OS_SEC_TEXT UINT32 LOS_MemboxFree(VOID *pool, VOID *box) +{ + LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool; + UINT32 ret = LOS_NOK; + UINT32 intSave; + + if ((pool == NULL) || (box == NULL)) { + return LOS_NOK; + } + + MEMBOX_LOCK(intSave); + do { + LOS_MEMBOX_NODE *node = OS_MEMBOX_NODE_ADDR(box);//通过节体获取节块首地址 + if (OsCheckBoxMem(boxInfo, node) != LOS_OK) { + break; + } + + node->pstNext = boxInfo->stFreeList.pstNext;//节块指向空闲链表表头 + boxInfo->stFreeList.pstNext = node;//空闲链表表头反指向它,意味节块排到第一,下次申请将首个分配它 + boxInfo->uwBlkCnt--;//已经使用的内存块减一 + ret = LOS_OK; + } while (0);//将被编译时优化 + MEMBOX_UNLOCK(intSave); + + return ret; +} +/// 清零指定静态内存块的内容 +LITE_OS_SEC_TEXT_MINOR VOID LOS_MemboxClr(VOID *pool, VOID *box) +{ + LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool; + + if ((pool == NULL) || (box == NULL)) { + return; + } + //将魔法数字一并清除了. + (VOID)memset_s(box, (boxInfo->uwBlkSize - OS_MEMBOX_NODE_HEAD_SIZE), 0, + (boxInfo->uwBlkSize - OS_MEMBOX_NODE_HEAD_SIZE)); +} +/// 打印指定静态内存池所有节点信息(打印等级是LOS_INFO_LEVEL),包括内存池起始地址、 +/// 内存块大小、总内存块数量、每个空闲内存块的起始地址、所有内存块的起始地址 +LITE_OS_SEC_TEXT_MINOR VOID LOS_ShowBox(VOID *pool) +{ + UINT32 index; + UINT32 intSave; + LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool; + LOS_MEMBOX_NODE *node = NULL; + + if (pool == NULL) { + return; + } + MEMBOX_LOCK(intSave); + PRINT_INFO("membox(%p,0x%x,0x%x):\r\n", pool, boxInfo->uwBlkSize, boxInfo->uwBlkNum); + PRINT_INFO("free node list:\r\n"); + + for (node = boxInfo->stFreeList.pstNext, index = 0; node != NULL; + node = node->pstNext, ++index) { + PRINT_INFO("(%u,%p)\r\n", index, node); + } + + PRINT_INFO("all node list:\r\n"); + node = (LOS_MEMBOX_NODE *)(boxInfo + 1); + for (index = 0; index < boxInfo->uwBlkNum; ++index, node = OS_MEMBOX_NEXT(node, boxInfo->uwBlkSize)) { + PRINT_INFO("(%u,%p,%p)\r\n", index, node, node->pstNext); + } + MEMBOX_UNLOCK(intSave); +} +/// 获取指定静态内存池的信息,包括内存池中总内存块数量、已经分配出去的内存块数量、每个内存块的大小 +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemboxStatisticsGet(const VOID *boxMem, UINT32 *maxBlk, + UINT32 *blkCnt, UINT32 *blkSize) +{ + if ((boxMem == NULL) || (maxBlk == NULL) || (blkCnt == NULL) || (blkSize == NULL)) { + return LOS_NOK; + } + + *maxBlk = ((OS_MEMBOX_S *)boxMem)->uwBlkNum; + *blkCnt = ((OS_MEMBOX_S *)boxMem)->uwBlkCnt; + *blkSize = ((OS_MEMBOX_S *)boxMem)->uwBlkSize; + + return LOS_OK; +} + +TRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_membox.h" +#include "los_hwi.h" +#include "los_spinlock.h" + #ifdef LOSCFG_AARCH64 #define OS_MEMBOX_MAGIC 0xa55a5aa5a55a5aa5 diff --git a/src/kernel_liteos_a/kernel/base/mem/tlsf/los_memory.c b/src/kernel_liteos_a/kernel/base/mem/tlsf/los_memory.c index 3441b613..5086ca7b 100644 --- a/src/kernel_liteos_a/kernel/base/mem/tlsf/los_memory.c +++ b/src/kernel_liteos_a/kernel/base/mem/tlsf/los_memory.c @@ -43,7 +43,7 @@ #include "los_lms_pri.h" #endif -/* Used to cut non-essential functions. */ +/* Used to cut non-essential functions. | 用于削减非必要功能 */ #define OS_MEM_FREE_BY_TASKID 0 #ifdef LOSCFG_KERNEL_VM #define OS_MEM_EXPAND_ENABLE 1 @@ -56,32 +56,32 @@ /* column num of the output info of mem node */ #define OS_MEM_COLUMN_NUM 8 -UINT8 *m_aucSysMem0 = NULL; -UINT8 *m_aucSysMem1 = NULL; +UINT8 *m_aucSysMem0 = NULL; ///< 异常交互动态内存池地址的起始地址,当不支持异常交互特性时,m_aucSysMem0等于m_aucSysMem1。 +UINT8 *m_aucSysMem1 = NULL; ///< (内核态)系统动态内存池地址的起始地址 #ifdef LOSCFG_MEM_MUL_POOL -VOID *g_poolHead = NULL; +VOID *g_poolHead = NULL; ///内存池头,由它牵引多个内存池 #endif /* The following is the macro definition and interface implementation related to the TLSF. */ /* Supposing a Second Level Index: SLI = 3. */ -#define OS_MEM_SLI 3 +#define OS_MEM_SLI 3 ///< 二级小区间级数, /* Giving 1 free list for each small bucket: 4, 8, 12, up to 124. */ -#define OS_MEM_SMALL_BUCKET_COUNT 31 -#define OS_MEM_SMALL_BUCKET_MAX_SIZE 128 -/* Giving OS_MEM_FREE_LIST_NUM free lists for each large bucket. */ -#define OS_MEM_LARGE_BUCKET_COUNT 24 -#define OS_MEM_FREE_LIST_NUM (1 << OS_MEM_SLI) +#define OS_MEM_SMALL_BUCKET_COUNT 31 ///< 小桶的偏移单位 从 4 ~ 124 ,共32级 +#define OS_MEM_SMALL_BUCKET_MAX_SIZE 128 ///< 小桶的最大数量 +/* Giving OS_MEM_FREE_LIST_NUM free lists for each large bucket. */ +#define OS_MEM_LARGE_BUCKET_COUNT 24 /// 为每个大存储桶空闲列表数量 大桶范围: [2^7, 2^31] ,每个小区间有分为 2^3个小区间 +#define OS_MEM_FREE_LIST_NUM (1 << OS_MEM_SLI) ///< 2^3 = 8 个,即大桶的每个区间又分为8个小区间 /* OS_MEM_SMALL_BUCKET_MAX_SIZE to the power of 2 is 7. */ -#define OS_MEM_LARGE_START_BUCKET 7 +#define OS_MEM_LARGE_START_BUCKET 7 /// 大桶的开始下标 /* The count of free list. */ -#define OS_MEM_FREE_LIST_COUNT (OS_MEM_SMALL_BUCKET_COUNT + (OS_MEM_LARGE_BUCKET_COUNT << OS_MEM_SLI)) +#define OS_MEM_FREE_LIST_COUNT (OS_MEM_SMALL_BUCKET_COUNT + (OS_MEM_LARGE_BUCKET_COUNT << OS_MEM_SLI)) ///< 总链表的数量 32 + 24 * 8 = 224 /* The bitmap is used to indicate whether the free list is empty, 1: not empty, 0: empty. */ -#define OS_MEM_BITMAP_WORDS ((OS_MEM_FREE_LIST_COUNT >> 5) + 1) - -#define OS_MEM_BITMAP_MASK 0x1FU +#define OS_MEM_BITMAP_WORDS ((OS_MEM_FREE_LIST_COUNT >> 5) + 1) ///< 224 >> 5 + 1 = 7 ,为什么要右移 5 因为 2^5 = 32 是一个32位整型的大小 + ///< 而 32 * 7 = 224 ,也就是说用 int[7]当位图就能表示完 224个链表 ,此处,一定要理解好,因为这是理解 TLSF 算法的关键. +#define OS_MEM_BITMAP_MASK 0x1FU ///< 因为一个int型为 32位, 2^5 = 32,所以此处 0x1FU = 5个1 足以. /* Used to find the first bit of 1 in bitmap. */ STATIC INLINE UINT16 OsMemFFS(UINT32 bitmap) @@ -101,7 +101,7 @@ STATIC INLINE UINT32 OsMemLog2(UINT32 size) return OsMemFLS(size); } -/* Get the first level: f = log2(size). */ +/* Get the first level: f = log2(size). | 获取第一级*/ STATIC INLINE UINT32 OsMemFlGet(UINT32 size) { if (size < OS_MEM_SMALL_BUCKET_MAX_SIZE) { @@ -110,56 +110,56 @@ STATIC INLINE UINT32 OsMemFlGet(UINT32 size) return OsMemLog2(size); } -/* Get the second level: s = (size - 2^f) * 2^SLI / 2^f. */ +/* Get the second level: s = (size - 2^f) * 2^SLI / 2^f. | 获取第二级 */ STATIC INLINE UINT32 OsMemSlGet(UINT32 size, UINT32 fl) { return (((size << OS_MEM_SLI) >> fl) - OS_MEM_FREE_LIST_NUM); } /* The following is the memory algorithm related macro definition and interface implementation. */ - +/// 内存池节点 struct OsMemNodeHead { - UINT32 magic; - union { - struct OsMemNodeHead *prev; /* The prev is used for current node points to the previous node */ - struct OsMemNodeHead *next; /* The next is used for last node points to the expand node */ + UINT32 magic; ///< 魔法数字 0xABCDDCBA + union {//注意这里的前后指向的是连续的地址节点,用于分割和合并 + struct OsMemNodeHead *prev; /* The prev is used for current node points to the previous node | prev 用于当前节点指向前一个节点*/ + struct OsMemNodeHead *next; /* The next is used for last node points to the expand node | next 用于最后一个节点指向展开节点*/ } ptr; -#ifdef LOSCFG_MEM_LEAKCHECK - UINTPTR linkReg[LOS_RECORD_LR_CNT]; +#ifdef LOSCFG_MEM_LEAKCHECK //内存泄漏检测 + UINTPTR linkReg[LOS_RECORD_LR_CNT];///< 存放左右节点地址,用于检测 #endif - UINT32 sizeAndFlag; + UINT32 sizeAndFlag; ///< 节点总大小+标签 }; - +/// 已使用内存池节点 struct OsMemUsedNodeHead { - struct OsMemNodeHead header; + struct OsMemNodeHead header;///< 已被使用节点 #if OS_MEM_FREE_BY_TASKID - UINT32 taskID; + UINT32 taskID; ///< 使用节点的任务ID #endif }; - +/// 内存池空闲节点 struct OsMemFreeNodeHead { - struct OsMemNodeHead header; - struct OsMemFreeNodeHead *prev; - struct OsMemFreeNodeHead *next; + struct OsMemNodeHead header; ///< 内存池节点 + struct OsMemFreeNodeHead *prev; ///< 前一个空闲前驱节点 + struct OsMemFreeNodeHead *next; ///< 后一个空闲后继节点 }; - +/// 内存池信息 struct OsMemPoolInfo { - VOID *pool; - UINT32 totalSize; - UINT32 attr; + VOID *pool; ///< 指向内存块基地址,仅做记录而已,真正的分配内存跟它没啥关系 + UINT32 totalSize; ///< 总大小,确定了内存池的边界 + UINT32 attr; ///< 属性 default attr: lock, not expand. #ifdef LOSCFG_MEM_WATERLINE - UINT32 waterLine; /* Maximum usage size in a memory pool */ - UINT32 curUsedSize; /* Current usage size in a memory pool */ + UINT32 waterLine; /* Maximum usage size in a memory pool | 内存吃水线*/ + UINT32 curUsedSize; /* Current usage size in a memory pool | 当前已使用大小*/ #endif }; - +/// 内存池头信息 struct OsMemPoolHead { - struct OsMemPoolInfo info; - UINT32 freeListBitmap[OS_MEM_BITMAP_WORDS]; - struct OsMemFreeNodeHead *freeList[OS_MEM_FREE_LIST_COUNT]; - SPIN_LOCK_S spinlock; + struct OsMemPoolInfo info; ///< 记录内存池的信息 + UINT32 freeListBitmap[OS_MEM_BITMAP_WORDS]; ///< 空闲位图 int[7] = 32 * 7 = 224 > 223 + struct OsMemFreeNodeHead *freeList[OS_MEM_FREE_LIST_COUNT];///< 空闲节点链表 32 + 24 * 8 = 224 + SPIN_LOCK_S spinlock; ///< 操作本池的自旋锁,涉及CPU多核竞争,所以必须得是自旋锁 #ifdef LOSCFG_MEM_MUL_POOL - VOID *nextPool; + VOID *nextPool; ///< 指向下一个内存池 OsMemPoolHead 类型 #endif }; @@ -168,16 +168,16 @@ struct OsMemPoolHead { #define MEM_UNLOCK(pool, state) LOS_SpinUnlockRestore(&(pool)->spinlock, (state)) /* The memory pool support expand. */ -#define OS_MEM_POOL_EXPAND_ENABLE 0x01 +#define OS_MEM_POOL_EXPAND_ENABLE 0x01 ///< 支持扩展 /* The memory pool support no lock. */ -#define OS_MEM_POOL_LOCK_ENABLE 0x02 - -#define OS_MEM_NODE_MAGIC 0xABCDDCBA -#define OS_MEM_MIN_ALLOC_SIZE (sizeof(struct OsMemFreeNodeHead) - sizeof(struct OsMemUsedNodeHead)) - -#define OS_MEM_NODE_USED_FLAG 0x80000000U -#define OS_MEM_NODE_ALIGNED_FLAG 0x40000000U -#define OS_MEM_NODE_LAST_FLAG 0x20000000U /* Sentinel Node */ +#define OS_MEM_POOL_LOCK_ENABLE 0x02 ///< 加锁 + +#define OS_MEM_NODE_MAGIC 0xABCDDCBA ///< 内存节点的魔法数字 +#define OS_MEM_MIN_ALLOC_SIZE (sizeof(struct OsMemFreeNodeHead) - sizeof(struct OsMemUsedNodeHead)) //最小分配空间 +// 必须给指向空闲块的指针留位置 +#define OS_MEM_NODE_USED_FLAG 0x80000000U ///< 已使用标签 +#define OS_MEM_NODE_ALIGNED_FLAG 0x40000000U ///< 对齐标签 +#define OS_MEM_NODE_LAST_FLAG 0x20000000U /* Sentinel Node | 哨兵节点标签*/ #define OS_MEM_NODE_ALIGNED_AND_USED_FLAG (OS_MEM_NODE_USED_FLAG | OS_MEM_NODE_ALIGNED_FLAG | OS_MEM_NODE_LAST_FLAG) #define OS_MEM_NODE_GET_ALIGNED_FLAG(sizeAndFlag) \ @@ -226,32 +226,33 @@ STATIC INLINE UINT32 OsMemAllocCheck(struct OsMemPoolHead *pool, UINT32 intSave) #if OS_MEM_FREE_BY_TASKID STATIC INLINE VOID OsMemNodeSetTaskID(struct OsMemUsedNodeHead *node) { - node->taskID = LOS_CurTaskIDGet(); + node->taskID = LOS_CurTaskIDGet();//将当前任务ID绑定到内存池节点上 } #endif #ifdef LOSCFG_MEM_WATERLINE STATIC INLINE VOID OsMemWaterUsedRecord(struct OsMemPoolHead *pool, UINT32 size) { - pool->info.curUsedSize += size; + pool->info.curUsedSize += size; //延长可使用空间 if (pool->info.curUsedSize > pool->info.waterLine) { - pool->info.waterLine = pool->info.curUsedSize; + pool->info.waterLine = pool->info.curUsedSize; //警戒线加高 } } #else STATIC INLINE VOID OsMemWaterUsedRecord(struct OsMemPoolHead *pool, UINT32 size) { - (VOID)pool; - (VOID)size; + (VOID)pool; + (VOID)size; } #endif #if OS_MEM_EXPAND_ENABLE +/// 更新哨兵节点内容 STATIC INLINE struct OsMemNodeHead *OsMemLastSentinelNodeGet(const struct OsMemNodeHead *sentinelNode) { struct OsMemNodeHead *node = NULL; - VOID *ptr = sentinelNode->ptr.next; - UINT32 size = OS_MEM_NODE_GET_SIZE(sentinelNode->sizeAndFlag); + VOID *ptr = sentinelNode->ptr.next;//返回不连续的内存块 + UINT32 size = OS_MEM_NODE_GET_SIZE(sentinelNode->sizeAndFlag); // 获取大小 while ((ptr != NULL) && (size != 0)) { node = OS_MEM_END_NODE(ptr, size); @@ -261,7 +262,7 @@ STATIC INLINE struct OsMemNodeHead *OsMemLastSentinelNodeGet(const struct OsMemN return node; } - +/// 检查哨兵节点 STATIC INLINE BOOL OsMemSentinelNodeCheck(struct OsMemNodeHead *sentinelNode) { if (!OS_MEM_NODE_GET_USED_FLAG(sentinelNode->sizeAndFlag)) { @@ -274,7 +275,7 @@ STATIC INLINE BOOL OsMemSentinelNodeCheck(struct OsMemNodeHead *sentinelNode) return TRUE; } - +/// 是否为最后一个哨兵节点 STATIC INLINE BOOL OsMemIsLastSentinelNode(struct OsMemNodeHead *sentinelNode) { if (OsMemSentinelNodeCheck(sentinelNode) == FALSE) { @@ -289,11 +290,11 @@ STATIC INLINE BOOL OsMemIsLastSentinelNode(struct OsMemNodeHead *sentinelNode) return FALSE; } - +/// 设置哨兵节点内容 STATIC INLINE VOID OsMemSentinelNodeSet(struct OsMemNodeHead *sentinelNode, VOID *newNode, UINT32 size) { - if (sentinelNode->ptr.next != NULL) { - sentinelNode = OsMemLastSentinelNodeGet(sentinelNode); + if (sentinelNode->ptr.next != NULL) { //哨兵节点有 逻辑地址不连续的衔接内存块 + sentinelNode = OsMemLastSentinelNodeGet(sentinelNode);//更新哨兵节点内容 } sentinelNode->sizeAndFlag = size; @@ -329,14 +330,14 @@ STATIC INLINE struct OsMemNodeHead *PreSentinelNodeGet(const VOID *pool, const s return NULL; } - +/// 大内存释放 UINT32 OsMemLargeNodeFree(const VOID *ptr) { - LosVmPage *page = OsVmVaddrToPage((VOID *)ptr); + LosVmPage *page = OsVmVaddrToPage((VOID *)ptr);//获取物理页 if ((page == NULL) || (page->nPages == 0)) { return LOS_NOK; } - LOS_PhysPagesFreeContiguous((VOID *)ptr, page->nPages); + LOS_PhysPagesFreeContiguous((VOID *)ptr, page->nPages);//释放连续的几个物理页 return LOS_OK; } @@ -375,7 +376,7 @@ STATIC INLINE BOOL TryShrinkPool(const VOID *pool, const struct OsMemNodeHead *n #endif return TRUE; } - +/// 内存池扩展实现 STATIC INLINE INT32 OsMemPoolExpandSub(VOID *pool, UINT32 size, UINT32 intSave) { UINT32 tryCount = MAX_SHRINK_PAGECACHE_TRY; @@ -383,11 +384,11 @@ STATIC INLINE INT32 OsMemPoolExpandSub(VOID *pool, UINT32 size, UINT32 intSave) struct OsMemNodeHead *newNode = NULL; struct OsMemNodeHead *endNode = NULL; - size = ROUNDUP(size + OS_MEM_NODE_HEAD_SIZE, PAGE_SIZE); - endNode = OS_MEM_END_NODE(pool, poolInfo->info.totalSize); + size = ROUNDUP(size + OS_MEM_NODE_HEAD_SIZE, PAGE_SIZE);//圆整 + endNode = OS_MEM_END_NODE(pool, poolInfo->info.totalSize);//获取哨兵节点 RETRY: - newNode = (struct OsMemNodeHead *)LOS_PhysPagesAllocContiguous(size >> PAGE_SHIFT); + newNode = (struct OsMemNodeHead *)LOS_PhysPagesAllocContiguous(size >> PAGE_SHIFT);//申请新的内存池 | 物理内存 if (newNode == NULL) { if (tryCount > 0) { tryCount--; @@ -411,26 +412,26 @@ RETRY: size = (resize == 0) ? size : resize; } #endif - newNode->sizeAndFlag = (size - OS_MEM_NODE_HEAD_SIZE); - newNode->ptr.prev = OS_MEM_END_NODE(newNode, size); - OsMemSentinelNodeSet(endNode, newNode, size); - OsMemFreeNodeAdd(pool, (struct OsMemFreeNodeHead *)newNode); + newNode->sizeAndFlag = (size - OS_MEM_NODE_HEAD_SIZE);//设置新节点大小 + newNode->ptr.prev = OS_MEM_END_NODE(newNode, size);//新节点的前节点指向新节点的哨兵节点 + OsMemSentinelNodeSet(endNode, newNode, size);//设置老内存池的哨兵节点信息,其实就是指向新内存块 + OsMemFreeNodeAdd(pool, (struct OsMemFreeNodeHead *)newNode);//将新节点加入空闲链表 - endNode = OS_MEM_END_NODE(newNode, size); - (VOID)memset(endNode, 0, sizeof(*endNode)); - endNode->ptr.next = NULL; - endNode->magic = OS_MEM_NODE_MAGIC; - OsMemSentinelNodeSet(endNode, NULL, 0); - OsMemWaterUsedRecord(poolInfo, OS_MEM_NODE_HEAD_SIZE); + endNode = OS_MEM_END_NODE(newNode, size);//获取新节点的哨兵节点 + (VOID)memset(endNode, 0, sizeof(*endNode));//清空内存 + endNode->ptr.next = NULL;//新哨兵节点没有后续指向,因为它已成为最后 + endNode->magic = OS_MEM_NODE_MAGIC;//设置新哨兵节的魔法数字 + OsMemSentinelNodeSet(endNode, NULL, 0); //设置新哨兵节点内容 + OsMemWaterUsedRecord(poolInfo, OS_MEM_NODE_HEAD_SIZE);//更新内存池警戒线 return 0; } - +/// 扩展内存池 STATIC INLINE INT32 OsMemPoolExpand(VOID *pool, UINT32 allocSize, UINT32 intSave) { - UINT32 expandDefault = MEM_EXPAND_SIZE(LOS_MemPoolSizeGet(pool)); + UINT32 expandDefault = MEM_EXPAND_SIZE(LOS_MemPoolSizeGet(pool));//至少要扩展现有内存池的 1/8 大小 UINT32 expandSize = MAX(expandDefault, allocSize); - UINT32 tryCount = 1; + UINT32 tryCount = 1;//尝试次数 UINT32 ret; do { @@ -447,7 +448,7 @@ STATIC INLINE INT32 OsMemPoolExpand(VOID *pool, UINT32 allocSize, UINT32 intSave return -1; } - +///< 允许指定内存池扩展 VOID LOS_MemExpandEnable(VOID *pool) { if (pool == NULL) { @@ -486,7 +487,7 @@ STATIC INLINE VOID OsLmsAllocAlignMark(VOID *ptr, VOID *alignedPtr, UINT32 size) g_lms->simpleMark((UINTPTR)ptr + sizeof(UINT32), (UINTPTR)alignedPtr, LMS_SHADOW_REDZONE_U8); } - /* mark remaining as redzone */ + /* mark remining as redzone */ g_lms->simpleMark(LMS_ADDR_ALIGN((UINTPTR)alignedPtr + size), (UINTPTR)OS_MEM_NEXT_NODE(allocNode), LMS_SHADOW_REDZONE_U8); } @@ -522,8 +523,7 @@ STATIC INLINE VOID OsLmsReallocResizeMark(struct OsMemNodeHead *node, UINT32 res g_lms->simpleMark((UINTPTR)node + resize, (UINTPTR)OS_MEM_NEXT_NODE(node), LMS_SHADOW_REDZONE_U8); } #endif - -#ifdef LOSCFG_MEM_LEAKCHECK +#ifdef LOSCFG_MEM_LEAKCHECK //内存泄漏检查 STATIC INLINE VOID OsMemLinkRegisterRecord(struct OsMemNodeHead *node) { LOS_RecordLR(node->linkReg, LOS_RECORD_LR_CNT, LOS_RECORD_LR_CNT, LOS_OMIT_LR_CNT); @@ -549,7 +549,7 @@ STATIC INLINE VOID OsMemUsedNodePrint(struct OsMemNodeHead *node) PRINTK("\n"); } } - +/// 打印已使用的节点 VOID OsMemUsedNodeShow(VOID *pool) { if (pool == NULL) { @@ -626,17 +626,17 @@ STATIC VOID OsMemNodeBacktraceInfo(const struct OsMemNodeHead *tmpNode, STATIC INLINE UINT32 OsMemFreeListIndexGet(UINT32 size) { - UINT32 fl = OsMemFlGet(size); + UINT32 fl = OsMemFlGet(size);//获取一级位图 if (size < OS_MEM_SMALL_BUCKET_MAX_SIZE) { return fl; } - UINT32 sl = OsMemSlGet(size, fl); + UINT32 sl = OsMemSlGet(size, fl);//获取二级位图 return (OS_MEM_SMALL_BUCKET_COUNT + ((fl - OS_MEM_LARGE_START_BUCKET) << OS_MEM_SLI) + sl); } STATIC INLINE struct OsMemFreeNodeHead *OsMemFindCurSuitableBlock(struct OsMemPoolHead *poolHead, - UINT32 index, UINT32 size) + UINT32 index, UINT32 size) { struct OsMemFreeNodeHead *node = NULL; @@ -663,7 +663,7 @@ STATIC INLINE UINT32 OsMemNotEmptyIndexGet(struct OsMemPoolHead *poolHead, UINT3 return OS_MEM_FREE_LIST_COUNT; } - +/// 找到下一个合适的块 STATIC INLINE struct OsMemFreeNodeHead *OsMemFindNextSuitableBlock(VOID *pool, UINT32 size, UINT32 *outIndex) { struct OsMemPoolHead *poolHead = (struct OsMemPoolHead *)pool; @@ -730,13 +730,13 @@ STATIC INLINE VOID OsMemListAdd(struct OsMemPoolHead *pool, UINT32 listIndex, st OsMemSetFreeListBit(pool, listIndex); node->header.magic = OS_MEM_NODE_MAGIC; } - +/// 从空闲链表中删除 STATIC INLINE VOID OsMemListDelete(struct OsMemPoolHead *pool, UINT32 listIndex, struct OsMemFreeNodeHead *node) { if (node == pool->freeList[listIndex]) { pool->freeList[listIndex] = node->next; - if (node->next == NULL) { - OsMemClearFreeListBit(pool, listIndex); + if (node->next == NULL) {//如果链表空了 + OsMemClearFreeListBit(pool, listIndex);//将位图位 置为 0 } else { node->next->prev = NULL; } @@ -748,27 +748,27 @@ STATIC INLINE VOID OsMemListDelete(struct OsMemPoolHead *pool, UINT32 listIndex, } node->header.magic = OS_MEM_NODE_MAGIC; } - +/// 添加一个空闲节点 STATIC INLINE VOID OsMemFreeNodeAdd(VOID *pool, struct OsMemFreeNodeHead *node) { - UINT32 index = OsMemFreeListIndexGet(node->header.sizeAndFlag); + UINT32 index = OsMemFreeListIndexGet(node->header.sizeAndFlag);//根据大小定位索引位 if (index >= OS_MEM_FREE_LIST_COUNT) { LOS_Panic("The index of free lists is error, index = %u\n", index); return; } - OsMemListAdd(pool, index, node); + OsMemListAdd(pool, index, node);//挂入链表 } - +/// 从空闲链表上摘除节点 STATIC INLINE VOID OsMemFreeNodeDelete(VOID *pool, struct OsMemFreeNodeHead *node) { - UINT32 index = OsMemFreeListIndexGet(node->header.sizeAndFlag); + UINT32 index = OsMemFreeListIndexGet(node->header.sizeAndFlag);//根据大小定位索引位 if (index >= OS_MEM_FREE_LIST_COUNT) { LOS_Panic("The index of free lists is error, index = %u\n", index); return; } OsMemListDelete(pool, index, node); } - +//获取一个空闲的节点 STATIC INLINE struct OsMemNodeHead *OsMemFreeNodeGet(VOID *pool, UINT32 size) { struct OsMemPoolHead *poolHead = (struct OsMemPoolHead *)pool; @@ -782,56 +782,67 @@ STATIC INLINE struct OsMemNodeHead *OsMemFreeNodeGet(VOID *pool, UINT32 size) return &firstNode->header; } - +/// 合并节点,和前面的节点合并 node 消失 STATIC INLINE VOID OsMemMergeNode(struct OsMemNodeHead *node) { struct OsMemNodeHead *nextNode = NULL; - node->ptr.prev->sizeAndFlag += node->sizeAndFlag; - nextNode = (struct OsMemNodeHead *)((UINTPTR)node + node->sizeAndFlag); - if (!OS_MEM_NODE_GET_LAST_FLAG(nextNode->sizeAndFlag)) { - nextNode->ptr.prev = node->ptr.prev; + node->ptr.prev->sizeAndFlag += node->sizeAndFlag; //前节点长度变长 + nextNode = (struct OsMemNodeHead *)((UINTPTR)node + node->sizeAndFlag); // 下一个节点位置 + if (!OS_MEM_NODE_GET_LAST_FLAG(nextNode->sizeAndFlag)) {//不是哨兵节点 + nextNode->ptr.prev = node->ptr.prev;//后一个节点的前节点变成前前节点 } } - +/// 切割节点 STATIC INLINE VOID OsMemSplitNode(VOID *pool, struct OsMemNodeHead *allocNode, UINT32 allocSize) { struct OsMemFreeNodeHead *newFreeNode = NULL; struct OsMemNodeHead *nextNode = NULL; - newFreeNode = (struct OsMemFreeNodeHead *)(VOID *)((UINT8 *)allocNode + allocSize); - newFreeNode->header.ptr.prev = allocNode; - newFreeNode->header.sizeAndFlag = allocNode->sizeAndFlag - allocSize; - allocNode->sizeAndFlag = allocSize; - nextNode = OS_MEM_NEXT_NODE(&newFreeNode->header); - if (!OS_MEM_NODE_GET_LAST_FLAG(nextNode->sizeAndFlag)) { - nextNode->ptr.prev = &newFreeNode->header; - if (!OS_MEM_NODE_GET_USED_FLAG(nextNode->sizeAndFlag)) { - OsMemFreeNodeDelete(pool, (struct OsMemFreeNodeHead *)nextNode); - OsMemMergeNode(nextNode); + newFreeNode = (struct OsMemFreeNodeHead *)(VOID *)((UINT8 *)allocNode + allocSize);//切割后出现的新空闲节点,在分配节点的右侧 + newFreeNode->header.ptr.prev = allocNode;//新节点指向前节点,说明是从左到右切割 + newFreeNode->header.sizeAndFlag = allocNode->sizeAndFlag - allocSize;//新空闲节点大小 + allocNode->sizeAndFlag = allocSize;//分配节点大小 + nextNode = OS_MEM_NEXT_NODE(&newFreeNode->header);//获取新节点的下一个节点 + if (!OS_MEM_NODE_GET_LAST_FLAG(nextNode->sizeAndFlag)) {//如果下一个节点不是哨兵节点(末尾节点) + nextNode->ptr.prev = &newFreeNode->header;//下一个节点的前节点为新空闲节点 + if (!OS_MEM_NODE_GET_USED_FLAG(nextNode->sizeAndFlag)) {//如果下一个节点也是空闲的 + OsMemFreeNodeDelete(pool, (struct OsMemFreeNodeHead *)nextNode);//删除下一个节点信息 + OsMemMergeNode(nextNode);//下一个节点和新空闲节点 合并成一个新节点 } } - OsMemFreeNodeAdd(pool, newFreeNode); + OsMemFreeNodeAdd(pool, newFreeNode);//挂入空闲链表 } - +// STATIC INLINE VOID *OsMemCreateUsedNode(VOID *addr) { - struct OsMemUsedNodeHead *node = (struct OsMemUsedNodeHead *)addr; - + struct OsMemUsedNodeHead *node = (struct OsMemUsedNodeHead *)addr;//直接将地址转成使用节点,说明节点信息也存在内存池中 + //这种用法是非常巧妙的 #if OS_MEM_FREE_BY_TASKID - OsMemNodeSetTaskID(node); + OsMemNodeSetTaskID(node);//设置使用内存节点的任务 #endif -#ifdef LOSCFG_KERNEL_LMS +#ifdef LOSCFG_KERNEL_LMS //检测内存泄漏 struct OsMemNodeHead *newNode = (struct OsMemNodeHead *)node; if (g_lms != NULL) { g_lms->mallocMark(newNode, OS_MEM_NEXT_NODE(newNode), OS_MEM_NODE_HEAD_SIZE); } #endif - return node + 1; + return node + 1; //@note_good 这个地方挺有意思的,只是将结构体扩展下,留一个 int 位 ,变成了已使用节点,返回的地址正是要分配给应用的地址 } +/*! + * @brief OsMemPoolInit 内存池初始化 + * 内存池节点部分包含3种类型节点:未使用空闲内存节点(OsMemFreeNodeHead),已使用内存节点(OsMemUsedNodeHead) 和 尾节点(OsMemNodeHead)。 + * \n 每个内存节点维护一个前序指针,指向内存池中上一个内存节点,还维护内存节点的大小和使用标记。 + * \n 空闲内存节点和已使用内存节点后面的内存区域是数据域 + * @param pool + * @param size + * @return + * + * @see + */ STATIC UINT32 OsMemPoolInit(VOID *pool, UINT32 size) { struct OsMemPoolHead *poolHead = (struct OsMemPoolHead *)pool; @@ -853,30 +864,32 @@ STATIC UINT32 OsMemPoolInit(VOID *pool, UINT32 size) #endif LOS_SpinInit(&poolHead->spinlock); - poolHead->info.pool = pool; - poolHead->info.totalSize = size; - poolHead->info.attr = OS_MEM_POOL_LOCK_ENABLE; /* default attr: lock, not expand. */ + poolHead->info.pool = pool; //内存池的起始地址,但注意真正的内存并不是从此处分配,它只是用来记录这个内存块的开始位置而已. + poolHead->info.totalSize = size;//内存池总大小 + poolHead->info.attr = OS_MEM_POOL_LOCK_ENABLE; /* default attr: lock, not expand. | 默认是上锁,不支持扩展,需扩展得另外设置*/ - newNode = OS_MEM_FIRST_NODE(pool); - newNode->sizeAndFlag = (size - sizeof(struct OsMemPoolHead) - OS_MEM_NODE_HEAD_SIZE); - newNode->ptr.prev = NULL; - newNode->magic = OS_MEM_NODE_MAGIC; - OsMemFreeNodeAdd(pool, (struct OsMemFreeNodeHead *)newNode); + newNode = OS_MEM_FIRST_NODE(pool);//跳到第一个节点位置,即跳过结构体本身位置,真正的分配内存是从newNode开始的. + newNode->sizeAndFlag = (size - sizeof(struct OsMemPoolHead) - OS_MEM_NODE_HEAD_SIZE);//这才是可供分配给外界使用的总内存块大小,即数据域 + //OS_MEM_NODE_HEAD_SIZE 叫当前使用节点,即指 newNode占用的空间 + newNode->ptr.prev = NULL;//开始是空指向 + newNode->magic = OS_MEM_NODE_MAGIC;//魔法数字 用于标识这是一个 OsMemNodeHead 节点, 魔法数字不能被覆盖, + OsMemFreeNodeAdd(pool, (struct OsMemFreeNodeHead *)newNode);//添加一个空闲节点,由此有了首个可供分配的空闲节点 /* The last mem node */ - endNode = OS_MEM_END_NODE(pool, size); - endNode->magic = OS_MEM_NODE_MAGIC; -#if OS_MEM_EXPAND_ENABLE - endNode->ptr.next = NULL; - OsMemSentinelNodeSet(endNode, NULL, 0); + endNode = OS_MEM_END_NODE(pool, size);//确定尾节点位置,尾节点没有数据域 + endNode->magic = OS_MEM_NODE_MAGIC; //填入尾节点的魔法数字 +#if OS_MEM_EXPAND_ENABLE //支持扩展 + endNode->ptr.next = NULL;//尾节点没有后继节点 + OsMemSentinelNodeSet(endNode, NULL, 0);//将尾节点设置为哨兵节点 #else - endNode->sizeAndFlag = 0; - endNode->ptr.prev = newNode; + endNode->sizeAndFlag = 0;//0代表没有数据域 + endNode->ptr.prev = newNode;//前驱指针指向第一个节点 OS_MEM_NODE_SET_USED_FLAG(endNode->sizeAndFlag); #endif -#ifdef LOSCFG_MEM_WATERLINE - poolHead->info.curUsedSize = sizeof(struct OsMemPoolHead) + OS_MEM_NODE_HEAD_SIZE; - poolHead->info.waterLine = poolHead->info.curUsedSize; +#ifdef LOSCFG_MEM_WATERLINE //吃水线开关 + poolHead->info.curUsedSize = sizeof(struct OsMemPoolHead) + OS_MEM_NODE_HEAD_SIZE;//内存池已使用了这么多空间,这些都是存内存池自身数据的空间, + //但此处是否还要算是 endNode ? @note_thinking + poolHead->info.waterLine = poolHead->info.curUsedSize; //设置吃水线 #endif #ifdef LOSCFG_KERNEL_LMS if (resize != 0) { @@ -896,13 +909,13 @@ STATIC VOID OsMemPoolDeinit(const VOID *pool, UINT32 size) #endif (VOID)memset_s(pool, size, 0, sizeof(struct OsMemPoolHead)); } - +/// 新增内存池 STATIC UINT32 OsMemPoolAdd(VOID *pool, UINT32 size) { VOID *nextPool = g_poolHead; VOID *curPool = g_poolHead; UINTPTR poolEnd; - while (nextPool != NULL) { + while (nextPool != NULL) {//单链表遍历方式 poolEnd = (UINTPTR)nextPool + LOS_MemPoolSizeGet(nextPool); if (((pool <= nextPool) && (((UINTPTR)pool + size) > (UINTPTR)nextPool)) || (((UINTPTR)pool < poolEnd) && (((UINTPTR)pool + size) >= poolEnd))) { @@ -916,15 +929,15 @@ STATIC UINT32 OsMemPoolAdd(VOID *pool, UINT32 size) } if (g_poolHead == NULL) { - g_poolHead = pool; + g_poolHead = pool; //首个内存池 } else { - ((struct OsMemPoolHead *)curPool)->nextPool = pool; + ((struct OsMemPoolHead *)curPool)->nextPool = pool; //两池扯上关系 } - ((struct OsMemPoolHead *)pool)->nextPool = NULL; + ((struct OsMemPoolHead *)pool)->nextPool = NULL; //新池下一个无所指 return LOS_OK; } - +/// 删除内存池 STATIC UINT32 OsMemPoolDelete(const VOID *pool) { UINT32 ret = LOS_NOK; @@ -955,29 +968,39 @@ STATIC UINT32 OsMemPoolDelete(const VOID *pool) } #endif +/*! + * @brief LOS_MemInit 初始化一块指定的动态内存池,大小为size + * 初始一个内存池后生成一个内存池控制头、尾节点EndNode,剩余的内存被标记为FreeNode内存节点。 + * @param pool + * @param size + * @return + * @attention EndNode作为内存池末尾的节点,size为0。 + * @see + */ UINT32 LOS_MemInit(VOID *pool, UINT32 size) { if ((pool == NULL) || (size <= OS_MEM_MIN_POOL_SIZE)) { return OS_ERROR; } - size = OS_MEM_ALIGN(size, OS_MEM_ALIGN_SIZE); + size = OS_MEM_ALIGN(size, OS_MEM_ALIGN_SIZE);//4个字节对齐 if (OsMemPoolInit(pool, size)) { return OS_ERROR; } -#ifdef LOSCFG_MEM_MUL_POOL +#ifdef LOSCFG_MEM_MUL_POOL //多内存池开关 if (OsMemPoolAdd(pool, size)) { (VOID)OsMemPoolDeInit(pool, size); return OS_ERROR; } #endif - OsHookCall(LOS_HOOK_TYPE_MEM_INIT, pool, size); + OsHookCall(LOS_HOOK_TYPE_MEM_INIT, pool, size);//打印日志 return LOS_OK; } #ifdef LOSCFG_MEM_MUL_POOL +/// 删除指定内存池 UINT32 LOS_MemDeInit(VOID *pool) { struct OsMemPoolHead *tmpPool = (struct OsMemPoolHead *)pool; @@ -997,7 +1020,7 @@ UINT32 LOS_MemDeInit(VOID *pool) OsHookCall(LOS_HOOK_TYPE_MEM_DEINIT, tmpPool); return LOS_OK; } - +/// 打印系统中已初始化的所有内存池,包括内存池的起始地址、内存池大小、空闲内存总大小、已使用内存总大小、最大的空闲内存块大小、空闲内存块数量、已使用的内存块数量。 UINT32 LOS_MemPoolList(VOID) { VOID *nextPool = g_poolHead; @@ -1011,7 +1034,7 @@ UINT32 LOS_MemPoolList(VOID) return index; } #endif - +/// 从指定动态内存池中申请size长度的内存 STATIC INLINE VOID *OsMemAlloc(struct OsMemPoolHead *pool, UINT32 size, UINT32 intSave) { struct OsMemNodeHead *allocNode = NULL; @@ -1024,15 +1047,15 @@ STATIC INLINE VOID *OsMemAlloc(struct OsMemPoolHead *pool, UINT32 size, UINT32 i UINT32 allocSize = OS_MEM_ALIGN(size + OS_MEM_NODE_HEAD_SIZE, OS_MEM_ALIGN_SIZE); #if OS_MEM_EXPAND_ENABLE -retry: +retry: //这种写法也挺赞的 @note_good #endif - allocNode = OsMemFreeNodeGet(pool, allocSize); - if (allocNode == NULL) { + allocNode = OsMemFreeNodeGet(pool, allocSize);//获取空闲节点 + if (allocNode == NULL) {//没有内存了,怎搞? #if OS_MEM_EXPAND_ENABLE if (pool->info.attr & OS_MEM_POOL_EXPAND_ENABLE) { - INT32 ret = OsMemPoolExpand(pool, allocSize, intSave); + INT32 ret = OsMemPoolExpand(pool, allocSize, intSave);//扩展内存池 if (ret == 0) { - goto retry; + goto retry;//再来一遍 } } #endif @@ -1047,22 +1070,22 @@ retry: return NULL; } - if ((allocSize + OS_MEM_NODE_HEAD_SIZE + OS_MEM_MIN_ALLOC_SIZE) <= allocNode->sizeAndFlag) { - OsMemSplitNode(pool, allocNode, allocSize); + if ((allocSize + OS_MEM_NODE_HEAD_SIZE + OS_MEM_MIN_ALLOC_SIZE) <= allocNode->sizeAndFlag) {//所需小于内存池可供分配量 + OsMemSplitNode(pool, allocNode, allocSize);//劈开内存池 } - OS_MEM_NODE_SET_USED_FLAG(allocNode->sizeAndFlag); - OsMemWaterUsedRecord(pool, OS_MEM_NODE_GET_SIZE(allocNode->sizeAndFlag)); + OS_MEM_NODE_SET_USED_FLAG(allocNode->sizeAndFlag);//给节点贴上已使用的标签 + OsMemWaterUsedRecord(pool, OS_MEM_NODE_GET_SIZE(allocNode->sizeAndFlag));//更新吃水线 -#ifdef LOSCFG_MEM_LEAKCHECK +#ifdef LOSCFG_MEM_LEAKCHECK //检测内存泄漏开关 OsMemLinkRegisterRecord(allocNode); #endif - return OsMemCreateUsedNode((VOID *)allocNode); + return OsMemCreateUsedNode((VOID *)allocNode);//创建已使用节点 } - +/// 从指定内存池中申请size长度的内存,注意这可不是从内核堆空间中申请内存 VOID *LOS_MemAlloc(VOID *pool, UINT32 size) { - if ((pool == NULL) || (size == 0)) { + if ((pool == NULL) || (size == 0)) {//没提供内存池时 return (size > 0) ? OsVmBootMemAlloc(size) : NULL; } @@ -1079,14 +1102,14 @@ VOID *LOS_MemAlloc(VOID *pool, UINT32 size) break; } MEM_LOCK(poolHead, intSave); - ptr = OsMemAlloc(poolHead, size, intSave); + ptr = OsMemAlloc(poolHead, size, intSave);//真正的分配内存函数,详细查看 鸿蒙内核源码分析(内存池篇) MEM_UNLOCK(poolHead, intSave); } while (0); - OsHookCall(LOS_HOOK_TYPE_MEM_ALLOC, pool, ptr, size); + OsHookCall(LOS_HOOK_TYPE_MEM_ALLOC, pool, ptr, size);//打印日志,到此一游 return ptr; } - +/// 从指定内存池中申请size长度的内存且地址按boundary字节对齐的内存 VOID *LOS_MemAllocAlign(VOID *pool, UINT32 size, UINT32 boundary) { UINT32 gapSize; @@ -1143,10 +1166,10 @@ VOID *LOS_MemAllocAlign(VOID *pool, UINT32 size, UINT32 boundary) ptr = alignedPtr; } while (0); - OsHookCall(LOS_HOOK_TYPE_MEM_ALLOCALIGN, pool, ptr, size, boundary); + OsHookCall(LOS_HOOK_TYPE_MEM_ALLOCALIGN, pool, ptr, size, boundary);//打印对齐日志,表示程序曾临幸过此处 return ptr; } - +/// 内存池有效性检查 STATIC INLINE BOOL OsMemAddrValidCheck(const struct OsMemPoolHead *pool, const VOID *addr) { UINT32 size; @@ -1160,7 +1183,7 @@ STATIC INLINE BOOL OsMemAddrValidCheck(const struct OsMemPoolHead *pool, const V if (OS_MEM_MIDDLE_ADDR_OPEN_END(pool + 1, addr, (UINTPTR)pool + size)) { return TRUE; } -#if OS_MEM_EXPAND_ENABLE +#if OS_MEM_EXPAND_ENABLE //如果支持可扩展 struct OsMemNodeHead *node = NULL; struct OsMemNodeHead *sentinel = OS_MEM_END_NODE(pool, size); while (OsMemIsLastSentinelNode(sentinel) == FALSE) { @@ -1250,7 +1273,7 @@ STATIC UINT32 OsMemCheckUsedNode(const struct OsMemPoolHead *pool, const struct return LOS_OK; } - +/// 释放内存 STATIC INLINE UINT32 OsMemFree(struct OsMemPoolHead *pool, struct OsMemNodeHead *node) { UINT32 ret = OsMemCheckUsedNode(pool, node); @@ -1260,10 +1283,10 @@ STATIC INLINE UINT32 OsMemFree(struct OsMemPoolHead *pool, struct OsMemNodeHead } #ifdef LOSCFG_MEM_WATERLINE - pool->info.curUsedSize -= OS_MEM_NODE_GET_SIZE(node->sizeAndFlag); + pool->info.curUsedSize -= OS_MEM_NODE_GET_SIZE(node->sizeAndFlag);//降低水位线 #endif - node->sizeAndFlag = OS_MEM_NODE_GET_SIZE(node->sizeAndFlag); + node->sizeAndFlag = OS_MEM_NODE_GET_SIZE(node->sizeAndFlag);//获取大小和标记 #ifdef LOSCFG_MEM_LEAKCHECK OsMemLinkRegisterRecord(node); #endif @@ -1274,17 +1297,17 @@ STATIC INLINE UINT32 OsMemFree(struct OsMemPoolHead *pool, struct OsMemNodeHead g_lms->check((UINTPTR)node + OS_MEM_NODE_HEAD_SIZE, TRUE); } #endif - struct OsMemNodeHead *preNode = node->ptr.prev; /* merage preNode */ + struct OsMemNodeHead *preNode = node->ptr.prev; /* merage preNode | 合并前一个节点*/ if ((preNode != NULL) && !OS_MEM_NODE_GET_USED_FLAG(preNode->sizeAndFlag)) { - OsMemFreeNodeDelete(pool, (struct OsMemFreeNodeHead *)preNode); - OsMemMergeNode(node); + OsMemFreeNodeDelete(pool, (struct OsMemFreeNodeHead *)preNode);//删除前节点的信息 + OsMemMergeNode(node);//向前合并 node = preNode; } - struct OsMemNodeHead *nextNode = OS_MEM_NEXT_NODE(node); /* merage nextNode */ + struct OsMemNodeHead *nextNode = OS_MEM_NEXT_NODE(node); /* merage nextNode | 计算后一个节点位置*/ if ((nextNode != NULL) && !OS_MEM_NODE_GET_USED_FLAG(nextNode->sizeAndFlag)) { - OsMemFreeNodeDelete(pool, (struct OsMemFreeNodeHead *)nextNode); - OsMemMergeNode(nextNode); + OsMemFreeNodeDelete(pool, (struct OsMemFreeNodeHead *)nextNode);//删除后节点信息 + OsMemMergeNode(nextNode);//合并节点 } #if OS_MEM_EXPAND_ENABLE @@ -1305,7 +1328,7 @@ STATIC INLINE UINT32 OsMemFree(struct OsMemPoolHead *pool, struct OsMemNodeHead #endif return ret; } - +/// 释放从指定动态内存中申请的内存 UINT32 LOS_MemFree(VOID *pool, VOID *ptr) { UINT32 intSave; @@ -1321,13 +1344,13 @@ UINT32 LOS_MemFree(VOID *pool, VOID *ptr) struct OsMemNodeHead *node = NULL; do { - UINT32 gapSize = *(UINT32 *)((UINTPTR)ptr - sizeof(UINT32)); + UINT32 gapSize = *(UINT32 *)((UINTPTR)ptr - sizeof(UINT32));//获取节点大小和标签 即: sizeAndFlag if (OS_MEM_NODE_GET_ALIGNED_FLAG(gapSize) && OS_MEM_NODE_GET_USED_FLAG(gapSize)) { PRINT_ERR("[%s:%d]gapSize:0x%x error\n", __FUNCTION__, __LINE__, gapSize); break; } - node = (struct OsMemNodeHead *)((UINTPTR)ptr - OS_MEM_NODE_HEAD_SIZE); + node = (struct OsMemNodeHead *)((UINTPTR)ptr - OS_MEM_NODE_HEAD_SIZE);//定位到节点开始位置 if (OS_MEM_NODE_GET_ALIGNED_FLAG(gapSize)) { gapSize = OS_MEM_NODE_GET_ALIGNED_GAPSIZE(gapSize); @@ -1415,7 +1438,7 @@ STATIC INLINE VOID *OsGetRealPtr(const VOID *pool, VOID *ptr) } STATIC INLINE VOID *OsMemRealloc(struct OsMemPoolHead *pool, const VOID *ptr, - struct OsMemNodeHead *node, UINT32 size, UINT32 intSave) + struct OsMemNodeHead *node, UINT32 size, UINT32 intSave) { struct OsMemNodeHead *nextNode = NULL; UINT32 allocSize = OS_MEM_ALIGN(size + OS_MEM_NODE_HEAD_SIZE, OS_MEM_ALIGN_SIZE); @@ -1446,7 +1469,7 @@ STATIC INLINE VOID *OsMemRealloc(struct OsMemPoolHead *pool, const VOID *ptr, } return tmpPtr; } - +/// 按size大小重新分配内存块,并将原内存块内容拷贝到新内存块。如果新内存块申请成功,则释放原内存块 VOID *LOS_MemRealloc(VOID *pool, VOID *ptr, UINT32 size) { if ((pool == NULL) || OS_MEM_NODE_GET_USED_FLAG(size) || OS_MEM_NODE_GET_ALIGNED_FLAG(size)) { @@ -1539,7 +1562,7 @@ UINT32 LOS_MemFreeByTaskID(VOID *pool, UINT32 taskID) return LOS_OK; } #endif - +/// 获取指定动态内存池的总大小 UINT32 LOS_MemPoolSizeGet(const VOID *pool) { UINT32 count = 0; @@ -1548,23 +1571,23 @@ UINT32 LOS_MemPoolSizeGet(const VOID *pool) return LOS_NOK; } - count += ((struct OsMemPoolHead *)pool)->info.totalSize; + count += ((struct OsMemPoolHead *)pool)->info.totalSize; // 这里的 += 好像没必要吧?, = 就可以了, @note_thinking -#if OS_MEM_EXPAND_ENABLE +#if OS_MEM_EXPAND_ENABLE //支持扩展 UINT32 size; struct OsMemNodeHead *node = NULL; - struct OsMemNodeHead *sentinel = OS_MEM_END_NODE(pool, count); + struct OsMemNodeHead *sentinel = OS_MEM_END_NODE(pool, count);//获取哨兵节点 - while (OsMemIsLastSentinelNode(sentinel) == FALSE) { - size = OS_MEM_NODE_GET_SIZE(sentinel->sizeAndFlag); - node = OsMemSentinelNodeGet(sentinel); - sentinel = OS_MEM_END_NODE(node, size); - count += size; + while (OsMemIsLastSentinelNode(sentinel) == FALSE) {//不是最后一个节点 + size = OS_MEM_NODE_GET_SIZE(sentinel->sizeAndFlag);//数据域大小 + node = OsMemSentinelNodeGet(sentinel);//再获取哨兵节点 + sentinel = OS_MEM_END_NODE(node, size);//获取尾节点 + count += size; //内存池大小变大 } #endif return count; } - +/// 获取指定动态内存池的总使用量大小 UINT32 LOS_MemTotalUsedGet(VOID *pool) { struct OsMemNodeHead *tmpNode = NULL; @@ -1637,7 +1660,7 @@ STATIC UINT32 OsMemAddrValidCheckPrint(const VOID *pool, struct OsMemFreeNodeHea } STATIC UINT32 OsMemIntegrityCheckSub(struct OsMemNodeHead **tmpNode, const VOID *pool, - const struct OsMemNodeHead *endNode) + const struct OsMemNodeHead *endNode) { if (!OS_MEM_MAGIC_VALID(*tmpNode)) { OsMemMagicCheckPrint(tmpNode); @@ -1653,7 +1676,7 @@ STATIC UINT32 OsMemIntegrityCheckSub(struct OsMemNodeHead **tmpNode, const VOID } STATIC UINT32 OsMemFreeListNodeCheck(const struct OsMemPoolHead *pool, - const struct OsMemFreeNodeHead *node) + const struct OsMemFreeNodeHead *node) { if (!OsMemAddrValidCheck(pool, node) || !OsMemAddrValidCheck(pool, node->prev) || @@ -1714,9 +1737,9 @@ OUT: #endif } } - +//对指定内存池做完整性检查, STATIC UINT32 OsMemIntegrityCheck(const struct OsMemPoolHead *pool, struct OsMemNodeHead **tmpNode, - struct OsMemNodeHead **preNode) + struct OsMemNodeHead **preNode) { struct OsMemNodeHead *endNode = OS_MEM_END_NODE(pool, pool->info.totalSize); @@ -1839,7 +1862,7 @@ STATIC INLINE UINT32 OsMemAllocCheck(struct OsMemPoolHead *pool, UINT32 intSave) return LOS_OK; } #endif - +/// 对指定内存池做完整性检查 UINT32 LOS_MemIntegrityCheck(const VOID *pool) { if (pool == NULL) { @@ -1864,7 +1887,7 @@ ERROR_OUT: } STATIC INLINE VOID OsMemInfoGet(struct OsMemPoolHead *poolInfo, struct OsMemNodeHead *node, - LOS_MEM_POOL_STATUS *poolStatus) + LOS_MEM_POOL_STATUS *poolStatus) { UINT32 totalUsedSize = 0; UINT32 totalFreeSize = 0; @@ -1893,8 +1916,17 @@ STATIC INLINE VOID OsMemInfoGet(struct OsMemPoolHead *poolInfo, struct OsMemNode poolStatus->freeNodeNum += freeNodeNum; } +/*! + * @brief LOS_MemInfoGet + * 获取指定内存池的内存结构信息,包括空闲内存大小、已使用内存大小、空闲内存块数量、已使用的内存块数量、最大的空闲内存块大小 + * @param pool + * @param poolStatus + * @return + * + * @see + */ UINT32 LOS_MemInfoGet(VOID *pool, LOS_MEM_POOL_STATUS *poolStatus) -{ +{//内存碎片率计算:同样调用LOS_MemInfoGet接口,可以获取内存池的剩余内存大小和最大空闲内存块大小,然后根据公式(fragment=100-最大空闲内存块大小/剩余内存大小)得出此时的动态内存池碎片率。 struct OsMemPoolHead *poolInfo = pool; if (poolStatus == NULL) { @@ -1975,7 +2007,7 @@ STATIC VOID OsMemInfoPrint(VOID *pool) status.freeNodeNum); #endif } - +/// 打印指定内存池的空闲内存块的大小及数量 UINT32 LOS_MemFreeNodeShow(VOID *pool) { struct OsMemPoolHead *poolInfo = (struct OsMemPoolHead *)pool; @@ -2022,7 +2054,7 @@ UINT32 LOS_MemFreeNodeShow(VOID *pool) return LOS_OK; } - +///内核空间动态内存(堆内存)初始化 , 争取系统动态内存池 STATUS_T OsKHeapInit(size_t size) { STATUS_T ret; @@ -2041,38 +2073,38 @@ STATUS_T OsKHeapInit(size_t size) return -1; } - m_aucSysMem0 = m_aucSysMem1 = ptr; - ret = LOS_MemInit(m_aucSysMem0, size); + m_aucSysMem0 = m_aucSysMem1 = ptr;// 指定内核内存池的位置 + ret = LOS_MemInit(m_aucSysMem0, size); //初始化内存池,供内核分配动态内存 if (ret != LOS_OK) { PRINT_ERR("vmm_kheap_init LOS_MemInit failed!\n"); g_vmBootMemBase -= size; return ret; } #if OS_MEM_EXPAND_ENABLE - LOS_MemExpandEnable(OS_SYS_MEM_ADDR); + LOS_MemExpandEnable(OS_SYS_MEM_ADDR);//支持扩展系统动态内存 #endif return LOS_OK; } - +///< 判断地址是否在堆区 BOOL OsMemIsHeapNode(const VOID *ptr) { - struct OsMemPoolHead *pool = (struct OsMemPoolHead *)m_aucSysMem1; - struct OsMemNodeHead *firstNode = OS_MEM_FIRST_NODE(pool); - struct OsMemNodeHead *endNode = OS_MEM_END_NODE(pool, pool->info.totalSize); + struct OsMemPoolHead *pool = (struct OsMemPoolHead *)m_aucSysMem1;//内核堆区开始地址 + struct OsMemNodeHead *firstNode = OS_MEM_FIRST_NODE(pool);//获取内存池首个节点 + struct OsMemNodeHead *endNode = OS_MEM_END_NODE(pool, pool->info.totalSize);//获取内存池的尾节点 - if (OS_MEM_MIDDLE_ADDR(firstNode, ptr, endNode)) { + if (OS_MEM_MIDDLE_ADDR(firstNode, ptr, endNode)) {//如果在首尾范围内 return TRUE; } -#if OS_MEM_EXPAND_ENABLE - UINT32 intSave; - UINT32 size; - MEM_LOCK(pool, intSave); - while (OsMemIsLastSentinelNode(endNode) == FALSE) { - size = OS_MEM_NODE_GET_SIZE(endNode->sizeAndFlag); - firstNode = OsMemSentinelNodeGet(endNode); - endNode = OS_MEM_END_NODE(firstNode, size); - if (OS_MEM_MIDDLE_ADDR(firstNode, ptr, endNode)) { +#if OS_MEM_EXPAND_ENABLE//内存池经过扩展后,新旧块的虚拟地址是不连续的,所以需要跳块判断 + UINT32 intSave; + UINT32 size;//详细查看百篇博客系列篇之 鸿蒙内核源码分析(内存池篇) + MEM_LOCK(pool, intSave); //获取自旋锁 + while (OsMemIsLastSentinelNode(endNode) == FALSE) { //哨兵节点是内存池结束的标记 + size = OS_MEM_NODE_GET_SIZE(endNode->sizeAndFlag);//获取节点大小 + firstNode = OsMemSentinelNodeGet(endNode);//获取下一块的开始地址 + endNode = OS_MEM_END_NODE(firstNode, size);//获取下一块的尾节点 + if (OS_MEM_MIDDLE_ADDR(firstNode, ptr, endNode)) {//判断地址是否在该块中 MEM_UNLOCK(pool, intSave); return TRUE; } @@ -2081,3 +2113,5 @@ BOOL OsMemIsHeapNode(const VOID *ptr) #endif return FALSE; } + + From f59cf2a3a630e6b1397139caba552e77caaaa297 Mon Sep 17 00:00:00 2001 From: dancer <2905764690@qq.com> Date: Fri, 19 Jan 2024 09:48:07 +0800 Subject: [PATCH 19/33] core --- .../kernel/base/core/los_process.c | 641 +++++++++--------- .../kernel/base/core/los_swtmr.c | 156 ++--- .../kernel/base/core/los_task.c | 413 ++++++----- .../kernel/base/core/los_tick.c | 14 +- 4 files changed, 641 insertions(+), 583 deletions(-) diff --git a/src/kernel_liteos_a/kernel/base/core/los_process.c b/src/kernel_liteos_a/kernel/base/core/los_process.c index 2ab53116..40fed7dd 100644 --- a/src/kernel_liteos_a/kernel/base/core/los_process.c +++ b/src/kernel_liteos_a/kernel/base/core/los_process.c @@ -1,3 +1,12 @@ +/* +进程模块主文件 + 并发(Concurrent):多个线程在单个核心运行,同一时间只能一个线程运行,内核不停切换线程, + 看起来像同时运行,实际上是线程不停切换 + 并行(Parallel)每个线程分配给独立的CPU核心,线程同时运行 + 单核CPU多个进程或多个线程内能实现并发(微观上的串行,宏观上的并行) + 多核CPU线程间可以实现宏观和微观上的并行 + LITE_OS_SEC_BSS 和 LITE_OS_SEC_DATA_INIT 是告诉编译器这些全局变量放在哪个数据段 + */ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. @@ -59,46 +68,28 @@ #include "los_vm_phys.h" #include "los_vm_syscall.h" -/* - @brief 进程模块主文件 - - 并发(Concurrent):多个线程在单个核心运行,同一时间只能一个线程运行,内核不停切换线程,看起来像同时运行,实际上是线程不停切换 - 并行(Parallel)每个线程分配给独立的CPU核心,线程同时运行 - 单核CPU多个进程或多个线程内能实现并发(微观上的串行,宏观上的并行) - 多核CPU线程间可以实现宏观和微观上的并行 - LITE_OS_SEC_BSS 和 LITE_OS_SEC_DATA_INIT 是告诉编译器这些全局变量放在哪个数据段 -*/ - -/* - bss 是英文 Block by Symbol 的简称。 - 通常用来存放程序中未初始化和初始化为 - 0的全局变量的一块内存区域,在程序载入时由内核清零。 -*/ - -LITE_OS_SEC_BSS LosProcessCB *g_processCBArray = NULL; //进程池数组 -LITE_OS_SEC_DATA_INIT STATIC LOS_DL_LIST g_freeProcess; //空闲状态下的进程链表 -LITE_OS_SEC_DATA_INIT STATIC LOS_DL_LIST g_processRecycleList; //需要回收的进程列表 -LITE_OS_SEC_BSS UINT32 g_processMaxNum; //进程最大数量,默认64个 +LITE_OS_SEC_BSS LosProcessCB *g_processCBArray = NULL;//进程池数组 +LITE_OS_SEC_DATA_INIT STATIC LOS_DL_LIST g_freeProcess;//空闲状态下的进程链表, +LITE_OS_SEC_DATA_INIT STATIC LOS_DL_LIST g_processRecycleList;//需要收回的进程列表 +LITE_OS_SEC_BSS UINT32 g_processMaxNum;//进程最大数量,默认64个 #ifndef LOSCFG_PID_CONTAINER -LITE_OS_SEC_BSS ProcessGroup *g_processGroup = NULL; //全局进程组,负责管理所有进程组 +LITE_OS_SEC_BSS ProcessGroup *g_processGroup = NULL;//全局进程组,负责管理所有的进程组 #define OS_ROOT_PGRP(processCB) (g_processGroup) #endif -// 将进程插入到空闲列表当中 STATIC INLINE VOID OsInsertPCBToFreeList(LosProcessCB *processCB) { #ifdef LOSCFG_PID_CONTAINER OsPidContainerDestroy(processCB->container, processCB); #endif - UINT32 pid = processCB->processID; // 获取进程ID - (VOID)memset_s(processCB, sizeof(LosProcessCB), 0, sizeof(LosProcessCB)); // 进程描述符数据清0 - processCB->processID = pid; - processCB->processStatus = OS_PROCESS_FLAG_UNUSED; // 设置状态为未使用 - processCB->timerID = (timer_t)(UINTPTR)MAX_INVALID_TIMER_VID; - LOS_ListTailInsert(&g_freeProcess, &processCB->pendList); // 将进程插入到空闲列表当中 + UINT32 pid = processCB->processID;//获取进程ID + (VOID)memset_s(processCB, sizeof(LosProcessCB), 0, sizeof(LosProcessCB));//进程描述符数据清0 + processCB->processID = pid;//进程ID + processCB->processStatus = OS_PROCESS_FLAG_UNUSED;//设置为进程未使用 + processCB->timerID = (timer_t)(UINTPTR)MAX_INVALID_TIMER_VID;//timeID初始化值 + LOS_ListTailInsert(&g_freeProcess, &processCB->pendList);//进程节点挂入g_freeProcess以分配给后续进程使用 } -// 从进程当中删除任务 VOID OsDeleteTaskFromProcess(LosTaskCB *taskCB) { LosProcessCB *processCB = OS_PCB_FROM_TCB(taskCB); @@ -108,7 +99,6 @@ VOID OsDeleteTaskFromProcess(LosTaskCB *taskCB) OsTaskInsertToRecycleList(taskCB); } -// 进程当中添加任务 UINT32 OsProcessAddNewTask(UINTPTR processID, LosTaskCB *taskCB, SchedParam *param, UINT32 *numCount) { UINT32 intSave; @@ -151,8 +141,6 @@ UINT32 OsProcessAddNewTask(UINTPTR processID, LosTaskCB *taskCB, SchedParam *par SCHEDULER_UNLOCK(intSave); return LOS_OK; } - -// 创建进程组 /** * @brief 创建进程组 * @details @@ -163,18 +151,18 @@ UINT32 OsProcessAddNewTask(UINTPTR processID, LosTaskCB *taskCB, SchedParam *par */ ProcessGroup *OsCreateProcessGroup(LosProcessCB *processCB) { - ProcessGroup *pgroup = LOS_MemAlloc(m_aucSysMem1, sizeof(ProcessGroup)); + ProcessGroup *pgroup = LOS_MemAlloc(m_aucSysMem1, sizeof(ProcessGroup));//分配一个进程组 if (pgroup == NULL) { return NULL; } - pgroup->pgroupLeader = (UINTPTR)processCB; - LOS_ListInit(&pgroup->processList); - LOS_ListInit(&pgroup->exitProcessList); + pgroup->pgroupLeader = (UINTPTR)processCB;//指定进程负责人 + LOS_ListInit(&pgroup->processList);//初始化组员链表 + LOS_ListInit(&pgroup->exitProcessList);//初始化僵死进程链表 LOS_ListTailInsert(&pgroup->processList, &processCB->subordinateGroupList); processCB->pgroup = pgroup; - processCB->processStatus |= OS_PROCESS_FLAG_GROUP_LEADER; + processCB->processStatus |= OS_PROCESS_FLAG_GROUP_LEADER;//进程状态贴上当老大的标签 ProcessGroup *rootPGroup = OS_ROOT_PGRP(processCB); if (rootPGroup == NULL) { @@ -185,13 +173,12 @@ ProcessGroup *OsCreateProcessGroup(LosProcessCB *processCB) } return pgroup; } - -/*! 退出进程组,参数是进程地址和进程组地址的地址 */ +//退出进程组,参数是进程地址和进程组地址的地址 STATIC VOID ExitProcessGroup(LosProcessCB *processCB, ProcessGroup **pgroup) { LosProcessCB *pgroupCB = OS_GET_PGROUP_LEADER(processCB->pgroup); LOS_ListDelete(&processCB->subordinateGroupList);//从进程组进程链表上摘出去 - if (LOS_ListEmpty(&processCB->pgroup->processList) && LOS_ListEmpty(&processCB->pgroup->exitProcessList)) {//进程组进程链表和退出进程链表都为空时 + if (LOS_ListEmpty(&processCB->pgroup->processList) && LOS_ListEmpty(&processCB->pgroup->exitProcessList)) { #ifdef LOSCFG_PID_CONTAINER if (processCB->pgroup != OS_ROOT_PGRP(processCB)) { #endif @@ -201,16 +188,15 @@ STATIC VOID ExitProcessGroup(LosProcessCB *processCB, ProcessGroup **pgroup) } #endif pgroupCB->processStatus &= ~OS_PROCESS_FLAG_GROUP_LEADER; - if (OsProcessIsUnused(pgroupCB) && !(pgroupCB->processStatus & OS_PROCESS_FLAG_EXIT)) { - LOS_ListDelete(&pgroupCB->pendList); //进程从全局进程链表上摘除 - OsInsertPCBToFreeList(pgroupCB); //释放进程的资源,回到freelist再利用 + if (OsProcessIsUnused(pgroupCB) && !(pgroupCB->processStatus & OS_PROCESS_FLAG_EXIT)) {//组长进程时退出的标签 + LOS_ListDelete(&pgroupCB->pendList);//进程从全局进程链表上摘除 + OsInsertPCBToFreeList(pgroupCB);//释放进程的资源,回到freelist再利用 } } processCB->pgroup = NULL; } - -// 根据gid 寻找进程组 +/*! 通过指定组ID找到进程组 */ STATIC ProcessGroup *OsFindProcessGroup(UINT32 gid) { ProcessGroup *pgroup = NULL; @@ -230,8 +216,7 @@ STATIC ProcessGroup *OsFindProcessGroup(UINT32 gid) PRINT_INFO("%s failed! pgroup id = %u\n", __FUNCTION__, gid); return NULL; } - -// 发送信号去查清楚进程组状态 +/*! 给指定进程组发送信号 */ STATIC INT32 OsSendSignalToSpecifyProcessGroup(ProcessGroup *pgroup, siginfo_t *info, INT32 permission) { INT32 ret, success, err; @@ -252,7 +237,6 @@ STATIC INT32 OsSendSignalToSpecifyProcessGroup(ProcessGroup *pgroup, siginfo_t * return success ? LOS_OK : ret; } -// 向所有的进程发送信号 LITE_OS_SEC_TEXT INT32 OsSendSignalToAllProcess(siginfo_t *info, INT32 permission) { INT32 ret, success, err; @@ -273,7 +257,6 @@ LITE_OS_SEC_TEXT INT32 OsSendSignalToAllProcess(siginfo_t *info, INT32 permissio return success ? LOS_OK : ret; } -// 向进程组发送信号 LITE_OS_SEC_TEXT INT32 OsSendSignalToProcessGroup(INT32 pid, siginfo_t *info, INT32 permission) { ProcessGroup *pgroup = NULL; @@ -288,7 +271,6 @@ LITE_OS_SEC_TEXT INT32 OsSendSignalToProcessGroup(INT32 pid, siginfo_t *info, IN return OsSendSignalToSpecifyProcessGroup(pgroup, info, permission); } -// 查找推出的进程 STATIC LosProcessCB *OsFindGroupExitProcess(ProcessGroup *pgroup, INT32 pid) { LosProcessCB *childCB = NULL; @@ -302,7 +284,6 @@ STATIC LosProcessCB *OsFindGroupExitProcess(ProcessGroup *pgroup, INT32 pid) return NULL; } -// 找到子进程 STATIC UINT32 OsFindChildProcess(const LosProcessCB *processCB, const LosProcessCB *wait) { LosProcessCB *childCB = NULL; @@ -328,23 +309,16 @@ STATIC LosProcessCB *OsFindExitChildProcess(const LosProcessCB *processCB, const return NULL; } -/// @brief 唤醒等待wakepid结束的task -/// @param taskCB -/// @param wakePID -/// @return +/*! 唤醒等待wakePID结束的任务 */ VOID OsWaitWakeTask(LosTaskCB *taskCB, UINTPTR wakePID) { - taskCB->waitID = wakePID; // waitID 置为唤醒 - taskCB->ops->wake(taskCB); // 唤醒taskCB + taskCB->waitID = wakePID; + taskCB->ops->wake(taskCB); #ifdef LOSCFG_KERNEL_SMP - LOS_MpSchedule(OS_MP_CPU_ALL); + LOS_MpSchedule(OS_MP_CPU_ALL);//向所有cpu发送调度指令 #endif } -/// @brief 唤醒等待参数进程结束的任务 -/// @param head -/// @param processCB -/// @param anyList -/// @return +/*! 唤醒等待参数进程结束的任务 */ STATIC BOOL OsWaitWakeSpecifiedProcess(LOS_DL_LIST *head, const LosProcessCB *processCB, LOS_DL_LIST **anyList) { LOS_DL_LIST *list = head; @@ -352,12 +326,12 @@ STATIC BOOL OsWaitWakeSpecifiedProcess(LOS_DL_LIST *head, const LosProcessCB *pr UINTPTR processID = 0; BOOL find = FALSE; - while (list->pstNext != head) { // 遍历 process->waitlist - taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(list)); + while (list->pstNext != head) {//遍历等待链表 processCB->waitList + taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(list));//一个一个来 if ((taskCB->waitFlag == OS_PROCESS_WAIT_PRO) && (taskCB->waitID == (UINTPTR)processCB)) { if (processID == 0) { processID = taskCB->waitID; - find = TRUE; + find = TRUE;//找到了 } else { processID = OS_INVALID_VALUE; } @@ -375,11 +349,7 @@ STATIC BOOL OsWaitWakeSpecifiedProcess(LOS_DL_LIST *head, const LosProcessCB *pr return find; } - -/// @brief 检查父进程的等待任务并唤醒父进程去处理任务 -/// @param parentCB -/// @param processCB -/// @return +/*! 检查父进程的等待任务并唤醒父进程去处理等待任务 */ STATIC VOID OsWaitCheckAndWakeParentProcess(LosProcessCB *parentCB, const LosProcessCB *processCB) { LOS_DL_LIST *head = &parentCB->waitList; @@ -387,7 +357,7 @@ STATIC VOID OsWaitCheckAndWakeParentProcess(LosProcessCB *parentCB, const LosPro LosTaskCB *taskCB = NULL; BOOL findSpecified = FALSE; - if (LOS_ListEmpty(&parentCB->waitList)) { // 父进程当中是否有在等待子进程退出的任务 + if (LOS_ListEmpty(&parentCB->waitList)) {//父进程中是否有在等待子进程退出的任务? return;//没有就退出 } @@ -395,11 +365,11 @@ STATIC VOID OsWaitCheckAndWakeParentProcess(LosProcessCB *parentCB, const LosPro if (findSpecified == TRUE) { /* No thread is waiting for any child process to finish */ if (LOS_ListEmpty(&parentCB->waitList)) {//没有线程正在等待任何子进程结束 - return; + return;//已经处理完了,注意在OsWaitWakeSpecifiedProcess中做了频繁的任务切换 } else if (!LOS_ListEmpty(&parentCB->childrenList)) { /* Other child processes exist, and other threads that are waiting * for the child to finish continue to wait - *////存在其他子进程,正在等待它们的子进程结束而将继续等待 + *///存在其他子进程,正在等待它们的子进程结束而将继续等待 return; } } @@ -441,9 +411,7 @@ STATIC VOID OsWaitCheckAndWakeParentProcess(LosProcessCB *parentCB, const LosPro return; } -/// @brief 回收指定进程的资源 -/// @param processCB -/// @return +/*! 回收指定进程的资源 */ LITE_OS_SEC_TEXT VOID OsProcessResourcesToFree(LosProcessCB *processCB) { #ifdef LOSCFG_KERNEL_VM @@ -452,10 +420,10 @@ LITE_OS_SEC_TEXT VOID OsProcessResourcesToFree(LosProcessCB *processCB) } #endif -#ifdef LOSCFG_SECURITY_CAPABILITY // 安全开关 +#ifdef LOSCFG_SECURITY_CAPABILITY//安全开关 if (processCB->user != NULL) { - (VOID)LOS_MemFree(m_aucSysMem1, processCB->user);// 删除用户 - processCB->user = NULL; // 重置指针为空 + (VOID)LOS_MemFree(m_aucSysMem1, processCB->user);//删除用户 + processCB->user = NULL;//重置指针为空 } #endif @@ -512,18 +480,14 @@ LITE_OS_SEC_TEXT VOID OsProcessResourcesToFree(LosProcessCB *processCB) processCB->resourceLimit = NULL; } } - -/// @brief 回收僵死状态的资源 -/// @param childCB -/// @param pgroup -/// @return +/*! 回收僵死状态进程的资源 */ STATIC VOID OsRecycleZombiesProcess(LosProcessCB *childCB, ProcessGroup **pgroup) { - ExitProcessGroup(childCB, pgroup); // 推出进程组 - LOS_ListDelete(&childCB->siblingList); ////从子孙链表上摘除 + ExitProcessGroup(childCB, pgroup);//退出进程组 + LOS_ListDelete(&childCB->siblingList);//从父亲大人的子孙链表上摘除 if (OsProcessIsDead(childCB)) { - OsDeleteTaskFromProcess(childCB->threadGroup);//去掉僵死标签 - childCB->processStatus &= ~OS_PROCESS_STATUS_ZOMBIES; + OsDeleteTaskFromProcess(childCB->threadGroup); + childCB->processStatus &= ~OS_PROCESS_STATUS_ZOMBIES;//去掉僵死标签 childCB->processStatus |= OS_PROCESS_FLAG_UNUSED;//贴上没使用标签,进程由进程池分配,进程退出后重新回到空闲进程池 } @@ -533,13 +497,10 @@ STATIC VOID OsRecycleZombiesProcess(LosProcessCB *childCB, ProcessGroup **pgroup } else if (OsProcessIsPGroupLeader(childCB)) { LOS_ListTailInsert(&g_processRecycleList, &childCB->pendList);//从尾部插入,意思就是组长尽量最后一个处理 } else { - OsInsertPCBToFreeList(childCB);//直接插到freeList中去,可用于重新分配了。 + OsInsertPCBToFreeList(childCB);//直接插到freeList中去,可用于重新分配了 } } - -/// @brief 进程退出时子进程由其父进程处理 -/// @param processCB -/// @return +/*! 当一个进程自然退出的时候,它的孩子进程由两位老祖宗收养 */ STATIC VOID OsDealAliveChildProcess(LosProcessCB *processCB) { LosProcessCB *childCB = NULL; @@ -553,33 +514,30 @@ STATIC VOID OsDealAliveChildProcess(LosProcessCB *processCB) } #endif - if (!LOS_ListEmpty(&processCB->childrenList)) { - childHead = processCB->childrenList.pstNext; - LOS_ListDelete(&(processCB->childrenList)); - if (OsProcessIsUserMode(processCB)) { + if (!LOS_ListEmpty(&processCB->childrenList)) {//如果存在孩子进程 + childHead = processCB->childrenList.pstNext;//获取孩子链表 + LOS_ListDelete(&(processCB->childrenList));//清空自己的孩子链表 + if (OsProcessIsUserMode(processCB)) {//是用户态进程 parentCB = OS_PCB_FROM_PID(OS_USER_ROOT_PROCESS_ID); } else { parentCB = OsGetKernelInitProcess(); } - for (nextList = childHead; ;) { - childCB = OS_PCB_FROM_SIBLIST(nextList); + for (nextList = childHead; ;) {//遍历孩子链表 + childCB = OS_PCB_FROM_SIBLIST(nextList);//找到孩子的真身 childCB->parentProcess = parentCB; - nextList = nextList->pstNext; - if (nextList == childHead) { + nextList = nextList->pstNext;//找下一个孩子进程 + if (nextList == childHead) {//一圈下来,孩子们都磕完头了 break; } } - LOS_ListTailInsertList(&parentCB->childrenList, childHead); + LOS_ListTailInsertList(&parentCB->childrenList, childHead);//挂到老祖宗的孩子链表上 } return; } - -/// @brief 回收指定进程的已经退出(死亡)的子进程所占资源 -/// @param processCB -/// @return +/*! 回收指定进程的已经退出(死亡)的孩子进程所占资源 */ STATIC VOID OsChildProcessResourcesFree(const LosProcessCB *processCB) { LosProcessCB *childCB = NULL; @@ -591,34 +549,32 @@ STATIC VOID OsChildProcessResourcesFree(const LosProcessCB *processCB) (VOID)LOS_MemFree(m_aucSysMem1, pgroup); } } -/// @brief 一个进程的自然消亡过程,参数是当前运行的任务 -/// @param processCB -/// @param status -/// @return +/*! 一个进程的自然消亡过程,参数是当前运行的任务*/ VOID OsProcessNaturalExit(LosProcessCB *processCB, UINT32 status) { - OsChildProcessResourcesFree(processCB); + OsChildProcessResourcesFree(processCB);//释放孩子进程的资源 /* is a child process */ if (processCB->parentProcess != NULL) { LosProcessCB *parentCB = processCB->parentProcess; - LOS_ListDelete(&processCB->siblingList); - if (!OsProcessExitCodeSignalIsSet(processCB)) { - OsProcessExitCodeSet(processCB, status); + LOS_ListDelete(&processCB->siblingList);//将自己从兄弟链表中摘除,家人们,永别了! + if (!OsProcessExitCodeSignalIsSet(processCB)) {//是否设置了退出码? + OsProcessExitCodeSet(processCB, status);//将进程状态设为退出码 } - LOS_ListTailInsert(&parentCB->exitChildList, &processCB->siblingList); - LOS_ListDelete(&processCB->subordinateGroupList); - LOS_ListTailInsert(&processCB->pgroup->exitProcessList, &processCB->subordinateGroupList); + LOS_ListTailInsert(&parentCB->exitChildList, &processCB->siblingList);//挂到父进程的孩子消亡链表,家人中,永别的可不止我一个. + LOS_ListDelete(&processCB->subordinateGroupList);//和志同道合的朋友们永别了,注意家里可不一定是朋友的,所有各有链表. + LOS_ListTailInsert(&processCB->pgroup->exitProcessList, &processCB->subordinateGroupList);//挂到进程组消亡链表,朋友中,永别的可不止我一个. + + OsWaitCheckAndWakeParentProcess(parentCB, processCB);//检查父进程的等待任务链表并唤醒对应的任务,此处将会频繁的切到其他任务运行. - OsWaitCheckAndWakeParentProcess(parentCB, processCB); + OsDealAliveChildProcess(processCB);//孩子们要怎么处理,移交给(用户态和内核态)根进程 - OsDealAliveChildProcess(processCB); - processCB->processStatus |= OS_PROCESS_STATUS_ZOMBIES; + processCB->processStatus |= OS_PROCESS_STATUS_ZOMBIES;//贴上僵死进程的标签 #ifdef LOSCFG_KERNEL_VM (VOID)OsSendSigToProcess(parentCB, SIGCHLD, OS_KERNEL_KILL_PERMISSION); #endif - LOS_ListHeadInsert(&g_processRecycleList, &processCB->pendList); + LOS_ListHeadInsert(&g_processRecycleList, &processCB->pendList);//将进程通过其阻塞节点挂入全局进程回收链表 return; } @@ -632,36 +588,33 @@ STATIC VOID SystemProcessEarlyInit(LosProcessCB *processCB) #ifdef LOSCFG_KERNEL_CONTAINER OsContainerInitSystemProcess(processCB); #endif - if (processCB == OsGetKernelInitProcess()) { - OsSetMainTaskProcess((UINTPTR)processCB); + if (processCB == OsGetKernelInitProcess()) {//2号进程 + OsSetMainTaskProcess((UINTPTR)processCB);//将内核根进程设为主任务所属进程 } } - -/// @brief 进程模块初始化,被编译放在代码段 .init -/// @param -/// @return +/*! 进程模块初始化,被编译放在代码段 .init 中*/ UINT32 OsProcessInit(VOID) { UINT32 index; UINT32 size; UINT32 ret; - g_processMaxNum = LOSCFG_BASE_CORE_PROCESS_LIMIT; + g_processMaxNum = LOSCFG_BASE_CORE_PROCESS_LIMIT;//默认支持64个进程 size = (g_processMaxNum + 1) * sizeof(LosProcessCB); - g_processCBArray = (LosProcessCB *)LOS_MemAlloc(m_aucSysMem1, size); + g_processCBArray = (LosProcessCB *)LOS_MemAlloc(m_aucSysMem1, size);// 进程池,占用内核堆,内存池分配 if (g_processCBArray == NULL) { return LOS_NOK; } - (VOID)memset_s(g_processCBArray, size, 0, size); + (VOID)memset_s(g_processCBArray, size, 0, size);//安全方式重置清0 - LOS_ListInit(&g_freeProcess); - LOS_ListInit(&g_processRecycleList); + LOS_ListInit(&g_freeProcess);//进程空闲链表初始化,创建一个进程时从g_freeProcess中申请一个进程描述符使用 + LOS_ListInit(&g_processRecycleList);//进程回收链表初始化,回收完成后进入g_freeProcess等待再次被申请使用 - for (index = 0; index < g_processMaxNum; index++) { - g_processCBArray[index].processID = index; - g_processCBArray[index].processStatus = OS_PROCESS_FLAG_UNUSED; - LOS_ListTailInsert(&g_freeProcess, &g_processCBArray[index].pendList); + for (index = 0; index < g_processMaxNum; index++) {//进程池循环创建 + g_processCBArray[index].processID = index;//进程ID[0-g_processMaxNum-1]赋值 + g_processCBArray[index].processStatus = OS_PROCESS_FLAG_UNUSED;// 默认都是白纸一张,贴上未使用标签 + LOS_ListTailInsert(&g_freeProcess, &g_processCBArray[index].pendList);//注意g_freeProcess挂的是pendList节点,所以使用要通过OS_PCB_FROM_PENDLIST找到进程实体. } /* Default process to prevent thread PCB from being empty */ @@ -680,23 +633,22 @@ UINT32 OsProcessInit(VOID) #ifdef LOSCFG_KERNEL_PLIMITS OsProcLimiterSetInit(); #endif - SystemProcessEarlyInit(OsGetIdleProcess()); + SystemProcessEarlyInit(OsGetIdleProcess());//初始化 0,1,2号进程 SystemProcessEarlyInit(OsGetUserInitProcess()); SystemProcessEarlyInit(OsGetKernelInitProcess()); return LOS_OK; } -/// @brief 进程回收再利用过程 -/// @param -/// @return +/*! 进程回收再利用过程*/ LITE_OS_SEC_TEXT VOID OsProcessCBRecycleToFree(VOID) { UINT32 intSave; LosProcessCB *processCB = NULL; SCHEDULER_LOCK(intSave); - while (!LOS_ListEmpty(&g_processRecycleList)) { - processCB = OS_PCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_processRecycleList)); - if (!(processCB->processStatus & OS_PROCESS_FLAG_EXIT)) { + while (!LOS_ListEmpty(&g_processRecycleList)) {//循环任务回收链表,直到为空 + processCB = OS_PCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_processRecycleList));//找到回收链表中第一个进程实体 + //OS_PCB_FROM_PENDLIST 代表的是通过pendlist节点找到 PCB实体,因为g_processRecyleList上面挂的是pendlist节点位置 + if (!(processCB->processStatus & OS_PROCESS_FLAG_EXIT)) {//进程没有退出标签 break; } SCHEDULER_UNLOCK(intSave); @@ -704,27 +656,27 @@ LITE_OS_SEC_TEXT VOID OsProcessCBRecycleToFree(VOID) OsTaskCBRecycleToFree(); SCHEDULER_LOCK(intSave); - processCB->processStatus &= ~OS_PROCESS_FLAG_EXIT; + processCB->processStatus &= ~OS_PROCESS_FLAG_EXIT;//给进程撕掉退出标签,(可能进程并没有这个标签) #ifdef LOSCFG_KERNEL_VM LosVmSpace *space = NULL; - if (OsProcessIsUserMode(processCB)) { - space = processCB->vmSpace; + if (OsProcessIsUserMode(processCB)) {//进程是否是用户态进程 + space = processCB->vmSpace;//只有用户态的进程才需要释放虚拟内存空间 } processCB->vmSpace = NULL; #endif /* OS_PROCESS_FLAG_GROUP_LEADER: The lead process group cannot be recycled without destroying the PCB. * !OS_PROCESS_FLAG_UNUSED: Parent process does not reclaim child process resources. */ - LOS_ListDelete(&processCB->pendList); + LOS_ListDelete(&processCB->pendList);//将进程从进程链表上摘除 if (OsProcessIsPGroupLeader(processCB) || OsProcessIsDead(processCB)) { - LOS_ListTailInsert(&g_processRecycleList, &processCB->pendList); + LOS_ListTailInsert(&g_processRecycleList, &processCB->pendList);//将进程挂到进程回收链表上,因为组长不能走啊 } else { /* Clear the bottom 4 bits of process status */ - OsInsertPCBToFreeList(processCB); + OsInsertPCBToFreeList(processCB);//进程回到可分配池中,再分配利用 } #ifdef LOSCFG_KERNEL_VM SCHEDULER_UNLOCK(intSave); - (VOID)LOS_VmSpaceFree(space); + (VOID)LOS_VmSpaceFree(space);//释放用户态进程的虚拟内存空间,因为内核只有一个虚拟空间,因此不需要释放虚拟空间. SCHEDULER_LOCK(intSave); #endif } @@ -747,11 +699,11 @@ STATIC VOID OsDeInitPCB(LosProcessCB *processCB) } #endif - OsProcessResourcesToFree(processCB); + OsProcessResourcesToFree(processCB);//释放进程所占用的资源 SCHEDULER_LOCK(intSave); if (processCB->parentProcess != NULL) { - LOS_ListDelete(&processCB->siblingList); + LOS_ListDelete(&processCB->siblingList);//将进程从兄弟链表中摘除 processCB->parentProcess = NULL; } @@ -759,8 +711,8 @@ STATIC VOID OsDeInitPCB(LosProcessCB *processCB) ExitProcessGroup(processCB, &pgroup); } - processCB->processStatus &= ~OS_PROCESS_STATUS_INIT; - processCB->processStatus |= OS_PROCESS_FLAG_EXIT; + processCB->processStatus &= ~OS_PROCESS_STATUS_INIT;//设置进程状态为非初始化 + processCB->processStatus |= OS_PROCESS_FLAG_EXIT;//设置进程状态为退出 LOS_ListHeadInsert(&g_processRecycleList, &processCB->pendList); SCHEDULER_UNLOCK(intSave); @@ -768,10 +720,8 @@ STATIC VOID OsDeInitPCB(LosProcessCB *processCB) OsWriteResourceEvent(OS_RESOURCE_EVENT_FREE); return; } -/// @brief /*! 设置进程的名字*/ -/// @param processCB -/// @param name -/// @return + +/*! 设置进程的名字*/ UINT32 OsSetProcessName(LosProcessCB *processCB, const CHAR *name) { errno_t errRet; @@ -803,31 +753,32 @@ UINT32 OsSetProcessName(LosProcessCB *processCB, const CHAR *name) } return LOS_OK; } + /*! 初始化PCB(进程控制块)*/ STATIC UINT32 OsInitPCB(LosProcessCB *processCB, UINT32 mode, const CHAR *name) { - processCB->processMode = mode; - processCB->processStatus = OS_PROCESS_STATUS_INIT; + processCB->processMode = mode;//用户态进程还是内核态进程 + processCB->processStatus = OS_PROCESS_STATUS_INIT;//进程初始状态 processCB->parentProcess = NULL; processCB->threadGroup = NULL; - processCB->umask = OS_PROCESS_DEFAULT_UMASK; + processCB->umask = OS_PROCESS_DEFAULT_UMASK;//掩码 processCB->timerID = (timer_t)(UINTPTR)MAX_INVALID_TIMER_VID; - LOS_ListInit(&processCB->threadSiblingList); - LOS_ListInit(&processCB->childrenList); - LOS_ListInit(&processCB->exitChildList); - LOS_ListInit(&(processCB->waitList)); + LOS_ListInit(&processCB->threadSiblingList);//初始化孩子任务/线程链表,上面挂的都是由此fork的孩子线程 见于 OsTaskCBInit LOS_ListTailInsert(&(processCB->threadSiblingList), &(taskCB->threadList)); + LOS_ListInit(&processCB->childrenList);//初始化孩子进程链表,上面挂的都是由此fork的孩子进程 见于 OsCopyParent LOS_ListTailInsert(&parentProcessCB->childrenList, &childProcessCB->siblingList); + LOS_ListInit(&processCB->exitChildList);//初始化记录退出孩子进程链表,上面挂的是哪些exit 见于 OsProcessNaturalExit LOS_ListTailInsert(&parentCB->exitChildList, &processCB->siblingList); + LOS_ListInit(&(processCB->waitList));//初始化等待任务链表 上面挂的是处于等待的 见于 OsWaitInsertWaitLIstInOrder LOS_ListHeadInsert(&processCB->waitList, &runTask->pendList); #ifdef LOSCFG_KERNEL_VM - if (OsProcessIsUserMode(processCB)) { - processCB->vmSpace = OsCreateUserVmSpace(); + if (OsProcessIsUserMode(processCB)) {//如果是用户态进程 + processCB->vmSpace = OsCreateUserVmSpace();//创建用户空间 if (processCB->vmSpace == NULL) { processCB->processStatus = OS_PROCESS_FLAG_UNUSED; return LOS_ENOMEM; } } else { - processCB->vmSpace = LOS_GetKVmSpace(); - } + processCB->vmSpace = LOS_GetKVmSpace();//从这里也可以看出,所有内核态进程是共享一个进程空间的 + }//在鸿蒙内核态进程只有kprocess 和 kidle 两个 #endif #ifdef LOSCFG_KERNEL_CPUP @@ -846,7 +797,7 @@ STATIC UINT32 OsInitPCB(LosProcessCB *processCB, UINT32 mode, const CHAR *name) #endif #ifdef LOSCFG_SECURITY_CAPABILITY - OsInitCapability(processCB); + OsInitCapability(processCB);//初始化进程安全相关功能 #endif if (OsSetProcessName(processCB, name) != LOS_OK) { @@ -855,10 +806,10 @@ STATIC UINT32 OsInitPCB(LosProcessCB *processCB, UINT32 mode, const CHAR *name) return LOS_OK; } - +//创建用户 #ifdef LOSCFG_SECURITY_CAPABILITY -STATIC User *OsCreateUser(UINT32 userID, UINT32 gid, UINT32 size) -{ +STATIC User *OsCreateUser(UINT32 userID, UINT32 gid, UINT32 size)//参数size 表示组数量 +{//(size - 1) * sizeof(UINT32) 用于 user->groups[..],这种设计节约了内存,不造成不需要的浪费 User *user = LOS_MemAlloc(m_aucSysMem1, sizeof(User) + (size - 1) * sizeof(UINT32)); if (user == NULL) { return NULL; @@ -868,11 +819,12 @@ STATIC User *OsCreateUser(UINT32 userID, UINT32 gid, UINT32 size) user->effUserID = userID; user->gid = gid; user->effGid = gid; - user->groupNumber = size; - user->groups[0] = gid; + user->groupNumber = size;//用户组数量 + user->groups[0] = gid;//用户组列表,一个用户可以属于多个用户组 return user; } +/*! 检查参数群组ID是否在当前用户所属群组中*/ LITE_OS_SEC_TEXT BOOL LOS_CheckInGroups(UINT32 gid) { UINT32 intSave; @@ -880,8 +832,8 @@ LITE_OS_SEC_TEXT BOOL LOS_CheckInGroups(UINT32 gid) User *user = NULL; SCHEDULER_LOCK(intSave); - user = OsCurrUserGet(); - for (count = 0; count < user->groupNumber; count++) { + user = OsCurrUserGet();//当前进程所属用户 + for (count = 0; count < user->groupNumber; count++) {//循环对比 if (user->groups[count] == gid) { SCHEDULER_UNLOCK(intSave); return TRUE; @@ -893,6 +845,7 @@ LITE_OS_SEC_TEXT BOOL LOS_CheckInGroups(UINT32 gid) } #endif +/*! 获取当前进程的用户ID*/ LITE_OS_SEC_TEXT INT32 LOS_GetUserID(VOID) { #ifdef LOSCFG_SECURITY_CAPABILITY @@ -912,6 +865,7 @@ LITE_OS_SEC_TEXT INT32 LOS_GetUserID(VOID) #endif } +/*! 获取当前进程的用户组ID*/ LITE_OS_SEC_TEXT INT32 LOS_GetGroupID(VOID) { #ifdef LOSCFG_SECURITY_CAPABILITY @@ -932,6 +886,7 @@ LITE_OS_SEC_TEXT INT32 LOS_GetGroupID(VOID) #endif } +/*! 进程创建初始化*/ STATIC UINT32 OsSystemProcessInit(LosProcessCB *processCB, UINT32 flags, const CHAR *name) { UINT32 ret = OsInitPCB(processCB, flags, name); @@ -940,7 +895,7 @@ STATIC UINT32 OsSystemProcessInit(LosProcessCB *processCB, UINT32 flags, const C } #ifdef LOSCFG_FS_VFS - processCB->files = alloc_files(); + processCB->files = alloc_files();//分配进程的文件的管理器 if (processCB->files == NULL) { ret = LOS_ENOMEM; goto EXIT; @@ -953,8 +908,8 @@ STATIC UINT32 OsSystemProcessInit(LosProcessCB *processCB, UINT32 flags, const C goto EXIT; } -#ifdef LOSCFG_SECURITY_CAPABILITY - processCB->user = OsCreateUser(0, 0, 1); +#ifdef LOSCFG_SECURITY_CAPABILITY //用户安全宏 + processCB->user = OsCreateUser(0, 0, 1); //创建用户 if (processCB->user == NULL) { ret = LOS_ENOMEM; goto EXIT; @@ -962,7 +917,7 @@ STATIC UINT32 OsSystemProcessInit(LosProcessCB *processCB, UINT32 flags, const C #endif #ifdef LOSCFG_KERNEL_PLIMITS - ret = OsPLimitsAddProcess(NULL, processCB); + ret = OsPLimitsAddProcess(NULL, processCB);//删除进程控制块,归还内存 if (ret != LOS_OK) { ret = LOS_ENOMEM; goto EXIT; @@ -974,7 +929,7 @@ EXIT: OsDeInitPCB(processCB); return ret; } - +/*! 创建2,0号进程,即内核态进程的老祖宗*/ LITE_OS_SEC_TEXT_INIT UINT32 OsSystemProcessCreate(VOID) { LosProcessCB *kerInitProcess = OsGetKernelInitProcess(); @@ -982,22 +937,22 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSystemProcessCreate(VOID) if (ret != LOS_OK) { return ret; } - kerInitProcess->processStatus &= ~OS_PROCESS_STATUS_INIT; + kerInitProcess->processStatus &= ~OS_PROCESS_STATUS_INIT;//去掉初始化标签 LosProcessCB *idleProcess = OsGetIdleProcess(); - ret = OsInitPCB(idleProcess, OS_KERNEL_MODE, "KIdle"); + ret = OsInitPCB(idleProcess, OS_KERNEL_MODE, "KIdle");//创建内核态0号进程 if (ret != LOS_OK) { return ret; } idleProcess->parentProcess = kerInitProcess; - LOS_ListTailInsert(&kerInitProcess->childrenList, &idleProcess->siblingList); + LOS_ListTailInsert(&kerInitProcess->childrenList, &idleProcess->siblingList);//挂到内核态祖宗进程的子孙链接上 idleProcess->pgroup = kerInitProcess->pgroup; LOS_ListTailInsert(&kerInitProcess->pgroup->processList, &idleProcess->subordinateGroupList); #ifdef LOSCFG_SECURITY_CAPABILITY - idleProcess->user = kerInitProcess->user; + idleProcess->user = kerInitProcess->user;//共享用户 #endif #ifdef LOSCFG_FS_VFS - idleProcess->files = kerInitProcess->files; + idleProcess->files = kerInitProcess->files;//共享文件 #endif idleProcess->processStatus &= ~OS_PROCESS_STATUS_INIT; @@ -1007,7 +962,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSystemProcessCreate(VOID) } return LOS_OK; } - +// 进程调度参数检查 INT32 OsSchedulerParamCheck(UINT16 policy, BOOL isThread, const LosSchedParam *param) { if (param == NULL) { @@ -1040,24 +995,24 @@ INT32 OsSchedulerParamCheck(UINT16 policy, BOOL isThread, const LosSchedParam *p STATIC INLINE INT32 ProcessSchedulerParamCheck(INT32 which, INT32 pid, UINT16 policy, const LosSchedParam *param) { - if (OS_PID_CHECK_INVALID(pid)) { + if (OS_PID_CHECK_INVALID(pid)) {//进程ID是否有效,默认 g_processMaxNum = 64 return LOS_EINVAL; } - if (which != LOS_PRIO_PROCESS) { + if (which != LOS_PRIO_PROCESS) {//进程标识 return LOS_EINVAL; } return OsSchedulerParamCheck(policy, FALSE, param); } -#ifdef LOSCFG_SECURITY_CAPABILITY +#ifdef LOSCFG_SECURITY_CAPABILITY//检查进程的安全许可证 STATIC BOOL OsProcessCapPermitCheck(const LosProcessCB *processCB, const SchedParam *param, UINT16 policy, UINT16 prio) { - LosProcessCB *runProcess = OsCurrProcessGet(); + LosProcessCB *runProcess = OsCurrProcessGet();//获得当前进程 /* always trust kernel process */ - if (!OsProcessIsUserMode(runProcess)) { + if (!OsProcessIsUserMode(runProcess)) {//进程必须在内核模式下,也就是说在内核模式下是安全的. return TRUE; } @@ -1073,7 +1028,7 @@ STATIC BOOL OsProcessCapPermitCheck(const LosProcessCB *processCB, const SchedPa return FALSE; } #endif - +// 设置进程调度计划 LITE_OS_SEC_TEXT INT32 OsSetProcessScheduler(INT32 which, INT32 pid, UINT16 policy, const LosSchedParam *schedParam) { SchedParam param = { 0 }; @@ -1086,8 +1041,8 @@ LITE_OS_SEC_TEXT INT32 OsSetProcessScheduler(INT32 which, INT32 pid, UINT16 poli } LosProcessCB *processCB = OS_PCB_FROM_PID(pid); - SCHEDULER_LOCK(intSave); - if (OsProcessIsInactive(processCB)) { + SCHEDULER_LOCK(intSave);//持有调度自旋锁,多CPU情况下调度期间需要原子处理 + if (OsProcessIsInactive(processCB)) {//进程未活动的处理 SCHEDULER_UNLOCK(intSave); return -LOS_ESRCH; } @@ -1127,20 +1082,20 @@ LITE_OS_SEC_TEXT INT32 OsSetProcessScheduler(INT32 which, INT32 pid, UINT16 poli needSched = taskCB->ops->schedParamModify(taskCB, ¶m); TO_SCHED: - SCHEDULER_UNLOCK(intSave); + SCHEDULER_UNLOCK(intSave);//还锁 - LOS_MpSchedule(OS_MP_CPU_ALL); + LOS_MpSchedule(OS_MP_CPU_ALL);//核间中断 if (needSched && OS_SCHEDULER_ACTIVE) { - LOS_Schedule(); + LOS_Schedule();//发起调度 } return LOS_OK; } - +// 设置指定进程的调度参数,包括优先级和调度策略 LITE_OS_SEC_TEXT INT32 LOS_SetProcessScheduler(INT32 pid, UINT16 policy, const LosSchedParam *schedParam) { return OsSetProcessScheduler(LOS_PRIO_PROCESS, pid, policy, schedParam); } - +// 获得指定进程的调度策略 LITE_OS_SEC_TEXT INT32 LOS_GetProcessScheduler(INT32 pid, INT32 *policy, LosSchedParam *schedParam) { UINT32 intSave; @@ -1184,7 +1139,7 @@ LITE_OS_SEC_TEXT INT32 LOS_GetProcessScheduler(INT32 pid, INT32 *policy, LosSche } return LOS_OK; } - +// 接口封装 - 设置进程优先级 LITE_OS_SEC_TEXT INT32 LOS_SetProcessPriority(INT32 pid, INT32 prio) { INT32 ret; @@ -1204,7 +1159,7 @@ LITE_OS_SEC_TEXT INT32 LOS_SetProcessPriority(INT32 pid, INT32 prio) return OsSetProcessScheduler(LOS_PRIO_PROCESS, pid, (UINT16)policy, ¶m); } - +// 接口封装 - 获取进程优先级 which:标识进程,进程组,用户 LITE_OS_SEC_TEXT INT32 OsGetProcessPriority(INT32 which, INT32 pid) { UINT32 intSave; @@ -1237,12 +1192,15 @@ LITE_OS_SEC_TEXT INT32 OsGetProcessPriority(INT32 which, INT32 pid) SCHEDULER_UNLOCK(intSave); return param.basePrio; } - +// 接口封装 - 获取指定进程优先级 LITE_OS_SEC_TEXT INT32 LOS_GetProcessPriority(INT32 pid) { return OsGetProcessPriority(LOS_PRIO_PROCESS, pid); } - +/*! +* 将任务挂入进程的waitList链表,表示这个任务在等待某个进程的退出 +* 当被等待进程退出时候会将自己挂到父进程的退出子进程链表和进程组的退出进程链表. +*/ STATIC VOID OsWaitInsertWaitListInOrder(LosTaskCB *runTask, LosProcessCB *processCB) { LOS_DL_LIST *head = &processCB->waitList; @@ -1274,7 +1232,7 @@ STATIC VOID OsWaitInsertWaitListInOrder(LosTaskCB *runTask, LosProcessCB *proces (VOID)runTask->ops->wait(runTask, list->pstNext, LOS_WAIT_FOREVER); return; } - +// 设置等待子进程退出方式方法 STATIC UINT32 WaitFindSpecifiedProcess(UINT32 pid, LosTaskCB *runTask, const LosProcessCB *processCB, LosProcessCB **childCB) { @@ -1295,7 +1253,7 @@ STATIC UINT32 WaitFindSpecifiedProcess(UINT32 pid, LosTaskCB *runTask, #endif /* Wait for the child process whose process number is pid. */ *childCB = OsFindExitChildProcess(processCB, waitProcess); - if (*childCB != NULL) { + if (*childCB != NULL) {//找到了,确实有一个已经退出的PID,注意一个进程退出时会挂到父进程的exitChildList上 return LOS_OK; } @@ -1303,7 +1261,7 @@ STATIC UINT32 WaitFindSpecifiedProcess(UINT32 pid, LosTaskCB *runTask, return LOS_ECHILD; } - runTask->waitFlag = OS_PROCESS_WAIT_PRO; + runTask->waitFlag = OS_PROCESS_WAIT_PRO;//设置当前任务的等待类型 runTask->waitID = (UINTPTR)waitProcess; return LOS_OK; } @@ -1322,18 +1280,18 @@ STATIC UINT32 OsWaitSetFlag(const LosProcessCB *processCB, INT32 pid, LosProcess if (childCB != NULL) { goto WAIT_BACK; } - } else if (pid == 0) { + } else if (pid == 0) {//等待同一进程组中的任何子进程 /* Wait for any child process in the same process group */ childCB = OsFindGroupExitProcess(processCB->pgroup, OS_INVALID_VALUE); - if (childCB != NULL) { - goto WAIT_BACK; + if (childCB != NULL) {//找到了,确实有一个已经退出的PID + goto WAIT_BACK;//直接成功返回 } runTask->waitID = (UINTPTR)OS_GET_PGROUP_LEADER(processCB->pgroup); - runTask->waitFlag = OS_PROCESS_WAIT_GID; - } else if (pid == -1) { + runTask->waitFlag = OS_PROCESS_WAIT_GID;//设置当前任务的等待类型 + } else if (pid == -1) {//等待任意子进程 /* Wait for any child process */ childCB = OsFindExitChildProcess(processCB, NULL); - if (childCB != NULL) { + if (childCB != NULL) {//找到了,确实有一个已经退出的PID goto WAIT_BACK; } runTask->waitID = pid; @@ -1351,14 +1309,14 @@ STATIC UINT32 OsWaitSetFlag(const LosProcessCB *processCB, INT32 pid, LosProcess } runTask->waitID = (UINTPTR)OS_GET_PGROUP_LEADER(pgroup); - runTask->waitFlag = OS_PROCESS_WAIT_GID; + runTask->waitFlag = OS_PROCESS_WAIT_GID;//设置当前任务的等待类型 } WAIT_BACK: *child = childCB; return LOS_OK; } - +// 等待回收孩子进程 STATIC UINT32 OsWaitRecycleChildProcess(const LosProcessCB *childCB, UINT32 intSave, INT32 *status, siginfo_t *info) { ProcessGroup *pgroup = NULL; @@ -1377,7 +1335,7 @@ STATIC UINT32 OsWaitRecycleChildProcess(const LosProcessCB *childCB, UINT32 intS SCHEDULER_UNLOCK(intSave); if (status != NULL) { - if (mode == OS_USER_MODE) { + if (mode == OS_USER_MODE) {//孩子为用户态进程 (VOID)LOS_ArchCopyToUser((VOID *)status, (const VOID *)(&(exitCode)), sizeof(INT32)); } else { *status = exitCode; @@ -1413,14 +1371,14 @@ STATIC UINT32 OsWaitRecycleChildProcess(const LosProcessCB *childCB, UINT32 intS (VOID)LOS_MemFree(m_aucSysMem1, pgroup); return pid; } - +// 检查要等待的孩子进程 STATIC UINT32 OsWaitChildProcessCheck(LosProcessCB *processCB, INT32 pid, LosProcessCB **childCB) -{ +{//当进程没有孩子且没有退出的孩子进程 if (LOS_ListEmpty(&(processCB->childrenList)) && LOS_ListEmpty(&(processCB->exitChildList))) { return LOS_ECHILD; } - return OsWaitSetFlag(processCB, pid, childCB); + return OsWaitSetFlag(processCB, pid, childCB);//设置等待子进程退出方式方法 } STATIC UINT32 OsWaitOptionsCheck(UINT32 options) @@ -1428,21 +1386,21 @@ STATIC UINT32 OsWaitOptionsCheck(UINT32 options) UINT32 flag = LOS_WAIT_WNOHANG | LOS_WAIT_WUNTRACED | LOS_WAIT_WCONTINUED; flag = ~flag & options; - if (flag != 0) { - return LOS_EINVAL; + if (flag != 0) {//三种方式中一种都没有 + return LOS_EINVAL;//无效参数 } - if ((options & (LOS_WAIT_WCONTINUED | LOS_WAIT_WUNTRACED)) != 0) { - return LOS_EOPNOTSUPP; + if ((options & (LOS_WAIT_WCONTINUED | LOS_WAIT_WUNTRACED)) != 0) {//暂不支持这两种方式. + return LOS_EOPNOTSUPP;//不支持 } - if (OS_INT_ACTIVE) { - return LOS_EINTR; + if (OS_INT_ACTIVE) {//中断发生期间 + return LOS_EINTR;//中断提示 } return LOS_OK; } - +//等待子进程结束并回收子进程,返回已经终止的子进程的进程ID号,并清除僵死进程。 STATIC INT32 OsWait(INT32 pid, USER INT32 *status, USER siginfo_t *info, UINT32 options, VOID *rusage) { (VOID)rusage; @@ -1453,13 +1411,13 @@ STATIC INT32 OsWait(INT32 pid, USER INT32 *status, USER siginfo_t *info, UINT32 LosProcessCB *processCB = OsCurrProcessGet(); LosTaskCB *runTask = OsCurrTaskGet(); SCHEDULER_LOCK(intSave); - ret = OsWaitChildProcessCheck(processCB, pid, &childCB); + ret = OsWaitChildProcessCheck(processCB, pid, &childCB);//先检查下看能不能找到参数要求的退出子进程 if (ret != LOS_OK) { pid = -ret; goto ERROR; } - if (childCB != NULL) { + if (childCB != NULL) {//找到了进程 #ifdef LOSCFG_PID_CONTAINER if (childCB == processCB) { SCHEDULER_UNLOCK(intSave); @@ -1471,21 +1429,22 @@ STATIC INT32 OsWait(INT32 pid, USER INT32 *status, USER siginfo_t *info, UINT32 #endif return (INT32)OsWaitRecycleChildProcess(childCB, intSave, status, info); } - - if ((options & LOS_WAIT_WNOHANG) != 0) { - runTask->waitFlag = 0; - pid = 0; + //没有找到,看是否要返回还是去做个登记 + if ((options & LOS_WAIT_WNOHANG) != 0) {//有LOS_WAIT_WNOHANG标签 + runTask->waitFlag = 0;//等待标识置0 + pid = 0;//这里置0,是为了 return 0 goto ERROR; } - + //等待孩子进程退出 OsWaitInsertWaitListInOrder(runTask, processCB); + //发起调度的目的是为了让出CPU,让其他进程/任务运行 runTask->waitFlag = 0; if (runTask->waitID == OS_INVALID_VALUE) { - pid = -LOS_ECHILD; + pid = -LOS_ECHILD;//没有此子进程 goto ERROR; } - + //回收僵死进程 childCB = (LosProcessCB *)runTask->waitID; if (!OsProcessIsDead(childCB)) { pid = -LOS_ESRCH; @@ -1572,12 +1531,12 @@ UINT32 OsGetProcessGroupCB(UINT32 pid, UINTPTR *ppgroupLeader) STATIC UINT32 OsSetProcessGroupCheck(const LosProcessCB *processCB, LosProcessCB *pgroupCB) { - LosProcessCB *runProcessCB = OsCurrProcessGet(); + LosProcessCB *runProcessCB = OsCurrProcessGet();//拿到当前运行进程 - if (OsProcessIsInactive(processCB)) { + if (OsProcessIsInactive(processCB)) {//进程是否活动 return LOS_ESRCH; } - + //参数进程不在用户态或者组长不在用户态 #ifdef LOSCFG_PID_CONTAINER if ((processCB->processID == OS_USER_ROOT_PROCESS_ID) || OS_PROCESS_CONTAINER_CHECK(processCB, runProcessCB)) { return LOS_EPERM; @@ -1694,12 +1653,12 @@ EXIT: SCHEDULER_UNLOCK(intSave); return gid; } - +// 获取当前进程的组ID LITE_OS_SEC_TEXT INT32 LOS_GetCurrProcessGroupID(VOID) { return LOS_GetProcessGroupID(OsCurrProcessGet()->processID); } - +// 为用户态任务分配栈空间 #ifdef LOSCFG_KERNEL_VM STATIC LosProcessCB *OsGetFreePCB(VOID) { @@ -1723,19 +1682,19 @@ STATIC LosProcessCB *OsGetFreePCB(VOID) STATIC VOID *OsUserInitStackAlloc(LosProcessCB *processCB, UINT32 *size) { LosVmMapRegion *region = NULL; - UINT32 stackSize = ALIGN(OS_USER_TASK_STACK_SIZE, PAGE_SIZE); - + UINT32 stackSize = ALIGN(OS_USER_TASK_STACK_SIZE, PAGE_SIZE);//1M栈空间 按页对齐 + //线性区分配虚拟内存 region = LOS_RegionAlloc(processCB->vmSpace, 0, stackSize, VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_READ | - VM_MAP_REGION_FLAG_PERM_WRITE, 0); + VM_MAP_REGION_FLAG_PERM_WRITE, 0);//可使用可读可写区 if (region == NULL) { return NULL; } - LOS_SetRegionTypeAnon(region); - region->regionFlags |= VM_MAP_REGION_FLAG_STACK; + LOS_SetRegionTypeAnon(region);//匿名映射 + region->regionFlags |= VM_MAP_REGION_FLAG_STACK;//标记该线性区为栈区 - *size = stackSize; + *size = stackSize;//记录栈大小 return (VOID *)(UINTPTR)region->range.base; } @@ -1770,6 +1729,14 @@ LITE_OS_SEC_TEXT LosVmSpace *OsExecProcessVmSpaceReplace(LosVmSpace *newSpace, U return oldSpace; } +/** + * @brief 进程的回收再利用,被LOS_DoExecveFile调用 + * @param processCB + * @param name + * @param oldSpace + * @param oldFiles + * @return LITE_OS_SEC_TEXT + */ LITE_OS_SEC_TEXT UINT32 OsExecRecycleAndInit(LosProcessCB *processCB, const CHAR *name, LosVmSpace *oldSpace, UINTPTR oldFiles) { @@ -1819,7 +1786,7 @@ LITE_OS_SEC_TEXT UINT32 OsExecRecycleAndInit(LosProcessCB *processCB, const CHAR return LOS_OK; } - +// 执行用户态任务, entry为入口函数 ,其中 创建好task,task上下文 等待调度真正执行, sp:栈指针 mapBase:栈底 mapSize:栈大小 LITE_OS_SEC_TEXT UINT32 OsExecStart(const TSK_ENTRY_FUNC entry, UINTPTR sp, UINTPTR mapBase, UINT32 mapSize) { UINT32 intSave; @@ -1828,29 +1795,30 @@ LITE_OS_SEC_TEXT UINT32 OsExecStart(const TSK_ENTRY_FUNC entry, UINTPTR sp, UINT return LOS_NOK; } - if ((sp == 0) || (LOS_Align(sp, LOSCFG_STACK_POINT_ALIGN_SIZE) != sp)) { + if ((sp == 0) || (LOS_Align(sp, LOSCFG_STACK_POINT_ALIGN_SIZE) != sp)) {//对齐 return LOS_NOK; } - - if ((mapBase == 0) || (mapSize == 0) || (sp <= mapBase) || (sp > (mapBase + mapSize))) { + //注意 sp此时指向栈底,栈底地址要大于栈顶 + if ((mapBase == 0) || (mapSize == 0) || (sp <= mapBase) || (sp > (mapBase + mapSize))) {//参数检查 return LOS_NOK; } - LosTaskCB *taskCB = OsCurrTaskGet(); - - SCHEDULER_LOCK(intSave); - taskCB->userMapBase = mapBase; - taskCB->userMapSize = mapSize; - taskCB->taskEntry = (TSK_ENTRY_FUNC)entry; + LosTaskCB *taskCB = OsCurrTaskGet();//获取当前任务 + SCHEDULER_LOCK(intSave);//拿自旋锁 + taskCB->userMapBase = mapBase;//用户态栈顶位置 + taskCB->userMapSize = mapSize;//用户态栈 + taskCB->taskEntry = (TSK_ENTRY_FUNC)entry;//任务的入口函数 + //初始化内核态栈 TaskContext *taskContext = (TaskContext *)OsTaskStackInit(taskCB->taskID, taskCB->stackSize, (VOID *)taskCB->topOfStack, FALSE); - OsUserTaskStackInit(taskContext, (UINTPTR)taskCB->taskEntry, sp); - SCHEDULER_UNLOCK(intSave); + OsUserTaskStackInit(taskContext, (UINTPTR)taskCB->taskEntry, sp);//初始化用户栈,将内核栈中上下文的 context->R[0] = sp ,context->sp = sp + //这样做的目的是将用户栈SP保存到内核栈中, + SCHEDULER_UNLOCK(intSave);//解锁 return LOS_OK; } #endif - +// 用户进程开始初始化 STATIC UINT32 OsUserInitProcessStart(LosProcessCB *processCB, TSK_INIT_PARAM_S *param) { UINT32 intSave; @@ -1871,7 +1839,7 @@ STATIC UINT32 OsUserInitProcessStart(LosProcessCB *processCB, TSK_INIT_PARAM_S * processCB->processStatus &= ~OS_PROCESS_STATUS_INIT; SCHEDULER_UNLOCK(intSave); - ret = LOS_SetTaskScheduler(taskID, LOS_SCHED_RR, OS_TASK_PRIORITY_LOWEST); + ret = LOS_SetTaskScheduler(taskID, LOS_SCHED_RR, OS_TASK_PRIORITY_LOWEST);//调度器:设置为抢占式调度和最低任务优先级(31级) if (ret != LOS_OK) { PRINT_ERR("User init process set scheduler failed! ERROR:%d \n", ret); goto EXIT; @@ -1990,7 +1958,7 @@ ERROR: OsDeInitPCB(processCB); return ret; } - +// 拷贝用户信息 直接用memcpy_s STATIC UINT32 OsCopyUser(LosProcessCB *childCB, LosProcessCB *parentCB) { #ifdef LOSCFG_SECURITY_CAPABILITY @@ -2005,6 +1973,7 @@ STATIC UINT32 OsCopyUser(LosProcessCB *childCB, LosProcessCB *parentCB) return LOS_OK; } +//拷贝一个Task过程 STATIC VOID GetCopyTaskParam(LosProcessCB *childProcessCB, UINTPTR entry, UINT32 size, TSK_INIT_PARAM_S *taskParam, SchedParam *param) { @@ -2012,15 +1981,15 @@ STATIC VOID GetCopyTaskParam(LosProcessCB *childProcessCB, UINTPTR entry, UINT32 LosTaskCB *runTask = OsCurrTaskGet(); SCHEDULER_LOCK(intSave); - if (OsProcessIsUserMode(childProcessCB)) { - taskParam->pfnTaskEntry = runTask->taskEntry; - taskParam->uwStackSize = runTask->stackSize; - taskParam->userParam.userArea = runTask->userArea; - taskParam->userParam.userMapBase = runTask->userMapBase; - taskParam->userParam.userMapSize = runTask->userMapSize; - } else { - taskParam->pfnTaskEntry = (TSK_ENTRY_FUNC)entry; - taskParam->uwStackSize = size; + if (OsProcessIsUserMode(childProcessCB)) {//用户态进程 + taskParam->pfnTaskEntry = runTask->taskEntry;//拷贝当前任务入口地址 + taskParam->uwStackSize = runTask->stackSize;//栈空间大小 + taskParam->userParam.userArea = runTask->userArea;//用户态栈区栈顶位置 + taskParam->userParam.userMapBase = runTask->userMapBase;//用户态栈底 + taskParam->userParam.userMapSize = runTask->userMapSize;//用户态栈大小 + } else {//注意内核态进程创建任务的入口由外界指定,例如 OsCreateIdleProcess 指定了OsIdleTask + taskParam->pfnTaskEntry = (TSK_ENTRY_FUNC)entry;//参数(sp)为内核态入口地址 + taskParam->uwStackSize = size;//参数(size)为内核态栈大小 } if (runTask->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) { taskParam->uwResved = LOS_TASK_ATTR_JOINABLE; @@ -2056,25 +2025,25 @@ STATIC UINT32 OsCopyTask(UINT32 flags, LosProcessCB *childProcessCB, const CHAR } LosTaskCB *childTaskCB = childProcessCB->threadGroup; - childTaskCB->taskStatus = runTask->taskStatus; + childTaskCB->taskStatus = runTask->taskStatus;//任务状态先同步,注意这里是赋值操作. ...01101001 childTaskCB->ops->schedParamModify(childTaskCB, ¶m); - if (childTaskCB->taskStatus & OS_TASK_STATUS_RUNNING) { - childTaskCB->taskStatus &= ~OS_TASK_STATUS_RUNNING; - } else { - if (OS_SCHEDULER_ACTIVE) { + if (childTaskCB->taskStatus & OS_TASK_STATUS_RUNNING) {//因只能有一个运行的task,所以如果一样要改4号位 + childTaskCB->taskStatus &= ~OS_TASK_STATUS_RUNNING;//将四号位清0 ,变成 ...01100001 + } else {//非运行状态下会发生什么? + if (OS_SCHEDULER_ACTIVE) {//克隆线程发生错误未运行 LOS_Panic("Clone thread status not running error status: 0x%x\n", childTaskCB->taskStatus); } - childTaskCB->taskStatus &= ~OS_TASK_STATUS_UNUSED; + childTaskCB->taskStatus &= ~OS_TASK_STATUS_UNUSED;//干净的Task } - if (OsProcessIsUserMode(childProcessCB)) { + if (OsProcessIsUserMode(childProcessCB)) {//是否是用户进程 SCHEDULER_LOCK(intSave); OsUserCloneParentStack(childTaskCB->stackPointer, entry, runTask->topOfStack, runTask->stackSize); SCHEDULER_UNLOCK(intSave); } return LOS_OK; } - +//拷贝父亲大人的遗传基因信息 STATIC UINT32 OsCopyParent(UINT32 flags, LosProcessCB *childProcessCB, LosProcessCB *runProcessCB) { UINT32 intSave; @@ -2082,13 +2051,14 @@ STATIC UINT32 OsCopyParent(UINT32 flags, LosProcessCB *childProcessCB, LosProces SCHEDULER_LOCK(intSave); if (childProcessCB->parentProcess == NULL) { - if (flags & CLONE_PARENT) { + if (flags & CLONE_PARENT) { //这里指明 childProcessCB 和 runProcessCB 有同一个父亲,是兄弟关系 parentProcessCB = runProcessCB->parentProcess; } else { - parentProcessCB = runProcessCB; + parentProcessCB = runProcessCB;//指认父亲,这个赋值代表从此是你儿了 } childProcessCB->parentProcess = parentProcessCB; - LOS_ListTailInsert(&parentProcessCB->childrenList, &childProcessCB->siblingList); + LOS_ListTailInsert(&parentProcessCB->childrenList, &childProcessCB->siblingList);//通过我的兄弟姐妹节点,挂到父亲的孩子链表上,于我而言,父亲的这个链表上挂的都是我的兄弟姐妹 + //不会被排序,老大,老二,老三 老天爷指定了。 } if (childProcessCB->pgroup == NULL) { @@ -2098,20 +2068,20 @@ STATIC UINT32 OsCopyParent(UINT32 flags, LosProcessCB *childProcessCB, LosProces SCHEDULER_UNLOCK(intSave); return LOS_OK; } - +//拷贝虚拟空间 STATIC UINT32 OsCopyMM(UINT32 flags, LosProcessCB *childProcessCB, LosProcessCB *runProcessCB) { status_t status; UINT32 intSave; - if (!OsProcessIsUserMode(childProcessCB)) { + if (!OsProcessIsUserMode(childProcessCB)) {//不是用户模式,直接返回,什么意思?内核虚拟空间只有一个,无需COPY !!! return LOS_OK; } - if (flags & CLONE_VM) { + if (flags & CLONE_VM) {//贴有虚拟内存的标签 SCHEDULER_LOCK(intSave); - childProcessCB->vmSpace->archMmu.virtTtb = runProcessCB->vmSpace->archMmu.virtTtb; - childProcessCB->vmSpace->archMmu.physTtb = runProcessCB->vmSpace->archMmu.physTtb; + childProcessCB->vmSpace->archMmu.virtTtb = runProcessCB->vmSpace->archMmu.virtTtb;//TTB虚拟地址基地址,即L1表存放位置,virtTtb是个指针,进程的虚拟空间是指定的范围的 + childProcessCB->vmSpace->archMmu.physTtb = runProcessCB->vmSpace->archMmu.physTtb;//TTB物理地址基地址,physTtb是个值,取决于运行时映射到物理内存的具体哪个位置. SCHEDULER_UNLOCK(intSave); return LOS_OK; } @@ -2122,7 +2092,7 @@ STATIC UINT32 OsCopyMM(UINT32 flags, LosProcessCB *childProcessCB, LosProcessCB } return LOS_OK; } - +// 拷贝进程文件描述符(proc_fd)信息 STATIC UINT32 OsCopyFile(UINT32 flags, LosProcessCB *childProcessCB, LosProcessCB *runProcessCB) { #ifdef LOSCFG_FS_VFS @@ -2152,7 +2122,7 @@ STATIC UINT32 OsCopyFile(UINT32 flags, LosProcessCB *childProcessCB, LosProcessC #endif #endif - childProcessCB->consoleID = runProcessCB->consoleID; + childProcessCB->consoleID = runProcessCB->consoleID;//控制台也是文件 childProcessCB->umask = runProcessCB->umask; return LOS_OK; } @@ -2160,16 +2130,16 @@ STATIC UINT32 OsCopyFile(UINT32 flags, LosProcessCB *childProcessCB, LosProcessC STATIC UINT32 OsForkInitPCB(UINT32 flags, LosProcessCB *child, const CHAR *name, UINTPTR sp, UINT32 size) { UINT32 ret; - LosProcessCB *run = OsCurrProcessGet(); + LosProcessCB *run = OsCurrProcessGet();//获取当前进程 - ret = OsCopyParent(flags, child, run); + ret = OsCopyParent(flags, child, run);//拷贝父亲大人的基因信息 if (ret != LOS_OK) { return ret; } - return OsCopyTask(flags, child, name, sp, size); + return OsCopyTask(flags, child, name, sp, size);//拷贝任务,设置任务入口函数,栈大小 } - +//设置进程组和加入进程调度就绪队列 STATIC UINT32 OsChildSetProcessGroupAndSched(LosProcessCB *child, LosProcessCB *run) { UINT32 intSave; @@ -2193,7 +2163,7 @@ STATIC UINT32 OsChildSetProcessGroupAndSched(LosProcessCB *child, LosProcessCB * (VOID)LOS_MemFree(m_aucSysMem1, pgroup); return LOS_OK; } - +// 拷贝进程资源 STATIC UINT32 OsCopyProcessResources(UINT32 flags, LosProcessCB *child, LosProcessCB *run) { UINT32 ret; @@ -2203,49 +2173,49 @@ STATIC UINT32 OsCopyProcessResources(UINT32 flags, LosProcessCB *child, LosProce return ret; } - ret = OsCopyMM(flags, child, run); + ret = OsCopyMM(flags, child, run);//拷贝虚拟空间 if (ret != LOS_OK) { return ret; } - ret = OsCopyFile(flags, child, run); + ret = OsCopyFile(flags, child, run);//拷贝文件信息 if (ret != LOS_OK) { return ret; } #ifdef LOSCFG_KERNEL_LITEIPC - if (run->ipcInfo != NULL) { - child->ipcInfo = LiteIpcPoolReInit((const ProcIpcInfo *)(run->ipcInfo)); - if (child->ipcInfo == NULL) { - return LOS_ENOMEM; + if (run->ipcInfo != NULL) {//重新初始化IPC池 + child->ipcInfo = LiteIpcPoolReInit((const ProcIpcInfo *)(run->ipcInfo));//@note_good 将沿用用户态空间地址(即线性区地址) + if (child->ipcInfo == NULL) {//因为整个进程虚拟空间都是拷贝的,ipc的用户态虚拟地址当然可以拷贝,但因进程不同了,所以需要重新申请ipc池和重新 + return LOS_ENOMEM;//映射池中两个地址. } } #endif #ifdef LOSCFG_SECURITY_CAPABILITY - OsCopyCapability(run, child); + OsCopyCapability(run, child);//拷贝安全能力 #endif return LOS_OK; } - +// 拷贝进程 STATIC INT32 OsCopyProcess(UINT32 flags, const CHAR *name, UINTPTR sp, UINT32 size) { UINT32 ret, processID; - LosProcessCB *run = OsCurrProcessGet(); // 获取当前进程 + LosProcessCB *run = OsCurrProcessGet();//获取当前进程 - LosProcessCB *child = OsGetFreePCB(); // 指向新的进程块 + LosProcessCB *child = OsGetFreePCB();//从进程池中申请一个进程控制块,鸿蒙进程池默认64 if (child == NULL) { return -LOS_EAGAIN; } - processID = child->processID; // 进程ID(cpid) + processID = child->processID; - ret = OsInitPCB(child, run->processMode, name); // 初始化PCB + ret = OsInitPCB(child, run->processMode, name); if (ret != LOS_OK) { goto ERROR_INIT; } #ifdef LOSCFG_KERNEL_CONTAINER - ret = OsCopyContainers(flags, child, run, &processID); + ret = OsCopyContainers(flags, child, run, &processID); if (ret != LOS_OK) { goto ERROR_INIT; } @@ -2258,24 +2228,24 @@ STATIC INT32 OsCopyProcess(UINT32 flags, const CHAR *name, UINTPTR sp, UINT32 si #endif #endif - ret = OsForkInitPCB(flags, child, name, sp, size); + ret = OsForkInitPCB(flags, child, name, sp, size);//初始化进程控制块 if (ret != LOS_OK) { goto ERROR_INIT; } - ret = OsCopyProcessResources(flags, child, run); //.. 拷贝进程的资源 + ret = OsCopyProcessResources(flags, child, run);//拷贝进程的资源,包括虚拟空间,文件,安全,IPC == if (ret != LOS_OK) { goto ERROR_TASK; } - ret = OsChildSetProcessGroupAndSched(child, run); // 设置进程组和加入进程调度就绪队列 + ret = OsChildSetProcessGroupAndSched(child, run);//设置进程组和加入进程调度就绪队列 if (ret != LOS_OK) { goto ERROR_TASK; } - LOS_MpSchedule(OS_MP_CPU_ALL); // 给CPU发送接收调度的 - if (OS_SCHEDULER_ACTIVE) { - LOS_Schedule(); + LOS_MpSchedule(OS_MP_CPU_ALL);//给各CPU发送准备接受调度信号 + if (OS_SCHEDULER_ACTIVE) {//当前CPU core处于活动状态 + LOS_Schedule();// 申请调度 } return processID; @@ -2286,6 +2256,7 @@ ERROR_INIT: OsDeInitPCB(child); return -ret; } + /*! * @brief OsClone 进程克隆 * @@ -2302,7 +2273,6 @@ LITE_OS_SEC_TEXT INT32 OsClone(UINT32 flags, UINTPTR sp, UINT32 size) #ifdef LOSCFG_KERNEL_CONTAINER #ifdef LOSCFG_PID_CONTAINER cloneFlag |= CLONE_NEWPID; - // 指向当前进程控制块的指针 LosProcessCB *curr = OsCurrProcessGet(); if (((flags & CLONE_NEWPID) != 0) && ((flags & (CLONE_PARENT | CLONE_THREAD)) != 0)) { return -LOS_EINVAL; @@ -2345,7 +2315,7 @@ LITE_OS_SEC_TEXT INT32 OsClone(UINT32 flags, UINTPTR sp, UINT32 size) return OsCopyProcess(cloneFlag & flags, NULL, sp, size); } - +//著名的 fork 函数 记得前往 https://gitee.com/weharmony/kernel_liteos_a_note fork一下 :) LITE_OS_SEC_TEXT INT32 LOS_Fork(UINT32 flags, const CHAR *name, const TSK_ENTRY_FUNC entry, UINT32 stackSize) { UINT32 cloneFlag = CLONE_PARENT | CLONE_THREAD | CLONE_VFORK | CLONE_FILES; @@ -2355,7 +2325,7 @@ LITE_OS_SEC_TEXT INT32 LOS_Fork(UINT32 flags, const CHAR *name, const TSK_ENTRY_ } flags |= CLONE_FILES; - return OsCopyProcess(cloneFlag & flags, name, (UINTPTR)entry, stackSize); + return OsCopyProcess(cloneFlag & flags, name, (UINTPTR)entry, stackSize);//拷贝一个进程 } #else LITE_OS_SEC_TEXT_INIT UINT32 OsUserInitProcess(VOID) @@ -2364,6 +2334,14 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsUserInitProcess(VOID) } #endif +/*! + * @brief LOS_Exit + * 进程退出 + * @param status + * @return + * + * @see + */ LITE_OS_SEC_TEXT VOID LOS_Exit(INT32 status) { UINT32 intSave; @@ -2373,7 +2351,7 @@ LITE_OS_SEC_TEXT VOID LOS_Exit(INT32 status) /* The exit of a kernel - state process must be kernel - state and all threads must actively exit */ LosProcessCB *processCB = OsCurrProcessGet(); SCHEDULER_LOCK(intSave); - if (!OsProcessIsUserMode(processCB) && (processCB->threadNumber != 1)) { + if (!OsProcessIsUserMode(processCB) && (processCB->threadNumber != 1)) {//内核态下进程的退出方式,必须是所有的任务都退出了 SCHEDULER_UNLOCK(intSave); PRINT_ERR("Kernel-state processes with multiple threads are not allowed to exit directly\n"); return; @@ -2384,24 +2362,33 @@ LITE_OS_SEC_TEXT VOID LOS_Exit(INT32 status) OsRunningTaskToExit(OsCurrTaskGet(), OS_PRO_EXIT_OK); } +/*! + * @brief LOS_GetUsedPIDList + * 获取使用中的进程列表 + * @param pidList + * @param pidMaxNum + * @return + * + * @see + */ LITE_OS_SEC_TEXT INT32 LOS_GetUsedPIDList(UINT32 *pidList, INT32 pidMaxNum) { LosProcessCB *pcb = NULL; INT32 num = 0; UINT32 intSave; UINT32 pid = 1; - // TSK_ENTRY_FUNC s + if (pidList == NULL) { return 0; } SCHEDULER_LOCK(intSave); - while (OsProcessIDUserCheckInvalid(pid) == false) { + while (OsProcessIDUserCheckInvalid(pid) == false) {//遍历进程池 pcb = OS_PCB_FROM_PID(pid); pid++; - if (OsProcessIsUnused(pcb)) { + if (OsProcessIsUnused(pcb)) {//未使用的不算 continue; } - pidList[num] = pcb->processID; + pidList[num] = pcb->processID;//由参数带走 num++; if (num >= pidMaxNum) { break; @@ -2427,12 +2414,12 @@ LITE_OS_SEC_TEXT struct fd_table_s *LOS_GetFdTable(UINT32 pid) return files->fdt; } #endif - +// 获取当前进程的进程ID LITE_OS_SEC_TEXT UINT32 LOS_GetCurrProcessID(VOID) { return OsCurrProcessGet()->processID; } - +// 按指定状态退出指定进程 #ifdef LOSCFG_KERNEL_VM STATIC VOID ThreadGroupActiveTaskKilled(LosTaskCB *taskCB) { @@ -2505,12 +2492,12 @@ LITE_OS_SEC_TEXT VOID OsProcessThreadGroupDestroy(VOID) #endif return; } - +// 获取系统支持的最大进程数目 LITE_OS_SEC_TEXT UINT32 LOS_GetSystemProcessMaximum(VOID) { return g_processMaxNum; } - +// 获取用户态进程的根进程,所有用户进程都是g_processCBArray[g_userInitProcess] fork来的 LITE_OS_SEC_TEXT LosProcessCB *OsGetUserInitProcess(VOID) { return &g_processCBArray[OS_USER_ROOT_PROCESS_ID]; @@ -2520,7 +2507,7 @@ LITE_OS_SEC_TEXT LosProcessCB *OsGetKernelInitProcess(VOID) { return &g_processCBArray[OS_KERNEL_ROOT_PROCESS_ID]; } - +// 获取空闲进程,0号进程为空闲进程,该进程不干活,专给CPU休息的。 LITE_OS_SEC_TEXT LosProcessCB *OsGetIdleProcess(VOID) { return &g_processCBArray[OS_KERNEL_IDLE_PROCESS_ID]; diff --git a/src/kernel_liteos_a/kernel/base/core/los_swtmr.c b/src/kernel_liteos_a/kernel/base/core/los_swtmr.c index 893cabd0..b648553c 100644 --- a/src/kernel_liteos_a/kernel/base/core/los_swtmr.c +++ b/src/kernel_liteos_a/kernel/base/core/los_swtmr.c @@ -28,12 +28,7 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/*! -* @file los_swtmr.c -* @brief 软定时器主文件 -* @details -* @attention @verbatim -基本概念 +/*基本概念 软件定时器,是基于系统Tick时钟中断且由软件来模拟的定时器。当经过设定的Tick数后,会触发用户自定义的回调函数。 硬件定时器受硬件的限制,数量上不足以满足用户的实际需求。因此为了满足用户需求,提供更多的定时器, 软件定时器功能,支持如下特性: @@ -88,9 +83,7 @@ 系统可配置的软件定时器个数是指:整个系统可使用的软件定时器总个数,并非用户可使用的软件定时器个数。 例如:系统多占用一个软件定时器,那么用户能使用的软件定时器资源就会减少一个。 创建单次不自删除属性的定时器,用户需要自行调用定时器删除接口删除定时器,回收定时器资源,避免资源泄露。 - 软件定时器的定时精度与系统Tick时钟的周期有关。 - @endverbatim -*/ + 软件定时器的定时精度与系统Tick时钟的周期有关。*/ #include "los_swtmr_pri.h" #include "los_init.h" #include "los_process_pri.h" @@ -113,14 +106,14 @@ LITE_OS_SEC_BSS UINT8 *g_swtmrHandlerPool = NULL; /* Pool of Swtmr Han LITE_OS_SEC_BSS LOS_DL_LIST g_swtmrFreeList; /* Free list of Software Timer */ /* spinlock for swtmr module, only available on SMP mode */ -LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_swtmrSpin); -#define SWTMR_LOCK(state) LOS_SpinLockSave(&g_swtmrSpin, &(state)) -#define SWTMR_UNLOCK(state) LOS_SpinUnlockRestore(&g_swtmrSpin, (state)) +LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_swtmrSpin);//初始化软件钟自旋锁,只有SMP情况才需要,只要是自旋锁都是由于CPU多核的同步 +#define SWTMR_LOCK(state) LOS_SpinLockSave(&g_swtmrSpin, &(state))//持有软时钟自旋锁 +#define SWTMR_UNLOCK(state) LOS_SpinUnlockRestore(&g_swtmrSpin, (state))//释放软时钟自旋锁 typedef struct { SortLinkAttribute swtmrSortLink; - LosTaskCB *swtmrTask; /* software timer task id */ - LOS_DL_LIST swtmrHandlerQueue; /* software timer timeout queue id */ + LosTaskCB *swtmrTask; /* software timer task id *///定时器任务ID + LOS_DL_LIST swtmrHandlerQueue; /* software timer timeout queue id *///定时器超时队列 } SwtmrRunqueue; STATIC SwtmrRunqueue g_swtmrRunqueue[LOSCFG_KERNEL_CORE_NUM]; @@ -316,7 +309,7 @@ STATIC INLINE VOID ScanSwtmrTimeList(SwtmrRunqueue *srq) LOS_SpinUnlockRestore(&swtmrSortLink->spinLock, intSave); return; } - +//软时钟的入口函数,拥有任务的最高优先级0级 STATIC VOID SwtmrTask(VOID) { SwtmrHandlerItem swtmrHandle; @@ -325,7 +318,7 @@ STATIC VOID SwtmrTask(VOID) SwtmrRunqueue *srq = &g_swtmrRunqueue[ArchCurrCpuid()]; LOS_DL_LIST *head = &srq->swtmrHandlerQueue; - for (;;) { + for (;;) {//死循环获取队列item,一直读干净为止 waitTime = OsSortLinkGetNextExpireTime(OsGetCurrSchedTimeCycle(), &srq->swtmrSortLink); if (waitTime != 0) { SCHEDULER_LOCK(intSave); @@ -341,29 +334,30 @@ STATIC VOID SwtmrTask(VOID) LOS_ListDelete(&swtmrHandlePtr->node); (VOID)memcpy_s(&swtmrHandle, sizeof(SwtmrHandlerItem), swtmrHandlePtr, sizeof(SwtmrHandlerItem)); - (VOID)LOS_MemboxFree(g_swtmrHandlerPool, swtmrHandlePtr); + (VOID)LOS_MemboxFree(g_swtmrHandlerPool, swtmrHandlePtr);//静态释放内存,注意在鸿蒙内核只有软时钟注册用到了静态内存 SwtmrHandler(&swtmrHandle); } } } +//创建软时钟任务,每个cpu core都可以拥有自己的软时钟任务 STATIC UINT32 SwtmrTaskCreate(UINT16 cpuid, UINT32 *swtmrTaskID) { UINT32 ret; TSK_INIT_PARAM_S swtmrTask; - (VOID)memset_s(&swtmrTask, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); - swtmrTask.pfnTaskEntry = (TSK_ENTRY_FUNC)SwtmrTask; - swtmrTask.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; - swtmrTask.pcName = "Swt_Task"; - swtmrTask.usTaskPrio = 0; - swtmrTask.uwResved = LOS_TASK_STATUS_DETACHED; + (VOID)memset_s(&swtmrTask, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));//清0 + swtmrTask.pfnTaskEntry = (TSK_ENTRY_FUNC)SwtmrTask;//入口函数 + swtmrTask.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;//16k默认内核任务栈 + swtmrTask.pcName = "Swt_Task";//任务名称 + swtmrTask.usTaskPrio = 0;// + swtmrTask.uwResved = LOS_TASK_STATUS_DETACHED;//分离模式 #ifdef LOSCFG_KERNEL_SMP - swtmrTask.usCpuAffiMask = CPUID_TO_AFFI_MASK(cpuid); + swtmrTask.usCpuAffiMask = CPUID_TO_AFFI_MASK(cpuid);//交给当前CPU执行这个任务 #endif - ret = LOS_TaskCreate(swtmrTaskID, &swtmrTask); + ret = LOS_TaskCreate(swtmrTaskID, &swtmrTask);//创建任务并申请调度 if (ret == LOS_OK) { - OS_TCB_FROM_TID(*swtmrTaskID)->taskStatus |= OS_TASK_FLAG_SYSTEM_TASK; + OS_TCB_FROM_TID(*swtmrTaskID)->taskStatus |= OS_TASK_FLAG_SYSTEM_TASK;//告知这是个任务系统 } return ret; @@ -381,16 +375,16 @@ BOOL OsIsSwtmrTask(const LosTaskCB *taskCB) } return FALSE; } - +//回收指定进程的软时钟 LITE_OS_SEC_TEXT_INIT VOID OsSwtmrRecycle(UINTPTR ownerID) { - for (UINT16 index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++) { + for (UINT16 index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++) {//一个进程往往会有多个定时器 if (g_swtmrCBArray[index].uwOwnerPid == ownerID) { - LOS_SwtmrDelete(index); + LOS_SwtmrDelete(index);//删除定时器 } } } - +//软时钟初始化,注意函数在多CPU情况下会执行多次 STATIC UINT32 SwtmrBaseInit(VOID) { UINT32 ret; @@ -400,15 +394,15 @@ STATIC UINT32 SwtmrBaseInit(VOID) return LOS_ERRNO_SWTMR_NO_MEMORY; } - (VOID)memset_s(swtmr, size, 0, size); - g_swtmrCBArray = swtmr; - LOS_ListInit(&g_swtmrFreeList); + (VOID)memset_s(swtmr, size, 0, size);//清0 + g_swtmrCBArray = swtmr;//软时钟 + LOS_ListInit(&g_swtmrFreeList);//初始化空间链表 for (UINT16 index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++, swtmr++) { - swtmr->usTimerID = index; - LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->stSortList.sortLinkNode); + swtmr->usTimerID = index;//按顺序赋值 + LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->stSortList.sortLinkNode);//通过sortLinkNode将节点挂到空闲链表 } - - size = LOS_MEMBOX_SIZE(sizeof(SwtmrHandlerItem), OS_SWTMR_HANDLE_QUEUE_SIZE); + //想要用静态内存池管理,就必须要使用LOS_MEMBOX_SIZE来计算申请列表的内存大小,因为需要点前缀内存承载头部信息 + size = LOS_MEMBOX_SIZE(sizeof(SwtmrHandlerItem), OS_SWTMR_HANDLE_QUEUE_SIZE);//规划一片内存区域作为软时钟处理函数的静态内存池 g_swtmrHandlerPool = (UINT8 *)LOS_MemAlloc(m_aucSysMem1, size); /* system resident resource */ if (g_swtmrHandlerPool == NULL) { return LOS_ERRNO_SWTMR_NO_MEMORY; @@ -536,14 +530,14 @@ STATIC UINT64 SwtmrToStart(SWTMR_CTRL_S *swtmr, UINT16 cpuid) if ((swtmr->uwOverrun == 0) && ((swtmr->ucMode == LOS_SWTMR_MODE_ONCE) || (swtmr->ucMode == LOS_SWTMR_MODE_OPP) || - (swtmr->ucMode == LOS_SWTMR_MODE_NO_SELFDELETE))) { - ticks = swtmr->uwExpiry; + (swtmr->ucMode == LOS_SWTMR_MODE_NO_SELFDELETE))) {//如果是一次性的定时器 + ticks = swtmr->uwExpiry;//获取定时间隔 } else { ticks = swtmr->uwInterval; } - swtmr->ucState = OS_SWTMR_STATUS_TICKING; + swtmr->ucState = OS_SWTMR_STATUS_TICKING;//获取周期性定时器时间间隔 - UINT64 period = (UINT64)ticks * OS_CYCLE_PER_TICK; + UINT64 period = (UINT64)ticks * OS_CYCLE_PER_TICK;//计数状态 UINT64 responseTime = swtmr->startTime + period; UINT64 currTime = OsGetCurrSchedTimeCycle(); if (responseTime < currTime) { @@ -584,7 +578,7 @@ STATIC INLINE VOID SwtmrStart(SWTMR_CTRL_S *swtmr) STATIC INLINE VOID SwtmrDelete(SWTMR_CTRL_S *swtmr) { /* insert to free list */ - LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->stSortList.sortLinkNode); + LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->stSortList.sortLinkNode);//直接插入空闲链表中,回收再利用 swtmr->ucState = OS_SWTMR_STATUS_UNUSED; swtmr->uwOwnerPid = OS_INVALID_VALUE; @@ -703,7 +697,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsSwtmrTimeGet(const SWTMR_CTRL_S *swtmr) } return (UINT32)time; } - +//创建定时器,设置定时器的定时时长、定时模式、回调函数、并返回定时器ID LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval, UINT8 mode, SWTMR_PROC_FUNC handler, @@ -732,7 +726,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval, } SWTMR_LOCK(intSave); - if (LOS_ListEmpty(&g_swtmrFreeList)) { + if (LOS_ListEmpty(&g_swtmrFreeList)) {//空闲列表不能为空 SWTMR_UNLOCK(intSave); return LOS_ERRNO_SWTMR_MAXSIZE; } @@ -743,19 +737,19 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval, SWTMR_UNLOCK(intSave); swtmr->uwOwnerPid = (UINTPTR)OsCurrProcessGet(); - swtmr->pfnHandler = handler; - swtmr->ucMode = mode; + swtmr->pfnHandler = handler;//时间到了的回调函数 + swtmr->ucMode = mode;//定时模式 swtmr->uwOverrun = 0; - swtmr->uwInterval = interval; - swtmr->uwExpiry = interval; - swtmr->uwArg = arg; - swtmr->ucState = OS_SWTMR_STATUS_CREATED; + swtmr->uwInterval = interval;//周期性超时间隔 + swtmr->uwExpiry = interval;//一次性超时间隔 + swtmr->uwArg = arg;//回调函数的参数 + swtmr->ucState = OS_SWTMR_STATUS_CREATED;//已创建状态 SET_SORTLIST_VALUE(&swtmr->stSortList, OS_SORT_LINK_INVALID_TIME); *swtmrID = swtmr->usTimerID; OsHookCall(LOS_HOOK_TYPE_SWTMR_CREATE, swtmr); return LOS_OK; } - +//接口函数 启动定时器 参数定时任务ID LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrID) { SWTMR_CTRL_S *swtmr = NULL; @@ -767,27 +761,27 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrID) return LOS_ERRNO_SWTMR_ID_INVALID; } - swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT; - swtmr = g_swtmrCBArray + swtmrCBID; + swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;//取模 + swtmr = g_swtmrCBArray + swtmrCBID;//获取定时器控制结构体 SWTMR_LOCK(intSave); - if (swtmr->usTimerID != swtmrID) { + if (swtmr->usTimerID != swtmrID) {//ID必须一样 SWTMR_UNLOCK(intSave); return LOS_ERRNO_SWTMR_ID_INVALID; } - switch (swtmr->ucState) { + switch (swtmr->ucState) {//判断定时器状态 case OS_SWTMR_STATUS_UNUSED: ret = LOS_ERRNO_SWTMR_NOT_CREATED; break; - /* + /*如果定时器的状态为启动中,应先停止定时器再重新启动 * If the status of swtmr is timing, it should stop the swtmr first, * then start the swtmr again. */ - case OS_SWTMR_STATUS_TICKING: - SwtmrStop(swtmr); + case OS_SWTMR_STATUS_TICKING://正在计数的定时器 + SwtmrStop(swtmr);//先停止定时器,注意这里没有break;在OsSwtmrStop中状态将会回到了OS_SWTMR_STATUS_CRWEATED接下来就是执行启动了 /* fall-through */ - case OS_SWTMR_STATUS_CREATED: + case OS_SWTMR_STATUS_CREATED://已经创建好了 SwtmrStart(swtmr); break; default: @@ -799,7 +793,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrID) OsHookCall(LOS_HOOK_TYPE_SWTMR_START, swtmr); return ret; } - +//接口函数 停止计时器 参加定时任务ID LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrID) { SWTMR_CTRL_S *swtmr = NULL; @@ -811,24 +805,24 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrID) return LOS_ERRNO_SWTMR_ID_INVALID; } - swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT; - swtmr = g_swtmrCBArray + swtmrCBID; + swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;//取模 + swtmr = g_swtmrCBArray + swtmrCBID;//获取定时器控制结构体 SWTMR_LOCK(intSave); - if (swtmr->usTimerID != swtmrID) { + if (swtmr->usTimerID != swtmrID) {//ID必须一样 SWTMR_UNLOCK(intSave); return LOS_ERRNO_SWTMR_ID_INVALID; } - switch (swtmr->ucState) { + switch (swtmr->ucState) {//判断定时器状态 case OS_SWTMR_STATUS_UNUSED: - ret = LOS_ERRNO_SWTMR_NOT_CREATED; + ret = LOS_ERRNO_SWTMR_NOT_CREATED;//返回没有创建 break; case OS_SWTMR_STATUS_CREATED: - ret = LOS_ERRNO_SWTMR_NOT_STARTED; + ret = LOS_ERRNO_SWTMR_NOT_STARTED;//返回没有开始 break; - case OS_SWTMR_STATUS_TICKING: - SwtmrStop(swtmr); + case OS_SWTMR_STATUS_TICKING://正在计数 + SwtmrStop(swtmr);//执行正在停止计时器操作 break; default: ret = LOS_ERRNO_SWTMR_STATUS_INVALID; @@ -839,7 +833,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrID) OsHookCall(LOS_HOOK_TYPE_SWTMR_STOP, swtmr); return ret; } - +//接口函数 获得软件定时器剩余Tick数 通过 *tick 带走 LITE_OS_SEC_TEXT UINT32 LOS_SwtmrTimeGet(UINT16 swtmrID, UINT32 *tick) { SWTMR_CTRL_S *swtmr = NULL; @@ -855,11 +849,11 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrTimeGet(UINT16 swtmrID, UINT32 *tick) return LOS_ERRNO_SWTMR_TICK_PTR_NULL; } - swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT; - swtmr = g_swtmrCBArray + swtmrCBID; + swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;//取模 + swtmr = g_swtmrCBArray + swtmrCBID;//获取定时器控制结构体 SWTMR_LOCK(intSave); - if (swtmr->usTimerID != swtmrID) { + if (swtmr->usTimerID != swtmrID) {//ID必须一样 SWTMR_UNLOCK(intSave); return LOS_ERRNO_SWTMR_ID_INVALID; } @@ -870,8 +864,8 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrTimeGet(UINT16 swtmrID, UINT32 *tick) case OS_SWTMR_STATUS_CREATED: ret = LOS_ERRNO_SWTMR_NOT_STARTED; break; - case OS_SWTMR_STATUS_TICKING: - *tick = OsSwtmrTimeGet(swtmr); + case OS_SWTMR_STATUS_TICKING://正在计数的定时器 + *tick = OsSwtmrTimeGet(swtmr);//获取 break; default: ret = LOS_ERRNO_SWTMR_STATUS_INVALID; @@ -880,7 +874,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrTimeGet(UINT16 swtmrID, UINT32 *tick) SWTMR_UNLOCK(intSave); return ret; } - +//接口函数 删除定时器 LITE_OS_SEC_TEXT UINT32 LOS_SwtmrDelete(UINT16 swtmrID) { SWTMR_CTRL_S *swtmr = NULL; @@ -892,11 +886,11 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrDelete(UINT16 swtmrID) return LOS_ERRNO_SWTMR_ID_INVALID; } - swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT; - swtmr = g_swtmrCBArray + swtmrCBID; + swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;//取模 + swtmr = g_swtmrCBArray + swtmrCBID;//获取定时器控制结构体 SWTMR_LOCK(intSave); - if (swtmr->usTimerID != swtmrID) { + if (swtmr->usTimerID != swtmrID) {//ID必须一样 SWTMR_UNLOCK(intSave); return LOS_ERRNO_SWTMR_ID_INVALID; } @@ -905,10 +899,10 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrDelete(UINT16 swtmrID) case OS_SWTMR_STATUS_UNUSED: ret = LOS_ERRNO_SWTMR_NOT_CREATED; break; - case OS_SWTMR_STATUS_TICKING: + case OS_SWTMR_STATUS_TICKING://正在计数就先停止在删除,这里没有break SwtmrStop(swtmr); /* fall-through */ - case OS_SWTMR_STATUS_CREATED: + case OS_SWTMR_STATUS_CREATED://再删除定时器 SwtmrDelete(swtmr); break; default: @@ -921,4 +915,4 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrDelete(UINT16 swtmrID) return ret; } -#endif /* LOSCFG_BASE_CORE_SWTMR_ENABLE */ +#endif /* LOSCFG_BASE_CORE_SWTMR_ENABLE */ \ No newline at end of file diff --git a/src/kernel_liteos_a/kernel/base/core/los_task.c b/src/kernel_liteos_a/kernel/base/core/los_task.c index 2bd80726..d0091651 100644 --- a/src/kernel_liteos_a/kernel/base/core/los_task.c +++ b/src/kernel_liteos_a/kernel/base/core/los_task.c @@ -68,13 +68,83 @@ #if (LOSCFG_BASE_CORE_TSK_LIMIT <= 0) #error "task maxnum cannot be zero" #endif /* LOSCFG_BASE_CORE_TSK_LIMIT <= 0 */ - -LITE_OS_SEC_BSS LosTaskCB *g_taskCBArray; -LITE_OS_SEC_BSS LOS_DL_LIST g_losFreeTask; -LITE_OS_SEC_BSS LOS_DL_LIST g_taskRecycleList; -LITE_OS_SEC_BSS UINT32 g_taskMaxNum; +/* +基本概念 + 从系统角度看,任务是竞争系统资源的最小运行单元。任务可以使用或等待CPU、 + 使用内存空间等系统资源,并独立于其它任务运行。 + 任务模块可以给用户提供多个任务,实现任务间的切换,帮助用户管理业务程序流程。具有如下特性: + 支持多任务。 + 一个任务表示一个线程。 + 抢占式调度机制,高优先级的任务可打断低优先级任务,低优先级任务必须在高优先级任务阻塞或结束后才能得到调度。 + 相同优先级任务支持时间片轮转调度方式。 + 共有32个优先级[0-31],最高优先级为0,最低优先级为31。 + + 任务状态通常分为以下四种: + 就绪(Ready):该任务在就绪队列中,只等待CPU。 + 运行(Running):该任务正在执行。 + 阻塞(Blocked):该任务不在就绪队列中。包含任务被挂起(suspend状态)、任务被延时(delay状态)、 + 任务正在等待信号量、读写队列或者等待事件等。 + 退出态(Dead):该任务运行结束,等待系统回收资源。 + + 任务状态迁移说明 + 就绪态→运行态 + 任务创建后进入就绪态,发生任务切换时,就绪队列中最高优先级的任务被执行, + 从而进入运行态,但此刻该任务依旧在就绪队列中。 + 运行态→阻塞态 + 正在运行的任务发生阻塞(挂起、延时、读信号量等)时,该任务会从就绪队列中删除, + 任务状态由运行态变成阻塞态,然后发生任务切换,运行就绪队列中最高优先级任务。 + 阻塞态→就绪态(阻塞态→运行态) + 阻塞的任务被恢复后(任务恢复、延时时间超时、读信号量超时或读到信号量等),此时被 + 恢复的任务会被加入就绪队列,从而由阻塞态变成就绪态;此时如果被恢复任务的优先级高于 + 正在运行任务的优先级,则会发生任务切换,该任务由就绪态变成运行态。 + 就绪态→阻塞态 + 任务也有可能在就绪态时被阻塞(挂起),此时任务状态由就绪态变为阻塞态,该任务 + 从就绪队列中删除,不会参与任务调度,直到该任务被恢复。 + 运行态→就绪态 + 有更高优先级任务创建或者恢复后,会发生任务调度,此刻就绪队列中最高优先级任务 + 变为运行态,那么原先运行的任务由运行态变为就绪态,依然在就绪队列中。 + 运行态→退出态 + 运行中的任务运行结束,任务状态由运行态变为退出态。退出态包含任务运行结束的正常退出状态 + 以及Invalid状态。例如,任务运行结束但是没有自删除,对外呈现的就是Invalid状态,即退出态。 + 阻塞态→退出态 + 阻塞的任务调用删除接口,任务状态由阻塞态变为退出态。 + + 主要术语 + 任务ID + 任务ID,在任务创建时通过参数返回给用户,是任务的重要标识。系统中的ID号是唯一的。用户可以 + 通过任务ID对指定任务进行任务挂起、任务恢复、查询任务名等操作。 + + 任务优先级 + 优先级表示任务执行的优先顺序。任务的优先级决定了在发生任务切换时即将要执行的任务, + 就绪队列中最高优先级的任务将得到执行。 + + 任务入口函数 + 新任务得到调度后将执行的函数。该函数由用户实现,在任务创建时,通过任务创建结构体设置。 + + 任务栈 + 每个任务都拥有一个独立的栈空间,我们称为任务栈。栈空间里保存的信息包含局部变量、寄存器、函数参数、函数返回地址等。 + + 任务上下文 + 任务在运行过程中使用的一些资源,如寄存器等,称为任务上下文。当这个任务挂起时,其他任务继续执行, + 可能会修改寄存器等资源中的值。如果任务切换时没有保存任务上下文,可能会导致任务恢复后出现未知错误。 + 因此,Huawei LiteOS在任务切换时会将切出任务的任务上下文信息,保存在自身的任务栈中,以便任务恢复后, + 从栈空间中恢复挂起时的上下文信息,从而继续执行挂起时被打断的代码。 + 任务控制块TCB + 每个任务都含有一个任务控制块(TCB)。TCB包含了任务上下文栈指针(stack pointer)、任务状态、 + 任务优先级、任务ID、任务名、任务栈大小等信息。TCB可以反映出每个任务运行情况。 + 任务切换 + 任务切换包含获取就绪队列中最高优先级任务、切出任务上下文保存、切入任务上下文恢复等动作。 + + 运作机制 + 用户创建任务时,系统会初始化任务栈,预置上下文。此外,系统还会将“任务入口函数” + 地址放在相应位置。这样在任务第一次启动进入运行态时,将会执行“任务入口函数”。 +*/ +LITE_OS_SEC_BSS LosTaskCB *g_taskCBArray;//任务池 128个 +LITE_OS_SEC_BSS LOS_DL_LIST g_losFreeTask;//空闲任务链表 +LITE_OS_SEC_BSS LOS_DL_LIST g_taskRecycleList;//回收任务链表 +LITE_OS_SEC_BSS UINT32 g_taskMaxNum;//任务最大个数 LITE_OS_SEC_BSS UINT32 g_taskScheduled; /* one bit for each cores */ -LITE_OS_SEC_BSS EVENT_CB_S g_resourceEvent; +LITE_OS_SEC_BSS EVENT_CB_S g_resourceEvent;//资源的事件 /* spinlock for task module, only available on SMP mode */ LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_taskSpin); @@ -82,7 +152,7 @@ STATIC VOID OsConsoleIDSetHook(UINT32 param1, UINT32 param2) __attribute__((weakref("OsSetConsoleID"))); /* temp task blocks for booting procedure */ -LITE_OS_SEC_BSS STATIC LosTaskCB g_mainTask[LOSCFG_KERNEL_CORE_NUM]; +LITE_OS_SEC_BSS STATIC LosTaskCB g_mainTask[LOSCFG_KERNEL_CORE_NUM];//启动引导过程中使用的临时任务 LosTaskCB *OsGetMainTask(VOID) { @@ -92,23 +162,23 @@ LosTaskCB *OsGetMainTask(VOID) VOID OsSetMainTask(VOID) { UINT32 i; - CHAR *name = "osMain"; + CHAR *name = "osMain";//任务名称 SchedParam schedParam = { 0 }; schedParam.policy = LOS_SCHED_RR; schedParam.basePrio = OS_PROCESS_PRIORITY_HIGHEST; schedParam.priority = OS_TASK_PRIORITY_LOWEST; - + //为每个CPU core 设置mainTask for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { g_mainTask[i].taskStatus = OS_TASK_STATUS_UNUSED; - g_mainTask[i].taskID = LOSCFG_BASE_CORE_TSK_LIMIT; + g_mainTask[i].taskID = LOSCFG_BASE_CORE_TSK_LIMIT;//128 g_mainTask[i].processCB = OS_KERNEL_PROCESS_GROUP; #ifdef LOSCFG_KERNEL_SMP_LOCKDEP g_mainTask[i].lockDep.lockDepth = 0; g_mainTask[i].lockDep.waitLock = NULL; #endif (VOID)strncpy_s(g_mainTask[i].taskName, OS_TCB_NAME_LEN, name, OS_TCB_NAME_LEN - 1); - LOS_ListInit(&g_mainTask[i].lockList); + LOS_ListInit(&g_mainTask[i].lockList);//初始化任务锁链表,上面挂的是任务已申请到的互斥锁 (VOID)OsSchedParamInit(&g_mainTask[i], schedParam.policy, &schedParam, NULL); } } @@ -122,31 +192,34 @@ VOID OsSetMainTaskProcess(UINTPTR processCB) #endif } } - +//空闲任务,每个CPU都有自己的空闲任务 LITE_OS_SEC_TEXT WEAK VOID OsIdleTask(VOID) { - while (1) { - WFI; + while (1) {//只有一个死循环 + WFI;//WFI指令:arm core立即进入low-power standly state,进入休眠模式,等待中断 } } VOID OsTaskInsertToRecycleList(LosTaskCB *taskCB) { - LOS_ListTailInsert(&g_taskRecycleList, &taskCB->pendList); + LOS_ListTailInsert(&g_taskRecycleList, &taskCB->pendList);//将任务挂入回收链表,等待回收 } - +/* +查找task通过OS_TCB_FROM_PENDLIST来实现,相当于由LOS_DL_LIST找到LosTaskCB, +将这些和参数任务绑在一起的task唤醒 +*/ LITE_OS_SEC_TEXT_INIT VOID OsTaskJoinPostUnsafe(LosTaskCB *taskCB) { - if (taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) { - if (!LOS_ListEmpty(&taskCB->joinList)) { - LosTaskCB *resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(taskCB->joinList))); - OsTaskWakeClearPendMask(resumedTask); + if (taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) {//join任务处理 + if (!LOS_ListEmpty(&taskCB->joinList)) {//joinList中的节点身上都有阻塞标签 + LosTaskCB *resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(taskCB->joinList)));//通过贴有JOIN标签链表的第一个节点找到Task + OsTaskWakeClearPendMask(resumedTask);//清除任务的挂起标记 resumedTask->ops->wake(resumedTask); } } - taskCB->taskStatus |= OS_TASK_STATUS_EXIT; + taskCB->taskStatus |= OS_TASK_STATUS_EXIT;//贴上任务退出标签 } - +//挂起任务,任务进入等待链表,Join代表是支持通过的第一个任务去唤醒其他的任务 LITE_OS_SEC_TEXT UINT32 OsTaskJoinPendUnsafe(LosTaskCB *taskCB) { if (taskCB->taskStatus & OS_TASK_STATUS_INIT) { @@ -165,13 +238,13 @@ LITE_OS_SEC_TEXT UINT32 OsTaskJoinPendUnsafe(LosTaskCB *taskCB) return LOS_EINVAL; } - +//任务设置分离模式Deatch和JOIN是一对有你没我的状态 LITE_OS_SEC_TEXT UINT32 OsTaskSetDetachUnsafe(LosTaskCB *taskCB) { - if (taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) { - if (LOS_ListEmpty(&(taskCB->joinList))) { - LOS_ListDelete(&(taskCB->joinList)); - taskCB->taskStatus &= ~OS_TASK_FLAG_PTHREAD_JOIN; + if (taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) {//join状态时 + if (LOS_ListEmpty(&(taskCB->joinList))) {//joinlist中没有数据了 + LOS_ListDelete(&(taskCB->joinList));//所谓删除就是自己指向自己 + taskCB->taskStatus &= ~OS_TASK_FLAG_PTHREAD_JOIN;//去掉JOIN标签 return LOS_OK; } /* This error code has a special purpose and is not allowed to appear again on the interface */ @@ -181,39 +254,40 @@ LITE_OS_SEC_TEXT UINT32 OsTaskSetDetachUnsafe(LosTaskCB *taskCB) return LOS_EINVAL; } +//初始化任务模块 LITE_OS_SEC_TEXT_INIT UINT32 OsTaskInit(UINTPTR processCB) { UINT32 index; UINT32 size; UINT32 ret; - g_taskMaxNum = LOSCFG_BASE_CORE_TSK_LIMIT; - size = (g_taskMaxNum + 1) * sizeof(LosTaskCB); + g_taskMaxNum = LOSCFG_BASE_CORE_TSK_LIMIT;//任务池中最多默认128个,可谓铁打的任务池流水的线程 + size = (g_taskMaxNum + 1) * sizeof(LosTaskCB);//计算需分配内存总大小 /* * This memory is resident memory and is used to save the system resources * of task control block and will not be freed. */ - g_taskCBArray = (LosTaskCB *)LOS_MemAlloc(m_aucSysMem0, size); + g_taskCBArray = (LosTaskCB *)LOS_MemAlloc(m_aucSysMem0, size);//任务池常驻内存,不被释放 if (g_taskCBArray == NULL) { ret = LOS_ERRNO_TSK_NO_MEMORY; goto EXIT; } (VOID)memset_s(g_taskCBArray, size, 0, size); - LOS_ListInit(&g_losFreeTask); - LOS_ListInit(&g_taskRecycleList); - for (index = 0; index < g_taskMaxNum; index++) { - g_taskCBArray[index].taskStatus = OS_TASK_STATUS_UNUSED; - g_taskCBArray[index].taskID = index; + LOS_ListInit(&g_losFreeTask);//初始化空闲任务链表 + LOS_ListInit(&g_taskRecycleList);//初始化回收任务链表 + for (index = 0; index < g_taskMaxNum; index++) {//任务挨个初始化 + g_taskCBArray[index].taskStatus = OS_TASK_STATUS_UNUSED;//默认未使用, + g_taskCBArray[index].taskID = index;//任务ID[0~g_taskMaxNum-1] g_taskCBArray[index].processCB = processCB; - LOS_ListTailInsert(&g_losFreeTask, &g_taskCBArray[index].pendList); - } + LOS_ListTailInsert(&g_losFreeTask, &g_taskCBArray[index].pendList);//通过pendlist节点插入空闲任务列表 + }//注意:这里挂的是pendList节点,可以取TCB也要通过OS_TCB_FROM-PENDLIST取 g_taskCBArray[index].taskStatus = OS_TASK_STATUS_UNUSED; g_taskCBArray[index].taskID = index; g_taskCBArray[index].processCB = processCB; - ret = OsSchedInit(); + ret = OsSchedInit();//调度器初始化 EXIT: if (ret != LOS_OK) { @@ -221,41 +295,41 @@ EXIT: } return ret; } - +//获取IdletaskId,每个CPU核都对Task进行了内部管理,做到真正的并行处理 UINT32 OsGetIdleTaskId(VOID) { return OsSchedRunqueueIdleGet()->taskID; } - +//创建一个空闲任务 LITE_OS_SEC_TEXT_INIT UINT32 OsIdleTaskCreate(UINTPTR processID) { UINT32 ret; TSK_INIT_PARAM_S taskInitParam; UINT32 idleTaskID; - (VOID)memset_s((VOID *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); - taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)OsIdleTask; - taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_IDLE_STACK_SIZE; - taskInitParam.pcName = "Idle"; + (VOID)memset_s((VOID *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));//任务初始参数清零 + taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)OsIdleTask;//入口函数 + taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_IDLE_STACK_SIZE;//任务栈大小 2K + taskInitParam.pcName = "Idle";//任务名称叫pcNAME taskInitParam.policy = LOS_SCHED_IDLE; - taskInitParam.usTaskPrio = OS_TASK_PRIORITY_LOWEST; + taskInitParam.usTaskPrio = OS_TASK_PRIORITY_LOWEST;//默认最低优先级31 taskInitParam.processID = processID; #ifdef LOSCFG_KERNEL_SMP - taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); + taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid());//每个idle任务只在单独的CPU上运行 #endif ret = LOS_TaskCreateOnly(&idleTaskID, &taskInitParam); if (ret != LOS_OK) { return ret; } LosTaskCB *idleTask = OS_TCB_FROM_TID(idleTaskID); - idleTask->taskStatus |= OS_TASK_FLAG_SYSTEM_TASK; + idleTask->taskStatus |= OS_TASK_FLAG_SYSTEM_TASK;//标记为系统任务,idle任务是给CPU休息用的,当然是个系统任务 OsSchedRunqueueIdleInit(idleTask); return LOS_TaskResume(idleTaskID); } /* - * Description : get id of current running task. + * Description : get id of current running task. |获取当前CPU正在执行的任务ID * Return : task id */ LITE_OS_SEC_TEXT UINT32 LOS_CurTaskIDGet(VOID) @@ -267,7 +341,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_CurTaskIDGet(VOID) } return runTask->taskID; } - +//创建指定任务同步信号量 STATIC INLINE UINT32 TaskSyncCreate(LosTaskCB *taskCB) { #ifdef LOSCFG_KERNEL_SMP_TASK_SYNC @@ -280,7 +354,7 @@ STATIC INLINE UINT32 TaskSyncCreate(LosTaskCB *taskCB) #endif return LOS_OK; } - +//销毁指定任务同步信号量 STATIC INLINE VOID OsTaskSyncDestroy(UINT32 syncSignal) { #ifdef LOSCFG_KERNEL_SMP_TASK_SYNC @@ -291,6 +365,7 @@ STATIC INLINE VOID OsTaskSyncDestroy(UINT32 syncSignal) } #ifdef LOSCFG_KERNEL_SMP +//任务同步等待,通过信号量保持同步 STATIC INLINE UINT32 OsTaskSyncWait(const LosTaskCB *taskCB) { #ifdef LOSCFG_KERNEL_SMP_TASK_SYNC @@ -316,7 +391,7 @@ STATIC INLINE UINT32 OsTaskSyncWait(const LosTaskCB *taskCB) #endif } #endif - +//同步唤醒 STATIC INLINE VOID OsTaskSyncWake(const LosTaskCB *taskCB) { #ifdef LOSCFG_KERNEL_SMP_TASK_SYNC @@ -338,14 +413,14 @@ STATIC INLINE VOID OsInsertTCBToFreeList(LosTaskCB *taskCB) taskCB->taskStatus = OS_TASK_STATUS_UNUSED; LOS_ListAdd(&g_losFreeTask, &taskCB->pendList); } - +//释放任务在内核状态下占用的资源 STATIC VOID OsTaskKernelResourcesToFree(UINT32 syncSignal, UINTPTR topOfStack) { - OsTaskSyncDestroy(syncSignal); + OsTaskSyncDestroy(syncSignal);//任务销毁,同步信息 - (VOID)LOS_MemFree((VOID *)m_aucSysMem1, (VOID *)topOfStack); + (VOID)LOS_MemFree((VOID *)m_aucSysMem1, (VOID *)topOfStack);//释放内核态空间 } - +//释放任务资源 STATIC VOID OsTaskResourcesToFree(LosTaskCB *taskCB) { UINT32 syncSignal = LOSCFG_BASE_IPC_SEM_LIMIT; @@ -353,7 +428,7 @@ STATIC VOID OsTaskResourcesToFree(LosTaskCB *taskCB) UINTPTR topOfStack; #ifdef LOSCFG_KERNEL_VM - if ((taskCB->taskStatus & OS_TASK_FLAG_USER_MODE) && (taskCB->userMapBase != 0)) { + if ((taskCB->taskStatus & OS_TASK_FLAG_USER_MODE) && (taskCB->userMapBase != 0)) {//释放用户态栈 SCHEDULER_LOCK(intSave); UINT32 mapBase = (UINTPTR)taskCB->userMapBase; UINT32 mapSize = taskCB->userMapSize; @@ -363,7 +438,7 @@ STATIC VOID OsTaskResourcesToFree(LosTaskCB *taskCB) LosProcessCB *processCB = OS_PCB_FROM_TCB(taskCB); LOS_ASSERT(!(OsProcessVmSpaceGet(processCB) == NULL)); - UINT32 ret = OsUnMMap(OsProcessVmSpaceGet(processCB), (UINTPTR)mapBase, mapSize); + UINT32 ret = OsUnMMap(OsProcessVmSpaceGet(processCB), (UINTPTR)mapBase, mapSize);//解除映射 if ((ret != LOS_OK) && (mapBase != 0) && !OsProcessIsInit(processCB)) { PRINT_ERR("process(%u) unmmap user task(%u) stack failed! mapbase: 0x%x size :0x%x, error: %d\n", processCB->processID, taskCB->taskID, mapBase, mapSize, ret); @@ -375,36 +450,36 @@ STATIC VOID OsTaskResourcesToFree(LosTaskCB *taskCB) } #endif - if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { + if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {//任务还未使用情况 topOfStack = taskCB->topOfStack; taskCB->topOfStack = 0; #ifdef LOSCFG_KERNEL_SMP_TASK_SYNC syncSignal = taskCB->syncSignal; taskCB->syncSignal = LOSCFG_BASE_IPC_SEM_LIMIT; #endif - OsTaskKernelResourcesToFree(syncSignal, topOfStack); + OsTaskKernelResourcesToFree(syncSignal, topOfStack);//释放内核所占内存,即内核栈的栈空间 SCHEDULER_LOCK(intSave); #ifdef LOSCFG_KERNEL_VM - OsClearSigInfoTmpList(&(taskCB->sig)); + OsClearSigInfoTmpList(&(taskCB->sig));//归还信号控制块的内存 #endif OsInsertTCBToFreeList(taskCB); SCHEDULER_UNLOCK(intSave); } return; } - +//批量回收任务 LITE_OS_SEC_TEXT VOID OsTaskCBRecycleToFree(void) { UINT32 intSave; SCHEDULER_LOCK(intSave); - while (!LOS_ListEmpty(&g_taskRecycleList)) { - LosTaskCB *taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_taskRecycleList)); - LOS_ListDelete(&taskCB->pendList); + while (!LOS_ListEmpty(&g_taskRecycleList)) {//遍历回收链表 + LosTaskCB *taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_taskRecycleList));//取出任务 + LOS_ListDelete(&taskCB->pendList);//重置节点 SCHEDULER_UNLOCK(intSave); - OsTaskResourcesToFree(taskCB); + OsTaskResourcesToFree(taskCB);//释放任务所占资源 SCHEDULER_LOCK(intSave); } @@ -414,7 +489,7 @@ LITE_OS_SEC_TEXT VOID OsTaskCBRecycleToFree(void) /* * Description : All task entry * Input : taskID --- The ID of the task to be run - */ + *///所有任务的入口函数,OsTaskEntry是new task OsTaskStackInit时指定的 LITE_OS_SEC_TEXT_INIT VOID OsTaskEntry(UINT32 taskID) { LOS_ASSERT(!OS_TID_CHECK_INVALID(taskID)); @@ -424,19 +499,19 @@ LITE_OS_SEC_TEXT_INIT VOID OsTaskEntry(UINT32 taskID) * from interrupt and other cores. release task spinlock and enable * interrupt in sequence at the task entry. */ - LOS_SpinUnlock(&g_taskSpin); - (VOID)LOS_IntUnLock(); + LOS_SpinUnlock(&g_taskSpin);//释放任务自旋锁 + (VOID)LOS_IntUnLock();//恢复中断 LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID); - taskCB->joinRetval = taskCB->taskEntry(taskCB->args[0], taskCB->args[1], + taskCB->joinRetval = taskCB->taskEntry(taskCB->args[0], taskCB->args[1],//调出任务的入口函数 taskCB->args[2], taskCB->args[3]); /* 2 & 3: just for args array index */ if (!(taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN)) { - taskCB->joinRetval = 0; + taskCB->joinRetval = 0;//结合数为0 } OsRunningTaskToExit(taskCB, 0); } - +//任务创建参数检查 STATIC UINT32 TaskCreateParamCheck(const UINT32 *taskID, TSK_INIT_PARAM_S *initParam) { UINT32 poolSize = OS_SYS_MEM_SIZE; @@ -455,30 +530,30 @@ STATIC UINT32 TaskCreateParamCheck(const UINT32 *taskID, TSK_INIT_PARAM_S *initP } } - if (initParam->pfnTaskEntry == NULL) { + if (initParam->pfnTaskEntry == NULL) {//入口函数不能为空 return LOS_ERRNO_TSK_ENTRY_NULL; } - if (initParam->usTaskPrio > OS_TASK_PRIORITY_LOWEST) { + if (initParam->usTaskPrio > OS_TASK_PRIORITY_LOWEST) {//优先级必须大于31 return LOS_ERRNO_TSK_PRIOR_ERROR; } - if (initParam->uwStackSize > poolSize) { + if (initParam->uwStackSize > poolSize) {//希望申请的栈大小不能大于总池子 return LOS_ERRNO_TSK_STKSZ_TOO_LARGE; } - if (initParam->uwStackSize == 0) { + if (initParam->uwStackSize == 0) {//任何任务都必须由内核态栈,所以uwStackSize不能为0 initParam->uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; } initParam->uwStackSize = (UINT32)ALIGN(initParam->uwStackSize, LOSCFG_STACK_POINT_ALIGN_SIZE); - if (initParam->uwStackSize < LOS_TASK_MIN_STACK_SIZE) { + if (initParam->uwStackSize < LOS_TASK_MIN_STACK_SIZE) {//运行栈空间不能低于最低值 return LOS_ERRNO_TSK_STKSZ_TOO_SMALL; } return LOS_OK; } - +//任务栈(内核态)内存分配,由内核态进程空间提供,即KProcess进程空间 STATIC VOID TaskCBDeInit(LosTaskCB *taskCB) { UINT32 intSave; @@ -531,13 +606,13 @@ STATIC VOID TaskCBBaseInit(LosTaskCB *taskCB, const TSK_INIT_PARAM_S *initParam) LOS_ListInit(&taskCB->joinList); } - LOS_ListInit(&taskCB->lockList); + LOS_ListInit(&taskCB->lockList);//初始化互斥锁链表 SET_SORTLIST_VALUE(&taskCB->sortList, OS_SORT_LINK_INVALID_TIME); #ifdef LOSCFG_KERNEL_VM taskCB->futex.index = OS_INVALID_VALUE; #endif } - +//任务初始化 STATIC UINT32 TaskCBInit(LosTaskCB *taskCB, const TSK_INIT_PARAM_S *initParam) { UINT32 ret; @@ -546,7 +621,7 @@ STATIC UINT32 TaskCBInit(LosTaskCB *taskCB, const TSK_INIT_PARAM_S *initParam) LosSchedParam initSchedParam = {0}; UINT16 policy = (initParam->policy == LOS_SCHED_NORMAL) ? LOS_SCHED_RR : initParam->policy; - TaskCBBaseInit(taskCB, initParam); + TaskCBBaseInit(taskCB, initParam);//初始化任务的基本信息,task->stackPointer指向内核态栈sp位置,该位置存着任务初始上下文 schedParam.policy = policy; ret = OsProcessAddNewTask(initParam->processID, taskCB, &schedParam, &numCount); @@ -598,25 +673,27 @@ STATIC UINT32 TaskStackInit(LosTaskCB *taskCB, const TSK_INIT_PARAM_S *initParam #endif return LOS_OK; } - +//获取一个空闲TCB STATIC LosTaskCB *GetFreeTaskCB(VOID) { UINT32 intSave; SCHEDULER_LOCK(intSave); - if (LOS_ListEmpty(&g_losFreeTask)) { + if (LOS_ListEmpty(&g_losFreeTask)) {//全局空闲task为空 SCHEDULER_UNLOCK(intSave); PRINT_ERR("No idle TCB in the system!\n"); return NULL; } LosTaskCB *taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_losFreeTask)); - LOS_ListDelete(LOS_DL_LIST_FIRST(&g_losFreeTask)); + LOS_ListDelete(LOS_DL_LIST_FIRST(&g_losFreeTask));//从g_losFreeTask链表中摘除自己 SCHEDULER_UNLOCK(intSave); return taskCB; } - +/* +创建任务,并使该任务进入suspend状态,不对该状态进行调度。如果需要调度,可以调用LOS_TaskResume使该任务进入ready状态 +*/ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreateOnly(UINT32 *taskID, TSK_INIT_PARAM_S *initParam) { UINT32 errRet = TaskCreateParamCheck(taskID, initParam); @@ -656,7 +733,7 @@ DEINIT_TCB: TaskCBDeInit(taskCB); return errRet; } - +//创建任务,并使该任务进入ready状态,如果就绪队列中没有更高优先级的任务,则运行该任务 LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreate(UINT32 *taskID, TSK_INIT_PARAM_S *initParam) { UINT32 ret; @@ -670,7 +747,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreate(UINT32 *taskID, TSK_INIT_PARAM_S *in return LOS_ERRNO_TSK_YIELD_IN_INT; } - if (OsProcessIsUserMode(OsCurrProcessGet())) { + if (OsProcessIsUserMode(OsCurrProcessGet())) {//当前进程为用户进程 initParam->processID = (UINTPTR)OsGetKernelInitProcess(); } else { initParam->processID = (UINTPTR)OsCurrProcessGet(); @@ -696,7 +773,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreate(UINT32 *taskID, TSK_INIT_PARAM_S *in return LOS_OK; } - +//恢复挂起的任务,是该任务进入ready状态 LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskResume(UINT32 taskID) { UINT32 intSave; @@ -711,7 +788,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskResume(UINT32 taskID) SCHEDULER_LOCK(intSave); /* clear pending signal */ - taskCB->signal &= ~SIGNAL_SUSPEND; + taskCB->signal &= ~SIGNAL_SUSPEND;//清楚挂起信号 if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { errRet = LOS_ERRNO_TSK_NOT_CREATED; @@ -737,13 +814,13 @@ LOS_ERREND: } /* - * Check if needs to do the suspend operation on the running task. - * Return TRUE, if needs to do the suspension. - * Return FALSE, if meets following circumstances: - * 1. Do the suspension across cores, if SMP is enabled - * 2. Do the suspension when preemption is disabled - * 3. Do the suspension in hard-irq - * then LOS_TaskSuspend will directly return with 'ret' value. + * Check if needs to do the suspend operation on the running task.//检查是否需要对正在运行的任务执行挂起操作。 + * Return TRUE, if needs to do the suspension. //如果需要暂停,返回TRUE。 + * Return FALSE, if meets following circumstances: //如果满足一下情况,则返回FALSE: + * 1. Do the suspension across cores, if SMP is enabled //1.如果启用了SMP,则跨CPU核执行挂起操作 + * 2. Do the suspension when preemption is disabled //2.当禁用抢占时则挂起 + * 3. Do the suspension in hard-irq //3.在硬中断时则挂起 + * then LOS_TaskSuspend will directly return with 'ret' value. //那么LOS_taskssuspend将直接返回ret值。 */ LITE_OS_SEC_TEXT_INIT STATIC BOOL OsTaskSuspendCheckOnRun(LosTaskCB *taskCB, UINT32 *ret) { @@ -752,20 +829,20 @@ LITE_OS_SEC_TEXT_INIT STATIC BOOL OsTaskSuspendCheckOnRun(LosTaskCB *taskCB, UIN #ifdef LOSCFG_KERNEL_SMP /* ASYNCHRONIZED. No need to do task lock checking */ - if (taskCB->currCpu != ArchCurrCpuid()) { + if (taskCB->currCpu != ArchCurrCpuid()) {//跨CPU核的情况 taskCB->signal = SIGNAL_SUSPEND; - LOS_MpSchedule(taskCB->currCpu); + LOS_MpSchedule(taskCB->currCpu);//task所属CPU执行调度 return FALSE; } #endif - if (!OsPreemptableInSched()) { + if (!OsPreemptableInSched()) {//不能抢占时 /* Suspending the current core's running task */ *ret = LOS_ERRNO_TSK_SUSPEND_LOCKED; return FALSE; } - if (OS_INT_ACTIVE) { + if (OS_INT_ACTIVE) {//正在硬抢断时 /* suspend running task in interrupt */ taskCB->signal = SIGNAL_SUSPEND; return FALSE; @@ -773,7 +850,7 @@ LITE_OS_SEC_TEXT_INIT STATIC BOOL OsTaskSuspendCheckOnRun(LosTaskCB *taskCB, UIN return TRUE; } - +//任务暂停,参数可以不是当前任务,也就是说A任务可以让B任务处于阻塞状态,挂起指定的任务,然后切换任务 LITE_OS_SEC_TEXT STATIC UINT32 OsTaskSuspend(LosTaskCB *taskCB) { UINT32 errRet; @@ -786,14 +863,14 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsTaskSuspend(LosTaskCB *taskCB) return LOS_ERRNO_TSK_ALREADY_SUSPENDED; } - if ((tempStatus & OS_TASK_STATUS_RUNNING) && - !OsTaskSuspendCheckOnRun(taskCB, &errRet)) { + if ((tempStatus & OS_TASK_STATUS_RUNNING) &&//如果参数任务正在运行,注意多Cpu core情况,贴着正在运行标签的任务并不一定是当前CPU的执行任务, + !OsTaskSuspendCheckOnRun(taskCB, &errRet)) {//很有可能是别的CPU core在跑的任务 return errRet; } return taskCB->ops->suspend(taskCB); } - +//外部接口,对OsTaskSuspend的封装 LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskSuspend(UINT32 taskID) { UINT32 intSave; @@ -813,7 +890,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskSuspend(UINT32 taskID) SCHEDULER_UNLOCK(intSave); return errRet; } - +//设置任务为不使用状态 STATIC INLINE VOID OsTaskStatusUnusedSet(LosTaskCB *taskCB) { taskCB->taskStatus |= OS_TASK_STATUS_UNUSED; @@ -959,7 +1036,7 @@ LOS_ERREND: } return ret; } - +//任务延时等待,释放CPU,等待时间到期后该任务会重新进入ready状态 LITE_OS_SEC_TEXT UINT32 LOS_TaskDelay(UINT32 tick) { UINT32 intSave; @@ -989,7 +1066,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_TaskDelay(UINT32 tick) SCHEDULER_UNLOCK(intSave); return ret; } - +//获取任务的优先级 LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskPriGet(UINT32 taskID) { UINT32 intSave; @@ -1010,7 +1087,7 @@ LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskPriGet(UINT32 taskID) SCHEDULER_UNLOCK(intSave); return param.priority; } - +//设置指定任务的优先级 LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskPriSet(UINT32 taskID, UINT16 taskPrio) { UINT32 intSave; @@ -1048,12 +1125,12 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskPriSet(UINT32 taskID, UINT16 taskPrio) } return LOS_OK; } - +//设置当前任务的优先级 LITE_OS_SEC_TEXT_MINOR UINT32 LOS_CurTaskPriSet(UINT16 taskPrio) { return LOS_TaskPriSet(OsCurrTaskGet()->taskID, taskPrio); } - +//当前任务释放CPU,并将其移到具有相同优先级的就绪任务队列的末尾。 LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskYield(VOID) { UINT32 intSave; @@ -1099,7 +1176,7 @@ LITE_OS_SEC_TEXT_MINOR VOID LOS_TaskUnlock(VOID) LOS_Schedule(); } } - +//获取任务信息,给shell使用的 LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskInfoGet(UINT32 taskID, TSK_INFO_S *taskInfo) { UINT32 intSave; @@ -1129,8 +1206,8 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskInfoGet(UINT32 taskID, TSK_INFO_S *taskInf taskCB->ops->schedParamGet(taskCB, ¶m); taskInfo->usTaskStatus = taskCB->taskStatus; taskInfo->usTaskPrio = param.priority; - taskInfo->uwStackSize = taskCB->stackSize; - taskInfo->uwTopOfStack = taskCB->topOfStack; + taskInfo->uwStackSize = taskCB->stackSize;//内核态栈大小 + taskInfo->uwTopOfStack = taskCB->topOfStack;//内核态栈顶位置 taskInfo->uwEventMask = taskCB->eventMask; taskInfo->taskEvent = taskCB->taskEvent; taskInfo->pTaskMux = taskCB->taskMux; @@ -1141,16 +1218,16 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskInfoGet(UINT32 taskID, TSK_INFO_S *taskInf } taskInfo->acName[LOS_TASK_NAMELEN - 1] = '\0'; - taskInfo->uwBottomOfStack = TRUNCATE(((UINTPTR)taskCB->topOfStack + taskCB->stackSize), + taskInfo->uwBottomOfStack = TRUNCATE(((UINTPTR)taskCB->topOfStack + taskCB->stackSize),//这里可以看出栈顶地址是高于栈顶 OS_TASK_STACK_ADDR_ALIGN); - taskInfo->uwCurrUsed = (UINT32)(taskInfo->uwBottomOfStack - taskInfo->uwSP); + taskInfo->uwCurrUsed = (UINT32)(taskInfo->uwBottomOfStack - taskInfo->uwSP);//当前任务栈已使用了多少 - taskInfo->bOvf = OsStackWaterLineGet((const UINTPTR *)taskInfo->uwBottomOfStack, + taskInfo->bOvf = OsStackWaterLineGet((const UINTPTR *)taskInfo->uwBottomOfStack,//获取栈的使用情况 (const UINTPTR *)taskInfo->uwTopOfStack, &taskInfo->uwPeakUsed); SCHEDULER_UNLOCK(intSave); return LOS_OK; } - +//CPU亲和性(affinity)将任务绑定在指定CPU上,用于多核CPU情况,(该函数仅在SMP模式下支持) LITE_OS_SEC_TEXT BOOL OsTaskCpuAffiSetUnsafe(UINT32 taskID, UINT16 newCpuAffiMask, UINT16 *oldCpuAffiMask) { #ifdef LOSCFG_KERNEL_SMP @@ -1176,17 +1253,17 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskCpuAffiSet(UINT32 taskID, UINT16 cpuAffiMa UINT32 intSave; UINT16 currCpuMask; - if (OS_TID_CHECK_INVALID(taskID)) { + if (OS_TID_CHECK_INVALID(taskID)) {//检测taskid是否有效,task由task池分配,鸿蒙默认128个任务 ID范围[0:127] return LOS_ERRNO_TSK_ID_INVALID; } - if (!(cpuAffiMask & LOSCFG_KERNEL_CPU_MASK)) { + if (!(cpuAffiMask & LOSCFG_KERNEL_CPU_MASK)) {//检测cpu亲和力 return LOS_ERRNO_TSK_CPU_AFFINITY_MASK_ERR; } LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID); SCHEDULER_LOCK(intSave); - if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { + if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {//贴有未使用标签的处理 SCHEDULER_UNLOCK(intSave); return LOS_ERRNO_TSK_NOT_CREATED; } @@ -1194,13 +1271,13 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskCpuAffiSet(UINT32 taskID, UINT16 cpuAffiMa SCHEDULER_UNLOCK(intSave); if (needSched && OS_SCHEDULER_ACTIVE) { - LOS_MpSchedule(currCpuMask); - LOS_Schedule(); + LOS_MpSchedule(currCpuMask);//发送信号调度信号给目标cpu + LOS_Schedule();//申请调度 } return LOS_OK; } - +//查询任务被绑在哪个cpu上 LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskCpuAffiGet(UINT32 taskID) { #ifdef LOSCFG_KERNEL_SMP @@ -1214,18 +1291,18 @@ LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskCpuAffiGet(UINT32 taskID) LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID); SCHEDULER_LOCK(intSave); - if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { + if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {//任务必须在使用 SCHEDULER_UNLOCK(intSave); return INVALID_CPU_AFFI_MASK; } - cpuAffiMask = taskCB->cpuAffiMask; + cpuAffiMask = taskCB->cpuAffiMask;//获取亲和力掩码 SCHEDULER_UNLOCK(intSave); return cpuAffiMask; #else (VOID)taskID; - return 1; + return 1;//单核情况直接返回1,0号cpu对应0x01 #endif } @@ -1235,14 +1312,14 @@ LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskCpuAffiGet(UINT32 taskID) LITE_OS_SEC_TEXT_MINOR VOID OsTaskProcSignal(VOID) { UINT32 ret; - + //私有且不可中断,无需保护。这个任务在其他cpu核看到它时总是在运行,所以它在执行代码的同时也可以继续接收信号 /* * private and uninterruptable, no protection needed. * while this task is always running when others cores see it, * so it keeps receiving signals while follow code executing. */ LosTaskCB *runTask = OsCurrTaskGet(); - if (runTask->signal == SIGNAL_NONE) { + if (runTask->signal == SIGNAL_NONE) {//意思是其他cpu发起了要干掉你的信号 return; } @@ -1250,23 +1327,23 @@ LITE_OS_SEC_TEXT_MINOR VOID OsTaskProcSignal(VOID) /* * clear the signal, and do the task deletion. if the signaled task has been * scheduled out, then this deletion will wait until next run. - */ - runTask->signal = SIGNAL_NONE; + *///如果发出信号的任务以出调度就绪队列,则此删除将等待下次运行 + runTask->signal = SIGNAL_NONE;//清除信号 ret = LOS_TaskDelete(runTask->taskID); if (ret != LOS_OK) { PRINT_ERR("Task proc signal delete task(%u) failed err:0x%x\n", runTask->taskID, ret); } - } else if (runTask->signal & SIGNAL_SUSPEND) { - runTask->signal &= ~SIGNAL_SUSPEND; + } else if (runTask->signal & SIGNAL_SUSPEND) {//意思是其他cpu发起了要挂起你的信号 + runTask->signal &= ~SIGNAL_SUSPEND;//任务贴在被其他cpu挂起的标签 /* suspend killed task may fail, ignore the result */ (VOID)LOS_TaskSuspend(runTask->taskID); #ifdef LOSCFG_KERNEL_SMP - } else if (runTask->signal & SIGNAL_AFFI) { - runTask->signal &= ~SIGNAL_AFFI; + } else if (runTask->signal & SIGNAL_AFFI) {//意思是下次调度其他cpu要媾和你 + runTask->signal &= ~SIGNAL_AFFI;//任务贴上被其他CPU媾和的标签 /* priority queue has updated, notify the target cpu */ - LOS_MpSchedule((UINT32)runTask->cpuAffiMask); + LOS_MpSchedule((UINT32)runTask->cpuAffiMask);//发生调度,此任务将移交给媾和CPU运行. #endif } } @@ -1339,7 +1416,7 @@ INT32 OsUserProcessOperatePermissionsCheck(const LosTaskCB *taskCB, UINTPTR proc return LOS_OK; } - +//创建任务之前,检查用户态任务栈的参数,是否地址在用户空间 LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsCreateUserTaskParamCheck(UINT32 processID, TSK_INIT_PARAM_S *param) { UserTaskParam *userParam = NULL; @@ -1349,25 +1426,25 @@ LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsCreateUserTaskParamCheck(UINT32 processID, } userParam = ¶m->userParam; - if ((processID == OS_INVALID_VALUE) && !LOS_IsUserAddress(userParam->userArea)) { + if ((processID == OS_INVALID_VALUE) && !LOS_IsUserAddress(userParam->userArea)) {//堆地址必须在用户空间 return OS_INVALID_VALUE; } - if (!LOS_IsUserAddress((UINTPTR)param->pfnTaskEntry)) { + if (!LOS_IsUserAddress((UINTPTR)param->pfnTaskEntry)) {//入口函数必须在用户空间 return OS_INVALID_VALUE; } - + //堆栈必须在用户空间 if (userParam->userMapBase && !LOS_IsUserAddressRange(userParam->userMapBase, userParam->userMapSize)) { return OS_INVALID_VALUE; } - + //检查堆,栈范围 if (!LOS_IsUserAddress(userParam->userSP)) { return OS_INVALID_VALUE; } return LOS_OK; } - +//创建一个用户态任务 LITE_OS_SEC_TEXT_INIT UINT32 OsCreateUserTask(UINTPTR processID, TSK_INIT_PARAM_S *initParam) { UINT32 taskID; @@ -1376,18 +1453,18 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsCreateUserTask(UINTPTR processID, TSK_INIT_PARAM_ INT32 policy; SchedParam param; - ret = OsCreateUserTaskParamCheck(processID, initParam); + ret = OsCreateUserTaskParamCheck(processID, initParam);//检查参数,堆栈,入口地址必须在用户空间 if (ret != LOS_OK) { return ret; } - + //这里可看出一个任务有两个栈,内核态栈(内核指定栈大小)和用户态栈(用户指定栈大小) initParam->uwStackSize = OS_USER_TASK_SYSCALL_STACK_SIZE; - initParam->usTaskPrio = OS_TASK_PRIORITY_LOWEST; - if (processID == OS_INVALID_VALUE) { + initParam->usTaskPrio = OS_TASK_PRIORITY_LOWEST;//设置最低优先级31级 + if (processID == OS_INVALID_VALUE) {//外面没指定进程ID的处理 SCHEDULER_LOCK(intSave); LosProcessCB *processCB = OsCurrProcessGet(); initParam->processID = (UINTPTR)processCB; - initParam->consoleID = processCB->consoleID; + initParam->consoleID = processCB->consoleID;//任务控制台ID归属 SCHEDULER_UNLOCK(intSave); ret = LOS_GetProcessScheduler(processCB->processID, &policy, NULL); if (ret != LOS_OK) { @@ -1400,20 +1477,20 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsCreateUserTask(UINTPTR processID, TSK_INIT_PARAM_ initParam->deadlineUs = param.deadlineUs; initParam->periodUs = param.periodUs; } - } else { - initParam->policy = LOS_SCHED_RR; - initParam->processID = processID; - initParam->consoleID = 0; + } else {//进程已经创建 + initParam->policy = LOS_SCHED_RR;//调度方式为抢占式,注意鸿蒙不仅仅只支持抢占式调度方式 + initParam->processID = processID;//进程ID赋值 + initParam->consoleID = 0;//默认0号控制台 } - ret = LOS_TaskCreateOnly(&taskID, initParam); + ret = LOS_TaskCreateOnly(&taskID, initParam);//只创建task实体,不申请调度 if (ret != LOS_OK) { return OS_INVALID_VALUE; } return taskID; } - +//获取任务的调度方式 LITE_OS_SEC_TEXT INT32 LOS_GetTaskScheduler(INT32 taskID) { UINT32 intSave; @@ -1426,7 +1503,7 @@ LITE_OS_SEC_TEXT INT32 LOS_GetTaskScheduler(INT32 taskID) LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID); SCHEDULER_LOCK(intSave); - if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { + if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {//任务不能是没有在使用 policy = -LOS_EINVAL; OS_GOTO_ERREND(); } @@ -1438,7 +1515,7 @@ LOS_ERREND: SCHEDULER_UNLOCK(intSave); return policy; } - +//设置任务的调度信息 LITE_OS_SEC_TEXT INT32 LOS_SetTaskScheduler(INT32 taskID, UINT16 policy, UINT16 priority) { SchedParam param = { 0 }; @@ -1582,12 +1659,12 @@ UINT32 LOS_TaskDetach(UINT32 taskID) SCHEDULER_UNLOCK(intSave); return errRet; } - +//获取最大任务数 LITE_OS_SEC_TEXT UINT32 LOS_GetSystemTaskMaximum(VOID) { return g_taskMaxNum; } - +//任务池中最后一个 LosTaskCB *OsGetDefaultTaskCB(VOID) { return &g_taskCBArray[g_taskMaxNum]; @@ -1602,44 +1679,44 @@ LITE_OS_SEC_TEXT VOID OsWriteResourceEventUnsafe(UINT32 events) { (VOID)OsEventWriteUnsafe(&g_resourceEvent, events, FALSE, NULL); } - +//资源回收任务 STATIC VOID OsResourceRecoveryTask(VOID) { UINT32 ret; - while (1) { + while (1) {//死循环,回收资源不存在退出情况,只要系统在运行资源就需要回收 ret = LOS_EventRead(&g_resourceEvent, OS_RESOURCE_EVENT_MASK, - LOS_WAITMODE_OR | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER); - if (ret & (OS_RESOURCE_EVENT_FREE | OS_RESOURCE_EVENT_OOM)) { + LOS_WAITMODE_OR | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER);//读取资源事件 + if (ret & (OS_RESOURCE_EVENT_FREE | OS_RESOURCE_EVENT_OOM)) {//收到资源释放或内存异常情况 OsTaskCBRecycleToFree(); - OsProcessCBRecycleToFree(); + OsProcessCBRecycleToFree();//回收进程到空闲进程池 } -#ifdef LOSCFG_ENABLE_OOM_LOOP_TASK - if (ret & OS_RESOURCE_EVENT_OOM) { - (VOID)OomCheckProcess(); +#ifdef LOSCFG_ENABLE_OOM_LOOP_TASK//内存溢出检测任务开关 + if (ret & OS_RESOURCE_EVENT_OOM) {//触发了这个事件 + (VOID)OomCheckProcess();//检查进程的内存溢出情况 } #endif } } - +//创建一个回收资源的任务 LITE_OS_SEC_TEXT UINT32 OsResourceFreeTaskCreate(VOID) { UINT32 ret; UINT32 taskID; TSK_INIT_PARAM_S taskInitParam; - ret = LOS_EventInit((PEVENT_CB_S)&g_resourceEvent); + ret = LOS_EventInit((PEVENT_CB_S)&g_resourceEvent);//初始化资源事件 if (ret != LOS_OK) { return LOS_NOK; } (VOID)memset_s((VOID *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); - taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)OsResourceRecoveryTask; + taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)OsResourceRecoveryTask;//入口函数 taskInitParam.uwStackSize = OS_TASK_RESOURCE_STATIC_SIZE; taskInitParam.pcName = "ResourcesTask"; - taskInitParam.usTaskPrio = OS_TASK_RESOURCE_FREE_PRIORITY; + taskInitParam.usTaskPrio = OS_TASK_RESOURCE_FREE_PRIORITY;//5,优先级很高 ret = LOS_TaskCreate(&taskID, &taskInitParam); if (ret == LOS_OK) { OS_TCB_FROM_TID(taskID)->taskStatus |= OS_TASK_FLAG_NO_DELETE; @@ -1647,5 +1724,5 @@ LITE_OS_SEC_TEXT UINT32 OsResourceFreeTaskCreate(VOID) return ret; } -LOS_MODULE_INIT(OsResourceFreeTaskCreate, LOS_INIT_LEVEL_KMOD_TASK); +LOS_MODULE_INIT(OsResourceFreeTaskCreate, LOS_INIT_LEVEL_KMOD_TASK);//资源回收任务初始化 diff --git a/src/kernel_liteos_a/kernel/base/core/los_tick.c b/src/kernel_liteos_a/kernel/base/core/los_tick.c index b5c2794e..4e9c4575 100644 --- a/src/kernel_liteos_a/kernel/base/core/los_tick.c +++ b/src/kernel_liteos_a/kernel/base/core/los_tick.c @@ -37,30 +37,30 @@ #endif -LITE_OS_SEC_DATA_INIT UINT32 g_sysClock; -LITE_OS_SEC_DATA_INIT UINT32 g_tickPerSecond; -LITE_OS_SEC_BSS DOUBLE g_cycle2NsScale; +LITE_OS_SEC_DATA_INIT UINT32 g_sysClock; //系统时钟,绝大部分部件工作的时钟源,以及所有外设的始终来源 +LITE_OS_SEC_DATA_INIT UINT32 g_tickPerSecond; //每秒Tick数,harmony默认为每秒100次即10ms +LITE_OS_SEC_BSS DOUBLE g_cycle2NsScale; //将周期转为纳秒级 /* spinlock for task module */ -LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_tickSpin); +LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_tickSpin); //节拍器自旋锁 /* * Description : Tick interruption handler */ -LITE_OS_SEC_TEXT VOID OsTickHandler(VOID) +LITE_OS_SEC_TEXT VOID OsTickHandler(VOID)//节拍中断处理函数,harmony默认1ms触发一次 { #ifdef LOSCFG_SCHED_TICK_DEBUG OsSchedDebugRecordData(); #endif #ifdef LOSCFG_KERNEL_VDSO - OsVdsoTimevalUpdate(); + OsVdsoTimevalUpdate(); //更新vdso数据页时间,vsdo可以直接在用户进程空间绕过系统调用获取系统时间 #endif #ifdef LOSCFG_BASE_CORE_TICK_HW_TIME HalClockIrqClear(); /* diff from every platform */ #endif - OsSchedTick(); + OsSchedTick();//由时钟发起的调度 } From 9bf0bf86d999b4abee40875cb82f9569caaf1292 Mon Sep 17 00:00:00 2001 From: Dio Date: Fri, 19 Jan 2024 09:51:30 +0800 Subject: [PATCH 20/33] =?UTF-8?q?mp=E6=96=87=E4=BB=B6=E5=A4=B9=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E5=B0=B1=E5=B0=B1=E5=B0=B1=E4=BD=8D=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kernel_liteos_a/kernel/base/mp/los_mp.c | 80 ++++++++++--------- .../kernel/base/mp/los_percpu.c | 2 +- 2 files changed, 45 insertions(+), 37 deletions(-) diff --git a/src/kernel_liteos_a/kernel/base/mp/los_mp.c b/src/kernel_liteos_a/kernel/base/mp/los_mp.c index 67bc7012..e2a13431 100644 --- a/src/kernel_liteos_a/kernel/base/mp/los_mp.c +++ b/src/kernel_liteos_a/kernel/base/mp/los_mp.c @@ -36,43 +36,43 @@ #include "los_swtmr.h" #include "los_task_pri.h" -#ifdef LOSCFG_KERNEL_SMP +#ifdef LOSCFG_KERNEL_SMP +//给参数CPU发送调度信号 #ifdef LOSCFG_KERNEL_SMP_CALL LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_mpCallSpin); #define MP_CALL_LOCK(state) LOS_SpinLockSave(&g_mpCallSpin, &(state)) #define MP_CALL_UNLOCK(state) LOS_SpinUnlockRestore(&g_mpCallSpin, (state)) #endif - -VOID LOS_MpSchedule(UINT32 target) +VOID LOS_MpSchedule(UINT32 target)//target每位对应CPU core { UINT32 cpuid = ArchCurrCpuid(); - target &= ~(1U << cpuid); - HalIrqSendIpi(target, LOS_MP_IPI_SCHEDULE); + target &= ~(1U << cpuid);//获取除了自身之外的其他CPU + HalIrqSendIpi(target, LOS_MP_IPI_SCHEDULE);//向目标CPU发送调度信号,核间中断(Inter-Processor Interrupts),IPI } - +///硬中断唤醒处理函数 VOID OsMpWakeHandler(VOID) { /* generic wakeup ipi, do nothing */ } - +///硬中断调度处理函数 VOID OsMpScheduleHandler(VOID) -{ +{//将调度标志设置为与唤醒功能不同,这样就可以在硬中断结束时触发调度程序。 /* * set schedule flag to differ from wake function, * so that the scheduler can be triggered at the end of irq. */ OsSchedRunqueuePendingSet(); } - +///硬中断暂停处理函数 VOID OsMpHaltHandler(VOID) { (VOID)LOS_IntLock(); - OsPercpuGet()->excFlag = CPU_HALT; + OsPercpuGet()->excFlag = CPU_HALT;//让当前Cpu停止工作 - while (1) {} + while (1) {}//陷入空循环,也就是空闲状态 } - +///MP定时器处理函数, 递归检查所有可用任务 VOID OsMpCollectTasks(VOID) { LosTaskCB *taskCB = NULL; @@ -80,19 +80,19 @@ VOID OsMpCollectTasks(VOID) UINT32 ret; /* recursive checking all the available task */ - for (; taskID <= g_taskMaxNum; taskID++) { + for (; taskID <= g_taskMaxNum; taskID++) { //递归检查所有可用任务 taskCB = &g_taskCBArray[taskID]; if (OsTaskIsUnused(taskCB) || OsTaskIsRunning(taskCB)) { continue; } - /* + /* 虽然任务状态不是原子的,但此检查可能成功,但无法完成删除,此删除将在下次运行之前处理 * though task status is not atomic, this check may success but not accomplish * the deletion; this deletion will be handled until the next run. */ - if (taskCB->signal & SIGNAL_KILL) { - ret = LOS_TaskDelete(taskID); + if (taskCB->signal & SIGNAL_KILL) {//任务收到被干掉信号 + ret = LOS_TaskDelete(taskID);//干掉任务,回归任务池 if (ret != LOS_OK) { PRINT_WARN("GC collect task failed err:0x%x\n", ret); } @@ -101,6 +101,7 @@ VOID OsMpCollectTasks(VOID) } #ifdef LOSCFG_KERNEL_SMP_CALL + VOID OsMpFuncCall(UINT32 target, SMP_FUNC_CALL func, VOID *args) { UINT32 index; @@ -110,13 +111,13 @@ VOID OsMpFuncCall(UINT32 target, SMP_FUNC_CALL func, VOID *args) return; } - if (!(target & OS_MP_CPU_ALL)) { + if (!(target & OS_MP_CPU_ALL)) {//检查目标CPU是否正确 return; } - for (index = 0; index < LOSCFG_KERNEL_CORE_NUM; index++) { + for (index = 0; index < LOSCFG_KERNEL_CORE_NUM; index++) {//遍历所有核 if (CPUID_TO_AFFI_MASK(index) & target) { - MpCallFunc *mpCallFunc = (MpCallFunc *)LOS_MemAlloc(m_aucSysMem0, sizeof(MpCallFunc)); + MpCallFunc *mpCallFunc = (MpCallFunc *)LOS_MemAlloc(m_aucSysMem0, sizeof(MpCallFunc));//从内核空间 分配回调结构体 if (mpCallFunc == NULL) { PRINT_ERR("smp func call malloc failed\n"); return; @@ -125,59 +126,66 @@ VOID OsMpFuncCall(UINT32 target, SMP_FUNC_CALL func, VOID *args) mpCallFunc->args = args; MP_CALL_LOCK(intSave); - LOS_ListAdd(&g_percpu[index].funcLink, &(mpCallFunc->node)); + LOS_ListAdd(&g_percpu[index].funcLink, &(mpCallFunc->node));//将回调结构体挂入链表尾部 MP_CALL_UNLOCK(intSave); } } - HalIrqSendIpi(target, LOS_MP_IPI_FUNC_CALL); + HalIrqSendIpi(target, LOS_MP_IPI_FUNC_CALL);//向目标CPU发起核间中断 } +/*! + * @brief OsMpFuncCallHandler + * 回调向当前CPU注册过的函数 + * @return + * + * @see + */ VOID OsMpFuncCallHandler(VOID) { UINT32 intSave; - UINT32 cpuid = ArchCurrCpuid(); + UINT32 cpuid = ArchCurrCpuid();//获取当前CPU LOS_DL_LIST *list = NULL; MpCallFunc *mpCallFunc = NULL; MP_CALL_LOCK(intSave); - while (!LOS_ListEmpty(&g_percpu[cpuid].funcLink)) { - list = LOS_DL_LIST_FIRST(&g_percpu[cpuid].funcLink); - LOS_ListDelete(list); + while (!LOS_ListEmpty(&g_percpu[cpuid].funcLink)) {//遍历回调函数链表,知道为空 + list = LOS_DL_LIST_FIRST(&g_percpu[cpuid].funcLink);//获取链表第一个数据 + LOS_ListDelete(list);//将自己从链表上摘除 MP_CALL_UNLOCK(intSave); - mpCallFunc = LOS_DL_LIST_ENTRY(list, MpCallFunc, node); - mpCallFunc->func(mpCallFunc->args); - (VOID)LOS_MemFree(m_aucSysMem0, mpCallFunc); + mpCallFunc = LOS_DL_LIST_ENTRY(list, MpCallFunc, node);//获取回调函数 + mpCallFunc->func(mpCallFunc->args);//获取参数并回调该函数 + (VOID)LOS_MemFree(m_aucSysMem0, mpCallFunc);//释放回调函数内存 MP_CALL_LOCK(intSave); } MP_CALL_UNLOCK(intSave); } - +/// CPU层级的回调模块初始化 VOID OsMpFuncCallInit(VOID) { UINT32 index; - /* init funclink for each core */ + /* init funclink for each core | 为每个CPU核整一个回调函数链表*/ for (index = 0; index < LOSCFG_KERNEL_CORE_NUM; index++) { - LOS_ListInit(&g_percpu[index].funcLink); + LOS_ListInit(&g_percpu[index].funcLink);//链表初始化 } } #endif /* LOSCFG_KERNEL_SMP_CALL */ - +//MP(multiprocessing) 多核处理器初始化 UINT32 OsMpInit(VOID) { UINT16 swtmrId; - (VOID)LOS_SwtmrCreate(OS_MP_GC_PERIOD, LOS_SWTMR_MODE_PERIOD, - (SWTMR_PROC_FUNC)OsMpCollectTasks, &swtmrId, 0); - (VOID)LOS_SwtmrStart(swtmrId); + (VOID)LOS_SwtmrCreate(OS_MP_GC_PERIOD, LOS_SWTMR_MODE_PERIOD, //创建一个周期性,持续时间为 100个tick的定时器 + (SWTMR_PROC_FUNC)OsMpCollectTasks, &swtmrId, 0);//OsMpCollectTasks为超时回调函数 + (VOID)LOS_SwtmrStart(swtmrId);//开始定时任务 #ifdef LOSCFG_KERNEL_SMP_CALL OsMpFuncCallInit(); #endif return LOS_OK; } -LOS_MODULE_INIT(OsMpInit, LOS_INIT_LEVEL_KMOD_TASK); +LOS_MODULE_INIT(OsMpInit, LOS_INIT_LEVEL_KMOD_TASK);//多处理器模块初始化 #endif diff --git a/src/kernel_liteos_a/kernel/base/mp/los_percpu.c b/src/kernel_liteos_a/kernel/base/mp/los_percpu.c index 4d883916..527c028f 100644 --- a/src/kernel_liteos_a/kernel/base/mp/los_percpu.c +++ b/src/kernel_liteos_a/kernel/base/mp/los_percpu.c @@ -33,7 +33,7 @@ #include "los_printf.h" #ifdef LOSCFG_KERNEL_SMP -Percpu g_percpu[LOSCFG_KERNEL_CORE_NUM]; +Percpu g_percpu[LOSCFG_KERNEL_CORE_NUM]; ///< CPU池,池大小由CPU核数决定 VOID OsAllCpuStatusOutput(VOID) { From d0dc3063a2974b8ad2240fef0c7148166c963f30 Mon Sep 17 00:00:00 2001 From: Dio Date: Fri, 19 Jan 2024 10:01:27 +0800 Subject: [PATCH 21/33] =?UTF-8?q?om=E6=96=87=E4=BB=B6=E5=A4=B9=E6=8B=BF?= =?UTF-8?q?=E4=B8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kernel_liteos_a/kernel/base/om/los_err.c | 24 ++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/kernel_liteos_a/kernel/base/om/los_err.c b/src/kernel_liteos_a/kernel/base/om/los_err.c index 6267a9d1..f3ad8a21 100644 --- a/src/kernel_liteos_a/kernel/base/om/los_err.c +++ b/src/kernel_liteos_a/kernel/base/om/los_err.c @@ -31,9 +31,29 @@ #include "los_err.h" +/** +基本概念 + 错误处理指程序运行错误时,调用错误处理模块的接口函数,上报错误信息,并调用注册的钩子函数 + 进行特定处理,保存现场以便定位问题。通过错误处理,可以控制和提示程序中的非法输入,防止程序崩溃。 -LITE_OS_SEC_BSS STATIC LOS_ERRORHANDLE_FUNC g_errHandleHook = NULL; +运作机制 + 错误处理是一种机制,用于处理异常状况。当程序出现错误时,会显示相应的错误码。 + 此外,如果注册了相应的错误处理函数,则会执行这个函数。 +系统中只有一个错误处理的钩子函数。当多次注册钩子函数时,最后一次注册的钩子函数会覆盖前一次注册的函数 + */ + +LITE_OS_SEC_BSS STATIC LOS_ERRORHANDLE_FUNC g_errHandleHook = NULL;///< 错误接管钩子函数 + +/** + * @brief 调用钩子函数,处理错误 + * @param fileName 存放错误日志的文件名,系统内部调用时,入参为"os_unspecific_file" + * @param lineNo 发生错误的代码行号系统内部调用时,若值为0xa1b2c3f8,表示未传递行号 + * @param errorNo 错误码 + * @param paraLen 入参para的长度系统内部调用时,入参为0 + * @param para 错误标签系统内部调用时,入参为NULL + * @return LITE_OS_SEC_TEXT_INIT + */ LITE_OS_SEC_TEXT_INIT UINT32 LOS_ErrHandle(CHAR *fileName, UINT32 lineNo, UINT32 errorNo, UINT32 paraLen, VOID *para) { @@ -43,7 +63,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_ErrHandle(CHAR *fileName, UINT32 lineNo, UINT32 return LOS_OK; } - +///设置钩子函数,处理错误 LITE_OS_SEC_TEXT_INIT VOID LOS_SetErrHandleHook(LOS_ERRORHANDLE_FUNC fun) { g_errHandleHook = fun; From a4918e9a1e21eaaf2ce6ce726f6bb8354407b5bf Mon Sep 17 00:00:00 2001 From: eee <719747958@qq.com> Date: Fri, 19 Jan 2024 10:05:53 +0800 Subject: [PATCH 22/33] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86mei=E7=9A=84?= =?UTF-8?q?=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/~$泛读报告.docx | Bin 162 -> 0 bytes doc/泛读报告.docx | Bin 156143 -> 157609 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 doc/~$泛读报告.docx diff --git a/doc/~$泛读报告.docx b/doc/~$泛读报告.docx deleted file mode 100644 index 4ad6b906510457f5e1251738e0b3478879968b88..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 162 zcmZRpP;gGn%wZr6urX9HC@?rPBr;?&fb>>8J0rq(oPj|)i3!CZ7!M|HC2{wEnb$4G c8IK_9k01YKUk>C;L3J&w*Aw_xk75J^0DVLjmjD0& diff --git a/doc/泛读报告.docx b/doc/泛读报告.docx index 56a3ce5f5a8f79cdd32c1a7cb67d7058ff546cd1..55b9d06314e73d74a5e0a632b315f5841cf9005b 100644 GIT binary patch delta 18520 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 Hz;npoyOgjm delta 17130 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 Bmze+n From 162af576ade9b99c5ff7a8456ad16b14067f243b Mon Sep 17 00:00:00 2001 From: dancer <2905764690@qq.com> Date: Fri, 19 Jan 2024 11:34:56 +0800 Subject: [PATCH 23/33] =?UTF-8?q?vm=E8=A7=A3=E6=95=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kernel/base/core/los_process.c | 1 - .../kernel/base/vm/los_vm_dump.c | 106 ++-- .../kernel/base/vm/los_vm_fault.c | 150 ++--- .../kernel/base/vm/los_vm_filemap.c | 291 +++++---- .../kernel/base/vm/los_vm_iomap.c | 57 +- .../kernel/base/vm/los_vm_map.c | 568 ++++++++++-------- .../kernel/base/vm/los_vm_page.c | 50 +- .../kernel/base/vm/los_vm_phys.c | 344 ++++++----- .../kernel/base/vm/los_vm_scan.c | 198 +++--- .../kernel/base/vm/los_vm_syscall.c | 167 +++-- src/kernel_liteos_a/kernel/base/vm/oom.c | 83 ++- src/kernel_liteos_a/kernel/base/vm/shm.c | 380 ++++++++---- 12 files changed, 1396 insertions(+), 999 deletions(-) diff --git a/src/kernel_liteos_a/kernel/base/core/los_process.c b/src/kernel_liteos_a/kernel/base/core/los_process.c index 40fed7dd..58dd593f 100644 --- a/src/kernel_liteos_a/kernel/base/core/los_process.c +++ b/src/kernel_liteos_a/kernel/base/core/los_process.c @@ -2315,7 +2315,6 @@ LITE_OS_SEC_TEXT INT32 OsClone(UINT32 flags, UINTPTR sp, UINT32 size) return OsCopyProcess(cloneFlag & flags, NULL, sp, size); } -//著名的 fork 函数 记得前往 https://gitee.com/weharmony/kernel_liteos_a_note fork一下 :) LITE_OS_SEC_TEXT INT32 LOS_Fork(UINT32 flags, const CHAR *name, const TSK_ENTRY_FUNC entry, UINT32 stackSize) { UINT32 cloneFlag = CLONE_PARENT | CLONE_THREAD | CLONE_VFORK | CLONE_FILES; diff --git a/src/kernel_liteos_a/kernel/base/vm/los_vm_dump.c b/src/kernel_liteos_a/kernel/base/vm/los_vm_dump.c index f326ea12..1fbc80b9 100644 --- a/src/kernel_liteos_a/kernel/base/vm/los_vm_dump.c +++ b/src/kernel_liteos_a/kernel/base/vm/los_vm_dump.c @@ -159,26 +159,26 @@ UINT32 OsKProcessPmUsage(LosVmSpace *kSpace, UINT32 *actualPm) /* Kernel resident memory, include default heap memory */ memUsed = SYS_MEM_SIZE_DEFAULT - (totalCount << PAGE_SHIFT); - spaceList = LOS_GetVmSpaceList(); + spaceList = LOS_GetVmSpaceList();//获取虚拟空间链表,上面挂了所有虚拟空间 LosMux *vmSpaceListMux = OsGVmSpaceMuxGet(); (VOID)LOS_MuxAcquire(vmSpaceListMux); - LOS_DL_LIST_FOR_EACH_ENTRY(space, spaceList, LosVmSpace, node) { - if (space == LOS_GetKVmSpace()) { + LOS_DL_LIST_FOR_EACH_ENTRY(space, spaceList, LosVmSpace, node) {//遍历链表 + if (space == LOS_GetKVmSpace()) {//内核空间不统计 continue; } UProcessUsed += OsUProcessPmUsage(space, NULL, NULL); } (VOID)LOS_MuxRelease(vmSpaceListMux); - /* Kernel dynamic memory, include extended heap memory */ + /* Kernel dynamic memory, include extended heap memory */ //内核动态内存,包括扩展堆内存 memUsed += ((usedCount << PAGE_SHIFT) - UProcessUsed); - /* Remaining heap memory */ + /* Remaining heap memory */ //剩余堆内存 memUsed -= freeMem; *actualPm = memUsed; return memUsed; } - +///shell task 物理内存的使用情况 UINT32 OsShellCmdProcessPmUsage(LosVmSpace *space, UINT32 *sharePm, UINT32 *actualPm) { if (space == NULL) { @@ -194,7 +194,7 @@ UINT32 OsShellCmdProcessPmUsage(LosVmSpace *space, UINT32 *sharePm, UINT32 *actu } return OsUProcessPmUsage(space, sharePm, actualPm); } - +///虚拟空间物理内存的使用情况,参数同时带走共享物理内存sharePm和actualPm单位是字节 UINT32 OsUProcessPmUsage(LosVmSpace *space, UINT32 *sharePm, UINT32 *actualPm) { LosVmMapRegion *region = NULL; @@ -230,10 +230,10 @@ UINT32 OsUProcessPmUsage(LosVmSpace *space, UINT32 *sharePm, UINT32 *actualPm) continue; } - shareRef = LOS_AtomicRead(&page->refCounts); + shareRef = LOS_AtomicRead(&page->refCounts);//ref 大于1 说明page被其他空间也引用了 if (shareRef > 1) { if (sharePm != NULL) { - *sharePm += PAGE_SIZE; + *sharePm += PAGE_SIZE;//一页4K字节 } pmSize += PAGE_SIZE / shareRef; } else { @@ -250,7 +250,9 @@ UINT32 OsUProcessPmUsage(LosVmSpace *space, UINT32 *sharePm, UINT32 *actualPm) return pmSize; } - +/// @brief 通过虚拟空间获取进程实体 +/// @param space +/// @return LosProcessCB *OsGetPIDByAspace(const LosVmSpace *space) { UINT32 pid; @@ -258,13 +260,13 @@ LosProcessCB *OsGetPIDByAspace(const LosVmSpace *space) LosProcessCB *processCB = NULL; SCHEDULER_LOCK(intSave); - for (pid = 0; pid < g_processMaxNum; ++pid) { + for (pid = 0; pid < g_processMaxNum; ++pid) {//循环进程池,进程池本质是个数组 processCB = g_processCBArray + pid; - if (OsProcessIsUnused(processCB)) { + if (OsProcessIsUnused(processCB)) {//进程还没被分配使用 continue; } - if (processCB->vmSpace == space) { + if (processCB->vmSpace == space) {//找到了 SCHEDULER_UNLOCK(intSave); return processCB; } @@ -272,7 +274,11 @@ LosProcessCB *OsGetPIDByAspace(const LosVmSpace *space) SCHEDULER_UNLOCK(intSave); return NULL; } - +/// @brief 统计虚拟空间中某个线性区的页数 +/// @param space +/// @param region +/// @param pssPages +/// @return UINT32 OsCountRegionPages(LosVmSpace *space, LosVmMapRegion *region, UINT32 *pssPages) { UINT32 regionPages = 0; @@ -306,7 +312,7 @@ UINT32 OsCountRegionPages(LosVmSpace *space, LosVmMapRegion *region, UINT32 *pss return regionPages; } - +///统计虚拟空间的总页数 UINT32 OsCountAspacePages(LosVmSpace *space) { UINT32 spacePages = 0; @@ -390,27 +396,30 @@ VOID OsDumpRegion2(LosVmSpace *space, LosVmMapRegion *region) region->range.size, flagsStr, regionPages, pssPages); (VOID)LOS_MemFree(m_aucSysMem0, flagsStr); } - +///dump 指定虚拟空间的信息 VOID OsDumpAspace(LosVmSpace *space) { LosVmMapRegion *region = NULL; LosRbNode *pstRbNode = NULL; LosRbNode *pstRbNodeNext = NULL; UINT32 spacePages; - LosProcessCB *pcb = OsGetPIDByAspace(space); + LosProcessCB *pcb = OsGetPIDByAspace(space);//通过虚拟空间找到进程实体 if (pcb == NULL) { return; } - - spacePages = OsCountAspacePages(space); + //进程ID | 进程虚拟内存控制块地址信息 | 虚拟内存起始地址 | 虚拟内存大小 | 已使用的物理页数量 + spacePages = OsCountAspacePages(space);//获取空间的页数 PRINTK("\r\n PID aspace name base size pages \n"); PRINTK(" ---- ------ ---- ---- ----- ----\n"); PRINTK(" %-4d %#010x %-10.10s %#010x %#010x %d\n", pcb->processID, space, pcb->processName, space->base, space->size, spacePages); + + //虚拟区间控制块地址信息 | 虚拟区间类型 | 虚拟区间起始地址 | 虚拟区间大小 | 虚拟区间mmu映射属性 | 已使用的物理页数量(包括共享内存部分 | 已使用的物理页数量 + PRINTK("\r\n\t region name base size mmu_flags pages pg/ref\n"); PRINTK("\t ------ ---- ---- ---- --------- ----- -----\n"); - RB_SCAN_SAFE(&space->regionRbTree, pstRbNode, pstRbNodeNext) + RB_SCAN_SAFE(&space->regionRbTree, pstRbNode, pstRbNodeNext)//按region 轮询统计 region = (LosVmMapRegion *)pstRbNode; if (region != NULL) { OsDumpRegion2(space, region); @@ -421,14 +430,14 @@ VOID OsDumpAspace(LosVmSpace *space) RB_SCAN_SAFE_END(&space->regionRbTree, pstRbNode, pstRbNodeNext) return; } - +///查看所有进程使用虚拟内存的情况 VOID OsDumpAllAspace(VOID) { LosVmSpace *space = NULL; - LOS_DL_LIST *aspaceList = LOS_GetVmSpaceList(); - LOS_DL_LIST_FOR_EACH_ENTRY(space, aspaceList, LosVmSpace, node) { + LOS_DL_LIST *aspaceList = LOS_GetVmSpaceList();//获取所有空间链表 + LOS_DL_LIST_FOR_EACH_ENTRY(space, aspaceList, LosVmSpace, node) {//循环取出进程虚拟 (VOID)LOS_MuxAcquire(&space->regionMux); - OsDumpAspace(space); + OsDumpAspace(space);//dump 空间 (VOID)LOS_MuxRelease(&space->regionMux); } return; @@ -447,11 +456,11 @@ STATUS_T OsRegionOverlapCheck(LosVmSpace *space, LosVmMapRegion *region) (VOID)LOS_MuxRelease(&space->regionMux); return ret; } - +///dump 页表项 VOID OsDumpPte(VADDR_T vaddr) { UINT32 l1Index = vaddr >> MMU_DESCRIPTOR_L1_SMALL_SHIFT; - LosVmSpace *space = LOS_SpaceGet(vaddr); + LosVmSpace *space = LOS_SpaceGet(vaddr);//通过虚拟地址获取空间,内核分三个空间 内核进程空间,内核堆空间,用户进程空间 UINT32 ttEntry; LosVmPage *page = NULL; PTE_T *l2Table = NULL; @@ -461,27 +470,27 @@ VOID OsDumpPte(VADDR_T vaddr) return; } - ttEntry = space->archMmu.virtTtb[l1Index]; + ttEntry = space->archMmu.virtTtb[l1Index];//找到 L1 页面项 if (ttEntry) { - l2Table = LOS_PaddrToKVaddr(MMU_DESCRIPTOR_L1_PAGE_TABLE_ADDR(ttEntry)); - l2Index = (vaddr % MMU_DESCRIPTOR_L1_SMALL_SIZE) >> PAGE_SHIFT; + l2Table = LOS_PaddrToKVaddr(MMU_DESCRIPTOR_L1_PAGE_TABLE_ADDR(ttEntry));//找到L1页面项对应的 L2表 + l2Index = (vaddr % MMU_DESCRIPTOR_L1_SMALL_SIZE) >> PAGE_SHIFT;//找到L2页面项 if (l2Table == NULL) { goto ERR; } - page = LOS_VmPageGet(l2Table[l2Index] & ~(PAGE_SIZE - 1)); + page = LOS_VmPageGet(l2Table[l2Index] & ~(PAGE_SIZE - 1));//获取物理页框 if (page == NULL) { goto ERR; } PRINTK("vaddr %p, l1Index %d, ttEntry %p, l2Table %p, l2Index %d, pfn %p count %d\n", - vaddr, l1Index, ttEntry, l2Table, l2Index, l2Table[l2Index], LOS_AtomicRead(&page->refCounts)); - } else { + vaddr, l1Index, ttEntry, l2Table, l2Index, l2Table[l2Index], LOS_AtomicRead(&page->refCounts));//打印L1 L2 页表项 + } else {//不在L1表 PRINTK("vaddr %p, l1Index %d, ttEntry %p\n", vaddr, l1Index, ttEntry); } return; ERR: PRINTK("%s, error vaddr: %#x, l2Table: %#x, l2Index: %#x\n", __FUNCTION__, vaddr, l2Table, l2Index); } - +///获取段剩余页框数 UINT32 OsVmPhySegPagesGet(LosVmPhysSeg *seg) { UINT32 intSave; @@ -489,14 +498,25 @@ UINT32 OsVmPhySegPagesGet(LosVmPhysSeg *seg) UINT32 segFreePages = 0; LOS_SpinLockSave(&seg->freeListLock, &intSave); - for (flindex = 0; flindex < VM_LIST_ORDER_MAX; flindex++) { - segFreePages += ((1 << flindex) * seg->freeList[flindex].listCnt); + for (flindex = 0; flindex < VM_LIST_ORDER_MAX; flindex++) {//遍历块组 + segFreePages += ((1 << flindex) * seg->freeList[flindex].listCnt);//1 << flindex等于页数, * 节点数 得到组块的总页数. } LOS_SpinUnlockRestore(&seg->freeListLock, intSave); - return segFreePages; + return segFreePages;//返回剩余未分配的总物理页框 } - +///dump 物理内存 +/*********************************************************** +* phys_seg:物理页控制块地址信息 +* base:第一个物理页地址,即物理页内存起始地址 +* size:物理页内存大小 +* free_pages:空闲物理页数量 +* active anon: pagecache中,活跃的匿名页数量 +* inactive anon: pagecache中,不活跃的匿名页数量 +* active file: pagecache中,活跃的文件页数量 +* inactive file: pagecache中,不活跃的文件页数量 +* pmm pages total:总的物理页数,used:已使用的物理页数,free:空闲的物理页数 +************************************************************/ VOID OsVmPhysDump(VOID) { LosVmPhysSeg *seg = NULL; @@ -508,7 +528,7 @@ VOID OsVmPhysDump(VOID) UINT32 flindex; UINT32 listCount[VM_LIST_ORDER_MAX] = {0}; - for (segIndex = 0; segIndex < g_vmPhysSegNum; segIndex++) { + for (segIndex = 0; segIndex < g_vmPhysSegNum; segIndex++) {//循环取段 seg = &g_vmPhysSeg[segIndex]; if (seg->size > 0) { segFreePages = OsVmPhySegPagesGet(seg); @@ -538,7 +558,7 @@ VOID OsVmPhysDump(VOID) PRINTK("\n\rpmm pages: total = %u, used = %u, free = %u\n", totalPages, (totalPages - totalFreePages), totalFreePages); } - +///获取物理内存的使用信息,两个参数接走数据 VOID OsVmPhysUsedInfoGet(UINT32 *usedCount, UINT32 *totalCount) { UINT32 index; @@ -551,12 +571,12 @@ VOID OsVmPhysUsedInfoGet(UINT32 *usedCount, UINT32 *totalCount) *usedCount = 0; *totalCount = 0; - for (index = 0; index < g_vmPhysSegNum; index++) { + for (index = 0; index < g_vmPhysSegNum; index++) {//循环取段 physSeg = &g_vmPhysSeg[index]; if (physSeg->size > 0) { - *totalCount += physSeg->size >> PAGE_SHIFT; - segFreePages = OsVmPhySegPagesGet(physSeg); - *usedCount += (*totalCount - segFreePages); + *totalCount += physSeg->size >> PAGE_SHIFT;//叠加段的总页数 + segFreePages = OsVmPhySegPagesGet(physSeg);//获取段的剩余页数 + *usedCount += (*totalCount - segFreePages);//叠加段的使用页数 } } } diff --git a/src/kernel_liteos_a/kernel/base/vm/los_vm_fault.c b/src/kernel_liteos_a/kernel/base/vm/los_vm_fault.c index 86b08199..902f84ea 100644 --- a/src/kernel_liteos_a/kernel/base/vm/los_vm_fault.c +++ b/src/kernel_liteos_a/kernel/base/vm/los_vm_fault.c @@ -54,7 +54,7 @@ extern char __exc_table_start[]; extern char __exc_table_end[]; - +//线性正确性检查 STATIC STATUS_T OsVmRegionPermissionCheck(LosVmMapRegion *region, UINT32 flags) { if ((region->regionFlags & VM_MAP_REGION_FLAG_PERM_READ) != VM_MAP_REGION_FLAG_PERM_READ) { @@ -62,14 +62,14 @@ STATIC STATUS_T OsVmRegionPermissionCheck(LosVmMapRegion *region, UINT32 flags) return LOS_NOK; } - if ((flags & VM_MAP_PF_FLAG_WRITE) == VM_MAP_PF_FLAG_WRITE) { + if ((flags & VM_MAP_PF_FLAG_WRITE) == VM_MAP_PF_FLAG_WRITE) {//写入许可 if ((region->regionFlags & VM_MAP_REGION_FLAG_PERM_WRITE) != VM_MAP_REGION_FLAG_PERM_WRITE) { VM_ERR("write permission check failed operation flags %x, region flags %x", flags, region->regionFlags); return LOS_NOK; } } - if ((flags & VM_MAP_PF_FLAG_INSTRUCTION) == VM_MAP_PF_FLAG_INSTRUCTION) { + if ((flags & VM_MAP_PF_FLAG_INSTRUCTION) == VM_MAP_PF_FLAG_INSTRUCTION) {//指令 if ((region->regionFlags & VM_MAP_REGION_FLAG_PERM_EXECUTE) != VM_MAP_REGION_FLAG_PERM_EXECUTE) { VM_ERR("exec permission check failed operation flags %x, region flags %x", flags, region->regionFlags); return LOS_NOK; @@ -97,7 +97,8 @@ STATIC VOID OsFaultTryFixup(ExcContext *frame, VADDR_T excVaddr, STATUS_T *statu } #ifdef LOSCFG_FS_VFS -STATIC STATUS_T OsDoReadFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault) +//读页时发生缺页的处理 +STATIC STATUS_T OsDoReadFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault)//读缺页 { status_t ret; PADDR_T paddr; @@ -105,26 +106,26 @@ STATIC STATUS_T OsDoReadFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault) VADDR_T vaddr = (VADDR_T)vmPgFault->vaddr; LosVmSpace *space = region->space; - ret = LOS_ArchMmuQuery(&space->archMmu, vaddr, NULL, NULL); - if (ret == LOS_OK) { - return LOS_OK; + ret = LOS_ArchMmuQuery(&space->archMmu, vaddr, NULL, NULL);//查询是否缺页 + if (ret == LOS_OK) {//注意这里时LOS_OK却返回,都OK了说明查到了物理地址,有页了。 + return LOS_OK;//查到了就说明不缺页的,缺页就是因为虚拟地址没有映射到物理地址嘛 } - if (region->unTypeData.rf.vmFOps == NULL || region->unTypeData.rf.vmFOps->fault == NULL) { + if (region->unTypeData.rf.vmFOps == NULL || region->unTypeData.rf.vmFOps->fault == NULL) {//线性区必须有实现了缺页接口 VM_ERR("region args invalid, file path: %s", region->unTypeData.rf.vnode->filePath); return LOS_ERRNO_VM_INVALID_ARGS; } (VOID)LOS_MuxAcquire(®ion->unTypeData.rf.vnode->mapping.mux_lock); - ret = region->unTypeData.rf.vmFOps->fault(region, vmPgFault); + ret = region->unTypeData.rf.vmFOps->fault(region, vmPgFault);// 函数指针,执行的是g_commVmOps.OsVmmFileFault if (ret == LOS_OK) { - paddr = LOS_PaddrQuery(vmPgFault->pageKVaddr); - page = LOS_VmPageGet(paddr); + paddr = LOS_PaddrQuery(vmPgFault->pageKVaddr);//查询物理地址 + page = LOS_VmPageGet(paddr);//获取page if (page != NULL) { /* just incase of page null */ - LOS_AtomicInc(&page->refCounts); + LOS_AtomicInc(&page->refCounts);//ref 自增 OsCleanPageLocked(page); } ret = LOS_ArchMmuMap(&space->archMmu, vaddr, paddr, 1, - region->regionFlags & (~VM_MAP_REGION_FLAG_PERM_WRITE)); + region->regionFlags & (~VM_MAP_REGION_FLAG_PERM_WRITE));//重新映射为非可写 if (ret < 0) { VM_ERR("LOS_ArchMmuMap failed"); OsDelMapInfo(region, vmPgFault, false); @@ -140,7 +141,7 @@ STATIC STATUS_T OsDoReadFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault) return LOS_ERRNO_VM_NO_MEMORY; } -/* unmap a page when cow happened only */ +/* unmap a page when cow happened only *///仅当写时拷贝发生时取消页面映射 STATIC LosVmPage *OsCowUnmapOrg(LosArchMmu *archMmu, LosVmMapRegion *region, LosVmPgFault *vmf) { UINT32 intSave; @@ -168,7 +169,7 @@ STATIC LosVmPage *OsCowUnmapOrg(LosArchMmu *archMmu, LosVmMapRegion *region, Los return oldPage; } #endif - +//在私有线性区写入文件时发生缺页的处理 status_t OsDoCowFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault) { STATUS_T ret; @@ -186,23 +187,23 @@ status_t OsDoCowFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault) } space = region->space; - ret = LOS_ArchMmuQuery(&space->archMmu, (VADDR_T)vmPgFault->vaddr, &oldPaddr, NULL); + ret = LOS_ArchMmuQuery(&space->archMmu, (VADDR_T)vmPgFault->vaddr, &oldPaddr, NULL);//查询出老物理地址 if (ret == LOS_OK) { - oldPage = OsCowUnmapOrg(&space->archMmu, region, vmPgFault); + oldPage = OsCowUnmapOrg(&space->archMmu, region, vmPgFault);//取消页面映射 } - newPage = LOS_PhysPageAlloc(); + newPage = LOS_PhysPageAlloc();//分配一个新页面 if (newPage == NULL) { VM_ERR("LOS_PhysPageAlloc failed"); ret = LOS_ERRNO_VM_NO_MEMORY; goto ERR_OUT; } - newPaddr = VM_PAGE_TO_PHYS(newPage); - kvaddr = OsVmPageToVaddr(newPage); + newPaddr = VM_PAGE_TO_PHYS(newPage);//拿到新的物理地址 + kvaddr = OsVmPageToVaddr(newPage);//拿到新的虚拟地址 (VOID)LOS_MuxAcquire(®ion->unTypeData.rf.vnode->mapping.mux_lock); - ret = region->unTypeData.rf.vmFOps->fault(region, vmPgFault); + ret = region->unTypeData.rf.vmFOps->fault(region, vmPgFault);// 函数指针 g_commVmOps.OsVmmFileFault if (ret != LOS_OK) { VM_ERR("call region->vm_ops->fault fail"); (VOID)LOS_MuxRelease(®ion->unTypeData.rf.vnode->mapping.mux_lock); @@ -214,20 +215,20 @@ status_t OsDoCowFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault) * we can take it as a normal file cow map. 2.this page has done file cow map, * we can take it as a anonymous cow map. */ - if ((oldPaddr == 0) || (LOS_PaddrToKVaddr(oldPaddr) == vmPgFault->pageKVaddr)) { - (VOID)memcpy_s(kvaddr, PAGE_SIZE, vmPgFault->pageKVaddr, PAGE_SIZE); - LOS_AtomicInc(&newPage->refCounts); - OsCleanPageLocked(LOS_VmPageGet(LOS_PaddrQuery(vmPgFault->pageKVaddr))); + if ((oldPaddr == 0) || (LOS_PaddrToKVaddr(oldPaddr) == vmPgFault->pageKVaddr)) {//没有映射或者 已在pagecache有映射 + (VOID)memcpy_s(kvaddr, PAGE_SIZE, vmPgFault->pageKVaddr, PAGE_SIZE);//直接copy到新页 + LOS_AtomicInc(&newPage->refCounts);//引用ref++ + OsCleanPageLocked(LOS_VmPageGet(LOS_PaddrQuery(vmPgFault->pageKVaddr)));//解锁 } else { - OsPhysSharePageCopy(oldPaddr, &newPaddr, newPage); + OsPhysSharePageCopy(oldPaddr, &newPaddr, newPage);//调用之前 oldPaddr肯定不等于newPaddr /* use old page free the new one */ - if (newPaddr == oldPaddr) { - LOS_PhysPageFree(newPage); + if (newPaddr == oldPaddr) {//注意这里newPaddr可能已经被改变了,参数传入的是 &newPaddr + LOS_PhysPageFree(newPage);//释放新页,别浪费的内存,内核使用内存是一分钱当十块用. newPage = NULL; } } - ret = LOS_ArchMmuMap(&space->archMmu, (VADDR_T)vmPgFault->vaddr, newPaddr, 1, region->regionFlags); + ret = LOS_ArchMmuMap(&space->archMmu, (VADDR_T)vmPgFault->vaddr, newPaddr, 1, region->regionFlags);//把新物理地址映射给缺页的虚拟地址,这样就不会缺页啦 if (ret < 0) { VM_ERR("LOS_ArchMmuMap failed"); ret = LOS_ERRNO_VM_NO_MEMORY; @@ -252,7 +253,7 @@ ERR_OUT: return ret; } - +///在共享线性区写文件操作发生缺页的情况处理,因为线性区是共享的 status_t OsDoSharedFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault) { STATUS_T ret; @@ -268,10 +269,10 @@ status_t OsDoSharedFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault) return LOS_ERRNO_VM_INVALID_ARGS; } - ret = LOS_ArchMmuQuery(&space->archMmu, vmPgFault->vaddr, &paddr, NULL); + ret = LOS_ArchMmuQuery(&space->archMmu, vmPgFault->vaddr, &paddr, NULL);//查询物理地址 if (ret == LOS_OK) { - LOS_ArchMmuUnmap(&space->archMmu, vmPgFault->vaddr, 1); - ret = LOS_ArchMmuMap(&space->archMmu, vaddr, paddr, 1, region->regionFlags); + LOS_ArchMmuUnmap(&space->archMmu, vmPgFault->vaddr, 1);//先取消映射 + ret = LOS_ArchMmuMap(&space->archMmu, vaddr, paddr, 1, region->regionFlags);//再重新映射,为啥这么干,是因为regionFlags变了, if (ret < 0) { VM_ERR("LOS_ArchMmuMap failed. ret=%d", ret); return LOS_ERRNO_VM_NO_MEMORY; @@ -279,16 +280,16 @@ status_t OsDoSharedFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault) LOS_SpinLockSave(®ion->unTypeData.rf.vnode->mapping.list_lock, &intSave); fpage = OsFindGetEntry(®ion->unTypeData.rf.vnode->mapping, vmPgFault->pgoff); - if (fpage) { - OsMarkPageDirty(fpage, region, 0, 0); + if (fpage) {//在页高速缓存(page cache)中找到了 + OsMarkPageDirty(fpage, region, 0, 0);//标记为脏页 } LOS_SpinUnlockRestore(®ion->unTypeData.rf.vnode->mapping.list_lock, intSave); return LOS_OK; } - + //以下是没有映射到物理地址的处理 (VOID)LOS_MuxAcquire(®ion->unTypeData.rf.vnode->mapping.mux_lock); - ret = region->unTypeData.rf.vmFOps->fault(region, vmPgFault); + ret = region->unTypeData.rf.vmFOps->fault(region, vmPgFault);//函数指针,执行的是g_commVmOps.OsVmmFileFault if (ret == LOS_OK) { paddr = LOS_PaddrQuery(vmPgFault->pageKVaddr); page = LOS_VmPageGet(paddr); @@ -319,23 +320,36 @@ status_t OsDoSharedFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault) * For COW fault, pagecache is copied to private anonyous pages and the changes on this page * won't write through to the underlying file. For SHARED fault, pagecache is mapping with * region->arch_mmu_flags and the changes on this page will write through to the underlying file - */ + */ //操作文件时产生缺页中断 STATIC STATUS_T OsDoFileFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault, UINT32 flags) { STATUS_T ret; - if (flags & VM_MAP_PF_FLAG_WRITE) { - if (region->regionFlags & VM_MAP_REGION_FLAG_SHARED) { - ret = OsDoSharedFault(region, vmPgFault); - } else { - ret = OsDoCowFault(region, vmPgFault); + if (flags & VM_MAP_PF_FLAG_WRITE) {//写页的时候产生缺页 + if (region->regionFlags & VM_MAP_REGION_FLAG_SHARED) {//共享线性区 + ret = OsDoSharedFault(region, vmPgFault);//写操作时的共享缺页,最复杂,此页上的更改将写入磁盘文件 + } else {//非共享线性区 + ret = OsDoCowFault(region, vmPgFault);//(写时拷贝技术)写操作时的私有缺页,pagecache被复制到私有的任意一个页面上,并在此页面上进行更改,不会直接写入磁盘文件 } - } else { - ret = OsDoReadFault(region, vmPgFault); + } else {//读页的时候产生缺页 + ret = OsDoReadFault(region, vmPgFault);//页面读取操作很简单,只需共享页面缓存(节省内存)并进行读权限映射(region->arch_mmu_flags&(~arch_mmu_FLAG_PERM_WRITE)) } return ret; } +/*************************************************************** +缺页中断处理程序 +通常有两种情况导致 +第一种:由编程错误引起的异常 +第二种:属于进程的地址空间范围但还尚未分配物理页框引起的异常 +***************************************************************/ +/** + * @brief + * @param vaddr + * @param flags + * @param frame + * @return STATUS_T + */ STATUS_T OsVmPageFaultHandler(VADDR_T vaddr, UINT32 flags, ExcContext *frame) { LosVmSpace *space = LOS_SpaceGet(vaddr); @@ -354,9 +368,9 @@ STATUS_T OsVmPageFaultHandler(VADDR_T vaddr, UINT32 flags, ExcContext *frame) return status; } - if (((flags & VM_MAP_PF_FLAG_USER) != 0) && (!LOS_IsUserAddress(vaddr))) { + if (((flags & VM_MAP_PF_FLAG_USER) != 0) && (!LOS_IsUserAddress(vaddr))) {//地址保护,用户空间不允许跨界访问 VM_ERR("user space not allowed to access invalid address: %#x", vaddr); - return LOS_ERRNO_VM_ACCESS_DENIED; + return LOS_ERRNO_VM_ACCESS_DENIED;//拒绝访问 } #ifdef LOSCFG_KERNEL_PLIMITS @@ -366,7 +380,7 @@ STATUS_T OsVmPageFaultHandler(VADDR_T vaddr, UINT32 flags, ExcContext *frame) #endif (VOID)LOS_MuxAcquire(&space->regionMux); - region = LOS_RegionFind(space, vaddr); + region = LOS_RegionFind(space, vaddr);//通过虚拟地址找到所在线性区 if (region == NULL) { VM_ERR("region not exists, vaddr: %#x", vaddr); status = LOS_ERRNO_VM_NOT_FOUND; @@ -375,11 +389,11 @@ STATUS_T OsVmPageFaultHandler(VADDR_T vaddr, UINT32 flags, ExcContext *frame) status = OsVmRegionPermissionCheck(region, flags); if (status != LOS_OK) { - status = LOS_ERRNO_VM_ACCESS_DENIED; + status = LOS_ERRNO_VM_ACCESS_DENIED;//拒绝访问 goto CHECK_FAILED; } - if (OomCheckProcess()) { + if (OomCheckProcess()) {//低内存检查 /* * under low memory, when user process request memory allocation * it will fail, and result is LOS_NOK and current user process @@ -389,18 +403,18 @@ STATUS_T OsVmPageFaultHandler(VADDR_T vaddr, UINT32 flags, ExcContext *frame) goto CHECK_FAILED; } - vaddr = ROUNDDOWN(vaddr, PAGE_SIZE); + vaddr = ROUNDDOWN(vaddr, PAGE_SIZE);//为啥要向下圆整,因为这一页要重新使用,需找到页面基地址 #ifdef LOSCFG_FS_VFS - if (LOS_IsRegionFileValid(region)) { + if (LOS_IsRegionFileValid(region)) {//是否为文件线性区 if (region->unTypeData.rf.vnode == NULL) { goto CHECK_FAILED; } - vmPgFault.vaddr = vaddr; - vmPgFault.pgoff = ((vaddr - region->range.base) >> PAGE_SHIFT) + region->pgOff; + vmPgFault.vaddr = vaddr;//虚拟地址 + vmPgFault.pgoff = ((vaddr - region->range.base) >> PAGE_SHIFT) + region->pgOff;//计算出文件读取位置 vmPgFault.flags = flags; - vmPgFault.pageKVaddr = NULL; + vmPgFault.pageKVaddr = NULL;//缺失页初始化没有物理地址 - status = OsDoFileFault(region, &vmPgFault, flags); + status = OsDoFileFault(region, &vmPgFault, flags);//缺页处理 if (status) { VM_ERR("vm fault error, status=%d", status); goto CHECK_FAILED; @@ -408,27 +422,27 @@ STATUS_T OsVmPageFaultHandler(VADDR_T vaddr, UINT32 flags, ExcContext *frame) goto DONE; } #endif - - newPage = LOS_PhysPageAlloc(); + //请求调页:推迟到不能再推迟为止 + newPage = LOS_PhysPageAlloc();//分配一个新的物理页 if (newPage == NULL) { status = LOS_ERRNO_VM_NO_MEMORY; goto CHECK_FAILED; } - newPaddr = VM_PAGE_TO_PHYS(newPage); - (VOID)memset_s(OsVmPageToVaddr(newPage), PAGE_SIZE, 0, PAGE_SIZE); - status = LOS_ArchMmuQuery(&space->archMmu, vaddr, &oldPaddr, NULL); + newPaddr = VM_PAGE_TO_PHYS(newPage);//获取物理地址 + (VOID)memset_s(OsVmPageToVaddr(newPage), PAGE_SIZE, 0, PAGE_SIZE);//获取虚拟地址 清0 + status = LOS_ArchMmuQuery(&space->archMmu, vaddr, &oldPaddr, NULL);//通过虚拟地址查询老物理地址 if (status >= 0) { - LOS_ArchMmuUnmap(&space->archMmu, vaddr, 1); - OsPhysSharePageCopy(oldPaddr, &newPaddr, newPage); + LOS_ArchMmuUnmap(&space->archMmu, vaddr, 1);//解除映射关系 + OsPhysSharePageCopy(oldPaddr, &newPaddr, newPage);//将oldPaddr的数据拷贝到newPage /* use old page free the new one */ - if (newPaddr == oldPaddr) { - LOS_PhysPageFree(newPage); + if (newPaddr == oldPaddr) {//新老物理地址一致 + LOS_PhysPageFree(newPage);//继续使用旧页释放新页 newPage = NULL; } /* map all of the pages */ - status = LOS_ArchMmuMap(&space->archMmu, vaddr, newPaddr, 1, region->regionFlags); + status = LOS_ArchMmuMap(&space->archMmu, vaddr, newPaddr, 1, region->regionFlags);//重新映射新物理地址 if (status < 0) { VM_ERR("failed to map replacement page, status:%d", status); status = LOS_ERRNO_VM_MAP_FAILED; @@ -439,8 +453,8 @@ STATUS_T OsVmPageFaultHandler(VADDR_T vaddr, UINT32 flags, ExcContext *frame) goto DONE; } else { /* map all of the pages */ - LOS_AtomicInc(&newPage->refCounts); - status = LOS_ArchMmuMap(&space->archMmu, vaddr, newPaddr, 1, region->regionFlags); + LOS_AtomicInc(&newPage->refCounts);//引用数自增 + status = LOS_ArchMmuMap(&space->archMmu, vaddr, newPaddr, 1, region->regionFlags);//映射新物理地址,如此下次就不会缺页了 if (status < 0) { VM_ERR("failed to map page, status:%d", status); status = LOS_ERRNO_VM_MAP_FAILED; diff --git a/src/kernel_liteos_a/kernel/base/vm/los_vm_filemap.c b/src/kernel_liteos_a/kernel/base/vm/los_vm_filemap.c index e95cd826..2da700d8 100644 --- a/src/kernel_liteos_a/kernel/base/vm/los_vm_filemap.c +++ b/src/kernel_liteos_a/kernel/base/vm/los_vm_filemap.c @@ -66,98 +66,114 @@ VOID ResetPageCacheHitInfo(int *try, int *hit) #define TRACE_TRY_CACHE() #define TRACE_HIT_CACHE() #endif - #ifdef LOSCFG_KERNEL_VM +/** + * @brief + @verbatim + 增加文件页到页高速缓存(page cache) + LosFilePage将一个文件切成了一页一页,因为读文件过程随机seek,所以文件页也不会是连续的, + pgoff记录文件的位置,并确保在cache的文件数据是按顺序排列的. + @endverbatim + * @param page + * @param mapping + * @param pgoff + * @return STATIC + */ STATIC VOID OsPageCacheAdd(LosFilePage *page, struct page_mapping *mapping, VM_OFFSET_T pgoff) { LosFilePage *fpage = NULL; - LOS_DL_LIST_FOR_EACH_ENTRY(fpage, &mapping->page_list, LosFilePage, node) { - if (fpage->pgoff > pgoff) { - LOS_ListTailInsert(&fpage->node, &page->node); + LOS_DL_LIST_FOR_EACH_ENTRY(fpage, &mapping->page_list, LosFilePage, node) {//遍历page_list链表 + if (fpage->pgoff > pgoff) {//插入的条件,这样插入保证了按pgoff 从小到大排序 + LOS_ListTailInsert(&fpage->node, &page->node);//等于挂到fpage节点的前面了 goto done_add; } } - LOS_ListTailInsert(&mapping->page_list, &page->node); + LOS_ListTailInsert(&mapping->page_list, &page->node);//将页挂到文件映射的链表上,相当于挂到了最后 done_add: - mapping->nrpages++; + mapping->nrpages++; //文件在缓存中多了一个 文件页 } - +///将页面加到活动文件页LRU链表上 VOID OsAddToPageacheLru(LosFilePage *page, struct page_mapping *mapping, VM_OFFSET_T pgoff) { OsPageCacheAdd(page, mapping, pgoff); OsLruCacheAdd(page, VM_LRU_ACTIVE_FILE); } - +///从页高速缓存上删除页 VOID OsPageCacheDel(LosFilePage *fpage) { /* delete from file cache list */ - LOS_ListDelete(&fpage->node); - fpage->mapping->nrpages--; + LOS_ListDelete(&fpage->node);//将自己从链表上摘除 + fpage->mapping->nrpages--;//文件映射的页总数减少 /* unmap and remove map info */ - if (OsIsPageMapped(fpage)) { + if (OsIsPageMapped(fpage)) {//是否映射过 OsUnmapAllLocked(fpage); } - LOS_PhysPageFree(fpage->vmPage); + LOS_PhysPageFree(fpage->vmPage);//释放物理内存 - LOS_MemFree(m_aucSysMem0, fpage); + LOS_MemFree(m_aucSysMem0, fpage);//释放文件页结构体内存 } - +/************************************************************************************************** +每个进程都有自己的地址空间, 多个进程可以访问同一个LosFilePage,每个进程使用的虚拟地址都需要单独映射 +所以同一个LosFilePage会映射到多个进程空间.本函数记录页面被哪些进程映射过 +在两个地方会被被空间映射 +1.缺页中断 2.克隆地址空间 +**************************************************************************************************/ VOID OsAddMapInfo(LosFilePage *page, LosArchMmu *archMmu, VADDR_T vaddr) { LosMapInfo *info = NULL; - info = (LosMapInfo *)LOS_MemAlloc(m_aucSysMem0, sizeof(LosMapInfo)); + info = (LosMapInfo *)LOS_MemAlloc(m_aucSysMem0, sizeof(LosMapInfo));//分配一个映射信息 if (info == NULL) { VM_ERR("OsAddMapInfo alloc memory failed!"); return; } - info->page = page; - info->archMmu = archMmu; - info->vaddr = vaddr; + info->page = page; //文件页 + info->archMmu = archMmu;//进程MMU,完成虚实地址转换 + info->vaddr = vaddr; //虚拟地址 - LOS_ListAdd(&page->i_mmap, &info->node); - page->n_maps++; + LOS_ListAdd(&page->i_mmap, &info->node);//将 LosMapInfo 节点挂入链表 + page->n_maps++;//映射总数++ } - +///通过虚拟地址获取文件页映射信息,archMmu每个进程都有属于自己的mmu LosMapInfo *OsGetMapInfo(const LosFilePage *page, const LosArchMmu *archMmu, VADDR_T vaddr) { LosMapInfo *info = NULL; - const LOS_DL_LIST *immap = &page->i_mmap; + const LOS_DL_LIST *immap = &page->i_mmap;//一个文件页被多个进程映射 - LOS_DL_LIST_FOR_EACH_ENTRY(info, immap, LosMapInfo, node) { - if ((info->archMmu == archMmu) && (info->vaddr == vaddr) && (info->page == page)) { + LOS_DL_LIST_FOR_EACH_ENTRY(info, immap, LosMapInfo, node) {//遍历每个节点 + if ((info->archMmu == archMmu) && (info->vaddr == vaddr) && (info->page == page)) {//全等时返回 return info; } } - return NULL; } - +///删除页高速缓存和LRU,对应 OsAddToPageacheLru VOID OsDeletePageCacheLru(LosFilePage *page) { - /* delete from lru list */ - OsLruCacheDel(page); - /* delete from cache list and free pmm if needed */ - OsPageCacheDel(page); + /* delete form lru list */ + OsLruCacheDel(page); //将页面从lru列表中删除 + /* delete from cache lits and free pmm if need */ + OsPageCacheDel(page); //从page缓存中删除 } +//解除文件页和进程的映射关系 STATIC VOID OsPageCacheUnmap(LosFilePage *fpage, LosArchMmu *archMmu, VADDR_T vaddr) { UINT32 intSave; LosMapInfo *info = NULL; LOS_SpinLockSave(&fpage->physSeg->lruLock, &intSave); - info = OsGetMapInfo(fpage, archMmu, vaddr); + info = OsGetMapInfo(fpage, archMmu, vaddr);//获取文件页在进程的映射信息 if (info == NULL) { VM_ERR("OsPageCacheUnmap get map info failed!"); } else { - OsUnmapPageLocked(fpage, info); + OsUnmapPageLocked(fpage, info);//解除进程和文件页映射关系 } if (!(OsIsPageMapped(fpage) && ((fpage->flags & VM_MAP_REGION_FLAG_PERM_EXECUTE) || OsIsPageDirty(fpage->vmPage)))) { @@ -166,7 +182,7 @@ STATIC VOID OsPageCacheUnmap(LosFilePage *fpage, LosArchMmu *archMmu, VADDR_T va LOS_SpinUnlockRestore(&fpage->physSeg->lruLock, intSave); } - +///删除文件 VOID OsVmmFileRemove(LosVmMapRegion *region, LosArchMmu *archMmu, VM_OFFSET_T pgoff) { UINT32 intSave; @@ -179,31 +195,31 @@ VOID OsVmmFileRemove(LosVmMapRegion *region, LosArchMmu *archMmu, VM_OFFSET_T pg LosVmPage *mapPage = NULL; if (!LOS_IsRegionFileValid(region) || (region->unTypeData.rf.vnode == NULL)) { - return; + return;//判断是否为文件映射,是否已map } vnode = region->unTypeData.rf.vnode; mapping = &vnode->mapping; - vaddr = region->range.base + ((UINT32)(pgoff - region->pgOff) << PAGE_SHIFT); + vaddr = region->range.base + ((UINT32)(pgoff - region->pgOff) << PAGE_SHIFT);//得到虚拟地址 - status_t status = LOS_ArchMmuQuery(archMmu, vaddr, &paddr, NULL); + status_t status = LOS_ArchMmuQuery(archMmu, vaddr, &paddr, NULL);//获取物理地址 if (status != LOS_OK) { return; } - mapPage = LOS_VmPageGet(paddr); + mapPage = LOS_VmPageGet(paddr);//获取物理页框 /* is page is in cache list */ LOS_SpinLockSave(&mapping->list_lock, &intSave); - fpage = OsFindGetEntry(mapping, pgoff); + fpage = OsFindGetEntry(mapping, pgoff);//获取fpage /* no cache or have cache but not map(cow), free it direct */ - if ((fpage == NULL) || (fpage->vmPage != mapPage)) { - LOS_PhysPageFree(mapPage); - LOS_ArchMmuUnmap(archMmu, vaddr, 1); + if ((fpage == NULL) || (fpage->vmPage != mapPage)) {//没有缓存或有缓存但没有映射(cow),直接释放它 + LOS_PhysPageFree(mapPage);//释放物理页框 + LOS_ArchMmuUnmap(archMmu, vaddr, 1);//取消虚拟地址的映射 /* this is a page cache map! */ } else { - OsPageCacheUnmap(fpage, archMmu, vaddr); - if (OsIsPageDirty(fpage->vmPage)) { - tmpPage = OsDumpDirtyPage(fpage); + OsPageCacheUnmap(fpage, archMmu, vaddr);////取消缓存中的映射 + if (OsIsPageDirty(fpage->vmPage)) {//脏页处理 + tmpPage = OsDumpDirtyPage(fpage);//dump 脏页 } } LOS_SpinUnlockRestore(&mapping->list_lock, intSave); @@ -213,15 +229,15 @@ VOID OsVmmFileRemove(LosVmMapRegion *region, LosArchMmu *archMmu, VM_OFFSET_T pg } return; } - +///标记page为脏页 进程修改了高速缓存里的数据时,该页就被内核标记为脏页 VOID OsMarkPageDirty(LosFilePage *fpage, const LosVmMapRegion *region, INT32 off, INT32 len) { if (region != NULL) { - OsSetPageDirty(fpage->vmPage); - fpage->dirtyOff = off; - fpage->dirtyEnd = len; + OsSetPageDirty(fpage->vmPage);//设置为脏页 + fpage->dirtyOff = off;//脏页偏移位置 + fpage->dirtyEnd = len;//脏页结束位置 } else { - OsSetPageDirty(fpage->vmPage); + OsSetPageDirty(fpage->vmPage);//设置为脏页 if ((off + len) > fpage->dirtyEnd) { fpage->dirtyEnd = off + len; } @@ -258,22 +274,22 @@ STATIC UINT32 GetDirtySize(LosFilePage *fpage, struct Vnode *vnode) return PAGE_SIZE; } - +///冲洗脏页,回写磁盘 STATIC INT32 OsFlushDirtyPage(LosFilePage *fpage) { UINT32 ret; size_t len; char *buff = NULL; - struct Vnode *vnode = fpage->mapping->host; + struct Vnode *vnode = fpage->mapping->host;/* owner of this mapping */ //此映射属于哪个文件,注意是1:1的关系. if (vnode == NULL) { VM_ERR("page cache vnode error"); return LOS_NOK; } - len = fpage->dirtyEnd - fpage->dirtyOff; + len = fpage->dirtyEnd - fpage->dirtyOff;//计算出脏数据长度 len = (len == 0) ? GetDirtySize(fpage, vnode) : len; - if (len == 0) { - OsCleanPageDirty(fpage->vmPage); + if (len == 0) {//没有脏数据 + OsCleanPageDirty(fpage->vmPage);//页面取消脏标签 return LOS_OK; } @@ -290,7 +306,7 @@ STATIC INT32 OsFlushDirtyPage(LosFilePage *fpage) return ret; } - +///备份脏页,老脏页撕掉脏页标签 LosFilePage *OsDumpDirtyPage(LosFilePage *oldFPage) { LosFilePage *newFPage = NULL; @@ -302,11 +318,11 @@ LosFilePage *OsDumpDirtyPage(LosFilePage *oldFPage) } OsCleanPageDirty(oldFPage->vmPage); - (VOID)memcpy_s(newFPage, sizeof(LosFilePage), oldFPage, sizeof(LosFilePage)); + (VOID)memcpy_s(newFPage, sizeof(LosFilePage), oldFPage, sizeof(LosFilePage));//直接内存拷贝 return newFPage; } - +///冲洗脏页数据,将脏页数据回写磁盘 VOID OsDoFlushDirtyPage(LosFilePage *fpage) { if (fpage == NULL) { @@ -328,7 +344,7 @@ STATIC VOID OsReleaseFpage(struct page_mapping *mapping, LosFilePage *fpage) LOS_SpinUnlockRestore(lruLock, lruSave); LOS_SpinUnlockRestore(&mapping->list_lock, intSave); } - +///删除映射信息 VOID OsDelMapInfo(LosVmMapRegion *region, LosVmPgFault *vmf, BOOL cleanDirty) { UINT32 intSave; @@ -349,9 +365,9 @@ VOID OsDelMapInfo(LosVmMapRegion *region, LosVmPgFault *vmf, BOOL cleanDirty) } if (cleanDirty) { - OsCleanPageDirty(fpage->vmPage); + OsCleanPageDirty(fpage->vmPage);//恢复干净页 } - info = OsGetMapInfo(fpage, ®ion->space->archMmu, (vaddr_t)vmf->vaddr); + info = OsGetMapInfo(fpage, ®ion->space->archMmu, (vaddr_t)vmf->vaddr);//通过虚拟地址获取映射信息 if (info != NULL) { fpage->n_maps--; LOS_ListDelete(&info->node); @@ -362,7 +378,10 @@ VOID OsDelMapInfo(LosVmMapRegion *region, LosVmPgFault *vmf, BOOL cleanDirty) } LOS_SpinUnlockRestore(&mapping->list_lock, intSave); } - +/*! +文件缺页时的处理,先读入磁盘数据,再重新读页数据 +被 OsDoReadFault(...),OsDoCowFault(...),OsDoSharedFault(...) 等调用 +*/ INT32 OsVmmFileFault(LosVmMapRegion *region, LosVmPgFault *vmf) { INT32 ret; @@ -374,7 +393,7 @@ INT32 OsVmmFileFault(LosVmMapRegion *region, LosVmPgFault *vmf) struct page_mapping *mapping = NULL; LosFilePage *fpage = NULL; - if (!LOS_IsRegionFileValid(region) || (region->unTypeData.rf.vnode == NULL) || (vmf == NULL)) { + if (!LOS_IsRegionFileValid(region) || (region->unTypeData.rf.vnode == NULL) || (vmf == NULL)) {//文件是否映射到了内存 VM_ERR("Input param is NULL"); return LOS_NOK; } @@ -383,26 +402,26 @@ INT32 OsVmmFileFault(LosVmMapRegion *region, LosVmPgFault *vmf) /* get or create a new cache node */ LOS_SpinLockSave(&mapping->list_lock, &intSave); - fpage = OsFindGetEntry(mapping, vmf->pgoff); + fpage = OsFindGetEntry(mapping, vmf->pgoff);//获取文件页 TRACE_TRY_CACHE(); - if (fpage != NULL) { + if (fpage != NULL) {//找到了,说明该页已经在页高速缓存中 TRACE_HIT_CACHE(); OsPageRefIncLocked(fpage); - } else { - fpage = OsPageCacheAlloc(mapping, vmf->pgoff); + } else {//真的缺页了,页高速缓存中没找到 + fpage = OsPageCacheAlloc(mapping, vmf->pgoff);//分配一个文件页,将数据初始化好,包括vmpage(物理页框) if (fpage == NULL) { LOS_SpinUnlockRestore(&mapping->list_lock, intSave); VM_ERR("Failed to alloc a page frame"); return LOS_NOK; } - newCache = true; + newCache = true;//分配了新文件页 } - OsSetPageLocked(fpage->vmPage); + OsSetPageLocked(fpage->vmPage);//对vmpage上锁 LOS_SpinUnlockRestore(&mapping->list_lock, intSave); - kvaddr = OsVmPageToVaddr(fpage->vmPage); + kvaddr = OsVmPageToVaddr(fpage->vmPage);//获取该页框在内核空间的虚拟地址,因为 page cache本身就是在内核空间, /* read file to new page cache */ - if (newCache) { + if (newCache) {//新cache ret = vnode->vop->ReadPage(vnode, kvaddr, fpage->pgoff << PAGE_SHIFT); if (ret == 0) { VM_ERR("Failed to read from file!"); @@ -410,32 +429,32 @@ INT32 OsVmmFileFault(LosVmMapRegion *region, LosVmPgFault *vmf) return LOS_NOK; } LOS_SpinLockSave(&mapping->list_lock, &intSave); - OsAddToPageacheLru(fpage, mapping, vmf->pgoff); + OsAddToPageacheLru(fpage, mapping, vmf->pgoff);//将fpage挂入pageCache 和 LruCache LOS_SpinUnlockRestore(&mapping->list_lock, intSave); } LOS_SpinLockSave(&mapping->list_lock, &intSave); /* cow fault case no need to save mapinfo */ if (!((vmf->flags & VM_MAP_PF_FLAG_WRITE) && !(region->regionFlags & VM_MAP_REGION_FLAG_SHARED))) { - OsAddMapInfo(fpage, ®ion->space->archMmu, (vaddr_t)vmf->vaddr); + OsAddMapInfo(fpage, ®ion->space->archMmu, (vaddr_t)vmf->vaddr);//添加<虚拟地址,文件页>的映射关系,如此进程以后就能通过虚拟地址操作文件页了. fpage->flags = region->regionFlags; } /* share page fault, mark the page dirty */ - if ((vmf->flags & VM_MAP_PF_FLAG_WRITE) && (region->regionFlags & VM_MAP_REGION_FLAG_SHARED)) { - OsMarkPageDirty(fpage, region, 0, 0); + if ((vmf->flags & VM_MAP_PF_FLAG_WRITE) && (region->regionFlags & VM_MAP_REGION_FLAG_SHARED)) {//有过写操作或者为共享线性区 + OsMarkPageDirty(fpage, region, 0, 0);//标记为脏页,要回写磁盘,内核会在适当的时候回写磁盘 } - vmf->pageKVaddr = kvaddr; + vmf->pageKVaddr = kvaddr;//缺陷页记录文件页的虚拟地址 LOS_SpinUnlockRestore(&mapping->list_lock, intSave); return LOS_OK; } - +///文件缓存冲洗,把所有fpage冲洗一边,把脏页洗到dirtyList中,配合OsFileCacheRemove理解 VOID OsFileCacheFlush(struct page_mapping *mapping) { UINT32 intSave; UINT32 lruLock; - LOS_DL_LIST_HEAD(dirtyList); + LOS_DL_LIST_HEAD(dirtyList);//LOS_DL_LIST list = { &(list), &(list) }; LosFilePage *ftemp = NULL; LosFilePage *fpage = NULL; @@ -443,70 +462,77 @@ VOID OsFileCacheFlush(struct page_mapping *mapping) return; } LOS_SpinLockSave(&mapping->list_lock, &intSave); - LOS_DL_LIST_FOR_EACH_ENTRY(fpage, &mapping->page_list, LosFilePage, node) { + LOS_DL_LIST_FOR_EACH_ENTRY(fpage, &mapping->page_list, LosFilePage, node) {//循环从page_list中取node给fpage LOS_SpinLockSave(&fpage->physSeg->lruLock, &lruLock); - if (OsIsPageDirty(fpage->vmPage)) { - ftemp = OsDumpDirtyPage(fpage); + if (OsIsPageDirty(fpage->vmPage)) {//是否为脏页 + ftemp = OsDumpDirtyPage(fpage);//这里挺妙的,copy出一份新页,老页变成了非脏页继续用 if (ftemp != NULL) { - LOS_ListTailInsert(&dirtyList, &ftemp->node); + LOS_ListTailInsert(&dirtyList, &ftemp->node);//将新页插入脏页List,等待回写磁盘 } } LOS_SpinUnlockRestore(&fpage->physSeg->lruLock, lruLock); } LOS_SpinUnlockRestore(&mapping->list_lock, intSave); - LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(fpage, ftemp, &dirtyList, LosFilePage, node) { - OsDoFlushDirtyPage(fpage); + LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(fpage, ftemp, &dirtyList, LosFilePage, node) {//仔细看这个宏,关键在 &(item)->member != (list); + OsDoFlushDirtyPage(fpage);//立马洗掉,所以dirtyList可以不是全局变量 } } +/****************************************************************************** + 删除文件缓存,清空文件在page cache的痕迹 + 参数 mapping 可理解为文件在内存的身份证 +******************************************************************************/ VOID OsFileCacheRemove(struct page_mapping *mapping) { UINT32 intSave; UINT32 lruSave; SPIN_LOCK_S *lruLock = NULL; - LOS_DL_LIST_HEAD(dirtyList); + LOS_DL_LIST_HEAD(dirtyList);//定义一个叫dirtyList的双循环链表并初始化,用于挂脏页 LosFilePage *ftemp = NULL; LosFilePage *fpage = NULL; LosFilePage *fnext = NULL; - LOS_SpinLockSave(&mapping->list_lock, &intSave); - LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(fpage, fnext, &mapping->page_list, LosFilePage, node) { + LOS_SpinLockSave(&mapping->list_lock, &intSave);//多进程操作,必须上锁. + LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(fpage, fnext, &mapping->page_list, LosFilePage, node) {//遍历文件在内存中产生的所有文件页(例如1,4,8页)不一定连续,取决于用户的读取顺序 lruLock = &fpage->physSeg->lruLock; - LOS_SpinLockSave(lruLock, &lruSave); - if (OsIsPageDirty(fpage->vmPage)) { - ftemp = OsDumpDirtyPage(fpage); - if (ftemp != NULL) { - LOS_ListTailInsert(&dirtyList, &ftemp->node); + LOS_SpinLockSave(lruLock, &lruSave);//@note_why 自旋锁有必要从这里开始上锁吗? + if (OsIsPageDirty(fpage->vmPage)) {//数据是脏页吗,脏页就是被修改过数据的页 + ftemp = OsDumpDirtyPage(fpage);//做这个拷贝动作是为了fpage的统一下线,因为数据回写磁盘的速度是很慢的,如果直接在这里处理脏数据 + if (ftemp != NULL) {//会导致函数持有mapping->list_lock自旋锁的时间太长了,影响其他CPU的处理效率 + LOS_ListTailInsert(&dirtyList, &ftemp->node);//将临时脏页挂到记录脏页链表上 } } - OsDeletePageCacheLru(fpage); + OsDeletePageCacheLru(fpage);//删除高速缓存和从置换链表中下线 LOS_SpinUnlockRestore(lruLock, lruSave); } - LOS_SpinUnlockRestore(&mapping->list_lock, intSave); + LOS_SpinUnlockRestore(&mapping->list_lock, intSave);//恢复自旋锁,不能让别的CPU等太久 - LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(fpage, fnext, &dirtyList, LosFilePage, node) { - OsDoFlushDirtyPage(fpage); + LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(fpage, fnext, &dirtyList, LosFilePage, node) {//到这里,再来慢慢的统一处理脏页数据 + OsDoFlushDirtyPage(fpage);//遍历脏页链表,一页一页处理 } } - -LosVmFileOps g_commVmOps = { +///虚拟内存文件操作实现类 +LosVmFileOps g_commVmOps = {// .open = NULL, .close = NULL, - .fault = OsVmmFileFault, - .remove = OsVmmFileRemove, + .fault = OsVmmFileFault, //缺页中断处理 + .remove = OsVmmFileRemove,//删除页 }; - +//文件映射 INT32 OsVfsFileMmap(struct file *filep, LosVmMapRegion *region) { - region->unTypeData.rf.vmFOps = &g_commVmOps; + region->unTypeData.rf.vmFOps = &g_commVmOps;//文件操作 region->unTypeData.rf.vnode = filep->f_vnode; region->unTypeData.rf.f_oflags = filep->f_oflags; return ENOERR; } - +/*! + 有名映射,可理解为文件映射,跟匿名映射相对应 + 参数filep是广义的文件,在鸿蒙内核,目录/普通文件/字符设备/块设备/网络套接字/管道/链接 都是文件 +*/ STATUS_T OsNamedMMap(struct file *filep, LosVmMapRegion *region) { struct Vnode *vnode = NULL; @@ -519,10 +545,10 @@ STATUS_T OsNamedMMap(struct file *filep, LosVmMapRegion *region) vnode->useCount++; VnodeDrop(); if (filep->ops != NULL && filep->ops->mmap != NULL) { - if (vnode->type == VNODE_TYPE_CHR || vnode->type == VNODE_TYPE_BLK) { - LOS_SetRegionTypeDev(region); + if (vnode->type == VNODE_TYPE_CHR || vnode->type == VNODE_TYPE_BLK) {//块设备或者字符设备 /dev/.. + LOS_SetRegionTypeDev(region);//设置为设备类型 } else { - LOS_SetRegionTypeFile(region); + LOS_SetRegionTypeFile(region);//设置为文件类型 } int ret = filep->ops->mmap(filep, region); if (ret != LOS_OK) { @@ -538,17 +564,21 @@ STATUS_T OsNamedMMap(struct file *filep, LosVmMapRegion *region) return LOS_OK; } +/************************************************************************************************** + 通过位置从文件映射页中找到的指定的文件页 + 举例:mapping->page_list上节点的数据可能只有是文件 1,3,4,6 页的数据,此时来找文件第5页的数据就会没有 +**************************************************************************************************/ LosFilePage *OsFindGetEntry(struct page_mapping *mapping, VM_OFFSET_T pgoff) { LosFilePage *fpage = NULL; - LOS_DL_LIST_FOR_EACH_ENTRY(fpage, &mapping->page_list, LosFilePage, node) { - if (fpage->pgoff == pgoff) { + LOS_DL_LIST_FOR_EACH_ENTRY(fpage, &mapping->page_list, LosFilePage, node) {//遍历文件页 + if (fpage->pgoff == pgoff) {//找到指定的页, return fpage; } - if (fpage->pgoff > pgoff) { - break; + if (fpage->pgoff > pgoff) {//大于之前还没有找到,说明不在链表中,往后的也不用找了, + break;//因为 mapping->page_list节点上的数据都是按 fpage->pgoff 从小到大的顺序排列的. } } @@ -556,6 +586,11 @@ LosFilePage *OsFindGetEntry(struct page_mapping *mapping, VM_OFFSET_T pgoff) } /* need mutex & change memory to dma zone. */ +/*! +以页高速缓存方式分配一个文件页 LosFilePage + Direct Memory Access(存储器直接访问)指一种高速的数据传输操作,允许在外部设备和存储器之间直接读写数据。 + 整个数据传输操作在一个称为"DMA控制器"的控制下进行的。CPU只需在数据传输开始和结束时做一点处理(开始和结束时候要做中断处理) +*/ LosFilePage *OsPageCacheAlloc(struct page_mapping *mapping, VM_OFFSET_T pgoff) { VOID *kvaddr = NULL; @@ -563,39 +598,39 @@ LosFilePage *OsPageCacheAlloc(struct page_mapping *mapping, VM_OFFSET_T pgoff) LosVmPage *vmPage = NULL; LosFilePage *fpage = NULL; - vmPage = LOS_PhysPageAlloc(); + vmPage = LOS_PhysPageAlloc(); //先分配一个物理页 if (vmPage == NULL) { VM_ERR("alloc vm page failed"); return NULL; } - physSeg = OsVmPhysSegGet(vmPage); - kvaddr = OsVmPageToVaddr(vmPage); + physSeg = OsVmPhysSegGet(vmPage);//通过页获取所在seg + kvaddr = OsVmPageToVaddr(vmPage);//获取内核空间的虚拟地址,具体点进去看函数说明,这里一定要理解透彻! if ((physSeg == NULL) || (kvaddr == NULL)) { - LOS_PhysPageFree(vmPage); + LOS_PhysPageFree(vmPage); //异常情况要释放vmPage VM_ERR("alloc vm page failed!"); return NULL; } - fpage = (LosFilePage *)LOS_MemAlloc(m_aucSysMem0, sizeof(LosFilePage)); + fpage = (LosFilePage *)LOS_MemAlloc(m_aucSysMem0, sizeof(LosFilePage));//从内存池中分配一个filePage if (fpage == NULL) { - LOS_PhysPageFree(vmPage); + LOS_PhysPageFree(vmPage); //异常情况要释放vmPage VM_ERR("Failed to allocate for page!"); return NULL; } - (VOID)memset_s((VOID *)fpage, sizeof(LosFilePage), 0, sizeof(LosFilePage)); + (VOID)memset_s((VOID *)fpage, sizeof(LosFilePage), 0, sizeof(LosFilePage));//调标准库函数 置0 - LOS_ListInit(&fpage->i_mmap); - LOS_ListInit(&fpage->node); - LOS_ListInit(&fpage->lru); - fpage->n_maps = 0; - fpage->dirtyOff = PAGE_SIZE; - fpage->dirtyEnd = 0; - fpage->physSeg = physSeg; - fpage->vmPage = vmPage; - fpage->mapping = mapping; - fpage->pgoff = pgoff; - (VOID)memset_s(kvaddr, PAGE_SIZE, 0, PAGE_SIZE); + LOS_ListInit(&fpage->i_mmap); //初始化映射,链表上挂 MapInfo + LOS_ListInit(&fpage->node); //节点初始化 + LOS_ListInit(&fpage->lru); //LRU初始化 + fpage->n_maps = 0; //映射次数 + fpage->dirtyOff = PAGE_SIZE; //默认页尾部,相当于没有脏数据 + fpage->dirtyEnd = 0; //脏页结束位置 + fpage->physSeg = physSeg; //页框所属段.其中包含了 LRU LIST == + fpage->vmPage = vmPage; //物理页框 + fpage->mapping = mapping; //记录所有文件页映射 + fpage->pgoff = pgoff; //将文件切成一页页,页标 + (VOID)memset_s(kvaddr, PAGE_SIZE, 0, PAGE_SIZE);//页内数据清0 return fpage; } @@ -609,4 +644,4 @@ INT32 OsVfsFileMmap(struct file *filep, LosVmMapRegion *region) } #endif -#endif +#endif \ No newline at end of file diff --git a/src/kernel_liteos_a/kernel/base/vm/los_vm_iomap.c b/src/kernel_liteos_a/kernel/base/vm/los_vm_iomap.c index a313da14..0d076a53 100644 --- a/src/kernel_liteos_a/kernel/base/vm/los_vm_iomap.c +++ b/src/kernel_liteos_a/kernel/base/vm/los_vm_iomap.c @@ -1,3 +1,42 @@ +/* + 直接内存访问 + 直接内存访问(Direct Memory Access,DMA)是计算机科学中的一种内存访问技术。它允许某些电脑内部的 + 硬件子系统(电脑外设),可以独立地直接读写系统内存,而不需中央处理器(CPU)介入处理 + 在同等程度的处理器负担下,DMA是一种快速的数据传送方式。很多硬件的系统会使用DMA,包含硬盘控制器、 + 绘图显卡、网卡和声卡。 + + DMA是所有现代电脑的重要特色,它允许不同速度的硬件设备来沟通,而不需要依于中央处理器的大量中断负载。 + 否则,中央处理器需要从来源把每一片段的资料复制到寄存器,然后把它们再次写回到新的地方。在这个时间中, + 中央处理器对于其他的工作来说就无法使用。 + + DMA传输常使用在将一个内存区从一个设备复制到另外一个。当中央处理器初始化这个传输动作,传输动作本身是 + 由DMA控制器来实行和完成。典型的例子就是移动一个外部内存的区块到芯片内部更快的内存去。像是这样的操作 + 并没有让处理器工作拖延,使其可以被重新调度去处理其他的工作。DMA传输对于高性能嵌入式系统算法和网络是 + 很重要的。 举个例子,个人电脑的ISA DMA控制器拥有8个DMA通道,其中的7个通道是可以让计算机的中央处理器所利用。 + 每一个DMA通道有一个16位地址寄存器和一个16位计数寄存器。要初始化资料传输时,设备驱动程序一起设置DMA通道的 + 地址和计数寄存器,以及资料传输的方向,读取或写入。然后指示DMA硬件开始这个传输动作。当传输结束的时候, + 设备就会以中断的方式通知中央处理器。 + + "分散-收集"(Scatter-gather)DMA允许在一次单一的DMA处理中传输资料到多个内存区域。相当于把多个简单的DMA要求 + 串在一起。同样,这样做的目的是要减轻中央处理器的多次输出输入中断和资料复制任务。 + DRQ意为DMA要求;DACK意为DMA确认。这些符号一般在有DMA功能的电脑系统硬件概要上可以看到。 + 它们表示了介于中央处理器和DMA控制器之间的电子信号传输线路。 + + 缓存一致性问题 + DMA会导致缓存一致性问题。想像中央处理器带有缓存与外部内存的情况,DMA的运作则是去访问外部内存, + 当中央处理器访问外部内存某个地址的时候,暂时先将新的值写入缓存中,但并未将外部内存的资料更新, + 若在缓存中的资料尚未更新到外部内存前发生了DMA,则DMA过程将会读取到未更新的资料。 + 相同的,如果外部设备写入新的值到外部内存内,则中央处理器若访问缓存时则会访问到尚未更新的资料。 + 这些问题可以用两种方法来解决: + + 缓存同调系统(Cache-coherent system):以硬件方法来完成,当外部设备写入内存时以一个信号来通知 + 缓存控制器某内存地址的值已经过期或是应该更新资料。 + 非同调系统(Non-coherent system):以软件方法来完成,操作系统必须确认缓存读取时,DMA程序已经 + 开始或是禁止DMA发生。 + 第二种的方法会造成DMA的系统负担。 + */ + + /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. @@ -36,7 +75,7 @@ #include "los_vm_map.h" #include "los_memory.h" - +///分配DMA空间 VOID *LOS_DmaMemAlloc(DMA_ADDR_T *dmaAddr, size_t size, size_t align, enum DmaMemType type) { VOID *kVaddr = NULL; @@ -53,24 +92,24 @@ VOID *LOS_DmaMemAlloc(DMA_ADDR_T *dmaAddr, size_t size, size_t align, enum DmaMe #ifdef LOSCFG_KERNEL_VM kVaddr = LOS_KernelMallocAlign(size, align); #else - kVaddr = LOS_MemAllocAlign(OS_SYS_MEM_ADDR, size, align); + kVaddr = LOS_MemAllocAlign(OS_SYS_MEM_ADDR, size, align);//不走内存池方式, 直接申请物理页 #endif if (kVaddr == NULL) { - VM_ERR("failed, size = %u, align = %u", size, align); + VM_ERR("failed, size = %u, align = %u", size, align);//从内存池中申请 return NULL; } if (dmaAddr != NULL) { - *dmaAddr = (DMA_ADDR_T)LOS_PaddrQuery(kVaddr); + *dmaAddr = (DMA_ADDR_T)LOS_PaddrQuery(kVaddr);//查询物理地址, DMA直接将数据灌到物理地址 } - if (type == DMA_NOCACHE) { + if (type == DMA_NOCACHE) {//无缓存模式 , 计算新的虚拟地址 kVaddr = (VOID *)VMM_TO_UNCACHED_ADDR((UINTPTR)kVaddr); } return kVaddr; } - +///释放DMA指针 VOID LOS_DmaMemFree(VOID *vaddr) { UINTPTR addr; @@ -79,13 +118,13 @@ VOID LOS_DmaMemFree(VOID *vaddr) return; } addr = (UINTPTR)vaddr; - + // 未缓存区 if ((addr >= UNCACHED_VMM_BASE) && (addr < UNCACHED_VMM_BASE + UNCACHED_VMM_SIZE)) { - addr = UNCACHED_TO_VMM_ADDR(addr); + addr = UNCACHED_TO_VMM_ADDR(addr);//转换成未缓存区地址 #ifdef LOSCFG_KERNEL_VM LOS_KernelFree((VOID *)addr); #else - LOS_MemFree(OS_SYS_MEM_ADDR, (VOID *)addr); + LOS_MemFree(OS_SYS_MEM_ADDR, (VOID *)addr);//内存池方式释放 #endif } else if ((addr >= KERNEL_VMM_BASE) && (addr < KERNEL_VMM_BASE + KERNEL_VMM_SIZE)) { #ifdef LOSCFG_KERNEL_VM diff --git a/src/kernel_liteos_a/kernel/base/vm/los_vm_map.c b/src/kernel_liteos_a/kernel/base/vm/los_vm_map.c index 5d4f62b3..4aeef716 100644 --- a/src/kernel_liteos_a/kernel/base/vm/los_vm_map.c +++ b/src/kernel_liteos_a/kernel/base/vm/los_vm_map.c @@ -1,3 +1,43 @@ +/* +基本概念 + 虚拟内存管理是计算机系统管理内存的一种技术。每个进程都有连续的虚拟地址空间,虚拟地址空间的大小由CPU的位数决定, + 32位的硬件平台可以提供的最大的寻址空间为0-4GiB。整个4GiB空间分成两部分,LiteOS-A内核占据3GiB的高地址空间, + 1GiB的低地址空间留给进程使用。各个进程空间的虚拟地址空间是独立的,代码、数据互不影响。 + + 系统将虚拟内存分割为称为虚拟页的内存块,大小一般为4KiB或64KiB,LiteOS-A内核默认的页的大小是4KiB, + 根据需要可以对MMU(Memory Management Units)进行配置。虚拟内存管理操作的最小单位就是一个页, + LiteOS-A内核中一个虚拟地址区间region包含地址连续的多个虚拟页,也可只有一个页。同样,物理内存也会按照页大小进行分割, + 分割后的每个内存块称为页帧。虚拟地址空间划分:内核态占高地址3GiB(0x40000000 ~ 0xFFFFFFFF), + 用户态占低地址1GiB(0x01000000 ~ 0x3F000000),具体见下表,详细可以查看或配置los_vm_zone.h。 + +内核态地址规划: + Zone名称 描述 属性 + ---------------------------------------------------------------------------- + DMA zone 供IO设备的DMA使用。 Uncache + + Normal zone 加载内核代码段、数据段、堆和栈的地址区间。 Cache + + high mem zone可以分配连续的虚拟内存,但其所映射的物理内存不一定连续。Cache + +用户态地址规划: + Zone名称 描述 属性 + ---------------------------------------------------------------------------- + 代码段 用户态代码段地址区间。 Cache + 堆 用户态堆地址区间。 Cache + 栈 用户态栈地址区间。 Cache + 共享库 用于加载用户态共享库的地址区间,包括mmap所映射的区间。 Cache + +运行机制 + 虚拟内存管理中,虚拟地址空间是连续的,但是其映射的物理内存并不一定是连续的,如下图所示。 + 可执行程序加载运行,CPU访问虚拟地址空间的代码或数据时存在两种情况: + + 1. CPU访问的虚拟地址所在的页,如V0,已经与具体的物理页P0做映射,CPU通过找到进程对应的页表条目(详见虚实映射), + 根据页表条目中的物理地址信息访问物理内存中的内容并返回。 + 2. CPU访问的虚拟地址所在的页,如V2,没有与具体的物理页做映射,系统会触发缺页异常,系统申请一个物理页, + 并把相应的信息拷贝到物理页中,并且把物理页的起始地址更新到页表条目中。此时CPU重新执行访问虚拟内存的指令 + 便能够访问到具体的代码或数据。 + */ + /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. @@ -51,57 +91,65 @@ #ifdef LOSCFG_KERNEL_VM -#define VM_MAP_WASTE_MEM_LEVEL (PAGE_SIZE >> 2) -LosMux g_vmSpaceListMux; -LOS_DL_LIST_HEAD(g_vmSpaceList); -LosVmSpace g_kVmSpace; -LosVmSpace g_vMallocSpace; +#define VM_MAP_WASTE_MEM_LEVEL (PAGE_SIZE >> 2) ///< 浪费内存大小(1K) +LosMux g_vmSpaceListMux; ///< 用于锁g_vmSpaceList的互斥量 +LOS_DL_LIST_HEAD(g_vmSpaceList); ///< 初始化全局虚拟空间节点,所有虚拟空间都挂到此节点上. +LosVmSpace g_kVmSpace; ///< 内核非分配空间,用于内核运行栈,代码区,数据区 +LosVmSpace g_vMallocSpace; ///< 内核分配空间,用于内核分配内存 +/************************************************************ +* 获取进程空间系列接口 +************************************************************/ +/// 获取当前进程空间结构体指针 LosVmSpace *LOS_CurrSpaceGet(VOID) { return OsCurrProcessGet()->vmSpace; } - +/// 获取虚拟地址对应的进程空间结构体指针 LosVmSpace *LOS_SpaceGet(VADDR_T vaddr) { - if (LOS_IsKernelAddress(vaddr)) { - return LOS_GetKVmSpace(); - } else if (LOS_IsUserAddress(vaddr)) { + if (LOS_IsKernelAddress(vaddr)) { //是否为内核空间 + return LOS_GetKVmSpace(); //获取内核空间 + } else if (LOS_IsUserAddress(vaddr)) {//是否为用户空间 return LOS_CurrSpaceGet(); - } else if (LOS_IsVmallocAddress(vaddr)) { - return LOS_GetVmallocSpace(); + } else if (LOS_IsVmallocAddress(vaddr)) {//是否为内核分配空间 + return LOS_GetVmallocSpace();//获取内核分配空间 } else { return NULL; } } - +///内核空间只有g_kVmSpace一个,所有的内核进程都共用一个内核空间 LosVmSpace *LOS_GetKVmSpace(VOID) { return &g_kVmSpace; } - +///获取进程空间链表指针 g_vmSpaceList中挂的是进程空间 g_kVmSpace, g_vMallocSpace,所有用户进程的空间(独有一个进程空间) LOS_DL_LIST *LOS_GetVmSpaceList(VOID) { return &g_vmSpaceList; } - +///获取内核堆空间的全局变量 LosVmSpace *LOS_GetVmallocSpace(VOID) { return &g_vMallocSpace; } +/************************************************************ +* 虚拟地址区间region相关的操作 +************************************************************/ +///释放挂在红黑树上节点,等于释放了线性区 ULONG_T OsRegionRbFreeFn(LosRbNode *pstNode) { LOS_MemFree(m_aucSysMem0, pstNode); return LOS_OK; } - +///通过红黑树节点找到对应的线性区 VOID *OsRegionRbGetKeyFn(LosRbNode *pstNode) { LosVmMapRegion *region = (LosVmMapRegion *)LOS_DL_LIST_ENTRY(pstNode, LosVmMapRegion, rbNode); return (VOID *)®ion->range; } - +///比较两个红黑树节点 ULONG_T OsRegionRbCmpKeyFn(const VOID *pNodeKeyA, const VOID *pNodeKeyB) { LosVmMapRange rangeA = *(LosVmMapRange *)pNodeKeyA; @@ -111,129 +159,146 @@ ULONG_T OsRegionRbCmpKeyFn(const VOID *pNodeKeyA, const VOID *pNodeKeyB) UINT32 startB = rangeB.base; UINT32 endB = rangeB.base + rangeB.size - 1; - if (startA > endB) { - return RB_BIGGER; + if (startA > endB) {// A基地址大于B的结束地址 + return RB_BIGGER; //说明线性区A更大,在右边 } else if (startA >= startB) { if (endA <= endB) { - return RB_EQUAL; + return RB_EQUAL; //相等,说明 A在B中 } else { - return RB_BIGGER; + return RB_BIGGER; //说明 A的结束地址更大 } - } else if (startA <= startB) { + } else if (startA <= startB) { //A基地址小于等于B的基地址 if (endA >= endB) { - return RB_EQUAL; + return RB_EQUAL; //相等 说明 B在A中 } else { - return RB_SMALLER; + return RB_SMALLER;//说明A的结束地址更小 } - } else if (endA < startB) { - return RB_SMALLER; + } else if (endA < startB) {//A结束地址小于B的开始地址 + return RB_SMALLER;//说明A在 } return RB_EQUAL; } +/*! + * @brief OsVmSpaceInitCommon 初始化进程虚拟空间,必须提供L1表的虚拟内存地址 + * + * @param virtTtb L1表的地址,TTB表地址 + * @param vmSpace + * @return + * + * @see + */ STATIC BOOL OsVmSpaceInitCommon(LosVmSpace *vmSpace, VADDR_T *virtTtb) { - LOS_RbInitTree(&vmSpace->regionRbTree, OsRegionRbCmpKeyFn, OsRegionRbFreeFn, OsRegionRbGetKeyFn); + LOS_RbInitTree(&vmSpace->regionRbTree, OsRegionRbCmpKeyFn, OsRegionRbFreeFn, OsRegionRbGetKeyFn);//初始化虚拟存储空间-以红黑树组织方式 - status_t retval = LOS_MuxInit(&vmSpace->regionMux, NULL); + status_t retval = LOS_MuxInit(&vmSpace->regionMux, NULL);//初始化互斥量 if (retval != LOS_OK) { VM_ERR("Create mutex for vm space failed, status: %d", retval); return FALSE; } (VOID)LOS_MuxAcquire(&g_vmSpaceListMux); - LOS_ListAdd(&g_vmSpaceList, &vmSpace->node); + LOS_ListAdd(&g_vmSpaceList, &vmSpace->node);//将虚拟空间挂入全局虚拟空间双循环链表上 (VOID)LOS_MuxRelease(&g_vmSpaceListMux); - return OsArchMmuInit(&vmSpace->archMmu, virtTtb); + return OsArchMmuInit(&vmSpace->archMmu, virtTtb);//对mmu初始化 } - +///@note_thinking 这个函数名称和内容不太搭 VOID OsVmMapInit(VOID) { - status_t retval = LOS_MuxInit(&g_vmSpaceListMux, NULL); + status_t retval = LOS_MuxInit(&g_vmSpaceListMux, NULL);//初始化虚拟空间的互斥量 if (retval != LOS_OK) { VM_ERR("Create mutex for g_vmSpaceList failed, status: %d", retval); } } - -BOOL OsKernVmSpaceInit(LosVmSpace *vmSpace, VADDR_T *virtTtb) +///初始化内核虚拟空间 +BOOL OsKernVmSpaceInit(LosVmSpace *vmSpace, VADDR_T *virtTtb)//内核空间页表是编译时放在bbs段指定的,共用 L1表 { - vmSpace->base = KERNEL_ASPACE_BASE; - vmSpace->size = KERNEL_ASPACE_SIZE; - vmSpace->mapBase = KERNEL_VMM_BASE; - vmSpace->mapSize = KERNEL_VMM_SIZE; + vmSpace->base = KERNEL_ASPACE_BASE;//内核空间基地址, 线性区将分配在此范围 + vmSpace->size = KERNEL_ASPACE_SIZE;//内核空间大小 + vmSpace->mapBase = KERNEL_VMM_BASE;//内核空间映射区基地址 + vmSpace->mapSize = KERNEL_VMM_SIZE;//内核空间映射区大小 #ifdef LOSCFG_DRIVERS_TZDRIVER - vmSpace->codeStart = 0; - vmSpace->codeEnd = 0; + vmSpace->codeStart = 0; //代码区开始地址 + vmSpace->codeEnd = 0; //代码区结束地址 #endif - return OsVmSpaceInitCommon(vmSpace, virtTtb); + return OsVmSpaceInitCommon(vmSpace, virtTtb);//virtTtb 用于初始化 mmu } - -BOOL OsVMallocSpaceInit(LosVmSpace *vmSpace, VADDR_T *virtTtb) +///初始化内核堆空间 +BOOL OsVMallocSpaceInit(LosVmSpace *vmSpace, VADDR_T *virtTtb)//内核动态空间的页表是动态申请得来,共用 L1表 { - vmSpace->base = VMALLOC_START; - vmSpace->size = VMALLOC_SIZE; - vmSpace->mapBase = VMALLOC_START; - vmSpace->mapSize = VMALLOC_SIZE; + vmSpace->base = VMALLOC_START; //内核堆空间基地址 + vmSpace->size = VMALLOC_SIZE; //内核堆空间大小 + vmSpace->mapBase = VMALLOC_START; //内核堆空间映射基地址 + vmSpace->mapSize = VMALLOC_SIZE; //内核堆空间映射区大小 #ifdef LOSCFG_DRIVERS_TZDRIVER vmSpace->codeStart = 0; vmSpace->codeEnd = 0; #endif - return OsVmSpaceInitCommon(vmSpace, virtTtb); + return OsVmSpaceInitCommon(vmSpace, virtTtb);//创建MMU,为后续的虚实映射做好初始化的工作 } - +///内核虚拟空间初始化 VOID OsKSpaceInit(VOID) { - OsVmMapInit(); - OsKernVmSpaceInit(&g_kVmSpace, OsGFirstTableGet()); - OsVMallocSpaceInit(&g_vMallocSpace, OsGFirstTableGet()); + OsVmMapInit();//初始化后续操作 g_vmSpaceList 的互斥锁 + OsKernVmSpaceInit(&g_kVmSpace, OsGFirstTableGet()); //初始化内核进程虚拟空间 + OsVMallocSpaceInit(&g_vMallocSpace, OsGFirstTableGet());//初始化内核动态分配空间 } - +/*! + * @brief OsUserVmSpaceInit 用户空间的TTB表是动态申请得来,每个进程有属于自己的L1,L2表 + * 初始化用户进程虚拟空间,主要划分数据区,堆区,映射区和创建mmu + * @param virtTtb + * @param vmSpace + * @return + * + * @see + */ BOOL OsUserVmSpaceInit(LosVmSpace *vmSpace, VADDR_T *virtTtb) { - vmSpace->base = USER_ASPACE_BASE; - vmSpace->size = USER_ASPACE_SIZE; - vmSpace->mapBase = USER_MAP_BASE; - vmSpace->mapSize = USER_MAP_SIZE; - vmSpace->heapBase = USER_HEAP_BASE; - vmSpace->heapNow = USER_HEAP_BASE; - vmSpace->heap = NULL; + vmSpace->base = USER_ASPACE_BASE;//用户空间基地址 + vmSpace->size = USER_ASPACE_SIZE;//用户空间大小 + vmSpace->mapBase = USER_MAP_BASE;//用户空间映射基地址 + vmSpace->mapSize = USER_MAP_SIZE;//用户空间映射大小 + vmSpace->heapBase = USER_HEAP_BASE;//用户堆区开始地址,只有用户进程需要设置这里,动态内存的开始地址 + vmSpace->heapNow = USER_HEAP_BASE;//堆区最新指向地址,用户堆空间大小可通过系统调用 do_brk()扩展 + vmSpace->heap = NULL; //最近分配的一个堆线性区 #ifdef LOSCFG_DRIVERS_TZDRIVER vmSpace->codeStart = 0; vmSpace->codeEnd = 0; #endif - return OsVmSpaceInitCommon(vmSpace, virtTtb); + return OsVmSpaceInitCommon(vmSpace, virtTtb);//创建MMU,为后续的虚实映射做好初始化的工作 } - +/// 创建用户进程空间 LosVmSpace *OsCreateUserVmSpace(VOID) { BOOL retVal = FALSE; - LosVmSpace *space = LOS_MemAlloc(m_aucSysMem0, sizeof(LosVmSpace)); + LosVmSpace *space = LOS_MemAlloc(m_aucSysMem0, sizeof(LosVmSpace));//在内核空间申请用户进程空间 if (space == NULL) { return NULL; } - - VADDR_T *ttb = LOS_PhysPagesAllocContiguous(1); - if (ttb == NULL) { + //此处为何直接申请物理页帧存放用户进程的页表,大概是因为所有页表都被存放在内核空间(g_kVmSpace)而非内核分配空间(g_vMallocSpace) + VADDR_T *ttb = LOS_PhysPagesAllocContiguous(1);//分配一个物理页用于存放虚实映射关系表, 即:L1表 + if (ttb == NULL) {//若连页表都没有,剩下的也别玩了. (VOID)LOS_MemFree(m_aucSysMem0, space); return NULL; } - - (VOID)memset_s(ttb, PAGE_SIZE, 0, PAGE_SIZE); - retVal = OsUserVmSpaceInit(space, ttb); - LosVmPage *vmPage = OsVmVaddrToPage(ttb); + + (VOID)memset_s(ttb, PAGE_SIZE, 0, PAGE_SIZE);//4K空间置0 + retVal = OsUserVmSpaceInit(space, ttb);//初始化用户空间,mmu + LosVmPage *vmPage = OsVmVaddrToPage(ttb);//找到所在物理页框 if ((retVal == FALSE) || (vmPage == NULL)) { (VOID)LOS_MemFree(m_aucSysMem0, space); LOS_PhysPagesFreeContiguous(ttb, 1); return NULL; } - LOS_ListAdd(&space->archMmu.ptList, &(vmPage->node)); + LOS_ListAdd(&space->archMmu.ptList, &(vmPage->node));//页表链表,先挂上L1,后续还会挂上 N个L2表 return space; } -STATIC BOOL OsVmSpaceParamCheck(const LosVmSpace *vmSpace) +STATIC BOOL OsVmSpaceParamCheck(const LosVmSpace *vmSpace)//这么简单也要写个函数? { if (vmSpace == NULL) { return FALSE; @@ -241,6 +306,7 @@ STATIC BOOL OsVmSpaceParamCheck(const LosVmSpace *vmSpace) return TRUE; } +//虚拟内存空间克隆,被用于fork进程 STATUS_T LOS_VmSpaceClone(UINT32 cloneFlags, LosVmSpace *oldVmSpace, LosVmSpace *newVmSpace) { LosRbNode *pstRbNode = NULL; @@ -255,23 +321,23 @@ STATUS_T LOS_VmSpaceClone(UINT32 cloneFlags, LosVmSpace *oldVmSpace, LosVmSpace return LOS_ERRNO_VM_INVALID_ARGS; } - if ((OsIsVmRegionEmpty(oldVmSpace) == TRUE) || (oldVmSpace == &g_kVmSpace)) { + if ((OsIsVmRegionEmpty(oldVmSpace) == TRUE) || (oldVmSpace == &g_kVmSpace)) {//不允许clone内核空间,内核空间是独一无二的. return LOS_ERRNO_VM_INVALID_ARGS; } - + //空间克隆的主体实现是:线性区重新一个个分配物理内存,重新映射. /* search the region list */ - newVmSpace->mapBase = oldVmSpace->mapBase; - newVmSpace->heapBase = oldVmSpace->heapBase; - newVmSpace->heapNow = oldVmSpace->heapNow; + newVmSpace->mapBase = oldVmSpace->mapBase; //复制映射区基址 + newVmSpace->heapBase = oldVmSpace->heapBase; //复制堆区基址 + newVmSpace->heapNow = oldVmSpace->heapNow; //复制堆区当前使用到哪了 (VOID)LOS_MuxAcquire(&oldVmSpace->regionMux); - RB_SCAN_SAFE(&oldVmSpace->regionRbTree, pstRbNode, pstRbNodeNext) + RB_SCAN_SAFE(&oldVmSpace->regionRbTree, pstRbNode, pstRbNodeNext)//红黑树循环开始 LosVmMapRegion *oldRegion = (LosVmMapRegion *)pstRbNode; #if defined(LOSCFG_KERNEL_SHM) && defined(LOSCFG_IPC_CONTAINER) if ((oldRegion->regionFlags & VM_MAP_REGION_FLAG_SHM) && (cloneFlags & CLONE_NEWIPC)) { continue; } #endif - LosVmMapRegion *newRegion = OsVmRegionDup(newVmSpace, oldRegion, oldRegion->range.base, oldRegion->range.size); + LosVmMapRegion *newRegion = OsVmRegionDup(newVmSpace, oldRegion, oldRegion->range.base, oldRegion->range.size);//复制线性区 if (newRegion == NULL) { VM_ERR("dup new region failed"); ret = LOS_ERRNO_VM_NO_MEMORY; @@ -279,50 +345,50 @@ STATUS_T LOS_VmSpaceClone(UINT32 cloneFlags, LosVmSpace *oldVmSpace, LosVmSpace } #ifdef LOSCFG_KERNEL_SHM - if (oldRegion->regionFlags & VM_MAP_REGION_FLAG_SHM) { - OsShmFork(newVmSpace, oldRegion, newRegion); - continue; + if (oldRegion->regionFlags & VM_MAP_REGION_FLAG_SHM) {//如果老线性区是共享内存 + OsShmFork(newVmSpace, oldRegion, newRegion);//fork共享线性区,如此新虚拟空间也能用那个线性区 + continue;//不往下走了,因为共享内存不需要重新映射,下面无非就是需要MMU映射虚拟地址<-->物理地址 } #endif - if (oldRegion == oldVmSpace->heap) { - newVmSpace->heap = newRegion; + if (oldRegion == oldVmSpace->heap) {//如果这个线性区是堆区 + newVmSpace->heap = newRegion;//那么新的线性区也是新虚拟空间的堆区 } - numPages = newRegion->range.size >> PAGE_SHIFT; - for (i = 0; i < numPages; i++) { + numPages = newRegion->range.size >> PAGE_SHIFT;//计算线性区页数 + for (i = 0; i < numPages; i++) {//一页一页进行重新映射 vaddr = newRegion->range.base + (i << PAGE_SHIFT); - if (LOS_ArchMmuQuery(&oldVmSpace->archMmu, vaddr, &paddr, &flags) != LOS_OK) { + if (LOS_ArchMmuQuery(&oldVmSpace->archMmu, vaddr, &paddr, &flags) != LOS_OK) {//先查物理地址 continue; } - page = LOS_VmPageGet(paddr); + page = LOS_VmPageGet(paddr);//通过物理页获取物理内存的页框 if (page != NULL) { - LOS_AtomicInc(&page->refCounts); + LOS_AtomicInc(&page->refCounts);//refCounts 自增 } - if (flags & VM_MAP_REGION_FLAG_PERM_WRITE) { - LOS_ArchMmuUnmap(&oldVmSpace->archMmu, vaddr, 1); - LOS_ArchMmuMap(&oldVmSpace->archMmu, vaddr, paddr, 1, flags & ~VM_MAP_REGION_FLAG_PERM_WRITE); + if (flags & VM_MAP_REGION_FLAG_PERM_WRITE) {//可写入区标签 + LOS_ArchMmuUnmap(&oldVmSpace->archMmu, vaddr, 1);//先删除老空间映射 + LOS_ArchMmuMap(&oldVmSpace->archMmu, vaddr, paddr, 1, flags & ~VM_MAP_REGION_FLAG_PERM_WRITE);//老空间重新映射 } - LOS_ArchMmuMap(&newVmSpace->archMmu, vaddr, paddr, 1, flags & ~VM_MAP_REGION_FLAG_PERM_WRITE); + LOS_ArchMmuMap(&newVmSpace->archMmu, vaddr, paddr, 1, flags & ~VM_MAP_REGION_FLAG_PERM_WRITE);//映射新空间 -#ifdef LOSCFG_FS_VFS - if (LOS_IsRegionFileValid(oldRegion)) { +#ifdef LOSCFG_FS_VFS //文件系统开关 + if (LOS_IsRegionFileValid(oldRegion)) {//是都是一个文件映射线性区 LosFilePage *fpage = NULL; LOS_SpinLockSave(&oldRegion->unTypeData.rf.vnode->mapping.list_lock, &intSave); fpage = OsFindGetEntry(&oldRegion->unTypeData.rf.vnode->mapping, newRegion->pgOff + i); if ((fpage != NULL) && (fpage->vmPage == page)) { /* cow page no need map */ - OsAddMapInfo(fpage, &newVmSpace->archMmu, vaddr); + OsAddMapInfo(fpage, &newVmSpace->archMmu, vaddr);//添加文件页映射,记录页面被进程映射过 } LOS_SpinUnlockRestore(&oldRegion->unTypeData.rf.vnode->mapping.list_lock, intSave); } #endif } - RB_SCAN_SAFE_END(&oldVmSpace->regionRbTree, pstRbNode, pstRbNodeNext) + RB_SCAN_SAFE_END(&oldVmSpace->regionRbTree, pstRbNode, pstRbNodeNext)//红黑树循环结束 (VOID)LOS_MuxRelease(&oldVmSpace->regionMux); return ret; } - +///通过虚拟(线性)地址查找所属线性区,红黑树 LosVmMapRegion *OsFindRegion(LosRbTree *regionRbTree, VADDR_T vaddr, size_t len) { LosVmMapRegion *regionRst = NULL; @@ -336,18 +402,18 @@ LosVmMapRegion *OsFindRegion(LosRbTree *regionRbTree, VADDR_T vaddr, size_t len) } return regionRst; } - +/// 查找线性区 根据起始地址在进程空间内查找是否存在 LosVmMapRegion *LOS_RegionFind(LosVmSpace *vmSpace, VADDR_T addr) { LosVmMapRegion *region = NULL; - (VOID)LOS_MuxAcquire(&vmSpace->regionMux); + (VOID)LOS_MuxAcquire(&vmSpace->regionMux);//因进程空间是隔离的,所以此处只会涉及到任务(线程)之间的竞争,故使用互斥锁,而自旋锁则用于CPU核间的竞争 region = OsFindRegion(&vmSpace->regionRbTree, addr, 1); (VOID)LOS_MuxRelease(&vmSpace->regionMux); return region; } - +/// 查找线性区 根据地址区间在进程空间内查找是否存在 LosVmMapRegion *LOS_RegionRangeFind(LosVmSpace *vmSpace, VADDR_T addr, size_t len) { LosVmMapRegion *region = NULL; @@ -358,14 +424,14 @@ LosVmMapRegion *LOS_RegionRangeFind(LosVmSpace *vmSpace, VADDR_T addr, size_t le return region; } - +/// 分配指定长度的线性区 VADDR_T OsAllocRange(LosVmSpace *vmSpace, size_t len) { LosVmMapRegion *curRegion = NULL; LosRbNode *pstRbNode = NULL; LosRbNode *pstRbNodeTmp = NULL; LosRbTree *regionRbTree = &vmSpace->regionRbTree; - VADDR_T curEnd = vmSpace->mapBase; + VADDR_T curEnd = vmSpace->mapBase;//获取映射区基地址 VADDR_T nextStart; curRegion = LOS_RegionFind(vmSpace, vmSpace->mapBase); @@ -384,7 +450,7 @@ VADDR_T OsAllocRange(LosVmSpace *vmSpace, size_t len) curEnd = curRegion->range.base + curRegion->range.size; } RB_MID_SCAN_END(regionRbTree, pstRbNode) - } else { + } else {//红黑树扫描排序,从小到大 /* rbtree scan is sorted, from small to big */ RB_SCAN_SAFE(regionRbTree, pstRbNode, pstRbNodeTmp) curRegion = (LosVmMapRegion *)pstRbNode; @@ -407,34 +473,34 @@ VADDR_T OsAllocRange(LosVmSpace *vmSpace, size_t len) return 0; } - +/// 分配指定开始地址和长度的线性区 VADDR_T OsAllocSpecificRange(LosVmSpace *vmSpace, VADDR_T vaddr, size_t len, UINT32 regionFlags) { STATUS_T status; - if (LOS_IsRangeInSpace(vmSpace, vaddr, len) == FALSE) { + if (LOS_IsRangeInSpace(vmSpace, vaddr, len) == FALSE) {//虚拟地址是否在进程空间范围内 return 0; } if ((LOS_RegionFind(vmSpace, vaddr) != NULL) || (LOS_RegionFind(vmSpace, vaddr + len - 1) != NULL) || - (LOS_RegionRangeFind(vmSpace, vaddr, len - 1) != NULL)) { + (LOS_RegionRangeFind(vmSpace, vaddr, len - 1) != NULL)) {//没找到的情况 if ((regionFlags & VM_MAP_REGION_FLAG_FIXED_NOREPLACE) != 0) { return 0; - } else if ((regionFlags & VM_MAP_REGION_FLAG_FIXED) != 0) { - status = LOS_UnMMap(vaddr, len); + } else if ((regionFlags & VM_MAP_REGION_FLAG_FIXED) != 0) {//线性区未填满,则解除这部分空间的映射 + status = LOS_UnMMap(vaddr, len);//解除映射 if (status != LOS_OK) { VM_ERR("unmap specific range va: %#x, len: %#x failed, status: %d", vaddr, len, status); return 0; } } else { - return OsAllocRange(vmSpace, len); + return OsAllocRange(vmSpace, len);//默认分配一个 } } return vaddr; } - +///映射类型为文件的线性区是否有效 BOOL LOS_IsRegionFileValid(LosVmMapRegion *region) { if ((region != NULL) && (LOS_IsRegionTypeFile(region)) && @@ -443,7 +509,7 @@ BOOL LOS_IsRegionFileValid(LosVmMapRegion *region) } return FALSE; } - +///向红黑树中插入线性区 BOOL OsInsertRegion(LosRbTree *regionRbTree, LosVmMapRegion *region) { if (LOS_RbAddNode(regionRbTree, (LosRbNode *)region) == FALSE) { @@ -453,46 +519,46 @@ BOOL OsInsertRegion(LosRbTree *regionRbTree, LosVmMapRegion *region) } return TRUE; } - +///创建一个线性区 LosVmMapRegion *OsCreateRegion(VADDR_T vaddr, size_t len, UINT32 regionFlags, unsigned long offset) { - LosVmMapRegion *region = LOS_MemAlloc(m_aucSysMem0, sizeof(LosVmMapRegion)); + LosVmMapRegion *region = LOS_MemAlloc(m_aucSysMem0, sizeof(LosVmMapRegion));//只是分配一个线性区结构体 if (region == NULL) { VM_ERR("memory allocate for LosVmMapRegion failed"); return region; } - + //创建线性区的本质就是在画饼,见如下操作: (void)memset_s(region, sizeof(LosVmMapRegion), 0, sizeof(LosVmMapRegion)); - region->range.base = vaddr; - region->range.size = len; - region->pgOff = offset; - region->regionFlags = regionFlags; - region->regionType = VM_MAP_REGION_TYPE_NONE; - region->forkFlags = 0; - region->shmid = -1; + region->range.base = vaddr; //虚拟地址作为线性区的基地址 + region->range.size = len; //线性区大小,这是线性区构思最巧妙的地方,只要不过分,蓝图随便画。 + region->pgOff = offset; //页标 + region->regionFlags = regionFlags;//标识,可读/可写/可执行 + region->regionType = VM_MAP_REGION_TYPE_NONE;//未映射 + region->forkFlags = 0; // + region->shmid = -1; //默认线性区为不共享,无共享资源ID return region; } - +///通过虚拟地址查询映射的物理地址 PADDR_T LOS_PaddrQuery(VOID *vaddr) { PADDR_T paddr = 0; STATUS_T status; LosVmSpace *space = NULL; LosArchMmu *archMmu = NULL; - - if (LOS_IsKernelAddress((VADDR_T)(UINTPTR)vaddr)) { + //先取出对应空间的mmu + if (LOS_IsKernelAddress((VADDR_T)(UINTPTR)vaddr)) {//是否内核空间地址 archMmu = &g_kVmSpace.archMmu; - } else if (LOS_IsUserAddress((VADDR_T)(UINTPTR)vaddr)) { + } else if (LOS_IsUserAddress((VADDR_T)(UINTPTR)vaddr)) {//是否为用户空间地址 space = OsCurrProcessGet()->vmSpace; archMmu = &space->archMmu; - } else if (LOS_IsVmallocAddress((VADDR_T)(UINTPTR)vaddr)) { + } else if (LOS_IsVmallocAddress((VADDR_T)(UINTPTR)vaddr)) {//是否为分配空间地址,堆区地址 archMmu = &g_vMallocSpace.archMmu; } else { VM_ERR("vaddr is beyond range"); return 0; } - status = LOS_ArchMmuQuery(archMmu, (VADDR_T)(UINTPTR)vaddr, &paddr, 0); + status = LOS_ArchMmuQuery(archMmu, (VADDR_T)(UINTPTR)vaddr, &paddr, 0);//查询物理地址 if (status == LOS_OK) { return paddr; } else { @@ -500,6 +566,10 @@ PADDR_T LOS_PaddrQuery(VOID *vaddr) } } +/*! + * 这里不是真的分配物理内存,而是逻辑上画一个连续的区域,标记这个区域可以拿用,表示内存已经归你了。 + 但真正的物理内存的占用会延迟到使用的时候才由缺页中断调入内存 +*/ LosVmMapRegion *LOS_RegionAlloc(LosVmSpace *vmSpace, VADDR_T vaddr, size_t len, UINT32 regionFlags, VM_OFFSET_T pgoff) { VADDR_T rstVaddr; @@ -510,37 +580,40 @@ LosVmMapRegion *LOS_RegionAlloc(LosVmSpace *vmSpace, VADDR_T vaddr, size_t len, * this is the most portable method of creating a new mapping. If addr is not NULL, * then the kernel takes it as where to place the mapping; */ - (VOID)LOS_MuxAcquire(&vmSpace->regionMux); - if (vaddr == 0) { + (VOID)LOS_MuxAcquire(&vmSpace->regionMux);//获得互斥锁 + if (vaddr == 0) {//如果地址是0,根据线性区管理的实际情况,自动创建虚拟地址, 这是创建新映射的最便捷的方法。 rstVaddr = OsAllocRange(vmSpace, len); } else { - /* if it is already mmapped here, we unmmap it */ - rstVaddr = OsAllocSpecificRange(vmSpace, vaddr, len, regionFlags); + /* if it is already mmapped here, we unmmap it | 如果已经被映射了, 则解除映射关系*/ + rstVaddr = OsAllocSpecificRange(vmSpace, vaddr, len, regionFlags);//创建包含指定虚拟地址的线性区, rstVaddr != vaddr || rstVaddr == vaddr if (rstVaddr == 0) { VM_ERR("alloc specific range va: %#x, len: %#x failed", vaddr, len); goto OUT; } } - if (rstVaddr == 0) { + if (rstVaddr == 0) {//没有可供映射的虚拟地址 goto OUT; } - newRegion = OsCreateRegion(rstVaddr, len, regionFlags, pgoff); + newRegion = OsCreateRegion(rstVaddr, len, regionFlags, pgoff);//创建一个线性区,指定线性区的开始地址rstVaddr ... if (newRegion == NULL) { goto OUT; } newRegion->space = vmSpace; - isInsertSucceed = OsInsertRegion(&vmSpace->regionRbTree, newRegion); - if (isInsertSucceed == FALSE) { - (VOID)LOS_MemFree(m_aucSysMem0, newRegion); + isInsertSucceed = OsInsertRegion(&vmSpace->regionRbTree, newRegion);//插入红黑树和双循环链表中管理 + if (isInsertSucceed == FALSE) {//插入失败 + (VOID)LOS_MemFree(m_aucSysMem0, newRegion);//从内存池中释放 newRegion = NULL; } OUT: - (VOID)LOS_MuxRelease(&vmSpace->regionMux); + (VOID)LOS_MuxRelease(&vmSpace->regionMux);//释放互斥锁 return newRegion; } - +/*! + * 删除匿名页,匿名页就是内存映射页 + * 1.解除映射关系 2.释放物理内存 +*/ STATIC VOID OsAnonPagesRemove(LosArchMmu *archMmu, VADDR_T vaddr, UINT32 count) { status_t status; @@ -552,20 +625,20 @@ STATIC VOID OsAnonPagesRemove(LosArchMmu *archMmu, VADDR_T vaddr, UINT32 count) return; } - while (count > 0) { + while (count > 0) {//一页页操作 count--; - status = LOS_ArchMmuQuery(archMmu, vaddr, &paddr, NULL); - if (status != LOS_OK) { + status = LOS_ArchMmuQuery(archMmu, vaddr, &paddr, NULL);//通过虚拟地址拿到物理地址 + if (status != LOS_OK) {//失败,拿下一页的物理地址 vaddr += PAGE_SIZE; continue; } - LOS_ArchMmuUnmap(archMmu, vaddr, 1); + LOS_ArchMmuUnmap(archMmu, vaddr, 1);//解除一页的映射 - page = LOS_VmPageGet(paddr); - if (page != NULL) { - if (!OsIsPageShared(page)) { - LOS_PhysPageFree(page); + page = LOS_VmPageGet(paddr);//通过物理地址获取所在物理页框的起始地址 + if (page != NULL) {//获取成功 + if (!OsIsPageShared(page)) {//不是共享页,共享页会有专门的共享标签,共享本质是有无多个进程对该页的引用 + LOS_PhysPageFree(page);//释放物理页框 } } vaddr += PAGE_SIZE; @@ -609,7 +682,7 @@ STATIC VOID OsFilePagesRemove(LosVmSpace *space, LosVmMapRegion *region) } } #endif - +/// 释放进程空间指定线性区 STATUS_T LOS_RegionFree(LosVmSpace *space, LosVmMapRegion *region) { if ((space == NULL) || (region == NULL)) { @@ -619,35 +692,34 @@ STATUS_T LOS_RegionFree(LosVmSpace *space, LosVmMapRegion *region) (VOID)LOS_MuxAcquire(&space->regionMux); -#ifdef LOSCFG_FS_VFS - if (LOS_IsRegionFileValid(region)) { - OsFilePagesRemove(space, region); +#ifdef LOSCFG_FS_VFS //文件开关 + if (LOS_IsRegionFileValid(region)) {//是否为文件线性区 + OsFilePagesRemove(space, region);//删除文件页 VnodeHold(); region->unTypeData.rf.vnode->useCount--; VnodeDrop(); } else #endif - -#ifdef LOSCFG_KERNEL_SHM - if (OsIsShmRegion(region)) { - OsShmRegionFree(space, region); +#ifdef LOSCFG_KERNEL_SHM //共享内存开关 + if (OsIsShmRegion(region)) { //是否为共享内存线性区 + OsShmRegionFree(space, region);//释放共享线性区 } else if (LOS_IsRegionTypeDev(region)) { #else - if (LOS_IsRegionTypeDev(region)) { + if (LOS_IsRegionTypeDev(region)) {//如果是设备线性区 #endif - OsDevPagesRemove(&space->archMmu, region->range.base, region->range.size >> PAGE_SHIFT); + OsDevPagesRemove(&space->archMmu, region->range.base, region->range.size >> PAGE_SHIFT);//删除映射设备 } else { - OsAnonPagesRemove(&space->archMmu, region->range.base, region->range.size >> PAGE_SHIFT); + OsAnonPagesRemove(&space->archMmu, region->range.base, region->range.size >> PAGE_SHIFT);//删除匿名映射 } /* remove it from space */ - LOS_RbDelNode(&space->regionRbTree, ®ion->rbNode); + LOS_RbDelNode(&space->regionRbTree, ®ion->rbNode);//从红黑树中删除线性区 /* free it */ - LOS_MemFree(m_aucSysMem0, region); + LOS_MemFree(m_aucSysMem0, region);//释放线性区结构体占用的内存 (VOID)LOS_MuxRelease(&space->regionMux); return LOS_OK; } - +/// 复制线性区 LosVmMapRegion *OsVmRegionDup(LosVmSpace *space, LosVmMapRegion *oldRegion, VADDR_T vaddr, size_t size) { LosVmMapRegion *newRegion = NULL; @@ -655,31 +727,31 @@ LosVmMapRegion *OsVmRegionDup(LosVmSpace *space, LosVmMapRegion *oldRegion, VADD (VOID)LOS_MuxAcquire(&space->regionMux); regionFlags = oldRegion->regionFlags; - if (vaddr == 0) { - regionFlags &= ~(VM_MAP_REGION_FLAG_FIXED | VM_MAP_REGION_FLAG_FIXED_NOREPLACE); + if (vaddr == 0) {//不指定地址 + regionFlags &= ~(VM_MAP_REGION_FLAG_FIXED | VM_MAP_REGION_FLAG_FIXED_NOREPLACE); //撕掉两个标签 } else { - regionFlags |= VM_MAP_REGION_FLAG_FIXED; + regionFlags |= VM_MAP_REGION_FLAG_FIXED; //贴上填满线性区标签 } - newRegion = LOS_RegionAlloc(space, vaddr, size, regionFlags, oldRegion->pgOff); + newRegion = LOS_RegionAlloc(space, vaddr, size, regionFlags, oldRegion->pgOff); //分配一个线性区 if (newRegion == NULL) { VM_ERR("LOS_RegionAlloc failed"); goto REGIONDUPOUT; } - newRegion->regionType = oldRegion->regionType; + newRegion->regionType = oldRegion->regionType;//复制线性区类型(文件,设备,匿名) #ifdef LOSCFG_KERNEL_SHM - if (OsIsShmRegion(oldRegion)) { - newRegion->shmid = oldRegion->shmid; + if (OsIsShmRegion(oldRegion)) {//如果是共享内存 + newRegion->shmid = oldRegion->shmid;//复制共享ID } #endif -#ifdef LOSCFG_FS_VFS - if (LOS_IsRegionTypeFile(oldRegion)) { - newRegion->unTypeData.rf.vmFOps = oldRegion->unTypeData.rf.vmFOps; - newRegion->unTypeData.rf.vnode = oldRegion->unTypeData.rf.vnode; - newRegion->unTypeData.rf.f_oflags = oldRegion->unTypeData.rf.f_oflags; +#ifdef LOSCFG_FS_VFS //文件开关 + if (LOS_IsRegionTypeFile(oldRegion)) {//如果是文件线性区 + newRegion->unTypeData.rf.vmFOps = oldRegion->unTypeData.rf.vmFOps; //文件操作接口 + newRegion->unTypeData.rf.vnode = oldRegion->unTypeData.rf.vnode; //文件索引节点 + newRegion->unTypeData.rf.f_oflags = oldRegion->unTypeData.rf.f_oflags;//读写标签 VnodeHold(); - newRegion->unTypeData.rf.vnode->useCount++; + newRegion->unTypeData.rf.vnode->useCount++;//索引节点使用数增加 VnodeDrop(); } #endif @@ -688,14 +760,14 @@ REGIONDUPOUT: (VOID)LOS_MuxRelease(&space->regionMux); return newRegion; } - +/// 劈开线性区 STATIC LosVmMapRegion *OsVmRegionSplit(LosVmMapRegion *oldRegion, VADDR_T newRegionStart) { LosVmMapRegion *newRegion = NULL; LosVmSpace *space = oldRegion->space; - size_t size = LOS_RegionSize(newRegionStart, LOS_RegionEndAddr(oldRegion)); + size_t size = LOS_RegionSize(newRegionStart, LOS_RegionEndAddr(oldRegion));//获取线性区大小 - oldRegion->range.size = LOS_RegionSize(oldRegion->range.base, newRegionStart - 1); + oldRegion->range.size = LOS_RegionSize(oldRegion->range.base, newRegionStart - 1);//获取旧线性区大小 if (oldRegion->range.size == 0) { LOS_RbDelNode(&space->regionRbTree, &oldRegion->rbNode); } @@ -710,14 +782,14 @@ STATIC LosVmMapRegion *OsVmRegionSplit(LosVmMapRegion *oldRegion, VADDR_T newReg #endif return newRegion; } - +///对线性区进行调整 STATUS_T OsVmRegionAdjust(LosVmSpace *space, VADDR_T newRegionStart, size_t size) { LosVmMapRegion *region = NULL; VADDR_T nextRegionBase = newRegionStart + size; LosVmMapRegion *newRegion = NULL; - region = LOS_RegionFind(space, newRegionStart); + region = LOS_RegionFind(space, newRegionStart);//先找到线性区 if ((region != NULL) && (newRegionStart > region->range.base)) { newRegion = OsVmRegionSplit(region, newRegionStart); if (newRegion == NULL) { @@ -737,7 +809,7 @@ STATUS_T OsVmRegionAdjust(LosVmSpace *space, VADDR_T newRegionStart, size_t size return LOS_OK; } - +///删除线性区 STATUS_T OsRegionsRemove(LosVmSpace *space, VADDR_T regionBase, size_t size) { STATUS_T status; @@ -748,12 +820,12 @@ STATUS_T OsRegionsRemove(LosVmSpace *space, VADDR_T regionBase, size_t size) (VOID)LOS_MuxAcquire(&space->regionMux); - status = OsVmRegionAdjust(space, regionBase, size); + status = OsVmRegionAdjust(space, regionBase, size);//线性区调整 if (status != LOS_OK) { goto ERR_REGION_SPLIT; } - RB_SCAN_SAFE(&space->regionRbTree, pstRbNodeTemp, pstRbNodeNext) + RB_SCAN_SAFE(&space->regionRbTree, pstRbNodeTemp, pstRbNodeNext)//扫描虚拟空间内的线性区 regionTemp = (LosVmMapRegion *)pstRbNodeTemp; if (regionTemp->range.base > regionEnd) { break; @@ -772,7 +844,7 @@ ERR_REGION_SPLIT: (VOID)LOS_MuxRelease(&space->regionMux); return status; } - +///根据指定参数范围[addr,addr+len] 释放用户空间中堆区所占用的物理内存 INT32 OsUserHeapFree(LosVmSpace *vmSpace, VADDR_T addr, size_t len) { LosVmMapRegion *vmRegion = NULL; @@ -781,25 +853,25 @@ INT32 OsUserHeapFree(LosVmSpace *vmSpace, VADDR_T addr, size_t len) VADDR_T vaddr; STATUS_T ret; - if (vmSpace == LOS_GetKVmSpace() || vmSpace->heap == NULL) { + if (vmSpace == LOS_GetKVmSpace() || vmSpace->heap == NULL) {//虚拟空间堆区必须在非内核空间 return -1; } - vmRegion = LOS_RegionFind(vmSpace, addr); + vmRegion = LOS_RegionFind(vmSpace, addr);//通过参数虚拟地址红黑树找到线性区,线性区范围内包含了参数虚拟地址 if (vmRegion == NULL) { return -1; } - if (vmRegion == vmSpace->heap) { + if (vmRegion == vmSpace->heap) {//地址所在的线性区为堆区 vaddr = addr; - while (len > 0) { - if (LOS_ArchMmuQuery(&vmSpace->archMmu, vaddr, &paddr, 0) == LOS_OK) { - ret = LOS_ArchMmuUnmap(&vmSpace->archMmu, vaddr, 1); + while (len > 0) {//参数0 代表不获取 flags 信息 + if (LOS_ArchMmuQuery(&vmSpace->archMmu, vaddr, &paddr, 0) == LOS_OK) {//通过虚拟地址查到物理地址 + ret = LOS_ArchMmuUnmap(&vmSpace->archMmu, vaddr, 1);//解除映射关系以页为单位,这里解除1页 if (ret <= 0) { VM_ERR("unmap failed, ret = %d", ret); } - vmPage = LOS_VmPageGet(paddr); - LOS_PhysPageFree(vmPage); + vmPage = LOS_VmPageGet(paddr);//获取物理页面信息 + LOS_PhysPageFree(vmPage);//释放页 } vaddr += PAGE_SIZE; len -= PAGE_SIZE; @@ -809,7 +881,7 @@ INT32 OsUserHeapFree(LosVmSpace *vmSpace, VADDR_T addr, size_t len) return -1; } - +///线性区是否支持扩展 STATUS_T OsIsRegionCanExpand(LosVmSpace *space, LosVmMapRegion *region, size_t size) { LosVmMapRegion *nextRegion = NULL; @@ -826,13 +898,13 @@ STATUS_T OsIsRegionCanExpand(LosVmSpace *space, LosVmMapRegion *region, size_t s return LOS_NOK; } - +///解除一定范围的虚拟地址的映射关系 STATUS_T OsUnMMap(LosVmSpace *space, VADDR_T addr, size_t size) { size = LOS_Align(size, PAGE_SIZE); addr = LOS_Align(addr, PAGE_SIZE); (VOID)LOS_MuxAcquire(&space->regionMux); - STATUS_T status = OsRegionsRemove(space, addr, size); + STATUS_T status = OsRegionsRemove(space, addr, size);//删除线性区 if (status != LOS_OK) { status = -EINVAL; VM_ERR("region_split failed"); @@ -843,28 +915,28 @@ ERR_REGION_SPLIT: (VOID)LOS_MuxRelease(&space->regionMux); return status; } - +/// 释放所有线性区 STATIC VOID OsVmSpaceAllRegionFree(LosVmSpace *space) { LosRbNode *pstRbNode = NULL; LosRbNode *pstRbNodeNext = NULL; /* free all of the regions */ - RB_SCAN_SAFE(&space->regionRbTree, pstRbNode, pstRbNodeNext) - LosVmMapRegion *region = (LosVmMapRegion *)pstRbNode; + RB_SCAN_SAFE(&space->regionRbTree, pstRbNode, pstRbNodeNext) //遍历红黑树 + LosVmMapRegion *region = (LosVmMapRegion *)pstRbNode;//拿到线性区 if (region->range.size == 0) { VM_ERR("space free, region: %#x flags: %#x, base:%#x, size: %#x", region, region->regionFlags, region->range.base, region->range.size); } - STATUS_T ret = LOS_RegionFree(space, region); + STATUS_T ret = LOS_RegionFree(space, region);//释放线性区 if (ret != LOS_OK) { VM_ERR("free region error, space %p, region %p", space, region); } - RB_SCAN_SAFE_END(&space->regionRbTree, pstRbNode, pstRbNodeNext) + RB_SCAN_SAFE_END(&space->regionRbTree, pstRbNode, pstRbNodeNext)//要好好研究下这几个宏,有点意思 return; } - +/// 释放虚拟空间 STATUS_T OsVmSpaceRegionFree(LosVmSpace *space) { if (space == NULL) { @@ -882,22 +954,21 @@ STATUS_T OsVmSpaceRegionFree(LosVmSpace *space) return LOS_OK; } - +///释放虚拟空间,注意内核空间不能被释放掉,永驻内存 STATUS_T LOS_VmSpaceFree(LosVmSpace *space) { if (space == NULL) { return LOS_ERRNO_VM_INVALID_ARGS; } - if (space == &g_kVmSpace) { + if (space == &g_kVmSpace) {//不能释放内核虚拟空间,内核空间常驻内存 VM_ERR("try to free kernel aspace, not allowed"); return LOS_OK; } /* pop it out of the global aspace list */ (VOID)LOS_MuxAcquire(&space->regionMux); - - LOS_ListDelete(&space->node); + LOS_ListDelete(&space->node);//从g_vmSpaceList链表里删除,g_vmSpaceList记录了所有空间节点。 OsVmSpaceAllRegionFree(space); @@ -920,7 +991,7 @@ STATUS_T LOS_VmSpaceFree(LosVmSpace *space) LOS_MemFree(m_aucSysMem0, space); return LOS_OK; } - +///虚拟地址和size是否在空间 BOOL LOS_IsRangeInSpace(const LosVmSpace *space, VADDR_T vaddr, size_t size) { /* is the starting address within the address space */ @@ -940,7 +1011,7 @@ BOOL LOS_IsRangeInSpace(const LosVmSpace *space, VADDR_T vaddr, size_t size) } return TRUE; } - +/// 在进程空间中预留一块内存空间 STATUS_T LOS_VmSpaceReserve(LosVmSpace *space, size_t size, VADDR_T vaddr) { UINT32 regionFlags = 0; @@ -961,7 +1032,7 @@ STATUS_T LOS_VmSpaceReserve(LosVmSpace *space, size_t size, VADDR_T vaddr) return region ? LOS_OK : LOS_ERRNO_VM_NO_MEMORY; } - +///实现从虚拟地址到物理地址的映射,将指定长度的物理地址区间与虚拟地址区间做映射,需提前申请物理地址区间 STATUS_T LOS_VaddrToPaddrMmap(LosVmSpace *space, VADDR_T vaddr, PADDR_T paddr, size_t len, UINT32 flags) { STATUS_T ret; @@ -976,19 +1047,19 @@ STATUS_T LOS_VaddrToPaddrMmap(LosVmSpace *space, VADDR_T vaddr, PADDR_T paddr, s } if (space == NULL) { - space = OsCurrProcessGet()->vmSpace; + space = OsCurrProcessGet()->vmSpace;//获取当前进程的空间 } - region = LOS_RegionFind(space, vaddr); - if (region != NULL) { + region = LOS_RegionFind(space, vaddr);//通过虚拟地址查找线性区 + if (region != NULL) {//已经被映射过了,失败返回 VM_ERR("vaddr : 0x%x already used!", vaddr); return LOS_ERRNO_VM_BUSY; } - region = LOS_RegionAlloc(space, vaddr, len, flags, 0); + region = LOS_RegionAlloc(space, vaddr, len, flags, 0);//通过虚拟地址 创建一个region if (region == NULL) { VM_ERR("failed"); - return LOS_ERRNO_VM_NO_MEMORY; + return LOS_ERRNO_VM_NO_MEMORY;//内存不够 } while (len > 0) { @@ -998,9 +1069,9 @@ STATUS_T LOS_VaddrToPaddrMmap(LosVmSpace *space, VADDR_T vaddr, PADDR_T paddr, s VM_ERR("Page is NULL"); return LOS_ERRNO_VM_NOT_VALID; } - LOS_AtomicInc(&vmPage->refCounts); + LOS_AtomicInc(&vmPage->refCounts);//ref自增 - ret = LOS_ArchMmuMap(&space->archMmu, vaddr, paddr, 1, region->regionFlags); + ret = LOS_ArchMmuMap(&space->archMmu, vaddr, paddr, 1, region->regionFlags);//mmu map if (ret <= 0) { VM_ERR("LOS_ArchMmuMap failed: %d", ret); LOS_RegionFree(space, region); @@ -1014,9 +1085,10 @@ STATUS_T LOS_VaddrToPaddrMmap(LosVmSpace *space, VADDR_T vaddr, PADDR_T paddr, s return LOS_OK; } +//对外接口|申请内核堆空间内存 VOID *LOS_VMalloc(size_t size) { - LosVmSpace *space = &g_vMallocSpace; + LosVmSpace *space = &g_vMallocSpace;//从内核动态空间申请 LosVmMapRegion *region = NULL; size_t sizeCount; size_t count; @@ -1025,48 +1097,48 @@ VOID *LOS_VMalloc(size_t size) PADDR_T pa; STATUS_T ret; - size = LOS_Align(size, PAGE_SIZE); + size = LOS_Align(size, PAGE_SIZE);// if ((size == 0) || (size > space->size)) { return NULL; } - sizeCount = size >> PAGE_SHIFT; + sizeCount = size >> PAGE_SHIFT;//按页申请所以需右移12位 LOS_DL_LIST_HEAD(pageList); - (VOID)LOS_MuxAcquire(&space->regionMux); + (VOID)LOS_MuxAcquire(&space->regionMux);//获得互斥锁 - count = LOS_PhysPagesAlloc(sizeCount, &pageList); + count = LOS_PhysPagesAlloc(sizeCount, &pageList);//一页一页申请,并从pageList尾部插入 if (count < sizeCount) { VM_ERR("failed to allocate enough pages (ask %zu, got %zu)", sizeCount, count); goto ERROR; } - /* allocate a region and put it in the aspace list */ - region = LOS_RegionAlloc(space, 0, size, VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE, 0); + /* allocate a region and put it in the aspace list *///分配一个可读写的线性区,并挂在space + region = LOS_RegionAlloc(space, 0, size, VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE, 0);//注意第二个参数是 vaddr = 0 !!! if (region == NULL) { VM_ERR("alloc region failed, size = %x", size); goto ERROR; } - va = region->range.base; - while ((vmPage = LOS_ListRemoveHeadType(&pageList, LosVmPage, node))) { - pa = vmPage->physAddr; - LOS_AtomicInc(&vmPage->refCounts); - ret = LOS_ArchMmuMap(&space->archMmu, va, pa, 1, region->regionFlags); + va = region->range.base;//va 该区范围基地址为虚拟地址的开始位置,理解va怎么来的是理解线性地址的关键! + while ((vmPage = LOS_ListRemoveHeadType(&pageList, LosVmPage, node))) {//从pageList循环拿page + pa = vmPage->physAddr;//获取page物理地址,因上面是通过LOS_PhysPagesAlloc分配 + LOS_AtomicInc(&vmPage->refCounts);//refCounts 自增 + ret = LOS_ArchMmuMap(&space->archMmu, va, pa, 1, region->regionFlags);//一页一页的map if (ret != 1) { VM_ERR("LOS_ArchMmuMap failed!, err;%d", ret); } - va += PAGE_SIZE; - } + va += PAGE_SIZE;//一页映射完成,进入下一页 + }//va 注意 region的虚拟地址页是连续的,但物理页可以不连续! 很重要!!! - (VOID)LOS_MuxRelease(&space->regionMux); - return (VOID *)(UINTPTR)region->range.base; + (VOID)LOS_MuxRelease(&space->regionMux);//释放互斥锁 + return (VOID *)(UINTPTR)region->range.base;//返回虚拟基地址供应用使用 ERROR: - (VOID)LOS_PhysPagesFree(&pageList); - (VOID)LOS_MuxRelease(&space->regionMux); + (VOID)LOS_PhysPagesFree(&pageList);//释放物理内存页 + (VOID)LOS_MuxRelease(&space->regionMux);//释放互斥锁 return NULL; } - +///对外接口|释放内核堆空间内存 VOID LOS_VFree(const VOID *addr) { LosVmSpace *space = &g_vMallocSpace; @@ -1080,13 +1152,13 @@ VOID LOS_VFree(const VOID *addr) (VOID)LOS_MuxAcquire(&space->regionMux); - region = LOS_RegionFind(space, (VADDR_T)(UINTPTR)addr); + region = LOS_RegionFind(space, (VADDR_T)(UINTPTR)addr);//先找到线性区 if (region == NULL) { VM_ERR("find region failed"); goto DONE; } - ret = LOS_RegionFree(space, region); + ret = LOS_RegionFree(space, region);//释放线性区 if (ret) { VM_ERR("free region failed, ret = %d", ret); } @@ -1097,10 +1169,9 @@ DONE: LosMux *OsGVmSpaceMuxGet(VOID) { - return &g_vmSpaceListMux; + return &g_vmSpaceListMux; } - -STATIC INLINE BOOL OsMemLargeAlloc(UINT32 size) +STATIC INLINE BOOL OsMemLargeAlloc(UINT32 size)//是不是分配浪费大于1K的内存 { if (g_kHeapInited == FALSE) { return FALSE; @@ -1122,28 +1193,28 @@ PADDR_T LOS_PaddrQuery(VOID *vaddr) return (PADDR_T)VMM_TO_DMA_ADDR((VADDR_T)vaddr); } #endif - +///内核空间内存分配,申请小于16KiB的内存则通过堆内存池获取,否则申请多个连续物理页 VOID *LOS_KernelMalloc(UINT32 size) { VOID *ptr = NULL; - + //从本函数可知,内核空间的分配有两种方式 #ifdef LOSCFG_KERNEL_VM - if (OsMemLargeAlloc(size)) { - ptr = LOS_PhysPagesAllocContiguous(ROUNDUP(size, PAGE_SIZE) >> PAGE_SHIFT); + if (OsMemLargeAlloc(size)) {//是不是分配浪费小于1K的内存 + ptr = LOS_PhysPagesAllocContiguous(ROUNDUP(size, PAGE_SIZE) >> PAGE_SHIFT);//分配连续的物理内存页 } else #endif { - ptr = LOS_MemAlloc(OS_SYS_MEM_ADDR, size); + ptr = LOS_MemAlloc(OS_SYS_MEM_ADDR, size);//从内存池分配 } return ptr; } - +/// 申请具有对齐属性的内存,申请规则:申请小于16KiB的内存则通过堆内存池获取,否则申请多个连续物理页 VOID *LOS_KernelMallocAlign(UINT32 size, UINT32 boundary) { VOID *ptr = NULL; -#ifdef LOSCFG_KERNEL_VM +#ifdef LOSCFG_KERNEL_VM if (OsMemLargeAlloc(size) && IS_ALIGNED(PAGE_SIZE, boundary)) { ptr = LOS_PhysPagesAllocContiguous(ROUNDUP(size, PAGE_SIZE) >> PAGE_SHIFT); } else @@ -1154,7 +1225,7 @@ VOID *LOS_KernelMallocAlign(UINT32 size, UINT32 boundary) return ptr; } - +/// 重新分配内核内存空间 VOID *LOS_KernelRealloc(VOID *ptr, UINT32 size) { VOID *tmpPtr = NULL; @@ -1162,6 +1233,7 @@ VOID *LOS_KernelRealloc(VOID *ptr, UINT32 size) #ifdef LOSCFG_KERNEL_VM LosVmPage *page = NULL; errno_t ret; + if (ptr == NULL) { tmpPtr = LOS_KernelMalloc(size); } else { @@ -1198,7 +1270,7 @@ VOID LOS_KernelFree(VOID *ptr) { #ifdef LOSCFG_KERNEL_VM UINT32 ret; - if (OsMemIsHeapNode(ptr) == FALSE) { + if (OsMemIsHeapNode(ptr) == FALSE) {//判断地址是否在堆区 ret = OsMemLargeNodeFree(ptr); if (ret != LOS_OK) { VM_ERR("KernelFree %p failed", ptr); @@ -1207,6 +1279,6 @@ VOID LOS_KernelFree(VOID *ptr) } else #endif { - (VOID)LOS_MemFree(OS_SYS_MEM_ADDR, ptr); + (VOID)LOS_MemFree(OS_SYS_MEM_ADDR, ptr);//从内存池中释放 } -} +} \ No newline at end of file diff --git a/src/kernel_liteos_a/kernel/base/vm/los_vm_page.c b/src/kernel_liteos_a/kernel/base/vm/los_vm_page.c index 650fd0b0..a711ea7c 100644 --- a/src/kernel_liteos_a/kernel/base/vm/los_vm_page.c +++ b/src/kernel_liteos_a/kernel/base/vm/los_vm_page.c @@ -40,26 +40,26 @@ #ifdef LOSCFG_KERNEL_VM -LosVmPage *g_vmPageArray = NULL; -size_t g_vmPageArraySize; - +LosVmPage *g_vmPageArray = NULL;//物理页框数组 +size_t g_vmPageArraySize;//物理页框大小 +//页框初始化 STATIC VOID OsVmPageInit(LosVmPage *page, paddr_t pa, UINT8 segID) { - LOS_ListInit(&page->node); - page->flags = FILE_PAGE_FREE; - LOS_AtomicSet(&page->refCounts, 0); - page->physAddr = pa; - page->segID = segID; - page->order = VM_LIST_ORDER_MAX; + LOS_ListInit(&page->node);//页节点初始化 + page->flags = FILE_PAGE_FREE;//页标签,初始为空闲页 + LOS_AtomicSet(&page->refCounts, 0);//引用次数0 + page->physAddr = pa;//物理地址 + page->segID = segID;//物理地址使用段管理,段ID + page->order = VM_LIST_ORDER_MAX;//初始化值,不属于任何块组 page->nPages = 0; #ifdef LOSCFG_PAGE_TABLE_FINE_LOCK LOS_SpinInit(&page->lock); #endif } - +///伙伴算法初始化 STATIC INLINE VOID OsVmPageOrderListInit(LosVmPage *page, size_t nPages) -{ - OsVmPhysPagesFreeContiguous(page, nPages); +{//@note_why 此时所有页面 page->order = VM_LIST_ORDER_MAX,能挂入伙伴算法的链表吗? + OsVmPhysPagesFreeContiguous(page, nPages);//释放连续的物理页框 } #define VMPAGEINIT(page, pa, segID) do { \ @@ -68,6 +68,10 @@ STATIC INLINE VOID OsVmPageOrderListInit(LosVmPage *page, size_t nPages) (pa) += PAGE_SIZE; \ } while (0) +/*! + 完成对物理内存整体初始化,本函数一定运行在实模式下 + 1.申请大块内存g_vmPageArray存放LosVmPage,按4K一页划分物理内存存放在数组中. +*/ VOID OsVmPageStartup(VOID) { struct VmPhysSeg *seg = NULL; @@ -76,7 +80,7 @@ VOID OsVmPageStartup(VOID) UINT32 nPage; INT32 segID; - OsVmPhysAreaSizeAdjust(ROUNDUP((g_vmBootMemBase - KERNEL_ASPACE_BASE), PAGE_SIZE)); + OsVmPhysAreaSizeAdjust(ROUNDUP((g_vmBootMemBase - KERNEL_ASPACE_BASE), PAGE_SIZE));//校正 g_physArea size /* * Pages getting from OsVmPhysPageNumGet() interface here contain the memory @@ -85,20 +89,20 @@ VOID OsVmPageStartup(VOID) */ UINT32 pageNum = OsVmPhysPageNumGet(); nPage = pageNum * PAGE_SIZE / (sizeof(LosVmPage) + PAGE_SIZE); - g_vmPageArraySize = nPage * sizeof(LosVmPage); - g_vmPageArray = (LosVmPage *)OsVmBootMemAlloc(g_vmPageArraySize); + g_vmPageArraySize = nPage * sizeof(LosVmPage);//页表总大小 + g_vmPageArray = (LosVmPage *)OsVmBootMemAlloc(g_vmPageArraySize);//实模式下申请内存,此时还没有初始化MMU OsVmPhysAreaSizeAdjust(ROUNDUP(g_vmPageArraySize, PAGE_SIZE)); - OsVmPhysSegAdd(); - OsVmPhysInit(); + OsVmPhysSegAdd();// 完成对段的初始化 + OsVmPhysInit();// 加入空闲链表和设置置换算法,LRU(最近最久未使用)算法 #ifdef LOSCFG_KERNEL_PLIMITS OsMemLimitSetLimit(pageNum * PAGE_SIZE); #endif - for (segID = 0; segID < g_vmPhysSegNum; segID++) { + for (segID = 0; segID < g_vmPhysSegNum; segID++) {//遍历物理段,将段切成一页一页 seg = &g_vmPhysSeg[segID]; - nPage = seg->size >> PAGE_SHIFT; + nPage = seg->size >> PAGE_SHIFT;//本段总页数 UINT32 count = nPage >> 3; /* 3: 2 ^ 3, nPage / 8, cycle count */ UINT32 left = nPage & 0x7; /* 0x7: nPage % 8, left page */ @@ -116,17 +120,17 @@ VOID OsVmPageStartup(VOID) for (; left > 0; left--) { VMPAGEINIT(page, pa, segID); } - OsVmPageOrderListInit(seg->pageBase, nPage); + OsVmPageOrderListInit(seg->pageBase, nPage);//伙伴算法初始化,将所有页加入空闲链表供分配 } } - +///通过物理地址获取页框 LosVmPage *LOS_VmPageGet(PADDR_T paddr) { INT32 segID; LosVmPage *page = NULL; - for (segID = 0; segID < g_vmPhysSegNum; segID++) { - page = OsVmPhysToPage(paddr, segID); + for (segID = 0; segID < g_vmPhysSegNum; segID++) {//物理内存采用段页管理 + page = OsVmPhysToPage(paddr, segID);//通过物理地址和段ID找出物理页框 if (page != NULL) { break; } diff --git a/src/kernel_liteos_a/kernel/base/vm/los_vm_phys.c b/src/kernel_liteos_a/kernel/base/vm/los_vm_phys.c index 2c581456..3dc182e6 100644 --- a/src/kernel_liteos_a/kernel/base/vm/los_vm_phys.c +++ b/src/kernel_liteos_a/kernel/base/vm/los_vm_phys.c @@ -1,3 +1,29 @@ +/*! +基本概念 + 物理内存是计算机上最重要的资源之一,指的是实际的内存设备提供的、可以通过CPU总线直接进行寻址的内存空间, + 其主要作用是为操作系统及程序提供临时存储空间。LiteOS-A内核管理物理内存是通过分页实现的,除了内核堆占用的一部分内存外, + 其余可用内存均以4KiB为单位划分成页帧,内存分配和内存回收便是以页帧为单位进行操作。内核采用伙伴算法管理空闲页面, + 可以降低一定的内存碎片率,提高内存分配和释放的效率,但是一个很小的块往往也会阻塞一个大块的合并,导致不能分配较大的内存块。 +运行机制 + LiteOS-A内核的物理内存使用分布视图,主要由内核镜像、内核堆及物理页组成。内核堆部分见堆内存管理一节。 + ----------------------------------------------------- + + kernel.bin | heap | page frames + (内核镜像) | (内核堆) | (物理页框) + ----------------------------------------------------- + 伙伴算法把所有空闲页帧分成9个内存块组,每组中内存块包含2的幂次方个页帧,例如:第0组的内存块包含2的0次方个页帧, + 即1个页帧;第8组的内存块包含2的8次方个页帧,即256个页帧。相同大小的内存块挂在同一个链表上进行管理。 + +申请内存 + 系统申请20KiB内存,按一页帧4K算,即5个页帧时,9个内存块组中索引为2的链表挂着一块大小为8个页帧的内存块满足要求,分配出20KiB内存后还剩余12KiB内存, + 即3个页帧,将3个页帧分成2的幂次方之和,即0跟1,尝试查找伙伴进行合并。2个页帧的内存块没有伙伴则直接插到索引为1的链表上, + 继续查找1个页帧的内存块是否有伙伴,索引为0的链表上此时有1个,如果两个内存块地址连续则进行合并,并将内存块挂到索引为0的链表上,否则不做处理。 +释放内存 + 系统释放12KiB内存,即3个页帧,将3个页帧分成2的幂次方之和,即2跟1,尝试查找伙伴进行合并,索引为1的链表上有1个内存块, + 若地址连续则合并,并将合并后的内存块挂到索引为2的链表上,索引为0的链表上此时也有1个,如果地址连续则进行合并, + 并将合并后的内存块挂到索引为1的链表上,此时继续判断是否有伙伴,重复上述操作。 + */ + /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. @@ -41,36 +67,36 @@ #define ONE_PAGE 1 -/* Physical memory area array */ -STATIC struct VmPhysArea g_physArea[] = { +/* Physical memory area array | 物理内存区数组 */ +STATIC struct VmPhysArea g_physArea[] = {///< 这里只有一个区域,即只生成一个段 { - .start = SYS_MEM_BASE, - .size = SYS_MEM_SIZE_DEFAULT, + .start = SYS_MEM_BASE, //整个物理内存基地址,#define SYS_MEM_BASE DDR_MEM_ADDR , 0x80000000 + .size = SYS_MEM_SIZE_DEFAULT,//整个物理内存总大小 0x07f00000 }, }; -struct VmPhysSeg g_vmPhysSeg[VM_PHYS_SEG_MAX]; -INT32 g_vmPhysSegNum = 0; - +struct VmPhysSeg g_vmPhysSeg[VM_PHYS_SEG_MAX]; ///< 最大32段 +INT32 g_vmPhysSegNum = 0; ///< 段数 +/// 获取段数组,全局变量,变量放在 .bbs 区 LosVmPhysSeg *OsGVmPhysSegGet(void) { return g_vmPhysSeg; } - +/// 初始化Lru置换链表 STATIC VOID OsVmPhysLruInit(struct VmPhysSeg *seg) { INT32 i; UINT32 intSave; - LOS_SpinInit(&seg->lruLock); + LOS_SpinInit(&seg->lruLock);//初始化自旋锁,自旋锁用于CPU多核同步 LOS_SpinLockSave(&seg->lruLock, &intSave); - for (i = 0; i < VM_NR_LRU_LISTS; i++) { - seg->lruSize[i] = 0; - LOS_ListInit(&seg->lruList[i]); + for (i = 0; i < VM_NR_LRU_LISTS; i++) { //五个双循环链表 + seg->lruSize[i] = 0; //记录链表节点数 + LOS_ListInit(&seg->lruList[i]); //初始化LRU链表 } LOS_SpinUnlockRestore(&seg->lruLock, intSave); } - +/// 创建物理段,由区划分转成段管理 STATIC INT32 OsVmPhysSegCreate(paddr_t start, size_t size) { struct VmPhysSeg *seg = NULL; @@ -79,8 +105,8 @@ STATIC INT32 OsVmPhysSegCreate(paddr_t start, size_t size) return -1; } - seg = &g_vmPhysSeg[g_vmPhysSegNum++]; - for (; (seg > g_vmPhysSeg) && ((seg - 1)->start > (start + size)); seg--) { + seg = &g_vmPhysSeg[g_vmPhysSegNum++];//拿到一段数据 + for (; (seg > g_vmPhysSeg) && ((seg - 1)->start > (start + size)); seg--) {//定位到合适的段 *seg = *(seg - 1); } seg->start = start; @@ -88,21 +114,21 @@ STATIC INT32 OsVmPhysSegCreate(paddr_t start, size_t size) return 0; } - +/// 添加物理段 VOID OsVmPhysSegAdd(VOID) { INT32 i, ret; LOS_ASSERT(g_vmPhysSegNum < VM_PHYS_SEG_MAX); - - for (i = 0; i < (sizeof(g_physArea) / sizeof(g_physArea[0])); i++) { - ret = OsVmPhysSegCreate(g_physArea[i].start, g_physArea[i].size); + + for (i = 0; i < (sizeof(g_physArea) / sizeof(g_physArea[0])); i++) {//遍历g_physArea数组 + ret = OsVmPhysSegCreate(g_physArea[i].start, g_physArea[i].size);//由区划分转成段管理 if (ret != 0) { VM_ERR("create phys seg failed"); } } } - +/// 段区域大小调整 VOID OsVmPhysAreaSizeAdjust(size_t size) { /* @@ -113,35 +139,36 @@ VOID OsVmPhysAreaSizeAdjust(size_t size) g_physArea[0].size -= size; } +/// 获得物理内存的总页数 UINT32 OsVmPhysPageNumGet(VOID) { UINT32 nPages = 0; INT32 i; for (i = 0; i < (sizeof(g_physArea) / sizeof(g_physArea[0])); i++) { - nPages += g_physArea[i].size >> PAGE_SHIFT; + nPages += g_physArea[i].size >> PAGE_SHIFT;//右移12位,相当于除以4K, 计算出总页数 } - return nPages; + return nPages;//返回所有物理内存总页数 } - +/// 初始化空闲链表,分配物理页框使用伙伴算法 STATIC INLINE VOID OsVmPhysFreeListInit(struct VmPhysSeg *seg) { int i; UINT32 intSave; struct VmFreeList *list = NULL; - LOS_SpinInit(&seg->freeListLock); + LOS_SpinInit(&seg->freeListLock);//初始化用于分配的自旋锁 LOS_SpinLockSave(&seg->freeListLock, &intSave); - for (i = 0; i < VM_LIST_ORDER_MAX; i++) { - list = &seg->freeList[i]; - LOS_ListInit(&list->node); - list->listCnt = 0; + for (i = 0; i < VM_LIST_ORDER_MAX; i++) {//遍历伙伴算法空闲块组链表 + list = &seg->freeList[i]; //一个个来 + LOS_ListInit(&list->node); //LosVmPage.node将挂到list->node上 + list->listCnt = 0; //链表上的数量默认0 } LOS_SpinUnlockRestore(&seg->freeListLock, intSave); } - +/// 物理段初始化 VOID OsVmPhysInit(VOID) { struct VmPhysSeg *seg = NULL; @@ -150,13 +177,13 @@ VOID OsVmPhysInit(VOID) for (i = 0; i < g_vmPhysSegNum; i++) { seg = &g_vmPhysSeg[i]; - seg->pageBase = &g_vmPageArray[nPages]; - nPages += seg->size >> PAGE_SHIFT; - OsVmPhysFreeListInit(seg); - OsVmPhysLruInit(seg); + seg->pageBase = &g_vmPageArray[nPages];//记录本段首页物理页框地址 + nPages += seg->size >> PAGE_SHIFT;//偏移12位,按4K一页,算出本段总页数 + OsVmPhysFreeListInit(seg); //初始化空闲链表,分配页框使用伙伴算法 + OsVmPhysLruInit(seg); //初始化LRU置换链表 } } - +/// 将页框挂入空闲链表,分配物理页框从空闲链表里拿 STATIC VOID OsVmPhysFreeListAddUnsafe(LosVmPage *page, UINT8 order) { struct VmPhysSeg *seg = NULL; @@ -173,36 +200,44 @@ STATIC VOID OsVmPhysFreeListAddUnsafe(LosVmPage *page, UINT8 order) LOS_ListTailInsert(&list->node, &page->node); list->listCnt++; } - +///将物理页框从空闲链表上摘除,见于物理页框被分配的情况 STATIC VOID OsVmPhysFreeListDelUnsafe(LosVmPage *page) { struct VmPhysSeg *seg = NULL; struct VmFreeList *list = NULL; - if ((page->segID >= VM_PHYS_SEG_MAX) || (page->order >= VM_LIST_ORDER_MAX)) { + if ((page->segID >= VM_PHYS_SEG_MAX) || (page->order >= VM_LIST_ORDER_MAX)) {//等于VM_LIST_ORDER_MAX也不行,说明伙伴算法最大支持 2^8的分配 LOS_Panic("The page segment id(%u) or order(%u) is invalid\n", page->segID, page->order); } - seg = &g_vmPhysSeg[page->segID]; - list = &seg->freeList[page->order]; - list->listCnt--; - LOS_ListDelete(&page->node); - page->order = VM_LIST_ORDER_MAX; + seg = &g_vmPhysSeg[page->segID]; //找到物理页框对应的段 + list = &seg->freeList[page->order]; //根据伙伴算法组序号找到空闲链表 + list->listCnt--; //链表节点总数减一 + LOS_ListDelete(&page->node); //将自己从链表上摘除 + page->order = VM_LIST_ORDER_MAX; //告诉系统物理页框已不在空闲链表上, 用于OsVmPhysPagesSpiltUnsafe的断言 } + +/** + * @brief 本函数很像卖猪肉的,拿一大块肉剁,先把多余的放回到小块肉堆里去. + * @param page + * @param oldOrder 原本要买 2^2肉 + * @param newOrder 却找到个 2^8肉块 + * @return STATIC + */ STATIC VOID OsVmPhysPagesSpiltUnsafe(LosVmPage *page, UINT8 oldOrder, UINT8 newOrder) { UINT32 order; LosVmPage *buddyPage = NULL; - for (order = newOrder; order > oldOrder;) { - order--; - buddyPage = &page[VM_ORDER_TO_PAGES(order)]; - LOS_ASSERT(buddyPage->order == VM_LIST_ORDER_MAX); - OsVmPhysFreeListAddUnsafe(buddyPage, order); + for (order = newOrder; order > oldOrder;) {//把肉剁碎的过程,把多余的肉块切成2^7,2^6...标准块, + order--;//越切越小,逐一挂到对应的空闲链表上 + buddyPage = &page[VM_ORDER_TO_PAGES(order)];//@note_good 先把多余的肉割出来,这句代码很赞!因为LosVmPage本身是在一个大数组上,page[nPages]可直接定位 + LOS_ASSERT(buddyPage->order == VM_LIST_ORDER_MAX);//没挂到伙伴算法对应组块空闲链表上的物理页框的order必须是VM_LIST_ORDER_MAX + OsVmPhysFreeListAddUnsafe(buddyPage, order);//将劈开的节点挂到对应序号的链表上,buddyPage->order = order } } - +///通过物理地址获取所属参数段的物理页框 LosVmPage *OsVmPhysToPage(paddr_t pa, UINT8 segID) { struct VmPhysSeg *seg = NULL; @@ -216,8 +251,8 @@ LosVmPage *OsVmPhysToPage(paddr_t pa, UINT8 segID) return NULL; } - offset = pa - seg->start; - return (seg->pageBase + (offset >> PAGE_SHIFT)); + offset = pa - seg->start;//得到物理地址的偏移量 + return (seg->pageBase + (offset >> PAGE_SHIFT));//得到对应的物理页框 } LosVmPage *OsVmPaddrToPage(paddr_t paddr) @@ -233,31 +268,37 @@ LosVmPage *OsVmPaddrToPage(paddr_t paddr) } return NULL; } - -VOID *OsVmPageToVaddr(LosVmPage *page) +/*! + * @brief 通过page获取内核空间的虚拟地址 参考OsArchMmuInit + \n #define SYS_MEM_BASE DDR_MEM_ADDR /* physical memory base 物理地址的起始地址 * / + \n 本函数非常重要,通过一个物理地址找到内核虚拟地址 + \n 内核静态映射:提升虚实转化效率,段映射减少页表项 + * @param page + * @return VOID* + */ +VOID *OsVmPageToVaddr(LosVmPage *page)// { VADDR_T vaddr; - vaddr = KERNEL_ASPACE_BASE + page->physAddr - SYS_MEM_BASE; - - return (VOID *)(UINTPTR)vaddr; + vaddr = KERNEL_ASPACE_BASE + page->physAddr - SYS_MEM_BASE;//表示申请的物理地址在物理空间的偏移量等于映射的虚拟地址在内核空间的偏移量 + return (VOID *)(UINTPTR)vaddr;//不需要存储映射关系,这简直就是神来之笔,拍案叫绝。@note_good 详见 鸿蒙内核源码分析(页表管理篇) } - +///通过虚拟地址找映射的物理页框 LosVmPage *OsVmVaddrToPage(VOID *ptr) { struct VmPhysSeg *seg = NULL; - PADDR_T pa = LOS_PaddrQuery(ptr); + PADDR_T pa = LOS_PaddrQuery(ptr);//通过空间的虚拟地址查询物理地址 UINT32 segID; - for (segID = 0; segID < g_vmPhysSegNum; segID++) { + for (segID = 0; segID < g_vmPhysSegNum; segID++) {//遍历所有段 seg = &g_vmPhysSeg[segID]; - if ((pa >= seg->start) && (pa < (seg->start + seg->size))) { - return seg->pageBase + ((pa - seg->start) >> PAGE_SHIFT); + if ((pa >= seg->start) && (pa < (seg->start + seg->size))) {//找到物理地址所在的段 + return seg->pageBase + ((pa - seg->start) >> PAGE_SHIFT);//段基地址+页偏移索引 得到虚拟地址经映射所在物理页框 } } return NULL; } - +/// 回收一定范围内的页框 STATIC INLINE VOID OsVmRecycleExtraPages(LosVmPage *page, size_t startPage, size_t endPage) { if (startPage >= endPage) { @@ -266,7 +307,7 @@ STATIC INLINE VOID OsVmRecycleExtraPages(LosVmPage *page, size_t startPage, size OsVmPhysPagesFreeContiguous(page, endPage - startPage); } - +/// 大块的物理内存分配 STATIC LosVmPage *OsVmPhysLargeAlloc(struct VmPhysSeg *seg, size_t nPages) { struct VmFreeList *list = NULL; @@ -276,11 +317,11 @@ STATIC LosVmPage *OsVmPhysLargeAlloc(struct VmPhysSeg *seg, size_t nPages) PADDR_T paEnd; size_t size = nPages << PAGE_SHIFT; - list = &seg->freeList[VM_LIST_ORDER_MAX - 1]; - LOS_DL_LIST_FOR_EACH_ENTRY(page, &list->node, LosVmPage, node) { + list = &seg->freeList[VM_LIST_ORDER_MAX - 1];//先找伙伴算法中内存块最大的开撸 + LOS_DL_LIST_FOR_EACH_ENTRY(page, &list->node, LosVmPage, node) {//遍历链表 paStart = page->physAddr; paEnd = paStart + size; - if (paEnd > (seg->start + seg->size)) { + if (paEnd > (seg->start + seg->size)) {//匹配物理地址范围 continue; } @@ -302,7 +343,7 @@ STATIC LosVmPage *OsVmPhysLargeAlloc(struct VmPhysSeg *seg, size_t nPages) return NULL; } - +/// 申请物理页并挂在对应的链表上 STATIC LosVmPage *OsVmPhysPagesAlloc(struct VmPhysSeg *seg, size_t nPages) { struct VmFreeList *list = NULL; @@ -312,13 +353,13 @@ STATIC LosVmPage *OsVmPhysPagesAlloc(struct VmPhysSeg *seg, size_t nPages) UINT32 newOrder; order = OsVmPagesToOrder(nPages); - if (order < VM_LIST_ORDER_MAX) { - for (newOrder = order; newOrder < VM_LIST_ORDER_MAX; newOrder++) { + if (order < VM_LIST_ORDER_MAX) {//按正常的伙伴算法分配 + for (newOrder = order; newOrder < VM_LIST_ORDER_MAX; newOrder++) {//从小往大了撸 list = &seg->freeList[newOrder]; - if (LOS_ListEmpty(&list->node)) { - continue; + if (LOS_ListEmpty(&list->node)) {//这条链路上没有可分配的物理页框 + continue;//继续往大的找 } - page = LOS_DL_LIST_ENTRY(LOS_DL_LIST_FIRST(&list->node), LosVmPage, node); + page = LOS_DL_LIST_ENTRY(LOS_DL_LIST_FIRST(&list->node), LosVmPage, node);//找到了直接返回第一个节点 goto DONE; } } else { @@ -339,7 +380,7 @@ DONE: return page; } - +/// 释放物理页框,所谓释放物理页就是把页挂到空闲链表中 VOID OsVmPhysPagesFree(LosVmPage *page, UINT8 order) { paddr_t pa; @@ -349,51 +390,59 @@ VOID OsVmPhysPagesFree(LosVmPage *page, UINT8 order) return; } - if (order < VM_LIST_ORDER_MAX - 1) { - pa = VM_PAGE_TO_PHYS(page); - do { - pa ^= VM_ORDER_TO_PHYS(order); - buddyPage = OsVmPhysToPage(pa, page->segID); - if ((buddyPage == NULL) || (buddyPage->order != order)) { + if (order < VM_LIST_ORDER_MAX - 1) {//order[0,7] + pa = VM_PAGE_TO_PHYS(page);//获取物理地址 + do {//按位异或 + pa ^= VM_ORDER_TO_PHYS(order);//@note_good 注意这里是高位和低位的 ^= ,也就是说跳到order块组物理地址处,此处处理甚妙! + buddyPage = OsVmPhysToPage(pa, page->segID);//通过物理地址拿到页框 + if ((buddyPage == NULL) || (buddyPage->order != order)) {//页框所在组块必须要对应 break; } - OsVmPhysFreeListDelUnsafe(buddyPage); + OsVmPhysFreeListDelUnsafe(buddyPage);//注意buddypage是连续的物理页框 例如order=2时,2^2=4页就是一个块组 |_|_|_|_| order++; pa &= ~(VM_ORDER_TO_PHYS(order) - 1); page = OsVmPhysToPage(pa, page->segID); } while (order < VM_LIST_ORDER_MAX - 1); } - OsVmPhysFreeListAddUnsafe(page, order); + OsVmPhysFreeListAddUnsafe(page, order);//伙伴算法 空闲节点增加 } - +///连续的释放物理页框, 如果8页连在一块是一起释放的 VOID OsVmPhysPagesFreeContiguous(LosVmPage *page, size_t nPages) { paddr_t pa; UINT32 order; size_t n; - while (TRUE) { - pa = VM_PAGE_TO_PHYS(page); - order = VM_PHYS_TO_ORDER(pa); - n = VM_ORDER_TO_PAGES(order); - if (n > nPages) { + while (TRUE) {//死循环 + pa = VM_PAGE_TO_PHYS(page);//获取页面物理地址 + order = VM_PHYS_TO_ORDER(pa);//通过物理地址找到伙伴算法的级别 + n = VM_ORDER_TO_PAGES(order);//通过级别找到物理页块 (1< nPages) {//nPages只剩下小于2^order时,退出循环 break; } - OsVmPhysPagesFree(page, order); - nPages -= n; - page += n; + OsVmPhysPagesFree(page, order);//释放伙伴算法对应块组 + nPages -= n;//总页数减少 + page += n;//释放的页数增多 } - + //举例剩下 7个页框时,依次用 2^2 2^1 2^0 方式释放 while (nPages > 0) { - order = LOS_HighBitGet(nPages); - n = VM_ORDER_TO_PAGES(order); - OsVmPhysPagesFree(page, order); + order = LOS_HighBitGet(nPages);//从高到低块组释放 + n = VM_ORDER_TO_PAGES(order);//2^order次方 + OsVmPhysPagesFree(page, order);//释放块组 nPages -= n; - page += n; + page += n;//相当于page[n] } } +/*! + * @brief OsVmPhysPagesGet 获取一定数量的页框 LosVmPage实体是放在全局大数组中的, + * LosVmPage->nPages 标记了分配页数 + * @param nPages + * @return + * + * @see + */ STATIC LosVmPage *OsVmPhysPagesGet(size_t nPages) { UINT32 intSave; @@ -404,11 +453,11 @@ STATIC LosVmPage *OsVmPhysPagesGet(size_t nPages) for (segID = 0; segID < g_vmPhysSegNum; segID++) { seg = &g_vmPhysSeg[segID]; LOS_SpinLockSave(&seg->freeListLock, &intSave); - page = OsVmPhysPagesAlloc(seg, nPages); - if (page != NULL) { - /* the first page of continuous physical addresses holds refCounts */ - LOS_AtomicSet(&page->refCounts, 0); - page->nPages = nPages; + page = OsVmPhysPagesAlloc(seg, nPages);//分配指定页数的物理页,nPages需小于伙伴算法一次能分配的最大页数 + if (page != NULL) {//分配成功 + /* */ + LOS_AtomicSet(&page->refCounts, 0);//设置引用次数为0 + page->nPages = nPages;//页数 LOS_SpinUnlockRestore(&seg->freeListLock, intSave); return page; } @@ -416,7 +465,7 @@ STATIC LosVmPage *OsVmPhysPagesGet(size_t nPages) } return NULL; } - +///分配连续的物理页 VOID *LOS_PhysPagesAllocContiguous(size_t nPages) { LosVmPage *page = NULL; @@ -424,15 +473,15 @@ VOID *LOS_PhysPagesAllocContiguous(size_t nPages) if (nPages == 0) { return NULL; } - - page = OsVmPhysPagesGet(nPages); + //鸿蒙 nPages 不能大于 2^8 次方,即256个页,1M内存,仅限于内核态,用户态不限制分配大小. + page = OsVmPhysPagesGet(nPages);//通过伙伴算法获取物理上连续的页 if (page == NULL) { return NULL; } - return OsVmPageToVaddr(page); + return OsVmPageToVaddr(page);//通过物理页找虚拟地址 } - +/// 释放指定页数地址连续的物理内存 VOID LOS_PhysPagesFreeContiguous(VOID *ptr, size_t nPages) { UINT32 intSave; @@ -443,17 +492,17 @@ VOID LOS_PhysPagesFreeContiguous(VOID *ptr, size_t nPages) return; } - page = OsVmVaddrToPage(ptr); + page = OsVmVaddrToPage(ptr);//通过虚拟地址找到页框 if (page == NULL) { VM_ERR("vm page of ptr(%#x) is null", ptr); return; } - page->nPages = 0; + page->nPages = 0;//被分配的页数置为0,表示不被分配 seg = &g_vmPhysSeg[page->segID]; LOS_SpinLockSave(&seg->freeListLock, &intSave); - OsVmPhysPagesFreeContiguous(page, nPages); + OsVmPhysPagesFreeContiguous(page, nPages);//具体释放实现 LOS_SpinUnlockRestore(&seg->freeListLock, intSave); #ifdef LOSCFG_KERNEL_PLIMITS @@ -468,7 +517,7 @@ PADDR_T OsKVaddrToPaddr(VADDR_T kvaddr) } return (kvaddr - KERNEL_ASPACE_BASE + SYS_MEM_BASE); } - +/// 通过物理地址获取内核虚拟地址 VADDR_T *LOS_PaddrToKVaddr(PADDR_T paddr) { struct VmPhysSeg *seg = NULL; @@ -484,10 +533,10 @@ VADDR_T *LOS_PaddrToKVaddr(PADDR_T paddr) return (VADDR_T *)(UINTPTR)(paddr - SYS_MEM_BASE + KERNEL_ASPACE_BASE); } } - - return (VADDR_T *)(UINTPTR)(paddr - SYS_MEM_BASE + KERNEL_ASPACE_BASE); + //内核 + return (VADDR_T *)(UINTPTR)(paddr - SYS_MEM_BASE + KERNEL_ASPACE_BASE);// } - +///释放一个物理页框 VOID LOS_PhysPageFree(LosVmPage *page) { UINT32 intSave; @@ -497,12 +546,12 @@ VOID LOS_PhysPageFree(LosVmPage *page) return; } - if (LOS_AtomicDecRet(&page->refCounts) <= 0) { + if (LOS_AtomicDecRet(&page->refCounts) <= 0) {//减少引用数后不能小于0 seg = &g_vmPhysSeg[page->segID]; LOS_SpinLockSave(&seg->freeListLock, &intSave); - OsVmPhysPagesFreeContiguous(page, ONE_PAGE); - LOS_AtomicSet(&page->refCounts, 0); + OsVmPhysPagesFreeContiguous(page, ONE_PAGE);//释放一页 + LOS_AtomicSet(&page->refCounts, 0);//只要物理内存被释放了,引用数就必须得重置为 0 LOS_SpinUnlockRestore(&seg->freeListLock, intSave); } @@ -510,12 +559,22 @@ VOID LOS_PhysPageFree(LosVmPage *page) OsMemLimitMemFree(PAGE_SIZE); #endif } - +/// 申请一个物理页 LosVmPage *LOS_PhysPageAlloc(VOID) { - return OsVmPhysPagesGet(ONE_PAGE); + return OsVmPhysPagesGet(ONE_PAGE);//分配一页物理页 } +/*! + * @brief LOS_PhysPagesAlloc 分配nPages页个物理页框,并将页框挂入list + \n 返回已分配的页面大小,不负责一定能分配到nPages的页框 + * + * @param list + * @param nPages + * @return + * + * @see + */ size_t LOS_PhysPagesAlloc(size_t nPages, LOS_DL_LIST *list) { LosVmPage *page = NULL; @@ -526,17 +585,17 @@ size_t LOS_PhysPagesAlloc(size_t nPages, LOS_DL_LIST *list) } while (nPages--) { - page = OsVmPhysPagesGet(ONE_PAGE); + page = OsVmPhysPagesGet(ONE_PAGE);//一页一页分配,由伙伴算法分配 if (page == NULL) { break; } - LOS_ListTailInsert(list, &page->node); + LOS_ListTailInsert(list, &page->node);//从参数链表list尾部挂入新页面结点 count++; } return count; } - +///拷贝共享页面 VOID OsPhysSharePageCopy(PADDR_T oldPaddr, PADDR_T *newPaddr, LosVmPage *newPage) { UINT32 intSave; @@ -550,43 +609,43 @@ VOID OsPhysSharePageCopy(PADDR_T oldPaddr, PADDR_T *newPaddr, LosVmPage *newPage return; } - oldPage = LOS_VmPageGet(oldPaddr); + oldPage = LOS_VmPageGet(oldPaddr);//由物理地址得到页框 if (oldPage == NULL) { VM_ERR("invalid oldPaddr %p", oldPaddr); return; } - seg = &g_vmPhysSeg[oldPage->segID]; + seg = &g_vmPhysSeg[oldPage->segID];//拿到物理段 LOS_SpinLockSave(&seg->freeListLock, &intSave); - if (LOS_AtomicRead(&oldPage->refCounts) == 1) { - *newPaddr = oldPaddr; - } else { - newMem = LOS_PaddrToKVaddr(*newPaddr); - oldMem = LOS_PaddrToKVaddr(oldPaddr); + if (LOS_AtomicRead(&oldPage->refCounts) == 1) {//页面引用次数仅一次,说明只有一个进程在操作 + *newPaddr = oldPaddr;//新老指向同一块物理地址 + } else {//是个共享内存 + newMem = LOS_PaddrToKVaddr(*newPaddr); //新页虚拟地址 + oldMem = LOS_PaddrToKVaddr(oldPaddr); //老页虚拟地址 if ((newMem == NULL) || (oldMem == NULL)) { LOS_SpinUnlockRestore(&seg->freeListLock, intSave); return; - } - if (memcpy_s(newMem, PAGE_SIZE, oldMem, PAGE_SIZE) != EOK) { + }//请记住,在保护模式下,物理地址只能用于计算,操作(包括拷贝)需要虚拟地址! + if (memcpy_s(newMem, PAGE_SIZE, oldMem, PAGE_SIZE) != EOK) {//老页内容复制给新页,需操作虚拟地址,拷贝一页数据 VM_ERR("memcpy_s failed"); } - LOS_AtomicInc(&newPage->refCounts); - LOS_AtomicDec(&oldPage->refCounts); + LOS_AtomicInc(&newPage->refCounts);//新页引用次数以原子方式自动减量 + LOS_AtomicDec(&oldPage->refCounts);//老页引用次数以原子方式自动减量 } LOS_SpinUnlockRestore(&seg->freeListLock, intSave); return; } - +///获取物理页框所在段 struct VmPhysSeg *OsVmPhysSegGet(LosVmPage *page) { if ((page == NULL) || (page->segID >= VM_PHYS_SEG_MAX)) { return NULL; } - return (OsGVmPhysSegGet() + page->segID); + return (OsGVmPhysSegGet() + page->segID);//等用于OsGVmPhysSegGet()[page->segID] } - +///获取参数nPages对应的块组,例如 7 -> 2^3 返回 3 UINT32 OsVmPagesToOrder(size_t nPages) { UINT32 order; @@ -595,7 +654,7 @@ UINT32 OsVmPagesToOrder(size_t nPages) return order; } - +///释放双链表中的所有节点内存,本质是回归到伙伴orderlist中 size_t LOS_PhysPagesFree(LOS_DL_LIST *list) { UINT32 intSave; @@ -608,16 +667,16 @@ size_t LOS_PhysPagesFree(LOS_DL_LIST *list) return 0; } - LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(page, nPage, list, LosVmPage, node) { - LOS_ListDelete(&page->node); - if (LOS_AtomicDecRet(&page->refCounts) <= 0) { - seg = &g_vmPhysSeg[page->segID]; - LOS_SpinLockSave(&seg->freeListLock, &intSave); - OsVmPhysPagesFreeContiguous(page, ONE_PAGE); - LOS_AtomicSet(&page->refCounts, 0); - LOS_SpinUnlockRestore(&seg->freeListLock, intSave); + LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(page, nPage, list, LosVmPage, node) {//宏循环 + LOS_ListDelete(&page->node);//先把自己摘出去 + if (LOS_AtomicDecRet(&page->refCounts) <= 0) {//无引用 + seg = &g_vmPhysSeg[page->segID];//获取物理段 + LOS_SpinLockSave(&seg->freeListLock, &intSave);//锁住freeList + OsVmPhysPagesFreeContiguous(page, ONE_PAGE);//连续释放,注意这里的ONE_PAGE其实有误导,让人以为是释放4K,其实是指连续的物理页框,如果3页连在一块是一起释放的. + LOS_AtomicSet(&page->refCounts, 0);//引用重置为0 + LOS_SpinUnlockRestore(&seg->freeListLock, intSave);//恢复锁 } - count++; + count++;//继续取下一个node } return count; @@ -632,4 +691,3 @@ VADDR_T *LOS_PaddrToKVaddr(PADDR_T paddr) return (VADDR_T *)DMA_TO_VMM_ADDR(paddr); } #endif - diff --git a/src/kernel_liteos_a/kernel/base/vm/los_vm_scan.c b/src/kernel_liteos_a/kernel/base/vm/los_vm_scan.c index ab467818..01624eac 100644 --- a/src/kernel_liteos_a/kernel/base/vm/los_vm_scan.c +++ b/src/kernel_liteos_a/kernel/base/vm/los_vm_scan.c @@ -37,6 +37,10 @@ #ifdef LOSCFG_KERNEL_VM /* unmap a lru page by map record info caller need lru lock */ +/************************************************************************************************** + 解除文件页和进程(mmu)的映射关系 + 参数info记录了进程的MMU +**************************************************************************************************/ VOID OsUnmapPageLocked(LosFilePage *page, LosMapInfo *info) { if (page == NULL || info == NULL) { @@ -47,88 +51,88 @@ VOID OsUnmapPageLocked(LosFilePage *page, LosMapInfo *info) LOS_ListDelete(&info->node); LOS_AtomicDec(&page->vmPage->refCounts); LOS_ArchMmuUnmap(info->archMmu, info->vaddr, 1); - LOS_MemFree(m_aucSysMem0, info); + LOS_MemFree(m_aucSysMem0, info);//释放虚拟 } - +///解除文件页在所有进程的映射 VOID OsUnmapAllLocked(LosFilePage *page) { LosMapInfo *info = NULL; LosMapInfo *next = NULL; LOS_DL_LIST *immap = &page->i_mmap; - - LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(info, next, immap, LosMapInfo, node) { + + LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(info, next, immap, LosMapInfo, node) {//遍历 immap->info 链表 OsUnmapPageLocked(page, info); } } /* add a new lru node to lru list, lruType can be file or anon */ -VOID OsLruCacheAdd(LosFilePage *fpage, enum OsLruList lruType) +VOID OsLruCacheAdd(LosFilePage *fpage, enum OsLruList lruType)//在lru列表中添加一个新的lru节点,lruType可以是文件或匿名 { UINT32 intSave; - LosVmPhysSeg *physSeg = fpage->physSeg; - LosVmPage *page = fpage->vmPage; + LosVmPhysSeg *physSeg = fpage->physSeg; //得到页面对应段 + LosVmPage *page = fpage->vmPage; //得到物理页面 - LOS_SpinLockSave(&physSeg->lruLock, &intSave); - OsSetPageActive(page); - OsCleanPageReferenced(page); - physSeg->lruSize[lruType]++; - LOS_ListTailInsert(&physSeg->lruList[lruType], &fpage->lru); + LOS_SpinLockSave(&physSeg->lruLock, &intSave);//自旋锁:最多只能被一个内核持有,CPU内核 互斥锁 + OsSetPageActive(page); //设置页面为活动页 + OsCleanPageReferenced(page);//清除页面被引用位 + physSeg->lruSize[lruType]++; //lruType页总size++ + LOS_ListTailInsert(&physSeg->lruList[lruType], &fpage->lru);//加入lruType页双循环链表中 - LOS_SpinUnlockRestore(&physSeg->lruLock, intSave); + LOS_SpinUnlockRestore(&physSeg->lruLock, intSave);//解锁 } -/* delete a lru node, caller need hold lru_lock */ -VOID OsLruCacheDel(LosFilePage *fpage) +/* dellete a lru node, caller need hold lru_lock */ +VOID OsLruCacheDel(LosFilePage *fpage)//删除lru节点,调用者需要拿到lru锁 { - LosVmPhysSeg *physSeg = fpage->physSeg; - int type = OsIsPageActive(fpage->vmPage) ? VM_LRU_ACTIVE_FILE : VM_LRU_INACTIVE_FILE; + LosVmPhysSeg *physSeg = fpage->physSeg; //得到页面对应段 + int type = OsIsPageActive(fpage->vmPage) ? VM_LRU_ACTIVE_FILE : VM_LRU_INACTIVE_FILE;//得到页面LRU类型 - physSeg->lruSize[type]--; - LOS_ListDelete(&fpage->lru); + physSeg->lruSize[type]--; //type页总size-- + LOS_ListDelete(&fpage->lru);//将自己从lru链表中摘出来 } - +///非活动文件页低于活动文件页吗 BOOL OsInactiveListIsLow(LosVmPhysSeg *physSeg) { return (physSeg->lruSize[VM_LRU_ACTIVE_FILE] > - physSeg->lruSize[VM_LRU_INACTIVE_FILE]) ? TRUE : FALSE; + physSeg->lruSize[VM_LRU_INACTIVE_FILE]) ? TRUE : FALSE;//直接对比size,效率杠杠的 } /* move a page from inactive list to active list head */ -STATIC INLINE VOID OsMoveToActiveList(LosFilePage *fpage) +STATIC INLINE VOID OsMoveToActiveList(LosFilePage *fpage)//将页面从非活动列表移动到活动列表 { - LosVmPhysSeg *physSeg = fpage->physSeg; + LosVmPhysSeg *physSeg = fpage->physSeg; //得到页面对应段 - physSeg->lruSize[VM_LRU_ACTIVE_FILE]++; - physSeg->lruSize[VM_LRU_INACTIVE_FILE]--; - LOS_ListDelete(&fpage->lru); - LOS_ListTailInsert(&physSeg->lruList[VM_LRU_ACTIVE_FILE], &fpage->lru); + physSeg->lruSize[VM_LRU_ACTIVE_FILE]++; //活动页总size++ + physSeg->lruSize[VM_LRU_INACTIVE_FILE]--; //不活动页总size-- + LOS_ListDelete(&fpage->lru); //将自己从lru链表中摘出来 + LOS_ListTailInsert(&physSeg->lruList[VM_LRU_ACTIVE_FILE], &fpage->lru);//加入活动页双循环链表中 } /* move a page from active list to inactive list head */ -STATIC INLINE VOID OsMoveToInactiveList(LosFilePage *fpage) +STATIC INLINE VOID OsMoveToInactiveList(LosFilePage *fpage)//将页面从活动列表移动到非活动列表 { - LosVmPhysSeg *physSeg = fpage->physSeg; + LosVmPhysSeg *physSeg = fpage->physSeg; //得到页面对应段 - physSeg->lruSize[VM_LRU_ACTIVE_FILE]--; - physSeg->lruSize[VM_LRU_INACTIVE_FILE]++; - LOS_ListDelete(&fpage->lru); - LOS_ListTailInsert(&physSeg->lruList[VM_LRU_INACTIVE_FILE], &fpage->lru); + physSeg->lruSize[VM_LRU_ACTIVE_FILE]--; //活动页总size-- + physSeg->lruSize[VM_LRU_INACTIVE_FILE]++; //不活动页总size++ + LOS_ListDelete(&fpage->lru); //将自己从lru链表中摘出来 + LOS_ListTailInsert(&physSeg->lruList[VM_LRU_INACTIVE_FILE], &fpage->lru);//加入不活动页双循环链表中 } -/* move a page to the most active pos in lru list(active head) */ +/* move a page to the most active pos in lru list(active head) *///将页面移至lru列表中最活跃的位置 STATIC INLINE VOID OsMoveToActiveHead(LosFilePage *fpage) { - LosVmPhysSeg *physSeg = fpage->physSeg; - LOS_ListDelete(&fpage->lru); - LOS_ListTailInsert(&physSeg->lruList[VM_LRU_ACTIVE_FILE], &fpage->lru); + LosVmPhysSeg *physSeg = fpage->physSeg; //得到页面对应段 + LOS_ListDelete(&fpage->lru); //将自己从lru链表中摘出来 + LOS_ListTailInsert(&physSeg->lruList[VM_LRU_ACTIVE_FILE], &fpage->lru);//加入活动页双循环链表中 } /* move a page to the most active pos in lru list(inactive head) */ -STATIC INLINE VOID OsMoveToInactiveHead(LosFilePage *fpage) +STATIC INLINE VOID OsMoveToInactiveHead(LosFilePage *fpage)//鸿蒙会从inactive链表的尾部开始进行回收,跟linux一样 { - LosVmPhysSeg *physSeg = fpage->physSeg; - LOS_ListDelete(&fpage->lru); - LOS_ListTailInsert(&physSeg->lruList[VM_LRU_INACTIVE_FILE], &fpage->lru); + LosVmPhysSeg *physSeg = fpage->physSeg; //得到页面对应段 + LOS_ListDelete(&fpage->lru); //将自己从lru链表中摘出来 + LOS_ListTailInsert(&physSeg->lruList[VM_LRU_INACTIVE_FILE], &fpage->lru);//加入不活动页双循环链表中 } /* page referced add: (call by page cache get) @@ -138,7 +142,7 @@ ref:0, act:0 --> ref:1, act:0 ref:1, act:0 --> ref:0, act:1 ref:0, act:1 --> ref:1, act:1 */ -VOID OsPageRefIncLocked(LosFilePage *fpage) +VOID OsPageRefIncLocked(LosFilePage *fpage)// ref ,act 标签转换功能 { BOOL isOrgActive; UINT32 intSave; @@ -148,16 +152,16 @@ VOID OsPageRefIncLocked(LosFilePage *fpage) return; } - LOS_SpinLockSave(&fpage->physSeg->lruLock, &intSave); + LOS_SpinLockSave(&fpage->physSeg->lruLock, &intSave);//要处理lruList,先拿锁 - page = fpage->vmPage; - isOrgActive = OsIsPageActive(page); + page = fpage->vmPage;//拿到物理页框 + isOrgActive = OsIsPageActive(page);//页面是否在活动 - if (OsIsPageReferenced(page) && !OsIsPageActive(page)) { - OsCleanPageReferenced(page); - OsSetPageActive(page); + if (OsIsPageReferenced(page) && !OsIsPageActive(page)) {//身兼 不活动和引用标签 + OsCleanPageReferenced(page);//撕掉引用标签 ref:1, act:0 --> ref:0, act:1 + OsSetPageActive(page); //贴上活动标签 } else if (!OsIsPageReferenced(page)) { - OsSetPageReferenced(page); + OsSetPageReferenced(page);//ref:0, act:0 --> ref:1, act:0 } if (!isOrgActive && OsIsPageActive(page)) { @@ -175,14 +179,14 @@ VOID OsPageRefIncLocked(LosFilePage *fpage) LOS_SpinUnlockRestore(&fpage->physSeg->lruLock, intSave); } -/* page referced dec: (call by shrinker) +/* page referced dec: (call by thrinker) ----------inactive----------|----------active------------ [ref:0,act:0], [ref:1,act:0]|[ref:0,act:1], [ref:1,act:1] ref:1, act:1 --> ref:0, act:1 ref:0, act:1 --> ref:1, act:0 ref:1, act:0 --> ref:0, act:0 */ -VOID OsPageRefDecNoLock(LosFilePage *fpage) +VOID OsPageRefDecNoLock(LosFilePage *fpage) // ref ,act 标签转换功能 { BOOL isOrgActive; LosVmPage *page = NULL; @@ -194,7 +198,7 @@ VOID OsPageRefDecNoLock(LosFilePage *fpage) page = fpage->vmPage; isOrgActive = OsIsPageActive(page); - if (!OsIsPageReferenced(page) && OsIsPageActive(page)) { + if (!OsIsPageReferenced(page) && OsIsPageActive(page)) {//[ref:0,act:1]的情况 OsCleanPageActive(page); OsSetPageReferenced(page); } else if (OsIsPageReferenced(page)) { @@ -205,39 +209,39 @@ VOID OsPageRefDecNoLock(LosFilePage *fpage) OsMoveToInactiveList(fpage); } } - +///缩小活动页链表 VOID OsShrinkActiveList(LosVmPhysSeg *physSeg, int nScan) { LosFilePage *fpage = NULL; LosFilePage *fnext = NULL; LOS_DL_LIST *activeFile = &physSeg->lruList[VM_LRU_ACTIVE_FILE]; - LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(fpage, fnext, activeFile, LosFilePage, lru) { - if (LOS_SpinTrylock(&fpage->mapping->list_lock) != LOS_OK) { - continue; + LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(fpage, fnext, activeFile, LosFilePage, lru) {//一页一页处理 + if (LOS_SpinTrylock(&fpage->mapping->list_lock) != LOS_OK) {//尝试获取文件页所在的page_mapping锁 + continue;//接着处理下一文件页 } - /* happened when caller hold cache lock and try reclaim this page */ - if (OsIsPageLocked(fpage->vmPage)) { - LOS_SpinUnlock(&fpage->mapping->list_lock); - continue; + /* happend when caller hold cache lock and try reclaim this page *///调用方持有缓存锁并尝试回收此页时发生 + if (OsIsPageLocked(fpage->vmPage)) {//页面是否被锁 + LOS_SpinUnlock(&fpage->mapping->list_lock);//失败时,一定要释放page_mapping锁. + continue;//接着处理下一文件页 } - if (OsIsPageMapped(fpage) && (fpage->flags & VM_MAP_REGION_FLAG_PERM_EXECUTE)) { - LOS_SpinUnlock(&fpage->mapping->list_lock); - continue; + if (OsIsPageMapped(fpage) && (fpage->flags & VM_MAP_REGION_FLAG_PERM_EXECUTE)) {//文件页是否被映射而且是个可执行文件 ? + LOS_SpinUnlock(&fpage->mapping->list_lock);//是时,一定要释放page_mapping锁. + continue;//接着处理下一文件页 } + //找了可以收缩的文件页 + OsPageRefDecNoLock(fpage); //将页面移到未活动文件链表 - OsPageRefDecNoLock(fpage); - - LOS_SpinUnlock(&fpage->mapping->list_lock); + LOS_SpinUnlock(&fpage->mapping->list_lock); //释放page_mapping锁. if (--nScan <= 0) { break; } } } - +///缩小未活动页链表 int OsShrinkInactiveList(LosVmPhysSeg *physSeg, int nScan, LOS_DL_LIST *list) { UINT32 nrReclaimed = 0; @@ -248,36 +252,36 @@ int OsShrinkInactiveList(LosVmPhysSeg *physSeg, int nScan, LOS_DL_LIST *list) LosFilePage *ftemp = NULL; LOS_DL_LIST *inactive_file = &physSeg->lruList[VM_LRU_INACTIVE_FILE]; - LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(fpage, fnext, inactive_file, LosFilePage, lru) { + LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(fpage, fnext, inactive_file, LosFilePage, lru) {//遍历链表一页一页处理 flock = &fpage->mapping->list_lock; - if (LOS_SpinTrylock(flock) != LOS_OK) { - continue; + if (LOS_SpinTrylock(flock) != LOS_OK) {//尝试获取文件页所在的page_mapping锁 + continue;//接着处理下一文件页 } - page = fpage->vmPage; - if (OsIsPageLocked(page)) { + page = fpage->vmPage;//获取物理页框 + if (OsIsPageLocked(page)) {//页面是否被锁 LOS_SpinUnlock(flock); - continue; + continue;//接着处理下一文件页 } if (OsIsPageMapped(fpage) && (OsIsPageDirty(page) || (fpage->flags & VM_MAP_REGION_FLAG_PERM_EXECUTE))) { - LOS_SpinUnlock(flock); - continue; + LOS_SpinUnlock(flock);//文件页是否被映射而且是个脏页获取是个可执行文件 ? + continue;//接着处理下一文件页 } - if (OsIsPageDirty(page)) { - ftemp = OsDumpDirtyPage(fpage); - if (ftemp != NULL) { - LOS_ListTailInsert(list, &ftemp->node); + if (OsIsPageDirty(page)) {//是脏页 + ftemp = OsDumpDirtyPage(fpage);//备份脏页 + if (ftemp != NULL) {//备份成功了 + LOS_ListTailInsert(list, &ftemp->node);//将脏页挂到参数链表上带走 } } - OsDeletePageCacheLru(fpage); + OsDeletePageCacheLru(fpage);//将文件页从LRU和pagecache上摘除 LOS_SpinUnlock(flock); - nrReclaimed++; + nrReclaimed++;//成功回收了一页 - if (--nScan <= 0) { + if (--nScan <= 0) {//继续回收 break; } } @@ -286,48 +290,48 @@ int OsShrinkInactiveList(LosVmPhysSeg *physSeg, int nScan, LOS_DL_LIST *list) } #ifdef LOSCFG_FS_VFS -int OsTryShrinkMemory(size_t nPage) +int OsTryShrinkMemory(size_t nPage)//尝试收缩文件页 { UINT32 intSave; size_t totalPages; size_t nReclaimed = 0; LosVmPhysSeg *physSeg = NULL; UINT32 index; - LOS_DL_LIST_HEAD(dirtyList); + LOS_DL_LIST_HEAD(dirtyList);//初始化脏页链表,上面将挂所有脏页用于同步到磁盘后回收 LosFilePage *fpage = NULL; LosFilePage *fnext = NULL; if (nPage == 0) { - nPage = VM_FILEMAP_MIN_SCAN; + nPage = VM_FILEMAP_MIN_SCAN;// } if (nPage > VM_FILEMAP_MAX_SCAN) { nPage = VM_FILEMAP_MAX_SCAN; } - for (index = 0; index < g_vmPhysSegNum; index++) { - physSeg = &g_vmPhysSeg[index]; + for (index = 0; index < g_vmPhysSegNum; index++) {//遍历整个物理段组 + physSeg = &g_vmPhysSeg[index];//一段段来 LOS_SpinLockSave(&physSeg->lruLock, &intSave); - totalPages = physSeg->lruSize[VM_LRU_ACTIVE_FILE] + physSeg->lruSize[VM_LRU_INACTIVE_FILE]; - if (totalPages < VM_FILEMAP_MIN_SCAN) { + totalPages = physSeg->lruSize[VM_LRU_ACTIVE_FILE] + physSeg->lruSize[VM_LRU_INACTIVE_FILE];//统计所有文件页 + if (totalPages < VM_FILEMAP_MIN_SCAN) {//文件页占用内存不多的情况下,怎么处理? LOS_SpinUnlockRestore(&physSeg->lruLock, intSave); - continue; + continue;//放过这一段,找下一段 } if (OsInactiveListIsLow(physSeg)) { - OsShrinkActiveList(physSeg, (nPage < VM_FILEMAP_MIN_SCAN) ? VM_FILEMAP_MIN_SCAN : nPage); + OsShrinkActiveList(physSeg, (nPage < VM_FILEMAP_MIN_SCAN) ? VM_FILEMAP_MIN_SCAN : nPage);//缩小活动页 } - nReclaimed += OsShrinkInactiveList(physSeg, nPage, &dirtyList); + nReclaimed += OsShrinkInactiveList(physSeg, nPage, &dirtyList);//缩小未活动页,带出脏页链表 LOS_SpinUnlockRestore(&physSeg->lruLock, intSave); - if (nReclaimed >= nPage) { - break; + if (nReclaimed >= nPage) {//够了,够了,达到目的了. + break;//退出收缩 } } - LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(fpage, fnext, &dirtyList, LosFilePage, node) { - OsDoFlushDirtyPage(fpage); + LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(fpage, fnext, &dirtyList, LosFilePage, node) {//遍历处理脏页数据 + OsDoFlushDirtyPage(fpage);//冲洗脏页数据,将脏页数据回写磁盘 } return nReclaimed; @@ -340,4 +344,4 @@ int OsTryShrinkMemory(size_t nPage) #endif #endif -#endif +#endif \ No newline at end of file diff --git a/src/kernel_liteos_a/kernel/base/vm/los_vm_syscall.c b/src/kernel_liteos_a/kernel/base/vm/los_vm_syscall.c index 6aa23993..72bdd10b 100644 --- a/src/kernel_liteos_a/kernel/base/vm/los_vm_syscall.c +++ b/src/kernel_liteos_a/kernel/base/vm/los_vm_syscall.c @@ -65,7 +65,7 @@ STATUS_T OsCheckMMapParams(VADDR_T *vaddr, unsigned long flags, size_t len, unsi return -EINVAL; } - if ((flags & MAP_SUPPORT_MASK) == 0) { + if ((flags & MAP_SUPPORT_MASK) == 0) {//映射权限限制 return -EINVAL; } if (((flags & MAP_SHARED_PRIVATE) == 0) || ((flags & MAP_SHARED_PRIVATE) == MAP_SHARED_PRIVATE)) { @@ -95,20 +95,54 @@ STATUS_T OsNamedMmapingPermCheck(struct file *filep, unsigned long flags, unsign return LOS_OK; } - +///匿名映射 STATUS_T OsAnonMMap(LosVmMapRegion *region) { LOS_SetRegionTypeAnon(region); return LOS_OK; } +/** + mmap基础概念: + 一种内存映射文件的方法,即将一个文件或者其它对象映射到进程的地址空间,实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系. + 实现这样的映射关系后,进程就可以采用指针的方式读写操作这一段内存,而系统会自动回写脏页面到对应的文件磁盘上, + 即完成了对文件的操作而不必再调用read,write等系统调用函数。相反,内核空间对这段区域的修改也直接反映用户空间, + 从而可以实现不同进程间的文件共享。 + + https://www.cnblogs.com/huxiao-tee/p/4660352.html + http://abcdxyzk.github.io/blog/2015/09/11/kernel-mm-mmap/ + + 参数 描述 + addr 指向欲映射的内存起始地址,通常设为 NULL,代表让系统自动选定地址,映射成功后返回该地址。 + length 代表将文件中多大的部分映射到内存。 + prot 用于设置内存段的访问权限,有如下权限: + PROT_EXEC 映射区域可被执行 + PROT_READ 映射区域可被读取 + PROT_WRITE 映射区域可被写入 + PROT_NONE 映射区域不能存取 + + flags 控制程序对内存段的改变所造成的影响,有如下属性: + MAP_FIXED 如果参数start所指的地址无法成功建立映射时,则放弃映射,不对地址做修正。通常不鼓励用此旗标。 + MAP_SHARED 对映射区域的写入数据会复制回文件内,而且允许其他映射该文件的进程共享。 + MAP_PRIVATE 对映射区域的写入操作会产生一个映射文件的复制,即私人的“写入时复制”(copy on write)对此区域作的任何修改都不会写回原来的文件内容。 + MAP_ANONYMOUS建立匿名映射。此时会忽略参数fd,不涉及文件,而且映射区域无法和其他进程共享。 + MAP_DENYWRITE只允许对映射区域的写入操作,其他对文件直接写入的操作将会被拒绝。 + MAP_LOCKED 将映射区域锁定住,这表示该区域不会被置换(swap)。 + + fd: 要映射到内存中的文件描述符。如果使用匿名内存映射时,即flags中设置了MAP_ANONYMOUS,fd设为-1。 + 有些系统不支持匿名内存映射,则可以使用fopen打开/dev/zero文件,然后对该文件进行映射,可以同样达到匿名内存映射的效果。 + + offset 文件映射的偏移量,通常设置为0,代表从文件最前方开始对应,offset必须是PAGE_SIZE的整数倍。 + 成功返回:虚拟内存地址,这地址是页对齐。 + 失败返回:(void *)-1。 + */ VADDR_T LOS_MMap(VADDR_T vaddr, size_t len, unsigned prot, unsigned long flags, int fd, unsigned long pgoff) { STATUS_T status; VADDR_T resultVaddr; UINT32 regionFlags; - LosVmMapRegion *newRegion = NULL; - struct file *filep = NULL; + LosVmMapRegion *newRegion = NULL;//应用的内存分配对应到内核就是分配一个线性区 + struct file *filep = NULL;// inode : file = 1:N ,一对多关系,一个inode可以被多个进程打开,返回不同的file但都指向同一个inode LosVmSpace *vmSpace = OsCurrProcessGet()->vmSpace; len = ROUNDUP(len, PAGE_SIZE); @@ -116,9 +150,9 @@ VADDR_T LOS_MMap(VADDR_T vaddr, size_t len, unsigned prot, unsigned long flags, if (checkRst != LOS_OK) { return checkRst; } - - if (LOS_IsNamedMapping(flags)) { - status = fs_getfilep(fd, &filep); + + if (LOS_IsNamedMapping(flags)) {//是否文件映射 + status = fs_getfilep(fd, &filep);//获取文件描述符和状态 if (status < 0) { return -EBADF; } @@ -131,30 +165,30 @@ VADDR_T LOS_MMap(VADDR_T vaddr, size_t len, unsigned prot, unsigned long flags, (VOID)LOS_MuxAcquire(&vmSpace->regionMux); /* user mode calls mmap to release heap physical memory without releasing heap virtual space */ - status = OsUserHeapFree(vmSpace, vaddr, len); - if (status == LOS_OK) { + status = OsUserHeapFree(vmSpace, vaddr, len);//用户模式释放堆物理内存而不释放堆虚拟空间 + if (status == LOS_OK) {//OsUserHeapFree 干两件事 1.解除映射关系 2.释放物理页 resultVaddr = vaddr; goto MMAP_DONE; } - - regionFlags = OsCvtProtFlagsToRegionFlags(prot, flags); - newRegion = LOS_RegionAlloc(vmSpace, vaddr, len, regionFlags, pgoff); + //地址不在堆区 + regionFlags = OsCvtProtFlagsToRegionFlags(prot, flags);//将参数flag转换Region的flag + newRegion = LOS_RegionAlloc(vmSpace, vaddr, len, regionFlags, pgoff);//分配一个线性区 if (newRegion == NULL) { - resultVaddr = (VADDR_T)-ENOMEM; + resultVaddr = (VADDR_T)-ENOMEM;//ENOMEM:内存溢出 goto MMAP_DONE; } newRegion->regionFlags |= VM_MAP_REGION_FLAG_MMAP; - resultVaddr = newRegion->range.base; + resultVaddr = newRegion->range.base;//线性区基地址为分配的地址 if (LOS_IsNamedMapping(flags)) { - status = OsNamedMMap(filep, newRegion); + status = OsNamedMMap(filep, newRegion);//文件映射 } else { - status = OsAnonMMap(newRegion); + status = OsAnonMMap(newRegion);//匿名映射 } if (status != LOS_OK) { - LOS_RbDelNode(&vmSpace->regionRbTree, &newRegion->rbNode); - LOS_RegionFree(vmSpace, newRegion); + LOS_RbDelNode(&vmSpace->regionRbTree, &newRegion->rbNode);//从红黑树和双循环链表中删除 + LOS_RegionFree(vmSpace, newRegion);//释放 resultVaddr = (VADDR_T)-ENOMEM; goto MMAP_DONE; } @@ -163,7 +197,7 @@ MMAP_DONE: (VOID)LOS_MuxRelease(&vmSpace->regionMux); return resultVaddr; } - +///解除映射关系 STATUS_T LOS_UnMMap(VADDR_T addr, size_t size) { if ((addr <= 0) || (size == 0)) { @@ -172,7 +206,6 @@ STATUS_T LOS_UnMMap(VADDR_T addr, size_t size) return OsUnMMap(OsCurrProcessGet()->vmSpace, addr, size); } - STATIC INLINE BOOL OsProtMprotectPermCheck(unsigned long prot, LosVmMapRegion *region) { UINT32 protFlags = 0; @@ -186,20 +219,28 @@ STATIC INLINE BOOL OsProtMprotectPermCheck(unsigned long prot, LosVmMapRegion *r return ((protFlags & permFlags) == protFlags); } - +/// 收缩堆区 VOID *OsShrinkHeap(VOID *addr, LosVmSpace *space) { VADDR_T newBrk, oldBrk; - newBrk = LOS_Align((VADDR_T)(UINTPTR)addr, PAGE_SIZE); - oldBrk = LOS_Align(space->heapNow, PAGE_SIZE); - if (LOS_UnMMap(newBrk, (oldBrk - newBrk)) < 0) { - return (void *)(UINTPTR)space->heapNow; + newBrk = LOS_Align((VADDR_T)(UINTPTR)addr, PAGE_SIZE);//新堆顶 + oldBrk = LOS_Align(space->heapNow, PAGE_SIZE);//旧堆顶 + if (LOS_UnMMap(newBrk, (oldBrk - newBrk)) < 0) {//解除相差区的映射 + return (void *)(UINTPTR)space->heapNow;//解除失败就持续现有的 } - space->heapNow = (VADDR_T)(UINTPTR)addr; + space->heapNow = (VADDR_T)(UINTPTR)addr;//返回新堆顶 return addr; } +/** + 用户进程向内核申请空间,进一步说用于扩展用户堆栈空间,或者回收用户堆栈空间 + 扩展当前进程的堆空间 + 一个进程所有的线性区都在进程指定的线性地址范围内, + 线性区之间是不会有地址的重叠的,开始都是连续的,随着进程的运行出现了释放再分配的情况 + 由此出现了断断续续的线性区,内核回收线性区时会检测是否和周边的线性区可合并成一个更大 + 的线性区用于分配。 + */ VOID *LOS_DoBrk(VOID *addr) { LosVmSpace *space = OsCurrProcessGet()->vmSpace; @@ -209,60 +250,60 @@ VOID *LOS_DoBrk(VOID *addr) VOID *alignAddr = NULL; VOID *shrinkAddr = NULL; - if (addr == NULL) { - return (void *)(UINTPTR)space->heapNow; + if (addr == NULL) {//参数地址未传情况 + return (void *)(UINTPTR)space->heapNow;//以现有指向地址为基础进行扩展 } - if ((UINTPTR)addr < (UINTPTR)space->heapBase) { + if ((UINTPTR)addr < (UINTPTR)space->heapBase) {//heapBase是堆区的开始地址,所以参数地址不能低于它 return (VOID *)-ENOMEM; } - size = (UINTPTR)addr - (UINTPTR)space->heapBase; - size = ROUNDUP(size, PAGE_SIZE); - alignAddr = (CHAR *)(UINTPTR)(space->heapBase) + size; + size = (UINTPTR)addr - (UINTPTR)space->heapBase;//算出大小 + size = ROUNDUP(size, PAGE_SIZE); //圆整size + alignAddr = (CHAR *)(UINTPTR)(space->heapBase) + size;//得到新的线性区的结束地址 PRINT_INFO("brk addr %p , size 0x%x, alignAddr %p, align %d\n", addr, size, alignAddr, PAGE_SIZE); (VOID)LOS_MuxAcquire(&space->regionMux); - if (addr < (VOID *)(UINTPTR)space->heapNow) { - shrinkAddr = OsShrinkHeap(addr, space); + if (addr < (VOID *)(UINTPTR)space->heapNow) {//如果地址小于堆区现地址 + shrinkAddr = OsShrinkHeap(addr, space);//收缩堆区 (VOID)LOS_MuxRelease(&space->regionMux); return shrinkAddr; } - if ((UINTPTR)alignAddr >= space->mapBase) { - VM_ERR("Process heap memory space is insufficient"); + if ((UINTPTR)alignAddr >= space->mapBase) {//参数地址 大于映射区地址 + VM_ERR("Process heap memory space is insufficient");//进程堆空间不足 ret = (VOID *)-ENOMEM; goto REGION_ALLOC_FAILED; } - if (space->heapBase == space->heapNow) { - region = LOS_RegionAlloc(space, space->heapBase, size, - VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE | + if (space->heapBase == space->heapNow) {//往往是第一次调用本函数才会出现,因为初始化时 heapBase = heapNow + region = LOS_RegionAlloc(space, space->heapBase, size,//分配一个可读/可写/可使用的线性区,只需分配一次 + VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE |//线性区的大小由range.size决定 VM_MAP_REGION_FLAG_FIXED | VM_MAP_REGION_FLAG_PERM_USER, 0); if (region == NULL) { ret = (VOID *)-ENOMEM; VM_ERR("LOS_RegionAlloc failed"); goto REGION_ALLOC_FAILED; } - region->regionFlags |= VM_MAP_REGION_FLAG_HEAP; - space->heap = region; + region->regionFlags |= VM_MAP_REGION_FLAG_HEAP;//贴上线性区类型为堆区的标签,注意一个线性区可以有多种标签 + space->heap = region;//指定线性区为堆区 } - space->heapNow = (VADDR_T)(UINTPTR)alignAddr; - space->heap->range.size = size; - ret = (VOID *)(UINTPTR)space->heapNow; + space->heapNow = (VADDR_T)(UINTPTR)alignAddr;//更新堆区顶部位置 + space->heap->range.size = size; //更新堆区大小,经此操作线性区变大或缩小了 + ret = (VOID *)(UINTPTR)space->heapNow;//返回堆顶 REGION_ALLOC_FAILED: (VOID)LOS_MuxRelease(&space->regionMux); return ret; } - +/// 继承老线性区的标签 STATIC UINT32 OsInheritOldRegionName(UINT32 oldRegionFlags) { UINT32 vmFlags = 0; - if (oldRegionFlags & VM_MAP_REGION_FLAG_HEAP) { - vmFlags |= VM_MAP_REGION_FLAG_HEAP; + if (oldRegionFlags & VM_MAP_REGION_FLAG_HEAP) { //如果是从大堆区中申请的 + vmFlags |= VM_MAP_REGION_FLAG_HEAP; //线性区则贴上堆区标签 } else if (oldRegionFlags & VM_MAP_REGION_FLAG_STACK) { vmFlags |= VM_MAP_REGION_FLAG_STACK; } else if (oldRegionFlags & VM_MAP_REGION_FLAG_TEXT) { @@ -277,7 +318,7 @@ STATIC UINT32 OsInheritOldRegionName(UINT32 oldRegionFlags) return vmFlags; } - +///修改内存段的访问权限 INT32 LOS_DoMprotect(VADDR_T vaddr, size_t len, unsigned long prot) { LosVmSpace *space = OsCurrProcessGet()->vmSpace; @@ -287,7 +328,7 @@ INT32 LOS_DoMprotect(VADDR_T vaddr, size_t len, unsigned long prot) int ret; (VOID)LOS_MuxAcquire(&space->regionMux); - region = LOS_RegionFind(space, vaddr); + region = LOS_RegionFind(space, vaddr);//通过虚拟地址找到线性区 if (!IS_ALIGNED(vaddr, PAGE_SIZE) || (region == NULL) || (vaddr > vaddr + len)) { ret = -EINVAL; goto OUT_MPROTECT; @@ -297,19 +338,18 @@ INT32 LOS_DoMprotect(VADDR_T vaddr, size_t len, unsigned long prot) ret = -EINVAL; goto OUT_MPROTECT; } - + //如果是堆区或VDSO区,说明区内容是不能修改的 if ((region->regionFlags & VM_MAP_REGION_FLAG_VDSO) || (region->regionFlags & VM_MAP_REGION_FLAG_HEAP)) { ret = -EPERM; goto OUT_MPROTECT; } - + //如果是共享文件,说明内容也不能修改 if (LOS_IsRegionTypeFile(region) && (region->regionFlags & VM_MAP_REGION_FLAG_SHARED)) { if (!OsProtMprotectPermCheck(prot, region)) { ret = -EACCES; goto OUT_MPROTECT; } } - len = LOS_Align(len, PAGE_SIZE); /* can't operation cross region */ if ((region->range.base + region->range.size) < (vaddr + len)) { @@ -318,11 +358,11 @@ INT32 LOS_DoMprotect(VADDR_T vaddr, size_t len, unsigned long prot) } /* if only move some part of region, we need to split first */ - if (region->range.size > len) { - OsVmRegionAdjust(space, vaddr, len); + if (region->range.size > len) {//如果只修改部分区域,我们需要先拆分区 + OsVmRegionAdjust(space, vaddr, len);//调整下线性区范围 } - vmFlags = OsCvtProtFlagsToRegionFlags(prot, 0); + vmFlags = OsCvtProtFlagsToRegionFlags(prot, 0);//转换FLAGS vmFlags |= (region->regionFlags & VM_MAP_REGION_FLAG_SHARED) ? VM_MAP_REGION_FLAG_SHARED : 0; vmFlags |= OsInheritOldRegionName(region->regionFlags); region = LOS_RegionFind(space, vaddr); @@ -332,7 +372,7 @@ INT32 LOS_DoMprotect(VADDR_T vaddr, size_t len, unsigned long prot) } region->regionFlags = vmFlags; count = len >> PAGE_SHIFT; - ret = LOS_ArchMmuChangeProt(&space->archMmu, vaddr, count, region->regionFlags); + ret = LOS_ArchMmuChangeProt(&space->archMmu, vaddr, count, region->regionFlags);//修改访问权限实体函数 if (ret) { ret = -ENOMEM; goto OUT_MPROTECT; @@ -387,7 +427,7 @@ STATUS_T OsMremapCheck(VADDR_T addr, size_t oldLen, VADDR_T newAddr, size_t newL } } - /* avoid new region overlapping with the old one */ + /* avoid new region overlaping with the old one */ if (flags & MREMAP_FIXED) { if (((region->range.base + region->range.size) > newAddr) && (region->range.base < (newAddr + newLen))) { @@ -401,7 +441,7 @@ STATUS_T OsMremapCheck(VADDR_T addr, size_t oldLen, VADDR_T newAddr, size_t newL return LOS_OK; } - +///重新映射虚拟内存地址。 VADDR_T LOS_DoMremap(VADDR_T oldAddress, size_t oldSize, size_t newSize, int flags, VADDR_T newAddr) { LosVmMapRegion *regionOld = NULL; @@ -496,7 +536,7 @@ OUT_MREMAP: (VOID)LOS_MuxRelease(&space->regionMux); return ret; } - +///输出内存线性区 VOID LOS_DumpMemRegion(VADDR_T vaddr) { LosVmSpace *space = NULL; @@ -506,12 +546,11 @@ VOID LOS_DumpMemRegion(VADDR_T vaddr) return; } - if (LOS_IsRangeInSpace(space, ROUNDDOWN(vaddr, MB), MB) == FALSE) { + if (LOS_IsRangeInSpace(space, ROUNDDOWN(vaddr, MB), MB) == FALSE) {//是否在空间范围内 return; } - OsDumpPte(vaddr); - OsDumpAspace(space); + OsDumpPte(vaddr);//dump L1 L2 + OsDumpAspace(space);//dump 空间 } -#endif - +#endif \ No newline at end of file diff --git a/src/kernel_liteos_a/kernel/base/vm/oom.c b/src/kernel_liteos_a/kernel/base/vm/oom.c index 72996781..60d80128 100644 --- a/src/kernel_liteos_a/kernel/base/vm/oom.c +++ b/src/kernel_liteos_a/kernel/base/vm/oom.c @@ -47,8 +47,8 @@ #ifdef LOSCFG_KERNEL_VM -LITE_OS_SEC_BSS OomCB *g_oomCB = NULL; -static SPIN_LOCK_INIT(g_oomSpinLock); +LITE_OS_SEC_BSS OomCB *g_oomCB = NULL; //全局内存溢出控制块 +static SPIN_LOCK_INIT(g_oomSpinLock);//内存溢出自旋锁 LITE_OS_SEC_TEXT_MINOR STATIC UINT32 OomScoreProcess(LosProcessCB *candidateProcess) { @@ -57,20 +57,20 @@ LITE_OS_SEC_TEXT_MINOR STATIC UINT32 OomScoreProcess(LosProcessCB *candidateProc #ifndef LOSCFG_KERNEL_SMP (VOID)LOS_MuxAcquire(&candidateProcess->vmSpace->regionMux); #endif - /* we only consider actual physical memory here. */ + /* we only consider actual physical memory here. */ //只考虑实际的物理内存 OsUProcessPmUsage(candidateProcess->vmSpace, NULL, &actualPm); #ifndef LOSCFG_KERNEL_SMP (VOID)LOS_MuxRelease(&candidateProcess->vmSpace->regionMux); #endif return actualPm; } - +///用于设置 g_oomCB->processVictimCB 回调函数 LITE_OS_SEC_TEXT_MINOR STATIC UINT32 OomKillProcess(UINTPTR param) { /* we will not kill process, and do nothing here */ return LOS_OK; } - +///强制收缩内存 LITE_OS_SEC_TEXT_MINOR STATIC UINT32 OomForceShrinkMemory(VOID) { UINT32 i; @@ -80,13 +80,14 @@ LITE_OS_SEC_TEXT_MINOR STATIC UINT32 OomForceShrinkMemory(VOID) * TryShrinkMemory maybe reclaim 0 pages in the first time from active list * to inactive list, and in the second time reclaim memory from inactive list. */ + //TryShrinkMemory可能会在第一时间从活动列表中回收0页到非活动列表,并在第二次从非活动列表中回收内存。 for (i = 0; i < MAX_SHRINK_PAGECACHE_TRY; i++) { reclaimMemPages += OsTryShrinkMemory(0); } return reclaimMemPages; } - +///内存不足时回收页高速缓存 LITE_OS_SEC_TEXT_MINOR STATIC BOOL OomReclaimPageCache(VOID) { UINT32 totalPm = 0; @@ -96,43 +97,44 @@ LITE_OS_SEC_TEXT_MINOR STATIC BOOL OomReclaimPageCache(VOID) UINT32 i; for (i = 0; i < MAX_SHRINK_PAGECACHE_TRY; i++) { - OsVmPhysUsedInfoGet(&usedPm, &totalPm); - isReclaimMemory = ((totalPm - usedPm) << PAGE_SHIFT) < g_oomCB->reclaimMemThreshold; - if (isReclaimMemory) { + OsVmPhysUsedInfoGet(&usedPm, &totalPm);//获取总的和已经使用的物理内存数量 + isReclaimMemory = ((totalPm - usedPm) << PAGE_SHIFT) < g_oomCB->reclaimMemThreshold;//检查是否过了回收门槛 + if (isReclaimMemory) {//要回收了 /* * we do force memory reclaim from page cache here. * if we get memory, we will reclaim pagecache memory again. * if there is no memory to reclaim, we will return. */ - reclaimMemPages = OomForceShrinkMemory(); - if (reclaimMemPages > 0) { + //在这里强制从页缓存中回收内存, + reclaimMemPages = OomForceShrinkMemory();//强制回收内存 + if (reclaimMemPages > 0) {//如果得到内存,将再次回收pagecache内存 continue; } } - break; + break;//实在没有内存可回收 } - return isReclaimMemory; + return isReclaimMemory;//返回回收的数量 } /* - * check is low memory or not, if low memory, try to kill process. - * return is kill process or not. + * check is low memory or not, if low memory, try to kill process. + * return is kill process or not. */ -LITE_OS_SEC_TEXT_MINOR BOOL OomCheckProcess(VOID) +LITE_OS_SEC_TEXT_MINOR BOOL OomCheckProcess(VOID)//检查内存是否不足,如果内存不足,请尝试终止进程,返回是否kill进程 { UINT32 totalPm; UINT32 usedPm; BOOL isLowMemory = FALSE; /* - * spinlock the current core schedule, make sure oom process atomic - * spinlock other place entering OomCheckProcess, make sure oom process mutex + * spinlock the current core schedule, make sure oom process atomic //旋转锁定当前核心计划,确保oom进程原子化 + * spinlock other place entering OomCheckProcess, make sure oom process mutex //旋转锁定其他进入OomCheckProcess的地方,确保oom进程互斥 */ LOS_SpinLock(&g_oomSpinLock); /* first we will check if we need to reclaim pagecache memory */ - if (OomReclaimPageCache() == FALSE) { + if (OomReclaimPageCache() == FALSE) {// LOS_SpinUnlock(&g_oomSpinLock); goto NO_VICTIM_PROCESS; } @@ -140,9 +142,7 @@ LITE_OS_SEC_TEXT_MINOR BOOL OomCheckProcess(VOID) /* get free bytes */ OsVmPhysUsedInfoGet(&usedPm, &totalPm); isLowMemory = ((totalPm - usedPm) << PAGE_SHIFT) < g_oomCB->lowMemThreshold; - LOS_SpinUnlock(&g_oomSpinLock); - if (isLowMemory) { PRINTK("[oom] OS is in low memory state\n" "total physical memory: %#x(byte), used: %#x(byte)," @@ -155,14 +155,14 @@ NO_VICTIM_PROCESS: return isLowMemory; } -#ifdef LOSCFG_ENABLE_OOM_LOOP_TASK -STATIC VOID OomWriteEvent(VOID) +#ifdef LOSCFG_ENABLE_OOM_LOOP_TASK //内存溢出监测任务开关 +STATIC VOID OomWriteEvent(VOID) // OomTaskInit中创建的定时器回调 { - OsWriteResourceEvent(OS_RESOURCE_EVENT_OOM); + OsWriteResourceEvent(OS_RESOURCE_EVENT_OOM);//广播内存溢出事件 } #endif - -LITE_OS_SEC_TEXT_MINOR VOID OomInfodump(VOID) +//打印内存不足时的信息 +LITE_OS_SEC_TEXT_MINOR VOID OomInfodump(VOID) //打印内存溢出信息 { PRINTK("[oom] oom loop task status: %s\n" " oom low memory threshold: %#x(byte)\n" @@ -172,7 +172,7 @@ LITE_OS_SEC_TEXT_MINOR VOID OomInfodump(VOID) g_oomCB->lowMemThreshold, g_oomCB->reclaimMemThreshold, g_oomCB->checkInterval); } - +///设置低内存门槛 LITE_OS_SEC_TEXT_MINOR VOID OomSetLowMemThreashold(UINT32 lowMemThreshold) { if ((lowMemThreshold > OOM_DEFAULT_LOW_MEM_THRESHOLD_MAX)) { @@ -186,7 +186,7 @@ LITE_OS_SEC_TEXT_MINOR VOID OomSetLowMemThreashold(UINT32 lowMemThreshold) g_oomCB->lowMemThreshold); } } - +///设置回收内存的门槛 LITE_OS_SEC_TEXT_MINOR VOID OomSetReclaimMemThreashold(UINT32 reclaimMemThreshold) { UINT32 totalPm = 0; @@ -204,7 +204,7 @@ LITE_OS_SEC_TEXT_MINOR VOID OomSetReclaimMemThreashold(UINT32 reclaimMemThreshol g_oomCB->reclaimMemThreshold); } } - +///设置监控间隔 LITE_OS_SEC_TEXT_MINOR VOID OomSetCheckInterval(UINT32 checkInterval) { if ((checkInterval >= OOM_CHECK_MIN) && (checkInterval <= OOM_CHECK_MAX)) { @@ -216,7 +216,7 @@ LITE_OS_SEC_TEXT_MINOR VOID OomSetCheckInterval(UINT32 checkInterval) g_oomCB->checkInterval, OOM_CHECK_MIN, OOM_CHECK_MAX); } } - +///内存不足监控任务初始化, OOM 通过开一个软件定时器来检查内存的使用情况 LITE_OS_SEC_TEXT_MINOR UINT32 OomTaskInit(VOID) { g_oomCB = (OomCB *)LOS_MemAlloc(m_aucSysMem0, sizeof(OomCB)); @@ -225,28 +225,27 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OomTaskInit(VOID) return LOS_NOK; } - g_oomCB->lowMemThreshold = OOM_DEFAULT_LOW_MEM_THRESHOLD; - g_oomCB->reclaimMemThreshold = OOM_DEFAULT_RECLAIM_MEM_THRESHOLD; - g_oomCB->checkInterval = OOM_DEFAULT_CHECK_INTERVAL; - g_oomCB->processVictimCB = (OomFn)OomKillProcess; - g_oomCB->scoreCB = (OomFn)OomScoreProcess; - g_oomCB->enabled = FALSE; + g_oomCB->lowMemThreshold = OOM_DEFAULT_LOW_MEM_THRESHOLD; //运行任务的门槛 + g_oomCB->reclaimMemThreshold = OOM_DEFAULT_RECLAIM_MEM_THRESHOLD; //回收内存的门槛 + g_oomCB->checkInterval = OOM_DEFAULT_CHECK_INTERVAL; //检测时间间隔 1S + g_oomCB->processVictimCB = (OomFn)OomKillProcess; //出问题时对进程的处理函数 + g_oomCB->scoreCB = (OomFn)OomScoreProcess; //统计进程占用的物理内存 + g_oomCB->enabled = FALSE; //是否启用监控 -#ifdef LOSCFG_ENABLE_OOM_LOOP_TASK +#ifdef LOSCFG_ENABLE_OOM_LOOP_TASK //内存溢出检测开关 g_oomCB->enabled = TRUE; UINT32 ret = LOS_SwtmrCreate(g_oomCB->checkInterval, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)OomWriteEvent, - &g_oomCB->swtmrID, (UINTPTR)g_oomCB); + &g_oomCB->swtmrID, (UINTPTR)g_oomCB);//创建检测定时器 if (ret != LOS_OK) { return ret; } - return LOS_SwtmrStart(g_oomCB->swtmrID); + return LOS_SwtmrStart(g_oomCB->swtmrID);//启动定时器 #else return LOS_OK; #endif } -LOS_MODULE_INIT(OomTaskInit, LOS_INIT_LEVEL_KMOD_TASK); - -#endif +LOS_MODULE_INIT(OomTaskInit, LOS_INIT_LEVEL_KMOD_TASK);//初始化内存监控模块 +#endif \ No newline at end of file diff --git a/src/kernel_liteos_a/kernel/base/vm/shm.c b/src/kernel_liteos_a/kernel/base/vm/shm.c index 637c6167..a61cb0f4 100644 --- a/src/kernel_liteos_a/kernel/base/vm/shm.c +++ b/src/kernel_liteos_a/kernel/base/vm/shm.c @@ -1,3 +1,17 @@ +/*! + 什么是共享内存 + 顾名思义,共享内存就是允许两个不相关的进程访问同一个物理内存。共享内存是在两个正在运行的进程之间 + 共享和传递数据的一种非常有效的方式。不同进程之间共享的内存通常安排为同一段物理内存。进程可以将同 + 一段共享内存连接到它们自己的地址空间中,所有进程都可以访问共享内存中的地址,就好像它们是由用C语言 + 函数malloc()分配的内存一样。而如果某个进程向共享内存写入数据,所做的改动将立即影响到可以访问同一段 + 共享内存的任何其他进程。 + + 特别提醒:共享内存并未提供同步机制,也就是说,在第一个进程结束对共享内存的写操作之前,并无自动机制 + 可以阻止第二个进程开始对它进行读取。所以我们通常需要用其他的机制来同步对共享内存的访问 + + 共享线性区可以由任意的进程创建,每个使用共享线性区都必须经过映射. + */ + /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. @@ -55,9 +69,9 @@ #ifdef LOSCFG_KERNEL_SHM -#define SHM_SEG_FREE 0x2000 -#define SHM_SEG_USED 0x4000 -#define SHM_SEG_REMOVE 0x8000 +#define SHM_SEG_FREE 0x2000 //空闲未使用 +#define SHM_SEG_USED 0x4000 //已使用 +#define SHM_SEG_REMOVE 0x8000 //删除 #ifndef SHM_M #define SHM_M 010000 @@ -66,21 +80,17 @@ #ifndef SHM_X #define SHM_X 0100 #endif - #ifndef ACCESSPERMS -#define ACCESSPERMS (S_IRWXU | S_IRWXG | S_IRWXO) -#endif +#define ACCESSPERMS (S_IRWXU | S_IRWXG | S_IRWXO)//文件权限值意思就是 用户,用户组,其他可读可写. +#endif //代表含义U:user G:group O:other #define SHM_S_IRUGO (S_IRUSR | S_IRGRP | S_IROTH) #define SHM_S_IWUGO (S_IWUSR | S_IWGRP | S_IWOTH) #define SHM_S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH) - #define SHM_GROUPE_TO_USER 3 #define SHM_OTHER_TO_USER 6 - #ifndef LOSCFG_IPC_CONTAINER STATIC LosMux g_sysvShmMux; - /* private data */ STATIC struct shminfo g_shmInfo; STATIC struct shmIDSource *g_shmSegs = NULL; @@ -96,6 +106,60 @@ STATIC UINT32 g_shmUsedPageCount; #define SYSV_SHM_LOCK() (VOID)LOS_MuxLock(&IPC_SHM_SYS_VSHM_MUTEX, LOS_WAIT_FOREVER) #define SYSV_SHM_UNLOCK() (VOID)LOS_MuxUnlock(&IPC_SHM_SYS_VSHM_MUTEX) +#if 0 // @note_#if0 + +//内核为每一个IPC对象保存一个ipc_perm结构体,该结构说明了IPC对象的权限和所有者 +struct ipc_perm { + key_t __ipc_perm_key; //调用shmget()时给出的关键字 + uid_t uid; //共享内存所有者的有效用户ID + gid_t gid; //共享内存所有者所属组的有效组ID + uid_t cuid; //共享内存创建 者的有效用户ID + gid_t cgid; //共享内存创建者所属组的有效组ID + mode_t mode; //权限 + SHM_DEST / SHM_LOCKED /SHM_HUGETLB 标志位 + int __ipc_perm_seq; //序列号 + long __pad1; //保留扩展用 + long __pad2; +}; +//每个共享内存段在内核中维护着一个内部结构shmid_ds +struct shmid_ds { + struct ipc_perm shm_perm;///< 操作许可,里面包含共享内存的用户ID、组ID等信息 + size_t shm_segsz; ///< 共享内存段的大小,单位为字节 + time_t shm_atime; ///< 最后一个进程访问共享内存的时间 + time_t shm_dtime; ///< 最后一个进程离开共享内存的时间 + time_t shm_ctime; ///< 创建时间 + pid_t shm_cpid; ///< 创建共享内存的进程ID + pid_t shm_lpid; ///< 最后操作共享内存的进程ID + unsigned long shm_nattch; ///< 当前使用该共享内存段的进程数量 + unsigned long __pad1; //保留扩展用 + unsigned long __pad2; +}; +// 共享内存模块设置信息 +struct shminfo { + unsigned long shmmax, shmmin, shmmni, shmseg, shmall, __unused[4]; +}; +struct shmIDSource {//共享内存描述符 + struct shmid_ds ds; //是内核为每一个共享内存段维护的数据结构 + UINT32 status; //状态 SHM_SEG_FREE ... + LOS_DL_LIST node; //节点,挂VmPage +#ifdef LOSCFG_SHELL + CHAR ownerName[OS_PCB_NAME_LEN]; +#endif +}; + +/* private data */ +STATIC struct shminfo g_shmInfo = { //描述共享内存范围的全局变量 + .shmmax = SHM_MAX,//共享内存单个上限 4096页 即 16M + .shmmin = SHM_MIN,//共享内存单个下限 1页 即:4K + .shmmni = SHM_MNI,//共享内存总数 默认192 + .shmseg = SHM_SEG,//每个用户进程可以使用的最多的共享内存段的数目 128 + .shmall = SHM_ALL,//系统范围内共享内存的总页数, 4096页 +}; + +STATIC struct shmIDSource *g_shmSegs = NULL; +STATIC UINT32 g_shmUsedPageCount; +#endif + +//共享内存初始化 struct shmIDSource *OsShmCBInit(LosMux *sysvShmMux, struct shminfo *shmInfo, UINT32 *shmUsedPageCount) { UINT32 ret; @@ -104,7 +168,6 @@ struct shmIDSource *OsShmCBInit(LosMux *sysvShmMux, struct shminfo *shmInfo, UIN if ((sysvShmMux == NULL) || (shmInfo == NULL) || (shmUsedPageCount == NULL)) { return NULL; } - ret = LOS_MuxInit(sysvShmMux, NULL); if (ret != LOS_OK) { goto ERROR; @@ -115,7 +178,6 @@ struct shmIDSource *OsShmCBInit(LosMux *sysvShmMux, struct shminfo *shmInfo, UIN shmInfo->shmmni = SHM_MNI; shmInfo->shmseg = SHM_SEG; shmInfo->shmall = SHM_ALL; - struct shmIDSource *shmSegs = LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, sizeof(struct shmIDSource) * shmInfo->shmmni); if (shmSegs == NULL) { (VOID)LOS_MuxDestroy(sysvShmMux); @@ -125,9 +187,9 @@ struct shmIDSource *OsShmCBInit(LosMux *sysvShmMux, struct shminfo *shmInfo, UIN 0, (sizeof(struct shmIDSource) * shmInfo->shmmni)); for (i = 0; i < shmInfo->shmmni; i++) { - shmSegs[i].status = SHM_SEG_FREE; - shmSegs[i].ds.shm_perm.seq = i + 1; - LOS_ListInit(&shmSegs[i].node); + shmSegs[i].status = SHM_SEG_FREE;//节点初始状态为空闲 + shmSegs[i].ds.shm_perm.seq = i + 1;//struct ipc_perm shm_perm;系统为每一个IPC对象保存一个ipc_perm结构体,结构说明了IPC对象的权限和所有者 + LOS_ListInit(&shmSegs[i].node);//初始化节点 } *shmUsedPageCount = 0; @@ -137,7 +199,6 @@ ERROR: VM_ERR("ShmInit fail\n"); return NULL; } - UINT32 ShmInit(VOID) { #ifndef LOSCFG_IPC_CONTAINER @@ -149,8 +210,9 @@ UINT32 ShmInit(VOID) return LOS_OK; } -LOS_MODULE_INIT(ShmInit, LOS_INIT_LEVEL_VM_COMPLETE); +LOS_MODULE_INIT(ShmInit, LOS_INIT_LEVEL_VM_COMPLETE);//共享内存模块初始化 +//共享内存反初始化 UINT32 ShmDeinit(VOID) { UINT32 ret; @@ -165,7 +227,7 @@ UINT32 ShmDeinit(VOID) return 0; } - +///给共享段中所有物理页框贴上共享标签 STATIC inline VOID ShmSetSharedFlag(struct shmIDSource *seg) { LosVmPage *page = NULL; @@ -174,7 +236,7 @@ STATIC inline VOID ShmSetSharedFlag(struct shmIDSource *seg) OsSetPageShared(page); } } - +///给共享段中所有物理页框撕掉共享标签 STATIC inline VOID ShmClearSharedFlag(struct shmIDSource *seg) { LosVmPage *page = NULL; @@ -183,7 +245,7 @@ STATIC inline VOID ShmClearSharedFlag(struct shmIDSource *seg) OsCleanPageShared(page); } } - +///seg下所有共享页引用减少 STATIC VOID ShmPagesRefDec(struct shmIDSource *seg) { LosVmPage *page = NULL; @@ -193,6 +255,15 @@ STATIC VOID ShmPagesRefDec(struct shmIDSource *seg) } } +/** + * @brief 为共享段分配物理内存 + 例如:参数size = 4097, LOS_Align(size, PAGE_SIZE) = 8192 + 分配页数 size >> PAGE_SHIFT = 2页 + * @param key + * @param size + * @param shmflg + * @return STATIC + */ STATIC INT32 ShmAllocSegCheck(key_t key, size_t *size, INT32 *segNum) { INT32 i; @@ -201,7 +272,7 @@ STATIC INT32 ShmAllocSegCheck(key_t key, size_t *size, INT32 *segNum) return -EINVAL; } - *size = LOS_Align(*size, PAGE_SIZE); + *size = LOS_Align(*size, PAGE_SIZE);//必须对齐 if ((IPC_SHM_USED_PAGE_COUNT + (*size >> PAGE_SHIFT)) > IPC_SHM_INFO.shmall) { return -ENOMEM; } @@ -211,11 +282,10 @@ STATIC INT32 ShmAllocSegCheck(key_t key, size_t *size, INT32 *segNum) return -ENOMEM; } #endif - - for (i = 0; i < IPC_SHM_INFO.shmmni; i++) { - if (IPC_SHM_SEGS[i].status & SHM_SEG_FREE) { - IPC_SHM_SEGS[i].status &= ~SHM_SEG_FREE; - *segNum = i; + for (i = 0; i < IPC_SHM_INFO.shmmni; i++) {//试图找到一个空闲段与参数key绑定 + if (IPC_SHM_SEGS[i].status & SHM_SEG_FREE) {//找到空闲段 + IPC_SHM_SEGS[i].status &= ~SHM_SEG_FREE;//变成非空闲状态 + *segNum = i;//标号 break; } } @@ -236,49 +306,47 @@ STATIC INT32 ShmAllocSeg(key_t key, size_t size, INT32 shmflg) if (ret < 0) { return ret; } - seg = &IPC_SHM_SEGS[segNum]; - count = LOS_PhysPagesAlloc(size >> PAGE_SHIFT, &seg->node); - if (count != (size >> PAGE_SHIFT)) { - (VOID)LOS_PhysPagesFree(&seg->node); - seg->status = SHM_SEG_FREE; + count = LOS_PhysPagesAlloc(size >> PAGE_SHIFT, &seg->node);//分配共享页面,函数内部把node都挂好了. + if (count != (size >> PAGE_SHIFT)) {//当未分配到足够的内存时,处理方式是:不稀罕给那么点,舍弃! + (VOID)LOS_PhysPagesFree(&seg->node);//释放节点上的物理页框 + seg->status = SHM_SEG_FREE;//共享段变回空闲状态 #ifdef LOSCFG_KERNEL_IPC_PLIMIT OsIPCLimitShmFree(size); #endif return -ENOMEM; } - - ShmSetSharedFlag(seg); + ShmSetSharedFlag(seg);//将node的每个页面设置为共享页 IPC_SHM_USED_PAGE_COUNT += size >> PAGE_SHIFT; - seg->status |= SHM_SEG_USED; + seg->status |= SHM_SEG_USED; //共享段贴上已在使用的标签 seg->ds.shm_perm.mode = (UINT32)shmflg & ACCESSPERMS; - seg->ds.shm_perm.key = key; - seg->ds.shm_segsz = size; - seg->ds.shm_perm.cuid = LOS_GetUserID(); - seg->ds.shm_perm.uid = LOS_GetUserID(); - seg->ds.shm_perm.cgid = LOS_GetGroupID(); - seg->ds.shm_perm.gid = LOS_GetGroupID(); - seg->ds.shm_lpid = 0; - seg->ds.shm_nattch = 0; - seg->ds.shm_cpid = LOS_GetCurrProcessID(); - seg->ds.shm_atime = 0; - seg->ds.shm_dtime = 0; - seg->ds.shm_ctime = time(NULL); + seg->ds.shm_perm.key = key;//保存参数key,如此 key 和 共享ID绑定在一块 + seg->ds.shm_segsz = size; //共享段的大小 + seg->ds.shm_perm.cuid = LOS_GetUserID(); //设置用户ID + seg->ds.shm_perm.uid = LOS_GetUserID(); //设置用户ID + seg->ds.shm_perm.cgid = LOS_GetGroupID(); //设置组ID + seg->ds.shm_perm.gid = LOS_GetGroupID(); //设置组ID + seg->ds.shm_lpid = 0; //最后一个操作的进程 + seg->ds.shm_nattch = 0; //绑定进程的数量 + seg->ds.shm_cpid = LOS_GetCurrProcessID(); //获取进程ID + seg->ds.shm_atime = 0; //访问时间 + seg->ds.shm_dtime = 0; //detach 分离时间 共享内存使用完之后,需要将它从进程地址空间中分离出来;将共享内存分离并不是删除它,只是使该共享内存对当前的进程不再可用 + seg->ds.shm_ctime = time(NULL);//创建时间 #ifdef LOSCFG_SHELL (VOID)memcpy_s(seg->ownerName, OS_PCB_NAME_LEN, OsCurrProcessGet()->processName, OS_PCB_NAME_LEN); #endif return segNum; } - +///释放seg->node 所占物理页框,seg本身重置 STATIC INLINE VOID ShmFreeSeg(struct shmIDSource *seg, UINT32 *shmUsedPageCount) { UINT32 count; - ShmClearSharedFlag(seg); - count = LOS_PhysPagesFree(&seg->node); - if (count != (seg->ds.shm_segsz >> PAGE_SHIFT)) { + ShmClearSharedFlag(seg);//先撕掉 seg->node 中vmpage的共享标签 + count = LOS_PhysPagesFree(&seg->node);//再挨个删除物理页框 + if (count != (seg->ds.shm_segsz >> PAGE_SHIFT)) {//异常,必须要一样 VM_ERR("free physical pages failed, count = %d, size = %d", count, seg->ds.shm_segsz >> PAGE_SHIFT); return; } @@ -288,31 +356,31 @@ STATIC INLINE VOID ShmFreeSeg(struct shmIDSource *seg, UINT32 *shmUsedPageCount) if (shmUsedPageCount != NULL) { (*shmUsedPageCount) -= seg->ds.shm_segsz >> PAGE_SHIFT; } - seg->status = SHM_SEG_FREE; - LOS_ListInit(&seg->node); + seg->status = SHM_SEG_FREE;//seg恢复自由之身 + LOS_ListInit(&seg->node);//重置node } - +///通过key查找 shmId STATIC INT32 ShmFindSegByKey(key_t key) { INT32 i; struct shmIDSource *seg = NULL; - for (i = 0; i < IPC_SHM_INFO.shmmni; i++) { + for (i = 0; i < IPC_SHM_INFO.shmmni; i++) {//遍历共享段池,找到与key绑定的共享ID seg = &IPC_SHM_SEGS[i]; if ((seg->status & SHM_SEG_USED) && - (seg->ds.shm_perm.key == key)) { + (seg->ds.shm_perm.key == key)) {//满足两个条件,找到后返回 return i; } } return -1; } - +///共享内存段有效性检查 STATIC INT32 ShmSegValidCheck(INT32 segNum, size_t size, INT32 shmFlg) { - struct shmIDSource *seg = &IPC_SHM_SEGS[segNum]; + struct shmIDSource *seg = &IPC_SHM_SEGS[segNum];//拿到shmID - if (size > seg->ds.shm_segsz) { + if (size > seg->ds.shm_segsz) {//段长 return -EINVAL; } @@ -323,7 +391,7 @@ STATIC INT32 ShmSegValidCheck(INT32 segNum, size_t size, INT32 shmFlg) return segNum; } - +///通过ID找到共享内存资源 STATIC struct shmIDSource *ShmFindSeg(int shmid) { struct shmIDSource *seg = NULL; @@ -341,7 +409,7 @@ STATIC struct shmIDSource *ShmFindSeg(int shmid) return seg; } - +///共享内存映射 STATIC VOID ShmVmmMapping(LosVmSpace *space, LOS_DL_LIST *pageList, VADDR_T vaddr, UINT32 regionFlags) { LosVmPage *vmPage = NULL; @@ -349,64 +417,64 @@ STATIC VOID ShmVmmMapping(LosVmSpace *space, LOS_DL_LIST *pageList, VADDR_T vadd PADDR_T pa; STATUS_T ret; - LOS_DL_LIST_FOR_EACH_ENTRY(vmPage, pageList, LosVmPage, node) { - pa = VM_PAGE_TO_PHYS(vmPage); - LOS_AtomicInc(&vmPage->refCounts); - ret = LOS_ArchMmuMap(&space->archMmu, va, pa, 1, regionFlags); + LOS_DL_LIST_FOR_EACH_ENTRY(vmPage, pageList, LosVmPage, node) {//遍历一页一页映射 + pa = VM_PAGE_TO_PHYS(vmPage);//拿到物理地址 + LOS_AtomicInc(&vmPage->refCounts);//自增 + ret = LOS_ArchMmuMap(&space->archMmu, va, pa, 1, regionFlags);//虚实映射 if (ret != 1) { VM_ERR("LOS_ArchMmuMap failed, ret = %d", ret); } va += PAGE_SIZE; } } - +///fork 一个共享线性区 VOID OsShmFork(LosVmSpace *space, LosVmMapRegion *oldRegion, LosVmMapRegion *newRegion) { struct shmIDSource *seg = NULL; SYSV_SHM_LOCK(); - seg = ShmFindSeg(oldRegion->shmid); + seg = ShmFindSeg(oldRegion->shmid);//通过老区ID获取对应的共享资源ID结构体 if (seg == NULL) { SYSV_SHM_UNLOCK(); VM_ERR("shm fork failed!"); return; } - newRegion->shmid = oldRegion->shmid; - newRegion->forkFlags = oldRegion->forkFlags; - ShmVmmMapping(space, &seg->node, newRegion->range.base, newRegion->regionFlags); - seg->ds.shm_nattch++; + newRegion->shmid = oldRegion->shmid;//一样的共享区ID + newRegion->forkFlags = oldRegion->forkFlags;//forkFlags也一样了 + ShmVmmMapping(space, &seg->node, newRegion->range.base, newRegion->regionFlags);//新线性区与共享内存进行映射 + seg->ds.shm_nattch++;//附在共享线性区上的进程数++ SYSV_SHM_UNLOCK(); } - +///释放共享线性区 VOID OsShmRegionFree(LosVmSpace *space, LosVmMapRegion *region) { struct shmIDSource *seg = NULL; SYSV_SHM_LOCK(); - seg = ShmFindSeg(region->shmid); + seg = ShmFindSeg(region->shmid);//通过线性区ID获取对应的共享资源ID结构体 if (seg == NULL) { SYSV_SHM_UNLOCK(); return; } - LOS_ArchMmuUnmap(&space->archMmu, region->range.base, region->range.size >> PAGE_SHIFT); - ShmPagesRefDec(seg); - seg->ds.shm_nattch--; + LOS_ArchMmuUnmap(&space->archMmu, region->range.base, region->range.size >> PAGE_SHIFT);//解除线性区的映射 + ShmPagesRefDec(seg);//ref -- + seg->ds.shm_nattch--;//附在共享线性区上的进程数-- if (seg->ds.shm_nattch <= 0 && (seg->status & SHM_SEG_REMOVE)) { - ShmFreeSeg(seg, &IPC_SHM_USED_PAGE_COUNT); + ShmFreeSeg(seg, &IPC_SHM_USED_PAGE_COUNT);//就释放掉物理内存!注意是:物理内存 } else { seg->ds.shm_dtime = time(NULL); seg->ds.shm_lpid = LOS_GetCurrProcessID(); /* may not be the space's PID. */ } SYSV_SHM_UNLOCK(); } - +///是否为共享线性区,是否有标签? BOOL OsIsShmRegion(LosVmMapRegion *region) { return (region->regionFlags & VM_MAP_REGION_FLAG_SHM) ? TRUE : FALSE; } - +///获取共享内存池中已被使用的段数量 STATIC INT32 ShmSegUsedCount(VOID) { INT32 i; @@ -415,16 +483,16 @@ STATIC INT32 ShmSegUsedCount(VOID) for (i = 0; i < IPC_SHM_INFO.shmmni; i++) { seg = &IPC_SHM_SEGS[i]; - if (seg->status & SHM_SEG_USED) { + if (seg->status & SHM_SEG_USED) {//找到一个 count++; } } return count; } - +///对共享内存段权限检查 STATIC INT32 ShmPermCheck(struct shmIDSource *seg, mode_t mode) { - INT32 uid = LOS_GetUserID(); + INT32 uid = LOS_GetUserID();//当前进程的用户ID UINT32 tmpMode = 0; mode_t privMode = seg->ds.shm_perm.mode; mode_t accMode; @@ -466,6 +534,22 @@ STATIC INT32 ShmPermCheck(struct shmIDSource *seg, mode_t mode) } } +/*! + * @brief ShmGet + * 得到一个共享内存标识符或创建一个共享内存对象 + * @param key 建立新共享内存对象 标识符是IPC对象的内部名。为使多个合作进程能够在同一IPC对象上汇聚,需要提供一个外部命名方案。 + 为此,每个IPC对象都与一个键(key)相关联,这个键作为该对象的外部名,无论何时创建IPC结构(通过msgget、semget、shmget创建), + 都应给IPC指定一个键, key_t由ftok创建,ftok当然在本工程里找不到,所以要写这么多. + * @param shmflg IPC_CREAT IPC_EXCL + IPC_CREAT: 在创建新的IPC时,如果key参数是IPC_PRIVATE或者和当前某种类型的IPC结构无关,则需要指明flag参数的IPC_CREAT标志位, + 则用来创建一个新的IPC结构。(如果IPC结构已存在,并且指定了IPC_CREAT,则IPC_CREAT什么都不做,函数也不出错) + IPC_EXCL: 此参数一般与IPC_CREAT配合使用来创建一个新的IPC结构。如果创建的IPC结构已存在函数就出错返回, + 返回EEXIST(这与open函数指定O_CREAT和O_EXCL标志原理相同) + * @param size 新建的共享内存大小,以字节为单位 + * @return + * + * @see + */ INT32 ShmGet(key_t key, size_t size, INT32 shmflg) { INT32 ret; @@ -476,13 +560,13 @@ INT32 ShmGet(key_t key, size_t size, INT32 shmflg) if (key == IPC_PRIVATE) { ret = ShmAllocSeg(key, size, shmflg); } else { - ret = ShmFindSegByKey(key); + ret = ShmFindSegByKey(key);//通过key查找资源ID if (ret < 0) { - if (((UINT32)shmflg & IPC_CREAT) == 0) { + if (((UINT32)shmflg & IPC_CREAT) == 0) {// ret = -ENOENT; goto ERROR; } else { - ret = ShmAllocSeg(key, size, shmflg); + ret = ShmAllocSeg(key, size, shmflg);//分配一个共享内存 } } else { shmid = ret; @@ -491,7 +575,7 @@ INT32 ShmGet(key_t key, size_t size, INT32 shmflg) ret = -EEXIST; goto ERROR; } - ret = ShmPermCheck(ShmFindSeg(shmid), (UINT32)shmflg & ACCESSPERMS); + ret = ShmPermCheck(ShmFindSeg(shmid), (UINT32)shmflg & ACCESSPERMS);//对共享内存权限检查 if (ret != 0) { ret = -ret; goto ERROR; @@ -526,13 +610,13 @@ INT32 ShmatParamCheck(const VOID *shmaddr, INT32 shmflg) return 0; } - +///分配一个共享线性区并映射好 LosVmMapRegion *ShmatVmmAlloc(struct shmIDSource *seg, const VOID *shmaddr, INT32 shmflg, UINT32 prot) { LosVmSpace *space = OsCurrProcessGet()->vmSpace; LosVmMapRegion *region = NULL; - UINT32 flags = MAP_ANONYMOUS | MAP_SHARED; + UINT32 flags = MAP_ANONYMOUS | MAP_SHARED;//本线性区为共享+匿名标签 UINT32 mapFlags = flags | MAP_FIXED; VADDR_T vaddr; UINT32 regionFlags; @@ -543,29 +627,29 @@ LosVmMapRegion *ShmatVmmAlloc(struct shmIDSource *seg, const VOID *shmaddr, } regionFlags = OsCvtProtFlagsToRegionFlags(prot, flags); (VOID)LOS_MuxAcquire(&space->regionMux); - if (shmaddr == NULL) { - region = LOS_RegionAlloc(space, 0, seg->ds.shm_segsz, regionFlags, 0); - } else { + if (shmaddr == NULL) {//未指定了共享内存连接到当前进程中的地址位置 + region = LOS_RegionAlloc(space, 0, seg->ds.shm_segsz, regionFlags, 0);//分配线性区 + } else {//指定时,就需要先找地址所在的线性区 if ((UINT32)shmflg & SHM_RND) { vaddr = ROUNDDOWN((VADDR_T)(UINTPTR)shmaddr, SHMLBA); } else { vaddr = (VADDR_T)(UINTPTR)shmaddr; - } + }//找到线性区并重新映射,当指定地址时需贴上重新映射的标签 if (!((UINT32)shmflg & SHM_REMAP) && (LOS_RegionFind(space, vaddr) || LOS_RegionFind(space, vaddr + seg->ds.shm_segsz - 1) || LOS_RegionRangeFind(space, vaddr, seg->ds.shm_segsz - 1))) { ret = EINVAL; goto ERROR; } - vaddr = (VADDR_T)LOS_MMap(vaddr, seg->ds.shm_segsz, prot, mapFlags, -1, 0); - region = LOS_RegionFind(space, vaddr); + vaddr = (VADDR_T)LOS_MMap(vaddr, seg->ds.shm_segsz, prot, mapFlags, -1, 0);//做好映射 + region = LOS_RegionFind(space, vaddr);//重新查找线性区,用于返回. } if (region == NULL) { ret = ENOMEM; goto ERROR; } - ShmVmmMapping(space, &seg->node, region->range.base, regionFlags); + ShmVmmMapping(space, &seg->node, region->range.base, regionFlags);//共享内存映射 (VOID)LOS_MuxRelease(&space->regionMux); return region; ERROR: @@ -574,6 +658,17 @@ ERROR: return NULL; } +/*! + * @brief ShmAt + * 用来启动对该共享内存的访问,并把共享内存连接到当前进程的地址空间。 + * @param shm_flg 是一组标志位,通常为0。 + * @param shmaddr 指定共享内存连接到当前进程中的地址位置,通常为空,表示让系统来选择共享内存的地址。 + * @param shmid 是shmget()函数返回的共享内存标识符 + * @return + * 如果shmat成功执行,那么内核将使与该共享存储相关的shmid_ds结构中的shm_nattch计数器值加1 + shmid 就是个索引,就跟进程和线程的ID一样 g_shmSegs[shmid] shmid > 192个 + * @see + */ VOID *ShmAt(INT32 shmid, const VOID *shmaddr, INT32 shmflg) { INT32 ret; @@ -582,13 +677,13 @@ VOID *ShmAt(INT32 shmid, const VOID *shmaddr, INT32 shmflg) struct shmIDSource *seg = NULL; LosVmMapRegion *r = NULL; - ret = ShmatParamCheck(shmaddr, shmflg); + ret = ShmatParamCheck(shmaddr, shmflg);//参数检查 if (ret != 0) { set_errno(ret); return (VOID *)-1; } - if ((UINT32)shmflg & SHM_EXEC) { + if ((UINT32)shmflg & SHM_EXEC) {//flag 转换 prot |= PROT_EXEC; acc_mode |= SHM_S_IXUGO; } else if (((UINT32)shmflg & SHM_RDONLY) == 0) { @@ -597,7 +692,7 @@ VOID *ShmAt(INT32 shmid, const VOID *shmaddr, INT32 shmflg) } SYSV_SHM_LOCK(); - seg = ShmFindSeg(shmid); + seg = ShmFindSeg(shmid);//找到段 if (seg == NULL) { SYSV_SHM_UNLOCK(); return (VOID *)-1; @@ -608,18 +703,18 @@ VOID *ShmAt(INT32 shmid, const VOID *shmaddr, INT32 shmflg) goto ERROR; } - seg->ds.shm_nattch++; - r = ShmatVmmAlloc(seg, shmaddr, shmflg, prot); + seg->ds.shm_nattch++;//ds上记录有一个进程绑定上来 + r = ShmatVmmAlloc(seg, shmaddr, shmflg, prot);//在当前进程空间分配一个线性区并映射到共享内存 if (r == NULL) { seg->ds.shm_nattch--; SYSV_SHM_UNLOCK(); return (VOID *)-1; } - r->shmid = shmid; - r->regionFlags |= VM_MAP_REGION_FLAG_SHM; - seg->ds.shm_atime = time(NULL); - seg->ds.shm_lpid = LOS_GetCurrProcessID(); + r->shmid = shmid;//把ID给线性区的shmid + r->regionFlags |= VM_MAP_REGION_FLAG_SHM;//这是一个共享线性区 + seg->ds.shm_atime = time(NULL);//访问时间 + seg->ds.shm_lpid = LOS_GetCurrProcessID();//进程ID SYSV_SHM_UNLOCK(); return (VOID *)(UINTPTR)r->range.base; @@ -630,6 +725,19 @@ ERROR: return (VOID *)-1; } +/*! + * @brief ShmCtl + * 此函数可以对shmid指定的共享存储进行多种操作(删除、取信息、加锁、解锁等) + * @param buf 是一个结构指针,它指向共享内存模式和访问权限的结构。 + * @param cmd command是要采取的操作,它可以取下面的三个值 : + IPC_STAT:把shmid_ds结构中的数据设置为共享内存的当前关联值,即用共享内存的当前关联值覆盖shmid_ds的值。 + IPC_SET:如果进程有足够的权限,就把共享内存的当前关联值设置为shmid_ds结构中给出的值 + IPC_RMID:删除共享内存段 + * @param shmid 是shmget()函数返回的共享内存标识符 + * @return + * + * @see + */ INT32 ShmCtl(INT32 shmid, INT32 cmd, struct shmid_ds *buf) { struct shmIDSource *seg = NULL; @@ -642,7 +750,7 @@ INT32 ShmCtl(INT32 shmid, INT32 cmd, struct shmid_ds *buf) SYSV_SHM_LOCK(); if ((cmd != IPC_INFO) && (cmd != SHM_INFO)) { - seg = ShmFindSeg(shmid); + seg = ShmFindSeg(shmid);//通过索引ID找到seg if (seg == NULL) { SYSV_SHM_UNLOCK(); return -1; @@ -656,13 +764,13 @@ INT32 ShmCtl(INT32 shmid, INT32 cmd, struct shmid_ds *buf) switch (cmd) { case IPC_STAT: - case SHM_STAT: + case SHM_STAT://取段结构 ret = ShmPermCheck(seg, SHM_S_IRUGO); if (ret != 0) { goto ERROR; } - ret = LOS_ArchCopyToUser(buf, &seg->ds, sizeof(struct shmid_ds)); + ret = LOS_ArchCopyToUser(buf, &seg->ds, sizeof(struct shmid_ds));//把内核空间的共享页数据拷贝到用户空间 if (ret != 0) { ret = EFAULT; goto ERROR; @@ -671,13 +779,13 @@ INT32 ShmCtl(INT32 shmid, INT32 cmd, struct shmid_ds *buf) ret = (unsigned int)((unsigned int)seg->ds.shm_perm.seq << 16) | (unsigned int)((unsigned int)shmid & 0xffff); /* 16: use the seq as the upper 16 bits */ } break; - case IPC_SET: + case IPC_SET://重置共享段 ret = ShmPermCheck(seg, SHM_M); if (ret != 0) { ret = EPERM; goto ERROR; } - + //从用户空间拷贝数据到内核空间 ret = LOS_ArchCopyFromUser(&shm_perm, &buf->shm_perm, sizeof(struct ipc_perm)); if (ret != 0) { ret = EFAULT; @@ -686,14 +794,14 @@ INT32 ShmCtl(INT32 shmid, INT32 cmd, struct shmid_ds *buf) seg->ds.shm_perm.uid = shm_perm.uid; seg->ds.shm_perm.gid = shm_perm.gid; seg->ds.shm_perm.mode = (seg->ds.shm_perm.mode & ~ACCESSPERMS) | - (shm_perm.mode & ACCESSPERMS); + (shm_perm.mode & ACCESSPERMS);//可访问 seg->ds.shm_ctime = time(NULL); #ifdef LOSCFG_SHELL (VOID)memcpy_s(seg->ownerName, OS_PCB_NAME_LEN, OS_PCB_FROM_PID(shm_perm.uid)->processName, OS_PCB_NAME_LEN); #endif break; - case IPC_RMID: + case IPC_RMID://删除共享段 ret = ShmPermCheck(seg, SHM_M); if (ret != 0) { ret = EPERM; @@ -701,11 +809,11 @@ INT32 ShmCtl(INT32 shmid, INT32 cmd, struct shmid_ds *buf) } seg->status |= SHM_SEG_REMOVE; - if (seg->ds.shm_nattch <= 0) { + if (seg->ds.shm_nattch <= 0) {//没有任何进程在使用了 ShmFreeSeg(seg, &IPC_SHM_USED_PAGE_COUNT); } break; - case IPC_INFO: + case IPC_INFO://把内核空间的共享页数据拷贝到用户空间 ret = LOS_ArchCopyToUser(buf, &IPC_SHM_INFO, sizeof(struct shminfo)); if (ret != 0) { ret = EFAULT; @@ -719,8 +827,8 @@ INT32 ShmCtl(INT32 shmid, INT32 cmd, struct shmid_ds *buf) shmInfo.shm_tot = 0; shmInfo.swap_attempts = 0; shmInfo.swap_successes = 0; - shmInfo.used_ids = ShmSegUsedCount(); - ret = LOS_ArchCopyToUser(buf, &shmInfo, sizeof(struct shm_info)); + shmInfo.used_ids = ShmSegUsedCount();//在使用的seg数 + ret = LOS_ArchCopyToUser(buf, &shmInfo, sizeof(struct shm_info));//把内核空间的共享页数据拷贝到用户空间 if (ret != 0) { ret = EFAULT; goto ERROR; @@ -743,55 +851,63 @@ ERROR: return -1; } +/** + * @brief 当对共享存储的操作已经结束时,则调用shmdt与该存储段分离 + 如果shmat成功执行,那么内核将使与该共享存储相关的shmid_ds结构中的shm_nattch计数器值减1 + * @attention 注意:这并不从系统中删除共享存储的标识符以及其相关的数据结构。共享存储的仍然存在, + 直至某个进程带IPC_RMID命令的调用shmctl特地删除共享存储为止 + * @param shmaddr + * @return INT32 + */ INT32 ShmDt(const VOID *shmaddr) { - LosVmSpace *space = OsCurrProcessGet()->vmSpace; + LosVmSpace *space = OsCurrProcessGet()->vmSpace;//获取进程空间 struct shmIDSource *seg = NULL; LosVmMapRegion *region = NULL; INT32 shmid; INT32 ret; - if (IS_PAGE_ALIGNED(shmaddr) == 0) { + if (IS_PAGE_ALIGNED(shmaddr) == 0) {//地址是否对齐 ret = EINVAL; goto ERROR; } (VOID)LOS_MuxAcquire(&space->regionMux); - region = LOS_RegionFind(space, (VADDR_T)(UINTPTR)shmaddr); + region = LOS_RegionFind(space, (VADDR_T)(UINTPTR)shmaddr);//找到线性区 if (region == NULL) { ret = EINVAL; goto ERROR_WITH_LOCK; } - shmid = region->shmid; + shmid = region->shmid;//线性区共享ID - if (region->range.base != (VADDR_T)(UINTPTR)shmaddr) { - ret = EINVAL; + if (region->range.base != (VADDR_T)(UINTPTR)shmaddr) {//这是用户空间和内核空间的一次解绑 + ret = EINVAL; //shmaddr 必须要等于region->range.base goto ERROR_WITH_LOCK; } /* remove it from aspace */ - LOS_RbDelNode(&space->regionRbTree, ®ion->rbNode); - LOS_ArchMmuUnmap(&space->archMmu, region->range.base, region->range.size >> PAGE_SHIFT); + LOS_RbDelNode(&space->regionRbTree, ®ion->rbNode);//从红黑树和链表中摘除节点 + LOS_ArchMmuUnmap(&space->archMmu, region->range.base, region->range.size >> PAGE_SHIFT);//解除线性区的映射 (VOID)LOS_MuxRelease(&space->regionMux); /* free it */ - free(region); + free(region);//释放线性区所占内存池中的内存 SYSV_SHM_LOCK(); - seg = ShmFindSeg(shmid); + seg = ShmFindSeg(shmid);//找到seg,线性区和共享段的关系是 1:N 的关系,其他空间的线性区也会绑在共享段上 if (seg == NULL) { ret = EINVAL; SYSV_SHM_UNLOCK(); goto ERROR; } - ShmPagesRefDec(seg); - seg->ds.shm_nattch--; - if ((seg->ds.shm_nattch <= 0) && - (seg->status & SHM_SEG_REMOVE)) { - ShmFreeSeg(seg, &IPC_SHM_USED_PAGE_COUNT); + ShmPagesRefDec(seg);//页面引用数 -- + seg->ds.shm_nattch--;//使用共享内存的进程数少了一个 + if ((seg->ds.shm_nattch <= 0) && //无任何进程使用共享内存 + (seg->status & SHM_SEG_REMOVE)) {//状态为删除时需要释放物理页内存了,否则其他进程还要继续使用共享内存 + ShmFreeSeg(seg, &IPC_SHM_USED_PAGE_COUNT);//释放seg 页框链表中的页框内存,再重置seg状态 } else { - seg->ds.shm_dtime = time(NULL); - seg->ds.shm_lpid = LOS_GetCurrProcessID(); + seg->ds.shm_dtime = time(NULL);//记录分离的时间 + seg->ds.shm_lpid = LOS_GetCurrProcessID();//记录操作进程ID } SYSV_SHM_UNLOCK(); @@ -847,7 +963,6 @@ STATIC VOID OsShmInfoCmd(VOID) } SYSV_SHM_UNLOCK(); } - STATIC VOID OsShmDeleteCmd(INT32 shmid) { struct shmIDSource *seg = NULL; @@ -876,7 +991,7 @@ STATIC VOID OsShmCmdUsage(VOID) "\t-r [shmid], Recycle the specified shared memory about shmid\n" "\t-h | --help, print shm command usage\n"); } - +///共享内存 UINT32 OsShellCmdShm(INT32 argc, const CHAR *argv[]) { INT32 shmid; @@ -911,4 +1026,3 @@ DONE: SHELLCMD_ENTRY(shm_shellcmd, CMD_TYPE_SHOW, "shm", 2, (CmdCallBackFunc)OsShellCmdShm); #endif #endif - From aa1fab3ff78ff368bbdc6510f0faaef674fab364 Mon Sep 17 00:00:00 2001 From: Dio Date: Fri, 19 Jan 2024 16:27:08 +0800 Subject: [PATCH 24/33] =?UTF-8?q?sched=E5=A4=A7=E6=A6=82=E5=B7=AE=E4=B8=8D?= =?UTF-8?q?=E5=A4=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kernel/base/sched/los_idle.c | 2 +- .../kernel/base/sched/los_priority.c | 22 +++++---- .../kernel/base/sched/los_sortlink.c | 49 +++++++++++-------- 3 files changed, 42 insertions(+), 31 deletions(-) diff --git a/src/kernel_liteos_a/kernel/base/sched/los_idle.c b/src/kernel_liteos_a/kernel/base/sched/los_idle.c index d2538595..0ba434dc 100644 --- a/src/kernel_liteos_a/kernel/base/sched/los_idle.c +++ b/src/kernel_liteos_a/kernel/base/sched/los_idle.c @@ -44,7 +44,7 @@ STATIC VOID IdleTimeSliceUpdate(SchedRunqueue *rq, LosTaskCB *taskCB, UINT64 cur STATIC INT32 IdleParamCompare(const SchedPolicy *sp1, const SchedPolicy *sp2); STATIC VOID IdlePriorityInheritance(LosTaskCB *owner, const SchedParam *param); STATIC VOID IdlePriorityRestore(LosTaskCB *owner, const LOS_DL_LIST *list, const SchedParam *param); - +//空闲调度 const STATIC SchedOps g_idleOps = { .dequeue = IdleDequeue, .enqueue = IdleEnqueue, diff --git a/src/kernel_liteos_a/kernel/base/sched/los_priority.c b/src/kernel_liteos_a/kernel/base/sched/los_priority.c index 610ba119..5f1c858d 100644 --- a/src/kernel_liteos_a/kernel/base/sched/los_priority.c +++ b/src/kernel_liteos_a/kernel/base/sched/los_priority.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -43,6 +43,8 @@ #define OS_SCHED_READY_MAX 30 #define OS_TIME_SLICE_MIN (INT32)((50 * OS_SYS_NS_PER_US) / OS_NS_PER_CYCLE) /* 50us */ +//基于优先数调度算法 Highest-Priority-First (HPF) + STATIC HPFRunqueue g_schedHPF; STATIC VOID HPFDequeue(SchedRunqueue *rq, LosTaskCB *taskCB); @@ -63,7 +65,7 @@ STATIC VOID HPFTimeSliceUpdate(SchedRunqueue *rq, LosTaskCB *taskCB, UINT64 curr STATIC INT32 HPFParamCompare(const SchedPolicy *sp1, const SchedPolicy *sp2); STATIC VOID HPFPriorityInheritance(LosTaskCB *owner, const SchedParam *param); STATIC VOID HPFPriorityRestore(LosTaskCB *owner, const LOS_DL_LIST *list, const SchedParam *param); - +//优先级调度算法操作 const STATIC SchedOps g_priorityOps = { .dequeue = HPFDequeue, .enqueue = HPFEnqueue, @@ -243,7 +245,7 @@ STATIC INLINE VOID PriQueInsert(HPFRunqueue *rq, LosTaskCB *taskCB) taskCB->taskStatus &= ~OS_TASK_STATUS_BLOCKED; taskCB->taskStatus |= OS_TASK_STATUS_READY; } - +//入就绪队列 STATIC VOID HPFEnqueue(SchedRunqueue *rq, LosTaskCB *taskCB) { #ifdef LOSCFG_SCHED_HPF_DEBUG @@ -253,14 +255,14 @@ STATIC VOID HPFEnqueue(SchedRunqueue *rq, LosTaskCB *taskCB) #endif PriQueInsert(rq->hpfRunqueue, taskCB); } - +//出就绪队列 STATIC VOID HPFDequeue(SchedRunqueue *rq, LosTaskCB *taskCB) { SchedHPF *sched = (SchedHPF *)&taskCB->sp; - if (taskCB->taskStatus & OS_TASK_STATUS_READY) { + if (taskCB->taskStatus & OS_TASK_STATUS_READY) {//是否有就绪状态 PriQueDelete(rq->hpfRunqueue, sched->basePrio, &taskCB->pendList, sched->priority); - taskCB->taskStatus &= ~OS_TASK_STATUS_READY; + taskCB->taskStatus &= ~OS_TASK_STATUS_READY;//更新成非就绪状态 } } @@ -475,7 +477,7 @@ STATIC VOID HPFPriorityInheritance(LosTaskCB *owner, const SchedParam *param) LOS_BitmapSet(&sp->priBitmap, sp->priority); sp->priority = param->priority; } - +/// 恢复任务优先级 STATIC VOID HPFPriorityRestore(LosTaskCB *owner, const LOS_DL_LIST *list, const SchedParam *param) { UINT16 priority; @@ -498,8 +500,8 @@ STATIC VOID HPFPriorityRestore(LosTaskCB *owner, const LOS_DL_LIST *list, const } if ((list != NULL) && !LOS_ListEmpty((LOS_DL_LIST *)list)) { - priority = LOS_HighBitGet(sp->priBitmap); - LOS_DL_LIST_FOR_EACH_ENTRY(pendedTask, list, LosTaskCB, pendList) { + priority = LOS_HighBitGet(sp->priBitmap);//获取在历史调度中最高优先级 + LOS_DL_LIST_FOR_EACH_ENTRY(pendedTask, list, LosTaskCB, pendList) {//遍历链表 SchedHPF *pendSp = (SchedHPF *)&pendedTask->sp; if ((pendedTask->ops == owner->ops) && (priority != pendSp->priority)) { LOS_BitmapClr(&sp->priBitmap, pendSp->priority); @@ -537,7 +539,7 @@ VOID HPFProcessDefaultSchedParamGet(SchedParam *param) { param->basePrio = OS_USER_PROCESS_PRIORITY_HIGHEST; } - +//HPF 调度策略初始化 VOID HPFSchedPolicyInit(SchedRunqueue *rq) { if (ArchCurrCpuid() > 0) { diff --git a/src/kernel_liteos_a/kernel/base/sched/los_sortlink.c b/src/kernel_liteos_a/kernel/base/sched/los_sortlink.c index 4f68436f..7dcfce04 100644 --- a/src/kernel_liteos_a/kernel/base/sched/los_sortlink.c +++ b/src/kernel_liteos_a/kernel/base/sched/los_sortlink.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -30,7 +30,7 @@ */ #include "los_sortlink_pri.h" - +/// 排序链表初始化 VOID OsSortLinkInit(SortLinkAttribute *sortLinkHeader) { LOS_ListInit(&sortLinkHeader->sortLink); @@ -38,38 +38,47 @@ VOID OsSortLinkInit(SortLinkAttribute *sortLinkHeader) sortLinkHeader->nodeNum = 0; } +/*! + * @brief OsAddNode2SortLink 向链表中插入结点,并按时间顺序排列 + * + * @param sortLinkHeader 被插入的链表 + * @param sortList 要插入的结点 + * @return + * + * @see + */ STATIC INLINE VOID AddNode2SortLink(SortLinkAttribute *sortLinkHeader, SortLinkList *sortList) { - LOS_DL_LIST *head = (LOS_DL_LIST *)&sortLinkHeader->sortLink; + LOS_DL_LIST *head = (LOS_DL_LIST *)&sortLinkHeader->sortLink; //获取双向链表 - if (LOS_ListEmpty(head)) { - LOS_ListHeadInsert(head, &sortList->sortLinkNode); - sortLinkHeader->nodeNum++; + if (LOS_ListEmpty(head)) { //空链表,直接插入 + LOS_ListHeadInsert(head, &sortList->sortLinkNode);//插入结点 + sortLinkHeader->nodeNum++;//CPU的工作量增加了 return; } - + //链表不为空时,插入分三种情况, responseTime 大于,等于,小于的处理 SortLinkList *listSorted = LOS_DL_LIST_ENTRY(head->pstNext, SortLinkList, sortLinkNode); - if (listSorted->responseTime > sortList->responseTime) { - LOS_ListAdd(head, &sortList->sortLinkNode); - sortLinkHeader->nodeNum++; - return; - } else if (listSorted->responseTime == sortList->responseTime) { - LOS_ListAdd(head->pstNext, &sortList->sortLinkNode); + if (listSorted->responseTime > sortList->responseTime) {//如果要插入的节点 responseTime 最小 + LOS_ListAdd(head, &sortList->sortLinkNode);//能跑进来说明是最小的,直接插入到第一的位置 + sortLinkHeader->nodeNum++;//CPU的工作量增加了 + return;//直接返回了 + } else if (listSorted->responseTime == sortList->responseTime) {//相等的情况 + LOS_ListAdd(head->pstNext, &sortList->sortLinkNode);//插到第二的位置 sortLinkHeader->nodeNum++; return; } - - LOS_DL_LIST *prevNode = head->pstPrev; - do { - listSorted = LOS_DL_LIST_ENTRY(prevNode, SortLinkList, sortLinkNode); - if (listSorted->responseTime <= sortList->responseTime) { + //处理大于链表中第一个responseTime的情况,需要遍历链表 + LOS_DL_LIST *prevNode = head->pstPrev;//注意这里用的前一个结点,也就是说前一个结点中的responseTime 是最大的 + do { // @note_good 这里写的有点妙,也是双向链表的魅力所在 + listSorted = LOS_DL_LIST_ENTRY(prevNode, SortLinkList, sortLinkNode);//一个个遍历,先比大的再比小的 + if (listSorted->responseTime <= sortList->responseTime) {//如果时间比你小,就插到后面 LOS_ListAdd(prevNode, &sortList->sortLinkNode); sortLinkHeader->nodeNum++; break; } - prevNode = prevNode->pstPrev; - } while (1); + prevNode = prevNode->pstPrev;//再拿上一个更小的responseTime进行比较 + } while (1);//死循环 } VOID OsAdd2SortLink(SortLinkAttribute *head, SortLinkList *node, UINT64 responseTime, UINT16 idleCpu) From aa3d9031634e0ef8c52229e74720af02f1f9f893 Mon Sep 17 00:00:00 2001 From: eee <719747958@qq.com> Date: Fri, 19 Jan 2024 19:17:08 +0800 Subject: [PATCH 25/33] =?UTF-8?q?=E7=94=A8=E4=BE=8B=E4=BA=A4=E4=BA=92?= =?UTF-8?q?=E5=9B=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/泛读报告.docx | Bin 157609 -> 219249 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/doc/泛读报告.docx b/doc/泛读报告.docx index 55b9d06314e73d74a5e0a632b315f5841cf9005b..ef36c45c645f80d301921d1cc194a4b8cea642a3 100644 GIT binary patch delta 85098 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 Date: Fri, 19 Jan 2024 23:54:07 +0800 Subject: [PATCH 26/33] something cheaty added --- doc/泛读报告.docx | Bin 219249 -> 388562 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/doc/泛读报告.docx b/doc/泛读报告.docx index ef36c45c645f80d301921d1cc194a4b8cea642a3..4db2a01343b1cd3b246650dbbf1c62c70ebceb5f 100644 GIT binary patch delta 195869 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 z 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 delta 25370 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 From 1bebb56d4659a2897c72e1a4e40aa537ff30f106 Mon Sep 17 00:00:00 2001 From: Dio Date: Sat, 20 Jan 2024 14:45:33 +0800 Subject: [PATCH 27/33] ipc to be continued --- .../kernel/base/ipc/los_event.c | 135 +++++------ .../kernel/base/ipc/los_futex.c | 226 +++++++++--------- 2 files changed, 182 insertions(+), 179 deletions(-) diff --git a/src/kernel_liteos_a/kernel/base/ipc/los_event.c b/src/kernel_liteos_a/kernel/base/ipc/los_event.c index 1503c7fb..ccea383b 100644 --- a/src/kernel_liteos_a/kernel/base/ipc/los_event.c +++ b/src/kernel_liteos_a/kernel/base/ipc/los_event.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -39,8 +39,8 @@ #ifdef LOSCFG_BASE_CORE_SWTMR_ENABLE #include "los_exc.h" #endif -/* -*/ + +/// 初始化一个事件控制块 LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventInit(PEVENT_CB_S eventCB) { UINT32 intSave; @@ -49,14 +49,14 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventInit(PEVENT_CB_S eventCB) return LOS_ERRNO_EVENT_PTR_NULL; } - intSave = LOS_IntLock(); - eventCB->uwEventID = 0; - LOS_ListInit(&eventCB->stEventList); - LOS_IntRestore(intSave); + intSave = LOS_IntLock();//锁中断 + eventCB->uwEventID = 0;//事件类型初始化 + LOS_ListInit(&eventCB->stEventList);//事件链表初始化 + LOS_IntRestore(intSave);//恢复中断 OsHookCall(LOS_HOOK_TYPE_EVENT_INIT, eventCB); return LOS_OK; } - +///事件参数检查 LITE_OS_SEC_TEXT STATIC UINT32 OsEventParamCheck(const VOID *ptr, UINT32 eventMask, UINT32 mode) { if (ptr == NULL) { @@ -78,52 +78,53 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsEventParamCheck(const VOID *ptr, UINT32 eventMa } return LOS_OK; } - +///根据用户传入的事件值、事件掩码及校验模式,返回用户传入的事件是否符合预期 LITE_OS_SEC_TEXT UINT32 OsEventPoll(UINT32 *eventID, UINT32 eventMask, UINT32 mode) { UINT32 ret = 0; - LOS_ASSERT(OsIntLocked()); - LOS_ASSERT(LOS_SpinHeld(&g_taskSpin)); + LOS_ASSERT(OsIntLocked());//断言不允许中断了 + LOS_ASSERT(LOS_SpinHeld(&g_taskSpin));//任务自旋锁 - if (mode & LOS_WAITMODE_OR) { + if (mode & LOS_WAITMODE_OR) {//如果模式是读取掩码中任意事件 if ((*eventID & eventMask) != 0) { ret = *eventID & eventMask; } - } else { - if ((eventMask != 0) && (eventMask == (*eventID & eventMask))) { + } else {//等待全部事件发生 + if ((eventMask != 0) && (eventMask == (*eventID & eventMask))) {//必须满足全部事件发生 ret = *eventID & eventMask; } } - if (ret && (mode & LOS_WAITMODE_CLR)) { + if (ret && (mode & LOS_WAITMODE_CLR)) {//读取完成后清除事件 *eventID = *eventID & ~ret; } return ret; } - +///检查读事件 LITE_OS_SEC_TEXT STATIC UINT32 OsEventReadCheck(const PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode) { UINT32 ret; LosTaskCB *runTask = NULL; - ret = OsEventParamCheck(eventCB, eventMask, mode); + + ret = OsEventParamCheck(eventCB, eventMask, mode);//事件参数检查 if (ret != LOS_OK) { return ret; } - if (OS_INT_ACTIVE) { - return LOS_ERRNO_EVENT_READ_IN_INTERRUPT; + if (OS_INT_ACTIVE) {//中断正在进行 + return LOS_ERRNO_EVENT_READ_IN_INTERRUPT;//不能在中断发送时读事件 } - runTask = OsCurrTaskGet(); - if (runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) { + runTask = OsCurrTaskGet();//获取当前任务 + if (runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) {//任务属于系统任务 OsBackTrace(); - return LOS_ERRNO_EVENT_READ_IN_SYSTEM_TASK; + return LOS_ERRNO_EVENT_READ_IN_SYSTEM_TASK;//不能在系统任务中读取事件 } return LOS_OK; } - +/// 读取指定事件类型的实现函数,超时时间为相对时间:单位为Tick LITE_OS_SEC_TEXT STATIC UINT32 OsEventReadImp(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeout, BOOL once) { @@ -132,57 +133,57 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsEventReadImp(PEVENT_CB_S eventCB, UINT32 eventM OsHookCall(LOS_HOOK_TYPE_EVENT_READ, eventCB, eventMask, mode, timeout); if (once == FALSE) { - ret = OsEventPoll(&eventCB->uwEventID, eventMask, mode); + ret = OsEventPoll(&eventCB->uwEventID, eventMask, mode);//检测事件是否符合预期 } - if (ret == 0) { - if (timeout == 0) { + if (ret == 0) {//不符合预期时 + if (timeout == 0) {//不等待的情况 return ret; } - if (!OsPreemptableInSched()) { + if (!OsPreemptableInSched()) {//不能抢占式调度 return LOS_ERRNO_EVENT_READ_IN_LOCK; } - runTask->eventMask = eventMask; - runTask->eventMode = mode; - runTask->taskEvent = eventCB; - OsTaskWaitSetPendMask(OS_TASK_WAIT_EVENT, eventMask, timeout); + runTask->eventMask = eventMask; //等待事件 + runTask->eventMode = mode; //事件模式 + runTask->taskEvent = eventCB; //事件控制块 + OsTaskWaitSetPendMask(OS_TASK_WAIT_EVENT, eventMask, timeout);//任务进入等待状态,等待事件的到来并设置时长和掩码 ret = runTask->ops->wait(runTask, &eventCB->stEventList, timeout); if (ret == LOS_ERRNO_TSK_TIMEOUT) { return LOS_ERRNO_EVENT_READ_TIMEOUT; } - ret = OsEventPoll(&eventCB->uwEventID, eventMask, mode); + ret = OsEventPoll(&eventCB->uwEventID, eventMask, mode);//检测事件是否符合预期 } return ret; } - +///读取指定事件类型,超时时间为相对时间:单位为Tick LITE_OS_SEC_TEXT STATIC UINT32 OsEventRead(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeout, BOOL once) { UINT32 ret; UINT32 intSave; - ret = OsEventReadCheck(eventCB, eventMask, mode); + ret = OsEventReadCheck(eventCB, eventMask, mode);//读取事件检查 if (ret != LOS_OK) { return ret; } SCHEDULER_LOCK(intSave); - ret = OsEventReadImp(eventCB, eventMask, mode, timeout, once); + ret = OsEventReadImp(eventCB, eventMask, mode, timeout, once);//读事件实现函数 SCHEDULER_UNLOCK(intSave); return ret; } - +///事件恢复操作 LITE_OS_SEC_TEXT STATIC UINT8 OsEventResume(LosTaskCB *resumedTask, const PEVENT_CB_S eventCB, UINT32 events) { - UINT8 exitFlag = 0; + UINT8 exitFlag = 0;//是否唤醒 if (((resumedTask->eventMode & LOS_WAITMODE_OR) && ((resumedTask->eventMask & events) != 0)) || ((resumedTask->eventMode & LOS_WAITMODE_AND) && - ((resumedTask->eventMask & eventCB->uwEventID) == resumedTask->eventMask))) { - exitFlag = 1; + ((resumedTask->eventMask & eventCB->uwEventID) == resumedTask->eventMask))) {//逻辑与 和 逻辑或 的处理 + exitFlag = 1; resumedTask->taskEvent = NULL; OsTaskWakeClearPendMask(resumedTask); @@ -191,33 +192,33 @@ LITE_OS_SEC_TEXT STATIC UINT8 OsEventResume(LosTaskCB *resumedTask, const PEVENT return exitFlag; } - +///以不安全的方式写事件 LITE_OS_SEC_TEXT VOID OsEventWriteUnsafe(PEVENT_CB_S eventCB, UINT32 events, BOOL once, UINT8 *exitFlag) { LosTaskCB *resumedTask = NULL; LosTaskCB *nextTask = NULL; BOOL schedFlag = FALSE; OsHookCall(LOS_HOOK_TYPE_EVENT_WRITE, eventCB, events); - eventCB->uwEventID |= events; - if (!LOS_ListEmpty(&eventCB->stEventList)) { + eventCB->uwEventID |= events;//对应位贴上标签 + if (!LOS_ListEmpty(&eventCB->stEventList)) {//等待事件链表判断,处理等待事件的任务 for (resumedTask = LOS_DL_LIST_ENTRY((&eventCB->stEventList)->pstNext, LosTaskCB, pendList); - &resumedTask->pendList != &eventCB->stEventList;) { - nextTask = LOS_DL_LIST_ENTRY(resumedTask->pendList.pstNext, LosTaskCB, pendList); - if (OsEventResume(resumedTask, eventCB, events)) { - schedFlag = TRUE; + &resumedTask->pendList != &eventCB->stEventList;) {//循环获取任务链表 + nextTask = LOS_DL_LIST_ENTRY(resumedTask->pendList.pstNext, LosTaskCB, pendList);//获取任务实体 + if (OsEventResume(resumedTask, eventCB, events)) {//是否恢复任务 + schedFlag = TRUE;//任务已加至就绪队列,申请发生一次调度 } - if (once == TRUE) { - break; + if (once == TRUE) {//是否只处理一次任务 + break;//退出循环 } - resumedTask = nextTask; + resumedTask = nextTask;//检查链表中下一个任务 } } - if ((exitFlag != NULL) && (schedFlag == TRUE)) { + if ((exitFlag != NULL) && (schedFlag == TRUE)) {//是否让外面调度 *exitFlag = 1; } } - +///写入事件 LITE_OS_SEC_TEXT STATIC UINT32 OsEventWrite(PEVENT_CB_S eventCB, UINT32 events, BOOL once) { UINT32 intSave; @@ -231,54 +232,54 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsEventWrite(PEVENT_CB_S eventCB, UINT32 events, return LOS_ERRNO_EVENT_SETBIT_INVALID; } - SCHEDULER_LOCK(intSave); - OsEventWriteUnsafe(eventCB, events, once, &exitFlag); - SCHEDULER_UNLOCK(intSave); + SCHEDULER_LOCK(intSave); //禁止调度 + OsEventWriteUnsafe(eventCB, events, once, &exitFlag);//写入事件 + SCHEDULER_UNLOCK(intSave); //允许调度 - if (exitFlag == 1) { - LOS_MpSchedule(OS_MP_CPU_ALL); - LOS_Schedule(); + if (exitFlag == 1) { //需要发生调度 + LOS_MpSchedule(OS_MP_CPU_ALL);//通知所有CPU调度 + LOS_Schedule();//执行调度 } return LOS_OK; } - +///根据用户传入的事件值、事件掩码及校验模式,返回用户传入的事件是否符合预期 LITE_OS_SEC_TEXT UINT32 LOS_EventPoll(UINT32 *eventID, UINT32 eventMask, UINT32 mode) { UINT32 ret; UINT32 intSave; - + //事件参数检查 ret = OsEventParamCheck((VOID *)eventID, eventMask, mode); if (ret != LOS_OK) { return ret; } - SCHEDULER_LOCK(intSave); + SCHEDULER_LOCK(intSave);//申请任务自旋锁 ret = OsEventPoll(eventID, eventMask, mode); SCHEDULER_UNLOCK(intSave); return ret; } - +///读取指定事件类型,超时时间为相对时间:单位为Tick LITE_OS_SEC_TEXT UINT32 LOS_EventRead(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeout) { return OsEventRead(eventCB, eventMask, mode, timeout, FALSE); } - +///写指定的事件类型 LITE_OS_SEC_TEXT UINT32 LOS_EventWrite(PEVENT_CB_S eventCB, UINT32 events) { return OsEventWrite(eventCB, events, FALSE); } - +///只读一次事件 LITE_OS_SEC_TEXT_MINOR UINT32 OsEventReadOnce(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeout) { return OsEventRead(eventCB, eventMask, mode, timeout, TRUE); } - +///只写一次事件 LITE_OS_SEC_TEXT_MINOR UINT32 OsEventWriteOnce(PEVENT_CB_S eventCB, UINT32 events) { return OsEventWrite(eventCB, events, TRUE); } - +///销毁指定的事件控制块 LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventDestroy(PEVENT_CB_S eventCB) { UINT32 intSave; @@ -299,7 +300,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventDestroy(PEVENT_CB_S eventCB) OsHookCall(LOS_HOOK_TYPE_EVENT_DESTROY, eventCB); return LOS_OK; } - +///清除指定的事件类型 LITE_OS_SEC_TEXT_MINOR UINT32 LOS_EventClear(PEVENT_CB_S eventCB, UINT32 eventMask) { UINT32 intSave; @@ -314,7 +315,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_EventClear(PEVENT_CB_S eventCB, UINT32 eventMa return LOS_OK; } - +///有条件式读事件 #ifdef LOSCFG_COMPAT_POSIX LITE_OS_SEC_TEXT UINT32 OsEventReadWithCond(const EventCond *cond, PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeout) diff --git a/src/kernel_liteos_a/kernel/base/ipc/los_futex.c b/src/kernel_liteos_a/kernel/base/ipc/los_futex.c index 384bb483..ea69c554 100644 --- a/src/kernel_liteos_a/kernel/base/ipc/los_futex.c +++ b/src/kernel_liteos_a/kernel/base/ipc/los_futex.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -43,28 +43,30 @@ #ifdef LOSCFG_KERNEL_VM -#define OS_FUTEX_FROM_FUTEXLIST(ptr) LOS_DL_LIST_ENTRY(ptr, FutexNode, futexList) -#define OS_FUTEX_FROM_QUEUELIST(ptr) LOS_DL_LIST_ENTRY(ptr, FutexNode, queueList) -#define OS_FUTEX_KEY_BASE USER_ASPACE_BASE -#define OS_FUTEX_KEY_MAX (USER_ASPACE_BASE + USER_ASPACE_SIZE) +#define OS_FUTEX_FROM_FUTEXLIST(ptr) LOS_DL_LIST_ENTRY(ptr, FutexNode, futexList) // 通过快锁节点找到结构体 +#define OS_FUTEX_FROM_QUEUELIST(ptr) LOS_DL_LIST_ENTRY(ptr, FutexNode, queueList) // 通过队列节点找到结构体 +#define OS_FUTEX_KEY_BASE USER_ASPACE_BASE ///< 进程用户空间基址 +#define OS_FUTEX_KEY_MAX (USER_ASPACE_BASE + USER_ASPACE_SIZE) ///< 进程用户空间尾址 /* private: 0~63 hash index_num * shared: 64~79 hash index_num */ -#define FUTEX_INDEX_PRIVATE_MAX 64 -#define FUTEX_INDEX_SHARED_MAX 16 -#define FUTEX_INDEX_MAX (FUTEX_INDEX_PRIVATE_MAX + FUTEX_INDEX_SHARED_MAX) +#define FUTEX_INDEX_PRIVATE_MAX 64 ///< 0~63号桶用于存放私有锁(以虚拟地址进行哈希),同一进程不同线程共享futex变量,表明变量在进程地址空间中的位置 +///< 它告诉内核,这个futex是进程专有的,不可以与其他进程共享。它仅仅用作同一进程的线程间同步。 +#define FUTEX_INDEX_SHARED_MAX 16 ///< 64~79号桶用于存放共享锁(以物理地址进行哈希),不同进程间通过文件共享futex变量,表明该变量在文件中的位置 +#define FUTEX_INDEX_MAX (FUTEX_INDEX_PRIVATE_MAX + FUTEX_INDEX_SHARED_MAX) ///< 80个哈希桶 -#define FUTEX_INDEX_SHARED_POS FUTEX_INDEX_PRIVATE_MAX +#define FUTEX_INDEX_SHARED_POS FUTEX_INDEX_PRIVATE_MAX ///< 共享锁开始位置 #define FUTEX_HASH_PRIVATE_MASK (FUTEX_INDEX_PRIVATE_MAX - 1) #define FUTEX_HASH_SHARED_MASK (FUTEX_INDEX_SHARED_MAX - 1) - +/// 单独哈希桶,上面挂了一个个 FutexNode typedef struct { - LosMux listLock; - LOS_DL_LIST lockList; + LosMux listLock;///< 内核操作lockList的互斥锁 + LOS_DL_LIST lockList;///< 用于挂载 FutexNode (Fast userspace mutex,用户态快速互斥锁) } FutexHash; -FutexHash g_futexHash[FUTEX_INDEX_MAX]; +FutexHash g_futexHash[FUTEX_INDEX_MAX];///< 80个哈希桶 +/// 对互斥锁封装 STATIC INT32 OsFutexLock(LosMux *lock) { UINT32 ret = LOS_MuxLock(lock, LOS_WAIT_FOREVER); @@ -84,15 +86,15 @@ STATIC INT32 OsFutexUnlock(LosMux *lock) } return LOS_OK; } - +///< 初始化Futex(Fast userspace mutex,用户态快速互斥锁)模块 UINT32 OsFutexInit(VOID) { INT32 count; UINT32 ret; - + // 初始化 80个哈希桶 for (count = 0; count < FUTEX_INDEX_MAX; count++) { - LOS_ListInit(&g_futexHash[count].lockList); - ret = LOS_MuxInit(&(g_futexHash[count].listLock), NULL); + LOS_ListInit(&g_futexHash[count].lockList); // 初始化双向链表,上面挂 FutexNode + ret = LOS_MuxInit(&(g_futexHash[count].listLock), NULL);//初始化互斥锁 if (ret) { return ret; } @@ -101,7 +103,7 @@ UINT32 OsFutexInit(VOID) return LOS_OK; } -LOS_MODULE_INIT(OsFutexInit, LOS_INIT_LEVEL_KMOD_EXTENDED); +LOS_MODULE_INIT(OsFutexInit, LOS_INIT_LEVEL_KMOD_EXTENDED);///< 注册Futex模块 #ifdef LOS_FUTEX_DEBUG STATIC VOID OsFutexShowTaskNodeAttr(const LOS_DL_LIST *futexList) @@ -152,63 +154,63 @@ VOID OsFutexHashShow(VOID) } } #endif - +/// 通过用户空间地址获取哈希key STATIC INLINE UINTPTR OsFutexFlagsToKey(const UINT32 *userVaddr, const UINT32 flags) { UINTPTR futexKey; if (flags & FUTEX_PRIVATE) { - futexKey = (UINTPTR)userVaddr; + futexKey = (UINTPTR)userVaddr;//私有锁(以虚拟地址进行哈希) } else { - futexKey = (UINTPTR)LOS_PaddrQuery((UINT32 *)userVaddr); + futexKey = (UINTPTR)LOS_PaddrQuery((UINT32 *)userVaddr);//共享锁(以物理地址进行哈希) } return futexKey; } - +/// 通过哈希key获取索引 STATIC INLINE UINT32 OsFutexKeyToIndex(const UINTPTR futexKey, const UINT32 flags) { - UINT32 index = LOS_HashFNV32aBuf(&futexKey, sizeof(UINTPTR), FNV1_32A_INIT); + UINT32 index = LOS_HashFNV32aBuf(&futexKey, sizeof(UINTPTR), FNV1_32A_INIT);//获取哈希桶索引 if (flags & FUTEX_PRIVATE) { - index &= FUTEX_HASH_PRIVATE_MASK; + index &= FUTEX_HASH_PRIVATE_MASK;//将index锁定在 0 ~ 63号 } else { index &= FUTEX_HASH_SHARED_MASK; - index += FUTEX_INDEX_SHARED_POS; + index += FUTEX_INDEX_SHARED_POS;//共享锁索引,将index锁定在 64 ~ 79号 } return index; } - +/// 设置快锁哈希key STATIC INLINE VOID OsFutexSetKey(UINTPTR futexKey, UINT32 flags, FutexNode *node) { - node->key = futexKey; - node->index = OsFutexKeyToIndex(futexKey, flags); - node->pid = (flags & FUTEX_PRIVATE) ? LOS_GetCurrProcessID() : OS_INVALID; + node->key = futexKey;//哈希key + node->index = OsFutexKeyToIndex(futexKey, flags);//哈希桶索引 + node->pid = (flags & FUTEX_PRIVATE) ? LOS_GetCurrProcessID() : OS_INVALID;//获取进程ID,共享快锁时 快锁节点没有进程ID } - +//析构参数节点 STATIC INLINE VOID OsFutexDeinitFutexNode(FutexNode *node) { node->index = OS_INVALID_VALUE; node->pid = 0; LOS_ListDelete(&node->queueList); } - +/// 新旧两个节点交换 futexList 位置 STATIC INLINE VOID OsFutexReplaceQueueListHeadNode(FutexNode *oldHeadNode, FutexNode *newHeadNode) { LOS_DL_LIST *futexList = oldHeadNode->futexList.pstPrev; - LOS_ListDelete(&oldHeadNode->futexList); - LOS_ListHeadInsert(futexList, &newHeadNode->futexList); - if ((newHeadNode->queueList.pstNext == NULL) || (newHeadNode->queueList.pstPrev == NULL)) { - LOS_ListInit(&newHeadNode->queueList); + LOS_ListDelete(&oldHeadNode->futexList);//将旧节点从futexList链表上摘除 + LOS_ListHeadInsert(futexList, &newHeadNode->futexList);//将新节点从头部插入futexList链表 + if ((newHeadNode->queueList.pstNext == NULL) || (newHeadNode->queueList.pstPrev == NULL)) {//新节点前后没有等待这把锁的任务 + LOS_ListInit(&newHeadNode->queueList);//初始化等锁任务链表 } } - +/// 将参数节点从futexList上摘除 STATIC INLINE VOID OsFutexDeleteKeyFromFutexList(FutexNode *node) { LOS_ListDelete(&node->futexList); } - +/// 从哈希桶中删除快锁节点 STATIC VOID OsFutexDeleteKeyNodeFromHash(FutexNode *node, BOOL isDeleteHead, FutexNode **headNode, BOOL *queueFlags) { FutexNode *nextNode = NULL; @@ -217,8 +219,8 @@ STATIC VOID OsFutexDeleteKeyNodeFromHash(FutexNode *node, BOOL isDeleteHead, Fut return; } - if (LOS_ListEmpty(&node->queueList)) { - OsFutexDeleteKeyFromFutexList(node); + if (LOS_ListEmpty(&node->queueList)) {//如果没有任务在等锁 + OsFutexDeleteKeyFromFutexList(node);//从快锁链表上摘除 if (queueFlags != NULL) { *queueFlags = TRUE; } @@ -226,10 +228,10 @@ STATIC VOID OsFutexDeleteKeyNodeFromHash(FutexNode *node, BOOL isDeleteHead, Fut } /* FutexList is not NULL, but the header node of queueList */ - if (node->futexList.pstNext != NULL) { - if (isDeleteHead == TRUE) { - nextNode = OS_FUTEX_FROM_QUEUELIST(LOS_DL_LIST_FIRST(&node->queueList)); - OsFutexReplaceQueueListHeadNode(node, nextNode); + if (node->futexList.pstNext != NULL) {//是头节点 + if (isDeleteHead == TRUE) {//是否要删除头节点 + nextNode = OS_FUTEX_FROM_QUEUELIST(LOS_DL_LIST_FIRST(&node->queueList));//取出第一个快锁节点 + OsFutexReplaceQueueListHeadNode(node, nextNode);//两个节点交换位置 if (headNode != NULL) { *headNode = nextNode; } @@ -242,22 +244,22 @@ EXIT: OsFutexDeinitFutexNode(node); return; } - +/// 从哈希桶上删除快锁 VOID OsFutexNodeDeleteFromFutexHash(FutexNode *node, BOOL isDeleteHead, FutexNode **headNode, BOOL *queueFlags) { FutexHash *hashNode = NULL; - + //通过key找到桶号 UINT32 index = OsFutexKeyToIndex(node->key, (node->pid == OS_INVALID) ? 0 : FUTEX_PRIVATE); if (index >= FUTEX_INDEX_MAX) { return; } - hashNode = &g_futexHash[index]; + hashNode = &g_futexHash[index];//找到hash桶 if (OsMuxLockUnsafe(&hashNode->listLock, LOS_WAIT_FOREVER)) { return; } - if (node->index != index) { + if (node->index != index) {//快锁节点桶号需和哈希桶号一致 goto EXIT; } @@ -270,7 +272,6 @@ EXIT: return; } - STATIC FutexNode *OsFutexDeleteAlreadyWakeTaskAndGetNext(const FutexNode *node, FutexNode **headNode, BOOL isDeleteHead) { FutexNode *tempNode = (FutexNode *)node; @@ -292,7 +293,7 @@ STATIC FutexNode *OsFutexDeleteAlreadyWakeTaskAndGetNext(const FutexNode *node, return tempNode; } - +/// 插入一把新Futex锁到哈希桶中,只有是新的key时才会插入,因为其实存在多个FutexNode是一个key STATIC VOID OsFutexInsertNewFutexKeyToHash(FutexNode *node) { FutexNode *headNode = NULL; @@ -322,16 +323,16 @@ STATIC VOID OsFutexInsertNewFutexKeyToHash(FutexNode *node) futexList != &(hashNode->lockList); futexList = futexList->pstNext) { headNode = OS_FUTEX_FROM_FUTEXLIST(futexList); - if (node->key <= headNode->key) { + if (node->key <= headNode->key) { LOS_ListTailInsert(&(headNode->futexList), &(node->futexList)); break; } + } EXIT: return; } - STATIC INT32 OsFutexInsertFindFormBackToFront(LOS_DL_LIST *queueList, const LosTaskCB *runTask, FutexNode *node) { LOS_DL_LIST *listHead = queueList; @@ -407,55 +408,54 @@ STATIC INT32 OsFutexRecycleAndFindHeadNode(FutexNode *headNode, FutexNode *node, return LOS_OK; } - +///< 将快锁挂到任务的阻塞链表上 STATIC INT32 OsFutexInsertTasktoPendList(FutexNode **firstNode, FutexNode *node, const LosTaskCB *run) { - LosTaskCB *taskHead = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&((*firstNode)->pendList))); + LosTaskCB *taskHead = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&((*firstNode)->pendList)));//获取阻塞链表首个任务 LOS_DL_LIST *queueList = &((*firstNode)->queueList); INT32 ret1 = OsSchedParamCompare(run, taskHead); if (ret1 < 0) { /* The one with the highest priority is inserted at the top of the queue */ - LOS_ListTailInsert(queueList, &(node->queueList)); - OsFutexReplaceQueueListHeadNode(*firstNode, node); + LOS_ListTailInsert(queueList, &(node->queueList));//查到queueList的尾部 + OsFutexReplaceQueueListHeadNode(*firstNode, node);//同时交换futexList链表上的位置 *firstNode = node; return LOS_OK; } - + //如果等锁链表上没有任务或者当前任务大于链表首个任务 if (LOS_ListEmpty(queueList) && (ret1 >= 0)) { /* Insert the next position in the queue with equal priority */ - LOS_ListHeadInsert(queueList, &(node->queueList)); + LOS_ListHeadInsert(queueList, &(node->queueList));//从头部插入当前任务,当前任务是要被挂起的 return LOS_OK; } - - FutexNode *tailNode = OS_FUTEX_FROM_QUEUELIST(LOS_DL_LIST_LAST(queueList)); - LosTaskCB *taskTail = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(tailNode->pendList))); + + FutexNode *tailNode = OS_FUTEX_FROM_QUEUELIST(LOS_DL_LIST_LAST(queueList));//获取尾部节点 + LosTaskCB *taskTail = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(tailNode->pendList)));//获取阻塞任务的最后一个 INT32 ret2 = OsSchedParamCompare(taskTail, run); if ((ret2 <= 0) || (ret1 > ret2)) { - return OsFutexInsertFindFormBackToFront(queueList, run, node); + return OsFutexInsertFindFormBackToFront(queueList, run, node);//从后往前插入 } - return OsFutexInsertFindFromFrontToBack(queueList, run, node); + return OsFutexInsertFindFromFrontToBack(queueList, run, node);//否则从前往后插入 } - +/// 由指定快锁找到对应哈希桶 STATIC FutexNode *OsFindFutexNode(const FutexNode *node) { - FutexHash *hashNode = &g_futexHash[node->index]; + FutexHash *hashNode = &g_futexHash[node->index];//先找到所在哈希桶 LOS_DL_LIST *futexList = &(hashNode->lockList); FutexNode *headNode = NULL; for (futexList = futexList->pstNext; - futexList != &(hashNode->lockList); + futexList != &(hashNode->lockList);//判断循环结束条件,相等时说明跑完一轮了 futexList = futexList->pstNext) { - headNode = OS_FUTEX_FROM_FUTEXLIST(futexList); - if ((headNode->key == node->key) && (headNode->pid == node->pid)) { - return headNode; - } + headNode = OS_FUTEX_FROM_FUTEXLIST(futexList);//拿到快锁节点实体 + if ((headNode->key == node->key) && (headNode->pid == node->pid)) {//已经存在这个节点,注意这里的比较 + return headNode;//是key和pid 一起比较,因为只有这样才能确定唯一性 } return NULL; } - +///< 查找快锁并插入哈希桶中 STATIC INT32 OsFindAndInsertToHash(FutexNode *node) { FutexNode *headNode = NULL; @@ -464,7 +464,7 @@ STATIC INT32 OsFindAndInsertToHash(FutexNode *node) INT32 ret; headNode = OsFindFutexNode(node); - if (headNode == NULL) { + if (headNode == NULL) {//没有找到,说明这是一把新锁 OsFutexInsertNewFutexKeyToHash(node); LOS_ListInit(&(node->queueList)); return LOS_OK; @@ -483,14 +483,14 @@ STATIC INT32 OsFindAndInsertToHash(FutexNode *node) return ret; } - +/// 共享内存检查 STATIC INT32 OsFutexKeyShmPermCheck(const UINT32 *userVaddr, const UINT32 flags) { PADDR_T paddr; /* Check whether the futexKey is a shared lock */ - if (!(flags & FUTEX_PRIVATE)) { - paddr = (UINTPTR)LOS_PaddrQuery((UINT32 *)userVaddr); + if (!(flags & FUTEX_PRIVATE)) {//非私有快锁 + paddr = (UINTPTR)LOS_PaddrQuery((UINT32 *)userVaddr);//能否查询到物理地址 if (paddr == 0) return LOS_NOK; } @@ -549,13 +549,13 @@ STATIC INT32 OsFutexDeleteTimeoutTaskNode(FutexHash *hashNode, FutexNode *node) } return LOS_ETIMEDOUT; } - +/// 将快锁节点插入任务 STATIC INT32 OsFutexInsertTaskToHash(LosTaskCB **taskCB, FutexNode **node, const UINTPTR futexKey, const UINT32 flags) { INT32 ret; - *taskCB = OsCurrTaskGet(); - *node = &((*taskCB)->futex); - OsFutexSetKey(futexKey, flags, *node); + *taskCB = OsCurrTaskGet(); //获取当前任务 + *node = &((*taskCB)->futex); //获取当前任务的快锁节点 + OsFutexSetKey(futexKey, flags, *node);//设置参数 key index pid ret = OsFindAndInsertToHash(*node); if (ret) { @@ -565,33 +565,33 @@ STATIC INT32 OsFutexInsertTaskToHash(LosTaskCB **taskCB, FutexNode **node, const LOS_ListInit(&((*node)->pendList)); return LOS_OK; } - +/// 将当前任务挂入等待链表中 STATIC INT32 OsFutexWaitTask(const UINT32 *userVaddr, const UINT32 flags, const UINT32 val, const UINT32 timeout) { INT32 futexRet; UINT32 intSave, lockVal; LosTaskCB *taskCB = NULL; FutexNode *node = NULL; - UINTPTR futexKey = OsFutexFlagsToKey(userVaddr, flags); - UINT32 index = OsFutexKeyToIndex(futexKey, flags); + UINTPTR futexKey = OsFutexFlagsToKey(userVaddr, flags);//通过地址和flags 找到 key + UINT32 index = OsFutexKeyToIndex(futexKey, flags);//通过key找到哈希桶 FutexHash *hashNode = &g_futexHash[index]; - if (OsFutexLock(&hashNode->listLock)) { + if (OsFutexLock(&hashNode->listLock)) {//操作快锁节点链表前先上互斥锁 return LOS_EINVAL; } - - if (LOS_ArchCopyFromUser(&lockVal, userVaddr, sizeof(UINT32))) { + //userVaddr必须是用户空间虚拟地址 + if (LOS_ArchCopyFromUser(&lockVal, userVaddr, sizeof(UINT32))) {//将值拷贝到内核空间 PRINT_ERR("Futex wait param check failed! copy from user failed!\n"); futexRet = LOS_EINVAL; goto EXIT_ERR; } - if (lockVal != val) { + if (lockVal != val) {//对参数内部逻辑检查 futexRet = LOS_EBADF; goto EXIT_ERR; } - - if (OsFutexInsertTaskToHash(&taskCB, &node, futexKey, flags)) { + //注意第二个参数 FutexNode *node = NULL + if (OsFutexInsertTaskToHash(&taskCB, &node, futexKey, flags)) {// node = taskCB->futex futexRet = LOS_NOK; goto EXIT_ERR; } @@ -602,7 +602,7 @@ STATIC INT32 OsFutexWaitTask(const UINT32 *userVaddr, const UINT32 flags, const taskCB->ops->wait(taskCB, &(node->pendList), timeout); LOS_SpinUnlock(&g_taskSpin); - futexRet = OsFutexUnlock(&hashNode->listLock); + futexRet = OsFutexUnlock(&hashNode->listLock);// if (futexRet) { OsSchedUnlock(); LOS_IntRestore(intSave); @@ -632,21 +632,21 @@ EXIT_ERR: EXIT_UNLOCK_ERR: return futexRet; } - +/// 设置线程等待 | 向Futex表中插入代表被阻塞的线程的node INT32 OsFutexWait(const UINT32 *userVaddr, UINT32 flags, UINT32 val, UINT32 absTime) { INT32 ret; UINT32 timeout = LOS_WAIT_FOREVER; - ret = OsFutexWaitParamCheck(userVaddr, flags, absTime); + ret = OsFutexWaitParamCheck(userVaddr, flags, absTime);//参数检查 if (ret) { return ret; } - if (absTime != LOS_WAIT_FOREVER) { - timeout = OsNS2Tick((UINT64)absTime * OS_SYS_NS_PER_US); + if (absTime != LOS_WAIT_FOREVER) {//转换时间 , 内核的时间单位是 tick + timeout = OsNS2Tick((UINT64)absTime * OS_SYS_NS_PER_US); //转成 tick } - return OsFutexWaitTask(userVaddr, flags, val, timeout); + return OsFutexWaitTask(userVaddr, flags, val, timeout);//将任务挂起 timeOut 时长 } STATIC INT32 OsFutexWakeParamCheck(const UINT32 *userVaddr, UINT32 flags) @@ -657,12 +657,12 @@ STATIC INT32 OsFutexWakeParamCheck(const UINT32 *userVaddr, UINT32 flags) PRINT_ERR("Futex wake param check failed! error flags: 0x%x\n", flags); return LOS_EINVAL; } - + //地址必须在用户空间 if ((vaddr % sizeof(INT32)) || (vaddr < OS_FUTEX_KEY_BASE) || (vaddr >= OS_FUTEX_KEY_MAX)) { PRINT_ERR("Futex wake param check failed! error userVaddr: 0x%x\n", userVaddr); return LOS_EINVAL; } - + //必须得是个共享内存地址 if (flags && (OsFutexKeyShmPermCheck(userVaddr, flags) != LOS_OK)) { PRINT_ERR("Futex wake param check failed! error shared memory perm userVaddr: 0x%x\n", userVaddr); return LOS_EINVAL; @@ -672,7 +672,8 @@ STATIC INT32 OsFutexWakeParamCheck(const UINT32 *userVaddr, UINT32 flags) } /* Check to see if the task to be awakened has timed out - * if time out, to weak next pend task. + * if time out, to weak next pend task. + * | 查看要唤醒的任务是否超时,如果超时,就唤醒,并查看下一个挂起的任务。 */ STATIC VOID OsFutexCheckAndWakePendTask(FutexNode *headNode, const INT32 wakeNumber, FutexHash *hashNode, FutexNode **nextNode, BOOL *wakeAny) @@ -707,6 +708,7 @@ STATIC VOID OsFutexCheckAndWakePendTask(FutexNode *headNode, const INT32 wakeNum } return; } + STATIC INT32 OsFutexWakeTask(UINTPTR futexKey, UINT32 flags, INT32 wakeNumber, FutexNode **newHeadNode, BOOL *wakeAny) { @@ -715,13 +717,13 @@ STATIC INT32 OsFutexWakeTask(UINTPTR futexKey, UINT32 flags, INT32 wakeNumber, F FutexNode *headNode = NULL; UINT32 index = OsFutexKeyToIndex(futexKey, flags); FutexHash *hashNode = &g_futexHash[index]; - FutexNode tempNode = { + FutexNode tempNode = { //先组成一个临时快锁节点,目的是为了找到哈希桶中是否有这个节点 .key = futexKey, .index = index, .pid = (flags & FUTEX_PRIVATE) ? LOS_GetCurrProcessID() : OS_INVALID, }; - node = OsFindFutexNode(&tempNode); + node = OsFindFutexNode(&tempNode);//找快锁节点 if (node == NULL) { return LOS_EBADF; } @@ -729,7 +731,7 @@ STATIC INT32 OsFutexWakeTask(UINTPTR futexKey, UINT32 flags, INT32 wakeNumber, F headNode = node; SCHEDULER_LOCK(intSave); - OsFutexCheckAndWakePendTask(headNode, wakeNumber, hashNode, newHeadNode, wakeAny); + OsFutexCheckAndWakePendTask(headNode, wakeNumber, hashNode, newHeadNode, wakeAny);//再找到等这把锁的唤醒指向数量的任务 if ((*newHeadNode) != NULL) { OsFutexReplaceQueueListHeadNode(headNode, *newHeadNode); OsFutexDeinitFutexNode(headNode); @@ -741,7 +743,7 @@ STATIC INT32 OsFutexWakeTask(UINTPTR futexKey, UINT32 flags, INT32 wakeNumber, F return LOS_OK; } - +/// 唤醒一个被指定锁阻塞的线程 INT32 OsFutexWake(const UINT32 *userVaddr, UINT32 flags, INT32 wakeNumber) { INT32 ret, futexRet; @@ -750,11 +752,11 @@ INT32 OsFutexWake(const UINT32 *userVaddr, UINT32 flags, INT32 wakeNumber) FutexHash *hashNode = NULL; FutexNode *headNode = NULL; BOOL wakeAny = FALSE; - + //1.检查参数 if (OsFutexWakeParamCheck(userVaddr, flags)) { return LOS_EINVAL; } - + //2.找到指定用户空间地址对应的桶 futexKey = OsFutexFlagsToKey(userVaddr, flags); index = OsFutexKeyToIndex(futexKey, flags); @@ -762,7 +764,7 @@ INT32 OsFutexWake(const UINT32 *userVaddr, UINT32 flags, INT32 wakeNumber) if (OsFutexLock(&hashNode->listLock)) { return LOS_EINVAL; } - + //3.换起等待该锁的进程 ret = OsFutexWakeTask(futexKey, flags, wakeNumber, &headNode, &wakeAny); if (ret) { goto EXIT_ERR; @@ -776,7 +778,7 @@ INT32 OsFutexWake(const UINT32 *userVaddr, UINT32 flags, INT32 wakeNumber) if (futexRet) { goto EXIT_UNLOCK_ERR; } - + //4.根据指定参数决定是否发起调度 if (wakeAny == TRUE) { LOS_MpSchedule(OS_MP_CPU_ALL); LOS_Schedule(); @@ -885,7 +887,7 @@ STATIC VOID OsFutexRequeueSplitTwoLists(FutexHash *oldHashNode, FutexNode *oldHe tailNode->queueList.pstNext = &newHeadNode->queueList; return; } - +/// 删除旧key并获取头节点 STATIC FutexNode *OsFutexRequeueRemoveOldKeyAndGetHead(UINTPTR oldFutexKey, UINT32 flags, INT32 wakeNumber, UINTPTR newFutexKey, INT32 requeueCount, BOOL *wakeAny) { @@ -921,7 +923,7 @@ STATIC FutexNode *OsFutexRequeueRemoveOldKeyAndGetHead(UINTPTR oldFutexKey, UINT return oldHeadNode; } - +/// 检查锁在Futex表中的状态 STATIC INT32 OsFutexRequeueParamCheck(const UINT32 *oldUserVaddr, UINT32 flags, const UINT32 *newUserVaddr) { VADDR_T oldVaddr = (VADDR_T)(UINTPTR)oldUserVaddr; @@ -930,12 +932,12 @@ STATIC INT32 OsFutexRequeueParamCheck(const UINT32 *oldUserVaddr, UINT32 flags, if (oldVaddr == newVaddr) { return LOS_EINVAL; } - + //检查标记 if ((flags & (~FUTEX_PRIVATE)) != FUTEX_REQUEUE) { PRINT_ERR("Futex requeue param check failed! error flags: 0x%x\n", flags); return LOS_EINVAL; } - + //检查地址范围,必须在用户空间 if ((oldVaddr % sizeof(INT32)) || (oldVaddr < OS_FUTEX_KEY_BASE) || (oldVaddr >= OS_FUTEX_KEY_MAX)) { PRINT_ERR("Futex requeue param check failed! error old userVaddr: 0x%x\n", oldUserVaddr); return LOS_EINVAL; @@ -948,7 +950,7 @@ STATIC INT32 OsFutexRequeueParamCheck(const UINT32 *oldUserVaddr, UINT32 flags, return LOS_OK; } - +/// 调整指定锁在Futex表中的位置 INT32 OsFutexRequeue(const UINT32 *userVaddr, UINT32 flags, INT32 wakeNumber, INT32 count, const UINT32 *newUserVaddr) { INT32 ret; @@ -965,12 +967,12 @@ INT32 OsFutexRequeue(const UINT32 *userVaddr, UINT32 flags, INT32 wakeNumber, IN return LOS_EINVAL; } - oldFutexKey = OsFutexFlagsToKey(userVaddr, flags); + oldFutexKey = OsFutexFlagsToKey(userVaddr, flags);//先拿key newFutexKey = OsFutexFlagsToKey(newUserVaddr, flags); - oldIndex = OsFutexKeyToIndex(oldFutexKey, flags); + oldIndex = OsFutexKeyToIndex(oldFutexKey, flags);//再拿所在哈希桶位置,共有80个哈希桶 newIndex = OsFutexKeyToIndex(newFutexKey, flags); - oldHashNode = &g_futexHash[oldIndex]; + oldHashNode = &g_futexHash[oldIndex];//拿到对应哈希桶实体 if (OsFutexLock(&oldHashNode->listLock)) { return LOS_EINVAL; } From 3ca4b7410a9b97f9be794ed56c876a1562986796 Mon Sep 17 00:00:00 2001 From: eee <719747958@qq.com> Date: Mon, 22 Jan 2024 08:12:49 +0800 Subject: [PATCH 28/33] misc content update --- .../kernel/base/misc/kill_shellcmd.c | 17 ++++++++++++ .../kernel/base/misc/los_misc.c | 10 ++++--- .../kernel/base/misc/los_stackinfo.c | 26 ++++++++++++++++++- 3 files changed, 49 insertions(+), 4 deletions(-) diff --git a/src/kernel_liteos_a/kernel/base/misc/kill_shellcmd.c b/src/kernel_liteos_a/kernel/base/misc/kill_shellcmd.c index e21dca7d..c0a7adfb 100644 --- a/src/kernel_liteos_a/kernel/base/misc/kill_shellcmd.c +++ b/src/kernel_liteos_a/kernel/base/misc/kill_shellcmd.c @@ -48,6 +48,23 @@ #include "shell.h" #endif +/********************************************* +命令功能 +命令用于发送特定信号给指定进程。 + +命令格式 +kill [signo | -signo] [pid] + +参数 参数说明 取值范围 +signo 信号ID [1,30] +pid 进程ID [1,MAX_INT] + +须知: signo有效范围为[0,64],建议取值范围为[1,30],其余为保留内容。 + +使用指南 +必须指定发送的信号编号及进程号。 +进程编号取值范围根据系统配置变化,例如系统最大支持pid为256,则取值范围缩小为[1-256]。 +*********************************************/ LITE_OS_SEC_TEXT_MINOR VOID OsPrintKillUsage(VOID) { PRINTK("\nkill: usage: kill [sigspec] [pid]\n"); diff --git a/src/kernel_liteos_a/kernel/base/misc/los_misc.c b/src/kernel_liteos_a/kernel/base/misc/los_misc.c index 05a083ee..f8b7cd85 100644 --- a/src/kernel_liteos_a/kernel/base/misc/los_misc.c +++ b/src/kernel_liteos_a/kernel/base/misc/los_misc.c @@ -31,7 +31,10 @@ #include "los_task_pri.h" - +// 这个函数接受两个参数,一个是地址(addr),另一个是对齐边界(boundary)。它返回一个对齐后的地址。 +// 这个函数首先检查地址加上边界再减去1是否大于地址,如果是, +// 就返回地址加上边界再减去1然后与~((UINTPTR)(boundary - 1))进行位与运算的结果, +// 否则就返回地址与~((UINTPTR)(boundary - 1))进行位与运算的结果。这实际上是在对地址进行对齐。 LITE_OS_SEC_TEXT UINTPTR LOS_Align(UINTPTR addr, UINT32 boundary) { if ((addr + boundary - 1) > addr) { @@ -41,13 +44,14 @@ LITE_OS_SEC_TEXT UINTPTR LOS_Align(UINTPTR addr, UINT32 boundary) } } + LITE_OS_SEC_TEXT_MINOR VOID LOS_Msleep(UINT32 msecs) { UINT32 interval; - + // 这个函数接受一个参数,毫秒数(msecs)。这个函数首先检查毫秒数是否为0,如果是,就将间隔设置为0。 if (msecs == 0) { interval = 0; - } else { + // } else { 否则,它将毫秒数转换为tick数(可能是操作系统的时间单位),如果转换后的间隔为0,就将间隔设置为1。然后,它调用LOS_TaskDelay函数来延迟指定的间隔。 interval = LOS_MS2Tick(msecs); if (interval == 0) { interval = 1; diff --git a/src/kernel_liteos_a/kernel/base/misc/los_stackinfo.c b/src/kernel_liteos_a/kernel/base/misc/los_stackinfo.c index 9eb7a9c0..49c46afd 100644 --- a/src/kernel_liteos_a/kernel/base/misc/los_stackinfo.c +++ b/src/kernel_liteos_a/kernel/base/misc/los_stackinfo.c @@ -37,7 +37,31 @@ #include "shcmd.h" #include "shell.h" #endif - +/** + * @file los_stackinfo.c + * @brief 栈内容 + * @verbatim + @note_pic OsExcStackInfo 各个CPU栈布局图,其他栈也是一样,CPU各核硬件栈都是紧挨着 + __undef_stack(SMP) + +-------------------+ <--- cpu1 top + | | + | CPU core1 | + | | + +--------------------<--- cpu2 top + | | + | cpu core 2 | + | | + +--------------------<--- cpu3 top + | | + | cpu core 3 | + | | + +--------------------<--- cpu4 top + | | + | cpu core 4 | + | | + +-------------------+ + * @endverbatim + */ const StackInfo *g_stackInfo = NULL; ///< CPU所有工作模式的栈信息 UINT32 g_stackNum; ///< CPU所有工作模式的栈数量 From 3e36d446af49adf1b8c433ac3801fb1b00743b1e Mon Sep 17 00:00:00 2001 From: eee <719747958@qq.com> Date: Mon, 22 Jan 2024 10:00:01 +0800 Subject: [PATCH 29/33] =?UTF-8?q?=E8=BD=AF=E4=BB=B6=E4=BD=93=E7=B3=BB?= =?UTF-8?q?=E6=9E=B6=E6=9E=84=E5=9B=BE=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/settings.json | 7 ------- doc/cache/~$$包图.~vsdx | Bin 0 -> 4096 bytes doc/cache/包图.vsdx | Bin 0 -> 78546 bytes doc/~$泛读报告.docx | Bin 0 -> 162 bytes doc/泛读报告.docx | Bin 388562 -> 429315 bytes 5 files changed, 7 deletions(-) delete mode 100644 .vscode/settings.json create mode 100644 doc/cache/~$$包图.~vsdx create mode 100644 doc/cache/包图.vsdx create mode 100644 doc/~$泛读报告.docx diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 3f272e5a..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "files.associations": { - "los_swtmr_pri.h": "c", - "los_vm_syscall.h": "c", - "regex": "c" - } -} \ No newline at end of file diff --git a/doc/cache/~$$包图.~vsdx b/doc/cache/~$$包图.~vsdx new file mode 100644 index 0000000000000000000000000000000000000000..b6903a8a77a5f806df9f544b4987e20302071157 GIT binary patch literal 4096 zcmca`Uhu)fjZzO8(10BSGsD0CoD6J8;*3Bx6O1pwz`zP*gT(&*|NkE(%nZap<|r6K zA@CRIR#5znf{_^lK@9moSi+#d;L4B(q>C6TL0Oq-AOLpM-;82Dl%mU?h7XbX7c1`$2UvvG#+)3RbU!^nd`!{jjp z%^PJ8?+|cxbtOKbVNvM{Y&TM3g1Mokxd|3?i4`(uFl4Y~FlQjw3_@)dV%;%R)d2ub C0914U literal 0 HcmV?d00001 diff --git a/doc/cache/包图.vsdx b/doc/cache/包图.vsdx new file mode 100644 index 0000000000000000000000000000000000000000..01b1908b87fd1b0a0b06a34bdc8a997b561bee1d GIT binary patch literal 78546 zcmeFY1CuU6v?cnrZQHhO+qP}n=4souZR2$JY1?-9Y5Sdf@4Sh5G57s~nT)8cs@z!> zk*jjmuAO_8q6`QqDgYb+2><|y0OCQ}-Z4M`fFL*kfC7L7))8^AcQvzjHBj|(G;`6T z_q4MmECL0lEC2xi>;Het|G@~fq)f^WGop&UNPdbO(MfNiLlG^tz=V^zD)A3A8ED6N zCSJ=2%(-NtM{;XbWQ#`m-FD6mcx`hK=%!|zLsG|801&Fc*8|~2x}~GDq)sy49vF|r#m#T1$X^($){-V z3c&k|$Twm63XG<+MC7A)cx#8Oh&Gwm{ytlD;Sfv>w`dH;ZasE)!*@Wb`U*v_EQR_&A)le9e5LNZ!(*5X*x+T5`fkrWDyt%m_>!}>m1lA~8Ns@2Jm>5%#NqDH zi-^3~DnjZYG}X4}aIkysk(4R(7rpv&g;eNG#1IT%Ehr zPUmm?yVw1I7HI>tw?*TTPpq$=oIbBqa|kBFpJ~S@swh zNJ@Mm8vYSP3uT&@Kf{m#oPHeZx_BzD?Gl{D(+kxe;3^ zdgam7WV&j6L_DpM3lm&R4=tiwh*x{T2UJRaH>@1XxXSN4OuCSmxg$oYLU3%TLI zb_k+I&NNi>{{i*Cv�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

        (4A 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 literal 0 HcmV?d00001 diff --git a/doc/~$泛读报告.docx b/doc/~$泛读报告.docx new file mode 100644 index 0000000000000000000000000000000000000000..cf0268df41c7cbf4e288d9f657d99313d4a87448 GIT binary patch literal 162 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 NJQS4gKHOV@{|7iNsV)Ej From 86cbb88fc20fe0fa1bf4502cb5de279bd374d66d Mon Sep 17 00:00:00 2001 From: eee <719747958@qq.com> Date: Mon, 22 Jan 2024 10:09:49 +0800 Subject: [PATCH 30/33] =?UTF-8?q?=E5=BF=83=E5=BE=97=E4=BD=93=E4=BC=9A?= =?UTF-8?q?=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 24 ------------------------ doc/泛读报告.docx | Bin 429315 -> 430574 bytes 2 files changed, 24 deletions(-) delete mode 100644 .gitignore diff --git a/.gitignore b/.gitignore deleted file mode 100644 index c796d20f..00000000 --- a/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -# General ignored file types -*.o -*.a -*.so -*.swp - -# IDE settings -.vscode -.idea -.settings -.cproject -.project - -# VIM files -cscope* -tags - -# Menuconfig temp files -/config.h -/.config -/.config.old - -# Build temp files -/out diff --git a/doc/泛读报告.docx b/doc/泛读报告.docx index be3e310a3bdd9e0000348abcb94fb29c3a58abf9..af869f337ad9b361f36cc06f82c7a6174b2926fb 100644 GIT binary patch delta 32358 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

        TY}= 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 delta 31153 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%0Ak8zuwG}41kzJb=6?zS*j}Xm-nMQOuYRqRA5WreE zv6hmX+FBjYP(dlrm1x4v8u``c3Rhl#i!6ol605GQdweO(EQzaO&By|0VPmlooL3i{ zwY62u&()jwMr5V1fdFd83Zp3Vbp>B@1(u^LLBEu#V_8X$xub=ZU`Z^Mic31xY9**h zcw=QPC$?(k^)T(KC(CY*XL+h#F+Hm=Ysf5;mJiuF=t0gK(wP<#{cC?yV;` zR+i0}>LE&vWj{yO)=HsJ!DG5~CA!4A6A>f8r`6>^MO-hqv0O0dNm48V=w{0yBNQaK zqO=h!RMr%d&&7(qfF4*a;dF2%B9l}CU!89h3@^75aL>E7Cef%jq$-hRV@Vd2WQ#$C z@sSxF0W=#CoXF(UdL|ljtp~h+TG-&Q_`>qCTy*=Zixtt|YM3rO7G^zxLfJR(@&sEh z7nYB>)nct+guI?oO>zqha(+330ES(W`S?=6QwzrQ2$pd#c`{jCSjQLf0`E?kflwjq zsjV((SzQSG3h8i!RyS(k*P5*8^$J_nW37O|C^a^2T7r#pm0)OT#XawTsTb8E9|1xU z_7-Vg$_E?yTs=gT-7yYp5#dEI8E)!~i%+{&+$$`%SWQC(aJe{HP(`m$4@3|^L5K+w ztdSII8Fpo1Rh7%u zn4)Oetejn0Nh+c@8_lYJ1YNByU@{lpSk%LD&L64NlFQ9COlxqnt0k-)&Su?>l3yw& z!lDoi(GgrWV_tsNwVX!)#gIn{N8+Sjkj3TtT1@3rtJNg441rTu8=f|=xJ_cDG zf!viKcbz{qSZ*JX67J>Q0k#Uc6>l&C%P2UU$*3oepDOI#sL^#|i2&{?gN`4u247|Y z4c1Zw-CSFZRkeA%0_duOVW5klAOHde1P%gl*H!D`6DLrAC3J+Ln+|;DH1gV^+m$dH zJ^vW`YU!ML9QoV8xkPT+9PrbDQ?J44)UVJ#G*LfVJvdrD7+F2&OB4WzV`yoyJ0CM` zD~$Fjo&^fcU*QCIFsp@kqifgw-Z|xEG!FNW6GSnR6Rhtv*_WGH5vL{EI!9*rMOq4D zC@?jhdZBiIuq4a!IL^`pGnyQ@%W~{dO6O0X(mBF3NUfJk!Gxb*L#xl;irHI-M)deU z1Q1V*C&c3tjY-ETj8%>cJjEVoF@>ezg1&@H{}(@jcmPoJbzQsOao=)mf+ z@h(H|;H&cdUaGgh)Ra30XH}Y3hR+cvX^{d3{S9Et+x?-2LlzgL!u<@iZepEP*gt#- z9TMJu{`hkH$+b!3Nyb#*0T0C@G7?AA0yhYPIg+QNw6y&IPL`H-AkY9mAkIMdtQfKh zmMr&jhD@qZEt=6zax0-EIjZA9fvvrhgp^) z8C)HT-F$-_l%wo5XV5!K$rw6Y@Q~T%^xUU^kE%t7B)MKkI>Bxx?Lg38!ST-Bu-&U4 zIg}HruH{yAE}d;Z_^f^BtM;QSVCH6bJtoYbBUzDG(YJt)q@XJWBed>(es}xkMJqBI z%$1>x^k}{Fj}JOeu1-d4hT{nmXC}#2d^>2p=ZW{D5|2XB?XzYp`Koj4Zu{Y8=lrvO zo#%ht-niGHudMYTS?487B_ ze6$yi^0oKs-FD~Ro*DT8vIA*`QaDK_ot!3AlI029c^ceLto5%XXKWAYn8a{@cXP}C z22aiI+iq((?ONx}+o0UC#pA6x$|8Gl^VH6l?^$WM-3LGUJ8086cfG5=ch17!*5miD zZ+~*vI-3Bh_3eMaBO=b70Yk!=p?IXrzqm9xk`P5nl8083Ff-OVH*Z;gL&l&bax31@A<#Oh{>8OF>^yup;iN)hWL_Qlj26XF z42iyOI*=Mgr8!}+C+DynV??Q&Nof})n!&Mg$(7TObJIi-{ftsFc^ac$WlAPa%N$MO zkdO8l864v%iIBQ6GOsKplfZa-@65@A=49eLOHP@SN%0s#K(ZfJP9_C^rs5dEVdPOt z<~~s%<5=-CP03_gj#U+5_)~af?qs+yl%*CV3#iPu{L(g0+ zF0Ej*^RP_j_Q_mSs|28bbuHkE`Rh5xi!se|D!1fQqS1wl&jM&jL_l80%9U*0n^&UC zk)lUmZSjj{$yX%^Jr<0wd2-osTEkn(l!0eG)QXmAl2k(W7Q$-YQ%c0$8J%|#<(8Fo z*YM>1^-@C0s1eoQtoajkszx>&@d8t!@p*AE8*45`J+oxFD&mrV#QK+Vd>Id9TtYlq z5koa02s0NW%Tc44D_Mz#MPGAvHOS=Is8EXd0!_WvBx@^TE#Ja7u(F3!#g)~}N>R$w zHEC8?Qa*OQ7{XQ;)@L(GZ!}tO`4vCg%qgi-$kJu3TJkj%#m9JO4Lr2&i7mPp^Y#3) zScnwXVjHc99BwUt#%m>0U#V~8F^O`olYvOl<#H`HYqfA|9m`2Pw#qE5caxKp^>W(B zdgirsX|dSK6>xTOQK15QZnnM=qUxa}<=2^1i!v5kp~QTGZ}98uT7$vkihs2c!MviO z24@%YfzXN%0gN_W3@$5$R1HYBR}VHSq4d0(NvugJ(dCVQ;&Rb2T!m`15_Yc!%B>ZZ zYHF-pa+}H`$5fn zMzu9xlXcQnZ|Hn3yEvaTn_x6_RZ>C2=UqyB{YsP%XW~B5Kmb`KExSu#I9?32qFF=F zWBJu3&w8+bEK2b;+{-QM@oe5Jg|uvhTld8n-nUp>UsE^CNXb)@1A5&|RP}{sA&58A z2w=6SiHV|6P&_)hB$RygqHBR!T?+f7G%ha$u~?4H5gSWXUBNcOsk(o@vARn6R$R?; zx#~(UtU@K|WiMI@UiCmfCkW|M$-g>iM&QY~c0gI)XwN?Lew4nxpkDC$}6AKM_ zA-ZCJcx5A{>a;+awct8NyWN#kv{;z8Xy{9|a4tuClGOqhbhSh#Gf%3enqSiw7E_fP zsV9iFb%U!Fi3s7Z&gzLY8^rUa)G9|L#D);0U0FSw<+-4tEh2!$06n{qT~^9X*;`dg zk-RTil3MXfUav&6JijcJ7dGfLw}^+6_TgcFZ1$psp~s6@@G7zw9eIJTB74yRkX~0) z{%i)`x(=GX*iAItM+O}~Vso$TMFbG0Fbarx9t(KC9U_&3iL*8i)4h-uz&YX^=li_T#h!*=N9;{43K3 zf5#qs&9CGIBiqlf1Zp=Z>)h4$h0k|B{Gom2x)t2lIe+TK&HvBdl{L3*Z0Wz^nx{;h ziW=x{EK^gi!m53vWNN9Yx70PYUUOf}ohD zcir1dFLgsn-9XT;09JvL?*Q?%c;})u+P9y)EL^x3pr?6kSxi}FG7NZGLNX7$sZ_M8@s1n2(39@NA0&g9K_Q)Wg;3t;3SDjLFObw1HhJ4t7YZBS`8j3HYn6&Qx^QndK&m#vpKDbjRPQaxt% z(Zj-nyH4$-Kb{tzeP^i$sfP9ZIjzJKd>XWZK-JifpAno!jW8_zahe?l(^=yFU9 zRXz}B@tv_$PyQeUm@QLdk6#8IkaCMIQ%1R>#OAnWU-bIFUVTn~n<5shT2q@Z9hhJN z1Uidz8nFcFz6CXI_s?&=`lN8-m%_Cd0hLKIOvNNM7CgvTuq0zi{he2)!sBZe4y1yi zMvMjv%MPZn@e!5BU#~6|pWH5de{S>5DRzCZmgIlhfTIDS=+3Y z==Ow)tDm?yj=iUYlRuPf>ba(s8IU7@9r#D-$9t^jO?s((j8DnZtN@|wJn?`mF??KtUoK18S@uke}CcrZ9vB>>4L5xM)9GfD-iMC4869TzHp`jcS(2CxkVZH)9ts)%yhEr z!R>esGCNHP0!ETz zdiOc;7j2b1%RMkv2;ucZ#Pt>tS+)<4>y43sWJMyq<<2045*9_-GMx4cg~s*fATM(G zzxRRbEnvWbnk`r1ddr+hYUA!-{aq+ovk95!+hp&5J=5cM%i@rdy%8^|D$lN-^M)yl zvS!<=vKg$JgRaV)Os!V{+Zep?_z})Q$04V}w8`H8@y?UID}Iq!au?ZK+6S^X_zev(88^1Z-g5~@=-J|@>L{v>o^b96{ zx)$*1$)%3?%;04I$^2@s9$Oe0Up|B7_t8eQsobMDLmHok+zdrn?4{X?-eg&SmvvMj7vr)*>Bi z$q3&Y&&5VEN+y4LMKXG`Vt*9mrN}T(Iq7Oz?3_9^noURN_0iGgQ%mE<>caT2I=iws zpe>uYJ3e-LVlLjRjpUc2QkNd<#d;qv#yWdbW6L;Vj4bvi;Xpn&FLqH*dU7y-wu}!QEy`UlltOC($tZlqP0ssG>PucI{~Q@s-hRzx5=OuxCJ2sV*mn$0D8l z$g&3JMpMyff6s`8{vvbn;{zFgBYkRUKEVT&;4)*Knv@3}9W&#{R~F{ihDP&q(j-{a z&VVz@u&|sHmy^_dWxM2#d{ojT&>4wlKq@t)4RocZQgU=`F1`SV$<& zni%Hiw5~-s5YKhyql?q?T5nDm;3DahD4(9B)pVC6v;v2QC1b2_@Khpyot{}Z6`k$L zjtPRiJfQaQd_0jq9mx-^2_2cfuJNf3%lyr(#iFUcxMkKZYYCYFr(-ae(LFFSE6rDu*$>0NV^(vTEgoz1#k#4gr1r9V4` zYsr~rS>L<()XlQKcQqJ)Q6@5zYPw<8x80z-8ZK#6%C9V@28rSJWqkub)^}-O+l6Zt zH|x8*yG5+;_Kf=-oN>3RV6993zR}~i7Y@bbJ%_x9vzaxt53|QZ=jsap&>e7>RbBu=Un`!ueck#oH)r6m~UA4W_$Q=Zv@6 zDAj| zB(6LyuAj9os8Gm%y$PV@E1h+7Qr5>|rZeOpLRPT(>12JM-u>py?KeMf{p)+{SJo|d z*3T7Qe^M##`RZKZ`E$x)-+X?RF6i%Eyi&aV=l@w(-u%As_dD+FAnWgPK@%s9!_IBB zD=XM(0N$iZCkN-VCxu(z(|#bi1UIjcY=Mnmw_aY@zH%;qAWs5AMNrt<7ld-B%Ti6k zwkK1f3J7l?+rvrrsFUF(l}*1z*rCgmR07C8e@Ta`QUUcf8s^p)2( z>UoI&3@|jTsilcbQl?1c+Q5D#D?W~VAeQUw!nq^dXJEOXtTJ;GiUp-7clbR;3oxC~yYt)Ve zPbEksz-hO9adOcbi=$*b`Ok67*EI18d)#M##260$R;8{Fw^6It|L6Tk+?G0W0 zT5qOjeMFc|5FK)IHmkfzwcva11Xsr(vBt1p;~{{->h?fTL{X4ekEaReL-)m2wWwZ>LgTMo64KsdawLI(LSD z0=xgBYe=ztF70nN?H~1})AQxNLrNt+5Fv@1_5{?nk>pe5OU=%UcYR+vVPCSC?owlm z#5K@QQToZjL!Ni(%p|ADpR?A{YJ}ddPAIY3Xkawa2-m4uU(i@iUlk?0c zOu_P8&Q1YkC&zPw!rK*XYfKqNZGi57{GK*U-^s^6mA=lAShDqh>60Tf`;E(Dn_jU8 zjMYwmA~RbSwPk^Fu}seSN+DU8)$irB&MYrmF9vv%+4c?rjn`%9oeGt^WtXygzoD~a z$Qy>uu&Al5O{<*yWLeFFYh6?7+FQ*K=S~=r0i&;q*4i?tC2ca0t4O`nw1UIWKPf_c|~`OTSlh!g?D?ax@2RW(q-x( z_Cq$LR(FZu*#sE5@)ar1?1w>r92t-U{lT6t6d~0x4S{hrt#qM{jS7)Bux?60cCV{z zR7jB5HJTAteZE`U=~c&aPVZ#bN?%gyFFB);G2lAK+S9k|wRla?teFF&YuM^3-B6k3 z5pS>3sHmXvNUpji^&#kLuY%Uo0@2G|`;b=cnI>*v*`5}9NGw1Nhyvq(A+2EtF-A>T zVQh#{^(-njJqRlDTp|;9BSS<%-#@#QNLh2VGE!%R^u9lH(-_h7%%Ne# zAe|j*Z-;;pJ?*s=BLY+9dCaCBnle&N-J2VGs4*hh%<%Tp!biUse|kyt$jd3<{=H8Q z^!H`)d0yAMIAyATh$p`PP~$}&i>fNx#IsQGqG2LQtX1#gNaICO(j@`13Du$|=$7(T zQZ^5LuXW4K;#V92gKu zWYhVK^_Q7Rc!g81YjxkGIvjW}o?gu6nguhSmkA9y?)~(CO(RFogNGAe^fcK@I3se3 z0g=H}E8!(gGYl86=O7qbm(BEcrmRC=qRFIsVT!ik36KTpeR(GVGHUqiaDFPWmr zb}gv3`QqU|HSQgy;k9d*M7Tw}zj%4QaQ*8LQ6?_~70EIa(LH=9Q&cdN6`5HSuaLwnfMPqa-dC=pTr|pclgs#0MxWYpXi5psOUf>PQDGOLIYHQlMMwU2Bz|Y ziIJdx=|`tmOL}`K0Tnc$05M`C)<`n|ohj|%2OR&_GRakhP_MJ+L|!&aiAH5W)xFpx zlJYeBUUaZqZ>5_@KoJZTGtpA4s7TRk>!8Q`902k9cXNGi(TOe4lIW#^>5Rm~y4N1A zz43SW=AT=y?rcB#xOn?dQl0(fw_9JIEk6E#eSdD}1GYa5q$Yv%ufDfW)~TW%jUxxz zPWf^C(2byC&QMiGcLJlET!wDYRvOd@N;SuM3t*3Ih^E9&rrWTm$qx7*|* zMHD3NUeZ5wslNrHx-Eu198jSoi)^q@gNBHW03;O0c(qJ&6(Q7XcCiR_sghuS zR*ua$nP#Kurk4;scW5~R!n~p@vc2=3OVU6x4N|@JFiD!}W=<2ehW4bS2*^q4xp2L3 z>4&Y`kE(q;)BgWABrV=URzPH~|}+%9fE9bX61#IY4yg z;Aj&g0HAPcV~ZBSA~FrPZ>j7a`8EwV?F5!?{G)K`DZA51cz3BWT*-l6Rlb>jXDGPM zxP%SUu;aEz6QYT#2!LSctQ{JN7Fv>SNi72!v(VxmqG6~iF^0oEFM|>7HVd7 zKWj7^d{oj%V!_{1_>P6p(sU$VkTt-DPI(A41cFSu1+3ewn!^VZ>623#kRO7e_58VAFdE}LpF9z504VAfLK>BJ8s&zqFV2Vg)2BD@)D_7?(TAbXdtLbM>mZm zTwK8h^xb!=x3QMu3SBTcNoR4zK~%qrSex?0wv$gRSngO!rP6Umj?I7w>WG)p>C`SV zN3e0|9u(e82RbNN;Q>x3*`;jCsct9;a+MVpU!QwKKw(9qO|P{13G@R8Wm)%VDV@xa zWJ%MQh(1<<0HA)bEO*_1M%X?0H(%bMw6U%G=iR8P`0uYtv9#O2Za;ap`F!01Sq$d- z>(w<{sEpP^^A{C4(3_P$pT-~a(*vK*wbvJ_jK z9?4II=6-#+@@}78;{GJp66Ftp?jP{&tWi1=I~^jTXldGx0u&uWX2g=s(nU_H5cm!~ zb|@o-;^iL-|NgY__{*&uHFiQL2l~sh;QW99)Ujcjm|0vrLO?)}bl%)WVQT|{YP}y8 zM;aqdHCg7lAWK+(GPNf5yJ`c0Jp>pU-A5zwOMyXh7$K;t_D1(d76>3D$e5PND9^zo ziCEJ?6;HcW=HP)E5BS(ixlDM^>H#FJboGKM8wQWrg<}o@6}qxp4w$R=?b-VLfAQL7 zMx~@8()=Al0P2*QM~$W`?m+A zq`UR2(pRMZ`}gOHUw+{}Nkb;Ik~?jEWmFtZ&@Q^c-GjTk6Wrb1-Q9I@4-Sh5*8suY zodkE+;O@>P@Au=o=bk&~bX9dt?@Uimb?l4WG=GL$AqsE~;#aq!mW)NKccZEv#8N-+LD2W_> z*hCl4Y%nnxBYw1@)gJi=bfdwzQ>}+Sq_v{ge*Uw-(yz>r+odjgE1QtYM-HbC->=N) zD?hYx)LY!y!Zi?H1efM-nC&V%zY(z$MbU>Z&x2KUH+Qw@EP3ewUw2%tW@Q(kbp^eD z^sxzz1jWT(!`y`UqGUjbp`mwii#Q>FMeAGOTL|doT>I2_5x^rTK;TM&aj)&;p*BqPFj)k>gox4$iLq} zLI2(OWC5CY6L~tsrHwKRO`wes1E+#QX$0zdm2mE;=Hm+(*vH4IzOL$5NvwA|48`_x zJMVM;UAXE@TanbxUqe^tS+Ww43)Kl~WX8kZeVm%Es9gita(>dp317FOO@9si9TwwH z%6-LdVj?2}BEpcznuY%TLVkDa_V6@uhf z8h5|N6?D&b(8V1>=f-!?)#A*#;1Pm3F$AHI$F?-hSjStVlf9rIgMQBit2d?{I1OI2 zbab4?YQD(Tex##+ zzt4zM4W%Tk@88Z9>yh@V0=aE#O-n&=c{5-Lldc4LiF}WMNol-`=jHSC4%||Nr$Zi$ zh3e!3n&$S6oNXA^)CQ+P=kD50)eT)?F;}@TKwfM{&0Js6{Zzx$zxoZizUVO29k<#$ zA!T?g%cmUU5I1+Q*>(PUK#^P^S4i# z18dz+YIQ+e-2S=13MY9E-1tB<2MYp9B6F$$;KW2+-!$suOY-TOlZ7qSi_>x^8-(P? z&sg^Nyegyd^RPlFdEr_dQM8nh>5jdWHN~&@;YWVv5zjRgaCPtDE6#W_O{i^M)s_GVW10ASgwvPOk zNlJ$-CT>B$fURw=!Kq!9s>V%`h^duH4Ad?;;1IYf3dZ_Q$+!eb-67$7LZnl9yxkuf z9nsZTGw0vBem^esNWV=+aKsh8{-&o3xd*?R*mhF>ekz&Zt&EyQU+W1)zD>Eq zPt)>5ptl~nTlkb{{phy*B2qT_GVYxI3O&Izn|Z$5{8Y;#7LP(vFux{wv1M`n2HY1j z&)Gs=A!-VOY(+&eS2c#}kolIgCdJN^SidAXVi@yv{?B(U*=g;ZD{*-R2wE`uj3)+% zxz{zREjjt*M++?-{O&#(^=VA50_;!xP@l*={}yL3PEI^&n$72f!^=F`U zZA{_)O2*u@kI2n#=_j&Y6$~(YP`55%L_m-2M__W$L>4QhRn`2MbF~J!K^l+5EfGVC zm^P|f!Qg^T@slQ<5SANy+2h(^X>QCrUfA_-NPg}*PYIDyY9e{Die_#i4xUvM*y+p@ z7f29jQB+|^WyfZ{*apm6om@htN|bxVnz(ASzgU|44n}Z*xk~}rWClo8eH5Qv4>L>qUy8n@WjTUW5`3`=eAPx$aLg8MNgZ!m4;8_ z#!lnI7wl?kmD4)CxALJN@P6Pm3d1tF8Yn7i0oUqloU<;)4x%_6mBy z7<$Ef4H)siMyp2jodohHC5Q;Wu}IP62)Ev~l!_KT6#zZw_tG_#q*+0^{>g zo=a;L=!fX#RhD$$(Ok_gB;_-(1o!26m&jhmpk>Bfn}5G}NDla03)oOovr)%sG(YH) znIGfFRHawrc7J->nOr=ZF6+Z9FN}`21vCyN^;8&y z8(vk__858~EAgG-!P2s+H$qy-A+^bl8A&H#e&$Q1qFMr%@kkC7@%Nk#kk$gSmwghJ zvnwI27m~yfe|4QXf?rZH9ktJ<2M)8nzBk#!{w&)q>rgFoPR3)q)!ojb8C@BV@CdGbineSig#9 zd^cSCGJ6QLypMO|eA{{3R|_zu^8B#2HnuS3O(qN?J8?3mPsS7X{5u4ss|s8ba&Sjg zcRHZ@WlBs4!IAnkbIk6W8x{7Iuij8V&`C{wa`!ZE%gJ2*+L(vK-+4pP=1QULWJE}< z0W(>Y18yVcv{T>d@V>GAcV$^Lv&wHa-l=pe9#sLrEJ&)!81m9<$T+g&yGM6Pp6*bn&S-4;5G9jIOVHD*0UsNA|pUPR7f-4S6 zUMQItq3aOIlW@O9v}cNe658sTH_bT%CI$6{_9p#Xa+cGJ(78PyINL&XCN_y8;Nvd` zR=pvBUU9D(T>Z|a4@#cJcUSN!BMfB$8P~|bl+rf$L*YQP8Mfkd;;3JIQl;zL^LFPcY&{O4K9Qpy=; z1l-*clTCf8d`lPdatFYGGeja94-d*Lg91U@o`|vwYY*!-x6HmOqAd&7`o@qYAsQc` zQ^2x+?V*BQd;DhG z<6hL7-;7nQqOxA(o=wpOeW^5_epnMoyR{S-{fUF!;SRl5pb_HwZpA6DEznJLPn;j76QCfm&CwLt z(Xjla)OUVd-t2eq?u>v8)suR#oWU`0dMM1~d5C4O|2?jSiEGO9bg4vz`;Ga5`9&4a zH%+AR^N~P~q=x@HcIcil#3VtIuPYF#y<8jUR?fVRATM5t@u5wa0}|_}75oiUopqaK z&x1AJt44Br4zwhqT{2wF4b*O5Kxr*GiVRMoY3q>R7Jw7yn@Xcm5BK0hxX-YkN-h&W?iuvmCW04 zo>v`>J_Pku4lTW60{-~?`eO;$Y1lT4J^c6U=_A&q)ptswf_+Z44pSCLve!MTfl!$+)Y1 z4el1Gl)zBI>Q+S*-A>s;b$5$?nTp=4o`*5+G*svqkSD10NBXjory(a08GEB8eu(v` zd45v&Cu|Z}N!2u0l2VxQII6vRDY^7tc6jRdn_GG+nK6gz{aG~?XPrF_?B5tddBZ{% z!ri=6-Uc8X<(t2I6!19s)XSGVfT@$j?w@2;BJ2QxRS&B0I{0!?HnNUrDTMW)%LkXx z*#0il%IuK5+$1!9vCs8i_)O= z^>lYD$8y|z)mWFh_?XW325I1m*d12SX0>9#(kO*LJzAb#gXEI!W%D3~uX9%2Dq2jv#g0C%^ zd-fcOi>6^F0Y<0zPFkVX1=;u5xAesHjh`D^Htv!dVR{?L@u&B1-_?uOM;Mqh&NL1! zHdI?qyy9`;4_46tgYT4R(?RRMZyzPMX)*H)^|7K#4q^CKFs}vWa?Xh45`GYRpL`Fm z)xGqK?(yz{F6=bqC9$Ja%Vw@i=01Y+KSHALna=ZWGCH198d*l0-Xr zNB%d9gam_9l7)lb-P(AfT&5IGY=i`3;DGvW~0F2!R)n_e2Qms>^Z7+!Dzq z_OO7?R~+`ol<8>Jh4wRdx_Zz9+(l;vIyN z`1ex-HAG_mtQqy@jj%?;(uc_yAASkAqfG4)vu)pk-1$-@9MV7R+@O{}L(69bNlXRjkywii9$YMX(Qu!EBJef}X-7=D2nDb1!QvW~WWT(9IE=YNS~>0aj3m`m$cM0iDQKSId? z4&k7`8`L+3E+d>{=VD~mZvn`%6yagM1X56v0kIg!9B@z`=Fhm@%(NS`eKheS?t>5| z?t7YtvccVKW?pG!mWD8S_05#x+(3tMQq^oW)7uKC^b#%)wIYut0|xi(&nzpdn`pA0 zysg3W7<1l9f3llD8|Ifsd6R)*=@BgjeJbks0ro!z{m-5; zzyM${pLr6nm7E{z4avmDguwB*6=syci_~YN#EUI*s1XTxx<)s;B0`Pzd+?4pl7%6` zI>eynnjFKn{K|yRln{cU+)1|G4C!+s1^S0LF>BgKI4D&juTaxOl`g}e&2B;}mdgg= zZ{n?6X3!I2ArW^6iVxx7*C7jsIkS>hYzJ!qpE%Y-V z7Fuu>Vohn!Ly8v)EmRO%3&gn%whnTuEKxBGCtCQce2bftrCLyQB7tp=;mgNiy{}mj z4WBy^R-o4+6*UA}DU2_(zKMqjr*y~t8nJ1F;*@oyq$feA8MU+)MWu66`c{5NRn^7D zUw(U1K2QAg%k<3IGa*~9TE4I{e4tuo6UNUdG>g?nDRFH`*(pbP+2admngw<}z{QUV zOfrq@1r8U1z7g2iB=3$$;1v0Ew_e*(_v&x5h1?<^VZ{LqPrrP~_)hW1!pZZpY)TJ` z3unm>PiP5}o*DPC&I-qQJg}wGVK^W1cg40^^A2|dydCqeFI^n_5P7P}7F^1Gl+{y5 zq#>+Dt74vFE?LSqSe_QxEJ-i%n0=lUNOgtN@zYKEvh-`iqliD-@)%?EfPc~t5TsXW za21+-88Li-qgCQf-@avS8+b!HG(_!`TqkDBw6_0e&F5Ve9i%Ll*07mUMG2^IT8Y0W zrIpT;HMnHfRu=}-D>7$ zQyWNJ`56#A7Ojc3x)U!e7mp(!2NMno1fKXVoikHMES%a%tA8Drj=L4Wdq3 zMOw+|ZK=Qcx#Ut+MUR`b#;$(~+$0-SSh>B)J2O$rt9`n{C(Pxu7I?YpukP|P^zfhO zW>|GbwX`Hp$Y;5Sgzf%GYmVd_tP-nU;H_LmwdK=z@1O+}`Hgne*o?URPbb!M2 znE|!B>v|3m#@#Jl=bEc7nzw=tFLfkNvmWgxc{S^+C;HQ!e5W-UXAXu4^Y-eR{cjwK zX#U=2vm1JZZ5GaE&W)8C`m4=Z#^l-!S@Mmv@xagZVHSV#B|mz&FQo#=T3{Lr9-8Q@wT~c^n^<>96J-G=fW-tDF5IQmXt-;$ zvwgU?(jeVkmbB<2o#k3|GD*QE5rGUn2MH2i>nj&NXxsC3Fz;Lpe_9=~r_%Um>)gGx zwE(9*=7*bbqgMoH0Atw?RMF@s-tSRot;>G7ohw-SwFUkJph@ef>MF(hp>NB|I3GS% z8vVv&8f@zx>kPo=!LHjIftQ2H6>&i%e69_{4#N~8solSAc+_DRm3P&7PP*Hk#xu&ATPg%pUx&Qb6I1U2akFMBlb>~gO@a2N! zk>9P{GaH#EniJuE)Lu2K9O_J@XB9Qb7l~Vk8Ip@Z@Qr(Bd$xbcw_I9kq^-w){S-*k zu78j6P(~dFE+=*w1`DF+*$t%v^Ixy`0}O}ih#6F7FBj=Km+2Sg-`&Nf3w)P<(u}{F z$Eat?FHb{YQsgdTu&OU^$ou57EgCj5dM^>NXUwz{gY-LH&zKw9u^(O-j-Eg2_h=3Y zcVl^b?^57~kh_(o1m)ya#?5Ihr6q4s^RLf~ha*{lD?*`cL-E>|@Z`}jsKSF^XCuX0 z3bB5W%2lwjv)*WNj{5oh`A|g74aX;w!J%(tT`+c#FqaOLqLuH#lW#=wD#dlx1|;h7 zg;2n-3KmWqX~iXuqz=`I=eowAq#X_rqA#ircp*LXhhFkDAfqQyK#)dPBG{x@XPDTs zRdoadIn8yFWk^i4q>Sj9`)6V9hGNlBb%I($`RIim4vEA%qOX@+zX?MiQw~P{VYA}F zLdRy2XV(TW3?~oBl-cHvkO!S8eI)8yK~JQZOnGv%$g&iKjx%#rHH5rubB@+tpzJs! zZEKhVYD~ZLiY7~!=UvFbEa+Oyu<^Mk*>)%ZrM`uDM|?q@JS3JPyy6uufxYD-bgQl< z5`&Y9K(+ri$3bz8;9HZIO20>`mE_x^+B+h-tpKf95Y9ps>VfrKhC*4(92|y`5x9b? z!updSKWXGLfF6@AT~tg$A>RDA*`KR`Y?B=X6V?cdkqmgP!q#h^TZ8Rl53kZ*C1xRV zVCI~Nt?bwmH=XQIRrne?PjK)`qKFne2Q3A53#UxEDzv+h)VWcLQn@FZYdt0A6uS8s z!aYicw1u(VZ#lZ`w_;Q92NG70hAC{>7&Ltl7nDe7UCc1v_uwDXRv6`B$~B=oOC>UO z7`BqqV=z+!GO8khyh@Z;SQc95$?3xSKswnCcz?BGIp{wO^9IJ{Y`wU1S)^GzyruZX z1UT?xu>G|XuD#CZ6y$85uLb<$5{*JbG8DxbaTkQy34g$`t3$)GC8g=n$dPdjuZL?y zfh-pu!za0-}hjp7dG@P?WA!kgsrtFcg;b!0r&9sPWmc?SQ_RXCMGUl|qo zWS*VGA;trr1WpM5hSXT?)QZG$XfM9W5F22ld>){wQ-Q4~0%R+n<9^ACEpCBl&Zuko z%C5i@&vC3KHAx%}2PWo1hOtn#2*iI_q;yK_$2Wn1CNQ9)&FFj6I!3u%URK#)nJUq6 z`qA(HQ_b?6^XHD6Tts9dmL<@Zz5i}5X$fm(u4E2bq^8cyUT@rP$UpGPG>13E7~%}fi-eaOTS_N^;*9Q+%ES^ zsW2Y?s+-aD(k|PCD4;55nkS~WBUu{N*)fBr*O@C_d8L=?>Q9-|Gsgj}N#jtnxHhe; z-5GtMC{D>}OK+n9+4h9hF!0KVxjCEH(CX~ZP2{AYcHV7FF%mtw))(QrSA_37G-(Vj z;l97=RVop7=U8xS?c!7;Agazxcw27t*(B<{rgTO7ayd5{8jqZld>Pw@c778K0=19Xyxu>RS!ugMZgUUt zCDIKm79;A0tSTY0| zO@uN8tr{(*k-$D~$U*^`l5Y|ijY~?4%GPm?x`nLE8Sd=rl=N9?DI>%t2&P^+DcWng zLu$CMbc%n{{}@3H%TXi0@$yz*uKWBEpToK8+ur0TTm*dJeeJ9Tynx?bJvxv9#HsR7 zTXXZ@pX%35{Cs%@(lZ6WBL^^gu!$R-I@qoSJp^!n$jbeVTd7wyuD@yD&Y2&*n!{Ece)nfp%pMxpP5<_NbeP2*Pc`23nZ0DV z_Ux_e^ti&?)Ai}n8Gp0EeSIVK1Uvo_TeKdnq%;h;`Lb}y-JZKK;?L&N9@^Eq1q}=g(G(o)ll{*G!NJ|$#N6d`itulSaGE3Q zNYGF$}!13d^dzUtySdEL#$&#bPSsQ2?D}fpTO^h*2vaHf_h*$p_ZFS`^+SvT2M^dMFx1 zRJ-WDp@Jo9TXj*CTC^ga`2?{u@3 zpjqX6>pQcK+=Af7dO#`Erb1J_XZ@4ii})y%9hC*E?z`1A>0P-@AB5po*{#CCW8R$I zlbn?Ktef_`>x$P`&-sJ;5<|=%OhC0CQU~h+RnP7&DFGW3T&wGri~4q&e&2NDFR+eW zvUKem6b{DXD*x_Vc<6pdg4eY^9?!~20LJq|`sw}gob+!CBM?0+&u5@*+cq!)?SuTA z)3F&AWkd5s9W6*J6y2=*`Zrr`M@76Z-A#vzbZcsHcsDOsQ_Y?^o?}@ezu$#i z%ZFLYtbBUy<(ei8=wax+y5$#lf$qFdEWYH)b!%qb2gkc&h)ZD5Fi|XgMCKRt=liS6 zHM8+YuV4)|%_zGF?Upf*^4HGU8=9-a86l7O9ZehFi)Wqa27O{Id}BSI2q3yXH% zt7ylRFBPzlE|DL`%OSwiFq?4$3rwC9DaQMOzjQ?Z7;5@f)(BEWI&$0h>kAwIrL>zY z%9q3Q1ICPve(rIvN5Qg}D%kTY9>Np(*Y)wI&`RfM+M3a?w!f*2dv>8n)iMf>Bk_K0 zMZ)6jkfP5rv0wfbf5L^7G|5$r8=^u90S!?lB!dR1V4^>z$ox-&b0`U{vK*rNY$tey z8`w0?{@__Z5vS(--UP+E{Hbh3G+Y<7l#11BSa5I%W0mTeIlh7+Du}wk1ZQp`D}d9!jJthV;z5jf|y7y zvwV|gm2eIX4DhGgLk(ocGx0xIT@*CzaWwoeIhGryS8+$h^T8_Tg+cU>Q6mTeh<(-x z|5H=-pGHGJBs^EV@?2Q-qCg$^C7(n!KSU;cD#5#$hutWa*z&KNBRnF$cqD~$241aJvY=}-HLUC;M=;?Xmt%G-!INkkr zpsC8m%9u}mw6{4oyFA*Ig%|S8?~KJCM+KVNg4uO=ZuvkF$ksU7MH*9xTh>c0ZoM=G zcy6x^x=*pg9~Y9}q4BdZf_$5w6MBgjinGWA0z`SxOkQMUK4n1SKM_vtQ>5H%Mg7zo z{L`}V{?l6h6M_H4F=r$zV$sYnZ9WDkPKeminWP2x-YagY%Uu6?lwGZ!vJ;=2^DM%v zm$YM}Z$Hg1D%%aMNoQ+hba>+pQ*SGi0@P<}WSXq@CMw7qc!AxT;ypN21>d|EGm~K` znNy1D#OKjD6#8Nlx#lCvW9KwC=mT*U{$lVa@WZjb6!EW%25IV#C$Sf3I2{ zNwBYD))+kt>$A%$tCcw?g{;TL!mkN!!o^xMpf37sUsbb_&`h$Bzy#K@n1vNmQG7Nb z)1Q*zv>JfO@4(&~D4#f#El(vuL~zK*CD`gGXQ!D5z7qW(w{LMr2h2wo+6A>axAnD? zely6yfzwdfRgF2f`CDQV${C&24`TK+2Y!F@%uE88jNY?XcoPt8wYzh7*s-7PFcx`6 zYf2yQQUVkX7FAhOks5MM+zl8hl>^CUT(htbz?EEXAAlqp*sAyOh``M$NCn!`Ma+Jn2sGqX z%fT^X4{;>h2V2=znRBf4$64<;on)Y) z?eTZ&fU0t~0y78eIO?Q9{Q5krDvp8?7%}n%M{&WY98o5Zs!?&FD^JpW+Sbn(!wLfj zV4qYBNM*uQ>Uy9cX625<94FK>WITy4!!8ljQ!tS2qc}%rL>3#2g6Iki9A}O17ThXk z3F#K>c`F)=Fydjo%e4-`;108YGtPaVG+;tvOs3qLik_!KhilOna|;=YQH)lijB zKllV2`xnzA13SBRPAuairMm(a+~uzC>LY0M2o15)4qmmQ;$${*5u20@UIK9Rl zzXMr}x_|txW%bJ3V@nM1KNS_v&tqSFLD$CBDWhom3?)~yD0C!rwGyhI%>$P()F`u5 zJWyufB)cR@_;Z@^Er`_qm68=@1e7xNUIRp~`@HdwtcZ)=10d^fkc2!+8Gt%oq%@N_ zug2DeG|6D4P->CC9Xc0L&q(R|KM_#Az9T%^4c(?uTm{sjxQw`~y^|ra3+bZ9t zP!5>~FG{&Wfg+{Rv6V$+2ZxXphj=$uoGSwt#t3$va`BRAW!uXu58;=1pu<(DHUr*H zjnvpZrhb2;eM&{tExn=p8erZJrO4XMK8)VWlR(O-W1BOFvKt7aN9n!jX7(kwpe4g!l$^syQqwgj{-qvPH7R zAsRRzm4hH6?LBv61S_XZe^m{XD%e2hfC&_}qa6F=kxtBCcU+&MGWIn3x+#S{TTJ z0hP*7ky{2XlVk*u>=h}W{}BNG(La|Qr|s)~NSCOXFvESBI#McStp=pM^OVXm0f1d6 zE@q-2otaTd8RIXFDkSzDmM7WL#ESB*!>ZtX@!<7T!Qn=?QGg-I^FnwwxM$pDj#Ab} zQ@)78BOxZiRlG#OPF>c!J6FY7Fg{Vm5eVD*VSu%Pzi!v+sT=c`kct4edpQDR>#ph}J5m0xx zTdbGnk0CC$Y$Mi2rfz0IpwUF~C6c~0HXUe!`#Nuw9Ie7=$*JGin zbzp#!Vasc0=#ySjP;%0MH-m?*7D2BmtPy851hxnE*@Z(7qjP;eH0^@Y-M-?T!iXIlz*8~zO)Ku%WN;2Ju6G<5nc15TnBIo0E{Aq0OXz_fjhLcI0 zyh#nlKSi^Gq~RVQfZ%{;V!BRenMPI4yaBov7v}kPA*LToeObJ^-sx(qJ~<5~MEr}g zvqls?>l$g&6`l*i{u=-bsV*Kcp(d|B;OdK5N-LO90m6Q;wDQd1{N;yJ_*BMT)}+rQ z*F1H9Es{wqw_P|#u$SjKkclP-SlEXWeZnzaxM5cvC5MNZE7hZ2Au2kMYabypy9d%Q z=)VeEyc5@d4#vo=H(xUNW86Xfus~gyU%cZf@y0zuoAR7W#C_C`@)qo-=7CF>pFJs0 zr5q6gaLFQg^dh~f_#80fXtOs}2Kb)Q59~kxGQJn%2%N(qjA_@)fb_ zO5U$k8Uq(m!swaVm|CY_r(|Oa@TW(wsNTmR(WBRIlpWVp%1y}BECaF^snAgL!e9k1 z(l+Y&+9qe#;PIzL!)`&bma_>NWL}0&eS^Q#qBezbmUGjn8k1cK-A{SZq7IIfrDmSu zPOW~qadrPHk}92Ab8T|r-2U8NW`z#Nc5m-PYpGp@%&@Srs#|eGyM(8PVCHT+rp=)- z4{MJ|OATwOB&CGm+W>4n%Q}B0 z?en0avGCzw^l+0p#Wtl23nMC5lThKj`SZ>58s&=OSo;XFCAfMX9JW;|t7I{vay+6c zTpjyi1d37ihzzk5!VuE(J*4YGT5I&Pm*7z-e=$y0DzX}*cek=!^YQ9PEHjP4Y?aIS zn*w_x;lkZb(}308(IK0e26-ZZLa^+~cFIcEDNFYmF(k23b)l3UZU#!HKOMBNob&r) z4oB2&gYTncQAyJD;KkbV^UAaxjKVWbsYyl9^`$;r@sbol6w^R%R=16rdV%7r1#}8{ zvEa0nxK4YM1SmlU82G!;bj4TJcJclY0)uXjSVd9?8E*f4$1*YI?fnD1*})1BPXJY1 zaB|!X9u8mw2a3WUvqLdw#3<_4nKA0#FEnbNh0Zjn-)`0fZZQj-o^ALl2r`z+?+=qc zAmx3hHjnNLBt|BuYfZ?)=&VV5NAMm}8MQW$k(!1@$h3U$gjHps9i zkSn&bt%_#hw1bD{2y&I8s+QGPI??IujjkhD2aAL82KGQ}jg=R-0G=zT3fPkB3Cr(! z9l^4VNAkg}5s^Yr3_Gygj2#HAQUoVNmXd?B78FiDgUNhM)zyVLY<@a?pa8qRb#rtd z!)sd(f|VApbP&b~$s*3fY&}Lu0mj+U+^0MRbO!s@piM^$H)@ z;Umn70JS~C7(AGr&a?4ecFx@x0tIvH3N?X++j=yO+Wo?FH6-w*$wRZqNvtfoDy;~=QlnUy$(-G-+q+F`V&6^x@&|gH*4Q3FOe z(jly-g5Hq>ieLG`me^{0zh_O2L}9Zuph(ceMt-Y%L)by|6hBDFCQ=&)l$twD&(rum zvgh1E^pr>jVlC(UA@Tyxcz80JoGKZ3s1JI=qyIopLv62)XmG)MNJQRIvuv1vGrcN}xIO6D3w_mStHUTe^fGB}X2F7)3 z8hpf*r@fl@EN}xlB=f^Fp#H&R3GM$Q!{4;w@zL$^Gvw$g5PlFK0YHWS|H4`Rw>ls( zkaPlo4FCW2Xa8@BJS9+M0zd#F(iAk30N_JJaRvO3x7*X)L=~i*0Qd@`O9bFSbozrN u69MG^4JaVTL;w~9WDqDK5kLn0pLv675&@VHwV%GBL;xwkG92)EhW`U~1Q*8u From 3a42194ac0a74e3d67ff69da3179fec233d22373 Mon Sep 17 00:00:00 2001 From: eee <719747958@qq.com> Date: Mon, 22 Jan 2024 11:30:47 +0800 Subject: [PATCH 31/33] report 90% finished --- doc/cache/UML用例图.vsdx | Bin 43805 -> 52911 bytes doc/cache/~$$包图.~vsdx | Bin 4096 -> 4096 bytes doc/~$泛读报告.docx | Bin 162 -> 0 bytes doc/泛读报告.docx | Bin 430574 -> 832650 bytes 4 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 doc/~$泛读报告.docx diff --git a/doc/cache/UML用例图.vsdx b/doc/cache/UML用例图.vsdx index d1c233bd6650a2bf324f2c1bf7c1d76e2bf7644f..73024512903ff180df5b6ac892befe60c79b78b2 100644 GIT binary patch delta 22055 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 delta 12850 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 S`iGi+CWTBhEx diff --git a/doc/cache/~$$包图.~vsdx b/doc/cache/~$$包图.~vsdx index b6903a8a77a5f806df9f544b4987e20302071157..b139c4fca36d87fbbb093536b5814eba2f69eb1c 100644 GIT binary patch delta 18 ZcmZorXi(UY!^Ubb%gp)l=0di9P5?Vf22cP1 delta 18 acmZorXi(UY!^ZmH{oxfCHy5(?a{>TM<_I+a diff --git a/doc/~$泛读报告.docx b/doc/~$泛读报告.docx deleted file mode 100644 index cf0268df41c7cbf4e288d9f657d99313d4a87448..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 162 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

        fqoUB6f0hw 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 Z*DyPEB_hzQ5dxtD|M`KBo(185{T~mE4MzX~ From 03118dec509589007132be67e0c849e4545b383b Mon Sep 17 00:00:00 2001 From: Dio Date: Mon, 22 Jan 2024 11:57:18 +0800 Subject: [PATCH 32/33] =?UTF-8?q?ipc=E5=B0=BD=E6=95=B0=E6=8B=BF=E4=B8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kernel_liteos_a/kernel/base/ipc/los_mux.c | 190 ++++++------- .../kernel/base/ipc/los_queue.c | 254 +++++++++--------- .../kernel/base/ipc/los_rwlock.c | 145 +++++----- src/kernel_liteos_a/kernel/base/ipc/los_sem.c | 116 ++++---- .../kernel/base/ipc/los_sem_debug.c | 24 +- .../kernel/base/ipc/los_signal.c | 234 ++++++++-------- 6 files changed, 492 insertions(+), 471 deletions(-) diff --git a/src/kernel_liteos_a/kernel/base/ipc/los_mux.c b/src/kernel_liteos_a/kernel/base/ipc/los_mux.c index fa4a67b8..45f43d6b 100644 --- a/src/kernel_liteos_a/kernel/base/ipc/los_mux.c +++ b/src/kernel_liteos_a/kernel/base/ipc/los_mux.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -40,19 +40,19 @@ #ifdef LOSCFG_BASE_IPC_MUX #define MUTEXATTR_TYPE_MASK 0x0FU - +///互斥属性初始化 LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrInit(LosMuxAttr *attr) { if (attr == NULL) { return LOS_EINVAL; } - attr->protocol = LOS_MUX_PRIO_INHERIT; - attr->prioceiling = OS_TASK_PRIORITY_LOWEST; - attr->type = LOS_MUX_DEFAULT; + attr->protocol = LOS_MUX_PRIO_INHERIT; //协议默认用继承方式, A(4)task等B(19)释放锁时,B的调度优先级直接升到(4) + attr->prioceiling = OS_TASK_PRIORITY_LOWEST;//最低优先级 + attr->type = LOS_MUX_DEFAULT; //默认 LOS_MUX_RECURSIVE return LOS_OK; } - +/// ????? 销毁互斥属 ,这里啥也没干呀 LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrDestroy(LosMuxAttr *attr) { if (attr == NULL) { @@ -61,7 +61,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrDestroy(LosMuxAttr *attr) return LOS_OK; } - +///获取互斥锁的类型属性,由outType接走,不送! LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrGetType(const LosMuxAttr *attr, INT32 *outType) { INT32 type; @@ -79,7 +79,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrGetType(const LosMuxAttr *attr, INT32 *outTyp return LOS_OK; } - +///设置互斥锁的类型属性 LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrSetType(LosMuxAttr *attr, INT32 type) { if ((attr == NULL) || (type < LOS_MUX_NORMAL) || (type > LOS_MUX_ERRORCHECK)) { @@ -89,7 +89,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrSetType(LosMuxAttr *attr, INT32 type) attr->type = (UINT8)((attr->type & ~MUTEXATTR_TYPE_MASK) | (UINT32)type); return LOS_OK; } - +///获取互斥锁的类型属性 LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrGetProtocol(const LosMuxAttr *attr, INT32 *protocol) { if ((attr != NULL) && (protocol != NULL)) { @@ -100,7 +100,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrGetProtocol(const LosMuxAttr *attr, INT32 *pr return LOS_OK; } - +///设置互斥锁属性的协议 LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrSetProtocol(LosMuxAttr *attr, INT32 protocol) { if (attr == NULL) { @@ -117,7 +117,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrSetProtocol(LosMuxAttr *attr, INT32 protocol) return LOS_EINVAL; } } - +///获取互斥锁属性优先级 LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrGetPrioceiling(const LosMuxAttr *attr, INT32 *prioceiling) { if (attr == NULL) { @@ -130,7 +130,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrGetPrioceiling(const LosMuxAttr *attr, INT32 return LOS_OK; } - +///设置互斥锁属性的优先级的上限 LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrSetPrioceiling(LosMuxAttr *attr, INT32 prioceiling) { if ((attr == NULL) || @@ -143,7 +143,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrSetPrioceiling(LosMuxAttr *attr, INT32 prioce return LOS_OK; } - +///设置互斥锁的优先级的上限,老优先级由oldPrioceiling带走 LITE_OS_SEC_TEXT UINT32 LOS_MuxSetPrioceiling(LosMux *mutex, INT32 prioceiling, INT32 *oldPrioceiling) { INT32 ret; @@ -172,7 +172,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_MuxSetPrioceiling(LosMux *mutex, INT32 prioceiling, return ret; } - +///获取互斥锁的优先级的上限 LITE_OS_SEC_TEXT UINT32 LOS_MuxGetPrioceiling(const LosMux *mutex, INT32 *prioceiling) { if ((mutex != NULL) && (prioceiling != NULL) && (mutex->magic == OS_MUX_MAGIC)) { @@ -182,7 +182,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_MuxGetPrioceiling(const LosMux *mutex, INT32 *prioce return LOS_EINVAL; } - +///互斥锁是否有效 LITE_OS_SEC_TEXT BOOL LOS_MuxIsValid(const LosMux *mutex) { if ((mutex != NULL) && (mutex->magic == OS_MUX_MAGIC)) { @@ -191,7 +191,7 @@ LITE_OS_SEC_TEXT BOOL LOS_MuxIsValid(const LosMux *mutex) return FALSE; } - +///检查互斥锁属性是否OK,否则 no ok :|) STATIC UINT32 OsCheckMutexAttr(const LosMuxAttr *attr) { if (((INT8)(attr->type) < LOS_MUX_NORMAL) || (attr->type > LOS_MUX_ERRORCHECK)) { @@ -205,7 +205,7 @@ STATIC UINT32 OsCheckMutexAttr(const LosMuxAttr *attr) } return LOS_OK; } - +/// 初始化互斥锁 LITE_OS_SEC_TEXT UINT32 LOS_MuxInit(LosMux *mutex, const LosMuxAttr *attr) { UINT32 intSave; @@ -215,24 +215,24 @@ LITE_OS_SEC_TEXT UINT32 LOS_MuxInit(LosMux *mutex, const LosMuxAttr *attr) } if (attr == NULL) { - (VOID)LOS_MuxAttrInit(&mutex->attr); + (VOID)LOS_MuxAttrInit(&mutex->attr);//属性初始化 } else { - (VOID)memcpy_s(&mutex->attr, sizeof(LosMuxAttr), attr, sizeof(LosMuxAttr)); + (VOID)memcpy_s(&mutex->attr, sizeof(LosMuxAttr), attr, sizeof(LosMuxAttr));//把attr 拷贝到 mutex->attr } - if (OsCheckMutexAttr(&mutex->attr) != LOS_OK) { + if (OsCheckMutexAttr(&mutex->attr) != LOS_OK) {//检查属性 return LOS_EINVAL; } - SCHEDULER_LOCK(intSave); - mutex->muxCount = 0; - mutex->owner = NULL; - LOS_ListInit(&mutex->muxList); - mutex->magic = OS_MUX_MAGIC; - SCHEDULER_UNLOCK(intSave); + SCHEDULER_LOCK(intSave); //拿到调度自旋锁 + mutex->muxCount = 0; //锁定互斥量的次数 + mutex->owner = NULL; //谁持有该锁 + LOS_ListInit(&mutex->muxList); //互斥量双循环链表 + mutex->magic = OS_MUX_MAGIC; //固定标识,互斥锁的魔法数字 + SCHEDULER_UNLOCK(intSave); //释放调度自旋锁 return LOS_OK; } - +///销毁互斥锁 LITE_OS_SEC_TEXT UINT32 LOS_MuxDestroy(LosMux *mutex) { UINT32 intSave; @@ -241,22 +241,22 @@ LITE_OS_SEC_TEXT UINT32 LOS_MuxDestroy(LosMux *mutex) return LOS_EINVAL; } - SCHEDULER_LOCK(intSave); + SCHEDULER_LOCK(intSave); //保存调度自旋锁 if (mutex->magic != OS_MUX_MAGIC) { - SCHEDULER_UNLOCK(intSave); + SCHEDULER_UNLOCK(intSave);//释放调度自旋锁 return LOS_EBADF; } if (mutex->muxCount != 0) { - SCHEDULER_UNLOCK(intSave); + SCHEDULER_UNLOCK(intSave);//释放调度自旋锁 return LOS_EBUSY; } - (VOID)memset_s(mutex, sizeof(LosMux), 0, sizeof(LosMux)); - SCHEDULER_UNLOCK(intSave); + (VOID)memset_s(mutex, sizeof(LosMux), 0, sizeof(LosMux));//很简单,全部清0处理. + SCHEDULER_UNLOCK(intSave); //释放调度自旋锁 return LOS_OK; } - +///设置互斥锁位图 STATIC VOID OsMuxBitmapSet(const LosMux *mutex, const LosTaskCB *runTask) { if (mutex->attr.protocol != LOS_MUX_PRIO_INHERIT) { @@ -271,7 +271,7 @@ STATIC VOID OsMuxBitmapSet(const LosMux *mutex, const LosTaskCB *runTask) owner->ops->priorityInheritance(owner, ¶m); } } - +///恢复互斥锁位图 VOID OsMuxBitmapRestore(const LosMux *mutex, const LOS_DL_LIST *list, const LosTaskCB *runTask) { if (mutex->attr.protocol != LOS_MUX_PRIO_INHERIT) { @@ -284,20 +284,21 @@ VOID OsMuxBitmapRestore(const LosMux *mutex, const LOS_DL_LIST *list, const LosT owner->ops->priorityRestore(owner, list, ¶m); } +/// 最坏情况就是拿锁失败,让出CPU,变成阻塞任务,等别的任务释放锁后排到自己了接着执行. STATIC UINT32 OsMuxPendOp(LosTaskCB *runTask, LosMux *mutex, UINT32 timeout) { UINT32 ret; - if ((mutex->muxList.pstPrev == NULL) || (mutex->muxList.pstNext == NULL)) { + if ((mutex->muxList.pstPrev == NULL) || (mutex->muxList.pstNext == NULL)) {//列表为空时的处理 /* This is for mutex macro initialization. */ - mutex->muxCount = 0; - mutex->owner = NULL; - LOS_ListInit(&mutex->muxList); + mutex->muxCount = 0;//锁计数器清0 + mutex->owner = NULL;//锁没有归属任务 + LOS_ListInit(&mutex->muxList);//初始化锁的任务链表,后续申请这把锁任务都会挂上去 } - if (mutex->muxCount == 0) { - mutex->muxCount++; - mutex->owner = (VOID *)runTask; + if (mutex->muxCount == 0) {//无task用锁时,肯定能拿到锁了.在里面返回 + mutex->muxCount++; //互斥锁计数器加1 + mutex->owner = (VOID *)runTask; //当前任务拿到锁 LOS_ListTailInsert(&runTask->lockList, &mutex->holdList); if (mutex->attr.protocol == LOS_MUX_PRIO_PROTECT) { SchedParam param = { 0 }; @@ -307,23 +308,23 @@ STATIC UINT32 OsMuxPendOp(LosTaskCB *runTask, LosMux *mutex, UINT32 timeout) } return LOS_OK; } - - if (((LosTaskCB *)mutex->owner == runTask) && (mutex->attr.type == LOS_MUX_RECURSIVE)) { - mutex->muxCount++; - return LOS_OK; + //递归锁muxCount>0 如果是递归锁就要处理两种情况 1.runtask持有锁 2.锁被别的任务拿走了 + if (((LosTaskCB *)mutex->owner == runTask) && (mutex->attr.type == LOS_MUX_RECURSIVE)) {//第一种情况 runtask是锁持有方 + mutex->muxCount++; //递归锁计数器加1,递归锁的目的是防止死锁,鸿蒙默认用的就是递归锁(LOS_MUX_DEFAULT = LOS_MUX_RECURSIVE) + return LOS_OK; //成功退出 } - - if (!timeout) { - return LOS_EINVAL; + //到了这里说明锁在别的任务那里,当前任务只能被阻塞了. + if (!timeout) {//参数timeout表示等待多久再来拿锁 + return LOS_EINVAL;//timeout = 0表示不等了,没拿到锁就返回不纠结,返回错误.见于LOS_MuxTrylock } - - if (!OsPreemptableInSched()) { - return LOS_EDEADLK; + //自己要被阻塞,只能申请调度,让出CPU core 让别的任务上 + if (!OsPreemptableInSched()) {//不能申请调度 (不能调度的原因是因为没有持有调度任务自旋锁) + return LOS_EDEADLK;//返回错误,自旋锁被别的CPU core 持有 } - OsMuxBitmapSet(mutex, runTask); + OsMuxBitmapSet(mutex, runTask);//设置锁位图,尽可能的提高锁持有任务的优先级 - runTask->taskMux = (VOID *)mutex; + runTask->taskMux = (VOID *)mutex; //记下当前任务在等待这把锁 LOS_DL_LIST *node = OsSchedLockPendFindPos(runTask, &mutex->muxList); if (node == NULL) { ret = LOS_NOK; @@ -332,10 +333,10 @@ STATIC UINT32 OsMuxPendOp(LosTaskCB *runTask, LosMux *mutex, UINT32 timeout) OsTaskWaitSetPendMask(OS_TASK_WAIT_MUTEX, (UINTPTR)mutex, timeout); ret = runTask->ops->wait(runTask, node, timeout); - if (ret == LOS_ERRNO_TSK_TIMEOUT) { + if (ret == LOS_ERRNO_TSK_TIMEOUT) {//这行代码虽和OsTaskWait挨在一起,但要过很久才会执行到,因为在OsTaskWait中CPU切换了任务上下文 OsMuxBitmapRestore(mutex, NULL, runTask); - runTask->taskMux = NULL; - ret = LOS_ETIMEDOUT; + runTask->taskMux = NULL;// 所以重新回到这里时可能已经超时了 + ret = LOS_ETIMEDOUT;//返回超时 } return ret; @@ -343,7 +344,7 @@ STATIC UINT32 OsMuxPendOp(LosTaskCB *runTask, LosMux *mutex, UINT32 timeout) UINT32 OsMuxLockUnsafe(LosMux *mutex, UINT32 timeout) { - LosTaskCB *runTask = OsCurrTaskGet(); + LosTaskCB *runTask = OsCurrTaskGet();//获取当前任务 if (mutex->magic != OS_MUX_MAGIC) { return LOS_EBADF; @@ -352,23 +353,23 @@ UINT32 OsMuxLockUnsafe(LosMux *mutex, UINT32 timeout) if (OsCheckMutexAttr(&mutex->attr) != LOS_OK) { return LOS_EINVAL; } - + //LOS_MUX_ERRORCHECK 时 muxCount是要等于0 ,当前任务持有锁就不能再lock了. 鸿蒙默认用的是递归锁LOS_MUX_RECURSIVE if ((mutex->attr.type == LOS_MUX_ERRORCHECK) && (mutex->owner == (VOID *)runTask)) { return LOS_EDEADLK; } return OsMuxPendOp(runTask, mutex, timeout); } - +/// 尝试加锁, UINT32 OsMuxTrylockUnsafe(LosMux *mutex, UINT32 timeout) { - LosTaskCB *runTask = OsCurrTaskGet(); + LosTaskCB *runTask = OsCurrTaskGet();//获取当前任务 - if (mutex->magic != OS_MUX_MAGIC) { + if (mutex->magic != OS_MUX_MAGIC) {//检查MAGIC有没有被改变 return LOS_EBADF; } - if (OsCheckMutexAttr(&mutex->attr) != LOS_OK) { + if (OsCheckMutexAttr(&mutex->attr) != LOS_OK) {//检查互斥锁属性 return LOS_EINVAL; } @@ -377,9 +378,9 @@ UINT32 OsMuxTrylockUnsafe(LosMux *mutex, UINT32 timeout) return LOS_EBUSY; } - return OsMuxPendOp(runTask, mutex, timeout); + return OsMuxPendOp(runTask, mutex, timeout);//当前任务去拿锁,拿不到就等timeout } - +/// 拿互斥锁, LITE_OS_SEC_TEXT UINT32 LOS_MuxLock(LosMux *mutex, UINT32 timeout) { LosTaskCB *runTask = NULL; @@ -394,19 +395,19 @@ LITE_OS_SEC_TEXT UINT32 LOS_MuxLock(LosMux *mutex, UINT32 timeout) return LOS_EINTR; } - runTask = (LosTaskCB *)OsCurrTaskGet(); + runTask = (LosTaskCB *)OsCurrTaskGet();//获取当前任务 /* DO NOT Call blocking API in system tasks */ - if (runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) { + if (runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) {//不要在内核任务里用mux锁 PRINTK("Warning: DO NOT call %s in system tasks.\n", __FUNCTION__); - OsBackTrace(); + OsBackTrace();//打印task信息 } - SCHEDULER_LOCK(intSave); - ret = OsMuxLockUnsafe(mutex, timeout); + SCHEDULER_LOCK(intSave);//调度自旋锁 + ret = OsMuxLockUnsafe(mutex, timeout);//如果任务没拿到锁,将进入阻塞队列一直等待,直到timeout或者持锁任务释放锁时唤醒它 SCHEDULER_UNLOCK(intSave); return ret; } - +///尝试要锁,没拿到也不等,直接返回,不纠结 LITE_OS_SEC_TEXT UINT32 LOS_MuxTrylock(LosMux *mutex) { LosTaskCB *runTask = NULL; @@ -421,39 +422,40 @@ LITE_OS_SEC_TEXT UINT32 LOS_MuxTrylock(LosMux *mutex) return LOS_EINTR; } - runTask = (LosTaskCB *)OsCurrTaskGet(); + runTask = (LosTaskCB *)OsCurrTaskGet();//获取当前执行的任务 /* DO NOT Call blocking API in system tasks */ - if (runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) { + if (runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) {//系统任务不能 PRINTK("Warning: DO NOT call %s in system tasks.\n", __FUNCTION__); OsBackTrace(); } SCHEDULER_LOCK(intSave); - ret = OsMuxTrylockUnsafe(mutex, 0); + ret = OsMuxTrylockUnsafe(mutex, 0);//timeout = 0,不等待,没拿到锁就算了 SCHEDULER_UNLOCK(intSave); return ret; } + STATIC UINT32 OsMuxPostOp(LosTaskCB *taskCB, LosMux *mutex, BOOL *needSched) { - if (LOS_ListEmpty(&mutex->muxList)) { - LOS_ListDelete(&mutex->holdList); + if (LOS_ListEmpty(&mutex->muxList)) {//如果互斥锁列表为空 + LOS_ListDelete(&mutex->holdList);//把持有互斥锁的节点摘掉 mutex->owner = NULL; return LOS_OK; } - LosTaskCB *resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(mutex->muxList))); + LosTaskCB *resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(mutex->muxList)));//拿到等待互斥锁链表的第一个任务实体,接下来要唤醒任务 OsMuxBitmapRestore(mutex, &mutex->muxList, resumedTask); - mutex->muxCount = 1; - mutex->owner = (VOID *)resumedTask; - LOS_ListDelete(&mutex->holdList); - LOS_ListTailInsert(&resumedTask->lockList, &mutex->holdList); + mutex->muxCount = 1;//互斥锁数量为1 + mutex->owner = (VOID *)resumedTask;//互斥锁的持有人换了 + LOS_ListDelete(&mutex->holdList);//自然要从等锁链表中把自己摘出去 + LOS_ListTailInsert(&resumedTask->lockList, &mutex->holdList);//把锁挂到恢复任务的锁链表上,lockList是任务持有的所有锁记录 OsTaskWakeClearPendMask(resumedTask); resumedTask->ops->wake(resumedTask); resumedTask->taskMux = NULL; - if (needSched != NULL) { - *needSched = TRUE; + if (needSched != NULL) {//如果不为空 + *needSched = TRUE;//就走起再次调度流程 } return LOS_OK; @@ -476,21 +478,21 @@ UINT32 OsMuxUnlockUnsafe(LosTaskCB *taskCB, LosMux *mutex, BOOL *needSched) if (mutex->muxCount == 0) { return LOS_EPERM; } - - if ((--mutex->muxCount != 0) && (mutex->attr.type == LOS_MUX_RECURSIVE)) { + //注意 --mutex->muxCount 先执行了-- 操作. + if ((--mutex->muxCount != 0) && (mutex->attr.type == LOS_MUX_RECURSIVE)) {//属性类型为LOS_MUX_RECURSIVE时,muxCount是可以不为0的 return LOS_OK; } - if (mutex->attr.protocol == LOS_MUX_PRIO_PROTECT) { + if (mutex->attr.protocol == LOS_MUX_PRIO_PROTECT) {//属性协议为保护时 SchedParam param = { 0 }; taskCB->ops->schedParamGet(taskCB, ¶m); taskCB->ops->priorityRestore(taskCB, NULL, ¶m); } - /* Whether a task block the mutex lock. */ - return OsMuxPostOp(taskCB, mutex, needSched); + /* Whether a task block the mutex lock. *///任务是否阻塞互斥锁 + return OsMuxPostOp(taskCB, mutex, needSched);//一个任务去唤醒另一个在等锁的任务 } - +///释放锁 LITE_OS_SEC_TEXT UINT32 LOS_MuxUnlock(LosMux *mutex) { LosTaskCB *runTask = NULL; @@ -506,9 +508,9 @@ LITE_OS_SEC_TEXT UINT32 LOS_MuxUnlock(LosMux *mutex) return LOS_EINTR; } - runTask = (LosTaskCB *)OsCurrTaskGet(); + runTask = (LosTaskCB *)OsCurrTaskGet();//获取当前任务 /* DO NOT Call blocking API in system tasks */ - if (runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) { + if (runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) {//不能在系统任务里调用,因为很容易让系统任务发生死锁 PRINTK("Warning: DO NOT call %s in system tasks.\n", __FUNCTION__); OsBackTrace(); } @@ -516,12 +518,12 @@ LITE_OS_SEC_TEXT UINT32 LOS_MuxUnlock(LosMux *mutex) SCHEDULER_LOCK(intSave); ret = OsMuxUnlockUnsafe(runTask, mutex, &needSched); SCHEDULER_UNLOCK(intSave); - if (needSched == TRUE) { - LOS_MpSchedule(OS_MP_CPU_ALL); - LOS_Schedule(); + if (needSched == TRUE) {//需要调度的情况 + LOS_MpSchedule(OS_MP_CPU_ALL);//向所有CPU发送调度指令 + LOS_Schedule();//发起调度 } return ret; } -#endif /* LOSCFG_BASE_IPC_MUX */ +#endif /* (LOSCFG_BASE_IPC_MUX == YES) */ diff --git a/src/kernel_liteos_a/kernel/base/ipc/los_queue.c b/src/kernel_liteos_a/kernel/base/ipc/los_queue.c index 8fe06ba2..40a4c197 100644 --- a/src/kernel_liteos_a/kernel/base/ipc/los_queue.c +++ b/src/kernel_liteos_a/kernel/base/ipc/los_queue.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -47,8 +47,8 @@ #endif /* LOSCFG_BASE_IPC_QUEUE_LIMIT <= 0 */ #ifndef LOSCFG_IPC_CONTAINER -LITE_OS_SEC_BSS LosQueueCB *g_allQueue = NULL; -LITE_OS_SEC_BSS STATIC LOS_DL_LIST g_freeQueueList; +LITE_OS_SEC_BSS LosQueueCB *g_allQueue = NULL;///< 消息队列池 +LITE_OS_SEC_BSS STATIC LOS_DL_LIST g_freeQueueList;///< 空闲队列链表,管分配的,需要队列从这里申请 #define FREE_QUEUE_LIST g_freeQueueList #endif @@ -83,10 +83,6 @@ LITE_OS_SEC_TEXT_INIT LosQueueCB *OsAllQueueCBInit(LOS_DL_LIST *freeQueueList) return allQueue; } -/* - * Description : queue initial - * Return : LOS_OK on success or error code on failure - */ LITE_OS_SEC_TEXT_INIT UINT32 OsQueueInit(VOID) { #ifndef LOSCFG_IPC_CONTAINER @@ -97,7 +93,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsQueueInit(VOID) #endif return LOS_OK; } - +///创建一个队列,根据用户传入队列长度和消息节点大小来开辟相应的内存空间以供该队列使用,参数queueID带走队列ID LITE_OS_SEC_TEXT_INIT UINT32 LOS_QueueCreate(CHAR *queueName, UINT16 len, UINT32 *queueID, UINT32 flags, UINT16 maxMsgSize) { @@ -114,7 +110,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_QueueCreate(CHAR *queueName, UINT16 len, UINT32 return LOS_ERRNO_QUEUE_CREAT_PTR_NULL; } - if (maxMsgSize > (OS_NULL_SHORT - sizeof(UINT32))) { + if (maxMsgSize > (OS_NULL_SHORT - sizeof(UINT32))) {// maxMsgSize上限 为啥要减去 sizeof(UINT32) ,因为前面存的是队列的大小 return LOS_ERRNO_QUEUE_SIZE_TOO_BIG; } @@ -122,83 +118,83 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_QueueCreate(CHAR *queueName, UINT16 len, UINT32 return LOS_ERRNO_QUEUE_PARA_ISZERO; } - msgSize = maxMsgSize + sizeof(UINT32); + msgSize = maxMsgSize + sizeof(UINT32);//总size = 消息体内容长度 + 消息大小(UINT32) /* * Memory allocation is time-consuming, to shorten the time of disable interrupt, * move the memory allocation to here. - */ - queue = (UINT8 *)LOS_MemAlloc(m_aucSysMem1, (UINT32)len * msgSize); - if (queue == NULL) { - return LOS_ERRNO_QUEUE_CREATE_NO_MEMORY; + *///内存分配非常耗时,为了缩短禁用中断的时间,将内存分配移到此处,用的时候分配队列内存 + queue = (UINT8 *)LOS_MemAlloc(m_aucSysMem1, (UINT32)len * msgSize);//从系统内存池中分配,由这里提供读写队列的内存 + if (queue == NULL) {//这里是一次把队列要用到的所有最大内存都申请下来了,能保证不会出现后续使用过程中内存不够的问题出现 + return LOS_ERRNO_QUEUE_CREATE_NO_MEMORY;//调用处有 OsSwtmrInit sys_mbox_new DoMqueueCreate == } SCHEDULER_LOCK(intSave); - if (LOS_ListEmpty(&FREE_QUEUE_LIST)) { - SCHEDULER_UNLOCK(intSave); + if (LOS_ListEmpty(&FREE_QUEUE_LIST)) {//没有空余的队列ID的处理,注意软时钟定时器是由 g_swtmrCBArray统一管理的,里面有正在使用和可分配空闲的队列 + SCHEDULER_UNLOCK(intSave);//g_freeQueueList是管理可用于分配的队列链表,申请消息队列的ID需要向它要 OsQueueCheckHook(); - (VOID)LOS_MemFree(m_aucSysMem1, queue); + (VOID)LOS_MemFree(m_aucSysMem1, queue);//没有就要释放 queue申请的内存 return LOS_ERRNO_QUEUE_CB_UNAVAILABLE; } - unusedQueue = LOS_DL_LIST_FIRST(&FREE_QUEUE_LIST); - LOS_ListDelete(unusedQueue); - queueCB = GET_QUEUE_LIST(unusedQueue); - queueCB->queueLen = len; - queueCB->queueSize = msgSize; - queueCB->queueHandle = queue; - queueCB->queueState = OS_QUEUE_INUSED; - queueCB->readWriteableCnt[OS_QUEUE_READ] = 0; - queueCB->readWriteableCnt[OS_QUEUE_WRITE] = len; - queueCB->queueHead = 0; - queueCB->queueTail = 0; - LOS_ListInit(&queueCB->readWriteList[OS_QUEUE_READ]); - LOS_ListInit(&queueCB->readWriteList[OS_QUEUE_WRITE]); - LOS_ListInit(&queueCB->memList); - - OsQueueDbgUpdateHook(queueCB->queueID, OsCurrTaskGet()->taskEntry); + unusedQueue = LOS_DL_LIST_FIRST(&FREE_QUEUE_LIST);//找到一个没有被使用的队列 + LOS_ListDelete(unusedQueue);//将自己从g_freeQueueList中摘除, unusedQueue只是个 LOS_DL_LIST 结点. + queueCB = GET_QUEUE_LIST(unusedQueue);//通过unusedQueue找到整个消息队列(LosQueueCB) + queueCB->queueLen = len; //队列中消息的总个数,注意这个一旦创建是不能变的. + queueCB->queueSize = msgSize;//消息节点的大小,注意这个一旦创建也是不能变的. + queueCB->queueHandle = queue; //队列句柄,队列内容存储区. + queueCB->queueState = OS_QUEUE_INUSED; //队列状态使用中 + queueCB->readWriteableCnt[OS_QUEUE_READ] = 0;//可读资源计数,OS_QUEUE_READ(0):可读. + queueCB->readWriteableCnt[OS_QUEUE_WRITE] = len;//可些资源计数 OS_QUEUE_WRITE(1):可写, 默认len可写. + queueCB->queueHead = 0;//队列头节点 + queueCB->queueTail = 0;//队列尾节点 + LOS_ListInit(&queueCB->readWriteList[OS_QUEUE_READ]);//初始化可读队列任务链表 + LOS_ListInit(&queueCB->readWriteList[OS_QUEUE_WRITE]);//初始化可写队列任务链表 + LOS_ListInit(&queueCB->memList);// + + OsQueueDbgUpdateHook(queueCB->queueID, OsCurrTaskGet()->taskEntry);//在创建或删除队列调试信息时更新任务条目 SCHEDULER_UNLOCK(intSave); - *queueID = queueCB->queueID; + *queueID = queueCB->queueID;//带走队列ID OsHookCall(LOS_HOOK_TYPE_QUEUE_CREATE, queueCB); return LOS_OK; } - +///读队列参数检查 STATIC LITE_OS_SEC_TEXT UINT32 OsQueueReadParameterCheck(UINT32 queueID, const VOID *bufferAddr, const UINT32 *bufferSize, UINT32 timeout) { - if (GET_QUEUE_INDEX(queueID) >= LOSCFG_BASE_IPC_QUEUE_LIMIT) { + if (GET_QUEUE_INDEX(queueID) >= LOSCFG_BASE_IPC_QUEUE_LIMIT) {//队列ID不能超上限 return LOS_ERRNO_QUEUE_INVALID; } - if ((bufferAddr == NULL) || (bufferSize == NULL)) { + if ((bufferAddr == NULL) || (bufferSize == NULL)) {//缓存地址和大小参数判断 return LOS_ERRNO_QUEUE_READ_PTR_NULL; } - if ((*bufferSize == 0) || (*bufferSize > (OS_NULL_SHORT - sizeof(UINT32)))) { - return LOS_ERRNO_QUEUE_READSIZE_IS_INVALID; + if ((*bufferSize == 0) || (*bufferSize > (OS_NULL_SHORT - sizeof(UINT32)))) {//限制了读取数据的上限64K, sizeof(UINT32)代表的是队列的长度 + return LOS_ERRNO_QUEUE_READSIZE_IS_INVALID; //所以要减去 } OsQueueDbgTimeUpdateHook(queueID); - if (timeout != LOS_NO_WAIT) { - if (OS_INT_ACTIVE) { - return LOS_ERRNO_QUEUE_READ_IN_INTERRUPT; + if (timeout != LOS_NO_WAIT) {//等待一定时间再读取 + if (OS_INT_ACTIVE) {//如果碰上了硬中断 + return LOS_ERRNO_QUEUE_READ_IN_INTERRUPT;//意思是:硬中断发生时是不能读消息队列的 } } return LOS_OK; } - +///写队列参数检查 STATIC LITE_OS_SEC_TEXT UINT32 OsQueueWriteParameterCheck(UINT32 queueID, const VOID *bufferAddr, const UINT32 *bufferSize, UINT32 timeout) { - if (GET_QUEUE_INDEX(queueID) >= LOSCFG_BASE_IPC_QUEUE_LIMIT) { + if (GET_QUEUE_INDEX(queueID) >= LOSCFG_BASE_IPC_QUEUE_LIMIT) {//队列ID不能超上限 return LOS_ERRNO_QUEUE_INVALID; } - if (bufferAddr == NULL) { + if (bufferAddr == NULL) {//没有数据源 return LOS_ERRNO_QUEUE_WRITE_PTR_NULL; } - if (*bufferSize == 0) { + if (*bufferSize == 0) {//这里没有限制写队列的大小,如果写入一个很大buf 会怎样? return LOS_ERRNO_QUEUE_WRITESIZE_ISZERO; } @@ -211,128 +207,129 @@ STATIC LITE_OS_SEC_TEXT UINT32 OsQueueWriteParameterCheck(UINT32 queueID, const } return LOS_OK; } - +///队列buf操作,注意队列数据是按顺序来读取的,要不从头,要不从尾部,不会出现从中间读写,所有可由 head 和 tail 来管理队列. STATIC VOID OsQueueBufferOperate(LosQueueCB *queueCB, UINT32 operateType, VOID *bufferAddr, UINT32 *bufferSize) { UINT8 *queueNode = NULL; UINT32 msgDataSize; UINT16 queuePosition; - /* get the queue position */ - switch (OS_QUEUE_OPERATE_GET(operateType)) { - case OS_QUEUE_READ_HEAD: - queuePosition = queueCB->queueHead; - ((queueCB->queueHead + 1) == queueCB->queueLen) ? (queueCB->queueHead = 0) : (queueCB->queueHead++); + /* get the queue position | 先找到队列的位置*/ + switch (OS_QUEUE_OPERATE_GET(operateType)) {//获取操作类型 + case OS_QUEUE_READ_HEAD://从列队头开始读 + queuePosition = queueCB->queueHead;//拿到头部位置 + ((queueCB->queueHead + 1) == queueCB->queueLen) ? (queueCB->queueHead = 0) : (queueCB->queueHead++);//调整队列头部位置 break; - case OS_QUEUE_WRITE_HEAD: - (queueCB->queueHead == 0) ? (queueCB->queueHead = queueCB->queueLen - 1) : (--queueCB->queueHead); - queuePosition = queueCB->queueHead; + case OS_QUEUE_WRITE_HEAD://从列队头开始写 + (queueCB->queueHead == 0) ? (queueCB->queueHead = queueCB->queueLen - 1) : (--queueCB->queueHead);//调整队列头部位置 + queuePosition = queueCB->queueHead;//拿到头部位置 break; - case OS_QUEUE_WRITE_TAIL: - queuePosition = queueCB->queueTail; - ((queueCB->queueTail + 1) == queueCB->queueLen) ? (queueCB->queueTail = 0) : (queueCB->queueTail++); + case OS_QUEUE_WRITE_TAIL://从列队尾部开始写 + queuePosition = queueCB->queueTail;//设置队列位置为尾部位置 + ((queueCB->queueTail + 1) == queueCB->queueLen) ? (queueCB->queueTail = 0) : (queueCB->queueTail++);//调整队列尾部位置 break; default: /* read tail, reserved. */ PRINT_ERR("invalid queue operate type!\n"); return; } + //queueHandle是create队列时,由外界参数申请的一块内存. 用于copy 使用 + queueNode = &(queueCB->queueHandle[(queuePosition * (queueCB->queueSize))]);//拿到队列节点 - queueNode = &(queueCB->queueHandle[(queuePosition * (queueCB->queueSize))]); - - if (OS_QUEUE_IS_READ(operateType)) { + if (OS_QUEUE_IS_READ(operateType)) {//读操作处理,读队列分两步走 if (memcpy_s(&msgDataSize, sizeof(UINT32), queueNode + queueCB->queueSize - sizeof(UINT32), - sizeof(UINT32)) != EOK) { + sizeof(UINT32)) != EOK) {//1.先读出队列大小,由队列头四个字节表示 PRINT_ERR("get msgdatasize failed\n"); return; } msgDataSize = (*bufferSize < msgDataSize) ? *bufferSize : msgDataSize; - if (memcpy_s(bufferAddr, *bufferSize, queueNode, msgDataSize) != EOK) { + if (memcpy_s(bufferAddr, *bufferSize, queueNode, msgDataSize) != EOK) {//2.读表示读走已有数据,所以相当于bufferAddr接着了queueNode的数据 PRINT_ERR("copy message to buffer failed\n"); return; } - *bufferSize = msgDataSize; - } else { - if (memcpy_s(queueNode, queueCB->queueSize, bufferAddr, *bufferSize) != EOK) { - PRINT_ERR("store message failed\n"); + *bufferSize = msgDataSize;//通过入参 带走消息的大小 + } else {//只有读写两种操作,这里就是写队列了.写也分两步走 , @note_thinking 这里建议鸿蒙加上 OS_QUEUE_IS_WRITE 判断 + if (memcpy_s(queueNode, queueCB->queueSize, bufferAddr, *bufferSize) != EOK) {//1.写入消息内容 + PRINT_ERR("store message failed\n");//表示把外面数据写进来,所以相当于queueNode接着了bufferAddr的数据 return; } if (memcpy_s(queueNode + queueCB->queueSize - sizeof(UINT32), sizeof(UINT32), bufferSize, - sizeof(UINT32)) != EOK) { + sizeof(UINT32)) != EOK) {//2.写入消息数据的长度,sizeof(UINT32) PRINT_ERR("store message size failed\n"); return; } } } - +///队列操作参数检查 STATIC UINT32 OsQueueOperateParamCheck(const LosQueueCB *queueCB, UINT32 queueID, UINT32 operateType, const UINT32 *bufferSize) { - if ((queueCB->queueID != queueID) || (queueCB->queueState == OS_QUEUE_UNUSED)) { + if ((queueCB->queueID != queueID) || (queueCB->queueState == OS_QUEUE_UNUSED)) {//队列ID和状态判断 return LOS_ERRNO_QUEUE_NOT_CREATE; } - if (OS_QUEUE_IS_WRITE(operateType) && (*bufferSize > (queueCB->queueSize - sizeof(UINT32)))) { - return LOS_ERRNO_QUEUE_WRITE_SIZE_TOO_BIG; + if (OS_QUEUE_IS_WRITE(operateType) && (*bufferSize > (queueCB->queueSize - sizeof(UINT32)))) {//写时判断 + return LOS_ERRNO_QUEUE_WRITE_SIZE_TOO_BIG;//塞进来的数据太大,大于队列节点能承受的范围 } return LOS_OK; } + UINT32 OsQueueOperate(UINT32 queueID, UINT32 operateType, VOID *bufferAddr, UINT32 *bufferSize, UINT32 timeout) { UINT32 ret; - UINT32 readWrite = OS_QUEUE_READ_WRITE_GET(operateType); + UINT32 readWrite = OS_QUEUE_READ_WRITE_GET(operateType);//获取读/写操作标识 UINT32 intSave; OsHookCall(LOS_HOOK_TYPE_QUEUE_READ, (LosQueueCB *)GET_QUEUE_HANDLE(queueID), operateType, *bufferSize, timeout); SCHEDULER_LOCK(intSave); - LosQueueCB *queueCB = (LosQueueCB *)GET_QUEUE_HANDLE(queueID); - ret = OsQueueOperateParamCheck(queueCB, queueID, operateType, bufferSize); + LosQueueCB *queueCB = (LosQueueCB *)GET_QUEUE_HANDLE(queueID);//获取对应的队列控制块 + ret = OsQueueOperateParamCheck(queueCB, queueID, operateType, bufferSize);//参数检查 if (ret != LOS_OK) { goto QUEUE_END; } - if (queueCB->readWriteableCnt[readWrite] == 0) { - if (timeout == LOS_NO_WAIT) { + if (queueCB->readWriteableCnt[readWrite] == 0) {//根据readWriteableCnt判断队列是否有消息读/写 + if (timeout == LOS_NO_WAIT) {//不等待直接退出 ret = OS_QUEUE_IS_READ(operateType) ? LOS_ERRNO_QUEUE_ISEMPTY : LOS_ERRNO_QUEUE_ISFULL; goto QUEUE_END; } - if (!OsPreemptableInSched()) { + if (!OsPreemptableInSched()) {//不支持抢占式调度 ret = LOS_ERRNO_QUEUE_PEND_IN_LOCK; goto QUEUE_END; } - + //任务等待,这里很重要啊,将自己从就绪列表摘除,让出了CPU并发起了调度,并挂在readWriteList[readWrite]上,挂的都等待读/写消息的task LosTaskCB *runTask = OsCurrTaskGet(); OsTaskWaitSetPendMask(OS_TASK_WAIT_QUEUE, queueCB->queueID, timeout); ret = runTask->ops->wait(runTask, &queueCB->readWriteList[readWrite], timeout); - if (ret == LOS_ERRNO_TSK_TIMEOUT) { + if (ret == LOS_ERRNO_TSK_TIMEOUT) {//唤醒后如果超时了,返回读/写消息失败 ret = LOS_ERRNO_QUEUE_TIMEOUT; - goto QUEUE_END; + goto QUEUE_END;// } } else { - queueCB->readWriteableCnt[readWrite]--; + queueCB->readWriteableCnt[readWrite]--;//对应队列中计数器--,说明一条消息只能被读/写一次 } - OsQueueBufferOperate(queueCB, operateType, bufferAddr, bufferSize); + OsQueueBufferOperate(queueCB, operateType, bufferAddr, bufferSize);//发起读或写队列操作 - if (!LOS_ListEmpty(&queueCB->readWriteList[!readWrite])) { - LosTaskCB *resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&queueCB->readWriteList[!readWrite])); + if (!LOS_ListEmpty(&queueCB->readWriteList[!readWrite])) {//如果还有任务在排着队等待读/写入消息(当时不能读/写的原因有可能当时队列满了==) + LosTaskCB *resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&queueCB->readWriteList[!readWrite]));//取出要读/写消息的任务 OsTaskWakeClearPendMask(resumedTask); resumedTask->ops->wake(resumedTask); SCHEDULER_UNLOCK(intSave); - LOS_MpSchedule(OS_MP_CPU_ALL); - LOS_Schedule(); + LOS_MpSchedule(OS_MP_CPU_ALL);//让所有CPU发出调度申请,因为很可能那个要读/写消息的队列是由其他CPU执行 + LOS_Schedule();//申请调度 return LOS_OK; } else { - queueCB->readWriteableCnt[!readWrite]++; + queueCB->readWriteableCnt[!readWrite]++;//对应队列读/写中计数器++ } QUEUE_END: SCHEDULER_UNLOCK(intSave); return ret; } - +///接口函数定时读取消息队列 LITE_OS_SEC_TEXT UINT32 LOS_QueueReadCopy(UINT32 queueID, VOID *bufferAddr, UINT32 *bufferSize, @@ -341,15 +338,15 @@ LITE_OS_SEC_TEXT UINT32 LOS_QueueReadCopy(UINT32 queueID, UINT32 ret; UINT32 operateType; - ret = OsQueueReadParameterCheck(queueID, bufferAddr, bufferSize, timeout); + ret = OsQueueReadParameterCheck(queueID, bufferAddr, bufferSize, timeout);//参数检查 if (ret != LOS_OK) { return ret; } - operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_READ, OS_QUEUE_HEAD); - return OsQueueOperate(queueID, operateType, bufferAddr, bufferSize, timeout); + operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_READ, OS_QUEUE_HEAD);//从头开始读 + return OsQueueOperate(queueID, operateType, bufferAddr, bufferSize, timeout);//定时执行读操作 } - +///接口函数从队列头开始写 LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteHeadCopy(UINT32 queueID, VOID *bufferAddr, UINT32 bufferSize, @@ -358,15 +355,15 @@ LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteHeadCopy(UINT32 queueID, UINT32 ret; UINT32 operateType; - ret = OsQueueWriteParameterCheck(queueID, bufferAddr, &bufferSize, timeout); + ret = OsQueueWriteParameterCheck(queueID, bufferAddr, &bufferSize, timeout);//参数检查 if (ret != LOS_OK) { return ret; } - operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_WRITE, OS_QUEUE_HEAD); - return OsQueueOperate(queueID, operateType, bufferAddr, &bufferSize, timeout); + operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_WRITE, OS_QUEUE_HEAD);//从头开始写 + return OsQueueOperate(queueID, operateType, bufferAddr, &bufferSize, timeout);//执行写操作 } - +///接口函数 从队列尾部开始写 LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteCopy(UINT32 queueID, VOID *bufferAddr, UINT32 bufferSize, @@ -375,15 +372,16 @@ LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteCopy(UINT32 queueID, UINT32 ret; UINT32 operateType; - ret = OsQueueWriteParameterCheck(queueID, bufferAddr, &bufferSize, timeout); + ret = OsQueueWriteParameterCheck(queueID, bufferAddr, &bufferSize, timeout);//参数检查 if (ret != LOS_OK) { return ret; } - operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_WRITE, OS_QUEUE_TAIL); - return OsQueueOperate(queueID, operateType, bufferAddr, &bufferSize, timeout); + operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_WRITE, OS_QUEUE_TAIL);//从尾部开始写 + return OsQueueOperate(queueID, operateType, bufferAddr, &bufferSize, timeout);//执行写操作 } + LITE_OS_SEC_TEXT UINT32 LOS_QueueRead(UINT32 queueID, VOID *bufferAddr, UINT32 bufferSize, UINT32 timeout) { return LOS_QueueReadCopy(queueID, bufferAddr, &bufferSize, timeout); @@ -398,6 +396,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_QueueWrite(UINT32 queueID, VOID *bufferAddr, UINT32 return LOS_QueueWriteCopy(queueID, &bufferAddr, bufferSize, timeout); } + LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteHead(UINT32 queueID, VOID *bufferAddr, UINT32 bufferSize, @@ -410,6 +409,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteHead(UINT32 queueID, return LOS_QueueWriteHeadCopy(queueID, &bufferAddr, bufferSize, timeout); } + LITE_OS_SEC_TEXT_INIT UINT32 LOS_QueueDelete(UINT32 queueID) { LosQueueCB *queueCB = NULL; @@ -422,50 +422,50 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_QueueDelete(UINT32 queueID) } SCHEDULER_LOCK(intSave); - queueCB = (LosQueueCB *)GET_QUEUE_HANDLE(queueID); + queueCB = (LosQueueCB *)GET_QUEUE_HANDLE(queueID);//拿到队列实体 if ((queueCB->queueID != queueID) || (queueCB->queueState == OS_QUEUE_UNUSED)) { ret = LOS_ERRNO_QUEUE_NOT_CREATE; goto QUEUE_END; } - if (!LOS_ListEmpty(&queueCB->readWriteList[OS_QUEUE_READ])) { + if (!LOS_ListEmpty(&queueCB->readWriteList[OS_QUEUE_READ])) {//尚有任务要读数据 ret = LOS_ERRNO_QUEUE_IN_TSKUSE; goto QUEUE_END; } - if (!LOS_ListEmpty(&queueCB->readWriteList[OS_QUEUE_WRITE])) { + if (!LOS_ListEmpty(&queueCB->readWriteList[OS_QUEUE_WRITE])) {//尚有任务要写数据 ret = LOS_ERRNO_QUEUE_IN_TSKUSE; goto QUEUE_END; } - if (!LOS_ListEmpty(&queueCB->memList)) { + if (!LOS_ListEmpty(&queueCB->memList)) {// ret = LOS_ERRNO_QUEUE_IN_TSKUSE; goto QUEUE_END; } if ((queueCB->readWriteableCnt[OS_QUEUE_WRITE] + queueCB->readWriteableCnt[OS_QUEUE_READ]) != - queueCB->queueLen) { + queueCB->queueLen) {//读写队列的内容长度不等于总长度 ret = LOS_ERRNO_QUEUE_IN_TSKWRITE; goto QUEUE_END; } - queue = queueCB->queueHandle; - queueCB->queueHandle = NULL; - queueCB->queueState = OS_QUEUE_UNUSED; - queueCB->queueID = SET_QUEUE_ID(GET_QUEUE_COUNT(queueCB->queueID) + 1, GET_QUEUE_INDEX(queueCB->queueID)); + queue = queueCB->queueHandle; //队列buf + queueCB->queueHandle = NULL; // + queueCB->queueState = OS_QUEUE_UNUSED;//重置队列状态 + queueCB->queueID = SET_QUEUE_ID(GET_QUEUE_COUNT(queueCB->queueID) + 1, GET_QUEUE_INDEX(queueCB->queueID));//@note_why 这里需要这样做吗? OsQueueDbgUpdateHook(queueCB->queueID, NULL); - LOS_ListTailInsert(&FREE_QUEUE_LIST, &queueCB->readWriteList[OS_QUEUE_WRITE]); - SCHEDULER_UNLOCK(intSave); + LOS_ListTailInsert(&FREE_QUEUE_LIST, &queueCB->readWriteList[OS_QUEUE_WRITE]);//回收,将节点挂入可分配链表,等待重新被分配再利用 + SCHEDULER_UNLOCK(intSave); OsHookCall(LOS_HOOK_TYPE_QUEUE_DELETE, queueCB); - ret = LOS_MemFree(m_aucSysMem1, (VOID *)queue); + ret = LOS_MemFree(m_aucSysMem1, (VOID *)queue);//释放队列句柄 return ret; QUEUE_END: SCHEDULER_UNLOCK(intSave); return ret; } - +///外部接口, 获取队列信息,用queueInfo 把 LosQueueCB数据接走,QUEUE_INFO_S对内部数据的封装 LITE_OS_SEC_TEXT_MINOR UINT32 LOS_QueueInfoGet(UINT32 queueID, QUEUE_INFO_S *queueInfo) { UINT32 intSave; @@ -477,14 +477,14 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_QueueInfoGet(UINT32 queueID, QUEUE_INFO_S *que return LOS_ERRNO_QUEUE_PTR_NULL; } - if (GET_QUEUE_INDEX(queueID) >= LOSCFG_BASE_IPC_QUEUE_LIMIT) { + if (GET_QUEUE_INDEX(queueID) >= LOSCFG_BASE_IPC_QUEUE_LIMIT) {//1024 return LOS_ERRNO_QUEUE_INVALID; } - (VOID)memset_s((VOID *)queueInfo, sizeof(QUEUE_INFO_S), 0, sizeof(QUEUE_INFO_S)); + (VOID)memset_s((VOID *)queueInfo, sizeof(QUEUE_INFO_S), 0, sizeof(QUEUE_INFO_S));//接走数据之前先清0 SCHEDULER_LOCK(intSave); - queueCB = (LosQueueCB *)GET_QUEUE_HANDLE(queueID); + queueCB = (LosQueueCB *)GET_QUEUE_HANDLE(queueID);//通过队列ID获取 QCB if ((queueCB->queueID != queueID) || (queueCB->queueState == OS_QUEUE_UNUSED)) { ret = LOS_ERRNO_QUEUE_NOT_CREATE; goto QUEUE_END; @@ -495,19 +495,19 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_QueueInfoGet(UINT32 queueID, QUEUE_INFO_S *que queueInfo->usQueueSize = queueCB->queueSize; queueInfo->usQueueHead = queueCB->queueHead; queueInfo->usQueueTail = queueCB->queueTail; - queueInfo->usReadableCnt = queueCB->readWriteableCnt[OS_QUEUE_READ]; - queueInfo->usWritableCnt = queueCB->readWriteableCnt[OS_QUEUE_WRITE]; + queueInfo->usReadableCnt = queueCB->readWriteableCnt[OS_QUEUE_READ];//可读数 + queueInfo->usWritableCnt = queueCB->readWriteableCnt[OS_QUEUE_WRITE];//可写数 - LOS_DL_LIST_FOR_EACH_ENTRY(tskCB, &queueCB->readWriteList[OS_QUEUE_READ], LosTaskCB, pendList) { - queueInfo->uwWaitReadTask |= 1ULL << tskCB->taskID; - } + LOS_DL_LIST_FOR_EACH_ENTRY(tskCB, &queueCB->readWriteList[OS_QUEUE_READ], LosTaskCB, pendList) {//找出哪些task需要读消息 + queueInfo->uwWaitReadTask |= 1ULL << tskCB->taskID;//记录等待读消息的任务号, uwWaitReadTask 每一位代表一个任务编号 + }//0b..011011011 代表 0,1,3,4,6,7 号任务有数据等待读消息. - LOS_DL_LIST_FOR_EACH_ENTRY(tskCB, &queueCB->readWriteList[OS_QUEUE_WRITE], LosTaskCB, pendList) { - queueInfo->uwWaitWriteTask |= 1ULL << tskCB->taskID; - } + LOS_DL_LIST_FOR_EACH_ENTRY(tskCB, &queueCB->readWriteList[OS_QUEUE_WRITE], LosTaskCB, pendList) {//找出哪些task需要写消息 + queueInfo->uwWaitWriteTask |= 1ULL << tskCB->taskID;//记录等待写消息的任务号, uwWaitWriteTask 每一位代表一个任务编号 + }////0b..011011011 代表 0,1,3,4,6,7 号任务有数据等待写消息. - LOS_DL_LIST_FOR_EACH_ENTRY(tskCB, &queueCB->memList, LosTaskCB, pendList) { - queueInfo->uwWaitMemTask |= 1ULL << tskCB->taskID; + LOS_DL_LIST_FOR_EACH_ENTRY(tskCB, &queueCB->memList, LosTaskCB, pendList) {//同上 + queueInfo->uwWaitMemTask |= 1ULL << tskCB->taskID; //MailBox模块使用 } QUEUE_END: @@ -515,5 +515,5 @@ QUEUE_END: return ret; } -#endif /* LOSCFG_BASE_IPC_QUEUE */ +#endif /* (LOSCFG_BASE_IPC_QUEUE == YES) */ diff --git a/src/kernel_liteos_a/kernel/base/ipc/los_rwlock.c b/src/kernel_liteos_a/kernel/base/ipc/los_rwlock.c index 546fe831..5ddd3b81 100644 --- a/src/kernel_liteos_a/kernel/base/ipc/los_rwlock.c +++ b/src/kernel_liteos_a/kernel/base/ipc/los_rwlock.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -37,9 +37,10 @@ #include "los_exc.h" #include "los_sched_pri.h" + #ifdef LOSCFG_BASE_IPC_RWLOCK #define RWLOCK_COUNT_MASK 0x00FFFFFFU - +/// 判断读写锁有效性 BOOL LOS_RwlockIsValid(const LosRwlock *rwlock) { if ((rwlock != NULL) && ((rwlock->magic & RWLOCK_COUNT_MASK) == OS_RWLOCK_MAGIC)) { @@ -48,7 +49,7 @@ BOOL LOS_RwlockIsValid(const LosRwlock *rwlock) return FALSE; } - +/// 创建读写锁,初始化锁信息 UINT32 LOS_RwlockInit(LosRwlock *rwlock) { UINT32 intSave; @@ -71,7 +72,7 @@ UINT32 LOS_RwlockInit(LosRwlock *rwlock) SCHEDULER_UNLOCK(intSave); return LOS_OK; } - +/// 删除指定的读写锁 UINT32 LOS_RwlockDestroy(LosRwlock *rwlock) { UINT32 intSave; @@ -95,18 +96,18 @@ UINT32 LOS_RwlockDestroy(LosRwlock *rwlock) SCHEDULER_UNLOCK(intSave); return LOS_OK; } - +/// 读写锁检查 STATIC UINT32 OsRwlockCheck(const LosRwlock *rwlock) { if (rwlock == NULL) { return LOS_EINVAL; } - if (OS_INT_ACTIVE) { + if (OS_INT_ACTIVE) { // 读写锁不能在中断服务程序中使用。请想想为什么 ? return LOS_EINTR; } - /* DO NOT Call blocking API in system tasks */ + /* DO NOT Call blocking API in system tasks | 系统任务不能使用读写锁 */ LosTaskCB *runTask = (LosTaskCB *)OsCurrTaskGet(); if (runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) { return LOS_EPERM; @@ -114,19 +115,23 @@ STATIC UINT32 OsRwlockCheck(const LosRwlock *rwlock) return LOS_OK; } - +/// 指定任务优先级优先级是否低于 写锁任务最高优先级 STATIC BOOL OsRwlockPriCompare(LosTaskCB *runTask, LOS_DL_LIST *rwList) { if (!LOS_ListEmpty(rwList)) { - LosTaskCB *highestTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(rwList)); - if (OsSchedParamCompare(runTask, highestTask) < 0) { + LosTaskCB *highestTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(rwList));//首个写锁任务优先级是最高的 + if (OsSchedParamCompare(runTask, highestTask) < 0) {//如果当前任务优先级低于等待写锁任务 return TRUE; } return FALSE; } return TRUE; } - +/* 申请读模式下的锁,分三种情况: +1. 若无人持有锁,读任务可获得锁。 +2. 若有人持有锁,读任务可获得锁,读取顺序按照任务优先级。 +3. 若有人(非自己)持有写模式下的锁,则当前任务无法获得锁,直到写模式下的锁释放。 +*/ STATIC UINT32 OsRwlockRdPendOp(LosTaskCB *runTask, LosRwlock *rwlock, UINT32 timeout) { UINT32 ret; @@ -135,12 +140,12 @@ STATIC UINT32 OsRwlockRdPendOp(LosTaskCB *runTask, LosRwlock *rwlock, UINT32 tim * When the rwlock mode is read mode or free mode and the priority of the current read task * is higher than the first pended write task. current read task can obtain this rwlock. */ - if (rwlock->rwCount >= 0) { - if (OsRwlockPriCompare(runTask, &(rwlock->writeList))) { - if (rwlock->rwCount == INT8_MAX) { + if (rwlock->rwCount >= 0) {//第一和第二种情况 + if (OsRwlockPriCompare(runTask, &(rwlock->writeList))) {//读优先级低于写优先级,意思就是必须先写再读 + if (rwlock->rwCount == INT8_MAX) {//读锁任务达到上限 return LOS_EINVAL; } - rwlock->rwCount++; + rwlock->rwCount++;//拿读锁成功 return LOS_OK; } } @@ -149,45 +154,51 @@ STATIC UINT32 OsRwlockRdPendOp(LosTaskCB *runTask, LosRwlock *rwlock, UINT32 tim return LOS_EINVAL; } - if (!OsPreemptableInSched()) { + if (!OsPreemptableInSched()) {//不可抢占时 return LOS_EDEADLK; } - /* The current task is not allowed to obtain the write lock when it obtains the read lock. */ - if ((LosTaskCB *)(rwlock->writeOwner) == runTask) { + /* The current task is not allowed to obtain the write lock when it obtains the read lock. + | 当前任务在获得读锁时不允许获得写锁 */ + if ((LosTaskCB *)(rwlock->writeOwner) == runTask) { //拥有写锁任务是否为当前任务 return LOS_EINVAL; } /* * When the rwlock mode is write mode or the priority of the current read task * is lower than the first pended write task, current read task will be pended. + | 当 rwlock 模式为写模式或当前读任务的优先级低于第一个挂起的写任务时,当前读任务将被挂起。 + 反正就是写锁任务优先 */ - LOS_DL_LIST *node = OsSchedLockPendFindPos(runTask, &(rwlock->readList)); - ret = runTask->ops->wait(runTask, node, timeout); + LOS_DL_LIST *node = OsSchedLockPendFindPos(runTask, &(rwlock->readList));//找到要挂入的位置 + //例如现有链表内任务优先级为 0 3 8 9 23 当前为 10 时, 返回的是 9 这个节点 + ret = runTask->ops->wait(runTask, node, timeout);//从尾部插入读锁链表 由此变成了 0 3 8 9 10 23 if (ret == LOS_ERRNO_TSK_TIMEOUT) { return LOS_ETIMEDOUT; } return ret; } - +/// 申请写模式下的锁 STATIC UINT32 OsRwlockWrPendOp(LosTaskCB *runTask, LosRwlock *rwlock, UINT32 timeout) { UINT32 ret; - /* When the rwlock is free mode, current write task can obtain this rwlock. */ + /* When the rwlock is free mode, current write task can obtain this rwlock. + | 若该锁当前没有任务持有,或者持有该读模式下的锁的任务和申请该锁的任务为同一个任务,则申请成功,可立即获得写模式下的锁。*/ if (rwlock->rwCount == 0) { rwlock->rwCount = -1; - rwlock->writeOwner = (VOID *)runTask; + rwlock->writeOwner = (VOID *)runTask;//直接给当前进程锁 return LOS_OK; } - /* Current write task can use one rwlock once again if the rwlock owner is it. */ + /* Current write task can use one rwlock once again if the rwlock owner is it. + | 如果 rwlock 拥有者是当前写入任务,则它可以再次使用该锁。*/ if ((rwlock->rwCount < 0) && ((LosTaskCB *)(rwlock->writeOwner) == runTask)) { if (rwlock->rwCount == INT8_MIN) { return LOS_EINVAL; } - rwlock->rwCount--; + rwlock->rwCount--;//注意再次拥有算是两把写锁了. return LOS_OK; } @@ -201,9 +212,9 @@ STATIC UINT32 OsRwlockWrPendOp(LosTaskCB *runTask, LosRwlock *rwlock, UINT32 tim /* * When the rwlock is read mode or other write task obtains this rwlock, current - * write task will be pended. + * write task will be pended. | 当 rwlock 为读模式或其他写任务获得该 rwlock 时,当前的写任务将被挂起。直到读模式下的锁释放 */ - LOS_DL_LIST *node = OsSchedLockPendFindPos(runTask, &(rwlock->writeList)); + LOS_DL_LIST *node = OsSchedLockPendFindPos(runTask, &(rwlock->writeList));//找到要挂入的位置 ret = runTask->ops->wait(runTask, node, timeout); if (ret == LOS_ERRNO_TSK_TIMEOUT) { ret = LOS_ETIMEDOUT; @@ -265,20 +276,22 @@ UINT32 OsRwlockTryWrUnsafe(LosRwlock *rwlock, UINT32 timeout) return LOS_EBADF; } - /* When the rwlock is read mode, current write task will be pended. */ + /* When the rwlock is read mode, current write task will be pended. + | 当 rwlock 为读模式时,当前的写任务将被挂起。*/ if (rwlock->rwCount > 0) { return LOS_EBUSY; } - /* When other write task obtains this rwlock, current write task will be pended. */ + /* When other write task obtains this rwlock, current write task will be pended. + | 当其他写任务获得这个rwlock时,当前的写任务将被挂起。*/ LosTaskCB *runTask = OsCurrTaskGet(); if ((rwlock->rwCount < 0) && ((LosTaskCB *)(rwlock->writeOwner) != runTask)) { return LOS_EBUSY; } - return OsRwlockWrPendOp(runTask, rwlock, timeout); + return OsRwlockWrPendOp(runTask, rwlock, timeout);// } - +/// 申请指定的读模式下的锁 UINT32 LOS_RwlockRdLock(LosRwlock *rwlock, UINT32 timeout) { UINT32 intSave; @@ -293,7 +306,7 @@ UINT32 LOS_RwlockRdLock(LosRwlock *rwlock, UINT32 timeout) SCHEDULER_UNLOCK(intSave); return ret; } - +/// 尝试申请指定的读模式下的锁 UINT32 LOS_RwlockTryRdLock(LosRwlock *rwlock) { UINT32 intSave; @@ -304,11 +317,11 @@ UINT32 LOS_RwlockTryRdLock(LosRwlock *rwlock) } SCHEDULER_LOCK(intSave); - ret = OsRwlockTryRdUnsafe(rwlock, 0); + ret = OsRwlockTryRdUnsafe(rwlock, 0);//所谓尝试就是没锁爷就返回,不等待,不纠结.当前任务也不会被挂起 SCHEDULER_UNLOCK(intSave); return ret; } - +/// 申请指定的写模式下的锁 UINT32 LOS_RwlockWrLock(LosRwlock *rwlock, UINT32 timeout) { UINT32 intSave; @@ -323,7 +336,7 @@ UINT32 LOS_RwlockWrLock(LosRwlock *rwlock, UINT32 timeout) SCHEDULER_UNLOCK(intSave); return ret; } - +/// 尝试申请指定的写模式下的锁 UINT32 LOS_RwlockTryWrLock(LosRwlock *rwlock) { UINT32 intSave; @@ -334,32 +347,32 @@ UINT32 LOS_RwlockTryWrLock(LosRwlock *rwlock) } SCHEDULER_LOCK(intSave); - ret = OsRwlockTryWrUnsafe(rwlock, 0); + ret = OsRwlockTryWrUnsafe(rwlock, 0);//所谓尝试就是没锁爷就返回,不等待,不纠结.当前任务也不会被挂起 SCHEDULER_UNLOCK(intSave); return ret; } - +/// 获取读写锁模式 STATIC UINT32 OsRwlockGetMode(LOS_DL_LIST *readList, LOS_DL_LIST *writeList) { BOOL isReadEmpty = LOS_ListEmpty(readList); BOOL isWriteEmpty = LOS_ListEmpty(writeList); - if (isReadEmpty && isWriteEmpty) { - return RWLOCK_NONE_MODE; + if (isReadEmpty && isWriteEmpty) { //读写链表都没有内容 + return RWLOCK_NONE_MODE; //自由模式 } - if (!isReadEmpty && isWriteEmpty) { + if (!isReadEmpty && isWriteEmpty) { //读链表有数据,写链表没有数据 return RWLOCK_READ_MODE; } - if (isReadEmpty && !isWriteEmpty) { + if (isReadEmpty && !isWriteEmpty) { //写链表有数据,读链表没有数据 return RWLOCK_WRITE_MODE; } LosTaskCB *pendedReadTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(readList)); LosTaskCB *pendedWriteTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(writeList)); if (OsSchedParamCompare(pendedWriteTask, pendedReadTask) <= 0) { - return RWLOCK_WRITEFIRST_MODE; + return RWLOCK_WRITEFIRST_MODE; //写的优先级高时,为写优先模式 } - return RWLOCK_READFIRST_MODE; + return RWLOCK_READFIRST_MODE; //读的优先级高时,为读优先模式 } - +/// 释放锁 STATIC UINT32 OsRwlockPostOp(LosRwlock *rwlock, BOOL *needSched) { UINT32 rwlockMode; @@ -367,15 +380,15 @@ STATIC UINT32 OsRwlockPostOp(LosRwlock *rwlock, BOOL *needSched) rwlock->rwCount = 0; rwlock->writeOwner = NULL; - rwlockMode = OsRwlockGetMode(&(rwlock->readList), &(rwlock->writeList)); - if (rwlockMode == RWLOCK_NONE_MODE) { + rwlockMode = OsRwlockGetMode(&(rwlock->readList), &(rwlock->writeList));//先获取模式 + if (rwlockMode == RWLOCK_NONE_MODE) {//自由模式则正常返回 return LOS_OK; } - /* In this case, rwlock will wake the first pended write task. */ - if ((rwlockMode == RWLOCK_WRITE_MODE) || (rwlockMode == RWLOCK_WRITEFIRST_MODE)) { - resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(rwlock->writeList))); - rwlock->rwCount = -1; - rwlock->writeOwner = (VOID *)resumedTask; + /* In this case, rwlock will wake the first pended write task. | 在这种情况下,rwlock 将唤醒第一个挂起的写任务。 */ + if ((rwlockMode == RWLOCK_WRITE_MODE) || (rwlockMode == RWLOCK_WRITEFIRST_MODE)) {//如果当前是写模式 (有任务在等写锁涅) + resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(rwlock->writeList)));//获取任务实体 + rwlock->rwCount = -1;//直接干成-1,注意这里并不是 -- + rwlock->writeOwner = (VOID *)resumedTask;//有锁了则唤醒等锁的任务(写模式) resumedTask->ops->wake(resumedTask); if (needSched != NULL) { *needSched = TRUE; @@ -383,29 +396,30 @@ STATIC UINT32 OsRwlockPostOp(LosRwlock *rwlock, BOOL *needSched) return LOS_OK; } - rwlock->rwCount = 1; + rwlock->rwCount = 1; //直接干成1,因为是释放操作 resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(rwlock->readList))); resumedTask->ops->wake(resumedTask); - while (!LOS_ListEmpty(&(rwlock->readList))) { + while (!LOS_ListEmpty(&(rwlock->readList))) {//遍历读链表,目的是要唤醒其他读模式的任务(优先级得要高于pendedWriteTaskPri才行) resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(rwlock->readList))); if (rwlockMode == RWLOCK_READFIRST_MODE) { LosTaskCB *pendedWriteTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(rwlock->writeList))); if (OsSchedParamCompare(resumedTask, pendedWriteTask) >= 0) { - break; - } + break;//跳出循环 + } } if (rwlock->rwCount == INT8_MAX) { return EINVAL; } - rwlock->rwCount++; - resumedTask->ops->wake(resumedTask); + rwlock->rwCount++;//读锁任务数量增加 + resumedTask->ops->wake(resumedTask);//不断唤醒读锁任务,由此实现了允许多个读操作并发,因为在多核情况下resumedTask很大可能 + //与当前任务并不在同一个核上运行, 此处非常有意思,点赞! @note_good } if (needSched != NULL) { *needSched = TRUE; } return LOS_OK; } - +/// 释放锁,唤醒任务 UINT32 OsRwlockUnlockUnsafe(LosRwlock *rwlock, BOOL *needSched) { if ((rwlock->magic & RWLOCK_COUNT_MASK) != OS_RWLOCK_MAGIC) { @@ -417,27 +431,28 @@ UINT32 OsRwlockUnlockUnsafe(LosRwlock *rwlock, BOOL *needSched) } LosTaskCB *runTask = OsCurrTaskGet(); - if ((rwlock->rwCount < 0) && ((LosTaskCB *)(rwlock->writeOwner) != runTask)) { + if ((rwlock->rwCount < 0) && ((LosTaskCB *)(rwlock->writeOwner) != runTask)) {//写模式时,当前任务未持有锁 return LOS_EPERM; } /* * When the rwCount of the rwlock more than 1 or less than -1, the rwlock mode will * not changed after current unlock operation, so pended tasks can not be waken. + | 当 rwlock 的 rwCount 大于 1 或小于 -1 时,当前解锁操作后 rwlock 模式不会改变,因此挂起的任务不能被唤醒。 */ - if (rwlock->rwCount > 1) { + if (rwlock->rwCount > 1) {//读模式 rwlock->rwCount--; return LOS_OK; } - if (rwlock->rwCount < -1) { + if (rwlock->rwCount < -1) {//写模式 rwlock->rwCount++; return LOS_OK; } return OsRwlockPostOp(rwlock, needSched); } - +/// 释放指定读写锁 UINT32 LOS_RwlockUnLock(LosRwlock *rwlock) { UINT32 intSave; @@ -451,9 +466,9 @@ UINT32 LOS_RwlockUnLock(LosRwlock *rwlock) SCHEDULER_LOCK(intSave); ret = OsRwlockUnlockUnsafe(rwlock, &needSched); SCHEDULER_UNLOCK(intSave); - LOS_MpSchedule(OS_MP_CPU_ALL); - if (needSched == TRUE) { - LOS_Schedule(); + LOS_MpSchedule(OS_MP_CPU_ALL);//设置调度CPU的方式,所有CPU参与调度 + if (needSched == TRUE) {//是否需要调度 + LOS_Schedule();//产生调度,切换任务执行 } return ret; } diff --git a/src/kernel_liteos_a/kernel/base/ipc/los_sem.c b/src/kernel_liteos_a/kernel/base/ipc/los_sem.c index 31d484a1..a161a85c 100644 --- a/src/kernel_liteos_a/kernel/base/ipc/los_sem.c +++ b/src/kernel_liteos_a/kernel/base/ipc/los_sem.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -40,17 +40,18 @@ #include "los_percpu_pri.h" #include "los_hook.h" + #ifdef LOSCFG_BASE_IPC_SEM #if (LOSCFG_BASE_IPC_SEM_LIMIT <= 0) #error "sem maxnum cannot be zero" #endif /* LOSCFG_BASE_IPC_SEM_LIMIT <= 0 */ -LITE_OS_SEC_DATA_INIT STATIC LOS_DL_LIST g_unusedSemList; -LITE_OS_SEC_BSS LosSemCB *g_allSem = NULL; +LITE_OS_SEC_DATA_INIT STATIC LOS_DL_LIST g_unusedSemList; ///< 可用的信号量列表,干嘛不用freeList? 可以看出这里是另一个人写的代码 +LITE_OS_SEC_BSS LosSemCB *g_allSem = NULL; ///< 信号池,一次分配 LOSCFG_BASE_IPC_SEM_LIMIT 个信号量 /* - * Description : Initialize the semaphore doubly linked list + * Description : Initialize the semaphore doubly linked list | 信号量初始化 * Return : LOS_OK on success, or error code on failure */ LITE_OS_SEC_TEXT_INIT UINT32 OsSemInit(VOID) @@ -58,18 +59,18 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSemInit(VOID) LosSemCB *semNode = NULL; UINT32 index; - LOS_ListInit(&g_unusedSemList); + LOS_ListInit(&g_unusedSemList);//初始化链表,链表上挂未使用的信号量,用于分配信号量,鸿蒙信号量的个数是有限的,默认1024个 /* system resident memory, don't free */ - g_allSem = (LosSemCB *)LOS_MemAlloc(m_aucSysMem0, (LOSCFG_BASE_IPC_SEM_LIMIT * sizeof(LosSemCB))); + g_allSem = (LosSemCB *)LOS_MemAlloc(m_aucSysMem0, (LOSCFG_BASE_IPC_SEM_LIMIT * sizeof(LosSemCB)));//分配信号池 if (g_allSem == NULL) { return LOS_ERRNO_SEM_NO_MEMORY; } for (index = 0; index < LOSCFG_BASE_IPC_SEM_LIMIT; index++) { - semNode = ((LosSemCB *)g_allSem) + index; - semNode->semID = SET_SEM_ID(0, index); - semNode->semStat = OS_SEM_UNUSED; - LOS_ListTailInsert(&g_unusedSemList, &semNode->semList); + semNode = ((LosSemCB *)g_allSem) + index;//拿信号控制块, 可以直接g_allSem[index]来嘛 + semNode->semID = SET_SEM_ID(0, index);//保存ID + semNode->semStat = OS_SEM_UNUSED;//标记未使用 + LOS_ListTailInsert(&g_unusedSemList, &semNode->semList);//通过semList把 信号块挂到空闲链表上 } if (OsSemDbgInitHook() != LOS_OK) { @@ -78,13 +79,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSemInit(VOID) return LOS_OK; } -/* - * Description : Create a semaphore, - * Input : count --- semaphore count, - * maxCount --- Max number of available semaphores, - * semHandle --- Index of semaphore, - * Return : LOS_OK on success ,or error code on failure - */ + LITE_OS_SEC_TEXT_INIT UINT32 OsSemCreate(UINT16 count, UINT16 maxCount, UINT32 *semHandle) { UINT32 intSave; @@ -97,45 +92,46 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSemCreate(UINT16 count, UINT16 maxCount, UINT32 * return LOS_ERRNO_SEM_PTR_NULL; } - if (count > maxCount) { + if (count > maxCount) {//信号量不能大于最大值,两参数都是外面给的 OS_GOTO_ERR_HANDLER(LOS_ERRNO_SEM_OVERFLOW); } - SCHEDULER_LOCK(intSave); + SCHEDULER_LOCK(intSave);//进入临界区,拿自旋锁 - if (LOS_ListEmpty(&g_unusedSemList)) { + if (LOS_ListEmpty(&g_unusedSemList)) {//没有可分配的空闲信号提供 SCHEDULER_UNLOCK(intSave); OsSemInfoGetFullDataHook(); OS_GOTO_ERR_HANDLER(LOS_ERRNO_SEM_ALL_BUSY); } - unusedSem = LOS_DL_LIST_FIRST(&g_unusedSemList); - LOS_ListDelete(unusedSem); + unusedSem = LOS_DL_LIST_FIRST(&g_unusedSemList);//从未使用信号量池中取首个 + LOS_ListDelete(unusedSem);//从空闲链表上摘除 SCHEDULER_UNLOCK(intSave); - semCreated = GET_SEM_LIST(unusedSem); - semCreated->semCount = count; - semCreated->semStat = OS_SEM_USED; - semCreated->maxSemCount = maxCount; - LOS_ListInit(&semCreated->semList); - *semHandle = semCreated->semID; + semCreated = GET_SEM_LIST(unusedSem);//通过semList挂到链表上的,这里也要通过它把LosSemCB头查到. 进程,线程等结构体也都是这么干的. + semCreated->semCount = count;//设置数量 + semCreated->semStat = OS_SEM_USED;//设置可用状态 + semCreated->maxSemCount = maxCount;//设置最大信号数量 + LOS_ListInit(&semCreated->semList);//初始化链表,后续阻塞任务通过task->pendList挂到semList链表上,就知道哪些任务在等它了. + *semHandle = semCreated->semID;//参数带走 semID OsHookCall(LOS_HOOK_TYPE_SEM_CREATE, semCreated); OsSemDbgUpdateHook(semCreated->semID, OsCurrTaskGet()->taskEntry, count); + return LOS_OK; ERR_HANDLER: OS_RETURN_ERROR_P2(errLine, errNo); } - +///对外接口 创建信号量 LITE_OS_SEC_TEXT_INIT UINT32 LOS_SemCreate(UINT16 count, UINT32 *semHandle) { return OsSemCreate(count, OS_SEM_COUNT_MAX, semHandle); } - +///对外接口 创建二值信号量,其计数值最大为1,可以当互斥锁用 LITE_OS_SEC_TEXT_INIT UINT32 LOS_BinarySemCreate(UINT16 count, UINT32 *semHandle) { return OsSemCreate(count, OS_SEM_BINARY_COUNT_MAX, semHandle); } - +///对外接口 删除指定的信号量,参数就是 semID LITE_OS_SEC_TEXT_INIT UINT32 LOS_SemDelete(UINT32 semHandle) { UINT32 intSave; @@ -147,23 +143,23 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_SemDelete(UINT32 semHandle) OS_GOTO_ERR_HANDLER(LOS_ERRNO_SEM_INVALID); } - semDeleted = GET_SEM(semHandle); + semDeleted = GET_SEM(semHandle);//通过ID拿到信号量实体 SCHEDULER_LOCK(intSave); - if ((semDeleted->semStat == OS_SEM_UNUSED) || (semDeleted->semID != semHandle)) { + if ((semDeleted->semStat == OS_SEM_UNUSED) || (semDeleted->semID != semHandle)) {//参数判断 SCHEDULER_UNLOCK(intSave); OS_GOTO_ERR_HANDLER(LOS_ERRNO_SEM_INVALID); } - if (!LOS_ListEmpty(&semDeleted->semList)) { + if (!LOS_ListEmpty(&semDeleted->semList)) {//当前还有任务挂在这个信号上面,当然不能删除 SCHEDULER_UNLOCK(intSave); - OS_GOTO_ERR_HANDLER(LOS_ERRNO_SEM_PENDED); + OS_GOTO_ERR_HANDLER(LOS_ERRNO_SEM_PENDED);//这个宏很有意思,里面goto到ERR_HANDLER } - LOS_ListTailInsert(&g_unusedSemList, &semDeleted->semList); - semDeleted->semStat = OS_SEM_UNUSED; - semDeleted->semID = SET_SEM_ID(GET_SEM_COUNT(semDeleted->semID) + 1, GET_SEM_INDEX(semDeleted->semID)); + LOS_ListTailInsert(&g_unusedSemList, &semDeleted->semList);//通过semList从尾部插入空闲链表 + semDeleted->semStat = OS_SEM_UNUSED;//状态变成了未使用 + semDeleted->semID = SET_SEM_ID(GET_SEM_COUNT(semDeleted->semID) + 1, GET_SEM_INDEX(semDeleted->semID));//设置ID OsHookCall(LOS_HOOK_TYPE_SEM_DELETE, semDeleted); OsSemDbgUpdateHook(semDeleted->semID, NULL, 0); @@ -174,11 +170,11 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_SemDelete(UINT32 semHandle) ERR_HANDLER: OS_RETURN_ERROR_P2(errLine, errNo); } - +///对外接口 申请指定的信号量,并设置超时时间 LITE_OS_SEC_TEXT UINT32 LOS_SemPend(UINT32 semHandle, UINT32 timeout) { UINT32 intSave; - LosSemCB *semPended = GET_SEM(semHandle); + LosSemCB *semPended = GET_SEM(semHandle);//通过ID拿到信号体 UINT32 retErr = LOS_OK; LosTaskCB *runTask = NULL; @@ -192,7 +188,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_SemPend(UINT32 semHandle, UINT32 timeout) return LOS_ERRNO_SEM_PEND_INTERR; } - runTask = OsCurrTaskGet(); + runTask = OsCurrTaskGet();//获取当前任务 if (runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) { OsBackTrace(); return LOS_ERRNO_SEM_PEND_IN_SYSTEM_TASK; @@ -204,19 +200,20 @@ LITE_OS_SEC_TEXT UINT32 LOS_SemPend(UINT32 semHandle, UINT32 timeout) retErr = LOS_ERRNO_SEM_INVALID; goto OUT; } + /* Update the operate time, no matter the actual Pend success or not */ OsSemDbgTimeUpdateHook(semHandle); - if (semPended->semCount > 0) { - semPended->semCount--; + if (semPended->semCount > 0) {//还有资源可用,返回肯定得成功,semCount=0时代表没资源了,task会必须去睡眠了 + semPended->semCount--;//资源少了一个 OsHookCall(LOS_HOOK_TYPE_SEM_PEND, semPended, runTask, timeout); - goto OUT; + goto OUT;//注意这里 retErr = LOS_OK ,所以返回是OK的 } else if (!timeout) { retErr = LOS_ERRNO_SEM_UNAVAILABLE; goto OUT; } - if (!OsPreemptableInSched()) { + if (!OsPreemptableInSched()) {//不能申请调度 (不能调度的原因是因为没有持有调度任务自旋锁) PRINT_ERR("!!!LOS_ERRNO_SEM_PEND_IN_LOCK!!!\n"); OsBackTrace(); retErr = LOS_ERRNO_SEM_PEND_IN_LOCK; @@ -226,7 +223,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_SemPend(UINT32 semHandle, UINT32 timeout) OsHookCall(LOS_HOOK_TYPE_SEM_PEND, semPended, runTask, timeout); OsTaskWaitSetPendMask(OS_TASK_WAIT_SEM, semPended->semID, timeout); retErr = runTask->ops->wait(runTask, &semPended->semList, timeout); - if (retErr == LOS_ERRNO_TSK_TIMEOUT) { + if (retErr == LOS_ERRNO_TSK_TIMEOUT) {//注意:这里是涉及到task切换的,把自己挂起,唤醒其他task retErr = LOS_ERRNO_SEM_TIMEOUT; } @@ -234,7 +231,7 @@ OUT: SCHEDULER_UNLOCK(intSave); return retErr; } - +///以不安全的方式释放指定的信号量,所谓不安全指的是不用自旋锁 LITE_OS_SEC_TEXT UINT32 OsSemPostUnsafe(UINT32 semHandle, BOOL *needSched) { LosTaskCB *resumedTask = NULL; @@ -246,23 +243,23 @@ LITE_OS_SEC_TEXT UINT32 OsSemPostUnsafe(UINT32 semHandle, BOOL *needSched) /* Update the operate time, no matter the actual Post success or not */ OsSemDbgTimeUpdateHook(semHandle); - if (semPosted->semCount == OS_SEM_COUNT_MAX) { + if (semPosted->semCount == OS_SEM_COUNT_MAX) {//当前信号资源不能大于最大资源量 return LOS_ERRNO_SEM_OVERFLOW; } - if (!LOS_ListEmpty(&semPosted->semList)) { - resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(semPosted->semList))); + if (!LOS_ListEmpty(&semPosted->semList)) {//当前有任务挂在semList上,要去唤醒任务 + resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(semPosted->semList)));//semList上面挂的都是task->pendlist节点,取第一个task下来唤醒 OsTaskWakeClearPendMask(resumedTask); resumedTask->ops->wake(resumedTask); - if (needSched != NULL) { - *needSched = TRUE; + if (needSched != NULL) {//参数不为空,就返回需要调度的标签 + *needSched = TRUE;//TRUE代表需要调度 } - } else { - semPosted->semCount++; + } else {//当前没有任务挂在semList上, + semPosted->semCount++;//信号资源多一个 } OsHookCall(LOS_HOOK_TYPE_SEM_POST, semPosted, resumedTask); return LOS_OK; } - +///对外接口 释放指定的信号量 LITE_OS_SEC_TEXT UINT32 LOS_SemPost(UINT32 semHandle) { UINT32 intSave; @@ -272,16 +269,15 @@ LITE_OS_SEC_TEXT UINT32 LOS_SemPost(UINT32 semHandle) if (GET_SEM_INDEX(semHandle) >= LOSCFG_BASE_IPC_SEM_LIMIT) { return LOS_ERRNO_SEM_INVALID; } - SCHEDULER_LOCK(intSave); ret = OsSemPostUnsafe(semHandle, &needSched); SCHEDULER_UNLOCK(intSave); - if (needSched) { - LOS_MpSchedule(OS_MP_CPU_ALL); - LOS_Schedule(); + if (needSched) {//需要调度的情况 + LOS_MpSchedule(OS_MP_CPU_ALL);//向所有CPU发送调度指令 + LOS_Schedule();////发起调度 } return ret; } -#endif /* LOSCFG_BASE_IPC_SEM */ +#endif /* (LOSCFG_BASE_IPC_SEM == YES) */ diff --git a/src/kernel_liteos_a/kernel/base/ipc/los_sem_debug.c b/src/kernel_liteos_a/kernel/base/ipc/los_sem_debug.c index 1ed42515..284a800d 100644 --- a/src/kernel_liteos_a/kernel/base/ipc/los_sem_debug.c +++ b/src/kernel_liteos_a/kernel/base/ipc/los_sem_debug.c @@ -78,11 +78,11 @@ STATIC VOID OsSemPendedTaskNamePrint(LosSemCB *semNode) #ifdef LOSCFG_DEBUG_SEMAPHORE typedef struct { - UINT16 origSemCount; /* Number of original available semaphores */ - UINT64 lastAccessTime; /* The last operation time */ - TSK_ENTRY_FUNC creator; /* The task entry who created this sem */ + UINT16 origSemCount; /* Number of orignal available semaphores *///原始可用信号量数 + UINT64 lastAccessTime; /* The last operation time */ //最后操作时间 + TSK_ENTRY_FUNC creator; /* The task entry who created this sem */ //由哪个task的入口函数创建了这个任务 } SemDebugCB; -STATIC SemDebugCB *g_semDebugArray = NULL; +STATIC SemDebugCB *g_semDebugArray = NULL;//默认1024个SemDebugCB debug信号量池 STATIC BOOL SemCompareValue(const IpcSortParam *sortParam, UINT32 left, UINT32 right) { @@ -102,23 +102,23 @@ UINT32 OsSemDbgInit(VOID) (VOID)memset_s(g_semDebugArray, size, 0, size); return LOS_OK; } - +///更新最后访问时间 VOID OsSemDbgTimeUpdate(UINT32 semID) { SemDebugCB *semDebug = &g_semDebugArray[GET_SEM_INDEX(semID)]; - semDebug->lastAccessTime = LOS_TickCountGet(); + semDebug->lastAccessTime = LOS_TickCountGet();//获取tick总数 return; } - +///更新信号量 VOID OsSemDbgUpdate(UINT32 semID, TSK_ENTRY_FUNC creator, UINT16 count) { SemDebugCB *semDebug = &g_semDebugArray[GET_SEM_INDEX(semID)]; - semDebug->creator = creator; - semDebug->lastAccessTime = LOS_TickCountGet(); - semDebug->origSemCount = count; + semDebug->creator = creator; //改为由参数入口函数创建了这个任务 + semDebug->lastAccessTime = LOS_TickCountGet();//获取tick总数 + semDebug->origSemCount = count;//原始信号量改变 return; } - +///按信号量访问时间排序 STATIC VOID OsSemSort(UINT32 *semIndexArray, UINT32 usedCount) { UINT32 i, intSave; @@ -296,6 +296,6 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdSemInfoGet(UINT32 argc, const CHAR **arg return ret; } -SHELLCMD_ENTRY(sem_shellcmd, CMD_TYPE_EX, "sem", 1, (CmdCallBackFunc)OsShellCmdSemInfoGet); +SHELLCMD_ENTRY(sem_shellcmd, CMD_TYPE_EX, "sem", 1, (CmdCallBackFunc)OsShellCmdSemInfoGet);//采用shell命令静态注册方式 #endif diff --git a/src/kernel_liteos_a/kernel/base/ipc/los_signal.c b/src/kernel_liteos_a/kernel/base/ipc/los_signal.c index bb7bd2f7..55e34cd9 100644 --- a/src/kernel_liteos_a/kernel/base/ipc/los_signal.c +++ b/src/kernel_liteos_a/kernel/base/ipc/los_signal.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -53,15 +53,17 @@ int raise(int sig) #define GETUNMASKSET(procmask, pendFlag) ((~(procmask)) & (sigset_t)(pendFlag)) #define UINT64_BIT_SIZE 64 + int OsSigIsMember(const sigset_t *set, int signo) { int ret = LOS_NOK; - /* In musl, sig No bits 00000100 present sig No 3, but 1<< 3 = 00001000, so signo needs minus 1 */ + /* In musl, sig No bits 00000100 present sig No 3, but 1<< 3 = 00001000, so signo needs minus 1 */ + //在musl中,sig No bits 00000100表示sig No 3,但是在SIGNO2SET中 1<<3 = 00001000,因此signo需要减1 signo -= 1; /* Verify the signal */ - if (GOOD_SIGNO(signo)) { + if (GOOD_SIGNO(signo)) {//有效信号判断 /* Check if the signal is in the set */ - ret = ((*set & SIGNO2SET((unsigned int)signo)) != 0); + ret = ((*set & SIGNO2SET((unsigned int)signo)) != 0);//检查信号是否还在集合中 } return ret; @@ -120,7 +122,6 @@ VOID OsClearSigInfoTmpList(sig_cb *sigcb) (VOID)LOS_MemFree(m_aucSysMem0, tmpInfoNode); } } - STATIC INLINE VOID OsSigWaitTaskWake(LosTaskCB *taskCB, INT32 signo) { sig_cb *sigcb = &taskCB->sig; @@ -132,14 +133,14 @@ STATIC INLINE VOID OsSigWaitTaskWake(LosTaskCB *taskCB, INT32 signo) OsSigEmptySet(&sigcb->sigwaitmask); } } - +///< 唤醒被挂起的处于等待指定信号的任务 STATIC UINT32 OsPendingTaskWake(LosTaskCB *taskCB, INT32 signo) { if (!OsTaskIsPending(taskCB) || !OsProcessIsUserMode(OS_PCB_FROM_TCB(taskCB))) { return 0; } - if ((signo != SIGKILL) && (taskCB->waitFlag != OS_TASK_WAIT_SIGNAL)) { + if ((signo != SIGKILL) && (taskCB->waitFlag != OS_TASK_WAIT_SIGNAL)) { // @note_thinking 这个判断会不会有问题 ? return 0; } @@ -153,16 +154,16 @@ STATIC UINT32 OsPendingTaskWake(LosTaskCB *taskCB, INT32 signo) OsTaskWakeClearPendMask(taskCB); taskCB->ops->wake(taskCB); break; - case OS_TASK_WAIT_SIGNAL: + case OS_TASK_WAIT_SIGNAL://等待普通信号 OsSigWaitTaskWake(taskCB, signo); break; - case OS_TASK_WAIT_LITEIPC: - OsTaskWakeClearPendMask(taskCB); + case OS_TASK_WAIT_LITEIPC://等待liteipc信号 + OsTaskWakeClearPendMask(taskCB);//重置任务的等待信息 taskCB->ops->wake(taskCB); break; - case OS_TASK_WAIT_FUTEX: - OsFutexNodeDeleteFromFutexHash(&taskCB->futex, TRUE, NULL, NULL); - OsTaskWakeClearPendMask(taskCB); + case OS_TASK_WAIT_FUTEX://等待快锁信号 + OsFutexNodeDeleteFromFutexHash(&taskCB->futex, TRUE, NULL, NULL);//从哈希桶中删除快锁 + OsTaskWakeClearPendMask(taskCB);//重置任务的等待信息 taskCB->ops->wake(taskCB); break; default: @@ -171,7 +172,7 @@ STATIC UINT32 OsPendingTaskWake(LosTaskCB *taskCB, INT32 signo) return 0; } - +///给任务(线程)发送一个信号 int OsTcbDispatch(LosTaskCB *stcb, siginfo_t *info) { bool masked = FALSE; @@ -179,19 +180,19 @@ int OsTcbDispatch(LosTaskCB *stcb, siginfo_t *info) OS_RETURN_IF_NULL(sigcb); /* If signo is 0, not send signal, just check process or pthread exist */ - if (info->si_signo == 0) { + if (info->si_signo == 0) {//如果信号为0,则不发送信号,只是作为检查进程和线程是否还存在. return 0; } - masked = (bool)OsSigIsMember(&sigcb->sigprocmask, info->si_signo); - if (masked) { - /* If signal is in wait list and mask list, need unblock it */ + masked = (bool)OsSigIsMember(&sigcb->sigprocmask, info->si_signo);//@note_thinking 这里还有 masked= -1的情况要处理!!! + if (masked) {//如果信号被屏蔽了,要看等待信号集,sigwaitmask + /* If signal is in wait list and mask list, need unblock it */ //如果信号在等待列表和掩码列表中,需要解除阻止 if (LOS_ListEmpty(&sigcb->waitList) || - (!LOS_ListEmpty(&sigcb->waitList) && !OsSigIsMember(&sigcb->sigwaitmask, info->si_signo))) { - OsSigAddSet(&sigcb->sigPendFlag, info->si_signo); + (!LOS_ListEmpty(&sigcb->waitList) && !OsSigIsMember(&sigcb->sigwaitmask, info->si_signo))) { + OsSigAddSet(&sigcb->sigPendFlag, info->si_signo);//将信号加入挂起/待办集 } - } else { + } else {//信号没有被屏蔽的处理 /* unmasked signal actions */ - OsSigAddSet(&sigcb->sigFlag, info->si_signo); + OsSigAddSet(&sigcb->sigFlag, info->si_signo);//不屏蔽的信号集 } if (OsAddSigInfoToTmpList(sigcb, info) == LOS_NOK) { @@ -206,14 +207,15 @@ void OsSigMaskSwitch(LosTaskCB * const rtcb, sigset_t set) sigset_t unmaskset; rtcb->sig.sigprocmask = set; - unmaskset = GETUNMASKSET(rtcb->sig.sigprocmask, rtcb->sig.sigPendFlag); + unmaskset = GETUNMASKSET(rtcb->sig.sigprocmask, rtcb->sig.sigPendFlag);//过滤出没有被屏蔽的信号集 if (unmaskset != NULL_SIGNAL_SET) { /* pendlist do */ - rtcb->sig.sigFlag |= unmaskset; - rtcb->sig.sigPendFlag ^= unmaskset; + rtcb->sig.sigFlag |= unmaskset; //加入不屏蔽信号集 + rtcb->sig.sigPendFlag ^= unmaskset;//从挂起/待办集中去掉unmaskset } } + int OsSigprocMask(int how, const sigset_t_l *setl, sigset_t_l *oldsetl) { LosTaskCB *spcb = NULL; @@ -223,11 +225,11 @@ int OsSigprocMask(int how, const sigset_t_l *setl, sigset_t_l *oldsetl) SCHEDULER_LOCK(intSave); spcb = OsCurrTaskGet(); - /* If requested, copy the old mask to user. */ + /* If requested, copy the old mask to user. | 如果需要,请将旧掩码复制给用户*/ if (oldsetl != NULL) { *(sigset_t *)oldsetl = spcb->sig.sigprocmask; } - /* If requested, modify the current signal mask. */ + /* If requested, modify the current signal mask. | 如有要求,修改当前信号屏蔽*/ if (setl != NULL) { set = *(sigset_t *)setl; /* Okay, determine what we are supposed to do */ @@ -236,46 +238,46 @@ int OsSigprocMask(int how, const sigset_t_l *setl, sigset_t_l *oldsetl) * set pointed to by set as the new sigprocmask. */ case SIG_BLOCK: - spcb->sig.sigprocmask |= set; + spcb->sig.sigprocmask |= set;//增加信号屏蔽位 break; /* Set the intersection of the current set and the * signal set pointed to by set as the new sigprocmask. */ case SIG_UNBLOCK: - spcb->sig.sigprocmask &= ~(set); + spcb->sig.sigprocmask &= ~(set);//解除信号屏蔽位 break; /* Set the signal set pointed to by set as the new sigprocmask. */ case SIG_SETMASK: - spcb->sig.sigprocmask = set; + spcb->sig.sigprocmask = set;//设置一个新的屏蔽掩码 break; default: ret = -EINVAL; break; } /* If pending mask not in sigmask, need set sigflag. */ - OsSigMaskSwitch(spcb, spcb->sig.sigprocmask); + OsSigMaskSwitch(spcb, spcb->sig.sigprocmask);//更新与屏蔽信号相关的变量 } SCHEDULER_UNLOCK(intSave); return ret; } - +///让进程的每一个task执行参数函数 int OsSigProcessForeachChild(LosProcessCB *spcb, ForEachTaskCB handler, void *arg) { int ret; /* Visit the main thread last (if present) */ - LosTaskCB *taskCB = NULL; - LOS_DL_LIST_FOR_EACH_ENTRY(taskCB, &(spcb->threadSiblingList), LosTaskCB, threadList) { - ret = handler(taskCB, arg); - OS_RETURN_IF(ret != 0, ret); + LosTaskCB *taskCB = NULL;//遍历进程的 threadList 链表,里面存放的都是task节点 + LOS_DL_LIST_FOR_EACH_ENTRY(taskCB, &(spcb->threadSiblingList), LosTaskCB, threadList) {//遍历进程的任务列表 + ret = handler(taskCB, arg);//回调参数函数 + OS_RETURN_IF(ret != 0, ret);//这个宏的意思就是只有ret = 0时,啥也不处理.其余就返回 ret } return LOS_OK; } - +///信号处理函数,这里就是上面的 handler = SigProcessSignalHandler,见于 OsSigProcessSend static int SigProcessSignalHandler(LosTaskCB *tcb, void *arg) { - struct ProcessSignalInfo *info = (struct ProcessSignalInfo *)arg; + struct ProcessSignalInfo *info = (struct ProcessSignalInfo *)arg;//先把参数解出来 int ret; int isMember; @@ -283,128 +285,130 @@ static int SigProcessSignalHandler(LosTaskCB *tcb, void *arg) return 0; } - /* If the default tcb is not set, then set this one as default. */ - if (!info->defaultTcb) { + /* If the default tcb is not setted, then set this one as default. */ + if (!info->defaultTcb) {//如果没有默认发送方的任务,即默认参数任务. info->defaultTcb = tcb; } - isMember = OsSigIsMember(&tcb->sig.sigwaitmask, info->sigInfo->si_signo); - if (isMember && (!info->awakenedTcb)) { + isMember = OsSigIsMember(&tcb->sig.sigwaitmask, info->sigInfo->si_signo);//任务是否在等待这个信号 + if (isMember && (!info->awakenedTcb)) {//是在等待,并尚未向该任务时发送信号时 /* This means the task is waiting for this signal. Stop looking for it and use this tcb. * The requirement is: if more than one task in this task group is waiting for the signal, * then only one indeterminate task in the group will receive the signal. */ - ret = OsTcbDispatch(tcb, info->sigInfo); - OS_RETURN_IF(ret < 0, ret); + ret = OsTcbDispatch(tcb, info->sigInfo);//发送信号,注意这是给其他任务发送信号,tcb不是当前任务 + OS_RETURN_IF(ret < 0, ret);//这种写法很有意思 /* set this tcb as awakenedTcb */ info->awakenedTcb = tcb; OS_RETURN_IF(info->receivedTcb != NULL, SIG_STOP_VISIT); /* Stop search */ } /* Is this signal unblocked on this thread? */ - isMember = OsSigIsMember(&tcb->sig.sigprocmask, info->sigInfo->si_signo); - if ((!isMember) && (!info->receivedTcb) && (tcb != info->awakenedTcb)) { - /* if unblockedTcb of this signal is not set, then set it. */ + isMember = OsSigIsMember(&tcb->sig.sigprocmask, info->sigInfo->si_signo);//任务是否屏蔽了这个信号 + if ((!isMember) && (!info->receivedTcb) && (tcb != info->awakenedTcb)) {//没有屏蔽,有唤醒任务没有接收任务. + /* if unblockedTcb of this signal is not setted, then set it. */ if (!info->unblockedTcb) { info->unblockedTcb = tcb; } - ret = OsTcbDispatch(tcb, info->sigInfo); + ret = OsTcbDispatch(tcb, info->sigInfo);//向任务发送信号 OS_RETURN_IF(ret < 0, ret); /* set this tcb as receivedTcb */ - info->receivedTcb = tcb; + info->receivedTcb = tcb;//设置这个任务为接收任务 OS_RETURN_IF(info->awakenedTcb != NULL, SIG_STOP_VISIT); /* Stop search */ } return 0; /* Keep searching */ } - +///进程收到 SIGKILL 信号后,通知任务tcb处理. static int SigProcessKillSigHandler(LosTaskCB *tcb, void *arg) { - struct ProcessSignalInfo *info = (struct ProcessSignalInfo *)arg; + struct ProcessSignalInfo *info = (struct ProcessSignalInfo *)arg;//转参 return OsPendingTaskWake(tcb, info->sigInfo->si_signo); } +//处理信号发送 static void SigProcessLoadTcb(struct ProcessSignalInfo *info, siginfo_t *sigInfo) { LosTaskCB *tcb = NULL; - if (info->awakenedTcb == NULL && info->receivedTcb == NULL) { - if (info->unblockedTcb) { - tcb = info->unblockedTcb; - } else if (info->defaultTcb) { + if (info->awakenedTcb == NULL && info->receivedTcb == NULL) {//信号即没有指定接收task 也没有指定被唤醒task + if (info->unblockedTcb) {//如果进程信号信息体中有阻塞task + tcb = info->unblockedTcb;// + } else if (info->defaultTcb) {//如果有默认的发送方task tcb = info->defaultTcb; } else { return; } /* Deliver the signal to the selected task */ - (void)OsTcbDispatch(tcb, sigInfo); + (void)OsTcbDispatch(tcb, sigInfo);//向所选任务发送信号 } } - +///给参数进程发送参数信号 int OsSigProcessSend(LosProcessCB *spcb, siginfo_t *sigInfo) { int ret; struct ProcessSignalInfo info = { - .sigInfo = sigInfo, - .defaultTcb = NULL, + .sigInfo = sigInfo, //信号内容 + .defaultTcb = NULL, //以下四个值将在OsSigProcessForeachChild中根据条件完善 .unblockedTcb = NULL, .awakenedTcb = NULL, .receivedTcb = NULL }; - - if (info.sigInfo == NULL) { + //总之是要从进程中找个至少一个任务来接受这个信号,优先级 + //awakenedTcb > receivedTcb > unblockedTcb > defaultTcb + if (info.sigInfo == NULL){ return -EFAULT; } - - /* visit all taskcb and dispatch signal */ - if (info.sigInfo->si_signo == SIGKILL) { - OsSigAddSet(&spcb->sigShare, info.sigInfo->si_signo); + /* visit all taskcb and dispatch signal */ //访问所有任务和分发信号 + if (info.sigInfo->si_signo == SIGKILL) {//需要干掉进程时 SIGKILL = 9, #linux kill 9 14 + OsSigAddSet(&spcb->sigShare, info.sigInfo->si_signo);//信号集中增加信号 (void)OsSigProcessForeachChild(spcb, SigProcessKillSigHandler, &info); return 0; } else { - ret = OsSigProcessForeachChild(spcb, SigProcessSignalHandler, &info); + ret = OsSigProcessForeachChild(spcb, SigProcessSignalHandler, &info);//进程通知所有task处理信号 } if (ret < 0) { return ret; } - SigProcessLoadTcb(&info, sigInfo); + SigProcessLoadTcb(&info, sigInfo);//确保能给一个任务发送信号 return 0; } - +///信号集全部清0 int OsSigEmptySet(sigset_t *set) { *set = NULL_SIGNAL_SET; return 0; } -/* Privilege process can't send to kernel and privilege process */ +/* Privilege process can't send to kernel and privilege process */ //内核进程组和用户特权进程组无法发送 static int OsSignalPermissionToCheck(const LosProcessCB *spcb) { UINTPTR gid = (UINTPTR)OS_GET_PGROUP_LEADER(spcb->pgroup); - if (gid == OS_KERNEL_PROCESS_GROUP) { + + if (gid == OS_KERNEL_PROCESS_GROUP) {//内核进程组 return -EPERM; - } else if (gid == OS_USER_PRIVILEGE_PROCESS_GROUP) { + } else if (gid == OS_USER_PRIVILEGE_PROCESS_GROUP) {//用户特权进程组 return -EPERM; } return 0; } - +///信号分发,发送信号权限/进程组过滤. STATIC int SendSigPermissionCheck(LosProcessCB *spcb, int permission) { if (spcb == NULL) { return -ESRCH; } - if (OsProcessIsUnused(spcb)) { + if (OsProcessIsUnused(spcb)) {//进程是否还在使用,不一定是当前进程但必须是个有效进程 return -ESRCH; } -#ifdef LOSCFG_SECURITY_CAPABILITY - LosProcessCB *current = OsCurrProcessGet(); - /* Kernel process always has kill permission and user process should check permission */ - if (OsProcessIsUserMode(current) && !(current->processStatus & OS_PROCESS_FLAG_EXIT)) { +#ifdef LOSCFG_SECURITY_CAPABILITY //启用能力安全模式 + LosProcessCB *current = OsCurrProcessGet();//获取当前进程,检查当前进程是否有发送信号的权限. + /* Kernel process always has kill permission and user process should check permission *///内核进程总是有kill权限,用户进程需要检查权限 + if (OsProcessIsUserMode(current) && !(current->processStatus & OS_PROCESS_FLAG_EXIT)) {//用户进程检查能力范围 if ((current != spcb) && (!IsCapPermit(CAP_KILL)) && (current->user->userID != spcb->user->userID)) { return -EPERM; } @@ -437,7 +441,7 @@ int OsSendSigToProcess(LosProcessCB *spcb, int sig, int permission) info.si_code = SI_USER; info.si_value.sival_ptr = NULL; - return OsSigProcessSend(spcb, &info); + return OsSigProcessSend(spcb, &info);//给参数进程发送信号 } int OsDispatch(pid_t pid, siginfo_t *info, int permission) @@ -470,14 +474,14 @@ int OsKill(pid_t pid, int sig, int permission) return -EINVAL; } - /* Create the siginfo structure */ - info.si_signo = sig; - info.si_code = SI_USER; + /* Create the siginfo structure */ //创建信号结构体 + info.si_signo = sig; //信号编号 + info.si_code = SI_USER; //来自用户进程信号 info.si_value.sival_ptr = NULL; if (pid > 0) { /* Send the signal to the specify process */ - ret = OsDispatch(pid, &info, permission); + ret = OsDispatch(pid, &info, permission);//发送信号 } else if (pid == -1) { /* Send SIG to all processes */ ret = OsSendSignalToAllProcess(&info, permission); @@ -489,18 +493,17 @@ int OsKill(pid_t pid, int sig, int permission) } return ret; } - +///给发送信号过程加锁 int OsKillLock(pid_t pid, int sig) { int ret; unsigned int intSave; SCHEDULER_LOCK(intSave); - ret = OsKill(pid, sig, OS_USER_KILL_PERMISSION); + ret = OsKill(pid, sig, OS_USER_KILL_PERMISSION);//用户权限向进程发送信号 SCHEDULER_UNLOCK(intSave); return ret; } - INT32 OsTaskKillUnsafe(UINT32 taskID, INT32 signo) { siginfo_t info; @@ -519,7 +522,7 @@ INT32 OsTaskKillUnsafe(UINT32 taskID, INT32 signo) * dispatch rules. */ return OsTcbDispatch(taskCB, &info); } - +///发送信号 int OsPthreadKill(UINT32 tid, int signo) { int ret; @@ -537,7 +540,7 @@ int OsPthreadKill(UINT32 tid, int signo) SCHEDULER_UNLOCK(intSave); return ret; } - +///向信号集中加入signo信号 int OsSigAddSet(sigset_t *set, int signo) { /* Verify the signal */ @@ -545,13 +548,13 @@ int OsSigAddSet(sigset_t *set, int signo) return -EINVAL; } else { /* In musl, sig No bits 00000100 present sig No 3, but 1<< 3 = 00001000, so signo needs minus 1 */ - signo -= 1; + signo -= 1;// 信号范围是 [1 ~ 64 ],而保存变量位的范围是[0 ~ 63] /* Add the signal to the set */ - *set |= SIGNO2SET((unsigned int)signo); + *set |= SIGNO2SET((unsigned int)signo);//填充信号集 return LOS_OK; } } - +///获取阻塞当前任务的信号集 int OsSigPending(sigset_t *set) { LosTaskCB *tcb = NULL; @@ -563,7 +566,7 @@ int OsSigPending(sigset_t *set) SCHEDULER_LOCK(intSave); tcb = OsCurrTaskGet(); - *set = tcb->sig.sigPendFlag; + *set = tcb->sig.sigPendFlag;//被阻塞的信号集 SCHEDULER_UNLOCK(intSave); return LOS_OK; } @@ -578,7 +581,7 @@ STATIC int FindFirstSetedBit(UINT64 n) for (count = 0; (count < UINT64_BIT_SIZE) && (n ^ 1ULL); n >>= 1, count++) {} return (count < UINT64_BIT_SIZE) ? count : (-1); } - +///等待信号时间 int OsSigTimedWaitNoLock(sigset_t *set, siginfo_t *info, unsigned int timeout) { LosTaskCB *task = NULL; @@ -589,19 +592,19 @@ int OsSigTimedWaitNoLock(sigset_t *set, siginfo_t *info, unsigned int timeout) sigcb = &task->sig; if (sigcb->waitList.pstNext == NULL) { - LOS_ListInit(&sigcb->waitList); + LOS_ListInit(&sigcb->waitList);//初始化信号等待链表 } - /* If pendingflag & set > 0, should clear pending flag */ + /* If pendingflag & set > 0, shound clear pending flag */ sigset_t clear = sigcb->sigPendFlag & *set; if (clear) { sigcb->sigPendFlag ^= clear; ret = FindFirstSetedBit((UINT64)clear) + 1; OsMoveTmpInfoToUnbInfo(sigcb, ret); } else { - OsSigAddSet(set, SIGKILL); - OsSigAddSet(set, SIGSTOP); + OsSigAddSet(set, SIGKILL);//kill 9 14 必须要处理 + OsSigAddSet(set, SIGSTOP);//终止进程的信号也必须处理 - sigcb->sigwaitmask |= *set; + sigcb->sigwaitmask |= *set;//按位加到等待集上,也就是说sigwaitmask的信号来了都是要处理的. OsTaskWaitSetPendMask(OS_TASK_WAIT_SIGNAL, sigcb->sigwaitmask, timeout); ret = task->ops->wait(task, &sigcb->waitList, timeout); if (ret == LOS_ERRNO_TSK_TIMEOUT) { @@ -614,7 +617,7 @@ int OsSigTimedWaitNoLock(sigset_t *set, siginfo_t *info, unsigned int timeout) } return ret; } - +///让当前任务等待的信号 int OsSigTimedWait(sigset_t *set, siginfo_t *info, unsigned int timeout) { int ret; @@ -622,12 +625,12 @@ int OsSigTimedWait(sigset_t *set, siginfo_t *info, unsigned int timeout) SCHEDULER_LOCK(intSave); - ret = OsSigTimedWaitNoLock(set, info, timeout); + ret = OsSigTimedWaitNoLock(set, info, timeout);//以不加锁的方式等待 SCHEDULER_UNLOCK(intSave); return ret; } - +///通过信号挂起当前任务 int OsPause(void) { LosTaskCB *spcb = NULL; @@ -637,7 +640,7 @@ int OsPause(void) oldSigprocmask = spcb->sig.sigprocmask; return OsSigSuspend(&oldSigprocmask); } - +///用参数set代替进程的原有掩码,并暂停进程执行,直到收到信号再恢复原有掩码并继续执行进程。 int OsSigSuspend(const sigset_t *set) { unsigned int intSave; @@ -677,6 +680,7 @@ int OsSigSuspend(const sigset_t *set) return -EINTR; } + int OsSigAction(int sig, const sigaction_t *act, sigaction_t *oact) { UINTPTR addr; @@ -685,14 +689,17 @@ int OsSigAction(int sig, const sigaction_t *act, sigaction_t *oact) if (!GOOD_SIGNO(sig) || sig < 1 || act == NULL) { return -EINVAL; } - if (LOS_ArchCopyFromUser(&action, act, sizeof(sigaction_t)) != LOS_OK) { - return -EFAULT; - } - - if (sig == SIGSYS) { - addr = OsGetSigHandler(); - if (addr == 0) { - OsSetSigHandler((unsigned long)(UINTPTR)action.sa_handler); + //将数据从用户空间拷贝到内核空间 + if (LOS_ArchCopyFromUser(&action, act, sizeof(sigaction_t)) != LOS_OK) { + return -EFAULT; + } + + if (sig == SIGSYS) {//鸿蒙此处通过错误的系统调用 来安装信号处理函数,有点巧妙. + addr = OsGetSigHandler();//是否已存在信号处理函数 + if (addr == 0) {//进程没有设置信号处理函数时 + OsSetSigHandler((unsigned long)(UINTPTR)action.sa_handler);//设置进程信号处理函数 + //void (*sa_handler)(int); //信号处理函数——普通版 + //void (*sa_sigaction)(int, siginfo_t *, void *);//信号处理函数——高级版 return LOS_OK; } return -EINVAL; @@ -717,11 +724,11 @@ VOID OsSigIntUnlock(VOID) (VOID)LOS_AtomicSub((Atomic *)&sigcb->sigIntLock, 1); } + VOID *OsSaveSignalContext(VOID *sp, VOID *newSp) { UINTPTR sigHandler; UINT32 intSave; - LosTaskCB *task = OsCurrTaskGet(); LosProcessCB *process = OsCurrProcessGet(); sig_cb *sigcb = &task->sig; @@ -754,7 +761,7 @@ VOID *OsSaveSignalContext(VOID *sp, VOID *newSp) OsProcessExitCodeSignalSet(process, signo); sigcb->sigContext = sp; - OsInitSignalContext(sp, newSp, sigHandler, signo, sigVal); + OsInitSignalContext(sp, newSp, sigHandler, signo, sigVal);//初始化信号上下文 /* sig No bits 00000100 present sig No 3, but 1<< 3 = 00001000, so signo needs minus 1 */ sigcb->sigFlag ^= 1ULL << (signo - 1); @@ -767,6 +774,7 @@ VOID *OsSaveSignalContext(VOID *sp, VOID *newSp) return sp; } + VOID *OsRestorSignalContext(VOID *sp) { UINT32 intSave; @@ -785,8 +793,8 @@ VOID *OsRestorSignalContext(VOID *sp) VOID *saveContext = sigcb->sigContext; sigcb->sigContext = NULL; sigcb->count--; - process->sigShare = 0; - OsProcessExitCodeSignalClear(process); + process->sigShare = 0; //回到用户态,信号共享清0 + OsProcessExitCodeSignalClear(process);//清空进程退出码 SCHEDULER_UNLOCK(intSave); return saveContext; } From 5f874bbc3d738dffa391f6a3ceb6d2175f9e8b7e Mon Sep 17 00:00:00 2001 From: Dio Date: Mon, 22 Jan 2024 12:09:54 +0800 Subject: [PATCH 33/33] =?UTF-8?q?=E4=B8=8D=E6=98=AF=E5=93=A5=E4=BB=AC?= =?UTF-8?q?=EF=BC=8Cinclude=E4=BD=A0=E4=B9=9F=E8=AF=BB=E5=95=8A=EF=BC=9F?= =?UTF-8?q?=20=E6=8A=B1=E6=AD=89=EF=BC=8C=E6=88=91=E8=BF=98=E7=9C=9F?= =?UTF-8?q?=E8=AF=BB=EF=BC=8C=E5=8F=AA=E5=9B=A0=E6=88=91=E6=98=AF=E5=A4=A7?= =?UTF-8?q?=E7=A5=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kernel/base/include/los_container_pri.h | 28 +- .../kernel/base/include/los_err_pri.h | 63 +---- .../kernel/base/include/los_futex_pri.h | 26 +- .../base/include/los_ipc_container_pri.h | 8 +- .../kernel/base/include/los_memstat_pri.h | 4 +- .../kernel/base/include/los_mux_pri.h | 2 +- .../kernel/base/include/los_percpu_pri.h | 14 +- .../base/include/los_pid_container_pri.h | 36 +-- .../kernel/base/include/los_process_pri.h | 247 ++++++++---------- 9 files changed, 177 insertions(+), 251 deletions(-) diff --git a/src/kernel_liteos_a/kernel/base/include/los_container_pri.h b/src/kernel_liteos_a/kernel/base/include/los_container_pri.h index d7b72c70..db10f529 100644 --- a/src/kernel_liteos_a/kernel/base/include/los_container_pri.h +++ b/src/kernel_liteos_a/kernel/base/include/los_container_pri.h @@ -57,10 +57,10 @@ typedef enum { CONTAINER = 0, - PID_CONTAINER, - PID_CHILD_CONTAINER, - UTS_CONTAINER, - MNT_CONTAINER, + PID_CONTAINER, //进程容器 + PID_CHILD_CONTAINER, //子进程容器 + UTS_CONTAINER, // + MNT_CONTAINER, //挂载容器 IPC_CONTAINER, USER_CONTAINER, TIME_CONTAINER, @@ -70,29 +70,29 @@ typedef enum { } ContainerType; typedef struct Container { - Atomic rc; + Atomic rc; //原子操作 #ifdef LOSCFG_PID_CONTAINER - struct PidContainer *pidContainer; - struct PidContainer *pidForChildContainer; + struct PidContainer *pidContainer; //进程容器 + struct PidContainer *pidForChildContainer;//进程的孩子容器 #endif #ifdef LOSCFG_UTS_CONTAINER - struct UtsContainer *utsContainer; + struct UtsContainer *utsContainer; // #endif #ifdef LOSCFG_MNT_CONTAINER - struct MntContainer *mntContainer; + struct MntContainer *mntContainer; //挂载容器 #endif #ifdef LOSCFG_IPC_CONTAINER - struct IpcContainer *ipcContainer; + struct IpcContainer *ipcContainer; //IPC容器 #endif #ifdef LOSCFG_TIME_CONTAINER - struct TimeContainer *timeContainer; - struct TimeContainer *timeForChildContainer; + struct TimeContainer *timeContainer; //时间容器 + struct TimeContainer *timeForChildContainer; #endif #ifdef LOSCFG_NET_CONTAINER - struct NetContainer *netContainer; + struct NetContainer *netContainer; //网络容器 #endif } Container; - +//容器数量上限 typedef struct TagContainerLimit { #ifdef LOSCFG_PID_CONTAINER UINT32 pidLimit; diff --git a/src/kernel_liteos_a/kernel/base/include/los_err_pri.h b/src/kernel_liteos_a/kernel/base/include/los_err_pri.h index 40a667ae..e7c7fc9c 100644 --- a/src/kernel_liteos_a/kernel/base/include/los_err_pri.h +++ b/src/kernel_liteos_a/kernel/base/include/los_err_pri.h @@ -40,78 +40,21 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ -/** - * @ingroup los_err - * Define the error magic word. - */ + #define OS_ERR_MAGIC_WORD 0xa1b2c3f8 -/** - * @ingroup los_err - * @brief Error handling macro capable of returning error codes. - * - * @par Description: - * This API is used to call the error handling function by using an error code and return the same error code. - * @attention - *

        - * - * @param errNo [IN] Error code. - * - * @retval errNo - * @par Dependency: - *
        • los_err_pri.h: the header file that contains the API declaration.
        - * @see None. - */ #define OS_RETURN_ERROR(errNo) do { \ (VOID)LOS_ErrHandle("os_unspecific_file", OS_ERR_MAGIC_WORD, errNo, 0, NULL); \ return errNo; \ } while (0) -/** - * @ingroup los_err - * @brief Error handling macro capable of returning error codes. - * - * @par Description: - * This API is used to call the error handling function by using an error code and the line number of - * the erroneous line, and return the same error code. - * @attention - *
          - *
        • None.
        • - *
        - * - * @param errLine [IN] Line number of the erroneous line. - * @param errNo [IN] Error code. - * - * @retval errNo - * @par Dependency: - *
        • los_err_pri.h: the header file that contains the API declaration.
        - * @see None. - */ + #define OS_RETURN_ERROR_P2(errLine, errNo) do { \ (VOID)LOS_ErrHandle("os_unspecific_file", errLine, errNo, 0, NULL); \ return errNo; \ } while (0) -/** - * @ingroup los_err - * @brief Macro for jumping to error handler. - * - * @par Description: - * This API is used to call the error handling function by using an error code. - * @attention - *
          - *
        • None.
        • - *
        - * - * @param errorNo [IN] Error code. - * - * @retval None. - * @par Dependency: - *
        • los_err_pri.h: the header file that contains the API declaration.
        - * @see None. - */ + #define OS_GOTO_ERR_HANDLER(errorNo) do { \ errNo = errorNo; \ errLine = OS_ERR_MAGIC_WORD; \ diff --git a/src/kernel_liteos_a/kernel/base/include/los_futex_pri.h b/src/kernel_liteos_a/kernel/base/include/los_futex_pri.h index 7671115b..758a2679 100644 --- a/src/kernel_liteos_a/kernel/base/include/los_futex_pri.h +++ b/src/kernel_liteos_a/kernel/base/include/los_futex_pri.h @@ -33,25 +33,27 @@ #define _LOS_FUTEX_PRI_H #include "los_list.h" -#define FUTEX_WAIT 0 -#define FUTEX_WAKE 1 -#define FUTEX_REQUEUE 3 -#define FUTEX_WAKE_OP 5 +#define FUTEX_WAIT 0 ///< 原子性的检查 uaddr 中计数器的值是否为 val,如果是则让任务休眠,直到 FUTEX_WAKE 或者超时(time-out)。 + //也就是把任务挂到 uaddr 相对应的等待队列上去。 +#define FUTEX_WAKE 1 ///< 最多唤醒 val 个等待在 uaddr 上任务。 +#define FUTEX_REQUEUE 3 ///< 调整指定锁在Futex表中的位置 +#define FUTEX_WAKE_OP 5 #define FUTEX_LOCK_PI 6 #define FUTEX_UNLOCK_PI 7 #define FUTEX_TRYLOCK_PI 8 #define FUTEX_WAIT_BITSET 9 -#define FUTEX_PRIVATE 128 +#define FUTEX_PRIVATE 128 //私有快锁(以虚拟地址进行哈希) #define FUTEX_MASK 0x3U - +/// 每个futex node对应一个被挂起的task ,key值唯一标识一把用户态锁,具有相同key值的node被queue_list串联起来表示被同一把锁阻塞的task队列。 typedef struct { - UINTPTR key; /* private:uvaddr shared:paddr */ - UINT32 index; /* hash bucket index */ - UINT32 pid; /* private:process id shared:OS_INVALID(-1) */ - LOS_DL_LIST pendList; /* point to pendList in TCB struct */ - LOS_DL_LIST queueList; /* thread list blocked by this lock */ - LOS_DL_LIST futexList; /* point to the next FutexNode */ + UINTPTR key; /* private:uvaddr | 私有锁,用虚拟地址 shared:paddr | 共享锁,用物理地址*/ + UINT32 index; /* hash bucket index | 哈希桶索引 OsFutexKeyToIndex */ + UINT32 pid; /* private:process id shared:OS_INVALID(-1) | 私有锁:进程ID , 共享锁为 -1 */ + LOS_DL_LIST pendList; /* point to pendList in TCB struct | 指向 TCB 结构中的 pendList, 通过它找到任务*/ + LOS_DL_LIST queueList; /* thread list blocked by this lock | 挂等待这把锁的任务,其实这里挂到是FutexNode.queueList , + 通过 queueList 可以找到 pendList ,通过 pendList又可以找到真正的任务*/ + LOS_DL_LIST futexList; /* point to the next FutexNode | 下一把Futex锁*/ } FutexNode; extern UINT32 OsFutexInit(VOID); diff --git a/src/kernel_liteos_a/kernel/base/include/los_ipc_container_pri.h b/src/kernel_liteos_a/kernel/base/include/los_ipc_container_pri.h index 42ccbf3e..d46bd84b 100644 --- a/src/kernel_liteos_a/kernel/base/include/los_ipc_container_pri.h +++ b/src/kernel_liteos_a/kernel/base/include/los_ipc_container_pri.h @@ -42,13 +42,13 @@ typedef struct TagQueueCB LosQueueCB; typedef struct OsMux LosMux; typedef LosMux pthread_mutex_t; typedef struct ProcessCB LosProcessCB; - +//IPC容器 typedef struct IpcContainer { Atomic rc; - LosQueueCB *allQueue; - LOS_DL_LIST freeQueueList; + LosQueueCB *allQueue; //队列控制块(读写分离模式) + LOS_DL_LIST freeQueueList;//空闲队列链表 fd_set queueFdSet; - struct mqarray queueTable[LOSCFG_BASE_IPC_QUEUE_LIMIT]; + struct mqarray queueTable[LOSCFG_BASE_IPC_QUEUE_LIMIT];//队列池 pthread_mutex_t mqueueMutex; struct mqpersonal *mqPrivBuf[MAX_MQ_FD]; struct shminfo shmInfo; diff --git a/src/kernel_liteos_a/kernel/base/include/los_memstat_pri.h b/src/kernel_liteos_a/kernel/base/include/los_memstat_pri.h index a2a9f581..7f3aee4b 100644 --- a/src/kernel_liteos_a/kernel/base/include/los_memstat_pri.h +++ b/src/kernel_liteos_a/kernel/base/include/los_memstat_pri.h @@ -42,7 +42,7 @@ extern "C" { #endif /* __cplusplus */ typedef struct { - UINT32 memUsed; + UINT32 memUsed; ///< 记录任务内存使用量 } TskMemUsedInfo; extern VOID OsTaskMemUsedInc(UINT32 usedSize, UINT32 taskID); @@ -53,7 +53,7 @@ extern VOID OsTaskMemClear(UINT32 taskID); #ifdef LOS_MEM_SLAB typedef struct { - UINT32 slabUsed; + UINT32 slabUsed; ///< 任务占用以slab分配方式内存量 } TskSlabUsedInfo; extern VOID OsTaskSlabUsedInc(UINT32 usedSize, UINT32 taskID); diff --git a/src/kernel_liteos_a/kernel/base/include/los_mux_pri.h b/src/kernel_liteos_a/kernel/base/include/los_mux_pri.h index 8837114c..ebab2648 100644 --- a/src/kernel_liteos_a/kernel/base/include/los_mux_pri.h +++ b/src/kernel_liteos_a/kernel/base/include/los_mux_pri.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: diff --git a/src/kernel_liteos_a/kernel/base/include/los_percpu_pri.h b/src/kernel_liteos_a/kernel/base/include/los_percpu_pri.h index 8a824ffd..e561c03d 100644 --- a/src/kernel_liteos_a/kernel/base/include/los_percpu_pri.h +++ b/src/kernel_liteos_a/kernel/base/include/los_percpu_pri.h @@ -43,9 +43,9 @@ extern "C" { #ifdef LOSCFG_KERNEL_SMP typedef enum { - CPU_RUNNING = 0, /* cpu is running */ - CPU_HALT, /* cpu in the halt */ - CPU_EXC /* cpu in the exc */ + CPU_RUNNING = 0, ///< cpu is running | CPU正在运行状态 + CPU_HALT, ///< cpu in the halt | CPU处于暂停状态 + CPU_EXC ///< cpu in the exc | CPU处于异常状态 } ExcFlag; typedef struct { @@ -55,14 +55,14 @@ typedef struct { #endif } Percpu; -/* the kernel per-cpu structure */ +/*! the kernel per-cpu structure | 每个cpu的内核描述符 */ extern Percpu g_percpu[LOSCFG_KERNEL_CORE_NUM]; - +/*! 获得当前运行CPU的信息 */ STATIC INLINE Percpu *OsPercpuGet(VOID) { - return &g_percpu[ArchCurrCpuid()]; + return &g_percpu[ArchCurrCpuid()]; } - +/*! 获得参数CPU的信息 */ STATIC INLINE Percpu *OsPercpuGetByID(UINT32 cpuid) { return &g_percpu[cpuid]; diff --git a/src/kernel_liteos_a/kernel/base/include/los_pid_container_pri.h b/src/kernel_liteos_a/kernel/base/include/los_pid_container_pri.h index cc047e68..eed94630 100644 --- a/src/kernel_liteos_a/kernel/base/include/los_pid_container_pri.h +++ b/src/kernel_liteos_a/kernel/base/include/los_pid_container_pri.h @@ -38,29 +38,29 @@ typedef struct TagTaskCB LosTaskCB; typedef struct ProcessCB LosProcessCB; struct ProcessGroup; struct Container; - +//虚拟进程/任务 信息 typedef struct { - UINT32 vid; /* Virtual ID */ - UINT32 vpid; /* Virtual parent ID */ - UINTPTR cb; /* Control block */ - LosProcessCB *realParent; /* process real parent */ - LOS_DL_LIST node; + UINT32 vid; /* Virtual ID | 虚拟ID*/ + UINT32 vpid; /* Virtual parent ID | 父进程虚拟ID*/ + UINTPTR cb; /* Control block | 控制块*/ + LosProcessCB *realParent; /* process real parent | 进程真实的父进程 */ + LOS_DL_LIST node;//用于挂入 PidContainer.pidFreeList | tidFreeList } ProcessVid; #define PID_CONTAINER_LEVEL_LIMIT 3 - +//进程容器 typedef struct PidContainer { - Atomic rc; - Atomic level; - Atomic lock; - BOOL referenced; - UINT32 containerID; - struct PidContainer *parent; - struct ProcessGroup *rootPGroup; - LOS_DL_LIST tidFreeList; - ProcessVid tidArray[LOSCFG_BASE_CORE_TSK_LIMIT]; - LOS_DL_LIST pidFreeList; - ProcessVid pidArray[LOSCFG_BASE_CORE_PROCESS_LIMIT]; + Atomic rc; //原子操作 + Atomic level; //等级,0为最高级,父比子高一级 + Atomic lock; //锁 + BOOL referenced; //是否被引用 + UINT32 containerID; //容器ID + struct PidContainer *parent; //父进程容器 + struct ProcessGroup *rootPGroup; //进程组 + LOS_DL_LIST tidFreeList; //任务空闲链表 + ProcessVid tidArray[LOSCFG_BASE_CORE_TSK_LIMIT];//虚拟任务池 + LOS_DL_LIST pidFreeList; //进程空闲链表 + ProcessVid pidArray[LOSCFG_BASE_CORE_PROCESS_LIMIT];//虚拟进程池 } PidContainer; #define OS_PID_CONTAINER_FROM_PCB(processCB) ((processCB)->container->pidContainer) diff --git a/src/kernel_liteos_a/kernel/base/include/los_process_pri.h b/src/kernel_liteos_a/kernel/base/include/los_process_pri.h index e100438d..a0d9d114 100644 --- a/src/kernel_liteos_a/kernel/base/include/los_process_pri.h +++ b/src/kernel_liteos_a/kernel/base/include/los_process_pri.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -65,82 +65,86 @@ extern "C" { #ifdef LOSCFG_SECURITY_CAPABILITY #define OS_GROUPS_NUMBER_MAX 256 +/*! 用户描述体*/ typedef struct { - UINT32 userID; + UINT32 userID; ///<用户ID [0,60000],0为root用户 UINT32 effUserID; - UINT32 gid; + UINT32 gid; ///<用户组ID [0,60000],0为root用户组 UINT32 effGid; - UINT32 groupNumber; - UINT32 groups[1]; + UINT32 groupNumber;///< 用户组数量 + UINT32 groups[1]; //所属用户组列表,一个用户可属多个用户组 } User; #endif - +/*! 进程组结构体*/ typedef struct ProcessGroup { - UINTPTR pgroupLeader; /**< Process group leader is the the process that created the group */ - LOS_DL_LIST processList; /**< List of processes under this process group */ - LOS_DL_LIST exitProcessList; /**< List of closed processes (zombie processes) under this group */ - LOS_DL_LIST groupList; /**< Process group list */ + UINTPTR pgroupLeader; /**< Process group leader is the the process that created the group | 负责创建进程组的进程首地址*/ + LOS_DL_LIST processList; /**< List of processes under this process group | 属于该进程组的进程链表*/ + LOS_DL_LIST exitProcessList; /**< List of closed processes (zombie processes) under this group | 进程组的僵死进程链表*/ + LOS_DL_LIST groupList; /**< Process group list | 进程组链表,上面挂的都是进程组*/ } ProcessGroup; +/** + * 进程控制块. + */ typedef struct ProcessCB { - CHAR processName[OS_PCB_NAME_LEN]; /**< Process name */ - UINT32 processID; /**< Process ID */ + CHAR processName[OS_PCB_NAME_LEN]; /**< Process name | 进程名称 */ + UINT32 processID; /**< Process ID = leader thread ID | 进程ID,由进程池分配,范围[0,64] */ UINT16 processStatus; /**< [15:4] Process Status; [3:0] The number of threads currently - running in the process */ - UINT16 consoleID; /**< The console id of task belongs */ - UINT16 processMode; /**< Kernel Mode:0; User Mode:1; */ // 用戶模式1 内核模式0 + running in the process | 这里设计很巧妙.用一个变量表示了两层逻辑 数量和状态,点赞! @note_good 从这里也可以看出一个进程可以有多个正在运行的任务*/ + UINT16 consoleID; /**< The console id of task belongs | 任务的控制台id归属 */ + UINT16 processMode; /**< Kernel Mode:0; User Mode:1; | 模式指定为内核还是用户进程 */ struct ProcessCB *parentProcess; /**< Parent process */ - UINT32 exitCode; /**< Process exit status */ - LOS_DL_LIST pendList; /**< Block list to which the process belongs */ - LOS_DL_LIST childrenList; /**< Children process list */ // 存放子進程,链表 - LOS_DL_LIST exitChildList; /**< Exit children process list */ // 要退出的子进程 - LOS_DL_LIST siblingList; /**< Linkage in parent's children list */ //兄弟进程链表 - ProcessGroup *pgroup; /**< Process group to which a process belongs */ //所属进程组 - LOS_DL_LIST subordinateGroupList; /**< Linkage in group list */ // 进程是组长时有哪些组员进程 - LosTaskCB *threadGroup; // 哪个线程组是进程的主线程ID - LOS_DL_LIST threadSiblingList; /**< List of threads under this process */ // 进程的线程任务列表 - volatile UINT32 threadNumber; /**< Number of threads alive under this process */ // 此进程下的活动线程数量 - UINT32 threadCount; /**< Total number of threads created under this process */ // 在此进程下创建的线程总数 - LOS_DL_LIST waitList; /**< The process holds the waitLits to support wait/waitpid */ // 进程持有等待链表以支持wait/waitpid + UINT32 exitCode; /**< Process exit status | 进程退出状态码*/ + LOS_DL_LIST pendList; /**< Block list to which the process belongs | 进程所在的阻塞列表,进程因阻塞挂入相应的链表.*/ + LOS_DL_LIST childrenList; /**< Children process list | 孩子进程都挂到这里,形成双循环链表*/ + LOS_DL_LIST exitChildList; /**< Exit children process list | 要退出的孩子进程链表,白发人要送黑发人.*/ + LOS_DL_LIST siblingList; /**< Linkage in parent's children list | 兄弟进程链表, 56个民族是一家,来自同一个父进程.*/ + ProcessGroup *pgroup; /**< Process group to which a process belongs | 所属进程组*/ + LOS_DL_LIST subordinateGroupList; /**< Linkage in group list | 进程组员链表*/ + LosTaskCB *threadGroup; + LOS_DL_LIST threadSiblingList; /**< List of threads under this process | 进程的线程(任务)列表 */ + volatile UINT32 threadNumber; /**< Number of threads alive under this process | 此进程下的活动线程数*/ + UINT32 threadCount; /**< Total number of threads created under this process | 在此进程下创建的线程总数*/ // + LOS_DL_LIST waitList; /**< The process holds the waitLits to support wait/waitpid | 父进程通过进程等待的方式,回收子进程资源,获取子进程退出信息*/ #ifdef LOSCFG_KERNEL_SMP - UINT32 timerCpu; /**< CPU core number of this task is delayed or pended */ // 统计各个线程被延迟或者阻塞的时间 + UINT32 timerCpu; /**< CPU core number of this task is delayed or pended | 统计各线程被延期或阻塞的时间*/ #endif - UINTPTR sigHandler; /**< Signal handler */ // 信号处理函数 - sigset_t sigShare; /**< Signal share bit */ // 信号共享位 + UINTPTR sigHandler; /**< Signal handler | 信号处理函数,处理如 SIGSYS 等信号*/ + sigset_t sigShare; /**< Signal share bit | 信号共享位 sigset_t是个64位的变量,对应64种信号*/ #ifdef LOSCFG_KERNEL_LITEIPC - ProcIpcInfo *ipcInfo; /**< Memory pool for lite ipc */ //用于进程间通讯的虚拟设备文件系统,设备装载点为 /dev/lite_ipc + ProcIpcInfo *ipcInfo; /**< Memory pool for lite ipc | 用于进程间通讯的虚拟设备文件系统,设备装载点为 /dev/lite_ipc*/ #endif #ifdef LOSCFG_KERNEL_VM - LosVmSpace *vmSpace; /**< VMM space for processes */ //虚拟空间,描述进程虚拟内存的数据结构,linux称为内存描述符 + LosVmSpace *vmSpace; /**< VMM space for processes | 虚拟空间,描述进程虚拟内存的数据结构,linux称为内存描述符 */ #endif #ifdef LOSCFG_FS_VFS - struct files_struct *files; /**< Files held by the process */ -#endif - timer_t timerID; /**< ITimer */ + struct files_struct *files; /**< Files held by the process | 进程所持有的所有文件,注者称之为进程的文件管理器*/ +#endif //每个进程都有属于自己的文件管理器,记录对文件的操作. 注意:一个文件可以被多个进程操作 + timer_t timerID; /**< iTimer */ -#ifdef LOSCFG_SECURITY_CAPABILITY - User *user; // 进程的拥有者 - UINT32 capability; // 安全能力范围 +#ifdef LOSCFG_SECURITY_CAPABILITY //安全能力 + User *user; ///< 进程的拥有者 + UINT32 capability; ///< 安全能力范围 对应 CAP_SETGID #endif -#ifdef LOSCFG_SECURITY_VID - TimerIdMap timerIdMap; +#ifdef LOSCFG_SECURITY_VID //虚拟ID映射功能 + TimerIdMap timerIdMap; #endif #ifdef LOSCFG_DRIVERS_TZDRIVER - struct Vnode *execVnode; /**< Exec bin of the process */ + struct Vnode *execVnode; /**< Exec bin of the process | 进程的可执行文件 */ #endif - mode_t umask; + mode_t umask; ///< umask(user file-creatiopn mode mask)为用户文件创建掩码,是创建文件或文件夹时默认权限的基础。 #ifdef LOSCFG_KERNEL_CPUP - OsCpupBase *processCpup; /**< Process cpu usage */ + OsCpupBase *processCpup; /**< Process cpu usage | 进程占用CPU情况统计*/ #endif - struct rlimit *resourceLimit; + struct rlimit *resourceLimit; ///< 每个进程在运行时系统不会无限制的允许单个进程不断的消耗资源,因此都会设置资源限制。 #ifdef LOSCFG_KERNEL_CONTAINER - Container *container; + Container *container; ///< 内核容器 #ifdef LOSCFG_USER_CONTAINER - struct Credentials *credentials; + struct Credentials *credentials; ///< 用户身份证 #endif #endif #ifdef LOSCFG_PROC_PROCESS_DIR - struct ProcDirEntry *procDir; + struct ProcDirEntry *procDir; ///< 目录文件项 #endif #ifdef LOSCFG_KERNEL_PLIMITS ProcLimiterSet *plimits; @@ -161,8 +165,8 @@ extern UINT32 g_processMaxNum; #define OS_PCB_FROM_TCB(taskCB) ((LosProcessCB *)((taskCB)->processCB)) #define OS_PCB_FROM_TID(taskID) ((LosProcessCB *)(OS_TCB_FROM_TID(taskID)->processCB)) #define OS_GET_PGROUP_LEADER(pgroup) ((LosProcessCB *)((pgroup)->pgroupLeader)) -#define OS_PCB_FROM_SIBLIST(ptr) LOS_DL_LIST_ENTRY((ptr), LosProcessCB, siblingList) -#define OS_PCB_FROM_PENDLIST(ptr) LOS_DL_LIST_ENTRY((ptr), LosProcessCB, pendList) +#define OS_PCB_FROM_SIBLIST(ptr) LOS_DL_LIST_ENTRY((ptr), LosProcessCB, siblingList)///< 通过siblingList节点找到 LosProcessCB +#define OS_PCB_FROM_PENDLIST(ptr) LOS_DL_LIST_ENTRY((ptr), LosProcessCB, pendList) ///< 通过pendlist节点找到 LosProcessCB /** * @ingroup los_process @@ -202,7 +206,7 @@ extern UINT32 g_processMaxNum; * * The process is run out but the resources occupied by the process are not recovered. */ -#define OS_PROCESS_STATUS_ZOMBIES 0x0100U +#define OS_PROCESS_STATUS_ZOMBIES 0x0100U ///< 进程状态: 僵死 /** * @ingroup los_process @@ -211,7 +215,7 @@ extern UINT32 g_processMaxNum; * The process status equal this is process control block unused, * coexisting with OS_PROCESS_STATUS_ZOMBIES means that the control block is not recovered. */ -#define OS_PROCESS_FLAG_UNUSED 0x0200U +#define OS_PROCESS_FLAG_UNUSED 0x0200U ///< 进程未使用标签,一般用于进程的初始状态 freelist里面都是这种标签 /** * @ingroup los_process @@ -219,7 +223,7 @@ extern UINT32 g_processMaxNum; * * The process has been call exit, it only works with multiple cores. */ -#define OS_PROCESS_FLAG_EXIT 0x0400U +#define OS_PROCESS_FLAG_EXIT 0x0400U ///< 进程退出标签,退出的进程进入回收链表等待回收资源 /** * @ingroup los_process @@ -227,7 +231,7 @@ extern UINT32 g_processMaxNum; * * The process is the leader of the process group. */ -#define OS_PROCESS_FLAG_GROUP_LEADER 0x0800U +#define OS_PROCESS_FLAG_GROUP_LEADER 0x0800U ///< 进程当了进程组领导标签 /** * @ingroup los_process @@ -235,21 +239,21 @@ extern UINT32 g_processMaxNum; * * The process has performed the exec operation. */ -#define OS_PROCESS_FLAG_ALREADY_EXEC 0x1000U +#define OS_PROCESS_FLAG_ALREADY_EXEC 0x1000U ///< 进程已执行exec操作 load elf时使用 /** * @ingroup los_process * Flag that indicates the process or process control block status. * * The process is dying or already dying. - */ -#define OS_PROCESS_STATUS_INACTIVE (OS_PROCESS_FLAG_EXIT | OS_PROCESS_STATUS_ZOMBIES) + */ /// 进程不活跃状态定义: 身上贴有退出便签且状态为僵死的进程 +#define OS_PROCESS_STATUS_INACTIVE (OS_PROCESS_FLAG_EXIT | OS_PROCESS_STATUS_ZOMBIES) /** * @ingroup los_process * Used to check if the process control block is unused. */ -STATIC INLINE BOOL OsProcessIsUnused(const LosProcessCB *processCB) +STATIC INLINE BOOL OsProcessIsUnused(const LosProcessCB *processCB)//查下进程是否还在使用? { return ((processCB->processStatus & OS_PROCESS_FLAG_UNUSED) != 0); } @@ -257,8 +261,8 @@ STATIC INLINE BOOL OsProcessIsUnused(const LosProcessCB *processCB) /** * @ingroup los_process * Used to check if the process is inactive. - */ -STATIC INLINE BOOL OsProcessIsInactive(const LosProcessCB *processCB) + */ /// 进程不活跃函数定义:身上贴有不使用且不活跃标签的进程 +STATIC INLINE BOOL OsProcessIsInactive(const LosProcessCB *processCB)//查下进程是否不活跃? { return ((processCB->processStatus & (OS_PROCESS_FLAG_UNUSED | OS_PROCESS_STATUS_INACTIVE)) != 0); } @@ -266,8 +270,8 @@ STATIC INLINE BOOL OsProcessIsInactive(const LosProcessCB *processCB) /** * @ingroup los_process * Used to check if the process is dead. - */ -STATIC INLINE BOOL OsProcessIsDead(const LosProcessCB *processCB) + */ /// 进程死啦死啦的定义: 身上贴有不使用且状态为僵死的进程 +STATIC INLINE BOOL OsProcessIsDead(const LosProcessCB *processCB)//查下进程是否死啦死啦滴? { return ((processCB->processStatus & OS_PROCESS_STATUS_ZOMBIES) != 0); } @@ -282,68 +286,44 @@ STATIC INLINE BOOL OsProcessIsPGroupLeader(const LosProcessCB *processCB) return ((processCB->processStatus & OS_PROCESS_FLAG_GROUP_LEADER) != 0); } -/** - * @ingroup los_process - * The highest priority of a kernel mode process. - */ -#define OS_PROCESS_PRIORITY_HIGHEST 0 -/** - * @ingroup los_process - * The lowest priority of a kernel mode process - */ -#define OS_PROCESS_PRIORITY_LOWEST 31 +#define OS_PROCESS_PRIORITY_HIGHEST 0 ///< 进程最高优先级 -/** - * @ingroup los_process - * The highest priority of a user mode process. - */ -#define OS_USER_PROCESS_PRIORITY_HIGHEST 10 -/** - * @ingroup los_process - * The lowest priority of a user mode process - */ -#define OS_USER_PROCESS_PRIORITY_LOWEST OS_PROCESS_PRIORITY_LOWEST +#define OS_PROCESS_PRIORITY_LOWEST 31 ///< 进程最低优先级 -/** - * @ingroup los_process - * User state root process default priority - */ -#define OS_PROCESS_USERINIT_PRIORITY 28 -/** - * @ingroup los_process - * ID of the kernel idle process - */ -#define OS_KERNEL_IDLE_PROCESS_ID 0U +#define OS_USER_PROCESS_PRIORITY_HIGHEST 10 ///< 内核模式和用户模式的优先级分割线 10-31 用户级, 0-9内核级 -/** - * @ingroup los_process - * ID of the user root process - */ -#define OS_USER_ROOT_PROCESS_ID 1U -/** - * @ingroup los_process - * ID of the kernel root process - */ -#define OS_KERNEL_ROOT_PROCESS_ID 2U +#define OS_USER_PROCESS_PRIORITY_LOWEST OS_PROCESS_PRIORITY_LOWEST ///< 用户进程的最低优先级 + + +#define OS_PROCESS_USERINIT_PRIORITY 28 ///< 用户进程默认的优先级,28级好低啊 + -#define OS_TASK_DEFAULT_STACK_SIZE 0x2000 -#define OS_USER_TASK_SYSCALL_STACK_SIZE 0x3000 -#define OS_USER_TASK_STACK_SIZE 0x100000 +#define OS_KERNEL_IDLE_PROCESS_ID 0U //0号进程为空闲进程 -#define OS_KERNEL_MODE 0x0U -#define OS_USER_MODE 0x1U + +#define OS_USER_ROOT_PROCESS_ID 1U //1号为用户态根进程 + + +#define OS_KERNEL_ROOT_PROCESS_ID 2U //1号为内核态根进程 +#define OS_TASK_DEFAULT_STACK_SIZE 0x2000 ///< task默认栈大小 8K +#define OS_USER_TASK_SYSCALL_STACK_SIZE 0x3000 ///< 用户通过系统调用的栈大小 12K ,这时是运行在内核模式下 +#define OS_USER_TASK_STACK_SIZE 0x100000 ///< 用户任务运行在用户空间的栈大小 1M + +#define OS_KERNEL_MODE 0x0U ///< 内核态 +#define OS_USER_MODE 0x1U ///< 用户态 +/*! 用户态进程*/ STATIC INLINE BOOL OsProcessIsUserMode(const LosProcessCB *processCB) { return (processCB->processMode == OS_USER_MODE); } -#define LOS_PRIO_PROCESS 0U -#define LOS_PRIO_PGRP 1U -#define LOS_PRIO_USER 2U +#define LOS_PRIO_PROCESS 0U ///< 进程标识 +#define LOS_PRIO_PGRP 1U ///< 进程组标识 +#define LOS_PRIO_USER 2U ///< 用户标识 #define OS_USER_PRIVILEGE_PROCESS_GROUP ((UINTPTR)OsGetUserInitProcess()) #define OS_KERNEL_PROCESS_GROUP ((UINTPTR)OsGetKernelInitProcess()) @@ -353,40 +333,40 @@ STATIC INLINE BOOL OsProcessIsUserMode(const LosProcessCB *processCB) * 31 15 8 7 0 * | | exit code | core dump | signal | */ -#define OS_PRO_EXIT_OK 0 - +#define OS_PRO_EXIT_OK 0 ///< 进程正常退出 +/// 置进程退出码第七位为1 STATIC INLINE VOID OsProcessExitCodeCoreDumpSet(LosProcessCB *processCB) { - processCB->exitCode |= 0x80U; + processCB->exitCode |= 0x80U; // 0b10000000 } - +/// 设置进程退出信号(0 ~ 7) STATIC INLINE VOID OsProcessExitCodeSignalSet(LosProcessCB *processCB, UINT32 signal) { - processCB->exitCode |= signal & 0x7FU; + processCB->exitCode |= signal & 0x7FU;// 0b01111111 } - +/// 清除进程退出信号(0 ~ 7) STATIC INLINE VOID OsProcessExitCodeSignalClear(LosProcessCB *processCB) { - processCB->exitCode &= (~0x7FU); + processCB->exitCode &= (~0x7FU);// 低7位全部清0 } - +/// 进程退出码是否被设置过,默认是 0 ,如果 & 0x7FU 还是 0 ,说明没有被设置过. STATIC INLINE BOOL OsProcessExitCodeSignalIsSet(LosProcessCB *processCB) { return (processCB->exitCode) & 0x7FU; } - +/// 设置进程退出号(8 ~ 15) STATIC INLINE VOID OsProcessExitCodeSet(LosProcessCB *processCB, UINT32 code) { processCB->exitCode |= ((code & 0x000000FFU) << 8U) & 0x0000FF00U; /* 8: Move 8 bits to the left, exitCode */ } #define OS_PID_CHECK_INVALID(pid) (((UINT32)(pid)) >= g_processMaxNum) - +/*! 内联函数 进程ID是否有效 */ STATIC INLINE BOOL OsProcessIDUserCheckInvalid(UINT32 pid) { return ((pid >= g_processMaxNum) || (pid == 0)); } - +/*! 获取当前进程PCB */ STATIC INLINE LosProcessCB *OsCurrProcessGet(VOID) { UINT32 intSave; @@ -398,6 +378,7 @@ STATIC INLINE LosProcessCB *OsCurrProcessGet(VOID) } #ifdef LOSCFG_SECURITY_CAPABILITY +/*! 获取当前进程的所属用户 */ STATIC INLINE User *OsCurrUserGet(VOID) { User *user = NULL; @@ -469,14 +450,14 @@ STATIC INLINE UINT32 OsGetRootPid(const LosProcessCB *processCB) /* * return immediately if no child has exited. */ -#define LOS_WAIT_WNOHANG (1 << 0U) +#define LOS_WAIT_WNOHANG (1 << 0U) ///< 如果没有孩子进程退出,则立即返回,而不是阻塞在这个函数上等待;如果结束了,则返回该子进程的进程号。 /* * return if a child has stopped (but not traced via ptrace(2)). * Status for traced children which have stopped is provided even * if this option is not specified. */ -#define LOS_WAIT_WUNTRACED (1 << 1U) +#define LOS_WAIT_WUNTRACED (1 << 1U) ///< 如果子进程进入暂停情况则马上返回,不予以理会结束状态。untraced #define LOS_WAIT_WSTOPPED (1 << 1U) /* @@ -488,7 +469,7 @@ STATIC INLINE UINT32 OsGetRootPid(const LosProcessCB *processCB) * return if a stopped child has been resumed by delivery of SIGCONT. * (For Linux-only options, see below.) */ -#define LOS_WAIT_WCONTINUED (1 << 3U) +#define LOS_WAIT_WCONTINUED (1 << 3U) ///< 可获取子进程恢复执行的状态,也就是可获取continued状态 continued /* * Leave the child in a waitable state; @@ -499,30 +480,30 @@ STATIC INLINE UINT32 OsGetRootPid(const LosProcessCB *processCB) /* * Indicates that you are already in a wait state */ -#define OS_PROCESS_WAIT (1 << 15U) +#define OS_PROCESS_WAIT (1 << 15U) ///< 表示已经处于等待状态 /* * Wait for any child process to finish */ -#define OS_PROCESS_WAIT_ANY OS_TASK_WAIT_ANYPROCESS +#define OS_PROCESS_WAIT_ANY OS_TASK_WAIT_ANYPROCESS ///< 等待任意子进程完成 /* * Wait for the child process specified by the pid to finish */ -#define OS_PROCESS_WAIT_PRO OS_TASK_WAIT_PROCESS +#define OS_PROCESS_WAIT_PRO OS_TASK_WAIT_PROCESS ///< 等待pid指定的子进程完成 /* * Waits for any child process in the specified process group to finish. */ -#define OS_PROCESS_WAIT_GID OS_TASK_WAIT_GID +#define OS_PROCESS_WAIT_GID OS_TASK_WAIT_GID ///< 等待指定进程组中的任意子进程完成 #define OS_PROCESS_INFO_ALL 1 -#define OS_PROCESS_DEFAULT_UMASK 0022 - -extern UINTPTR __user_init_entry; -extern UINTPTR __user_init_bss; -extern UINTPTR __user_init_end; -extern UINTPTR __user_init_load_addr; +#define OS_PROCESS_DEFAULT_UMASK 0022 ///< 系统默认的用户掩码(umask),大多数的Linux系统的默认掩码为022。 +//用户掩码的作用是用户在创建文件时从文件的默认权限中去除掩码中的权限。所以文件创建之后的权限实际为:创建文件的权限为:0666-0022=0644。创建文件夹的权限为:0777-0022=0755 +extern UINTPTR __user_init_entry; ///< 第一个用户态进程(init)的入口地址 查看 LITE_USER_SEC_ENTRY +extern UINTPTR __user_init_bss; ///< 查看 LITE_USER_SEC_BSS ,赋值由liteos.ld完成 +extern UINTPTR __user_init_end; ///< init 进程的用户空间初始化结束地址 +extern UINTPTR __user_init_load_addr;///< init 进程的加载地址 ,由链接器赋值 extern UINT32 OsProcessInit(VOID); extern UINT32 OsSystemProcessCreate(VOID); extern VOID OsProcessNaturalExit(LosProcessCB *processCB, UINT32 status);

        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